From 9849075a381ac519cb11acd5517f8cb47283c61d Mon Sep 17 00:00:00 2001 From: oSTEVEo Date: Sun, 24 May 2026 19:12:04 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=20=D0=BA=D0=BB=D0=B0=D1=81=D1=81-=D0=BE?= =?UTF-8?q?=D1=80=D0=BA=D0=B5=D1=81=D1=82=D1=80=D0=B0=D1=82=D0=BE=D1=80=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D1=82=D0=B5=D1=81=D1=82=D0=B8=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MusinAA/docs/data/mazeRezults.csv | 13 +++ MusinAA/main.py | 20 ---- MusinAA/task2/.gitignore | 1 + MusinAA/task2/mazeExamples/maze_100x100.txt | 100 ++++++++++++++++++++ MusinAA/task2/mazeExamples/maze_10x10.txt | 10 ++ MusinAA/task2/mazeExamples/maze_50x50.txt | 50 ++++++++++ MusinAA/task2/mazeSolver.py | 12 ++- MusinAA/task2/tester.py | 83 ++++++++++++++++ 8 files changed, 268 insertions(+), 21 deletions(-) create mode 100644 MusinAA/docs/data/mazeRezults.csv delete mode 100644 MusinAA/main.py create mode 100644 MusinAA/task2/.gitignore create mode 100644 MusinAA/task2/mazeExamples/maze_100x100.txt create mode 100644 MusinAA/task2/mazeExamples/maze_10x10.txt create mode 100644 MusinAA/task2/mazeExamples/maze_50x50.txt create mode 100644 MusinAA/task2/tester.py diff --git a/MusinAA/docs/data/mazeRezults.csv b/MusinAA/docs/data/mazeRezults.csv new file mode 100644 index 0000000..ad636c7 --- /dev/null +++ b/MusinAA/docs/data/mazeRezults.csv @@ -0,0 +1,13 @@ +Алгоритм,Лабиринт,Время (мс),Посещённые клетки,Длинна пути +BFS,50x50,3.2134529003087664,720,431 +BFS,10x10,0.2288821000547614,53,23 +BFS,5x5,0.035640300302475225,8,7 +BFS,100x100,11.366462300065905,2495,1171 +DFS,50x50,1.7320569000730757,747,431 +DFS,10x10,0.0645840002107434,35,31 +DFS,5x5,0.015984299898264,8,7 +DFS,100x100,8.414763500331901,3219,1243 +AStar,50x50,1.8410825001410558,509,455 +AStar,10x10,0.1062644998455653,23,23 +AStar,5x5,0.03181890006089816,8,7 +AStar,100x100,6.592893099877983,1286,1171 diff --git a/MusinAA/main.py b/MusinAA/main.py deleted file mode 100644 index 752e187..0000000 --- a/MusinAA/main.py +++ /dev/null @@ -1,20 +0,0 @@ -from task2.consoleView import ConsoleView -from task2.mazeBuilder import TextFileMazeBuilder -from task2.mazeSolver import MazeSolver - -from task2.strategyObjects.BFS import BFS -from task2.strategyObjects.DFS import DFS -from task2.strategyObjects.AStar import AStar - -console = ConsoleView() -builder = TextFileMazeBuilder() -solver = MazeSolver(BFS()) -solver.attach(console) - -maze = builder.buildFromFile("task2/mazeExamples/low.txt") -console.maze = maze # хмммм -solver.setMaze(maze) - -input() - -solver.solve() diff --git a/MusinAA/task2/.gitignore b/MusinAA/task2/.gitignore new file mode 100644 index 0000000..a548902 --- /dev/null +++ b/MusinAA/task2/.gitignore @@ -0,0 +1 @@ +maze_generator.py \ No newline at end of file diff --git a/MusinAA/task2/mazeExamples/maze_100x100.txt b/MusinAA/task2/mazeExamples/maze_100x100.txt new file mode 100644 index 0000000..cadb849 --- /dev/null +++ b/MusinAA/task2/mazeExamples/maze_100x100.txt @@ -0,0 +1,100 @@ +S # # # # # # # # # # # # # # + # # ####### ### # ##### # # # # # # # # ### # # ### # # ### # ##### # ##### ### ### ### ######### # + # # # # # # # # # # # # # # # # # # # # # # # # # # + # ##### ##### ### ### ##### ##### ####### # ##### ####### # # # ####### ##### # ######### ### ### # + # # # # # # # # # # # # # # # # # # # # # # # # # + # # ##### # # ##### # # ####### # ### ##### # # # # ### ### ######### ##### # ##### # # ### ### # # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + ##### # # # ### ### ####### # # ### ######### ### ### ### ### # # # # # ### ##### # # ### # # # # # + # # # # # # # # # # # # # # # # # # # # # # # # # # + ### # ### # ##### ##### ######### ######### # ##### ### # ####### # ##### ### ####### # ### # ### # + # # # # # # # # # # # # # # # # # # # # # + # ################# # ### # # # # # ########### ############# # ##### ##### ##### # ##### ### # ### + # # # # # # # # # # # # # # # # # # # # # # + ### # ### # ### ####### # ##### ######### ### # ### ### # ####### # ### ####### ##### # ### # # # # + # # # # # # # # # # # # # # # # # # # # # # # + ######### ### ### # ### # ####### ##### # # # ####### ##### ####### # ########### ####### ######### + # # # # # # # # # # # # # # # # # # # # # +## # ####### ### ##### # ####### ### # # # # ##### ### ########### # # # ### # ##### # # ### ##### # + # # # # # # # # # # # # # # # # # # # # # # # # # + ### # # ########### ######### # ### # # ### ### ####### ### # # # # ##### # ### ##### # # ### ### # + # # # # # # # # # # # # # # # # # # # # # # # # # # # +## ##### # # # # # ### # ### ##### # # # ##### # ### # ### # # # # # # # ##### ### ####### # ### ### + # # # # # # # # # # # # # # # # # # # # # # # # # # # # + ##### ### # # # # # ######### ### ### ### # ##### ##### ### # ##### # ######### ############# ### # + # # # # # # # # # # # # # # # # # # # # # # # # + # ##### # # ### ### ##### # ### ### ##### # # ### # ##### ##### ### ### # ##### ### # # ### # # ### + # # # # # # # # # # # # # # # # # # # # # # # # # # + # # # ####### ####### ### ### ######### ### # # ##### # ### ########### ### # ### ####### ### # # # + # # # # # # # # # # # # # # # # # # # # # # + ################### # # # # ### # # # ######### # # ### ############### # ### ##### ### ### ##### # + # # # # # # # # # # # # # # # # # # # # # + ##### # # ### # # ### # ####### # # ##### # # ### ##### # ####### # # # ######### # ######### ##### + # # # # # # # # # # # # # # # # # # # # # # # # # # # # +#### # # ### # # ### # ### ####### ##### # # ### # # ##### # # ####### # # # ##### ### # # ####### # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +## # # # # ### ### # ### ### # # # ### # ####### ### # ########### # ##### ##### # # ### ### ##### # + # # # # # # # # # # # # # # # # # # # # # # # # # # + ########### # # ########### ### # # # # # ### # # ### # ####### # ######### # # ### # ######### ### + # # # # # # # # # # # # # # # # # # # # # # # # +######## # # # ### # ########### # # ####### ### # # # ####### ### # # # ### # ### ######### # # # # + # # # # # # # # # # # # # # # # # # # # # # # + ##### ##### ### # # # ####### ### ### # # # # ############# # ##### # ### ##### ######### ### ### # + # # # # # # # # # # # # # # # # # # # # # # # # # + ### ### # ### # ##### # # # ### # # # ### # ### ### # # # # ########### ####### # ##### ####### ### + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +## ####### # ##### # ### ### # # # # # # # ####### ### # # # # # # # # ### # # ##### # # # # ##### # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + ### # # # ##### ####### # ### # ### ### ####### # # ### ####### ### ####### # ### ####### # # # # # + # # # # # # # # # # # # # # # # # # # # # # # # + # ##### ##### # # ### ### # ######### ### ### ### ### ####### ##### # ######### ##### # ### # ### # + # # # # # # # # # # # # # # # # # # # # # # # # # + # # ####### # ##### ### # # # # # ### ### # ### ### ######### # ####### # ####### ### ######### ### + # # # # # # # # # # # # # # # # # # # # # # # # # # # + ######### # ### ### # # # # # # ####### ##### ### # # ##### # ### # # ####### # # # ### # # # # # # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # +## # # # ### ##### # ######### # # ####### ### ### # ##### ######### # # # ####### ### # # # # ### # + # # # # # # # # # # # # # # # # # # # # # # # + ### ######### ####### # # ######### # # ### ### ### ##### ### # ########### ######### # # # ### ### + # # # # # # # # # # # # # # # # # # # # # # # # +## ######### # ### # ####### ### # ### ### # # ####### # ### ##### ### # # ### # ### ##### # # ### # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + # # ### ### ### # # # ##### # ### # ### ### # # # ####### ##### ### ### # ##### # ##### # ### # # # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + # # # ### ### # ### # ######### # ######### # ### # # # ### ##### ### # ### # # ### # ##### ##### # + # # # # # # # # # # # # # # # # # # # # # # # # # # + ##### # ### ##### ####### ### # ##### # # # ### ### # ##### # # ### # ####### ##### # # # ### # # # + # # # # # # # # # # # # # # # # # # # # # # # # # # + ### # ### ######### # ##### ### # ### # # # ############# ### ### # ##### # ### ######### # ### # # + # # # # # # # # # # # # # # # # # # # # # # # # +## # # # ### ##### # ##### # ### ### # # # ### # # ######### # # ##### ### ####### ### # ######### # + # # # # # # # # # # # # # # # # # # # # # # # # # # # + # ############### ### ####### ### # ### ####### # # # # ######### # ### # # # ##### ##### # # ##### + # # # # # # # # # # # # # # # # # # # # # # + ##### # # ### # ### ######### # ######### # # ### # # ####### # ########### # # # ##### ####### # # + # # # # # # # # # # # # # # # # # # # # # # # +## # ####### ### # # # ############# ### ### ### ### ##### # # ### ########### ##### # ### ### # # # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # + ### ### # # # ##### ### # # ##### ####### # # ### ### # # ##### # # ####### ##### # # # # # ##### # + # # # # # # # # # # # # # # # # # # # # # # # # # # # +###### ##### ### # ### ### # # ########### # # # ##### # ### ##### # # ### ######### ### ##### # ### + # # # # # # # # # # # # # # # # # # # # # # # + # # # # # ### ####### ######### # # ######### ### # ##### ##### ##### ### # # # # # # ### ####### # + # # # # # # # # # # # # # # # # # # # # # # # # +#### # ##### # # # ##### ### # ### # ##### ### # ##### ### ######### ### ### ########### # # ##### # + # # # # # # # # # # # # # # # # # # # # # # # # # # # + ######### ##### # ####### # # # ##### # ### # # # # ####### ##### # # ### ### # # # # ### # # ### # + # # # # # # # # # # # # # # # # # # # # # # # # # # + # ### # ##### # # # ############### ### ######### ### # ##### # # ######### # ### # ### # # # # ### + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + # # # ####### # ### # ##### ##### # # ### # ### # # ##### # ### # # # ####### # ##### # # # ### # # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # + ##### # ### # # # ##### ##### # # # ### ### # # # # ######### # ########### # # ##### ####### # # # + # # # # # # # # # # # # # # # # # # # # # # # # # # # +## # # # # ##### # ### ####### ########### ### # # ####### # # ##### # # # ### ##### ##### # ##### # + # # # # # # # # # # # # # # # # # # # # # # + ### ##### ########### # ### # # ####### # # # ############# # ### ### # ### ######### # ### ### # # + # # # # # # # # # # # # # # # # # # # # # # # # # + ##### # # # ##### ####### # ### # # ##### # ### ####### ######### # ########### ### # ######### # # + # # # # # # # # # +################################################################################################## E diff --git a/MusinAA/task2/mazeExamples/maze_10x10.txt b/MusinAA/task2/mazeExamples/maze_10x10.txt new file mode 100644 index 0000000..3633a55 --- /dev/null +++ b/MusinAA/task2/mazeExamples/maze_10x10.txt @@ -0,0 +1,10 @@ +S # + ### ### # + # # # +## # # ### + # # # + ####### # + # # +## # ##### + +######## E diff --git a/MusinAA/task2/mazeExamples/maze_50x50.txt b/MusinAA/task2/mazeExamples/maze_50x50.txt new file mode 100644 index 0000000..eea2134 --- /dev/null +++ b/MusinAA/task2/mazeExamples/maze_50x50.txt @@ -0,0 +1,50 @@ +S # # # # + ####### ### # # ########### ##### # ##### ##### # + # # # # # # # # # # +## # # ### ####### ##### ####### # ### ######### # + # # # # # # # # # # # # # + ####### # # # # ### ##### # ### ### # # # # ### # + # # # # # # # # # # # # # # # # # + # ### # ### # ### ### # # ### ### ####### # # ### + # # # # # # # # # # # # # # + # # ############# # ### ### # ######### # # ### # + # # # # # # # # # + ########### ########### # ##### ### ### # # # ### + # # # # # # # # # # # # # # + # # ####### # ### # ##### ### ### ### ### # # # # + # # # # # # # # # # # # # # # # +###### ### ### # # # # # # # ### ### ##### # # # # + # # # # # # # # # # # # # # # + ### # # ######### ### # # # # ####### ##### # # # + # # # # # # # # # # # # # # + ### ### # ##### # # ######### # # # # ##### # # # + # # # # # # # # # # # # +## # ######### # # ### ### # ### ######### ##### # + # # # # # # # # # # # # + ##### # ### # ### ##### # # # ####### ##### # # # + # # # # # # # # # # # # # # # +## # ##### # # ##### ##### ### ### # ### # # # ### + # # # # # # # # # # # # # + ##### # ### # # ##### ### # ### ######### # ##### + # # # # # # # # # # # + # ####### ######### ### ####### # # ####### ### # + # # # # # # # # # # # # # # + # # ####### # # ##### # # ### ### # # # # ##### # + # # # # # # # # # # # # # # # # + # ##### # ####### # # # # # ### # ### # # # ### # + # # # # # # # # # # # # # # # + # ########### # ### ####### ### # ### # # # # # # + # # # # # # # # # # # # # + # # ####### ##### ########### ##### # # ##### # # + # # # # # # # # # # # + ### ### ### # ############### # # # ##### ### ### + # # # # # # # # # # # # # # + # ### ### # ### ##### # # # # # ##### # ### # # # + # # # # # # # # # # # # # # + # # ####### # ### ######### ######### ### # # # # + # # # # # # # # # # # # # # # + ##### # ####### # # # ### # # # # # ### ### # # # + # # # # # # # # # # # # # # # +## ### ##### ####### ### # # ### ##### # ### ### # + # # # # +################################################ E diff --git a/MusinAA/task2/mazeSolver.py b/MusinAA/task2/mazeSolver.py index 6d28cdc..6d380e3 100644 --- a/MusinAA/task2/mazeSolver.py +++ b/MusinAA/task2/mazeSolver.py @@ -8,6 +8,7 @@ from task2.strategyObjects.BFS import BFS import time class SearchStats: + maze_name:str = "None" """Время выполнения в миллисекундах, количество посещённых клеток, длина найденного пути""" def __init__(self, path: list[Cell]|None, duration:float, visited_cells:int, path_len:int, strategy_name:str): self.duration = duration @@ -15,6 +16,15 @@ class SearchStats: self.path_len = path_len self.path = path self.strategy_name = strategy_name + + def toDict(self,): + return { + "strategy_name" : self.strategy_name, + "maze_name" : self.maze_name, + "duration" : self.duration, + "visited_cells" : self.visited_cells, + "path_len" : self.path_len + } class MazeSolver(Subject): """ @@ -46,7 +56,7 @@ class MazeSolver(Subject): t_start = time.perf_counter() path = self.strategy.findPath(self._maze, self._maze.startCell, self._maze.endCell) - duration = time.perf_counter() - t_start + duration = (time.perf_counter() - t_start) * 1000 path_len = len(path.array) if path.array else 0 strategy_name = self.getStrategyName() diff --git a/MusinAA/task2/tester.py b/MusinAA/task2/tester.py new file mode 100644 index 0000000..1abf6db --- /dev/null +++ b/MusinAA/task2/tester.py @@ -0,0 +1,83 @@ +from task2.mazeBuilder import MazeBuilder +from task2.mazeObjects.maze import Maze +from task2.mazeSolver import MazeSolver, SearchStats + +from task2.strategyObjects.BFS import BFS +from task2.strategyObjects.DFS import DFS +from task2.strategyObjects.AStar import AStar + +import csv +import os + +TEST_ITERATIONS = 10 + +class Tester(): + """Для каждого лабиринта и каждой стратегии запустить solve() 5–10 раз, + усреднить время, количество посещённых клеток, длину пути. + Записать результаты в CSV: + лабиринт,стратегия,время_мс,посещено_клеток,длина_пути.""" + result:list[SearchStats] + def __init__(self, builder:MazeBuilder, writefile:str): + self.builder = builder + self.writefile = writefile + + def setTestingDirectory(self, directory:str): + if directory[-1] != "/": + directory += "/" + self._directory = directory + + def _getMazes(self) -> list[Maze]: + arr = [] + files = os.listdir(self._directory) + only_txt_files = [f for f in files if os.path.isfile(os.path.join(self._directory, f)) and os.path.splitext(f)[1] == ".txt"] + + for f in only_txt_files: + arr.append(builder.buildFromFile(os.path.join(self._directory, f))) + return arr + + def _solveAvg(self, solver: MazeSolver): + avgtime = 0 + for i in range(TEST_ITERATIONS): + result = solver.solve() + # Всё кроме времени будет одинаковым + avgtime += result.duration/TEST_ITERATIONS + result.duration = avgtime + return result + + def saveCSV(self): + rows = [] + for r in self.result: + r = r.toDict() + row = (r["strategy_name"], + r["maze_name"], + r["duration"], + r["visited_cells"], + r["path_len"] + ) + rows.append(row) + with open(self.writefile, "w", newline="") as f: + writer = csv.writer(f) + writer.writerow(["Алгоритм", "Лабиринт", "Время (мс)", "Посещённые клетки", "Длинна пути"]) + writer.writerows(rows) + + def test(self): + self.result = [] + arr = self._getMazes() + for algoritm in (BFS, DFS, AStar): + solver = MazeSolver(algoritm()) # это прикол + for maze in arr: + solver.setMaze(maze) + self.result.append(self._solveAvg(solver)) + self.result[-1].maze_name = f"{maze.height}x{maze.width}" + return self.result + + +if __name__ == "__main__": + from task2.mazeBuilder import TextFileMazeBuilder + + builder = TextFileMazeBuilder() + tester = Tester(builder, "docs/data/mazeRezults.csv") + tester.setTestingDirectory("task2/mazeExamples") + tester.test() + tester.saveCSV() + \ No newline at end of file