void basicStructuralTests() { beginTest("Basic Structural Tests"); /* This try ... catch system is designed to catch any errors that the * program explicitly generates. It does not guard against runtime * crashes from errors like following a bad pointer, so if your * program crashes and pulls up the debugger, you should be looking * for memory errors. */ try { /* The use of curly braces here introduces a new block scope. We * use this so that we can construct multiple different priority * queues. */ /* Basic test: Add 5 elements to the queue and ensure that * the size is correct at each step. */ { logInfo("These tests will check size() isEmpty() without calling dequeueMin()."); PQueue queue; checkCondition(queue.isEmpty(), "New priority queue should be empty."); checkCondition(queue.size() == 0, "New priority queue should have size 0."); for (int i = 0; i < 5; i++) { queue.enqueue("Test String"); checkCondition(queue.size() == i + 1, "Queue should have proper size after inserting a value."); checkCondition(!queue.isEmpty(), "Queue containing elements should not be empty."); cout<<i<<endl; } } /* Slightly more complex test: Enqueue and dequeue elements, ensuring the * size matches at each step. */ { logInfo("We're about to start calling dequeueMin()."); PQueue queue; for (int i = 0; i < 5; i++) { queue.enqueue("Test String"); } for (int i = 5; i > 0; i--) { checkCondition(queue.size() == i, "Queue should have proper size after dequeues."); checkCondition(!queue.isEmpty(), "Queue should not be empty before all elements are removed."); queue.dequeueMin(); } checkCondition(queue.size() == 0, "After removing all elements, the queue should have size 0."); checkCondition(queue.isEmpty(), "After removing all elements, the queue should be empty."); } /* Getting harder: The value dequeued should always match the value of peek(). */ { logInfo("This next test will check whether peek() matches dequeueMin()."); PQueue queue; for (int i = 0; i < 5; i++) { queue.enqueue(randomString()); } while (!queue.isEmpty()) { string expected = queue.peek(); checkCondition(queue.dequeueMin() == expected, "Value returned by peek() matches value returned by dequeueMin()"); } } /* A different one - let's make sure that peeking at an empty queue causes an * error. */ { PQueue queue; bool didThrow = false; try { logInfo("About to peek into an empty queue. This may cause a crash"); logInfo("if your implementation is incorrect."); queue.peek(); } catch (ErrorException&) { didThrow = true; } checkCondition(didThrow, "Priority queue uses 'error' when peek() called on empty queue."); } /* In the same vein - what happens if we dequeue from an empty queue? */ { PQueue queue; bool didThrow = false; try { logInfo("About to dequeue from an empty queue. This may cause a crash"); logInfo("if your implementation is incorrect."); queue.dequeueMin(); } catch (ErrorException&) { didThrow = true; } checkCondition(didThrow, "Priority queue uses 'error' when dequeueMin() called on empty queue."); } } catch (ErrorException& e) { cout << "TEST FAILURE: Unexpected exception: " << e.getMessage() << endl; } catch (exception& e) { cout << "TEST FAILURE: Unexpected exception: " << e.what() << endl; } catch (...) { cout << "TEST FAILURE: Unknown exception." << endl; } endTest("Basic Structural Tests"); }
int main(void) { Queue bankQueue; //represents the line of customers in the bank/bank line PQueue eventListPQueue; //priority queue eventListPQueue for the event list bool tellerAvailable = true; loadIntoPriorityQueue(eventListPQueue); //load data into Priority Queue from file/Create and add arrival events to event list //waitTime = SUM(time of departure) - SUM(processing time) - SUM(time of arrival)/COUNT(EVENTS) unsigned int sumDepartureTime = 0; unsigned int sumProcessingTime = 0; unsigned int sumArrivalTime = 0; unsigned int eventCount = 0; //track how many customers came in float waitTime; //Calculated at the end cout << "Simulation Begins" << endl; while(!eventListPQueue.isEmpty()) //run while eventListPQueue is not empty { Event newEvent = eventListPQueue.peek(); // Get current time unsigned int currentTime = newEvent.getTime(); // get time of newEvent if (newEvent.getType() == 'A') //check if newEvent is an arrival event { // Processes an arrival event. //processArrival(newEvent, eventListPQueue, bankQueue, tellerAvailable, currentTime); eventListPQueue.dequeue(); //Remove this event from the event list Event customer = newEvent; //customer referenced in arrivalEvent if (bankQueue.isEmpty() && tellerAvailable) { unsigned int departureTime = currentTime + customer.getLength();//currentTime + transaction time in arrivalEvent Event newDepartureEvent('D', departureTime, 0); //a new departure event with departureTime eventListPQueue.enqueue(newDepartureEvent); tellerAvailable = false; } else { bankQueue.enqueue(customer); } cout << "Processing an arrival event at time:\t" << customer.getTime() << endl; eventCount++; //count how many customers arrived sumArrivalTime += customer.getTime(); sumProcessingTime += customer.getLength(); } else { // Processes a departure event. // processDeparture(newEvent, eventListPQueue, bankQueue, tellerAvailable, currentTime); eventListPQueue.dequeue(); // Remove this event from the event list if(!bankQueue.isEmpty()) { // Customer at front of line begins transaction Event customer = bankQueue.peek(); bankQueue.dequeue(); unsigned int departureTime = currentTime + customer.getLength(); //currentTime + transaction time in customer Event newDepartureEvent('D', departureTime, 0); //a new departure event with departureTime eventListPQueue.enqueue(newDepartureEvent); } else { tellerAvailable = true; } cout << "Processing a departure event at time:\t" << currentTime << endl; //temp sumDepartureTime += currentTime; } } waitTime = (float)(sumDepartureTime - sumProcessingTime - sumArrivalTime)/eventCount; //do the average wait time calculation cout << "Simulation Ends\n\n"; cout << "Final Statistics:" << endl; cout << "\tTotal number of people processed: " << eventCount << endl; cout << "\tAverage amount of time spent waiting: " << waitTime << endl; // cout << "Bank Queue Contents:" << endl; // bankQueue.print(); // cout << "Priority Queue Contents:" << endl; // eventListPQueue.print(); // resultPrinterQueue(bankQueue); //print out the results return 0; }