You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: additional_tasks/petya_and_vasya_labyrinth/README.md
+64-3Lines changed: 64 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -95,7 +95,7 @@ P0#000#000#
95
95
* В случае, когда из лабиринта не удается выйти, вывести "Standoff! Valery!", тем самым обозначая, что охранник провел друзей.
96
96
97
97
98
-
# Используемый алгоритм: построение дерева кратчайших путей: DAG Relaxation (как выяснилось, для этой задачи подходит очень не очень...)
98
+
# Используемый алгоритм: построение дерева кратчайших путей: DAG Relaxation (для этой задачи подходит очень не очень)
99
99
100
100
Алгоритм релаксации является стандартным алгоритмом для нахождения кратчайших путей в направленном ацикличном графе (DAG). Алгоритм работает, последовательно обновляя расстояния до каждой вершины, используя информацию о расстояниях до её предков. Он работает за линейное время (`O(|V|+|E|)`, где `V` - количество вершин, а `E` - количество ребер).
В итоге `dists` будет содержать кратчайшие расстояния от начальной вершины до всех остальных вершин в графе.
152
152
153
-
Основные моменты:
153
+
### Основные моменты:
154
154
* Топологическая сортировка важна, чтобы гарантировать, что мы не будем обновлять расстояния до вершины, пока не найдем кратчайший путь к ее предку.
155
155
* Релаксация - это процесс обновления расстояний до вершин, используя информацию о расстояниях до их предков.
156
156
* Код работает только для DAG, так как для циклических графов может не сходиться.
157
157
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
+
* (если до вершины нет пути, то значение будет равно
Код реализует алгоритм 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
+
Этот алгоритм является одним из наиболее эффективных алгоритмов поиска кратчайшего пути в графах, особенно когда пространство поиска велико. Выбор эвристики является ключевым фактором, влияющим на производительность алгоритма.
0 commit comments