Graph Algorithms

Download Graph Algorithms

Post on 24-Oct-2014

112 views

Category:

Documents

0 download

Embed Size (px)

TRANSCRIPT

<p>Introduction to AlgorithmsCS135</p> <p>Elementary Graph AlgorithmsProf. Ronald M. Tugol</p> <p>Graphs1 1 5 5 2 2 3 3 4 a digraph 4 5 5 1 1 2 2 3 3 4 an undirected 4 graph</p> <p>A graph G = (V, E): V is a finite set of vertices. E is a set of vertex pairs called edges. directed edge (arc): (u, v), u, v V undirected edge: {u, v}, u, v V, u v2/14/02 Introduction to Algorithms CLRS16.2</p> <p>Adjacency-list1 1 5 5 4 4 2 2 3 31 2 3 4 5 1 4 2 3 3 4 5</p> <p>Array Adj of |V| lists. Space requirement is (V + E). Query (u, v) E? takes O(E) time. Suitable for sparse graphs: |E| = o(V2).2/14/02 Introduction to Algorithms CLRS16.3</p> <p>Adjacency-matrix1 1 5 5 4 4 2 2 3 3A 1 2 3 4 5 1 0 1 1 0 1 2 0 0 1 1 0 3 0 0 0 0 0 4 1 0 0 0 0 5 0 0 0 1 0</p> <p>A[u, v] =1 (u, v) E.</p> <p>|V| |V| matrix A. Space requirement is (V2). Query (u, v) E? takes (1) time. Suitable for dense graphs: |E| = (V2).2/14/02 Introduction to Algorithms CLRS16.4</p> <p>Breadth-first searchrr vv ss tt w w u u x xBFS(G, s) for each vertex u V[G] {s} do state[u] undiscovered state[s] discovered Q ENQUEUE(Q, s) while Q do u DEQUEUE(Q) for each v Adj[u] do if state[v] = undiscovered then state[v] discovered ENQUEUE(Q, v) state[u] completely explored</p> <p> the closer the earlier can be modified to find shortest-paths from a source vertex. Denote by (s, v) the shortest-path distance from source s to vertex v V.2/14/02 Introduction to Algorithms</p> <p>CLRS16.5</p> <p>Shortest paths with BFSBFS(G, s) for each vertex u V[G] {s} do state[u] undiscovered state[s] discovered vv w x Q w x ENQUEUE(Q, s) Use arrays d and to store shortest while Q do u DEQUEUE(Q) distances and predecessors. for each v Adj[u] do Initialize: d[u] + for all if state[v] = undiscovered then nonsource vertices u, d[s] 0. state[v] discovered ENQUEUE(Q, v) As vertex v is discovered from state[u] completely explored</p> <p>rr</p> <p>ss</p> <p>tt</p> <p>u u</p> <p>vertex u, set d[v] d[u] + 1.</p> <p>Theorem. d[v] = (s, v) for all v V upon termination of BFS.2/14/02 Introduction to Algorithms CLRS16.6</p> <p>Shortest paths with BFSr: r: vv: : s:0 s:0 t: t: w: w: s:0 u: u: x: x: BFS(G, s) for each vertex u V[G] {s} do state[u] undiscovered d[u] , [u] NIL state[s] discovered d[s] 0, [s] NIL Q ENQUEUE(Q, s) while Q do u DEQUEUE(Q) for each v Adj[u] do if state[v] = undiscovered then state[v] discovered d[v] d[u] + 1, [v] u ENQUEUE(Q, v) state[u] completely exploredCLRS16.7</p> <p>Q</p> <p>2/14/02</p> <p>Introduction to Algorithms</p> <p>Shortest paths with BFSr: r: vv:1 :1 s:0 s:0 t:1 t:1 w: w: t:1 v:1 u: u: x: x: BFS(G, s) for each vertex u V[G] {s} do state[u] undiscovered d[u] , [u] NIL state[s] discovered d[s] 0, [s] NIL Q ENQUEUE(Q, s) while Q do u DEQUEUE(Q) for each v Adj[u] do if state[v] = undiscovered then state[v] discovered d[v] d[u] + 1, [v] u ENQUEUE(Q, v) state[u] completely exploredCLRS16.8</p> <p>Q</p> <p>2/14/02</p> <p>Introduction to Algorithms</p> <p>Shortest paths with BFSr: r: vv:1 :1 s:0 s:0 t:1 t:1 w:2 w:2 v:1 w:2 u: u: x: x: BFS(G, s) for each vertex u V[G] {s} do state[u] undiscovered d[u] , [u] NIL state[s] discovered d[s] 0, [s] NIL Q ENQUEUE(Q, s) while Q do u DEQUEUE(Q) for each v Adj[u] do if state[v] = undiscovered then state[v] discovered d[v] d[u] + 1, [v] u ENQUEUE(Q, v) state[u] completely exploredCLRS16.9</p> <p>Q</p> <p>2/14/02</p> <p>Introduction to Algorithms</p> <p>Shortest paths with BFSr:2 r:2 vv:1 :1 s:0 s:0 t:1 t:1 w:2 w:2 w:2 r:2 u: u: x: x: BFS(G, s) for each vertex u V[G] {s} do state[u] undiscovered d[u] , [u] NIL state[s] discovered d[s] 0, [s] NIL Q ENQUEUE(Q, s) while Q do u DEQUEUE(Q) for each v Adj[u] do if state[v] = undiscovered then state[v] discovered d[v] d[u] + 1, [v] u ENQUEUE(Q, v) state[u] completely exploredCLRS16.10</p> <p>Q</p> <p>2/14/02</p> <p>Introduction to Algorithms</p> <p>Shortest paths with BFSr:2 r:2 vv:1 :1 s:0 s:0 t:1 t:1 w:2 w:2 r:2 u:3 x:3 u:3 u:3 x:3 x:3 BFS(G, s) for each vertex u V[G] {s} do state[u] undiscovered d[u] , [u] NIL state[s] discovered d[s] 0, [s] NIL Q ENQUEUE(Q, s) while Q do u DEQUEUE(Q) for each v Adj[u] do if state[v] = undiscovered then state[v] discovered d[v] d[u] + 1, [v] u ENQUEUE(Q, v) state[u] completely exploredCLRS16.11</p> <p>Q</p> <p>2/14/02</p> <p>Introduction to Algorithms</p> <p>Shortest paths with BFSr:2 r:2 vv:1 :1 s:0 s:0 t:1 t:1 w:2 w:2 u:3 x:3 u:3 u:3 x:3 x:3 BFS(G, s) for each vertex u V[G] {s} do state[u] undiscovered d[u] , [u] NIL state[s] discovered d[s] 0, [s] NIL Q ENQUEUE(Q, s) while Q do u DEQUEUE(Q) for each v Adj[u] do if state[v] = undiscovered then state[v] discovered d[v] d[u] + 1, [v] u ENQUEUE(Q, v) state[u] completely exploredCLRS16.12</p> <p>Q</p> <p>2/14/02</p> <p>Introduction to Algorithms</p> <p>Shortest paths with BFSr:2 r:2 vv:1 :1 s:0 s:0 t:1 t:1 w:2 w:2 x:3 u:3 u:3 x:3 x:3 BFS(G, s) for each vertex u V[G] {s} do state[u] undiscovered d[u] , [u] NIL state[s] discovered d[s] 0, [s] NIL Q ENQUEUE(Q, s) while Q do u DEQUEUE(Q) for each v Adj[u] do if state[v] = undiscovered then state[v] discovered d[v] d[u] + 1, [v] u ENQUEUE(Q, v) state[u] completely exploredCLRS16.13</p> <p>Q</p> <p>2/14/02</p> <p>Introduction to Algorithms</p> <p>Shortest paths with BFSBFS(G, s) for each vertex u V[G] {s} do state[u] undiscovered d[u] , [u] NIL vv:1 w:2 x:3 state[s] discovered :1 w:2 x:3 d[s] 0, [s] NIL Q ENQUEUE(Q, s) while Q do u DEQUEUE(Q) for each v Adj[u] do if state[v] = undiscovered then G = (V, E) where state[v] discovered V = {vV: [v] NIL} {s} d[v] d[u] + 1, [v] u ENQUEUE(Q, v) E = {([v], v): vV {s}} state[u] completely explored r:2 r:2 s:0 s:0 t:1 t:1 u:3 u:3</p> <p>Q Breadth-first search tree</p> <p>Running time: O(V + E)2/14/02</p> <p>Introduction to Algorithms</p> <p>CLRS16.14</p> <p>Depth-first searchrr vv ss tt w w u u x xDFS(G) for each vertex u V[G] do state[u] undiscovered [u] NIL time 0 for each vertex u V[G] do if state[u] = undiscovered then DFS-VISIT(u) DFS-VISIT(u) state[u] discovered d[u] time time + 1 for each v Adj[u] do if state[v] = undiscovered then [v] u DFS-VISIT(v) state[u] completely explored f[u] time time + 1CLRS16.15</p> <p> search deeper, backtrack when stuck produces a DFS forest makes recursive calls to DFS-VISIT2/14/02</p> <p>Introduction to Algorithms</p> <p>Depth-first searchr:1/ r:1/</p> <p>ss</p> <p>tt w w</p> <p>u u x x</p> <p>vv</p> <p>For each node u, compute d[u]: time of first visit f[u]: time when all adjacent nodes have been visited2/14/02</p> <p>DFS(G) for each vertex u V[G] do state[u] undiscovered [u] NIL time 0 for each vertex u V[G] do if state[u] = undiscovered then DFS-VISIT(u) DFS-VISIT(u) state[u] discovered d[u] time time + 1 for each v Adj[u] do if state[v] = undiscovered then [v] u DFS-VISIT(v) state[u] completely explored f[u] time time + 1CLRS16.16</p> <p>Introduction to Algorithms</p> <p>Depth-first searchr:1/ r:1/</p> <p>ss</p> <p>tt w w</p> <p>u u x x</p> <p>v:2/ v:2/</p> <p>DFS(G) for each vertex u V[G] do state[u] undiscovered [u] NIL time 0 for each vertex u V[G] do if state[u] = undiscovered then DFS-VISIT(u) DFS-VISIT(u) state[u] discovered d[u] time time + 1 for each v Adj[u] do if state[v] = undiscovered then [v] u DFS-VISIT(v) state[u] completely explored f[u] time time + 1</p> <p>2/14/02</p> <p>Introduction to Algorithms</p> <p>CLRS16.17</p> <p>Depth-first searchr:1/ r:1/ s:3/ s:3/</p> <p>tt w w</p> <p>u u x x</p> <p>v:2/ v:2/</p> <p>DFS(G) for each vertex u V[G] do state[u] undiscovered [u] NIL time 0 for each vertex u V[G] do if state[u] = undiscovered then DFS-VISIT(u) DFS-VISIT(u) state[u] discovered d[u] time time + 1 for each v Adj[u] do if state[v] = undiscovered then [v] u DFS-VISIT(v) state[u] completely explored f[u] time time + 1</p> <p>2/14/02</p> <p>Introduction to Algorithms</p> <p>CLRS16.18</p> <p>Depth-first searchr:1/ r:1/ s:3/ s:3/ t:4/ t:4/</p> <p>u u x x</p> <p>v:2/ v:2/</p> <p>w w</p> <p>DFS(G) for each vertex u V[G] do state[u] undiscovered [u] NIL time 0 for each vertex u V[G] do if state[u] = undiscovered then DFS-VISIT(u) DFS-VISIT(u) state[u] discovered d[u] time time + 1 for each v Adj[u] do if state[v] = undiscovered then [v] u DFS-VISIT(v) state[u] completely explored f[u] time time + 1</p> <p>2/14/02</p> <p>Introduction to Algorithms</p> <p>CLRS16.19</p> <p>Depth-first searchr:1/ r:1/ s:3/ s:3/ t:4/5 t:4/5</p> <p>u u x x</p> <p>v:2/ v:2/</p> <p>w w</p> <p>DFS(G) for each vertex u V[G] do state[u] undiscovered [u] NIL time 0 for each vertex u V[G] do if state[u] = undiscovered then DFS-VISIT(u) DFS-VISIT(u) state[u] discovered d[u] time time + 1 for each v Adj[u] do if state[v] = undiscovered then [v] u DFS-VISIT(v) state[u] completely explored f[u] time time + 1</p> <p>2/14/02</p> <p>Introduction to Algorithms</p> <p>CLRS16.20</p> <p>Depth-first searchr:1/ r:1/ s:3/6 s:3/6 t:4/5 t:4/5</p> <p>u u x x</p> <p>v:2/ v:2/</p> <p>w w</p> <p>DFS(G) for each vertex u V[G] do state[u] undiscovered [u] NIL time 0 for each vertex u V[G] do if state[u] = undiscovered then DFS-VISIT(u) DFS-VISIT(u) state[u] discovered d[u] time time + 1 for each v Adj[u] do if state[v] = undiscovered then [v] u DFS-VISIT(v) state[u] completely explored f[u] time time + 1</p> <p>2/14/02</p> <p>Introduction to Algorithms</p> <p>CLRS16.21</p> <p>Depth-first searchr:1/ r:1/ s:3/6 s:3/6 t:4/5 t:4/5</p> <p>u u x x</p> <p>v:2/ v:2/</p> <p>w:7/ w:7/</p> <p>DFS(G) for each vertex u V[G] do state[u] undiscovered [u] NIL time 0 for each vertex u V[G] do if state[u] = undiscovered then DFS-VISIT(u) DFS-VISIT(u) state[u] discovered d[u] time time + 1 for each v Adj[u] do if state[v] = undiscovered then [v] u DFS-VISIT(v) state[u] completely explored f[u] time time + 1</p> <p>2/14/02</p> <p>Introduction to Algorithms</p> <p>CLRS16.22</p> <p>Depth-first searchr:1/ r:1/ s:3/6 s:3/6 t:4/5 t:4/5</p> <p>u u x x</p> <p>v:2/ v:2/</p> <p>w:7/8 w:7/8</p> <p>DFS(G) for each vertex u V[G] do state[u] undiscovered [u] NIL time 0 for each vertex u V[G] do if state[u] = undiscovered then DFS-VISIT(u) DFS-VISIT(u) state[u] discovered d[u] time time + 1 for each v Adj[u] do if state[v] = undiscovered then [v] u DFS-VISIT(v) state[u] completely explored f[u] time time + 1</p> <p>2/14/02</p> <p>Introduction to Algorithms</p> <p>CLRS16.23</p> <p>Depth-first searchr:1/ r:1/ s:3/6 s:3/6 t:4/5 t:4/5</p> <p>u u x x</p> <p>v:2/9 v:2/9</p> <p>w:7/8 w:7/8</p> <p>DFS(G) for each vertex u V[G] do state[u] undiscovered [u] NIL time 0 for each vertex u V[G] do if state[u] = undiscovered then DFS-VISIT(u) DFS-VISIT(u) state[u] discovered d[u] time time + 1 for each v Adj[u] do if state[v] = undiscovered then [v] u DFS-VISIT(v) state[u] completely explored f[u] time time + 1</p> <p>2/14/02</p> <p>Introduction to Algorithms</p> <p>CLRS16.24</p> <p>Depth-first searchr:1/10 r:1/10 s:3/6 s:3/6 t:4/5 t:4/5</p> <p>u u x x</p> <p>v:2/9 v:2/9</p> <p>w:7/8 w:7/8</p> <p>DFS(G) for each vertex u V[G] do state[u] undiscovered [u] NIL time 0 for each vertex u V[G] do if state[u] = undiscovered then DFS-VISIT(u) DFS-VISIT(u) state[u] discovered d[u] time time + 1 for each v Adj[u] do if state[v] = undiscovered then [v] u DFS-VISIT(v) state[u] completely explored f[u] time time + 1</p> <p>2/14/02</p> <p>Introduction to Algorithms</p> <p>CLRS16.25</p> <p>Depth-first searchr:1/10 r:1/10 s:3/6 s:3/6 t:4/5 t:4/5</p> <p>v:2/9 v:2/9</p> <p>w:7/8 w:7/8</p> <p>DFS(G) u:11/ for each vertex u V[G] do u:11/ state[u] undiscovered [u] NIL time 0 x x for each vertex u V[G] do if state[u] = undiscovered then DFS-VISIT(u) DFS-VISIT(u) state[u] discovered d[u] time time + 1 for each v Adj[u] do if state[v] = undiscovered then [v] u DFS-VISIT(v) state[u] completely explored f[u] time time + 1</p> <p>2/14/02</p> <p>Introduction to Algorithms</p> <p>CLRS16.26</p> <p>Depth-first searchr:1/10 r:1/10 s:3/6 s:3/6 t:4/5 t:4/5</p> <p>v:2/9 v:2/9</p> <p>w:7/8 w:7/8</p> <p>DFS(G) u:11/ for each vertex u V[G] do u:11/ state[u] undiscovered [u] NIL time 0 x:12/ x:12/ for each vertex u V[G] do if state[u] = undiscovered then DFS-VISIT(u) DFS-VISIT(u) state[u] discovered d[u] time time + 1 for each v Adj[u] do if state[v] = undiscovered then [v] u DFS-VISIT(v) state[u] completely explored f[u] time time + 1</p> <p>2/14/02</p> <p>Introduction to Algorithms</p> <p>CLRS16.27</p> <p>Depth-first searchr:1/10 r:1/10 s:3/6 s:3/6 t:4/5 t:4/5</p> <p>v:2/9 v:2/9</p> <p>w:7/8 w:7/8</p> <p>DFS(G) u:11/ for each vertex u V[G] do u:11/ state[u] undiscovered [u] NIL time 0 x:12/13 x:12/13 for each vertex u V[G] do if state[u] = undiscovered then DFS-VISIT(u) DFS-VISIT(u) state[u] discovered d[u] time time + 1 for each v Adj[u] do if state[v] = undiscovered then [v] u DFS-VISIT(v) state[u] completely explored f[u] time time + 1</p> <p>2/14/02</p> <p>Introduction to Algorithms</p> <p>CLRS16.28</p> <p>Depth-first searchr:1/10 r:1/10 s:3/6 s:3/6 t:4/5 t:4/5 u:11/14 u:11/14</p> <p>Running time: (V + E)v:2/9 v:2/9 w:7/8 w:7/8 x:12/13 x:12/13</p> <p>Classification of edges tree edges: those on the DFS forest back edges: those that connect descendants to ancestors (self-loops, too) forward edges: non-tree edges connecting ancestors to descendants cross edges: all other edges2/14/02 Introduction to Algorithms</p> <p>CLRS16.29</p> <p>Depth-first searchr:1/10 r:1/10 s:3/6 s:3/6 t:4/5 t:4/5 u:11/14 u:11/14</p> <p>v:2/9 v:2/9</p> <p>w:7/8 w:7/8</p> <p>x:12/13 x:12/13</p> <p>r v s t w</p> <p>u x</p> <p>Theorem. (Parenthesis structure) Let I[u] = [d[u], f[u]]. Then either I[u] and I[v] are disjoint or one is entirely contained within the other.</p> <p>1 2 3 4 5 6 7 8 9 10 11 12 13 14 (r (v (s (t t) s) (w w) v) r) (u (x x) u)2/14/02 Introduction to Algorithms CLRS16.30</p> <p>Topological sortu u x x vv yy w w zzTOPOLOGICAL-SORT(G) call DFS(G) to compute the finishing times f[v] for each vertex v as each vertex is finished, insert it onto the front of a linked list return the linked list of vertices</p> <p>A topological sort of a dag G = (V, E) is a linear ordering p of V such that if (u, v) E then u p v. Lemma. A directed graph is acyclic if and only if a depth-first search of G yields no back edges.2/14/02 Introduction to Algorithms CLRS16.31</p> <p>Topological sortu:1/12 u:1/12 v:2/11 v:2/11 w:3/4 w:3/4</p> <p>x:6/7 x:6/7</p> <p>y:5/10 y:5/10</p> <p>z:8/9 z:8/9</p> <p>TOPOLOGICAL-SORT(G) call DFS(G) to compute the finishing times f[v] for each vertex v as each vertex is finished, insert it onto the front of a linked list return the linked list of vertices</p> <p>u u</p> <p>vv</p> <p>yy</p> <p>zz</p> <p>x x</p> <p>w w</p> <p>Topological sort: u p v p y p z p x p w Running time: (V + E)2/14/02 Introduction to Algorithms CLRS16.32</p> <p>Strongly connected componentsGiven a digraph G = (V, E). Write u v if there is a path from u to v in G.a a g g b b h h cc ii d d jj ee k k ff ll</p> <p>A strongly connected component of G is a maximal set of vertices C V such that for every pair u, v V, both u v and v u, that is, u and v are reachable from each other.2/14/02 Introduction to Algorithms CLRS16.33</p> <p>Strongly connected componentsA (V + E) algorithm:a:1/24 a:1/24 b:2/21 b:2/21 c:5/18 c:5/18 d:6/17 d:6/17 e:7/16 e:7/16 f:8/11 f:8/11</p> <p>g:22/23 g:22/23</p> <p>h:3/20 h:3/20</p> <p>i:4/19 i:4/19</p> <p>j:13/14 j:13/14</p> <p>k:12/15 k:12/15</p> <p>l:9/10 l:9/10</p> <p>STRONGLY-CONNECTED-COMPONENTS(G) call DFS(G) to compute the finishing times f[u] for each vertex u compute GT call DFS(GT), but in the mai...</p>