我是java的新手,并且一直在研究涉及概率的程序。 Currentley我被困在我有一个看起来像这样的dictonary / map / hashMap的位置。
["Charlie":0.2,"Fred":0.1,"Ricky":0.5,"Damon":0.2]
从这个我想要一个有20%的机会选择查理的机会,有10%的机会选择弗雷德等等......
但是,我不知道如何解决这个问题。我完全迷失了。谢谢你的帮助。编辑:一些额外的信息。 我需要它可扩展,因为列表的大小可能不同。此外,它只需要返回一个值。
答案 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,等等。