N皇后:
N皇后是排列树,也是n叉树,排列数要求:n后不在对角线上;n叉树:n后不在对角线上且不在同一列上。
约束条件:
n后不在对角线上且不在同一列上。
通过画图,可以轻易得到:对角线,行差距==列差距:
def place(self,k):
for i in range(k):
if abs(k-i) == abs(self.solution[k]-self.solution[i]) or self.solution[k]==self.solution[i]:
return False
return True
实现如下,递归方式:
class Nqueen:
def __init__(self,N):
self.N = N
self.sum = 0
self.solution = [-1]*N
self.solutionlist = []
self.depth = 0
def place(self,k):
for i in range(k):
if abs(k-i) == abs(self.solution[k]-self.solution[i]) or self.solution[k]==self.solution[i]:
return False
return True
def back_tracking(self,depth):
if depth > N-1:
self.sum +=1
# print self.solution
self.solutionlist += [self.solution[:]]
else:
for i in range(N):
self.solution[depth] = i
if self.place(depth):
self.back_tracking(depth+1)
self.solution[depth] = -1
def output_nQueen(self):
self.back_tracking(self.depth)
return self.solutionlist,self.sum
if __name__ =='__main__':
N=4
nqueen = Nqueen(N)
list,sum =nqueen.output_nQueen()
print list
print sum
[[1, 3, 0, 2], [2, 0, 3, 1]]
2
迭代实现如下:
class Nqueen2:
def __init__(self,N):
self.N = N
self.sum = 0
self.solution = [-1]*N
self.solutionlist = []
self.depth = 0
def place(self,k):
for i in range(k):
if abs(k-i) == abs(self.solution[k]-self.solution[i]) or self.solution[k]==self.solution[i]:
return False
return True
def back_tracking_iteration(self):
while self.depth >=0:
self.solution[self.depth] +=1
# 找到一个满足条件的
while self.solution[self.depth] < self.N and not self.place(self.depth):
self.solution[self.depth] +=1
# 子树没有遍历完毕
if self.solution[self.depth] <= N-1:
if self.depth == N-1:
self.sum += 1
self.solutionlist += [self.solution[:]]
# 进入下一层,初始化下一层子树起始点
else:
self.depth +=1
self.solution[self.depth] =-1
# 子树遍历完毕开始回溯 ,还是从上一层没走完的地方继续走
else:
self.depth -=1
def output_nQueen(self):
self.back_tracking_iteration()
return self.solutionlist,self.sum
if __name__ =='__main__':
N=4
nqueen = Nqueen2(N)
list,sum =nqueen.output_nQueen()
print list
print sum
[[1, 3, 0, 2], [2, 0, 3, 1]]
2