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;
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.