Python数独回溯问题解决了!但没有回答
我已经正确地做了一个数独回溯解算器。但现在我需要得到解决方案,但出于某种原因,我一直得到原始的数独网格。数独问题有一个独特的解决方案Python数独回溯问题解决了!但没有回答,python,sudoku,Python,Sudoku,我已经正确地做了一个数独回溯解算器。但现在我需要得到解决方案,但出于某种原因,我一直得到原始的数独网格。数独问题有一个独特的解决方案 answer = [] count = 0 def solution(sudoku): global answer global count for y in range(9): for x in range(9): if sudoku[y][x] == 0: # Found an empty gri
answer = []
count = 0
def solution(sudoku):
global answer
global count
for y in range(9):
for x in range(9):
if sudoku[y][x] == 0: # Found an empty grid
for n in range(1, 10):
if isPossible(x, y, n, sudoku):
sudoku[y][x] = n
solution(sudoku) # Recursion here
sudoku[y][x] = 0 # If no solution then reset the grid and go back
solved = False
return sudoku
print("hi look at me")
if count == 0:
answer = list(sudoku)
print(answer)
count += 1
return sudoku
hi = solution(board)
print(answer)
print(hi)
在这个解决方案中,answer=list(sudoku)将把解决方案放在我的全局变量中。还请注意,我使用list()来确保当sudoku参数更改时,全局答案不会更改。我已确保这只发生一次。我理解这种回溯将导致原来的数独板,因为一旦解决了问题,该算法将设置数独[y][x]=0,从而有效地将解决方案归零。但是唯一的解决方案已经存储在answer中,当我尝试在函数之外打印answer时,我会得到原始的未解决的数独板。
那么为什么函数中的“答案”得到了正确的解决方案,而函数外部的“答案”给了我原始的电路板呢?answer=list(数独)只出现一次,list()给了我一个新的list对象,所以即使数独改变了,答案也不会改变,所以改变后怎么能改变呢?经过几个小时的调试,我真的被卡住了。如何将解决方案引入函数之外的内容
完整代码以防万一
board = [
[0, 0, 0, 2, 6, 0, 7, 0, 1],
[6, 8, 0, 0, 7, 0, 0, 9, 0],
[1, 9, 0, 0, 0, 4, 5, 0, 0],
[8, 2, 0, 1, 0, 0, 0, 4, 0],
[0, 0, 4, 6, 0, 2, 9, 0, 0],
[0, 5, 0, 0, 0, 3, 0, 2, 8],
[0, 0, 9, 3, 0, 0, 0, 7, 4],
[0, 4, 0, 0, 5, 0, 0, 3, 6],
[7, 0, 3, 0, 1, 8, 0, 0, 0]
]
def isPossible(x, y, n, sudoku):
if n in sudoku[y]: # Check if in row
return False
for i in range(0, 9):
if n == sudoku[i][x]: # Check if in column
return False
y //= 3
x //= 3
for i in range(y*3, y*3 + 3): # Check if in squares
for j in range(x*3, x*3 + 3):
if n == sudoku[i][j]:
return False
return True
answer = []
count = 0
def solution(sudoku):
global answer
global count
for y in range(9):
for x in range(9):
if sudoku[y][x] == 0: # Found an empty grid
for n in range(1, 10):
if isPossible(x, y, n, sudoku):
sudoku[y][x] = n
solution(sudoku) # Recursion here
sudoku[y][x] = 0 # If no solution then reset the grid and go back
return sudoku
print("hi look at me")
if count == 0:
answer = list(sudoku)
print(answer)
count += 1
return sudoku
hi = solution(board)
print(answer)
print(hi)
问题是你只是做了一个肤浅的董事会副本,所以它会随着更新而不断变化 浅拷贝:
answer = list(sudoku)
一种选择是使用:
在代码中将列表替换为deepcopy后,global将保留答案
今后的问题可能是:
问题是您有一个嵌套的列表结构,
list(sudoku)
只生成一个浅拷贝。内部列表仍然是被后续代码修改的对象。如果需要深度复制,可能需要使用copy
模块的deepcopy
功能:
answer = copy.deepcopy(sudoku)
虽然这可以解决您在成功解决方案上的回溯涂鸦的直接问题,但这并不能改变这样一个事实,即您的解算器将在您已经找到一个解决方案后继续尝试寻找更多的解决方案。为了避免这种情况,您可能需要更改代码,以便在成功与否时,返回的值会发出信号。如果只返回已解决的电路板,或者如果未找到,则返回None
,可以使用该选项在找到解决方案后立即结束搜索。作为奖励,您不再需要使用任何全局变量
下面是它应该是什么样子:
def solution(sudoku): # no more global variables needed
for y in range(9):
for x in range(9):
if sudoku[y][x] == 0:
for n in range(1, 10):
if isPossible(x, y, n, sudoku):
sudoku[y][x] = n
result = solution(sudoku)
if result is not None: # check if the recursion was successful or not
return result # and stop searching if it was!
sudoku[y][x] = 0
return None # signal failure
return sudoku # signal success by returning the board
def solution(sudoku): # no more global variables needed
for y in range(9):
for x in range(9):
if sudoku[y][x] == 0:
for n in range(1, 10):
if isPossible(x, y, n, sudoku):
sudoku[y][x] = n
result = solution(sudoku)
if result is not None: # check if the recursion was successful or not
return result # and stop searching if it was!
sudoku[y][x] = 0
return None # signal failure
return sudoku # signal success by returning the board