2017-04-21 5 views
0

com.google.common.graph.MutableValueGraphの要素を置き換える際に壁に当たっています。Guava MutableValueGraphでノードを交換する

私は要素の状態、以下のデータクラス上の(私はthe docsアドバイスは注意する知っている何か)を更新する必要があります:私は、グラフが別のノードを交換する方法を提供していないので

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

を私自身の圧延:

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を打つ:

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) 
... 

forループでノードの束を交換しているようですが、すでに交換されている隣接ノードに触れようとしているのでしょうか?

私の質問は、ValueGraphの複数のノードをどのように置き換えてエッジ値を保持するのですか?

+0

当分、私はGuavaの文書で言うように、余分なデータ構造で可変状態を追跡します。質問はまだそれ自身の価値があると思います。 – 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 
}