AmandaV
AmandaV

Reputation: 31

Using nested if or ifelse in Netlogo to specify probabilities

I am having trouble using nested ifs in Netlogo to specify deer reproductive probabilities. Here is what I have come up with so far:

to reproduce-adult
let chance-fawn random-float 1.001
let chance-to-reproduce .9 
let chance-for-one .3 
let chance-for-two .4 
let chance-for-three .02
  if any? femadults [
    ask femadults [
  if random-float 1.001 < chance-to-reproduce [
    if chance-fawn < chance-for-three
    [set births (births + 3)
      let new-offspring nobody
      hatch-infants 3
      [set new-offspring self set color red - 1 set size 1]
      set offspring new-offspring]
    if chance-fawn > chance-for-two
    [set births (births + 2)
      let new-offspring nobody
      hatch-infants 2
      [set new-offspring self set color red - 1 set size 1]
      set offspring new-offspring]
    if (chance-fawn > .02) and (chance-fawn < chance-for-one)
    [set births (births + 1)
      let new-offspring nobody
      hatch-infants 1
      [set new-offspring self set color red - 1 set size 1]
      set offspring new-offspring]
     ]]]
   end

Basically, the chance of a doe getting pregnant is 90%. So I want that if the doe gets pregnant, she either has 1, 2 or 3 fawns. The chance of having 1 fawn is 28%. The chance of having 2 fawns is 60%. The chance of having 3 fawns is 2%. The problem with my current code is that if "chance-fawn" is between .3 and .4, it is not accounted for in the if statements, when it should be part of the 60% of having 2 fawns. Is there a better way to do this, using either if statements or something else? Thank you!

Upvotes: 1

Views: 1139

Answers (2)

Luke C
Luke C

Reputation: 10291

You can do what you want with ifelse, but you may want to have a look at the rnd extension, as it simplifies this type of thing. Specifically, the weighted-one-of-list command allows you to make roulette wheel selection where you assign different weights to different options. For an example, look at this setup:

extensions [ rnd ]
globals [ fawn-probs ]

to setup
  ca
  crt 10 [
    setxy random-xcor random-ycor
  ]
  set fawn-probs [ [ 1 0.31 ] [ 2 0.67 ] [ 3 0.02 ] ]
  set offspring-list-norm []
  set offspring-list-alt []
  reset-ticks
end

You've got a list called fawn-probs that groups the different probabilities to different birth events. Note that I've made them sum to 1 by dividing each by 0.9; as p._phidot_ pointed out, your original probabilities did not. Now, you can use rnd:weighted-one-of-list to have your turtles randomly choose the number of fawns, weighted appropriately, from the fawn-probs list.

to reproduce
  ask turtles [
    ; If a spawning event occurs
    if random-float 1 < 0.9 [  
      ; Select the number of fawns to spawn based on the weighted
      ; probability list 'fawn-probs'
      let num-to-spawn first rnd:weighted-one-of-list fawn-probs [ p -> last p ]
      hatch num-to-spawn [
        rt random 360 
        fd 1
      ]
    ]
  ]
end

Alternatively, if you want to have the 10% chance of no-birth bundled into the same list, you could skip the if random-float ... chunk and just do:

to reproduce-alternative
  set fawn-probs [ [ 0 0.1 ] [ 1 0.28 ] [ 2 0.6 ] [ 3 0.02 ] ]
  ask turtles [
    let num-to-spawn first rnd:weighted-one-of-list fawn-probs [ p -> last p ]
    hatch num-to-spawn [
      rt random 360
      fd 1
    ]
  ]
end

Upvotes: 3

p._phidot_
p._phidot_

Reputation: 1925

ok.. here's my drawing (not to scale) :

   +---------+---------+---------+---------+---------+--------->
   0.0      0.02      0.1       0.3       0.4       0.5

a number line.. after the 1st if, you covered :

   +=========+---------+---------+---------+---------+--------->
   0.0      0.02      0.2       0.3       0.4       0.5

on the 2nd if :

   +=========+---------+---------+---------+=========+=========>
   0.0      0.02      0.2       0.3       0.4       0.5

the 3rd if:

   +=========+=========+=========+---------+=========+=========>
   0.0      0.02      0.2       0.3       0.4       0.5

So, it is logical that your conditions DOESN'T covers 0.3 to 0.4 range. (:

Also note that if your random number generated is EXACTLY 0.02 for example.. the 1st if and the 3rd if will miss it too. unless you use something like <= or >=.

Hope that explains.. (:

Upvotes: 1

Related Questions