Upload
others
View
5
Download
0
Embed Size (px)
Citation preview
Multi-Agent Modelling with MARS
A Handbook
Julius Weyl
Multi-Agent Modelling with MARS: A Handbook
Contents
1 Foreword and Installation 1
2 MARS Models 3
2.1 MARS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2 From Technical Model to MARS Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2.1 Starting Position . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2.2 Creating the Model Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.2.3 Advanced Model Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.3 Layers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.3.1 Creating Layers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.3.2 Using GIS Data in Models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.4 Agents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.4.1 Creating Agents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.4.2 Agent Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Agent States . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Life and Death . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.4.3 Tick: Step based execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.4.4 Agent Behavior . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Positions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Moving Agents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Exploring the Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Finding other Agents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Interactions between Agents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Passive Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Active Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Message Passing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Interactions with the Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.4.5 Creating new Agents during Simulation . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3 Local simulations 13
3.1 Creating a simulation config . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.1.1 Globals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.1.2 Data layers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.1.3 Agent parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.1.4 Agent initialization files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.1.5 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
4 Cloud simulations 16
4.1 Preparing the Model for Execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
4.1.1 Opening a Command Prompt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Mac . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
4.1.2 Changing Directory to the Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
4.1.3 Model File Structure and LIFEStarter . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
4.1.4 Building the Model with Dotnet Core . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
4.1.5 Creating a Model Zip File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
4.2 MARS Cloud Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
Page 2 of 60
Multi-Agent Modelling with MARS: A Handbook
4.2.1 Creating an Account . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4.2.2 Login to the System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4.2.3 Working with Projects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4.3 Importing Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4.3.1 Uploading Models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
4.3.2 Uploading GIS Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
4.3.3 Uploading Agent Init Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
4.4 Scenarios and result configs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
4.4.1 Creating Scenarios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
4.4.2 Filling out Scenarios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
4.4.3 Creating Result Configs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
4.5 Conducting Simulations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
4.5.1 Simulation Plans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
4.5.2 Running Simulations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
4.6 Analyzing Simulation Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
4.6.1 Agent Populations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
4.6.2 Spatial Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
4.6.3 Agent Attribute Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
4.6.4 Download Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
5 Language Reference 30
5.1 agent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
5.2 distance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
5.3 explore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Explore basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Explore with predicate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Null Reference Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
5.4 external . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
5.5 initialize . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
5.6 kill me . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
5.7 layer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
5.7.1 Layer Attributes and Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
5.8 move . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
5.8.1 Coordinate System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
5.8.2 Movement Command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
5.9 nearest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Null Reference Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
5.10 observe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
5.11 pos at . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
5.12 random . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
5.13 raster-layer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
5.14 simtime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
5.14.1 Simtime Example 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
5.14.2 Simtime Example 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
5.15 spawn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
5.16 static . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
5.17 tick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
5.18 ts-layer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
5.19 val . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Page 3 of 60
5.20 var . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
5.21 vector-layer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
5.22 x-cor and ycor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
6 Cookbook 50
6.1 Example Models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
6.1.1 Wolf, Sheep, Grass . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
6.1.2 Chatting Agents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
6.2 Useful Code Snippets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
6.2.1 Agent Evolution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
6.2.2 Agent Live Stages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
6.2.3 Random Walk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
6.2.4 Biomass Removal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
6.2.5 Agent Interaction: Buying Goods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
6.3 Data Usage Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
6.3.1 Agent Init Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
6.3.2 GIS ASC Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
6.4 GIS GeoJSON Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
6.4.1 Time-series CSV Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
6.5 Programming Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
6.5.1 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
6.5.2 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
6.5.3 Enums . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
6.5.4 Maps/ Dictionaries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
6.5.5 Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
for loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
foreach loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
while loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Example: Observer agent use loop to iterate over all raster cells. . . . . . . . . . . . . 59
Multi-Agent Modelling with MARS: A Handbook
1 Foreword and Installation
Welcome to the modeling handbook on agent-based models with MARS. This will be an introduction to
multi-agent modeling, the technical details during model implementation and the simulation execution. In
order to work with the handbook you will have to install the following things:
• Dotnet Core https://dotnet.microsoft.com/download
• JAVA SDK https://www.oracle.com/technetwork/java/javase/downloads/index.h
tml
• Eclipse https://www.eclipse.org/downloads/
• MARS Plugin https://mars.haw-hamburg.de/mars-dsl/
All programming is going to be done in Eclipse. Before you can use Eclipse to build MARS models you have
to install the JAVA software development kit. Once JAVA has been installed and Eclipse opened you can
add MARS functionality to it by installing our Eclipse plugin.
Figure 1: Eclipse: installing new software
After programming the model in Eclipse, Dot-
net Core will be needed to build and exe-
cute the model. But lets install the plu-
gin first: On both MacOS and Windows you
can find the ’Install New Software’ menu un-
der ’Help’ as shown in figure 1. Once you
open the window it will look like figure 2 with-
out the pop-up. The first step is to add
the MARS plugin URL to Eclipse. Click on
the ’Add’ field marked with a red one in fig-
ure 2. Step number two is to add the URL
specified above as ’MARS plugin’ to the field
marked with two. For ’name’ you can put MARS
(marked with three), then press ’ok’. Now you
should see the entry above the red number five
where it says ’MARS DSL’. Check the checkbox
and press ’next’ marked by the red six. Af-
ter this you will be lead through the installa-
tion process by Eclipse. It might be required
to restart Eclipse but then the plugin should
work.
If you encounter any problems you can contact us through our Slack system. You can join via the following
link:
mars-explorers.slack.com
Page 1 of 60
Multi-Agent Modelling with MARS: A Handbook
Figure 2: Installing the MARS DSL plugin to Eclipse part 2
Page 2 of 60
Multi-Agent Modelling with MARS: A Handbook
2 MARS Models
Agent based modeling derives from the field of artificial intelligence. This simulation paradigm incorporates
individuals, so called agents, who interact with each other and their surroundings. The behavior is pro-
grammed on an individual level to follow a set of rules and interactions between them are studied to gain
insights into collective behavior [2]. Note that an agent isn’t restricted to be an individual but can also be
a group, community or other entity that acts and reacts to outer conditions [4]. The way of creating results
bottom-up from an individual levels actions leading to complex effect makes it especially suited for research
on social sciences [1].
This handbook is designed to be an introduction for people who are new to multi-agent modeling, program-
ming in general and the MARS framework.
2.1 MARS
The multi-agent framework MARS (Multi-Agent Research and Simulation) is a research project, developed at
the University of Applied Sciences Hamburg [5]. Incorporating newest concepts of agent-based and individual-
based programming [6]. The frameworks targets both simple and complex models by using specifically
designed approaches tailored to the respective disciplines like for example social ecology [3].
2.2 From Technical Model to MARS Model
Throughout this workshop we are going to use a custom domain specific language (DSL) for programming.
Daniel Glake, a member of the MARS group, created this language which targets socio-ecological models.
To make the introduction easier, we will implement an example model throughout this handbook. This
model is going to be a simple predator-prey scenario consisting of two agent types: wolves and sheep. Each
Agent is considered a living entity that has to eat in order to stay alive. For the wolves this means that
they have to eat sheep. The sheep have to eat grass. Grass will be added to the model later on as GIS file.
Wolves and sheep agents can reproduce. If they have eaten enough, they eventually hatch a juvenile wolf or
sheep. The grass periodically grows back on its own.
2.2.1 Starting Position
Every model needs to start somewhere. This is usually a class diagram which already covers the models
agents and layers. The authors expect that you are familiar with conceptual modeling at this point of reading
and have a valid design model at hand. For the layers the modeler should know the type and for the agents
he ideally has a set of attributes and rules describing the agent behavior. From there he can follow this
handbook to transform the existing technical model, that is what the model ideas on paper are being called,
to a working piece of code. This is the actual model which will be executed on the MARS platform.
Figure 3: Class diagram of the models agents
Page 3 of 60
Multi-Agent Modelling with MARS: A Handbook
2.2.2 Creating the Model Structure
New models follow a set of formatting rules that enable the computer to understand them. Generally
speaking the models are divided into three groups:
1. model definition
2. layer definition
3. agent definition
This is also the basic structure the model idea has to be brought to when implementing a model. So when
you as a modeler start implementing your model with the MARS DSL, this is the pattern you have to stick to.
Model definition happens in the first line of every model. Listing 1 demonstrates this by creating a model
in line 0 with the name wolf sheep model. When creating your own model, this is where the name of your
model is going to be put.
Line 2 proceeds to create the layers. For this simple model it is going to be a single layer with the name of
AgentLayer. While implementing models every layer should be created after the model definition and before
the agent definitions.
The agent definition happens in line 4. Agents are defined by giving them a name and specifying on which
layer they are going to live. In this first, simple model the agent has the name wolf and will be managed by
the layer with name AgentLayer that has been created before.
0 model wolf_sheep_model
1
2 layer AgentLayer
3
4 agent wolf on AgentLayer{}
Listing 1: Basic model structure
2.2.3 Advanced Model Structure
Models don’t have to be written in the same file anymore. As long as the source files (.mars) are con-
tained in the solution and have the same model name in the first line, they will work together
2.3 Layers
Layers in MARS are an instrument to fulfill the tasks of agent management or data management. This
differs by their type. Depending on your model, you’ll use different layers. Baseline is the so called basic
layer for managing agents which is always used in models since multi-agent models always contain agents.
Therefore this layer is present in every model. GIS layers and time-series layers are designed to provide GIS
and time-series functionality. They can be included to access such data during simulations.
1. Basic Layer Used to manage agents
2. GIS Raster Layers Used to provide access to rasterized GIS data, cannot manage agents
3. GIS Vector Layers Offer access to vector GIS data and time-series data, cannot manage agents
Page 4 of 60
Multi-Agent Modelling with MARS: A Handbook
2.3.1 Creating Layers
Now that you know the basics about layers, it is time to create the ones that your model includes. First we
define a basic layer which will handle everything agent related. Think of a name that describes the agents
surroundings and create such a layer as shown in listing 2 in line 0. In the example the layer has the name
AgentLayer, you name yours according to what you have thought of. The name has no effect on the model
behavior.
Once that is done, we continue with the optional GIS layers and time-series layers. If your model doesn’t
contain such data, you can skip ahead.
GIS layers can be created like shown in the 2nd and 4th line in listing 2. The keyword for GIS raster
layers is raster-layer followed by the name the layer should have and an alias which we will use to refer to
the layer later in the model. For these two names (GisGrassLayer and gisgrasslayer in the example) it is
customary to give them the same name. Write the first one in camel case and the second one in lower case.
Again, the names have no effect on the model. For GIS vector layers the procedure works accordingly with
the vector-layer keyword.
Time-series layers are created similar to the GIS layer since their functionality is provided through the
vector-layer . Line 6 of listing 2 shows a vector-layer that is being used to provide time-series data about
temperature values to the agents during the simulation. More information about the use of time-series can
be found in the next section.
0 layer AgentLayer
1
2 raster-layer GisGrassLayer as gisgrasslayer
3
4 vector-layer WaterPointLayer as waterpointlayer
5
6 vector-layer TemperatureLayer as temperaturelayer
Listing 2: Available Layer types
2.3.2 Using GIS Data in Models
The GIS layers ( vector-layer and raster-layer ) allow to use a range of GIS files in the simulation. At
the moment these are ASC files and GeoJSON. Data in other formats has to be converted to one of these,
otherwise you cannot make use of them.
To use the GIS data in your model you first have to create either a raster-layer or a vector-layer as shown
in listing 2. If you’re unsure which one to use, you can read up on each of them in the language reference
at 5.13 for raster-layer and at 5.21 for the vector-layer . In addition to the name of the layer you have to
specify an alias by which the layer is referred to in the code. The actual GIS file will be added later when
the model gets uploaded to the MARS cloud system or has to be specified in the simulation configuration.
For now it is important to note that the information of raster-layer can be accessed in a reading as well as
writing manner while the vector-layer only allows for reading access.
0 gisgrasslayer.GetNumberValue(xcor, ycor)
1 gisgrasslayer.GetIntegerValue(xcor, ycor)
2
3 gisgrasslayer.Increase(xcor, ycor, 3)
Page 5 of 60
Multi-Agent Modelling with MARS: A Handbook
4 gisgrasslayer.Reduce(xcor, ycor, 5.0)
5
6 nearest on GisGrassLayer
7
8 waterpointlayer.GetNumberValue()
9 waterpointlayer.GetIntegerValue()
10 nearest on WaterPointLayer
11
12 temperaturelayer.GetNumberValue()
13 temperaturelayer.GetIntegerValue()
Listing 3: Available methods for using the GIS layer
Once the layers have been created in the model, the agents will be able to work with the GIS and time-series
layers in the following way. If you take a look at listing 3 you can see three basic ways of working with
them. Lines 0 and 1 show the reading process on the raster-layer . Here the agent wants to know the
current value of the grid cell it is standing on. The result is a number which is either coded as floating
point (’GetNumberValue’) or as an integer (’GetIntegerValue’). Lines 3 and 4 show the writing operation on
the raster-layer where the value of the agents current position is altered. The ’increase’ function increases
the current value by the amount specified in the third parameter. This is same with the ’reduce’ function
with the difference that this one decreases the current value. A special function can be seen in line 6 which
returns a coordinate of the nearest grid cell with a value that is not equal to the ’noData’ value specified in
the ASC file. This is specific to the raster-layer.
Lines 8+9 and 12+13 look the same at first glance (and even at second). The difference between them can
only be seen in context which will now be explained. The ’waterpointlayer’ is used in the model as a GIS
layer. It contains information about the positions of waterpoints while the ’temperaturelayer’ is used to
provide time-series information. This might be confusing at first but it bear with me. If you wan’t to use
time-series data in your model you will be using a vector-layer to represent that information. For every
simulation step the layer will return the current value for that point in time. Depending on the used method
this number is either formatted as float (’GetNumberValue’) or as an integer. So if you call the method in
line 12 your agents can get the current temperature value for that simulation step. This temperature value
is not bound to a location but the same for the whole simulated area. At the same time the vector-layer
can also be used to represent GIS data. In that case the methods shown in lines 8 and 9 return the value
for the closest point to the agent, contained in the input file (GeoJSON).
More information about the raster-layer can be found in the language reference chapter in the raster-
layer (5.13) section. The vector-layer is to be found in the vector-layer (5.21) section.
2.4 Agents
Agents are the second main part of every model (besides layers). Once the layers have been created, we can
start with the agent specification. For this step you, as a modeler, need to know what your agents are going
to be, what attributes define them and what their actions will look like. When all this is present, we can
start with the agent creation.
To illustrate the agent creation process, we will continue with the wolf, sheep, grass example model
that was described in the introduction. First this model will be described in detail, then the agents are
going to be created throughout this part of the handbook.
Page 6 of 60
Multi-Agent Modelling with MARS: A Handbook
The wolf, sheep, grass model consists of two agent types and two layers. One basic layer to manage the
agents and one GIS layer to represent the grass. Wolf and sheep agents will live on the basic layer:
Wolf Agent This agent moves around the simulated area and tries to find sheep agents in order to feed on
them. When he catches one, he eats it, thereby increasing his energy level. If the wolf can’t find sheep
for a period of time, he dies. If the wolf eats enough sheep agents, he can reproduce which leads to
new wolf agents in a juvenile state. This juvenile state lasts for a fixed amount of time. Wolf agents
in that state have a reduced amount of energy and are therefore more likely to die.
Sheep Agent This agent type moves around the simulated area as well. His objective is to find grass that
he can eat. Once grass has been found, the sheep increases its energy level by eating it. Like the wolf
agent, the sheep agent can reproduce when he eats enough grass. New sheep are created in a juvenile
state where they move slower. If the sheep agent can’t find grass for an extended period of time he
dies.
2.4.1 Creating Agents
With the wolf, sheep and grass model as demonstration use-case in place, it is time to create the agents.
Listing 4 shows this step. It starts with a model definition in line 0, this should be familiar from the
introduction. Next we define a basic layer with the name AgentLayer that will serve to manage the agents.
From line 5 on we create the two agent types, starting with the wolf. The keyword for creating agents is
agent . It is followed by the name of the agent and a layer allocation. This layer allocation tells the model
on which layer the agents are going to live. For the wolf this is going to be the AgentLayer that we defined
before. Note the curly braces at the end of line 5. The agent’s attributes and behavior is going to be enclosed
by these. More about this in the next section. For the sheep agent we do the same as for the wolf. It is
defined, receives a name and is told to live on the AgentLayer.
0 model wolf_sheep_model
1
2 layer AgentLayer
3 raster-layer GisGrassLayer as gisgrasslayer
4
5 agent wolf on AgentLayer{}
6 agent sheep on AgentLayer{}
Listing 4: Creating wolf and sheep agents
2.4.2 Agent Attributes
Agents have a set of attributes that define their state. These attributes are defined through variables inside
the agents curly braces. Variables can be thought of as little boxes that store information. For each of the
agents attributes like age, energy etc. we define one of those variables that can later be worked with or
altered during simulation execution.
Variables can be of different types. MARS supports integers, floating point numbers, boolean values and
strings - for those familiar with programming. Listing 5 shows an example for these variables and how they
are defined in the MARS DSL. Integer variables can save integers (numbers without floating point) whereas
real variables can save floating point numbers. Boolean values allow a binary distinction between true and
false. The last type of variables are strings which are useful to store text or characters.
Page 7 of 60
Multi-Agent Modelling with MARS: A Handbook
0 agent wolf on AgentLayer {
1 var Energy : integer = 10
2 var Weight : real = 70
3 var Name : string = "Wolf1"
4 }
Listing 5: Creating attributes of each available type
Agent States If an agent is designed to have various states like for example juvenile and adult in the
case of the wolf agent, this can be achieved through agent states. Depending on its current state, the agent
changes his behavior.
0 agent wolf on AgentLayer{
1 var agentState : integer = 0
2
3 tick{
4 i f(simtime > 50){
5 agentState = 1
6 }
7 //juvenile state
8 i f(agentState === 0){
9 //act as juvenile
10 }
11 //adult state
12 else{
13 //behave like an adult
14 }
15 }
16 }
Listing 6: Wolf agent with two states
Life and Death Agents will be removed from a simulation once they die. When it is desired that agents
can die, the agents can use the kill command. Code 7 shows the wolf agent dying when its Energy level
falls to 0 or below. In every simulation step the wolfs energy is reduced by 1. After 100 simulation steps the
energy will be zero and the wolf will be removed from the simulation.
0 agent wolf on AgentLayer {
1 var Energy : integer = 100
2 tick{
3 Energy = Energy - 1
4 i f(Energy<=0){
5 k i l l me
6 }
7 }
8 }
Listing 7: Wolf agent dying if its energy level falls below 0
Page 8 of 60
Multi-Agent Modelling with MARS: A Handbook
Figure 4: Example grid with 100 by 100 cells
2.4.3 Tick: Step based execution
Agent-based simulations are executed time-discrete. In each simulation step the agents get to perform their
actions. This behavior is specified inside the curly braces of the agents tick method. Listing 8 shows an
agent creation with the tick method (line 2) to specify the agent’s behavior. All commands for the agent
will be stored there. Before the first simulation step is executed the agent’s have to be initialized to set the
initial values of all their variables. This is where the initialize method shown in line 1 comes into play.
0 agent my_first_agent on my_first_layer{
1 i n i t i a l i z e{}
2 tick{}
3 }
Listing 8: Agent definition with initialize and tick methods
Detailed information about these two agent methods can be found in the tick (5.17) and initialize
(5.5) sections.
2.4.4 Agent Behavior
All agents follow a set of rules that define their behavior. Therefore, the next step in programming agents is
implementing this. In general, the behavior can be divided in two groups: exploring and acting. Both have
different implications on the environment and other agents. Agent movement and environment exploration
have no direct impact on the outer world whereas anything that involves interactions does. But before agents
can do any of these, they have to know where they are.
Page 9 of 60
Multi-Agent Modelling with MARS: A Handbook
Positions Basis for the simulated space is a grid on which the agents are positioned. This grid can be
as big as the modelers makes it (that is you). Origin of the grid is the lower left corner which corresponds
to position (0/0). From there the grid spans in x- and y-direction to the specified size. Figure 4 shows an
example with 100 by 100 grid cells.
Moving Agents One of the most basic actions an agent can perform is movement. This is simply the
way of changing the agents position from one point to another. Movement actions can be performed in
various levels of sophistication ranging from changing position one grid cell at a time to complex pathfinding
operations to avoid obstacles. It is up to you as a modeler to decide on the level used.
The basic move command consists of the move me part followed by to and a coordinate specifying the
direction. Directions have to be written in the DSL specific coordinate notation as shown in listing 9. This
notation starts with a hash symbol and braces that enclose the x and y-coordinates, separated through a
comma. So in line 0 the agent is told to move to position (1/5). Optionally a distance in grid cells can be
specified, telling the agent how far he should move. This can be seen in line 1 where the agent is told to
move three grid cells in the direction of (10/15).
0 move me to #(1,5)
1 move me 3 to #(10,15)
Listing 9: Example move commands
Exploring the Environment Agents capable of moving around the environment usually do it for a
reason. Besides the possibility of moving randomly, most agents make out a destination they want to move
to prior to the movement. In the case of the wolf agent, this is the search for sheep agents. In order to eat
them, the wolf has to move to their position.
Finding other Agents Other agents can be found through explore or nearest operations on the
environment. Listing 10 shows the nearest command in combination with a variable. This variable
(nearestSheep) saves the nearest sheep position and is used as input for the move command afterwards. As
a consequence the wolf moves there.
The nearest command always provides the closest agent of the specified type. In listing 10 the desired type
was sheep. This works as long as there are sheep in the simulation. Once all sheep are gone, the nearest
command can crash the simulation. This happens because the nearest command can only return a valid
position if there is something to find. If there are no sheep left, the nearest command returns a useless
coordinate that the move command can’t handle. Since the ”there” doesn’t exist, the computer doesn’t
know what to do. More details on this topic and how to avoid the problems can be found in the explore
section (5.3).
0 agent wolf on AgentLayer{
1
2 tick{
3 var nearestSheep = nearest sheep
4 move me to nearestSheep
5 }
6 }
Listing 10: Wolf agent searching the nearest sheep and moving there
Page 10 of 60
Multi-Agent Modelling with MARS: A Handbook
Interactions between Agents As of yet we are able to locate other agents and move around the simula-
tion. The interesting part of multi-agent models starts when agents interact either with each other or with
their environment. In the final section of the handbook there are many examples showing you how this can
be used:
• Agent Interaction: Buying Goods (6.2.5): One agent sells apples, the other one buys them
• Chatting Agents (6.1.2): Agents exchange messages
Add more
example
models
Add more
example
models
Direct interactions between agents consist of an active and a passive part. The initiating agent does the
active part whereas the chosen partner-agent takes the passive role. Before the active agent can perform the
interaction, the passive agent has to specify what such an interaction means.
In the wolf, sheep, grass model, when a wolf eats a sheep, he is the active agent. The sheep, which is about
to be eaten, has to determine what that means. For us as humans it is clear that the sheep would die and
the wolf would eat. The computer/ the model has to be told that in detail.
Passive Actions define the implications of an interaction to the passive agent which the action is per-
formed on. To give an example we’ll program the passive action part of an wolf - sheep interaction where the
sheep will be eaten (listing 11). Passive actions are written in the agent and start with the passive keyword,
followed by the name of the interaction. Parentheses enclose potential input arguments. The main part of
the passive actions follows inside curly braces afterwards. In the case of the sheep we devise a passive action
with the name BeEaten that takes no input parameters. Enclosed by the curly braces follows the statement
that the sheep dies (line 4).
0 agent sheep on AgentLayer{
1 tick{}
2 passive BeEaten(){
3 k i l l me
4 }
5 }
Listing 11: Sheep passive action
Active Actions When passive actions have been defined, the other half of interactions can be performed:
the active part. Agents that wan’t to initiate an interaction must select an agent before they can interact.
In the wolf, sheep, grass model that means that a wolf has to select a sheep first before he can eat it. Listing
12 shows that process. In line 2 the wolf locates the closest sheep and then moves there. Note that we didn’t
check if the wolf and the sheep are close by, we’ll do that later. For now it is more important to look at line
4 where the just implemented passive BeEaten action of the sheep is being called. Thereby the wolf initiates
the interaction and the sheep reacts to it by doing what has been specified. In this case that means that the
sheep dies.
0 agent wolf on AgentLayer{
1 tick{
2 var nearestSheep = nearest sheep
3 move me to nearestSheep
4 nearestSheep.BeEaten()
5 }
6 }
Page 11 of 60
Multi-Agent Modelling with MARS: A Handbook
Listing 12: Wolf eating the nearest sheep
Message Passing Now that the agents know how to find and interact with each other, the ability to
communicate might be desired. Agents can either communicate directly or via a proxy in form of a layer.
Direct communication is best suited for scenarios in which two agents want to exchange messages. If more
than two agents want to communicate the latter approach is the way to go. Communication over a layer
follows the idea of a blackboard where agents can leave each other messages and react to them. If you want
your agents to use a message based approach, take a look at Chatting Agents (6.1.2) in the cookbook
section where an example model is explained. That model uses message-passing through a layer so that two
agent types can communicate with each other.
Interactions with the Environment aren’t the same as those among agents. The interactions consist of
predefined passive methods that the agents can call, offered by the raster-layer and vector-layer . Subsection
Using GIS Data in Models (2.3.2) is dedicated to handling GIS and time-series data during simulation. In
that subsection, a list of available passive actions can be found. More detailed information is located in
the language reference in section 5.13 for the raster-layer and in section 5.21 for the, time-series capable,
vector-layer .
2.4.5 Creating new Agents during Simulation
For situations where new agents have to be created during simulation, for example if agents reproduce, the
spawn command can be used. This creates a new agent with own variables, a complete, independent entity.
In the wolf, sheep, grass model this is used when wolves or sheep reproduce. Pre-requirement for such a
reproduction is that the wolf or sheep has eaten enough so that its energy level is high enough. Listing 13
shows the model code. In line 7, the wolf checks if he has enough energy and eventually spawns a new wolf.
0 agent wolf on AgentLayer{
1 var energy = 10
2 tick{
3 var nearestSheep = nearest sheep
4 move me to nearestSheep
5 nearestSheep.BeEaten()
6 energy = energy + 5
7 i f(energy > 12){
8 spawn wolf
9 }
10 }
11 }
Listing 13: Wolf spawns a new agent if he has enough energy
Page 12 of 60
Multi-Agent Modelling with MARS: A Handbook
Currently there a two ways of running simulations:
1. Execute the simulations on a local machine which is the default and easier method of doing
things. If you want to use this style of execution, read the Local simulations section.
2. Use the MARS servers to run the simulation in Hamburg. This way of running simulations is
only for large-scale models. Setting up a simulation in that way is complicated and involves
more steps than running locally. If you wan’t to run your simulation there, read the Cloud
simulations section.
3 Local simulations
Once the model has been written and the code compiles without errors, a simulation can be performed.
Please make sure that your code works by saving the model (cmd + s/ ctrl + s) and see if there are errors
shown in Eclipse. If so, please fix them prior to attempting a simulation as the model can only be executed
then.
3.1 Creating a simulation config
To run a simulation, a so called ”simulation configuration” or ”sim config” is needed. This is a JSON
configuration file that tells the MARS core how long the simulation is supposed to run, how many agents
should be created and which input files are to be used. Listing 14 shows an example file for the wolf-sheep-
grass model. The file itself is divided into three sections: 1) globals, 2) layers and 3) agents. Before any
simulation can run, such a file has to be created for your respective model that follows the shown scheme.
3.1.1 Globals
The first thing to specify is the desired simulation duration or, to be more precise, the period of time that
the simulation should cover. The process is straightforward as the start- and end-times have to be inserted
as as combination of date and time. In listing 14 the start time is January 1st of 2019 at 18:00 (6pm) and the
end-time is 18:10 (6:10pm) on the same day which gives us a simulation time of 10 minutes. The 10 minutes
don’t say anything about the amount of single simulation steps as these have to be calculated from there.
It is customary that each simulation model operates on its own time schedule as the tick method specifies
the behavior of an agent that can be performed in this time step. If your model describes what an agent
can do in an hour, you would divide the simulated time into hours. Should your tick method specify an
agents behavior for a second, you divide the simulated time into seconds. Dividing the specified time period
by this time unit gives you the amount of simulation steps. For the wolf-sheep-grass model the time unit
has been set to seconds so there will be 600 simulation steps as dividing 10 minutes into seconds equals 600.
Take a look at listing 14 to see the required parameters. startTime and endTime set the respective times
while the deltaTUnit parameter determines the unit of time. Change these values accordingly for you own
model. The last option(deltaT ) can be used to further refine the amount of simulation steps. In the current
configuration the 10 minutes of simulation duration are divided into seconds which gives us 600 seconds. If
you want your simulation to execute a simulation every two seconds instead of every second you can use this
parameter to change it. Setting the deltaT parameter to 2 would change the calculation as there would only
be a simulation step every 2 second which results in 300 simulation steps. This parameter is usually set to 1
as there is seldom the requirement to temper with the time resolution. If you want your simulation to run
longer or shorter, you should change the start- and end-times instead. It is very important to understand
that this only defines the inner clock for the simulation. The actual simulation execution time (real time as
we know it) will have nothing to do with what ever you set here. Even if you set the simulation execution
Page 13 of 60
Multi-Agent Modelling with MARS: A Handbook
to many years it can still run in a few minutes. On the other hand your simulation might take several days,
even if your just covering a time frame of ten minutes.
The next parameter output specifies the desired way of persisting results. Here you can choose between
saving them to CSV files, storing them in a local MongoDB or to omit them all-together. The default way
for local execution is to save the results as CSV files as they allow for easy analysis afterwards. For each agent
type, a CSV file will be created which contains a line of output per agent and simulation step. The contents
of this lines are the current values for the agents attributes, marked with the observe (5.10) keyword. Since
most people prefer a certain style of formatting, the options parameter allow to specify this up to the desired
delimiter in the CSV file and the number format. If you want you entries to be separated by a comma set the
delimiter value to ”,” or any other separator you might like. The number format specifies how floating point
numbers (reals) should formatted. Using ”en-EN” should be kept as this specifies the standard computer
science formatting where a dot denotes the decimal place. If other formats are desired, you can read up
on them here https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard
-numeric-format-strings. Should you wish to store the results in a MongoDB, please use our slack
system to contact us as the setup is not as easy as with CSV files. If you don’t want to save any results at
all, you can set the ”output” parameter to ”none” and remove the ”options” part completely.
3.1.2 Data layers
Once the global parameters have been set, eventual data layers have to be configured. If you don’t use the
GIS layers ( raster-layer , vector-layer ) , you can skip this section.
Data layers receive their respective input files through the simulation config. In line 15 of listing 14 you see
this mechanism for the ”BiomassRaster” layer where the file ”grass 4 100x100 v4.asc” is assigned. Inside
the ”layers” section you have to add each layer in your model. The name of the layer has to match the layers
name in the model exactly, otherwise it won’t work. In the line beneath, the filename that should be used
has to be added in the same way. To avoid problems with file locations, it is best to place the input files
inside the ”src-gen” folder. More information about the supported file types can be found in the sections
about the GIS layers.
3.1.3 Agent parameters
Agents and their parameters can either be set in the model itself or from outside. For local simulations
these parameters can either be set for all agents or per individual agent. If set for all agents, all of them
will have the same parameter start-values. If this is desired keep reading here, otherwise skip to the next
part where agent initialization files are described that allow to give each agent its individual parameter values.
If all agents (of the same agent type) should receive the same input parameter values, this can be done as
shown with the wolf agent in listing 14. In line 27 the so called mapping allows the assign each parameter
a certain value. Inside the curly braces, each individual parameter that has been marked with the external
keyword has to be included. In the wolves’ case, these are the Energy and EnergyMax attributes. Each of
them has to be placed inside its own curly braces, following the notation shown. The value assigned can
either be integers, reals, strings or booleans. Please note that strings have to be enclosed in quotation marks
(”value”:”example”). For boolean values the correct way of formatting is lower case (true or false). Integers
and floating point numbers can be used as shown.
3.1.4 Agent initialization files
To assign each agent individual parameter values so called ”agent initialization files” can be used. These
are CSV files are described in detail in the cookbook part of this handbook ( Agent Init Files (6.3.1) ). To
Page 14 of 60
Multi-Agent Modelling with MARS: A Handbook
use one of these input files, you have to put said file in the ”src-gen” folder and link them as shown in line
22 of listing 14. During initialization, each of the 10 created sheep will be assigned its individual parameter
values from the sheep.csv file. This works almost as with the data layers with the exception that you have
to provide the desired agent count. Without the ”count” parameter, no agents will be created.
0 {
1 "globals": {
2 "startTime": "2019-01-01T18:00:00.000Z",
3 "endTime": "2019-01-01T18:10:00.000Z",
4 "deltaT": 1,
5 "deltaTUnit": "seconds",
6 "output": "csv",
7 "options": {
8 "delimiter": ";",
9 "format": "en-EN"
10 }
11 },
12 "layers": [
13 {
14 "name":"BiomassRaster",
15 "file":"grass_4_100x100_v4.asc"
16 }
17 ],
18 "agents": [
19 {
20 "name":"Sheep",
21 "count":10,
22 "file": "sheep.csv"
23 },
24 {
25 "name":"Wolve",
26 "count":10,
27 "mapping": [
28 {
29 "parameter": "Energy",
30 "value": 100
31 },
32 {
33 "parameter": "EnergyMax",
34 "value": 100
35 }
36 ]
37 }
38 ]
39 }
Listing 14: Simulation config for wolf sheep model
Page 15 of 60
Multi-Agent Modelling with MARS: A Handbook
3.1.5 Summary
1. Go to src-gen folder where all the generated code is being stored
2. Create a simulation config that specifies how long the simulation should run, which layer information
should be used and how many agents should be created. This must be a JSON file.
3. Run a simulation by adapting the following command to your individual model
dotnet run -sm config.json -project Wolves.csproj
In the shown example the name of the simulation config is config.json. The name of the project is Wolf-
SheepPredation.csproj. Change these names accordingly for your simulation.
4 Cloud simulations
All simulations with the MARS system are being run on our servers in Hamburg. Once you finish building
your model you will have to upload it there. This gives you the advantage of using our resources to run
models as big as you want.
4.1 Preparing the Model for Execution
Before models can be executed on the MARS platform, a couple of preparation steps have to be made.
These steps transform the model from your written description file to computer understandable code that
can be uploaded to the MARS cloud in order to be executed there. A tool necessary to build such a packet
is the command prompt (or terminal for the OSX users). From this command prompt the model code is
transformed to a ZIP file which can then be uploaded to the cloud.
4.1.1 Opening a Command Prompt
The procedure differs slightly between Windows and Mac. See the suitable paragraph for your operating
system below.
Windows To open a command prompt in Windows you have to go to the start menu and type the three
letters ”cmd” into the search bar. Windows will suggest the program ”Command Prompt”. Click on it to
open the program. Once the command prompt is running it should look like this:
Mac Mac users should open a terminal, that is what the command prompt is called in OSX. This can be
achieved by either opening the spotlight search and typing terminal or by going to the application folder an
double clicking on terminal. Result should look like this:
4.1.2 Changing Directory to the Model
For both Windows and OSX users the following step is going to be similar. It is assumed that you have
set your Eclipse workspace to the Desktop of your computer. That way you can follow this tutorial easily.
Those who chose another location will have to adapt.
cd directory
Changing directories over the command line works by using the cd command. This is the same on Windows
and OSX. First you write the keyword itself and then you specify the desired directory you want to change
to. Since you might not know every’s folders content by heart, the following commands might help: dir on
Page 16 of 60
Multi-Agent Modelling with MARS: A Handbook
Figure 5: Command prompt on Windows
Windows and ls on OSX. Both show the contents of the current folder and thereby list the folders you can
change into.
As I said in the beginning of this paragraph I assume that you put you Eclipse workspace on the desktop.
Therefore the first command after opening the command prompt/ terminal is to change the director to the
Desktop. This is done by typing the following command into the terminal:
cd Desktop
If you did it right you should now be in the Desktop folder. This is indicated by the Desktop name in front
of the prompt (OSX). See figure 7 for details. If you are using Windows this change of directory is indicated
by the whole directory path as shown in figure 8.
The next step is to move inside the Eclipse workspace. This is where the models are located. To check if
the workspace is on your Desktop you can use dir or ls command after you changed the directory to the
Desktop. If you execute this command you should see something like whats shown in figure 9.
From there on use the cd command to move to the LIFEStarter folder inside your model. The general file
structure is discussed in the next section in case you need further information. To get there you have to go
through the following steps:
1. Change directory to the eclipse-workspace as discussed
2. In there you have to go to your model. You know the name, otherwise use dir or ls to look up the
available model names
3. Inside every model is a folder called src-gen, go into that
4. As last step you have to change the directory to the LIFEStarter folder which is located in the src-gen
folder
Page 17 of 60
Multi-Agent Modelling with MARS: A Handbook
Figure 6: Terminal on Mac OS/ OSX
Figure 7: Desktop on OSX
4.1.3 Model File Structure and LIFEStarter
All models are to be found in the Eclipse workspace. You should be asked where this folder should go when
you open Eclipse. Set it to the Desktop so you can find your models easily. In there you’ll find all models
that you created. Each is contained in its own folder.
In these model folders you’ll find two sub-folders. One is called src, this is where the .mars files are located
that you programmed. The other one is called src-gen and contains the automatically generated code that
can be run on the MARS system. In there you can find the LIFEStarter directory in which you have to
change to before you can build the model. This is the last step you have to make before you can upload
your model to the cloud.
4.1.4 Building the Model with Dotnet Core
For this step to work you have to have a stable internet connection. This step downloads up to multiple
megabytes of data onto your computer. If you are not connected to the internet it won’t work
Page 18 of 60
Multi-Agent Modelling with MARS: A Handbook
Figure 8: Desktop on Windows
Figure 9: List of folders on the desktop
If you want to understand why the step of building the model is necessary read-on, otherwise you can skip
this paragraph. Here it is going to get a bit more technical: The model you wrote using the MARS domain
specific language is a description of how your model should look like. From there the model is translated to
C#, a regular programming language that a computer can execute. You don’t see any of that because it
happens in the background every time you save your model. Before the model can be uploaded to our cloud
system you have to take that written code and make a package of it. This is what happens if you build the
model. Everything that the model needs in order to run is packed into one folder.
For every model the procedure is the same. As it has been described in the Changing Directory to the Model
(4.1.2) section, it is required to change the directory to the LIFEStarter folder inside your model prior to
this step. From there you can execute the following command:
dotnet publish -c release -o out
Once you typed this into the command prompt you have to hit enter. If you do this the first time it can
take a while. For repeated runs its going to work faster since most of the required things has already been
downloaded to your computer.
When the process finishes your terminal should look something like figure 10 (Windows). The most important
part is that you don’t see anything red on your screen. Red lines indicate that something went wrong in
which case these lines also contain the reason. This should only happen when your model has errors though.
Figure 10: Finished build process
Once the process finishes you should have a new sub-folder in the LIFEStarter directory with name out.
You need this folder for the next step.
4.1.5 Creating a Model Zip File
The last step before the model can be uploaded is to create a zip file that contains the just created out
folder. How this is done doesn’t matter so go ahead if you know how to create such a file. Those who aren’t
computer experts might use one of the following methods:
Page 19 of 60
Multi-Agent Modelling with MARS: A Handbook
• Create the zip file right here using the terminal (OSX only)
• Use the explorer (Windows)/ finder (OSX) to create the zip file
The quickest way is to use the terminal. OSX comes with the needed program pre-installed, I wish I could
say the same about Windows. If you execute the following command, your Mac will create a zip file by the
name of model.zip right here in the folder. You can name your zip file in any way you want (e.g. replace
model.zip with wolves sheep.zip).
zip -r model.zip out
Way number two is to use the file explorer. This works on both Windows and OSX. Open the folder where
your model is and navigate to the LIFEStarter folder just as we did using the command prompt/ terminal.
Once you’re in that folder do a right-click on the out folder that we created. If you use OSX select compress,
this should create a zip file by the name out.zip. On Windows go to sent to and then select compressed
(zipped) folder which results in the same out.zip archive. It makes sense to name the file in a way that you
know what this folder contains so that you will still know in two weeks or so.
4.2 MARS Cloud Basics
The MARS cloud system is being run on the servers of the University of Applied Sciences. Its usage is free
so you can run as many simulations as you want. Please use the following link to get there:
www.mars.haw-hamburg.de
4.2.1 Creating an Account
Before you can use the system you have to create an account. This can be done by clicking on the Register
Now! button on the right side of figure 11. Please fill in your personal information and remember the
username. This in combination with the chosen password will give you access.
YOU WON’T RECEIVE A CONFIRMATION EMAIL. Someone of the Mars group will have to unlock
your account. Until this hasn’t happened, you cannot access the system.
4.2.2 Login to the System
Once your account has been unlocked you can log-in and use the system. To do this, you’ll need your
username and password. Please don’t use your email address instead of the username, this will NOT work.
After you have logged in, you can go ahead with the next steps and use the system as much as you want.
4.2.3 Working with Projects
The first thing to understand when working with the MARS system is that everything you do is separated
into projects. You can use them to work on multiple ideas at a time or just to structure your work. Figure
12 shows a view of the user interface with a couple of projects. Before you can work on a project you first
have to select it by clicking in the upper-left corner of the project itself (marked with ”1”). New projects
can be created using the Create button in the lower-left corner (marked with ”2”).
4.3 Importing Files
This section will cover the upload process to the MARS cloud. Once you have registered, are logged-in
and have created a project it is time to upload your model and potential input data for the simulation.
Everything upload related can be found in the import panel.
Page 20 of 60
Multi-Agent Modelling with MARS: A Handbook
Figure 11: Login view of the MARS system
Figure 12: List of projects in the projects view
Page 21 of 60
Multi-Agent Modelling with MARS: A Handbook
Figure 13: Upload process for a model
4.3.1 Uploading Models
The first thing you wan’t to do is to upload your model. Prerequisite for this are the steps described in
Preparing the Model for Execution (4.1) . Once you have created the described zip file you can upload it
here. To do so click on the choose file field marked with a red 1 in figure 13. This prompts you with a
file picker in which you select the zip file you created earlier. Next you select the type of the upload in the
drop-down menu marked with a red 2 in figure 13. Since this is a model, you’ll select model as type. Next
you press the green upload button. Once the process is finished the uploaded model will appear in the top
half of the window.
4.3.2 Uploading GIS Data
If your model contains a raster-layer you will upload that GIS data in the import panel. The process is the
same as for model uploads described above. Instead of the zip file containing the model you will upload the
ASC file with the raster. Read more about the supported file types in section raster-layer (5.13) . Click
the choose file field, select the ASC file and then select GIS as type. The last step is to click on the green
upload button.
4.3.3 Uploading Agent Init Files
The last type of data you can upload are so called agent init files. When parameterizing agents in bulk you
use these files. Read more about them in the Agent Init Files (6.3.1) section. Uploading them is the same
as described above. Select the desired agent init file which should be in csv format, choose the Agent Init
CSV type and press the upload button.
Page 22 of 60
Multi-Agent Modelling with MARS: A Handbook
Figure 14: Scenario view
4.4 Scenarios and result configs
Scenarios and result configs specify the parameters of a simulation run as well as the results. They define
what is going to be simulated and what will be contained in the results . Main purpose of scenarios is to set
the overall simulation length and assign data to agents and layers. Data that has been uploaded previously
will be connected with the model during this step. Once the scenario is filled out, the result configuration
is produced to define the desired simulation output in terms of result data. Here you specify which agent
variables and layer information are going to be saved for a subsequent analysis.
4.4.1 Creating Scenarios
Everything scenario related is to be found in the Scenarios section which is shown in figure 14. New scenarios
are created by clicking on the Create button marked with 1 in figure 14. If you click it, a popup will show and
ask you to name the scenario and to select a model on which the scenario will be based. Choose a meaningful
name and describe the scenario if needed. The creation process works as well without the description. Now
you should see your new scenario in the center of the screen. In the example in figure 14 the scenario was
named wolf sheep scenario 1, yours will be named accordingly.
4.4.2 Filling out Scenarios
The overall structure of scenarios consists of three parts. Part one are the agents and their parameters. Here
you specify how many agents you want to have in your simulation and assign them values from previously
uploaded agent init files. Part two contains the layers. Layer input data like raster files or time-series data
will be assigned to the layers in that section. The last part is there to specify the simulation start- and
end-time as well as the duration of ticks.
Page 23 of 60
Multi-Agent Modelling with MARS: A Handbook
Figure 15: Standard agent parameters in a scenario
Lets start with the agent parameters. For every agent in your model the scenario will display its name and
at least four fields as shown in figure 15. Here you specify the starting position, the desired amount of agents
and the frequency in which the agents are supposed to be simulated.
CoordinateX: x-value of all agents starting position (all agents = all agents of that type)
CoordinateY: y-value of all agents starting position ”
TickFrequency: This specifies the frequency in which the agent’s tick method will be executed. Agents
can be simulated in every tick, then the TickFrequency should be set to one. If the agents should be
simulated only every second tick, set the TickFrequency to two. Every third tick → set to three, you
get the idea.
InstantiationCount This is where you set the amount of agents you want to have in the simulation (of
that agent type). This number must be greater than zero so you have to at least create one instance
of every agent.
Other attributes your agents have will only show if you marked them as external in your model. See
external (5.4) section to learn all about that. To fill out the information you start by clicking on the small
pen symbol marked with 1 in figure 15 which opens up the input field as marked with 2. Once you typed in
the desired value you press on the arrow marked with a 3 to lock it in. Now the value should look like in the
box marked with a 4. After pressing the Apply button in the bottom left corner the values will be saved and
marked with a little checkmark to indicate that the agent mapping is finished and valid. An alternative to
filling out the parameters manually is to drag and drop field from an agent init file to the respective agent
parameter. The agent init files should appear on the right side as shown in figure 14. Before you can assign
values from an agent init file you first have to upload said file. See Uploading Agent Init Files (4.3.3)
section for more information.
Now we take a look at the layers of your model. Only raster-layer and ts-layer will be shown since
these are the only layer types that you can assign data to. As with agent files you will have to upload the
layer data prior to the scenario so that you can use them here. On the right side as shown in figure 14
you will find these files (marked with 2). In the example you can see a single raster file by the name of
grass 4 100x100 v4.asc. Figure 16 shows more details about the file. To map the file to a layer simply drag
the red colored oval onto the layer. The result should look like figure 17 where you see the completed mapping
of the grass ASC file onto the Biomass(-layer). Once the mapping has been completed and you clicked Apply
in the bottom left corner your input will be examined and tagged as valid (green checkmark) if it was correct.
Page 24 of 60
Multi-Agent Modelling with MARS: A Handbook
Figure 16: Uploaded layer input data
Figure 17: Grass ASC file mapped on the biomass layer
The last step of the scenario is to set the global parameters for the simulation. They specify when the
simulation will start and end as well as the duration of a simulation step. For start- and end-time the
process is simple. You click in the value box and a time-picker will open that allows you to set the date
and time when the simulation starts. Same goes for the simulation end. Next you set the duration of each
simulation step. This might seem a bit tricky but it is straightforward if you understood the concept so bare
with me.
Example: You set the start time to now and the end time to one hour in the future. If you take a look at
the DeltaTUnit parameter shown in figure 18 you will see that it offers different time intervals ranging from
microseconds to years. This lets you choose the intervals that will be applied to the duration you specified
through start- end end-time. In this case we have an hour in total. If we set the DeltaTUnit to minutes, we
will have sixty simulation steps since one hour divided into minutes gives us sixty. If we would set it to hours
we would get one simulation step while setting it to seconds would give us 3600 steps. So far so good now
what does the DeltaT parameter do? In most situations you will set it to one (1). But in case you wan’t
your simulation to do a simulation step every three minutes instead of every minute as describe before, you
would set it to three (3). Instead of sixty steps as before when the DeltaT was 1 you now divide the hour
by minutes (60) and then you divide by three (3) which gives you twenty ticks. What this does is it spaces
out the tick execution interval thereby reducing the amount of simulation steps.
The most important thing to understand about this whole time thing is that it is only defining the inner
clock for the simulation. The actual simulation execution time (real time as you know it) will have nothing
to do with what ever you set here. Even if you set the simulation execution to many years it can still run
in a few minutes. You set the simulation time so that the simulation itself can run in any point of time.
This is necessary if you use time-series data that has a time constraints (is only valid for a specific point in
time). If you use the ts-layer functionality in your model you will have to select the start- and end-date
Page 25 of 60
Multi-Agent Modelling with MARS: A Handbook
Figure 18: Global parameter determining the length of the simulation
carefully. For all other models it is only necessary to select the four parameters in a way that you get the
desired amount of ticks (simulation steps).
4.4.3 Creating Result Configs
Simulations calculate something and that something (simulation results) should be saved in a way that one
can analyze it afterwards. Since most models produce a lot of results it makes sense to reduce this amount
to the results you’re actually interested in. This is where Result Configs come into play.
But lets start with more information about simulation results in general. Every agent has a position and an
ID and in every tick this information is persisted. If you wan’t to save more information from an agent like
the current value of certain agent attributes you will have to enable this since this isn’t by default. Agent
attributes annotated with the observe keyword will be saved in every simulation step. More information
can be found in the observe (5.10) section. For raster-layers the concept is similar. The layer itself is
initialized with a file that you upload prior to the simulation execution. If the agents change the information
contained in that layer you can save these changes by storing the layers current values (whole grid) after a tick.
The way you save these things is to go to the Output section where you create a new Simulation Config.
If you open the section you will be asked to select the model you want to create the output configuration
for. Once you have done this your screen will look like figure 19 where you can see the agents and layers
in the model. This is marked with a red 1. For each agent you can open the tab where you will see the
agents attributes in on the right side. Each of these attributes will be saved after every simulation step. If
you don’t want this, you can deselect the respective attribute by clicking on the checkbox next to it. For
raster-layers the window will look exactly like figure 19. First of all you can select whether you wan’t to
output the layers values at all by using the big switch. And second you can decide how often this output
will happen. Marked with a red 2 is the little dropdown menu in which you can select either Read-Only or
Dynamic. With the first option the layers data will be saved once when the simulation starts (before the
first tick). If you select option two the layers data will be saved after every tick so that you can go through
the different stages during result analysis. The last step is to press the Save button so that the configuration
is saved. You can come back to existing configs at any time, change and re-use them.
Page 26 of 60
Multi-Agent Modelling with MARS: A Handbook
Figure 19: Result configuration for wolf sheep grass model
4.5 Conducting Simulations
Once you have gone through the described steps you are ready to run the first simulation. This section will
include the last instructions on how to actually start a simulation and monitor the progress.
4.5.1 Simulation Plans
Simulation plans connect the model with scenarios and result configurations. When you open the Runs sec-
tion you will be presented with a view similar to figure 21. The figure shows a view for the wolf, sheep, grass
model with two simulation plans already created. To create a new one click on the Create button marked
with a red 1. This will open a popup shown in figure 20 where you will be asked to name the simulation
plan and choose a scenario or mapping configuration as well as an output configuration/ result config. After
entering these information press the Create button to save it and return to the main screen.
If you want to delete a simulation plan click on the delete button that looks like a trash-bin. This button
is marked with a red 3 in figure 21. Deleting the simulation plan will delete the simulations based on said
plan as well and the deletion will not work if one of these simulations is still running.
4.5.2 Running Simulations
Simulations can be started once a simulation plan has been created. In figure 21 you can see example simu-
lation plans from the wolf, sheep, grass model. Each of them has the Play button that is marked with a red
2. If you press this a simulation will be started in the MARS cloud system. These simulations are shown in
the lower half of the figure where you can see the plan they are based on, an ID, the start date as well as
status and the current tick of the simulation (marked with a red 4). To get an update on the current status
you can press the Reload button (red 5 mark). The view will NOT update itself.
Page 27 of 60
Multi-Agent Modelling with MARS: A Handbook
Figure 20: Creating a new simulation plan
Figure 21: View of the simulation section
As with the simulation plans the simulation runs have two buttons to manage them. Marked with a red 6
is the stop button which aborts the simulation run. Once stopped, the simulation can not be resumed. If
you wan’t to delete a simulation run you can do this by clicking on the trash-bin symbol marked with a red 7.
The last two buttons marked with red 8 and 9 show the simulations logs and open the result view. More
about the result view and how to analyze simulations will follow in the next section. To get there click on
the button marked with 9. Simulation logs show the console output of the running simulation. If you click
on the icon marked with the red 8 a popup will open showing the logs.
Add new image with visualization button instead of figure 18
4.6 Analyzing Simulation Results
The MARS system offers a couple of ways to analyze simulations ranging from the logs to a visual analytics
dashboard.Add Jans visualization as third option of Analysis + add reference to his Springsim Paper
Probably one of the best features is that you can analyze while the simulation is still running so you don’t
have to wait until it finishes.
Page 28 of 60
Multi-Agent Modelling with MARS: A Handbook
Figure 22: Result view of a wolf sheep grass model simulation run
4.6.1 Agent Populations
The result view looks like shown in figure 22 and is basically divided into four parts as marked with the
rectangles of different color. The red rectangle on top shows the agent population of a model. On the right
side of it you see the map legend of the agents and layers shown in the diagram. Said diagram displays the
agent count over the simulation runtime. For each agent type the total count for each tick will be shown. If
selected in the result config, the raster-layers sum of values for all grid-cells will be shown as well.
4.6.2 Spatial Analysis
The blue box in figure 22 shows a map of the simulated area. In the top of it you can select the raster-layer
that will be the surface for the agents moving around. On the right side you see a scale that depicts the
rasters values shown on the map. The agents themselves are the little points moving around. Directly below
the surface selection menu you’ll see the currently displayed tick. With the controls in the green box on the
left you can change that. This gives you full control to show certain ticks or to start an animation of a range
of simulated ticks.
4.6.3 Agent Attribute Analysis
The brown box on the right contains an analysis of the agent specific attributes. In this example the wolf
and the sheep agent both had two attributes hunger and energy which are displayed in blue and red. As
with the spatial analysis you can view the attributes for a specific tick. To do that you have to select the
tick on the right side in the green box.
4.6.4 Download Results
If the offered analysis tools aren’t enough you can also download the results. For this purpose the green box
on the left contains a Dataset Download button. Here you can select the agent and the tick you wan’t to
download data for. The field query is sent to our MongoDB where all the results are being stored. Feel free
to enter any query to our database, you’re not limited to the default entry shown. The resulting information
will be packed into a CSV file that you can download afterwards.
Page 29 of 60
Multi-Agent Modelling with MARS: A Handbook
5 Language Reference
5.1 agent
Agents are the smallest entity in each simulation. They are the building blocks of it all. Creating them
works through the agent keyword. They live on layers and have therefore to be created with the following
syntax:
agent agent name on layer name {}
The first keyword ( agent ) tells the model that a new agent type will be created followed by the on keyword.
This defines on which layer the new agent-type will live. Layer name is the name of the layer where the
agent will be created on. Agent definitions end with curly braces {} which enclose the agents behavior.
Behavior is specified through the initialize and tick methods. See sections tick (5.17) and initialize
(5.5) for more details. Agent attributes are managed by variables on which you can read up in section
Variables (2.4.2) . More on layers can be found in here: layer (5.7)
5.2 distance
If you wan’t to calculate the distance between two agents, you can do this by using the distance command.
This returns a decimal number, specifying the gap between them. The command works by writing the
distance keyword and adding the agent ( other agent ) afterwards to which the distance should be calculated.
distance other agent
Listing 15 shows an example how this can be used in a model. The wolf agent tries to find the nearest sheep,
this isn’t new. But before he eats it, he checks the distance (line 5). If the distance is equal to zero, this
means that he is on the same grid cell as the sheep. In that case he eats the sheep, otherwise he doesn’t.
0 agent wolf on AgentLayer{
1 tick{
2 var nearestSheep = nearest sheep
3 i f(nearestSheep != nil){
4 move me to nearestSheep
5 var distanceNearestSheep = distance nearestSheep
6 i f(distanceNearestSheep === 0){
7 nearestSheep.BeEaten()
8 }
9 }
10 }
11 }
Listing 15: Wolf agent checking the distance to the closest sheep
5.3 explore
Exploration of the environment is a vital part of every model. The agents sense what is around them and
act based on that. For this purpose the DSL includes the explore and nearest keywords. In this part we’ll
exclusively talk about explore . The next section (5.9) is about the nearest command.
Page 30 of 60
Multi-Agent Modelling with MARS: A Handbook
Please read the null reference exceptions paragraph further down prior to using explore command in
your model. This will save you a lot of trouble later on.
The explore command is available in two stages of sophistication. Depending on your desired result one or
the other will be used. If you are trying to find a specific agent type the basic version is sufficient. Complex
queries can be used as well. For those, the second version has been build. See the next paragraph Explore
with predicate for details.
Explore basics The basic version of the explore is designed to find specific agents. The command
consists of two parts. Part one is the actual explore keyword, the second one ( agent type ) specifies the
desired agent type. By using this command you can find all agents of that type. The result of the operation
is an array of agents that is sorted in ascending distance to the current agent.
explore agent type
Listing 16 shows an example in which the wolf agent tries to find sheep. This is done in line 2 where the
explore command is used. As result of the explore operation, the agent receives a list of sheep in ascending
distance. This result is saved directly to a variable with the name sheep. In line 3 the agent uses the first
list element (the closest sheep) as destination for his movement. Without checking if the wolf is on the same
grid cell he then proceeds to eat the sheep by calling its BeEaten() method.
0 agent wolf on AgentLayer{
1 tick{
2 var sheeps = explore sheep
3 move me to sheeps[0]
4 sheeps[0].BeEaten()
5 }
6 }
Listing 16: Wolf agent exploring sheep agents
Explore with predicate More sophisticated explorations can be performed using a predicate. These
predicates allow to specify certain conditions that the desired agent has to meet. For example the wolf could
look for sheep with an energy level above 30 instead of just trying to find any sheep. For the latter request,
the basic explore command is sufficient. As the base version, the advanced explore operation starts with
the explore keyword followed by the desired agent type . Following up is the where and the actual
predicate enclosed in brackets.
explore agent type where [ predicate ]
The syntax for specifying predicates follows a certain scheme. Inside the brackets one has to define which
letter is going to represent the single agents viewed during the exploration process. Take a look at line 2 in
listing 17 for an example in which the wolf tries to find sheep with an energy level of at least 30. First the
wolf states that the sheep are going to be represented by the letter x. After this, the little arrow denotes
the start of the condition. No matter how conditions are defined, they have to evaluate to a boolean value
of either true or false. In the wolf’s case the check whether a sheep has an energy level of thirty or above
evaluates to true if the sheep has more than thirty energy points or false if the sheep’s energy level is below
thirty-one. This check is performed by calling the sheep GetEnergy() method as base for the comparison.
Note that you cannot access other agents variables directly and therefore have to define passive actions. In
line 16 of listing 17 the sheep agent implements the aforementioned method.
Page 31 of 60
Multi-Agent Modelling with MARS: A Handbook
0 agent wolf on AgentLayer{
1 tick{
2 var sheeps = explore sheep where [x => x.GetEnergy > 30]
3 move to sheeps[0]
4 sheeps[0].BeEaten()
5 }
6 }
7 agent sheep on AgentLayer{
8
9 var Energy : integer = 40
10 tick{
11 move me to #(random(10),random(10))
12 }
13 passive BeEaten(){
14 k i l l me
15 }
16 passive GetEnergy() : integer {
17 return Energy
18 }
19 }
Listing 17: Wolf agent looking for sheep with an energy level of over 30
Null Reference Exceptions Caution is advisable when using the explore command. The yielded list
of desired agents might be empty. It is sorted in ascending distance to the current agent but only if there
are agents of that type. As long as agents of that type are available, the command works absolutely fine. If
there aren’t any agents of the desired type left or a predicate has been used to e.g. find only agents with
an energy level of over 30, the command can return an empty list. Until now, the explore operation itself
is completely safe. Problems arise from using the list of agents that has been returned without checking it
first.
If the result of a explore command is used as input for other commands like for example the move action,
the simulation might crash. This is due to the fact, that the agent then tries to move towards a non existing
agent which naturally leads to a so called null reference exception. Programmers reading this handbook
should be familiar with the problem. For those not proficient in coding: this is very bad!
Luckily there is a solution to it. Whenever we use the explore keyword we have to add a conditional
statement that checks if the list returned by the command contains at least a single entry. Listing 18 shows
an example from the wolf, sheep, grass model where the wolf looks for sheep and then moves to the closest
one. This is the safe version of listing 16.
We start inside the wolfs tick method. In line 2 the wolf explores its surroundings by using the explore
command. The results of that exploration are stored in a variable named sheep. Contrary to line 3 in listing
16 the wolf now revises the result of the explore command prior to using it as destination for the move
operation. This is done in line 3. If the first entry in the list of found sheep isn’t nil, then, and only then,
the agents proceeds with the move command. The word nil comes from the latin word nihil and means
”nothing”. So the agents checks if the entry is something else than nil (nothing) and then executes the
move operation. If the first entry is indeed nil, then the agents skips to the else path where an alternative
action should be placed.
With this check in place, the model will not execute potentially bad code and won’t crash. It is up to you
Page 32 of 60
Multi-Agent Modelling with MARS: A Handbook
as a modeler to deal with the case where there is no sheep available appropriately.
0 agent wolf on AgentLayer{
1 tick{
2 var sheeps = explore sheep
3 i f(sheeps[0] !== nil){
4 mov me to sheeps[0]
5 sheeps[0].BeEaten()
6 }
7 else{
8 //specify alternative action
9 }
10 }
11 }
Listing 18: Wolf agent safely looking for sheep without risking a null reference exception
5.4 external
When an agent’s variables are defined, they have to be initialized with a value. This value can either be
set directly in the code or can be filled-in later from a file. The use-case for setting agent variables later is
that you can easily initialize a large amount of agents. Each of them with individual attribute values. For
that purpose it is possible to create agents from a CSV (comma separated value) file that includes these
individual attributes.
An example from the wolf, sheep, grass model would be if each agent should have its own set of starting
parameters. The standard way would be to create the agent’s variables and assign them either a fix value
or a random value. Wolfs could have a starting energy level of 100 and a random hunger level between zero
and fifty. Take a look at listing 19 where line 1 shows the assignment of a fixed value. No matter how many
wolf agents you use during the simulation, all of them will have a starting energy level of 100. The second
option is to assign a random value in between zero and fifty as starting point as shown in line 2. Using this
technique, every wolf agent would start with a random hunger level in between these bounds.
0 agent wolf on AgentLayer{
1 var Energy : integer = 100
2 var Hunger : integer = random(50)
3 }
Listing 19: Wolf agent variable definition
Every time you simulate, these random values would be set differently. If you want your simulations to
always start up with the exact same set of variables, but at the same time want your agents of the same type
to have different values you can use the external keyword. This enables you to (later-on during simulation
creation) initialize these values from a file. Another good thing about using these files is that they only have
to be created once. The general idea for the file is that every line represents a set of initial values for one
agent.
To use this in your model, you have to write the external keyword before each variable that you wan’t to
set from a file. Additionally the starting value has to be left blank. In listing 20 you see the exact same wolf
agent as in the code snippet above. Only this time the wolf agent variables Energy and Hunger are created
without an initial value.
Page 33 of 60
Multi-Agent Modelling with MARS: A Handbook
0 agent wolf on AgentLayer{
1 external var Energy : integer
2 external var Hunger : integer
3 }
Listing 20: Wolf agent with external variable initialization
Please familiarize yourself with the syntax for using the external command during a variable definition. As
in a regular definition we write the var keyword, give the variable a name and specify the desired variable
type after a colon. The new thing, when initializing a variable from outside, is the fact that instead of
following up with an equals and an initial value, you write the external keyword at the beginning before
the var command.
external var variable name : variable type
You can mix the different ways of creating variables in an agent. Some attributes can be set fixed, some
can be created from a random value and the remaining ones from a file.
Now that you know how to use the external keyword, lets talk about the initialization files: There is only
one type of files support, and that are comma separated value files (CSV’s). You can use any text editor
to create such files since they are simple text files. The first line is used as header where you specify the
names of the variables in your model. Every variable name is separated by a semicolon. By separating
these names by semicolons you are basically creating a table. Each variable name is essentially a column
(just as in Excel). It is very important that you don’t leave spaces in between the names or the semicolons.
Additionally it is to be noted that the whole file to variable mapping process is case sensitive.
Let me give you an example: If your variable in the model has the name energy, then the first line of the file
must contain energy. It won’t work if you type Energy, eNergy, energy or anything else but the very same
notation.
Now that you have created the header and assigned each column a name you can go ahead and create as
many lines beneath as you want. Every line will be used as one set of starting parameters for one agent.
Depending of the type of parameter you want to put in the agent init CSV you have to use a slightly different
syntax. Integers and floating point numbers can be set directly, please note that for floats you have to use
a point instead of a comma. For strings you have to set the value in quotes (”value”). The most important
thing is that you separate each of the values by a semicolon. When you want to save the file, make sure you
specify the file ending as ”.csv” so that the comma separated value file is saved as such.
0 Energy;Hunger
1 10;14
2 12;40
3 24;2
4 5;80
5 70;5
Listing 21: Example initialization file for the wolf agent
In the first line of listing 21 you can see an example file of the wolf agent. Remember, it had two external
variables named Energy and Hunger. For that reason the CSV file has two columns named Energy and
Hunger. If you were to use that file to create wolfs, you could initialize five agents since the files has five
Page 34 of 60
Multi-Agent Modelling with MARS: A Handbook
lines with agent parameter values. The first one would have an energy level of 10 and a hunger level of
14. Wolf number two starts with 12 energy points and a hunger of 40. This goes on until you reach line
number five which would be used to create the last agent with an initial energy level of 70 and a hunger of five.
Another example agent init CSV with different variable types can be found in the cookbook section of this
handbook. See section Agent Init Files(6.3.1) for details. For more information about how to upload these
files to the MARS cloud and how to use them in scenarios see sections Uploading Agent Init Files(4.3.3) and
Filling out Scenarios (4.4.2) sections.
5.5 initialize
The two most important parts of each agent are the tick and the initialize methods. While the tick
method defines what each agent does in a time-step and is executed over and over again, the initialize
method is only performed once. Before the first simulation step takes place, this method can be used to
set-up all the basics in an agent prior to the actual simulation start.
initialize (){}
The syntax is equal to the tick method. Write the initialize keyword, add empty braces and append a
pair of curly braces. Everything enclosed by the curly ones is whats being executed. For those proficient in
programming, the initialize method is the agent constructor.
In listing 22 you can see an example of the wolf agent with its initialize method. Besides defining variables
and specifying a tick method the wolf uses its initialize method to set a random starting position and to
assign a value to the Hunger variable. This is done in lines five through eight. When the simulation starts
the program gets executed in the following order:
1. Create the agent variables and fill them with values. This can either happen directly in code or through
an external file. See sections Variables (2.4.2) and external (5.4) for details
2. Call each agent’s initialize method and execute the enclosed commands once
3. For each time-step, execute the commands inside the tick method until the simulation finishes
0 agent wolf on AgentLayer{
1 var Energy : integer = 10
2 var Hunger : real
3
4 i n i t i a l i z e(){
5 pos at #(random(10),random(10))
6 Hunger = 15.3
7 }
8
9 tick{
10 move 1 up
11 Energy = Energy - 1
12 i f(Energy<=0){
13 k i l l me
14 }
15 }
16 }
Page 35 of 60
Multi-Agent Modelling with MARS: A Handbook
Listing 22: Wolf agent with an initialize method to set its start position to a random location
5.6 kill me
Depending on the kind of model you are writing, your agents might be expected to die. To account for this,
we added a special kill me command to the language that allows to kill an agent. If the agent should die,
use the kill me command as shown in listing 23. The wolves defines a variable Energy that represents his
energy level as an integer. This variable is only there for demonstration purpose. In the wolfs tick method
he decreases the energy level and afterwards checks if the energy is equal to zero or even smaller. This is
done in lines 4 and 5. After one simulation step, the wolf has an energy level of 5 and the check in line 4
passes as false. In the next simulation step the energy is reduced by another 5 which leaves the wolf with
an energy level of 0. The check in line 4 goes through and the command in line 5 is executed, which kills
the wolf. After this line of code has been executed, the wolf has died and will not be part of the simulation
anymore.
0 agent wolf on AgentLayer{
1 var Energy : integer = 10
2 tick{
3 Energy = Energy - 5
4 i f(Energy <= 0){
5 k i l l me
6 }
7 }
8 }
Listing 23: Wolf agent dying from not having enough energy
5.7 layer
Layers serve two purposes. They are containers for agents and can contain data as in the case of raster-layer
and vector-layer . They are used to manage the agents and allow for exploration functionality which will
be covered in the explore (5.3) section. For now, the layer keyword will be used as container for agents.
Later in this handbook, layers with time-series capabilities ( vector-layer (5.21) ) and GIS functionality (
raster-layer (5.13) ) will be introduced. In general, new layers are created by using the following syntax:
layer layer name
The layer keyword tells the model that a new layer with the name layer name should be added. The
layer should be named so that it can later be referred to as it is the case with creating new agent types.
5.7.1 Layer Attributes and Functions
Basic layers (the ones that contain agents) can fulfill different tasks in the model. They can store information
and even offer actions that can be used by the agents. Listing 24 shows an example model that demonstrates
how this works. In the scenario the firewood collector agent can go out and collect firewood that is then
stored in the village. Alternatively the agent can check if the village has enough firewood so that he can take
it from there instead. In the example, the layer is used as shared resource between the agents. To implement
this, the agent layer (AgentLayer) will offer two methods. The first method (StoreFirewood) is performed
by the agents when they return from collecting. The second method (WithdrawFirewood) can be used to
Page 36 of 60
Multi-Agent Modelling with MARS: A Handbook
take firewood when there is plenty.
In line 17 the agent checks how much firewood is available in the village. The layer stores this information in
the AmountOfFirewood variable that can be read by the agents. If there is enough firewood, the agent will
take it from there as shown in line 18 by using the WithdrawFirewood method. In case there isn’t enough
available in the village (line 20), the agent will go and look for firewood in the surroundings. When he comes
back from collecting, he puts some of it in the villages storage so that others can take from there. To store
firewood he uses the StoreFirewood method.
0 model firewood
1
2
3 layer AgentLayer as agentlayer{
4 var AmountOfFirewood : integer = 0
5
6 def StoreFirewood(KiloFirewood : integer){
7 AmountOfFirewood = AmountOfFirewood + KiloFirewood
8 }
9
10 def WithdrawFirewood(KiloFirewood : integer){
11 AmountOfFirewood = AmountOfFirewood - KiloFirewood
12 }
13 }
14
15 agent FirewoodCollector on AgentLayer{
16 tick{
17 i f(agentlayer.AmountOfFirewood > 5){
18 agentlayer.WithdrawFirewood(5)
19 }
20 else{
21 //go get firewood
22 //...
23
24 agentlayer.StoreFirewood(3)
25 }
26 }
27 }
Listing 24: Firewood collectors using a layer as shared resource
5.8 move
Most agents will move during simulations, the basis for that is the positioning system. This system is based
on a grid which spans the whole simulated area and can have any size. The actual size is determined by the
user of the MARS system and will be specified once the model has been uploaded for simulation execution
in the MARS cloud.
Page 37 of 60
Multi-Agent Modelling with MARS: A Handbook
Figure 23: Coordinate system for the models
5.8.1 Coordinate System
Starting in the lower left corner, the coordinate system stretches the whole simulation area. The actual size,
meaning the number grid cells in x- and y-direction will be set later during simulation setup in the MARS
cloud. Coordinates in the system are composed of two values for x- and y-position thus the notation as
shown in figure 23. The position in the lowest left corner is (0/0). Moving one field to the right leads to
(1/0) whereas one field to the top would lead to position (0/1). In a simulation model, the coordinates are
noted in the following way:
#( x-coordinate , y-coordinate )
Please note that the coordinate system has its bounds. It is not possible to move to negative coordinate
like (-3/-4), (-10/6) or (5/-7). Moving outside the defined grid is not possible either. This means that
the agents can’t go to (101/101) if the grid has the dimensions of 100x100 fields. The agents will stop
at the borders and will not move farther. There is NO such thing as a wraparound that inserts the
agents at the opposite site of the grid.
5.8.2 Movement Command
The agents can move by using the move me to command. It is up to you as a modeler to move the agent
either from one grid cell to another or even over multiple cells at once. Movements can be performed in
any direction so it is possible to go up, down, left, right and diagonally as well. The syntax for the move
command looks like this:
move me distance to destination
Page 38 of 60
Multi-Agent Modelling with MARS: A Handbook
First the move me command is written, followed by an optional distance parameter specifying how far
the agent (how many grid cells) is going to move. If this distance parameter is left out, a default value
of 1 is assumed so that the agent moves to the next grid cell corresponding to a step length of one. Again
this can either be up, down, left, right or diagonally. All of these movements have a length of 1, there is no
Manhattan metric involved. The next part of the move command is to write the to statement followed by
the destination the agent is supposed to move to. Destination can either be another agent or a coordinate.
Movement Examples
0 //start position: (1/1)
1 move me to #(0,0) //position: (0/0)
2 move me to #(1,0) //position: (1/0)
3
4 //start position: (10/10)
5 move me 5 to #(10,15) //position: (10/15)
6 move 10 to #(20,15) //position: (20/15)
7
8 //start position: (5/5)
9 move me 10 to #(8,5) //position: (15/5)
10 move me 10 to #(15,10) //position: (15/15)
11
12 //start position: (3/3)
13 move me 5 to #(-3,3) //position: (0/3)
14 move me 5 to #(0,-3) //position: (0/0)
Listing 25: Example movement actions
Line 0:
The agent starts at position (1/1). Executing the move command in line 1 moves him to position (0/0). No
distance parameter was specified so the step length is set to 1. If the agent moves towards position (0/0) he
does that one step at a time. Since the grid cell (0/0) is exactly one field away from the agents start position
of (1/1), the move command brings the agent there in one step. The agent has moved diagonally.
Now that the agent is at (0/0), the next move command (line 2) brings him to position (1/0). Again no
distance parameter was specified so 1 is assumed. The field (1/0) is one grid cell apart from (0/0) so the
agent can move there in one step moving to the right.
Line 4:
New start position is (10/10). The first move command (line 5) tells the agent to move 5 field towards
position (10/15). Distance to that position is 5 so the agent can move there in one step as specified.
Same goes for the move command in line 6. The agent starts at position (10/15) and is told to move to
position (20/15). Distance this time is 10 fields. Again the agent is told to move exactly that far which
leaves him at position (20/15).
Line 8:
The agent starts at position (5/5) and is sent 10 fields in the direction of (8/5). Since the direction coordinate
(8/5) is on the way but the 10 fields he is told to move is farer away than the 3 steps the destination is away,
the agents steps over the (8/5) field and keeps going in that direction until he reaches its new position (15/5)
which is 10 grid cells apart from the starting point. In line 10 the agent is told something similar. The
direction (15/10) is closer to the agent in terms of distance than the 10 fields he is told to move. Therefore
the agent heads in the direction of (15/10) and gets to its new position (15/15).
Line 12:
This example shows whats going to happen when the agent tries to exceed the coordinate system. Starting
Page 39 of 60
Multi-Agent Modelling with MARS: A Handbook
point is (3/3) with the first command telling the agent to move 5 field in the direction of (−3/3). The agent
can move in that direction but only until he hits the minimum x-coordinate of 0. Therefore he stops at
position (0/3). In the the next line the agent is told to move in the direction of (0/− 3) which, as before, is
outside of the valid coordinate space. The agent starts to move in that direction until he reaches position
(0/0) at which he cannot move further. His movement leaves him at position (0/0).
5.9 nearest
Another way of exploring the environment is the nearest command. Similar to the explore keyword,
this can be used to find agents. The feature that distinguishes the two commands is the GIS capabilities of
nearest . Besides finding agents, it is possible to find features on raster-layers and vector-layers as well.
The difference between nearest and explore is that the nearest command returns the closest point, not
all points as explore does. Even though one tries to find the nearest agent or feature on a raster-layer /
vector-layer , one receives that entities position. So the nearest functionality returns a position, not an
agent or raster/ vector feature.
The nearest command can lead to model crashes if you don’t treat the returned values right. Since
the nearest keyword returns the position of agents/ GIS features, it can only do so if the desired entity
is available. Please read the Null Reference Exceptions paragraph below prior to using nearest in you
model. This might spare you a lot of trouble later on.
Finding agents works similar to the explore command. First you write the nearest command, then you
specify the agent type that you want to find. As a result you get the position of the closest agent of that
type which can then be used to calculate a distance for moving there.
nearest agent type
When you are trying to find certain GIS features with the nearest command you have to modify it a bit.
We start again with the nearest keyword but then we add on afterwards. The last part of the command is
specifying the raster layer name / vector layer name . This tells the system on which layer it should look
for the closest feature. As with the basic version of nearest , you receive the closest position of the desired
feature, not the feature itself.
nearest on raster layer name
nearest on vector layer name
Additionally, the nearest function can be extended with a search radius. In the default setting, the nearest
command searches the whole simulated area to find either an agent or a feature on a GIS layer. If you wan’t
to limit this radius, thereby giving the agent a field of view, you can use the notation below. The radius
originates in the agents current position.
nearest agent type in radius
nearest on raster layer name in radius
nearest on vector layer name in radius
Page 40 of 60
Multi-Agent Modelling with MARS: A Handbook
Null Reference Exceptions When you use the nearest command you have to treat the results with
caution since there might be no result. Remember, the returned value of nearest is a position of either
an agent or a GIS feature. Problems can occur if the desired feature or agent doesn’t exist. In the wolf,
sheep, grass model this could happen if the wolf tries to find the nearest sheep but there aren’t any left.
Nearest would return an empty position since there is no sheep nearby. If the wolf was to use this empty po-
sition as input for the move command, the model would crash. Instead, the agent should be build in a way
that checks if the position is valid prior to using it as parameter for other commands like the move operation.
Listing 26 shows an example from the wolf, sheep, grass model where the wolf examines the resulting
coordinate before using them. In line 2 he tries to find the nearest sheep by using the nearest command.
Before he tries to go there (line 4), he checks the resulting position from the nearest operation. This is
done in line 3 where he checks if the result is something different than nil. Nil is the replacement value if
the nearest operation couldn’t find anything. It basically means nothing (latin: nil = nothing). In case the
coordinate is indeed nil, he wouldn’t execute the move operation but execute the else path.
0 agent wolf on AgentLayer{
1 tick{
2 var nearestSheep = nearest sheep
3 i f(nearestSheep != nil){
4 move to nearestSheep
5 nearestSheep.BeEaten()
6 }
7 else{
8 //specify alternative action
9 }
10 }
11 }
Listing 26: Wolf agent examining the results of nearest prior to using it
continue here
5.10 observe
Part of the simulation results are custom agent attributes. By default only the agents position is written in
the result database. That way you can examine the movement in the browser and look at population counts.
If you wan’t to have additional agent attributes added to the results, you can use the observe keyword.
Written before a variable, it leads to that variable being saved in every simulation step.
In listing 27 you can see a sheep agent with a variable name Energy. Before writing the var keyword, the
observe keyword has been added. In every simulation step that Energy variables value will be written to the
result database so you as a modeler can look at the current value for every simulated time step afterwards.
0 agent sheep on AgentLayer{
1 observe var Energy : integer = 40
2 tick{
3 Energy = Energy - random(3)
4 }
5 }
Listing 27: Sheep agents who’s Energy variable is added to the results in every simulation step
Page 41 of 60
Multi-Agent Modelling with MARS: A Handbook
5.11 pos at
Besides the move command there is another way of changing an agents position. Using the pos at keyword
you can set the agent position to a grid cell of your choice. The difference between the two commands is
that move actually moves the agent while pos at relocates the agent by basically beaming him there. If
you ask yourself when you should use which, consider the following: Whenever your agent is supposed to
move a certain amount of grid cells in a direction use the move command. When you know the agents
destination coordinates you can use pos at to get him there instantly. For the model it makes no difference
how the agent got to a position so feel free to use the command of your choice.
pos at destination coordinate
Using the command is very easy. Write pos at and add the destination coordinate in coordinate notation.
You can either do this with a coordinate or with a placeholder like the nearest command. In listing 28 you
can see the wolf agent using the pos at command to change its position. Line 2 shows him setting position
to coordinate (5/5). In line 3 he uses the pos at command to relocate to the nearest sheep’s position.
0 agent wolf on AgentLayer{
1 tick{
2 pos at #(5,5)
3 pos at nearest sheep
4 }
5 }
Listing 28: Wolf agent using the pos at to set its position
5.12 random
The random command creates random numbers in a specified range. These numbers will be in between zero
an a upper bound. The upper bound is specified through the parameter enclosed by parentheses.
random ( upper bound )
The generated numbers will be from zero up to the specified bound, but not the upper bound itself. Creating
a random number in between zero and five will be 0,1,2,3,4 but never five! Another example can be seen in
listing 29 where, in line 0, we create random numbers in between zero and three. Possible values are zero,
one and two, but not three.
0 random(3)
1
2 random(10)-5
3 random(15)+5
Listing 29: Examples on how to use the random function
If you want to create random numbers starting at another point than zero you will have to take a different
approach. Add or subtract the lower bound from the random value and specify the range you want by
adapting the upper bound. For example if you want to have random numbers between -5 and 5 you would
write it like shown in line 2 of listing 29. Possible values from that statement are {-5,-4,-3,-2,-1,0,1,2,3,4}.Same goes for the command in line 3 which produces random numbers in between five and twenty.
Page 42 of 60
Multi-Agent Modelling with MARS: A Handbook
5.13 raster-layer
Refine wording since the raster layer isn’t the only way to use GIS data anymore
If you want to use GIS data during simulation, the raster-layer is the way to go. This special layer type
allows access to rasterized GIS files in the ASC format. During simulation the agents can read information
from these files and even change them (writing access). Like regular layers the raster-layer has to be defined
in the beginning of the model.
raster-layer layer name as layer alias
Listing 30 shows an example model that includes a raster-layer and uses the whole capabilities of it: At first
a model is defined (name: wolf sheep grass), then an agent layer (name: agentLayer) is put in and at last
a new agent type (name: sheepAgent) is created on the agent layer. The raster-layer with the name Gis-
GrassLayer is created in line two. You start by defining the layer, giving it a name and then specifying the
alias by which it is referred to in the model code. Naming is done in the way that the name (GisGrassLayer)
is written in camel case and the alias (gisgrasslayer) in lower case. Once this is done the layer is ready to
be used by the agents. This usage can be divided into three groups: reading information from the layer,
changing the layers information and finding coordinates with certain features.
Starting with the last category: Take a look at line 8 where the nearest command is used in combination
with the raster-layer. Similar to the usage of nearest with agents this operation doesn’t return a value from
the raster-layer but a coordinate with a certain feature. The feature that the raster-layer is looking for is
a value not equal to the nodata value specified in the ASC file that will be added later to the simulation.
Take a look at the GIS ASC Files (6.3.2) section where you can find more information about ASC files
as well as an example file. What the nearest function does is trying to find the closest grid cell with an
actual value. That grid cell is the result and will be returned. For more information about the usage of
nearest in combination with the raster-layer please see section nearest (5.9) where the details are described.
Next usage scenario for the raster-layer is reading information from it. The type of information you can
read depends on the information contained in the ASC file. In general it is possible to read the values either
as integers or floating point numbers. Therefore the DSL offers two corresponding functions by the name of
GetIntegerValue and GetNumberValue. How they are used can be seen in listing 30 in lines ten and eleven.
Both functions return the value in their respective format (integer or real). That is why the lines start
with variable declarations to save these resulting values. The syntax for using the two commands is straight
forward. First you specify the raster-layer you want to read from, then you choose the format in which
you want to read the information. For both GetIntegerValue as well as GetNumberValue you have to specify
the coordinate you wan’t to have the value for. If you want to read values from the grid cell your agent is
currently on you just pass xcor and ycor . In case you want to read from a different grid cell you can
specify the coordinates alike.
0 model wolf_sheep_grass
1
2 raster-layer GisGrassLayer as gisgrasslayer
3
4 layer agentLayer
5
6 agent sheepAgent on agentLayer{
7 tick{
8 var nearestGrass = nearest on GisGrassLayer
9
Page 43 of 60
Multi-Agent Modelling with MARS: A Handbook
10 var a = gisgrasslayer.GetIntegerValue(xcor,ycor)
11 var b = gisgrasslayer.GetNumberValue(xcor,ycor)
12
13 gisgrasslayer.Increase(xcor,ycor,2)
14 gisgrasslayer.Reduce(xcor,ycor,5)
15 }
16 }
Listing 30: Model creation with a raster-layer
The third way of working with the raster-layer is changing its values. Increase and Reduce are functions
built into the DSL that allow to increase the value of a grid cell by adding something while the reduce
command allows to subtract something from the cells value. As with the commands to read from the layer
you have to specify a grid cell in coordinate notation for which you want to change the values. If it is the
same position the agent is on you can use xcor and ycor . The last parameter passed to the function is the
number/ amount you want to either add or subtract. Listing 30 shows examples for both commands in line
thirteen and fourteen. Please note that neither Increase nor Reduce return any values. Another example
of changing the values of a raster-layer can be found in section 6.5.5 where an observer agent is used to go
through all grid cells and update the values.
5.14 simtime
When you wan’t to know about the time during simulation you can use the simtime . It can either be used
to learn about the current tick you’re in as well as be used to find out the exact date and time. This means
you can let an agent do something after the 200th tick has happened for example. You can also use the
actual time to tailor behavior to a certain point in time like having wolfs howl when the moon is out.
5.14.1 Simtime Example 1
In this example the observer agent is using the simtime function to find out in which tick it is. If it reaches
the 20th tick a new wolf agent will be spawned at a random position. The comparison shown in line 2 of
listing 31 reads the simtime object and checks if the current tick equals 20. If that is the case the command
in line 3 is executed thereby spawning a new wolf agent.
0 agent Observer on AgentLayer{
1 tick{
2 i f(simtime === 20){
3 spawn wolf at #(random(100),random(100))
4 }
5 }
6 }
Listing 31: Observer agent using the simtime functionality
5.14.2 Simtime Example 2
The second example demonstrates another functionality of the simtime command. By using simtime in
combination with the Time package you can get exact information about the current year, month, day,
hour, minute or even second of the tick.
Page 44 of 60
Multi-Agent Modelling with MARS: A Handbook
Before using the Time package you have to include Mars as shown in line 2 of listing 32. With this included
you have access to the needed functionality. Take a look at lines 8 through 12 in the example. For each of
these lines we create a variable to store the received information (a-e).
The time (year, month, day, hour, minute, second) that the shown commands will return depend on
the simulation start date as well as the delta t set in the MARS cloud UI.
0 model wolf_sheep_grass
1
2 use Mars
3
4 layer AgentLayer
5
6 agent Observer on AgentLayer{
7 tick{
8 var a = Time.Year(simtime)
9 var b = Time.Month(simtime)
10 var c = Time.Day(simtime)
11 var d = Time.Minute(simtime)
12 var e = Time.Second(simtime)
13 }
14 }
Listing 32: Observer agent finding out about the exact time during a simulation
If you set the start date to January 1st of 2019 at midnight, the example will yield the following results in
the first tick:
Line 8: Variable a will return the number 2019
Line 9: Variable b will return the number 1
Line 10: Variable c will return the number 1
Line 11: Variable d will return the number 0
Line 12: Variable e will return the number 0
5.15 spawn
Creating agents during simulation can be done using the spawn command. This feature comes in handy
if your agents reproduce for example. Spawning can happen at any point in the simulated area. When you
create a new agent with the spawn keyword, the new agents initialize method will be executed once when
he is created. This is the place where you should specify the agents initial attributes. For more information
on initialize see section 5.5.
spawn agent type
Syntax for the spawn command is straightforward. First you write the keyword itself and then you add the
desired agent type of which a new agent should be created. While the simple version of spawn command
spawns a new agent at the position of the calling agent, the more elaborate one can spawn new agents at
any point in the simulated space.
Page 45 of 60
Multi-Agent Modelling with MARS: A Handbook
spawn agent type at coordinate
If you wan’t to spawn the agent at a position different from the current agent you simply add a coordinate
after the on keyword. The beginning of the spawn process is the same.
In listing 33 you can see the wolf agent using the spawn command twice. Line 2 shows him spawning a new
wolf at his current position. In line 3 he creates a new wolf at position (3/3).
0 agent wolf on AgentLayer{
1 tick{
2 spawn wolf
3 spawn wolf at #(3,3)
4 }
5 }
Listing 33: Wolf agent spawning new wolves during simulation
5.16 static
Agents can have static properties. This allows all agents of the same type to have a shared status than is
the same for every agent instance. Each agent can read and change that value, thereby changing it for all
agents. The static concept is the same as in the programming language C#. For more information you
can read up on it here.
5.17 tick
The tick method is the central method of every agent. Here you specify what each agent is doing during
each simulation step. These agent instruction go in between the curly braces. Inside the agents curly braces
you define the tick as shown in listing 34 where you can see the wolf agent with its tick method.
tick {}
0 agent wolf on AgentLayer{
1 var Energy : integer = 10
2
3 tick{
4 move 1 up
5 Energy = Energy - 1
6 i f(Energy<=0){
7 k i l l me
8 }
9 }
10 }
Listing 34: Tick example from the wolf sheep grass model
5.18 ts-layer
Time-series data can be used during simulation through the ts-layer . As with other layers you have to
create it prior to the agent definition. The ts-layer cannot manage agents so it isn’t possible to place agents
on it. Lets say you have a file that contains precipitation or temperature values for certain points in time
Page 46 of 60
Multi-Agent Modelling with MARS: A Handbook
and you wan’t to use the data in your simulation. You would create a ts-layer in the model and then upload
the data to the MARS cloud. Read sections 4.3 through 4.4.2 to learn about the process of importing files
and assigning them to a model.
ts-layer layer name as layer alias
Creating time-series layers works the same as with the raster-layer . First you write the keyword ts-layer
then you give the layer a name ( layer name ). The creation step is completed by adding the as keyword
an assigning the layer an alias by which it is referred to in the model ( layer alias ). It is customary to write
the layer name in camel case and the layer alias in lower case.
Lets take a look at listing 35 which demonstrates the layers capabilities. In line 2 a new ts-layer by the
name of PrecipitationLayer is created. The grass agent accesses this layer in line 9 where it reads the current
value for the simulated time. The value that is going to be read originates in the file uploaded to the MARS
cloud once the simulation is running. You will have to setup the scenario so that the the simulated time
matches the time span covered in that time-series file. Learn more about time-series files in the Time-series
CSV Files (6.4.1) section. The values contained in that file for the current simulation tick can be requested
by the ts-layer either as integer or a floating point number. Line 18 demonstrates functions, head over to
section to learn more about them.
0 model wolf_sheep_grass
1
2 ts-layer PrecipiationLayer as precipitationlayer
3
4 layer AgentLayer
5
6 agent grass on AgentLayer{
7 var energy : integer = 10
8 tick{
9 var currentPrecipitation = precipitationlayer.GetNumberValue()
10
11 i f(currentPrecipitation > 5){
12 grow(2)
13 }
14 else{
15 grow(1)
16 }
17 }
18 def grow(amount : integer){
19 energy = energy + amount
20 }
21 }
Listing 35: Grass agents growth depending on the amount of current rainfall
5.19 val
There are two types of variables that differ only in the way they can be accessed. The var command
specifies variables that can be assigned and then modified while variables created with val can only be
Page 47 of 60
Multi-Agent Modelling with MARS: A Handbook
assigned once and keep their value after that. This is corresponds to the readonly modifier in C# on which
you can read more here.
Use this type of variables when you wan’t to make sure that the value isn’t being change over the course of
the agents/ layers life.
5.20 var
There are two types of variables that differ only in the way they can be accessed. The var command
specifies variables that can be assigned and then modified while variables created with val can only be
assigned once and keep their value after that.
The var keyword is the default way of working with variables. Unless you have a good reason you should
always stick to them.
5.21 vector-layer
Utilizing vector-based GIS data during simulation can be achieved by using the vector-layer command. This
type of layer allows to import and query GeoJSON files. During simulation the agents can read information
from these files and even change them (writing access). Like regular layers the vector-layer has to be defined
in the beginning of the model.
vector-layer layer name as layer alias
Listing 36 shows an example model that includes a vector-layer and uses the whole capabilities of it: First,
a model is defined (name: wolf sheep grass), then a layer (name: agentLayer) is put in and at last a new
agent type (name: sheepAgent) is created on the agent layer. This follows the basic principles for agents and
layers. The vector-layer with the name GisGrassLayer is created in line two. You start by defining the
layer, giving it a name and then specifying the alias by which it is referred to in the model code. Naming
is done in the way that the name (GisGrassLayer) is written in camel case and the alias (gisgrasslayer) in
lower case. Once this is done the layer is ready to be used by the agents. This usage can be divided in two
groups groups: reading information from the layer for the current tick and finding coordinates with certain
features.
Starting with the last category: Take a look at line 8 where the nearest command is used in combination
with the vector-layer . Similar to the usage of nearest with agents this operation doesn’t return a value
from the vector-layer but a coordinate with a certain feature. Take a look at the GIS GeoJSON Files
(6.4) section where you can find more information about GeoJSON files as well as an example. What the
nearest function does, is trying to find the closest position with an actual value. That coordinate is the
result and will be returned, saved to the nearestGrass variable.
Line 9 shows a similar search for a feature. The difference is the origin of that search. While the search
of line 8 originates in the agents current position, the one in line 9 originates at the specified coordinate
with position (2/2) and reveals the closest feature from that point. For more information about the usage
of nearest in combination with the vector-layer please see section nearest (5.9) where the details are
described.
Next usage scenario for the vector-layer is reading information from it. The type of information you can
read depends on the information contained in the GeoJSON file. In general it is possible to read the values
either as integers or floating point numbers. Therefore the DSL offers two corresponding functions by the
name of GetIntegerValue and GetNumberValue. How they are used can be seen in listing 30 in lines ten and
eleven. Both functions return the value in their respective format (integer or real). Lines 11 and 12 both
start with a variable declaration where the results of these methods will be stored. The syntax for using
Page 48 of 60
Multi-Agent Modelling with MARS: A Handbook
the two commands is straight forward. First you specify the vector-layer you want to read from, then you
choose the format in which you want to read the information.
0 model wolf_sheep_grass
1
2 vector-layer GisGrassLayer as gisgrasslayer
3
4 layer agentLayer
5
6 agent sheepAgent on agentLayer{
7 tick{
8 var nearestGrass = nearest on GisGrassLayer
9 var nearestPoint = nearest on GisGrassLayer of #(2, 2)
10
11 var a = gisgrasslayer.GetIntegerValue()
12 var b = gisgrasslayer.GetNumberValue()
13 }
14 }
Listing 36: Model creation with a vector-layer
5.22 x-cor and ycor
The agents position on the grid are denoted by the two variables xcor and ycor . Each agent automatically
has these variables. They are read-only so you cannot change their values directly. If you wan’t to relocate
an agent you can either use the move or the pos at command.
Page 49 of 60
Multi-Agent Modelling with MARS: A Handbook
6 Cookbook
6.1 Example Models
6.1.1 Wolf, Sheep, Grass
0 model WolfSheepPredation
1
2 use Mars
3 layer Grassland
4 raster-layer BiomassRaster as biomass {
5 def EatBiomass(cell : Tuple<integer, integer>, amount : real)
6 {
7 var mass = biomass.Reduce(cell.Item1, cell.Item2, amount)
8 i f(mass >= 0) return mass else return 0
9 }
10 }
11
12 /**agent Observer on Grassland {
13 tick {
14 var growthRate = random(10)
15 while(growthRate > 0) {
16 biomass.Increase(random(100), random(100), random(5) - 5)
17 growthRate--
18 }
19 }
20 }*/
21
22 agent Sheep on Grassland {
23
24 observe var Energy : real = 50
25 observe var EnergyMax : integer = 80
26 observe var Hunger : integer
27 observe var TargetDistance : real
28 observe var Rule : string = ""
29 //var Target : Grass
30
31 i n i t i a l i z e Sheep {
32 pos at #(random(100), random(100))
33 println "Current position (" + xcor + ", " + ycor + ")"
34 }
35
36 tick{
37 //reduce energy
38 Energy = Energy - (1 + random(3))
39 i f(Energy < 0) k i l l me
40 var diff = (EnergyMax - Energy)
41 var rel = (diff / ((EnergyMax) as real))
42 var hunger = (rel * 100)
43 Hunger = hunger as integer
Page 50 of 60
Multi-Agent Modelling with MARS: A Handbook
44 i f(hunger > 20) Energy = Energy +
45 Math::Abs(biomass.EatBiomass(#(xcor, ycor), random(4)))
46 RandomMove()
47 }
48
49 def RandomMove() => move me to #(xcor + random(2)-1, ycor + random(2)-1)
50
51 passive Die() => k i l l me
52 passive GetPosition() => return #(xcor,ycor)
53 passive GetFoodValue() => return Energy
54 }
55 agent Wolve on Grassland {
56
57 observe var Energy : real = 80
58 observe var EnergyMax : integer = 100
59 observe var Hunger : integer
60 observe var TargetDistance : real
61 observe var Rule : string = ""
62 var Target : Sheep
63
64 i n i t i a l i z e {
65 pos at #(random(100), random(100))
66 println "Current position (" + xcor + ", " + ycor + ")"
67 }
68
69 tick {
70 //reduce energy
71 Energy = Energy - (1 + random(3))
72 i f(Energy < 0) {
73 k i l l me
74 }
75
76 var diff = (EnergyMax - Energy)
77 var rel = (diff / ((EnergyMax) as real))
78 var hunger = (rel * 100)
79 Hunger = hunger as integer
80
81 i f(hunger > 20) {
82 i f(Target == nil or not Target.Alive) {
83 Target = nearest Sheep
84 }
85 i f(Target !== nil) {
86 var sheepDistance = distance(Target)
87 i f(sheepDistance <= 1.4143) {
88 Rule = "R1 - Kill the sheep.";
89 IncreaseEnergy(Target)
90 } else {
91 var position = Target.GetPosition
92 Rule = "R2 - Moving towards sheep (" +
Page 51 of 60
Multi-Agent Modelling with MARS: A Handbook
93 position.Item1 + ", " + position.Item2 + ").";
94 move 1 to Target
95 }
96 }
97 } else {
98 TargetDistance = 0
99 Rule = "R3 - No target: Random movement.";
100 move me to #(random(60), random(60))
101 }
102 }
103
104 active IncreaseEnergy(sheep : Sheep) {
105 var energy = sheep.GetFoodValue
106 Energy = Energy + energy
107 i f(Energy > EnergyMax) Energy = EnergyMax
108 sheep.Die
109 }
110 }
Listing 37: Wolf sheep grass example model
6.1.2 Chatting Agents
This model features two agent types (TeaLover and CoffeeLover) that use a layer to communicate with each
other. Both wait for an invitation for either tea or coffee. If they receive such an invitation they would
accept it by responding with yes. All communication is handled by the MailboxLayer which implements two
functions PutMessage and ReadMailbox to access the messages. Thereby agents can send and read messages.
0 model LayerMailbox
1
2 layer MailboxLayer as mailbox {
3
4 var Mailbox : Tuple<string, Sender> = nil
5
6 def PutMessage(message : string, sender : Sender)
7 => Mailbox = #(message, sender)
8
9 def ReadMailbox() => return Mailbox
10 }
11
12 agent TeaLover on MailboxLayer {
13 tick {
14 var post = mailbox.ReadMailbox;
15 i f("Tea time?" === post.Item1) {
16 post.Item2.Answer("Yes")
17 }
18 }
19 }
20
21 agent CoffeeLover on MailboxLayer {
Page 52 of 60
Multi-Agent Modelling with MARS: A Handbook
22 tick {
23 var post = mailbox.ReadMailbox;
24 i f("Coffee time?" === post.Item1) {
25 post.Item2.Answer("Yes")
26 }
27 }
28 }
Listing 38: Two agent types using a layer to communicate
6.2 Useful Code Snippets
6.2.1 Agent Evolution
0 agent caterpillar on AgentLayer{
1 var agentState : integer = 0
2
3 tick{
4 i f(simtime > 200){
5 agentState = 1
6 }
7 //caterpillar state
8 i f(agentState === 0){
9
10 }
11 //butterfly state
12 else i f (agentState === 1){
13
14 }
15 }
16 }
Listing 39: Simulation of a caterpillar that turns into a butterfly after 200 ticks
6.2.2 Agent Live Stages
0 agent elephant on AgentLayer{
1 var stage : integer = 0
2 var simulatedDays = 0
3
4 tick{
5 simulatedDays = simulatedDays + 1
6
7 //change agent stage base on simulation time
8 i f(simulatedDays === 10){
9 stage = 1
10 }
11 i f(simulatedDays === 20){
12 stage = 2
Page 53 of 60
Multi-Agent Modelling with MARS: A Handbook
13 }
14
15
16 //Calf
17 i f(stage === 0){
18
19 }
20 //Adolescent
21 else i f(stage === 1){
22
23 }
24 //Adult
25 else{
26
27 }
28 }
29 }
Listing 40: Elephant with conditional behavior based on the stage of live he is in
6.2.3 Random Walk
0 model random_walker
1
2 layer AgentLayer
3
4 agent RandomWalkAgent on AgentLayer {
5 tick {
6 switch (random(8)) {
7 case 0 : { move left }
8 case 1 : { move right }
9 case 2 : { move down }
10 case 3 : { move up }
11 case 4 : { move up-left }
12 case 5 : { move up-right }
13 case 6 : { move down-right }
14 case 7 : { move down-left }
15 }
16 }
17 }
Listing 41: Randomly walking agent. Moves 1 grid cell in every simulation step
6.2.4 Biomass Removal
This snippets shows an example where the surroundings are modeled as biomass. The biomass information
itself is contained in a raster-layer . Each grid cell contains a certain amount of biomass that the agents,
elephants in this case, can eat. The elephant moves around in every tick but only eats between 6am and
8pm. Using the simtime command together with the Mars package we can get the current hour of the day
(line 10). Simulation step duration (delta t) has to be set to one hour when executing this model.
Page 54 of 60
Multi-Agent Modelling with MARS: A Handbook
0 model elephant_biomass_removal
1
2 use Mars
3
4 raster-layer BiomassLayer as biomasslayer
5 layer AgentLayer
6
7 agent Elephant on AgentLayer{
8 var energy : integer = 10
9 tick{
10 var currentHourOfDay = Time.Hour(simtime)
11 i f(currentHourOfDay > 6 and currentHourOfDay < 20){
12 biomasslayer.Reduce(xcor,ycor,5)
13 }
14 move me 3 to #(random(100),random(100))
15 }
16 }
Listing 42: Elephant agent removing biomass from its surroundings
6.2.5 Agent Interaction: Buying Goods
0 agent FruitDealer on AgentLayer{
1 var AppleSupply = 20
2 passive BuyApple(money : integer) : bool{
3 i f(money >= 2){
4 i f(AppleSupply > 0){
5 AppleSupply = AppleSupply - 1
6 return true
7 }
8 }
9 return fa l se
10 }
11 }
12 agent buyer on AgentLayer{
13 var money : integer = 10
14 tick{
15 var dealer = nearest FruitDealer
16 i f(dealer.BuyApple(money)){
17 money = money - 2
18 println "I bought an apple"
19 }
20 else{
21 println "Couldn’t get an apple"
22 }
23 }
24 }
Listing 43: Two agents trading apples
Page 55 of 60
Multi-Agent Modelling with MARS: A Handbook
6.3 Data Usage Examples
6.3.1 Agent Init Files
Agent init files can be used to initialize agents individually so that each agent has its own set of variables that
differs from these of other agents of the same agent type. This is advanced functionality that can be used in
combination with the MARS cloud system. Prerequisite to using this is to annotate the agents parameter
that should be set with this method by adding the external keyword to the variable definition. Listing
45 shows an agent init file example that can be used with the model shown in listing 44. This wolf agent
has three external variables name energy, weight and name (listing 44). All are of different types (integer,
floating point and string).
0 agent wolf on AgentLayer{
1 external var Energy : integer
2 external var Weight : real
3 external var Name : string
4 }
Listing 44: Wolf agent with three external attributes
These attributes are filled later on during simulation creation with the following agent init file. Since the file
has four lines, you can created up to four agents from it. The first line of an agent init file should contain
the names of the variables that are going to be set through it. The correct formatting is important, if not
done properly it won’t work. Delimiter for everything are semicolons, no spaces are to be used.
0 energy;weight;name
1 10;14.3;"Bob"
2 12;20.6;"John"
3 24;2.0;"Chad"
4 5;15.4;"James"
Listing 45: Agent init file for the wolf
6.3.2 GIS ASC Files
Here we can see an example file that was used in the wolf, sheep, grass model to represent the grass. Each
patch in that 10 by 10 grid has an integer number depicting the amount of grass on that patch. sheep would
move around the simulated area and eat from the grass by decreasing the values.
0 ncols 10
1 nrows 10
2 xllcorner 0
3 yllcorner 0
4 cellsize 0.1
5 nodata_value -99
6 4 7 4 4 4 2 4 4 4 4
7 1 4 4 4 4 6 4 4 4 1
8 4 4 3 4 4 4 4 7 4 4
9 2 4 4 8 4 5 4 6 4 2
10 4 9 4 4 4 4 4 4 4 4
Page 56 of 60
Multi-Agent Modelling with MARS: A Handbook
11 4 4 4 7 4 1 4 4 3 4
12 3 0 4 4 4 4 1 4 4 4
13 4 4 8 4 9 4 9 9 4 8
14 5 4 4 4 4 4 4 4 4 4
15 4 4 4 4 8 4 4 4 2 4
Listing 46: GIS grass ASC file with 10x10 grid size
6.4 GIS GeoJSON Files
Add section about GeoJSON Files
6.4.1 Time-series CSV Files
Time-series data can be used by the MARS system if it is formatted as CSV file. Each line must contain a
timestamp as shown in figure 47 followed by the actual value. This value can either be of type float or an
integer. Delimiter for the file are semicolons and no spaces are allowed. The first line of the file must be
similar to the depicted version in figure 47, otherwise the MARS system won’t recognize it as a time-series
file. Parameter number three of the first line (temperature) should be a description of the data. In figure 47
the files contains temperature values so its called temperature.
0 date;hour;temperature
1 2019-01-01;12:00;5.0
2 2019-01-01;13:00;6.1
3 2019-01-01;14:00;7.3
4 2019-01-01;15:00;7.0
5 2019-01-01;16:00;6.8
6 2019-01-01;17:00;6
7 2019-01-01;18:00;5.9
Listing 47: Example time-series file with temperature values
6.5 Programming Features
6.5.1 Functions
Agents and layers can use functions to simplify or structure their code. Functions can be defined inside
classes, agents and layers. Note that you cannot define functions inside the agents tick and initialize
methods.
def method name ( parameters ) : return type {}
New functions are defined by writing the def command followed by the desired name of the function.
Enclosed in braces follow parameters which are optional. After the parameters you can specify the return
type of the function. This is optional as well. You can choose between bool , integer , real , string and
void to either return a boolean value, an integer, real, string or nothing in the case of void . At last you
have to put curly braces. The function code will be contained in these. Listing 48 shows an agent with two
example functions. The first one defined in line 7 takes two parameter a and b and multiplies them. In line
8 the result is computed and returned to the caller. When this function is called (line 3) it will take the two
input parameters (2 and 3 in this case) and multiply them. Line 4 prints the result which will be 6 in the
example. Functions can also be used to alter variables. The TestAgent defines a variable named health in
Page 57 of 60
Multi-Agent Modelling with MARS: A Handbook
line 1 which will be changed by the increaseHealth function. This function expects a floating point number
as input (amount) and won’t return any values as denoted by the void in the definition. When this function
is called in line 5 the agents health is going to increase by five.
0 agent TestAgent on AgentLayer{
1 var health : real = 10
2 tick{
3 var result = multiply(2,3)
4 print(result)
5 increaseHealth(5)
6 }
7 def multiply(a : integer, b : integer) : integer{
8 return a * b
9 }
10 def increaseHealth(amount : real) : void{
11 health = health + amount
12 }
13 }
Listing 48: Function examples
6.5.2 Arrays
Arrays work the same as in most programming languages as they start at zero. New arrays can be created
as shown in figure ???. Accessing an arrays’ value works by specifying the index the value should be read
off. Line ??? in figure ??? demonstrates this.
Write more about arrays and add a screenshot with code to demonstrate
6.5.3 Enums
add section about enums
6.5.4 Maps/ Dictionaries
add section about dictionaries/ maps
6.5.5 Loops
As in most programming languages, there are multiple loop constructs available in the DSL. Depending on
you use-case you can pick the one that suits you best. Below you’ll find example code for each of the various
loop types.
for loops are to be used when a process is to be repeated a known amount of times. You begin by
specifying a variable, i in this case, whom’s value will be checked for a condition afterwards. In this example
we define the variable i to start out at zero and then check if its value is lower than ten. If this evaluates
to true the statement enclosed by the curly braces is executed. After this has happened the last step in the
braces (incrementing i by one) is executed. This loop is repeated until i is bigger than ten which gives you
exactly ten iterations.
Page 58 of 60
Multi-Agent Modelling with MARS: A Handbook
0 agent DemoAgent on DemoLayer{
1 tick{
2 for (var i = 0; i<10; i++){
3 print "hello"
4 }
5 }
6 }
Listing 49: For loop
foreach loops should be used if you have a list, array or set of variables you want to go through one by
one and do something. In the example below this is the array with the name c which contains two integers.
When the code is executed the loop goes over this array and prints each integer one by one. The variable
b is a placeholder that is used as the reference to the current value of the array we are currently looping
through.
0 agent DemoAgent on DemoLayer{
1 tick{
2 var c = ##[1,2]
3 each (var b in c ){
4 print b
5 }
6 }
7 }
Listing 50: Foreach loop
while loops are to be used if a piece of code is supposed to be repeated until a certain condition is met.
In the example below the condition is that the variable a is bigger or equal to ten. As long as a is smaller
than ten the statement in the curly braces is executed over and over again. Since the statement in the braces
increments a in every iteration the loop will end after executing ten times.
0 agent DemoAgent on DemoLayer{
1 tick{
2 var a = 0
3 while(a < 10){
4 print "hello"
5 a = a + 1
6 }
7 }
Listing 51: While loop
Example: Observer agent use loop to iterate over all raster cells. This code snippet shows a mini
model with a raster layer and an observer agent. The agent (Observer) uses two nested for loops to go
through all raster cells and increase their values.
Page 59 of 60
Multi-Agent Modelling with MARS: A Handbook
0 raster-layer GrassLayer as grasslayer
1
2 layer AgentLayer
3
4 agent Observer on AgentLayer{
5 tick{
6 for (var x = 0; x <= 10; x++){
7 for (var y = 0; y <= 10; y++){
8 grasslayer.Increase(x,y,5)
9 }
10 }
11 }
12 }
Listing 52: Observer agent going through all raster cells increasing their values
Release
Version: 1.5.5
Author: Julius Weyl
Published 08.07.2019
References
[1] Robert Axelrod. Advancing the art of simulation in the social sciences. In Simulating Social Phenomena,
pages 21–40. Springer Berlin Heidelberg, 1997.
[2] Nigel Gilbert and Klaus G. Troitzsch. Simulation for the Social Scientist. Open University Press, 2005.
[3] Daniel Glake, Julius Weyl, Christian Huning, Carolin Dohmen, and Thomas Clemen. Modeling through
Model Transformation with MARS 2.0. In 2017 Spring Simulation Multiconference, page 12, 2017.
[4] Dirk Helbing and Stefano Balietti. Agent-Based Modeling. In Social Self-Organization, pages 25–70.
Springer Berlin Heidelberg, 2012.
[5] Christian Huning, Mitja Adebahr, Thomas Thiel-Clemen, Jan Dalski, Ulfia Lenfers, Lukas Grundmann,
Janus Dybulla, and Gregory Kiker. Modeling & Simulation as a Service with the Massive Multi-Agent
System MARS. In Spring Simulation Multiconference, 2016.
[6] Julius Weyl, Daniel Glake, and Thomas Clemen. Agent-based Traffic Simulation at City Scale with
MARS. In 2018 Spring Simulation Multiconference, 2018.
Page 60 of 60