DAG 最长路径

此功能在 Aura 图分析无服务器中不可用。

词汇表

有向

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

有向

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

有向

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

无向

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

无向

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

异构节点

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

异构节点

允许异构节点。该算法对所有选定的节点进行相似处理,无论其标签如何。

异构关系

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

异构关系

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

加权关系

加权特性。该算法支持将关系属性用作权重,通过 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. 参数
名称 类型 默认值 可选 描述

graphName

字符串

不适用

存储在目录中的图名称。

configuration

Map

{}

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

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

nodeLabels

字符串列表

['*']

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

relationshipTypes

字符串列表

['*']

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

concurrency

整数

4 [1]

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

jobId

字符串

内部生成

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

logProgress

布尔值

true

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

relationshipWeightProperty

字符串

null

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

1. 在 GDS 会话中,默认值为可用处理器数量。

表 3. 结果
名称 类型 描述

索引

整数

找到路径的 0-基索引。

sourceNode

整数

路径的源节点。

targetNode

整数

路径的目标节点。

totalCost

浮点数

从源到目标的总成本。

nodeIds

整数列表

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

costs

浮点数列表

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

path

路径

表示为 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. 结果
索引 sourceNode targetNode totalCost nodeNames costs path

0

"原木"

"原木"

0.0

["原木"]

[0.0]

[节点[0]]

1

"原木"

"木材"

1.0

["原木", "木材"]

[0.0, 1.0]

[节点[0], 节点[1]]

2

"螺丝"

"制桌工坊"

3.0

["螺丝", "制桌工坊"]

[0.0, 3.0]

[节点[2], 节点[3]]

3

"螺丝"

"螺丝"

0.0

["螺丝"]

[0.0]

[节点[2]]

4

"螺丝"

"桌子"

4.0

["螺丝", "制桌工坊", "桌子"]

[0.0, 3.0, 4.0]

[节点[2], 节点[3], 节点[4]]

© . All rights reserved.