Random
There are many ways to generate random numbers using the Java 2 SDK base Class library. But if you can't keep up with the updates to these libraries, you might be using an inefficient random-number generation mechanism, and worse: You might not get random numbers that are evenly distributed. This article will show you a more reliable method of random number generation, while comparing it with other methods.
Since the JDK initial release, we can use the Java.util.Random class to generate random numbers. In JDK1.2, the random class has a method named Nextint ():
public int Nextint (int n)
Given a parameter N,nextint (n) returns a random number greater than or equal to 0 less than N, that is: 0 <= nextint (n) < N.
All you have to do is declare a random object and call its nextint (n) function to return the random value.
Here's an example where the following code snippet generates a lot of random numbers and outputs their averages:
int count = 1000000;
int range = INTEGER.MAX_VALUE/3 * 2;
Double sum = 0;
Random rand = new Random ();
for (int i=0; i
Sum + + rand.nextint (range);
}
System.out.println (Sum/count);
After 1 million cycles are executed, the resulting average is basically in the midpoint of the range of random numbers (midpoint).
So far, things are not complicated, but we will ask why we use Nextint (n)? The random number generation method to consider:
(1) using the old Method Nextint (), no numerical range is established
(2) using Math.Abs () static function to get (1) The absolute value of the resulting values
(3) The result of (2) is modulo operation (%), and the value of the desired range class is obtained.
We say Nextint (n) is better than the above method, why? Refer to the following code snippet:
sum = 0;
for (int i=0; i
Sum + + math.abs (rand.nextint ())% range;
}
System.out.println (Sum/count);
It is not difficult to find that each cycle has a few more steps. In fact, this method of random number generation has the following three problems:
First, the values returned by Nextint () tend to be evenly distributed between Integer.min_value and Integer.max_value. If you take the absolute value of the integer.min_value, the resulting number is still not a positive number. In fact, Math.Abs (integer.min_value) equals Integer.min_value. Therefore, there is such a situation (although rarely seen): Rand.nextint () =integer.min_value, after taking the absolute value Math.Abs (Rand.nextint ()), the result is a negative number. The odds are 1/(2^31), which is unlikely to happen in our tests--only 1 million cycles per second.
Second, when you take a nextint (), you discount the randomness of the results. Smaller values in random numbers are more likely to appear. This is known as pseudo random number generation, so we are not using modulo method.
Finally, it may be the worst: random numbers are not evenly distributed. If you execute the two paragraphs above, the result of the first code will be greater than 715,000,000, considering that the midpoint of the range of values (midpoint) is 715,827,882, so this is an acceptable result. However, you will be surprised to find that the second code will have an average of no more than 600,000,000.
Why is the result of the second code so biased? Correcting its essence, the problem lies in the uneven distribution of the numerical value. When you do the modulo operation, you convert the larger number to the smaller one. This makes the smaller numbers easier to produce.
Using Nextint (range) will solve the above three problems.
There is also a method for generating random numbers-using math.random (). What is the effect of this method?
sum = 0;
for (int i=0; i
sum + = (int) (Math.random () * range);
}
System.out.println (Sum/count);
Well, using random () won't run into Nextint () trouble. You don't get negative returns, you don't use modulo operations, and the values are evenly distributed. Do you have any questions? Have you considered that math.random () uses floating-point operations, while Nextint () and Nextint (range) are only integer operations? Math.random () may be four times times slower. Combined with type conversions from floating-point to integer, the entire operation will be slower.
Well, after a comparison, we find that using Nextint (range) to generate random numbers is more efficient because it avoids the drawbacks of other methods.
Finally, a section of code is given, which can be used to compare several random number generation methods mentioned in this paper.
Import java.util.*;
Import java.text.*;
public class Randomtest {
public static void Main (String args[]) {
NumberFormat NF = numberformat.getinstance ();
int count = 1000000;
int range = INTEGER.MAX_VALUE/3 * 2;
System.out.println ("Midpoint:" + Nf.format (RANGE/2));
Double sum = 0;
Random rand = new Random ();
for (int i=0; i
Sum + + rand.nextint (range);
}
System.out.println ("good:" + Nf.format (sum/count));
sum = 0;
for (int i=0; i
Sum + + math.abs (rand.nextint ())% range;
}
System.out.println ("bad:" + Nf.format (sum/count));
sum = 0;
for (int i=0; i
sum + = (int) (Math.random () * range);
}
System.out.println ("Longer:" + Nf.format (sum/count));
}
}