找到邻接矩阵中所有缺失的有向边

时间:2013-07-12 16:31:49

标签: python numpy graph-theory

我使用numpy矩阵来表示有向图,如下所示:

0 0 0
1 0 1
1 0 0

给定这样的矩阵,我想找到所有缺失的有向边,其中存在相反方向的有向边。

例如,在上面的矩阵中,对于节点1(索引为0),边缘1 -> 21 -> 3在这个意义上缺失,因为存在边2 -> 13 -> 1在另一个方向。同样,由于存在边3 -> 2,边2 -> 3也会丢失。

我的应用程序中的实际矩阵很大,例如数千个节点,用于查找此类边缘的算法必须快速。蛮力方法是检查每对(给定矩阵的主对角线对称)并查看两者之间是否缺少边缘。

我想知道是否有一种更有效的方法(由numpy提供?)来做到这一点。一些线性代数技巧?

2 个答案:

答案 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)