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…
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:
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:
And here’s how I build an array with repeated values (the number of repetitions corresponds to the weight):
To get an idea of whether this works on not, I keep track of the number of instances of each shape:
I use a similar technique to generate fractals, maybe I should send you a screen grab.
If you have a sec, please do…I’d be interested to see it. thx
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.
Try this compound
You just enter a string of weights eg 0.1, 0.2, 0.7
Very interesting, it works like a charm.
Thanks again for your support ! Your blog is such a source of knowledge for me !