2 Commits

Author SHA1 Message Date
da7e 16d97e9912 fix(astar): function f() miscalculate the best path 2026-03-27 21:51:49 +01:00
Maoake Teriierooiterai b078241359 fix something on the solver 2026-03-27 18:05:05 +01:00
5 changed files with 68 additions and 81 deletions
+2 -2
View File
@@ -1,5 +1,5 @@
WIDTH=20
HEIGHT=20
WIDTH=15
HEIGHT=15
ENTRY=1,1
EXIT=2,2
OUTPUT_FILE=maze.txt
+1 -1
View File
@@ -33,7 +33,7 @@ class AMazeIng(BaseModel):
return
def solve_path(self) -> str:
return self.solver.solve(self.maze)
return self.solver.solve(self.maze, self.height, self.width)
def __str__(self) -> str:
res = self.maze.__str__()
+47 -56
View File
@@ -9,44 +9,30 @@ class MazeSolver(ABC):
self.end = (end[1] - 1, end[0] - 1)
@abstractmethod
def solve(self, maze: Maze, height: int = None,
width: int = None) -> str: ...
def solve(
self, maze: Maze, height: int = None, width: int = None
) -> str: ...
class AStar(MazeSolver):
def __init__(self, start: tuple[int, int], end: tuple[int, int]) -> None:
super().__init__(start, end)
self.path = []
def f(self, n):
def g(n: tuple[int, int]) -> int:
res = 0
if n[0] < self.start[0]:
res += self.start[0] - n[0]
else:
res += n[0] - self.start[0]
if n[1] < self.start[1]:
res += self.start[1] - n[1]
else:
res += n[1] - self.start[1]
return res
def g() -> int:
return len(self.path) + 1
def h(n: tuple[int, int]) -> int:
res = 0
if n[0] < self.end[0]:
res += self.end[0] - n[0]
else:
res += n[0] - self.end[0]
if n[1] < self.end[1]:
res += self.end[1] - n[1]
else:
res += n[1] - self.end[1]
return res
return (
max(n[0], self.end[0])
- min(n[0], self.end[0])
+ max(n[1], self.end[1])
- min(n[1], self.end[1])
)
try:
return g(n) + h(n)
except Exception:
return 1000
return g() + h(n)
def best_path(
self,
@@ -113,46 +99,46 @@ class AStar(MazeSolver):
return actual
def get_path(self, maze: np.ndarray) -> str | None:
path = [(self.start, self.best_path(maze, self.start, None))]
self.path = [(self.start, self.best_path(maze, self.start, None))]
visited = [self.start]
while len(path) > 0 and path[-1][0] != self.end:
if len(path[-1][1]) == 0:
path.pop(-1)
if len(path) == 0:
while len(self.path) > 0 and self.path[-1][0] != self.end:
if len(self.path[-1][1]) == 0:
self.path.pop(-1)
if len(self.path) == 0:
break
k = next(iter(path[-1][1]))
path[-1][1].pop(k)
k = next(iter(self.path[-1][1]))
self.path[-1][1].pop(k)
continue
while len(path[-1][1]) > 0:
while len(self.path[-1][1]) > 0:
next_pos = self.get_next_pos(
list(path[-1][1].keys())[0], path[-1][0]
list(self.path[-1][1].keys())[0], self.path[-1][0]
)
if next_pos in visited:
k = next(iter(path[-1][1]))
path[-1][1].pop(k)
k = next(iter(self.path[-1][1]))
self.path[-1][1].pop(k)
else:
break
if len(path[-1][1]) == 0:
path.pop(-1)
if len(self.path[-1][1]) == 0:
self.path.pop(-1)
continue
pre = self.get_opposit(list(path[-1][1].keys())[0])
path.append(
pre = self.get_opposit(list(self.path[-1][1].keys())[0])
self.path.append(
(
next_pos,
self.best_path(maze, next_pos, pre),
)
)
visited += [next_pos]
if len(path) == 0:
if len(self.path) == 0:
return None
path[-1] = (self.end, {})
self.path[-1] = (self.end, {})
return "".join(
str(list(c[1].keys())[0]) for c in path if len(c[1]) > 0
str(list(c[1].keys())[0]) for c in self.path if len(c[1]) > 0
)
def solve(self, maze: Maze) -> str:
def solve(self, maze: Maze, height: int = None, width: int = None) -> str:
res = self.get_path(maze.get_maze())
if res is None:
raise Exception("Path not found")
@@ -161,11 +147,9 @@ class AStar(MazeSolver):
class DepthFirstSearchSolver(MazeSolver):
def __init__(self, start, end):
self.start = (start[1] - 1, start[0] - 1)
self.end = (end[1] - 1, end[0] - 1)
super().__init__(start, end)
def solve(self, maze: Maze, height: int = None,
width: int = None) -> str:
def solve(self, maze: Maze, height: int = None, width: int = None) -> str:
path_str = ""
visited = np.zeros((height, width), dtype=bool)
path = list()
@@ -179,8 +163,9 @@ class DepthFirstSearchSolver(MazeSolver):
rand_p = self.random_path(visited, coord, maze_s, h_w)
if not rand_p:
path, move = self.back_on_step(path, visited, maze_s, h_w,
move)
path, move = self.back_on_step(
path, visited, maze_s, h_w, move
)
if not path:
break
coord = path[-1]
@@ -195,8 +180,9 @@ class DepthFirstSearchSolver(MazeSolver):
return path_str
@staticmethod
def random_path(visited: np.ndarray, coord: tuple,
maze: np.ndarray, h_w: tuple) -> list:
def random_path(
visited: np.ndarray, coord: tuple, maze: np.ndarray, h_w: tuple
) -> list:
random_p = []
h, w = h_w
y, x = coord
@@ -219,8 +205,13 @@ class DepthFirstSearchSolver(MazeSolver):
return np.random.choice(rand_path)
@staticmethod
def back_on_step(path: list, visited: np.ndarray,
maze: np.ndarray, h_w: tuple, move: list) -> list:
def back_on_step(
path: list,
visited: np.ndarray,
maze: np.ndarray,
h_w: tuple,
move: list,
) -> list:
while path:
last = path[-1]
if DepthFirstSearchSolver.random_path(visited, last, maze, h_w):
+2 -1
View File
@@ -1,5 +1,5 @@
from src.amaz_lib.MazeGenerator import DepthFirstSearch, Kruskal
from src.amaz_lib.MazeSolver import AStar
from src.amaz_lib.MazeSolver import AStar, DepthFirstSearchSolver
class DataMaze:
@@ -68,6 +68,7 @@ class DataMaze:
}
available_solver = {
"AStar": AStar,
"DFS": DepthFirstSearchSolver
}
res = {}
res["GENERATOR"] = available_generator[data["GENERATOR"]](entry, exit,
+16 -21
View File
@@ -1,24 +1,19 @@
B9153957955513953953
AEA96A9569792C6BAAD6
C5443AA9169281102C53
95556A82816C2AC2A952
A93916A86A956C3A86D6
AEC6C542944513806953
C395553AC393C2AC787A
BC69512C7AAC56855692
A952BAAF96AFFFAD53AE
A810686FC5057FC516C3
AAC4543FFFAFFFB96952
AC5553817FAFD52ABC3A
815552843FEFFF80296A
AC553A85413D55406C12
C53BAAC392C3953C13AA
9386AC386A9683C56AAA
846903AE96C568517C2A
AD3A82C385397C3C5546
C12AA87AA94293AD5513
D46C6C5446D46C45556E
D53939553D13B93
93AAC697A92C6AA
AC6A95056AE956A
A916856D1454152
A843C5394555696
A87AF96AFFFB96B
AE96FC5457F8412
C52BFFFBFFFC102
B94453FAFD516EA
86953AFAFFFA956
81692C54153A853
AC3A83950546C3A
ABA86C2D69517C2
C2AC55293ABC53A
D6C55546C4457C6
1,1
2,2
SSEEENENWWWS
EESSWN