Рефакторинг всего и готовый отчёт

This commit is contained in:
oSTEVEo 2026-05-25 03:00:00 +03:00
parent 9849075a38
commit 3d9390a894
19 changed files with 1087 additions and 80 deletions

903
MusinAA/docs/Report 2.ipynb Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,13 +0,0 @@
Алгоритм,Лабиринт,Время (мс),Посещённые клетки,Длинна пути
BFS,50x50,3.2134529003087664,720,431
BFS,10x10,0.2288821000547614,53,23
BFS,5x5,0.035640300302475225,8,7
BFS,100x100,11.366462300065905,2495,1171
DFS,50x50,1.7320569000730757,747,431
DFS,10x10,0.0645840002107434,35,31
DFS,5x5,0.015984299898264,8,7
DFS,100x100,8.414763500331901,3219,1243
AStar,50x50,1.8410825001410558,509,455
AStar,10x10,0.1062644998455653,23,23
AStar,5x5,0.03181890006089816,8,7
AStar,100x100,6.592893099877983,1286,1171
1 Алгоритм Лабиринт Время (мс) Посещённые клетки Длинна пути
2 BFS 50x50 3.2134529003087664 720 431
3 BFS 10x10 0.2288821000547614 53 23
4 BFS 5x5 0.035640300302475225 8 7
5 BFS 100x100 11.366462300065905 2495 1171
6 DFS 50x50 1.7320569000730757 747 431
7 DFS 10x10 0.0645840002107434 35 31
8 DFS 5x5 0.015984299898264 8 7
9 DFS 100x100 8.414763500331901 3219 1243
10 AStar 50x50 1.8410825001410558 509 455
11 AStar 10x10 0.1062644998455653 23 23
12 AStar 5x5 0.03181890006089816 8 7
13 AStar 100x100 6.592893099877983 1286 1171

View File

@ -0,0 +1,16 @@
Алгоритм,Лабиринт,Время (мс),Посещённые клетки,Длинна пути
BFS,10x10,0.4038135000882903,53,23
BFS,5x5,0.07533170064562,8,7
BFS,100x100,17.14356810080062,2495,1171
BFS,50x50,3.010086300491821,640,427
BFS,25x25,1.0405578999780118,232,173
DFS,10x10,0.07943829987198114,35,31
DFS,5x5,0.018403499416308478,8,7
DFS,100x100,8.430859900545329,3219,1243
DFS,50x50,2.0664067997131497,995,435
DFS,25x25,0.5787261994555593,316,173
AStar,10x10,0.0671462003083434,23,23
AStar,5x5,0.022370600345311686,8,7
AStar,100x100,4.951790099585196,1286,1171
AStar,50x50,2.081632300541969,496,427
AStar,25x25,0.5791453000711044,186,177
1 Алгоритм Лабиринт Время (мс) Посещённые клетки Длинна пути
2 BFS 10x10 0.4038135000882903 53 23
3 BFS 5x5 0.07533170064562 8 7
4 BFS 100x100 17.14356810080062 2495 1171
5 BFS 50x50 3.010086300491821 640 427
6 BFS 25x25 1.0405578999780118 232 173
7 DFS 10x10 0.07943829987198114 35 31
8 DFS 5x5 0.018403499416308478 8 7
9 DFS 100x100 8.430859900545329 3219 1243
10 DFS 50x50 2.0664067997131497 995 435
11 DFS 25x25 0.5787261994555593 316 173
12 AStar 10x10 0.0671462003083434 23 23
13 AStar 5x5 0.022370600345311686 8 7
14 AStar 100x100 4.951790099585196 1286 1171
15 AStar 50x50 2.081632300541969 496 427
16 AStar 25x25 0.5791453000711044 186 177

View File

@ -0,0 +1,7 @@
Алгоритм,Лабиринт,Время (мс),Посещённые клетки,Длинна пути
BFS,maze_25x25_wo_exit,1.9682294001540868,338,-1
BFS,maze_25x25_empty,4.574537699954817,625,49
DFS,maze_25x25_wo_exit,0.719102000221028,338,-1
DFS,maze_25x25_empty,0.903778699648683,625,337
AStar,maze_25x25_wo_exit,1.0117966015968705,338,-1
AStar,maze_25x25_empty,0.21763520016975235,49,49
1 Алгоритм Лабиринт Время (мс) Посещённые клетки Длинна пути
2 BFS maze_25x25_wo_exit 1.9682294001540868 338 -1
3 BFS maze_25x25_empty 4.574537699954817 625 49
4 DFS maze_25x25_wo_exit 0.719102000221028 338 -1
5 DFS maze_25x25_empty 0.903778699648683 625 337
6 AStar maze_25x25_wo_exit 1.0117966015968705 338 -1
7 AStar maze_25x25_empty 0.21763520016975235 49 49

View File

@ -1,6 +1,7 @@
from abc import ABC, abstractmethod
from itertools import product
import sys
import os.path as path
from task2.mazeObjects.maze import Maze
from task2.mazeObjects.cell import Cell
@ -18,8 +19,8 @@ class TextFileMazeBuilder(MazeBuilder):
задаёт координаты и флаги,
после чего возвращает готовый Maze."""
start = {'x': 0, 'y': 0}
end = {'x': 0, 'y': 0}
start:dict
end:dict
def _cellStrategy(self, letter: str) -> Cell:
if letter == '#':
@ -63,7 +64,9 @@ class TextFileMazeBuilder(MazeBuilder):
cell.y = y
array[y][x] = cell
except IndexError:
raise ValueError(f"Строка {x+1} имеет длину {len(rows[x])}, ожидалось {width}")
raise ValueError(f"В файле {filename}: Строка {y+1} имеет длину {len(rows[y])}, ожидалось {width}")
return Maze(array, self.start, self.end)
maze_name, _ = path.splitext(path.basename(filename))
return Maze(array, self.start, self.end, name=maze_name)

View File

@ -0,0 +1,25 @@
S # # #
# ##### # # # ####### #
# # # # # #
#### # ##### # # #######
# # # # # # #
## # # # ##### ### # # #
# # # # # # # # #
### # # # # ### # # # #
# # # # # # # #
# ### # # ### ### # ####
# # # # # # #
### # # # ####### #####
# # # #
# ################# ###
# # # #
# # # ####### ####### ##
# # # # #
### ##### # ### ### ###
# # # # # #
# # # ##### # # #######
# # # # # #
##### # ####### # ### ##
# # # # # # #
#### # # # ### ##### # #
# # # E

View File

@ -0,0 +1,50 @@
S # # # # # # #
### # ##### # ### ### # # ### # # ### # ### # # #
# # # # # # # # # # # # # # #
####### # # ####### ##### # ##### ####### ### ###
# # # # # # # # # #
### # ##### ### # ### # # ##### # ############# #
# # # # # # # # # # # # #
# ### # # ### ############# # # ##### ##### # # #
# # # # # # # # # # # # # #
#### ##### # ### # ##### # # ##### # ### # ##### #
# # # # # # # # # # # #
### ####### ####### # ####### # ##### # ### ### #
# # # # # # # # # # # #
####### # # # ### ##### # ##### ### # ### #######
# # # # # # # # # # # # #
## ### ####### ### # # ### # # # # ### # ### ### #
# # # # # # # # # # # #
####### # ##### ####### ### ######### ##### ### #
# # # # # # # # # # #
#### # # ### ##### ####### # # # ### # # # ### # #
# # # # # # # # # # # # # # # #
# # # ### # # # # # # ### ####### # ##### # ### #
# # # # # # # # # # # # # # # #
# # # ### ######### # # ### # # # ##### # # # ###
# # # # # # # # # # # # #
####### ### # ### ####### # # ##### # ######### #
# # # # # # # # # # # # #
########### ### ### ### # ### # # ##### # ### # #
# # # # # # # # # # # # # #
### # ### ### ####### ### # ### # # # ####### # #
# # # # # # # # # # # # # # # #
## # ### # # ### # # # # # # # # # ### # ### ### #
# # # # # # # # # # # # # # # # # #
##### # # ##### # # # ####### # ### # # # ### # #
# # # # # # # # # # # # # # #
# # # ### # ### ########### # ##### # ### # # ###
# # # # # # # # # # # # #
#### ##### # # ### ### # ##### # ##### # #########
# # # # # # # # # # #
# ### ##### ### ### # ### ########### ######### #
# # # # # # # # # #
### # ##### # # ##### # ####### # ### ### # #####
# # # # # # # # # # #
## ##### # ### ### # ##### ####### # # ######### #
# # # # # # # # # # # #
### # ##### # # ##### # ### ##### ##### ####### #
# # # # # # # # # # #
# ########### ########### ##### ####### # ### # #
# # # #
################################################ E

View File

@ -1,50 +0,0 @@
S # # # #
####### ### # # ########### ##### # ##### ##### #
# # # # # # # # # #
## # # ### ####### ##### ####### # ### ######### #
# # # # # # # # # # # # #
####### # # # # ### ##### # ### ### # # # # ### #
# # # # # # # # # # # # # # # # #
# ### # ### # ### ### # # ### ### ####### # # ###
# # # # # # # # # # # # # #
# # ############# # ### ### # ######### # # ### #
# # # # # # # # #
########### ########### # ##### ### ### # # # ###
# # # # # # # # # # # # # #
# # ####### # ### # ##### ### ### ### ### # # # #
# # # # # # # # # # # # # # # #
###### ### ### # # # # # # # ### ### ##### # # # #
# # # # # # # # # # # # # # #
### # # ######### ### # # # # ####### ##### # # #
# # # # # # # # # # # # # #
### ### # ##### # # ######### # # # # ##### # # #
# # # # # # # # # # # #
## # ######### # # ### ### # ### ######### ##### #
# # # # # # # # # # # #
##### # ### # ### ##### # # # ####### ##### # # #
# # # # # # # # # # # # # # #
## # ##### # # ##### ##### ### ### # ### # # # ###
# # # # # # # # # # # # #
##### # ### # # ##### ### # ### ######### # #####
# # # # # # # # # # #
# ####### ######### ### ####### # # ####### ### #
# # # # # # # # # # # # # #
# # ####### # # ##### # # ### ### # # # # ##### #
# # # # # # # # # # # # # # # #
# ##### # ####### # # # # # ### # ### # # # ### #
# # # # # # # # # # # # # # #
# ########### # ### ####### ### # ### # # # # # #
# # # # # # # # # # # # #
# # ####### ##### ########### ##### # # ##### # #
# # # # # # # # # # #
### ### ### # ############### # # # ##### ### ###
# # # # # # # # # # # # # #
# ### ### # ### ##### # # # # # ##### # ### # # #
# # # # # # # # # # # # # #
# # ####### # ### ######### ######### ### # # # #
# # # # # # # # # # # # # # #
##### # ####### # # # ### # # # # # ### ### # # #
# # # # # # # # # # # # # # #
## ### ##### ####### ### # # ### ##### # ### ### #
# # # #
################################################ E

View File

@ -0,0 +1,25 @@
S
E

View File

@ -0,0 +1,25 @@
S # # #
# ##### # # # ####### #
# # # # # #
#### # ##### # # #######
# # # # # # #
## # # # ##### ### # # #
# # # # # # # # #
### # # # # ### # # # #
# # # # # # # #
# ### # # ### ### # ####
# # # # # # #
### # # # ####### #####
# # # #
# ################# ###
# # # #
# # # ####### ####### ##
# # # # #
### ##### # ### ### ###
# # # # # #
# # # ##### # # #######
# # # # # #
##### # ####### # ### ##
# # # # # # #
#### # # # ### ##### # #
# # # #

View File

@ -7,13 +7,14 @@ class Maze:
getCell(x, y), getNeighbors(cell) возвращает список соседних проходимых клеток
(вверх, вниз, влево, вправо, если в пределах границ и не стена)."""
def __init__(self, mazeArray: list[list[Cell]], start: dict, end: dict) -> None:
def __init__(self, mazeArray: list[list[Cell]], start: dict, end: dict, name:str="") -> None:
self.mazeArray = mazeArray
self.height = len(mazeArray) # X
self.width = len(mazeArray[0]) # Y
self.startCell = self.getCell(start['x'], start['y'])
self.endCell = self.getCell(end['x'], end['y'])
self.name = name
def getCell(self, x: int, y: int):
return self.mazeArray[y][x]

View File

@ -58,7 +58,7 @@ class MazeSolver(Subject):
path = self.strategy.findPath(self._maze, self._maze.startCell, self._maze.endCell)
duration = (time.perf_counter() - t_start) * 1000
path_len = len(path.array) if path.array else 0
path_len = len(path.array) if path.array else -1
strategy_name = self.getStrategyName()
stats = SearchStats(path.array, duration, path.visited_cells, path_len, strategy_name)

View File

@ -29,7 +29,7 @@ class AStar(PathFindingStrategy):
continue
visited.add(current)
if current == exit:
if current.isExit:
return Path(restorePath(parents, exit), len(visited))
for neighbor in maze.getNeighbors(current):

View File

@ -19,11 +19,14 @@ class BFS(PathFindingStrategy):
visited[start] = 0
parents[start] = None
found_exit = False
while not q.empty():
current = q.get()
# Условие нахождение выхода
if current == exit: break
if current.isExit:
found_exit = True
break
# Перебор соседей
for hood in maze.getNeighbors(current):
@ -33,4 +36,8 @@ class BFS(PathFindingStrategy):
parents[hood] = current
q.put(hood)
return Path(restorePath(parents, exit), len(visited))
if not found_exit:
path_list = None
else:
path_list = restorePath(parents, exit)
return Path(path_list, len(visited))

View File

@ -17,11 +17,14 @@ class DFS(PathFindingStrategy):
visited[start] = 0
parents[start] = None
found_exit = False
while stack:
current = stack.pop()
# Условие нахождение выхода
if current == exit: break
if current.isExit:
found_exit = True
break
# Перебор соседей
for hood in maze.getNeighbors(current):
@ -31,4 +34,8 @@ class DFS(PathFindingStrategy):
parents[hood] = current
stack.append(hood)
return Path(restorePath(parents, exit), len(visited))
if not found_exit:
path_list = None
else:
path_list = restorePath(parents, exit)
return Path(path_list, len(visited))

View File

@ -18,13 +18,13 @@ class Tester():
лабиринт,стратегия,время_мс,посещено_клеток,длина_пути."""
result:list[SearchStats]
def __init__(self, builder:MazeBuilder, writefile:str):
self.builder = builder
self.writefile = writefile
self._builder = builder
self.writefile = "../" + writefile
def setTestingDirectory(self, directory:str):
if directory[-1] != "/":
directory += "/"
self._directory = directory
self._directory = "../" + directory
def _getMazes(self) -> list[Maze]:
arr = []
@ -32,7 +32,7 @@ class Tester():
only_txt_files = [f for f in files if os.path.isfile(os.path.join(self._directory, f)) and os.path.splitext(f)[1] == ".txt"]
for f in only_txt_files:
arr.append(builder.buildFromFile(os.path.join(self._directory, f)))
arr.append(self._builder.buildFromFile(os.path.join(self._directory, f)))
return arr
def _solveAvg(self, solver: MazeSolver):
@ -68,15 +68,16 @@ class Tester():
for maze in arr:
solver.setMaze(maze)
self.result.append(self._solveAvg(solver))
self.result[-1].maze_name = f"{maze.height}x{maze.width}"
self.result[-1].maze_name = maze.name
return self.result
if __name__ == "__main__":
exit()
from task2.mazeBuilder import TextFileMazeBuilder
builder = TextFileMazeBuilder()
tester = Tester(builder, "docs/data/mazeRezults.csv")
tester = Tester(builder, "docs/data/task2/results.csv")
tester.setTestingDirectory("task2/mazeExamples")
tester.test()
tester.saveCSV()