2009-10-31 175 views
47

這真的很奇怪,我不明白爲什麼會發生這種情況。在foreach循環中,我遍歷A類集合,對於每個類,我調用Count()方法,其中r1r2數字根據範圍[-1,1]生成。問題是Random.Next爲每個實例返回相同的「隨機」數字。當第一個實例的結果爲0和-1時,將從以下實例返回相同的結果。請你能告訴我爲什麼會發生這種情況嗎?另外,我無法在每個A類實例中獲得不同的結果。這是代碼:Random.Next總是返回相同的值

class a 
{ 
Random rnd = new Random(); 
private void Count() 
{ 
    int r1 = rnd.Next(-1, 1); 
    int r2 = rnd.Next(-1, 1); 
} 
} 
class b 
{ 
List<a> listofA=new list<a>(); 
foreach (a ACLASS in listofA) 
{ 
    ACLASS.Count(); 
} 
} 

回答

94

的問題是,你正在創建的Random類的實例太近的時間。

當您創建一個Random對象時,它將使用來自系統時鐘的值進行播種。如果您創建的實例太接近Random,它們將全部使用相同的隨機序列播種。

創建一個單一的Random對象,並在創建「a」類的實例時將其引用傳遞給構造函數,而不是爲每個「a」實例創建一個Random對象。

+1

我忘了還有的範圍內,我曾經有過同樣的問題,早在一天做賓果爲紙箱一個俱樂部,當時,我用了人類已知的最糟糕的技巧:暫停線程2女士沒有經驗和瘋狂...... 足夠瘋狂,我有一個類創建隨機的名稱與頂部的靜態隨機聲明一切。 – 2013-06-26 04:25:39

5

您爲每個A實例包含一個隨機實例。這聽起來像他們都獲得相同的默認種子值。您可能希望對所有A實例進行靜態隨機並重復使用它,或者向A構造函數中的Random()實例提供種子值。

8

您正在創建一個非常接近的新實例Random(您的循環非常緊張),因此每個實例都有效地使用相同的種子值。

更好的方法是創建一個實例並將其傳遞給您的方法Count

你problably知道這下一點,但我會在這裏包括它的完整性:

MSDN對這個細節,但基本上你的問題是你使用的Random.Next方法生成:

大於或等於minValue且小於maxValue的32位有符號整數;也就是說,返回值的範圍包含minValue,但不包含maxValue。如果minValue等於maxValue,則返回minValue。

因爲這樣您的通話將返回-1或0

7

使用單一,靜態隨機數發生器,用於在類的所有實例。

class a 
{ 
    private static Random rnd; 
    static a() { 
     rnd = new Random(); 
    } 
    private void Count() 
    { 
    int r1 = rnd.Next(-1, 2); 
    int r2 = rnd.Next(-1, 2); 
    } 
} 

注意的變化給你號碼1,1,而不是1,0

+0

我認爲這個範圍它也可以返回1,他們只想要0和-1? – Lucas 2009-10-31 18:38:39

+0

@Svante編輯了問題以使間隔打開以匹配代碼示例。原來的問題指定了一個封閉的時間間隔,儘管不使用精確的語言我認爲代碼是不正確的,我將要恢復問題來指定一個關閉的時間間隔。 – tvanfosson 2009-10-31 18:57:22

+0

@tvanfosson你能告訴我爲什麼這可行嗎?我不明白如何讓這種靜力學給你隨機性。我知道它有效,但不是爲什麼。他們仍然非常接近時間。謝謝。 – johnny 2016-11-08 18:06:22