From 003d8819ce3c682d058ec3881da38cf8bcb9e830 Mon Sep 17 00:00:00 2001 From: "ray.j.greenwell" Date: Wed, 13 Oct 2010 19:48:05 +0000 Subject: [PATCH] Nix getWeighted() and rearrange the Map overload of pick(). git-svn-id: https://samskivert.googlecode.com/svn/trunk@2918 6335cc39-0255-0410-8fd6-9bcaacd3b74c --- .../java/com/samskivert/util/Randoms.java | 86 ++++++------------- 1 file changed, 28 insertions(+), 58 deletions(-) diff --git a/src/main/java/com/samskivert/util/Randoms.java b/src/main/java/com/samskivert/util/Randoms.java index 7d394b9c..e29fb4a2 100644 --- a/src/main/java/com/samskivert/util/Randoms.java +++ b/src/main/java/com/samskivert/util/Randoms.java @@ -142,64 +142,6 @@ public class Randoms return (float)_r.nextGaussian() * dev + mean; } - /** - * Pick a random key from the specified mapping of weight values, or return - * ifEmpty if no mapping has a weight greater than 0. - * - *

Implementation note: a random number is generated for every entry with a - * non-zero weight after the first such entry. - * - * @throws IllegalArgumentException if any weight is less than 0. - */ - public T pick (Map weightMap, T ifEmpty) - { - T pick = ifEmpty; - double total = 0.0; - for (Map.Entry entry : weightMap.entrySet()) { - double weight = entry.getValue().doubleValue(); - if (weight > 0.0) { - total += weight; - if ((total == weight) || ((_r.nextDouble() * total) < weight)) { - pick = entry.getKey(); - } - } else if (weight < 0.0) { - throw new IllegalArgumentException("Weight less than 0: " + entry); - } // else: weight == 0.0 is OK - } - return pick; - } - - /** - * Returns a key from the supplied map according to a probability computed as - * the key's value divided by the total of all the key's values. - * - * @throws NullPointerException if the map is null. - * @throws IllegalArgumentException if the sum of the weights is not positive. - * - * @deprecated Use {@link #pick(Map, Object)} instead. - */ - @Deprecated - public T getWeighted (Map valuesToWeights) - { - // TODO: validate each weight to ensure it's not below 0 - double sum = Folds.sum(0.0, valuesToWeights.values()); - if (sum <= 0) { - throw new IllegalArgumentException("The sum of the weights is not positive"); - } - // TODO: iterate all entries once, similarly to picking from an Iterable? - double d = _r.nextDouble() * sum; - for (Map.Entry entry : valuesToWeights.entrySet()) { - d -= entry.getValue().doubleValue(); - if (d < 0) { - return entry.getKey(); - } - } - // TODO: due to rounding error when iteratively subtract doubles, it might - // be possible to fall out of the loop here. Remember the highest-weighted entry - // and return it? (returning the last entry could be incorrect if it had a weight of 0). - throw new AssertionError("Not possible"); - } - /** * Pick a random element from the specified Iterator, or return ifEmpty * if it is empty. @@ -240,6 +182,34 @@ public class Randoms return pickPluck(iterable, ifEmpty, false); } + /** + * Pick a random key from the specified mapping of weight values, or return + * ifEmpty if no mapping has a weight greater than 0. Each + * weight value is evaluated as a double. + * + *

Implementation note: a random number is generated for every entry with a + * non-zero weight after the first such entry. + * + * @throws IllegalArgumentException if any weight is less than 0. + */ + public T pick (Map weightMap, T ifEmpty) + { + T pick = ifEmpty; + double total = 0.0; + for (Map.Entry entry : weightMap.entrySet()) { + double weight = entry.getValue().doubleValue(); + if (weight > 0.0) { + total += weight; + if ((total == weight) || ((_r.nextDouble() * total) < weight)) { + pick = entry.getKey(); + } + } else if (weight < 0.0) { + throw new IllegalArgumentException("Weight less than 0: " + entry); + } // else: weight == 0.0 is OK + } + return pick; + } + /** * Pluck (remove) a random element from the specified Iterable, or return ifEmpty * if it is empty.