I have created a small network consist of nodes which are connected through links.
Some of the nodes are sources and some of the targets. I try to implement Random Walk algorithm.
I place walkers on source nodes, and walkers are moving randomly through the network. Now, I want to check walker reached to targets nodes, if all target nodes are visited by walker then ask walker to stop or die.
I'm new to NetLogo and don't know how to implement this logic.
Any help or guide will be appreciated.
One way to do this is to have your nodes know if they are a target, and if they have been visited. That way, if a turtle visits a node, that node can be marked as having been visited. Then, you can have a stop procedure at the end of your go procedure that checks if any nodes are still present that are a target but have not been visited. I have made slight modifications to the Link-Walking Turtles Example to show one way that you could do this- almost all the code below is directly pulled from that model.
breed [nodes node]
breed [walkers walker]
walkers-own [location]
nodes-own [ target? visited? ]
to setup
clear-all
set-default-shape nodes "circle"
create-nodes 30 [
set color blue
set target? false
set visited? false
]
ask nodes [ create-link-with one-of other nodes ]
repeat 500 [ layout ]
ask nodes [
setxy 0.95 * xcor 0.95 * ycor
]
ask n-of 5 nodes [
set target? true
set color white
]
create-walkers 1 [
set color red
set location one-of nodes
move-to location
]
reset-ticks
end
to layout
layout-spring nodes links 0.5 2 1
end
to go
ask links [ set thickness 0 ]
ask walkers [
let new-location one-of [link-neighbors] of location
move-to new-location
set location new-location
;; This gets turtles to ask their current location
;; to set visited and target to true.
ask location [
set visited? true
if target? = true [
set color red
]
]
]
;; Check for target nodes that have NOT been visited.
;; If there aren't any, stop the model.
if not any? nodes with [ target? = true and visited? = false ] [
print ("All target nodes have been visited.")
stop
]
tick
end
Related
We're creating code and we're having trouble doing the following:
We would like to create a specific number of turtles (for example 100 turtles) based on the following criteria:
distance between agents must be greater than or equal to 2
We've already tried:
to setup
ask n-of 100 patches [
if not any? turtles in-radius 2 [
sprout-turtles 1 [ setup-turtles ] ]
]
]
end
to setup-turtles
set energy 0
set size 1
set color orange
end
it didn't work, because less than 100 agents are being born even though the world holds the required amount of agents, which in this case is 100
Does anyone have any suggestions on how we can resolve this issue?
Thanks in advance
The approach you outline is running into issues because you are asking patches to sprout turtles if they meet some condition. Because the patches are operating in a random sequential order, you are selecting some patches that, by the time it is their turn to act, no longer fulfill the condition to sprout since other nearby patches have already sprouted a nearby turtle.
One option is to use a while loop to keep trying to sprout turtles until the desired number is reached:
to setup
ca
while [ count turtles < 100 ] [
ask one-of patches with [ not any? turtles in-radius 2 ] [
sprout 1
]
]
reset-ticks
end
Be careful with while loops- if you do not code such that the while condition can eventually become false, your model will run forever stuck in the loop.
Another option that will give a more explicit error if it fails would be to just create your number of turtles, then have them move to a space that fulfills the condition:
to setup-2
ca
crt 100 [
move-to one-of patches with [ not any? turtles in-radius 2 ]
]
reset-ticks
end
I have a network of nodes connected by links. Agents move randomly around this network, i.e they have an equal probability of going backwards and forwards. Here is my code to move the turtles to a random nearby node:
to start-movement
let nearest-node min-one-of nodes [distance myself]
set wlocation nearest-node
move-to wlocation
end
to move
ask walkers
[
set prevlocation wlocation
if any? [link-neighbors] of wlocation [
let new-location one-of [link-neighbors] of wlocation
move-to new-location
set wlocation new-location
]
]
end
When a turtle moves to a node, I would like to check where they came from, then with some probability move them to another node that is not the previous one. For example they move from node 1 to node 2. Node 3 is to the right, node 4 straight and node 5 to the right. I would like something like 'if turtle is on node 2, move to node 3 with p=x, node 4 with p=y, or node 5 with p=z.
Could I do this by accessing the who variable of wlocation and prevlocation?
I think you want something like this. It's unclear how you want to choose the probability values for selecting the next location, so I have done something that favours heading 'up'. To make it clear that nodes and walkers are different types of turtles, I have added explicit breed statements that I assume you have in your code. This is not tested or syntax checked.
The trick is to work out the possible next places to go BEFORE changing the value of prevlocation to the current location. Then you can exclude it from the agentset of potential next places.
breed [nodes node]
breed [walkers walker]
walkers-own [prevlocation wlocation]
to start-movement ; walker procedure
set wlocation min-one-of nodes [distance myself]
move-to wlocation
end
to move
ask walkers
[ let targets ([link-neighbors] of wlocation) with [self != [prevlocation] of myself]
set prevlocation wlocation
if any? targets
[ set wlocation ifelse-value random-float 1 < 0.3
[ max-one-of targets [y-cor] ]
[ one-of targets ]
move-to wlocation
]
]
end
I have set up agents and nodes to represent people and stores and it is my intention that the agents will "target" the store in their "awareness" space with the highest value ("vulnerability"). I've largely coded what I have so far through trial and error however setting the turtle's target to the patch with the highest value within a 10 unit radius is a hurdle I can't get over. Currently they target the patch with the highest value regardless of its position in the world. Could somebody suggest what I might consider to achieve this please? I have pasted what I have written so far for reference.
Thanks.
breed [shoplifters a-shoplifter]
patches-own [vulnerability]
shoplifters-own [target
awareness]
to setup
clear-all
setup-patches
setup-turtles
reset-ticks
end
to setup-patches
setup-stores
end
to setup-stores
ask n-of num-stores patches [ set pcolor lime ] ;; create 'num-stores' randomly
ask patches [
if pcolor = lime
[ set vulnerability random 100
]
]
end
to setup-turtles
setup-shoplifters
setup-target
end
to setup-shoplifters
create-shoplifters num-shoplifters [ ;; create 'num-turtles' shoplifters randomly
set xcor random-xcor
set ycor random-ycor
set shape "person"
set color red
]
end
to setup-awareness
ask turtles [
set awareness
patches in-radius 10
]
end
to setup-target
ask turtles [
set target
max-one-of patches [vulnerability]
]
end
You are on the right track using max-one-of. At the moment, however, you are sending patches as the space to search through to look for the one with maximum vulnerability value, when you really want patches in-radius 10. So you could simply do this:
to setup-target
ask turtles [
set target max-one-of patches in-radius 10 [vulnerability]
]
end
However, this is going to be inefficient because NetLogo will have to first work out which are the patches within the radius. You have already asked the turtles to work this out and assign it to their variable 'awareness'. What you really want to do is therefore:
to setup-target
ask shoplifters [
set target max-one-of patches awareness [vulnerability]
]
end
Note that I also changed ask turtles to ask shoplifters. It is only shoplifters who have the attribute 'target' so you should only be asking them to calculate it. Same thing goes for 'awareness'. At the moment you don't have any other breeds so it's not causing an error, but it is good practice to use the breed, otherwise there is no point in creating it.
I am trying to move my agents from one vertex of my road network to another one which the following code. However, I got an error, saying that MOVE-TO expected input to be an agent but got NOBODY instead.
If new location is already defined which this code as part of the agentset of slocation, where is the problem?
to go
ask citizens [start-movement]
move
end
to start-movement
let nearest-node min-one-of nodes [distance myself]
set slocation nearest-node
move-to slocation
end
to move
ask citizens
[let new-location one-of [link-neighbors] of slocation
move-to new-location
set slocation new-location]
end
Here is a complete minimum working example copying your code and adding the setup and breed information required to make it run.
breed [ citizens citizen ]
citizens-own [slocation]
breed [ nodes node ]
to setup
clear-all
create-nodes 20 [ set color blue setxy random-xcor random-ycor ]
ask nodes [ create-links-with n-of 2 other nodes ]
create-citizens 1 [ set size 3 set color red ]
end
to go
ask citizens [start-movement]
move
end
to start-movement
let nearest-node min-one-of nodes [distance myself]
set slocation nearest-node
move-to slocation
end
to move
ask citizens
[ let new-location one-of [link-neighbors] of slocation
move-to new-location
set slocation new-location
]
end
This works fine. As I suggested in my comment, the most likely problem is that one of your citizens happened to start at a node without any link-neighbors. The way to check this is show count nodes with [not any? link-neighbors]. The error is saying that it couldn't find any agents in the set of link-neighbors.
If the nodes are only there to mark roads, then simply delete any that aren't marking roads. If there are other nodes as well, then you need to restrict your citizens to nodes that are road waypoints.
We try to show a simple infection via Netlogo. For our purpose we need to start the infection with the same turtle for several times.
But right now with every setup another turtle begins with the infection. We already tried to work with the Node ID, but unfortunately the ID of the different turtles changes with every setup, too. We are out of ideas but
maybe there is a way to sove this problem I am happy for any answers :)
This is our Code so far:
extensions [nw]
globals
[
num-informed
informed-size
]
turtles-own
[
informed?
]
to setup
clear-all
nw:load-graphml "JK_nachnamen.graphml"
ask turtles [ set size 1.5 ]
layout-radial turtles links turtle 61
ask turtles [set color red]
ask turtles [set shape "dot"]
ask links [set color grey + 1.5]
ask patches [set pcolor white]
ask turtles [set label-color black]
ask turtles [set informed? false]
ask turtle 72
[
set informed? true
set color green
]
set num-informed 1
set informed-size 2
reset-ticks
nw:save-graphml "JKnachnamennetlogo.graphml"
end
to spread
if (count turtles with [informed? = true] > .7 * count turtles) [stop]
ask turtles with [ informed? = true ]
[
ask link-neighbors with [not informed?]
[
if (random-float 1 <= 0.01)
[
set informed? true
show-turtle
set color green
]
]
]
set num-informed count turtles with [informed? = true]
tick
end
Thank you a lot.
I am a little unclear so am giving bits of different answers for different situations.
If the turtles are different each time, what do you mean by 'the same turtle'. For example, do you mean the turtle in a particular position? If so, you could select the turtle on the appropriate patch.
If it doesn't matter which particular turtle it is (just that it's the same turtle), then the simplest approach is to set the random-seed. Then every time you run any random process (including choosing one-of the turtles to select the starting infection, or ask turtles to do something), NetLogo will use the same chain of random numbers. Of course, if you are still building your model, then adding new pieces of code that change how many calls are made to the random number generator will lead to a different chain, but rerunning with the same code will give the identical run.
You may need to use with-local-randomness and random-seed new-seed if you want to have some parts actually change.
The problem is that nw does not store the WHO variable this is to avoid conflict with already existing turtles in a model.
A work-around would be assigning each turtle a separate id variable and setting that to who.
turtles-own [informed? id]
in turtles creation asign them each the id thus
set id who
you may want to write a conversion procedure like this
to convert
nw:load-graphml "JK_nachnamen.graphml"
ask turtles [set id who]
nw:save-graphml file-name "JK_nachnamen(id).graphml"
end
and use the copy. Of course you would not use
turtle 74
but
one-of turtles with [id = 74]