Алгоритм D* — различия между версиями
Kabanov (обсуждение | вклад) |
Kabanov (обсуждение | вклад) |
||
| Строка 2: | Строка 2: | ||
LPA* | LPA* | ||
| − | Обозначим множество <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>. | ||
| Строка 50: | Строка 50: | ||
'''ComputeShortestPath'''(): | '''ComputeShortestPath'''(): | ||
{ | { | ||
| − | while (U.TopKey()< CalcKey(s_{goal}) OR rhs(s_{goal}) != g(s_{goal})) | + | while (U.TopKey()< CalcKey(<tex>s_{goal}</tex>) OR rhs(<tex>s_{goal}) != g(s_{goal}</tex>)) |
u = U.Pop(); | u = U.Pop(); | ||
if (g(u) > rhs(u)) | if (g(u) > rhs(u)) | ||
| Строка 57: | Строка 57: | ||
else | else | ||
g(u) = 1; | g(u) = 1; | ||
| − | for all s \in Succ(u) perec {u} | + | for all <tex>s \in Succ(u) perec {u}</tex> |
UpdateVertex(s); | UpdateVertex(s); | ||
} | } | ||
| Строка 64: | Строка 64: | ||
{ | { | ||
Initialize(); | Initialize(); | ||
| − | while (<tex> | + | while (<tex>s_{start} != s_{goal}</tex>) |
{ | { | ||
ComputeShortestPath(); | ComputeShortestPath(); | ||
| Строка 77: | Строка 77: | ||
Таким образом мы описали алгоритм LPA*. Он неоднократно определяет путь между вершинами <tex>s_start</tex> и <tex>s_goal</tex>, используя при этом данные из предыдущих итераций. Очевидно, что в худшем случае (а именно когда все ребра вокруг текущей вершины изменили свой вес) алгоритм будет работать как последовательные вызовы алгоритма А* за O(n^2*log(n)). Улучшим эту оценку с помощью алгоритма D* lite. | Таким образом мы описали алгоритм LPA*. Он неоднократно определяет путь между вершинами <tex>s_start</tex> и <tex>s_goal</tex>, используя при этом данные из предыдущих итераций. Очевидно, что в худшем случае (а именно когда все ребра вокруг текущей вершины изменили свой вес) алгоритм будет работать как последовательные вызовы алгоритма А* за O(n^2*log(n)). Улучшим эту оценку с помощью алгоритма D* lite. | ||
| + | |||
'''Примечание''': на практике же такой подход тоже имеет место на плотных графах (или матрицах), так как в среднем дает оценку О(n*log(n)). | '''Примечание''': на практике же такой подход тоже имеет место на плотных графах (или матрицах), так как в среднем дает оценку О(n*log(n)). | ||
== Алгоритм D* == | == Алгоритм D* == | ||
| + | |||
| + | '''CalcKey'''(s): | ||
| + | return [min(g(s);rhs(s)) + h(sstart;s);min(g(s); rhs(s))]; | ||
| + | |||
| + | '''Initialize'''(): | ||
| + | U = null; | ||
| + | for all s 2 S rhs(s) = g(s) = 1; | ||
| + | rhs(sgoal) = 0; | ||
| + | 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(); | ||
Версия 11:23, 19 декабря 2013
D* (pronounced "D star") is any one of the following three related incremental search algorithms.
LPA* Обозначим множество как множество вершин графа. Обозначим множество как множество вершин, исходящих из вершины . Аналогично множество как множество вершин, входящих в вершину .
Функция будет возвращать перехода из вершины в вершину . При этом .
Функция до .
Если Иначе
Будем говорить, что вершина s @A vertex s is called locally consistent@, если Очевидно, что если все вершины "locally consistent", то мы можем найти расстояние от стартовой вершины до любой.
Функция , где - вершина, возвращает вектор из 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*. Он неоднократно определяет путь между вершинами и , используя при этом данные из предыдущих итераций. Очевидно, что в худшем случае (а именно когда все ребра вокруг текущей вершины изменили свой вес) алгоритм будет работать как последовательные вызовы алгоритма А* за O(n^2*log(n)). Улучшим эту оценку с помощью алгоритма D* lite.
Примечание: на практике же такой подход тоже имеет место на плотных графах (или матрицах), так как в среднем дает оценку О(n*log(n)).
Алгоритм D*
CalcKey(s): return [min(g(s);rhs(s)) + h(sstart;s);min(g(s); rhs(s))];
Initialize(): U = null; for all s 2 S rhs(s) = g(s) = 1; rhs(sgoal) = 0; 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();