I've done this before, too, and I'd like to point out that the addition of 0.1 and the check of <= will throw off your probabilities. It may look right, and may even suffice for what you're doing, but it won't be the precise probabilities that you fed in at the top.

Also, I'd like to discourage the idea of separating the weights from the options. It's far, far too easy to get the quantities out of sync. Perl makes anon hashes and arrays so easy that there's no excuse to do this.

my @likelihood = (1, 3, 4, 9, 2, 8); my @option = qw(foo bar baz quux biz);
Oops! Maybe if we lined it up better ...
my @likelihood = (1, 3, 4, 9, 2, 8); my @option = qw(foo bar baz quux biz);
Now it's obvious. But what if we have 50 items? It'll scroll off the right side of the screen and be practically impossible to deal with. Better to use an AoA or AoH instead.
my @options = ( { name => 'foo', weight => 1 }, { name => 'bar', weight => 3 }, { name => 'baz', weight => 4 }, { name => 'quux', weight => 9 }, { name => 'biz', weight => 2 }, );
Back to your probabilities ... remembering that rand(n) gives you a random number such that 0 < rand(n) < n, theoretically with even distribution, you're getting a random number r that is 0.1 < r < n + 0.1, then truncating it. That gives you a 0.9/17 (or about 5.3%) chance of getting 0, plus a 1/17 chance (or about 5.9%) of getting a 1, both of which (total of about 11.2%) will get you 'foo' in your case. Meanwhile, 'bar', with a weight of 3, has a 3/17 chance, or 17.6%, of being selected, which does not seem to be a triple weight compared to 'foo' as one would expect. Finally, there is only a 0.1/17 chance (or about 0.6%) of getting 17, plus the other 8 numbers that get you your 'quux', which is much less than 9/17 chance.

Best, instead, to stick to int(rand($total_weight)) and comparing < instead of <=.


In reply to Re^2: Picking a random item through probability by Tanktalus
in thread Picking a random item through probability by muba

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.