Populating multiple random number generators

I recently discussed the initialization of several random number generators of the same type in the comments of another post, and in this discussion we asked the following questions:

1) Is it good to create several instances of the same random number generator with different seeds and use these random number generators in different parts of the program?

2) In particular, can there be a problem of creating random number generators using the .Net Random class, seeded as shown below, and using each RNG in different program contexts:

int size = 64; // The number of RNGs to use int seed; // Get seed using some normal technique Random[] r = new Random[size]; for (int i = 0; i < size; i++) { r[i] = new Random(seed + i); } 

3) What would you recommend instead if multiple streams of random numbers are required?

4) How do you recommend generating random numbers if thread safety is required?

+6
source share
2 answers

1) Is it good to create several instances of the same random number generator with different seeds and use these random number generators in different parts of the program?

No. The above circuit is generally not recommended.

In his book, The Art of Programming, Volume 2: Seven-Dimensional Algorithms. Addison-Wesley, Reading, MA, Third Edition, 1997, Dr. Knut argues that

It’s not easy to come up with a reliable source of random numbers.

In this case, I point out that taking subsequences from a random sequence may be less random than the original sequence of random numbers:

Please note that the implementation of Micosoft Random is based on a lagging fibonacci generator:

This random number generator is known for its built-in three-point correlation, because we generate the following random number: Subtractive Fibonacci Delay Generator

These random number generators also rely heavily on the initialization of the initial state of the number 55. Poor initialization can lead to incorrect random numbers. In the above case, similar states can lead to correlated random numbers from each of the different random number generators. Microsoft even recommends against this in its MSDN post about System.Random: MSDN System.Random class and thread safety :

Instead of creating instances of individual random objects, we recommend creating one random instance to generate all the random numbers your application needs.

We will look at an example where a certain initialization creates a strong correlation between different random number generators and looks for alternatives.

2) I implemented a program that tries to initialize 64 instances of Random, as described above, so that we observe any visible flaws. I chose a specific initialization as a proof of concept:

 int size = 64; // The number of random numbers generators int length = 20; // The number of random numbers from each generator int steps = 18; // Move 18 steps forward in the beginning to show a particular phenomenon Random[] r = new Random[size]; for (int i = 0; i < size; i++) { r[i] = new Random(i + 1); // move RNG forward 18 steps for (int j = 0; j < steps; j++) { r[i].Next(3); } } for (int i = 0; i < size; i++) { for (int j = 0; j < length; j++) { Console.Write(r[i].Next(3) + ", "); // Generate a random number, 0 represents a small number, 1 a medium number and 2 a large number } Console.WriteLine(); } 

This program generates the output shown here, each line represents output from another RNG:

Program output

Note that the highlighted columns: in certain places seem to be synchronizing and generating output that does not look independent of each other.

I also want to add another note: creating a single list of random numbers and getting one random number from the list of each line also leads to bad looking random numbers (the RNG used here, as you know, does not give statistics after all!).

3) The type of RNG used depends on your context. Some of them may be pleased with the above output. In other cases, the RNG used may not be suitable (Monte Carlo simulation and cryptography are two scenarios in which System.Random should never be used even for a single stream of random numbers).

If you need to extract several subsequences of random numbers, find the RNG that was designed for this purpose:

4) Finally, what if I want to use System.Random in multiple threads? Microsoft MSDN has the answer in the same link that I mentioned above:

+11
source

Not sure what “multiple streams of random numbers” mean. In random numbers, there is no connection between any two random numbers, there is no order, each of which is an autonomous instance.

If you use cryptographic PRNG, no seeding is required. Consider the .net class RNGCryptoServiceProvider .

+1
source

All Articles