A weighted version of random.choice

后端 未结 25 1888
闹比i
闹比i 2020-11-21 06:29

I needed to write a weighted version of random.choice (each element in the list has a different probability for being selected). This is what I came up with:



        
25条回答
  •  太阳男子
    2020-11-21 06:59

    I'm probably too late to contribute anything useful, but here's a simple, short, and very efficient snippet:

    def choose_index(probabilies):
        cmf = probabilies[0]
        choice = random.random()
        for k in xrange(len(probabilies)):
            if choice <= cmf:
                return k
            else:
                cmf += probabilies[k+1]
    

    No need to sort your probabilities or create a vector with your cmf, and it terminates once it finds its choice. Memory: O(1), time: O(N), with average running time ~ N/2.

    If you have weights, simply add one line:

    def choose_index(weights):
        probabilities = weights / sum(weights)
        cmf = probabilies[0]
        choice = random.random()
        for k in xrange(len(probabilies)):
            if choice <= cmf:
                return k
            else:
                cmf += probabilies[k+1]
    

提交回复
热议问题