以深度優先方式系統搜索問題解的算法稱為回溯法。在回溯法中,解空間樹主要分為了四種子集樹、排列樹、n叉樹和不確定樹。
在《算法設計與分析課本》中介紹了11個回溯法的問題樣例,這里根據解空間樹的類型做一個分類。
子集樹
裝載問題
0-1背包問題
算法模板:
void backtrack(int t) { if(搜索到葉子結點) { return; } for(i=0; i<=1; i++) //01二叉樹 { if(滿足約束函數和限界函數)//剪枝 { backtrack(t+1); } } }
排列樹
旅行售貨員問題
圓排列問題
電路板排列問題
算法模板:
void backtrack(int t) { if(搜索到葉子結點) { return; } for(i=0; i<=n; i++) { if(滿足約束函數和限界函數)//剪枝 { swap(x[t],x[i]); backtrack(t+1); swap(x[t],x[i]); } } }
n叉樹
圖的m着色問題
算法模板:
void backtrack(int t) { if(搜索到葉子結點) { return; } for(i=1; i<=n; i++) //n叉樹 { x[t]=i;//例如n后問題中,記錄第t后所在的第i列 if(滿足約束函數和限界函數)//剪枝 { backtrack(t+1); } } }
不確定樹
連續郵資問題
算法模板:
void backtrack(int t) { if(搜索到葉子結點) { return; } for(i=x; i<=y; i++) //x與y由相應的函數得到 { x[t]=i; if(滿足約束函數和限界函數)//剪枝 { backtrack(t+1); } } }