Java solves the eight queens problem

Keywords: Java Algorithm data structure

Video link: Han Ping's Java data structure and algorithm -- 8 Queen Problem

Eight emperors and empress N

VIII. Introduction to questions:

The eight queens problem is an ancient and famous problem and a typical case of backtracking algorithm. The problem was put forward by international chess player Max Bethel in 1848: in August × Eight queens are placed on the 8-grid chess so that they can't attack each other, that is, any two Queens can't be in the same row, column or slash. Ask how many kinds of pendulum methods there are (92).

Analysis of algorithm ideas:

  • The first queen puts the first row and the first column first
  • The second queen is placed 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 column and the third column, and put all the columns in turn to find a suitable one
  • Continue the third queen, or the first and second columns... Until the eighth queen can also be placed in a non conflict position, it can be regarded as finding a correct solution
  • When a correct solution is obtained, when the stack returns to the previous stack, it will start backtracking, that is, the first queen will get all the correct solutions put in the first column
  • Then go back and continue to put the first queen in the second column, and then continue to cycle through steps 1, 2, 3 and 4
  • Sketch Map:

  • explain:

Theoretically, we should create a two-dimensional array to represent the chessboard, but in fact, we can solve the problem by using a one-dimensional array through the algorithm. Arr [8] = {0, 4, 7, 5, 2, 6, 1, 3} / / the corresponding arr subscript indicates the row, that is, the queen. arr[i] = val, val indicates the i+1 Queen, which is placed in column val+1 of row i+1.

Teacher Han's code:

public class Queue8 {
	public static void main(String[] args) {
		// Test whether the 8 Queen is correct
		Queue8 queue8 = new Queue8();
		queue8.check(0);
		System.out.printf("Altogether%d solution", count);
		System.out.println();
		System.out.printf("Total number of conflicts judged%d second", judgeCount); // 1.5w
	}
	
	/**
	 * Note: theoretically, a two-dimensional array should be created to represent the chessboard, but in fact, the problem can be solved by using a one-dimensional array through the algorithm 
	 * arr[8] = {0 , 4, 7, 5, 2, 6, 1, 3}
	 * The corresponding arr subscript indicates the row, that is, the queen, arr [i] = Val, Val indicates the I + 1st queen, which is placed in column val+1 of row i+1
	 */
	// Define a max to indicate how many queens there are
	int max = 8;// Eight queens are placed on an 8 * 8 chessboard
	// Define the array array to save the results of the Queen's placement position, such as arr = {0, 4, 7, 5, 2, 6, 1, 3}
	int[] array = new int[max];
	static int count = 0;// How many records are there and how they are placed
	static int judgeCount = 0;// Record how many times you judged

	/**
	 * Write a method to place the nth queen. Pay special attention to: check means that there is for (int i = 0; I < max; I + +) in the check every time you recurse
	 * So there will be backtracking
	 * 
	 * @param n
	 */
	private void check(int n) {
		if (n == max) {// n = 8: n+1=9 queens, indicating that the first 8 queens have been placed
			print(); // Output the pendulum method for this case
			return;// end
		}

		// Put the queen in turn and judge whether there is conflict
		for (int i = 0; i < max; i++) {
			// First, put the current queen n in column (i+1) of the row
			array[n] = i;
			// Judge whether there is a conflict when placing the nth queen to column i
			if (judge(n)) { // No conflict
				// If there is no conflict, then put n+1 queens, that is, start recursion
				check(n + 1); //
			}
			// If there is a conflict, continue to execute array[n] = i; That is, the nth queen is placed in a position where the line has to be moved back
		}
	}

	/**
	 * Judge that when we place the nth queen, we will detect whether the queen conflicts with the queen already placed in front
	 * 
	 * @param n Represents the nth queen
	 * @return
	 */
	private boolean judge(int n) {
		judgeCount++;
		for (int i = 0; i < n; i++) {
			// explain
			// 1. array[i] == array[n] means to judge whether the nth queen is in the same column as the previous n-1 queens
			// 2. Math.abs(n-i) == Math.abs(array[n] - array[i]) indicates whether the nth queen and the ith queen are in the same slash
			// N = 1 place column 2: 1 < --- > n = 1 array [1] = 1
			// Math.abs(1-0) == 1 similarly, Math.abs(array[n] - array[i]) = Math.abs(1-0) = 1
			// 3. It is not necessary to judge whether it is on the same line, because n is increasing every time
			if (array[i] == array[n] || Math.abs(n - i) == Math.abs(array[n] - array[i])) {
				return false;
			}
		}
		return true;
	}

	// Write a method to output the position of the queen
	private void print() {
		count++;
		for (int i = 0; i < array.length; i++) {
			System.out.print(array[i] + " ");
		}
		System.out.println();
	}
}

Force buckle queen related topics

public class Test36 {
	public static void main(String[] args) {
		// Test max=4
		System.out.println(new Test36().solveNQueens(4));
	}

	public List<List<String>> solveNQueens(int max) {
		/**
		 * Note: theoretically, a two-dimensional array should be created to represent the chessboard, but in fact, the problem can be solved by using a one-dimensional array through the algorithm 
		 * arr[8] = {0 , 4, 7, 5, 2, 6, 1, 3}
		 * The corresponding arr subscript indicates the row, that is, the queen, arr [i] = Val, Val indicates the I + 1st queen, which is placed in column val+1 of row i+1
		 */
		// Define a max to indicate how many queens there are
		int[] array = new int[max];// Max queens are placed on the max*max chessboard
		
		// Returned result set
		// eg: when there are 4 queens, output - > [. Q.... Q, Q....,.. Q.], [.. Q., Q..,... Q,. Q..]]
		List<List<String>> res = new ArrayList<>();
		// Place the 0 (i.e. the first queen) and max queens at most. The two-dimensional chessboard represented by the one-dimensional array array needs to return the result set
		check(0, max, array, res);
		return res;
	}

	/**
	 * Backtracking method: place the nth queen
	 * @param n Place the n+1 Queen (n starts from 0)
	 * @param max Place max queens
	 * @param array Two dimensional chessboard represented by one-dimensional array array
	 * @param res Result set to return
	 */
	private void check(int n, int max, int[] array, List<List<String>> res) {
		if (n == max) { // n+1 queens have been placed, indicating that the first n queens have been placed
			List<String> list = print(array);// Store the pendulum method of this case in list < string >
			res.add(list);// Store the pendulum method in this case into the result set list < list < string > >
			return;// end
		}

		// Put the queen in turn and judge whether there is conflict
		for (int i = 0; i < max; i++) {
			// First, put the current queen n in column (i+1) of the row
			array[n] = i;// The first queen places the nth column in turn after all conditions in the first row and the first column occur
			if (judge(n, array)) {// Judge whether there is a conflict when placing the nth queen to column i
				// If there is no conflict, then put n+1 queens, that is, start recursion
				check(n + 1, max, array, res);
			}
			// If there is a conflict, continue to execute array[n] = i; That is, the nth queen is placed in a position where the line has to be moved back
		}
	}

	/**
	 * Judge whether there is conflict with the previous queen when placing the nth emperor
	 * @param n
	 * @param array
	 * @return
	 */
	private boolean judge(int n, int[] array) {
		for (int i = 0; i < n; i++) {
			// explain
			// 1. array[i] == array[n] means to judge whether the nth queen is in the same column as the previous n-1 queens
			// 2. Math.abs(n-i) == Math.abs(array[n] - array[i]) indicates whether the nth queen and the ith queen are in the same slash
			// N = 1 place column 2: 1 < --- > n = 1 array [1] = 1
			// Math.abs(1-0) == 1 similarly, Math.abs(array[n] - array[i]) = Math.abs(1-0) = 1
			// 3. It is not necessary to judge whether it is on the same line, because n is increasing every time
			if (array[i] == array[n] || Math.abs(n - i) == Math.abs(array[n] - array[i])) {
				return false;
			}
		}
		return true;
	}

	/**
	 * Save the placement method in a certain case into list < string > and return
	 * @param array
	 * @return
	 */
	private List<String> print(int[] array) {
		List<String> list = new ArrayList<String>();
		for (int i = 0; i < array.length; i++) {// array = [1 3 0 2]
			String str = "";
			for (int j = 0; j < array.length; j++) {
				if (j == array[i]) {
					str = str + "Q";
				} else {
					str = str + ".";
				}
			}
			list.add(str);
		}
		return list;
	}
}

Posted by raffael3d on Sun, 10 Oct 2021 19:56:38 -0700