我尝试使用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
。
答案 0 :(得分:1)
您的块检查错误 - 如果您输入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
这不会改变整体错误,但至少会补偿一个错误。
您递归到solve()
而不更改e
- 当前选中的行/列表 - 您的solve()
适用于本地变量{{1您的e
更改全局 checkEmpty()
,更改永远不会反映在e
中。
修正:
solve()
即使您修复了这两个错误:
你需要能够丢弃更早的发现 - 例如。在开始时,一个空间可能可以被9,1,3,4填充 - 你首先检查1 - 宾果游戏 - 把它放进去,但是后来遇到的问题是这个区块中只能持有1的位置。现在1已经发出,你没有解决方案。
你需要计算所有可能的"首先填写所有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
的数字,然后填写只有一种可能性的数字,从相应的行/列/块0
可能性列表中删除该数字并继续,直到所有数字都填入。
底线:使用可用的第一选择来解决它可能会以局部最小值结束,解决12个剩余零中的10个,然后你就被卡住了。