

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
求图的最短路径(详谈Floyd和Dijkstra)(注:在这一部分起点、源点意思相近;点的距离、边的长度、权值意思相近)(再注:这里面包含一个隐含知识点,遇到有关图的问题时部分同学会感到无从下手,无法把握数据规模,其实一个包含n个点的图,最多包含n*(n-1)条通路,知道了这一点,也就对数据规模有所把握了。笔者看多许多教参都没有提到这一点,所以想在最开始讲最短路前提一下这一点。这一点也非常好证明,每个点可能有若干的入度和出度,但是每条边只有一个出度一个入度这样两个维度,所以边的数量的规模最人就是n的平方,想要加深理解的话还可以化成一张n行n列的二维表格(一个包含n个点的图),行坐标表示边的入度(出发点),列坐标表示出度(目标点),[i][j]所在的格子就是连接i和j的边,边的数量最多不多于格子的数量即nF,n的平方)(1)最短路径的概念什么是最短路径问题,这个问题有着人量的生产实际背景。爭实上人至海陆空各种运输小至一个人每天上班,都会遇到这一问题。甚至有些问题从表面上看与最短路问题没有什么关系,却也可以归结为最短路问题。设有一个铁路系统连接着若干城市,xO是系统中的一个固定城市(比如首都或者省会城市),在该系统中试求xO到其他各城市的最短路线,这个问题就称为最短路问题。我们用一个带权图表示这个铁路系统,权值表示城市之间的铁路里程,于是最短路问题就归结为在带权图中找出顶点xO到其他顶点y且具有最小权的路径。更一般的最短路问题的提法是:设(D,w)是有正值加权的简单有向图,xO是D中的一个固定顶点,寻找从xO到其他顶点y且具有最小权的有向图。(2)求图的最短路径算法求图中两点的最短路径问题,可归结为①源点(起点)固定,终点不确定的两点间最短路径②求图中任意两点间的最短路径。对于第一类问题,我们经常采用Dijkstra算法;对于第二类问题,我们可以采用Floyd算法。理论上来说先有Dijkstra算法(1959年)后有Floyd算法(1962年),上面的实际问题也是从第一类问题向第二类问题推广,但是我还是准备先讲Floyd算法再讲Dijkstra算法。因为从“特殊”到"一般”(类似于数学中的“数学归纳法”)需要强大的归纳能力,而从学习者的角度出发从“一般”到“特殊”则要简单许多。我们先来比较一下两种算法:Floyd算法是多源最短路算法,时间复杂度为(n的三次方),通常用在点比较少,源点(起点)不固定的问题中,能够解决权值为负的情况。Dijkstra算法是单源最短路算法,时间复杂度通常为(n的平方),不能够解决权值为负的情况。Floyd算法Floyd算法比较简单,就是暴力枚举了所有的可能,将所有可能找遍就知道了两点之间的最短路参数解释Chara数组:储存两点间的距离,Chara[i][j]的值就是点i到点j的距离。n:总共有n个点。p[i][j]:代表对应顶点的最小路径的前驱矩阵MAX:定义最犬值,路不通的情况距离就是MAX算法思想很容易理解,我们从一个点i到另一个点j,无非就两种走法直接从i到j通过中间点k中转,i->k->j所以我们就遍历所有情况,如杲通过某个中转点距离小于直接到达的距离,就更新这两点间的距离。if(Chara[i][j]>Chara[i][k]+Chara[k][j])Chara[i][j]=Chara[i][k]+Chara[k][j];代码//defineMAX65535intChara[N][N],p[N][N];intn,m;voidFloyd(){for(inti=0;i<n;i++){for(intj=O;j<n;j++){P[i】[j冃;〃初始化}}for(intk=O;k<n;k++)〃中介点{for(inti=0;i<n;i++)//起始点源点{for(intj=O;j<n;j++)//目标点终点{if(Chara[i][k]==MAX11Chara[k][j]==MAX)continue;//暂时不通if(Chara[i][j]>Chara[i][k]+Chara[k][j]){〃如果经过下标k顶点路径比原两点间路径更短〃将当前两点权值设为更小的那一个Chara[i][j]=Chara[i][k]+Chara[k][j];p[i]U]=p[i][k];//路径设置经过卜标k的顶点}注:这里的三重循坏相当于先确立(假定)一个中介点,然后穷举源点和终点每个Chara[i][j]里存放的值是i至ljj的距离,注意哦i和j是可以不直接相连的甚至可以有多种通路。Floyd最终穷举了整张图,得到一个n*n的二维表格Chara,整张表格你可以视为是以行坐标i为源点,列坐标j为终点,每个Chara[i]U]的值就是从i到j的最短路的距离。Floyd例题链接/createprogram/article/details/87118930Dijkstra算法Dijkstra算法算是贪心思想实现的,首先把起点到所有点的距离存卞来找个最短的,然后松弛一次再找出最短的,所谓的松弛操作就是,遍历一遍看通过刚刚找到的距离最短的点作为中转站会不会更近,如果更近了就更新距离,这样把所有的点找遍之后就存下了起点到其他所有点的最短距离,下面仔细讲。算法思想在具体讲Dijkstra之前,我们先来做个对比,Floyd算法是穷举了整张图,得到一张二维表,n个点一共n行,第i行的一系列值就表示表示以i为起点到其他各点的最短路径。单源最短路Dijkstra是源点确定时该源点到其他各点的最短路径。聪明的同学一定发现了,哎,这么说来,假如Dijkstra中的源点为iO,那么我在Floyd的二维表找到第iO行不就解决问题了吗?恭喜你,答对了,就是这样。事实上Floyd中的第iO行就是我们所要求的结呆。但是在最开始的两种算法的比较中也提到了Floyd的时间复杂度是n的三次方,他把每一行全都求出来了,而许多实际问题中我们只需要特定的那一行,并且在数据较犬的时候,在算法竞赛中非常容易超时,此时就需要用到Dijkstra算法了。(由此可见Dijkstra其实就是Floyd的一种特殊情况,所以笔者想采用从一般到特殊的叙述方式)回想一下刚刚的Floyd是怎么做的,三重循环首先选出中介值k然后穷举起始点i和目标点joDijkstra里目标点i确定只需要循环k和j即可,二重循坏时间复杂度自然是n的平方了。那么问题来了,直接在Floyd的三重循环里面删除其中的源点循环就可以了吗?答案是否定的。如果部分同学对上文Floyd有一定疑惑的,此时正好可以讲解,为什么从i到j无非就是两种走法呢?就是因为源点在循环,假设现在有另一种最短的情况是i可以先走到i2再走到k再走到j,需要经过两个中介点,那么显然在i直接到k的路要比i走到i2再走到k的路要长,所以你才回选择多走一个中介点嘛,这肯定是经过了一次源点为i中介点为i2终点为k的循环。此时你获得了一个方案1【i】[j]=【i】【k】+【k】[j](其中【i】【k】=【i】[i2]+[i2][k]经过那次循环【i】【k】里的值得到了更新)。但这不是唯一方案哦,另一种方案2是[i][j]=[i][i2]+[i2][j](其中[i2][j]=[i2][k]+【k】[j]),看,就算是四个点两种方案,但最终都变成了形如if(Chara[i][j]>Chara[i][k]+Chara[k][j])Chara[i][j]=Chara[i][k]+Chara[k][j];的式子。所以无论怎么走最终都会只有两种情况,即Chara[i][j]和Chara[i][k]+Chara[k][j]。这个案例中因为要两个中介点都经过所以这两种方案的最终值是相等的。如果还是这四个点i,i2,k,j,但这次我们的走法是i,i2,j不经过k才是最短路径,那么我们的方案应该是[i][j]=[il【i2】+[i21[j]([i2]【j】小于[i2][k]+[k][j])这种方案我们单单去掉Floyd算法中的源点循坏就会发生错误啦。因为,这里需要判断[i2]【j】小于【i2】[k]+[k]【j】,在Floyd中必然需要做一次源点为i2中介值为k终点为j的判断,但是我们单纯的删掉了源点的循坏,源点永远在i永远不会出现在i2的位置上,我们就会与这种方案失之交臂了。所以我们不能单纯的删除源点的循环,而是要完善思路。我们提出的改良方案就是在中介点的这个循环时,中介点不能是任取的。在Floyd中这个中介点可以说是任取的,因为我们直接按编号从1到n循坏着来取得,并没有去考虑权值的问题。改良的核心思路是(当然了学术史上Dijkstra并非Floyd的改良,这里是从学习者的角度看)按从源点i到其余每个顶点的最短路径升序依次求出从源点到各顶点的最短路径。也就是说现在循坏这个中介点的顺序必须是按距离源点的距离升序顺序排列的!接卜•来的操作就和Floyd类似了,下面请看代码。参数解释Chara数组:储存两点间的距离,Chara[i]U]的值就是点i到点j的距离。dis数组:储存起点到各个点的距离,dis[i]就是起点到i点的距离。vis数组:标记点是否访问过INF:宏定义的最大值路不通有两个数组,dis和vis含义参见上面,初始时vis中只有起点,更新dis中的起点到所有点的距离.遍历所有节点,找到距离起点最近的一个点K,将这个点加入vis中标记进行松弛操作,遍历没有在vis数组中的其他所有点,比较起点一一>该点和起点一一水点一一>该点的距离,重复2-3操作,直到所有的点遍历完代码#defineINF65535intn,m,s,t;intChara[N][N],dis[N],vis[N],p[i];voidDijkstra(intsrc)//src传入的起点{for(inti=0;i<m;i卄)〃初始化起点到所有点的距离{dis[i]=Chara[src][i];〃起始位置到i点的距离vis[i]=0;//初始化visitP[i]=0;}dis[src]=0;//到自身距离为0vis[src]=1;//标记注src=0for(inti=0;i<m;i++)//i为此二维表的层数(m个点最多m*m条路i为m层)intans=INF,k;//INF最大距离表示不通for(intj=0;j<m;j++)//寻找未被访问过距离起点vO最近的点{if(!vis[j]&&dis[j]<ans){k=j;
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 交通信号控制系统操作规程
- 三农村电商售后服务与客户关系管理实战指南
- 安装光伏发电划算不
- 汽车 充电桩 新能源
- 课题研究可行性分析格式模板
- 项目进度管理与风险控制的工作计划
- 三农产品三农村市场风险防控方案
- 消防中级监控练习试题及答案
- 中级养老护理练习试题
- 茶艺师复习测试题
- 2023年四川省绵阳市中考数学试卷
- 《统编教材背景下小学语文整本书阅读策略的研究》中期报告
- (正式版)JBT 2930-2024 低压电器产品型号编制方法
- 【课件】2024届新高考英语语法填空专项.解题技巧课件
- 九年级物理《第5节 磁生电》课件(三套)
- 肾上腺腺瘤切除术的围术期护理
- 人工智能在健康管理与疾病预防中的应用
- 高中英语作文感谢信写作格式及范文
- 马工程《思想政治教育学原理 第二版》课后习题详解
- 海康威视公司员工手册
- 第一次月考试卷(试题)2023-2024学年语文三年级下册统编版
评论
0/150
提交评论