我对@ PeterLawrey的评论没有名气
答案:Random weighted selection in Java。这很好。但是现在我打电话给next()
得到A的结果,并希望从map
中删除A的重量,以避免再次获得A.我该如何处理?
答案 0 :(得分:1)
你可以在PeterLawrey的解决方案中简单地改变这一行
public E next() {
double value = random.nextDouble() * total;
return map.higherEntry(value).getValue();
}
到
public E next() {
double value = random.nextDouble() * total--;
return map.remove(higherKey(value));
}
原因remove()
在删除
或者,如果您在选择后需要删除元素,则可以使用其他解决方案。将所有元素添加到'LinkedList'中,每个元素必须按重量添加多次,然后使用Collections.shuffle()
,根据JavaDoc
使用默认的随机源随机置换指定的列表。所有排列都以大致相等的可能性发生。
最后,使用pop()
或removeFirst()
Map<String, Integer> map = new HashMap<String, Integer>() {{
put("Five", 5);
put("Four", 4);
put("Three", 3);
put("Two", 2);
put("One", 1);
}};
LinkedList<String> list = new LinkedList<>();
for (Map.Entry<String, Integer> entry : map.entrySet()) {
for (int i = 0; i < entry.getValue(); i++) {
list.add(entry.getKey());
}
}
Collections.shuffle(list);
System.out.println("Size: " + list.size());
int size = list.size();
for (int i = 0; i < size; i++) {
System.out.println(list.pop());
}
System.out.println("Size: " + list.size());