Math#random ain't so random?

It is neither Java Math.rand() nor pseudo random generation problem. This is causing the weird (but expected) behaviour:

Math.random() - Math.random()

The sum (and subtraction) of two uniformly distributed random variables do not result in uniformly distributed variable. As far as I remember they result in triangular distribution:

triangular distribution

See: Distribution of mean of two standard uniform variables.

This is what you are seeing - a perfect illustration of 2-dimensional random variable with triangular distribution. Moreover, if you keep adding uniformly distributed random variables you will eventually get normal distribution.

To achieve uniform distribution all you have to do is replace awkward:

int x = center.x
                - (int) ((Math.random() - Math.random())
                        * Math.random() * center.x);

with simple:

int x = (int) (Math.random() * center.x * 2);

Your code (without multiplication) generates random variable with possible values from 0 to center.x * 2 and with expected value at center.x. So far so good. But the distribution is trangular which means the probability density is not equal in that range.

Multiplication of two random variables (out of which one is no longer uniformly distributed) has even more complex distribution, but certainly not uniform.

The latter code snippet generates a simple, uniformly distributed variables with probability density function equal in the whole space.

Side note

In your program it is an obvious math mistake, but pseudo-random generator can in fact generate "non-random" patterns in space. Have a look at Strange Attractors and TCP/IP Sequence Number Analysis, image from that article:

3d-space
(source: coredump.cx)


Instead of using Math.random(), use java.util.Random. First, seed the random generator with the current time:

Random randGenerator = new java.util.Random(System.currentTimeMillis());

then generate one random after another.

randGenerator.nextDouble();

Tags:

Java

Math

Random