Реализация алгоритма A*

This commit is contained in:
GordStep 2026-05-22 22:27:49 +03:00
parent e54b6c0a7e
commit ef877978d2
3 changed files with 183 additions and 58 deletions

View File

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

View File

@ -1,4 +1,7 @@
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
@ -7,8 +10,55 @@ class AStar(PathFindingStrategy):
def name(self) -> str: def name(self) -> str:
return "A*" return "A*"
def findPath(self, maze: Maze, start: Cell, exit: Cell): def heuristic(self, a: Cell, b: Cell) -> int:
pass x1, y1 = a.getXY()
x2, y2 = b.getXY()
def __A__(self, maze: Maze, start: Cell, exit: Cell): return abs(x1 - x2) + abs(y1 - y2)
pass
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

@ -2,14 +2,14 @@
"cells": [ "cells": [
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 1, "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, Dijkstra\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": 2, "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": 3, "execution_count": 17,
"id": "4489fc7e", "id": "4489fc7e",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@ -55,7 +56,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 4, "execution_count": 18,
"id": "fde1eddb", "id": "fde1eddb",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@ -83,7 +84,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 5, "execution_count": 19,
"id": "22325f68", "id": "22325f68",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@ -116,7 +117,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 6, "execution_count": 20,
"id": "19840429", "id": "19840429",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@ -154,7 +155,7 @@
" (7, 1)])" " (7, 1)])"
] ]
}, },
"execution_count": 6, "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": 7, "execution_count": 21,
"id": "73ba37a8", "id": "73ba37a8",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@ -206,7 +207,7 @@
" (7, 1)])" " (7, 1)])"
] ]
}, },
"execution_count": 7, "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": 8, "execution_count": 22,
"id": "857c5c04", "id": "857c5c04",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@ -229,11 +230,11 @@
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"0\n", "0\n",
"2\n",
"1\n", "1\n",
"4\n",
"3\n", "3\n",
"3\n" "4\n",
"2\n",
"2\n"
] ]
}, },
{ {
@ -242,7 +243,7 @@
"{'0', '1', '2', '3', '4'}" "{'0', '1', '2', '3', '4'}"
] ]
}, },
"execution_count": 8, "execution_count": 22,
"metadata": {}, "metadata": {},
"output_type": "execute_result" "output_type": "execute_result"
} }
@ -271,7 +272,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 9, "execution_count": 23,
"id": "9a5ea5cb", "id": "9a5ea5cb",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@ -357,7 +358,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 10, "execution_count": 24,
"id": "32edf4d1", "id": "32edf4d1",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@ -382,7 +383,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 11, "execution_count": 25,
"id": "48d20564", "id": "48d20564",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@ -403,7 +404,7 @@
"#. #\n", "#. #\n",
"#..................................E#\n", "#..................................E#\n",
"#####################################\n", "#####################################\n",
"time: 0.000567700000374316 ms\n", "time: 0.0008461000002171204 ms\n",
"visited cells: 315\n", "visited cells: 315\n",
"path length: 43\n" "path length: 43\n"
] ]
@ -420,7 +421,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 12, "execution_count": 26,
"id": "bf13d5ba", "id": "bf13d5ba",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@ -430,25 +431,34 @@
"text": [ "text": [
"DFS\n", "DFS\n",
"Путь найден:\n", "Путь найден:\n",
"#####################################\n", "####################\n",
"#S..................................#\n", "S...# # # #\n",
"# .#\n", "###.# ### # ### # ##\n",
"#...................................#\n", "#...# # # # # # # ##\n",
"#. #\n", "#.### # ### # ### ##\n",
"#...................................#\n", "#.# .....# # # ##\n",
"# .#\n", "#.###.###.### # # ##\n",
"#...................................#\n", "#.# #.# #...# # # ##\n",
"#. #\n", "#.# #.# ###.# # # ##\n",
"#..................................E#\n", "#.# #.# #.# # # ##\n",
"#####################################\n", "#.# #.### #.# # # ##\n",
"time: 0.0004403000002639601 ms\n", "#.# #...# #...# # ##\n",
"visited cells: 315\n", "#.# ###.# ###.# # ##\n",
"path length: 179\n" "#.# #.# #.# ##\n",
"#.### #.### #.### ##\n",
"#.#...#.# # #.# # ##\n",
"#.#.#.#.# # #.# # ##\n",
"#.#.#.#.# # #.# # ##\n",
"#...#...# #.....E#\n",
"####################\n",
"time: 0.00014700000019729487 ms\n",
"visited cells: 83\n",
"path length: 76\n"
] ]
} }
], ],
"source": [ "source": [
"maze2 = builder.buildFromFile(test_lab2)\n", "maze2 = builder.buildFromFile(test_lab3)\n",
"\n", "\n",
"solver = MazeSolver(maze2, DFS(), ConsoleView())\n", "solver = MazeSolver(maze2, DFS(), ConsoleView())\n",
"print(solver.strategyName())\n", "print(solver.strategyName())\n",
@ -458,7 +468,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 13, "execution_count": 27,
"id": "9383cb75", "id": "9383cb75",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@ -468,25 +478,34 @@
"text": [ "text": [
"Dijkstra\n", "Dijkstra\n",
"Путь найден:\n", "Путь найден:\n",
"#####################################\n", "####################\n",
"#S #\n", "S...# # # #\n",
"#. #\n", "###.# ### # ### # ##\n",
"#. #\n", "#...# # # # # # # ##\n",
"#. #\n", "#.### # ### # ### ##\n",
"#. #\n", "#.# .....# # # ##\n",
"#. #\n", "#.###.###.### # # ##\n",
"#. #\n", "#.# #.# #...# # # ##\n",
"#. #\n", "#.# #.# ###.# # # ##\n",
"#..................................E#\n", "#.# #.# #.# # # ##\n",
"#####################################\n", "#.# #.### #.# # # ##\n",
"time: 0.0007290000003195019 ms\n", "#.# #...# #...# # ##\n",
"visited cells: 315\n", "#.# ###.# ###.# # ##\n",
"path length: 43\n" "#.# #.# #.# ##\n",
"#.### #.### #.### ##\n",
"#.#...#.# # #.# # ##\n",
"#.#.#.#.# # #.# # ##\n",
"#.#.#.#.# # #.# # ##\n",
"#...#...# #.....E#\n",
"####################\n",
"time: 0.00022080000007917988 ms\n",
"visited cells: 120\n",
"path length: 76\n"
] ]
} }
], ],
"source": [ "source": [
"maze2 = builder.buildFromFile(test_lab2)\n", "maze2 = builder.buildFromFile(test_lab3)\n",
"\n", "\n",
"solver = MazeSolver(maze2, Dijkstra(), ConsoleView())\n", "solver = MazeSolver(maze2, Dijkstra(), ConsoleView())\n",
"print(solver.strategyName())\n", "print(solver.strategyName())\n",
@ -496,9 +515,56 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 28,
"id": "835cff61", "id": "835cff61",
"metadata": {}, "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",
"execution_count": null,
"id": "2d84a151",
"metadata": {},
"outputs": [], "outputs": [],
"source": [] "source": []
} }