如何在javascript中获得与特定数字相等的随机数

How to get random numbers to equal a specific number in javascript?

本文关键字:数字 随机数 javascript      更新时间:2023-09-26

好吧,我的问题是我有三个随机数生成器,我希望所有三个随机生成的数字(从1-5生成)的值加起来为9。例如,我随机生成一个4、一个3和一个2。再点击一次按钮,就会得到一个5、一个3和一个1。我试着做了一段时间,但就是想不通。

        function statGen() {
            var x = document.getElementById("number");
            x.innerHTML = Math.floor((Math.random() * 5) + 1);
            var a = document.getElementById("agl");
            a.innerHTML = Math.floor((Math.random() * 4) + 1);
            var l = document.getElementById("lck");
            l.innerHTML = Math.floor((Math.random() * 3) + 1);
        }
 <button id="statbutton" onclick="statGen()">Get Numbers</button>       
        <p id="main">Main:</p>
        <p id="number"></p>
        <br/>
        <p id="Agl">Agl:</p>
        <p id="agl"></p>
        <br/>
        <p id="Lck">Lck:</p>
        <p id="lck"></p>

我试过多次在循环中运行它,直到它变成数字9,但都不起作用。

到目前为止,所有的答案都没有很好的随机性。通过选择第一个数字,然后选择第二个数字,再选择第三个数字,你会有很大的极端倾向。

让我举一个骰子的例子来说明。假设你想掷三个骰子,它们加起来是8。如果你一次滚动一个,那么你最终得到的排列有1/6的机会是[6,1,1]。这是因为在你滚动了6(以1/6的概率)之后,剩下的唯一可接受的数字是1和1。

实际上,[6,1,1]并不是所有可接受轧辊的1/6。例如,从3开始,得到[3,1,4],[3,2,3],[3、3,2],[3。因此,将3作为第一个数字的可能性应该是6的四倍。但其他方法并非如此!

因此,有几种方法可以获得"良好"的随机性。最简单的方法实际上是将三个"骰子"全部掷下,如果结果不符合您的限制,则再次掷下。

function roll() {
   return Math.floor(Math.random() * 5 + 1); //1-5 uniformly
}
function chooseNumbers() {
   var x = 0, y = 0, z = 0;
   while (x + y + z !== 9) {
      x = roll();
      y = roll();
      z = roll();
   }
   return [x, y, z];
}

对于大多数目的来说,这将是非常快的,但你最终会抛出相当多的面包卷。另一种选择是枚举(使用代码或手动)可能具有的所有排列,然后使用统一随机数选择索引。

var permutations = [
   [5, 3, 1],
   [5, 2, 2],
   [5, 1, 3],
   [4, 4, 1],
   //...
   [1, 3, 5]
];
function chooseNumbers() {
   return permutations[Math.floor(Math.random() * permutations.length)];
}

最后一个随机数r3取决于r1r2,因此它被认为是随机的。

    function statGen() {
        var x = document.getElementById("number");
        var r1=Math.floor((Math.random() * 9) + 1);
        var r2=Math.floor((Math.random() * (8-r1)) + 1);
        var r3=9-r1-r2;
        x.innerHTML = r1;
        var a = document.getElementById("agl");
        a.innerHTML = r2;
        var l = document.getElementById("lck");
        l.innerHTML = r3;
    }

Mark Peters在他的回答中概述了两种方法。第一种方法是一种蛮力方法:生成三个随机数的组,直到找到一个和为9的随机数。第二种方法是将所有28种可能的排列形式制成表格,然后随机选择一种。

第一种方法可能较慢,第二种方法将消耗更多内存。只要您只需要执行一次,并且所需的三个数字之和很小(如9),那么您使用哪一个数字没有太大区别。

但是,如果所需的金额很大,您可能需要一种不同的方法。假设所需金额为100万。暴力手段可能相当缓慢。对的所有排列进行制表可能会消耗太多内存(或磁盘空间,具体取决于实现)。

排列的总数是整数1到最大可能值的总和。使用数学堆栈交换:中的公式可以快速计算出这个总和

取第一个数字和最后一个数字的平均值,然后乘以数字的数量。

因此,在这种情况下,排列的总数几乎是1,000,000 x 500,000;关于CCD_ 6排列。

因此,我们可以生成一个随机数n,并在给定所需和的情况下仅计算第n个排列,而不是计算所有可能的排列:

function getPermutation( n, requiredSum) {
  var remainder = n;
  var step = requiredSum - 2;
  var firstNumber = 1;
  while(remainder > step){
    firstNumber++;
    remainder -= step;
    step--;
  }
  var secondNumber = remainder;
  var thirdNumber = requiredSum - firstNumber - secondNumber;
  return [ firstNumber, secondNumber, thirdNumber ];
}

此处的示例:

$(document).ready( function(){
  $("button").click( function() {
    $("div").text( JSON.stringify( get3Numbers(1000000) ) );
  });
});
function get3Numbers(requiredSum){
  var maximum = requiredSum - 2;
  var permutations = maximum * ( (maximum + 1.0) / 2.0);
  var randomNumber = Math.floor((Math.random() * permutations) + 1);
  var threeNumbers = getPermutation(randomNumber, requiredSum);
  var sumOfNumbers = threeNumbers[0] + threeNumbers[1] + threeNumbers[2];
  return {
    threeNumbers: threeNumbers,
    total:  sumOfNumbers
  };
}
function getPermutation( n, requiredSum) {
  var remainder = n;
  var step = requiredSum - 2;
  var firstNumber = 1;
  while(remainder > step){
    firstNumber++;
    remainder -= step;
    step--;
  }
  var secondNumber = remainder;
  var thirdNumber = requiredSum - firstNumber - secondNumber;
  return [ firstNumber, secondNumber, thirdNumber ];
}
div {
    border: 1px solid silver;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>&nbsp;</div>
<button>Get three numbers!</button>

类似的东西?(这是伪代码):

var first = Math.floor((Math.random() * 5) + 1);
var second = Math.floor((Math.random() * 8-first) + 1);
var third = Math.floor((Math.random() * 9 - (first+second);

如果您需要保证3个数字,除非您接受0作为第三个可能的数字,否则前两个数字的总和应小于或等于8。

这里有一种方法。

function statGen() {
    var x = document.getElementById("number");
    var firstNumber = Math.floor((Math.random() * 5) + 1);
    x.innerHTML = firstNumber;
    var a = document.getElementById("agl");
    if (firstNumber == 5) {
        var secondNumber = Math.floor((Math.random() * 4) + 1);
    } else {
        var secondNumber = Math.floor((Math.random() * 5) + 1);
    }
    a.innerHTML = secondNumber;
    var l = document.getElementById("lck");
    l.innerHTML = 9-(firstNumber + secondNumber);
 }
 <button id="statbutton" onclick="statGen()">Get Numbers</button>       
        <p id="main">Main:</p>
        <p id="number"></p>
        <br/>
        <p id="Agl">Agl:</p>
        <p id="agl"></p>
        <br/>
        <p id="Lck">Lck:</p>
        <p id="lck"></p>