我正在尝试生成具有对数分布的随机数。
其中 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);
大多数时候,我得到了我需要的结果,但是每隔一段时间,我就会得到一个值n
大于maxN
.
为什么会这样呢?在我看来,最大值Math.random()
is 1.0;
因此最大值(Math.random() * t))
is t
;
因此 log2(t) 的最大值为 maxN,因为 t = 2^maxN;
我的逻辑哪里跑偏了?
Thanks
小于 1.0 的数的对数为负数。当生成的随机数小于 1.0 时,表达式((int) (Math.log(Math.random() * t) / Math.log(2)))
是一个负数,因此maxN - (the negative number)
大于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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)