回溯法
基本思想:
構建問題的解空間樹,在其解空間樹中,從根節點出發,進行深度優先搜索。在搜索過程中,對解空間
樹的每個結點進行判斷,判斷該結點是否包含問題的解,若肯定不包含,則跳過對以該結點為根的子樹的
搜索,逐層向其祖先結點回溯。否則,則進入該子樹,繼續按深度優先策略搜索。
步驟:
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)
結對編程以及學習心得:
在本章學習中,了解了回溯法的基本用法,對於大部分的題目中,都可以利用回溯法來解出他的答案,主要
難點是構造解空間和搜索時的剪枝的方法,剪枝的方法會影響到算法的最終效率,需要多加考慮。在本次結對編程
中,還是存在一些小問題,對同一題的不同想法等,在不斷的交流中加深了對回溯法的理解,對學習理解有一定的幫助促進效果。