Randomizing with weighted probabilities


The question came up the other day of how to use Randomize Value by Range so that some values were more likely to come up than others. For example, suppose you wanted some shapes to be instanced 4 more times than some other shape…

From http://docs.python.org/3.2/library/random.html

A common task is to make a random.choice() with weighted probabilities.

If the weights are small integer ratios, a simple technique is to build a sample population with repeats:

>>>
>>> weighted_choices = [('Red', 3), ('Blue', 2), ('Yellow', 1), ('Green', 4)]
>>> population = [val for val, cnt in weighted_choices for i in range(cnt)]
>>> random.choice(population)
'Green'

So basically, if I want shape 1 to have a weight of 4 (so that roughly it is used 40% of the time), I would build an array that looks something like this:
[0, 0, 1, 1, 1, 1, 2, 2, 3, 3]
Then I generate a random integer and use it to select from that array. Because the “1” appears more often in the array, in the long run it should be more likely to be randomly selected.

Here’s an ICE tree where I apply this technique:
weighted-random
scn file here if you want it

This is what goes on inside the compound where I randomly select from the “weighted array” of possible shape IDs:
weighted-randomize

And here’s how I build an array with repeated values (the number of repetitions corresponds to the weight):
weighted-random3

To get an idea of whether this works on not, I keep track of the number of instances of each shape:
weighted-count-shapes

For example:
weight-example

5 thoughts on “Randomizing with weighted probabilities

  1. Hey this is sooo cool you decided to work on this question I posted on si-community.com !
    As I said on the forum I am not a coder at all, I just have a few basic knowledge in maths. However I dug into your compound and managed to perfectly understand how it works. Thank you so much ! You rules ! 🙂
    Just have one question :
    In the “build weight array” compound, is there a way to dynamically/automatically create as many “build array from constant” as there are objects in the group ? Say I have 100 objects in the group, I would save time not creating them and connecting them manually.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s