用概率分布进行随机抽样的更好方法是什么?

时间:2017-07-05 01:52:49

标签: javascript arrays random

我想从数组中选择随机项,但具有一定的概率分布。 目前我这样做:     myarray =[5,5,5,95] 这让我有75%的几率获得95%的机会获得5%和25%的机会。

我有更多的数字,而且写出所有这些数字需要花费太多时间,是否有更快/更好的方法呢?

2 个答案:

答案 0 :(得分:3)

您可以拥有一个包含valuechance属性的对象的数组,该属性的值介于01之间。数组中所有chance属性的总和应该总和为1,然后你就可以得到这样的函数:



// data
var samples = [
  {
    value: 5,
    chance: .75
  }, {
    value: 95,
    chance: .25
  }
];

// requested method
function randomSample(samples) {
  var sample = Math.random();
  
  return samples.find(
    element => (sample -= element.chance) < 0
  ).value;
}

// demo
var counts = Array(100).fill()
  .map(() => randomSample(samples))
  .reduce((acc, val) => (acc[val]++, acc), { 5: 0, 95: 0});

console.log(counts);
&#13;
&#13;
&#13;

此方法的优点是对象不必按任何特定顺序位于数组中。

答案 1 :(得分:2)

&#13;
&#13;
function weightedChoice(array, weights) {
  let s = weights.reduce((a, e) => a + e);
  let r = Math.random() * s;
  return array.find((e, i) => (r -= weights[i]) < 0);
}

let randomArray =
    Array.apply(null, Array(32)).
    map(() => weightedChoice([5, 95], [75, 25]));
console.log(JSON.stringify(randomArray));
&#13;
&#13;
&#13;

编辑:帕特里克比我快一点,所以我会赞同他的答案,我只是补充一点,你绝对不需要总和为1,你可以规范化通过自己找出总和来加权。