NetLogo selecting a value from a matrix - netlogo

I have a model in which dispersing male animals challenge resident males for their territory. The dispersing male has a certain probability of winning based on his age and the age of the resident male being challenged. In other words, I ask the model to compare the age of the male agent to that of the male being challenged and then select a probability of winning. For example:
let d random-float 1
if [age] of resident-male < [age] of dispersing-male
[
set prob-winning 0.7
]
if [age] of resident-male = [age] of dispersing-male
[
set prob-winning 0.5
]
if [age] of resident-male > [age] of dispersing-male
[
set prob-winning 0.3
]
if d < prob-winning
[
ask resident-male
[
die
]
]
I have data (see below) that provides the probability of winning in a matrix with age (years) of dispersing male (3 columns) and age of resident male (13 rows).
4 5 6
3 1 1 1
4 0.5 0.55 0.65
5 0.45 0.5 0.55
6 0.4 0.45 0.5
7 0.35 0.4 0.45
8 0.4 0.45 0.5
9 0.45 0.5 0.55
10 0.5 0.55 0.6
11 0.7 0.75 0.8
12 1 1 1
13 1 1 1
14 1 1 1
15 1 1 1
It seems really inefficient to use a bunch of if statements to determine whether the male wins. Does anyone know whether there is a way to input the matrix with the probability values that I can refer to during the challenge procedure? Or any other more efficient way of selecting a specific value from a two-dimensional matrix?

You could always use the NetLogo array or table extensions for that, but in your case, a list of lists could also do the trick:
to-report prob-winning [ age-res age-dis ]
let probabilities [
[ 3 1 1 1 ]
[ 4 0.5 0.55 0.65 ]
[ 5 0.45 0.5 0.55 ]
[ 6 0.4 0.45 0.5 ]
[ 7 0.35 0.4 0.45 ]
[ 8 0.4 0.45 0.5 ]
[ 9 0.45 0.5 0.55 ]
[ 10 0.5 0.55 0.6 ]
[ 11 0.7 0.75 0.8 ]
[ 12 1 1 1 ]
[ 13 1 1 1 ]
[ 14 1 1 1 ]
[ 15 1 1 1 ]
]
report item (age-dis - 3) first filter [ first ? = age-res ] probabilities
end
The last line uses a combination of first and filter to find the row corresponding to the age of the resident male, and then maps the age of the displacing male (i.e., age-dis - 3) to the right "column" in the table.
You can use it like this:
let p prob-winning [age] of resident-male [age] of dispersing-male
if random-float 1.0 < p [
ask resident-male [ die ]
]
There is no validation in the code, so if you give it an age that is not part of the table, you will get an error.

Related

How to create variables with several levels and associate to different turtle profiles in NetLogo?

I'm stuck in a piece of code. Could someone please help me?
The question is: I have 31 turtle profiles (which varies from one turtle to another turtle is where you place the "nest" that can place the nest in any type of ground cover and then there are even more variations. experts who only place the "nest" in a specific habitat type).
But each of these profiles has 2 parameters which are: metabolism (which has 3 levels = 3 values) and reproduction energy (which also has 3 levels = 3 values). That is:
Metabolism:
-level 1
-level 2
-level 3
Reproduction energy:
-level 1
-level 2
-level 3
So I wanted each of the 31 turtle profiles to have these 2 parameters with these 3 levels. For example:
Profile 1:
Metabolism:
-level 1
-level 2
-level 3
Reproduction energy:
-level 1
-level 2
-level 3
The point is that to create the 2 parameters with these values ​​3 values, I created a code as follows:
turtles-own [ energy-reproduction metabolism ]
to setup
ask turtles [
let a2 random-float 1.01
(
ifelse
a2 <= 0.33
[
set energy-reproduction 5
]
a2 > 0.33 and a2 <= 0.66
[
set energy-reproduction 25
]
a2 > 0.66
[
set energy-reproduction 50
]
)
]
ask turtles [
let a3 random-float 1.01
(
ifelse
a3 <= 0.33 [
set metabolism 2
]
a3 > 0.33 and a3 <= 0.66
[
set metabolism 8
]
a3 > 0.66
[
set metabolism 16
]
)
]
end
The point is that it could be that for profile 1 the turtle has: 1 colony with metabolism 3 and two colonies with metabolism 2 and none with metabolism 1. And the idea is that all 31 profiles have each of the 3 levels of each of the 2 parameters (which is the energy of reproduction and metabolism). How could I do this?
I would greatly appreciate any help.
If I understand you correctly, you want to have any possible combination of parameter levels in at least one turtle. Here is an example on how to create one turtle for each parameter combination, with var1, var2, var3 input via interface:
to go
let list1 [green red blue]
let list2 (list var1 var2 var3)
foreach list1 [ item1 ->
foreach list2 [ item2 ->
crt 1 [
set color item1
set size item2
setxy random-xcor random-ycor
]
]
]
end

How to make a variable belong to a range Netlogo

I have a turtle who can eat different amount of food for every tick, updating its stomach content every time. I would like to round the stomach content value so that it belongs to a range x.
this is the forage function that updates the stomach-content :
to forage
;; item=0.064g
set patch-n random-float 100
if patch-n <= 8 [set stomach-content (stomach-content + 0.00) ] ; does not find any item
if patch-n > 8 and patch-n <= 99 [set stomach-content (stomach-content + 0.192) ] ; finds 3 items
if patch-n > 99 [set stomach-content 0.4 ]; full stomach
ifelse stomach-content >= 0.132
[set fat-reserves (fat-reserves + 0.132 ) set stomach-content (stomach-content - 0.132)]
[set fat-reserves (fat-reserves + (stomach-content * 1)) set stomach-content 0] ;;
set fat-reserves (fat-reserves - (8 * bmr)) ; metabolic rate removes fat from fat reserves
end
the range I would like the stomach-content to belong to is
set x (range 0 0.4 0.04)
Is there a way to make my stomach-content value to be in this finite range of 11 values?
Something like to round stomach-content to the nearest value with mod=0.04 in the interval (0 , 0.4)
You could do something fancy with the mod reporter, but if you don't need it to be super fast, the following is easy enough, and also more flexible, as it would work with any list of values:
to-report nearest-in-list [ the-value the-list ]
report first sort-by [ [a b] ->
abs (a - the-value) < abs (b - the-value)
] the-list
end
You can then use it like this:
observer> show nearest-in-list 0.11 (range 0 0.4 0.04)
observer: 0.12
observer> show nearest-in-list 0.021 (range 0 0.4 0.04)
observer: 0.04
observer> show nearest-in-list 0.02 (range 0 0.4 0.04)
observer: 0
Note that, in case of ties (like with 0.02 in the example, which is halfway between 0 and 0.04) it gives you the lowest value.

Problems creating a x% fraction of turtles using n-of command

I want x% of turtles, called pholders, to change their choice from a good 1 to a good 2.
The code is as follows:
ask pholders [ifelse random-float 1 <= probkauf
[ask (n-of (count pholders with [choice-num = 1] * 0.01) pholders with[choice-num = 1]) [set choice-num 2]]
[ifelse random-float 1 < 0.5[imitation set typeofchoice 1][beratung set typeofchoice 4]]
]
Initially 100% of the pholders chose good 1. The Problem is as follows: When i rise the number of pholders above something between 102 and 108 n-of doesn't calculate a 1%-fraction anymore, it calculates 10%. The higher the number of pholders the bigger the fraction: for 200 pholders the code calculates 60%. When i leave the number of pholders constant and below 108 but change the percentage from 0.01 to 0.02 it calculates something like 55% or 58%. Is the problem probably coming from ask n-of in an ask environment?
Thank you very much in advance.
Your problem is that you are running the probabilistic code multiple times. Your code has this structure:
ask pholders
[ ifelse random-float 1 <= probkauf
[ ask (n-of (count pholders with [choice-num = 1] * 0.01) pholders with [choice-num = 1])
[ set choice-num 2]
]
[ <do something else> ]
]
If you have 500 pholders, then there will be 500 times that a pholder selects a random number and, if the number is lower than your value probkauf, it instructs a number of pholders with choice-num of 1 to change it to choice-num 2. 500 potential occasions of 1% conversion is why you have so many being converted.
Based on the description in your comments, I think you want this:
globals [probkauf]
turtles-own [choice-num]
to setup
clear-all
set probkauf 0.5
create-turtles 1000
[ setxy random-xcor random-ycor
set color blue
set choice-num 1
]
reset-ticks
end
to go
update-choices
tick
end
to update-choices
ifelse random-float 1 < probkauf
[ ask turtles with [choice-num = 1]
[ if random-float 1 < 0.01
[ set choice-num 2
set color red
]
]
]
[ ; whatever happens with other part of probability
]
end

Netlogo - non-valid results from random float, logic, and choosers

In Netlogo, I use choosers to pick a strategy and its associated outcome given an event. In my case, building codes are the strategy, fire damage is the outcome, and a fire is the event). A random variable denotes whether a fire event occurs. However, my results are not valid (I sometimes get fire damage > 0 resulting from a p > 0.40). Thank you so much for any insight regarding the problem.
to fire?
ask patches [
if (strategy = "updated-building-codes")
[set p random-float 1.00
if p > 0.40 [ set fire-level 0 ]
if p > 0.01 and p <= 0.40 [ set fire-level 1 ]
if p > 0.002 and p <= 0.01 [ set fire-level 2 ]
if p <= 0.002 [ set fire-level 3 ]
]
if (strategy = "no-updated-building-codes")
[set p random-float 1.00
if p > 0.40 [ set fire-level 0 ]
if p > 0.01 and p <= 0.40 [ set fire-level 5 ]
if p > 0.002 and p <= 0.01 [ set fire-level 6 ]
if p <= 0.002 [ set fire-level 7 ]
]
]
end

How to stop increasing a turtle variable once it reaches some maximum value?

Hi I need help in NetLogo variable settings.
I have turtles that own attributes with range of values, that is the minimum and the maximum.
turtles-own [weight history state-turtles run-duration ek tt cu sp]
to setup-turtles
create- NMAs 2 [
set ek 8 ; range 8 to 9
set tt 5 ;range 5 to 7
set cu 3 ; range 3 to 5
set sp 4 ; range 4 to 7
]
create- NBSs 2 [
set ek 3 ; range 3 to 5
set tt 4 ; range 4 to 7
set cu 3 ; range 3 to 4
set sp 3 ; range 3 to 6
]
to setup-patches
ask patches [ let projects random 4
;setup colours
]
End
to go
tick
ask turtles [
......
]
search-patch
if .....
]
End
to search-patch
if ( [ pcolor ] of patch-here = brown ) [
ifelse (;statement) [
update-turtles
] [
action-turtles
]
]
end
to update-turtles
if pcolor = yellow [
set ek ek + 0.1
set tt tt + 0.5
set cu cu + 0.1
set sp sp + 1 ]
if pcolor = green [
set ek ......
The numbers are kept increasing and I want to set up limits (range) as shown in setup turtles for each attribute Thank you
turtles-own [... ek-max tt-max cu-max sp-max ...]
to setup
...
create-NMAs 2 [
set ek 8
set ek-max 9
...
]
...
end
to update-turtles
...
if ek + 0.1 <= ek-max [ set ek ek + 0.1 ]
if tt + 0.5 <= tt-max [ set tt tt + 0.5 ]
if cu + 0.1 <= cu-max [ set cu cu + 0.1 ]
if sp + 1 <= sp-max [ set sp sp + 1 ]
...
end
As a side note, tick should come at the end of your go procedure, not at the beginning (reference).