我开始使用自己的解决数独谜题的方法。我在每行,每列和每个框中都列出了每个未使用的数字。然后我遍历我打开的未解决方块列表,寻找一个只有1个可能放在那里的数字的方块,或者只有一个方格可以容纳特定数字的行,列或方框。当我找到另一个方块的解决方案时,我从广场所属的行,列和方框中删除了我刚刚找到的数字。
好的,一切正常。这是我的solve()方法的主要部分。在该方法的最后,如果板未解决,我调用depthFirst()。这应该使用回溯技术通过剩余的未解决的方块。
这是我用于测试的电路板:
400000805
030000000
000700000
020000060
000080400
000010000
000603070
500200000
104000000
我将我的代码与此解决方案进行了比较,但我看不出太多差异。 Algorithm for solving Sudoku
有没有人知道为什么我的代码的回溯部分不起作用?
谢谢!
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()