Алгоритъмът D*-Lite

Опитвам се да внедря алгоритъма за намиране на път D*-Lite, както е описано в Статия от 2002 г. от Кьониг и Лихачов за Boost::Graph. Мисля, че схванах добре основните идеи и теория зад него, но имам проблем да разбера кога се актуализират наборите Pred и Succ.

Предполагам, че това се случва в стъпка Move to sstart в Main, но тогава първото повикване до ComputeShortestPath ще бъде доста безсмислено? И трябва ли наборът Succ да бъде вмъкнат в същото време само като Pred? Тогава Pred и Succ могат да бъдат внедрени като двойно свързани списъци?

Вмъкнах псевдокода на алгоритъма по-долу. Наборите Pred и Succ са съответно предшественици и наследници. g, h, rhs и c са различни разходи и тегла. U е приоритетна опашка от върхове за посещение.

procedure CalculateKey(s)
{01’} return [min(g(s), rhs(s)) + h(sstart, s) + km; min(g(s), rhs(s))];

procedure Initialize()
{02’} U = ∅;
{03’} km = 0;
{04’} for all s ∈ S rhs(s) = g(s) = ∞;
{05’} rhs(sgoal) = 0;
{06’} U.Insert(sgoal, CalculateKey(sgoal));

procedure UpdateVertex(u)
{07’} if (u ≠ sgoal) rhs(u) = min s'∈Succ(u)(c(u, s') + g(s'));
{08’} if (u ∈ U) U.Remove(u);
{09’} if (g(u) ≠ rhs(u)) U.Insert(u, CalculateKey(u));

procedure ComputeShortestPath()
{10’} while (U.TopKey() < CalculateKey(sstart) OR rhs(sstart) ≠ g(sstart))
{11’}   kold = U.TopKey();
{12’}   u = U.Pop();
{13’}   if (kold ˙<CalculateKey(u))
{14’}     U.Insert(u, CalculateKey(u));
{15’}   else if (g(u) > rhs(u))
{16’}     g(u) = rhs(u);
{17’}     for all s ∈ Pred(u) UpdateVertex(s);
{18’}   else
{19’}     g(u) = ∞;
{20’}     for all s ∈ Pred(u) ∪ {u} UpdateVertex(s);

procedure Main()
{21’} slast = sstart;
{22’} Initialize();
{23’} ComputeShortestPath();
{24’} while (sstart ≠ sgoal)
{25’}   /* if (g(sstart) = ∞) then there is no known path */
{26’}   sstart = argmin s'∈Succ(sstart)(c(sstart, s') + g(s'));
{27’}   Move to sstart;
{28’}   Scan graph for changed edge costs;
{29’}   if any edge costs changed
{30’}     km = km + h(slast, sstart);
{31’}     slast = sstart;
{32’}     for all directed edges (u, v) with changed edge costs
{33’}       Update the edge cost c(u, v);
{34’}       UpdateVertex(u);
{35’}     ComputeShortestPath();

person carlpett    schedule 12.08.2011    source източник


Отговори (2)


Оказа се, че не имах прилична представа за основните идеи и теория... Разбрах погрешно значението на „наследник“ и „предшественик“, тъй като предположих, че се има предвид „в реда на пътя“ ", така че в пътя v0->v1->v2, v0 да бъде предшественик на v1, а v2 наследник.

Имаха предвид обаче просто съседите. Наборът предшественик беше наборът от всички върхове с "вътрешен ръб" към дадения връх, а наследниците имаха "извън ръбове".

person carlpett    schedule 15.08.2011

Прочетете хартията LPA* и ще разберете какви са. По принцип в LPA* търсенето започва от начална позиция. Така че наследниците ще бъдат възлите около възела u.Pop. Това означава, че те са възлите, към които ще отидете от текущия възел. И Pred, това е просто майчин възел. Това означава, че Пред от наследниците е u.Pop.

В DLite всичко върви обратното. Търсенето започва от позицията на целта. Така че е малко объркано за вас. Наследник на DLite е Pred в LPA*. И така, наследник = U.pop. Pred of DLite е наследник на LPA. И така, Pred е възелът, към който ще отидете от наследник.

Надявам се, че разбирате лошия ми английски.

person Truc Nguyen    schedule 22.10.2014