Анализ алгоритмов, применяемых в настоящее время для поиска кратчайших путей между вершинами графа, позволил выявить алгоритмы Уоршолла, Дейкстры, Форда [1]. Все алгоритмы характеризуются разными вычислительными затратами и позволяют решать поставленную задачу, но наиболее эффективным считается алгоритм Дейкстры, предложенный в 1959 году.
Перед началом выполнения алгоритма все вершины и дуги не отмечены. Каждой вершине в ходе выполнения алгоритма присваивается число d(xi), равное длине кратчайшего пути из xi в xj, включающего только отмеченные вершины.
Выполняется присвоение начальных значений, для чего необходимо обозначить d(xi) пометку исходной вершины и считать, что d(xi) = 0. Отметить постоянной пометкой исходную вершину xi и положить y = xi, где y - последняя из отмеченных вершин. Остальные вершины имеют временные пометки и считать, что для xj ≠ y d(xj) = ∞. Алгоритм итерационный. Каждая итерация состоит из ряда шагов. Алгоритм Дейкстры рассмотрен на примере взвешенного графа (рисунок 1, a). Матрица весов дуг приведена на рисунке 1,b. Требуется найти кратчайший путь от вершины x1 до вершины x6 .
Выполняется присвоение начальных значений: d(x1) = 0; xi ≠ x1 d(xi) = ∞.
Для каждой итерации, в соответствующую строку таблицы 1 заносится отмеченная вершина и текущие значения d(xi). Для 1-й итерации будем иметь:
y = x1. Г(x1) = {x2, x3, x4}. Для всех вершин, входящих в Г(x1), пометки которых временные, необходимо пересчитать d(xi) в виде:
d(x2) = min [d(x2), d(x1) + t(x1, x2)] = min [∞, 0 + 4] = 4. Аналогично для d(x3) , d(x4). Массив временных пометок будет иметь вид: {d(x2), d(x3) , d(x4)} = {4, 3, 7}.
Поскольку величина d(x3) = 3 является минимальной, то вершина x3 отмечается x3*. Также отмечается и дуга (x1, x3)*. Наименьшее из значений d(xi) среди неотмеченных вершин в таблице 1 выделено полужирным шрифтом.
Текущее дерево кратчайших путей состоит из дуги (x1, x3)* (рисунок 2,а).
Таким образом, выполнив еще 4 итерации, получим окончательно построенное дерево кратчайших путей, которое состоит из дуг (x1, x3)*, (x1, x2)*, (x3, x5)*, (x2, x4)* и (x5, x6)* (рисунок 2,д).
Кратчайший путь, соединяющий вершину x1 с вершиной x6, состоит из дуг (x1, x2), (x2, x5) и (x5, x6) имеет длину 4+2+2 =8. Это не единственный кратчайший путь между вершинами x1 и x6. Путь, состоящий из дуг (x1, x3), (x3, x5) и (x5, x6) имеет длину 3+3+2 =8 и также является кратчайшим путем между вершинами x1 и x6.
Существуют алгоритмы более эффективные, чем процедура многократного повторения алгоритма Дейкстры. Эти алгоритмы принадлежат Флойду и Данцигу. В обоих алгоритмах для длин дуг допускаются отрицательные значения, однако не допускается наличие контуров отрицательной длины.
Как видно из описания алгоритмов поиска кратчайших путей, в основном они состоят из операций двух типов: операции сложения и операции сравнения по минимуму. При анализе вычислительной сложности любого из этих алгоритмов обычно предполагается, что для выполнения обеих операций требуется одинаковое время.
Литература
1. Майника Э. Алгоритмы оптимизации на сетях и графах. - М.: Мир, 1981. - 324 стр.
2. Новиков Ф. А. Дискретная математика для программистов. - Спб: Питер, 2000. - 304стр.
3. Хаггарти Р. Дискретная математика для программистов. - М.: Техносфера, 2005. - 400стр.