in reply to Re^2: an algorithm to randomly pick items that are present at different frequencies
in thread an algorithm to randomly pick items that are present at different frequencies
Then something like this should do the trick:
#! perl -slw use strict; use Data::Dump qw[ pp ]; sub genPicker { my $fh = shift; my( @vals, @odds ); ( $vals[ @vals ], $odds[ @odds ] ) = split( ' +' ) for <$fh>; ## Sort if not sorted my @order = sort{ $odds[ $a ] <=> $odds[ $b ] } 0 .. $#odds; @odds = @odds[ @order ]; @vals = @vals[ @order ]; ## Calculate and accumulate break points my $t = 0; $t += $_ for @odds; $_ /= $t for @odds; $odds[ $_ + 1 ] += $odds[ $_ ] for 0 .. $#odds - 1; ## Generate a subroutine to do the picking return sub { my $r = rand(); $r < $odds[ $_ ] and return $vals[ $_ ] for 0 .. $#odds; }; } my $pick = genPicker( *DATA ); ## run a quick test my %tally; ++$tally{ $pick->() } for 1 .. 10e6; pp \%tally; __DATA__ A 1e-7 B 20e-7 C 10e-5
Produces:
C:\test>1127420 { A => 9949, B => 195307, C => 9794744 } C:\test>1127420 { A => 10077, B => 196613, C => 9793310 }
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^4: an algorithm to randomly pick items that are present at different frequencies
by efoss (Acolyte) on May 27, 2015 at 05:40 UTC | |
by BrowserUk (Patriarch) on May 27, 2015 at 05:46 UTC | |
by efoss (Acolyte) on May 27, 2015 at 19:01 UTC | |
by BrowserUk (Patriarch) on May 27, 2015 at 22:33 UTC | |
by efoss (Acolyte) on May 28, 2015 at 04:54 UTC | |
by efoss (Acolyte) on Jun 04, 2015 at 20:30 UTC | |
|