Python 如何停止递归并返回答案?

Python 如何停止递归并返回答案?,python,python-3.x,recursion,return,Python,Python 3.x,Recursion,Return,这是一个数独解算器函数,我有两个问题: import numpy as np def possible(y, x, n): global sudoku for i in range(9): if sudoku[y][i] == n: return False for i in range(9): if sudoku[i][x] == n: return False x0 = (x /

这是一个数独解算器函数,我有两个问题:

import numpy as np

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


def solve():
    global sudoku
    for y in range(9):
        for x in range(9):
            if sudoku[y][x] == 0:
                for n in range(1, 10):
                    if possible(y, x, n):
                        sudoku[y][x] = n
                        solve()
                        sudoku[y][x] = 0
                return
    print("solution:\n", np.matrix(sudoku))
    return sudoku # (This is what I have trid)


sudoku = [[0, 0, 0, 0, 7, 0, 0, 0, 0],
          [0, 0, 6, 0, 0, 0, 7, 0, 0],
          [2, 0, 0, 8, 0, 3, 0, 0, 5],
          [0, 0, 8, 0, 0, 0, 5, 0, 0],
          [0, 2, 0, 4, 0, 9, 0, 3, 0],
          [9, 0, 0, 6, 0, 7, 0, 0, 2],
          [5, 0, 9, 0, 0, 0, 3, 0, 8],
          [0, 0, 3, 0, 0, 0, 9, 0, 0],
          [0, 7, 0, 9, 0, 4, 6, 5, 0]]
solve()
print("solution:\n", np.matrix(sudoku))
  • 为什么要打印原始数独

     # This is the 1st print:
     solution:
      [[3 5 4 1 7 6 2 8 9]
      [1 8 6 2 9 5 7 4 3]
      [2 9 7 8 4 3 1 6 5]
      [4 6 8 3 1 2 5 9 7]
      [7 2 1 4 5 9 8 3 6]
      [9 3 5 6 8 7 4 1 2]
      [5 4 9 7 6 1 3 2 8]
      [6 1 3 5 2 8 9 7 4]
      [8 7 2 9 3 4 6 5 1]]
    
     # This is the 2nd print:
     solution:
      [[0 0 0 0 7 0 0 0 0]
      [0 0 6 0 0 0 7 0 0]
      [2 0 0 8 0 3 0 0 5]
      [0 0 8 0 0 0 5 0 0]
      [0 2 0 4 0 9 0 3 0]
      [9 0 0 6 0 7 0 0 2]
      [5 0 9 0 0 0 3 0 8]
      [0 0 3 0 0 0 9 0 0]
      [0 7 0 9 0 4 6 5 0]]
    
  • 我如何获得数独解决方案(而不是打印它),因为我想重用该解决方案。(我尝试过使用
    返回数独
    ,但没有得到
    结果


  • 谢谢:)

    也许它并不优雅,但我使用全局列表“所有解决方案”并附加重复的解决方案

    solution = copy.deepcopy(sudoku)
    all_solutions.append(solution)
    
    它适用于你的例子。但我还是不确定你的代码是否正确



    使用
    return
    而不是全局变量也一样

    因为
    solve()
    返回解决方案列表,所以它还必须
    将[solution]
    作为列表返回

    import numpy as np
    import copy
    
    def possible(y, x, n):
    
        for i in range(9):
            if sudoku[y][i] == n:
                return False
                
        for i in range(9):
            if sudoku[i][x] == n:
                return False
                
        x0 = (x // 3) * 3
        y0 = (y // 3) * 3
        
        for i in range(3):
            for j in range(3):
                if sudoku[y0 + i][x0 + j] == n:
                    return False
                    
        return True
    
    
    def solve():
        
        all_solutions = []
        
        for y in range(9):
            for x in range(9):
                if sudoku[y][x] == 0:
                    for n in range(1, 10):
                        if possible(y, x, n):
                            sudoku[y][x] = n
                            all_solutions += solve()
                            sudoku[y][x] = 0
                    return all_solutions
                    
        print("solution:\n", np.matrix(sudoku))
    
        solution = copy.deepcopy(sudoku)
    
        #return all_solutions + [solution]
        return [solution]
    
    
    sudoku = [[0, 0, 0, 0, 7, 0, 0, 0, 0],
              [0, 0, 6, 0, 0, 0, 7, 0, 0],
              [2, 0, 0, 8, 0, 3, 0, 0, 5],
              [0, 0, 8, 0, 0, 0, 5, 0, 0],
              [0, 2, 0, 4, 0, 9, 0, 3, 0],
              [9, 0, 0, 6, 0, 7, 0, 0, 2],
              [5, 0, 9, 0, 0, 0, 3, 0, 8],
              [0, 0, 3, 0, 0, 0, 9, 0, 0],
              [0, 7, 0, 9, 0, 4, 6, 5, 0]]
    
    all_solutions = solve()
    
    if all_solutions:
        print("solution:\n", np.matrix(all_solutions[0]))
    

    问题是递归一直在进行,这会重置由于行
    数独[y][x]=0
    而产生的谜题

    要停止第一个解决方案的递归,您需要某种标志来指示谜题已解决。一种方法是返回
    True
    (如果是)

    def solve():
        ...
        return True  # All cells are filled, so it's solved
    
    然后,您需要从递归调用中捕获并返回:

    def solve():
        ...
            if possible(y, x, n):
                sudoku[y][x] = n
                solved = solve()
                if solved:
                    return True  # Recursive return on first solution
                sudoku[y][x] = 0
        ...
    
    然后您可以从内部
    solve()
    移除
    print()
    ,您将从外部
    print()
    获得正确的输出

    顺便说一句,这个问题与之类似,只是你正在变异一个全局(
    sudoku


    顺便说一句:

    • 不需要
      全局
      声明,因为您从不重新分配
      数独
      ,只需对其进行变异即可

    • 只需打印每一行,即可删除对
      numpy
      的依赖关系:

      print("solution:")
      for row in sudoku:
          print(*row)
      
    • 可以使用折叠两个嵌套for循环,例如:

      for y, x in product(range(9), repeat=2):
      

    如果有多个解决方案怎么办?您只想要第一个吗?您应该在
    solve()
    中使用
    returnresult
    将其发送回上一级-和
    result=solve()
    在上一级中获取它,并使用此
    结果创建新结果,然后将其发送到上一级中的另一个级别。您获得原始数独,因为在
    解算
    中,您使用
    数独[y][x]=0
    将其设置回原始值。您将值放在
    0
    的位置,然后再放回
    0
    ,但您从未检查是否已填充所有位置,以及它们是否正确填充-因此您从未检查是否已解析数独。当你们检查你们是否解数独时,你们应该显示解或者把它保存在分开的矩阵中(或者所有正确矩阵的列表)@wjandrea我更新我的输出。多个解决方案也可以。(如果我可以重用Solotion)Thanks@wjandrea谢谢只要第一个解决方案就可以了。那么如何获得第一个解决方案并退出递归。谢谢。它对我有效:)我添加了使用
    return
    而不是全局变量的版本。非常清楚,非常感谢:)
    solution:
    3 5 4 1 7 6 2 8 9
    1 8 6 2 9 5 7 4 3
    2 9 7 8 4 3 1 6 5
    4 6 8 3 1 2 5 9 7
    7 2 1 4 5 9 8 3 6
    9 3 5 6 8 7 4 1 2
    5 4 9 7 6 1 3 2 8
    6 1 3 5 2 8 9 7 4
    8 7 2 9 3 4 6 5 1
    
    for y, x in product(range(9), repeat=2):