首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >python回溯

python回溯
EN

Stack Overflow用户
提问于 2012-07-18 09:46:49
回答 2查看 7.3K关注 0票数 2

我最近发了几个问题来理解递归和回溯,我觉得我现在得到了一些东西,并且试图写一个测试,我确实解决了sudoku问题,但是当我用另一种格式编写代码时,代码会停顿一段时间并返回False,这表明这个问题没有解决方案。

网格是一个9x9的列表,如果listi是零,那么它就意味着它需要被填充。

下面是解决问题的代码:

代码语言:javascript
复制
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

这是另一个函数,我试图用不同的方法来解决这个问题,但是它失败了,我找不到问题在哪里。

代码语言:javascript
复制
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

我试着调试程序,但没有发现任何有用的东西,顺便说一下,有什么好的方法来调试一段递归代码吗?

编辑:

下面是我用来测试的矩阵:

代码语言:javascript
复制
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]]
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-07-18 09:59:01

correct_solve查看所有网格,而buggy_solve查看单个列。这意味着,如果问题还没有解决,buggy_solve将只在当前列中查找要填充的单元格--如果该列没有一个空单元格,它就会从外层for循环和退出中掉出来,而不使用显式的return语句。因此,当发生这种情况时,需要代码在下一列上调用buggy_solve (并使用适当的return语句)。

票数 1
EN

Stack Overflow用户

发布于 2012-07-18 10:38:53

问题是您的递归解决方案从未开始回溯。相反,它将以无休止的递归结束,除非它会意外地找到一个解决方案--这是非常不可能的,而且只适用于大多数已解决的sudokus。除去这些情况,这就是正在发生的事情:

代码语言:javascript
复制
if buggy_solve(grid, col + 1) == True:
    return True

这个buggy_solve调用永远不会返回false。因为如果有必要,该函数将继续尝试并迭代这些列。当它到达最后一篇专栏时,它将在第一篇中重新开始,覆盖以前发生的一切。

因此,回溯永远不会开始。考虑到我们还处于早期处理阶段,check_sudoku很少会失败,而且大部分未填充的sudoku可能允许在给定单元格中包含多个值。

您想要做的是防止buggy_solve从头开始,即删除列重置并使其只返回无效列的false。这样,buggy_solve会在某个时候返回false,并且回溯实际上可以开始。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11538611

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档