图论应用 floyd(弗洛伊德)算法、dijkstra(迪杰斯特拉)算法
前言
图论应用是非常广泛的,不同于二叉树,二叉树是应用在数据存储结构提高查询效率的,而图论则是用在辅助决策系统中,求得最优化解的等等,而本篇文章中介绍的floyd(弗洛伊德)算法、dijkstra(迪杰斯特拉)算法 是分别用于解决多元路径和最短路径问题的。应用比较广泛。辅助决策系统中使用
弗洛伊德算法
这个算法是为了解决多元路径问题的出现,从而找到最优的路径。 例如 下面的例子
从v1到v3之间的路径上有多种方式,但是权重是不相同的,两个节点之间得最短路径,用下图 邻接矩阵去表示
弗洛伊德算法不管是有向图还是无向图,都能统计出一个节点到另一个节点最短路径,他可以找出整个图中节点之间得最短路径,所以叫多源最短路径算法。在算法实现中,通过邻接矩阵去实现。
算法分析
- 从v0开始,找每个节点得最短路径,把v0给锁住
第一行 就是 v0到v1 和 v0到v2 v0到v3 然后倒过来得距离, 这个初始值,有个点是在v0到v3,如果经过v2权重路径是比v0直接到v3路径短得。 也就是 5和4(3+1)得权重
所以 我们从v1开始 到v2 的最短路径,中转点了 我们从左开始不断进行看点修正
从v1走到v2路径
v1->v2 4
v1->v0->v2 2+1=3
明显经过中间点,就最近了
已经就把以0为跳板将某个点进行修正了最短路径了。v1到v2 以0为中介转折点
看v1到v3 从直观来看就是经过了两个节点,路径最小,因此有可能出现多个中转节点的情况
都经过算一次
这样得出最短路径 ,也就是不断修正数据,经过分析,从一个节点到另一个节点的最短路径
这样就能找到最短的路径了。
另外需要一个路径数据记录好修改的路径,这个需要记录上面的 更改的过程 路径更改的过程,当然这个路径可以任意取值的,我们注意的关键点在于值得修改
这样我们就能记录好其中得跳板节点。
代码实现
首先我们先建两个邻接矩阵
public static final int I = 100;//邻接距阵public static int[][] d = new int[][]{{0, 2, 1, 5},{2, 0, 4, I},{1, 4, 0, 3},{5, I, 3, 0}};public static int[][] p=new int[][]{{0,1,2,3},{0,1,2,3},{0,1,2,3},{0,1,2,3}};
而向矩阵中填数据,则预先填了,生成这个很简单就不用通过代码生成
然后弗洛伊德算法 方法
public static void floyd(){for (int k = 0; k < d.length; k++) {for(int i=0;i<d.length;i++){for (int j = 0; j < d.length; j++) {if(d[i][j]>d[i][k]+d[k][j]){d[i][j]=d[i][k]+d[k][j];//记录下路径p[i][j]=p[i][k];}}}}}
两层循环可以将二维数组都遍历得到, 遍历同时 d[i][j]>d[i][k]+d[k][j] 不断判断,也就是记录更小的数据,进行赋值,并将记录好变化的节点。
时间复杂度是n的三次方。经过三层循环就能找到对应的值,就是通过三层循环去找到对应的值。
迪杰斯特拉算法
上面的弗洛伊德算法算法去求任意两个顶点之间的最优路径问题,性能是比较低的,n的三次方法,但是不能改变的。
而迪杰斯特拉算法,相当于弗洛伊德算法算法的提升,只需要求某个顶点到其他任意顶点的最短路径,起点只能从一个点开始
核心思想
我们用一个v0点为开始点,我们去查找到任意个点的最短路径。
- 首先建立两个集合,假设为U 和V 从那个节点开始,我们就先将节点放到U集合中
以当前节点开始找到最短路径 如果小的路径,继续拿过来
现在从v0到v2的路径有 经过v1和直到的两种方式,然后新建权重数组和路径数组,
权重数组保存经过的权重,而路径数组用来保存前面的顶点
这样不断的往前走,当到v3时,不可达,就直接跳过v3,到v4
最后得到得到下面得权重和路径,
两个集合顶点,一直在计算和修正,这样就能找到一个顶点到后面顶点得最短路径,这就是迪杰斯特拉算法。
在代码中实现,是通过邻阶矩阵,左上进行看最大和最小。
代码实现
首先创建一个邻接矩阵
public static final int I = 100;int[][] array=new int[][]{{0,1,5,I,I,I,I,I,I},{1,0,3,7,5,I,I,I,I},{5,3,0,I,1,7,I,I,I},{I,7,I,0,2,I,3,I,I},{I,5,1,2,0,3,6,I,I},{I,I,7,I,3,0,I,5,I},{I,I,I,3,6,I,0,2,7},{I,I,I,I,9,5,2,0,4},{I,I,I,I,I,I,7,4,0}};
处理顶点,首先要创建两个集合
int k=0;//表示当前正要处理的顶点Vk//初始化相关的信息int[] path=new int[9];int[] weight=array[0];
最开始表示v0智能到v1和v2,然后不断修正
//定义一个数组来存放U和V两个集合的信息int[] flag=new int[9];
就开始逻辑进行修正数据了
//开始逻辑,求VO到某个顶点的最短路径for(int v=1;v<9;v++){//在能走的路径中找到最短的一条int min=I;for(int i=0;i<9;i++){if(flag[i]==0 && weight[i]<min){k=i;//K为U集合到V集合中找到的顶点min=weight[i];//min找到了最小值的位置}}//从这个最短的路径对应的顶点开始找下一轮flag[k]=1;//修正当前最短路径for(int i=0;i<9;i++){//如果经过V顶点的路径比现在的路径短,新更新if(flag[i]==0 && (min+array[k][i])<weight[i]){weight[i]=min+array[k][i];//修改路径长度path[i]=k;//保存前驱}}}
按照之前得思路, 先选择 v0中最小权重得那个顶点,K为U集合到V集合中找到的顶点
//在能走的路径中找到最短的一条int min=I;for(int i=0;i<9;i++){if(flag[i]==0 && weight[i]<min){k=i;//K为U集合到V集合中找到的顶点min=weight[i];//min找到了最小值的位置}}
从这个最短的路径对应的顶点开始找下一轮,这里得修正也是我们只会修正最上面行,weight 数组,以来保证最短的路径
flag[k]=1;//修正当前最短路径for(int i=0;i<9;i++){//如果经过V顶点的路径比现在的路径短,新更新if(flag[i]==0 && (min+array[k][i])<weight[i]){weight[i]=min+array[k][i];//修改路径长度path[i]=k;//保存前驱}}
这里进行修正路径就是按照下面的方式进行修正,如果他下面的值加上左边的任意一个值,小于他就行修正,也就是min+array[k][i]<werght 则进行修改
也就是修正过后就为 [0,1,4,8,6,i,i,i,i],然后继续进行修正, 到2开始继续进行修正
就是继续标记下去,
flage[]={0,0,0,0....}
weight[]={0,1,5,i,i....}
path[]={0,0,0,0}
然后继续看下一行 {0,1,4,8,5,i,i,i,i}
int[][] array=new int[][]{{0,1,4,8,6,I,I,I,I},,{5,1,0,I,1,7,I,I,I},{I,7,I,0,2,I,3,I,I},{I,5,1,2,0,3,6,I,I},{I,I,7,I,3,0,I,5,I},{I,I,I,3,6,I,0,2,7},{I,I,I,I,9,5,2,0,4},{I,I,I,I,I,I,7,4,0}};
最后把值打印出来就行
for(int i=0;i<path.length;i++){System.out.print(path[i]+" ");}System.out.println();for(int i=0;i<weight.length;i++){System.out.print(weight[i]+" ");}
//打印结果int v=8;while(v!=0){System.out.print(path[v]);v=path[v];}
在现实生活中如何去找到最短路径,我们可以提高效率这些
最小生成树
图论中的应用包括下面的最小生成树算法应用非常广泛,一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。 [1] 最小生成树可以用kruskal(克鲁斯卡尔)算法或prim(普里姆)算法求出。
克鲁斯卡尔(Kruskal) 算法
这个算法也是图论算法中使用的,以边进行操作,点先进行排序,最小生成树
总结
图论的应用,弗洛伊德算法和迪杰斯特拉算法,的应用,都是为了寻找最短路径的。应用是相当广泛,提高程序性能,解决最短路径的问题,我们在学习这个算法,对提高自己技术是非常有用的。
图论应用 floyd(弗洛伊德)算法、dijkstra(迪杰斯特拉)算法相关推荐
- 图论基础知识--最小生成树算法kruskal(克鲁斯克尔)和普里姆算法(Prim算法);最短路径算法Dijkstra(迪杰斯特拉)和Floyd(弗洛伊德)
一.基础知识 有向图 无向图 以无向图为例: 邻接矩阵: 度矩阵(对角矩阵): 二.最小生成树 应用:将网络顶点看着城市,边看着城市之间通讯网,边的权重看着成本,根据最小生成树可以构建城市之间 ...
- [转]最短路径算法—Dijkstra(迪杰斯特拉)算法分析与实现
最短路径算法-Dijkstra(迪杰斯特拉)算法分析与实现(C/C++) Dijkstra算法 ----------- 最后更新时间:2011.9.25 ----------- Dijkstra(迪杰 ...
- 最短路径的两种算法(迪杰斯特拉算法和弗洛伊德算法)
一.迪杰斯特拉(Dijkstra)算法 1.定义描述 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩 ...
- 最短路径算法—Dijkstra(迪杰斯特拉)算法分析与实现(C/C++)
Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Dijkstra算法能得出最短路径的最优 ...
- 最短路径之Dijkstra(迪杰斯特拉)算法(无向图)
简介 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.由for循环可知,其时间 ...
- 图 相关算法~从头学算法【广搜、 深搜、 拓扑排序、 并查集、 弗洛伊德算法、迪杰斯特拉算法】
图的相关主流算法主要有: 广度优先搜索 深度优先搜索 拓扑排序 并查集 多源最短路径(弗洛伊德算法) 单源最短路径(迪杰斯特拉算法) 其中呢,最基本的是前两种,也就是平时常用的广搜和深搜,本文中将概要 ...
- JavaScript实现dijkstra迪杰斯特拉算法(附完整源码)
JavaScript实现dijkstra迪杰斯特拉算法 PriorityQueue完整源代码 MinHeap.js完整源代码 Heap.js完整源代码 Comparator.js完整源代码 dijks ...
- C++实现Dijkstra(迪杰斯特拉)算法(附完整源码)
C++Dijkstra迪杰斯特拉算法的实现 C++Dijkstra(迪杰斯特拉)算法的完整源码(定义,实现,main函数测试) C++Dijkstra(迪杰斯特拉)算法的完整源码(定义,实现,main ...
- Dijkstra迪杰斯特拉算法 C++实现
本篇文章主要介绍了Dijkstra迪杰斯特拉算法的C++实现,文章包含两个部分,在第一部分中我会简单介绍迪杰斯特拉算法以及一些个人的理解,第二部分会对C++代码的逻辑进行解释.下面是我已经上传的代码资 ...
- Dijkstra(迪杰斯特拉)算法求单源最短路径问题
Dijkstra(迪杰斯特拉)算法求单源最短路径问题 重要的事情说三遍:代码不是我写的!代码不是我写的!代码不是我写的! 第一个算法是严蔚敏数据结构(C语言版)上写的,第二个算法是王道数据结构上写的, ...
最新文章
- python自学什么书比较好-有什么好的自学 Python 的书籍推荐?
- Steam 导入已下载好的游戏
- PHP+jQuery+Ajax实现用户登录与退出
- Authentication vs. Authorization 验证与授权[整理]
- 图解Oracle 11g physical standby Rolling Upgrade物理备库滚动升级特性
- react——一个todolist的demo
- Delphi之virtual,dynamic,abstract
- amd r5 m330 linux驱动下载,AMDAMD Radeon(TM) R5 M330 14.502.1014.0000显卡驱动官方正式版下载,适用于win8.1-64-驱动精灵...
- 前端学习(3284):立即执行函数三
- linux socket read 接受缓存为空_Linux直接IO、缓存IO、阻塞与同步?
- java 随机化快速排序,JS实现随机化快速排序的实例代码
- QT获取本机IP,本地IP
- ssis 包配置组织程序_如何停止失控的SSIS程序包
- Linux操作Oracle(1)——Linux下 Weblogic启动关闭方法
- zookeeper相关知识与集群搭建
- SANYUKI:净化空气,顺便美颜?
- 基于springboot的医院管理系统
- 职业资格计算机操作员,职业资格 计算机操作员
- python每天定时执行任务_Python设置定时任务
- 树莓派 Pico ADC温度测量
热门文章
- 你不得不掌握的前端提交规范(git cz)
- jvm.option是什么,它是如何加载的
- Html设置背景图模糊,CSS设置背景图片模糊内容不模糊的解决方法
- 中科蓝讯 AB32VG1 RISC-V开发板模块评测任务大挑战
- HTML期末作业-我的大学生活
- 构造和析构:construct,destory
- 阅读笔记_一本书读懂财报
- Python -- 大作业 — 使用turtle库画皮卡丘
- 戴尔微型计算机进bois,dell进bios按什么键 戴尔进bios的方法
- 小米一代扫地机器人磨损家具_为了以后的众测 篇二:无差评居家神器——Mi 小米 扫地机器人...