標籤:style blog http 使用 os io 檔案 資料
標頭檔<cstdlib>中有一個重要的函數 rand() , 可以作為隨機數發生器。
現在現在我想產生一個隨機數, 我使用如下的程式:
#include <iostream>#include <ctsdlib><span style="font-family: Arial, Helvetica, sans-serif;">using namespace std;</span>int main(){ cout << rand() << endl; return 0;}
問題來了, 雖然我們產生了一個隨機數, 但是無論我運行上述程式多少遍(重新編譯, 在運行,也一樣是41), 都產生一個確定的數。 即41, 如下:
這是為什麼呢。
答案是要想得到一個隨機數, 我們需要給這個隨機數發生器(random number generator) 輸入一個seed(種子)。
現在讓我們在函數中調用rand() 函數25次, 用於產生25個隨機數:
上述的情況也是一樣的, 無論是將該程式運行多少遍, 或者再次編譯, 運行, 結果仍然是產生了25個與上述隨機數完全一樣的隨機數。 這仍然是沒有seed的原因。
在舉一個例子, 類比骰子。 隨機出現的資料是: 1, 2, 3, 4, 5, 6, 現在我們編程產生這個範圍的數字, 投25次, 程式如下:
#include <iostream>#include <random>using namespace std;int main(){ for (int i = 0; i < 25; i++) { cout << 1+ (rand() % 6) << endl; // 必須加1, 否則產生0 } return 0;}
運行結果如下:
不難推廣, 我們可以產生任意範圍整數的隨機數。
但是問題來了, 由於上述的幾個程式的隨機數沒有seed, 所有無論我們運行多少次程式, 產生的隨機數都是相同的。
問什麼呢?
因為沒有電腦能夠產生完全隨機的隨機數。 電腦畢竟不是人, 電腦必須按照一定的演算法(Algorithm), 一定的指令去執行命令。 也就是說電腦不可能產生完全隨機的資料。 但是電腦通過一定的複雜的演算法, 我們可以使得其產生的資料看起來是隨機的。
C++產生隨機數可以使用的seed random number。 常用的函數是srand()(函數有一個參數, 使我們給進去的任何一個隨機數),:
#include <iostream>#include <cstdlib>using namespace std;int main(){ srand(6); for (int i = 0; i < 25; i++) { cout << 1+ (rand() % 6) << endl; } return 0;}
產生的結果如下:
顯然不同了。 但是如果我們不改變srand(6)函數中的參數, 只要我們運行, 或者重新編譯運行, 仍然出現同樣的結果(同上面的問題一樣)。 但是只要我們改變srand() 中的參數, 重新編譯, 運行, 出現不同的結果。 例如我們將srand(6)改為srand(10), 就會改變的:
現在我們給出上述所有問題的終極解決辦法:
這個解決辦法需要包含一個叫做<ctime>的標頭檔。 這個標頭檔允許我們去得到電腦的時鐘。 如下:
#include <iostream>#include <cstdlib>#include <ctime>using namespace std;int main(){ srand(time(0)); for (int i = 0; i < 25; i++) { cout << 1+ (rand() % 6) << endl; } return 0;}
編譯運行:
再次運行:
也就是說只要重新運行, 就會重新產生和偽隨機數。 這正是我們希望得到的結果。
現在我們解釋原因:
我們知道可以通過srand() 去修改我們的演算法。 但是如果我們向srand()中傳遞一個確定的數字, 那麼演算法產生的結果也是一個確定的數字。 無論我們運行多少次,結果都是一樣的。
但是我們想srand 傳遞的參數為time(0), time(0) 函數的返回值每一秒都在變化。 隨機這樣 , 每一次我們運行函數的時候 , 結果都看似隨機的了。