GENERATING INTEGER RANDOM NUMBERS(幾種產生隨機數方法的效率分析) (轉)
GENERATING INTEGER RAN NUMBERS
There are many ways to generate random numbers with the base libraries found in the 2 SDK, Standard Edition. If you haven't kept up to date with changes to the libraries, you might be using an inefficient mechanism or, possibly worse, getting results that are not uniformly distributed. Here's a look at a good way to generate integer random numbers, and then a look at what's not so good about some other ways.
The java.util.Random
class has been available for generating random numbers since the initial release of the system libraries. Starting with the 1.2 release of the Java 2 SDK, Standard Edition, the Random class has a nextInt()
method that accepts an integer argument:
public int nextInt(int n)
Given some value n
, nextInt(n)
returns a value greater than or equal to zero but less then that value: 0 <= nextInt(n) < n
.
All you have to do is create a Random
first, then call nextInt(n)
to return the next random int value.
Here's a demonstration. The following code snippet generates a large set of random numbers and prints out the average:
int count = 1000000; int range = Integer.MAX_VALUE / 3 * 2; double sum = 0; Random rand = new Random(); for (int i=0; i After ling a million times, the average value should be approximately at the midpoint of the ed range. So far, that isn't too complicated, but what's special about using sum = 0; for (int i=0; i There are actually three problems with the latter approach. First, Second, when you mod Finally, and possibly worst of all, the results are not evenly distributed. If you execute the loops in the two approaches, the first loop will produce results above 715 million, with a midpoint of the range at 715,827,882. That is within an acceptable tolerance for randomness. Surprisingly, the results of the second loop are consistently less than 600,000,000. How can the second loop be so far off base? Essentially, the problem is that the map is unfair. When you use the mod Using the That leaves the sum = 0; for (int i=0; i Well, using this method at least doesn't have any of the problems of What is the problem, though, is that Because it avoids the problems inherent in using the other approaches, using the Here's a complete program you can use to test the different approaches discussed in this tip. 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; inextInt(n)
? Why is using nextInt(n)
better than (1) using the older nextInt()
method, with no range, then (2) using Math.abs()
to get the absolute value, and then (3) using the mod (%)
operator to get the value into the right range? The latter approach is demonstrated in the following code snippet. While there are a few extra operations in this approach, isn't it just as good as the first approach? nextInt()
is equally likely to return a value between Integer.MIN_VALUE
and Integer.MAX_VALUE
. If you take the absolute value of Integer.MIN_VALUE
, the result is not a positive number. In fact, the result of Math.abs(Integer.MIN_VALUE)
is Integer.MIN_VALUE
. So, on rare occasions, you'll get back a negative number. Given the rarity of the event, 1 out of 2^31
times, the likelihood of the event happening during testing, and being repeatable, is highly unlikely. (%)
the results of nextInt()
, you effectively reduce the randomness of the results. The low order bits of random numbers can repeat more regularly than the entire number. This is a known issue with pseudo-random number generators, and so it's another reason not to use mod (%)
. (%)
operator, you are taking values that are too large and squeezing them into the low end. This favors the lesser values. Compare this to rolling a single dwith three other friends. Because there are only four of you and six possible values, the mapping for the first four values is easy. Die value 1 is mapped to person 1, value 2 to person 2, and so on. Now what about the larger values, 5 and 6? If you take the same approach as the mod (%)
operator, you map the large values in such a way that any time a 5 is rolled, person 1 wins, and any time a 6 is rolled, person 2 wins. Is this fair? Well, that's what happens when you mod (%)
the results of nextInt()
. nextInt(range)
method solves all three of these problems. random()
method of the Math class as another possible way to generate random numbers. Using that method can't be that bad, can it? You just have to multiply the result by the range: nextInt()
. You can't get a negative number back, you are not using the mod (%)
operator so you don't run into the low-order byte range problem. And the range is uniform. Math.random()
uses floating point arithmetic, and both versions of nextInt()
work with only integer operations. Math.random()
can be up to four times slower because of its use of floating point operations. Throw in the cast, and the operation is even slower. nextInt(range)
method of Random is a better way to generate integer random numbers.
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-990706/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- ORACLE產生隨機數的多種方法分享 轉Oracle隨機
- 利用arc4random_uniform()產生隨機數randomORM隨機
- Random 專案總結 -11 產生隨機數字random隨機
- 幾種生成隨機數方法隨機
- 隨機數種子(random seed)隨機random
- 計算機隨機數的產生 (轉)計算機隨機
- 產生唯一隨機碼的方法分析隨機
- 關於如何產生隨機數的幾種方法彙總!(2018.07.08)隨機
- C 語言產生隨機數的方法隨機
- C語言產生隨機數的方法C語言隨機
- 一種快速可預製的隨機陣列產生方法(轉)隨機陣列
- JavaScript 隨機數方法 Math.random()JavaScript隨機random
- dbms_random包呼叫隨機數的方法:random隨機
- 【RANDOM】使用dbms_random.string產生隨機字串的用法及應用random隨機字串
- R產生隨機數隨機
- C# 生成隨機數,呼叫Random方法C#隨機random
- 【知識積累】隨機數生成的幾種方法隨機
- vc中產生隨機數隨機
- c++產生隨機數C++隨機
- 扒一扒隨機數(Random Number)的誕生歷史隨機random
- 隨機產生0-1之間實數的方法隨機
- Random獲取隨機數random隨機
- 高效產生不重複的隨機數隨機
- Java隨機數的幾種有趣用法Java隨機
- C# 隨機數 Random 的使用C#隨機random
- 【筆記】如何產生隨機數筆記隨機
- js隨機產生區間數JS隨機
- matlab產生隨機數或隨機矩陣Matlab隨機矩陣
- Python產生20個隨機整數的方法詳解!Python隨機
- C語言中產生真隨機數的方法,帶封裝C語言隨機封裝
- oracle隨機數 — dbms_randomOracle隨機random
- 如何產生指定範圍的隨機數隨機
- PHP生成隨機密碼的幾種方法PHP隨機密碼
- linux生產32位隨機數Linux隨機
- 高效產生一組不重複的隨機數隨機
- Python生成隨機數random模組Python隨機random
- AS使用Random函式建立隨機數random函式隨機
- 偽隨機數 pseudo random number隨機random