Алгоритмы и структуры данных, часть 1, осень 2016:...
TRANSCRIPT
![Page 1: Алгоритмы и структуры данных, часть 1, осень 2016: Кратчайшие пути](https://reader031.vdocuments.site/reader031/viewer/2022021506/587c5ff21a28ab633c8b5ab3/html5/thumbnails/1.jpg)
Кратчайшие пути I.Скрытая угроза
![Page 2: Алгоритмы и структуры данных, часть 1, осень 2016: Кратчайшие пути](https://reader031.vdocuments.site/reader031/viewer/2022021506/587c5ff21a28ab633c8b5ab3/html5/thumbnails/2.jpg)
Простой путь
Найти кратчайший путь от start до finish в неориентированном графе.
Длина пути — количество рёбер.
![Page 3: Алгоритмы и структуры данных, часть 1, осень 2016: Кратчайшие пути](https://reader031.vdocuments.site/reader031/viewer/2022021506/587c5ff21a28ab633c8b5ab3/html5/thumbnails/3.jpg)
Динамическое программирование?
![Page 4: Алгоритмы и структуры данных, часть 1, осень 2016: Кратчайшие пути](https://reader031.vdocuments.site/reader031/viewer/2022021506/587c5ff21a28ab633c8b5ab3/html5/thumbnails/4.jpg)
● Точно знаем ответ для вершины start● Можем найти множество вершин на
расстоянии 1
![Page 5: Алгоритмы и структуры данных, часть 1, осень 2016: Кратчайшие пути](https://reader031.vdocuments.site/reader031/viewer/2022021506/587c5ff21a28ab633c8b5ab3/html5/thumbnails/5.jpg)
BFSBreadth first search (поиск в ширину)
S[i] — множество вершин на расстоянии i.
![Page 6: Алгоритмы и структуры данных, часть 1, осень 2016: Кратчайшие пути](https://reader031.vdocuments.site/reader031/viewer/2022021506/587c5ff21a28ab633c8b5ab3/html5/thumbnails/6.jpg)
def bfs(graph, start): work = {start} dist = {}
current_dist = 0 while work: for u in work: dist[u] = current_dist
work = {nb for u in work for nb in graph[u] if v not in dist}
![Page 7: Алгоритмы и структуры данных, часть 1, осень 2016: Кратчайшие пути](https://reader031.vdocuments.site/reader031/viewer/2022021506/587c5ff21a28ab633c8b5ab3/html5/thumbnails/7.jpg)
Детали релизации● Вместо двух массивов можно использовать одну очередь.● Какого максимального размера может быть очередь?● Массив и два указателя — ring buffer.● Не бывает stack overflow, в отличие от dfs => если надо обойти граф как-
то на практике, используйте bfs.● Как восстановить путь?● Какая сложность?
![Page 8: Алгоритмы и структуры данных, часть 1, осень 2016: Кратчайшие пути](https://reader031.vdocuments.site/reader031/viewer/2022021506/587c5ff21a28ab633c8b5ab3/html5/thumbnails/8.jpg)
Взвешенные рёбраУ каждого ребра есть неотрицательный вес (длина дороги). Найти кратчайший путь в смысле суммы весов рёбер.
![Page 9: Алгоритмы и структуры данных, часть 1, осень 2016: Кратчайшие пути](https://reader031.vdocuments.site/reader031/viewer/2022021506/587c5ff21a28ab633c8b5ab3/html5/thumbnails/9.jpg)
Алгоритм Дейкстры (Dijkstra's algorithm)● Точно знаем расстояние до вершины start. ● Не знаем расстояние до её соседей (путь из двух рёбер может быть
короче, чем путь из одного ребра)● Но! Знаем расстояние до одной из вершин.
Идея: если S это вершины, для которых мы точно знаем ответ, то мы точно знаем ответ и для ближайшей вершины из соседей S
![Page 10: Алгоритмы и структуры данных, часть 1, осень 2016: Кратчайшие пути](https://reader031.vdocuments.site/reader031/viewer/2022021506/587c5ff21a28ab633c8b5ab3/html5/thumbnails/10.jpg)
def dijkstra(graph, start): dist = {start: 0} border = {u: weight for (u, weight) in graph[start]}
while border: u = min(border, key=lambda u: border[u]) dist[u] = border.pop(u) for (v, weight) in graph[u]: if v in dist: assert dist[u] + weight >= dist[v] continue
border[v] = min( dist[u] + weight, border.get(v, float("inf")) )
![Page 11: Алгоритмы и структуры данных, часть 1, осень 2016: Кратчайшие пути](https://reader031.vdocuments.site/reader031/viewer/2022021506/587c5ff21a28ab633c8b5ab3/html5/thumbnails/11.jpg)
Трудоемкость● На каждой итерации увеличиваем S на 1 => V итераций. ● На каждой итерации извлекаем минимум из границы => в худшем случае
V на итерацию● На каждой итерации рассматриваем какие-то рёбра, и на каждое ребро
смотрим ровно один раз => E за все итерации.
Итого: O(V^2 + E)
Напоминание: в дереве E = V, в полном графе E = V^2
![Page 12: Алгоритмы и структуры данных, часть 1, осень 2016: Кратчайшие пути](https://reader031.vdocuments.site/reader031/viewer/2022021506/587c5ff21a28ab633c8b5ab3/html5/thumbnails/12.jpg)
Посмотрим на границу● Хранит вершины и веса● Можно добавить вершину с весом/уменьшать весь (E раз)● Можно доставать минимальную вершину из границы (V раз)
![Page 13: Алгоритмы и структуры данных, часть 1, осень 2016: Кратчайшие пути](https://reader031.vdocuments.site/reader031/viewer/2022021506/587c5ff21a28ab633c8b5ab3/html5/thumbnails/13.jpg)
Как хранить границу● Массив весов (V^2 + E) всегда● Хэш мап весов (V*(размер границы) + E)● Очередь с приоритетом (V + E) * log(V)
![Page 14: Алгоритмы и структуры данных, часть 1, осень 2016: Кратчайшие пути](https://reader031.vdocuments.site/reader031/viewer/2022021506/587c5ff21a28ab633c8b5ab3/html5/thumbnails/14.jpg)
Напоминание про очередь с приоритетомХорошая структура данных — куча.
Стандартные кучи не умеют изменять значения ключа.
Можно написать свою кучу, можно использовать дерево поиска.
![Page 15: Алгоритмы и структуры данных, часть 1, осень 2016: Кратчайшие пути](https://reader031.vdocuments.site/reader031/viewer/2022021506/587c5ff21a28ab633c8b5ab3/html5/thumbnails/15.jpg)
Когда не работает Дейкстра?
![Page 16: Алгоритмы и структуры данных, часть 1, осень 2016: Кратчайшие пути](https://reader031.vdocuments.site/reader031/viewer/2022021506/587c5ff21a28ab633c8b5ab3/html5/thumbnails/16.jpg)
Отрицательные весаРешим всё:
Найти расстояние между всеми парами вершин, веса могут быть отрицательными.
![Page 17: Алгоритмы и структуры данных, часть 1, осень 2016: Кратчайшие пути](https://reader031.vdocuments.site/reader031/viewer/2022021506/587c5ff21a28ab633c8b5ab3/html5/thumbnails/17.jpg)
Отрицательные весаРешим всё:
Найти расстояние между всеми парами вершин, веса могут быть отрицательными, но нет отрицательных циклов
![Page 18: Алгоритмы и структуры данных, часть 1, осень 2016: Кратчайшие пути](https://reader031.vdocuments.site/reader031/viewer/2022021506/587c5ff21a28ab633c8b5ab3/html5/thumbnails/18.jpg)
![Page 19: Алгоритмы и структуры данных, часть 1, осень 2016: Кратчайшие пути](https://reader031.vdocuments.site/reader031/viewer/2022021506/587c5ff21a28ab633c8b5ab3/html5/thumbnails/19.jpg)
Как навести порядок?● Перейдём в третье измерение!
D[u, v, m] — длина кратчайшего пути от u до v по вершинам с номерами меньше m.
D[u, v, 0] — путь, где все промежуточные вершины имеют номер меньше 0 =>
нет промежуточных вершин => D[u, v, 0] = d[u, v]
![Page 20: Алгоритмы и структуры данных, часть 1, осень 2016: Кратчайшие пути](https://reader031.vdocuments.site/reader031/viewer/2022021506/587c5ff21a28ab633c8b5ab3/html5/thumbnails/20.jpg)
D[u, v, m] =
// нет вершины m - 1 вообще
D[u, v, m - 1]
// есть ровно одна вершина m - 1
D[u, m - 1, m -1] + D[m - 1, v, m - 1]
![Page 21: Алгоритмы и структуры данных, часть 1, осень 2016: Кратчайшие пути](https://reader031.vdocuments.site/reader031/viewer/2022021506/587c5ff21a28ab633c8b5ab3/html5/thumbnails/21.jpg)
Как программировать?Трёхмерная табличка, заполняем в порядке увеличения третьей координаты.
Нулевой уровень — матрица смежности.
Можно сэкономить на памяти, и помнить только один предыдущий уровень.
Сложно…
![Page 22: Алгоритмы и структуры данных, часть 1, осень 2016: Кратчайшие пути](https://reader031.vdocuments.site/reader031/viewer/2022021506/587c5ff21a28ab633c8b5ab3/html5/thumbnails/22.jpg)
Floyd–Warshall algorithm O(n^3)
for k in range(n): for i in range(n): for j in range(n): d[i, j] = min(d[i, j], d[i, k] + d[k, j])
![Page 23: Алгоритмы и структуры данных, часть 1, осень 2016: Кратчайшие пути](https://reader031.vdocuments.site/reader031/viewer/2022021506/587c5ff21a28ab633c8b5ab3/html5/thumbnails/23.jpg)
А если есть отрицательный цикл?
![Page 24: Алгоритмы и структуры данных, часть 1, осень 2016: Кратчайшие пути](https://reader031.vdocuments.site/reader031/viewer/2022021506/587c5ff21a28ab633c8b5ab3/html5/thumbnails/24.jpg)
Дополнительное времяРегулярное выражение
R = 'a', 'b', 'c' — буквы R1 R2 — конкатенация двух регулярных выражений R1 | R2 — альтернация, либо R1, либо R2 R* — замыкание Клини: конкатенация произвольного числа R.
"" — пустое слово 0 — пустой язык
![Page 25: Алгоритмы и структуры данных, часть 1, осень 2016: Кратчайшие пути](https://reader031.vdocuments.site/reader031/viewer/2022021506/587c5ff21a28ab633c8b5ab3/html5/thumbnails/25.jpg)
Конечный автоматОриентированный мультиграф состояний.
На каждом ребре написана буква.
Есть стартовое и некоторое количество финальных состояний.
![Page 26: Алгоритмы и структуры данных, часть 1, осень 2016: Кратчайшие пути](https://reader031.vdocuments.site/reader031/viewer/2022021506/587c5ff21a28ab633c8b5ab3/html5/thumbnails/26.jpg)
Посмотрим на язык
(a | b)* aabСлова из букв a, b, которые оканчиваются на aab.
![Page 27: Алгоритмы и структуры данных, часть 1, осень 2016: Кратчайшие пути](https://reader031.vdocuments.site/reader031/viewer/2022021506/587c5ff21a28ab633c8b5ab3/html5/thumbnails/27.jpg)
Флойд наносит ответный удар
Задача: Построить по данному конечному автомату эквивалентное регулярное выражение.