pseudo-random numbers : Java Glossary
home P words local find no local find frame, full screen Google search web for topic jump to footer translate with Babelfish 2008-02-21 by Roedy Green ©1996-2008 Canadian Mind Products
Go to : punctuation 0-9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z (all)
pseudo-random numbers
There are two kinds of random numbers, pseudo-random numbers that can be rapidly generated from mathematical formulae, and true random numbers, generated from some random physical process such as radioactive decay. We are discussing pseudo-random numbers here.
int Playing Cards
Seeding Math.Random
JDK 1.1 SecureRandom
low and high bounds Bad Code
boolean UUID
double Random Daily Quotation
Random Strings Books
Gaussian Learning More
Distributions Links
Unique

Random.nextInt(int)

The pseudo random number generator built into Java is portable and repeatable. If two Random objects are created with the same seed and the same sequence of method calls is made for each, they will generate and return identical sequences of numbers in all Java implementations.

I have seen dozens of routines posted on the Internet for generating uniformly distributed random numbers. Almost none of them worked. If you want 100 evenly distributed random integers 0..10 you would use JDK 1.2+s Random.nextInt(int) to generate them:

Note, nextInt generates numbers 0 .. n-1, not 0 .. n.

Seeding

Seed the random number generator only once. If you keep restarting it (by doing new Random() more than once) using the system time default or some chosen seed, your numbers are not going to be very random. Since the clock does not tick over all that fast you may even create generators with identical default seeds, which then generate identical streams of numbers.

Don’t use two different generators with a null seed. The default seed is based on time of day and thus the two generators will then usually give identical streams of numbers.

To create a repeatable sequence seed with a constant, e.g. 149L. That will let you for example generate the exact same fake data for a benchmark over and over, or debug something that behaves predictable.

The best way to stay out of trouble in to use new Random only once a program in a static init.

Random in the old JDK 1.1

If you have JDK 1.1, which does not support nextInt(int), you can extend the Random class with the following code for nextInt stolen from JDK 1.2. Random.next(bits) that cleverly selects the high order bits of the seed, which are more random. When n is a power of two, this code selects the high order bits of 31 selected bits. When n is not a power of two, it uses the less random low order bits.

Random between low and high bounds

To get an evenly distributed random number between integers low and high inclusive use:
import java.util.Random;
// ...
static Random wheel = new Random();
//...
// generate an int in range low..high inclusive.
int m = wheel.nextInt( high - low + 1 ) + low;
Be aware that Random.nextInt( n ) gives a number between 0 and n-1 inclusive, not 0 to n. Random.nextDouble() returns a number between 0.0 inclusive and 1.0 exclusive.

Random.nextBoolean

To simulate throwing a coin, generating a boolean, use Random.nextBoolean. If you are using JDK 1.1 which does not support nextBoolean, you can use the following code which bypasses the sticky low-bit problem with nextInt(). You can avoid the sticky low order bits by picking a bit out of the middle of the result this way:
import java.util.Random;
// ...
static Random wheel = new Random();
// ...
// generating a boolean without nextBoolean to avoid the sticky bit problem.
boolean heads = ( wheel.nextInt() & (1 << 15) ) != 0;

Random.nextDouble

If you wanted a random double between 0.0 and 10.0 here is how you would generate it.

Random Strings

Sometimes you want a random String to use as an almost unique identifier. You could use code like this:
But what about collisions? How likely are you to run into problems with uniqueness? In most cases it is highly unlikely you will get duplicates even though Sun’s generator generates many more collisions than a theoretically perfect true random number generator. Internally Sun’s nextLong uses only a 32-bit generator and it does not cycle through all possible 32-bit patterns. I have written code to compute the theoretical possibility of a collision with a perfect true number generator, and a simulator that exercises Sun’s generator and tracks how well it performs. Here is the code:

Normal Gaussian Distribution

If you want your random numbers to lie on a bell shaped normal curve, use java.util.Random. nextGaussian, which produces numbers with mean 0.0 and standard deviation 1.0.

Exotic Distributions

If you want more exotic distributions, e.g. Poisson, Skewed Gamma or Lognormal have a look at the source code for java.util.Random. nextGaussian and use the same technique to warp the nextDouble uniform distribution, or read Donald Knuth’s Art Of Computer Programming which is the reference works for standard algorithms. In particular you want volume 2, Seminumerical Algorithms. If you just want to play around, have a look how java.util. nextGaussian works. You can warp the output n of nextGaussian to have a different mean μ and a different standard deviation σ with a simple formula:
n′ = ( n * σ ) + μ;

To compute a geometric distribution where n is the number you get from nextDouble.

n′ = ceil(ln n / ln (1 - p));
Precompute ln ( 1 - p ); Use Java’s Math.log to compute ln — the natural logarithm.

The basic idea is you take some function of nextDouble after suitably scaling its range 0..1 e.g. sqrt or exp. Then you scale the result back into the range 0..1. Different functions will do different warpings.

For serious work, you will have to consult a probability and statistics text to see what the various distributions look like to simulate various natural processes. To get a distribution that fits some shape, you can try differentiating the shape either analytically or numerically, then inverting the function, exchanging the roles of x and y. Use that function to warp your outputs from nextDouble. To see what I mean, draw graphs of the various functions. You can see that flat areas of your warping curve tend to accumulate more random hits, and sharp inclines and declines do not.

Unique Random Numbers

What if you need unique random integers? Generate them in the ordinary way with nextInt(int). Tick them off as used in a java.util.BitSet. Discard any that are already in use. If that BitSet would be too huge and you only need to generate a few random numbers, wrap them in Integers and store them in a HashSet.

Playing Card Hands

When you are trying to simulate playing card hands, you can create an ArrayList of Integers 0 .. n-1, (or Card objects) and use Collections.shuffle. Then just peel the cards off the bottom or top of the ArrayList.

Math.Random

Math.Random is an alternate method to create random doubles that does not require you to create a Random object, but it does not give you control over the seed and has no nextInt(int) or nextBoolean . Other than that, it has the same shortcomings as java.util.Random.

SecureRandom

If you need very high quality random numbers for cryptography, see java.security. SecureRandom. Since it is derived from java.util.Random, it works much the same way. The main difference is the way you construct the wheel:
import java.security.SecureRandom;
// ...
// generate cryptographic quality (but still not true random) numbers.
static SecureRandom wheel = SecureRandom.getInstance ( "SHA1PRNG" , "SUN" );
// ...
// generate 100 ints 0..9
for ( int i=0; i<100; i++ )
 {
  System.out.println( wheel.nextInt( 10 ) );
 }
Unfortunately, early versions of Netscape do not include any of the java.security classes. For ordinary use, use java.util.Random.

For a faster, higher quality random number generator try the Mersenne Twister.Java source and other languges are available. SecureRandom is extremely slow under Linux. If you need any quantity of high quality random numbers you will have to look outside the core Java classes.

Random Number Code to Avoid

Unfortunately, even if you do everything perfectly to use java.util.Random, the generator itself is flawed. It falls into the trap Knuth says to avoid — using a power of two for the modulus. The random numbers it generates are not all that random. It is blindingly obvious when you plot the low order bits of the random numbers visually.

Knuth gave me permission to translate his definitive random number generators into Java. Now all I need in the time and energy to tackle the task.

Using nextInt(int) for generating random integers is faster than using nextDouble, multiplying and converting to int as many authors suggest. In solving problems of this sort, you must be mindful that nextInt() (no parameter) returns a positive or negative integer, including MIN_VALUE (whose absolute value cannot be represented) and MAX_VALUE, and that Java division/modulus has unexpected results for negative operands. You must also be careful to maintain even distribution. Consider the following code that also produces a random integer in the range 0 .. 10.

// bad way to generate random ints
import java.util.Random;
// ...
static Random wheel = new Random();
// ...
int m = wheel.nextInt() % 6 + 5; // not recommended!!
However, that code would generate 5 twice as frequently as the other values.

The following paragraph is controversial. Two experts disagreed on it. I have not taken the time to research it. In any case nextInt is faster than use nextDouble.

nextDouble() can return a 0.0, but never a 1.0. However, if you want a random number in the interval [0, N), taking the result returned by nextDouble() and multiplying by N will not always work; for some values of N, the final result can be N (the high bound). nextDouble() works by taking 53 random bits divided by (double) (1 << 53). So, the closest it can get to 1.0 is 0.99999999999999988897. When you multiply by a sufficiently large number, the tiny difference from 1.0 gets lost, and the result is the same as if you had started with 1.0 not a number just less than 1.0. According to Merlin Hughes, any number that the generator produces will occur 32 times more commonly than for a perfect distribution; 31 of every 32 numbers just won’t ever be produced.

About every four days someone will post the following code as a way to generate a random integer 0 .. 10:

// bad way to generate random ints
import java.util.Random;
// ...
static Random wheel = new Random();
// ...
int m = (int)( Math.random() * 10.0d ); // not recommended!!
There are four things wrong with the technique:
  1. It will generate a number 0 to 9, not 0 to 10.
  2. However the technique in general may once in a blue moon generate "10". It won’t actually do this with 10, but it will hit the upper bound with larger ranges, so I think it wise a avoid the technique on general principles.
  3. It requires two int <=> double floating point conversions and a floating point multiply. These are slow operations, and completely unnecessary.
  4. Math.Random gives you no power over the seed. It is hard to debug if your program behaves a totally different way every time you run it.

The Java random number generator does very poorly at generating the low order bit. It tends to repeat itself every 128 times you call nextInt(). It tends to get stuck for long runs of 0s or 1s, if you look only at every 128th result. In other words it is somewhat predictable. Bit 1 tends to repeat on a 256 cycle. The following code to generate simulate a heads or tail coin flip will thus not work very well.

// bad way to generate booleans
import java.util.Random;
// ...
static Random wheel = new Random();
// ...
boolean heads = ( wheel.nextInt() & 1 ) != 0; // not recommended!!

The following code works quickly to generate a random number between 0 and n, but the technique skews the results for large values of n, returning small numbers more frequently than it should. Instead use the nextInt(int) technique given above.

Random Daily Quotation

What if you want a “random” daily quotation to display on a web page chosen from a set of candidates, but you want the choice to remain stable for a day, even if you recompute the choice. Here is how you could do that, without using java.util. Random at all.
I use code similar to the above to use static macros to create such automatically changing quotations on pages such as the mindprod.com home page, The Java Glossary home page, The Computer Buyers’ Glossary home page, The Gay Glossary home page, The Environment page, The Politics page, The Religion page, The Ethics page, The Living Love page.

Books

book_cover recommend book⇒Art Of Computer Programming
 hardcover
ISBN13:978-0-201-48541-7
ISBN10:0-201-48541-9clickcounter
publisher:Addison-Wesley
published:1998-10-15
by:Donald Knuth
volumes 1, 2 and 3.
Canadian flag amazon.ca. amazon.com. American flag
Canadian flag chapters.indigo.ca . powells.com American flag
French flag amazon.fr. barnesandnoble.com American flag
German flag amazon.de. amazon.co.uk. UK flag

Learning More

Sun’s Javadoc on java.util.Random : available:
Sun’s Javadoc on the SecureRandom class : available:
Sun’s Javadoc on the UUID class : available:
combination
ISSAC: fast cryptographic random number generator
Mersenne Twister: theory
modulus
Orion Random Number Generator
permutation
shuffle
true random numbers
Uncommon Maths: a library of random number generators
unique numbers
UUID

CMP_homejump to top
CMP logo
feedback Please email your feedback for publication, errors, omissions, broken/redirected link reports
and suggestions to improve this page to Roedy Green : feedback email
made with CSS
HTML Checked!
ICRA ratings logo
mindprod.com IP:[65.110.21.43]
Your face IP:[38.103.63.16] Greenpeace energy [r]evolution
You are visitor number 28,477.
You can get a fresh copy of this page from: or possibly from your local J: drive (Java virtual drive/Mindprod website mirror)
http://mindprod.com/jgloss/pseudorandom.html J:\mindprod\jgloss\pseudorandom.html