Java 数独解算器的算法复杂度(Big-O)

Java 数独解算器的算法复杂度(Big-O),java,recursion,multidimensional-array,sudoku,Java,Recursion,Multidimensional Array,Sudoku,我正在寻找“你是如何找到它的”,因为我不知道如何找到我的程序的算法复杂性 我用java编写了一个数独解算器,但没有考虑效率(我想让它递归工作,我成功了!) 一些背景: 我的策略是使用回溯来确定,对于给定的数独游戏,该游戏是否只有一个唯一的解决方案。所以我基本上读了一个给定的谜题,并解决了它。一旦我找到了一个解决方案,我不一定完成,需要继续探索进一步的解决方案。最后,出现了三种可能的结果之一:谜题根本不可解,谜题有唯一的解决方案,或者谜题有多个解决方案 我的程序从一个文件中读取拼图坐标,该文件的每

我正在寻找“你是如何找到它的”,因为我不知道如何找到我的程序的算法复杂性

我用java编写了一个数独解算器,但没有考虑效率(我想让它递归工作,我成功了!)

一些背景:

我的策略是使用回溯来确定,对于给定的数独游戏,该游戏是否只有一个唯一的解决方案。所以我基本上读了一个给定的谜题,并解决了它。一旦我找到了一个解决方案,我不一定完成,需要继续探索进一步的解决方案。最后,出现了三种可能的结果之一:谜题根本不可解,谜题有唯一的解决方案,或者谜题有多个解决方案

我的程序从一个文件中读取拼图坐标,该文件的每个给定数字有一行,由行、列和数字组成。按照我自己的惯例,7的左上角的正方形写为007

实施:

我从文件中加载值,并将它们存储在二维数组中 我沿着数组向下走,直到找到一个空白(未填充的值),然后将其设置为1。并检查是否存在任何冲突(我输入的值是否有效)。 如果是,则转到下一个值。 如果否,我将值增加1,直到找到一个有效的数字,或者如果它们都不起作用(1到9),我返回到我调整的最后一个值的1步,并增加该值(使用递归)。 当所有81个元素都被填满,没有冲突时,我就完成了求解。 如果找到任何解决方案,我会将它们打印到终端。 否则,如果我尝试对最初修改的第一个元素“返回一步”,这意味着没有解决方案

如何提高我的程序的算法复杂度?我认为它可能是线性[O(n)],但我多次访问阵列,因此我不确定:(

感谢任何帮助

O(n^m),其中n是每个正方形的可能数(即经典数独中的9),m是空白的空格数

这可以通过从一个空白处向后操作来看出。如果只有一个空白,那么在最坏的情况下,您必须处理n个可能性。如果有两个空白,那么您必须处理第一个空白处的n个可能性,以及第一个bla的每个可能性的第二个空白处的n个可能性nk.如果有三个空格,那么你必须对第一个空格进行n种可能性的运算。每种可能性都会产生一个包含两个空格的谜题,其中两个空格有n^2种可能性


此算法对可能的解执行深度优先搜索。图的每一级表示单个正方形的选择。图的深度是需要填充的正方形数。分支因子为n,深度为m,在图中查找解的最坏性能为O(n^m).

在许多数独游戏中,会有一些数字可以通过思考直接放置。通过将数字放置在第一个空单元格中,你放弃了许多减少可能性的机会。如果前十个空单元格有很多可能性,你会得到指数级增长。我想问以下问题:

第一行的数字1可以去哪里

2号线在第一行的什么地方

最后一行9号可以去哪里

相同但有九列

九个盒子也一样吗

哪个号码可以进入第一个单元格

哪个号码可以进入81号牢房

这是324个问题。如果任何问题只有一个答案,你就选择那个答案。如果任何问题根本没有答案,你就回溯。如果每个问题都有两个或更多答案,你就选择一个答案最少的问题


你可能会得到指数级的增长,但这只适用于真正困难的问题。

如果你使用回溯,你的复杂性可能是指数级的。也就是说,对于每一步,你都会或多或少地重复到每一步。你能发布你的代码吗?或者只是它的相关部分吗?你不需要只通过n-1个pos吗第二个空格的sibilities,第三个空格的n-2个可能性,等等,因为在数独中,一个数字只能用一次?如果正好有一个空格,那么就只有一个可能性——缺失的数字。嗯……我的意思是,我想你必须检查行和列,以排除其他(n-1=8)数字,这需要O(n)时间,但这些不会导致递归。对于最幼稚的算法来说,这是最糟糕的情况。如果使用任何基于规则的消除,O(n^m)将被m的一个比n^2小得多的数字所取代。事实上,一个已经填充了某些方块的9x9 Sodoku可能会在非常快的时间内使用蛮力规则修剪算法来解决。当然,它是非线性的和NP完全的,并且也有从这个角度解决它的方法。它转换NP复杂度所以只要不是一个简单的数独游戏,就会有指数增长。。。