In this lab you write a program that simulates a ride at a theme park. In this ride, people get into a small boat, navigate the boat through a course of obstacles and then dock and leave the boat. Management would like to assess how long people spend waiting for the ride and as well as how much utilization they are getting out of each boat. Note that each person takes a variable amount to time to navigate the course, so the order they depart is not necessarily the order in which they leave. Also, there is only one spot on the dock where a person can get into a boat, so while the person is climbing in, boats must wait in line. This means you will have to have two queues: one for people waiting to board a boat and one for boats waiting to be boarded. For simplicity, you can assume that unloading from the boat happens quickly and doesn't need to be accounted for.
You should write a JApplet or application which extends JFrame which has labels and text fields which prompt the user for several pieces of input. Specifically, you need to know the average inter-arrival time of riders, the average loading time for a rider, the average ride time for a rider, the total length of the simulation and the number of boats. The inter-arrival time of riders is the length of time that elapses after one riders arrives until the next one arrives. This will vary from rider to rider, but you can input the average value so that you can examine the system under different levels of demand. Similarly, the loading and ride time of each person will vary, but you can specify the average of these values.
Time is measured in an arbitrary unit which we will call `clock ticks'. It's not terribly important what a clock tick actually represents because all the values are relative. Any interval of time (including the average values input by the user) should be specified as integers, so time is rounded to the nearest clock tick. I recommend that you keep the average inter-arrival time of riders to be at least 100 so as to minimize the effects of rounding. If the inter-arrival time is 100, then you should simulate the system for about a million clock ticks so that the values that you are measuring will converge to an average value. (The longer you run the simulation, the more stable these values will be).
The running time of your algorithm should not depend on the number of clock ticks that you run your simulation. This is because you should write your code as an event-driven simulation. That is, you will determine the next event (whether it be the arrival of a person to the rider, the departure of a boat with a rider from the dock, the return of a boat and rider to the dock) and advance the clock automatically to the time of the next event. That is, your program should take roughtly the same amount of time if the average inter-arrival time, loading time and riding time is 10 and the simulation length is 1000 as it would if all of these values were multiplied by 10.
I am providing you with a few classes for your use. The first is class EventGenerator which generates the arrival of riders. Your program should have an instance of this class to generate the input data. Before you run your simulation, you should use the following method to inform the event generator of the parameters input by the user:
public void setParameters( int avgInterArrivalTime, int avgLoadingTime, int avgRideTime )
public Rider getNextEvent( int lastArrival )
The EventGenerator uses a random number generator to produce the inter-arrival time, loading time and riding time for the particular customer. On average, the values generated will match the average values input by the user, but there are some random fluctuations in the values. In this case, it is implemented as a Poisson Process . You will probably learn about these some time in your career here in ICS.
I have also supplied you with a class Priority Queue
which will be useful for storing the boat/rider pairs are currently
out on the course.
You want to store these in a priority queue since you will
need to determine which one returns next.
The constructor for PriorityQueue takes in a value which is the maximum
number of items that will ever be stored in the priority queue.
Each time you run a simulation, you should create an instance
of class PriorityQueue in which this value is set to be
the number of boats.
The method add throws an instance of class
QueueFullException (also provided) if
you attempt to add an item when the priority queue is full.
You will need to provide code which will catch that exception
when you call the add method.
The PriorityQueue is written as a generic data structure
so that it can store any set of items which implements the
interface Comparable which I have
also provided for you.
Note that your class which implements Comparable will
have to implement a method compareTo
because it is declared as an abstract method in Comparable.
The deleteMin() method returns the item
with the smallest values according to the
compareTo method.
You will need to write your own class Queue . This should also be written as a generic data structure. In particular, you will have an instance of Queue which stores instances of Boat and an instance which stores instances of Rider. You can choose how you want to implement your queue. However, your choice must be completely transparent to the user.
The statistics which you should print out after processing all the events are:
What to turn in: