VS2010中的C++产生各种“随机数”的方法(第2讲)——等概率随机量

第1讲已经详细介绍了rand()如何生成随机数的方法和基本原理。本讲我们介绍一些常见均匀随机量的生成方法:

一、闭区间[0, 1]上等概率随机小数的生成       
       x1 = rand()/(RAND_MAX+0.0) ,则x1~U[0,1]。
       如果是开区间(0, 1),则x2 = (rand()+1)/(RAND_MAX+2.0)。
       如果是半开半闭区间[0,1),则x3 = rand()/(RAND_MAX+1.0);  或者区间(0, 1],则x4 = (rand()+1)/(RAND_MAX+1.0)。
说明:1.这样生成的随机小数之间最小间隔为1.0/RAND_MAX(0至1之间最多分布RAND_MAX个不同的数);
           2.如果我们要提高均匀随机小数的分布密度,可以这样:x' = (rand()+rand()+...+rand())/(n*RAND_MAX+0.0),前面分子的rand()有n个,注意一定要离散写,因为每个rand()都是独立生成的不同随机数。

二、闭区间[float a, float b]上等概率随机浮点数的生成
      利用上面的结论,很容易知道x = x1 * float(b-a)+a ,即x~U[a,b]。
      区间为(a, b),[a, b)或(a, b]可同理推导。
说明:如果(b-a)的值很大,即a,b之间间隔很大,由于生成的所有x之间最小间隔为float(b-a)/RAND_MAX,例如如果a=0,b=RAND_MAX,则x = 0,1,2,...,RAND_MAX。所以为了提高生成的随机浮点数的分布密度,我们可以用上面的方法,即 x = x' * float(b-a)+a 。    

三、闭区间[int a, int b]上等概率随机整数的生成
      利用第一、第二的结论,生成[a, b]上等概率随机整数的公式为:k = int(x3 * float(b+1-a)+a),其中x3~U[0, 1),该方法先生成[a, b+1)上的均匀随机浮点数,然后取整,这样[a,a+1)上的浮点数取整为a,[a+1,a+2)上的浮点数取整为a+1,...,[b,b+1)上的浮点数取整为b,保证了可以得到[a, b]上所有随机整数,且取每一个的概率都相同。
      当(b-a)的值很大,即a,b之间间隔很大,同理可以用“第二”的方法提高随机分布“均匀性”!
说明:这个地方网上很多教程给的公式都是k = rand()%(b-a+1)+a,这样是不严密的!!!仅仅当(b-a)远远小于RAND_MAX时,该方法可行;但是当(b-a)比较大,例如a=0,b=20000时,这样产生的随机整数并不是“等概率”的。为什么呢?因为rand()产生的随机整数为0~RAND_MAX(=32767),整数0和20000生成的概率就不一样,rand()为0和20001时,生成的随机数都是0,但是生成整数20000却仅当rand()=20000,很明显生成0和20000的概率不相等!!!(楼主亲测)

四、三维空间沿任意方向等概率单位随机向量N = {x,y,z}的生成

float x,y,z,length;
while(1)
{
   x = -1+2*rand()/(RAND_MAX+0.0);
   y = -1+2*rand()/(RAND_MAX+0.0);
   z = -1+2*rand()/(RAND_MAX+0.0);
     if((length=x*x+y*y+z*z)<=1)  //Notice this!
             break;
}
length = sqrt(length);
float N[3] = {x/length,y/length,z/length};


 上图为空间一个包围单位球的单位立方体,生成的单位随机向量可以沿球上任何方向。如果要生成n维单位随机向量,只需将上面代码推广到n个指标!

这一讲就到此结束,第三讲讨论不等概率随机量的生成!!!

 

 

     

     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值