回溯法
有许多问题,当需要找出它的解集
或者要求回答什么解是满足某些约束条件的最佳解
时,往往要使用回溯法。
回溯法的基本做法是搜索
,或是一种组织得井井有条的,能避免不必要搜索的穷举式搜索法。这种方法适用于解一些组合数相当大的问题。
思想方法
回溯法在问题的解空间树中,按深度优先
策略,从根结点出发搜索解空间树。算法搜索至解空间树的任意一点时,先判断该结点是否包含问题的解。如果肯定不包含,则跳过
对该结点为根的子树的搜索,逐层
向其祖先结点回溯
;否则,进入该子树,继续按深度优先策略搜索。
剪枝函数:
用约束函数在扩展结点处剪去不满足约束的子树;
用限界函数剪去得不到最优解的子树。
特点
用回溯法解题的一个显著特征是在搜索过程中动态产生问题的解空间。在任何时刻,算法只保存从根结点到当前扩展结点的路径。如果解空间树中从根结点到叶结点的最长路径的长度为h(n),则回溯法所需的计算空间通常为O(h(n))。而显式地存储整个解空间则需要O(2h(n))或O(h(n)!)内存空间。
N皇后问题
问题描述
N皇后问题要求在一个NXN的棋盘上放上N个皇后,使得每一个皇后既攻击不到另外N-1个皇后,也不被另外N-1个皇后所攻击。
问题分析
按照国际象棋的规则,一个皇后可以攻击与之处在同一行或同一列或同一斜线上的其他任何棋子。因此,N皇后问题等于要求N个皇后中的任意两个不能被放在同一行或同一列或同一斜线上。
我们给N×N棋盘的行和列分别从左到右和从上到下编号为1,2,3…N,同时也给N个皇后也分别编号为1,2,3…N。由于要求不同的皇后不能放在同一行,不失广般性,可设皇后i只放在第i行。这样,N后问题的解可用N元组(x1,x2,x3…xN)来表示。其中xi表示皇后i所处的列的列号。
那么约束条件或者说是限界函数便为:
① xi≠xj(皇后i和j不在同一列上);
② xi−i≠xj−j(皇后i和j不在斜率为-l的同一条斜线上);
③ xi+i≠xj+j(皇后i和j不在斜率为+l的同一条斜线上);
④ 其中i、j=1,2,…,k,且i<>j。
代码及详细注释