floyd算法学习

浪子不回头ぞ 提交于 2020-12-18 09:52:33

1、问题引入

  带权有向图中单源点的最短路径问题可以用地杰斯特拉算法求解,如果要求解图中每一对顶点之间的最短路径,类似可以想到的方法为:每次以一个顶点为源点,重复执行地杰斯特拉算法算法n次,这样,便可以求得每一对顶点之间的最短路径,总的执行时间为O(n3)。

  这里可以采用另外一种求解算法:Floyd算法。

2、Floyd的基本思想为:

  从邻接矩阵a开始进行n次迭代,第一次迭代后a[i,j]的值是从vi到vj且中间不经过变化大于1的顶点的最短路径长度;第k次迭代后a[i,j]的值是从vi到vj且中间不经过变化大于k的顶点的最短路径长度 第n次迭代后a[i,j]的值就是从vi到vj的最短路径长度。

3、算法描述:

  (1) 用数组d[i][j]来记录i,j之间的最短距离。初始化d[i][j],若i=j则d[i][j]=0,
    若i,j之间有边连接则d[i][j]的值为该边的权值,否则d[i][j]的值为max 。
  (2) 对所有的k值从1到n,修正任意两点之间的最短距离,计算d[i][k]+d[k][j]的值,
    若小于d[i][j],则d[i][j]= d[i][k]+d[k][j],否则d[i][j]的值不变。

4、具体实现:

  带权有向图如下:

在b.txt文件中保存的带权有向图的数据为:

其中第一个数据4表述图中有4个节点,其他的四行四列数据表示各个节点之间的路径长度,9999表示两个节点之间不可达。

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class Floyd {

	public static int N;
	public static int[][] f;
	public static int[][] path;
	
	public static void floyd(){
		int i,j,k;
		i = j = k = 0;
		for(i = 0; i < N; ++i)
			for(j = 0; j < N; ++j)
				for(k = 0; k < N; ++k)
					if(f[i][j] > f[i][k] + f[k][j]){
						f[i][j] = f[i][k] + f[k][j];
						path[i][j] = k;
					}
		print();
	}
	
	public static void print(){
		for(int i = 0; i < N; ++i){
			for(int j = 0; j < N; ++j){
				printPath(i, j);
				System.out.print("="+f[i][j]+"\t");
			}
			System.out.println();
		}
	}
	
	public static void printPath(int i, int j){
		if(i == j || path[i][j] == -1)
			System.out.print(i+"->"+j);
		else{
			printPath(i,path[i][j]);
			System.out.print("->"+j);
		}
	}
	
	public static void main(String[] args) {
		String p = "d:/b.txt";
		try {
			Scanner s = new Scanner(new File(p));
			while(s.hasNext()){
				N = s.nextInt();
				f = new int[N][N];
				path = new int[N][N];
				for(int i = 0; i < N; ++i){
					for(int j =0; j < N; ++j){
						f[i][j] = s.nextInt();
						path[i][j] = -1;
					}
				}
				floyd();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}

}




标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!