回溯法
算法思想
回溯法的算法思想就是通过有组织的穷尽搜索,在搜索的过程中通过各种约束条件(剪枝函数),进行剪枝,避免对所有状态的搜索,从而提高算法的效率。
回溯法求解问题的所有解时,要回溯到根节点并且根节点的所有子树都被搜索遍才结束。回溯法求问题的一个解时,只需要搜索到问题的一个解就可以结束。
运用回溯法在问题的解空间树中,按深度优先策略,从根节点出发搜索解空间树,算法搜索至解空间树任一结点时,先判断该结点是否包含问题的解,如果肯定不包含,则跳过,逐层向其祖先结点回溯,否则继续按深度优先策略搜索。
适用
回溯法适用于求解组合数众多,且有大量潜在的解的问题。
8皇后、N皇后问题
八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
解决这个问题的思路就是将每一个皇后逐行放置,第一个皇后放在第一行的一个位置,第二个皇后放在第二行的一个位置,等等,如果出现到某一行时,无论将皇后放在这一行的哪个位置都不满足,这个时候就要进行回溯,回溯到上一行,将这行的皇后重新找一个可行的位置,如果再不行,继续回溯。
代码如下,注释应该比较清晰:
import java.util.LinkedList;
/**
* Created on 2020/1/4 0004
* BY Jianlong
* 8皇后问题
*/
public class EightQueen {
// 皇后的个数
private static final int NUM = 8;
// 摆放的种类的计数
private static int count;
// 静态内部类
// 在初始化时会进行加载,对于经常使用的类,应该使用static关键字
static class Location{
// 代表行
private int x;
// 代表列
private int y;