为了获得乐趣,我有时间,我喜欢编写游戏以了解它有多难,或者只是因为我想从内部看到它是如何工作的,或者只是为了个人挑战.我只是喜欢编码.现在,我做了这些.
所以我做了一个数独板.首先它是正常的3x3x3板,但后来有人让我做一个4x4x4板.我很成功但我的算法很慢.
问题是,你如何为4x4x4(或更多)数独板做快速算法?
我当前的算法是这样的:我将用随机数填充网格1,确保我没有放回相同的数字,然后切换到网格2.当我在位置0.0或网格中的任何其他位置时我从网格1中删除任何可能的数字.我继续这样对网格中的每一行/列.(现在你可以看到英语不是我的第一语言,所以如果难以理解,我很抱歉.)
更新:
几个月后的一点点跟进.
我现在的解决方案可以在这里找到
因此,当我开始这个问题时,它每30-50秒做一次网格,现在每秒超过300次
考虑以下网格:
1 2 3 4 | 5 6 7 8 | 9 10 11 12 | 13 14 15 16 5 6 7 8 | 9 10 11 12 | 13 14 15 16 | 1 2 3 4 9 10 11 12 | 13 14 15 16 | 1 2 3 4 | 5 6 7 8 13 14 15 16 | 1 2 3 4 | 5 6 7 8 | 9 10 11 12 ------------+-------------+-------------+------------ 2 3 4 1 | 6 7 8 5 | 10 11 12 9 | 14 15 16 13 6 7 8 5 | 10 11 12 9 | 14 15 16 13 | 2 3 4 1 10 11 12 9 | 14 15 16 13 | 2 3 4 1 | 6 7 8 5 14 15 16 13 | 2 3 4 1 | 6 7 8 5 | 10 11 12 9 ------------+-------------+-------------+------------ 3 4 1 2 | 7 8 5 6 | 11 12 9 10 | 15 16 13 14 7 8 5 6 | 11 12 9 10 | 15 16 13 14 | 3 4 1 2 11 12 9 10 | 15 16 13 14 | 3 4 1 2 | 7 8 5 6 15 16 13 14 | 3 4 1 2 | 7 8 5 6 | 11 12 9 10 ------------+-------------+-------------+------------ 4 1 2 3 | 8 5 6 7 | 12 9 10 11 | 16 13 14 15 8 5 6 7 | 12 9 10 11 | 16 13 14 15 | 4 1 2 3 12 9 10 11 | 16 13 14 15 | 4 1 2 3 | 8 5 6 7 16 13 14 15 | 4 1 2 3 | 8 5 6 7 | 12 9 10 11
假设我没有做过任何拼写错误,那么它应该是显而易见的(从它的构造模式来看)这遵循了Sudoku布局的要求(每个值1..16在每行,每列和4x4子网格中恰好出现一次).
此外,显而易见的是,以下每项更改都会满足要求(假设采用1原点索引):
列交换:交换位于同一子网格中的任意两列的全部内容(例如,交换cols 1和3,交换cols 10和11,但不交换cols 6和13).
行交换:交换位于同一子网格中的任意两列的全部内容(类似于#1的索引).
子网格列交换:交换两列子网格的相应列(例如,交换子网格列2和4,这意味着交换所有列5和13,列6和14,列7和15以及列8和16).
子网格行交换:交换两行子网格的相应行(类似索引到#3).
因此,基于上述事实,策略是从上面显示的网格开始,然后进行一些适当的迭代次数(您可以通过实验确定),随机选择四种变换中的一种,并将其应用于随机选择满足变换规定要求的指数.
例如,要应用变换#1,随机地选择一个子网格列数
sgcn
的范围内(1..4),然后随机选择两个不同的列号cn1
和cn2
在范围(1..4).SWAP所有值列(sgcn - 1) * 4 + cn1
和(sgcn - 1) * 4 + cn2
.
通过从(任何)合法网格开始,并执行合法性保留转换,结果保证是合法的.然而,随着所应用的变换的数量增加,人类观察者越来越难以将模式与随机性区分开.
用空格替换"加扰"网格中的值以获得所需的难度.