Dijkstra算法及伪代码

本文图片及算法均来自 《算法导论》,建议阅读英文原版,里面有更加详细的介绍和算法证明。

在进入Dijkstra算法之前先把书中一些关于图的表达表示清楚,会更加的清晰。因为本质上Dijkstra算法是一个基于图的算法,如果不把一些图的基本概念搞清楚可能会出现难于理解或者理解的偏差。所以这里还是觉得,有能力一定要自己去看英文的原版,尽可能的减少翻译或者别人解释所带来的的理解偏差。

图G的基本表示,G = (V,E)。 V(vertex)为图里所有顶点,E(edge)为图里所有的边,w(U,V)为从顶点U到顶点V的权重,可以简单的理解为距离(如果是想找一条最短距离的话),如果要更详细一些的话,一个带权重的图可以表示为G = (V,E,w),w为所有边的权重的集合。

图的表示有两种,如下图所示,这里的所有算法都是基于图是用Adjacency list来表示的(下图b中所示)。比如,G.adj [1] = {2,5}, 说明在图G中,顶点1和顶点2,5相连。
图的简单表示

Dijkstra’s algorithm:
Given: A weighted, directed graph G(V,E) with edge weights w, w stores weight w(u,v) for each edge (u,v) belongs to E. Assume w(u,v) >= 0.
输入:一个有向权重图(无向图也可以),并且各权重大于等于0。起点用source s表示。
返回:?

这里返回的其实是两个数组,一个数组表示起始点source s到各个顶点的最短距离,另一个数组表示在最短路径中,各顶点的前任顶点(predecessor)也可以理解为父顶点,比如我们有一条最短路径从s到b,s -> a -> b, 那么数组里b对应的父顶点就为a。
第一个数组很好理解,我们要求最短的路径嘛,从s到各个顶点的距离直接数组里取出来就行了。
第二个数组是干嘛用的呢?为什么要记录顶点的父顶点呢?很自然,我们不止想要知道最短路径的距离,我们还想知道路径是怎么来的,这时候,我们只要从终点开始,顺着终点的父顶点,一路回溯到起点就可以了。这里也贴一个书里关于打印路径的算法。
在这里插入图片描述
PRINT PATH的参数为图G,起点s,终点v。π 代表的是父顶点,v.π 表示的是顶点v的父顶点,v.π = NIL 说明顶点v没有父顶点。这里的v.π 我们可以把它转换到数组里,其实表达的意思是一致的,但是为了方便表述,接下来都用书中的方法表示。同理,s到v的最短距离可以表示为v.d。

下面总结一下符号表示,v.d 表示s到v的最短距离,v.π 表示v的父顶点。v.π = NIL表示v没有父顶点。

现在直接进行一个Dijkstra的算法。
在这里插入图片描述
下面进入代码解读。
参数:图G,各个边的权重w,起点s。
第一行:初始化。对于所有的顶点v,我们先假设s到顶点的最短距离为∞,相当于最开始我们没有找到路径,∞就表示路径不存在。然后所有顶点的父顶点设成NIL,没有父顶点。最后s.d = 0,这也很好理解,从s到顶点s的最短距离为0,从自己到自己不需要距离。
在这里插入图片描述
第二行:初始化一个空集S。这个S是干嘛用的呢?这个S是用来储存那些已经确定最短路径的顶点的。注意一点,所有的表示都是基于顶点,当我们想知道顶点的最短路径,我们直接去访问那个顶点的属性(attribute),比如v.d,v.π。一开始没有任何确定最短路径的顶点,除了起始点,但我们先不急着把起始点放进去。
第三行:初始化一个集合Q,包括了图里所有的顶点G.V。这里的Q是一种特殊的数据结构,最小优先队列,键为各个顶点的最短距离,v.d,这样每次弹出的都会是最短距离最小的顶点。
第四行到第八行:

  1. Q中弹出从s到顶点最短距离最小的顶点u
  2. 把u加入S
  3. 对每个和u相邻的顶点,做一个“放松”的操作

我们发现我们一直在从Q中弹出顶点(简称Q弹),当顶点都弹完了,并且加入到S中时,整个算法结束,我们就能得到最开始所说的两个量,到此顶点的最短距离,以及此顶点的父顶点

“放松”是什么操作?本质上来说就是找到了一条更加好的路径,代替原来的路径。
在这里插入图片描述
RELAX:参数为顶点u, v以及各边权重。
如果v.d > u.d + w(u,v)? 这是什么意思呢?v.d 我们知道是当前到v的最短距离,如果这个距离大于某个距离,说明它其实并不是最短距离,为什么会这样呢,式子里u.d + w(u,v)是什么意思呢?u.d是当前到u的最短距离,w(u,v)是边 u->v 的距离,说明我们可以先到u,再到v,并且使这两段的距离之和比原来到v的距离短。如果式子成立的话,那么到v的最短距离v.d 就会变成u.d + w(u,v), 而v的父节点将变成u (因为路径中是从u 到 v)。

所以通俗上来说,Dijkstra的第7到8行表示的意思就是,我们想看一看有没有可能通过u,从u到v,来使得它相邻顶点v的最短距离变短,即v.d > u.d + w(u,v), 其实这里的相邻顶点应该取不在S中的顶点,相当于未探索的顶点,而不是所有的相邻顶点,因为有些相邻顶点的可能已经在S中了,那就说明该顶点的最短路径已经确定,不需要再进行操作了。更严谨一些应该是:
for each vertex v in G.adj [u] and v is not in S:
RELAX(u, v, w)
这样可以避免一些多余操作,当然你不加这个判定应该也没事,因为该顶点已经到达最优了,也不会进行“放松”操作。

综上所述,整个算法都是基于顶点的性质来进行的,比如v.d, v.π,还有图的表示是基于Adjacency list,这样的好处就是足够的抽象,足够灵活,让整个算法的表示非常的简洁明了。

  • 12
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在有关算法的书中,有一些叙述非常严谨,但不够全面;另一些涉及了大量的题材,但又缺乏严谨性。本书将严谨性和全面性融为一体,深入讨论各类算法,并着力使这些算法的设计和分析能为各个层次的读者接受。全书各章自成体系,可以作为独立的学习单元;算法以英语和伪代码的形式描述,具备初步程序设计经验的人就能看懂;说明和解释力求浅显易懂,不失深度和数学严谨性。 --------------------------------------------------------------- 目录 Introduction to Algorithms, Third Edition 出版者的话 译者序 前言 第一部分 基础知识 第1章 算法在计算中的作用  1.1 算法  1.2 作为一种技术的算法  思考题  本章注记 第2章 算法基础  2.1 插入排序  2.2 分析算法  2.3 设计算法   2.3.1 分治法   2.3.2 分析分治算法  思考题  本章注记 第3章 函数的增长  3.1 渐近记号  3.2 标准记号与常用函数  思考题  本章注记 第4章 分治策略  4.1 最大子数组问题  4.2 矩阵乘法的Strassen算法  4.3 用代入法求解递归式  4.4 用递归树方法求解递归式  4.5 用主方法求解递归式  4.6 证明主定理   4.6.1 对b的幂证明主定理   4.6.2 向下取整和向上取整  思考题  本章注记 第5章 概率分析和随机算法  5.1 雇用问题  5.2 指示器随机变量  5.3 随机算法  ?5.4 概率分析和指示器随机变量的进一步使用   5.4.1 生日悖论   5.4.2 球与箱子   5.4.3 特征序列   5.4.4 在线雇用问题  思考题  本章注记 第二部分 排序和顺序统计量 第6章 堆排序  6.1 堆  6.2 维护堆的性质  6.3 建堆  6.4 堆排序算法  6.5 优先队列  思考题  本章注记 第7章 快速排序  7.1 快速排序的描述  7.2 快速排序的性能  7.3 快速排序的随机化版本  7.4 快速排序分析   7.4.1 最坏情况分析   7.4.2 期望运行时间  思考题  本章注记 第8章 线性时间排序  8.1 排序算法的下界  8.2 计数排序  8.3 基数排序  8.4 桶排序  思考题  本章注记 第9章 中位数和顺序统计量  9.1 最小值和最大值  9.2 期望为线性时间的选择算法  9.3 最坏情况为线性时间的选择算法  思考题  本章注记 第三部分 数据结构 第10章 基本数据结构  10.1 栈和队列  10.2 链表  10.3 指针和对象的实现  10.4 有根树的表示  思考题  本章注记 第11章 散列表  11.1 直接寻址表  11.2 散列表  11.3 散列函数   11.3.1 除法散列法   11.3.2 乘法散列法   11.3.3 全域散列法  11.4 开放寻址法  11.5 完全散列  思考题  本章注记 第12章 二叉搜索树  12.1 什么是二叉搜索树  12.2 查询二叉搜索树  12.3 插入和删除  12.4 随机构建二叉搜索树  思考题  本章注记 第13章 红黑树  13.1 红黑树的性质  13.2 旋转  13.3 插入  13.4 删除  思考题  本章注记 第14章 数据结构的扩张  14.1 动态顺序统计  14.2 如何扩张数据结构  14.3 区间树  思考题  本章注记 第四部分 高级设计和分析技术 第15章 动态规划  15.1 钢条切割  15.2 矩阵链乘法  15.3 动态规划原理  15.4 最长公共子序列  15.5 最优二叉搜索树  思考题  本章注记 第16章 贪心算法  16.1 活动选择问题  16.2 贪心算法原理  16.3 赫夫曼编码  16.4 拟阵和贪心算法  16.5 用拟阵求解任务调度问题  思考题  本章注记 第17章 摊还分析  17.1 聚合分析  17.2 核算法  17.3 势能法  17.4 动态表   17.4.1 表扩张   17.4.2 表扩张和收缩  思考题  本章注记 第五部分 高级数据结构 第18章 B树  18.1 B树的定义  18.2 B树上的基本操作  18.3 从B树中删除关键字  思考题  本章注记 第19章 斐波那契堆  19.1 斐波那契堆结构  19.2 可合并堆操作  19.3 关键字减值和删除一个结点  19.4 最大度数的界  思考题  本章注记 第20章 van Emde Boas树  20.1 基本方法  20.2 递归结构   20.2.1 原型van Emde Boas结构   20.2.2 原型van Emde Boas结构上的操作  20.3 van Emde Boas树及其操作   20.3.1 van Emde Boas树   20.3.2 van Emde Boas树的操作  思考题  本章注记 第21章 用于不相交集合的数据结构  21.1 不相交集合的操作  21.2 不相交集合的链表表示  21.3 不相交集合森林  *21.4 带路径压缩的按秩合并的分析  思考题  本章注记 第六部分 图算法 第22章 基本的图算法  22.1 图的表示  22.2 广度优先搜索  22.3 深度优先搜索  22.4 拓扑排序  22.5 强连通分量  思考题  本章注记 第23章 最小生成树  23.1 最小生成树的形成  23.2 Kruskal算法和Prim算法  思考题  本章注记 第24章 单源最短路径  24.1 Bellman?Ford算法  24.2 有向无环图中的单源最短路径问题  24.3 Dijkstra算法  24.4 差分约束和最短路径  24.5 最短路径性质的证明  思考题  本章注记 第25章 所有结点对的最短路径问题  25.1 最短路径和矩阵乘法  25.2 Floyd?Warshall算法  25.3 用于稀疏图的Johnson算法  思考题  本章注记 第26章 最大流  26.1 流网络  26.2 Ford\Fulkerson方法  26.3 最大二分匹配  26.4 推送重贴标签算法  26.5 前置重贴标签算法  思考题  本章注记 第七部分 算法问题选编 第27章 多线程算法  27.1 动态多线程基础  27.2 多线程矩阵乘法  27.3 多线程归并排序  思考题  本章注记 第28章 矩阵运算  28.1 求解线性方程组  28.2 矩阵求逆  28.3 对称正定矩阵和最小二乘逼近  思考题  本章注记 第29章 线性规划  29.1 标准型和松弛型  29.2 将问题表达为线性规划  29.3 单纯形算法  29.4 对偶性  29.5 初始基本可行解  思考题  本章注记 第30章 多项式与快速傅里叶变换  30.1 多项式的表示  30.2 DFT与FFT  30.3 高效FFT实现  思考题  本章注记 第31章 数论算法  31.1 基础数论概念  31.2 最大公约数  31.3 模运算  31.4 求解模线性方程  31.5 中国余数定理  31.6 元素的幂  31.7 RSA公钥加密系统  31.8 素数的测试  31.9 整数的因子分解  思考题  本章注记 第32章 字符串匹配  32.1 朴素字符串匹配算法  32.2 Rabin\Karp算法  32.3 利用有限自动机进行字符串匹配  32.4 Knuth?Morris?Pratt算法  思考题  本章注记 第33章 计算几何学  33.1 线段的性质  33.2 确定任意一对线段是否相交  33.3 寻找凸包  33.4 寻找最近点对  思考题  本章注记 第34章 NP完全性  34.1 多项式时间  34.2 多项式时间的验证  34.3 NP完全性与可归约性  34.4 NP完全性的证明  34.5 NP完全问题   34.5.1 团问题   34.5.2 顶点覆盖问题   34.5.3 哈密顿回路问题   34.5.4 旅行商问题   34.5.5 子集和问题  思考题  本章注记 第35章 近似算法  35.1 顶点覆盖问题  35.2 旅行商问题  35.2.1 满足三角不等式的旅行商问题  35.2.2 一般旅行商问题  35.3 集合覆盖问题  35.4 随机化和线性规划  35.5 子集和问题  思考题  本章注记 第八部分 附录:数学基础知识 附录A 求和  A.1 求和公式及其性质  A.2 确定求和时间的界  思考题  附录注记 附录B 集合等离散数学内容  B.1 集合  B.2 关系  B.3 函数  B.4 图  B.5 树   B.5.1 自由树   B.5.2 有根树和有序树   B.5.3 二叉树和位置树  思考题  附录注记 附录C 计数与概率  C.1 计数  C.2 概率 C.3 离散随机变量  C.4 几何分布与二项分布  *C.5 二项分布的尾部  思考题  附录注记 附录D 矩阵  D.1 矩阵与矩阵运算  D.2 矩阵基本性质  思考题  附录注记

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值