Compare commits

...

2 Commits

Author SHA1 Message Date
ef877978d2 Реализация алгоритма A* 2026-05-22 22:27:49 +03:00
e54b6c0a7e исправление метода name 2026-05-22 22:10:16 +03:00
5 changed files with 235 additions and 70 deletions

View File

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

View File

@ -5,6 +5,7 @@ from source.strategy import PathFindingStrategy, reconstruct_path
from source.classes import Maze, Cell from source.classes import Maze, Cell
class BFS(PathFindingStrategy): class BFS(PathFindingStrategy):
@property
def name(self): def name(self):
"""Возвращает название метода""" """Возвращает название метода"""
return "BFS" return "BFS"

View File

@ -1,10 +1,64 @@
from source.strategy import PathFindingStrategy from heapq import *
from source.strategy import PathFindingStrategy, reconstruct_path
from source.classes import Maze, Cell from source.classes import Maze, Cell
class AStar(PathFindingStrategy): class AStar(PathFindingStrategy):
def findPath(self, maze: Maze, start: Cell, exit: Cell): @property
pass def name(self) -> str:
return "A*"
def __A__(self, maze: Maze, start: Cell, exit: Cell): def heuristic(self, a: Cell, b: Cell) -> int:
pass x1, y1 = a.getXY()
x2, y2 = b.getXY()
return abs(x1 - x2) + abs(y1 - y2)
def findPath(self, maze: Maze):
start_cell = maze.start
exit_cell = maze.exit
queue = []
counter = 0 # счётчик для уникальности, чтобы не сравнивать клетки
start_h = self.heuristic(start_cell, exit_cell)
heappush(queue, (start_h, counter, start_cell))
counter += 1
cost_visited = {start_cell.getXY(): 0}
came_from = {start_cell.getXY(): None}
visited_count = 1
while queue:
current_cost, _, current_cell = heappop(queue)
current_g = cost_visited[current_cell.getXY()]
if current_cell.getXY() == exit_cell.getXY():
return reconstruct_path(
came_from=came_from,
start=start_cell,
end=current_cell
), visited_count
next_cells = maze.getNeighbors(current_cell)
for next_cell in next_cells:
neighbor_cost = next_cell.value
neighbor_cell_xy = next_cell.getXY()
new_cost = current_g + neighbor_cost
if neighbor_cell_xy not in cost_visited or new_cost < cost_visited[neighbor_cell_xy]:
priority = new_cost + self.heuristic(next_cell, exit_cell)
heappush(queue, (priority, counter, next_cell))
counter += 1
cost_visited[neighbor_cell_xy] = new_cost
came_from[neighbor_cell_xy] = current_cell
visited_count += 1
return [], visited_count

View File

@ -12,7 +12,7 @@ class MazeSolver:
self.strategy = strategy self.strategy = strategy
self.observer = observer self.observer = observer
def strategyName(self): def strategyName(self) -> str:
return self.strategy.name return self.strategy.name
def setStrategy(self, strategy: PathFindingStrategy): def setStrategy(self, strategy: PathFindingStrategy):
@ -46,3 +46,7 @@ class SearchStats:
self.visitedCells = visitedCells self.visitedCells = visitedCells
self.pathLength = pathLength self.pathLength = pathLength
self.path = path self.path = path
def show(self):
"""Вывод информации о тесте в консоль"""
print(f'time: {self.timeMs} ms\nvisited cells: {self.visitedCells}\npath length: {self.pathLength}')

View File

@ -2,14 +2,14 @@
"cells": [ "cells": [
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 12, "execution_count": 15,
"id": "4dbe48b6", "id": "4dbe48b6",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"from source.builder import TextFileMazeBuilder\n", "from source.builder import TextFileMazeBuilder\n",
"from source.observer import ConsoleView, Event\n", "from source.observer import ConsoleView, Event\n",
"from source.strategy import MazeSolver, BFS, DFS\n", "from source.strategy import MazeSolver, BFS, DFS, Dijkstra, AStar\n",
"# from source.strategy.maze_solver import \n", "# from source.strategy.maze_solver import \n",
"from source.classes import Cell\n", "from source.classes import Cell\n",
"# from source.strategy import " "# from source.strategy import "
@ -17,19 +17,20 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 13, "execution_count": null,
"id": "007bf97a", "id": "007bf97a",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"test_lab = './mazes/tests/test_lab.txt'\n", "test_lab = './mazes/tests/test_lab.txt'\n",
"test_lab2 = './mazes/tests/test_lab2.txt'\n", "test_lab2 = './mazes/tests/test_lab2.txt'\n",
"test_lab3 = './mazes/tests/test_lab20x20.txt'" "test_lab3 = './mazes/tests/test_lab3.txt'\n",
"test_lab4 = './mazes/tests/test_lab20x20.txt'"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 14, "execution_count": 17,
"id": "4489fc7e", "id": "4489fc7e",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@ -55,7 +56,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 15, "execution_count": 18,
"id": "fde1eddb", "id": "fde1eddb",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@ -83,7 +84,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 16, "execution_count": 19,
"id": "22325f68", "id": "22325f68",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@ -116,7 +117,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 17, "execution_count": 20,
"id": "19840429", "id": "19840429",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@ -154,7 +155,7 @@
" (7, 1)])" " (7, 1)])"
] ]
}, },
"execution_count": 17, "execution_count": 20,
"metadata": {}, "metadata": {},
"output_type": "execute_result" "output_type": "execute_result"
} }
@ -168,7 +169,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 18, "execution_count": 21,
"id": "73ba37a8", "id": "73ba37a8",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@ -206,7 +207,7 @@
" (7, 1)])" " (7, 1)])"
] ]
}, },
"execution_count": 18, "execution_count": 21,
"metadata": {}, "metadata": {},
"output_type": "execute_result" "output_type": "execute_result"
} }
@ -220,7 +221,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 19, "execution_count": 22,
"id": "857c5c04", "id": "857c5c04",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@ -230,10 +231,9 @@
"text": [ "text": [
"0\n", "0\n",
"1\n", "1\n",
"3\n",
"4\n", "4\n",
"2\n", "2\n",
"3\n",
"3\n",
"2\n" "2\n"
] ]
}, },
@ -243,7 +243,7 @@
"{'0', '1', '2', '3', '4'}" "{'0', '1', '2', '3', '4'}"
] ]
}, },
"execution_count": 19, "execution_count": 22,
"metadata": {}, "metadata": {},
"output_type": "execute_result" "output_type": "execute_result"
} }
@ -272,7 +272,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 20, "execution_count": 23,
"id": "9a5ea5cb", "id": "9a5ea5cb",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@ -358,7 +358,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 21, "execution_count": 24,
"id": "32edf4d1", "id": "32edf4d1",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@ -383,7 +383,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 22, "execution_count": 25,
"id": "48d20564", "id": "48d20564",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@ -391,40 +391,37 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"BFS\n",
"Путь найден:\n", "Путь найден:\n",
"# # # # # # # # # # # # # # # # # # # #\n", "#####################################\n",
"S. # # # #\n", "#S #\n",
"#.# # # # # # # # # # # # #\n", "#. #\n",
"#..... # # # # # # # # #\n", "#. #\n",
"# #.# # # # # # # # # # # #\n", "#. #\n",
"# #............. # # # # #\n", "#. #\n",
"# # # # # # #. # # # # # # #\n", "#. #\n",
"# # # # #..... # # # # #\n", "#. #\n",
"# # # # # # #. # # # # #\n", "#. #\n",
"# # # # #. # # # # #\n", "#..................................E#\n",
"# # # # # # #. # # # # #\n", "#####################################\n",
"# # # # #..... # # # #\n", "time: 0.0008461000002171204 ms\n",
"# # # # # # # # #. # # # #\n", "visited cells: 315\n",
"# # # # #. # # #\n", "path length: 43\n"
"# # # # # # # # #. # # # # #\n",
"# # # # # # #. # # # #\n",
"# # # # # # #. # # # #\n",
"# # # # # # #. # # # #\n",
"# # # #...........E #\n",
"# # # # # # # # # # # # # # # # # # # #\n"
] ]
} }
], ],
"source": [ "source": [
"maze2 = builder.buildFromFile(test_lab3)\n", "maze2 = builder.buildFromFile(test_lab2)\n",
"\n", "\n",
"solver = MazeSolver(maze2, BFS(), ConsoleView())\n", "solver = MazeSolver(maze2, BFS(), ConsoleView())\n",
"stats = solver.solve()" "print(solver.strategyName())\n",
"stats = solver.solve()\n",
"stats.show()"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 23, "execution_count": 26,
"id": "bf13d5ba", "id": "bf13d5ba",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@ -432,27 +429,31 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"DFS\n",
"Путь найден:\n", "Путь найден:\n",
"####################\n", "####################\n",
"S.......# # # #\n", "S...# # # #\n",
"###.# ### # ### # ##\n", "###.# ### # ### # ##\n",
"#.......# # # # # # # # #\n", "#...# # # # # # # ##\n",
"#.### # ### # ### ##\n", "#.### # ### # ### ##\n",
"#...# ...........# # # # #\n", "#.# .....# # # ##\n",
"#.###.###.### # # ##\n", "#.###.###.### # # ##\n",
"#...# #...# # .....# # # # #\n", "#.# #.# #...# # # ##\n",
"#.# #.# ###.# # # ##\n", "#.# #.# ###.# # # ##\n",
"#...# #...# #...# # # # #\n", "#.# #.# #.# # # ##\n",
"#.# #.### #.# # # ##\n", "#.# #.### #.# # # ##\n",
"#...# #..... # #.......# # # #\n", "#.# #...# #...# # ##\n",
"#. # # # #...# # # # .# # # #\n", "#.# ###.# ###.# # ##\n",
"#...#.......# .# #...# # #\n", "#.# #.# #.# ##\n",
"# .#.# # .#...# # # #. # # # # #\n", "#.### #.### #.### ##\n",
"#...#. #...#. # # #...# # # #\n", "#.#...#.# # #.# # ##\n",
"#. #...#. #...# # # .# # # #\n", "#.#.#.#.# # #.# # ##\n",
"#...# .#...# .# # # .# # # #\n", "#.#.#.#.# # #.# # ##\n",
"# .....# .....# # .........E #\n", "#...#...# #.....E#\n",
"# # # # # # # # # # # # # # # # # # # #\n" "####################\n",
"time: 0.00014700000019729487 ms\n",
"visited cells: 83\n",
"path length: 76\n"
] ]
} }
], ],
@ -460,13 +461,109 @@
"maze2 = builder.buildFromFile(test_lab3)\n", "maze2 = builder.buildFromFile(test_lab3)\n",
"\n", "\n",
"solver = MazeSolver(maze2, DFS(), ConsoleView())\n", "solver = MazeSolver(maze2, DFS(), ConsoleView())\n",
"stats = solver.solve()" "print(solver.strategyName())\n",
"stats = solver.solve()\n",
"stats.show()"
]
},
{
"cell_type": "code",
"execution_count": 27,
"id": "9383cb75",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Dijkstra\n",
"Путь найден:\n",
"####################\n",
"S...# # # #\n",
"###.# ### # ### # ##\n",
"#...# # # # # # # ##\n",
"#.### # ### # ### ##\n",
"#.# .....# # # ##\n",
"#.###.###.### # # ##\n",
"#.# #.# #...# # # ##\n",
"#.# #.# ###.# # # ##\n",
"#.# #.# #.# # # ##\n",
"#.# #.### #.# # # ##\n",
"#.# #...# #...# # ##\n",
"#.# ###.# ###.# # ##\n",
"#.# #.# #.# ##\n",
"#.### #.### #.### ##\n",
"#.#...#.# # #.# # ##\n",
"#.#.#.#.# # #.# # ##\n",
"#.#.#.#.# # #.# # ##\n",
"#...#...# #.....E#\n",
"####################\n",
"time: 0.00022080000007917988 ms\n",
"visited cells: 120\n",
"path length: 76\n"
]
}
],
"source": [
"maze2 = builder.buildFromFile(test_lab3)\n",
"\n",
"solver = MazeSolver(maze2, Dijkstra(), ConsoleView())\n",
"print(solver.strategyName())\n",
"stats = solver.solve()\n",
"stats.show()"
]
},
{
"cell_type": "code",
"execution_count": 28,
"id": "835cff61",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"A*\n",
"Путь найден:\n",
"####################\n",
"S...# # # #\n",
"###.# ### # ### # ##\n",
"#...# # # # # # # ##\n",
"#.### # ### # ### ##\n",
"#.# .....# # # ##\n",
"#.###.###.### # # ##\n",
"#.# #.# #...# # # ##\n",
"#.# #.# ###.# # # ##\n",
"#.# #.# #.# # # ##\n",
"#.# #.### #.# # # ##\n",
"#.# #...# #...# # ##\n",
"#.# ###.# ###.# # ##\n",
"#.# #.# #.# ##\n",
"#.### #.### #.### ##\n",
"#.#...#.# # #.# # ##\n",
"#.#.#.#.# # #.# # ##\n",
"#.#.#.#.# # #.# # ##\n",
"#...#...# #.....E#\n",
"####################\n",
"time: 0.00025749999986146577 ms\n",
"visited cells: 92\n",
"path length: 76\n"
]
}
],
"source": [
"maze2 = builder.buildFromFile(test_lab3)\n",
"\n",
"solver = MazeSolver(maze2, AStar(), ConsoleView())\n",
"print(solver.strategyName())\n",
"stats = solver.solve()\n",
"stats.show()"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"id": "9383cb75", "id": "2d84a151",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [] "source": []