From: Mel on
southof40 wrote:

> I have list of of N Vehicle objects - the only possible vehicles are
> cars, bikes, trucks.
>
> I want to select an object from the list with a probability of : cars
> 0.7, bikes 0.3, trucks 0.1.
>
> I've currently implemented this by creating another list in which each
> car object from the original list appears 7 times, each bike 3 times
> and each truck once. I then pick at random from that list.

This seems about right. It's like a lottery where the more likely
winners have more tickets, but all tickets are the same. Pick one to
pick the winner.

There's a very expensive, but flexible technique that effectively gives
some tickets a better chance than others. You have to examine each
ticket individually, so this algorithm burns random numbers like
kindling:



import random

#===============================
def weighted_choice (candidates, weight):
chosen = None
total = 0
for c in candidates:
w = weight (c)
total += w
if random.randint (0, total-1) < w:
chosen = c
return chosen
#===============================

def test_weight (c):
return {'c':7, 'b':3, 't':1}[c]

def item_count (s, target):
return sum (1 for x in s if x==target)

test_candidates = 'c'*100 + 'b'*100 + 't'*100

for i in xrange (10):
test = [weighted_choice (test_candidates, test_weight) for k in xrange (100)]
for x in 'cbt':
print x, item_count (test, x), '\t',
print




Mel.