感謝每一位朋友的閱讀與建議,今天對最短路徑blog進行了修改,調整圖和部份內容。感謝各位關注。提前祝你們聖誕節平安快樂。java
給定一個帶權有向圖G=(V,E),其中每條邊的權是一個實數。另外,還給定V中的一個頂點,稱爲源。如今要計算從源到其餘全部各頂點的最短路徑長度。這裏的長度就是指路上各邊權之和。這個問題一般稱爲單源最短路徑問題git
藉助隊列實現每條邊只訪問一次。github
/** * 無權最短路徑 * * @param s 起點 */ public void unweight(Vertex s) { Queue<Vertex> q = new LinkedList<Vertex>(); for (Vertex x : graph) { //每一個節點的初始最短路徑爲Integer的最大值,表示該節點的最短路徑未知 x.setDist(Integer.MAX_VALUE); } s.dist = 0; q.add(s); while (!q.isEmpty()) { Vertex v = q.poll(); if (v != null) { if (v.getAdj() != null && !v.getAdj().isEmpty()) { for (Vertex w : v.getAdj()) { if (w.getDist() == Integer.MAX_VALUE) {//每條邊只訪問一次 w.setDist(v.getDist()+1); w.setPath(v); q.add(w); } } } } } }
O(|E|+|V|)
Dijkstra算法是解決有權無負值單源最短路徑的經典算法。算法
/** * 著名的dijkstra算法 解決單源最短路徑(權無負值) * * @param s * 起點 */ public void dijkstra(Vertex s) { for (Vertex v : graph) {// 初始默認全部頂點未被訪問 v.setDist(Integer.MAX_VALUE); v.known = false; } s.dist = 0;// 聲明起點的距離爲0 PriorityQueue<Vertex> priorityQueue = new PriorityQueue<Vertex>(); // 將s放入優先隊列 priorityQueue.add(s); while (!priorityQueue.isEmpty()) {// 知道全部頂點的最短路徑都已知而且優先隊列爲空 Vertex v = priorityQueue.poll();// 取出未知節點中最短路徑最小的節點 if (v != null) { if (!v.known) { v.known = true;// 聲明該節點已知 if (v.getAdj() != null && !v.getAdj().isEmpty()) { // 如 dv+cvw<=dw 則更新臨接點的最短路徑,而且更新值放入到優先隊列中 for (AdjVertex adjW : v.getAdj()) { if (!adjW.getW().known) { if (v.dist + adjW.cvw < adjW.getW().getDist()) { adjW.getW().setDist(v.dist + adjW.cvw); adjW.getW().setPath(v); priorityQueue.add(adjW.getW()); } } } } } } } }
針對一個有權圖,該圖的權有負值,使用某個頂點s做爲輸入參數,找出該頂點s到其餘頂點的最短距離。url
藉助廣度優先搜素實現。.net
/** * 有權有負值最短路徑 * 藉助廣度優先搜素 * @param s 起點 */ public void weightNegative(Vertex s) { Queue<Vertex> q = new LinkedList<Vertex>(); for (Vertex v : graph) { v.dist = Integer.MAX_VALUE; v.isInQueue = false; } s.dist = 0; s.isInQueue = true; q.add(s); while (!q.isEmpty()) { Vertex v = q.poll(); v.isInQueue = false; if (v.getAdj() != null && !v.getAdj().isEmpty()) { for (AdjVertex wadj : v.getAdj()) { if (wadj.cvw + v.dist < wadj.getW().dist) { wadj.getW().setDist(wadj.cvw + v.dist); wadj.getW().setPath(v); if (!wadj.getW().isInQueue) { wadj.getW().isInQueue = false; q.add(wadj.getW()); } } } } } }
O(|E|*|V|)
O(|E|+|V|)
Dijkstra是解決有權無負值圖單源最短路徑的經典算法。3d
若權有負值,藉助廣度優先搜素與有權無負值最短路徑思想結合來解決 ,其時間界限爲:code
O(|E|*|V|)
無權無圈最短路徑blog