随机数独生成器

时间:2017-06-20 21:26:08

标签: python numpy random sudoku

我试图构建一个python脚本,生成一个9x9块,数字1-9在行,列和3x3块中是唯一的 - 你知道,Sudoku!

所以,我认为我会开始变得简单,随着时间的推移变得越来越复杂。首先我做了它,所以它随机填充每个数组值1-9。然后确保沿着行的数字不被复制。接下来,我想对行和行进行相同的操作。列。我认为我的代码没问题 - 它当然不会很快但我不知道为什么它会堵塞......

import numpy as np
import random

#import pdb
#pdb.set_trace()

#Soduku solver!

#Number input

soduku = np.zeros(shape=(9,9))

for i in range(0,9,1):
    for j in range(0,9,1):
        while True:
            x = random.randint(1,9)
            if x not in soduku[i,:] and x not in soduku[:,j]:
                soduku[i,j] = x
                if j == 8: print(soduku[i,:])
                break

因此,它会移动填充随机整数的列,删除一行并重复。代码应该真正需要做的最多就是为每个方块生成9个数字,如果它真的不走运的话 - 我认为如果我们解决这个问题,那么需要生成的数据将少于9 * 9 * 9。有什么东西打破了它!

有什么想法吗?!

4 个答案:

答案 0 :(得分:0)

我认为发生的事情是你的代码在你的while循环中陷入困境。您测试条件if x not in soduku[i,:] and x not in soduku[:,j],但如果不满足此条件会发生什么?您的代码很可能已经运行到一个死胡同的数独板(无法用任何值解决),并且它会陷入while循环中,因为要破坏它的条件永远无法满足。

答案 1 :(得分:0)

像这样生成它是不太可能的。有很多种方法可以生成9个3 * 3方格中的8个,因此根本不可能填充最后一个方格,让它永远挂起。

另一种方法是填写当时的所有数字(因此,首先是1,然后是所有2,等等。它就像Eight queens puzzle,但有9个皇后。当你到达无​​法放置号码的位置时,重启。

另一种方法是在9开始所有方格,并以某种方式策略性地减少它们,例如首先递减所有不能为9的,不包括当前行/列/平方中的9,然后如果它们都不可能或全部可能,则随机减1。

您也可以尝试enumerate all sudoku boards,然后使用随机整数反转enumaration函数,但我不知道这可能有多成功,但这是唯一可以选择它们的方法均匀随机性。

答案 2 :(得分:0)

你是从困难的方向来解决问题的。从有效的数独游戏板开始并使用它来制作不同的有效数独游戏板要容易得多。

一个简单有效的董事会是:

1 2 3 | 4 5 6 | 7 8 9
4 5 6 | 7 8 9 | 1 2 3
7 8 9 | 1 2 3 | 4 5 6
---------------------
2 3 4 | 5 6 7 | 8 9 1
5 6 7 | 8 9 1 | 2 3 4
8 9 1 | 2 3 4 | 5 6 7
---------------------
3 4 5 | 6 7 8 | 9 1 2
6 7 8 | 9 1 2 | 3 4 5
9 1 2 | 3 4 5 | 6 7 8

找到有效的电路板后,您可以通过播放原件来制作新的有效电路板。

您可以将任意三个3x3块的行与任何其他块行交换。您可以将三个3x3块的任何列与另一个块列交换。在每个块行中,您可以交换单个单元格行;在每个块列中,您可以交换单个单元格列。最后,您可以置换数字,这样只要整个板上的排列一致,单元格中就会有不同的数字。

这些更改都不会使有效的电路板无效。

答案 3 :(得分:0)

我使用 itertools 中的 permutations(range(1,10)) 创建所有可能行的列表。然后我将每一行从上到下一个一个地放入数独。如果发生矛盾,请使用列表中的另一行。通过这种方法,我可以在短时间内找到一些有效的完整数独板。它会在一分钟内继续生成完整的电路板。

然后我从有效的完整数独板中随机位置一个一个地删除数字。删除每个数字后,检查它是否仍然有唯一的解决方案。如果不是,则恢复原始数字并更改到下一个随机位置。通常我可以从板上删除 55~60 个数字。也需要一分钟之内的时间。这是可行的。

然而,前几个生成完整的数独板在第一行的数字为 1、2、3、4、5、6、7、8、9。所以我打乱了整个列表。对列表进行洗牌后,生成完整的数独板变得困难。任务失败。

更好的方法可能是这种方式。您从互联网上收集了一些数独。您完成它们,以便将它们用作种子。如上文第 2 段所述,您可以从中删除数字。您可以获得一些数独。您可以使用这些数独通过以下任何一种方法进一步生成更多

  1. 交换第 1 行和第 3 行,或第 4 行和第 6 行,或第 7 行和第 9 行
  2. 列的类似方法
  3. 相应地将 3x3 块 1,4,7 与 3,6,9 或 1,2,3 与 7,8,9 交换。
  4. 垂直或水平镜像数独
  5. 将数独旋转 90、180、270 次
  6. 随机排列板上的数字。例如,1->2, 2->3, 3->4, .... 8->9, 9->1。或者你可以只交换其中的 2 个。例如。 1->2, 2->1。这也有效。