mesa package#

Subpackages#

Submodules#

mesa.agent module#

The agent class for Mesa framework.

Core Objects: Agent

class Agent(unique_id: int, model: Model)[source]#

Bases: object

Base class for a model agent in Mesa.

Attributes:

unique_id (int): A unique identifier for this agent. model (Model): A reference to the model instance. self.pos: Position | None = None

Create a new agent.

Args:

unique_id (int): A unique identifier for this agent. model (Model): The model instance in which the agent exists.

remove() None[source]#

Remove and delete the agent from the model.

step() None[source]#

A single step of the agent.

advance() None[source]#
property random: Random#
class AgentSet(agents: Iterable[Agent], model: Model)[source]#

Bases: MutableSet, Sequence

Warning

The AgentSet is experimental. It may be changed or removed in any and all future releases, including patch releases. We would love to hear what you think about this new feature. If you have any thoughts, share them with us here: projectmesa/mesa#1919

A collection class that represents an ordered set of agents within an agent-based model (ABM). This class extends both MutableSet and Sequence, providing set-like functionality with order preservation and sequence operations.

Attributes:

model (Model): The ABM model instance to which this AgentSet belongs.

Methods:

__len__, __iter__, __contains__, select, shuffle, sort, _update, do, get, __getitem__, add, discard, remove, __getstate__, __setstate__, random

Note:

The AgentSet maintains weak references to agents, allowing for efficient management of agent lifecycles without preventing garbage collection. It is associated with a specific model instance, enabling interactions with the model’s environment and other agents.The implementation uses a WeakKeyDictionary to store agents, which means that agents not referenced elsewhere in the program may be automatically removed from the AgentSet.

Initializes the AgentSet with a collection of agents and a reference to the model.

Args:

agents (Iterable[Agent]): An iterable of Agent objects to be included in the set. model (Model): The ABM model instance to which this AgentSet belongs.

agentset_experimental_warning_given = False#
select(filter_func: Callable[[Agent], bool] | None = None, n: int = 0, inplace: bool = False, agent_type: type[Agent] | None = None) AgentSet[source]#

Select a subset of agents from the AgentSet based on a filter function and/or quantity limit.

Args:
filter_func (Callable[[Agent], bool], optional): A function that takes an Agent and returns True if the

agent should be included in the result. Defaults to None, meaning no filtering is applied.

n (int, optional): The number of agents to select. If 0, all matching agents are selected. Defaults to 0. inplace (bool, optional): If True, modifies the current AgentSet; otherwise, returns a new AgentSet. Defaults to False. agent_type (type[Agent], optional): The class type of the agents to select. Defaults to None, meaning no type filtering is applied.

Returns:

AgentSet: A new AgentSet containing the selected agents, unless inplace is True, in which case the current AgentSet is updated.

shuffle(inplace: bool = False) AgentSet[source]#

Randomly shuffle the order of agents in the AgentSet.

Args:

inplace (bool, optional): If True, shuffles the agents in the current AgentSet; otherwise, returns a new shuffled AgentSet. Defaults to False.

Returns:

AgentSet: A shuffled AgentSet. Returns the current AgentSet if inplace is True.

Note:

Using inplace = True is more performant

sort(key: Callable[[Agent], Any] | str, ascending: bool = False, inplace: bool = False) AgentSet[source]#

Sort the agents in the AgentSet based on a specified attribute or custom function.

Args:

key (Callable[[Agent], Any] | str): A function or attribute name based on which the agents are sorted. ascending (bool, optional): If True, the agents are sorted in ascending order. Defaults to False. inplace (bool, optional): If True, sorts the agents in the current AgentSet; otherwise, returns a new sorted AgentSet. Defaults to False.

Returns:

AgentSet: A sorted AgentSet. Returns the current AgentSet if inplace is True.

do(method_name: str, *args, return_results: bool = False, **kwargs) AgentSet | list[Any][source]#

Invoke a method on each agent in the AgentSet.

Args:

method_name (str): The name of the method to call on each agent. return_results (bool, optional): If True, returns the results of the method calls; otherwise, returns the AgentSet itself. Defaults to False, so you can chain method calls. *args: Variable length argument list passed to the method being called. **kwargs: Arbitrary keyword arguments passed to the method being called.

Returns:

AgentSet | list[Any]: The results of the method calls if return_results is True, otherwise the AgentSet itself.

get(attr_names: str | list[str]) list[Any][source]#

Retrieve the specified attribute(s) from each agent in the AgentSet.

Args:

attr_names (str | list[str]): The name(s) of the attribute(s) to retrieve from each agent.

Returns:

list[Any]: A list with the attribute value for each agent in the set if attr_names is a str list[list[Any]]: A list with a list of attribute values for each agent in the set if attr_names is a list of str

Raises:

AttributeError if an agent does not have the specified attribute(s)

add(agent: Agent)[source]#

Add an agent to the AgentSet.

Args:

agent (Agent): The agent to add to the set.

Note:

This method is an implementation of the abstract method from MutableSet.

discard(agent: Agent)[source]#

Remove an agent from the AgentSet if it exists.

This method does not raise an error if the agent is not present.

Args:

agent (Agent): The agent to remove from the set.

Note:

This method is an implementation of the abstract method from MutableSet.

remove(agent: Agent)[source]#

Remove an agent from the AgentSet.

This method raises an error if the agent is not present.

Args:

agent (Agent): The agent to remove from the set.

Note:

This method is an implementation of the abstract method from MutableSet.

property random: Random#

Provide access to the model’s random number generator.

Returns:

Random: The random number generator associated with the model.

mesa.batchrunner module#

batch_run(model_cls: type[Model], parameters: Mapping[str, Any | Iterable[Any]], number_processes: int | None = 1, iterations: int = 1, data_collection_period: int = -1, max_steps: int = 1000, display_progress: bool = True) list[dict[str, Any]][source]#

Batch run a mesa model with a set of parameter values.

Parameters#

model_clsType[Model]

The model class to batch-run

parametersMapping[str, Union[Any, Iterable[Any]]],

Dictionary with model parameters over which to run the model. You can either pass single values or iterables.

number_processesint, optional

Number of processes used, by default 1. Set this to None if you want to use all CPUs.

iterationsint, optional

Number of iterations for each parameter combination, by default 1

data_collection_periodint, optional

Number of steps after which data gets collected, by default -1 (end of episode)

max_stepsint, optional

Maximum number of model steps after which the model halts, by default 1000

display_progressbool, optional

Display batch run process, by default True

Returns#

List[Dict[str, Any]]

[description]

mesa.datacollection module#

Mesa Data Collection Module#

DataCollector is meant to provide a simple, standard way to collect data generated by a Mesa model. It collects three types of data: model-level data, agent-level data, and tables.

A DataCollector is instantiated with two dictionaries of reporter names and associated variable names or functions for each, one for model-level data and one for agent-level data; a third dictionary provides table names and columns. Variable names are converted into functions which retrieve attributes of that name.

When the collect() method is called, each model-level function is called, with the model as the argument, and the results associated with the relevant variable. Then the agent-level functions are called on each agent.

Additionally, other objects can write directly to tables by passing in an appropriate dictionary object for a table row.

The DataCollector then stores the data it collects in dictionaries:
  • model_vars maps each reporter to a list of its values

  • tables maps each table to a dictionary, with each column as a key with a list as its value.

  • _agent_records maps each model step to a list of each agents id and its values.

Finally, DataCollector can create a pandas DataFrame from each collection.

The default DataCollector here makes several assumptions:
  • The model has an agent list called agents

  • For collecting agent-level variables, agents must have a unique_id

class DataCollector(model_reporters=None, agent_reporters=None, tables=None)[source]#

Bases: object

Class for collecting data generated by a Mesa model.

A DataCollector is instantiated with dictionaries of names of model- and agent-level variables to collect, associated with attribute names or functions which actually collect them. When the collect(…) method is called, it collects these attributes and executes these functions one by one and stores the results.

Instantiate a DataCollector with lists of model and agent reporters. Both model_reporters and agent_reporters accept a dictionary mapping a variable name to either an attribute name, a function, a method of a class/instance, or a function with parameters placed in a list.

Model reporters can take four types of arguments: 1. Lambda function:

{“agent_count”: lambda m: len(m.agents)}

  1. Method of a class/instance: {“agent_count”: self.get_agent_count} # self here is a class instance {“agent_count”: Model.get_agent_count} # Model here is a class

  2. Class attributes of a model: {“model_attribute”: “model_attribute”}

  3. Functions with parameters that have been placed in a list: {“Model_Function”: [function, [param_1, param_2]]}

Agent reporters can similarly take: 1. Attribute name (string) referring to agent’s attribute:

{“energy”: “energy”}

  1. Lambda function: {“energy”: lambda a: a.energy}

  2. Method of an agent class/instance: {“agent_action”: self.do_action} # self here is an agent class instance {“agent_action”: Agent.do_action} # Agent here is a class

  3. Functions with parameters placed in a list: {“Agent_Function”: [function, [param_1, param_2]]}

The tables arg accepts a dictionary mapping names of tables to lists of columns. For example, if we want to allow agents to write their age when they are destroyed (to keep track of lifespans), it might look like:

{“Lifespan”: [“unique_id”, “age”]}

Args:

model_reporters: Dictionary of reporter names and attributes/funcs/methods. agent_reporters: Dictionary of reporter names and attributes/funcs/methods. tables: Dictionary of table names to lists of column names.

Notes:
  • If you want to pickle your model you must not use lambda functions.

  • If your model includes a large number of agents, it is recommended to use attribute names for the agent reporter, as it will be faster.

collect(model)[source]#

Collect all the data for the given model object.

add_table_row(table_name, row, ignore_missing=False)[source]#

Add a row dictionary to a specific table.

Args:

table_name: Name of the table to append a row to. row: A dictionary of the form {column_name: value…} ignore_missing: If True, fill any missing columns with Nones;

if False, throw an error if any columns are missing

get_model_vars_dataframe()[source]#

Create a pandas DataFrame from the model variables.

The DataFrame has one column for each model variable, and the index is (implicitly) the model tick.

get_agent_vars_dataframe()[source]#

Create a pandas DataFrame from the agent variables.

The DataFrame has one column for each variable, with two additional columns for tick and agent_id.

get_table_dataframe(table_name)[source]#

Create a pandas DataFrame from a particular table.

Args:

table_name: The name of the table to convert.

mesa.main module#

mesa.model module#

The model class for Mesa framework.

Core Objects: Model

class Model(*args: Any, **kwargs: Any)[source]#

Bases: object

Base class for models in the Mesa ABM library.

This class serves as a foundational structure for creating agent-based models. It includes the basic attributes and methods necessary for initializing and running a simulation model.

Attributes:

running: A boolean indicating if the model should continue running. schedule: An object to manage the order and execution of agent steps. current_id: A counter for assigning unique IDs to agents. agents_: A defaultdict mapping each agent type to a dict of its instances.

This private attribute is used internally to manage agents.

Properties:

agents: An AgentSet containing all agents in the model, generated from the _agents attribute. agent_types: A list of different agent types present in the model.

Methods:

get_agents_of_type: Returns an AgentSet of agents of the specified type. run_model: Runs the model’s simulation until a defined end condition is reached. step: Executes a single step of the model’s simulation process. next_id: Generates and returns the next unique identifier for an agent. reset_randomizer: Resets the model’s random number generator with a new or existing seed. initialize_data_collector: Sets up the data collector for the model, requiring an initialized scheduler and agents.

Create a new model. Overload this method with the actual code to start the model. Always start with super().__init__() to initialize the model object properly.

property agents: AgentSet#

Provides an AgentSet of all agents in the model, combining agents from all types.

property agent_types: list[type]#

Return a list of different agent types.

get_agents_of_type(agenttype: type[Agent]) AgentSet[source]#

Retrieves an AgentSet containing all agents of the specified type.

run_model() None[source]#

Run the model until the end condition is reached. Overload as needed.

step() None[source]#

A single step. Fill in here.

next_id() int[source]#

Return the next unique ID for agents, increment current_id

reset_randomizer(seed: int | None = None) None[source]#

Reset the model random number generator.

Args:

seed: A new seed for the RNG; if None, reset using the current seed

initialize_data_collector(model_reporters=None, agent_reporters=None, tables=None) None[source]#

mesa.space module#

Mesa Space Module#

Objects used to add a spatial component to a model.

Grid: base grid, which creates a rectangular grid. SingleGrid: extension to Grid which strictly enforces one agent per cell. MultiGrid: extension to Grid where each cell can contain a set of agents. HexGrid: extension to Grid to handle hexagonal neighbors. ContinuousSpace: a two-dimensional space where each agent has an arbitrary

position of float’s.

NetworkGrid: a network where each node contains zero or more agents.

accept_tuple_argument(wrapped_function: F) F[source]#

Decorator to allow grid methods that take a list of (x, y) coord tuples to also handle a single position, by automatically wrapping tuple in single-item list rather than forcing user to do it.

is_integer(x: Real) bool[source]#
is_single_argument_function(function)[source]#

Check if a function is a single argument function.

ufunc_requires_additional_input(ufunc)[source]#
class PropertyLayer(name: str, width: int, height: int, default_value, dtype=<class 'numpy.float64'>)[source]#

Bases: object

A class representing a layer of properties in a two-dimensional grid. Each cell in the grid can store a value of a specified data type.

Attributes:

name (str): The name of the property layer. width (int): The width of the grid (number of columns). height (int): The height of the grid (number of rows). data (numpy.ndarray): A NumPy array representing the grid data.

Methods:

set_cell(position, value): Sets the value of a single cell. set_cells(value, condition=None): Sets the values of multiple cells, optionally based on a condition. modify_cell(position, operation, value): Modifies the value of a single cell using an operation. modify_cells(operation, value, condition_function): Modifies the values of multiple cells using an operation. select_cells(condition, return_list): Selects cells that meet a specified condition. aggregate_property(operation): Performs an aggregate operation over all cells.

Initializes a new PropertyLayer instance.

Args:

name (str): The name of the property layer. width (int): The width of the grid (number of columns). Must be a positive integer. height (int): The height of the grid (number of rows). Must be a positive integer. default_value: The default value to initialize each cell in the grid. Should ideally

be of the same type as specified by the dtype parameter.

dtype (data-type, optional): The desired data-type for the grid’s elements. Default is np.float64.

Raises:

ValueError: If width or height is not a positive integer.

Notes:

A UserWarning is raised if the default_value is not of a type compatible with dtype. The dtype parameter can accept both Python data types (like bool, int or float) and NumPy data types (like np.int64 or np.float64). Using NumPy data types is recommended (except for bool) for better control over the precision and efficiency of data storage and computations, especially in cases of large data volumes or specialized numerical operations.

agentset_experimental_warning_given = False#
set_cell(position: tuple[int, int], value)[source]#

Update a single cell’s value in-place.

set_cells(value, condition=None)[source]#

Perform a batch update either on the entire grid or conditionally, in-place.

Args:

value: The value to be used for the update. condition: (Optional) A callable (like a lambda function or a NumPy ufunc)

that returns a boolean array when applied to the data.

modify_cell(position: tuple[int, int], operation, value=None)[source]#

Modify a single cell using an operation, which can be a lambda function or a NumPy ufunc. If a NumPy ufunc is used, an additional value should be provided.

Args:

position: The grid coordinates of the cell to modify. operation: A function to apply. Can be a lambda function or a NumPy ufunc. value: The value to be used if the operation is a NumPy ufunc. Ignored for lambda functions.

modify_cells(operation, value=None, condition_function=None)[source]#

Modify cells using an operation, which can be a lambda function or a NumPy ufunc. If a NumPy ufunc is used, an additional value should be provided.

Args:

operation: A function to apply. Can be a lambda function or a NumPy ufunc. value: The value to be used if the operation is a NumPy ufunc. Ignored for lambda functions. condition_function: (Optional) A callable that returns a boolean array when applied to the data.

select_cells(condition, return_list=True)[source]#

Find cells that meet a specified condition using NumPy’s boolean indexing, in-place.

Args:

condition: A callable that returns a boolean array when applied to the data. return_list: (Optional) If True, return a list of (x, y) tuples. Otherwise, return a boolean array.

Returns:

A list of (x, y) tuples or a boolean array.

aggregate_property(operation)[source]#

Perform an aggregate operation (e.g., sum, mean) on a property across all cells.

Args:

operation: A function to apply. Can be a lambda function or a NumPy ufunc.

class SingleGrid(width: int, height: int, torus: bool, property_layers: None | PropertyLayer | list[PropertyLayer] = None)[source]#

Bases: _PropertyGrid

Rectangular grid where each cell contains exactly at most one agent.

Grid cells are indexed by [x, y], where [0, 0] is assumed to be the bottom-left and [width-1, height-1] is the top-right. If a grid is toroidal, the top and bottom, and left and right, edges wrap to each other.

This class provides a property empties that returns a set of coordinates for all empty cells in the grid. It is automatically updated whenever agents are added or removed from the grid. The empties property should be used for efficient access to current empty cells rather than manually iterating over the grid to check for emptiness.

Properties:

width, height: The grid’s width and height. torus: Boolean which determines whether to treat the grid as a torus. empties: Returns a set of (x, y) tuples for all empty cells. This set is

maintained internally and provides a performant way to query the grid for empty spaces.

Initializes a new _PropertyGrid instance with specified dimensions and optional property layers.

Args:

width (int): The width of the grid (number of columns). height (int): The height of the grid (number of rows). torus (bool): A boolean indicating if the grid should behave like a torus. property_layers (None | PropertyLayer | list[PropertyLayer], optional): A single PropertyLayer instance,

a list of PropertyLayer instances, or None to initialize without any property layers.

Raises:

ValueError: If a property layer’s dimensions do not match the grid dimensions.

place_agent(agent: Agent, pos: tuple[int, int]) None[source]#

Place the agent at the specified location, and set its pos variable.

remove_agent(agent: Agent) None[source]#

Remove the agent from the grid and set its pos attribute to None.

class MultiGrid(width: int, height: int, torus: bool, property_layers: None | PropertyLayer | list[PropertyLayer] = None)[source]#

Bases: _PropertyGrid

Rectangular grid where each cell can contain more than one agent.

Grid cells are indexed by [x, y], where [0, 0] is assumed to be at bottom-left and [width-1, height-1] is the top-right. If a grid is toroidal, the top and bottom, and left and right, edges wrap to each other.

This class maintains an empties property, which is a set of coordinates for all cells that currently contain no agents. This property is updated automatically as agents are added to or removed from the grid.

Properties:

width, height: The grid’s width and height. torus: Boolean which determines whether to treat the grid as a torus. empties: Returns a set of (x, y) tuples for all empty cells.

Initializes a new _PropertyGrid instance with specified dimensions and optional property layers.

Args:

width (int): The width of the grid (number of columns). height (int): The height of the grid (number of rows). torus (bool): A boolean indicating if the grid should behave like a torus. property_layers (None | PropertyLayer | list[PropertyLayer], optional): A single PropertyLayer instance,

a list of PropertyLayer instances, or None to initialize without any property layers.

Raises:

ValueError: If a property layer’s dimensions do not match the grid dimensions.

grid: list[list[list[Agent]]]#
static default_val() list[Agent][source]#

Default value for new cell elements.

place_agent(agent: Agent, pos: tuple[int, int]) None[source]#

Place the agent at the specified location, and set its pos variable.

remove_agent(agent: Agent) None[source]#

Remove the agent from the given location and set its pos attribute to None.

iter_neighbors(pos: tuple[int, int], moore: bool, include_center: bool = False, radius: int = 1) Iterator[Agent][source]#

Return an iterator over neighbors to a certain point.

Args:

pos: Coordinates for the neighborhood to get. moore: If True, return Moore neighborhood

(including diagonals)

If False, return Von Neumann neighborhood

(exclude diagonals)

include_center: If True, return the (x, y) cell as well.

Otherwise, return surrounding cells only.

radius: radius, in cells, of neighborhood to get.

Returns:

An iterator of non-None objects in the given neighborhood; at most 9 if Moore, 5 if Von-Neumann (8 and 4 if not including the center).

iter_cell_list_contents(positions) Any[source]#
class HexSingleGrid(width: int, height: int, torus: bool, property_layers: None | PropertyLayer | list[PropertyLayer] = None)[source]#

Bases: _HexGrid, SingleGrid

Hexagonal SingleGrid: a SingleGrid where neighbors are computed according to a hexagonal tiling of the grid.

Functions according to odd-q rules. See http://www.redblobgames.com/grids/hexagons/#coordinates for more.

This class also maintains an empties property, similar to SingleGrid, which provides a set of coordinates for all empty hexagonal cells.

Properties:

width, height: The grid’s width and height. torus: Boolean which determines whether to treat the grid as a torus. empties: Returns a set of hexagonal coordinates for all empty cells.

Initializes a new _PropertyGrid instance with specified dimensions and optional property layers.

Args:

width (int): The width of the grid (number of columns). height (int): The height of the grid (number of rows). torus (bool): A boolean indicating if the grid should behave like a torus. property_layers (None | PropertyLayer | list[PropertyLayer], optional): A single PropertyLayer instance,

a list of PropertyLayer instances, or None to initialize without any property layers.

Raises:

ValueError: If a property layer’s dimensions do not match the grid dimensions.

class HexMultiGrid(width: int, height: int, torus: bool, property_layers: None | PropertyLayer | list[PropertyLayer] = None)[source]#

Bases: _HexGrid, MultiGrid

Hexagonal MultiGrid: a MultiGrid where neighbors are computed according to a hexagonal tiling of the grid.

Functions according to odd-q rules. See http://www.redblobgames.com/grids/hexagons/#coordinates for more.

Similar to the standard MultiGrid, this class maintains an empties property, which is a set of coordinates for all hexagonal cells that currently contain no agents. This property is updated automatically as agents are added to or removed from the grid.

Properties:

width, height: The grid’s width and height. torus: Boolean which determines whether to treat the grid as a torus. empties: Returns a set of hexagonal coordinates for all empty cells.

Initializes a new _PropertyGrid instance with specified dimensions and optional property layers.

Args:

width (int): The width of the grid (number of columns). height (int): The height of the grid (number of rows). torus (bool): A boolean indicating if the grid should behave like a torus. property_layers (None | PropertyLayer | list[PropertyLayer], optional): A single PropertyLayer instance,

a list of PropertyLayer instances, or None to initialize without any property layers.

Raises:

ValueError: If a property layer’s dimensions do not match the grid dimensions.

class HexGrid(width: int, height: int, torus: bool)[source]#

Bases: HexSingleGrid

Hexagonal Grid: a Grid where neighbors are computed according to a hexagonal tiling of the grid.

Functions according to odd-q rules. See http://www.redblobgames.com/grids/hexagons/#coordinates for more.

Properties:

width, height: The grid’s width and height. torus: Boolean which determines whether to treat the grid as a torus.

Initializes a new _PropertyGrid instance with specified dimensions and optional property layers.

Args:

width (int): The width of the grid (number of columns). height (int): The height of the grid (number of rows). torus (bool): A boolean indicating if the grid should behave like a torus. property_layers (None | PropertyLayer | list[PropertyLayer], optional): A single PropertyLayer instance,

a list of PropertyLayer instances, or None to initialize without any property layers.

Raises:

ValueError: If a property layer’s dimensions do not match the grid dimensions.

class ContinuousSpace(x_max: float, y_max: float, torus: bool, x_min: float = 0, y_min: float = 0)[source]#

Bases: object

Continuous space where each agent can have an arbitrary position.

Assumes that all agents have a pos property storing their position as an (x, y) tuple.

This class uses a numpy array internally to store agents in order to speed up neighborhood lookups. This array is calculated on the first neighborhood lookup, and is updated if agents are added or removed.

The concept of ‘empty cells’ is not directly applicable in continuous space, as positions are not discretized.

Create a new continuous space.

Args:

x_max, y_max: Maximum x and y coordinates for the space. torus: Boolean for whether the edges loop around. x_min, y_min: (default 0) If provided, set the minimum x and y

coordinates for the space. Below them, values loop to the other edge (if torus=True) or raise an exception.

place_agent(agent: Agent, pos: tuple[float, float] | ndarray[Any, dtype[float]]) None[source]#

Place a new agent in the space.

Args:

agent: Agent object to place. pos: Coordinate tuple for where to place the agent.

move_agent(agent: Agent, pos: tuple[float, float] | ndarray[Any, dtype[float]]) None[source]#

Move an agent from its current position to a new position.

Args:

agent: The agent object to move. pos: Coordinate tuple to move the agent to.

remove_agent(agent: Agent) None[source]#

Remove an agent from the space.

Args:

agent: The agent object to remove

get_neighbors(pos: tuple[float, float] | ndarray[Any, dtype[float]], radius: float, include_center: bool = True) list[Agent][source]#

Get all agents within a certain radius.

Args:

pos: (x,y) coordinate tuple to center the search at. radius: Get all the objects within this distance of the center. include_center: If True, include an object at the exact provided

coordinates. i.e. if you are searching for the neighbors of a given agent, True will include that agent in the results.

get_heading(pos_1: tuple[float, float] | ndarray[Any, dtype[float]], pos_2: tuple[float, float] | ndarray[Any, dtype[float]]) tuple[float, float] | ndarray[Any, dtype[float]][source]#

Get the heading vector between two points, accounting for toroidal space. It is possible to calculate the heading angle by applying the atan2 function to the result.

Args:

pos_1, pos_2: Coordinate tuples for both points.

get_distance(pos_1: tuple[float, float] | ndarray[Any, dtype[float]], pos_2: tuple[float, float] | ndarray[Any, dtype[float]]) float[source]#

Get the distance between two point, accounting for toroidal space.

Args:

pos_1, pos_2: Coordinate tuples for both points.

torus_adj(pos: tuple[float, float] | ndarray[Any, dtype[float]]) tuple[float, float] | ndarray[Any, dtype[float]][source]#

Adjust coordinates to handle torus looping.

If the coordinate is out-of-bounds and the space is toroidal, return the corresponding point within the space. If the space is not toroidal, raise an exception.

Args:

pos: Coordinate tuple to convert.

out_of_bounds(pos: tuple[float, float] | ndarray[Any, dtype[float]]) bool[source]#

Check if a point is out of bounds.

class NetworkGrid(g: Any)[source]#

Bases: object

Network Grid where each node contains zero or more agents.

Create a new network.

Args:

G: a NetworkX graph instance.

static default_val() list[source]#

Default value for a new node.

place_agent(agent: Agent, node_id: int) None[source]#

Place an agent in a node.

get_neighborhood(node_id: int, include_center: bool = False, radius: int = 1) list[int][source]#

Get all adjacent nodes within a certain radius

get_neighbors(node_id: int, include_center: bool = False, radius: int = 1) list[Agent][source]#

Get all agents in adjacent nodes (within a certain radius).

move_agent(agent: Agent, node_id: int) None[source]#

Move an agent from its current node to a new node.

remove_agent(agent: Agent) None[source]#

Remove the agent from the network and set its pos attribute to None.

is_cell_empty(node_id: int) bool[source]#

Returns a bool of the contents of a cell.

get_cell_list_contents(cell_list: list[int]) list[Agent][source]#

Returns a list of the agents contained in the nodes identified in cell_list; nodes with empty content are excluded.

get_all_cell_contents() list[Agent][source]#

Returns a list of all the agents in the network.

iter_cell_list_contents(cell_list: list[int]) Iterator[Agent][source]#

Returns an iterator of the agents contained in the nodes identified in cell_list; nodes with empty content are excluded.

mesa.time module#

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]#

Bases: object

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.

property agents: AgentSet#
get_agent_keys(shuffle: bool = False) list[int][source]#
do_each(method, shuffle=False)[source]#
class RandomActivation(model: Model, agents: Iterable[Agent] | None = None)[source]#

Bases: BaseScheduler

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.

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

Bases: BaseScheduler

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.

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

Bases: BaseScheduler

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.

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

Bases: BaseScheduler

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

property agents_by_type#
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.

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

Bases: BaseScheduler

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.

Module contents#

Mesa Agent-Based Modeling Framework

Core Objects: Model, and Agent.

class Model(*args: Any, **kwargs: Any)[source]#

Bases: object

Base class for models in the Mesa ABM library.

This class serves as a foundational structure for creating agent-based models. It includes the basic attributes and methods necessary for initializing and running a simulation model.

Attributes:

running: A boolean indicating if the model should continue running. schedule: An object to manage the order and execution of agent steps. current_id: A counter for assigning unique IDs to agents. agents_: A defaultdict mapping each agent type to a dict of its instances.

This private attribute is used internally to manage agents.

Properties:

agents: An AgentSet containing all agents in the model, generated from the _agents attribute. agent_types: A list of different agent types present in the model.

Methods:

get_agents_of_type: Returns an AgentSet of agents of the specified type. run_model: Runs the model’s simulation until a defined end condition is reached. step: Executes a single step of the model’s simulation process. next_id: Generates and returns the next unique identifier for an agent. reset_randomizer: Resets the model’s random number generator with a new or existing seed. initialize_data_collector: Sets up the data collector for the model, requiring an initialized scheduler and agents.

Create a new model. Overload this method with the actual code to start the model. Always start with super().__init__() to initialize the model object properly.

property agents: AgentSet#

Provides an AgentSet of all agents in the model, combining agents from all types.

property agent_types: list[type]#

Return a list of different agent types.

get_agents_of_type(agenttype: type[Agent]) AgentSet[source]#

Retrieves an AgentSet containing all agents of the specified type.

run_model() None[source]#

Run the model until the end condition is reached. Overload as needed.

step() None[source]#

A single step. Fill in here.

next_id() int[source]#

Return the next unique ID for agents, increment current_id

reset_randomizer(seed: int | None = None) None[source]#

Reset the model random number generator.

Args:

seed: A new seed for the RNG; if None, reset using the current seed

initialize_data_collector(model_reporters=None, agent_reporters=None, tables=None) None[source]#
class Agent(unique_id: int, model: Model)[source]#

Bases: object

Base class for a model agent in Mesa.

Attributes:

unique_id (int): A unique identifier for this agent. model (Model): A reference to the model instance. self.pos: Position | None = None

Create a new agent.

Args:

unique_id (int): A unique identifier for this agent. model (Model): The model instance in which the agent exists.

remove() None[source]#

Remove and delete the agent from the model.

step() None[source]#

A single step of the agent.

advance() None[source]#
property random: Random#
class DataCollector(model_reporters=None, agent_reporters=None, tables=None)[source]#

Bases: object

Class for collecting data generated by a Mesa model.

A DataCollector is instantiated with dictionaries of names of model- and agent-level variables to collect, associated with attribute names or functions which actually collect them. When the collect(…) method is called, it collects these attributes and executes these functions one by one and stores the results.

Instantiate a DataCollector with lists of model and agent reporters. Both model_reporters and agent_reporters accept a dictionary mapping a variable name to either an attribute name, a function, a method of a class/instance, or a function with parameters placed in a list.

Model reporters can take four types of arguments: 1. Lambda function:

{“agent_count”: lambda m: len(m.agents)}

  1. Method of a class/instance: {“agent_count”: self.get_agent_count} # self here is a class instance {“agent_count”: Model.get_agent_count} # Model here is a class

  2. Class attributes of a model: {“model_attribute”: “model_attribute”}

  3. Functions with parameters that have been placed in a list: {“Model_Function”: [function, [param_1, param_2]]}

Agent reporters can similarly take: 1. Attribute name (string) referring to agent’s attribute:

{“energy”: “energy”}

  1. Lambda function: {“energy”: lambda a: a.energy}

  2. Method of an agent class/instance: {“agent_action”: self.do_action} # self here is an agent class instance {“agent_action”: Agent.do_action} # Agent here is a class

  3. Functions with parameters placed in a list: {“Agent_Function”: [function, [param_1, param_2]]}

The tables arg accepts a dictionary mapping names of tables to lists of columns. For example, if we want to allow agents to write their age when they are destroyed (to keep track of lifespans), it might look like:

{“Lifespan”: [“unique_id”, “age”]}

Args:

model_reporters: Dictionary of reporter names and attributes/funcs/methods. agent_reporters: Dictionary of reporter names and attributes/funcs/methods. tables: Dictionary of table names to lists of column names.

Notes:
  • If you want to pickle your model you must not use lambda functions.

  • If your model includes a large number of agents, it is recommended to use attribute names for the agent reporter, as it will be faster.

collect(model)[source]#

Collect all the data for the given model object.

add_table_row(table_name, row, ignore_missing=False)[source]#

Add a row dictionary to a specific table.

Args:

table_name: Name of the table to append a row to. row: A dictionary of the form {column_name: value…} ignore_missing: If True, fill any missing columns with Nones;

if False, throw an error if any columns are missing

get_model_vars_dataframe()[source]#

Create a pandas DataFrame from the model variables.

The DataFrame has one column for each model variable, and the index is (implicitly) the model tick.

get_agent_vars_dataframe()[source]#

Create a pandas DataFrame from the agent variables.

The DataFrame has one column for each variable, with two additional columns for tick and agent_id.

get_table_dataframe(table_name)[source]#

Create a pandas DataFrame from a particular table.

Args:

table_name: The name of the table to convert.

batch_run(model_cls: type[Model], parameters: Mapping[str, Any | Iterable[Any]], number_processes: int | None = 1, iterations: int = 1, data_collection_period: int = -1, max_steps: int = 1000, display_progress: bool = True) list[dict[str, Any]][source]#

Batch run a mesa model with a set of parameter values.

Parameters#

model_clsType[Model]

The model class to batch-run

parametersMapping[str, Union[Any, Iterable[Any]]],

Dictionary with model parameters over which to run the model. You can either pass single values or iterables.

number_processesint, optional

Number of processes used, by default 1. Set this to None if you want to use all CPUs.

iterationsint, optional

Number of iterations for each parameter combination, by default 1

data_collection_periodint, optional

Number of steps after which data gets collected, by default -1 (end of episode)

max_stepsint, optional

Maximum number of model steps after which the model halts, by default 1000

display_progressbool, optional

Display batch run process, by default True

Returns#

List[Dict[str, Any]]

[description]