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.
Related
I'm working on a smaller project and got stuck on an issue, I'm not really sure if it's possible to solve it in NetLogo but I want to give StackOverflow a go!
I got a model that divides the world into different parts and randomly add physical features (such as rivers). If a feature goes through the whole region, I want it to separate the region and make into two regions. As an example, in the picture below, I want to separate the purple region into two unique regions accordingly to the physical feature (black).
The code I used to generate the picture above, can be found below.
to setup
ca
;Setting world.
resize-world 0 19 0 19
;Creating regions.
let x 5
let y 5
let col 45
while [y <= max-pycor + 1][
while [x <= max-pxcor + 1 ][
ask patches with [pxcor < x and pxcor >= x - 5 and pycor < y and pycor >= y - 5][
set pcolor col
]
set x x + 5
set col col + 10
]
set x 5
set y y + 5
]
;Generating physical features.
ask n-of 5 patches[ sprout 1[
set pcolor black]
]
let i 0
while [ i < (max-pycor * 2 )][
ask turtles [
fd 1
set pcolor black
ifelse (random 20 <= 1)
[
rt one-of [-90 0 90]
forward 1
]
[
fd 1
set pcolor black
fd 1
set pcolor black
]
set pcolor black
set i i + 1]
]
ask turtles [die]
end
My strategy for handling this is to realize that all we really need to do is "flood" a patch out by color and tag all the found adjacent patches, then repeat for any un-tagged, non-black patches until they are all done.
NetLogo does not have a "flood" command to get all patches adjacent to a patch meeting a criteria, so we make a special reporter of our own to handle it, patches-adjacent. Then it's just easy to ask those patches-adjacent to set their region to the currently chosen region.
I don't love this code, it's a little finicky and would be prone to infinite loops if tweaked incorrectly, but it should work. I bet there is a cleaner way to do this that I'm not thinking of at the moment.
; add a variable to track the different regions
; the default value will be `0` for each patch when `clear-all` is called
patches-own [ region ]
to set-regions
let current-region 1
; only act on non-black patches that haven't yet been assigned a region
let untagged patches with [ region = 0 and pcolor != black ]
while [any? untagged] [
ask one-of untagged [
ask patches-adjacent [
set region current-region
]
]
; update the region and the untagged patches we have left to process
set current-region current-region + 1
set untagged patches with [ region = 0 and pcolor != black ]
]
; this is just to get a view of the regions to quickly see if our code worked, it can be removed
ask patches [ set plabel region ]
end
to-report patches-adjacent
report patches-adjacent-ex (patch-set self) pcolor
end
to-report patches-adjacent-ex [found pc]
let newly-found neighbors4 with [ (not member? self found) and pcolor = pc and region = 0 and pcolor != black ]
set found (patch-set found newly-found)
ask newly-found [
; use recursion to find the patches adjacent to each newly-found one
; relying on updating the `found` agentset as we go to avoid duplicates
; or looping forwarder
set found (patches-adjacent-ex found pc)
]
report found
end
I solved this by using the Patch Clusters model that can be found in the NetLogo model library.
I'm trying to make groups of four turtles rotate randomly around the center of the group, however I'm having trouble calculating said center. Group ids are sequential (eg turtles with [who] 0-3 are group 1, 4-7 are group 2 etc). Currently, my attempt at calculating the group center is as follows:
let i 0
while [i < group_num] [ ;;iterates over each group
;;setup some information about the group
let j 0
let cmx 0
let cmy 0
let cmz 0
while [j < 4] [
set cmx (cmx + (turtles ((i * 4) + j) xcor)) ;this doesn't work
;set cmy (cmx + (turtles with ((who = ((i * 4) + j)) ycor ))) ;nor does this
;set cmz (cmx + (turtles with ((who = ((i * 4) + j)) zcor )))
]
set cmx (cmx / 4)
set cmy (cmy / 4)
set cmz (cmz / 4)
;; rest of the program
]
Both the cmx and cmy line tell me that there's a missing closing parenthesis, but all parenthesis have a partner and the program highlights them as such. Any advice on how to call the position of a particular turtle?
Thanks in advance!
This is for NetLogo3D, correct? Maybe this base can get you on the right track. Some details in comments. With this setup:
turtles-own [ group-id static-center my-radius]
to setup
ca
let i 1
crt 16 [
set group-id i
if count turtles with [ group-id = i ] > 3 [
set i i + 1
]
set color 25 + ( 20 * group-id )
setxyz random-xcor / 2 random-ycor / 2 random-zcor / 2
pd
]
ask turtles [
; Identify the starting center of the group, as well
; as each turtles distance to that point
set static-center group-center
set my-radius distancexyz item 0 group-center item 1 group-center item 2 group-center
; Face the center point, then tilt up to be tangential
; to the circle the turtle should transcribe
facexyz item 0 static-center item 1 static-center item 2 static-center
tilt-up 90
ask patch item 0 group-center item 1 group-center item 2 group-center [
set pcolor [color] of myself
]
]
reset-ticks
end
That makes use of a group-center reporter that returns a list of the mean xyz coordinates of the group:
to-report group-center
let my-group turtles with [ group-id = [ group-id ] of myself ]
let group-x mean [xcor] of my-group
let group-y mean [ycor] of my-group
let group-z mean [zcor] of my-group
report ( list group-x group-y group-z )
end
And this is just a simple go for the turtles to tilt-down according to their radius.
to go
ask turtles [
tilt-down 180 / ( pi * my-radius )
fd 1
]
tick
end
I have limited programming experience (mechanical engineering student, so a bit of matlab and labview experience) and am very new to NetLogo, so I apologize in advance if this question is pretty basic or my code is of poor quality.
I need to have my turtles move to 1 of 2 possible neighboring patches based on a given probability function. The two patches that I need to input to the probability function are the two neighboring patches with the lowest nest-scent value. I have been able to pull the two lowest nest-scent values, but I cannot figure out how to actually figure out which patches those are, and how to put those coordinates into an ifelse statement to move the turtle to one of them based on the aformentioned probability function. I have the following code that is obviously not working:
to move
set farthest-patch sort-by < [nest-scent] of neighbors
let a1x pxcor of item 0 farthest-patch
let a1y pycor of item 0 farthest-patch
let a2x pxcor of item 1 farthest-patch
let a2y pycor of item 1 farthest-patch
let a1 item 0 farthest-patch
let a2 item 1 farthest-patch
let x (((a1 + a2) / 100 ) - 1)
let probability-move 0.5 * (1 + ((exp(x) - exp( - x)) / (exp(x) + exp( - x))))
ifelse random-float 1 < probability-move
[set to-move 1]
[set to-move 0]
let a1-probability (a1 / (a1 + a2))
ifelse random-float 1 < a1-probability
[set destination [a1x a1y]]
[set destination [a2x a2y]]
ifelse count turtles-here >= 20
[set full 1]
[set full 0]
if [a1x a21] = full
[set destination [a2x a2y]]
if [a2x a2y] = full
[set destination [a1x a1y]]
if [a2x a2y] and [a1x a1y] = full
[set to-move 0]
ifelse to-move = 1
[move-to destination]
[stop]
end
Basically what I have (tried) to do here is sort a farthest-patches list by increasing nest-scent, and I have pulled the two lowest nest-scent values in order to input those values into my probability functions (both for whether or not to move, and if they are to move which of the two patches to select). I am not sure how to properly pull the patch coordinates of the patches that the a1 and a2 values were taken from.
Thanks for any help,
Brad
okay, you are making life way more complicated than it needs to be. You can select the two patches (or turtles) with the smallest values of a variable with min-n-of. Look it up in the dictionary to get the details.
Having found the two candidates, the best option is to use the rnd extension for choosing the destination because it has a primitive for random selection by weight. Finally, since you are using a function of your variable as the weight (rather than the variable value itself), you need a way to construct that weight. The best option is to separate it out - you could also have a second variable with the weight value, but that just proliferates variables.
Here is a complete working model. Please copy the whole thing into a new instance of NetLogo and try and understand how it works, rather than just copy the relevant bits into your code because min-n-of, using agentsets and passing variables to procedures are important aspects of NetLogo that you need to know about. I have also set up colouring etc so you can see the choices it makes.
extensions [rnd]
patches-own [ nest-scent ]
to setup
clear-all
create-turtles 1 [ set color red ]
ask patches
[ set nest-scent random 100
set plabel nest-scent
]
reset-ticks
end
to go
ask one-of turtles [ move ]
tick
end
to move
set pcolor blue
let targets min-n-of 2 neighbors [ nest-scent ]
let destination rnd:weighted-one-of targets [ calc-weight nest-scent ]
move-to destination
end
to-report calc-weight [ XX ]
let weight 0.5 * (1 + ((exp(XX) - exp( - XX)) / (exp(XX) + exp( - XX))))
report weight
end
I wish to find out whether in a given turtle's heading there is another agent present upto a given distance.
Here the Distance is "D".
Note:
Any agent present before D in the given direction should be also considered.
Even the direction doesn't coincide with the other's agent centre but just touches it ,even then that agent should be considered.
Problem:
No turtle-ahead procedure available. Combination of patch-ahead and turtles-on not applicable due to patch-size>> turtle-size.
Possible approach:
1.Represent the turtle's heading by the equation of a line.
to-report calculate-line[x y angle]
let m tan angle
let A m
let B -1
let C (- m * x + y)
report (list A B C)
end
to-report heading-to-angle [ h ]
report (90 - h) mod 360
end
let line-equ calculate-line (xcor) (ycor) (heading-to-angle heading)
2.Calculate the perpendicular distance from other turtles here, Check if there are within a range that the size of other turtles.
to-report value[A X1 Y1];;A is list of coefficents of line, x1 and y1 are coordinates of red turtle
if-else(abs((item 0 A * X1 + item 1 A * Y1 + item 2 A) / (sqrt((item 0 A ^ 2) + (item 1 A ^ 2) ))) < [size] of wall )
[ report "true"][report "false"]
end
3.To check if the red turtle is within D. One could obtain a line perpendicular to black one and compute the red turtle distance from it to check if it is less than or equal to D. But then that adds more complication.(Though one can simplify rotate the turtle by 90 left or right and get the line equation.)
This is what I meant by my comment. Run this code (as its own model). What it does is turn all the turtles on a few 'ahead' patches a different colour. I know this is not what you are trying to do, but the agentset candidates is a relatively small number of turtles. These are the only ones that you have to check whether they are on the correct path. So instead of turning them a different colour you could check the direction that they are from your initial turtle.
to setup
clear-all
set-patch-size 25
resize-world -10 10 -10 10
create-turtles 1000
[ setxy random-xcor random-ycor
set color yellow
set size 0.4
]
ask one-of turtles
[ set color red
set size 1
check-from-me 5
]
end
to check-from-me [howfar]
let counter 0
let candidates turtles-here
while [counter < howfar]
[ set counter counter + 1
set candidates (turtle-set candidates turtles-on patch-ahead counter)
]
ask candidates [set color red]
end
to-report check-wall
let return false
hatch 1[
set color black
set size ([size] of one-of walls) / 2
show (2.5 * ([size] of myself))
while [distance myself < (2.5 * ([size] of myself))]
[
fd ([size] of one-of walls) / 64
if any? walls in-radius size
[
set return true
]
show distance myself
]
]
report return
end
The above works. But still is approx. I am looking for better solution with probably less maths as one elucidated in the question.
In NetLogo I setup a model such that male predators create a home range that varies within some bounds. I previously asked for help on stackoverflow on how to do that.
Selecting values from bounded normal distribution in NetLogo
This worked great. When the predator moves around the landscape I ask the predator to check whether it is outside its specific home range (these are different sizes because of the random process), and if so to face the center of the home range my-base. I can ask the predator to check whether it is outside of a circle with a specific radius, however, I'm having trouble asking the predator to detect its specific home range created at setup. I figure I could have "home range" be a predator characteristic and then ask them to look at their own home range, but again I'm having trouble with that. Any suggestions? A snippet of my code with the setup and "random-movement" procedure is below.
to setup
ca
clear-all-plots
clear-output
clear-turtles
create-males 20
[
move-to one-of patches with [is-park?] ;inside a National Park
if any? males in-radius (((sqrt ((54.4 * 1000000)/ pi))/ 100) * 0.4) ;avoid other males
[move-to one-of patches with [is-park?] ]
set size 4
set shape "harimau"
set my-base patch-here
set homerange patches in-radius (((sqrt ((random-normal-in-bounds 54.4 35.8 19 151 * 1000000)/ pi))/ 100) * 0.4)
set numberofAdultMale ( numberofAdultMale + 1)
]
reset-ticks
end
to-report random-normal-in-bounds [mid dev mmin mmax]
let result random-normal mid dev
if result < mmin or result > mmax
[report random-normal-in-bounds mid dev mmin mmax]
report result
end
to random-movement
if-else my-base != no-patches[if distance my-base > (((sqrt ((54.4 * 1000000)/ pi))/ 100) * 0.4) ;this checks within a certain radius but not within the specific home range of the male
[ face my-base]
]
[ ]
rt random 180
lt random 180
fd time-step * random-gamma((meansRandomMove * meansRandomMove)/((deltaRandomMove)^ 2)) (1 / (((deltaRandomMove)^ 2) / meansRandomMove))
end
In above code I have the predators distribute themselves based on a predefined home range size (((sqrt ((54.4 * 1000000)/ pi))/ 100) * 0.4). A related question is how to have predators distribute themselves based on the actual home ranges homerange patches in-radius (((sqrt ((random-normal-in-bounds 54.4 35.8 19 151 * 1000000)/ pi))/ 100) * 0.4) created from the random distribution?
I think I figured it out. First I set homerange as an attribute of males. Then, at setup, set homerange patches in-radius (((sqrt ((random-normal-in-bounds HomerangeSizeMales 35.8 19 151 * 1000000)/ pi))/ 100) * 0.4). Then, in the movement procedure, used sqrt (count homerange / pi)