- •Очередь
- •Двусвязные списки
- •Пример использования стеков: постфиксная, префиксная и инфиксная записи
- •Бинарныедеревья
- •Общие деревья
- •Реализация деревьев
- •Представление графов
- •Задача нахождения кратчайшего пути
- •Нахождение кратчайших путей между парами вершин
- •Транзитивное замыкание
- •Нахождение центра ориентированного графа
- •Обход ориентированных графов
Задача нахождения кратчайшего пути
Рассмотрим задачи нахождения путей в ориентированном графе. Пусть есть ориентированный граф G, у которого все дуги имеют неотрицательные веса, а одна вершина определена как источник. Задача состоит в нахождении стоимости кратчайших путей от источника ко всем другим вершинам графаG(длина пути определяется как сумма стоимостей дуг, составляющих путь). Эта задача часто называется задачей нахождения кратчайшего пути с одним источником (может показаться, что более естественной задачей будет нахождение кратчайшего пути от источника к определенной вершине назначения, но эта задача в общем случае имеет такой же уровень сложности, что и задача нахождения кратчайшего пути для всех вершин графа, за исключением того счастливого случая, когда путь к вершине назначения будет найден ранее, чем просмотрены пути ко всем вершинам графа).
Для решения поставленной задачи будем использовать «жадный» алгоритм, который часто называют алгоритмом Дейкстры (Dijkstra). Алгоритм строит множествоSвершин, для которых кратчайшие пути от источника уже известны. На каждом шаге к множествуSдобавляется та из оставшихся вершин, расстояние до которой от источника меньше, чем для других оставшихся вершин. Если стоимости всех дуг неотрицательны, то можно быть уверенным, что кратчайший путь от источника к конкретной вершине проходит только через вершины множестваS. Назовем такой путь особым. На каждом шаге алгоритма используется также массивD, в который записываются длины кратчайших особых путей для каждой вершины. Когда множествоSбудет содержать все вершины орграфа, то есть для всех вершин будут найдены особые пути, тогда массивDбудет содержать длины кратчайших путей от источника к каждой вершине.
Пример. Алгоритм Дейкстры. Здесь предполагается, что в орграфеGвершины поименованы целыми числами, а вершина 1 является источником. Массив С – двумерный массив стоимостей, где элементC[i,j] равен стоимости дугиij. Если такой дуги не существует, тоC[i,j] берется равным, то есть большим любой фактической стоимости дуг. На каждом шагеD[i] содержит длину текущего кратчайшего особого пути к вершинеi.
v
oid
Dijkstra ()
{
int i;
S = {1};
for (i=2; i<=n; i++)
D[i] = C[1][i]; //инициализация D
for (i=1; i<=n-1; i++)
{
выбор из множества S такой вершины w,
что значение D[w] минимально;
добавить w к множеству S;
for каждая вершина v из множества S
D[v] = min (D[v], D[w]+C[w][v];
}
}
Применим алгоритм Дейкстры для орграфа с рисунка 13. Вначале S={1},D[2]=10,D[3]=,D[4]=30,D[5]=100. На первом шаге циклаw=2, то есть вершинаwимеет минимальное значение в массивеD. Затем вычисляемD[3]=min(, 10+50)=60.D[4] иD[5] не изменяются, так как не существует дуг, исходящих из вершины 2 и ведущих к вершинам 4 и 5. Последовательность значений элементов массиваDпосле каждой итерации цикла показаны в таблице:
|
Итерации |
S |
W |
D[2] |
D[3] |
D[4] |
D[5] |
|
Начало |
{1} |
- |
10 |
|
30 |
100 |
|
1 |
{1, 2} |
2 |
10 |
60 |
30 |
100 |
|
2 |
{1, 2, 4} |
4 |
10 |
50 |
30 |
90 |
|
3 |
{1, 2, 4, 3} |
3 |
10 |
50 |
30 |
60 |
|
4 |
{1, 2, 4, 3, 5} |
5 |
10 |
50 |
30 |
60 |
Несложно внести изменения в алгоритм так, чтобы можно было определить сам кратчайший путь (то есть последовательность вершин) для любой вершины. Для этого надо ввести еще один массив Р вершин, где P[v] содержит вершину, непосредственно предшествующую вершинеvв кратчайшем пути. Вначале положимP[v]=1 для всехv1. В конец цикла добавим условный оператор с условиемD[w]+C[w,v]<D[v], при выполнении которого элементуP[v] присваивается значениеw. После выполнения алгоритма кратчайший путь к каждой вершине можно найти с помощью обратного прохождения по предшествующим вершинам массива Р.
Если количество дуг значительно меньше квадрата количества вершин, то лучшим выбором для представления орграфа будут списки смежности, а для множества вершин – очередь с приоритетами, реализованная в виде частично упорядоченного дерева.
