【问题标题】:Hermitian Adjacency Matrix of Digraph有向图的厄密邻接矩阵
【发布时间】:2021-04-21 03:52:28
【问题描述】:

我正在尝试找到一种 Python 方法来计算 Python 中的 Hermitian 邻接矩阵,但我真的很挣扎。 Hermitian Adjacency 矩阵的定义如下图所示:

它的工作原理如下。假设我们有两个名为ij 的节点。如果从i to jj to i 都有一条有向边,则位置 [i, j] 处的相应矩阵值应设置为 1。如果只有来自i to j 的有向边,则位置 [i, j] 处的矩阵元素应设置为 +i。如果只有来自j to i 的有向边,则位置 [i, j] 的矩阵元素应设置为 -i。所有其他矩阵值都设置为 0。

我想不出一种聪明的方法来制作这个不涉及逐个遍历我的节点的 Hermitian 邻接矩阵。有什么建议吗?

【问题讨论】:

    标签: python-3.x networkx graph-theory


    【解决方案1】:

    我认为没有内置的,所以我拼凑了我自己的矢量化解决方案:

    import numpy as np
    import networkx as nx
    
    # Create standard adjacency matrix
    A = nx.linalg.graphmatrix.adjacency_matrix(G).toarray()
    
    # Add to its transpose and convert from sparse array
    B = A + A.T
    
    # Get row index matrix
    I = np.indices(B.shape)[0] + 1
    
    # Apply vectorised formula to get Hermitian adjacency matrix
    H = np.multiply(B/2 * (2*I)**(B%2), 2*A-1).astype(int)
    

    说明

    让我们从有向图开始:

    我们首先使用nx.linalg.graphmatrix.adjacency_matrix() 创建正常的邻接矩阵,得到以下矩阵:

    >>> A = nx.linalg.graphmatrix.adjacency_matrix(G).toarray()
    [[1, 1, 0, 1, 0, 1, 0, 0],
     [1, 0, 0, 1, 0, 0, 1, 0],
     [1, 1, 1, 1, 0, 1, 0, 0],
     [0, 1, 0, 0, 0, 0, 0, 0],
     [1, 0, 0, 1, 0, 0, 0, 0],
     [1, 1, 0, 0, 1, 0, 1, 1],
     [0, 1, 0, 0, 1, 0, 0, 1],
     [0, 0, 0, 0, 1, 0, 0, 0]]
    

    然后我们可以将这个矩阵添加到它的转置中,在每个有从i to j 的有向边的位置给我们2,反之亦然,在每个只有这些边之一的位置给我们一个1存在,并且在每个不存在边缘的位置都有一个0

    >>> B = A + A.T
    >>> B
    [[2, 2, 1, 1, 1, 2, 0, 0],
     [2, 0, 1, 2, 0, 1, 2, 0],
     [1, 1, 2, 1, 0, 1, 0, 0],
     [1, 2, 1, 0, 1, 0, 0, 0],
     [1, 0, 0, 1, 0, 1, 1, 1],
     [2, 1, 1, 0, 1, 0, 1, 1],
     [0, 2, 0, 0, 1, 1, 0, 1],
     [0, 0, 0, 0, 1, 1, 1, 0]]
    

    现在,我们要对矩阵应用一个函数,使0 映射到02 映射到1,而1 映射到行号i。我们可以使用np.indices() 来获取行号,并使用以下等式:x/2 * (2*i)**(x%2),其中i 是行号,x 是元素。最后,我们需要将不存在边ij 的位置的元素乘以-1。这可以向量化如下:

    >>> I = np.indices(B.shape)[0] + 1
    >>> H = np.multiply(B/2 * (2*I)**(B%2), 2*A-1).astype(int)
    >>> H
    [[ 1,  1, -1,  1, -1,  1,  0,  0],
     [ 1,  0, -2,  1,  0, -2,  1,  0],
     [ 3,  3,  1,  3,  0,  3,  0,  0],
     [-4,  1, -4,  0, -4,  0,  0,  0],
     [ 5,  0,  0,  5,  0, -5, -5, -5],
     [ 1,  6, -6,  0,  6,  0,  6,  6],
     [ 0,  1,  0,  0,  7, -7,  0,  7],
     [ 0,  0,  0,  0,  8, -8, -8,  0]]
    

    根据需要。

    我们可以使用简单的迭代节点方法来检查这是否正确:

    >>> check = np.zeros([8,8])
    >>> for i in G.nodes:
            for j in G.nodes:
                if (i, j) in G.edges:
                    if (j, i) in G.edges:
                        check[i-1, j-1] = 1
                    else:
                        check[i-1, j-1] = i
                else:
                    if (j, i) in G.edges:
                        check[i-1, j-1] = -i
                    else:
                        check[i-1, j-1] = 0
    >>> (check == H).all()
    True
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多