原创 随机数生成器

2007-5-27 11:42 3999 2 2 分类: 软件与OS

             周围同学有不少学计算物理的,自然有不少人寻求关随机数生成函数,于是以易用,高效的原则写了一个随机数生成器,希望对大家有所帮助,本人初学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中为几个有关怎样使用的例子;






vc++6.0默认编译内联函数展开项是关闭的,如果需要获得较高的效率,可以用cl命令的/Ob2优化编译:
 cl  /Ob2  /GX   文件名.cpp
 



运行速度比较: 
(1)若不用内联展开优化,a.rand0()执行100000000次约需18-20秒;若使用约需7-8秒,效率比较可观。
(2)直接运行
                       Zn=a*(Zn%q)-r*(Zn/q);
                        if(Zn<0)Zn+=m;   //将Zn调整为(0,m)之间的数
                   100000000次约需5秒;
(3)运行rand()100000000次约需2秒;





测试机型:pdf

文档下载:rar 


19:30:11 UTC+0800

文章评论0条评论)

登录后参与讨论
我要评论
0
2
关闭 站长推荐上一条 /2 下一条