I have the following code in netlogo 6.0.1 using the dbscan (density-based clustering) extension to measure clustering effects and cluster distribution attributes among turtles on the world interface.
extensions [ dbscan ]
to setup
clear-all
ask patches [ set pcolor white ]
create-turtles 1000 [
set color black
set label-color blue
setxy random-xcor random-ycor
]
ask n-of 5 turtles [
ask turtles in-radius 3 [
set color one-of [red grey]
]
]
end
to-report radial-extent [ cluster ]
report max map [
a -> max map [
b -> [
distance a ] of b
]
cluster
]
cluster
end
to find-clusters
let red-grey-turtles turtles with [ member? color [red grey] ]
let clusters dbscan:cluster-by-location red-grey-turtles 3 3
(foreach clusters range length clusters [ [c i] ->
foreach c [
t -> ask t [
set label i
]
]
])
let num-clust length clusters
let max-clust-count max map length clusters
let mean-clust-count mean map length clusters
let var-clust-count variance map length clusters
let stdev-clust-count standard-deviation map length clusters
let max-clust-size mean map radial-extent clusters
let mean-clust-size mean map radial-extent clusters
let var-clust-size variance map radial-extent clusters
let stdev-clust-size standard-deviation radial-extent clusters
end
However, when I run the code, I keep getting the following error:
OF expected input to be an agent or agentset but got the list [(turtle 3) (turtle 19) (turtle 93) (turtle 186) (turtle 239) (turtle 243) (turtle 322) (turtle 326) (turtle 528) (turtle 587) (turtle 610) (turtle 712) (turtle 719) (turtle 736) (turtle 754) (turtle 799) (turtle 873) (turtle 874) (turtle 887) (turtle 889) (turtle 963) (turtle 18) (turtle 140) (turtle 156) (turtle 530) (turtle 557) (turtle 605) (turtle 687) (turtle 693) (turtle 919) (turtle 979) (turtle 252) (turtle 506) (turtle 978) (turtle 989) (turtle 14) (turtle 534) (turtle 586) (turtle 658) (turtle 133) (turtle 606) (turtle 702) (turtle 995) (turtle 597) (turtle 949) (turtle 160) (turtle 244) (turtle 703) (turtle 742) (turtle 902)] instead.
Clearly the radial extent function is treating the turtle clusters as lists instead of agent sets due to the use of the ofoperator to determine out cluster radii.
Any ideas on how to fix this?
Good news: your reporter is OK ...
... just correct the last line
let stdev-clust-size standard-deviation radial-extent clusters
to map the reporter over clusters:
let stdev-clust-size standard-deviation map radial-extent clusters
Related
I am trying to make a program where if a turtle detects a turtle ahead of it, it dies. Simple, but for some reason whenever one instance of this occurs, all of my turtles die, and I can't figure out how to correct this.
Here is my code:
to setup
ca
ask patches
[ set pcolor white
]
end
to spawn
crt 1
[ set color random 140
setxy random-xcor random-ycor
]
end
to wiggle
lt 100
rt 100
ifelse not any? turtles-on patch-ahead 1
[ fd 1
set pcolor color
]
[ die
]
end
to go
ask turtles
[ wiggle
]
end
It seems that ifelse not any? turtles-on patch-ahead 1 at one point always starts to evaluate as false, and I don't understand why.
I think the following example might shed a bit of light on what's happening to you:
to setup
clear-all
create-turtles 1 [
set xcor -0.5
set ycor -0.5
set heading 45
show (word "patch-here: " patch-here)
show (word "patch-ahead 1: " patch-ahead 1)
show (word "patch-ahead 1: " patch-ahead 1)
show (word
"not any? turtles-on patch-ahead 1: "
not any? turtles-on patch-ahead 1
)
show (word
"not any? other turtles-on patch-ahead 1: "
not any? other turtles-on patch-ahead 1
)
]
end
It's creating one turtle, placing it on the bottom left corner of the central patch and making it face north east, before checking for a few things. If you run the code, you'll get:
observer> setup
(turtle 0): "patch-here: (patch 0 0)"
(turtle 0): "patch-ahead 1: (patch 0 0)"
(turtle 0): "patch-ahead 1: (patch 0 0)"
(turtle 0): "not any? turtles-on patch-ahead 1: false"
(turtle 0): "not any? other turtles-on patch-ahead 1: true"
The key point is that the diagonal of a patch is longer than one (remember Pythagoras' theorem). This means that patch-ahead 1 can still be the same patch that the turtle is on! In this case, not any? turtles-on patch-ahead 1 will be false. Since your turtles are moving randomly across the world, this is bound to happen eventually.
Luckily for you, there is a simple solution. Just use other:
not any? other turtles-on patch-ahead 1
Edited:
Each turtle has different values depending on its connections, I have several lists for different purposes. one of those lists seems to be stored once for all the turtles. My question is, how can I store values that are only related to each turtle in its list and not mix up all the values in one list.
I am getting something like this as a result:
(turtle 0): [3.1198376765467213 2.296024229601798 3.42548843517858 -1.259846009171373 -0.7503525744180024 0.8329075988682271 2.5179361772122446 2.499561039717374]
(turtle 1): [3.1198376765467213 2.296024229601798 3.42548843517858 -1.259846009171373 -0.7503525744180024 0.8329075988682271 2.5179361772122446 2.499561039717374]
(turtle 2): [3.1198376765467213 2.296024229601798 3.42548843517858 -1.259846009171373 -0.7503525744180024 0.8329075988682271 2.5179361772122446 2.499561039717374]
(turtle 3): [3.1198376765467213 2.296024229601798 3.42548843517858 -1.259846009171373 -0.7503525744180024 0.8329075988682271 2.5179361772122446 2.499561039717374]
when in fact the result should be like this
(turtle 0): [3.1198376765467213 2.296024229601798]
(turtle 1): [3.42548843517858 -1.259846009171373]
(turtle 2): [-0.7503525744180024 0.8329075988682271]
(turtle 3): [2.5179361772122446 2.499561039717374]
Here is the codes I tried: (please note that calc-payoff is a function that calculates the payoff values for each turtle and it works perfectly fine)
ask turtles [
calc-payoff
set p_list lput ([payoff] of self) p_list
reset]
AND
Added part:
the problem is that some of the turtles have turtle_list2 = 0 by the end since the if condition was not fulfilled for them. However, I want the round to keep going until all the turtles find their stable values. (this part is after the tick)
ask turtles [
calc-payoff
set p_list lput payoff p_list
reset]
ask turtles [create-links-to other turtles
calc-payoff2
set turtle_list lput payoff turtle_list
reset]
ask turtles [
ask one-of links [die]
calc-payoff2
set turtle_list lput payoff turtle_list
reset]
tick
set tickcount tickcount + 1
if tickcount >= 3[
ask turtles
[
let p1 item (length turtle_list - 3) turtle_list
let p2 item (length turtle_list - 2) turtle_list
let p3 item (length turtle_list - 1 ) turtle_list
if p1 < p2 [if p2 > p3 [ set turtle_list2 (list p2) ]]
set payoff_list lput (sum turtle_list2 ) payoff_list]
user-message (word "stability is reached at payoff = " sum payoff_list)]
end
Hard to say for sure without seeing your code, but my guess is that p_list is a globals variable instead of a turtles-own variable. Have a look at the variables section of the NetLogo user manual for some more details.
For an example, have a look at the following toy setup:
globals [ global-list ]
turtles-own [ turtle-list ]
to setup
ca
set global-list []
crt 10 [
move-to one-of patches
set global-list lput xcor global-list
set turtle-list ( list xcor )
]
reset-ticks
end
After running that setup, if you do print global-list, you should see output like:
[-14 4 -3 11 -16 -2 4 8 -1 -9]
If we ask the turtles to show their own list with
ask turtles [ show turtle-list ]
you should see something like:
observer> ask turtles [ show turtle-list ]
(turtle 3): [-14]
(turtle 5): [8]
(turtle 9): [4]
(turtle 7): [-16]
(turtle 2): [4]
(turtle 0): [11]
(turtle 6): [-3]
(turtle 8): [-9]
(turtle 1): [-1]
(turtle 4): [-2]
Where each turtle has their own version of that list.
Edit:
To have your turtles update their lists, you can use exactly the same lput syntax you used in your question- for example, the following loops until a randomly drawn float value is less than 0.25, then has turtles print out their turtle-list. For each iteration of the loop, the turtles will move, then add to their turtle-list:
to go
loop [
if random-float 1 < 0.25 [
ask turtles [ show turtle-list ]
stop
]
ask turtles [
fd 1
set turtle-list lput xcor turtle-list
]
]
end
You get an output like:
(turtle 2): [13 13 13 13]
(turtle 5): [-4 -4.3583679495453005 -4.716735899090601 -5.0751038486359015]
(turtle 9): [14 13.015192246987791 12.030384493975582 11.045576740963373]
(turtle 7): [-3 -2.5 -2 -1.5]
(turtle 3): [-2 -2.3420201433256693 -2.6840402866513386 -3.026060429977008]
(turtle 0): [7 7.951056516295154 8.902113032590307 9.853169548885461]
(turtle 4): [-14 -13.947664043757056 -13.895328087514113 -13.842992131271169]
(turtle 8): [12 11.35721239031346 10.71442478062692 10.071637170940381]
(turtle 1): [16 15.674431845542843 15.348863691085686 15.02329553662853]
(turtle 6): [-16 16.426423563648953 15.852847127297908 15.279270690946863]
I am making a NetLogo model. Each agent has a list of 5 integers (agent-list). On each tick, turtles create link with one other turtle, and share with each other their list.
turtles-own [ agent-list ]
.
.
.
ask turtles [
create-link-with one-of other turtles
set agent-list lput agent-list of link-neighbors agent-list
]
I know the code above doesn't work, how should I fix it?
The simplest way to combine the lists as you've described would probably be sentence:
turtles-own [ agent-list ]
to setup
ca
crt 3 [
set agent-list map [random 10] range 5
]
reset-ticks
end
to link-and-share
ask turtles [
let target one-of other turtles
create-link-with target
set agent-list sentence agent-list [agent-list] of target
show agent-list
]
end
However, you'll have do do some tweaking depending on what you're actually looking to do since that means that turtles linking later in the procedure are likely to pull the agent-list of turtles that have already modified their own agent-list. So, if turtle 0 grabs the agent-list of turtle 1, then later turtle 4 grabs the agent-list of turtle 0, turtle 4 would have an agent-list of 15 integers, not 10, similar to the output below:
(turtle 1): [6 1 5 4 7 3 9 8 1 1]
(turtle 0): [9 0 3 3 5 3 9 8 1 1]
(turtle 2): [3 9 8 1 1 9 0 3 3 5 3 9 8 1 1]
I have a NetLogo model in which agents retrieve multiple lists of variables from other agents. The order in which these lists are returned is crucial, because variables in each list are associated with each other. However, I believe lists are returned from other agents in a random order each time. For example, take the following simplified test case:
turtles-own [testlist1 testlist2 testlist3 testlist4]
to setup
random-seed 1
clear-all
create-turtles 5
ask turtles [
create-links-with other turtles
set testlist1 []
set testlist2 []
set testlist3 []
set testlist4 []
set testlist1 lput [who] of self testlist1
set testlist2 lput [who] of self testlist2] ;identical to testlist1
end
to go
ask turtles[
set testlist3 reduce sentence [testlist1] of link-neighbors
show testlist3
set testlist4 reduce sentence [testlist2] of link-neighbors
show testlist4]
end
For my use case, values in testlist3 and testlist4 should be in the same order, but their orders differ at random. Output:
(turtle 2): [0 3 1 4]
(turtle 2): [3 4 1 0]
(turtle 3): [4 1 0 2]
(turtle 3): [1 0 2 4]
(turtle 0): [4 2 3 1]
(turtle 0): [3 4 2 1]
(turtle 1): [0 4 2 3]
(turtle 1): [4 2 3 0]
(turtle 4): [0 2 1 3]
(turtle 4): [0 3 2 1]
My question: What is the best way to return multiple lists (such as testlist and testlist2 above) from an agent-set in the same order in a given procedure?
Replacing link-neighbors with turtle-set sort link-neighbors doesn't work, because after converting the sorted list back to an agent-set, the agents in the agent-set are called in a random order. If at all possible, I'd prefer not to have to refactor the entire model from lists to matrices using the matrix extension.
You were on the right track with the idea of turning your agentset to a list. The only part missing was using map instead of turning it back into a turtle set and then using of again:
to go
ask turtles[
set testlist3 reduce sentence map [ t -> [ testlist1 ] of t ] sort link-neighbors
show testlist3
set testlist4 reduce sentence map [ t -> [ testlist2 ] of t ] sort link-neighbors
show testlist4
]
end
See this answer for a bit more detail about the parallel between list operations and agentset operations.
How can I find all triangles in an undirected network in Netlogo, that is, list all instances of A-B, B-C, C-A?
Thank you,
Thomas
Here is a fairly naive approach. If your network is not too big, it could be good enough:
to-report find-triangles
let triangles (list)
ask turtles [
let t1 self
; find all the triangles that the turtle is a part of
ask link-neighbors [
let t2 self
ask link-neighbors [
let t3 self
if link-with t1 != nobody [
set triangles lput (turtle-set t1 t2 t3) triangles
]
]
]
]
report remove-duplicates triangles
end
Let's test it with a simple network:
to setup
clear-all
create-turtles 4
ask turtle 0 [
create-link-with turtle 1
create-link-with turtle 2
]
ask turtle 1 [
create-link-with turtle 2
]
ask turtle 3 [
create-link-with turtle 1
create-link-with turtle 2
]
ask turtles [ set label who ]
repeat 30 [ layout-spring turtles links 0.2 5 1 ]
show map sort find-triangles
end
From the command center, the result is:
observer> setup
observer: [[(turtle 1) (turtle 2) (turtle 3)] [(turtle 0) (turtle 1) (turtle 2)]]