Math.random()
返回一个带有“均匀”分布的伪随机数。
我需要生成一个在[0,1]范围内的随机数,该随机数偏向于两侧中的一侧。 (即更有可能获得靠近0或靠近1的数字)
理想情况下,我希望有一个参数来设置这个曲线。
我可以使用Math.random^2
来获得此结果,但还有什么更复杂的方法可以实现这一点?
Math.random()
返回一个带有“均匀”分布的伪随机数。
我需要生成一个在[0,1]范围内的随机数,该随机数偏向于两侧中的一侧。 (即更有可能获得靠近0或靠近1的数字)
理想情况下,我希望有一个参数来设置这个曲线。
我可以使用Math.random^2
来获得此结果,但还有什么更复杂的方法可以实现这一点?
我认为你想要 alpha=beta=0.5的beta分布
通过反向累积分布可以将均匀随机数转换为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;
return 1 - Number.EPSILON - a;
。虽然我不确定这是否会产生略小于0的值。 - tremby我认为你需要重新思考你的问题。泊松分布是一种计数分布,它是以速率为基础来指定的,例如在每个时间段内平均看到多少次某件事情的发生。它产生正整数,因此结果不能仅在[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))
<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);
还在jsfiddle上