加权有向无环图的最长路径
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
【讨论】:
以上是关于加权有向无环图的最长路径的主要内容,如果未能解决你的问题,请参考以下文章