120 likes | 134 Vues
Testing for Connectedness and Cycles. Connectedness of Undirected Graphs Implementation of Connectedness detection Algorithm for Undirected Graphs. Implementation of Strong Connectedness Algorithm. Cycles in Directed Graphs. Implementation of Cycle detection Algorithm for Directed Graphs.
E N D
Testing for Connectedness and Cycles • Connectedness of Undirected Graphs • Implementation of Connectedness detection Algorithm for Undirected Graphs. • Implementation of Strong Connectedness Algorithm. • Cycles in Directed Graphs. • Implementation of Cycle detection Algorithm for Directed Graphs. • Cycles in Undirected Graphs • Review Questions.
Connectedness of Undirected Graphs • An undirected graph G = (V, E) is connected if there is a path between every pair of vertices. • Although the figure below appears to be two graphs, it is actually a single graph. • Clearly, G is not connected. For example there is no path between A and D. • G consists of two unconnected parts, each of which is a maximal connected sub-graph (i.e., a connected component).
Implementation of Connectedness Algorithm for Undirected Graphs • A simple way to test for connectedness in an undirected graph is to use either depth-first or breadth-first traversal starting from any vertex - Only if all the vertices are visited is the graph connected. The algorithm uses the following visitor: public class CountingVisitor extends AbstractVisitor { protected int counter; public int getCount(){ return counter;} public void visit(Object obj) {counter++;} } • Using the CountingVisitor, the isConnected method is implemented as follows: public boolean isConnected() { if(this.isDirected()) throw new InvalidOperationException( "Invalid for Directed Graphs"); CountingVisitor visitor = new CountingVisitor(); Iterator i = getVertices(); Vertex start = (Vertex) i.next(); breadthFirstTraversal(visitor, start); return visitor.getCount() == numberOfVertices; }
Connectedness of Directed Graphs • A directed graph G = (V, E) is strongly connected if there is a directed path between every pair of vertices [i.e, given any pair of vertices v1 and v2, there is a directed path from v1 to v2, and there is a directed path from v2 to v1]. • A directed graph G =(V, E) is weakly connected if: • The underlying undirected graph is connected, and if • The is at least one pair of vertices v1 and v2 that are not reachable from one another. • A directed graph G = (V, E) is disconnected if the underlying undirected graph is disconnected. Example: A weakly connected directed graph
Implementation of Strong Connectedness Algorithm • A simple way to test for strong connectedness in a directed graph G = (V, E) is to use |V| traversals, each traversal starting from a different graph vertex - The graph is strongly connected if in each traversal all vertices are visited; otherwise it is either disconnected or it is weakly connected. public boolean isStronglyConnected() { if (!this.isDirected()) throw new InvalidOperationException( "Invalid for Undirected Graphs"); Iterator it = getVertices(); while(it.hasNext()) { CountingVisitor visitor = new CountingVisitor(); breadthFirstTraversal(visitor, (Vertex) it.next()); if(visitor.getCount() != numberOfVertices) return false; } return true; } • Note: The implementation of weak connectedness algorithm is a task in the Lab.
Detection of Cycles in Directed Graphs • One algorithm to detect the presence of cycles in a directed graph uses source-removal topological order traversal algorithm. • This algorithm visits all the vertices of a directed graph if the graph has no cycles; otherwise not all vertices are visited. • Example: In the graph below, after A is visited and removed, all the remaining vertices have in-degree of one. Thus, a topological order traversal cannot complete. This is because of the presence of the cycle { B, C, D, B}. public boolean isCyclic() { if (!this.isDirected()) throw new InvalidOperationException( "Invalid for Undirected Graphs"); CountingVisitor visitor = new CountingVisitor(); topologicalOrderTraversal(visitor); return visitor.getCount() != numberOfVertices; }
Detection of Cycles in Directed Graphs: DFS based Algorithm dfsAllVertices(G){ color all vertices white; for( each v V) if (v is white){ if (DFS(v)) Output(“cycle detected”); exit;} Output(“No cycle detected”); } boolean DFS(v){ color[v] = “gray”; [previsit(v)] for (each w adjacent to v){ if(color[w] == “gray”){ return true;} // Cycle exists if (color[w] == “white”){ [ Add edge (v, w) to DFS tree] DFS(w); } } [postvisit(v)] color[v] = black; return false; // No cycle exists in the group of vertices reachable from current v } A cycle exits in a directed graph if a back edge is detected during a DFS traversal. A back edge exists in a directed graph if the currently explored vertex has an adjacent vertex that was already colored gray
Detection of Cycles in Undirected Graphs: Algorithm1 dfsAll(G){ for each vertex v of G{ color[v] = “white”; parent[v] = null; } for each vertex v of G { if( color[v] == “white”) if(DFS(v)) {Output(“Cycle detected”); exit;}; } Output(“No cycle detected”); } boolean DFS(v){ color[v] = “gray”; for( each vertex w adjacent to v ){ if (color[w] == “white”){ parent[w] = v; DFS(w); } else if( color[w] == “gray” and parent[w] != v) return true; // cycle detected } color[v] = black; return false; // no cycle detected in this component } • The algorithm traverses the graph, ignoring each back edge from a vertex to the parent of that vertex. If an edge (v, w) is encountered where both v and w are colored gray, and vis not the parent of w in the DFS tree, a cycle exists in the graph.
Detection of Cycles in Undirected Graphs: Algorithm1 (Cont’d) • Exercise: Trace the algorithm in the previous slide on the graph given below starting at vertex A : • Note: The graph is represented as shown below. The representation is not a multi-graph:
Detection of Cycles in Undirected Graphs: Algorithm2 • This algorithm is based on the fact that an undirected acyclic graph G = (V, E) is a free tree, in which |E| = |V| - 1; however since each edge in an undirected graph is represented by two edges; the relationship used in the algorithm is |E|/2 = |V| - 1 • Thus a connected component of an undirected graph has a cycle if |Ecomponent| / 2 |Vcomponent| • The algorithm is given in the next slide
Detection of Cycles in Undirected Graphs: Algorithm2 (Cont’d) DFSAll(G){ Mark all vertices as unvisited; for(i = 0; i < numberOfVertices; i++){ if(vertexi is not visited){ ncce = 0; // global variable, numberOfConnectedComponentEdges nccv = 0; // global variable, numberOfConnectedComponentVertices DFS(vertexi, nccv, ncce); if(ncce/2 nccv){ Output("There is a cycle"); return; } } } Output("There is no cycle"); } DFS(v, nccv, ncce){ mark v visited; nccv++; for(each vertex w adjacent to v){ ncce++; if(w is not visited) DFS(w, nccv, ncce); } }
Review Questions 1. Every tree is a directed, acyclic graph (DAG), but there exist DAGs that are not trees. a) How can we tell whether a given DAG is a tree? b) Devise an algorithm to test whether a given DAG is a tree. 2. Consider an acyclic, connected, undirected graph G that has n vertices. How many edges does G have? 3. In general, an undirected graph contains one or more connected components. a) Devise an algorithm that counts the number of connected components in a graph. b) Devise an algorithm that labels the vertices of a graph in such a way that all the vertices in a given connected component get the same label and vertices in different connected components get different labels. 4. Devise an algorithm that takes as input a graph, and a pair of vertices, v and w, and determines whether w is reachable from v.