回溯法理解
回溯法
基本思想:
構建問題的解空間樹,在其解空間樹中,從根節點出發,進行深度優先搜尋。在搜尋過程中,對解空間
樹的每個結點進行判斷,判斷該結點是否包含問題的解,若肯定不包含,則跳過對以該結點為根的子樹的
搜尋,逐層向其祖先結點回溯。否則,則進入該子樹,繼續按深度優先策略搜尋。
步驟:
1、針對所給問題,定義其解空間
2、確定易於搜尋的解空間結構
3、深度優先搜尋其解空間,並在搜尋過程中用剪枝函式避免無效搜尋
剪枝:
回溯法搜尋空間樹時,常用限界函式和約束函式避免無效搜尋,其中約束函式將不滿足約束的子樹剪去,限界函式將得不到
最優解的子樹。一般可以利用這兩種剪枝方式提升演算法的效率,避免大量的不必要搜尋。
常見解空間:
常見的解空間有子集樹和排列樹兩種,當問題是從n個元素的集合S中找到滿足某種性質的s的子集時,相應的解空間為子集樹,
通常存在2n個葉結點。0-1揹包的問題相應解空間即為子集樹。當問題是確定n個元素的滿足某種性質的序列時,相應的解空間樹為排列樹
通常有n!個葉結點。旅行售貨問題的解空間即為排列樹。
個人理解:
學習了回溯法後,個人感覺回溯法就是通過對解空間的遍歷,在解空間不斷更新答案,最後找到最優的結果。回溯法最主要的是三點,
一是構造問題的解空間,不同問題的解空間不同,同一個問題也可以構造不同的解空間,最適合的解空間是便通過於搜尋找到答案的一種。
二是搜尋策略,回溯法用的是深度優先搜尋策略,在回溯是需要注意對一些變數的處理操作。三是剪枝,剪枝是回溯法的精髓所在,通過剪
枝去掉大量不必要的搜尋可以大幅的提高演算法的效率,因此回溯法構造合理的剪枝方式可以決定演算法的優劣,十分重要。
例題說明:
7-1 子集和問題
問題描述:存在一個正整數集合S={x1,x2,…,xn},c是一個整數,判讀S是否存在一個子集s1,子集的和等於c
//輸入 5 10 //5個數字的集合S c為10 2 2 6 5 4 //輸出 2 2 6
解空間:
子集和問題的解空間為子集樹結構。其中子集樹的每一層表示是否選擇該數值。
約束函式:
當遞迴的層數大於等於n時,表示當前層次已經大於元素的個數,接下來的為無用搜索,直接剪去該結點的搜尋即可
當搜尋到當前結點後所得的值大於題目中的c,則表示接下來的搜尋不可能找到等於c的答案,直接剪去以該節為根的子樹
的搜尋即可。
if(i>=n||c<ans) //ans為遍歷到該節點時,所選擇的元素的和 return; if(ans+a[i]<=c) //第i個元素是否加入子集 if(ans<=c)
結對程式設計以及學習心得:
在本章學習中,瞭解了回溯法的基本用法,對於大部分的題目中,都可以利用回溯法來解出他的答案,主要
難點是構造解空間和搜尋時的剪枝的方法,剪枝的方法會影響到演算法的最終效率,需要多加考慮。在本次結對程式設計
中,還是存在一些小問題,對同一題的不同想法等,在不斷的交流中加深了對回溯法的理解,對學習理解有一定的幫助
促進效果。