Experiment - 6
Experiment - 6
First, we will traverse the nodes that are directly connected to 0. Those are {1, 2,
3}. If node x is part of {1, 2, 3}, we stop. If not, we continue traversing the graph.
Next, we consider the set of nodes that are connected to or previous set {1, 2, 3}.
Those would be {4, 5, 6}. Nodes 4 and 5 are connected to node 1 and node 6 is
connected to node 3. We look for node x again and then we stop becausre there
aren’t any more nodes.
If the graph was larger, we would continue traversing the graph by considering the
nodes connected to {4, 5, 6} and so on.
See that this order of traversal guarantees that we find the shortest path between
node 0 and node x because we start by searching the nodes that are one edge away
from node1, then those that are two edges distant, and so on.
Graph representation
We will represent our graph as a dictionary, mapping each node to the set of the
nodes it is connected to.
For example, let’s consider the following graph.
Source: Wikipedia
In this graph, node 4 is connected to nodes 3, 5, and 6. Our graph dictionary would
then have the following key: value pair:
graph[4] = {3, 5, 6}
We would have similar key: value pairs for each one of the nodes in the graph.
Our BFS function will take a graph dictionary, and two node ids (node1 and node2).
For this tutorial, each graph will be identified using integer numbers (1, 2, etc).
Function output
The function will return a list of nodes that connect node1 and node2, starting
with node1 and including node2: [node1, node_x, node_y, ..., node2]. This
list will be the shortest path between node1 and node2.
If there is more than one possible shortest path, it will return any of them.
We return the trivial path [node1] for the case node1 == node2.
Variable path_index keeps track of the path that we’re currently following. We stop
the loop when we reach the end of path_list.
At all times, we have a shortest path from node1 to last_node. Based on this path,
we can find the path from node1 to node2 if node2 is connected to last_node.
The order in which new paths are added to path_list guarantees that we traverse
the graph in breadth first order.
Verification
Let’s check our algorithm with the graph shared at the beginning of this post.
We create a graph dictionary.
graph = {}
graph[1] = {2, 5}
graph[2] = {1, 3, 5}
graph[3] = {2, 4}
graph[4] = {3, 5, 6}
graph[5] = {1, 2, 4}
graph[6] = {4}
>>> shortest_path(graph, 1, 6)
[1, 5, 4, 6]