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

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.

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: have patches calculate influence value using reporter

I'm modeling a cityscape for looking at movement, where patches equate to buildings and have different influence values. I need to use a reporter function that calculates the value of each patch with something like:
(its own influence) plus (the influence of neighbors) divided by the
distance to a specific turtle (max-one-of distance myself)
The turtle will then move towards the patch with the highest influence value, but along a defined street.
I'm new to using netlogo and have gotten completely stuck.
I've included a portion of what I have so far, but I can't figure out how to write the reporter function that will compute each patches influence value (in-cone) so that the turtles can then move towards the best option.
to setup-influence-field
ask patches with [pcolor = green] [set influence commercial-influence]
ask patches with [pcolor = orange] [set influence production-influence]
ask patches with [pcolor = yellow] [set influence domestic-influence]
ask patches with [pcolor = pink] [set influence religious-influence]
ask patches with [pcolor = blue] [set influence public-influence]
end
to go
move-serapis
end
to move-serapis
ask serapis [set-procession-heading]
repeat 2 [ ask serapis [ fd .25 ] display ]
tick
end
;;;;; the reporter values are need for this part of the code so that the turtles (serapis) can move towards the patches with the highest influence value;;;;
to set-procession-heading
let direction patches in-cone 4 40 with [influence-field > 0]
if any? influence-field
[face max-one-of influence-field] ;;;; face towards the highest computed influence value
ifelse any? patches with [pcolor = black] in-cone 1 25
[process]
end
Any help would be greatly appreciated!
I don't think this is completely correct and I can't test it, but it should start you off and maybe someone here can fix it if you let us know the errors.
to set-procession-heading
let direction-targets patches in-cone 4 40 with [influence-field > 0]
if any? direction-targets
[ face max-one-of direction-targets [ influence-amount self ] ]
end
to-report influence-amount [ target-node ]
report ( [ influence-field ] + sum [ influence-field] of neighbors ) / distance target-node
end
What I have done is set up a separate procedure to report the results of your calculation. That procedure takes an argument (named target-node) because you need to be able to pass the identity of the turtle being influenced. Once you have that procedure, then you can simply pass the agent-set of potential directions to the calculation procedure and pick the one with the largest value.

Netlogo: How to make turtles stop moving when a condition (suitable patch is found) is met?

I'm trying to construct a model that simulates patterns of housing selection in a given area.
I am asking turtles to seek a settlement patch in radius-3 that offers the most resource, if one is found, they should settle there and stop moving; otherwise, they should move to somewhere else and stop moving. However, no matter what I do, no turtle seems to stop; every turtle is constantly moving around regardless of whether a settlement is found.
Below is my seek-settlement module under "go". Please advise on how to make a turtle stop moving if a condition is met (i.e. a suitable settlement is found)? I tried sticking “stop” in various places but with no difference.
to seek-settlement-1
ask turtles with [wealth >= com]
[
ifelse any? patches in-radius 3 with [pcolor = green and count turtles-here = 0]
[ ;;; if there are any neighboring empty green patches with resource larger than wealth of the turtle
move-to max-one-of patches in-radius 3 with [pcolor = green and count turtles-here = 0] [resource] ;+ (0.5 * count turtles in-radius 3 with [color = blue])]
set settlement patch-here ;;; move to the one with the most utility (defined as an even combination of resource and number of blue turtles in radius 1) and settle there
stop ;;; this stop appears to make no difference
]
[right random 360
forward 3
set wealth (wealth - com)
stop] ;;; this stop appears to make no difference
if settlement != nobody
[
set wealth (wealth - com + (0.5 * [resource] of settlement)) ;;; update the turtle's wealth by subtracting the cost of movement and adding 20% of the resource of the patch here
ask settlement
[set resource (0.5 * resource)] ;;; update the settlement patch's resource by subtracting 20%
stop ;;; this stop appears to make no difference
]
]
end
Please review the documentation of stop:
http://ccl.northwestern.edu/netlogo/docs/dict/stop.html
The stop will merely exit your ask.
Your code does not match your description. Trying to follow your description, I get something like the following:
globals [com]
patches-own [resource]
turtles-own [wealth settlement]
to setup
ca
set com 10
crt 50 [
set wealth random 500
set settlement nobody
setxy random-xcor random-ycor
]
ask patches [
if random-float 1 < 0.2 [set resource 100 set pcolor green]
]
end
to go
;you can change the filter any way you wish
ask turtles with [wealth >= com and settlement = nobody] [seek-settlement]
end
to seek-settlement
let _candidates (patches in-radius 3 with [pcolor = green and count turtles-here = 0])
if any? _candidates [
set settlement max-one-of _candidates [resource]
move-to settlement
]
ifelse (settlement = nobody) [ ;this conditional shd probably be in a separate proc
right random 360
forward 3
set wealth (wealth - com)
][
set wealth (wealth - com + (0.5 * [resource] of settlement))
ask settlement [set resource (0.5 * resource)]
]
end

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.

Test if the nearest turtle is in-radius

I try to ask to my turtles: if the nearest turtle is in radius lower to "distance-min" (a global), so get out!
But the following code doesn't work, and I really don't understand why.
to go
ask boeufs [get-out]
tick
end
to get-out
let x min-one-of boeufs in-radius distance-min [distance myself]
ifelse (x != nobody) [
face x
rt 180
fd 1
set color red
]
[
wiggle
]
end
It seems like if: x equals to the turtle himself …
the condition is always true, even with only 1 turtle in the world, why? :/
You want to use other. All it does is take an agent set and remove the current agent from it. So your code becomes:
let x min-one-of other boeufs in-radius distance-min [distance myself]
other boeufs won't include the turtle itself, so it will never be reported by this.