我正在寻找"你如何找到它",因为我不知道如何接近找到我的程序的算法复杂度。
我用java写了一个数独解算器,没有考虑效率(我想尝试让它递归地工作,我成功了!)
一些背景:我的策略使用回溯来确定,对于给定的数独谜题,谜题是否只有一个唯一的解决方案。所以我基本上是读一个给定的谜题,然后解决它。一旦我找到了一个解决方案,我就不一定完成了,需要继续探索进一步的解决方案。最后,出现以下三种可能的结果之一:谜题根本无法解决,谜题有一个唯一的解决方案,或者谜题有多个解决方案。
我的程序从一个文件中读取谜题坐标,该文件对每个给定的数字有一行,由行、列和数字组成。按照我自己的习惯,7的左上角写成007。
实现:我从文件中加载值,并将它们存储在二维数组中我沿着数组走,直到我找到一个空白(未填充的值),并将其设置为1。并检查是否有任何冲突(我输入的值是否有效)。如果是,我移动到下一个值。如果没有,我将值增加1,直到我找到一个有效的数字,或者如果它们都不有效(1到9),我返回1步到我调整的最后一个值,并增加该值(使用递归)。当所有81个元素都被填满,没有冲突时,我就完成了求解。如果找到任何解决方案,我将它们打印到终端。否则,如果我试图在我最初修改的第一个元素上"后退一步",这意味着没有解决方案。
我的程序怎么能算法复杂?我认为它可能是线性的[O(n)],但我访问数组多次,所以我不确定:(
感谢您的帮助
O(n ^ m)其中n是每个方格的可能个数(即经典数独中的9),m是空格的个数。
这可以通过只从一个空白向后工作来看到。如果只有一个空格,那么在最坏的情况下,您必须处理n个可能性。如果有两个空格,那么您必须为第一个空格处理n种可能性,为第二个空白处理n种可能性,以处理第一个空白的每种可能性。如果有三个空格,那么您必须处理第一个空格的n种可能性。每一种可能性都将产生一个包含两个空格的谜题,这些空格具有n^2种可能性。
该算法对可能的解执行深度优先搜索。图形的每一层代表单个正方形的选择。图的深度是需要填充的正方形的数量。当分支因子为n,深度为m时,图的最坏情况性能为O(n ^ m)。
在很多数独游戏中,会有几个数字是稍加思考就能直接放出来的。通过在第一个空单元格中放置一个数字,您放弃了许多减少可能性的机会。如果前10个空单元格有很多可能性,你就会得到指数增长。我会问这些问题:
数字1在第一行的哪个位置?
数字2可以在第一行的哪个位置?
…
最后一行的数字9可以在哪里?
相同,但有九列?
还是那九个盒子?
哪个数字可以放入第一个单元格?
哪个数字可以进入第81格?
那是324个问题。如果任何问题只有一个答案,你就选那个答案。如果任何问题都没有答案,你就回溯。如果每个问题都有两个或两个以上的答案,你选择一个答案最少的问题。
你可能得到指数级增长,但只有在真正困难的问题上。