;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Variable declarations ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;; globals [ grid-x-inc ;; the amount of patches in between two roads in the x direction grid-y-inc ;; the amount of patches in between two roads in the y direction acceleration ;; the constant that controls how much a car speeds up or slows down by if it is to accelerate or decelerate phase ;; keeps track of the phase clock ;; keeps track of the total times thru the go procedure num-cars-stopped ;; the number of cars that are stopped during a single pass thru the go procedure ;; patch agentsets intersections ;; agentset containing the patches that are intersections controllers ;; agentset containing the intersections that control traffic lights roads ;; agentset containing the patches that are roads Sroads ;; Southbound roads Nroads ;; Northbound roads Eroads ;; Eastbound roads Wroads ;; Westbound roads exits ;; agentset containing the patches where cars will go out of simulation if torus off gates ;; agentset containing the patches where cars will sprout from if torus off ;vgates ;; vertical gates ;hgates ;; horizontal gates Ngates ;; Northbound gates Sgates ;; Southbound gates Egates ;; Eastbound gates Wgates ;; Westbound gates destinations ;; roads that can be used as a destination for a car ;; string and list variables that hold data passed accumulated in the model run wait-data ;; list that holds the average wait time of the cars for each pass through the go procedure stopped-data ;; list that holds the number of stopped of the cars for each pass through the go procedure speed-data ;; list that holds the average speed of the cars for each pass through the go procedure cars-data ;; list that holds the number of cars for each pass through the go procedure time-data ;; list that holds the value of clock for each pass through the go procedure c-cars-data ;; list that holds the number of circulating cars for each pass through the go procedure avg-range ;; range (time steps) for plot averages (blue lines) ;; vectors for keeping averages in range stopped-avgs speed-avgs wait-avgs num-crashes ;; number of crashes ;; should next 2 be defined with "let" in cars-remove-create? cars-missing ;; number of cars missing from originally created cars-to-create ;; number of cars to be created at gates num-over-l max-over-length previous-control ;; test if the user changes the control during the same run initial-p adjust-2-lane ;; debug max-crossing-cars min-greensteps max-greensteps max-flow parked-cars ;; number of cars currently parked def-hb-value ;; default value in the history of a controller (for history-based SOTL) ;; QL-sotl & LA-sotl specifics states-thresholds default-probability ;; by default, equal chances pgs ;; length of the green period according to the decision taken max-prob ;;max value for the probability of choosing one alternative prob-limit-reward ;; max value for the probability of an alternative to be rewarded gamma dR v-state-counter ;; the current state of the controller (north-south) h-state-counter ;; the current state of the controller (east-west) ] breed [ cars car ] cars-own [ speed ;; the speed of the car v-car? ;; this will be true if the car moves vertically and false if it moves horizontally SE-car? ;; true if car is southbound OR eastbound wait-time ;; the amount of time since the last time a car has moved destination ;; the endpoint of the car's path path-length ;; distance between origin and endpoint of the path last-x last-y run-length in-intersection? parking-time ;; count of timesteps the car is going to be parked parked? ;; is the car parked? commuter? ;; is the car a commuter? home-place ;; home patch for commuters work-place ;; workplace for commuters ] patches-own [ vertical? horizontal? southbound? eastbound? northbound? westbound? bidir-h? ;; the patch belongs to a horizontally bidirectional road bidir-v? ;; the patch belongs to a vertically bidirectional road dual-lane-v? ;; the patch belong to a vertical road with 2 lanes in the same direction external-v? ;; if dual-lane, the patch is in the external lane dual-lane-h? ;; the patch belong to a horizontal road with 2 lanes in the same direction external-h? ;; if dual-lane, the patch is in the external lane dir ;; direction ;0=E , 1= S, 2= W, 3= N parking ;; if the patch is a destination, the parking place for the cars with this destination ;; intersection variables intersection? ;; this is true if the patch is at the intersection of two roads accident? ;; this is true if a crash has occurred at this intersection. this will never be true for a non-intersection patch my-row ;; this holds the row of the intersection counting from the upper left corner of the graphics window. it is -1 for patches that are not intersections. my-column ;; this holds the column of the intersection counting from the upper left corner of the graphics window. it is -1 for patches that are not intersections. intersection-dirs ;; indicates directions of streets at intersection ;0=SE , 1= SW, 2= NW, 3= NE my-controller ;; the patch that controls this intersection ;; controller variables controller? ;; this is true if the patch is the controller of an intersection green-light-v? ;; this is true if the green light is for the vertical road. otherwise, it is false. this is only true for patches that are intersections. yellow-light? ;; this is true if there is any yellow light in the intersection. otherwise, it is false. this is only true for patches that are intersections. ;p = ticks-per-cycle = period ;; for now global p q ;; translation; this holds the phase for the intersection. it is -1 for patches that are not intersections. kappa1 ;; number of cars * number of time steps waiting (north-south) kappa2 ;; number of cars * number of time steps waiting (east-west) oldkappa1 ;; number of cars * number of time steps waiting (north-south) oldkappa2 ;; number of cars * number of time steps waiting (east-west) lambda1 ;; number of tolerances reached (kappa1 reseted) lambda2 ;; number of tolerances reached (kappa2 reseted) greensteps ;; steps since last change of lights no-corr-p ;; p for no-corr method v-lights ;; agentset containing the vertical streets which hold lights ;; for the intersection h-lights ;; agentset containing the horizontal streets which hold lights ;; for the intersection v-control ;; agentset containing the vertical section of streets handled ;; by an intersection controller h-control ;; agentset containing the horizontal section of streets handled ;; by an intersection controller v-offset-n ;; vertical distance to v-control, northbound v-offset-s ;; vertical distance to v-control, southbound h-offset-e ;; horizontal distance to v-control, eastbound h-offset-w ;; horizontal distance to v-control, westbound v-height ;; intersection vertical height h-width ;; intersection horizontal width pg-v ;; period of vertical green light (north-south) pg-h ;; period of horizontal green light (east-west) ;;pg-x... could add more directions... ;; HB, HB-COMM, QL and LA specifics crossing-cars ;; number of car that crossed the intersection in this cycle v-history ;; vector for keeping crossing-cars in the last cycles (north-south) h-history ;; vector for keeping crossing-cars in the last cycles (east-west) v-cycle-count ;; number of cycles the controller has undergone (north-south) h-cycle-count ;; number of cycles the controller has undergone (east-west) car-meter? ;; true if the controller is provided with a device to measure the amount of cars traversing the intersection ;; QL and LA specifics v-action ;; the action we have chosen: 0 short cycle, 1 medium, 2 large (north-south) h-action ;; the action we have chosen: 0 short cycle, 1 medium, 2 large (east-west) v-state ;; the current state of the controller (north-south) h-state ;; the current state of the controller (east-west) v-probability ;; probability of taking an certain action being on a certain state (north-south) h-probability ;; probability of taking an certain action being on a certain state (east-west) last-v-cars-in-queue ;; average number of waiting cars in previous cycles (north-south) last-h-cars-in-queue ;; average number of waiting cars in previous cycles (east-west) v-cars-in-queue-data ;; vector for the number of waiting cars in previous cycles (north-south) h-cars-in-queue-data ;; vector for the number of waiting cars in previous cycles (east-west) num-h-decisions num-v-decisions ;; HB-COMM specifics v-neighbors ;; vector for keeping neighbor controllers (north-south) provided with a car-meter h-neighbors ;; vector for keeping neighbor controllers (east-west) provided with a car-meter v-future ;; average crossing-cars in neighbors in the last cycles (north-south) h-future ;; average crossing-cars in neighbors in the last cycles (east-west) ] ;;;;;;;;;;;;;;;;;;;;; ;; Setup Functions ;; ;;;;;;;;;;;;;;;;;;;;; to startup setup true end ;; Initialize the display by giving the global and patch variables initial values. ;; Create num-cars of cars if there are enough road patches for one car to be created per road patch. ;; Setup the plots ;; "setup false" is done by the re-run button. to setup [full-setup?] clear-all clear-output random-seed new-seed if full-setup? ;; We only want to clear the patches if we are doing a full-setup [ clear-patches ] clear-turtles clear-all-plots setup-globals full-setup? ;; First we ask the patches to draw themselves and set up a few variables setup-patches full-setup? set-default-shape cars "car" if ( number > count roads ) [ user-message (word "There are too many cars for the amount of road. " "Either increase the amount of roads by increasing the GRID-SIZE-X " "or GRID-SIZE-Y sliders, or decrease the number of cars by lowering " "the NUMBER slider.\nThe setup has stopped.") stop ] ;; Now create the cars and have each created car call the functions setup-cars and set-car-color create-cars number [ ifelse ((random 100) < %commuters) [ set commuter? true ] [ set commuter? false ] setup-cars false set-car-color record-data ] ;; give the cars an initial speed ask cars [ set-car-speed ;; pen-down ] update-list-info my-setup-plots if (movie?) [ movie-start "test-film.mov" movie-grab-view ] reset-ticks end ;; Initialize the global variables to appropriate values to setup-globals [full-setup?] set phase 0 set clock 0 set num-cars-stopped 0 set avg-range 100 set num-crashes 0 if full-setup? [ set grid-x-inc world-width / grid-size-x set grid-y-inc world-height / grid-size-y ] ;; initialize the lists and string set wait-data [] set stopped-data [] set speed-data [] set cars-data [] set time-data [] set c-cars-data [] set wait-avgs n-values avg-range [0] set stopped-avgs n-values avg-range [0] set speed-avgs n-values avg-range [0] ;; length of the different states set states-thresholds [] let i 0 while [i < num-states] [ set states-thresholds lput ((i + 1) * (i + 2) / 2) states-thresholds set i (i + 1) ] set default-probability 1 / num-states ;; don't make acceleration 0.1 since we could get a rounding error and end up on a patch boundary set acceleration 0.099 if over-length? [ set num-over-l 0 set max-over-length 0 ] set previous-control control set initial-p p set adjust-2-lane 49 - 0.3 * %bidirectional - 0.04 * %2-lane ;; debug set max-crossing-cars 0 set max-greensteps 0 set min-greensteps 10000 set max-flow 0 set parked-cars 0 ;; QL ;; length of the green cycle for every action set pgs [] set pgs lput short-cycle pgs set i 1 while [i < num-states] [ set pgs lput ((last pgs) + (i * cycle-leap)) pgs set i (i + 1) ] set def-hb-value round ((p * mingreen) / (aggressiveness * 2)) set max-prob 0.95 set prob-limit-reward (max-prob - alpha) / (1 - alpha) set gamma 0.2 set dR 0.25 set h-state-counter n-values num-states [0] set v-state-counter n-values num-states [0] end ;; Make the patches have appropriate colors, setup the roads and intersections agentsets, ;; and initialize the traffic lights to one setting to setup-patches [full-setup?] if full-setup? [ ;; initialize the patch-own variables and color the patches to a base-color ask patches [ set intersection? false set controller? false set accident? false set green-light-v? true set yellow-light? false set my-row -1 set my-column -1 set q -1 set no-corr-p -1 set intersection-dirs -1 set dir -1 set southbound? false set eastbound? false set northbound? false set westbound? false set vertical? false set horizontal? false set bidir-h? false set bidir-v? false set dual-lane-v? false set external-v? false set dual-lane-h? false set external-h? false set car-meter? false set pcolor brown + 3 ] ;; initialize the global variables that hold patch agentsets ;0=E , 1= S, 2= W, 3= N ask patches with [ pycor = max-pycor ] [ set horizontal? true set eastbound? true set dir 0 ] ask patches with [ pxcor = max-pxcor ] [ set vertical? true set southbound? true set dir 1 ] ask patches with [ pycor = min-pycor ] [ set horizontal? true set westbound? true set dir 2 ] ask patches with [ pxcor = min-pxcor ] [ set vertical? true set northbound? true set dir 3 ] let posx min-pxcor + 1 while [posx < max-pxcor] [ if (floor ((posx + max-pxcor) mod grid-x-inc) = 0) [ ifelse ((random 100) < %bidirectional) [ ask patches with [ pxcor = posx ] [ set vertical? true set northbound? true set dir 3 set bidir-v? true ] if ((random 100) < %2-lane) [ ask patches with [ pxcor = posx ] [ set dual-lane-v? true ] ask patches with [ pxcor = posx + 1 ] [ set vertical? true set northbound? true set dir 3 set bidir-v? true set dual-lane-v? true set external-v? true ] ] ask patches with [ pxcor = posx - 1 ] [ set vertical? true set southbound? true set dir 1 set bidir-v? true ] if ((random 100) < %2-lane) [ ask patches with [ pxcor = posx - 1 ] [ set dual-lane-v? true ] ask patches with [ pxcor = posx - 2 ] [ set vertical? true set southbound? true set dir 1 set bidir-v? true set dual-lane-v? true set external-v? true ] ] ] [ ifelse ((floor ((posx + max-pxcor) / grid-x-inc ) mod 2) = 0) [ ask patches with [ pxcor = posx ] [ set vertical? true set northbound? true set dir 3 ] if ((random 100) < %2-lane) [ ask patches with [ pxcor = posx ] [ set dual-lane-v? true ] ask patches with [ pxcor = posx + 1 ] [ set vertical? true set northbound? true set dir 3 set dual-lane-v? true set external-v? true ] ] ] [ ask patches with [ pxcor = posx ] [ set vertical? true set southbound? true set dir 1 ] if ((random 100) < %2-lane) [ ask patches with [ pxcor = posx ] [ set dual-lane-v? true ] ask patches with [ pxcor = posx - 1 ] [ set vertical? true set southbound? true set dir 1 set dual-lane-v? true set external-v? true ] ] ] ] ] set posx (posx + 1) ] let posy min-pycor + 1 while [posy < max-pycor] [ if (floor ((posy + max-pycor) mod grid-y-inc) = 0) [ ifelse ((random 100) < %bidirectional) [ ask patches with [ pycor = posy ] [ set horizontal? true set westbound? true set dir 2 set bidir-h? true ] if ((random 100) < %2-lane) [ ask patches with [ pycor = posy ] [ set dual-lane-h? true ] ask patches with [ pycor = posy + 1 ] [ set horizontal? true set westbound? true set dir 2 set bidir-h? true set dual-lane-h? true set external-h? true ] ] ask patches with [ pycor = posy - 1 ] [ set horizontal? true set eastbound? true set dir 0 set bidir-h? true ] if ((random 100) < %2-lane) [ ask patches with [ pycor = posy - 1 ] [ set dual-lane-h? true ] ask patches with [ pycor = posy - 2 ] [ set horizontal? true set eastbound? true set dir 0 set bidir-h? true set dual-lane-h? true set external-h? true ] ] ] [ ifelse ((floor ((posy + max-pycor) / grid-y-inc ) mod 2) = 0) [ ask patches with [ pycor = posy ] [ set horizontal? true set westbound? true set dir 2 ] if ((random 100) < %2-lane) [ ask patches with [ pycor = posy ] [ set dual-lane-h? true ] ask patches with [ pycor = posy + 1 ] [ set horizontal? true set westbound? true set dir 2 set dual-lane-h? true set external-h? true ] ] ] [ ask patches with [ pycor = posy ] [ set horizontal? true set eastbound? true set dir 0 ] if ((random 100) < %2-lane) [ ask patches with [ pycor = posy ] [ set dual-lane-h? true ] ask patches with [ pycor = posy - 1 ] [ set horizontal? true set eastbound? true set dir 0 set dual-lane-h? true set external-h? true ] ] ] ] ] set posy ( posy + 1 ) ] set roads patches with [ (horizontal?) or (vertical?) ] set intersections roads with [ (horizontal?) and (vertical?) ] set controllers intersections with [ (((floor ((pxcor + max-pxcor) mod grid-x-inc) = 0) and (floor ((pycor + max-pycor) mod grid-y-inc) = 0)) or ((floor ((pxcor + max-pxcor) mod grid-x-inc) = 0) and (pycor = max-pycor)) or ((pxcor = max-pxcor) and (floor ((pycor + max-pycor) mod grid-y-inc) = 0))) and ( not (((pxcor = min-pxcor) or (pxcor = max-pxcor)) and ((pycor = min-pycor) or (pycor = max-pycor)))) ;; not corner ] set Sroads roads with [ vertical? and southbound? ] set Nroads roads with [ vertical? and northbound? ] set Eroads roads with [ horizontal? and eastbound? ] set Wroads roads with [ horizontal? and westbound? ] set exits roads with [ ((southbound? and (pycor = min-pycor)) or (northbound? and (pycor = max-pycor)) or (eastbound? and (pxcor = max-pxcor)) or (westbound? and (pxcor = min-pxcor))) and ( not (((pxcor = min-pxcor) or (pxcor = max-pxcor)) and ((pycor = min-pycor) or (pycor = max-pycor)))) ;; not corner ] set gates roads with [ ((southbound? and (pycor = max-pycor)) or (northbound? and (pycor = min-pycor)) or (eastbound? and (pxcor = min-pxcor)) or (westbound? and (pxcor = max-pxcor))) and ( not (((pxcor = min-pxcor) or (pxcor = max-pxcor)) and ((pycor = min-pycor) or (pycor = max-pycor)))) ;; not corner ] set Sgates gates with [ southbound? ] set Ngates gates with [ northbound? ] set Egates gates with [ eastbound? ] set Wgates gates with [ westbound? ] ;; We choose the car's destinations at random, but, in order to be able to ;; park cars, the destination cannot be in the internal lane of a dual-lane ;; bidirectional road set destinations roads with [ ((not bidir-v?) or (not dual-lane-v?) or (external-v?)) and ((not bidir-h?) or (not dual-lane-h?) or (external-h?)) ] ask roads [ set pcolor white ] ask gates [ set pcolor pink] ask exits [ set pcolor black] ] setup-intersections full-setup? setup-controllers full-setup? setup-destinations full-setup? ; ask controllers ; [ set pcolor black] end ;; Give the intersections appropriate values for the intersection?, my-row, my-column and ;; intersection-dirs patch variables. to setup-intersections [full-setup?] ask intersections [ set intersection? true if full-setup? [ set my-row floor ((pycor + max-pycor) / grid-y-inc ) set my-column floor ((pxcor + max-pxcor) / grid-x-inc ) ;intersection-dirs 0=SE , 1= SW, 2= NW, 3= NE ifelse southbound? [ ifelse eastbound? [ set intersection-dirs 0 ] [ set intersection-dirs 1 ] ] [ ifelse eastbound? [ set intersection-dirs 3 ] [ set intersection-dirs 2 ] ] ] ] end ;; Select the appropriate parking place for the destination to setup-destinations [full-setup?] if full-setup? [ ask destinations [ ;; if possible, try to select the closest patch which is not a road set parking one-of neighbors4 with [ not member? self roads ] if parking = nobody [ ;; if not (this should only happen at an intersection), try to select a ;; diagonal patch which is not a road set parking one-of neighbors with [ not member? self roads ] if parking = nobody [ type "This should never happen!!!" ] ] ] ] end to v-section [ list-lanes height ] let section [ ] let i 0 set v-lights roads at-points list-lanes set v-offset-n 0 set v-offset-s 0 foreach list-lanes [ set i 0 while [i < floor grid-y-inc - 1] [ ifelse ( item 1 ? > 0 ) [ set section lput (list ( item 0 ? ) ( item 1 ? + i) ) section ] [ set section lput (list ( item 0 ? ) ( item 1 ? - i) ) section ] set i (i + 1) ] ifelse ( item 1 ? > 0 ) [ set v-offset-n item 1 ? ask patch-at ( item 0 ? ) (item 1 ? - 1) [ set my-controller myself ] ] [ set v-offset-s item 1 ? ask patch-at ( item 0 ? ) (item 1 ? + 1) [ set my-controller myself ] ] ] set v-height height ;; set v-control sort-by [abs (item 1 ?1) < abs (item 1 ?2) ] section set v-control roads at-points section end to h-section [ list-lanes width ] let section [ ] let i 0 set h-lights roads at-points list-lanes set h-offset-e 0 set h-offset-w 0 foreach list-lanes [ set i 0 while [i < floor grid-x-inc - 1] [ ifelse ( item 0 ? > 0 ) [ set section lput (list ( item 0 ? + i) ( item 1 ? ) ) section ] [ set section lput (list ( item 0 ? - i) ( item 1 ? ) ) section ] set i (i + 1) ] ifelse ( item 0 ? > 0 ) [ set h-offset-e item 0 ? ask patch-at ( item 0 ? - 1 ) (item 1 ? ) [ set my-controller myself ] ] [ set h-offset-w item 0 ? ask patch-at ( item 0 ? + 1 ) (item 1 ? ) [ set my-controller myself ] ] ] set h-width width set h-control roads at-points section end ;; Give the intersection controllers appropriate values for the controller?, my-row, and my-column ;; patch variables. Make all the traffic lights start off so that the lights are red ;; horizontally and green vertically. to setup-controllers [full-setup?] reset-traffic-lights ask controllers [ set controller? true ;; set pcolor black if full-setup? [ if ( not (((pxcor = min-pxcor) or (pxcor = max-pxcor)) and ((pycor = min-pycor) or (pycor = max-pycor)))) [ ;; not corner ifelse bidir-h? [ ifelse bidir-v? [ ;; both bidir-h and bidir-v ifelse (dual-lane-v?) [ ifelse (dual-lane-h?) [ ifelse ([dual-lane-v?] of patch-at -1 -1) [ ifelse ([dual-lane-h?] of patch-at -1 -1) [ v-section [ [-2 2] [-1 2] [0 -3] [1 -3] ] 4 h-section [ [-3 -1] [-3 -2] [2 0] [2 1] ] 4 ] [ v-section [ [-2 2] [-1 2] [0 -2] [1 -2] ] 3 h-section [ [-3 -1] [2 0] [2 1] ] 4 ] ] [ ifelse ([dual-lane-h?] of patch-at -1 -1) [ v-section [ [-1 2] [0 -3] [1 -3] ] 4 h-section [ [-2 -1] [-2 -2] [2 0] [2 1] ] 3 ] [ v-section [ [-1 2] [0 -2] [1 -2] ] 3 h-section [ [-2 -1] [2 0] [2 1] ] 3 ] ] ] [ ifelse ([dual-lane-v?] of patch-at -1 -1) [ ifelse ([dual-lane-h?] of patch-at -1 -1) [ v-section [ [-2 1] [-1 1] [0 -3] [1 -3] ] 3 h-section [ [-3 -1] [-3 -2] [2 0] ] 4 ] [ v-section [ [-2 1] [-1 1] [0 -2] [1 -2] ] 2 h-section [ [-3 -1] [2 0] ] 4 ] ] [ ifelse ([dual-lane-h?] of patch-at -1 -1) [ v-section [ [-1 1] [0 -3] [1 -3] ] 3 h-section [ [-2 -1] [-2 -2] [2 0] ] 3 ] [ v-section [ [-1 1] [0 -2] [1 -2] ] 2 h-section [ [-2 -1] [2 0] ] 3 ] ] ] ] [ ifelse (dual-lane-h?) [ ifelse ([dual-lane-v?] of patch-at -1 -1) [ ifelse ([dual-lane-h?] of patch-at -1 -1) [ v-section [ [-2 2] [-1 2] [0 -3] ] 4 h-section [ [-3 -1] [-3 -2] [1 0] [1 1] ] 3 ] [ v-section [ [-2 2] [-1 2] [0 -2] ] 3 h-section [ [-3 -1] [1 0] [1 1] ] 3 ] ] [ ifelse ([dual-lane-h?] of patch-at -1 -1) [ v-section [ [-1 2] [0 -3] ] 4 h-section [ [-2 -1] [-2 -2] [1 0] [1 1] ] 2 ] [ v-section [ [-1 2] [0 -2] ] 3 h-section [ [-2 -1] [1 0] [1 1] ] 2 ] ] ] [ ifelse ([dual-lane-v?] of patch-at -1 -1) [ ifelse ([dual-lane-h?] of patch-at -1 -1) [ v-section [ [-2 1] [-1 1] [0 -3] ] 3 h-section [ [-3 -1] [-3 -2] [1 0] ] 3 ] [ v-section [ [-2 1] [-1 1] [0 -2] ] 2 h-section [ [-3 -1] [1 0] ] 3 ] ] [ ifelse ([dual-lane-h?] of patch-at -1 -1) [ v-section [ [-1 1] [0 -3] ] 3 h-section [ [-2 -1] [-2 -2] [1 0] ] 2 ] [ v-section [ [-1 1] [0 -2] ] 2 h-section [ [-2 -1] [1 0] ] 2 ] ] ] ] ] [ ;; bidir-h and not bidir-v ifelse (intersection-dirs = 1)[;SW ifelse (dual-lane-v?) [ ifelse (dual-lane-h?) [ ifelse ([dual-lane-h?] of patch-at -1 -1) [ v-section [ [-1 2] [0 2] ] 4 h-section [ [-2 -1] [-2 -2] [1 0] [1 1] ] 2 ] [ v-section [ [-1 2] [0 2] ] 3 h-section [ [-2 -1] [1 0] [1 1] ] 2 ] ] [ ifelse ([dual-lane-h?] of patch-at -1 -1) [ v-section [ [-1 1] [0 1] ] 3 h-section [ [-2 -1] [-2 -2] [1 0] ] 2 ] [ v-section [ [-1 1] [0 1] ] 2 h-section [ [-2 -1] [1 0] ] 2 ] ] ] [ ifelse (dual-lane-h?) [ ifelse ([dual-lane-h?] of patch-at -1 -1) [ v-section [ [0 2] ] 4 ifelse (pxcor = max-pxcor) [ h-section [ [-1 -1] [-1 -2] ] 1 ] [ h-section [ [-1 -1] [-1 -2] [1 0] [1 1] ] 1 ] ] [ v-section [ [0 2] ] 3 ifelse (pxcor = max-pxcor) [ h-section [ [-1 -1] ] 1 ] [ h-section [ [-1 -1] [1 0] [1 1] ] 1 ] ] ] [ ifelse ([dual-lane-h?] of patch-at -1 -1) [ v-section [ [0 1] ] 3 ifelse (pxcor = max-pxcor) [ h-section [ [-1 -1] [-1 -2] ] 1 ] [ h-section [ [-1 -1] [-1 -2] [1 0] ] 1 ] ] [ v-section [ [0 1] ] 2 ifelse (pxcor = max-pxcor) [ h-section [ [-1 -1] ] 1 ] [ h-section [ [-1 -1] [1 0] ] 1 ] ] ] ] ] [ if (intersection-dirs = 2)[;NW ifelse (dual-lane-v?) [ ifelse (dual-lane-h?) [ ifelse ([dual-lane-h?] of patch-at 1 -1) [ v-section [ [0 -3] [1 -3] ] 4 h-section [ [-1 -1] [-1 -2] [2 0] [2 1] ] 2 ] [ v-section [ [0 -2] [1 -2] ] 3 h-section [ [-1 -1] [2 0] [2 1] ] 2 ] ] [ ifelse ([dual-lane-h?] of patch-at 1 -1) [ v-section [ [0 -3] [1 -3] ] 3 h-section [ [-1 -1] [-1 -2] [2 0] ] 2 ] [ v-section [ [0 -2] [1 -2] ] 2 h-section [ [-1 -1] [2 0] ] 2 ] ] ] [ ifelse (dual-lane-h?) [ ifelse ([dual-lane-h?] of patch-at 1 -1) [ v-section [ [0 -3] ] 4 ifelse (pxcor = min-pxcor) [ h-section [ [1 0] [1 1] ] 1 ] [ h-section [ [-1 -1] [-1 -2] [1 0] [1 1] ] 1 ] ] [ v-section [ [0 -2] ] 3 ifelse (pxcor = min-pxcor) [ h-section [ [1 0] [1 1] ] 1 ] [ h-section [ [-1 -1] [1 0] [1 1] ] 1 ] ] ] [ ifelse ([dual-lane-h?] of patch-at 1 -1) [ v-section [ [0 -3] ] 3 ifelse (pxcor = min-pxcor) [ h-section [ [1 0] ] 1 ] [ h-section [ [-1 -1] [-1 -2] [1 0] ] 1 ] ] [ v-section [ [0 -2] ] 2 ifelse (pxcor = min-pxcor) [ h-section [ [1 0] ] 1 ] [ h-section [ [-1 -1] [1 0] ] 1 ] ] ] ] ] ] ] ] [ ifelse bidir-v? [ ;; bidir-v and not bidir-h ifelse (intersection-dirs = 2)[;NW ifelse (dual-lane-v?) [ ifelse (dual-lane-h?) [ ifelse ([dual-lane-v?] of patch-at -1 1) [ v-section [ [-2 2] [-1 2] [0 -1] [1 -1] ] 2 h-section [ [2 0] [2 1] ] 4 ] [ v-section [ [-1 2] [0 -1] [1 -1] ] 2 h-section [ [2 0] [2 1] ] 3 ] ] [ ifelse ([dual-lane-v?] of patch-at -1 1) [ ifelse (pycor = min-pycor) [ v-section [ [-2 1] [-1 1] ] 1 ] [ v-section [ [-2 1] [-1 1] [0 -1] [1 -1] ] 1 ] h-section [ [2 0] ] 4 ] [ ifelse (pycor = min-pycor) [ v-section [ [-1 1] ] 1 ] [ v-section [ [-1 1] [0 -1] [1 -1] ] 1 ] h-section [ [2 0] ] 3 ] ] ] [ ifelse (dual-lane-h?) [ ifelse ([dual-lane-v?] of patch-at -1 1) [ v-section [ [-2 2] [-1 2] [0 -1] ] 2 h-section [ [1 0] [1 1] ] 3 ] [ v-section [ [-1 2] [0 -1] ] 2 h-section [ [1 0] [1 1] ] 2 ] ] [ ifelse ([dual-lane-v?] of patch-at -1 1) [ ifelse (pycor = min-pycor) [ v-section [ [-2 1] [-1 1] ] 1 ] [ v-section [ [-2 1] [-1 1] [0 -1] ] 1 ] h-section [ [1 0] ] 3 ] [ ifelse (pycor = min-pycor) [ v-section [ [-1 1] ] 1 ] [ v-section [ [-1 1] [0 -1] ] 1 ] h-section [ [1 0] ] 2 ] ] ] ] [ if (intersection-dirs = 3)[;NE ifelse (dual-lane-v?) [ ifelse (dual-lane-h?) [ ifelse ([dual-lane-v?] of patch-at -1 -1) [ v-section [ [-2 1] [-1 1] [0 -2] [1 -2] ] 2 h-section [ [-3 -0] [-3 -1] ] 4 ] [ v-section [ [-1 1] [0 -2] [1 -2] ] 2 h-section [ [-2 -0] [-2 -1] ] 3 ] ] [ ifelse ([dual-lane-v?] of patch-at -1 -1) [ ifelse (pycor = max-pycor) [ v-section [ [0 -1] [1 -1] ] 1 ] [ v-section [ [-2 1] [-1 1] [0 -1] [1 -1] ] 1 ] h-section [ [-3 0] ] 4 ] [ ifelse (pycor = max-pycor) [ v-section [ [0 -1] [1 -1] ] 1 ] [ v-section [ [-1 1] [0 -1] [1 -1] ] 1 ] h-section [ [-2 0] ] 3 ] ] ] [ ifelse (dual-lane-h?) [ ifelse ([dual-lane-v?] of patch-at -1 -1) [ v-section [ [-2 1] [-1 1] [0 -2] ] 2 h-section [ [-3 -0] [-3 -1] ] 3 ] [ v-section [ [-1 1] [0 -2] ] 2 h-section [ [-2 -0] [-2 -1] ] 2 ] ] [ ifelse ([dual-lane-v?] of patch-at -1 -1) [ ifelse (pycor = max-pycor) [ v-section [ [0 -1] ] 1 ] [ v-section [ [-2 1] [-1 1] [0 -1] ] 1 ] h-section [ [-3 -0] ] 3 ] [ ifelse (pycor = max-pycor) [ v-section [ [0 -1] ] 1 ] [ v-section [ [-1 1] [0 -1] ] 1 ] h-section [ [-2 -0] ] 2 ] ] ] ] ] ] [ ;; neither bidir-h nor bidir-v ifelse (intersection-dirs = 0)[;SE ifelse (dual-lane-v?) [ ifelse (dual-lane-h?) [ v-section [ [-1 1] [0 1] ] 2 h-section [ [-2 0] [-2 -1] ] 2 ] [ ifelse (pycor < max-pycor) [ v-section [ [-1 1] [0 1] ] 1 h-section [ [-2 0] ] 2 ] [ set controller? false ] ] ] [ ifelse (dual-lane-h?) [ v-section [ [0 1] ] 2 h-section [ [-1 0] [-1 -1] ] 1 ] [ ifelse (pycor < max-pycor) [ v-section [ [0 1] ] 1 h-section [ [-1 0] ] 1 ] [ set controller? false ] ] ] ] [ ifelse (intersection-dirs = 1)[;SW ifelse (dual-lane-v?) [ ifelse (dual-lane-h?) [ v-section [ [-1 2] [0 2] ] 2 h-section [ [1 0] [1 1] ] 2 ] [ v-section [ [-1 1] [0 1] ] 1 h-section [ [1 0] ] 2 ] ] [ ifelse (dual-lane-h?) [ ifelse (pxcor < max-pxcor) [ v-section [ [0 2] ] 2 h-section [ [1 0] [1 1] ] 1 ] [ set controller? false ] ] [ ifelse (pxcor < max-pxcor) [ v-section [ [0 1] ] 1 h-section [ [1 0] ] 1 ] [ set controller? false ] ] ] ] [ ifelse (intersection-dirs = 2)[;NW ifelse (dual-lane-v?) [ ifelse (dual-lane-h?) [ v-section [ [0 -1] [1 -1] ] 2 h-section [ [2 0] [2 1] ] 2 ] [ ifelse (pycor > min-pycor) [ v-section [ [0 -1] [1 -1] ] 1 h-section [ [2 0] ] 2 ] [ set controller? false ] ] ] [ ifelse (dual-lane-h?) [ v-section [ [0 -1] ] 2 h-section [ [1 0] [1 1] ] 1 ] [ ifelse (pycor > min-pycor) [ v-section [ [0 -1] ] 1 h-section [ [1 0] ] 1 ] [ set controller? false ] ] ] ] [ ;=3 ; NE ifelse (dual-lane-v?) [ ifelse (dual-lane-h?) [ v-section [ [0 -2] [1 -2] ] 2 h-section [ [-1 0] [-1 -1] ] 2 ] [ v-section [ [0 -1] [1 -1] ] 1 h-section [ [-1 0] ] 2 ] ] [ ifelse (dual-lane-h?) [ ifelse (pxcor > min-pxcor) [ v-section [ [0 -2] ] 2 h-section [ [-1 0] [-1 -1] ] 1 ] [ set controller? false ] ] [ ifelse (pxcor > min-pxcor) [ v-section [ [0 -1] ] 1 h-section [ [-1 0] ] 1 ] [ set controller? false ] ] ] ] ] ] ] ] ] ] ] set controllers controllers with [ controller? ] if ((control = "hb-sotl") or (control = "hb-comm-sotl")) [ ask controllers [ if ((random 100) < %car-meters) [ set car-meter? true ] ] ] ask controllers [ set green-light-v? true set yellow-light? false set-signal-colors setup-histories-probabilities ] end to setup-histories-probabilities set num-h-decisions 0 set num-v-decisions 0 set crossing-cars 0 set v-cycle-count 0 set h-cycle-count 0 ifelse (control = "hb-sotl") or (control = "hb-comm-sotl") [ ;; create 2 vectors of "hb-depth" values, initialized to the default hb value set v-history n-values hb-depth [def-hb-value] set h-history n-values hb-depth [def-hb-value] if (control = "hb-comm-sotl") [ set v-neighbors controllers in-radius (ceiling grid-y-inc) with [(((pycor > [pycor] of myself) and (bidir-v? or southbound?)) or ((pycor < [pycor] of myself) and (bidir-v? or northbound?))) and car-meter?] set h-neighbors controllers in-radius (ceiling grid-x-inc) with [(((pxcor > [pxcor] of myself) and (bidir-h? or westbound?)) or ((pxcor < [pxcor] of myself) and (bidir-h? or eastbound?))) and car-meter?] set v-future def-hb-value set h-future def-hb-value ] ] [ if (control = "QL-sotl") or (control = "LA-sotl") [ ;; create a vector of "n-cycles-avg" values, initialized to 0 set v-history n-values n-cycles-avg [0] set h-history n-values n-cycles-avg [0] set v-cars-in-queue-data n-values n-cycles-avg [0] set h-cars-in-queue-data n-values n-cycles-avg [0] ;; initialize QL-sotl and LA-sotl probabilities set v-state -1 set h-state -1 let i 0 let probability1 base-probabilities set v-probability probability1 while [i < num-states - 1] [ set v-probability sentence v-probability probability1 set i i + 1 ] set h-probability v-probability ] ] end ;; Initialize the car variables to appropriate values and place the car on an empty road patch. to setup-cars [unparking?] ;; car procedure set speed 0 ;; if unparking, the new origin is the old destination ifelse unparking? [ move-to destination ;; if the car is a commuter: ifelse commuter? [ ;; with excursion-probability make a trip to a different place ifelse ((random 100) < excursion-probability) [ select-destination ] [ ;; the rest of the times, interchange origin and destination ifelse destination = home-place [ set destination work-place ] [ set destination home-place ] set path-length abs ([pxcor] of destination - xcor) + abs ([pycor] of destination - ycor) set run-length 0 ] ] [ ;; if the car is not a commuter, choose a new destination select-destination ] ] [ ;; if it's a newly created car, choose an origin and a destination set wait-time 0 put-on-empty-road select-destination if commuter? [ set home-place patch-here set work-place destination ] ] ifelse intersection? [ ifelse ((random 100) < %vertical) [ set v-car? true ] [ set v-car? false ] ;intersection-dirs 0=SE , 1= SW, 2= NW, 3= NE ifelse (v-car?) [ ifelse (intersection-dirs < 2) [ set SE-car? true ] [ set SE-car? false ] ] [ ifelse (intersection-dirs = 0) or (intersection-dirs = 3) [ set SE-car? true ] [ set SE-car? false ] ] set in-intersection? true ] [ ;ifelse (floor ((pxcor + screen-edge-x - floor(grid-x-inc / 2)) mod grid-x-inc) = 0) ;dir 0=E , 1= S, 2= W, 3= N ifelse ((dir mod 2) = 1) [ set v-car? true ] ; car going in vertical direction [ set v-car? false ] ifelse (dir < 2) [ set SE-car? true ] ; car going south or east [ set SE-car? false ] set in-intersection? false ] ifelse SE-car? [ ifelse v-car? [ set heading 180 ] ; S [ set heading 90 ] ; E ] [ ifelse v-car? [ set heading 0 ] ; N [ set heading 270 ] ; W ] set parked? false end ;; Find a road patch without any cars on it and place the car there. to put-on-empty-road ;; car procedure let road 0 ifelse ((random 100) < %origin-out) [ set road one-of destinations with [ member? self gates ] ] [ ifelse commuter? [ set road one-of destinations with [ (not member? self gates) and ((abs(pxcor) > world-width / 4) or (abs(pycor) > world-height / 4)) ] ] [ set road one-of destinations with [ not member? self gates ] ] ] move-to road if any? other cars-here [ put-on-empty-road ] set last-x xcor set last-y ycor end ;; Select the endpoint of the car's path. to select-destination ;; car procedure ifelse ((random 100) < %destination-out) [ set destination one-of destinations with [ member? self exits ] ] [ ifelse commuter? [ set destination one-of destinations with [ (abs(pxcor) <= world-width / 4) and (abs(pycor) <= world-height / 4) ] ] [ set destination one-of destinations with [ not member? self exits ] ] ] set path-length abs ([pxcor] of destination - xcor) + abs ([pycor] of destination - ycor) set run-length 0 end ;; Initialize the plots to my-setup-plots set-current-plot "% Stopped Cars" set-plot-y-range 0 100 set-current-plot-pen "default" plot num-cars-stopped set-current-plot "Average Wait Time of Cars" set-current-plot-pen "default" plot mean [wait-time] of cars set-current-plot "Average Speed of Cars" set-current-plot-pen "default" set-plot-y-range 0 speed-limit plot mean [speed] of cars with [ not parked? ] set-current-plot "Number of Cars" set-current-plot-pen "default" plot count cars set-current-plot-pen "c-default" plot count cars - parked-cars end ;"uncorrelates" self-org. T.L. to reset-traffic-lights ask controllers [ set q 0 set pg-v (p / 2) set pg-h (p / 2) ;set pg-v round (p / 3) ;set pg-h round (2 * p / 3) ;set pg-v (p / 3) ;set pg-h (2 * p / 3) set kappa1 0 set kappa2 0 set lambda1 0 set lambda2 0 set greensteps 0 set no-corr-p (random (max-pxcor + 3)) if yellow-light? [set-signal-colors] set crossing-cars 0 ;; debug set max-crossing-cars 0 set max-greensteps 0 set min-greensteps 10000 set max-flow 0 ] end ;;;;;;;;;;;;;;;;;;;;;;; ;; Runtime Functions ;; ;;;;;;;;;;;;;;;;;;;;;;; ;; receives information from the clients and runs the simulation to go every delay [ ;; clear any accidents from the last time thru the go procedure clear-accidents ;; if control has changed, automatically call reset-traffic-lights if ( control != previous-control ) [ reset-traffic-lights set previous-control control set p initial-p ask controllers [ setup-histories-probabilities ] ] ;; if there are any intersections that are to switch automatically, have them change their color set-signals set num-cars-stopped 0 cars-remove-create ;; set the cars speed for this time thru the procedure, move them forward their speed, ;; record data for plotting, and set the color of the cars ;; to an appropriate color based on their speed ask cars [ if not parked? [ set-car-speed fd speed ;; if the car is at an intersection: ;; if previously, it was not at an intersection ;; the number of cars which have crossed the intersection is incremented, and ;; in the next cycle, the car "was previously at an intersection" ifelse (intersection?) [ if (not in-intersection?) [ if is-agent? my-controller [ ask my-controller [ set crossing-cars (crossing-cars + 1) ] ] set in-intersection? true ] ;; if not at an intersection, in the next cycle, the car "was not previously at an intersection" ] [ set in-intersection? false ;;ifelse ([intersection?] of patch-ahead 1) [ ifelse ([intersection?] of patch-right-and-ahead 180 1) [ ifelse v-car?[ set xcor pxcor ] [ set ycor pycor ] ] [ ifelse (pxcor = min-pxcor) or (pxcor = max-pxcor) [ if ( xcor != pxcor ) [ set xcor pxcor ] ] [ if (pycor = min-pycor) or (pycor = max-pycor) [ if ( ycor != pycor ) [ set ycor pycor ] ] ] ] ] set run-length (run-length + abs(xcor - last-x) + abs(ycor - last-y)) set last-x xcor set last-y ycor record-data set-car-color ] ] ;; crash the cars if crash? is true if crash? [ crash-cars ] if ( count cars > 0 ) [ ;; update the information in the lists of plot data update-list-info ;; update the plots with the new information from this pass thru the procedure if plots? [do-plotting] ] ;; update the clock and the phase clock-tick if (movie?) [ if ((clock mod 1000) = 0) [ movie-cancel movie-start "test-film.mov" ] movie-grab-view if ((mean [wait-time] of cars) > 60) [ movie-close stop ] ] ] end ;; Reports the base probabilities, i.e. the initial probability of an ;; intersection controller to-report base-probabilities let bprobability (list n-values num-states [ default-probability ] ) report bprobability end to park-car ;; car procedure move-to [parking] of destination set hidden? true set parked-cars (parked-cars + 1) set parking-time random (parking-time-max - parking-time-min) + parking-time-min set parked? true end to unpark-car ;; car procedure set parking-time (parking-time - 1) if (parking-time <= 0) [ if not any? cars-on destination [ setup-cars true set hidden? false set parked-cars (parked-cars - 1) ] ] end to-report at-destination? ifelse (distance destination < 1) [ report true ] [ ifelse ((v-car? and dual-lane-v? and external-v?) or (not v-car? and dual-lane-h? and external-h?)) and (distance destination < 2) [ report true ] [ report false ] ] end ;;removes leaving cars, creates incoming cars to cars-remove-create ask cars [;;if you please ifelse parked? [ unpark-car ] [ if at-destination? [ if over-length? [ let over-length run-length - path-length - 2 * (world-width + world-height) if (over-length > 0) [ set num-over-l (num-over-l + 1) if (over-length > max-over-length) [ set max-over-length over-length ] ] ] ifelse (commuter?) or ((random 100) < parking-probability) [ park-car ] [ die ;; thank you... ] ] ] ] set cars-missing ( number - count cars + parked-cars) set cars-to-create 0 if ( cars-missing > 0 ) [ set cars-to-create (round random-float (cars-missing * 1.66 )) create-cars cars-to-create [ set commuter? false setup-cars false set-car-color set-car-speed ] ] end ;; reports the amount of seconds by which to slow the model down to-report delay ifelse simulation-speed <= 0 [ report ln (10 / 0.001) ] [ report ln (10 / simulation-speed) ] end ;; have the traffic lights change color if phase equals each intersections' q to set-signals let intersections-to-change 0 let intersections-to-yellow 0 if (control = "sotl-request") [ ;;do self-org traffic lights (crappy version) ask controllers [ self-org-request ] set intersections-to-yellow controllers with [ ((q = (clock mod pg-v)) and (green-light-v?)) or ((q = (pg-v + (clock mod pg-h))) and (not green-light-v?)) ] set intersections-to-change controllers with [ ((q = ((clock - v-height) mod pg-v)) and (green-light-v?)) or ((q = (pg-v + ((clock - h-width) mod pg-h))) and (not green-light-v?)) ] ] if (control = "sotl-phase") [ ;;do self-org traffic lights ask controllers [ self-org-phase ] set intersections-to-change controllers with [ (((q + pg-h + v-height) mod p = phase) and (green-light-v?)) or (((q + h-width) mod p = phase) and (not green-light-v?)) ] set intersections-to-yellow controllers with [ (((q + pg-h) mod p = phase) and (green-light-v?)) or (((q) mod p = phase) and (not green-light-v?)) ] ] if (control = "sotl-platoon") [ ;;do self-org traffic lights ask controllers [ self-org-platoon ] set intersections-to-change controllers with [ (((q + pg-h + v-height) mod p = phase) and (green-light-v?)) or (((q + h-width) mod p = phase) and (not green-light-v?)) ] set intersections-to-yellow controllers with [ (((q + pg-h) mod p = phase) and (green-light-v?)) or (((q) mod p = phase) and (not green-light-v?)) ] ] if (control = "hb-sotl") [ ;;do history-based self-org traffic lights set intersections-to-change controllers with [ ;; if the controller is provided with a device to measure the amount of cars traversing the intersection, ;; it makes a decision based on the amount of cars which have traversed this intersection in the previous cycle ;; if not, it acts as the "marching" controllers. (green-light-v? and ((car-meter? and (greensteps = round(pg-v))) or (not car-meter? and (phase = 0)))) or (not green-light-v? and ((car-meter? and (greensteps = round(pg-h))) or (not car-meter? and (phase = 0)))) ] set intersections-to-yellow controllers with [ ;; if the controller is provided with a device to measure the amount of cars traversing the intersection, ;; it makes a decision based on the amount of cars which have traversed this intersection in the previous cycle ;; if not, it acts as the "marching" controllers. (green-light-v? and ((car-meter? and (greensteps = round(pg-v) - v-height)) or (not car-meter? and (phase = p - v-height)))) or (not green-light-v? and ((car-meter? and (greensteps = round(pg-h) - h-width)) or (not car-meter? and (phase = p - h-width)))) ] ;; in this case, the control measures take place after the decision ;; and only in those which are about to change to red ;; and if the controller is provided with a device to measure the amount of cars traversing the intersection ask intersections-to-change with [ car-meter? ] [ self-org-history ] ] if (control = "hb-comm-sotl") [ ;;do history-based self-org traffic lights set intersections-to-change controllers with [ ;; if the controller or its neighbor are provided with a device to measure the amount of cars traversing the intersection, ;; it makes a decision based on the amount of cars which have traversed this intersection in the previous cycle ;; and/or the amount of cars which have traversed the neighbor intersection in the previous cycle ;; if not, it acts as the "marching" controllers. (green-light-v? and (((car-meter? or any? v-neighbors) and (greensteps = round(pg-v))) or ((not car-meter? and not any? v-neighbors) and (phase = 0)))) or (not green-light-v? and (((car-meter? or any? h-neighbors) and (greensteps = round(pg-h))) or ((not car-meter? and not any? h-neighbors) and (phase = 0)))) ] set intersections-to-yellow controllers with [ ;; if the controller or its neighbor are provided with a device to measure the amount of cars traversing the intersection, ;; it makes a decision based on the amount of cars which have traversed this intersection in the previous cycle ;; and/or the amount of cars which have traversed the neighbor intersection in the previous cycle ;; if not, it acts as the "marching" controllers. (green-light-v? and (((car-meter? or any? v-neighbors) and (greensteps = round(pg-v) - v-height)) or ((not car-meter? and not any? v-neighbors) and (phase = p - v-height)))) or (not green-light-v? and (((car-meter? or any? h-neighbors) and (greensteps = round(pg-h) - h-width)) or ((not car-meter? and not any? h-neighbors) and (phase = p - h-width)))) ] ;; in this case, the control measures take place after the decision ;; and only in those which are about to change to red ask intersections-to-change [ self-org-comm-history ] ] if (control = "QL-sotl") [ ;;do Q Learning self-org traffic lights set intersections-to-change controllers with [ ((greensteps = round(pg-h)) and (not green-light-v?)) or ((greensteps = round(pg-v)) and (green-light-v?)) ] set intersections-to-yellow controllers with [ ((not green-light-v?) and (greensteps = round(pg-h) - h-width)) or ((green-light-v?) and (greensteps = round(pg-v) - v-height)) ] ;; in this case, the control measures take place after the decision ;; and only in those which are about to change to red ask intersections-to-change [ self-org-QL ] ] if (control = "LA-sotl") [ ;;do Q Learning self-org traffic lights set intersections-to-change controllers with [ ((greensteps = round(pg-h)) and (not green-light-v?)) or ((greensteps = round(pg-v)) and (green-light-v?)) ] set intersections-to-yellow controllers with [ ((not green-light-v?) and (greensteps = round(pg-h) - h-width)) or ((green-light-v?) and (greensteps = round(pg-v) - v-height)) ] ;; in this case, the control measures take place after the decision ;; and only in those which are about to change to red ask intersections-to-change [ self-org-LA ] ] if (control = "marching") [;; marching control set intersections-to-change controllers with [ (phase = 0) ] set intersections-to-yellow controllers with [ ((green-light-v?) and (phase = p - v-height)) or ((not green-light-v?) and (phase = p - h-width)) ] ] if (control = "optim");; optimized for south+eastbounds [;; "green-wave" control set p (max-pxcor + 3) set intersections-to-change controllers with [ (phase = round (((max-pxcor + pxcor) + (max-pycor - pycor)) / 4)) ] set intersections-to-yellow controllers with [ ((green-light-v?) and (phase = round (((max-pxcor + pxcor) + (max-pycor - pycor)) / 4) - v-height)) or ((not green-light-v?) and (phase = round (((max-pxcor + pxcor) + (max-pycor - pycor)) / 4) - h-width)) ] ] if (control = "no-corr") [;; no correlation in phases set p (max-pxcor + 3) set intersections-to-change controllers with [ phase = no-corr-p ] set intersections-to-yellow controllers with [ ((green-light-v?) and (phase = (no-corr-p - v-height) mod p)) or ((not green-light-v?) and (phase = (no-corr-p - h-width) mod p)) ] ] if (control = "cut-off") [;; turn green when WAITING queue reaches queue-cut ask controllers [ cut-off-count ] set intersections-to-change controllers with [ (q = 0) ] set intersections-to-yellow controllers with [ ((green-light-v?) and (q = ( - v-height))) or ((not green-light-v?) and (q = ( - h-width))) ] ] ask intersections-to-change [ set green-light-v? (not green-light-v?) set-signal-colors ] if (yellow?) [ ask intersections-to-yellow [ if ( member? self intersections-to-change ) [ type ">>>> " type pxcor type " " type pycor type " change and yellow "] set-signal-yellow ] ] end ;; This procedure counts waiting cars in redlight, q=0 if >=queue-cut... (for yellow) to cut-off-count ;; controller (patch) procedure let wcars 0 ifelse (q <= 0) [ set q ( q + 1 ) ] [ ; if ( not (((pxcor = min-pxcor) or (pxcor = max-pxcor)) and ; ((pycor = min-pycor) or (pycor = max-pycor)))) [ ;; not corner ifelse (green-light-v?) [ ;;red light in horizontal street if is-agentset? h-control [ set wcars (wcars + count (cars-on h-control with [ not intersection? and (((pxcor > [pxcor] of myself) and (pxcor < [pxcor] of myself + [h-offset-e] of myself + queue-cut)) or ((pxcor < [pxcor] of myself) and (pxcor > [pxcor] of myself + [h-offset-w] of myself - queue-cut))) ] )) ; if (pxcor = x) and (pycor = y) [ ask h-control with [ ; not intersection? and ; (((pxcor > pxcor-of myself) and (pxcor < pxcor-of myself + h-offset-e-of myself + queue-cut)) or ; ((pxcor < pxcor-of myself) and (pxcor > pxcor-of myself + h-offset-w-of myself - queue-cut))) ; ] [ show cars-here ] ] ] ; if (pxcor = x) and (pycor = y) [ type "wcars " print wcars ] if (wcars >= queue-cut) and (greensteps > mingreen) [ set q ( - v-height) ] ] [ ;;red light in vertical street if is-agentset? v-control [ set wcars (wcars + count (cars-on v-control with [ not intersection? and (((pycor > [pycor] of myself) and (pycor < [pycor] of myself + [v-offset-n] of myself + queue-cut)) or ((pycor < [pycor] of myself) and (pycor > [pycor] of myself + [v-offset-s] of myself - queue-cut))) ] )) ; if (pxcor = x) and (pycor = y) [ ask v-control with [ ; not intersection? and ; (((pycor > pycor-of myself) and (pycor < pycor-of myself + v-offset-n-of myself + queue-cut)) or ; ((pycor < pycor-of myself) and (pycor > pycor-of myself + v-offset-s-of myself - queue-cut))) ; ] [ show cars-here ] ] ] ; if (pxcor = x) and (pycor = y) [ type "wcars " print wcars ] if (wcars >= queue-cut) and (greensteps > mingreen) [ set q ( - h-width) ] ] ; ] ] end ;; This procedure self-organizes the pg's and q's of intersections to optimize traffic flow... to self-org-request ;; controller (patch) procedure let v-cars 0 let h-cars 0 ; if ( not (((pxcor = min-pxcor) or (pxcor = max-pxcor)) and ; ((pycor = min-pycor) or (pycor = max-pycor)))) [ ;; not corner ifelse (green-light-v?) [ ;;red light in horizontal street if is-agentset? h-control [ set h-cars (h-cars + count (cars-on h-control with [not intersection?])) ] set kappa2 (kappa2 + h-cars) if (kappa2 > tolerance) and (not yellow-light?) [ set q (clock mod pg-v) set kappa2 0 ] ] [ ;;red light in vertical street if is-agentset? v-control [ set v-cars (v-cars + count (cars-on v-control with [not intersection?])) ] set kappa1 (kappa1 + v-cars) if (kappa1 > tolerance) and (not yellow-light?) [ set q (pg-v + (clock mod pg-h)) set kappa1 0 ] ] ; ] end ;; This procedure self-organizes the pg's and q's of intersections to optimize traffic flow... to self-org-phase ;; controller (patch) procedure let v-cars 0 let h-cars 0 ; if ( not (((pxcor = min-pxcor) or (pxcor = max-pxcor)) and ; ((pycor = min-pycor) or (pycor = max-pycor)))) [ ;; not corner ifelse (not green-light-v?) [ if is-agentset? v-control [ set v-cars (v-cars + count (cars-on v-control with [not intersection?])) ] set kappa1 (kappa1 + v-cars) if (kappa1 > tolerance) and (not yellow-light?) and (greensteps > mingreen)[ set q phase adj-q set kappa1 0 set lambda1 (lambda1 + 1) if (metatolerance > 0) and (lambda1 >= metatolerance) [ ;; adjust pg's if (pg-h > 1) [ ;; should change if more than two pg's set pg-h (pg-h - 1) set pg-v (pg-v + 1) ] set lambda1 0 ] ] ] [ ;;red light in horizontal street if is-agentset? h-control [ set h-cars (h-cars + count (cars-on h-control with [not intersection?])) ] set kappa2 (kappa2 + h-cars) if (kappa2 > tolerance) and (not yellow-light?) and (greensteps > mingreen)[ set q (phase - pg-h) adj-q set kappa2 0 set lambda2 (lambda2 + 1) if (metatolerance > 0) and (lambda2 >= metatolerance) [ ;; adjust pg's if (pg-v > 1) [ ;; should change if more than two pg's set pg-v (pg-v - 1) set pg-h (pg-h + 1) ] set lambda2 0 ] ] ] ; ] end ;; This procedure self-organizes the pg's and q's of intersections to optimize traffic flow... to self-org-platoon ;; controller (patch) procedure let v-cars 0 let h-cars 0 ; if ( not (((pxcor = min-pxcor) or (pxcor = max-pxcor)) and ; ((pycor = min-pycor) or (pycor = max-pycor)))) [ ;; not corner ifelse (not green-light-v?) [ if is-agentset? v-control [ set v-cars (v-cars + count (cars-on v-control with [not intersection?])) ] if is-agentset? h-control [ set h-cars (h-cars + count (cars-on h-control with [ not intersection? and (((pxcor > [pxcor] of myself) and (pxcor < [pxcor] of myself + h-offset-e + keep-platoon)) or ((pxcor < [pxcor] of myself) and (pxcor > [pxcor] of myself + h-offset-w - keep-platoon))) ] )) ] set kappa1 (kappa1 + v-cars) if (kappa1 > tolerance) and (not yellow-light?) and (greensteps > mingreen) and ((0 = h-cars) or (h-cars >= cut-platoon))[ set q phase adj-q set kappa1 0 set lambda1 (lambda1 + 1) if (metatolerance > 0) and (lambda1 >= metatolerance) [ ;; adjust pg's if (pg-h > 1) [ ;; should change if more than two pg's set pg-h (pg-h - 1) set pg-v (pg-v + 1) ] set lambda1 0 ] ] ] [ ;;red light in horizontal street if is-agentset? h-control [ set h-cars (h-cars + count (cars-on h-control with [not intersection?])) ] if is-agentset? v-control [ set v-cars (v-cars + count (cars-on v-control with [ not intersection? and (((pycor > [pycor] of myself) and (pycor < [pycor] of myself + v-offset-n + keep-platoon)) or ((pycor < [pycor] of myself) and (pycor > [pycor] of myself + v-offset-s - keep-platoon))) ] )) ] set kappa2 (kappa2 + h-cars) if (kappa2 > tolerance) and (not yellow-light?) and (greensteps > mingreen) and ((0 = v-cars) or (v-cars >= cut-platoon))[ set q (phase - pg-h) adj-q set kappa2 0 set lambda2 (lambda2 + 1) if (metatolerance > 0) and (lambda2 >= metatolerance) [ ;; adjust pg's if (pg-v > 1) [ ;; should change if more than two pg's set pg-v (pg-v - 1) set pg-h (pg-h + 1) ] set lambda2 0 ] ] ] ; ] end ;; bounds q to adj-q ;; controller (patch) procedure if (q < 0) [ set q (q + p) ] if (q > p) [ set q (p mod q)] end ;; This procedure self-organizes the pg's and q's of intersections to optimize traffic flow... to self-org-history ;; controller (patch) procedure ifelse ( green-light-v? ) [ set v-history replace-item v-cycle-count v-history (crossing-cars) set v-cycle-count (v-cycle-count + 1) mod hb-depth let scaled-flow (aggressiveness * mean v-history) / greensteps set pg-v max ( list round (scaled-flow) mingreen ) set pg-v min ( list pg-v p ) ] [ set h-history replace-item h-cycle-count h-history (crossing-cars) set h-cycle-count (h-cycle-count + 1) mod hb-depth let scaled-flow (aggressiveness * mean h-history) / greensteps set pg-h max ( list round (scaled-flow) mingreen ) set pg-h min ( list pg-h p ) ] end ;; This procedure self-organizes the pg's and q's of intersections to optimize traffic flow... to self-org-comm-history ;; controller (patch) procedure ifelse ( green-light-v? ) [ ifelse ( car-meter? ) [ set v-history replace-item v-cycle-count v-history (crossing-cars) set v-cycle-count (v-cycle-count + 1) mod hb-depth let scaled-flow (aggressiveness * mean v-history) / greensteps ifelse ( any? v-neighbors) [ set v-future (aggressiveness * sum [mean v-history] of v-neighbors) / greensteps set pg-v max ( list round ((beta * scaled-flow + (1 - beta) * v-future)) mingreen ) ] [ set pg-v max ( list round (scaled-flow) mingreen ) ] set pg-v min ( list pg-v p ) ] [ if ( any? v-neighbors) [ set v-future (aggressiveness * sum [mean v-history] of v-neighbors) / greensteps set pg-v max ( list round (v-future) mingreen ) set pg-v min ( list pg-v p ) ] ] ] [ ifelse ( car-meter? ) [ set h-history replace-item h-cycle-count h-history (crossing-cars) set h-cycle-count (h-cycle-count + 1) mod hb-depth let scaled-flow (aggressiveness * mean h-history) / greensteps ifelse ( any? h-neighbors) [ set h-future (aggressiveness * sum [mean h-history] of h-neighbors) / greensteps set pg-h max ( list round ((beta * scaled-flow + (1 - beta) * h-future)) mingreen ) ] [ set pg-h max ( list round (scaled-flow) mingreen ) ] set pg-h min ( list pg-h p ) ] [ if ( any? h-neighbors) [ set h-future (aggressiveness * sum [mean h-history] of h-neighbors) / greensteps set pg-h max ( list round (h-future) mingreen ) set pg-h min ( list pg-h p ) ] ] ] end ;; This procedure self-organizes the pg's and q's of intersections to optimize traffic flow... to self-org-QL ;; controller (patch) procedure ; if ( not (((pxcor = min-pxcor) or (pxcor = max-pxcor)) and ; ((pycor = min-pycor) or (pycor = max-pycor)))) [ ;; not corner ifelse (green-light-v?) [ ;;red light in horizontal street set h-history replace-item h-cycle-count h-history (crossing-cars) ifelse is-agentset? h-control [ set h-cars-in-queue-data replace-item h-cycle-count h-cars-in-queue-data (count (cars-on h-control)) ] [ type "No h-control in a controller: this should never happen!!!" set h-cars-in-queue-data replace-item h-cycle-count h-cars-in-queue-data (0) ] set h-cycle-count (h-cycle-count + 1) mod n-cycles-avg if h-cycle-count = 0 [ select-h-cycle-QL mean h-cars-in-queue-data ] ] [ ;;red light in vertical street set v-history replace-item v-cycle-count v-history (crossing-cars) ifelse is-agentset? v-control [ set v-cars-in-queue-data replace-item v-cycle-count v-cars-in-queue-data (count (cars-on v-control)) ] [ type "No v-control in a controller: this should never happen!!!" set v-cars-in-queue-data replace-item v-cycle-count v-cars-in-queue-data (0) ] set v-cycle-count (v-cycle-count + 1) mod n-cycles-avg if v-cycle-count = 0 [ select-v-cycle-QL mean v-cars-in-queue-data ] ] ; ] end to select-h-cycle-QL [ h-cars-in-queue ] let old-state h-state set-h-state h-cars-in-queue ;;we set the initial value of h-state in -1, because first time we don't want a valoration if (old-state >= 0) [ valorate-last-h-action-QL old-state h-cars-in-queue ] choose-h-action-QL h-cars-in-queue set pg-h item (h-action) pgs + h-width end to set-h-state [ h-cars-in-queue ] set h-state h-cars-in-queue * (item (num-states - 1) states-thresholds) / (count h-control) let i 0 let found false while [(i < num-states) and (not found)] [ if h-state < (item i states-thresholds) [ set h-state i set found true ] set i (i + 1) ] if (not found) [ set h-state num-states - 1 ] let previous (item h-state h-state-counter) + 1 set h-state-counter replace-item (h-state) h-state-counter previous end ;;Let's choose an h-action at random to choose-h-action-QL [ h-cars-in-queue ] let rand-value (random 100) / 100 let dmQ-action n-values num-states [0] let threshold 0 let located? false ;; dmQ-action are the Q values of the current state set last-h-cars-in-queue h-cars-in-queue set dmQ-action item (h-state) h-probability let i 0 ; type "rand-value" print rand-value let dSum 0 foreach dmQ-action [ set dSum ? + dSum ];;foreach ;type "dSum: " print (dSum) foreach dmQ-action [ ;type "item value: " print (?) if (? != 0 and not located?) [ set threshold ( ? / dSum ) + threshold ;type "threshold: " print threshold ;this is the h-action we are gonna take if ( rand-value <= threshold and not located? ) [ set h-action i ;type "h-action: " print h-action set located? true ] ] set i i + 1 ];;foreach set num-h-decisions num-h-decisions + 1 end ;;here we have to valorate last h-action to valorate-last-h-action-QL [ old-state h-cars-in-queue ] let old-dmQ-action n-values num-states [0] let new-dmQ-action n-values num-states [0] let change-rate 0 let dRAux 0 ;; old-dmQ-action are the Q values of the old state set old-dmQ-action item (old-state) h-probability ;; new-dmQ-action are the Q values of the new state set new-dmQ-action item (h-state) h-probability let dMaxQS2A2 0 foreach new-dmQ-action [ if ? > dMaxQS2A2 [ set dMaxQS2A2 ? ] ] ;; if rewarding this action will lead us to overtake the min h-probability ;; we don't modify probabilities if (item h-action old-dmQ-action <= max-prob) or (item h-action old-dmQ-action >= 1 - max-prob) [ ;; the success indicator is a decrease of the number of waiting cars ;; ifelse (h-cars-in-queue <= last-h-cars-in-queue) [ ;; the success indicator is a number of crossing cars higher than the preceding number of ;; waiting cars. This needs further refinement! ;; ifelse (mean h-history >= last-h-cars-in-queue) [ ;; the success indicator is a number of crossing cars higher than the preceding number of ;; waiting cars, and a throughput higher than one car per lane and per timestep ifelse (mean h-history >= 0.5 * last-h-cars-in-queue) and (mean h-history / pg-h >= 0.025 * v-height) [ set dRAux dR ] [ set dRAux (- dR) ] let dmQa item (h-action) old-dmQ-action set change-rate (alpha * (dRAux + gamma * dMaxQS2A2 - item (h-action) old-dmQ-action)) ;; if the resulting value is lower than the minimum, we set the minimum allowed value ifelse (dmQa + change-rate < 1 - max-prob) [ set change-rate (dmQa - (1 - max-prob)) set dmQa (1 - max-prob) ] [ ;; if the resulting value is higher than the maximum, we set the maximum allowed value ifelse (dmQa + change-rate > max-prob) [ set change-rate (max-prob - dmQa) set dmQa max-prob ] [ ;; otherwise, we set the resulting value set dmQa (dmQa + change-rate) ] ] set old-dmQ-action replace-item h-action old-dmQ-action dmQa set h-probability replace-item (old-state) h-probability old-dmQ-action ] end to select-v-cycle-QL [ v-cars-in-queue ] let old-state v-state set-v-state v-cars-in-queue ;;we set the initial value of v-state in -1, because first time we don't want a valoration if (old-state >= 0) [ valorate-last-v-action-QL old-state v-cars-in-queue ] choose-v-action-QL v-cars-in-queue set pg-v item (v-action) pgs + v-height end to set-v-state [ v-cars-in-queue ] set v-state v-cars-in-queue * (item (num-states - 1) states-thresholds) / (count v-control) let i 0 let found false while [(i < num-states) and (not found)] [ if v-state < (item i states-thresholds) [ set v-state i set found true ] set i (i + 1) ] if (not found) [ set v-state num-states - 1 ] let previous (item v-state v-state-counter) + 1 set v-state-counter replace-item v-state v-state-counter previous end ;;Let's choose an h-action at random to choose-v-action-QL [ v-cars-in-queue ] let rand-value (random 100) / 100 let dmQ-action n-values num-states [0] let threshold 0 let located? false ;; dmQ-action are the Q values of the current state set last-v-cars-in-queue v-cars-in-queue set dmQ-action item (v-state) v-probability let i 0 ; type "rand-value" print rand-value let dSum 0 foreach dmQ-action [ set dSum ? + dSum ];;foreach ;type "dSum: " print (dSum) foreach dmQ-action [ ;type "item value: " print (?) if (? != 0 and not located?) [ set threshold ( ? / dSum ) + threshold ;type "threshold: " print threshold ;this is the v-action we are gonna take if ( rand-value <= threshold and not located? ) [ set v-action i ;type "v-action: " print v-action set located? true ] ] set i i + 1 ];;foreach set num-v-decisions num-v-decisions + 1 end ;;here we have to valorate last v-action to valorate-last-v-action-QL [ old-state v-cars-in-queue ] let old-dmQ-action n-values num-states [0] let new-dmQ-action n-values num-states [0] let change-rate 0 let dRAux 0 ;; old-dmQ-action are the Q values of the old state set old-dmQ-action item (old-state) v-probability ;; new-dmQ-action are the Q values of the new state set new-dmQ-action item (v-state) v-probability let dMaxQS2A2 0 foreach new-dmQ-action [ if ? > dMaxQS2A2 [ set dMaxQS2A2 ? ] ] ;; if rewarding this action will lead us to overtake the min v-probability ;; we don't modify probabilities if (item v-action old-dmQ-action <= max-prob) or (item v-action old-dmQ-action >= 1 - max-prob) [ ;; the success indicator is a decrease of the number of waiting cars ;;ifelse (v-cars-in-queue <= last-v-cars-in-queue) [ ;; the success indicator is a number of crossing cars higher than the preceding number of ;; waiting cars. This needs further refinement! ;;ifelse (mean v-history >= last-v-cars-in-queue) [ ;; the success indicator is a number of crossing cars higher than the preceding number of ;; waiting cars, and a throughput higher than one car per lane and per timestep ifelse (mean v-history >= 0.5 * last-v-cars-in-queue) and (mean v-history / pg-v >= 0.025 * h-width) [ set dRAux dR ] [ set dRAux (- dR) ] let dmQa item (v-action) old-dmQ-action set change-rate (alpha * (dRAux + gamma * dMaxQS2A2 - item (v-action) old-dmQ-action)) ;; if the resulting value is lower than the minimum, we set the minimum allowed value ifelse (dmQa + change-rate < 1 - max-prob) [ set change-rate (dmQa - (1 - max-prob)) set dmQa (1 - max-prob) ] [ ;; if the resulting value is higher than the maximum, we set the maximum allowed value ifelse (dmQa + change-rate > max-prob) [ set change-rate (max-prob - dmQa) set dmQa max-prob ] [ ;; otherwise, we set the resulting value set dmQa (dmQa + change-rate) ] ] set old-dmQ-action replace-item v-action old-dmQ-action dmQa set v-probability replace-item (old-state) v-probability old-dmQ-action ] end ;; This procedure self-organizes the pg's and q's of intersections to optimize traffic flow... to self-org-LA ;; controller (patch) procedure ; if ( not (((pxcor = min-pxcor) or (pxcor = max-pxcor)) and ; ((pycor = min-pycor) or (pycor = max-pycor)))) [ ;; not corner ifelse (green-light-v?) [ ;;red light in horizontal street set h-history replace-item h-cycle-count h-history (crossing-cars) ifelse is-agentset? h-control [ set h-cars-in-queue-data replace-item h-cycle-count h-cars-in-queue-data (count (cars-on h-control)) ] [ type "No h-control in a controller: this should never happen!!!" set h-cars-in-queue-data replace-item h-cycle-count h-cars-in-queue-data (0) ] set h-cycle-count (h-cycle-count + 1) mod n-cycles-avg if h-cycle-count = 0 [ select-h-cycle-LA mean h-cars-in-queue-data ] ] [ ;;red light in vertical street set v-history replace-item v-cycle-count v-history (crossing-cars) ifelse is-agentset? v-control [ set v-cars-in-queue-data replace-item v-cycle-count v-cars-in-queue-data (count (cars-on v-control)) ] [ type "No v-control in a controller: this should never happen!!!" set v-cars-in-queue-data replace-item v-cycle-count v-cars-in-queue-data (0) ] set v-cycle-count (v-cycle-count + 1) mod n-cycles-avg if v-cycle-count = 0 [ select-v-cycle-LA mean v-cars-in-queue-data ] ] ; ] end to select-h-cycle-LA [ h-cars-in-queue ] ;;we set the initial value of h-state in -1, because first time we don't want a valoration if (h-state >= 0) [ valorate-last-h-action-LA h-cars-in-queue ] set-h-state h-cars-in-queue choose-h-action-LA h-cars-in-queue set pg-h item (h-action) pgs + h-width end ;;Let's choose an h-action at random to choose-h-action-LA [ h-cars-in-queue ] let rand-value (random 100) / 100 let probable n-values num-states [0] let threshold 0 let located? false set last-h-cars-in-queue h-cars-in-queue set probable item (h-state) h-probability let i 0 ; type "rand-value" print rand-value foreach probable [ ;type "item value: " print (?) if (? != 0 and not located?) [ set threshold ? + threshold ;type "threshold: " print threshold ;this is the h-action we are gonna take if ( rand-value <= threshold and not located? ) [ set h-action i set located? true ] ] set i i + 1 ];;foreach set num-h-decisions num-h-decisions + 1 end ;;here we have to valorate last h-action to valorate-last-h-action-LA [ h-cars-in-queue ] let probable n-values num-states [0] let change-rate 0 ;; probable are the probabilities of the current state set probable item (h-state) h-probability ;; if rewarding this action will lead us to overtake the max probability ;; we don't modify probabilities if item h-action probable <= prob-limit-reward [ let proba 0 let i 0 let valor 0 ;; the success indicator is a decrease of the number of waiting cars ;;if (h-cars-in-queue < last-h-cars-in-queue) [ ;; the success indicator is a number of crossing cars higher than the preceding number of ;; waiting cars. This needs further refinement! ;;if (mean h-history >= last-h-cars-in-queue) [ ;; the success indicator is a number of crossing cars higher than the preceding number of ;; waiting cars, and a throughput higher than one car per lane and per timestep if (mean h-history >= 0.5 * last-h-cars-in-queue) and (mean h-history / pg-h >= 0.025 * v-height) [ foreach probable [ if (? != 0) and (? != 1) [ ;;this is our last action ifelse (i = h-action ) [ set change-rate alpha *(1 - ?) set proba ? + change-rate set probable replace-item i probable proba ] [ set proba (1 - alpha)* ? set probable replace-item i probable proba ] ] set i i + 1 ] set h-probability replace-item (h-state) h-probability probable ] ] end to select-v-cycle-LA [ v-cars-in-queue ] ;;we set the initial value of v-state in -1, because first time we don't want a valoration if (v-state >= 0) [ valorate-last-v-action-LA v-cars-in-queue ] set-v-state v-cars-in-queue choose-v-action-LA v-cars-in-queue set pg-v item (v-action) pgs + v-height end ;;Let's choose an v-action at random to choose-v-action-LA [ v-cars-in-queue ] let rand-value (random 100) / 100 let probable n-values num-states [0] let threshold 0 let located? false set last-v-cars-in-queue v-cars-in-queue set probable item (v-state) v-probability let i 0 ; type "rand-value" print rand-value foreach probable [ ;type "item value: " print (?) if (? != 0 and not located?) [ set threshold ? + threshold ;type "threshold: " print threshold ;this is the v-action we are gonna take if ( rand-value <= threshold and not located? ) [ set v-action i set located? true ] ] set i i + 1 ];;foreach set num-v-decisions num-v-decisions + 1 end ;;here we have to valorate last v-action to valorate-last-v-action-LA [ v-cars-in-queue ] let probable n-values num-states [0] let change-rate 0 ;; probable are the probabilities of the current state set probable item (v-state) v-probability ;; if rewarding this action will lead us to overtake the max probability ;; we don't modify probabilities if item v-action probable <= prob-limit-reward [ let proba 0 let i 0 let valor 0 ;; the success indicator is a decrease of the number of waiting cars ;; if (v-cars-in-queue < last-v-cars-in-queue) [ ;; the success indicator is a number of crossing cars higher than the preceding number of ;; waiting cars. This needs further refinement! ;;if (mean v-history >= last-v-cars-in-queue) [ ;; the success indicator is a number of crossing cars higher than the preceding number of ;; waiting cars, and a throughput higher than one car per lane and per timestep if (mean v-history >= 0.5 * last-v-cars-in-queue) and (mean v-history / pg-v >= 0.025 * h-width) [ foreach probable [ if (? != 0) and (? != 1) [ ;;this is our last action ifelse (i = v-action ) [ set change-rate alpha *(1 - ?) set proba ? + change-rate set probable replace-item i probable proba ] [ set proba (1 - alpha)* ? set probable replace-item i probable proba ] ] set i i + 1 ] set v-probability replace-item (v-state) v-probability probable ] ] end ;; This procedure checks the variable green-light-v? at each intersection and sets the ;; traffic lights to have the green light up or the green light to the left. to set-signal-colors ;; controller (patch) procedure ; if ( not (((pxcor = min-pxcor) or (pxcor = max-pxcor)) and ; ((pycor = min-pycor) or (pycor = max-pycor)))) [ ;; not corner ifelse power? [ ;; debug if crossing-cars > max-crossing-cars [ set max-crossing-cars crossing-cars ] if greensteps > max-greensteps [ set max-greensteps greensteps ] if greensteps != 0 [ if greensteps < min-greensteps [ set min-greensteps greensteps ] if (crossing-cars / greensteps) > max-flow [ set max-flow crossing-cars / greensteps ] ] set crossing-cars 0 set yellow-light? false set greensteps 0 ifelse green-light-v? [ if is-agentset? v-lights [ ask v-lights [ set pcolor green ] ] if is-agentset? h-lights [ ask h-lights [ set pcolor red ] ] ] [ if is-agentset? v-lights [ ask v-lights [ set pcolor red ] ] if is-agentset? h-lights [ ask h-lights [ set pcolor green ] ] ] ] [ if is-agentset? v-lights [ ask v-lights [ set pcolor white ] ] if is-agentset? h-lights [ ask h-lights [ set pcolor white ] ] ] ; ] end ;; to set-yellow-lights to set-signal-yellow ;; controller (patch) procedure ; if ( not (((pxcor = min-pxcor) or (pxcor = max-pxcor)) and ; ((pycor = min-pycor) or (pycor = max-pycor)))) [ ;; not corner ifelse power? [ set yellow-light? true ifelse green-light-v? [ if is-agentset? v-lights [ ask v-lights [ set pcolor yellow ] ] if is-agentset? h-lights [ ask h-lights [ set pcolor red ] ] ] [ if is-agentset? v-lights [ ask v-lights [ set pcolor red ] ] if is-agentset? h-lights [ ask h-lights [ set pcolor yellow ] ] ] ] [ if is-agentset? v-lights [ ask v-lights [ set pcolor white ] ] if is-agentset? h-lights [ ask h-lights [ set pcolor white ] ] ] ; ] end ;; set any intersection's color that had an accident back to white and make accident? false to clear-accidents if crash? [ ask patches with [accident?] [ set pcolor white set accident? false ] ] end ;; set the cars' speed based on whether they are at a red traffic light or the speed of the ;; car (if any) on the patch in front of them to set-car-speed ;; car procedure ifelse (pcolor = red) or (pcolor = yellow) [ set speed 0 move-to patch-here ;; move to center of the patch ] [ if intersection? [ ifelse ( wait-time <= deadlock-limit ) [ guide-car ] [ resolve-deadlock ] ] ifelse v-car?[ ifelse SE-car? [ set-speed 0 -1 ] ;S [ set-speed 0 1 ] ;N ][ ifelse SE-car? [ set-speed 1 0 ] ;E [ set-speed -1 0 ] ;w ] ] end ;; set the speed variable of the car to an appropriate value (not exceeding the ;; speed limit) based on whether there are cars on the patch in front of the car to set-speed [delta-x delta-y] ;; car procedure let up-cars?-ahead 0 let cars-ahead 0 ;; get the cars on the patch in front of the car ask patch-at delta-x delta-y [ set cars-ahead cars-here ] ;; if there are cars in front of the car, slow down ;; otherwise, speed up ifelse any? cars-ahead [ set up-cars?-ahead [v-car?] of cars-ahead ifelse member? v-car? up-cars?-ahead and member? (not v-car?) up-cars?-ahead [ if not crash? [ set speed 0 ] ] [ set speed [speed] of one-of cars-ahead slow-down ] ] [ speed-up ] end ;; decrease the speed of the car to slow-down ;; car procedure set speed speed - acceleration if speed < 0 ;;if speed < 0 [ set speed 0 ] end ;; increase the speed of the car to speed-up ;; car procedure set speed speed + acceleration if speed > speed-limit [ set speed speed-limit ] end ;; set the color of the car to a different color based on how fast the car is moving to set-car-color ;; car procedure ifelse speed < (speed-limit / 2) [ set color blue ] [ set color cyan - 2 ] ;; if over-length? [ ;; if (run-length > path-length + 2 * (world-width + world-height)) [ ;; pen-down ;; set color red ;; ] ;; ] end ;; The 4 following reporters force the cars to use dual-lanes in a balanced way. ;; In an intersection, if the car has to turn, it does so: ;; - always, if the new direction is single lane ;; - with a 50% probability, if the new direction is dual lane, and the car is in ;; the first lane it finds in the intersection ;; - always, if the new direction is dual lane, and the car is in the second lane ;; (obviously, it only reaches this point in the 50% of the cases) ;; If changing from Northbound to Eastbound, or from Southbound to Westbound, ;; first lane is the external, and second lane is the internal to-report h-turn-ei? report (not dual-lane-h?) or (dual-lane-h? and external-h? and ((random 100) < adjust-2-lane)) or (dual-lane-h? and not external-h?) end ;; If changing from Westbound to Northbound, or from Eastbound to Southbound, ;; first lane is the external, and second lane is the internal to-report v-turn-ei? report (not dual-lane-v?) or (dual-lane-v? and external-v? and ((random 100) < adjust-2-lane)) or (dual-lane-v? and not external-v?) end ;; If changing from Northbound to Westbound, or from Southbound to Eastbound, ;; first lane is the internal, and second lane is the external to-report h-turn-ie? report (not dual-lane-h?) or (dual-lane-h? and not external-h? and ((random 100) < (100 - adjust-2-lane))) or (dual-lane-h? and external-h?) end ;; If changing from Westbound to Southbound, or from Eastbound to Northbound, ;; first lane is the internal, and second lane is the external to-report v-turn-ie? report (not dual-lane-v?) or (dual-lane-v? and not external-v? and ((random 100) < (100 - adjust-2-lane))) or (dual-lane-v? and external-v?) end ;; changes direction of car at intersection if necessary to guide-car ;; car procedure slow-down ;; if over-length? [ ;; if (run-length > path-length + 2 * (world-width + world-height)) [ ;; type pxcor type " " type pycor type " -> " type [pxcor] of destination type " " print [pycor] of destination ;; ] ;; ] ;; if moving vertically ifelse v-car? [ ;; if this vertical street is bidirectional ifelse bidir-v? [ ;; if moving to the south ifelse (SE-car?) [ ;; if intersecting street is westbound if (westbound?) [ if (([pycor] of destination >= pycor) and (pxcor > min-pxcor) and (h-turn-ei?)) [ set SE-car? false set heading 270 ;->W set v-car? false ] ] ] [ ;; else (moving to the north) ;; if intersecting street is eastbound if (eastbound?) [ if (([pycor] of destination <= pycor) and (pxcor < max-pxcor) and (h-turn-ei?)) [ set SE-car? true set heading 90 ;->E set v-car? false ] ] ] ] [ ;; else this vertical street is not bidirectional ;; if moving to the south ifelse (SE-car?) [ ;; if intersecting street is eastbound ifelse (eastbound?) [ if (((([pycor] of destination >= pycor) and ([pxcor] of destination >= pxcor)) or (pycor = min-pycor) ) and (pxcor < max-pxcor) and (h-turn-ie?) ) [ set SE-car? true set heading 90 ;->E set v-car? false ] ] [ ;; else (street is westbound) if (((([pycor] of destination >= pycor) and ([pxcor] of destination <= pxcor)) or (pycor = min-pycor) ) and (pxcor > min-pxcor) and (h-turn-ei?) ) [ set SE-car? false set heading 270 ;->W set v-car? false ] ] ] [ ;; else (moving to the north) ;; if intersecting street is eastbound ifelse (eastbound?) [ if (((([pycor] of destination <= pycor) and ([pxcor] of destination >= pxcor)) or (pycor = max-pycor) ) and (pxcor < max-pxcor) and (h-turn-ei?) ) [ set SE-car? true set heading 90 ;->E set v-car? false ] ] [ ;; else (street is westbound) if (((([pycor] of destination <= pycor) and ([pxcor] of destination <= pxcor)) or (pycor = max-pycor) ) and (pxcor > min-pxcor) and (h-turn-ie?) ) [ set SE-car? false set heading 270 ;->W set v-car? false ] ] ] ] ] [ ;; else (moving horizontally) ;; if this horizontal street is bidirectional ifelse bidir-h? [ ;; if moving to the east ifelse (SE-car?) [ ;; if intersecting street is southbound if (southbound?) [ if (([pxcor] of destination <= pxcor) and (pycor > min-pycor) and (v-turn-ei?)) [ set SE-car? true set heading 180 ;->S set v-car? true ] ] ] [ ;; else (moving to the west) ;; if intersecting street is northbound if (northbound?) [ if (([pxcor] of destination >= pxcor) and (pycor < max-pycor) and (v-turn-ei?)) [ set SE-car? false set heading 0 ;->N set v-car? true ] ] ] ] [ ;; else this horizontal street is not bidirectional ;; if moving to the east ifelse (SE-car?) [ ;; if intersecting street is southbound ifelse (southbound?) [ if (((([pxcor] of destination <= pxcor) and ([pycor] of destination <= pycor)) or (pxcor = max-pxcor) ) and (pycor > min-pycor) and (v-turn-ei?) ) [ set SE-car? true set heading 180 ;->S set v-car? true ] ] [ ;; else (street is northbound) if (((([pxcor] of destination <= pxcor) and ([pycor] of destination >= pycor)) or (pxcor = max-pxcor) ) and (pycor < max-pycor) and (v-turn-ie?) ) [ set SE-car? false set heading 0 ;->N set v-car? true ] ] ] [ ;; else (moving to the west) ;; if intersecting street is southbound ifelse (southbound?) [ if (((([pxcor] of destination >= pxcor) and ([pycor] of destination <= pycor)) or (pxcor = min-pxcor) ) and (pycor > min-pycor) and (v-turn-ie?) ) [ set SE-car? true set heading 180 ;->S set v-car? true ] ] [ ;; else (street is northbound) if (((([pxcor] of destination >= pxcor) and ([pycor] of destination >= pycor)) or (pxcor = min-pxcor) ) and (pycor < max-pycor) and (v-turn-ei?) ) [ set SE-car? false set heading 0 ;->N set v-car? true ] ] ] ] ] end ;; resolves a deadlock condition to resolve-deadlock ;; car procedure ;; if moving vertically ifelse v-car? [ ;; if intersecting street is westbound, and there are no cars westbound if (westbound?) and (pxcor > min-pxcor) and ((count (cars-at (-1) 0 )) = 0) [ set SE-car? false set heading 270 ;->W set v-car? false ;; watch-me ;; type clock type ": (" type mean [wait-time] of cars type " -> " type who print " resolving deadlock" ] ;; if intersecting street is eastbound, and there are no cars eastbound if (eastbound?) and (pxcor < max-pxcor) and ((count (cars-at 1 0 )) = 0) [ set SE-car? true set heading 90 ;->E set v-car? false ;; watch-me ;; type clock type ": (" type mean [wait-time] of cars type " -> " type who print " resolving deadlock" ] ] [ ;; else (moving horizontally) ;; if intersecting street is southbound, and there are no cars southbound if (southbound?) and (pycor > min-pycor) and ((count (cars-at 0 (-1))) = 0) [ set SE-car? true set heading 180 ;->S set v-car? true ;; watch-me ;; type clock type ": (" type mean [wait-time] of cars type " -> " type who print " resolving deadlock" ] if (northbound?) and (pycor < max-pycor) and ((count (cars-at 0 1)) = 0) [ set SE-car? false set heading 0 ;->N set v-car? true ;; watch-me ;; type clock type ": (" type mean [wait-time] of cars type " -> " type who print " resolving deadlock" ] ] end ;; keep track of the number of stopped cars and the amount of time a car has been stopped ;; if its speed is 0 to record-data ;; car procedure ifelse speed = 0 [ set num-cars-stopped num-cars-stopped + 1 set wait-time wait-time + 1 ] [ set wait-time 0 ] end ;; crash any cars at the same intersection going in different directions to crash-cars ask intersections with [any? cars-here with [v-car?] and any? cars-here with [not v-car?]] [ set accident? true set pcolor orange set num-crashes num-crashes + 1 ] end ;; add the new information from this pass thru the go procedure to the HubNet lists to update-list-info set num-cars-stopped (100 * num-cars-stopped / (count cars - parked-cars)) set wait-data lput (mean [wait-time] of cars) wait-data set stopped-data lput num-cars-stopped stopped-data set speed-data lput (mean [speed] of cars with [ not parked? ]) speed-data set cars-data lput (count cars) cars-data set time-data lput clock time-data set c-cars-data lput (count cars - parked-cars) c-cars-data set wait-avgs replace-item (clock mod avg-range) wait-avgs (mean [wait-time] of cars) set stopped-avgs replace-item (clock mod avg-range) stopped-avgs (num-cars-stopped) set speed-avgs replace-item (clock mod avg-range) speed-avgs (mean [speed] of cars with [ not parked? ]) end ;; plot the data from this pass thru the go procedure to do-plotting set-current-plot "% Stopped Cars" set-current-plot-pen "default" plot num-cars-stopped set-current-plot-pen "avg" plot mean stopped-avgs set-current-plot-pen "global" plot mean stopped-data set-current-plot "Average Wait Time of Cars" set-current-plot-pen "default" plot mean [wait-time] of cars set-current-plot-pen "avg" plot mean wait-avgs set-current-plot-pen "global" plot mean wait-data set-current-plot "Average Speed of Cars" set-current-plot-pen "default" plot mean [speed] of cars with [ not parked? ] set-current-plot-pen "avg" plot mean speed-avgs set-current-plot-pen "global" plot mean speed-data set-current-plot "Number of Cars" set-current-plot-pen "default" plot count cars set-current-plot-pen "global" plot mean cars-data set-current-plot-pen "c-default" plot (count cars - parked-cars) set-current-plot-pen "c-global" plot mean c-cars-data end to plot-new-value [name-of-plot value] set-current-plot name-of-plot plot value end to clear-plots-and-plot-in-new-plot [name-of-plot list-to-plot] clear-all-plots plot-new-list name-of-plot list-to-plot end to plot-new-list [name-of-plot list-to-plot] let index 0 set-current-plot name-of-plot clear-plot repeat length list-to-plot [ plot item index list-to-plot set index index + 1 ] end to plot-value-and-lists [value-plot value list-plot1 list-to-plot1 list-plot2 list-to-plot2] plot-new-value value-plot value plot-new-list list-plot1 list-to-plot1 plot-new-list list-plot2 list-to-plot2 end ;; increases the clock by 1 and cycles phase to the next appropriate value to clock-tick set clock clock + 1 ;; The phase cycles from 0 to p, then starts over. set phase phase + 1 if phase mod p = 0 [ set phase 0 ] ask controllers [ set greensteps (greensteps + 1) ] end to-report h-state-avgs [pos] ifelse pos < num-states [ let h-state-sum 0 let i 0 while [i < num-states] [ set h-state-sum h-state-sum + (item i h-state-counter) set i (i + 1) ] report (item pos h-state-counter) / h-state-sum ] [ report 0 ] end to-report v-state-avgs [pos] ifelse pos < num-states [ let v-state-sum 0 let i 0 while [i < num-states] [ set v-state-sum v-state-sum + (item i v-state-counter) set i (i + 1) ] report (item pos v-state-counter) / v-state-sum ] [ report 0 ] end ; *** NetLogo Model Copyright Notice *** ; ; This activity and associated models and materials was created as part of the projects: ; PARTICIPATORY SIMULATIONS: NETWORK-BASED DESIGN FOR SYSTEMS LEARNING IN CLASSROOMS and ; INTEGRATED SIMULATION AND MODELING ENVIRONMENT. ; These projects gratefully acknowledge the support of the ; National Science Foundation (REPP & ROLE programs) -- grant numbers ; REC #9814682 and REC-0126227. ; ; Copyright 2002 by Uri Wilensky & Walter Stroup. Updated 2002. All rights reserved. ; ; Permission to use, modify or redistribute this model is hereby granted, ; provided that both of the following requirements are followed: ; a) this copyright notice is included. ; b) this model will not be redistributed for profit without permission ; from the copyright holders. ; Contact the copyright holders for appropriate licenses for redistribution ; for profit. ; ; To refer to this model in academic publications, please use: ; Wilensky, U. & Stroup, W. (2002). NetLogo HubNet Gridlock model. ; http://ccl.northwestern.edu/netlogo/models/HubNetGridlock. ; Center for Connected Learning and Computer-Based Modeling, ; Northwestern University, Evanston, IL. ; ; In other publications, please use: ; Copyright 1998 by Uri Wilensky and Walter Stroup. All rights reserved. See ; http://ccl.northwestern.edu/netlogo/models/HubNetGridlock ; for terms of use. ; ; *** End of NetLogo Model Copyright Notice *** @#$#@#$#@ GRAPHICS-WINDOW 491 10 1021 561 80 80 3.23 1 12 1 1 1 0 0 0 1 -80 80 -80 80 0 0 1 ticks 30.0 PLOT 279 565 558 754 Average Wait Time of Cars Time Average Wait 0.0 100.0 0.0 5.0 true false "" "" PENS "default" 1.0 0 -2674135 true "" "" "avg" 1.0 0 -13345367 true "" "" "global" 1.0 0 -16777216 true "" "" PLOT 1 372 280 561 Average Speed of Cars Time Average Speed 0.0 100.0 0.0 1.0 true false "" "" PENS "default" 1.0 0 -2674135 true "" "" "avg" 1.0 0 -13345367 true "" "" "global" 1.0 0 -16777216 true "" "" SLIDER 100 10 197 43 grid-size-y grid-size-y 1 20 5 1 1 NIL HORIZONTAL SLIDER 4 10 98 43 grid-size-x grid-size-x 1 20 5 1 1 NIL HORIZONTAL SWITCH 190 82 280 115 crash? crash? 1 1 -1000 SWITCH 4 82 94 115 power? power? 0 1 -1000 SLIDER 200 10 399 43 number number 1 3000 360 1 1 cars HORIZONTAL PLOT -1 565 278 754 % Stopped Cars Time % Stopped Cars 0.0 100.0 0.0 100.0 true false "" "" PENS "default" 1.0 0 -2674135 true "" "" "avg" 1.0 0 -13345367 true "" "" "global" 1.0 0 -16777216 true "" "" BUTTON 213 337 277 370 Go go T 1 T OBSERVER NIL NIL NIL NIL 1 SLIDER 3 119 131 152 simulation-speed simulation-speed 0 10.0 10 0.1 1 NIL HORIZONTAL BUTTON 401 10 485 43 Setup setup true NIL 1 T OBSERVER NIL NIL NIL NIL 1 SLIDER 135 119 227 152 speed-limit speed-limit 0.0 1.0 1 0.1 1 NIL HORIZONTAL BUTTON 3 337 59 370 Re-Run setup false NIL 1 T OBSERVER NIL NIL NIL NIL 1 MONITOR 284 270 358 315 Current Phase phase 3 1 11 SLIDER 4 154 99 187 p p 1 200 83 1 1 timesteps HORIZONTAL BUTTON 133 337 207 370 Refresh Plots clear-all-plots NIL 1 T OBSERVER NIL NIL NIL NIL 1 SLIDER 4 187 173 220 tolerance tolerance 1 300 41 1 1 cars * timesteps HORIZONTAL BUTTON 65 337 127 370 ResetTL reset-traffic-lights NIL 1 T OBSERVER NIL NIL NIL NIL 1 SLIDER 2 45 94 78 %vertical %vertical 0 100 50 1 1 NIL HORIZONTAL SLIDER 4 222 173 255 metatolerance metatolerance 0 10 0 1 1 tolerances HORIZONTAL SWITCH 97 82 187 115 yellow? yellow? 0 1 -1000 CHOOSER 174 211 266 256 control control "marching" "optim" "cut-off" "sotl-request" "sotl-phase" "sotl-platoon" "hb-sotl" "QL-sotl" "LA-sotl" "hb-comm-sotl" "no-corr" 9 SLIDER 102 153 230 186 mingreen mingreen 0 50 20 1 1 timesteps HORIZONTAL MONITOR 428 270 485 315 cars count turtles 0 1 11 PLOT 284 317 484 467 Number of Cars Time cars 0.0 100.0 0.0 100.0 true false "" "" PENS "default" 1.0 0 -2674135 true "" "" "global" 1.0 0 -16777216 true "" "" "c-default" 1.0 0 -10899396 true "" "" "c-global" 1.0 0 -5825686 true "" "" SWITCH 286 469 389 502 plots? plots? 0 1 -1000 MONITOR 360 270 426 315 NIL clock 3 1 11 SLIDER 232 153 366 186 keep-platoon keep-platoon 0 10 4 1 1 patches HORIZONTAL SLIDER 367 153 491 186 cut-platoon cut-platoon 0 10 3 1 1 cars HORIZONTAL SLIDER 227 119 337 152 queue-cut queue-cut 1 10 3 1 1 cars HORIZONTAL MONITOR 286 517 387 562 NIL num-crashes 0 1 11 MONITOR 396 469 483 514 Verticals count turtles with [v-car? = true ] 0 1 11 MONITOR 396 517 484 562 South or East count turtles with [ SE-car? = true ] 0 1 11 BUTTON 212 299 277 332 Step go NIL 1 T OBSERVER NIL NIL NIL NIL 1 MONITOR 559 566 624 611 NIL cars-missing 0 1 11 MONITOR 625 566 702 611 NIL cars-to-create 0 1 11 MONITOR 703 566 760 611 mean cars mean cars-data 2 1 11 SLIDER 290 46 383 79 %origin-out %origin-out 0 100 10 1 1 NIL HORIZONTAL SLIDER 383 46 490 79 %destination-out %destination-out 0 100 10 1 1 NIL HORIZONTAL MONITOR 943 566 1021 611 NIL num-over-l 0 1 11 SLIDER 93 45 197 78 %bidirectional %bidirectional 0 100 25 1 1 NIL HORIZONTAL SLIDER 198 46 290 79 %2-lane %2-lane 0 100 25 1 1 NIL HORIZONTAL SWITCH 390 82 480 115 movie? movie? 1 1 -1000 SLIDER 337 119 485 152 deadlock-limit deadlock-limit 25 200 40 5 1 timesteps HORIZONTAL SWITCH 281 82 389 115 over-length? over-length? 0 1 -1000 MONITOR 722 614 807 659 max-crossing-cars max-crossing-cars 0 1 11 MONITOR 808 614 889 659 max-greensteps max-greensteps 0 1 11 MONITOR 890 613 968 658 min-greensteps min-greensteps 0 1 11 MONITOR 969 613 1021 658 max-flow max-flow 4 1 11 SLIDER 267 188 395 221 aggressiveness aggressiveness 50 1000 200 10 1 NIL HORIZONTAL SLIDER 4 258 161 291 parking-probability parking-probability 0 100 50 1 1 NIL HORIZONTAL SLIDER 4 293 191 326 parking-time-max parking-time-max 0 1000 200 10 1 timesteps HORIZONTAL SLIDER 163 257 277 290 parking-time-min parking-time-min 5 20 10 1 1 NIL HORIZONTAL MONITOR 761 566 826 611 parked cars parked-cars 0 1 11 MONITOR 828 566 911 611 not parked cars count cars - parked-cars 0 1 11 SLIDER 267 222 369 255 %commuters %commuters 0 100 25 1 1 NIL HORIZONTAL SLIDER 369 222 489 255 excursion-probability excursion-probability 0 100 10 1 1 NIL HORIZONTAL SLIDER 396 189 489 222 hb-depth hb-depth 1 10 10 1 1 NIL HORIZONTAL SLIDER 559 721 651 754 alpha alpha 0 1 0.1 0.05 1 NIL HORIZONTAL SLIDER 559 659 732 692 short-cycle short-cycle 1 30 5 1 1 timesteps HORIZONTAL SLIDER 559 689 732 722 cycle-leap cycle-leap 1 50 5 1 1 timesteps HORIZONTAL SLIDER 654 721 823 754 n-cycles-avg n-cycles-avg 1 20 1 1 1 cycles HORIZONTAL MONITOR 559 610 632 655 h-decisions mean [num-h-decisions] of controllers 2 1 11 MONITOR 641 610 714 655 v-decisions mean [num-v-decisions] of controllers 2 1 11 SLIDER 733 659 837 692 num-states num-states 2 10 6 1 1 NIL HORIZONTAL SLIDER 732 689 837 722 beta beta 0 1 0 0.05 1 NIL HORIZONTAL SLIDER 846 659 1018 692 %car-meters %car-meters 0 100 50 1 1 NIL HORIZONTAL @#$#@#$#@ ## WHAT IS IT? HB-SOTL is a model of traffic moving in a city grid. It allows you to control traffic lights and global variables, such as the speed limit and the number of cars, and explore traffic dynamics. In our model, cars have a source and a destination, roads can have one or two directions, each of which can can have one or two lanes. We add new control methods, namely hb-sotl, hb-comm-sotl, QL-sotl, and LA-sotl. From version 8.0 on, HB-SOTL is an extension of HB-COMM-SOTL (History-Based Self-Organizing Traffic Lights with Communication) by Pedro S. Rodriguez-Hernandez & Juan C. Burguillo-Rial. HB-COMM-SOTL was an extension of Learning-SOTL (Self-Organizing Traffic Lights with Learning Algorithms) by Pedro S. Rodriguez-Hernandez & Juan C. Burguillo-Rial. Learning-SOTL was an extension of HB-SOTL (History-Based Self-Organizing Traffic Lights) by Pedro S. Rodriguez-Hernandez & Juan C. Burguillo-Rial. HB-SOTL versions 1.0 to 7.0 was an extension of SOTL (Self-Organizing Traffic Lights) by Carlos Gershenson. The HB-SOTL is documented at the publication: Juan C. Burguillo-Rial, Pedro S. Rodríguez-Hernández, Enrique Costa-Montenegro, Felipe Gil-Castiñeira. History-based Self-Organizing Traffic Lights. Journal of Computing and Informatics (CAI) 22, pp. 1001-1012. 2009. Available at: http://www.cai.sk/ojs/index.php/cai/article/viewFile/30/17 SOTL was extended from the model "Gridlock" by Uri Wilensky & Walter Stroup, which comes with NetLogo 2.0.0 (see more info at the bottom) ## NOTES: + HB-SOTL is based upon version 1.0 of HB-COMM-SOTL + HB-COMM-SOTL was based upon version 7.2 of Learning-SOTL + Learning-SOTL was based upon version 7.0 of HB-SOTL + We are trying to test the effect of having devices to measure the cars which traverse the intersection in only a fraction of the traffic lights controllers + HB-SOTL's name stands for "history-based SOTL" + At every lights cycle, the intersection controller makes a decision based on the amount of cars which have traversed this intersection in the *previous* cycle, if it has this information. If not, it acts as the "marching" controllers. ## CHANGELOG: HB-SOTL 0.00 2007-03-08 just removed torus? and four-dirs? all our models will be non-torus and four-directions 1.00 2007-04-30 added source/destination to cars. Modified the procedures put-on-empty-road and cars-remove-create. Added procedures select-destination and guide-car. 2.00 2007-05-15 added a "Step" button, to run the scenario step by step. Added a count of "stray cars" (cars whose path deviates in excess from the shortest) 3.00 2007-06-06 added bidirectional roads. This includes modifying guide-car and all the procedures for traffic control. Added deadlock resolution 4.00 2007-06-07 added dual-lane roads. Modified the yellow lights cycle to adapt it to the width of the intersection 5.00 2007-11-13 added "hb-sotl" control method. Added automatic call to reset-traffic-lights when control changes. Adapted to NetLogo4.0 6.00 2008-03-23 added the ability to park cars when they reach their destinations and to unpark them later (instead of removing/creating) 7.00 2008-05-14 added depth to the history in "hb-sotl" method LEARNING-SOTL 1.00 2009-05-22 cleaning of HB-SOTL 7.0 2.00 2009-06-01 added QL-SOTL. Whenever a green cycle ends, i.e. whenever a controller changes a lane's lights to red, it selects the next action (i.e. the length of the next green cycle) at random. Whenever a red cycle ends, the controller valorates its last decision comparing the current length of the waiting cars queue with that of the previous red cycle. 3.00 2009-08-01 added LA-SOTL. Idem. 4.00 2009-10-13 corrected 2 problems with car guidance: now cars run in the middle of the lane, and, in the case of dual-lanes, cars use both lanes. The deadlock resolution algorithm is more aggressive now. The average speed metric now avoids counting parked cars. In HB-SOTL, now we have separate histories for horizontal and vertical traffic 5.00 2009-10-28 the commuters commute between downtown (the central patches) and the residential areas (the outmost patches and the outside world) 6.00 2009-11-01 the valoration of the last decision is made on the basis of the ratio: number of cars crossing the intersection in the current green cycle / length of the (waiting + approaching) cars queue in the previous red cycle, instead of the ratio: length of the waiting cars queue in the current red cycle / length of the waiting cars queue in the previous red cycle 7.00 2009-11-02 both the decision and the valoration are made on the last "n" cycles average value, instead of on the last cycle value (where "n" is selectable by means of a slider) 7.10 2009-11-20 both the decision and the valoration are based on the number of cars rather than on the queue length 7.20 2009-11-20 added a slider for defining the number of states, and changed the sliders for defining the "width" of the states refined the valoration heuristics: now we have into account not only the ratio cars crossing / cars waiting, but also the controller's "throughput" i.e. the cars crossing per timestep HB-COMM-SOTL 1.00 2009-12-11 cleaning of Learning-SOTL 7.2 added HB-COMM-SOTL changed the definition of "aggressiveness": scaled up to a factor of 10 (just to avoid multiplying it by 10 once and again) HB-SOTL 8.00 2010-09-15 cleaning of HB-COMM-SOTL 1.0 added %car-meters slider: the fraction of controllers provided with a device to measure the amount of cars which traverse the intersection the car-meters information now is only used by hb-sotl. 8.10 2010-11-11 now the car-meters information is used by hb-comm-sotl too. ## HOW TO USE IT ## QUICKSTART INSTRUCTIONS: Run "Setup" before starting simulation. Then start and stop with "Go". Some parameters, such as grid-sizes and four-dirs? will be applied only after pressing "Setup". Tip: you can "freeze" the display (on top of the "city" display) and/or switch off the plots to accelerate simulations. For SOTL details, consult the paper "Self-Organizing Traffic Lights" http://uk.arxiv.org/abs/nlin.AO/0411066 ## BUTTONS: "Setup"- Initializes simulation "Re-run"- "soft" and quick "Setup" (just clears variables, doesn't change street topology) "Reset-TL"- Turns phases of adaptive control methods ("sotl"'s and "cut-off") to zero, so that they need to adapt again (to check robustness) "Go"- Start and stop simulation "Step"- Run simulation just one time step "Refresh Plots"- Clear all plots ## CHOOSERS: -control- select control method for traffic lights (now, when changing methods during the same run, resetTL is automatically called. (If one was yellow, can cause problems...) ## SLIDERS: "grid-size-x"- number of vertical streets "grid-size-y"- number of horizontal streets "number"- initial number of cars for "Setup" and "Re-run", intended average number of circulating cars %vertical- percentage of cars initially flowing in vertical roads, if starting at an intersection (%horizontal= 100-%vertical) %origin-out- percentage of cars with origin outside the world %destination-out- percentage of cars with destination outside the world %bidirectional- percentage of bidirectional streets %2-lane- percentage of streets with two lanes in the same direction simulation-speed- regulates processing speed speed-limit- maximum speed of cars p- phase period for cyclic control methods ("marching", "optim", and "no-corr") mingreen- minimum green phase for "sotl-phase" and "sotl-platoon" controls keep-platoon- "omega" distance at which cars are checked from green light in "sotl-platoon" control cut-platoon- "miu" cars approaching a green light at which platoons can be cut in "sotl-platoon" control queue-cut- lambda queue length for "cut-off" control tolerance- "theta" threshold for all "sotl" control methods metatolerance- attempt of metaadaptive regime. Doesn't work, keep set to zero... deadlock-limit- maximum time to decide that a car is suffering a deadlock aggressiveness- scale factor for the time slots of the green cycles in "self-org-history" hb-depth- number of previous cycles to be taken into account in "self-org-history" parking-probability- probability of parking a car that reaches its destination and is not a commuter (commuters always park) parking-time-min- minimum time a car is going to be parked parking-time-max- maximum time a car is going to be parked (the actual parking time is a random variable uniformly distributed among this value and the previous) %commuters- percentage of cars with a fixed home-place and work-place, which are going to switch origin and destination between those 2 places excursion-probability- probability for a commuter to make an "excursion" to a place other than its work-place or its home-place ## SWITCHES: power?- makes traffic lights work yellow?- include yellow phase (1 timestep) between green and red phases crash?- monitor crashes at intersections plots?- switches plotting (off increases simulation speed) movie?- activates the recording of the simulation as a movie over-length?- activates the control of cars running for a extra-long time (this should only happen if there is an error in the guidance procedure) ## CREDITS AND REFERENCES OF ORIGINAL "GRIDLOCK" This activity and associated models and materials was created as part of the projects: PARTICIPATORY SIMULATIONS: NETWORK-BASED DESIGN FOR SYSTEMS LEARNING IN CLASSROOMS and INTEGRATED SIMULATION AND MODELING ENVIRONMENT. These projects gratefully acknowledge the support of the National Science Foundation (REPP & ROLE programs) -- grant numbers REC #9814682 and REC-0126227. Copyright 2002 by Uri Wilensky & Walter Stroup. All rights reserved. Permission to use, modify or redistribute this model is hereby granted, provided that both of the following requirements are followed: a) this copyright notice is included. b) this model will not be redistributed for profit without permission from the copyright holders. Contact the copyright holders for appropriate licenses for redistribution for profit. To refer to this model in academic publications, please use: Wilensky, U. & Stroup, W. (2002). NetLogo HubNet Gridlock model. http://ccl.northwestern.edu/netlogo/models/HubNetGridlock. Center for Connected Learning and Computer-Based Modeling, Northwestern University, Evanston, IL. In other publications, please use: Copyright 2002 by Uri Wilensky and Walter Stroup. All rights reserved. See http://ccl.northwestern.edu/netlogo/models/HubNetGridlock for terms of use. @#$#@#$#@ default true 0 Polygon -7500403 true true 150 5 40 250 150 205 260 250 car true 15 Circle -1 false true 185 55 60 Circle -1 false true 183 186 61 Polygon -1 true true 214 52 214 22 182 26 162 38 144 74 138 102 100 120 99 161 102 201 118 246 152 267 190 275 210 251 187 240 178 200 204 182 215 181 214 118 193 112 182 98 181 72 198 52 link true 0 Line -7500403 true 150 0 150 300 link direction true 0 Line -7500403 true 150 150 30 225 Line -7500403 true 150 150 270 225 @#$#@#$#@ NetLogo 5.2.1 @#$#@#$#@ @#$#@#$#@ @#$#@#$#@ setup true go mean speed-data variance speed-data mean stopped-data variance stopped-data mean wait-data variance wait-data mean cars-data variance cars-data setup true go mean speed-data variance speed-data mean stopped-data variance stopped-data mean wait-data variance wait-data mean cars-data variance cars-data setup true go mean speed-data variance speed-data mean stopped-data variance stopped-data mean wait-data variance wait-data mean cars-data variance cars-data @#$#@#$#@ @#$#@#$#@ default 0.0 -0.2 0 0.0 1.0 0.0 1 1.0 0.0 0.2 0 0.0 1.0 link direction true 0 Line -7500403 true 150 150 90 180 Line -7500403 true 150 150 210 180 @#$#@#$#@ 0 @#$#@#$#@