CS2514 Lab 4
Introduction
Object-oriented programming languages are supposed to be very good for writing programs that carry out simulations, and that is the subject of this lab sheet, which will run for 2 weeks. We simulate a simple post office. Our post office has just one service position and one queue. (For those of you who know and care, this simulation is a discrete simulation involving a single-channel and a single-queue.)
Customers
I suggest your first job is to begin a class definition called Customer
.
Every customer object should have a unique identification number, which
gets passed into the constructor. The constructor should also take in the
customer's arrival time at the post office. The time will just be an
integer. So the signature is: public Customer(int id, int arrivalTime)
.
That's probably all that you need for now. But you will probably come back and add some methods later. It's your job to decide what else to add.
QueueOfCustomers
The next job is to write a class definition for QueueOfCustomers
.
From your data structures lectures, you know that queues are
first-in-first-out.
The constructor should take in the maximum capacity of the queue:
public QueueOfCustomers(int capacity)
. You decide what else
this class definition needs.
Important: I want you to write this class definition yourself
using arrays. You will lose all credit if you use classes from
java.util
.
To help you, I have written QueueTester.java
, which
you can use to check that your class definition works. (Note: When the queue is already full,
your insert
method can just do nothing. Similarly, when the queue is empty, your
remove
method can just do nothing.)
ServicePosition
The post office has a service position, where the person who is currently
being served stands. Write a class definition ServicePosition
whose constructor is: public ServicePosition(int minServiceTime, int maxServiceTime)
.
You decide what else this class definition needs.
PostOffice
Finally, write a class definition PostOffice
, with the
following interface:
public PostOffice(int capacity, double probabilityOfArrival, int minServiceTime, int maxServiceTime)
The constructor takes in the queue capacity (e.g. 5), the probability that a customer arrives (e.g. 0.6), and the minimum and maximum time it takes to serve a customer (e.g. 1 and 5).public void run(int period, boolean isVerbose)
This is where the action is!A
for
loop keeps track of time. The parameterperiod
determines how many times we go around the loop. E.g. ifperiod
is 30, then we go around 30 times. You can think of it as a 30 minute simulation.Within the loop, do all four of the following things:
- If someone is at the service position but their transaction is over, then finish serving them.
- Then, if no one is at the service position but there are people in the queue, start serving the person at the front of the queue.
- Also work out whether a new customer has arrived. (See below) If they have but the queue is full, they turn away; if the queue isn't full, they join it
-
Then, if the parameter
isVerbose
istrue
, display the state of the simulation.
In the above, you wanted to know whether a new customer has arrived at the post office. To do this, generate a random floating-point number between 0 and 1 and if that number is less than the number that was supplied as the second parameter of the constructor, then a new customer has arrived.
public void displayStats()
This method displays some stats and a bar chart on the screen. See example below.
PostOfficeTester
Here's a typical example of PostOfficeTester.java
:
class PostOfficeTester { public static void main(String[] args) { /* Create a post office in which - queue capacity is 4 - probability of arrival is 0.6 - min serving time is 1 - max serving time is 5 */ PostOffice po = new PostOffice(4, 0.6, 1, 5); /* Run the simulation - for a period of 15 mins - in verbose mode (hence lots of output) */ po.run(15, true); /* Display stats */ po.displayStats(); } }
And here's some sample output when I ran my version of this program. (The output may be different every time because of the use of random numbers.)
Time: 0 Service position: unoccupied Queue: [ Customer: 0 ] ===================================================================================================== Time: 1 Service position: Customer: 0 Queue: [ Customer: 1 ] ===================================================================================================== Time: 2 Service position: Customer: 0 Queue: [ Customer: 1 ] ===================================================================================================== Time: 3 Service position: Customer: 0 Queue: [ Customer: 1 Customer: 2 ] ===================================================================================================== Time: 4 Service position: Customer: 1 Queue: [ Customer: 2 ] ===================================================================================================== Time: 5 Service position: Customer: 1 Queue: [ Customer: 2 ] ===================================================================================================== Time: 6 Service position: Customer: 2 Queue: [ ] ===================================================================================================== Time: 7 Service position: Customer: 2 Queue: [ Customer: 3 ] ===================================================================================================== Time: 8 Service position: Customer: 3 Queue: [ Customer: 4 ] ===================================================================================================== Time: 9 Service position: Customer: 3 Queue: [ Customer: 4 Customer: 5 ] ===================================================================================================== Time: 10 Service position: Customer: 4 Queue: [ Customer: 5 Customer: 6 ] ===================================================================================================== Time: 11 Service position: Customer: 4 Queue: [ Customer: 5 Customer: 6 ] ===================================================================================================== Time: 12 Service position: Customer: 4 Queue: [ Customer: 5 Customer: 6 Customer: 7 ] ===================================================================================================== Time: 13 Service position: Customer: 5 Queue: [ Customer: 6 Customer: 7 ] ===================================================================================================== Time: 14 Service position: Customer: 5 Queue: [ Customer: 6 Customer: 7 Customer: 8 ] ===================================================================================================== STATISTICS Total customers: 8 Served: 5 Turned away: 0 Still in queue: 3 Service position idle time: 1 Service position busy time: 14 Waiting Times 0 1 ** 2 * 3 ** 4 * 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19You can see that at time 0, the service positon is unoccupied but customer 0 arrives in the queue. At time 1, customer 0 moves to the service position and customer 1 arrives in the queue. At time 2, customer 0 is still being served so customer 1 is still queuing. At time 3, this continues and also customer 2 arrives and joins the queue. At time 4, customer 0 has departed the service position, so customer 1 moves form the queue to be served, leaving customer 2 still in the queue. And so on!
The stats show that this post office is always busy but, happily, no one turned away. The bar chart shows that two people waited 1 minute, one person waited 2 minutes, two people waited 3 minutes, and so on.
Other class definitions
Are you allowed to write more class definitions than the ones I mentioned above? Yes!
Submission
Deadline: 4pm, Monday 29th February 2016.
Put all your class definitions into a directory called lab4
.
lab4
, not Lab4
,
lab-4
, Lab-4
or some other variant. Henceforth, variants will not be graded.
- Open the Dolphin File Manager. Right-click on your
lab4
directory. Choose Compress from the menu and As Zip File from the sub-menu. You should see a new icon appear, namedlab4.zip
. - Open a console; use the cd command to move to the directory that contains
lab4.zip
and type:submit-2514 lab4.zip
Challenge exercise
Remember that challenge exercises are always optional. They do not form part of your year's work and they are not worth any marks. They are designed for those students who finish the main exercise quickly and easily, and wish to explore further. You may need to use things not covered so far in lectures.
So far our simulation has a single-channel (i.e. single service position) and a single-queue. The challenge is to generalise this.
Many post offices have multiple-channels (i.e. several service positions). When they do, they then choose between having a single-queue (the head of which can go to whichever service position becomes free next) or multiple queues (one per service position). Let's try the multiple-channel, single-queue scenario.
You need another class definition, SetOfServicePositions
.
This has as an instance variable an array of ServicePosition
s.
Then you need a class MultiChannelPostOffice
.
At any time interval, we need to check each service position.
If it is busy, maybe the transaction is now over; if it is idle,
a queue member can move in. There may thus be several people
leaving the post office or moving from the queue to a service
position at each time point. You'll need to add methods to
SetOfServicePositions
to facilitate this.
(It's not as easy as you might think, especially if we are to get
a neat solution.)