??????? 很多人喜歡用 rand()%n產生區間 [0,n]內的一個隨機整數。姑且不論這樣產生的整數是否仍然均勻分布,當 n大于 RAND_MAX 時,此法并不能得到期望的結果。由于RAND_MAX 很可能只是32767這么小,在使用此法時應當小心。
?
#include "stdio.h"
#include "stdlib.h"
#include "time.h"
int n=100,m=1000;double random()
{return (double)rand()/RAND_MAX;
}//產生[0,m-1]閉區間的隨機數
double random(int m)
{return (int)(random()*(m-1)+0.5);
}int main()
{srand(time(NULL)); //初始化隨機數種子 /*程序每次執行時使用一個不同的種子,因此用time.h 中的 time(NULL)為參數調用srand。函數返回值是自1970年1月1日0點以來經過的 "秒數" 。*/
// printf("RAND_MAX: %d\n",RAND_MAX); printf("%d %d\n",m,n); for(int i=0;i<m;i++){if(rand()%2==0) printf("A ");else printf("B ");int X,Y;for(;;){X=random(n)+1;Y=random(n)+1;if(X!=Y) break;}printf("%d %d\n",X,Y);}return 0;
} /*核心函數式stdlib.h中的rand(),它生成一個閉區間 [0,RAND_MAX]的均勻隨機整數(均勻的含義是:該區間內
每個整數被產生的概率相同) ,其中 RAND_MAX 至少為 32767(2^15-1),在不同環境下的值可能不同。嚴格地說,
這里的隨機數是"偽隨機數",因為它也是由數學公式計算出來的,不過在算法領域,多數情況下可以把它當作真正
的隨機數。 */
?
?????? 上述代碼采取的方法是先除以RAND_MAX,得到 [0,1] 之間的隨機實數,擴大n-1 倍之后四舍五入,再加1 得到 [1,n] 之間的均勻整數。這樣做在n很大時“精度”不好(好像把圖片放大后的“鋸齒”),但這里的 n 很小,這樣做已經可以滿足要求了。
?????? 程序最開始執行了一次 srand(time(NULL)),其中srand函數用來初始化“隨機數種子”。簡單地說,種子是偽隨機數計算的依據。種子相同,計算出來的“隨機數”序列總是相同。如果不調用srand而直接使用rand(),相當于調用過一次srand(1),因此程序每次執行,將得到同一套隨機數。另外,不要在同一個程序每次生成隨機數之間都重新調用一次srand。有的初學者抱怨“rand()產生的隨機數根本不隨機”,就是因為誤解了srand()的作用——再次強調,請只在程序開頭調用一次srand,而不要在同一個程序中多次調用。