Is this a "good enough" random algorithm; why isn't it used if it's faster? Is this a "good enough" random algorithm; why isn't it used if it's faster? java java

Is this a "good enough" random algorithm; why isn't it used if it's faster?


Your QuickRandom implementation hasn't really an uniform distribution. The frequencies are generally higher at the lower values while Math.random() has a more uniform distribution. Here's a SSCCE which shows that:

package com.stackoverflow.q14491966;import java.util.Arrays;public class Test {    public static void main(String[] args) throws Exception {        QuickRandom qr = new QuickRandom();        int[] frequencies = new int[10];        for (int i = 0; i < 100000; i++) {            frequencies[(int) (qr.random() * 10)]++;        }        printDistribution("QR", frequencies);        frequencies = new int[10];        for (int i = 0; i < 100000; i++) {            frequencies[(int) (Math.random() * 10)]++;        }        printDistribution("MR", frequencies);    }    public static void printDistribution(String name, int[] frequencies) {        System.out.printf("%n%s distribution |8000     |9000     |10000    |11000    |12000%n", name);        for (int i = 0; i < 10; i++) {            char[] bar = "                                                  ".toCharArray(); // 50 chars.            Arrays.fill(bar, 0, Math.max(0, Math.min(50, frequencies[i] / 100 - 80)), '#');            System.out.printf("0.%dxxx: %6d  :%s%n", i, frequencies[i], new String(bar));        }    }}

The average result looks like this:

QR distribution |8000     |9000     |10000    |11000    |120000.0xxx:  11376  :#################################                 0.1xxx:  11178  :###############################                   0.2xxx:  11312  :#################################                 0.3xxx:  10809  :############################                      0.4xxx:  10242  :######################                            0.5xxx:   8860  :########                                          0.6xxx:   9004  :##########                                        0.7xxx:   8987  :#########                                         0.8xxx:   9075  :##########                                        0.9xxx:   9157  :###########                                       MR distribution |8000     |9000     |10000    |11000    |120000.0xxx:  10097  :####################                              0.1xxx:   9901  :###################                               0.2xxx:  10018  :####################                              0.3xxx:   9956  :###################                               0.4xxx:   9974  :###################                               0.5xxx:  10007  :####################                              0.6xxx:  10136  :#####################                             0.7xxx:   9937  :###################                               0.8xxx:  10029  :####################                              0.9xxx:   9945  :###################    

If you repeat the test, you'll see that the QR distribution varies heavily, depending on the initial seeds, while the MR distribution is stable. Sometimes it reaches the desired uniform distribution, but more than often it doesn't. Here's one of the more extreme examples, it's even beyond the borders of the graph:

QR distribution |8000     |9000     |10000    |11000    |120000.0xxx:  41788  :##################################################0.1xxx:  17495  :##################################################0.2xxx:  10285  :######################                            0.3xxx:   7273  :                                                  0.4xxx:   5643  :                                                  0.5xxx:   4608  :                                                  0.6xxx:   3907  :                                                  0.7xxx:   3350  :                                                  0.8xxx:   2999  :                                                  0.9xxx:   2652  :                                                  


What you are describing is a type of random generator called a linear congruential generator. The generator works as follows:

  • Start with a seed value and multiplier.
  • To generate a random number:
    • Multiply the seed by the multiplier.
    • Set the seed equal to this value.
    • Return this value.

This generator has many nice properties, but has significant problems as a good random source. The Wikipedia article linked above describes some of the strengths and weaknesses. In short, if you need good random values, this is probably not a very good approach.

Hope this helps!


Your random number function is poor, as it has too little internal state -- the number output by the function at any given step is entirely dependent on the previous number. For instance, if we assume that magicNumber is 2 (by way of example), then the sequence:

0.10 -> 0.20

is strongly mirrored by similar sequences:

0.09 -> 0.180.11 -> 0.22

In many cases, this will generate noticeable correlations in your game -- for instance, if you make successive calls to your function to generate X and Y coordinates for objects, the objects will form clear diagonal patterns.

Unless you have good reason to believe that the random number generator is slowing your application down (and this is VERY unlikely), there is no good reason to try and write your own.