用python实现八皇后问题(简易版,无复杂函数或语法)

数据结构与算法 之 python实现——算法源码

用python实现八皇后问题(简易版,无复杂函数或语法)

python 版本:3.7.5

八皇后问题的全代码在下面了,里面有比较详细的注释方便大家理解。下面讲解一些个人认为比较重要的点:

一、 整体思路

该算法用到了两类矩阵,第一类是place,用于存放queen的位置,有queen的位置标记为1,其他位置标记为0;第二类是flag_col, flag_d1, flag_d2(下边有详细讲解),用于记录棋盘上哪些位置可以被已有的queen攻击到(即不能再放置其他的queen),可以放置标记为1,不可以放置标记为0。这两个矩阵的含义就是,如果在一点放置了queen,就将place中相应的位置标记为1;相应的如果放置了queen,就会有新的点不能放置queen,因此需要更新flag_col, flag_d1, flag_d2(三个矩阵分别存放queen能攻击到的列、从左上到右下的斜线、从右上到左下的斜线)。

有了以上矩阵的理解,算法思路如下:

从上往下逐行进行检验,若发现第n行某一点可以放置queen,就放置,然后同样方式处理下一行(n+1行),即在n+1行找到可行的位置放置queen;

若第n行的这个点不能放置,则检验该行的下一个点。

若第n行所有的点都不能放置,则退回到上一行(n-1行),检验上一行(n-1行)queen所在位置之后的点,找到下一个可以放置queen的位置,放置queen,之后再到第n行寻找可以放置queen的点。

如此往复,直到所有的queen都放置完毕。

二、 递归和回溯思想

递归:体现在重复性函数上:寻找可放置queen的点,并放置queen,之后对下一行进行同样操作。

回溯:体现在当第n行所有点都不能放置queen时,回溯到第n-1行,并将第n-1行的queen挪到下一个可行的位置。

三、 小技巧

flag_d1  &  flag_d2

这两个矩阵是一维矩阵,每个数字代表一条斜线。

以5*5图片为例:

                                                                                                                   嗷呜~             

如上图所示,对二维矩阵的行列下标进行加和,可以得到图1,可见同一右倾斜线的值相同,因此可以用一个数字表示一个斜线。同理左倾斜线如图2所示。

源码如下:

# ###########八皇后问题的解决###################
import numpy as np


def eightQueens(row):
    global count
    global place
    global flag_col
    global flag_d1
    global flag_d2
    for col in range(0, 8):
        """以下为找到不冲突的位置并放置queen"""
        if flag_col[0, int(col)] and flag_d1[0, int(row - col + 7)] and flag_d2[0, int(row + col)]:  # 判断(row, col)点所在位置是否可以放置queen
            place[row, col] = 1  # 放置queen
            """由于放置queen,一些位置被占领,不能再放置queen,下边三行用于标记被占领的位置"""
            flag_col[0, col] = 0  # 标记queen所在列被占领,0含义为不可放置queen
            flag_d1[0, row - col + 7] = 0  # 标记queen所在左倾斜线被占领
            flag_d2[0, row + col] = 0  # 标记queen所在右倾斜线被占领
            if row < 7:  # 递归 若没有到最后一行 寻找下一行的可行位置并放置queen
                eightQueens(row + 1)
            else:  # 8个queen放置完毕,输出queen的摆放情况并计数
                count = count + 1  # 需要在def 的eightQueens函数内进行global count(定义为全局变量),将main中定义的count变量传递到函数中,否则报错
                print("第", count, "种情况")
                print(place)

            """"以下为回溯过程(回溯就类似于艾克的两极反转,相当于退回到没有放置前一个queen的情况,即与14—17行相反)"""""
            place[row, col] = 0
            flag_col[0, col] = 1
            flag_d1[0, row - col + 7] = 1
            flag_d2[0, row + col] = 1


if __name__ == '__main__':
    place = np.zeros((8, 8))
    flag_col = np.ones((1, 8))
    flag_d1 = np.ones((1, 15))
    flag_d2 = np.ones((1, 15))
    count = 0
    eightQueens(0)

参考:懒猫老师-C语言-递归函数-八皇后问题(搜索,回溯)_哔哩哔哩_bilibili

光学专业想转码于是在苦逼的自学路上摸爬滚打。技术有限,欢迎大佬们在评论区指出问题,也欢迎转码的伙伴一起交流!

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值