11

JavascriptMath.random()返回一个具有“均匀”分布的伪随机数。

我需要在 [0,1] 范围内生成一个向任一侧倾斜的随机数。(意思是,在 0 或 1 旁边获得更多数字的机会更高)

理想情况下,我希望有一个参数来设置这条曲线。

我想我可以做得到Math.random^2这样的结果,但是有什么更复杂的方法可以实现呢?

4

4 回答 4

17

我想你想要beta 发行版alpha=beta=0.5

可以使用逆累积分布将均匀随机数转换为 beta 分布。

unif = Math.random()

我不熟悉javascript,但这应该很清楚:

beta = sin(unif*pi/2)^2

PS:您可以生成许多这样的数字并绘制直方图 在此处输入图像描述

编辑:

对于向 0 倾斜,将beta值转换为 -

beta_left = (beta < 0.5) ? 2*beta : 2*(1-beta);

在此处输入图像描述

为了向 1 倾斜,变换为 -

beta_right = (beta > 0.5) ? 2*beta-1 : 2*(1-beta)-1;

在此处输入图像描述

于 2013-04-20T12:20:21.247 回答
4

我只是想出了一种更简单的方法来让随机数偏向每一侧,并且没有任何依赖关系。

此方法使用两个 Javascript 的常规随机数。第一个与自身相乘(指数越大,偏斜效应越大),第二个选择要偏斜到分布的哪一侧。

function skewedRandom() {
    const a = Math.pow(Math.random(), 2);
    if (Math.random() < 0.5) {
        return a;
    }
    return 1 - a;
}

在此代码中,指数设置为 2。来自 10,000 次执行的示例直方图,指数为 2,如上所示:

指数为 2 的直方图

使用指数 3:

指数为 3 的直方图

使用指数 10: 指数为 10 的直方图

于 2018-01-10T05:55:10.720 回答
3

我认为你需要重新考虑你的问题。Poisson 是一种以速率指定的计数分布,例如我在每个时间段内平均看到某事的发生次数。它产生正整数,因此结果不能仅在 [0,1] 范围内。你能澄清你想要什么吗?

无论如何,要生成具有速率 lambda 的泊松,一种算法是:

threshold = Math.exp(-lambda)
count = 0
product = 1.0
while (product *= rand) >= threshold {
      count += 1
}
return count

其中“rand”是对 Uniform(0,1) 的函数调用。我不知道javascript,但这应该足够简单,您可以实现。

回复编辑的问题:

有几种分布会在有界范围内产生结果,但其中许多并不适合胆小的人,例如 Johnson 家族或 Beta 分布。

一个简单的方法是三角形分布。Sqrt(rand) 将给出一个朝向 1 的三角形分布,而 (1-Sqrt(1-rand)) 将给出一个朝向零的三角形分布。

可以生成一个更一般的三角形,其模式(最常见的值)为 m(其中 0 <= m <= 1)

if rand <= m
    return m * Sqrt(rand)
else
    return 1 - ((1 - m) * Sqrt(1 - rand))

请注意,rand 的每次调用都是一个单独的统一随机数,如果您为 rand 生成一个值并在整个过程中使用它,这将是不正确的。

于 2013-04-19T18:14:02.790 回答
2

Yoy 可以在可用的情况下使用window.crypto.getRandomValues

<div id="result"></div>

var randVal = new Uint8Array(1);

window.crypto.getRandomValues(randVal);

document.getElementById("result").textContent = randVal[0] / 255;

jsfiddle 上

(如果这是你的要求,我不确定)

或者也许像这样

<div id="result"></div>

function poissonRandomNumber(lambda) {
    var L = Math.exp(-lambda),
        k = 0,
        p = 1;

    do {
        k = k + 1;
        p = p * Math.random();
    } while (p > L);

    return k - 1;
}

document.getElementById("result").textContent = poissonRandomNumber(100);

也在jsfiddle上

于 2013-04-19T18:29:05.843 回答