Exercises 4.x: Pseudo Random Numbers

For this assignment, you will design and implement a pseudorandom number generator class. Your class should implement the RandI interface (provided on Eureka).

About random number generators

Computers cannot generate ‘truly’ random numbers. Instead, they compute ‘pseudo-random’ numbers that appear to be random but which are generated deterministically. The basic approach is the linear congruence method. The sequence generated is dependent upon a seed, a multiplier, an increment, and a modulus. The formula for generating the next pseudorandom number in the sequence is:

(multiplier * seed + increment) % modulus
(You can look up the Java % operator to see what it does, though you may be able to guess from the name of its second operand.)

The seed is initially set by one of several schemes such as sampling the current time of day; for our purposes, it will be an input to the constructor. After the first pseudorandom number has been generated, the seed is always set to the most recently generated number. For example: with multiplier, increment and modulus values of 40, 3641 and 729 respectively, and an initial seed of 1, our first pseudorandom number would be:

(40 * 1 + 3641) % 729 = 36
and after accessing this first random number, the seed value will be 36. When asked for the next pseudo-random number, this generator would compute
(40 * 36 + 3641) % 729 = 707
with the seed having a new value of 707. And so on.


Design and implement a class, PRNG, that generates a sequence of (pseudo) random numbers in the manner just described. As mentioned above, we want your class to implement the RandI interface.

  1. Your PRNG class should have at least three constructors: a default constructor that consumes no arguments, a second that consumes a single int representing the intitial seed, and a third that consumes four int inputs, for initial seed, multiplier, increment and modulus (in that order).
  2. The primary way we will want to interact with instances of the PRNG class will be through the random() method of the RandI interface. You should also implement the reset() method.
  3. In addition to implementing the three constructors and the two methods prescribed by the RandI interface, your class should provide a method, public void setSeed(int newseed), which has the effect of (re)setting the seed to the given value whenever this method is called. Note: reset() will restart the sequence from the original seed, while setSeed will change the original seed to an arbitrary value. Following a call on the setSeed method, any subsequent calls to reset() should restart the sequence at the most recently given newseed value given to setSeed.
  4. In a separate file, write a driver class, RandDriver, that exists to exercise the functionality of your PRNG class. As a driver class, RandDriver should have an appropriate main method; often driver classes will have no other methods. However, in this case your RandDriver class should have a bit more content. Your driver will use a local array to create a distribution of frequencies for the random numbers that are generated by your PRNG class. Every time a random number is generated, the range in which it falls will have a corresponding count increased. When completed, you will be able to print the frequencies of each range over some large number of random numbers. Obviously, a ‘good’ random number generator will produce something approximately uniform.
    1. The constructor for RandDriver should consume two arguments: a single int that specifies the number of ranges and their bounds, and an instance of your PRNG class.
    2. Provide a method public void sample(int nTimes) that records the counts in respective ranges for generating nTimes many random numbers from the PRNG instance.
    3. Write a method public void report() that displays the counts from any previous calls to sample.
    4. Finally, in your RandDriver's main method, create an instance of RandDriver and report the results from a large number of samples.

  5. Your result should look something like this
  6. In yet another file, implement the class RandomWalk that extends java.awt.Frame. This class should be similar to your RandDriver, but instead of storing a distribution in an array, RandomWalk should store positions (represented using your Posn class) in a java.util.Vector. You should use a generic instance of the Vector, such as Vector<MyPosn>. An instance of RandomWalk should have an instance variable that records the current location; this location should be initialized to the center of your canvas.
    1. write a method public void randomWalk(int nTimes) generates one random number and moves the x-value of the current position left four pixels if less than 0.5 and moves it right the same amount otherwise. Then generate another random number and move the y-value of the current position up four pixels if less than 0.5 and down four pixels otherwise. Each time the position moves, add to the Vector a new position representing the current location. Repeat this the given number of nTimes.
    2. override the public void paint(Graphics g) method. Your paint method should draw a small solid circle at the starting place and the ending place, and should draw lines showing the path taken from position to position during the random walk. The path will undoubtedly double back on itself so do not expect to see a visibly tracable path.

As always, you should fully document your code using javadoc directives. Similarly, you should generate the html files resulting from those comments and inspect them for completeness and correctness. Include these html files in your final submission.

Submission instructions:

Important: you should continue using the default package. When bundling your files for submission, make sure that you create a folder named with your Westmont email name followed by ‘Ex4.x’. For example, someone with email address ‘cjones’ would create a folder called ‘cjonesEx4.x’. Make sure that inside that folder you have: java source files as well as html documentation files resulting from javadoc. Finally, either tar or zip the folder so that when we extract it, the folder “<emailname>Ex4.x” will be created (with your actual eamil name). Submit the resulting archive on Eureka.

If you already submitted code for what was initially 4.1, please include that in your submission for 4.x. You are welcome to revise what you previously submitted.