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

Let’s begin by defining an Actor class.
It’s important that the class inherits first from 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.AgentSets 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()