1. 定義
回溯法是一種優選搜索法,又稱爲試探法,按優選條件向前搜索,以達到目標。但當搜索到某一步時,發現原先選擇並不憂或達不到目標,就退回一步重新選擇,這種走不通就退回再走的技術爲回溯法,而滿足回溯條件的某個狀態的點稱爲回溯點。
2. 解題步驟
(1)針對所給問題,確定問題的解空間:
首先應明確定義問題的解空間,問題的解空間應至少包含問題的一個(最優)解。
(2)確定結點的擴展搜索規則
(3)以深度優先方式搜索解空間,並在搜索過程中用剪枝函數避免無效搜索。
3. 算法框架
- 遞歸算法框架
Input : X = {X1, X2, ..., Xn}
Output: T = (t1, t2, ..., tn)
back-track-rec(int now)
{
for x0 in X
{
T[now] = x0
if (T[0...now] is valid) //如果有效則進行,否則嘗試下一個x0
{
if (now == n) //是完整解
{
print(T[1...now]);
return;
}
else if (now < n) //是部分解
{
back-track-rec(now+1);
}
}
}
}
- 非遞歸算法
Input : X = {X1, X2, ..., Xn}
Output: T = (t1, t2, ..., tn)
back-track-itor()
{
int top = 0;
while (top >= 0)
{
while T[top] 沒有取盡 X 中的元素
{
T[top] = next(X)
if (check(top) is valid)
{
if (top < N) //部分解
print();
else
top++;
}
}
reset(T[top])
top--
}
}
回溯法的大致思想:對於 T[i], 嘗試每一個 x0, 只要 T[i]=x0 有效,則對 T[i+1] 進行嘗試,否則回退到 T[i-1]
4. 例子——全排列
a=[1,2,3]
n=len(a)
res=[]
def permutation(a,solution):
#注意,這裏要用global修飾res,才能更新結果
global res
if len(a)==0:
res.append(solution)
return
for i in range(len(a)):
newsolution=solution+[a[i]]
new_a=a[:i]+a[i+1:]
permutation(new_a,newsolution)
permutation(a,[])
print(res)
輸出:
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
5.參考鏈接
https://www.cnblogs.com/sinkinben/p/11481811.html
https://www.cnblogs.com/steven_oyj/archive/2010/05/22/1741376.html
https://www.cnblogs.com/xiximayou/p/11695640.html