2026-rff_mp/zhigalovrd/lab2/main.py

136 lines
4.2 KiB
Python
Raw Normal View History

# main.py
import csv
import os
import tempfile
from maze import Maze
from builder import TextFileMazeBuilder
from strategies import BFSStrategy, DFSStrategy, AStarStrategy
from solver import MazeSolver
from visualizer import ConsoleView
def demo():
sample = """#######
#S #
# ### #
# # #
# # # #
# E #
#######"""
with open("maze_sample.txt", "w") as f:
f.write(sample)
builder = TextFileMazeBuilder()
maze = builder.build_from_file("maze_sample.txt")
print("Загруженный лабиринт:")
ConsoleView.render(maze)
strategies = {
"BFS": BFSStrategy(),
"DFS": DFSStrategy(),
"A*": AStarStrategy()
}
for name, strat in strategies.items():
solver = MazeSolver(maze, strat)
stats = solver.solve()
print(f"\n{name}: время = {stats.time_ms:.3f} мс, посещено = {stats.visited_cells}, длина пути = {stats.path_length}")
ConsoleView.render(maze, stats.path)
def run_experiments():
builder = TextFileMazeBuilder()
def make_maze_from_str(s):
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.txt') as f:
f.write(s)
name = f.name
maze = builder.build_from_file(name)
os.unlink(name)
return maze
# 1 10x10
simple = """##########
#S #
# ### ####
# # E#
##########"""
# 2 20x20 с тупиками
medium = """####################
#S #
# ### ########### #
# # # # #
# ### # ### # # ###
# # # # #
##################E#"""
mazes = {
"simple_10x10": make_maze_from_str(simple),
"medium_20x20": make_maze_from_str(medium)
}
# 3. 50x50
empty_lines = []
for y in range(50):
row = []
for x in range(50):
if x == 0 and y == 0:
row.append('S')
elif x == 49 and y == 49:
row.append('E')
else:
row.append(' ')
empty_lines.append(''.join(row))
empty_str = '\n'.join(empty_lines)
mazes["empty_50x50"] = make_maze_from_str(empty_str)
# 4. Лабиринт без выхода (заменяем 'E' на '#', чтобы выхода не было)
no_exit_str = empty_str.replace('E', '#')
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.txt') as f:
f.write(no_exit_str)
name = f.name
# Строим лабиринт без проверки на наличие выхода
maze_no_exit = builder.build_from_file(name, require_exit=False)
os.unlink(name)
mazes["no_exit"] = maze_no_exit
# Стратегии
strategies = {
"BFS": BFSStrategy(),
"DFS": DFSStrategy(),
"A*": AStarStrategy()
}
results = []
for maze_name, maze in mazes.items():
for strat_name, strat in strategies.items():
times = []
visiteds = []
lengths = []
for _ in range(5): # 5 запусков для усреднения
solver = MazeSolver(maze, strat)
stats = solver.solve()
times.append(stats.time_ms)
visiteds.append(stats.visited_cells)
lengths.append(stats.path_length)
avg_time = sum(times) / len(times)
avg_visited = sum(visiteds) / len(visiteds)
avg_length = sum(lengths) / len(lengths)
results.append({
"maze": maze_name,
"strategy": strat_name,
"avg_time_ms": avg_time,
"avg_visited": avg_visited,
"avg_path_length": avg_length
})
print(f"{maze_name},{strat_name}: time={avg_time:.2f}ms visited={avg_visited:.0f} length={avg_length:.0f}")
with open("experiment_results.csv", "w", newline='', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=["maze", "strategy", "avg_time_ms", "avg_visited", "avg_path_length"])
writer.writeheader()
writer.writerows(results)
print("\nРезультаты сохранены в experiment_results.csv")
if __name__ == "__main__":
demo()
print("\n=== ЗАПУСК ЭКСПЕРИМЕНТОВ ===")
run_experiments()