418
правок
Изменения
Нет описания правки
* Обозначим множество <tex>Pred(s) \subseteq V</tex> как множество вершин, входящих в вершину <tex>s</tex>.
Функция <tex>0 \leqslant c(s, s') \leqslant +\infty</tex> будет возвращать стоимость ребра <tex>(s;, s')</tex>. При этом <tex>c(s, s') = +\infty</tex> будет тогда и только тогда, когда ребра <tex>(s;, s')</tex> не существует.
{{Определение
Основная функция, описывающая алгоритм
Ждем каких-либо изменений графа.
'''for ''' всех ориентированных ребер (u; , v) с измененными весами: Обновляем результат функции c(u; , v); '''UpdateVertex'''(v);
=== Асимптотика ===
CalcKey(s):
'''return''' [min(g(s),rhs(s)) + h(f,s); , min(g(s),rhs(s))];
Initialize():
U = <tex>\varnothing</tex>;
'''for''' s <tex>\in</tex> V
rhs(s) = g(s) = <tex>+\infty</tex>
rhs(t) = 0
U.Insert(t; , CalcKey(t))
'''if''' u <tex>\ne</tex> t
rhs(u) = <tex>\min\limits_{s' \in Succ(u)}(c(u,s')+g(s'))</tex>
U.Remove(u)
'''if''' g(u) <tex>\ne</tex> rhs(u)
U.Insert(u; , CalcKey(u))
ComputeShortestPath():
UpdateVertex(s)
Initialize()
ComputeShortestPath()
<tex>f</tex> = такая вершина s', что <tex>\min\limits_{s' \in Succ(f)}(c(f, s') + g(s'))</tex>
Передвинулись вдоль найденного пути и изменили вершину <tex>f</tex>;
Сканируем роботом какие-либо изменения в графе или убеждаемся, что граф остается прежним.
'''if''' граф изменился
'''for''' всех ориентированных ребер <tex>(u; , v) </tex> с измененными весами: Обновляем результат функции <tex>c(u; , v)</tex>
UpdateVertex(u)
'''for''' s <tex>\in</tex> U
U.Update(s; , '''CalcKey'''(s));
'''ComputeShortestPath'''()
Теперь эвристическая функция должна поддерживать неравенство треугольника для всех вершин <tex>s,s',s'' \in V</tex>, т.е. <tex>h(s,s'') \leqslant h(s, s') + h(s',s'')</tex>. Так же должно выполняться свойство <tex>h(s,s') \leqslant c^*(s,s')</tex>, где <tex>c^*(s,s')</tex> - стоимость перехода по кратчайшему пути из <tex>s</tex> в <tex>s'</tex>, при этом <tex>s</tex> и <tex>s'</tex> не должны быть обязательно смежными. Такие свойства не противоречат свойствами из первой версии, а лишь усиливают их.
Допустим, что после того, как робот продвинется вдоль найденного пути на предыдущих итерациях, из вершины <tex>s </tex> в <tex>s'</tex>, он обнаружит изменения в графе. Первая компонента ключей <tex>k_1(s')</tex> может уменьшится максимум на <tex>h(s,s')</tex> (по определению ключа). Вторая компонента не зависит от функции h. Аналогично первой версии алгоритма, мы должны уменьшить первую компоненту ключа у всех вершин в очереди U. Очевидно, что <tex>h(s,s')</tex> будет одинаковым для всех вершин из U. Порядок в очереди не изменится, если произвести уменьшение. Следовательно уменьшение можно отложить, тем самым очередь не придется перестраивать на каждой итерации. Так же исходя из нового определения функции <tex>h</tex>, её значение будет всегда меньше, чем разность первых компонент ключей у соседних по приоритету вершин. Таким образом мы можем добавлять h(s,s') ко всем <tex>k_1(s')</tex> у ключей вершин из U.
Будем называть <tex>K_m</tex> ключевым модификатором. В нем мы и будет хранить сумму <tex>h(s,s')</tex>, которые нужно добавить ко всем вершинам из U.
=== Псевдокод ===
<tex>K_m = 0</tex>
'''for ''' s <tex>\in</tex> V
rhs(s) = g(s) = <tex>+\infty</tex>
rhs(t) = 0
U.Insert(t; , CalcKey(t));
'''if (''' <tex>K_{old}</tex> < '''CalcKey'''(u)) U.Insert(u; ''', CalcKey'''(u));
'''if ''' (g(u) > rhs(u)) g(u) = rhs(u); '''for ''' s <tex>\in</tex> Pred(u) UpdateVertex(s); '''else''' g(u) = <tex>+\infty</tex>; '''for ''' s <tex>\in</tex> Pred(u) <tex>\cup</tex> {u} '''UpdateVertex'''(s);
<tex>s_{last} = f</tex>
while (f <tex>\ne</tex> t)
<font color="green">// if (g(f) = <tex>+\infty</tex>) тогда путь на данной итерации не найден.</font>
<tex>f</tex> = такая вершина s', что <tex>\min\limits_{s' \in Succ(f)}(c(f, s') + g(s'))</tex>
Передвинулись вдоль найденного пути и изменили вершину <tex>f</tex>;.
Сканируем роботом какие-либо изменения в графе или убеждаемся, что граф остается прежним.
'''if (''' граф изменился) <tex>K_m = K_m + h(s_{last}, h_{start})</tex>; <tex>s_{last} = f</tex>; '''for ''' всех ориентированных ребер (u; , v) с измененными весами: Обновляем результат функции c(u; , v); '''UpdateVertex'''(u); '''ComputeShortestPath'''();
=== Асимптотика ===