This repository holds the source code for the Kleptomove simulation, an individual-based, evolutionary model of the co-evolution of animal movement and competition strategies, written by Christoph Netz, based on a previous model by Hanno Hildenbrandt, in the Modelling Adaptive Response Mechanisms Group (Weissing Lab) at the Groningen Institute for Evolutionary Life Science, at the University of Groningen.
The source code for analyses of this simulation's output can be found on Github, or archived on Zenodo: https://doi.org/10.5281/zenodo.4904497.
Please contact Christoph Netz and Franjo Weissing (PI) for questions on the model or the project. Please contact Pratik Gupte or Christoph or Franjo for questions about the associated manuscript.
Please cite this simulation as
@software{netz_2021_kleptomove,
author = {Christoph FG Netz and
Pratik Rajan Gupte},
title = {{Kleptomove: Source code for an individual-based
model of the co-evolution of animal movement and
competition strategies}},
month = jun,
year = 2021,
publisher = {Zenodo},
version = {v0.9.1},
doi = {10.5281/zenodo.4905476},
url = {https://doi.org/10.5281/zenodo.4905476}
}
The default simulation parameters are set using the config.ini
file in bin/settings/
, and can also be passed using the command line.
This section describes what the important parameters mean and their acceptable values. If a parameter is not described here, it is not varied in the simulation.
Gburnin=0 # how many generations to run before displaying output
G=10 # how many generations to run
T=400 # the number of timesteps per generation
Gfix=998 # the number of generations after which to run one, long generation
# i.e., in generation 999, there will be a final, long generation
Tfix=10000 # the number of timesteps in the final, long generation
agents.N=10000 # the number of individuals
agents.obligate=1 # whether agents follow a fixed strategy (1 = True, 0 = False)
agents.forage=0 # whether agents are foragers (1 = True),
# or can they steal (0 = False)
agents.sprout_radius=512 # how far away from a parent the offspring is initialised
agents.mutation_prob=0.001 # the probability of each cue preference mutating
agents.mutation_step=0.01 # the scale of a Cauchy distribution, which determines
# the potential size of the mutation
agents.noise_sigma=0.1 # the noise around individuals' assessment of their landscape
agents.input_mask={1,1,1} # whether agents can sense their environment
# setting this to {0,0,0} leads to random movement
agents.flee_radius=5 # how far a kleptoparasite can displace its target
agents.handling_time=5 # the handling time for a prey item
win_rate=1.0 # the probability of a kleptoparasite successfully stealing
landscape.max_item_cap=5.0 # the carrying capacity of each cell
landscape.item_growth=0.01 # the maximum rate at which an item appears, called r_max
landscape.detection_rate=0.20 # the probability of an agent detecting any one item
landscape.capacity.image=kernels32.png # the gridded landscape from where the underlying growth rate is derived
landscape.capacity.channel=0 # which layer of the png image holds the growth rate 0: red, 1: green, 2: blue
outdir=data # where the data is saved
The simulation source code is in cine/
, while code for a GUI is in cinema/
. This simulation is Windows only.
simulation.cpp
runs the main simulation. Individual agents are defined in individuals.h
, the landscape in landscape.h
, and neural networks in {any_ann.hpp, any_ann.cpp}
. Parameters are defined, read from command line and
written out through {parameter.h, parameter.cpp}
, relying on cmd_line.h
. Preliminary data analysis is performed in {analysis.cpp, analysis.hpp}
, and output is generated via an observer chain in {observer.h, cnObserver.h}
and cnObserver.cpp
, relying on {archive.cpp, archive.hpp}
.
Files in the subproject extract/
provides a custom executable to extract data from the archives.
This refers to code in the cine/
directory.
-
main.cpp
Reads in the parameters, creates theSimulationHost
andSimulation
class, chains back the observers and runs the simulation. -
simulation.h
-
Defines the
Simulation
class, consisting of a population structure (defined in the same file, with neural networks defined inany_ann.hpp
,any_ann.cpp
andann.hpp
, and the individual class defined inindividuals.h
), landscape (inlandscape.h
), parameters (inparameter.h
) and analysis (inanalysis.h
). -
This simulation is encapsuled in a
SimulationHost
class that also contains the first observer. -
The simulation is started using the function
bool run(Observer* observer = nullptr);
, that along with its component functions is defined insimulation.cpp
.
-
-
simulation.cpp
-
Defines the constructor of the simulation class (initializing population (agents, neural networks, fitness vector, other record keeping), and landscape.
-
Defines the main function
bool run(Observer* observer = nullptr);
which loops over generations and within generations over timesteps, with main functions beingsimulate_timestep(t_);
, and at the end of a generationassess_fitness();
,assess_inds
andcreate_new_generations();
, as well asanalysis_.generation()
(defined inanalysis.cpp
) and notification messages to the observer chain. -
Within a timestep, resource items regenerate, agents move (defined in
any_ann.cpp
), occupancy is updated (defined inlandscape.h
), and grazing and stealing events are resolved. At the end of the generation, fitness values are calculated inassess_fitness();
, individual time budget is assessed inassess_inds
, and a new generation is created from the calculated fitness values, with some probability of mutation (defined inany_ann.cpp
).
-
-
any_ann.hpp
-
Defines the class
any_ann
, which contains an array of all network weights, total number of ANNs within the array and the length of one individual. -
Important functions are
move()
(for individual movements within timesteps),mutate()
(mutation of weights during reproduction) andinitialize()
(at the beginning of the simulation). These functions are defined inany_ann.cpp
.
-
-
any_ann.cpp
Constructor ofany_ann
, and the functionsmove()
,mutate()
, andinitialize()
, explained above. -
ann.hpp
Artificial neural network library for feedforward and recursive networks. -
individuals.h
Defines theIndividual
structure with all state variables such as position or food, and functions implementing individual actions likehandle
orflee
. ANNs are stored separately in thepopulation
class. -
landscape.h
Defines thelandscape
class with all the contained layers. Theupdate_occupancy
function updates the different layers with the momentary positions of individuals. -
convolution.h
Provides the function to transform discrete individual counts into gaussian density kernels. -
image.h
andimage.cpp
Allow the transformation of landscape layers into images that can be written out to file, and vice versa the transformation of images to layers (when setting thekernels32.png
as thelandscape.capacity
parameter). -
rnd.hpp
,rnd.cpp
andrndutils.hpp
Random number generation and custom distributions (mutable_discrete_distribution
,uniform_signed_distribution
). -
parameter.h
andparameter.cpp
-
Contains the parameter structure, which is split into general parameters and substructures for agents, the landscape and the gui.
-
Additionally contains a parser for parameters for input from command line (in
cmd_line.h
), declaration of different network types (inann.hpp
) whose usage is defined by a parameter, fitness function for individuals, default values for parameters and streaming of parameters to file.
-
-
analysis.cpp
andanalysis.hpp
At the end of each generation,Analysis::generation
is called on the entire simulation class, which then provides two different sets of data:-
An assessment of inputs, which documents the minimum, maximum, mean and median of available cues for all three sensory input layers (resource items, handlers and non-handlers), and
-
Summary statistics on the population consisting of average fitness, individuals with fitness > 0, number of unique anns, and total number of handling and foraging events.
This analysis is then streamed to file by cnObserver.cpp at the end of the simulation (upon
msg_type::FINISHED
). -
-
cnObserver.cpp
This observer of classObserver
(fromobserver.h
) is chained to the head observer of the simulation class, and through it receives messages during the simulation.-
Upon
msg_type::INITIALIZED
, five different archive files are opened (seearchive.cpp
andarchive.hpp
). -
Upon
msg_type::GENERATION
, the observer writes to file all ANNs, fitness values, ancestry data and foraging and handling counts for all individuals in the present generation in compressed format. -
Upon
msg_type::FINISHED
, the observer writes out the analysis of all generations (input statistics and summary population statistics, fromanalysis.cpp
andanalysis.hpp
), as well as the parameters used and thesourceMe.R
script to extract the data. -
This
R
script relies on anextract.exe
file that is custom-built in the sub-projectextract/
.
-
-
game_watches.hpp
Time measurements during the simulation run.
The scripts in this folder generate the simulation GUI, containing a landscape view, a histogram of ANN weights and timelines of the metrics calculated in the summary structure of cine/analysis.cpp
.
This code has no influence on the data produced during the simulation, and we will not elaborate further on it here. For feedback and questions please drop us a mail.
This stores the simulation data locally.
Simulation data are available from DataverseNL as a draft: https://dataverse.nl/privateurl.xhtml?token=1467641e-2c30-486b-a059-1e37be815b7c; persistent link after publication: doi.org/10.34894/JFSC41.