Breadth-First Search
Graph Algorithm Type #3
Depth-First Search
More Orderly Technique?
Breadth First Search (BFS)
int main () { Node *sourceNode = getNodebyID (sourceID); bool found = bfsPath (sourceNode, destID); . . . }
bool bfsPath (Node* sourceNode, int destID) { ...}
source
dest
start – 0 hops
1 hop away
2 hops away
3 hops away
Breadth First Searchbool bfsPath (Node* sourceNode, int destID) { list<Node *> wavefront; wavefront.push_back (sourceNode);
while (wavefront not empty) { Node *currNode = wavefront.front (); wavefront.pop_front(); // Remove node from wavefront
if (currNode->id == destID) return (true);
for each (outEdge of currNode) { Node *toNode = outEdge.toNode; wavefront.push_back (toNode); } } return (false); // No path exits!}
source
dest
0
1 2
3 4
5
wavefront = {0}
{1, 2}
{2, 3} {3,4,3}
{4,3,5}
{5}
wavefront = {}
{2}
{3} {4,3}
{3,5}{5,5} {5}
BFS: How Do I Print Out the Path?
source
dest
bool bfsPath (Node* sourceNode, int destID) { list<Node *> wavefront; wavefront.push_back (sourceNode);
while (wavefront not empty) { Node *currNode = wavefront.front (); wavefront.pop_front(); // Remove node from wavefront
if (currNode->id == destID) return (true);
for each (outEdge of currNode) { Node *toNode = outEdge.toNode; wavefront.push_back (toNode); } } return (false); // No path exits!}
0
1 2
3 4
5
wavefront = {0}
{1, 2}
{2, 3} {3,4,3}
{4,3,5}
{5}
wavefront = {}
{2}
{3} {4,3}
{3,5}What do I know here?{5,5} {5}
BFS: How Do I Print Out the Path?Need more information!
struct waveElem { Node *node; int edgeID; // ID of edge used to reach this node waveElem (Node *n, int id) {node = n; edgeID = id;}};
#define NO_EDGE -1 // Illegal edge ID no edge
Why did I use an int instead of an Edge?
BFS: How Do I Print Out the Path?
source
dest
bool bfsPath (Node* sourceNode, int destID) { list<waveElem> wavefront; wavefront.push_back (waveElem (sourceNode, NO_EDGE));
while (wavefront not empty) { waveElem curr = wavefront.front (); wavefront.pop_front(); // Remove node from wavefront
if (curr.node->id == destID) return (true);
for each (outEdge of curr.node) { Node *toNode = outEdge.toNode; wavefront.push_back ( waveElem(toNode, outEdge.id); } } return (false); // No path exits!}
0
1 2
3 4
5
{4/c,5/f}
f
c
{5/f}Know I got here from edge f. Good enough?
ab
de
BFS: How Do I Print Out the Path?bool bfsPath (Node* sourceNode, int destID) { list<waveElem> wavefront; wavefront.push_back (waveElem (sourceNode, NO_EDGE));
while (wavefront not empty) { waveElem curr = wavefront.front (); wavefront.pop_front(); // Remove node from wavefront curr.node->reachingEdge = curr.edgeID;
if (curr.node->id == destID) return (true);
for each (outEdge of curr.node) { Node *toNode = outEdge.toNode; wavefront.push_back ( waveElem(toNode, outEdge.id); } } return (false); // No path exits!}
source
dest
f
c
a b
de
NO_EDGE
a b
e c
f
d
BFS: How Do I Print Out the Path?int main () { Node *sourceNode = getNodebyID (sourceID); bool found = bfsPath (sourceNode, destID); if (found) list<Edge> path = bfsTraceBack (destID);}
list<Edge> bfsTraceBack (int destID) { list<Edge> path; Node *currNode = getNodebyID (destID); prevEdge = currNode->reachingEdge;
while (prevEdge != NO_EDGE) { path.push_front (prevEdge); currNode = prevEdge.fromNode; prevEdge = currNode->reachingEdge; } return (path);}
source
dest
f
c
a b
de
NO_EDGE
a b
c
f
d
path = {}path = {f}path = {f,d}path = {f,d,b}
reachingEdge = areachingEdge = c
Min. Path Issues
source
dest
c
a
b
d
wavefront =
0
1
2
3
{0}{1,2}{2,3}{3,1}
4
{1,4}{4,3}
b
d
e
e
What happened?• Node 1 was re-expanded• Overwrote the reachingEdge• Messed up the path traceback
d
source
reachingEdge = a
Solution?
dest
c
a
b
d
wavefront =
0
1
2
3
{0}{1,2}{2,3}{3,1}
4
{1,4}{4}
b
e
e
• Mark nodes as visited when you reach them
• Never allow them to be visited again
d
source
reachingEdge = a
Solution?
dest
c
a
b
d
wavefront =
0
1
2
3
{0}{1,2}{2,3}{3,1}
4
{1,4}{4}
b
e
e
• Another test case• With travel times
t = 5 s
t = 5 s
t = 20 s
e
d
source
reachingEdge = a
Visited Flag: Problem
dest
c
a
b
d
0
1
2
3
4
b
e
t = 5 s
t = 5 s
t = 20 s
Shortest path
Path we obtain
a, 20 sc, 10 s
Solution #2
source
dest
c
a
b
d
wavefront =
0
1
2
3
{0}{1,2}{2,3}{3,1}
4
{1,4}{4,3}
b, 5 s
d, 26 s
e, 29 s
e
1. Store shortest travel time from source at each node
2. Only process node if shortest travel time to it has dropped
t = 5 s
t = 5 s
t = 20 s
t = 6 s
t = 3 s
Half fixed. Got right path, but wrong travel time at dest!
a, 20 s
Solution #2
source
dest
c
a
b
d
wavefront =
0
1
2
3
{0}{1,2}{2,3}{3,1}
b, 5 s
d, 26 s
Another Test Case
t = 5 s
t = 5 s
t = 20 s
t = 6 s
This path is wrong!
a, 20 sc, 10 s
Solution #2++
source
dest
c
a
b
d
wavefront =0
1
2
3
{0/0s}{1/20s,2/5s}{2/5s,3/26s}{3/26s,1/10s}
4
{1/10s,4/29s}{4/29s,3/16s}
b, 5 s
d, 26 s
e, 29 s
e
1. Store shortest travel time from source at each node
2. Only update reachingEdge if shortest travel time drops
3. Don’t stop BFS on first reach of destination• Continue BFS until all
entries in wavefront have higher travel time than best path found so far
t = 5 s
t = 5 s
t = 20 s
t = 6 s
t = 3 s
d, 16 s
e, 19 s
{3/16s}{4/19s}