Reputation: 31
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
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
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