【问题标题】:Efficient shortest path in DAG with Python's graph-tool使用 Python 的图形工具在 DAG 中实现有效的最短路径
【发布时间】:2023-03-12 14:01:01
【问题描述】:

任务:我想使用 Python 的graph-tool高效计算 DAG(有向无环图)中源节点和目标节点之间的最短路径。我的 DAG 具有负权重。

理论上,这是一个计算上“简单”的问题(即O(V + E)),首先计算图的拓扑排序,然后访问和更新父节点和距离(例如讨论here)。

如何使用graph-tool 有效地实现这一点?

到目前为止我的失败尝试:

  • 在 Python 中手动实现理论上有效的算法。但是,由于我必须遍历图中的每个顶点,这变得非常慢
  • 使用graph-tool 中的shortest_path 函数从Boost Graph Library 调用Dijkstra 例程将具有可接受的运行时间,但没有充分利用DAG 结构,并且无论如何都不适用于负权重
  • 使用shortest_path 调用Bellman-Ford 会返回正确的最短路径,但不会利用DAG 结构并且速度太慢(O(VE))。

高效的 DAG 最短路径算法在底层Boost Graph Library 中实现为dag_shortest_paths。有没有什么方法可以通过graph-tool 访问这个函数,或者通过graph-tool 有效地计算这个函数?

【问题讨论】:

    标签: python graph-tool


    【解决方案1】:

    此功能已添加到 git 版本的 graph-tool 中:

    https://git.skewed.de/count0/graph-tool/commit/012787ecde818efc2b893ad0d8aff819b8deb6ca

    现在可以将可选参数dag=True 传递给shortest_path(),从而实现您想要的效果。

    【讨论】:

    • 谢谢! :) 如果通过dag=True,您能否澄清negative_weights 标志的行为?在试运行时,使用 dag=True, negative_weights=False 调用 shortest_path 比使用 dag=True, negative_weights=True 运行得快得多,即使对于 DAG,负权重不应影响运行时间
    • negative_weights=True 参数触发 Bellman-Ford 算法。使用dag=True时,无需传递negative_weights=True
    【解决方案2】:

    您是否尝试过使用 Networkx 库?据我所知,它很高效,适用于加权图和非加权图,而且使用起来非常简单。

    https://networkx.github.io/documentation/networkx-1.10/reference/generated/networkx.algorithms.shortest_paths.weighted.all_pairs_dijkstra_path.html#networkx.algorithms.shortest_paths.weighted.all_pairs_dijkstra_path

    一个例子:

        >>> import networkx as nx
    
        >>> G=nx.path_graph(5)
        >>> path=nx.all_pairs_dijkstra_path(G)
        >>> print(path[0][4])
    
    [0, 1, 2, 3, 4]
    

    【讨论】:

    • 您好 Eduardo,感谢您的回答,但我明确地在寻找使用 graph-tool 并且可以与净边权重一起使用的解决方案。此外,我希望能够利用 DAG 结构。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多