DAG Kth最短路径动态编程

时间:2013-12-01 22:07:02

标签: algorithm dynamic-programming pseudocode shortest-path directed-acyclic-graphs

这不适用于家庭作业。我正在通过练习测试(未评分)为几周的决赛做准备。我不知道该去哪儿。

令G =(V; E)为n个顶点和m个边的DAG(有向无环图)。

E的每个边(u; v)具有权重w(u; v),其是任意值(正,零或负)。

设k为输入正整数。

如果路径不超过k个边,则G中的路径称为k-link路径。设s和t为G的两个顶点。从s到t的k-link最短路径被定义为从s到t的k-link路径,其具有所有可能的k-link s-to中的边缘权重的最小总和。 G.中的-t路径。

设计一个 O(k(m + n))时间算法来计算从s到t的k-link最短路径。

对此算法的任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

dp[amount][currentVertex]给出G中最短路径的长度,该路径从s开始,在currentVertex结束,由amount边组成。

make all values of dp unset
dp[0][s] = 0

for pathLength in (0, 1, .. k-1)             // (1)
    for vertex in V
        if dp[pathLength][vertex] is set     
            for each u where (vertex, u) is in E    // (2), other vertex of the edge
                if dp[pathLength+1][u] is unset or greater than dp[pathLength][vertex] + cost(vertex, u)
                    set dp[pathLength+1][u] = dp[pathLength][vertex] + cost(vertex, u)

best = dp[k][t]
for pathLength in (0, 1, .. k)
    if dp[pathLength][t] < best
        best = dp[pathLength][t]

上面的算法将给出从G到s的k-link最短路径的长度。它的时间复杂度由循环的复杂性决定(1)。单独的循环(1)具有强制性O(k),而其内部 - (2)简单地遍历图形。如果使用邻接表,则(2)可以在O(n + m)中实现。因此总体复杂度为O(k *(n + m))。

但是,这只会给出路径的长度,而不是路径本身。您可以通过为dp[][]的每个值存储上一个顶点来修改此算法。因此,每当您为某些变量dp[pathLength+1][u]dp[pathLength][vertex] + cost(vertex, u)vertex设置u的值为pathLength时,您就会知道之前使用过的顶点是vertex。因此,您可以将其存储为prev[pathLength+1][u] = vertex

之后,您可以获得您想要的路径。我们的想法是使用您在prev中创建的链接:

pLen = pathLength such that dp[pathLength][t] is minimal
curVertex = t

path = []           // empty array
while pLen >= 0
    insert curVertex in the beginning of path
    curVertex = prev[pLen][curVertex]
    pLen = pLen - 1

path存储了G中从s到t的k-link最短路径。