2013-12-21 50 views
2

這裏的C++問題,使用Code :: Blocks。 我試圖運行此代碼以測試僞隨機函數蘭德()返回相同或非常相似的輸出值

#include <iostream> 
#include <cstdlib> 
#include <ctime> 

using namespace std; 

int main() 
{ 
    int count = 0; 
    while (count < 10){ 
     srand(time(NULL)); 
     cout << rand() << ' '; 
     cout << (time(NULL)) << " \n"; 
     count++; 
    } 
    return 0; 
} 

從這個輸出是10條相等的線。這不是真正的問題,因爲這裏的種子是相同的,所以結果應該是相同的。問題是,如果我再次運行這個程序,它會給出10條非常相似的行,不僅在time()輸出上有很小的變化,而且在rand輸出上也是如此。

的函數srand(時間(NULL))是給這基本上是相同的返回值非常相似的答案,只有一點點大。

(第一次運行返回9631,然後在第二9656)。

我的問題是,是預期的行爲?我怎麼能得到更多不同的結果,如第一次運行38次,第二次運行671次?

+0

你能更精確嗎?你期望看到什麼?你看到了什麼?這如何不能達到你的期望? –

回答

0

爲了使隨機數與一個幾乎相同的種子(時間),你可以添加一個靜態變量,使rand()行爲即使有相同的參數不同;或者,當你獲得相同的時間時,你可以改變參數。例如:

int t=0; 
... 
rand(t=(t*7)^time(NULL)); 
+0

這實際上是一個很好的解決方案!我這樣做了,我可以使用同一時間獲得100種不同的解決方案(通過運行此程序一次,同時計數達到100)。再次運行它似乎解決方案的可預測性也非常非常低。我唯一需要補充的是我需要改變的函數調用是srand,而不是rand。但我明白你的意思。非常感謝! –

2

這裏很多的誤解......這接近兩個彼此time(NULL)調用之間的差別很小,預計。畢竟,時間過得很快。接下來的問題是rand()返回一個(僞)隨機值(不同質量):在這種情況下,隨機意味着您可以重複幾次,只要它不可預測。這就是說,rand()是依賴於實現的,很可能你的實現使用了類似於LCG的東西,它不會生成好的統一的隨機值。唯一的解決方法是切換到不同的rng。由於它被標記爲C++,因此您可能需要查看C++ 11s隨機頭並使用像mersenne twister實現這樣的東西,這是一個很好的僞隨機數生成器,可生成高質量,均勻分佈的隨機數。

+0

我知道這一切。我只是說,一旦我知道我第一次運行我的程序的價值,我可以期待如果我關閉它並再次運行它,我會得到什麼樣的價值。我甚至可以計算出這個數字需要多長時間才能達到某個特定點,然後我可以始終預測我將從中得到的數量。這不是隨意給我的。甚至沒有任何僞隨機。如果我只是打印「時間(空)」,結果將是相同的:總是以一定的速度增長的數字。 –

1

變化執行之間的差異想必會變化的在time差小。的rand結果可以爲不同的C運行時不同,但這裏是rand從Visual Studio 10

int __cdecl rand() 
{ 
    _ptiddata ptd = _getptd(); 

    return(((ptd->_holdrand = ptd->_holdrand * 214013L 
     + 2531011L) >> 16) & 0x7fff); 
} 

holdrand存儲種子,開始與開始實施。這是一個linear congruential generator,它通常不會產生高質量的隨機性。它每次都會丟掉很多狀態,這並沒有幫助。

+0

所以基本上,這意味着rand的工作方式實際上是一個線性和可預測的功能?那麼,我猜想讓它看起來像返回一個隨機值的唯一方法是,如果我限制了我可以從中獲得的最大值。就像使用rand(時間(0))%10或%一個數字一樣。我試圖得到更加相似和可預測結果的結果會越大。 –