Tinkerpop 3:使用 Gremlin 遍历计算连通分量
Tinkerpop 3: compute connected components with Gremlin traversal
我认为标签很好地解释了我的问题:)
我一直在尝试编写一个 Gremlin 遍历来计算 post.
末尾描述的简单图的连通分量
我试过
g.V().repeat(both('e')).until(cyclicPath()).dedup().tree().by('name').next()
获得
==>a={b={a={}, c={b={}}, d={c={d={}}}}, c={d={c={}}}}
==>e={f={e={}, g={f={}}}, h={f={h={}}}}
==>g={f={g={}}}
这很糟糕,因为 cyclicPath
过滤器在到达 g
之前终止了从 e
开始的遍历。
显然,如果我删除 until
子句,我会得到一个无限循环。
此外,如果我使用 simplePath
遍历在一步后结束。
有没有办法告诉它按深度优先顺序探索节点?
干杯!
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)
此查询was also discussed in the Gremlin-users group。
这是我提出的解决方案。
@Daniel Kuppitz 也有一个有趣的解决方案,您可以在上述主题中找到。
我认为如果在无向图中始终为真,则连通组件遍历的"last"节点要么导致先前访问过的节点(cyclicPath()
),要么度< =1 这个查询应该有效
g.V().repeat(both('e')).until( cyclicPath().or().both('e').count().is(lte(1)) ).dedup().tree().by('name').next()
在我的示例中,它给出了以下输出
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={}}}}
只是为了增强运行良好的@Alberto 版本,您可以使用 simplePath()
遍历步骤 (http://tinkerpop.apache.org/docs/current/reference/#simplepath-step) 来确保遍历器不会重复其通过图的路径
g.V().repeat(both().simplePath())
.until(bothE().count().is(lte(1)))
.dedup().tree().by('name').next()
我认为标签很好地解释了我的问题:)
我一直在尝试编写一个 Gremlin 遍历来计算 post.
末尾描述的简单图的连通分量我试过
g.V().repeat(both('e')).until(cyclicPath()).dedup().tree().by('name').next()
获得
==>a={b={a={}, c={b={}}, d={c={d={}}}}, c={d={c={}}}}
==>e={f={e={}, g={f={}}}, h={f={h={}}}}
==>g={f={g={}}}
这很糟糕,因为 cyclicPath
过滤器在到达 g
之前终止了从 e
开始的遍历。
显然,如果我删除 until
子句,我会得到一个无限循环。
此外,如果我使用 simplePath
遍历在一步后结束。
有没有办法告诉它按深度优先顺序探索节点?
干杯!
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)
此查询was also discussed in the Gremlin-users group。 这是我提出的解决方案。 @Daniel Kuppitz 也有一个有趣的解决方案,您可以在上述主题中找到。
我认为如果在无向图中始终为真,则连通组件遍历的"last"节点要么导致先前访问过的节点(cyclicPath()
),要么度< =1 这个查询应该有效
g.V().repeat(both('e')).until( cyclicPath().or().both('e').count().is(lte(1)) ).dedup().tree().by('name').next()
在我的示例中,它给出了以下输出
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={}}}}
只是为了增强运行良好的@Alberto 版本,您可以使用 simplePath()
遍历步骤 (http://tinkerpop.apache.org/docs/current/reference/#simplepath-step) 来确保遍历器不会重复其通过图的路径
g.V().repeat(both().simplePath())
.until(bothE().count().is(lte(1)))
.dedup().tree().by('name').next()