動態規劃經典問題--TSP問題

來源:互聯網
上載者:User

標籤:

Travelling Salesman Problem

旅行商問題,即TSP問題(Travelling Salesman Problem)又譯為旅行推銷員問題、貨郎擔問題,是數學領域中著名問題之一。假設有一個旅行商人要拜訪n個城市,他必須選擇所要走的路徑,路徑的限制是每個城市只能拜訪一次,而且最後要回到原來出發的城市。路徑的選擇目標是要求得的路徑路程為所有路徑之中的最小值。
旅行商問題是圖論中最著名的問題之一,即“已給一個n個點的完全圖,每條邊都有一個長度,求總長度最短的經過每個頂點正好一次的封閉迴路”。該問題通常被認為是一個NP完全問題。時間複雜度為O(n!)。因此,通常n的值不是很大。

因此我們如何求其近似解(非多項式時間演算法)呢?這裡使用動態規劃

  1. 假定我們從城市1出發,經過了一些地方,併到達了城市j。毋庸置疑,我們需要記錄的資訊有當前的城市j。同時我們還需要記錄已經走過的城市的集合。同理,使用S記錄未走過的城市的集合也可以的,且運算方便。
  2. 於是我們可以得出狀態轉移方程 go(S,init)=min{go(S?i,i)+dp[i][init]}?s∈S go(s,init)表示從init點開始,要經過s集合中的所有點的距離
  3. 因為是NP問題,所以時間複雜度通常比較大。使用dis[s][init]用來去重,初始化為-1,如果已經計算過init—>S(遞迴形式),則直接返回即可

例: Sicily1000. Traveling Salesman Problem
題目大意:有編號1到N的N個城市,問從1號城市出發,遍曆完所有的城市並最後停留在N號城市的最短路徑長度。N<=20
那麼如何有效地儲存當前還未走過的城市集合S呢?使用一個整形即可。每個整形可以表示32位,即32個城市,用1代表當前未去,0代表當前已經訪問過的點。因N<=20,所以S<=1048576.

代碼如下:*

#include<iostream>#include<cmath> #include<iomanip>using namespace std;int s;int N;//點的個數 int init_point;double x[20];double y[20];double dp[20][20];//兩個城市的距離 double dis[1048577][20];//2^20=1048576 表示出發點到S集合是否已經訪問過 double go(int s,int init){    if(dis[s][init]!=-1) return dis[s][init];//去重     if(s==(1<<(N-1))) return dp[N-1][init];//只有最後一個點返回     double minlen=100000;    for(int i=0;i<N-1;i++)//只能在1到n-2點中尋找     {        if(s&(1<<i))//如果i點在s中且不為發出點         {            if(go(s&(~(1<<i)),i)+dp[i][init]<minlen)                minlen=go(s&(~(1<<i)),i)+dp[i][init];        }     }     return dis[s][init]=minlen;}int main(){    int T;    cin>>T;    while(T--)//測試範例數     {        cin>>N;        for(int i=0;i<N;i++)            cin>>x[i]>>y[i];//讀入城市的座標         for(int i=0;i<N;i++)            for(int j=0;j<N;j++)            {                dp[i][j]=sqrt(pow((x[i]-x[j]),2)+pow((y[i]-y[j]),2));                //計算兩個城市的距離             }           for(int i=0;i<pow(2,N);i++)            for(int j=0;j<N;j++)                dis[i][j]=-1;//去重數組初始化          init_point=0;        s=0;         for(int i=1;i<N;i++)            s=s|(1<<i);//從1開始,保證初始點沒有在S裡面                   double distance=go(s,init_point);        cout<<fixed<<setprecision(2)<<distance<<endl;    }       } 

動態規劃經典問題--TSP問題

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.