in reply to Re^2: Picking a random item through probability
in thread Picking a random item through probability
Actually, even this is problematic. Because you need to go through the list in a defined order to ensure that each item has its respective probabilities. So you really do need the array refs ... but you need them in a list, not a hash.
Then, when you generate a number, you first loop through summing $_->[1]:my @items = ( ["foo", 1], ["bar", 3], ["baz", 4], ["quux", 9] );
and then you generate a number from that, and then find the item in the total:use List::Util; my $total_weight = List::Util::sum(map { $_->[1] } @items);
Ok, that's a bit convoluted, but I don't quite want to do someone's homework ;-) Anyway, the point is that if, when iterating over the hash, you end up with the hash being reordered from lookup to lookup, I don't think you'll get precisely the correct distribution. (Of course, I'm assuming a perfectly random rand function, but that is a separate problem.)my $pick = int(rand($total_weight)); my $picked_item = (List::Util::first { $pick -= $_->[1]; $pick < 0 } + @items)->[0];
Update: fix some minor formatting, and off-by-one error (was $pick <= 0)
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^4: Picking a random item through probability
by muba (Priest) on Nov 23, 2006 at 21:56 UTC | |
by Tanktalus (Canon) on Nov 23, 2006 at 22:14 UTC | |
by doom (Deacon) on Nov 24, 2006 at 01:02 UTC | |
by muba (Priest) on Nov 23, 2006 at 22:51 UTC |