加权有向无环图的最长路径

Posted

技术标签:

【中文标题】加权有向无环图的最长路径【英文标题】:Longest path for weighted directed acyclic graph 【发布时间】:2012-12-05 11:31:37 【问题描述】:

我正在尝试将这个问题概念化,然后为它编写 Java 代码。我知道这里有一些讨论,但我没有看到很多回答者,所以我想通过写下我的想法来重申这个问题,我希望得到你们的一些反馈。谢谢!

我的想法: 对于每个叶节点 找到从根节点到它的最长路径 对于所有路径 求最大路径长度

但是,这不就是蛮力吗?有没有更优雅的解决方案?

我听说过使用负权重的 Djikstra 算法,但在某些地方它说这仅适用于特定情况?我还看到了有关 Bellman Ford 算法的建议,但这不是用来找到最短路径的吗?

谢谢!!

【问题讨论】:

【参考方案1】:

我认为您应该做的是计算根到叶的所有最短路径,然后取计算出的路径中最长的。一般来说,这将是一个难题,但幸运的是,您使用的是有向无环图。在实践中,由于这种限制,该算法将执行得非常好。以下代码可能对您有所帮助,它是使用 yWorks 开发的,取自 site:

// To hold an edge list for every path. 
YList allShortestPaths = new YList();

// The actual number of proper shortest paths is unknown, so we start with a really great value for 'k'. 
YCursor pathCursor = ShortestPaths.kShortestPathsCursor(graph, edgeCostsDP, startNode, endNode, Integer.MAX_VALUE);
if (pathCursor.ok())

  // The first path between the two nodes having least costs. 
  final EdgeList firstPath = (EdgeList)pathCursor.current();
  final double costsOfFirstPath = calculateCostsForPath(firstPath, edgeCostsDP);

  allShortestPaths.add(firstPath);
  pathCursor.next();

  // Look further. 
  while (pathCursor.ok())
  
    EdgeList currPath = (EdgeList)pathCursor.current();
    double currCosts = calculateCostsForPath(currPath, edgeCostsDP);
    // If the current path is also a proper shortest path with costs equal to those 
    // of the first path, then add it to the list. 
    if (!(currCosts > costsOfFirstPath))
    
      allShortestPaths.add(currPath);
      pathCursor.next();
    
    else
      break;
  

【讨论】:

【参考方案2】:

我们可以进行拓扑排序来获得有向无环图(DAG)的顶点的排序。一旦我们有了拓扑排序,我们就可以应用动态规划来获得 DAG 中的最长路径。

令toposort后顶点的索引为0,1,2,....,n-1(图中总共n个顶点)

令 F[i] 为结束于顶点 i 的最长路径的值。

然后对于从 i 到所有 j 的每个出边,我们可以将 F[j] 更新为 F[j]=max(F[j],F[i]+1)

我们可以从将所有 F[i] 初始化为零开始 然后从 i=1 循环到 n-1

最终答案是 maxF[i] 0

【讨论】:

以上是关于加权有向无环图的最长路径的主要内容,如果未能解决你的问题,请参考以下文章

输出有向无环图的所有路径

一个有向无环图的拓扑排序序列是否唯一的

输出有向无环图的所有路径

算法:有向无环图的最短路径

数据结构-图有向无环图的应用

一个有向无环图的拓扑排序序列是唯一的么