2012-11-13 135 views
20

也許有一個非常邏輯的解釋,但我似乎無法理解爲什麼種子02,147,483,647產生相同的「隨機」序列,使用.NET的Random Class (System)兩個不同的種子產生相同的「隨機」序列

快速代碼例如:

var random1 = new Random(0); 
var random2 = new Random(1); 
var random3 = new Random(int.MaxValue); //2,147,483,647 

var buffer1 = new byte[8]; 
var buffer2 = new byte[8]; 
var buffer3 = new byte[8]; 

random1.NextBytes(buffer1); 
random2.NextBytes(buffer2); 
random3.NextBytes(buffer3); 

for (int i = 0; i < 8; i++) 
{ 
    Console.WriteLine("{0}\t\t{1}\t\t{2}", buffer1[i], buffer2[i], buffer3[i]); 
} 

輸出:

26  70  26 
12  208  12 
70  134  76 
111  130  111 
93  64  93 
117  151  115 
228  228  228 
216  163  216 

正如你可以看到,第一和第三序列是相同的。有人可以向我解釋這個嗎?

編輯:顯然,正如alro指出的,這些序列是不一樣的。但他們非常相似。

+1

你有沒有嘗試過任何其他的任意數字來反對,如果是的話,你是否得到與該數字相同的結果? –

+3

'System.Random'在很多方面都是按設計劃分的。這是其中之一。 – CodesInChaos

+3

+1非常有趣的觀察! – quetzalcoatl

回答

10

好吧,原因將與隨機類用來從種子派生僞隨機序列的任何派生函數相關聯。 答案,因此,是數學(並超出我的能力)。

事實上 - 我不相信有任何保證,兩種不同的種子總會產生不同的序列。

編輯好了 - 我要做的已經做了什麼bitbonk - 但解釋爲什麼

public Random(int Seed) 
{ 
    int num = (Seed == -2147483648) ? 2147483647 : Math.Abs(Seed); 
    int num2 = 161803398 - num; 
    this.SeedArray[55] = num2; 
    int num3 = 1; 
    for (int i = 1; i < 55; i++) 
    { 
     int num4 = 21 * i % 55; 
     this.SeedArray[num4] = num3; 
     num3 = num2 - num3; 
     if (num3 < 0) 
     { 
      num3 += 2147483647; 
     } 
     num2 = this.SeedArray[num4]; 
    } 
    for (int j = 1; j < 5; j++) 
    { 
     for (int k = 1; k < 56; k++) 
     { 
      this.SeedArray[k] -= this.SeedArray[1 + (k + 30) % 55]; 
      if (this.SeedArray[k] < 0) 
      { 
       this.SeedArray[k] += 2147483647; 
      } 
     } 
    } 
    this.inext = 0; 
    this.inextp = 21; 
    Seed = 1; 
} 

,我們實際上並不需要太遠進入代碼,看看爲什麼 - 讀取從頂部到底部的代碼這些是將由上述代碼當種子是0和被存儲的值時所述種子是2147483647

int num = (Seed == -2147483648) ? 2147483647 : Math.Abs(Seed); 
    => num is 0 and 2147483647 

int num2 = 161803398 - num; 
    => num2 is 161803398 and -1985680249 

this.SeedArray[55] = num2; 
    => this.SeedArray is as above in both cases 

int num3 = 1; 
for (int i = 1; i < 55; i++) 
{ 
    int num4 = 21 * i % 55 
    this.SeedArray[num4] = num3; 

    => num4 is 21, SeedArray[21] is 1 

num3 = num2 - num3 
    => num3 is 161803397 and -1985680250 

if(num3 < 0) 
    num3 += 2147483647 

    => num3 is 161803397 and 161803397 

在第一個循環之後,算法已經收斂了兩個種子值。

編輯

正如已指出了問題 - 序列是不一樣的 - 但他們顯然非常非常相似 - 在這裏,我們可以看到的是相似的原因。

+1

感謝您的詳細信息!值得注意的是,{0,int.Max,int.Min}與本線程證明的結果是相同的種子。我想知道這個實施是否有其他這樣的共同種子?如果有更多的人,這將是一篇文章的不錯基礎:) – quetzalcoatl

+0

+1幹得好! @quetzalcoatl我認爲System.Random的實現並不是一個體面的隨機數生成器,但它可以隨時使用,每當你甚至不需要考慮它的優點時,就可以很快地使用它。這就是爲什麼(甚至在框架內部)有這麼多不同的實現。 –

+0

@Adriano但文檔意味着更多。 http://msdn.microsoft.com/en-us/library/ctssatww.aspx如果您的應用程序需要不同的隨機數字序列,請使用不同的種子值重複調用此構造函數。 – Paparazzi

相關問題