COMP 2100 Project 3: Queuing System Simulation

Fall 2015

PHASE 4 : Develop and test Specialized Random Number Generators

Due: in lab, Thursday 12 November 2015
20 points

PHASE 4 : Develop and test Specialized Random Number Generators

A complex project like this needs to be developed in phases. In the fourth phase, you will define classes to represent objects capable of sampling randomly from a normal distribution and an exponential distribution. You will test them using your own test drivers embedded into the classes.

Modeling Random Behavior

A significant feature of many discrete event simulation models is they are non-deterministic. That is, the model has elements of random behavior. The most common of these are random inter-arrival times and random service times. That is, customer arrivals occur at random intervals, and service times vary randomly from one customer to the next.

In the event processing algorithms, the action of creating a new ArrivalEvent includes determining at what future time the next arrival event will occur. This is done by generating a random value and adding it to the current clock value. Since this is done at the time of an arrival, the random value represents the inter-arrival time. Similarly, when an ArrivalEvent or a DepartureEvent creates a new DepartureEvent, the time at which that departure will occur is determined by adding a random value to the current clock value. Since the random value is generated at the start of service, it represents the service time required.

Although we can generate random values using the static Math.random() method, for simulations it is better to create a different object of the java.util.Random class for each random variable. In this case, create one Random object for inter-arrival times and another for service times.

Creating a different Random object for each random variable gives us much greater control over simulation behavior. In particular, it allows us to control the sequence of random values. We have the option of giving a Random object a seed value. If we do so, we can guarantee that it will produce the same sequence (stream) of values every time we run the program. This is important for reproducibilty, which allows us to determine the effect of changing one factor (such as average inter-arrival time) while keeping all other factors the same.

Background: Software random number generators (RNG) are more accurately called pseudo-random number generators. The values are not truly random. In fact, each value in a sequence produced by such a generator is a function of the value that preceded it in the sequence. For instance, if an RNG generates the value 23 followed by the value 678, and later on it produces 23 again then a cycle has been established and it must be followed by 678 again! Therefore, giving the RNG a fixed seed value guarantees the same sequence every time we run the program.

Random variables such as inter-arrival times follow different probabilty distributions. The default behavior of an RNG is to produce values that vary according to a uniform distribution. This means that given a range of possible integer values, every value in the range has an equal probability of being produced. The Random method nextInt() generates uniformly-distributed random integer values while nextDouble() generates uniformly-distributed random double (real) values.

Sampling from the Uniform Distribution

The Random method nextInt() produces values from the entire integer range. That's a pretty wide range. Fortunately, it is overloaded with nextInt(int n) to produce values in the range from 0 (inclusive) to n (exclusive). If the low end of the desired range is greater than zero, we need to add the low end to the random value. For example: We have a Random object called randu and we want values from the range 10 (inclusive) to 25(exclusive). We get these from the expression 10 + randu.nextInt(15).

The Random method nextDouble() returns a randomly selected double value in the range from 0 (inclusive) to 1 (exclusive). It can similarly be mapped to a different range (multiply to widen the range, add/subtract to shift it).

Sampling Interrival Times from the Exponential Distribution

Unfortunately, real-life interarrival times are not uniformly distributed. They are "truly" random, following what is called the Exponential distribution. The Exponential distribution is the reciprocal of the well-known Poisson distribution. In other words, the Poisson distribution models arrival rates. For example: if customers arrive at the rate of 10 per hour on average, it is modeled by the Poisson distribution with a mean of 10. The flip side of this (reciprocal!) is the mean time between arrivals (i.e. interarrival time). For this example that is 1/10 hour, or 6 minutes.

Although the Java library does not provide a way to sample from an Exponential distribution, it is pretty easy to convert a value from the uniform distribution to fit it. Here's how.

Sampling from the Exponential Distribution: To convert a value R sampled from a random number generator (0 <= R < 1, uniform distribution) into a sample from the exponential distribution with mean M, simply apply the formula -M * ln(R), where ln is the natural log function.

Sampling Service Times from the Normal Distribution

In real-life, service times are not uniformly distributed either. They usually follow the well-known Normal distribution, a.k.a. Gaussian. Normal distributions are characterized by a mean and standard deviation, and form the familiar "bell curve" which peaks at the mean value and drops off symmetricly according to the standard deviation.

Fortunately, the Random class provides a method called nextGaussian() that samples from the standard normal distribution. The standard normal distribution has mean 0 and standard deviation 1. It is pretty easy to convert a value from the standard normal distribution to fit any normal distribution. Here's how.

Sampling from the Normal Distribution: To convert a value Z sampled from the standard normal distribution into a sample from the normal distribution with mean M and standard deviation D, simply apply the formula Z * D + M.

Implementation Notes

  1. Here is a ZIP file that contains the file you will need for development: phase4.zip. You can work in a separate folder if you like but if you do this, copy your work into the main Project 3 folder when you're done.
  2. The only file provided is RandomtTests.java, which is a test driver program.
  3. You will need to completely implement two classes: RandomNormal and RandomExponential classes (click for API).
  4. You must start by developing "stubbed" versions of both classes that meet the API specifications. Until this is completed the test driver will not compile.
  5. You do not need to provide any Javadoc. Please include your names and any comments you feel necessary to document the code.
  6. Each class will need at least an instance variable of type Random to do the actual work. Then you manipulate its results as needed.
  7. You will need additional instance variables. Remember: any information needed by more than one method or that needs to be retained over time should be represented by an instance variable.
  8. Some of the methods specify that the returned random sample fall into a specfied range. Those methods will need to use a while loop to repeat the sampling process until the random sample falls within the specified range. A similar technique is commonly used for user input verification.

Scoring

PointsDescription
10the RandomNormal class (2 points total for constructors, 2 points each for the 4 remaining methods)
10the RandomExponential class (2 points total for constructors, 2 points each for the 4 remaining methods)

To Turn In

Zip your entire Pr3 working folder into a ZIP file with phase4 in its name. Then drop it into your DropBox.
[ COMP 2100 | Peter Sanderson | Math Sciences home page | Otterbein ]

Last updated: 
Peter Sanderson (PSanderson@otterbein.edu)