;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; MARS 1.07m ; MARS = "Multi-Agent Religion Simulation" ; (Schelling-like Simulation of Migration/Conformity/Conversion) ; ; Last modified: 2005-7-29, 12:30am ; Runs under NetLogo 2.1beta2 ; ; ; Coding credits: ; Coded in NetLogo by XXXXXXXXX in 12/2002, 1/2003, 5-6/2003, and 10-11/2004 ; with assistance from XXXXXXXXXXX. ; ; ; Note: ";:" at left indicates commands for debugging use only ; Note: ";x" at left indicates commands needed in TRX (type x rate) version ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Globals, Breeds, etc.: globals [ ; Globals defined by sliders and switches: ; ; Sliders (for each type, i = 0, 1, ..., N-1 and/or j = r(ed), g(reen), b(lue), y(ellow)) ; j_num ; j_pull1 j_pull2 ... j_pullN-1 j_type j_self j_pull ; j_copy1 j_copy2 ... j_copyN-1 j_rate j_habit j_copy ; ; red green blue yellow ; rand-wgts ; move-rate ; density ; regions ; rateX ; ;x rateX ;x replace with 0-100 slider in TRX version n-search ;; list - number of patches that "find-new-patch" checks (use with ;; patch selection criteria, such as max num of nbrs, num like self, etc.) t-sliders ;; list of root-names of type sliders ("pull1" "pull2" ... "type" "self" "pull") r-sliders ;; list of root-names of rate sliders ("copy1" "copy2" ... "rate" "habit" "copy") ;; used with "run" command to automate copying values to/from sliders ;; type and color info N-types ;; number of different types (referred to as "N" in comments) zeroN ;; list of N zeros, [0 0 ... 0] zeroN1 ;; list of N+1 zeros, [0 0 ... 0 0] zeroN3 ;; list of N+3 zeros, [0 0 ... 0 0 0 0] oneN ;; list of N ones, [1 1 ... 1] oneN1 ;; list of N+1 ones, [1 1 ... 1 1 ] oneN3 ;; list of N+3 ones, [1 1 ... 1 1 1 1] type-colors ;; list of type names (e.g. red, ...) type-names ;; list of the actual strings (e.g., "red", ...) c-list ;; list of first letter of colors ["r" "g" ...] type-shapes ;; list of shapes of each type of turtle turtle-shape-list ;; list of the actual strings ("circle", "box", ...) turtle-size-list ;; Use to alter turtle size according to rate (only for circles) border-color ;; color of border patches (currently grey) divider-color ;; color of divider patches (currently grey) main-board-color ;; color of main board (currently black) ;; model variables shares ;; share each type in turtle population type-percents t-pull ;; weighting factors used in adjust-type calculations r-copy ;; random weighting factors used in adjust-rate calculations copy-flag-value pull-flag-value modify-stage-list ;; toggles state of buttons, used to interpret sliders current-state ;; which turtle-state (saved via t-history) was recalled last. color-mode ;; 0 = rate-shaded mono, 1 = type-colored, 2 = type-colored and rate-shaded. color-state ;; 0 = original type and rate, 1 = current. current-region ;; Cycles over [1 .. N-regions] as "populate-region" is invoked. population ;; list = [total population, region 1 pop, region 2 pop, etc.] region-totals ;; list = [region 1's current population, region 2's pop, ..., total pop] region-max ;; list = [total number of patches, total in region 1, in region 2 ...] ;; statistics percent-similar ;; average percent of local turtles of same type g-stats ;; actual-g/expected-g statistics for each type of turtle type-totals ;; list w/ current number of turtles (one entry for each type + one for overall) rate-totals ;; list w/ current summed turtle rates (one entry for each type + one for overall) types-list1 ;; used in "foreach" loops = [0 1 2 3 ] types-list2 ;; used in "foreach" loops = [0 1 2 3 4] ;; parameters that can only be changed via recoding slow-speeds ;; cut-off slider speed value for blinking action max-speed ;; slider speed setting that sets wait to zero. max-wait ;; longest pause (corresponds to slowest slider speed setting) blink-period ;; total blinking time blink-interval ;; time per blink (in seconds) no-rates ;; Flag = 1 if only types are calculated, = 0 if both are used. ;; "no-rate=1" yields simple (type-only) version of program (MARS-1) plot-period ;; time (in periods) between updating of plots (currently set to 10) ;; parameters that remain fixed for a given run N-regions ;; Number of religions, as determined by "regions" slider ;; parameters that may vary during run ;; (see also sliders) target-type ;; parameters for "find-new-patch" (N-list) period ;; tracks total number of number of moves (including to same location) w-span ;; type parameter used by set-rand-wgts method. r-span ;; rate parameter used by set-rand-wgts method. current-scenario-data ;; information required to replay scenario (since last "start/run") ;; ... not yet implemented; see "to scenario-update". ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;FOR DEBUGGING ONLY ;;;;;;;;;;;;;;;;; zz1 zz2 zz3 zz4 ; globals for testing ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; rate and type adjustment parameters (copied to/from sliders) saved-rcopy-sets ; saved r-copy matrices saved-tpull-sets ; saved t-pull matrices saved-shares ] turtles-own [ ;; matrix of turtle's past "states": [ [state0] [state1] ...] t-history ;; Each "state" is a (sub)list of form [xcor, ycor, rate, type]. ;; State0 (sublist 0) is for birth, sublist 1 for initial ;; state (after adjusting rate and type), and subsequent sublists are those ;; saved by user. ;; Random values used to "personalize" the parameters that determine turtle type changes. ;; Determined when via "set-rand-wgts" procedure when turtle is "born." ;; Used when "rand-wgt" switch is "on"; ignored when "off" rnd-type ;; 3+N-item list ;; Random values used to "personalize" the parameters that determine turtle rate changes. ;; Determined when via "set-rand-wgts" procedure when turtle is "born." ;; Used when "rand-wgt" switch is "on"; ignored when "off" rnd-rate ;; 3+N-item list ;; Key state variables own-rate ;; current rate of participation (e.g., church attendance rate) own-type ;; current type of particpant (e.g., type of religion) ] patches-own [ region-id ;; 0 for edges, 1 for region 1, 2 for 2, etc. nearby-types ;; list with item i = number of type-i nbrs, and ; last item = total number of nbrs. ] to save-parameters if saved-rcopy-sets = 0 [set saved-rcopy-sets [] ] set saved-rcopy-sets lput ((length saved-rcopy-sets) / 2) saved-rcopy-sets set saved-rcopy-sets lput r-copy saved-rcopy-sets if saved-tpull-sets = 0 [set saved-tpull-sets [] ] set saved-tpull-sets lput ((length saved-tpull-sets) / 2) saved-tpull-sets set saved-tpull-sets lput t-pull saved-tpull-sets if saved-shares = 0 [set saved-shares [] ] set saved-shares lput ((length saved-shares) / 2) saved-shares set saved-shares lput shares saved-shares end to recall-parameters [i] if saved-rcopy-sets != 0 [ set r-copy item (2 * i + 1) saved-rcopy-sets set t-pull item (2 * i + 1) saved-tpull-sets set shares item (2 * i + 1) saved-shares ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Set/initialize basic paramters: ;; Buttons (and the procedures they run) ; ; reds (add-turtles-manually 0), ditto for greens, blues, yellows ; Start/End (Setup) ; Run/Pause (go) ; Options (menu) ; Populate (populate-region) ; Color (toggle-color-mode) ; Scenarios (menu) ; ;; Switches (and their globals) ; ; rand-wgts (rand-wgts) to initialize-shapes-and-colors set type-colors [sky red green yellow] ; color values (numerical values) as defined by NetLogo set type-names ["blue" "red" "green" "yellow"] ; color names (strings) used by plots (note "blue", not "sky") ;set type-shapes ["circle" "circle" "circle" "circle"] ; for color output set type-shapes ["circle" "x" "triangle" "box"] ; for b&w (printed) output ; shape names (strings) used on board. set c-list ["b" "r" "g" "y"] ; first letter in color names (could be derived via "first" operator) ;set turtle-size-list ; ["circle0" "circle1" "circle2" "circle3" "circle4" "circle5" "circle6" "circle7"] set-default-shape turtles item 0 type-shapes set main-board-color white set border-color black set divider-color black end to initialize-parameters ;; Use this section to store basic parameters locals [ XX ] set no-rates 0 ; use to suppress rate-related features. set current-state 0 ; use to track which (saved) board is being displayed set slow-speeds 3 ; moving turtles blink only if speed < slow-speeds set max-wait 1 ; time (in seconds) to wait if speed = 0 set max-speed 10 ; maximal speed setting set period 1 ; use to limit stat and plot updates set blink-period 1 ; use for 1 sec of blinking set blink-interval .2 ; use for .2 sec per blink set plot-period 10 ; number of periods between plot-updates set w-span 1.0 ; used in set-rand-wgts set r-span 1.0 ; used in set-rand-wgts set N-types 4 ; number of "types" (i.e., turtle colors) set zeroN n-values (N-types) [0] ; = [0 0 ... 0], length N set oneN n-values (N-types) [1] ; = [1 1 ... 1], length N set zeroN1 n-values (N-types + 1) [0] ; = [ 0 0 ... 0 0 ], length N+1 set oneN1 n-values (N-types + 1) [1] ; = [ 1 1 ... 1 1 ], length N+1 set zeroN3 n-values (N-types + 3) [0] ; = [ 0 0 ... 0 0 0 0 ], length N+3 set oneN3 n-values (N-types + 3) [1] ; = [ 1 1 ... 1 1 1 1 ], length N+3 set n-search oneN ; find-new-patch initially searches just one patch set target-type oneN ; multi-patch searches default: prefer max turtles of own type set shares make-constant-list N-types ( 1 / N-types) ; initially all types have equal shares (even if all are zero). set type-percents make-constant-list N-types ( 1 / N-types) ; ... and hence also equal percentages (even if all are zero). set type-totals (sentence zeroN1 ) ; = [ 0 0 ... 0 ], length N+1 set rate-totals n-values (N-types + 1) [.5] ; = [ .5 .5 ... .5 ], length N+1 set types-list1 [0 1 2 3 ] ; used in "foreach" loops set population (sentence zeroN1 ) ; start w/ zero turtles of all types on board set region-totals (sentence zeroN1 ) ; start w/ zero turtles of all types on board ; Initialize t(ype)-pull and r(ate)-copy matrices: ; Sub-lists have (N+3) elements, one for each type factor ; plus initial base, habit, and alternate (uniform-conformity) factor. ; Create t-pull and r-copy as list of lists, ; each containing N-copies of the XX sub-list, yielding two N x (N+3) matrices overall. set t-pull n-values (N-types) [zeroN3] set r-copy n-values (N-types) [zeroN3] ; Equivalent to "set t-pull [ [0 0 0 0 0 0 0] ... [0 0 0 0 0 0 0] ]" set t-sliders ["pull1" "pull2" "pull3" "pull4" "type" "self" "pull"] set r-sliders ["copy1" "copy2" "copy3" "copy4" "rate" "habit" "copy"] ; strings with base-names of sliders (which give full names when appended to "r_" "g_" ...) set copy-flag-value 2.1 ; flag to read from full matrix of copy-sliders set pull-flag-value 2.1 ; flag to read from full matrix of pull-sliders ;x set rateX 0 ;x remove for TRX version set current-scenario-data [] end to initialize-board locals [ i ] ;; Lay out board (borders, regions, etc.) ;; Step 1a: Set region-id's for borders and dividers ask patches [ ;; initialize all patches set region-id 1 if N-regions >= 1 [ if N-regions >= 2 and pycor <= 0 [ifelse pycor = 0 [set region-id .2] [set region-id 2]] if N-regions >= 3 and pycor < 0 and ((pxcor >= 0)) [ifelse ((pxcor = 0)) [set region-id .3] [set region-id 3]] if N-regions >= 4 and pycor > 0 and ((pxcor >= 0)) [ifelse ((pxcor = 0)) [set region-id .4] [set region-id 4]] ;; create border around edge and through y-axis if ((abs(pxcor) = screen-edge-x) or (abs(pycor) = screen-edge-y)) [set region-id 0] ] ] ;; Step 1b: Count patches (max potential population) in each region and place total in last item set region-max n-values (N-types + 1) [0] ; initialize list if N-regions = 0 [set N-regions 1] ;; trick to make "zero" region case work. set i 1 while [i <= N-regions] [ set region-max replace-item i region-max (count patches with [region-id = i]) set i i + 1 ] set region-max replace-item 0 region-max sum but-first region-max ;; Step 3: Color patches (based on region-id's) ;; and initialize nearby-types and nearby-rates = [0 0 ... 0] ask patches [ ifelse (region-id = 0) [set pcolor border-color] [ ifelse (region-id < 1)[set pcolor divider-color] [ set pcolor main-board-color ;; "nearby" stats only relevant on main board regions set nearby-types (sentence zeroN 0) ] ] ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Pass parameter values to/from sliders ;; (there MUST be a better way to do this!) to get-type-percents ;; Calculates percentages from shares (each of which may range between 0 and 100). locals [ i ] ; 1) Re-read shares list from sliders ; (Use "run" to create commands: "set shares replace-item 0 shares r_num", ; "set shares replace-item 1 shares g_num", etc.) set i 0 while [i < N-types] [ run "set shares replace-item " + i + " shares " + item i c-list + "_num" set i (i + 1) ] if shares = zeroN [ set shares replace-item 0 shares 1 set shares replace-item 1 shares 1 ] ; error trap: if all shares are zero, then reset first two to 1. ; 2) Calculate percentages foreach types-list1 [ set type-percents replace-item ? type-percents ((item ? shares) / (sum shares)) ] end to copy-to-sliders ;; Re-set sliders to display type-matrix and rate-matrix parameters of type i locals [i j] set i 0 while [i < N-types] [ run "set " + (item i c-list) + "_num " + " (item " + i + " shares)" ; equivalent to "set r_num (item 0 shares)", "set g_num (item 1 shares)", etc. set j 0 while [j < 7] [ run "set " + (item i c-list) + "_" + (item j t-sliders) + " (item " + j + " (item " + i + " t-pull))" ; equivalent to "set r_pull2 (item 1 (item 0 t-pull))" iterated over all types and type-sliders run "set " + (item i c-list) + "_" + (item j r-sliders) + " (item " + j + " (item " + i + " r-copy))" ; equivalent to "set r_copy3 (item 2 (item 0 t-copy))" iterated over all types and rate-sliders set j (j + 1) ] set i (i + 1) ] end to copy-from-sliders ;; Re-set type i's type-list and rate-list parameters from sliders locals [i j] set i 0 ; Loop through each type i (red, green, etc.) while [i < N-types] [ ; 1) Copy values from i's share slider: run "set shares (replace-item " + i + " shares " + item i c-list + "_num)" ; equivalent to "set shares (replace-item 0 shares r_num)" etc. ; 2) Copy values from i's type and rate sliders: ; 2a) Always copy from i's basic type sliders ("_type", "_self", and "_pull") ; and basic rate sliders ("_rate", "_habit", and "_copy"). set j N-types while [j < N-types + 3] [ run "set t-pull (replace-matrix-element " + i + " " + j + " t-pull " + item i c-list + "_" + item j t-sliders + ") " run "set r-copy (replace-matrix-element " + i + " " + j + " r-copy " + item i c-list + "_" + item j r-sliders + ") " set j (j + 1) ] ; 2b) Copy full matrix of type-interactions from separate sliders ; only if "_pull" slider is set to "pull-flag-value", otherwise set ; all interactions (uniformly) equal to "_pull" slider. ; Likewise for matrix of rate-interactions" set j 0 while [j < N-types] [ run "ifelse (" + item i c-list + "_pull = pull-flag-value) " + "[set t-pull (replace-matrix-element " + i + " " + j + " t-pull " + item i c-list + "_" + item j t-sliders + ") ] " + "[set t-pull (replace-matrix-element " + i + " " + j + " t-pull " + item i c-list + "_" + item (N-types + 2) t-sliders + ") ] " run "ifelse (" + item i c-list + "_copy = copy-flag-value) " + "[set r-copy (replace-matrix-element " + i + " " + j + " r-copy " + item i c-list + "_" + item j r-sliders + ") ] " + "[set r-copy (replace-matrix-element " + i + " " + j + " r-copy " + item i c-list + "_" + item (N-types + 2) r-sliders + ") ] " set j (j + 1) ] set i (i + 1) ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Setup invoked at start of program (and reinvoked via "setup" button): to setup ;; (Re-)initialize board layout and other key key parameters ca clear-output initialize-parameters initialize-shapes-and-colors set N-regions regions ;; Set number of regions (until next "setup") initialize-board ifelse no-rates = 1 [set color-mode 1] [set color-mode 2] ;; initially display type-colored (and rate-shaded unless suppressing rates). set color-state 1 ;; initially, ready to "toggle" state back to original color, rate, and shape. set current-region 1 ;; Initialize to region #1. copy-from-sliders ; get initial parameter values end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Set basic run-time options to options-menu-select ;; set various options via queries to user ;; good way to simplify interface without eliminating options ;; Other choices to add: ; default values (for all options: regions, shares, etc.) ; move-rate? ; % or # to move when run is pressed (escape via stop), ; rand-wgts? ; scenarios!!! ; maintain regional densities vs. choose any open location? locals [choice1 choice2 choice3 choice4 Ntype] set choice1 (user-choice "Option to alter?" [ "Show" "Search" "Display" "Replot" "Skip Ahead-%" "Skip Ahead-n" "Quit" ]) if choice1 = "Quit" [stop] if choice1 = "Show" [ set choice2 (user-choice "Show Regional-Shares or Search-Methods" [ "Shares" "Search" "Quit"]) if choice2 = "Quit" [stop] if choice2 = "Shares" [output-regional-shares] if choice2 = "Search" [ output-print " SEARCH METHODS:" output-type " " output-print list n-search target-type ] ] if choice1 = "Skip Ahead-%" [ set choice2 (user-choice "Percent to move?" ["5" "10" "15" "20" "Quit"]) if choice2 = "Quit" [stop] make-x-percent-move (read-from-string choice2) / 100 ] if choice1 = "Skip Ahead-n" [ set choice2 (user-choice "number to move?" ["10" "100" "200" "500" "1000" "2000" "Quit"]) if choice2 = "Quit" [stop] make-x-move (read-from-string choice2) ] if choice1 = "Display" [ set choice2 (user-choice "(1) Return to initial layout? (2) Restore types?" [ "(1) Return" "(2) Restore" "Quit"]) if choice2 = "(1) Return" [restore-turtles-all] if choice2 = "(2) Restore" [restore-turtles-types] if choice2 = "Quit" [stop] ] if choice1 = "Replot" [clear-all-plots] if choice1 = "Search" [ set choice2 (user-choice "Alter whose method?" ["Blue" "Red" "Green" "Yellow" "Quit"]) if choice2 = "Quit" [stop] set Ntype position (first choice2) "BRGY" set choice3 (user-choice "Number of locations to search each move?" [ "1" "2" "4" "8" "32" "Quit"]) if choice3 = "Quit" [stop] set n-search (replace-item Ntype n-search (read-from-string choice3)) set choice3 (user-choice "Search for own-type or any-type?" ["Own-type" "Any-type" "Quit"]) if choice3 = "Quit" [stop] if choice3 = "Own-type" [set target-type (replace-item Ntype target-type 1)] if choice3 = "Any-type" [set target-type (replace-item Ntype target-type 0)] output-print " SEARCH METHODS:" output-type " " output-print list n-search target-type ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Go/Pause Methods: to populate-region ;; This method cycles through the regions, 1 through N-regions get-type-percents add-turtles current-region ;; invoke for current region only set current-region 1 + (remainder current-region N-regions ) ;; Cycle to next region end to go ;; Move a turtle (attached to "forever" button) ; Key parameters governing move are set via sliders, button, or parameters section of program locals [i r cum-pop xx yy old-type old-rate old-patch new-patch new-type] if item 0 population = 0 [stop] ;; Exit if this button before any turtles are present. every 2 [copy-from-sliders] ;; Copy from sliders at least every 2 seconds ask random-one-of turtles [ ;; Randomly select random turtle to update if speed < slow-speeds ;; Blink turtle at slow speeds. [blink-turtle blink-period blink-interval shape color white] set old-patch patch-here set old-type own-type if random-int-or-float 100 < move-rate [ ;; Decide to move or merely adjust type & rate set r random-int-or-float 1.0 ;; Choose target region for jump, so as to set i 1 ;; maintain regional population densities set cum-pop (item 1 population) while [r > (cum-pop / (item 0 population))] [ set i (i + 1) ;; To ignore population densities, set cum-pop (cum-pop + (item i population)) ;; skip regional-choice routine ] ;; and simply use: "find-new-patch 0" ifelse (item own-type target-type = 1) ; if 1, prefer more nbrs of own-type ; if 0, prefer more nbrs of any-type [find-new-patch i own-type (item own-type n-search)] [find-new-patch i N-types (item own-type n-search)] ] if speed < slow-speeds ;; blink turtle at slow speeds [blink-turtle blink-period blink-interval shape color color] without-interruption [ if patch-here != old-patch [ ;; update "nearby" stats if turtle moved ask old-patch [update-nearby old-type -1] ] adjust-type ;; re-evaluate type if patch-here != old-patch [ ;; update "nearby" stats if turtle moved set new-type own-type ask patch-here [update-nearby new-type 1] ] ] adjust-rate 3 ;; re-evaluate rate ] if period mod plot-period < 1 [ ;; For speed, do stats and plots only 1/Nth of the time. do-plots ;; plot-period currently = 10 ] set period (period + 1) ;; increment counter, one per move if (speed < max-speed) [wait max-wait / (2 ^ speed)] ;; set length of pause per loop (10 skips pause). end to make-x-percent-move [x-percent] ;; Move N times, then pause ; where N = x-percent of total number of turtles. locals [n] set n x-percent * count turtles repeat n [ go ] end to make-x-move [x] ;; Move x times, then pause ; where x= number of turtles. repeat x [ go ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Methods that alter types or locations of *all* turtles to restore-turtles-types ;; Restore each turtle to its original type ask turtles [restore-type] ; Recompute global type-totals list and rate-totals list recompute-totals ; Restore each patches' "nearby-types" list ask patches with [ region-id >= 1 ] [recompute-nearby] end to show-original-states ; Attached to a "forever" button, this continuously displays turtles original (rate and type) states. ; Attached to a regular button, this displays original states for 2 seconds, then reverts to regular. ; In either case, the turtles' underlying rate and type values are not affected. ask turtles [display-original-color] ask patches with [ (pxcor = (screen-edge-x - 1)) and (abs(pycor) = screen-edge-y) ] [ set plabel "ORIGINAL TYPES" set plabel-color red ] wait .5 ; revert to actual (rate and type) display: ask turtles [recolor-turtle] ask patches with [(pxcor = (screen-edge-x - 1)) and (abs(pycor) = screen-edge-y)] [ set plabel no-label ] end to restore-turtles-all ;; Restore each turtles to it's setup type AND coordinates restore-turtles-types ask turtles [restore-position ] ; Recompute global type-totals list and rate-totals list recompute-totals ; Restore each patches' "nearby-types" list ask patches with [ region-id >= 1 ] [recompute-nearby] ; Display number of recalled state ask patch 1 screen-edge-y [set plabel 0 set plabel-color magenta] end to toggle-color-mode ;; Toggle between rate-shaded monochrome, type-based color, and shaded-color modes if no-rates != 1 [ set color-mode remainder (color-mode + 1) 3 ;; progresses from 0, to 1, to 2 ask turtles [recolor-turtle] ;; recolor ] end to recall-saved-state ;; Cycle board through saved states. ; First use reverts to original state (t-history0), ; second use reverts to initial adjusted state (t-history1), ; then on to states saved via "save" button. ; Last recalled state is displayed above board. locals [num-states] ask turtle 0 [set num-states length t-history] set current-state (current-state - 1) mod (num-states) ; cycle "current-state" counter to next state ask turtles [ revert-to-history current-state ] ; Recompute global type-totals list and rate-totals list: recompute-totals ; Restore each patch's "nearby-types" list: ask patches with [ region-id >= 1 ] [recompute-nearby] ; Display number of recalled state ask patch 1 screen-edge-y [set plabel current-state set plabel-color red] output-type " Last recalled state: " output-print current-state end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Primitive Help System to help-menu locals [choice1 choice2 choice3 Ntype] set choice1 (user-choice "Help with which topic?" [ "Overview" "Buttons" "Sliders" "Quit" ]) if choice1 = "Quit" [stop] output-type " HELP: " output-print choice1 if choice1 = "Overview" [ output-print "See 'Information' tab above." ] if choice1 = "Buttons" [ set choice2 (user-choice "Which button?" [ "Superstar" "Originals" "Density" "Start/Stop" "Run" "Quit"]) if choice2 = "Superstar" [ output-print "SUPERSTAR: Press this button and then click " output-print "on an agent to give it ten-fold 'pull'" output-print "compared to typical agents of its type." output-print "Must also switch 'rand-wgts' on." ] if choice2 = "Quit" [stop] ] if choice1 = "Sliders" [ output-print "(No help yet on this topic.)" ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Methods that select complete "scenarios" to scenario-select ; Use to set any of the globals - including sliders! - and run ; any methods - including those linked to buttons!. So user can simply choose ; from various scenarios, modes, etc. ; Can use control center via print or show to describe mode or results ; For example: ; (1) pure peer effects (no rate effects, no history, no birth effects) ; (2) pure rate effects, just one type & mono-mode ; (3) one group is effectively anti-religious, depressing rates of others ; (4) various values for habit, etc. ; (5) various numbers of regions, density, speed, etc. ; Recall that t-pull holds ["pull1" "pull2" "pull3" "pull4" "type" "self" "pull"] for each type. ; Recall that t-copy holds ["copy1" "copy2" "copy3" "copy4" "rate" "habit" "copy"] for each type. locals [choice1 choice2 choice3 Ntype Nfile scenario-data s-period s-regions s-density s-n-search s-target-type s-rand-wgts s-move-rate s-shares s-t-pull s-r-copy ] set choice1 (user-choice "Scenario?" [ "Basic" "Resist" "Conform" "Save" "Recall" "Quit" ]) if choice1 = "Quit" [stop] if choice1 = "Basic" [ set regions 2 setup set density 75 set speed 10 set move-rate 100 set rand-wgts false set t-pull [ [0 0 0 0 .3 .3 1.6] [0 0 0 0 .3 .3 1.6] [0 0 0 0 .3 .3 1.6] [0 0 0 0 .3 .3 1.6] ] set r-copy [ [0 0 0 0 .5 0 0] [0 0 0 0 .5 0 0] [0 0 0 0 .5 0 0] [0 0 0 0 .5 0 0] ] set shares [70 30 0 0] copy-to-sliders populate-region set shares [30 70 0 0] copy-to-sliders populate-region recall-saved-state recall-saved-state ] if choice1 = "Resist" [ set regions 2 setup set density 75 set speed 10 set move-rate 100 set rand-wgts false set t-pull [ [0 0 0 0 .3 .3 .3] [0 0 0 0 .3 .3 .3] [0 0 0 0 .3 .3 .3] [0 0 0 0 .3 .3 .3] ] set r-copy [ [0 0 0 0 .5 0 0] [0 0 0 0 .5 0 0] [0 0 0 0 .5 0 0] [0 0 0 0 .5 0 0] ] set shares [70 30 0 0] copy-to-sliders populate-region set shares [30 70 0 0] copy-to-sliders populate-region recall-saved-state recall-saved-state ] if choice1 = "Conform" [ set regions 2 setup set density 75 set speed 10 set move-rate 100 set rand-wgts false set t-pull [ [0 0 0 0 .0 .01 1.9] [0 0 0 0 .0 .01 1.9] [0 0 0 0 0 0 0] [0 0 0 0 0 0 0] ] set r-copy [ [0 0 0 0 .5 0 0] [0 0 0 0 .5 0 0] [0 0 0 0 .5 0 0] [0 0 0 0 .5 0 0] ] set shares [70 30 0 0] copy-to-sliders populate-region set shares [30 70 0 0] copy-to-sliders populate-region recall-saved-state recall-saved-state ] if choice1 = "Save" [ scenario-save ;; File names automatically increment with each successive save: set Nfile 1 while [file-exists? ("scenario-" + Nfile + ".txt")] [set Nfile Nfile + 1] file-open ("scenario-" + Nfile + ".txt") file-write current-scenario-data file-close ] if choice1 = "Recall" [ ;; Note: Tighten this code using the read-string tricks used in copy-to-sliders. set choice2 (user-choice "Full or partial recall?" [ "Full (start over)" "Partial (maintain board)" "Quit" ]) if choice2 = "Partial (maintain board)" [ ;; Partial does *not* restart, but merely changes parameters that affect motion. ;; Hence, no change in current configuration of agents, nor regions, density, shares. set scenario-data scenario-recall ; set period item 0 scenario-data ; set regions item 1 scenario-data ; set density item 2 scenario-data set n-search item 3 scenario-data set target-type item 4 scenario-data set move-rate item 5 scenario-data set rand-wgts item 6 scenario-data ; set shares item 7 scenario-data set t-pull item 8 scenario-data set r-copy item 9 scenario-data copy-to-sliders ] if choice2 = "Full (start over)" [ ;; Full resets everything and starts again with a blank board, ready to populate. set scenario-data scenario-recall ; set period item 0 scenario-data set regions item 1 scenario-data set density item 2 scenario-data set n-search item 3 scenario-data set target-type item 4 scenario-data set move-rate item 5 scenario-data set rand-wgts item 6 scenario-data set shares item 7 scenario-data set t-pull item 8 scenario-data set r-copy item 9 scenario-data copy-to-sliders setup ; Just for debugging: ; output-type "s-period: " output-print period ; output-type "s-regions: " output-print regions ; output-type "s-density: " output-print density ; output-type "s-n-search: " output-print n-search ; output-type "s-target-type: " output-print target-type ; output-type "s-move-rate: " output-print move-rate ; output-type "s-rand-wgts: " output-print rand-wgts ; output-type "s-shares: " output-print shares ; output-type "s-t-pull: " output-print t-pull ; output-type "s-r-copy: " output-print r-copy ] ] end to scenario-save ; Called by "scenario-select save" procedure. ; Each "select-scenario save" appends a new list of parameters to "current-scenario-data". ; Currely, each save writes "current-scenario-data" to a new file, "scenario-NNN.txt" ; where NNN = 1, 2, ... set current-scenario-data (list period regions density n-search target-type move-rate rand-wgts shares t-pull r-copy) ;; Note: ;; Eventually, design a "scenario-select record" mode that automatically tracks user actions ;; for a given run: regions, density, sliders, populate, etc. ;; "Record" should also track use of "make-x-percent-move" and other scenarios and options, ;; but this will get complicated! ;; Must also track each subsequent push of populate, run, and/or manually added turtle. ;; Then design "scenario-select replay" to fully replay the scenario based on the saved info. end to-report scenario-recall locals [scenario-list] ; Get scenario data list (created by scenario-save) from file file-open user-choose-file set scenario-list file-read file-close report scenario-list end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Methods that create (but do not move) turtles: to add-turtles [ this-region ] ;; Add turtles over current region, filling {density} percent of open patches locals[ n-new n-sum n-type-i pct-sum i XX list-sum n-histories new-patch turtle-type] ;; calculate number of new turtles to add set n-new round((density / 100) * count patches with [(region-id = this-region) and (not any? turtles-here)]) ;; determine number of prior state-saves (i.e., length of t-history) ; it should suffice to check any single turtle ; ifelse needed to avoid error when board is empty. ifelse any? turtles [ask one-of turtles [set n-histories length t-history] ] [set n-histories 2] ;; update slider-based parameters copy-from-sliders ;; determine types of new turtles based on share sliders get-type-percents ; Get type-percents from current share sliders ;; loop over types, creating cumulative list with one "i" ; for each new turtle of type i that must be created set list-sum [] set pct-sum 0 set n-sum 0 while [ i < N-types ] [ set pct-sum pct-sum + (item i type-percents) ; pct-sum = sum of percents up through type-i set n-type-i round(n-new * pct-sum) - n-sum ; n-type-i = number of i's added to list ; (= number of type-i turtles added to board). set n-sum n-sum + n-type-i set list-sum sentence list-sum (make-constant-list n-type-i i) ; append {n-new} elements to list-sum, ; each equal to i's current value set i (i + 1) ] ;; loop over elements in list-sum, randomly selecting (and removing) items, ; and adding a new turtle based on the (type) value of each item. set n-sum n-new while [n-sum > 0] [ set XX random-int-or-float length list-sum ; select an item location at random from list-sum set i item XX list-sum ; value of item determines type of turtle to be added set list-sum remove -99 (replace-item XX list-sum -99) ; drop used item from list. Can't use ; "remove XX list-sum" as it removes _all_ i's from list. ; this trick only works if -99 isn't already in the list. cct 1 [ ; procedure to add next (real) turtle ht set heading 0 ; compute turtle's personal adjustments ; for rate- and type- effects: set-rand-wgts w-span r-span set-type-id i ; type is based on value of item removed from list-sum ifelse (no-rates = 1) [ set own-rate .5 recolor-turtle ] ;; Rates == 1 in "no-rates" mode, else [adjust-rate 0] ;; need "0" for new turtle not yet moved onto board ifelse (item own-type target-type = 1) ; if 1, prefer more nbrs of own-type ; if 0, prefer more nbrs of any-type [find-new-patch this-region own-type (item own-type n-search)] [find-new-patch this-region N-types (item own-type n-search)] ; move turtle to new random location, and add-to-history ; add initial state of turtle to history list ; should get item 0 = initial [xcor,ycor,rate,type] ;; Update "type-totals" list set type-totals replace-item own-type type-totals (1 + (item own-type type-totals)) set type-totals replace-item N-types type-totals (1 + (item N-types type-totals)) ;; Update "rate-totals" list if no-rates != 1 [ set rate-totals replace-item own-type rate-totals (own-rate + (item own-type rate-totals)) set rate-totals replace-item N-types rate-totals (own-rate + (item N-types rate-totals)) ] adjust-type ; now adjust type and rate based on nbrs if no-rates != 1 [ adjust-rate 2 ; "2" forces standard adjustments (based on nbrs and own past). ] repeat (n-histories - 1) [add-to-history] ; add current (adjusted) state of turtle to turtle's history list ; make additional copies if necessary to insure that all turtles ; have same length t-history ; should get item 1 = current [xcor,ycor,rate,type] st ;; Update "nearby" type stats for self and nbrs set turtle-type own-type ask patch-here [update-nearby turtle-type 1] ] set n-sum (n-sum - 1) ; ready for next item ] ;; Update population set population replace-item 0 population (n-new + (item 0 population)) set population replace-item this-region population (n-new + (item this-region population)) end to add-turtles-manually [type-id] ; Button must be set to cycle "forever" ; Add type-i turtle if mouse button is pressed ; and mouse is over an empty patch on the real side of board locals [ i n-histories turtle-type] set i type-id if (mouse-down?) [ ask patch-at mouse-xcor mouse-ycor [ if (not any? turtles-here) and (region-id > 0) [ ifelse any? turtles [ask one-of turtles [set n-histories length t-history] ] [set n-histories 2] ;; determine number of prior state-saves (i.e., length of t-history) ; it should suffice to check any single turtle ; ifelse needed to avoid error when board is empty. every 5 [copy-from-sliders] ;; periodically update adjustment parameters from sliders sprout 1 [ ht set heading 0 set breed turtles ; compute turtle's personal adjustments for rate- and type- effects: set-rand-wgts w-span r-span set-type-id type-id ifelse (no-rates = 1) [ set own-rate .5 recolor-turtle ] ;; Rates == 1 in "no-rates" mode, else [adjust-rate 1] ;; need "1" when new turtle is dropped on board add-to-history ;; record turtle's "birth state" repeat (n-histories - 1) [add-to-history] ;; record turtle's rate-adjusted "initial state" ; repeated as needed to match other t-history lengths. st ;; Update regional "populations" list set population replace-item 0 population (1 + (item 0 population)) set population replace-item region-id population (1 + (item region-id population)) ;; Update "type-totals" list set type-totals replace-item own-type type-totals (1 + (item own-type type-totals)) set type-totals replace-item N-types type-totals (1 + (item N-types type-totals)) ;; Update "rate-totals" list if no-rates != 1 [ set rate-totals replace-item own-type rate-totals (own-rate + (item own-type rate-totals)) set rate-totals replace-item N-types rate-totals (own-rate + (item N-types rate-totals)) ] ;; Update "nearby" stats for self & nbrs: without-interruption [ set turtle-type own-type ask patch-here [update-nearby turtle-type 1] ] ] ] ] ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Methods that calculate and plot overall statistics: to do-plots ;; Bug: Plot of color-X doesn't start until number of type-X's on board > 4. locals [i x] ;; 1t) Percentage Markers ; Place a bar every N time periods (where N = total number of turtles) set-current-plot-pen "time-tick" ifelse (precision ((period - (plot-period) / 2) / item 0 population) 0) != (precision ((period + (plot-period) / 2) / item 0 population) 0) [plot 5 plot-pen-down] [plot-pen-up plot 0] ; To also plot N/10 ticks, replace last line with the following: ; [ ; ifelse (precision ((period - (plot-period) / 2) / item 0 population) 1) != ; (precision ((period + (plot-period) / 2) / item 0 population) 1) ; [plot 2 plot-pen-down] ; [plot-pen-up plot 0] ; ] ;; 1a) Share plots set-current-plot "Shares" foreach types-list1 [ ;; Careful! The pen names here must match the names in type-names ;; Plot share-stats for type i only if number of type-i turtles >= 5. set-current-plot-pen item ? type-names ifelse item ? type-totals > 4 [plot (100 * (item ? type-totals) / (item N-types type-totals)) plot-pen-down] [plot-pen-up plot 0] ] ;; 1b) Overall similiarity statistic - plotted on same graph as "Shares" ;; "similar" = mean share of nbrs same type as self. set-current-plot-pen "similar" plot similarity-all ; ;; Alternative to "similarity" reporter - same result (and faster?): ; ifelse (any? patches with [(region-id > 0) and (any? turtles-here) and ; (item N-types nearby-types) > 0] ; ) ; [set percent-similar mean values-from ; patches with [(region-id > 0) and (any? turtles-here) ; and (item N-types nearby-types) > 0] ; [100 * (item (own-type-of one-of turtles-here) nearby-types) / (item N-types nearby-types) ] ; ] ; [set percent-similar 0] ; set-current-plot-pen "similar" ; plot similarity-all ;; No Rate Plots for this version ; ;; 2a) Compute and plot mean rates for each type (and all together) ; ; Note: Use pen-up/down to suppress plot for any type with fewer than five cases ; if no-rates != 1 [ ; set-current-plot "Rates" ; ; Plot separate line for each type of turtle ; foreach types-list1 [ ; set-current-plot-pen item ? type-names ; ifelse (item ? type-totals > 4) ; [plot (item ? rate-totals / item ? type-totals) plot-pen-down] ; [plot-pen-up plot 0 ] ; ] ; ; 2b) Plot a line for all types of turtles ; set-current-plot-pen "all" ; plot (item N-types rate-totals / item N-types type-totals) ; ] ;; No Grimson Plots for this version ; ; 3) Compute & Plot Grimson Clustering Stats: ; set-current-plot "Clustering" ; calculate-grimson-stats ; foreach types-list1 [ ; set-current-plot-pen item ? type-names ; ifelse item ? g-stats > 0 [plot item ? g-stats plot-pen-down] [plot-pen-up plot 0] ; ] end ;; Similiarity statistic for all types to-report similarity-all ifelse any? patches with [(region-id > 0) and (any? turtles-here) and (item N-types nearby-types) > 0] [report mean values-from patches with [(region-id > 0) and (any? turtles-here) and (item N-types nearby-types) > 0] [100 * (item (own-type-of one-of turtles-here) nearby-types) / (item N-types nearby-types) ]] [report -1] end ;; Similiarity statistic for specific types to-report similarity-x [ x-type ] locals [x-list ] ;; "similar" = mean share of nbrs same type as self. show x-type set zz1 values-from turtles with [ (own-type = x-type) and (value-from patch-here [item N-types nearby-types] > 0 )] [100 * value-from patch-here [(item x-type nearby-types) / (item N-types nearby-types) ]] ifelse (empty? zz1) [report -1] [report mean zz1] end ;; No Grimson Plots for this version ;to calculate-grimson-stats ; ;; ** Grimson's clustering statistic (web reference ...geomed/stats/Grimson) ; ;; ** Get a separate G-stat for each type ; locals [i a exp-a var-a y var-y n x actual-gi expected-gi ] ; set g-stats zeroN ;; initialize the list of g-statistic ratios (one for each turtle type) ; ; def: x = total number of turtles ("items") of all types ; set x item N-types type-totals ; ; def: y = average number of neighbors (= "occupied borders") per item ; set y mean values-from turtles [item N-types nearby-types] ; ; def: Var-y = variance of y ; set var-y variance values-from turtles [item N-types nearby-types] ; ; Testing: type "type-" + i + ": y=" + precision y 1 + " x=" + x print " " ; ; For each item type i = 1, 2, ..., N-types: ; ; def: n_i = number of type i items ; ; def: a_i = number of "borders" shared by type i items ( = 1/2 number of adjacent type i's) ; ; def actual-g_i = a_i ; ; expected-g_i = yn(n-1)/2(x-1) ; ; variance-g_i = var-a_i = ... see below ; foreach types-list1 [ ; ifelse (item i type-totals < 4) [set g-stats ( replace-item i g-stats 0 )] [ ; set n item i type-totals ; set a (1 / 2 ) * ( sum values-from turtles with [own-type = i] ; [item i nearby-types ] ) ; set exp-a (y * n * (n - 1) / (2 * (x - 1)) ) ; set var-a exp-a * ( 1 + ; ( (2 * (y - 1) * (n - 2) ) / (x - 2) ) + ; ( (x * y - 4 * y + 2) * (n - 2) * (n - 3)) / (2 * (x - 2) * (x - 3 ) ) - exp-a ) + ; var-y * ; ( ((x - n) * n * (n - 1) * (n - 2)) / ((x - 1) * (x - 2) * (x - 3)) ) ; ; ( (n * (n - 1) * (n - 2)) / ((x - 1) * (x - 2)) ) - ; ; ( (n * (n - 1) * (n - 2) * (n - 3)) / ((x - 1) * (x - 2) * (x - 3)) ) ) ; set g-stats ( replace-item i g-stats ((a - exp-a ) / (var-a )) ) ; ; Testing: type "type-" + i + ": n=" + n + " actual-g=" + precision a 1 + ; ; " expected-g=" + precision exp-a 1 + " g-stat=" + precision (item i g-stats) 1 print "" ; ] ; ] ;end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Turtle Methods (invoked via "ask turtles"- type commands ) to find-new-patch [ target-region target-id n-patches ] locals [i value-max xcor-max ycor-max value-list patch-set maxnear steps initial-pcolor] ; Find a new location in {target-region}. ; Search over {n-patches} randomly selected patches, and ; Select patch with highest nearby population of {target-id}-type turtles. ; If {target-id} = N-types, count all types of turtles population. ifelse (n-patches < 2) ; skip search if only 1 patch is to be checked. [ ask random-one-of patches with [(not any? turtles-here) and (region-id = target-region)] [ set xcor-max pxcor set ycor-max pycor] ] [ ; Don't search over more patches than remain open in region set n-patches min list n-patches (item target-region region-max - item target-region population) set patch-set random-n-of n-patches patches with [(region-id = target-region) and (not any? turtles-here)] set maxnear max values-from patch-set [item target-id nearby-types] ask random-one-of patch-set with [ item target-id nearby-types = maxnear] [set xcor-max pxcor set ycor-max pycor ] ] ; Note: Can't use "ask max-one-of patch-set [item target-id nearby-types] ; [set xcor-max pxcor set ycor-max pycor ]" in place of the two lines above ; because "max-one-of" (and "one-of") chooses the *first* patch from the set ; of patches ordering lexographically, by pycor and then pxcor! ;; Show "walking" turtle on slowest speed if speed = 1 [ set steps distancexy-nowrap xcor-max ycor-max set heading towardsxy-nowrap xcor-max ycor-max repeat steps [ fd 1 (set initial-pcolor pcolor) (set pcolor white) wait 0.3 (set pcolor initial-pcolor) ] set heading (heading - heading) ; rotate turtle back to zero heading ] setxy xcor-max ycor-max end to update-nearby [ x-type x-change ] ;; Updates "nearby" lists for new or old nbrs of moved/added turtle ;; Invoked by (turtle's new or old) patch ;; Value of x-change is 1 for turtle's new patch and -1 for turtle's old patch ;; 1) Update nearby-types ask neighbors with [region-id >= 1] [ set nearby-types replace-item x-type nearby-types (x-change + (item x-type nearby-types)) set nearby-types replace-item N-types nearby-types (x-change + (item N-types nearby-types)) ] end to-report nearby-populations [ pxx pyy id ] ; reports list of turtle populations [total type1 type2 ... ] nearby patch locals [ n-near ] ifelse (id = 0) ; get number of type-i nbrs (or all if type-i = 0) [ask patch pxx pyy [set n-near (count neighbors with [any? turtles-here]) ]] [ask patch pxx pyy [set n-near (count neighbors with [any? turtles-here with [own-type = id ]]) ]] report n-near end to set-type-id [type-id] ;; changes turtle's type to value of {type-id} set own-type type-id end to empower-turtle [xpower] ;; Creates a "superstar" agent with "xpower" times normal "pull". ;; Procedures also turns on individualized (rand-wgts) weighting, ;; because "superstar" impact occurs through "rnd-type" effect. loop [ if (mouse-down?) [ ifelse (not any? turtles-at mouse-xcor mouse-ycor) [stop] [ ask one-of turtles-at mouse-xcor mouse-ycor [ ; Revise following code block so that (re-)clicking on a superstar ; normalizes him by (re-)setting his rnd-type to [1 ... 1]. without-interruption [ foreach [0 1 2 3 4 5 6] [ set rnd-type replace-item ? rnd-type xpower set shape "superstar" ] ] ] set rand-wgts true stop ] ] ] end to recolor-turtle ;; changes turtle's color and shape based on its current rate and type (and program's current color-mode) ;; Base color on own-type and shading on own-rate. ;; Previously used: "set color ... + int(8 * own-rate) - 4" in place of "set color scale-color ..." ;; To set rate-based (circular) size: "set shape item (int(7.9 * own-rate)) turtle-size-list" if color-mode = 0 [set color scale-color gray (.5 * own-type) 0 1 ] if color-mode = 1 [set color (item own-type type-colors) ] if color-mode = 2 [set color scale-color (item own-type type-colors) (.2 + .75 * own-rate) 0 1] ;; Set turtle shape based on type unless it is an "empowered" super-turtle: ifelse (item 0 rnd-type >= 5) [set shape "superstar"] [set shape item own-type type-shapes] end to display-original-color ;; changes turtle's color based on its original rate and type (and program's current color-mode) ;; does not alter turtle's actual rate and type, stored in "own-type" and "own-rate". ;; Base color on own-type and shading on own-rate. if color-mode = 0 [set color scale-color gray (.3 + .5 * (item 3 (item 0 t-history))) 0 1 ] if color-mode = 1 [set color (item (item 3 (item 0 t-history)) type-colors) ] if color-mode = 2 [set color scale-color (item (item 3 (item 0 t-history)) type-colors) (.2 + .75 * (item 2 (item 0 t-history))) 0 1 ] end to restore-type ;; changes turtle's type, rate, and color back to original values. set-type-id (item 3 (item 0 t-history)) if no-rates != 1 [ set own-rate (item 2 (item 0 t-history)) if (rand-wgts = 1) [set own-rate own-rate * (item 0 rnd-rate)] ] recolor-turtle end to restore-position ;; moves turtle back to original patch (but retains all other attributes) set xcor (item 0 (item 0 t-history)) ; set xcor birth-xcor set ycor (item 1 (item 0 t-history)) ; set ycor birth-ycor end to recompute-nearby ;; When called by any patch on main board, re-computes patch's "nearby-types" list ; Invoke after altering board via restore, recall, etc. foreach types-list1 [ set nearby-types replace-item ? nearby-types (count neighbors with [region-id >= 1 and any? turtles-here with [own-type = ?]]) ] set nearby-types replace-item N-types nearby-types (sum but-last nearby-types) end to-report totals-in-region [xx] ; Recopute type-totals and rate-totals for region [xx] ; Invoke before displaying regional shares locals [type-totals-xx ] set type-totals-xx zeroN1 ; 1) Recompute type-totals: foreach types-list1 [ set type-totals-xx replace-item ? type-totals-xx (count turtles with [(own-type = ?) and (region-id = xx) ]) ] set type-totals-xx replace-item N-types type-totals-xx (sum but-last type-totals-xx) report type-totals-xx ;; 2) To recompute rate-totals: Modify code from recompute-totals. end to-report shares-in-region [xx] ; Recopute type-shares and rate-averages for region [xx] ; Invoke to display regional shares locals [type-shares-xx ] ; 1) Recompute type-totals: ; Get regional type totals from "totals-in-region" reporter set type-shares-xx totals-in-region xx if item N-types type-shares-xx > 0 [ foreach types-list1 [ set type-shares-xx replace-item ? type-shares-xx (round(1000 * (item ? type-shares-xx / item N-types type-shares-xx)) / 10) ] ] report but-last type-shares-xx ;; 2) To recompute rate-totals: Modify code from recompute-totals. end to output-regional-shares ; Uses shares-in-region reporter to output current shares by region output-type " REGIONAL SHARES (at time = " output-type period output-print ")" foreach (sublist types-list1 0 regions) [output-write shares-in-region (1 + ?)] output-print " " end to recompute-totals ; Recopute type-totals and rate-totals (used in plots) ; Invoke after altering board via restore, recall, etc. ; 1) Recompute type-totals: foreach types-list1 [set type-totals replace-item ? type-totals (count turtles with [own-type = ?])] set type-totals replace-item N-types type-totals (sum but-last type-totals) ; 2) Recompute rate-totals: if no-rates != 1 [ foreach types-list1 [set rate-totals replace-item ? rate-totals (sum values-from turtles with [own-type = ?][own-rate])] set rate-totals replace-item N-types rate-totals (sum but-last rate-totals) ] end to blink-turtle [ blink-time blink-pause blink-shape blink-color blink-pcolor ] ;; causes turtle to temporarily display a different shape, color, and patch color locals [ i actual-shape actual-color actual-pcolor blinks] set actual-shape shape set actual-color color set actual-pcolor pcolor set blinks int(blink-time / blink-pause) set i 0 while [i < blinks] [ set color blink-color set shape blink-shape set pcolor blink-pcolor wait blink-pause set color actual-color set shape actual-shape set pcolor actual-pcolor wait blink-pause set i (i + 1) ] end to add-to-history ;; Adds "snapshot" of turtle's current state to t-history list. locals [n-states] ; initialize t-history as empty list [ ] if (t-history = 0) [set t-history [ ] ] ; add sublist = [xcor,ycor,rate,type] of current turtle set t-history lput (sentence xcor (sentence ycor (sentence own-rate own-type) )) t-history ; Display number of newly saved state ask one-of turtles [set n-states length t-history - 1] ; update "num-state" counter ask patch 1 screen-edge-y [set plabel n-states set plabel-color red] end to revert-to-history [state-num] ;; Reverts turtle to position, rate, and type saved in item {state-num} ; of t-history list. set xcor item 0 (item state-num t-history) set ycor item 1 (item state-num t-history) if no-rates != 1 [set own-rate item 2 (item state-num t-history)] set own-type item 3 (item state-num t-history) recolor-turtle set current-state state-num end to set-rand-wgts [ w r ] locals [ i ] ;; Computes turtle-specific random adjustment factors that are applied to ;; the turtle-type based parameters if "rand-wgt" is on. ;; Must provide decimal bases w & r, ;; since "random" returns *discrete* numbers when base is integer. ;; Consider picking weights from bounded normal distribution or something analogous. ;; 1) Multiplicative weights for adjust-type calculations ;; uniformly distributed over [1 - w/2, 1 + w/2] ;; If rnd-type not yet initialized, set it to N+3 zeros if (rnd-type = 0) [ set rnd-type zeroN3] set i 0 while [i < (N-types + 3)] [ set rnd-type ( replace-item i rnd-type (precision (1 + (random-float w) - (w / 2)) 2) ) ;; For readability when inspecting turtles, use "precision" to round weights. ;; Rounding to 2 decimal places should not significantly affect behavior. set i (i + 1) ] ;; 2) Multiplicative weights for adjust-rate calculations, ;; uniformly distributed over [1 - r/2, 1 + r/2] ;; If rnd-type not yet initialized, set it to N+3 zeros if no-rates != 1 [ if (rnd-rate = 0) [ set rnd-rate zeroN3 ] set i 0 while [i < (N-types + 3)] [ set rnd-rate ( replace-item i rnd-rate (1 + (random-int-or-float r) - (r / 2)) ) set i (i + 1) ] ] end to adjust-type locals [totals i x largest-id largest-total current-total my-type max-possible-nbrs birth-type xx1 xx2] ; Recall matrix t-pull, elements 0 ... N-1 = cross-type conformity effects ; element N = born/base-type effect, N+1 = self/habit/last-period, N+2 = (uniform) conformity set my-type own-type set max-possible-nbrs (count neighbors with [ region-id > 0 ]) set totals zeroN ; initialize totals = [0 0 ... 0] ; i-th entry will hold "utility" from switching to type i. set birth-type (item 3 (item 0 t-history)) ; item 0 of t-history = original[pxcor pycor rate type] set i 0 ; Prepare to loop over each type ifelse (rand-wgts = true) ; Execute different versions if rand-wgts "on"/"off" ;; Random-wgts case: [ while [i < N-types] [ set x item i totals ;; 1) Include "birth" effect if i = person's "born" type if (i = birth-type)[ set x (x + (item N-types (item i t-pull)) * item N-types rnd-type) ] ;; 2) Add internal "habit" factor if i = person's current type ; plus 0-to-1 "rateX" factor for additional impact of own-rate ; Intuition re. "rateX": Higher current rate -> more incentive to stay with current type. if (i = own-type) [ set x (x + ((item (N-types + 1) (item i t-pull) * item (N-types + 1) rnd-type) + (own-rate * rateX / 100)) ) ] ;; 3) Add the "pull" from any type-i neighbors ; Recall that "copy-from-sliders" procedure adjusts t-pull coefs to take account of pull-flag-value ; Note that pull toward type-i is proportional to i's share of possbible nbrs ; Also, if rand-wgts are "on", must custom weight each neighbor's pull on people of "my-type". set x x + (sum values-from neighbors with [ (region-id > 0) and (any? turtles-here with [own-type = i]) ] [value-from one-of turtles-here [(item my-type item i t-pull) * (item my-type rnd-type) ] ]) / (max-possible-nbrs) ;; 4) Having summed up all three factors (born, habit, nbr-pull) for type-i, ; copy to item i of totals and loop to next type. set totals (replace-item i totals x) set i (i + 1) ] ] ;; No random-wgts case (same comments as above): [ while [i < N-types] [ set x item i totals if (i = birth-type)[set x (x + (item N-types (item i t-pull)) )] if (i = own-type) [ set x (x + ((item (N-types + 1) (item i t-pull) ) + (own-rate * rateX / 100)) )] ;; New (faster?) approach? ; The following "set command work only if "go" procedure has already run update-nearby procedure for old-patch ; Update-nearby for this new-patch (in "go" and "populate" and "manually-add") must run *after* adjusting type set x x + (item my-type item i t-pull) * (item i nearby-types-of patch-here) / (max-possible-nbrs) ; ;; Old (slower?) approach? ; set x x + (sum values-from neighbors with ; [ (region-id > 0) and (any? turtles-here with [own-type = i]) ] ; [value-from one-of turtles-here [(item my-type item i t-pull) ] ]) ; / (max-possible-nbrs) ; ; Debugging check for equivalence: if abs (x - xx2) > .001 [print "x = " + x + " xx2 = " + xx2 wait 2] set totals (replace-item i totals x) set i (i + 1) ] ] ;; 5) Determine which item in "totals" is greatest, and select corresponding type. ;; add random epsilon to prevent ties foreach types-list1 [ set totals replace-item ? totals ((item ? totals) + (random-float 0.0001)) ] set-type-id (position (max totals) totals) ;; 6) Update "type-totals" and "rates-totals" list ; Note that "my-type" is the original type and "own-type" is the new type if own-type != my-type [ set type-totals replace-item my-type type-totals ((item my-type type-totals) - 1) set type-totals replace-item own-type type-totals ((item own-type type-totals) + 1) ; Must also shift turtle's rate from old to new type ; (but no change in overall rate-totals): ] ; Can skip rate calculations in simple (no-rate = 1) versions of program, if no-rates != 1 [ set rate-totals replace-item my-type rate-totals (item my-type rate-totals - own-rate) set rate-totals replace-item own-type rate-totals (item own-type rate-totals + own-rate) ] end to adjust-rate [case] locals [my-type my-rate max-possible-nbrs h base-term c-term bc-term x] ;; for simple version of program, set rates = .5, recolor turtle, and skip all other calculations. if no-rates = 1 [ recolor-turtle stop] ; Identify self (for use by neighboring turtles): set my-type own-type set my-rate own-rate ;; Distinguish cases: ; Case 0 -> adding new turtle via "populate" button, ; Case 1 -> adding new turtle via mouse, and ; Case 2 -> second adjustment (after being added via populate) ; Case 3 -> moving around (via "go") ;; Set base rate term - from history in case 2, from current sliders in cases 0 and 1: ifelse (case = 2 or case = 3) [set base-term (item 2 (item 0 t-history))] [ifelse (rand-wgts = false) [set base-term (item N-types (item my-type r-copy)) ] [set base-term (item N-types rnd-rate) * (item N-types (item my-type r-copy)) ] ] ;; Compute remaining terms: ifelse (case = 0) ;; Case 0: Skip all but base-rate calculation when creating new turtles via "populate" [ set own-rate base-term ] ;; Cases 1 - 3: Otherwise, calculate interaction and habit (h) effects: [ ; In case 1 (adding turtles via mouse) omit habit effect, else get h from rate matrix: ifelse (case = 1) [set h 0] [set h (item (N-types + 1) item my-type r-copy)] ; Sum the interaction terms used in rate calculation ; (each term has form: nbr_rate * interaction_coef * rnd_wgt) ; Apply random weights only if rand-wgts slider is "on" ; Note that "copy-from-sliders" procedure properly adjusts r-copy ; interaction matrix values depending on whether the x_copy value ; is set to flag for full vs. uniform interactions set max-possible-nbrs (count neighbors with [ region-id > 0 ]) ifelse (rand-wgts = true) [set c-term (sum values-from neighbors with [ (region-id > 0) and (any? turtles-here)] [value-from one-of turtles-here [own-rate * (item my-type item own-type r-copy) * (item own-type rnd-rate) ] ]) / (max-possible-nbrs) ] [set c-term (sum values-from neighbors with [ (region-id > 0) and (any? turtles-here)] [sum values-from turtles-here [own-rate * (item my-type item own-type r-copy) ] ]) / (max-possible-nbrs) ] ;; Truncate c-term if it falls beyond [0,1]? ;; Note: Dropped because it prevents negative c-terms. ;set c-term (min (list 1 max (list 0 c-term) ) ) ; Add in base-term effect and truncate if beyond [0,1] range: set bc-term (min (list 1 max (list 0 (c-term + base-term) ) ) ) ; Take account of habit effect (which is 0 in case 1): ; Note that this also scales down the b- and c- effects ; by (1-h) so h alters speed of adjustments but not equilibrium level. set own-rate (h * own-rate) + (1 - h) * (bc-term) ] ;; Recolor turtle based on new value of own-rate: recolor-turtle ;; Finally, update overall rate statistics. But only when moving around (case 3) ; Note "my-rate" = old rate & "own-rate" = new rate if (case = 3) and (own-rate != my-rate) [ set rate-totals replace-item own-type rate-totals (item own-type rate-totals + own-rate - my-rate) set rate-totals replace-item N-types rate-totals (item N-types rate-totals + own-rate - my-rate) ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; List & Matrix Functions: ; Note that a n x m "matrix" is just a list of n-items, each of which is a m-item (sub)list to-report remove-first [x l] ; reports list {l} with first instance of {x} removed. ; works unless "$#$" already appears in the list. ; can use any string or value in place of "$#$". locals [pos] set pos position x l ifelse pos = false [ report l ] [ report remove "$#$" (replace-item pos l "$#$") ] end to-report make-constant-list [ list-length constant-value ] ; Makes list of length {list-length} with all elements equal to {constant-value} locals [i x] set i 0 set x [] while [i < list-length] [ set x lput constant-value x set i (i + 1) ] report x end to-report nm-list [n m] ; reports an entire n-by-m matrix (i.e., a list of lists) locals [i j x y] set i 0 set x [] while [i < n] [ set y [] set j 0 while [j < m] [ set y sentence y ((10 * i) + j) set j (j + 1) ] set x lput y x set i (i + 1) ] report x end to-report element [ i j mm] ; reports the ixj element of a matrix (i.e., a list of lists) report (item j (item i mm)) end to-report replace-list-element [ i mm xx] ; list-element replacement function ; works on lists, if used with "set {list-name} replace-list-element i {list-name} {new-value}" report (replace-item i mm xx) end to-report replace-matrix-element [ i j mm xx] ; matrix-element replacement function ; works on matrices, if used with "set {matrix-name} replace-matrix-element i j {matrix-name} {new-value}" report (replace-item i mm (replace-item j (item i mm) xx)) end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @#$#@#$#@ GRAPHICS-WINDOW 396 10 870 505 14 14 16.0 1 10 1 1 1 0 1 1 1 CC-WINDOW 5 803 879 898 Command Center 0 BUTTON 98 10 191 43 Start/End Setup NIL 1 T OBSERVER NIL NIL BUTTON 297 84 389 158 Run/Pause go T 1 T OBSERVER NIL NIL SLIDER 204 11 296 44 density density 1 100 75 1 1 NIL SLIDER 7 10 99 43 regions regions 0 4 2 1 1 NIL PLOT 8 50 292 200 SHARES time % 0.0 1000.0 0.0 100.0 true true PENS "red" 10.0 0 -2674135 true "green" 10.0 0 -10899396 true "blue" 10.0 0 -13345367 true "yellow" 10.0 0 -9452 true "similar" 10.0 0 -16777216 true "time-tick" 10.0 1 -7500403 false SLIDER 297 52 389 85 speed speed 1 10 10 1 1 NIL SWITCH 211 454 314 487 rand-wgts rand-wgts 1 1 -1000 SLIDER 211 421 314 454 move-rate move-rate 0 100 100 5 1 NIL BUTTON 296 11 389 44 Populate populate-region NIL 1 T OBSERVER NIL NIL BUTTON 8 423 68 479 Scenarios scenario-select NIL 1 T OBSERVER NIL NIL BUTTON 100 263 192 296 Reds add-turtles-manually 1 T 1 T OBSERVER NIL NIL BUTTON 192 264 284 298 Greens add-turtles-manually 2 T 1 T OBSERVER NIL NIL BUTTON 7 264 99 299 Blues add-turtles-manually 0 T 1 T OBSERVER NIL NIL BUTTON 286 263 378 298 Yellows add-turtles-manually 3 T 1 T OBSERVER NIL NIL SLIDER 100 231 192 264 r_num r_num 0 100 70 1 1 NIL SLIDER 100 296 192 329 r_type r_type 0 1 0.3 0.1 1 NIL SLIDER 100 329 192 362 r_pull r_pull 0 2.1 1.6 0.1 1 NIL SLIDER 100 362 192 395 r_self r_self 0 1 0.3 0.01 1 NIL SLIDER 9 657 101 690 r_pull1 r_pull1 -1 1 1.0 0.1 1 NIL SLIDER 9 688 101 721 r_pull2 r_pull2 -1 1 1.0 0.1 1 NIL SLIDER 9 721 101 754 r_pull3 r_pull3 -1 1 1.0 0.1 1 NIL SLIDER 9 753 101 786 r_pull4 r_pull4 -1 1 1.0 0.1 1 NIL SLIDER 193 231 285 264 g_num g_num 0 100 0 1 1 NIL SLIDER 192 298 284 331 g_type g_type 0 1 0.3 0.1 1 NIL SLIDER 192 331 284 364 g_pull g_pull 0 2.1 1.6 0.1 1 NIL SLIDER 192 365 284 398 g_self g_self 0 1 0.3 0.1 1 NIL SLIDER 105 658 197 691 g_pull1 g_pull1 -1 1 1.0 0.1 1 NIL SLIDER 105 689 197 722 g_pull2 g_pull2 -1 1 1.0 0.1 1 NIL SLIDER 105 722 197 755 g_pull3 g_pull3 -1 1 1.0 0.1 1 NIL SLIDER 105 755 197 788 g_pull4 g_pull4 -1 1 1.0 0.1 1 NIL SLIDER 7 231 99 264 b_num b_num 0 100 30 1 1 NIL SLIDER 7 299 99 332 b_type b_type 0 1 0.3 0.1 1 NIL SLIDER 7 332 99 365 b_pull b_pull 0 2.1 1.6 0.1 1 NIL SLIDER 7 365 99 398 b_self b_self 0 1 0.3 0.01 1 NIL SLIDER 200 658 292 691 b_pull1 b_pull1 -1 1 1.0 0.1 1 NIL SLIDER 200 690 292 723 b_pull2 b_pull2 -1 1 1.0 0.1 1 NIL SLIDER 200 723 292 756 b_pull3 b_pull3 -1 1 1.0 0.1 1 NIL SLIDER 200 756 292 789 b_pull4 b_pull4 -1 1 1.0 0.1 1 NIL SLIDER 286 230 378 263 y_num y_num 0 100 0 1 1 NIL SLIDER 286 298 378 331 y_type y_type 0 1 0.3 0.1 1 NIL SLIDER 285 331 377 364 y_pull y_pull 0 2.1 1.6 0.1 1 NIL SLIDER 286 364 378 397 y_self y_self 0 1 0.3 0.01 1 NIL SLIDER 296 658 388 691 y_pull1 y_pull1 -1 1 1.0 0.1 1 NIL SLIDER 296 689 388 722 y_pull2 y_pull2 -1 1 1.0 0.1 1 NIL SLIDER 296 722 388 755 y_pull3 y_pull3 -1 1 1.0 0.1 1 NIL SLIDER 296 755 388 788 y_pull4 y_pull4 -1 1 1.0 0.1 1 NIL BUTTON 76 423 131 457 Store if item 0 population = 0 [stop]\nask turtles [add-to-history]\nset current-state value-from (turtle 0) [length t-history - 1]\noutput-type " Stored state: " output-print current-state\n NIL 1 T OBSERVER NIL NIL BUTTON 76 456 131 489 Recall if item 0 population = 0 [stop] ;; Exit if this button before any turtles are present.\nrecall-saved-state NIL 1 T OBSERVER NIL NIL BUTTON 142 422 202 476 Options options-menu-select NIL 1 T OBSERVER T NIL BUTTON 297 166 389 200 Original show-original-states\n T 1 T OBSERVER NIL NIL TEXTBOX 146 404 275 422 Additional Features: TEXTBOX 10 634 229 653 Advanced Features (type-specific "pulls"): OUTPUT 7 530 386 626 BUTTON 323 421 384 454 HELP help-menu NIL 1 T OBSERVER T NIL TEXTBOX 11 210 107 228 Agent Parameters:\n BUTTON 323 454 383 487 Superstar empower-turtle 10 NIL 1 T OBSERVER NIL NIL BUTTON 76 489 131 522 Shading toggle-color-mode NIL 1 T OBSERVER NIL NIL SLIDER 211 487 314 520 rateX rateX 0 100 0 5 1 NIL SLIDER 426 529 518 562 r_rate r_rate 0 1 0.5 0.1 1 NIL SLIDER 426 561 518 594 r_copy r_copy 0 2.1 0.0 0.1 1 NIL SLIDER 426 594 518 627 r_habit r_habit 0 1 0.0 0.1 1 NIL SLIDER 427 655 519 688 r_copy1 r_copy1 -1 1 0.0 0.1 1 NIL SLIDER 427 688 519 721 r_copy2 r_copy2 -1 1 0.0 0.1 1 NIL SLIDER 427 719 519 752 r_copy3 r_copy3 -1 1 0.0 0.1 1 NIL SLIDER 427 754 519 787 r_copy4 r_copy4 -1 1 0.0 0.1 1 NIL SLIDER 522 529 614 562 g_rate g_rate 0 1 0.5 0.1 1 NIL SLIDER 522 562 614 595 g_copy g_copy 0 2.1 0.0 0.1 1 NIL SLIDER 523 594 615 627 g_habit g_habit 0 1 0.0 0.1 1 NIL SLIDER 523 656 615 689 g_copy1 g_copy1 -1 1 0.0 0.1 1 NIL SLIDER 523 691 615 724 g_copy2 g_copy2 -1 1 0.0 0.1 1 NIL SLIDER 523 722 615 755 g_copy3 g_copy3 -1 1 0.0 0.1 1 NIL SLIDER 523 754 615 787 g_copy4 g_copy4 -1 1 0.0 0.1 1 NIL SLIDER 619 529 711 562 b_rate b_rate 0 1 0.5 0.1 1 NIL SLIDER 619 561 711 594 b_copy b_copy 0 2.1 0.0 0.1 1 NIL SLIDER 619 593 711 626 b_habit b_habit 0 1 0.0 0.1 1 NIL SLIDER 619 656 711 689 b_copy1 b_copy1 -1 1 0.0 0.1 1 NIL SLIDER 619 687 711 720 b_copy2 b_copy2 -1 1 0.0 0.1 1 NIL SLIDER 619 720 711 753 b_copy3 b_copy3 -1 1 0.0 0.1 1 NIL SLIDER 619 753 711 786 b_copy4 b_copy4 -1 1 0.0 0.1 1 NIL SLIDER 715 529 807 562 y_rate y_rate 0 1 0.5 0.1 1 NIL SLIDER 715 563 807 596 y_copy y_copy 0 2.1 0.0 0.1 1 NIL SLIDER 715 593 807 626 y_habit y_habit 0 1 0.0 0.1 1 NIL SLIDER 716 655 808 688 y_copy1 y_copy1 -1 1 0.0 0.1 1 NIL SLIDER 716 686 808 719 y_copy2 y_copy2 -1 1 0.0 0.1 1 NIL SLIDER 716 719 808 752 y_copy3 y_copy3 -1 1 0.0 0.1 1 NIL SLIDER 716 751 808 784 y_copy4 y_copy4 -1 1 0.0 0.1 1 NIL TEXTBOX 426 510 576 528 Rate controls: TEXTBOX 429 635 714 653 Advanced Features (rate-specific "copy" parameters) MONITOR 133 478 210 527 NIL similarity-all 3 1 @#$#@#$#@ MARS 1s: Multi-Agent Religion Simulation OVERVIEW: MARS is a social science simulation of religious migration and conformity created within the Netlogo programmable modeling environment. Agents and the environment they exist within are programmed constructs whose attributes and the rules they operate by are a combination of programmed algorithms, endogenous variables, and exogenous parameters. The focus of this guide is to help the user understand the model and what it simulates, and to create his or her own experiments by adjusting the observer controlled parameters and employing the full range of tools available. All are encouraged to read the story behind the model, the basics of the observer interface, and the section on getting started. The tools and techniques described in the advanced section are just that - useful to researchers with specific goals, but not necessary for most experiments. THE STORY Agents exist within a two dimensional space (lattice) not unlike a checkerboard, Divided into a number of regions set by the observer (1 – 4). Agents move randomly, exogenously driven by the program to chosen patches, and upon arrival choose whether or not to maintain their religion (color) based on their original religion (when created), current religion (the one they had before moving), the religions of each of their new neighbors (community). The choice process amounts to evaluating a utility function for each possible choice of religion, and weighting original by the "origin" parameter, current religion by the "inertia" parameter, and the influence of neighbor religions by the "community" parameters. Additionally, in more advanced models, agents have a choice to make regarding their congregation attendance, and quantity represented by shading. Attendance is our chosen variable for representation of agent religiosity, as it is the most accepted metric of religiosity and it has a clear cut community dynamic. Similar to religion selection, Attendance decisions are a utility evaluation based on original attendance, current attendance, and community attendance. QUICK START Using the Scenarios. Key sequence: Click Scenario, then click on either "Basic" "Conform" or "Resist" You may then either click Run/Pause to run it indefinitely, or Options-->Skip-ahead-n and then choose the exact number of moves for the simulation to run. Note: to replicate runs from the paper, the Recall button must be clicked twice after selecting a scenario to begin from the exact starting assortment. GETTING STARTED: What kind of agents do you want? This is for most experiments at the core of what you are trying to accomplish. There are two questions to be asked in the process: 1) How many different types (religions) of agents do you want? 2) In what relative ratios do you want them to populate your model? These preferences are both met by adjusting the parameter slider adjacent to each color button. If you would like some portion of your agents to be red, simply set the R_num¬ slider to a number greater than zero. Do this for each type you wish to be present. The ratio that will be realized in the initial conditions of your model will simply be that type’s (color’s) assigned number as a fraction of the sum pf all the _num¬ slider settings. Where do they go? Designing your environment and populating it with agents is an obviously important, and relatively straightforward task. 1) Choose your number of regions by moving the slider. You may have between one and four regions. 2) Click Start/End. Notice that if you chose multiple regions that lines of gray patches divide the lattice. 3) Choose a population density. You have between 1 and 100 percent density. 4) Click Populate. Each time you click populate a region will fill with agents to your prescribed density. If you have three regions you will have to click populate, then wait for it to fill three successive times Note: If after all regions are filled you click populate an additional time the lattice spaces unoccupied will be filled by the density percentage chosen ( ex if there are 10 unoccupied spaces and you click populate with 60% density, 6 of the remaining spaces will be filled). Once these basic parameters have been set you may run the model by clicking Run/Pause. Clicking again will pause the model, and it can be restarted by clicking it yet again. How much do they move? Agents operating within the model once it is running will be exogenously forced to move on a percentage of their turns. The move-rate¬ slider sets this percentage. What are their attributes? Finally, you wish to design your agents. For each type used within your model you have the option of assigning a set of relative values regarding the religion and attendance related attributes. This is accomplished by adjusting a series of sliders that dictate the relative strength and weaknesses of your agents in six different categories. - [j_ type] equals the utility associated with choosing to maintain (or return to) one’s type-of-origin. If zero, then the agent displays no attachment to his religious upbringing. - [k_ self] equals the utility associated with not changing one’s current type. If zero, then the agent displays no internalized “inertia” across periods. - [i_ pull] equals the “social” utility that the agent receives from neighbors who share his type. If zero, then neighbors of type-i exert no “pull” on their co-religionists. This effect is weighted by the number of type-i neighbors relative to the number of potential (not actual) neighbors. --------------------------------------------------- PROGRAMMING NOTES: MINOR BUGS: - Re. "Store" and "Recall" buttons: Stored state "1" corresponds to state never seen, nor used. It's what would happen *if* each turtle adjusted as it was dropped on board. Nice to know, but not worth computing and saving in general? Delete from "add turtles" procedure and add as a special option? Slows "populate". At the very least, should reverse displayed numbering states "0" and "1", and then suppress display of state "0" except via special command. @#$#@#$#@ default true 0 Polygon -7500403 true true 150 5 40 250 150 205 260 250 ant true 0 Polygon -7500403 true true 136 61 129 46 144 30 119 45 124 60 114 82 97 37 132 10 93 36 111 84 127 105 172 105 189 84 208 35 171 11 202 35 204 37 186 82 177 60 180 44 159 32 170 44 165 60 Polygon -7500403 true true 150 95 135 103 139 117 125 149 137 180 135 196 150 204 166 195 161 180 174 150 158 116 164 102 Polygon -7500403 true true 149 186 128 197 114 232 134 270 149 282 166 270 185 232 171 195 149 186 Polygon -7500403 true true 225 66 230 107 159 122 161 127 234 111 236 106 Polygon -7500403 true true 78 58 99 116 139 123 137 128 95 119 Polygon -7500403 true true 48 103 90 147 129 147 130 151 86 151 Polygon -7500403 true true 65 224 92 171 134 160 135 164 95 175 Polygon -7500403 true true 235 222 210 170 163 162 161 166 208 174 Polygon -7500403 true true 249 107 211 147 168 147 168 150 213 150 arrow true 0 Polygon -7500403 true true 150 0 0 150 105 150 105 293 195 293 195 150 300 150 bee true 0 Polygon -1184463 true false 151 152 137 77 105 67 89 67 66 74 48 85 36 100 24 116 14 134 0 151 15 167 22 182 40 206 58 220 82 226 105 226 134 222 Polygon -16777216 true false 151 150 149 128 149 114 155 98 178 80 197 80 217 81 233 95 242 117 246 141 247 151 245 177 234 195 218 207 206 211 184 211 161 204 151 189 148 171 Polygon -7500403 true true 246 151 241 119 240 96 250 81 261 78 275 87 282 103 277 115 287 121 299 150 286 180 277 189 283 197 281 210 270 222 256 222 243 212 242 192 Polygon -16777216 true false 115 70 129 74 128 223 114 224 Polygon -16777216 true false 89 67 74 71 74 224 89 225 89 67 Polygon -16777216 true false 43 91 31 106 31 195 45 211 Line -1 false 200 144 213 70 Line -1 false 213 70 213 45 Line -1 false 214 45 203 26 Line -1 false 204 26 185 22 Line -1 false 185 22 170 25 Line -1 false 169 26 159 37 Line -1 false 159 37 156 55 Line -1 false 157 55 199 143 Line -1 false 200 141 162 227 Line -1 false 162 227 163 241 Line -1 false 163 241 171 249 Line -1 false 171 249 190 254 Line -1 false 192 253 203 248 Line -1 false 205 249 218 235 Line -1 false 218 235 200 144 bird1 false 0 Polygon -7500403 true true 2 6 2 39 270 298 297 298 299 271 187 160 279 75 276 22 100 67 31 0 bird2 false 0 Polygon -7500403 true true 2 4 33 4 298 270 298 298 272 298 155 184 117 289 61 295 61 105 0 43 boat1 false 0 Polygon -1 true false 63 162 90 207 223 207 290 162 Rectangle -6459832 true false 150 32 157 162 Polygon -13345367 true false 150 34 131 49 145 47 147 48 149 49 Polygon -7500403 true true 158 33 230 157 182 150 169 151 157 156 Polygon -7500403 true true 149 55 88 143 103 139 111 136 117 139 126 145 130 147 139 147 146 146 149 55 boat2 false 0 Polygon -1 true false 63 162 90 207 223 207 290 162 Rectangle -6459832 true false 150 32 157 162 Polygon -13345367 true false 150 34 131 49 145 47 147 48 149 49 Polygon -7500403 true true 157 54 175 79 174 96 185 102 178 112 194 124 196 131 190 139 192 146 211 151 216 154 157 154 Polygon -7500403 true true 150 74 146 91 139 99 143 114 141 123 137 126 131 129 132 139 142 136 126 142 119 147 148 147 boat3 false 0 Polygon -1 true false 63 162 90 207 223 207 290 162 Rectangle -6459832 true false 150 32 157 162 Polygon -13345367 true false 150 34 131 49 145 47 147 48 149 49 Polygon -7500403 true true 158 37 172 45 188 59 202 79 217 109 220 130 218 147 204 156 158 156 161 142 170 123 170 102 169 88 165 62 Polygon -7500403 true true 149 66 142 78 139 96 141 111 146 139 148 147 110 147 113 131 118 106 126 71 border1 false 0 Rectangle -7500403 true true 1 0 299 299 Rectangle -16777216 true false 30 26 268 269 border2 false 0 Rectangle -7500403 true true 0 0 30 308 Rectangle -7500403 true true 270 2 300 298 Rectangle -7500403 true true 1 0 298 31 Rectangle -7500403 true true 0 269 312 308 border3 false 0 Polygon -7500403 true true 59 13 15 61 15 238 59 282 224 282 239 282 286 240 287 59 239 14 149 14 150 59 224 60 239 75 241 225 224 241 75 239 60 225 59 74 76 58 153 59 153 14 Rectangle -7500403 true true 137 15 166 59 box true 0 Polygon -7500403 true true 45 255 255 255 255 45 45 45 butterfly1 true 0 Polygon -16777216 true false 151 76 138 91 138 284 150 296 162 286 162 91 Polygon -7500403 true true 164 106 184 79 205 61 236 48 259 53 279 86 287 119 289 158 278 177 256 182 164 181 Polygon -7500403 true true 136 110 119 82 110 71 85 61 59 48 36 56 17 88 6 115 2 147 15 178 134 178 Polygon -7500403 true true 46 181 28 227 50 255 77 273 112 283 135 274 135 180 Polygon -7500403 true true 165 185 254 184 272 224 255 251 236 267 191 283 164 276 Line -7500403 true 167 47 159 82 Line -7500403 true 136 47 145 81 Circle -7500403 true true 165 45 8 Circle -7500403 true true 134 45 6 Circle -7500403 true true 133 44 7 Circle -7500403 true true 133 43 8 circle false 0 Circle -7500403 true true 35 35 230 circle0 false 0 Circle -7500403 true true 120 121 59 circle1 false 0 Circle -7500403 true true 105 103 92 circle2 false 0 Circle -7500403 true true 90 88 122 circle3 false 0 Circle -7500403 true true 76 76 148 circle4 false 0 Circle -7500403 true true 61 60 178 circle5 false 0 Circle -7500403 true true 46 45 208 circle6 true 0 Circle -7500403 true true 31 30 238 circle7 false 0 Circle -7500403 true true 16 16 269 person false 0 Circle -7500403 true true 155 20 63 Rectangle -7500403 true true 158 79 217 164 Polygon -7500403 true true 158 81 110 129 131 143 158 109 165 110 Polygon -7500403 true true 216 83 267 123 248 143 215 107 Polygon -7500403 true true 167 163 145 234 183 234 183 163 Polygon -7500403 true true 195 163 195 233 227 233 206 159 sheep false 15 Rectangle -1 true true 90 75 270 225 Circle -1 true true 15 75 150 Rectangle -16777216 true false 81 225 134 286 Rectangle -16777216 true false 180 225 238 285 Circle -16777216 true false 1 88 92 star false 0 Polygon -7500403 true true 150 0 195 105 300 150 195 195 150 300 105 195 0 150 105 105 superstar false 0 Polygon -7500403 true true 150 0 120 75 0 0 75 120 0 150 75 180 0 300 120 225 150 300 180 225 300 300 225 180 300 150 225 120 300 0 180 75 thin-arrow true 0 Polygon -7500403 true true 150 0 0 150 120 150 120 293 180 293 180 150 300 150 triangle true 0 Polygon -7500403 true true 149 14 29 211 277 210 truck-down false 0 Polygon -7500403 true true 225 30 225 270 120 270 105 210 60 180 45 30 105 60 105 30 Polygon -8630108 true false 195 75 195 120 240 120 240 75 Polygon -8630108 true false 195 225 195 180 240 180 240 225 truck-left false 0 Polygon -7500403 true true 120 135 225 135 225 210 75 210 75 165 105 165 Polygon -8630108 true false 90 210 105 225 120 210 Polygon -8630108 true false 180 210 195 225 210 210 truck-right false 0 Polygon -7500403 true true 180 135 75 135 75 210 225 210 225 165 195 165 Polygon -8630108 true false 210 210 195 225 180 210 Polygon -8630108 true false 120 210 105 225 90 210 turtle true 0 Polygon -7500403 true true 138 75 162 75 165 105 225 105 225 142 195 135 195 187 225 195 225 225 195 217 195 202 105 202 105 217 75 225 75 195 105 187 105 135 75 142 75 105 135 105 wolf false 0 Rectangle -7500403 true true 15 105 105 165 Rectangle -7500403 true true 45 90 105 105 Polygon -7500403 true true 60 90 83 44 104 90 Polygon -16777216 true false 67 90 82 59 97 89 Rectangle -1 true false 48 93 59 105 Rectangle -16777216 true false 51 96 55 101 Rectangle -16777216 true false 0 121 15 135 Rectangle -16777216 true false 15 136 60 151 Polygon -1 true false 15 136 23 149 31 136 Polygon -1 true false 30 151 37 136 43 151 Rectangle -7500403 true true 105 120 263 195 Rectangle -7500403 true true 108 195 259 201 Rectangle -7500403 true true 114 201 252 210 Rectangle -7500403 true true 120 210 243 214 Rectangle -7500403 true true 115 114 255 120 Rectangle -7500403 true true 128 108 248 114 Rectangle -7500403 true true 150 105 225 108 Rectangle -7500403 true true 132 214 155 270 Rectangle -7500403 true true 110 260 132 270 Rectangle -7500403 true true 210 214 232 270 Rectangle -7500403 true true 189 260 210 270 Line -7500403 true 263 127 281 155 Line -7500403 true 281 155 281 192 wolf-left false 3 Polygon -6459832 true true 117 97 91 74 66 74 60 85 36 85 38 92 44 97 62 97 81 117 84 134 92 147 109 152 136 144 174 144 174 103 143 103 134 97 Polygon -6459832 true true 87 80 79 55 76 79 Polygon -6459832 true true 81 75 70 58 73 82 Polygon -6459832 true true 99 131 76 152 76 163 96 182 104 182 109 173 102 167 99 173 87 159 104 140 Polygon -6459832 true true 107 138 107 186 98 190 99 196 112 196 115 190 Polygon -6459832 true true 116 140 114 189 105 137 Rectangle -6459832 true true 109 150 114 192 Rectangle -6459832 true true 111 143 116 191 Polygon -6459832 true true 168 106 184 98 205 98 218 115 218 137 186 164 196 176 195 194 178 195 178 183 188 183 169 164 173 144 Polygon -6459832 true true 207 140 200 163 206 175 207 192 193 189 192 177 198 176 185 150 Polygon -6459832 true true 214 134 203 168 192 148 Polygon -6459832 true true 204 151 203 176 193 148 Polygon -6459832 true true 207 103 221 98 236 101 243 115 243 128 256 142 239 143 233 133 225 115 214 114 wolf-right false 3 Polygon -6459832 true true 170 127 200 93 231 93 237 103 262 103 261 113 253 119 231 119 215 143 213 160 208 173 189 187 169 190 154 190 126 180 106 171 72 171 73 126 122 126 144 123 159 123 Polygon -6459832 true true 201 99 214 69 215 99 Polygon -6459832 true true 207 98 223 71 220 101 Polygon -6459832 true true 184 172 189 234 203 238 203 246 187 247 180 239 171 180 Polygon -6459832 true true 197 174 204 220 218 224 219 234 201 232 195 225 179 179 Polygon -6459832 true true 78 167 95 187 95 208 79 220 92 234 98 235 100 249 81 246 76 241 61 212 65 195 52 170 45 150 44 128 55 121 69 121 81 135 Polygon -6459832 true true 48 143 58 141 Polygon -6459832 true true 46 136 68 137 Polygon -6459832 true true 45 129 35 142 37 159 53 192 47 210 62 238 80 237 Line -16777216 false 74 237 59 213 Line -16777216 false 59 213 59 212 Line -16777216 false 58 211 67 192 Polygon -6459832 true true 38 138 66 149 Polygon -6459832 true true 46 128 33 120 21 118 11 123 3 138 5 160 13 178 9 192 0 199 20 196 25 179 24 161 25 148 45 140 Polygon -6459832 true true 67 122 96 126 63 144 x false 0 Polygon -7500403 true true 270 75 225 30 30 225 75 270 Polygon -7500403 true true 30 75 75 30 270 225 225 270 x-shape false 0 Polygon -7500403 true true 75 60 210 255 225 255 90 60 75 60 Polygon -7500403 true true 210 60 225 60 75 255 60 255 210 60 @#$#@#$#@ NetLogo 3.0beta3 @#$#@#$#@ @#$#@#$#@ @#$#@#$#@ setup set shares [70 30 0 0] copy-to-sliders populate-region set shares [30 70 0 0] copy-to-sliders populate-region recall-saved-state recall-saved-state go shares-in-region(1) shares-in-region(2) similarity-all @#$#@#$#@