2011-11-08 119 views
16

我剛剛發現難以將重置C(++)的PRNG到srand之前的狀態(如reference )。 然而,種子0似乎也是這樣做的,或者在調用srand之前的狀態似乎使用種子0. 這兩個調用之間的區別是什麼或者他們做同樣的事情的原因是什麼?srand(1)和srand(0)之間的區別

例如這個代碼(execute on Ideone

#include <stdio.h> 
#include <stdlib.h> 

int main() { 
    for (int seed = 0; seed < 4; seed++) { 
     printf("Seed %d:", seed); 
     srand(seed); 
     for(int i = 0; i < 5; i++) 
      printf(" %10d", rand()); 
     printf("\n"); 
    } 
    return 0; 
} 

返回

Seed 0: 1804289383  846930886 1681692777 1714636915 1957747793 
Seed 1: 1804289383  846930886 1681692777 1714636915 1957747793 
Seed 2: 1505335290 1738766719  190686788  260874575  747983061 
Seed 3: 1205554746  483147985  844158168  953350440  612121425 
+1

非常有趣的問題。就我所知,srand沒有任何「魔術」價值,但rand()只是初始化爲1的種子,並且因此從該種子開始,除非被告知不同的東西。這意味着如果你調用srand(1),你會「重置到原始狀態」。然而,你發佈的輸出表明,它真的「神奇地重置」到你以前設置的種子0,而不是1(這就是說,我的實現沒有_not_做)。 – Damon

回答

11

這可能是一個實現細節。標準規定隨機種子1是特殊的,並且特定隨機生成器算法的內部寄存器可能是零初始化的,因此對種子(0)和種子(1)產生相同的隨機序列。我甚至打賭你的srand()實現的第一行看起來像:

if (seed == 1) seed = 0; 

強制執行符合標準的行爲。

通常,rand()和srand()的隨機數生成器不需要爲不同的種子給出不同的序列,但是對於相同的種子卻是相同的序列。所以,不依賴於不同的種子產生不同的隨機序列,你應該沒問題。如果不是,歡迎使用特定於實現的樂趣。

+9

實際上,代碼更像'if(seed == 0)seed = 1;',因爲'rand()'的GNU實現使用的算法不適用於零的種子。 –

7

既不與c也不是C++標準多講的rand()srand()實施的細節。細節幾乎完全取決於實現者。 C標準要求:

如果然後用相同的種子值調用srand,則應重複僞隨機數的序列。如果已作出任何函數srand調用之前蘭特被調用時,相同的序列應按srand時首先用1

種子值稱爲產生,但是它不包含任何要求,即不同種子必須產生不同的序列。顯然,在你的系統中,零和一顆種子具有相同的效果。我猜想這是爲了向後兼容一些軟件,它希望srand(0)將PRNG重置爲初始狀態。

0

閱讀手冊頁時,他們都聲明「如果沒有提供種子值,則rand()函數將自動播種值爲1」。這可能是爲什麼您鏈接的參考頁面聲明種子1重置狀態。

對於0和1兩種播種而言,相同的結果最可能取決於實現,不應將其計入所有平臺上。

0

srand()函數使用參數作爲隨機調用rand()返回的新隨機數序列的種子。如果srand()然後用相同的種子值調用,則應該重複僞隨機數的序列。如果在對srand()進行任何調用之前調用rand(),則應當生成與srand()首次調用種子值爲1時相同的序列。

也許有用:http://pubs.opengroup.org/onlinepubs/009695399/functions/rand.html

1

如果種子被設置爲1,發電機被重新初始化到它的初始值,併產生相同的值,以蘭特或函數srand任何呼叫之前。srand參考

15

glibc的,它是如何摘自:

around line 181 of glibc/stdlib/random_r.c,內部功能__srandom_r

/* We must make sure the seed is not 0. Take arbitrarily 1 in this case. */ 
    if (seed == 0) 
    seed = 1; 

但是,這只是glibc的是怎麼做的。這取決於C標準庫的實現。

-3

指定原因1是因爲如果種子設置爲零,某些隨機數生成器將卡住零。例如移位寄存器和乘法同餘類型,即r(n+1) = (A * r(n))mod M。許多C實現使用線性同餘r(n+1) = (A * r(n) + B) mod M,B <> 0,它們不會卡住。

+0

這與問題有什麼關係? – melpomene

相關問題