diff --git a/BoriskovaDV/docs/data/2-nd-exercise/main.py b/BoriskovaDV/docs/data/2-nd-exercise/main.py index f3cabfdd..2baa9c25 100644 --- a/BoriskovaDV/docs/data/2-nd-exercise/main.py +++ b/BoriskovaDV/docs/data/2-nd-exercise/main.py @@ -3,6 +3,9 @@ import os from collections import deque import heapq import time +import csv +import matplotlib.pyplot as plt +import numpy as np class GridPoint: def __init__(self, x, y): @@ -289,7 +292,101 @@ def run_experiment(maze_file, algo, runs=5): total_len += plen return total_ms / runs, total_visited / runs, total_len / runs +def generate_plots(results): + mazes = list(set([r['maze'] for r in results])) + strategies = ['BFS', 'DFS', 'AStar'] + + fig, axes = plt.subplots(1, 3, figsize=(15, 5)) + x = np.arange(len(mazes)) + width = 0.25 + + for i, strat in enumerate(strategies): + times = [] + for maze in mazes: + val = next((r['time_ms'] for r in results if r['maze'] == maze and r['strategy'] == strat), 0) + times.append(val) + axes[0].bar(x + i*width, times, width, label=strat) + axes[0].set_xlabel('Maze') + axes[0].set_ylabel('Time (ms)') + axes[0].set_title('Execution Time') + axes[0].set_xticks(x + width) + axes[0].set_xticklabels(mazes, rotation=45, ha='right') + axes[0].legend() + axes[0].grid(True, alpha=0.3) + + for i, strat in enumerate(strategies): + visited = [] + for maze in mazes: + val = next((r['visited_cells'] for r in results if r['maze'] == maze and r['strategy'] == strat), 0) + visited.append(val) + axes[1].bar(x + i*width, visited, width, label=strat) + axes[1].set_xlabel('Maze') + axes[1].set_ylabel('Visited Cells') + axes[1].set_title('Visited Cells') + axes[1].set_xticks(x + width) + axes[1].set_xticklabels(mazes, rotation=45, ha='right') + axes[1].legend() + axes[1].grid(True, alpha=0.3) + + for i, strat in enumerate(strategies): + lengths = [] + for maze in mazes: + val = next((r['path_length'] for r in results if r['maze'] == maze and r['strategy'] == strat), 0) + lengths.append(val) + axes[2].bar(x + i*width, lengths, width, label=strat) + axes[2].set_xlabel('Maze') + axes[2].set_ylabel('Path Length') + axes[2].set_title('Path Length') + axes[2].set_xticks(x + width) + axes[2].set_xticklabels(mazes, rotation=45, ha='right') + axes[2].legend() + axes[2].grid(True, alpha=0.3) + + plt.tight_layout() + plt.savefig('performance_comparison.png', dpi=150, bbox_inches='tight') + plt.show() + if __name__ == "__main__": + if len(sys.argv) > 1 and sys.argv[1] == 'experiment': + print("Running experiments on all mazes...") + maze_files = [ + ("maze/maze1.txt", "Small 10x6"), + ("maze/maze10x10.txt", "Medium 10x10"), + ("maze/maze20x20.txt", "Large 20x20"), + ("maze/maze_empty.txt", "Empty 15x15"), + ("maze/maze_no_exit.txt", "No exit 10x10") + ] + algorithms = [ + ("BFS", BreadthFirst()), + ("DFS", DepthFirst()), + ("AStar", AStar()) + ] + results = [] + for fname, label in maze_files: + print(f"Testing {label}...") + for aname, algo in algorithms: + try: + avg_t, avg_v, avg_l = run_experiment(fname, algo, runs=3) + results.append({ + 'maze': label, + 'strategy': aname, + 'time_ms': avg_t, + 'visited_cells': avg_v, + 'path_length': avg_l + }) + print(f" {aname}: time={avg_t:.3f}ms visited={avg_v:.0f} length={avg_l:.0f}") + except Exception as e: + print(f" {aname}: ERROR {e}") + # save csv + with open('experiment_results.csv', 'w', newline='', encoding='utf-8') as f: + writer = csv.DictWriter(f, fieldnames=['maze', 'strategy', 'time_ms', 'visited_cells', 'path_length']) + writer.writeheader() + writer.writerows(results) + generate_plots(results) + print("Done. Results saved to experiment_results.csv and performance_comparison.png") + sys.exit(0) + + # else interactive mode loader = TextMazeLoader() lab = loader.load("maze/maze1.txt") player = Player(lab.start_point, lab)