你如何在你的Java方法中引入概率——以一种灵活而简洁的方式?



我学习Java只有一周半的时间。在这一点上,我能想到的在代码中包含随机元素的唯一方法是使用Random类的nextInt方法。下面是我的方法的一部分:

Random random = new Random();
int randomInt = random.nextInt(10)+1;
[...]
if(randomInt <= 3){
System.out.println("Magnificent!");
} else if (randomInt >= 7){
System.out.println("Marvelous!");
} else {
System.out.println("Delectable!");
}

然而,它冗长且缺乏灵活性。我希望能够以简洁的方式将总概率为1的片段分配到不同的场景中a事件发生的概率为0.3,B事件发生的概率为0.5,С事件发生的概率为0.2。我怎么才能做到呢?

一般情况下,你有一个加权值集合,它可以基于概率生成一个随机值,该概率是其权重占总权重的百分比。. 权重可以归一化(即它们的和为1),也可以不归一化,这是更简单的假设。

当从该集合中滚动一个随机值时,首先检查概率最高的值是最有效的。在0和总权重之间滚动一个随机数,然后按其权重的顺序(降序)遍历这些值,并检查随机数是否低于累积权重->如果是,返回该值。

代码:

public class WeightedRandom<T> {    
private final Comparator<WeightedValue<T>> byWeight = 
Comparator.comparing(wv -> wv.weight);
private final Set<WeightedValue<T>> weightedValues = 
new TreeSet<>(byWeight.reversed());
private double totalWeight;
void put(double weight, T value) {
if (weight <= 0) {
return;
}
totalWeight += weight;
weightedValues.add(new WeightedValue<>(weight, value));
}
public T next() {
if (weightedValues.isEmpty()) {
throw new NoSuchElementException();
}
double rnd = ThreadLocalRandom.current().nextDouble(totalWeight);
double sum = 0;
Iterator<WeightedValue<T>> iterator = weightedValues.iterator();
WeightedValue<T> result;
do {
result = iterator.next();
sum += result.weight;
} while (rnd > sum && iterator.hasNext());
return result.value;
}
private static class WeightedValue<T> {
final double weight;
final T value;
public WeightedValue(double weight, T value) {
this.weight = weight;
this.value = value;
}
}
}

的例子:

public static void main(String[] args) {
WeightedRandom<String> random = new WeightedRandom<>();
random.put(3, "AAA");
random.put(2, "BBB");
random.put(5, "CCC");
for (int i = 0; i < 1000; i++) {
String value = random.next();
System.out.println(value);
}
}

通常,您将使用Random.nextDouble(),并测试例如random.nextDouble() < 0.3的概率为0.3。

要测试多个可能性,你需要对一些东西求和,例如

double r = random.nextDouble();
if (r < 0.3) {
...0.3 probability
} else if (r < 0.8) {
...0.5 probability
} else {
...0.2 probability
}

最新更新