2.15k likes | 2.17k Views
Explore graph theory concepts and representation methods, including adjacency matrix and lists. Learn graph types, edges, vertices, and graph connectivity. Understand complete, sparse, and dense graphs.
E N D
Decomposition of Graph • In the remaining of this chapter, we will cover graphs, • including Depth-First Search and Breadth-First Search • and Topological Sorting
Graphs: • A graph G = (V, E) is defined by a pair of two sets: • V is a finite set of vertices (nodes) and • E is a set of pairs of vertices, called edges. • This definition disallows multiple edges between the same vertices of an undirected graph. • If these pairs of vertices are unordered, i.e., a pair of vertices (u, v) is the same as the pair (v, u), we say • that the vertices u and v are adjacent to each other and • that they are connected by the undirected edge (u, v).
We said that • the vertices u and v are endpoints of the edge (u, v) and • u and v are incident to this edge; • the edge (u, v) is incident to its endpoints u and v. • A graph G is calledundirectedif every edge in it is undirected.
Directed graph • If a pair of vertices (u, v) is not the same as the pair (v, u) we say that the edge (u, v) is directed from the vertexu, called the edge’s tail, to the vertex v, called the edge’s head. u v • We also say that the edge (u, v) leaves u and enters v. • A graph whose every edge is directed is called a directed graph, which are also called a digraph.
The following inequality for the number of edges |E| which is possible in an undirected graph with |V| vertices and no loops (self-loop?): • 0 ≤ |E| ≤ |V| (|V| - 1) • Example 3.4: • Let the number of vertices |V| = 6. • The max number of edges |E| = (|V| * |V-1|) = (6 * 5 ) = 15. • a c b • d e f
A graph with every pair of its vertices connected by an edge is called complete. • K|V|is used to denote a complete graph with |V| vertices. • A graph with relatively few possible edges missing is called dense. • A graph with few edges relative to the number of its vertices is called sparse.
Example 3.5: Let G = (V, E) be an undirected graph where V = { a, b, c, d, e, f} E = {(a, c), (a, d), (b, c), (b, f), (c, e), (d, e), (e, f)} a c b d e f It is not a complete graph since not every pair of vertices is connected by an edge; for example, there is no edge between a and b, between c and d, etc.
Example 3.6: Let G = (V, E) be a digraph, where V = { a, b, c, d, e, f} E = {(a, c), (b, c), (b, f), (c, e), (d, a), (d, e), (e, c), (e, f)} a c b d e f
Graph representation • Graphs for computer algorithm can be represented in two ways: • the adjacency matrix and • adjacency lists.
A graph or digraph can be represented by an adjacency matrix; if there are n = |V| vertices v1, v2, …, vn, this is an n x n array whose (irow, jcol)th entry is 1 if there is an edge from vi to vj, aij = 0 otherwise. The adjacency matrix of a graph with n vertices is an n-by-n Boolean matrix with one row and one column for each of the graph’s vertices, in which theelement in(irow, jcol)th entry is equal to 1if there is an edge from the ithvertex to thejthvertex, and theelement in (irow, jcol)th entry is equal to 0 if there is no such edge. The following adjacency matrix is of the graph in Example 3.5.
Example 3.5: An adjacency matrix for the graph G. Let G = (V, E) be an undirected graph where V = { a, b, c, d, e, f} E = {(a, c), (a, d), (b, c), (b, f), (c, e), (d, e), (e, f)} a c b d e f
The adjacency matrix of a graph with n vertices • The biggest convenience of this format is that the presence of a particular edge can be checked in constant time Θ(1), with just one memory access. (is the entry of ith row and jth column A[i, j] = 1.) • But the matrix takes up O(n2) space, which is wasteful if the graph does not have very many edges.
The adjacency lists of a graph or a digraph is a collection of linked lists one for each vertex, that contain all the vertices adjacent to the list’s vertex (i.e., all the vertices connected to it by an edge). The following adjacency lists is of the graph in Example 3.5.
Example 3.5: An adjacency list for the graph G Let G = (V, E) be an undirected graph where V = { a, b, c, d, e, f} E = {(a, c), (a, d), (b, c), (b, f), (c, e), (d, e), (e, f)} a c b d e f
The adjacency-list consists of |V| linked lists, one per vertex. • For a directgraph, each edge appears in exactly one of the linked lists. • For an undirectedgraph, each edge is represented by two of the lists. • For undirected graphs, this representation has a symmetry of sorts: v is in u’s adjacency list if and only if u is in v’s adjacency list. • The total size of the data structure is O(|E|) for either way. • Checking for a particular edge (u, v) for a digraph is no longer constant time, because it requires sifting through u’s adjacency list. • But it is easy to iterate through all neighbors of a vertex (by running down the corresponding linked list). But the matrix takes up O(n2) space O(|V|)
Two representations of a directed graph G with 6 vertices and 9 edges: • An adjacency-list representation of G. • An adjacency-matrix representation of G.
Example 3.6: An adjacency-list representation of a digraph G. Let G = (V, E) be a digraph, where V = { a, b, c, d, e, f} E = {(a, a) (a, c), (b, c), (b, f), (c, e), (d, a), (d, e), (e, c), (e, f)} c a b f d e What is the best data structure needed to support DFS and BFS?
Example 3.6: An adjacency-matrix representation of a digraph G. Let G = (V, E) be a digraph, where V = { a, b, c, d, e, f} E = {(a, a), (a, c), (b, c), (b, f), (c, e), (d, a), (d, e), (e, c), (e, f)} What is the best data structure needed to support DFS and BFS? c a b f d e
c • Weighted graphs • A weighted graph (or weighted digraph) is a graph (or digraph) with numbers (called weights or costs) assigned to its edges. • Both adjacency-list and adjacency-matrix representations of a graph can be extended to accommodate weighted graphs. • For a weighted graph which is represented by its adjacency-matrix, its element A[i, j] will simply contain • the weight of the edge from the ith vertex to the jthvertex if there is such an edge and • a special symbol, e.g., ∞, there is no such edge. • Such a matrix is called the weight matrix or cost matrix.
c Example of a weighted graph a 5 b 1 4 c 2 d 7 The weight matrix or cost matrix. 7
Paths, Cycles, Connectivity and Acyclicity. • Apathfrom vertex u to vertex v of a graph G can be defined as a sequence of adjacent (connected by an edge) vertices that starts with u and ends with v. • p = { u = u0, u1, u2, … , un = v | for all ui, ui+1 ε V and (ui, ui+1) ε E} • A path of length n from a vertex u to a vertex v in a graph G=(V, E) is a sequence < u = u0, u1, u2, … , un = v> of vertices such that (ui-1, ui ) ε E for 1≤ i ≤ n. • Thelengthof a path is the total number of vertices in a vertex sequence defining the path minus one, (|V| - 1), which is the same as the number of edges in the path. c
The path contains the vertices u = u0, u1, u2, … , un = v and the edges (u0, u1), (u1 , u2 ), …, (un-1, un ). • There is always a 0-length path from u to u. • If there is a path p from u to v, we say that v is reachable from u via p, which we denote as u v if G is directed. • A path is said to be simple, if all vertices of a path are distinct • Psimple = { u = u0, u1, u2, … , un = v | for all ui, ui+1, uj ε V and • (ui, ui+1) ε E, ui, ≠ ui+1 ≠ uj }. c ui, ≠ ui+1 ≠ uj, ui, ≠ uj and ui+1 ≠ uj rule out a cyclic.
Example 3.5: Let G = (V, E) be an undirected graph where V = { a, b, c, d, e, f} E = {(a, c), (a, d), (b, c), (b, f), (c, e), (d, e), (e, f)} a c b d e f a, c, b, f is a simple pathof length 3 from a to f. a, c, e, c, b, f is a path (not simple)of length 5 from a to f. So as a, d, e, c, b, f, e is not a simple path for e appears twice.
Example 3.6: Let G = (V, E) be a digraph, where V = { a, b, c, d, e, f} E = {(a, a) (a, c), (b, c), (b, f), (c, e), (d, a), (d, e), (e, c), (e, f)} For example: In the directed graph, a, c, e, f is a directed path from a to f in the graph. c a b A directed path is a sequence of vertices in which every consecutive pair of the vertices is connected by an edge directed from the vertex listed first to the vertex listed next. f d e
c A graph is said to be connected if for every pair of its vertices u and v there is a path from u to v. {Are there any difference between directed graph and undirected graph?} A subgraphof a given graph G = (V, E) is a graph G’ = (V’, E’) such that V’ (is a subset of) V and E’ E. Formally, a connected component is a maximal (not expandable via an inclusion of an extra vertex) connected subgraph of a given graph. Example: All the given graphs in our previous examples are connected.
Example 3.7 a f b c e g h d i a node k The graph is not connected because there is no path, for example, from a to f. However, it does have three disjoint connected regions, corresponding to the following sets of vertices: {a, b, c, d, e}, {f, g, h, i}, {k}. c k These regions are called connected components: each of them is a subgraph that is internally connected but has no edges to the remaining vertices.
A cycle is a path <u = u0, u1, u2, … , un = v> of a positive length (that is the path contains at least one edge) that starts and ends at the same vertex (that is u = v) [and does not traverse the same edge more than once]. The cycle is simpleif, in addition, u = u0, u1, u2, … , un = v are distinct.
Example 3.7 a f b c e g h d i a node k k For example, the path < f, g, i, h, f > is a cycle. The paths < f, g, i, h, f >, < g, i, h, f, g> , < i, h, f, g, i> and < h, f, g, i, h > form the same cycle. These cycles are simple. The path < f, g, i, h, g, f > is not a simple cycle.
c A graph with no cycles is said to be acyclic. An undirected graph is connected if every vertex is reachable from all other vertices. The connected components of a graph are the equivalence classes of vertices under the “is reachable from” relation. 6 5 4 3 2 1
The graph has three connected components: {1, 2, 5}, {3, 6} and { 4 } An undirected graph is connected if it has exactly one connected component. c 6 5 4 3 2 1
Depth-First Search and Breadth-First Search Algorithms • Viewed as applications of the decrease-by-one technique. • Doing their main job of visiting vertices and traversing edges of a graph.
Depth-First Search Depth-first search is a surprisingly versatile linear-time procedure that reveals a wealth of information about a graph. The most basic question it addresses is, What parts of the graph are reachable from a given vertex? To understand this task, consider a given graph, say in the form of an adjacency list. This representation offers just one basic operation: finding the neighbors of a vertex. With only this primitive, the reachability problem is rather like exploring a labyrinth. Given the following Figure 3.1, clearly you need to record some intermediate information during exploration. c
Figure 3.1: Exploring a graph is rather like navigating a maze. c
c E D A B I J G H C F L K
Clearly during exploration (/expand?) for any graph traversal, • we need to mark for each vertex by maintaining a Boolean variable for indicating whether a vertex has been visited already. • We need a stack with two primitive operations: push the new vertex (i.e., unwind to get to a new junction), and pop the stack (i.e., rewind to return to the previous junction).
Starts visiting vertices of a graph at an arbitrary vertex by marking it as having been visited. • On each iteration, the algorithm proceeds to an unvisited vertex that is adjacent to the one it is currently in. • If there are several such vertices, a tie can be resolved arbitrarily. As a practical matter, which of the adjacent unvisited candidates is chosen is dictated by the data structure representing the graph. • The process continues until a dead end – a vertex with no adjacent unvisited vertices – is encountered. • At a dead end, the algorithm backs up one edge to the vertex it came from and tries to continue visiting unvisited vertices from there. • The algorithm eventually halts after backing up to the starting vertex, with the latter being a dead end. • By then, all the verticesin the same connected component as the starting vertex have been visited. • If unvisited vertices still remain, the depth-first search must be restarted at any one of them.
c • A stack is used to trace the operation of depth-first search. • Push a vertex onto the stack when the vertex is reached for the first time (i.e., the visit of the vertex starts), and • Pop a vertex off the stack when it becomes a dead end (i.e., the visit of the vertex ends).
Accompanying a depth-first search traversal, let construct the so-called depth-first search forest. • [Traversal of a graph] The traversal’s starting vertex serves as the root of the first tree in such a forest. • [Form a tree] Whenever a new unvisited vertex is reached for the first time, it is attached as a child to the vertex from which it is being reached. Such an edge is called a tree edge because the set of all such edges forms a forest. • The algorithm may also encounter an edge leading to a previously visited vertex other than its immediate predecessor (i.e., its parent in the tree). Such an edge is called a back edgebecause it connects a vertex to its ancestor, other than the parent, in the depth-first search forest. c
[e.g., Traverse from a, to c { (a, c) is a tree edge}, then d {(c, d)atree edge}. At d it is a dead end. But go from d to a {(d, a) is aback edge}. Or …]. c a a c c d d a0 c d c0 a d d0 a c back edge d3 1 c2 2 a1 3 null tree edge
Instead of explicitly maintaining a stack, we will do so implicitly via recursion (which is implemented using a stack of activation records). The resulting algorithm is shown in Algorithm DFS(G).
The depth-first Search Algorithm Algorithm DFS(G) //Implements a depth-first search traversal of a given graph //Input: Graph G =(V, E) //Output: Graph G with its vertices marked with consecutive integer in // the order they are first encountered by the DFS traversal mark each vertex in V with 0 as a mark of being “unvisited”; count ← 0; //a global variable; use for timestamp for each vertex v in V do if v is marked with 0 dfs(v); ; //end if and end for-do
Algorithm DFS(G) … dfs(v) //visits recursively all the unvisited vertices connected to vertex v by a path //and numbers them in the order they are encountered via global variable count count ← count + 1; mark v with count; for each vertex w in V adjacent to v do if w is marked with 0 dfs(w); //end if and end for-do
Example 3.8: An example of a depth-first search traversal, with the traversal’s stack and corresponding depth-first search forest shown as well. (a) Graph a e Input: An adjacency list a → c → d → e b → e → f c → a → d → f d → a → c e → a → b → f f → b → c → e g → h → j h → g → i i → h → j j → g → i c g h e a f c b d j i
Example 3.8: An example of a depth-first search traversal, with the traversal’s stack and corresponding depth-first search forest shown as well. (a) Graph c Input: An adjacency list a,0 → c → d → e b,0 → e → f c,0 → a → d → f d,0 → a → c e,0 → a → b → f f,0 → b → c → e g,0 → h → j h,0 → g → i i,0 → h → j j,0 → g → i g,0 h,0 e,0 a,0 f,0 c,0 b,0 d,0 j,0 i,0 e6, 2 b5, 3 j10, 7 d3, 1 f4, 4 i9, 8 c2, 5 h8, 9 a1, 6g7, 10
(b) Traversal’s stack: • the first subscript number indicates the order in which a vertex was visited, i.e., pushed onto the stack; • the second one indicates the order in which it became a dead-end, i.e., popped off the stack. • e6, 2 • b5, 3 j10, 7 • d3, 1 f4, 4 i9, 8 • c2, 5 c2, 5 h8, 9 • a1, 6 a1, 6 g7, 10 c
(b) Traversal’s stack: • the first subscript number indicates the order in which a vertex was visited, i.e., pushed onto the stack; • the second one indicates the order in which it became a dead-end, i.e., popped off the stack. • e6, 2 • b5, 3 j10, 7 • d3, 1 f4, 4 i9, 8 • c2, 5 c2, 5 h8, 9 • a1, 6 a1, 6 g7, 10 a g c h d f i b j e c Parenthesis structure : (a (c ( d d) (f (b (e e) b) f) c ) a) (g (h (i (j j) i) h) g) (push-onto pop-off) or (discover finish) order
If we represent, using timestamp, • the discovery (push onto) of vertex u with a left parenthesis “(u”, and • its finishing (pop off) by a right parenthesis “u )”, • then the history of discoveries and finishingscan be written as • a well-formed expression that the parentheses are properly nested. c Parenthesis structure : (a (c ( d d) (f (b (e e) b) f) c ) a) (g (h (i (j j) i) h) g)
The predecessor and successor of a node X in a binary tree, assuming all keys are distinct? 12, 13, 17, 20, 24, 25, 27 30, 33 30 Inorder walks: 20 30 39 X 20 39 c 25 36 50 13 51 40 38 27 17 24 33 12 Successor(X) Predecessor(X)
The predecessor and successor of a node X in a binary tree, assuming all keys are distinct? 30 20 Predecessor(X) 50 c 28 55 24 48 23 25 21 X Successor(X) 22