Эвристики для поиска кратчайших путей — различия между версиями
(→Многоуровневые корзины(multi-level buckets, MLB)) |
Xottab (обсуждение | вклад) (→Калибровка(caliber)) |
||
Строка 62: | Строка 62: | ||
===Калибровка(caliber)=== | ===Калибровка(caliber)=== | ||
− | Введём величину | + | Введём величину <b><i>калибр</i></b> вершины <tex>c(v)</tex> - вес минимального ребра, входящего в <tex>v</tex> , или <tex>\infty</tex>, если в вершину не входит ни одно ребро. Будем говорить, что текущее значение <tex>d(v)</tex> точно, если оно равно длине пути <tex>s \rightsquigarrow v</tex>. |
+ | {{Лемма | ||
+ | |about = 1 | ||
+ | |statement = | ||
+ | Предположим, что длины рёбер неотрицательны. Пусть <tex>\mu</tex> - минимальное из текущих значений <tex>d(v):v \in V</tex>. Тогда, если существует такая вершина <tex>u</tex>, что <tex>\mu + c(u) \geqslant d(u)</tex>, то текущее значение <tex>d(u)</tex> точно. | ||
+ | }} | ||
+ | Эта лемма позволяет нам смягчить правило выбора текущей вершины в алгоритме Дейкстры, при этом сохраняя инвариант(почти все вершины обрабатываются единожды). | ||
+ | Калибровка использует Лемму 1 чтобы находить и обрабатывать вершины с точными текущими значениями расстояния до них. | ||
+ | |||
+ | Модифицируем нашу MLB - структуру: будем хранить помеченные вершины в двух группах: сет <tex>F</tex> и приоритетная очередь <tex>B</tex>, реализованная на MLB. | ||
+ | Назовём наш алгоритм <b><i>алгоритмом умной очереди</i></b>. | ||
+ | |||
+ | Вершины в <tex>F</tex> будут иметь точные метки. Если <tex>F</tex> непусто, мы удалим оттуда вершину и прорелаксируем всех её соседей. Если же <tex>F</tex> пусто, мы достанем из | ||
+ | <tex>B</tex> вершину с минимальной меткой и прорелаксируем всех её соседей. | ||
+ | |||
+ | Рассмотрим механизм релаксации: пусть мы уменьшаем <tex>d(u)</tex>. Заметим, что в этом случае <tex>u</tex> не могло лежать в <tex>F</tex>(иначе <tex>d(u)</tex> было не точно). Если <tex>u \in B</tex> - применим <tex>decrease - key</tex> к <tex>u</tex>. Эта операция либо переместила <tex>u</tex> внутри <tex>B</tex>, либо определила, что метка <tex>d(u)</tex> точна и переместила <tex>u</tex> в <tex>F</tex>. | ||
+ | Если же <tex>u \notin F \hspace{2 mm} \& \hspace{2 mm} u \notin B</tex>, мы применим операцию <tex>insert</tex>, и <tex>u</tex> запишется в | ||
+ | <tex>F</tex> или <tex>B</tex>, в зависимости от того, выполняется ли условие леммы. |
Версия 17:00, 3 декабря 2013
Данная статья - перевод выступления Renato F. Werneck в Microsoft Data Structures and Algorithms School в 2010 году.
Содержание
Проблема поиска кратчайшего пути
Дано:
- ориентированный граф
- отправная точка - вершина , пункт назначения - вершина
Цель: найти кратчайший путь
Мы будем рассматривать сеть автомобильных дорог:
- - множество перекрёстков
- - множество дорог
- - среднее время, которое занимает проезд по дороге
Алгоритм Дейкстры
основная статья: Алгоритм Дейкстры
- на каждом шаге выбирает из множества непросмотренных вершин вершину с наименьшим расстоянием до старта и релаксирует рёбра, исходящие из неё
- завершает свою работу, когда цель достигнута (или просмотрены все вершины)
Скорость работы алгоритма Дейкстры сильно зависит от скорости операций с приоритетной очередью.
Поскольку мы рассматриваем сеть автомобильных дорог, то
(граф планарен почти везде).Для фибоначчиевых куч время работы алгоритма составляет
, для двоичных куч:Но на практике чаще используются 2-, 4- и 8-ичные кучи: они более простые, оценка времени работы содержит меньшее количество скрытых констант.
Улучшения алгоритма Дейкстры
Многоуровневые корзины(multi-level buckets, MLB)
Структура данных | Время работы (сек) |
---|---|
Двоичная куча | 12,38 |
4-куча | 11,53 |
8-куча | 11,52 |
MLB | 9,36 |
MLB + калибровка | 8,04 |
Подходит только графов с целочисленными рёбрами.
- Будем складывать вершины в "корзины"
- Наша структура данных будет поддерживать индекс
- На каждом шаге алгоритма, если пусто, то увеличим , а иначе достанем одну вершину из
- При релаксации будем убирать вершину из исходной корзины и класть в корзину, соответствующую новому значению
Можно заметить, что при такой реализации, все операции с приоритетной очередью будут выполняться за
. Тогда, для одного уровня корзин время работы алгоритма Дейкстры можно оценить как , где - максимальная длина ребра в графе.При двухуровневой реализации будем поддерживать два уровня корзин: первый уровень будет соответствовать одноуровневой реализации, а корзины второго уровня будут содержать диапазон значений корзин первого уровня, которые в них входят.
Соответственно, нам нужно поддерживать два индекса
и для каждого из уровней соответственно.При такой реализации, время работы алгоритма Дейкстры можно оценить как
Калибровка(caliber)
Введём величину калибр вершины
- вес минимального ребра, входящего в , или , если в вершину не входит ни одно ребро. Будем говорить, что текущее значение точно, если оно равно длине пути .Лемма (1): |
Предположим, что длины рёбер неотрицательны. Пусть - минимальное из текущих значений . Тогда, если существует такая вершина , что , то текущее значение точно. |
Эта лемма позволяет нам смягчить правило выбора текущей вершины в алгоритме Дейкстры, при этом сохраняя инвариант(почти все вершины обрабатываются единожды). Калибровка использует Лемму 1 чтобы находить и обрабатывать вершины с точными текущими значениями расстояния до них.
Модифицируем нашу MLB - структуру: будем хранить помеченные вершины в двух группах: сет
и приоритетная очередь , реализованная на MLB. Назовём наш алгоритм алгоритмом умной очереди.Вершины в
будут иметь точные метки. Если непусто, мы удалим оттуда вершину и прорелаксируем всех её соседей. Если же пусто, мы достанем из вершину с минимальной меткой и прорелаксируем всех её соседей.Рассмотрим механизм релаксации: пусть мы уменьшаем
. Заметим, что в этом случае не могло лежать в (иначе было не точно). Если - применим к . Эта операция либо переместила внутри , либо определила, что метка точна и переместила в . Если же , мы применим операцию , и запишется в или , в зависимости от того, выполняется ли условие леммы.