Integration into ABM frameworks
Pop2net provides seamless integration with two widely used agent-based modeling frameworks: Mesa and AgentPy. To use Pop2net with either framework, you only need to follow two steps:
First, when defining an Actor or Location class, it must inherit from both the corresponding Pop2net class and the framework’s class — in that order. For example:
class Actor(p2n.Actor, mesa.Agent):
pass
class Location(p2n.Location, mesa.Agent):
pass
Second, provide the model instance and the name of the framework to the Environment object:
env = p2n.Environment(model=model, framework="mesa")
Basic examples
Mesa
Actor
class.p2n.Actor
, and then from mesa.Agent
:[162]:
import mesa
import pop2net as p2n
[163]:
class Actor(p2n.Actor, mesa.Agent):
def say_hello(self):
print("Hello I am an actor.")
Location classes must also inherit from mesa.Agent
:
[164]:
class Location(p2n.Location, mesa.Agent):
def say_hello(self):
print("Hello I am a location.")
A common use case when integrating Pop2net with Mesa (or AgentPy) is to extend the simulation model with an Environment
object. This object stores all actors and locations and manages their relationships using Pop2net’s structure. When extending a Mesa model with a Pop2net environment, it’s important to pass the model instance to the Environment
and to set the framework
argument to "mesa"
:
[165]:
class Model(mesa.Model):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# add pop2net environment object as model attribute
self.env = p2n.Environment(model=self, framework="mesa")
# add one actor to the environment
self.env.add_actor(Actor(model=self))
# add one location to the environment
self.env.add_location(Location(model=self))
def step(self):
# Because env.actors and env.locations are AgentSets now,
# we can use the Mesa Syntax to let the agents do something:
self.env.actors.do("say_hello")
self.env.locations.do("say_hello")
Let’s create the model and have a look at the agent attribute:
[166]:
model = Model()
list(model.agents)
[166]:
[<__main__.Actor at 0x133bca900>, <__main__.Location at 0x133bcaa50>]
The model’s agent attribute includes both the actor and the location because locations are also considered as agents in Pop2net. This is something you have to keep in mind!
To get only actors or only locations, you can use model.env.actors
or model.env.locations
. Both are mesa.AgentSet
s now:
[167]:
model.env.actors
[167]:
<mesa.agent.AgentSet at 0x133d573b0>
[168]:
list(model.env.actors)
[168]:
[<__main__.Actor at 0x133bca900>]
[169]:
model.env.locations
[169]:
<mesa.agent.AgentSet at 0x133d57530>
[170]:
list(model.env.locations)
[170]:
[<__main__.Location at 0x133bcaa50>]
Let’s run the model for one step:
[171]:
model.step()
Hello I am an actor.
Hello I am a location.
AgentPy
Here is the same example adapted for AgentPy.
[172]:
import agentpy as ap
[173]:
class Actor(p2n.Actor, ap.Agent):
def say_hello(self):
print("Hello I am an actor.")
[174]:
class Location(p2n.Location, ap.Agent):
def say_hello(self):
print("Hello I am a location.")
[175]:
class Model(ap.Model):
def setup(self):
# add pop2net environment object as model attribute
self.env = p2n.Environment(model=self, framework="agentpy")
# add one actor to the environment
self.env.add_actor(Actor(model=self))
# add one location to the environment
self.env.add_location(Location(model=self))
def step(self):
# Because env.actors and env.locations are AgentLists now,
# we can use the AgentPy Syntax to let the agents do something:
self.env.actors.say_hello()
self.env.locations.say_hello()
[176]:
model = Model()
model.run(steps=1)
Hello I am an actor.
Hello I am a location.
Completed: 1 steps
Run time: 0:00:00.000219
Simulation finished
[176]:
DataDict {
'info': Dictionary with 9 keys
'reporters': DataFrame with 1 variable and 1 row
}
Simple examples with the Creator
Below are some super simple examples of how to integrate the Creator in Mesa’s or AgentPy’s models. One important aspect here is that the creator automatically makes sure that the created actors and locations inherit from the specified framework if you do not provide custom actor or location classes.
Mesa
[177]:
class CompleteGraph(p2n.LocationDesigner):
pass
class Model(mesa.Model):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# add pop2net's objects to mesa's model
self.env = p2n.Environment(model=self, framework="mesa")
self.creator = p2n.Creator(env=self.env)
self.inspector = p2n.NetworkInspector(env=self.env)
# create actors and locations
self.creator.create_actors(n=10)
self.creator.create_locations(location_designers=[CompleteGraph])
model = Model()
[178]:
model.env.actors
[178]:
<mesa.agent.AgentSet at 0x133d82690>
[179]:
isinstance(model.env.actors[0], mesa.Agent) and isinstance(model.env.actors[0], p2n.Actor)
[179]:
True
[180]:
model.env.locations
[180]:
<mesa.agent.AgentSet at 0x133ad49b0>
[181]:
isinstance(model.env.locations[0], mesa.Agent) and isinstance(model.env.locations[0], p2n.Location)
[181]:
True
[182]:
model.inspector.plot_networks()
AgentPy
[183]:
class CompleteGraph(p2n.LocationDesigner):
pass
class Model(ap.Model):
def setup(self):
# add pop2net's objects to agentpy's model
self.env = p2n.Environment(model=self, framework="agentpy")
self.creator = p2n.Creator(env=self.env)
self.inspector = p2n.NetworkInspector(env=self.env)
# create actors and locations
self.creator.create_actors(n=10)
self.creator.create_locations(location_designers=[CompleteGraph])
model = Model()
model.run(steps=1)
Completed: 1 steps
Run time: 0:00:00.001282
Simulation finished
[183]:
DataDict {
'info': Dictionary with 9 keys
'reporters': DataFrame with 1 variable and 1 row
}
[184]:
model.env.actors
[184]:
AgentList (10 objects)
[185]:
isinstance(model.env.actors[0], ap.Agent) and isinstance(model.env.actors[0], p2n.Actor)
[185]:
True
[186]:
model.env.locations
[186]:
AgentList (1 object)
[187]:
isinstance(model.env.locations[0], ap.Agent) and isinstance(model.env.locations[0], p2n.Location)
[187]:
True
[188]:
model.inspector.plot_networks()