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