Here's the code from the Perl Cookbook:
If you have a list of weights and values you want to randomly pick
from, follow this two step process: first, turn the weights into
a probability distribution with weight_to_dist below, then
use the distribution to randomly pick a value with weighted_rand:
# weight_to_dist: takes a hash mapping key to weight and returns
# a hash mapping key to probability
sub weight_to_dist {
my %weights = @_;
my %dist = ();
my $total = 0;
my ($key, $weight);
local $_;
foreach (values %weights) {
$total += $_;
}
while ( ($key, $weight) = each %weights ) {
$dist{$key} = $weight/$total;
}
return %dist;
}
# weighted_rand: takes a hash mapping key to probability, and
# returns the corresponding element
sub weighted_rand {
my %dist = @_;
my ($key, $weight);
while (1) { # to avoid floating point inac
+curacies
my $rand = rand;
while ( ($key, $weight) = each %dist ) {
return $key if ($rand -= $weight) < 0;
}
}
}
I hope this helps. I'm not sure how closely it approximates
your problem. Let me know if I can help more.
Nat