Probability selection algorithm
Mike C. Fletcher
mcfletch at rogers.com
Sat Feb 1 18:10:12 EST 2003
Take the total of the entire set, do your random call, then use a
function such as indexOf below to get the index. There are probably
nicer approaches (such as using bisect on a list of transition-points),
but this should work fine.
import operator
def total( probset ):
return reduce( operator.add, probset )
def enumerate( probset ):
return map( None, range(len(probset)), probset)
def indexOf( value, probset ):
"""Get index of value in probset
value -- float value
values < 0 will return index 0
values > total(probset) will return len(probset)
probset -- sequence of partial float probabilities
"""
index = 0
for i,v in enumerate(probset):
value = value-v
if value <= 0:
return i
return len(probset)
Enjoy,
Mike
Noah wrote:
>I'm chewing over a little algorithm problem. It's a simple problem.
>Given a list of probabilities, what is the simplest way to randomly select
>one of the items from the list based on that item's probability?
>For example, here are some lists of probabilities:
> [0.2, 0.2, 0.2, 0.2, 0.2]
> items all have equal chance of getting selected (20%)
> [0.33, 0.33, 0.33]
> items all have equal chance of getting selected (33%)
> [0.33, 0.66]
> item 1 is twice as likely to get selected as item 0.
> [0.46, 0.27, 0.27]
> item 0 has slightly less than 50% chance of selection...
> [0.17, 0.62, 0.21]
> items have all unequal chances of selection.
>
>I can generate a random number between 0.0 and 1.0,
>but how do I turn that into an index into a given list?
>I was thinking that I could convert the lists of probabilities
>into lists of probability ranges. Then I would choose a random number
>between 0 and 1 and then select the item that falls in that range.
>For example the last list [0.17, 0.62, 0.21] would be converted to
>[0.17, 0.79, 1.0]
> if the random number is in the range 0.0-0.17 then select the first item.
> if the random number is in the range 0.17-0.79 then select the second item.
> if the random number is in the range 0.79-1.0 then select the third item.
>
>That seems like a crufty algorithm. There must be a simpler way.
>
>Yours,
>Noah
>
>
--
_______________________________________
Mike C. Fletcher
Designer, VR Plumber, Coder
http://members.rogers.com/mcfletch/
More information about the Python-list
mailing list