单源最短路径(Bellman_flyod算法)

1. Bellman_ford算法

下面是百度百科对于算法的介绍:

在计算机科学中,Floyd-Warshall算法是一种在具有正或负边缘权重(但没有负周期)的加权图中找到最短路径的算法。算法的单个执行将找到所有顶点对之间的最短路径的长度(加权)。 虽然它不返回路径本身的细节,但是可以通过对算法的简单修改来重建路径。 该算法的版本也可用于查找关系R的传递闭包,或(与Schulze投票系统相关)在加权图中所有顶点对之间的最宽路径

总的来说,Bellman_flyod算法是用来寻找有向图中的某一个顶点到其他顶点中最短路径

时间复杂度 : O(n^3);

空间复杂度 : O(n^2)

所以来说算法的时间复杂度是比较高的,效率比较低,使用得也会比较少

2. 算法的大致过程如下:

① 首先有一个具有权重的无向图,所以当两个顶点有边的时候数组中的元素值肯定不为零,我们可以使用一个二维数组来表示有向图,数组里面存放的是两个顶点之间的权重,二维数组的行表示的是边的入度,二维数组的列表示的是边的初度,也可以表示顶点

声明一个一维数组用来存放某个顶点到达其他顶点的最短距离,所以这个数组的意义也是某个顶点到达当前顶点的最短路径,刚开始初始化除了源点s之外,其他顶点的值都置为Integer.MAX_VALUE

比如求解顶点B到顶点ACDFGH的最短路径,将一维数组d的d[1] = 0,其他的下标0,2,3,4,5,6对应的值为最大值

② 使用双重循环来进行扫描,第一层循环表示顶点的入度,第二层循环表示的是顶点的初度,当扫描到i到j有边的时候那么我们需要查看d[j] 是否大于当前顶点d[i] + graph[i][j]的距离,如果大于说明源点到达当前这个顶点的距离会更短,因为在图中可能存在多条路径到达当前这个顶点,所以要进行比较

例如B---->C------>E,也可以B------F------D------E假如第一次的时候更新了源点B到C和E的距离,那么d[C]和d[E]的值会更新,第二次的时候更新了d[F]和d[D]的距离,然后比较d[E] 与d[D] + graph[D][E]的距离发现更短,所以会更新d[E]的距离

上面的过程结合图会更好理解,反正就是发现顶点i到顶点j有边那么久比较当前顶点与之前其他路径到达这个顶点的距离是否更短假如更短则更新

③ 其中需要在最外层的循环设置一个更新标志因为有的时候到达某个顶点更新了一次,但是后面循环的时候有其他更短的路径到达这个顶点,所以还需要对其进行更新,所以需要一个最外层的循环加上一个更新标志,当循环中没有更新的时候说明全部的数据已经更新完毕这样就可以退出整个循环,一维数组中保存的就是源点s到达其他顶点的最短路径

3. 代码如下:

public class Main {
	static int graph[][] = {
		  {0, 2, 5, 0, 0, 0, 0},
	      {2, 0, 4, 6, 10, 0, 0},
	      {5, 4, 0, 2, 0, 0, 0},
	      {0, 6, 2, 0, 0, 1, 0},
	      {0, 10, 0, 0, 0, 3, 5},
	      {0, 0, 0, 1, 3, 0, 9},
	      {0, 0, 0, 0, 5, 9, 0}
	};
	public static void main(String[] args) {
		int arr[] = shortMinistPath(7, 0);
		for(int i = 0; i < arr.length; i++){
			System.out.print(arr[i] + " ");
		}
	}
	
	private static int[] shortMinistPath(int n, int s) {
		int d[] = new int[n];
		d[s] = 0;
		for(int i = 0; i < n; i++){
			if(s != i)d[i] = Integer.MAX_VALUE;
		}
		boolean updateflag = false;
		while(true){
			updateflag = false;
			for(int i = 0; i < n; i++){
				if(d[i] == Integer.MAX_VALUE) continue;
				for(int j = 0; j < n; j++){
					if(graph[i][j] > 0 && d[j] > d[i] + graph[i][j]){
						d[j] = d[i] + graph[i][j];
						updateflag = true;
					}
				}
			}
			if(!updateflag){
				break;
			}
		}
		return d;
	}
}

猜你喜欢

转载自blog.csdn.net/qq_39445165/article/details/88320791
今日推荐