JavascriptMath.random()
返回一个具有“均匀”分布的伪随机数。
我需要在 [0,1] 范围内生成一个向任一侧倾斜的随机数。(意思是,在 0 或 1 旁边获得更多数字的机会更高)
理想情况下,我希望有一个参数来设置这条曲线。
我想我可以做得到Math.random^2
这样的结果,但是有什么更复杂的方法可以实现呢?
JavascriptMath.random()
返回一个具有“均匀”分布的伪随机数。
我需要在 [0,1] 范围内生成一个向任一侧倾斜的随机数。(意思是,在 0 或 1 旁边获得更多数字的机会更高)
理想情况下,我希望有一个参数来设置这条曲线。
我想我可以做得到Math.random^2
这样的结果,但是有什么更复杂的方法可以实现呢?
可以使用逆累积分布将均匀随机数转换为 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;
我只是想出了一种更简单的方法来让随机数偏向每一侧,并且没有任何依赖关系。
此方法使用两个 Javascript 的常规随机数。第一个与自身相乘(指数越大,偏斜效应越大),第二个选择要偏斜到分布的哪一侧。
function skewedRandom() {
const a = Math.pow(Math.random(), 2);
if (Math.random() < 0.5) {
return a;
}
return 1 - a;
}
在此代码中,指数设置为 2。来自 10,000 次执行的示例直方图,指数为 2,如上所示:
使用指数 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 生成一个值并在整个过程中使用它,这将是不正确的。
Yoy 可以在可用的情况下使用window.crypto.getRandomValues
<div id="result"></div>
var randVal = new Uint8Array(1);
window.crypto.getRandomValues(randVal);
document.getElementById("result").textContent = randVal[0] / 255;
(如果这是你的要求,我不确定)
或者也许像这样
<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);