2026-rff_mp/konnovaea/laba2/maze_experiments.py

257 lines
7.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)