Context
В настоящее время я работаю над восстановлением пути в некоторых из моих алгоритмов графа.Для решения задачи «один источник-кратчайшие пути» я использовал массив предшественников для восстановления кратчайшего пути от одного узла-источника ко всем остальным узлам.
Быстрый пример: [0, 3, 0,0]
Кратчайший путь от источника 0 до цели 1 будет [0, 3, 1], потому что начиная с целевого узла 1, путь можно построить, возвращаясь назад, используя 'родительский массив.1 достигнуто за 3, а 3 достигнуто за 0. 0 является источником.Готово.
Следующие алгоритмы представляют собой алгоритмы всех пар кратчайших путей.Самым простым примером был алгоритм Флойда-Варшалла, в результате которого получается матрица, содержащая все узлы-преемники.Хороший пример псевдокода восстановления можно найти в Wikipedia - Floyd Warshall .Подводя итог: Матрица используется для хранения каждого преемника из одного конкретного исходного узла.В основном он использует тот же подход, что и раньше, для каждого узла в качестве источника и продвижения вперед, а не назад.
Вопрос - Как создать матрицу преемников в случае алгоритма псевдоумножения?
Давайте сначала посмотрим на алгоритм:
for(int m = 0; m < nodeCount - 1; m++) {
Matrix nextResultMatrix = new Matrix(nodeCount, nodeCount, Integer.MAX_VALUE);
for(int i = 0; i < nodeCount; i++) {
for(int j = 0; j < nodeCount; j++) {
int value = Integer.MAX_VALUE;
for(int k = 0; k < nodeCount; k++) {
value = Math.min(
value,
resultMatrix.at(i, k) + sourceMatrix.at(k, j)
);
}
nextResultMatrix.setAt(i, j, value);
}
}
resultMatrix = nextResultMatrix;
}
На каждой итерации будет вычисляться матрица для кратчайших путей длины m.Внутренний цикл очень похож на умножение матрицы.В самом внутреннем цикле алгоритм проверяет, является ли текущий путь короче пути от источника i по k до цели j.После завершения внутреннего k-цикла устанавливается значение внутри новой матрицы результатов.Что приводит к проблеме:
В случае алгоритма Флойда-Варшалла было легче определить, был ли путь короче и какой узел теперь является преемником.В этом случае значение, которое было вычислено в k-петле, будет установлено в любом случае.Можно ли здесь определить преемника?
Размышления о возможном решении
- Алгоритм псевдоумножения предоставляет матрицу для каждой итерации, которая представляет кратчайшие пути длины m.Может быть, это поможет найти решение, не увеличивая и без того сложную по времени и не сохраняя каждую матрицу одновременно.
- Я нашел интересную идею в комментарии здесь к stackoverflow, которая может привести крешение ссылка .Из того, что там заявлено, кажется, что это довольно тяжелая работа для отслеживания кратчайших путей.Я еще не полностью обдумал идею и то, как ее реализовать.