How to generate a random weighted distribution of elements

前端 未结 4 346
执笔经年
执笔经年 2021-01-13 07:04

I would like to return an array which has a set of unique elements randomly distributed according to custom frequency. My real world use-case is the repetition of carousel i

4条回答
  •  执念已碎
    2021-01-13 07:13

    To expand on a_gupta's answer:

    function pick_bin(binProbabilities){     // e.g. [0.1, 0.3, 0.3, 0.3]
      var cumulative = [];                   // e.g. [0.1, 0.4, 0.7, 1]
      var accumulator = 0;
    
      // Iterating over an array with forEach:
      binProbabilities.forEach(function(item, index){
        var prob = Number(item);
        accumulator += prob;
        cumulative[index] = accumulator;
      })
    
      if(accumulator !== 1){
        throw new Error('Sum of binProbabilities must equal 1')
      }
    
      var n = binProbabilities.length;
      var rFloat = Math.random();
    
      // Iterating over an array with for:
      for(var i=0; i= rFloat){            // Found the first bin fitting the random number
          console.log(i);
          return i;
        }
      }
    }
    
    pick_bin([1]); // returns 0 every time
    pick_bin([.5, .5]) // returns 0,1 50/50
    pick_bin([0.1, 0.3, 0.3, 0.3])
    

    followup for your > 100% example, you can recalculate the weights to make them equal 1 (for a valid probability)

    Desired weightings:     20% 50% 80% 10%
    Sum these weights:      20 + 50 + 80 + 10 = 160
    Divide each by the sum: 2/16, 5/16, 8/16, 1/16
    Now they sum to 1
    

提交回复
热议问题