Decision-making Simulation: Checkout Lines
The main purpose of this project is to give you the opportunity to use your Queue implementation to simulate shoppers picking which check-out line to use. We'll use the simulation to compare the performance of three different algorithms for selecting a queue. For example, if you are checking out at a big box store, there may be 20 queues open. How do you optimize your choice?
The optimal process would be to select the queue with the shortest line. However, in practice that takes a lot of work, and by the time you're done picking, the situation may have changed.
The simplest strategy is to pick a line at random. While it takes no time, following a random strategy means you may end up at the end of the longest line, standing next to a short line.
It turns out that a much better strategy than picking randomly is to pick two queues randomly and then select the shorter queue (Mitzenmacher, The Power of Two Choices in Randomized Load Balancing, TPDS, 2001).
Design and implement a simulation of a multi-station checkout situation. Once you have your simulation working, test out the three strategies given below for customers selecting a checkout line.
- Randomly select one checkout line.
- Scan all of the checkout stations and pick the shortest checkout line.
- Randomly select two checkout lines. Of the two, pick the one with the shortest line.
You can design this simulation however you like. The tasks are simply hints as to one design approach within the general framework.
- This simulation involves adding and removing agents each turn. One method of adding agents to a simulation is to have a Spawner agent class that has no visual representation but that adds a certain number of agents to the Landscape each iteration. When you set up the simulation, adding a single Spawner agent takes care of adding whatever other kinds of agents are needed for the simulation. In this case, the Spawner would be creating Customer agents.
- The simulation obviously needs a Customer agent. The Customer
agent needs to know how many items it has and also needs to keep track
of what it is doing each iteration. When starting, give each Customer
just one item.
The trajectory a Customer agent should follow is described below. These behaviors should be implemented as part of the Customer's updateState() method.
- After spawning, the Customer should be in the selection phase. Depending on the strategy it is using, the selection phase should take 1 time step (random), 2 time steps (best of 2 random choices), or 4 time steps (check all counters). An extension is to design the class so the wait time for the check-all strategy is proportional to the number of checkout counters.
- At the end of the selection phase, the Customer should join a CheckoutQueue, entering the wait phase.
- When the Customer is at the head of a CheckoutQueue, the Checkout agent should decrement the number of items in the Customer's basket. When there is nothing left in the Customer's basket, the Customer should remove itself from the simulation.
To achieve the above trajectory, the Customer agent must have fields for its current phase, how much time is left until it can select a queue, and how many items it has in its basket. The Customer should also keep track of how many turns it takes from spawning until the customer reaches the head of the checkout queue. For flexibility, it may also be useful to have a field that determines the agent's selection strategy, although this could be a global class variable.
The Customer must have methods to allow a Checkout agent to both test and decrement the number of items in its basket.
- The simulation will also need a Checkout agent. The checkout agent
needs to maintain a queue of Customers. For this project, use the
MyQueue class you wrote yourself in the lab. You may not use a Java
library type to implement the queue (except during debugging, if you
To enable the customer to make decisions, the Checkout agent must be able to tell a Customer agent the length of its queue. You can decide whether the length of a queue is modified by the number of items in each Customer's basket.
In its updateState method, the Checkout agent needs to set the spatial position of each Customer agent in its queue on each iteration since each Customer agent will always be situated relative to the (non-moving) Checkout agents. The Checkout agent's updateState method should implement the following rules.
- There is no one in line: do nothing.
- There is a Customer at the head of the line with more than zero items in their basket: decrement the number of items in the Customer's basket.
- There is a Customer at the head of the line with zero items in their basket: remove this Customer from the checkout queue and update the positions of all other Customer agents in the queue.
The Checkout agent class needs to have methods so a Customer can join a checkout queue.
- Create a new CheckoutSimulation class that initializes a Landscape with several Checkout agents and a single Spawner agent. Place all of the Checkout agents at the bottom of the Landscape, regularly spaced, with the lines growing upwards. The simulation should continue until the application is closed. Make sure to balance the number of Customers being spawned with the number of items per customer and the number of Checkout agents. On the first turn it is reasonable to create extra Customer agents to populate the store.
- Once your simulation is working, run lots of customers (at least 2000) and calculate the average and standard deviation of the time to check out for the three different strategies. You may want to add some type of list to the Landscape to either hang on to all Customers removed from the simulation, or store just the time to checkout for each Customer that completes the process. Have the statistics periodically print out during the simulation, such as once every 100 customers.
- Try other strategies for checking out. Keep track of how complex they are.
- Make the simulation visually interesting.
- Allow each agent to choose one of the three strategies randomly. Then calculate the statistics for each strategy in the mixed situation. Which strategy does the best?
- For any assignment, a good extension will be to implement a Java class that you have't implemented in the past projects and demonstrate that it has the same functionality as the Java class.
- Re-implement your Queue using an array-based method instead of a Node-based method and show the functionality is identical.
Your report should have a simple format.
- A brief description of the overall project, in your own words. Identify both the data structure used and the simulation built using it. Finish by indicating whether the simulation worked as expected and what you discovered.
- An explanation of your solution, focusing on the interesting bits. In this assignment, for example, the line-choosing strategies are the interesting bits, as is how you visualized the simulation.
- Printouts, pictures, or results to show what you did. For this assignment, you should include at least one animated gif or video of the simulation and a report of the customer check-out time statistics. Graphs are better than pure text! But all images (all results of any kind, really) should be interpreted for your audience in accompanying text.
- Other results to demonstrate extensions you undertook. If you tried additional line-choosing strategies, for example, show how those affected the overall simulation results.
- A brief conclusion and description of what you learned.
- A list of people you worked with, including TAs, and instructors. Include in that list anyone whose code you may have seen, such as those of friends who have taken the course in a previous semester.
Make your report for the project a wiki page in your personal space. If you have questions about making a wiki page, stop by my office or ask in lab.
Once you have written up your assignment, give the page the label:
You can give any wiki page a label using the label field at the bottom of the page. The label is different from the title.
Do not put code on your writeup page or anywhere it can be publicly accessed. To hand in code, put it in your folder on the Courses fileserver. Create a directory for each project inside the private folder inside your username folder.