[英]How to fix my sudoku solver based on backtracking
我试图使用python并基于回溯来创建数独求解器算法,但它始终不返回任何内容来表示数独不正确。
这是我的代码:
board = [[3,0,6,5,0,8,4,0,0],
[5,2,0,0,0,0,0,0,0],
[0,8,7,0,0,0,0,3,1],
[0,0,3,0,1,0,0,8,0],
[9,0,0,8,6,3,0,0,5],
[0,5,0,0,9,0,6,0,0],
[1,3,0,0,0,0,2,5,0],
[0,0,0,0,0,0,0,7,4],
[0,0,5,2,0,6,3,0,0]]
e = [0, 0]
def checkEmpty():
for i in range(0, 9):
for j in range(0, 9):
if board[i][j] == 0:
e[0] = i
e[1] = j
return True
return False
def vLine(i, test):
for j in range(9):
if board[i][j] == test:
return True
return False
def vColumn(j, test):
for i in range(9):
if board[i][j] == test:
return True
return False
def vBlock(i, j, test):
for I in range(3):
for J in range(3):
if(board[i+I][j + J] == test):
return True
return False
def validMove(i, j, test):
if vColumn(j, test) == False and vBlock(i, j, test) == False and vLine(i, test) == False:
return True
else:
return False
def solve():
e = [0, 0]
if checkEmpty() == False:
return True
i = e[0]
j = e[1]
for k in range(1, 10):
if validMove(i, j, k) == True:
board[i][j] = k
if solve() == True:
return True
board[i][j] = 0
return False
if solve():
print("solved!")
else:
print("No solution exists")
问题在于if函数中的代码if validMove(i, j, k) == True:
似乎永远不会执行。 但是,我无法在此函数中找到任何错误。
另外,我真的不知道该在这里缩进,缩进还是保留此线路board[i][j] = 0
。
您的块检查器是错误的-如果您输入2,2,9,它将不会检查正确的块,但会出现未对齐的情况。
def vBlock(i, j, test):
for I in range(3):
for J in range(3):
if(board[i+I][j + J] == test): # checks 2-5. 2-5 row&col
return True
return False
更改为
def vBlock(i, j, test):
for I in range(3):
for J in range(3):
if(board[i//3+I][j//3 + J] == test): # this way it cecks the blocks correctly
# if you input 2,2,9 it checks 2//3+range == 0+0-3
return True
return False
这不会改变整体误差,但是至少补偿一个误差。
您无需更改当前检查的行/列的e
即可递归到solve()
-您的solve()
在局部变量e
-您的checkEmpty()
更改了全局 e
,更改从未反映在solve()
内部。
固定:
def checkEmpty():
global e # explicitly use the global e
for i in range(0, 9):
for j in range(0, 9):
if board[i][j] == 0:
e[0] = i
e[1] = j
return True
return False
def solve():
global e # explicitly use the global e
if checkEmpty() == False:
return True
i = e[0]
j = e[1]
print(e)
for k in range(1, 10):
if validMove(i, j, k) == True:
board[i][j] = k
if solve() == True:
return True
board[i][j] = 0
return False
即使您修复了这两个错误:
您需要能够丢弃更安全的发现-在开始时一个空间可能可以被9,1、3、4填充-您首先检查1个-宾果游戏-将其放入,但稍后会遇到问题这个只能容纳1个的块。现在将1个分配给您,您将无解。
您需要首先计算所有0
“所有可能”数字,然后填写只有1种可能性的数字,然后从相应的行/列/块0
可能性列表中删除该数字,然后继续进行操作,直到所有数字都填满为止。
底线:使用第一选择方法求解可能会导致您获得解决12个剩余零中的10个的局部最小值,然后陷入困境。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.