简体   繁体   English

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

[英]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.

相关问题 寻找两个节点之间的最短路径 - Finding shortest path between two nodes 找到两个节点之间的最短距离 - Finding the shortest distance between two nodes 利用负循环找到图上两个节点之间零/负权重的路径 - Finding path of zero/Negative weight between Two Nodes on Graph by Utilizing Negative Cycles 查找两个字符串之间最短路径的数据结构 - Datastrutcture for finding shortest path between two strings 寻找两点之间的最短路径(bfs) - Finding the shortest path between two points(bfs) 提供节点之间的最短路径,以及是否连接了图形 - FInding the shortest path between nodes, and whether a graph is connected 贪婪递归算法,用于为具有节点和边权重的完全二叉树中的所有节点寻找最短路径 - greedy and recursive algorithm for finding shortest path for all nodes in a complete binary tree with node and edge weights Dijkstra算法在大图中找到两个节点之间的最短路径? - Dijkstra algorithm to find shortest path between two nodes in big graph? 在 NxN 矩阵中,什么算法可以找到两个节点之间的最短路径? - In a NxN matrix, what algorithm finds the shortest path between two nodes? 如何使用广度优先搜索获得两个节点之间的最短路径? - How to get shortest path between two nodes with Breadth First Search?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM