使用(负)指数分布生成介于0和1之间的随机数

4

嘿哟,

我正在尝试使用指数/负指数分布生成介于0.0和1.0之间的随机数。有一篇文章告诉我们需要获取"分位函数"。但是结果仍然大于1.0。因此,我需要以某种方式缩放我的方程。

我的目标是在一个范围内生成随机数,例如更高/更低的值具有更高的概率。(分布应该是可扩展的)

相关问题(不要将结果截断为[0,1]):


https://en.wikipedia.org/wiki/Exponential_distribution#Generating_exponential_variates - Oliver Charlesworth
当然,指数分布具有无限的尾部,因此您必须进行近似处理... - Oliver Charlesworth
@OliCharlesworth,也许有另一种分布(带有[0,1]),它的行为类似于指数函数,即x越高,y更高的概率越大,或者x越高,y更高的概率越小? - maxammann
3个回答

7
负指数分布的支持范围在[0,∞),因此我将您的问题解释为要求一个截断的负指数分布。具有下限l>= 0,上限h>l和速率λ的这种分布的累积分布函数为:
F(x) = (exp(-λl) - exp(-λx)) / (exp(-λl) - exp(-λh))

我们可以通过将其设置为 U ,一个均匀分布在(0,1)范围内的随机数,并解决x来找到反演:
X = -ln(exp(-λl) - (exp(-λl) - exp(-λh)) * U) / λ

由于你指定了下限和上限分别为0和1,因此这可简化为

X = -ln(1 - (1 - exp(-λ)) * U) / λ

U 替换为您喜欢的 U(0,1) 生成器的调用,这就是您生成具有所需分布的 X 的算法。

这是使用 λ = 5 生成的 10,000 个值的直方图。较小的 λ 值会产生更平坦的分布,而较大的值则显示更快的指数下降。

10,000 truncated exponentials with lambda = 5


谢谢啊,我觉得最难的任务就是获得我想要的东西,因为我也不确定。但这正是我在寻找的!(您也可以在此处测试它:http://www.petrileskinen.fi/random/randomDistribution.html)。您用哪个工具生成的直方图? - maxammann
我经常使用JMP进行统计分析。很高兴能够帮忙。 - pjs

2

根据您的评论,您希望较低和较高的数字都具有更高的可能性:

// let u,v be random real numbers from [1, 10]
x = log(u) // x is from 0.0 to 1.0, with higher probability getting higher values.
y = 1 - log(v) // y is from 0.0 to 1.0, with higher probability of getting lower values.
if abs(x - 0.5) > abs(y - 0.5):
    return x
else:
    return y

这有点不正规,但它使得获得恰好在中间值0.5的可能性极小,并且很可能得到边缘值。尽管如此,它似乎符合您的要求。
编辑:当x == y时,它需要进行一些微调。在这种情况下,您可以使用另一个随机选择来确定应选择哪个值:
if x == y:
    // let w be a random number either 1 or 2.
    if w == 1:
        return x
    else:
        return y

此外,如果应用程序需要将此功能变得更加或更少极性,它可以进行适应:
// let u,v be random real numbers from [1, K] where K > 1 
// and let j be a real number given by log(K).  j is selected by the function's caller.
x = log(u) / j
y = (1 - log(v)) / j
// The remainder of the formula is identical.

通过使用2这样的值来代替j,K = 100,则更可能成为极性值。如果使用小于10的值来代替j,则其不太可能成为极性值。以此方式你可以控制函数的“斜率”。


可能性是存在的,但不是非常灵活:P,随机生成器是为游戏而设计的,因此应该具有相当的可扩展性。 - maxammann
你希望它以什么方式“灵活”?我敢打赌我可以让它工作 - 只要告诉我。 - BlackVegetable
基本上,我想要一个函数,可以修改不同的常量,比如斜率。通过缩放这个斜率,高/低结果的概率就会改变。 - maxammann
我已经修改了这个答案,这样你可以编写一个函数来提供一个常量,以确定如何极化这个函数。j>1的值将使它更加极化。j<1的值将使它不那么极化。 - BlackVegetable
k,我需要先考虑一下这个:D 然后再回复你:D - maxammann

1
你可以使用Math.random()生成0.0到1.0之间的随机双精度数,然后简单地取结果的平方根。这样可以达到所需的效果(“我的目标是在一个范围内生成一个随机数,例如更高的值具有更高的概率。”)。
或者,这不是你想要的,因为它不是特定的指数分布,而是二次多项式?

这个方法是可行的,我之前也试过了。问题在于我还希望较小的值能够有更高的概率。 - maxammann
我用方程 f(x) = -x² + 1 进行了尝试,但是测试结果似乎并不匹配。它比指数函数更线性。 - maxammann
你想让较小的值具有更高的概率吗?因为你的问题表述了相反的意思。 - asaini007
基本上我想要能够两者兼顾。它还应该具有灵活性,这样更有可能获得更高的结果。 - maxammann
如果你对 Math.random() 取平方根,那么能否通过缩放输出来改变分布,使得更高的值比以前有更高的概率出现? - maxammann

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接