C/C++的线性同余法·C语言中标准库就是用线性同余产生器实现随机数的生成,其中各个参数的设置如下:m=231a=1103515245c=12345。这个算法的优势在于计算速度快,内存消耗少。并且可以看到它的随机数列周期为231。但是对于其它一些具体应用,随机数质量要求较高,比如像基于蒙特卡洛的算法粒子滤波器等就不适合用这种方法,因为对于这种算法而言,相邻的随机数并不独立,序列关联性较大。。C语言下随机数生成函数.声明在头文件stdlib.h中#include<cstdlib>int rand();●此函数提供均匀随机数的生成,均匀分布的范围是[O,RANDMAXI因为randO是按照指定顺序生成随机数的,所以如果每次随机种子相司,每次生成的随机数都是一致的
C/C++的线性同余法 #include <cstdlib>
C/C++的线性同余法if(fx<0.1) (f[0]+=1.0;1else if(fx<0.2) (#include<iostream>f[1]+=1.0;#include<cmath>1#include<cstdlib>#include<ctime>else(using namespace std;f[9]+=1.0;1int main()mean+=fx;variance+=fx*fx;double mean=0.0;1double variance=0.0;mean=mean/double(NN);double chi2=0.0;variance=sqrt(variance/double(NN)-mean*mean);double f[10];for(int i=0; i<10; i++)(for(int i=0; <10; i++) (chi2+=(f[i]-double(NN)/10.0)*(f[i]f[i]=0.;double(NN)/10.0)/(double(NN)/10.0);1chi2=chi2/10.0;srand(unsigned(time()cout<<"mean="<<mean<<endl;for(int i=O; i<NN; i++) (cout<<"variance="<<variance<<endl;doublefx=rand()/(double)RAND_MAX;cout<<"chi2="<<chi2<<endl;
C/C++的线性同余法 #include <iostream> #include <cmath> #include <cstdlib> #include <ctime> using namespace std; int main() { double mean=0.0; double variance=0.0; double chi2=0.0; double f[10]; for(int i=0; i<10; i++) { f[i]=0.; } srand(unsigned(time(0))); for(int i=0; i<NN; i++) { double fx=rand()/(double)RAND_MAX; if(fx<0.1) { f[0]+=1.0; } else if(fx<0.2) { f[1]+=1.0; } . else{ f[9]+=1.0; } mean+=fx; variance+=fx*fx; } mean=mean/double(NN); variance=sqrt(variance/double(NN)-mean*mean); for(int i=0; i<10; i++) { chi2+=(f[i]-double(NN)/10.0)*(f[i]- double(NN)/10.0)/(double(NN)/10.0); } chi2=chi2/10.0; cout<<"mean= "<<mean<<endl; cout<<"variance= "<<variance<<endl; cout<<"chi2= "<<chi2<<endl; }
反馈移位寄存器1965年,Tauisworthe发明了反馈移位寄存器方法,可以用以消除司余法中的关联问题。但后来发现情况并非那么简单,但至少但至少该方法提供了随机数产生的另一种途径。该方法是对整数进行位操作:首先用其它方法产生一个随机的整数序列,然后对两个整数进行XOR(异或)操作以产生一个新的随机整数0In=In-p④In-q●其中的p,ql是一对整数,最佳的选择是满足条件:p?+q?+1 =prime number。如:[31,3],[98,27],[250,103],[1279,(216,418)]等,其中的R250(p=250,q=103)是最为常用的产生器。一般来说[p,q]值越大,产生的随机数质量越好,而且起始的随机整数表的质量非常重要
反馈移位寄存器
反馈移位寄存器c中为m^n●Fortran中对两个整数m和n进行“异或”位操作的函数是IEOR(m,n),例如: I1 = 6,I148 =11,。则,I251=I1@I148=01101011=1101=23+22+2=13●程序中可写成NK)=IEOR(N(K-250),N(K-103)),要求数组N中存储所有之前的250个随机整数。当然要得到0.1区间的随机数需再除以m梅森旋转算法就是利用反馈移位寄存器产生随机数的,目前Python,Ruby,Matlab,C++11,中都有这个算法的实现。梅森旋转算法周期很长(219937-1),远高于线性同余算法的231。不同的算法在不同的场合下各有利整,统计检验也不能保证随机数的质量。一种产生器的好坏还是要在具体的应用中根据结果来判断。经验指出,一种新的随机数产生器要经过持久和广泛的应用累积才能知道它的各种隐含的缺陷
反馈移位寄存器 C 中为 m^n
CERNRoot随机数产生器1.Fromtheoriginal implementation inFORTRANbyFred JamesaspartofCLHEp.The initialisation is carried out using a Multiplicative Congruentialgeneratorusingformula constants of L'Ecuyerasdescribed in"F.James, Comp.Phys.Comm.60(1990)329-344"https:/root.cern.ch/doc/master/TRandom18cxxsource.html2.Randomnumbergeneratorclassbasedonthemaximallyguidistributedcombined Tausworthegeneratorby L'Ecuyer.Theperiod of thegeneratoris2**88(about10**26)anditusesonly3wordsforthestate.https://root.cern.ch/doc/master/classTRandom2.html3.TRandom3,isbasedonthe"MersenneTwistergenerator",andistherecommendedone,sinceithasgoodrandomproprieties(periodofabout10**6000)anditisfasthttp://root.cern.ch/root/html/TRandom3.htmlgRandom=newTRandom1/2/3(0);
CERN Root随机数产生器 1. From the original implementation in FORTRAN by Fred James as part of CLHEP. The initialisation is carried out using a Multiplicative Congruential generator using formula constants of L'Ecuyer as described in "F.James, Comp. Phys. Comm. 60 (1990) 329-344". https://root.cern.ch/doc/master/TRandom1_8cxx_source.html 2. Random number generator class based on the maximally quidistributed combined Tausworthe generator by L'Ecuyer. The period of the generator is 2**88 (about 10**26) and it uses only 3 words for the state. https://root.cern.ch/doc/master/classTRandom2.html 3. TRandom3, is based on the "Mersenne Twister generator", and is the recommended one, since it has good random proprieties (period of about 10**6000 ) and it is fast http://root.cern.ch/root/html/TRandom3.html gRandom = new TRandom1/2/3(0);