问题描述
有一个8x8的棋盘,需要摆8个皇后在棋盘上,让8个皇后分别不相见。问:有多少种摆法。知道8皇后怎么解决,自然就解决了n皇后问题。
思考
- 这个题目也是CSDN一抓一大把的解答,在力扣上,这个题目也是难度中上的,大多数人用的是DFS算法,有没有不用算法的解,能破8皇后的局?
- 这道题的解答,将体现出人脑和机器脑的比例。比如,你设规则从第一行开始摆皇后,这就是给机器一个限制。如果你这么设置了,那么最后得到的摆法个数恐怕要乘以4。因为有方向性的摆法,转四次,会有不一样的结局。给你们看看八皇后的一个案例,转几下,是不是不一样。
- 这意味着,很多人的计算方法是可能是不够(也有人是冗余)的。
- 所以,我们试着更新方法,放宽人对机器的限制试试
更新方法
- 用 n = 8 来建立棋盘数组boardlist,数组里的每一个元素,都是【行,列】坐标;
- 定义落下一个皇后,会“占据”或“无效化"那些坐标,定义为taken列表,并实时更新boardlist;
- 准备100000个皇后随机往下丢
– 判断是否可以落子:随机行列数是不是在boardlist中;
——>在:落子,执行落下后更新的taken和boardlist
——>不在:返回,继续丢,反正我们皇后多的是
– 条件判断:如果boardlist在某个时刻变空,无法再摆皇后了。
——>如果此时在盘皇后为n,如果这个组合从未被记录,则记录这个组合
——>记录或者不记录,这个时刻都要更新Boardlist和相关的动态变量 - 最后我们会获得一个很杂乱的组合,同样的组合,就算是排序不一样,也会被记录,所以需要数据清洗。
- 清洗后的,就是我们要的答案。
- 完毕
代码实现
- 所用的库
import numpy as np
import random
import time
from operator import itemgetter
numpy大家都知道,是做数组的运算需要的
random是随机用法的库
time用来计算程序花多少时间执行
operator是拿来给我按照列表中某个元素排序用的
- 初始数据
n = 8
taken = [] # 棋盘上已经占用了的行列数组
nums = list(set(np.arange(1, n+1))) # 1到n的数字列表
queen = []
- 生成棋盘数组
def board():
boardlist = []
for row in range(1, n+1):
for col in range(1, n+1):
a = [row, col]
boardlist.append(a)
return boardlist
boardlist = board() # 棋盘上所有的行列数组(list)
- 定义落下一个伟大的皇后,棋盘上会无效化多少格子(taken),以及实时更新棋盘(boardlist)