- •А.Н. Горитов
- •Учебное пособие
- •Учебное пособие
- •Введение
- •1 Введение в предмет
- •1.1 Непрерывная и дискретная информация
- •1.2 Данные и эвм
- •1.3 Объекты предметной области
- •1.4 Представление информации об объектах
- •1.5 Абстрактные алфавиты. Кодирование
- •2 Основные типы и структуры данных эвм
- •2.1 Архитектурные особенности эвм, наиболее существенные для представления данных
- •2.2 Основные понятия о типах и структурах данных
- •2.3 Массивы
- •2.4 Строки
- •2.5 Записи
- •2.6 Записи с вариантами
- •2.7 Множества
- •3 Последовательный файл
- •3.1 Основные свойства последовательных файлов
- •3.2 Сортировка последовательных файлов
- •4 Полустатические структуры
- •4.1 Стек, очередь и дек как полустатические структуры
- •4.2 Представление полустатических структур с помощью массивов
- •5 Линейные динамические структуры
- •5.1 Основные свойства динамических структур
- •5.2 Реализация связного списка массивом
- •5.3 Кольцевой связный список
- •5.4 Линейный двусвязный список
- •6 Представление динамических структур с помощью указателей
- •6.1 Указатели
- •6.2 Представление стека
- •6.3 Представление очереди
- •6.4 Ведение динамических списков с помощью указателей
- •6.5 Алгоритм составления кольцевого двусвязного списка
- •7 Древовидные структуры данных
- •7.1 Основные понятия и определения
- •7.2 Представление деревьев в эвм
- •7.3 Основные операции с бинарными деревьями
- •7.4 Сильно ветвящиеся деревья
- •8 Алгоритмы на графах
- •8.1 Машинное представление графов
- •8.2 Поиск в глубину в графе
- •8.3 Поиск в ширину в графе
- •8.4 Стягивающие деревья (каркасы)
- •8.5 Отыскание фундаментального множества циклов в графе
- •8.6 Эйлеровы пути в графе
- •8.7 Алгоритмы с возвратом
- •8.8 Нахождение кратчайших путей в графе
- •8.9 Кратчайшие пути от фиксированной вершины
- •8.10 Алгоритм Дейкстры
- •8.11 Пути в бесконтурном графе
- •Литература
8.10 Алгоритм Дейкстры
Существуют более эффективные алгоритмы для двух важных случаев:
веса всех дуг неотрицательны;
граф не имеет контуров.
Для первого случая справедлив известный нам алгоритм Дейкстры. Обобщенно он может быть записан следующим образом.
1 BEGIN
FOR v eV DO D[v] := a[s, v]; D[s] := 0;
T := V \ {s};
WHILE T;t0DO
BEGIN
u := произвольная вершина t eT, такая, что D[t]=min{D[p], peT};
T := T \ {u};
FOR v eT DO D[v] := min(D[v], D[u]+a[u, v])
9 END
10 END
Чтобы пояснить работу алгоритма, покажем, что инвариантом цикла 4 является следующее условие: для каждой вершины D[v]=d(s, v), v eV \ T
D[v]= длине кратчайшего из тех путей из s в v, для которых предпоследняя вершина принадлежит множеству V \ Т. В самом деле, в строке 5 мы находим вершину и еТ такую, что значение D[u] является минимальным из всех значением D[t] для t еТ. Причем, D[u]=d(s,u).
Это действительно так, потому что, если кратчайший путь из s в и имеет длину меньше D[u], то в силу второй части условия (1) его предпоследняя вершина принадлежит множеству Т. Пусть t - первая вершина пути, принадлежащая множеству Т. Начальный отрезок нашего пути из s в t составляет кратчайший путь из s в t, причем его предпоследняя вершина не принадлежит множеству Т. По первой части условия (1) имеем
D[t] = d(s, t). Используя предположение о неотрицательности весов, получаем
D[t] = d(s, t)<d(s, u) < D[u] вопреки принципу, по которому была выбрана вершина и.
Таким образом D[u] = d(s, и) и мы можем в строке 7 удалить и из множества Т, не нарушая 1-ой части условия (1). Чтобы обеспечить выполнение также и второй части условия (1), нужно еще проверить пути из s в v еТ, предпоследняя вершина в которой есть и, и уточнить оценки D[v], v еТ. Именно это выполняет цикл 8.
Очевидно, что условие (1) выполняется при входе в цикл 4. По окончании работы алгоритма Т = 0, а следовательно, согласно условию (1), D[v]=d(s, v), veV.
Оценим сложность алгоритма Дейкстры. Цикл 4 выполняется п-1 раз, прчем каждое его выполнение требует 0(п) шагов:
(1)
для каждой вершины v еТ
O(n) шагов для нахождения вершины u в строке 6 и O(n) шагов для выполнения цикла 8.
Таким образом общая сложность алгоритма есть O(n2). При удачном подборе структуры данных можно получить вариант алгоритма со сложностью O(mlog2n). Для этого множество T нужно представить бинарным деревом с высотой O(log2n) и с таким свойством, что для произвольных его вершин u и v,
если u – сын v, то D[u]≤D[v]. (2)
Вершина u, для которой D[u] минимально, является тогда корнем дерева. Этот корень можно устранить за O(log n) шагов, сохраняя свойство уменьшения значения D[j] на каждом пути до корня. Достаточно сместить на место корня его сына s с большим (или равным) значением D[j], затем на освободившееся место передвинуть сына вершины s с большим значением D[j] и т.д.
Если граф представлен списками инцидентности, то строку 8 можно заменить на FOR v∈СПИСОК[u] DO
IF D[u] + a(u, v) < D[v] THEN BEGIN D[v] := D[u] + a(u, v); передвинуть вершину v в дереве в направлении корня
так,
чтобы сохранить условие (2)
END
Если существует таблица указателей на вершины нашего дерева, то передвижение вершины v может быть осуществлено за O(log n) шагов.
В алгоритме, модифицированном таким способом, каждая дуга графа анализируется ровно один раз, причем с этим связано O(log n) шагов на перемещение соответствующей вершины в дереве, представляющем множество T. Это дает в сумме O(mlog n) шагов. Сюда нужно добавить O(nlog n) шагов, необходимых для построения нашего дерева и для устранения n-1 раз из него корня. Общая сложность алгоритма есть O(mlog n).