Dijkstra演算法求最短路徑(java)__演算法

來源:互聯網
上載者:User
任務描述:在一個無向圖中,擷取起始節點到所有其他節點的最短路徑描述

Dijkstra(迪傑斯特拉)演算法是典型的最短路徑路由演算法,用於計算一個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴充,直到擴充到終點為止。

Dijkstra一般的表述通常有兩種方式,一種用永久和臨時標號方式,一種是用OPEN, CLOSE表方式
用OPEN,CLOSE表的方式,其採用的是貪進法的演算法策略,大概過程如下:
1.聲明兩個集合,open和close,open用於儲存未遍曆的節點,close用來儲存已遍曆的節點
2.初始階段,將初始節點放入close,其他所有節點放入open
3.以初始節點為中心向外一層層遍曆,擷取離指定節點最近的子節點放入close並從新計算路徑,直至close包含所有子節點

代碼執行個體如下:
Node對象用於封裝節點資訊,包括名字和子節點
public class Node {private String name;private Map<Node,Integer> child=new HashMap<Node,Integer>();public Node(String name){this.name=name;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Map<Node, Integer> getChild() {return child;}public void setChild(Map<Node, Integer> child) {this.child = child;}}

MapBuilder用於初始化資料來源,返回圖的起始節點
public class MapBuilder {public Node build(Set<Node> open, Set<Node> close){Node nodeA=new Node("A");Node nodeB=new Node("B");Node nodeC=new Node("C");Node nodeD=new Node("D");Node nodeE=new Node("E");Node nodeF=new Node("F");Node nodeG=new Node("G");Node nodeH=new Node("H");nodeA.getChild().put(nodeB, 1);nodeA.getChild().put(nodeC, 1);nodeA.getChild().put(nodeD, 4);nodeA.getChild().put(nodeG, 5);nodeA.getChild().put(nodeF, 2);nodeB.getChild().put(nodeA, 1);nodeB.getChild().put(nodeF, 2);nodeB.getChild().put(nodeH, 4);nodeC.getChild().put(nodeA, 1);nodeC.getChild().put(nodeG, 3);nodeD.getChild().put(nodeA, 4);nodeD.getChild().put(nodeE, 1);nodeE.getChild().put(nodeD, 1);nodeE.getChild().put(nodeF, 1);nodeF.getChild().put(nodeE, 1);nodeF.getChild().put(nodeB, 2);nodeF.getChild().put(nodeA, 2);nodeG.getChild().put(nodeC, 3);nodeG.getChild().put(nodeA, 5);nodeG.getChild().put(nodeH, 1);nodeH.getChild().put(nodeB, 4);nodeH.getChild().put(nodeG, 1);open.add(nodeB);open.add(nodeC);open.add(nodeD);open.add(nodeE);open.add(nodeF);open.add(nodeG);open.add(nodeH);close.add(nodeA);return nodeA;}}
圖的結構如下圖所示:


Dijkstra對象用於計算起始節點到所有其他節點的最短路徑
public class Dijkstra {Set<Node> open=new HashSet<Node>();Set<Node> close=new HashSet<Node>();Map<String,Integer> path=new HashMap<String,Integer>();//封裝路徑距離Map<String,String> pathInfo=new HashMap<String,String>();//封裝路徑資訊public Node init(){//初始路徑,因沒有A->E這條路徑,所以path(E)設定為Integer.MAX_VALUEpath.put("B", 1);pathInfo.put("B", "A->B");path.put("C", 1);pathInfo.put("C", "A->C");path.put("D", 4);pathInfo.put("D", "A->D");path.put("E", Integer.MAX_VALUE);pathInfo.put("E", "A");path.put("F", 2);pathInfo.put("F", "A->F");path.put("G", 5);pathInfo.put("G", "A->G");path.put("H", Integer.MAX_VALUE);pathInfo.put("H", "A");//將初始節點放入close,其他節點放入openNode start=new MapBuilder().build(open,close);return start;}public void computePath(Node start){Node nearest=getShortestPath(start);//取距離start節點最近的子節點,放入closeif(nearest==null){return;}close.add(nearest);open.remove(nearest);Map<Node,Integer> childs=nearest.getChild();for(Node child:childs.keySet()){if(open.contains(child)){//如果子節點在open中Integer newCompute=path.get(nearest.getName())+childs.get(child);if(path.get(child.getName())>newCompute){//之前設定的距離大於新計算出來的距離path.put(child.getName(), newCompute);pathInfo.put(child.getName(), pathInfo.get(nearest.getName())+"->"+child.getName());}}}computePath(start);//重複執行自己,確保所有子節點被遍曆computePath(nearest);//向外一層層遞迴,直至所有頂點被遍曆}public void printPathInfo(){Set<Map.Entry<String, String>> pathInfos=pathInfo.entrySet();for(Map.Entry<String, String> pathInfo:pathInfos){System.out.println(pathInfo.getKey()+":"+pathInfo.getValue());}}/** * 擷取與node最近的子節點 */private Node getShortestPath(Node node){Node res=null;int minDis=Integer.MAX_VALUE;Map<Node,Integer> childs=node.getChild();for(Node child:childs.keySet()){if(open.contains(child)){int distance=childs.get(child);if(distance<minDis){minDis=distance;res=child;}}}return res;}}

Main用於測試Dijkstra對象
public class Main {public static void main(String[] args) {Dijkstra test=new Dijkstra();Node start=test.init();test.computePath(start);test.printPathInfo();}}

列印輸出如下:
D:A->D
E:A->F->E
F:A->F
G:A->C->G
B:A->B
C:A->C
H:A->B->H

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.