0

Okay. I am actually having an issue with logic more-so than with the actual coding of the main method. Here is the background:

Your program will allow the manager to run multiple simulations for different numbers of customers to determine the optimal number of servers to hire. The exact service time for a customer is difficult to predict. Using an average time based on past observations is one possible approach. But, a more realistic strategy is to use average minimum and maximum service times and generate each customer’s service time randomly between these two numbers. The program will allow the manager to set the minimum and maximum length of service time. Predicting how often customers will arrive (represented usually by the customer inter-arrival time) is another issue to be addressed. Again, a strategy similar to generating service times is used. The program will allow the manager to enter minimum and maximum inter-arrival times. The exact time between arrivals for each customer will be generated randomly between the two inter-arrival times.

Your program will read in the following data:

  • minimum and maximum service times (in minutes)
  • minimum and maximum inter-arrival times (in minutes)
  • the number of customers

Once the data items are entered, your program will display

  • the average wait time for the customers
  • the largest number of customers waiting in line during the entire simulation (maximum queue length).

In a situation like this, where the inputs variables are random in nature, running a simulation just once is not adequate for drawing reliable inferences. So, the program should also allow the manager to run the simulation multiple times.

I wrote out pseudocode for the program and it seemed okay until I was working it by hand and realized that some of the times are actual times and some are durations of time.

The problem that I am having is that the only way I can calculate some things is by using info from a previous customer that is no longer available as that customer has been removed from the queue (adapted from a single linked list).

How can I organize the simulation by time instead of customer arrival? (Algorithm help would be preferred to code as it would most help me understand the logic, which is the problem I am having.)

Here is the code that I have so far in the main method:

/**
 * Class FastFoodSimulation simulates customer service at a fast food restaurant.
 * This simulation serves as a tool for managers to determine how many servers are needed
 * for average amount of customers to be serviced in a timely manner.
 * 
 * @author (Ebony Brewer) 
 * @version (10272013)
 */
import javax.swing.JOptionPane;
import java.util.Random;

public class FastFoodSimulation
{
    public static void main(String args[])
    {
    int time;
    boolean reRun = true;
    int maxQueueLength;
    int customerCounter;
    int serviceTime;
    int arrivalTime;
    int departureTime;
    int waitTime;
    int interArrivalTime;
    int totalTime;
    int totalWaitTime;

    do
    {
        int minServiceTime = Integer.parseInt(JOptionPane.showInputDialog("Enter Minimum Service Time (in minutes)."));
        int maxServiceTime = Integer.parseInt(JOptionPane.showInputDialog("Enter Maximum Service Time (in minutes)."));
        int minInterArrivalTime = Integer.parseInt(JOptionPane.showInputDialog("Enter Minimum Time Between Customers(in minutes)."));
        int maxInterArrivalTime = Integer.parseInt(JOptionPane.showInputDialog("Enter Maximum Time Between Customers(in minutes)."));
        int numberOfCustomers = Integer.parseInt(JOptionPane.showInputDialog("Enter Number of Customers to Simulate."));

        time = 0;
        //LinkedQueue queue = new LinkedQueue();
        maxQueueLength = 0;
        customerCounter = 0;
        arrivalTime = 0;
        departureTime = 0;
        waitTime = 0;
        totalTime = 0;
        totalWaitTime = 0;

        while(customerCounter < numberOfCustomers)
        {
            serviceTime = randInt(minServiceTime, maxServiceTime);
            interArrivalTime = randInt(minInterArrivalTime, maxInterArrivalTime);
            arrivalTime = time + interArrivalTime;

            SimulationCustomer cust = new SimulationCustomer();
            cust.setServiceTime(serviceTime);
            cust.setInterArrivalTime(interArrivalTime);
            cust.setArrivalTime(arrivalTime);

            if(time == cust.getArrivalTime() && maxQueueLength == 0)
            {
                //queue.offer(cust);
                customerCounter++;
                departureTime = arrivalTime + serviceTime;
                totalTime = departureTime - arrivalTime;
                cust.setWaitTime(0);
                cust.setDepartureTime(departureTime);
                cust.setTotalTime(totalTime);
                //int length = queue.size();
                //if(length > maxQueueLength)
                  //  maxQueueLength = length;
                //queue.remove(cust);
                time++;
            }
            else if(time == cust.getArrivalTime() && maxQueueLength >= 1)
            {
                //queue.offer(cust);
                customerCounter++;
            }
        }
    }
    while(reRun);
}
/**
 * Returns a psuedo-random number between min and max, inclusive.
 * The difference between min and max can be at most
 * Integer.MAX_VALUE - 1
 * By Greg Case @ http://stackoverflow.com/questions/363681/generating-random-numbers-in-a-range-with-java
 *
 * @param min Minimim value
 * @param max Maximim value.  Must be greater than min.
 * @return Integer between min and max, inclusive.
 * @see java.util.Random#nextInt(int)
 */
public static int randInt(int min, int max)
{

    // Usually this can be a field rather than a method variable
    Random rand = new Random();

    // nextInt is normally exclusive of the top value,
    // so add 1 to make it inclusive
    int randomNum = rand.nextInt((max - min) + 1) + min;

    return randomNum;
}

}

Aalyiah7492
  • 33
  • 1
  • 4
  • 1
    A good start, but it is not clear what your problem is. Please describe it in more detail, and try to make the provided code more concise. It will help us to help you. – Zong Nov 05 '13 at 23:42
  • *"The problem that I am having is that the only way I can calculate some things is by using info from a previous customer"* - I'm curious as to why? Are you trying to monitor changes in the state, if so, you should have arrive and leave style events so that you can be notified when some state has changed and make calculations from there? – MadProgrammer Nov 05 '13 at 23:44
  • I'm also curious about the *"the number of customers"* value? Is this the expected total number of customers or some other value? – MadProgrammer Nov 05 '13 at 23:44
  • Consider the `Restaurant`, it may have one or more `Counter`s, each `Counter` will have a FIFO `Queue` of `Customer`s... Try to implement that. – Germann Arlington Nov 05 '13 at 23:45
  • Well I guess a better way to put it is to say that I can only think of using the previous customers info in some cases. For example, the only way I can think to calculate the wait time of a customer that arrives while someone else is still being served (ordering/receiving food) is to use the previous customers departure time vs the current customers arrival time. I thought to store it in a variable but had the problem that the information would be incorrect after the first customer and would not be able to update info either. The program is just getting really far from the algorithm I had. – Aalyiah7492 Nov 06 '13 at 01:15
  • The number of customer is the number of customers the manager would like to run the simulation for. Ex. How long to service and clear 30 customers in one sinulation. – Aalyiah7492 Nov 06 '13 at 01:17

2 Answers2

1

You don't have a complete/workable logical structure for the simulation.

At the moment, you drive the simulation by customers walking in the door. Having just set their arrival time, you then check the arrival time (redundantly).. before trying to decide what to do with them.

Driving the loop by customers walking in the door is not necessarily wrong -- but it's not necessarily simplest or easiest either. You have to drive the loop by something, but could drive by time instead.

You need to manage "state" within the restaurant. Currently you don't have logic to put customers into the queue, to finish serving customers, or to serve the next customers in the queue.

"Customer states" within the restaurant define the transitions, aka events, which your program must implement & model for this simulation to be correct.

As to your comments: all the generated & specified times are intervals. You may internally want to use or generate a reference time or timestamp for scheduling upcoming events, or to print for logging purposes.

There's no problem with needing info from the last customer after using it -- you can either keep a last variable & use that later, or randomly generate nextCustomerTime while you still have the customer. This is all pretty simple.

Lastly, put your "single simulation run" code into a method, or (perhaps even better) a separate class. Simpler & clearer will enable you to more clearly isolate your relevant logic, work on it & focus on getting it right.

Thomas W
  • 13,374
  • 3
  • 50
  • 70
  • Thank you for your response. I realize, now that my whole simulation is falling apart, that it is kinda backwards in structure. It all started with a faulty algorithm that looked fine until I began translating it into code. Would you be able to show me a way to start that manages with time instead of customer arrival via a beginning algorithm?? I can't figure out how to code anything because I can't wholly grasp the possible solution. – Aalyiah7492 Nov 06 '13 at 01:44
1

You should use a PriorityQueue<FastFoodEvent> instance, where the events include some of CustomerEnters, CustomerOrders, CustomerServed. The events all have a time variable, and the queue will order by time.

You'll want a Customer class that has an id and some I/O methods.

You'll want some Cashier objects, each of which will try to handle customers from the queue. While a cashier is handling a customer, he does not handle another. Alternatively, he may have his own queue.

Eric Jablow
  • 7,611
  • 2
  • 20
  • 29
  • Thank you for your response but I need to use a queue adapted by a linked list so a priority queue is not acceptable, but a very good solution as it does order the time thru the heap underlay. – Aalyiah7492 Nov 06 '13 at 01:51
  • Good answer @EricJablow I think -- the `PriorityQueue` would be a very nice way to store, sort & receive the "events-by-time" used in this simulation. One point is that events with equal time could be in arbitrary order, so generating both "customer enters" and "customer orders" with simultaneous times (when there is no-one else in the queue) are not explicitly guaranteed to be de-queued in order. I assume it is possible to design the algorithm within such a limitation, anyway.. it's just a detail to implementation design. – Thomas W Nov 08 '13 at 00:44
  • "Customer 5 enters" and "Customer 3 orders" can happen at the same time. That doesn't matter very much, I don't think. Besides, "Customer 5" enters" would be followed by "Customer 5 enters Cashier 1's queue", which would be followed later by him coming to the end of the queue, and his ordering. There won't be a single method that generates all the events in advance. – Eric Jablow Nov 12 '13 at 00:27