生成具有概率的随机整数

Posted

技术标签:

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

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

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

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

【问题讨论】:

如果您想了解有关如何快速完成此操作的大量技术细节,这是一个很好的资源。但是,对于在 4 个选项中进行加权选择,这是完全不需要的。 keithschwarz.com/darts-dice-coins 另见***.com/questions/3094873 【参考方案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 表会是什么?测验:它将使用多少内存?我宁愿说这是解决这个问题的最糟糕的方法。

以上是关于生成具有概率的随机整数的主要内容,如果未能解决你的问题,请参考以下文章

使用概率分布扩展整数的随机范围

合成法生成随机数原理

excel中RAND函数产生随机数的概率控制

生成具有给定分布的随机数

使用给定概率matlab生成随机数

python随机生成近100年内的200个人的生日,统计同一天出生的人数,并按照人数的多少从高到底排序?