生成最小/不可约数独游戏

7
一个数独谜题是最小的(也称为不可约)当且仅当它有唯一的解,但是移除任何数字都会产生一个有多个解的谜题。换句话说,每个数字都是必要的来确定解决方案。
我有一个生成最小数独的基本算法:
- 生成一个完成的谜题。 - 以随机顺序访问每个单元格。对于每个访问的单元格:
- 暂时删除其数字 - 使用递归回溯算法两次解决谜题。一个求解器按正向顺序尝试1-9的数字,另一个按相反的顺序。从某种意义上说,求解器正在遍历包含所有可能配置的搜索树,但从相反的方向。这意味着如果谜题有唯一解,则两个解决方案将匹配。 - 如果谜题有唯一的解,则永久删除数字;否则,将其放回。
这种方法保证产生最小的谜题,但速度很慢(在我的计算机上为100毫秒,在智能手机上为几秒钟)。我想减少解决数,但我能想到的所有明显的方法都是不正确的。例如:
- 添加数字而不是删除它们。这样做的好处是,由于最小谜题需要至少17个填充数字,因此前17个数字保证没有唯一的解决方案,从而减少了求解量。不幸的是,由于以随机顺序访问单元格,许多不必要的数字将在一个重要的数字“锁定”唯一解决方案之前被添加。例如,如果添加的前9个单元格都在同一列中,则存在大量冗余信息。 - 如果没有其他数字可以替换当前数字,请保留它并且不要解决谜题。因为检查放置是否合法比解决谜题快上千倍,这可能会节省大量时间。但是,只是因为现在没有其他合法数字并不意味着以后不会有,在我们删除其他数字后。 - 既然我们生成了原始解决方案,就只需要每个单元格解决一次,看看它是否与原始解决方案匹配。这种方法行不通,因为原始解决方案可能在所有可能解决方案的搜索树中的任何位置。例如,如果原始解决方案靠近树的“左侧”,并且我们从左侧开始搜索,我们将错过树的右侧的解决方案。
我也想优化解决算法本身。难点在于确定解决方案是否唯一。我可以进行微小的优化,例如为每个单元格创建合法放置的位掩码,如这篇绝妙的文章所述。但是,更高级的算法(如Dancing Links或模拟退火)不是设计用于确定唯一性,而只是找到任何解决方案。
我该如何优化我的最小数独生成器?

4
我认为你可以通过使用一个回溯求解器来改进你的原始解决方案,而不是两个。一旦它找到一个解决方案,不要停止——继续搜索直到找到另一个解决方案。一旦你找到第二个解决方案,就停止搜索。 - mbeckish
wildplasser,completed 意味着完全填写。mbeckish,这是一个好主意! - 1''
此外,我认为你只需要有一个起始谜题。在创建了一个不可约的谜题之后,您可以重新排列其簇中的行和列,重新排列簇的行和列,并“重新着色”谜题。但我不确定这是否会导致所有可能的不可约谜题。 - user824425
1
检查原始解决方案可能是排除移除的快速方法。这样可以启发式地节省很多时间。如果匹配了,仍然需要进行第二次求解(或者像@mbeckish指出的那样,继续第一次回溯),但如果没有匹配,则可以立即继续。 - user295691
2
Dancing Links 可以用于检查多个解决方案。例如,请参见 http://garethrees.org/2007/06/10/zendoku-generation/#section-4.4。 - Reinstate Monica
显示剩余4条评论
2个回答

0

这里是我实施的主要优化措施以及(高度近似的)速度增加百分比:

  • 使用位掩码来跟踪每个单元格中满足的约束条件(行、列、盒子)。这样可以更快地查找放置是否合法,但放置操作会变慢。在使用位掩码生成谜题时,一个复杂因素是可能需要删除数字,这意味着你需要将三种类型的约束条件作为不同的位进行跟踪。进一步的小优化是将每个数字和每个约束条件的掩码保存在数组中。速度提升40%
  • 如果生成过程时间太长,则设置超时并重新开始。详见此处。最佳策略是在每次失败的生成后增加超时时间,以减少无限循环的可能性。速度提升30%,主要是减少了最坏情况下的运行时间。
  • mbeckish和user295691的建议(请参阅原帖的评论)。速度提升25%

0

我有一个想法,你提出的第二个选项会更好,只要你为前17个数字添加3个额外的检查。

  • 找到1-9之间的17个随机数字列表
  • 在随机位置添加每个项目

    1. 这些新添加的数字不违反数独的3个基本条件

      • 同一行中没有相同的数字
      • 同一列中没有相同的数字
      • 同一3x3矩阵中没有相同的数字
    2. 如果条件1失败,请移动到下一列或行,并再次检查3个基本条件。

    3. 如果没有下一行(即在第9列或第9行),则添加到第1列。填满17个字符后,在此运行求解器逻辑并寻找您的唯一解决方案。

1
这是如何避免在获取唯一解之前添加太多数字,然后删除一些数字以获得最小难度谜题的? - 1''

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接