Professional Documents
Culture Documents
Written by:
Yosfik Alqadri, S.T.
92312066
GRADUATE PROGRAM
GUNADARMA UNIVERSITY
JAKARTA
2014
THE DESIGN AND IMPLEMENTATION OF GENERIC
QUEUEING SYSTEMS SIMULATION
Written by:
Yosfik Alqadri, S.T.
THESIS
Management
Gunadarma University
GRADUATE DEGREE
GUNADARMA UNIVERSITY
JAKARTA
2014
PAGE OF APPROVAL
Date of graduation :
Approved by:
Board of Advisors
. . . . . . . . . . . . . . . . . . .
(Chair Person)
. . . . . . . . . . . . . . . . . . .
(Coordinator)
. . . . . . . . . . . . . . . . . . .
Dr. Tb. Maulana Kusuma, S.Kom., MEngSc.
(Director)
ii
ABSTRACT
(xii + 49 + 6)
Waiting in queue is part of our daily life. We, as the customer do not need
the waiting. The service providers also do not want the customer to wait, because
too much waiting may lose them the business. Computer-based simulation is one
solution to find the optimum service rate for queueing systems. Queueing systems
generic queueing model used as the basis of the simulation is chosen from the ex-
isting queueing models. The simulation makes use of the pseudo-random generator.
The generic queueing systems simulation is designed as a function in Python pro-
gramming language, which can then be called from another program to generate the
simulation results.
In this thesis, it is concluded that the best model for the generic queueing
simulation is the multi channel single phase model. The simulation makes use a
kind of multiplicative pseudo-random number generator, called Lehmer’s random
number generator, to substitute the built-in random number generator in Python.
iii
The performance of the simulation is of class O(n) = n, where n is the number of
server in the queueing systems.
Bibliography (1967-2014)
iv
CURRICULUM VITAE
Yosfik Alqadri, was born in Padang on April 26th , 1989. The educational
background started from SDN 44 Padang Elementary School from 1994 until 2000.
He continued his education to SMPN 18 Padang Junior High School and gradu-
ated in 2003. From then, he continued to SMAN 10 Padang Senior High School
and graduated in 2006. In 2009, he continued to Gundarma University majoring
v
ACKNOWLEDGEMENTS
Praise be to God for all the blessing, for which without, this work could not
be completed. This work was done to complete the requirement to finish the study
at Information Systems Management Master’s Program, Gunadarma University.
Author wishes to thank everyone who has given their support, kindness, and
patience in making this work completed. It is not possible to name them all here.
However, author would like to dedicate acknowledgements to:
University.
Program.
Management.
7. Dr. Ernastuti, S.Si., M.Kom., as supervisor of this work, for her excellent
supervision.
8. Mr. Remi Senjaya, ST., MMSI who sincerely take care of us (SarMag students)
and give us all information and needs in SarMag Program.
vi
10. All of SarMag lecturers, for support and knowledge given to author.
11. All SarMag staffs in Simatupang and Salemba Campus, for the supports.
12. All my friends, especially in SarMag, for a lot of supports, sharings, jokes, and
joys. Thank you for such happiness.
13. And a special thanks to Citra Bunga Putri, for all the talks and chats, a relief
from all the pressure from this work.
Last but not least, Author is looking forward to get suggestions and critics
from anyone to help improving this work in the future. Hopefully, readers would
vii
Contents
COVER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i
PAGE OF APPROVAL . . . . . . . . . . . . . . . . . . . . . . . . . . ii
ABSTRACT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iii
CURRICULUM VITAE . . . . . . . . . . . . . . . . . . . . . . . . . . v
ACKNOWLEDGEMENTS . . . . . . . . . . . . . . . . . . . . . . . . vi
Contents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . viii
List of Figure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi
1.1 Background . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
viii
2.2.6 Queueing Discipline [4] . . . . . . . . . . . . . . . . . . . . . . 10
2.2.7 Service Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3.3.4 Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Chapter IV : IMPLEMENTATION AND TESTING . . . . . . . . 28
ix
4.4.1 Queueing Problem in Mainframe Computer [6] . . . . . . . . . 41
4.4.2 Queueing Problem in Logistics . . . . . . . . . . . . . . . . . . 45
Chapter V : CONCLUSION . . . . . . . . . . . . . . . . . . . . . . 50
5.1 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
5.2 Future Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
BIBLIOGRAPHY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
x
List of Figures
xi
List of Tables
xii
Chapter I
INTRODUCTION
1.1 Background
We only need the service. And the service providers also do not want the customer
to wait, because too much waiting may lose them the business.
Queue is formed when the number of demand for service is greater than the
resources. Therefore, they have to find the optimum service rate, based on the equi-
librium from the cost for providing the resources and the customers’ waiting time.
Queueing processes can generally be classified into four models. They are: Single
Channel Single Phase model, Multi Channel Single Phase model, Single Channel
Multi Phase model, and Multi Channel Multi Phase model [6].
1
2
plaints going on about the poor service of several public services, with the most
frequently encountered being the traffic jam and the long wait in the toll booths
(figure 1.1). The public service systems is not carefully planned, which results in
low service rate. The use of queueing systems simulation in the planning stages
should improve this service rate problem.
2. What are the components needed and how to integrate them into a simulation
software?
However, for some reasons (such as security concerns), the algorithm of the built-in
for the simulation software. A less complex but faster algorithm is chosen for the
2. Develop components necessary for the simulation model, and implement the
model.
compare and then choose the best model and the best pseudo-random number
generator to be implemented.
3. System Design. This phase carries out the process of designing the simula-
tion components needed and how to integrate them.
the best model and algorithm, and then design the components needed for the
software. Chapter 4 is Implementation and Testing. This chapter will describe the
implementation and testing of the completed simulation software. The last chapter
is Conclusion.
Chapter II
LITERATURE REVIEW
Agner Krarup Erlang, a Danish engineer who worked for the Copenhagen
Telephone Exchange, published the first paper on what would now be called queueing
theory in 1909 [3]. He modeled the number of telephone calls arriving at an exchange
by a Poisson process [7]. A queueing process can be very simple, but sometimes can
also very complex. The main components are arrival of customer and service. These
6
7
ities are idle, which might indicate that they are beyond the real need.
Service facility can be of a single or multiple server. For example, there are
multiple toll booth at the toll road, while a theater might only have a single ticket
booth.
The most common way to describe the pattern of arrival is through the
use of inter-arrival time. Inter-arrival time is defined as the interval between two
consecutive event of customer arrival. If arrival time stochastically change over time,
1
λ= (2.1)
Ta
within an interval ∆t. If λ is defined as the mean of the number of arrival over a
certain amount of time, then the probability of a customer arrival within ∆t is λ∆t.
λ is the mean of the number of arrival over a certain amount of time. The
(λt)r e−λt
P (r) = with (r = 0, 1, 2, . . . ) (2.5)
r!
∫ t
y= λe−λt dt = 1 − e−λt (2.6)
0
λt = −ln(1 − y) (2.7)
1. Within this range, the natural logarithm yields negative value. The minus sign
−ln(y)
t= = Ta ln(y) (2.8)
λ
In queueing theory, a queue begin with the assumption that its length, to-
gether with the source of arrival, to be infinite.
10
∫ t
y= µe−µt dt = 1 − e−µt (2.10)
0
−ln(y)
t= = Ts ln(y) (2.11)
µ
1. Single Channel Single Phase Single Channel Single Phase is the simplest
queueing model. It has only one waiting line, and only one server. Example
of this model is the queueing process at a ticket booth at a theater.
registration.
model that has multiple waiting line, and multiple server with more than one
Figures 2.2, 2.3, 2.4, and 2.5 illustrate these four models.
These measures are essential as the basis for making decisions about the
λ
Wq = (2.12)
µ(µ − λ)
1
W = (2.13)
µ−λ
λ2
Lq = (2.14)
µ(µ − λ)
λ
L= (2.15)
µ−λ
λ
Pw = (2.16)
µ
ous numbers on the sequence. Because of this untrue nature, the random number
produced by the algorithms is called pseudo-random numbers.
current result of executing the algorithm, can then be used to produce another
random number in the next execution.
Uniform distribution means that the chance of every number (within a certain
Below are some well known approach for pseudo-random number generators
Z0 is the seed.
number generator. However, the algorithms chosen are usually the complex one, such
as the Marsenne Twister, which is the built-in pseudo-random number generator for
Python. The complex ones are usually chosen because of security concern, thus
sacrificing running time to produce more unpredictable random number sequence.
16
ducted to better understand the system’s behavior and planning a better strategy
For dynamic models that cannot be solved analytically, numerical computation ap-
proach is used. Simulation is the name of the name of this special technique in
Since 2008, Python has consistently ranked in the top eight most popular pro-
gramming languages as measured by the TIOBE Programming Community Index.
It is the third most popular language whose grammatical syntax is not predomi-
nantly based on C, e.g. C++, C#, Objective-C, Java. Python does borrow heavily,
however, from the expression and statement syntax of C, making it easier for pro-
grammers to transition between languages.
An empirical study found that, for a programming problem involving string
18
tively in scientific computing, with specialized libraries such as BioPython and As-
and calculus.
3D animation packages such as 3ds Max, Blender, Cinema 4D, Lightwave, Houdini,
Maya, modo, MotionBuilder, Softimage, the visual effects compositor Nuke, and
2D imaging programs like GIMP, Inkscape, Scribus and Paint Shop Pro. GNU
Debugger uses Python as a pretty printer to show complex structures such as C++
containers. Esri is now promoting Python as the best choice for writing scripts in
ArcGIS. It has even been used in several video games, and has been adopted as
first of the three available programming languages in Google App Engine, the other
two being Java and Go. Python has also been used in artificial intelligence tasks.
Thanks to being a scripting language with module architecture, syntax simplicity
and rich text processing tools, Python is often used for natural language processing
tasks.
Chapter III
ANALYSIS AND DESIGN
In order for the simulation software to be usable for most cases, a generic
queueing model must be decided first. Based on the previous chapter, there are
four queueing models: single channel single phase, multi channel single phase, single
Regarding the channel, a multiple one should handle all the case. The multi
channel is flexible, with customers having the tendency to choose the shortest line
at each arrival and also to change line if some of the server become idle (available
for service). This makes more sense rather than a strict multi channel with the
Now, if we look closely, the single phase service should suffice for most cases.
The single phase service can also be seen as the accumulation of multi phase service.
By taking into account the waiting time for each phase of service, and carefully
adding it to the total service time for each phase of service, we can still get the
mean time in system for each customer. In short, the desired performance parameter
of a multi phase service simulation can still be achieved via single phase service
simulation.
By following arguments above, the multi channel single phase model is
selected as the most adequate generic model for the simulation software. Now, how
about the number of the server? The number of the server is arbitrary. The user will
provide the number of server for the simulation. If the number is zero or negative,
the simulation will not run, and will produce empty output.
19
20
After selecting the model, detailed steps for the simulation procedure is de-
veloped. The output of the simulation is to measure the following performance
parameters.
In order for the simulation to be carried out, the following simulation vari-
ables is used. The name inside the bracket will be the actual name in the software
implementation.
19. Result mean number of waiting customer in the system (rerataP anjangSistem)
2. Input the value for variables jumlahP elayan, lamda, mu, and waktuSimulasi,
which are the number of server, mean inter-arrival time, mean service time,
and duration of simulation, respectively.
22
4. Select the idle server. If all server is busy, select the one closest to finishing
the job. Store the selected server in variable pelayan.
5. If the currently arriving customer is the first customer in system, the value
of arrival time variable, waktuDatang, is the exponentially distributed inter-
−ln(angkaAcak)
waktuDatang = (3.1)
lamda
If it is not the first customer in system, the value of waktuDatang is its old
value added with the result of equation 3.1.
6. If the currently arriving customer is the first customer in system, the value of
the first customer in system, the value of waktuM ulai is the maximum value
7. Service time for currently arriving customer, lamaP elayanan is the exponen-
tially distributed service time, mu, computed by
−ln(angkaAcak)
lamaP elayanan = (3.2)
mu
8. End time of service for currently arriving customer, waktuSelesai, is waktuM ulai
added with lamaP elayanan.
9. Waiting time of a customer before being processed, lamaT unggu, is the dif-
ference between waktuM ulai and waktuDatang.
24
10. Append the list of customers, daf tarP elanggan, with the currently arriving
customer.
11. Update the finishing time of the selected server, pelayan, with the value of
waktuM ulai added with lamaP elayanan.
12. Update t with waktuDatang. If the new t is less than waktuSimulasi, repeat
concerned here are the input process, simulation data keeping mechanism, pseudo-
random number generator, and the output process.
as the generic model, single channel single phase, is chosen, the user will supply
the value for the number of server (jumlahP elayan), mean inter-arrival time per
customer (lamda), mean service time per customer (mu), and number of unit time
programming languages, there are even more convenient way to do this, by using
object. Instead of viewing data for each customer as a separate record, each cus-
tomer can be viewed as objects with properties attached to each of them. To create
customer’s object, there will be a class called P elanggan with properties including:
server selected by currently arrived customer (pelayan), arrival time of a customer
(waktuDatang), start time of service for a customer (waktuM ulai), service time of
Because security concern is not taken into account for random numbers in
the simulation, a fast and easy to implement algorithm is chosen. For this purpose,
Lehmer random number generator, or commonly known as MINSTD, is chosen.
This algorithm is still in use today, noticeably in C++ 2011 standard spec-
ification (C++11). Its first version, suggested by Park and Miller in 1988, uses
parameters n = 23 1 − 1 = 2, 147, 483, 647 along with g = 75 = 16, 807 [8]. Later,
in 1993, Park and Miller revised the parameter g = 48, 271 [9]. The later version is
the one used in C++11’s minstd_rand random number generator [2].
A pseudo random number generator needs a first arbitrary number in order
to generate the sequence. This first arbitrary number is commonly known as the
seed, represented by X0 . If the seed is an input from user, it will be inconvenient
26
because it should not have been taken into consideration by him/her. The software
will take care of that. If the arbitrary number is hard-coded into the source code,
then it is no longer arbitrary. Also, the sequence produced will be constant, as
the seed is also constant. The simulation will produce identical result for the same
input.
In order to solve this, the software will take the Operating System’s time.
The time will then be converted to long integer and then multiplied by 256. This
method is used in Python’s random module in order to get the seed. This method
will produce non identical seed for several consecutive simulation run.
3.3.4 Output
The summary of the simulation will be displayed right after a simulation run
ended. However, if a user want to view the simulation data used in the run, an
output file is needed. For this purpose, a comma separated values (CSV) file should
suffice. This kind of file can be opened in a text editor, and is supported by most
process the data further, he/she can then open it in the spreadsheet and do the
analysis. Format of the simulation data on the CSV file is illustrated by table 3.1.
In this example, customer #1 arrived at the first unit of time. Because the
27
simulation had just started, there is no customer waiting in the queue, which means
that waiting time is zero. Therefore, customer #1 proceeded to server #1. The
service lasted for 1 unit of time, and customer #1 finished at the second unit of
time. The same thing went for customers #2, #3, and #4, each of which arrived
at the third, fifth, and sixth unit of time. Because of the server selection algorithm
in the simulation program, each customer proceeded to servers #2, #3, and #4
respectively. Customers #2, #3, and #4 were served for 2, 2, and 1 units of time,
and finished at the fifth, seventh, and seventh unit of time respectively. When
customer #5 arrived at the tenth unit of time, server #1 was already in idle state
and served customer #5 directly, which means zero waiting time. The service lasted
for 2 units of time, and customer #5 finished at the twelfth unit of time.
Chapter IV
IMPLEMENTATION AND TESTING
is better than Python 3.x. The reason of choosing Python 3.x as the language for
be the last Python 2.x implementation, and then it will be discontinued. For this
reason, Python 3.x is used, in order for the software to be usable for a longer period
of time.
The simulation makes use of some built-in functionality from Python library.
The simulation data will be exported as a CSV file, so csv module is needed. For
computing random numbers, natural logarithm and ceiling functions (log() and
ceil()) from math module are also needed. And to get current system time from
the operating system, the time() function from time module is needed. Below is
the code to import the necessary modules.
import csv
import math
import time
28
29
as the constructor to create the object of the class. Below is how the code looks like.
class Pelanggan:
self.pelayan = pelayan
self.waktuDatang = waktuDatang
self.waktuMulai = waktuMulai
self.lamaPelayanan = lamaPelayanan
function accept no parameter at all, but instead a global variable named angkaAcak
which is also defined in function mulaiSimulasi. All the values used inside this
function follows the later version of Lehmer random number generator, revised by
Park and Miller in 1993. To map the random number into a range between 0 and
1, it is divided by the range before returning it as the final value. Below is how the
code looks like.
30
def acak():
global angkaAcak
a = 48271
m = (2 ** 31) - 1
angkaAcak = (a * angkaAcak) % m
return float(angkaAcak) / m
time per customer. This function follows the formula to compute an exponentially
def acakEksponensial(lamda):
User will start the simulation by calling the main function, simulasi(). The
arrival time per customer (lamda), mean service time per customer (mu), and number
of unit time for duration of the simulation (waktuSimulasi). The simulation will
• jumlahPelayan is an integer
If all the conditions are satisfied, the real simulation process will start, by
calling function mulaiSimulasi(). If one or more conditions are not satisfied,
an error message will be printed. Also defined in the function, is the five vari-
ables for performance parameters to be measured by the simulation. They are:
rerataPanjangAntrian, rerataPanjangSistem, rerataLamaTunggu, rerataLamaSistem,
and utilisasi, each defined as a global variable. The five variables will be return
as the result every time function simulasi() is called. Below is how the code looks
like.
lamda != 0 and
mu != 0 and
waktuSimulasi > 0:
mulaiSimulasi(jumlahPelayan, lamda, mu, waktuSimulasi)
return (rerataPanjangAntrian, rerataPanjangSistem,
rerataLamaTunggu, rerataLamaSistem, utilisasi)
else:
print(’Salah satu atau lebih parameter simulasi tidak valid.’)
daftarPelanggan = []
global angkaAcak
...
with parameter lamda, and the value of waktuMulai is the maximum between
waktuDatang and the finishing time of the chosen server (value of daftarPelayan
at index pelayan). The value of lamaPelayanan is the rounded up (ceil()) re-
sult of calling acakEksponensial() with parameter mu. After all that steps, a new
customer object is created by calling the constructor of class Pelanggan, and then
store the object to list daftarPelanggan. Before the next iteration, value of fin-
ishing time in list daftarPelayan and value of t are updated with the new one.
...
while t < waktuSimulasi:
pelayan = daftarPelayan.index(min(daftarPelayan))
if len(daftarPelanggan) == 0:
waktuDatang = int(math.ceil(acakEksponensial(lamda)))
waktuMulai = waktuDatang
else:
waktuDatang += int(math.ceil(acakEksponensial(lamda)))
waktuMulai = max(waktuDatang, daftarPelayan[pelayan])
lamaPelayanan = int(math.ceil(acakEksponensial(mu)))
daftarPelanggan.append(Pelanggan(pelayan+1, waktuDatang,
waktuMulai, lamaPelayanan))
daftarPelayan[pelayan] = waktuMulai + lamaPelayanan
t = waktuDatang
...
34
After the iteration ended, next step is to compute the result. All the five
return value for function simulasi() is computed in the following steps. Below is
how the code looks like.
pelanggan in daftarPelanggan]
rerataLamaTunggu = sum(daftarLamaTunggu) /
len(daftarLamaTunggu)
rerataPanjangAntrian = sum(daftarLamaTunggu) /
waktuBerakhir
daftarLamaTotal = [pelanggan.lamaTunggu +
pelanggan.lamaPelayanan for
pelanggan in daftarPelanggan]
rerataLamaTotal = sum(daftarLamaTotal) /
len(daftarLamaTotal)
rerataPanjangSistem = sum(daftarLamaSistem) /
waktuBerakhir
...
After getting all the results needed, the next step is to print them out. Below
is how the code looks like.
print(’Hasil simulasi:’)
print()
print(’ Jumlah pelayan:’, jumlahPelayan)
print(’ Rerata panjang antrian:’, rerataPanjangAntrian)
print()
...
The next step is to store the simulation data generated during the simulation,
into a CSV file. The data can then be opened in a spreadsheet application for further
processing, if desired by the user. Below is how the data stored to a CSV file in
keluaran = csv.writer(fileKeluaran)
keluaran.writerow([’Pelanggan’, ’Waktu datang’, ’Lama tunggu’,
’Pelayan’, ’Waktu mulai’, ’Lama pelayanan’,
’Waktu selesai’])
i = 0
for pelanggan in daftarPelanggan:
i += 1
baris = []
baris.append(i)
baris.append(pelanggan.waktuDatang)
baris.append(pelanggan.lamaTunggu)
baris.append(pelanggan.pelayan)
baris.append(pelanggan.waktuMulai)
baris.append(pelanggan.lamaPelayanan)
baris.append(pelanggan.waktuSelesai)
keluaran.writerow(baris)
fileKeluaran.close()
...
After the storing process is complete, a message about the name of the file is
displayed so that user can find it. Below is how the code looks like.
The simulation source file is named antrian.py. To run the simulation, first
user should go to the directory of the source file in a console application. After that,
user should run the python interpreter in that location, by typing python. Below is
D:\>cd Python
D:\Python>python
>>>
The triple > sign prompt indicates that user are inside Python interpreter
environment at the moment. Next step is to load the source into the interpreter, by
typing import antrian. To start the simulation and supply the parameters, type
antrian.simulasi(a,b,c,d), where:
• a is number of server
1
Below is an example of how to run the simulation with 4 servers, 4
mean
1
inter-arrival time, 3
mean service time, and 500 unit time of duration.
Figure 4.1 shows the result from the execution of the call to antrian.simulasi(4,
1/4, 1/3, 500) above. At the bottom of the result, a message about the name of
the file containing the simulation data is displayed. The file is located in the same
directory as the source file. Figure 4.2 shows the content of the file, opened with
The simulation procedure developed for this work, makes use of function
min() to find the minimum value of server’s finish time from the list daftarPelayan.
To find the minimum value of a list, all values need to be checked. This means that
the complexity of the algorithm is linear to n, the length of the list. In other words,
it has a complexity of class O(n) = n.
The performance being measured here is the runtime of the simulation, de-
pending on the number of server. The goal of the testing is to make sure that the
growth of runtime is linear to the number of server, supplied by the user as one of
the parameter to run the simulation.
To run the performance testing, two new lines of code are added to function
simulasi(). The first is to take the system time, right before the call to function
mulaiSimulasi(). The second is to take the system time, right after the call, and
40
then compute the difference, convert it to milliseconds, and print the result. Below
is how the code looks like, after modification.
waktuSimulasi > 0:
waktuMulai = time.time()
else:
The range of value for the number of server is from 500 up to 5000, increased
by 500 in each step. One step of testing consist of five run, and the result is the
average runtime from the five runs. The other parameters are kept constant, which
1 1
are 4
mean inter-arrival time, 3
mean service time, and 100000 unit time of duration.
Table 4.1 shows the result of the test.
Figure 4.3 shows the plot of the test result. From this plot, it can be seen that
the growth of runtime is linear to the growth of the number of server. This result is
just as expected, given that the function min() used in the simulation procedure,
is of complexity O(n) = n.
41
Figure 4.3: The growth of runtime is linear to the growth of number of server
2.12-2.16 in chapter 2, subsection 2.5. After getting the results, the expected perfor-
mance measurements is then compared to the performance measurements computed
by the simulation by calling function simulasi() in module antrian. Below is the
code that computes the expected and simulated performance measurements of the
import antrian
W = 1 / (mu - lamda)
print()
return (L_q, L, W_q, W, P_w)
lamda = 60/120
mu = 60/90
ekspektasi(lamda, mu)
expected W is 6 seconds, and the simulated one is 6.1 seconds (error: 1.67%). The
expected Wq is 4.5, and the simulated one is 4.07 (error: 9.55%).
lamda = 60/120
mu = 60/90
L_q, L, W_q, W, P_w = ekspektasi(lamda, mu)
total_run = 10000
iterasi = 0
p_w_error = 0
w_error = 0
w_q_error = 0
l_q,l,w_q,w,p_w = antrian.simulasi(1,lamda,mu,5000)
w_error += abs(W - w)
w_q_error += abs(W_q - w_q)
iterasi += 1
The mean error for 10,000 executions of the simulation is 7.69% for Pw ,
12.76% for W , and 15.87% for Wq . An example of the result from the extended test
can be seen in figure 4.5.
A furniture rental company owns a warehouse with a machine for loading and
in one hour.
As with the previous subsection, the expected and simulated cost will be
computed. The expected performance measurement is still computed by formula
2.12-2.16 in chapter 2, subsection 2.5. Below is the code that computes the expected
and simulated cost of the furniture rental company above.
import antrian
import numpy as np
import matplotlib.pyplot as plt
W = 1 / (mu - lamda)
def autolabel(rects):
kelompok = 3
jamKerja = 8
47
biayaTruk = 20
biayaPekerja = 6
lamda = 4/60
mu = 6/60
L_ekspektasi = []
L_simulasi = []
i*mu, 5000)
L_simulasi.append(L)
biaya_ekspektasi = []
biaya_simulasi = []
for i in range(1, 4):
biaya = L_ekspektasi[i-1]*jamKerja*biayaTruk +
i*kelompok*biayaPekerja*jamKerja
biaya_ekspektasi.append(biaya)
biaya = L_simulasi[i-1]*jamKerja*biayaTruk +
i*kelompok*biayaPekerja*jamKerja
biaya_simulasi.append(biaya)
N = 3
b_eks = tuple(biaya_ekspektasi)
ind = np.arange(N)
48
width = 0.35
fig, ax = plt.subplots()
rects1 = ax.bar(ind, b_eks, width, color=’c’)
b_sim = tuple(biaya_simulasi)
rects2 = ax.bar(ind+width, b_sim, width, color=’b’)
ax.set_xlabel(’Jumlah kelompok’)
ax.set_ylabel(’Biaya (US$)’)
(’Ekspektasi’, ’Simulasi’) )
autolabel(rects1)
autolabel(rects2)
plt.show()
Result of the logistic cost simulation can be seen in figure 4.6. For 1 group,
the expected cost is US$463, and the simulated one is US$545. For 2 groups, the
expected cost is US$368, and the simulated one is US$347. For 3 groups, the ex-
pected cost is US$477, and the simulated one is US$476. Based on the results, the
lowest cost is achieved by adding one more group of employee.
49
5.1 Conclusion
as the generic model, because of its ability in representing most of the problems
The design phase begin with establishing what performance parameters are
going to be measured. For this generic queueing systems simulation, they are: mean
waiting time per customer, mean time in system per customer, mean number of
waiting customer in queue, mean number of waiting customer in the system, and
After the performance parameters had been established, the design phase
continues with developing the simulation procedure. There are a total of 20 variables
used in the simulation procedure. The procedure itself rely on the common min()
function, to decide which server is chosen by the customer. By doing so, the customer
will always choose the idle or the closest-to-finish server. This is an optimal strategy
for the simulation.
Because security concern of random number is not taken into account for
the simulation, a simple and fast algorithm is chosen for this work. The chosen
algorithm is Lehmer random number generator, which is a kind of multiplicative
random number generator. The values for the variables used in Lehmer random
number generator, follows the one suggested by Park and Miller in 1988, and later
50
51
revised in 1993.
The simulation software is implemented using Python programming language.
The implementation follows the specification stated in chapter 3, about the input
process, simulation data-keeping mechanism, pseudo-random number generator, and
the output. Simulation data is stored to a CSV file, as convenient way for the user
to explore it at a later time.
Since the simulation procedure rely heavily on the min() function, it is hy-
pothesized that the runtime of the simulation depends on the length of the queue.
To confirm this, a performance test is done to see whether the growth of runtime is
linear to the growth of queue length. The test result confirmed this, and show that
each run of simulation. The mean error for 10,000 executions of the simulation are
still large (> 5%). Therefore, there is still room for improvement to reduce the error
rate of the simulation.
[5] F. Haight, Handbook of the Poisson Distribution. John Wiley & Sons, 1967.
[6] T. Kakiay, Dasar Teori Antrian untuk Kehidupan Nyata. Penerbit Andi, 2004.
[7] J. Kingman, “The first erlang century and the next,” Queueing Systems, vol. 63,
no. 1-4, pp. 1–2, 2009.
[8] S. Park and K. Miller, “Random number generators: Good ones are hard to
find,” Communications of the ACM, vol. 31, pp. 1192–1201, 1988.
[10] W. Payne, J. Rabung, and T. Bogyo, “Coding the lehmer pseudo-random num-
ber generator,” Communications of the ACM, vol. 12, pp. 85–86, 1969.
52
APPENDIX
Code Listings
Listing 5.1: program/antrian.py
1 import csv
2 import math
3 import time
4
5 class Pelanggan :
6 def __init__ ( self , pelayan , waktuDatang , waktuMulai ,
lamaPelayanan ) :
7 self . pelayan = pelayan
8 self . waktuDatang = waktuDatang
9 self . waktuMulai = waktuMulai
10 self . lamaPelayanan = lamaPelayanan
11 self . waktuSelesai = self . waktuMulai + self . lamaPelayanan
12 self . lamaTunggu = self . waktuMulai - self . waktuDatang
13
14 def acak () :
15 global angkaAcak
16 a = 48271
17 m = (2 ** 31) - 1
18 angkaAcak = ( a * angkaAcak ) % m
19 return float ( angkaAcak ) / m
20
21 def acakEksponensial ( lamda ) :
22 return - math . log ( acak () ) / lamda
23
24 def mulaiSimulasi ( jumlahPelayan , lamda , mu , waktuSimulasi ) :
25 t = 0
26 daftarPelanggan = []
27 daftarPelayan = [0] * jumlahPelayan
28
29 global angkaAcak , rerataPanjangAntrian , rerataPanjangSistem ,
rerataLamaTunggu , rerataLamaSistem , utilisasi
30
31 try :
32 fileMasukan = open ( " input . txt " , " r " )
33 angkaAcak = int ( fileMasukan . readline () )
34 except IOError :
35 fileMasukan = open ( " input . txt " , " w " )
36 angkaAcak = int ( time . time () * 256)
37 fileMasukan . write ( str ( angkaAcak ) )
38 finally :
39 fileMasukan . close ()
40
41 while t < waktuSimulasi :
53
42 pelayan = daftarPelayan . index ( min ( daftarPelayan ) )
43 if len ( daftarPelanggan ) == 0:
44 waktuDatang = int ( math . ceil ( acakEksponensial ( lamda ) ) )
45 waktuMulai = waktuDatang
46 else :
47 waktuDatang += int ( math . ceil ( acakEksponensial ( lamda ) ) )
48 waktuMulai = max ( waktuDatang , daftarPelayan [ pelayan ])
49 lamaPelayanan = int ( math . ceil ( acakEksponensial ( mu ) ) )
50 daftarPelanggan . append ( Pelanggan ( pelayan +1 , waktuDatang ,
waktuMulai , lamaPelayanan ) )
51 daftarPelayan [ pelayan ] = waktuMulai + lamaPelayanan
52 t = waktuDatang
53
54 fileMasukan = open ( " input . txt " , " w " )
55 fileMasukan . truncate ()
56 fileMasukan . write ( str ( angkaAcak ) )
57 fileMasukan . close ()
58
59 waktuBerakhir = daftarPelanggan [ -1]. waktuSelesai
60
61 daftarLamaTunggu = [ pelanggan . lamaTunggu for pelanggan in
daftarPelanggan ]
62 rerataLamaTunggu = sum ( daftarLamaTunggu ) / len ( daftarLamaTunggu )
63 r er a t a P a n j a n g Antrian = sum ( daftarLamaTunggu ) / waktuBerakhir
64
65 daftarLamaSistem = [ pelanggan . lamaTunggu + pelanggan .
lamaPelayanan for pelanggan in daftarPelanggan ]
66 rerataLamaSistem = sum ( daftarLamaSistem ) / len ( daftarLamaSistem )
67 r erat a Pa n j an g S istem = sum ( daftarLamaSistem ) / waktuBerakhir
68
69 d afta r La m a Pe l a yanan = [ pelanggan . lamaPelayanan for pelanggan in
daftarPelanggan ]
70 utilisasi = sum ( daftarL amaP el ayan a n ) / waktuBerakhir
71
72 print ( ’ Hasil simulasi : ’)
73 print ()
74 print ( ’ Jumlah pelayan : ’ , jumlahPelayan )
75 print ( ’ Rerata panjang antrian : ’ ,
re r a t a P a n j a ngAntrian )
76 print ( ’ Rerata panjang antrian dalam sistem : ’ ,
r er a ta P a nj angSistem )
77 print ( ’ Rerata lama tunggu : ’ , rerataLamaTunggu )
78 print ( ’ Rerata lama dalam sistem : ’ , rerataLamaSistem )
79 print ( ’ Utilisasi sistem : ’ , utilisasi )
80 print ()
81
82 namaFile = ’ simulasi (% s ,% s ,% s ,% s ) . csv ’ % ( jumlahPelayan , lamda ,
mu , waktuSimulasi )
83 with open ( namaFile , ’w ’ , newline = ’ ’) as fileKeluaran :
84 keluaran = csv . writer ( fileKeluaran )
54
85 keluaran . writerow ([ ’ Pelanggan ’ , ’ Waktu datang ’ , ’ Lama tunggu ’ ,
’ Pelayan ’ , ’ Waktu mulai ’ , ’ Lama pelayanan ’ , ’ Waktu selesai ’
])
86 i = 0
87 for pelanggan in daftarPelanggan :
88 i += 1
89 baris = []
90 baris . append ( i )
91 baris . append ( pelanggan . waktuDatang )
92 baris . append ( pelanggan . lamaTunggu )
93 baris . append ( pelanggan . pelayan )
94 baris . append ( pelanggan . waktuMulai )
95 baris . append ( pelanggan . lamaPelayanan )
96 baris . append ( pelanggan . waktuSelesai )
97 keluaran . writerow ( baris )
98 fileKeluaran . close ()
99
100 print ( ’ Data simulasi tersedia dalam file : ’ , namaFile )
101
102 def simulasi ( jumlahPelayan , lamda , mu , waktuSimulasi ) :
103 global rerataPanjangAntrian , rerataPanjangSistem ,
rerataLamaTunggu , rerataLamaSistem , utilisasi
104 if isinstance ( jumlahPelayan , int ) and jumlahPelayan >= 1 and
lamda != 0 and mu != 0 and waktuSimulasi > 0:
105 waktuMulai = time . time ()
106 mulaiSimulasi ( jumlahPelayan , lamda , mu , waktuSimulasi )
107 print ( ’ Simulasi selesai dalam ’ , int ( round (( time . time () -
waktuMulai ) * 1000) ) , ’ milidetik \ n ’)
108 return ( rerataPanjangAntrian , rerataPanjangSistem ,
rerataLamaTunggu , rerataLamaSistem , utilisasi )
109 else :
110 print ( ’ Salah satu atau lebih parameter simulasi tidak valid . ’)
111 return
55
Listing 5.2: program/mainframe.py
1 import antrian
2
3 def ekspektasi ( lamda , mu ) :
4 W_q = lamda / ( mu * ( mu - lamda ) )
5 W = 1 / ( mu - lamda )
6 L_q = ( lamda ** 2) / ( mu * ( mu - lamda ) )
7 L = lamda / ( mu - lamda )
8 P_w = lamda / mu
9 print ( ’ Ekspektasi sistem : ’)
10 print ()
11 print ( ’ Rerata panjang antrian : ’ , L_q )
12 print ( ’ Rerata panjang antrian dalam sistem : ’ , L)
13 print ( ’ Rerata lama tunggu : ’ , W_q )
14 print ( ’ Rerata lama dalam sistem : ’ , W)
15 print ( ’ Utilisasi sistem : ’ , P_w )
16 print ()
17 return ( L_q , L , W_q , W , P_w )
18
19 lamda = 60/120
20 mu = 60/90
21 ekspektasi ( lamda , mu )
22 antrian . simulasi (1 , lamda , mu , 5000)
56
Listing 5.3: program/logistik.py
1 import antrian
2 import numpy as np
3 import matplotlib . pyplot as plt
4
5 def ekspektasi ( lamda , mu ) :
6 W_q = lamda / ( mu * ( mu - lamda ) )
7 W = 1 / ( mu - lamda )
8 L_q = ( lamda ** 2) / ( mu * ( mu - lamda ) )
9 L = lamda / ( mu - lamda )
10 P_w = lamda / mu
11 return ( L_q , L , W_q , W , P_w )
12
13 def autolabel ( rects ) :
14 for rect in rects :
15 height = rect . get_height ()
16 ax . text ( rect . get_x () + rect . get_width () /2. , 1.05* height , ’% d ’% int
( height ) , ha = ’ center ’ , va = ’ bottom ’)
17
18 kelompok = 3
19 jamKerja = 8
20 biayaTruk = 20
21 biayaPekerja = 6
22 lamda = 4/60
23 mu = 6/60
24 L_ekspektasi = []
25 L_simulasi = []
26 for i in range (1 , 4) :
27 L_q , L , W_q , W , P_w = ekspektasi ( lamda , i * mu )
28 L_ekspektasi . append ( L )
29 L_q , L , W_q , W , P_w = antrian . simulasi (i , lamda , i * mu , 5000)
30 L_simulasi . append ( L )
31 biaya_ekspektasi = []
32 biaya_simulasi = []
33 for i in range (1 , 4) :
34 biaya = L_ekspektasi [i -1]* jamKerja * biayaTruk + i * kelompok *
biayaPekerja * jamKerja
35 biaya_ekspektasi . append ( biaya )
36 biaya = L_simulasi [i -1]* jamKerja * biayaTruk + i * kelompok *
biayaPekerja * jamKerja
37 biaya_simulasi . append ( biaya )
38
39 N = 3
40 b_eks = tuple ( biaya_ekspektasi )
41 ind = np . arange ( N )
42 width = 0.35
43 fig , ax = plt . subplots ()
44 rects1 = ax . bar ( ind , b_eks , width , color = ’c ’)
45 b_sim = tuple ( biaya_simulasi )
57
46 rects2 = ax . bar ( ind + width , b_sim , width , color = ’b ’)
47 ax . set_xlabel ( ’ Jumlah kelompok ’)
48 ax . set_ylabel ( ’ Biaya ( US$ ) ’)
49 ax . set_title ( ’ Perkiraan biaya : ekspektasi & hasil simulasi ’)
50 ax . set_xticks ( ind + width )
51 ax . set_xticklabels ( ( ’1 ’ , ’2 ’ , ’3 ’) )
52 ax . legend ( ( rects1 [0] , rects2 [0]) , ( ’ Ekspektasi ’ , ’ Simulasi ’) )
53 autolabel ( rects1 )
54 autolabel ( rects2 )
55 plt . show ()
58