Introduce to algorithm--------pseudo code to C/C++ code (chapter 24)

单源最短路径


最短路径问题也是有向图算法领域中的一个经典问题。从某一点到某一点有多条路径可选,如何选择
其中最‘ ’的一条即为最短路径问题。其中‘‘的定义很广泛:如果是交通问题,‘短’也
可以被描述为到达目的地耗费的时间;如果是运输问题,‘短’有可以被定义为运输耗费的资金…

最短路径有几个变体,中最为熟知的就是单源最短路径。‘单源’即是从单个源节点出发。

通用算法基本点

算法导论中介绍说,单源节点路径问题有通用的算法解。以下是应用于这个通用算法的基本点。

短(权重)

算法导论中将‘短’抽象表示为权重,每条路径上都带有一个权重。(不应该存在权重和为负值的环路
,详见算法导论P376)

环路

最短路径不应该包含环路。(详见算法导论P376)

最短路径表示

算法导论中规定,对于每个节点,维持一个前驱结点,用以导出最短路径的表示。

松弛操作

对每个节点v, 维持一个属性v.d,用来记录从源节点s到节点v最短权重路径的上界(即当前最小路
径值)。称v.d为源节点s到节点v的最短路径估计

对一条边的(u,v)的松弛过程为:首先测试一下是否可以对从s到v的最短路径进行改善。测试方
法是将从节点s到节点u之间的最短路径距离加上u与v之间的最短边权重,并与当前的s到v的最短路
径进行比较,如果前者更小,则对v.d和v.π进行更新。松弛步骤可能降低最短路径的估计值v.d并
更新v的前驱属性v.π。

在通用算法基础上具体化的算法都调用次操作,不同的是每条边进行松弛的次数和松弛边的次序有所不同。

Dijkstra算法


Dijkstra算法解决的是带权重的有向图上单源最短路径问题,该算法要求所有边的权重都为非负值。

Dijkstra算法是通用算法中的一个具体化算法。

初始化

初始化有向图的节点:

  1. 将前驱设为空
  2. 最短路径估计设为无穷大
  3. 选择源节点

Introduce to algorithm--------pseudo code to C/C++ code (chapter 24)_第1张图片

上图选择s为源节点,圆圈中的数值为每个节点的最短估计路径,圆圈上的字母 为节点名
称,边上的数值为权重。

Extract

每次循环提取出所有剩余节点中最短路径估计值最小的节点,表示**从源节点到该节点的
最短路径已被找到**。(提取后,该节点在剩余节点中被去除)

Introduce to algorithm--------pseudo code to C/C++ code (chapter 24)_第2张图片

涂黑节点即为所提取出的节点,右边部分即为剩余节点。

松弛(relax)

对于每个提取出的节点u,对每条以u为出发点的边进行松弛操作(relax)。

Introduce to algorithm--------pseudo code to C/C++ code (chapter 24)_第3张图片

图中提取出的节点为s,可以看到s有两条以它为出发点的有向边,因此分别更新两条有向边的目的
节点t、y。

重复

重复Extract和松弛(relax)操作,直至剩余节点为空。

结果

Introduce to algorithm--------pseudo code to C/C++ code (chapter 24)_第4张图片

灰色描出的有向边即为选出的最‘短’路径。

Code

https://code.csdn.net/snippets/1388077(注:windows8.1,VS2013下编译运行通过)

你可能感兴趣的:(Introduce,to,algorithm,算法导论,Dijkstra,单源最短路径)