In this code:
Random random = new Random(441287210);
for(int i=0;i<10;i++)
System.out.print(random.nextInt(10)+" ");
}
The output is 1 1 1 1 1 1 1 1 1 1
, every time.
Why is this? Isn't Random
supposed to be... well... random? I thought that the Random
class use System.nanoTime
, so the output should be generally random. Can someone please explain?
Random is a linear congruential generator; i.e. it is based on a formula of the form:
where C1, C2 and M are constants.
One of the properties of this class of generator is that has high auto-correlation. Indeed, if you plot successive numbers you can see clear stripping patterns in the numbers.
Your test program has effectively taken 10 successive numbers from the underlying generator, calculated their value modulo 10 ... and found that they are all the same. Effectively, the modulo 10 is "resonating" with the natural periodicity of the generator ... over a short period of time.
This is one of the downsides of using a PRNG with high auto-correlation. In layman's terms ... it is "not very random" ... and you can get into trouble if you use it in a situation where randomness is critical.
Notes:
Random
is not random at all. In fact, it is totally predictable once you have figured out what the current value ofN
is. The problem is the auto-correlation that is making the sequence appear intuitively non-random.There's nothing to say that a sequence of 10
1
s in a row is not possible. Whoever gave you the seed value441287210
just happens to have found such a value that results in starting with 101
s in a row. If you continue callingnextInt()
(i.e. more than 10 times) you will see random values. It should be possible to find other seed values that will result in other "apparently non-random" sequences.If you use
for(int i=0;i<100;i++)
, the sequence outputted is "more random" again. The probability of a random sequence of ten1
s in succession occuring might be small, but it's not impossible. (Insofar that given enough samples, any sequence is almost certain to occur.)It's merely an interesting coincidence.
Random class uses seed to generate random number when you call nextInt() and is advised to be a long number, when you are creating random object, you are providing an int which is not sufficient enough for randomness.
Try to run the loop for 20 times, you will see randomness or remove seed or provide a very long seed value
The values generated by
Random
class are pseudo-random: they are created using a deterministic algorithm, based on seed value. Typically (if you use parameterless constructor, for example) the seed is initialized using current time, which is obviously a unique value. Hence a unique, 'random' sequence is generated.Here you are using a constant seed value which doesn't change between executions of your code. Therefore you always get the same sequence. It just happens that this sequence is
1 1 1 1 1 1 ...
for this particular seed.Let it print a couple more, the first 100 are
which looks okay.
Every good (pseudo) random sequence contains streaks of repeated numbers, this one begins with one.