例如,如果我有这样的一组int:
int[] list = {1, 4, 2};
我想选择这3个数字中的一个,但是更频繁地选择更高的值:
1 get chosen 1/7 of the time
4 gets chosen 4/7 of the time
2 gets chosen 2/7 of the time
如果Java中还没有函数,我怎么能为此编写函数。
编辑:我正在寻找一个有效的解决方案,O(n)或更好。
我将在很多线程中多次运行此代码。建立新的清单是不够的。
答案 0 :(得分:3)
累计列表中的值并调用结果总和S
。现在生成一个从0到S - 1
的随机数。在list
上再次迭代,并为每个元素执行以下操作:如果元素大于S
,则选择该元素。否则,按元素值减少S
并继续下一个元素。
答案 1 :(得分:1)
您只需使用Math.random()
获取0..1
范围内的随机数,然后选择累积权重为"覆盖"的索引处的数字。随机数:
public static int random(int[] numbers, double[] weights) {
double r = Math.random();
double sum = 0;
for (int i = 0; i < weights.length; i++) {
sum += weights[i];
if (r < sum)
return numbers[i];
}
return 0; // You can only get here if sum weights is less than 1
}
此解决方案根据您在O(N)中提供的权重选择一个随机数。在大多数情况下,算法甚至不会读取整个weights
数组。这是最好的。最大步长为N,平均步数为N / 2.
备注:强>
如果较大的权重位于weights
数组的开头,则该方法平均会更快。
权重之和预计为1
。如果权重之和小于
1
,此方法可能返回0
(概率为1-sum(weights)
)。
答案 2 :(得分:0)
1)取元素之和(S)(A [i]) 2)获取累积金额清单(C [i]) 3)从0到S-1获得随机值(R) 4)如果R&lt; C [i],你的随机值是A [i]
Cumulative Sum Range Index in the Cumulative Array Value in Original Array
----------------- ----------------------------- ----------------------
0 <= x < 1 0 1
1 <= x < 6 1 4
6 <= x < 7 2 2