136 lines
4.2 KiB
Python
136 lines
4.2 KiB
Python
|
|
# 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()
|