C++中常用rand()函數產生隨機數,但嚴格意義上來講產生的只是偽隨機數(pseudo-random integral number)。產生隨機數時需要我們指定一個種子,如果在程式內迴圈,那麼下一次產生隨機數時調用上一次的結果作為種子。但如果分兩次執行程式,那麼由於種子相同,產生的“隨機數”也是相同的。
在工程應用時,我們一般將系統目前時間(Unix時間)作為種子,這樣產生的隨機數更接近於實際意義上的隨機數。給一下常式如下:
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
int main()
{
double random(double,double);
srand(unsigned(time(0)));
for(int icnt = 0; icnt != 10; ++icnt)
cout << "No." << icnt+1 << ": " << int(random(0,10))<< endl;
return 0;
}
double random(double start, double end)
{
return start+(end-start)*rand()/(RAND_MAX + 1.0);
}
/* 運行結果
* No.1: 3
* No.2: 9
* No.3: 0
* No.4: 9
* No.5: 5
* No.6: 6
* No.7: 9
* No.8: 2
* No.9: 9
* No.10: 6
*/
利用這種方法能不能得到完全意義上的隨機數呢?似乎9有點多哦?卻沒有1,4,7?!我們來做一個機率實驗,產生1000萬個隨機數,看0-9這10個數出現的頻率是不是大致相同的。程式如下:
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <iomanip>
using namespace std;
int main()
{
double random(double,double);
int a[10] = {0};
const int Gen_max = 10000000;
srand(unsigned(time(0)));
for(int icnt = 0; icnt != Gen_max; ++icnt)
switch(int(random(0,10)))
{
case 0: a[0]++; break;
case 1: a[1]++; break;
case 2: a[2]++; break;
case 3: a[3]++; break;
case 4: a[4]++; break;
case 5: a[5]++; break;
case 6: a[6]++; break;
case 7: a[7]++; break;
case 8: a[8]++; break;
case 9: a[9]++; break;
default: cerr << "Error!" << endl; exit(-1);
}
for(int icnt = 0; icnt != 10; ++icnt)
cout << icnt << ": " << setw(6) << setiosflags(ios::fixed) << setprecision(2) << double(a[icnt])/Gen_max*100 << "%" << endl;
return 0;
}
double random(double start, double end)
{
return start+(end-start)*rand()/(RAND_MAX + 1.0);
}
/* 運行結果
* 0: 10.01%
* 1: 9.99%
* 2: 9.99%
* 3: 9.99%
* 4: 9.98%
* 5: 10.01%
* 6: 10.02%
* 7: 10.01%
* 8: 10.01%
* 9: 9.99%
*/
可知用這種方法得到的隨機數是滿足統計規律的。