五大經常使用算法之四:回溯法 五大經常使用算法之四:回溯法

一、概念

      回溯算法實際上一個相似枚舉的搜索嘗試過程,主要是在搜索嘗試過程當中尋找問題的解,當發現已不知足求解條件時,就「回溯」返回,嘗試別的路徑。html

    回溯法是一種選優搜索法,按選優條件向前搜索,以達到目標。但當探索到某一步時,發現原先選擇並不優或達不到目標,就退回一步從新選擇,這種走不通就退回再走的技術爲回溯法,而知足回溯條件的某個狀態的點稱爲「回溯點」。算法

      許多複雜的,規模較大的問題均可以使用回溯法,有「通用解題方法」的美稱。數組

二、基本思想

       在包含問題的全部解的解空間樹中,按照深度優先搜索的策略,從根結點出發深度探索解空間樹。當探索到某一結點時,要先判斷該結點是否包含問題的解,若是包含,就從該結點出發繼續探索下去,若是該結點不包含問題的解,則逐層向其祖先結點回溯。(其實回溯法就是對隱式圖的深度優先搜索算法)。框架

       若用回溯法求問題的全部解時,要回溯到根,且根結點的全部可行的子樹都要已被搜索遍才結束。函數

       而若使用回溯法求任一個解時,只要搜索到問題的一個解就能夠結束。post

三、用回溯法解題的通常步驟:

    (1)針對所給問題,肯定問題的解空間:url

            首先應明肯定義問題的解空間,問題的解空間應至少包含問題的一個(最優)解。spa

    (2)肯定結點的擴展搜索規則code

    (3)以深度優先方式搜索解空間,並在搜索過程當中用剪枝函數避免無效搜索。htm

四、算法框架

     (1)問題框架

      設問題的解是一個n維向量(a1,a2,………,an),約束條件是ai(i=1,2,3,…..,n)之間知足某種條件,記爲f(ai)。

     (2)非遞歸回溯框架

int a[n],i;
初始化數組a[];
i = 1;
while (i>0(有路可走)   and  (未達到目標))  // 還未回溯到頭
{
    if(i > n)                                              // 搜索到葉結點
    {   
          搜索到一個解,輸出;
    }
    else                                                   // 處理第i個元素
    { 
          a[i]第一個可能的值;
          while(a[i]在不知足約束條件且在搜索空間內)
          {
              a[i]下一個可能的值;
          }
          if(a[i]在搜索空間內)
         {
              標識佔用的資源;
              i = i+1;                              // 擴展下一個結點
         }
         else 
        {
              清理所佔的狀態空間;            // 回溯
              i = i –1; 
         }
}

(3)遞歸的算法框架

         回溯法是對解空間的深度優先搜索,在通常狀況下使用遞歸函數來實現回溯法比較簡單,其中i爲搜索的深度,框架以下:

int a[n];
try(int i)
{
     if(i>n)
        輸出結果;
      else
     {
        for(j = 下界; j <= 上界; j=j+1)  // 枚舉i全部可能的路徑
        {
           if(fun(j))                 // 知足限界函數和約束條件
             {
                a[i] = j;
              ...                         // 其餘操做
                try(i+1);
              回溯前的清理工做(如a[i]置空值等);
              }
         }
     }
}

 (以上內容轉自五大經常使用算法之四:回溯法

相關文章
相關標籤/搜索