- •Предназначено студентам очной формы обучения.
- •Введение
- •1. Оценки сложности алгоритмов
- •1.1. Определение понятия алгоритм
- •1.2. Оценка сложности алгоритмов
- •2. Линейные структуры данных
- •2.1. Методы организации и хранения линейных списков
- •2.2. Операции со списками при последовательном хранении
- •2.3. Операции со списками при связном хранении
- •2.4. Организация двусвязных списков
- •Задания для самоконтроля
- •2.5. Стеки и очереди
- •2.6. Сжатое и индексное хранение линейных списков
- •3. Сортировка и слияние
- •3.1. Пузырьковая сортировка
- •3.2. Сортировка вставкой
- •3.3. Сортировка посредством выбора
- •3.4. Сортировка квадратичной выборкой
- •3.5. Слияние списков
- •3.6. Сортировка списков путем слияния
- •3.7. Быстрая и распределяющая сортировки
- •4. Поиск
- •4.1. Последовательный поиск
- •4.2. Бинарный поиск
- •4.4. Методы вычисления адреса
- •4.5. Выбор в линейных списках
- •5. Рекурсия
- •6. Алгоритмы на графах и сетях
- •6.1. Исходные понятия
- •6.2. Матричные представления графов
- •6.3. Другие представления графов
- •6.4. Поиск в глубину как система исследования графа
- •6.5. Перебор цепей поиском в глубину
- •6.6. Взвешенные графы. Ориентированные графы
- •6.7. Нахождение фундаментального множества циклов
- •6.8. Выявление мостов и точек сочленений
- •6.9. Поиск в ширину как система исследования графа
- •6.10. Кратчайшие пути, ведущие от заданного узла X ко всем прочим
- •6.11. Алгоритм Дейкстры нахождения кратчайших путей во взвешенном графе
- •6.12. Улучшения алгоритма Дейкстры
- •6.13. Построение кратчайшего каркаса
- •6.14. Нахождение всевозможных кратчайших путей в графе
- •6.15. Потоковые задачи
- •6.16. Пример практической задачи на графах
- •7. Генераторы случайных и псевдослучайных последовательностей
- •7.1. Общая постановка задачи
- •7.3. Генератор случайных чисел, поставляемый с системой
- •7.4. Генератор с малым кодом
- •7.5. Генератор Парка-Миллера
- •7.6. Улучшенная версия генератора Парка-Миллера
- •7.7. Быстрый генератор для 32-битового представления целых и действительных чисел
- •7.8. Алгоритм л'Экюера, комбинирующий две последовательности
- •Оглавление
- •7. Генераторы случайных и псевдослучайных последовательностей 144
- •394026 Воронеж, Московский просп., 14
6.12. Улучшения алгоритма Дейкстры
В матрице смежности из примера 5.11 отсутствие ребра показано О, тогда как в исходном алгоритме [7] используют знак , что логично. Матрицу мы заменим другим описанием, ибо ее применение делает неизбежной оценку сложности О (n2 ).
Граф G2 (см. п.5.11) описывают следующие пары (1-й элемент - номер узла, 2-й – вес ребра):
(2,20),(6,30),(4,30),(5,70),
(1,20),(4,20),(5,100),
(4,70),(5,40))(6,20),
(1,30),(2,20),(3170),
(1,70),(2,100),(3,40),(6,30),
(1,30),(3,20),(5,30) .
и оглавление этого списка, показывающее, что 4 первые пары относятся к связям 1-го узла, 3 следующих - к связям 2-го узла и т.д. Другими словами, для построения оглавления надо задать степени stp узлов графа G2: 4, 3,3, 3, 4, 3.
Анализ программы примера 5.11 показывает, что нахождение минимума путем перебора ведет к сложности О(n2) независимо от представления графа. С целью сокращения затрат времени применим для выбора минимума структуру, а именно - динамическое сортдерево (п.1.8), образуемое непостоянными оценками d узлов. Минимальная из них будет в корне сортдерева, где ее просто найти и откуда ее легко исключить при переводе в ранг постоянной.
Улучшение оценки узла требует исключения прежней оценки и внедрение в сортдерево новой. Для нас - это единый акт продвижения измененной оценки "вниз", к корню, так как оценка может лишь уменьшиться. Оценку нового узла мы добавляем как лист сортдерева, ее место также уточняется движением "вниз".
Указанные операции требуют п р я м о г о обращения к dj по номеру узла i. Применим оглавление og м а с с и в а d (сортдерево представлено массивом), а в сортдереве вместе с оценками dj придется хранить и номера j - мы разместим их в отдельном массиве nоm, "параллельном" массиву d.
Пример 6.12.
Изучим содержание массивов при поиске в графе G2, когда узел 6 уже использован как база, а из сортдерева его оценка (306) еще не исключена:
Теперь оценка 306 удаляется блоком Out; сначала ее место займет лист 601, но не удержится в корне дерева, будучи вытеснен "сыном" 403. В корне - очередной минимум:
Рассмотрелный процесс D-поиска с построением каркаса, имеющего заданный корень - узел L, осуществляет блок DeikOer. Подблок Vniz реализует продвижение оценок в сортдереве по мере их улучшения, подблок Out - удаление из корня оценки, ставшей постоянной.
Const n=6; m=10; т1=2*m;
Type spis = Array[1..m 1, 1..2] of word;
mas = Array[1..n] of word; vec = Array[1..n+1] of word;
Constopi:spis=((2,20),(6,30),(4,30),(5,70),( 1,20),(4,20),(5,100),
(4,70),(5,40),(6,20),(1,30),(2,20),(3,70),(1,70),
(2,100),(3,40),(6,30),(1,30),(3,20),(5,30));
stp: vec = (4,3,3,3,4,3,0); {Степени узлов графа G2 и ноль - в конце}
Var og,d,r:mas; j.Lword;
Procedure DeikDer(var opi:spis; stp:vec; var d,og,r:mas; L:word);
Var nom:mas; basa,g,dl,i,j,k,s,v,x:word;
Procedure Vniz(i:word); {Блокищетместодляновойоценки g узлаграфа}
Begin
Repeatj:= iShr 1; {Сдвигомвправокодапозицииiузласортдерева}
Ifg<d[j] Then { найдем позицию] его предшественника в дереве}
Begin d[i]:=d[j]; nom[i]:=nom[j]; og[nom[j]]:=i; i:=j End
Else j:=1
Until j=1;
d[i]:= g; nom[i]:= v; og[v]:= i; r[v]:= L {Достраиваемкаркас}
End {блока включения новой оценки или оценки нового узла в дерево};
ProcedureOut; Label 1; {В Турбо Паскале 7.0 вместо Goto 1 можно }
Beginj:=1; k:=2; { использовать оператор Break, исключив метку 1}
While k<i do
Begin If d[k+1] < d[k] Then k:= k+1;
If d[i] <= d[k] Then Goto 1;
d[j]:= d[k]; nom[j]:= nom[k]; og[nom[k]]:=j; j:=k; k:= k+k
End; 1: d[j]:= d[i]; nom[j]:= nom[i]; og[nom[i]]:=j
End {блока исключения корневого узла сортдерева};
Begin {Начало операторной части блока D-поиск,}
s:=0; For j:= 1 to n do s:= s + stp[j];
Ifs<>m1 ThenWriteln('Ошибка в описании или в значении m');
If s <> ml Then Exit;
stp[n+1 ]:= s+1; {Создаем оглавление stp описания граф:}
For j:= n downto 1 do stp[j]:= stp[j+1] - stp[j];
Fork:= 1 tondoog[kj:= 0; {"О" обозначает узел k вне окружени}
s:=n; i:=1; nom[1]:= L; d[1]:= 0; r[L]:=n+1;
Repeat L:= nom[1]; basa:= d[1]; {Используемтекущуюбазу – узел}
For k:= stp[L] to stp[L+1]-1 do
Beginv:= opi[k,1]; {v - номер смежного узла, ах – позиция}
x:=og[v]; { его оценки в массиве d, либо это 0}
If х<= i Then Begin g:= basa + opi[k,2];
If x = 0 Then Begin i:=i+1; Vniz(i) End
Else If g < d[x] Then Vniz(x)
End
End;
{Исключаем узел L из дерева, перенося его оценку в конец d:}
Out; i:=i-1; d[s]:= basa; nom[s]:= L; og[L]:=s; s:=s-1
Untili = 0 {Сортдерево пусто, следовательно, D-поиск завершен}
End{блока DeikDer, выполняющего D-поиск от заданного узла L};
BEGINWriteln('Укажите отправной узел '); Readln(L);
DeikDer(opi, stp, d, og, r, L);
Writeln ('Длины кратчайших цепей, ведущих от узла L к узлам');
Writeln ('1 2 3 4 5 6 :');
For j:=1 to n do write(d[og[j]],' '); Readln
END.
Для вывода узлов кратчайшей цепи <Lj> применяйте блок OutPt из ответа к заданию 5.10. Заметим, что в результирующем массиве d оценки узлов расположены по убыванию их значений*, а это дает; простой способ нахождения множества узлов, удаленных от узла L не более (не менее) чем на заданную величину Z.
Оценим данную модификацию алгоритма. Если число ребер m>>n, достаточно оценить сложность обработки ребер: рассматривается каждое ребро, при этом, кроме действий фиксированной сложности, которыми пренебрегаем, происходят операции в сортдереве. Их число - в расчете на одно ребро - зависит от высоты сортдерева, не превосходящей logn. Если исходить из максимума этого числа, получим асимптотическую ВС, равную О(m*logn). Если m и n одного порядка, оценка приобретает вид О(n + m*logn), ибо главный цикл Repeat работает с каждым узлом связного графа как с базой.
Если число m ребер графа приближается к максимуму О(n2), применять модифицированный алгоритм нет смысла, хотя особого проигрыша по времени и не будет - в сравнении с алгоритмом п.5.11.
Задание 6.12.
Используя блок DeikDer (пример 5.12), найдите все узлы, расстояние от которых до заданного узла X имеет значение в диапазоне от А до В. Сложность их выявления должна быть минимальной.