Implementing Breadth-First Search
Distance, precisely
Here’s the algorithm we ended up with last time:
function distance(start, end):
distance to start = 0
to-visit = [start]
while nodes in to-visit:
node = first node from to-visit
for neighbor in neighbors:
if we haven't yet set neighbor's distance:
distance to neighbor = distance to node + 1
if neighbor == end:
return distance to neighbor
add neighbor to to-visit
return Infinity
How can we make this a bit more concrete? We’ll need to figure out how to track the
distances, and what data structure to use as the to-visit queue.
One possibility (among others!) would be to use a dictionary for the distances and a list for the queue. Then we could write something like this:
function distance(graph, start, end):
distances = {start: 0}
to-visit = [start]
while not to-visit is empty:
node = to-visit.head
to-visit = to-visit.tail
for neighbor in graph.neighbors(start):
if neighbor not in distances:
distances[neighbor] = distance[node] + 1
if neighbor == end:
return distances[neighbor]
to-visit = to-visit + [neighbor]
return Infinity
Implementing distance
In order to implement our distance algorithm, we need a graph! We could
implement it on the social graph included with the project; I’m implementing it
with a FlightGraph class I’ve made for this purpose. Our Scala implementation
ends up looking like this:
def distance(graph: FlightGraph, start: String, end: String): Int = { var distances = Map(start -> 0) var visit = List(start) while (!visit.isEmpty) { val node = visit.head visit = visit.tail for (neighbor <- graph.neighbors(node)) { if (!distances.contains(neighbor)) { distances = distances + (neighbor -> (distances(node) + 1)) if (neighbor == end) { return distances(neighbor) } visit = visit :+ neighbor } } } -1 }
The breadth-first search algorithm we see here can be used to solve any problem where we need to visit all of the nodes we can get to from a starting node, in order of how far away we are. The important properties of breadth-first search are that:
- It visits every node in order of the number of edges it is from the starting
node (this is guaranteed by the
visitqueue) - It only visits a node once (this is guaranteed by the
if (!distances.contains(neighbor))check).