Two ideas (let me illustrate this with separate parameters and relationships for clarity in the argument names, if they are packed in a tuple, you can save the "zip"):
a) Denormalize the weights to get the whole relationship, then put as many copies as the ratio on the list and use random.choice .
def choice_with_ratios(options, ratios): tmp = sum([[v]*n for v, n in zip(options, ratios)], []) return random.choice(tmp)
b) Use normalized weights and start summing until you reach an arbitrarily generated uniform value
def choice_with_weights(options, weights): s = 0 r = random.random() for v, w in zip(options, weights): s += w if s >= r: break return v
By the way, if the first field is used as a key, you should have it in the dictionary, for example:
d = { 701: ((1, 0.2), (2, 0.3), (3, 0.5), 702: ((1, 0.3), (2, 0.2), (3, 0.5) }
fortran Jan 15 '10 at 17:23 2010-01-15 17:23
source share