globals [ min-route mean-route max-route margin NORMAL WAITING TOE-TAPPING IMPATIENT ] breed [ sitters sitter ] ;; runners that have found a rallypoint breed [ runners runner ] breed [ lostones lostone ] breed [ rallypoints rallypoint ] rallypoints-own [ capacity load full? ] runners-own [ destination route-length choice ;; which choice of rallypoint is the runner on? impatient? ;; is the runner impatient waittime ;; how long waiting waitlimit ;; time until runner becomes impatient with waiting mood ;; set and used to help set color ] sitters-own [ route-length ] to setup clear-all let rallypoint-count 10 let runner-count 3000 let general-capacity int ( (runner-count / rallypoint-count) ) if choose-destination = "randomly" [ set choose-destination 0 ] if choose-destination = "nearest" [ set choose-destination 1 ] if choose-destination = "nearest-impatient" [ set choose-destination 2 ] setup-moods setup-rallypoints rallypoint-count general-capacity setup-runners runner-count set min-route "waiting" set max-route "waiting" set mean-route "waiting" display end to go if rally-points-move? [ ask rallypoints with [ not full? ] [ let my-sitters sitters-here rt -45 + random-float 90 ifelse can-move? margin [ jump .5 ] [ rt 170 + random-float 20 ] ] ] ask runners [ without-interruption [ go-runner ] ] if not any? runners [ bookkeeping display stop ] tick end to go-runner ;; first, see if the current rallypoint destination is full now ;; of if the runner is tired of waiting if ([full?] of destination) or impatient? [ choose-rallypoint-destination ;; make sure a destination was actually found, of not, become lost if not is-rallypoint? destination [ become-lostone stop ] ] ;; next, see if the runner has arrived at the rallypoint ;; if so, occupy the destination and stop if any? rallypoints-here [ occupy-destination stop ] ;; if this point is reached, runner is still on route to a rallypoint, so head for it face-nowrap destination ;; no crowding--only move if destination is clear of other runners ifelse any? (runners-on patch-ahead 1) with [ self != myself and destination = [destination] of myself] [ runner-wait ] [ runner-take-step ] ;; finally, update appearance for the mood set-color-mood end to setup-rallypoints [ rallypoint-count general-capacity ] set margin world-width * .05 let too-close margin * 2 create-rallypoints rallypoint-count [ set shape "circle" set size 3 set color yellow set full? false set capacity general-capacity set load 0 ;; make sure rally-points are not clumped together let crowded? true while [ crowded? ] [ ;; random location setxy random-pxcor random-pycor ;; see if location is OK set crowded? any? ( ( rallypoints with [ self != myself ] ) in-radius too-close ) OR not ( pxcor > (min-pxcor + margin) and pxcor < (max-pxcor - margin) and pycor > (min-pycor + margin) and pycor < (max-pycor - margin) ) ] ;; (for this number of patches, this works a lot faster ;; than finding a random set of patches that meet the criteria ;; (within margins and not too close to each other) ] end to setup-runners [ runner-count ] ;; make runners, make sure they do not start on a rallypoint create-runners runner-count [ set size 1 set shape "circle" let on-rallypoint? true while [ on-rallypoint? ] [ setxy random-pxcor random-pycor set on-rallypoint? (any? rallypoints-here) ] set choice 0 set impatient? false set waittime 0 set waitlimit wait-limit choose-rallypoint-destination set route-length 0 set mood NORMAL set-color-mood ] end ;; to-report nearest-rallypoint ;; report min-one-of (rallypoints with [ not full? ]) [ distance-nowrap myself ] ;; end to jump-to [ agent ] setxy ([pxcor] of agent) ([pycor] of agent) end to set-color-mood set color blue + 10 * mood end to choose-rallypoint-destination ifelse choose-destination = 0 [ set destination one-of rallypoints with [ not full? ] ][ ifelse choose-destination = 1 [ set destination min-one-of rallypoints with [ not full? ] [ distance-nowrap myself ] ][ ifelse choose-destination = 2 [ let current ifelse-value (impatient?) [ destination ] [ nobody ] set destination min-one-of rallypoints with [ not full? and self != current] [ distance-nowrap myself ] ;; if no new place found, revert to the current destination if destination = nobody [ set destination current set choice choice - 1 ] ][ ;; otherwise... set destination nobody ]]] set choice choice + 1 set impatient? false set waittime 0 set waitlimit wait-limit set mood NORMAL end to bookkeeping set min-route min [ route-length ] of sitters set max-route max [ route-length ] of sitters set mean-route mean [ route-length ] of sitters output-print "Route length results" output-print (word " min-route: " min-route ) output-print (word " max-route: " max-route ) output-print "" output-print (word " mean-route: " mean-route ) end to setup-moods set TOE-TAPPING 7 set IMPATIENT 3 set WAITING 5 set NORMAL 0 end to occupy-destination ;; snap to the center of the destination setxy pxcor pycor ;; ask destination to update its statistics ask destination [ set load load + 1 set full? (load >= capacity) if full? [ set color red set size 5 ] ] ;; finally, become a sitter, and hide set breed sitters hide-turtle end to become-lostone set breed lostones set color red end to runner-take-step jump 1 set color white set route-length route-length + 1 if waittime > 0 [ set waittime waittime - 1 ] set mood NORMAL end to runner-wait ;; path is crowded, wait set mood WAITING if choose-destination = 2 ;; impatient [ set waittime waittime + 1 ifelse waittime > waitlimit [ set mood IMPATIENT if random-float 1.0 < .1 [ set impatient? true ] ] [ if waittime > waitlimit * .5 [ set mood TOE-TAPPING ] ] ] end @#$#@#$#@ GRAPHICS-WINDOW 324 10 736 443 100 100 2.0 1 10 1 1 1 0 0 0 1 -100 100 -100 100 1 1 1 ticks CC-WINDOW 5 457 745 552 Command Center 0 BUTTON 11 58 66 91 NIL setup NIL 1 T OBSERVER NIL NIL NIL NIL BUTTON 11 95 66 128 go ;;slow down\nno-display\ngo\nevery freq [ display ]\n T 1 T OBSERVER NIL NIL NIL NIL BUTTON 11 132 66 165 go 1x go display NIL 1 T OBSERVER NIL NIL NIL NIL MONITOR 121 58 178 103 runners count runners 0 1 11 MONITOR 121 110 178 155 sitters count sitters 0 1 11 OUTPUT 22 266 215 434 12 CHOOSER 11 10 158 55 choose-destination choose-destination 0 "randomly" 1 "nearest" 2 "nearest-impatient" 0 MONITOR 121 161 216 206 spots available sum [ capacity ] of rallypoints 0 1 11 MONITOR 121 213 215 258 spots in use sum [ load ] of rallypoints 0 1 11 SLIDER 15 188 107 221 freq freq 0 1 0 0.05 1 NIL HORIZONTAL SLIDER 16 226 108 259 wait-limit wait-limit 1 1000 991 10 1 NIL HORIZONTAL BUTTON 192 58 264 91 go-fast no-display go T 1 T OBSERVER NIL NIL NIL NIL SWITCH 164 15 301 48 rally-points-move? rally-points-move? 0 1 -1000 @#$#@#$#@ AT SETUP... a number of rallypoints are created a number of runners are created each runner selects a rallypoint according to the selection criteria e.g. the nearest rallypoint EACH TURN... if rallypoint movement is activated, --- rallypoints move half the speed that runners can move runners run to the open rallypoint that meets the selection criteria (randomly, nearest, farest) runners don't move if the way is not clear of other runners heading for the same destination in "nearest-impatient" mode: runners count waittime up each turn they cant move runners count waittime down each turn they can move when waittime exceeds waitlimit, runners become "impatient" impatient runners look for the next-nearest open rallypoint, if any if no other open rallypoints, runners keep waiting if another open rallypoint is found, runners abandon the current rallypoint in favor of the next nearest rallypoint waittime is reset to 0 when a new rallypoint is selected @#$#@#$#@ default true 0 Polygon -7500403 true true 150 5 40 250 150 205 260 250 circle false 0 Circle -7500403 true true 0 0 300 link true 0 Line -7500403 true 150 0 150 300 link direction true 0 Line -7500403 true 150 150 30 225 Line -7500403 true 150 150 270 225 @#$#@#$#@ NetLogo 4.0 @#$#@#$#@ @#$#@#$#@ @#$#@#$#@ @#$#@#$#@ @#$#@#$#@ default 0.0 -0.2 0 0.0 1.0 0.0 1 1.0 0.0 0.2 0 0.0 1.0 link direction true 0 Line -7500403 true 150 150 90 180 Line -7500403 true 150 150 210 180 @#$#@#$#@