【问题标题】:Generate random integers with probabilities生成具有概率的随机整数
【发布时间】:2012-02-11 05:32:58
【问题描述】:

我对如何生成具有概率的整数值有点困惑。

例如,我有四个整数及其概率值:1|0.4、2|0.3、3|0.2、4|0.1

如何在考虑概率的情况下生成这四个数字?

【问题讨论】:

标签: javascript random probability


【解决方案1】:
let cases = {
  10 : 60,// 0-10 : 60  => 10%
  90 : 10,// 10-90 : 10  => 80%
  100 : 70,// 90-100 : 70 => 10%
};
function randomInt(){
  let random = Math.floor(Math.random() * 100);
  for(let prob in cases){
    if(prob>=random){
      return cases[prob];
    }
  }
}
console.log(randomInt())

【讨论】:

    【解决方案2】:

    这是我发现最灵活的解决方案,用于在任何一组具有概率的对象中进行选择:

    // set of object with probabilities:
    const set = {1:0.4,2:0.3,3:0.2,4:0.1};
    
    // get probabilities sum:
    var sum = 0;
    for(let j in set){
        sum += set[j];
    }
    
    // choose random integers:
    console.log(pick_random());
    
    function pick_random(){
        var pick = Math.random()*sum;
        for(let j in set){
            pick -= set[j];
            if(pick <= 0){
                return j;
            }
        }
    }

    【讨论】:

      【解决方案3】:

      我建议对概率和随机数的其余部分进行连续检查。

      此函数首先将返回值设置为最后一个可能的索引,然后迭代直到随机值的其余部分小于实际概率。

      概率之和必须为 1。

      function getRandomIndexByProbability(probabilities) {
          var r = Math.random(),
              index = probabilities.length - 1;
      
          probabilities.some(function (probability, i) {
              if (r < probability) {
                  index = i;
                  return true;
              }
              r -= probability;
          });
          return index;
      }
      
      var i,
          probabilities = [0.4, 0.3, 0.2, 0.09, 0.01 ],
          count = {},
          index;
      
      probabilities.forEach(function (a) { count[a] = 0; });
      
      for (i = 0; i < 1e6; i++) {
          index = getRandomIndexByProbability(probabilities);
          count[probabilities[index]]++
      }
      
      console.log(count);

      【讨论】:

        【解决方案4】:

        基于@bhups 答案的更灵活的解决方案。这使用概率值(权重)数组。 “权重”元素的总和应该等于 1。

        var weights = [0.3, 0.3, 0.3, 0.1]; // probabilities
        var results = [1, 2, 3, 4]; // values to return
        
        function getRandom () {
            var num = Math.random(),
                s = 0,
                lastIndex = weights.length - 1;
        
            for (var i = 0; i < lastIndex; ++i) {
                s += weights[i];
                if (num < s) {
                    return results[i];
                }
            }
        
            return results[lastIndex];
        };
        

        【讨论】:

          【解决方案5】:

          一个简单的天真的方法可以是:

          function getRandom(){
            var num=Math.random();
            if(num < 0.3) return 1;  //probability 0.3
            else if(num < 0.6) return 2; // probability 0.3
            else if(num < 0.9) return 3; //probability 0.3
            else return 4;  //probability 0.1
          }

          【讨论】:

          • 如果两个数字的概率相同怎么办? :-)
          • Sergio Tulentsev -> 轻松使用后续步骤之间的相同差异
          【解决方案6】:

          这是一个有用的技巧:-)

          function randomWithProbability() {
            var notRandomNumbers = [1, 1, 1, 1, 2, 2, 2, 3, 3, 4];
            var idx = Math.floor(Math.random() * notRandomNumbers.length);
            return notRandomNumbers[idx];
          }
          

          【讨论】:

          • 正确的方向,只需动态创建notRandomNumbers(给定数字及其权重/概率),我认为这是理想的解决方案。
          • 不错!谢谢。这看起来正是我所需要的。
          • @ShadowWizard:是的,为了清楚起见,我把它简单化了 :-)
          • 当然,我只是在等待更多解决方案来选择最好的解决方案;)
          • 我认为这不是一种有效的方法。假设我们有如下概率:[0.000000000001, 0.299999999999, 0.7],那么在这种情况下,notRandomNumbers 表会是什么?测验:它将使用多少内存?我宁愿说这是解决这个问题的最糟糕的方法。
          猜你喜欢
          • 1970-01-01
          • 2011-03-07
          • 1970-01-01
          • 1970-01-01
          • 2016-01-26
          • 2012-12-04
          • 2019-09-14
          相关资源
          最近更新 更多