我有一个数组char[] Select = {'A','B','C','D','E','F','G','H','I','J'}
,并且此数组中的每个元素都有不同的选择概率。例如,
int[] Weight = {10,30,25,60,20,70,10,80,20,30};
我的要求是从这个数组中选择5个元素,具有高权重值的元素具有更高的选择概率,这5个元素应该是不同的。
我的计划首先是权重
int[] weightSum = {10, 40, 65, 125, 145, 215, 225, 305, 325, 355}
然后我使用Random生成[0,355]范围内的随机数k
。然后在k
中查找大于weightSum[]
的第一个元素。这个过程重复5次。
问题是可以多次选择具有高概率的元素。我尝试在每次迭代时删除重复的元素。删除重复项,但不选择具有高权重值的元素。
如何解决这个问题?
感谢。
答案 0 :(得分:3)
我不确定我是否理解正确,但是这样的事情怎么样:
char[] Select
int[] Weight
int[] weightSum
答案 1 :(得分:1)
我想每次删除重复项时,都必须更新weightSum数组。
答案 2 :(得分:1)
不要保持累积金额或每次调整:(虽然每个选择都需要O(n))
char[] Select = {'A','B','C','D','E','F','G','H','I','J'};
int[] Weight = {10,30,25,60,20,70,10,80,20,30};
int sum = 355;
for(int a=0;i<5;i++){
int rand = (int)(Math.random()*sum);
int s=0;//temp cumulative sum
int i=0;
while( (s+=Weight[i])<rand)i++;
result.add(Select[i]);
sum-=Weight[i];//total weight is lower now
Weight[i]=0;//if weight is 0 it will never be selected
}
编辑:已修复,因此我不会从sum
答案 3 :(得分:0)
我并不是真的理解你的问题,但你的算法听起来是正确的:你应该做的事情就像将每个生成的值存储在一个列表中(基于随机数生成器),但首先检查一下这个数字是否已经存在于添加之前的列表。重复,直到列表中有5个数字。
答案 4 :(得分:0)
我的统计记忆有点模糊,但我认为您想要做的是在选择后删除元素。换句话说,在选择条目后,从weightSum
中删除该条目,并从所有后续条目和随机数的范围中减去其Weight
。如果使用ArrayList
而不是原始数组,可能更容易管理。