Алгоритм D* — различия между версиями
Kabanov (обсуждение | вклад) м (links) |
Kabanov (обсуждение | вклад) |
||
| Строка 1: | Строка 1: | ||
| − | D* | + | '''Алгоритм D*''' {{---}} алгоритм поиска кратчайшего пути во взвешенном ориентированном графе, где структура графа неизвестна заранее или постоянно подвергается изменению. Разработан Свеном Кёнигом и Максимом Лихачевым в 2002 году. |
| − | LPA* | + | == Алгоритм LPA* == |
| + | |||
| + | === Постановка задачи === | ||
| + | Дан взвешенный ориентированный граф <tex> G(V, E) </tex>. Даны вершины <tex>s_{start}</tex> и <tex>s_{goal}</tex>. Требуется после каждого изменения графа <tex>G</tex> уметь вычислять функцию <tex>g(s)</tex> для каждой известной вершины <tex>s \in V</tex> | ||
| + | |||
| + | === Описание === | ||
Обозначим множество <tex>S</tex> как множество вершин графа. | Обозначим множество <tex>S</tex> как множество вершин графа. | ||
| + | |||
Обозначим множество <tex>Succ(s) \in S</tex> как множество вершин, исходящих из вершины <tex>s</tex>. | Обозначим множество <tex>Succ(s) \in S</tex> как множество вершин, исходящих из вершины <tex>s</tex>. | ||
| + | |||
Аналогично множество <tex>Pred(s) \in S</tex> как множество вершин, входящих в вершину <tex>s</tex>. | Аналогично множество <tex>Pred(s) \in S</tex> как множество вершин, входящих в вершину <tex>s</tex>. | ||
| − | Функция <tex>0 | + | Функция <tex>0 \le с(s, s') \le +inf</tex> будет возвращать перехода из вершины <tex>s</tex> в вершину <tex>s'</tex>. При этом <tex>s' \in Succ(s)</tex>. |
| − | Функция <tex>g(s) будет возвращать последнее известное значение расстояние от вершины <tex>s_{start}</tex> до <tex>s</tex>. | + | Функция <tex>g(s)</tex> будет возвращать последнее известное значение расстояние от вершины <tex>s_{start}</tex> до <tex>s</tex>. |
Если <tex>s = s_{start}</tex> | Если <tex>s = s_{start}</tex> | ||
| Строка 15: | Строка 22: | ||
<tex>rhs(s) = min_{s' \in pred(s)}(g(s') + c(s', s)</tex> | <tex>rhs(s) = min_{s' \in pred(s)}(g(s') + c(s', s)</tex> | ||
| − | Будем говорить, что вершина s насыщена | + | Будем говорить, что вершина <tex>s</tex> насыщена, если <tex>g(s) = rhs(s)</tex> |
переполнена | переполнена | ||
| − | + | ненасыщена | |
| − | Очевидно, что если все вершины | + | Очевидно, что если все вершины насыщены, то мы можем найти расстояние от стартовой вершины до любой. |
Функция <tex>key(s)</tex>, где <tex>s</tex> - вершина, возвращает вектор из 2-ух значений <tex>k_1(s)</tex>, <tex>k_2(s)</tex>. <tex>k_1(s) = min(g(s), rhs(s)) + h(s, s_goal)</tex>. <tex>k_2(s) = min(g(s), rhs(s))</tex> | Функция <tex>key(s)</tex>, где <tex>s</tex> - вершина, возвращает вектор из 2-ух значений <tex>k_1(s)</tex>, <tex>k_2(s)</tex>. <tex>k_1(s) = min(g(s), rhs(s)) + h(s, s_goal)</tex>. <tex>k_2(s) = min(g(s), rhs(s))</tex> | ||
| Строка 24: | Строка 31: | ||
Если в конце поиска пути <tex>g(s_{goal}) = +inf</tex>, то мы не смогли найти путь от <tex>s_{start}</tex> до <tex>s_{goal}</tex> | Если в конце поиска пути <tex>g(s_{goal}) = +inf</tex>, то мы не смогли найти путь от <tex>s_{start}</tex> до <tex>s_{goal}</tex> | ||
| − | Псевдокод | + | === Псевдокод === |
'''CalcKey'''(s): | '''CalcKey'''(s): | ||
Версия 22:53, 2 января 2014
Алгоритм 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 all U.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();