http://www.perlmonks.org?node_id=1069449


in reply to Sampling From a Histogram Distribution

Another approach: Use Bytes::Random::Secure's string_from method. Supply it with the following "bag" string: "aaaaoooooooooooooooooooppppppppppccccc", and draw as many random characters as you need. The distribution will be appropriately weighted.

Update: Here's how it would look. I'm not convinced that I care for it aesthetically, but the randomness is high quality, and the source is well tested.

use Bytes::Random::Secure; my $rng = Bytes::Random::Secure->new( NonBlocking => 1 ); my %weight = ( apples => 4, oranges => 19, pairs => 10, peaches => 5 ) +; my %map = ( qw/ apples a oranges o pairs p peaches c / ); my %rmap = reverse %map; my $bag = join '', map { ( $map{$_} ) x $weight{$_} } keys %weight; print $rmap{$rng->string_from($bag,1)}, $_% 8 == 0 ? "\n" : "\t" for 1 .. 100; print "\n";

Sample output:

$ ./mytest.pl pairs oranges oranges oranges pairs apples oranges + apples oranges pairs oranges oranges pairs peaches peaches + apples peaches pairs oranges oranges oranges pairs oranges + oranges peaches peaches peaches oranges oranges peaches oran +ges oranges ... and so on ...

When that module was created, it was an intentional design decision that duplicate characters in the "bag" string would increase the weighting of those characters.


Dave