Customer Stores Choice Model
Model was written in NetLogo 6.2.0
•
Viewed 887 times
•
Downloaded 92 times
•
Run 0 times
Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)
Comments and Questions
Please start the discussion about this model!
(You'll first need to log in.)
Click to Run Model
breed [persons person] breed [stores store] breed [houses house] ;; the start-time (unhappiness start-time) is the first time when each customer have visited the target store at least once ;; the unhappiness-values-list keeps track of the unhappiness values of the population of the customers for calculation of standard-deviation globals [start-time unhappiness-values-list] persons-own [house-id home-xcor home-ycor ;; who-number of the home belonging to person, the x-coordinate and y-coordinate of the home store-travel-time-list store-visit-count-list store-total-waiting-time-list ;; store-travel-time-list contains the list of travel-distance from home to each store, store-visit-count-list contains the total number of visits by the person to each store ;; store-waiting-time-list contains the total waiting time for each store in the past visits of the person rest-time wait-time demand target-store-id ;; how much time the person will rest at home after returning from store ;; what is the quantity of the item that person requires in current visit to store ;; in the beginning of journey, the person decides which store to visit, the who of target store is saved in target-store-id at-home? at-store? travelling-to-store? travelling-to-home?] ;; the state variables, at-home is true if the person is at home, travelling-to-store if on way to store, travelling-to-home if on way to home, at-store if at store currently stores-own [quantity] ;; every store keeps track of its current quantity ;; Reports the current average-unhappiness of the population ;; A person's unhappiness for a given store = Avg. Waiting Time at the store + Travel Time for the store (proportional to distance of store from home) ;; A person's unhappiness is counted towards average unhappiness, only when the person has visited the current targeted store at least once. ;; ^ This is to avoid bad unhappiness values when the person is yet to experience the target store atleast once to-report average-unhappiness ;; Initialize the list for the unhappiness values of the customers set unhappiness-values-list [] ;; The number of customers which have actually experienced the target-store at least once let actual-num-consumers 0 ask persons [ ;; If the person has visited the target store at least once if (item target-store-id store-visit-count-list) > 0 [ ;; insert its unhappiness value in the unhappiness list for the population set unhappiness-values-list lput store-unhappiness target-store-id unhappiness-values-list set actual-num-consumers actual-num-consumers + 1 ] ] ;; If all of the customers have atleast experienced their current target store at least once, then set the current time as the start-time if actual-num-consumers = num-consumers and start-time = 0 [set start-time ticks] ;; color the customers and houses as per the unhappiness distribution ;; report the standard-deviation and mean of the unhappiness if the actual numbers of customers are greater than 2 if (actual-num-consumers >= 2) [ let std-dev-unhappiness standard-deviation unhappiness-values-list let mean-unhappiness mean unhappiness-values-list ;;set the colors of the customer and house agents set-customer-unhappiness-colors std-dev-unhappiness mean-unhappiness ;; If the user has turned ON the visual tool to show the unhappiness distribution over the patches, then color the patches accordingly ;; otherwise set all the patches to turquoise color ifelse (show-unhappiness-terrain?) [show-unhappiness-terrain] [ ask patches [set pcolor turquoise] ] ] ;; report the average unhappiness value ifelse actual-num-consumers > 0 [report mean unhappiness-values-list] [report 0] end ;; sets the color of the customers and houses as per the current unhappiness value in the population distribution to set-customer-unhappiness-colors [std-dev mean-val] ask persons [ ;; get the unhappiness value of the customer let person-unhappiness store-unhappiness target-store-id ;; red color for person with unhappiness more than mean value + standard-deviation (ifelse (person-unhappiness >= mean-val + std-dev) [set color red] ;; orange color for person with unhappiness above mean (person-unhappiness >= mean-val) [set color orange] ;; sky color for unhappiness below the mean-value - standard deviation, the happiest of the customers (person-unhappiness < mean-val - std-dev) [set color sky] ;; rest green color for below mean [ set color green]) ;; set the same color for the house as of the associated customer ask house house-id [set color [color] of myself] ] end ;; set the color of the patches as per the color of the nearest house (denoting the unhappiness value of customer residing in the region) to show-unhappiness-terrain ask patches [ ;; local variable to store the new color value of the patch let my-new-color 0 ;; get the color of the nearest house to the patch ask houses with-min [distance myself] [ set my-new-color [color] of self ] ;; set a lighter tone for the patch color set pcolor my-new-color + 2 ] end ;; reports the first time, when all of the customers have experienced their target store atleast once to-report unhappiness-start-time report start-time end to setup clear-all ask patches [set pcolor turquoise] ;; initialize the unhappiness start-time to 0 set start-time 0 ;; setup the stores in the grid setup-stores-initial ;; setup the persons in the grid setup-homes-and-consumers ;; initialize the lists and initial state variables for the persons ask persons [ initialize-person-lists-and-state ] reset-ticks end ;; if we want keep the location of stores same, but want to try a new location of consumers to setup-consumers clear-all-plots ask patches [set pcolor turquoise] ;; initialize the unhappiness start-time to 0 set start-time 0 ;; kill all the persons and houses and generate a new set of customers and houses with different location ask persons [die] ask houses [die] ;; reset the quantity in the stores ask stores [set quantity store-capacity] ;; generate the customer and house pairs in the grid setup-homes-and-consumers ;; intialize the lists for each consumer ask persons [initialize-person-lists-and-state] reset-ticks end ;; if we want to keep the same location of consumers, but want to try a new location for shops to setup-stores clear-all-plots ;; initialize the unhappiness start-time to 0 set start-time 0 ;; set a unifrom random location of the stores ;; intially the inventory (quantity) at each store is full ask stores [ setxy random-xcor random-ycor set quantity store-capacity ] ;; initialize the list and state variables of the customers ask persons [initialize-person-lists-and-state] reset-ticks end ;; create the stores in the grid to setup-stores-initial create-stores num-stores [ setxy random-xcor random-ycor set shape "building store" set color yellow set size 1.5 ;; intially the inventory (quantity) at each store is full set quantity store-capacity ] end ;; move each of the store to the average coordinate of its current customers to move-shops-to-customers ask stores [ let num-customers count link-neighbors let mean-x-customer mean [xcor] of link-neighbors let mean-y-customer mean [ycor] of link-neighbors ;; move the store to the mean coordian setxy mean-x-customer mean-y-customer ] reset-consumers end ;; move the store to the unhappiness weighted mean coordinate of its current customers to move-shops-to-unhappiness-customers ask stores [ let current-store-id [who] of self ;; the total unhappiness of current store customers let total-customer-unhappiness 0 let mean-unhappiness-x-customer 0 let mean-unhappiness-y-customer 0 ;; ask the houses of its customers ask link-neighbors[ let current-house-id [who] of self ;; get the customer who is associated with this house let person-here persons with [house-id = current-house-id] ;; ask the customer associated with this house ask person-here [ let unhappiness-value store-unhappiness current-store-id ;; take the weigted x and y coordinate of the customer set mean-unhappiness-x-customer mean-unhappiness-x-customer + (xcor * unhappiness-value) set mean-unhappiness-y-customer mean-unhappiness-y-customer + (ycor * unhappiness-value) set total-customer-unhappiness total-customer-unhappiness + unhappiness-value ] ] ;; finally get the unhappiness weighted customer coordinates set mean-unhappiness-x-customer mean-unhappiness-x-customer / total-customer-unhappiness set mean-unhappiness-y-customer mean-unhappiness-y-customer / total-customer-unhappiness setxy mean-unhappiness-x-customer mean-unhappiness-y-customer ] reset-consumers end ;; reset the customer variables and set the location to its home location ;; reset the quantity of the store as well to reset-consumers clear-all-plots set start-time 0 ;; reset the quantity in the stores ask stores [set quantity store-capacity] ;; intialize the lists for each consumer ask persons [initialize-person-lists-and-state] reset-ticks end ;; create the customer and the associated house pairs on the grid to setup-homes-and-consumers ;; create persons/consumers create-persons num-consumers [ setxy random-xcor random-ycor ;; the initial location will be the location of person's home as well set home-xcor xcor set home-ycor ycor set shape "person" set color blue ;; store the current person in local variable parent let parent self ;; ask the patch on the where the person is standing to create an agent of breed house ask patch-here[ sprout-houses 1 [ set shape "house" set color blue ;; store the who number of house in local variable of the associated customer let current-house-id who ;; ask the customer stored as parent, to set its house-id to the who number of this house ask parent [ set house-id current-house-id ] ] ] ] ;; reset the unhappiness values of the population list set unhappiness-values-list [] end ;; initializes the calling customer's lists and initial-state to initialize-person-lists-and-state ;; calculate the travelling distance to each store set store-travel-time-list n-values num-stores distance-from-store ;; initialize visit count for each store to zero set store-visit-count-list n-values num-stores [i -> 0] ;; initialize the total waiting time for each store to zero set store-total-waiting-time-list n-values num-stores [i -> 0] ;; set the initial state of person as at home set at-home? true ;; initialize the rest-time of the person set rest-time random person-max-rest-time ;; place the person at associated house setxy home-xcor home-ycor end ;; reports the euclidean distance from calling customer's house to the store with given who number as store-id to-report distance-from-store [store-id] let distance-to-store 0 ;; store the distance from home to store in distance-to-store variable ask house house-id [ set distance-to-store distance store store-id] ;; resport the distance report distance-to-store end ;; reports the best store option for the calling customer depending on the unhappiness values ;; unhappiness for a store = distance-from-home + (average waiting time at the store) to-report best-store-option ;; prepare the unhappiness value for each store and store in a local variable - list let store-unhappiness-list n-values num-stores store-unhappiness ;; find the minimum unhappiness value let min-unhappiness min store-unhappiness-list ;; report the index (who of the store in this case) with the given minimum unhappiness-value report position min-unhappiness store-unhappiness-list end ;; reports the unhappiness for a particular store for the calling customer ;; unhappiness for a store = distance-from-home + (average waiting time at the store) to-report store-unhappiness [store-id] ;; initally unhappiness = distance-from-home let unhappiness item store-id store-travel-time-list ;; add average waiting time for the store to the unhappiness value, if the number of visits to the store > 0 if (item store-id store-visit-count-list) > 0 [ set unhappiness unhappiness + (item store-id store-total-waiting-time-list) / (item store-id store-visit-count-list) ] ;; report the unhappiness value report unhappiness end ;; display the inner influence circles for each store ;; every house strictly inside this radius is a customer to calling store only, not to any other store to-report inner-influence-radius let current-store self ;; the list of the houses of the current customers of the store let current-store-link-neighbors link-neighbors ;; report the distance of the nearest home which is a customer of another store report min [distance current-store] of houses with [not member? self current-store-link-neighbors] end ;; the distance of the home of the farthest customer for the store ;; this is the radius of the star network of this to-report outer-influence-radius let current-store self ;; report the distance of the home of the farthest customer report max [distance current-store] of link-neighbors end to go ;; perform the following actions for each customer ask persons[run-consumer-finite-state-logic] ;; increase the quantity in each store by the supply-rate ask stores [ set quantity quantity + supply-rate ;; if the quantity of the store goes above its capacity, set quantity to exactly its capacity if quantity > store-capacity [set quantity store-capacity] ] ;; clear all the previous drawings clear-drawing ;; display inner-circles if inner-influence-circles? switch is ON if inner-influence-circles? [display-inner-influence-circles] ;; display outer-circles if outer-influence-circles? switch is ON if outer-influence-circles? [display-outer-influence-circles] ;; hide links if show-links? switch if OFF ask links [set hidden? not show-links?] tick end ;; contains the logic of customer for the go procedure to run-consumer-finite-state-logic ;; fetch the target store via the target-store-id let target-store store target-store-id (ifelse ;; if the person is currently inside home at-home? = true [ ;; if the person at home doesn't need rest ifelse rest-time = 0 [ ;; set demand to a random value over the range set demand random person-max-demand let person-home house house-id ;; kill the link with previous target-store ask target-store[ let link-with-person-home link-with person-home if link-with-person-home != nobody [ ask link-with-person-home [die] ] ] ;; calculate the best store, as per the unhappiness values set target-store-id best-store-option ;; update the target-store local variable as well set target-store store target-store-id ;; create a link between updated target-store and home of the person ask target-store[create-link-with person-home ask link-with person-home [set color red]] ;; set at-home to false, set travelling-to-store to true set at-home? false set travelling-to-store? true] ;; otherwise if the person requires rest, then person stays at home and rest-time is decreased by 1 [set rest-time rest-time - 1] ] ;; if the person is on its way to store travelling-to-store? = true[ ;; if reached the store (that is when distance from store is less or equal to one) ifelse distance target-store <= 1[ ;; move inside the shop setxy [xcor] of target-store [ycor] of target-store ;; travelling-to-store is set to false and at-store set to true set travelling-to-store? false set at-store? true ] ;; if still far from store, then face towards the store and move 1 step forward [ face target-store fd 1] ] ;; if the person is inside store at-store? = true [ ;; try to get the demand fulfilled ifelse demand > 0 [ ;; initialize the wait-time if the quantity at store is less than the demand of person if [quantity] of target-store < demand [ set wait-time floor (( demand - [quantity] of target-store ) / supply-rate) ] ;; increase the store visit count and total waiting time for the store accordingly set store-visit-count-list replace-item target-store-id store-visit-count-list (item target-store-id store-visit-count-list + 1) set store-total-waiting-time-list replace-item target-store-id store-total-waiting-time-list (item target-store-id store-total-waiting-time-list + wait-time) let person-demand demand ;; update the quantity at the store and the demand is fulfilled, set it to zero ask target-store[set quantity quantity - person-demand] set demand 0] [ ;; if waiting is over ifelse wait-time = 0 [ ;; move outside the store and get on way back to home set at-store? false set travelling-to-home? true] ;; if still needs to wait, decrease wait-time by 1 [set wait-time wait-time - 1]] ] ;; if is travelling to home travelling-to-home? = true [ ;; if reached near home ifelse (distancexy home-xcor home-ycor) <= 1 [ ;; move inside home and set travelling to home as false setxy home-xcor home-ycor set travelling-to-home? false ;; set a rest-time uniform random in range 1 to person-max-rest-time set rest-time random person-max-rest-time set at-home? true ] ;; if far from home, face towards home and move forward one step [ facexy home-xcor home-ycor fd 1]] ) end ;; display the inner influence circle for the calling store-agent to display-inner-influence-circles ask stores [ let distance-influence inner-influence-radius stamp-circle "circle" distance-influence ] end ;; display the outer influence circles for the calling store-agent to display-outer-influence-circles ask stores [ let distance-influence outer-influence-radius stamp-circle "circle 3" distance-influence ] end ;; to draw the influence circles on the grid ;; it stamps a shape of given size as "distance-influence * 2" ;; parameters are drawing-shape, the shape of the stamp, distance-influence, the radius in case of circles to stamp-circle [drawing-shape distance-influence] ;; store-xcor and store-ycor stores the coordinates of the current store let store-xcor xcor let store-ycor ycor ;; ask the patch-here to create a circle turle, then stamp and then die ask patch-here[ sprout 1[ ;; set the center of the turtle at the store setxy store-xcor store-ycor set shape drawing-shape ;; lighten the shade of the color set color color + 1 ;; make the turtle half transparent set color lput 125 extract-rgb color ;; set appropriate turtle-size for the set size 2 * ( distance-influence ) ;; mark the color impression of the turtle and make it die stamp die ] ] end
There are 3 versions of this model.
Attached files
File | Type | Description | Last updated | |
---|---|---|---|---|
Customer Stores Choice Model.pdf | Research Paper | over 3 years ago, by Sachin Yadav | Download | |
Customer Stores Choice Model.png | preview | Preview for 'Customer Stores Choice Model' | over 3 years ago, by Sachin Yadav | Download |
customer_logic.png | png | Customer Logic Flowchart | over 3 years ago, by Sachin Yadav | Download |
store_logic.png | png | Store Logic Flowchart | over 3 years ago, by Sachin Yadav | Download |
This model does not have any ancestors.
This model does not have any descendants.