【发布时间】:2014-12-10 16:54:30
【问题描述】:
在我发布这个问题之前,我阅读了here 的帖子。但是对于这个特殊的问题,我真的不知道我该如何应用同样的理念?
在以下问题中,我的变量graph 具有以下结构:HashMap<Integer, ArrayList<Integer>>。
而u 和v 的类型为int。基本上,我想删除键值为i 的arraylists 中的值v,其中i 出现在v 的arraylist 中。
所以,如果整数i出现在v的arraylist中,我们在图中得到i的arraylist并从中删除值v。
这听起来很复杂。但是我现在被这个 ConcurrentModificationException 困了一段时间。
public int random_contraction_algo(){
while(graph.size() > 2){
int u = select_remaining_edges_at_random(new ArrayList<Integer> (graph.keySet()));
int v = select_remaining_edges_at_random(graph.get(u));
merge(u,v);
}
return -1;
}
// select a pair of vertices from an edge
public int select_remaining_edges_at_random(ArrayList<Integer> vertices){
int index = (int)(Math.random() * (vertices.size()));
return vertices.get(index);
}
public void merge(int u, int v){
graph.get(u).addAll(graph.get(v));
// remove self-loops
graph.get(u).removeAll(Collections.singleton(u));
graph.get(u).removeAll(Collections.singleton(v));
// make sure all the edges of v are connected to u instead v
for(Iterator<Integer> iterator = graph.get(v).iterator(); iterator.hasNext();){
Integer i = iterator.next();
graph.get(i).remove((Integer) v);
graph.get(i).add(u);
}
// remove key
graph.remove(v);
}
更新:非常感谢您的回答。但是,我意识到我忘了告诉你们我的代码中有一个外循环。
我尝试实施您的解决方案,但 ConcurrentModificationException 仍然发生。
这些是错误消息:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:886)
at java.util.ArrayList$Itr.next(ArrayList.java:836)
at HashMapOfArrayList.merge(ArraylistOfArrayList.java:96)
at HashMapOfArrayList.random_contraction_algo(ArraylistOfArrayList.java:69)
at RunAlgo.main(ArraylistOfArrayList.java:111)
【问题讨论】:
-
我认为这不会是一个问题,除非 i == v,但是你可以使用标准的迭代器方法。
-
你能给我举个例子吗?
-
在循环中修改其他列表不会有问题。如果您仍然遇到以下两种解决方案中的任何一种异常,这是由您未包含在帖子中的某些代码引起的。 @Ordous 的解决方案也可能会失败,如果您将相同的列表存储在地图中的不同键下。我的对此免疫(但效率稍低,因为它涉及对列表的一次添加扫描)。
-
我将再次编辑这个问题,因为我想向你们展示更多涉及外循环的代码。请参阅更新
-
@mynameisJEFF 您是否有可能给出一个失败的小数据示例?像 2-3 个带边的节点?我已经尝试了 3 个节点,每个节点都相互连接,效果很好(如果没有明确的自循环删除,则会抛出异常)