非常多人喜欢用 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,而不要在同一个程序中多次调用。
本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5146156.html,如需转载请自行联系原作者