2011-10-13 106 views
20

我輸出的隨機數,每次運行遊戲時都以相同的順序輸出。這是爲什麼發生?每次運行程序時都使用相同的隨機數

#include <cstdlib> 

和現在用這個來產生隨機數

randomDiceRollComputer = 1 + rand() % 6; 
+0

請參閱http://en.wikipedia.org/wiki/Pseudorandom_number_generator – DuckMaestro

回答

26

您需要種子的隨機數發生器:

嘗試把此在的開始程序:

srand (time(NULL)); 

請注意,您將需要#include <ctime>

這裏的想法是每次啓動程序時都會給RNG添加一個不同的數字。通過使用時間作爲種子,每次啓動程序時都會得到不同的編號。

+0

嗯播種方面究竟意味着什麼? – mystycs

+4

基本上,RNG並不是真正的隨機。他們使用一個公式來生成看似(僞)的隨機數。因此,他們需要一個「起點」來開始生成一個序列。如果您沒有種子,它將使用相同的默認種子並每次生成相同的序列。 – Mysticial

+2

爲了獲得更好的結果,請在'srand'後面調用'rand'並丟棄返回值。事實證明,類似的種子產生了類似的第一個值,但它迅速發散。 –

7

您需要給隨機數生成器一個種子。這可以通過考慮當前時間來完成,因爲這是希望的某種隨機。

#include <cstdlib> 
#include <ctime> 
using namespace std; 

int main() 
{ 
    int r; 
    srand(time(0)); 
    r = rand(); 
    return 0; 
} 
0

僞隨機數發生器取一個起始數字或種子,然後從這個序列中產生下一個數字。這就是爲什麼它們被稱爲僞隨機數的原因,因爲如果它們始終使用相同的起始值,它們將生成與C標準庫生成器相同的數字序列。這可以通過給發生器一個初始值來修復,該值將在下一次程序運行時改變,如當前時間。

無論如何,你看像其他人所說的代碼是:

srand(time(0)); //Seed the generator, give it a starting value 
+0

不,他們'我們稱之爲僞隨機數,因爲它們在數學意義上並不是真正的隨機數,只是一個近似值。每次運行時都會生成不同數字的PRNG仍然是僞隨機數。 –

+0

@KeithThompson我知道,我的意思是這就是爲什麼這種特定類型的PRNG是PRNG。更一般地說,PRNG被稱爲僞隨機,因爲它使用確定性算法來查找序列的每個值,是否正確? – jgon

1

rand()功能是專門須出示相同的數字序列時,與給定的種子播種(通過調用srand()) ;每個可能的種子值指定一個序列。如果您從未撥打srand(),您可以在致電rand()之前致電srand(1),獲得相同的序列。

(這不會跨越不同的C或C++實現適用。)

這可以是用於測試目的是有用的。例如,如果程序中存在一個錯誤,您可以通過使用相同的種子重新運行它來重現該錯誤,從而保證(除其他不可預知的行爲外),您將獲得相同的僞隨機數序列。

調用srand(time(NULL))是通常推薦的方法來獲得或多或少不可預知的僞隨機數。但這並不完美。如果程序在同一秒內運行兩次,則可能會得到相同的序列,因爲time()(通常)的分辨率爲1秒。並且典型的rand()實現是而不是足夠好用於密碼使用;攻擊者很容易猜出你將得到的數字。

還有一些其他的隨機數實現。 Linux系統有兩個僞設備/dev/random/dev/urandom,您可以從中讀取合理的高質量僞隨機字節值。某些系統可能具有random(),drand48()等功能。還有很多算法;我聽說過有關Mersenne Twister的好消息。

對於類似遊戲的遊戲,您不希望或不關心玩家試圖作弊的情況,srand(time(NULL))rand()可能已經足夠。對於更嚴肅的目的,你應該從比我更瞭解這個東西的人那裏得到建議。

comp.lang.c FAQ的第13部分有關於僞隨機數生成的一些非常好的信息。

相關問題