Python检查9 * 9矩阵中的3 * 3矩阵,用于重复,如数独

时间:2017-09-15 05:29:15

标签: python numpy matrix

Detect duplicate in each 3*3 block in a 9*9 matrix

我的方法:使用numpy.vsplit和hsplit将9 * 9分成9个3 * 3块 并使用.flat函数展平每个3 * 3块,然后使用set()检查列表是否包含重复

import numpy as np
def validSolution(board):


    b=np.array(board)
    b=np.vsplit(b,3)
    for n,ar in enumerate(b):
        b[n]=np.hsplit(ar,3)

    for ar in b:
        for arr in ar:
            print(len(set(arr.flat))==len(arr.flat))

validSolution([[5, 3, 4, 6, 7, 8, 9, 1, 2],
               [6, 7, 2, 1, 9, 5, 3, 4, 8],
               [1, 9, 8, 3, 4, 2, 5, 6, 7],
               [8, 5, 9, 7, 6, 1, 4, 2, 3],
               [4, 2, 6, 8, 5, 3, 7, 9, 1],
               [7, 1, 3, 9, 2, 4, 8, 5, 6],
               [9, 6, 1, 5, 3, 7, 2, 8, 4],
               [2, 8, 7, 4, 1, 9, 6, 3, 5],
               [3, 4, 5, 2, 8, 6, 1, 7, 9]])

由于我对python和numpy缺乏经验,我想请求一种更有效的方法来完成这项工作。

1 个答案:

答案 0 :(得分:3)

设置:假设a9x9网格而b是您在{{1}中搜索的3x3子矩阵(较小的网格) }。

步骤:

  • 解决问题的一种方法是将a重塑为a 4D形状a4D,因此每个窗口都沿着第二和第四轴

  • 我们需要将(3,3,3,3)扩展到b,以便第一个轴与3D的第二个轴对齐,第二个轴与{{1}的第四个轴对齐}}。

  • 执行比较,这将是有效的,礼貌的NumPy广播,给我们一个a4D布尔数组。查看这两个dims的所有匹配项,只需获取匹配的索引。

因此,实施 -

a4D

示例运行 -

4D

如果由于某种原因看起来很混乱而你更喜欢使用np.argwhere((a.reshape(3,3,3,3) == b[:,None]).all((1,3))) ,我们可以使用In [190]: a Out[190]: array([[5, 3, 4, 6, 7, 8, 9, 1, 2], [6, 7, 2, 1, 9, 5, 3, 4, 8], [1, 9, 8, 3, 4, 2, 5, 6, 7], [8, 5, 9, 7, 6, 1, 4, 2, 3], [4, 2, 6, 8, 5, 3, 7, 9, 1], [7, 1, 3, 9, 2, 4, 8, 5, 6], [9, 6, 1, 5, 3, 7, 2, 8, 4], [2, 8, 7, 4, 1, 9, 6, 3, 5], [3, 4, 5, 2, 8, 6, 1, 7, 9]]) In [196]: b = a[-3:,-6:-3] # (2,1) grid In [197]: b Out[197]: array([[5, 3, 7], [4, 1, 9], [2, 8, 6]]) In [198]: np.argwhere((a.reshape(3,3,3,3) == b[:,None]).all((1,3))) Out[198]: array([[2, 1]]) In [199]: b = a[:3:,:3] # (0,0) grid In [200]: b Out[200]: array([[5, 3, 4], [6, 7, 2], [1, 9, 8]]) In [201]: np.argwhere((a.reshape(3,3,3,3) == b[:,None]).all((1,3))) Out[201]: array([[0, 0]]) 中的view_as_blocks来获得与形状无关的解决方案 -

built-ins

请注意,这些重塑只是scikit-image,因此不需要额外的内存空间。虽然比较会导致创建一个与In [206]: from skimage.util.shape import view_as_blocks In [207]: np.argwhere((view_as_blocks(a, b.shape) == b).all((2,3))) Out[207]: array([[0, 0]]) 形状相同的布尔数组,但是它是一个布尔数组,它比int / float数组要轻得多(在Linux系统上轻8倍),所以那里也不错关于记忆效率。