From eca504b98cf84fc50ae624a46564a243e5c84f9e Mon Sep 17 00:00:00 2001 From: JadeKim042386 Date: Sat, 27 May 2023 16:23:06 +0900 Subject: [PATCH 01/10] fix: typo #8770 --- graphs/greedy_best_first.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphs/greedy_best_first.py b/graphs/greedy_best_first.py index 35f7ca9feeef..e21a2495bace 100644 --- a/graphs/greedy_best_first.py +++ b/graphs/greedy_best_first.py @@ -146,8 +146,8 @@ def get_successors(self, parent: Node) -> list[Node]: Node( pos_x, pos_y, - self.target.pos_y, self.target.pos_x, + self.target.pos_y, parent.g_cost + 1, parent, ) From 5daf1c04dc0ab0a47ad28190e774c04e69f8327d Mon Sep 17 00:00:00 2001 From: JadeKim042386 Date: Sat, 27 May 2023 16:23:49 +0900 Subject: [PATCH 02/10] refactor: delete unnecessary continue --- graphs/greedy_best_first.py | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/graphs/greedy_best_first.py b/graphs/greedy_best_first.py index e21a2495bace..674ffe96f601 100644 --- a/graphs/greedy_best_first.py +++ b/graphs/greedy_best_first.py @@ -136,22 +136,20 @@ def get_successors(self, parent: Node) -> list[Node]: pos_x = parent.pos_x + action[1] pos_y = parent.pos_y + action[0] - if not (0 <= pos_x <= len(grid[0]) - 1 and 0 <= pos_y <= len(grid) - 1): - continue - - if grid[pos_y][pos_x] != 0: - continue - - successors.append( - Node( - pos_x, - pos_y, - self.target.pos_x, - self.target.pos_y, - parent.g_cost + 1, - parent, + if (0 <= pos_x <= len(grid[0]) - 1 + and 0 <= pos_y <= len(grid) - 1 + and grid[pos_y][pos_x] == 0): + + successors.append( + Node( + pos_x, + pos_y, + self.target.pos_x, + self.target.pos_y, + parent.g_cost + 1, + parent, + ) ) - ) return successors def retrace_path(self, node: Node | None) -> Path: From b78ff3f6098a1a060e75eee2a249dac2173a1a54 Mon Sep 17 00:00:00 2001 From: JadeKim042386 Date: Sat, 27 May 2023 16:27:41 +0900 Subject: [PATCH 03/10] add test grids --- graphs/greedy_best_first.py | 72 ++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 25 deletions(-) diff --git a/graphs/greedy_best_first.py b/graphs/greedy_best_first.py index 674ffe96f601..cffe40b08994 100644 --- a/graphs/greedy_best_first.py +++ b/graphs/greedy_best_first.py @@ -6,15 +6,33 @@ Path = list[tuple[int, int]] -grid = [ - [0, 0, 0, 0, 0, 0, 0], - [0, 1, 0, 0, 0, 0, 0], # 0 are free path whereas 1's are obstacles - [0, 0, 0, 0, 0, 0, 0], - [0, 0, 1, 0, 0, 0, 0], - [1, 0, 1, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 1, 0, 0], -] +# 0 are free path whereas 1's are obstacles +TEST_GRIDS = [ + [ + [0, 0, 0, 0, 0, 0, 0], + [0, 1, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 1, 0, 0, 0, 0], + [1, 0, 1, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 1, 0, 0], + ], + [ + [0, 0, 0, 1, 1, 0, 0], + [0, 0, 0, 0, 1, 0, 1], + [0, 0, 0, 1, 1, 0, 0], + [0, 1, 0, 0, 1, 0, 0], + [1, 0, 0, 1, 1, 0, 1], + [0, 0, 0, 0, 0, 0, 0] + ], + [ + [0, 0, 1, 0, 0], + [0, 1, 0, 0, 0], + [0, 0, 1, 0, 1], + [1, 0, 0, 1, 1], + [0, 0, 0, 0, 0] + ] +] delta = ([-1, 0], [0, -1], [1, 0], [0, 1]) # up, left, down, right @@ -82,7 +100,8 @@ class GreedyBestFirst: (6, 2), (6, 3), (5, 3), (5, 4), (5, 5), (6, 5), (6, 6)] """ - def __init__(self, start: tuple[int, int], goal: tuple[int, int]): + def __init__(self, grid: list[list[int]], start: tuple[int, int], goal: tuple[int, int]): + self.grid = grid self.start = Node(start[1], start[0], goal[1], goal[0], 0, None) self.target = Node(goal[1], goal[0], goal[1], goal[0], 99999, None) @@ -136,9 +155,9 @@ def get_successors(self, parent: Node) -> list[Node]: pos_x = parent.pos_x + action[1] pos_y = parent.pos_y + action[0] - if (0 <= pos_x <= len(grid[0]) - 1 - and 0 <= pos_y <= len(grid) - 1 - and grid[pos_y][pos_x] == 0): + if (0 <= pos_x <= len(self.grid[0]) - 1 + and 0 <= pos_y <= len(self.grid) - 1 + and self.grid[pos_y][pos_x] == 0): successors.append( Node( @@ -166,18 +185,21 @@ def retrace_path(self, node: Node | None) -> Path: if __name__ == "__main__": - init = (0, 0) - goal = (len(grid) - 1, len(grid[0]) - 1) - for elem in grid: - print(elem) - - print("------") - - greedy_bf = GreedyBestFirst(init, goal) - path = greedy_bf.search() - if path: - for pos_x, pos_y in path: - grid[pos_x][pos_y] = 2 + for idx, grid in enumerate(TEST_GRIDS): + print(f"==grid-{idx + 1}==") + init = (0, 0) + goal = (len(grid) - 1, len(grid[0]) - 1) for elem in grid: print(elem) + + print("------") + + greedy_bf = GreedyBestFirst(grid, init, goal) + path = greedy_bf.search() + if path: + for pos_x, pos_y in path: + grid[pos_x][pos_y] = 2 + + for elem in grid: + print(elem) From 28a8c2b16f7021f13a87ffb53f7c33b639376f87 Mon Sep 17 00:00:00 2001 From: JadeKim042386 Date: Sat, 27 May 2023 16:30:54 +0900 Subject: [PATCH 04/10] fix: add \_\_eq\_\_ in Node class #8770 --- graphs/greedy_best_first.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/graphs/greedy_best_first.py b/graphs/greedy_best_first.py index cffe40b08994..a49a238436e3 100644 --- a/graphs/greedy_best_first.py +++ b/graphs/greedy_best_first.py @@ -82,6 +82,9 @@ def calculate_heuristic(self) -> float: def __lt__(self, other) -> bool: return self.f_cost < other.f_cost + + def __eq__(self, other): + return self.pos == other.pos class GreedyBestFirst: From 36e4db563aa8c01041133c496348679507e3c231 Mon Sep 17 00:00:00 2001 From: JadeKim042386 Date: Sat, 27 May 2023 16:31:48 +0900 Subject: [PATCH 05/10] fix: delete unnecessary code - node in self.open_nodes is always better node #8770 --- graphs/greedy_best_first.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/graphs/greedy_best_first.py b/graphs/greedy_best_first.py index a49a238436e3..a685ec6f859b 100644 --- a/graphs/greedy_best_first.py +++ b/graphs/greedy_best_first.py @@ -136,14 +136,6 @@ def search(self) -> Path | None: if child_node not in self.open_nodes: self.open_nodes.append(child_node) - else: - # retrieve the best current path - better_node = self.open_nodes.pop(self.open_nodes.index(child_node)) - - if child_node.g_cost < better_node.g_cost: - self.open_nodes.append(child_node) - else: - self.open_nodes.append(better_node) if not self.reached: return [self.start.pos] From 0aed998356a681615c98e643489023ee1022b1c9 Mon Sep 17 00:00:00 2001 From: JadeKim042386 Date: Sat, 27 May 2023 16:33:41 +0900 Subject: [PATCH 06/10] fix: docstring --- graphs/greedy_best_first.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/graphs/greedy_best_first.py b/graphs/greedy_best_first.py index a685ec6f859b..66ebcfb90695 100644 --- a/graphs/greedy_best_first.py +++ b/graphs/greedy_best_first.py @@ -89,7 +89,8 @@ def __eq__(self, other): class GreedyBestFirst: """ - >>> gbf = GreedyBestFirst((0, 0), (len(grid) - 1, len(grid[0]) - 1)) + >>> grid = [[0, 0, 1, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 1], [1, 0, 0, 1, 1], [0, 0, 0, 0, 0]] + >>> gbf = GreedyBestFirst(grid, (0, 0), (len(grid) - 1, len(grid[0]) - 1)) >>> [x.pos for x in gbf.get_successors(gbf.start)] [(1, 0), (0, 1)] >>> (gbf.start.pos_y + delta[3][0], gbf.start.pos_x + delta[3][1]) @@ -99,8 +100,8 @@ class GreedyBestFirst: >>> gbf.retrace_path(gbf.start) [(0, 0)] >>> gbf.search() # doctest: +NORMALIZE_WHITESPACE - [(0, 0), (1, 0), (2, 0), (3, 0), (3, 1), (4, 1), (5, 1), (6, 1), - (6, 2), (6, 3), (5, 3), (5, 4), (5, 5), (6, 5), (6, 6)] + [(0, 0), (1, 0), (2, 0), (2, 1), (3, 1), (4, 1), (4, 2), (4, 3), + (4, 4)] """ def __init__(self, grid: list[list[int]], start: tuple[int, int], goal: tuple[int, int]): From 6504c31745e7cacb0525e5bb3d57007e62da189c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 27 May 2023 07:39:16 +0000 Subject: [PATCH 07/10] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- graphs/greedy_best_first.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/graphs/greedy_best_first.py b/graphs/greedy_best_first.py index 66ebcfb90695..177b78769082 100644 --- a/graphs/greedy_best_first.py +++ b/graphs/greedy_best_first.py @@ -10,7 +10,7 @@ TEST_GRIDS = [ [ [0, 0, 0, 0, 0, 0, 0], - [0, 1, 0, 0, 0, 0, 0], + [0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0], [1, 0, 1, 0, 0, 0, 0], @@ -23,16 +23,16 @@ [0, 0, 0, 1, 1, 0, 0], [0, 1, 0, 0, 1, 0, 0], [1, 0, 0, 1, 1, 0, 1], - [0, 0, 0, 0, 0, 0, 0] + [0, 0, 0, 0, 0, 0, 0], ], [ [0, 0, 1, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 1], [1, 0, 0, 1, 1], - [0, 0, 0, 0, 0] - ] -] + [0, 0, 0, 0, 0], + ], +] delta = ([-1, 0], [0, -1], [1, 0], [0, 1]) # up, left, down, right @@ -82,7 +82,7 @@ def calculate_heuristic(self) -> float: def __lt__(self, other) -> bool: return self.f_cost < other.f_cost - + def __eq__(self, other): return self.pos == other.pos @@ -104,7 +104,9 @@ class GreedyBestFirst: (4, 4)] """ - def __init__(self, grid: list[list[int]], start: tuple[int, int], goal: tuple[int, int]): + def __init__( + self, grid: list[list[int]], start: tuple[int, int], goal: tuple[int, int] + ): self.grid = grid self.start = Node(start[1], start[0], goal[1], goal[0], 0, None) self.target = Node(goal[1], goal[0], goal[1], goal[0], 99999, None) @@ -151,10 +153,11 @@ def get_successors(self, parent: Node) -> list[Node]: pos_x = parent.pos_x + action[1] pos_y = parent.pos_y + action[0] - if (0 <= pos_x <= len(self.grid[0]) - 1 + if ( + 0 <= pos_x <= len(self.grid[0]) - 1 and 0 <= pos_y <= len(self.grid) - 1 - and self.grid[pos_y][pos_x] == 0): - + and self.grid[pos_y][pos_x] == 0 + ): successors.append( Node( pos_x, From 3ccf2853174ce6159a71d0c3b322099135ccaea3 Mon Sep 17 00:00:00 2001 From: JadeKim042386 Date: Sat, 27 May 2023 16:53:00 +0900 Subject: [PATCH 08/10] fix: docstring max length --- graphs/greedy_best_first.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphs/greedy_best_first.py b/graphs/greedy_best_first.py index 177b78769082..3188cb5a8b56 100644 --- a/graphs/greedy_best_first.py +++ b/graphs/greedy_best_first.py @@ -89,7 +89,7 @@ def __eq__(self, other): class GreedyBestFirst: """ - >>> grid = [[0, 0, 1, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 1], [1, 0, 0, 1, 1], [0, 0, 0, 0, 0]] + >>> grid = TEST_GRIDS[2] >>> gbf = GreedyBestFirst(grid, (0, 0), (len(grid) - 1, len(grid[0]) - 1)) >>> [x.pos for x in gbf.get_successors(gbf.start)] [(1, 0), (0, 1)] From c63a974c49b0857a70dc09f6799935b81028e715 Mon Sep 17 00:00:00 2001 From: JadeKim042386 Date: Tue, 15 Aug 2023 19:36:29 +0900 Subject: [PATCH 09/10] refactor: get the successors using a list comprehension --- graphs/greedy_best_first.py | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/graphs/greedy_best_first.py b/graphs/greedy_best_first.py index 3188cb5a8b56..ac70815499da 100644 --- a/graphs/greedy_best_first.py +++ b/graphs/greedy_best_first.py @@ -148,27 +148,22 @@ def get_successors(self, parent: Node) -> list[Node]: """ Returns a list of successors (both in the grid and free spaces) """ - successors = [] - for action in delta: - pos_x = parent.pos_x + action[1] - pos_y = parent.pos_y + action[0] - + return [ + Node( + pos_x, + pos_y, + self.target.pos_x, + self.target.pos_y, + parent.g_cost + 1, + parent, + ) + for action in delta if ( - 0 <= pos_x <= len(self.grid[0]) - 1 - and 0 <= pos_y <= len(self.grid) - 1 + 0 <= (pos_x := parent.pos_x + action[1]) < len(self.grid[0]) + and 0 <= (pos_y := parent.pos_y + action[0]) < len(self.grid) and self.grid[pos_y][pos_x] == 0 - ): - successors.append( - Node( - pos_x, - pos_y, - self.target.pos_x, - self.target.pos_y, - parent.g_cost + 1, - parent, - ) - ) - return successors + ) + ] def retrace_path(self, node: Node | None) -> Path: """ From 7a865eac31814c616e0991f4a4486a840b8e2f02 Mon Sep 17 00:00:00 2001 From: Tianyi Zheng Date: Tue, 15 Aug 2023 15:49:11 -0700 Subject: [PATCH 10/10] Apply suggestions from code review --- graphs/greedy_best_first.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/graphs/greedy_best_first.py b/graphs/greedy_best_first.py index ac70815499da..bb3160047e34 100644 --- a/graphs/greedy_best_first.py +++ b/graphs/greedy_best_first.py @@ -6,7 +6,7 @@ Path = list[tuple[int, int]] -# 0 are free path whereas 1's are obstacles +# 0's are free path whereas 1's are obstacles TEST_GRIDS = [ [ [0, 0, 0, 0, 0, 0, 0], @@ -83,7 +83,7 @@ def calculate_heuristic(self) -> float: def __lt__(self, other) -> bool: return self.f_cost < other.f_cost - def __eq__(self, other): + def __eq__(self, other) -> bool: return self.pos == other.pos