Title: Produce a repeatable series of "random" numbers in C#
The Random class can generate a series of pseudo-random numbers. They're called "pseudo-random" rather than "random" because the numbers are generated by a mathematical algorithm rather than by some completely unpredictable process such as observing a source of radioactive decay or the static in radio waves. Given enough information about the algorithm used by the class and a Random object's current state, you could predict the next number (in fact all following numbers) in a sequence.
However, the Random class does produce numbers that look random enough for most applications. Currently the class uses Donald Knuth's subtractive random number generator algorithm described in his book The Art of Computer Programming, Volume 2: Seminumerical Algorithms, Addison-Wesley, 1981. Look it up for more details.
The obvious time when the Random class isn't "random enough" is in cryptography of important information. If you need to encrypt financial information, passwords, or other really sensitive information, use the cryptographic library instead of Random.
Generating pseudo-random numbers is often useful in programs, but sometimes it's useful to be able to generate the same pseudo-random set of numbers repeatedly. For example, suppose you want a demonstration program to display a graph of some pseudo-random data. If might look weird if it displayed a different graph every time you ran the program.
For another example, suppose you have a program that uses randomization techniques to look for a good solution of a hard problem such as the Traveling Salesperson Problem (TSP). Now suppose there's a bug in the program. It can be very hard to find this kind of bug because every time you run the program you get a different series of pseudo-random numbers so the bug may occur at a different place or not at all.
Fortunately it's easy to generate a repeatable series of pseudo-random numbers. Simply pass the Random class's constructor an integer seed value to use when initializing the pseudo-random number generating algorithm. If you omit this number, the object uses the system's time to initialize the generator, so if you run the program again later at a different time, you get a different sequence of numbers.
This brings up an important issue: If you create two Random objects at roughly the same time, the system's time may not have changed so you may end up with two objects initialized with the same seed value and therefore producing the same pseudo-random numbers. To avoid this, create a single Random object and then use it whenever you need to generate pseudo-random numbers.
This example uses the following code to add 100 pseudo-random numbers to a ListBox.
// Initialize the random number generator and generate some numbers.
private void GenerateNumbers(TextBox seed_textbox, ListBox lst)
{
// Get the seed.
int seed = int.Parse(seed_textbox.Text);
// Initialize the random number generator.
Random Rand = new Random(seed);
// Generate numbers.
lst.Items.Clear();
for (int i = 1; i < 100; i++)
{
lst.Items.Add(Rand.Next(0, 10000));
}
}
The code takes as parameters a TextBox holding a seed value and the ListBox where it should place the pseudo-random numbers. It parses the seed value and uses it to initialize a new Random object. It then clears the ListBox and uses the Random object to fill it with 100 pseudo-random numbers between 0 and 9999.
Run the program, enter seed values in the TextBox controls, and click the Generate buttons. If the two seed values are the same, the lists will show the same pseudo-random numbers. If the seed values are different, even by a tiny amount, the values will be very different.
Download the example to experiment with it and to see additional details.
|