是否有可能得到一个1-100之间的随机数,并将结果主要保持在40-60的范围内?我的意思是,它很少会超出这个范围,但我希望它主要在这个范围内……这是可能的JavaScript/jQuery?
现在我只使用基本的Math.random() * 100 + 1。
是否有可能得到一个1-100之间的随机数,并将结果主要保持在40-60的范围内?我的意思是,它很少会超出这个范围,但我希望它主要在这个范围内……这是可能的JavaScript/jQuery?
现在我只使用基本的Math.random() * 100 + 1。
当前回答
获取数字数组等并不是有效的。您应该采用一个映射,该映射采用0到100之间的随机数,并映射到所需的分布。在这个例子中,你可以取f(x)=-(1/25)x2+4x来得到在你的范围中间值最多的分布。
其他回答
最好的方法是生成一个随机数,该随机数平均分布在某一组数字中,然后对0到100之间的集合应用投影函数,其中投影更有可能击中你想要的数字。
通常,实现这一点的数学方法是绘制所需数字的概率函数。我们可以用钟形曲线,但为了计算方便,我们还是用翻转抛物线吧。
我们画一条抛物线,使它的根在0和100处,而不使它倾斜。得到如下方程:
f(x) = -(x-0)(x-100) = -x * (x-100) = -x^2 + 100x
现在,曲线下0到100之间的所有面积都代表了我们想要生成数字的第一个集合。在那里,生成是完全随机的。我们要做的就是求出第一个集合的上界。
下界当然是0。上限是函数在100处的积分,也就是
F(x) = -x^3/3 + 50x^2
F(100) = 500,000/3 = 166,666.66666 (let's just use 166,666, because rounding up would make the target out of bounds)
所以我们知道我们需要生成一个介于0到166666之间的数字。然后,我们只需要把这个数字投影到我们的第二个集合,它在0到100之间。
我们知道我们生成的随机数是输入x在0到100之间的抛物线的积分。这意味着我们只需假设随机数是F(x)的结果,然后解出x。
在这种情况下,F(x)是一个三次方程,形式为F(x) = ax^3 + bx^2 + cx + d = 0,下列表述成立:
a = -1/3
b = 50
c = 0
d = -1 * (your random number)
为x解出这个问题会得到你所寻找的实际随机数,它保证在[0,100]范围内,并且更接近中心而不是边缘。
var randNum;
// generate random number from 1-5
var freq = Math.floor(Math.random() * (6 - 1) + 1);
// focus on 40-60 if the number is odd (1,3, or 5)
// this should happen %60 of the time
if (freq % 2){
randNum = Math.floor(Math.random() * (60 - 40) + 40);
}
else {
randNum = Math.floor(Math.random() * (100 - 1) + 1);
}
分布
5% for [ 0,39]
90% for [40,59]
5% for [60,99]
解决方案
var f = Math.random();
if (f < 0.05) return random(0,39);
else if (f < 0.95) return random(40,59);
else return random(60,99);
通用解决方案
random_choose([series(0,39),series(40,59),series(60,99)],[0.05,0.90,0.05]);
function random_choose (collections,probabilities)
{
var acc = 0.00;
var r1 = Math.random();
var r2 = Math.random();
for (var i = 0; i < probabilities.length; i++)
{
acc += probabilities[i];
if (r1 < acc)
return collections[i][Math.floor(r2*collections[i].length)];
}
return (-1);
}
function series(min,max)
{
var i = min; var s = [];
while (s[s.length-1] < max) s[s.length]=i++;
return s;
}
针对这个问题的最佳解决方案是BlueRaja - Danny Pflughoeft提出的解决方案,但我认为一个更快、更通用的解决方案也值得一提。
当我必须生成随机数(字符串,坐标对等)时,满足的两个要求
结果集非常小。(不大于16K) 结果集是离散的。(只像整数)
我通常首先创建一个数字数组(字符串,坐标对等)来满足需求(在您的情况下:一个包含多次更可能的数字的数字数组),然后从该数组中随机选择一个项目。这样,每个项目只需要调用一次昂贵的随机函数。
当然这是可能的。随机抽取1-100。如果数字<30,则在1-100范围内生成数字,如果不在40-60范围内生成数字。