Graph Algorithms, Disjoint Sets ADTs, and Dynamic Programming | CPSC 311, Study notes of Algorithms and Programming

Material Type: Notes; Class: ANALYSIS OF ALGORITHMS; Subject: COMPUTER SCIENCE; University: Texas A&M University; Term: Unknown 1989;

Typology: Study notes

Pre 2010

Uploaded on 02/13/2009

koofers-user-daz-1
koofers-user-daz-1 🇺🇸

9 documents

1 / 48

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
CPSC 311 O. Burchan Bayazit Fall 02 Graph Algorithms, Union/Find, Dynamic Programming [ 1 ]
CPSC 311 Lecture Notes
Graph Algorithms,
Disjoint Sets ADTs, and
Dynamic Programming
(Chapters 21, 22-25, 15)
Acknowledgement: These notes are compiled by Nancy Amato at Texas A&M University.
Parts of these course notes are based on notes from courses given by Jennifer Welch at
Texas A&M University.
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20
pf21
pf22
pf23
pf24
pf25
pf26
pf27
pf28
pf29
pf2a
pf2b
pf2c
pf2d
pf2e
pf2f
pf30

Partial preview of the text

Download Graph Algorithms, Disjoint Sets ADTs, and Dynamic Programming | CPSC 311 and more Study notes Algorithms and Programming in PDF only on Docsity!

CPSC 311 Lecture Notes

Graph Algorithms,

Disjoint Sets ADTs, and

Dynamic Programming

(Chapters 21, 22-25, 15)

Acknowledgement: These notes are compiled by Nancy Amato at Texas A&M University. Parts of these course notes are based on notes from courses given by Jennifer Welch at Texas A&M University.

Graph Algorithms - Outline of Topics

Topic Outline

  • Elementary Graph Algorithms – Chapt 22 (review)
    • graph representation
    • depth-first-search, breadth-first-search, topological sort
  • Union-Find Data Structure – Chapt 21
    • implementing dynamic sets
  • Minimum Spanning Trees – Chapt 23
    • Kruskal’s and Prim’s algorithms (greedy algorithms)
  • Single-Source Shortest Paths – Chapt 24
    • Dijkstra’s algorithm (greedy)
  • Dynamic Programming – Chapt 15
    • All Pairs Shortest Paths (Chapt 25, Floyd-Warshall Alg as example)

Representing a Graph – Adjacency List

Adjacency List: An array A[1, V ] of lists, one for each node v ∈ V. v’s list contains (ptrs to) all nodes adjacent to v in G

example:

3

6

1 2

4 5

7

Complexity Issues

  • advantage – storage is O(V + E) (good for sparse graphs)
  • drawback – need to traverse list to find edge

Representing a Graph – Adjacency Matrix

Adjacency Matrix: An array A[V, V ] such that

A[i, j] =

  

1 if (i, j) ∈ E 0 otherwise

example:

3

6

1 2

4 5

7

1 2 3 4 5 6 7

1 2 3 4 5 6 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1

o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o

1

1

Complexity Issues

  • drawback – storage is O(V 2 ) (good for dense graphs)
  • advantage – O(1) time to check for edge

Exercise: Breadth-First Search and Adjacency Matrices

BFS(G, s) enqueue(Q, s) and visit(s) while (not-emptyQ) u := dequeue(Q) for each v adjacent to u if (v not visited yet) enqueue(Q, v) and visit(v) endfor endwhile

Exercise:

  1. What is the running time of BFS if its input graph is represented by an adjacency matrix and the algorithm is modified to handle this form of input?

Depth-First Search

DFS(G, s) visit(s) for each v adjacent to s if (v not visited yet) DFS(G, v) endfor

Complexity (Adjacency List Representation)

  • check all edges adjacent to each node encounted – O(E) time
  • need to do ’clean up’ to deal with directed or unconnected graphs
  • total = O(V + E)

Note: DFS divides edges into two categories:

  • tree edges (edges traversed in DFS)
  • back edges (other edges)

Claim: if (u, v) is a back edge, then v is an ancestor of u

Data Structures for Disjoint Sets

Disjoint Set Abstract Data Type (ADT) (Chapt 22)

  • set of underlying elements U = { 1 , 2 ,... , n}
  • collection of disjoint subsets C = s 1 , s 2 ,... , sm of U
    • each si has an id (a distinguished element)
  • operations on C
    • create(x): x ∈ U , makes set {x}
    • union(x, y): x, y ∈ U and are id’s of their resp. sets sx and sy, replaces sets sx and sy with a set that is sx ∪ sy and returns the id of the new set
    • find(x): x ∈ U , returns the id of the the set containing x

Note 1: The create operation is typically used during the initialization of a particular algorithm.

Note 2: We assume we have a pointer to each x ∈ U (so we never have to look for a particular element). Thus the the problems we’re trying to solve are how to manage the sets (unions) and how to find the id of the set containing a particular element (finds)

Graph Algorithm Application – Connected Components

a b

c d f

e

g

Connected-Components(G) let U = V = {a, b, c, d, e, f, g}

  1. for each v ∈ U create(v)
  2. for each (u, v) ∈ E if find(u) 6 = find(v) union(find(u), find(v))

Initially (after step 1), we have the V sets:

{a}, {b}, {c}, {d}, {e}, {f }, {g}

Finally (after step 2), we have the two sets:

{a, b, c, d}, {e, f, g}

which represent the two connected components of the graph.

Weighted Union Implementation

Idea: add weight field to each node holding the number of nodes in the subtree rooted at this node (we’ll only care about weight field of roots)

find(x):

  • as before with simple implementation, running time O(log n)

union(x, y):

  • x and y are ids (roots of trees)
  • make node (x or y) with smaller weight the child of the other

x (^) U y (^) = x

y

Theorem: Any k-node tree created by k − 1 weighted unions has height ≤ log k (assume we start with singleton sets). That is, trees stay ‘short’.

Proof: By induction on k. Basis: k = 1, height = 0 = log 1 Inductive Hypothesis: Assume true for all i < k. Induction Step: Show true for k. Suppose the last operation performed was union(x, y) and that m = wt(x) ≤ wt(y) = k − m, so that m ≤ k/2.

hx hy h

U y = k−m k−m nodes

y

nodes

x

nodes m

x

nodes m

h = max(hx + 1, hy) ≤ log k

  • hx + 1 ≤ log m + 1 ≤ log k 2 + 1 = log k − 1 + 1 = log k
  • hy ≤ log(k − m) ≤ log k 2

Path Compression Implemenation

Idea: extend the idea of weighted union (i.e., unions still weighted), but on a find(x) operation, make every node on the path from x to the root (the id) a child of the root.

after find(x)

a

b

c

d

x

a

b c d

x

So... find(x) still has worst-case time of O(log n), but subsequent finds for nodes that used to be ancestors of x will now be very fast.

Theorem: Let S be any sequence of O(n) unions and finds. Then the worst-case time for performing S with weighted unions and path compres- sion is O(n log∗^ n)

log∗^ n is ‘almost’ constant log∗^ n is the number of times we have to take the log of a number to reach 1:

  • log∗^ 2 = 1 (log∗^ 2 = 1)
  • log∗^3 − log∗^ 4 = 2 (log∗^22 = 2)
  • log∗^ 16 = 3 (log∗^22 2 = 3)
  • log∗^ 65536 = 4 (log∗^22 22 = 4)

Minimum Spanning Trees (Chapt 24)

a b c

d e

f g h

1

2

3

4

6 5 6

7

2

3

8 5

Definition: Given an undirected graph G = (V, E) with weights on the edges, a minimum spanning tree of G is a subset T ⊆ E such that T has

  • no cycles
  • contains all nodes in V
  • sum of the weights of all edges in T is minimum

Kruskal’s MST Algorithm

Idea:

  • use a greedy strategy
  • consider edges in increasing order of weight
  • add edge to T if it doesn’t create a cycle

MST-Kruskal(G)

  1. T := ∅
  2. for each v ∈ V create(v) /make singleton set/
  3. sort edges in E by increasing weight
  4. for each (u, v) ∈ E /in sorted order/ if find(u) 6 = find(v) /doesn’t create a cycle/ T := T ∪ {(u, v)} /add edge to MST/ union(find(u), find(v)) /put u and v in same CC/ endfor
  5. return T

Running Time

  • initialization – O(1) + O(V ) + O(E log E) = O(V + E log E)
  • 2 E iterations (two for each edge)
    • 4E finds – O(E log∗^ E) time
    • O(V ) unions – O(V ) time (at most V − 1 unions)
  • total: O(V + E log E) time
    • note log E = O(log V ) since E = O(V 2 ) and log E = O(2 log V )

Note: We only get this bound because of amortized analysis

Correctness of Kruskal’s Algorithm

Theorem: Kruskal’s MST algorithm produces a MST.

Proof: Clearly algorithm produces a spanning tree. We need to argue it is an MST.

Suppose in contradiction it is not an MST. Suppose that the algorithm adds edges to the tree in order e 1 , e 2 ,... , en− 1 and let i be the value such that e 1 , e 2 ,... , ei− 1 is a subset of some MST T , but e 1 , e 2 ,... , ei− 1 , ei is not a subset of any MST.

Consider T ∪ {ei}

  • T ∪ {ei} must have a cycle c involvin ei
  • in the cycle c there is at least one edge that is not in e 1 , e 2 ,... , ei− 1 (since algorithm doesn’t pick ei if it makes a cycle)
  • let e∗^ be edge with minimum weight on c that is not in e 1 , e 2 ,... , ei
    • wt(ei) < wt(e∗) (else algorithm would have picked e∗)

Claim: T ′^ = T − {e∗} ∪ {ei} is a MST

  • T ′^ is a spanning tree
    • contains all nodes
    • contains no cycles
  • wt(T ′) < wt(T ), so T is not MST (contradiction)

This contradiction means our original assumption must be wrong (so the algo- rithm does find an MST). 2

Prim’s MST Algorithm

Idea:

  • always maintain a connected subgraph (different from Kruskal’s algorithm)
  • at each iteration choose the cheapest edge that goes out from the current tree (a greedy strategy)

MST-Prim(G)

  1. v 0 := any node in V
  2. T := ∅
  3. while |T | < |V | Eout := {(u, v) ∈ E|u in T and v not in T } let (x, y) be edge in Eout with minimum weight T := T ∪ {(x, y)} endwhile
  4. return T

Running Time – Adjacency List Rep

  • |V | − 1 iterations
  • at each iteration, check all edges for minimum element of Eout
  • total: O(V E) time

Note: we don’t find the minimum element of Eout very efficiently...