我找了“你如何找到它”,因为我不知道如何处理找到我的程序的算法复杂度。
我写了使用Java数独解算器,没有考虑效率(我想尽量做到递归工作,这是我成功,但有!)
一些背景资料:
我的策略采用回溯来确定,对于给定的数独题,难题是否只有一个独特的解决方案或没有。 所以我基本上都看过在给定的难题,并解决它。 一旦我找到一个解决方案,我不一定完成,需要继续探讨进一步的解决方案。 最后,有三种可能的结果之一发生:难题是不可解可言,拼图有一个独特的解决方案,或拼图有多种解决方案。
我的程序读取拼图从对每个给定的数字一条线,由行,列和数字的文件坐标。 根据我自己的惯例,7左上角方形写为007。
执行:
我加载值,从文件,并将其存储在一个2-d阵列我下去数组,直到我找到一个空(未填充值),并将其设置为1,并检查是否有冲突(无论是i的值进入有效与否)。 如果是的话,我移动到下一个值。 如果没有,我加1的值,直到我找到一个合适的数字,或者,如果他们没有工作(1至9),我回去1步,我调整了最后的价值,我增加一个(使用递归)。 我做了,当所有81个元素已经排满,没有冲突解决。 如果发现任何解决方案,我把它们打印到终端。 否则,如果我尝试“退一万步”是我最初修改的第一个元素,这意味着没有解决方法。
我的程序如何算法复杂度? 我想这可能是线性的[O(N)],但我访问数组多次,所以我不知道:(
任何帮助表示赞赏
为O(n ^ m),其中n是可能性(在经典数独即,9)每个正方形且m的数量的是空格数。
这可以通过只从单一的空白向后工作中可以看出。 如果只有一个空白,那么您有n个 ,你必须在最坏的情况下工作,通过的可能性。 如果有两个空格,则必须到n准备工作,为每一个为第一空白准备第二空白的第一个空白和n的可能性。 如果有三个空格,则必须到n准备工作的第一个空白。 每个这些可能性将产生一个难题与具有n ^ 2的可能性两个坯件。
该算法通过执行可能的解决方案的深度优先搜索。 图中的每个电平表示为一个单一的正方形的选择。 图的深度是需要填补的方块数。 随着n的支化系数和米的深度时,发现在曲线图中的溶液为O的最坏情况下的性能(N ^ 米 )。
在许多数独,会有可以直接带着几分心思放在几个数字。 通过将在第一空单元格的数字,你放弃了很多的机会,以减少的可能性。 如果前十个空单元格有很多的可能性,你会得到指数级增长。 我问这个问题:
在第一线哪里能1号去了?
在第一线哪里能2号去了?
...
在最后一行在哪里可以9号去了?
相同的,但有九根柱子?
相同的,但与九个格子?
哪个号码可以进入第一个单元格?
哪个号码可以进入第81个细胞?
这是324度的问题。 如果有任何问题都只有一个答案,你选择的答案。 如果有任何问题没有答案可言,你原路返回。 如果每一个问题有两个或两个以上的答案,你选择的答案的最小数量的问题。
你可能会呈指数级增长,但只对确有困难的问题。