在n * n二进制矩阵中计数2 * 2个正方形

时间:2013-12-06 12:00:37

标签: python python-3.x

我有一个n * n二进制矩阵(只有1和0),我怎样才能计算2 * 2个正方形(正方形由1制成)

例如A=[[1,1],[1,1]]被认为是一个2 * 2平方。或

A = [[1, 1, 0, 1],
     [1, 1, 1, 1],
     [1, 1, 1, 0],
     [0, 1, 1, 1]]

被认为是四个2 * 2的正方形。 这是我的代码,但我不知道为什么它不起作用。

A = [[1, 1, 0, 1] , [1, 1, 1, 1], [1, 1, 1, 0], [0, 1, 1, 1]]
result=[]
for x in range(len(A)-1):
    for y in range(len(A)-1):
        if A[x][y]==1:
            if A[x+1][y]==1:
                if A[x][y+1]==1 or A[x][y-1]==1 and A[x+1][y] or A[x+1][y-1]==1:
                    result.append(1)
            if A[x-1][y]==1:
                if A[x][y+1]==1 or A[x][y-1]==1 and A[x-1][y] or A[x-1][y-1]==1:
                    result.append(1)        
print(len(result))        

`

4 个答案:

答案 0 :(得分:2)

  • 生成宽度指数 - 1高度 - 1; itertools.product()可以为我们这样做。
  • 使用all()测试每个生成的索引的4坐标,以仅测试反驳正方形所需的数量。
  • 使用sum()与生成器计算找到的方格数;比使用列表或计数器手动计数更快。

与lambda一起测试正方形,然后变为:

from itertools import product

def count_squares(A):
    width, height = len(A[0]), len(A)
    indices = product(range(width - 1), range(height - 1))
    is_square = lambda x, y: all(A[a][b] == 1 for a, b in product((x, x + 1), (y, y + 1)))
    return sum(1 for x, y in indices if is_square(x, y))

演示:

>>> from itertools import product
>>> count_squares([[1,1],[1,1]])
>>> def count_squares(A):
...     width, height = len(A[0]), len(A)
...     indices = product(range(width - 1), range(height - 1))
...     is_square = lambda x, y: all(A[a][b] == 1 for a, b in product((x, x + 1), (y, y + 1)))
...     return sum(1 for x, y in indices if is_square(x, y))
... 
>>> count_squares([[1,1],[1,1]])
1
>>> count_squares([[1, 1, 0, 1] , [1, 1, 1, 1], [1, 1, 1, 0], [0, 1, 1, 1]])
4

答案 1 :(得分:1)

要获得列数,请使用len(A [x])

for y in range(len(A)-1)

变为

for y in range(len(A[x])-1)

更改

if A[x][y]==1:
        if A[x+1][y]==1:
            if A[x][y+1]==1 or A[x][y-1]==1 and A[x+1][y] or A[x+1][y-1]==1:
                result.append(1)
        if A[x-1][y]==1:
            if A[x][y+1]==1 or A[x][y-1]==1 and A[x-1][y] or A[x-1][y-1]==1:
                result.append(1)  

        if A[x][y]==1 and A[x+1][y]==1 and a[x+1][y+1]==1 and a[x][y+1]:
             result.append(1) 

除非您想多次计算方块。

答案 2 :(得分:1)

使用scipy.signal有一个简单的解决方案,可以找到目标和输入之间的相关性。这很好,因为它推广到“几乎匹配”和任意形状!

import numpy as np
from scipy import signal

A = np.array([[1,1,0,1] ,[1,1,1,1],[1,1,1,0],[0,1,1,1]],dtype=int)
b = np.ones((2,2),dtype=int)

c   = signal.correlate(A, b, 'valid')
idx = np.where(c==4)
count = sum(idx[0])

print count

这会按预期提供4。如果你觉得这很有趣,那么有一个(更长的)答案使用同样的想法:

Finding matching submatrices inside a matrix

答案 3 :(得分:0)

我将每个2 * 2子矩阵的值乘以多个并总结:

A = [[1, 1, 0, 1],
    [1, 1, 1, 1],
    [1, 1, 1, 0],
    [0, 1, 1, 1]]

sum( A[x][y]*A[x+1][y]*A[x][y+1]*A[x+1][y+1] 
         for y in range(len(A)-1)
         for x in range(len(A[y])-1)
)


Out[79]: 4