回溯法

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

發佈了73 篇原創文章 · 獲贊 25 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章