Python 回溯数独并将所有可能的答案保存在列表中

Python 回溯数独并将所有可能的答案保存在列表中,python,backtracking,sudoku,Python,Backtracking,Sudoku,我想用回溯法保存数独的所有可能答案 但补充的答案和数独问题一样。 但是,当我在“列表”后面添加“网格”时,它就可以了。我怎样才能解决这个问题 def backtrack(grid,x,y,alist): if x == 9: alist.append(grid) print(grid) return alist v = grid[x][y] if v == 0: for i in range(1,10)

我想用回溯法保存数独的所有可能答案 但补充的答案和数独问题一样。 但是,当我在“列表”后面添加“网格”时,它就可以了。我怎样才能解决这个问题

def backtrack(grid,x,y,alist):
    if x == 9:

        alist.append(grid)
        print(grid)
        return alist

    v = grid[x][y]

    if v == 0:
        for i in range(1,10):

            check = True
            if i in grid[x]:
                check = False
                continue
            for row in range(0,9):
                if i == grid[row][y]:
                    check = False
                    continue

            for row in range(3*(x//3),3*(x//3)+3):
                for col in range(3*(y//3),3*(y//3)+3):
                    if i == grid[row][col]:
                        check = False
                        continue
            if check == True:
                grid[x][y]= i
                if y < 8:
                    backtrack(grid,x,y+1,alist)

                else:
                    backtrack(grid,x+1,0,alist)
        grid[x][y] = 0
        return alist
    else:
        if y< 8:
            backtrack(grid,x,y+1,alist)
        else:
            backtrack(grid,x+1,0,alist)

        return alist


problem = [[4, 0, 3, 0, 2, 0, 6, 0, 0],
                          [9, 6, 0, 3, 0, 0, 0, 0, 0],
                          [2, 0, 1, 8, 0, 6, 0, 9, 0],
                          [0, 0, 8, 1, 0, 2, 9, 0, 0],
                          [7, 2, 0, 0, 6, 0, 0, 0, 8],
                          [0, 0, 6, 7, 0, 8, 2, 0, 0],
                          [0, 0, 2, 6, 0, 9, 5, 0, 0],
                          [8, 0, 0, 2, 0, 3, 0, 0, 9],
                          [0, 0, 5, 0, 1, 0, 3, 0, 0]]
alist = []
for a in backtrack(problem,0,0,alist):
    print(a)
def回溯(栅格、x、y、alist):
如果x==9:
alist.append(网格)
打印(网格)
返回列表
v=网格[x][y]
如果v==0:
对于范围(1,10)内的i:
检查=正确
如果我在网格[x]中:
检查=错误
持续
对于范围(0,9)中的行:
如果i==grid[row][y]:
检查=错误
持续
对于范围(3*(x//3)、3*(x//3)+3)中的行:
对于范围(3*(y//3),3*(y//3)+3中的列:
如果i==grid[row][col]:
检查=错误
持续
如果check==True:
网格[x][y]=i
如果y<8:
回溯(栅格、x、y+1、alist)
其他:
回溯(栅格,x+1,0,alist)
网格[x][y]=0
返回列表
其他:
如果y<8:
回溯(栅格、x、y+1、alist)
其他:
回溯(栅格,x+1,0,alist)
返回列表
问题=[[4,0,3,0,2,0,6,0,0],
[9, 6, 0, 3, 0, 0, 0, 0, 0],
[2, 0, 1, 8, 0, 6, 0, 9, 0],
[0, 0, 8, 1, 0, 2, 9, 0, 0],
[7, 2, 0, 0, 6, 0, 0, 0, 8],
[0, 0, 6, 7, 0, 8, 2, 0, 0],
[0, 0, 2, 6, 0, 9, 5, 0, 0],
[8, 0, 0, 2, 0, 3, 0, 0, 9],
[0, 0, 5, 0, 1, 0, 3, 0, 0]]
alist=[]
对于回溯中的a(问题,0,0,alist):
印刷品(a)
代替注释:

你对“继续”的使用很奇怪

        if i in grid[x]:
            check = False
            continue  # here we break out to the next value of i
        for row in range(0,9):
            if i == grid[row][y]:
                check = False
                continue  # here we move to the next value of 'row' 
                          # which we would do anyway
我想这意味着在很多情况下你会继续

return alist
在你想之前


我唯一的另一个评论是,函数返回'alist',但在递归中,您从未使用该值(可能您依赖于append?我不清楚)

我添加了第二个答案,因为我现在确实发现了问题。尽管我坚持我之前的评论,你使用continue是很奇怪的

考虑变量
grid
,因为这是一个对象的python,当您找到解决方案时,您会将
grid
附加到
alist
中,但因为python列表是可变的(我认为这是一个正确的术语),当您稍后调用
grid[x][y]=0时,您会更改对象网格,在列表的第一个位置引用

请尝试以下代码:

grid = [[4, 0, 3, 0, 2, 0, 6, 0, 0],
                      [9, 6, 0, 3, 0, 0, 0, 0, 0],
                      [2, 0, 1, 8, 0, 6, 0, 9, 0],
                      [0, 0, 8, 1, 0, 2, 9, 0, 0],
                      [7, 2, 0, 0, 6, 0, 0, 0, 8],
                      [0, 0, 6, 7, 0, 8, 2, 0, 0],
                      [0, 0, 2, 6, 0, 9, 5, 0, 0],
                      [8, 0, 0, 2, 0, 3, 0, 0, 9],
                      [0, 0, 5, 0, 1, 0, 3, 0, 0]]

alist = [grid, grid, grid]

grid[0][0] = "hello"
print alist
列表中的每个网格都已修改

相反,您可以创建栅格对象的副本,并将该副本附加到列表中,以查看选项。例如:

import copy

...

...alist.append(copy.deepcopy(grid))

copy.copy
似乎不起作用,可能是因为您使用的是带列表的列表,而不是numpy数组或类似的东西。

我使用continue,因为我不符合数独的限制。在行、列或正方形中不应该有相同的数字。我不认为它在做你认为它是做的事情,但这似乎不是主要问题-我已经添加了第二个答案,现在我已经知道了到底发生了什么。