Skip to content

Commit 43622b9

Browse files
authored
Revert PR #161: Replace schedulers with AgentSet functionality (#170)
This commit reverts PR #161 #161 That PR assumed that time advancement would be done automatically, like proposed in projectmesa/mesa#2223 We encountered some underlying issues with time, which we couldn't resolve in time.
1 parent 0ebc4d1 commit 43622b9

File tree

28 files changed

+170
-123
lines changed

28 files changed

+170
-123
lines changed

examples/bank_reserves/bank_reserves/agents.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,15 @@
1010
Northwestern University, Evanston, IL.
1111
"""
1212

13-
from .random_walk import RandomWalker
13+
import mesa
1414

15+
from .random_walk import RandomWalker
1516

16-
class Bank:
17-
"""Note that the Bank class is not a Mesa Agent, but just a regular Python
18-
class. This is because there is only one bank in this model, and it does not
19-
use any Mesa-specific features like the scheduler or the grid, and doesn't
20-
have a step method. It is just used to keep track of the bank's reserves and
21-
the amount it can loan out, for Person agents to interact with."""
2217

23-
def __init__(self, model, reserve_percent=50):
24-
self.model = model
18+
class Bank(mesa.Agent):
19+
def __init__(self, unique_id, model, reserve_percent=50):
20+
# initialize the parent class with required parameters
21+
super().__init__(unique_id, model)
2522
# for tracking total value of loans outstanding
2623
self.bank_loans = 0
2724
"""percent of deposits the bank must keep in reserves - this is set via
@@ -176,6 +173,7 @@ def take_out_loan(self, amount):
176173
# increase the bank's outstanding loans
177174
self.bank.bank_loans += amount
178175

176+
# step is called for each agent in model.BankReservesModel.schedule.step()
179177
def step(self):
180178
# move to a cell in my Moore neighborhood
181179
self.random_move()

examples/bank_reserves/bank_reserves/model.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,38 +26,40 @@
2626
def get_num_rich_agents(model):
2727
"""return number of rich agents"""
2828

29-
rich_agents = [a for a in model.agents if a.savings > model.rich_threshold]
29+
rich_agents = [a for a in model.schedule.agents if a.savings > model.rich_threshold]
3030
return len(rich_agents)
3131

3232

3333
def get_num_poor_agents(model):
3434
"""return number of poor agents"""
3535

36-
poor_agents = [a for a in model.agents if a.loans > 10]
36+
poor_agents = [a for a in model.schedule.agents if a.loans > 10]
3737
return len(poor_agents)
3838

3939

4040
def get_num_mid_agents(model):
4141
"""return number of middle class agents"""
4242

4343
mid_agents = [
44-
a for a in model.agents if a.loans < 10 and a.savings < model.rich_threshold
44+
a
45+
for a in model.schedule.agents
46+
if a.loans < 10 and a.savings < model.rich_threshold
4547
]
4648
return len(mid_agents)
4749

4850

4951
def get_total_savings(model):
5052
"""sum of all agents' savings"""
5153

52-
agent_savings = [a.savings for a in model.agents]
54+
agent_savings = [a.savings for a in model.schedule.agents]
5355
# return the sum of agents' savings
5456
return np.sum(agent_savings)
5557

5658

5759
def get_total_wallets(model):
5860
"""sum of amounts of all agents' wallets"""
5961

60-
agent_wallets = [a.wallet for a in model.agents]
62+
agent_wallets = [a.wallet for a in model.schedule.agents]
6163
# return the sum of all agents' wallets
6264
return np.sum(agent_wallets)
6365

@@ -73,7 +75,7 @@ def get_total_money(model):
7375

7476
def get_total_loans(model):
7577
# list of amounts of all agents' loans
76-
agent_loans = [a.loans for a in model.agents]
78+
agent_loans = [a.loans for a in model.schedule.agents]
7779
# return sum of all agents' loans
7880
return np.sum(agent_loans)
7981

@@ -116,7 +118,7 @@ def __init__(
116118
self.height = height
117119
self.width = width
118120
self.init_people = init_people
119-
121+
self.schedule = mesa.time.RandomActivation(self)
120122
self.grid = mesa.space.MultiGrid(self.width, self.height, torus=True)
121123
# rich_threshold is the amount of savings a person needs to be considered "rich"
122124
self.rich_threshold = rich_threshold
@@ -136,7 +138,7 @@ def __init__(
136138
)
137139

138140
# create a single bank for the model
139-
self.bank = Bank(self, self.reserve_percent)
141+
self.bank = Bank(1, self, self.reserve_percent)
140142

141143
# create people for the model according to number of people set by user
142144
for i in range(self.init_people):
@@ -146,13 +148,15 @@ def __init__(
146148
p = Person(i, self, True, self.bank, self.rich_threshold)
147149
# place the Person object on the grid at coordinates (x, y)
148150
self.grid.place_agent(p, (x, y))
151+
# add the Person object to the model schedule
152+
self.schedule.add(p)
149153

150154
self.running = True
151155
self.datacollector.collect(self)
152156

153157
def step(self):
154158
# tell all the agents in the model to run their step function
155-
self.agents.shuffle().do("step")
159+
self.schedule.step()
156160
# collect data
157161
self.datacollector.collect(self)
158162

examples/bank_reserves/batch_run.py

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,15 @@
3737
def get_num_rich_agents(model):
3838
"""list of rich agents"""
3939

40-
rich_agents = [a for a in model.agents if a.savings > model.rich_threshold]
40+
rich_agents = [a for a in model.schedule.agents if a.savings > model.rich_threshold]
4141
# return number of rich agents
4242
return len(rich_agents)
4343

4444

4545
def get_num_poor_agents(model):
4646
"""list of poor agents"""
4747

48-
poor_agents = [a for a in model.agents if a.loans > 10]
48+
poor_agents = [a for a in model.schedule.agents if a.loans > 10]
4949
# return number of poor agents
5050
return len(poor_agents)
5151

@@ -54,7 +54,9 @@ def get_num_mid_agents(model):
5454
"""list of middle class agents"""
5555

5656
mid_agents = [
57-
a for a in model.agents if a.loans < 10 and a.savings < model.rich_threshold
57+
a
58+
for a in model.schedule.agents
59+
if a.loans < 10 and a.savings < model.rich_threshold
5860
]
5961
# return number of middle class agents
6062
return len(mid_agents)
@@ -63,15 +65,15 @@ def get_num_mid_agents(model):
6365
def get_total_savings(model):
6466
"""list of amounts of all agents' savings"""
6567

66-
agent_savings = [a.savings for a in model.agents]
68+
agent_savings = [a.savings for a in model.schedule.agents]
6769
# return the sum of agents' savings
6870
return np.sum(agent_savings)
6971

7072

7173
def get_total_wallets(model):
7274
"""list of amounts of all agents' wallets"""
7375

74-
agent_wallets = [a.wallet for a in model.agents]
76+
agent_wallets = [a.wallet for a in model.schedule.agents]
7577
# return the sum of all agents' wallets
7678
return np.sum(agent_wallets)
7779

@@ -89,7 +91,7 @@ def get_total_money(model):
8991
def get_total_loans(model):
9092
"""list of amounts of all agents' loans"""
9193

92-
agent_loans = [a.loans for a in model.agents]
94+
agent_loans = [a.loans for a in model.schedule.agents]
9395
# return sum of all agents' loans
9496
return np.sum(agent_loans)
9597

@@ -127,7 +129,7 @@ def __init__(
127129
self.height = height
128130
self.width = width
129131
self.init_people = init_people
130-
132+
self.schedule = mesa.time.RandomActivation(self)
131133
self.grid = mesa.space.MultiGrid(self.width, self.height, torus=True)
132134
# rich_threshold is the amount of savings a person needs to be considered "rich"
133135
self.rich_threshold = rich_threshold
@@ -148,8 +150,8 @@ def __init__(
148150
agent_reporters={"Wealth": "wealth"},
149151
)
150152

151-
# create a single bank object for the model
152-
self.bank = Bank(self, self.reserve_percent)
153+
# create a single bank for the model
154+
self.bank = Bank(1, self, self.reserve_percent)
153155

154156
# create people for the model according to number of people set by user
155157
for i in range(self.init_people):
@@ -160,14 +162,16 @@ def __init__(
160162
p = Person(i, (x, y), self, True, self.bank, self.rich_threshold)
161163
# place the Person object on the grid at coordinates (x, y)
162164
self.grid.place_agent(p, (x, y))
165+
# add the Person object to the model schedule
166+
self.schedule.add(p)
163167

164168
self.running = True
165169

166170
def step(self):
167171
# collect data
168172
self.datacollector.collect(self)
169173
# tell all the agents in the model to run their step function
170-
self.agents.shuffle().do("step")
174+
self.schedule.step()
171175

172176
def run_model(self):
173177
for i in range(self.run_time):

examples/boid_flockers/Flocker Test.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
"def draw_boids(model):\n",
2626
" x_vals = []\n",
2727
" y_vals = []\n",
28-
" for boid in model.agents:\n",
28+
" for boid in model.schedule.agents:\n",
2929
" x, y = boid.pos\n",
3030
" x_vals.append(x)\n",
3131
" y_vals.append(y)\n",

examples/boid_flockers/boid_flockers/SimpleContinuousModule.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def __init__(self, portrayal_method=None, canvas_height=500, canvas_width=500):
1818

1919
def render(self, model):
2020
space_state = []
21-
for obj in model.agents:
21+
for obj in model.schedule.agents:
2222
portrayal = self.portrayal_method(obj)
2323
x, y = obj.pos
2424
x = (x - model.space.x_min) / (model.space.x_max - model.space.x_min)

examples/boid_flockers/boid_flockers/model.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ def __init__(
120120
self.vision = vision
121121
self.speed = speed
122122
self.separation = separation
123-
123+
self.schedule = mesa.time.RandomActivation(self)
124124
self.space = mesa.space.ContinuousSpace(width, height, True)
125125
self.factors = {"cohere": cohere, "separate": separate, "match": match}
126126
self.make_agents()
@@ -144,6 +144,7 @@ def make_agents(self):
144144
**self.factors,
145145
)
146146
self.space.place_agent(boid, pos)
147+
self.schedule.add(boid)
147148

148149
def step(self):
149-
self.agents.shuffle().do("step")
150+
self.schedule.step()

examples/boltzmann_wealth_model/boltzmann_wealth_model/model.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33

44
def compute_gini(model):
5-
agent_wealths = [agent.wealth for agent in model.agents]
5+
agent_wealths = [agent.wealth for agent in model.schedule.agents]
66
x = sorted(agent_wealths)
77
N = model.num_agents
88
B = sum(xi * (N - i) for i, xi in enumerate(x)) / (N * sum(x))
@@ -21,14 +21,14 @@ def __init__(self, N=100, width=10, height=10):
2121
super().__init__()
2222
self.num_agents = N
2323
self.grid = mesa.space.MultiGrid(width, height, True)
24-
24+
self.schedule = mesa.time.RandomActivation(self)
2525
self.datacollector = mesa.DataCollector(
2626
model_reporters={"Gini": compute_gini}, agent_reporters={"Wealth": "wealth"}
2727
)
2828
# Create agents
2929
for i in range(self.num_agents):
3030
a = MoneyAgent(i, self)
31-
31+
self.schedule.add(a)
3232
# Add the agent to a random grid cell
3333
x = self.random.randrange(self.grid.width)
3434
y = self.random.randrange(self.grid.height)
@@ -38,7 +38,7 @@ def __init__(self, N=100, width=10, height=10):
3838
self.datacollector.collect(self)
3939

4040
def step(self):
41-
self.agents.shuffle().do("step")
41+
self.schedule.step()
4242
# collect data
4343
self.datacollector.collect(self)
4444

examples/boltzmann_wealth_model_experimental/model.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33

44
def compute_gini(model):
5-
agent_wealths = [agent.wealth for agent in model.agents]
5+
agent_wealths = [agent.wealth for agent in model.schedule.agents]
66
x = sorted(agent_wealths)
77
N = model.num_agents
88
B = sum(xi * (N - i) for i, xi in enumerate(x)) / (N * sum(x))
@@ -21,14 +21,14 @@ def __init__(self, N=100, width=10, height=10):
2121
super().__init__()
2222
self.num_agents = N
2323
self.grid = mesa.space.MultiGrid(width, height, True)
24-
24+
self.schedule = mesa.time.RandomActivation(self)
2525
self.datacollector = mesa.DataCollector(
2626
model_reporters={"Gini": compute_gini}, agent_reporters={"Wealth": "wealth"}
2727
)
2828
# Create agents
2929
for i in range(self.num_agents):
3030
a = MoneyAgent(i, self)
31-
31+
self.schedule.add(a)
3232
# Add the agent to a random grid cell
3333
x = self.random.randrange(self.grid.width)
3434
y = self.random.randrange(self.grid.height)
@@ -38,7 +38,7 @@ def __init__(self, N=100, width=10, height=10):
3838
self.datacollector.collect(self)
3939

4040
def step(self):
41-
self.agents.shuffle().do("step")
41+
self.schedule.step()
4242
# collect data
4343
self.datacollector.collect(self)
4444

examples/boltzmann_wealth_model_network/boltzmann_wealth_model_network/model.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44

55
def compute_gini(model):
6-
agent_wealths = [agent.wealth for agent in model.agents]
6+
agent_wealths = [agent.wealth for agent in model.schedule.agents]
77
x = sorted(agent_wealths)
88
N = model.num_agents
99
B = sum(xi * (N - i) for i, xi in enumerate(x)) / (N * sum(x))
@@ -19,7 +19,7 @@ def __init__(self, num_agents=7, num_nodes=10):
1919
self.num_nodes = num_nodes if num_nodes >= self.num_agents else self.num_agents
2020
self.G = nx.erdos_renyi_graph(n=self.num_nodes, p=0.5)
2121
self.grid = mesa.space.NetworkGrid(self.G)
22-
22+
self.schedule = mesa.time.RandomActivation(self)
2323
self.datacollector = mesa.DataCollector(
2424
model_reporters={"Gini": compute_gini},
2525
agent_reporters={"Wealth": lambda _: _.wealth},
@@ -30,15 +30,15 @@ def __init__(self, num_agents=7, num_nodes=10):
3030
# Create agents
3131
for i in range(self.num_agents):
3232
a = MoneyAgent(i, self)
33-
33+
self.schedule.add(a)
3434
# Add the agent to a random node
3535
self.grid.place_agent(a, list_of_random_nodes[i])
3636

3737
self.running = True
3838
self.datacollector.collect(self)
3939

4040
def step(self):
41-
self.agents.shuffle().do("step")
41+
self.schedule.step()
4242
# collect data
4343
self.datacollector.collect(self)
4444

examples/caching_and_replay/model.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ def __init__(
7070
self.homophily = homophily
7171
self.radius = radius
7272

73+
self.schedule = mesa.time.RandomActivation(self)
7374
self.grid = mesa.space.SingleGrid(width, height, torus=True)
7475

7576
self.happy = 0
@@ -86,6 +87,7 @@ def __init__(
8687
agent_type = 1 if self.random.random() < self.minority_pc else 0
8788
agent = SchellingAgent(self.next_id(), self, agent_type)
8889
self.grid.place_agent(agent, pos)
90+
self.schedule.add(agent)
8991

9092
self.datacollector.collect(self)
9193

@@ -94,9 +96,9 @@ def step(self):
9496
Run one step of the model.
9597
"""
9698
self.happy = 0 # Reset counter of happy agents
97-
self.agents.shuffle().do("step")
99+
self.schedule.step()
98100

99101
self.datacollector.collect(self)
100102

101-
if self.happy == len(self.agents):
103+
if self.happy == self.schedule.get_agent_count():
102104
self.running = False

0 commit comments

Comments
 (0)