# 如何select一个项目的概率？

``[{A,1},{B,1},{C,2}]` `

Java代码：

` `class Item { int relativeProb; String name; //Getters Setters and Constructor } ... class RandomSelector { List<Item> items = new List(); Random rand = new Random(); int totalSum = 0; RandomSelector() { for(Item item : items) { totalSum = totalSum + item.relativeProb; } } public Item getRandom() { int index = rand.nextInt(totalSum); int sum = 0; int i=0; while(sum < index ) { sum = sum + items.get(i++).relativeProb; } return items.get(Math.max(0,i-1)); } }` `
1. 生成一个均匀分布的随机数。
2. 迭代你的列表，直到访问元素的累积概率大于随机数

` `double p = Math.random(); double cumulativeProbability = 0.0; for (Item item : items) { cumulativeProbability += item.probability(); if (p <= cumulativeProbability) { return item; } }` `

` `Item A 25% Item B 15% Item C 35% Item D 5% Item E 20%` `

` `Start - Sum of probability of all items before End - Start + own probability` `

` `Item A 0 to 25 Item B 26 to 40 Item C 41 to 75 Item D 76 to 80 Item E 81 to 100` `

MJ

` `random number between 0.00 and 0.40 -> pick A between 0.40 and 0.70 -> pick B between 0.70 and 0.95 -> pick C between 0.95 and 1.00 -> pick D` `

` `def probabilities = [ new Pair<String, Double>("one", 25), new Pair<String, Double>("two", 30), new Pair<String, Double>("three", 45)] def distribution = new EnumeratedDistribution<String>(probabilities) println distribution.sample() // here you get one of your values` `

`[{A,50},{B,100},{C,200}]`

` ` A.value = random(0 to 50); B.value = random(0 to 100); C.value = random (0 to 200);` `

`[{A,50},{B,100},{C,200}]`

` ` A.lowLimit= 0; A.topLimit=50; B.lowLimit= A.topLimit+1; B.topLimit= B.lowLimit+100 C.lowLimit= B.topLimit+1; C.topLimit= C.lowLimit+200` `

` `A.limits = 0,50 B.limits = 51,151 C.limits = 152,352` `

Brent的答案是好的，但是它没有考虑在p = 0的情况下错误地select概率为0的项目的可能性。通过检查概率很容易处理（或者可能不在第一个项目中添加项目地点）：

` `double p = Math.random(); double cumulativeProbability = 0.0; for (Item item : items) { cumulativeProbability += item.probability(); if (p <= cumulativeProbability && item.probability() != 0) { return item; } }` `

` `function selrnd(a::Vector{Int}) c = a[:] sumc = c[1] for i=2:length(c) sumc += c[i] c[i] += c[i-1] end r = rand()*sumc for i=1:length(c) if r <= c[i] return i end end end` `