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