我有一个问题,我应该使用 pythong 对谢林分离问题进行建模。我已经坚持了很长一段时间,但我认为我的问题是我的邻居没有被正确地从一个不快乐的代理人换成一个空代理人。
**问题范围:** 我们有一个包含 0、1 和 2 的矩阵。 os代表空房子,1s代表一种种族,2s代表另一种种族。如果一个种族不满意他们的邻居(由 self.par 定义)与他们相似,那么他们就会成为不快乐的代理人。这些不开心的特工需要调换到空房子里。这需要在多个时间步长上重复,并且随着人们变得“快乐”
,指标(即下面代码定义的 frac_mean)应该减少但是,我的问题是 frac mean 指标没有显示出一致的下降模式。
** 我尝试过的事情:** 我尝试的主要事情不是在原始 self.array 中进行交换,而是复制它并在其上进行所有交换,然后将其等同于代码倒数第二行所见的原始 self 数组。
任何帮助将不胜感激:
class Schelling():
kernel = [[1,1,1],[1,0,1],[1,1,1]]
#par = 0.3
def __init__(self, n, par=0.3):
self.par=par
probs = [0.1, 0.45, 0.45]
choices = [0, 1, 2]
self.array = np.random.choice(choices, (n, n), p=probs)
def count_neighbours(self):
a = self.array
empty = a == 0
red = a == 1
blue = a == 2
num_red = correlate2d(red, self.kernel, mode='same', boundary='wrap')
num_blue = correlate2d(blue, self.kernel, mode='same', boundary='wrap')
num_neighbours = num_red + num_blue
frac_red = num_red / num_neighbours
frac_blue = num_blue / num_neighbours
frac_red[num_neighbours == 0] = 0
frac_blue[num_neighbours == 0] = 0
# Nice way to do a vector if-else application
frac_same = np.where(red, frac_red, frac_blue)
# Because only if-else, empty will have frac_blue, so we need to correct this
frac_same[empty] = np.nan
return empty, frac_red, frac_blue, frac_same, a
def step(self):
empty, frac_red, frac_blue, frac_same, count_neighbours_list = self.count_neighbours()
metric=np.nanmean(frac_same)
unhappy_address = list(zip(*np.array(np.nonzero(frac_same < self.par))))
np.random.shuffle(unhappy_address)
empty_address = list(zip(*np.array(np.nonzero(empty))))
# Perform swaps until no more swaps are possible
unhappy_copy=unhappy_address.copy()
empty_copy=empty_address.copy()
ind=len(unhappy_copy)
#ind=min(len(unhappy_address), len(empty_address))
for i in range(ind):
#adding a check:
#add in a break: for the value of i if its greater than len-1 of empty_address, then break
if i == len(empty_address):
break
else:
unhappy_tup_req=unhappy_copy[i]
emp_tup_req=empty_copy[i]
#count_neighbours_list[emp_tup_req]=count_neighbours_list[unhappy_tup_req]
#count_neighbours_list[unhappy_tup_req]==0
count_neighbours_list[emp_tup_req], count_neighbours_list[unhappy_tup_req] = count_neighbours_list[unhappy_tup_req], count_neighbours_list[emp_tup_req]
self.array= count_neighbours_list
return unhappy_address, empty_address, count_neighbours_list, metric
这里有一些你可以尝试的东西:
swap
功能来做到这一点。update
功能来做到这一点。以下是如何在 Python 中实现上述步骤的示例:
def schelling_segregation(array, similarity_threshold):
"""
This function implements the Schelling segregation model.
Args:
array: A 2D array representing the city.
similarity_threshold: The threshold that is used to determine if an agent is happy.
Returns:
A 2D array representing the final state of the city.
"""
# Initialize the list of unhappy agents.
unhappy_agents = []
# Loop through the array and identify the unhappy agents.
for i in range(len(array)):
for j in range(len(array[0])):
if array[i][j] != 0:
fraction_of_neighbors = 0
for neighbor in [(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)]:
if 0 <= neighbor[0] < len(array) and 0 <= neighbor[1] < len(array[0]):
if array[neighbor[0]][neighbor[1]] == array[i][j]:
fraction_of_neighbors += 1
if fraction_of_neighbors < similarity_threshold:
unhappy_agents.append((i, j))
# Loop through the list of unhappy agents and swap them with an empty house.
for i, j in unhappy_agents:
while True:
empty_house = None
for neighbor in [(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)]:
if 0 <= neighbor[0] < len(array) and 0 <= neighbor[1] < len(array[0]):
if array[neighbor[0]][neighbor[1]] == 0:
empty_house = neighbor
break
if empty_house is not None:
array[i][j], array[empty_house[0]][empty_house[1]] = array[empty_house[0]][empty_house[1]], array[i][j]
break
return array
希望对您有所帮助!