NetLogo - Have one variable changed with a certain probability of a group of randomly chosen turtles - netlogo

In NetLogo, I would like to have each round a likelihood of between 0 to 10 % turtles of the whole population to have a change of a variable. Within the chosen turtles, their variable can change between +1 and +4 by a certain likelihood.
breed [ humans human ]
humans-own [ var ]
to setup
create-humans(population) [ set var 0 ]
end
to go
ask humans [ var_change ]
end
to var_change [
let %draw (random-float 100)
let %strength 0 ;no eco loss
if (%draw < 50) [ set %strength (%strength + 1) ] ;1 little eco loss
if (%draw < 10) [ set %strength (%strength + 2) ] ;2 middle eco loss
if (%draw < 5) [ set %strength (%strength + 3) ] ;3 strong eco loss
if (%draw < 1) [ set %strength (%strength + 4) ] ;4 complete eco loss
[ ask one-of %strength patches [ set economic economic + 3 ]]; here I do not know how to continue(*)
]
end
*I do not know how to code that between 0 to 10 % of turtles can have with a certain probability have their variable var changed. How can I achieve that?

The way you have it set up, all turtles are sent to the var_change procedure. It would be easier to have the var_change procedure both select the turtles to change and assign the amount of change. Something like:
to go
var_change
end
to var_change
; choose proportion to change
let %draw-prop random-float 0.1
let n-changers round (%draw-prop * count turtles) + 1 ; +1 so at least one changes
; change by some amount
ask n-of n-changers turtles
[ let %draw-change random 100
set economic economic + 1 ;all get some eco loss
if (%draw-change < 10) [ set economic economic + 1 ] ;2 middle eco loss
if (%draw-change < 5) [ set economic economic + 1] ;3 strong eco loss
if (%draw-change < 1) [ set economic economic + 1 ] ;4 complete eco loss
]
end
Note that I changed all your + amounts to + 1. The way you had it written, drawing a number like 3 would have added 1 (as <50) then another 2 (as <10) then another 3 (as <5) for a total increase of 6. An if clause runs the code if the if condition is satisfied and skips over it if not satisfied. Either way, the next code always runs.

Related

NetLogo - calculate the difference of a variable of neighbouring agents

I would like to have each agents ask their neighbours of their value of a turtle-owned variable and set them according to the differences the have.
I know how to do this for distances:
if (any? other turtles-here)
[
ask neighbors [ ;; ask 8 neighbors / neighbors4 for 4
;if (max-one-of turtles [distance myself]) <= 3
;[set opinion opinion - .1] ; no change in opinion
;if (distancexy point1-pxcor point1-pycor) > 20 and (distancexy point1-pxcor point1-pycor) <= 50
;[set point1-location "middle"]
;if (distancexy point1-pxcor point1-pycor) > 50
;[set point1-location "far"]
]
however I struggle with implementing it for an exchange of values. How do I achieve this?
This is my MWE.
Note that the code part in question is in pseudo-code.
breed [ turtles ]
turtles-own [ variable ]
to setup
clear-all
create-turtles 100
[
set variable random-float 10
]
reset-ticks
end
to communicate
if (any? other turtles-here)
[
ask neighbors [
pseudo-code: if difference of your variable and my variable is bigger then 3, than do nothing
if differences less then 3, calculate the higher variable minus 0.1 and the lower variable plus 0.1
if difference less then 2, calculate the higher variable minus 0.3 and the lower plus 0.3
if difference less then 1, calculate the arithmetical mean
]
]
end
to go
ask turtles [
rt random 360
fd 1
communicate
]
tick
end
Your pseudo-code leaves a lot of room for interpretation, so this might not be exactly what you want, but I think it can get you started:
to communicate
ask turtles-on neighbors [
let both-turtles (turtle-set self myself)
let difference abs (variable - [ variable ] of myself)
if difference < 1 [ ask both-turtles [ set variable mean [ variable ] of both-turtles ] ]
if difference < 2 [ bring-closer both-turtles 0.3 ]
if difference < 3 [ bring-closer both-turtles 0.1 ]
]
end
to bring-closer [ both-turtles delta ]
ask min-one-of both-turtles [ variable ] [ set variable variable + delta ]
ask max-one-of both-turtles [ variable ] [ set variable variable - delta ]
end
There is a lot going on here, but nothing overly complicated. I think the main concepts you will have to understand here are: self and myself, the idea of storing an agentset in a local variable, and the idea of writing a procedure that takes arguments. You can read about all of this in the programming guide and look up the relevant primitives in the dictionnary.

Distance-based mortality model in netlogo

I am calculating cumulative turtle mortality in netlogo as a function of distance moved by turtles (100 of them) from the origin (start-patch) in the netlogo interface world. In the code below the 'Pass-Away' procedure is linked to a global interface switch called "space-death" which when switched on yields said distance-based mortality undertaken by the procedure called "Pass-Away-Space", otherwise maintains regular per-time-step (tick) mortality undertaken by the procedure called "Pass-Away-Time":
to Pass-Away-Time
ask turtles [
let chances 1 - exp( -1 * mortality * ticks )
if chances >= 1 [die
set dead-count dead-count + 1
]
]
end
to Pass-Away-Space
ask turtles [
let chances 1 - exp( -1 * mortality * [distance start-patch] of turtles)
if chances >= 1 [die
set dead-count dead-count + 1
]
]
end
to Pass-Away
ask turtles [
ifelse space-death [
Pass-Away-Space][
Pass-Away-Time
]
]
end
I get two errors doing this, both likely due to issues with the coding of the "Pass-Away-Space" procedure. The first is Only the observer can ASK the set of all turtles. Then when I move the let chances 1 - exp( -1 * mortality * [distance start-patch] of turtles) outside of the ask turtles[] brackets this error is resolved only yield another that says ** expected input to be a number but got the list* followed by a sequence of numbers. Perhaps due to the fact that the section of the mortality equation that reads * [distance start-patch] of turtles is invoked for multiple turtles (which is exactly what I want to achieve - have each random-walking turtle use its distance from the origin to calculate its cumulative per-step mortality and die above a threshold - an event that occurs at different times for different turtles at different distances). Any thoughts on how to resolve this?
The first error is because you are asking all turtles to ask all turtles. Starting with your Pass-Away procedure and assuming space-death is set to TRUE. What happens? You ask all turtles to run the Pass-Away-Space procedure. That is, each turtle will run that procedure in turn. The first step of that procedure is to ask turtles [ ]. So a turtle is asking all turtles to do something. Hence the error.
To fix it, you need to rewrite the Pass-Away-Space procedure so it runs whatever code needs to be run for a SINGLE turtle (and similarly for Pass-Away-Time). You probably want something like:
to Pass-Away-Space
if exp( -1 * mortality * [distance start-patch]) < 0
[ die
set dead-count dead-count + 1
]
end
So the first issue here is the nested use of the ask turtles [ ... ] command, which we can disambiguate by removing it from the to Pass-Away procedure or alternatively, from both of the other two (preceding) functions nested within it, as seen below (demonstrating the later of the aforementioned means.
let start-patch patch 0 0
to Pass-Away-Time
ask turtles [
let chances 1 - exp( -1 * mortality * ticks )
if chances >= 1 [die
set dead-count dead-count + 1
]
]
end
to Pass-Away-Space
ask turtles [
; let chances 1 - exp( -1 * mortality * [distance start-patch] of turtles)
let chances 1 - exp( -1 * mortality * (distance start-patch))
if chances >= 1 [die
set dead-count dead-count + 1
]
]
end
to Pass-Away
ifelse space-death [
Pass-Away-Space][
Pass-Away-Time
]
end
The second error can be resolved by switching the line of code commented (;) out in the to Pass-Away-Space procedure withe the immediate succeeding line so that when each turtle attempts to execute chances, cumulative per-distance (from origin) mortality is not calculated as an array of turtle chances with the use of the [distance start-patch] of turtles command, but rather per individual turtle with (distance start-patch) whenever the procedure is called by the nesting to Pass-Away procedure.

How to distribute turtles similar to a population distributed across the patches

I have a model in which a population is normally distributed across the patches. I used the following code to do that:
ask patches [
let x1 (pxcor - mean1) / sd-pop1
let y1 (pycor - mean2) / sd-pop1
set popualation ( (pop1) * exp (-0.5 * ( x1 ^ 2 + y1 ^ 2)) / (2 * pi * sd-pop1 ^ 2))
]
I want to distribute 10 turtles in a similar manner. In the attached image just as how the major chunk of the population is distributed across the patches close to the center of the grid space. Similarly of the 10 turtles to be created, i want a major chunk to be randomly spread across the population rich patches and a few which are spread on the periphery.
to setup-parties
create-parties Num-of-parties
let sp sqrt((((sd-pop1 ^ 2) * (pop1 - 1)) + ((sd-pop2 ^ 2) * (pop2 - 1))) / (pop1 + pop2 - 2))
ask parties [
ifelse (pop2 > 0) [ set heading random-float 360 jump random-float sp ] [ set heading random-float 360 jump random-float sd-pop1 ]
set size 3
set color random 130
set label who + 1
set label-color red
set my-old-size 1
set shape "default"
set old-x xcor
set old-y ycor
update-rule
]
end
I would use the rnd extension for this and select 10 patches (weighted by population) to sprout a turtle. Something like ask rnd:weighted-n-of 10 patches [ population ] [ sprout 1 ]. You will also need extensions [rnd] at the top of your code if you use this method.

How do I properly use the 'random' function for multiple agents?

In my model I have some agents collecting from another agent who they bump into at random after which they move back to their base. As they move back they drop off some material as defined by the random function. Here's some sample code
to go
ask searchers
[ set energy energy - 1
fd 0.0125
if random-float 1 < (1 / 50)
[ ifelse random 2 = 0
[ rt 45 ]
[ lt 45 ]
]
search
]
end
to search
if any? depots in-radius vision with [color = yellow]
[spread
set energy 0] ;; makes them to back to base
end
to spread
if random 10000 = 1 [hatch-rubbish 1 [ set color white
set shape "circle"
set size 0.5]]
end
If I set the visual radius to something enormous so they can always see the depot the number of bits of rubbish works out.
However if I allow them to move around with a radius of 1, the count of rubbish is much higher than 1 in 10,000.
Why would that make a difference?
Thanks

Creating overlapping agents in a line

Using the below code I get agents are like this:
to setup
ask breadth-patches [sprout-walls wall-agents[set color 2]]
ask length-patches [sprout-walls wall-agents[set color 2]]
ask gap-patches [sprout-walls wall-agents[set color 2]]
ask length-patches[align-inside-at-top]
ask breadth-patches [align-inside-at-right-left]
ask gap-patches[align-inside-at-top]
end
to align-inside-at-top ;; patch procedure
let counter count walls-here ;; we will use this as a count-down, after using it in some calculations
if counter > 0 ;; could assume there are turtles, but we are not.
[ let gap1 1 / counter ;; size of turtles, gap between turtles
let half-gap gap1 / 2 ;; half-size of turtles
let ytop 0
if-else(pycor < 0)[set ytop pycor - .5 - half-gap]
[set ytop pycor + .5 - half-gap]
let xleft pxcor - .5 - half-gap
ask walls-here
[ set size gap1
set ycor ytop
set xcor xleft + gap1 * counter
set counter counter - 1 ;; so we're placing them from right to left
; set ycor ycor + 0.125
]
]
end
to align-inside-at-right-left ;; patch procedure
let counter count turtles-here ;; we will use this as a count-down, after using it in some calculations
if counter > 0 ;; could assume there are turtles, but we are not.
[ let gap1 1 / counter ;; size of turtles, gap between turtles
let half-gap gap1 / 2 ;; half-size of turtles
let ytop pycor + .5 + half-gap
let xleft 0
if-else (pxcor < 0)[
set xleft pxcor + .5 - half-gap]
[ set xleft pxcor - .5 + half-gap
]
ask turtles-here
[ set size gap1
set ycor ytop - gap1 * counter
set xcor xleft ;+ gap * counter
set counter counter - 1 ;; so we're placing them from right to left
]
]
end
Note: The gap in the rectangle is due to the following code
ask patches with [pxcor > (gap * (-1)) and pxcor < gap and pycor =(breadthrec - 1)][ask walls-here[die]]
Here, gap = 1 ,i.e, a width of 1 patch.
So the input parameter is the wall-agents which specifies the number of agents to created per patch along the length and breadth patches.
I wish to change to create overlapping agents as in the figure below(Sorry the figure is not so perfect, but I hope it explains it). Please help on how to achieve this.
This is a lot of code to ask anybody to debug for you.
I would suggest solving a simpler version of the problem first. Do you have code that can create wall-agents turtles in a single patch, evenly spaced along a line? Once you had a working code that did that, then you could attempt to generalize it to your more complex problem.
If you run into trouble writing that simpler version, you'll have a smaller question to ask here on Stack Overflow that will be much easier for someone to answer than your current, very large question.
If you are able to write the simpler version, don't throw it away — keep it, so you can go back to it if you need to. Then tackle the bigger problem.
You might even be able to take the simpler version, put it into a procedure, and then call that procedure from your larger solution. Making small procedures that work, and then calling those smaller procedures from other ones, is often a good way to break a problem down into manageable parts.