1

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

enter image description here

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Alex Tan
  • 51
  • 1
  • 6

1 Answers1

2

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.

enter image description here

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:

enter image description here

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:

enter image description here

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.

Luke C
  • 10,081
  • 1
  • 14
  • 21
  • First of all, i really really appreciate the help. Here's my question since nw:extension is use to find the shortest path , why do you still need to do permutation to build all possible path?? – Alex Tan Apr 24 '18 at 07:28
  • And sorry for the messy code, I am still new to netlogo – Alex Tan Apr 24 '18 at 07:35
  • Well, you could definitely more easily have the walker just pick the closest (by weight) target node and move to that, then pick the next closest target node and move to that, and so on. However, that does not guarantee the shortest path- example image in edit. – Luke C Apr 24 '18 at 20:25
  • So is it the same if i use the start node and find all shortest path to the destination and from there i take the minimum path eg: The first path (turtle0) (turtle4) Second Path (turtle0) (turtle1) (turtle2). I then take the first path and then replace the start node with node4 (turtle4) and continue doing the same. – Alex Tan Apr 26 '18 at 05:37
  • I understand your code and appreciate the help, but i want to try my idea first before using your setup. Thankyouu – Alex Tan Apr 26 '18 at 05:39
  • @AlexTan - Yes, exactly! Just have the turtle select its nearest target, and pathfind using `nw:turtles-on-weighted-path-to` (eg. as in the `follow-path` procedure above). Once they complete that path, select the next nearest, and so on. Just a heads up, I modified some of the code/images so the turtle is assessing least cost (by weight) of the entire path, rather than least distance. – Luke C Apr 26 '18 at 18:01