首页 > 编程语言 >弗洛伊德算法

弗洛伊德算法

时间:2022-09-29 13:46:02浏览次数:48  
标签:弗洛伊德 matrix int vertex length 算法 顶点 dis

  • 简介
和Dijkstra算法一样,弗洛伊德(Floyd)算法也是一种用于寻找给定的加权图中顶点间最短路径的算法。
该算法名称以创始人之一、1978年图灵奖获得者、斯坦福大学计算机科学系教授罗伯特·弗洛伊德命名

弗洛伊德算法(Floyd)计算图中各个顶点之间的最短路径

迪杰斯特拉算法用于计算图中某一个顶点到其他顶点的最短路径。

弗洛伊德算法 VS 迪杰斯特拉算法:迪杰斯特拉算法通过选定的被访问顶点,求出从出发访问顶点到其他顶点的最短路径;
弗洛伊德算法中每一个顶点都是出发访问点,所以需要将每一个顶点看做被访问顶点,求出从每一个顶点到其他顶点的最短路径
  • 实现步骤
设置顶点vi到顶点vk的最短路径已知为Lik,顶点vk到vj的最短路径已知为Lkj,顶点vi到vj的路径为Lij,
则vi到vj的最短路径为:min((Lik+Lkj),Lij),vk的取值为图中所有顶点,则可获得vi到vj的最短路径

至于vi到vk的最短路径Lik或者vk到vj的最短路径Lkj,是以同样的方式获得
  • 思路分析
将A作为中间顶点情况有
1. C-A-G [9],9表示权值之和
2. C-A-B [12]
3. G-A-B [7]

  • 查看距离表,权值之和小于N,所以替换N,权值之和大于本来的值,则不替换

  • 前驱关系表变为如下,例如CAB中间借用了A

  • 遍历逻辑,中间顶点为A,出发顶点为A,遍历完所有终点,出发顶点为B,再依次遍历所有终点;将中间顶点换为B,再依次遍历出发顶点和终点,依次类推

  • 代码实现

public class FloydAlgorithm {

	public static void main(String[] args) {
		// 测试看看图是否创建成功
		char[] vertex = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' };
		//创建邻接矩阵
		int[][] matrix = new int[vertex.length][vertex.length];
		final int N = 65535;
		matrix[0] = new int[] { 0, 5, 7, N, N, N, 2 };
		matrix[1] = new int[] { 5, 0, N, 9, N, N, 3 };
		matrix[2] = new int[] { 7, N, 0, N, 8, N, N };
		matrix[3] = new int[] { N, 9, N, 0, N, 4, N };
		matrix[4] = new int[] { N, N, 8, N, 0, 5, 4 };
		matrix[5] = new int[] { N, N, N, 4, 5, 0, 6 };
		matrix[6] = new int[] { 2, 3, N, N, 4, 6, 0 };
		
		//创建 Graph 对象
		Graph graph = new Graph(vertex.length, matrix, vertex);
		//调用弗洛伊德算法
		graph.floyd();
		graph.show();
	}

}

// 创建图
class Graph {
	private char[] vertex; // 存放顶点的数组
	private int[][] dis; // 保存,从各个顶点出发到其它顶点的距离,最后的结果,也是保留在该数组
	private int[][] pre;// 保存到达目标顶点的前驱顶点

	// 构造器
	/**
	 * 
	 * @param length
	 *            大小
	 * @param matrix
	 *            邻接矩阵
	 * @param vertex
	 *            顶点数组
	 */
	public Graph(int length, int[][] matrix, char[] vertex) {
		this.vertex = vertex;
		this.dis = matrix;
		this.pre = new int[length][length];
		// 对pre数组初始化, 注意存放的是前驱顶点的下标
		for (int i = 0; i < length; i++) {
			Arrays.fill(pre[i], i);
		}
	}

	// 显示pre数组和dis数组
	public void show() {
		//为了显示便于阅读,我们优化一下输出
		char[] vertex = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' };
		for (int k = 0; k < dis.length; k++) {
			// 先将pre数组输出的一行
			for (int i = 0; i < dis.length; i++) {
				System.out.print(vertex[pre[k][i]] + " ");
			}
			System.out.println();
			// 输出dis数组的一行数据
			for (int i = 0; i < dis.length; i++) {
				System.out.print("("+vertex[k]+"到"+vertex[i]+"的最短路径是" + dis[k][i] + ") ");
			}
			System.out.println();
			System.out.println();
		}

	}
	
	//弗洛伊德算法, 比较容易理解,而且容易实现
	public void floyd() {
		int len = 0; //变量保存距离
		//对中间顶点遍历, k 就是中间顶点的下标 [A, B, C, D, E, F, G] 
		for(int k = 0; k < dis.length; k++) { // 
			//从i顶点开始出发 [A, B, C, D, E, F, G]
			for(int i = 0; i < dis.length; i++) {
				//到达j顶点 // [A, B, C, D, E, F, G]
				for(int j = 0; j < dis.length; j++) {
					len = dis[i][k] + dis[k][j];// => 求出从i 顶点出发,经过 k中间顶点,到达 j 顶点距离
					if(len < dis[i][j]) {//如果len小于 dis[i][j]
						dis[i][j] = len;//更新距离
						pre[i][j] = pre[k][j];//更新前驱顶点
					}
				}
			}
		}
	}
	
}

标签:弗洛伊德,matrix,int,vertex,length,算法,顶点,dis
From: https://www.cnblogs.com/chniny/p/16741182.html

相关文章

  • 数据结构与算法(数组&二维数组)
    数组集合、列表和数组集合:一个或多个元素构成的整体,里面的元素类型不一定相同,且是无序的列表:又称线性列表,有顺序且长度是可变的,没有索引有顺序,可以增删改数组:列表的实......
  • 2022“杭电杯”中国大学生算法设计超级联赛(3)-K - Taxi -曼哈顿+二分
    K-Taxi题意开始给你n个点每个点的坐标\((x_i,y_i)\),权值\(w_i\),一共q次询问,每次询问给你一个点(qx,qy),求该点到前面某个点的距离的最大值是多少。两个点之间的距离定义......
  • 大步小步算法
    大步小步算法(babystepgiantstep,BSGS)是一种用来求解离散对数(即模意义下对数)的算法,即给出\(a^x\equivb\pmodm\)中\(a,b,m\)的值(这里保证\(a\)和\(m\)互质,求......
  • 聚类算法中聚类数量的确定方法
    聚类算法中聚类数量的确定方法聚类算法是对实体进行分组归类的有效方法,也是有利于降低人力工作量的有效手段,例如先用AI聚类方法对实体数据进行聚类分组,再由人工介入指认,能......
  • 荷兰国旗问题与快速排序算法
    荷兰国旗问题与快速排序算法作者:Grey原文地址:博客园:荷兰国旗问题与快速排序算法CSDN:荷兰国旗问题与快速排序算法荷兰国旗问题问题描述给定一个整数数组,给定一个值K......
  • GC 清除算法--常用垃圾回收算法和常用垃圾回收器
    1:Mark-Sweep(标记清除)缺点-- 碎片话特别严重2:Copying(拷贝)找到可用的一半复制到另外一半,再把以前的一半给清除掉; 缺点:浪费内存3:Mark-Compact(标记压缩) --......
  • AcWing 算法提高课 treap平衡树
    1、基本性质tree+heap=treap平衡树包含treap红黑树splaysbtAVL等等splay比较常用treap=①BST二叉搜索树+②heap2、set不能做的操作  ⑤和⑥这种与排名相......
  • DFS算法练习 POJ1111; POJ1129; POJ2245; POJ2657
    POJ1111:importjava.util.Scanner;/***@Authorjinjun99*@DateCreatedin2022/9/279:49*@Description*@Sinceversion-1.0*/publicclassMain{......
  • 16 -- 排序算法之插入排序
    算法介绍:插入排序属于内部排序法,时对于待排序的元素以插入的方式找到改元素的适当位置,以达到排序的目的。【类似于生活中的斗地主游戏,每抓起一张牌按照便把改张牌按照指定......
  • 克鲁斯卡尔算法
    应用场景某城市新增7个站点(A,B,C,D,E,F,G),现在需要修路把7个站点连通各个站点的距离用边线表示(权),比如A–B距离12公里问:如何修路保证各个站点都能连通......