【问题标题】:Use Gremlin to find the shortest path in a graph avoiding a given list of vertices?使用 Gremlin 在图中找到最短路径,避免给定的顶点列表?
【发布时间】:2011-11-07 12:00:23
【问题描述】:

我需要使用 Gremlin 找到两个节点(顶点)之间的最短路径,同时避开给定顶点的列表。

我已经有了:

v.bothE.bothV.loop(2){!it.object.equals(y)}.paths>>1

为了得到我的最短路径。

我正在尝试类似:

v.bothE.bothV.filter{it.name!="ignored"}.loop(3){!it.object.equals(y)}.paths>>1

但它似乎不起作用。

请帮忙!!!

【问题讨论】:

  • 您可以使用 neo4j 图算法:docs.neo4j.org/chunked/snapshot/graph-algo.html。当然,您需要在 gremlin 之外进行操作。如果我在嵌入模式下使用 neo4j,我个人将 gremlin 与直接调用 neo4j 结合使用。

标签: graph neo4j traversal gremlin


【解决方案1】:

您的第二个解决方案看起来是正确的。但是,要清楚您要完成的工作。如果 x 和 y 是您要查找之间的最短路径的顶点,并且是在遍历过程中要忽略的顶点(如果它具有属性名称:“ignored”),则查询是:

x.both.filter{it.name!="ignored"}.loop(2){!it.object.equals(y)}.paths>>1

如果你要过滤的“给定顶点列表”实际上是一个列表,那么遍历是这样描述的:

list = [ ... ] // construct some list
x.both.except(list).loop(2){!it.object.equals(y)}.paths>>1

此外,为了安全起见,我倾向于使用范围过滤器,因为如果您忘记了 >>1,这将进入无限循环 :)

x.both.except(list).loop(2){!it.object.equals(y)}[1].paths>>1

另外,如果有可能没有路径,那么为了避免无限长的搜索,你可以做一个循环限制(例如不超过 4 步):

x.both.except(list).loop(2){!it.object.equals(y) & it.loop < 5}.filter{it.object.equals(y)}.paths>>1

注意为什么需要路径之前的最后一个过滤步骤。循环中断的原因有两个。因此,当您跳出循环时,您可能不在 y 处(相反,您跳出循环是因为 it.loops

这是您通过 Gremlin 分发的 Grateful Dead 图实现的解决方案。首先是一些设置代码,我们在其中加载图形并定义两个顶点 x 和 y:

gremlin> g = new TinkerGraph()
==>tinkergraph[vertices:0 edges:0]
gremlin> g.loadGraphML('data/graph-example-2.xml')
==>null
gremlin> x = g.v(89) 
==>v[89]
gremlin> y = g.v(100) 
==>v[100]
gremlin> x.name
==>DARK STAR
gremlin> y.name
==>BROWN EYED WOMEN

现在你的遍历。请注意,没有 name:"ignored" 属性,因此我对其进行了更改以考虑沿路径的每首歌曲的表演次数。因此,最短路径的歌曲在音乐会上播放了 10 次以上:

gremlin> x.both.filter{it.performances > 10}.loop(2){!it.object.equals(y)}.paths>>1
==>v[89]
==>v[26]
==>v[100]

如果您使用 Gremlin 1.2+,那么您可以使用路径闭包来提供这些顶点的名称(例如),而不仅仅是原始顶点对象:

gremlin> x.both.filter{it.performances > 10}.loop(2){!it.object.equals(y)}.paths{it.name}>>1
==>DARK STAR
==>PROMISED LAND
==>BROWN EYED WOMEN

我希望这会有所帮助。

祝你好运! 马尔科。

【讨论】:

  • 很好的答案感谢马尔科。很通过!只有一个问题,我相信你可以为我回答。我无法使用我的问题中所述的查询,但是当我将其更改为: v.bothE.bothV.filter{it.getProperty('name')!='ignored'}.loop(3){ !it.object.equals(y)}.paths>>1 它起作用了,即使用 it.getProperty。这是为什么呢?
  • 这可以按预期工作,因为循环中的管道被评估为广度优先(请参阅groups.google.com/forum/#!msg/gremlin-users/X8sOoijCPhY/…)。如果不是这种情况,那么如果有一个从 x 到 y 通过顶点 a 的 3 步路径,但有一个通过顶点 b 的 2 步路径,并且从两个管道返回的第一个顶点是顶点 a,那么这个管道将返回 3 步路径,而不是最短路径。
猜你喜欢
  • 2023-04-11
  • 2019-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多