Coverage for C:\checkouts\github\OpenQTSim\openqtsim\mm1.py : 13%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1from scipy import stats
2import numpy as np
3import pandas as pd
6class MM1:
7 """
8 A simple simulation method for MM1 queues
9 - Lists of IAT's and ST's are drawn from exponential distributions
10 - Values for AT, TSB, TSE, TCSS, TCWG and ITS are calculated per arrival
11 """
12 def __init__(self, lam, mu, nr_arr, seed=None):
13 """
14 Initialization the basic time unit is hours.
15 """
16 # todo: consider to remove seed
17 self.lam = lam # arrivals per hour
18 self.mu = mu # departures per hour
19 self.nr_arr = nr_arr # nr of customers
21 np.random.seed(seed)
23 def get_IAT_and_ST(self): # generate list of inter arrival times
25 rv_iat = stats.expon(scale=1 / self.lam)
26 rv_st = stats.expon(scale=1 / self.mu)
28 # generate list of inter arrival times
29 IAT = rv_iat.rvs(self.nr_arr)
31 # generate list of service times
32 ST = rv_st.rvs(self.nr_arr)
34 return IAT, ST
36 def calculate_MM1(self, IAT, ST):
37 df = pd.DataFrame()
38 AT = []
39 TSB = []
40 TSE = []
41 TCSS = []
42 TCWQ = []
43 ITS = []
45 for i in range(len(IAT)):
46 # AT
47 if i == 0:
48 AT.append(IAT[i]) # time starts at 0 and the first arrival arrives at 0 + IAT
49 else:
50 AT.append(AT[i - 1] + IAT[i]) # next arrivals start at the previous arrival AT[i-1] + IAT
51 # TSB
52 if i == 0:
53 TSB.append(AT[i]) # first arrival the queue is empty so service begins as soon as customer arrives
54 else:
55 TSB.append(np.max([AT[i], TSE[i - 1]]))
56 # TSE
57 TSE.append(TSB[i] + ST[i]) # moment service begins plus service time
58 # TCSS
59 TCSS.append(TSE[i] - AT[i]) # moment of arrival until service ends
60 # TCWQ
61 TCWQ.append(TSB[i] - AT[i]) # moment of arrival until service begins
62 # ITS
63 if i == 0:
64 ITS.append(IAT[i]) # the server will start idle until the first arrival
65 else:
66 ITS.append(np.max([AT[i] - TSE[i - 1], 0])) # todo: I don't think this works with multiple servers
68 # Add lists to dataframe
69 df["IAT"] = IAT
70 df["ST"] = ST
71 df["AT"] = AT
72 df["TSB"] = TSB
73 df["TSE"] = TSE
74 df["TCSS"] = TCSS
75 df["TCWQ"] = TCWQ
76 df["ITS"] = ITS
78 return df
80 def get_stats(self, df):
81 value = np.mean(df["TCWQ"]) / np.mean(df["ST"])
82 print('Waiting time over service time: {:.4f}'.format(value))
83 print('')
85 value = (df["TSE"].iloc[-1] - np.sum(df["ITS"])) / df["TSE"].iloc[-1]
86 print('Rho: system utilisation: {:.4f}'.format(value))
87 print('')
89 value = np.sum(df["ITS"]) / df["TSE"].iloc[-1]
90 print('P_0: probability nobody in the system: {:.4f}'.format(value))
92 value = np.mean(df["TCSS"])
93 print('W_s: the long term average time spent in the system: {:.4f}'.format(value))
95 value = np.mean(df["TCWQ"])
96 print('W_q: the long term average time spent in the queue: {:.4f}'.format(value))
98 value = df["AT"].iloc[-1]/(len(df["ST"])-1)
99 print('IAT: average inter arrival time: {:.4f}'.format(value))
101 value = np.sum(df["ST"])/(len(df["ST"]))
102 print('ST: average service time: {:.4f}'.format(value))
103 print('')