How to find the distance between two patches? - netlogo

I'm trying to have agents go the most efficient possible route to their destination (randomly selected from a patchset of 10 patches). The problem is, distance seems to be an agent-only command, and the only code I've found that does anything similar seems to work by running the distance command with patches, which gives an error.
This is the troublesome procedure:
to-report best-route
let visible-patches patches in-radius turtles-vision-dist
let visible-routes visible-patches with [ pcolor = gray ]
let routes-that-take-me-closer visible-routes with [
;;THIS IS THE PROBLEM LINE RIGHT BELOW HERE
[ distance visible-routes] of destination < [ distance destination - 1 ] of myself
]
In the example I had found, Paths, this was the code:
to-report best-way-to [ destination ]
let visible-patches patches in-radius walker-vision-dist
let visible-routes visible-patches with [ pcolor = gray ]
let routes-that-take-me-closer visible-routes with [
distance destination < [ distance destination - 1 ] of myself
]
ifelse any? routes-that-take-me-closer [
; from those route patches, choose the one that is the closest to me
report min-one-of routes-that-take-me-closer [ distance self ]
] [
; if there are no nearby routes to my destination
report destination
]
end
I had originally had something more similar, but it wasn't working, so I've been playing around with it with no luck, as have a classmate and my professor.

I can't figure out how your paths algorithm is supposed to work since it doesn't look like you are restricting movement to grey patches. However, assuming your destination is stored as a patch, then you can can calculate distance to that patch directly with distance destination, like this:
turtles-own [ destination ]
to testme
clear-all
create-turtles 1
[ set destination one-of patches
ask destination [ set pcolor blue ]
]
ask one-of turtles
[ print distance destination
]
end

Related

Netlogo NW extension - nw:turtles-on-path-to reverts to first turtle location

I'm new to Netlogo and trying to build a model imported from GIS city plan in which agents ("walkers") find the closest of several set destinations, walk there along the streets, and then return to their "home". I have three breeds: walkers, nodes, and destinations. I've created a network of nodes that are linked on which the walkers move. So far I've only figured out the first step where a single walker finds the closet route to a destination using nw:turtles-on-path-to and then moves towards it. The problem is when I then move the walker to a new location to test whether it can find the closest destination to this new location. It can identify the proper closest destination, but the path reverts back to the walker's original location, and it moves the walker back there when I move them. I cannot figure out why it does this, nor how to fix it.
This is snippet of the setup:
ask patches with [ destination? ]
[ sprout-destinations 1 [
set size 3
set shape "circle"
set color blue
]
]
ask patches with [ street? ]
[ sprout-nodes 1 [
set color pcolor
set size 0.5
set shape "circle"
set color green
]
]
set near-destination nodes-on destinations
create-walkers 1 [
set color red
set size 3
set shape "person"
move-to one-of nodes
set mypath []
if draw-route = true ;; if true, a route will be traced following the leader
[ pen-down ]
ask nodes [
create-links-with turtles-on neighbors [
set color green
]
This is how the route to the closest destination is identified:
to find-nearest-destination
nw:set-context turtles links
set mypath []
ask walkers [
set mynode one-of nodes-on patch-here
set my-destination min-one-of near-destination [
length nw:turtles-on-path-to mynode]]
ask walkers [
set mypath nw:turtles-on-path-to my-destination]
end
And this is how the walkers move towards it:
to go
ask walkers [
if xcor != [xcor] of my-destination or ycor != [ycor] of my-destination[
move-to item 0 mypath
ifelse length mypath > 0
[ set mypath remove-item 0 mypath ]
[ print "at destination" ]
]
end
I thought that by resetting "mypath" before finding the new path it should use the new "mynode" as the starting point, but it somehow always ends up with the first one. mynode and near-destination are global, but mypath and my-destination are owned by the walkers.
Thanks to anybody who can straighten me out!

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!

How can I get Netlogo turtle coordinates which can then be used by the other turtles to navigate them to that turtle?

In netlogo, I have four turtles, one Pacman turtle and 3 ghosts which will attempt to track the Pacman down by using its location that should be reported inside a variable, but I can't understand how to retrieve the Pacman turtle's location and store it in a variable. This variable should be updated with every move the Pacman makes so that the ghosts are attracted to the newest patch location where the Pacman was.
Update: I have used the patch-here command to retrieve the location of the pacman and store it in a global variable called "PacManLocation". Is this correct and if so how can I get my ghost's turtles to go to that specific patch one step at a time? I've tried the forward command writing "forward PacManLocation" but I get an error saying that it expected a numerical input.
Here is the original code:
to PlayGame
ask ghostsOne [
face min-one-of patches with [ pcolor = blue ] [ distance PacManLocation ] forward 0.7
]
ask ghostsTwo [
face min-one-of patches with [ pcolor = blue ] [ distance PacManLocation ] forward 0.7
]
ask ghostsThree [
face min-one-of patches with [ pcolor = blue ] [ distance PacManLocation ] forward 0.7
]
end
This should get you started. (Not tested.)
to PlayGame
;;it is better to make a ghosts breed or at least use a global,
;;but here we stick with what you have
let ghosts (turtle-set ghostsOne ghostsTwo ghostsThree)
ask ghosts [move]
end
to move
if (blue != [pcolor] of patch-ahead 0.7) [
face min-one-of neighbors with [pcolor = blue] [distance PacManLocation]
]
fd 0.7
end

Placing turtles at edges of patch clusters

I'm looking for a way to rapidly place turtles at edges of patch clusters. I tried this code but I found that it is a little slow when I increase the size of my study area:
to draw-edges [ID-cluster]
ask patches with [cluster != ID-cluster] [
ask neighbors with [cluster = ID-cluster] [
if not any? turtles-here [
sprout 1 [
set shape "x" ] ] ] ]
end
Thanks in advance for your help.
You're currently asking the whole world outside your cluster to check for neighbors that are in the cluster. It should be faster to ask patches that are part of your cluster to check if they are next to an outside patch:
to draw-edges [ ID-cluster ]
ask patches with [
cluster = ID-cluster and
any? neighbors with [cluster != ID-cluster] and
not any? turtles-here
] [
sprout 1
set shape "x"
]
end

edge to edge distance between polygons that are situated within a buffer

I would like to calculate edge to edge distance between a polygon in which is situated a turtle and each polygon that is situated in a radius of 2 km around the polygon in which is situated the turtle. The polygons are represented by different IDs and each polygon is composed of several patches. I obtain a error message with the following code "FOREACH expected this input to be a list, but got an agentset instead". I don't understand why "patches with [plabel = ID-polygon])" is not a list ? In fact, I would like to select all patches of which label is equal to label of the polygon.
Thank you for your help.
to-report create-edge-turtles [ID-polygon]
let edge-turtles nobody
ask ID-polygon [
foreach (patches with [plabel = ID-polygon]) [
foreach sort neighbors [
sprout 1 [
if [plabel] of neighbors != ID-polygon [
face ?
fd distance ? / 2
set edge-turtles (turtle-set edge-turtles self)] ] ] ] ]
report edge-turtles
end code here
to-report edge-distance-between-polygons-in-buffer [indvidual]
ask individual [
set list-ID-polygon-in-buffer ([plabel] of patch-here in-radius 2)
set list-ID-polygon-in-buffer remove ([plabel] of patch-here) list-ID-polygon-in-buffer
foreach list-ID-polygon-in-buffer [
let ID-polygon-with-individual ([plabel] of patch-here)
let ID-polygon-in-buffer ?
let edges-polygon-with-individual create-edge-turtles ID-polygon-with-individual
let edges-polygon-in-buffer create-edge-turtles ID-polygon-in_buffer
set distance-patches min [ min [ distance myself ] of edges-polygon-in-buffer ] of edges-polygon-with-individual
ask edges-polygon-with-individual [ die ]
ask edges-polygon-in-buffer [ die ] ] ]
report distance-patches
end
The command
patches with [plabel = ID-polygon]
returns an agentset, not a list. To turn an agentset into list simply use the sort keyword, as such
sort patches with [plabel = ID-polygon]