1、對回溯算法的理解
回溯法(探索與回溯法)是一種選優搜索法,又稱為試探法,按選優條件向前搜索,以達到目標。但當探索到某一步時,發現原先選擇並不優或達不到目標,就退回一步重新選擇,這種走不通就退回再走的技術為回溯法,而滿足回溯條件的某個狀態的點稱為"回溯點"。
(1)回溯法解題時通常包含3個步驟:
①針對所給問題,定義問題的解空間;
② 確定易於搜索的解空間結構;
③以深度優先方式搜索解空間,並在搜索過程中用剪枝函數避免無效搜索。
(2)回溯法的算法框架
①解空間:問題的解空間至少包含問題的一個(最優)解。其表示形式一般是解空間樹:子集樹和排列樹
②遞歸回溯:
1 void Backtrack(int t) 2 { 3 if(t>n) Output(x); 4 else { 5 for(int i=f(n,t);i<=g(n,t);i++) { 6 x[t]=h(i); 7 if(Constraint(t)&&Bound(t)) Backtrack(t+1); 8 } 9 } 10 }
③迭代回溯:
1 void IterativeBacktrack(void) 2 { 3 int t=1; 4 while(t>0) { 5 if(f(n,t)<=g(n,t)) { 6 for(int i=f(n,t);i<=g(n,t);i++) { 7 x[t]=h(i); 8 if(Constraint(t)&&Bound(t)) { 9 if(Solution(t)) Output(x); 10 else t++; 11 } 12 } 13 } 14 else t--; 15 } 16 }
2、例題:子集和問題
(1)子集和問題
設集合S={x1,x2,…,xn}是一個正整數集合,c是一個正整數,子集和問題判定是否存在S的一個子集S1,使S1中的元素之和為c。試設計一個解子集和問題的回溯法。
輸入格式:輸入數據第1行有2個正整數n和c,n表示S的大小,c是子集和的目標值。接下來的1行中,有n個正整數,表示集合S中的元素。
輸出格式:輸出子集和問題的解,以空格分隔,最后一個輸出的后面有空格。當問題無解時,輸出“No Solution!”。
輸入樣例:5 10
2 2 6 5 4
輸出樣例:2 2 6
(2)解空間
本題的解空間為:{x1,x2,x3,x4,···,xn},其中xi表示是否加上第i個數
(3)約束函數
本題的約束方式有兩部分,①isC + num[i] <= c,通過判斷當前子集和是否超出題目要求的子集和來剪枝
②isC+total >= c,與第一部分類似
(4)具體代碼
1 #include <iostream> 2 using namespace std; 3 #define N 1000 4 int n,c,total=0; // total表示所有整數之和 5 int isSelect[N]={0}; // 表示整數n是否被選擇,1表示選擇 6 int num[N]; // 表示整數集 7 int isC=0; // 表示當前子集和 8 9 bool sum(int i) 10 { 11 if(isC == c) return true; // 當子集和符合條件時返回 12 if(i > n) return false; 13 total-=num[i]; 14 if(isC + num[i] <= c) { 15 isSelect[i]=1; 16 isC+=num[i]; 17 if(sum(i+1)) return true; 18 isC-=num[i]; // 回溯法 19 } 20 if(isC+total >= c) { 21 isSelect[i]=0; // 回溯法 22 if(sum(i+1)) return true; 23 } 24 total += num[i]; // 回溯法 25 return false; 26 } 27 28 int main() 29 { 30 cin>>n>>c; 31 for(int i=1;i<=n;i++) { 32 cin>>num[i]; 33 total+=num[i]; 34 } 35 if(!sum(1)) cout<<"No Solution!"; // 無解時 36 else { 37 for(int i=1;i<=n;i++) { 38 if(isSelect[i]) cout<<num[i]<<" "; 39 } 40 } 41 return 0; 42 }
3、在本章學習過程中遇到的問題及結對編程的情況
對於回溯法的概念,結合解空間樹,理解起來不是很難,但是在代碼實踐時,有時候會出現不是很明白為什么要怎么寫代碼的情況,結對小伙伴也不是很明白,總體上還可以,但是還需要多實踐多理解。
參考資料:https://baike.so.com/doc/6735197-6949574.html