回溯法

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万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章