UniqueVertices:路径还是全局?

问题描述

UniqueVertices: Path 和 UniqueVertices: Global 有什么区别?

根据 araNGO 文档:

  1. path”——保证没有返回带有重复顶点的路径

  2. “全局”——保证每个顶点在遍历过程中最多被访问一次,无论从起始顶点到这个顶点有多少条路径。如果您以最小深度 > 1 开始,则可能根本不会返回在最小深度之前找到的顶点(它仍然可能是路径的一部分)。注意:使用此配置,结果不再具有确定性。如果从 startVertex 到顶点有多个路径,则选择其中之一。需要设置 bfs: true ,因为深度优先搜索的结果是不可预测的。

UniqueVertices global 实际上是做什么的?在遍历过程中最多访问一次顶点意味着什么?

解决方法

考虑这个有 5 个顶点的图,其中包含一个循环 B -> D -> E -> B

Graph with cycle

没有唯一性限制的出站遍历将进入这个循环,并在单个路径上多次访问一些顶点和边,直到达到最大遍历深度:

FOR v,e,p IN 1..10 OUTBOUND "vert/A" edge
  OPTIONS { uniqueVertices: "none",uniqueEdges: "none" }
  RETURN CONCAT_SEPARATOR(" --> ",p.vertices[*]._key)
[
  "A --> B","A --> B --> C","A --> B --> D","A --> B --> D --> E","A --> B --> D --> E --> B","A --> B --> D --> E --> B --> C","A --> B --> D --> E --> B --> D","A --> B --> D --> E --> B --> D --> E","A --> B --> D --> E --> B --> D --> E --> B","A --> B --> D --> E --> B --> D --> E --> B --> C","A --> B --> D --> E --> B --> D --> E --> B --> D","A --> B --> D --> E --> B --> D --> E --> B --> D --> E","A --> B --> D --> E --> B --> D --> E --> B --> D --> E --> B"
]

默认情况下,uniqueVertices"none"uniqueEdges"path"。这些选项可避免同一条边在一条路径上出现两次。这可以防止遍历第二次进入循环(从 B 到 D 的边),但后两条路径仍然包括 B 两次:

FOR v,uniqueEdges: "path" }
  RETURN CONCAT_SEPARATOR(" --> ","A --> B --> D --> E --> B --> C"
]

通过将顶点和边的唯一性限制为 "path",每个路径不会访问任何顶点或边两次。遵循从 E 到 B 的边,因为这是第一次在路径上遇到此边(uniqueEdges"none" 还是 "path" 与此特定图形无关)。但是顶点 B 在一开始就已经被访问过(A --> B --> D),所以遍历在那里停止并且不会第二次包括 B:

FOR v,p IN 1..10 OUTBOUND "vert/A" edge
  OPTIONS { uniqueVertices: "path","A --> B --> D --> E"
]

需要一个不同的示例图来显示 uniqueVertices: "global" 的效果,其中 4 个顶点呈菱形:

Graph with diamond

从 F 开始的出站遍历通过 G 和 H 通向同一个顶点 I。没有顶点或边可能被访问两次,但每个发现的路径可能包含 I:

FOR v,p IN 1..10 OUTBOUND "vert/F" edge
  OPTIONS { bfs: true,uniqueVertices: "path",p.vertices[*]._key)
[
  "F --> G","F --> H","F --> G --> I","F --> H --> I"
]

如果我们现在将顶点的唯一性更改为 "global",则只有一条路径可以以 I 结尾。选择哪条路径(通过 G 或 H)是不确定的:

FOR v,uniqueVertices: "global","F --> G --> I"
]

请注意,uniqueVertices: "global" 需要 bfs: true(广度优先搜索)。虽然它不会使遍历具有确定性,但确实使其更可预测。使用深度优先搜索,它会沿着一条路径向下移动直到结束(或直到达到最大深度),然后才会跟随相同深度的其他边。如果某些路径包含已经访问过的顶点,则遍历将在某些路径上提前停止,但发现路径的顺序未定义,这可能导致为同一查询返回不同的顶点集。另一方面,广度优先搜索可确保返回相同的顶点集,即使所遵循的边可能因运行而异。