Freitag, 2. Mai 2014

Netlogo tutorial: Rabbits on grass

Today we are going to look at a simulation where mobile agents interact with some kind of habitat - eg. rabbits eating grass. The habitat can be implemented as patches and the mobile agents as turtles in Netlogo.



In this example (DOWNLOAD here) rabbits walk randomly and eat grass. After the grass has been eaten it takes some time to regrow. When rabbits eat they grow in size and when a rabbit has eaten enough it gives birth to a new rabbit (let's assume asexual reproduction for simplicity). If rabbits go hungry for too long, they die. The simulation starts with nr-rabbits rabbits. The plots show the number of patches with grass (scaled /10) vs the number of rabbits and the number of rabbits on the brink of death (they would die in the next step if they don't find anything to eat right now).

Implementation

We have seen in the last post how turtles can interact with patches. So today let's look at some other things. First, what we have here is a feedback loop: the more rabbits, the more grass they eat and therefore, the less grass. The less grass, the less rabbits can feed on it. Unlike in SD / CLDs we don't have to model this feedback loop explicitly, though. We simply encode the behaviors of the turtles and the patches and then let the simulation run its course.
As in the Langton's ant example we simply use the color of a patch as state information - a patch with grass is green, a patch where the grass has been eaten is brown. Since Netlogo offers several shades of green we could also use more than two colors to indicate the height of the grass in more detail if we wanted. To be flexible with the colors it is a good idea to set up some variables and declare the colors only once. We declare
globals [grass-high grass-low]

and in setup
  ; color setup
  set grass-high (lime - 2)
  set grass-low (brown + 1)

and later only refer to these colors by their variable names grass-high and grass-low. If we later decided to change the colors for aesthetic reasons we only have to change the initialization in setup and not all over the code.

Then, we need countdown timers for both the patches and the rabbits - patches regrow after a certain time and rabbits die if they have not eaten for some time. For this we simply declare a grow-timer variable for patches and a ttl variable for the turtles, set them to the maximum remaining time and then decrease these variables at each tick. When the countdown variable reaches zero, the rabbit dies or the grass regrows. To keep our code easy to read we put the regrowing code into its own procedure:
to regrow-grass  
  ask patches with [pcolor = grass-low] [
    set grow-timer grow-timer - 1
    if grow-timer = 0 [
      set pcolor grass-high
      set grow-timer grass-regrow-time
    ]
  ]
end


in our go procedure we can call the regrow-grass procedure by simply writing its name:
...
 regrow-grass
...

Procedures can also have parameters. We define a move procedure:
to move [ stepsize ]
  ifelse (random 2) = 0 [ rt random 90 ] [ lt random 90 ] 
  fd random stepsize   
end

This procedure defines a 50:50 chance of turning either to the right or left and then moves forward according to the stepsize parameter. In the go procedure we call move from inside the ask turtles section like this:
    move 2

to make our turtles move.

In this simulation turtles grow when they eat (simply increase the size variable of the turtle) and give birth when they have eaten enough. This is done with the hatch command. When a turtle is born with hatch from another turtle it inherits its mother's state unless we set it explicitly.
    ; give birth
    if stomach >= rabbit-born-after [ 
      set stomach 0
      set size 1
      hatch 1 ; inherits stomach and size
    ]

Keine Kommentare:

Kommentar veröffentlichen