Вы можете попробовать сделать версию Floyd-Warshall более быстрой на разреженных матрицах.
Во-первых, давайте вспомним, что делает этот алгоритм:
Пусть - матрица расстояний. В начале алгоритма - вес ребра . Если это ребро не существует, то .M i , j i → j M i , j = ∞MMя , джя → jMя , дж= ∞
Алгоритм имеет шагов. На шаге алгоритма для каждой пары узлов мы устанавливаемk i , jВКя , дж
Mя , дж← мин { Мя , дж, Mя , к+ МК , Дж} .
Ясно, что если или обновление не требуется. Таким образом, на первых этапах алгоритма нам нужно только приблизительно выполнить где и обозначают количество входящих и исходящих ребер узла соответственно. По мере развития алгоритма заполняется все больше и больше элементов матрицыСледовательно, последние шаги могут занять гораздо больше времени.Mя , к= ∞MК , Дж= ∞dе гя н( к ) ⋅ де го у т( к )dе гя н( к )dе го у т( к )КM
Обратите внимание, что нам нужен эффективный способ итерации только по бесконечным ячейкам в строке и столбце матрицы. Это можно сделать, сохранив набор входящих и исходящих ребер для каждого узла.k
Похоже, что первые шаги алгоритма могут значительно выиграть от разреженности. Например, случайно построенный граф с предполагает, что первая итерация ( ) состоит всего из шагов. Если график разбит на множество связанных компонентов, то матрица будет оставаться относительно разреженной по всему алгоритму, а общее время выполнения может составлять всего . С другой стороны, если граф содержит только одну связную компоненту, то последняя итерациякак ожидается, предпримет шагов. В этом случае общее время выполнения может быть . Столь же, как не разреженная версия.k = 0 O ( 1 ) M O ( V ) k = | V | O ( V 2 ) O ( V 3 )E=O(V)k=0O(1)MO(V)k=|V|O(V2)O(V3)