Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何将一个矩阵分解为一组连通分量之和?_Python_Matrix_Decomposition - Fatal编程技术网

Python 如何将一个矩阵分解为一组连通分量之和?

Python 如何将一个矩阵分解为一组连通分量之和?,python,matrix,decomposition,Python,Matrix,Decomposition,我有一个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和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

有趣的是,在这个问题()中,Guy Adini建议使用BFS分解来分解连接组件中的矩阵。但是,我找不到它的python实现,也找不到如何使用BFS来解决我的问题。

一个有效的算法如下:

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

  • 您将逐个检查矩阵的所有元素:

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

    • 这里有一个自定义实现。我允许您修改它以删除重复项(如果需要)

      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)
      
      导入itertools
      类矩阵():
      定义初始化(自身,矩阵):
      self.matrix=矩阵
      def计算连接组件(自身):
      行\u id=列表(范围(len(self.matrix)))
      cols_id=list(范围(len(self.matrix[0]))
      #以下是网格中每个1的位置。(行号、列号)索引从0开始
      positions=[self.generate_pairs(rows_id,cols_id)if self.matrix[couple[0]][couple[1]==1]
      #在这里,我们存储查找到的所有连接组件
      allConnectedComponents=[]
      #而位置不影响任何连接的组件
      而位置[] :
      #第一个元素作为连接组件的起点
      to_explore=[positions.pop(0)]
      currentConnectedComponent=set()
      #而有一个节点连接到一个节点连接到该组件
      while list(去探索)!=[]:
      currentNode=to_explore.pop()
      currentConnectedComponent.add(currentNode)
      to_explore+=[self.node_邻域(currentNode)中的坐标(self.matrix[coord[0]][coord[1]==1和(坐标不在to_explore中)和(坐标不在currentConnectedComponent中))]
      allConnectedComponents.append(currentConnectedComponent)
      位置=[如果位置不在currentConnectedComponent中,则位置在位置中的位置]
      返回所有连接的组件
      #http://stackoverflow.com/questions/16135833/generate-combinations-of-elements-from-multiple-lists
      def生成_对(自身,*参数):
      对于枚举中的i,l(args,1):
      对于itertools.product(l,itertools.chain(*args[i:])中的x,y:
      产量(x,y)
      def节点_邻域(自身,坐标):
      行,列=坐标[0],坐标[1]
      结果=[]
      如果(第1行)>=0:
      结果.追加((第1行第1列))
      如果(行+1)=0:
      结果.追加((行,列-1))
      如果(列+1)