回溯法:N皇后
阿新 • • 發佈:2019-02-20
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