Floyd算法(三)之 Java详解
前面分别通过C和C++实现了弗洛伊德算法,本文介绍弗洛伊德算法的Java实现。
目录
1. 弗洛伊德算法介绍
2. 弗洛伊德算法图解
3. 弗洛伊德算法的代码说明
4. 弗洛伊德算法的源码转载请注明出处:http://www.cnblogs.com/skywang12345/
更多内容:数据结构与算法系列 目录
弗洛伊德算法介绍
和Dijkstra算法一样,弗洛伊德(Floyd)算法也是一种用于寻找给定的加权图中顶点间最短路径的算法。该算法名称以创始人之一、1978年图灵奖获得者、斯坦福大学计算机科学系教授罗伯特·弗洛伊德命名。
基本思想
通过Floyd计算图G=(V,E)中各个顶点的最短路径时,需要引入一个矩阵S,矩阵S中的元素a[i][j]表示顶点i(第i个顶点)到顶点j(第j个顶点)的距离。
假设图G中顶点个数为N,则需要对矩阵S进行N次更新。初始时,矩阵S中顶点a[i][j]的距离为顶点i到顶点j的权值;如果i和j不相邻,则a[i][j]=∞。 接下来开始,对矩阵S进行N次更新。第1次更新时,如果"a[i][j]的距离" > "a[i][0]+a[0][j]"(a[i][0]+a[0][j]表示"i与j之间经过第1个顶点的距离"),则更新a[i][j]为"a[i][0]+a[0][j]"。 同理,第k次更新时,如果"a[i][j]的距离" > "a[i][k]+a[k][j]",则更新a[i][j]为"a[i][k]+a[k][j]"。更新N次之后,操作完成!
单纯的看上面的理论可能比较难以理解,下面通过实例来对该算法进行说明。
弗洛伊德算法图解
以上图G4为例,来对弗洛伊德进行算法演示。
初始状态:S是记录各个顶点间最短路径的矩阵。
第1步:初始化S。
矩阵S中顶点a[i][j]的距离为顶点i到顶点j的权值;如果i和j不相邻,则a[i][j]=∞。实际上,就是将图的原始矩阵复制到S中。
注:a[i][j]表示矩阵S中顶点i(第i个顶点)到顶点j(第j个顶点)的距离。
第2步:以顶点A(第1个顶点)为中介点,若a[i][j] > a[i][0]+a[0][j],则设置a[i][j]=a[i][0]+a[0][j]。
以顶点a[1]6,上一步操作之后,a[1][6]=∞;而将A作为中介点时,(B,A)=12,(A,G)=14,因此B和G之间的距离可以更新为26。
同理,依次将顶点B,C,D,E,F,G作为中介点,并更新a[i][j]的大小。
弗洛伊德算法的代码说明
以"邻接矩阵"为例对弗洛伊德算法进行说明,对于"邻接表"实现的图在后面会给出相应的源码。
1. 基本定义
public class MatrixUDG {
private int mEdgNum; // 边的数量
private char[] mVexs; // 顶点集合
private int[][] mMatrix; // 邻接矩阵
private static final int INF = Integer.MAX_VALUE; // 最大值
...
}
MatrixUDG是邻接矩阵对应的结构体。mVexs用于保存顶点,mEdgNum用于保存边数,mMatrix则是用于保存矩阵信息的二维数组。例如,mMatrix[i][j]=1,则表示"顶点i(即mVexs[i])"和"顶点j(即mVexs[j])"是邻接点;mMatrix[i][j]=0,则表示它们不是邻接点。
2. 弗洛伊德算法
/*
* floyd最短路径。
* 即,统计图中各个顶点间的最短路径。
*
* 参数说明:
* path -- 路径。path[i][j]=k表示,"顶点i"到"顶点j"的最短路径会经过顶点k。
* dist -- 长度数组。即,dist[i][j]=sum表示,"顶点i"到"顶点j"的最短路径的长度是sum。
*/
public void floyd(int[][] path, int[][] dist) {
// 初始化
for (int i = 0; i < mVexs.length; i++) {
for (int j = 0; j < mVexs.length; j++) {
dist[i][j] = mMatrix[i][j]; // "顶点i"到"顶点j"的路径长度为"i到j的权值"。
path[i][j] = j; // "顶点i"到"顶点j"的最短路径是经过顶点j。
}
}
// 计算最短路径
for (int k = 0; k < mVexs.length; k++) {
for (int i = 0; i < mVexs.length; i++) {
for (int j = 0; j < mVexs.length; j++) {
// 如果经过下标为k顶点路径比原两点间路径更短,则更新dist[i][j]和path[i][j]
int tmp = (dist[i][k]==INF || dist[k][j]==INF) ? INF : (dist[i][k] + dist[k][j]);
if (dist[i][j] > tmp) {
// "i到j最短路径"对应的值设,为更小的一个(即经过k)
dist[i][j] = tmp;
// "i到j最短路径"对应的路径,经过k
path[i][j] = path[i][k];
}
}
}
}
// 打印floyd最短路径的结果
System.out.printf("floyd: \n");
for (int i = 0; i < mVexs.length; i++) {
for (int j = 0; j < mVexs.length; j++)
System.out.printf("%2d ", dist[i][j]);
System.out.printf("\n");
}
}
弗洛伊德算法的源码
这里分别给出"邻接矩阵图"和"邻接表图"的弗洛伊德算法源码。
Floyd算法(三)之 Java详解的更多相关文章
- Prim算法(三)之 Java详解
前面分别通过C和C++实现了普里姆,本文介绍普里姆的Java实现. 目录 1. 普里姆算法介绍 2. 普里姆算法图解 3. 普里姆算法的代码说明 4. 普里姆算法的源码 转载请注明出处:http:// ...
- Kruskal算法(三)之 Java详解
前面分别通过C和C++实现了克鲁斯卡尔,本文介绍克鲁斯卡尔的Java实现. 目录 1. 最小生成树 2. 克鲁斯卡尔算法介绍 3. 克鲁斯卡尔算法图解 4. 克鲁斯卡尔算法分析 5. 克鲁斯卡尔算法的 ...
- Dijkstra算法(三)之 Java详解
http://www.cnblogs.com/skywang12345/p/3711516.html
- Floyd算法(二)之 C++详解
本章是弗洛伊德算法的C++实现. 目录 1. 弗洛伊德算法介绍 2. 弗洛伊德算法图解 3. 弗洛伊德算法的代码说明 4. 弗洛伊德算法的源码 转载请注明出处:http://www.cnblogs.c ...
- 拓扑排序(三)之 Java详解
前面分别介绍了拓扑排序的C和C++实现,本文通过Java实现拓扑排序. 目录 1. 拓扑排序介绍 2. 拓扑排序的算法图解 3. 拓扑排序的代码说明 4. 拓扑排序的完整源码和测试程序 转载请注明出处 ...
- 邻接表有向图(三)之 Java详解
前面分别介绍了邻接表有向图的C和C++实现,本文通过Java实现邻接表有向图. 目录 1. 邻接表有向图的介绍 2. 邻接表有向图的代码说明 3. 邻接表有向图的完整源码 转载请注明出处:http:/ ...
- 邻接矩阵有向图(三)之 Java详解
前面分别介绍了邻接矩阵有向图的C和C++实现,本文通过Java实现邻接矩阵有向图. 目录 1. 邻接矩阵有向图的介绍 2. 邻接矩阵有向图的代码说明 3. 邻接矩阵有向图的完整源码 转载请注明出处:h ...
- 邻接表无向图(三)之 Java详解
前面分别介绍了邻接表无向图的C和C++实现,本文通过Java实现邻接表无向图. 目录 1. 邻接表无向图的介绍 2. 邻接表无向图的代码说明 3. 邻接表无向图的完整源码 转载请注明出处:http:/ ...
- 邻接矩阵无向图(三)之 Java详解
前面分别介绍了邻接矩阵无向图的C和C++实现,本文通过Java实现邻接矩阵无向图. 目录 1. 邻接矩阵无向图的介绍 2. 邻接矩阵无向图的代码说明 3. 邻接矩阵无向图的完整源码 转载请注明出处:h ...
随机推荐
- PXE网络启动提示no default or ui configuration directive问题解决
按照 https://help.ubuntu.com/community/DisklessUbuntuHowto 的提示配置完系统,准备网络启动的时候,遇到: Trying to load pxeli ...
- jquery Ajax获取本地json 以及xml文件
$(function() { $("#Button1").click(function() { //按钮单击事件 //打开文件,并通过回调函数处理获取的数据 $.get(" ...
- (转) silverlight 样式学习
原文地址:http://www.cnblogs.com/Joetao/articles/2074727.html <UserControl x:Class="StyleDemo.Mai ...
- Sprint评分表
组名:第七班 姓名:王炳午 1.Cs 小分队: 项目: 游戏与办公的集合一些小的程序的整合有2048,倒计时,记 ...
- 循环处理--sqlserver
alter PROCEDURE [dbo].[sp_gongzi] @gongzi_yf varchar(7) as DECLARE @input_id varchar(20)DECLARE @s ...
- Oracle PL/SQL块
PL/SQL块 简介 :PL/SQL是 Procedure Language & Structured Query Language 的缩写,是ORACLE公司对标准数据库语言的扩展 PL/S ...
- 可在广域网部署运行的QQ高仿版 -- GG叽叽V3.6,增加语音消息、语音留言等功能
自从微信出来后,语音消息和语音留言变得非常流行,按下一个键说话,比打字要方便多了.GG在V3.6版本增加了对语音消息和语音留言(或称为离线语音消息)的支持.这两个功能的实现已经很完整,只是比较遗憾的一 ...
- 探求网页同步提交、ajax和comet不为人知的秘密(上篇)
标题里的技术都是web开发里最常见的技术,但是我想这些常用的技术有很多细节是很多朋友不太清楚的,理解这些细节是我们深入掌握这些技术的一把钥匙,今天我就讲讲我使用这些技术时体会到的这些细节. 同步提交是 ...
- Perl重命名当前目录下的文件
下载的zip包解压后,中文都变成了乱码,就写了个脚本重命名文件. use strict; use warnings; use Cwd; sub main { my $dir = getcwd(); o ...
- 大叔也说Xamarin~Android篇~环境部署与破解
回到目录 现在移动开发很HOT,以至于很多人都转向了它,大叔也不例外,这次有机制接触一下xamarin这个东西,其实之前也用于xamarin,只是用来写网页程序,没有接触到移动开发,对于xamarin ...