演算法之旅行售貨員問題
阿新 • • 發佈:2018-12-18
問題描述:售貨員要到n個城市去推銷商品,已知各城市之間的路程(代價)a[][],試選擇一條路,從第一個城市出發經過每個城市一遍,最後回到出發城市所耗費的代價最小。例:
問題分析:分析可知解空間是一棵排列樹,每一條從根節點到達葉子結點的路徑代表了n個頂點的一種排列。定義x[N]記錄可行解。剪枝函式:兩個城市之間是否連通,到達當前為止的代價是否已經超過了最優代價,當前城市是否已經走過
#include <iostream> using namespace std; #define NoEdge -1 //兩點之間無法到達 int n=4; //頂點(城市)數量 int cost=0; //從出發城市到當前位置的代價 int bestc=NoEdge; //最優代價 int bestx[4]; //最優解 int x[4]; //x[i]記錄第i個城市的索引 int a[4][4]= //記錄城市之間代價,如果兩座城市之間不連通則為NoEdge { -1,30,6,4, 30,-1,5,10, 6,5,-1,20, 4,10,20,-1 }; bool isHave(int i,int t) { for(int j=0; j<t; j++) if(x[j]==i)return true; return false; } void Backtrack(int t) { if(t==n) { //最後一個城市和出發城市是否可到達,該條通路的代價是不是最優 if(a[x[n-1]][0]!=NoEdge &&((cost+a[x[n-1]][0])<bestc||bestc==NoEdge)) { for(int i=0; i<n; i++) { bestx[i]=x[i]; bestc=cost+a[x[n-1]][0]; } } } else { for(int i=0; i<n; i++) { //當前城市是否已經走過,當前城市與上一座城市之間是否連通 if(!isHave(i,t)&&a[x[t-1]][i]!=NoEdge&&((cost+a[x[t-1]][i])<bestc||bestc==NoEdge)) { cost+=a[x[t-1]][i]; //cout<<t<<endl; x[t]=i; Backtrack(t+1); cost-=a[x[t-1]][i]; } } } } int main() { x[0]=0; //出發城市固定為第一座城市 Backtrack(1); for(int i=0; i<n; i++) cout<<bestx[i]+1<<" "; cout<<endl; cout<<bestc<<endl; }
時間複雜度:O(n^3)