<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=217.66.152.119&amp;*</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=217.66.152.119&amp;*"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/217.66.152.119"/>
		<updated>2026-07-09T09:46:44Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_D*&amp;diff=34434</id>
		<title>Алгоритм D*</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_D*&amp;diff=34434"/>
				<updated>2013-12-19T12:18:00Z</updated>
		
		<summary type="html">&lt;p&gt;217.66.152.119: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;D* (pronounced &amp;quot;D star&amp;quot;) is any one of the following three related incremental search algorithms.&lt;br /&gt;
&lt;br /&gt;
LPA*&lt;br /&gt;
Обозначим множество &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; как множество вершин графа.&lt;br /&gt;
Обозначим множество &amp;lt;tex&amp;gt;Succ(s) \in S&amp;lt;/tex&amp;gt; как множество вершин, исходящих из вершины &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Аналогично множество &amp;lt;tex&amp;gt;Pred(s) \in S&amp;lt;/tex&amp;gt; как множество вершин, входящих в вершину &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Функция &amp;lt;tex&amp;gt;0 &amp;lt;= с(s, s') &amp;lt;= +inf&amp;lt;/tex&amp;gt; будет возвращать перехода из вершины &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; в вершину &amp;lt;tex&amp;gt;s'&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;s' \in Succ(s)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Функция &amp;lt;tex&amp;gt;g(s) будет возвращать последнее известное значение расстояние от вершины &amp;lt;tex&amp;gt;s_{start}&amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;tex&amp;gt;s = s_{start}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;rhs(s) = 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
Иначе &lt;br /&gt;
&amp;lt;tex&amp;gt;rhs(s) = min_{s' \in pred(s)}(g(s') + c(s', s)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Будем говорить, что вершина s насыщена @A vertex s is called locally consistent@, если &amp;lt;tex&amp;gt;g(s) = rhs(s)&amp;lt;/tex&amp;gt;&lt;br /&gt;
переполнена&lt;br /&gt;
несыщена&lt;br /&gt;
Очевидно, что если все вершины &amp;quot;locally consistent&amp;quot;, то мы можем найти расстояние от стартовой вершины до любой.&lt;br /&gt;
&lt;br /&gt;
Функция &amp;lt;tex&amp;gt;key(s)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; - вершина, возвращает вектор из 2-ух значений &amp;lt;tex&amp;gt;k_1(s)&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;k_2(s)&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;k_1(s) = min(g(s), rhs(s)) + h(s, s_goal)&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;k_2(s) = min(g(s), rhs(s))&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если в конце поиска пути &amp;lt;tex&amp;gt;g(s_{goal}) = +inf&amp;lt;/tex&amp;gt;, то мы не смогли найти путь от &amp;lt;tex&amp;gt;s_{start}&amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt;s_{goal}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Псевдокод:&lt;br /&gt;
&lt;br /&gt;
  '''CalcKey'''(s):&lt;br /&gt;
  {&lt;br /&gt;
    return [&amp;lt;tex&amp;gt;min(g(s); rhs(s)) + h(s;s_{goal})&amp;lt;/tex&amp;gt;;&amp;lt;tex&amp;gt;min(g(s); rhs(s))&amp;lt;/tex&amp;gt;];&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  '''Initialize'''():&lt;br /&gt;
  {&lt;br /&gt;
    &amp;lt;tex&amp;gt;U = null;&amp;lt;/tex&amp;gt;&lt;br /&gt;
    &amp;lt;tex&amp;gt;for all s \in S&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt;rhs(s) = g(s) = 1;&amp;lt;/tex&amp;gt;&lt;br /&gt;
    &amp;lt;tex&amp;gt;rhs(s_start) = 0;&amp;lt;/tex&amp;gt;&lt;br /&gt;
    &amp;lt;tex&amp;gt;U.Insert(s_{start};CalcKey(s_{start}));&amp;lt;/tex&amp;gt;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  '''UpdateVertex'''(&amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;):&lt;br /&gt;
  {&lt;br /&gt;
    if (&amp;lt;tex&amp;gt;u != s_{start}&amp;lt;/tex&amp;gt;) &lt;br /&gt;
      &amp;lt;tex&amp;gt;rhs(u) = min_{s' \in Pred(u)}(g(s')+c(s',u));&amp;lt;/tex&amp;gt;&lt;br /&gt;
    if (&amp;lt;tex&amp;gt;u \in U&amp;lt;/tex&amp;gt;)&lt;br /&gt;
      U.Remove(u);&lt;br /&gt;
    if (g(u) != rhs(u))&lt;br /&gt;
      U.Insert(&amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;;CalcKey(&amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;));&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  '''ComputeShortestPath'''():&lt;br /&gt;
  {&lt;br /&gt;
    while (U.TopKey()&amp;lt; CalcKey(&amp;lt;tex&amp;gt;s_{goal}&amp;lt;/tex&amp;gt;) OR rhs(&amp;lt;tex&amp;gt;s_{goal}) != g(s_{goal}&amp;lt;/tex&amp;gt;))&lt;br /&gt;
      u = U.Pop();&lt;br /&gt;
      if (g(u) &amp;gt; rhs(u))&lt;br /&gt;
        g(u) = rhs(u);&lt;br /&gt;
        for all s 2 Succ(u) UpdateVertex(s);&lt;br /&gt;
      else&lt;br /&gt;
        g(u) = 1;&lt;br /&gt;
      for all &amp;lt;tex&amp;gt;s \in Succ(u) perec {u}&amp;lt;/tex&amp;gt;&lt;br /&gt;
        UpdateVertex(s);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  '''Main'''():&lt;br /&gt;
  {&lt;br /&gt;
    Initialize();&lt;br /&gt;
    while (&amp;lt;tex&amp;gt;s_{start} != s_{goal}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    {&lt;br /&gt;
      ComputeShortestPath();&lt;br /&gt;
      Wait for changes in edge costs;&lt;br /&gt;
      for all directed edges (u;v) with changed edge costs&lt;br /&gt;
      {&lt;br /&gt;
        Update the edge cost c(u;v);&lt;br /&gt;
        UpdateVertex(v);&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Таким образом мы описали алгоритм LPA*. Он неоднократно определяет путь между вершинами &amp;lt;tex&amp;gt;s_start&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;s_goal&amp;lt;/tex&amp;gt;, используя при этом данные из предыдущих итераций. Очевидно, что в худшем случае (а именно когда все ребра вокруг текущей вершины изменили свой вес) алгоритм будет работать как последовательные вызовы алгоритма А* за &amp;lt;tex&amp;gt;O(n^2*log(n))&amp;lt;/tex&amp;gt;. Улучшим эту оценку с помощью алгоритма D* lite.&lt;br /&gt;
&lt;br /&gt;
'''Примечание''': на практике же такой подход тоже имеет место на плотных графах (или матрицах), так как в среднем дает оценку О(n*log(n)).&lt;br /&gt;
&lt;br /&gt;
== Алгоритм D* ==&lt;br /&gt;
&lt;br /&gt;
  '''CalcKey'''(s):&lt;br /&gt;
    return [&amp;lt;tex&amp;gt;min(g(s);rhs(s)) + h(sstart;s)&amp;lt;/tex&amp;gt;;&amp;lt;tex&amp;gt;min(g(s); rhs(s))&amp;lt;/tex&amp;gt;];&lt;br /&gt;
&lt;br /&gt;
  '''Initialize'''():&lt;br /&gt;
    U = null;&lt;br /&gt;
    for all &amp;lt;tex&amp;gt;s \in S&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt;rhs(s) = g(s) = 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
    &amp;lt;tex&amp;gt;rhs(s_{goal}) = 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
    U.Insert(sgoal;CalcKey(sgoal));&lt;br /&gt;
&lt;br /&gt;
  '''UpdateVertex'''(u):&lt;br /&gt;
    if (u 6= s_{goal}) rhs(u) = mins02Succ(u)&lt;br /&gt;
(c(u;s&lt;br /&gt;
0&lt;br /&gt;
) + g(s&lt;br /&gt;
0&lt;br /&gt;
));&lt;br /&gt;
f07’g if (u 2 U) U.Remove(u);&lt;br /&gt;
f08’g if (g(u) 6= rhs(u)) U.Insert(u;CalcKey(u));&lt;br /&gt;
&lt;br /&gt;
  '''ComputeShortestPath'''()&lt;br /&gt;
    while (U.TopKey()&amp;lt;_ CalcKey(s_{start}) OR rhs(s_{start}) 6= g(s_{start}))&lt;br /&gt;
      u = U.Pop();&lt;br /&gt;
      if (g(u) &amp;gt; rhs(u))&lt;br /&gt;
        g(u) = rhs(u);&lt;br /&gt;
      for all s 2 Pred(u) UpdateVertex(s);&lt;br /&gt;
      else&lt;br /&gt;
        g(u) = 1;&lt;br /&gt;
      for all s 2 Pred(u) [ fug UpdateVertex(s);&lt;br /&gt;
&lt;br /&gt;
  '''Main'''():&lt;br /&gt;
    Initialize();&lt;br /&gt;
    ComputeShortestPath();&lt;br /&gt;
    while (s_{start} 6= s_{goal})&lt;br /&gt;
      if (g(sstart) = 1) then there is no known path */&lt;br /&gt;
      sstart = argmins02Succ(sstart)&lt;br /&gt;
(c(sstart;s&lt;br /&gt;
0&lt;br /&gt;
) + g(s&lt;br /&gt;
0&lt;br /&gt;
));&lt;br /&gt;
f22’g Move to sstart;&lt;br /&gt;
f23’g Scan graph for changed edge costs;&lt;br /&gt;
f24’g if any edge costs changed&lt;br /&gt;
f25’g for all directed edges (u;v) with changed edge costs&lt;br /&gt;
f26’g Update the edge cost c(u;v);&lt;br /&gt;
f27’g UpdateVertex(u);&lt;br /&gt;
f28’g for all s 2 U&lt;br /&gt;
f29’g U.Update(s;CalcKey(s));&lt;br /&gt;
f30’g ComputeShortestPath();&lt;/div&gt;</summary>
		<author><name>217.66.152.119</name></author>	</entry>

	</feed>