Я хочу вычислить транзитивное замыкание разреженной матрицы в Python. . В настоящее время я использую разреженные матрицы scipy.
Степень матрицы (в моем случае **12
) хорошо работает на очень разреженных матрицах, какими бы большими они ни были, но для направленных не очень разреженных случаев хотелось бы использовать более умный алгоритм.
Я нашел алгоритм Флойда-Уоршалла (немецкая страница лучше псевдокод) в scipy.sparse.csgraph
, который делает немного больше, чем должен: нет функции только для алгоритма Уоршалла - это одно.
Основная проблема в том, что я могу передать в функцию разреженную матрицу, но это совершенно бессмысленно, так как функция всегда будет возвращать плотную матрицу, потому что то, что должно быть 0 в транзитивном замыкании, теперь является путем длины inf
и кто-то это почувствовал необходимо хранить в явном виде.
Итак, мой вопрос: Есть ли какой-либо модуль Python, который позволяет вычислять транзитивное замыкание разреженной матрицы и сохраняет ее разреженной?
Я не уверен на 100%, что он работает с теми же матрицами, но Джеральд Пенн показывает впечатляющее ускорение в его сравнительный документ, из которого следует, что проблему можно решить.
РЕДАКТИРОВАТЬ: Поскольку возник ряд недоразумений, я укажу на теоретическую подоплеку:
Я ищу транзитивное замыкание (не рефлексивное и не симметричное).
Я позабочусь о том, чтобы мое отношение, закодированное в булевой матрице, обладало требуемыми свойствами, т. е. симметрией или рефлексивностью.
У меня есть два случая отношения:
- рефлексивный
- рефлексивный и симметричный
Я хочу применить транзитивное замыкание к этим двум отношениям. Это прекрасно работает с мощностью матрицы (только в некоторых случаях это слишком дорого):
>>> 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]])
Таким образом, в первом случае мы получаем всех потомков узла (включая самого себя), а во втором — все компоненты, то есть все узлы, находящиеся в одном компоненте.
sparse.csr
не меняет индекс разреженности каждый раз, когда вы меняете значение. Иногда вам нужно запуститьeliminate_zeros
, чтобы очистить его. - person hpaulj   schedule 21.12.2017other
в разреженную матрицу.sparse*sparse
производитsparse
. - person hpaulj   schedule 21.12.2017floyd_warshall
находится вsparse.csgraph.shortest_path.so
, скомпилированном модуле. - person hpaulj   schedule 21.12.2017