An agent-based (or individual-based) model is a computational simulation of autonomous agents that react to their environment (including other agents) given a predefined set of rules . ABM has gained wide usage in a variety of research disciplines. One reason for its popularity is that it allows relaxing many simplifying assumptions usually made by mathematical models. Relaxing such assumptions of a "perfect world" can change a model's behavior . ABM is specifically an important tool for studying complex systems where a system's behavior cannot be predicted and has to be explored (see the "Why we need ABM" section for detailed examples).
Agent.jl provides a structure and components for quickly implementing agent-based models, run them in batch, collect data, and visualize them. To that end, it provides the following functionalities:
- Default grids to run the simulation, including simple or toroidal 1D grids, simple or toroidal regular rectangular and triangular 2D grids, and simple or toroidal regular cubic 3D grids with von Neumann or Moore neighborhoods. Users can use their defined graphs too.
- Automatic data collection in a
DataFrameat desired intervals.
- Exploring the simulation results interactively in Data Voyager 2.
- Batch running and batch data collection
- Visualize agent distributions on grids
Implementing an ABM framework in Julia has several advantages:
- Using a general purpose programming language instead of a custom scripting language, such as NetLogo's, removes a learning step and provides a single environment for building the models and analyzing their results.
- Julia has a rich ecosystem for data analysis and visualization, implemented and maintained independently from Agents.jl.
- Julia is easier-to-use than Java (used for Repast and MASON), and provides a REPL (Read-Eval-Print-Loop) environment to build and analyze models interactively.
- Unlike Python (used for Mesa), Julia is fast to run. This is a crucial criterion for models that require considerable computations.
Agents.jl provides users with core components that make it easy to build ABMs, run them in batch, collect model outputs, and visualize the results. Briefly, the framework eases the following tasks for the user, and is at the same time flexible enough to allow implementation of almost any ABM.
- Schedulers: users can choose from a range of activation regimes, i.e. the order with which agents activate, or implement a custom one.
- Spatial structures: the framework implements 1D, 2D, and 3D grids which can optionally have periodic boundary conditions, meaning that edges of a grid connect to their opposite edges. An agent exiting from one edge enters the grid from the opposite edge. Moreover, users can construct irregular networks as the space where the agents live.
- Data collection: users only specify the kind of data they need and the framework automatically collects them in a table. The collected data are then ready to be analyzed and visualized.
- Batch run: in agent-based modeling, we can rarely make conclusions from single simulation runs. Instead we run many replicates of a simulation and observe the mean behavior of the system. Agents.jl automates running simulation replicates and collecting and aggregating their results.
- Visualization users can create custom plots interactively from the simulation outputs using the Data Voyager platform. Furthermore, they can visualize agent distributions on 2D grids.
Agents.jl is lightweight and modular. It has a short learning curve, and allows one to extend its capabilities and express complicated modeling scenarios. Agents.jl is inspired by Mesa framework for Python.
batchrunner_parallel function allows you to run several simulation replicates in parallel and get all their results in a single Data Frame. It works the same as
batchrunner except each replicate runs independently.
Sometimes, it is easier to take summary statistics than collect all the raw data. The
step! function accepts a list of aggregating functions, e.g.
median. If such a list is provided, each function will apply to a list of the agent fields at each step. Only the summary statistics will be returned. It is possible to pass a dictionary of agent fields and aggregator functions that only apply to those fields. To collect data from the model object, pass
:model instead of an agent field. To collect data from a list of agent objects, rather than a list of agents' fields, pass
Since ABMs are stochastic, researchers often run multiple replicates of a simulation and observe its mean behavior. Agents.jl provides the
batchrunner function which allows running and collecting data from multiple simulation replicates. Furthermore, the
combine_columns! function merges the results of simulation replicates into single columns using user-passed aggregator functions.
Julia has extensive tools for data analysis. Having the results of simulations in
DataFrame format makes it easy to take advantage of most of such tools. Examples include the VegaLite.jl package for data visualization, which uses a grammar of graphics syntax to produce interactive plots. Moreover, DataVoyager.jl provides an interactive environment to build custom plots from
DataFrames. Agents.jl provides
visualize_data function that sends the simulation outputs to Data Voyager.
Agent-based models (ABMs) are increasingly recognized as the approach for studying complex systems [3,4,5,6]. Complex systems cannot be fully understood using the traditional mathematical tools that aggregate the behavior of elements in a system. The behavior of a complex system depends on the behavior and interaction of its elements (agents). Small changes in the input to complex systems or the behavior of its agents can lead to large changes in system's outcome. That is to say a complex system's behavior is nonlinear, and that it is not the sum of the behavior of its elements. Use of ABMs have become feasible after the availability of computers and has been growing since, especially in modeling biological and economical systems, and has extended to social studies and archaeology.
An ABM consists of autonomous agents that behave given a set of rules. A classic and simple example of an ABM is a cellular automaton. A cellular automaton is a regular grid where each cell is an agent. Cells have different states, for example, on or off. A cell's state can change at each step depending on the state of its neighbors. This simple model can lead to unpredictable emergent patterns on the grid. Famous examples of which are Wolfram's rule 22 and rule 30 (see here and figures below).
Another classic example of an ABM is Schelling's segregation model, which we implement in the Tutorial page. This model also uses a regular grid and defines agents as the cells of the grid. Agents can be from different social groups. Agents are happy/unhappy based on the fraction of their neighbors that belong to the same group as they are. If they are unhappy, they keep moving to new locations until they are happy. Schelling's model shows that even small preferences of agents to have neighbors belonging to the same group (e.g. preferring that at least 30% of neighbors to be in the same group) could lead to total segregation of neighborhoods. This is another example of an emergent phenomenon from simple interactions of agents.
The package is in Julia's package list. Install it using this command:
To run tests, just run the
runtests.jl file in the