首先 - 这是一个作业 - 但它主要是一个理论问题,而不是一个实际问题,我只是要求确认我是否正确思考或任何提示,如果我不是。
我被要求编译一个简单的数独求解器(在 Prolog 上,但现在不是那么重要),唯一的限制是它必须使用Best-First Algorithm的启发式函数。我能够提出的唯一启发函数解释如下:
1. Select an empty cell.
1a. If there are no empty cells and there is a solution return solution.
Else return No.
2. Find all possible values it can hold. %% It can't take values currently assigned to cells on the same line/column/box.
3. Set to all those values a heuristic number starting from 1.
4. Pick the value whose heuristic number is the lowest && you haven't checked yet.
4a. If there are no more values return no.
5. If a solution is not found: GoTo 1.
Else Return Solution.
// I am sorry for errors in this "pseudo code." If you want any clarification let me know.
我这样做是对的,还是有其他方法,我的是假的? 提前谢谢。
答案 0 :(得分:1)
我将使用的启发式是:
1-9
填充它们。如果你设法填补每个方格,你就找到了一个有效的解决方案。
如果你达到没有有效选项的点,将最后一个游戏状态弹出堆栈(即回溯到你最后一次随机选择。)做出不同的选择,再试一次。
作为一个有趣的旁注,你被告知使用贪婪的启发式方法来做到这一点,但是数独实际上可以简化为布尔可满足性问题(SAT问题)和solved using a general-purpose SAT solver。这非常优雅,实际上可以更快而不是启发式方法。
答案 1 :(得分:1)
当我在Prolog中自己编写一个数独求解器时,我使用的算法如下:
此算法始终首先对“解决最多”的单元格进行排序,并尽早检测到故障。与解决随机单元格的算法相比,它减少了很多求解时间。
答案 2 :(得分:0)
您所描述的是最受约束的变量启发式算法。它拾取具有最少可能性的单元格,然后从该单元格开始递归地递归分支。这种启发式算法在深度优先搜索算法中速度极快,因为它可以在根部附近检测到碰撞,而搜索树仍然很小。
以下是C#中最受约束的变量启发式的实现:Exercise #2: Sudoku Solver
本文还包含了通过此算法对Sudoku单元的总访问次数的分析 - 它非常小。它几乎看起来像启发式在第一次尝试中解决了数独。