adj_list.h

00001 /*
00002  *  Copyright (C) 2005 M.J. Zaki <zaki@cs.rpi.edu>, Rensselaer Polytechnic Institute
00003  *  Written by parimi@cs.rpi.edu
00004  *  Updated by chaojv@cs.rpi.edu, alhasan@cs.rpi.edu, salems@cs.rpi.edu
00005  *
00006  *  This program is free software; you can redistribute it and/or
00007  *  modify it under the terms of the GNU General Public License
00008  *  as published by the Free Software Foundation; either version 2
00009  *  of the License, or (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License along
00017  *  with this program; if not, write to the Free Software Foundation, Inc.,
00018  *  59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
00019  */
00020 
00021 #ifndef _ADJ_LIST
00022 #define _ADJ_LIST
00023 
00024 #include <ext/hash_map>
00025 #include <algorithm>
00026 #include <map>
00027 #include <sstream>
00028 #include <iostream>
00029 
00030 using namespace std;
00031 
00032 
00033 template<typename VERTEX_T, typename EDGE_T, template <typename> class ALLOC> struct vertex_info;
00034 template<typename VERTEX_T, typename EDGE_T, template <typename> class ALLOC>
00035 ostream& operator<< (ostream&, const vertex_info<VERTEX_T, EDGE_T, ALLOC>&);
00036 
00038 template<typename VERTEX_T, typename EDGE_T, template <typename> class ALLOC=std::allocator>
00039 struct vertex_info
00040 {
00041 
00042   typedef pair<int, EDGE_T> EDGE_P;
00043   typedef vector<EDGE_P, ALLOC<EDGE_P> > EDGES;
00044   typedef typename EDGES::iterator EIT;
00045   typedef typename EDGES::const_iterator CONST_EIT;
00046   
00047   vertex_info(const VERTEX_T& vert, const int& idval): v(vert), id(idval) {}
00049   EIT out_begin() {return out_edges.begin();}
00051   CONST_EIT out_begin() const {return out_edges.begin();}
00053   EIT out_end() {return out_edges.end();}
00055   CONST_EIT out_end() const {return out_edges.end();}
00056   
00058   EIT in_begin() {return in_edges.begin();}
00060   CONST_EIT in_begin() const {return in_edges.begin();}
00062   EIT in_end() {return in_edges.end();}
00064   CONST_EIT in_end() const {return in_edges.end();}
00066   void add_out_edge(const int& dest, const EDGE_T& e)
00067   {
00068     //out_edges.insert(make_pair(dest, e));
00069     out_edges.push_back(make_pair(dest, e));
00070   }
00072   void add_in_edge(const int& src, const EDGE_T& e)
00073   {
00074     //in_edges.insert(make_pair(src, e));
00075     in_edges.push_back(make_pair(src, e));
00076   }
00077 
00082   bool out_edge(const int& dest, EDGE_T& e) const {
00083     CONST_EIT it;
00084     for(it=out_begin(); it!=out_end(); it++)
00085       if(it->first==dest) {
00086         e=it->second;
00087         return true;
00088     }
00089     return false;
00090   }//out_edge()
00091    
00094   bool in_edge(const int& src, EDGE_T& e) const {
00095     CONST_EIT it;
00096     for(it=in_begin(); it!=in_end(); it++)
00097       if(it->first==src) {
00098         e=it->second;
00099         return true;
00100       }
00101     return false;
00102   }//in_edge()
00104   bool operator< (const vertex_info<VERTEX_T, EDGE_T, ALLOC>& vertex2) const {
00105 
00106      if(v < vertex2.v)
00107         return true;
00108      else
00109         return false;
00110   }
00111 
00113   friend ostream& operator<< <>(ostream&, const vertex_info<VERTEX_T, EDGE_T, ALLOC>&);
00114 
00116   VERTEX_T v; //vertex object
00117   int id; //id of this vertex
00118   EDGES out_edges; //stores all edges for an undirected graph
00119   EDGES in_edges; //calls to this member should be made only for digraphs
00120 
00121 }; //end struct vertex_info
00122 
00123 // overloaded extraction over a pair - used by following hash_map extraction
00124 template<typename E_T>
00125 ostream& operator<< (ostream& ostr, const std::pair<int, E_T>& p) {
00126   ostr<<"("<<p.first<<" "<<p.second<<")";
00127   return ostr;
00128 }
00129 
00130 // overloaded extraction over the edgelist map
00131 template<typename E_T>
00132 ostream& operator<< (ostream& ostr, const vector<pair<int, E_T> >& hm) {
00133   typename vector<pair<int, E_T> >::const_iterator it;
00134   for(it=hm.begin(); it!=hm.end(); it++)
00135     std::cout<<*it<<" ";
00136   return ostr;
00137 }
00138 
00139 
00140 //friend extraction over output streams
00141 template<typename V_T, typename E_T>
00142 ostream& operator<< (ostream& ostr, const vertex_info<V_T, E_T>& vi) {
00143   ostr<<"["<<vi.id<<"|"<<vi.v<<"] OUT: ";
00144   typename vertex_info<V_T, E_T>::CONST_EIT it;
00145   ostr<<vi.out_edges;
00146   ostr<<" IN: ";
00147   ostr<<vi.in_edges;
00148   ostr<<endl;
00149   return ostr;
00150 }//end operator<<
00151 
00152 template<typename V_T, typename E_T, template <typename> class ALLOC >
00153 class adj_list;
00154   
00155 template<typename V_T, typename E_T, template <typename> class ALLOC >
00156 ostream& operator<< (ostream&, const adj_list<V_T, E_T, ALLOC>&);
00157 
00164 template<typename V_T, typename E_T, template <typename> class ALLOC=std::allocator>
00165 class adj_list
00166 {
00167 
00168  public:
00169   typedef V_T VERTEX_T;
00170   typedef E_T EDGE_T;
00171   typedef vertex_info<VERTEX_T, EDGE_T, ALLOC> VERTEX_INFO;
00172   typedef adj_list<V_T, E_T, ALLOC > ADJ_L;
00173 
00174   template<typename T>
00175   class VERTEX_LIST: public std::vector<T, ALLOC<T> > {};//each vertex and its info is stored as a vector, for fast lookup since we'll know its unique id
00176 
00177   typedef VERTEX_LIST<VERTEX_INFO> ADJ_LIST;
00178 
00179   typedef typename ADJ_LIST::iterator IT;
00180   typedef typename ADJ_LIST::const_iterator CONST_IT;
00181   typedef typename VERTEX_INFO::EIT EIT;
00182   typedef typename VERTEX_INFO::CONST_EIT CONST_EIT;
00183   typedef std::pair<EIT, EIT> EIT_PAIR;
00184   typedef std::pair<CONST_EIT, CONST_EIT> CONST_EIT_PAIR;
00185 
00186   void* operator new(size_t size) {
00187     ALLOC<ADJ_L> aa;
00188     return aa.allocate(size);
00189   }
00190 
00191   void  operator delete(void *p, size_t size) {
00192     if (p) {
00193       ALLOC<ADJ_L> aa;
00194       aa.deallocate(static_cast<ADJ_L*> (p), size);
00195     }
00196   }
00197  
00198   //default constructor
00199   adj_list() {}
00200     
00201   IT begin() {return _alist.begin();}
00202   CONST_IT begin() const {return _alist.begin();}
00203   IT end() {return _alist.end();}
00204   CONST_IT end() const {return _alist.end();}
00205 
00206   inline
00207   int size() const {return _alist.size();} 
00208   void clear() {_alist.clear();}
00209   void push_back(const VERTEX_INFO& vi) {_alist.push_back(vi);}
00210 
00212   IT vertex_vals(const int&);
00213 
00214   CONST_IT vertex_vals(const int& idval) const {
00215     CONST_IT it=_alist.begin();
00216     if(idval>size()-1) {
00217   std::cerr<<"adj_list.vertex_vals: out of range vertex id, "<<idval<<endl;
00218   exit(0);
00219     }
00220     it+=idval;
00221     return it;
00222   }// end vertex_vals() const
00223 
00226   std::pair<EIT, EIT> out_edges(const int& idval) {
00227     IT it=vertex_vals(idval);
00228     return make_pair(it->out_begin(), it->out_end());
00229   }//end out_edges()
00230   
00231   std::pair<CONST_EIT, CONST_EIT> out_edges(const int& idval) const {
00232     CONST_IT it=vertex_vals(idval);
00233     return make_pair(it->out_begin(), it->out_end());
00234   }//end out_edges() const
00235 
00238   std::pair<EIT, EIT> in_edges(const int& idval) {
00239     IT it=vertex_vals(idval);
00240     return make_pair(it->in_begin(), it->in_end());
00241   }//end in_edges()
00242   
00243   std::pair<CONST_EIT, CONST_EIT> in_edges(const int& idval) const {
00244     CONST_IT it=vertex_vals(idval);
00245     return make_pair(it->in_begin(), it->in_end());
00246   }//end in_edges() const
00247 
00249   int out_nbr_size(const int& vid) const {
00250     pair<CONST_EIT, CONST_EIT> out_pit=out_edges(vid);
00251     return out_pit.second-out_pit.first;
00252   }
00253 
00255   int in_nbr_size(const int& vid) const {
00256     pair<CONST_EIT, CONST_EIT> in_pit=in_edges(vid);
00257     return in_pit.second-in_pit.first;
00258   }
00259 
00262   int add_vertex(const VERTEX_T& v) {
00263     _alist.push_back(VERTEX_INFO(v, size()));
00264     return size()-1;
00265   } // end add_vertex()
00266   
00268   void add_out_edge(const int& src, const int& dest, const EDGE_T& e) {
00269     if((src>size()-1) || (dest>size()-1)) {
00270       std::cerr<<"adj_list::add_out_edge:out of bound vertex IDs, src="<<src<<" dest="<<dest<<" size()="<<_alist.size()<<endl;
00271       exit(0);
00272     }
00273     
00274     IT it=vertex_vals(src);
00275     it->add_out_edge(dest, e);
00276     
00277   } // end add_out_edge()
00278 
00280   void add_in_edge(const int& dest, const int& src, const EDGE_T& e) {
00281     if((src>size()-1) || (dest>size()-1)) {
00282       std::cerr<<"adj_list::add_in_edge:out of bound vertex IDs, src="<<src<<" dest="<<dest<<" size()="<<_alist.size()<<endl;
00283       exit(0);
00284     }
00285     
00286     IT it=vertex_vals(dest);
00287     it->add_in_edge(src, e);
00288     
00289   } // end add_in_edge()
00290 
00291 
00294   bool get_out_edge(const int& src, const int& dest, EDGE_T& e) const {
00295     CONST_IT it=vertex_vals(src);
00296     return it->out_edge(dest, e);
00297   }//end get_edge()      
00298 
00301   bool get_in_edge(const int& src, const int& dest, EDGE_T& e) const {
00302     CONST_IT it=vertex_vals(src);
00303     return it->in_edge(dest, e);
00304   }//end get_edge()      
00305 
00306   // friend output extraction
00307   friend ostream& operator<< <>(ostream&, const adj_list<V_T, E_T, ALLOC>&);
00308   
00309  private:
00310   ADJ_LIST _alist;
00311   //int _sz;
00312   
00313 }; //end class adj_list
00314 
00315 
00316 // friend extraction over output stream
00317 template<typename V_T, typename E_T, template <typename> class ALLOC>
00318 ostream& operator<< (ostream& ostr, const adj_list<V_T, E_T, ALLOC>& al) {
00319   typename adj_list<E_T, V_T, ALLOC>::CONST_IT it=al.begin();
00320   while(it!=al.end()) {
00321     ostr<<*it;
00322     it++;
00323   }
00324   ostr<<"---";
00325   return ostr;
00326 }
00327 
00328 template<typename V_T, typename E_T, template <typename> class ALLOC >
00329 typename adj_list<V_T, E_T, ALLOC>::IT adj_list<V_T, E_T, ALLOC>::vertex_vals(const int& idval) {
00330   typename adj_list<V_T, E_T, ALLOC>::IT it=_alist.begin();
00331   if(idval>size()-1) {
00332     std::cerr<<"adj_list.vertex_vals: out of range vertex id, "<<idval<<endl;
00333     exit(0);
00334   }
00335   it+=idval;
00336   return it;
00337 }// end vertex_vals()
00338 
00339 
00340 #endif

Generated on Wed Jul 26 14:01:08 2006 for DMTL by  doxygen 1.4.7