Python 用回溯法解决数独难题的困难
我开始用我自己的方法解决数独难题。我在每行、每列和每框中保留一个未使用的数字列表。然后,我在未解决的方块的开放列表上循环寻找一个方块,该方块要么只有一个可能的数字可以放在那里,要么是一行、一列或一个只有一个方块可以容纳特定数字的方框。当我找到另一个正方形的解时,我会从该正方形所属的行、列和框中删除刚找到的数字 好了,一切都好。这是我的solve()方法的主要部分。在该方法的最后,如果电路板的问题没有解决,我调用depthFirst()。这应该使用回溯技术通过剩余未解决的方块 这是我用于测试的板:Python 用回溯法解决数独难题的困难,python,recursion,sudoku,backtracking,Python,Recursion,Sudoku,Backtracking,我开始用我自己的方法解决数独难题。我在每行、每列和每框中保留一个未使用的数字列表。然后,我在未解决的方块的开放列表上循环寻找一个方块,该方块要么只有一个可能的数字可以放在那里,要么是一行、一列或一个只有一个方块可以容纳特定数字的方框。当我找到另一个正方形的解时,我会从该正方形所属的行、列和框中删除刚找到的数字 好了,一切都好。这是我的solve()方法的主要部分。在该方法的最后,如果电路板的问题没有解决,我调用depthFirst()。这应该使用回溯技术通过剩余未解决的方块 这是我用于测试的板:
400000805
030000000
000700000
020000060
000080400
000010000
000603070
500200000
104000000
我将我的代码与这个解决方案进行了比较,没有发现太多的差异
有人知道我代码的回溯部分为什么不起作用吗
谢谢
import copy
# Only removes the element from the list if it exists in the list
def safeRemove(l, e):
if l.count(e) > 0:
l.remove(e)
# Represents the board and keeps track of everything needed for solving the puzzle
class Sudoku:
# 3x3 array of 3x3 arrays to represent the board
# board is filled with BoardPos objects that keep track of the square's value, row, column, and box the square is a part of
board = [[[[None for i in range(3)] for j in range(3)] for k in range(3)] for l in range(3)]
# Keeps track of all numbers that are not currently taken in each row, column, and box
rows = [[i for i in range(1, 10)] for j in range(9)]
cols = [[i for i in range(1, 10)] for j in range(9)]
boxes = [[i for i in range(1, 10)] for j in range(9)]
# Unsolved squares
openList = list()
# Keeps track of each square's current value (0 for unsolved) and which
# row, column, and box the square is a part of
class BoardPos:
def __init__(self, w, x, y, z):
self.a = w
self.r = x
self.c = y
self.b = z
# Use an algorith similar to DFS to solve the remainder of the puzzle
def depthFirst(self):
if len(self.openList) == 0:
self.board = boardState.board
return True
curSquare = self.openList[0]
possibilities = self.getPossibilities(curSquare)
# Save current state to return to
tempBoard = copy.deepcopy(self.board)
tempRows = copy.deepcopy(self.rows)
tempCols = copy.deepcopy(self.cols)
tempBoxes = copy.deepcopy(self.boxes)
tempOpenList = copy.deepcopy(self.openList)
for e in possibilities:
self.found(curSquare, e)
if self.depthFirst():
return True
# Restore to state of the last partial, possibile solution
self.board = tempBoard
self.rows = tempRows
self.cols = tempCols
self.boxes = tempBoxes
self.openList = tempOpenList
return False
# Set the square the value found and remove that value from the square's
# row, column, and box and remove the square from the open list
def found(self, index, el):
i, j, k, l = index
self.board[i][j][k][l].a = el
self.removeFound(index, el)
del self.openList[0]
# Remove the value from the square's row, column, and box
def removeFound(self, index, el):
i, j, k, l = index
safeRemove(self.rows[self.board[i][j][k][l].r], el)
safeRemove(self.cols[self.board[i][j][k][l].c], el)
safeRemove(self.boxes[self.board[i][j][k][l].b], el)
# Returns a list of all possible values for the square
def getPossibilities(self, index):
i, j, k, l = index
tempRow = self.rows[self.board[i][j][k][l].r]
tempCol = self.cols[self.board[i][j][k][l].c]
tempBox = self.boxes[self.board[i][j][k][l].b]
return list(set(tempRow) & set(tempCol) & set(tempBox))
# Returns the box of the square
def box(self, i, j, k, l):
return i * 3 + j
# Returns the row of the square
def row(self, i, j, k, l):
return i * 3 + k
# Returns the column of the square
def col(self, i, j, k, l):
return j * 3 + l
def main():
# Removed constructor to reduce code. Constructor just initialized the board with values from board.txt
puzzle = Sudoku("board.txt")
puzzle.depthFirst()
puzzle.printBoard()
if __name__ == "__main__":
main()
这是太多的代码,我们无法查看。尽量减少你的代码,直到你找到一个最小的例子,它不能像你期望的那样工作。