I know if i use the Random generator from Java, generating numbers with nextInt, the numbers will be uniformly distributed. But what happens if I use 2 instances of Random, generating numbers with the both Random classes. The numbers will be uniformly distributed or not?
Standard uniform generates a random number x from any continuous distribution with the specified cumulative distribution function F.
Uniformly then means that you sample from the uniform distribution, i.e., you sample it from a set where drawing each element is equally probable. Let us assume you have a set of 4 elements, then sampling uniformly at random from this set, every element is drawn with probability 1/4.
X = rand returns a random scalar drawn from the uniform distribution in the interval (0,1). X = rand( n ) returns an n -by- n matrix of uniformly distributed random numbers.
The numbers generated by each Random
instance will be uniformly distributed, so if you combine the sequences of random numbers generated by both Random
instances, they should be uniformly distributed too.
Note that even if the resulting distribution is uniform, you might want to pay attention to the seeds to avoid correlation between the output of the two generators. If you use the default no-arg constructor, the seeds should already be different. From the source code of java.util.Random
:
private static volatile long seedUniquifier = 8682522807148012L;
public Random() { this(++seedUniquifier + System.nanoTime()); }
If you are setting the seed explicitly (by using the Random(long seed)
constructor, or calling setSeed(long seed)
), you'll need to take care of this yourself. One possible approach is to use a random number generator to produce the seeds for all other generators.
Well, if you seed both Random
instances with the same value, you will definitely not get quality discrete uniform distribution. Consider the most basic case, which literally prints the exact same number twice (doesn't get much less random than that ...):
public class RngTest2 {
public static void main(String[] args) throws Exception {
long currentTime = System.currentTimeMillis();
Random r1 = new Random(currentTime);
Random r2 = new Random(currentTime);
System.out.println(r1.nextInt());
System.out.println(r2.nextInt());
}
}
But that's just a single iteration. What happens if we start cranking up the sample size?
Here is a scatter plot of a distribution from running two same-seeded RNGs side-by-side to generate 2000 numbers total:
And here is a distribution of running a single RNG to generate 2000 numbers total:
It seems pretty clear which approach produced higher quality discrete uniform distribution over this finite set.
Now almost everyone knows that seeding two RNGs with the same seed is a bad idea if you're looking for high quality randomness. But this case does make you stop and think: we have created a scenario where each RNG is independently emitting fairly high quality randomness, but when their output is combined it is notably lower in quality (less discrete.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With