回溯算法之八皇后问题实现Java
1.回溯算法的简单介绍
回溯算法也叫试探法,它是一种系统地搜索问题的解的方法。
回溯法以深度优先的方式来解决问题,每次以试探的思想去尝试,如果走不通,就回退重新作出选择去尝试。
2.典型应用场景–八皇后问题
在国际象棋中,皇后是最强大的一枚棋子,可以吃掉与其在同一行、列和斜线的敌方棋子。
也就是说,我们需要在8*8的国际象棋棋盘上摆放8个皇后,使他们既不能同一行,也不能同一列,也不能同一斜线上。
- 解决思路
我们知道想要正确的摆放的话,那么8个皇后必须要在各不同的列,(当然也可以说不同的行),那我们可以先试着把第一个皇后放在第一行的某个位置,然后去放第二个,然后第三个,一直到第八个。当然我们人为摆放的话,可以放一步看一步,看看是否冲突,但是程序的话就必须要遍历,有一个判断的冲突的方法,也就是我下面代码的judge()方法,如果没有冲突,就摆放下一个
代码里的注释都也得很清楚,不理解的可以留言
public class Queen8 {
int max = 8;
static int count;
int[] a = new int[max]; //用于表示八皇后摆放的结果a[i]=m 即表示i+1个皇后摆放于m+1列
public static void main(String[] args) {
Queen8 queen8 = new Queen8();
queen8.set(0);
System.out.println(count);
}
//用于打印最后的结果
public void print(){
count++;
System.out.println(Arrays.toString(a));
}
/**
* 判断放置第n+1个皇后时是否有冲突
* a[i] == a[n]时表示在同一列
* Math.abs(n-i) == Math.abs(a[n]-a[i])表示同一斜线
*/
public boolean judge(int n){
for (int i = 0; i < n; i++) {
if (a[i] == a[n] || Math.abs(n-i) == Math.abs(a[n]-a[i])){
return false;
}
}
return true;
}
/**
* 放置第n+1个皇后,会用到递归
*/
public void set(int n){
if (n == max){ //当n=8的时候,实际上已经放到第9个皇后了,所以这就是递归的出口
print();
return;
}
for (int i = 0; i < max; i++) {
a[n] = i; //把第n+1个皇后放在了第i+1列,就要判断是否有冲突,这里先是第1列
if (judge(n)){ //如果没有冲突的话,继续放下一个,有冲突的话,程序就会回到循环,将n+1个皇后放在第二列尝试
set(n+1);
}
}
}
}
可以看到,最后一共92种解法。