Algorithm 迪克斯特拉';负边有向无环图的s算法
Dijkstra算法是否适用于具有负边的图,如果它是非循环的(DAG)?我认为这是因为没有循环就不可能有负循环。这个算法失败还有其他原因吗 谢谢[明天期中考试]考虑一下图表(直接Algorithm 迪克斯特拉';负边有向无环图的s算法,algorithm,dijkstra,directed-acyclic-graphs,Algorithm,Dijkstra,Directed Acyclic Graphs,Dijkstra算法是否适用于具有负边的图,如果它是非循环的(DAG)?我认为这是因为没有循环就不可能有负循环。这个算法失败还有其他原因吗 谢谢[明天期中考试]考虑一下图表(直接1->2,2->4,4->3,1->3,3->5): 最小路径为1-2-4-3-5,成本为-3。但是,Dijkstra将在第一步中设置d[3]=2,d[2]=3,然后从其优先级队列中提取节点3,并设置d[5]=4。由于节点3是从优先级队列中提取出来的,并且Dijkstra不会多次将给定节点推送到其优先级队列,因此它将永远
1->2,2->4,4->3,1->3,3->5
):
最小路径为1-2-4-3-5
,成本为-3
。但是,Dijkstra将在第一步中设置d[3]=2,d[2]=3
,然后从其优先级队列中提取节点3
,并设置d[5]=4
。由于节点3是从优先级队列中提取出来的,并且Dijkstra不会多次将给定节点推送到其优先级队列,因此它将永远不会再次进入优先级队列,因此该算法将无法工作
Dijkstra的算法不适用于负边,周期。没有一个周期,什么都不会改变。贝尔曼福特是一个可以检测到负成本周期,并与负面的优势。如果你有负边缘,Dijkstra就不起作用
如果更改Dijkstra的算法,使其能够多次将节点推送到优先级队列,则该算法将在负成本边缘下工作。但是,如果新算法仍然是Dijkstra的,这是有争议的:我会说你用这种方式得到Bellman Ford,它通常是这样实现的(通常使用FIFO队列,而不是优先级队列)。如果没有负权重,Dijkstra的算法将适用于DAG。因为Dijkstra算法不能给出负加权边图的正确答案。但有时它是基于图类型的。只要边权重为负,Dijkstra的纯实现就会失败。以下变体仍适用于给定的问题场景
有一种更有效的方法可以使用拓扑排序计算DAG的最短路径距离O(V+E)时间。更多详细信息请参见您正在寻找贝尔曼·福特·摩尔。在这种情况下,Dijkstra的算法如何(以及是否)失败取决于Dijkstra的算法在你的教科书中写得有多准确。假设在您提到的已更改的Dijkstra中,节点3再次添加到优先级提示。这不会产生访问节点2的效果。你能解释一下“不止一次推”吗?@Gerard node
2
仍将被访问。首先,从队列中提取节点1
,因为这是开始节点。然后更新距离:d[3]=2,d[2]=3
。将节点3
和2
添加到优先级队列。然后提取3
,因为这是队列中距离它最小的节点。更新d[4]=4,d[5]=4
,并将节点4,5
添加到队列中。然后提取节点2
,更新d[4]=-7,将4`添加到队列中。然后提取节点4
,更新d[3]=-5
,并将节点3
再次添加到队列中,这将导致找到成本-3
的最佳路径@Gerard在经典的Dijkstra算法中,不允许再次将节点3
添加到优先级队列中。当它有d[3]=2
时,我们提取了它之后,我们就不会再添加它了,当有负成本优势时,可能会导致错误的答案。如果我理解正确,你1)删除经典DijkstraIf(endnode.IsVisited)break的停止标准代码>?然后2)你说在经典的Dijkstra中,当一个替代节点被访问时,只有在这种情况下,你才能快速地重新添加到优先级队列中?我相信这会起作用。问题很可能是,在一个大型图形中,可能需要很长时间才能重新访问具有负长度的备选路线。假设一条成功的路线在早期阶段达到-1000,其终点的总距离为+100。由于早期的-1000,可能90%的网络位于优先级队列的顶部,您必须等待,直到最后另一条路由也达到-1000并赢得总距离为+90的算法。
1---(2)---3--(2)--5
| |
(3) (2)
| |
2--(-10)--4