Skip to content

Commit 6d4925d

Browse files
committed
Fixed B* (I think), removed Forbidden nodes.
1 parent 69f268d commit 6d4925d

File tree

7 files changed

+83
-66
lines changed

7 files changed

+83
-66
lines changed

README.md

+6-4
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,8 @@ While an algorithm isn't running:
3636
- Press <kbd>Q</kbd> to exit
3737
- Press <kbd>C</kbd> to clear grid
3838
- Press <kbd>G</kbd> to generate a new maze
39-
- <kbd>Left Shift</kbd> + <kbd>Left Click</kbd> to place a forbbiden node after placing Start and End nodes
4039
- <kbd>Left Click</kbd> to place Start, then End, then Obstacles
41-
- <kbd>Right Click</kbd> to remove Start, End, Forbbiden nodes, or Obstacles
40+
- <kbd>Right Click</kbd> to remove Start, End, or Obstacles
4241

4342
After an algorithm has run:
4443

@@ -59,7 +58,6 @@ The testing will take longer as the visitable nodes increases. For my system, an
5958
- Start: where the search algorithm will start
6059
- End: where the search algorithm is trying to get to
6160
- Obstacle: a position the algorithms avoid
62-
- Forbidden: a position certain algorithms avoid (a different type of obstacle)
6361
- Check/Uncheck: markup for visualizing the algorithm
6462
- Path: markup for visualizing the found path
6563
- Default: a position that can be traversed
@@ -118,4 +116,8 @@ Planned algorithms (Going to look at them):
118116
- Viterbi algorithm
119117
120118
- Yen's k-Shortest Paths
121-
```
119+
```
120+
121+
Possible Incorrectly Implemented algorithms:
122+
123+
- [B*](./resources/b_star.pdf)

main/Testing.py

+5-20
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ def __init__(self, *argv: list):
6565
wr = csv.writer(myfile, delimiter=',',
6666
quotechar='|', quoting=csv.QUOTE_MINIMAL)
6767

68-
wr.writerow(['Algorithm', 'Local Run Time', 'Times Nodes Checked'])
69-
algo_data: list = [['', '', len(get_unvisited_nodes(self.start))]]
68+
wr.writerow(['Algorithm', 'Local Run Time', 'Times Nodes Checked', 'Path Length'])
69+
algo_data: list = [['', '', len(get_unvisited_nodes(self.start)), '']]
7070

7171
for alg in ALGORITHMS:
7272
# Clear grid after every run
@@ -98,24 +98,10 @@ def __init__(self, *argv: list):
9898
wr.writerows(algo_data)
9999

100100

101-
def get_num_nodes(self, start: object):
102-
checked_nodes = []
103-
to_check = [start]
104-
num_nodes = 0
105-
106-
while to_check:
107-
print(to_check)
108-
current = to_check.pop(0)
109-
num_nodes += 1
110-
for neighbor in current.neighbors:
111-
if not neighbor in checked_nodes and neighbor not in to_check:
112-
to_check.append(neighbor)
113-
return num_nodes
114-
115101
def clear_grid(self, current_grid: list, rows: int, width: int):
116102
"""
117103
Clear the grid by creating a new 2D list of Node objects,
118-
keeping the start, end, obstacles and forbidden nodes from the
104+
keeping the start, end, and obstacles nodes from the
119105
original grid.
120106
121107
Parameters:
@@ -135,14 +121,13 @@ def clear_grid(self, current_grid: list, rows: int, width: int):
135121
for i in range(rows):
136122
grid.append([])
137123
for j in range(rows):
138-
# If the current node is not the start, end, an obstacle or
139-
# forbidden, create a new Node object for the current position
124+
# If the current node is not the start, end, or an obstacle
125+
# create a new Node object for the current position
140126
# and add it to the grid
141127
if (
142128
not current_grid[i][j].is_start()
143129
and not current_grid[i][j].is_end()
144130
and not current_grid[i][j].is_obstacle()
145-
and not current_grid[i][j].is_forbidden()
146131
):
147132
node = Node(i, j, node_width, rows)
148133
grid[i].append(node)

main/algorithms/BStar.py

+26-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,28 @@
11
import pygame
22
from queue import PriorityQueue
3-
from .RP import reconstruct_path, heuristic, check
3+
from .RP import reconstruct_path, check
4+
5+
# Manhattan distance
6+
def heuristic(node1: object, node2: object):
7+
"""
8+
Calculate the Dynamic Manhattan distance between two nodes.
9+
10+
Parameters:
11+
node1 (Node): The first node.
12+
node2 (Node): The second node.
13+
14+
Returns:
15+
int: The Dynamic Manhattan distance between the two nodes.
16+
"""
17+
x1, y1 = node1.get_pos()
18+
x2, y2 = node2.get_pos()
19+
20+
blocked_penalty = len(node1.neighbors)
21+
for node in node1.neighbors:
22+
if not node.is_checked() and not node.is_unchecked():
23+
blocked_penalty -= 1
24+
25+
return abs(x1 - x2) + abs(y1 - y2) + blocked_penalty
426

527

628
def b_star(draw: object, grid: list, start: object, end: object):
@@ -27,7 +49,7 @@ def b_star(draw: object, grid: list, start: object, end: object):
2749
g_score = {node: float("inf") for row in grid for node in row}
2850
g_score[start] = 0
2951
f_score = {node: float("inf") for row in grid for node in row}
30-
f_score[start] = heuristic("manhattan", start, end)
52+
f_score[start] = heuristic(start, end)
3153

3254
# Initialize a set to store the nodes in the open set
3355
open_set_hash = {start}
@@ -60,11 +82,10 @@ def b_star(draw: object, grid: list, start: object, end: object):
6082
if temp_g_score < g_score[neighbor]:
6183
came_from[neighbor] = current
6284
g_score[neighbor] = temp_g_score
63-
f_score[neighbor] = temp_g_score + heuristic("manhattan", neighbor, end)
85+
f_score[neighbor] = temp_g_score + heuristic(neighbor, end)
6486

6587
# Add the neighbor to the open set if it is not already there
66-
# and the neighbor isn't marked as forbidden
67-
if neighbor not in open_set_hash and not neighbor.is_forbidden():
88+
if neighbor not in open_set_hash:
6889
count += 1
6990
open_set.put((f_score[neighbor], count, neighbor))
7091
open_set_hash.add(neighbor)

main/node.py

-7
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
START = COLORS.get("ORANGE")
1111
END = COLORS.get("TURQUOISE")
1212
PATH = COLORS.get("PURPLE")
13-
FORBID = COLORS.get("GREY")
1413

1514

1615
class Node:
@@ -67,9 +66,6 @@ def is_start(self):
6766
def is_end(self):
6867
return self.color == END
6968

70-
def is_forbidden(self):
71-
return self.color == FORBID
72-
7369
# Setting node states
7470
def check(self):
7571
"""
@@ -107,9 +103,6 @@ def make_color(self, color: tuple):
107103
"""
108104
self.color = color
109105

110-
def make_forbbiden(self):
111-
self.color = FORBID
112-
113106
def mult_check(self, dec: int):
114107
"""
115108
Changes the color of a checked node that has been checked multiple times.

main/pathfinding.py

+3-8
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def make_grid(rows: int, width: int):
3737
def clear_grid(current_grid: list, rows: int, width: int):
3838
"""
3939
Clear the grid by creating a new 2D list of Node objects,
40-
keeping the start, end, obstacles and forbidden nodes from the
40+
keeping the start, end, and obstacles nodes from the
4141
original grid.
4242
4343
Parameters:
@@ -57,14 +57,12 @@ def clear_grid(current_grid: list, rows: int, width: int):
5757
for i in range(rows):
5858
grid.append([])
5959
for j in range(rows):
60-
# If the current node is not the start, end, an obstacle or
61-
# forbidden, create a new Node object for the current position
62-
# and add it to the grid
60+
# If the current node is not the start, end, or an obstacle, create a new Node
61+
# object for the current position and add it to the grid
6362
if (
6463
not current_grid[i][j].is_start()
6564
and not current_grid[i][j].is_end()
6665
and not current_grid[i][j].is_obstacle()
67-
and not current_grid[i][j].is_forbidden()
6866
):
6967
node = Node(i, j, node_width, rows)
7068
grid[i].append(node)
@@ -282,9 +280,6 @@ def main(argv: list):
282280
end = node
283281
end.make_end()
284282
elif node != start and node != end:
285-
if pygame.key.get_mods() & pygame.K_LSHIFT:
286-
node.make_forbbiden()
287-
else:
288283
node.make_obstacle()
289284

290285
# Right mouse click

main/testing/BStar.py

+26-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,27 @@
11
from queue import PriorityQueue
2-
from .RP import heuristic
2+
3+
4+
# Manhattan distance
5+
def heuristic(node1: object, node2: object):
6+
"""
7+
Calculate the Dynamic Manhattan distance between two nodes.
8+
9+
Parameters:
10+
node1 (Node): The first node.
11+
node2 (Node): The second node.
12+
13+
Returns:
14+
int: The Dynamic Manhattan distance between the two nodes.
15+
"""
16+
x1, y1 = node1.get_pos()
17+
x2, y2 = node2.get_pos()
18+
19+
blocked_penalty = len(node1.neighbors)
20+
for node in node1.neighbors:
21+
if not node.is_checked() and not node.is_unchecked():
22+
blocked_penalty -= 1
23+
24+
return abs(x1 - x2) + abs(y1 - y2) + blocked_penalty
325

426

527
def b_star(grid: list, start: object, end: object):
@@ -25,7 +47,7 @@ def b_star(grid: list, start: object, end: object):
2547
g_score = {node: float("inf") for row in grid for node in row}
2648
g_score[start] = 0
2749
f_score = {node: float("inf") for row in grid for node in row}
28-
f_score[start] = heuristic("manhattan", start, end)
50+
f_score[start] = heuristic(start, end)
2951

3052
# Initialize a set to store the nodes in the open set
3153
open_set_hash = {start}
@@ -54,11 +76,10 @@ def b_star(grid: list, start: object, end: object):
5476
if temp_g_score < g_score[neighbor]:
5577
came_from[neighbor] = current
5678
g_score[neighbor] = temp_g_score
57-
f_score[neighbor] = temp_g_score + heuristic("manhattan", neighbor, end)
79+
f_score[neighbor] = temp_g_score + heuristic(neighbor, end)
5880

5981
# Add the neighbor to the open set if it is not already there
60-
# and the neighbor isn't marked as forbidden
61-
if neighbor not in open_set_hash and not neighbor.is_forbidden():
82+
if neighbor not in open_set_hash:
6283
count += 1
6384
open_set.put((f_score[neighbor], count, neighbor))
6485
open_set_hash.add(neighbor)
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
Algorithm,Local Run Time,Times Nodes Checked
2-
,,1163
3-
astar,0.0019658000019262545,124
4-
beam,0.0003242999991925899,101
5-
bellford,1.1534317000005103,1352569
6-
bestfs,0.0008029999989958014,124
7-
bfs,0.0009060999982466456,679
8-
bisearch,0.00019459999748505652,358
9-
bstar,0.002126800001860829,124
10-
dfs,0.0013380999989749398,1120
11-
dijkstra,0.14483109999855515,713
12-
floyd,232.8206220000029,1574390316
13-
gbfs,0.0006450000000768341,101
14-
gbls,0.0008083000029728282,98
15-
ida,0.0016050999984145164,192
16-
iddfs,0.017313199998170603,16276
17-
lbfs,0.001781999999366235,2326
18-
rand,0.011425200002122438,11573
2+
,,1167
3+
astar,0.0030056999985390576,353
4+
beam,0.001310100000409875,400
5+
bellford,1.1081830999992235,1361889
6+
bestfs,0.002110999999786145,353
7+
bfs,0.0012076000002707588,1000
8+
bisearch,0.00026840000100492034,554
9+
bstar,0.003316300000733463,353
10+
dfs,0.0009766000002855435,846
11+
dijkstra,0.14303250000011758,1017
12+
floyd,245.82318180000038,1590686352
13+
gbfs,0.0020392000005813316,401
14+
gbls,0.00287439999920025,315
15+
ida,0.007990200001586345,1234
16+
iddfs,0.044287400000030175,36801
17+
lbfs,0.002202099998612539,2334
18+
rand,0.21115649999956076,230522

0 commit comments

Comments
 (0)