Перебор (СПБГУ МатМех, март 2013, спецкурс 344-й группы)
- Графы и динамика
- Динамика на ацикличном графе (на примере задачи "самый длинный путь в ацикличном графе")
- Дейкстра с кучей (задача поиска кратчайшего пути)
- Почему нельзя также найти самый длинный простой путь? Отрицательные ребра, отрицательные циклы.
- Поиск гамильтонова пути рекурсивным перебором.
- Поиск гамильтонова пути рекурсивной динамикой.
- Простейшие читы в полном переборе
- Предподсчет (количество простых путей из точки (0,0) длины N)
- Отсечение по времени (к задаче гамильтонова пути)
- Запоминание (задачи: гамильтонов путь, максимальный путь, про котят). Получаем ленивую динамику.
- Общая задача на языке графов
- Найти какой-нибудь путь из s в t.
- Найти кратчайший путь из s в t.
- Найти количество путей из s в t.
- Граф, возможно, содержит циклы
- Если граф ацикличен, мы знаем решение всех трех задач за O(E)
- Если цикличен, то за O(E), O(ElogV) и O(E) (проверить на наличие цикла, если есть, ответ -- бексонечность)
- Нас интересуют решения за o(E) (т.к. граф огромен)
- Отсечения для задачи о гамильтоновом пути
- Запоминание
- Идти в вершину минимальной степени
- Начинать из случайно вершины несколько раз
- Отсечение "если конец точно не достижим, выйти"
- Пример1: задача обхода конем шахматной доски
- Пример2: гамильтонов путь в произвольном графе
- Решение перебором задачи поиска кратчайшего или максимального пути (на примере задачи про зеркала)
- Базовое решение: полный перебор
- Добавили запоминание: maxF[state] = D(s, state) = "расстояние от начала до state". Теперь в глубину мы идем только если функция улучшается.
- Другой способ: maxF[state] = D(state, t) = "расстояние от state до конца". Теперь, если мы зашли в состояние, где уже были, ответ уже известен.
- Отсечение по ответу: пусть есть оценка F(state) ≥ D(state, t), тогда если D(s, state) + F(state) ≤ best, можно сразу выйти.
- Отсечение по ответу работает лучше, если ответ посчитан более точно. Как посчитать ответ наиболее точно?
- Перебирать ребра из текущего состояния в правильном порядке. Чтобы среди первых был ответ близкий к оптимуму.
- Iterative Deepening. Перебираем ответ внешним циклом for.
- Делаем дерево перебора более равномерным
- У нас уже есть сортировка ребер в каждой вершине.
- Если из каждой вершины перебирать только одно (лучшее) ребро, мы получим жадность.
- Если перебирать все ребра, то дерево перебора будет похоже на "куст"
- Будем перебирать лучшие k ребер.
- Как выбрать k? while (not TimeLimit) k++;
- Алгоритм A*
- Задача: есть две вершины -- s и t, нужно найти кратчайший путь от s до t.
- Dijkstra на плоскости: куча по ключу D(s, v) + distance(v, t)
- Картинка, показывающая, что до некоторых вершин мы вообще не дойдем (идем почти по прямой)
- Переписываем перебор, как Dijkstra по величине D(s, v) + F(state)