java 随机数 分布_Java:生成具有对数分布的随机数

我试图生成一个具有对数分布的随机数.

其中n = 1出现一半的时间,n = 2出现四分之一的时间,n = 3出现八分之一的时间,等等.

int maxN = 5;

int t = 1 << (maxN); // 2^maxN

int n = maxN -

((int) (Math.log((Math.random() * t))

/ Math.log(2))); // maxN - log2(1..maxN)

System.out.println("n=" + n);

大多数时候,我得到了我需要的结果,但是每隔一段时间,我得到一个大于maxN的n值.

为什么会这样?我看到它的方式,Math.random()的最大值是1.0;

因此(Math.random()* t))的最大值是t;

因此,log2(t)的最大值是maxN,因为t = 2 ^ maxN;

我的逻辑在哪里偏离轨道?

谢谢

解决方法:

数字小于1.0的对数为负数.当生成的随机数小于1.0时,表达式((int)(Math.log(Math.random()* t)/ Math.log(2)))是负数,因此maxN – (负数)大于maxN.

以下表达式应该给出正确的分布.

n = Math.floor(Math.log((Math.random() * t) + 1)/Math.log(2))

注意:

0.0 <= Math.random() <= 1.0

0.0 <= Math.random() * t <= t

1.0 <= (Math.random() * t) + 1 <= t + 1.0

0.0 <= Math.log((Math.random() * t) + 1) <= Math.log(t + 1.0)

0.0 <= Math.log((Math.random() * t) + 1)/Math.log(2) <= Math.log(t + 1.0)/Math.log(2)

Since t = 2^maxN,

Math.log(t + 1.0)/Math.log(2) is slightly larger than maxN.

So do a Math.floor and you get the correct result:

0.0 <= Math.floor(Math.log((Math.random() * t) + 1)/Math.log(2)) <= maxN

标签:logarithm,java,math,random,distribution

来源: https://codeday.me/bug/20190723/1517958.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值