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):