mirror of
https://github.com/TheAlgorithms/Python.git
synced 2025-01-18 16:27:02 +00:00
Add docstr and algorithm to BFS shortest path module (#1637)
* Add docs and type alias to bfs_shortest_path.py * Add bfs_shortest_path_distance algorithm * Make requested changes
This commit is contained in:
parent
86dbf0a9d3
commit
5f57ac975f
|
@ -1,3 +1,11 @@
|
||||||
|
"""Breadth-first search shortest path implementations.
|
||||||
|
|
||||||
|
doctest:
|
||||||
|
python -m doctest -v bfs_shortest_path.py
|
||||||
|
|
||||||
|
Manual test:
|
||||||
|
python bfs_shortest_path.py
|
||||||
|
"""
|
||||||
graph = {
|
graph = {
|
||||||
"A": ["B", "C", "E"],
|
"A": ["B", "C", "E"],
|
||||||
"B": ["A", "D", "E"],
|
"B": ["A", "D", "E"],
|
||||||
|
@ -9,7 +17,22 @@ graph = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def bfs_shortest_path(graph, start, goal):
|
def bfs_shortest_path(graph: dict, start, goal) -> str:
|
||||||
|
"""Find shortest path between `start` and `goal` nodes.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
graph (dict): node/list of neighboring nodes key/value pairs.
|
||||||
|
start: start node.
|
||||||
|
goal: target node.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Shortest path between `start` and `goal` nodes as a string of nodes.
|
||||||
|
'Not found' string if no path found.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
>>> bfs_shortest_path(graph, "G", "D")
|
||||||
|
['G', 'C', 'A', 'B', 'D']
|
||||||
|
"""
|
||||||
# keep track of explored nodes
|
# keep track of explored nodes
|
||||||
explored = []
|
explored = []
|
||||||
# keep track of all the paths to be checked
|
# keep track of all the paths to be checked
|
||||||
|
@ -44,4 +67,48 @@ def bfs_shortest_path(graph, start, goal):
|
||||||
return "So sorry, but a connecting path doesn't exist :("
|
return "So sorry, but a connecting path doesn't exist :("
|
||||||
|
|
||||||
|
|
||||||
bfs_shortest_path(graph, "G", "D") # returns ['G', 'C', 'A', 'B', 'D']
|
def bfs_shortest_path_distance(graph: dict, start, target) -> int:
|
||||||
|
"""Find shortest path distance between `start` and `target` nodes.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
graph: node/list of neighboring nodes key/value pairs.
|
||||||
|
start: node to start search from.
|
||||||
|
target: node to search for.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Number of edges in shortest path between `start` and `target` nodes.
|
||||||
|
-1 if no path exists.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
>>> bfs_shortest_path_distance(graph, "G", "D")
|
||||||
|
4
|
||||||
|
>>> bfs_shortest_path_distance(graph, "A", "A")
|
||||||
|
0
|
||||||
|
>>> bfs_shortest_path_distance(graph, "A", "H")
|
||||||
|
-1
|
||||||
|
"""
|
||||||
|
if not graph or start not in graph or target not in graph:
|
||||||
|
return -1
|
||||||
|
if start == target:
|
||||||
|
return 0
|
||||||
|
queue = [start]
|
||||||
|
visited = [start]
|
||||||
|
# Keep tab on distances from `start` node.
|
||||||
|
dist = {start: 0, target: -1}
|
||||||
|
while queue:
|
||||||
|
node = queue.pop(0)
|
||||||
|
if node == target:
|
||||||
|
dist[target] = (
|
||||||
|
dist[node] if dist[target] == -1 else min(dist[target], dist[node])
|
||||||
|
)
|
||||||
|
for adjacent in graph[node]:
|
||||||
|
if adjacent not in visited:
|
||||||
|
visited.append(adjacent)
|
||||||
|
queue.append(adjacent)
|
||||||
|
dist[adjacent] = dist[node] + 1
|
||||||
|
return dist[target]
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print(bfs_shortest_path(graph, "G", "D")) # returns ['G', 'C', 'A', 'B', 'D']
|
||||||
|
print(bfs_shortest_path_distance(graph, "G", "D")) # returns 4
|
||||||
|
|
Loading…
Reference in New Issue
Block a user