最短距离----迪杰斯塔拉算法----java版

原理(自己理解的,不当之处希望有人可以指出)

图如上, 以求v0到v8顶点为例

首先求一下v0到各个顶点的距离,得到如下数组

我们的目的就是根据上面的数组确定v0到其他各个顶点的最短距离,这样也就获得了v0到v8的最短距离.

第一个可以确定最短距离的点

     从这个数组我们可以知道v0到达v1的最短距离肯定是1,但是v0到v2的最短距离却不一定是5

     为什么这么肯定呢??????????????

因为与v0直接连通的点就v1和v2这两个点

     那么v0到v1的最近距离要么是v0直接到v1的距离:v0-->v1,要么就是v0-->v2-->[....]-->v1的距离

    同理v0到v2的最近距离要么是v0直接到v2的距离:v0-->v2,要么就是v0-->v1-->[....]-->v2的距离

    由于v0-->v1的距离小于v0-->v2,因此v0直接到v1的距离为v0到v1的直接距离

    而对于v0-->v2的距离和v0-->v1-->[....]-->v2的距离并不能得到确定的判断

由此我们找到了v0到v1的最短距离为1

第二个可以确定最短距离的点

那么接着我们就从v0--->v1这条路继续往下走,会得到下图

由此我们找到了v0到v2的最短距离为4

    按照上诉思想,我们就可以找到v0到其他各个点的最短距离,当然假如只是为了找v0到某个点如v4,我们只要是v4这个点的最短距离确定了就可以结束上诉过程.

按照上诉思想我写的代码如下:

package cn.nrsc.graph;

/**
 * @author 孙川 ---- 最短路径---迪杰斯塔拉算法(dijkstra)
 */

public class Graph_Dijkstra {

	// ----------------------------图的表示方式------------------------
	private int vertexSize;// 顶点的数量
	private int[] vertexs;// 顶点对应的数组
	private int[][] matrix;// 邻接矩阵
	private static final int MAX_WEIGHT = 1000;// 代表顶点之间不连通
	private boolean[] isVisited; // 顶点是否已经被访问

	public Graph_Dijkstra(int vertexSize) {
		this.vertexSize = vertexSize;
		this.matrix = new int[vertexSize][vertexSize];
		this.vertexs = new int[vertexSize];
		for (int i = 0; i < vertexSize; i++) {
			vertexs[i] = i;
		}

		isVisited = new boolean[vertexSize];
	}
	// ----------------------------图的表示方式------------------------

	// 最短距离----迪杰斯塔拉算法 start--->end之间的最短距离
	public void dijkstra(int start, int end) {
		// 自己到自己的距离为0
		if (start == end) {
			System.out.println(start + "到" + end + "的最短距离为:" + 0);
			return;
		}

		// 首先计算出start到图中其他各个顶点的距离
		int[] distance = new int[vertexSize];
		// start到其他各个点的距离
		for (int i = 0; i < vertexSize; i++)
			distance[i] = matrix[start][i];

		// 记录已经确认点的Id,如果是end就可以结束循环了
		int targetId = 0;
		// 记录start到该点是否为最短距离
		boolean[] isMinPath = new boolean[vertexSize];
		// 到自身的最短距离肯定获取到了
		isMinPath[start] = true;

		// 迪杰斯塔拉算法的思想是利用distance数组确认出start到图中任意一个点的最短距离
		// 一次只能确认start到一个点的最短距离,并且不知道什么时候会确认了到end点的距离,
		// 所以我们需要让他一个点一个点的去确认, 直到end点确认了就可以退出循环了
		// 最坏的情况下由start到end需要确认的次数是vertexSize-1次
		for (int j = 1; j < vertexSize; j++) { // 外层控制确认的次数---最坏情况下为n-1次

			int min = MAX_WEIGHT; // 先假设最小距离为MAX_WEIGHT

			// distance数组中的最小值为start到它的最短距离 ----- 这里必须得好好理解一下(看我写的原理部分)

			// 找到distance数组中的最小值
			for (int k = 0; k < vertexSize; k++) {

				if (distance[k] < min && !isMinPath[k]) {
					min = distance[k];
					targetId = k;
				}
			}

			// 确定了start到targetId的最短距离
			System.out.println(start + "到" + targetId + "的最短距离为:" + min);
			// 在是否获得最短距离数组中进行标记
			isMinPath[targetId] = true;

			// 如果targetId = end了就说明找到了start到end的最短距离
			if (targetId == end)
				break;

			// 以min这条路继续往下走,找到start到不确定点更小的距离----循环后,不确定点中的最小值,将可以被确定
			for (int w = 0; w < vertexSize; w++)
				if (!isMinPath[w] && min + matrix[targetId][w] < distance[w])
					distance[w] = min + matrix[targetId][w];

		}
		// 打印一下--start到各个点的最短距离

		// for (int i = 0; i < vertexSize; i++)
		// System.out.print(" " + distance[i]);
	}

	public static void main(String[] args) {
		Graph_Dijkstra graph = new Graph_Dijkstra(9);
		int[] v0 = { 0, 1, 5, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT };
		int[] v1 = { 1, 0, 3, 7, 5, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT };
		int[] v2 = { 5, 3, 0, MAX_WEIGHT, 1, 7, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT };
		int[] v3 = { MAX_WEIGHT, 7, MAX_WEIGHT, 0, 2, MAX_WEIGHT, 3, MAX_WEIGHT, MAX_WEIGHT };
		int[] v4 = { MAX_WEIGHT, 5, 1, 2, 0, 3, 6, 9, MAX_WEIGHT };
		int[] v5 = { MAX_WEIGHT, MAX_WEIGHT, 7, MAX_WEIGHT, 3, 0, MAX_WEIGHT, 5, MAX_WEIGHT };
		int[] v6 = { MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 3, 6, MAX_WEIGHT, 0, 2, 7 };
		int[] v7 = { MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 9, 5, 2, 0, 4 };
		int[] v8 = { MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 7, 4, 0 };

		graph.matrix[0] = v0;
		graph.matrix[1] = v1;
		graph.matrix[2] = v2;
		graph.matrix[3] = v3;
		graph.matrix[4] = v4;
		graph.matrix[5] = v5;
		graph.matrix[6] = v6;
		graph.matrix[7] = v7;
		graph.matrix[8] = v8;

		graph.dijkstra(0, 8);
		System.out.println("---------------------");
		graph.dijkstra(8, 0);
		
	}
}

粘贴一下打印结果:

猜你喜欢

转载自blog.csdn.net/nrsc272420199/article/details/82913805