单源多点最短路径-Dijkstra算法

Dijkstra算法使用了贪心算法思想,在实现Dijkstra算法的时候,维持一个节点的集合S,该集合节点到源点的最短路径都已经找到;而对于S集合之外的节点,放置在集合Q中,表示还没有找到最短路径的节点,每次添加到S的是离S最近的节点u,在将u加入S之后,对Q中节点更新其到源节点的距离。以下是java实现:

首先构造Node对象:

/**
 * Dijkstra算法的节点对象
 * @author Qing
 *
 */
public class DijkstraNode {
	public static final int MAX = Integer.MAX_VALUE;  
	private int name;
	private int distance;//记录S集合中到节点A的路径长度
	private boolean in;
	
	public DijkstraNode(int name){
		this.name = name;
		this.distance = MAX;
		this.in = false;
	}
	
	public int getName() {
		return name;
	}
	public void setName(int name) {
		this.name = name;
	}
	public int getDistance() {
		return distance;
	}
	public void setDistance(int distance) {
		this.distance = distance;
	}
	public boolean isIn() {
		return in;
	}

	public void setIn(boolean in) {
		this.in = in;
	}
}

构造Dijkstra最短路径,特别的,使用的图为与博文 贪心算法-Kruskal 中使用了同一幅图,图片显示请见:
点击打开链接

/**
 * 单源多点的最短路径问题的Dijkstra 算法
 * @author Qing
 *
 */
public class Dijkstra {
    public static final int N = 8;  
    public static final int MAX = Integer.MAX_VALUE;  
    public static final int[][] E={{0,3,MAX,MAX,MAX,MAX,MAX,14},  
                                   {3,0,10,MAX,MAX,MAX,MAX,8},  
                                   {MAX,10,0,15,MAX,7,MAX,MAX},  
                                   {MAX,MAX,15,0,MAX,MAX,MAX,MAX},  
                                   {MAX,MAX,MAX,MAX,0,9,MAX,MAX},  
                                   {MAX,MAX,7,MAX,9,0,12,5},  
                                   {MAX,MAX,MAX,MAX,MAX,12,0,6},  
                                   {14,8,MAX,MAX,MAX,5,6,0}};  
    public static  List<DijkstraNode> nodes = new ArrayList<DijkstraNode>();
    public static final int[] V = {0,1,2,3,4,5,6,7};//各节点的名称
    public static final int start = 0;//源节点
    public static List<String> S = new ArrayList<String>();//S表,存放加入最短路径的节点
    public static List<String> Q = new ArrayList<String>();//Q表,存放还没哟加入最短路径的节点
    
    //S初始化,出自身节点之外所有节点距离设为最大值
    public static void init(){
    	for(int i = 0; i < N; i ++){
    		DijkstraNode n = new DijkstraNode(i);
    		nodes.add(n);
    		Q.add(String.valueOf(i));
    		if(i == start){
    			nodes.get(i).setDistance(0);
    			nodes.get(i).setIn(true);
    			S.add(String.valueOf(start));
    			Q.remove(String.valueOf(start));
    		}
    	}
    }
    //找出不在S中的节点中距离源最近的那个节点
    public static DijkstraNode findMinNode(){
    	int minDistance = MAX;
    	int minName = 0;
    	for(int i = 0; i < N; i ++){
    		if(nodes.get(i).getDistance() < minDistance && nodes.get(i).isIn() == false){//选取未加入S集合的距离源点最近的点
    			minDistance = nodes.get(i).getDistance();
    			minName = nodes.get(i).getName();
    		}
    	}
    	return nodes.get(minName);
    }
    	//降距操作,计算不在S中的各节点距离源节点的新距离。
    public static void newDistance(DijkstraNode u){
    	int node = u.getName();
    	int distance = u.getDistance();
    	for(int i =0; i < Q.size(); i ++){//对Q中的元素重新计算距离
    		int id = Integer.valueOf(Q.get(i));
    		int beforedistance = nodes.get(id).getDistance();//初始值为node的distance
    		int afterdistance = MAX;
    		if(E[node][id] != MAX){
    			afterdistance = E[node][id] + distance;
    		}
    		if(afterdistance < beforedistance){
    			nodes.get(id).setDistance(afterdistance);
    		}
    		
    	}
    	
    }
    //构建Dijkstra最短路径
    public static void DijkstraPath(){
    	while(S.size() < N){
    		 DijkstraNode minnode = findMinNode();//找出距离A最近的点
    		 minnode.setIn(true);
    		 S.add(String.valueOf(minnode.getName()));//加入S
    		 Q.remove(String.valueOf(minnode.getName()));//从Q集中移除
    		 newDistance(minnode);//降距操作,重新计算Q中节点与A的距离
    		 System.out.println("put the " + minnode.getName() +" into S");
    		 printPath();
    	}
    }
    
    //打印当前情况下的路径状况,即V-S表
    public static void printPath(){
    	for(int i = 0; i < N; i ++){
    		System.out.println(nodes.get(i).getName() +"'s min distance is "+ nodes.get(i).getDistance());
    	}
    	System.out.println("");
    }
    public static void main(String[] args){
    	init();
    	DijkstraPath();
    	System.out.println("the final path is:");
    	printPath();
    	
    }

}

构造Dijkstra路径的过程如下图:

《单源多点最短路径-Dijkstra算法》

《单源多点最短路径-Dijkstra算法》

    原文作者:Dijkstra算法
    原文地址: https://blog.csdn.net/u010726042/article/details/51170398
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞