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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

回溯法——旅行售货员问题

發(fā)布時(shí)間:2024/4/17 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 回溯法——旅行售货员问题 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

旅行售貨員問(wèn)題即給幾個(gè)地點(diǎn),相互之間有路徑,有每個(gè)路徑對(duì)應(yīng)的消耗的費(fèi)用。我們將起點(diǎn)設(shè)為1,其他地點(diǎn)設(shè)為2,3,4…n。我們起初將所有路徑費(fèi)用都設(shè)置成∞,然后再輸入 相通路徑的費(fèi)用,再更新費(fèi)用值。我們以下圖為例。如下圖:

注意BackTrack主要是一個(gè)求排列組合函數(shù)(排列組合函數(shù)思路見“遞歸分治——排列組合”博客),加上了路徑和費(fèi)用回溯。代碼如下(適用于旅行售貨員問(wèn)題無(wú)向圖)主要代碼端在BackTraack處:

//回溯法 //旅行售貨員問(wèn)題 class TraveLing { private:int n; // 頂點(diǎn)個(gè)數(shù)vector<vector<int>> a; // 圖的鄰接矩陣int* x; // 記錄當(dāng)前路徑int* bestx; // 最優(yōu)解路徑int cc; // 當(dāng)前費(fèi)用int bestc; // 最優(yōu)解費(fèi)用void BackTrack(int i)//排列組合{if (i == n)//遞歸出口{if (a[x[n - 1]][x[n]] != INT_MAX && a[x[n][x[1]] != INT_MAX && (cc + a[x[n - 1]][x[n]] + a[x[n]][x[1]] < bestc))//當(dāng)前路徑比之前路徑費(fèi)用少{for (int j = 1; j < n+1; ++j){bestx[j] = x[j];//更新目前最優(yōu)路徑 ,注意bestx和x都是從下標(biāo)1開始用的,下標(biāo)0我們實(shí)際不用}bestc = cc + a[x[n - 1]][x[n]] + a[x[n]][x[1]];}}else{for (int j = i; j <= n; ++j){if (a[x[i - 1]][x[i]] != INT_MAX && cc + a[x[i - 1]][x[i]] < bestc ||bestc == INT_MAX){swap(x[i], x[j]);cc += a[x[i - 1]][x[i]];BackTrack(i + 1);cc -= a[x[i - 1]][x[i]];//遞歸回退就回溯swap(x[i], x[j]);}}}} public:TraveLing(int sum) :n(sum), cc(0), bestc(INT_MAX){x = new int[n + 1];//多申請(qǐng)一個(gè)空間,我們從下標(biāo)1開始用,下標(biāo)0實(shí)際不用bestx = new int[n + 1];//多申請(qǐng)一個(gè)空間,我們從下標(biāo)1開始用,下標(biāo)0實(shí)際不用for (int i = 1; i < n+1 ; i++){x[i] = i;//當(dāng)前路徑初始化為1,2,3...n,注意x的0下標(biāo)我們實(shí)際不用bestx[i] = 1;//當(dāng)前最優(yōu)解路徑初始化為11111...}a.resize(n + 1);//初始化鄰接矩陣,并且每個(gè)路徑都初始化為最大值,為了邏輯清晰一點(diǎn),下標(biāo)0沒(méi)有實(shí)際用for (int i = 0; i < n + 1; i++){a[i].resize(n + 1);}for (int i = 0; i < n + 1; i++){for (int j = 0; j < n + 1; j++){a[i][j] = INT_MAX;}}//輸入每?jī)蓚€(gè)地點(diǎn)和這兩個(gè)地點(diǎn)消耗的費(fèi)用cout << "please input 'way1' to 'way1' and 'cost'if way1 < 1 or way2 < 1 or cost < 0 end:\n";int u = 1;int v = 1;int w = 0;while (u >= 1 && v >= 1 && w >= 0){cin >> u >> v >> w;a[u][v] = w;a[v][u] = w;}BackTrack(2);//傳入2 是因?yàn)槲覀儚钠瘘c(diǎn)1出發(fā),只需要對(duì)地點(diǎn)2開始到n這些地點(diǎn)進(jìn)行排列組合}~TraveLing(){delete[] x;delete[] bestx;}void PrintBestx()//打印最優(yōu)解路徑{for (int i = 1; i < n+1; i++){cout << bestx[i] << " ";}cout << "1";//路徑結(jié)束后肯定回到起點(diǎn)1cout << endl;}int GetBestc()//獲取最優(yōu)解路徑下的費(fèi)用{return bestc;} };int main() {TraveLing tra(4);tra.PrintBestx();cout << tra.GetBestc() << endl;return 0; }

運(yùn)行截圖:

總結(jié)

以上是生活随笔為你收集整理的回溯法——旅行售货员问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。