[英]Finding shortest path between two nodes in a weighted DAG with negative weights
I have a connected DAG with weighted edges. 我有一个带有加权边缘的已连接DAG。 The weights can be positive or negative.
权重可以为正或负。 And I have a start node called root and a goal node called goal.
我有一个名为root的起始节点和一个名为Goal的目标节点。 I need to find a path from root to goal such that the net weight is as small as possible (if net weight is -ve it's even better) in O(V + E) time.
我需要找到一条从根本到目标的路径,以使净重在O(V + E)时间内尽可能小(如果净重为-ve甚至更好)。
I came up with the following pseudocode which is almost identical to Dijkstra's except it goes to only the goal node instead of all nodes. 我想出了以下伪代码,该伪代码与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])
}
}
Does this algorithm work? 该算法有效吗? Also, I'm not very sure if this is necessarily O(V + E).
另外,我不太确定这是否一定是O(V + E)。
PS: What if the weight upto the current node as I traverse the graph should always be <= k? PS:如果在遍历图形时达到当前节点的权重始终小于等于k怎么办? How can I find the shortest path such that weight of that path throughout the entire path is always <= k in O(V + E) time provided it exists in the graph?
如何找到最短路径,以使该路径在整个路径中的权重始终等于O =(V + E)时间中的k =(在图形中存在)?
There's a very simple algorithm to solve the recurrence described in David's answer: We can use depth-first search with memoization to ensure that at every time all the subproblems that we need to solve the result for the current node are already known. 有一个非常简单的算法可以解决David的答案中描述的重复:我们可以使用带有记忆的深度优先搜索来确保每次都需要知道解决当前节点结果所需的所有子问题。 This implicitly results in the topological order we need:
这隐式导致我们需要的拓扑顺序:
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]
The result is just dfs(root)
结果只是
dfs(root)
For the case where you want to find a shortest path with no prefix ever exceeding weight k , you can use a reverse DFS from the goal: 对于要查找最短路径且没有前缀超过权重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]
The solution is rdfs(goal)
. 解决方案是
rdfs(goal)
。
The key here is acyclic directed graph. 此处的关键是非循环有向图。 If you relax (ie, set d(w) = min(d(w), d(v) + length(v->w))) the arcs in topological order , then every arc, once relaxed, stays relaxed.
如果您放松(即设置d(w)= min(d(w),d(v)+长度(v-> w))),则这些弧以拓扑顺序排列 ,那么一旦放松,每个弧都会保持放松。 By the correctness proof of Bellman--Ford, this means that the distance labels d are correct.
通过Bellman-Ford的正确性证明,这意味着距离标签d是正确的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.