Алгоритм A* — различия между версиями
| Строка 1: | Строка 1: | ||
Алгоритм '''А*''' (англ. ''A star'') {{---}} алгоритм поиска, который находит во взвешенном графе маршрут наименьшей стоимости от начальной вершины до выбранной конечной. | Алгоритм '''А*''' (англ. ''A star'') {{---}} алгоритм поиска, который находит во взвешенном графе маршрут наименьшей стоимости от начальной вершины до выбранной конечной. | ||
==Описание== | ==Описание== | ||
| + | [[Файл:Astar_progress_animation.gif|right|frame|Пример работы А*. Пустые кружки принадлежат к открытому списку, а окрашенные к закрытому.]] | ||
В процессе работы алгоритма для вершин рассчитывается функция <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> из стартовой вершины, | ||
| Строка 7: | Строка 8: | ||
Фактически, функция <tex>f(v)</tex> {{---}} длина пути до цели, которая складывается из пройденного расстояния <tex>g(v)</tex> и оставшегося расстояния <tex>h(v)</tex>. Исходя из этого, чем меньше значение <tex>f(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>. А* действует подобно [[Алгоритм Дейкстры | алгоритму Дейкстры]] и просматривает среди всех маршрутов ведущих к цели сначала те, которые благодаря имеющейся информации (эвристическая функция) в данный момент являются наилучшими. | Открытые алгоритмом вершины можно хранить в очереди с приоритетом по значению <tex>f(v)</tex>. А* действует подобно [[Алгоритм Дейкстры | алгоритму Дейкстры]] и просматривает среди всех маршрутов ведущих к цели сначала те, которые благодаря имеющейся информации (эвристическая функция) в данный момент являются наилучшими. | ||
| − | + | <br clear="all"> | |
==Свойства== | ==Свойства== | ||
Чтобы A* был оптимален, выбранная функция <tex>h(v)</tex> должна быть '''допустимой''' эвристической функцией. | Чтобы A* был оптимален, выбранная функция <tex>h(v)</tex> должна быть '''допустимой''' эвристической функцией. | ||
| Строка 42: | Строка 43: | ||
==Примеры эвристик== | ==Примеры эвристик== | ||
| − | Поведение алгоритма сильно зависит от того, какая эвристика используется. В свою очередь, выбор эвристики зависит[[Файл:Diagonal.png|thumb|right|Пример А* на сетке с возможностью ходить в восьми напрвлениях]] от постановки задачи. Часто А* используется для моделирования перемещения по поверхности, покрытой | + | Поведение алгоритма сильно зависит от того, какая эвристика используется. В свою очередь, выбор эвристики зависит[[Файл:Diagonal.png|thumb|right|Пример А* на сетке с возможностью ходить в восьми напрвлениях]] от постановки задачи. Часто А* используется для моделирования перемещения по поверхности, покрытой координатной сеткой. |
| − | * Если мы можем перемещаться в четырех направлениях, то в качестве эвристики стоит выбрать [ | + | * Если мы можем перемещаться в четырех направлениях, то в качестве эвристики стоит выбрать манхэттенское расстояние<ref>[https://en.wikipedia.org/wiki/Manhattan_distance Wikipedia {{---}} Manhattan distance]</ref><br> <tex>h(v) = |{v.x-goal.x}| + |{v.y-goal.y}|</tex>. |
| − | * [ | + | * Расстояние Чебышева<ref>[https://ru.wikipedia.org/wiki/Расстояние_Чебышева Википедия {{---}} Расстояние Чебышева]</ref> применяется, когда к четырем направлениям добавляются диагонали:<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>. | * Если передвижение не ограничено сеткой, то можно использовать евклидово расстояние по прямой:<br> <tex>h(v) = \sqrt{(v.x-goal.x)^2 + (v.y-goal.y)^2}</tex>. | ||
| Строка 54: | Строка 55: | ||
==Реализация== | ==Реализация== | ||
В приведённой реализации: | В приведённой реализации: | ||
| − | * <tex>Q</tex> {{---}} множество вершин, которые требуется рассмотреть | + | * <tex>Q</tex> {{---}} множество вершин, которые требуется рассмотреть, |
| − | * <tex>U</tex> {{---}} множество рассмотренных вершин | + | * <tex>U</tex> {{---}} множество рассмотренных вершин, |
| − | * <tex>f[x]</tex> {{---}} значение эвристической функции "расстояние + стоимость" для вершины <tex>x</tex> | + | * <tex>f[x]</tex> {{---}} значение эвристической функции "расстояние + стоимость" для вершины <tex>x</tex>, |
| − | * <tex>g[x]</tex> {{---}} стоимость пути от начальной вершины до <tex>x</tex> | + | * <tex>g[x]</tex> {{---}} стоимость пути от начальной вершины до <tex>x</tex>, |
* <tex>h(x)</tex> {{---}} эвристическая оценка расстояния от вершины <tex>x</tex> до конечной вершины. | * <tex>h(x)</tex> {{---}} эвристическая оценка расстояния от вершины <tex>x</tex> до конечной вершины. | ||
На каждом этапе работы алгоритма из множества <tex>Q</tex> выбирается вершина с наименьшим значением эвристической функции и просматриваются её соседи. Для каждого из соседей обновлятся расстояние, значение эвристическо функции и он добавляется в множество <tex>Q</tex>.<br> | На каждом этапе работы алгоритма из множества <tex>Q</tex> выбирается вершина с наименьшим значением эвристической функции и просматриваются её соседи. Для каждого из соседей обновлятся расстояние, значение эвристическо функции и он добавляется в множество <tex>Q</tex>.<br> | ||
| Строка 74: | Строка 75: | ||
U.push(current) | U.push(current) | ||
'''for''' v : смежные с current вершины | '''for''' v : смежные с current вершины | ||
| − | + | tentativeScore = g[current] + d(current, v) <font color="green">// d(current, v) {{---}} стоимость пути между current и v</font> | |
| − | '''if''' <tex>v \in U</tex> '''and''' | + | '''if''' <tex>v \in U</tex> '''and''' tentativeScore >= g[v] |
'''continue''' | '''continue''' | ||
| − | '''if''' <tex>v \notin U</tex> '''or''' | + | '''if''' <tex>v \notin U</tex> '''or''' tentativeScore < g[v] |
parent[v] = current | parent[v] = current | ||
| − | g[v] = | + | g[v] = tentativeScore |
f[v] = g[v] + h(v) | f[v] = g[v] + h(v) | ||
'''if''' <tex>v \notin Q</tex> | '''if''' <tex>v \notin Q</tex> | ||
Q.push(v) | Q.push(v) | ||
'''return''' ''false'' | '''return''' ''false'' | ||
| + | |||
| + | ==Примечания== | ||
| + | <references/> | ||
==См. также== | ==См. также== | ||
* [[Эвристики для поиска кратчайших путей]] | * [[Эвристики для поиска кратчайших путей]] | ||
| + | * [[Алгоритм Флойда]] | ||
| + | * [[Алгоритм Дейкстры]] | ||
| + | * [[Алгоритм Форда-Беллмана]] | ||
==Источники информации== | ==Источники информации== | ||
Версия 21:42, 12 января 2016
Алгоритм А* (англ. A star) — алгоритм поиска, который находит во взвешенном графе маршрут наименьшей стоимости от начальной вершины до выбранной конечной.
Содержание
Описание
В процессе работы алгоритма для вершин рассчитывается функция , где
- — наименьшая стоимость пути в из стартовой вершины,
- — эвристическое приближение стоимости пути от до конечной цели.
Фактически, функция — длина пути до цели, которая складывается из пройденного расстояния и оставшегося расстояния . Исходя из этого, чем меньше значение , тем раньше мы откроем вершину , так как через неё мы предположительно достигнем расстояние до цели быстрее всего.
Открытые алгоритмом вершины можно хранить в очереди с приоритетом по значению . А* действует подобно алгоритму Дейкстры и просматривает среди всех маршрутов ведущих к цели сначала те, которые благодаря имеющейся информации (эвристическая функция) в данный момент являются наилучшими.
Свойства
Чтобы A* был оптимален, выбранная функция должна быть допустимой эвристической функцией.
| Определение: |
| Говорят, что эвристическая оценка допустима, если для любой вершины значение меньше или равно весу кратчайшего пути от до цели. |
Допустимая оценка является оптимистичной, потому что она предполагает, что стоимость решения меньше, чем оно есть на самом деле.
Второе, более сильное условие — функция должна быть монотонной.
| Определение: |
| Эвристическая функция называется монотонной (или преемственной), если для любой вершины и ее потомка разность и не превышает фактического веса ребра от до , а эвристическая оценка целевого состояния равна нулю. |
| Теорема: |
Любая монотонная эвристика допустима, однако обратное неверно. |
| Доказательство: |
|
Пусть — длина кратчайшего пути из вершины до цели.
Докажем индукцией по числу шагов до цели, что . Таким образом, монотонная эвристика допустима. |
| Утверждение: |
Если монотонна, то последовательность значений на любом пути неубывает. |
|
Доказательство следует из определения монотонности. Следовательно, . |
| Утверждение: |
Алгоритм A* является оптимальным, если функция монотонна. |
| Последовательность вершин "развёрнутых" во время работы алгоритма находится в неубывающем порядке значений . Поэтому очередная выбираемая вершина должна представлять собой оптимальное решение, поскольку все дальнейшие узлы будут, по меньшей мере, столь же дорогостоящими. |
Примеры эвристик
Поведение алгоритма сильно зависит от того, какая эвристика используется. В свою очередь, выбор эвристики зависит от постановки задачи. Часто А* используется для моделирования перемещения по поверхности, покрытой координатной сеткой.- Если мы можем перемещаться в четырех направлениях, то в качестве эвристики стоит выбрать манхэттенское расстояние[1]
.
- Расстояние Чебышева[2] применяется, когда к четырем направлениям добавляются диагонали:
.
- Если передвижение не ограничено сеткой, то можно использовать евклидово расстояние по прямой:
.
Также стоит обратить внимание на то как соотносятся и . Если они измеряются в разных величинах (например, — это расстояние в километрах, а — оценка времени пути в часах) А* может выдать некорректный результат.
Реализация
В приведённой реализации:
- — множество вершин, которые требуется рассмотреть,
- — множество рассмотренных вершин,
- — значение эвристической функции "расстояние + стоимость" для вершины ,
- — стоимость пути от начальной вершины до ,
- — эвристическая оценка расстояния от вершины до конечной вершины.
На каждом этапе работы алгоритма из множества выбирается вершина с наименьшим значением эвристической функции и просматриваются её соседи. Для каждого из соседей обновлятся расстояние, значение эвристическо функции и он добавляется в множество .
Псевдокод:
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 вершины
tentativeScore = g[current] + d(current, v) // d(current, v) — стоимость пути между current и v
if and tentativeScore >= g[v]
continue
if or tentativeScore < g[v]
parent[v] = current
g[v] = tentativeScore
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*
