有人能告诉我为什么Dijkstra算法单源最短路径假定边缘必须是非负的。
我说的只是边缘不负重量周期。
有人能告诉我为什么Dijkstra算法单源最短路径假定边缘必须是非负的。
我说的只是边缘不负重量周期。
回想一下,在Dijkstra算法, 一旦顶点被标记为“关闭”(进出开集的) -算法找到最短路径它,将永远不会再开发这个节点-它假定发展到这个路径路径是最短的。
但随着负权重 - 这可能不是真的。 例如:
A
/ \
/ \
/ \
5 2
/ \
B--(-10)-->C
V={A,B,C} ; E = {(A,C,2), (A,B,5), (B,C,-10)}
Dijkstra算法从A将首先开发C,稍后会无法找到A->B->C
编辑深一点的解释:
请注意,这是很重要的,因为在每个松弛工序中,算法假定“成本”到“封闭”节点确实是最小的,因此,下一个将要选择的节点也微乎其微。
它的想法是:如果我们在开这样的顶点,它的成本是最小的-通过添加任何正数的任何顶点-在极小永远不会改变。
而对正数的限制 - 上面的假设是不正确的。
由于我们“知道”,这是每个顶点“封闭”是最小的 - 我们可以放心地做放松步骤 - 没有“回头看”。 如果我们确实需要“回头看” - 贝尔曼-福特提供这样的递归式(DP)解决方案。
当我提到Dijkstra算法在我的解释,我将谈论的Dijkstra算法如下实施,
这样开始了的值最初被分配给每个顶点是( 在从源到顶点的距离 ),
我们首先提取在Q上的顶点= [A,B,C],其具有最小的值,即A,之后,Q = [B,C]。 注意A具有向边以B和C,也两者都是在Q,因此我们更新两个这些值,
现在我们提取C作为(2 <5),现在Q = [B]。 需要注意的是C连接到什么都没有,所以line16
循环不运行。
最后,我们提取物B,之后, 。 注意B有向边至C,但C是不存在Q中,因此我们再次没有进入中环路line16
,
所以,我们最终的距离为
注意这是怎么错了,因为从A到C的最短距离是5 + -10 = -5,当你去 。
因此,对于这个图Dijkstra算法错误计算从A到C的距离
这是因为Dijkstra算法并不试图找到其已经自Q提取顶点较短的路径。
什么line16
循环做的是顶点u和说:“嘿,看起来我们可以通过u去到v从源代码,是(ALT或替代)的距离比目前的DIST [V]我们还有更好的吗?如果这样可以让更新DIST [v]“
请注意,在line16
他们检查所有邻居V(即从u存在到v的有向边),U的它仍然在Q值 。 在line14
他们remove从Q.访问笔记所以如果x为u的被访问邻居,路径 甚至不被认为是从源到v可能更短的方式。
在上面的例子中,C为B的访问邻居,从而该路径 没有考虑,离开当前的最短路径 不变。
这实际上是有用的,如果边缘的权重都为正数 ,因为那样的话我们就不会浪费我们的时间考虑路径不能缩短 。
所以我说,如果X是自Q 在y之前提取运行该算法时,那么它不可能找到一个路径- 这是较短的。 让我用一个例子来说明这一点,
为Y刚刚被提取和X已经提取自己之前,则DIST [Y]> DIST [X],否则y还得到X之前提取。 ( line 13
分钟距离第一)
正如我们已假设边缘权重是正的,即长度(X,Y)> 0。 所以经由y中的替代距离(ALT)总是一定要更大,即DIST [Y] +长度(X,Y)> DIST [X]。 所以DIST的值[X]就不会被更新,甚至如果y被视为对x的路径,因此,我们得出结论,是有意义的只考虑Y的邻居,其仍然在Q(在附注注释line16
)
但是这件事情取决于我们正沿长度的假设,如果长度(U,V)<0,则取决于如何负即边缘是我们可以在比较之后更换DIST [X] line18
。
因此,任何DIST [X]计算,我们做如果X是所有的顶点v在去除将是不正确-是x为诉与下降沿邻居将它们连接起来-被删除。
因为那些v顶点的是一个潜在的“更好”从源头到X的路径,这是由Dijkstra算法丢弃在倒数第二个顶点。
因此,在例子中,我给上面的错误是因为B在删除之前,C去除。 而C为B的带负边缘的邻居!
只是为了澄清,B和C是A的邻居。 B有一个邻居C和C有没有邻居。 长度(A,B)是顶点a和b之间的边缘长度。
Dijkstra算法假定路径只能成为“重”,所以,如果你有从A权重为3,而从A到C重量为3的路径到B的路径,也没有办法,你可以添加一个边缘从A到C以重量计小于3到B。
这种假设使算法比不得不采取消极的权重考虑算法快。
Dijkstra算法的正确性:
我们有2组顶点在算法的任何步骤。 集A由顶点的,这是我们已经计算的最短路径。 设置B由剩下的顶点。
归纳假设 :在每一步中,我们将假定所有以前的迭代是正确的。
感应步骤 :当我们增加一个顶点V所设定的A和设定的距离为DIST [V],我们必须证明该距离是最佳的。 如果这不是最优的,则必须存在一些其他的路径顶点V是长度短的。
假设这一些其他的路径经过一些顶点X.
现在,由于DIST [V] <= DIST [X],因此任何其他路径到V将是ATLEAST DIST [V]的长度,除非该图具有负边缘的长度。
因此,对于Dijkstra算法工作,边权必须为非负数。
尝试Dijkstra的上下面的图算法,假设A
是源节点,看看发生了什么:
回想一下,在Dijkstra算法,一旦顶点被标记为“关闭”(进出开集的) - 它假定发生的任何节点将导致更大的距离 ,因此,该算法找到最短路径给它,并会再也不用开发这个节点,但这并不在负权重的情况下成立。