有关Floyd相关算法的一点点改进

今天看到了华山大师兄的博客中的Floyd算法,自己用java动手写了一个,发现存在一些问题,特此在这里写出来,跟大家分享一下:

java代码:

	public static final int UNREACH = Integer.MAX_VALUE;//设置不可到达点权值
	public static void main(String[] args) {
		// 邻接矩阵
		int[][] A = { { 0, 5, UNREACH, 7 }, { UNREACH, 0, 4, 2 },
				{ 3, 3, 0, 2 }, { UNREACH, UNREACH, 1, 0 } };
		for (int k = 0; k < A.length; k++) {
			// 行计算:
			for (int i = 0; i < A.length; i++) {
				for (int j = 0; j < A.length; j++) {
					// 源代码:
					// if (A[i][j] > A[i][k] + A[k][j]) {
					// 修改以后的代码
					if (i != j && i != k && A[i][j] - A[i][k] > A[k][j]) {
						A[i][j] = A[i][k] + A[k][j];
					}
				}
			}
		}
	}

1.i!=j&&i!=k

这部分代码是为了减少不必要的计算:

i==j时:出发点和目标点相同,肯定为0,所以不用计算

k==i时:出发点和中间点相同,没必要计算

2. A[i][j] - A[i][k] > A[k][j] 

首先需要注意的是,我在这里将不可达到的点的权值设置为了Integer.MAX_VALUE,那就是有符号整数的最大值,这时如果还是按照原作者的代码:

if (A[i][j] > A[i][k] + A[k][j])

来写的话,如果A[i][k]或者A[k][j]其中之一为不可达到的点就会溢出,他俩的和会变成一个负数(具体为什么可以看看其他相关资料)从而导致了算法的失败,因此,需要先计算两个的差值,然后再比较大小,这样数值就不会溢出,从而完成算法。

3.注:

如果有朋友想到:那我写成:

if(A[i][j] - A[i][k] - A[k][j]>0)
是否可以呢?

答案是不行

因为如果A[i][j]为可达,而A[i][k]和A[k][j]都不可达,那么就会造成负数的溢出,还是会影响到算数结果(大家如果有不明白,可以看看整数如何存储在电脑上,相加/相减为什么有时候结果会不对相关的资料)

这些也都是我自己总结出来的,如有不对希望大家批评指点!



你可能感兴趣的:(算法相关)