2012-10-12 55 views
0

可能重複:
Java random always returns the same number when I set the seed?隨機數總是在同一順序

我使用的是Java的Random類和nextInt()方法獲取隨機數。但似乎這些數字總是以相同的順序排列。有沒有辦法來解決這個問題?我知道一些隨機生成器會獲得種子值,然後使用系統計時器來獲取種子。

代碼:

+0

你播種的隨機數發生器? –

+3

看起來像你不小心你的代碼。請張貼您目前正在生成它們的方式,因爲這將需要查看發生了什麼問題。 – Blumer

回答

0

這就是你真正需要參考的https://stackoverflow.com/a/11705615/1143977。從引用鏈接引用我的回答。

有兩個問題引起你所看到的。第一個是代碼爲Random實例設置種子值。第二個是實例方法「隨機」實例一個新的Random對象,然後每次立即使用相同的種子設置其種子。這兩個組合確保了對於i的相同值,「隨機」方法將始終返回相同的值,並且它始終是種子始終生成的序列中的第一個。

假設設置種子是強制性的,爲了獲得序列中的下一個值而不是每次序列的相同第一個值,Random的randnum實例不能每次都在其下一個方法之前設置其種子被調用。要解決這個問題,請將隨機實例方法範圍內的Random的randnum局部變量實例移至類作用域。其次,只有在隨機分配了一個隨機實例或者只是爲了從中得到相同的結果序列以重新開始時才設置種子。 Class Random的setSeed(long seed)實例方法不能在類作用域中執行,所以構造函數必須使用具有long種子參數的Random構造函數來設置它。下面的代碼演示了變化:

public class RandomDemo { // arbitrary example class name 
    // lots of class related stuff may be here... 

    // still inside the class scope... 
    // private is a good idea unless an external method needs to change it 
    private Random randnum = new Random(123456789L); 
    // the seed guarantees it will always produce the same sequence 
    // of pseudo-random values when the next methods get called 
    // for unpredicable sequences, use the following constructor instead: 
    // private Random randnum = new Random(); 

    // lots of code may be here... 

    // publicly exposed instance method for getting random number 
    // from a sequence determined by seed 123456789L 
    // in the range from 0 through i-1 
    public int randnum(int i) { 
     // don't set the seed in here, or randnum will return the exact same integer 
     // for the same value of i on every method call 
     // nextInt(i) will give the next value from randnum conforming to range i 
     return randnum.nextInt(i); 
    } // end randnum 

    // lots of more code may be here... 

} // end class RandDemo 

上述會給你一個確切的解決您的具體問題,如指出。然而,使用強制種子似乎是不尋常的,因爲它具有什麼功能。

下面解釋更多關於隨機,隨機的種子以及爲什麼有提供種子的規定。

隨機

具有兩個構造函數:

Random() 

Random(long seed) 

和實例方法

setSeed(long seed) 

所有影響從隨機實例獲得的數字序列。實例方法

setSeed(long seed) 

將Random對象設置爲與原構造函數實參相同的種子只會實例化的相同狀態。只有一個種子值的低階48位被使用。

如果Random對象的實例沒有種子,則種子將與系統時間相同,以毫秒爲單位。這確保了,除非兩個Random對象在同一毫秒內實例化,否則它們將產生不同的僞隨機序列。只有種子值的低位48位被使用。這導致不可預知的僞隨機序列。每次調用下一個方法時,都不需要浪費計算資源來獲取Random的新實例。

提供了Random的種子參數,以便人們可以實例化一個Random對象,該Random對象產生一個可重複的序列。對於給定的種子,無論何時使用種子,下一種方法中的值序列都保證是相同的序列。這對測試將使用僞隨機序列的軟件非常有用,因爲結果必須是可預測和可重複的。它在操作中創建不同的不可預測的僞隨機序列是沒有用的。

+1

如果您可以從另一個問題中剪切並粘貼答案,則應該將此問題標記爲重複。 (謝謝你引用源代碼!) – Sam

+0

做到了。謝謝。 – VendettaDroid

+0

感謝您花時間向我解釋隨機函數, –

0

這應該給你隨機數埃夫裏的時間:

Time t = new Time(); 
t.setToNow(); 
mRandom = new Random(t.toMillis(false)); 
int rand = mRandom.nextInt(10); 
+0

從[Random()](http://developer.android.com/reference/java/util/Random.html#Random%28%29)構造函數文檔:「初始狀態(即種子)是_partially_基於一天中的當前時間,以毫秒爲單位。「因此,根據當前時間將其設置爲_wholly_,似乎不那麼隨意。 – Sam

0

(在應用程序的onCreate爲例)創建Random對象只有一次,它應該每次給你相對隨機的結果你啓動應用程序。

0

要在Android中生成隨機數,可以使用java.util.Random類。

該類java.util.Random提供了生成不同類型的僞隨機數的方法,例如int,long,double和float。

它支持兩個公共構造:

  1. Random() - 構造一個隨機生成與 一天以毫秒爲單位的初始狀態的當前時間。

  2. Random(long seed) - 構建一個隨機生成器,將給定的 種子作爲初始狀態。

欲瞭解更多詳情,請參閱以下鏈接:

Generate random number in Android

Generate Random number, Random()