以下递归函数如何工作?

How does the following recursion function work?

我最近观看了 this 视频,该视频展示了解决数独问题的递归函数,这似乎不合理,因为最后我们总是将值改回零。

为什么这个功能在视频中有效,但对我却无效?由于最后我们使用 grid[y][x] = 0 重置网格并丢弃所做的所有更改,网格是否应该对我们双方保持不变?

此代码的想法是遍历每个数字单元格和每个数字 (1-9),并检查是否可能 将数字放入该单元格。如果我们走到死胡同,我们就原路返回。

这是我手动复制的代码:

import numpy as np
global grid
grid = [[5,3,0,0,7,0,0,0,0],
        [6,0,0,1,9,5,0,0,0],
        [0,9,8,0,0,0,0,6,0],
        [8,0,0,0,6,0,0,0,3],
        [4,0,0,8,0,3,0,0,1],
        [7,0,0,0,2,0,0,0,6],
        [0,6,0,0,0,0,2,8,0],
        [0,0,0,4,1,9,0,0,5],
        [0,0,0,0,8,0,0,7,9]]

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

def solve():
    global grid
    for y in range(9):
        for x in range(9):
            if grid[y][x] == 0:
                for n in range(1, 10):
                    if possible(y,x,n):
                        grid[y][x] = n
                        solve()
                        grid[y][x] = 0
                return


print(np.matrix(grid))
print("")
solve()
print(np.matrix(grid))

问题是solve函数确实在执行完后将网格重置回初始状态,但它也解决了数独问题。

在视频中,请注意网格打印在 solve 函数内部,而不是在它之后:

def solve():
    global grid
    for y in range(9):
        for x in range(9):
            if grid[y][x] == 0:
                for n in range(1, 10):
                    if possible(y,x,n):
                        grid[y][x] = n
                        solve()
                        grid[y][x] = 0
                return
    print(np.matrix(grid))

print(np.matrix(grid))
print("")
solve()

这是可行的,因为它循环遍历每个单元格,并且仅在单元格尚未填充值时才递归,然后在尝试每个值后,它 returns。 完成 for y in range(9): 循环的唯一方法是,如果它永远找不到不为 0 的单元格,即如果数独已解决,那么通过在循环完成后打印矩阵,它将确保打印已解决的数独.