Fellow monks,
Disclaimers:
* This is more a call-for-code-feedback than a question...
* Please mentally perform s/random/pseudo-random/ on this post
A weighted random generator is needed when events should happen at random, but some should have a higher probability of happening than others ("All animals are equal, but pigs are more equal than the others" ... Orwell). For example, I'd like to decide between 0, 1 and 2 randomly, with 0 and 1 having an equal chance to be chosen, and 2 having a chance that is twice higher.
The following code shows a function implementing this weighted random generator, with some test code. Please tell me what do you think about it... Any obvious slumps ? What about efficiency ?
Thanks in advance
#!/usr/local/bin/perl -w
use strict;
# Given an array of weights, chooses an array element
# pseudo-randomly based on those weights.
#
# For example, given (1, 1.25, 3.6, 2)
# The chance that the 2nd element will be chosen is
# 3.6 times as large as the chance that the 0th element
# will be chosen
#
sub choose_weighted
{
my @weights = @{$_[0]};
my $acc = 0;
my @acc_arr;
foreach (@weights)
{
$acc += $_;
push(@acc_arr, $acc);
}
my $rand_val = $acc * rand;
my $i = 0;
++$i while ($acc_arr[$i] <= $rand_val);
return $i;
}
# Test code - just to prove that we get reasonable
# distributions
#
# With the test array used below, $count[3] obviously
# should be about twice as large as $count[1], etc...
#
my @ss = (1.75, 2, 3.6, 4);
my @count = (0, 0, 0, 0);
for (my $i = 0; $i < 500000; ++$i)
{
++$count[choose_weighted(\@ss)];
}
$, = "\n";
print @count;
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: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.