下面的递归函数是如何工作的?

Posted

技术标签:

【中文标题】下面的递归函数是如何工作的?【英文标题】:How does the following recursion function work? 【发布时间】:2020-05-18 16:29:05 【问题描述】:

我最近观看了 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))

【问题讨论】:

【参考方案1】:

问题是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()

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

【讨论】:

以上是关于下面的递归函数是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章

递归调用后的代码递归

mysql中的递归调用

postgres中的递归函数

这个 ocaml 递归函数是如何工作的?

使用 C++ 模板函数编译时间递归

这个递归数组置换函数如何在幕后工作?