最短路問題之Bellman-ford算法

題目:java

  最短路:給定兩個頂點,在以這兩個點爲起點和終點的路徑中,邊的權值和最小的路徑。考慮權值爲點之間的距離。算法

  單源最短路問題,Bellman-ford算法數組

  思路:每次循環檢查全部邊,可優化。ide

  應用於旅遊等路徑最小問題。優化

代碼:ui

 1 import java.util.Arrays;  2 
 3 public class 圖的最短路問題_單源 {  4     public static void main(String[] args) {  5         int[] shortestPath = shortestPath(0);  6  System.out.println(Arrays.toString(shortestPath));  7         // 輸出[0, 2, 5, 7, 11, 8, 16]
 8  }  9 
10     /**
11  * 求起點到各頂點的最短距離 12  * 13  * @param s 起點 14  * @return
15      */
16     private static int[] shortestPath(int s) { 17         int n = graph.length; 18         // 記錄s到各頂點的最短距離
19         int[] d = new int[n]; 20         for (int i = 0; i < n; i++) { 21             d[i] = Integer.MAX_VALUE; 22  } 23         d[s] = 0;// 到本身的距離爲0
24         while (true) { 25             boolean update = false; 26             // 掃描全部的邊
27             for (int i = 0; i < n; i++) { 28                 // 起點到i的最短距離還沒算出來
29                 if (d[i] == Integer.MAX_VALUE) 30                     continue; 31                 for (int j = 0; j < n; j++) { 32                     int cost = graph[i][j]; // i,j之間的距離
33                     if (cost > 0) { // i,j 兩點之間有邊,起點是i
34                         if (d[j] > d[i] + cost) { // 起點先到i,i->j 35                                                     // 兩端距離加起來比起點直接到j的距離短,則更新
36                             update = true; 37                             d[j] = d[i] + cost; 38  } 39  } 40  } 41  } 42             // 無需任何更新,退出外循環
43             if (!update) 44                 break; 45  } 46         return d; 47  } 48 
49     static int[][] graph = { 50             { 0, 2, 5, 0, 0, 0, 0 }, 51             { 2, 0, 4, 6, 10, 0, 0 }, 52             { 5, 4, 0, 2, 0, 0, 0 }, 53             { 0, 6, 2, 0, 0, 1, 0 }, 54             { 0, 10, 0, 0, 0, 3, 5 }, 55             { 0, 0, 0, 1, 3, 0, 9 }, 56             { 0, 0, 0, 0, 5, 9, 0 } 57  }; 58 }

   對於上一個代碼。能夠先把邊集提取出來,這樣不用每次掃描二維數組。this

   Edge類:spa

 1 /**
 2  * 邊 的封裝  3  * 邊集能夠用來表示圖  4  */
 5 public class Edge<T> implements Comparable<Edge> {  6     private T start;  7       private T end;  8       private int distance;  9 
10       public Edge(T start, T end, int distance) { 11         this.start = start; 12         this.end = end; 13         this.distance = distance; 14  } 15 
16       public T getStart() { 17         return start; 18  } 19 
20       public void setStart(T start) { 21         this.start = start; 22  } 23 
24       public T getEnd() { 25         return end; 26  } 27 
28       public void setEnd(T end) { 29         this.end = end; 30  } 31 
32       public int getDistance() { 33         return distance; 34  } 35 
36       public void setDistance(int distance) { 37         this.distance = distance; 38  } 39 
40  @Override 41       public String toString() { 42         return start + "->" + end + ":" + distance; 43  } 44 
45  @Override 46       public int compareTo(Edge obj) { 47         int targetDis = obj.getDistance(); 48         return distance > targetDis ? 1 : (distance == targetDis ? 0 : -1); 49  } 50 }
View Code

  優化事後的代碼:code

 1 import java.util.ArrayList;  2 import java.util.Arrays;  3 import java.util.List;  4 
 5 public class 圖的最短路問題_優化_邊集 {  6     public static void main(String[] args) {  7         edges = buildEdges(graph);  8         int[] shortestPath = shortestPath(0);  9  System.out.println(Arrays.toString(shortestPath)); 10         // 輸出[0, 2, 5, 7, 11, 8, 16]
11  } 12 
13     /**
14  * 求起點到各頂點的最短距離 15  * 16  * @param s 17  * 起點 18  * @return
19      */
20     private static int[] shortestPath(int s) { 21         int n = graph.length; 22         // 記錄s到各頂點的最短距離
23         int[] d = new int[n]; 24         for (int i = 0; i < n; i++) { 25             d[i] = Integer.MAX_VALUE; 26  } 27         d[s] = 0;// 到本身的距離爲0
28         while (true) { 29             boolean update = false; 30 
31             for (Edge<Integer> e : edges) { 32                 if (d[e.getStart()] != Integer.MAX_VALUE && d[e.getEnd()] > d[e.getStart()] + e.getDistance()) { 33                     update = true; 34                     d[e.getEnd()] = d[e.getStart()] + e.getDistance(); 35  } 36  } 37 
38             if (!update) 39                 break; 40  } 41         return d; 42  } 43 
44     static List<Edge<Integer>> edges; 45 
46     static List<Edge<Integer>> buildEdges(int[][] graph) { 47         int n = graph.length; 48         List<Edge<Integer>> edges = new ArrayList<>(); 49         for (int i = 0; i < n; i++) { 50             for (int j = 0; j < n; j++) { 51                 int cost = graph[i][j]; // i,j之間的距離
52                 if (cost > 0) { // i,j 兩點之間有邊,起點是i
53                     edges.add(new Edge<>(i, j, cost)); 54  } 55  } 56  } 57         return edges; 58  } 59 
60     static int[][] graph = { 61             { 0, 2, 5, 0, 0, 0, 0 }, 62             { 2, 0, 4, 6, 10, 0, 0 }, 63             { 5, 4, 0, 2, 0, 0, 0 }, 64             { 0, 6, 2, 0, 0, 1, 0 }, 65             { 0, 10, 0, 0, 0, 3, 5 }, 66             { 0, 0, 0, 1, 3, 0, 9 }, 67             { 0, 0, 0, 0, 5, 9, 0 } 68  }; 69 }
View Code
相關文章
相關標籤/搜索