NetLogo: How to pull coordinates from neighboring patches based on patch-variable - netlogo

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

Related

Divide regions accordingly to physical features

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.

NetLogo: Changing one breed's variable depending on other breed's variable in an ego-centric network environment

Dear Stackoverflow users,
I am a newbie to NetLogo and the community here, so I hope I can express myself adequately. If you need more information in order to understand my question, please, let me know. As I am not completely sure, where my problem lies, my title might even be misleading.
Here is what I am trying to do: I want an ego-centric network model, in which 1 ego (a Latino immigrant in the US) starts with a given value (between 1 and 6) for
identification with Latino culture and
identification with US/White culture.
The ego (breed #1) has 8 alters (breed #2). The alters consist of Latinos and Whites (ratio to be determined by slider in the interface: number-Latinos). The alters are randomly connected between themselves (amount of undirected links to be determined by another slider in the interface: number-of-alter-links). Each alter has a value for degree d (which is the number of links within the same ethnicity).
At each tick, ego is supposed to interact randomly with one of the alters. If the alter is Latino, then ego's initial value for Latino identification should increase by 0.1 + d * 0.1. If the alter is White, ego's initial value for US identification should increase by 0.1 + d * 0.1. The maximum value that can be reached for the identification variables is 6.
Here comes the code:
breed [egos ego]
breed [alters alter]
egos-own[identification-US identification-Latino]
alters-own[degree]
to setup
clear-all
setup-alters
setup-egos
reset-ticks
end
to setup-alters
create-alters 8
[layout-circle alters 8
if who < number-Latinos [set color orange] ; Latinos are orange
if who >= number-Latinos [set color yellow] ; Whites are yellow
]
while [count links < number-of-alter-links][
let node1 random 8
let node2 random 8
if (node1 != node2)[
ask alter node1 [create-link-with alter node2]
]
]
ask alters [ ; set degree within same ethnicity
ifelse color = yellow
[set degree (count link-neighbors with [color = yellow])]
[set degree (count link-neighbors with [color = orange])]
]
end
to setup-egos
create-egos 1 [
set identification-US initial-US-identification-ego
set identification-Latino initial-Latino-identification-ego]
end
to go
if ticks >= 50 [stop]
interact
change-identification
tick
end
to interact
ask egos [create-link-with one-of alters [set color green]]
end
to change-identification
ask links with [color = green] [let d [degree] of end1
ask egos [
ifelse link-neighbors = yellow
[ifelse (identification-US < 6)
[set identification-US identification-US + 0.1 + d * 0.1]
[set identification-US 6]
]
[ifelse (identification-Latino < 6)
[set identification-Latino identification-Latino + 0.1 + d * 0.1]
[set identification-Latino 6]
]
]
]
ask egos [ask my-links [die]]
end
This is my problem: When I am running the simulation, only the value for Latino identification changes, but not the one for US identification. This is even true, when there are no Latinos in the network. I am not sure where the problem lies. Is it in the nested ifelse command? I have tried to work my way around the nested ifelse and made several if commands, but the problem remains. Does it have to do with how I defined the two ethnicities with colors? Also, when I ask in the command center something about a particular turtle (e.g., turtle 3), I get the answer 9 times (total number of turtles). Maybe the problem is how I ask the link-neighbor(s) for its color?
Thanks for your attention! Any idea, suggestion or possible solution is highly appreciated.
This will always be false: link-neighbors = yellow.
Btw, if you post an entire model like this, you need to replace the interface globals with code-based declaration and initialization of the variables.

Netlogo model is extremely slow and has a delay between each tick

The model that i have created is very slow. I am a beginner in Netlogo and not sure if my code is inefficient or my system configuration is the problem.
I have a 35 x 35 grid and most of my operations are patch based i.e. each patch has to find the closest and farthest turtle as well as their distance and perform additional operations based on that. In addition at every tick based on an if-else logic where the patches that don't meet the condition turn white with a gradient using the scale-color function while those patches that meet the condition have to take the color of the closest turtle.
I can post the code but don't want to spam, please advise. Thanks.
Following piece of code seems to be problem.
to update-support
ask patches [
set closest-party min-one-of parties [distance myself]
set closest-party-dist [distance myself] of closest-party
set farthest-party max-one-of parties [distance myself]
set farthest-party-dist [distance myself] of farthest-party
set f 0
set h 0
set f ( -1 / ( [my-old-size] of closest-party / sum[my-old-size] of parties )) * (closest-party-dist ^ 2)
set h ( [my-old-size] of farthest-party / sum[my-old-size] of parties ) * (farthest-party-dist ^ 2)
set b-c (f + h)
ifelse (b-c <= threshold)
[ set votes-with-benefit 0 set pcolor scale-color white citizen-share 0 max-citizen-share ]
[ set votes-with-benefit citizens set pcolor scale-color ([color] of closest-party) citizen-share 0 max-citizen-share]
]
ask parties [ set my-size sum [votes-with-benefit] of patches with [closest-party = myself]
;set my-benefit mean[b] of patches with [closest-party = myself]
set my-benefit-chen mean[b-c] of patches with [closest-party = myself]
]
set largest-party max-one-of parties [my-size]
end
The number of parties is dynamic - it can range between 2 & 10. The update-support module is called both in the set & go. Below is that code:
to setup
clear-all
setup-citizens
setup-parties
update-support
setup-plot
reset-ticks
end
to go
ask parties [ adapt set my-old-size my-size ]
update-support
plot-voter-support
plot-voter-turnout
tick
end
Regards
Yuvaraj
First simple fix, if you are using a patchset multiple times, create it once and then call it. So:
ask parties [ set my-size sum [votes-with-benefit] of patches with [closest-party = myself]
set my-benefit-chen mean[b-c] of patches with [closest-party = myself]
]
becomes (and easier to read, and ensures consistency if you change the condition later)
ask parties
[ let my-patches patches with [closest-party = myself]
set my-size sum [votes-with-benefit] of my-patches
set my-benefit-chen mean[b-c] of my-patches
]
In a similar vein, you have sum[my-old-size] of parties twice in the code (calculating f and h), and you actually calculate it over and over again because you ask each patch to run this code. You should calculate it once and then use it:
to update-support
let old-total sum [my-old-size] of parties
ask patches
[ ...
set f ( -1 / ( [my-old-size] of closest-party / old-total )) * (closest-party-dist ^ 2)
set h ( [my-old-size] of farthest-party / old-total ) * (farthest-party-dist ^ 2)
set b-c (f + h)
...
]
...
end
How much improvement these changes make will depend mostly on the number of parties. Please try them and see if it's solved the problem.

How can I get an agent to decay as multiple agents feed on it?

In my model I have some agents which act as food items with a set energy. These are fed upon by a number of turtle breeds who each have their own food-energy which is less than the energy of the food item.
The code for the feeding agents is as follows:
to eat
ifelse [food-energy] of myfood > 1.5 [
set food-energy 1.5]
end
and the associated code for the food item to decay is:
to decay
if any? turtles-here [set food-energy
(1.5 * count feeders-here with [myfood = myself]
end
The problem occurs if the energy of the food is not an exact multiple of the amount of energy the feeders can consume. So for example it can go down to 1 and this results in the feeders taking 1.5 units which should be impossible. This is exacerbated when I have different breeds with different food energies (i.e. < or > 1.5).
So my question is how can I get this things to balance?
You need to study the Wolf-Sheep Predation model. This is the first NetLogo tutorial: http://ccl.northwestern.edu/netlogo/docs/tutorial1.html There are five versions of increasing complexity in the NetLogo Models Library, which are covered in chapter 4 of Wilensky and Rand (2015), which you should read.
See some related material here:
http://jasss.soc.surrey.ac.uk/14/2/5.html
Some hints follow, but many details need filling in.
breed [feeders feeder]
patches-own [ food-energy ]
feeders-own [ myfood ]
to setup
ca
ask patches [set food-energy random 50]
create-feeders 500 [
move-to one-of patches
set myfood one-of patches
]
end
to go
ask feeders [move]
ask feeders [feed]
ask patches [growback]
end
to move ;how shd they move?
rt random 20
left random 40
fd 1
;shd movement cost energy?
end
to feed
if (patch-here = myfood) [
let _extracted min (list food-energy 1.5)
set food-energy (food-energy - _extracted)
]
end
to growback
;do you want growback?
end
thanks for your responses. I'll try to implement them. This is one inelegant workaround that worked for me:
to eat
ifelse (food-energy / capacity) < 1 and [meat] of myfood > capacity [
set food-energy 1.5] [set food-energy [meat] of myfood
ask myfood [set shape "square"]]
if (food-energy / capacity) = 1 [
set color white]
if (food-energy > 0 and food-energy / capacity < 1)
[ set color white ]
end
This was initially causing a problem such that when the food energy went down to 0 and I asked it to die any animal looking at the [meat] of myfood lost it's target and I got an error. So I made the animals break this connection once their colour was white.
to ignore
set myfood nobody
set food-energy food-energy * 1
end

Find the presence of other turtles in a given direction upto a distance

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.