Skip to content

Commit 0fd7f82

Browse files
committed
Reinstate PR #161: Replace schedulers with AgentSet functionality
This reinstates PR #161 after the previous revert.
1 parent fc18ece commit 0fd7f82

File tree

28 files changed

+123
-170
lines changed

28 files changed

+123
-170
lines changed

examples/bank_reserves/bank_reserves/agents.py

+9-7
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,18 @@
1010
Northwestern University, Evanston, IL.
1111
"""
1212

13-
import mesa
14-
1513
from .random_walk import RandomWalker
1614

1715

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)
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."""
22+
23+
def __init__(self, model, reserve_percent=50):
24+
self.model = model
2225
# for tracking total value of loans outstanding
2326
self.bank_loans = 0
2427
"""percent of deposits the bank must keep in reserves - this is set via
@@ -173,7 +176,6 @@ def take_out_loan(self, amount):
173176
# increase the bank's outstanding loans
174177
self.bank.bank_loans += amount
175178

176-
# step is called for each agent in model.BankReservesModel.schedule.step()
177179
def step(self):
178180
# move to a cell in my Moore neighborhood
179181
self.random_move()

examples/bank_reserves/bank_reserves/model.py

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

29-
rich_agents = [a for a in model.schedule.agents if a.savings > model.rich_threshold]
29+
rich_agents = [a for a in model.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.schedule.agents if a.loans > 10]
36+
poor_agents = [a for a in model.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
45-
for a in model.schedule.agents
46-
if a.loans < 10 and a.savings < model.rich_threshold
44+
a for a in model.agents if a.loans < 10 and a.savings < model.rich_threshold
4745
]
4846
return len(mid_agents)
4947

5048

5149
def get_total_savings(model):
5250
"""sum of all agents' savings"""
5351

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

5856

5957
def get_total_wallets(model):
6058
"""sum of amounts of all agents' wallets"""
6159

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

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

7674
def get_total_loans(model):
7775
# list of amounts of all agents' loans
78-
agent_loans = [a.loans for a in model.schedule.agents]
76+
agent_loans = [a.loans for a in model.agents]
7977
# return sum of all agents' loans
8078
return np.sum(agent_loans)
8179

@@ -118,7 +116,7 @@ def __init__(
118116
self.height = height
119117
self.width = width
120118
self.init_people = init_people
121-
self.schedule = mesa.time.RandomActivation(self)
119+
122120
self.grid = mesa.space.MultiGrid(self.width, self.height, torus=True)
123121
# rich_threshold is the amount of savings a person needs to be considered "rich"
124122
self.rich_threshold = rich_threshold
@@ -138,7 +136,7 @@ def __init__(
138136
)
139137

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

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

154150
self.running = True
155151
self.datacollector.collect(self)
156152

157153
def step(self):
158154
# tell all the agents in the model to run their step function
159-
self.schedule.step()
155+
self.agents.shuffle().do("step")
160156
# collect data
161157
self.datacollector.collect(self)
162158

examples/bank_reserves/batch_run.py

+10-14
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.schedule.agents if a.savings > model.rich_threshold]
40+
rich_agents = [a for a in model.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.schedule.agents if a.loans > 10]
48+
poor_agents = [a for a in model.agents if a.loans > 10]
4949
# return number of poor agents
5050
return len(poor_agents)
5151

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

5656
mid_agents = [
57-
a
58-
for a in model.schedule.agents
59-
if a.loans < 10 and a.savings < model.rich_threshold
57+
a for a in model.agents if a.loans < 10 and a.savings < model.rich_threshold
6058
]
6159
# return number of middle class agents
6260
return len(mid_agents)
@@ -65,15 +63,15 @@ def get_num_mid_agents(model):
6563
def get_total_savings(model):
6664
"""list of amounts of all agents' savings"""
6765

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

7270

7371
def get_total_wallets(model):
7472
"""list of amounts of all agents' wallets"""
7573

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

@@ -91,7 +89,7 @@ def get_total_money(model):
9189
def get_total_loans(model):
9290
"""list of amounts of all agents' loans"""
9391

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

@@ -129,7 +127,7 @@ def __init__(
129127
self.height = height
130128
self.width = width
131129
self.init_people = init_people
132-
self.schedule = mesa.time.RandomActivation(self)
130+
133131
self.grid = mesa.space.MultiGrid(self.width, self.height, torus=True)
134132
# rich_threshold is the amount of savings a person needs to be considered "rich"
135133
self.rich_threshold = rich_threshold
@@ -150,8 +148,8 @@ def __init__(
150148
agent_reporters={"Wealth": "wealth"},
151149
)
152150

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

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

168164
self.running = True
169165

170166
def step(self):
171167
# collect data
172168
self.datacollector.collect(self)
173169
# tell all the agents in the model to run their step function
174-
self.schedule.step()
170+
self.agents.shuffle().do("step")
175171

176172
def run_model(self):
177173
for i in range(self.run_time):

examples/boid_flockers/Flocker Test.ipynb

+1-1
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.schedule.agents:\n",
28+
" for boid in model.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

+1-1
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.schedule.agents:
21+
for obj in model.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

+2-3
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-
self.schedule = mesa.time.RandomActivation(self)
123+
124124
self.space = mesa.space.ContinuousSpace(width, height, True)
125125
self.factors = {"cohere": cohere, "separate": separate, "match": match}
126126
self.make_agents()
@@ -144,7 +144,6 @@ def make_agents(self):
144144
**self.factors,
145145
)
146146
self.space.place_agent(boid, pos)
147-
self.schedule.add(boid)
148147

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

examples/boltzmann_wealth_model/boltzmann_wealth_model/model.py

+4-4
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.schedule.agents]
5+
agent_wealths = [agent.wealth for agent in model.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-
self.schedule = mesa.time.RandomActivation(self)
24+
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-
self.schedule.add(a)
31+
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.schedule.step()
41+
self.agents.shuffle().do("step")
4242
# collect data
4343
self.datacollector.collect(self)
4444

examples/boltzmann_wealth_model_experimental/model.py

+4-4
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.schedule.agents]
5+
agent_wealths = [agent.wealth for agent in model.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-
self.schedule = mesa.time.RandomActivation(self)
24+
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-
self.schedule.add(a)
31+
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.schedule.step()
41+
self.agents.shuffle().do("step")
4242
# collect data
4343
self.datacollector.collect(self)
4444

examples/boltzmann_wealth_model_network/boltzmann_wealth_model_network/model.py

+4-4
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.schedule.agents]
6+
agent_wealths = [agent.wealth for agent in model.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-
self.schedule = mesa.time.RandomActivation(self)
22+
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-
self.schedule.add(a)
33+
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.schedule.step()
41+
self.agents.shuffle().do("step")
4242
# collect data
4343
self.datacollector.collect(self)
4444

examples/caching_and_replay/model.py

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

73-
self.schedule = mesa.time.RandomActivation(self)
7473
self.grid = mesa.space.SingleGrid(width, height, torus=True)
7574

7675
self.happy = 0
@@ -87,7 +86,6 @@ def __init__(
8786
agent_type = 1 if self.random.random() < self.minority_pc else 0
8887
agent = SchellingAgent(self.next_id(), self, agent_type)
8988
self.grid.place_agent(agent, pos)
90-
self.schedule.add(agent)
9189

9290
self.datacollector.collect(self)
9391

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

10199
self.datacollector.collect(self)
102100

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

0 commit comments

Comments
 (0)