任意两点之间的最短路径问题(Floyd算法)--Java语言

我在前面的一篇博客中详细讲到了有权图中的最短路径问题--dijkstra算法,有兴趣的可以点开下面插件温习一下dijkstra算法。但是,dijkstra算法无法解决边权为负的情况。因为dijkstra在对于路径长短的选择上采用了贪心思想。因此,若某一边权为负,则容易忽略该线路。对于dijkstra算法来说,访问点的选择是选择未访问过的点中距离源点最近的点,而不是对每一种路径可能都进行遍历。

有权图中的最短路径问题--Dijkstra算法(Java语言实现)

而Floyd算法,则修正了dijkstra算法对于边权为负问题的不足,引入了一个外循环,来遍历每个点,从而查询该点是不是在i和j之间,这样的话,无论边权为负值还是正值,都会被考虑进去。对于邻接矩阵A来说,在k-1次迭代后,A(k-1)[i][j]为所有从顶点i到j且不经过k之后的顶点的最小长度,有可能经过k之前的点。所以在遍历过程中需要比较A[i][j]与A[i][k]+A[k][j]的大小,取小值,表示比较经过k点与不经过k点的路径长度大小。

代码实现:

import java.util.*;

public class Floyd {
	public static int[][] path;
	public static int[][] floyd(int[][] C,int n)
	{
		path=new int[n][n];
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<n;j++)
			{
				path[i][j]=-1;
			}
		}
		for(int k=0;k<n;k++)
		{
			for(int i=0;i<n;i++)
			{
				for(int j=0;j<n;j++)
				{
					if(C[i][k]!=Integer.MAX_VALUE&&C[k][j]!=Integer.MAX_VALUE&&C[i][k]+C[k][j]<C[i][j])
					{
						C[i][j]=C[i][k]+C[k][j];
						path[i][j]=k;
					}
					
				}
			}
		}
		return C;
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int a=Integer.MAX_VALUE;
		int[][] C= {{0,a,10,a,30,100},{a,0,5,a,a,a},{a,a,0,50,a,a},{a,a,a,0,a,10},
				{a,a,a,20,0,60},{a,a,a,a,a,0}};
		int n=C.length;
		int[][] route=floyd(C,n);
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<n;j++)
			{
				if(i==j) continue;
				else if(route[i][j]==a)
					System.out.println(i+"到"+j+"之间没路径");
				else
					System.out.println(i+"到"+j+"之间的最短路径长度为:"+route[i][j]);
			}
		}

	}

}
测试结果:

0到1之间没路径
0到2之间的最短路径长度为:10
0到3之间的最短路径长度为:50
0到4之间的最短路径长度为:30
0到5之间的最短路径长度为:60
1到0之间没路径
1到2之间的最短路径长度为:5
1到3之间的最短路径长度为:55
1到4之间没路径
1到5之间的最短路径长度为:65
2到0之间没路径
2到1之间没路径
2到3之间的最短路径长度为:50
2到4之间没路径
2到5之间的最短路径长度为:60
3到0之间没路径
3到1之间没路径
3到2之间没路径
3到4之间没路径
3到5之间的最短路径长度为:10
4到0之间没路径
4到1之间没路径
4到2之间没路径
4到3之间的最短路径长度为:20
4到5之间的最短路径长度为:30
5到0之间没路径
5到1之间没路径
5到2之间没路径
5到3之间没路径
5到4之间没路径

Floyd算法与dijkstra算法相比的优势之处在于可以处理边权为负值的情况,但是不足之处在于,它对每一种路径都进行了迭代,用了三层循环,所以时间复杂度比dijkstra算法高,为O(n^3)。


转发请注明:转自http://blog.csdn.net/carson0408/article/details/78707444

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值