Agent-based models

The Model contains all objects and defines the procedures of an agent-based simulation. It is meant as a template for custom model classes that override the custom procedure methods.

class Model(parameters=None, _run_id=None, **kwargs)[source]

Template of an agent-based model.

Parameters
  • parameters (dict, optional) –

    Dictionary of the model’s parameters. Default values will be selected from entries of type Range, IntRange, and Values. The following parameters will be used automatically:

    • steps (int, optional): Defines the maximum number of time-steps. If none is passed, there will be no step limit.

    • seed (int, optional): Used to initiate the model’s random number generators. If none is passed, a random seed will be generated.

    • report_seed (bool, optional): Whether to document the random seed used (default True).

  • **kwargs – Will be forwarded to Model.setup().

Variables
  • type (str) – The model’s class name.

  • info (InfoStr) – Information about the model’s current state.

  • p (AttrDict) – The model’s parameters.

  • t (int) – Current time-step of the model.

  • id (int) – The model’s object id, which will always be zero.

  • random (random.Random) – Random number generator.

  • nprandom (numpy.random.Generator) – Numpy random number generator.

  • var_keys (list) – Names of the model’s custom variables.

  • running (bool) – Indicates whether the model is currently running.

  • log (dict) – The model’s recorded variables.

  • reporters (dict) – The model’s documented reporters.

  • output (DataDict) – Output data after a completed simulation.

Examples

To define a custom model with a custom agent type:

class MyAgent(ap.Agent):

    def setup(self):
        # Initialize an attribute with a parameter
        self.my_attribute = self.p.my_parameter

    def agent_method(self):
        # Define custom actions here
        pass

class MyModel(ap.Model):

    def setup(self):
        # Called at the start of the simulation
        self.agents = ap.AgentList(self, self.p.agents, MyAgent)

    def step(self):
        # Called at every simulation step
        self.agents.agent_method()  # Call a method for every agent

    def update(self):
        # Called after setup as well as after each step
        self.agents.record('my_attribute')  # Record variable

    def end(self):
        # Called at the end of the simulation
        self.report('my_reporter', 1)  # Report a simulation result

To run a simulation:

parameters = {
    'my_parameter': 42,
    'agents': 10,
    'steps': 10  # Used automatically to define simulation length
}

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

Simulation tools

Model.run(steps=None, seed=None, display=True)[source]

Executes the simulation of the model. Can also be used to continue a partly-run simulation for a given number of additional steps.

It starts by calling Model.run_setup() and then calls Model.run_step() until the method Model.stop() is called or steps is reached. After that, Model.end() and Model.create_output() are called. The simulation results can be found in Model.output.

Parameters
  • steps (int, optional) – Number of (additional) steps for the simulation to run. If passed, the parameter ‘Model.p.steps’ will be ignored. The simulation can still be stopped with :func:’Model.stop’.

  • seed (int, optional) – Seed to initialize the model’s random number generators. If none is given, the parameter ‘Model.p.seed’ is used. If there is no such parameter, a random seed will be used. For a partly-run simulation, this argument will be ignored.

  • display (bool, optional) – Whether to display simulation progress (default True).

Returns

Recorded variables and reporters.

Return type

DataDict

Model.stop()[source]

Stops Model.run() during an active simulation.

Custom procedures

Model.setup()[source]

Defines the model’s actions before the first simulation step. Can be overwritten to initiate agents and environments.

Model.step()[source]

Defines the model’s actions during each simulation step (excluding t==0). Can be overwritten to define the models’ main dynamics.

Model.update()[source]

Defines the model’s actions after each simulation step (including t==0). Can be overwritten for the recording of dynamic variables.

Model.end()[source]

Defines the model’s actions after the last simulation step. Can be overwritten for final calculations and reporting.

Data collection

Model.record(var_keys, value=None)

Records an object’s variables at the current time-step. Recorded variables can be accessed via the object’s log attribute and will be saved to the model’s output at the end of a simulation.

Parameters
  • var_keys (str or list of str) – Names of the variables to be recorded.

  • value (optional) – Value to be recorded. The same value will be used for all var_keys. If none is given, the values of object attributes with the same name as each var_key will be used.

Notes

Recording mutable objects like lists can lead to wrong results if the object’s content will be changed during the simulation. Make a copy of the list or record each list entry seperately.

Examples

Record the existing attributes x and y of an object a:

a.record(['x', 'y'])

Record a variable z with the value 1 for an object a:

a.record('z', 1)

Record all variables of an object:

a.record(a.vars)
Model.report(rep_keys, value=None)[source]

Reports a new simulation result. Reporters are meant to be ‘summary statistics’ or ‘evaluation measures’ of the simulation as a whole, and only one value can be stored per run. In comparison, variables that are recorded with Model.record() can be recorded multiple times for each time-step and object.

Parameters
  • rep_keys (str or list of str) – Name(s) of the reporter(s) to be documented.

  • value (int or float, optional) – Value to be reported. The same value will be used for all rep_keys. If none is given, the values of object attributes with the same name as each rep_key will be used.

Examples

Store a reporter x with a value 42:

model.report('x', 42)

Define a custom model that stores a reporter sum_id with the sum of all agent ids at the end of the simulation:

class MyModel(ap.Model):
    def setup(self):
        agents = ap.AgentList(self, self.p.agents)
    def end(self):
        self.report('sum_id', sum(self.agents.id))

Running an experiment over different numbers of agents for this model yields the following datadict of reporters:

>>> sample = ap.sample({'agents': (1, 3)}, 3)
>>> exp = ap.Experiment(MyModel, sample)
>>> results = exp.run()
>>> results.reporters
        sum_id
run_id
0            1
1            3
2            6

Conversion

classmethod Model.as_function(**kwargs)[source]

Converts the model into a function that can be used with the ema_workbench library.

Parameters

**kwargs – Additional keyword arguments that will passed to the model in addition to the parameters.

Returns

The model as a function that takes parameter values as keyword arguments and returns a dictionary of reporters.

Return type

function