Было бы легче понять, что вы делаете, если вы используете матрицу для сохранения результата в матрице.Рассмотрим следующий простой взвешенный граф:
2
1 +---------+ 2
|\ |
| -\ |
3 | -\5 | 2
| -\ |
| -\|
3 +---------+ 4
4
Теперь рассмотрим эту реализацию алгоритма Флойд-Варшалла :
public Matrix floyd() {
Matrix m = new Matrix(numVertices, numVertices, Integer.MAX_VALUE);
for (int i = 1; i<=numVertices; i++) {
EdgeNode edge = edges[i];
while (edge != null) {
m.setData(i, edge.getY(), edge.getWeight());
edge = edge.getNext();
}
m.setData(i, i, 0);
}
for (int i = 1; i <= numVertices; i++) {
for (int j = 1; j <= numVertices; j++) {
for (int k = 1; k <= numVertices; k++) {
if (m.getData(i, j) < Integer.MAX_VALUE && m.getData(i, k) < Integer.MAX_VALUE) {
int through = m.getData(i, j) + m.getData(i, k);
if (through < m.getData(j, k)) {
m.setData(j, k, through);
}
}
}
}
}
return m;
}
Первая часть этого семени матрицырезультат с Integer.MAX_VALUE
.Установка 0 здесь приведет к неверному результату, но использование значений 1 и 0 (соответственно) будет хорошо работать для невзвешенного графика.Integer.MAX_VALUE
существует просто для правильной проверки минимального значения.
Вторая часть является ключевой частью алгоритма.Он смотрит на расстояние между двумя точками (i, k), сравнивая его с расстоянием (i, j) + (j, K) для всех вершин j.Если косвенный путь меньше, он подставляется в матрицу как кратчайший путь и т. Д.
Результат этого алгоритма на приведенном выше (очень простом) графике:
[ 0 2 3 5 ]
[ 2 0 5 3 ]
[ 3 5 0 4 ]
[ 5 3 4 0 ]
Это говорит вам о кратчайшем расстоянии между любой парой вершин. Примечание: Я добавил результат (i, i) в 0, так как вы можете утверждать, что расстояние любого узла до него равно 0. Вы можете достаточно легко отказаться от этого предположения, получив результат:
[ 4 2 3 5 ]
[ 2 4 5 3 ]
[ 3 5 6 4 ]
[ 5 3 4 6 ]
Таким образом, узел 3 сам по себе - это расстояние 6, когда он проходит 3-> 1-> 3 как кратчайший путь.Это было бы намного интереснее в ориентированном графе, который может обрабатывать Флойд.
Флойд - алгоритм O (n 3 ).Он не будет реконструировать фактический путь между каждой парой точек, только общее расстояние (вес).Вы можете использовать алгоритм Дейкстры между каждой парой вершин, чтобы построить фактические пути, что довольно интересно, также O (n 3 ), но имеет тенденцию быть медленнее в реальном мире, как вычисленияФлойд довольно прост.
Ваш алгоритм использует список смежности вместо матрицы для реализации этого алгоритма, что немного запутывает проблему.Моя версия использует Integer.MAX_VALUE
в качестве часового значения, чтобы указать отсутствие пути (пока не рассчитано), тогда как ваша использует отсутствие ребра для той же вещи.Кроме того, это точно так же.