> weight by the reciprocal of the votes
FWIW, here my attempts with different reciprocal functions and evaluation of distribution. See also Re^3: Randomly choosing from a set of alternatives with varying popularity for interpretation.
use strict;
use warnings;
use Data::Dump qw/pp dd/;
my %vote = ( alligator => 100, bear => 90, cat => 80, jellyfish => 10
+);
my $N =0;
$N += $_ for values %vote;
# --- invert by division, proportion of non-voters
my $N2 = 0;
my %vote2 = map {
my $v2 = 1/$vote{$_};
$N2 += $v2;
$_ => $v2
} keys %vote;
# --- invert by subtraction, number of non-voters
my $N3 = 0;
my %vote3 = map {
my $v3 = $N-$vote{$_};
$N3 += $v3;
$_ => $v3
} keys %vote;
my (%dist1,%dist2,%dist3);
my $e=5;
$dist1{pick($N,\%vote)}++ for 1..10**$e;
$dist2{pick($N2,\%vote2)}++ for 1..10**$e;
$dist3{pick($N3,\%vote3)}++ for 1..10**$e;
pp \%dist1,\%dist2,\%dist3;
sub pick {
my ($N,$h_vote)=@_;
my @deb;
my $r =rand($N);
push @deb,$r;
scalar keys %$h_vote; # reset each
while ( my ($k,$v) = each %$h_vote) {
$r -= $v;
push @deb,[$r,$k,$v];
return $k if $r <=0;
}
die "ERROR", pp \@deb;
}
OUTPUT:
(
{ alligator => 35891, bear => 31807, cat => 28792, jellyfish => 3510
+ },
{ alligator => 7497, bear => 8300, cat => 9481, jellyfish => 74722 }
+,
{ alligator => 21416, bear => 22542, cat => 23870, jellyfish => 3217
+2 },
)
On a tangent: had to debug why each failed me. Needed reset.