根据字典中的百分比选择选项

时间:2017-08-26 13:56:51

标签: java

我是java的新手,并且一直在研究涉及概率的程序。 Currentley我被困在我有一个看起来像这样的dictonary / map / hashMap的位置。

["Charlie":0.2,"Fred":0.1,"Ricky":0.5,"Damon":0.2]

从这个我想要一个有20%的机会选择查理的机会,有10%的机会选择弗雷德等等......

但是,我不知道如何解决这个问题。我完全迷失了。谢谢你的帮助。

编辑:一些额外的信息。 我需要它可扩展,因为列表的大小可能不同。此外,它只需要返回一个值。

3 个答案:

答案 0 :(得分:1)

这个怎么样(我测试过并且有效):

String[] keys = map.keySet().toArray(new String[map.size()]);
Double[] values = map.values().toArray(new Double[map.size()]);

for(int x=1; x<values.length; x++)
    values[x] += values[x-1];            //Accumulate probabilities

double rand = Math.random();
for(int x=0; x<values.length; x++){
    if(rand < values[x])
        System.out.println(keys[x]);
        break;
    }

<强>解释

累计每个名字的概率:

Charlie: 0.0-0.2
Fred:    0.2-0.3
Ricky:   0.3-0.8
Damon:   0.8-1.0

然后只需滚动一个随机数并检查它是否属于谁的范围。 Ricky的范围比其他人更广(在这种情况下为50%),因此有50%的机会被选中。

前15次:

Fred
Ricky
Charlie
Ricky
Ricky
Damon
Charlie
Damon
Fred
Charlie
Fred
Charlie
Ricky
Ricky
Ricky

将代码置于1000万次以下

Charlie: 19.98881%
Fred:    10.014190000000001%
Rcicky:  50.00255%
Damon:   19.99445%

答案 1 :(得分:0)

  • 按概率级别对条目进行排序,使用相同级别的数组。
  • 随机选择一个数组
  • 在阵列中随机挑选一个人。
Python

答案 2 :(得分:0)

假设您有两个名称和概率的枚举加上一个随机数生成器random,您应该保留并且不会在每次调用时重新创建:

double r = random.nextDouble();
double sump = 0.0;
while(names.hasMoreElements() && probs.hasMoreElements()) {
    double p = probs.nextElement();
    String n = names.nextElement();
    if(r >= sump && r < sump + p)
        return n;
    sump += p;
}

当0.0 <= r <时,想法选择查理。当0.2 <= r <时,Fred为0.2。 0.3,等等。