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.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.
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.
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;
If the set of unique values is small, consider permuting the set of unique values e.g. 0..n, and permuting/shuffling them, then just dealing them in order (without reshuffling), as you would to generate a card hand.
To compute a geometric distribution where n is the number you get from nextDouble.
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.
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.
Specifically, like all LCGs (Linear Congruential random number Generators) that use a power of two for the modulus, the lower-order bits of the generated sequence have a much shorter period than the sequence as a whole. Fortunately, this limitation is mitigated in the implementation of nextInt( int n ), which uses the high-order bits when n is a power of two.
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:
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.
// picking a random enum static Random wheel = new Random(); ... // Fruit is an enum, possibleFruits an array of all possible Fruit constants Fruit[] possibleFruits = Fruit.values(); // pick is a randomly selected enum constant Fruit pick = possibleFruits[ Wheel.nextInt( possibleFruits.length ) ];
![]() |
recommend book⇒Art of Computer Programming | |
| hardcover | ||
|---|---|---|
| ISBN13: | 978-0-201-48541-7 | |
| publisher: | Addison-Wesley | |
| published: | 1998-10-15 | |
| by: | Donald Knuth | |
| volumes 1, 2 and 3. | ||
| You can get the freshest copy of this page from: | or possibly from your local J: drive (Java virtual drive/mindprod.com website mirror) | |
| http://mindprod.com/jgloss/pseudorandom.html | J:\mindprod\jgloss\pseudorandom.html | |
![]() | ||
| Canadian Mind Products | ||
| mindprod.com IP:[65.110.21.43] | ||
| view Blog | Your face IP:[38.107.191.107] | |
| Feedback | You are visitor number 45,838. | |