210 likes | 351 Views
Connected Components: The LEDA Implementation. Melissa Patton 252a-ae Smith College December 12, 2000. Contents. Connected Components LEDA’s implementation COMPONENTS() Structures it uses DFS() Its variables An explanation of the function Its time complexity
E N D
Connected Components:The LEDA Implementation Melissa Patton 252a-ae Smith College December 12, 2000
Contents • Connected Components • LEDA’s implementation • COMPONENTS() • Structures it uses • DFS() • Its variables • An explanation of the function • Its time complexity • code for calling COMPONENTS() • simple call of function • possible code if called using LEDA window system • Some websites that where helpful to me in my research • Summary
Connected Components An example of a connected components using gw_basic_graph_algorithm for LEDA
COMPONENTS() int COMPONENTS(ugraph& G, node_array<int& compnum) { node v,w; list<node S; int count = 0; node_array(bool) reached(G,false); forall_nodes(v,G) if ( !reached[v] ) { S = DFS(G,v,reached); forall(w,S) compnum[w] = count; count++; } return count; }
Structures used by COMPONENT() int COMPONENTS(ugraph& G, node_array<int& compnum) { node v,w; list<node S; int count = 0; node_array(bool) reached(G,false); forall_nodes(v,G) if ( !reached[v] ) { S = DFS(G,v,reached); forall(w,S) compnum[w] = count; count++; } return count; } • Undirected graph • Graph G • node array • Interger (compnum) • Boolean (reached) • list • list of nodes S
DFS() //------------------------------------------------------------------------------ // Depth First Search //------------------------------------------------------------------------------ #include <LEDA/graph_alg.h> static void dfs(node s, node_array<bool>& reached, list<node>& L) { L.append(s); reached[s] = true; node v; forall_adj_nodes(v,s) if ( !reached[v] ) dfs(v,reached,L); } list<node> DFS(const graph&, node v, node_array<bool>& reached) { list<node> L; dfs(v,reached,L); return L; } • DFS() is used by COMPONENTS() to determine which nodes are connected to each other. • Each node in a single DFS() tree is given the same number. • DFS is given the graph, a node to start from, and a flag ‘reached’ to mark visited nodes. Leda code for DFS ( _dfs.c )
How COMPONENTS() works int COMPONENTS(ugraph& G, node_array<int& compnum) { node v,w; list<node S; int count = 0; node_array(bool) reached(G,false); forall_nodes(v,G) if ( !reached[v] ) { S = DFS(G,v,reached); forall(w,S) compnum[w] = count; count++; } return count; } • Receives an undirected graph G and an empty array of nodes compnum • If it is possible to reach node v then set ever node that can reach it to the number in count, then increment count • It returns the number of reachable nodes
COMPONENTS()- variables int COMPONENTS(ugraph& G, node_array<int& compnum) { node v,w; list<node S; int count = 0; node_array(bool) reached(G,false); forall_nodes(v,G) if ( !reached[v] ) { S = DFS(G,v,reached); forall(w,S) compnum[w] = count; count++; } return count; } • v is used to cycle through all the nodes in the graph. • w works as an index. It is used to run giving all connected nodes the same label • S is a list of nodes reachable from a node v • count is used to label each node in the graph and later returns the number of connected components
COMPONENTS() variable cont. int COMPONENTS(ugraph& G, node_array<int& compnum) { node v,w; list<node S; int count = 0; node_array(bool) reached(G,false); forall_nodes(v,G) if ( !reached[v] ) { S = DFS(G,v,reached); forall(w,S) compnum[w] = count; count++; } return count; } • Reached is an array with an entry for each node in G. All of its entries are set to False.
COMPONENTS() -its actions int COMPONENTS(ugraph& G, node_array<int& compnum) { node v,w; list<node S; int count = 0; node_array(bool) reached(G,false); forall_nodes(v,G) if ( !reached[v] ) { S = DFS(G,v,reached); forall(w,S) compnum[w] = count; count++; } return count; } The steps of this function
COMPONENTS() -its actions forall_nodes(v,G) if ( !reached[v] ) { S = DFS(G,v,reached); forall(w,S) compnum[w] = count; count++; } return count; • Takes place on every node in the Graph • If a node is currently unreachable, do a DFS and return a list of al the nodes it connects to • Set every node that was reached to have the same label • Increment the count • COMPONENTS() returns the number components in the graph along with the labeled nodes
COMPONENTS() -its actions forall_nodes(v,G) if ( !reached[v] ) { S = DFS(G,v,reached); forall(w,S) compnum[w] = count; count++; } return count; • Takes place on every node in the Graph • If a node is currently unreachable, do a DFS and return a list of the numbers of the nodes it connects to • Set every node that was reached to have the same label • Increment the count • COMPONENTS() returns the number components in the graph along with the labeled nodes
COMPONENTS() -its actions forall_nodes(v,G) if ( !reached[v] ) { S = DFS(G,v,reached); forall(w,S) compnum[w] = count; count++; } return count; • Takes place on every node in the Graph • If a node is currently unreachable, do a DFS and return a list of al the nodes it connects to • Give every reachable node the same label (indicated by count) • Increment the count • COMPONENTS() returns the number components in the graph along with the labeled nodes
COMPONENTS() -its actions forall_nodes(v,G) if ( !reached[v] ) { S = DFS(G,v,reached); forall(w,S) compnum[w] = count; count++; } return count; • Takes place on every node in the Graph • If a node is currently unreachable, do a DFS and return a list of al the nodes it connects to • Set every node that was reached to have the same label • Increment the count • COMPONENTS() returns the number components in the graph along with the labeled nodes
COMPONENTS() -its actions forall_nodes(v,G) if ( !reached[v] ) { S = DFS(G,v,reached); forall(w,S) compnum[w] = count; count++; } return count; • Takes place on every node in the Graph • If a node is currently unreachable, do a DFS and return a list of al the nodes it connects to • Set every node that was reached to have the same label • Increment the count • COMPONENTS() returns the number components in the graph along with the node labels
The time complexity of COMPONENTS() int COMPONENTS(ugraph& G, node_array<int& compnum) { node v,w; list<node S; int count = 0; node_array(bool) reached(G,false); forall_nodes(v,G) if ( !reached[v] ) { S = DFS(G,v,reached); forall(w,S) compnum[w] = count; count++; } return count; } • COMPONENTS() has the running time O(V+E) 1. Forall_nodes(v,G) iteraticely cycles through every node v in the Graph G O(V) 2. DFS will eventually run through every edge in the graph O(V+E) 3. Forall(w,S) will run on all the nodes in G, and only once on each node O(V) So the running time will be (3V +E) = O(V+E) 1 2 1 3 2 3
Simple code to call COMPONENTS() #include <LEDA/graph_alg.h> #include <LEDA/array.h> /* Initalize a graph */ graph G; /*---------------------MakeGraph-------------------------*/ void MakeGraph() { node first, second, third, four, five; int nnodes, nedges; /*COMPONENTS() works on undirected graphs*/ G.make_undirected(); /*Add objects to the graph*/ first = G.new_node(); second = G.new_node(); third = G.new_node(); four = G.new_node(); five = G.new_node(); /*Add an edge between the following nodes*/ G.new_edge(first, second); G.new_edge(third, five); /*Get the number of nodes and edges*/ nnodes = G.number_of_nodes(); nedges = G.number_of_edges(); cout<<"There are "<<nnodes<<" nodes and "<<nedges<<" edges"<<endl; }/* end of MakeGraph */ /*---------------------CallComponents-------------------------*/ void CallComponents() { int count; node_array<int> nodenumber(G); /* call the function COMPONENTS() and receive the number of components */ count = COMPONENTS(G,nodenumber); cout<<"*|*****************************************************|*"<<endl; cout<<"*|-----------------------------------------------------|*"<<endl; cout<<"*| This graph has <-- "<<count<<" --> connected components |*"<<endl; cout<<"*|-----------------------------------------------------|*"<<endl; cout<<"*|*****************************************************|*"<<endl; }/* end of CallComponent */ /*---------------------Main-------------------------*/ void main() { cout<<"This program calls COMPONENTS() on this graph with this:"<<endl; cout<<"---------------------------"<<endl; cout<<"| [1]----[2] [3] [4] |"<<endl; cout<<"| | |"<<endl; cout<<"| [5] |"<<endl; cout<<"---------------------------"<<endl<<endl; /**** make the graph above ****/ MakeGraph(); /**** calling COMPONENTS*******/ CallComponents(); }/* end of main */ /* End of comptest.cpp */
Code to call COMPONENTS() using the LEDA windows system #include <LEDA/graph_alg.h> #include <LEDA/graphwin.h> #include <LEDA/array.h> void Concomp(GraphWin& gw) {graph& G = gw.get_graph(); node_array<int> nodenumber(G); COMPONENTS(G,nodenumber); forall_nodes(v, G) {gw.set_color(v,nodenumber[v]); gw.set_user_label(v,string (” ”<<nodenumber[v])<<“ “); gw.set_label_type(v,user_label); } } int main() { gw.add_simple_call(Concomp,"CONNECTED COMPONENTS"); gw.display(window::center,window::center); window& W = gw.get_window(); gw.edit(); return 0;} This code SHOULD work for windows, but is currently untested gw.set_init_graph_handler(del_edge_handler); gw.set_new_edge_handler(new_edge_handler); gw.set_del_edge_handler(del_edge_handler); gw.set_new_node_handler(new_node_handler); gw.set_del_node_handler(del_node_handler); gw.set_directed(false); gw.set_node_shape(circle_node); gw.set_node_label_type(user_label); gw.set_node_width(20); #ifdef BOOK gw.set_node_color(white); #endif
Helpful sources in my research • LEDA • Manual • Book • online (http://www.cs.bgu.ac.il/~cgproj/LEDA/) • graph_alg.h • gw_basic_graph_algorithm.c • http://www-pool.math.tu-berline.de/doc/LEDA/ • http://www.sedan.uni-osnabrueck.de/~sewi/leda.html • extremely useful, but also written German • http://www.altavista.com (babelfish) • http://dictionaries.travlang.com/GermanEnglish/ • an German to English online dictionary
Summary • LEDA implements connected components using the function COMPONENTS() • This function takes an undirected graph and an array of nodes and returns the number of connected componets using the variable count. • It iterates over a recursive DFS to find the connect components and number them • COMPONENTS() has a complexity of O(V+E) • If you need to translate something on line …go to altavista