7

これは何度か質問されたことは知っていますが、Tinkerpop の最新バージョン (3.1) に関する参照は見つかりませんでした。これには、トラバーサルで使用できる多くの新しい便利な機能が含まれています。

ノード 3 と 4 の間の最短経路を見つけなければならないとしましょう。このトラバーサル サウンドは適切ですか?

g.V(3).repeat(out()).until(id().is(4).and().simplePath()).path().limit(1)

ここでは、ループしているときに BFS 検索が実行されると仮定しています (したがって、最初の結果は最短パスですloop())

asさらに、以前にバインドされた変数を (ステップを使用して) ステップに含める方法はありますuntilか? より正確には、トラバーサル中に 2 つのノードを選択し、それらの間の最短パスを見つけようとしています。たとえば、

g.V().match(
__as('e0').out('Feedbacks').as('e1'),
__as('e0').repeat(out('Meets')).until(<I reach e1>).path().<get_length>.as('len')
).select('e0', 'e1', 'len')

最後に、前のトラバーサルからわかるように、最短経路の長さを取得する方法が明確ではありません。のようなものを使用して

g.V(3).repeat(out()).until(id().is(4).and().simplePath()).path().size()

結果のサイズ (返される行数) を返します。

g.V(3).repeat(out()).until(id().is(4).and().simplePath()).path().by(__size())

エラーを返します。

これが私が実験しているグラフです。

graph = TinkerGraph.open()
e0 = graph.addVertex(T.id, 0, label, "User", "name", "e0")
e1 = graph.addVertex(T.id, 1, label, "User", "name", "e1")
e2 = graph.addVertex(T.id, 2, label, "User", "name", "e2")
e3 = graph.addVertex(T.id, 3, label, "User", "name", "e3")
e4 = graph.addVertex(T.id, 4, label, "User", "name", "e4")
e0.addEdge("Feedbacks", e2)
e0.addEdge("Meets", e1)
e2.addEdge("Feedbacks", e4)
e2.addEdge("Meets", e4)
e3.addEdge("Feedbacks", e0)
e3.addEdge("Meets", e2)
e4.addEdge("Feedbacks", e0)
g = graph.traversal()
4

1 に答える 1

13

最短パス クエリには、少し短いバリアントがあります。

g.V(3).repeat(out().simplePath()).until(hasId(4)).path().limit(1)

最初のパスが常に最短パスであるというあなたの仮定は正しいです。パスの長さを取得するには、次を使用できますcount(local)

g.V(3).repeat(out().simplePath()).until(hasId(4)).path().count(local)

アップデート

更新されたクエリに関しては、これで問題が解決するはずです。

g.V().as("e0").out("Feedbacks").as("e1").select("e0").
      repeat(out("Meets")).until(where(eq("e1"))).path().
      map(union(count(local), constant(-2)).sum()).as("len").
      select("e0","e1","len")

repeat()パス全体の長さから 2 を引きます。これは、ブロックが通過するパスの長さにのみ関心がありout().select()、先頭に含まれるべきではないと思うためです。そうでない場合は、3 行目を に置き換えるだけですcount(local).as("len").

于 2015-12-02T15:14:34.617 に答える