TSP heuristics

No preview image

1 collaborator

Default-person Shrinidhi KR KR (Author)

Tags

(This model has yet to be categorized with any tags)
Visible to everyone | Changeable by everyone
Model was written in NetLogo 5.0.4 • Viewed 121 times • Downloaded 12 times • Run 0 times
Download the 'TSP heuristics' modelDownload this modelEmbed this model

Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)


Info tab cannot be displayed because of an encoding error

Comments and Questions

Please start the discussion about this model! (You'll first need to log in.)

Click to Run Model

;;
globals [k-unfeasible cn-failed-ants cn-lambda-invocations]
breed [handlers a-handler]
breed [nodes a-city]
breed [ants an-ant]
breed [tellers a-teller]
undirected-link-breed [arcs an-arc]
arcs-own    [dm-distance dm-pheromone]
patches-own [dm-zone]
turtles-own [dm-arrival dm-departure dm-cohort]
handlers-own [lambda-event dm-severity dm-next-event ]
ants-own     [lambda-andon  dm-tabu-list dm-best-next-arc dm-last-arc]
nodes-own    [dm-node]
tellers-own  [dm-input]
;;

to setup
  clear-all
  carefully [
    set-default-shape handlers "flag" 
    set-default-shape nodes "circle" 
    set-default-shape ants "sheep" 
    set-default-shape tellers "person"
    ask patches [set dm-zone "geography"]
    ask patches with [11 < pycor]  [set pcolor cyan set dm-zone "FEL"]
    ask patches with [pxcor < -11] [set pcolor gray set dm-zone "arrival"]
    ask patches with [pxcor < -11 and 0 < pycor] [set pcolor turquoise set dm-zone "departure"]
    mt-data-entry
    mt-tour-construction
    reset-ticks
    eh-schedule-event "trigger-arcs" 1  task [eh-trigger-evaporation false]
    eh-schedule-event "trigger-ants" 2  task [eh-trigger-ants ]
    show (word " info! ---------------------------  TRAVEL SALESPERSON ANT COLONY OPTIMIZATION STARTS ... ---------------------------- nodes: "  rpt-full-network-list)
    mt-feedback-dataentry
    mt-label-habitat 
  ] [eh-catch "observer" 0 "setup" error-message ]
end 
;;

to go
  carefully [
    if any? handlers with [member? "HALT!" dm-cohort]     [error (word " HALT! order accepted by observer!")]
    if any? handlers with [member? "exch"  dm-cohort]     [error (word " there are reported bugs in the system!")]
    let lv-lane patches with ["FEL" = dm-zone]
    let lv-dead-events (handlers-on patches with ["arrival" = dm-zone]) with [member? "event-" dm-cohort]
    if bu-verify-mode? [show (word  rpt-display-cron   " DEBUG! "  count lv-dead-events  " dead events will now be moved to departure zone.") ]
    ask  lv-dead-events [
      if (ticks < dm-next-event ) [error (word self dm-cohort " in arrival before due " dm-next-event)]
      set dm-departure ticks
      set color violet
      move-to one-of patches with ["departure" = dm-zone]
    ]
    let lv-due-events (handlers-on lv-lane) with [(member? "event-" dm-cohort) and (dm-next-event <= ticks )]
    if bu-verify-mode? [show (word  rpt-display-cron   " DEBUG! "  count lv-due-events  " due events will run now  their lambda. ") ]
    ask lv-due-events [
      set dm-departure ticks
      move-to one-of patches with ["arrival" = dm-zone]
      set color green
      run lambda-event
    ]
    ask arcs [
      set thickness 1.0 - exp ( -1 *  dm-pheromone)
    ]
    update-plots
    tick-advance rpt-adv-cron
  ]  [eh-catch "observer" ticks "go" error-message  stop]  
end 
;;

to eh-catch [#who #when #where #issue]
  show (word " -------------------  system interrupted by "  #who  " at tick " #when " where? " #where " -----------------------------------------------")
  ask one-of patches with ["arrival" = dm-zone] [
    sprout-handlers 1 [
      set dm-cohort ifelse-value (member? "HALT!" #issue) ["HALT!"] ["exch"]
      set shape ifelse-value (member? "HALT!" #issue) ["flag"] ["bug"]
      set dm-arrival #when
      set color ifelse-value (member? "HALT!" #issue) [blue] [violet]
      set size 2
      set dm-severity ifelse-value (member? "HALT!" #issue) ["warning!"]  ["PANIC!"]
      set label (word dm-severity " – "  #issue)
      watch-me
      show (word dm-cohort " – " dm-severity " message: " #issue)
    ]
  ]
end 
;;

to eh-schedule-event [#tag #when  #lambda]
  ask one-of patches with ["FEL" = dm-zone] [
    sprout-handlers 1 [
      set dm-cohort (word "event-" #tag)
      set dm-arrival ticks
      set dm-next-event #when
      set color blue
      set size 1.5
      set dm-severity "info!"
      set label (word dm-cohort "@" precision dm-next-event 1)
      if not is-command-task? #lambda [error (word self dm-cohort " expected a lambda when scheduling event! found :" #lambda)]
      set lambda-event #lambda
    ]
  ]
end 
;;

to eh-trigger-ants
  carefully [
    if not (is-a-handler? self  and member? "event-" dm-cohort)  [error (word self label " was expected to be an event handler!" ) ]
    if not any? ants [error (word "HALT!  there are no ants to continue exploring solutions!")]
    if bu-verify-mode? [show (word rpt-display-cron label " DEBUG! event lambda runs trigger event acceptor for ants.")]
    ifelse  0 < count ants with ["successful" != dm-cohort] [
      eh-schedule-event "trigger-ants" (2 + ticks) task [eh-trigger-ants ]
      ask ants [
        let k-prob-genchi-genbutsu 0.10
        if (rpt-roulette? k-prob-genchi-genbutsu) [mt-audit-city-of-ant self]
        set cn-lambda-invocations ( 1 + cn-lambda-invocations) 
        run lambda-andon
      ]
    ] [eh-schedule-event "trigger-halt" (1 + ticks) task [eh-trigger-halt ]]
  ]  [eh-catch self ticks "trigger event acceptor for ants" error-message ] 
end 
;;

to eh-trigger-halt
  carefully [
    if not (is-a-handler? self  and member? "event-" dm-cohort)  [error (word self label " was expected to be an event handler!" ) ]
    ask ants with ["star" = shape] [set size 1]
    ask min-one-of ants [rpt-my-tour-distance]  [
      show (word label rpt-display-cron dm-cohort " info!  EUREKA: I am an OPTIMAL solution for this problem: " dm-tabu-list " total tour TSP distance:" rpt-my-tour-distance)
      foreach dm-tabu-list [
        show (word " --> " rpt-display-city ? " distance to next city: " rpt-distance-to-next-node ? )
      ]
      set label "*"
      set size 2
    ]
    error (word " HALT! order received!")
  ]  [eh-catch self ticks "trigger HALT! acceptor" error-message ] 
end 
;;

to eh-trigger-evaporation [#mode]
  carefully [
    if not (is-boolean? #mode) [error (word #mode " expected boolean!")]
    if not (is-a-handler? self  and member? "event-" dm-cohort)  [error (word self label " was expected to be an event handler!" ) ]
    if bu-verify-mode? [show (word rpt-display-cron label " DEBUG! event lambda runs trigger event acceptor for ARCS.")]
    eh-schedule-event "trigger-ARCS" (2 + ticks)  task [eh-trigger-evaporation not #mode]
    ask arcs [ ifelse #mode [ mt-pheromone-evaporation] [set color yellow] ]
  ]  [eh-catch self ticks "trigger event acceptor for ARCS" error-message ] 
end 
;;

to mt-pheromone-evaporation
  carefully [
    if not (is-an-arc? self)  [error (word self label " was expected to be an arc so to evaporate pheromone!" ) ]
    set dm-pheromone (1 - bu-rho) * dm-pheromone
    if bu-verify-mode? [show (word rpt-display-cron label " DEBUG! pheromone after evaporation: " dm-pheromone)]
    set color green
  ]  [eh-catch self ticks "arc evaporates pheromone" error-message ] 
end 
;;

to pm-ant-failed-tour
  carefully [
    if not is-an-ant? self [error (word self label " is expected to be an ant!" ) ]
    set color red
    set cn-failed-ants (1 + cn-failed-ants)
    show (word rpt-display-cron rpt-display-self " warning! my tour " dm-tabu-list " has failed; there are some nodes not visited and no arcs to continue... total failed ants:" cn-failed-ants)
    die
  ]  [eh-catch self ticks "ant failed tour" error-message ] 
end 
;;

to pm-ant-sucessful-tour
  carefully [
    if not is-an-ant? self [error (word self label " is expected to be an ant!" ) ]
    set color green
    set size 2
    set dm-cohort "successful"
    set shape "star"
    mt-deposit-pheromone  self
    set lambda-andon task []
    show (word rpt-display-cron rpt-display-self " info!  EUREKA: I have completed a TSP tour " dm-tabu-list " to visit all cities; distance: " rpt-my-tour-distance)
  ]  [eh-catch self ticks "ant successful tour" error-message ] 
end 
;;

to pm-try-close-tour
  carefully [
    if not is-an-ant? self [error (word self label " is expected to be an ant!" ) ]
    set dm-last-arc rpt-arc  last dm-tabu-list first dm-tabu-list
    ifelse nobody = dm-last-arc [ set lambda-andon task [pm-ant-failed-tour] ]  
                                [ set lambda-andon task [pm-ant-sucessful-tour] ]
    set color green
  ]  [eh-catch self ticks "ant tries to close tour" error-message ] 
end 
;;

to pm-check-tour
  carefully [
    if not is-an-ant? self [error (word self label " is expected to be an ant!" ) ]
    set color orange
    ifelse rpt-quasi-complete-tour? self [
      show (word rpt-display-cron rpt-display-self " info! my tour is  almost complete " dm-tabu-list "; just need to go back to origin.")
      set lambda-andon task [pm-try-close-tour]
    ] [
      set lambda-andon task [pm-ant-failed-tour]
    ]
  ]  [eh-catch self ticks "ant checks her tour complete?" error-message ] 
end 
;;

to pm-arrival-at-city
  carefully [
    if not is-an-ant? self             [error (word self label " subject arriving at the end of one must must be an ANT!" ) ]
    set color blue
    set dm-tabu-list lput [dm-node] of (rpt-next-node-using-best-arc self) dm-tabu-list
    move-to one-of nodes with [last [dm-tabu-list] of myself = dm-node] 
    set lambda-andon task [pm-pheromone-trail]
    show (word rpt-display-cron rpt-display-self " info! ant arrival at " rpt-display-city patch-here " tabu list:"  dm-tabu-list " tour distance:" rpt-tour-distance self)
  ]  [eh-catch self ticks "ant arrives to node" error-message ] 
end 
;;

to pm-visit-arc 
  carefully [
    if not is-an-ant? self             [error (word self label " subject of the arc visit  must be an ant!" ) ]
    set color green
    if ticks >= dm-departure [
      set lambda-andon task [pm-arrival-at-city]
    ]
  ]  [eh-catch self ticks "ant visiting arc" error-message ] 
end 
;;

to pm-pheromone-trail
  carefully [
    if not is-an-ant? self [error (word self label " is expected to be an ant to update its pheromone trail!" ) ]
    set color yellow
    set dm-best-next-arc nobody
    let tb-my-next-arcs rpt-feasible-arcs-for  self
    ifelse  (empty? tb-my-next-arcs) [ 
      set lambda-andon task [pm-check-tour] 
      show (word rpt-display-cron rpt-display-self " info! no more feasible arcs found! my tabu: " dm-tabu-list " now ant will check if she can arrive to origin and get a full tour.")
    ] [
       set dm-best-next-arc rpt-select-arc tb-my-next-arcs
       set lambda-andon task [pm-visit-arc ]  set dm-departure (ticks + rpt-walk-duration dm-best-next-arc)
       show (word rpt-display-cron rpt-display-self " info! ant starts walking " rpt-display-arc dm-best-next-arc " and will arrive  next city at " dm-departure)
    ]
  ]  [watch-me set size 4 eh-catch self ticks "update ants pheromone trail" error-message ]  
end 
;;

to  mt-deposit-pheromone [#ant]
  if not is-an-ant? #ant [error (word #ant " only ants can pour pheromome over arcs!")]
  ask #ant [
    let tb-arcs rpt-getter-tour #ant
    if not rpt-audit-are-arcs-connected? tb-arcs [error (word #ant " corrupted tour!  arcs " tb-arcs " do not make a chain." )]
    foreach tb-arcs [
      ask ? [ set dm-pheromone ((1 / rpt-tour-distance myself) + dm-pheromone)] 
    ]
    show (word rpt-display-cron rpt-display-self " info!  pour some pheromone on travelled arcs; overall pheromone level : " sum [dm-pheromone] of arcs)  
  ]
end 
;;

to  mt-audit-city-of-ant [#ant]
  if not is-an-ant? #ant [error (word #ant " was expected to be an ant when randomly auditing that she is currently placed upon a city-node!")] 
  let lv-city rpt-current-city-of-ant #ant
  if nobody = lv-city [error (word #ant " violates the rule that she must be placed upon a city!")]
  if [dm-node] of lv-city != last [dm-tabu-list] of #ant [
    error (word #ant " tabu list " dm-tabu-list " last item should match node number " [dm-node] of lv-city " of the city " [label] of lv-city " where ant is now!")
  ]
  if bu-verify-mode? [show (word rpt-display-cron rpt-display-ant #ant " DEBUG!  pass AUDIT; placed upon node " rpt-display-city lv-city)]
end 
;;

to mt-link [#destination #distance]
  if not is-a-city? #destination  [error (word #destination  label  " was expected to be a destination node!")]
  ask #destination [
    if bu-verify-mode? [show (word label  " DEBUG! distance " #distance " from node# " [label] of myself) ]
    if (k-unfeasible <= #distance)   [show (word label " Warning! this arc with " [label] of myself " is defined as non-feasible! Not created." )  stop]
    create-an-arc-with myself [
      set dm-distance #distance
      set dm-pheromone (1 / dm-distance)
      set label precision dm-distance 1 
    ]
  ] 
end 
;;

to  mt-create-arcs [#nodes #arcs]
  if not is-a-city? self [error (word self label " was expected to be a node!")]
  let tb-destinations n-values dm-node [?] 
  if bu-verify-mode? [show (word label " DEBUG! creating arcs from node# " dm-node " with nodes " tb-destinations) ]
  foreach tb-destinations [
    let lv-destination one-of nodes with [dm-node = ?]
    let lv-distance ifelse-value  ("non-FAT" = bu-fat)  [ rpt-input (word " enter distance (or \"NA\" for no-arc) from " label " to node# " ?) task [rpt-valid-distance?] ]  [ (item ? #arcs)]                                                    
    mt-link lv-destination lv-distance
  ]
end 
;;

to  mt-create-city [#index #nodes #arcs]
  if not is-list? #arcs  [error (word #arcs " is expected to be a list of distances between this city and its predecessors!")]
  if not is-list? #nodes [error (word #nodes " is expected to be a list of cities!")]
  if not (0 <= #index and #index <= length #nodes) [error (word #index " is an invalid subscriptor for " #nodes)]
  ask one-of patches with ["geography" = dm-zone] [
    sprout-nodes 1 [
      set dm-node #index
      set dm-cohort item #index #nodes
      set label (word dm-node ":" dm-cohort)
      set color lime
      if "?" =  label  [set label user-input "please enter city name"  ]
      if bu-verify-mode? [show (word  label " DEBUG! creating node " #index  "  of the city's network " #nodes "; distances to predecesors: " #arcs)]
      mt-create-arcs #nodes #arcs
    ]
    ask (patch-set self neighbors)  [set dm-zone "node" set pcolor orange]
  ]
end 
;;

to mt-data-entry
  set k-unfeasible 1E20
  let tb-cities n-values (bu-num-cities)  ["?"]
  let tb-distance n-values (bu-num-cities)  [ (list ) ] 
  if bu-fat = "Wilson-p751" [
    set tb-cities ["NewYork" "Miami" "Dallas" "Chicago"]
    set bu-num-cities length tb-cities
    let lv-row1 (list 1334)
    let lv-row2 (list 1559 1343)
    let lv-row3 (list  809 1397 921)
    set tb-distance (list [] lv-row1 lv-row2 lv-row3)
  ]
  if bu-fat = "Dasgupta" [
    set tb-cities ["origin" "city1" "city2" "city3" "city4" "city5"]
    set bu-num-cities length tb-cities
    let lv-row1 (list 3)
    let lv-row2 (list 3 4)
    let lv-row3 (list k-unfeasible 5 3)
    let lv-row4 (list k-unfeasible 2 6 4 )
    let lv-row5 (list k-unfeasible k-unfeasible k-unfeasible 3 2 )
    set tb-distance (list [] lv-row1 lv-row2 lv-row3 lv-row4 lv-row5)
  ]
  if bu-fat = "—delta" [
    set tb-cities ["O" "A" "B" "C" ]
    set bu-num-cities length tb-cities
    let lv-row1 (list 10)
    let lv-row2 (list k-unfeasible 20)
    let lv-row3 (list k-unfeasible 30 40)
    set tb-distance (list [] lv-row1 lv-row2 lv-row3 )
  ]
  if bu-fat = "acid-TEST" [
    set tb-cities ["O" "A" "B" "C" "D" "E"]
    set bu-num-cities length tb-cities
    let lv-row1 (list 10)
    let lv-row2 (list 20 k-unfeasible)
    let lv-row3 (list 30 k-unfeasible k-unfeasible )
    let lv-row4 (list 40 k-unfeasible k-unfeasible k-unfeasible k-unfeasible )
    let lv-row5 (list 50 k-unfeasible k-unfeasible k-unfeasible k-unfeasible k-unfeasible )
    set tb-distance (list [] lv-row1 lv-row2 lv-row3 lv-row4 lv-row5)
  ]
  if bu-verify-mode? [show (word " DEBUG! now this list of cities: "  tb-cities  " will be created ...")]
  foreach n-values (bu-num-cities)  [?] [
    mt-create-city  ? tb-cities (item ? tb-distance)
  ]
end 
;;

to mt-create-ant-on-node [#node]
  if (not is-a-city? #node)  [error (word #node " was expected to be a city when creating an ant upon it!")]
  ask #node [
    hatch-ants 1 [
      set dm-cohort [label] of myself
      set label ""
      set color blue
      set dm-tabu-list (list [dm-node] of myself) 
      set lambda-andon task [pm-pheromone-trail]
      set dm-last-arc nobody
      set dm-best-next-arc nobody
    ]
  ]
end 
;;

to mt-tour-construction
  set cn-lambda-invocations 0 
  set cn-failed-ants 0
  foreach sort-on [dm-node] nodes [
     repeat bu-popsize-per-node [mt-create-ant-on-node ?]
  ]
end 
;;

to mt-feedback-dataentry
  foreach sort-on [dm-node] nodes [
    ask ? [
      show (word label " info! city " dm-node " has " rpt-count-ants-on self  " ants on here;  and has connections to neighbor cities...")
      ask my-arcs [
        show (word  "     info! has a connection to " [label] of other-end " at distance " dm-distance)
      ]
    ]
    ask one-of ants-on ? [show (word label " info!  my starting node is " first dm-tabu-list  " and my partial tour is "  but-first dm-tabu-list )]
  ]
  show (word " info! ants will travel : "  rpt-velocity  " units of distance during each tick.")
end 
;;

to mt-label-habitat
  ask patches with [member? dm-zone (list "geography" "node" )]  [set dm-zone ""]
  foreach remove-duplicates [dm-zone] of patches [
    ask one-of patches with [rpt-is-patch-inside-zone? ?] [set plabel dm-zone]
  ]
end 
;;

to-report rpt-my-strength [#arc]
  report ([dm-pheromone] of #arc ^ bu-alpha) * ([dm-distance] of #arc ^ (-1 * bu-beta))
end 
;;

to-report rpt-my-prob-arc [#arc]
  if nobody = #arc  [report 0.0]
  if not is-an-ant? self [error (word self " only ants can calculate probability of arcs in her neighbor!")]
  if not (member? #arc rpt-feasible-arcs-for self) [error (word #arc " only feasible arcs can be asked by an ant about probability!")]
  let ac-pheromone  sum map [rpt-my-strength ?]  (rpt-feasible-arcs-for self)
  let lv-prob rpt-my-strength #arc /  ifelse-value (0 < ac-pheromone) [ac-pheromone] [1.0]
  if not (0 <= lv-prob and lv-prob <= 1 ) [error (word self label " probability "  lv-prob " is out of range!")]
  report lv-prob
end 
;;

to-report rpt-count-ants-on [#city]
  if not is-a-city? #city [error (word #city " was expected to be a node!" )]
  report count ants-on ([patch-here] of #city)
end 
;;

to-report rpt-valid-distance?
   if not is-a-teller? self [error (word self " was expected to be a teller who takes care for this distance validation!")]
   if  ("NA" = dm-input) [set dm-input k-unfeasible]
   report rpt-positive-number?
end 
;;

to-report rpt-positive-number? 
  if not is-a-teller? self [error (word self " was expected to be a teller who takes care for a positive number validation!")]
  if not ( (is-number? dm-input) and (0 < dm-input) ) [user-message (word dm-input  " should be a positive number!") report false]
  if k-unfeasible < dm-input [user-message (word dm-input  " too large! amended to upper bound.") set dm-input k-unfeasible]
  report true
end 
;;

to-report rpt-is-string?
  report (is-string? dm-input)
end 
;;

to-report rpt-input [#inquiry #is-valid?]
  if not is-reporter-task? #is-valid?  [error (word #is-valid? " was expected to be a reporter task to validate a data entry!")]  
  ask one-of patches with ["arrival" = dm-zone] [
    sprout-tellers 1 [
      set dm-cohort "teller"
      set label (word dm-cohort " : " #inquiry)
      set color red
      set dm-input read-from-string user-input #inquiry
      if (not runresult #is-valid?)  [die report rpt-input #inquiry #is-valid? ] 
      move-to one-of patches with ["departure" = dm-zone]
    ]
  ]
  report [dm-input] of one-of tellers with [(word dm-cohort " : " #inquiry) = label]
end 
;;

to-report rpt-other-node [#node #arc]
  if (not is-a-city? #node)  [error (word #node " was expected to be a city when finding the other end of " #arc "!")]
  let lv-next-city nobody
  ask #node [
    if (not is-an-arc? #arc)   [error (word #arc " should be an arc when finding other node of " #node)]
    ask #arc [ set lv-next-city other-end ]
  ]
  report lv-next-city
end 
;;

to-report rpt-next-node-using-best-arc [#ant]
  if not is-an-ant? #ant [error (word #ant  " is expected to be an ant when trying to move to next city!")]
  report rpt-other-node (rpt-current-city-of-ant #ant) [dm-best-next-arc] of #ant
end 
;;

to-report rpt-my-current-city
  report rpt-current-city-of-ant self
end 
;;

to-report rpt-current-city-of-ant [#ant]
  if not is-an-ant? #ant [error (word #ant  " is expected to be an ant, to determine the city in which she is now!")]
  report one-of nodes-on ([patch-here] of #ant)
end 
;;

to-report rpt-quasi-complete-tour? [#ant]
  if not is-an-ant? #ant            [error  (word #ant " was expected to be an ant when asking whether her tour is ready to complete or not!")] 
  report (sort [dm-node] of nodes) = (sort [dm-tabu-list] of #ant)
end 
;;

to-report rpt-make-chain? [#arc1 #arc2]
  if (not is-an-arc? #arc1) or (not is-an-arc? #arc2) [error (word #arc1 #arc2  " were both expected to be arcs to check if they are inter-connected!")] 
  let tb-nodes []
  foreach  (list #arc1 #arc2) [
    set tb-nodes fput [end2] of ? tb-nodes
    set tb-nodes fput [end1] of ? tb-nodes
  ]
  if (4 !=  length tb-nodes) [error (word #arc1 #arc2 " together they must have 4 nodes!  but got  " length tb-nodes )] 
  let tb-trajectory remove-duplicates tb-nodes
  report (length tb-trajectory < length tb-nodes)
end 
;;

to-report rpt-audit-are-arcs-connected? [#arcs]
  if not is-list? #arcs [error (word #arcs " expected to be a list of arcs, when checking if they are connected as in a chain!")]
  if (length #arcs <= 1) [report true]
  report reduce [?1 and ?2 ] (map [rpt-make-chain? ?1 ?2]  but-last #arcs but-first #arcs)
end 
;;

to-report rpt-getter-tour [#ant]
  if not is-an-ant? #ant            [error  (word #ant " was expected to be an ant when asking to display her tour!")] 
  let tb-arcs []
  ask #ant [
    set tb-arcs  (map [rpt-arc ?1 ?2]  but-last dm-tabu-list but-first dm-tabu-list)
  ]
  report tb-arcs
end 
;;

to-report rpt-is-tabu? [#node #list]
   if (not is-a-city? #node)  [error (word #node " was expected to be a city when checking in a tabu list!")]
   if not (is-list? #list)    [error (word #list " was expected to be a tabu list of nodes.")]
   let sw-member? false
   ask #node [
     set sw-member? (member? dm-node #list)
     if (bu-verify-mode? and rpt-roulette? 0.01) [show (word rpt-display-city #node  " sample DEBUG!  in tabu list " #list  " ? " sw-member?  )] 
   ]
   report sw-member?
end 
;;

to-report rpt-neighbors [#ant]
  if not (is-an-ant? #ant)   [error (word #ant  " argument should be an ant to report its arcs connected to her current node!")]
  report arcs with [member? (rpt-current-city-of-ant #ant) both-ends]
end 
;;

to-report rpt-acum-prob-arcs [#list]
  let ac-prob 0.0
  foreach #list [
    if not (is-an-arc? ?)   [error (word ? " was expected to be an arc when calculating acum prob of a list of arcs!")]  
    set ac-prob (rpt-my-prob-arc ?) + ac-prob
  ] 
  report ac-prob
end 
;;

to-report rpt-select-arc [#list]
  if not (is-an-ant? self)   [error (word self  " was expected to be an ant selecting her next node to visit!")]
  let lv-roulette random-float (rpt-acum-prob-arcs #list)
  if (bu-verify-mode? and rpt-roulette? 0.10)  [show (word rpt-display-cron rpt-display-self " sample DEBUG! selecting next arc, using roulette: " lv-roulette " arcs:" length #list) ]
  let ac-prob 0.0
  foreach #list [
    set ac-prob (rpt-my-prob-arc ?) + ac-prob
    if lv-roulette <= ac-prob [
      if bu-verify-mode? [ show (word rpt-display-cron rpt-display-self  " DEBUG! ant selects arc "  rpt-display-arc ?  " roulette:" lv-roulette " acum arcs prob:"  ac-prob ) ]
      report ?
    ]
  ]
  error (word self " fails selecting  among  the list of feasible arcs: " #list)
end 
;;

to-report rpt-feasible-arcs-for  [#ant]
  let lv-feasible-arcs []
  if not (is-an-ant? #ant)  [error (word #ant  " is expected to be an ant when filtering feasible next arcs in her tour!")]
  ask rpt-my-current-city [
    ask   rpt-neighbors #ant [ 
      if not (rpt-is-tabu? other-end [dm-tabu-list] of #ant) [ set lv-feasible-arcs lput self lv-feasible-arcs]
    ]
  ]
  if (bu-verify-mode? and rpt-roulette? 0.05) [
    show (word  rpt-display-cron rpt-display-self " sample DEBUG! finished gathering my feasible arcs " lv-feasible-arcs  " using tabu list " dm-tabu-list)
  ]
  report lv-feasible-arcs
end 
;;

to-report rpt-velocity
  report min [dm-distance] of arcs
end 
;;

to-report rpt-walk-duration [#arc]
  if not is-an-arc? #arc [error (word #arc " was expected to be an arc in order to calculate walk duration at standarized speed!")]
  report ceiling (rpt-distance #arc / rpt-velocity)
end 
;;

to-report rpt-arc [#node-a #node-b]
  let tb-nodes map [one-of nodes with [? = dm-node] ]  (list #node-a #node-b)
  foreach tb-nodes [
    if (nobody = ?)  [show  (word " warning! "  ? " is expected to match a node # when looking for an arc between " #node-a " and " #node-b "!")  report nobody]
  ]
  report  reduce [one-of arcs with [(member? ?1 both-ends) and (member? ?2 both-ends)]] tb-nodes 
end 
;;

to-report rpt-distance-to-next-node [#node]
  if not is-an-ant? self [error (word self " expected to be an ant to calculate distance to next node of " #node)]
  let lv-pos position #node dm-tabu-list
  let lv-next-pos (1 + lv-pos) mod (length dm-tabu-list)
  report rpt-distance-between #node item lv-next-pos dm-tabu-list
end 
;;

to-report rpt-distance-between [#node-a #node-b]
  report rpt-distance (rpt-arc #node-a #node-b)
end 
;;

to-report rpt-distance [#arc]
  if #arc = nobody [report 0.0]
  if not (is-an-arc? #arc)  [error (word #arc " is expected to be an arc so to ask about its distance!")]
  report [dm-distance] of #arc
end 
;;

to-report rpt-tour-distance [#ant]
  if not (is-an-ant? #ant) [error (word #ant " is expected to be an ant so to calculate the tour distance already travelled (my tabu list)!")]
  if empty? [dm-tabu-list] of #ant [report 0.0]
  let tb-distances (map  [rpt-distance-between ?1 ?2 ]  but-last [dm-tabu-list] of #ant   but-first [dm-tabu-list] of #ant )
  report sum tb-distances
end 
;;

to-report rpt-my-tour-distance
  report rpt-distance dm-last-arc + rpt-tour-distance self
end 
;;

to-report rpt-full-network-list
  let tb-node [dm-node] of nodes
  report sort tb-node
end 
;;

to-report rpt-is-patch-inside-zone? [#where]
  if not (is-patch? self) [error (word self " was expected to be a patch!")]
  let tb-zones-around  fput dm-zone [dm-zone] of neighbors
  report reduce [?1 and (#where = ?2)] (fput true tb-zones-around )
end 
;;

to-report rpt-roulette? [#prob]
  report (random-float 1 < #prob)
end 
;;

to-report rpt-adv-cron
  let lv-lane patches with ["FEL" = dm-zone]
  let lv-candidates (handlers-on lv-lane) with [member? "event-" dm-cohort]
  if not (any? lv-candidates) [error (word lv-candidates " Future Event List should not be empty!")]
  let lv-next-due min [dm-next-event] of lv-candidates
  if not (ticks < lv-next-due) [error (word " cron can only move forward! next event scheduled at " lv-next-due)]
  report lv-next-due - ticks
end 
;;

to-report rpt-display-city [#node]
  if is-number? #node [report rpt-display-city one-of nodes with [#node = dm-node] ]
  if is-an-ant? #node [report rpt-display-city (rpt-current-city-of-ant #node)]
  if is-patch? #node  [report rpt-display-city one-of nodes-on #node ]
  if (not is-a-city? #node)  [error (word #node " was expected to be a city when displaying node ID!")]
  report (word " "   [label] of #node " ")
end 
;;

to-report rpt-display-ant [#ant]
  if not is-an-ant? #ant [error (word #ant " was expected to be an ant when asking to display her ID!")] 
  report (word " origin " first [dm-tabu-list] of #ant ":"  [label] of #ant ", ")  
end 
;;

to-report rpt-display-arc [#arc]
  if nobody = #arc [report "nobody"]
  if not is-an-arc? #arc [error (word #arc " expected to be an arc when asking to display its ID!")]
  report (word " arc between " rpt-display-city [end1] of #arc  " and " rpt-display-city [end2] of #arc ", ")
end 
;;

to-report rpt-display-self
  if  is-an-ant? self [report  rpt-display-ant  self]
  if  is-an-arc? self [report  rpt-display-arc  self]
  if  is-a-city? self [report  rpt-display-city self] 
end 
;;

to-report rpt-display-cron
  report (word " CRON " precision ticks 1 ", ")
end 
;;

There is only one version of this model, created almost 5 years ago by Shrinidhi KR KR.

Attached files

No files

This model does not have any ancestors.

This model does not have any descendants.