Checkout Simulation Time Table Conditions

Checkout Simulation Time Table Conditions

kevskon
Enthusiast Enthusiast
326 Views
8 Replies
Message 1 of 9

Checkout Simulation Time Table Conditions

kevskon
Enthusiast
Enthusiast

Hey @moehlmann_fe it is me again with our favorite checkout simulation. I created a new global table AssociatesByHour showing how many available associates can run traditional and quick lane registers each quarter hour from 7-22. I am trying to do something different from the current model, where I utilize this table to tell the simulation how many lanes are open at a given time in the simulation run, instead of our current logic to open and close registers each quarter hour based on queue lengths. I am trying to test the results of the two versions against each other, hoping you can provide some guidance on how I can modify the simulation to achieve this. Thank you!

0 Likes
Accepted solutions (3)
327 Views
8 Replies
Replies (8)
Message 2 of 9

moehlmann_fe
Enthusiast
Enthusiast
Accepted solution

This is actually much simpler than the previous logic. You can add a label to the token that denotes the current row of the table. At each interval, increment the row by one and then compare the number in the table to the number of currently active lanes. If there is a difference, have the token shift queues from the inactive list to the active list or vice versa to match the number from the table.

The attached model assumes that the rows follow a fixed interval of 15min. But you could also read the date and time and delay the token until that time is reached. Check out the DateTime class and its methods for that.

https://docs.flexsim.com/en/25.0/Reference/CodingInFlexSim/FlexScriptAPIReference/Data/DateTime.html

Message 3 of 9

kevskon
Enthusiast
Enthusiast

This is great! Now if possible I would like to take this a step further. I updated the table AssociatesByHour to provide more granularity as to what type of lanes should be open, for example if there are 5 max associates I would like to test 3 different scenarios ( 5 Std 0 QL , 4 Std 1 QL, 3 Std 2 QL). I added a column with a scenario number and 12 different configurations for that day. I think we are getting close and I really appreciate all your help. My true end goal is me being able to summarize all the data into a table that looks somewhat like this: 

StoreDateIntervalStartIntervalEnd  MaxAssociatesStdLanes OpenQLs OpenSLs OpenCustomerType Count QLItemCount Sum QL CustomersAvgStaytime QL CustomersCustomerType Count TRADItemCount Sum TRAD CustomersAvgStaytime TRAD CustomersNum QL Cust using QLNum QL Cust using SLNum QL Cust using StdL
14/25/20257:00:00 AM7:15:00 AM1108         
14/25/20258:15:00 AM8:30:00 AM2208         
14/25/20259:00:00 AM9:15:00 AM3218         
14/25/202511:15:00 AM11:30:00 AM5328         
14/25/202512:00:00 PM12:15:00 PM4318         

I basically want to compare the experience of QL customers to TRAD customers across different lane configuration scenarios.

Thank you!

0 Likes
Message 4 of 9

moehlmann_fe
Enthusiast
Enthusiast
Accepted solution

To use that table I would change the logic to create one token per queue. That token then looks up whether its queue should be active or not. I have made that change for the Std-Lanes in the attached model. The Quick-Lanes would function the same just with a different column offset. The Self-Lanes are represented by the processors and share a queue. As such they are not pushed/pulled from the Lane list. Instead you would just open/close their inputs.

I added a parameter to denote the chosen scenario. The Associates table copies all entries belonging to that scenario from a master table in its reset trigger. That way you don't have to deal with managing the correct starting and end row in the process flow.

 

With regards to your other post: The number of customers per 15min interval can be tracked with the default "Throughput By Type By Hour" chart. The Statistics Collector for that chart can be edited to also count the number of items. But it uses a template that is shared with many other charts and as such it is (in my opinion) needlessly complicated for what it does. Building a new Statistics Collector from scratch isn't much harder due to this, especially if you copy the relevant functionality from the "Throughput By Type By Hour" one.

 

In the attached model I assign a WaitTime label to each customer when they exit a queue. This is then used by the Stats Collector to also track the total and average wait time of customers. (I feel like "AverageStaytime" is a bit ambiguous when used in the context of measurement in a fixed interval. So tracking the wait time of customers who left during that timeframe is what I decided makes the most sense)

Message 5 of 9

kevskon
Enthusiast
Enthusiast

Thank you so much this is very helpful! A few more minor things:

- Is it at all possible to bring the lane type label in as well so I can get the stats for QL vs TRAD customers on Std vs Quick vs Self lanes? I tried adding in another event for lane type using the same code as for the workload stats collector and it overwrote the customer type and if I just add the column only I get blanks because it doesn't know I'm referring to the queue labels 

kevskon_0-1751042254542.png

- Is there a way to test and visually see what is happening in one of my other scenarios 2-12 without having to overwrite the AssociatesByHour table or can those just be ran in the Experimenter only? Edit: Ok I think I just answered this myself, I can go in the Parameters table and change the value and that is very cool!! Where is the reset trigger that overwrites the table located?

- As for self lanes not being able to follow the same logic because they are connected to the same queue, do you think I could just create 9 more queues and use the same logic as for Std lanes? I've got a lot of different SL configurations I am going to test for different stores with a differing number of SL's so opening/closing their inputs manually will not be feasible.

Thanks again for all your help!

 

0 Likes
Message 6 of 9

moehlmann_fe
Enthusiast
Enthusiast
Accepted solution

- To get the customer and register type, you have to use an array of both values as row value, so each row is identified by the combination of both values. The event object is the processor which you can access as current. You can get the lane type by reading the label from the queue - the processor's inObject.

- As I said, the table copies the relevant entries to itself in its reset trigger.

moehlmann_fe_0-1751053779855.png

- You could certainly also use one queue per self checkout. But the inputs don't need to be set manually. The structure of the logic stays the same, just that instead of swapping a value between lists, the token closes/opens the input of the processor. (In addition updating the "BusyCheckouts" label on the queue, so they are properly accounted for in the lane choice logic). If there is ever a case where all self checkouts are closed, you would need to detect that and pull the queue from the list of active lanes.

 

Message 7 of 9

kevskon
Enthusiast
Enthusiast

Hey @moehlmann_fe!

I am currently working on a few more adjustments to this simulation and was wondering if you could help me out again. I want to set the simulation up to be able to run through multiple dates and stores at once, I added a store column to the AssociatesByHour_All table, added 720 rows for an additional 12 scenarios for a different store on a different date and added 3 new parameters for store, date & store-date combo. I assume for anything involving dates I have to use options.

kevskon_0-1751937025045.png

In the AssociatesByHour reset trigger I used the same methodology for the store parameter as the RegisterScenario parameter.

kevskon_1-1751937142599.png

On the arrivals table that feeds the source with flow items, I added another column and changed the column headers to be the store-date combo and am hoping to set it up so that the parameter will choose the right set of arrivals for the correct scenarios, but not sure if it is working as intended yet. 

kevskon_2-1751937317735.png

And the most challenging change I need to make is to the empirical distribution that feeds the ItemCount label creation. The item count distribution varies by time of day and from store to store and I don't know exactly how I can set it up within the built in empirical distribution properties to have more conditions. I added all of the data I am trying to use to accomplish this in the ItemDist global table, there is a frequency and weight column header for each hour of the day for 200 rows ( 1-200 items ) for the first store-date combo and then in rows 201-400 for the next store-date combo. Not sure if this is possible to achieve, but I wanted to see if you have some ideas.

kevskon_3-1751937680440.png

Lastly, I think this one might be easy but I tried it and must have gotten the syntax wrong. On the processors R1-R15 I am trying to make an adjustment to the process time (currently 0.464 + item.ItemCount*0.0642). I want to add an if statement in here to add more time if the item count label is over 30 and want it to look like this: 

0.464 + ( item.ItemCount * 0.0642 ) + if ( item.ItemCount > 30, ( ( item.ItemCount - 30 ) * 0.0126 * 0.5 ), 0 )

I know this is a lot and happy to post separate new posts, thanks for your continued help!

0 Likes
Message 8 of 9

kevskon
Enthusiast
Enthusiast

Hey @moehlmann_fe

I had to change my reset trigger a little for it to work properly, but now it does.

kevskon_0-1752083449887.png

The arrivals being store specific I believe I got working too, by following a similar methodology and creating a master table arrivals_all and a table with a reset trigger using the store-date combo variable like this:

kevskon_1-1752083632527.png

For the empirical item distribution to be store specific I could probably use a similar methodology again with a master table and reset trigger, but getting it to work time of day specific is something I am still struggling with.

As for the processing time if statement formula [ 0.464 + ( item.ItemCount * 0.0642 ) + if ( item.ItemCount > 30, ( ( item.ItemCount - 30 ) * 0.0126 * 0.5 ), 0 ) ] still getting a 'Could not finish parsing because of previous errors' message in the console. Thanks!

0 Likes
Message 9 of 9

kevskon
Enthusiast
Enthusiast

This did the trick for the processing time if statement: 0.464 + (item.ItemCount * 0.0642) + (item.ItemCount > 30 ? ((item.ItemCount - 30) * 0.0126 * 0.5) : 0)

Just need help with the time of day specific empirical distribution, I may start a new topic, thank you!