Алгоритм D*
Алгоритм D* — алгоритм поиска кратчайшего пути во взвешенном ориентированном графе, где структура графа неизвестна заранее или постоянно подвергается изменению. Разработан Свеном Кёнигом и Максимом Лихачевым в 2002 году.
Алгоритм LPA*
Постановка задачи
Дан взвешенный ориентированный граф
. Даны вершины и . Требуется после каждого изменения графа уметь вычислять функцию для каждой известной вершиныОписание
Обозначим множество
как множество вершин графа.Обозначим множество
как множество вершин, исходящих из вершины .Аналогично множество
как множество вершин, входящих в вершину .Функция
будет возвращать перехода из вершины в вершину . При этом .Функция
будет возвращать последнее известное значение расстояние от вершины до .Если
ИначеБудем говорить, что вершина
насыщена, если переполнена ненасыщена Очевидно, что если все вершины насыщены, то мы можем найти расстояние от стартовой вершины до любой.Функция
, где - вершина, возвращает вектор из 2-ух значений , . .Если в конце поиска пути
, то мы не смогли найти путь от доПсевдокод
CalcKey(s): { return [; ]; }
Initialize(): {}
UpdateVertex(): { if ( ) if ( ) U.Remove(u); if (g(u) != rhs(u)) U.Insert( ;CalcKey( )); }
ComputeShortestPath(): { while (U.TopKey()< CalcKey() OR rhs( )) u = U.Pop(); if (g(u) > rhs(u)) g(u) = rhs(u); for all s 2 Succ(u) UpdateVertex(s); else g(u) = 1; for all UpdateVertex(s); }
Main():
{
Initialize();
while (
)
{
ComputeShortestPath();
Wait for changes in edge costs;
for all directed edges (u;v) with changed edge costs
{
Update the edge cost c(u;v);
UpdateVertex(v);
}
}
}
Таким образом мы описали алгоритм LPA*. Он неоднократно определяет путь между вершинами
и , используя при этом данные из предыдущих итераций. Очевидно, что в худшем случае (а именно когда все ребра вокруг текущей вершины изменили свой вес) алгоритм будет работать как последовательные вызовы алгоритма А* за . Улучшим эту оценку с помощью алгоритма D* lite.Примечание: на практике же такой подход тоже имеет место на плотных графах (или матрицах), так как в среднем дает оценку О(n*log(n)).
Алгоритм D*
CalcKey(s): return [; ];
Initialize(): U = null; for allU.Insert(sgoal;CalcKey(sgoal));
UpdateVertex(u): if (u 6= s_{goal}) rhs(u) = mins02Succ(u)
(c(u;s 0 ) + g(s 0 )); f07’g if (u 2 U) U.Remove(u); f08’g if (g(u) 6= rhs(u)) U.Insert(u;CalcKey(u));
ComputeShortestPath() while (U.TopKey()<_ CalcKey(s_{start}) OR rhs(s_{start}) 6= g(s_{start})) u = U.Pop(); if (g(u) > rhs(u)) g(u) = rhs(u); for all s 2 Pred(u) UpdateVertex(s); else g(u) = 1; for all s 2 Pred(u) [ fug UpdateVertex(s);
Main(): Initialize(); ComputeShortestPath(); while (s_{start} 6= s_{goal}) if (g(sstart) = 1) then there is no known path */ sstart = argmins02Succ(sstart)
(c(sstart;s 0 ) + g(s 0 )); f22’g Move to sstart; f23’g Scan graph for changed edge costs; f24’g if any edge costs changed f25’g for all directed edges (u;v) with changed edge costs f26’g Update the edge cost c(u;v); f27’g UpdateVertex(u); f28’g for all s 2 U f29’g U.Update(s;CalcKey(s)); f30’g ComputeShortestPath();