数据结构——图——最短路径DF算法
一、Dijkstra算法(贪心地求最短距离的算法)
在此算法中,我按照自己的理解去命名,理解起来会轻松一些。
#define MAXSIZE 100 #define UNVISITED 0 #define VISITED 1 #define INFINITY 66666typedef struct tool {int visited[MAXSIZE];/*是否已访问的数组,visited[i]表示顶点i已经访问,也就是到顶点i的最短距离已求出*/int known_shortest_distance[MAXSIZE];/*已知的最短距离数组。known_shortest_distance[i]代表从V0到Vi的最短距离*/int previous_vertex[MAXSIZE];/*previous_vertex[i]=j,代表:在从V0到Vi的最短路径上,顶点i的前一个顶点是顶点j*/ } Tool;typedef struct gragh {int num_of_vertexes;int adjacent_matrix[MAXSIZE][MAXSIZE]; } Gragh;void init_tool(Gragh g, Tool &t) {int i = 0;for(i = 0; i < g.num_of_vertexes; i++) {t.visited[i] = UNVISITED;t.known_shortest_distance[i] = g.adjacent_matrix[0][i];t.previous_vertex[i] = 0;} }void dijstra_shortest_distance(Gragh g, Tool &t) {int i, j, x; //循环变量int min_distance, x_index;/*min_distance存储的是当前已知的最短距离数组中从V0到Vx最小的距离;x_index存储的Vx的下标*/init_tool(g, t);for(i = 0; i < g.num_of_vertexes; i++) {min_distance = INFINITY;for(x = 0; x < g.num_of_vertexes; x++) {if(!t.visited[x] && t.known_shortest_distance[x] < min_distance) {min_distance = t.known_shortest_distance[x];x_index = x;}}/*通过上面一个循环,最短距离数组中的最小值就是min_distance;该顶点的下标就是x_index;在当前没有访问且以V0为起点距离最短的顶点中,这个点的下标就是x_index.*/t.visited[x_index] = VISITED;for(j = 0; j < g.num_of_vertexes; j++) {if(!t.visited[j] && (min_distance + g.adjacent_matrix[x_index][j] < t.known_shortest_distance[j])) {t.known_shortest_distance[j] = min_distance + g.adjacent_matrix[x_index][j];t.previous_vertex[j] = x_index;}}}}
如果要求任意两点之间的最短距离:只需在外层加一层循环,把最短距离数组和previous_vertex数组变成二维数组即可。
输出从V0到Vi的最短距离和完整路径:
#include<stack> void print_path(Tool &t, int dest) {int i = dest;stack<int> s;cout << "从V0到V" << i << "的最短距离:" << t.known_shortest_distance[i] << endl;while(t.previous_vertex[i] != 0) {s.push(t.previous_vertex[i]);i = t.previous_vertex[i];}cout << "从V0到V" << i << "的路径:";cout<<"V0";while(!s.empty()) {cout << "->V" << s.top();s.pop();}cout << "->V" << dest; }
一、Floyd算法(不管三七二十一,先把整个图中任意两点的最短距离求出再说)
核心思想:对图中任意两个顶点(即下面代码中的j和k),如果能在其他顶点中(也就是下面代码中的i,在原始版本中,i和j,k可以相同)找到一个顶点i,使得顶点j到顶点i的距离加上顶点i的距离到顶点k的距离比直接从顶点j到顶点k的距离短,那么,就修改顶点j到顶点k的距离。
typedef struct floyd_tool {int known_shortest_distance[MAXSIZE][MAXSIZE];/*已知的最短距离数组。known_shortest_distance[i][j]代表从Vi到Vj的最短距离*/int path_matrix[MAXSIZE][MAXSIZE];/*path_matrix[i][j]=k,代表:在从Vi到Vj的最短路径上,要经过顶点k;用k代替i,直到path_matrix[k][j]=j*/ } FloydTool;void init_floyd_tool(FloydTool &ft, Gragh g) {for(int i = 0; i < g.num_of_vertexes; i++) {for(int j = 0; j < g.num_of_vertexes; j++) {ft.known_shortest_distance[i][j] = g.adjacent_matrix[i][j];ft.path_matrix[i][j] = j;}} }void floyd_shortest_distance(Gragh g,FloydTool &ft) {init_floyd_tool(ft,g);for(int i = 0;i < g.num_of_vertexes; i++){for(int j = 0;j < g.num_of_vertexes;j++){for(int k = 0;k < g.num_of_vertexes;k++){if(ft.known_shortest_distance[j][k] >ft.known_shortest_distance[j][i] + ft.known_shortest_distance[i][k]){ft.known_shortest_distance[j][k] =ft.known_shortest_distance[j][i] + ft.known_shortest_distance[i][k];ft.path_matrix[j][k] = ft.path_matrix[j][i];}}}} }
改进版:
改进依据:由上面初始版本的思想可知,对于任意两个顶点j和顶点k,如果顶点j和顶点i是同一个,那么,最里面一层的比较相当于是D和0+D在比,显然,这是没必要的。或者,如果j和i不相等,但是i不是j的邻接点,那么j到i的距离就是“无穷大”,很显然,通过这个桥梁i是不可能缩短j到k的距离的。所以,有了第一个if;同理,第二个if也是这么来的。然后,初始版本中,最里面两层循环的循环变量都是从0开始的,但是因为我们考虑的是无向图,j到k的距离和k到j的距离是一样的,所以,我在改进版本中减去了重复求k到j的距离。
void floyd_shortest_distance(Gragh g,FloydTool &ft) {init_floyd_tool(ft,g);for(int i = 0;i < g.num_of_vertexes; i++){for(int j = 0;j < g.num_of_vertexes;j++){if(j == i || ft.known_shortest_distance[j][i] == INFINITY)continue;for(int k = j + 1;k < g.num_of_vertexes;k++){if(k == i || ft.known_shortest_distance[k][i] == INFINITY)continue;if(ft.known_shortest_distance[j][k] >ft.known_shortest_distance[j][i] + ft.known_shortest_distance[i][k]){ft.known_shortest_distance[j][k] =ft.known_shortest_distance[j][i] + ft.known_shortest_distance[i][k];ft.path_matrix[j][k] = ft.path_matrix[j][i];}}}} }
输出最短距离和完整路径:
void print_path(FloydTool &ft,int orig,int dest) {cout << "从V"<<orig<<"到V"<<dest<< "的最短距离:" << ft.known_shortest_distance[orig][dest] << endl;cout << "从V"<<orig<<"到V"<<dest<<"的路径:";cout<<"V"<<orig;while(ft.path_matrix[orig][dest] != dest){cout<<"->V"<<ft.path_matrix[orig][dest];orig = ft.path_matrix[orig][dest];}cout << "->V" << dest; }
转载于:https://www.cnblogs.com/fuzhihong0917/p/6262811.html
数据结构——图——最短路径DF算法相关推荐
- 数据结构笔记——最短路径BFS算法
写在前面:科班出身,应届考研党,愿21考研成功上岸,冲冲冲! 目录 一.最短路径问题 二.BFS求无权图的单源最短路径 三.代码实现 四.总结 一.最短路径问题 单源最短路径--BFS算法.Dijks ...
- 【数据结构与算法】带权图最短路径Dijkstra算法
伪代码 //u是源节点 Initialization: N' = {u} for all nodes v if v is a neighbor of u then D(v) = c(u,v) e1se ...
- 漫画:数据结构之最短路径 Dijkstra 算法的优化 | 技术头条
作者小灰,本文经授权转载自程序员小灰(ID:chengxuyuanxiaohui). 在<漫画:图的 "最短路径" 问题>一文中小灰介绍了单源最短路径算法 Dijkst ...
- python棋盘最短路径_Python数据结构与算法之图的最短路径(Dijkstra算法)完整实例...
本文实例讲述了Python数据结构与算法之图的最短路径(Dijkstra算法).分享给大家供大家参考,具体如下: # coding:utf-8 # Dijkstra算法--通过边实现松弛 # 指定一个 ...
- 【数据结构】图(最短路径Dijkstra算法)的JAVA代码实现
最短路径的概念 最短路径的问题是比较典型的应用问题.在图中,确定了起始点和终点之后,一般情况下都可以有很多条路径来连接两者.而边或弧的权值最小的那一条路径就称为两点之间的最短路径,路径上的第一个顶点为 ...
- 【数据结构-图】3.图的最短路径的几种算法(图解+演绎)
最短路径 最短路径的求取有两种经典的算法,分别是Dijkstra算法和Floyd算法 这Dijkstra算法的算法思想是基于贪心算法的,也就是选择权值最小的边 而Floyd算法的算法思想是根据动态规划 ...
- 数据结构(19)图的最小生成树算法
数据结构(19)图的最小生成树算法 前言 普里姆(Prim)算法 克鲁斯卡尔(Kruskal)算法 代码 GraphMtx.h GraphMtx.c Main.c 前言 在有n个顶点的图中,要连接所有 ...
- 数据结构—图(Part Ⅱ)—最小生成树 最短路径
目录 最小生成树 普里姆(Prim)算法 算法实现 运行结果 程序分析 克鲁斯卡尔(Kruskal)算法 算法实现 运行结果 程序分析 最短路径 广度优先搜索(BFS)算法 算法实现 运行结果 程序分 ...
- 数据结构—图及其应用(交通问题,实现最短路径、最短时间、最少费用查询)
数据结构-图及其应用(交通问题,实现最短路径.最短时间.最少费用查询) 1.任务描述 (1).任务: 设计一个城市交通咨询模拟系统,利用该系统实现至少两种最优决策:最短路程到达.最省时到达等线路规划. ...
最新文章
- linux本地agent执行脚本_github 4.4K星|马哥教育企业教练团队研发一款轻量级、无Agent自动化运维平台...
- 三代测序的基本原理、组装方法和应用场景
- ERP顾问在甲方好还是乙方好?
- generate报错 make_如何安装opencv_contrib及解决其安装编译问题
- javaScript第六天(2)
- php实现小说字典功能_PHP实现生成数据字典功能示例
- 生成缩略图代码(转帖)
- 传承开源-耿航2018中国开源云超级人物获奖感言
- 入坑AI一路过来走过的弯路和思考
- union union all
- java学校信息管理系统 论文设计与实现
- yb3防爆电机型号含义_YB3防爆电机和YBX3防爆电机的区别
- java小游戏实战局域网联机_结对编程3——黄金点小游戏实现局域网联机
- js word 预览_Word页眉横线怎么去掉与插入、修改、删除页眉页脚
- 战地2142 我喜欢...
- 高通8953内核模块签名问题解决方法
- 万能命令:快捷直达你想要的在线工具
- Web端编写(四)——查看会议议程
- python中set如何添加元素_python中如何在set中添加元素?语句是什么
- 【机器学习】RBF神经网络原理与Python实现