鄰接矩陣的dijkstra演算法 迭代法以及使用PriorityQueue的java實現
阿新 • • 發佈:2019-01-06
import java.util.PriorityQueue; public class DijkstraMy { //設定最大值 int MAX=999; //頂點總個數 int total; //鄰接矩陣表示距離 int[][] matrix; //結點相關資訊 String[] nodes; //儲存最後結果 int[] dis; //標記結點 int[] mark; DijkstraMy(int total,String[] nodes) { this.total = total; this.nodes = nodes; this.matrix = new int[total][total]; this.dis = new int[total]; this.mark = new int[total]; } private void initMatrix() { // 初始化矩陣為最大值(各節點都不連通) for (int i = 0; i < this.total; i++) { for (int j = 0; j < this.total; j++) { if (i == j) { this.matrix[i][j] = 0; } else { this.matrix[i][j] = MAX; } } } // 手動設定有向路徑 // A->B, A->E, A->D this.matrix[0][1] = 2; this.matrix[0][4] = 3; this.matrix[0][3] = 1; // B->C this.matrix[1][2] = 2; // C->F this.matrix[2][5] = 1; // D->E, D->G this.matrix[3][4] = 5; this.matrix[3][6] = 2; // E->F, E->H this.matrix[4][5] = 6; this.matrix[4][7] = 1; // F->I this.matrix[5][8] = 3; // G->H this.matrix[6][7] = 4; // H->F, H->I this.matrix[7][5] = 1; this.matrix[7][8] = 2; } private void printMatrix() { System.out.println("--------- weighted directed matrix ---------"); System.out.println("---0---1---2---3---4---5---6---7---8---"); System.out.println("---A---B---C---D---E---F---G---H---I---"); for (int i = 0; i < this.total; i++) { System.out.print("-" + this.nodes[i] + "|"); for (int j = 0; j < this.total; j++) { System.out.print(String.format("%03d", this.matrix[i][j]) + "-"); } System.out.print("\n"); } System.out.println("--------- weighted directed matrix ---------"); } private void dijkstra1(int s) { for(int i=0;i<total;i++ ) mark[i]=0; mark[s]=1; for(int i=0;i<total;i++) { dis[i]=matrix[s][i]; } /**每次找到一個最小值,標記,然後修改其相鄰的值*/ for(int i=0;i<total;i++) { int min=MAX; int index=-1; for(int j=0;j<total;j++) { if(mark[j]==0&&dis[j]<min) { index=j; min=matrix[s][j]; } } if(index==-1) return; mark[index]=1; for(int k=0;k<total;k++) { if(mark[k]==0&&dis[index]+matrix[index][k]<dis[k]) { dis[k]=dis[index]+matrix[index][k]; } } printDis(0,this.nodes[i],"第"+i+"次"); } } //使用小頂堆,幫助找到最小值 private void dijkstra2() { class Node implements Comparable<Node> { int id; int weight; Node(int i,int j) { this.id=i; this.weight=j; } @Override public int compareTo(Node node) { if(this.weight==node.weight) return 0; else if(this.weight<node.weight) return -1; else return 1; } } //小頂堆 PriorityQueue<Node> queue=new PriorityQueue<Node>(); queue.offer(new Node(0,0)); for(int i=0;i<total;i++ ) mark[i]=0; for(int i=0;i<total;i++) { dis[i]=matrix[0][i]; if(dis[i]!=MAX) queue.offer(new Node(i,dis[i])); } int count=0; while(queue!=null) { count++; Node node=queue.poll(); if(node==null) return; int index=node.id; mark[index]=1; for(int i=0;i<total;i++) { if(mark[i]==0&&dis[index]+matrix[index][i]<dis[i]) { dis[i]=dis[index]+matrix[index][i]; queue.add(new Node(i,dis[i])); } } printDis(0,"0","第"+count+"次"); } } private void printDis(int i, String node, String pre) { /*System.out.print("\n" + pre + "," + node + "," + i + "--->"); for (int t = 0; t < this.dis.length; t++) { System.out.print(t + ","); }*/ System.out.print("\n" + pre + i + "--->"); for (int t : this.dis) { System.out.print(t + ","); } System.out.print("\n"); } public static void main(String[] args) { String[] nodes = new String[] { "A", "B", "C", "D", "E", "F", "G", "H", "I" }; DijkstraMy dij = new DijkstraMy(nodes.length, nodes); dij.initMatrix(); dij.printMatrix(); System.out.println(); System.out.println("------ Dijkstra演算法-(迪傑斯特拉)演算法之迭代開始 ------"); dij.dijkstra1(0); dij.printDis(0, "迭代結果", "最終值"); System.out.print("\n"); System.out.println("------ Dijkstra演算法-(迪傑斯特拉)演算法之迭代結束 ------"); System.out.println(); System.out.println("------ Dijkstra演算法-(迪傑斯特拉)演算法之優先佇列開始 ------"); dij.dijkstra2(); dij.printDis(0, "優先順序佇列", "最終值"); System.out.print("\n"); System.out.println("------ Dijkstra演算法-(迪傑斯特拉)演算法之優先佇列結束 ------"); } }