DAG 最长路径

词汇表

有向

有向特征。该算法在有向图上定义良好。

有向

有向特征。该算法忽略图的方向。

有向

有向特征。该算法不在有向图上运行。

无向

无向特征。该算法在无向图上定义良好。

无向

无向特征。该算法忽略图的无向性。

异构节点

异构节点 完全支持。该算法能够区分不同类型的节点。

异构节点

异构节点 允许。该算法对所有选定的节点进行类似处理,而不管其标签如何。

异构关系

异构关系 完全支持。该算法能够区分不同类型的关系。

异构关系

异构关系 允许。该算法对所有选定的关系进行类似处理,而不管其类型如何。

加权关系

加权特征。该算法支持使用关系属性作为权重,通过 relationshipWeightProperty 配置参数指定。

加权关系

加权特征。该算法将每个关系视为同等重要,丢弃任何关系权重的值。

此功能处于 alpha 阶段。有关功能阶段的更多信息,请参阅 API 阶段

简介

在图中找到通往某个节点的最长路径,对于 DAG(即不包含循环的图)的特殊情况,可以在线性时间内完成。

此问题的 GDS 实现基于拓扑排序,并在线性时间内运行。当图不是 DAG 时,属于至少包含一个循环的组件的任何节点都将从结果中排除。也就是说,该实现只会给出形成 DAG 的图的那些组件的结果。

您可以使用 拓扑排序 来确保图是 DAG。

该算法支持加权和未加权图。目前不支持负权重。

用法

此算法的一个用法示例是在供应链图的上下文中。如果边表示供应时间,则到达目标节点的最长路径的距离是从决策到完成制造节点所需的时间。

语法

本节介绍在每种执行模式下执行 DAG 最长路径算法时使用的语法。我们正在描述命名的图语法的变体。要了解有关通用语法变体的更多信息,请参阅 语法概述

示例 1. 每种模式下的最长路径语法
在命名图上以流模式运行 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
表 1. 参数
名称 类型 默认值 可选 描述

图名称

字符串

不适用

存储在目录中的图的名称。

配置

映射

{}

算法特定和/或图过滤的配置。

表 2. 配置
名称 类型 默认值 可选 描述

节点标签

字符串列表

['*']

使用给定的节点标签过滤命名图。将包含具有任何给定标签的节点。

关系类型

字符串列表

['*']

使用给定的关系类型过滤命名图。将包含具有任何给定类型的关系。

并发性

整数

4

用于运行算法的并发线程数。

作业ID

字符串

内部生成

可以提供的 ID,以便更轻松地跟踪算法的进度。

记录进度

布尔值

如果禁用,则不会记录进度百分比。

关系权重属性

字符串

用作权重的关系属性的名称。如果未指定,则算法将运行无权重。

表 3. 结果
名称 类型 描述

索引

整数

找到路径的基于 0 的索引。

源节点

整数

路径的源节点。

目标节点

整数

路径的目标节点。

总成本

浮点数

从源到目标的总成本。

节点ID

整数列表

路径上节点的遍历顺序的 ID。

成本

浮点数列表

路径上每个节点的累积成本。

路径

路径

表示为 Cypher 实体的路径。

示例

在本节中,我们将展示在具体图上运行 DAG 最长路径算法的示例。目的是说明结果是什么样子,并提供有关如何在实际环境中使用该算法的指南。我们将在少量节点以特定模式连接的小型供应链图上执行此操作。示例图如下所示

Visualization of the example graph
以下 Cypher 语句将在 Neo4j 数据库中创建示例图
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 车间构建表格的简单供应链。为了获得表格的木材,车间加工木材,这需要 1 天才能完成。木材准备就绪后,它已经在车间里了,因此运送它需要零时间。但是,螺丝需要 3 天才能运送到车间。只有在车间满足所有要求后,才能建造桌子,这个过程需要 1 天。

到表格节点的最长路径从螺丝开始,然后是车间,然后是表格,总共:4 天。这是瓶颈路径,以及制造表格所需的总时间。

以下 Cypher 语句将图投影到 GDS
MATCH (n)
OPTIONAL MATCH (n)-[r:Processing|Shipment]->(target)
RETURN gds.graph.project("g", n, target, {relationshipProperties: r {.time}})

流过程会流式传输图中的每个节点以及通向该节点的最长路径的距离。

有关一般流模式的更多详细信息,请参阅

以下将在 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,以使结果更易于阅读。

表 4. 结果
索引 源节点 目标节点 总成本 节点名称 成本 路径

0

"木材"

"木材"

0.0

["木材"]

[0.0]

[Node[0]]

1

"木材"

"木料"

1.0

["木材", "木料"]

[0.0, 1.0]

[Node[0], Node[1]]

2

"螺丝"

"制表机"

3.0

["螺丝", "制表机"]

[0.0, 3.0]

[Node[2], Node[3]]

3

"螺丝"

"螺丝"

0.0

["螺丝"]

[0.0]

[Node[2]]

4

"螺丝"

"表格"

4.0

["螺丝", "制表机", "表格"]

[0.0, 3.0, 4.0]

[Node[2], Node[3], Node[4]]