需要帮助提出一种算法来根据计数和百分比在 Java 中生成随机布尔值



我不确定我是否正确地命名了这篇文章。如果我没有,请告诉我,我会编辑标题。

我试图做的是模拟电池充电的"真实世界"情况:

1st charge == 100% chance of an error (a.k.a., boolean false)
2nd charge == 90% chance of an error
3rd charge == 80% chance of an error
4th charge == 70% chance of an error
5th charge == 60% chance of an error
6th charge == 50% chance of an error
7th charge == 40% chance of an error
8th charge == 30% chance of an error
9th charge == 20% chance of an error
10th charge == 10% chance of an error

所以,我需要的是一种算法来根据这些百分比生成真假,但我不知道该怎么做。我知道有RandomThreadLocalRandom,但无法输入任何边界或值nextBoolean()。我想我可以做这样的事情:

switch(charge){
case 1:
if(ThreadLocalRandom.nextInt(10,10) > 10) return ThreadLocalRandom.nextBoolean();
break;
case 2:
if(ThreadLocalRandom.nextInt(9,10) > 9) return ThreadLocalRandom.nextBoolean();
break;
case 3:
if(ThreadLocalRandom.nextInt(8,10) > 8) return ThreadLocalRandom.nextBoolean();
break;
case 4:
if(ThreadLocalRandom.nextInt(7,10) > 7) return ThreadLocalRandom.nextBoolean();
break;
case 5:
if(ThreadLocalRandom.nextInt(6,10) > 6) return ThreadLocalRandom.nextBoolean();
break;
case 6:
if(ThreadLocalRandom.nextInt(5,10) > 5) return ThreadLocalRandom.nextBoolean();
break;
case 7:
if(ThreadLocalRandom.nextInt(4,10) > 4) return ThreadLocalRandom.nextBoolean();
break;
case 8:
if(ThreadLocalRandom.nextInt(3,10) > 3) return ThreadLocalRandom.nextBoolean();
break;
case 9:
if(ThreadLocalRandom.nextInt(2,10) > 2) return ThreadLocalRandom.nextBoolean();
break;
case 10:
if(ThreadLocalRandom.nextInt(1,10) > 1) return ThreadLocalRandom.nextBoolean();
break;
}

正如你所看到的,我不知道我在做什么,所以我需要一些帮助。

谢谢!

1. 解释和解决方案:

您需要的是:

  • 生成一个介于 0 和 10 之间的随机数(使用类Random
  • 根据charge的值,找到随机数的接受范围:
    • 示例:如果电荷是4,要得到一个错误,随机必须是[0;7](范围的70%(,所以return random >=7;
private static boolean isError(int charge) {
int random = new Random().nextInt(10);
switch (charge) {
case 1:  return random >= 10;
case 2:  return random >= 9;
case 3:  return random >= 8;
case 4:  return random >= 7;
case 5:  return random >= 6;
case 6:  return random >= 5;
case 7:  return random >= 4;
case 8:  return random >= 3;
case 9:  return random >= 2;
case 10: return random >= 1;
default: return false;
}
}

2. 更短的解决方案

这可以简化为:

private static boolean isError(int charge) {
return new Random().nextInt(10) >= (11 - charge);
}

3. 测试和演示:演示

使用此main,您可以测试该方法的有效性,它测试nbTest次,每次charge,并查看您收到错误的次数

public static void main(String[] args) {
DecimalFormat df = new DecimalFormat("##.##%");
double nbError, nbTest = 100000;
for (int charge = 1; charge < 11; charge++) {
nbError = 0;
for (int j = 0; j < nbTest; j++) {
nbError += (isError(charge) ? 0 : 1);
}
System.out.println(charge + " -> " + df.format(nbError / nbTest));
}
}

1 -> 100   %   ~100%
2 ->  90,06%   ~ 90%
3 ->  80,31%   ~ 80%
4 ->  69,97%   ~ 70%
5 ->  59,92%   ~ 60%
6 ->  49,9 %   ~ 50%
7 ->  39,9 %   ~ 40%
8 ->  30,08%   ~ 30%
9 ->  19,84%   ~ 20%
10 -> 10,18%   ~ 10%

一种简单的机制是根据电荷计数计算0.01.0之间的值,然后将其与随机double进行比较。

public void test() {
// Test each charge.
for (int charge = 0; charge < 10; charge++) {
// Using ints here so output is clearer - could just as easily use bool.
List<Integer> results = new ArrayList<>();
for (int test = 0; test <= 100; test++) {
// Use 0 or 1 debending on random biased boolean.
results.add(biasedBoolean(1.0 - ((float) charge / 10)) ? 0 : 1);
}
System.out.println("Charge " + (charge + 1) + " -> " + results);
}
}
Random random = new Random();
private Boolean biasedBoolean(double bias) {
return random.nextDouble() < bias;
}

您可能需要调整数学以确保获得有关值的正确统计数据,但这肯定显示了一种技术。

最新更新