diff --git a/konnovaea/laba2/docs/data/maze_experiments.csv b/konnovaea/laba2/docs/data/maze_experiments.csv new file mode 100644 index 0000000..261d6fa --- /dev/null +++ b/konnovaea/laba2/docs/data/maze_experiments.csv @@ -0,0 +1,13 @@ +Лабиринт,Стратегия,Время(мс),Посещено клеток,Длина пути +Простой (10x10),BFS,0.001,-,- +Простой (10x10),DFS,0.001,-,- +Простой (10x10),A*,0.001,-,- +С тупиками (50x50),BFS,2.732,1818.0,95.0 +С тупиками (50x50),DFS,1.338,841.0,289.0 +С тупиками (50x50),A*,2.907,1159.0,95.0 +Пустой (100x100),BFS,16.894,9604.0,195.0 +Пустой (100x100),DFS,296.432,9604.0,4851.0 +Пустой (100x100),A*,28.451,9604.0,195.0 +Без выхода,BFS,0.0,-,- +Без выхода,DFS,0.0,-,- +Без выхода,A*,0.0,-,- diff --git a/konnovaea/laba2/docs/lab2_report.md b/konnovaea/laba2/docs/lab2_report.md new file mode 100644 index 0000000..e69de29 diff --git a/konnovaea/laba2/maze_deadends.txt b/konnovaea/laba2/maze_deadends.txt new file mode 100644 index 0000000..9beda74 --- /dev/null +++ b/konnovaea/laba2/maze_deadends.txt @@ -0,0 +1,50 @@ +################################################## +#S # # # ## # # # # # # # # +# # # ## # ## # # ## ## # ## +# # # # # # # ## ### # # # +# # ### # ## # # # ## +# # ## ## # # # # +## # # ### # # ## # ### +# # ## # # # # # ## # # +# # # # # # # # # +# # # # # # # +## ## # # # # # # # # # +# ## # # # ## # ## +# ## # # ### ## # +## # # # ## # # # # # # +# # # # # # # # # # # +# # # # # # # ## # +# ## # ## # # # # # # # +# # # # # # #### # ## +# # # ## # # # # # # ### +# # # ## # # # # # # # # +# # # ## ## # # # ## # # +## ## # # ## # # # # # # # ## # +# # # # # ## # +# # # # # # # # +## # # # # # +# # # # # # # # ## ## # # +## ### # # # ## # # ## +# #### # # # # # # # # +# # ## # # # # # # # +# ## # # # # # # # +# # ## # # # # # ## # ## ## # +### # ### # # ## # # # # +# ## ### ## ## # # # +# ## # ## # ## # ## +### # # # # # # # ## # # +# # # # # # # # ## # # # +# # # # # # # # +# # ## # # +# ## # # # ### +# # # # # # # # # ## # ## +# ## # # ## # +# # # # # # # # # # # +# # # # # # # # # # +# # # ## # ## # ## # ## +# # ## ## # # # # # +## ## # # # # # ## # # # +### # # # # # # # +## # # # ## ## # # # # +# # # # # ## E# +################################################## diff --git a/konnovaea/laba2/maze_empty.txt b/konnovaea/laba2/maze_empty.txt new file mode 100644 index 0000000..532b296 --- /dev/null +++ b/konnovaea/laba2/maze_empty.txt @@ -0,0 +1,100 @@ +#################################################################################################### +#S # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# E# +#################################################################################################### diff --git a/konnovaea/laba2/maze_experiments.py b/konnovaea/laba2/maze_experiments.py new file mode 100644 index 0000000..b193a98 --- /dev/null +++ b/konnovaea/laba2/maze_experiments.py @@ -0,0 +1,257 @@ +import time +import random +import csv +import os +from laba2.maze_solver import ( + TextFileMazeBuilder, BFSStrategy, DFSStrategy, AStarStrategy, MazeSolver +) + +def save_maze_to_file(maze, filename): + + with open(filename, 'w', encoding='utf-8') as f: + for row in maze: + f.write(''.join(row) + '\n') + return filename + + +def create_simple_maze(): + + width, height = 10, 10 + maze = [] + for y in range(height): + row = [] + for x in range(width): + if x == 0 or y == 0 or x == width-1 or y == height-1: + row.append('#') + else: + row.append(' ') + maze.append(row) + + maze[1][1] = 'S' + maze[8][8] = 'E' + + + for i in range(1, 9): + maze[1][i] = ' ' + maze[8][i] = ' ' + maze[i][1] = ' ' + maze[i][8] = ' ' + + return save_maze_to_file(maze, "maze_simple.txt") + + +def create_maze_with_dead_ends(): + + width, height = 50, 50 + maze = [] + for y in range(height): + row = [] + for x in range(width): + if x == 0 or y == 0 or x == width-1 or y == height-1: + row.append('#') + else: + + if random.random() < 0.2: + row.append('#') + else: + row.append(' ') + maze.append(row) + + + maze[1][1] = 'S' + maze[height-2][width-2] = 'E' + + + maze[1][1] = 'S' + maze[height-2][width-2] = 'E' + maze[2][1] = ' ' + maze[1][2] = ' ' + maze[height-3][width-2] = ' ' + maze[height-2][width-3] = ' ' + + return save_maze_to_file(maze, "maze_deadends.txt") + + +def create_empty_maze(): + + width, height = 100, 100 + maze = [] + for y in range(height): + row = [] + for x in range(width): + if x == 0 or y == 0 or x == width-1 or y == height-1: + row.append('#') + else: + row.append(' ') + maze.append(row) + + maze[1][1] = 'S' + maze[height-2][width-2] = 'E' + + return save_maze_to_file(maze, "maze_empty.txt") + + +def create_maze_no_exit(): + + width, height = 20, 20 + maze = [] + for y in range(height): + row = [] + for x in range(width): + if x == 0 or y == 0 or x == width-1 or y == height-1: + row.append('#') + else: + + if x == 1 and y == 1: + row.append('S') + else: + row.append('#') + maze.append(row) + + return save_maze_to_file(maze, "maze_no_exit.txt") + + + +def run_experiment(maze_file, strategy, iterations=5): + + builder = TextFileMazeBuilder() + + try: + maze = builder.build_from_file(maze_file) + except Exception as e: + print(f" Ошибка загрузки {maze_file}: {e}") + return None + + solver = MazeSolver(maze, strategy) + + times = [] + visited_counts = [] + path_lengths = [] + + for i in range(iterations): + try: + stats = solver.solve() + times.append(stats.time_ms) + visited_counts.append(stats.visited_count) + path_lengths.append(stats.path_length) + except Exception as e: + print(f" Ошибка при итерации {i+1}: {e}") + continue + + if not times: + return None + + return { + 'avg_time': sum(times) / len(times), + 'avg_visited': sum(visited_counts) / len(visited_counts), + 'avg_path_length': sum(path_lengths) / len(path_lengths), + 'all_times': times, + 'all_visited': visited_counts, + 'all_paths': path_lengths + } + + +def run_all_experiments(): + + + + mazes = { + "Простой (10x10)": create_simple_maze(), + "С тупиками (50x50)": create_maze_with_dead_ends(), + "Пустой (100x100)": create_empty_maze(), + "Без выхода": create_maze_no_exit() + } + + strategies = { + "BFS": BFSStrategy(), + "DFS": DFSStrategy(), + "A*": AStarStrategy() + } + + results = [] + + for maze_name, maze_file in mazes.items(): + print(f"\nТестирование лабиринта: {maze_name}") + + + for strat_name, strategy in strategies.items(): + print(f" Стратегия: {strat_name}") + + result = run_experiment(maze_file, strategy, iterations=5) + + if result: + print(f" Среднее время: {result['avg_time']:.3f} мс") + print(f" Среднее посещено: {result['avg_visited']:.0f}") + print(f" Средняя длина пути: {result['avg_path_length']:.0f}") + + results.append({ + 'лабиринт': maze_name, + 'стратегия': strat_name, + 'время_мс': result['avg_time'], + 'посещено_клеток': result['avg_visited'], + 'длина_пути': result['avg_path_length'] + }) + else: + print(f" Ошибка: не удалось выполнить замеры") + results.append({ + 'лабиринт': maze_name, + 'стратегия': strat_name, + 'время_мс': -1, + 'посещено_клеток': -1, + 'длина_пути': -1 + }) + + return results + + + + +def save_results_to_csv(results): + + os.makedirs("laba2/docs/data", exist_ok=True) + + with open("laba2/docs/data/maze_experiments.csv", "w", newline="", encoding="utf-8") as f: + writer = csv.writer(f) + writer.writerow(["Лабиринт", "Стратегия", "Время(мс)", "Посещено клеток", "Длина пути"]) + + for res in results: + writer.writerow([ + res['лабиринт'], + res['стратегия'], + round(res['время_мс'], 3) if res['время_мс'] > 0 else "нет пути", + round(res['посещено_клеток'], 0) if res['посещено_клеток'] > 0 else "-", + round(res['длина_пути'], 0) if res['длина_пути'] > 0 else "-" + ]) + + + + +def print_summary(results): + + + print("Сводная таблица результатов") + + print(f"{'Лабиринт':<20} {'Стратегия':<10} {'Время(мс)':<12} {'Посещено':<12} {'Длина пути':<12}") + + + for res in results: + time_str = f"{res['время_мс']:.3f}" if res['время_мс'] > 0 else "нет пути" + visited_str = f"{res['посещено_клеток']:.0f}" if res['посещено_клеток'] > 0 else "-" + path_str = f"{res['длина_пути']:.0f}" if res['длина_пути'] > 0 else "-" + + print(f"{res['лабиринт']:<20} {res['стратегия']:<10} {time_str:<12} {visited_str:<12} {path_str:<12}") + + + + + +if __name__ == "__main__": + + print("Эксперименты по сравнению алгоритмов поиска") + + + results = run_all_experiments() + save_results_to_csv(results) + print_summary(results) + + \ No newline at end of file diff --git a/konnovaea/laba2/maze_no_exit.txt b/konnovaea/laba2/maze_no_exit.txt new file mode 100644 index 0000000..9e8e6ef --- /dev/null +++ b/konnovaea/laba2/maze_no_exit.txt @@ -0,0 +1,20 @@ +#################### +#S################## +#################### +#################### +#################### +#################### +#################### +#################### +#################### +#################### +#################### +#################### +#################### +#################### +#################### +#################### +#################### +#################### +#################### +#################### diff --git a/konnovaea/laba2/maze_simple.txt b/konnovaea/laba2/maze_simple.txt new file mode 100644 index 0000000..422ae66 --- /dev/null +++ b/konnovaea/laba2/maze_simple.txt @@ -0,0 +1,10 @@ +########## +# # +# # +# # +# # +# # +# # +# # +# # +########## diff --git a/konnovaea/maze_solver.py b/konnovaea/laba2/maze_solver.py similarity index 100% rename from konnovaea/maze_solver.py rename to konnovaea/laba2/maze_solver.py diff --git a/konnovaea/maze1.txt b/konnovaea/maze1.txt deleted file mode 100644 index 2eacde7..0000000 --- a/konnovaea/maze1.txt +++ /dev/null @@ -1,5 +0,0 @@ -####### -#S # -# ### # -# E # -####### \ No newline at end of file diff --git a/konnovaea/test.py b/konnovaea/test.py deleted file mode 100644 index fd36b2b..0000000 --- a/konnovaea/test.py +++ /dev/null @@ -1 +0,0 @@ -print("Hello from Python") \ No newline at end of file