前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >回溯求解N皇后问题

回溯求解N皇后问题

作者头像
luanhz
发布2020-03-31 17:21:11
4270
发布2020-03-31 17:21:11
举报
文章被收录于专栏:小数志小数志

前期尝试过8皇后问题,虽然最后完成了求解,但过程其实是比较懵圈的

最近学习了“图”的数据结构相关知识,对深度优先和广度优先有了全新认识,所以重新用DPS递归加回溯求解八皇后问题,并将之推广到N皇后。

基本思路:

  1. 构建N皇后求解的结果数据结构,因为N皇后必然是N行中每行一个,而只需遍历求解纵坐标,所以定义N皇后的结果数据结构为一个 len= N 列表,用于存储第N个皇后的纵坐标;
  2. 实现一个判断函数,用于对给定的结果列表判断是否满足N皇后共存,返回bool值;
  3. 递归实现一个N皇后求解函数,在已有共存的皇后坐标基础上,增加一个新的皇后纵坐标,且遍历该纵坐标为0~N-1,并逐个调用判断函数,看增加了新皇后之后是否共存:
    1. 若共存,则在求解中增加该位置值,
      1. 若此时已经完成了N个皇后的设计,则保存当前结果
      2. 若完成皇后个数<N,则在此基础上递归调用N皇后求解函数。
    2. 无论当前是否共存,都将新加入的皇后位置弹出,来寻求新的结果。
  4. 实现了一个显示N皇后共存结果的函数,打印显示,便于可视化验证。
代码语言:javascript
复制
import copy

def judge(queenLocs):
    """
    判断给定的位置列表下,是否满足皇后共存
    :param queenLocs:  1-N个元素,每个元素为该一个皇后的列坐标
    :return: True or False
    """
    for queen1, loc1 in enumerate(queenLocs[:-1]):
        for queen2, loc2 in enumerate(queenLocs[queen1+1:], queen1+1):
            if loc2 == loc1 or queen2 - queen1 == abs(loc2 - loc1):#位于同列或对角线
                return False
    return True

def display(queenLocs):
    """
    显示皇后位置
    :param queenLocs:皇后位置列表
    :return: None
    """
    for loc in queenLocs:
        line = "___"*loc + " * " + "___"*(len(queenLocs)-loc-1)
        print(line)

def solveNqueen(queenNum, queenLocs = [], results = []):
    """
    利用DPS递归+回溯所有可能的N皇后问题,并返回所有解
    :param queenNum: 皇后数目
    :param queenLocs: 已有皇后位置,默认为空
    :param results: 记录所有解决方案
    :return: None
    """
    for loc in range(queenNum):
        queenLocs.append(loc)                              #在已有皇后位置的基础上,尝试再放置一个皇后
        if judge(queenLocs):                               #新放入的皇后能够共存
            if len(queenLocs) == queenNum:                 #若已放置目标数量的皇后
                results.append(copy.deepcopy(queenLocs))   #记录当前解决方案,并将一份深拷贝加入到结果
            else:                                          #未达到目标数量且当前可以共存,在此基础上
                solveNqueen(queenNum, queenLocs, results)
        queenLocs.pop()

if __name__ == "__main__":
    results = []
    solveNqueen(8, results = results)
    print(len(results))
    display((results[0]))
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-02-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小数志 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档