DAG 最长路径
术语表
- 有向
-
有向图特性。该算法在有向图上定义良好。
- 有向
-
有向图特性。该算法忽略图的方向。
- 有向
-
有向图特性。该算法不适用于有向图。
- 无向
-
无向图特性。该算法在无向图上定义良好。
- 无向
-
无向图特性。该算法忽略图的无向性。
- 异构节点
-
异构节点完全支持。该算法具有区分不同类型节点的能力。
- 异构节点
-
异构节点允许使用。无论标签如何,该算法对所有选定节点的处理方式相同。
- 异构关系
-
异构关系完全支持。该算法具有区分不同类型关系的能力。
- 异构关系
-
异构关系允许使用。无论类型如何,该算法对所有选定关系的处理方式相同。
- 加权关系
-
加权特性。该算法支持将关系属性用作权重,通过 relationshipWeightProperty 配置参数指定。
- 加权关系
-
加权特性。该算法将每种关系视为同等重要,丢弃任何关系权重值。
- 节点属性
-
节点属性特性。该算法利用节点属性。
简介
对于 DAG(即不包含循环的图)这一特殊情况,可以在线性时间内找到指向图中某个节点的最长路径。
GDS 对该问题的实现基于拓扑排序,并在线性时间内运行。当图不是 DAG 时,任何属于包含至少一个循环的组件的节点都将从结果中排除。也就是说,该实现仅针对构成 DAG 的图组件提供结果。
你可以使用 拓扑排序 来确保该图是一个 DAG。
该算法支持加权图和无权图。目前不支持负权重。
语法
本节介绍了在每种执行模式下执行 DAG 最长路径算法所使用的语法。我们正在描述该语法的命名图变体。要了解有关通用语法变体的更多信息,请参阅 语法概述。
CALL gds.dag.longestPath.stream(
graphName: String,
configuration: Map
) YIELD
index: Integer,
sourceNode: Integer,
targetNode: Integer,
totalCost: Float,
nodeIds: List of Integer,
costs: List of Float,
path: Path
| 名称 | 类型 | 默认 | 可选 | 描述 |
|---|---|---|---|---|
graphName |
字符串 |
|
否 |
存储在目录中的图的名称。 |
配置 |
Map |
|
是 |
算法特定配置和/或图过滤配置。 |
| 名称 | 类型 | 默认 | 可选 | 描述 |
|---|---|---|---|---|
字符串列表 |
|
是 |
使用给定的节点标签过滤命名图。具有任何给定标签的节点都将被包含。 |
|
字符串列表 |
|
是 |
使用给定的关系类型过滤命名图。具有任何给定类型的关系都将被包含。 |
|
整数 |
|
是 |
用于运行算法的并发线程数。 |
|
字符串 |
|
是 |
可以提供一个 ID 以更轻松地跟踪算法的进度。 |
|
布尔值 |
|
是 |
如果禁用,进度百分比将不会被记录。 |
|
字符串 |
|
是 |
用作权重的关系属性名称。如果未指定,算法将作为无权重运行。 |
|
| 名称 | 类型 | 描述 |
|---|---|---|
index |
整数 |
已发现路径的从 0 开始的索引。 |
sourceNode |
整数 |
路径的源节点。 |
targetNode |
整数 |
路径的目标节点。 |
totalCost |
浮点数 |
从源到目标的总成本。 |
nodeIds |
整数列表 |
遍历顺序中路径上的节点 ID。 |
costs |
浮点数列表 |
路径上每个节点的累计成本。 |
path |
路径 |
以 Cypher 实体表示的路径。 |
示例
在本节中,我们将展示在具体图上运行 DAG 最长路径算法的示例。其目的是说明结果的样子,并为如何在实际环境中使用该算法提供指导。我们将使用一个小型的供应链图进行演示,该图由少量按特定模式连接的节点组成。示例图如下所示:
CREATE
(n0:Goods {name: 'Timber'}),
(n1:Goods {name: 'Lumber'}),
(n2:Goods {name: 'Screws'}),
(n3:Workshop {name: 'Table Maker'}),
(n4:Product {name: 'Table'}),
(n0)-[:Processing {time: 1}]->(n1),
(n1)-[:Shipment {time: 0}]->(n3),
(n2)-[:Shipment {time: 3}]->(n3),
(n3)-[:Processing {time: 1}]->(n4)
该图描述了一个简单的供应链,即在“桌子制造坊”(Table Maker workshop)制造桌子的过程。为了获得桌子所需的木材,工作坊需要加工木料,这需要 1 天时间。一旦木材准备好,它就已经在工作坊中了,因此运输它不需要时间。然而,螺丝需要 3 天才能运送到工作坊。只有在工作坊满足所有要求后,才能制造桌子,这个过程需要 1 天。
通往桌子节点的最长路径从螺丝开始,然后是工作坊,最后是桌子,总共需要:4 天。这就是瓶颈路径,也是制造桌子所需的总时间。
MATCH (n)
OPTIONAL MATCH (n)-[r:Processing|Shipment]->(target)
RETURN gds.graph.project("g", n, target, {relationshipProperties: r {.time}})
流模式
流过程(stream procedure)会流式输出图中的每个节点以及指向该节点的最长路径距离。
有关流模式的更多一般性详细信息,请参阅 流 (Stream)。
stream 模式下运行最长路径算法:CALL gds.dag.longestPath.stream("g", {relationshipWeightProperty: "time"})
YIELD index, sourceNode, targetNode, totalCost, nodeIds, costs, path
RETURN
index,
gds.util.asNode(sourceNode).name AS sourceNode,
gds.util.asNode(targetNode).name AS targetNode,
totalCost,
[nodeId IN nodeIds | gds.util.asNode(nodeId).name] AS nodeNames,
costs,
nodes(path) as path
ORDER BY index
我们使用实用函数 asNode 来返回节点名称而不是 ID,以使结果更具可读性。
| index | sourceNode | targetNode | totalCost | nodeNames | costs | path |
|---|---|---|---|---|---|---|
0 |
"Timber"(木料) |
"Timber"(木料) |
0.0 |
["Timber"] |
[0.0] |
[Node[0]] |
1 |
"Timber"(木料) |
"Lumber"(木材) |
1.0 |
["Timber", "Lumber"] |
[0.0, 1.0] |
[Node[0], Node[1]] |
2 |
"Screws"(螺丝) |
"Table Maker"(桌子制造坊) |
3.0 |
["Screws", "Table Maker"] |
[0.0, 3.0] |
[Node[2], Node[3]] |
3 |
"Screws"(螺丝) |
"Screws"(螺丝) |
0.0 |
["Screws"] |
[0.0] |
[Node[2]] |
4 |
"Screws"(螺丝) |
"Table"(桌子) |
4.0 |
["Screws", "Table Maker", "Table"] |
[0.0, 3.0, 4.0] |
[Node[2], Node[3], Node[4]] |