Experimental#

This namespace contains experimental features. These are under development, and their API is not necessarily stable.

Devs#

Simulator implementations for different time advancement approaches in Mesa.

Deprecated since version 3.5.0: The Simulator, ABMSimulator, and DEVSimulator classes are deprecated and will be removed in Mesa 4.0. Use the new public methods on Model instead: run_for(), run_until(), schedule_event(), and schedule_recurring(). See https://mesa.readthedocs.io/latest/migration_guide.html#replacing-simulator-classes

This module provides simulator classes that control how simulation time advances and how events are executed. It supports both discrete-time and continuous-time simulations through three main classes:

  • Simulator: Base class defining the core simulation control interface

  • ABMSimulator: A simulator for agent-based models that combines fixed time steps with event scheduling. Uses integer time units and automatically schedules model.step()

  • DEVSimulator: A pure discrete event simulator using floating-point time units for continuous time simulation

Key features: - Flexible time units (integer or float) - Event scheduling using absolute or relative times - Priority-based event execution - Support for running simulations for specific durations or until specific end times

The simulators enable Mesa models to use traditional time-step based approaches, pure event-driven approaches, or hybrid combinations of both.

class Simulator(time_unit: type, start_time: int | float)[source]#

The Simulator controls the time advancement of the model.

The simulator uses next event time progression to advance the simulation time, and execute the next event

event_list#

The list of events to execute

Type:

EventList

time#

The current simulation time

Type:

float | int

time_unit#

The unit of the simulation time

Type:

type

model#

The model to simulate

Type:

Model

Initialize a Simulator instance.

Parameters:
  • time_unit – type of the smulaiton time

  • start_time – the starttime of the simulator

property event_list: EventList#

Return the event list from the model.

property time: float#

Simulator time (deprecated).

setup(model: Model) None[source]#

Set up the simulator with the model to simulate.

Parameters:

model (Model) – The model to simulate

Raises:
  • Exception if simulator.time is not equal to simulator.starttime

  • Exception if event list is not empty

reset()[source]#

Reset the simulator.

run_until(end_time: int | float) None[source]#

Run the simulator until the end time.

Parameters:

end_time (int | float) – The end time for stopping the simulator

Raises:

Exception if simulator.setup() has not yet been called

run_next_event()[source]#

Execute the next event.

Raises:

Exception if simulator.setup() has not yet been called

run_for(time_delta: int | float)[source]#

Run the simulator for the specified time delta.

Parameters:

time_delta (float| int) – The time delta. The simulator is run from the current time to the current time plus the time delta

Raises:

Exception if simulator.setup() has not yet been called

schedule_event_now(function: Callable, priority: Priority = Priority.DEFAULT, function_args: list[Any] | None = None, function_kwargs: dict[str, Any] | None = None) Event[source]#

Schedule event for the current time instant.

Parameters:
  • function (Callable) – The callable to execute for this event

  • priority (Priority) – the priority of the event, optional

  • function_args (List[Any]) – list of arguments for function

  • function_kwargs (Dict[str, Any]) – dict of keyword arguments for function

Returns:

the simulation event that is scheduled

Return type:

Event

schedule_event_absolute(function: Callable, time: int | float, priority: Priority = Priority.DEFAULT, function_args: list[Any] | None = None, function_kwargs: dict[str, Any] | None = None) Event[source]#

Schedule event for the specified time instant.

Parameters:
  • function (Callable) – The callable to execute for this event

  • time (int | float) – the time for which to schedule the event

  • priority (Priority) – the priority of the event, optional

  • function_args (List[Any]) – list of arguments for function

  • function_kwargs (Dict[str, Any]) – dict of keyword arguments for function

Returns:

the simulation event that is scheduled

Return type:

Event

schedule_event_relative(function: Callable, time_delta: int | float, priority: Priority = Priority.DEFAULT, function_args: list[Any] | None = None, function_kwargs: dict[str, Any] | None = None) Event[source]#

Schedule event for the current time plus the time delta.

Parameters:
  • function (Callable) – The callable to execute for this event

  • time_delta (int | float) – the time delta

  • priority (Priority) – the priority of the event, optional

  • function_args (List[Any]) – list of arguments for function

  • function_kwargs (Dict[str, Any]) – dict of keyword arguments for function

Returns:

the simulation event that is scheduled

Return type:

Event

cancel_event(event: Event) None[source]#

Remove the event from the event list.

Parameters:

event (Event) – The simulation event to remove

class ABMSimulator[source]#

This simulator uses incremental time progression, while allowing for additional event scheduling.

Deprecated since version 3.5.0: ABMSimulator is deprecated and will be removed in Mesa 4.0. Use model.run_for(), model.run_until(), and model.schedule_event() instead. See https://mesa.readthedocs.io/latest/migration_guide.html#replacing-simulator-classes

The basic time unit of this simulator is an integer. It schedules model.step for each tick with the highest priority. This implies that by default, model.step is the first event executed at a specific tick. In addition, discrete event scheduling, using integer as the time unit is fully supported, paving the way for hybrid ABM-DEVS simulations.

Initialize a ABM simulator.

setup(model)[source]#

Set up the simulator with the model to simulate.

Parameters:

model (Model) – The model to simulate

check_time_unit(time) bool[source]#

Check whether the time is of the correct unit.

Parameters:

time (int | float) – the time

Returns:

whether the time is of the correct unit

Return type:

bool

schedule_event_next_tick(function: Callable, priority: Priority = Priority.DEFAULT, function_args: list[Any] | None = None, function_kwargs: dict[str, Any] | None = None) Event[source]#

Schedule a Event for the next tick.

Parameters:
  • function (Callable) – the callable to execute

  • priority (Priority) – the priority of the event

  • function_args (List[Any]) – List of arguments to pass to the callable

  • function_kwargs (Dict[str, Any]) – List of keyword arguments to pass to the callable

class DEVSimulator[source]#

A simulator where the unit of time is a float.

Deprecated since version 3.5.0: DEVSimulator is deprecated and will be removed in Mesa 4.0. Use model.run_for(), model.run_until(), model.schedule_event(), and model.schedule_recurring() instead. See https://mesa.readthedocs.io/latest/migration_guide.html#replacing-simulator-classes

Can be used for full-blown discrete event simulating using event scheduling.

Initialize a DEVS simulator.

setup(model: Model) None[source]#

Set up the simulator with the model to simulate.

Parameters:

model (Model) – The model to simulate

check_time_unit(time) bool[source]#

Check whether the time is of the correct unit.

Parameters:

time (float) – the time

Returns: bool: whether the time is of the correct unit

Continuous Space#

A Continuous Space class.

class ContinuousSpace(dimensions: ArrayLike, torus: bool = False, random: Random | None = None, n_agents: int = 100)[source]#

Continuous space where each agent can have an arbitrary position.

Create a new continuous space.

Parameters:
  • dimensions – a numpy array like object where each row specifies the minimum and maximum value of that dimension.

  • torus – boolean for whether the space wraps around or not

  • random – a seeded stdlib random.Random instance

  • n_agents – the expected number of agents in the space

Internally, a numpy array is used to store the positions of all agents. This is resized if needed, but you can control the initial size explicitly by passing n_agents.

property agents: AgentSet#

Return an AgentSet with the agents in the space.

calculate_difference_vector(point: ndarray, agents=None) ndarray[source]#

Calculate the difference vector between the point and all agenents.

Parameters:
  • point – the point to calculate the difference vector for

  • agents – the agents to calculate the difference vector of point with. By default, all agents are considered.

calculate_distances(point: ArrayLike, agents: Iterable[Agent] | None = None, **kwargs) tuple[ndarray, list][source]#

Calculate the distance between the point and all agents.

Parameters:
  • point – the point to calculate the difference vector for

  • agents – the agents to calculate the difference vector of point with. By default, all agents are considered.

  • kwargs – any additional keyword arguments are passed to scipy’s cdist, which is used only if torus is False. This allows for non-Euclidian distance measures.

get_agents_in_radius(point: ArrayLike, radius: float | int = 1) tuple[list, ndarray][source]#

Return the agents and their distances within a radius for the point.

get_k_nearest_agents(point: ArrayLike, k: int = 1) tuple[list, ndarray][source]#

Return the k nearest agents and their distances to the point.

Notes

This method returns exactly k agents, ignoring ties. In case of ties, the earlier an agent is inserted the higher it will rank.

in_bounds(point: ArrayLike) bool[source]#

Check if point is inside the bounds of the space.

torus_correct(point: ArrayLike) ndarray[source]#

Apply a torus correction to the point.

Continuous space agents.

class HasPositionProtocol(*args, **kwargs)[source]#

Protocol for continuous space position holders.

class ContinuousSpaceAgent(space: ContinuousSpace, model)[source]#

A continuous space agent.

space#

the continuous space in which the agent is located

Type:

ContinuousSpace

position#

the position of the agent

Type:

np.ndarray

Initialize a continuous space agent.

Parameters:
  • space – the continuous space in which the agent is located

  • model – the model to which the agent belongs

property position: ndarray#

Position of the agent.

remove() None[source]#

Remove and delete the agent from the model and continuous space.

get_neighbors_in_radius(radius: float | int = 1) tuple[list, ndarray][source]#

Get neighbors within radius.

Parameters:

radius – radius within which to look for neighbors

get_nearest_neighbors(k: int = 1) tuple[list, ndarray][source]#

Get neighbors within radius.

Parameters:

k – the number of nearest neighbors to return

Continuous Space#

A Continuous Space class.

class ContinuousSpace(dimensions: ArrayLike, torus: bool = False, random: Random | None = None, n_agents: int = 100)[source]#

Continuous space where each agent can have an arbitrary position.

Create a new continuous space.

Parameters:
  • dimensions – a numpy array like object where each row specifies the minimum and maximum value of that dimension.

  • torus – boolean for whether the space wraps around or not

  • random – a seeded stdlib random.Random instance

  • n_agents – the expected number of agents in the space

Internally, a numpy array is used to store the positions of all agents. This is resized if needed, but you can control the initial size explicitly by passing n_agents.

property agents: AgentSet#

Return an AgentSet with the agents in the space.

calculate_difference_vector(point: ndarray, agents=None) ndarray[source]#

Calculate the difference vector between the point and all agenents.

Parameters:
  • point – the point to calculate the difference vector for

  • agents – the agents to calculate the difference vector of point with. By default, all agents are considered.

calculate_distances(point: ArrayLike, agents: Iterable[Agent] | None = None, **kwargs) tuple[ndarray, list][source]#

Calculate the distance between the point and all agents.

Parameters:
  • point – the point to calculate the difference vector for

  • agents – the agents to calculate the difference vector of point with. By default, all agents are considered.

  • kwargs – any additional keyword arguments are passed to scipy’s cdist, which is used only if torus is False. This allows for non-Euclidian distance measures.

get_agents_in_radius(point: ArrayLike, radius: float | int = 1) tuple[list, ndarray][source]#

Return the agents and their distances within a radius for the point.

get_k_nearest_agents(point: ArrayLike, k: int = 1) tuple[list, ndarray][source]#

Return the k nearest agents and their distances to the point.

Notes

This method returns exactly k agents, ignoring ties. In case of ties, the earlier an agent is inserted the higher it will rank.

in_bounds(point: ArrayLike) bool[source]#

Check if point is inside the bounds of the space.

torus_correct(point: ArrayLike) ndarray[source]#

Apply a torus correction to the point.

Continuous space agents.

class HasPositionProtocol(*args, **kwargs)[source]#

Protocol for continuous space position holders.

class ContinuousSpaceAgent(space: ContinuousSpace, model)[source]#

A continuous space agent.

space#

the continuous space in which the agent is located

Type:

ContinuousSpace

position#

the position of the agent

Type:

np.ndarray

Initialize a continuous space agent.

Parameters:
  • space – the continuous space in which the agent is located

  • model – the model to which the agent belongs

property position: ndarray#

Position of the agent.

remove() None[source]#

Remove and delete the agent from the model and continuous space.

get_neighbors_in_radius(radius: float | int = 1) tuple[list, ndarray][source]#

Get neighbors within radius.

Parameters:

radius – radius within which to look for neighbors

get_nearest_neighbors(k: int = 1) tuple[list, ndarray][source]#

Get neighbors within radius.

Parameters:

k – the number of nearest neighbors to return

Scenarios#

Base Scenario class.

class Scenario(*, rng: Generator | BitGenerator | int | integer | Sequence[int] | SeedSequence | None = None, **kwargs)[source]#

A Scenario class for defining model parameters and experiments.

Supports both simple instantiation and type-hinted subclassing:

# Simple usage scenario = Scenario(rng=42, density=0.8, minority_pc=0.5)

# Type-hinted subclass (recommended for complex models) class MyScenario(Scenario):

citizen_density: float = 0.7 cop_vision: int = 7 movement: bool = True

scenario = MyScenario(rng=42, cop_vision=10) # Override defaults

model#

The model instance to which this scenario belongs

scenario_id#

A unique identifier for this scenario, auto-generated starting from 0

rng#

Random number generator or seed value

Notes

All parameters are accessible via attribute access (scenario.param). Class-level attributes in subclasses serve as default values. Scenario parameters cannot be modified during model execution.

Initialize a Scenario.

Parameters:
  • rng – Random number generator or valid seed value

  • **kwargs – All other scenario parameters (override class-level defaults)

to_dict() dict[str, Any][source]#

Return dict representation of the scenario.