x可能结果的概率

时间:2016-02-27 02:52:27

标签: java

所以我正在编写一个程序,用户可以根据需要定义任意数量的随机结果。他们还定义了每个概率(所以不,它们不相等)。什么是检查发生的最佳方法。注意:我的程序恰好是一个Minecraft插件,但问题更多的是一般的java,所以我试图让代码反映出来:

Map<String,Integer> possibilities = new HashMap<String,Integer>();

int x = (int) (Math.random() * 100)

我的想法是创建另一个变量,并每次添加先前检查过的概率,并检查它是否小于x。如果它没有冲洗并重复,但我不确定如何构建它。

因此,例如:如果用户配置了它,那么他有3种不同的结果,分别有30%,20%,50%的几率,我该怎么做?

3 个答案:

答案 0 :(得分:2)

使用NavigableMap,这样您就可以通过一次干净简单的查找来检索正确的结果。 (在内部,这使用了有效的O(log n)查找 - 而不是你的地图足够重要。)

import java.util.NavigableMap;
import java.util.TreeMap;
import static java.util.concurrent.ThreadLocalRandom.current;

final class LoadedDie {

  public static void main(String... argv) {
    NavigableMap<Integer, String> loot = new TreeMap<>();
    int cumulative = 0;
    loot.put(cumulative += 20, "Gold");
    loot.put(cumulative += 30, "Iron");
    loot.put(cumulative += 50, "Coal");

    /* Use */
    System.out.println(loot.higherEntry(current().nextInt(cumulative)).getValue());
    System.out.println(loot.higherEntry(current().nextInt(cumulative)).getValue());
  }

}

答案 1 :(得分:1)

这是一个大致的想法,

您可能会声明一个方法。这是标题应该是什么样子

public static <T> T selectRandomFrom (Map<T, Integer>)

您也可以将其设为非通用,但我认为通用更好。

你要像这样传递地图

Keys        Values
Diamond     5
Gold        20
Iron        30
Coal        45

值是百分比,我们假设键的类型为Item

我想首先你要检查机会是否加起来为100.否则,抛出异常或其他东西。

然后你应该将地图的值从上面改为:(我建议你为此创建一个新地图)

5 (5)
25 (20 + 5) 
55 (30 + 25)
100 (45 + 55)

每个值都会添加到上面的值中。你会在一秒钟内看到它是如何使用的。

现在生成1到100的随机数

int randomNumber = new Random().nextInt(100) + 1;

之后,循环遍历地图的新值。对于每个值,请查看它是否小于或等于随机数。如果是,则返回与值关联的键。

让我举个例子:(伪代码)

The random number generated is 77. 
Is it less than or equal to 5 (Diamond)? It is not.
is it less than or equal to 25 (Gold)? It is not.
Is it less than or equal to 55 (Iron)? It is not.
Is it less than or equal to 100 (Coal)? It is.
Return Coal.

我决定为你编写代码。

public static <T> T selectRandomFrom (Map<T, Integer> possibilities) {
    ArrayList<T> keys = new ArrayList<>();
    ArrayList<Integer> values = new ArrayList<>();
    int i = 0;
    for (Map.Entry<T, Integer> entry : possibilities.entrySet()) {
        keys.add(entry.getKey());
        values.add(entry.getValue() + i);
        i = entry.getValue();
    }

    int randomNumber = new Random().nextInt(100) + 1;
    for (int j = 0 ; j < keys.size() ; j++) {
        if (randomNumber <= values.get(j)) {
            return keys.get(j);
        }
    }

    throw new IllegalArgumentException("The possibilities don't add up to 100!");
}

答案 2 :(得分:0)

这是一种方法。

public static String getOutcome(Map<String, Integer> possibilities) {
    int x = (int) (Math.random() * 100);

    for (Map.Entry<String, Integer> possibility : possibilities.entrySet()) {
        if (x <= possibility.getValue()) {
            return possibility.getKey();
        }
        x -= possibility.getValue();
    }

    // unreachable if probabilities are correctly mapped
    return null;
}