Vishal Singh 2018CS50426
Prerequisite:-
- gnuplot
- Mac OSX
brew install gnuplot
- Linux
sudo apt-get install -y gnuplot
- Mac OSX
Commands
$ make
$ ./qSim 100 4 60 2.3
Here the format is of the following ./qSim #customers #tellers simulationTime averageServiceTime
Note: Sometimes it can take upto a 10-30 seconds for some long testcases because for plotting graph many simulations have to be done.
output will be
Total number of customers served: 97
Total time required to serve all customers: 63.262562
Number of tellers: 4
Type of queuing: one per teller
Amount of time a customer spent in the bank:-
average (i.e., mean): 4.153656
standard deviation: 2.888069
Maximum wait time for a customer: 7.735855
Total amount of teller service time: 207.803787
Total amount of teller idle time: 26.288153
------------------------------------------------
Total number of customers served: 86
Total time required to serve all customers: 68.912361
Number of tellers: 4
Type of queuing: common line
Amount of time a customer spent in the bank:-
average (i.e., mean): 4.678920
standard deviation: 5.930138
Maximum wait time for a customer: 9.628124
Total amount of teller service time: 191.429520
Total amount of teller idle time: 39.118591
and you will have plot.png
in folder ./output
#include "../include/structures.h"
#include "../include/simulator.h"
int main(int argc, char **argv) {
...
EventQueue eventQueue = initialEventQueue;
initializeEventQueue(&eventQueue, noOfCustomers, noOfTellers, simulationTime);
simulateEventQueue(&eventQueue, noOfCustomers, noOfTellers, simulationTime, averageServiceTime, 0, 0, 0);
...
}
- You import
structures.h
(contains main structures) andsimulator.h
(contains main simulator function) - Then you make a Event queue
EventQueue eventQueue = initialEventQueue;
- Then you initialize the eventQueue. i.e. add all the customer arrival events and teller arrival from idle at time 0 events.
initializeEventQueue(&eventQueue, noOfCustomers, noOfTellers, simulationTime);
- Then you simulate the eventQueue
simulateEventQueue(&eventQueue, noOfCustomers, noOfTellers, simulationTime,
averageServiceTime, commonLine: 0, debug: 0, graphPlot: 0);
pass commonLine as 0 or 1, if commonLine is 0 that means each teller has one queue and if commonLine is 1 and there is a common line
pass debug as 1, then you will see all the event simulation
pass graphPlot as 0 if you are not plotting graph
I have used only linked list and no heap because it makes debugging of eventQueue easy.
./include/strcutures.c
contains all the main structures used in the program.
For example consider EventQueueStructure
struct EventQueueStructure {
...
void (*addEvent)(struct EventQueueStructure *this, Event *event);
int (*removeEvent)(struct EventQueueStructure *this, int id);
void (*print)(struct EventQueueStructure *this);
};
typedef struct EventQueueStructure EventQueue;
function pointers are used here so that common functions like addEvent, removeEvent, print can be added inside structure. Usage example:-
EventQueue eventQueue = initialEventQueue;
eventQueue.addEvent(&eventQueue, &newEvent);
Similarly function pointers are used for EventStructure and TellerQueueStructure
struct EventStructure {
...
void (*actionMethod)(struct EventStructure* event);
};
struct TellerQueueStructure {
...
void (*addEvent)(struct TellerQueueStructure *this, Event *event);
int (*removeEvent)(struct TellerQueueStructure *this, int id);
void (*print)(struct TellerQueueStructure *this, Event *event);
};
1) Testcase 1 (High no of customers)
$ ./qSim 500 10 100 0.5
output
Total number of customers served: 494
Total time required to serve all customers: 100.845932
Number of tellers: 10
Type of queuing: one per teller
Amount of time a customer spent in the bank:-
average (i.e., mean): 0.688466
standard deviation: 0.104874
Maximum wait time for a customer: 1.638729
Total amount of teller service time: 262.818634
Total amount of teller idle time: 726.796387
------------------------------------------------
Total number of customers served: 497
Total time required to serve all customers: 100.684746
Number of tellers: 10
Type of queuing: common line
Amount of time a customer spent in the bank:-
average (i.e., mean): 0.638620
standard deviation: 0.095207
Maximum wait time for a customer: 1.474644
Total amount of teller service time: 244.738754
Total amount of teller idle time: 749.054260
2) Testcase 2 (Less no of customers)
$ ./qSim 50 10 100 0.5
output
Total number of customers served: 50
Total time required to serve all customers: 96.489937
Number of tellers: 10
Type of queuing: one per teller
Amount of time a customer spent in the bank:-
average (i.e., mean): 0.639895
standard deviation: 0.091869
Maximum wait time for a customer: 1.338753
Total amount of teller service time: 25.789745
Total amount of teller idle time: 928.501465
------------------------------------------------
Total number of customers served: 48
Total time required to serve all customers: 100.256233
Number of tellers: 10
Type of queuing: common line
Amount of time a customer spent in the bank:-
average (i.e., mean): 0.715205
standard deviation: 0.089030
Maximum wait time for a customer: 1.342545
Total amount of teller service time: 29.065121
Total amount of teller idle time: 962.187439
3) Testcase 3 (Graph with different average service times of teller)
Analysis
From main testcase, testcase 2 and testcase 3, it seems that one queue per teller is better as it decreases
- Total time required to serve all customers
- average (i.e., mean) of average time spend in bank
- standard deviation
- Maximum wait time for a customer
- Total amount of teller idle time
and increases
- Total amount of teller service time