Biased random?

Gabriel Genellina gagsl-py2 at yahoo.com.ar
Tue Aug 28 02:30:52 EDT 2007


En Mon, 27 Aug 2007 17:42:45 -0300, Ivan Voras <ivoras at __fer.hr__>  
escribi�:

> I have a list of items, and need to choose several elements from it,
> "almost random". The catch is that the elements from the beginning
> should have more chance of being selected than those at the end (how
> much more? I don't care how the "envelope" of probability looks like at
> this point - can be linear). I see that there are several functions in
> Python standard libraries for various distribution, but is there an easy
> pythonic way to make them do what I need?


Using a linear (or triangular) distribution:

--- begin ---
 from random import randint

def biased_choice(values):
     """Choose a random element from values;
     first elements are chosen more frequently than later ones.
     Weights are linearly assigned; given n elements, the first
     has weight n, second has n-1, ... last has weight 1.
     """
     n = len(values)
     sumw = ((n + 1) * n) // 2
     x = randint(1, sumw)
     F = 0
     for i in xrange(1, n+1):
         F += i
         if x<=F: return values[-i]

# test
 from collections import defaultdict
values = ["a", "b", "c", "d", "e"]
stats = defaultdict(int)
for i in xrange(150000):
     stats[biased_choice(values)] += 1
for key in sorted(stats):
     print key, stats[key]
--- end ---

Output:
a 50023
b 39869
c 30256
d 19784
e 10068

-- 
Gabriel Genellina




More information about the Python-list mailing list