1. 程式人生 > >回溯法:N皇后

回溯法:N皇后

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