圖 dijkstra和prim演算法
阿新 • • 發佈:2019-02-19
package b; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class Graph { private int[][] array; private Map<Integer,String> xyToName = new HashMap<>(); private Map<String,Integer> nameToXy = new HashMap<>(); private int len; public void setNode(String[] nodes){ len = nodes.length; array = new int[len][len]; for(int i=0; i<len; i++){ xyToName.put(i, nodes[i]); nameToXy.put(nodes[i], i); for(int j=0; j<len; j++){ if(j == i){ array[i][j] = 0; }else{ array[i][j] = Integer.MAX_VALUE; } } } } public void setPath(String node1, String node2, int weight){ int node1Xy = nameToXy.get(node1); int node2Xy = nameToXy.get(node2); array[node1Xy][node2Xy] = weight; array[node2Xy][node1Xy] = weight; } public void createExample(){ this.setNode(new String[]{"A","B","C","D","E","F","G"}); this.setPath("A", "B", 7); this.setPath("C", "B", 8); this.setPath("A", "D", 5); this.setPath("D", "B", 9); this.setPath("E", "B", 7); this.setPath("E", "C", 5); this.setPath("D", "E", 15); this.setPath("D", "F", 6); this.setPath("F", "E", 8); this.setPath("F", "G", 11); this.setPath("E", "G", 9); } public void printArray(){ for(int i=0; i<len; i++){ for(int j=0; j<len; j++){ if(array[i][j] < Integer.MAX_VALUE){ int l = 10 - (array[i][j]+"").length(); while(l > 0){ System.out.print(" "); l--; } } System.out.print(array[i][j]+", "); } System.out.println(); } } public void dijkstra(String node){ int nodexy = nameToXy.get(node); int[] minLen = new int[len]; int[] visite = new int[len];//表示是否訪問過,0沒有,1訪問過 Map<Integer,String> path = new HashMap<>(); visite[nodexy] = 1; for(int i=0; i<len; i++){ minLen[i] = array[nodexy][i]; path.put(i, node+"->"+xyToName.get(i)); } int cur = nodexy; for(int w=0; w<len; w++){ int minPath = Integer.MAX_VALUE; //尋找沒有訪問的,距離源節點最近的 for(int e=0; e<len; e++){ if(visite[e] == 0 && minLen[e] < minPath){ cur = e; minPath = minLen[e]; } } //訪問此節點 visite[cur] = 1; for(int k=0; k<len; k++){ if(visite[k] == 0 //未訪問過的 && minLen[cur] != Integer.MAX_VALUE && array[cur][k] != Integer.MAX_VALUE && minLen[k] > (minLen[cur]+array[cur][k])){ minLen[k] = minLen[cur]+array[cur][k]; path.put(k, path.get(cur)+" / "+xyToName.get(cur)+"->"+xyToName.get(k)); } } } System.out.println("---------"); for(int i=0; i<len; i++){ System.out.println(node+"->"+xyToName.get(i)+" 最小:"+minLen[i]+" 路徑:"+path.get(i)); } } public void prim(String node){ System.out.println(); System.out.println("最小生成樹 prim from: "+node); int nodexy = nameToXy.get(node); int[] visite = new int[len];// 0,0,0,1,0,0,0 visite[nodexy] = 1; //int[] notVisited = new int[len];// 0,0,0,1,0,0,0 //notVisited[nodexy] = 1; int sum = len - 1; for(int s=0; s<sum; s++){ int min = Integer.MAX_VALUE; int selectedX = -1; int selectedY = -1; for(int i=0; i < len; i++){ if(visite[i] == 0){ for(int j=0; j < len; j++){ if(visite[j] == 1 && array[i][j] < min){ min = array[i][j]; selectedX = i; selectedY = j; } } } } System.out.println(xyToName.get(selectedY) +"->"+ xyToName.get(selectedX)); visite[selectedX] = 1; } } public static void main(String[] args) { Graph g = new Graph(); g.createExample(); g.printArray(); g.dijkstra("A"); g.dijkstra("G"); g.prim("D"); } }
0, 7, 2147483647, 5, 2147483647, 2147483647, 2147483647, 7, 0, 8, 9, 7, 2147483647, 2147483647, 2147483647, 8, 0, 2147483647, 5, 2147483647, 2147483647, 5, 9, 2147483647, 0, 15, 6, 2147483647, 2147483647, 7, 5, 15, 0, 8, 9, 2147483647, 2147483647, 2147483647, 6, 8, 0, 11, 2147483647, 2147483647, 2147483647, 2147483647, 9, 11, 0, --------- A->A 最小:0 路徑:A->A A->B 最小:7 路徑:A->B A->C 最小:15 路徑:A->B / B->C A->D 最小:5 路徑:A->D A->E 最小:14 路徑:A->B / B->E A->F 最小:11 路徑:A->D / D->F A->G 最小:22 路徑:A->D / D->F / F->G --------- G->A 最小:22 路徑:G->F / F->D / D->A G->B 最小:16 路徑:G->E / E->B G->C 最小:14 路徑:G->E / E->C G->D 最小:17 路徑:G->F / F->D G->E 最小:9 路徑:G->E G->F 最小:11 路徑:G->F G->G 最小:0 路徑:G->G 最小生成樹 prim from: D D->A D->F A->B B->E E->C E->G