【问题标题】:How to decompose a matrix into a sum of connected components?如何将矩阵分解为连通分量的总和?
【发布时间】:2014-10-17 08:49:27
【问题描述】:

我有一个 0 和 1 的矩阵:

       1 0 0 0 0
       0 0 1 1 0
  a =  0 0 1 1 0
       1 0 0 0 0
       1 1 0 0 0

并且我想使用 python 将其分解为连接组件的总和,其中“连接”是指每个“1”在其上方/下方/左侧/右侧至少有另一个“1”的矩阵。否则“1”必须被隔离:

       1 0 0 0 0   1 0 0 0 0   0 0 0 0 0   0 0 0 0 0
       0 0 1 1 0   0 0 0 0 0   0 0 1 1 0   0 0 0 0 0
  a =  0 0 1 1 0 = 0 0 0 0 0 + 0 0 1 1 0 + 0 0 0 0 0
       1 0 0 0 0   0 0 0 0 0   0 0 0 0 0   1 0 0 0 0
       1 1 0 0 0   0 0 0 0 0   0 0 0 0 0   1 1 0 0 0

有趣的是,在这个问题 (Largest rectangle of 1's in 2d binary matrix) 中,Guy Adini 建议使用 BFS 分解来分解连通分量中的矩阵。但是我找不到它的 python 实现,也找不到如何使用 BFS 来解决我的问题。

【问题讨论】:

    标签: python matrix decomposition


    【解决方案1】:

    一个有效的算法如下:

    • 对于算法访问的元素(或等效地,一组已访问元素的坐标),您保留一个与 true 大小相同的 visited 矩阵。

    • 你一个一个地遍历矩阵的所有元素:

      • 如果一个元素未被访问并且为 1,则将其标记为已访问,并以相同的方式递归地探索其所有邻居。递归函数必须返回连接的集合(包含这些元素的矩阵、包含它们的坐标的集合等)。

    【讨论】:

      【解决方案2】:

      这里有一个自定义实现。如果你愿意,我让你修改它以删除重复项。

      import itertools
      
      class Matrix():
          def __init__(self, matrix):
              self.matrix = matrix
      
          def computeConnectedComponents(self):
              rows_id = list(range(len(self.matrix)))
              cols_id = list(range(len(self.matrix[0])))
      
              #here are the position of every 1 in the grid. ( row number, column number) indexes start at 0
              positions = [couple for couple in self.generate_pairs(rows_id, cols_id) if self.matrix[couple[0]][couple[1]]==1]
      
              #here we store all the connected component finded
              allConnectedComponents = []
      
              #while there is position not affected to any connected component
              while positions != [] :
                  #the first element is taken as start of the connected component
                  to_explore = [positions.pop(0)]
                  currentConnectedComponent = set()
                  #while there is node connected to a node connected to the component
                  while list(to_explore) != []:
                      currentNode = to_explore.pop()
                      currentConnectedComponent.add(currentNode)
      
                      to_explore += [coord for coord in self.node_neighbourhood(currentNode) if (self.matrix[coord[0]][coord[1]]==1 and (coord not in to_explore) and (coord not in currentConnectedComponent))]
      
                      allConnectedComponents.append(currentConnectedComponent)
                      positions = [position for position in positions if position not in currentConnectedComponent]
      
              return allConnectedComponents
      
          #http://stackoverflow.com/questions/16135833/generate-combinations-of-elements-from-multiple-lists
          def generate_pairs(self, *args):
              for i, l in enumerate(args, 1):
                  for x, y in itertools.product(l, itertools.chain(*args[i:])):
                      yield (x, y)
      
          def node_neighbourhood(self, coordinates):
              row, column = coordinates[0], coordinates[1]
              result = []
              if (row - 1) >= 0 :
                  result.append((row-1, column))
              if (row + 1) < len(self.matrix):
                  result.append((row+1, column))
              if (column - 1) >= 0:
                  result.append((row, column-1))
              if (column + 1) < len(self.matrix[0]):
                  result.append((row, column+1))
              return result
      
      
      if __name__ == "__main__":
          data = [[1,0,0,0,0],
                 [0,0,1,1,0],
                 [0,0,1,1,0],
                 [1,0,0,0,0],
                 [1,1,0,0,0]]
      
          matrix = Matrix(data)
          for connectedComponent in matrix.computeConnectedComponents():
              print(connectedComponent)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-30
        • 1970-01-01
        • 2020-05-14
        • 2011-12-28
        相关资源
        最近更新 更多