Chapter 6 Recursion (3) (Eight Queens Problem)

6.7 Recursion-Eight Queens Problem (Backtracking Algorithm)

6.7.1 Introduction to Eight Queens Problem

The eight queens problem is an old and well-known problem, and it is a typical case of backtracking algorithms. The problem was raised by international chess player Max Bethel in 1848: place eight queens on an 8×8 grid chess so that they cannot attack each other, that is, any two queens cannot be in the same row , on the same column or on the same oblique line, ask how many pendulum methods there are. 【92】

insert image description here

6.7.2 Analysis of the Eight Queens Problem Algorithm

1) The first queen is first placed in the first row and first column
2) The second queen is placed in the second row and first column, and then judge whether it is OK, if not OK, continue to be placed in the second column, third column, and so on Put all the columns and find a suitable one
3) Continue to the third queen, or the first column, the second column... until the 8th queen can also be placed in a non-conflicting position, it is considered to have found a correct solution
4 ) When a correct solution is obtained, when the stack rolls back to the previous stack, it will start backtracking, that is, the first queen, put all the correct solutions in the first column, all get. 5) Then go back and continue with the
first Put the queen in the second column, and then continue to execute steps 1, 2, 3, and
4 in a loop. [Schematic diagram]
insert image description here
Description: In theory, a two-dimensional array should be created to represent the chessboard, but in fact, a one-dimensional array can be used through an algorithm The problem can be solved. arr[8] = {0 , 4, 7, 5, 2, 6, 1, 3} //The subscript corresponding to arr indicates the row, that is, the queen, arr[i] = val , val represents the i+1th queen, placed in the val+1th column of the i+1th row

6.7.3 Eight Queens Problem Algorithm Code Implementation

package pers.th.d6_recursion;

/**
 * 八皇后问题
 */
public class Queue8 {
    
    
    //定义一个max表示共有多少个皇后
    int max = 8;
    //定义数组array,保存皇后放置位置的结果,比如 arr = {0, 4, 7, 5, 2, 6, 1, 3}
    int[] array = new int[max];
    static int count = 0;
    static int judgeCount = 0;

    public static void main(String[] args) {
    
    
        Queue8 queue8 = new Queue8();
        queue8.check(0);
        System.out.printf("一共有 %d 种解法:\n", count);
        System.out.printf("一共判断冲突的次数 %d 次", judgeCount);// 1.5w
    }

    //编写一个方法,放置第n个皇后
    //特别注意:check 是 每一次递归时,进入到 check中都有 for(int i = 0; i < max; i++),因此会有回溯
    private void check(int n) {
    
    
        if (n == max) {
    
    //n = 8 , 其实8个皇后就这样放好
            print();
            return;
        }

        //依次放入皇后,并判断是否冲突
        for (int i = 0; i < max; i++) {
    
    
            //先把当前这个皇后 n, 放到该行的第1列
            array[n] = i;
            //判断当放置第 n个皇后到 i列时,是否冲突
            if (judge(n)) {
    
    //不冲突
                //接着放 n + 1 个皇后,即开始递归
                check(n + 1);
            }
            //如果冲突,就继续执行 array[n] = i;即将第 n个皇后,放置在本行的 后移的一个位置
        }
    }

    //查看当我们放置第n个皇后,就去检查该皇后是否和前面已经摆放的皇后冲突

    /**
     * @param n 表示第n个皇后
     * @return
     */
    private boolean judge(int n) {
    
    
        judgeCount++;
        for (int i = 0; i < n; i++) {
    
    
            //说明
            //1.array[i] = array[n]
            //2.Math.abs(n - i) == Math.abs(array[n] - array[i])  表示判断第n个皇后是否和第i个皇后是否在同一斜线

            //n = 1 放置第 2列 l , n = l , array[1]= 1
            //Math.abs(1 - 0) == 1 , Math.abs(array[n] - array[i]) = Math.abs(1 - 0) = 1
            //3.判断是否在同一行,没有必要,n 每次都在递增
            if (array[i] == array[n] || Math.abs(n - i) == Math.abs(array[n] - array[i])) {
    
    
                return false;
            }
        }
        return true;
    }

    //将皇后摆放的位置输出
    private void print() {
    
    
        count++;
        for (int i : array) {
    
    
            System.out.print(i + " ");
        }
        System.out.println();
    }
}

0 4 7 5 2 6 1 3 
0 5 7 2 6 3 1 4 
0 6 3 5 7 1 4 2 
0 6 4 7 1 3 5 2 
1 3 5 7 2 0 6 4 
1 4 6 0 2 7 5 3 
1 4 6 3 0 7 5 2 
1 5 0 6 3 7 2 4 
1 5 7 2 0 3 6 4 
1 6 2 5 7 4 0 3 
1 6 4 7 0 3 5 2 
1 7 5 0 2 4 6 3 
2 0 6 4 7 1 3 5 
2 4 1 7 0 6 3 5 
2 4 1 7 5 3 6 0 
2 4 6 0 3 1 7 5 
2 4 7 3 0 6 1 5 
2 5 1 4 7 0 6 3 
2 5 1 6 0 3 7 4 
2 5 1 6 4 0 7 3 
2 5 3 0 7 4 6 1 
2 5 3 1 7 4 6 0 
2 5 7 0 3 6 4 1 
2 5 7 0 4 6 1 3 
2 5 7 1 3 0 6 4 
2 6 1 7 4 0 3 5 
2 6 1 7 5 3 0 4 
2 7 3 6 0 5 1 4 
3 0 4 7 1 6 2 5 
3 0 4 7 5 2 6 1 
3 1 4 7 5 0 2 6 
3 1 6 2 5 7 0 4 
3 1 6 2 5 7 4 0 
3 1 6 4 0 7 5 2 
3 1 7 4 6 0 2 5 
3 1 7 5 0 2 4 6 
3 5 0 4 1 7 2 6 
3 5 7 1 6 0 2 4 
3 5 7 2 0 6 4 1 
3 6 0 7 4 1 5 2 
3 6 2 7 1 4 0 5 
3 6 4 1 5 0 2 7 
3 6 4 2 0 5 7 1 
3 7 0 2 5 1 6 4 
3 7 0 4 6 1 5 2 
3 7 4 2 0 6 1 5 
4 0 3 5 7 1 6 2 
4 0 7 3 1 6 2 5 
4 0 7 5 2 6 1 3 
4 1 3 5 7 2 0 6 
4 1 3 6 2 7 5 0 
4 1 5 0 6 3 7 2 
4 1 7 0 3 6 2 5 
4 2 0 5 7 1 3 6 
4 2 0 6 1 7 5 3 
4 2 7 3 6 0 5 1 
4 6 0 2 7 5 3 1 
4 6 0 3 1 7 5 2 
4 6 1 3 7 0 2 5 
4 6 1 5 2 0 3 7 
4 6 1 5 2 0 7 3 
4 6 3 0 2 7 5 1 
4 7 3 0 2 5 1 6 
4 7 3 0 6 1 5 2 
5 0 4 1 7 2 6 3 
5 1 6 0 2 4 7 3 
5 1 6 0 3 7 4 2 
5 2 0 6 4 7 1 3 
5 2 0 7 3 1 6 4 
5 2 0 7 4 1 3 6 
5 2 4 6 0 3 1 7 
5 2 4 7 0 3 1 6 
5 2 6 1 3 7 0 4 
5 2 6 1 7 4 0 3 
5 2 6 3 0 7 1 4 
5 3 0 4 7 1 6 2 
5 3 1 7 4 6 0 2 
5 3 6 0 2 4 1 7 
5 3 6 0 7 1 4 2 
5 7 1 3 0 6 4 2 
6 0 2 7 5 3 1 4 
6 1 3 0 7 4 2 5 
6 1 5 2 0 3 7 4 
6 2 0 5 7 4 1 3 
6 2 7 1 4 0 5 3 
6 3 1 4 7 0 2 5 
6 3 1 7 5 0 2 4 
6 4 2 0 5 7 1 3 
7 1 3 0 6 4 2 5 
7 1 4 2 0 6 3 5 
7 2 0 5 1 4 6 3 
7 3 0 2 5 1 6 4 
一共有 92 种解法:
一共判断冲突的次数 15720

Guess you like

Origin blog.csdn.net/weixin_45828554/article/details/132437350