views:

163

answers:

4

I'm math challenged today :(

I want to generate random numbers with a range (n to m, eg 100 to 150), but instead of purely random I want the results to be based on the normal distribution.

By this I mean that in general I want the numbers "clustered" around 125.

I've found this random number package that seems to have a lot of what I need: http://beta.codeproject.com/KB/recipes/Random.aspx

It supports a variety of random generators (include mersiene twister) and can apply the generator to a distribution.

But I'm confused... if I use a normal distribution generator the random numbers are from roughly -6 to +8 (apparently the true range is float.min to float.max).

How do a scale that to my required range?

+3  A: 

A standard normal distribution has mean 0 and standard deviation of 1; if you want to make a distribution with mean m and deviation s, simply multiply by s and then add m. Since the normal distribution is theoretically infinite, you can't have a hard cap on your range e.g. (100 to 150) without explicitly rejecting numbers that fall outside of it, but with an appropriate choice of deviation you can be assured that (e.g.) 99% of your numbers will be within the range.

About 99.7% of a population is within +/- 3 standard deviations, so if you pick yours to be about (25/3), it should work well.

So you want something like: (normal * 8.333) + 125

tzaman
Thanks... this makes much sense :)
ConfusedAgain
You're welcome. :)
tzaman
A: 

This may be too simplistic for your needs, but a quick & cheap way to get a random number with a distribution that's weighted toward the center is to simply add 2 (or more) random numbers.

Think of when you roll two 6-sided dice and add them. The sum is most often 7, then 6 and 8, then 5 and 9, etc. and only rarely 2 or 12.

dkamins
Central Limit Theorem means that adding uniforms will approximate a normal distribution, but it's hackish, and hard to keep track of the variance.
tzaman
It also requires taking an arbitrarily large number of samples for a given approximation to a normal distribution.
Will Vousden
+1  A: 

tzaman's answer is correct, but when using the library you linked there is a simpler way than performing the calculation yourself: The NormalDistribution object has writable properties Mu (meaning the mean) and Sigma (standard deviation). So going by tzaman's numbers, set Mu to 125 and Sigma to 8.333.

interjay
Of course, setting those directly would be more convenient. :) +1
tzaman
+2  A: 

For the sake of interest, it's pretty straightforward to generate a normal distribution from a uniform distribution (though it requires two samples):

Random generator = new Random();
double u1 = generator.NextDouble();
double u2 = generator.NextDouble();
double normal = Math.Sqrt(-2 * Math.Log(u1)) * Math.Cos(2 * Math.PI * u2);

You can then scale and translate this as necessary to get the range you want (as interjay explains).

Will Vousden