回溯在Python中的工作原理
我从Youtube上学习到了这段代码。我通过执行回溯来解决数独问题回溯在Python中的工作原理,python,backtracking,sudoku,Python,Backtracking,Sudoku,我从Youtube上学习到了这段代码。我通过执行回溯来解决数独问题 import pandas as pd import numpy as np raw = pd.read_csv(r'C:\Users\Administrator\Dropbox\Python_Learning\debaisudoku.csv', header = None) sudoku = np.nan_to_num(raw) def possible(x,y,n): # global sudoku f
import pandas as pd
import numpy as np
raw = pd.read_csv(r'C:\Users\Administrator\Dropbox\Python_Learning\debaisudoku.csv', header = None)
sudoku = np.nan_to_num(raw)
def possible(x,y,n):
# global sudoku
for i in range(0,9):
if sudoku[i][y] == n:
return False
for i in range(0,9):
if sudoku[x][i] == n:
return False
x0 = (x//3) * 3
y0 = (y//3) * 3
for i in range(0,3):
for j in range(0,3):
if sudoku[x0+i][y0+j] == n:
return False
return True
def solve():
# global sudoku
for x in range(9):
for y in range(9):
if sudoku[x][y] == 0:
for n in range(1,10):
if possible(x,y,n):
sudoku[x][y] = n
if solve(): return True
sudoku[x][y] = 0
return False
print(sudoku)
solve()
一切都很好,我理解代码,除了以下几行代码:
if possible(x,y,n):
sudoku[x][y] = n
if solve(): return True
sudoku[x][y] = 0
return False
Python如何运行、循环并记住位置,然后继续计算上次使用的数字?顺便说一下,如果可能的话,请告诉我如何在VBA中执行回溯。我试过用if条件下的goto,但没有效果
非常感谢你,我感谢你的回答 在youtube上看了computerphile一集后,我也在VBA内部尝试过 我想如果您想在VBA中“返回”,您需要使用“退出功能”功能 当我在excel表格中使用前9*9单元格作为网格时,这段代码对我起到了作用,在确认消息框后,数独将自动重置,我还不知道为什么会发生这种情况 如果有人知道一个更干净的编码方式,我很高兴知道,希望这能帮助你
Function possible(y, x, n) As Boolean
For i = 1 To 9
If Cells(y, i) = n Then
possible = False
Exit Function
End If
Next i
For i = 1 To 9
If Cells(i, x) = n Then
possible = False
Exit Function
End If
Next i
x0 = ((x - 1) \ 3) * 3
y0 = ((y - 1) \ 3) * 3
For i = 1 To 3
For j = 1 To 3
If Cells(y0 + i, x0 + j) = n Then
possible = False
Exit Function
End If
Next j
Next i
possible = True
End Function
Function solve()
For y = 1 To 9
For x = 1 To 9
If Cells(y, x).Value = 0 Then
For n = 1 To 10
Debug.Print (n)
If n = 10 Then
Exit Function
End If
If possible(y, x, n) = True Then
Cells(y, x).Value = n
solve
Cells(y, x).Value = 0
End If
Next n
End If
Next x
Next y
MsgBox ("solved!")
End Function
Sub solve_sudoku()
solve
End Sub
这就是递归的全部原理。请参阅,…。当函数返回时(例如使用
return False
),执行返回给调用方。调用者就是您有solve()
的地方。如果返回值为False,则将不执行作为条件的If
块,因此执行将继续(而不是重新启动)并使用sudoku[x][y]=0
和循环的的其余迭代。
零只是对应于“移动”的“撤消”操作这显然没有通过递归调用带来解决方案(因为它返回False)。for
循环的下一次迭代需要尝试另一种“移动”,再次启动递归调用。如果该调用也返回False,并且循环没有更多的迭代,那么该函数执行也将向其自己的调用方返回False。它不会向后循环。但是要意识到,函数solve
的每次递归执行都有自己的变量和执行上下文。因此,如果您进行递归调用,该调用将从一开始就为
循环执行自己的。如果它执行返回
,则返回到函数的另一个实例,即进行递归调用的实例。那是在循环的中间,所以它在循环调用之前从循环中继续它的循环。不要混淆不同的循环:递归树中的每一级都有一个循环。是的,我想你知道了。非常感谢。我会尽快测试它,它真的有效。非常感谢你。这里的关键是退出功能