Mesa Time Module#

Objects for handling the time component of a model. In particular, this module contains Schedulers, which handle agent activation. A Scheduler is an object which controls when agents are called upon to act, and when.

The activation order can have a serious impact on model behavior, so it’s important to specify it explicitly. Example simple activation regimes include activating all agents in the same order every step, shuffling the activation order every time, activating each agent on average once per step, and more.

Key concepts:

Step: Many models advance in ‘steps’. A step may involve the activation of all agents, or a random (or selected) subset of them. Each agent in turn may have their own step() method.

Time: Some models may simulate a continuous ‘clock’ instead of discrete steps. However, by default, the Time is equal to the number of steps the model has taken.

class BaseScheduler(model: Model, agents: Iterable[Agent] | None = None)[source]#

A simple scheduler that activates agents one at a time, in the order they were added.

This scheduler is designed to replicate the behavior of the scheduler in MASON, a multi-agent simulation toolkit. It assumes that each agent added has a step method which takes no arguments and executes the agent’s actions.

Attributes:
  • model (Model): The model instance associated with the scheduler.

  • steps (int): The number of steps the scheduler has taken.

  • time (TimeT): The current time in the simulation. Can be an integer or a float.

Methods:
  • add: Adds an agent to the scheduler.

  • remove: Removes an agent from the scheduler.

  • step: Executes a step, which involves activating each agent once.

  • get_agent_count: Returns the number of agents in the scheduler.

  • agents (property): Returns a list of all agent instances.

Create a new BaseScheduler.

Args:

model (Model): The model to which the schedule belongs agents (Iterable[Agent], None, optional): An iterable of agents who are controlled by the schedule

add(agent: Agent) None[source]#

Add an Agent object to the schedule.

Args:

agent: An Agent to be added to the schedule. NOTE: The agent must have a step() method.

remove(agent: Agent) None[source]#

Remove all instances of a given agent from the schedule.

Note:

It is only necessary to explicitly remove agents from the schedule if the agent is not removed from the model.

Args:

agent: An agent object.

step() None[source]#

Execute the step of all the agents, one at a time.

get_agent_count() int[source]#

Returns the current number of agents in the queue.

class RandomActivation(model: Model, agents: Iterable[Agent] | None = None)[source]#

A scheduler that activates each agent once per step, in a random order, with the order reshuffled each step.

This scheduler is equivalent to the NetLogo ‘ask agents…’ behavior and is a common default for ABMs. It assumes that all agents have a step method.

The random activation ensures that no single agent or sequence of agents consistently influences the model due to ordering effects, which is crucial for certain types of simulations.

Inherits all attributes and methods from BaseScheduler.

Methods:
  • step: Executes a step, activating each agent in a random order.

Create a new BaseScheduler.

Args:

model (Model): The model to which the schedule belongs agents (Iterable[Agent], None, optional): An iterable of agents who are controlled by the schedule

step() None[source]#

Executes the step of all agents, one at a time, in random order.

add(agent: Agent) None#

Add an Agent object to the schedule.

Args:

agent: An Agent to be added to the schedule. NOTE: The agent must have a step() method.

get_agent_count() int#

Returns the current number of agents in the queue.

remove(agent: Agent) None#

Remove all instances of a given agent from the schedule.

Note:

It is only necessary to explicitly remove agents from the schedule if the agent is not removed from the model.

Args:

agent: An agent object.

class SimultaneousActivation(model: Model, agents: Iterable[Agent] | None = None)[source]#

A scheduler that simulates the simultaneous activation of all agents.

This scheduler is unique in that it requires agents to have both step and advance methods. - The step method is for activating the agent and staging any changes without applying them immediately. - The advance method then applies these changes, simulating simultaneous action.

This scheduler is useful in scenarios where the interactions between agents are sensitive to the order of execution, and a quasi-simultaneous execution is more realistic.

Inherits all attributes and methods from BaseScheduler.

Methods:
  • step: Executes a step for all agents, first calling step then advance on each.

Create a new BaseScheduler.

Args:

model (Model): The model to which the schedule belongs agents (Iterable[Agent], None, optional): An iterable of agents who are controlled by the schedule

step() None[source]#

Step all agents, then advance them.

add(agent: Agent) None#

Add an Agent object to the schedule.

Args:

agent: An Agent to be added to the schedule. NOTE: The agent must have a step() method.

get_agent_count() int#

Returns the current number of agents in the queue.

remove(agent: Agent) None#

Remove all instances of a given agent from the schedule.

Note:

It is only necessary to explicitly remove agents from the schedule if the agent is not removed from the model.

Args:

agent: An agent object.

class StagedActivation(model: Model, agents: Iterable[Agent] | None = None, stage_list: list[str] | None = None, shuffle: bool = False, shuffle_between_stages: bool = False)[source]#

A scheduler allowing agent activation to be divided into several stages, with all agents executing one stage before moving on to the next. This class is a generalization of SimultaneousActivation.

This scheduler is useful for complex models where actions need to be broken down into distinct phases for each agent in each time step. Agents must implement methods for each defined stage.

The scheduler also tracks steps and time separately, allowing fractional time increments based on the number of stages. Time advances in fractional increments of 1 / (# of stages), meaning that 1 step = 1 unit of time.

Inherits all attributes and methods from BaseScheduler.

Attributes:
  • stage_list (list[str]): A list of stage names that define the order of execution.

  • shuffle (bool): Determines whether to shuffle the order of agents each step.

  • shuffle_between_stages (bool): Determines whether to shuffle agents between each stage.

Methods:
  • step: Executes all the stages for all agents in the defined order.

Create an empty Staged Activation schedule.

Args:

model (Model): The model to which the schedule belongs agents (Iterable[Agent], None, optional): An iterable of agents who are controlled by the schedule stage_list (list of str): List of strings of names of stages to run, in the

order to run them in.

shuffle (bool, optional): If True, shuffle the order of agents each step. shuffle_between_stages (bool, optional): If True, shuffle the agents after each

stage; otherwise, only shuffle at the start of each step.

step() None[source]#

Executes all the stages for all agents.

add(agent: Agent) None#

Add an Agent object to the schedule.

Args:

agent: An Agent to be added to the schedule. NOTE: The agent must have a step() method.

get_agent_count() int#

Returns the current number of agents in the queue.

remove(agent: Agent) None#

Remove all instances of a given agent from the schedule.

Note:

It is only necessary to explicitly remove agents from the schedule if the agent is not removed from the model.

Args:

agent: An agent object.

class RandomActivationByType(model: Model, agents: Iterable[Agent] | None = None)[source]#

A scheduler that activates each type of agent once per step, in random order, with the order reshuffled every step.

This scheduler is useful for models with multiple types of agents, ensuring that each type is treated equitably in terms of activation order. The randomness in activation order helps in reducing biases due to ordering effects.

Inherits all attributes and methods from BaseScheduler.

If you want to do some computations / data collections specific to an agent type, you can either: - loop through all agents, and filter by their type - access via your_model.scheduler.agents_by_type[your_type_class]

Attributes:
  • agents_by_type (defaultdict): A dictionary mapping agent types to dictionaries of agents.

Methods:
  • step: Executes the step of each agent type in a random order.

  • step_type: Activates all agents of a given type.

  • get_type_count: Returns the count of agents of a specific type.

Create a new BaseScheduler.

Args:

model (Model): The model to which the schedule belongs agents (Iterable[Agent], None, optional): An iterable of agents who are controlled by the schedule

add(agent: Agent) None[source]#

Add an Agent object to the schedule

Args:

agent: An Agent to be added to the schedule.

remove(agent: Agent) None[source]#

Remove all instances of a given agent from the schedule.

step(shuffle_types: bool = True, shuffle_agents: bool = True) None[source]#

Executes the step of each agent type, one at a time, in random order.

Args:
shuffle_types: If True, the order of execution of each types is

shuffled.

shuffle_agents: If True, the order of execution of each agents in a

type group is shuffled.

step_type(agenttype: type[Agent], shuffle_agents: bool = True) None[source]#

Shuffle order and run all agents of a given type. This method is equivalent to the NetLogo ‘ask [breed]…’.

Args:

agenttype: Class object of the type to run.

get_type_count(agenttype: type[Agent]) int[source]#

Returns the current number of agents of certain type in the queue.

get_agent_count() int#

Returns the current number of agents in the queue.

class DiscreteEventScheduler(model: Model, time_step: float | int = 1)[source]#

A scheduler for discrete event simulation in Mesa.

This scheduler manages events where each event is associated with a specific time and agent. The scheduler advances time not in fixed increments, but to the moment the next event is scheduled to occur.

This implementation uses a priority queue (heapq) to manage events. Each event is a tuple of the form (time, random_value, agent), where:

  • time (float): The scheduled time for the event.

  • random_value (float): A secondary sorting criterion to randomize the order of events that are scheduled for the same time.

  • agent (Agent): The agent associated with the event.

The random value for secondary sorting ensures that when two events are scheduled for the same time, their execution order is randomized, thus preventing direct comparison issues between different types of agents and maintaining the integrity of the simulation’s randomness.

Attributes:

model (Model): The model instance associated with the scheduler. event_queue (list): A priority queue of scheduled events. time_step (int or float): The fixed time period by which the model advances

on each step. Defaults to 1.

Methods:

schedule_event(time, agent): Schedule an event for a specific time. schedule_in(delay, agent): Schedule an event after a specified delay. step(): Execute all events within the next time_step period. get_next_event_time(): Returns the time of the next scheduled event.

Usage:
  1. Instantiate the DiscreteEventScheduler with a model instance and a time_step period.

  2. Add agents to the scheduler using schedule.add(). With schedule_now=True (default),

    the first event for the agent will be scheduled immediately.

  3. In the Agent step() method, schedule the next event for the agent

    (using schedule_in or schedule_event).

  1. Add self.schedule.step() to the model’s step() method, as usual.

Now, with each model step, the scheduler will execute all events within the next time_step period, and advance time one time_step forward.

Args:

model (Model): The model to which the schedule belongs time_step (TimeT): The fixed time step between steps

schedule_event(time: float | int, agent: Agent) None[source]#

Schedule an event for an agent at a specific time.

schedule_in(delay: float | int, agent: Agent) None[source]#

Schedule an event for an agent after a specified delay.

step() None[source]#

Execute the next event and advance the time.

get_next_event_time() float | int | None[source]#

Returns the time of the next scheduled event.

add(agent: Agent, schedule_now: bool = True) None[source]#

Add an Agent object to the schedule and optionally schedule its first event.

Args:

agent: An Agent to be added to the schedule. Must have a step() method. schedule_now: If True, schedules the first event for the agent immediately.

get_agent_count() int#

Returns the current number of agents in the queue.

remove(agent: Agent) None#

Remove all instances of a given agent from the schedule.

Note:

It is only necessary to explicitly remove agents from the schedule if the agent is not removed from the model.

Args:

agent: An agent object.