单源最短路径: Dijkstra 算法

本文详细介绍了Dijkstra算法如何解决有向图中单源最短路径问题,重点阐述了算法的正确性证明及其实现原理。通过贪心策略,Dijkstra算法在非负权重的图上确保找到最短路径。文章还讨论了算法在不同情况下的应用,最终推论在源节点s的有向图上,Dijkstra算法生成的前驱子图是一棵最短路径树。

Dijkstra 算法解决带非负权重的有向图上单源路径最短问题,若实现方法合适,则其运行时间小于 Bellman_Ford 算法。

Dijkstra 算法在运行过程中维持一组关键信息:结点集合S,从源节点 s 到该集合中每个结点的最短路径已经被找到。算法将重复从V - S 中选择最短路径估计最小的结点 u,并对它进行加入到集合、对所有从 u 出发的边进行松弛。

其中,我们用最小优先队列管理结点集合 V - S。与之前相同,我们用最短路径估计来作为队列中结点比较的方式。

Dijkstra(G, w, s)
Initialize_Single_Source(G, s)
S = NULL
Q = G.V
while Q != NULL
      u = Extract_Min(Q);
      S = S∪{u};
      for each vertex v∈G.Adj[u]
          Relax(u, v, w)

该算法由源节点出发开始循环,并在循环中一遍又一遍选择d最小的结点,并通过将它出队列中排出,并松弛由它出发的边。因此可以看到,该算法实行的是贪心算法——选取路径最短的结点并纳入到S中。

定理6(Dijkstra 算法的正确性): Dijkstra 算法运行在带权重的有向图 G = (V, E)时,若所有权重非负,则算法终止时,对于所有结点 v ∈ V,我们有 u.d = δ(s, u)。

证明:

在初始化时,我们有S = NULL,因此直接成立。

在保持的过程中,我们利用反证法进行证明。

我们先假设一个结点 u,它是即将要被划入集合V中的结点。那么利用反证法,那么我们先假设它是第一个加入到集合S时,使得 u.d != δ(s, u)。之后,我们先把这个假设置于一边,通过对从s到u的最短路径

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值