-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path16_2-Server_queue.py
251 lines (195 loc) · 10 KB
/
16_2-Server_queue.py
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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# -*- coding: utf-8 -*-
"""SSQ-Final-2_Report.ipynb
Automatically generated by Colaboratory.
Original file is located at
https://colab.research.google.com/drive/1szJkhMrtRDIbasmBjsC0ti0aemE3k2Ul
"""
import numpy as np
class SSQ:
def __init__(self,option): #Initialization
'''
self.interarrivals= [0.397937254081555, 0.6279653814829189, 0.4616115729020344,
0.39360057615863536, 0.2755242455477496, 0.5190796474718047, 0.2877595995843199,
1.1117622065163284, 1.657456091026907, 0.24180105045112665, 0.7844480699845842,
0.3763370547682942, 0.41971642336941145, 1.2991270769627203,
0.03684267745642394, 0.04558051455950024, 0.010212793342112475,
0.8937438398074441, 0.7528921159326077, 1.0201571404727754] #exponential distribution
self.service_times= [4.998788389616904, 2.08681142663519, 0.8046082961968591,
1.9714967699441972, 0.16363673537970563, 1.3278614523096948,
0.20114858754593876, 3.762746584598984, 0.9591754618043763, 0.6962354337909832,
0.3994644590175899, 1.9347312903447555, 0.7918071411940105, 1.0924351189278956,
0.02465914316109906, 1.2497952079533172, 1.2310956811969116, 1.2474123645480066,
3.7412896023633304, 1.4886806462454891] #exponential distribution
'''
self.interarrivals= list(np.random.exponential(0.5,100))
self.service_times= list(np.random.exponential(1.3, 100))
self.clock= 0.0
self.next_arrival=self.interarrivals.pop(0)
self.next_departure1= float('inf')
self.next_departure2=float('inf')
self.num_in_queue= 0
self.times_of_arrivalqueue= [] #store times of arrivals who are waiting in the queue
self.service_times_in_queue= [] #store service times of waiting customers in the queue
self.total_delay=0.0
self.num_of_delays= 0.0
self.area_under_q= 0.0
self.area_under_b1= 0.0
self.area_under_b2= 0.0
self.server1_status= 0 #0 for IDLE , 1 for BUSY
self.server2_status=0
self.last_event_time=0.0 #we will need to store last event clock time
self.departure1_list= []
self.departure2_list= []
self.average_delay=0.0
self.exp_number_customer_in_queue=0.0
self.exp_utilization_server1=0.0
self.exp_utilization_server2=0.0
if (option==1):
print("FIFO")
elif (option==2):
print("LIFO")
else:
print("SJF")
def start(self):
while self.num_of_delays<60:
self.timing()
def timing(self):
self.clock= min(self.next_arrival,self.next_departure1,self.next_departure2) #First set clock to minimum time of next event
self.update_register()
if (self.next_arrival<=self.next_departure1 and self.next_arrival<=self.next_departure2):
self.arrival()
print("Arrival at Clock:" +str(self.clock))
elif self.next_departure1<=self.next_arrival and self.next_departure1<=self.next_departure2:
self.departure1(option)
self.departure1_list.append(self.clock)
print("Departure from server-1 at "+str(self.clock))
else:
self.departure2(option)
self.departure2_list.append(self.clock)
print("Departure from server-2 at "+str(self.clock))
print("Next Arrival Time: "+str(self.next_arrival))
print("Next Departure1 Time: "+str(self.next_departure1))
print("Next Departure2 Time: "+str(self.next_departure2))
print("Server1 Status: "+str(self.server1_status))
print("Server2 Status: "+str(self.server2_status))
print("Times of arrivals in Queue: "+ str(self.times_of_arrivalqueue))
print("Service times in Queue: "+str(self.service_times_in_queue))
print("Total Delay: " +str(self.total_delay))
print("Number of customers delayed: "+str(self.num_of_delays))
print("Area under q: "+str(self.area_under_q))
print("Area under b1: "+str(self.area_under_b1))
print("Area under b2: "+str(self.area_under_b2))
#print("Next Departure1 List: "+str(self.departure1_list))
#print("Next Departure2 List: "+str(self.departure2_list))
print(" ")
self.exp_utilization_server1=self.area_under_b1/self.last_event_time
self.exp_utilization_server2=self.area_under_b2/self.last_event_time
self.average_delay=self.total_delay/self.num_of_delays
self.exp_number_customer_in_queue=self.area_under_q/self.last_event_time
print("Average Delay: "+str(self.average_delay))
print("Expected Number of Customers in the queue: "+str(self.exp_number_customer_in_queue))
print("Expected Utilization of the server-1: "+str(self.exp_utilization_server1))
print("Expected Utilization of the server-2: "+str(self.exp_utilization_server2))
print("==================================================")
def arrival(self):
#Schedule next arrival , new_arrival = previous_arrival + inter_arrival time of next customer
self.next_arrival= self.next_arrival+ self.interarrivals.pop(0)
if self.server1_status==0: #server is idle
self.server1_status= 1 #make server BUSY
delay=0.0 #so delay is zero
self.total_delay += delay
self.num_of_delays +=1 #increase the number of customers delayed
#schedule next departure, pop the first element of service_times list to get service time of this customer
self.next_departure1 = self.clock+ self.service_times.pop(0)
elif self.server2_status==0: #server is idle
self.server2_status= 1 #make server BUSY
delay=0.0 #so delay is zero
self.total_delay += delay
self.num_of_delays +=1 #increase the number of customers delayed
#schedule next departure, pop the first element of service_times list to get service time of this customer
self.next_departure2 = self.clock+ self.service_times.pop(0)
else: #Server is BUSY
#increase queue length, this customer will have to wait in the queue
self.num_in_queue+=1
#store the arrival time and service time of this customer in seperate lists
self.times_of_arrivalqueue.append(self.clock)
self.service_times_in_queue.append(self.service_times.pop(0))
def departure1(self,option): ##depart from server-1
#check number of customers in the queue
if self.num_in_queue==0: #if no customer in the queue
#make server IDLE
self.server1_status= 0
#schedule next departure= infinity
self.next_departure1= float('inf')
else:
#if queue not empty, pop one customer, decrease queue length
self.num_in_queue-=1
self.num_of_delays+=1
#AS FIFO, pop first arrival and service time from the queue. IF LIFO we have to pop last arrival and service time
#For SJF, finf the index of minimum service time from service_times_in_queue list.
#Then pop the arrival of that index from times_of_arrivalqueue for delay count and others.
if (option==1):
arrival= self.times_of_arrivalqueue.pop(0)
delay= self.clock- arrival
self.total_delay+=delay
self.next_departure1= self.clock+ self.service_times_in_queue.pop(0)
elif (option==2):
arrival= self.times_of_arrivalqueue.pop(-1)
delay= self.clock- arrival
self.total_delay+=delay
self.next_departure1= self.clock+ self.service_times_in_queue.pop(-1)
else:
min_time=min(self.service_times_in_queue)
find_index=self.service_times_in_queue.index(min_time)
arrival= self.times_of_arrivalqueue.pop(find_index)
delay= self.clock- arrival
self.total_delay+=delay
self.next_departure1= self.clock+ self.service_times_in_queue.pop(find_index)
def departure2(self,option): ##depart from server-2
#check number of customers in the queue
if self.num_in_queue==0: #if no customer in the queue
#make server IDLE
self.server2_status= 0
#schedule next departure= infinity
self.next_departure2= float('inf')
else:
#if queue not empty, pop one customer, decrease queue length
self.num_in_queue-=1
self.num_of_delays+=1
#AS FIFO, pop first arrival and service time from the queue. IF LIFO we have to pop last arrival and service time
#For SJF, finf the index of minimum service time from service_times_in_queue list.
#Then pop the arrival of that index from times_of_arrivalqueue for delay count and others.
if (option==1):
arrival= self.times_of_arrivalqueue.pop(0)
delay= self.clock- arrival
self.total_delay+=delay
self.next_departure2= self.clock+ self.service_times_in_queue.pop(0)
elif (option==2):
arrival= self.times_of_arrivalqueue.pop(-1)
delay= self.clock- arrival
self.total_delay+=delay
self.next_departure2= self.clock+ self.service_times_in_queue.pop(-1)
else:
min_time=min(self.service_times_in_queue)
find_index=self.service_times_in_queue.index(min_time)
arrival= self.times_of_arrivalqueue.pop(find_index)
delay= self.clock- arrival
self.total_delay+=delay
self.next_departure2= self.clock+ self.service_times_in_queue.pop(find_index)
def update_register(self):
time_difference= self.clock - self.last_event_time
self.area_under_q= self.area_under_q+(time_difference*self.num_in_queue)
self.area_under_b1= self.area_under_b1+(time_difference*self.server1_status)
self.area_under_b2= self.area_under_b2+(time_difference*self.server2_status)
self.last_event_time=self.clock
###################Report Print###################
#self.exp_utilization_server1=self.area_under_b1/total_time
#self.exp_utilization_server2=self.area_under_b2/total_time
#self.average_delay=self.total_delay/self.num_of_delays
print("Enter 1 for FIFO\nEnter 2 for LIFO\nEnter 3 for SJF\n")
option= int(input("You choose: "))
#Option 1 FIFO
#Option 2 LIFO
#Else SJF
s = SSQ(option)
s.start()