python 实现n皇后问题算法

n皇后问题算法介绍

N皇后问题是一个经典的回溯算法问题,属于组合优化中的放置问题。问题目标是在N×N的棋盘上放置N个皇后,使得她们互不攻击,即任意两个皇后都不在同一行、同一列或同一对角线上。

下面是N皇后问题的一种常见解法,使用回溯法(Backtracking)来实现:

Python 示例代码

def is_safe(board, row, col, n):
    # 检查列上是否有皇后冲突
    for i in range(row):
        if board[i] == col:
            return False
    
    # 检查左上对角线是否有皇后冲突
    for i, j in zip(range(row-1, -1, -1), range(col-1, -1, -1)):
        if board[i] == j:
            return False
    
    # 检查右上对角线是否有皇后冲突
    for i, j in zip(range(row-1, -1, -1), range(col+1, n)):
        if board[i] == j:
            return False
    
    return True

def solve_n_queens(n):
    def place_queen(row, board):
        if row >= n:
            # 如果所有行都放置了皇后,则找到了一个解决方案
            result.append(board[:])
            return
        
        for col in range(n):
            if is_safe(board, row, col, n):
                board[row] = col
                place_queen(row + 1, board)
                board[row] = -1  # 回溯,撤销选择

    result = []
    board = [-1] * n  # 使用数组来记录每一行皇后的列位置,-1 表示尚未放置
    place_queen(0, board)
    return result

# 调用函数
n = 4  # 例如,4皇后问题
solutions = solve_n_queens(n)

# 打印所有解决方案
for solution in solutions:
    for row in solution:
        print(" ".join(".Q"[col != row] for col in range(n)))
    print()

代码说明

is_safe 函数检查在棋盘的 (row, col) 位置放置皇后是否安全。
solve_n_queens 函数定义了递归函数 place_queen 来放置皇后。它首先检查是否已经将所有皇后放置完毕(即 row >= n),如果是,则将当前棋盘状态添加到结果列表中。否则,它尝试在当前行的每一列放置皇后,并递归地放置下一行的皇后。
在递归调用 place_queen 之前,将皇后放置在 (row, col) 位置,并在递归调用之后,通过 board[row] = -1 撤销该选择,以尝试下一个可能的列位置。

该算法通过递归和回溯来探索所有可能的棋盘布局,并只保留那些满足N皇后条件的布局。

n皇后问题算法python实现样例

以下是使用递归回溯的方法来解决N皇后问题的Python实现:

def solveNQueens(n):
    def is_valid(board, row, col):
        # 检查同列是否有皇后冲突
        for i in range(row):
            if board[i] == col:
                return False
            # 检查对角线是否有皇后冲突
            if abs(board[i] - col) == abs(i - row):
                return False
        return True

    def backtrack(board, row):
        # 找到一个解,保存结果
        if row == n:
            res.append(board[:])
            return
        for col in range(n):
            if not is_valid(board, row, col):
                continue
            # 更新当前行的状态
            board[row] = col
            # 进入下一行的决策
            backtrack(board, row + 1)

    res = []
    board = [-1] * n  # 初始化棋盘
    backtrack(board, 0)  # 从第一行开始回溯
    return res

n = 4
solutions = solveNQueens(n)
print(f"共有 {
      
      len(solutions)} 种摆放方法:")
for solution in solutions:
    for row in range(n):
        line = ""
        for col in range(n):
            if solution[row] == col:
                line += "Q "
            else:
                line += ". "
        print(line)
    print()

运行以上代码,您将得到在4x4棋盘上的2种解法:

Q . . . 
. . Q . 
. . . Q 
. Q . . 

. Q . . 
. . . Q 
Q . . . 
. . Q . 

注意,此代码解决的是通用的N皇后问题,对于大型的N可能会有较长的运行时间。

猜你喜欢

转载自blog.csdn.net/u010634139/article/details/143205089