PredatorPrey Dynamics#

This model is implemented as a cellular automaton (CA) with the cells arranged on a two-dimensional grid and represents a simple case of spatially resolved population dynamics.

Note

Currently, the execution order of rules is different from the code referred to in the script. There, cells are called randomly and the sequence of rules is applied to an individual cell before proceeding to the next one. In the Utopia PredatorPrey model, a rule is applied to all cells before the proceeding to the next rule. Due to that, results from the script can not be replicated exactly with this code.

Scenario#

As the name suggests, there are two different species present in this model: prey and predator. The prey species has a steady inflow of resources (e.g. by eating plants, whose population dynamics are not represented in this model). The predator species feeds on the prey. Both species expend resources to uphold their structure (“living costs”) and to reproduce, which happens in an asexual manner (i.e. individuals can reproduce without a mate).

The interaction consists of the predator moving on the grid and looking for prey in its neighborhood. Upon making contact, it consumes the prey. The prey may flee with a certain probability.

Implementation#

This is modelled using a cellular automaton (CA). Each cell of the CA has four possible states:

  • Empty

  • Inhabited by a prey

  • Inhabited by a predator

  • Inhabited by both a prey and a predator

No two individuals of the same species can be on the same cell at the same time. Consequently, each cell contains a variable for each species, in which the resource level of the respective individual is stored. The interaction is calculated for each timestep and consists of four sequentially applied rules:

  1. Cost: resources of each individual are depleted by the cost of living. Individuals with negative or zero resources die and are hence removed.

  2. Movement: predators move to a cell populated by prey in their neighborhood, or to an empty cell if there is no prey. Prey that are on a cell together with a predator flee to an empty cell in their neighborhood with a certain probability. If there are several cells in the neigborhood that meet the above condition, one is chosen at random.

  3. Eating:: prey consume resources and predators eat prey if they are on the same cell.

  4. Reproduction: if an individual’s resources exceed a certain value and if there is a cell in its neighborhood that is not already populated by an individual of the same species, it reproduces and an individual of the same species is created on the empty cell. 2 resource units are transferred to the offspring.

All cells are updated asynchronously. The order for the cell update is random for rules 2 and 4, to avoid introducing any ordering artefacts. For rules 1 and 3, this is not required.

Initialization#

Cells are initialized in a random fashion: depending on the probabilities configured by the user, each is initialized in one of the four states. The parameters controlling this are given in the model configuration, listed below.

Default configuration parameters#

Below are the default configuration parameters for the PredatorPrey model:

# --- Space -------------------------------------------------------------------
space:
  periodic: true


# --- CellManager -------------------------------------------------------------
cell_manager:
  grid:
    structure: square
    resolution: 64            # in cells per unit length of physical space

  neighborhood:
    mode: Moore

  # Initial species parameters
  cell_params:
    # Resource reservoir for predator and prey
    predator:
      init_resources: !is-unsigned 2
    prey:
      init_resources: !is-unsigned 2

    # The probabilities to have a cell initialized with prey and/or predator 
    # on it. Need be non-negative and sum up to a value <= 1.0
    p_predator: !is-probability 0.1
    p_prey: !is-probability 0.2


# Load species positions from datasets of a HDF5 file.
# If enabled, the presence of an entity is set using data from the respective
# dataset, i.e. `predator` and `prey`.
# Values can only be 0 or 1, specifying whether the respective entity is
# present on the corresponding cell.
cell_states_from_file:
  hdf5_file: !is-string /abs/path/to/data.hdf5  # TODO Set this in your run.yml
  load_predator: !is-bool false
  load_prey: !is-bool false


# --- Model dynamics ----------------------------------------------------------
# Species-specific parameters; the model dynamics arise from these
predator:
  # Resource intake from eating and maximum resource value
  resource_intake: !is-positive-or-zero 3.
    
  resource_max: !is-positive-or-zero 8.

  # Cost of living (per time step)
  cost_of_living: !is-positive-or-zero 1.

  # Reproduction parameters: minimum resources required, probability for
  # the reproduction taking place, and cost of reproduction.
  repro_resource_requ: !is-positive-or-zero 4.

  repro_prob: !is-probability 0.2
  repro_cost: !is-positive-or-zero 2

prey:
  resource_intake: !is-positive-or-zero 3.
    
  resource_max: !is-positive-or-zero 8.

  # Cost of living (per time step)
  cost_of_living: !is-positive-or-zero 1.

  # Fleeing probability when on the same cell together with a predator
  p_flee: !is-probability 0.5

  repro_resource_requ: !is-positive-or-zero 4.
  repro_prob: !is-probability 0.2
  repro_cost: !is-positive-or-zero 2.

Available plots#

The following plot configurations are available for the PredatorPrey model:

Default Plot Configuration#

# --- Plot of the predator density against the prey density -------------------
phase_space:
  based_on: phase_space


# --- Time series of the predator and prey spatial densities and resources ----
species_densities:
  based_on: species_densities

mean_resources:
  based_on: mean_resources


# --- Animation of the spatial resource development of prey and predators -----
ca/resources:
  based_on: resources

ca/population:
  based_on: population

ca/population_detailed:
  based_on: population_detailed
  enabled: false

Base Plot Configuration#

.variables:
  model_name: &model_name PredatorPrey
  base_path: &base_path data/PredatorPrey

  # Colors used throughout these plots
  cmap: &cmap
    empty: &color_empty white
    predator: &color_predator '#FFCC66'
    prey: &color_prey '#006666'
    both: &color_both '#CC3333'

# =============================================================================
#  ╔╦╗╔═╗╔╦╗╔═╗╦  ╔═╗╔╦╗╔═╗╔═╗
#   ║ ║╣ ║║║╠═╝║  ╠═╣ ║ ║╣ ╚═╗
#   ╩ ╚═╝╩ ╩╩  ╩═╝╩ ╩ ╩ ╚═╝╚═╝
# =============================================================================
# -- Overloads ----------------------------------------------------------------
# Overload some configs to insert model-specific settings

# Model-specific defaults
.defaults:
  based_on: .defaults

  # Can define something here ...


# .. Creators .................................................................
.creator.universe:
  based_on:
    - .creator.universe
    - .defaults

  dag_options:
    select_path_prefix: *base_path

.creator.multiverse:
  based_on:
    - .creator.multiverse
    - .defaults

  select_and_combine:
    base_path: *base_path








# =============================================================================
#  ╔═╗╦  ╔═╗╔╦╗╔═╗
#  ╠═╝║  ║ ║ ║ ╚═╗
#  ╩  ╩═╝╚═╝ ╩ ╚═╝
# =============================================================================
# -- Plot of the predator density against the prey density --------------------
phase_space:
  based_on:
    - .creator.universe
    - .plot.facet_grid.scatter

  select: &pred_prey_density
    predator_density:
      path: predator
      transform:
        - .mean: [!dag_prev , ['x', 'y']]
    prey_density:
      path: prey
      transform:
        - .mean: [!dag_prev , ['x', 'y']]

  transform:
    - operation: xr.Dataset
      kwargs:
        data_vars:
          predator_density: !dag_tag predator_density
          prey_density: !dag_tag prey_density
      tag: data

  # Specify the encoding
  x: predator_density
  y: prey_density
  hue: time

  # Set helpers accordingly
  helpers:
    set_labels:
      x: Predator Density $[1/A]$
      y: Prey Density $[1/A]$

  # Parameters that are passed on to plt.scatter
  cmap: viridis_r
  s: 3.5



# -- Time series of the predator and prey densities ---------------------------
species_densities:
  based_on:
    - .creator.universe
    - .plot.facet_grid.line
    - .hlpr.kind.time_series

  select:
    <<: *pred_prey_density

  transform:
    - xr.Dataset:
        data_vars:
          predator: !dag_tag predator_density
          prey: !dag_tag prey_density
    - .to_array: [!dag_prev ]
      kwargs:
        dim: kind
      tag: data

  hue: kind

  helpers:
    set_labels:
      y: Density $[1/A]$
    set_title:
      title: Predator and Prey Densities
    set_legend:
      title: Species

  style: &color_cycler
    axes.prop_cycle: !format
      fstr: "cycler('color', ['{cmap[predator]:}', '{cmap[prey]:}'])"
      cmap: *cmap

# -- Time series of the predator and prey resources ---------------------------
mean_resources:
  based_on:
    - .creator.universe
    - .plot.facet_grid.line
    - .hlpr.kind.time_series

  select:
    resource_predator:
      path: resource_predator
      transform:
        - .where: [ !dag_prev ge 1, !dag_prev , 0]  # TODO Syntax ok???
        - .mean: [!dag_prev , ['x', 'y']]
    resource_prey:
      path: resource_prey
      transform:
        - .where: [ !dag_prev ge 1, !dag_prev , 0]
        - .mean: [!dag_prev , ['x', 'y']]

  transform:
    - operation: xr.Dataset
      kwargs:
        data_vars:
          predator: !dag_tag resource_predator
          prey: !dag_tag resource_prey
    - .to_array: [ !dag_prev ]
      kwargs:
        dim: kind
      tag: data

  x: time
  hue: kind

  helpers:
    set_limits:
      y: [0, ~]
    set_labels:
      y: Resource Density $[1/A]$
    set_title:
      title: Mean Total Resources
    set_legend:
      title: Species

  style:
    <<: *color_cycler


# -- A grid animation that shows combined predator and prey positions ---------
combined_grid_animation:
  based_on:
    - .creator.universe
    - .plot.ca

  # TODO


# --- Animation of the spatial resource development of prey and predators -----
resources:
  based_on:
    - .creator.universe
    - .plot.ca

  select:
    resource_predator: resource_predator
    resource_prey: resource_prey

    resource_max_predator:
      path: "../../cfg"
      with_previous_result: true
      transform:
        - recursive_getitem: [[*model_name, predator, resource_max]]

    resource_max_prey:
      path: "../../cfg"
      with_previous_result: true
      transform:
        - recursive_getitem: [[*model_name, prey, resource_max]]

  # Select the properties to plot
  to_plot:
    resource_predator:
      title: Predator resources
      vmin: 0
      vmax: !dag_result resource_max_predator
      cmap: YlGn

    resource_prey:
      title: Prey resources
      vmin: 0
      vmax: !dag_result resource_max_prey
      cmap: YlGn


# --- Animation of the spatial development of prey and predator populations ---
population:
  based_on:
    - .creator.universe
    - .plot.ca

  select:
    predator:
      path: predator
      transform: [.data]  # resolve GridDC to have an xr-native object
    prey:
      path: prey
      transform: [.data]  # resolve GridDC to have an xr-native object

  transform:
    # Use base-2 encoding to denote whether a cell is empty, contains only a
    # prey, only a predator or both:
    - mul: [!dag_tag predator, 2]
    - add: [!dag_prev , !dag_tag prey]
      tag: combined

  to_plot:
    combined:
      title: Predator & Prey
      cmap:
        empty: *color_empty         # 0
        prey: *color_prey           # 1
        predator: *color_predator   # 2
        both: *color_both           # 3



# --- More detailed animation: prey only, combined, predator only -------------
population_detailed:
  based_on:
    - .creator.universe
    - .plot.ca
  select:
    predator:
      path: predator
      transform: [.data]  # resolve GridDC to have an xr-native object
    prey:
      path: prey
      transform: [.data]  # resolve GridDC to have an xr-native object

  transform:
    # Use base-2 encoding to denote whether a cell is empty or contains both
    - mul: [ !dag_tag predator, !dag_tag prey ]
    - .assign_attrs: [!dag_prev , {'grid_structure': 'square'}]
      tag: combined

  to_plot:
    predator:
      title: Predator
      add_colorbar: false
      cmap:
        empty: *color_empty
        predator: *color_predator

    combined:
      title: Both
      add_colorbar: false
      cmap:
        empty: *color_empty
        both: *color_both

    prey:
      title: Prey
      add_colorbar: false
      cmap:
        empty: *color_empty
        prey: *color_prey

For available base plots, see Base Plot Configuration Pool.

References#

Kurt Roth: Chaotic, Complex, and Evolving Environmental Systems, unpublished lecture notes, University of Heidelberg, 2019.