1. 程式人生 > >關於Random(47)與randon.nextInt(100)的區別

關於Random(47)與randon.nextInt(100)的區別

stat 一次循環 隨機種子 隨著 target 沒有 strong 實用 一起

參考https://blog.csdn.net/md_shmily92/article/details/44059313

Java中Random也稱為偽隨機函數。

這句代碼在Thinking in java中很常見

Java代碼
  1. Random rand = new Random(47);

但是下面兩句代碼放在一起就會有點暈了

Java代碼
  1. Random rand = new Random(47);
  2. int i = rand.nextInt(100); //產生的隨機數 不包括100,最大到99,

生成的隨機數範圍到底是什麽,是0-47還是0-100,跟47和100又有什麽關系。
下面Random()方法做一些簡單說明吧。


偽隨機數
對於隨機數,大家都知道,計算機不可能產生完全隨機的數字,所謂的隨機數發生器都是通過一定的算法對事先選定的隨機種子做復雜的運算,用產生的結果來近似的模擬完全隨機數,這種隨機數被稱作偽隨機數。偽隨機數是以相同的概率從一組有限的數字中選取的。所選數字並不具有完全的隨機性,但是從實用的角度而言,其隨機程度已足夠了。偽隨機數的選擇是從隨機種子開始的,所以為了保證每次得到的偽隨機數都足夠地“隨機”,隨機種子的選擇就顯得非常重要。如果隨機種子一樣,那麽同一個隨機數發生器產生的隨機數也會一樣。
一般地,我們使用同系統時間有關的參數作為隨機種子。

Random對象的生成
Random類包含兩個構造方法,下面依次進行介紹:
(1)public Random()
該構造方法使用一個和當前系統時間對應的相對時間有關的數字作為種子數,然後使用這個種子數構造Random對象。

Java代碼
  1. public Random() { this(++seedUniquifier + System.nanoTime()); }
  2. private static volatile long seedUniquifier = 8682522807148012L;

(2)public Random(long seed)
該構造方法可以通過制定一個種子數進行創建。

Java代碼
  1. Random r = new Random(10);

切記,種子數只是隨機算法的起源數字,和生成的隨機數字的區間無關!

隨機種子對結果的影響
(1)隨機種子一定,隨機數範圍一定,則單個對象單次運行的結果一定
選取隨機種子為47,隨機數最大值為19.
下面代碼運行10次的結果總是為18.


Java代碼
  1. public static void main(String[] args) {
  2. for (int i = 0; i < 10; i++) {
  3. Random rand = new Random(47);
  4. int j = rand.nextInt(20);
  5. System.out.println(j);
  6. }
  7. }

(2)隨機種子一定,隨機數範圍一定,則多個對象單次運行的結果一定
用相同的隨機種子和隨機範圍生成了兩個Random對象,但j和k的值每次都為18

Java代碼
  1. public static void main(String[] args) {
  2. for (int i = 0; i < 10; i++) {
  3. Random rand1 = new Random(47);
  4. Random rand2 = new Random(47);
  5. int j = rand1.nextInt(20);
  6. int k = rand2.nextInt(20);
  7. System.out.println(j);
  8. System.out.println(k);
  9. }
  10. }

(3)隨機種子一定,隨機數範圍一定,但對象連續調用,運行結果不同
在下面的代碼中一次循環內,rand對象被連續調用了3次,分別輸出了18,15,13.
但每次循環的結果都一樣,18,15,13會被順序循環輸出。
也就是說同一個Random對象在隨機種子和隨著範圍一定的情況下,連續調用的次數不同會生成不同的隨機數。

Java代碼
  1. public static void main(String[] args) {
  2. for (int i = 0; i < 10; i++) {
  3. Random rand = new Random(47);
  4. int j = rand.nextInt(20);
  5. int k = rand.nextInt(20);
  6. int p = rand.nextInt(20);
  7. System.out.println(j);
  8. System.out.println(k);
  9. System.out.println(p);
  10. }
  11. }

產生特定區間的隨機值

如產生5-26之間的隨機值,為rand.nextInt(26-5+1)+5;

總結
最後結合API中的說明,再簡要總結寫Random()方法的功能:
(1)java.util.Random類中實現的隨機算法是偽隨機,也就是有規則的隨機,所謂有規則的就是在給定種(seed)的區間內隨機生成數字;
(2)相同種子數的Random對象,相同次數生成的隨機數字是完全相同的;
(3)Random類中各方法生成的隨機數字都是均勻分布的,也就是說區間內部的數字生成的幾率均等;

(4) 47是一個產生隨機數的魔法數字,這個問題到現在都沒人能夠解釋,只是經過很多次試驗得到的,包括《Thinking in java》的作者布魯斯.艾克爾也這麽提到:由47做種後,產生的隨機數更加體現了隨機性。它沒有什麽具體的意義,只要理解隨機數如果有一個種子,哪麽出現了比較隨即的隨機數,而當種子是47的時候,隨即率是最大的。

關於Random(47)與randon.nextInt(100)的區別