210 likes | 224 Views
This introduction to computing lab simulates a supermarket checkout system with cashiers and customers. Explore Queue Data Structures and Cashier Operations.
E N D
ITI 1221. Introduction to Computing IILab-8 Dewan Tanvir Ahmed University of Ottawa
Today’s Objective • Case Study • Simulating a Supermarket Check out
MarketModel Creates Generates Serves Cashier Customer Uses Contains Queue Supermarket Checkout – General Idea (cont..) For simplicity, Let’s consider only one cashier, During Program we’ll handle it.
Supermarket Checkout • Two types of Cashiers • Express ( if number of items are less 13 ) • Regular • Each cashier has an queue for the customers • A new customer joins to a queue having minimum number of customers for both cases (express and regular cashiers).
Customer • Each customer has • Arrival time • Initial number of items • Remaining number of items for serve • Constructor to initialize the instance variables • public Customer(int arrivalTime, int numberOfItems) • Methods • Access methods • arrival time and • number of remaining items • Current status of the Served (on going) customer • int numberOfServedItems() • number of items served so far • Update remaining items of a customer • void serve()
Customer – (cont..) public class Customer { private int arrivalTime; private int numberOfItems; private int initialnumberOfItems; // constructor public Customer(int arrivalTime, int numberOfItems) { this.arrivalTime = arrivalTime; this.numberOfItems = numberOfItems; this.initialnumberOfItems = numberOfItems; } public int numberOfServedItems() { return this.initialnumberOfItems - this.numberOfItems; } public void serve() {numberOfItems--; } // access methods public int arrivalTime() { return arrivalTime; } public int numberOfItems() { return numberOfItems; } }
Queue public interface Queue { public void enqueue(Object obj); public Object dequeue(); public boolean isEmpty(); public int size(); }
Queue - ArrayQueue public class ArrayQueue implements Queue { private static final int MAX_QUEUE_SIZE = 10000; private Object[] q; private int front, rear, size; public ArrayQueue() { q = new Object[MAX_QUEUE_SIZE]; front = 0; rear = -1; size = 0; } public int size() { return size; } public boolean isEmpty() { return size == 0; } public boolean isFull() { return size == MAX_QUEUE_SIZE; }
Queue – ArrayQueue (cont..) public void enqueue(Object o) { // pre-condition: ??? if (rear == (MAX_QUEUE_SIZE -1)) { int j=0; for (int i=front; i<=rear; i++) { q[j++] = q[i]; } front = 0; rear = size - 1; } q[++rear] = o; size++; } public Object dequeue() { // pre-condition: ??? Object savedValue = q[front]; q[front] = null; front++; size--; return savedValue; } } // end of the class
Cashier • Each cashier has • Total waiting time of all customers • Total number of served customers • Total number of served items • Current customer • A queue to store waiting customers • Constructor • Initialize - instance variables • You need a Queue Data Structure • Methods & Access methods • Get total waiting time • Get total served items • Get total served customers • Add a new customer to the cashier queue • Get Number of customers in the queue • Serve one customer at a time
Cashier – (cont..) public class Cashier { private int totalCustomerWaitTime, customersServed, totalItemsServed; private Customer currentCustomer; private Queue queue; // constructor public Cashier(){ totalCustomerWaitTime = 0; customersServed = 0; currentCustomer = null; totalItemsServed = 0; queue = new ArrayQueue(); } // access methods public int getTotalCustomerWaitTime() { return this.totalCustomerWaitTime; } public int getTotalItemsServed() { if(this.currentCustomer != null) return totalItemsServed + this.currentCustomer.numberOfServedItems(); else return totalItemsServed; } public int getTotalCustomersServed() { return customersServed; } public void addCustomer(Customer c){ queue.enqueue(c); } public int lengthOfQueue() { return queue.size(); }
Cashier – (cont..) public void serveCustomers(int currentTime){ if (currentCustomer == null){ // no customers yet!!! if (queue.isEmpty()) return; else{ // dequeue first waiting customer and tally results currentCustomer = (Customer) queue.dequeue(); totalCustomerWaitTime = totalCustomerWaitTime + currentTime - currentCustomer.arrivalTime(); customersServed++; } } // give a unit of service currentCustomer.serve(); // if current customer is finished, send it away if (currentCustomer.numberOfItems() == 0) { totalItemsServed += currentCustomer.numberOfServedItems(); currentCustomer = null; } } } // end of the class
Cashiers • Cashiers has • An array of cashier • Constructor • Initialized the size of the cashiers array • Methods • Adding a new customer • Where size of the queue is minimum • Serving customers at a particular instant of time • toString() • Average number of customers currently waiting • Average number of items per customer • Average waiting time per customer • Average number of customers served per cashier • Average number of items Handled per cashier • Total number of clients served • Total number of items handled
Cashiers – (cont..) import java.text.NumberFormat; public class Cashiers { private Cashier[] cashiers; private static final String nl = System.getProperty("line.separator"); public Cashiers(int n) { if (n < 1) throw new IllegalArgumentException(); cashiers = new Cashier[n]; for (int i=0; i<n; i++) cashiers[i] = new Cashier(); } public void addCustomer(Customer c) { int iMax, vMax; iMax = 0; for (int i=1; i<cashiers.length; i++) if (cashiers[i].lengthOfQueue() < cashiers[iMax].lengthOfQueue()) iMax = i; cashiers[iMax].addCustomer(c); }
Cashiers – (cont..) public void serveCustomers(int currentTime) { for (int i=0; i<cashiers.length; i++) cashiers[i].serveCustomers(currentTime); } public String toString() { int nbCustomers = 0; int nbItems = 0; int waitingTime = 0; int nbServedCustomers = 0; String out = "Tally: " + nl; for (int i=0; i<cashiers.length; i++) { nbCustomers += cashiers[i].lengthOfQueue(); nbItems += cashiers[i].getTotalItemsServed(); waitingTime += cashiers[i].getTotalCustomerWaitTime(); nbServedCustomers += cashiers[i].getTotalCustomersServed(); } double aveLength = (double) nbCustomers / (double) cashiers.length; double aveItemsCustomer = (double) nbItems/ (double) nbServedCustomers; double aveItemsCashier = (double) nbItems/ (double) cashiers.length; double aveWaitingTimeCus = (double) waitingTime / (double) nbServedCustomers; double aveServedCustomersCashier = (double) nbServedCustomers/ (double) cashiers.length;
Cashiers – (cont..) NumberFormat nf = NumberFormat.getNumberInstance(); out += "Average number of customers currently waiting: " + nf.format(aveLength) +nl; out += "Average number of items per customer: " + nf.format(aveItemsCustomer)+nl; out += "Average waiting time per customer: " + nf.format(aveWaitingTimeCus)+nl; out += "Average number of customers served per cashier: " + nf.format(aveServedCustomersCashier)+nl; out += "Average number of items Handled per cashier: " + nf.format(aveItemsCashier)+nl; out += "Total number of clients served: " + nf.format(nbServedCustomers)+nl; out += "Total number of items handled: " + nf.format(nbItems)+nl; return out; } }
MarketModel public class MarketModel { private static final int SECONDS_PER_MINUTE = 60; private static final int MINUTES_PER_HOUR = 60; private static final int TICK = 5; private static final String nl = System.getProperty("line.separator"); private static final double probabilityOfNewArrival = 0.5; private Cashiers express; private Cashiers regular; private int lengthOfSimulation, aveNbItems; public MarketModel(int duration) { this.lengthOfSimulation = duration; express = new Cashiers(3); regular = new Cashiers(10); }
MarketModel – (cont..) public void runSimulation() { int currentTime = 0; while (currentTime < lengthOfSimulation) { if (Math.random() <= probabilityOfNewArrival) { Customer customer = new Customer(currentTime, (int) (50 * Math.random()) + 1); if (customer.numberOfItems() <= 12) express.addCustomer(customer); else regular.addCustomer(customer); } express.serveCustomers(currentTime); regular.serveCustomers(currentTime); if ((currentTime % (5 * SECONDS_PER_MINUTE)) == 0) System.out.println(this); currentTime += TICK; } }
MarketModel – (cont..) public String toString() { String out = "MarketModel" + nl; out += "express lanes: " + express + nl; out += "regular lanes: " + regular + nl; return out; } public static void main(String[] args) throws java.io.IOException { MarketModel mm = new MarketModel(SECONDS_PER_MINUTE * MINUTES_PER_HOUR); mm.runSimulation(); } }