Mesa is a Python-based framework for agent-based modeling (ABM). It offers built-in core components from which one can quickly setup and customize the implementation of an ABM. Furthermore, Mesa has built-in tools for data collection and analysis of the results obtained from the ABM simulations.
import mesaMesa contains three categories of modules:
Modeling: Modules used to build the models themselves: a model and agent classes, a scheduler to determine the sequence in which the agents act, and space for them to move around on.
Analysis: Tools to collect data generated from your model, or to run it multiple times with different parameter values.
Visualization: Classes to create and launch an interactive model visualization, using a server with a JavaScript interface.
Agent¶
First create one or more agent classes based on the mesa.Agent base class.
Agents are the individual entities that act in the model. Mesa automatically assigns to each agent that is created an integer acting as a unique_id.
The agents can have attributes and methods. One or more methods may be intended to be called when time steps are taken in the model. We here implement the step() method for that purpose.
class Predator(mesa.Agent):
def __init__(self, model, age=0, strength=100):
super().__init__(model) # parent class initialization
self.type = "predator"
self.age = age
self.strength = strength
def step(self):
self.age += 1
self.strength -= 10
print(f"agent: {self.unique_id}, age: {self.age}, strength: {self.strength}")class Prey(mesa.Agent):
def __init__(self, model, age=0, food_value=50):
super().__init__(model) # parent class initialization
self.type = "prey"
self.age = age
self.food_value = food_value
def step(self):
self.age += 1
self.food_value += 1
print(
f"agent: {self.unique_id}, age: {self.age}, food value: {self.food_value}"
)Model¶
Next, create the model. This gives us the two basic classes of any ABM namely the agent class (population of agent objects that doing something) and the manager class (a model object that manages the creation, activation, data collection etc of the agents).
The model can be visualized as a list containing all the agents. The model creates, holds and manages all the agent objects, specifically in a dictionary. The model activates agents in discrete time steps.
A model is created as a derived class that extends mesa.Model. Agents can be added to the model upon its creation by doing so in the __init__() function. Here we instead implement specific functions for adding agents after the creation of the model.
The step() method of the model class handles the time propagation carried out with the model.agents.shuffle_do() method. The name of the step() method of the model cannot be changed.
class EcoSystem(mesa.Model):
def __init__(self):
super().__init__() # parent class initialization
def add_predators(self, number_predators=1):
Predator.create_agents(self, n=number_predators)
def add_prey(self, number_prey=1):
Prey.create_agents(self, n=number_prey)
def step(self):
print("model step")
self.agents.shuffle_do("step")Time propagation¶
Create an instance of the model.
my_model = EcoSystem()Add agents to the ABM.
my_model.add_predators(1)
my_model.add_prey(3)Time propagate the ABM a certain number of discrete time steps. The shuffle_do() function will time propagate agents in random order. This is normally what you want to do, but ordered activation is also available with the do() function.
my_model.run_for(5)model step
agent: 4, age: 1, food value: 51
agent: 2, age: 1, food value: 51
agent: 3, age: 1, food value: 51
agent: 1, age: 1, strength: 90
model step
agent: 4, age: 2, food value: 52
agent: 1, age: 2, strength: 80
agent: 3, age: 2, food value: 52
agent: 2, age: 2, food value: 52
model step
agent: 3, age: 3, food value: 53
agent: 1, age: 3, strength: 70
agent: 2, age: 3, food value: 53
agent: 4, age: 3, food value: 53
model step
agent: 3, age: 4, food value: 54
agent: 2, age: 4, food value: 54
agent: 1, age: 4, strength: 60
agent: 4, age: 4, food value: 54
model step
agent: 2, age: 5, food value: 55
agent: 3, age: 5, food value: 55
agent: 4, age: 5, food value: 55
agent: 1, age: 5, strength: 50
Adding space¶
Cells form the foundation of the cell space system, enabling rich spatial environments where both location properties and agent behaviors matter. They’re useful for modeling things like varying terrain, infrastructure capacity, or environmental conditions.
Cell Agents are agents that understand how to exist in and move through cell spaces. They are specialized agent classes that handle cell occupation, movement, and proper registration.
We have:
CellAgent: Mobile agents that can move between cells
FixedAgent: Immobile agents permanently fixed to cells
Grid2DMovingAgent: Agents with grid-specific movement capabilities
These classes ensure consistent agent-cell relationships and proper state management as agents move through the space. They can be used directly or as examples for creating custom cell-aware agents.
Moving cell agents¶
class MyAgent(mesa.discrete_space.CellAgent):
def __init__(self, model, cell):
super().__init__(model)
self.move_to(cell) # place agent in grid
def move(self):
new_cell = self.cell.neighborhood.select_random_cell()
self.move_to(new_cell)
print(f"agent: {self.unique_id}, position: {self.cell.position}")
class MyModel(mesa.Model):
def __init__(self, number_agents, width, height):
super().__init__()
self.num_agents = number_agents
self.grid = mesa.discrete_space.OrthogonalMooreGrid(
(width, height),
torus=False,
random=self.random,
)
agents = MyAgent.create_agents(
self,
self.num_agents,
# Randomly select cells for agents
self.random.choices(self.grid.all_cells.cells, k=self.num_agents),
)
print(f"model time: {self.time}")
for agent in agents:
print(f"agent: {agent.unique_id}, position: {agent.cell.position}")
def step(self):
print(f"model time: {self.time}")
self.agents.shuffle_do("move")my_model = MyModel(3, 10, 10)model time: 0.0
agent: 1, position: [5. 0.]
agent: 2, position: [7. 3.]
agent: 3, position: [2. 9.]
my_model.run_for(5)model time: 1.0
agent: 2, position: [8. 2.]
agent: 3, position: [1. 8.]
agent: 1, position: [6. 0.]
model time: 2.0
agent: 1, position: [5. 0.]
agent: 2, position: [9. 2.]
agent: 3, position: [2. 8.]
model time: 3.0
agent: 1, position: [4. 0.]
agent: 3, position: [1. 9.]
agent: 2, position: [9. 3.]
model time: 4.0
agent: 3, position: [1. 8.]
agent: 2, position: [9. 4.]
agent: 1, position: [5. 1.]
model time: 5.0
agent: 1, position: [5. 0.]
agent: 2, position: [9. 3.]
agent: 3, position: [2. 9.]
In this example, we have created a model with three cell agents moving in a landscape of 10x10 grid cells. In every time step, every agent move from its present cell to a neighboring cell.