in reply to Re^4: Picking a random item through probability
in thread Picking a random item through probability

List::Util - yeah, it was other monks who introduced me to this module. I've made good use of it since ;-)

Back to your question ... Let's say that the number we get is "5". Looking at this list, that should result in picking "baz". How do we do that? We look at the numbers: the first weight is one. So that would be a pick of 0. That's not it. So then the next option, 'bar', has a weight of 3. So that will cover picks 1-3. But we have 5, so that's not in range, either. Next option has a weight of 4 - numbers 4-7. We have 5. Got it.

That's the straight-forward approach. The convoluted approach reverses this. We start with the first option, and discover that it has a weight of 1. So, now we look at the number - if the number were 0, this would be a match. If the number were 1, it isn't. So we could simply check if $pick < $weight and return 1, otherwise we just subtract the weight from our pick, and check the next number. However, since we're in a block, not a sub, we need to be a bit more tricky. So, we do a bit of algebraic magic, and we come up with $pick - $weight < 0, and we still want to subtract the weight before going on to the next one. Finally, we just do the subtraction first, and let $pick < 0 be our boolean return from the block.

  • Comment on Re^5: Picking a random item through probability

Replies are listed 'Best First'.
Re^6: Picking a random item through probability
by doom (Deacon) on Nov 24, 2006 at 01:02 UTC
    While we're plugging modules, in addition to List::Util I recommend looking at List::MoreUtils (note the irregular naming, plural "Utils"). This is pretty useful, if only for the "any":
    print "At least one value undefined" if any { !defined($_) } @list;

    Which is not as clean as the syntax of the "any" in Damien Conway's Quantum::Superpositions , but it has the virtue of not requiring the use of a deranged Damien Conway module...

    I'm also a fan of: Hash::Util. Being able to lock the keys on a hash is a great trick to catch typos.

    And I see there's also a Hash::MoreUtils but that's one I haven't played with yet.

Re^6: Picking a random item through probability
by muba (Priest) on Nov 23, 2006 at 22:51 UTC
    That does it for me. Thank you for your simple, straight-forward solution and explanation (or convoluted, then, but still... I was worrying it would take dozens of lines of code etc)