How do you find the length of the shortest path between two nodes in an unweighted graph?
Run a breadth first search from the start node, recording the distance to each node as you discover it. The distance of a neighbour is one more than the distance of the node that found it, and the answer for the goal falls out of the search.
from collections import deque
def shortest_path_length(graph, start, goal):
distance = {start: 0}
queue = deque([start])
while queue:
node = queue.popleft()
if node == goal:
return distance[node]
for neighbour in graph[node]:
if neighbour not in distance:
distance[neighbour] = distance[node] + 1
queue.append(neighbour)
return -1
graph = {"A": ["B", "C"], "B": ["D"], "C": ["D", "E"], "D": [], "E": []}
print(shortest_path_length(graph, "A", "E"))The output is 2. The route A to C to E has two edges, while the route through B and D has three, so the shorter one wins.
The mechanism is that breadth first search processes nodes in order of their distance from the start, so the first time a node is discovered it has been reached by a shortest path. The distance map doubles as the visited set, which is why there is no separate visited structure.
The trade-off to name is that this only works because every edge has the same cost. With weighted edges you need Dijkstra or a breadth first search over the expanded state space, and the ordering guarantee disappears. The other detail is that the search can stop as soon as the goal is reached, but if you also want the distances to every other node you have to let it run to the end.