Search code examples
javarandomnormal-distribution

Is there a way in Java to generate random numbers following fixed mean and standard deviation?


Question

I know how to generate random numbers with a fixed mean and standard deviation.

I'd additionally like those values to be constrained to be within a range (I understand that this means the results won't be a true Gaussian distribution as a result, but a clipped Gaussian distribution)

Context

The wider question I'm trying to answer is

Assume you have a black box that gives out a monkey every 10 sec, the height of the monkey is between 24 and 36 inches. The height of the monkeys generated over half n hour follows a normal distribution with mean 30.5 inches and standard deviation 2.5. While there is another box in the room that causes a monkey to vanish if it’s height is below 28 inches, this happens every 20 secs. Write a program to calculate the number of monkeys left in the room after n-days (n is a user input). For the sake of logic assume room is large enough to accommodate an infinite number of monkeys and they have food.


Solution

  • The nextGaussian() method returns random numbers with a mean of 0 and a standard deviation of 1.

    This means that numbers returned by nextGaussian() will tend to "cluster" around 0, and that (approximately) 70% of values will be between -1 and 1. Based on the values returned by nextGaussian(), you can scale and shift them to get other normal distributions:

    • to change the maen (average) of the distribution, add the required value;

    • to change the standard deviation, multiply the value.

    Examples: to generate values with an average of 500 and a standard deviation of 100:

    double val = r.nextGaussian() * 100 + 500;
    

    to generate values with an average of 30.5 and a standard deviation of 2.5:

    double val = r.nextGaussian() * 2.5 + 30.5;
    

    with this 70% of values will be between 28 and 33. As 99.7% of the values lie in the 3-sigma range the height of the monkeys is between 24 and 36.