从最短路径开始,学习Dijstar算法
下面是求最短路径问题描述:
下面是Dijkstar算法的描述:
下面是使用Dijkstar算法求解右图中的问题:
下面是图的邻接矩阵:
下面是计算过程:
下面是求解最短路径:
下面是Java代码实现,其中需要注意的问题我已经标出(一定要细心!!!!):
package greedy_algorithm; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; public class Dijkstra { private Set<Integer> permanent=new HashSet<>(); private Set<Integer> temporary=new HashSet<>(); private Map<Integer, Integer> nodeMap=new HashMap<Integer, Integer>(); //key=永久节点,value=最短路径前一个节点,提高回溯效率 private int [][] m; private Mark [][] d; private int n; private final static int MAX=65535; class Mark{ private int length=MAX; private int previous=-1; private boolean isMarked=false; public Mark(){} public Mark(int length,int previous,boolean isMarked){ this.length=length; this.previous=previous; this.isMarked=isMarked; } } public Dijkstra(){ n=6; m=new int[][]{{ 0, 1, 4,-1,-1,-1}, { 1, 0, 2, 7, 5,-1}, { 4, 2, 0,-1, 1,-1}, {-1, 7,-1, 0, 3, 2}, {-1, 5, 1, 3, 0, 6}, {-1,-1,-1, 2, 6, 0}}; d=new Mark[n][n]; for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ d[i][j]=new Mark(); //System.out.println(d[i][j].length+" "+d[i][j].previous+" "+d[i][j].isMarked); } } } public Dijkstra(int n,int [][]m,Mark [][]d){ this.n=n;this.m=m;this.d=d; if(n!=m.length && n!=m[0].length && n!=d.length && n!=d[0].length){ System.out.println("输入格式有误"); System.exit(1); } } public void shortestPath(){ ArrayList<Mark> vList; permanent.add(0); for(int i=1;i<n;i++){ temporary.add(i); } d[0][0]=new Mark(0,-1,true); nodeMap.put(0, -1); /*for(int q=0;q<n;q++) System.out.print("("+d[0][q].length+","+d[0][q].previous+","+d[0][q].isMarked+") "); System.out.println();*/ for(int i=1;i<n;i++){ for(int t:temporary){ vList=new ArrayList<Dijkstra.Mark>(); for(int p:permanent){ if(m[t][p]!=-1){ vList.add(new Mark(getLength(t, p),p,false)); } } if(vList.size()!=0){ d[i][t]=getMin(vList); } } markNode(i); /*for(int r=0;r<n;r++) System.out.print("("+d[i][r].length+","+d[i][r].previous+","+d[i][r].isMarked+") "); System.out.println();*/ } } public void traceBack(int end){ int node=end; for(int i=0;i<n;i++){ if(d[i][node].isMarked==true){ System.out.println("The shortest lenth from V0 to V"+node+" is:"+d[i][node].length); } } System.out.println("The shortest path is:"); trace(end); } public void trace(int end){ int node =end; if(node>=0){ trace(nodeMap.get(node)); if(node==5) System.out.print("V"+node); else System.out.print("V"+node+"->"); } } public int getLength(int t,int p){ int length=m[t][p]; for(int i=0;i<n;i++){ if(d[i][p].isMarked==true){ length+=d[i][p].length; break; } } return length; } public Mark getMin(ArrayList<Mark> vList){ Mark mark=new Mark(); int min=MAX; //注意这里一定是min=MAX,这个地方的问题查了好久的错误!!! //System.out.println("min="+min); for(Mark c:vList){ //System.out.println("("+c.length+","+c.previous+","+c.isMarked+")"); if(min>c.length){ min=c.length; mark=c; //System.out.println("break"); } } //System.out.println("("+mark.length+","+mark.previous+","+mark.isMarked+")"); return mark==null?new Mark(-1,-1,false):mark; } public void markNode(int row){ int min=MAX; int position=-1; for(int j=0;j<n;j++){ if(d[row][j].length!=MAX){ if(min>d[row][j].length){ min=d[row][j].length; position=j; } } } if(position!=-1){ d[row][position].isMarked=true; permanent.add(position); temporary.remove(position); nodeMap.put(position, d[row][position].previous); } } public static void main(String[] args) { Dijkstra dijkstra=new Dijkstra(); dijkstra.shortestPath(); /*for(Map.Entry<Integer, Integer> entry:dijkstra.nodeMap.entrySet()) System.out.println(entry);*/ dijkstra.traceBack(5); } }
原文地址:http://blog.csdn.net/weiweiyixiaocsdn/article/details/45815347