具有回溯的数独求解器不能总是检测到多个解决方案

Posted

技术标签:

【中文标题】具有回溯的数独求解器不能总是检测到多个解决方案【英文标题】:Sudoku solver with backtracking can't always detect multiple solutions 【发布时间】:2020-04-19 02:18:31 【问题描述】:

这是我编写的代码,用于检查 KenKen 谜题是否有多种解决方案(类似于数独)。从技术上讲,如果有 2 个解决方案,它应该返回 true,但由于算法中的逻辑错误,它似乎不起作用。

我似乎找不到错误,在花了一整天的时间一步步调试整个事情之后,我觉得我永远也找不到问题所在。

代码可以毫无问题地解决难题,但它似乎并不总是能检测到何时有多个解决方案,这很奇怪。

    boolean solutionFlag = false;    

    static boolean backtrackingUniqueSolution(int startIndex) 
        for (int i=1; i<=sudokuGridElements.length; i++)
            sudokuGridCells[startIndex] = i;
            if(checkConditons())
                if(endOfBounds || backtrackingUniqueSolution(startIndex + 1)))
                    if(!solutionFlag) //Used to "count to 1"
                        solutionFlag = true;
                     else 
                        return true; //Should return true only after it finds the second solution
                    
                
            
            sudokuGridCells[startIndex] = null;
        
        return false;
    

【问题讨论】:

我认为endOfBounds变量的初始化有些错误 已经检查过了,不是 【参考方案1】:

当您找到第一个解决方案时,您设置了标志,但返回 false,因此您不知道是否在递归堆栈的更深处找到了解决方案。旗帜告诉你这一点,但你仍然必须寻找第二种解决方案才能得到答案。

您应该区分在到达最后一个单元格时实际找到解决方案和在您已经找到第二个解决方案时缩短递归。在第一种情况下,通过标志进行延迟计数。在第二种情况下,如果找到第二个解决方案,即递归函数返回 true,则返回 true。

boolean solutionFlag = false;    

static boolean multiSolution(int startIndex) 

    for (int i = 1; i <= sudokuGridElements.length; i++) 
        sudokuGridCells[startIndex] = i;

        if(checkConditons()) 
            if (endOfBounds) 
                if (solutionFlag) return true;

                solutionFlag = true;
             else 
                if (multiSolution(startIndex + 1)) return true;
            
        

        sudokuGridCells[startIndex] = null;
    

    return false;

(你可以去掉非本地状态标志,如果你让函数返回一个整数或枚举值,告诉你是否找到了一个或多个解决方案。)

【讨论】:

还是不行。好像它并不总是找到其他解决方案。我真的把头发拉出来了,因为它应该可以工作,但它只是没有。 我真的很喜欢那些“仍然不起作用”的 cmets。我在 C 中使用我仍然躺在身边的 sudoke 求解器测试了这段代码。在为这篇文章翻译成 Java(连同愚蠢的长名称)时,我可能犯了一个错误。无论如何,您对 what 在您的帖子中也不起作用的情况并不是很具体。 (顺便说一句,我假设endOfBound 在索引为 80 的最后一个单元格上为真,而不是在最后一个单元格之外。) “仍然不起作用”是指在某些实际上有多个解决方案的数独中它仍然无法检测到多个解决方案,而在其他数独中它会检测到它们。 是的,但对我来说,“不起作用”听起来像“你为此得了 F。坐下。”问题是,您不太清楚问题中哪些有效,哪些无效。如果没有您的检查代码和示例输入,我无法测试我的更改。正如我所说,我在 C sudoke 求解器中对其进行了测试,但我会以不同的方式编程很多东西。 (例如,看到for (int i = 1; i &lt;= length; i++) 让我感到怀疑,而你没有告诉我我对endOfBound 的假设是否正确。这些信息对我来说比你在这个问题上扯头发的事实更有用。@987654325 @.)

以上是关于具有回溯的数独求解器不能总是检测到多个解决方案的主要内容,如果未能解决你的问题,请参考以下文章

优化回溯算法求解数独

为啥这个数独求解器返回相同的板而不解决任何问题?

数独回溯 无效数独

Gui 可视化递归回溯数独

数独求解器回溯算法不起作用

回溯数独求解器不起作用