【发布时间】:2018-06-04 00:54:11
【问题描述】:
我想在 Python 中计算稀疏矩阵的 transitive closure。目前我正在使用 scipy 稀疏矩阵。
矩阵幂(在我的例子中为**12)适用于非常稀疏的矩阵,无论它们有多大,但对于有向的不太稀疏的情况,我想使用更智能的算法。
我在scipy.sparse.csgraph 中找到了Floyd-Warshall algorithm(德文页面有更好的伪代码),这比它应该做的要多一点:没有仅适用于Warshall 算法的函数 - 这是一回事。
主要问题是我可以将稀疏矩阵传递给函数,但这完全没有意义,因为函数将始终返回一个密集矩阵,因为传递闭包中应该为 0 的现在是 inf 的路径长度,有人觉得这需要明确存储。
所以我的问题是:是否有任何 python 模块允许计算稀疏矩阵的传递闭包并保持其稀疏?
我不能 100% 确定他使用相同的矩阵,但 Gerald Penn 在 his comparison paper 中显示出令人印象深刻的加速提升,这表明有可能解决该问题。 p>
编辑:由于存在许多混淆,我将指出理论背景:
我正在寻找传递闭包(不是自反或对称的)。
我将确保我在布尔矩阵中编码的关系具有所需的属性,即对称性或自反性。
我有两种关系:
- 自反
- 自反和对称
我想对这两个关系应用传递闭包。这对矩阵功率非常有效(只是在某些情况下它太昂贵了):
>>> reflexive
matrix([[ True, True, False, True],
[False, True, True, False],
[False, False, True, False],
[False, False, False, True]])
>>> reflexive**4
matrix([[ True, True, True, True],
[False, True, True, False],
[False, False, True, False],
[False, False, False, True]])
>>> reflexive_symmetric
matrix([[ True, True, False, True],
[ True, True, True, False],
[False, True, True, False],
[ True, False, False, True]])
>>> reflexive_symmetric**4
matrix([[ True, True, True, True],
[ True, True, True, True],
[ True, True, True, True],
[ True, True, True, True]])
所以在第一种情况下,我们得到一个节点的所有后代(包括它自己),而在第二种情况下,我们得到所有组件,即在同一个组件中的所有节点。
【问题讨论】:
-
关于 PS,我想看一些例子(在另一个问题中?)。稀疏矩阵与密集数组的乘法返回密集数组。为提高效率,
sparse.csr不会在每次更改值时更改稀疏索引。有时你必须运行eliminate_zeros来清理它。 -
如果乘法返回密集矩阵,请先尝试将
other数组转换为稀疏矩阵。sparse*sparse产生sparse。 -
floyd_warshall在sparse.csgraph.shortest_path.so中,一个已编译的模块。 -
你说得对,我刚刚在“对 scipy 的失望”下收集了这个......我会为此做一个新问题。
标签: python numpy scipy sparse-matrix floyd-warshall