Sure. The tools required are:
- an instance of
java.util.Random
- call its
nextDouble
method.
The algorithm is something like:
- First calculate, once-off, the incremental weighting. In your example that would be
[0.5, 0.8, 1.0]
.
- Multiply the output of
nextDouble
with the final weight (here the final weight is 1.0, so not needed. Multiplying by 1.0 doesn't hurt, of course).
- loop through the incremental weights and check if the random number you have is less than it. If yes, that's your choice.
Example:
public class WeightedList {
private final char[] choices;
private final double[] weights;
private final Random rnd = new Random();
public WeightedList(char[] choices, double[] weights) {
if (choices.length != weights.length) throw new IllegalArgumentException();
this.choices = Arrays.copyOf(choices);
this.weights = new double[weights.length];
double s = 0.0;
for (int i = 0; i < weights.length; i++) {
this.weights[i] = (s += weights[i]);
}
}
public char get() {
double v = rnd.nextDouble() * weights[weights.length - 1];
for (int i = 0; i < weights.length - 1; i++) {
if (v < weights[i]) return choices[i];
}
return weights[weights.length - 1];
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…