今天补一下回溯法,别的不说,n皇后问题必须列出来才行~
- 目录:
算法:附录
算法(1):递归
算法(2):链表
算法(3):数组
算法(4):字符串
算法(5):二叉树
算法(6):二叉查找树
算法(7):队列和堆栈(附赠BFS和DFS)
算法(8):动态规划
算法(9):哈希表
算法(10):排序
算法(11):回溯法
算法(12):位操作
问题1:n皇后问题,在n x n
格的国际象棋上摆放n个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
代码实现方案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 )
wherep + q == x + y
orp - q == x - y
would be invalid. We can use this information to keep track of the indicators (xy_dif
andxy_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))