2017-04-21 14 views
0

com.google.common.graph.MutableValueGraph에있는 요소를 바꿀 때 벽을 치려고합니다.Guava MutableValueGraph에서 노드 교환하기

나는 다음과 같은 데이터 클래스에 요소 상태를 (뭔가 내가 조심하는 the docs 조언을 알고) 업데이트해야합니다

data class Frame(val method: String, val merged: Boolean = false) 

그래프가 서로에 대한 노드를 교환하는 방법을 제공하지 않기 때문에

, I

Exception in thread "main" java.util.ConcurrentModificationException 
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1437) 
at java.util.HashMap$EntryIterator.next(HashMap.java:1471) 
at java.util.HashMap$EntryIterator.next(HashMap.java:1469) 
at com.google.common.graph.DirectedGraphConnections$1$1.computeNext(DirectedGraphConnections.java:113) 
at com.google.common.collect.AbstractIterator.tryToComputeNext(AbstractIterator.java:145) 
at com.google.common.collect.AbstractIterator.hasNext(AbstractIterator.java:140) 
at TestKt.exchangeNode(Test.kt:292) 
... 
:

fun MutableValueGraph<Frame, Int>.exchangeNode(old: Frame, new: Frame): Boolean { 
    if (old == new) return true 

    if (isDirected) { 
     this.predecessors(old).forEach { 
      this.putEdgeValue(it, new, this.edgeValue(it, old)) } 
     this.successors(old).forEach { 
      this.putEdgeValue(new, it, this.edgeValue(old, it)) } 
    } else { 
     this.adjacentNodes(old).forEach { 
      this.putEdgeValue(it, new, this.edgeValue(it, old)) } 
    } 
    return this.removeNode(old) 
} 

그러나, 나는 ConcurrentModificationException를 공격 : 내 자신을 압연

for 루프에서 많은 노드를 교환하면서 이미 교환 된 인접 노드를 만지려고 노력한 것처럼 들리는가요?

내 질문은 : ValueGraph에서 여러 노드를 대체하고 에지 값을 유지하려면 어떻게해야합니까?

+0

당분간 구아바의 문서에서 말하는대로 추가 데이터 구조에서 변경 가능한 상태를 추적합니다. 문제는 여전히 자신의 가치를 가지고 있다고 생각합니다. – mabi

답변

0

덜 효율적인 접근하지만 확실히 ConcurrentModificationException는 해당 노드에서 서브 그래프를 유도하는 것입니다 다음에 다시 에지 값을 추가 유도 서브 그래프를 사용하여 마지막으로 이전 노드를 제거하고 새를 추가하고 피해야 하나

fun MutableValueGraph<Frame, Int>.exchangeNode(old: Frame, new: Frame): Boolean { 
    if (old == new) return false 

    val inducedSubgraph = Graphs.inducedSubgraph(this, adjacentNodes(old) + old) 

    removeNode(old) 
    addNode(new) 

    if (isDirected) { 
     for (predecessor in inducedSubgraph.predecessors(old)) { 
      putEdgeValue(predecessor, new, inducedSubgraph.edgeValue(predecessor, old)) 
     } 
     for (successor in inducedSubgraph.successors(old)) { 
      putEdgeValue(new, successor, inducedSubgraph.edgeValue(old, successor)) 
     } 
    } else { 
     for (adjacentNode in inducedSubgraph.adjacentNodes(old)) { 
      putEdgeValue(adjacentNode, new, inducedSubgraph.edgeValue(adjacentNode, old)) 
     } 
    } 

    return true 
}