The mesa library is very nice, and it should be faster and easier to implement models that a plain numpy
implementation.
However, mesa is undergoing changes so many of the online examples are based on earlier versions of the library. This page is a collection of code segments that I used to build all examples covered in class and what I suggest you use for assignments. These are based on the latest version of the library (3.0.0b0).
Using a consistent style between models/applications means that it is easier to focus on the similarities between the applications and should result in faster development.
As we implement more complicated models and need more functionality I will add to this page.
However, this page is not intended to be a replacement for the mesa documentation so spend some time browsing that.
First load in the standard modules — I have broken this into three cells based on their general purpose
1 2 3 4 5 6 |
|
Next load functions to build animations
1 2 |
|
Finally install mesa using
1 |
|
and load in mesa and verify the correct version is used
1 2 |
|
You should get output '3.0.2' or '3.1.0.dev'.
Agent
classWe need to create a class to represent the Agent
. Depending on the application, I might called this class
Cell
(for Game of Life model),
Tree
(for fire model),
Person
(for SIR models), etc., or I might be lazy and just call them Agent
. In this page of code snippets I will always use name Agent
.
The minimal code for Agent
is
1 2 3 4 5 6 |
|
Agent
class with statesOften an agent can be in one of a number of predefined states, so take the Game of Life where the agent, Cell
, is either DEAD
or ALIVE
. In this case our class definition starts with:
1 2 3 4 5 6 7 8 9 10 |
|
Agent
class with simultaneous updateIn some applications, such as the Game of Life, we want to update ALL agents at exactly the same time — in contrast to updating agents either in order (for the Traffic model) or at random.
To get the simultaneous update in mesa we have class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
In this code, our agent has:
_next_step
which stores the state that the agent will change to in the next step.compute_step
which computes the value of _next_state
, typically based on the agent's state
and the state
of its neighbours.step
just update state
using the value in _next_state
.Then in the step
function in the Model
class we have
1 2 3 4 5 6 7 |
|
where the first line updates the _next_state
for all agents without changing state
and once that is completed the second line updates the state
for all agents.
Model
classThe Model
class stores the agents, controls how that are updated, and what data is recorded. Similar to the Agent
class you can call this anything, so you could use
FireModel
(for fire model),
SchellingModel
(for the Schelling model), etc., but I tend to just use Model
. In this page of code snippets I will always use name Model
.
At a minimum the Model
class has
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Mesa comes with a nice visualisation and UI (for model parameter selection) but I had issues in getting it to work with Colab so we are going build our own using matplotllib.animation
. We need to implement the following:
draw_model
creates a graphical representation of the current state of the model and its agents.1 2 3 4 5 6 7 8 9 |
|
mode.step
) and displays the model (by calling draw_model
)1 2 3 |
|
Then to create an animation we:
Model
with desired parameter values.matplotlib
window using (or similar if multiple plots).1 2 |
|
1 2 3 |
|
DataCollector
classSee mesa documentation for details.
If Model
has a grid, we often need to loop over all locations in the grid, for example to place an agent at each location (think Cell
in Game of Life or a Tree
in Fire Model). This can be done from within a method of Model
using
1 2 |
|
or if not interested in the contents (say when in Model.__init__
and placing agents) we use
1 2 3 |
|
To loop over all agents in the model use
1 2 |
|
Within the Agent
class, we often need to get a list of its neighbours — and then filter/count those alive, etc. The cleanest approach is to have a method which performs the task of getting the list of neighbours. For example, in the Game of Life we might have
1 2 3 4 5 6 |
|