回溯算法總結

 一、   回溯算法是一種組織搜索的一般技術,有“通用的解題法”之稱,它可以系統地搜索一個問題的所有解或任意解。

    1、應用回溯算法時,需要明確定義問題的解空間,問題的解空間應至少包含問題的一個最優解。

   /2、定義了問題的解空間後,還應將解空間很好的組織起來,使得回溯法能方便的搜索解空間,通常組織成數或圖的形式。

   /3、從樹根到葉子節點的任一路徑表示解空間的一個元素。

二、回溯算法的基本思想:

    在確定瞭解空間的基本結構後,回溯從開始結點出發,以深度優先的方式搜索整個解空間。這個開始結點成爲一個活結點,同時成爲當前的擴展結點。通過當前的擴展節點,搜索向深度方向進入一個新的結點。這個新的節點成爲一個新的活結點,併成爲當前的擴展結點。若在當前擴展結點處不能再向深度方向移動,則當前擴展結點成爲一個死結點。此時回溯到最近的一個活節點處,並使當前的的活節點成爲擴展結點。回溯算法以這樣的方法遞歸搜索整個空間樹,直至滿足終止條件。

三、算法基本結構與相關問題:

1、遞歸回溯:

void Backtrack(int t)
{
 if (t > n)
 {
  output(x);
 }
 else
 {
  for (int i = f(n,t); i < g(n,t); ++i)
  {
   x[t] = h(i);
   if (Constraint(t)&&Bound(t))
    Backtrack(t+1);
  }
 }

}

 2、迭代回溯

如果採用樹的非遞歸深度優先搜索遍歷算法;也可以將回溯法表示爲一個非遞歸的迭代過程。如下:

void iterativeBacktrack(void)

{

     int t = 1;

    while(t  > 0)

    {

        if (f(n,t)<g(n,t))

       {

                for (int i = f(n,t); i < g(n,t);++i)

               {

                     x[t] =h(i);

                     if (Constraint(t)&&Bound(t))

                    { 

                           if (Solution(x)) output(x);

                           else ++t;

                      }// end if

                      else   --t;

        }// end for

    }// end while

}// end function iterativeBacktrack

1、0-1揹包問題。

2、旅行商問題。

子集數與排列數

3、裝載問題。

4、圖的m着色問題。

5、n皇后問題。

6、流水作業調度問題。

7、子集和問題。

四、題目:

問題:給出一組候選數字(C)和目標數字(T),找出C中所有的組合,使組合中數字的和爲T。C中每個數字在每個組合中只能使用一次。

樣例

給出一個例子,候選數字集合爲[10,1,6,7,2,1,5] 和目標數字 8  ,

解集爲:[[1,7],[1,2,5],[2,6],[1,1,6]]

代碼:

class Solution {  
public:  
    /** 
     * @param num: Given the candidate numbers 
     * @param target: Given the target number 
     * @return: All the combinations that sum to target 
     */  
    vector<vector<int> > combinationSum2(vector<int> &num, int target) {  
        // write your code here  
        set<vector<int> > r;  
        vector<int> cur;  
        sort(num.begin(),num.end());  
        combination(cur,num,0,0,target,r);  
        vector<vector<int> > ret;  
        copy(r.begin(),r.end(),back_inserter(ret));  
        return ret;  
    }  
    void combination(vector<int> cur,vector<int> &num,int index,int curSum,int target,set<vector<int> >&ret)  
    {  
        if(curSum>target)  
            return;  
        if(curSum==target)  
        {  
            ret.insert(cur);  
            return;  
        }  
        if(index==num.size())  
            return;  
        combination(cur,num,index+1,curSum,target,ret);  
        cur.push_back(num[index]);  
        combination(cur,num,index+1,curSum+num[index],target,ret);  
    }  
};  




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章