n Queen backtracking 迭代所有位置
n Queen backtracking for iterating all the position
我正在尝试在没有任何第 3 方库的情况下解决 n Queen 问题。所以我只使用普通的 python 数组和循环。这是 nQueen 函数
def nQueenBackTrack(self, row, n):
for i in range(n):
if self.isTheQueenSafe(row , i):
print(row,i)
self.board[row][i] = "Q"
self.print_the_board()
if row == n:
self.print_the_board()
else:
self.nQueenBackTrack(row + 1, n)
非常简单。现在对于我的 isQueenSafe
功能,我检查来自其他皇后的水平和对角线攻击。
def isTheQueenSafe(self, row,col):
for i in range(self.N):
# check horizontal Queens
if self.does_board_has_a_queen_at(row,i) or self.does_board_has_a_queen_at(i, col):
return False
# check diagonal Queens
s = row + col
k = row - col
for x in range(self.N):
for y in range(self.N):
if x + y == s and self.board[x][y] == "Q":
return False
if x - y == k and self.board[x][y] == "Q":
return False
这是我遇到问题的功能。我相信我是为了正确检查条件。我将其作为 4 x 4 板的输出得到。
['Q', '.', '.', '.']
['.', '.', 'Q', '.']
['.', '.', '.', '.']
['.', '.', '.', '.']
谁能告诉我正确的方向
当你不能把女王放在任何地方时,你就不是在处理这个案子。
让我们考虑一下:
- 你调用函数 starting 并将第一个皇后放在 (0,0)
- 女王被安置是因为你可以
- 你不在最后一行,因此你进入递归将皇后放在下一行
- 您尝试将皇后放在第二行的 (0,1),然后放在 (1,1),这两者都是不可能的。
- 然后你尝试把它放在 (2,1) 处,成功了,你就进入了递归的第三层
- 您现在不能将皇后放在该行的任何位置。
- 您没有放置皇后就到达了数组的末尾
- 递归return到第二行
- 然后您(可能)甚至尝试将另一个皇后放在第二排,但您做不到。到达第二行的末尾,此递归调用也 returns
- 然后您(可能)甚至尝试将另一个皇后放在第一排,但您还是做不到。到达第一行的末尾,第一次调用
nQueenBackTrack
returns.
- 程序终止,只有两个皇后完全放在输出中可以看到的位置。
我建议您调试调试您的程序 (Python debugging tips) 或者您也可以添加一些额外的打印语句(例如在进入方法调用时和 returning 之前)这样您真能看出是怎么回事。
我假设一些东西:
- 我假设您在打印时旋转了板,因为...通常 x 是列,y 是行。 x 在水平方向,y 在垂直方向。
- 我还假设您确实正确地实施了
isTheQueenSafe
方法。你在评论中提到你实际上 return true
在某些时候。
- 我假设您的
nQueenBackTrack
方法中没有更多代码。
回溯算法需要能够撤销它对游戏状态所做的更改。在您的代码的情况下,它应该在找到有效位置时删除它放置的皇后:
def nQueenBackTrack(self, row, n):
for i in range(n):
if self.isTheQueenSafe(row , i):
self.board[row][i] = "Q" # this will need to be reversed later
if row == n:
self.print_the_board()
else:
self.nQueenBackTrack(row + 1, n)
self.board[row][i] = "." # backtrack: reset the modified square
此代码应打印出所有解决方案,但最后会使棋盘留空。如果你只想打印你能找到的第一个解决方案(并让棋盘上有皇后),你需要将函数更改为 return
一个指示是否找到解决方案的值。然后递归代码可以传递成功报告,或者如果递归失败则回溯:
def nQueenBackTrack(self, row, n):
for i in range(n):
if self.isTheQueenSafe(row , i):
self.board[row][i] = "Q"
if row == n:
self.print_the_board()
return True # success!
result = self.nQueenBackTrack(row + 1, n)
if result:
return True # pass on report of success
self.board[row][i] = "." # otherwise, backtrack
return False # if no solution was found, report failure
我正在尝试在没有任何第 3 方库的情况下解决 n Queen 问题。所以我只使用普通的 python 数组和循环。这是 nQueen 函数
def nQueenBackTrack(self, row, n):
for i in range(n):
if self.isTheQueenSafe(row , i):
print(row,i)
self.board[row][i] = "Q"
self.print_the_board()
if row == n:
self.print_the_board()
else:
self.nQueenBackTrack(row + 1, n)
非常简单。现在对于我的 isQueenSafe
功能,我检查来自其他皇后的水平和对角线攻击。
def isTheQueenSafe(self, row,col):
for i in range(self.N):
# check horizontal Queens
if self.does_board_has_a_queen_at(row,i) or self.does_board_has_a_queen_at(i, col):
return False
# check diagonal Queens
s = row + col
k = row - col
for x in range(self.N):
for y in range(self.N):
if x + y == s and self.board[x][y] == "Q":
return False
if x - y == k and self.board[x][y] == "Q":
return False
这是我遇到问题的功能。我相信我是为了正确检查条件。我将其作为 4 x 4 板的输出得到。
['Q', '.', '.', '.']
['.', '.', 'Q', '.']
['.', '.', '.', '.']
['.', '.', '.', '.']
谁能告诉我正确的方向
当你不能把女王放在任何地方时,你就不是在处理这个案子。
让我们考虑一下:
- 你调用函数 starting 并将第一个皇后放在 (0,0)
- 女王被安置是因为你可以
- 你不在最后一行,因此你进入递归将皇后放在下一行
- 您尝试将皇后放在第二行的 (0,1),然后放在 (1,1),这两者都是不可能的。
- 然后你尝试把它放在 (2,1) 处,成功了,你就进入了递归的第三层
- 您现在不能将皇后放在该行的任何位置。
- 您没有放置皇后就到达了数组的末尾
- 递归return到第二行
- 然后您(可能)甚至尝试将另一个皇后放在第二排,但您做不到。到达第二行的末尾,此递归调用也 returns
- 然后您(可能)甚至尝试将另一个皇后放在第一排,但您还是做不到。到达第一行的末尾,第一次调用
nQueenBackTrack
returns. - 程序终止,只有两个皇后完全放在输出中可以看到的位置。
我建议您调试调试您的程序 (Python debugging tips) 或者您也可以添加一些额外的打印语句(例如在进入方法调用时和 returning 之前)这样您真能看出是怎么回事。
我假设一些东西:
- 我假设您在打印时旋转了板,因为...通常 x 是列,y 是行。 x 在水平方向,y 在垂直方向。
- 我还假设您确实正确地实施了
isTheQueenSafe
方法。你在评论中提到你实际上 returntrue
在某些时候。 - 我假设您的
nQueenBackTrack
方法中没有更多代码。
回溯算法需要能够撤销它对游戏状态所做的更改。在您的代码的情况下,它应该在找到有效位置时删除它放置的皇后:
def nQueenBackTrack(self, row, n):
for i in range(n):
if self.isTheQueenSafe(row , i):
self.board[row][i] = "Q" # this will need to be reversed later
if row == n:
self.print_the_board()
else:
self.nQueenBackTrack(row + 1, n)
self.board[row][i] = "." # backtrack: reset the modified square
此代码应打印出所有解决方案,但最后会使棋盘留空。如果你只想打印你能找到的第一个解决方案(并让棋盘上有皇后),你需要将函数更改为 return
一个指示是否找到解决方案的值。然后递归代码可以传递成功报告,或者如果递归失败则回溯:
def nQueenBackTrack(self, row, n):
for i in range(n):
if self.isTheQueenSafe(row , i):
self.board[row][i] = "Q"
if row == n:
self.print_the_board()
return True # success!
result = self.nQueenBackTrack(row + 1, n)
if result:
return True # pass on report of success
self.board[row][i] = "." # otherwise, backtrack
return False # if no solution was found, report failure