How to retrieve a row, biased by populatity?
Chris Devers
cdevers at pobox.com
Tue Aug 21 21:38:06 BST 2012
On Tue, Aug 21, 2012 at 4:22 PM, Dave Hodgkinson <davehodg at gmail.com> wrote:
>
> Possibly a perl question. SQL would do...
>
> Given a set of data, say bands, with each having a ranking, either a
> review metric or a sales ranking, how would you retrieve a random
> row, but biased towards the higher ranking?
>
If you have access to a copy of _Mastering Algorithms with Perl_, it had
some examples like this in chapter 14.
The sample code can be downloaded from O’Reilly:
http://examples.oreilly.com/9781565923980/
The one you’re interested seems to be the rand-dist-weighted example,
pasted below:
$ cat rand-dist-weighted
#!/usr/bin/perl
# $selection = rand_dist_weighted( \%dist, \@key_order, $total_weight )
# Select an element from %dist. The total of the weights, and the
# keys sorted by their weights can be provided, or else they are
# computed.
sub rand_dist_weighted {
my( $dist, $key_order, $total_weight ) = @_;
my $running_weight;
$key_order = [ sort { $dist->{$a} <=> $dist->{$b} } keys %$dist ]
unless $key_order;
unless ( $total_weight ) {
foreach (@$key_order) { $total_weight += $dist->{$_} }
}
# Get a random value.
my $rand = rand( $total_weight );
# Use it to determine a key.
foreach my $key (@$key_order) {
return $key if ($running_weight += $dist->{$key}) >= $rand;
}
}
%smartie_weights = ( orange => 3, green => 10, pink => 8, brown => 10,
tan => 0, red => 6, blue => 11, yellow => 7,
purple => 5);
print rand_dist_weighted( \%smartie_weights ), "\n";
$smartie_weight = 0;
@smartie_order = sort { $smartie_weights{$a} <=> $smartie_weights{$b} }
keys %smartie_weights;
for (@smartie_order) { $smartie_weight += $smartie_weights{$_} }
for ( 0..50 ) {
print rand_dist_weighted( \%smartie_weights, \@smartie_order,
$smartie_weight ), "\n";
}
--
Chris Devers
More information about the london.pm
mailing list