Randomly choosing from a list with weighted probabilities

前端 未结 2 1980
一个人的身影
一个人的身影 2020-12-03 03:50

I have an array of N elements (representing the N letters of a given alphabet), and each cell of the array holds an integer value, that integer value meaning the number of o

相关标签:
2条回答
  • 2020-12-03 04:08

    The Alias Method has amortized O(1) time per value generated, but requires two uniforms per lookup. Basically, you create a table where each column contains one of the values to be generated, a second value called an alias, and a conditional probability of choosing between the value and its alias. Use your first uniform to pick any of the columns with equal likelihood. Then choose between the primary value and the alias based on your second uniform. It takes a O(n log n) work to initially set up a valid table for n values, but after the table's built generating values is constant time. You can download this Ruby gem to see an actual implementation.

    Two other very fast methods by Marsaglia et al. are described here. They have provided C implementations.

    0 讨论(0)
  • 2020-12-03 04:22

    The idea:

    • Iterate through all the elements and set the value of each element as the cumulative frequency thus far.
    • Generate a random number between 1 and the sum of all frequencies
    • Do a binary search on the values for this number (finding the first value greater than or equal to the number).

    Example:

    Element    A B C D
    Frequency  1 4 3 2
    Cumulative 1 5 8 10
    

    Generate a random number in the range 1-10 (1+4+3+2 = 10, the same as the last value in the cumulative list), do a binary search, which will return values as follows:

    Number   Element returned
    1        A
    2        B
    3        B
    4        B
    5        B
    6        C
    7        C
    8        C
    9        D
    10       D
    
    0 讨论(0)
提交回复
热议问题