欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Dijkstra算法,求最短路径问题

程序员文章站 2024-03-16 13:51:52
...

解析过程:

    使用两个S[ ]和dis[ ]两个数组,S[i]表示i节点是否已经找到最短路径,dis[i]表示定点距离i的最短路程。

    例如:

     假设已知定点为0,求各个节点到0的距离。

   Dijkstra算法,求最短路径问题

    构建出一个表格方便观察过程:

    第一排代表节点

    第二排是判断是否已经找到最短路径

    第三排是定点到任意点的距离

   Dijkstra算法,求最短路径问题

  0这个点离自己距离是0,且已经是最短路径,变为true

   Dijkstra算法,求最短路径问题

   0的出度有1和2,且距离分别是1和12,再在所有false中找到距离最短的,则就可确定离0最近的是1,变为true

   Dijkstra算法,求最短路径问题

   同理,1的出度有2和3,离0的距离分别是1+9和1+3,因为到2的距离为10<12,所有更新为10,且3的距离最短,变为true

   Dijkstra算法,求最短路径问题

   同理,3的出度有2,4,5,例如到2的情况:0-1-3-2的路程为8<10,更新为8。4和5同理。

   Dijkstra算法,求最短路径问题

   接下来情况和前面类似

   Dijkstra算法,求最短路径问题

   Dijkstra算法,求最短路径问题

   这样就求得dis数组为0,1,8,4,13,17,分别表示距离0的距离

代码实现:

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		//邻接矩阵
  		int[][] map = {
  				{0,1,12,0,0,0},
  				{0,0,9,3,0,0},
  				{0,0,0,0,5,0},
  				{0,0,4,0,13,15},
  				{0,0,0,0,0,4},
  				{0,0,0,0,0,0}};
  		int[] dis = new int[map[0].length];//任意一点到定点的距离数组
  		boolean[] S = new boolean[map[0].length];	//是否寻找到最短路径
  		for (int i = 0; i < dis.length; i++) {
  			S[i] = false;
			dis[i] = Integer.MAX_VALUE;
		}
  		getdis(dis,S,map,0);
	}
	/**
	 * 
	 * @param dis	dis数组
	 * @param S		S数组
	 * @param map	邻接矩阵
	 * @param first	定点
	 */
	private static void getdis(int[] dis, boolean[] S, int[][] map, int first) {
		dis[first]=0;//到自己的距离为0
		S[first]=true;//自己已经是最短
		int n = map[0].length;//节点个数
		for (int i = 0; i < n; i++) {
			if(map[first][i]!=0){
				dis[i]=map[first][i];//从自己出发到能到点的距离
			}
		}
		for (int i = 1; i < n; i++) {
			int min = Integer.MAX_VALUE;
			int flag=-1;
			//找到未被置为true的最短点
			for (int j = 0; j < n; j++) {
				if(!S[j] && dis[j]<min){
					min = dis[j];
					flag=j;
				}
			}
			if(flag!=-1) {
				S[flag]=true;
				for (int j = 0; j < n; j++) {
					if(!S[j] && map[flag][j]!=0 && map[flag][j]+dis[flag] < dis[j]){
						dis[j]= map[flag][j]+dis[flag];//更新
					}
				}
			}
		}
		for (int i = 0; i < dis.length; i++) {
			if(dis[i]==Integer.MAX_VALUE) System.out.print("无法到达 ");
			else System.out.print(dis[i]+" ");
		}
	}
}

输出结果:

0 1 8 4 13 17 

如果改变定点为1,则输出结果变为:

无法到达 0 7 3 12 16 

注意这个算法不能运用到边的权值存在负值的情况。