-
Notifications
You must be signed in to change notification settings - Fork 847
/
Schelling.py
129 lines (103 loc) · 3.49 KB
/
Schelling.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
'''
Schelling Segregation Model
=========================================
A simple implementation of a Schelling segregation model.
'''
from __future__ import division # For Python 2.x compatibility
import random
from mesa import Model, Agent
from mesa.time import RandomActivation
from mesa.space import SingleGrid
from mesa.datacollection import DataCollector
from mesa.visualization.TextVisualization import (TextData, TextGrid,
TextVisualization)
class SchellingModel(Model):
'''
Model class for the Schelling segregation model.
'''
def __init__(self, height, width, density, minority_pc, homophily):
'''
'''
self.height = height
self.width = width
self.density = density
self.minority_pc = minority_pc
self.homophily = homophily
self.schedule = RandomActivation(self)
self.grid = SingleGrid(height, width, torus=True)
self.happy = 0
self.datacollector = DataCollector(
{"happy": lambda m: m.happy}, # Model-level count of happy agents
# For testing purposes, agent's individual x and y
{"x": lambda a: a.pos[0], "y": lambda a: a.pos[1]})
self.running = True
# Set up agents
# We use a grid iterator that returns
# the coordinates of a cell as well as
# its contents. (coord_iter)
for cell in self.grid.coord_iter():
x = cell[1]
y = cell[2]
if random.random() < self.density:
if random.random() < self.minority_pc:
agent_type = 1
else:
agent_type = 0
agent = SchellingAgent((x, y), agent_type)
self.grid.position_agent(agent, (x, y))
self.schedule.add(agent)
def step(self):
'''
Run one step of the model. If All agents are happy, halt the model.
'''
self.happy = 0 # Reset counter of happy agents
self.schedule.step()
self.datacollector.collect(self)
if self.happy == self.schedule.get_agent_count():
self.running = False
class SchellingAgent(Agent):
'''
Schelling segregation agent
'''
def __init__(self, pos, agent_type):
'''
Create a new Schelling agent.
Args:
unique_id: Unique identifier for the agent.
x, y: Agent initial location.
agent_type: Indicator for the agent's type (minority=1, majority=0)
'''
self.unique_id = pos
self.pos = pos
self.type = agent_type
def step(self, model):
similar = 0
for neighbor in model.grid.neighbor_iter(self.pos):
if neighbor.type == self.type:
similar += 1
# If unhappy, move:
if similar < model.homophily:
model.grid.move_to_empty(self)
else:
model.happy += 1
class SchellingTextVisualization(TextVisualization):
'''
ASCII visualization for schelling model
'''
def __init__(self, model):
'''
Create new Schelling ASCII visualization.
'''
self.model = model
grid_viz = TextGrid(self.model.grid, self.ascii_agent)
happy_viz = TextData(self.model, 'happy')
self.elements = [grid_viz, happy_viz]
@staticmethod
def ascii_agent(a):
'''
Minority agents are X, Majority are O.
'''
if a.type == 0:
return 'O'
if a.type == 1:
return 'X'