2013-03-25 52 views
1

當我執行下面的代碼時,我總是選擇相同的顏色。爲什麼Random會始終進行相同的選擇?

static void Main(string[] args) 
     { 
      string[] Colors = new string[10] { "Red", "Yellow", "Green", "Blue", "Purple", "White", "violet", "orange", "indigo", "blue" }; 
      for (int i = 0; i < 13; i++) 
      { 
       Random rnd = new Random(); 
       int code = rnd.Next(0, 9); 
       string Color = Colors[code]; 
       Console.WriteLine(Color); 
      } 
      Console.ReadLine(); 
     } 

但是,如果Random rnd = new Random();'在循環外創建,那麼結果是唯一的。如果循環以更快的速度執行,那麼輸出將是相同的。假設我在for循環中執行了一些數據庫插入操作,結果將是不同的(隨機的)(使用斷點的逐步執行也會導致隨機選擇)。

真的不可能在這麼短的時間內提供不同的種子嗎?

+2

你確切的問題靜態對象Random'](http://msdn.microsoft.com/en-us/library/h343ddh9.aspx)。 「隨機」實例默認採用系統時間播種。你的循環速度足夠讓他們擁有相同的種子。爲什麼每次迭代都會生成一個新的RNG? – Carsten 2013-03-25 09:54:36

+0

@阿蘭我只看到它!在我受到攻擊之前請關閉它。我無法刪除它 - 已經回答 – 2013-03-25 09:55:13

+0

@Carsten我剛試過!但是,看到它 – 2013-03-25 09:56:32

回答

2

儘量使隨機對象的靜態成員:

private static Random rnd = new Random(); 

這防止建設有一個相同的種子(當前時間)的隨機數的對象,並且防止產生數字的相同序列。

循環在每次迭代時使用相同的種子(當前時間)初始化一個新實例Random。每個實例都包含一系列不同的隨機數字。代碼使用序列中的第一個數字,在迭代完成後,隨機對象將被丟棄,並且實例化一個新的Random對象。由於代碼已經運行得相當快,下一個隨機對象與前一個同時創建,因此它具有與那個相同的種子。新對象包含各種數字的序列,但序列與前一個相同(即它們具有相同的第一個數字,第二個數字等等)。代碼再次使用來自相同序列的第一個數字,這會導致重複的數字。

如果您將Random對象設爲靜態成員,則隨機序列會創建一次,並且代碼將使用該序列的下一個數字(並非總是第一個數字),因此您將遍歷各種隨機序列數字。

如果您不想讓隨機對象成爲靜態成員,請嘗試爲其構造函數提供唯一的種子。你可以使用你的循環變量來達到這個目的。

5

隨機使用當前時間作爲seed。當你在循環中創建它時,它發生得如此之快,以至於每次創建的時間都保持不變。所以種子是一樣的,隨機產生的值也是一樣的。

0

你需要保持相同的隨機對象爲以下原因:

僞隨機數從有限的數字選概率相同。所選擇的數字不是完全隨機的,因爲使用確定的數學算法來選擇它們,但它們對於實際目的而言是足夠隨機的。 隨機數的產生從種子值開始。如果重複使用相同的種子,則生成相同系列的數字

http://msdn.microsoft.com/en-gb/library/system.random.aspx

+0

-1就會感到困惑......重點是他已經知道把它放在循環外面並獲得所需的結果......他問*爲什麼*。 – Arran 2013-03-25 09:58:31

+0

我只是編輯我的答案,尋找官方解釋 – 2013-03-25 09:59:53

+0

是否不可能爲同一實例提供不同的種子? – 2013-03-25 11:34:03

2

如果您不提供種子,Random將使用Environment.TickCount作爲種子。在這樣的短循環中,完全可能的是整個循環在一個tick中執行。所以種子每次都是一樣的,因此你的「隨機」數字也是。

只需在整個循環中使用相同的隨機對象。

2

隨機是不是在計算機編程隨機;)你可以把它「更」隨機由包括種子或通過其[`爲文檔中得到解決含有隨機:)

相關問題