Алгоритм A* — различия между версиями
| Строка 1: | Строка 1: | ||
| − | Алгоритм '''А*'''( | + | Алгоритм '''А*''' (англ. ''A star'') {{---}} алгоритм поиска, который находит во взвешенном графе маршрут наименьшей стоимости от начальной вершины до выбранной конечной. |
==Описание== | ==Описание== | ||
В процессе работы алгоритма для вершин рассчитывается функция <tex>f(v) = g(v) + h(v)</tex>, где | В процессе работы алгоритма для вершин рассчитывается функция <tex>f(v) = g(v) + h(v)</tex>, где | ||
*<tex>g(v)</tex> {{---}} наименьшая стоимость пути в <tex>v</tex> из стартовой вершины, | *<tex>g(v)</tex> {{---}} наименьшая стоимость пути в <tex>v</tex> из стартовой вершины, | ||
| − | *<tex>h(v)</tex> {{---}} эвристическое приближение стоимости пути от <tex>v</tex> до конечной цели | + | *<tex>h(v)</tex> {{---}} эвристическое приближение стоимости пути от <tex>v</tex> до конечной цели. |
| − | |||
| + | Фактически, функция <tex>f(v)</tex> {{---}} длина пути до цели, которая складывается из пройденного расстояния <tex>g(v)</tex> и оставшегося расстояния <tex>h(v)</tex>. Исходя из этого, чем меньше значение <tex>f(v)</tex>, тем раньше мы откроем вершину <tex>v</tex>, так как через неё мы предположительно достигнем расстояние до цели быстрее всего. | ||
| + | Открытые алгоритмом вершины можно хранить в очереди с приоритетом по значению <tex>f(v)</tex>. А* действует подобно [[Алгоритм Дейкстры | алгоритму Дейкстры]] и просматривает среди всех маршрутов ведущих к цели сначала те, которые благодаря имеющейся информации (эвристическая функция) в данный момент являются наилучшими. | ||
| + | |||
| + | ==Свойства== | ||
| + | Чтобы A* был оптимален, выбранная функция <tex>h(v)</tex> должна быть '''допустимой''' эвристической функцией. | ||
| + | {{Определение | ||
| + | |definition=Говорят, что эвристическая оценка <tex>h(v)</tex> '''допустима''', если для любой вершины <tex>v</tex> значение <tex>h(v)</tex> меньше или равно весу кратчайшего пути от <tex>v</tex> до цели. | ||
| + | }} | ||
| + | |||
| + | Допустимая оценка является оптимистичной, потому что она предполагает, что стоимость решения меньше, чем оно есть на самом деле. <br> | ||
| + | Второе, более сильное условие {{---}} функция <tex>h(v)</tex> должна быть '''монотонной'''. | ||
| + | |||
| + | {{Определение | ||
| + | |definition=Эвристическая функция <tex>h(v)</tex> называется '''монотонной''' (или '''преемственной'''), если для любой вершины <tex>v_1</tex> и ее потомка <tex>v_2</tex> разность <tex>h(v_1)</tex> и <tex>h(v_2)</tex> не превышает фактического веса ребра <tex>c(v_1, v_2)</tex> от <tex>v_1</tex> до <tex>v_2</tex>, а эвристическая оценка целевого состояния равна нулю. | ||
| + | }} | ||
| + | |||
| + | {{Теорема | ||
| + | |statement=Любая монотонная эвристика допустима, однако обратное неверно. | ||
| + | |proof=Пусть <tex>k(v)</tex> {{---}} длина кратчайшего пути из вершины <tex>v</tex> до цели. | ||
| + | Докажем индукцией по числу шагов до цели, что <tex>h(v) \leqslant k(v)</tex>.<br><br> | ||
| + | Если до цели расстояние <tex>0</tex>, то <tex>v</tex> {{---}} цель и <tex>h(v) = 0 \leqslant k(v)</tex>.<br><br> | ||
| + | Пусть <tex>v</tex> находится на расстоянии <tex>i</tex> от цели. Тогда существует потомок <tex>v'</tex>, который находится на кратчайшем пути от <tex>v</tex> до цели и <tex>v'</tex>лежит на расстоянии <tex>i - 1</tex> шагов до цели. Следовательно, <tex>h(v) \leqslant c(v, v') + h(v')</tex>. <br> | ||
| + | По предположению, <tex>h(v') \leqslant k(v')</tex>. Следовательно, <tex>h(v) \leqslant c(v, v') + k(v') = k(v)</tex>. <br><br>Таким образом, монотонная эвристика <tex>h(v)</tex> допустима. | ||
| + | }} | ||
| + | |||
| + | {{Утверждение | ||
| + | |statement=Если <tex>h(v)</tex> монотонна, то последовательность значений <tex>f(v)</tex> на любом пути неубывает. | ||
| + | |proof=Доказательство следует из определения монотонности.<br> | ||
| + | Пусть <tex>v'</tex> {{---}} потомок <tex>v</tex>, тогда <tex>g(v') = g(v) + c(v, v')</tex>. <br>Следовательно, <tex>f(v') = g(v') + h(v') = g(v) + c(v, v') + h(v') \geqslant g(v) + h(v) = f(v)</tex>. | ||
| + | }} | ||
| + | |||
| + | {{Утверждение | ||
| + | |statement=Алгоритм A* является оптимальным, если функция <tex>h(v)</tex> монотонна. | ||
| + | |proof=Последовательность вершин "развёрнутых" во время работы алгоритма находится в неубывающем порядке значений <tex>f</tex>. Поэтому очередная выбираемая вершина должна представлять собой оптимальное решение, поскольку все дальнейшие узлы будут, по меньшей мере, столь же дорогостоящими. | ||
| + | }} | ||
| + | |||
| + | ==Примеры эвристик== | ||
Поведение алгоритма сильно зависит от того, какая эвристика используется. В свою очередь, выбор эвристики зависит[[Файл:Diagonal.png|thumb|right|Пример А* на сетке с возможностью ходить в восьми напрвлениях]] от постановки задачи. Часто А* используется для моделирования перемещения по поверхности, покрытой [http://deep-beta.co.uk/wp-content/uploads/2010/11/terrain.0.3+grid.png координатной сеткой]. | Поведение алгоритма сильно зависит от того, какая эвристика используется. В свою очередь, выбор эвристики зависит[[Файл:Diagonal.png|thumb|right|Пример А* на сетке с возможностью ходить в восьми напрвлениях]] от постановки задачи. Часто А* используется для моделирования перемещения по поверхности, покрытой [http://deep-beta.co.uk/wp-content/uploads/2010/11/terrain.0.3+grid.png координатной сеткой]. | ||
| − | * Если мы можем перемещаться в четырех направлениях, в качестве эвристики стоит выбрать [http://en.wikipedia.org/wiki/Manhattan_distance манхэттенское расстояние]<br> <tex>h(v) = |{v.x-goal.x}| + |{v.y-goal.y}|</tex>. | + | * Если мы можем перемещаться в четырех направлениях, то в качестве эвристики стоит выбрать [http://en.wikipedia.org/wiki/Manhattan_distance манхэттенское расстояние]<br> <tex>h(v) = |{v.x-goal.x}| + |{v.y-goal.y}|</tex>. |
| − | * [http://ru.wikipedia.org/wiki/Расстояние_Чебышева Расстояние Чебышева] | + | * [http://ru.wikipedia.org/wiki/Расстояние_Чебышева Расстояние Чебышева] применяется когда к четырем направлениям добавляются диагонали:<br> <tex>h(v) = \max{(|{v.x-goal.x}|, |{v.y-goal.y}|)}</tex>. |
| − | * Если передвижение не | + | * Если передвижение не ограничено сеткой, то можно использовать евклидово расстояние по прямой:<br> <tex>h(v) = \sqrt{(v.x-goal.x)^2 + (v.y-goal.y)^2}</tex>. |
Также стоит обратить внимание на то как соотносятся <tex>f(v)</tex> и <tex>h(v)</tex>. Если они измеряются в разных величинах (например, <tex>g(v)</tex> {{---}} это расстояние в километрах, а <tex>h(v)</tex> {{---}} оценка времени пути в часах) А* может выдать некорректный результат. | Также стоит обратить внимание на то как соотносятся <tex>f(v)</tex> и <tex>h(v)</tex>. Если они измеряются в разных величинах (например, <tex>g(v)</tex> {{---}} это расстояние в километрах, а <tex>h(v)</tex> {{---}} оценка времени пути в часах) А* может выдать некорректный результат. | ||
| − | == | + | ==Реализация== |
| − | + | В приведённой реализации: | |
| − | [[ | + | * <tex>Q</tex> {{---}} множество вершин, которые требуется рассмотреть |
| − | + | * <tex>U</tex> {{---}} множество рассмотренных вершин | |
| − | + | * <tex>f[x]</tex> {{---}} значение эвристической функции "расстояние + стоимость" для вершины <tex>x</tex> | |
| − | + | * <tex>g[x]</tex> {{---}} стоимость пути от начальной вершины до <tex>x</tex> | |
| − | f[start] = g[start] + h | + | * <tex>h(x)</tex> {{---}} эвристическая оценка расстояния от вершины <tex>x</tex> до конечной вершины. |
| − | + | На каждом этапе работы алгоритма из множества <tex>Q</tex> выбирается вершина с наименьшим значением эвристической функции и просматриваются её соседи. Для каждого из соседей обновлятся расстояние, значение эвристическо функции и он добавляется в множество <tex>Q</tex>.<br> | |
| − | while | + | Псевдокод: |
| − | + | '''bool''' A*(start, goal)''':''' | |
| − | if | + | U = <tex> \varnothing </tex> |
| − | return | + | Q = <tex> \varnothing </tex> |
| − | + | Q.push(start) | |
| − | for | + | g[start] = 0 |
| − | + | f[start] = g[start] + h(start) | |
| − | + | '''while''' Q.size() != 0 | |
| − | + | current = вершина из <tex>Q</tex> с минимальным значением <tex>f</tex> | |
| − | if | + | '''if''' current == goal |
| − | + | '''return''' ''true'' <font color="green">// нашли путь до нужной вершины</font> | |
| − | + | Q.remove(current) | |
| − | + | U.push(current) | |
| − | + | '''for''' v : смежные с current вершины | |
| − | + | tentative_score = g[current] + d(current, v) <font color="green">// d(current, v) {{---}} стоимость пути между current и v</font> | |
| − | + | '''if''' <tex>v \in U</tex> '''and''' tentative_score >= g[v] | |
| − | + | '''continue''' | |
| − | if | + | '''if''' <tex>v \notin U</tex> '''or''' tentative_score < g[v] |
| − | parent[ | + | parent[v] = current |
| − | g[ | + | g[v] = tentative_score |
| − | f[ | + | f[v] = g[v] + h(v) |
| − | return | + | '''if''' <tex>v \notin Q</tex> |
| + | Q.push(v) | ||
| + | '''return''' ''false'' | ||
| − | == | + | ==См. также== |
| − | == | + | * [[Эвристики для поиска кратчайших путей]] |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | == | + | ==Источники информации== |
| − | + | * С. Рассел, П. Норвиг {{---}} Искусственный интеллект. Современный подход, 2е издание | |
| − | + | * [https://ru.wikipedia.org/wiki/Алгоритм_поиска_A* Википедия {{---}} Алгоритм поиска A*] | |
| − | *[ | + | * [https://en.wikipedia.org/wiki/A*_search_algorithm Wikipedia {{---}} A* search algorithm] |
| − | *[ | + | * [http://theory.stanford.edu/~amitp/GameProgramming/ Статья о поиске кратчайших путей] |
| − | *[http://theory.stanford.edu/~amitp/GameProgramming/ Статья о поиске кратчайших путей] | + | * [http://dl.acm.org/citation.cfm?id=3830&coll=portal&dl=ACM Generalized best-first search strategies and the optimality of A*] |
| − | *[http://dl.acm.org/citation.cfm?id=3830&coll=portal&dl=ACM Generalized best-first search strategies and the optimality of A*] | ||
[[Категория: Алгоритмы и структуры данных]] | [[Категория: Алгоритмы и структуры данных]] | ||
[[Категория: Кратчайшие пути в графах ]] | [[Категория: Кратчайшие пути в графах ]] | ||
Версия 18:53, 12 января 2016
Алгоритм А* (англ. A star) — алгоритм поиска, который находит во взвешенном графе маршрут наименьшей стоимости от начальной вершины до выбранной конечной.
Описание
В процессе работы алгоритма для вершин рассчитывается функция , где
- — наименьшая стоимость пути в из стартовой вершины,
- — эвристическое приближение стоимости пути от до конечной цели.
Фактически, функция — длина пути до цели, которая складывается из пройденного расстояния и оставшегося расстояния . Исходя из этого, чем меньше значение , тем раньше мы откроем вершину , так как через неё мы предположительно достигнем расстояние до цели быстрее всего. Открытые алгоритмом вершины можно хранить в очереди с приоритетом по значению . А* действует подобно алгоритму Дейкстры и просматривает среди всех маршрутов ведущих к цели сначала те, которые благодаря имеющейся информации (эвристическая функция) в данный момент являются наилучшими.
Свойства
Чтобы A* был оптимален, выбранная функция должна быть допустимой эвристической функцией.
| Определение: |
| Говорят, что эвристическая оценка допустима, если для любой вершины значение меньше или равно весу кратчайшего пути от до цели. |
Допустимая оценка является оптимистичной, потому что она предполагает, что стоимость решения меньше, чем оно есть на самом деле.
Второе, более сильное условие — функция должна быть монотонной.
| Определение: |
| Эвристическая функция называется монотонной (или преемственной), если для любой вершины и ее потомка разность и не превышает фактического веса ребра от до , а эвристическая оценка целевого состояния равна нулю. |
| Теорема: |
Любая монотонная эвристика допустима, однако обратное неверно. |
| Доказательство: |
|
Пусть — длина кратчайшего пути из вершины до цели.
Докажем индукцией по числу шагов до цели, что . Таким образом, монотонная эвристика допустима. |
| Утверждение: |
Если монотонна, то последовательность значений на любом пути неубывает. |
|
Доказательство следует из определения монотонности. Следовательно, . |
| Утверждение: |
Алгоритм A* является оптимальным, если функция монотонна. |
| Последовательность вершин "развёрнутых" во время работы алгоритма находится в неубывающем порядке значений . Поэтому очередная выбираемая вершина должна представлять собой оптимальное решение, поскольку все дальнейшие узлы будут, по меньшей мере, столь же дорогостоящими. |
Примеры эвристик
Поведение алгоритма сильно зависит от того, какая эвристика используется. В свою очередь, выбор эвристики зависит от постановки задачи. Часто А* используется для моделирования перемещения по поверхности, покрытой координатной сеткой.- Если мы можем перемещаться в четырех направлениях, то в качестве эвристики стоит выбрать манхэттенское расстояние
.
- Расстояние Чебышева применяется когда к четырем направлениям добавляются диагонали:
.
- Если передвижение не ограничено сеткой, то можно использовать евклидово расстояние по прямой:
.
Также стоит обратить внимание на то как соотносятся и . Если они измеряются в разных величинах (например, — это расстояние в километрах, а — оценка времени пути в часах) А* может выдать некорректный результат.
Реализация
В приведённой реализации:
- — множество вершин, которые требуется рассмотреть
- — множество рассмотренных вершин
- — значение эвристической функции "расстояние + стоимость" для вершины
- — стоимость пути от начальной вершины до
- — эвристическая оценка расстояния от вершины до конечной вершины.
На каждом этапе работы алгоритма из множества выбирается вершина с наименьшим значением эвристической функции и просматриваются её соседи. Для каждого из соседей обновлятся расстояние, значение эвристическо функции и он добавляется в множество .
Псевдокод:
bool A*(start, goal):
U =
Q =
Q.push(start)
g[start] = 0
f[start] = g[start] + h(start)
while Q.size() != 0
current = вершина из с минимальным значением
if current == goal
return true // нашли путь до нужной вершины
Q.remove(current)
U.push(current)
for v : смежные с current вершины
tentative_score = g[current] + d(current, v) // d(current, v) — стоимость пути между current и v
if and tentative_score >= g[v]
continue
if or tentative_score < g[v]
parent[v] = current
g[v] = tentative_score
f[v] = g[v] + h(v)
if
Q.push(v)
return false
См. также
Источники информации
- С. Рассел, П. Норвиг — Искусственный интеллект. Современный подход, 2е издание
- Википедия — Алгоритм поиска A*
- Wikipedia — A* search algorithm
- Статья о поиске кратчайших путей
- Generalized best-first search strategies and the optimality of A*