#input
values = #value#;
import math
import copy
import numpy as np
#input number
arrival_mean = values[0]
serve_range = [values[1],values[2]]
end_time = values[3]
if not (( arrival_mean > 0 and end_time > 0 ) and serve_range[1] > serve_range[0] ):
show('Please enter proper parameters.')
assert()
class Queue:
#class constructor: initialize queue
def __init__(self,arrival_mean,serve_range,end_time):
self.curr_time = 0
self.queue = []
self.customer_num = 0
self.arrival_mean = arrival_mean
self.serve_range = serve_range
self.next_event = 'arrive'
self.next_arrive = math.inf
self.served = 0
self.serving = {}
self.serving_time_left = math.inf
self.end_time = end_time
self.served_cus_list = []
self.queue_time_list = [[0,0]]
self.events = []
#end of constructor
# randomly draw a arrival time
# change self.next_arrive
# no return value
def draw_arrive(self):
show(html('Draw an interarival time.'))
Rand_Num = randint(0, 99)
show(html('Random number drawn: ' + str(Rand_Num)))
Cal_Rand_Num = Rand_Num/100
arrival_time = -1 * self.arrival_mean * log(1 - Cal_Rand_Num)
show(html('Next interarival time is ' + str(n(arrival_time,digits=4)) + ' minutes.'))
self.next_arrive = arrival_time
# draw serving time
# return serve_time for function start_serving
def draw_serve_time(self):
a = self.serve_range[0]
b = self.serve_range[1]
show(html('Draw a service time.'))
Rand_Num = randint(0, 99)
show(html('Random number drawn: ' + str(Rand_Num)))
Cal_Rand_Num = Rand_Num/100
serve_time = a + (b-a) * Cal_Rand_Num
show(html('Service will last ' + str(n(serve_time,digits=4)) + ' minutes.'))
return serve_time
# action when customer arrive
def arrive(self):
self.customer_num += 1
customer = {}
customer['Num'] = self.customer_num
customer['arrive_time'] = self.curr_time
self.queue += [customer]
show(html('-'))
show(html('Customer number ') + str(self.customer_num) + ' has arrived')
#action when head of queue being start serving
def start_service(self):
customer = copy.deepcopy(self.queue[0])
self.queue.pop(0)
customer['start_service_time'] = self.curr_time
customer['wait_time'] = customer['start_service_time'] - customer['arrive_time']
# show message customer is being served
show(html('-'))
show(html('Customer number ' + str(customer['Num']) + ' is being served'))
self.serving_time_left = self.draw_serve_time()
customer['service_time'] = self.serving_time_left
customer['serve_end_time'] = self.curr_time + self.serving_time_left
self.serving = customer
#action when service end
def end_service(self):
show(html('-'))
show(html('Service of Customer number ' + str(self.serving['Num']) + ' is ended'))
customer = copy.deepcopy(self.serving)
customer['end_service_time'] = self.curr_time
customer['service_time'] = customer['end_service_time'] - customer['start_service_time']
self.served_cus_list += [customer]
self.serving = {}
self.serving_time_left = math.inf
self.served += 1
# show current time
def show_curr_time(self):
# display current time
show(html('-'))
show('Current time is ' + str(n(self.curr_time,digits=4)) + ' minutes after start.')
if self.next_arrive != math.inf:
show(html('Next customer will arrive in ' + str(n(self.next_arrive,digits=4)) + ' minutes later.'))
if self.serving != {}:
show(html('serving time left: ' + str(n(self.serving_time_left,digits=4)) + ' minutes.'))
# determine time to pass and pass time
def det_pass_time(self):
#debug: announce this is running
#show('det_pass running')
# comapare next arrive time and serving time left
#show('service time left: ' + str(n(self.serving_time_left)))
#show('next_arrive: ' + str(n(self.next_arrive)))
if (self.serving_time_left > self.next_arrive):
self.next_event = 'arrive'
time_to_pass = self.next_arrive
#show(1)
else:
self.next_event = 'serv_end'
time_to_pass = self.serving_time_left
#show(2)
#pass time
show(html('-'))
show(str(n(time_to_pass,digits=4)) + ' minutes passed.')
show(html('-'))
self.curr_time = self.curr_time + time_to_pass
self.next_arrive = self.next_arrive - time_to_pass
self.serving_time_left = self.serving_time_left - time_to_pass
# show queue
def show_curr_queue(self):
show(html('-'))
begin_code = '\\\\[ \\\\begin{array}{}'
end_code = ' \\\\end{array} \\\\]'
#server code
server_code = '\\\\begin{array}{} '
server_code += '\\\\colorbox{cyan}{Serving:} '
server_code += '\\\\\\\\ \\\\colorbox{cyan}{Service end time:} '
server_code += '\\\\end{array} '
if self.serving != {}:
server_code += '& \\\\begin{array}{} '
server_code += '\\\\colorbox{LightGreen}{C' + str(self.serving['Num']) + '}'
server_code += '\\\\\\\\ \\\\colorbox{LightGreen}{ '+ str(n(self.serving['serve_end_time'],digits=4)) + '} '
server_code += '\\\\end{array}'
server_code += '\\\\\\\\ \\\\\\\\'
#queue code
queue_row_count = 0
queue_code = '\\\\begin{array}{} '
queue_code += '\\\\colorbox{orange}{Queue:}'
queue_code += '\\\\\\\\ \\\\colorbox{orange}{Arrival time:}'
queue_code += '\\\\end{array} '
for customer in self.queue:
queue_code += '& \\\\begin{array}{} '
queue_code += '\\\\colorbox{yellow}{C' + str(customer['Num']) + '} '
queue_code += '\\\\\\\\ \\\\colorbox{yellow}{' + str(n(customer['arrive_time'],digits=4)) + '} '
queue_code += '\\\\end{array} '
queue_row_count += 1
if queue_row_count > 11:
queue_code += '\\\\\\\\ '
queue_row_count = 0
show(html(begin_code + server_code + queue_code + end_code))
#add event to events list
def add_event(self,type):
if type == 'first':
event = {}
event['time'] = 0
event['type'] = 'first'
event['interarrival_time'] = n(self.next_arrive,digits=4)
event['next_arrival_time'] = str(n(self.next_arrive,digits=4)) + '(C1)'
event['server_status'] = 'idle'
event['queue_length'] = 0
self.events += [event]
if type == 'serv_end':
event = {}
event['time'] = n(self.curr_time,digits=4)
event['type'] = 'serv_end'
event['server_status'] = 'idle'
event['queue_length'] = len(self.queue)
self.events += [event]
if type == 'serv_end_start':
event = {}
event['time'] = n(self.curr_time,digits=4)
event['type'] = 'serv_end_start'
event['server_status'] = 'busy'
event['service_time'] = n(self.serving_time_left,digits=4)
event['service_ending_time'] = n(self.serving['serve_end_time'],digits=4)
event['queue_length'] = len(self.queue)
event['wait_time'] = str(n(self.serving['wait_time'],digits=4)) + '(C' + str(self.serving['Num']) +')'
self.events += [event]
if type == 'arrive':
next_arrive_time = self.next_arrive + self.curr_time
event = {}
event['time'] = n(self.curr_time,digits=4)
event['type'] = 'arrive'
event['interarrival_time'] = n(self.next_arrive,digits=4)
event['next_arrival_time'] = str(n(next_arrive_time,digits=4)) + '(C' + str(self.customer_num + 1) + ')'
event['server_status'] = 'busy'
event['queue_length'] = len(self.queue)
if next_arrive_time > self.end_time:
event['next_arrival_time'] += ' (not accepted)'
self.events += [event]
if type == 'arrive_start':
next_arrive_time = self.next_arrive + self.curr_time
event = {}
event['time'] = n(self.curr_time,digits=4)
event['type'] = 'arrive_start'
event['interarrival_time'] = n(self.next_arrive,digits=4)
event['next_arrival_time'] = str(n(next_arrive_time,digits=4)) + '(C' + str(self.customer_num + 1) + ')'
event['server_status'] = 'busy'
event['service_time'] = n(self.serving_time_left,digits=4)
event['service_ending_time'] = n(self.serving['serve_end_time'],digits=4)
event['queue_length'] = len(self.queue)
event['wait_time'] = str(n(self.serving['wait_time'],digits=4)) + '(C' + str(self.serving['Num']) +')'
if next_arrive_time > self.end_time:
event['next_arrival_time'] += ' (not accepted)'
self.events += [event]
#main
P = Queue(arrival_mean,serve_range,end_time)
#first arrive
P.show_curr_time()
P.show_curr_queue()
P.draw_arrive()
P.add_event('first')
while True:
P.det_pass_time()
if P.curr_time > P.end_time:
break
P.show_curr_time()
if P.next_event == 'serv_end':
P.end_service()
event_type = 'serv_end'
P.show_curr_queue()
P.queue_time_list += [[P.curr_time,len(P.queue)]]
if len(P.queue) > 0:
P.start_service()
event_type = 'serv_end_start'
P.show_curr_time()
P.show_curr_queue()
P.queue_time_list += [[P.curr_time,len(P.queue)]]
if P.next_event == 'arrive':
P.arrive()
P.draw_arrive()
event_type = 'arrive'
P.show_curr_queue()
P.queue_time_list += [[P.curr_time,len(P.queue)]]
if P.serving == {}:
P.start_service()
event_type = 'arrive_start'
P.show_curr_time()
P.show_curr_queue()
P.queue_time_list += [[P.curr_time,len(P.queue)]]
P.add_event(event_type)
# passed queue up time
# change arrive time to infinity
P.next_arrive = math.inf
P.show_curr_time()
show(html('-'))
show('Current time exceeds Queue up ending time, no more customer is allowed to enter the queue.')
show('Customers in the queue will still be served.')
show(html('-'))
# serve customers still serving and left in queue
if P.next_event == 'arrive':
P.show_curr_time()
if P.serving != {}:
P.det_pass_time()
P.next_arrive = math.inf
P.show_curr_time()
P.end_service()
event_type = 'serv_end'
else:
P.show_curr_time()
P.end_service()
event_type = 'serv_end'
while True:
P.show_curr_time()
P.show_curr_queue()
if len(P.queue) == 0:
break
P.start_service()
P.add_event('serv_end_start')
P.show_curr_queue()
P.queue_time_list += [[P.curr_time,len(P.queue)]]
P.det_pass_time()
P.next_arrive = math.inf
P.show_curr_time()
P.end_service()
P.add_event('serv_end')
show('Service session has ended, Here are the list of events and statistics.')
#show(P.queue_time_list)
#calculate average wait time and average service time by cus list
cus_table = []
for cus in P.served_cus_list:
cus_table += [[cus['Num'],cus['arrive_time'],cus['start_service_time'],cus['end_service_time'],cus['wait_time'],cus['service_time']]]
#show(table(cus_table))
#calculate average wait time to variable 'wait_mean'
list_wait = [cus[4] for cus in cus_table]
wait_mean = np.mean(list_wait)
#calculate average service time to variable 'serv_mean'
list_serv = [cus[5] for cus in cus_table]
serv_mean = np.mean(list_serv)
#calculate average queue length from P.queue_time_list to variable 'aver_queue_length'
queue_time_list = copy.deepcopy(P.queue_time_list)
queue_time_list += [queue_time_list[-1]]
list_timelength_queuelength = []
for i in range(len(P.queue_time_list)):
list_timelength_queuelength += [[queue_time_list[i+1][0] - queue_time_list[i][0] , queue_time_list[i][1]]]
total_time = queue_time_list[-1][0]
if end_time > total_time:
total_time = end_time
weight_sum = 0
for vl in list_timelength_queuelength:
weight_sum += vl[0] * vl[1]
aver_queue_length = weight_sum / total_time
#construct event table
event_table = []
for ev in P.events:
if ev['type'] == 'first':
event_table += [[ ev['time'] , ev['interarrival_time'] , ev['next_arrival_time'] , ev['server_status'],'','',ev['queue_length'],'']]
if ev['type'] == 'serv_end':
event_table += [[ ev['time'],'','',ev['server_status'],'','',ev['queue_length'],'']]
if ev['type'] == 'serv_end_start':
event_table += [[ ev['time'],'','',ev['server_status'],ev['service_time'],ev['service_ending_time'],ev['queue_length'],ev['wait_time']]]
if ev['type'] == 'arrive':
event_table += [[ ev['time'] , ev['interarrival_time'] , ev['next_arrival_time'] , ev['server_status'] ,'','',ev['queue_length'],'']]
if ev['type'] == 'arrive_start':
event_table += [[ ev['time'] , ev['interarrival_time'] , ev['next_arrival_time'] , ev['server_status'] ,ev['service_time'],ev['service_ending_time'],ev['queue_length'],ev['wait_time']]]
event_table = [['Time','Interarrival time','Next arrival time','Server state','Service time','Service ending time','Queue \n length','waiting time']] + event_table
#convert custable to readable format
read_cus_table = copy.deepcopy(cus_table)
for row in read_cus_table:
for i in range(5):
row[i+1] = n(row[i+1],digits=4)
read_cus_table = [['Customer','Arrival Time','Start service time','End service time','Wait time','Service time']] + read_cus_table
#show event table
show(html('-'))
show(html('Events Table'))
show(table(event_table,frame = True))
#show customer table
show(html('-'))
show(html('Customers Table'))
show(table(read_cus_table,frame = True))
#show number of served customers, mean waiting time, mean service time and average queue length
show(html('-'))
show(html('Number of customers served: ' + str(P.served)))
show(html('Average waiting time is ' + str(n(wait_mean,digits=4)) + ' minutes.'))
show(html('Average service time is ' + str(n(serv_mean,digits=4)) + ' minutes.'))
show(html('Average queue length is ' + str(n(aver_queue_length,digits=4)) + '.'))