我的模型中有不同的场景,并且在每种情况下,道路网络(图形)的某些路段(边缘)降级(丢失容量)或中断(由于总损坏而移除)。出于这个原因,我试图从原始网络开始迭代每个场景的一组边缘,并通过改变某些边缘的容量并删除其他边缘来更新网络。在开始时,我没有使用迭代器迭代边缘,导致“ConcurrentModificationException”。然后我更改了代码以便使用Iterator,但这次它不允许我使用remove方法和我的迭代器(edgeIt.remove())。我该如何解决这个问题?感谢您的帮助。
.....
ArrayList<FloydWarshallShortestPaths<Integer, DefaultWeightedEdge>> FWS = new ArrayList<FloydWarshallShortestPaths<Integer, DefaultWeightedEdge>>();
for(int w=0; w<numOfScenarios; w++){
FWS.add(w, fr.readData(fileName));
}
....
//Road Network and Shelters after disruption in Scenarios
for(int i=1; i<6; i++){
Iterator<FloydWarshallShortestPaths<Integer, DefaultWeightedEdge>> it = FWS.iterator();
while(it.hasNext()){
FloydWarshallShortestPaths<Integer, DefaultWeightedEdge> FWIt = it.next();
Iterator<DefaultWeightedEdge> edgeIt = FWIt.getGraph().edgeSet().iterator();
while(edgeIt.hasNext()){
DefaultWeightedEdge e = edgeIt.next();
if(arcRiskZoneIndex[FWIt.getGraph().getEdgeSource(e)][FWIt.getGraph().getEdgeTarget(e)][FWS.indexOf(FWIt)]==i){
if(rng.nextDouble()<=arcDisruptProb[FWS.indexOf(FWIt)][i-1]){
roadCapS[FWS.get(FWS.indexOf(FWIt)).getGraph().getEdgeSource(e)][FWS.get(FWS.indexOf(FWIt)).getGraph().getEdgeTarget(e)][FWS.indexOf(FWIt)]=(roadCap[FWIt.getGraph().getEdgeSource(e)][FWIt.getGraph().getEdgeTarget(e)]*10000-rng.nextInt(((int) (10000*roadCap[FWIt.getGraph().getEdgeSource(e)][FWIt.getGraph().getEdgeTarget(e)]/2000))+1)*2000)/10000;
if(roadCapS[FWIt.getGraph().getEdgeSource(e)][FWIt.getGraph().getEdgeTarget(e)][FWS.indexOf(FWIt)]==0.0){
**edgeIt.remove()**;
}
}
}
}
for(int s:setOfFacilityNodesDummy){
if(shelterRiskZoneIndex[s][FWS.indexOf(FWIt)]==i){
if(rng.nextDouble()<=shelterDisruptProb[FWS.indexOf(FWIt)][i-1]){
setOfFacilityNodesS.get(FWS.indexOf(FWIt)).remove(s);
}
}
}
}
}
答案 0 :(得分:2)
Collection
返回的edgeSet()
很可能根本不支持remove()
操作,或支持remove()
,但Iterator
支持ConcurrentModificationException
没有。
要解决此问题(以及Set
),您必须在单独的{{1}}中收集要删除的边缘,并在完成迭代后删除他们通过图表的适当API。
答案 1 :(得分:1)
好的,我做了一些谷歌搜索,显然你正在使用JGraphT库。 (Protip:在你的问题中指明这一点很有帮助!) JavaDoc for Graph.edgeSet()
说:
返回此图中包含的一组边。该套装备受支持 通过图表,对图表的更改将反映在集合中。如果 当集合上的迭代正在进行时,图形被修改 迭代结果未定义。
现在,这只是意味着如果Graph
的边缘发生变化,那么可以在返回的Set
中看到这些变化。不幸的是,它没有说明返回Set
的更改,导致Graph
边缘的更改。鉴于您正在获得UnsupportedOperationException
,我假设 Graph
不允许您更改返回的Set
。 The source code of AbstractBaseGraph
证实了这一假设:
/**
* @see Graph#edgeSet()
*/
public Set<E> edgeSet()
{
if (unmodifiableEdgeSet == null) {
unmodifiableEdgeSet = Collections.unmodifiableSet(edgeMap.keySet());
}
return unmodifiableEdgeSet;
}
edgeSet()
会返回Graph
边缘的无法修改的视图。您无法直接更改edgeSet
,您必须使用{ {1}}添加/更改/删除边缘的界面。此外,如果您在进行这些更改时迭代Graph
,则可能会遇到未定义的行为。
要解决这个问题,我建议首先在迭代时收集要删除的边,然后再删除它们:
edgeSet