产生a到b之间均匀分布的随机数
均匀分布(Uniform Distribution)
生成随机变量x,符合参数为(a,b)的均匀分布Unit(a,b),其概率密度分布函数为:
f(x)=1/(b-a), a<=x<=b
f(x)=0, x为其它
在计算机上可以用物理方法来产生随机数,但价格昂贵,不能重复,使用不便。另一种方法是用数学递推公式产生,这样产生的序列与真正的随机数序列不同,所以称为伪随机数或伪随机序列,只要方法和参数选择合适,所产生的伪随机数就能满足均匀性和独立性,与真正的随机数具有相近的性质。
(注:这里生成的随机数所处的分布为 0-1 区间上的均匀分布。不是 0-1 区间怎么办? 除以 (high-low), 再加上 low 就可以完成任务。我们需要的随机数序列应具有非退化性,周期长,相关系数小等优点。)
一般采用生成伪随机序列的方法得到均匀分布的随机数,有两个基本方法:乘同余法和混和同余法。
1. 乘同余法
乘同余法的迭代式如下:
Xn+1=Lamda*Xn(mod M)
Rn+1=Xn/M
当然,这里的参数选取是有一定理论基础的,否则所产生的随机数的周期将较小,相关性会较大。经过前人检验的两组性能较好的素数取模乘同余法迭代式的系数为:
Lamda=5^5,M=2^35-31
Lamda=7^5,M=2^31-1
实现代码(C语言)关键部分:
double long M;//请注意,这里一定要用到double long,否则计算2^32会溢出
float MyRnd()
{
Xn=fmod(Lamda*Xn,M);//here can's use %
Rn=Xn/M;
return Rn;
}
另外初始化段应有:
Lamda=pow(5,5);
M=pow(2,35)-31;
2. 混和同余法
混合同余法是加同余法和乘同余法的混合形式,其迭代式如下:
Xn+1=(Lamda*Xn+Miu)%M
Rn+1=Xn/M
经前人研究表明,在M=2^q的条件下,参数lamda,miu,X0按如下选取,周期较大,概率统计特性好:
Lamda=2^c+1,c取q/2附近的数
Miu=(1/2+sqrt(3))/M
X0为任意非负整数
实现代码(C语言)关键部分:
float MyRnd()
{
Xn=fmod(Lamda*Xn+Miu,M);
Rn=Xn/M;
return Rn;
}
另外初始化段应有:
M=pow(2,32);
Lamda=pow(2,16)+1;
Miu=(0.5+sqrt(3)/6)/M;