隨機數
int rand ();
rand函數返回一個0-32767之間的一個偽隨機整數,32767可以由宏RAND_MAX表示,該函數需要頭文件<stdlib.h>。
常用的是如何生成一個范圍內的隨機數,例如想生成0-100之間的隨機數,那么我們可以編寫如下語句:
1 #include <stdlib.h> 2 #include <iostream> 3 4 using namespace std; 5 6 void RAND(int max, int min, int n) 7 { 8 for(int i = 0; i < n; ++i) 9 { 10 int u = (double)rand() / (RAND_MAX + 1) * (max - min) + min; 11 cout << u << " "; 12 } 13 }
第10行是關鍵,rand()生成一個隨機數,通過一系列簡單的數學計算將隨機范圍變到min與max之間。需要注意的是,將rand轉化為double類型之后是保證在做除法時得到有效地數字,最后因為u聲明為int類型,最后可以保證得到的是整數序列。參數n是隨機數的個數。生成0-100的10個隨機數的語句為
RAND(100, 1, 10);
結果如圖,但是這樣每次生成的隨機數都相同,因此我們需要一種方法來生成不同的隨機數。srand()函數用以設定隨機數種子,我們知道隨機數的產生實際上是從一個偽隨機數列中取值,我們通過設置隨機數種子,即可以從該偽隨機數列的不同位置取值,顯示出來就達到了更新隨機數的目的。
void srand( unsigned int seed );
里面接受一個int數值,一般采取的方式是根據當前系統時間來產生一個數值,用該數值來作為隨機數種子,需要頭文件<time.h>。
1 void RAND(int max, int min, int n) 2 { 3 srand(time(NULL)); 4 for (int i = 0; i < n; i++) 5 { 6 int u = (double)rand() / (RAND_MAX + 1) * (max - min) + min; 7 cout << u << " "; 8 } 9 }
第三行便更新了隨機數種子,得到結果為 ,可以看出隨機數有了更新。
不重復隨機數
從第二次運行的結果來看,我們發現產生了兩個90,如果我們想要避免這種情況,即產生的隨機數不會重復,那么該如何進行代碼的編寫?
最初的思想是每生成一個隨機數,便於前面的所有隨機數進行比較,如果有重復,則舍去不要,重新選取。但該方法十分費時,並且在數據量巨大的並且有一定限制的時候,會引發巨大問題。例如要生成10000個隨機數,范圍是0-9999,且不能重復,那么最后幾個隨機數有可能需要相當長的時間才能篩選出來。
下面我們從另外一個角度來思考,假設我們已經由一個數組長度為10000的數組,里面分別存儲了數據0-9999,我現在的做法是想辦法讓10000個數進行隨機排列,便得到了這樣一個隨機數列,如果我只要其中的100個數,那么從前面取出100個就好。這里利用algorithm.h里面的一個函數,,來進行簡單處理。
template<class RandomAccessIterator> void random_shuffle( RandomAccessIterator _First, RandomAccessIterator _Last );
這個函數操作的對象是容器的迭代器,即我們需要將存儲數據從數組變為容器就好了,下面代碼實現一下:
1 #include <algorithm> 2 #include <iostream> 3 #include <vector> 4 5 using namespace std; 6 7 void randperm(int Num) 8 { 9 vector<int> temp; 10 for (int i = 0; i < Num; ++i) 11 { 12 temp.push_back(i + 1); 13 } 14 15 random_shuffle(temp.begin(), temp.end()); 16 17 for (int i = 0; i < temp.size(); i++) 18 { 19 cout << temp[i] << " "; 20 } 21 } 22 23 cout << endl;
給函數傳10為,參數,即生成一個從1-10的不重復隨機數,結果為:。
上面的方式只是一種,還有很多方式用以產生不重復隨機數,有興趣的朋友可以參考一下下面的連接:
http://www.hoopercao.com/2011/01/23/%E7%94%9F%E6%88%90%E4%B8%8D%E9%87%8D%E5%A4%8D%E7%9A%84%E9%9A%8F%E6%9C%BA%E6%95%B0%E7%9A%84%E6%96%B9%E6%B3%95/
http://www.cnblogs.com/afarmer/archive/2011/05/01/2033715.html
http://www.cnblogs.com/zuisanlang/archive/2011/12/09/2282960.html