先引用一下果壳网对谢林模型的介绍
该模型由马里兰大学的经济学家托马斯·谢林建立。主要感兴趣的隔离有两种:一种是种族隔离,另一种是由收入差异导致的隔离。
每一个红点代表城市中白人的聚集地,每一个蓝点代表城市中美国黑人的聚集地,每一个黄点代表城市中拉美人的聚集地,绿点则代表城市中亚裔的聚集地。从这幅图可以看到非常明显的种族隔离。
图片每个红点代表富人,浅蓝色的点代表穷人,而深蓝点则代表中产阶层。从这幅图可以看到收入隔离现象尽管非常明显,但并没有种族隔离现象明显。
谢林构建了一个基于代理人的模型。该类模型要点有三个:代理人,规则,以及群体表现。
谢林模型是个关于人们选择在哪居住的模型。他把每个人放置在棋盘上,整个城市看作是一块巨大的棋盘。棋盘上每一个小格子可以住一个人也可以空着。
假设红格子表示住着富人,灰格子表示住了穷人,白格子表示没有主人。对在中间X格子的富人来说,周围7个邻居有3个是同类,他应该留下还是搬走?
谢林设定了规则称作阈值基本准则:每个人都有一个阈值(threshold),根据阈值做决定是留下还是搬走。比如假设X的阈值是33%,则此时他会选择留下。而当他的富人邻居有一位搬走时,由于只剩2/7是同类所以那时会选择搬走。
居住地总数:60*60;居民总数:2800
满意度阈值:(0,1) 设定
红蓝两色代表不同肤色,绿色代表空
每个节点相似比低于相似度阈值随机搬家,所有节点相似比不低于相似度阈值,停止迭代
下面是我用python实现的仿真:python2.7+matplotlib+numpy
import random
import numpy as np
import matplotlib.pyplot as plt
import time
# plt.ion()
vector = range(1,3601) #1-3600
random.shuffle(vector)
white = vector[0:1400]
black = vector[1400:2800]
temp = vector[2800:3600]
tmap = np.zeros((62,62,3))
# init
for i in range(1,3601):
if i in white:
tmap[(i - 1) / 60 + 1][(i - 1) % 60 + 1] = [1, 0, 0]
elif i in black:
tmap[(i - 1) / 60 + 1][(i - 1) % 60 + 1] = [0, 0, 1]
else:
tmap[(i - 1) / 60 + 1][(i - 1) % 60 + 1] = [0, 1, 0]
row = [-1,-1,-1, 0, 0, 1, 1, 1] #neiborhood
col = [-1, 0, 1,-1, 1,-1, 0, 1]
simv = []
for m in range(7):
thd = 0.3+m*0.1 #threshold
print 'Threshold:'+str(thd)
sim = 0.0 #similarity
nosat = 1
times = 0
while nosat and times<50:
times=times+1
sim = 0.0
bnosat = 0
wnosat = 0
nosatv=[]
for i in range(1,61):
for j in range(1,61):
if(tmap[i][j][1] != 1):
ns=0.0
n=0.0
for k in range(8):
if tmap[i+row[k]][j+col[k]][0]==1 or tmap[i+row[k]][j+col[k]][2]==1:
n=n+1.0
if tmap[i+row[k]][j+col[k]][0] == tmap[i][j][0]:
ns=ns+1.0
if n!=0:
sim = sim + ns/n #similarity plus
if(ns/n < thd):
if(tmap[i][j][0]==1):
wnosat = wnosat+1
else:
bnosat = bnosat+1
nosatv.append([i, j])
else:
nosatv.append([i, j])
nosat = wnosat + bnosat
print 'Unsatisfied:' + str(nosat / 2800.0*100)+'%'
#-------------move--------------
random.shuffle(nosatv)
wnosatv=nosatv[0:wnosat]
bnosatv=nosatv[wnosat:wnosat+bnosat]
tempv = nosatv[wnosat+bnosat:]
for i in range(wnosat):
tmap[wnosatv[i][0]][wnosatv[i][1]]=[1,0,0]
for i in range(bnosat):
tmap[bnosatv[i][0]][bnosatv[i][1]]=[0,0,1]
for i in range(tempv.__len__()):
tmap[tempv[i][0]][tempv[i][1]] = [0, 1, 0]
sim = sim/2800.0
simv.append(sim)
print 'Similarity:' + str(sim*100)+'%'
plt.figure()
plt.axis("off")
plt.imshow(tmap, interpolation="nearest")
plt.title('Threshold = '+str(thd)+' Similarity:'+ str(sim*100)+'%')
plt.show()
plt.figure()
plt.plot([0.3+m*0.1 for m in range(7)],simv,'-')
plt.title('Similarity of different threshold')
plt.xlabel('threshold')# make axis labels
plt.ylabel('Similarity')
plt.xlim(0.2, 1.0)
plt.xlim(0.2, 1.0)
plt.show()