[note] this blog is the original of the revision of the original code [laughing and crying] it's very tongue twisting.
At present, we can't go to school because of the epidemic. We can learn extra-curricular things [Snickers] after studying online classes
Because it is found that the agent model codes on CSDN and Baidu are wrong, and most of the errors in various codes are the same. So in order to facilitate the need of friends to learn to send the right, if you want to see the original can refer to the following links.
This is the link to the agent model I found: Original link This article only corrects some minor errors of the code in the above links
After running, these four files will be generated in the directory where the code file is located, and the detailed ones will not be distributed
Blogger's senior high school students after 00, I don't know if there are any friends after 00 who read this article and see the trouble
This is the revised code
import matplotlib.pyplot as plt import itertools import random import copy class Schelling: def __init__( self,width, height, empty_ratio, similarity_threshold, n_iterations, races = 2): self.width = width self.height = height self.races = races self.empty_ratio = empty_ratio self.similarity_threshold = similarity_threshold self.n_iterations = n_iterations self.empty_houses = [] self.agents = {} def populate(self): self.all_houses = list(itertools.product(range(self.width),range(self.height))) random.shuffle(self.all_houses) self.n_empty = int( self.empty_ratio * len(self.all_houses) ) self.empty_houses = self.all_houses[:self.n_empty] self.remaining_houses = self.all_houses[self.n_empty:] houses_by_race = [self.remaining_houses[i::self.races] for i in range(self.races)] for i in range(self.races): # Create for each race agent self.agents = dict(self.agents.items() + dict(zip(houses_by_race[i], [i+1]*len(houses_by_race[i]))).items()) def is_unsatisfied(self, x, y): race = self.agents[(x,y)] count_similar = 0 count_different = 0 if x > 0 and y > 0 and (x-1, y-1) not in self.empty_houses: if self.agents[(x-1, y-1)] == race: count_similar += 1 else: count_different += 1 if y > 0 and (x,y-1) not in self.empty_houses: if self.agents[(x,y-1)] == race: count_similar += 1 else: count_different += 1 if x < (self.width-1) and y > 0 and (x+1,y-1) not in self.empty_houses: if self.agents[(x+1,y-1)] == race: count_similar += 1 else: count_different += 1 if x > 0 and (x-1,y) not in self.empty_houses: if self.agents[(x-1,y)] == race: count_similar += 1 else: count_different += 1 if x < (self.width-1) and (x+1,y) not in self.empty_houses: if self.agents[(x+1,y)] == race: count_similar += 1 else: count_different += 1 if x > 0 and y < (self.height-1) and (x-1,y+1) not in self.empty_houses: if self.agents[(x-1,y+1)] == race: count_similar += 1 else: count_different += 1 if x > 0 and y < (self.height-1) and (x,y+1) not in self.empty_houses: if self.agents[(x,y+1)] == race: count_similar += 1 else: count_different += 1 if x < (self.width-1) and y < (self.height-1) and (x+1,y+1) not in self.empty_houses: if self.agents[(x+1,y+1)] == race: count_similar += 1 else: count_different += 1 if (count_similar+count_different) == 0: return False else: return float(count_similar)/(count_similar+count_different) < self.similarity_threshold def update(self): for i in range(self.n_iterations): self.old_agents = copy.deepcopy(self.agents) n_changes = 0 for agent in self.old_agents: if self.is_unsatisfied(agent[0], agent[1]): agent_race = self.agents[agent] empty_house = random.choice(self.empty_houses) self.agents[empty_house] = agent_race del self.agents[agent] self.empty_houses.remove(empty_house) self.empty_houses.append(agent) n_changes += 1 print n_changes if n_changes == 0: break def move_to_empty(self, x, y): race = self.agents[(x,y)] empty_house = random.choice(self.empty_houses) self.updated_agents[empty_house] = race del self.updated_agents[(x, y)] self.empty_houses.remove(empty_house) self.empty_houses.append((x, y)) def plot(self, title, file_name): fig, ax = plt.subplots() # [0, self. Width] ax. Set [ylim ([0, self. H eight]) ax.set_xticks([]) ax.set_yticks([]) plt.savefig(file_name) schelling_1 = Schelling(50, 50, 0.3, 0.3, 500, 2) schelling_1.populate() schelling_2 = Schelling(50, 50, 0.3, 0.5, 500, 2) schelling_2.populate() schelling_3 = Schelling(50, 50, 0.3, 0.8, 500, 2) schelling_3.populate() schelling_1.plot('Schelling Model with 2 colors: Initial State' , 'schelling_2_initial.png') schelling_1.update() schelling_2.update() schelling_3.update() schelling_1.plot('Schelling Model with 2 colors: Final State with Similarity Threshold 30%', 'schelling_2_30_final.png') schelling_2.plot('Schelling Model with 2 colors: Final State with Similarity Threshold 50%', 'schelling_2_50_final.png') schelling_3.plo t('Schelling Model with 2 colors: Final State with Similarity Threshold 80%', 'schelling_2_80_final.png')
First error:
In DEF is unsatisfied (self, x, y): in the above line, the last face of dict is missing a parenthesis ")", resulting in the interpreter thinking DEF is unsatisfied (self, x, y): is wrong and marking def red.
dict(zip(houses_by_race[i], [i+1]*len(houses_by_race[i]))).items()) def is_unsatisfied(self, x, y):
Second error:
In def update(self): the else statement in the above line, the original self.happy'threshold should be self.similarity'threshold.
else: return float(count_similar)/(count_similar+count_different) < self.similarity_threshold#self.happy_threshold def update(self):
Because the def init ion of "similarity" is "threshold"
class Schelling: def __init__( self,width, height, empty_ratio, similarity_threshold, n_iterations, races = 2):
Third error:
The same mistake as the second
def update(self): for i in range(self.n_iterations): self.old_agents = copy.deepcopy(self.agents) n_changes = 0 for agent in self.old_agents: if self.is_unsatisfied(agent[0], agent[1]):
In the if statement in def update(self): statement
Self.is.unhappy of the original text should be self.is.unsatisfied. The reason is also because self.is unsatisfied is used when defining "init"
if self.is_unsatisfied(agent[0], agent[1]):
The last question is:
schelling_1.plot('Schelling Model with 2 colors: Initial State', 'schelling_2_initial.png') schelling_1.update() schelling_2.update() schelling_3.update()
In the original text, schelling_1.plot('Schelling Model with 2 colors: Initial State','schelling_2_initial.png ') is schelling_1_1, which makes it impossible to run
This is the initial distribution diagram, and I changed it to schelling_1
The Ending