Python 有人能解释一下这个回溯算法中的递归吗?
这是一个使用python和回溯算法求解数独板的程序,但我似乎不理解solvebo中的递归。如果不满足条件,则索引将重置为0,并继续在相同位置尝试数字 也许有人能用更简单的术语解释一下,函数是如何回溯和重新检查条件的Python 有人能解释一下这个回溯算法中的递归吗?,python,recursion,backtracking,sudoku,Python,Recursion,Backtracking,Sudoku,这是一个使用python和回溯算法求解数独板的程序,但我似乎不理解solvebo中的递归。如果不满足条件,则索引将重置为0,并继续在相同位置尝试数字 也许有人能用更简单的术语解释一下,函数是如何回溯和重新检查条件的 board = [ [7,8,0,4,0,0,1,2,0], [6,0,0,0,7,5,0,0,9], [0,0,0,6,0,1,0,7,8], [0,0,7,0,4,0,2,6,0], [0,0,1,0,5,0,9,3,0], [9,
board = [
[7,8,0,4,0,0,1,2,0],
[6,0,0,0,7,5,0,0,9],
[0,0,0,6,0,1,0,7,8],
[0,0,7,0,4,0,2,6,0],
[0,0,1,0,5,0,9,3,0],
[9,0,4,0,6,0,0,0,5],
[0,7,0,3,0,0,0,1,2],
[1,2,0,0,0,7,4,0,0],
[0,4,9,2,0,6,0,0,7]
]
def solve(bo):
find = find_empty(bo)
if not find:
return True
else:
row, col = find
for i in range(1,10):
if valid(bo, i, (row, col)):
bo[row][col] = i
if solve(bo):
return True
bo[row][col] = 0
return False
def valid(bo, num, pos):
# Check row
for i in range(len(bo[0])):
if bo[pos[0]][i] == num and pos[1] != i:
return False
# Check column
for i in range(len(bo)):
if bo[i][pos[1]] == num and pos[0] != i:
return False
# Check box
box_x = pos[1] // 3
box_y = pos[0] // 3
for i in range(box_y*3, box_y*3 + 3):
for j in range(box_x * 3, box_x*3 + 3):
if bo[i][j] == num and (i,j) != pos:
return False
return True
def print_board(bo):
for i in range(len(bo)):
if i % 3 == 0 and i != 0:
print("- - - - - - - - - - - - - ")
for j in range(len(bo[0])):
if j % 3 == 0 and j != 0:
print(" | ", end="")
if j == 8:
print(bo[i][j])
else:
print(str(bo[i][j]) + " ", end="")
def find_empty(bo):
for i in range(len(bo)):
for j in range(len(bo[0])):
if bo[i][j] == 0:
return (i, j) # row, col
return None
print_board(board)
solve(board)
print("___________________")
print_board(board)
对!!因此,这个解决方案的操作方式是找到电路板上的下一个空字段,尝试在其中插入范围为1..9的数字,然后检查有效性。有效性检查是对给定数字是否正确的初步回答,即是否不违反规则。如果是这样,则将数字插入数组中,并递归调用solve。现在,隐式回溯正在发生。如果这个递归的solve调用未能产生一个完全一致的谜题解决方案,那么从我们的试探性猜测开始的整个分支将从调用堆栈中移除,失败的猜测将在移除的板上重置,我们继续下一个猜测。所以基本上整个解决方案分支都是这个初步猜测的一部分?而且我仍然不明白它是如何继续使用其他可能的解决方案的。重置为0似乎是从一个全新的开始使用整个求解方法。此外,程序如何知道解决方案是否已经过测试。首先,重置为零并不意味着重新开始。请记住,我们仍然处于要求解的某个递归调用的上下文中,因此我们从错误的猜测中回溯到下一个猜测。至于跟踪进度,程序不知道测试猜测的历史,而是组织递归调用的层次结构,以便它们跨越整个组合空间。该程序在该空间中的运行使我们逐渐接近正确答案。与此算法类似的是:在国际象棋中,一名棋手思考了几步,然后如果该序列最终失败,他/她将恢复到当前状态,并继续进行其他可能的移动。。。这是一个不精确的类比,因为在数独游戏中,一旦你达到它,很容易发现不一致,而在国际象棋中,为了实现你的长期目标,你可能准备好面对一些明显的局部劣势。但在某种意义上,这是相似的。