if elseif elseif else in netlogo - if-statement

I want to have a if elseif else if else structure in netlogo but it seems that at the moment it is not working.
ifelse random 100 < 68 [ set HBB-Genes "A,A" ];;68%
[ifelse random 100 < 2 [set HBB-Genes "S,S"] ;;2%
[ifelse random 100 < 15 [set HBB-Genes "A,A"];;15%
[set HBB-Genes "A,A"] ;;15%
]]
I would like to have a 68% chance of occurring the set HBB-Genes with "A,A" and the next one with 2% chance of occurring and so on. If anyone has experience with netlogo and can help it will be much appreciated. Thanks.

You only want to pick one random number, not several. You can use let to store the random number so you can refer to it later. So:
let chance random 100
ifelse chance < 68
[ set HBB-Genes "A,A" ]
[ ifelse chance < 70
[ set HBB-Genes "S,S" ]
[ ifelse chance < 85
...
And so on.

It can be done in the following way with if statements otherwise the next if statements got the remainder of the chance of occuring.
if geneNumber <= 68
[
set HBB-Genes "A,A"
set color blue
]
if (geneNumber > 68) and (geneNumber <= 83)
[
set HBB-Genes "A,S"
set color green
]
if (geneNumber > 83) and geneNumber <= 98
[
set HBB-Genes "S,A"
set color green
]
if geneNumber > 98
[
set HBB-Genes "S,S"
set color red
]

Related

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!
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
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.. (:

Netlogo: replacing matrix elements by conditioning on other rows/columns

I am working in Netlogo on a series of models making heavy use matrices. Briefly, the models include a number of state-variables for different breeds, where the state-variables are often stock-like items. As a simple example, consider the model:
extensions [ matrix ]
globals
[
]
turtles-own
[
n-items
stock-list
]
to setup
clear-all
reset-ticks
create-turtles 2
ask turtles
[
setxy random-xcor random-ycor
set n-items 10
let n-vars 3
set stock-list matrix:make-constant n-items n-vars [0] ; empty matrix
let stock-item n-values n-items [i -> i]
let stock-cost n-values n-items [ random-normal 10 2 ]
let stock-age n-values n-items [ random 50 ]
matrix:set-column stock-list 0 stock-item
matrix:set-column stock-list 1 stock-cost
matrix:set-column stock-list 2 stock-age
]
end
Here, each turtle's matrix stock-list is initialised as an empty matrix and then its columns filled in depending on the variables stock-item (id for stock), stock-cost and stock-age.
Imagine a go procedure that increments the stock age by one each time-step:
to go
ask turtles
[
let current-age matrix:get-column stock-list 1
let new-age map [x -> x + 1] current-age
matrix:set-column stock-list 2 new-age
]
tick
end
What I would like to do is an operation on stock-cost only if the age is greater than some value, e.g. 10
;; pseudo-code
for( i = 1 to I = number of items )
{
if ( stock-age[i] > 10 )
{
stock-cost[i] - 1
}
}
I know how to change the list of stock-cost conditional on its own values, using the map primitive, e.g.:
to decrease-stock-value
ask turtles
[
let current-cost matrix:get-column stock-list 1
set current-cost map [[?] -> ifelse-value (? > 10) [? - 1][?]] current-cost
matrix:set-column stock-list 1 current-cost
]
But my efforts to generalise this to using values in a different list to condition upon have failed.
Thanks for your help! Also, any insight onto whether this is a good approach to modelling state variables such as stocks would be useful.
I think I sorted it out using:
to decrease-stock-value
ask turtles
[
let current-cost matrix:get-column stock-list 1
let current-age matrix:get-column stock-list 2
let new-cost ( map [ [ a b ] ->
ifelse-value ( a > 10 ) [ b - 1 ] [ b ] ]
current-age current-cost
)
matrix:set-column stock-list 1 new-cost
]
end

A list containing NOBODY as one of its entities

I have a sub-routing in my code where each patch is asked to pick its closest & farthest turtle based on certain conditions. I keep getting this error after a couple of ticks
OF expected input to be a turtle agentset or turtle but got NOBODY instead.
error while patch 0 30 running OF
called by procedure UPDATE-SUPPORT
called by procedure GO
called by Button 'Go'
There are two other routines where a turtle dies or is born depending on a few other metrics that are measured. I am not able to debug the code but what i have figured so far is that it happens after a turtle dies or is born.
Below is the code based on which the closest & farthest turtles are assigned at each tick.
to update-support
ask patches [
let old-total sum [my-old-size] of parties
set f-party []
set h-party []
set party-list (sort parties)
set voteshare-list n-values length(party-list) [ (([my-old-size] of party ? ) + 1 ) / ( old-total + 1 ) ]
set party-citizen-dist n-values length(party-list) [ ( distance party ? ) ^ 2 ]
set f-list n-values length(party-list) [ ( ( 1 / ( item ? voteshare-list ) ) * ( item ? party-citizen-dist ) ) ]
set f-index position (min f-list) f-list
set h-list n-values length(party-list) [ ( ( item ? voteshare-list ) * ( item ? party-citizen-dist ) ) ]
set h-index position (max h-list) h-list
set f ((-1) * (min f-list))
set h max h-list
set f-party lput item f-index party-list f-party
set h-party lput item h-index party-list h-party
set closest-party first f-party
set farthest-party first h-party
]
After a turtle dies, when I inspected the patch which was throwing the error, i found the word nobody as an element in the list. The error is highlighted to be in the Party ? section while creating the voteshare-list in the above code
When I inspected the patch throwing the error, Party-list which is the list with all the current parties sorted was showing this:
Party-list: [(party 0) nobody (party 2)]
and my f-party list just had [(nobody)]
Has anyone faced such a situation.?
Below is the death & birth routine:
to party-death
ask parties [if (fitness < survival-threshold and count parties > 2)
[ die
] update-support
]
to party-birth
ifelse (endogenous-birth? = true)
[ ask one-of patches with [distancexy 0 0 < 30]
[ if (random-float 1 < (kpi * 1000)) [sprout-parties 1 [initialize-party] ]]
[ create-parties 1 [set heading random-float 360 jump random-float 30 initialize-party] ]
update-support
end

How does one achieve a square spiral like the the Ulam spiral in Netlogo?

I spent the morning trying to find an easy function (x,y) -> n that would number the patches like this
I was not successful. Do any of Y'all have any experience or suggestions?
Here is my take on it:
patches-own [ n ]
to setup
clear-all
resize-world -4 4 -4 4 ; so it looks better, but use any size you like...
create-turtles 1 [
set heading 180
foreach n-values count patches [ ? + 1 ] [
set n ?
if [ n = 0 ] of patch-left-and-ahead 90 1 [ left 90 ]
fd 1
]
die
]
ask patches [ set plabel n ]
end
Funny you should ask I also spent the morning doing the same thing. There is a function that uses the floor function but I remembered that this is netlogo
so I made a turtle do it for me.
with this procedure
to spin
let k 1
set t t + 1
repeat 2
[
lt 90
repeat t [fd 1 ask patch-here [set n k set k k + 1]]
]
end
and this code in the start up.
crt 1 [
set heading 0
repeat 41 [spin]
die
]
and of course
patches-own [n]
to call them in n order use
foreach sort-on [n] patches ask ? [ "the stuff you want them to do" ]

How to make turtles move along a list of locations in order

My objective is to have an agentset (named ships) hatch at another agentset (named ports and listed in index) containing 2 locations representing the start and end of a pathway. To go- start moving ships/ heading towards a third agentset (called waypoints and listed in index1) in their given order.
However, if a port is closer to the current waypoint than another waypoint- move to port instead. Once the ships have reached the other port, I would also like them to stop.
Currently I have the model working with only two agentsets (ships and ports) however I would like to include a third set(called waypoints) to prevent ships from hatching at all locations(ports and waypoints) and to have the ships move in a sequential order by traveling along the waypoints (like stepping stones) before reaching the beginning or the end (ports).
Here is an example of my code:
breed [ships ship]
breed [ports port]
breed [waypoints waypoint]
ships-own [target-port
current-port]
to setup
ca
let index 0
create-ports 2
[ let loc item index [ [0 -32] [32 0] ]
setxy (item 0 loc) (item 1 loc)
set index index + 1
set shape "circle"
set size 2
set color red - 1]
let index1 0
create-waypoints 2
[let loc item index1 [[12 -3] [14 -26]]
setxy (item 0 loc) (item 1 loc)
set index1 index1 + 1
set shape "circle"
set size 1
set color red - 1]
ask ports
[ let s who
hatch-ships 1
[ set current-port s
set size 1
set color red
pen-down
set pen-size 1
set target-port min-one-of ports with [ who != s] [distance myself]
set heading towards target-port
]
]
reset-ticks
end
to go
;(obey-elevation)
ask ships
[ if (distance target-port = 0)
[ let other_ports no-turtles
ask target-port [set other_ports (other ports)]
set target-port min-one-of other_ports [distance myself]
face target-port
]
ifelse (distance target-port < 1)
[ move-to target-port
]
[fd 1
]
]
tick
end
Any help would be greatly appreciated.