有向图的厄米邻接矩阵

问题描述

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

picture of definition

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

我想不出一种聪明的方法来制作这个 hermitian Adjacency Matrix,它不涉及一个一个地遍历我的节点。有什么建议吗?

解决方法

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

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)

说明

让我们从有向图开始:

enter image description here

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

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

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

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

现在,我们想对矩阵应用一个函数,使 0 映射到 02 映射到 11 映射到行号 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,-2,[ 3,3,[-4,-4,[ 5,5,-5,-5],6,-6,6],[ 0,7,-7,7],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,j-1] = -i
                else:
                    check[i-1,j-1] = 0
>>> (check == H).all()
True