【问题标题】:Python Computing Vertex Degree MatrixPython计算顶点度矩阵
【发布时间】:2015-09-03 16:46:11
【问题描述】:

我目前正在尝试编写代码来计算度数矩阵,以便我可以计算拉普拉斯算子 L = D - A,其中 D=度数矩阵,A=邻接矩阵。

这将在我的谱聚类算法中使用。我正在使用 Python。因此,对于这个玩具示例,我很难做到。任何人都可以提供一种有效的方法来执行此操作,或者是否有用于计算度数矩阵的 API?我的问题很简单,什么是计算连通度矩阵的有效方法,或者是否有 python 模块?

例子:

import numpy as np
matrix = np.matrix('1, 1, 1, 1; 1, 0, 0, 0; 0, 0, 1, 1')

matrix =

 1     1     1     1
 1     0     0     0
 0     1     0     1
 0     0     1     1

如何计算得到 5 3 4 4 的度数(矩阵),它代表每个节点的连接度?谢谢。

【问题讨论】:

  • err,您想在计算机上使用数值方法对图论对象进行编码,并且您已经声明了一个矩阵。 Here 是关于邻接矩阵的另一个 SO 问题/答案(还有其他类似的问题和答案,您应该先阅读而不是询问另一个版本),here 是互联网上关于如何做你所要求的,here 是理论。
  • 只问如何高效计算度数矩阵。剩下的我知道怎么做。

标签: python cluster-analysis graph-theory adjacency-matrix


【解决方案1】:

图表有一个特殊的包networkx

import networkx as nx
import numpy as np

m = np.matrix('1, 1, 1, 1;'
              '1, 0, 0, 0;'
              '0, 1, 0, 1;'
              '0, 0, 1, 1')
G = nx.from_numpy_matrix(m)
nx.laplacian_matrix(G).toarray()

结果:

array([[ 3, -1, -1, -1],
       [-1,  2, -1,  0],
       [-1, -1,  3, -1],
       [-1,  0, -1,  2]], dtype=int64)

【讨论】:

    【解决方案2】:

    好吧,我想通了,但我不知道这是否是最有效的方法。但是,这是我找到的答案。

    #### Example of Computing Degree Matrix
    import numpy as np
    matrix = np.matrix('1, 1, 1, 1;'
                       '1, 0, 0, 0;'
                       '0, 1, 0, 1;'
                       '0, 0, 1, 1')
    
    degree = np.zeros(len(matrix)) # initialize list to hold values of degree
    
    # calculate the sums along rows and sum along columns
    colsum = matrix.sum(axis=0)
    rowsum = matrix.sum(axis=1)
    
    # loop through matrix and add up all degree connections
    for j in range(0, len(matrix)):
        degree[j] = colsum[0,j] + rowsum[j,0]
    
    # get the diagonal entries to correct the for loop oversumming
    A = matrix.diagonal()
    d = A.flat
    diagMat = list(d)
    
    # print the degree of connectivity matrix 
    print np.diag(degree - diagMat)
    
    [[ 5.  0.  0.  0.]
     [ 0.  3.  0.  0.]
     [ 0.  0.  4.  0.]
     [ 0.  0.  0.  4.]]
    

    【讨论】:

      【解决方案3】:

      您可以使用sumdiagnumpy 只是代替矩阵使用数组

      import numpy as np
      matrix = np.array([[1, 1, 1, 1],[1, 0, 0, 0],[ 0 ,1 ,0 ,1 ],[0, 0, 1, 1]])    
      degree = np.diag(np.sum(matrix, axis=1))
      

      【讨论】:

        【解决方案4】:

        要回答这个问题,如何从邻接矩阵中得到度数矩阵:

        它可能不会比其他一些答案快,但至少稍微简单一点并且用 PyTorch 编写(应该很容易翻译成 numpy,因为其他答案已经使用过)

        import torch
        A = torch.Tensor([[1, 1, 1, 1],
                          [1, 0, 0, 0],
                          [0, 1, 0, 1],
                          [0, 0, 1, 1]])
        
        out_degree = torch.sum(A, dim=0)
        in_degree = torch.sum(A, dim=1)
        
        identity = torch.eye(A.size()[0])
        
        degree_matrix = diag*in_degree + diag*out_degree - torch.diagflat(torch.diagonal(A))
        
        tensor([[5., 0., 0., 0.],
                [0., 3., 0., 0.],
                [0., 0., 4., 0.],
                [0., 0., 0., 4.]])
        

        相当直接的代码,一些解释:

        • torch.diagonal 获取一维数组中的对角元素
        • torch.diagflat 接受一个数组并创建一个二维对角矩阵

        【讨论】:

          【解决方案5】:

          对于那些处理无向图的人,可以使用以下方法创建节点的对角度矩阵:

          def diagonal_degree_matrix(adj):
              diag = np.zeros([adj.shape[0], adj.shape[0]]) # basically dimensions of your graph
              rows, cols = adj.nonzero()
              for row, col in zip(rows, cols):
                  diag[row, row] += 1
              return diag
          

          其中 adjcsr_matrix 类型的邻接矩阵,np 是 numpy 库。

          【讨论】:

            【解决方案6】:

            你是在计算入度还是出度?

            我认为更高效的代码是: degree_size = np.size(矩阵, 0)

            out_degree = np.zeros((degree_size,degree_size))
            in_degree = np.zeros((degree_size,degree_size))
            
            out_degree_sum = Matrix.sum(axis=0)
            in_degree_sum = Matrix.sum(axis=1)
            
            for i in range(0, degree_size):
                out_degree[i,i] = out_degree_sum[i]
            
            for j in range(0, degree_size):
                in_degree[j,j] = in_degree_sum[j]
            

            【讨论】:

              猜你喜欢
              • 2022-01-13
              • 2017-05-30
              • 2016-10-22
              • 1970-01-01
              • 2016-07-03
              • 2012-09-11
              • 1970-01-01
              • 2011-11-15
              • 2018-08-01
              相关资源
              最近更新 更多