Java 图的最短路径问题-迪杰斯特拉算法VS弗洛伊德算法

1.迪杰斯特拉算法VS弗洛伊德算法

迪杰斯特拉算法通过选定的被访问顶点,求出从出发访问顶点到其他顶点的最短路径
弗洛伊德算法中每一个顶点都是出发访问点,所以需要将每一个顶点看做被访问顶点,求出从每一个顶点到其他顶点的最短路径。

2.迪杰斯特拉算法

迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个结点到其他结点的最短路径。 它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止。
迪杰斯特拉(Dijkstra)算法过程
设置出发顶点为v,顶点集合V{v1,v2,vi…},v到V中各顶点的距离构成距离集合Dis,Dis{d1,d2,di…},Dis集合记录着v到图中各顶点的距离(到自身可以看作0,v到vi距离对应为di)

  1. 从Dis中选择值最小的di并移出Dis集合,同时移出V集合中对应的顶点vi,此时的v到vi即为最短路径
  2. 更新Dis集合,更新规则为:比较v到V集合中顶点的距离值,与v通过vi到V集合中顶点的距离值,保留值较小的一个(同时也应该更新顶点的前驱节点为vi,表明是通过vi到达的)
    重复执行两步骤,直到最短路径顶点为目标顶点即可结束

光看算法过程,很难理解,其实理解迪杰斯特拉算法只需要理解中间结点的问题。
Java 图的最短路径问题-迪杰斯特拉算法VS弗洛伊德算法_第1张图片
接下来,复杂一点
Java 图的最短路径问题-迪杰斯特拉算法VS弗洛伊德算法_第2张图片

迪杰斯特拉算法就是需要维持一个minPathLen[]数组,每一次计算都能确定到某个顶点的最短路径,该点就是下一次继续的中间点。

/**
 * 迪杰斯特拉算法
 * @param i  从i点出发
 * @return   返回从i点出发的到某点的最短路径长度数组
 */
public int[] digkstra(int i){
	final int N = 65535;
	int []minPathLength=new int[vertex.length];         //存放最短路径长度
	HashSet vertexset=new HashSet<>();         //存放顶点的集合
	//初始化
	for(int index=0;index vertexset){
	vertexset.remove(i);
	while(vertexset.size()>0){
		//广度优先搜索,比较长度并选择最短长度
		for(Integer index:vertexset){
			//比较是保留原来的minPathLength,还是要新的minPathLength
			minPathLength[index]=Math.min(minPathLength[index], minPathLength[i]+matrix[i][index]);
		}
		
		//确定下一个广度优先搜索的顶点(在集合内,且当前minPathLength最小)
		int min=65535;
		int nextIndex=0;
		for(Integer index:vertexset){
			if(minPathLength[index]

3.弗洛伊德算法

弗洛伊德算法同样是根据中间结点的的性质得到
Java 图的最短路径问题-迪杰斯特拉算法VS弗洛伊德算法_第3张图片
它的具体做法是将每个结点都作为中间结点来求,其余结点作为作为开始结点和结束结点,至于为什么能保持它的正确性,请查阅更多资料。

//弗洛伊德算法
public void floyd(){
	//i作为中间结点,j作为开始结点,k作为结束结点
	for(int i=0;i

你可能感兴趣的:(数据结构与算法,Java学习)