Starting from:

$30

CS2030S-Project 2 Discrete Event Simulator Plus Solved

This stage of the project comprises three parts:

Dealing with side-effects
Randomizing arrival and service times
More complex behavior of shops, servers, and customers
Dealing with Side-Effects
For this part of the project, we shall first tackle the issue of side effects in Project #1. You would probably have coded something similar to the following, when processing the different Events (arrive, serve, wait, leave, done, ...) in the PriorityQueue pq.

while (!pq.isEmpty()) {
    Event e;
    e = pq.poll();
    System.out.println(e);
    Event nextEvent = e.execute();
    if (nextEvent.isValidEvent()) {
        pq.add(nextEvent);
    } 
}

Notice that every time the execute method of an event is invoked, it not only generates the next event based on the status of the Servers (here we call it a Shop), it will actually change the status of the servers as a side-effect. As such, we would like to address this side-effect by re-defining event generation as follows:

e.execute(s) -> (e',s') 

That is to say, the invocation of the execute method of an Event e with the argument Shop s, would now generate the next Event e' and Shop s' as a pair of values. In a similar fashion, e'and s' can then be used to generate the next pair of values.

Randomized Arrival and Service Time
Rather than fixed arrival and service times, we will generate random times. A random number generator is an entity that generates one random number after another. Since it is not possible to generate a truly random number algorithmically, pseudo random number generation is adopted instead. A pseudo-random number generator can be initialized with a seed, such that the same seed always produces the same sequence of (seemingly random) numbers.

Although, Java provides a class java.util.Random, an alternative RandomGenerator class that is more suitable for discrete event simulation is provided for you that encapsulates different random number generators for use in our simulator. Each random number generator generates a different stream of random numbers. The constructor for RandomGenerator takes in three parameters:

int seed is the base seed. Each random number generator uses its own seed that is derived from this base seed;
double lambda is the arrival rate, λ;
double mu is the service rate, μ.
The inter-arrival time is usually modeled as an exponential random variable, characterized by a single parameter λ denoting the arrival rate. The genInterArrivalTime() method of the class RandomGenerator is used for this purpose. Specifically,

start the simulation by generating the first customer arrival event with timestamp 0
if there are still more customers to simulate, generate the next arrival event with a timestamp of T + now, where T is generated with the method genInterArrivalTime();
The service time is modeled as an exponential random variable, characterized by a single parameter, service rate μ. The method genServiceTime() from the class RandomGenerator can be used to generate the service time. Specifically,

each time a customer is being served, a DONE event is generated and scheduled;
the DONE event generated will have a timestamp of T + now, where T is generated with the method genServiceTime().
You may refer to the API of the RandomGenerator class here. The class file can be downloaded from here.

Note that RandomGenerator class resides in the cs2030.simulator package. So, RandomGenerator.class should be saved in the cs2030/simulator directory.More Complex Behaviour of Shops, Serves and Customers
You will extend the simulator to model the following entities.

FIFO (first-in-first-out) queues for customers with a given maximum capacity
Two new eventsSERVER_REST that simulates a server taking a rest, and
SERVER_BACK that simulates a server returning back from rest
Two types of servers,human servers who may rest after serving a customer, and
self-checkout counters that never rest
Two types of customerstypical customers that joins the first queue (scanning from server 1 onwards) that is still not full, and
greedy customers that joins the queue with the fewest waiting customers
Customer Queues
Each human server now has a queue of customers to allow multiple customers to queue up. A customer that chooses to join a queue joins at the tail. When a server is done serving a customer, it serves the next waiting customer at the head of the queue. Hence, the queue should be a first-in-first-out (FIFO) structure. The self-checkout counters, however, have only a single shared queue.

Taking a Rest
The human servers are allowed to take occasional breaks. When a server finishes serving a customer, there is a probability Pr that the server takes a rest for a random amount of time Tr. During the break, the server does not serve the next waiting customer. Upon returning from the break, the server serves the next customer in the queue immediately.

To implement this behavior, introduce two new events, SERVER_REST and SERVER_BACK, to simulate taking a break, and returning. These events should be generated and scheduled in the simulator when the server decides to rest.

Self-Checkout
To reduce waiting time, self-checkout counters have been set-up. These self-checkout counters never need to rest. Customers queue up for the self-checkout counters in the same way as human servers. There is one shared queue for all self-checkout counters.

Customers' Choice of Queue
As before, when a customer arrives, he or she first scans through the servers (in order, from 1 to k) to see if there is an idle server (i.e. not serving a customer and not resting). If there is one, the customer will go to the server to be served. Otherwise, a typical customer just chooses the first queue (while scanning from servers 1 to k) that is still not full to join. However, other than the typical customer, a greedy customer is introduced that always joins the queue with the fewest customers. In the case of a tie, the customer breaks the tie by choosing the first one while scanning from servers 1 to k.

If a customer cannot find any queue to join, he/she will leave the shop.

All classes dealing with the simulation should now reside in the cs2030.simulator package, with the Main class outside the package, but importing the necessary classes from the package.

Program Style
Check for styling errors by invoking checkstyle. For example, to check styling for all java files

$ java -jar checkstyle-8.2-all.jar -c cs2030_checks.xml *.java

Writing and Generating Javadoc
You are to document your classes and methods with Javadoc comments. For more details, see the javadoc guide.

The Task
This task is divided into several levels. As the levels get progressively more complex, specific details will be provided in the corresponding levels.

As usual, you will need to keep track of the following statistics:

the average waiting time for customers who have been served
the number of customers served
the number of customers who left without being served
Take note of the following assumptions:

There is no longer an upper bound for the number of customers;
The format of the input is always correct;
Output of a double value, say d, is to be formatted with String.format("%.3f", d);
You have to complete ALL levels. 

Level 1
Levels 1 and 2 are specified with very rigid requirements, primarily so that students can meet the desired learning outcomes for the project. Do not worry if your code is packaged in cs2030.simulator. CodeCrunch will ignore the packages when testing in JShell.

First, we shall implement an immutable Shop class to hold the Servers. Recall that our Server class is defined as follows:

class Server {
    ...
    Server(int identifier, boolean isAvailable, boolean hasWaitingCustomer, double nextAvailableTime) {
        ...
    }
}

The Shop class is to be developed using a very functional style. Hence no loops are allowed. Do not write explicit for-loops or while-loops or recursion; you may use implicit loops such as Java streams.jshell> new Shop(2)
$.. ==> [1 is available, 2 is available]
jshell> Shop shops = new Shop(List.of(new Server(1, true, false, 0), new Server(2, false, false, 1.0)))
jshell> shops
shops ==> [1 is available, 2 is busy; available at 1.000]
jshell> shops.find(x -> x.isAvailable())
$.. ==> Optional[1 is available]
jshell> new Shop(2).find(x -> x.isAvailable())
$.. ==> Optional[1 is available]
jshell> shops.find(x -> x.isAvailable()).ifPresent(System.out::println)
1 is available
jshell> Server s = new Server(1, false, false, 2.0)
jshell> shops.replace(s)
$.. ==> [1 is busy; available at 2.000, 2 is busy; available at 1.000]
jshell> shops.replace(s).find(x -> x.isAvailable())
$.. ==> Optional.empty
jshell> shops
shops ==> [1 is available, 2 is busy; available at 1.000]
jshell> /exit

Level 2
Before proceeding to the Event class, you will first need to implement a generic Pair<T,U> class. This class is useful when returning multiple values from a function.

jshell> Pair<Integer,String> pair = Pair.of(1, "one");
jshell> pair.first()
$.. ==> 1
jshell> pair.second()
$.. ==> "one"
jshell> Pair<Long,Long> pair = Pair.of(0L, 100L);
jshell> pair.first()
$.. ==> 0
jshell> pair.second()
$.. ==> 100
jshell> /exit

As for the Event class, previously we created different events by overridding the execute method in Event. Rather than substitution via overriding, we shall use substitution via lambdas!

The Event class is now required to have a property of type Function<Shop, Pair<Shop, Event>>. Different types of events shall assign this lambda to a different functionality. For example, suppose we have a DummyEvent defined with a functionality that takes in a Shop comprising some Servers, and creates an empty shop and another dummy event. So DummyEvent will be defined as follows (here we assume that the Event has a constructor that only takes a Function as argument):

class DummyEvent extends Event {
    DummyEvent() {
        super(x -> new Pair<Shop,Event>(new Shop(), new DummyEvent()));
    }
    @Override
    public String toString() {
        return "DummyEvent";
    }
}

jshell> Event e = new DummyEvent()
e ==> DummyEvent

jshell> e.execute(new Shop(1))
$.. ==> Pair@........

jshell> e.execute(new Shop(1)).first()
$.. ==> []

jshell> e.execute(new Shop(1)).second()
$.. ==> DummyEvent

Notice that the execute method of the Event class can be defined simply as:

final Pair<Shop, Event> execute(Shop shop) { // declared final to avoid overriding
    return this.func.apply(shop); // func is the Function property
}

Invoking execute with a Shop will result in a Pair comprising a Shop (which is empty), and another DummyEvent. As you can see, other than Event itself, all specific types of events — arrive, serve, wait, done and leave, can now be fully specified with their relevant properties, and the addition of only one toString() method. Note that this constraint shall be enforced during grading. You still have the liberty of constructing your Event class in any way you wish.With this, you can now test the behaviour and correctness of your events by passing in a Shop and checking the returned Pair. Below is a snippet of how arrival events can be tested.

jshell> // one available server with no waiting customer
jshell> new ArriveEvent(new Customer(1, 1.0)).execute(new Shop(List.of(new Server(1,true,false,0)))).first() // (*) will not be tested
$.. ==> [1 is available]
jshell> new ArriveEvent(new Customer(1, 1.0)).execute(new Shop(List.of(new Server(1,true,false,0)))).second() // (*) will not be tested
$.. ==> 1.000 1 served by server 1
jshell> // one busy server with no waiting customer
jshell> new ArriveEvent(new Customer(1, 1.0)).execute(new Shop(List.of(new Server(1,false,false,1.0)))).first()
$.. ==> [1 is busy; available at 1.000]
jshell> new ArriveEvent(new Customer(1, 1.0)).execute(new Shop(List.of(new Server(1,false,false,1.0)))).second()
$.. ==> 1.000 1 waits to be served by server 1
jshell> // one busy server with waiting customer
jshell> new ArriveEvent(new Customer(1, 1.0)).execute(new Shop(List.of(new Server(1,false,true,2.0)))).first()
$.. ==> [1 is busy; waiting customer to be served at 2.000]
jshell> new ArriveEvent(new Customer(1, 1.0)).execute(new Shop(List.of(new Server(1,false,true,2.0)))).second()
$.. ==> 1.000 1 leaves
jshell> /exit

Note that an arrival event does not cause the servers in the shop to change, but only transits to another event depend on the state of the servers.

(*) This test case will not be tested as it is not deterministic. In the case if the server rests (level 5) in between the arrival and serve events, then the server will actually not be able to serve.

Just remember the following constraints:

every subclass of Event can only have properties, and at most ONE toString() method;
every subclass of Event must not contain explicit loops.
As there could be varying ways in how your specific events are constructed, there will be no test cases. That said, you should still test out this new implementation of event generation on the inputs of the final level of Project #1 and check if the behaviour is the same.
Level 3
Randomizing arrival and service times

From this level on, we shall test your implementation with the Main class. Make sure that all other classes reside in the cs2030.simulator package.

Input to the program comprises (in order of presentation):

an int value denoting the base seed for the RandomGenerator object;
an int value representing the number of servers
an int representing the number of customers (or the number of arrival events) to simulate
a positive double parameter for the arrival rate, λ
a positive double parameter for the service rate, μ
Remember to start the simulation by generating the first customer arrival event with timestamp 0, and then generate the next arrival event of the next customer by adding the time generated using the method genInterArrivalTime() from the class RandomGenerator.

The method genServiceTime() from the class can be used to generate the service time. Intuitively, the service time ought to be generated together with the arrival time as each customer is created before the simulation starts. However, do note that the nth customer to arrive might not be the nth customer to be served! So service time should be generated when the customer is being served, which might entail passing the RandomGenerator along with the Customer. This need not be so! Hint: Think Lazy...

The following is a sample run of the program. Note that inputs are passed as command line arguments to Main.

 

$ java Main 1 1 5 1.0 1.0
0.000 1 arrives
0.000 1 served by server 1
0.313 1 done serving by server 1
0.314 2 arrives
0.314 2 served by server 1
0.417 2 done serving by server 1
1.205 3 arrives
1.205 3 served by server 1
1.904 3 done serving by server 1
2.776 4 arrives
2.776 4 served by server 1
2.791 4 done serving by server 1
3.877 5 arrives
3.877 5 served by server 1
4.031 5 done serving by server 1
[0.000 5 0]

$ java Main 1 2 10 1.0 1.0
0.000 1 arrives
0.000 1 served by server 1
0.313 1 done serving by server 1
0.314 2 arrives
0.314 2 served by server 1
0.417 2 done serving by server 1
1.205 3 arrives
1.205 3 served by server 1
1.904 3 done serving by server 1
2.776 4 arrives
2.776 4 served by server 1
2.791 4 done serving by server 1
3.877 5 arrives
3.877 5 served by server 1
3.910 6 arrives
3.910 6 served by server 2
3.922 6 done serving by server 2
4.031 5 done serving by server 1
9.006 7 arrives
9.006 7 served by server 1
9.043 8 arrives
9.043 8 served by server 2
9.105 9 arrives
9.105 9 waits to be served by server 1
9.160 10 arrives
9.160 10 waits to be served by server 2
10.484 7 done serving by server 1
10.484 9 served by server 1
10.781 9 done serving by server 1
11.636 8 done serving by server 2
11.636 10 served by server 2
11.688 10 done serving by server 2
[0.386 10 0]

Level 4
Implement the customer queues

Input to the program comprises (in order of presentation):

an int value denoting the base seed for the RandomGenerator object;
an int value representing the number of servers
an int value for the maximum queue length, Qmax
an int representing the number of customers (or the number of arrival events) to simulate
a positive double parameter for the arrival rate, λ
a positive double parameter for the service rate, μ
Now, each queue has a maximum capacity Qmax, and a customer cannot join a queue that is full. Note that a customer being served is not inside the queue. When a customer arrives and all the queues are full, then the customer leaves.

Clearly, if Qmax = 1, then the simulation reverts back to the one that allows only one waiting customer.

The following is a sample run of the program.

$ java Main 1 2 2 10 1.0 1.0
0.000 1 arrives
0.000 1 served by server 1
0.313 1 done serving by server 1
0.314 2 arrives
0.314 2 served by server 1
0.417 2 done serving by server 1
1.205 3 arrives
1.205 3 served by server 1
1.904 3 done serving by server 1
2.776 4 arrives
2.776 4 served by server 1
2.791 4 done serving by server 1
3.877 5 arrives
3.877 5 served by server 1
3.910 6 arrives
3.910 6 served by server 2
3.922 6 done serving by server 2
4.031 5 done serving by server 1
9.006 7 arrives
9.006 7 served by server 1
9.043 8 arrives
9.043 8 served by server 2
9.105 9 arrives
9.105 9 waits to be served by server 1
9.160 10 arrives
9.160 10 waits to be served by server 1
10.484 7 done serving by server 1
10.484 9 served by server 1
10.781 9 done serving by server 1
10.781 10 served by server 1
10.833 10 done serving by server 1
11.636 8 done serving by server 2
[0.300 10 0]

Notice that the number of command line inputs is different from the previous level, as well as subsequent ones. In your Main class, you will need to identify the number of inputs, so as parse the inputs correctly for the correct level.
Level 5
Implementing server breaks

Input to the program comprises (in order of presentation):

an int value denoting the base seed for the RandomGenerator object;
an int value representing the number of servers
an int value for the maximum queue length, Qmax
an int representing the number of customers (or the number of arrival events) to simulate
a positive double parameter for the arrival rate, λ
a positive double parameter for the service rate, μ
a positive double parameter for the resting rate, ρ
a double parameter for the probability of resting, Pr
Include two events SERVER_REST and SERVER_BACK, to simulating taking a break, and returning. These events should be generated and scheduled in the simulator when the server decides to rest.

To decide if the server should rest, a random number uniformly drawn from [0, 1] is generated using the RandomGenerator method genRandomRest(). If the value returned is less than Pr, the server rests with a SERVER_REST event generated. Otherwise, the server does not rest but continues serving the next customer.

As soon as the server rests, a random rest period Tr is generated using the RandomGenerator method genRestPeriod(). This variable is an exponential random variable, governed by the resting rate, ρ. A SERVER_BACK event will be scheduled at Tr + now.

The following is a sample run of the program.

$ java Main 1 2 2 10 1.0 1.0 0 0
0.000 1 arrives
0.000 1 served by server 1
0.313 1 done serving by server 1
0.314 2 arrives
0.314 2 served by server 1
0.417 2 done serving by server 1
1.205 3 arrives
1.205 3 served by server 1
1.904 3 done serving by server 1
2.776 4 arrives
2.776 4 served by server 1
2.791 4 done serving by server 1
3.877 5 arrives
3.877 5 served by server 1
3.910 6 arrives
3.910 6 served by server 2
3.922 6 done serving by server 2
4.031 5 done serving by server 1
9.006 7 arrives
9.006 7 served by server 1
9.043 8 arrives
9.043 8 served by server 2
9.105 9 arrives
9.105 9 waits to be served by server 1
9.160 10 arrives
9.160 10 waits to be served by server 1
10.484 7 done serving by server 1
10.484 9 served by server 1
10.781 9 done serving by server 1
10.781 10 served by server 1
10.833 10 done serving by server 1
11.636 8 done serving by server 2
[0.300 10 0]

$ java Main 1 2 2 20 1.0 1.0 0.1 0.5
0.000 1 arrives
0.000 1 served by server 1
0.313 1 done serving by server 1
0.314 2 arrives
0.314 2 served by server 1
0.417 2 done serving by server 1
1.205 3 arrives
1.205 3 served by server 2
1.904 3 done serving by server 2
2.776 4 arrives
2.776 4 served by server 2
2.791 4 done serving by server 2
3.877 5 arrives
3.877 5 served by server 1
3.910 6 arrives
3.910 6 served by server 2
3.922 6 done serving by server 2
4.031 5 done serving by server 1
9.006 7 arrives
9.006 7 served by server 1
9.043 8 arrives
9.043 8 served by server 2
9.105 9 arrives
9.105 9 waits to be served by server 1
9.160 10 arrives
9.160 10 waits to be served by server 1
9.225 11 arrives
9.225 11 waits to be served by server 2
10.148 12 arrives
10.148 12 waits to be served by server 2
10.484 7 done serving by server 1
10.484 9 served by server 1
10.781 9 done serving by server 1
11.205 13 arrives
11.205 13 waits to be served by server 1
11.636 8 done serving by server 2
11.636 11 served by server 2
11.688 11 done serving by server 2
11.688 12 served by server 2
12.429 14 arrives
12.429 14 waits to be served by server 2
13.109 15 arrives
13.109 15 waits to be served by server 2
14.644 10 served by server 1
15.013 10 done serving by server 1
15.178 12 done serving by server 2
15.178 14 served by server 2
15.264 16 arrives
15.264 16 waits to be served by server 1
15.338 14 done serving by server 2
15.338 15 served by server 2
15.524 17 arrives
15.524 17 waits to be served by server 2
15.940 18 arrives
15.940 18 waits to be served by server 2
17.793 19 arrives
17.793 19 leaves
18.207 15 done serving by server 2
18.207 17 served by server 2
18.765 20 arrives
18.765 20 waits to be served by server 2
19.103 17 done serving by server 2
19.103 18 served by server 2
20.146 18 done serving by server 2
40.474 13 served by server 1
40.480 13 done serving by server 1
40.480 16 served by server 1
41.056 16 done serving by server 1
57.110 20 served by server 2
57.852 20 done serving by server 2
[6.025 19 1]

Level 6
Include self-checkout counters

Input to the program comprises (in order of presentation):

an int value denoting the base seed for the RandomGenerator object;
an int value representing the number of servers
an int value representing the number of self-checkout counters, Nself
an int value for the maximum queue length, Qmax
an int representing the number of customers (or the number of arrival events) to simulate
a positive double parameter for the arrival rate, λ
a positive double parameter for the service rate, μ
a positive double parameter for the resting rate, ρ
a double parameter for the probability of resting, Pr
There are Nself self-checkout counters set up. In particular, if there are k human servers, then the self-checkout counters are identified from k + 1 onwards. All self-checkout counters share the same queue. When we print out the wait event, we always say that the customer is waiting for the self-checkout counter k + 1, even though this customer may eventually be served by another self-checkout counter.

The following is a sample run of the program.

$ java Main 1 2 0 2 20 1.0 1.0 0.1 0.5
0.000 1 arrives
0.000 1 served by server 1
0.313 1 done serving by server 1
0.314 2 arrives
0.314 2 served by server 1
0.417 2 done serving by server 1
1.205 3 arrives
1.205 3 served by server 2
1.904 3 done serving by server 2
2.776 4 arrives
2.776 4 served by server 2
2.791 4 done serving by server 2
3.877 5 arrives
3.877 5 served by server 1
3.910 6 arrives
3.910 6 served by server 2
3.922 6 done serving by server 2
4.031 5 done serving by server 1
9.006 7 arrives
9.006 7 served by server 1
9.043 8 arrives
9.043 8 served by server 2
9.105 9 arrives
9.105 9 waits to be served by server 1
9.160 10 arrives
9.160 10 waits to be served by server 1
9.225 11 arrives
9.225 11 waits to be served by server 2
10.148 12 arrives
10.148 12 waits to be served by server 2
10.484 7 done serving by server 1
10.484 9 served by server 1
10.781 9 done serving by server 1
11.205 13 arrives
11.205 13 waits to be served by server 1
11.636 8 done serving by server 2
11.636 11 served by server 2
11.688 11 done serving by server 2
11.688 12 served by server 2
12.429 14 arrives
12.429 14 waits to be served by server 2
13.109 15 arrives
13.109 15 waits to be served by server 2
14.644 10 served by server 1
15.013 10 done serving by server 1
15.178 12 done serving by server 2
15.178 14 served by server 2
15.264 16 arrives
15.264 16 waits to be served by server 1
15.338 14 done serving by server 2
15.338 15 served by server 2
15.524 17 arrives
15.524 17 waits to be served by server 2
15.940 18 arrives
15.940 18 waits to be served by server 2
17.793 19 arrives
17.793 19 leaves
18.207 15 done serving by server 2
18.207 17 served by server 2
18.765 20 arrives
18.765 20 waits to be served by server 2
19.103 17 done serving by server 2
19.103 18 served by server 2
20.146 18 done serving by server 2
40.474 13 served by server 1
40.480 13 done serving by server 1
40.480 16 served by server 1
41.056 16 done serving by server 1
57.110 20 served by server 2
57.852 20 done serving by server 2
[6.025 19 1]

$ java Main 1 2 1 2 20 1.0 1.0 0.1 0.5
0.000 1 arrives
0.000 1 served by server 1
0.313 1 done serving by server 1
0.314 2 arrives
0.314 2 served by server 1
0.417 2 done serving by server 1
1.205 3 arrives
1.205 3 served by server 2
1.904 3 done serving by server 2
2.776 4 arrives
2.776 4 served by server 2
2.791 4 done serving by server 2
3.877 5 arrives
3.877 5 served by server 1
3.910 6 arrives
3.910 6 served by server 2
3.922 6 done serving by server 2
4.031 5 done serving by server 1
9.006 7 arrives
9.006 7 served by server 1
9.043 8 arrives
9.043 8 served by server 2
9.105 9 arrives
9.105 9 served by self-check 3
9.160 10 arrives
9.160 10 waits to be served by server 1
9.225 11 arrives
9.225 11 waits to be served by server 1
9.402 9 done serving by self-check 3
10.148 12 arrives
10.148 12 served by self-check 3
10.200 12 done serving by self-check 3
10.484 7 done serving by server 1
10.484 10 served by server 1
11.205 13 arrives
11.205 13 served by self-check 3
11.574 13 done serving by self-check 3
11.636 8 done serving by server 2
12.429 14 arrives
12.429 14 served by self-check 3
12.589 14 done serving by self-check 3
13.109 15 arrives
13.109 15 served by self-check 3
13.974 10 done serving by server 1
13.974 11 served by server 1
14.869 11 done serving by server 1
15.264 16 arrives
15.264 16 served by server 1
15.524 17 arrives
15.524 17 served by server 2
15.531 17 done serving by server 2
15.940 18 arrives
15.940 18 waits to be served by server 1
15.978 15 done serving by self-check 3
16.307 16 done serving by server 1
16.307 18 served by server 1
16.883 18 done serving by server 1
17.793 19 arrives
17.793 19 served by server 1
18.535 19 done serving by server 1
18.765 20 arrives
18.765 20 served by server 1
21.773 20 done serving by server 1
[0.322 20 0]

$ java Main 1 1 2 2 20 1.0 0.1 0.1 0.5
0.000 1 arrives
0.000 1 served by server 1
0.314 2 arrives
0.314 2 served by self-check 2
1.205 3 arrives
1.205 3 served by self-check 3
1.351 2 done serving by self-check 2
2.776 4 arrives
2.776 4 served by self-check 2
2.919 4 done serving by self-check 2
3.131 1 done serving by server 1
3.877 5 arrives
3.877 5 served by server 1
3.910 6 arrives
3.910 6 served by self-check 2
4.036 6 done serving by self-check 2
5.419 5 done serving by server 1
8.200 3 done serving by self-check 3
9.006 7 arrives
9.006 7 served by server 1
9.043 8 arrives
9.043 8 served by self-check 2
9.105 9 arrives
9.105 9 served by self-check 3
9.160 10 arrives
9.160 10 waits to be served by server 1
9.225 11 arrives
9.225 11 waits to be served by server 1
10.148 12 arrives
10.148 12 waits to be served by self-check 2
11.205 13 arrives
11.205 13 waits to be served by self-check 2
12.074 9 done serving by self-check 3
12.074 12 served by self-check 3
12.429 14 arrives
12.429 14 waits to be served by self-check 2
12.591 12 done serving by self-check 3
12.591 13 served by self-check 3
13.109 15 arrives
13.109 15 waits to be served by self-check 2
15.264 16 arrives
15.264 16 leaves
15.524 17 arrives
15.524 17 leaves
15.940 18 arrives
15.940 18 leaves
17.793 19 arrives
17.793 19 leaves
18.765 20 arrives
18.765 20 leaves
23.784 7 done serving by server 1
24.631 10 served by server 1
28.318 10 done serving by server 1
28.318 11 served by server 1
29.923 11 done serving by server 1
34.974 8 done serving by self-check 2
34.974 14 served by self-check 2
47.487 13 done serving by self-check 3
47.487 15 served by self-check 3
56.445 15 done serving by self-check 3
63.665 14 done serving by self-check 2
[6.320 15 5]

Level 7
Include greedy customers

Input to the program comprises (in order of presentation):

an int value denoting the base seed for the RandomGenerator object;
an int value representing the number of servers
an int value representing the number of self-checkout counters, Nself
an int value for the maximum queue length, Qmax
an int representing the number of customers (or the number of arrival events) to simulate
a positive double parameter for the arrival rate, λ
a positive double parameter for the service rate, μ
a positive double parameter for the resting rate, ρ
a double parameter for the probability of resting, Pr
a double parameter for the probability of a greedy customer occurring, Pg
An arriving customer is a greedy customer with probability Pg. To decide whether a typical or greedy customer is created, a random number uniformly drawn from [0, 1] is generated with the RandomGenerator method genCustomerType(). If the value returned is less than Pg, a greedy customer is generated, otherwise, a typical customer is generated.The following is a sample run of the program.

$ java Main 1 2 1 2 20 1.0 1.0 0.1 0.5 0
0.000 1 arrives
0.000 1 served by server 1
0.313 1 done serving by server 1
0.314 2 arrives
0.314 2 served by server 1
0.417 2 done serving by server 1
1.205 3 arrives
1.205 3 served by server 2
1.904 3 done serving by server 2
2.776 4 arrives
2.776 4 served by server 2
2.791 4 done serving by server 2
3.877 5 arrives
3.877 5 served by server 1
3.910 6 arrives
3.910 6 served by server 2
3.922 6 done serving by server 2
4.031 5 done serving by server 1
9.006 7 arrives
9.006 7 served by server 1
9.043 8 arrives
9.043 8 served by server 2
9.105 9 arrives
9.105 9 served by self-check 3
9.160 10 arrives
9.160 10 waits to be served by server 1
9.225 11 arrives
9.225 11 waits to be served by server 1
9.402 9 done serving by self-check 3
10.148 12 arrives
10.148 12 served by self-check 3
10.200 12 done serving by self-check 3
10.484 7 done serving by server 1
10.484 10 served by server 1
11.205 13 arrives
11.205 13 served by self-check 3
11.574 13 done serving by self-check 3
11.636 8 done serving by server 2
12.429 14 arrives
12.429 14 served by self-check 3
12.589 14 done serving by self-check 3
13.109 15 arrives
13.109 15 served by self-check 3
13.974 10 done serving by server 1
13.974 11 served by server 1
14.869 11 done serving by server 1
15.264 16 arrives
15.264 16 served by server 1
15.524 17 arrives
15.524 17 served by server 2
15.531 17 done serving by server 2
15.940 18 arrives
15.940 18 waits to be served by server 1
15.978 15 done serving by self-check 3
16.307 16 done serving by server 1
16.307 18 served by server 1
16.883 18 done serving by server 1
17.793 19 arrives
17.793 19 served by server 1
18.535 19 done serving by server 1
18.765 20 arrives
18.765 20 served by server 1
21.773 20 done serving by server 1
[0.322 20 0]

$ java Main 1 2 1 2 20 1.0 1.0 0.1 0.5 0.9
0.000 1(greedy) arrives
0.000 1(greedy) served by server 1
0.313 1(greedy) done serving by server 1
0.314 2(greedy) arrives
0.314 2(greedy) served by server 1
0.417 2(greedy) done serving by server 1
1.205 3(greedy) arrives
1.205 3(greedy) served by server 2
1.904 3(greedy) done serving by server 2
2.776 4(greedy) arrives
2.776 4(greedy) served by server 2
2.791 4(greedy) done serving by server 2
3.877 5(greedy) arrives
3.877 5(greedy) served by server 1
3.910 6(greedy) arrives
3.910 6(greedy) served by server 2
3.922 6(greedy) done serving by server 2
4.031 5(greedy) done serving by server 1
9.006 7(greedy) arrives
9.006 7(greedy) served by server 1
9.043 8(greedy) arrives
9.043 8(greedy) served by server 2
9.105 9(greedy) arrives
9.105 9(greedy) served by self-check 3
9.160 10 arrives
9.160 10 waits to be served by server 1
9.225 11(greedy) arrives
9.225 11(greedy) waits to be served by server 2
9.402 9(greedy) done serving by self-check 3
10.148 12(greedy) arrives
10.148 12(greedy) served by self-check 3
10.200 12(greedy) done serving by self-check 3
10.484 7(greedy) done serving by server 1
10.484 10 served by server 1
11.205 13(greedy) arrives
11.205 13(greedy) served by self-check 3
11.574 13(greedy) done serving by self-check 3
11.636 8(greedy) done serving by server 2
12.429 14(greedy) arrives
12.429 14(greedy) served by self-check 3
12.589 14(greedy) done serving by self-check 3
13.109 15(greedy) arrives
13.109 15(greedy) served by self-check 3
13.974 10 done serving by server 1
15.264 16 arrives
15.264 16 served by server 1
15.500 11(greedy) served by server 2
15.524 17(greedy) arrives
15.524 17(greedy) waits to be served by server 1
15.940 18(greedy) arrives
15.940 18(greedy) waits to be served by server 2
15.978 15(greedy) done serving by self-check 3
16.159 16 done serving by server 1
16.159 17(greedy) served by server 1
16.166 17(greedy) done serving by server 1
16.543 11(greedy) done serving by server 2
16.543 18(greedy) served by server 2
17.119 18(greedy) done serving by server 2
17.793 19(greedy) arrives
17.793 19(greedy) served by server 2
18.535 19(greedy) done serving by server 2
18.765 20(greedy) arrives
18.765 20(greedy) served by server 2
21.773 20(greedy) done serving by server 2
[0.442 20 0]
 

More products