How to set a regular lattice of turtles in the world - netlogo

I would like to set a regular grid of turtles. With the following example, I have gotten to distribute the reader agents equally spaced in the x dimension, but I can not set a maximum number of agents per row and place the followings rows of readers in the world.
breed [readers reader]
globals [ reader-ycor ]
to setup
clear-all
setup-globals
setup-readers
end
to setup-globals
set-default-shape readers "square 2"
set reader-ycor (min-pycor + 1)
end
to setup-readers
let horizontal-interval (world-width / number-of-readers)
create-readers number-of-readers [
set color green
setxy (min-pxcor - 0.5 + horizontal-interval * (0.5 + who)) reader-ycor
set size 3
set label ""
]
end
to go
setup
end
The global number-of-readers indicates the total number of readers, and max-number-per-row would be a variable set to 10 (the maximum number of readers per row).
I do not know how to tell the x-coordinate to stop when a row has 10 readers and how to tell Netlogo to add a new row of readers when the who of a reader is greater than 10.
Regards

I think instead of using who numbers (which is not recommended) you might be better off just calculating the coordinates manually and then spawning the turtles on the calculated values. With this setup:
breed [ readers reader ]
to setup
ca
spawn-by-row
reset-ticks
end
And these sliders for readers per row and number of readers:
This code will build readers from the lowest x/y value (details in comments):
to spawn-by-row
; get the intervals
let h-int world-width / readers-per-row
let v-int world-height / readers-per-row
; Get a range of horizontal and vertical coordinates, starting at half
; of the interval value from the minimum x coordinate
let h-vals ( range ( min-pxcor + h-int / 2 ) max-pxcor h-int )
let v-vals ( range ( min-pycor + v-int / 2 ) max-pycor v-int )
; Create an empty list to build into
let possible-coords []
; For each possible vertical value, map all horizontal values in order and
; combine these into an ordered list starting at the lowest px and py coords
foreach v-vals [
v ->
set possible-coords ( sentence possible-coords map [ i -> (list i v) ] h-vals )
]
; Use the number of readers to sublist the possible coordinates, and
; create a turtle at each of the coordinate combinations left.
let use-coords sublist possible-coords 0 number-of-readers
foreach use-coords [
coords ->
create-readers 1 [
setxy item 0 coords item 1 coords
set shape "square 2"
]
]
end
If you have more number-of-readers than can be accommodated by readers-per-row you will throw an error, but that would be easily fixed.
Edit 2:
Add a slider for distance-var to the interface above, and try this modified version of spawn-by-row
to spawn-by-row
; Get a range of coordinate values
let half-step 0.5 * distance-var
let d-vals ( range ( min-pxcor + half-step ) ( max-pxcor ) distance-var )
; Create an empty list to build into
let possible-coords []
; For each possible vertical value, map all horizontal values in order and
; combine these into an ordered list starting at the lowest px and py coords
foreach d-vals [
d ->
set possible-coords ( sentence possible-coords map [ i -> (list i d) ] d-vals )
]
; Use the number of readers to sublist the possible coordinates, and
; create a turtle at each of the coordinate combinations left.
let max-positions length possible-coords
if max-positions > number-of-readers [ set max-positions number-of-readers ]
let use-coords sublist possible-coords 0 max-positions
foreach use-coords [
coords ->
create-readers 1 [
setxy item 0 coords item 1 coords
set shape "dot"
set color white
]
]
end

I have managed a solution but using the avoidable who numbers.
breed [readers reader]
undirected-link-breed [ rris rri ]
globals [ reader-ycor ]
to setup
clear-all
ask patches [ set pcolor blue - 3 ]
setup-globals
setup-readers
end
to setup-globals
set-default-shape readers "square 2"
set separation-distance-ratio 10 ; should be > 10
set number-of-readers 24
set interf-rri-radius 110
end
to setup-readers
let horizontal-interval (world-width / separation-distance-ratio )
let vertical-interval (world-height / separation-distance-ratio )
create-readers number-of-readers [
setxy (min-pxcor - 0.5 + horizontal-interval * (0.5 + who mod 10 ))
(min-pycor - 0.5 + vertical-interval * (0.5 + floor (who / 10) ) )
set size 2.5
set color green
]
ask readers [ create-rris-with other readers in-radius interf-rri-radius ]
end
to go
setup
end

Related

NetLogo - Getting turtle position from mathematically generated turtle id

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

NetLogo nw extension: how to use nw:extension for multiple destination

Hi guys is it possible for netlogo nw:extension to calculate path for multiple destination.
I wanted my source 0 to pass by all the red nodes destination.
I've attempt by first putting the node-links of to all destination is a list. Then from there i take the minimum number of node-links as my first path and then put the nodes(turtle) and node-link to visited so it doesn't check the node and it's link again. Eg (node-link 0 4) (node-link 0 8), then add the links and the destination node 8 to visited. I do not know how to check that the node 8 is selected.
Any idea??
to setup
ca
crt Nodes
set-default-shape turtles "circle"
let positions [
[-7 7] [-1 7] [5 7] [11 7] [-7 1] [-1 1] [5 1] [11 1] [-7 -5] [-1 -5] [5 -5] [11 -5]
[-7 -11] [-1 -11] [5 -11] [11 -11]
]
foreach sort turtles [
nodePos -> ask nodePos [
setxy (first first positions) (last first positions)
set positions but-first positions
]
]
ask turtles [;setxy random-xcor random-ycor
if Show_Names? = True [show-names]]
;ask patches [set pcolor white]
end
to create-random-graph
ask links [die]
ask turtles [
set color blue
let neighbor-nodes other turtles in-radius 6
create-node-links-with neighbor-nodes [
set weight 1
set label weight
set color grey
set thickness 0.1
]
]
to TEST
let FDestin[ 9 6 8]
let Origin 0
let a 0
let b []
let i 0
while [a < length(FDestin) ][
let Destin item a FDestin
ask turtle Origin [
set path nw:weighted-path-to turtle Destin weight
set b lput(path ) b
]
set a a + 1
]
let findMinPath sort-by [ [list1 list2] -> length(list1) < length (list2) ]b
let findMin []
set findMin lput item 0 findMinPath findMin
;foreach findMin [ x -> ask one-of node-links x [die]]
end
This is sort of rough but may get you started. With these extensions and setup:
extensions [ nw ]
undirected-link-breed [ node-links node-link ]
breed [ nodes node ]
breed [ walkers walker ]
turtles-own [ path target-nodes ]
links-own [ weight ]
to setup
ca
set-default-shape nodes "circle"
set-default-shape walkers "arrow"
let vals ( range 11 -11 -5 )
foreach vals [ y ->
foreach reverse vals [ x ->
ask patch x y [
sprout-nodes 1 [
set color blue
set label who
set size 2
]
]
]
]
create-network
ask one-of nodes [
hatch-walkers 1 [
set color green
set pen-size 5
pd
set target-nodes nobody
set path []
]
ask n-of 3 other nodes [ set color red ]
]
reset-ticks
end
That creates a grid of nodes, as well as a single walker randomly placed on one of the nodes. Three of the nodes without a walker are red to act as 'target' nodes in the path. Then, your network procedure as in your question:
to create-network
ask links [die]
ask nodes [
set color blue
let neighbor-nodes other turtles in-radius 5
create-node-links-with neighbor-nodes [
set weight one-of [ 1 2 3 ]
set label weight
set color grey
set thickness 0.1
]
]
end
That gives you a randomly weighted network of links for the walker to follow.
Now, to build paths, get the walkers to recognize the red nodes as possible targets. Then, generate all possible path permutations, always starting at the node that the walker is on.
Permutations are generated using code modified from this answer
to-report path-permutations [ node-list ] ;Return all permutations of `lst`
let n length node-list
if (n = 0) [report node-list]
if (n = 1) [report (list node-list)]
if (n = 2) [report (list node-list reverse node-list)]
let result []
let idxs range n
foreach idxs [? ->
let xi item ? node-list
foreach (path-permutations remove-item ? node-list) [?? ->
set result lput (fput xi ??) result
]
]
report result
end
Edit: instead of fewest turtles en route, turtles now select the route with the smallest weighted distance.
Count the number of turtles of each possible path, and select the path with the smallest weighted distance over the entire route.
to set-path
if target-nodes = nobody [
; Designate any red nodes as targets
set target-nodes nodes with [ color = red ]
let start-node one-of nodes-here
; Get a list of nodes
let target-node-list sort target-nodes
; Build all possible paths
let possible-paths map [ i -> sentence start-node i ] path-permutations target-node-list
; Get the weighted distance turtles for each possible path
let path-turtles map [ i -> turtles-on-path i ] possible-paths
; Keep the path with the smallest overall weighted distance
let shortest-path reduce [
[ shortest next ] ->
ifelse-value ( weighted-dist-of-path shortest < weighted-dist-of-path next ) [ shortest ] [ next ] ] path-turtles
set path shortest-path
]
end
set-path uses these two reporters:
to-report turtles-on-path [ in-path ]
; A reporter that returns the path from the start node of a given path
; to the final node of that path.
let temp-path []
( foreach ( but-last in-path ) ( but-first in-path ) [
[ from to_ ] ->
ask from [
ifelse length temp-path = 0 [
set temp-path nw:turtles-on-weighted-path-to to_ weight
] [
set temp-path sentence temp-path but-first nw:turtles-on-weighted-path-to to_ weight
]
]
] )
report temp-path
end
to-report weighted-dist-of-path [ in-path ]
let weighted-dist 0
( foreach ( but-last in-path ) ( but-first in-path ) [
[ f t ] ->
ask f [
set weighted-dist weighted-dist + nw:weighted-distance-to t weight
]
] )
report weighted-dist
end
Once the turtle knows what path it should take, it can follow that path somehow- here is a simple example.
to follow-path
if length path > 0 [
let target first path
face target
ifelse distance target > 0.5 [
fd 0.5
] [
move-to target
ask target [
set color yellow
]
set path but-first path
]
]
end
All that is wrapped up in go like so:
to go
if not any? nodes with [ color = red ] [
stop
]
ask walkers [
set-path
follow-path
]
tick
end
To give behavior something like:
Edit:
The much-simpler option is to just have the walker check the nearest (by weight) target node, build the path, follow that path, then select the next nearest target once it reaches the end of that path (and so on). However, that may not give the overall shortest path- for example, look at the image below:
The green trace is the path taken by the path-permutations walker. The blue square indicates the starting node, the orange squares designate the target nodes. The orange trace is the one taken by the simpler walker (as described above). You can see that overall, the path taken by the simpler walker has a higher overall weight cost because it is only assessing the weighted path to the next target rather than the overall weighted cost of the entire path.

How to distribute turtles similar to a population distributed across the patches

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.

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.

How to control square size in a grid from square area?

I am new to Netlogo. I used the code of "Traffic grid" to draw square grid. From this code, how can I control square size in the grid from square area (e.g. one square = 100km²) instead of horizontal and vertical road number ? In my Netlogo world, one patch = 10km².
to setup
let grid-x-inc world-width / grid-size-x
let grid-y-inc world-height / grid-size-y
ask patches [ set pcolor brown ]
let roads patches with [( floor( (pxcor + max-pxcor - floor(grid-x-inc - 1) ) mod grid-x-inc ) = 0) or ( floor( (pycor + max-pycor) mod grid-y-inc ) = 0)]
ask roads [ set pcolor white ]
end
Thanks in advance for your help.
Pierre
to setup
clear-all
let block-area 100 ; desired area for a grid block in km²
let patch-area 10 ; area represented by a patch in km²
let num-patches-in-block (block-area / patch-area)
let side round sqrt num-patches-in-block
if side != sqrt num-patches-in-block [
user-message (word
"Can't make blocks of " block-area " km², since their "
"sides would have to be " sqrt num-patches-in-block ". "
"Using sides of " side " instead, which will give "
"you blocks of " (side ^ 2 * patch-area) " km².")
]
; the rest of the code is similar, expect both `grid-x-inc`
; and `grid-y-inc` are replaced by `side`
ask patches [ set pcolor brown ]
let roads patches with [
(pxcor mod (side + 1) = 0 ) or
(pycor mod (side + 1) = 0 )
]
ask roads [ set pcolor white ]
ask patches with [ pcolor = brown ] [
; sprout square turtles inside blocks
; just to make their size easier to see
sprout 1 [ set shape "square" set color brown - 2]
]
end