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