Changed getWeighted() to accept a Map<T, ? extends Number>.
git-svn-id: https://samskivert.googlecode.com/svn/trunk@2914 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
@@ -149,16 +149,24 @@ public class Randoms
|
|||||||
* @throws NullPointerException if the map is null.
|
* @throws NullPointerException if the map is null.
|
||||||
* @throws IllegalArgumentException if the sum of the weights is not positive.
|
* @throws IllegalArgumentException if the sum of the weights is not positive.
|
||||||
*/
|
*/
|
||||||
public <T> T getWeighted (Map<T, Integer> valuesToWeights)
|
public <T> T getWeighted (Map<T, ? extends Number> valuesToWeights)
|
||||||
{
|
{
|
||||||
// TODO: validation?
|
// TODO: validate each weight to ensure it's not below 0
|
||||||
int idx = _r.nextInt(Folds.sum(0, valuesToWeights.values()));
|
double sum = Folds.sum(0.0, valuesToWeights.values());
|
||||||
for (Map.Entry<T, Integer> entry : valuesToWeights.entrySet()) {
|
if (sum <= 0) {
|
||||||
idx -= entry.getValue();
|
throw new IllegalArgumentException("The sum of the weights is not positive");
|
||||||
if (idx < 0) {
|
}
|
||||||
|
// TODO: iterate all entries once, similarly to picking from an Iterable?
|
||||||
|
double d = _r.nextDouble() * sum;
|
||||||
|
for (Map.Entry<T, ? extends Number> entry : valuesToWeights.entrySet()) {
|
||||||
|
d -= entry.getValue().doubleValue();
|
||||||
|
if (d < 0) {
|
||||||
return entry.getKey();
|
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");
|
throw new AssertionError("Not possible");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user