# TSP with ACO ###### tags: `Algorithm` `Metaheuristic` --- [toc] --- ## 定義 ### 初始化 ``` void Initial( vector<vector<double>>&pheromone, vector<vector<double>>&n, vector<vector<int>>&path, vector<vector<double>>&dis); ``` pheromone費洛蒙表 n距離倒數表 path每隻螞蟻所走過的路徑 dis距離表 執行初始化時會先將pheromone(費洛蒙表)表都先給予最小值0.000001,以及先將dis(距離表)和n(距離倒數表)建立(將51個城市之間的距離算好),將path路徑初始化。 pheromone[i][j] 路徑ij的費洛蒙 dis[i][j] 路徑ij的距離 n[i][j] 路徑ij的距離的倒數 path[i][j] 城市(第i隻螞蟻,第j個順序的城市) ### 建構螞蟻初始路徑 ``` void ConstructAntSolutions( vector<vector<int>>&path, vector<vector<double>>pheromone, vector<vector<double>>n); ``` pheromone[i][j]=路徑ij的費洛蒙 path[i][j]=城市(第i隻螞蟻,第j個順序的城市) n[i][j]=路徑ij的距離的倒數 ### 更新費洛蒙及最佳解 ``` void UpdatePheromones( vector<vector<double>>&pheromone, vector<vector<double>>dis, vector<vector<int>>path, vector<double>&Lk, vector<int>&best_path, double &MIN_Lk); ``` Lk每隻隻螞蟻的總路徑長 best_path存放最佳解的路徑 MIN_LK存放最佳解的路徑長 pheromone[i][j]=路徑ij的費洛蒙 dis[i][j]=路徑ij的距離 path[i][j]=城市(第i隻螞蟻,第j個順序的城市) Lk[i] 存放51隻螞蟻的總路徑長 best_path[i] 存放最佳解的路徑 MIN_LK 存放最佳解的路徑長 ### 計算距離 ``` double Distance( int x1, int y1, int x2, int y2); ``` 回傳第二個點跟第一個點之間的距離 ### 計算機率 ![](https://i.imgur.com/2Mz5k4t.png) ``` double Prob( vector<vector<double>>pheromone, vector<vector<double>>n, int alpha, int beta, int i, int j, vector<double>p); ``` pheromone[i][j]=路徑ij的費洛蒙 n[i][j]=路徑ij的距離的倒數 alpha=1 beta=2 i 城市1 j 城市2 p[i] 如果不等於-1,代表城市尚未走過 公式上半部為費洛蒙表[i][j]的alpha次方乘上距離倒數[i][j]的beta次方 公式下半部為尚未走過的路徑的,費洛蒙表[i][j]的alpha次方乘上距離倒數[i][j]的beta次方的加總 ### 計算總路徑長 ``` void CalculateLk( vector<vector<int>>path, vector<vector<double>>dis, vector<double>&Lk); ``` dis[i][j]=路徑ij的距離 path[i][j]=城市(第i隻螞蟻,第j個順序的城市) Lk[i] 存放51隻螞蟻的總路徑長 計算每隻螞蟻的總路徑長(一整圈) ### 查看這隻螞蟻是否走過此路徑 ``` bool FindAntPath( int pos1, int pos2, int ant, vector<vector<int>>path); ``` pos1 城市1 pos2 城市2 ant 哪一隻螞蟻 path[i][j]=城市(第i隻螞蟻,第j個順序的城市) 判斷螞蟻是否走過指定路徑,回傳true或false ### 查看城市(debug用) ``` void ShowCity( int size, vector<city>City); ``` 查看讀入的測資 ### 查看路徑(debug用) ``` void ShowPath( vector<vector<int>>path); ``` 查看每一隻螞蟻所走過的路徑 ## 程式碼說明 ### 建構螞蟻初始路徑 ![](https://i.imgur.com/UWywXrW.png) > 上圖中,宣告以及將城市洗牌,rnd_city[i]代表第i隻螞蟻的初始城市 ![](https://i.imgur.com/SW6r5Lg.png) > 上圖中,外迴圈圍每隻螞蟻,pos紀錄順序(已經選擇到第幾個城市了),p[]為建立機率表,來決定下一點要走向哪個城市,已經走過的點p[第幾個城市(而不是前述的pos,pos是順序)]=-1,path[第幾隻螞蟻][順序]=起始城市。進入無窮迴圈,這邊會將每座城市的機率算出來(其中i為我現在所在的城市,j為我尚未走過的城市),temp會將所有機率相加,rnd_d會隨機產生亂數範圍從0~temp(大約為1.多),下面迴圈的部份是我將剛剛所產生的rnd_d(機率),如果尚未走過(p[k]!=-1),如果rnd_d大於此機率那就減去,如果rnd_d小於此機率代表下一個要選擇的城市為此,如果pos已經走完所有城市那就代表已經建構完成。 ### 更新費洛蒙及最佳解 ![](https://i.imgur.com/ECYRJVk.png) ![](https://i.imgur.com/HTorwep.png) > 上圖中,CalculateLk為計算每隻螞蟻所走的路徑總長,雙重迴圈當中是利用上面的公式將費洛蒙表做更新,公式前半部是要留下之前的多少比例,後半部為先判斷每隻螞蟻是否有走過此路徑(ij),如果有的話dis_total會將走過此路段的螞蟻,使用mQ/路徑長(Lk[i])相加。結束費洛蒙表更新後,會來判斷每隻螞蟻的總路徑長是否有小於目前的最佳解的路徑長(MIN_Lk),如果有的話將路徑長(MIN_Lk)及最佳解(best_path)更新。 ### 主程式 ![](https://i.imgur.com/SO0kiNu.png) ## 執行(目前最好為427.389,但因疏失沒有紀錄) ### Github > https://github.com/taro0520/TSP_ACO ### 指令 > ./main [#runs] [#iteration] [#ants] [#citynumber] [#alpha] [#beta] [#p] [#q] [#filename] ### 參數設置 > Runs:30 > Iteration:1000(平均執行完1000iteration需花16-30分鐘) > Ants:51(小於等於城市數量) > Citynumber:51 > Alpha:1 > Beta:2 > P:0.8 > Q:100 > Filename:data.txt > 測資: http://elib.zib.de/pub/mp-testdata/tsp/tsplib/tsp/ (eil51) ### 產生gnuplot圖 1. 將產生好的Best Path貼至result/path.txt 2. 使用此指令將路徑轉成xy座標.\point 51 city.txt path.txt path_xy.txt (城市數量:51 城市座標:city.txt 路徑順序:path.txt 輸出:path_xy.txt) 3. plt寫法 ![](https://i.imgur.com/No4LGev.png) 4. 使用gnuplot產生圖檔 ### 輸出(持續更新) > =[Travelling Salesman Problem]= > #Algorithm:Ant Colony Optimization > #Runs:9 > #Iteration:1000 > #Ants:51 > #Citynumber:51 > #Alpha:1 > #Beta:2 > #P:0.8 > #Q:100 > **#Best Distance:432.187** > **#Best Path:** > **36 16 3 17 13 24 12 40 18 39 41 43 14 44 32 38 9 48 4 37 10 31 0 21 1 15 49 8 29 33 20 28 19 34 35 2 27 30 7 25 6 42 23 22 47 5 26 50 45 11 46** > #Cost Time:13140s #### gnuplot圖 ![](https://i.imgur.com/H8dBCWK.png) ### 多筆測試輸出 1. > =[Travelling Salesman Problem]= > #Algorithm:Ant Colony Optimization > #Runs:30 > #Iteration:1000 > #Ants:51 > #Citynumber:51 > #Alpha:1 > #Beta:2 > #P:0.8 > #Q:100 > **#Best Distance:433.795** > **#Best Path:** > **8 49 15 1 21 0 31 10 37 4 48 9 38 32 44 14 43 41 39 18 40 12 24 13 17 46 3 16 36 11 45 50 26 47 5 22 23 42 6 25 7 30 27 2 35 34 19 28 20 33 29** > #Cost Time:41646s ![](https://i.imgur.com/rW9kJVi.png) 2. > =[Travelling Salesman Problem]= > #Algorithm:Ant Colony Optimization > #Runs:30 > #Iteration:1000 > #Ants:51 > #Citynumber:51 > #Alpha:1 > #Beta:2 > #P:0.8 > #Q:100 > **#Best Distance:435.644** > **#Best Path:** > **24 12 40 18 39 41 16 36 43 14 44 32 38 9 29 8 48 4 37 10 31 0 21 1 15 49 33 20 28 19 34 35 2 27 30 25 7 47 22 6 42 23 13 5 26 50 45 11 46 3 17** > #Cost Time:46916s ![](https://i.imgur.com/tA8eO4M.png) 3. > =[Travelling Salesman Problem]= > #Algorithm:Ant Colony Optimization > #Runs:30 > #Iteration:1000 > #Ants:51 > #Citynumber:51 > #Alpha:1 > #Beta:2 > #P:0.8 > #Q:100 > **#Best Distance:436.646** > **#Best Path:** > **5 26 50 45 11 46 3 17 13 24 12 40 18 39 41 16 36 43 14 44 32 38 9 29 33 49 15 1 21 0 31 10 37 4 48 8 20 28 19 34 35 2 27 30 25 7 47 22 6 42 23** > #Cost Time:46863s ![](https://i.imgur.com/iGSE5Gk.png) 4. > =[Travelling Salesman Problem]= > #Algorithm:Ant Colony Optimization > #Runs:30 > #Iteration:1000 > #Ants:51 > #Citynumber:51 > #Alpha:1 > #Beta:2 > #P:0.8 > #Q:120 > **#Best Distance:437.053** > **#Best Path:** > **14 44 32 38 9 48 4 37 10 31 0 21 1 15 49 33 29 8 20 28 19 34 35 2 27 30 7 25 6 42 23 22 47 5 26 50 45 11 46 3 17 13 24 12 40 39 18 41 43 36 16** > #Cost Time:41593s ![](https://i.imgur.com/g2luhwa.png) 5. > =[Travelling Salesman Problem]= > #Algorithm:Ant Colony Optimization > #Runs:30 > #Iteration:1000 > #Ants:51 > #Citynumber:51 > #Alpha:1 > #Beta:2 > #P:0.8 > #Q:100 > **#Best Distance:437.615** > **#Best Path: > **22 6 42 23 13 24 12 40 18 39 41 16 36 43 14 44 32 9 38 29 8 48 4 37 10 31 0 21 1 15 49 33 20 28 19 34 35 2 27 30 25 7 47 26 50 45 11 46 3 17 5** > #Cost Time:46893s ![](https://i.imgur.com/RVWAmbT.png)