queue simulation to calculate customer waiting time - java

I've been working away at this problem for the past 10-12 hours, and was wondering if you guys could help me debug/point me in the right general direction. The object of the program is to simulate a fast food store queue-line, which I'm attempting to accomplish using:
PriorityQueue (FIFO) data structure
I've consulted with colleagues, on-campus tutoring services, professors and the given course textbook: "Java How To Program: Deitel & Deitel" to no avail.
The provided pseudocode for the problem is as follows (I'm not trying to get you to do it for me):
BigBurger Inc. wants to see if having a single person at the counter both to take orders and to serve them is feasible. At each BigBurger, customers will arrive and get in line. When they get to the head of the line they will place their order, which will be assembled and served to them. Then they will leave the BigBurger and the next person in line will be able to order.
We need to know how long a customer may be forced to wait before he or she can place an order. Given a script that lists each customer for a typical day, we want to calculate the maximum customer waiting time. Each customer in the script is characterized by an arrival time (measured in minutes after the store opened) and a service duration (the number of minutes between ordering and getting the food).
Create a class BigBurger that contains method maxWait that is given a int[] arrival and a int[] service describing all the customers and returns the maximum time spent by a customer between arriving and placing the order. Corresponding elements of arrival and service refer to the same customer, and they are given in the order in which they arrive at the store (arrival is in non-descending order).
If multiple customers arrive at the same time they will all join the line at the same time, with the ones listed earlier ahead
of ones appearing later in the list.
Definition
    
Class:
BigBurger
Method:
maxWait
Parameters:
int[], int[]
Returns:
int
Method signature:
int maxWait(int[] arrival, int[] service)
(be sure your method is public)
    
Constraints-
arrival will contain between 1 and 50 elements inclusive-
service will contain the same number of elements as arrival-
the elements of arrival will be in non-decreasing order-
each element of arrival will be between 1 and 720 inclusive-
each element of service will be between 1 and 15 inclusive
Examples    
{3,3,9}
{2,15,14}
Returns: 11
Two customers arrive at time 3. The first one waits 0 time, orders, and is served after 2 minutes, leaving at time 5. The second one then orders and is served at time 20. Meanwhile a customer arrives at time 9 and waits until the second customer leaves. This last customer then orders at time 20, and is served and leaves at time 20+14 = 34. The first customer waited 0 minutes, the second waited 2 minutes (from time 3 to time 5), and the last customer waited 11 minutes (from time 9 to time 20).
    
I have researched for example on the net, usually arrival time is calculated using system nano time or using a random method, but here in this case the arrival time and service time is already provided in the examples and I have to calculate the total wait time of each customer. Please guide me through this as I am new to coding.
The issues I'm experiencing:
Unable to print maxWaitTime for the customer when I call return maxWaitTime in the method maxWait(int[], int[])
Here is my code:
import java.util.*;
public class QueueProgram
{
static int[] arrival = {3,3,9};
static int[] service = {2,15,14};
int waitTime;
int finishTime;
int serviceTime;
static int index;
Queue<Integer> Customers = new LinkedList<Integer>();
public int maxWait(int[] arrival, int[] service)
{
//this.arrival = arrival;
//this.service = service
int maxWaitTime = 0;
int[]finishTime = new int[arrival.length];
for(int i=0; i<arrival.length;i++)
{
int startTime;
index = i;
if(index == 0)
{
startTime = arrival[index];
System.out.println(startTime);
}
else
{
startTime = Math.max(arrival[i],finishTime[i-1]);
}
finishTime[i] = startTime + service[i];
waitTime = finishTime[i] - service[i] - arrival[i];
if(waitTime > maxWaitTime)
{
maxWaitTime = waitTime;
}
}
return maxWaitTime;
}
public static void main(String[] args)
{
QueueProgram q = new QueueProgram();
q.maxWait(arrival, service);
}
}

import java.util.*;
public class QueueProgram
{
static int[] arrival = {3,3,9};
static int[] service = {2,15,14};
int waitTime;
int finishTime;
int serviceTime;
static int index;
Queue<Integer> Customers = new LinkedList<Integer>();
public int maxWait(int[] arrival, int[] service)
{
//this.arrival = arrival;
//this.service = service
int maxWaitTime = 0;
int[]finishTime = new int[arrival.length];
for(int i=0; i<arrival.length;i++)
{
int startTime;
index = i;
if(index == 0)
{
startTime = arrival[index];
//System.out.println(startTime);
}
else
{
startTime = Math.max(arrival[i],finishTime[i-1]);
}
finishTime[i] = startTime + service[i];
waitTime = finishTime[i] - service[i] - arrival[i];
if(waitTime > maxWaitTime)
{
maxWaitTime = waitTime;
}
}
return maxWaitTime;
}
public static void main(String[] args)
{
QueueProgram q = new QueueProgram();
q.maxWait(arrival, service);
System.out.println("Maximum wait time is: " + q.maxWait(arrival, service));
}
}

variable index is redundant, i already represents array index. Secondly, waitTime can be calculated as finshTime[i-1]-arrival[i], no need to calculate startTime. Lesser operations better space and time complexity.
try this:
for(int i=0; i<arrival.length;i++)
{
if(i != 0) {
waitTime = finishTime[i-1] - arrival[i];
if(waitTime > maxWaitTime)
{ maxWaitTime = waitTime;}
}
finishTime[i] = arrival[i] + service[i];
}

Related

How to calculate how many start-end pairs run in a given range of time-of-day

I have class called Running with start time and end time:
public class Running {
private double startTime;
private double endTime;
public Running(double startTime, double endTime) {
this.startTime = startTime;
this.endTime = endTime;
}
}
And in my main class:
Running runningA = new Running(1, 10);
Running runningB = new Running(5,9);
Running runningC = new Running(4, 8);
How can I calculate in the right way between which time most of them are running?
For example:
between 5 to 8 all of them are running
between 1 to 3 only one run
I'm not sure why the Running class holds the start time and end time as doubles rather than ints, but okay.
Using your example:
Running runningA = new Running(1, 10);
Running runningB = new Running(5, 9);
Running runningC = new Running(4, 8);
We create a List<Running> to hold the 3 instances of Running. Then we do the following:
Create a Map<Integer, Integer>
Go through the List<Running> and find the minimum start time and the maximum end time.
Start a time counter at the minimum start time.
Go through the List<Running> and see which instances have a time counter in their range. The first instance has a 1, for example. So we put a (time counter, 1) in the map.
Increment the time counter and repeat step 4 until the maximum end time.
The Map contains the answer for each time. Iterate through the Map and summarize which time periods have 1 instance, which time periods have 2 instances, and so on.
You can create a method in your class called 'isBetween' that returns if the object is between passed startTime and endTime:
public class Running {
private double startTime;
private double endTime;
public Running(double startTime, double endTime) {
this.startTime = startTime;
this.endTime = endTime;
}
public boolean isBetween(int startTime, int endTime) {
return return startTime>=this.startTime && endTime<=this.endTime && startTime<=endTime;
}
#Override
public String toString() {
return "Start time: " + this.startTime + " End time: " + this.endTime ;
}
}
And in your main method, you can verify if only one object is between two times, or if all objects in a list are between two given numbers:
public static void main(String[] args) {
Running runningA = new Running(1, 10);
Running runningB = new Running(5,9);
Running runningC = new Running(4, 8);
List<Running> list = new ArrayList<>();
list.add(runningA);
list.add(runningB);
list.add(runningC);
// for only one object:
System.out.println(runningA.isBetween(5, 8)); //print true if object is between 5 and 8
// for all objects in a list:
list.stream().filter(n -> n.isBetween(5, 8)).forEach(System.out::println); //print all objects between 5 and 8
}

Compartmentalizing loops over a large iteration

The Goal of my question is to enhance the performance of my algorithm by splitting the range of my loop iterations over a large array list.
For example: I have an Array list with a size of about 10 billion entries of long values, the goal I am trying to achieve is to start the loop from 0 to 100 million entries, output the result for the 100 million entries of whatever calculations inside the loop; then begin and 100 million to 200 million doing the previous and outputting the result, then 300-400million,400-500million and so on and so forth.
after I get all the 100 billion/100 million results, then I can sum them up outside of the loop collecting the results from the loop outputs parallel.
I have tried to use a range that might be able to achieve something similar by trying to use a dynamic range shift method but I cant seem to have the logic fully implemented like I would like to.
public static void tt4() {
long essir2 = 0;
long essir3 = 0;
List cc = new ArrayList<>();
List<Long> range = new ArrayList<>();
// break point is a method that returns list values, it was converted to
// string because of some concatenations and would be converted back to long here
for (String ari1 : Breakpoint()) {
cc.add(Long.valueOf(ari1));
}
// the size of the List is huge about 1 trillion entries at the minimum
long hy = cc.size() - 1;
for (long k = 0; k < hy; k++) {
long t1 = (long) cc.get((int) k);
long t2 = (long) cc.get((int) (k + 1));
// My main question: I am trying to iterate the entire list in a dynamic way
// which would exclude repeated endpoints on each iteration.
range = LongStream.rangeClosed(t1 + 1, t2)
.boxed()
.collect(Collectors.toList());
for (long i : range) {
// Hard is another method call on the iteration
// complexcalc is a method as well
essir2 = complexcalc((int) i, (int) Hard(i));
essir3 += essir2;
}
}
System.out.println("\n" + essir3);
}
I don't have any errors, I am just looking for a way to enhance performance and time. I can do a million entries in under a second directly, but when I put the size I require it runs forever. The size I'm giving are abstracts to illustrate size magnitudes, I don't want opinions like a 100 billion is not much, if I can do a million under a second, I'm talking massively huge numbers I need to iterate over doing complex tasks and calls, I just need help with the logic I'm trying to achieve if I can.
One thing I would suggest right off the bat would be to store your Breakpoint return value inside a simple array rather then using a List. This should improve your execution time significantly:
List<Long> cc = new ArrayList<>();
for (String ari1 : Breakpoint()) {
cc.add(Long.valueOf(ari1));
}
Long[] ccArray = cc.toArray(new Long[0]);
I believe what you're looking for is to split your tasks across multiple threads. You can do this with ExecutorService "which simplifies the execution of tasks in asynchronous mode".
Note that I am not overly familiar with this whole concept but have experimented with it a bit recently and give you a quick draft of how you could implement this.
I welcome those more experienced with multi-threading to either correct this post or provide additional information in the comments to help improve this answer.
Runnable Task class
public class CompartmentalizationTask implements Runnable {
private final ArrayList<Long> cc;
private final long index;
public CompartmentalizationTask(ArrayList<Long> list, long index) {
this.cc = list;
this.index = index;
}
#Override
public void run() {
Main.compartmentalize(cc, index);
}
}
Main class
private static ExecutorService exeService = Executors.newCachedThreadPool();
private static List<Future> futureTasks = new ArrayList<>();
public static void tt4() throws ExecutionException, InterruptedException
{
long essir2 = 0;
long essir3 = 0;
ArrayList<Long> cc = new ArrayList<>();
List<Long> range = new ArrayList<>();
// break point is a method that returns list values, it was converted to
// string because of some concatenations and would be converted back to long here
for (String ari1 : Breakpoint()) {
cc.add(Long.valueOf(ari1));
}
// the size of the List is huge about 1 trillion entries at the minimum
long hy = cc.size() - 1;
for (long k = 0; k < hy; k++) {
futureTasks.add(Main.exeService.submit(new CompartmentalizationTask(cc, k)));
}
for (int i = 0; i < futureTasks.size(); i++) {
futureTasks.get(i).get();
}
exeService.shutdown();
}
public static void compartmentalize(ArrayList<Long> cc, long index)
{
long t1 = (long) cc.get((int) index);
long t2 = (long) cc.get((int) (index + 1));
// My main question: I am trying to iterate the entire list in a dynamic way
// which would exclude repeated endpoints on each iteration.
range = LongStream.rangeClosed(t1 + 1, t2)
.boxed()
.collect(Collectors.toList());
for (long i : range) {
// Hard is another method call on the iteration
// complexcalc is a method as well
essir2 = complexcalc((int) i, (int) Hard(i));
essir3 += essir2;
}
}

Timer alternative to measure request rate on the server side

I have client-server application in which i need to measure the rate of request arrival per second(Request rate). For this, i have a timer object that activates after every seconds, reads a synchronized counter and then sets it to zero. The counter increments on each request arrival.I used following code to detect request rate. There are so many other threads and timers in my application running.The problem is "due to the inaccuracy of timers i am not getting the perfect request rate". Is there any alternative of measuring request rate other than using timers.
public class FrequencyDetector extends TimerTask {
RequestCounter requestCounter;
FrequencyHolder frequencyHolder;
public FrequencyDetector(RequestCounter requestCounter,FrequencyHolder frequencyHolder){
this.frequencyHolder=new FrequencyHolder();
this.frequencyHolder=frequencyHolder;
}
#Override
public void run() {
int newFrequency=requestCounter.getCounter();
frequencyHolder.setFrequency(newFrequency);
requestCounter.setCounterToZero();
//calls to other fuctions
}
}
Instead of checking counter per unit time you can check time per unit counter. That will probably give you more accurate results. Algorithm is given below.
Increment counter on every request.
When counter reaches a certain FIXED_LIMIT calculate frequency by frequency=FIXED_LIMIT/duration since last record
Reset the counter and start with step 1
However this will record frequency at unpredictable intervals and if frequency of request decreases the duration between successive records will increase.
To handle it we can implement an adaptive algorithm, algorithm is given below.
Increment the counter on every request.
When counter reaches a certain ADAPTIVE_LIMIT record frequency as frequency=ADAPTIVE_LIMIT/duration since last record
Change ADAPTIVE_LIMIT as ADAPTIVE_LIMIT=frequency * DESIRED RECORD INTERVAL
Reset counter and start with step 1.
Above algorithm will reset the limit based on frequency last recorded. It's given that it will not be recording at optimal intervals but it will be pretty close.
Also it will give you highly accurate frequencies as it does not depend on any scheduled thread.
Following is an implementation of such an adaptive counter.
import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;
public class TestCounter {
//Keep initial counterInterval to a small value otherwise first record may take long time
final AtomicLong counterInterval = new AtomicLong(10);
AtomicLong requestCounter = new AtomicLong();
volatile long lastTime;
/**OPTIMAL_DURATION is the duration after which frequency is expected to be recorded
* Program adaptively tries to reach this duration
*/
static final double OPTIMAL_DURATION = 1.0; // 1 second
static final Random random = new Random();
public static void main(String[] args) {
System.out.println("Started ");
TestCounter main = new TestCounter();
for(int i = 0; i < 1000; i++) {
main.requestArrived();
}
}
/*
* Simulating requests
*/
public void requestArrived() {
printCounter();
try {
Thread.sleep(random.nextInt(100));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//This will be in some Utility class
private void printCounter() {
requestCounter.incrementAndGet();
long currentTime = System.nanoTime();
long currentInterval = counterInterval.get();
if(requestCounter.get() > currentInterval) {
if(lastTime != 0) {
long timeDelta = currentTime - lastTime;
long frequency = (long)(currentInterval / (timeDelta / 1e9));
System.out.printf("time=%.2f, frequency=%d\n", (timeDelta / 1e9), frequency);
//updating the currentInterval for the miss
long newCounterInterval = (long)(frequency * OPTIMAL_DURATION);
counterInterval.set(newCounterInterval);
}
requestCounter.set(0);
lastTime = currentTime;
}
}
}
Output
Started
time=0.54, frequency=18
time=0.98, frequency=18
time=1.01, frequency=17
time=0.96, frequency=17
time=0.99, frequency=17
time=0.85, frequency=19
time=0.96, frequency=19
time=0.82, frequency=23
time=1.08, frequency=21
time=0.98, frequency=21
time=0.94, frequency=22
time=1.06, frequency=20
time=1.07, frequency=18
time=0.99, frequency=18
time=0.98, frequency=18
time=1.02, frequency=17
time=0.92, frequency=18
time=0.92, frequency=19
time=0.89, frequency=21
time=0.82, frequency=25
time=1.31, frequency=19
time=1.02, frequency=18

Decrementing value stored in a queue

I'm working on a queue project where the program is simulating a grocery store. In my program, I have a method call that sets up a random variable that represents the time that it takes to service the customer in queue. The total iterations are 60, signifying minutes. Say if the first customer is given a 4 minute wait time, I need to be able to decrement the time after each minute until it reaches 0. I cannot figure out how to decrement the value stored in the queue named myQueue. Any suggestions how I can decrease the value stored in the queue after each minute?
import java.util.*;
import java.util.Random;
public class GroceryStore{
public static void main (String[] args){
int newCust=0; //to hold random variable 1-4 for 25% chance of new customer
Queue<Integer> myQueue = new LinkedList<Integer>(); //instantiates new queue
int wait = 0;
int numCust = 0; //holds counter for number of customer
for (int i = 1; i <= 60; i++) //iterator to cycle through 60 minutes
{
Random randomNum = new Random();
newCust = randomNum.nextInt(4)+1; //gives random #1-4, if 1, new cust added
if(newCust == 1) //if statement to execute code if new cust added
{
Customer cust = new Customer();
wait = cust.getServiceTime(); //stores wait time in variable
myQueue.add(wait); //adds customer to the queue by wait time
System.out.println("New customer added to queue, queue length is now " + myQueue.size());
}
if(myQueue.isEmpty()) //if to check if queue is empty and skip other conditionals
System.out.println("-----------");
else if(myQueue.peek()==0) //if top of queue is at 0, remove from queue
{
myQueue.remove();
System.out.println("Customer removed");
}
else
//THIS IS WHERE I AM TRYING TO DECREASE THE VALUE IN THE TOP QUEUE
}
Integer is immutable, so wrap an int in your own class:
class Customer {
int time;
public Customer(int time) {
this.time = time;
}
// getter, setter
}
and define a corresponding Queue:
Queue<Customer> myQueue = new ...;
Instantiate a java.util.Timer; in the corresponding java.util.TimerTask, iterate through the Queue using a for-each loop, altering or removing each in turn:
for (Customer c : myQueue) { ... }
Your wanting to decrement a value stored in the Customer object that is located at the top of the queue.
The easiest way would be to add a method to reduce the serviceTime within the Customer class.
public decServiceTime() {
serviceTime--;
}
Looking at the value associated to the Customer object sitting in the queue you can perform the actions necessary.
Also if you have any questions you should first try sending me, your TA an email. =)

Java: PriorityQueue - Grocery Store Simulation

I've been working away at this problem for the past 10-12 hours, and was
wondering if you guys could help me debug/point me in the right general direction. The object of the program is to simulate a grocery store queue-line, which I'm attempting to accomplish using:
PriorityQueue (FIFO) data structure
System.nanoTime() - to keep track of elapsed time
SimpleDateFormat - to keep track of when customers enter queue (timestamp)
I've consulted with colleagues, on-campus tutoring services, professors and the given course textbook: "Java How To Program: Deitel & Deitel" to no avail.
The provided pseudocode for the problem is as follows (I'm not trying to get you to do it for me):
Run the supermarket simulation for a 12-hour day (720 minutes), using the following algorithm:
Choose a random integer between 1 and 4 to determine the mintue at which first customer arrives
At first customer's arrival time, do the following:
Determine the customer's service time (random integer 1 to 4)
Begin servicing the customer
Schedule arrival time of next customer (random integer 1 to 4 added to current time)
For each minute of the day, consider the following:
If the next customer arrives, proceed as follows:
Say so.
Enqueue the customer.
Schedule the arrival time of the next customer.
If the service was completed for the last customer, do the following:
Say so.
Dequeue the next customer to be serviced
Determine the customer's service completion time (random integer from 1 to 4 added to the current time)
The issues I'm experiencing:
Attempts to 'delay' program as customers arrive/are serviced are ineffective (perhaps System.nanoTime() miscalculations? (I've double checked all calculations, may still be wrong) - see: newCustomer(), serveCustomer()
84983 customers at the end of 1 minute, illogical since delays of 1-4 minutes between customer arrivals (timing issue)
Queue never increases in size, customers are added, then removed linearly (wrong)
Note
I have reduced the simulation time to 1 minute for testing purposes
I cannot use a multithreaded approach to solve this problem, must be done using FIFO on single thread
Customers arrive at intervals of 1 to 4 SECONDS, reduced for testing purposes
Here is my code:
package grocerystoresimulation;
/*
* #import
*/
import java.util.PriorityQueue;
import java.util.Random;
import java.util.ArrayList;
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
/*
* #author: Tyler J Fisher
* Date: 2/27/2012
*/
public class GroceryStoreSimulation {
/*
* #fields
*/
private PriorityQueue<Integer> pq = new PriorityQueue<Integer>();
private Random rand = new Random(); //instantiate new Random object
private Date date = new Date();
private DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd - hh:mm:ss a");
private ArrayList<String> timeStamp = new ArrayList<String>(); //store timestamps
private int totalCustomers; //# of customers served during simulation
private long startTime = System.nanoTime(); //time of initial build
private long simulationTime = 1; //desired time in minutes
private long firstWaitTime = generateWaitTime();
private long serviceCustomerAt;
/*
* #constuctor
*/
public GroceryStoreSimulation(){
System.out.println("Instantiated new GroceryStoreSimulation # ["
+ dateFormat.format(date) + "]\n" + insertDivider());
} //GroceryStoreSimulation()
public void run(){
//Main program body
try {
Thread.sleep(firstWaitTime); //generate wait time for first customer
System.out.println("Delay until first customer: " + firstWaitTime);
newCustomer(totalCustomers);
serveCustomer();
} catch (InterruptedException e){/*Catch 'em all*/}
while((System.nanoTime()-startTime)<=(simulationTime*60000000000L)-firstWaitTime){
try {
newCustomer(totalCustomers); //enque customer
serveCustomer();
} catch(Exception e){/*Catch 'em all*/}
}
System.out.println("Exit");
System.exit(0); //stop runtime
} //run()
/*
* #return String
*/
#Override
public String toString(){
return this.pq.toString();
} //toString()
private void serveCustomer(){
long elapsedTime = System.nanoTime()-startTime;
while((elapsedTime)<(serviceCustomerAt)){
elapsedTime += System.nanoTime()/10000000;
}
if(pq.size()!=0){
System.out.println("Dequeued customer #[" + dateFormat.format(new Date())
+ "]");
pq.poll(); //remove first element of queue
} else {
System.out.println("ERROR: Queue is empty!");
}
} //serveCustomer()
/*
* #param String ID
*/
private void newCustomer(int ID){
long elapsedTime = System.nanoTime()-startTime;
long waitTime = (long)generateWaitTime()*1000000;
long generateAt = elapsedTime+waitTime;
while((elapsedTime)<(generateAt)){/*Wait*/
elapsedTime += System.nanoTime()/10000000; //increment elapsed time
}
serviceCustomerAt = 0; //reset service wait time value
System.out.println("Customer # " + totalCustomers + " added to queue. . .");
totalCustomers++;
pq.offer(ID); //insert element into PriorityQueue
System.out.println("Queue size: " + pq.size()); //output linesize
assignTimestamp(ID); //call assignArrivalTime() method
//Calculate time until customer served
waitTime = (long)generateWaitTime()*1000000;
elapsedTime = System.nanoTime()-startTime;
serviceCustomerAt = elapsedTime + waitTime;
System.out.println("Service delay: " + waitTime/1000000);
} //newCustomer()
/*
* #param String ID
*/
private void assignTimestamp(int ID){
timeStamp.add(ID + ": " + dateFormat.format(new Date()));
System.out.println(timeStamp.get(totalCustomers-1));
} //assignArrivalTime()
* #return int
*/
private int generateWaitTime(){
//Local variables
int Low = 1000; //1000ms
int High = 4000; //4000ms
return rand.nextInt(High-Low) + Low;
}//generateWaitTime()
/*
* #return String
*/
private static String insertDivider(){
return ("****");
}//insertDivider()
output:
run:
Instantiated new GroceryStoreSimulation # [2012/03/13 - 01:55:23 AM]
Delay until first customer: 1263
Customer # 0 added to queue. . .
Queue size: 1
0: 2012/03/13 - 01:55:24 AM
Service delay: 1373
Dequeued customer #[2012/03/13 - 01:55:24 AM]
Customer # 1 added to queue. . .
Queue size: 1
1: 2012/03/13 - 01:55:24 AM
Service delay: 2188
Dequeued customer #[2012/03/13 - 01:55:24 AM]
Customer # 2 added to queue. .
.
.
.
Service delay: 3379
Dequeued customer #[2012/03/13 - 01:55:24 AM]
Customer # 927 added to queue. . .
Queue size: 1
927: 2012/03/13 - 01:55:24 AM
Service delay: 2300
Service delay: 2300BUILD STOPPED (total time: 1 second)
A couple things to think about:
You're simulating a 12-hour day, at 1 minute resolution, there is no need to have your program actually running for any specific amount of time (ie there is no need for Thread.sleep() at any point).
You do want a FIFO queue, a PriorityQueue is, by definition, not a FIFO queue. (I haven't checked if it actually makes a difference in your case, but you should probably be aware of the difference).
Doing things like this:
try {
newCustomer(totalCustomers); //enque customer
serveCustomer();
} catch(Exception e){/*Catch 'em all*/}
Will cause nothing but frustration and hair pulling.
Edit
Unless there's a specific requirement to use sleep() to time your code (wasn't clear, but I'm assuming there isn't), something like this would be a lot easier:
for(int minute = 0; minute < 720; minute++){
// process customer arrival and service
}
Hopefully that can give you some ideas.
Try changing
while((elapsedTime)<(generateAt)){/*Wait*/
elapsedTime += System.nanoTime()/10000000; //increment elapsed time
}
to
while((elapsedTime)<(generateAt)){/*Wait*/
elapsedTime = System.nanoTime()-startTime; //update elapsed time
}
NOTE: I believe you should re-work your two methods to not do any waiting, but rather simply check if it is time to queue/de-queue a customer. In the main while loop, you can add a Thread.sleep(1000) so that every 1 second, you call each method which checks if it's time to queue/de-queue a customer. Upon successfully doing so, update the time at which the next person should be serviced/generated.

Categories

Resources