【问题标题】:Generate 4 random numbers that add to a certain value in Javascript在Javascript中生成4个随机数添加到某个值
【发布时间】:2013-10-17 03:54:30
【问题描述】:

我想要一些 javascript,它可以让我生成 4 个随机数,这些数字加起来等于某个值,例如

如果

max = 20

然后

num1 = 4
num2 = 4
num3 = 7
num4 = 5

max = 36

然后

num1 = 12
num2 = 5
num3 = 9
num4 = 10

到目前为止我所拥有的是......

var maxNum = 20;
var quarter;
var lowlimit;
var upplimit;
var num1 = 1000;
var num2 = 1000;
var num3 = 1000;
var num4 = 1000;
var sumnum = num1+num2+num3+num4;

quarter = maxNum * 0.25;
lowlimit = base - (base * 0.5);
upplimit = base + (base * 0.5);

if(sumnum != maxNum){
    num1 = Math.floor(Math.random()*(upplimit-lowlimit+1)+lowlimit);
    num2 = Math.floor(Math.random()*(upplimit-lowlimit+1)+lowlimit);
    num3 = Math.floor(Math.random()*(upplimit-lowlimit+1)+lowlimit);
    num4 = Math.floor(Math.random()*(upplimit-lowlimit+1)+lowlimit);
}

【问题讨论】:

  • 到目前为止你有什么?如果您有一些代码但不能正常工作或尚未完成,我们会为您提供帮助,但我们不会为您编写。
  • 您不能有 4 个随机数合计为预定值。如果你有 3 个随机数和总数,那么第 4 个不是随机数。
  • 提示:生成一个介于 1 和 max-3 之间的随机数 r1,然后生成另一个介于 1 和 max-2-r1 之间的随机数 r2,然后再生成一个介于 1 和 max-1-r1-r2 之间的随机数 r3 .剩下的数必须是max和其他三个数之差
  • @ChrisC 这不太对。如果我在 0 和 1 之间选择一个随机浮点数,那么 1-p 将与 p 一样随机。
  • 对不起,你是对的。我希望他们是 iid,但 OP 没有要求。

标签: javascript random numbers generator


【解决方案1】:

试试这个:

  1. 首先生成一个介于零和最大负 3 之间的数字(对于三个 剩下的数字)。
  2. 然后在第一个数字和最大值之间生成一个数字 负 2。
  3. 然后在第一个数字和第二个数字之间生成一个数字 最大减 1。
  4. 那么最后一个数字就是剩下的数字。

【讨论】:

  • 一开始你会得到一个更大的数字
【解决方案2】:

并不是说生成的随机数都应该是不同的,例如如果数字的总和应该是 4,则不可能。

<!DOCTYPE html>
<html>
<head>
    <title>Random numbers</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <script type="text/javascript">
        function randomSum(sum, nrOfNumbers) {
            var a = new Array(nrOfNumbers);
            var i = 0;
            var remainingSum = sum;
            while(i < nrOfNumbers) {
                if(i == (nrOfNumbers -1)) {
                    a[i] = remainingSum;
                }
                else {
                    // get a random number in range [0, remainingSum]
                    a[i] = Math.floor(Math.random() * (remainingSum + 1));
                    remainingSum -= a[i];
                }
                ++i;
            }
            return a;
        }
    </script>
</head>
<body>
    <script type="text/javascript">
        var randomNumbers = randomSum(20,4);
        for(var i in randomNumbers) {
            document.writeln(randomNumbers[i]+"<br>");
        }
    </script>
</body>
</html>

【讨论】:

  • 我认为这将允许有零......如果它对我来说可以,但对我来说没关系:-)
【解决方案3】:

此代码将创建四个整数,总和为最大数且不为零

var max = 36;
var r1 = randombetween(1, max-3);
var r2 = randombetween(1, max-2-r1);
var r3 = randombetween(1, max-1-r1-r2);
var r4 = max - r1 - r2 - r3;


function randombetween(min, max) {
  return Math.floor(Math.random()*(max-min+1)+min);
}

编辑:这将创建thecount 的整数个数,总和为max 并将它们返回到一个数组中(使用上面的randombetween 函数)

function generate(max, thecount) {
  var r = [];
  var currsum = 0;
  for(var i=0; i<thecount-1; i++) {
     r[i] = randombetween(1, max-(thecount-i-1)-currsum);
     currsum += r[i];
  }
  r[thecount-1] = max - currsum;
  return r;
}

【讨论】:

  • 但是这个解决方案不会对 4 个数字中的每一个产生不均匀的概率吗?第一个有 50% 的机会获得至少 50% 的整个“max-3”数字,而最后一个有 50% 的机会获得至少 50% 剩余的数字,这可能是这样小于第一个。 pastebin.com/QbsxvGXF
  • 我刚刚根据您的解决方案用我的解决方案回答了这个问题。
【解决方案4】:

对于我自己的项目,我找到了另一个可能对其他人有帮助的解决方案。

想法是让所有数字具有相同的概率......我想到的第一件事是创建一个长度为max的数组[1,2,3,..,N,undefined,undefined,....],将其打乱,并得到1,2,3,...,N的位置indexOf,但是对于大数字来说这很慢。

最后我找到了另一个我认为是对的解决方案:创建0到1之间的N随机数,这就是“他们想要取的”分数的一部分。如果所有数字都选择相同的数字(例如 1),它们都会得到相同的值。

代码,基于@devnull69的解决方案:

function generate(max, thecount) {
    var r = [];
    var currsum = 0;
    for(var i=0; i<thecount; i++) {
        r.push(Math.random());
        currsum += r[i];
    }
    for(var i=0; i<r.length; i++) {
        r[i] = Math.round(r[i] / currsum * max);
    }
    return r;
}

编辑:此解决方案与 Math.round 存在问题。假设我们想要 4 个数字加起来等于 20,并在执行 Math.round 之前得到这些数字:

 7.4 3.4 5.7 3.3 

如果将它们相加,它们的总和为 20。但如果应用 Math.round:

 7 3 6 3

他们加到 18。

然后在我的项目中,我不得不再做一轮,将那些“缺失”的值赋予具有更高小数部分的数字。这变得更加复杂,例如:

function generate(max, thecount) {
    var r = [];
    var decimals = [];
    var currsum = 0;
    for(var i=0; i<thecount; i++) {
        r.push(Math.random());
        currsum += r[i];
    }

    var remaining = max;
    for(var i=0; i<r.length; i++) {
        var res = r[i] / currsum * max;
        r[i] = Math.floor(res);
        remaining -= r[i];
        decimals.push(res - r[i]);
    }

    while(remaining > 0){
        var maxPos = 0;
        var maxVal = 0;

        for(var i=0; i<decimals.length; i++){
            if(maxVal < decimals[i]){
                maxVal = decimals[i];
                maxPos = i;
            }
        }

        r[maxPos]++;
        decimals[maxPos] = 0; // We set it to 0 so we don't give this position another one.
        remaining--;
    }

    return r;
}

【讨论】:

    【解决方案5】:

    任何语言的伪代码。

    a = rand()
    b = rand()
    c = rand()
    d = rand()
    
    total = a + b + c + d
    adjust = desiredNumber / total
    
    a *= adjust
    b *= adjust
    c *= adjust
    d *= adjust
    

    【讨论】:

      猜你喜欢
      • 2014-12-11
      • 1970-01-01
      • 1970-01-01
      • 2018-01-25
      • 1970-01-01
      • 1970-01-01
      • 2020-06-24
      • 2014-05-23
      • 2014-06-30
      相关资源
      最近更新 更多