Recursively solve the eight queens problem

Important rules for recursion

  1. When a method is executed, a new protected independent space (stack space) is created
  2. The local variables of the method are independent and will not affect each other, such as n variables
  3. If the method uses a reference type variable (such as an array), the data of the reference type will be shared.
  4. The recursion must approach the condition of exiting the recursion, otherwise it will be infinite recursion, a StackOverflowError will appear, and the turtle will be dead :)
  5. When a method is executed, or when it encounters a return, it will return. Whoever calls it will return the result to whoever is called. At the same time, when the method is executed or returns, the method will also be executed.

Introduction to the
Eight Queens Problem The Eight Queens problem is an old and well-known problem, a typical case of backtracking algorithms. The problem was raised by the chess player Max Bethel in 1848: place eight queens on an 8×8 chess board so that they cannot attack each other, that is: no two queens can be in the same row , In the same column or on the same diagonal line, ask how many ways there are.

Analysis of the Algorithms of the Eight Queens Problem

  1. Put the first queen first in the first row and first column
  2. Put the second queen in the first column of the second row, and then judge whether it is OK. If it is not OK, continue to put it in the second and third columns, put all the columns in order, and find a suitable one
  3. Continue to the third queen, still the first and second columns... Until the eighth queen can 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 is rolled back to the previous stack, the backtracking will begin, that is, all correct solutions that are placed in the first column of the first queen will be obtained.
  5. Then go back to the first queen to put the second column, and then continue to loop through the steps 1, 2, 3, and 4

Note : In theory, a two-dimensional array should be created to represent the chessboard, but in fact, a one-dimensional array can be used to solve the problem through an algorithm. arr[8] = {0, 4, 7, 5, 2, 6, 1 , 3} //corresponding to arr subscript indicates the row, that is, the queen, arr[i] = val, val indicates the i+1 queen, placed in the val+1 column of the i+1 row

Code:

public class Queen8 {
    
    

    //定义一个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) {
    
    
        //测试一把 , 8皇后是否正确
        Queen8 queue8 = new  Queen8();
        queue8.check(0);
        System.out.printf("一共有%d解法", 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]  表示判断 第n个皇后是否和前面的n-1个皇后在同一列
            //2. Math.abs(n-i) == Math.abs(array[n] - array[i]) 表示判断第n个皇后是否和第i皇后是否在同一斜线
            // n = 1  放置第 2列 1 n = 1 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 = 0; i < array.length; i++) {
    
    
            System.out.print(array[i] + " ");
        }
        System.out.println();
    }
}

operation result:

Insert picture description here

Guess you like

Origin blog.csdn.net/qq_41784749/article/details/113114429