Skip to content

Commit

Permalink
Replace SimultaneousActivation scheduler by AgentSet
Browse files Browse the repository at this point in the history
The SimultaneousActivation scheduler used a "step" and "advanced" function in the Agent. These have been renamed for each model to be more descriptive (like "determine_state" and "assume_state"), and then the model step was replace by something like:
        self.agents.do("determine_state")
        self.agents.do("assume_state")

Docstring was also updated accordingly.
  • Loading branch information
EwoutH committed Aug 17, 2024
1 parent b7f67c7 commit 7e396fe
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 39 deletions.
20 changes: 7 additions & 13 deletions examples/color_patches/color_patches/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def get_state(self):
"""Return the current state (OPINION) of this cell."""
return self._state

def step(self):
def determine_opinion(self):
"""
Determines the agent opinion for the next step by polling its neighbors
The opinion is determined by the majority of the 8 neighbors' opinion
Expand All @@ -54,7 +54,7 @@ def step(self):

self._next_state = self.random.choice(tied_opinions)[0]

def advance(self):
def assume_opinion(self):
"""
Set the state of the agent to the next state
"""
Expand All @@ -73,7 +73,6 @@ def __init__(self, width=20, height=20):
"""
super().__init__()
self._grid = mesa.space.SingleGrid(width, height, torus=False)
self.schedule = mesa.time.SimultaneousActivation(self)

# self._grid.coord_iter()
# --> should really not return content + col + row
Expand All @@ -91,17 +90,12 @@ def __init__(self, width=20, height=20):

def step(self):
"""
Advance the model one step.
Perform the model step in two stages:
- First, all agents determine their next opinion based on their neighbors current opinions
- Then, all agents update their opinion to the next opinion
"""
self.schedule.step()

# the following is a temporary fix for the framework classes accessing
# model attributes directly
# I don't think it should
# --> it imposes upon the model builder to use the attributes names that
# the framework expects.
#
# Traceback included in docstrings
self.agents.do("determine_opinion")
self.agents.do("assume_opinion")

@property
def grid(self):
Expand Down
4 changes: 2 additions & 2 deletions examples/conways_game_of_life/conways_game_of_life/cell.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def isAlive(self):
def neighbors(self):
return self.model.grid.iter_neighbors((self.x, self.y), True)

def step(self):
def determine_state(self):
"""
Compute if the cell will be dead or alive at the next tick. This is
based on the number of alive or dead neighbors. The state is not
Expand All @@ -46,7 +46,7 @@ def step(self):
if live_neighbors == 3:
self._nextState = self.ALIVE

def advance(self):
def assume_state(self):
"""
Set the state to the new computed state -- computed in step().
"""
Expand Down
16 changes: 5 additions & 11 deletions examples/conways_game_of_life/conways_game_of_life/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,6 @@ def __init__(self, width=50, height=50):
Create a new playing area of (width, height) cells.
"""
super().__init__()

# Set up the grid and schedule.

# Use SimultaneousActivation which simulates all the cells
# computing their next state simultaneously. This needs to
# be done because each cell's next state depends on the current
# state of all its neighbors -- before they've changed.
self.schedule = mesa.time.SimultaneousActivation(self)

# Use a simple grid, where edges wrap around.
self.grid = mesa.space.SingleGrid(width, height, torus=True)

Expand All @@ -39,6 +30,9 @@ def __init__(self, width=50, height=50):

def step(self):
"""
Have the scheduler advance each cell by one step
Perform the model step in two stages:
- First, all cells assume their next state (whether they will be dead or alive)
- Then, all cells change state to their next state
"""
self.schedule.step()
self.agents.do("determine_state")
self.agents.do("assume_state")
6 changes: 3 additions & 3 deletions examples/hex_snowflake/hex_snowflake/cell.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def neighbors(self):
def considered(self):
return self.isConsidered is True

def step(self):
def determine_state(self):
"""
Compute if the cell will be dead or alive at the next tick. A dead
cell will become alive if it has only one neighbor. The state is not
Expand All @@ -53,8 +53,8 @@ def step(self):
for a in self.neighbors:
a.isConsidered = True

def advance(self):
def assume_state(self):
"""
Set the state to the new computed state -- computed in step().
Set the state to the new computed state
"""
self.state = self._nextState
15 changes: 5 additions & 10 deletions examples/hex_snowflake/hex_snowflake/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,6 @@ def __init__(self, width=50, height=50):
Create a new playing area of (width, height) cells.
"""
super().__init__()
# Set up the grid and schedule.

# Use SimultaneousActivation which simulates all the cells
# computing their next state simultaneously. This needs to
# be done because each cell's next state depends on the current
# state of all its neighbors -- before they've changed.
self.schedule = mesa.time.SimultaneousActivation(self)

# Use a hexagonal grid, where edges wrap around.
self.grid = mesa.space.HexSingleGrid(width, height, torus=True)

Expand All @@ -42,6 +34,9 @@ def __init__(self, width=50, height=50):

def step(self):
"""
Have the scheduler advance each cell by one step
Perform the model step in two stages:
- First, all cells assume their next state (whether they will be dead or alive)
- Then, all cells change state to their next state
"""
self.schedule.step()
self.agents.do("determine_state")
self.agents.do("assume_state")

0 comments on commit 7e396fe

Please sign in to comment.