From 8a6344f301078dddd6f28ae56647d1f44746d64b Mon Sep 17 00:00:00 2001 From: Proninvv Date: Tue, 19 May 2026 22:35:33 +0300 Subject: [PATCH] =?UTF-8?q?=D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BD?= =?UTF-8?q?=D0=BE=20=D1=82=D0=B5=D1=81=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ProninVV/task-2-oop/AStarStrategy.py | 2 +- ProninVV/task-2-oop/BreadthFirstSearch.py | 2 +- ProninVV/task-2-oop/DepthFirstSearch.py | 5 +- ProninVV/task-2-oop/MazeBuilder.py | 4 + ProninVV/task-2-oop/main.py | 1 + ProninVV/task-2-oop/test.py | 124 ++++++++++++++++++++++ 6 files changed, 135 insertions(+), 3 deletions(-) create mode 100644 ProninVV/task-2-oop/test.py diff --git a/ProninVV/task-2-oop/AStarStrategy.py b/ProninVV/task-2-oop/AStarStrategy.py index e366706..b179458 100644 --- a/ProninVV/task-2-oop/AStarStrategy.py +++ b/ProninVV/task-2-oop/AStarStrategy.py @@ -31,7 +31,7 @@ class AStarStrategy(PathFindingStrategy): path.append(current) current = parents[current] path.reverse() - return path + return path, len(parents) childs = maze.getNeighbors(u) for child in childs: diff --git a/ProninVV/task-2-oop/BreadthFirstSearch.py b/ProninVV/task-2-oop/BreadthFirstSearch.py index 6837a21..3fa9166 100644 --- a/ProninVV/task-2-oop/BreadthFirstSearch.py +++ b/ProninVV/task-2-oop/BreadthFirstSearch.py @@ -21,7 +21,7 @@ class BFSStrategy(PathFindingStrategy): path.append(current) current = parents[current] path.reverse() - return path + return path, len(parents) childs = maze.getNeighbors(u) for child in childs: diff --git a/ProninVV/task-2-oop/DepthFirstSearch.py b/ProninVV/task-2-oop/DepthFirstSearch.py index 5f0f2c0..a54d9ba 100644 --- a/ProninVV/task-2-oop/DepthFirstSearch.py +++ b/ProninVV/task-2-oop/DepthFirstSearch.py @@ -11,9 +11,12 @@ class DFSStrategy(PathFindingStrategy): visited = set() path = [] + count_cell = 0 + def dfs(root: Cell) -> bool: visited.add(root) path.append(root) + count_cell += 1 if root == exit: return True @@ -28,6 +31,6 @@ class DFSStrategy(PathFindingStrategy): return False if dfs(start): - return path + return path, count_cell return [] diff --git a/ProninVV/task-2-oop/MazeBuilder.py b/ProninVV/task-2-oop/MazeBuilder.py index cff52e9..c43a4b4 100644 --- a/ProninVV/task-2-oop/MazeBuilder.py +++ b/ProninVV/task-2-oop/MazeBuilder.py @@ -12,6 +12,10 @@ class TextFileMazeBuilder(MazeBuilder): def __init__(self): self._maze = None + @property + def maze(self): + return self._maze + def buildFromFile(self, filename: str): with open(filename, mode='r', encoding='utf-8') as file: diff --git a/ProninVV/task-2-oop/main.py b/ProninVV/task-2-oop/main.py index 77589db..bee4738 100644 --- a/ProninVV/task-2-oop/main.py +++ b/ProninVV/task-2-oop/main.py @@ -1,5 +1,6 @@ from MazeBuilder import TextFileMazeBuilder from BreadthFirstSearch import BFSStrategy +from Maze import Maze maze1 = TextFileMazeBuilder().buildFromFile("text.txt") diff --git a/ProninVV/task-2-oop/test.py b/ProninVV/task-2-oop/test.py new file mode 100644 index 0000000..47e2e86 --- /dev/null +++ b/ProninVV/task-2-oop/test.py @@ -0,0 +1,124 @@ +import csv +import time +import os +import matplotlib.pyplot as plt +import numpy as np + +from MazeBuilder import TextFileMazeBuilder +from MazeSolver import MazeSolver, SearchStats +from DepthFirstSearch import DFSStrategy +from BreadthFirstSearch import BFSStrategy +from Deikstra import DeikstraFind +from AStarStrategy import AStarStrategy + + +def run_benchmarks(): + files = ["maze_small.txt", "maze_empty.txt", + "maze_no_exit.txt", "maze_medium.txt", "maze_large.txt"] + strategies = { + "BFS": BFSStrategy(), + "DFS": DFSStrategy(), + "A*": AStarStrategy(), + "Deikstra": DeikstraFind() + } + + NUM_RUNS = 5 + results = [] + + print("Запуск экспериментов...") + + for file in files: + if not os.path.exists(file): + print(f"Файл {file} не найден. Пропуск.") + continue + + for name, strategy in strategies.items(): + total_time = 0.0 + visited_counts = [] + path_lengths = [] + + for _ in range(NUM_RUNS): + # Пересоздаем лабиринт + builder = TextFileMazeBuilder() + builder.buildFromFile(file) + maze = builder.maze + + solver = MazeSolver(maze, strategy) + stats = solver.solve() + + total_time += stats.execution_time + visited_counts.append(stats.visited_count) + path_lengths.append(stats.path_length) + + # средние значения + avg_time = total_time / NUM_RUNS + avg_visited = int(np.mean(visited_counts)) + avg_path = int(np.mean(path_lengths)) + + results.append({ + "лабиринт": file, + "стратегия": name, + "время_мс": round(avg_time, 4), + "посещено_клеток": avg_visited, + "длина_пути": avg_path + }) + + # Запись в CSV + csv_file = "maze_benchmark_results.csv" + with open(csv_file, mode="w", encoding="utf-8", newline="") as f: + writer = csv.DictWriter(f, fieldnames=[ + "лабиринт", "стратегия", "время_мс", "посещено_клеток", "длина_пути"]) + writer.writeheader() + writer.writerows(results) + + print(f"Результаты успешно сохранены в {csv_file}") + return results + +# Построение графиков + + +def plot_results(results): + print("Генерация графиков...") + mazes = sorted(list(set(r["лабиринт"] for r in results))) + strategies = ["BFS", "DFS", "A*"] + + # График Количество посещенных клеток + fig, ax = plt.subplots(figsize=(10, 6)) + x = np.arange(len(mazes)) + width = 0.25 + + for i, strat in enumerate(strategies): + visited = [next(r["посещено_клеток"] for r in results if r["лабиринт"] + == m and r["стратегия"] == strat) for m in mazes] + ax.bar(x + i*width, visited, width, label=strat) + + ax.set_ylabel('Количество посещенных клеток') + ax.set_title('Сравнение эффективности обхода лабиринтов (меньше = лучше)') + ax.set_xticks(x + width) + ax.set_xticklabels(mazes, rotation=15) + ax.legend() + plt.tight_layout() + plt.savefig("benchmark_visited_cells.png", dpi=300) + plt.close() + + # График Время выполнения + fig, ax = plt.subplots(figsize=(10, 6)) + for i, strat in enumerate(strategies): + times = [next(r["время_мс"] for r in results if r["лабиринт"] + == m and r["стратегия"] == strat) for m in mazes] + ax.bar(x + i*width, times, width, label=strat) + + ax.set_ylabel('Время выполнения (мс)') + ax.set_title('Сравнение времени работы алгоритмов') + ax.set_xticks(x + width) + ax.set_xticklabels(mazes, rotation=15) + ax.legend() + plt.tight_layout() + plt.savefig("benchmark_execution_time.png", dpi=300) + plt.close() + print("Графики сохранены в текущую директорию.") + + +if __name__ == "__main__": + data = run_benchmarks() + plot_results(data)