2010-09-19 40 views
3

我试图用对数分布生成随机数。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;因此,由于t = 2^maxN,所以log2(t)的最大值是maxN。

我的逻辑走向何处?

感谢

回答

6

小于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 
+0

+1 @ abhin4v:感谢您的评论! – bguiz 2010-09-19 13:32:02

+0

我有支票,然后你拿了它! – 2010-09-19 13:47:11

+0

+ check @ abhin4v:你说得对log(t)/ log(2)> maxN 由于转换为int,错误是“隐藏的”,但这是一个更符合实际的正确方法。 – bguiz 2010-09-19 13:47:23

2

如果Math.random()*t是小于1,那么你会当你把Math.log(Math.random()*t),通过对数的规则得到了否定的回答。这意味着当您除以Math.log(2)时,您会得到否定答案,因为这是0.69314718055994530941723212145818。这是一个负数除以正数。答案是否定的。 maxN - 负数= maxN +正值,所以n大于maxN。为了解决这个问题铸造的Math.random()* T为int,并添加1:

int n = maxN - 
     ((int) (Math.log((int)((Math.random() * t)+1)) 
     /Math.log(2))); // maxN - log2(1..maxN) 

通知日志内的铸造,并且1.

加入一种将所述的目的的添加避免0.不能取0的日志。另外,不加1,你永远不会在日志中获得maxN,因为Math.random()永远不会产生1.这样,而不是得到1的一半,2,a第四,第三和第八,它只是从0开始。这给出了0,1,2,四分之一,2,8等。

+0

将小于1.0的数字投射到'int'将产生0,并记录它将产生'-Infinity'。因此你的建议是不正确的。 – 2010-09-19 13:18:44

+0

@ abhin4v:你将如何解决这个问题..有没有办法做到这一点,而不使用if-then-else类型的构造? – bguiz 2010-09-19 13:23:17

+0

我刚刚解决了这个问题。 – 2010-09-19 13:23:43

1

的问题是在天平的另一端。

请考虑如果您得到一个非常随机数会发生什么。