Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 11 of 11

Thread: Need some help with a Checkout Area Simulator

  1. #1
    Junior Member
    Join Date
    Apr 2013
    Location
    San Francisco, CA
    Posts
    16
    Thanks
    1
    Thanked 1 Time in 1 Post

    Default Need some help with a Checkout Area Simulator

    Hi all,

    I've been working on this project for the past week and feel like I'm almost done. I've worked through most of the bugs but one is escaping me. The program is a Checkout Area Simulator for an electronics store. The premise is that you can input the amount of total time of the simulation, max duration of each transaction, chances of a new customer arriving, number of cashiers, etc.

    The problem I have is in step 2 of my code: setting a "busy" cashier to "free" and adding a waiting customer from the queue to the "free" cashier. I've run the program and each time that a cashier gets a customer, the customer never leaves and the cashier is never set to "free." I can only see two problems. Either something is wrong with the transaction time, or the cashier is not getting set to "free" and taking a waiting customer. I've looked at the code and everything seems right.

    There are four files in the package but I'll show the code for one of the files where I'm having trouble in step 2. If you need to see the other files, let me know and I'll post them.

     package PJ3;
     
    import java.util.*;
    import java.io.*;
    import java.util.Random;
     
    // You may add new functions or data in this class 
    // You may modify any functions or data members here
    // You must use Customer, Cashier and CheckoutArea
    // to implement your simulator
     
    class CheckoutAreaSimulator {
    	Random rand = new Random();
     
      // input parameters
      private int numCashiers, customerQLimit;
      private int simulationTime, dataSource;
      private int chancesOfArrival, maxCheckoutTime;
     
      // statistical data
      private int numGoaway, numServed, totalWaitingTime;
     
      // internal data
      private int customerIDCounter;
      private CheckoutArea checkoutarea; // checkout area object
      private Scanner dataFile;	     // get customer data from file
     
     
      // most recent customer arrival info, see getCustomerData()
      private boolean anyNewArrival;  
      private int checkoutTime;
     
      // initialize data fields
      private CheckoutAreaSimulator()
      {
    	numCashiers = 0;
    	customerQLimit = 0;
    	simulationTime = 0;
    	dataSource = 0;
    	chancesOfArrival = 0;
    	maxCheckoutTime = 0;
    	numGoaway = 0;
    	numServed = 0;
    	totalWaitingTime = 0;
    	customerIDCounter = 1;
    	checkoutarea = null;
    	dataFile = null;
    	anyNewArrival = false;
    	checkoutTime = 0;
      }
     
      private void setupParameters()
      {
    	// add statements, read input parameters
    	// setup dataFile or dataRandom
    	  Scanner input = new Scanner(System.in);
     
     
          System.out.println("Enter simulation time:");
          do{
          simulationTime = input.nextInt();
          } while(simulationTime < 1 || simulationTime > 10000);
     
          System.out.println("Enter maximum duration of transaction:");
          do{
          maxCheckoutTime = input.nextInt();
          } while(maxCheckoutTime < 1 || maxCheckoutTime > 500);
     
          System.out.println("Enter chances (0% < & <= 100%:) of a new customer:");
          do{
          chancesOfArrival = input.nextInt();
          } while (chancesOfArrival < 1 || chancesOfArrival > 100);
     
          System.out.println("Enter the number of cashiers:");
          do{
        	  numCashiers = input.nextInt();
          } while (numCashiers < 1 || numCashiers > 10);
     
          System.out.println(" Enter customer waiting queue limit: ");
          do{
        	  customerQLimit = input.nextInt();
          } while(customerQLimit < 1 || customerQLimit > 50);
     
          System.out.println(" Enter 1/0 to get data from file/random:");
          do{
          dataSource = input.nextInt();
          } while(dataSource < 0 || dataSource > 1);
     
          if (dataSource == 1){
     
                  System.out.println("Enter filename:");
                  //this asks the user to enter a filename               
                  String file;
                  Scanner scanner = new Scanner(System.in);
                  file = scanner.nextLine();
                  //checks if the filename by the user exists
                        try{
                                dataFile = new Scanner(new File(file));
                        }
                        catch (FileNotFoundException e){
                                System.out.println("Error opening the file:" + file);
                        }      
                        scanner.close();
          }
          input.close();
     
     
    }  
     
     
      private void getCustomerData()
      {
    	// get next customer data : from file or random number generator
    	// set anyNewArrival and checkoutTime
    	// add statements
    	  if (dataSource == 1){
     
              int data1 = dataFile.nextInt();
              int data2 = dataFile.nextInt();
     
              anyNewArrival = (((data1%100)+1)<= chancesOfArrival);
              checkoutTime= (data2%maxCheckoutTime)+1;
              }
     
    else {
                      anyNewArrival = ((rand.nextInt(100)+1) <= chancesOfArrival);
                      checkoutTime = rand.nextInt(maxCheckoutTime)+1;  
     
    }
    }      
     
     
      private void doSimulation()
      {
    	// add statements
     
    	// Initialize CheckoutArea
    	  checkoutarea = new CheckoutArea(numCashiers, customerQLimit, customerIDCounter);
     
     
     
          // Time driver simulation loop
          for (int currentTime = 0; currentTime < simulationTime; currentTime++) {
     
     
                  // Step 1: any new customers?
                      getCustomerData();
                  if (anyNewArrival) {
     
                          Customer newCustomer = new Customer(customerIDCounter, checkoutTime, currentTime);
                          customerIDCounter++;
                          if(checkoutarea.isCustomerQTooLong()){
                                  System.out.println("Customer Q is too long");
                                  numGoaway++;
                          }
                          else{
                                  checkoutarea.insertCustomerQ(newCustomer);
                          }
     
     
                  } else {
                      System.out.println("\tNo new customer!");
                  }
     
     
     
           // Step 2: free busy cashiers, add to free cashierQ
     
           for(int i = 0; i < checkoutarea.numBusyCashiers(); i++){
     
                                  Cashier newCashier = checkoutarea.removeBusyCashierQ();
                                  if(newCashier.getEndBusyIntervalTime() == currentTime) {
                                	  Customer newCustomer;
                                  newCustomer = newCashier.busyToFree();
                                  System.out.println("Customer #:" + newCustomer.getCustomerID() + " is done.");
                                  checkoutarea.insertFreeCashierQ(newCashier);
     
                                  }
                                  else {
     
                                  checkoutarea.insertBusyCashierQ(newCashier);
     
                  }
          }
     
            // Step 3: Get free cashiers to serve waiting customers     
            for(int i = 0; i < checkoutarea.numFreeCashiers(); i++){
     
                          if(checkoutarea.numWaitingCustomers() != 0) {
                                  Customer newCustomer;
                                  newCustomer = checkoutarea.removeCustomerQ();
                                  Cashier newCashier = checkoutarea.removeFreeCashierQ();
                                  newCashier.freeToBusy(newCustomer, currentTime);
                                  System.out.println("Customer #:" + newCustomer.getCustomerID() + "is now busy.");
                                  numServed++;
                                  totalWaitingTime = totalWaitingTime + (currentTime - newCustomer.getArrivalTime());
                          }
                  }
     
     
     
     
     
          }
     
     
     
     
     
      }
     
      private void printStatistics()
      {
    	// add statements into this method!
    	// print out simulation results
    	// see the given example in project statement
            // you need to display all free and busy cashiers
    	  System.out.println("   End of simulation report");
          System.out.println("         # total arrival customers:" + --customerIDCounter);
          System.out.println("         # customers gone-away    :" + numGoaway);
          System.out.println("         # customers served       :" + numServed);
          System.out.println("         *** Current Cashier Info.");
          System.out.println("         # waiting customers      :" + checkoutarea.numWaitingCustomers());
          System.out.println("         # busy cashiers          :" + checkoutarea.numBusyCashiers());
          System.out.println("         # free cashiers          :" + checkoutarea.numFreeCashiers());
          System.out.println("         Total waiting line       :" + totalWaitingTime);
     
     
     
    }
     
     
      // *** main method to run simulation ****
     
      public static void main(String[] args) {
       	CheckoutAreaSimulator runCheckoutAreaSimulator=new CheckoutAreaSimulator();
       	runCheckoutAreaSimulator.setupParameters();
       	runCheckoutAreaSimulator.doSimulation();
       	runCheckoutAreaSimulator.printStatistics();
      }
     
    }


  2. #2
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    SW Missouri
    Posts
    20,074
    Thanks
    47
    Thanked 2,147 Times in 2,120 Posts

    Default Re: Need some help with a Checkout Area Simulator

    Can you explain the sequence of events that the code is trying to follow to do the simulation?

    Post all the code so the program can be tested.
    If you don't understand my answer, don't ignore it, ask a question.

  3. #3
    Junior Member
    Join Date
    Apr 2013
    Location
    San Francisco, CA
    Posts
    16
    Thanks
    1
    Thanked 1 Time in 1 Post

    Default Re: Need some help with a Checkout Area Simulator

    Quote Originally Posted by Norm View Post
    Can you explain the sequence of events that the code is trying to follow to do the simulation?

    Post all the code so the program can be tested.
    Absolutely. First, you enter all of the required fields that the program is asking for (total simulation time, max transaction time, chances of a new customer entering the queue, number of cashiers, customer waiting queue limit, and finally a "0" for a random number generator, or a "1" for a read from a file, which I haven't gotten the file to work yet either), then the program executes according to what you input. At the end, the program displays all of the statistics from the duration of the simulation.

    I'm getting stuck on freeing up a cashier to serve another customer. Currently, it runs with all cashiers taking only one customer and never serving anyone else. Thanks for any help. Here are the other three files in the package:

    // DO NOT ADD NEW METHODS OR DATA FIELDS!
     
    package PJ3;
     
    class Cashier {
     
       // define constants for representing intervals
       static int BUSY = 1;
       static int FREE = 0;
     
       // start time and end time of current interval
       private int startTime;
       private int endTime;
     
       // cashier id and current customer which is served by this cashier 
       private int cashierID;
       private Customer currentCustomer;
     
       // for keeping statistical data
       private int totalFreeTime;
       private int totalBusyTime;
       private int totalCustomers;
     
       // Constructor
       Cashier()
       {
    	   cashierID = -1;
    	   startTime = 0;
    	   endTime = 0;
    	   totalFreeTime = 0;
    	   totalBusyTime = 0;
    	   totalCustomers = 0;
       }
     
     
       // Constructor with cashier id
       Cashier(int cashierId)
       {
    	cashierId = cashierID;
    	startTime = 0;
    	endTime = 0;
    	totalFreeTime = 0;
    	totalBusyTime = 0;
    	totalCustomers = 0;
       }
     
       // accessor methods
     
       int getCashierID () 
       {
    	return cashierID;
       }
     
       Customer getCustomer() 
       {
     
    	return currentCustomer;
       }
     
     
       int getEndBusyIntervalTime() 
       {
     
    	return endTime; 
       }
     
       // functions for state transition
       // FREE -> BUSY :
       void freeToBusy (Customer currentCustomer, int currentTime)
       {
      	// Main goal  : switch from free interval to busy interval
      	//
      	// end free interval, start busy interval
      	// steps	: update totalFreeTime
      	// 		  set startTime, endTime, currentCustomer, 
      	// 		  update totalCustomers
     
    	   totalFreeTime += currentTime - startTime;
    	   BUSY = 1;
    	   this.currentCustomer = currentCustomer;
    	   startTime = currentTime;
    	   endTime = startTime + currentCustomer.getCheckoutDuration();
    	   totalCustomers++;
       }
     
       // BUSY -> FREE :
       Customer busyToFree ()
       {
       	// Main goal : switch from busy interval to free interval
       	// 
      	// steps     : update totalBusyTime 
      	// 	       set startTime 
      	//             return currentCustomer
     
    	   totalBusyTime += endTime - startTime;
    	   FREE = 0;
    	   startTime = endTime;
    	   return currentCustomer;
       }
     
       // need this method at the end of simulation to update cashier data
       void setEndIntervalTime (int endsimulationtime, int intervalType, Customer currentCustomer)
       {
      	// for end of simulation
      	// set endTime, 
      	// for FREE interval, update totalFreeTime
      	// for BUSY interval, update totalBusyTime
     
    	   endTime = endsimulationtime;
    	   if (FREE == 1) {
    		   totalFreeTime += endTime - startTime;
    	   }else{
    		   totalBusyTime += endTime - startTime;
    		   this.currentCustomer = currentCustomer;
    	   }
       }
     
       // functions for printing statistics :
       void printStatistics () 
       {
      	// print cashier statistics, see project statement
     
      	System.out.println("\t\tCashier ID             : "+cashierID);
      	System.out.println("\t\tTotal free time        : "+totalFreeTime);
      	System.out.println("\t\tTotal busy time        : "+totalBusyTime);
      	System.out.println("\t\tTotal # of customers   : "+totalCustomers);
      	if (totalCustomers > 0)
      	    System.out.format("\t\tAverage checkout time  : %.2f%n\n",(totalBusyTime*1.0)/totalCustomers);
       }
     
       public String toString()
       {
    	return "Cashier:"+cashierID+":"+startTime+"-"+endTime+":Customer:"+currentCustomer;
       }
     
       public static void main(String[] args) {
            // quick check
            Customer mycustomer = new Customer(20,30,40);
    	Cashier mycashier = new Cashier(5);
            mycashier.freeToBusy (mycustomer, 13);
            System.out.println(mycashier);
     
       }
     
    };

    package PJ3;
     
    import java.util.*;
     
    //--------------------------------------------------------------------------
    //
    // Define simulation queues in a checkout area. Queues hold references to Customer 
    // and Cashier objects
    //
    // Customer (FIFO) queue is used to hold waiting customers. If the queue is too long
    // (i.e. >  customerQLimnit), customer goes away without entering customer queue
    //
    // There are several cashiers in a checkout area. Use PriorityQueue to 
    // hold BUSY cashiers and FIFO queue to hold FREE cashiers, 
    // i.e. a cashier that is FREE for the longest time should start be used first.
    //
    // To handle cashier in PriorityQueue, we need to define comparator 
    // for comparing 2 cashier objects. Here is a constructor from Java API:
    //
    // 	PriorityQueue(int initialCapacity, Comparator<? super E> comparator) 
    //
    // For priority queue, the default compare function is "natural ordering"
    // i.e. for numbers, minimum value is returned first
    //
    // User can define own comparator class for PriorityQueue.
    // For cashier objects, we like to have smallest end busy interval time first.
    //
    // The following class define compare() for two cashiers :
     
    class CompareCashier implements Comparator<Cashier>{
    	// override compare() method
     	public int compare(Cashier o1, Cashier o2) {
    		return o1.getEndBusyIntervalTime() - o2.getEndBusyIntervalTime(); 
    	}
    }
     
    // DO NOT ADD NEW METHODS OR DATA FIELDS
    class CheckoutArea {
     
     
      // Private data fields:
     
      // define one priority queue 
      private PriorityQueue <Cashier> busyCashierQ;
     
      // define two FIFO queues
      private Queue<Customer> customerQ;
      private Queue<Cashier> freeCashierQ;
     
      // define customer queue limit
      private int customerQLimit;
     
     
      // Constructor 
      public CheckoutArea() 
      {
     
      }
     
      // Constructor 
      public CheckoutArea(int numCashiers, int customerQlimit, int startCashierID)
      {
    	// use ArrayDeque to construct FIFO queue objects
    	ArrayDeque<Customer> adCust = new ArrayDeque<Customer>();
    	ArrayDeque<Cashier> adCash = new ArrayDeque<Cashier>();
    	  customerQ = new ArrayDeque<Customer>();
    	  freeCashierQ = new ArrayDeque<Cashier>();
    	// construct PriorityQueue object
     	// override compare() in Comparator to compare Cashier objects
    	busyCashierQ= new PriorityQueue<Cashier>( numCashiers, 
    						  new CompareCashier()); 
     
    	// initialize customerQlimit
    	this.customerQLimit = customerQlimit;
            // Construct Cashier objects and insert into FreeCashierQ
    	for (int i = startCashierID; i < numCashiers; i++) {
    		freeCashierQ.add(new Cashier(i));
    	}
      }
     
      public Cashier removeFreeCashierQ()
      {
    	  return freeCashierQ.poll();
      }
     
      public Cashier removeBusyCashierQ() 
      {
    	  return busyCashierQ.poll();
      }
     
      public Customer removeCustomerQ()
      {
    	  return customerQ.remove();
      }
     
      public void insertFreeCashierQ(Cashier cashier)
      {
    	  freeCashierQ.add(cashier);
      }
     
      public void insertBusyCashierQ(Cashier cashier)
      {
    	  busyCashierQ.add(cashier);
      }
     
      public void insertCustomerQ(Customer customer)
      {
    	// insert a customer 
    	  customerQ.add(customer);
      }
     
      public boolean emptyFreeCashierQ()
      {
    	// is freeCashierQ empty?
    	  return freeCashierQ.isEmpty();
      }
     
      public boolean emptyBusyCashierQ()
      {
    	// is busyCashierQ empty?
    	  return busyCashierQ.isEmpty();
      }
     
      public boolean emptyCustomerQ()
      {
    	// is customerQ empty?
    	  return customerQ.isEmpty();
      }
     
      public int numFreeCashiers()
      {
    	// get number of free cashiers
    	  return freeCashierQ.isEmpty() ? 0 : freeCashierQ.size();
      }
     
      public int numBusyCashiers()
      {
    	// get number of busy cashiers
    	  return busyCashierQ.isEmpty() ? 0 : busyCashierQ.size();
      }
     
      public int numWaitingCustomers()
      {
    	// get number of customers 
    	  return customerQ.isEmpty() ? 0 : customerQ.size();
      }
     
      public Cashier getFrontBusyCashierQ() 
      {
    	// get front of busy cashiers
    	// "retrieve" but not "remove"
    	  return busyCashierQ.peek();
      }
     
      public boolean isCustomerQTooLong()
      {
    	// is customerQ too long?
    	  return !customerQ.isEmpty() && customerQ.size() >= customerQLimit;
      }
     
      public void printStatistics()
      {
      	System.out.println("\t# waiting customers  : "+numWaitingCustomers());
      	System.out.println("\t# busy cashiers      : "+numBusyCashiers());
      	System.out.println("\t# free cashiers      : "+numFreeCashiers());
      }
     
      public static void main(String[] args) {
     
            // quick check
     
            CheckoutArea sc = new CheckoutArea(4, 5, 1001);
            Customer c1 = new Customer(1,18,10);
            Customer c2 = new Customer(2,33,10);
            Customer c3 = new Customer(3,21,10);
            Customer c4 = new Customer(3,37,10);
      	sc.insertCustomerQ(c1);
      	sc.insertCustomerQ(c2);
      	sc.insertCustomerQ(c3);
    	System.out.println(""+sc.customerQ);
    	System.out.println("Remove customer:"+sc.removeCustomerQ());
    	System.out.println("Remove customer:"+sc.removeCustomerQ());
    	System.out.println("Remove customer:"+sc.removeCustomerQ());
     
    	System.out.println(""+sc.freeCashierQ);
    	Cashier p1=sc.removeFreeCashierQ();
    	Cashier p2=sc.removeFreeCashierQ();
    	Cashier p3=sc.removeFreeCashierQ();
    	Cashier p4=sc.removeFreeCashierQ();
    	System.out.println("Remove free cashier:"+p1);
    	System.out.println("Remove free cashier:"+p2);
    	System.out.println("Remove free cashier:"+p3);
    	System.out.println("Remove free cashier:"+p4);
     
            p1.freeToBusy (c1, 13);
            p2.freeToBusy (c2, 13);
            p3.freeToBusy (c3, 13);
            p4.freeToBusy (c4, 13);
    	sc.insertBusyCashierQ(p1);
    	sc.insertBusyCashierQ(p2);
    	sc.insertBusyCashierQ(p3);
    	sc.insertBusyCashierQ(p4);
    	System.out.println(""+sc.busyCashierQ);
    	p1=sc.removeBusyCashierQ();
    	p2=sc.removeBusyCashierQ();
    	p3=sc.removeBusyCashierQ();
    	p4=sc.removeBusyCashierQ();
    	System.out.println("Remove busy cashier:"+p1);
    	System.out.println("Remove busy cashier:"+p2);
    	System.out.println("Remove busy cashier:"+p3);
    	System.out.println("Remove busy cashier:"+p4);
     
       }
     
     
    };

    // DO NOT ADD NEW METHODS OR DATA FIELDS!
     
    package PJ3;
     
    class Customer
    {
        private int customerID;
        private int checkoutDuration;
        private int arrivalTime;
     
        Customer()
        {
     
        }
     
        Customer(int customerid, int checkoutduration, int arrivaltime)
        {
    	customerid = 0;
    	checkoutduration = 0;
    	arrivaltime = 0;
     
        }
     
        int getCheckoutDuration() 
        {
      	return checkoutDuration;
        }
     
        int getArrivalTime() 
        {
      	return arrivalTime;
        }
     
        int getCustomerID() 
        {
      	return customerID; 
        }
     
        public String toString()
        {
        	return ""+customerID+":"+checkoutDuration+":"+arrivalTime;
     
        }
     
        public static void main(String[] args) {
            // quick check!
    	Customer mycustomer = new Customer(20,30,40);
    	System.out.println("Customer Info:"+mycustomer);
     
        }
    }

  4. #4
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    SW Missouri
    Posts
    20,074
    Thanks
    47
    Thanked 2,147 Times in 2,120 Posts

    Default Re: Need some help with a Checkout Area Simulator

    I was asking about the events in the simulation that control what happens and when. Things like: arrival, wait for cashier, go to cashier, leave cashier. How are all the future events created? Is there a queue that holds the events that the simulator gets the next event from? What is done when an event happens? For example when there is a "leave cashier" event.
    If you don't understand my answer, don't ignore it, ask a question.

  5. #5
    Junior Member
    Join Date
    Apr 2013
    Location
    San Francisco, CA
    Posts
    16
    Thanks
    1
    Thanked 1 Time in 1 Post

    Default Re: Need some help with a Checkout Area Simulator

    Ah, that's in the "CheckoutArea" file. Second one down from the previous post. All of the events are handled there, from cashier free to busy, to customer waiting and being served, to setting up the queue.

  6. #6
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    SW Missouri
    Posts
    20,074
    Thanks
    47
    Thanked 2,147 Times in 2,120 Posts

    Default Re: Need some help with a Checkout Area Simulator

    I'm interested in the design for the code. How are the events created and "executed"?
    For example the initial part of the simulation can create 1000 customers each arriving at a specified time. They are all placed in the event queue. Then the simulation loop starts. It takes the next event from the event queue, say a customer arrival, checks for an empty cashier, moves the customer to the cashier and creates an event for when the cashier is finished and puts that event in the event queue. The next event is taken from the event queue and processed. The loop continues until the event queue is empty.
    When a cashier finished event happens, the customer is moved away from the cashier, the customer waiting queue is checked. If there is a customer waiting, he is moved to a cashier and an event for when the cashier is finished is created and added to the event queue.
    If you don't understand my answer, don't ignore it, ask a question.

  7. #7
    Junior Member
    Join Date
    Apr 2013
    Location
    San Francisco, CA
    Posts
    16
    Thanks
    1
    Thanked 1 Time in 1 Post

    Default Re: Need some help with a Checkout Area Simulator

    Sorry for the confusion. It's pretty much how you just explained it but it's according to each customer's transaction time and the total simulation time you set. You can set the total simulation time to between 1 and 10,000 and the maximum transaction time of each customer to between 1 and 500. Let's just say we set the total simulation time to 100 and the max transaction time to 5. Each cashier and customer are assigned an ID number. At the start, all cashiers are free. When a customer arrives (according to your input of the chances of a customer arriving between 1% - 100%), they are put in the queue. We'll say we set it at 100% so a customer arrives every time interval. There is only one queue or "line" in the store. Then, each customer is assigned to a free cashier. i.e. you set the number of cashiers to 5 and 5 customers come in and get assigned to the 5 free cashiers. When one customer's transaction time is up, the customer leaves the store and that particular cashier is set to free. The next customer in the queue is then assigned to that free cashier, so on and so forth until the total simulation time is up.

    You can also set a queue limit time between 1 and 50 to where a customer will only wait so long in the "line" before leaving the store without purchasing anything. If that limit is reached, the customer will leave the queue. Hope this helps.

  8. #8
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    SW Missouri
    Posts
    20,074
    Thanks
    47
    Thanked 2,147 Times in 2,120 Posts

    Default Re: Need some help with a Checkout Area Simulator

    Try debugging the code by adding some println() statements that print out the values of the variables used to control the logic flow. Use the Customer class's toString() method for most info display.

    This simulation uses "real time" vs event times. The time goes to each unit of time even if there are no events for that time.
    Using event times, the time jumps from one event to the next.
    If you don't understand my answer, don't ignore it, ask a question.

  9. The Following User Says Thank You to Norm For This Useful Post:

    Semion (April 21st, 2013)

  10. #9
    Junior Member
    Join Date
    Apr 2013
    Location
    San Francisco, CA
    Posts
    16
    Thanks
    1
    Thanked 1 Time in 1 Post

    Default Re: Need some help with a Checkout Area Simulator

    I'll try that out. Thanks!

  11. #10
    Junior Member
    Join Date
    Nov 2013
    Posts
    1
    Thanks
    1
    Thanked 0 Times in 0 Posts

    Default Re: Need some help with a Checkout Area Simulator

    Could you please post the fixed files, Semion? Where was the problem?
    Thanks a lot

  12. #11
    Junior Member
    Join Date
    Apr 2013
    Location
    San Francisco, CA
    Posts
    16
    Thanks
    1
    Thanked 1 Time in 1 Post

    Default Re: Need some help with a Checkout Area Simulator

    // DO NOT ADD NEW METHODS OR DATA FIELDS!
     
    package PJ3;
     
    class Cashier {
     
    	// define constants for representing intervals
    	static int BUSY = 1;
    	static int FREE = 0;
     
    	// start time and end time of current interval
    	private int startTime;
    	private int endTime;
     
    	// cashier id and current customer which is served by this cashier 
    	private int cashierID;
    	private Customer currentCustomer;
     
    	// for keeping statistical data
    	private int totalFreeTime;
    	private int totalBusyTime;
    	private int totalCustomers;
     
    	// Constructor
    	Cashier()
    	{
    		this.cashierID = 0;
    		this.startTime = 0;
    		this.endTime = 0;
    		this.totalFreeTime = 0;
    		this.totalBusyTime = 0;
    		this.totalCustomers = 0;
    	}
     
    	// Constructor with cashier id
    	Cashier(int cashierId)
    	{
    		this.cashierID = cashierId;
    		this.startTime = 0;
    		this.endTime = 0;
    		this.totalFreeTime = 0;
    		this.totalBusyTime = 0;
    		this.totalCustomers = 0;
    	}
     
    	// accessor methods
     
    	int getCashierID () 
    	{
    		return cashierID;
    	}
     
    	Customer getCustomer() 
    	{
    		return currentCustomer;
    	}
     
     
    	int getEndBusyIntervalTime() 
    	{
    		return endTime; 
    	}
     
    	// functions for state transition
    	// FREE -> BUSY :
    	void freeToBusy (Customer currentCustomer, int currentTime)
    	{
    		// Main goal  : switch from free interval to busy interval
    		//
    		// end free interval, start busy interval
    		// steps	: update totalFreeTime
    		// 		  set startTime, endTime, currentCustomer, 
    		// 		  update totalCustomers
     
    		totalFreeTime += currentTime - startTime;
    		BUSY = 1;
    		this.currentCustomer = currentCustomer;
    		startTime = currentTime;
    		endTime = startTime + currentCustomer.getCheckoutDuration();
    		totalCustomers++;
    	}
     
    	// BUSY -> FREE :
    	Customer busyToFree ()
    	{
    		// Main goal : switch from busy interval to free interval
    		// 
    		// steps     : update totalBusyTime 
    		// 	       set startTime 
    		//             return currentCustomer
     
    		totalBusyTime += endTime - startTime;
    		FREE = 0;
    		startTime = endTime;
    		//   this.currentCustomer = currentCustomer;
    		//   return currentCustomer;
    		Customer tempCustomer = currentCustomer;
    		this.currentCustomer=null;
    		return tempCustomer;
    	}
     
    	// need this method at the end of simulation to update cashier data
    	void setEndIntervalTime (int endsimulationtime, int intervalType, Customer currentCustomer)
    	{
    		// for end of simulation
    		// set endTime, 
    		// for FREE interval, update totalFreeTime
    		// for BUSY interval, update totalBusyTime
     
    		endTime = endsimulationtime;
    		if (FREE == 1) {
    			totalFreeTime += endTime - startTime;
    		}else{
    			totalBusyTime += endTime - startTime;
    			this.currentCustomer = currentCustomer;
    		}
    	}
     
    	// functions for printing statistics :
    	void printStatistics () 
    	{
    		// print cashier statistics, see project statement
     
    		System.out.println("\t\tCashier ID             : "+cashierID);
    		System.out.println("\t\tTotal free time        : "+totalFreeTime);
    		System.out.println("\t\tTotal busy time        : "+totalBusyTime);
    		System.out.println("\t\tTotal # of customers   : "+totalCustomers);
    		if (totalCustomers > 0)
    			System.out.format("\t\tAverage checkout time  : %.2f%n\n",(totalBusyTime*1.0)/totalCustomers);
    	}
     
    	public String toString()
    	{
    		return "Cashier:"+cashierID+":"+startTime+"-"+endTime+":Customer:"+currentCustomer;
    	}
     
    	public static void main(String[] args) {
    		// quick check
    		Customer mycustomer = new Customer(20,30,40);
    		Cashier mycashier = new Cashier(5);
    		mycashier.freeToBusy (mycustomer, 13);
    		System.out.println(mycashier);
    	}
     
    };

    package PJ3;
     
    import java.util.*;
     
    //--------------------------------------------------------------------------
    //
    // Define simulation queues in a checkout area. Queues hold references to Customer 
    // and Cashier objects
    //
    // Customer (FIFO) queue is used to hold waiting customers. If the queue is too long
    // (i.e. >  customerQLimnit), customer goes away without entering customer queue
    //
    // There are several cashiers in a checkout area. Use PriorityQueue to 
    // hold BUSY cashiers and FIFO queue to hold FREE cashiers, 
    // i.e. a cashier that is FREE for the longest time should start be used first.
    //
    // To handle cashier in PriorityQueue, we need to define comparator 
    // for comparing 2 cashier objects. Here is a constructor from Java API:
    //
    // 	PriorityQueue(int initialCapacity, Comparator<? super E> comparator) 
    //
    // For priority queue, the default compare function is "natural ordering"
    // i.e. for numbers, minimum value is returned first
    //
    // User can define own comparator class for PriorityQueue.
    // For cashier objects, we like to have smallest end busy interval time first.
    //
    // The following class define compare() for two cashiers :
     
    class CompareCashier implements Comparator<Cashier>{
    	// override compare() method
    	public int compare(Cashier o1, Cashier o2) {
    		return o1.getEndBusyIntervalTime() - o2.getEndBusyIntervalTime(); 
    	}
    }
     
    // DO NOT ADD NEW METHODS OR DATA FIELDS
    class CheckoutArea {
     
     
    	// Private data fields:
     
    	// define one priority queue 
    	private PriorityQueue <Cashier> busyCashierQ;
     
    	// define two FIFO queues
    	private Queue<Customer> customerQ;
    	private Queue<Cashier> freeCashierQ;
     
    	// define customer queue limit
    	private int customerQLimit;
     
     
    	// Constructor 
    	public CheckoutArea() 
    	{
     
    	}
     
    	// Constructor 
    	public CheckoutArea(int numCashiers, int customerQlimit, int startCashierID)
    	{
    		// use ArrayDeque to construct FIFO queue objects
    		customerQ = new ArrayDeque<Customer>();
    		freeCashierQ = new ArrayDeque<Cashier>();
    		// construct PriorityQueue object
    		// override compare() in Comparator to compare Cashier objects
    		busyCashierQ= new PriorityQueue<Cashier>( numCashiers, 
    				new CompareCashier()); 
     
    		// initialize customerQlimit
    		this.customerQLimit = customerQlimit;
    		// Construct Cashier objects and insert into FreeCashierQ
    		for (int i = startCashierID; i < startCashierID+numCashiers; i++) {
    			freeCashierQ.add(new Cashier(i));
    		}
    	}
     
    	public Cashier removeFreeCashierQ()
    	{
    		return freeCashierQ.poll();
    	}
     
    	public Cashier removeBusyCashierQ() 
    	{
    		return busyCashierQ.poll();
    	}
     
    	public Customer removeCustomerQ()
    	{
    		return customerQ.remove();
    	}
     
    	public void insertFreeCashierQ(Cashier cashier)
    	{
    		freeCashierQ.add(cashier);
    	}
     
    	public void insertBusyCashierQ(Cashier cashier)
    	{
    		busyCashierQ.add(cashier);
    	}
     
    	public void insertCustomerQ(Customer customer)
    	{
    		// insert a customer 
    		customerQ.add(customer);
    	}
     
    	public boolean emptyFreeCashierQ()
    	{
    		// is freeCashierQ empty?
    		return freeCashierQ.isEmpty();
    	}
     
    	public boolean emptyBusyCashierQ()
    	{
    		// is busyCashierQ empty?
    		return busyCashierQ.isEmpty();
    	}
     
    	public boolean emptyCustomerQ()
    	{
    		// is customerQ empty?
    		return customerQ.isEmpty();
    	}
     
    	public int numFreeCashiers()
    	{
    		// get number of free cashiers
    		return freeCashierQ.isEmpty() ? 0 : freeCashierQ.size();
    	}
     
    	public int numBusyCashiers()
    	{
    		// get number of busy cashiers
    		return busyCashierQ.isEmpty() ? 0 : busyCashierQ.size();
    	}
     
    	public int numWaitingCustomers()
    	{
    		// get number of customers 
    		return customerQ.isEmpty() ? 0 : customerQ.size();
    	}
     
    	public Cashier getFrontBusyCashierQ() 
    	{
    		// get front of busy cashiers
    		// "retrieve" but not "remove"
    		return busyCashierQ.peek();
    	}
     
    	public boolean isCustomerQTooLong()
    	{
    		// is customerQ too long?
    		return !customerQ.isEmpty() && customerQ.size() >= customerQLimit;
    	}
     
    	public void printStatistics()
    	{
    		System.out.println("\t# waiting customers  : "+numWaitingCustomers());
    		System.out.println("\t# busy cashiers      : "+numBusyCashiers());
    		System.out.println("\t# free cashiers      : "+numFreeCashiers());
    	}
     
    	public static void main(String[] args) {
     
    		// quick check
     
    		CheckoutArea sc = new CheckoutArea(4, 5, 1001);
    		Customer c1 = new Customer(1,18,10);
    		Customer c2 = new Customer(2,33,10);
    		Customer c3 = new Customer(3,21,10);
    		Customer c4 = new Customer(3,37,10);
    		sc.insertCustomerQ(c1);
    		sc.insertCustomerQ(c2);
    		sc.insertCustomerQ(c3);
    		System.out.println(""+sc.customerQ);
    		System.out.println("Remove customer:"+sc.removeCustomerQ());
    		System.out.println("Remove customer:"+sc.removeCustomerQ());
    		System.out.println("Remove customer:"+sc.removeCustomerQ());
     
    		System.out.println(""+sc.freeCashierQ);
    		Cashier p1=sc.removeFreeCashierQ();
    		Cashier p2=sc.removeFreeCashierQ();
    		Cashier p3=sc.removeFreeCashierQ();
    		Cashier p4=sc.removeFreeCashierQ();
    		System.out.println("Remove free cashier:"+p1);
    		System.out.println("Remove free cashier:"+p2);
    		System.out.println("Remove free cashier:"+p3);
    		System.out.println("Remove free cashier:"+p4);
     
    		p1.freeToBusy (c1, 13);
    		p2.freeToBusy (c2, 13);
    		p3.freeToBusy (c3, 13);
    		p4.freeToBusy (c4, 13);
    		sc.insertBusyCashierQ(p1);
    		sc.insertBusyCashierQ(p2);
    		sc.insertBusyCashierQ(p3);
    		sc.insertBusyCashierQ(p4);
    		System.out.println(""+sc.busyCashierQ);
    		p1=sc.removeBusyCashierQ();
    		p2=sc.removeBusyCashierQ();
    		p3=sc.removeBusyCashierQ();
    		p4=sc.removeBusyCashierQ();
    		System.out.println("Remove busy cashier:"+p1);
    		System.out.println("Remove busy cashier:"+p2);
    		System.out.println("Remove busy cashier:"+p3);
    		System.out.println("Remove busy cashier:"+p4);
     
    	}
     
     
    };

    package PJ3;
     
    import java.util.*;
    import java.io.*;
    import java.util.Random;
     
    // You may add new functions or data in this class 
    // You may modify any functions or data members here
    // You must use Customer, Cashier and CheckoutArea
    // to implement your simulator
     
    class CheckoutAreaSimulator {
    	Random rand = new Random();
     
    	// input parameters
    	private int numCashiers, customerQLimit;
    	private int simulationTime, dataSource;
    	private int chancesOfArrival, maxCheckoutTime;
     
    	// statistical data
    	private int numGoaway, numServed, totalWaitingTime;
     
    	// internal data
    	private int customerIDCounter;
    	private CheckoutArea checkoutarea; // checkout area object
    	private Scanner dataFile;	     // get customer data from file
     
     
    	// most recent customer arrival info, see getCustomerData()
    	private boolean anyNewArrival;  
    	private int checkoutTime;
     
    	// initialize data fields
    	private CheckoutAreaSimulator()
    	{
    		numCashiers = 0;
    		customerQLimit = 0;
    		simulationTime = 0;
    		dataSource = 0;
    		chancesOfArrival = 0;
    		maxCheckoutTime = 0;
    		numGoaway = 0;
    		numServed = 0;
    		totalWaitingTime = 0;
    		customerIDCounter = 0;
    		checkoutarea = null;
    		dataFile = null;
    		anyNewArrival = false;
    		checkoutTime = 0;
    	}
     
    	private void setupParameters()
    	{
    		// add statements, read input parameters
    		// setup dataFile or dataRandom
    		Scanner input = new Scanner(System.in);
     
     
    		System.out.println("Enter simulation time:");
    		do{
    			simulationTime = input.nextInt();
    		} while(simulationTime < 1 || simulationTime > 10000);
     
    		System.out.println("Enter maximum duration of transaction:");
    		do{
    			maxCheckoutTime = input.nextInt();
    		} while(maxCheckoutTime < 1 || maxCheckoutTime > 500);
     
    		System.out.println("Enter chances (0% < & <= 100%:) of a new customer:");
    		do{
    			chancesOfArrival = input.nextInt();
    		} while (chancesOfArrival < 1 || chancesOfArrival > 100);
     
    		System.out.println("Enter the number of cashiers:");
    		do{
    			numCashiers = input.nextInt();
    		} while (numCashiers < 1 || numCashiers > 10);
     
    		System.out.println(" Enter customer waiting queue limit: ");
    		do{
    			customerQLimit = input.nextInt();
    		} while(customerQLimit < 1 || customerQLimit > 50);
     
    		System.out.println(" Enter 1/0 to get data from file/random:");
    		do{
    			dataSource = input.nextInt();
    		} while(dataSource < 0 || dataSource > 1);
     
    		if (dataSource == 1){
     
    			System.out.println("Enter filename:");
    			//this asks the user to enter a filename               
    			String file;
    			Scanner scanner = new Scanner(System.in);
    			file = scanner.nextLine();
    			//checks if the filename by the user exists
    			try{
    				dataFile = new Scanner(new File(file));
    			}
    			catch (FileNotFoundException e){
    				System.out.println("Error opening the file:" + file);
    			}      
    			scanner.close();
    		}
    		input.close();
     
     
    	}  
     
     
    	private void getCustomerData()
    	{
    		// get next customer data : from file or random number generator
    		// set anyNewArrival and checkoutTime
    		// add statements
    		if (dataSource == 1){
     
    			int data1 = dataFile.nextInt();
    			int data2 = dataFile.nextInt();
     
    			anyNewArrival = (((data1%100)+1)<= chancesOfArrival);
    			checkoutTime= (data2%maxCheckoutTime)+1;
    		}
     
    		else {
    			anyNewArrival = ((rand.nextInt(100)+1) <= chancesOfArrival);
    			checkoutTime = rand.nextInt(maxCheckoutTime)+1;  
     
    		}
    	}      
     
     
    	private void doSimulation()
    	{
    		// add statements
     
    		// Initialize CheckoutArea
    		checkoutarea = new CheckoutArea(numCashiers, customerQLimit, 1);
     
     
     
    		// Time driver simulation loop
    		for (int currentTime = 0; currentTime < simulationTime; currentTime++) {
    			System.out.println("Time "+currentTime);
     
    			// Step 1: any new customers?
    			getCustomerData();
    			if (anyNewArrival) {
    				customerIDCounter++;
    				Customer newCustomer = new Customer(customerIDCounter, checkoutTime, currentTime);
    				System.out.println("\tCustomer id #"+customerIDCounter+" arrives with checkout time "+newCustomer.getCheckoutDuration()+" units");
     
    				if(checkoutarea.isCustomerQTooLong()){
    					System.out.println("\tCustomer Q is too long: Customer id "+customerIDCounter+" leaves the queue");
    					numGoaway++;
    				}
    				else{
    					checkoutarea.insertCustomerQ(newCustomer);
    					System.out.println("\tCustomer id "+customerIDCounter+" waits in the customer queue");
    				}
     
     
    			} else {
    				System.out.println("\tNo new customer!");
    			}
     
    			// Step 2: free busy cashiers, add to free cashierQ
     
    			for(int i = 0; i < checkoutarea.numBusyCashiers(); i++){
    				//Peek and check if it is still busy, if not remove and add it to free, otherwise do nothing
    				Cashier newCashier = checkoutarea.getFrontBusyCashierQ();
    				if(newCashier.getEndBusyIntervalTime() <= currentTime) {
    					Customer newCustomer;
    					newCashier = checkoutarea.removeBusyCashierQ();
    					newCustomer = newCashier.busyToFree();	                              
    					System.out.println("\tCustomer #:" + newCustomer.getCustomerID() + " is done.");
    					checkoutarea.insertFreeCashierQ(newCashier);
    					System.out.println("\tCashier #:" + newCashier.getCashierID() + " is free.");
    				}
     
    			}
     
    			// Step 3: get free cashiers to serve waiting customers 
     
    			for(int i = 0; i < checkoutarea.numFreeCashiers(); i++){
     
    				if(checkoutarea.numWaitingCustomers() != 0) {
    					Customer newCustomer = checkoutarea.removeCustomerQ();
    					Cashier newCashier = checkoutarea.removeFreeCashierQ();
    					newCashier.freeToBusy(newCustomer, currentTime);
    					//insert  cashier to busy queue; 
    					checkoutarea.insertBusyCashierQ(newCashier);
    					System.out.println("\tCustomer #:" + newCustomer.getCustomerID() + "gets a cashier.");
    					System.out.println("\tCashier #:" + newCashier.getCashierID() + " starts serving customer #"+newCustomer.getCustomerID()+" for "+newCustomer.getCheckoutDuration()+" units.");
    					System.out.println("\tCustomer #:" + newCashier.getCustomer().getCustomerID() + ", currently served , is set to now busy cashier #"+newCashier.getCashierID());
    					numServed++;
    					totalWaitingTime = totalWaitingTime + (currentTime - newCustomer.getArrivalTime());
    				}
    			}
    		}
    	}
     
    	private void printStatistics()
    	{
    		// add statements into this method!
    		// print out simulation results
    		// see the given example in project statement
    		// you need to display all free and busy gas pumps
    		System.out.println("   End of simulation report");
    		System.out.println("         # total arrival customers :" + --customerIDCounter);
    		System.out.println("         # customers gone-away :" + numGoaway);
    		System.out.println("         # customers served :" + numServed);
    		System.out.println("         *** Current Cashier Info.");
    		System.out.println("         # waiting customers       :" + checkoutarea.numWaitingCustomers());
    		System.out.println("         # busy cashiers" + checkoutarea.numBusyCashiers());
    		System.out.println("         # free cashiers" + checkoutarea.numFreeCashiers());
    		System.out.println("         Total waiting line :         " + totalWaitingTime);
     
    		System.out.println("         *** Busy Cashiers Info. :");
    		while(checkoutarea.numBusyCashiers()>0){
    			Cashier cashier = checkoutarea.removeBusyCashierQ();
    			cashier.setEndIntervalTime ( simulationTime, Cashier.BUSY, cashier.getCustomer());
    			cashier.printStatistics();
    		}
     
    		System.out.println("         *** Free Cashiers Info. :");
    		while(checkoutarea.numFreeCashiers()>0){
    			Cashier cashier = checkoutarea.removeFreeCashierQ();
    			cashier.setEndIntervalTime ( simulationTime, Cashier.FREE, cashier.getCustomer());
    			cashier.printStatistics();
    		}
    	}
     
     
    	// *** main method to run simulation ****
     
    	public static void main(String[] args) {
    		CheckoutAreaSimulator runCheckoutAreaSimulator=new CheckoutAreaSimulator();
    		runCheckoutAreaSimulator.setupParameters();
    		runCheckoutAreaSimulator.doSimulation();
    		runCheckoutAreaSimulator.printStatistics();
    	}
     
    }

    // DO NOT ADD NEW METHODS OR DATA FIELDS!
     
    package PJ3;
     
    class Customer
    {
    	private int customerID;
    	private int checkoutDuration;
    	private int arrivalTime;
     
    	Customer()
    	{
     
    	}
     
    	Customer(int customerid, int checkoutduration, int arrivaltime)
    	{
    		this.customerID = customerid;
    		this.checkoutDuration = checkoutduration;
    		this.arrivalTime = arrivaltime;
     
    	}
     
    	int getCheckoutDuration() 
    	{
    		return checkoutDuration;
    	}
     
    	int getArrivalTime() 
    	{
    		return arrivalTime;
    	}
     
    	int getCustomerID() 
    	{
    		return customerID; 
    	}
     
    	public String toString()
    	{
    		return ""+customerID+":"+checkoutDuration+":"+arrivalTime;
     
    	}
     
    	public static void main(String[] args) {
    		// quick check!
    		Customer mycustomer = new Customer(20,30,40);
    		System.out.println("Customer Info:"+mycustomer);
     
    	}
    }

  13. The Following User Says Thank You to Semion For This Useful Post:

    adgteq (November 7th, 2013)

Similar Threads

  1. Traffic Simulator
    By slimergan in forum What's Wrong With My Code?
    Replies: 1
    Last Post: December 5th, 2012, 05:38 AM
  2. smpp simulator
    By ridg18 in forum Java Theory & Questions
    Replies: 3
    Last Post: September 21st, 2012, 06:57 PM
  3. Developing a simulator
    By jack_nutt in forum AWT / Java Swing
    Replies: 1
    Last Post: September 5th, 2012, 07:06 AM
  4. Checkout line Simulation
    By BuhRock in forum What's Wrong With My Code?
    Replies: 4
    Last Post: November 7th, 2011, 09:38 PM
  5. Creating a Simulator
    By william in forum Java Theory & Questions
    Replies: 4
    Last Post: June 16th, 2011, 10:11 AM