You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现Python高效n皇后问题求解算法?适配n≥20及更大场景

高效求解N皇后问题:Python实现与优化方案

一、核心优化逻辑

你之前用排列校验的方法,本质是生成所有可能的皇后列位置组合再逐一验证,时间复杂度为O(n! * n),n≥20时n!已是天文数字,完全不可行。

优化核心为回溯+剪枝+位运算:

  • 回溯:逐行放置皇后,每放一行就记录当前约束条件,避免后续无效尝试
  • 剪枝:放置皇后前直接排除会与已放皇后冲突的位置,从根源上不生成无效路径
  • 位运算:用整数二进制位表示列、对角线的占用状态,位操作比数组/集合操作快数个数量级,且Python支持任意精度整数,无溢出顾虑

二、位运算优化的回溯实现

统计所有解的数量

如果仅需统计解的总数,这个实现效率极高:

def count_n_queens(n):
    def backtrack(cols, pie, na):
        # cols: 已占用列(二进制位为1表示被占用)
        # pie: 已占用主对角线(左上→右下)
        # na: 已占用副对角线(右上→左下)
        row = bin(cols).count('1')  # 当前处理的行号(已放皇后数量)
        if row == n:
            return 1
        # 计算当前行可放置皇后的位置:排除所有已约束的位
        available = ((1 << n) - 1) & (~(cols | pie | na))
        count = 0
        while available:
            # 取出最右侧的1(选中一个可放置位置)
            pos = available & -available
            available ^= pos  # 标记该位置已被选择
            # 递归处理下一行,更新约束条件
            count += backtrack(cols | pos, (pie | pos) << 1, (na | pos) >> 1)
        return count
    return backtrack(0, 0, 0)

生成所有可行解的具体棋盘

如果需要输出所有解的棋盘格式,可调整为:

def solve_n_queens(n):
    solutions = []
    def backtrack(row, cols, pie, na, path):
        if row == n:
            # 转换为棋盘字符串格式
            board = ['.'*i + 'Q' + '.'*(n-i-1) for i in path]
            solutions.append(board)
            return
        available = ((1 << n) - 1) & (~(cols | pie | na))
        while available:
            pos = available & -available
            available ^= pos
            col = bin(pos).count('1') - 1  # 计算当前位置对应的列号
            backtrack(row+1, cols | pos, (pie | pos) << 1, (na | pos) >> 1, path + [col])
    backtrack(0, 0, 0, 0, [])
    return solutions

三、高效性细节说明

  1. 剪枝效率:每一步仅处理当前行的可行位置,不会生成任何已冲突的路径,比如n=20时,实际递归次数远小于20!,大部分无效路径在早期就被剪掉。
  2. 位运算速度:Python的位操作是底层实现,比用列表、集合记录约束条件快很多,判断可用位置、更新约束均为单步位运算,无循环开销。
  3. 递归栈安全:递归深度等于n,Python默认递归深度限制为1000,因此n≤1000时都不会栈溢出,完全覆盖n≥20甚至n=100的场景。

四、处理n=100这类超大值的场景

统计解的数量

n=100的解数量是一个超100位的数,上述统计解数量的算法可以快速计算结果(但仅为数字,无实际枚举意义)。

求单个可行解

无需遍历所有路径,找到第一个可行解就返回,效率更高:

def find_one_n_queen(n):
    def backtrack(row, cols, pie, na, path):
        if row == n:
            return path
        available = ((1 << n) - 1) & (~(cols | pie | na))
        while available:
            pos = available & -available
            available ^= pos
            col = bin(pos).count('1') - 1
            res = backtrack(row+1, cols | pos, (pie | pos) << 1, (na | pos) >> 1, path + [col])
            if res:
                return res
        return None
    path = backtrack(0, 0, 0, 0, [])
    if path:
        return ['.'*i + 'Q' + '.'*(n-i-1) for i in path]
    return None

构造法生成可行解

对于n≥4的场景,可直接用构造法O(n)生成可行解,无需递归:

  • 若n为偶数且不是6k+2:皇后放在(2,4,6,...,n,1,3,5,...,n-1)列
  • 若n为偶数且是6k+2:皇后放在(1,3,5,...,n-1,2,4,6,...,n)列
  • 若n为奇数:先按偶数方法处理n-1行,最后一行放在中间列

内容的提问来源于stack exchange,提问作者user21429639

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 08:47:43