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

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!

Related

Netlogo Help - neighbors function

I am a beginner with Netlogo and I am attempting to make a simple model so that when an individual is created, it must be placed in a patch that is neighboring the parent (in one of the 8 spaces). I think I need to use the one-of neighbours command and sprout but I am not sure how to do this.
Currently, I have something this in my code:
to birth-death
set npop count turtles
ask turtles [
if random-float 1.0 < dt * r [
set i random-pxcor
set j random-pycor
ask patch i j [set lpop count turtles-here]
if lpop = 0 [
hatch 1 [
set color green
set xcor i
set ycor j
]
]
]
if random-float 1.0 < dt [ die ]
]
end
Which sets a turtle at a random location, but I am not sure what to write so that when an individual is born it knows to select one of the eight neighbors of the parent site to add a new turtle.
You are close. When a turtle is born (created with the hatch command) it is created at the same patch as the parent. So you just need to move it to one of the neighbouring patches from where it already is. Instead of:
hatch 1
[ set color green
set xcor i
set ycor j
]
Use:
hatch 1
[ set color green
move-to one-of neighbors
]

Netlogo Dijkstra algorithm

to-report find-path [ init final ]
ask init [set dist_d 0]
let current init
let p_dij []
set p_dij insert-item 0 p_dij current
show "dij"
while [not (current = final)]
[
ask [neighbors with [pcolor = yellow and not (dist_d = -1)]] of current [set dist_d min (list dist_d (1 + [dist_d] of current))]
ask current [set dist_d -1]
let min_d min [dist_d] of neighbors
set current one-of neighbors with [dist_d = min_d and pcolor = yellow]
set p_dij insert-item (length p_dij - 1) p_dij current
]
ask patches with [pcolor = yellow] [set plabel dist_d set plabel-color red]
report p_dij
end
I'm trying to find the shortest path using Dijkstra's algorithm. There is a problem with the neighbors, every time the program tries to find the next current node, it comes back to init.
This is not a direct answer to your question, and won't help you if you're trying to figure out how to code Dijkstra's algorithm as an exercise for yourself, but if you're just looking for a shortest path, you can always use the nw:path-to from the network extension.
That primitive is actually using Dijkstra's algorithm under the hood.
In order to use it, however, you need an actual network, so you would have to use turtles instead of patches. That's easy to do, however. Supposing you have a turtle breed called nodes, you can put a node on each patch by saying:
ask patches [
sprout-nodes 1 [
set color pcolor ; give the node the same color as the patch
set hidden? true ; hide the node if you prefer not seeing it
]
]
Then you can create links between, say, yellow nodes:
ask nodes with [ color = yellow ] [
create-links-with (nodes-on neighbors) with [ color = yellow ]
]
The path from one yellow node another is then just:
let yellow-nodes nodes with [ color = yellow ]
show [ nw:path-to one-of other yellow-nodes ] of one-of yellow-nodes
If all you want is the distance, you can use nw-distance-to instead.

How to find the distance between two patches?

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

Shortest path between nodes in netlogo using nw extension

I want to find the shortest path between two nodes - slocation and new-location - in a network of links
I have several slocation and new-location. One slocation for each citizen with some age, sex, and other characteristics, and one new-location for each node close to a work building.
I could identify these nodes with colors - see image.
However, I could not identify the shortest path between each slocation (for each citizen) and newlocation.
I got the following error: BUT-FIRST expected input to be a string or list but got the TRUE/FALSE false instead.
when I run these lines of code:
ask slocation
[set path but-first nw:turtles-on-weighted-path-to new-location weight]
Is this because I have several slocation and new-location?
should I introduce and foreach variable to calculate the shortest path for each citizen? I tried already only with one citizen and still this part of the code is not capable to find the path
I think the error is that the nodes slocation and new-location are not connected with a single link. The citizens have to select the shortest path created by links connecting these nodes to reach the new-location. Someone knows how to do this?
Here, it is my other part of the code:
breed [citizens citizen]
breed [nodes node]
links-own [weight]
to go
set-timekeeper
ask citizens
[find-day-activities]
end
to set-timekeeper
tick
if (counter = 2) [set timekeeper 2] ;From 7:00 AM to 9:00 AM
end
to find-day-activities
if (timekeeper = 2) [Do_7AM_9AM]
end
to Do_7AM_9AM
if (sex = 0 and age = 1 and employment = 0 and household-size = 0)
[shortest-distance]
end
to shortest-distance
let slocation min-one-of nodes [distance myself]
ask slocation [set color yellow]
let new-location one-of nodes with-min [distance one-of workbuildings]
ask new-location [set color blue]
ask links [set weight link-length]
let path nobody
ask slocation
[set path but-first nw:turtles-on-weighted-path-to new-location weight]
ask turtle-set path [ set color yellow ]
end
If there is any question about how I create the road network from a shapefile, this is the code:
to make-road-network
clear-links
let first-node nobody
let previous-node nobody
foreach gis:feature-list-of roads [ polyline ->
foreach gis:vertex-lists-of polyline [ segment ->
foreach segment [ coordinate ->
let location gis:location-of coordinate
if not empty? location [
create-nodes 1 [
set color green
set size 1
set xcor item 0 location
set ycor item 1 location
if first-node = nobody [
set first-node self
]
if previous-node != nobody [
create-link-with previous-node
]
set previous-node self
]
]
]
set previous-node nobody
]
]
ask links [set color red
set thickness 1]
end

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