Lecture 28: Graphs
Breadth-first
traversal
Use bft to answer the following questions:
·
is
the graph connected? – follow preds & successors
·
is
there a path from node j to node k?
·
what
are all the nodes reachable from j?
·
what
is the shortest path from one node to another?
NOT: does the graph have a cycle?, or topological
ordering
idea: visit all nodes 1-away from n,
visit all nodes 2-away from n,
etc.
·
similar to level-order tree traversal
·
use a Queue
Example:
A B A
C E F
B
C D
E F
·
like dft, must
mark each node to avoid visiting more than once
(e.g., node F in the example above)
bft(n) algorithm -- simulate on the above example
·
mark n visited
·
enqueue(n)
·
while queue not empty
o
dequeue
m
§
for each unvisited successor s of m,
mark
s, enqueue s
Simulate bft(A):
A B
C D
E F
:
implementation of breadth-first graph traversal:
static void bft(Graphnode n)
1 // unmark all nodes
2 n.mark = true; // call it “marked”, not “visited”
3 Q.enqueue(n) // into an empty Q
4 while (!Q.empty()) {
5 Graphnode m = (graphnode) Q.dequeue();
6 Iterator it = m.getSuccessors().iterator();
7 while(it.hasNext()) {
8 Graphnode s = (Graphnode) it.next();
9 if (!s.mark) {
10 S.mark = true;
11 Q.enqueue(S)
}
}
}
}
Time
for Breadth-first Traversal
·
each reachable node is enqueued/dequeued
once
·
when a node is dequeued,
each of its successors are considered
so,
the total time is
T(n) = c1 + (c2
+ e1 ´ c3) + (c2
+ e2 ´ c3) + … + (c2 + er
´ c3)
c1
= time for statements 1, 2, and 3
c2 =
time for statements 4, 5, and 6;
c3 =
time for statements 7, 8, and 9;
ei
= number of successor edges for ith node dequeued
r =
number of nodes reachable from n
In the worst
case, r = N:
T(n) = c1
+ N ´ c2
+ c3´ (e1 + e2
+ … + eN)
= O(N + E)
Summary:
depth-first traversal: for each path, go as far away as possible
breadth-first traversal: visit all nodes 1 away, then all nodes 2
away, etc
Example:
A
® B
¬ C
¯ ¯
D
¬ E ¬ F
¯
G
You
try:
·
find 2 different orderings
for dft(A)
A B F G D
E and A D F G E B
·
find 2 different orderings
for bft(A)
A B D F G
E and A D B F E G
·
for what node(s) n is there an order that
is both dfs(n) and bfs(n)
D: D F E G or
E: E D F G or
G: G D F E
Recall: code for dft(n) and bft(n):
// unmark all nodes
dft(n) {
mark n // call it
"mark", not "visit"
for each unmarked successor m of n {
dft(m)
}
}
bft(n)
// unmark all nodes
mark n
Q.enqueue(n)
(into an empty Q)
while Q not empty {
m = Q.dequeue()
for each unmarked successor S of m {
mark S // call it
"mark", not "visit"
Q.enqueue(S)
}
}
}
Where
should you print the node that is visited?
dft: when you mark it
bft: when you enqueue
it or when you dequeue it
Path detection - is there a path from node
j to node k?
1.
start with all nodes unmarked
2.
do dfs(j) or bfs(j), then check wheter k is
marked
time
= O(N+E)
Note: extra work is done;
You try: write the code for a more efficient isPath method
boolean isPath(n,goal) {
//
precondition: all nodes are unmarked
// fill in
your code here
}
Solution
based on bfs:
if (n = goal) return true;
mark n;
Q.enqueue(n)
while (!Q.empty())
{
m = Q.dequeue();
for each unmarked successor s of m {
if (s = goal) return true;
mark s
Q.enqueue(s);
}
}
return false;
solution
based on dfs:
if (n == goal) return true;
mark n
for each unmarked successor s of n {
if (isPath(s,goal))
return true;
}
return false;
Cycle Detection: use dfs(n):
Q: when doing a
dfs, what will happen to indicate a cycle?
A: a successor
will be marked (i.e., already looked at)
but
this isn't sufficient to know that there's a cycle
use 3
values: "unmarked", "in-progress",
"done"
Boolean hasCycle(n) {
mark n "in progress"
for each successor m of n {
if m is "unmarked" if (hasCycle(m))
return true;
if m is "in progress" return true;
}
mark n
"done"
}
Simulate hasCycle(X) for : X ® A ® B ® D
¯
¬
¬ C
Can we identify
just the nodes that are in the cycle?
Note:
To find whether
a graph contains a cycle, it isn't sufficient to call hasCycle() on just one of
the nodes;
instead: call hasCycle on an
unmarked node, and then repeat on another unmarked node
Graphs Summary
·
Graph = set of nodes and set of edges
·
two kinds of graphs: directed, undirected
·
low-level operations:
o
add a node
o
add an edge
o
remove a node
o
remove an edge
o
is
there an edge from node j to node k?
o
what
are all the successors of node j?
·
high-level operations:
o
dft: reachability, cycle
detection, topological order
o
bft: reachability,
shortest path
·
there
are algorithms for finding the strongly connected components – covered in CS
577 (?)