mesa package#

Submodules#

mesa.agent module#

Agent related classes.

Core Objects: Agent and AgentSet.

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

Bases: object

Base class for a model agent in Mesa.

model#

A reference to the model instance.

Type:

Model

unique_id#

A unique identifier for this agent.

Type:

int

pos#

A reference to the position where this agent is located.

Type:

Position

Notes

unique_id is unique relative to a model instance and starts from 1

Create a new agent.

Parameters:
  • model (Model) – The model instance in which the agent exists.

  • args – passed on to super

  • kwargs – passed on to super

Notes

to make proper use of python’s super, in each class remove the arguments and keyword arguments you need and pass on the rest to super

remove() None[source]#

Remove and delete the agent from the model.

Notes

If you need to do additional cleanup when removing an agent by for example removing it from a space, consider extending this method in your own agent class.

step() None[source]#

A single step of the agent.

advance() None[source]#
classmethod create_agents(model: Model, n: int, *args, **kwargs) AgentSet[Agent][source]#

Create N agents.

Parameters:
  • model – the model to which the agents belong

  • args – arguments to pass onto agent instances each arg is either a single object or a sequence of length n

  • n – the number of agents to create

  • kwargs – keyword arguments to pass onto agent instances each keyword arg is either a single object or a sequence of length n

Returns:

AgentSet containing the agents created.

property random: Random#

Return a seeded stdlib rng.

property rng: Generator#

Return a seeded np.random rng.

class AgentSet(agents: Iterable[Agent], random: Random | None = None)[source]#

Bases: MutableSet, Sequence

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.

model#

The ABM model instance to which this AgentSet belongs.

Type:

Model

Notes

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.

Notes

A UserWarning is issued if random=None. You can resolve this warning by explicitly passing a random number generator. In most cases, this will be the seeded random number generator in the model. So, you would do random=self.random in a Model or Agent instance.

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

Parameters:
  • agents (Iterable[Agent]) – An iterable of Agent objects to be included in the set.

  • random (Random) – the random number generator

select(filter_func: Callable[[Agent], bool] | None = None, at_most: int | float = inf, 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.

Parameters:
  • 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.

  • at_most (int | float, optional) – The maximum amount of agents to select. Defaults to infinity. - If an integer, at most the first number of matching agents are selected. - If a float between 0 and 1, at most that fraction of original the agents are selected.

  • 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:

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

Return type:

AgentSet

Notes

  • at_most just return the first n or fraction of agents. To take a random sample, shuffle() beforehand.

  • at_most is an upper limit. When specifying other criteria, the number of agents returned can be smaller.

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

Randomly shuffle the order of agents in the AgentSet.

Parameters:

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

Returns:

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

Return type:

AgentSet

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.

Parameters:
  • 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:

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

Return type:

AgentSet

do(method: str | Callable, *args, **kwargs) AgentSet[source]#

Invoke a method or function on each agent in the AgentSet.

Parameters:
  • method (str, callable) –

    the callable to do on each agent

    • in case of str, the name of the method to call on each agent.

    • in case of callable, the function to be called with each agent as first argument

  • *args – Variable length argument list passed to the callable being called.

  • **kwargs – Arbitrary keyword arguments passed to the callable being called.

Returns:

The results of the callable calls if return_results is True, otherwise the AgentSet itself.

Return type:

AgentSet | list[Any]

shuffle_do(method: str | Callable, *args, **kwargs) AgentSet[source]#

Shuffle the agents in the AgentSet and then invoke a method or function on each agent.

It’s a fast, optimized version of calling shuffle() followed by do().

map(method: str | Callable, *args, **kwargs) list[Any][source]#

Invoke a method or function on each agent in the AgentSet and return the results.

Parameters:
  • method (str, callable) –

    the callable to apply on each agent

    • in case of str, the name of the method to call on each agent.

    • in case of callable, the function to be called with each agent as first argument

  • *args – Variable length argument list passed to the callable being called.

  • **kwargs – Arbitrary keyword arguments passed to the callable being called.

Returns:

The results of the callable calls

Return type:

list[Any]

agg(attribute: str, func: Callable) Any[source]#

Aggregate an attribute of all agents in the AgentSet using a specified function.

Parameters:
  • attribute (str) – The name of the attribute to aggregate.

  • func (Callable) – The function to apply to the attribute values (e.g., min, max, sum, np.mean).

Returns:

The result of applying the function to the attribute values. Often a single value.

Return type:

Any

get(attr_names: str, handle_missing: Literal['error', 'default'] = 'error', default_value: Any = None) list[Any][source]#
get(attr_names: list[str], handle_missing: Literal['error', 'default'] = 'error', default_value: Any = None) list[list[Any]]

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

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

  • handle_missing (str, optional) – How to handle missing attributes. Can be: - ‘error’ (default): raises an AttributeError if attribute is missing. - ‘default’: returns the specified default_value.

  • default_value (Any, optional) – The default value to return if ‘handle_missing’ is set to ‘default’ and the agent does not have the attribute.

Returns:

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

Return type:

list[Any]

Raises:
  • AttributeError – If ‘handle_missing’ is ‘error’ and the agent does not have the specified attribute(s).

  • ValueError – If an unknown ‘handle_missing’ option is provided.

set(attr_name: str, value: Any) AgentSet[source]#

Set a specified attribute to a given value for all agents in the AgentSet.

Parameters:
  • attr_name (str) – The name of the attribute to set.

  • value (Any) – The value to set the attribute to.

Returns:

The AgentSet instance itself, after setting the attribute.

Return type:

AgentSet

add(agent: Agent)[source]#

Add an agent to the AgentSet.

Parameters:

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.

Parameters:

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.

Parameters:

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

Note

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

groupby(by: Callable | str, result_type: str = 'agentset') GroupBy[source]#

Group agents by the specified attribute or return from the callable.

Parameters:
  • by (Callable, str) –

    used to determine what to group agents by

    • if by is a callable, it will be called for each agent and the return is used for grouping

    • if by is a str, it should refer to an attribute on the agent and the value of this attribute will be used for grouping

  • result_type (str, optional) – The datatype for the resulting groups {“agentset”, “list”}

Returns:

GroupBy

Notes: There might be performance benefits to using result_type=’list’ if you don’t need the advanced functionality of an AgentSet.

class GroupBy(groups: dict[Any, list | AgentSet])[source]#

Bases: object

Helper class for AgentSet.groupby.

groups#

A dictionary with the group_name as key and group as values

Type:

dict

Initialize a GroupBy instance.

Parameters:

groups (dict) – A dictionary with the group_name as key and group as values

map(method: Callable | str, *args, **kwargs) dict[Any, Any][source]#

Apply the specified callable to each group and return the results.

Parameters:
  • method (Callable, str) –

    The callable to apply to each group,

    • if method is a callable, it will be called it will be called with the group as first argument

    • if method is a str, it should refer to a method on the group

    Additional arguments and keyword arguments will be passed on to the callable.

  • args – arguments to pass to the callable

  • kwargs – keyword arguments to pass to the callable

Returns:

dict with group_name as key and the return of the method as value

Notes

this method is useful for methods or functions that do return something. It will break method chaining. For that, use do instead.

do(method: Callable | str, *args, **kwargs) GroupBy[source]#

Apply the specified callable to each group.

Parameters:
  • method (Callable, str) –

    The callable to apply to each group,

    • if method is a callable, it will be called it will be called with the group as first argument

    • if method is a str, it should refer to a method on the group

    Additional arguments and keyword arguments will be passed on to the callable.

  • args – arguments to pass to the callable

  • kwargs – keyword arguments to pass to the callable

Returns:

the original GroupBy instance

Notes

this method is useful for methods or functions that don’t return anything and/or if you want to chain multiple do calls

count() dict[Any, int][source]#

Return the count of agents in each group.

Returns:

A dictionary mapping group names to the number of agents in each group.

Return type:

dict

agg(attr_name: str, func: Callable) dict[Hashable, Any][source]#

Aggregate the values of a specific attribute across each group using the provided function.

Parameters:
  • attr_name (str) – The name of the attribute to aggregate.

  • func (Callable) – The function to apply (e.g., sum, min, max, mean).

Returns:

A dictionary mapping group names to the result of applying the aggregation function.

Return type:

dict[Hashable, Any]

mesa.batchrunner module#

batchrunner for running a factorial experiment design over a model.

To take advantage of parallel execution of experiments, batch_run uses multiprocessing if number_processes is larger than 1. It is strongly advised to only run in parallel using a normal python file (so don’t try to do it in a jupyter notebook). Moreover, best practice when using multiprocessing is to put the code inside an if __name__ == '__main__': code black as shown below:

from mesa.batchrunner import batch_run

params = {"width": 10, "height": 10, "N": range(10, 500, 10)}

if __name__ == '__main__':
    results = batch_run(
        MoneyModel,
        parameters=params,
        iterations=5,
        max_steps=100,
        number_processes=None,
        data_collection_period=1,
        display_progress=True,
    )
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_cls (Type[Model]) – The model class to batch-run

  • parameters (Mapping[str, Union[Any, Iterable[Any]]]) – Dictionary with model parameters over which to run the model. You can either pass single values or iterables.

  • number_processes (int, optional) – Number of processes used, by default 1. Set this to None if you want to use all CPUs.

  • iterations (int, optional) – Number of iterations for each parameter combination, by default 1

  • data_collection_period (int, optional) – Number of steps after which data gets collected, by default -1 (end of episode)

  • max_steps (int, optional) – Maximum number of model steps after which the model halts, by default 1000

  • display_progress (bool, optional) – Display batch run process, by default True

Returns:

List[Dict[str, Any]]

Notes

batch_run assumes the model has a datacollector attribute that has a DataCollector object initialized.

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 four types of data: model-level data, agent-level data, agent-type-level data, and tables.

A DataCollector is instantiated with three dictionaries of reporter names and associated variable names or functions for each, one for model-level data, one for agent-level data, and one for agent-type-level data; a fourth 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, and the agent-type-level functions are called on each agent of the specified type.

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 agent’s id and its values.

  • _agenttype_records maps each model step to a dictionary of agent types, each containing a list of each agent’s id and its values.

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

class DataCollector(model_reporters=None, agent_reporters=None, agenttype_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-, agent-, and agent-type-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, agent, and agent-type reporters.

Both model_reporters, agent_reporters, and agenttype_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]]}

Agenttype reporters take a dictionary mapping agent types to dictionaries of reporter names and attributes/funcs/methods, similar to agent_reporters:

{Wolf: {“energy”: lambda a: a.energy}}

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”]}

Parameters:
  • model_reporters – Dictionary of reporter names and attributes/funcs/methods.

  • agent_reporters – Dictionary of reporter names and attributes/funcs/methods.

  • agenttype_reporters – Dictionary of agent types to dictionaries 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.

Parameters:
  • 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_agenttype_vars_dataframe(agent_type)[source]#

Create a pandas DataFrame from the agent-type variables for a specific agent type.

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

Parameters:

agent_type – The type of agent to get the data for.

get_table_dataframe(table_name)[source]#

Create a pandas DataFrame from a particular table.

Parameters:

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, seed: float | None = None, rng: Generator | BitGenerator | int | integer | Sequence[int] | SeedSequence | None = None, **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.

running#

A boolean indicating if the model should continue running.

steps#

the number of times model.step() has been called.

random#

a seeded python.random number generator.

rng#

a seeded numpy.random.Generator

Notes

Model.agents returns the AgentSet containing all agents registered with the model. Changing the content of the AgentSet directly can result in strange behavior. If you want change the composition of this AgentSet, ensure you operate on a copy.

Create a new model.

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

Parameters:
  • args – arguments to pass onto super

  • seed – the seed for the random number generator

  • rng – Pseudorandom number generator state. When rng is None, a new numpy.random.Generator is created using entropy from the operating system. Types other than numpy.random.Generator are passed to numpy.random.default_rng to instantiate a Generator.

  • kwargs – keyword arguments to pass onto super

Notes

you have to pass either seed or rng, but not both.

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 all unique agent types registered with the model.

property agents_by_type: dict[type[Agent], AgentSet]#

A dictionary where the keys are agent types and the values are the corresponding AgentSets.

register_agent(agent)[source]#

Register the agent with the model.

Parameters:

agent – The agent to register.

Notes

This method is called automatically by Agent.__init__, so there is no need to use this if you are subclassing Agent and calling its super in the __init__ method.

deregister_agent(agent)[source]#

Deregister the agent with the model.

Parameters:

agent – The agent to deregister.

Notes

This method is called automatically by Agent.remove

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.

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

Reset the model random number generator.

Parameters:

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

reset_rng(rng: Generator | BitGenerator | int | integer | Sequence[int] | SeedSequence | None = None) None[source]#

Reset the model random number generator.

Parameters:

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

remove_all_agents()[source]#

Remove all agents from the model.

Notes

This method calls agent.remove for all agents in the model. If you need to remove agents from e.g., a SingleGrid, you can either explicitly implement your own agent.remove method or clean this up near where you are calling this method.

mesa.space module#

Mesa Space Module.

Objects used to add a spatial component to a model.

Note

All Grid classes (_Grid, SingleGrid, MultiGrid, HexGrid, etc.) are now in maintenance-only mode. While these classes remain fully supported, new development occurs in the experimental cell space module (mesa.experimental.cell_space).

The PropertyLayer and ContinuousSpace classes remain fully supported and actively developed.

Classes#

  • PropertyLayer: A data layer that can be added to Grids to store cell properties

  • SingleGrid: a Grid which strictly enforces one agent per cell.

  • MultiGrid: a Grid where each cell can contain a set of agents.

  • HexGrid: a 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.

Tuples are wrapped in a single-item list rather than forcing user to do it.

is_integer(x: Real) bool[source]#

Check if x is either a CPython integer or Numpy integer.

warn_if_agent_has_position_already(placement_func)[source]#

Decorator to give warning if agent has position already set.

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.

name#

The name of the property layer.

Type:

str

width#

The width of the grid (number of columns).

Type:

int

height#

The height of the grid (number of rows).

Type:

int

data#

A NumPy array representing the grid data.

Type:

numpy.ndarray

Initializes a new PropertyLayer instance.

Parameters:
  • 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.

propertylayer_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.

Parameters:
  • 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.

Parameters:
  • 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.

Parameters:
  • 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.

Parameters:
  • 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.

Parameters:

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.

Parameters:
  • 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, *args, **kwargs)[source]#
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.

Parameters:
  • 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, *args, **kwargs)[source]#
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.

Parameters:
  • 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.

Parameters:
  • 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.

Parameters:
  • 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.

Parameters:
  • x_max – the maximum x-coordinate

  • y_max – the maximum y-coordinate.

  • torus – Boolean for whether the edges loop around.

  • x_min – (default 0) If provided, set the minimum x -coordinate for the space. Below them, values loop to the other edge (if torus=True) or raise an exception.

  • y_min – (default 0) If provided, set the minimum y -coordinate for the space. Below them, values loop to the other edge (if torus=True) or raise an exception.

property agents: AgentSet#

Return an AgentSet with the agents in the space.

place_agent(agent, *args, **kwargs)[source]#
move_agent(agent: Agent, pos: tuple[float, float] | ndarray[tuple[int, ...], dtype[float]]) None[source]#

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

Parameters:
  • 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.

Parameters:

agent – The agent object to remove

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

Get all agents within a certain radius.

Parameters:
  • 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.

Notes

If 1 or more agents are located on pos, include_center=False will remove all these agents from the results. So, if you really want to get the neighbors of a given agent, you should set include_center=True, and then filter the list of agents to remove the given agent (i.e., self when calling it from an agent).

get_heading(pos_1: tuple[float, float] | ndarray[tuple[int, ...], dtype[float]], pos_2: tuple[float, float] | ndarray[tuple[int, ...], dtype[float]]) tuple[float, float] | ndarray[tuple[int, ...], 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.

Parameters:
  • pos_1 – Coordinate tuples for both points.

  • pos_2 – Coordinate tuples for both points.

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

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

Parameters:
  • pos_1 – Coordinate tuples for point1.

  • pos_2 – Coordinate tuples for point2.

torus_adj(pos: tuple[float, float] | ndarray[tuple[int, ...], dtype[float]]) tuple[float, float] | ndarray[tuple[int, ...], 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.

Parameters:

pos – Coordinate tuple to convert.

out_of_bounds(pos: tuple[float, float] | ndarray[tuple[int, ...], 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.

Parameters:

g – a NetworkX graph instance.

property agents: AgentSet#

Return an AgentSet with the agents in the space.

static default_val() list[source]#

Default value for a new node.

place_agent(agent, *args, **kwargs)[source]#
get_neighborhood(node_id: int, include_center: bool = False, radius: int = 1) list[int][source]#

Get all adjacent nodes within a certain radius.

Parameters:
  • node_id – node id for which to get neighborhood

  • include_center – boolean to include node itself or not

  • radius – size of neighborhood

Returns:

a list

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).

Parameters:
  • node_id – node id for which to get neighbors

  • include_center – whether to include node itself or not

  • radius – size of neighborhood in which to find neighbors

Returns:

list of agents in neighborhood.

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

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

Parameters:
  • agent – agent instance

  • node_id – id of node

remove_agent(agent: Agent) None[source]#

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

Parameters:

agent – agent instance

is_cell_empty(node_id: int) bool[source]#

Returns a bool of the contents of a cell.

Parameters:

node_id – id of node

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.

Parameters:

cell_list – list of cell ids.

Returns:

list of the agents contained in the nodes identified in cell_list.

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.

Parameters:

cell_list – list of cell ids.

Returns:

iterator of the agents contained in the nodes identified in cell_list.

Module contents#

Mesa Agent-Based Modeling Framework.

Core Objects: Model, and Agent.

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

Bases: object

Base class for a model agent in Mesa.

model#

A reference to the model instance.

Type:

Model

unique_id#

A unique identifier for this agent.

Type:

int

pos#

A reference to the position where this agent is located.

Type:

Position

Notes

unique_id is unique relative to a model instance and starts from 1

Create a new agent.

Parameters:
  • model (Model) – The model instance in which the agent exists.

  • args – passed on to super

  • kwargs – passed on to super

Notes

to make proper use of python’s super, in each class remove the arguments and keyword arguments you need and pass on the rest to super

remove() None[source]#

Remove and delete the agent from the model.

Notes

If you need to do additional cleanup when removing an agent by for example removing it from a space, consider extending this method in your own agent class.

step() None[source]#

A single step of the agent.

advance() None[source]#
classmethod create_agents(model: Model, n: int, *args, **kwargs) AgentSet[Agent][source]#

Create N agents.

Parameters:
  • model – the model to which the agents belong

  • args – arguments to pass onto agent instances each arg is either a single object or a sequence of length n

  • n – the number of agents to create

  • kwargs – keyword arguments to pass onto agent instances each keyword arg is either a single object or a sequence of length n

Returns:

AgentSet containing the agents created.

property random: Random#

Return a seeded stdlib rng.

property rng: Generator#

Return a seeded np.random rng.

class DataCollector(model_reporters=None, agent_reporters=None, agenttype_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-, agent-, and agent-type-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, agent, and agent-type reporters.

Both model_reporters, agent_reporters, and agenttype_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]]}

Agenttype reporters take a dictionary mapping agent types to dictionaries of reporter names and attributes/funcs/methods, similar to agent_reporters:

{Wolf: {“energy”: lambda a: a.energy}}

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”]}

Parameters:
  • model_reporters – Dictionary of reporter names and attributes/funcs/methods.

  • agent_reporters – Dictionary of reporter names and attributes/funcs/methods.

  • agenttype_reporters – Dictionary of agent types to dictionaries 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.

Parameters:
  • 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_agenttype_vars_dataframe(agent_type)[source]#

Create a pandas DataFrame from the agent-type variables for a specific agent type.

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

Parameters:

agent_type – The type of agent to get the data for.

get_table_dataframe(table_name)[source]#

Create a pandas DataFrame from a particular table.

Parameters:

table_name – The name of the table to convert.

class Model(*args: Any, seed: float | None = None, rng: Generator | BitGenerator | int | integer | Sequence[int] | SeedSequence | None = None, **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.

running#

A boolean indicating if the model should continue running.

steps#

the number of times model.step() has been called.

random#

a seeded python.random number generator.

rng#

a seeded numpy.random.Generator

Notes

Model.agents returns the AgentSet containing all agents registered with the model. Changing the content of the AgentSet directly can result in strange behavior. If you want change the composition of this AgentSet, ensure you operate on a copy.

Create a new model.

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

Parameters:
  • args – arguments to pass onto super

  • seed – the seed for the random number generator

  • rng – Pseudorandom number generator state. When rng is None, a new numpy.random.Generator is created using entropy from the operating system. Types other than numpy.random.Generator are passed to numpy.random.default_rng to instantiate a Generator.

  • kwargs – keyword arguments to pass onto super

Notes

you have to pass either seed or rng, but not both.

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 all unique agent types registered with the model.

property agents_by_type: dict[type[Agent], AgentSet]#

A dictionary where the keys are agent types and the values are the corresponding AgentSets.

register_agent(agent)[source]#

Register the agent with the model.

Parameters:

agent – The agent to register.

Notes

This method is called automatically by Agent.__init__, so there is no need to use this if you are subclassing Agent and calling its super in the __init__ method.

deregister_agent(agent)[source]#

Deregister the agent with the model.

Parameters:

agent – The agent to deregister.

Notes

This method is called automatically by Agent.remove

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.

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

Reset the model random number generator.

Parameters:

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

reset_rng(rng: Generator | BitGenerator | int | integer | Sequence[int] | SeedSequence | None = None) None[source]#

Reset the model random number generator.

Parameters:

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

remove_all_agents()[source]#

Remove all agents from the model.

Notes

This method calls agent.remove for all agents in the model. If you need to remove agents from e.g., a SingleGrid, you can either explicitly implement your own agent.remove method or clean this up near where you are calling this method.

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_cls (Type[Model]) – The model class to batch-run

  • parameters (Mapping[str, Union[Any, Iterable[Any]]]) – Dictionary with model parameters over which to run the model. You can either pass single values or iterables.

  • number_processes (int, optional) – Number of processes used, by default 1. Set this to None if you want to use all CPUs.

  • iterations (int, optional) – Number of iterations for each parameter combination, by default 1

  • data_collection_period (int, optional) – Number of steps after which data gets collected, by default -1 (end of episode)

  • max_steps (int, optional) – Maximum number of model steps after which the model halts, by default 1000

  • display_progress (bool, optional) – Display batch run process, by default True

Returns:

List[Dict[str, Any]]

Notes

batch_run assumes the model has a datacollector attribute that has a DataCollector object initialized.