NetLogo - calculating area of convex hull - netlogo

Agents in my model add patches to their territory patch-set. I'd like to calculate the area of the convex hull for their territories. However I am really having trouble figuring out how to implement those functions in the model. Any suggestions?

Based on the answer provided to the same question for Python:
to-report convex-hull-area [ #hull ]
;; #hull is an agentset of links,
;; presumably defining a complete hull
report (.5 * abs (
sum [
[ xcor ] of end1 * [ ycor ] of end2
- [ xcor ] of end2 * [ ycor ] of end1
] of #hull
)
end
It's easy using links, but you could also do something similar for sets of paired patches, or turtles, or an ordered list. MAP and REDUCE may be helpful there.

Related

How to find the average distance from turtles that fulfill a certain condition?

I want to move the current turtle one step closer to the others that fulfill a certain condition (e.g. have color = green).
I am doing this the hard way (because I don't know any better), by trying to calculate the the average distance of the current turtle from all others that fulfill the condition, and calculate the average from x+1, x-1, y+1, y-1. Then whichever is the smallest would indicate the direction of the move. Not very elegant, I know, and limits movements to horizontal and vertical, but I couldn't come up with anything better (the only other idea that struck me was to calculate average x and y coordinates of all turtles that fulfill the condition and move the current turtle towards that, but that seemed even more ridiculous to me)
Problem is that even with my clumsy solution, I am not getting anywhere, since I am struggling with how to calculate the average distance from the "green" turtles.
If you want to calculate the mean distance, you can have the asking turtle call mean and [distance myself].
With this setup:
to setup
ca
crt 10 [
set color green
move-to one-of patches with [ pxcor < 0 ]
]
crt 1 [
set color red
move-to one-of patches with [ pxcor > 10 ]
]
reset-ticks
end
Calling the function below will have the red turtle print out first all distances between itself and all green turtles, then the mean of those distances:
to calc-mean-distance
ask turtles with [ color = red ] [
print [ distance myself ] of turtles with [ color = green ]
print mean [ distance myself ] of turtles with [ color = green ]
]
end
Beyond that, I'm not 100% sure what you're trying to do- are you hoping to move the asking turtle towards the nearest turtle that meets some condition? If so, this might work for you:
to go
ask turtles with [ color = red ] [
let target min-one-of ( turtles with [ color = green ] ) [ distance myself ]
face target
ifelse distance target > 1 [
fd 1
] [
move-to target
]
]
tick
end
If you want the asking turtle to move instead towards the geographic center of those turtles that meet a condition, you could indeed get the mean x and y coordinates of those turtles as you describe, then have the asking turtle move towards that point:
to go
let central-x mean [ xcor ] of turtles with [ color = green ]
let central-y mean [ ycor ] of turtles with [ color = green ]
ask turtles with [ color = red ] [
facexy central-x central-y
ifelse distancexy central-x central-y > 1 [
fd 1
] [
setxy central-x central-y
]
]
tick
end
If those aren't quite what you're trying to achieve, feel free to leave a comment for clarification!

NetLogo: How to create links with a defined number of other turtles

I want to create a (scale-free) network where each turtle is connected to a specific number, say four, of other turtles. To allow some turtles to have many connections while others have few (but not less than four), my thought was to let each turtle have four out-links and let in-links would necessarily vary. Using the code for building a Barabasi-Albert scale-free network available on pg. 131 in Scott and Koehler's "A Field Guide to NetLogo" as a starting point, my code is included below.
My question is how to make each turtle connnect to four other turtles.
breed [liberals liberal]
breed [conservatives conservative]
to setup
clear-all
set-default-shape turtles "circle"
create-liberals 5 [
set adopt? false
let n count turtles
set color blue
]
create-conservatives 20 [
set adopt? false
let n count turtles
set color red
]
let m 4
let p .05
set my-threshold my-threshold
ask turtles[
let me self
let degrees max-n-of m turtles [count link-neighbors]
foreach (sort degrees) [ [?] ->
let chance random-float 1.0
if ( ? != self) and (chance < p ) [
ask self [ create-link-to ? ]
]
]
]
ask turtles with [(count out-link-neighbors) = 0 ] [
let degrees max-n-of m turtles [ count link-neighbors ]
let t one-of degrees
foreach (sort degrees) [
ask self [ if ( t != self) [ create-link-to t] ]
]
]
reset-ticks
end
The code above is part of my attempt to recreate Paul Ormerod's model, available at https://onlinelibrary.wiley.com/doi/abs/10.1111/j.1468-0270.2006.00611.x
Since you are doing a directed network, you won't have any issues with simply telling each turtle to select 4 other turtles and connect to them. The code for that would be:
ask turtles
[ create-links-to n-of 4 other turtles
]
Note that this is much more difficult in undirected networks because the links they 'receive' lead to too many links overall. Then you need to do something like NetLogo Efficient way to create fixed number of links
However, this will not get to your stated goal of a preferential attachment (scale-free, Barabasi-Albert or whatever you want to call it) degree distribution. The mechanism that generates that outcome is that the turtles select the turtles to make links with using weighted random selection, with the weight a normalised degree. You need the rnd extension and that gets you the weighted-n-of primitive.
I also noted some general issues with your code that are related to (I think) confusion about how the preferential attachment algorithm works and/or how NetLogo works. The weighted-n-of primitive will get rid of your need to look at random numbers and should simplify your code a lot. However, I am not clear what let degrees max-n-of m turtles [count link-neighbors] is supposed to do, but it appears to be creating a list of the four highest degree turtles. But the preferential attachment algorithm allows links to be created with even low degree nodes, just with lower probability.

NetLogo - Distributing grains of sand in sandpile model to random neighbours

This code relates to an adaption of the NetLogo sandpile model. When the count go grains in each patch exceeds the threshold which in this case is 3, the grains are re-distributed to the surrounding neighbors. I am trying to re-distribute one grain to 4 random neighbour patches.
The code returns a run time error because patches at the edge will not have all the 8 neighbors, so when asking for 4 random neighbours it returns an errors stating can't request 4 ransom agents from 3 etc.
I am trying to find a piece of code that will resolve this problem.
****Code Below*****
to-report stabilize [animate?]
let active-patches patches with [ n > threshold ]
;; The number iterations the avalanche has gone for. Use to calculate lifetimes.
let iters 0
;; we want to count how many patches became overloaded at some point
;; during the avalanche, and also flash those patches. so as we go, we'll
;; keep adding more patches to to this initially empty set.
let avalanche-patches no-patches
while [ any? active-patches ] [
let overloaded-patches active-patches with [ n > threshold ]
if any? overloaded-patches [
set iters iters + 1
]
ask overloaded-patches [
set base-color fired-color
;; subtract 'threshold' amount from this patch
update-n -4
if animate? [ recolor ]
;; edge patches have less than four neighbors, so some sand may fall off the edge
ask n-of 4 neighbors [
update-n 1
if animate? [ recolor ]
]
]
if animate? [ display ]
;; add the current round of overloaded patches to our record of the avalanche
;; the patch-set primitive combines agentsets, removing duplicates
set avalanche-patches (patch-set avalanche-patches overloaded-patches)
;; find the set of patches which *might* be overloaded, so we will check
;; them the next time through the loop
set active-patches patch-set [ neighbors ] of overloaded-patches
]
report (list avalanche-patches iters)
end
Instead of asking 4 neighbors, ask min list 4 count neighbors:
ask n-of (min list 4 count neighbors) neighbors [
...
]
But from the model point of view, there will be different redistribution on the edge of the table, so this is not a good idea. Maybe it is better to have a wrapped world and then manually "push" the grains off the table: select 4 neighbours and call just the ones with close pxcor and pycor. The rest is off the table.
If the world is wrapped (horizontally and vertically), we can always select 4 neighbors:
let selected-neighbors n-of 4 neighbors
Among these 4 neighbors only real neighbors are on the table
set selected-neighbors selected-neighbors with [
(abs (pxcor - [ pxcor ] of myself) < 2)
and
(abs (pycor - [ pycor ] of myself) < 2)
]
ask selected-neighbors [
....
]

NetLogo check if turtles are on same coordinates

I have two turtle breeds who populate each sides of the window and then only move round in there own side.
The problem I am having is that I want to constantly check to see if one singular instance of a turtle from each breed are both on the same y coordinate. And if this returns true i want both of those turtles to stop, but for all other turtles from each breed to carry on moving. I know you can identify a turtle by there unique ID but i don't know how to use this and how to use the correct syntax.
The best way to describe this in pseudo code would be
ask turtles [
if breed1 turtle ycor = breed2 turtle ycor
[ stop breed1 turtle and breed2 turtle ] ]
UPDATE
Tried getting the code to work but still nothing happening. Not sure if it is the way the procedure is wrote or the number I have chosen for the threshold.
to move-turtles
ask turtles [
if not any? turtles with [ breed != [ breed ] of myself and abs (ycor - [ycor] of myself) < 1 ]
[
ask redteam with [pcolor = green - 3] [
right random 360
forward 1
]
ask redteam with [pcolor != green - 3] [
back 1
]
ask blueteam with [pcolor = green - 2] [
right random 360
forward 1
]
ask blueteam with [pcolor != green - 2] [
back 1
]]
]
end
Note that "same coordinate" is actually somewhat ambiguous. If one turtles ycor is 5.0000001 and another's is 5.0000000, are they at the same coordinate? Because of this, you should check to see if their coordinates are within a certain amount of each other.
Also, the best way to stop moving is to simply not move. So, here is a possible go procedure that would do what you want:
to go
ask turtles [
if not any? turtles with [ breed != [ breed ] of myself and abs (ycor - [ ycor ] of myself) < threshold ] [
move ;; replace with your move procedure or code
]
]
end
Here, each turtle checks to see if there are any turtles of a different breed who's ycor is within threshold of their own ycor. If there are not, then it moves. Otherwise, it does nothing.
The myself stuff is the most confusing part here, so I recommend reading the docs.

To build patch clusters at large spatial scales

I used the code from How to create cluster patches that do not overlap between them to build patches as shown in the first figure below.
Here is the code :
to make-cluster
loop [
let cluster [patches in-radius (2 + random-float 2)] of one-of patches
if all? (patch-set [neighbors] of cluster) [pcolor = black] [
ask cluster [ set pcolor green ]
stop ] ]
clear-all repeat 20 [ make-cluster ]
When I use this code in a large spatial extent (i.e. 1000 x 1000 patches with patch size = 1 pixel), green patches are like circles (see the second figure below).
How can I have patches as shown in the first figure ?
Thank you very much for your help.
If your goal is to simply have heterogeneous regions (rather than specifically blocky, symmetric things), you might play around with some of the answers here: Creating a random shape (blob) of a given area in NetLogo
Frank's solution and my first solution will probably run pretty slow on that large of a world. I just added a solution that should scale to a world of your size. I've put it here too for convenience:
to make-blob [ area x y ]
let blob-maker nobody
crt 1 [ set blob-maker self setxy x y ]
let border patch-set [ patch-here ] of blob-maker
repeat area [
ask blob-maker [
ask min-one-of border [ distance myself ] [
set pcolor green
set border (patch-set border neighbors4) with [ pcolor = black ]
]
rt random 360
fd .8
]
]
ask blob-maker [ die ]
end
That said, if you like the blockiness, it's often the case that models with a large number of patches in a blocky formation can be reworked into models with a smaller number of patches that behave quite similarly. For example, one strategy is to scale down the size and movements of the turtles so that the world is still relatively large to them.