【问题标题】:UniqueVertices: path or global?UniqueVertices:路径还是全局?
【发布时间】:2021-04-28 01:32:32
【问题描述】:

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

根据 ARANGO 文档:

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

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

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

【问题讨论】:

    标签: arangodb aql


    【解决方案1】:

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

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

    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,e,p IN 1..10 OUTBOUND "vert/A" edge
      OPTIONS { uniqueVertices: "none", uniqueEdges: "path" }
      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"
    ]
    

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

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

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

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-08
      • 2013-01-26
      • 2014-10-17
      • 1970-01-01
      • 1970-01-01
      • 2011-11-25
      相关资源
      最近更新 更多