周围同学有不少学计算物理的,自然有不少人寻求关随机数生成函数,于是以易用,高效的原则写了一个随机数生成器,希望对大家有所帮助,本人初学c++,里面bug也是不少的,欢迎高手的指正^_^.
说明:
c++/c标准库/中定义了随机数生成函数
int rand(void):每次调用返回【0,RAND_MAX】之间的整数;
void srand(unsigned seed):设置随机数种子
库函数当然有高效,易用等优点,但是rand()使用的是【0,2^16-1】16位算法,周期比较短(2^16),如果要在32位机上产生质量和周期比较好的随机数,还需用Schrage算法(参见丁泽军的《计算物理》[下载需打开intenet选项最后一项]),另外如果想定义多维数也是不可能的,这两点都对蒙特卡罗方法不利。
如果随机数周期要求不高 rand()还是很不错的。
rand.h中定义了
(1)Schrage类:
m0引用参数m
a0引用参数b
b0引用参数b
rand0(long int& seed):利用公式Zn=a×Zn%m生成随机数。
rand1(long int& seed):利用公式Zn=(a×Zn+b)%m生成随机数。
原则上定义一个Schrage类,再定义一个种子,便可生成随机数,但这样易用性比较差。
(2)long int tmseed(int dt)函数:在当前系统时间上加dt秒生成一个种子。
(3)randomer类模板
静态成员rdm: Schrage类,是所有随机数生成器的内核,默认设置为16807生成器。可以用randomer::set()函数设置rdm的a,b,m参数,
静态成员delta_t: 可以使得每个生成器默认起始种子不同。(因为 this->seed=tmseed(delta_t++));
randomer(T mod="1"): 定义为【0,mod)区间均匀分布的T型随机数生成器,默认【0,1)。
T mod(): 返回生成器的模;
setmod(mod): 设置生成器的模,设置为【0,mod)区间均匀分布的T型随机数生成器;
setseed(long int seed):设置随机数种子,需要从系统时间设置可用setseed(tmseed(0));
T rand0(void): 内联函数,利用公式Zn=a×Zn%m生成随机数。
T rand1(void): 利用公式Zn=(a×Zn+b)%m生成随机数。
T operator ()(int i="0",bool w="0"):利用 rand0()[w=0时]或rand1()[w=1时]连续执行n+1次,输出随机数(相当于用rand?()跳过n次,再用用rand?()输出)。
可用 ()替代rand0(),但是执行效率会降低。
一个randomer对应一个种子,实现seed与rdm封装,想定义多维种子定义多个randomer即可。
除非必要,rdm内核不要更改,16807生成器毕竟是通过大量验证的。
how_to_use.cpp中为几个有关怎样使用的例子;
19:30:11 UTC+0800
文章评论(0条评论)
登录后参与讨论