Tinkerpop 3: compute connected components with Gremlin traversal

荒凉一梦 提交于 2019-12-10 11:06:57

问题


I think the tags explain quite well my problem :)

I've been trying to write a Gremlin traversal to compute the connected components of the simple graph described at the end of the post.

I tried with

g.V().repeat(both('e')).until(cyclicPath()).dedup().tree().by('name').next()

obtaining

==>a={b={a={}, c={b={}}, d={c={d={}}}}, c={d={c={}}}}
==>e={f={e={}, g={f={}}}, h={f={h={}}}}
==>g={f={g={}}}

which is bad, since the cyclicPath filter terminated the traversal starting from e before reaching g. Obviously, if I remove the until clause I get an infinite loop. Moreover, if I use simplePath the traverse ends after one step. Is there any way to tell it to explore the nodes in depth-first order?

Cheers!

a = graph.addVertex(T.id, 1, "name", "a")
b = graph.addVertex(T.id, 2, "name", "b")
c = graph.addVertex(T.id, 3, "name", "c")
d = graph.addVertex(T.id, 4, "name", "d")
e = graph.addVertex(T.id, 5, "name", "e")
f = graph.addVertex(T.id, 6, "name", "f")
g = graph.addVertex(T.id, 7, "name", "g")
h = graph.addVertex(T.id, 8, "name", "h")

a.addEdge("e", b)
a.addEdge("e", c)
b.addEdge("e", c)
b.addEdge("e", d)
c.addEdge("e", d)

e.addEdge("e", f)
e.addEdge("e", h)
f.addEdge("e", h)
f.addEdge("e", g)

回答1:


This query was also discussed in the Gremlin-users group. Here is the solution I came out with. @Daniel Kuppitz also had an interesting solution you can find in the mentioned thread.

I think that if it is always true that in an undirected graph the "last" node of the traversal of a connected component either leads to a previously visited node (cyclicPath()) or has degree <=1 this query should work

g.V().repeat(both('e')).until( cyclicPath().or().both('e').count().is(lte(1)) ).dedup().tree().by('name').next()

On my example it gives the following output

gremlin>  g.V().repeat(both('e')).until(cyclicPath().or().both('e').count().is(lte(1))).dedup().tree().by('name').next()
==>a={b={a={}, c={b={}}, d={c={d={}}}}, c={d={c={}}}}
==>e={f={e={}, g={}, h={f={}}}, h={f={h={}}}}



回答2:


Just to enhance the @Alberto version, which is working well, you can use the simplePath() traversal step (http://tinkerpop.apache.org/docs/current/reference/#simplepath-step) to ensure that the traverser does not repeat its path through the graph

g.V().repeat(both().simplePath())
  .until(bothE().count().is(lte(1)))
  .dedup().tree().by('name').next()


来源:https://stackoverflow.com/questions/33895587/tinkerpop-3-compute-connected-components-with-gremlin-traversal

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!