我最近发布了几个问题来理解递归和回溯,我觉得我现在得到了一些东西,并试图编写测试,我确实解决了数独问题,但是当我用其他格式编写代码时,代码卡住一段时间并返回False,表示此问题无法解决。
grid是一个9x9的列表列表,如果list [i] [j]为零则表示需要填写。
以下是解决问题的代码:
def correct_solve(grid):
# if there is no more zeros
if found_solution(grid):
return True
for row in xrange(9):
for col in xrange(9):
if grid[row][col] == 0:
for num in xrange(1, 10):
grid[row][col] = num
if check_sudoku(grid) == True:
if correct_solve(grid) == True:
return True
# there are no numbers which could make
# a valid solution, so backtrack
grid[row][col] = 0
return False
这是另一个我尝试以不同的方式解决问题的功能,但它失败了,我找不到问题在哪里
def buggy_solve(grid, col):
# if there is no more zeros
if found_solution(grid):
return True
# if the col is over 8, make it to 0
if col > 8:
col = 0
for row in xrange(9):
if grid[row][col] == 0:
for num in xrange(1, 10):
grid[row][col] = num
if check_sudoku(grid) == True:
# I tend to move to the next cell, and it seems that
# this is correct.
if buggy_solve(grid, col + 1) == True:
return True
# if there are no valid solutions, backtrack.
grid[row][col] = 0
return False
我试图调试程序并没有发现任何有用的东西,顺便说一下有什么好的做法来调试一段递归代码吗?
修改
这是我用来测试的矩阵:
easy = [[2,9,0,0,0,0,0,7,0],
[3,0,6,0,0,8,4,0,0],
[8,0,0,0,4,0,0,0,2],
[0,2,0,0,3,1,0,0,7],
[0,0,0,0,8,0,0,0,0],
[1,0,0,9,5,0,0,6,0],
[7,0,0,0,9,0,0,0,1],
[0,0,1,2,0,0,3,0,6],
[0,3,0,0,0,0,0,5,9]]
答案 0 :(得分:1)
correct_solve
查看所有网格,而buggy_solve
查看单个列。这意味着,如果问题尚未解决,buggy_solve
只会在当前列中查找要填充的单元格 - 如果该列没有碰巧有空单元格,它将脱离外部for循环并退出,而不使用显式return
语句。因此,当发生这种情况时,您需要使用代码在下一列调用buggy_solve
(并使用相应的return
语句)。
答案 1 :(得分:0)
问题是你的递归解决方案永远不会开始回溯。相反,它将最终进行无休止的递归,除非它意外地找到解决方案 - 这是非常不可能的,只适用于大多数解决的sudokus。把这些情况拿出来,这就是正在发生的事情:
if buggy_solve(grid, col + 1) == True:
return True
此buggy_solve
来电永远不会返回false。因为该函数将在必要时继续尝试并迭代列。当它到达最后一列时,它将再次从第一列开始,覆盖之前发生的所有事情。
因此,回溯将永远不会开始。 check_sudoku
很少会失败,因为我们还处于早期处理过程中,而且大多数未填充的数据可能会允许给定单元格中的多个值。
您要做的是阻止buggy_solve
从头开始,即删除列重置并使其仅对无效列返回false。那样buggy_solve
将在某个时刻返回false,并且回溯实际上可以开始。