
- •1. Асимптотическая оценка алгоритма
- •2. Методика оценки не рекурсивных алгоритмов. Пример
- •3. Рекурсивные алгоритмы, построение асимптотической оценки. Пример
- •4. Методика оценки рекурсивных алгоритмов.
- •5. Алгоритмы сортировки массивов за полиномиальное время
- •6. Быстрые алгоритмы сортировки массивов, основанные на сравнении элементов
- •7. Алгоритмы сортировки массивов за линейное время
- •8. Линейные структуры данных, основные операции и характеристики
- •9. Деревья, виды, способы представления, структуры данных, обходы дерева
- •10. Двоичные деревья поиска, операции добавления элементов.
- •11. Двоичные деревья поиска, операции удаления элементов и поиска следующих
- •13. Двоичные кучи, основные операции и характеристики
- •16. Динамическое программирование, основные особенности
- •17. Жадные алгоритмы, основные особенности
- •18. Построение кода Хаффмена
- •19. Алгоритм обхода графов в ширину
- •20. Алгоритм обхода графов в глубину
- •21. Остовое дерево, классификация ребер, топологическая сортировка.
- •22. Сильно связные компоненты, алгоритм поиска
- •23. Построение минимально покрывающего дерева, алгоритм Крускала
- •24. Построение минимального покрывающего дерева, алгоритм Прима
- •25. Происк кратчайшего пути. Алгоритм Дейкстры
- •26. Поиск кратчайшего пути. Алгоритм Беллмана-Форда
19. Алгоритм обхода графов в ширину
Пусть задан граф G = (V, Е) и выделена исходная (source) вершина s. Алгоритм поиска в ширину систематически обходит все ребра G для "открытия" всех вершин, достижимых из s, вычисляя при этом расстояние (минимальное количество ребер) до каждой достижимой из s вершины. Кроме того, в процессе обхода строится "дерево поиска в ширину" с корнем s, содержащее все достижимые вершины. Для каждой достижимой из s вершины v путь в дереве поиска в ширину соответствует кратчайшему (т.е. содержащему наименьшее количество ребер) пути от s до v в G. Алгоритм работает как для ориентированных, так и для неориентированных графов.
BFS(G,s) {
for each u in V { // initialization
color [u] = white
d [u] = infinity
red[u] = null
}
color [s] = gray // initialize source s
d[s] = 0
Q = {s} // put s in the queue
while (Q is nonempty) {
u = Q.Dequeue() // u is the next to visit
for each v in Adj[u] {
if (color[v] == white) { //if neighbor v undiscovered
color[v] = gray // ...mark it discovered
d[v] = d[u]+l // ...set its distance
pred[v] = u // ...and its predecessor
Q.Enqueue(v) // ...put it in the queue
}
}
color [u] = black // we are done with u
}
}
20. Алгоритм обхода графов в глубину
Стратегия поиска в глубину, чтобы идти "вглубь" графа, насколько это возможно. При выполнении поиска в глубину исследуются все ребра, выходящие из вершины, открытой последней, и покидает вершину, только когда не остается неисследованных ребер — при этом происходит возврат в вершину, из которой была открыта вершина v. Этот процесс продолжается до тех пор, пока не будут открыты все вершины, достижимые из исходной. Если при этом остаются неоткрытые вершины, то одна из них выбирается в качестве новой исходной вершины и поиск повторяется уже из нее. Этот процесс повторяется до тех пор, пока не будут открыты все вершины.
DFS(G) { // main program
for each u in V { // initialization
color[u] = white;
pred[u] = null;
}
time = 0;
for each u in V
if (color[u] == white) // found an undiscovered vertex
DFSVisit(u); // start a new search here
}
DFSVisit(u) { // start a search at u
color[u] = gray; // mark u visited
d[u] = ++time;
for each v in Adj(u) do
if (color[v] == white) {
pred[v] = u; // ...set predecessor pointer
DFSVisit(v); // ...visit v
}
color[u] = black; // we're done with u
f[u] = ++time;
}
21. Остовое дерево, классификация ребер, топологическая сортировка.
Дан взвешенный неориентированный граф G с n вершинами и m рёбрами. Требуется найти такое поддерево этого графа, которое бы соединяло все его вершины, и при этом обладало наименьшим возможным весом (т.е. суммой весов рёбер).
Поддерево — это набор рёбер, соединяющих все вершины, причём из любой вершины можно добраться до любой другой ровно одним простым путём.
Такое поддерево называется минимальным остовным деревом или просто минимальным остовом. Любой остов будет содержать n-1 ребро.
Остовое дерево - ацикличный подграф G1 = (V 1,E 1) графа G = (V,E), где E1 Í E,V 1 = V,
Минимальное остовое дерево - остовое дерево с минимальным весом.
В естественной постановке эта задача звучит следующим образом: есть n городов, и для каждой пары известна стоимость соединения их дорогой (либо известно, что соединить их нельзя). Требуется соединить все города так, чтобы можно было доехать из любого города в другой, а при этом стоимость прокладки дорог была бы минимальной.
Проблема построения сети
Области возникновения: коммуникационные и дорожные сети.
Дано: множество узлов сети (хосты, города).
Необходимо: построение сети с наименьшим общим весом ребер (длина сетевых кабелей, длина дорог).
Графовая модель: узлы сети являются узлами графа, E = V2, нам известны веса всех ребер.
Результат: свободное дерево.
Подход к поиску МОД
Строим дерево A путем добавления по одному ребру, и перед каждой итерацией текущее дерево является подмножеством некоторого МОД.
На каждом шаге алгоритма мы определяем ребро (u, v), которое можно добавить к А без нарушения этого свойства. Мы назовем такое ребро безопасным
GenericMST(G, w)
1 A ← 0
2 while A не является МОД
3 do Найти безопасное для A ребро (u, v)
4 A ← A U {(u, v)}
5 return A
____________________________________________________________________________
Классификация ребер
1. Ребра деревьев (tree edges) — это ребра графа G. Ребро (u, v) является ребром дерева, если при исследовании этого ребра открыта вершина v.
2. Обратные ребра (back edges) — это ребра (u,v), соединяющие вершину u с ее предком v в дереве поиска в глубину. Ребра-циклы, которые могут встречаться в ориентированных графах, рассматриваются как обратные ребра.
3. Прямые ребра (forward edges) — это ребра (u,v), не являющиеся ребрами дерева и соединяющие вершину u с ее потомком v в дереве поиска в глубину.
4. Перекрестные ребра (cross edges) — все остальные ребра графа. Они могут соединять вершины одного и того же дерева поиска в глубину, когда ни одна из вершин не является предком другой, или соединять вершины в разных деревьях.
Алгоритм DFS можно модифицировать так, что он будет классифицировать встречающиеся при работе ребра. Ключевая идея заключается в том, что каждое ребро (u, v) можно классифицировать при помощи цвета вершины v при пер- первом его исследовании (правда, при этом не различаются прямые и перекрестные ребра).
Белый цвет говорит о том, что это ребро дерева.
Серый цвет определяет обратное ребро.
Черный цвет указывает на прямое или перекрестное ребро.
Первый случай следует непосредственно из определения алгоритма.
Рассматривая второй случай, заметим, что серые вершины всегда образуют линейную цепочку потомков, соответствующую стеку активных вызовов процедуры DFS_Visit; количество серых вершин на единицу больше глубины последней открытой вершины в дереве поиска в глубину. Исследование всегда начинается от самой глубокой серой вершины, так что ребро, которое достигает другой серой вершины, достигает предка исходной вершины.
В третьем случае мы имеем дело с остальными ребрами, не подпадающими под первый или второй случай. Можно показать, что ребро (u, v) является прямым, если d [u] < d [v], и перекрестным, если d [u] > d [v]
___________________________________________________________________________
Топологическая сортировка
В графе предшествования каждое ребро (u, v) означает, что u предшествует v
Топологическая сортировка графа есть построение последовательности а, где для всех ai и aj выполняется $(аi,аj) Þ i < j.
Топологическая сортировка (topological sort) ориентированного ациклического графа G = (V, Е) представляет собой такое линейное упорядочение всех его вершин, что если граф G содержит ребро (u,v) то u при таком упорядочении располагается до v (если граф не является ацикличным, такая сортировка невозможна). Топологическую сортировку графа можно рассматривать как такое упорядочение его вершин вдоль горизонтальной линии, что все ребра направлены слева направо.
Отсортированная последовательность: C2, C6, C7, C1, C3, C4, C5, C8
TopSort(G) {
for each(u in V) color[u] = white; // initialize
L = new linked_list; // L is an empty linked list
for each (u in V)
if (color[u] == white) TopVisit(u);
return L; // L gives final order
}
TopVisit(u) { // start a search at u
color[u] = gray; // mark u visited
for each (v in Adj(u))
if (color[v] == white) TopVisit(v);
Append u to the front of L; // on finishing u add to list
}
T (n) = Θ(V + E)