goal-seeking-boids
Model was written in NetLogo 6.2.0
•
Viewed 249 times
•
Downloaded 75 times
•
Run 0 times
Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)
Comments and Questions
Please start the discussion about this model!
(You'll first need to log in.)
Click to Run Model
;; MODEL NAME: goal-seeking-boids-v2-1py ;; DATE: written 14-Nov-2019 ;; HISTORY: ;; 01-Feb-2011 uploaded first version to modeling commons ;; latest version updated 1-Feb-2021 at 6:28 AM CST (Chicago time zone ) ;; 14-Oct-2021 Modified to allow rerunning random-seed values. ;; Tests for running netlogo-web. If local, allows importing landscape and saving snapshots ;; added "maxwealth" and "stepsize" to turtles-own variables ;; ;; TRANSIENT Work in process ;; * migrate local-gorup-horizon to all instances of everyone, wej ust put it in everyone uphill ;; * correction for angles near 360 has only been applied to every plus uphill case ;; known bugs: ;; * prints stopped when all turtles succeeded twice in output ;; * on stop for everyone, neither of the plots are accurate, and the last 45 or so never are caught ;; * motion can get locked up in a corner ;;============ UN-comment the next line if you are running locally! ================= ; extensions [view2.5d] ;; ================================================================================== globals [ stop-now? ;; stop flag for subroutines to back up to the go command patch-count ;; for this size display on-peak-count ;; number of turtles on the peak peak-height ;; height of highest patch my-center ;; weighted centroid of all the agents, or possibly of VISIBLE nearby agents timestamp ;; updated date-and-time to show on interface, only updated when taking snapshot stop-at-tick ;; stop run when ticks >= stop-at-tick filechoice ;; imported landscape jpg file name, if any ;; global variables defined by the interface controls ;; note - these are NOT cleared by "clear-globals" or "clear-all" ;; =============================================== ;; randomseed ;; ( added 13-Oct-2021 ) ;; number-of-hits ;; turtle-count ;; rule-to-use ;; leave-a-trail? ;; run-title ;; turtle-color ;; turtle-shape ;; landscape-source ;; noise? ;; noise-size ;; noise-density ;; group-weight ;; timestamp ;; braking-pct ( insert a wait X seconds into the end of the go loop for fine tuning) ;;; ============== automater's globals begin ==================== ; working-directory ;; the operating system working directory ; command-file ;; where the commands will be read from ; output-file ;; optional, where output from the go step can be written ; log-file ;; a log of what commands were executed ; run-title ;; whatever you want to name this run ; show-commands-as-run? ;; controls whether you want to see commands as they are run ; use-sample-input-file? ;; if true, generates a file called test-01-input.txt to use ; ;; as input for this model. ; ;; This will destroy an existing file of that name! ;;; ================ automater's globals end ===================== ] turtles-own[ maxwealth ;; maximum wealth turtle has ever seen - 10/13/21 wealth ;; just equal to the pcolor of the patch the turtle is on prior-wealth ;; wealth before this latest step on-peak? old-heading ;; actually exponentially smoothed history of prior headings inertia ;; [0,1], turtle specific, weight of old-heading in updated heading, defaults to zero empathy ;; [0,1] actually misnamed to be shorter, susceptibility to group peer pressure step-size-multiplier ;; 10/13/21 good-step-count ;; counts number of steps with improving height my-heading-uphill ;; before step my-heading-group ;; before step ] patches-own [ height basepcolor ] to setup if ( netlogo-web? = false ) [ print "\n ================================== \n If you get an error that VIEW2.5:PATCH-VIEW is undefined, \n uncomment out the EXTENSION definition in the first line of actual code \n ================================== \n"; ] let mystr88 "Test" if ( netlogo-web? = false ) [ run " view2.5d:patch-view mystr88 [ [the-patch] -> [height] of the-patch ] " run " view2.5d:set-z-scale mystr88 zfactor " ] ;; we persist randomseed across runs by putting the prior value in the "local" variable "oldseed" ;; but if that has never been set, we need to set it as well. clear-all if (reuse-seed? = false ) [ set randomseed ( random 999999 ) ] ;; note, if randomseed is not reset above, the value from the interface input box will persist random-seed randomseed set timestamp date-and-time set stop-now? false ;; no-display ( won't work over the web ! ) if landscape-source = "generated" [make-landscape ] if landscape-source = "imported" [import-landscape] make-turtles ;; display( won't work over the web ! ) set my-center (patch 0 0) ;; weighted centroid of the agents, dynamically updated ;;======================================= automaters commands begin ;; setup-automater ;;======================================= automaters commands end prepare-outputs set stop-at-tick max-ticks ;; stop normally if time is reached ask patches [ set basepcolor pcolor ] ask patches [ ifelse ( count turtles-here > 0 ) [ set pcolor green][set pcolor basepcolor]] reset-ticks end to prepare-outputs ;; called once during setup ;; select external log and output files here, if any ;; write experiment title and date to output area output-print run-title output-print timestamp ;; set at start of run, not output date-and-time ! output-print " " output-print (word "turtle-count: " turtle-count) output-print (word "rule-to-use: " rule-to-use) output-print (word "landscape: " landscape-source) if (landscape-source = "imported") [output-print (word "file: " filechoice)] ;; other experimental settings could be output here output-print " " ;; write column headers to the output area (if-else rule-to-use = "single: wander" [ output-print (word "turtle " " ticks " ) ] rule-to-use = "single: go-uphill" [ output-print (word "turtle " " ticks " ) ] rule-to-use = "single: find-everyone" [ output-print (word "turtle " " ticks " " group-weight: " ) ] rule-to-use = "pair: uphill with inertia" [ output-print (word "turtle " " ticks " " inertia " ) ] rule-to-use = "pair: uphill with everyone" [ output-print (word "turtle " " ticks " " group-weight " ) ] rule-to-use = "triple: use all three" [ output-print (word "turtle " " ticks " " group-weight " " inertia " ) ] ; else commands [ error (word " unexpected rule-to-use choice: " rule-to-use) ] ) end to import-landscape ;; only if local. Won't compile in netlogo-web. ifelse ( netlogo-web? = false ) [ let msg1 "starting runstring" let msg2 " no file selected! " let msg3 "Importing image file " let msg4 " failed, so generating the image locally" let msg5 "generated" let msg6 "You asked to import this landscape file: " let runstring ( word " print msg1 " " set filechoice user-file " " if-else filechoice = false " " [ " " print msg2 " " print (word msg3 user-file msg4) " " set landscape-source msg5 " " make-landscape " " ] " " [ " " print (word msg6 filechoice) " " import-pcolors filechoice " " ask max-one-of patches [pcolor] [set peak-height pcolor] " " ask patches [ set height pcolor] " " ] " ) run runstring ] [ print "Landscapes can only be imported if this model is downloaded and run locally! "] end to trackwho inspect turtle monturtle end to go ask patches [ ifelse ( count turtles-here > 0 ) [ set pcolor green][set pcolor basepcolor]] let mystr88 "Test" if ( netlogo-web? = false ) [ run "view2.5d:set-z-scale mystr88 zfactor" run "view2.5d:update-all-patch-views" ] ;; WARNING -- this will not print final output if stopped by interface if stop-now? [ print "Stop was requested by a subroutine" stop ] if ticks > stop-at-tick [wrap-up-run stop] ;; prevent runaway models from consuming computer time if all? turtles [on-peak?] [ wrap-up-run stop ] move-turtles if stop-now? [ print "Stop was requested by a subroutine." stop ] if stop-now? [ error "stop was requested but failed" ] update-status if braking-pct > 0 [ wait ( braking-pct / 100) ] ;; slowdown despite top master speed switch tick end to wrap-up-run ;; wrap up the entire run ;; this is a place-holder ;; print "any wrapping up will go here", such as writing output to a file if (ticks >= stop-at-tick) [ print (word "stopped at time limit, ticks = " ticks) output-print (word "stopped at time limit, ticks = " ticks) ] if (stop-now?) [ print (word "stopped unexpectedly, ticks = " ticks) output-print (word "stopped unexpectedly, ticks = " ticks) ] if-else (all? turtles [on-peak?]) [ print (word "stopped when all turtles succeeded, ticks = " ticks) output-print (word "stopped when all turtles succeeded, ticks = " ticks) ] [ print ( word "count of turtles not yet on the peak: " count turtles with [on-peak? = false] ) output-print ( word "count of turtles not yet on the peak: " count turtles with [on-peak? = false] ) ] ;; for inertia plot, set the time to 100 and plot the straglers if rule-to-use = "pair: uphill with inertia" [ set-current-plot "inertia-influence" ;;plotxy inertia ticks ask turtles with [on-peak? = false ] [ let cluster-show 98 + random-float 2 plotxy inertia cluster-show ; output-print (word " ? " " " cluster-show ) ] ] ;; for group plot, set the time to 100 and plot the straglers if rule-to-use = "pair: uphill with everyone" [ set-current-plot "social-influence" ask turtles with [on-peak? = false ] [ let cluster-show2 98 + random-float 2 plotxy empathy cluster-show2 ; output-print (word " ? " " " cluster-show2 " " 1.0 " (forced) " ) ] ] end to update-status set on-peak-count count turtles with [on-peak?] ;; ======================================================= automater code begins ;; file-open output-file ;; file-print (word "turtles on peak: " on-peak-count) ;;======================================================== automater code ends end to-report local-group-center ;; for each agent, vision limited by horizon ( or links ? ) ;; side-effect: this sets the global variable my-center let sumx 0 let sumy 0 let sumx-wealth 0 let sumy-wealth 0 let numnearby count turtles with [ (distance myself ) < horizon] print ( word "nearby turtle count " numnearby) ask turtles with [ (distance myself ) < horizon] [ set sumx sumx +(pxcor * wealth) set sumx-wealth sumx-wealth + wealth set sumy sumy +(pycor * wealth) set sumy-wealth sumy-wealth + wealth ] ;; at set-up avoid division by zero if-else ( sumx-wealth > 0 ) [ set sumx sumx / sumx-wealth set sumy sumy / sumy-wealth] [ set sumx 0 set sumy 0 ] ;; put centroid in the center on first pass report (patch sumx sumy) ;report (list sumx sumy) end to-report centroid ;; compute center of the swarm, weighted by wealth ;; side-effect: this sets the global variable my-center let sumx 0 let sumy 0 let sumx-wealth 0 let sumy-wealth 0 ask turtles [ set sumx sumx +(pxcor * wealth) set sumx-wealth sumx-wealth + wealth set sumy sumy +(pycor * wealth) set sumy-wealth sumy-wealth + wealth ] ;; at set-up avoid division by zero if-else ( sumx-wealth > 0 ) [ set sumx sumx / sumx-wealth set sumy sumy / sumy-wealth] [ set sumx 0 set sumy 0 ] ;; put centroid in the center on first pass set my-center (patch sumx sumy) report (list sumx sumy) end ; =========== turtle movement commands =============== to wrap-up-step ;; Utility, called by every rule, in every step, in a turtle context set wealth height ; transfer patch parameter to a turtle parameter ;; This output relies on the various move steps ONLY being called for ;; turtles that were not already at peak height. Otherwise, this ;; will generate way too much output!! if height = peak-height ;; did we just reach the peak? [ set on-peak? true set color green set label "" (if-else rule-to-use = "single: wander" [ output-print (word who " " ticks ) ] rule-to-use = "single: go-uphill" [ output-print (word who " " ticks ) ] rule-to-use = "single: find-everyone" [ output-print (word who " " ticks " " group-weight ) ] rule-to-use = "pair: uphill with inertia" [ output-print (word who " " ticks " " inertia ) set-current-plot "inertia-influence" set-current-plot-pen "default" plotxy inertia ticks ] rule-to-use = "pair: uphill with everyone" [ output-print (word who " " ticks " " group-weight ) set-current-plot "social-influence" set-current-plot-pen "default" plotxy empathy ticks ] rule-to-use = "triple: use all three" [ output-print (word who " " ticks " " group-weight " " inertia ) set-current-plot "inertia-influence" set-current-plot-pen "default" plotxy inertia ticks set-current-plot "social-influence" set-current-plot-pen "default" plotxy empathy ticks ] ; else commands [ error (word " unexpected rule-to-use choice: " rule-to-use) ] ) ] end to go-wander ask turtles with [not on-peak?] [ set heading heading + random 45 set heading heading - random 45 step-or-reverse ( 1 ) ;;set wealth height wrap-up-step ] end to step-or-reverse [ size-of-step ] set prior-wealth height if-else can-move? size-of-step [forward (size-of-step * step-size-multiplier)][ set heading heading + 180 forward ( size-of-step * step-size-multiplier) ] ifelse ( dynamic-speed? = true ) [ ;; following variable step-size control is experimental 14-Oct-2021 set wealth height if ( wealth > maxwealth) [ set maxwealth wealth ] ifelse ( wealth > prior-wealth ) [ if ( good-step-count < 0) [set good-step-count 0] set good-step-count ( good-step-count + 1 ) ] [ if ( good-step-count > 0) [set good-step-count 0] set good-step-count ( good-step-count - 1 ) ] set step-size-multiplier ( 1 + ( good-step-count / 5 ) ) if ( step-size-multiplier > 5 ) [ set step-size-multiplier 5] if ( step-size-multiplier < 0.2) [ set step-size-multiplier 0.2 ] ] [ set step-size-multiplier 1 ] end to-report uphill-heading ;; heading is in degrees , 0 to 360 ;; hard-codes a search radius let search-radius 2.5 ;; ask turtles with [not on-peak?] [ let old-patch patch-here let neighborhood patches with [ distance myself < search-radius ] let target max-one-of neighborhood [height ] face target ;; WARNING -- side-effect report heading ;; ] end to go-uphill ;; hard-codes a step size let step-size 1 ask turtles with [not on-peak?] [ set heading uphill-heading step-or-reverse ( 1 ) wrap-up-step ] end to go-find-everyone ;; centroid and my-center needs to be refactored ;; first, comput the weighted centroid of all the turtles let new-centroid (list 0 0) set new-centroid centroid ;; sets global my-center as side-effect ;; computes new-centroid but only uses the side effect ;; WARNING -- twisted way of simply setting my-center ask turtles with [not on-peak?] [ ;; let old-patch patch-here ;; obsolete?? face my-center step-or-reverse ( 1 ) wrap-up-step ] end to go-uphill-inertia ;; draft ask turtles with [not on-peak?] [ set label inertia let old-patch patch-here ;; used???? let heading-uphill uphill-heading set heading ( inertia * old-heading) + (1 - inertia) * heading-uphill step-or-reverse ( 1 ) set old-heading heading ;; this is a turtle-own variable wrap-up-step ] end to go-use-all-rules ;; runs but not validated, not even one full walk-through ;; first, compute the weighted centroid of all the turtles let new-centroid (list 0 0) if ticks > 1 [ set new-centroid centroid ] ;; can't run on first tick because weath is zero and get division error ;; type "centroid is " show new-centroid ask turtles with [not on-peak?] [ let old-patch patch-here ;; let's find what heading goes uphill let target max-one-of neighbors [height] face target let heading-uphill heading ;; ok soften that with inertia set heading-uphill ( inertia * old-heading) + (1 - inertia) * heading-uphill set old-heading heading ;; this is a turtle-own variable face my-center let heading-group heading set heading (empathy)*(heading-group) + (1 - empathy)*(heading-uphill) ;; set heading (group-weight)*(heading-group) + (1 - group-weight)*(heading-uphill) step-or-reverse ( 1 ) set old-heading heading ;; this is a turtle-own variable wrap-up-step ] end to go-uphill-everyone ;;draft ;; first, comput the weighted centroid of all the turtles let new-centroid (list 0 0) if ticks > 1 [ set new-centroid centroid ] ;; can't run on first tick because weath is zero and get division error ;; type "centroid is " show new-centroid ask turtles with [not on-peak?] [ let old-patch patch-here ;; let's find what heading goes uphill let target max-one-of neighbors [height] face target let heading-uphill heading ifelse ( limit-horizon? = true ) [ face local-group-center ] [ face my-center] face my-center ;; <&&&&&&&&&&&&&&&&&&&&&& if we limit horizon I think it can create polarization , split up groups. let heading-group heading set my-heading-uphill heading-uphill set my-heading-group heading-group if (( heading-uphill > 270) and ( heading-group < 90 )) [ set heading-uphill ( heading-uphill - 360 ) ] if (( heading-uphill < 90 ) and ( heading-group > 270 )) [ set heading-group ( heading-group - 360 ) ] set heading (empathy)*(heading-group) + (1 - empathy)*(heading-uphill) ;; set heading (group-weight)*(heading-group) + (1 - group-weight)*(heading-uphill) step-or-reverse ( 1 ) wrap-up-step ] end ;================end of turtle movement commands ======= to snapshot ;; save a picture of the whole interface to disk, bare bones draft only ;; ask for a file-name ;; This should set a directory and base file name then increment a number add .jpg and save silently set timestamp date-and-time ifelse ( netlogo-web? = true ) [ print " export snapshot only works locally " ] [ run "export-interface user-new-file" ] ;; UNCOMMENT the next line to save a snapshot of the image to disk only works locally won't compile netlogo web ;; export-interface user-new-file ;; print OK end to apologize print " that function is not yet working!" set stop-now? true end to move-turtles if-else leave-a-trail? [ ask turtles [ pen-down ]] [ ask turtles [ pen-up ]] (if-else rule-to-use = "single: wander" [ go-wander ] rule-to-use = "single: go-uphill" [ go-uphill ] rule-to-use = "single: find-everyone" [ go-find-everyone ] rule-to-use = "pair: uphill with inertia" [ go-uphill-inertia ] rule-to-use = "pair: uphill with everyone" [ go-uphill-everyone ] rule-to-use = "triple: use all three" [ go-use-all-rules ] ; else commands [ error (word " unexpected rule-to-use choice: " rule-to-use) ] ) ;;set stop-now? false end to make-landscape set patch-count count patches; ask patch -7 -4 [set pcolor 125] ;; always make at least one hill if number-of-hills >= 2 [ ask patch 3 6 [set pcolor 95] ] if number-of-hills >= 3 [ ask patch 7 -5 [set pcolor 75] ] repeat 15 [ diffuse pcolor 1] ;; smooth that out somewhat if noise? [ ask N-of ( noise-density * patch-count) patches [set pcolor pcolor + noise-size] ] repeat 2 [ diffuse pcolor 1] ;; smooth the noise ask max-one-of patches [pcolor] [set peak-height pcolor] ask patches [ set height pcolor] ask patches [ set pcolor scale-color red height 0 peak-height ] end to make-turtles ; set the turtle color from the user menu let use-color green ;; default if turtle-color = "green" [ set use-color green ] if turtle-color = "white" [ set use-color white ] if turtle-color = "black" [ set use-color black ] if turtle-color = "red" [ set use-color red ] create-turtles turtle-count [ ;; turtle-count is set by a slider setxy random-xcor random-ycor set on-peak? FALSE set color use-color set size 2 set shape turtle-shape set wealth 0 set maxwealth 0 set good-step-count 0 set step-size-multiplier 1.0 if-else ( randomize-inertia? ) [ set inertia precision (random-float 1) 2 ] [ set inertia inertia-static ] if-else ( randomize-group-weight? ) [set empathy precision (random-float 1) 2 ] ;; set to random uniform on [0,1] [set empathy group-weight] ;; set in slider ] end to help ;; UNCOMMENT this section if you have a help file on your local PC ;if-else file-exists? "help-for-goals.txt" ; [ ; file-open "help-for-goals.txt" ; while [not file-at-end? ] ; [print file-read-line] ; file-close ; ] ; [ print "The help file 'help-for-goals.txt' was not found!" ; ] end
There are 10 versions of this model.
Attached files
File | Type | Description | Last updated | |
---|---|---|---|---|
goal-seeking-boids.png | preview | Preview for 'goal-seeking-boids' | almost 4 years ago, by R. Wade Schuette | Download |
This model does not have any ancestors.
This model does not have any descendants.