Skip to content

Commit e23b804

Browse files
authored
Replace the remaining schedulers with AgentSet functionality (#202)
This PR completes the migration from schedulers to AgentSet functionality across the mesa-examples repository for all regular (non-`gis`/-`rl`) examples. Key changes include: - Replaced `RandomActivation`, `SimultaneousActivation`, and `RandomActivationByType` schedulers with appropriate AgentSet methods - Updated `Model.step()` implementations to use AgentSet activation - Removed references to `schedule.steps`, `schedule.agents`, and `schedule.agents_by_type` - Updated agent addition/removal logic to work with AgentSets - Adjusted data collection and visualization code to use `Model.steps` and `Model.agents` For more details on migrating from schedulers to AgentSets, see the migration guide: https://mesa.readthedocs.io/en/latest/migration_guide.html#time-and-schedulers
1 parent 0f4b939 commit e23b804

File tree

7 files changed

+28
-26
lines changed

7 files changed

+28
-26
lines changed

examples/advanced/pd_grid/analysis.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
" grid[y][x] = 0\n",
7373
" ax.pcolormesh(grid, cmap=bwr, vmin=0, vmax=1)\n",
7474
" ax.axis(\"off\")\n",
75-
" ax.set_title(f\"Steps: {model.schedule.steps}\")"
75+
" ax.set_title(f\"Steps: {model.steps}\")"
7676
]
7777
},
7878
{

examples/advanced/pd_grid/pd_grid/agent.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def step(self):
3333
best_neighbor = max(neighbors, key=lambda a: a.score)
3434
self.next_move = best_neighbor.move
3535

36-
if self.model.schedule_type != "Simultaneous":
36+
if self.model.activation_order != "Simultaneous":
3737
self.advance()
3838

3939
def advance(self):
@@ -42,7 +42,7 @@ def advance(self):
4242

4343
def increment_score(self):
4444
neighbors = self.model.grid.get_neighbors(self.pos, True)
45-
if self.model.schedule_type == "Simultaneous":
45+
if self.model.activation_order == "Simultaneous":
4646
moves = [neighbor.next_move for neighbor in neighbors]
4747
else:
4848
moves = [neighbor.move for neighbor in neighbors]

examples/advanced/pd_grid/pd_grid/model.py

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,45 +6,39 @@
66
class PdGrid(mesa.Model):
77
"""Model class for iterated, spatial prisoner's dilemma model."""
88

9-
schedule_types = {
10-
"Sequential": mesa.time.BaseScheduler,
11-
"Random": mesa.time.RandomActivation,
12-
"Simultaneous": mesa.time.SimultaneousActivation,
13-
}
9+
activation_regimes = ["Sequential", "Random", "Simultaneous"]
1410

1511
# This dictionary holds the payoff for this agent,
1612
# keyed on: (my_move, other_move)
1713

1814
payoff = {("C", "C"): 1, ("C", "D"): 0, ("D", "C"): 1.6, ("D", "D"): 0}
1915

2016
def __init__(
21-
self, width=50, height=50, schedule_type="Random", payoffs=None, seed=None
17+
self, width=50, height=50, activation_order="Random", payoffs=None, seed=None
2218
):
2319
"""
2420
Create a new Spatial Prisoners' Dilemma Model.
2521
2622
Args:
2723
width, height: Grid size. There will be one agent per grid cell.
28-
schedule_type: Can be "Sequential", "Random", or "Simultaneous".
24+
activation_order: Can be "Sequential", "Random", or "Simultaneous".
2925
Determines the agent activation regime.
3026
payoffs: (optional) Dictionary of (move, neighbor_move) payoffs.
3127
"""
3228
super().__init__()
29+
self.activation_order = activation_order
3330
self.grid = mesa.space.SingleGrid(width, height, torus=True)
34-
self.schedule_type = schedule_type
35-
self.schedule = self.schedule_types[self.schedule_type](self)
3631

3732
# Create agents
3833
for x in range(width):
3934
for y in range(height):
4035
agent = PDAgent(self)
4136
self.grid.place_agent(agent, (x, y))
42-
self.schedule.add(agent)
4337

4438
self.datacollector = mesa.DataCollector(
4539
{
4640
"Cooperating_Agents": lambda m: len(
47-
[a for a in m.schedule.agents if a.move == "C"]
41+
[a for a in m.agents if a.move == "C"]
4842
)
4943
}
5044
)
@@ -53,8 +47,19 @@ def __init__(
5347
self.datacollector.collect(self)
5448

5549
def step(self):
56-
self.schedule.step()
57-
# collect data
50+
# Activate all agents, based on the activation regime
51+
match self.activation_order:
52+
case "Sequential":
53+
self.agents.do("step")
54+
case "Random":
55+
self.agents.shuffle_do("step")
56+
case "Simultaneous":
57+
self.agents.do("step")
58+
self.agents.do("advance")
59+
case _:
60+
raise ValueError(f"Unknown activation order: {self.activation_order}")
61+
62+
# Collect data
5863
self.datacollector.collect(self)
5964

6065
def run(self, n):

examples/advanced/pd_grid/pd_grid/server.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
model_params = {
1010
"height": 50,
1111
"width": 50,
12-
"schedule_type": mesa.visualization.Choice(
13-
"Scheduler type",
12+
"activation_order": mesa.visualization.Choice(
13+
"Activation regime",
1414
value="Random",
15-
choices=list(PdGrid.schedule_types.keys()),
15+
choices=PdGrid.activation_regimes,
1616
),
1717
}
1818

examples/advanced/pd_grid/readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Launch the ``Demographic Prisoner's Dilemma Activation Schedule.ipynb`` notebook
2828
## Files
2929

3030
* ``run.py`` is the entry point for the font-end simulations.
31-
* ``pd_grid/``: contains the model and agent classes; the model takes a ``schedule_type`` string as an argument, which determines what schedule type the model uses: Sequential, Random or Simultaneous.
31+
* ``pd_grid/``: contains the model and agent classes; the model takes a ``activation_order`` string as an argument, which determines in which order agents are activated: Sequential, Random or Simultaneous.
3232
* ``Demographic Prisoner's Dilemma Activation Schedule.ipynb``: Jupyter Notebook for running the scheduling experiment. This runs the model three times, one for each activation type, and demonstrates how the activation regime drives the model to different outcomes.
3333

3434
## Further Reading

examples/advanced/sugarscape_g1mt/tests.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def test_decreasing_price_variance():
2323
model.datacollector._new_model_reporter(
2424
"price_variance",
2525
lambda m: np.var(
26-
flatten([a.prices for a in m.schedule.agents_by_type[Trader].values()])
26+
flatten([a.prices for a in m.agents_by_type[Trader].values()])
2727
),
2828
)
2929
model.run_model(step_count=50)
@@ -40,7 +40,7 @@ def calculate_carrying_capacities(enable_trade):
4040
for vision_max in visions:
4141
model = SugarscapeG1mt(vision_max=vision_max, enable_trade=enable_trade)
4242
model.run_model(step_count=50)
43-
carrying_capacities.append(len(model.schedule.agents_by_type[Trader]))
43+
carrying_capacities.append(len(model.agents_by_type[Trader]))
4444
return carrying_capacities
4545

4646
# Carrying capacity should increase over mean vision (figure IV-6).

examples/advanced/wolf_sheep/wolf_sheep/test_random_walk.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
from mesa import Model
77
from mesa.space import MultiGrid
8-
from mesa.time import RandomActivation
98
from mesa.visualization.TextVisualization import TextGrid, TextVisualization
109
from wolf_sheep.random_walk import RandomWalker
1110

@@ -40,17 +39,15 @@ def __init__(self, width, height, agent_count):
4039
self.grid = MultiGrid(self.width, self.height, torus=True)
4140
self.agent_count = agent_count
4241

43-
self.schedule = RandomActivation(self)
4442
# Create agents
4543
for i in range(self.agent_count):
4644
x = self.random.randrange(self.width)
4745
y = self.random.randrange(self.height)
4846
a = WalkerAgent(i, (x, y), self, True)
49-
self.schedule.add(a)
5047
self.grid.place_agent(a, (x, y))
5148

5249
def step(self):
53-
self.schedule.step()
50+
self.agents.shuffle_do("step")
5451

5552

5653
class WalkerWorldViz(TextVisualization):

0 commit comments

Comments
 (0)