2010-04-04 150 views
4

好的,這是一個非常奇怪的結果。不同的rand()序列在表達式中產生相同的結果

我有一個MPI程序,其中每個進程必須在固定範圍內生成隨機數(範圍從文件中讀取)。會發生什麼情況是即使我爲每個進程使用不同的值,並且每個進程中生成的數字都不相同,但生成隨機數的表達式仍然會在它們之間產生相同的序列。

這裏的所有相關的代碼:

// 'rank' will be unique for each process 
int rank; 
MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
// seed the RNG with a different value for each process 
srand(time(NULL) + rank); 
// print some random numbers to see if we get a unique sequence in each process 
// 'log' is a uniquely named file, each process has its own 
log << rand() << " " << rand() << " " << rand() << std::endl; 

// do boring deterministic stuff 

while (true) 
{ 
    // waitTimeMin and waitTimeMax are integers, Max is always greater than Min 
    waitSecs = waitTimeMin + rand() % (waitTimeMax - waitTimeMin); 
    log << "waiting " << waitSecs << " seconds" << std::endl; 
    sleep(waitSecs); 
    // do more boring deterministic stuff 
} 

這裏的每個過程的輸出,用3個過程在範圍[1,9]產生的數字。

過程1:

15190 28284 3149 
waiting 6 seconds 
waiting 8 seconds 
waiting 9 seconds 
waiting 4 seconds 

過程2:

286 6264 3153 
waiting 6 seconds 
waiting 8 seconds 
waiting 9 seconds 
waiting 4 seconds 

過程3:

18151 17013 3156 
waiting 6 seconds 
waiting 8 seconds 
waiting 9 seconds 
waiting 4 seconds 

因此,儘管rand()清楚地生成不同的數字,表達式來計算waitSecs仍評估爲所有進程的序列相同。更奇怪的是:如果我再次運行帶有相同參數的程序,只有前3個隨機數字會改變,其餘的「隨機」序列在每次運行中將完全相同!更改數字範圍顯然會產生與此不同的結果,但執行過程中的進程之間的相同參數始終產生相同的序列:除前3個數字外。

這到底是怎麼回事?


編輯:所以只是爲了看看它的簡單隨機生成和/或低的範圍內,我取代了隨機生成這一行:

waitSecs = waitTimeMin + (int)((double)rand()/((double)RAND_MAX + 1) * (waitTimeMax - waitTimeMin)); 

而且在範圍內開始產生數[1,99]。這裏的結果:

過程1:

7833 3798 10977 
waiting 1 seconds 
waiting 20 seconds 
waiting 58 seconds 
waiting 35 seconds 
waiting 82 seconds 
waiting 18 seconds 

過程2:

25697 14547 10980 
waiting 1 seconds 
waiting 20 seconds 
waiting 58 seconds 
waiting 35 seconds 
waiting 82 seconds 
waiting 18 seconds 

過程3:

10794 25295 10984 
waiting 1 seconds 
waiting 20 seconds 
waiting 58 seconds 
waiting 35 seconds 
waiting 82 seconds 
waiting 18 seconds 

同樣的事情。這仍然只是rand()真的很糟糕?

EDIT2:1生成號碼10000

+0

檢查是否真的是rand()問題: log <<「min」<< waitTimeMin <<「max」<< waitTimeMax << endl; – 2010-04-04 17:43:21

+0

在每種情況下打印您正在播種srand()的值。 – 2010-04-04 18:15:12

+0

做了那個Neil:過程1爲X,過程2爲X + 1,過程3爲X + 2等。 – suszterpatt 2010-04-04 18:22:21

回答

1

好吧,顯然我被推遲了。在初始化RNG之後,我產生了一個新的線程並在那裏生成了隨機數,而不需要初始化。在新線程中調用srand()可解決問題。所以是的,這裏的教訓是srand()rand()每個線程工作,而不是每個進程。我還需要在我的問題中發佈更多關於我的程序的信息。

Ouch。

對不起浪費大家的時間。

+0

如果你正在使用rand與多線程應用程序,你可能也想看看線程安全版本rand_r,它應該是POSIX指定的可重入的,其中rand不是必須的(但可能取決於實現)。 – 2010-04-04 18:49:33

+0

我認爲你可以'接受'自己的答案作爲正確答案。這會將它泡到最高層,並防止任何人讀這條線來追蹤紅鯡魚。 – brainjam 2010-04-04 18:49:52

+0

它不會讓我接受2天的答案,必須是一個新功能。另外,我實際上使用Qt的'qrand()',它聲稱是'rand()'的線程安全版本。 – suszterpatt 2010-04-04 18:52:04

1

當同樣的事情,嘗試使用一個隨機數發生器從TR1像std::tr1::mt19937。通常使用低質量的隨機數生成器來實現功能rand()

編輯:低質量可能意味着,例如,即使在[0,100]^2中生成2D點(x,y)也會導致點不均勻分佈在正方形中。你可能會認爲它不應該表現得那麼糟糕,但是你會對它的實際表現有多麼的驚訝(這在大多數語言中都是可悲的)。

編輯2:方法range*(rand()/RAND_MAX)不是一個好的。它具有雙精度問題,甚至不會產生結果。

請嘗試以下,看看你的程序仍然給你,你是感到吃驚的結果:

std::tr1::mt19937 engine(thread_seed); 
std::tr1::uniform_int<> unigen(waitTimeMin, waitTimeMax); 
std::tr1::variate_generator<std::tr1::mt19937, 
          std::tr1::uniform_int<> >gen(engine, unigen); 
waitSec = gen(); 

EDIT3: http://dilbert.com/dyn/str_strip/000000000/00000000/0000000/000000/00000/2000/300/2318/2318.strip.gif

+0

正如你所看到的,前三個數字的%9似乎是相等的:只是rand()的質量太差,以至於你的序列高度相關。 – baol 2010-04-04 17:38:15

+0

我不需要高質量的隨機數字,當然'rand()'預計會比這更好。我可能會嘗試其他方法,但我仍然想知道是什麼導致了這種現象。 – suszterpatt 2010-04-04 17:39:33

+1

也許,但低質量的隨機數字不是隨機的:)。請注意,高質量的隨機數發生器也可能非常快。 – baol 2010-04-04 17:44:17

4

在你的代碼只使用低3位,如果產生隨機數(除以8的餘數)。您的實驗顯示,生成的數字序列中最低3位的序列每次都是相同的。這是完全可能的。實際上,這是一個衆所周知的問題,通常用於實現rand()的簡單僞隨機數生成器。

如果您想使用rand()(而不是更復雜的自定義生成器),最好使用高位而不是低位。即請勿使用%運營商來減少rand()的範圍。在這裏看看更好的方法:http://c-faq.com/lib/randrange.html

+0

我使用更大的範圍和更好的方法從該網站進行測試,結果相同(請參閱問題中的編輯)。 – suszterpatt 2010-04-04 18:02:27

1

計算(rand() % n)通常是一個壞主意 - 你會得到比隨機的結果。相反,如果RAND_MAXrand()的輸出範圍,請嘗試將rand()除以(RAND_MAX/(waitTimeMax - waitTimeMin))。您正在使用的rand()可能是linear congruential generator。如果你遵循後面的鏈接,你會發現更多關於它是如何工作的信息,以及爲什麼低位比較高位「不那麼隨機」的解釋。

相關問題