Random Number Generators

Summary

Random Generators are a collection of PRNGs (pseudo-random number generators) above and beyond the default .NET random generator. At present, this collection includes:

  • Interface: an IRandomGenerator interface, so you can swap random generators for different ones in the future without having to refactor
  • Uniform Distribution Generator: An implemention of Mersenne Twister as a standard uniform distribution generator. It has several benefits over the built-in .NET random generator.
  • Normal Distribution Generator: Generates a random number in a given range, with the distribution being a bell-shaped normal distribution curve.

Download

Benefits of Using Random Number Generators

Mersenne Twister is a known, efficient and high-period random number generator. While that might not matter, the code is fast and free, and provides a better out-of-the-box standard uniform distribution.

Additionally, there’s no obvious, free normally-distributed random number generator available, certainly nothing that lets you limit the range of numbers; until now. Our normal distribution is statistically correct; it generates 67-69% of numbers within the first standard deviation, 94-96% within th second standard deviation, and 99%+ within the third standard deviation.

Drawbacks

At present, many of the standard methods (eg. NextDouble) are not available; if someone needs them, we can implement them in a future release.

Sample Code

The code below generates ten numbers between 0 and 100 using a normal distribution, and ten under a uniform distribution..


using CSharpCity.Tools.RandomNumberGenerators;

// Sample initialization code
UniformRandomGenerator r= new UniformRandomGenerator();
for (int i = 0; i < 10; i++) {
  Console.Writeline(i + "th uniform number: " + r.Next(100));
}

NormalRandomGenerator n= new NormalRandomGenerator(0, 100); // range specified here
for (int i = 0; i < 10; i++) {
  Console.Writeline(i + "th normal number: " + n.Next());
}

Technical Design

I can’t take credit for the Mersenne Twister code, since I didn’t write it; I merely wrapped it and provided an implementation of the IRandomGenerator interface. It’s fast, space-efficient, and it works.

For the normal distribution, we use the standard formula to generate the probability of a number occurring, for every integer in the range of integers specified; then we pick one at random, and use the weighted probability to determine which number comes out. Easy.

Future Development

We may include more functions on our random number generators like GetDouble(), and we may include more distributions, like a Guassian or Poisson.

12 Responses to Random Number Generators

  1. Emmanuel Olowosulu says:

    This is great!
    Keep up the good work.

  2. Ashiq Alibhai, PMP says:

    @Emmanuel thanks!

  3. Tyler says:

    When I ran the code from the binary to generate a normal distribution and I got a KeyNotFound exception. I looked at the source and I believe it is because in the NormalRandomGenerator constructor you assume that the min is always zero. While it is true you can calculate from zero then add, there is a simple fix:
    In this block:
    for (int i = min; i 0) //Change this to i > min
    ….
    }
    Seems like it works from there.

  4. Tyler says:

    Weird, the previous comment got kind of messed up, I think it interprets less-than as the start of an html tag.
    Just change the “if i greater than zero” to “if i greater than min” in the constructor.

  5. Ashiq Alibhai, PMP says:

    @Tyler do you have a JUnit test case you can pass down to me so I can reproduce this locally?

  6. Ashiq Alibhai, PMP says:

    @Tyler sorry, I don’t know what the problem is.

  7. Richard Williams says:

    I think what Tyler is getting at is that if you define a normal distribution with a min value greater than 0 – i.e. NormalRandomGenerator n= new NormalRandomGenerator(20, 100). Then line 49 in NormalRandomGenerator.cs fails, because the if statement on line 45 should be “greater than min”, rather than “greater than 0″. Hope that helps.

  8. Richard Lott says:

    This is great, thanks. I have a question though….

    After a bit of experimentation the Normal distrubution doesn’t seem to work properly when min is less than 0 (e.g. NormalRandomGenerator(-100,100)). I can get around this by using 0-200 and subtracting 100, but a fix would be good.

  9. Ashiq Alibhai, PMP says:

    Thanks Tyler, Richard, and Richard for your comments — I have now updated the library so that it can accept negative numbers in its range. It wasn’t quite as simple as I had hoped, but now it works. Enjoy!

  10. Franklin Ross says:

    Hey, thanks for providing this, I haven’t found so many good examples like this.

    Just wondering whether it’s necessary to implement “int Next()” in terms of “double NextDouble()”, as int to double conversions (and visa-versa) can be very slow on some hardware, including recent PC hardware, although I’m not particularly up to date on the latest CPUs at the moment.

    I can’t say I understand the algorithm, or random number generation enough in general to make the change myself.

  11. Vi says:

    Why this function doesn’t have mu and sigma parameters like it usually needs?

  12. Ashiq Alibhai, PMP says:

    Hi Vi,

    The intention behind this library is that a developer who already uses the normal random number generators wants to quickly swap in a different type (eg. normal random number generator) without changing all their code.

    For this reason, I decided to match the Random class more closely, instead of modelling after the mathematical model (with mu and sigma).

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>