算法(11):回溯法

今天补一下回溯法,别的不说,n皇后问题必须列出来才行~


  • 目录:
    算法:附录
    算法(1):递归
    算法(2):链表
    算法(3):数组
    算法(4):字符串
    算法(5):二叉树
    算法(6):二叉查找树
    算法(7):队列和堆栈(附赠BFS和DFS)
    算法(8):动态规划
    算法(9):哈希表
    算法(10):排序
    算法(11):回溯法
    算法(12):位操作

问题1:n皇后问题,在n x n 格的国际象棋上摆放n个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。

算法(11):回溯法_第1张图片
八皇后图片

代码实现方案1:

class nqueen(object):
    def __init__(self,N):
        self.N=N
        b=[[0 for i in range(N)] for j in range(N)]
        self.count=0
        self._work(b,0)
        print(self.count)

    def printboard(self,board):
        for i in range(self.N):
            for j in range(self.N):
                print(board[i][j],end=' ')
            print()
        print()

    def _check(self,board,row,col):
        for i in range(row):
            if board[i][col]==1:
                return False
        for i,j in zip(range(row,-1,-1),range(col,-1,-1)):
            if board[i][j]==1:
                return False
        for i,j in zip(range(row,-1,-1),range(col,self.N,1)):
            if board[i][j]==1:
                return False
        return True

    def _work(self,board,row):
        if row ==self.N:
            self.count+=1
            self.printboard(board)
        else:
            for j in range(self.N):
                if self._check(board,row,j):
                    board[row][j] = 1
                    self._work(board,row+1)
                    board[row][j] = 0


if __name__ == '__main__':
    queen=nqueen(4)

代码实现方案2:

  Use the DFS helper function to find solutions recursively. A solution will be found when the length of queens is equal to n ( queens is a list of the indices of the queens).
  In this problem, whenever a location (x, y) is occupied, any other locations (p, q ) where p + q == x + y or p - q == x - y would be invalid. We can use this information to keep track of the indicators (xy_dif and xy_sum ) of the invalid positions and then call DFS recursively with valid positions only.
  At the end, we convert the result (a list of lists; each sublist is the indices of the queens) into the desire format.

def NQueens(n):
    def DFS(queens, xy_dif, xy_sum):
        p = len(queens)
        if p==n:
            result.append(queens)
            return None
        for q in range(n):
            if q not in queens and p-q not in xy_dif and p+q not in xy_sum: 
                DFS(queens+[q], xy_dif+[p-q], xy_sum+[p+q])  
    result = []
    DFS([],[],[])
    return [ [[1 if x ==i else 0 for x in range(n)] for i in sol] for sol in result]

def printboard(board):
    N = len(board)
    for i in range(N):
        for j in range(N):
            print(board[i][j],end=' ')
        print()
    print()

if __name__ == '__main__':
    ans = NQueens(8)
    
    [printboard(b) for b in ans]
    print(len(ans))

你可能感兴趣的:(算法(11):回溯法)