日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

tsp 分支界限 java_干货 | 10分钟教你用branch and bound(分支定界)算法求解TSP旅行商问题...

發布時間:2024/10/8 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 tsp 分支界限 java_干货 | 10分钟教你用branch and bound(分支定界)算法求解TSP旅行商问题... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在此之前,先給大家講講最重要的一個點,搜索樹的節點定義,節點定義了原問題的solution和子問題的solution。Node節點定義如下:

public class Node {private ArrayList path;private double bound;private int level;public double computeLength(double[][] distanceMatrix) {// TODO Auto-generated method stubdouble distance = 0;for(int i=0;i

其余不重要的接口略過。如下:

- path:保存該節點目前已經走過的城市序列。

- bound:記錄該節點目前所能達到的最低distance。

- level:記錄節點處于搜索樹的第幾層。

- computeLength:記錄當前城市序列的distance。

可能大家還沒理解節點是如何分支的,看一張圖大家就懂了。我們知道TSP問題的一個solution是能用一個序列表示城市的先后訪問順序,比如現在有4座城市(1,2,3,4):

圖中每個節點的數字序列就是path保存的。大家都看到了吧,其實分支就是一個窮枚舉的過程。

相對于窮舉,分支定界算法的優越之處就在于其加入了定界過程,在分支的過程中就砍掉了某些不可能的支,減少了枚舉的次數,大大提高了算法的效率。如下:

分支定界算法的主過程如下:

private static void solveTSP(double[][] distanceMatrix) {int totalCities = distanceMatrix.length;ArrayList cities = new ArrayList();for (int i = 0; i < totalCities; i++) {cities.add(i);}ArrayList path;double initB = initbound(totalCities, distanceMatrix);Node v = new Node(new ArrayList<>(), 0, initB, 0);queue.add(v);queueCount++;while (!queue.isEmpty()) {v = queue.remove();if (v.getBound() < shortestDistance) {Node u = new Node();u.setLevel(v.getLevel() + 1);for (int i = 1; i < totalCities; i++) {path = v.getPath();if (!path.contains(i)) {u.setPath(v.getPath());path = u.getPath();path.add(i);u.setPath(path);if (u.getLevel() == totalCities - 2) {// put index of only vertex not in u.path at the end// of u.pathfor (int j = 1; j < cities.size(); j++) {if (!u.getPath().contains(j)) {ArrayList temp = new ArrayList<>();temp = u.getPath();temp.add(j);u.setPath(temp);}}path = u.getPath();path.add(0);u.setPath(path);if (u.computeLength(distanceMatrix) < shortestDistance) {shortestDistance = u.computeLength(distanceMatrix);// implementshortestPath = u.getPath();}} else {u.setBound(computeBound(u, distanceMatrix, cities));//u.getBound()獲得的是不完整的解,如果一個不完整的解bound都大于當前最優解,那么完整的解肯定會更大,那就沒法玩了。//所以這里只要u.getBound() < shortestDistance的分支if (u.getBound() < shortestDistance) {queue.add(u);queueCount++;}else {System.out.println("currentBest = "+shortestDistance+" cut bound >>> "+u.getBound());}}}}}}}

1. 首先initbound利用貪心的方式獲得一個bound,作為初始解。

2. 而后利用優先隊列遍歷搜索樹,進行branch and bound算法。對于隊列里面的任意一個節點,只有(v.getBound() < shortestDistance)條件成立我們才有分支的必要。不然將該支砍掉。

3. 分支以后判斷該支是否到達最底層,這樣意味著我們獲得了一個完整的解。那么此時就可以更新當前的最優解了。

4. 如果沒有到達最底層,則對該支進行定界操作。如果該支的bound也比當前最優解還要大,那么也要砍掉的,就像林志炫的單身情歌里面唱的一樣:每一個單身狗都得砍頭。

然后講講定界過程,TSP問題是如何定界的呢?

private static double computeBound(Node u, double[][] distanceMatrix, ArrayList cities) {double bound = 0;ArrayList path = u.getPath();for (int i = 0; i < path.size() - 1; i++) {bound = bound + distanceMatrix[path.get(i)][path.get(i + 1)];}int last = path.get(path.size() - 1);List subPath1 = path.subList(1, path.size());double min;//回來的for (int i = 0; i < cities.size(); i++) {min = Integer.MAX_VALUE;if (!path.contains(cities.get(i))) {for (int j = 0; j < cities.size(); j++) {if (i != j && !subPath1.contains(cities.get(j))) {if (min > distanceMatrix[i][j]) {min = distanceMatrix[i][j];}}}}if (min != Integer.MAX_VALUE)bound = bound + min;}//出去的min = Integer.MAX_VALUE;for (int i = 0; i < cities.size(); i++) {if (/*cities.get(i) != last && */!path.contains(i) && min > distanceMatrix[last][i]) {min = distanceMatrix[last][i];}}bound = bound + min;//System.out.println("bound = "+bound);return bound;}

我們知道,每個節點保存的城市序列可能不是完整的解。bound的計算方式:bound = 當前節點path序列的路徑距離 + 訪問下一個城市的最短路徑距離 + 從下一個城市到下下城市(有可能是起點)的最短路徑距離。

比如城市節點5個{1,2,3,4,5}。當前path = {1,2},那么:

- 當前節點path序列的路徑距離 =d12

- 訪問下一個城市的最短路徑距離 =min (d2i), i in {3,4,5}

- 從下一個城市到下下城市(有可能是起點)的最短路徑距離=min (dij), i in {3,4,5} , j in {3,4,5,1}, i != j 。

注意這兩個是可以不相等的。

總結

以上是生活随笔為你收集整理的tsp 分支界限 java_干货 | 10分钟教你用branch and bound(分支定界)算法求解TSP旅行商问题...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。