旅行商问题—蛮力法
旅行商問題之蠻力法求解最短路徑
找到一個從任一頂點出發,經過所有頂點再回到此頂點的最短路徑。
如圖,假設從頂點0開始出發,經過頂點1,2,3再回到頂點0,求解路徑最短的方法。
?暴力法求解,就是將所有情況列舉出來,然后選擇權值最小的路徑為最優解??梢韵葘旤c進行全排列,然后用計算回路權值的函數將每種情況的權值之和計算出來,再選擇其中最小的作為最優解。
具體c++代碼如下:
#include<vector> #include<iostream> using namespace std;//計算權值 double pathCost(const vector<vector<double>>& G, const vector<int>& path) {double cost = 0;int k = path[0];for (int i = 1; i < path.size(); i++){cost += G[k][path[i]];k = path[i];}//最后要構成回路,所以再加上一個回到起點的權值cost += G[k][path[0]];return cost; }//全排列求最短路徑 G是權值數組 S是存放頂點 minPath存放最短路徑 double TSP_BF(vector<vector<double>>& G, vector<int>& S, int k, vector<int> minPath) {int n = S.size();if (k == n) //全排列完畢return pathCost(G, S);double minCost = 100000;for (int i = k; i < n; i++) //進行全排列{swap(S[i], S[k]); //回溯法 交換位置之后為了不讓原序列打亂,需要再換回來double cost = TSP_BF(G, S, k + 1, minPath);if (cost < minCost) //比之前的花費更少,則記錄此時的cost和此時的路徑{minCost = cost;minPath = S;//此時S已經交換了 所以可以得到最小路徑}swap(S[i], S[k]); //換回來}return minCost; }//輸出vector void Pirnt_vec(vector<int>& vec) {for (int i = 0; i < vec.size(); i++)cout << vec[i] << " ";cout << endl; }void main() {double inf = 100000;//自己到自己的權值是無窮大//G用來存放頂點之間的權值,用了一個二維的集合,定義權值類型為doublevector<vector<double>> G = { {inf,30,6,4},{30,inf,5,10},{6,5,inf,20},{4,10,20,inf} };//S用來存放頂點的集合vector<int> S = { 0,1,2,3 };//minPath用來存儲最優解的路徑vector<int> minPath;//設置0頂點作為初始位置,所以k從1開始double minCost = TSP_BF(G, S, 1, minPath);cout << minCost << endl;Pirnt_vec(minPath); }總結
- 上一篇: 最优化:一维搜索的Wolfe条件与Gol
- 下一篇: 不修条地铁,都不好意思叫自己大城市(附地