N皇后问题的实现
问题简介
给出一个nxn规格的国际象棋棋盘,要求在上面摆放n个皇后,要求这些皇后相互之间并不会相互攻击,则就给出的规格n,求:
-
有无可行摆放方式
-
有几种摆放方式
注:由于随着n的增大,解数量剧增,因此不实现所有解的列举
求解思路
已知,皇后会对同行,同列,以及45度倾斜角的棋子发动攻击,所以答案的组织形式可以是从0-n-1的某个排列,表示对应行皇后所在的列数。同时,我们采取深度优先的回溯算法,先着重解决有无解的问题,再解决解有多少的问题。
剪枝的触发条件为:该节点的新皇后会与该路径之前的皇后相互攻击。
代码实现
class n_queen:
## 初始化棋盘,并直接计算解并存储
def __init__(self,size):
self.size=size
self.solution=[]
self.solutions=[]
self.calSolutions()
#判断新皇后是否与老皇后处于同行同列或同斜线
def judge(self,col):
row=len(self.solution)
for i in range(row):
if (row-i)**2-(col-self.solution[i])**2==0:
return False
if col==self.solution[i]:
return False
return True
#计算解并存储可行解
def calSolutions(self,row=0):
if row>=self.size:
#存储解
self.solutions.append(self.solution)
else:
for i in range(self.size):
if(self.judge(i)):
self.solution.append(i)
self.calSolutions(row+1)
#回溯
self.solution.pop()
#返回可行解的数量
def solutionNum(self):
return len(self.solutions)
#判断是否可行
def solvable(self):
if len(self.solutions)==0:
return False
else:
return True
测试结果
这同现有的N皇后问题研究是相符的。