打印工作,但使用回溯解决数独时返回值为 None

Posted

技术标签:

【中文标题】打印工作,但使用回溯解决数独时返回值为 None【英文标题】:Print works but return value is None when using backtracking to solve a sudoku 【发布时间】:2020-02-26 10:25:27 【问题描述】:

我编写了以下代码来使用回溯方法解决数独游戏。可以打印正确的结果,但我还没有找到一种方法来获得与返回值相同的结果而不是打印它。我必须如何更改程序才能使其正常工作?

import numpy as np

def find_possible(sudoku,r,c):
    """returns the possible Values as numpy array for a given position"""
    position = sudoku[r, c]
    if position == 0:
        line = sudoku[r, :]
        column = sudoku[: ,c]
        r0 = (r//3)*3
        c0 = (c//3)*3
        square = sudoku[r0:r0+3,c0:c0+3]
        numbers = np.arange(1, 10)
        blocked_numbers = np.unique(np.append(np.append(line,column),square))
        return np.setdiff1d(numbers,blocked_numbers)
    else: return np.array([])

def backtrack(sudoku):
    """solve the game with the backtracking method"""
    for r in range(9):
        for c in range(9):
            list_of_possible = find_possible(sudoku,r, c)
            if sudoku[r,c] == 0:
                for i in range(len(list_of_possible)):
                    sudoku[r,c] = list_of_possible[i]
                    backtrack(sudoku)
                    sudoku[r,c] = 0
                return

    result = sudoku
    print(result)

table = np.array([[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]])

backtrack(table)

编辑

如果将print 替换为return,则返回值仍为None,因为第一个return。而如果我给第一个return数独矩阵的值,输出的不是最终结果

【问题讨论】:

【参考方案1】:

您没有将结果“沿轨道返回”传递给 backtrack 函数的原始调用。 (结果意味着数独已解决。)您的 print 有效,因为您恰好到达该行一次:当您的 for 循环在没有零之后完成时。但是,解决问题并不止于此,backtrack 调用的“树”还在继续。您可以通过查看table 来验证这一点:在某些时候它已被完全解决(没有留下零),但如果您在最后打印它,那里将再次出现零。

通过以下更改,您的函数要么返回None(就像你以前一样,我只是添加了None 以明确表示)或sudoku 中的已解决数独。在for 循环中,result 存储了对backtrack 的调用结果,我们可以测试结果是否为None(我们必须继续解决)或者我们已经完成并且可以返回@987654333 @(可以是之前的backtrack调用,也可以是函数外的原始调用)。

def backtrack(sudoku):
    """solve the game with the backtracking method"""
    for r in range(9):
        for c in range(9):
            list_of_possible = find_possible(sudoku, r, c)
            if sudoku[r, c] == 0:
                for i in range(len(list_of_possible)):
                    sudoku[r, c] = list_of_possible[i]
                    result = backtrack(sudoku)
                    if result is not None:
                        return result
                    sudoku[r, c] = 0
                return None
    return sudoku

顺便说一句,result 名称只是对与sudoku 相同的对象的另一个引用。我认为这可能有助于了解正在发生的事情,但您并不真正需要它:

def backtrack(sudoku):
    """solve the game with the backtracking method"""
    for r in range(9):
        for c in range(9):
            list_of_possible = find_possible(sudoku, r, c)
            if sudoku[r, c] == 0:
                for i in range(len(list_of_possible)):
                    sudoku[r, c] = list_of_possible[i]
                    if backtrack(sudoku) is not None:
                        return sudoku
                    sudoku[r, c] = 0
                return None
    return sudoku

另外,尝试开始使用 Pylint 或 flake8 之类的 linter,它会稍微分析您的代码以进行一些改进。例如,在 Python 中,而不是

for i in range(len(list_of_possible)):

你可以写

for possible in list_of_possible:

【讨论】:

【参考方案2】:

您需要使用return 语句。代替print(result),使用return result

【讨论】:

不幸的是,它并不那么容易。如果我将print 替换为return,则返回值仍然是None,因为第一个return。如果我给第一个return 数独谜题的值,我不会得到最终结果

以上是关于打印工作,但使用回溯解决数独时返回值为 None的主要内容,如果未能解决你的问题,请参考以下文章

为啥我使用回溯解决数独的 JAVA 代码没有给出任何解决方案? [关闭]

python中数独的回溯算法

具有回溯的数独求解器不能总是检测到多个解决方案

保存结果数独回溯

数独回溯 无效数独

如何通过回溯和递归解决数独?