120 likes | 137 Views
Explore algorithms for testing connectedness in undirected graphs and detecting cycles in directed and undirected graphs. Includes code implementation examples and review questions.
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.