5 回答

TA貢獻(xiàn)1802條經(jīng)驗(yàn) 獲得超4個(gè)贊
考慮這段代碼:
if check(sudoku, row, col, num): sudoku[row, col] = num solve_sudoku(sudoku) sudoku[row, col] = 0 # undo this move
如果數(shù)獨(dú)是可解的,則solve_sudoku(sudoku)
調(diào)用最終會(huì)找到解決方案。當(dāng)你得到解決方案時(shí),你應(yīng)該立即停止使用 進(jìn)行回溯return
。否則,下一行將sudoku[row, col] = 0
撤消您找到的解決方案,并進(jìn)一步迭代繼續(xù)嘗試下一個(gè)可能的數(shù)字。由于數(shù)獨(dú)只有一個(gè)解,因此沒(méi)有必要在找到解后檢查更多的數(shù)字。您可以只返回一個(gè)真值來(lái)結(jié)束遞歸。
例如,您可以這樣編寫代碼:
if solve_sudoku(sudoku): return True
或者
if solve_sudoku(sudoku): return sudoku
這可以防止sudoku[row, col] = 0
擦除解決方案并最終在遞歸調(diào)用堆棧展開后將解決的網(wǎng)格返回給初始調(diào)用者。

TA貢獻(xiàn)1872條經(jīng)驗(yàn) 獲得超4個(gè)贊
def check(grid, num, x, y):
for i in range(9):
if grid[i][y] == num:
return False
for j in range(9):
if grid[x][j] == num:
return False
x0 = (x//3) * 3
y0 = (y//3) * 3
for i in range(3):
for j in range(3):
if grid[x0+i][y0+j] == num:
return False
return True
def solve(grid):
for i in range(9 + 1):
if i==9:
return True
for j in range(9):
if grid[i][j] == 0:
for num in range(1,10):
if check(grid, num, i, j):
grid[i][j] = num
if solve(grid):
return True
grid[i][j] = 0
return False
這應(yīng)該對(duì)你有用。它不返回?cái)?shù)組,而是修改它。所以如果你通過(guò)了
solve(sudoku_grid)
然后打印 sudoku_grid 它會(huì)給你解決的輸出

TA貢獻(xiàn)1765條經(jīng)驗(yàn) 獲得超5個(gè)贊
當(dāng)使用完全填充的數(shù)獨(dú)數(shù)組(沒(méi)有任何剩余零)調(diào)用時(shí),而不是在頂級(jí)遞歸調(diào)用中,會(huì)print(sudoku)
發(fā)生該調(diào)用。solve_sudoku
每次solve_sudoku
使用不完整的數(shù)獨(dú)數(shù)組調(diào)用時(shí),您都在左上角的零填充單元格中測(cè)試從一到十之間的每個(gè)數(shù)字,如果該數(shù)字可以放置在該單元格中,則將其放置在那里,嘗試解決其余的問(wèn)題網(wǎng)格,然后將單元格設(shè)置回零。一旦您對(duì) 1 到 10 之間的每個(gè)數(shù)字執(zhí)行此操作,您就會(huì)返回None
,這就是您看到None
從頂級(jí)solve_sudoku
調(diào)用返回的原因。

TA貢獻(xiàn)1946條經(jīng)驗(yàn) 獲得超3個(gè)贊
import numpy as np
sudoku = np.array([[0, 9, 0, 0, 5, 0, 6, 0, 8],
? ? ? ? ? ? ? ? ? ?[0, 0, 0, 7, 1, 0, 3, 5, 0],
? ? ? ? ? ? ? ? ? ?[2, 1, 0, 0, 0, 0, 7, 0, 4],
? ? ? ? ? ? ? ? ? ?[0, 0, 1, 5, 0, 0, 0, 0, 6],
? ? ? ? ? ? ? ? ? ?[6, 3, 0, 2, 0, 8, 0, 4, 5],
? ? ? ? ? ? ? ? ? ?[7, 0, 0, 0, 0, 4, 9, 0, 0],
? ? ? ? ? ? ? ? ? ?[9, 0, 3, 0, 0, 0, 0, 2, 1],
? ? ? ? ? ? ? ? ? ?[0, 4, 8, 0, 2, 7, 0, 0, 0],
? ? ? ? ? ? ? ? ? ?[5, 0, 6, 0, 8, 0, 0, 3, 0]])
solved = np.zeros_like(sudoku)
def check(arg, row, col, n):
? ? if np.sum(arg[row,:] == n) != 0: return False;
? ? if np.sum(arg[:,col] == n) != 0: return False;
? ? row0, col0 = (row//3)*3, (col//3)*3
? ? if np.sum(arg[row0:row0+3,col0:col0+3] == n) != 0: return False;
? ? return True
def solve_sudoku(arg):
? ? global solved
? ? rows, cols = np.where(arg == 0)
? ? for row in rows:
? ? ? ? for col in cols:
? ? ? ? ? ? for num in range(1, 10):
? ? ? ? ? ? ? ? if check(arg, row, col, num):
? ? ? ? ? ? ? ? ? ? arg[row, col] = num
? ? ? ? ? ? ? ? ? ? solve_sudoku(arg)
? ? ? ? ? ? ? ? ? ? arg[row, col] = 0
? ? ? ? ? ? return
? ? solved = arg.copy()
solve_sudoku(sudoku)
我不知道這是否是優(yōu)化代碼的最佳方式,歡迎反饋。

TA貢獻(xiàn)1859條經(jīng)驗(yàn) 獲得超6個(gè)贊
問(wèn)題出在您的代碼中:
solve_sudoku(sudoku) sudoku[row, col] = 0 return
在第一行中,您進(jìn)行遞歸,但忽略返回值,這會(huì)丟棄該調(diào)用及其下面的所有遞歸的任何返回值。
在最后一行中,您返回 的默認(rèn)值None
。其中任何一個(gè)都會(huì)破壞遞歸返回值的連續(xù)性。
添加回答
舉報(bào)