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

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.

Related

How can I make the model run?

I am essentially trying to combine elements of the 'Segregation' model and 'Rebellion' model to form a model that is representative of alliance forming.
Here is what I have so far- when I attempt to run it I receive the error: THREATS breed does not own variable ACTIVE?
error while threat 0 running ACTIVE?
called by procedure GO
called by Button 'go'
breed [ agents an-agent]
breed [ threats threat ]
globals [
k ; factor for determining attack probability
threshold ; by how much must D - BS > A to make a state burden share
percent-similar ; on the average, what percent of a turtle's neighbors
; are the same color as that turtle? Likely to ally
percent-unhappy ; what percent of the turtles are unhappy? Or percieve threats?
visualization
]
agents-own [
allied-states ; R, fixed for the agent's lifetime, ranging from 0-1 (inclusive)- for each turtle, indicates whether at least %-similar-wanted percent of
; that turtle's neighbors are the same color as the turtle
perceived-threat ; T, also ranging from 0-1 (inclusive)- how many have a turtle of another color?
active? ; if true, then the agent is actively allied
; if false, then the agent is free-riding
conflict ; how many turns in conflict remain? (if 0, the agent is not in conflict)- sum of previous two variables
total-nearby ; sum of previous two variables
]
patches-own [
neighborhood ; surrounding patches within the vision radius
]
to setup
clear-all
; set globals
set k 2.3
set threshold 0.1
ask patches [
; make background a slightly dark gray
set pcolor gray - 1
; cache patch neighborhoods
set neighborhood patches in-radius vision
]
if initial-threats-density + initial-agent-density > 206 [
user-message (word
"The sum of INITIAL-THREATS-DENSITY and INITIAL-AGENT-DENSITY "
"should not be greater than 206.")
stop
]
; create threats
create-threats round (initial-threats-density * .01 * count patches) [
move-to one-of patches with [ not any? turtles-here ]
display-threats
]
; create agents
create-agents round (initial-agent-density * .01 * count patches) [
move-to one-of patches with [ not any? turtles-here ]
set heading 0
set allied-states random-float 1.0
set perceived-threat random-float 1.0
set active? false
set conflict 0
display-agent
]
; start clock and plot initial state of system
reset-ticks
end
to go
if all? turtles [ active? ] [ stop ]
move-unhappy-turtles
update-turtles
update-globals
tick
end
; unhappy turtles try a new spot
to move-unhappy-turtles
ask turtles with [ not active? ]
[ find-new-spot ]
end
; move until we find an unoccupied spot
to find-new-spot
rt random-float 360
fd random-float 10
if any? other turtles-here [ find-new-spot ] ; keep going until we find an unoccupied patch
move-to patch-here ; move to center of patch
end
to update-turtles
ask turtles [
; in next two lines, we use "neighbors" to test the eight patches
; surrounding the current patch
set allied-states count (turtles-on neighbors) with [ color = [ color ] of myself ]
set perceived-threat count (turtles-on neighbors) with [ color != [ color ] of myself ]
set total-nearby allied-states + perceived-threat
set active? allied-states >= (percent-similar * total-nearby / 100)
; add visualization here
if visualization = "old" [ set shape "default" set size 1.3 ]
if visualization = "square-x" [
ifelse active? [ set shape "square" ] [ set shape "X" ]
]
]
end
to update-globals
let similar-neighbors sum [ allied-states ] of turtles
let total-neighbors sum [ total-nearby ] of turtles
set percent-similar (similar-neighbors / total-neighbors) * 100
set percent-unhappy (count turtles with [ not active? ]) / (count turtles) * 100
; Agents engaged in conflict have the duration reduced at the end of each clock tick
ask agents [ if conflict > 0 [ set conflict conflict - 1 ] ]
; update agent display
ask agents [ display-agent ]
ask threats [ display-threats ]
; advance clock and update plots
tick
end
; AGENT AND THREAT BEHAVIOR
; move to an empty patch
to move ; turtle procedure
if movement? or breed = threats [
; move to a patch in vision; candidate patches are
; empty or contain only jailed agents
let targets neighborhood with [
not any? threats-here and all? agents-here [ conflict > 0 ]
]
if any? targets [ move-to one-of targets ]
]
end
; AGENT BEHAVIOR
to determine-behavior
set active? (burden-sharing - allied-states * estimated-conflict-probability > threshold)
end
to-report burden-sharing
report perceived-threat * (1 - alliance-protection)
end
to-report estimated-conflict-probability
let t count (threats-on neighborhood)
let a 1 + count (agents-on neighborhood) with [ active? ]
; See Info tab for a discussion of the following formula
report 1 - exp (- k * floor (t / a))
end
to alliance
if any? threats [attack]
set active? true
end
; THREAT BEHAVIOR
to attack
if any? (agents-on neighborhood) with [ active? ] [
; arrest suspect
let suspect one-of (agents-on neighborhood) with [ active? ]
move-to suspect ; move to patch of the jailed agent
ask suspect [
set active? false
set conflict random conflict-term
set color pink
]
]
end
; VISUALIZATION OF AGENTS AND COPS
to display-agent ; agent procedure
set color cyan
set shape "triangle"
end
to display-active?
set color pink
set shape "triangle"
end
to display-threats
set color red
set shape "circle 2"
end
The problem is that you have two breeds of turtles, agents and threats, and only agents "own" the variable active?. turtles is a superset of all breeds, so when the all? primitive tries to query the active? variable of literally all turtles, it tries to query active? for threats too, and can't find it. The line should be
if all? agents [ active? ] [ stop ]

NetLogo - turtle to go to the closest concentration of turtles

I would like a turtle to go to the closest patches with most turtles if a threshold of a given variable is met for 5 ticks.
My code is:
to move
let count-tick 5
if var >= 9.5 [
set count-tick count-tick - 1
if count-tick = 0 [
ask turtle [
let nearest-group min-one-of (patches with [sum turtles >= 3] in-radius 3 ) [ distance myself ]
move-to nearest-group ;; go to the biggest crowd near you
ask turtle [ ;; once there do the following
set shape "star"
set color red
]
]
]
]
end
The issue I have is that a) I am unsure how to say the patch with >= 3 turtles closest to you at the given range of 3 (attempted code above) and b) how to say once there, change your shape.
Revised to keep a permanent variable to track whether the variable is high enough 5 times in a row.
turtles-own
[ count-tick
]
; wherever you create the turtles, you need to `set count-tick 5`
to move
ifelse var >= 9.5
[ set count-tick count-tick - 1 ]
[ set count-tick 5 ]
if count-tick = 0
[ let nearest-group min-one-of (patches with [count turtles >= 3] in-radius 3 ) [ distance myself ]
move-to nearest-group ;; go to the biggest crowd near you
set shape "star"
set color red
]
end
First, you are already within an ask turtles code block from the procedure calling this move procedure. So you don't need the additional ask turtles. Look up ask in the NetLogo Dictionary, it iterates through the turtles, running all the code for each turtle in turn.
Second, you need count turtles rather than sum turtles as sum is to add up values.
Note that there is no error checking in this, you may have problems if there are no patches within radius of 3 that have at least 3 turtles.

How to extract a highly linked node from a network

I want to extract a node with highest degree centrality from the network. I don't want to extract a node with max links only. I want to extract the node along with the nodes adjacent to it.
Below is the code. In this code, I have loaded a network using nw extensions.
extensions [nw]
turtles-own [ explored? ]
to setup
ca
crt 25
ask turtles [fd random 15]
load-graph
extract_deg
end
to load-graph
let filename user-file
if (filename != false) [
nw:load-graphml filename [
set shape "circle"
set size 1
]
nw:set-context turtles links
]
end
to extract_deg
let n turtles with [my-links = max [count link-neighbors] of turtles]
ask n [show other turtles network:in-link-radius 1 turtles]
end
to layout
ask turtles [ set size sqrt count my-links ]
layout-spring turtles links 0.5 2 1
ask turtles [
facexy 0 0
fd (distancexy 0 0) / 100 ]
end
The code below will choose one of the nodes with largest degree (just remove one-of if you want all of them), turn it red and make its network neighbours green.
You don't need the expression [my-links = max [count link-neighbors] of turtles], standard NetLogo includes the very useful with-max primitive. However, I think your construction would have worked if you had counted my-links (like let n turtles with [count my-links = max [count link-neighbors] of turtles]). Then you have some syntax errors in the next line (the extension is nw and you don't need the turtles.
to extract_deg
let maxk-set one-of turtles with-max [count my-links]
ask maxk-set
[ set color red
ask other nw:turtles-in-radius 1 [set color green]
]
end

Counting breeds with neighbors (to plot)

I have two breeds: supras and subs.
I'd like to draw two lines:
Number of subs who have neighbors that are supras (divided by total
population of turtles)
Number of supras who have neighbors that
are subs (divided by total population of turtles)
How can I do this? I've tried this:
plot count (subs with [one-of neighbors = supras]) / num-turtles
plot count (supras with [one-of neighbors = subs]) / num-turtles
The number is always 0 for each population, which should not be the case. Here is my code:
breed [supras supra]
breed [subs sub]
turtles-own [age]
subs-own [status]
to setup
clear-all
;; Color the patches so they're easier to see
ask patches [ set pcolor random-float 2 ]
;; 1/2 of num-turtles patches will sprout subs
ask n-of (num-turtles / 2) patches [
if not any? turtles-on patch-set self [
sprout-subs 1
]
]
;; 1/2 of num-turtles patches will sprout supras
ask n-of (num-turtles / 2) patches [
if not any? turtles-on patch-set self [
sprout-supras 1
]
]
;; Set breed colors and own-variables
ask subs [
set color blue
set shape "dot"
set age 0
set status random 10
]
ask supras [
set color pink
set shape "dot"
set age 0
]
reset-ticks
end
to go
ask turtles [
let empty-patches neighbors with [not any? turtles-here]
if any? empty-patches[
let target one-of empty-patches
face target
move-to target
]
]
;; Mating conditions
ask supras [
if any? subs-on neighbors [
;; Mate with highest status sub
mate
]
]
tick
end
to mate
move-to max-one-of subs [status]
end
neighbors returns an agentset of patches, so saying neighbors = supras is not going to get your what you need- no patches are supras or subs. Instead, you want to check if any of the neighbors have any supras-here or subs-here. This worked for me:
plot (count ( subs with [ any? neighbors with [ any? supras-here ] ] ) ) / ( count turtles )
plot (count ( supras with [ any? neighbors with [ any? subs-here ] ] ) ) / ( count turtles )
You will probably want to scale your Y max down to 1 in order to see much.

Optimal Path on a given graph

I am working on a project in netLogo in which i have a random network in which each and every link is assigned a bandwidth. The algorithm chooses a random Source and Destination by itself and after which it has to choose an optimal path between these two.
My question is how to choose the optimal path by exploring all the possible paths.
hereby attaching the sourcecode of my model:
breed[nodes node]
breed[ants ant ]
globals [nodename nodenumbersource nodenumberdestination relaynode dead-network num ]
nodes-own[visited ]
links-own[visit bandwidth]
ants-own
[
distance-gone
distance-to-go
target-node
current-node
]
to cr11
ask nodes with [label = "Source"]
[
set num count (link-neighbors)
]
create-ants num ;num-ants
[
let n one-of nodes with [label = "Source"]
setxy ([xcor] of n) ([ycor]of n)
set current-node n
set color white set size 0.95
set distance-gone 0
set distance-to-go 0
set target-node one-of nodes with [ label = "Relay Node" ] ;nobody
]
end
to face-targets
ask ants ;with [ target-node]; = node 4 ] ;nobody ]
[
let d 0
face (one-of nodes with [ label = "Relay Node" ]);target-node
ask current-node [
set d distance (one-of nodes with [ label = "Relay Node" ]);target-node)
]
set distance-to-go d
]
end
to move-forward
face-targets
ask ants [
while [ distance-gone < (distance-to-go )]
[
fd 1
set distance-gone (distance-gone + 1)
]
]
ask ants [
if distance-gone < distance-to-go
[
set current-node target-node
setxy ([xcor] of current-node) ([ycor] of current-node)
set distance-gone 0
set distance-to-go 0
]
]
end
;This is used to design the Network
to setup
setup1
setup-spatially-clustered-network
ask links [set color white
set visit false
set bandwidth (5 + random 10) ;min bw 5 max 15
]
end
to setup1
__clear-all-and-reset-ticks
set dead-network 0
create-nodes number-of-nodes
[
setxy (random-xcor * 0.95) (random-ycor * 0.95)
set shape "circle"
set color green
set visited false
set label who
]
end
;Links are created for the nodes
to setup-spatially-clustered-network
let num-links (6 * number-of-nodes) / 2
while [count links < num-links ]
[
ask one-of turtles
[
let choice (min-one-of (other turtles with [not link-neighbor? myself])
[distance myself])
if choice != nobody [ create-link-with choice
]
]
]
repeat 10
[
layout-spring turtles links 0.3 (world-width / (sqrt number-of-nodes)) 1
]
end
;This is to Generate Message for nodes
to test1
ask one-of nodes
[
set color red
set label "Source"
set nodenumbersource who
]
ask one-of nodes with [color = green]
[
set color red
set label "Destination"
set nodenumberdestination who
]
cr11
end
to test3
ask turtles with [label = "Source"]
[
set label "ants moving"
ask my-links
[
set color green
]
ask link-neighbors
[
set color blue
]
ask min-one-of turtles with [color = blue and my-links] [distance turtle nodenumberdestination ]
[
ask max-one-of my-links [bandwidth ]
[
set color red
]
set color white
set relaynode who
set label "Relay Node"
]
; face-targets
move-forward
end
to test4
ask turtle nodenumberdestination
[
while [color != white]
[
ask turtle relaynode
[
set label ""
ask my-links
[
set color green
]
ask link-neighbors
[
set color yellow
]
]
ask turtles with [color = yellow]
[
set color violet
]
ask turtles with [color = violet] with [visited = false]
[
set color magenta
]
ask min-one-of turtles with [color = magenta] [distance turtle nodenumberdestination]
[
set color white
set relaynode who
set label "Relay Node"
set visited true
]
move-forward
]
]
end
to test6
ask nodes ; turtles
[
set color green
set visited false
set label ""
]
ask links
[
set color white
set visit false
]
end
to test5
test1
test3
test4
end
You can use the NW-Extension for that! Just download it and stick it in NetLogo's extensions folder. Then, in your model, you can start using by adding
extensions [ nw ]
to the top of your code. Then you can use one of the weighted-path-to primitives to get the turtles or links along the shortest path between two nodes.
Note that the nw extension is under active development, though it is well tested. You also must be using the latest version of NetLogo.
If you want to implement it yourself, Dijkstra's algorithm is the classic solution if you have nonnegative weights in your graph.