MagdalenaOlewinska-GroceryStoreLines-EECS- 372
Model was written in NetLogo 6.0-M5
•
Viewed 555 times
•
Downloaded 50 times
•
Run 0 times
Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)
Info tab cannot be displayed because of an encoding error
Comments and Questions
Please start the discussion about this model!
(You'll first need to log in.)
Click to Run Model
globals [ ;;NOTE: SAVED INPUT, so if user changes parameters after pressing setup, model characteristics will not change thus running model will still be correct ;; model characteristics stations ;; patches that are designated stations ;; business characteristics closing-at ;; tick count at which no more customers should arrive hourly-pay ;; employee hourly rate dynamic? ;; true if stations can dynamically open & close dynamic-check-range ;; evaluate whether to open/close stations every X hours (increments in half hour units) short-line-length ;; close a station (if possible) if a station's line is shorter than this number @half hour marks long-line-length ;; open a new station (if possible) if a station's line is longer than this number @half hour marks ;; customer characteristics distraction-level ;; decreases a customer's sense of wait-time by % of distraction provided impatience? ;; allows unsatisfied customers to balk if average wait of store is large or renege when perceived wait while in line too large ideal-wait ;; time (in min) believed to be best waiting time at this particular grocery store avg-arrival-count ;; average number of customers arriving per tick arrival-schedule ;; schedule of customer arrival with average as avg-arrival-count: uniform, oscillating ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; running totals all-total-wait ;; running total of all wait time of all customers since store opening total-customers ;; running total of all arrivals total-checkout-customers ;; running total of all customers who successfully checked out total-balk-customers ;; running total of all customers who arrived but left because avg. wait time too long total-renege-customers ;; running total of all customers who waited but left because his/her wait time too long in line general-total-wait ;; running total of all wait time of customers serviced at a general checkout station since store opening general-total-customers ;; running total of all customers serviced at a general checkout station since store opening express-total-wait ;; running total of all wait time of customers serviced at an express checkout station since store opening express-total-customers ;; running total of all customers serviced at an express checkout station since store opening self-total-wait ;; running total of all wait time of customers serviced at a self-checkout station since store opening self-total-customers ;; running total of all customers serviced at a self-checkout station since store opening ;; report to user statistics average-wait ;; tracks average total time waited of a customer now "checking-out" and leaving general-average-wait ;; average-wait but for general stations express-average-wait ;; average-wait but for express stations self-average-wait ;; average-wait but for self stations current-cost ;; tracks cost of operation depending on how many and what types of checkout stations are open total-general ;; current cost of general stations total-express ;; current cost of express stations total-self ;; current cost of self checkout stations ] breed [customers customer] patches-own [ max-items ;; depending on type of station, how many max scan-rate ;; how many items per tick stations scans line-length ;; keeps track of line length; 0 if no one is in line interested-customers ;; keeps track of count of customers who have selected this line (location = here , state "found-line" or "in-line") total-items-scanned ;; keeps track of number of items scanned total-customers-helped ;; keeps track how many customers serviced last-number-served ;; keeps track ensures next customer being served has larger wait-number about-to-close? ;; if true, inefficient so will close as soon as customers in line serviced, no new customers accepted #-renege-customers ;; keeps track how many customers left line because wait too long ] customers-own [ state ;; no-line, found-line, in-line, checking-out grocery-items ;; number items needed to be checked out wait-number ;; indicates place in line wait-time ;; counts how long has been "in-line" perceived-wait-time ;; how long the customer perceives he/she is in line dependent on distractions location ;; checkout station the customer has selected ] ;;; setup procedures to setup clear-all set-store-characteristics setup-stations reset-ticks end ;; go procedure to go if ticks > closing-at and count customers = 0 ;;end simulation after all customers leave and it is past closing time [stop] if ticks > 0 and ticks mod dynamic-check-range = 0 and dynamic? [adjust-open-stations] ;;access layout and make changes every evaluation period if impatience? [balk-customers] check-out-customers find-line move-forward if impatience? [renege-customers] leave-customers if dynamic? [close-stations] if ticks < closing-at [arrive-customers] ;;keep doors open to customers for indicated period color-customers update-graphs update-plots tick end ;;; setup helper procedure ;;; set up global variables. this includes using user inputs to initialize store characteristics to set-store-characteristics set closing-at (closing-time * 60) ;convert hours to tick count (1 tick = 1 minute) set dynamic-check-range (evaluate-every-X-hours * 60) set distraction-level distracted-in-line set impatience? impatient-customers? set ideal-wait ideal-wait-time set hourly-pay employee-hourly-rate set dynamic? dynamic-layout? set short-line-length line-too-short set long-line-length line-too-long set arrival-schedule customer-arrival-schedule set avg-arrival-count avg-#-customers-arriving end ;; patch procedure ;; set up checkout stations based on user parameters to setup-stations ;; floor is white ask patches [set pcolor grey + 3 ] ;; create stations of each type let new-station 0 ;;not used for initial creation open-new-station blue general-stations new-station open-new-station green express-stations new-station open-new-station yellow self-stations new-station end ;; patch procedure ;; open new-station-count amount of stations with pcolor checkout-type to open-new-station [checkout-type new-station-count new-station-loc] ;; set up check out area on y axis = 6 let station-space patches with [pycor = 14 and pxcor mod 2 = 0] set station-space station-space with [pcolor = grey + 3] let express-space station-space with [pxcor >= 16] let general-space station-space with [pxcor > -16 and pxcor < 16] let self-space station-space with [pxcor <= -16] if checkout-type = blue [set station-space n-of new-station-count general-space] if checkout-type = green [set station-space min-n-of new-station-count express-space [pxcor]] if checkout-type = yellow [set station-space max-n-of new-station-count self-space [pxcor]] ;;create num-to-open patches of checkout-type (pcolor indicating type) ask station-space [set pcolor checkout-type if-else pcolor = green [set max-items 15] ;;express types have grocery-item count restriction of <= 15 items [set max-items 1000] if-else pcolor = yellow [set scan-rate 10] ;;self-checkout types have slower scan-rates [set scan-rate 15] set line-length 0 set interested-customers 0 set total-items-scanned 0 set total-customers-helped 0 set last-number-served 0 set #-renege-customers 0 set about-to-close? false set new-station-loc self] set stations patches with [pcolor != grey + 3] end ;;customer procedure ;; queueing theory: balking - just arrived customer chooses not to join queue because wait time is too long to balk-customers ask customers with [state = "no-line"] [ ;; leave if model's wait time is 20% higher than ideal wait if impatience? and average-wait > (1.20 * ideal-wait) [set total-balk-customers total-balk-customers + 1 die] ] end ;;customer procedure ;; queueing theory: reneging - leaving queue without being serviced because wait is too long to renege-customers ask customers with [state = "in-line"] [ ;; leave if customer's preceived wait time is 20% higher than ideal wait if perceived-wait-time > (1.20 * ideal-wait) [ask location [;set line-length line-length - 1 set interested-customers interested-customers - 1 set #-renege-customers #-renege-customers + 1 ask customers with [state = "in-line" and location = self] [set wait-number wait-number - 1] ] set total-renege-customers total-renege-customers + 1 die] ] ask stations with [#-renege-customers > 0] [ let reg #-renege-customers ask customers with [location = myself and state = "in-line"] [if reg >= 2 [move-to patch-ahead (reg - 2)]] set #-renege-customers 0 ] end ;; patch procedure ;; at every user indicated dynamic-range-check increment in time, if dynamic-layout? is switched on: ;; evaluate line-length per station (note: stations open cannot exceed max allowed for store: 5 - express, self; 15 - general) ;; if line-length <= close-if-line-shorter-than: mark station to be closed, ;; customers "found-line" heading to this underwhelmed station will have to pick new station ;; current customers "in-line" will still be serviced ;; if line-length >= open-if-line-longer-than: open new station of same type, ;; customers "found-line" heading to this overwhelmed station will be redirected to new station to adjust-open-stations ask patches with [pcolor = green or pcolor = blue or pcolor = yellow] [ let given-color pcolor let my-type-of-stations stations with [pcolor = given-color] if count my-type-of-stations with [about-to-close? = false] > 1 ;;range for any given checkout type is to have between 1-15 stations open at any time [ if line-length <= short-line-length ;; line too short and at least one type of this station open [set about-to-close? true ask patch pxcor (pycor + 1) [set pcolor red]] ] let current-line line-length let max-amount 5 ;; max amount of express or self checkout stations is 5 if pcolor = blue [set max-amount 15] ;; max amount of general stations is 15 if count my-type-of-stations < max-amount [ if line-length >= long-line-length ;; line too long and still room for more stations so open a station like this [let new-station self open-new-station pcolor 1 new-station ask customers with [location = myself and state = "found-line"] ;;relocate customers who chose this line but havent arrived yet to redirect to new open station [set location new-station ask new-station [set about-to-close? false set interested-customers interested-customers + 1] ask location [set interested-customers interested-customers - 1] face location] ] ] set stations patches with [pcolor != grey + 3] ] end ;; patch procedure ;; if dynamic-layout? switched on and marked to close ASAP, ;; actually close when all customers who were already in line serviced to close-stations ask stations with [about-to-close? = true and count customers-here = 0 and interested-customers = 0] [set pcolor grey + 3 ask patch pxcor (pycor + 1) [set pcolor grey + 3] set stations patches with [pcolor != grey + 3]] end ;; customer procedure ;; if you have no more grocery items while checking out, leave the store, ;; decrease the station's line-length, increase the station's customers helped count, ;; and decrease the wait-number of everyone who was in your checkout line to leave-customers ask customers with [state = "checking-out"] [if grocery-items <= 0 [let num wait-number ask location [set line-length line-length - 1 set interested-customers interested-customers - 1 set total-customers-helped total-customers-helped + 1] update-statistics die] ] end ;; customer procedure ;; if checking-out, decrease your grocery-items by the scan-rate of the station ;; and increase the total-items-scanned count of the station by the number of items scanned ;; if in-line, increase your wait time, if you are the smallest wait-number in your patch, ;; move up and set state to checking-out to check-out-customers ask customers with [state = "checking-out"] [ let scan 0 let num wait-number let just-arrived false ask patch-here [set scan scan-rate if last-number-served != num [set just-arrived true set last-number-served num] ] if just-arrived = false ;; every station has 1 minute of transaction overall [ if grocery-items < scan [set scan grocery-items] set grocery-items grocery-items - scan ask patch-here [set total-items-scanned total-items-scanned + scan] ] ] end ;; customer procedure ;; if station is in front of you, ask the station to increase its line-length, assign ;; yourself a customer of the day number as your wait-number, and set your state to in-line ;; if station is not in front of you, keep moving forward toward your selected station to move-forward ask customers with [state = "in-line"] [ set wait-time wait-time + 1 set perceived-wait-time perceived-wait-time + (1 - (distraction-level / 100)) if-else patch-here = location [set state "checking-out" set label-color red set color white] [let customers-ahead 1000 ask patch-ahead 1 [set customers-ahead count customers-here] if customers-ahead = 0 and wait-number = min [wait-number] of customers-here [ if patch-here != location [move-to patch-ahead 1 let temp 0 ask patch-ahead 1 [ask customers-here with [state = "in-line" or state = "checking-out"] with-max [wait-number] [set temp wait-number]] if temp > wait-number and patch-here != location [move-to patch-ahead 1]] if patch-here = location [set state "checking-out" set label-color red set color white]] ;; ask patch-here [if last-number-served >= [wait-number] of myself [type "ERROR: queueing out of order at station: " type pxcor type " " type last-number-served type " > " print [wait-number] of myself]]] ]] ask customers with [state = "found-line"] [ let w 1000 let new-x pxcor let new-y pycor if-else patch-ahead 1 = location [ask location [set line-length line-length + 1 set new-x pxcor set new-y pycor - line-length ; if count customers-here with [state = "checking-out"] > 0 [set new-y new-y + 1] set w total-customers-helped + line-length] set state "in-line" set color grey set wait-number w set heading 0 if-else new-y > -18 [move-to patch new-x new-y] ;; move to end of line [move-to patch new-x -18];; end of line would be off screen, so group together at the last patch ] [fd 1] ] end ;; customers procedure ;; for customers with no-line state, pick the shortest lines closet to you and set ;; state to found-line to find-line ask customers with [state = "no-line"] [ let my-items grocery-items let options 0 if-else random 101 <= 33 [set location stations with [max-items >= my-items and about-to-close? = false] with-min [interested-customers] let selection min-one-of location [distance myself] set location selection ask location [set interested-customers interested-customers + 1] ] [set location stations with [max-items >= my-items and about-to-close? = false and pcolor != yellow] with-min [interested-customers] let selection min-one-of location [distance myself] set location selection ask location [set interested-customers interested-customers + 1] ] set state "found-line" face location ] end ;; customers procedure ;; create customers based on arrival-schedule preference set; ;; uniform creates X amount of customers at every tick (x user input value ;; max store capacity set at 500 to arrive-customers let num-arriving 0 let customer-count floor(avg-arrival-count) if-else customer-count <= 0 [user-message "Error: Number of customers arriving must be greather than zero."] [if arrival-schedule = "uniform" ;; arrive user input # of customers per tick [set num-arriving customer-count] if arrival-schedule = "oscillating" ;; arrive variable customers with max of user input # [set customer-count customer-count * 2 set num-arriving ticks mod (customer-count * 2) + 1 if num-arriving > customer-count ;; past max magnitude of oscillation needs to count backwards [set num-arriving -1 * (num-arriving - (customer-count * 2))] ] if arrival-schedule = "poisson" ;; arrive with poisson distribution of user input # average [set num-arriving random-poisson customer-count] ] create-customers num-arriving [ setxy random 28 - 14 18 ;; enter at the top of screen in the middle set shape "person" set state "no-line" ;; no decision on any line at first set grocery-items 1 + random 99 ;; random amount of items 1 - 100 set wait-number 1000 ;; default head to very back set wait-time 0 ;; start off with no wait time set perceived-wait-time 0 ;; start off with no perceived wait time set size 1 ;set label grocery-items set label-color white ] set total-customers (total-customers + num-arriving) end ;;customer procedure ;; customers go across the violet color spectrum with deeper violets indicating longer ;; perceived-wait-times as compared to the ideal wait to color-customers ask customers with [state = "in-line"] [set color scale-color violet perceived-wait-time (1.20 * ideal-wait) 0] end ;; calculates current-cost, per checkout cost, ;; overall average wait, per checkout type average wait to update-graphs let general-count count stations with [pcolor = blue] let express-count count stations with [pcolor = green] let self-count count stations with [pcolor = yellow] let temp-g general-count * 2 * (hourly-pay / 60) ;; 2 employees for general station (scanner + bagger) let temp-e express-count * (hourly-pay / 60) ;; 1 employee for express station (scanner) let temp-s 0 if self-count > 0 ;; 1 employee oversees all self checkouts [set temp-s (hourly-pay / 60)] set total-general total-general + temp-g set total-express total-express + temp-e set total-self total-self + temp-s set current-cost current-cost + temp-g + temp-e + temp-s if total-checkout-customers > 0 [set average-wait all-total-wait / total-checkout-customers] if general-total-customers > 0 [set general-average-wait general-total-wait / general-total-customers] if express-total-customers > 0 [set express-average-wait express-total-wait / express-total-customers] if self-total-customers > 0 [set self-average-wait self-total-wait / self-total-customers] end ;; after customers check out, ;; update global statistics across all checkout station types to update-statistics set all-total-wait all-total-wait + wait-time set total-checkout-customers total-checkout-customers + 1 let type-checkout "" ask patch-here [if pcolor = blue [set type-checkout "general"] if pcolor = green [set type-checkout "express"] if pcolor = yellow [set type-checkout "self"]] if type-checkout = "general" [set general-total-wait general-total-wait + wait-time set general-total-customers general-total-customers + 1] if type-checkout = "express" [set express-total-wait express-total-wait + wait-time set express-total-customers express-total-customers + 1] if type-checkout = "self" [set self-total-wait self-total-wait + wait-time set self-total-customers self-total-customers + 1] end
There are 4 versions of this model.
Attached files
File | Type | Description | Last updated | |
---|---|---|---|---|
MagdalenaOlewinska-GroceryStoreLines-EECS- 372.png | preview | Preview for 'MagdalenaOlewinska-GroceryStoreLines-EECS- 372' | almost 9 years ago, by Magdalena Olewinska | Download |
MagdalenaOlewinska_May16.docx | word | Progress Report 2 | almost 9 years ago, by Magdalena Olewinska | Download |
MagdalenaOlewinska_May23.docx | word | Progress Report 3 | almost 9 years ago, by Magdalena Olewinska | Download |
MagdalenaOlewinska_May9.docx | word | Progress Report 1 | almost 9 years ago, by Magdalena Olewinska | Download |
This model does not have any ancestors.
This model does not have any descendants.