数据结构之图论算法(五)——关键路径(Dijkstra算法与Floyd算法)
最短路径
1.最短路径问题
一般是求带权有向图G = (V,E)中的一个或多个点到G中其他各个点的最短路径。
源点:路径上的第一个顶点
终点:最后一个顶点
求解方法:
- 单源点最短路径——迪杰斯特拉(Dijkstra)算法
- 多源点最短路径——佛洛伊德(Floyd)算法
2.Dijkstra算法
——从一个指定给源点到图上其余各点的最短路径
【思路】按路径长度递增的次序产生最短路径
引进一个辅助向量D,每个分量D[i]表示当前所找到的起始点v到每个终点vi的最短路径的长度。
(类比于最小生成树中的closedge数组的使用,每次纳入一个点都更新一次数组,只不过closedge是整个连通分量到其他顶点最短距离,现在是起点V₀到其他各个顶点的最短距离)
- 初始状态:D[ 0 ] = arcs[ v ][ vi ],S = { v }
- 选取当前最短路径:D[ j ] = Min { D[ i ] | vi ∈ V-S},vj就是当前求得的一条从v0出发的最短路径的终点,令S = S U { vj }
- 更新从v到V-S上任一顶点vk的当前最短路径长度: D[ k ] = Min { D[ k ],D[ j ] + arcs[ vj ][ vk ] }
- 重复执行2、3共n-1次
算法满足最优子结构原则
图示如下:
该思想可以表示成下列伪代码:
清除所有点的标号 //这些点的标号使用来表示两点间的距离是否已经算过,//如果标记了就说明算过了,没有标记就要重新计算//这样一来可以避免重复计算,提高效率设d[0] = 0,其他d[i] = INF;循环n次{在所有未标号结点中,选出d值最小的结点x;给结点x标记;对于从x出发的所有边(x, y),更新d[y] = MIN{d[y], d[x]+w[x,y]}; //w[x,y]的值点x和y之间的权值}
代码实现如下:
(图的实现形式:二位数组)
void ShortestPath_DIJ(MGraph G, int v0, PathMartrix &P, int &D){int i, v, w;Status final[MAX_VERTEX_NUM];//final[v]为TRUE当且仅当v∈S,即已经球的从v0到v的最短距离//1.初始化,把任意两点间距离距离都算作无穷大,而且现在done全部为FALSE;//2.设定初始状态for(v = 0;v < G.vexnum; v++){final[v] = FALSE; //表示v0和vi点间的最短距离并没有找到(vi中包括v0)distance[v] = G.arcs[v0][v].adj; //各点和v0的距离放入时时变化的distance数组中distance[v0] = 0;final[v0] = TRUE; //还要考虑边界因素,从v0到v0,distance[v0] = 0,也就是相当于找到了从v0到v0的最短距离了,所以final[v0] = 0;//开始主循环,每次求得v0到vi的最短距离,就把vi并入S集合中(初始状态时,S = {v0})for(i = 1; i < G.vexnum; i++){int min = INFINITY; //min表示当前所知离v0顶点的最近距离(现在是对v0的初始化)for(w = 0; w < G.vexnum; ++w){if(!final[w]) //v0到w点的最短距离没找到,即点w不在S集合中if(distance[w] < min){v = w; min = distance[w];}//说明w里v0点更近}final[v] = TRUE; //循环一边之后,就找到了min距离对应的点//选完点后修改distance数组for(w = 0; w < G.vexnum; w++){if(!final[w]&&((min+G.arcs[v][w].adj)<distance[w])){//看是原来的小还是纳入点后新的通路距离小,如果新点与其他点没有路径,就是INFINITYdistance[w] = min + G.arcs[v][w].adj;}}}}
}
3.Floyd算法
typedef int PathMartrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef int ShortPathTable[MAX_VERTEX_NUM][MAX_VERTEX_NUM];void ShortestPath_FLOYD(MGraph G){int v, w, k;PathMartrix p; //二维数组。用来描绘路径,比如ShortPathTable D; //二维数组,表示出了所有边的大小(所两点之间不存在边,就把边的weight设置成infinty)//初始化:for(v = 0; v < G.vexnum; v++){for(w = 0; w < G.vexnum; v++){D[v][w] = G.arcs[v][w].adj;p[v][w] = w;}}//算法思想:两点之间的原来距离会不会因为加入一个点而减少,如果会,就改变两点之间的最小距离,而且加入的点可以不止一个,可以有n个(包括那两个点本身也是可以的)for(k = 0; k < G.vexnum; k++){ //假设点k为v、w两点之间的插入点for(v = 0; v < G.vexnum; v++){ for(w = 0;w < G.vexnum; w++){if(D[v][w] > D[v][k] + D[k][w]){D[v][w] = D[v][k] + D[k][w]; //若原先的距离大于插入点后的距离,就改变最小距离的值p[v][w] = p[v][k]; //}}}}//路径打印for(v = 0; v < G.vexnum; v++){for(w = v+1; w < G.vexnum; w++){printf("\nV%d-->V%d weight:%d\n", v, w, D[v][w]);k = p[v][w];printf("Path:V%d", v);while(k != w){printf("-->V%d", k);k = p[k][w];}printf("-->%d", w);}}}
数据结构之图论算法(五)——关键路径(Dijkstra算法与Floyd算法)相关推荐
- 【Java数据结构与算法】第二十章 Dijkstra算法和Floyd算法
第二十章 Dijkstra算法和Floyd算法 文章目录 第二十章 Dijkstra算法和Floyd算法 一.Dijkstra算法 1.介绍 2.代码实现 二.Floyd算法 1.介绍 2.代码实现 ...
- 最短路径Dijkstra算法和Floyd算法整理、
转载自:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html 最短路径-Dijkstra算法和Floyd算法 Dijks ...
- Dijkstra算法和Floyd算法对比分析
转载:http://blog.csdn.net/liuyanling_cs/article/details/56330652 首先,Dijkstra算法与Floyd算法都是广度优先搜索的算法.都可以用 ...
- 最短路径—Dijkstra算法和Floyd算法
Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Di ...
- 最短路径:Dijkstra算法和Floyd算法
一.Dijkstra算法(单个顶点到其他顶点的最短距离) 定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层 ...
- Dijkstra算法和Floyd算法详解(MATLAB代码)
一.Dijkstra算法 1.算法简介 Dijkstra算法是由E.W.Dijkstra于1959年提出,又叫迪杰斯特拉算法,它应用了贪心算法模式,是目前公认的最好的求解最短路径的方法.算法解决的是有 ...
- dijkstra算法和floyd算法(C语言)
dijkstra算法: /* 邻接表存储 - 无权图的单源最短路算法 *//* dist[]和path[]全部初始化为-1 */ void Unweighted ( LGraph Graph, int ...
- 最短路径(Dijkstra算法和Floyd算法)
最短路径 在图中,不可避免要解决的一个问题就是计算两点之间的最短路径,对于图结构来说,两个点之间不一定只有一条路径,那么如何才能找出最短的那一条就是图中最短路径问题.最短路径问题在实际生活中应用十 ...
- 任意两点最短路floyd算法matlab,多源最短路——Floyd算法
Floyd算法 问题的提出:已知一个有向网(或者无向网),对每一对定点vi!=vj,要求求出vi与vj之间的最短路径和最短路径的长度. 解决该问题有以下两种方法: (1)轮流以每一个定点为源点,重复执 ...
- 惯性导航算法(五)-等效旋转矢量+双子样算法
文章目录 等效旋转矢量 转动的不可交换性 转动的不可交换性与惯性导航有何关系? 等效旋转矢量 等效旋转矢量多子样算法的理论基础 等效旋转矢量微分方程 等效旋转矢量微分方程的工程近似 等效旋转矢量的双子 ...
最新文章
- 服务高可用:幂等性设计
- 导入Oracle 数据库镜像,创建Oracle虚拟机_01
- linux rm 某个时间以前,(转)linux的一个find命令配合rm删除某天前的文件
- 基础知识回顾——通用序列操作
- 世界服务器系统竞赛,他们为何对ASC世界大学生超算竞赛情有独钟?
- “十四五”国家重点研发计划“区块链”重点专项 2022年(附pdf下载地址)
- axvspan函数--Matplotlib
- Win10账户已被锁定解决方法
- IMAGE_DOS_HEADER解析
- 马上过年了,还在为没抢到回家的车票天天犯愁吗?这些好用的抢票神器赶紧用起来吧!...
- 《辛雷学习方法》读书笔记——第三章 身体
- 实现LZW字典压缩算法
- 柴俊理金:临近公投市场屏息,黄金沥青谨慎而行
- SpringBoot整合lombok日志
- mongodb集群修改IP地址
- i7z命令工具 – 用来查看CPU状况
- Java毕设项目共享充电宝系统(java+VUE+Mybatis+Maven+Mysql)
- oracle 索引的创建和生效
- c语言expand函数,编纂expand(s1,s2)
- 突发!LayUI宣布下线
热门文章
- linux上C++开发——1. C++包管理工具
- 数据挖掘之面临的主要问题
- 基于jsp+mysql+java+ssm高校学生心理测评网站——计算机毕业设计
- 修改live mail路径
- html css 范围选择框,jquery日期范围选择器插件
- 什么是全员营销?企业开展全员营销的好处
- 复现KGAT: Knowledge Graph Attention Network for Recommendation(四)
- 中职计算机教师个人专业发展方向,中职计算机教师工作计划总结
- Word简历中如何插入头像?
- 我的勇者服务器维护3月5日,我的勇者2021年3月5日周礼包兑换码