【发布时间】:2019-11-26 20:54:37
【问题描述】:
这是我解决 8-queens 问题的 python 程序。除了打印已解决的电路板的最后一步外,一切正常。我使用递归/回溯来用皇后填充棋盘,直到找到解决方案。包含解决方案的板对象是self,它是对b1 的引用,所以我假设我初始化的原始板b1 将被更新以包含最终解决的板,并将打印解决方案使用printBoard。但是,b1 没有更新,当我出于某种未知原因打印它时,它持有一个故障板。
编辑:在solve 中添加了placeQueen
EMPTY = 0
QUEEN = 1
RESTRICTED = 2
class Board:
# initializes a 8x8 array
def __init__ (self):
self.board = [[EMPTY for x in range(8)] for y in range(8)]
# pretty prints board
def printBoard(self):
for row in self.board:
print(row)
# places a queen on a board
def placeQueen(self, x, y):
# restricts row
self.board[y] = [RESTRICTED for i in range(8)]
# restricts column
for row in self.board:
row[x] = RESTRICTED
# places queen
self.board[y][x] = QUEEN
self.fillDiagonal(x, y, 0, 0, -1, -1) # restricts top left diagonal
self.fillDiagonal(x, y, 7, 0, 1, -1) # restructs top right diagonal
self.fillDiagonal(x, y, 0, 7, -1, 1) # restricts bottom left diagonal
self.fillDiagonal(x, y, 7, 7, 1, 1) # restricts bottom right diagonal
# restricts a diagonal in a specified direction
def fillDiagonal(self, x, y, xlim, ylim, xadd, yadd):
if x != xlim and y != ylim:
self.board[y + yadd][x + xadd] = RESTRICTED
self.fillDiagonal(x + xadd, y + yadd, xlim, ylim, xadd, yadd)
# recursively places queens such that no queen shares a row or
# column with another queen, or in other words, no queen sits on a
# restricted square. Should solve by backtracking until solution is found.
def solve(self, col):
if col == -1:
return True
for i in range(8):
if self.board[i][col] == EMPTY:
temp = self.copy()
self.placeQueen(col, i)
if self.solve(col - 1):
return True
temp.board[i][col] = RESTRICTED
self = temp.copy()
return False
# deep copies a board onto another board
def copy(self):
copy = Board()
for i in range(8):
for j in range (8):
copy.board[j][i] = self.board[j][i]
return copy
b1 = Board()
b1.solve(7)
b1.printBoard()
我知道我的实际求解器正在工作,因为当我像这样添加printBoard 时:
if col == -1:
self.printBoard()
return True
在solve 方法中,打印了已解决的板。简而言之,为什么板子的self 实例没有更新b1?
【问题讨论】:
-
您认为
copy会做什么?你是怎么用的? -
我建议将
copy()更改为仅复制8x8数组,然后不要尝试设置self,而是将8x8数组重置为保存的数组。 -
我认为错误是您将函数内部的 self 变量重新分配给 temp.copy() 的返回结果。 Python 创建了一个新变量 self ,仅此而已。所以你对原始对象的引用丢失了。如果要更改 self 对象,请更新其属性之一,而不是重新分配结果。
-
感谢您的建议。我在解决问题时错过了
placeQueen调用,我只是在复制代码和删除一些 cmets 时出错。 -
我使用复制作为一种将 Board 对象的板“复制”到另一个 Board 对象的方式。我这样做是为了保存一个棋盘,以防我想在回溯过程中撤消皇后的位置,如果这有意义的话。
标签: python reference self backtracking n-queens