使用 Gremlin 查找图中避开给定顶点列表的最短路径?

发布于 2024-12-02 06:56:55 字数 330 浏览 1 评论 0原文

我需要使用 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

但它似乎不起作用。

请帮助!

I need to use Gremlin find the shortest path between two nodes (vertices) while avoiding a list of given vertices.

I already have:

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

To get my shortest path.

I was attempting something like:

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

but it does not seem to work.

Please HELP!!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

心如狂蝶 2024-12-09 06:56:55

您的第二个解决方案看起来是正确的。但是,要明确您要实现的目标。如果 x 和 y 是您想要查找之间最短路径的顶点,并且是在遍历期间要忽略的顶点(如果它的属性名称为:“ignored”),则查询为:

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

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

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 < 5)。

这是通过 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

我希望有帮助。

祝你好运!
马可.

The second solution you have looks correct. However, to be clear on what you are trying to accomplish. If x and y are the vertices that you want to find the shortest path between and a vertex to ignore during the traversal if it has the property name:"ignored", then the query is:

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

If the "list of given vertices" you want filtered is actually a list, then the traversal is described as such:

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

Moreover, I tend to use a range filter just to be safe as this will go into an infinite loop if you forget the >>1 :)

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

Also, if there is a potential for no path, then to avoid an infinitely long search, you can do a loop limit (e.g. no more than 4 steps):

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

Note why the last filter step before paths is needed. There are two reasons the loop is broken out of. Thus, you might not be at y when you break out of the loop (instead, you broke out of the loop because it.loops < 5).

Here is you solution implemented over the Grateful Dead graph distributed with Gremlin. First some set up code, where we load the graph and define two vertices x and 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

Now your traversal. Note that there is not name:"ignored" property, so instead, I altered it to account for the number of performances of each song along the path. Thus, shortest path of songs played more than 10 times in concert:

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

If you use Gremlin 1.2+, then you can use a path closure to provide the names of those vertices (for example) instead of just the raw vertex objects:

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

I hope that helps.

Good luck!
Marko.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文