This lab is designed to give you experience implementing and using priority queues and to give you experience writing simulations. This lab will use the doubly-linked list library (Dllist.h) and the Fields library (Fields.h).
const int DEFAULT_SIZE = 2;
class pQueue;
class HeapNode {
friend class pQueue;
protected:
int key;
Jval val;
HeapNode(int k, Jval v) : key(k), val(v) {}
};
class pQueue {
public:
pQueue(int capacity = DEFAULT_SIZE);
~pQueue();
// Insert new node into priority queue. Expand the heap if it is full.
void insert(int key, Jval val);
// Delete smallest item; return the smallest key and
// the value associated with this key
void deleteMin(int &key, Jval &val);
bool isEmpty();
void print(); // prints the keys in the heap
void printEvents(); // prints the events in the heap
protected:
void percolateDown(int);
protected:
HeapNode **heap;
int heapSize;
int heapCapacity;
};
|
Note that this interface is somewhat different from the one we discussed in class. Here, the deleteMin method returns the minimum key and associated value in the parameters, so there aren't separate functions for those. Also note that the insert method must explicitly expand the heap if it is full.
You should implement the pQueue class using heaps as described in the book. You should use an array as your base heap. This means that you have to worry about what happens when the array gets full (you'll have to allocate a new bigger one, and copy the first to the second).
You will notice that the this interface contains a declaration for a HeapNode class. That is because in this lab, you must bundle the keys and values into an object and store a pointer to the object in your heap array.
Start with an array of 2 entries, and then double it whenever it grows too big. You will probably find it useful to store a sentinel in array entry 0 for insertions.
sortem < inputLater in this lab you will further test your code by using it in the simulation described below.
In the remainder of this lab you will implement the banking simulation described in class and in these notes. The class notes serve as an important resource for this lab so whenever you have questions about design or implementation, the class notes are a good place to look. The goal of running the simulation will be to determine the minimal number of tellers required in order to ensure that no more than x% of customers have to wait more than y minutes in line. Once you have completed the simulation program, you will be able to experimentally increase or decrease the number of tellers in order to determine the minimal number of tellers.
The program you will write will be named bankSimulator and will take the following arguments:
bankSimulator time_limit num_tellers wait_threshold mean_transaction_time dist_file seedThe arguments have the following meaning:
An example invocation of the simulation program would look as follows:
cetus3> bankSimulator 72000 3 100 120 expon_120 53
Number of customers = 615
Average customer waiting time = 3
Maximum customer wait = 150
Percentage of customers who waited longer than 100 seconds for a teller: 0.5
Teller Idle Time Idle
0 47358 65.8
1 47882 66.5
2 45889 63.7
The binary for simulation can be found in /home/parker/courses/cs302/labs/lab6/bankSimulator. If you have any questions about how your program should execute, the way the format of the output should look, or what the correct values for the output are, you should execute the simulation binary. The bankSimulator in the course directory has an optional additional argument, called doprint which goes at the end of the argument list. By default it is 'no' and you do not have to include it. If you say 'yes', then the simulator will print out certain information about the events as they are processed. This information might help you in creating and debugging your simulation program.
Each execution of your simulation program should produce five outputs, formatted as shown above:
Although some of these statistics are not required to answer the minimal teller question, they would be useful to a bank executive trying to make decisions about the number of tellers to hire. For example, a bank executive probably would also want to factor into his or her decision the average time that a customer spends waiting for a teller and the maximum time a customer has to wait for a teller.
You should use the implementation scheme described in class for the bank teller problem (also see pages 224-225 of Weiss). In other words, you should have a priority queue that is ordered by timestamped events. You should also use the classes shown in class and you should use inheritance to handle the events.
Specifically you will need to write the following routines:
Some of the routines might be lumped together into the main procedure. For example routines 2-4 might go into the main procedure.
In order to help get you started, some code has already been prepared for you. This code can be found in the usual location (i.e., /home/parker/courses/cs302/labs/lab6), as follows:
uniformTest 47 100 20
histogramTest 58 100 expon_120
sortem < input
randomNumber = drand48() * 2 * meanThis works since drand48() returns a number between 0 and 1. However, random() returns a number between 0 and RAND_MAX, which is a very large number. So, your random number generator for this lab should use the following definition instead:
randomNumber = random() % (2*mean + 1)For example, if mean is 50 this formula will cause you to generate random numbers between 0 and 100.
Dlist<Event *> a;
will get the unintelligable linker messages if a is a global
variable. However, the following declaration and initialization will
work just fine:
Dlist<Event *> *a = new Dlist<Event *>();
You need to submit two different things for this lab:
x = 5, y = 180, mean_transaction_time = 120, seed = 53
x = 5, y = 180, mean_transaction_time = 240, seed = 137
x = 2, y = 180, mean_transaction_time = 300, seed = 333
x = 2, y = 300, mean_transaction_time = 240, seed = 217
All simulations should be run for 144000 seconds and your answers
should be placed in a file called answers.