回溯法求解N皇后问题

简介: 回溯法求解N皇后问题

问题描述

给定一个n*n的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条对角线上,任意的两个白皇后都不在同一行、同一列或同一条对角线上。问总共有多少种放法?n小于等于8


解决方案

思路分析

先讨论n个皇后放在n*n的棋盘中,且不能同行、同列、同对角线的问题,那么第一个条件就是这些皇后的位置需要在不同行,即每行一个皇后。剩下的两个限制条件不妨用以下4*4的棋盘模拟展示(用Q代表皇后):

当选择第一个位置放置皇后时:


回溯算法大致思路:当一条路可以前进时就一直前进,行不通则退回上一步,以此类推。

当选择(1,1)作为起始皇后的位置时,那么第二排就有两个位置可以选择(23)、(24),但是当选择(23)时,第三排就无法继续了,现在退回去选择(24),在第三排hi有一种选择(32),在选择了这一点之后,发现第四排已经无法继续了,而且也无法再向第三排后退,说明(11)这一点无法作为皇后的位置,上述过程就是本题的一个回溯过程。以此类推,可以发现(12)和(13)两个点可以作为皇后的起点。

由于每个皇后占一行,所以可以用一个列表来存储每个皇后的所在列,对于上述4*4的棋盘,当选择(12)作为起点时,列表可以表示为[2,4,1,3],当选择(13)作为起点时,列表可以表示为[3,1,4,2]。同理可以得到n*n棋盘的可行列表。

首先定义一个判断可行位置的函数,分三种情况讨论;

然后开始定义选择棋盘函数,当位置满足判断函数时,把该位置加入到棋盘中,开始递归,递归终止的条件就是每个皇后都找到位置,然后将棋盘加入列表中。

回到本题,找出了可行棋盘也就求出了皇后位置的摆放方法总数,然后在进行排列(由于是黑白两种皇后故排列时有顺序)。


python代码

def feasible_index(box, nextx):  # box是一个存放每一行皇后位置的横坐标(即每个皇后所在列)nestx表示下个皇后的横坐标

    if len(box)>0:

        if nextx in box:#第一种情况,下一个皇后的位置位于其他皇后位置的同一列

            return False

        elif nextx==box[-1]-1:#第二种情况,下一个皇后的位置位于上一个皇后的左对角线

            return False

        elif nextx==box[-1]+1:#第三种情况,下一个皇后的位置位于上一个皇后的右对角线

            return False

    return True  # 满足位置条件,返回True

def queen(feasible_box, n, ans):

    if len(feasible_box) == n:  # n个皇后都找到位置后,递归结束

        ans.append(feasible_box)  # 将可行棋盘加到ans列表中

    else:

        for i in range(n):  # 皇后没排完,开始在下一行加入皇后

            if feasible_index(feasible_box, i):  # 判断i位置是否可行

                queen(feasible_box + [i], n, ans) # 将可行的i位置加入棋盘feasible_box,然后递归

lis = []

queen([], 4, lis)

if len(lis)<2:

    print(0)

else:

    print(len(lis)*(len(lis)-1))#排列黑白皇后。


结语

回溯算法最大的难点就是找到回退或者继续前进的条件,然后找到递归的出口递归的开始条件,对于运用回溯算法的问题,可以通过特殊的简单的案列结合图形的帮助来模拟回溯的步骤,再将特殊推广到普遍。

目录
相关文章
|
9月前
|
算法 定位技术 C++
基本算法-回溯法(迷宫问题)
基本算法-回溯法(迷宫问题)
310 0
|
2月前
|
算法
【算法学习】—n皇后问题(回溯法)
【算法学习】—n皇后问题(回溯法)
|
存储 算法
【回溯算法篇】组合问题(上)
【回溯算法篇】组合问题(上)
【回溯算法篇】组合问题(上)
|
机器学习/深度学习 算法
【回溯算法篇】N皇后问题
【回溯算法篇】N皇后问题
【回溯算法篇】N皇后问题
|
算法
【算法】 八皇后问题之回溯法
会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。每次填满第一行第一列,当不满足时候,试下第一行第二列,依次进行,递归的出口为找到第八个点,跳出递归。,在循环里面还要判断是否满足不同行,不同列,不同对角线。使用回溯法来解决该问题,下面的代码是我看到过的最精简的代码,相关的注释都写在代码上了。运行得出结果,总共有92中结果。
222 0
|
存储 缓存 移动开发
动态规划法
动态规划是在20世纪50年代由美国数学家贝尔曼为研究最优控制问题而提出的,当该方法在应用数学中的价值被大家认同以后,在计算机学界,动态规划法成为一种通用的算法设计技术用来求解多阶段决策最优化问题。
|
人工智能 算法
【动态规划】矩阵连乘
完全加括号的矩阵连乘积可递归地定义为: • 单个矩阵是完全加括号的 • 矩阵连乘积A是完全加括号的,则A可表示为2个完全加括号的矩阵连乘积B和C 的乘积并加括号,即A=(BC) 设有四个矩阵A, B, C, D ,它们的维数分别是: A = 50*10 B = 10*40 C = 40*30 D = 30*5 总共有五种完全加括号的方式:
289 0
|
存储 数据可视化
回溯求解N皇后问题
前期尝试过8皇后问题,虽然最后完成了求解,但过程其实是比较懵圈的
87 0
|
算法
回溯法解决N皇后问题
来源: 维基百科-N皇后问题 解题思路 采用回溯法,即逐一位置放置,然后放置下一行,如果下一行没有合法位置,则回溯到上一行,调整位置,直到得到所有值. 实现代码 /** * solve the N-Queen problem */ public class NQueen { //the ...
2479 0

热门文章

最新文章