/
finitePopModel.cpp
194 lines (173 loc) · 5.46 KB
/
finitePopModel.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
/*
* finitePopModel.cpp
*
* Created on: Oct 28, 2012
* Author: Aditya
* Student ID: 2021132636
*/
#include<iostream>
#include"finitePopTypes.h"
#include "rv.h"
#include "event.h"
using namespace std;
/*********************************
* Declaration of Global Variables
*********************************/
double clock = 0.0; // System clock
EventList Elist; // Create event list
sysConfig configInfo; // This is needed to store User Inputs
statCounters countInfo; // This keeps track of statistical information
static void getUserInputs();
static void initializeQSystem(int numTerminals);
static void generateArrEvent(int numTerminals);
int main()
{
bool done = false;
double EN = 0.0; // For calculating E[N]
double Util = 0.0;
Event* CurrentEvent;
//Get system configuration inputs from user
getUserInputs();
countInfo.terminalPool = configInfo.numTerminals;
//this will initialize the queuing system
initializeQSystem(configInfo.numTerminals);
/*
* This while loop represents the finite population system where
* customer arrive (from the event list in our case),
* get accepted if the system has capacity, get served
* by the next available server and then depart
*/
while (!done)
{
CurrentEvent = Elist.get(); // Get next Event from list
double prev = clock; // Store old clock value
clock=CurrentEvent->time; // Update system clock
switch (CurrentEvent->type)
{
case ARR:
countInfo.NArr++;
EN += countInfo.NSys*(clock-prev);
if(countInfo.NSys<configInfo.numCPU)
Util += countInfo.NSys*(clock-prev);
else
Util += configInfo.numCPU*(clock-prev);
if(countInfo.serverPool<configInfo.numCPU)
{
//Server is idle, accept the element in the system and depart it
countInfo.serverPool++;
countInfo.NSys++;
Elist.insert(clock+exp_rv(configInfo.serviceRate),DEP);
}
else if((countInfo.serverPool==configInfo.numCPU) &&
(countInfo.NQueue<configInfo.queueSize))
{
//All servers are occupied, accept the element and queue it
countInfo.NSys++;
countInfo.NQueue++;
}
else if((countInfo.serverPool==configInfo.numCPU) &&
(countInfo.NQueue == configInfo.queueSize))
{
//system is full to its capacity. Block the customer and free a terminal
countInfo.NBlocked++;
countInfo.terminalPool++;
generateArrEvent(configInfo.numTerminals);
}
break;
case DEP:
EN += countInfo.NSys*(clock-prev);
if(countInfo.NSys<configInfo.numCPU)
Util += countInfo.NSys*(clock-prev);
else
Util += configInfo.numCPU*(clock-prev);
if(countInfo.NSys)
{
countInfo.NSys--;
countInfo.serverPool--;
countInfo.terminalPool++;
countInfo.NDep++;
if ((countInfo.serverPool < configInfo.numCPU) && (countInfo.NQueue>0))
{
//If a server is idle and customer is waiting in queue then generate dep
countInfo.serverPool++;
countInfo.NQueue--;
Elist.insert(clock+exp_rv(configInfo.serviceRate),DEP);
}
}
//triger new arrival. If a terminal is free then it will generate arr
generateArrEvent(configInfo.numTerminals);
break;
}
delete CurrentEvent;
if (countInfo.NDep > 100000)
done=true; // End condition
}
cout<<endl<<"****Statistical Output with lambda="<<configInfo.arrivalRate<<"****"<<endl;
cout <<"Expected number of customers (simulation)= " << EN/clock << endl;
cout<<"Expected time spent in the system= "<<EN/100000<<endl;
cout<<"P(Blocking)= "<<(double)countInfo.NBlocked/countInfo.NArr<<endl;
cout<<"Utilization= "<<(double)Util/(clock*configInfo.numCPU)<<endl;
}
/*
* This Function gets System Configuration
* information from the user
*/
static void getUserInputs()
{
int l = 0;
int m = 0;
int k = 0;
int mu = 0;
cout<<"****Finite Population Queuing System Simulation****"<<endl<<endl;
cout<<"Please Provide Following Inputs:"<<endl;
cout<<"L - Number of Terminals In The System [Range is 1-10][Default is 1]:";
cin>>l;
if(l>=1 && l<=10)
{
configInfo.numTerminals=l;
}
cout<<"m - Number of CPUs in the System [Default is 1]:";
cin>>m;
if(m>=1)
{
configInfo.numCPU = m;
}
cout<<"K - Queue Size [Default is 1]:";
cin>>k;
if(k>=1)
{
//Queue Size is K (system size) - m (number of CPU)
configInfo.queueSize = k-configInfo.numCPU;
}
cout<<"mu - Service Rate of Each CPU [Default is 2 for stability]: ";
cin>>mu;
if(mu>=2)
{
configInfo.serviceRate = mu;
}
}
/*
* This function initializes the system by
* generating arrivals for the available free
* terminal
*/
static void initializeQSystem(int numTerminals)
{
//generate arrival request for each request.
for(int i=0; i<numTerminals; i++)
{
generateArrEvent(numTerminals);
}
}
/*
* This function checks if there is free terminal
* and generates arrival if there is free terminal
*/
static void generateArrEvent(int numTerminals)
{
if((countInfo.terminalPool>0) && (countInfo.terminalPool<=numTerminals))
{
Elist.insert(clock + exp_rv(configInfo.arrivalRate),ARR);
countInfo.terminalPool--;
}
}