我使用numpy
矩阵来表示有向图,如下所示:
0 0 0
1 0 1
1 0 0
给定这样的矩阵,我想找到所有缺失的有向边,其中存在相反方向的有向边。
例如,在上面的矩阵中,对于节点1
(索引为0),边缘1 -> 2
和1 -> 3
在这个意义上缺失,因为存在边2 -> 1
和3 -> 1
在另一个方向。同样,由于存在边3 -> 2
,边2 -> 3
也会丢失。
我的应用程序中的实际矩阵很大,例如数千个节点,用于查找此类边缘的算法必须快速。蛮力方法是检查每对(给定矩阵的主对角线对称)并查看两者之间是否缺少边缘。
我想知道是否有一种更有效的方法(由numpy
提供?)来做到这一点。一些线性代数技巧?
答案 0 :(得分:2)
我稍微修改了你的例子,以显示一对节点在两个方向上连接的情况。这是一种用numpy做的方法:
import numpy as np
A = np.array([[0, 1, 0],
[1, 0, 1],
[1, 0, 0]]).astype(bool)
A = A
print A.astype(int)
B = A.transpose() & ~A
print B.astype(int)
这应该给出:
[[0 1 0]
[1 0 1]
[1 0 0]]
[[0 0 1]
[0 0 0]
[0 1 0]]
我认为这就是你想要的。如果你的矩阵非常大,你可以考虑使用稀疏矩阵,但原理是相同的。
<强>解释强>:
对于任何边,A [i,j],该边的反转是A [j,i]。 A [j,i]与A.transpose()[i,j]相同。因此,如果反转每条边的方向,则A.transpose()是图形的邻接矩阵。 〜运算符等同于np.logical_not函数。只要没有边缘,~A的值就是1。您对“缺少连接”感兴趣,这些连接不在A中但在A.transpose()中。您可以使用&amp ;;获得这些连接。运算符,相当于A.transpose()和~A。
上的np.logical_and答案 1 :(得分:0)
像这样的邻接矩阵应该是对称的。如何取下三角形部分,将其移位并将其与上三角形部分进行比较?像这样:
low = tril(m).transpose()
upp = triu(m)
missing = mod(low + upp, 2)
missing
应为1,其中上三角部分缺少位置。
如果您只关心它确保上部是正确的,您可以执行以下操作:
m = tril(m).transpose() + tril(m)