2022年随机数的生成资料 .pdf
第一章随机数生成方法一、引言在 C+中常用的随机数生成方法是首先使用rand 函数生成一个随机数,然后将生成的随机数映射到所需要的区间。但是在使用rand 函数之前需要使用srand 设置初始“种子” ,以保证每次生成的随机数都不相同。在实际应用中,通常使用系统当前时间作为“种子”,这样生成的随机数更接近于实际意义的随机数。程序1 为生成指定区间的随机数的代码。程序 1 生成 start 到 end 之间的一个随机数template T random(T start, T end) return start+(end-start)*rand()/(RAND_MAX + 1.0); int main() srand(unsigned(time(0); int r = random(0,10) ; coutgenerate a random data in 0, 10: r endl; return 0; 但是以上的生成算法有两个问题:1.rand 生成的最大随机数为32767,有时无法达到我们的要求; 2.每个生成的随机数的概率未必相等,例如要生成0,30000 之间的随机数,这种做法就会导致后面生成的随机数的概率偏小。在唐纳德克努特(Donald Ervin Knuth) 的经典巨著计算机程序设计的艺术中,有一章专门介绍了生成随机数的方法。程序2 为来自 crafty19.3 的源码,它是对计算机程序设计的艺术中2.2.2 节的实现。程序 2 生成一个 32 位的随机数/*A 32 bit random number generator. An implementation in C of the algorithm given byKnuth, the art of computer programming, vol. 2, pp. 26-27. We use e=32, so we have to evaluate y(n) = y(n - 24) + y(n - 55) mod 232, which is implicitlydone by unsigned arithmetic.*/unsignedint Random32(void) /*random numbers from Mathematica 2.0.SeedRandom = 1;TableRandomInteger, 0, 232 - 1*/static constunsignedlong x55 = 1410651636UL, 3012776752UL, 3497475623UL, 2892145026UL, 1571949714UL, 3253082284UL, 3489895018UL, 387949491UL, 2597396737UL, 1981903553UL, 3160251843UL, 129444464UL, 1851443344UL, 4156445905UL, 224604922UL, 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 6 页 - - - - - - - - - 1455067070UL, 3953493484UL, 1460937157UL, 2528362617UL, 317430674UL, 3229354360UL, 117491133UL, 832845075UL, 1961600170UL, 1321557429UL, 747750121UL, 545747446UL, 810476036UL, 503334515UL, 4088144633UL, 2824216555UL, 3738252341UL, 3493754131UL, 3672533954UL, 29494241UL, 1180928407UL, 4213624418UL, 33062851UL, 3221315737UL, 1145213552UL, 2957984897UL, 4078668503UL, 2262661702UL, 65478801UL, 2527208841UL, 1960622036UL, 315685891UL, 1196037864UL, 804614524UL, 1421733266UL, 2017105031UL, 3882325900UL, 810735053UL, 384606609UL, 2393861397UL ; staticint init = 1; staticunsignedlong y55; staticint j, k; unsignedlong ul; if (init) int i; init = 0; for (i = 0; i 55; i+) yi = xi; j = 24 - 1; k = 55 - 1; ul = (yk += yj); if (-j 0) j = 55 - 1; if (-k 0) k = 55 - 1; return(unsignedint)ul); 二、生成大范围的随机数通常情况下可以使用将生成的多个随机数拼接在一起,以获得更大范围的随机数。人程序 3 拼接生成一个32 位的随机数long r = (long)rand()16) |(long)rand()8)&0 x0000FF00L) |(long)rand()&0 x000000FFL); 使用 STL 可以很方便的生成一个随机序列,其中主要是同generate 算法直接生成,程序 4 展示生成的过程。程序 3 通过 STL 的 generate生成随机序列#include #include #include #include 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 6 页 - - - - - - - - - #include using namespace std ; class rand_num public : rand_num(int m = 31) if( m31 ) throw range_error(range out ,please input integer in 1,31) ; mask = (1m)-1 ; long operator()() /重载()以方便 generate 算法的调用return (rand()&3)30)+(rand()15)+rand()&mask; private : unsignedlong mask ; /用于获得相应位数的随机数的掩码; int main() vector arr(10) ; srand(unsigned(time(0) ; rand_num r ; generate(arr.begin(), arr.end(), r) ; vector:iterator it = arr.begin(); while( it != arr.end() ) cout*it+ y); return x; 参数说明: double miu:,正态函数的数学期望double sigma:,正态函数的均方差double min, max : 表明产生的随机数的范围四、生成各不相同的随机数通常的生成随机数的做法是不考虑重复的,因为即使重复也属于概率意义上的正常情况。要产生一定范围内不可重复的随机数,最朴素的想法是把曾经生成的随机数保存起来作名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 6 页 - - - - - - - - - 为历史数据。 将每一个新产生的随机数都与历史数据进行比较,如果不相同则认为产生了一个新的随机数,否则丢弃后重新进行搜索。程序5 为这种思想的实现。程序 5 生成不重复的随机数/在min, max 区间生成 num个不相同的随机数int *random(int num, int min, int max) if( num max-min ) throw range_error(range error) ; int *result = new intnum; /用来保存随机生成的不重复的数int tmp = -1; bool repeat = false; for (int i = 0; i num; i+) repeat = false; tmp = random(min, max); for (int j = 0; j i; j+) if (tmp = resultj) repeat = true; break; if (!repeat) resulti = tmp; else i = i - 1; /循环变量 -1 return result ; 对于生成数量较少的随机数,这种方法简单易行,但是如果给出的范围比较小,那么新产生的随机数就会以极大的概率与已有的数据相同。为了达到较好的一种效果,通常使用额外的空间。 其主要的思想是:生成一个有序的互不相同的数列,生成一个小于序列长度的随机数, 并将序列中对应位置的元素作为结果,然后将序列最后一个元素复制到对应位置,序列长度减一,重复以上操作直到找到所有的数。程序6 为以上算法的实现。程序 6 生成不重复的随机数/生成 num个不相同的随机数int *random(int num) int indexRAND_MAX; for (int i = 0; i RAND_MAX; i+) indexi = i; int *result = new intnum; /用来保存随机生成的不重复的数int site = RAND_MAX; /设置下限int id; for (int j = 0; j num ; j+) 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 6 页 - - - - - - - - - id = random(0, site - 1); /在随机位置取出一个数,保存到结果数组resultj = indexid; /最后一个数复制到当前位置indexid = indexsite - 1; /位置的下限减少一site-; return result ; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 6 页 - - - - - - - - -