繁体   English   中英

在负权重的加权DAG中找到两个节点之间的最短路径

[英]Finding shortest path between two nodes in a weighted DAG with negative weights

我有一个带有加权边缘的已连接DAG。 权重可以为正或负。 我有一个名为root的起始节点和一个名为Goal的目标节点。 我需要找到一条从根本到目标的路径,以使净重在O(V + E)时间内尽可能小(如果净重为-ve甚至更好)。

我想出了以下伪代码,该伪代码与Dijkstra的伪代码几乎相同,只不过它只涉及目标节点,而不涉及所有节点。

Q = PriorityQueue()
Q.insert(root, 0)
while (Q is not empty) {
    node = Q.extractMin()
    if (node == goal) {
        return path from node to goal
    }
    else {
        for (x in adjacent[node]) {
            Q.insert(x, weight[x])
    }
}

该算法有效吗? 另外,我不太确定这是否一定是O(V + E)。

PS:如果在遍历图形时达到当前节点的权重始终小于等于k怎么办? 如何找到最短路径,以使该路径在整个路径中的权重始终等于O =(V + E)时间中的k =(在图形中存在)?

有一个非常简单的算法可以解决David的答案中描述的重复:我们可以使用带有记忆的深度优先搜索来确保每次都需要知道解决当前节点结果所需的所有子问题。 这隐式导致我们需要的拓扑顺序:

for all nodes x: 
    dis[x] = UNKNOWN
def dfs(x):
    if x == goal: return 0
    if dis[x] != UNKNOWN: return x
    dis[x] = infinity
    for all edges (x,y) with weight w:
        dis[x] = min(dis[x], w + dfs(y))
    return dis[x]

结果只是dfs(root)

对于要查找最短路径且没有前缀超过权重k的情况 ,可以使用与目标相反的DFS:

for all nodes x: 
    dis[x] = UNKNOWN
def rdfs(x):
    if x == root: return 0
    if dis[x] != UNKNOWN: return x
    dis[x] = infinity
    for all edges (y,x) with weight w:
        dis[x] = min(dis[x], w + rdfs(y))
    if dis[x] > k:
        dis[x] = infinity
    return dis[x]

解决方案是rdfs(goal)

此处的关键是非循环有向图。 如果您放松(即设置d(w)= min(d(w),d(v)+长度(v-> w))),则这些弧以拓扑顺序排列 ,那么一旦放松,每个弧都会保持放松。 通过Bellman-Ford的正确性证明,这意味着距离标签d是正确的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM