具有递归回溯的数独求解器未按预期工作(已修复!)

时间:2013-04-09 15:34:01

标签: c recursion sudoku backtracking

我正在使用一个使用递归回溯算法的解算器制作数独游戏程序,并使用单解决方案数独生成器作为我正在进行的在线CS类的项目。 然而,当与生成器一起使用时,求解器似乎经常陷入无限循环(我使用求解器来检查每一步是否有解决方案),并且我无法弄清楚我的求解函数有什么问题。

我花了很多时间试图找出导致它不按预期行事的原因,但此时我感到困惑。

我不希望任何人提供使用的确切代码,我也不想。但是,如果有人能给我一些关于这个功能有什么问题的指针,我将非常感激。 这是我的代码:

    bool solve(int cell)
    {
        // if reached the end, return true
        if (cell == 81)
            return true;

        // if is a given number, go to next cell
        if (givnums[0][cell] == true)
        {   // pass in the return value of next cell to previous cell
            if (solve(cell + 1) == false)
                return false;
            else
                return true;
        }

        // find a valid number to insert
        for (int i = 1; i <= 9; i++)
        {
            // if is an invalid move, continue
            if (rows[cell / 9][i - 1] == true || cols[cell % 9][i - 1] == true || minigrids[((cell / 9) / 3) * 3 + (cell % 9) / 3][i - 1] == true)
                continue;
            // else place the number, update all grids and go to next cell
            else
            {
                s_grid[0][cell] = i;
                s_rows[cell / 9][i - 1] = true;
                s_cols[cell % 9][i - 1] = true;
                s_minigrids[((cell / 9) / 3) * 3 + (cell % 9) / 3][i - 1] = true;
                // go to next cell
                if (solve(cell + 1) == false)
                {
                    // if next cell returns false, undo last step
                    s_grid[0][cell] = 0;
                    s_rows[cell / 9][i - 1] = false;
                    s_cols[cell % 9][i - 1] = false;
                    s_minigrids[((cell / 9) / 3) * 3 + (cell % 9) / 3][i - 1] = false;    
                }
                // else return true
                else
                    return true;
            }
        }

    // no valid number, return false
    return false;
    }

该函数在找到解决方案时应返回true,如果没有则返回false。数组s_cols,s_rows和s_minigrids用于跟踪有效移动,而givnums用于跟踪不应触及的数字。

编辑:
所以,如果有人关心的话,还有一点点更新 - 我最新修订的程序(我在这里发布的代码)的逻辑很好。造成这个错误的原因在于这一行:

if (rows[cell / 9][i - 1] == true || cols[cell % 9][i - 1] == true || minigrids[((cell / 9) / 3) * 3 + (cell % 9) / 3][i - 1] == true)

我应该使用s_grid,s_rows等,它们是当前网格状态的副本,可以使用solve()。我错过了那种愚蠢的感觉,但现在一切都很完美!对于强力方法来说它也非常快。生成随机有效sodoku网格只需1-2秒,我在随机空闲单元格中插入一个随机数,并在每一步使用求解器检查是否有解决方案,否则返回一步。

0 个答案:

没有答案