回溯法分析題


2019-04-24

東 華 大 學

《算法設計分析與綜合實踐》分析題作業

 

學生姓名:曹晨 學號:171310402

  1. 作業題目

    旅行售貨員問題的費用上限

    設G是一個有n個頂點的有向圖,從頂點i發出的邊的最大費用記為max(i)。

    1. 證明旅行售貨員回路的費用不超過
    2. 在旅行售貨員問題的回溯法中,用上面的界作為bestc的初始值,重寫該算法,並盡可能的簡化代碼
  2. 解題過程(針對算法設計題)
  3. 簡明扼要地寫出解題思路或算法設計思路。可用文字、圖等描述
    1. 證明:旅行售貨員的回路有很多種解,假設有四個節點分別是ABCD,按照可行的一種順序B D A C 的求解費用,其費用為,推廣都所有解的情況,按照節點經過的順序編號為1,2,3,4,其費用為,再推廣到n個節點的情況。由此可以看出
    2. 在回溯法中,旅行售貨員算法中的bestc的初始化為NoEdge,現將其修改bestc=

     

  4. 寫出算法描述(要有每個步驟加數字標號,必要的地方加注釋,注釋用雙斜杠//表示),例如:

    輸入:

    4

    0 30 6 4

    30 0 5 10

    6 5 0 20

    4 10 20 0

    輸出:

    1à3à2à4à1

    25

    算法描述如下:

    算法包括定義一個類,類里有三個函數,一個構造函數,一個遞歸函數,一個求bestc的函數如下

    1 template <class ElemType>
    
    2 class Travelling{
    
    3 public:
    
    4 Travelling(int nw,ElemType **ai,ElemType no)//構造函數
    
    5 {
    
    6 n=nw;
    
    7 for(int i=1 to n)
    
    8 for(int j=1 to n)
    
    9 a[i][j]=ai[i][j];
    
    10 NoEdge=no;
    
    11 }
    
    12 ElemType CalSum();//初始化bestc並調用遞歸函數的函數
    
    13 private:
    
    14 void Recursive(int i);//遞歸尋找可行回路的函數
    
    15 int n;//圖的頂點數
    
    16 int *x;//當前解
    
    17 int *bestx;//當前最優解
    
    18 ElemType **a;//圖的鄰接矩陣
    
    19 ElemType s;//當前費用
    
    20 ElemType bestc;//當前最優值
    
    21 ElemType NoEdge;//無邊標記
    
    22 };
    
    23 void Travelling<ElemType>::Recursive(int i)
    
    24 {
    
    25 if(i到達第n層即搜索到葉子結點)
    
    26 {
    
    27 if(城市x[n-1]可以到達城市x[n],並且城市x[n]可以回到城市1,且此時所走的路程s加上x[n-1]與x[n]的距離和x[n]與1的距離小於當前最優值bestc)
    
    28
    
    29 {
    
    30 for(int j=1 to n)
    
    31 bestx[j]=x[j];//保存當前最優解的順序
    
    32 bestc=s+a[x[n-1]][x[n]]+a[x[n]][x[1]];//記錄當前最優解的值
    
    33 }
    
    34 }
    
    35 else
    
    36 {
    
    37 for(int j=i to n)
    
    38 if(城市x[i-1]能達到城市x[j]即這兩個城市間有邊,並當前所走的路程s加上這兩個城市的距離比當前最優值bestc小)
    
    39 {
    
    40 swap(x[i],x[j]);
    
    41 s+=a[x[i-1]][x[i]];//修改此時所走的路程s,進入下一層遞歸
    
    42 Recursive(i+1);
    
    43 s-=a[x[i-1]][x[i]];//恢復原來cc的值
    
    44 swap(x[i],x[j]);
    
    45 }
    
    46 }
    
    47 }
    
    48 ElemType Travelling<ElemType>::CalSum()
    
    49 {
    
    50 int maxi;
    
    51 bestc=1;//初始化為1
    
    52 for(int i=1 to n)
    
    53 for(int j=1 to n)
    
    54 if(a[i][j]>maxi)//遍歷找到從節點i發出的最大費用的邊
    
    55 maxi=a[i][j];
    
    56 if(maxi!=NoEdge)//如果沒有
    
    57 return NoEdge;//直接返回無邊標記
    
    58 bestc+=maxi;//否則加緊bestc
    
    59 for(int i=1 to n)
    
    60 x[i]=i;
    
    61 bestx[i]=i;//初始化x和bestx的順序
    
    62 s=0;//初始化當前費用
    
    63 Recursive(2);//從第二層開始遞歸求回路
    
    64 return bestc;
    
    65 }

     

     

  5. 算法分析:

    時間復雜度:

    在函數CalSum中,兩個嵌套的for循環用來求bestc的初始值,一個for循環來初始化x和bestx,總時間為f(n)=n+n*n=O(n)。在函數Recursive中,在最壞的情況下可能需要更新當前最優解O((n-1)!),每次更新bestx需要O(n)計算時間,從而整個算法的時間復雜度為O((n)!);

    空間復雜度:

    圖的鄰接矩陣用了一個二維數組,當前解和最優解分別用了兩個一維數組,所以f(n)=n*n+n*2=O(n² ),算法的空間復雜度維O(n² )

代碼見打包文件


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM