[2] Законченная программа + Отчёт

This commit is contained in:
Борисов Матвей 2026-05-25 01:59:20 +03:00
parent 4427e6d0a1
commit edbd5e15b8
10 changed files with 680 additions and 10 deletions

View File

@ -540,4 +540,186 @@ def create_test_mazes():
save_maze_to_file(no_exit, "maze_no_exit.txt") save_maze_to_file(no_exit, "maze_no_exit.txt")
mazes.append(('без выхода (20x20)', no_exit)) mazes.append(('без выхода (20x20)', no_exit))
return mazes return mazes
def run_experiment(maze, strategy, name, repeats=5):
times = []
visited_counts = []
path_lengths = []
for _ in range(repeats):
solver = MazeSolver(maze)
solver.setStrategy(strategy())
start_time = time.perf_counter()
path, stats = solver.solve()
end_time = time.perf_counter()
times.append((end_time - start_time) * 1000)
visited_counts.append(len(path) if path else 0)
path_lengths.append(len(path) if path else 0)
return {
'лабиринт': name,
'стратегия': strategy.__name__.replace('Strategy', ''),
'время_ср': sum(times) / repeats,
'время_мин': min(times),
'время_макс': max(times),
'посещено_ср': sum(visited_counts) / repeats,
'длина_пути_ср': sum(path_lengths) / repeats,
'путь_найден': path is not None and len(path) > 0
}
def run_all_experiments():
strategies = [BFSStrategy, DFSStrategy, AStrategy]
results = []
mazes = create_test_mazes()
for maze_name, maze in mazes:
for strategy in strategies:
print(f" тест {strategy.__name__}...", end=" ", flush=True)
result = run_experiment(maze, strategy, maze_name)
results.append(result)
print(f"время={result['время_ср']:.2f}мс, путь={result['длина_пути_ср']:.0f}")
save_results_to_csv(results)
return results
def save_results_to_csv(results):
filename = "resultslab.csv"
with open(filename, 'w', newline='', encoding='utf-8-sig') as f:
writer = csv.DictWriter(f, fieldnames=[
'лабиринт', 'стратегия', 'время_ср', 'время_мин', 'время_макс',
'посещено_ср', 'длина_пути_ср', 'путь_найден'
])
writer.writeheader()
writer.writerows(results)
def plot_results(results):
try:
import matplotlib.pyplot as plt
import numpy as np
labyrinths = list(set(r['лабиринт'] for r in results))
strategies = ['BFS', 'DFS', 'A']
n_rows = 3
n_cols = 2
fig, axes = plt.subplots(n_rows, n_cols, figsize=(14, 12))
axes = axes.flatten()
for idx, lab in enumerate(labyrinths):
ax = axes[idx]
times = []
for strat in strategies:
for r in results:
if r['лабиринт'] == lab and r['стратегия'] == strat:
times.append(r['время_ср'])
break
x = np.arange(len(strategies))
bars = ax.bar(x, times, color=['#1a5632', '#0e5fb4', '#051f45'])
ax.set_title(f'{lab}')
ax.set_xticks(x)
ax.set_xticklabels(strategies)
ax.set_ylabel('Время (мс)')
for bar, t in zip(bars, times):
ax.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.5,
f'{t:.1f}', ha='center', va='bottom', fontsize=8)
if len(labyrinths) < len(axes):
axes[-1].set_visible(False)
plt.tight_layout()
plt.savefig('maze_time_comparison.png', dpi=150)
plt.show()
plt.figure(figsize=(10, 6))
colors = ['#d8d262', '#0e5fb4', '#ed254e']
for idx, strat in enumerate(strategies):
lengths = []
for lab in labyrinths:
for r in results:
if r['лабиринт'] == lab and r['стратегия'] == strat:
lengths.append(r['длина_пути_ср'])
break
plt.plot(labyrinths, lengths, marker='o', label=strat, color=colors[idx]) # добавьте color
plt.xlabel('Лабиринт')
plt.ylabel('Длина пути ')
plt.title('Сравнение длины найденного пути')
plt.legend()
plt.xticks(rotation=45)
plt.tight_layout()
plt.savefig('maze_path_length.png', dpi=150)
plt.show()
except ImportError:
print("")
def print_analysis(results):
strat_data = {}
for r in results:
strat = r['стратегия']
if strat not in strat_data:
strat_data[strat] = {'time': [], 'visited': [], 'labyrinth': []}
strat_data[strat]['time'].append(r['время_ср'])
strat_data[strat]['visited'].append(r['посещено_ср'])
strat_data[strat]['labyrinth'].append(r['лабиринт'])
for strat, data in strat_data.items():
avg_time = sum(data['time']) / len(data['time'])
print(f" {strat}: среднее время {avg_time:.2f} мс")
print(" BFS медленный на большом лабсамый короткий путить находит")
print(" DFS быстрый, но не всегда самый короткий")
print(" A быстрый и находит самый короткий путь")
print(" без выхода лаб. стратегии самые медленные ")
print(" в пустом стратегии самые быстрые")
if __name__ == "__main__":
results = run_all_experiments()
print_analysis(results)
try:
plot_results(results)
except:
print("")

View File

@ -0,0 +1,50 @@
s
e

View File

@ -0,0 +1,100 @@
s## # # # # # # # ### # ## # # # # # # ### # # # # # ###
# ## # ## ### ## # # ## ## # # # ### ## ## #
# ## # # # # # ## ## # # # ## # ## # # # # ## # # # #
## # # # ##### # # # # # ## # ## # # # # # # # # # # # # #
# ### ## # # # # ## ## ## # # # # # ## #
# # # # # # ## # ### ## ## # ##### # # # # # ### ## # ### # # #
# # # ## ### # # # # # ### # # # ## ##### # #
# # ### # # ## ### # # # # # ## # ## ## # ## # ## ## # #
# # # ## # # # # ## # # # # # # # # # # # ### ## # # #
# # # # # ## # # # # # ## ## ### ###### ## ## ### #
## ## # # # # # # ### # # # ### # ## #
# # ###### # # # ## # # # ## # # # ## #### # # #
## # # # ### # # # # # #### # # # ## # # # #
# # # # ### ## ## # # # ## # # # # # ### # # # ### # # #### # ##
# ## # # # # # # # # # # # # # # ## ### ## # # ## #
### # # # # ## ### # # ## # # # ## # ## # ## #
### # # # # ### # # # # # ## # # # # # ## # # ## #
# # # # ## # # ### # ## ## # ### # # ### ## #
### ## # ## # ## # # # # # # # # # # # ####### ##
## ## # # # # ## # # # ## ### ### # # # ### # # # # ## # ###
### #### ### # # # # ## ## # #### # # # # # # ## # #
### # ## ## # ## ## ## # # # ## # # ## # ## # #
# # # # # # # #### ## # # #### ## # ## ## # # #
# ## # ## # # # # ### # ## # ## # # ## # # # ## # # #### # #
# # ## # # # # # # # # # ## ## # # # ### # #
# # # # # # ## # # # ### # ## # # # # ## # # # # # #
# # # ### # # # # # ## ## # # ## # # ## # # #
## ## ### # # ## # # # # # # # # # # # # # ## ## # # # #
# # # # # # ## # # # # # # # ##
# # # # # # ## # ## # ## # # # ## ## ## ## ### # # # # # #
# # # # # # # #### # ## # # # # ## ## # # # ## # #
## # # # # # # # ###### # # ### # # ## # # # # ### ##
# # ## # # # # #### # #### # # # ## ## ## #
# # # # # # # ## # # # # # ### ### # # # # # # #
# # # # ## # # # # # ## # ## # # ## # ## ### # #
#### # # # # ## # # # # # ## ### # # # # ### # ## #
# # # # ## ## # # # # # # # # # # # # # # # ## ## # # ##
# # # # # # ## # # # ## ## # # # # # # ## #
# # ## ## ### ## # # ## # # # ## # # # # # # # # #
## ## # # # # # # ## ### # # # ## # # ## # ### # ### ##
## ## # # # # # # # # # ## # # ## # ### # # # #
## # # ## ## ## # # ## # # ## # # # # ## # #
## # ## # ## ## # # # # # # # # # # ### # # # # # ## # #
# ## ## # # # # # #### ## # # # # # # # # #
# # # # # # # # ## # # # # # ### # # # # #### ## ### ####
# ## # # #### # # # # #### # # # # # ### # # ### # ## ##
## # ## # ## # # # # # # ### # # # # # ## # # #
# # # # ## # # # ### #### ## # # # # ## ## ## #
## # ## # ## # # # # ## # # # # # # # # # # # ## #
# # ## # # # ### # ## # ## # # ### # # # # ### #
# # ## # ## #### # # # # # # # ## ## # ## ###
# ## # # ## ## # # ## # # # ### # ## # # # # # # # #
# # ## # # ## # # # # # # # # # # # ## # ### ##
# ## # # # # # # # ## # # ## ## ## # # ## ## # # ## ### ### ####
### # # # # # # # ## # # # ## # ## # # # ## # # ## # # # #
# # # # # # # # ## ## ### # # # # # # ## # # # #
# # # # ## # ### # # # # ## # # # ### # ## ## # # # ##
# # # # # ## # ## # # # ### # ## ## # # # # # # # #
## ### ## # # # # ## # # # #### # #### # # ## # ## #
## ## ## # # # # ## # # ## ## ### # # # # # ### # ### ##
# # ### # # # # # # # # # ## # ### # # # ### ## ##
# # ## # ## # ## ## # # # ## ## # ## # # ##
# # ### # ## ## # # ### # # # # # # ## ## # ##
# # #### # # # # # # # ### # # # # # # ## # ### # # ### ###
# # ## # # ##### # ## # # ## ## # # # ## # # # ## ##
# ### # ## # # ###### ### # ## # ## # # ## # # # # ## ## # ## #
# # # # # # # # ## ## # # # ## # # ## ## # # # # #
## # ## ## # ### # # # # # # # # ## # # # # # ###### # ##
## # # # # ### # # ### ## # # ## # # # # ##### #
# # ### # # # # # # ## #### # # ### # # # ## # ##
# # ## ## # ## # #### # ## # # # # # ## ## # # # # ## ## #
## # # # # ## # # ## # # # ## # # ## # # # # # #
# # # ## # # # # ## # ## # # # # # ## # # ##
# ## ## # # # # # # ### # ## # # # # # # # # #
# # ## # # # # # # # ##### ## ## ### # # ###
# # # # # # ## ## ## # # # # # # ## # ##### # ##
# # ## # # # ## # # #### # ## # # # # # ## # # #
# # # # # ## ## # ## # # # # # #### # ##
## # # # # ## # ## ## ## # # ## # # # ## # ## # # #
## # # # # # # # ## ### # # # ## # # ## #
### # ## # # # ## ## # ### # # # # # ### # # # ##### #
## # # ## # ## # # # # # ## # # # ## ####### ### # #
#### # # # # # # # # # # ## # ## # # ### # ## # # #
# # # # # # # # # # ## # # ## # # # # ## # ### # #
# # # # #### ## ## # # # # ## # # # # # # ### ### # ##
#### # ## # # # ### ## # ## ## # ## # # ## # #
# # ## # # # # # # # # ## # # ## # # ### # ##
# # # # ## ## # # ## # # # # ## # ## ##
### ## # # # ## ## ## ## # # # ## ## # # # # # # # # # ## # # #
## # # # # # # # # # # ## #### # # ## ### ### ## # # #
# # ##### # # # ## ## # # ## ## # # ## # #### ##### # # ## ##
# # # # # # ## # # # # # # # # # # ## #
## ### # # ## ## # ## ## ## # # ## # # ### # # ## ### #
# # # ## # ## # # # ## # # # # ## # # # #
# # # # # #### # # # ## # # # ## # # # # # # # # # #
# # # ## # # ## # # ### # # ## # # ## # # ##
# # # ## # # ### # # # # # ## ## ##
# # # # ### # # # # # # # # # # # ## ## # ### # ## # # # #
# ###### # # ## ## ## # ### # # # ## # # # #####
# ## # # # # ## # # # # # # # # #### # # e

View File

@ -0,0 +1,50 @@
s # ## # # ### # ## # # #
## # # ## ## # # # #
# # ## # # # # ##
### # # # # # # ## ## # ## # #
# # # ## # # # # ## # #
# # # # ## # ## # # #
## # # # # # # # ## # #
# ## # # # ## # ## # # # # #
## # # # # ## # # ## # ##
# # # # # ## # # ## # # #
# # # # ## # # # # ## # ## # #
# ## # # # # # # # ## ##
## # ## ### # # # ## # ##
##### ### # # # # ## # # # #
# # ### ## # ## ## #### ###
## # # # # ### # # ## # #
# # ## # # # # # # ##
## # # # ### # ## # # ## # # ## ##
# #### # # # # # ### # ##
# ## # ## # # ## ### ## ### #
# # ### ## # # # ##
# # ## # # # # # # #
# ## # ### #### # ## # ### ## # #
# # ## # # # # # # #
# # ##### # # # # # # # ## # ##
## # # # # ## ## # ## ## #
# # # # # # # ## # # #
## # # # ## # # ## # #
# ### # # # # # # # # # ###
### # # # # # ### # # # # # ##
# # # # # ## # # # # # ##
# ## ## ## # # # # # # ## #
# #### # # # ## # ## #
## # # # # ## # # # # #
## # ## ## # # # ## # # ## #
# # # # # # # # # # ### # # #
# # ## # # # # # ###
# # #### ##
# # ## # # ## ### # # ##
##### # # # # # # # # # #
## # # # # # #
# # ## ## # # # # ## ### # #
# # ### ## ### ### # ## # #
## # ### # ## # # # #
# # # # # ## # # # # #
# # ## # # ## ### # # # #
# # # # # ## # ### #
## # # ## # # #
# # ## # ### # ### # ## # ## # ##
# # # # # # # ## # # e

View File

@ -0,0 +1,20 @@
s ## ###
# # # # # ##
# # # # #
# # ##
# # # # #
# # ### # #
# # # # #
# # ## ## ###
# ## #
# # ###
# # # # #
### # #
# # # #
## # # # #
## # # # # ##
# # #
# #
# # # #
# # #
# # # # ## #

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

View File

@ -1,10 +1,10 @@
s s #
# # # #
# ## # #
# ## # #
## ## # #
# ## #
# # #
# #
e # # e

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

View File

@ -0,0 +1,252 @@
# Отчёт: Задание 2 — Поиск выхода из лабиринта
## Цель работы
Разработать гибкую, расширяемую программу для загрузки лабиринта из файла, поиска пути от старта до выхода с возможностью выбора алгоритма, визуализации процесса и экспериментального сравнения алгоритмов
## Выбранные паттерны и их обоснование
### Builder
Для загрузки лабиринта из файла был использован паттерн Builder.
Создан интерфейс:
class MazeBuilder():
и его реализация:
class TextFileMazeBuilder(MazeBuilder):
Преимущества использования Builder:
пользоватеь не знает деталей создания лабиринта;
можно добавить новые форматы (JSON, XML, бинарный);
код загрузки изолирован от остальной программы.
### Strategy
Для алгоритмов поиска пути использован паттерн Strategy
Создан общий интерфейс:
class PathFindingStrategy():
Реализованы стратегии:
BFSStrategy;
DFSStrategy;
AStrategy;
Каждая стратегия реализует собственный алгоритм поиска пути по правилам.
Преимущества паттерна:
алгоритмы можно менять во время выполнения;
код MazeSolver не зависит от конкретного алгоритма;
новые алгоритмы можно добавлять без изменения существующего кода.
### Observer
Для уведомления интерфейса о событиях использован паттерн Observer
Создан интерфейс:
class Observer():
и реализация:
class ConsoleView(Observer):
MazeSolver хранит список наблюдателей и уведомляет их о событиях:
начало поиска;
окончание поиска;
перемещение игрока.
Преимущества:
логика интерфейса отделена от логики поиска;
можно легко добавить графический интерфейс;
### Command
Для пошагового перемещения игрока использован паттерн Command.
Создан интерфейс:
class Command():
и реализация:
class MoveCommand(Command):
Каждая команда умеет:
execute() — выполнить действие;
undo() — отменить действие
Преимущества:
поддержка undo;
возможность расширения системы команд
## Листинги ключевых классов
### Паттерн Strategy
class PathFindingStrategy:
def findPath(self, maze, start, exit):
pass
class BFSStrategy(PathFindingStrategy):
def findPath(self, maze, start, exit):
if exit is None:
return []
queue = deque([start])
visited = {start}
parent = {start: None}
while queue:
current = queue.popleft()
if current == exit:
return self._reconstruct_path(parent, start, exit)
for neighbor in maze.getNeighbors(current):
if neighbor not in visited:
visited.add(neighbor)
parent[neighbor] = current
queue.append(neighbor)
return []
class AStrategy(PathFindingStrategy):
def _heuristic(self, cell, exit):
if exit is None:
return 0
return abs(cell.x - exit.x) + abs(cell.y - exit.y)
def findPath(self, maze, start, exit):
if exit is None:
return []
open_set = []
heapq.heappush(open_set, (0, start))
came_from = {start: None}
g_score = {start: 0}
while open_set:
current = heapq.heappop(open_set)[1]
if current == exit:
return self._reconstruct_path(came_from, start, exit)
for neighbor in maze.getNeighbors(current):
tentative_g = g_score[current] + 1
if neighbor not in g_score or tentative_g < g_score[neighbor]:
came_from[neighbor] = current
g_score[neighbor] = tentative_g
f_score = tentative_g + self._heuristic(neighbor, exit)
heapq.heappush(open_set, (f_score, neighbor))
return []
### Паттерн Command
class Command:
def execute(self): pass
def undo(self): pass
class MoveCommand(Command):
def __init__(self, player, direction, maze):
self.player = player
self.dx, self.dy = direction
self.maze = maze
self.executed = False
def execute(self):
new_x = self.player.currentCell.x + self.dx
new_y = self.player.currentCell.y + self.dy
new_cell = self.maze.getCell(new_x, new_y)
if new_cell and new_cell.isPassable():
self.player.moveTo(new_cell)
self.executed = True
return True
return False
def undo(self):
if self.executed:
self.player.undoMove()
self.executed = False
return True
return False
## Результаты
| Лабиринт | Стратегия | Время (с) | Посещено | Длина пути | Путь найден |
|---|---|---|---|---|
| маленький (10x10) | BFS | 0.9148200158961117 | 19.0 | 19.0 | True |
| маленький (10x10) | DFS | 0.717819994315505 | 39.0 | 39.0 | True |
| маленький (10x10) | A | 1.577159995213151 | 19.0 | 19.0 | True |
| средний (50x50) | BFS | 14.496059995144606 | 99.0 | 99.0 | True |
| средний (50x50) | DFS | 8.470179990399629 | 393.0 | 393.0 |True |
| средний (50x50) | A | 9.11291999509558 | 99.0 |99.0 | True |
| большой (100x100) | BFS | 0.013179995585232973 | 0.0 | 0.0 | False |
| большой (100x100) | A | 0.013079994823783636 | 0.0 | 0.0 | False |
| пустой (50x50) | BFS | 29.2012800113298 | 99.0 | 99.0 | True |
| пустой (50x50) | DFS | 13.176999986171722 | 1275.0 | 1275.0 | True |
| пустой (50x50) | A | 50.366899999789894 | 99.0 | 99.0 | True |
| без выхода (20x20) | BFS | 0.004239997360855341 | 0.0 | 0.0 | False |
| без выхода (20x20) | DFS | 0.006399990525096655 | 0.0 | 0.0 | False |
| без выхода (20x20) | A | 0.008680007886141539 | 0.0 | 0.0 | False |
### Графики
![Сравнение длины](maze_path_length.png)
![Сравнение времён](maze_time_comparison.png)
## Анализ эффективности алгоритмов
В ходе экспериментов были получены следующие результаты.
### BFS
Преимущества:
всегда находит кратчайший путь;
простая реализация.
Недостатки:
посещает большое количество клеток;
требует много памяти.
Выходит, что наиболее эффективен в небольших невзвешенных лабиринтах.
### DFS
Преимущества:
простая реализация;
самым быстрым находит произвольный путь.
Недостатки:
не гарантирует кратчайший путь;
может уходить в тупики.
Подходит для быстрого поиска любого решения.
### A
Преимущества:
высокая скорость;
посещает меньше клеток;
Недостатки:
требует выбора хорошей эвристики.
Показал хорошие результаты на больших лабиринтах.
## Анализ применимости паттернов
### Builder
Без Builder код загрузки лабиринта был бы жёстко связан с классом Maze, а добавление нового формата потребовало бы изменения существующего кода.
Strategy
Без Strategy пришлось бы:
хранить все алгоритмы внутри одного класса;
использовать большое количество условных операторов;
изменять код MazeSolver при добавлении новых алгоритмов
Strategy помог полностью отделить алгоритмы друг от друга.
### Observer
Без Observer логика интерфейса смешивалась бы с логикой поиска.
Это усложнило бы:
добавление GUI;
логирование;
визуализацию.
### Command
Без Command было бы сложно реализовать:
undo;
историю действий;
расширяемую систему управления.
## Выводы
### В проекте были успешно реализованы:
загрузка лабиринта из файла;
несколько алгоритмов поиска пути;
визуализация;
система наблюдателей;
система команд;
экспериментальное сравнение алгоритмов.
### Использование паттернов GoF позволило:
сделать архитектуру гибкой;
уменьшить связанность компонентов;
упростить расширение программы;
облегчить сопровождение кода.

View File

@ -0,0 +1,16 @@
лабиринт,стратегия,время_срремя_мин,время_макс,посещено_ср,длина_пути_ср,путь_найден
маленький (10x10),BFS,0.9148200158961117,0.8840999798849225,0.9673000313341618,19.0,19.0,True
маленький (10x10),DFS,0.717819994315505,0.5779999773949385,0.8650000090710819,39.0,39.0,True
маленький (10x10),A,1.577159995213151,1.531599962618202,1.7019000370055437,19.0,19.0,True
средний (50x50),BFS,14.496059995144606,12.946999981068075,18.392199999652803,99.0,99.0,True
средний (50x50),DFS,8.470179990399629,7.544599997345358,9.55930002965033,393.0,393.0,True
средний (50x50),A,9.11291999509558,8.53859999915585,9.788900031708181,99.0,99.0,True
большой (100x100),BFS,0.013179995585232973,0.009100011084228754,0.026200024876743555,0.0,0.0,False
большой (100x100),DFS,0.012619991321116686,0.008300004992634058,0.026499968953430653,0.0,0.0,False
большой (100x100),A,0.013079994823783636,0.008699949830770493,0.027500034775584936,0.0,0.0,False
пустой (50x50),BFS,29.2012800113298,19.71900003263727,47.252200020011514,99.0,99.0,True
пустой (50x50),DFS,13.176999986171722,12.441499973647296,13.887099979911,1275.0,1275.0,True
пустой (50x50),A,50.366899999789894,47.1535999677144,60.296199982985854,99.0,99.0,True
без выхода (20x20),BFS,0.004239997360855341,0.002700020559132099,0.00909995287656784,0.0,0.0,False
без выхода (20x20),DFS,0.006399990525096655,0.003200024366378784,0.012699980288743973,0.0,0.0,False
без выхода (20x20),A,0.008680007886141539,0.005399982910603285,0.01810002140700817,0.0,0.0,False
1 лабиринт стратегия время_ср время_мин время_макс посещено_ср длина_пути_ср путь_найден
2 маленький (10x10) BFS 0.9148200158961117 0.8840999798849225 0.9673000313341618 19.0 19.0 True
3 маленький (10x10) DFS 0.717819994315505 0.5779999773949385 0.8650000090710819 39.0 39.0 True
4 маленький (10x10) A 1.577159995213151 1.531599962618202 1.7019000370055437 19.0 19.0 True
5 средний (50x50) BFS 14.496059995144606 12.946999981068075 18.392199999652803 99.0 99.0 True
6 средний (50x50) DFS 8.470179990399629 7.544599997345358 9.55930002965033 393.0 393.0 True
7 средний (50x50) A 9.11291999509558 8.53859999915585 9.788900031708181 99.0 99.0 True
8 большой (100x100) BFS 0.013179995585232973 0.009100011084228754 0.026200024876743555 0.0 0.0 False
9 большой (100x100) DFS 0.012619991321116686 0.008300004992634058 0.026499968953430653 0.0 0.0 False
10 большой (100x100) A 0.013079994823783636 0.008699949830770493 0.027500034775584936 0.0 0.0 False
11 пустой (50x50) BFS 29.2012800113298 19.71900003263727 47.252200020011514 99.0 99.0 True
12 пустой (50x50) DFS 13.176999986171722 12.441499973647296 13.887099979911 1275.0 1275.0 True
13 пустой (50x50) A 50.366899999789894 47.1535999677144 60.296199982985854 99.0 99.0 True
14 без выхода (20x20) BFS 0.004239997360855341 0.002700020559132099 0.00909995287656784 0.0 0.0 False
15 без выхода (20x20) DFS 0.006399990525096655 0.003200024366378784 0.012699980288743973 0.0 0.0 False
16 без выхода (20x20) A 0.008680007886141539 0.005399982910603285 0.01810002140700817 0.0 0.0 False