Python递归数独解算器不';不要返回解决方案

Python递归数独解算器不';不要返回解决方案,python,numpy,sudoku,Python,Numpy,Sudoku,我试图优化代码,最终的代码如下所示 将numpy导入为np 数独=np.数组([[0,9,0,0,0,5,0,6,0,8], [0, 0, 0, 7, 1, 0, 3, 5, 0], [2, 1, 0, 0, 0, 0, 7, 0, 4], [0, 0, 1, 5, 0, 0, 0, 0, 6], [6, 3, 0, 2, 0, 8, 0, 4, 5], [7, 0, 0, 0, 0, 4, 9, 0, 0], [9, 0, 3, 0, 0, 0, 0, 2, 1], [0, 4, 8, 0,

我试图优化代码,最终的代码如下所示

将numpy导入为np
数独=np.数组([[0,9,0,0,0,5,0,6,0,8],
[0, 0, 0, 7, 1, 0, 3, 5, 0],
[2, 1, 0, 0, 0, 0, 7, 0, 4],
[0, 0, 1, 5, 0, 0, 0, 0, 6],
[6, 3, 0, 2, 0, 8, 0, 4, 5],
[7, 0, 0, 0, 0, 4, 9, 0, 0],
[9, 0, 3, 0, 0, 0, 0, 2, 1],
[0, 4, 8, 0, 2, 7, 0, 0, 0],
[5, 0, 6, 0, 8, 0, 0, 3, 0]])
#检查数字(n)是否可以放在那里(行、列)
def检查(数独、行、列、n):
#行检查
如果np.sum(数独[row,:]==n)!=0:返回False;
#Col检查
如果np.sum(数独[:,列]==n)!=0:返回False;
#Sqr检查
行0,列0=(行//3)*3,(列//3)*3
如果np.sum(数独[row0:row0+3,col0:col0+3]==n)!=0:返回False;
返回真值
def solve_数独(数独):
行,cols=np.where(数独==0)
对于行中的行:
对于col中的col:
对于范围(1,10)中的num:
如果选中(数独、行、列、数):
数独[行,列]=num
解数独(数独)
数独[行,列]=0
返回
打印(数独)
返回数独
已解决=求解数独(数独)
我的问题是,即使解决方案如下图所示成功打印,变量solved也只是一个非类型,不存储任何内容

[[3 9 7 4 5 2 6 1 8]
[8 6 4 7 1 9 3 5 2]
[2 1 5 8 3 6 7 9 4]
[4 8 1 5 9 3 2 7 6]
[6 3 9 2 7 8 1 4 5]
[7 5 2 1 6 4 9 8 3]
[9 7 3 6 4 5 8 2 1]
[1 4 8 3 2 7 5 6 9]
[5 2 6 9 8 1 4 3 7]]

函数打印解决方案,但不返回任何内容。如何存储打印的解决方案?

问题在您的代码中:

                    solve_sudoku(sudoku)
                    sudoku[row, col] = 0
            return
在第一行中,重复执行,但忽略返回值,这将丢弃该调用的任何返回值及其下的所有递归

在最后一行中,返回
None
上的默认值。这两种方法都会破坏递归返回值的连续性。

当使用完全填充的数独数组(其中一个没有任何剩余零)而不是在顶级递归调用中调用
solve\u sudoku
时,会发生
print(sudoku)
调用


每次使用不完整的数独数组调用
solve\u sudoku
时,您都要测试最左上角零填充单元格中1到10之间的每个数字,如果该数字可以放在单元格中,则将其放在该单元格中,尝试解算网格的其余部分,然后将单元格设置回零。对1到10之间的每个数字执行此操作后,将返回
None
,这就是为什么您会看到顶级
solve\u sudoku
调用返回的
None

几个小时后,我想出了此解决方案已解决立即存储解决方案

将numpy导入为np
数独=np.数组([[0,9,0,0,0,5,0,6,0,8],
[0, 0, 0, 7, 1, 0, 3, 5, 0],
[2, 1, 0, 0, 0, 0, 7, 0, 4],
[0, 0, 1, 5, 0, 0, 0, 0, 6],
[6, 3, 0, 2, 0, 8, 0, 4, 5],
[7, 0, 0, 0, 0, 4, 9, 0, 0],
[9, 0, 3, 0, 0, 0, 0, 2, 1],
[0, 4, 8, 0, 2, 7, 0, 0, 0],
[5, 0, 6, 0, 8, 0, 0, 3, 0]])
已解决=np.zeros_like(数独)
def检查(参数、行、列、n):
如果np.sum(arg[行,:]==n)!=0:返回False;
如果np.sum(arg[:,col]==n)!=0:返回False;
行0,列0=(行//3)*3,(列//3)*3
如果np.sum(arg[row0:row0+3,col0:col0+3]==n)!=0:返回False;
返回真值
def solve_数独(arg):
全球解决
行,cols=np。其中(arg==0)
对于行中的行:
对于col中的col:
对于范围(1,10)中的num:
如果选中(arg、row、col、num):
arg[行,列]=num
求解数独(arg)
arg[行,列]=0
返回
已解决=arg.copy()
解数独(数独)
我不知道这是否是优化代码的最佳方式,欢迎反馈

def check(grid, num, x, y):
    for i in range(9):
        if grid[i][y] == num:
            return False
    for j in range(9):
        if grid[x][j] == num:
            return False
    x0 = (x//3) * 3
    y0 = (y//3) * 3
    for i in range(3):
        for j in range(3):
            if grid[x0+i][y0+j] == num:
                return False
    return True

def solve(grid):
    for i in range(9 + 1):
        if i==9:
            return True
        for j in range(9):
            if grid[i][j] == 0:
                for num in range(1,10):
                    if check(grid, num, i, j):
                        grid[i][j] = num
                        if solve(grid):
                            return True
                        grid[i][j] = 0
                return False
这应该对你有用。它不返回数组,而是修改它。所以如果你通过了

solve(sudoku_grid) 
然后打印数独网格,它将为您提供已解决的输出

if check(sudoku, row, col, num):
                sudoku[row, col] = num
                solve_sudoku(sudoku)
                sudoku[row, col] = 0
在特定的循环中,“求解数独(sudoku)”将得到解。当你得到你的解决方案,你应该立即停止回溯返回或打破循环。否则,下一行“数独[row,col]=0”将取消您以前的尝试,并继续检查下一个可能的数字。因为索多库只有一个解决方案,所以不必继续检查下一个数字。您可以只返回一个真值来结束循环。例如,您可以这样编写代码 如果求解数独(数独)=真:
返回True

您需要使用递归调用的结果来求解数独并检查游戏是否在该点完成。