單源最短路徑-Dijkstra演算法
阿新 • • 發佈:2018-12-31
package com.data.struct; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Random; import java.util.Set; public class Dijkstra { private Node [][]graphic; private Node s; private Set<Node> nextNodes=new HashSet<Node>(); public Dijkstra(int v,int e){ graphic=new Node[v][v]; for(int i=0;i<e;i++){ int v1=new Random().nextInt(v); int v2=new Random().nextInt(v); Node node=new Node(); node.d=Integer.MAX_VALUE-1000; node.w=new Random().nextInt(e); node.start=v1; node.end=v2; graphic[v1][v2]=node; } for(int i=0;i<v;i++){ if(graphic[i][i]==null){ Node node=new Node(); node.d=Integer.MAX_VALUE-1000; node.w=new Random().nextInt(e); node.start=i; node.end=i; graphic[i][i]=node; } } for(int i=0;i<v;i++){ nextNodes.add(graphic[i][i]); } s=graphic[0][0]; s.d=0; } public void dijkstra(){ for(int k=0;k<graphic.length;k++){ if(k!=s.start&&graphic[s.start][k]!=null){ relex(s,graphic[k][k]); } } nextNodes.remove(s); while(nextNodes.size()>0){ Node node=extractMin(); for(int k=0;k<graphic.length;k++){ if(k!=node.start&&graphic[node.start][k]!=null){ relex(node,graphic[k][k]); } } nextNodes.remove(node); } } public Node extractMin() { Iterator<Node> it = nextNodes.iterator(); Node node=null; while(it.hasNext()){ if(node==null){ node=it.next(); }else{ Node n=it.next(); if(n.d<node.d){ node=n; } } } return node; } public void relex(Node u,Node v){ if(graphic[v.end][v.end].d>u.d+graphic[u.start][v.start].w){ graphic[v.end][v.end].d=u.d+graphic[u.start][v.start].w; graphic[v.end][v.end].parent=u; System.out.println(graphic[v.end][v.end].start+"=>"+u.start); } } public void print(){ for(int i=0;i<graphic.length;i++){ for(int j=0;j<graphic[i].length;j++){ if(graphic[i][j]==null){ System.out.print(-1+"|"+-1+"|"+-1+" "); }else{ System.out.print(graphic[i][j].start+"|"+graphic[i][j].end+"|"+graphic[i][j].w+" "); } } System.out.println(); } } public void printPath(){ List<Integer> indexList=new ArrayList<Integer>(); List<Integer> removeList=new ArrayList<Integer>(); List<Integer> addList=new ArrayList<Integer>(); indexList.add(0); while(indexList.size()>0){ removeList.clear(); addList.clear(); for(int x=0;x<indexList.size();x++){ int l=indexList.get(x); removeList.add(l); for(int j=0;j<graphic.length;j++){ if(graphic[j][j].parent==graphic[l][l]){ graphic[l][l].children.add(graphic[j][j]); addList.add(j); } } } indexList.removeAll(removeList); indexList.addAll(addList); } Node h = this.s; this.print(0, h,h); System.out.println(); } private void print(int level,Node parent, Node node){ for (int i = 0; i < level; i++) { System.out.format(" "); } System.out.format("|"); if(parent!=node){ System.out.print("("+graphic[parent.start][node.end].w+")"); for (int i = 0; i < level; i++) { System.out.format("-"); } }else{ for (int i = 0; i < level; i++) { System.out.format("-"); } } System.out.format("%d%n", node.start); List<Node> children = node.children; for(int i=0;i<children.size();i++){ print(level+1,node,children.get(i)); } } private class Node{ private int d; private int w; private int start; private int end; private Node parent; private List<Node> children=new ArrayList<Node>(); } public static void main(String[] args) { Dijkstra d=new Dijkstra(5,20); d.print(); d.dijkstra(); d.printPath(); } }