Generated on Tue Dec 16 12:49:16 2008 for BIU-2.2.0 by doxygen 1.5.1

src/biu/Graph_UD.cc

Go to the documentation of this file.
00001 #include "Graph_UD.hh"
00002 
00003 #include <stack>
00004 #include "assertbiu.hh"
00005 #include <limits.h>
00006 
00007 
00008 namespace biu
00009 {
00010 
00011     Graph_UD::Graph_UD( size_t nodeNumber) 
00012       : adjList(nodeNumber)
00013     {
00014     }
00015     
00016     Graph_UD::~Graph_UD()
00017     {
00018     }
00019     
00020     void
00021     Graph_UD::addEdge(const size_t n1, const size_t n2) {
00022         assertbiu(std::max(n1,n2) < adjList.size(), "node index out of range");
00023         adjList[n1].insert(n2);
00024         adjList[n2].insert(n1);
00025     }
00026 
00027     void 
00028     Graph_UD::remEdge(const size_t n1, const size_t n2) {
00029         assertbiu(std::max(n1,n2) < adjList.size(), "node index out of range");
00030         adjList[n1].erase(n2);
00031         adjList[n2].erase(n1);
00032     }
00033     
00034     bool
00035     Graph_UD::isEdge(const size_t n1, const size_t n2) {
00036         assertbiu(std::max(n1,n2) < adjList.size(), "node index out of range");
00037         return adjList[n1].find(n2) != adjList[n1].end();
00038     }
00039     
00040     size_t
00041     Graph_UD::nodes(void) const {
00042         return adjList.size();
00043     }
00044 
00045     size_t
00046     Graph_UD::edges(void) const {
00047         size_t num = 0;
00048         for(size_t i = 0; i< adjList.size(); i++) {
00049             num += adjList[i].size();
00050         }
00051         return num/2; // each edges was counted twice
00052     }
00053 
00054     size_t 
00055     Graph_UD::degree(const size_t n) const {
00056         return adjList[n].size();
00057     }
00058 
00059     size_t 
00060     Graph_UD::connectedComponents( Graph_UD::CompLabel & compID ) const {
00061           // initializing the labels
00062         compID.resize(adjList.size()); // resizing to neccessary size
00063           // check if anything to do
00064         if (adjList.size() == 0)
00065             return 0;
00066           // set initial labels
00067         for (Graph_UD::CompLabel::iterator it1 = compID.begin(); it1!=compID.end(); it1++) {
00068             *it1 = UINT_MAX;
00069         }
00070           // temp data
00071         size_t curLabel = 0;
00072         size_t lastInitID = 0;
00073         
00074         // recursion for complete graph exploration
00075         do {
00076               // color the connected component adjacent to node lastInitID
00077             labelAdjacentNodes(lastInitID, compID, curLabel);
00078               // shift lastInitID to next unseen node and therefore next component
00079             for (lastInitID++; lastInitID < compID.size() && compID[lastInitID] != UINT_MAX; lastInitID++);
00080               // increase connected component label
00081             curLabel++;
00082         } while (lastInitID < adjList.size());
00083         
00084         return curLabel;
00085     }
00086     
00087     // NON-RECURSIVE VERSION
00088     void 
00089     Graph_UD::labelAdjacentNodes( const size_t curNode, Graph_UD::CompLabel & compID, const size_t label) const {
00090         assertbiu( curNode < compID.size() , "initial node out of node index range");
00091         if (compID[curNode] != UINT_MAX)    // nothing to do
00092             return;
00093           // temporary stack and initialization
00094         typedef std::set<size_t>::const_iterator adjIT;
00095         std::stack<adjIT> path;
00096         compID[curNode] = label;
00097         
00098         if (adjList[curNode].empty()) // abortion if no adjacent nodes
00099             return;
00100         else
00101             path.push( adjList[curNode].begin() );  // add first adjacent node
00102         
00103         while ( !path.empty() ) {
00104             if ( compID[*path.top()] == UINT_MAX) {
00105                 compID[*path.top()] = label;    // set label
00106                 if ( ! adjList[*path.top()].empty() )   // add adjacency iterator
00107                     path.push( adjList[*path.top()].begin() );
00108             } else {
00109                 adjIT t = path.top(); // get head element
00110                 path.pop();
00111                 t++; // shift to next in list
00112                 // if a valid neighbor add to stack again
00113                 if ( (path.empty() && t != adjList[curNode].end()) || 
00114                     (!path.empty() && t != adjList[*path.top()].end()) ) { 
00115                     path.push(t);
00116                 }
00117             }
00118         }
00119     }
00120 /*  // RECURSIVE VERSION
00121     void 
00122     Graph_UD::labelAdjacentNodes( const size_t curNode, Graph_UD::CompLabel & compID, const size_t label) const {
00123         assertbiu( curNode < compID.size() , "initial node out of node index range");
00124           // recursion abortion
00125         if (compID[curNode] != UINT_MAX)
00126             return;
00127           // label current node
00128         compID[curNode] = label;
00129           // recursive labeling of all adjacent nodes if not already labeled.
00130         for (std::set<size_t>::const_iterator it = adjList[curNode].begin();
00131             it != adjList[curNode].end(); it++) 
00132         {
00133             labelAdjacentNodes(*it, compID, label);
00134         }
00135     }
00136 */
00137     void 
00138     Graph_UD::printDOT( std::ostream & out ) const {
00139         size_t i = 0;
00140           // initial header
00141         out <<"graph G {\n";
00142           // print node indices
00143         for (i=0; i<nodes(); i++)
00144             out <<" "<<i <<";";
00145         out <<"\n";
00146           // print edges
00147         for (i=0; i<nodes(); i++)
00148             for (std::set<size_t>::const_iterator it = adjList[i].begin(); it != adjList[i].end(); it++) 
00149                 if (i <= (*it))
00150                     out <<" " <<i <<"--" <<(*it) <<";\n";
00151           // closing
00152         out <<"}";
00153     }
00154     
00155     void
00156     Graph_UD::setNodeNumber(const size_t max) {
00157           // resize adjacency list
00158         adjList.resize(max);
00159           // remove all nodes with index >= max
00160         for (size_t i=0; i< adjList.size(); i++) {
00161             adjList[i].erase(adjList[i].find(max), adjList[i].end());
00162         }
00163     }
00164     
00165     Graph_UD::AdjItPair
00166     Graph_UD::adjNodes( const size_t n ) const
00167     {
00168         return AdjItPair(adjList[n].begin(), adjList[n].end());
00169     }
00170 
00171 
00172 }