数独生成器算法

时间:2012-02-15 14:50:50

标签: c# sudoku

我制作了一个生成sudokus的算法,但效率非常低。每个难题都需要几分钟才能生成所以现在我试图以最佳方式再次编写它。但我遇到了一些我需要帮助的问题。

  1. 有两个aproaches,从空白网格开始并添加数字,然后检查它是否可以解决。第二种方法是创建包含所有81个数字的完整有效网格,然后删除,直到我们对剩余数字的数量感到满意并且它仍然可以解决。
  2. 首先我使用第一种方法,但现在我将使用第二种方法,因为我认为它更有效(我们从有效拼图开始,保证可以解决)。我认为第二种方法更好吗?

    1. 当我尝试生成完整填充的网格时,我遇到了困难。我的算法是:

      • 为每个单元格设置候选项。最初他们是1到9号。
      • 选择没有价值的随机单元格。
      • 从该单元格中选择随机候选项并将其指定为单元格值。其他候选人被丢弃。
      • 现在对于每一行,与指定单元格对应的单元格和正方形我从这些候选中删除单元格的值,因此每个数字在行/列/正方形中是唯一的
      • 重复
    2. 此技术可确保无重复数字的随机网格。但是,大多数情况下,当我没有违反任何放置规则时,就会发生冲突 - 比如所有候选人都已被移除的空单元格,我需要重新开始。是否有更优雅/有效的方法用数字填充整个网格而不破坏放置规则和仍然是随机数?

      谢谢。

4 个答案:

答案 0 :(得分:6)

你看过现有的算法和/或代码吗?

查看http://www.sudokuwiki.org/Sudoku_Creation_and_Grading.pdf的算法说明,以及Peter Norvig在http://norvig.com/sudoku.html的文章。

Python中有一些实现。到目前为止,我从未见过已发布的C#解决方案。

祝你好运!

答案 1 :(得分:0)

如果您正在查看一些现有的算法,那么就有一个c#项目。这实际上来自与Peter Norvig相同的解决方案。详细了解here

希望这会有所帮助!

答案 2 :(得分:0)

我使用编程来删除与最后一个条目冲突的所有先前条目。使用这种方法,我可以输入一些数量并定期计算解决方案或输入整个网格。我没有使用整个网格的随机输入,因为随机删除先前的条目可能导致长时间设置。对于随机输入,我希望阻止输入冲突会导致空白单元格,因此答案可能是在删除先前冲突的条目时使用较长的设置。您将需要返回所有空单元格,直到没有空单元格为止。填充所有单元格后,解决方案必须有效,否则冲突将被删除。

答案 3 :(得分:0)

我的方法是将您的第一种方法和第二种方法结合在一起。

首先,您必须有一个数独求解器。在空的数独上应用求解器。那就是为没有线索的数独找到解决方案。从左上到右下依次填入数字。否则有时间问题。我不知道为什么。无论如何,它的工作速度非常快,无需等待完成数独谜题。当您应用回溯时,随机排列每个位置的可能数字列表。否则,你每次都会得到同样的谜题。

其次,随机化一个所有位置的新列表。这是一个以随机顺序排列的 81 个位置的列表。根据这个顺序列表,尝试从上面的拼图中删除数字。每次删除一个数字时,您都必须检查它是否有多个解决方案。如果它有多个解决方案。该号码应该放回并尝试随机列表中的下一个位置。这个过程一直持续到列表结束或者您已经成功地从拼图中删除了 64 个数字。这个数字是 64,因为有人已经证明不存在少于 17 条线索的数独和唯一解。此过程从 15 秒到 2 分钟不等。通常需要 30 秒才能获得一个数独谜题。

第三,如果您不想为每个数独游戏等待 30 秒到 2 分钟,您可以对上述数独应用一些突变。这包括切换行和列、旋转。您也可以重新映射数字。例如,1->2、2->3...9->1。旋转和重新映射后,没有人会注意到这是原始的数独。