数据结构与算法 之 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
光学专业想转码于是在苦逼的自学路上摸爬滚打。技术有限,欢迎大佬们在评论区指出问题,也欢迎转码的伙伴一起交流!