Skip to content

Commit b600b27

Browse files
committed
update README.md
1 parent 5d4385a commit b600b27

File tree

1 file changed

+64
-3
lines changed
  • additional_tasks/petya_and_vasya_labyrinth

1 file changed

+64
-3
lines changed

additional_tasks/petya_and_vasya_labyrinth/README.md

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ P0#000#000#
9595
* В случае, когда из лабиринта не удается выйти, вывести "Standoff! Valery!", тем самым обозначая, что охранник провел друзей.
9696

9797

98-
# Используемый алгоритм: построение дерева кратчайших путей: DAG Relaxation (как выяснилось, для этой задачи подходит очень не очень...)
98+
# Используемый алгоритм: построение дерева кратчайших путей: DAG Relaxation (для этой задачи подходит очень не очень)
9999

100100
Алгоритм релаксации является стандартным алгоритмом для нахождения кратчайших путей в направленном ацикличном графе (DAG). Алгоритм работает, последовательно обновляя расстояния до каждой вершины, используя информацию о расстояниях до её предков. Он работает за линейное время (`O(|V|+|E|)`, где `V` - количество вершин, а `E` - количество ребер).
101101

@@ -140,7 +140,7 @@ P0#000#000#
140140
*/
141141
template <AllowedVertType vert_t, AllowedWeightType weight_t>
142142
std::unordered_map<vert_t, weight_t> DAGRelaxation(
143-
const Graph<vert_t, weight_t>& graph, vert_t start_vert)
143+
const Graph<vert_t, weight_t>& graph, vert_t start);
144144
```
145145
146146
1. Проверяет, что граф направленный и что начальная вершина существует.
@@ -150,8 +150,69 @@ std::unordered_map<vert_t, weight_t> DAGRelaxation(
150150
151151
В итоге `dists` будет содержать кратчайшие расстояния от начальной вершины до всех остальных вершин в графе.
152152
153-
Основные моменты:
153+
### Основные моменты:
154154
* Топологическая сортировка важна, чтобы гарантировать, что мы не будем обновлять расстояния до вершины, пока не найдем кратчайший путь к ее предку.
155155
* Релаксация - это процесс обновления расстояний до вершин, используя информацию о расстояниях до их предков.
156156
* Код работает только для DAG, так как для циклических графов может не сходиться.
157157
158+
# Используемый алгоритм: нахождение кратчайшего расстояния между двумя вершинами: A* (для этой задачи подходит лучше)
159+
160+
Алгоритм A* — это эвристический алгоритм поиска пути, который находит кратчайший путь между начальной и конечной вершинами в графе. Он использует эвристическую функцию для оценки стоимости пути до конечной вершины, что позволяет ему эффективно обходить пространство поиска. В отличие от алгоритмов полного перебора, A* ориентирован на поиск наиболее перспективных путей.
161+
162+
## Теория алгоритма:
163+
164+
A* основывается на концепции функции стоимости `f(n) = g(n) + h(n)`, где:
165+
166+
`n` — текущая вершина.
167+
168+
`g(n)` — фактическая стоимость пути от начальной вершины до `n`.
169+
170+
`h(n)` — эвристическая оценка стоимости пути от n до конечной вершины. Эта функция должна быть допустимой (никогда не завышает фактическую стоимость) и монотонной (для улучшения эффективности, хотя это не является обязательным условием корректности).
171+
172+
Алгоритм A* использует приоритетную очередь для хранения вершин, которые ещё нужно посетить, отсортированных по возрастанию значения `f(n)`. На каждом шаге выбирается вершина с наименьшим `f(n)`, и её соседи рассматриваются. Если стоимость пути до соседа через текущую вершину меньше, чем текущая лучшая оценка стоимости до соседа, то оценка обновляется, и сосед добавляется в приоритетную очередь (или его приоритет изменяется).
173+
174+
Процесс повторяется до тех пор, пока не будет найдена конечная вершина, или приоритетная очередь не опустеет (в последнем случае путь не существует).
175+
176+
## Объяснение кода:
177+
```C++
178+
/**
179+
* @brief Вычисляет кратчайший путь между двумя вершинами с помощью A*.
180+
* @tparam vert_t: тип вершины в графе
181+
* @tparam weight_t: тип веса в графе
182+
* @param start: начальная вершина.
183+
* @param goal: конечная вершина.
184+
* @param graph: граф, для которого необходимо вычислить кратчайшие пути.
185+
* @param heuristic_range: функция эвристической оценки расстояния от
186+
* произвольной вершины до конечной вершины. Должна принимать две вершины в
187+
* качестве аргументов и возвращать вес (оценку расстояния).
188+
* @throw `std::invalid_argument("AStar: there is no such start vertice in
189+
* graph.")`.
190+
* @throw `std::invalid_argument("AStar: there is no such goal vertice in
191+
* graph.")`.
192+
* @return `weight_t`: стоимость кратчайшего пути от `start` до `goal`
193+
* (если до вершины нет пути, то значение будет равно
194+
* `std::numeric_limits<weight_t>::max()`).
195+
*/
196+
template <AllowedVertType vert_t, AllowedWeightType weight_t>
197+
weight_t AStar(
198+
const vert_t& start, const vert_t& goal,
199+
const Graph<vert_t, weight_t>& graph,
200+
std::function<weight_t(const vert_t&, const vert_t&)> heuristic_range);
201+
```
202+
203+
Код реализует алгоритм A* с использованием приоритетной очереди (`std::priority_queue`) и словарей для хранения стоимости пути от начальной вершины (`cost_from_start`) и суммы стоимости пути и эвристики (`range_plus_cost`).
204+
205+
1. Проверка входных данных: Код проверяет наличие начальной и конечной вершин в графе.
206+
2. Инициализация: Создаётся приоритетная очередь `visited_verts`, отсортированная по возрастанию стоимости `f(n)`. Словари `cost_from_start` и `range_plus_cost` инициализируются. Стоимость пути до начальной вершины устанавливается в 0, а до всех остальных — в бесконечность.
207+
3. Поиск пути: Пока приоритетная очередь не пуста, алгоритм извлекает вершину с наименьшей оценкой `f(n)`. Если это конечная вершина, то алгоритм возвращает стоимость пути. В противном случае, алгоритм рассматривает соседей текущей вершины, обновляет оценки стоимости пути и добавляет соседей в приоритетную очередь.
208+
209+
Возврат результата: Если конечная вершина не найдена после обработки всех вершин, алгоритм возвращает бесконечность, указывая на отсутствие пути.
210+
211+
### Основные моменты:
212+
213+
1. Эвристическая функция: качество работы A* сильно зависит от качества эвристической функции. Более точная эвристика приводит к более быстрому поиску.
214+
2. Допустимость и монотонность: эвристическая функция должна быть допустимой (не завышать фактическую стоимость) для гарантии нахождения кратчайшего пути. Монотонность (согласованность) эвристики улучшает производительность, но не является необходимым условием корректности.
215+
3. Сложность: сложность A* зависит от размера графа и качества эвристики. В худшем случае она может быть экспоненциальной, но на практике часто работает значительно быстрее, чем полный перебор.
216+
217+
Этот алгоритм является одним из наиболее эффективных алгоритмов поиска кратчайшего пути в графах, особенно когда пространство поиска велико. Выбор эвристики является ключевым фактором, влияющим на производительность алгоритма.
218+

0 commit comments

Comments
 (0)