Generate random integers with probabilities

前端 未结 5 841
离开以前
离开以前 2020-11-30 02:27

I\'m a bit confused about how to generate integer values with probabilities.

As an example, I have four integers with their probability values: 1|0.4, 2|0.3, 3|0.2,

相关标签:
5条回答
  • 2020-11-30 02:57

    I suggest to use a continuous check of the probability and the rest of the random number.

    This function sets first the return value to the last possible index and iterates until the rest of the random value is smaller than the actual probability.

    The probabilities have to sum to one.

    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);

    0 讨论(0)
  • 2020-11-30 03:15

    More flexible solution based on @bhups answer. This uses the array of probability values (weights). The sum of 'weights' elements should equal 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];
    };
    
    0 讨论(0)
  • 2020-11-30 03:15

    This is the solution i find the most flexible, for picking within any set of object with probabilities:

    // 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;
            }
        }
    }

    0 讨论(0)
  • A simple naive approach can be:

    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
    }

    0 讨论(0)
  • 2020-11-30 03:24

    Here's a useful trick :-)

    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];
    }
    
    0 讨论(0)
提交回复
热议问题