回溯法:N皇后
N皇后:
N皇后是排列樹,也是n叉樹,排列數要求:n后不在對角線上;n叉樹:n后不在對角線上且不在同一列上。
約束條件:
n后不在對角線上且不在同一列上。
通過畫圖,可以輕易得到:對角線,行差距==列差距:
實現如下,遞歸方式:
class Nqueen:def __init__(self,N):self.N = Nself.sum = 0self.solution = [-1]*Nself.solutionlist = []self.depth = 0def 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 Falsereturn Truedef back_tracking(self,depth):if depth > N-1:self.sum +=1 # print self.solutionself.solutionlist += [self.solution[:]]else:for i in range(N):self.solution[depth] = iif self.place(depth):self.back_tracking(depth+1)self.solution[depth] = -1def output_nQueen(self):self.back_tracking(self.depth)return self.solutionlist,self.sum if __name__ =='__main__': N=4nqueen = Nqueen(N)list,sum =nqueen.output_nQueen()print listprint sum[[1, 3, 0, 2], [2, 0, 3, 1]] 2迭代實現如下:
class Nqueen2:def __init__(self,N):self.N = Nself.sum = 0self.solution = [-1]*Nself.solutionlist = []self.depth = 0def 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 Falsereturn Truedef 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 += 1self.solutionlist += [self.solution[:]]# 進入下一層,初始化下一層子樹起始點 else:self.depth +=1self.solution[self.depth] =-1# 子樹遍歷完畢開始回溯 ,還是從上一層沒走完的地方繼續走 else:self.depth -=1def output_nQueen(self):self.back_tracking_iteration()return self.solutionlist,self.sum if __name__ =='__main__': N=4nqueen = Nqueen2(N)list,sum =nqueen.output_nQueen()print listprint sum[[1, 3, 0, 2], [2, 0, 3, 1]] 2總結
- 上一篇: 回溯法:批量作业调度
- 下一篇: 回溯法:全排列