一、实验目的
利用回溯法搜索或爬山法找到八皇后问题的一个可行解。
二、实验内容
有一个 8 × 8 的棋盘,现在要将8个皇后放到棋盘上,满足:对于每一个皇后,在
自己所在的行、列、两个对角线都没有其他皇后。求所有满足的摆放方式。
图2-1 八皇后问题示意图
三、实验方法
爬山法:
回溯法:
- Queen_set 函数接受一个参数 n,表示已经放置的皇后数量。
- queen_col_loc 列表用于存储皇后的列位置。
- 如果 n 等于 8,表示已经成功放置了八个皇后。在这种情况下,函数通过显示皇后的位置来打印解决方案。
- 调用 plot_chess 函数绘制当前的皇后摆放方案。
- 递增方案数 num 的值。
- 返回函数。
- 否则,循环遍历当前行的每个位置。
- 检查当前位置是否可以放置皇后,调用 check 函数进行检测。
- 如果可以放置皇后,将当前位置添加到 queen_list 列表中。
- 递归调用 Queen_set 函数放置下一个皇后。
- 回溯,尝试当前行的其他皇后摆放方法,从 queen_list 列表中移除最后一个元素。
- check 函数用于检测皇后的位置是否合法。
- 如果是第一行,直接返回 True。
- 否则,循环遍历之前的每一行。
- 检查当前位置是否与之前的皇后所在的列有冲突。
- 检查当前位置是否与之前的皇后所在的主对角线和副对角线有冲突。
- 如果有任何冲突,返回 False。
- 如果通过了所有检测,返回 True。
- plot_chess 函数用于绘制棋盘并保存求解结果。
- 创建一个大小为 8x8 的全零数组 map。
- 遍历每一行,将皇后所在的列位置设为 1。
- 创建一个颜色映射 cmap,用于绘制棋盘。
- 使用 plt.imshow 函数绘制棋盘。
- 设置标题和刻度。
- 保存绘制的棋盘图像。
- 初始化 queen_list 列表为空。
- 初始化当前方案数 num 为 1。
- 调用 Queen_set 函数,从第一行开始放置皇后。
图3-1 回溯法解决八皇后问题运行结果
目录: 代码段一:导包 代码段二:函数定义 代码段三:调用运行 |
导包 |
import numpy as np import matplotlib import matplotlib.pyplot as plt #设定中文字符集,解决绘图时中文乱码问题 matplotlib.rcParams['font.sans-serif'] = ['SimHei'] |
函数定义 |
#放置函数,参数为已放置的皇后数量 def Queen_set(n): global num global queen_list queen_col_loc=[i+1 for i in queen_list] #方案可行 if n==8: print("第"+str(num)+"种:",(1,queen_col_loc[0]),(2,queen_col_loc[1]),(3,queen_col_loc[2]),(4,queen_col_loc[3]) ,(5,queen_col_loc[4]),(6,queen_col_loc[5]),(7,queen_col_loc[6]),(8,queen_col_loc[7])) #绘制当前的皇后摆放方案 plot_chess(queen_list) num+=1 return else: #检查当前行哪一个位置可以放置 for i in range(8): if check(n,i): queen_list.append(i)#在当前位置放置皇后 Queen_set(n+1)#递归放置下一个皇后 queen_list.pop()#回溯,尝试当前行的其他皇后摆放方法 #检测,传入参数为皇后摆放的位置 def check(row,col): if row==0: return True else: #检测列是否与之前摆放的皇后有冲突 for i in range(row): if col==queen_list[i]: return False #检测对角线是否有冲突,分为主对角线和副对角线,满足直线方程x+y=n 和x-y=n elif i+queen_list[i]==row+col or i-queen_list[i]==row-col: return False return True
#绘制棋盘并保存求解结果 def plot_chess(result): global num map=np.zeros((8,8)) for i in range(8): map[i,result[i]]=1 cmap = matplotlib.colors.LinearSegmentedColormap.from_list('my_camp', ['white', 'black'], 2) plt.imshow(map, cmap=cmap) plt.title("第" + str(num) + "种解法", fontsize=16) plt.xticks([]) plt.yticks([]) plt.savefig('C:/Users/14767/Desktop/expriment/'+str(num)+'.png') #保存图片的路径,自行修改 |
调用运行 |
#从第一行开始逐行放置皇后,将皇后的列坐标放入列表中 queen_list=[] #当前的方案数 num=1 Queen_set(0) |
图3-2 八皇后问题解法可视化部分结果