我正在研究一个带有递归回溯的数独求解器,除了一件事之外它已经完成了。如果我将重复项放在拼图中的某个位置(例如,在顶角的1,1),它可以继续尝试寻找解决方案,即使它不是可解决的难题。
非常感谢任何帮助!
罗布
答案 0 :(得分:2)
你知道回溯的方式是当你的谜题遇到矛盾时,所以在每一步都应该运行“验证”方法,如果谜题是非法的,那么你所做的最后一步是非法的。
当你发现你的举动是非法的时,你可以递归地回溯并继续前进。
另外,请注意,这是一种相当天真的方法,也许一些数独专家有更好的算法,但这种蛮力应该可以解决问题。
答案 1 :(得分:2)
您想要检测无效情况,因此您应该在调用解算器之前检查它。你的求解器本身不会产生无效的解决方案......
答案 2 :(得分:2)
关于重复项,我建议保留每个单元格的可能数字列表,当您尝试求解单元格时,您可以将此列表与匹配的行,列和框进行比较,这样就可以防止创建重复项。有了它,你可以解决更容易的难题,而无需回溯。如果你遇到困难,那就继续使用回溯......
答案 3 :(得分:1)
这不一定是答案,但它可以帮到你。我之前为宏程序做过这样的事情,它是评价最高的一个。
数独求解器可能是一个很大的挑战。判断移动是否正确的唯一方法是它是绝对的还是稍后证明的。这可能会带来相当大的挑战,因为目前的情况和动作都是基于目的。这意味着您可以将其作为排列来处理。您可以浏览每个方块并找出它有哪些可能的数字。从那里,你可以得到一个或两个定义的正方形。基于此,有许多可能的方法来达到终点。
解决谜题时会定义'终点'(没有错误 - 每个方格都填满)或者有错误。
基于此,您可以将每个移动视为一个节点,然后构建围绕可能移动的树系统。
例如:
8 7 1 2 _ _ 6 9 3
2 9 6 3 8 7 1 _ _
这只是一个小例子,但基于它,分别扫过每一行,然后每列我们可以生成可能的数字:
(5, 1) -> [4, 5]
(6, 1) -> [4, 5]
(8, 2) -> [4, 5]
(9, 2) -> [4, 5]
基于此,以及给予我们的解决方案,我们可以看到有四种可能的解决方案:
8 7 1 2 4 5 6 9 3
2 9 6 3 8 7 1 4 5
-OR -
8 7 1 2 5 4 6 9 3
2 9 6 3 8 7 1 4 5
-OR -
8 7 1 2 4 5 6 9 3
2 9 6 3 8 7 1 5 4
-OR -
8 7 1 2 5 4 6 9 3
2 9 6 3 8 7 1 5 4
虽然这还不足以解决整个难题并弄清楚哪个是“正确”,但这可以标准化并用于创建类似的系统并很快找到解决方案。
因此,您可以将所有这四种可能性添加到树中,每个树都从原始树分支:
8 7 1 2 _ _ 6 9 3
2 9 6 3 8 7 1 _ _
然后递归处理它们。
希望这有帮助!
答案 4 :(得分:1)
要实现Validate类,你不能只在你的solve方法中写Validate.validate();
吗?希望它有所帮助。