Skip to content

Commit 5f57ac9

Browse files
kylepwcclauss
authored andcommitted
Add docstr and algorithm to BFS shortest path module (TheAlgorithms#1637)
* Add docs and type alias to bfs_shortest_path.py * Add bfs_shortest_path_distance algorithm * Make requested changes
1 parent 86dbf0a commit 5f57ac9

File tree

1 file changed

+69
-2
lines changed

1 file changed

+69
-2
lines changed

graphs/bfs_shortest_path.py

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
"""Breadth-first search shortest path implementations.
2+
3+
doctest:
4+
python -m doctest -v bfs_shortest_path.py
5+
6+
Manual test:
7+
python bfs_shortest_path.py
8+
"""
19
graph = {
210
"A": ["B", "C", "E"],
311
"B": ["A", "D", "E"],
@@ -9,7 +17,22 @@
917
}
1018

1119

12-
def bfs_shortest_path(graph, start, goal):
20+
def bfs_shortest_path(graph: dict, start, goal) -> str:
21+
"""Find shortest path between `start` and `goal` nodes.
22+
23+
Args:
24+
graph (dict): node/list of neighboring nodes key/value pairs.
25+
start: start node.
26+
goal: target node.
27+
28+
Returns:
29+
Shortest path between `start` and `goal` nodes as a string of nodes.
30+
'Not found' string if no path found.
31+
32+
Example:
33+
>>> bfs_shortest_path(graph, "G", "D")
34+
['G', 'C', 'A', 'B', 'D']
35+
"""
1336
# keep track of explored nodes
1437
explored = []
1538
# keep track of all the paths to be checked
@@ -44,4 +67,48 @@ def bfs_shortest_path(graph, start, goal):
4467
return "So sorry, but a connecting path doesn't exist :("
4568

4669

47-
bfs_shortest_path(graph, "G", "D") # returns ['G', 'C', 'A', 'B', 'D']
70+
def bfs_shortest_path_distance(graph: dict, start, target) -> int:
71+
"""Find shortest path distance between `start` and `target` nodes.
72+
73+
Args:
74+
graph: node/list of neighboring nodes key/value pairs.
75+
start: node to start search from.
76+
target: node to search for.
77+
78+
Returns:
79+
Number of edges in shortest path between `start` and `target` nodes.
80+
-1 if no path exists.
81+
82+
Example:
83+
>>> bfs_shortest_path_distance(graph, "G", "D")
84+
4
85+
>>> bfs_shortest_path_distance(graph, "A", "A")
86+
0
87+
>>> bfs_shortest_path_distance(graph, "A", "H")
88+
-1
89+
"""
90+
if not graph or start not in graph or target not in graph:
91+
return -1
92+
if start == target:
93+
return 0
94+
queue = [start]
95+
visited = [start]
96+
# Keep tab on distances from `start` node.
97+
dist = {start: 0, target: -1}
98+
while queue:
99+
node = queue.pop(0)
100+
if node == target:
101+
dist[target] = (
102+
dist[node] if dist[target] == -1 else min(dist[target], dist[node])
103+
)
104+
for adjacent in graph[node]:
105+
if adjacent not in visited:
106+
visited.append(adjacent)
107+
queue.append(adjacent)
108+
dist[adjacent] = dist[node] + 1
109+
return dist[target]
110+
111+
112+
if __name__ == "__main__":
113+
print(bfs_shortest_path(graph, "G", "D")) # returns ['G', 'C', 'A', 'B', 'D']
114+
print(bfs_shortest_path_distance(graph, "G", "D")) # returns 4

0 commit comments

Comments
 (0)