Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 用回溯法解决数独难题的困难_Python_Recursion_Sudoku_Backtracking - Fatal编程技术网

Python 用回溯法解决数独难题的困难

Python 用回溯法解决数独难题的困难,python,recursion,sudoku,backtracking,Python,Recursion,Sudoku,Backtracking,我开始用我自己的方法解决数独难题。我在每行、每列和每框中保留一个未使用的数字列表。然后,我在未解决的方块的开放列表上循环寻找一个方块,该方块要么只有一个可能的数字可以放在那里,要么是一行、一列或一个只有一个方块可以容纳特定数字的方框。当我找到另一个正方形的解时,我会从该正方形所属的行、列和框中删除刚找到的数字 好了,一切都好。这是我的solve()方法的主要部分。在该方法的最后,如果电路板的问题没有解决,我调用depthFirst()。这应该使用回溯技术通过剩余未解决的方块 这是我用于测试的板:

我开始用我自己的方法解决数独难题。我在每行、每列和每框中保留一个未使用的数字列表。然后,我在未解决的方块的开放列表上循环寻找一个方块,该方块要么只有一个可能的数字可以放在那里,要么是一行、一列或一个只有一个方块可以容纳特定数字的方框。当我找到另一个正方形的解时,我会从该正方形所属的行、列和框中删除刚找到的数字

好了,一切都好。这是我的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()

这是太多的代码,我们无法查看。尽量减少你的代码,直到你找到一个最小的例子,它不能像你期望的那样工作。