[2]Реализация остальной части кода (без этапа 5)

This commit is contained in:
Artem 2026-05-21 19:05:20 +03:00
parent 1923a02552
commit 7ea5690be9
2 changed files with 213 additions and 0 deletions

View File

@ -0,0 +1,21 @@
labyrint,strategy,time_ms,passed_cells,path_length
Small (10x10),BFS,0.1973,59,27
Small (10x10),DFS,0.1615,49,27
Small (10x10),AStar,0.2375,50,27
Small (10x10),Dijkstra,0.2487,60,27
Empty (50x50),BFS,8.3316,2500,99
Empty (50x50),DFS,4.6278,1275,1275
Empty (50x50),AStar,17.5549,2500,99
Empty (50x50),Dijkstra,14.7128,2500,99
Middle with dead ends (50x50),BFS,4.8741,1420,1083
Middle with dead ends (50x50),DFS,4.3282,1275,1275
Middle with dead ends (50x50),AStar,7.1452,1404,1083
Middle with dead ends (50x50),Dijkstra,6.0643,1420,1083
Big (100x100),BFS,17.0733,5590,199
Big (100x100),DFS,15.1471,4933,4519
Big (100x100),AStar,31.4644,5140,199
Big (100x100),Dijkstra,26.7258,5590,199
Without exit (10x10),BFS,0.0140,5,0
Without exit (10x10),DFS,0.0124,5,0
Without exit (10x10),AStar,0.0164,5,0
Without exit (10x10),Dijkstra,0.0143,5,0
1 labyrint strategy time_ms passed_cells path_length
2 Small (10x10) BFS 0.1973 59 27
3 Small (10x10) DFS 0.1615 49 27
4 Small (10x10) AStar 0.2375 50 27
5 Small (10x10) Dijkstra 0.2487 60 27
6 Empty (50x50) BFS 8.3316 2500 99
7 Empty (50x50) DFS 4.6278 1275 1275
8 Empty (50x50) AStar 17.5549 2500 99
9 Empty (50x50) Dijkstra 14.7128 2500 99
10 Middle with dead ends (50x50) BFS 4.8741 1420 1083
11 Middle with dead ends (50x50) DFS 4.3282 1275 1275
12 Middle with dead ends (50x50) AStar 7.1452 1404 1083
13 Middle with dead ends (50x50) Dijkstra 6.0643 1420 1083
14 Big (100x100) BFS 17.0733 5590 199
15 Big (100x100) DFS 15.1471 4933 4519
16 Big (100x100) AStar 31.4644 5140 199
17 Big (100x100) Dijkstra 26.7258 5590 199
18 Without exit (10x10) BFS 0.0140 5 0
19 Without exit (10x10) DFS 0.0124 5 0
20 Without exit (10x10) AStar 0.0164 5 0
21 Without exit (10x10) Dijkstra 0.0143 5 0

View File

@ -0,0 +1,192 @@
class SearchStats:
def __init__(self, timeMs: float, visitedCells: int, pathLength: int):
self.timeMs = timeMs
self.visitedCells = visitedCells
self.pathLength = pathLength
class MazeSolver:
def __init__(self, maze: Maze, strategy: PathFindingStrategy):
self.maze = maze
self.strategy = strategy
self.observers = []
def setStrategy(self, strategy: PathFindingStrategy):
self.strategy = strategy
def addObserver(self, observer):
self.observers.append(observer)
def _notify(self, event: str):
for obs in self.observers:
obs.update(event)
def solve(self) -> tuple:
self._notify("Поиск начат")
start_time = time.perf_counter()
path = self.strategy.findPath(self.maze, self.maze.start, self.maze.exit)
end_time = time.perf_counter()
time_ms = (end_time - start_time) * 1000
stats = SearchStats(time_ms, self.strategy.visited_count, len(path))
self._notify("Поиск завершен")
return path, stats
class Observer(ABC):
@abstractmethod
def update(self, event: str):
pass
class ConsoleView(Observer):
def update(self, event: str):
pass
def render(self, maze: Maze, path: list):
path_set = set(path)
for y in range(maze.height):
row = ""
for x in range(maze.width):
cell = maze.getCell(x, y)
if cell == maze.start:
row += "S"
elif cell == maze.exit:
row += "E"
elif cell in path_set:
row += "*"
elif cell.isWall:
row += "#"
elif cell.weight == 3:
row += "W" # Болото
elif cell.weight == 2:
row += "D" # Песок
else:
row += "."
print(row)
def get_test_mazes():
builder = TextMazeBuilder()
mazes = {}
small = [
"S.........",
"#####.####",
"..........",
"####.#####",
"..........",
"#.#######.",
"..........",
"######.###",
"..........",
"........XE"
]
small[-1] = small[-1].replace('X', '.')
mazes["Small (10x10)"] = builder.buildFromStringList(small)
empty = ["." * 50 for _ in range(50)]
empty_list = list(empty)
empty_list[0] = "S" + empty_list[0][1:]
empty_list[-1] = empty_list[-1][:-1] + "E"
mazes["Empty (50x50)"] = builder.buildFromStringList(empty_list)
medium = []
for y in range(50):
if y == 0:
row = "S" + "." * 49
elif y == 49:
row = "." * 49 + "E"
elif y % 2 == 1:
row = "#" * 45 + "." * 5 if y % 4 == 1 else "." * 5 + "#" * 45
else:
row = "." * 50
medium.append(row)
mazes["Middle with dead ends (50x50)"] = builder.buildFromStringList(medium)
large = []
for y in range(100):
if y == 0: row = "S" + "." * 99
elif y == 99: row = "." * 99 + "E"
elif y % 2 == 1:
row = ("#" * 9 + ".") * 10
else:
row = "." * 100
large.append(row)
mazes["Big (100x100)"] = builder.buildFromStringList(large)
no_exit = [
"S....#....",
"##########",
"##########",
"##########",
"##########",
"##########",
"##########",
"##########",
"##########",
"######...E"
]
mazes["Without exit (10x10)"] = builder.buildFromStringList(no_exit)
return mazes
def main():
mazes = get_test_mazes()
strategies = {
"BFS": BFSStrategy(),
"DFS": DFSStrategy(),
"AStar": AStarStrategy(),
"Dijkstra": DijkstraStrategy()
}
output_rows = []
print("Запуск всех тестов...")
print("-" * 70)
for maze_name, maze in mazes.items():
print(f"Testing: {maze_name}")
for strat_name, strategy in strategies.items():
solver = MazeSolver(maze, strategy)
runs = 5
total_time = 0
path = []
stats = None
for _ in range(runs):
path, stats = solver.solve()
total_time += stats.timeMs
avg_time = total_time / runs
output_rows.append([
maze_name,
strat_name,
f"{avg_time:.4f}",
stats.visitedCells,
stats.pathLength
])
print(
f" -> {strat_name}: Time: {avg_time:.3f}ms | Passed cells: {stats.visitedCells} | Path length: {stats.pathLength}")
print("-" * 70)
with open("results_all.csv", "w", newline="", encoding="utf-8") as csvfile:
writer = csv.writer(csvfile)
writer.writerow(["labyrint", "strategy", "time_ms", "passed_cells", "path_length"])
writer.writerows(output_rows)
print("Все замеры успешно выполнены! Результаты сохранены в 'results_all.csv'")
if __name__ == "__main__":
main()