Java recursion: the eight queens problem (backtracking algorithm)

The eight queens problem is an old and well-known problem, a typical case of backtracking algorithms. The problem was proposed 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, the same column, or the same diagonal, how many ways are there to ask (92)?

Thinking analysis

  1. Put the first queen in the first row and first column
  2. The second queen is placed in the first column of the second row, and then judge whether it is OK [that is, whether it is conflicted], if it is not OK, continue to put it in the second and third columns of the row, put all the columns in order, and find A suitable location, perform the third step
  3. Continue to the third queen, the first column, the second column... Until the eighth queen can be placed in a non-conflicting position, that is, it is counted as finding a correct solution.
  4. When a correct solution is obtained, when the stack is rolled back to the previous stack, it will start to backtrack and traverse the result set, that is, at this time, all correct solutions of the first queen in the first column will be obtained.
  5. Then put the first queen in the second column, perform the above steps, find all the solutions in the second column, and finally find all the solutions.

Description:

Theoretically, a two-dimensional array should be created to represent the chessboard, but in practice, a one-dimensional array can be used to solve the problem through algorithms.
arr[8] = {0, 4, 7, 5, 2, 6, 1, 3} // Corresponding to the arr subscript indicates the number of rows, that is, the number of queens, and the left indicates a set of solutions, that is, the first queen In the first column, the second queen is in the fifth column...
arr[i] = val // val means the i+1th element

Code

package com.beyond.recursion;

public class Queen8 {
    
    
	// 定义一个 max 表示共有多少个皇后
	int max = 8;
	int success = 0; // 统计多少种摆法
	int count = 0; // 统计多少次check中的for循环
	// 定义数组array, 保存皇后放置位置的结果, 比如 arr[8] = {0, 4, 7, 5, 2, 6, 1, 3}
	int[] array = new int[max];

	// 查看当我们放置第 n个皇后, 就去检查该皇后是否和前面已经摆放的(n-1)个皇后冲突
	/**
	 * @param n 表示换的第n个皇后
	 * @return
	 */
	private boolean judge(int n) {
    
    
		for (int x = 0; x < n; x++) {
    
    
			// array[x] == array[n] 表示任意的两个皇后不能为 同一列
			// Math.abs(n-x) == Math.abs(array[x]-array[n]) 用斜率不能为1 或者-1, 即用来表示任意两个皇后不再斜线上
			if (array[x] == array[n] || Math.abs(n - x) == Math.abs(array[x] - array[n])) {
    
    
				return false;
			}
		}
		return true;
	}

	// 编写一个方法, 放置第n个皇后
	private void check(int n) {
    
    
		if (n == max) {
    
     // n = 8, 相当于在放第九个皇后, 前八个皇后已经放好了
			print();
			return;
		}

		// 依次换入皇后, 并且判断是否冲突
		for (int x = 0; x < max; x++) {
    
    
			// 先把当前这个皇后n, 放到该行的第一列
			array[n] = x;
			// 判断放到第x列时候是否冲突
			if (judge(n)) {
    
     // 成立这不冲突
				// 接着放第 n+1 个皇后, 开始递归
				check(n + 1);
			}
			// 冲突则会继续循环, 将该皇后移动到本行的下一列

			count++;
		}

	}

	// 写一个方法, 可以将皇后摆放的位置输出
	private void print() {
    
    
		for (int x = 0; x < array.length; x++) {
    
    
			System.out.print(array[x] + 1 + " "); // array[x]+1 直接表示位置
		}
		success++;
		System.out.println();
	}

	public static void main(String[] args) {
    
    
		Queen8 queen8 = new Queen8();
		queen8.check(0);
		System.out.println("========================");
		System.out.println("一共循环了" + queen8.count + "次");
		System.out.println("一共有" + queen8.success + "种");
	}

}

Insert picture description here

Guess you like

Origin blog.csdn.net/Beyond_Nothing/article/details/113009257