Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Random class acting odd?

Tags:

java

random

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?

like image 535
tckmn Avatar asked Nov 05 '12 23:11

tckmn


4 Answers

Let it print a couple more, the first 100 are

1 1 1 1 1 1 1 1 1 1 3 4 7 2 2 6 0 3 0 2 8 4 1 6 0 0 0 2 8 2 9 8 9 2 5 2 1 1 4 5 3 4 1 4 1
8 7 6 6 0 6 5 0 4 5 5 6 0 8 3 8 9 7 4 0 9 9 7 7 9 3 9 6 4 5 0 6 3 7 4 9 8 7 6 2 8 9 8 4 4
8 4 9 0 1 6 9 6 1 5

which looks okay.

Every good (pseudo) random sequence contains streaks of repeated numbers, this one begins with one.

like image 104
Daniel Fischer Avatar answered Nov 17 '22 06:11

Daniel Fischer


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.

like image 30
Xion Avatar answered Nov 17 '22 05:11

Xion


There's nothing to say that a sequence of 10 1s in a row is not possible. Whoever gave you the seed value 441287210 just happens to have found such a value that results in starting with 10 1s in a row. If you continue calling nextInt() (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.

like image 5
Jim Garrison Avatar answered Nov 17 '22 06:11

Jim Garrison


Random is a linear congruential generator; i.e. it is based on a formula of the form:

N <- (N * C1 + C2) % M

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 a random number generator. It is a pseudo-random number generator. That means that if you know the initial state, the numbers generated are entirely predictable.
  • Using a true random seed for Random doesn't really help. It just makes the problem harder to reproduce.
  • There are likely to be other seeds for Random that will give you similar patterns with this particular test.
  • From a purely mathematical standpoint, ten ones is no more or less "random" than any other sequence of ten numbers. But from a mathematical perspective, Random is not random at all. In fact, it is totally predictable once you have figured out what the current value of N is. The problem is the auto-correlation that is making the sequence appear intuitively non-random.
  • If you want to avoid this kind of intuitive non-randomness, use SecureRandom which should either be a true random number source, or a generator of pseudo-random numbers that are much, much harder to predict.
like image 3
Stephen C Avatar answered Nov 17 '22 05:11

Stephen C