是否有可能得到一个1-100之间的随机数,并将结果主要保持在40-60的范围内?我的意思是,它很少会超出这个范围,但我希望它主要在这个范围内……这是可能的JavaScript/jQuery?

现在我只使用基本的Math.random() * 100 + 1。


当前回答

几年前,我需要解决这个问题,我的解决方案比其他任何答案都要简单。

我在边界之间随机生成3个,然后取平均值。这将结果拉向中心,但完全有可能到达边缘。

其他回答

你有一些很好的答案,给出了具体的解决方案;让我给你描述一下通解。问题是:

我有一个在0到1之间或多或少均匀分布的随机数源。 我希望产生一个遵循不同分布的随机数序列。

这个问题的一般解决方案是计算出所需分布的分位数函数,然后将分位数函数应用于均匀源的输出。

分位数函数是你想要的分布函数的积分的倒数。分布函数是这样的函数,曲线的一部分下面的面积等于随机选择的项目将在该部分的概率。

我在这里给出一个如何做到这一点的例子:

http://ericlippert.com/2012/02/21/generating-random-non-uniform-data/

其中的代码是c#编写的,但原则适用于任何语言;它应该很容易适应JavaScript的解决方案。

用这样的东西怎么样:

var loops = 10; var tries = 10; var div = $("#results").html(random()); function random() { var values = ""; for(var i=0; i < loops; i++) { var numTries = tries; do { var num = Math.floor((Math.random() * 100) + 1); numTries--; } while((num < 40 || num >60) && numTries > 1) values += num + "<br/>"; } return values; } <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <div id="results"></div>

我的编码方式允许你设置几个变量: 循环=结果的数量 Tries =函数在停止while循环之前尝试获得40-60之间的数字的次数

额外的好处:它使用do while!!这是最棒的

最简单的方法是从0-50中生成两个随机数,然后将它们相加。

这给出了偏向50的分布,就像滚动两个骰子偏向7一样。

事实上,通过使用更大数量的“骰子”(如@Falco所建议的),你可以更接近钟形曲线:

function weightedRandom(max, numDice) {
    let num = 0;
    for (let i = 0; i < numDice; i++) {
        num += Math.random() * (max/numDice);
    }    
    return num;
}

JSFiddle: http://jsfiddle.net/797qhcza/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;
}

几年前,我需要解决这个问题,我的解决方案比其他任何答案都要简单。

我在边界之间随机生成3个,然后取平均值。这将结果拉向中心,但完全有可能到达边缘。