单源最短路径,在现实中是很多应用的,是图的经典应用,比如在地图中找出两个点之间的最短距离、最小运费等。单源最短路径的问题:已知图G=(V,E),找出给定源顶点s∈V到每个顶点v∈V的最短路径。单源最短路径衍生出的变体问题如下:

1)单终点最短路径问题:找出从每个顶点v到指定终点t的最短路径。这个是单源最短路径的反向,把图的每条边反向,问题就变成单源最短路径的问题;

2)单对顶点最短路径问题:对于给定顶点u和v,找出从u到v的一条最短路径。找出所有顶点的单源最短路径,该问题自然得解。

3)每队顶点间最短路径问题:对于给定顶点u和v,找出从u到v的最短路径。单独讨论

针对单源最短路径问题,构建如下的数学模型来描述:

给定的带权有向图G=(V,E),加权函数w:E->R为从边到实型权值的映射。路径p=<v0,v1,…,vk>的权是指其组成边的所有权值之和:

如果u到v存在一条路径,则其最小权值的边集合为最短路径。

最短路径算法具有动态规划和贪心算法的最优子结构性质:最短路径的子路径是最短路径,即一条顶点间的最短路径包含路径上其他的最短路径。

对图求解最短路径的问题,存在负权值边和负权回路的情况。经过负权值边,权值会减小,而无限次经过负权回路,权值会趋近-∞,所以一条最短路径是不应该包含负权回路。在最短路径算法总,Dijkstra算法假定图的所有边权值都非负;而Bellman-Ford算法,允许图存在负权边,但不能存在从源点可达的负权回路,该算法还能检测出负权回路。

最短路径之于一个图的发现,其实是一棵有根的最短路径树,只要回溯每个顶点的父顶点即可。定义定点集Vπ为G总所有具有非空前趋(存在负顶点)的顶点集合,再加上源点s。

Vπ={v∈V:π[v]≠null}U{s}

有向边集Eπ是有Vπ中的顶点π值导出的边集:

Eπ={(π[v],v)∈E:v∈Vπ-{s}}

Gπ(Vπ,,Eπ)就是最短路径树,s是根节点。

设图G=(V,E)是带权有向图,其加权函数w:E->R,并假定G中不包含从源点s∈V可达的权值为负的回路,那么最短路径是良定义 。以s为根的最短路径树是有向子图Gπ(Vπ,,Eπ),其中Vπ⊆V,Eπ⊆E,那么:

1)Vπ是G中从s可达的顶点集合;

2)Gπ形成一颗以s为根的有根树;

3)对所有v属于Vπ,Gπ中从s到v的唯一简单路径是G中从s到v的最短路径。

当然最短路径并不是唯一的,最短路径树也是。

导论中给出松弛技术,就是表示紧缩上界的方法。对每个顶点v∈V,设置一个属性d[v],表示从源点s到v的最短路径上权值的上界,称为最短路径估计。松弛操作,对每个顶点d[v]初始为∞,松弛一条边(u,v)可以减小最短路径估计的值d[v],并更新v的前趋π[v]。

Relax_Func(){

if d[v]>d[u]+w(u,v)

then d[v]=d[u]+w(u,v)

π[v]=u

}

松弛操作,通俗地说,就是先设置d[v]最大,然后找出其边权来更新d[v]和π[v],从而不断减小d[v]值,是算法的一种指示变量。

最短路径和松弛操作是最短路径算法的基础,具有三角不等式、上界、无路径、收敛、路径松弛、前趋子图六个性质。还有一个无穷运算的约定:

假定对任何实数a≠-∞,有a+∞=∞+a=∞,出现负权回路下,假定对任何实数a≠∞,有a+(-∞)= (-∞)+a=-∞。

1)Bellman-Ford算法

Bellman-Ford算法支持存在负权边的情况下,解决单源最短路径问题。输入给定的带权有向图G=(V,E),其源点为s,加权函数为w:E->R,执行Bellman-Ford算法后输出一个返回值,表明图中是否存在着一个从源点可达的权为负的回路。如存在,则无解,否则将产生最短路径及其权值。

简单来说,Bellman-Ford算法的执行结果将确认是否存在负权回路,如果没有就会产生最短路径及其权值。具体算法如下:

Func_Bellman-Ford(G,w,s){

Func_Initialize-single-source(G,s);//初始化每个顶点的d和π值

//开始进行松弛操作

for i=1 to |V(G)|-1

do for each edge (u,v)∈E(G)

do Func_Relax(u,v,w)

for each edge(u,v) ∈E(G)

do if d[v]>d[u]+w(u,v)  //已经松弛操作了,如果还存在子顶点大于负顶点权值的情况,则存在负权回路

then return false  //存在负权回路,返回false

return true

}

Func_Relax(u,v,w){

if d[v]>d[u]+w(u,v)

then d[v]= d[u]+w(u,v)

π[v]=u

}

Func_Initialize-single-source(G,s){

for eachvertex v∈V[G]

do d[v]=∞

π[v]=null

d[s]=0

}

Bellman-Ford算法的运行时间为O(VE),主要是如何证明该算法执行结果的正确性。算法导论中通过反证法和三角不等式证明了该算法可以正确计算出从源点出到所有顶点的最小路径的权。

有兴趣可以理解下证明过程,不过中心思想依然是说明不存在负权回路情况下从源点到所有顶点间的最小路径权值。

在有向无回路情况下,按顶点的拓扑序列对某加权dag图(有向无回路图)G=(V,E)的边进行松弛后,可以在⊙(V+E)时间内计算出单源最短路径。Dag图最短路径总是存在的,即使图中有权值为负的边存在,也不可能存在负权回路。

有向无回路图中的单源最短路径算法开始对dag图进行拓扑排序(运用DFS),获得顶点的线性序列。如果从顶点u到v存在一条路径,则在拓扑序列中u先于v;对顶点线性序列的每个顶点做松弛操作即获得单源最短路径。算法的典型应用是在PERT图分析中确定关键路径。关键路径是通过dag的一条最长路径,对应于执行一个有序的工作序列的最长时间。关键路径的权值是完成所有工作所需要时间的下限。理解下就是这个算法适合于序列图。

2)Dijkstra算法

Dijkstra算法解决有向图G=(V,E)上带权的单源最短路径问题,但要求所有边的权值非负,即每条边(u,v)∈E,有w(u,v)≥0。Dijkstra算法有一个顶点集合S,包含具有最短路径的顶点。算法反复选择具有最短路径估计的顶点u∈V-S,将u加入S,对u的所有边进行松弛操作。算法采用了最小优先队列Q来排序关键字为顶点的d值。最小优先队列操作有插入、抽取最小、删除三个操作,不同数据结构实现由不同的时间性能:第一种数组结构,从1到|V|编好号的顶点,简单将d[v]存入一个数组的第v项,插入和删除操作都是O(1),但搜索最小时间是O(V);第二种二叉最小堆结构,时间性能有提升;第三种是斐波那契堆,时间性能也会有提升。Dijkstra算法和最小生成树的Prim算法相似。下面看具体算法:

Func_Relax(u,v,w){

if d[v]>d[u]+w(u,v)

then d[v]= d[u]+w(u,v)

π[v]=u

}

Func_Initialize-single-source(G,s){

for eachvertex v∈V[G]

do d[v]=∞

π[v]=null

d[s]=0

}

Func_Dijkstra(G,w,s){

Func_Initialize-single-source(G,s)

S=∅

Q=V[G] //包含所有顶点,最小优先队列插入

While Q≠∅

do u=Extract-Min(Q) //最小优先队列搜索最小值

S=SU{u}

for each vertex v∈Adj[u]//所有u的邻接表中的顶点

do Func_Relax(u,v,w) //包含最小优先队列u出列

}

Dijkstra算法总是在V-S中选择最轻或最近的顶点插入集合S中,是一种贪心策略。算法导论中证明了Dijkstra算法应用贪心策略可以得出最短路径。证明过程采用的数学思路也很值得去细细品味,包括最短路径的性质的证明:三角不等式、上界性质、无路径性质、收敛性质、路径松弛性质和前驱子图性质(构建以s为根的最短路径树)。在算法中,树和图是有着紧密联系。

3)差分约束系统与最短路径

将计算机中的某类问题求解转化成数学模型来求解,是一以贯之的。同样的,将不包含负权回路的图G=(V,E)求解单源最短路径问题转为线性规划中的差分约束系统模型来求解,而Bellman-Ford算法实际就是一种线性规划算法。

一般的线性规划问题(linear-programmingproblem)中,给定一个mXn的矩阵A,一个m维向量b和一个n维向量c,找出由n个元素组成的向量x,在由Ax≤b所给出的m个约束条件下,使目标函

算法导论之单源最短路径相关推荐

  1. 贪心算法单源点最短路径例题c语言源代码,Dijkstra算法是解单源最短路径问题的一个贪心算法...

    问题描述 给定一个带权有向图 G=(V,E) ,其中每条边的权是一个非负实数. 另外,还给定 V 中的一个项点,称为源. 现在我们要计算从源到所有其他各项点的最短路径长度. 这里的长度是指路上各边权之 ...

  2. 最短路径:Dijkstra算法(求单源最短路径)Floyd算法(求各顶点之间最短路径)

    最短路径: 在一个带权图中,顶点V0到图中任意一个顶点Vi的一条路径所经过边上的权值之和,定义为该路径的带权路径长度,把带权路径最短的那条路径称为最短路径. DiskStra算法: 求单源最短路径,即 ...

  3. 最小生成树之迪杰斯特拉算法(Dijkstra算法)之单源最短路径

    贪心法算法思想 1.通过Dijkstra计算图G中的最短路径时,需要指定起点s(即从顶点s开始计算). 2.此外,引进两个集合S和U.S的作用是记录已求出最短路径的顶点(以及相应的最短路径长度),而U ...

  4. 单源最短路径算法java_数据结构 - 单源最短路径之迪杰斯特拉(Dijkstra)算法详解(Java)...

    给出一个图,求某个端点(goal)到其余端点或者某个端点的最短路径,最容易想到的求法是利用DFS,假设求起点到某个端点走过的平均路径为n条,每个端点的平均邻接端点为m,那求出这个最短路径使用DFS算法 ...

  5. dijkstra最短路径算法视频_单源最短路径(1):Dijkstra 算法

    一:背景 Dijkstra 算法(中文名:迪杰斯特拉算法)是由荷兰计算机科学家 Edsger Wybe Dijkstra 提出.该算法常用于路由算法或者作为其他图算法的一个子模块.举例来说,如果图中的 ...

  6. BFS算法之求单源最短路径

    //BFS求两顶点最短距离问题 //总结:图的代码并不像链表,而更像是顺序表,其存储结构使用的是数组的方式. int BFS_Mix_Distance(Graph G,int u,int i) //求 ...

  7. 图算法:2、计算带有负权值的单源最短路径:Bellman-Ford算法

    原文地址:http://www.wutianqi.com/?p=1912 相关文章: 1.Dijkstra算法: http://www.wutianqi.com/?p=1890 2.Floyd算法: ...

  8. 单源最短路径-Dijkstra(迪杰斯特拉算法)

    迪杰斯特拉算法时间复杂度为O(n^2),其中n为顶点个数. 该算法用于求单源最短路径.并且图中的边不允许带负权值. #include <iostream> using namespace ...

  9. 四种不同单源最短路径算法性能比较

    四种不同单源最短路径算法性能比较   一.最短路径问题描述 单源最短路径描述:给定带权有向图G=(V,E),其中每条边的权是非负实数.另外,还给定V中的一个顶点,称之为源.现在要计算从源到其他各顶点的 ...

最新文章

  1. POJ 1061 青蛙的约会(扩展欧几里得)
  2. AlexNet代码解读
  3. 爬虫笔记:爬虫的基本原理
  4. 处理程序“ExtensionlessUrlHandler-Integrated-4.0”在其模块列表中有一个错误模块“ManagedPipelineHandler”...
  5. 认识5G——解开5G的神秘面纱
  6. 在Tomcat中配配置数据源汇总
  7. 你的飞碟在这儿(洛谷-P1200 )
  8. Docker Compose学习之docker-compose.yml编写规则 及 实战案例
  9. webpack Plugin常用 optimization splitChunks UglifyJsPlugin sourceMap
  10. arduino neo 定位不可用_arduino霹雳七彩灯
  11. Linux终端登录微信,Ubuntu18.04安装微信(Linux通用)
  12. php生成svg图片不显示,css svg不显示不出来怎么办
  13. android重写返回按钮点击事件,Android Fragment监听返回键
  14. css基础知识汇总6
  15. 第三十二讲:循环思想(项目三十二:输出小星星图案)
  16. 文华学院大学计算机基础考试数据库ip,文华学院大学计算机基础模拟试卷
  17. 快手资讯|快手推出多档世界杯相关节目
  18. “添翼杯”人工智能创新应用大赛之垃圾分类
  19. 你的华为手机还会卡?那是这3个功能没设置吧,越早关掉越好
  20. 用R语言拟合Eurogenes G25祖源坐标的学习笔记

热门文章

  1. 定制linux版本,Instalinux:在线自由定制 Linux 发行版
  2. 在Linux里安装和启动nginx的方法
  3. BZOJ2208 [Jsoi2010]连通数
  4. Flume概述和简单实例
  5. poj1195 Mobile phones 二维线段树入门
  6. Xcode7 项目转 Xcode6 时 出现问题
  7. [爬虫]通过url获取连接地址中的数据
  8. 实现一个队列类,该类用两个栈来实现
  9. SQL Server 2008备份数据库失败,拒绝访问的原因
  10. ubuntu10.04开启root登陆