Graph-Based Algorithms
Graphs
A graph G = (V, E)
V = set of vertices, E = set of edges
Dense graph: |E| |V|2; Sparse graph: |E| |V|
Undirected graph:
edge (u, v) = edge (v, u) No self-loops
Directed graph:
Edge (u, v) goes from vertex u to vertex v, notated u v
A weighted graph associates weights with either the edges or the vertices
Adjacency Matrix Representation
a c d b e a b c d eCheck for an edge in constant time
a b c d e 0 1 1 0 0 1 0 0 1 1 1 0 0 1 0 0 1 1 0 1 0 1 0 1 0
Adjacency Matrix Representation
Memory required
O(V + V2)=O(V2)
Preferred when
The graph is dense: E = O(V2)
Advantage
Can quickly determine
if there is an edge between two vertices
Disadvantage
Adjacency List Representation
a c d b e a b c d e b c a d e a d b c e b dAdjacency List Representation
Memory required
O(V + E)
Preferred when
for sparse graphs: E = O(V)
Disadvantage
No quick way to determine whether there is an edge between vertices u and v
Advantage
Can quickly determine the vertices adjacent from a given vertex
O(V) for sparse graphs since E=O(V) O(V2) for dense graphs since E=O(V2)
Graph Searching
Given: a graph G = (V, E), directed or undirected
Goal: methodically explore every vertex and every edge Ultimately: build a tree on the graph
Pick a vertex as the root
Choose certain edges to produce a tree
Graph Traversals
Ways to traverse/search a graph
Visit every vertex exactly once
Breadth-First Search Depth-First Search
Breadth-First Search
“Explore” a graph, turning it into a tree
One vertex at a time
Expand frontier of explored vertices across the breadth of the frontier
Builds a tree over the graph
Pick a source vertex to be the root
Breadth-First Search
Associate vertex “colors” to guide the algorithm
White vertices have not been discovered
All vertices start out white
Gray vertices are discovered but not fully explored
They may be adjacent to white vertices
Black vertices are discovered and fully explored
They are adjacent only to black and gray vertices
BFS Trees
BFS tree is not necessarily unique for a given graph
Depends on the order in which neighboring vertices are processed
During the breadth-first search, assign an integer to each vertex
Breadth-First Search
BFS(G, s)
1. for each vertex u ϵ G.V − {s}
2. u.color = WHITE 3. u.d = ∞ 4. u.π = NIL 5. s.color = GRAY 6. s.d = 0 7. s.π = NIL 8. Q = Ø 9. ENQUEUE(Q, s) 10 while Q ≠ Ø 11. u = DEQUEUE(Q) 12. for each v ϵ G.Adj[u]
13. if v.color == WHITE 14. v.color = GRAY 15. v.d = u.d + 1 16. v.π = u 17. ENQUEUE(Q, v) 18. u.color = BLACK
Breadth-First Search: Example
r s t u v w x yBreadth-First Search: Example
0
r s t u v w x y sQ:
Breadth-First Search: Example
1
0
1
r s t u v w x y wQ:
rBreadth-First Search: Example
1
0
1
2
2
r s t u v w x y rQ:
t xBreadth-First Search: Example
1
2
0
1
2
2
r s t u v w x yQ:
t x vBreadth-First Search: Example
1
2
0
1
2
2
3
r s t u v w x yQ:
x v uBreadth-First Search: Example
1
2
0
1
2
2
3
3
r s t u v w x yQ:
v u yBreadth-First Search: Example
1
2
0
1
2
2
3
3
r s t u v w x yQ:
u yBreadth-First Search: Example
1
2
0
1
2
2
3
3
r s t u v w x yQ:
yBreadth-First Search: Example
1
2
0
1
2
2
3
3
r s t u v w x yQ:
ØBFS Running Time
Initialization of each vertex takes O(V) time
Every vertex is enqueued once and dequeued once, taking
O(V) time
When a vertex is dequeued, all its neighbors are checked to see if they are unvisited, taking time proportional to
number of neighbors of the vertex, and summing to O(E) over all iterations
Breadth-First Search: Properties
BFS calculates the shortest-path distance to the source node
Shortest-path distance (s, v) = minimum number of edges from s to v, or if v not reachable from s
BFS builds breadth-first tree, in which paths to root represent shortest paths in G
Thus can use BFS to calculate shortest path from one vertex to another in O(V + E) time
Depth-First Search
Depth-first search is another strategy for exploring a graph
Explore “deeper” in the graph whenever possible
Edges are explored out of the most recently discovered vertex v that still has unexplored edges
When all of v’s edges have been explored, backtrack to the vertex from which v was discovered
Depth-First Search
Vertices initially colored white
Then colored gray when discovered Then black when finished
DFS Tree
Actually might be a DFS forest (collection of trees) Keep track of parents
Depth-First Search
DFS (G)
1. for each vertex u ϵ G.V
2. u.color = WHITE 3. u.π = NIL
4. time = 0
5. for each vertex u ϵ G.V
6. if u.color == WHITE 7. DFS-VISIT(G, u) DFS-VISIT(G, u) 1. time = time + 1 2. u.d = time 3. u.color = GRAY
4. for each v ϵ G.Adj[u]
5. if v.color == WHITE 6. v.π = u 7. DFS-VISIT(G, v) 8. u.color = BLACK 9. time = time + 1 10. u.f = time
DFS Example
source vertex
DFS Example
1 | | | | | | | | source vertex d fDFS Example
1 | | | | | | 2 | | source vertex d fDFS Example
1 | | | | | 3 | 2 | | source vertex d fDFS Example
1 | | | | | 3 | 4 2 | | source vertex d fDFS Example
1 | | | | 5 | 3 | 4 2 | | source vertex d fDFS Example
1 | | | | 5 | 6 3 | 4 2 | | source vertex d fDFS Example
1 | | | | 5 | 6 3 | 4 2 | 7 | source vertex d fDFS Example
1 | 8 | | | 5 | 6 3 | 4 2 | 7 | source vertex d fDFS Example
1 | 8 | | | 5 | 6 3 | 4 2 | 7 9 | source vertex d fWhat is the structure of the gray vertices? What do they represent?
DFS Example
1 | 8 | | | 5 | 6 3 | 4 2 | 7 9 |10 source vertex d fDFS Example
1 | 8 |11 | | 5 | 6 3 | 4 2 | 7 9 |10 source vertex d fDFS Example
1 |12 8 |11 | | 5 | 6 3 | 4 2 | 7 9 |10 source vertex d fDFS Example
1 |12 8 |11 13| | 5 | 6 3 | 4 2 | 7 9 |10 source vertex d fDFS Example
1 |12 8 |11 13| 14| 5 | 6 3 | 4 2 | 7 9 |10 source vertex d fDFS Example
1 |12 8 |11 13| 14|15 5 | 6 3 | 4 2 | 7 9 |10 source vertex d fDFS Example
1 |12 8 |11 13|16 14|15 5 | 6 3 | 4 2 | 7 9 |10 source vertex d fRunning Time of DFS
initialization takes O(V) time
second for loop in non-recursive wrapper considers each vertex, so O(V) iterations
one recursive call is made for each vertex
in recursive call for vertex u, all its neighbors are checked; total time in all recursive calls is O(E)
Properties of DFS
Parentheses structure: If we represent the discovery of vertex with a left parenthesis “ ” and represent its finishing by a right parenthesis “ ”, then the history of discoveries and finishings makes a well-formed expression in the sense that the parentheses are properly nested.
Properties of DFS
This yields the parentheses theorem: For any two vertices and , exactly one of the following three conditions
holds:
1. the intervals and are entirely disjoint, and neither nor is a descendant of the other in the depth-first forest
2. the interval is contained entirely within the interval , and is a descendant of in a
depth-first tree, or
3. the interval is contained entirely within the interval , and is a descendant of in a
Classifying Edges
Consider edge in directed graph w.r.t. DFS forest
1. tree edge: is a child of
2. back edge: is an ancestor of
3. forward edge: is a descendant of (but not a child) 4. cross edge: all other edges. They can go between
vertices in the same depth-first tree, as long as one vertex is not an ancestor of the other, or they can go between vertices in different depth-first trees.
Classifying Edges
The DFS algorithm can be used to classify graph edges by assigning colors to them. Each edge can be classified by the color of the vertex that is reached when the edge is explored:
• white indicates a tree edge
• gray indicates a back edge
• black indicates a forward or cross edge. An edge is
• a forward edge if and
DFS Application: Topological Sort
Given a directed acyclic graph (DAG), find a linear
ordering of the vertices such that if is an edge, then precedes in the ordering.
DAG indicates precedence among events:
events are graph vertices, edge from to means event has precedence over event
Partial order because not all events have to be done in a certain order
DFS Application: Topological Sort
Precedence Example:
Consider how Professor Bumstead gets dressed for his office.
undershorts, pants, shirt, jacket, tie, watch, belt, shoes, socks
Certain garments must before others (e.g., socks before shoes)
DFS Application: Topological Sort
A directed edge in the DAG indicates that garment must be donned before garment . A topological sort of this DAG therefore gives an order for getting dressed.
DFS Application: Topological Sort
The following simple algorithm topologically sorts a DAG:
TOPOLOGICAL-SORT(G)
1 call DFS(G) to compute finishing times for each vertex 2 as each vertex is finished, insert it onto the front of a linked list 3 return the linked list of vertices
We can perform a topological sort in time, since depth-first search takes time and it takes
time to insert each of the vertices onto the front of the linked list.
Strongly Connected Components
Strongly connected graph
A directed graph is called strongly connected if for every pair of vertices and there is a path from to and a path from to
.
Strongly Connected Components (SCC)
The strongly connected components (SCC) of a directed graph are its maximal strongly connected subgraphs.
Strongly Connected Components
G is strongly connected if every pair (u, v) of vertices in G is reachable from one another.
A strongly connected component (SCC) of G is a maximal set of vertices C V such that for all u, v C, both u v
Strongly Connected Components
A D E C F B G HStrongly Connected Components
A D E C F B G HStrongly Connected Components
GSCC = (VSCC, ESCC).
VSCC has one vertex for each SCC in G.
ESCC has an edge if there’s an edge between the corresponding SCC’s in G.
Strongly Connected Components
GT = transpose of directed graph G.
GT = (V, ET), ET = {(u, v) : (v, u) E}.
GT is G with all edges reversed.
We can create GT in Θ(V + E) time if we are using adjacency lists.
G and GT have the same SCC’s. (u and v are reachable from each other in G if and only if reachable
from each other in GT).
a b c d a d b c GT G Edges have reverse direction! a b c d a b c d a b c d a b c d 1 1 1 1 1 1 1 1
Algorithm to Determine SCCs
SCC(G)
1. call DFS(G) to compute finishing times f [u] for all u
2. compute GT
3. call DFS(GT), but in the main loop, consider vertices in order of decreasing f [u] (as computed in first DFS)
4. output the vertices in each tree of the depth-first forest formed in second DFS as a separate SCC
9
Example
a b c d e f g h 1/ 2/ 3/ 4 7 5/6 8/ 11/ 12/ 13/14 10 9 15 16 f 4 h 6 g 7 d 9 c 10 a 14 e 15 b 16DFS on the initial graph G
DFS on GT:
• start at b: visit a, e • start at c: visit d • start at g: visit f • start at h
Strongly connected components: C1 = {a, b, e}, C2 = {c, d}, C3 = {f, g}, C4 = {h}
a b c d
e f g h