最近寫一個遺傳算法的程序,須要用到隨機數,很容易想到了C庫裏面的srand()和rand(),原本覺得很簡單的東西仍是用出了問題。找了些資料,最後才搞定,看似簡單的東西並不必定簡單。
簡單總結一下吧:
1.RAND_MAX
這個是stdlib.h裏面定義的一個宏,定義以下:
/*
* RAND_MAX is the maximum value that may be returned by rand.
* The minimum is zero.
*/
#define RAND_MAX 0x7FFF
說的很明白了,這是rand()函數可能返回的最大數,換成十進制就是32767,也就是說調用rand()函數返回結果是[0,32767]間的一個數,注意範圍,這是一個閉區間。
2.隨機數種子
通常應用都傾向於使用系統時間,因此通常初始化是這樣的:
srand((unsigned)time(NULL));
這樣一來就要包含time.h文件,也有包含windows.h而後調用windows的API來作初始化種子的,有興趣能夠去google之。
初始化隨機數種子只須要在調用rand()前執行一次就行了,一種常見錯誤就是在每次調用rand()前都調用srand()。
3.隨機數的範圍
rand()返回一個0~RAND_MAX的隨機數,通常這個不是你想獲得的數據範圍,須要進行調整,比較經常使用的是'%'和'/'操做,若是須要一個0~100的隨機數那麼就rand()%100好了,很容易理解。若是你須要一個浮點數,能夠考慮用除法,注意運算時的數據轉換操做,rand()返回的是整數,RAND_MAX也是整數,若是你想獲得一個0到1的浮點數,你這樣寫rand()/RAND_MAX你就大錯特錯了,這樣的結果是0,緣由仔細想一想也很簡答,基本的C語言運算數據類型提高問題,小數部分的尾巴取整的時候舍掉了,解決方法也很簡單rand()/(RAND_MAX-0.0),一個產生指定範圍隨機數的函數大概是這樣的:
double randval(double low, double high)
{
double val;
val = ((double)(rand()/(RAND_MAX-0.0))*(high - low)) + low;
return(val);
}
4.隨機數有多隨機
教科書上把這裏生成的隨機數叫作僞隨機數,也就是說仍是有規律的,至於什麼規律,我也不得而知:(