2

在java中,当我想生成一个高斯值时,我直接使用

Random r = new Random();
r.nextGaussian(); 

但现在我想生成一个概率为 1/x 的值,而不是高斯!

在我的解决方案中,我必须创建一个随机值,但这些值以越接近 1 开始,依此类推(有序)。例子 :

0.98
0.90
0.85
0.6
0.4
...

并不是

0.3
0.9
0.4
0.8
...

我们有关于 java 的解决方案吗?

4

3 回答 3

3

要找到以 为概率分布的值1/x

1/xis的积分ln x,正如@dbaupp 指出的那样,它无限增长。事实上,ln x当 x 接近 0 时,极限是无限的(负),当它增长到正无穷时,极限是无限的(正)。

所以我们必须将函数的范围限制在某个区间[min, max),其中min > 0和 都是有限的。

的倒数q = ln xx = e^q,所以分位数函数是e^[(ln max - ln min)q + ln(min)],其中 q 落在区间内[0,1)

经过一点代数,就变成了(max/min)^q * min=(max^q)(min^(1-q))

(我不确定哪种形式在数值上更稳定)

因此,将范围从 0 到 1 的均匀分布值(例如您从 nextDouble 获得的值)插入此函数将为您提供具有 apdf = 1/x且范围从给定最小值到最大值的值:

public static double reciprocalQuantile(double q, double min, double max) {
    return Math.pow(max, q)*Math.pow(min, 1-q);
}

所以你可以说:

Random rand = new Random();
double value = reciprocalQuantile(rand.nextDouble(), 0.0001, 10000);

我认为:-)请随时检查我的数学。

还有一点:您当然可以将 min 设置为 Double.MIN_VALUE 并将 max 设置为 Double.MAX_VALUE,但我对浮点表示的了解不够多,无法知道这是否会出现问题,如果是,那么我不知道一个数字需要多小/多才能变得如此。它也可能不是很有用。一个小测试显示了很多非常小的值和很多非常大的值——这并不奇怪,因为顶部和底部的积分接近无穷大。因此,要在中等范围内获得足够的值以获得漂亮的直方图,您需要很多值。

于 2012-04-30T14:00:27.880 回答
0

您可能需要实现自己的转换方法。从 Random 实例中,您可以获得用于以均匀概率获取数字的对象,并将这些作为输入到您的方法中,以将其转换为您喜欢的任何分布。因此,您将获取生成的数字,并将其用于计算 1/x(不确定您的意思是什么......)并根据需要返回该操作的结果......

于 2012-04-30T12:43:40.473 回答
-1
Random random = new SecureRandom();
double x = random.nextDouble();
return 1.0 / x; 

将为您在范围 [0.0, 1.0] 内为 x 提供值 1/x

编辑 - 不回答 OP 的问题,我误解了。

于 2012-04-30T12:37:33.737 回答