使用回溯方法解决数独谜题的麻烦

时间:2015-03-13 17:06:31

标签: python recursion sudoku backtracking

我开始使用自己的解决数独谜题的方法。我在每行,每列和每个框中都列出了每个未使用的数字。然后我遍历我打开的未解决方块列表,寻找一个只有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()

0 个答案:

没有答案