Recursion -- maze problem, eight queens problem

1.1 recursive application scenario

Look at a practical application scenario, maze problem (backtracking): the red part in the figure is the fence of maze. From the starting position of the ball, go to the position indicated by the arrow in the lower right corner, and find a way to go

1.2 the concept of recursion

To put it simply: recursion is that a method calls itself, passing in different variables each time it is called. Recursion helps programmers solve complex problems, and at the same time makes the code concise.

1.3 recursive call mechanism

To help you understand recursion, list some small cases, and review the recursion call mechanism:

The execution process of the above code is illustrated as follows: the program execution process constantly calls its own test() method, which opens up four stack spaces. In the top stack, n = 2, the test() method does not hold up. After calling the print statement, return to the stack of n=3 to execute the print statement, then return to the stack of n=4 to print the statement, finally return to the main function, and the statement execution ends.

1.4 what problems can recursion solve

What kind of problem is recursion used to solve

  1. Various mathematical problems, such as: 8 Queen's problem, Hanoi Tower, factorial problem, maze problem
  2. Recursion is also used in various algorithms, such as fast sorting, merge sorting, binary search, divide and conquer algorithm, etc
  3. Turn the problem solved by stack to recursion, the code is simpler

1.5 important rules for recursion

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 do not affect each other, such as n variables
  3. If a reference type variable (such as an array) is used in the method, the data of that reference type will be shared
  4. Recursion must approach to the condition of exit recursion, otherwise it is infinite recursion and stackoverflowerror appears.)
  5. When a method is executed or returns, it will return. Whoever obeys the call will return the result to whom. At the same time, when the method is executed or returned, the method will be executed

1.6 recursion maze problem


Some conventions on maze:

  1. Create a two-dimensional array to simulate the maze. If the two-dimensional array map[i][j] = 1, it means that the maze line i+1, column j+1, is not fenced
  2. When map[i][j] is 0, it means the point has not passed, when map[i][j] is 1, it means the wall, 2 means the path can go, 3 means the point has passed but can not go
    The code implementation is as follows:
public class MiGong {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		// First, create a two-dimensional array to simulate the maze
		// Map
		int[][] map = new int[8][7];
		// Use 1 for walls
		// All positions are 1
		for (int i = 0; i < 7; i++) {
			map[0][i] = 1;
			map[7][i] = 1;
		}
		// Set baffle, 1 means
		map[3][1] = 1;
		map[3][2] = 1;
		// All left and right positions are 1
		for (int i = 0; i < 8; i++) {
			map[i][0] = 1;
			map[i][6] = 1;
		}
		// Output map
		System.out.println("The map is:");
		for (int i = 0; i < 8; i++) {
			for (int j = 0; j < 7; j++) {
				System.out.print(map[i][j] + " ");
			}
			System.out.println();
		}
		// Using recursive backtracking to find the way for the ball
		setWay(map, 1, 1);
		System.out.println("The map of Xiaoqiu is:");
		for (int i = 0; i < 8; i++) {
			for (int j = 0; j < 7; j++) {
				System.out.print(map[i][j] + " ");
			}
			System.out.println();
		}
	}

	// Using recursive backtracking to find the way for the ball
	// Explain
	// 1.map represents map
	// 2.i,j indicates where to start from (1,1)
	// 3. If the ball can reach the map[6][5], it means the path is found
	// 4. Convention: when map[i][j] is 0, it means that the point has not passed. When map[i][j] is 1, it means that wall 2 means that the path can go. 3, it means that the point has passed, but cannot go
	// 5. When walking the maze, you need to determine a strategy (method): down - > right - > up - > left. If this point cannot be reached, go back
	/***
	 * 
	 * @param map
	 *            Map presentation
	 * @param i
	 *            Where to start (array row)
	 * @param j
	 *            Where to start (array columns)
	 * @return Returns true if the path is found, false otherwise
	 */
	public static boolean setWay(int[][] map, int i, int j) {

		if (map[6][5] == 2) {// Access has been found
			return true;
		} else {
			if (map[i][j] == 0) { // If the current road is not crossed
				// According to the strategy, go down - > right - > up - > left
				map[i][j] = 2; // Let's assume that the giant point is accessible
				if (setWay(map, i + 1, j)) {// Go down
					return true;
				} else if (setWay(map, i, j + 1)) {// Turn right
					return true;
				} else if (setWay(map, i - 1, j)) {// Go up
					return true;
				} else if (setWay(map, i, j - 1)) {
					return true;
				} else {
					// It means that this point can't be reached
					map[i][j] = 3;
					return false;
				}
			} else { // If map [i] [J]! = 0, it may be 1, 2, 3
				return false;
			}
		}
	}

}

The results are as follows:

1.7 recursion eight queens problem (backtracking algorithm)

1.7.1 introduction to the question of eight queens

The eight queens problem is an old and famous problem and a typical case of backtracking algorithm. In 1848, the chess player Max Bethel proposed that eight queens should be placed on the 8 × 8 grid chess, so that they can not attack each other, that is, any two Queens can not be on the same line, the same column or the same diagonal line, and asked how many kinds of placement there are.

1.7.2 algorithm analysis of the eight queens problem
  1. First queen, first row, first column
  2. The second queen put it in the second row, the first column, and then judge whether it is OK. If it is not OK, continue to put it in the second column, the third column, and then put all the columns in order to find a suitable one
  3. Continue with the third queen, or the first and second Until the eighth queen can be put in a non conflict position, it is to find a correct solution
  4. When we get a correct solution, when the stack goes back to the previous stack, we will start to backtrack, that is, the first queen, put all the correct solutions in the first column, and we will get all of them
  5. Then go back to the first queen and put the second column, and then continue to loop through the steps of 1,2,3,4

Code implementation:

  • Convention: define array and save the result of Queen placement. For example, arr = {0,4,7,5,2,6,1,3} corresponds to the row of the ARR subscript, that is, the queen, arr[i] = val, that is, the i+1 Queen, that is, the val+1 column of the i+1 row
public class Queue8 {

   // Define how many queens a max represents
   int max = 8;
   // Define array to save the result of Queen placement, such as arr = {0,4,7,5,2,6,1,3}
   // The corresponding arr subscript indicates the row, i.e. the queen. Arr [i] = Val, Val indicates the i+1 Queen, which is placed in the val+1 column of the i+1 row
   int[] array = new int[max];
   // How many middle solutions are there in statistics
   static int count = 0;
   // How many times have statistics judged
   static int judgeCount = 0;

   public static void main(String[] args) {
   	// TODO Auto-generated method stub
   	// test
   	Queue8 queue8 = new Queue8();
   	queue8.check(0);
   	System.out.printf("In total %d Solution method.", count);
   	System.out.printf("All in all%d Number of conflicts", judgeCount);
   }

   private void check(int n) {
   	if (n == max) {// The first eight queens are ready
   		print();
   		return;
   	}
   	// 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 the first column of the row
   		array[n] = i;
   		// Determine whether there is conflict when placing the nth queen i n column I
   		if (judge(n)) {
   			// Then put n+1 queens, i.e. start recursion
   			check(n + 1);
   		}
   		// If there is a conflict, continue array[n] = i; move the nth queen backward
   	}
   }

   /**
    * @param n
    *            The n th queen
    * @return
    */
   // Check if the queen conflicts with the queen already placed in front when we place the nth queen
   private boolean judge(int n) {
   	judgeCount++;
   	for (int i = 0; i < n; i++) {
   		// array[i] == array[n] indicates whether the nth queen is in the same column as the ith queen
   		// Math.abs(n - i) == Math.abs(array[n]) - array[i]
   		// Indicates whether the nth queen is on the same diagonal as the ith queen
   		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.printf(array[i] + " ");
   	}
   	System.out.println();
   }

}

The results are as follows:

Published 28 original articles, won praise 16, visited 1594
Private letter follow

Posted by Thethug on Sun, 16 Feb 2020 03:14:52 -0800