Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 计算scipy稀疏矩阵的稀疏传递闭包_Python_Numpy_Scipy_Sparse Matrix_Floyd Warshall - Fatal编程技术网

Python 计算scipy稀疏矩阵的稀疏传递闭包

Python 计算scipy稀疏矩阵的稀疏传递闭包,python,numpy,scipy,sparse-matrix,floyd-warshall,Python,Numpy,Scipy,Sparse Matrix,Floyd Warshall,我想用Python计算稀疏矩阵的。目前我正在使用scipy稀疏矩阵 矩阵幂(**12在我的例子中)适用于非常稀疏的矩阵,无论它们有多大,但对于定向不太稀疏的情况,我希望使用更智能的算法 我在中发现了(德语页面有更好的伪代码),这比它应该做的要多一些:只有Warshall的算法没有函数——这是一回事 主要问题是我可以将稀疏矩阵传递给函数,但这完全没有意义,因为函数总是返回密集矩阵,因为传递闭包中应该为0的现在是inf长度的路径,有人认为需要显式存储 所以我的问题是:是否有任何python模块允许计

我想用Python计算稀疏矩阵的。目前我正在使用scipy稀疏矩阵

矩阵幂(
**12
在我的例子中)适用于非常稀疏的矩阵,无论它们有多大,但对于定向不太稀疏的情况,我希望使用更智能的算法

我在中发现了(德语页面有更好的伪代码),这比它应该做的要多一些:只有Warshall的算法没有函数——这是一回事

主要问题是我可以将稀疏矩阵传递给函数,但这完全没有意义,因为函数总是返回密集矩阵,因为传递闭包中应该为0的现在是
inf
长度的路径,有人认为需要显式存储

所以我的问题是:是否有任何python模块允许计算稀疏矩阵的传递闭包,并使其保持稀疏

我不是100%确定他是否使用相同的矩阵,但杰拉尔德·佩恩(Gerald Penn)在这方面表现出了令人印象深刻的加速,这表明有可能解决这个问题


编辑:由于存在许多困惑,我将指出理论背景:

我正在寻找传递闭包(非自反或对称)

我将确保在布尔矩阵中编码的关系具有所需的属性,即对称性或自反性

我有两个关系的案例

  • 反射的
  • 自反对称
  • 我想对这两个关系应用传递闭包。这在矩阵幂下非常有效(只是在某些情况下过于昂贵):

    所以在第一种情况下,我们得到一个节点的所有子节点(包括它本身),在第二种情况下,我们得到所有组件,也就是同一组件中的所有节点

    这是我提出来的。问题不在于输出格式;Floyd Warshall的实现是从充满无穷大的矩阵开始,然后在找到路径时插入有限值。稀疏立即消失

    networkx库提供了另一种具有。它的输出是一个迭代器,它返回形式的元组

    (source, dictionary of reachable targets) 
    
    转换成SciPy稀疏矩阵(csr格式在这里很自然)需要一些工作。一个完整的例子:

    import numpy as np
    import networkx as nx
    import scipy.stats as stats
    import scipy.sparse as sparse
    
    A = sparse.random(6, 6, density=0.2, format='csr', data_rvs=stats.randint(1, 2).rvs).astype(np.uint8)
    G = nx.DiGraph(A)       # directed because A need not be symmetric
    paths = nx.all_pairs_shortest_path_length(G)
    indices = []
    indptr = [0]
    for row in paths:
      reachable = [v for v in row[1] if row[1][v] > 0]
      indices.extend(reachable)
      indptr.append(len(indices))
    data = np.ones((len(indices),), dtype=np.uint8)
    A_trans = A + sparse.csr_matrix((data, indices, indptr), shape=A.shape)
    print(A, "\n\n", A_trans)
    
    添加back的原因如下所示。Networkx输出包括长度为0的路径,这将立即填充对角线。我们不希望发生这种情况(您希望传递闭包,而不是自反和传递闭包)。因此,如果行[1][v]>0],则行
    reachable=[v代表行[1]中的v]。但是我们根本没有得到任何对角线条目,即使在A有对角线条目的地方(0长度的空路径比自循环形成的1长度路径好)。所以我给结果加了一个back。它现在有条目1或条目2,但只有它们不是零这一事实才有意义

    运行上述操作的一个示例(为了输出的可读性,我选择了6×6的大小)。原始矩阵:

      (0, 3)    1
      (3, 2)    1
      (4, 3)    1
      (5, 1)    1
      (5, 3)    1
      (5, 4)    1
      (5, 5)    1 
    
    传递闭包:

      (0, 2)    1
      (0, 3)    2
      (3, 2)    2
      (4, 2)    1
      (4, 3)    2
      (5, 1)    2
      (5, 2)    1
      (5, 3)    2
      (5, 4)    2
      (5, 5)    1
    
    您可以看到这是正确的:添加的条目是(0,2)、(4,2)和(5,2),所有条目都是通过路径(3,2)获取的


    顺便说一句,networkx也有方法,但它的文档中说

    该算法最适合于稠密图。运行时间是O(n^3),运行空间是O(n^2),其中n是G中的节点数

    输出再次密集。我得到的印象是,这个算法本质上被认为是稠密的。似乎所有对的最短路径长度是一种

    及物与反身 如果您想要传递闭包(包含给定路径的最小传递关系)和自反闭包(包含给定路径的最小传递和自反关系),而不是传递闭包,那么代码将简化,因为我们不再担心0长度路径

    for row in paths:
      indices.extend(row[1])
      indptr.append(len(indices))
    data = np.ones((len(indices),), dtype=np.uint8)
    A_trans = sparse.csr_matrix((data, indices, indptr), shape=A.shape)
    
    传递的、自反的和对称的 这意味着找到包含给定等价关系的最小等价关系。等效地,将顶点划分为连接的组件。为此,您不需要转到networkx,这里有一种SciPy方法。在此处设置
    directed=False
    。例如:

    import numpy as np
    import scipy.stats as stats
    import scipy.sparse as sparse
    import itertools
    
    A = sparse.random(20, 20, density=0.02, format='csr', data_rvs=stats.randint(1, 2).rvs).astype(np.uint8)
    components = sparse.csgraph.connected_components(A, directed=False)
    nonzeros = []
    for k in range(components[0]):
      idx = np.where(components[1] == k)[0]
      nonzeros.extend(itertools.product(idx, idx))
      row = tuple(r for r, c in nonzeros)
      col = tuple(c for r, c in nonzeros)
      data = np.ones_like(row)
    B = sparse.coo_matrix((data, (row, col)), shape=A.shape)
    
    这是一个随机示例的输出
    print(B.toarray())
    的样子,20 x 20:

    [[1 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0]
     [0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     [1 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0]
     [0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     [0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     [0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     [1 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0]
     [0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0]
     [1 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0]
     [1 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0]
     [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0]
     [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1]]
    

    关于PS,我想看一些例子(另一个问题?)。稀疏矩阵与密集数组相乘返回密集数组。为了提高效率,
    sparse.csr
    不会在每次更改值时更改稀疏索引。有时您必须运行
    消除_零
    来清除它。过去的示例:,如果乘法返回密集矩阵,请尝试先将
    其他
    数组转换为稀疏矩阵
    sparse*sparse
    生成
    sparse
    floyd_warshall
    sparse.csgraph.shortest_path中。所以
    ,一个编译模块。你说得对,我刚刚在“关于scipy的失望”下面收集了这个。。。我要问一个新问题。我有点担心创建python字典作为输出的开销,但可能真的没有基于C的实现返回稀疏的scipy矩阵……也许我误解了传递闭包的含义。我实际上想要你们所说的“自反和传递闭包”。这也是一个选项,但我希望有一个解决方案能够与通常的依赖项一起工作。numy或scipyConnected组件也执行对称闭包,因为关系“a和b在同一个组件中”是对称的。请向自己和他人明确说明,您是寻求传递闭包、传递闭包和自反闭包、传递闭包和自反闭包、对称闭包(因此,由给定闭包生成的等价关系)还是其他什么。添加了完整的示例f
    [[1 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0]
     [0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     [1 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0]
     [0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     [0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     [0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     [1 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0]
     [0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0]
     [1 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0]
     [1 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0]
     [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0]
     [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1]]