Simple solution to eight queens problem and n queens problem

insert image description here

Hard work is not to be mediocre~

The biggest reason for learning is to get rid of mediocrity. One day earlier, there will be more splendor in life; one day later, one day more mediocrity.

Table of contents

1. Problem description 

2. Problem solving ideas

1. Create a data structure:

2. Realization of constraints:

3. Result display:

4. Expand to the n queens problem:

 3. Code display

4. Thoughts on the n queen problem

Solve the problem that users cannot freely enter

Optimization of solution display and saving


1. Problem description 

     The Eight Queens Problem (English: Eight queens ), a problem raised by chess player Max Bethel in 1848, is a typical case of backtracking algorithms .

    The problem is stated as: place 8 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, column or slant, how many ways are there . Gauss believes that there are 76 schemes. In 1854, different authors published 40 different solutions in the Chess Magazine in Berlin. Later, someone used graph theory to solve 92 results . If rotated by ±90 degrees, ±180 degrees, and the pendulum method of diagonal symmetric transformation , there are 42 types in total. After the computer was invented, there are many computer languages ​​that can be programmed to solve this problem.

2. Problem solving ideas

1. Create a data structure:

     We can use a one-dimensional array to represent the position of the queen. The index of the array represents the column where the queen is located, and the value of the array represents the row where the queen is located.

     For example, for the eight queens problem, the array [0, 4, 7, 5, 2, 6, 1, 3] means that the queen in the first column is in row 0, the queen in the second column is in row 4, and so on.

     When expanding to the n queen problem, the length of the array is n, and each value ranges from 0 to n-1, indicating the row where the queen of each column is located.

2. Realization of constraints:

     In the backtracking algorithm, we need to implement constraints to ensure that the position of each queen is legal, that is, they will not attack each other.

   Same-row and same-column constraints are easy to implement, just check for the same value in the array.

   For the diagonal constraints, we can determine whether the two queens are on the same diagonal by judging whether the absolute values ​​of the row difference and the column difference are equal.

   In the code, a helper function can be used to check whether the constraint is satisfied at each location, and if so, continue recursively to the next column.

3. Result display:

    The results show that the matplotlib library can be used to draw a chessboard, where the position of the queen can be represented by different colors or symbols.

You can create a function that receives an array of queen positions as a parameter, then use matplotlib to draw a checkerboard, and draw the queens at the corresponding positions.

4. Expand to the n queens problem:

     To extend to the n-queens problem, we need to modify the code appropriately. The main modification is to modify the length of the array from 8 to n, indicating that the size of the chessboard is n×n.

     In the realization of constraint conditions, it is necessary to pay attention to the condition of judging the diagonal line, that is, judging whether the absolute values ​​of the row difference and column difference of two queens are equal.

     In the result display, it is necessary to dynamically adjust the size of the chessboard according to the size of n, and draw the corresponding queen position.

 3. Code display

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

def is_safe(board, row, col):
    # 检查当前位置是否安全(不受其他皇后的攻击)
    for i in range(col):
        if board[i] == row or board[i] == row - (col - i) or board[i] == row + (col - i):
            return False
    return True

def solve_n_queens_util(board, col, solutions):
    if col == len(board):
        # 所有列都已经尝试过,找到一个解决方案
        # 将解决方案添加到DataFrame中
        solutions.loc[len(solutions)] = board
        return

    for row in range(len(board)):
        if is_safe(board, row, col):
            # 在当前位置放置皇后
            board[col] = row

            # 递归尝试下一列
            solve_n_queens_util(board, col + 1, solutions)

def solve_n_queens():
    board = [-1] * 8
    solutions = pd.DataFrame(columns=['Q{}'.format(i+1) for i in range(8)])
    solve_n_queens_util(board, 0, solutions)
    return solutions

def draw_board(board, solution_number):
    plt.figure()
    plt.xlim(0, 8)
    plt.ylim(0, 8)

    # 绘制棋盘格子
    for i in range(8):
        for j in range(8):
            if (i + j) % 2 == 0:
                plt.fill([j, j, j + 1, j + 1], [i, i + 1, i + 1, i], 'white')
            else:
                plt.fill([j, j, j + 1, j + 1], [i, i + 1, i + 1, i], 'gray')

    # 绘制皇后位置
    for col, row in enumerate(board):
        plt.text(row + 0.5, col + 0.5, 'Q', fontsize=20, ha='center', va='center', color='black')

    plt.axis('off')
    plt.savefig('solution_{}.png'.format(solution_number), bbox_inches='tight')
    plt.close()

if __name__ == '__main__':
    solutions = solve_n_queens()
    print('总共找到 {} 个解决方案'.format(len(solutions)))
    for i, solution in solutions.iterrows():
        print('解决方案 {}:'.format(i + 1))
        draw_board(np.array(solution), i + 1)

4. Thoughts on the n queen problem

    The code for n queens does little processing compared to the previous code for the eight queens problem.

  1. Solve the problem that users cannot freely enter

In the eight queens problem, the value of n is fixed (n=8), which is specified directly in the code. In the modified code, the input function is used to allow users to input the value of n through the keyboard, so as to solve n queens problems of different scales according to user needs.

  1. Optimization of solution display and saving

In the original code, all found solutions were displayed and saved as image files. In this code, first output the number of found solutions, and then ask the user whether to save the image file of the solution, and perform corresponding operations according to the user's choice. This provides more flexible options and avoids unnecessary picture saving.

Overall, this code has no essential changes in the solution of the eight queens problem, mainly in terms of user interaction and result display, which increases the flexibility and customizability of the code.

The partially modified code snippet is shown below:

def is_safe(board, row, col):
    # 检查当前位置是否安全(不受其他皇后的攻击)
    for i in range(col):
        if board[i] == row or board[i] == row - (col - i) or board[i] == row + (col - i):
            return False
    return True

def solve_n_queens_util(board, col, solutions):
    if col == len(board):
        # 所有列都已经尝试过,找到一个解决方案
        # 将解决方案添加到DataFrame中
        solutions.loc[len(solutions)] = board
        return

    for row in range(len(board)):
        if is_safe(board, row, col):
            # 在当前位置放置皇后
            board[col] = row

            # 递归尝试下一列
            solve_n_queens_util(board, col + 1, solutions)

def solve_n_queens(n):
    board = [-1] * n
    solutions = pd.DataFrame(columns=['Q{}'.format(i+1) for i in range(n)])
    solve_n_queens_util(board, 0, solutions)
    return solutions

n = int(input("请输入皇后的数量:"))
solutions = solve_n_queens(n)
print('总共找到 {} 个解决方案'.format(len(solutions)))
user_input = input("是否保存解决方案图片?(yes/no): ")
if user_input.lower() == "yes":
    for i, solution in solutions.iterrows():
        draw_board(np.array(solution), i + 1)
        print("解决方案 {} 已保存为图片".format(i + 1))
else:
    print("解决方案未保存为图片")

Other parts are consistent with the eight queens problem.

Guess you like

Origin blog.csdn.net/m0_63794226/article/details/130953444