-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathrunner.py
104 lines (85 loc) · 2.79 KB
/
runner.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
from collections import namedtuple
from functools import partial
from timeit import default_timer as timer
import matplotlib.animation as ani
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from algos import bfs, dfs, astar, manhattan_heuristic
from maze import create_maze
from plotting import Plotter
import tabulate
import tqdm
import os
np.random.seed(0)
SIZE = 100
START = (0, 0)
GOAL = (SIZE - 1, SIZE - 1)
OBSTACLE_COUNT = SIZE ** 2 // 30
OBSTACLE_SIZE = 7
ALGOS = [
("DFS", partial(dfs, start=START, goal=GOAL)),
("BFS", partial(bfs, start=START, goal=GOAL)),
(
"A-star",
partial(astar, start=START, goal=GOAL, heuristic=manhattan_heuristic(SIZE)),
),
]
Result = namedtuple(
"Result", ["round", "finished", "n_explored", "length_path", "seconds", "algo"]
)
def simulate(n, max_good_mazes=float("inf")):
results = []
good_mazes = []
for i in tqdm.tqdm(range(n), mininterval=1):
maze = create_maze(SIZE, OBSTACLE_COUNT, OBSTACLE_SIZE)
for algo_name, algo in ALGOS:
time_start = timer()
finished, explored_nodes, path = algo(maze)
time_end = timer()
r = Result(
round=i,
finished=finished,
n_explored=len(explored_nodes),
length_path=None if not finished else len(path),
seconds=time_end - time_start,
algo=algo_name,
)
results.append(r)
if finished and algo_name == ALGOS[0][0]:
good_mazes.append(maze)
if len(good_mazes) >= max_good_mazes:
break
results_df = pd.DataFrame(results)
return results_df, good_mazes
def create_animation(title, algo, maze):
finished, explored, path = algo(maze)
assert finished, "goal not reachable"
plotter = Plotter(
maze, explored, path, frame_skip_path=8, frame_skip_search=32, end_frames=30
)
plotter.init_fig(title)
anim = ani.FuncAnimation(
plotter.fig,
plotter.anim_fn,
init_func=plotter.init_fn,
frames=plotter.total_frames,
interval=1,
repeat=True,
)
return anim
result_df, good_mazes = simulate(1000)
result_agg = result_df.groupby(["finished", "algo"])[
"seconds", "n_explored", "length_path"
].mean()
result_agg["count"] = result_df.groupby(["finished", "algo"]).size()
result_agg = result_agg.reset_index()
print(tabulate.tabulate(result_agg.values, result_agg.columns, tablefmt="pipe"))
output_path = "_files/anim3"
os.makedirs(output_path, exist_ok=True)
for algo_name, algo in ALGOS:
anim = create_animation(algo_name, algo, good_mazes[0])
anim.save(
f"{output_path}/{algo_name.replace('*', '-star')}.gif", writer="imagemagick"
)
plt.close()