Note

You can download this demonstration as a Jupyter Notebook here

# Wealth transfer¶

This is a tutorial for beginners on how to create a simple agent-based model with the agentpy package. It shows the how to create a basic model with a custom agent type, run a simulation, record data, and visualize results.

The model explores the distribution of wealth under a trading population of agents. We will see that their random interaction will create an inequality of wealth that follows a Boltzmann distribution. The original version of this model been written in MESA and can be found here.

## Getting started¶

[1]:

# !pip install agentpy


Once installed, the recommended way to import the package is as follows:

[2]:

import agentpy as ap


We also import two other libraries that will be used in this demonstration.

[3]:

import numpy as np  # Scientific computing tools
import matplotlib.pyplot as plt  # Visualization


## Model definition¶

We start by defining a new type of agent as a subcluss of Agent. Each agent starts with one unit of wealth. When wealth_transfer() is called, the agent selects another agent at random and gives them one unit of their own wealth if they have one to spare.

[4]:

class WealthAgent(ap.Agent):

""" An agent with wealth """

def setup(self):

self.wealth = 1

def wealth_transfer(self):

if self.wealth > 0:

partner = self.model.agents.random()
partner.wealth += 1
self.wealth -= 1


Next, we define a method to calculate the Gini Coefficient, which will measure the inequality among our agents.

[5]:

def gini(x):

""" Calculate Gini Coefficient """
# By Warren Weckesser https://stackoverflow.com/a/39513799

mad = np.abs(np.subtract.outer(x, x)).mean()  # Mean absolute difference


Finally, we define our model as a subclass of Model. In Model.setup(), we define how many agents should be created at the beginning of the simulation. In Model.step(), we define that at every time-step all agents will perform the action wealth_transfer. In Model.update(), we calculate and record the current Gini coefficient. And in Model.end(), we further record the wealth of each agent.

[6]:

class WealthModel(ap.Model):

""" A simple model of random wealth transfers """

def setup(self):

def step(self):

self.agents.wealth_transfer()

def update(self):

self.record('Gini Coefficient', gini(self.agents.wealth))

def end(self):

self.agents.record('wealth')


## Running a simulation¶

To run a simulation, we define a dictionary of parameters that defines the number of agents and the number of steps that the model will run.

[7]:

parameters = {
'agents': 100,
'steps': 100
}


To perform a simulation, we initialize our model with these parameters and call the method Model.run, which returns a DataDict of our recorded variables and measures.

[8]:

model = WealthModel(parameters)
results = model.run()

Completed: 100 steps
Run time: 0:00:00.183086
Simulation finished


To visualize the evolution of our Gini Coefficient, we can use pandas.DataFrame.plot().

[9]:

data = results.variables.WealthModel
ax = data.plot()


And to visualize the final distribution of wealth, we can use pandas.DataFrame.hist().

[10]:

data = results.variables.WealthAgent
data.hist(bins=range(data.wealth.max()+1))

plt.title('')
plt.xlabel('Wealth')
plt.ylabel('Number of agents')
plt.show()


What we get is a Boltzmann distribution. For those interested to understand this result, you can read more about it here.