回溯算法原理总结

回溯算法理论总结

回溯法是一种类似枚举的搜索尝试过程,既然是枚举,那么就会遍历解空间树中的所有解(或者是“路径”),搜索的过程按照DFS原则,而尝试就意味着,在遍历的过程中,有可能到达某一个结点后,发现不能够满足约束条件,在这次尝试中,这条“路”是不优的,将走不通,即无法找到所求的解,那么就会回退到上一步的状态,重新作出选择。如果即满足约束条件,但是依然没有获得有效的解,那么我们就需要在此基础上做下一步选择,即将当前结点当做一个新的根结点。所以经常会使用递归的方法。如果一步步下来的选择结果正好满足我们所求的问题,那么就是一个有效的解。

 

回溯法思想:在包含问题所有解的解空间树中,按照深度优先搜索的策略,从根结点出发深度搜索解空间树。当搜索到某一结点时,要先判断该结点是否包含问题的解,如果包含,就从该结点出发继续探索下去,如果该结点不包含问题的解,则逐层向其祖先结点回溯。(其实回溯法就是对隐式图的深度优先搜索算法)。若用回溯法求问题的所有解时,要回溯到根,且根结点的所有可行的子树都要已被检索一遍才结束。而若使用回溯法求任一个解时,只要搜索到问题的一个解就可以结束。

若用回溯法求问题的所有解时,要回溯到根,且根结点的所有可行的子树都要已被搜索遍才结束。

若使用回溯法求任一个解时,只要搜索到问题的一个解就可以结束。

 

回溯法中的三个概念:

(1)约束函数:约束函数是根据题意定出的。通过描述合法解的一般特征用于去除不合法的解(即使这个解并不是完整的解),从而避免继续搜索出这个不合法解的剩余部分,起到了剪值函数的作用。因此,约束函数是对于解空间树上的任何节点都有效、等价的。

(2)状态空间树:状态空间树是一个对所有解的图形描述。

(3)扩展节点:当前正求出它的子节点的节点,在DFS中,只允许有一个扩展节点。

        活节点:通过与约束函数对照,节点本身和其父节点均满足约束函数要求的节点。

        死节点: 与活节点正好相反,死节点是在与约束函数对照中,不满足约束函数的节点。那么就不需要求该节点的子节点情况了。

 

回溯法的步骤:

(1)明确问题的解空间树内容,比如,在求组合问题时,最后有效解中元素是否可重复的,元素个数是否是固定的等。且保证问题的解空间中应至少包含问题的一个解。

(2)确定结点的扩展搜索规则,在回溯法中,就是深度优先遍历规则。扩展节点就是当前正在求出它的子节点的节点,在DFS中,只允许有一个扩展节点。

(3)构造约束条件。作为剪枝函数,避免无效搜索。

 

DFS实现回溯的具体流程如下:

(1)设置初始化的方案(给变量赋初值,读入已知数据等);

(2)选择所到深度层(k)中其中的一个节点进行试探,如果k层的节点已经全部都试探完毕,则进入(7);

(3)如果试探不成功(不满足约束条件),则转入(2);

(4)如果试探成功,则进入下一个深度层进行试探。

(5)如果正确解还没找到,则进入(2);

(6)如果找到了正解,如果问题只求其中的一个解,那么可以退出程序了,如果是求一组解,那么将该种解存储;

(7)退回上一步的状态(深度为k-1时,变量的状态),如果没有退到头,则进入(2);

(8)已退到头则结束或打印无解。

 

在使用回溯法解决实际问题时,往往会和递归算法结合,更容易解决问题,但是也可以使用非递归的方法实现,这就需要具体情况进行分析了。

 

相关题目的链接

(1)机器人的运动轨迹

(2)矩阵中的路径

 

参考资源

http://www.cnblogs.com/steven_oyj/archive/2010/05/22/1741376.html

http://www.cnblogs.com/wuyuegb2312/p/3273337.html#intro

http://www.cnblogs.com/jiangchen/p/5393849.html

http://blog.csdn.net/yanerhao/article/details/68561290

http://www.cnblogs.com/jiangchen/p/5931754.html

https://www.cnblogs.com/jiangchen/p/5930049.html

    原文作者:回溯法
    原文地址: https://blog.csdn.net/XINGKONG_04/article/details/79463690
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞