diff --git a/examples/advanced/pd_grid/analysis.ipynb b/examples/advanced/pd_grid/analysis.ipynb index 1fe69759743..e3f52170a1c 100644 --- a/examples/advanced/pd_grid/analysis.ipynb +++ b/examples/advanced/pd_grid/analysis.ipynb @@ -72,7 +72,7 @@ " grid[y][x] = 0\n", " ax.pcolormesh(grid, cmap=bwr, vmin=0, vmax=1)\n", " ax.axis(\"off\")\n", - " ax.set_title(f\"Steps: {model.schedule.steps}\")" + " ax.set_title(f\"Steps: {model.steps}\")" ] }, { diff --git a/examples/advanced/pd_grid/pd_grid/agent.py b/examples/advanced/pd_grid/pd_grid/agent.py index 40e6ca527f0..85121327826 100644 --- a/examples/advanced/pd_grid/pd_grid/agent.py +++ b/examples/advanced/pd_grid/pd_grid/agent.py @@ -33,7 +33,7 @@ def step(self): best_neighbor = max(neighbors, key=lambda a: a.score) self.next_move = best_neighbor.move - if self.model.schedule_type != "Simultaneous": + if self.model.activation_order != "Simultaneous": self.advance() def advance(self): @@ -42,7 +42,7 @@ def advance(self): def increment_score(self): neighbors = self.model.grid.get_neighbors(self.pos, True) - if self.model.schedule_type == "Simultaneous": + if self.model.activation_order == "Simultaneous": moves = [neighbor.next_move for neighbor in neighbors] else: moves = [neighbor.move for neighbor in neighbors] diff --git a/examples/advanced/pd_grid/pd_grid/model.py b/examples/advanced/pd_grid/pd_grid/model.py index cf3512ad036..b1c2a05c257 100644 --- a/examples/advanced/pd_grid/pd_grid/model.py +++ b/examples/advanced/pd_grid/pd_grid/model.py @@ -6,11 +6,7 @@ class PdGrid(mesa.Model): """Model class for iterated, spatial prisoner's dilemma model.""" - schedule_types = { - "Sequential": mesa.time.BaseScheduler, - "Random": mesa.time.RandomActivation, - "Simultaneous": mesa.time.SimultaneousActivation, - } + activation_regimes = ["Sequential", "Random", "Simultaneous"] # This dictionary holds the payoff for this agent, # keyed on: (my_move, other_move) @@ -18,33 +14,31 @@ class PdGrid(mesa.Model): payoff = {("C", "C"): 1, ("C", "D"): 0, ("D", "C"): 1.6, ("D", "D"): 0} def __init__( - self, width=50, height=50, schedule_type="Random", payoffs=None, seed=None + self, width=50, height=50, activation_order="Random", payoffs=None, seed=None ): """ Create a new Spatial Prisoners' Dilemma Model. Args: width, height: Grid size. There will be one agent per grid cell. - schedule_type: Can be "Sequential", "Random", or "Simultaneous". + activation_order: Can be "Sequential", "Random", or "Simultaneous". Determines the agent activation regime. payoffs: (optional) Dictionary of (move, neighbor_move) payoffs. """ super().__init__() + self.activation_order = activation_order self.grid = mesa.space.SingleGrid(width, height, torus=True) - self.schedule_type = schedule_type - self.schedule = self.schedule_types[self.schedule_type](self) # Create agents for x in range(width): for y in range(height): agent = PDAgent(self) self.grid.place_agent(agent, (x, y)) - self.schedule.add(agent) self.datacollector = mesa.DataCollector( { "Cooperating_Agents": lambda m: len( - [a for a in m.schedule.agents if a.move == "C"] + [a for a in m.agents if a.move == "C"] ) } ) @@ -53,8 +47,19 @@ def __init__( self.datacollector.collect(self) def step(self): - self.schedule.step() - # collect data + # Activate all agents, based on the activation regime + match self.activation_order: + case "Sequential": + self.agents.do("step") + case "Random": + self.agents.shuffle_do("step") + case "Simultaneous": + self.agents.do("step") + self.agents.do("advance") + case _: + raise ValueError(f"Unknown activation order: {self.activation_order}") + + # Collect data self.datacollector.collect(self) def run(self, n): diff --git a/examples/advanced/pd_grid/pd_grid/server.py b/examples/advanced/pd_grid/pd_grid/server.py index f2447da37c1..57785acccac 100644 --- a/examples/advanced/pd_grid/pd_grid/server.py +++ b/examples/advanced/pd_grid/pd_grid/server.py @@ -9,10 +9,10 @@ model_params = { "height": 50, "width": 50, - "schedule_type": mesa.visualization.Choice( - "Scheduler type", + "activation_order": mesa.visualization.Choice( + "Activation regime", value="Random", - choices=list(PdGrid.schedule_types.keys()), + choices=PdGrid.activation_regimes, ), } diff --git a/examples/advanced/pd_grid/readme.md b/examples/advanced/pd_grid/readme.md index 8b4bc40c88f..51b91fd4287 100644 --- a/examples/advanced/pd_grid/readme.md +++ b/examples/advanced/pd_grid/readme.md @@ -28,7 +28,7 @@ Launch the ``Demographic Prisoner's Dilemma Activation Schedule.ipynb`` notebook ## Files * ``run.py`` is the entry point for the font-end simulations. -* ``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. +* ``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. * ``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. ## Further Reading diff --git a/examples/advanced/sugarscape_g1mt/tests.py b/examples/advanced/sugarscape_g1mt/tests.py index bcfcf73931d..274afa6bb89 100644 --- a/examples/advanced/sugarscape_g1mt/tests.py +++ b/examples/advanced/sugarscape_g1mt/tests.py @@ -23,7 +23,7 @@ def test_decreasing_price_variance(): model.datacollector._new_model_reporter( "price_variance", lambda m: np.var( - flatten([a.prices for a in m.schedule.agents_by_type[Trader].values()]) + flatten([a.prices for a in m.agents_by_type[Trader].values()]) ), ) model.run_model(step_count=50) @@ -40,7 +40,7 @@ def calculate_carrying_capacities(enable_trade): for vision_max in visions: model = SugarscapeG1mt(vision_max=vision_max, enable_trade=enable_trade) model.run_model(step_count=50) - carrying_capacities.append(len(model.schedule.agents_by_type[Trader])) + carrying_capacities.append(len(model.agents_by_type[Trader])) return carrying_capacities # Carrying capacity should increase over mean vision (figure IV-6). diff --git a/examples/advanced/wolf_sheep/wolf_sheep/test_random_walk.py b/examples/advanced/wolf_sheep/wolf_sheep/test_random_walk.py index d2340fedba3..393a46b18c4 100644 --- a/examples/advanced/wolf_sheep/wolf_sheep/test_random_walk.py +++ b/examples/advanced/wolf_sheep/wolf_sheep/test_random_walk.py @@ -5,7 +5,6 @@ from mesa import Model from mesa.space import MultiGrid -from mesa.time import RandomActivation from mesa.visualization.TextVisualization import TextGrid, TextVisualization from wolf_sheep.random_walk import RandomWalker @@ -40,17 +39,15 @@ def __init__(self, width, height, agent_count): self.grid = MultiGrid(self.width, self.height, torus=True) self.agent_count = agent_count - self.schedule = RandomActivation(self) # Create agents for i in range(self.agent_count): x = self.random.randrange(self.width) y = self.random.randrange(self.height) a = WalkerAgent(i, (x, y), self, True) - self.schedule.add(a) self.grid.place_agent(a, (x, y)) def step(self): - self.schedule.step() + self.agents.shuffle_do("step") class WalkerWorldViz(TextVisualization):