Javascript的Math.random()
返回带有“统一”分布的伪随机数。
我需要生成一个偏向任一侧的[0,1]范围内的随机数。 (意思是,在0或1旁边获得更多数字的机会更高)
理想情况下,我希望有一个参数来设置此曲线。
我认为我可以Math.random^2
来获得这样的结果,但是有什么更复杂的方法来实现这一目标?
答案 0 :(得分:15)
我想你想要beta distribution with alpha=beta=0.5
可以使用逆累积分布将均匀随机数转换为β分布。
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;
答案 1 :(得分:3)
我认为你需要重新考虑你的问题。泊松是根据速率指定的计数分布,例如每个时间段平均看到的事物的出现次数。它产生正整数,因此结果不能只在[0,1]范围内。你能澄清一下你想要的吗?
无论如何,要生成具有速率λ的泊松,一个算法是:
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都是一个单独的Uniform随机数,如果为rand生成一个值并在整个过程中使用它,这将不正确。
答案 2 :(得分:3)
我想出了一种更简单的方法,可以将随机数倾斜到每一侧,并且没有任何依赖关系。
此方法使用两个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:
答案 3 :(得分:2)
您可以在可用的情况下使用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);
也在jsfiddle
上