Numpy 从自反非对称传递关系中删除不必要的对

Numpy 从自反非对称传递关系中删除不必要的对,numpy,graph,scipy,relation,minimum-spanning-tree,Numpy,Graph,Scipy,Relation,Minimum Spanning Tree,我有一个自反的不对称传递关系,表示为nxnsparsescipycsr矩阵 现在,由于一些转换,我留下了许多“不必要的”对: set([('a','b'),('b','c'),('a','c')]) 我需要删除对('a','c'),当存在“间接”边时,这些对可以被视为“直接”边 首先,我认为这是一个特殊的,但实际上在以下情况下: set([('a','b'),('b','d'),('a','c'),('c','d')]) 。。。不应移除任何一对。结果不一定是一棵树 这类问题有名字吗 sci

我有一个自反的不对称传递关系,表示为
n
x
n
sparse
scipy
csr矩阵

现在,由于一些转换,我留下了许多“不必要的”对:

set([('a','b'),('b','c'),('a','c')])
我需要删除对
('a','c')
,当存在“间接”边时,这些对可以被视为“直接”边

首先,我认为这是一个特殊的,但实际上在以下情况下:

set([('a','b'),('b','d'),('a','c'),('c','d')])
。。。不应移除任何一对。结果不一定是一棵树

  • 这类问题有名字吗

  • scipy
    中是否有实现

  • 如果没有,您能否在
    python
    /
    numpy
    /
    scipy
    中推荐一种有效的算法

EDIT:这似乎被称为传递性归约? 但是没有
scipy.sparse.csgraph
实现?


编辑:我想要得到一个无环有向图,我必须(暂时)去掉“自反性”,但这不是问题。

所以这个问题被称为有向无环图的传递归约

下面的代码应该可以解决这个问题,尽管它可能远远不是最优的:

def transitive_reduction(edges): # edges is irreflexive and scipy sparse bool
    reduction = edges.copy()
    num, i    = 99,2
    while num > 0:
        new        = edges**i
        num        = len(new.nonzero()[0])
        reduction  = reduction > new
        i         += 1
        reduction.eliminate_zeros() # might or might not be required
    return reduction
说明:只要存在此长度的路径,我们就从
reduce
中删除所有存在长度为
i
的间接路径的直接路径


归功于@PaulPanzer。

你不能检查矩阵和它的平方/幂之间的重叠吗?但是平方/幂仍然有“间接”边-或者没有?所以所有的东西都是重叠的。我从你的样本中假设“自反”(意思是“自我”,对吧?)边没有明确建模。如果是,则必须在相乘之前删除对角线。然后,正方形应该只包含长度为2的路径的端点,因此如果它们出现在原始邻接中,则应删除这些端点。不知道这是否有效。哦,好吧,我不知道。这可能不是特别有效,但肯定是一种选择。我对没有
scipy
实现感到有点失望,但我想也可以,