Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members  

graph.h

00001 /*
00002  *      gtc.h - Graph Template Classes (alpha)
00003  *
00004  *      Copyright (c) 2003 - Norman Lippincott, Jr. - Saylorsburg PA USA
00005  *      All Rights Reserved
00006  *
00007  *      This library is free software; you can redistribute it and/or
00008  *      modify it under the terms of the GNU Lesser General Public
00009  *      License as published by the Free Software Foundation; either
00010  *      version 2.1 of the License, or (at your option) any later version.
00011  *
00012  *      This library is distributed in the hope that it will be useful,
00013  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  *      Lesser General Public License for more details.
00016  *
00017  *      You should have received a copy of the GNU Lesser General Public
00018  *      License along with this library; if not, write to the Free Software
00019  *      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00020  *
00021  *      The author may be contacted via e-mail at nl@acm.org.
00022  */
00023 
00024 /*
00025  *      Documentation for this library is produced directly from this source file
00026  *      using the Doxygen documentation system.
00027  *
00028  *      Please see http://www.doxygen.org/ for information about Doxygen.
00029  */
00030 
00031 #ifndef GTC_H
00032 #define GTC_H
00033 
00034 #include <algorithm>
00035 #include <list>
00036 #include <map>
00037 #include <queue>
00038 #include <set>
00039 #include <stack>
00040 #include <string>
00041 
00075 /*****************************************************************************
00076  * namespace gtc                                                             *
00077  *****************************************************************************/
00078 
00080 
00081 namespace gtc {
00082 
00083 /*****************************************************************************
00084  * class _base_graph                                                         *
00085  *****************************************************************************/
00086 
00087 
00089 
00099 template <typename K, typename W, typename T>
00100 class _base_graph {
00101 
00102 protected:
00104 
00108         _base_graph () {}
00109 
00111         _base_graph (size_t n);
00112 
00114         _base_graph (size_t n, const K& k);
00115 
00117         template <typename F>
00118         _base_graph (size_t n, F f);
00119 
00120 public:
00122         void add_node (const K& k);
00123 
00125         void add_node (const K& k, const T& t);
00126 
00128         std::size_t order () { return nod.size(); }
00129 
00131         size_t size() { return edg.size(); }
00132 
00134 
00139         T& operator[] (const K& k);
00140 
00142 
00153         class iterator {
00154         friend class _base_graph<K, W, T>;
00155         public:
00156                 iterator& operator++ () { ++it; return *this; }
00157                 iterator operator++ (int) { iterator i = (*this); ++it; return i; }
00158                 iterator& operator-- () { --it; return *this; }
00159                 iterator operator-- (int) { iterator i = (*this); --it; return i; }
00160 
00161                 std::pair<const K, T>& operator* () { return *it; }
00162                 std::pair<const K, T>* operator-> () { return &(*it); }
00163 
00164                 bool operator== (const iterator& i) { return it == i.it; }
00165                 bool operator!= (const iterator& i) { return it != i.it; }
00166 
00167         private:
00168                 std::map<K, T>::iterator begin, end;
00169                 std::map<K, T>::iterator it;
00170         };
00171 
00173         virtual iterator begin ();
00174 
00176         virtual iterator end ();
00177 
00179         virtual iterator find (const K& k);
00180 
00182 
00195         class edge {
00196         public:
00197 
00198                 edge (const K& k1, const K& k2, const W& w = 0) :
00199                         ky1(k1), ky2(k2), wt(w) {}
00200 
00201                 bool operator== (const edge& e) const
00202                         { return key1() == e.key1() && key2() == e.key2(); }
00203                 bool operator!= (const edge& e) const
00204                         { return key1() != e.key1() || key2() != e.key2(); }
00205 
00207                 const K& key1 () const { return ky1; }
00208 
00210                 const K& key2 () const { return ky2; }
00211 
00213 
00223                 const K& key (const K& k);
00224 
00226                 K& weight () { return wt; }
00227 
00228         private:
00229                 K ky1;
00230                 K ky2;
00231                 W wt;
00232         };
00233 
00235         virtual bool is_edge (const K& k1, const K& k2) = 0;
00236 
00238 
00251         class edge_iterator {
00252         friend class _base_graph<K, W, T>;
00253         public:
00254                 edge_iterator& operator++ ();
00255                 edge_iterator operator++ (int);
00256                 edge_iterator& operator-- ();
00257                 edge_iterator operator-- (int);
00258 
00259                 edge& operator* () { return *it; }
00260                 edge* operator-> () { return &(*it); }
00261 
00262                 bool operator== (const edge_iterator& i) { return it == i.it; }
00263                 bool operator!= (const edge_iterator& i) { return it != i.it; }
00264 
00265         private:
00266                 std::list<edge>::iterator begin, end;
00267                 std::list<edge>::iterator it;
00268 
00269                 K key;
00270         };
00271 
00273         edge_iterator begin (const K& k);
00274 
00276         edge_iterator end (const K& k);
00277 
00279         template <typename F>
00280         F BFS (const K& k, F f);
00281 
00283         template <typename F>
00284         F DFS (const K& k, F f);
00285 
00286 protected:
00287         std::map<K, T> nod;
00288         std::list<edge> edg;
00289 };
00290 
00291 template <typename K, typename W, typename T>
00292 _base_graph<K, W, T>::_base_graph (size_t n)
00293 {
00304         K key(1);
00305 
00306         for (size_t i = 0; i < n; i++)
00307                 nod[key++] = T();
00308 }
00309 
00310 template <typename K, typename W, typename T>
00311 _base_graph<K, W, T>::_base_graph (size_t n, const K& k)
00312 {
00322         K key(k);
00323 
00324         for (size_t i = 0; i < n; i++)
00325                 nod[key++] = T();
00326 }
00327 
00328 template <typename K, typename W, typename T>
00329 template <typename F>
00330 _base_graph<K, W, T>::_base_graph (size_t n, F f)
00331 {
00340         for (size_t i = 0; i < n; i++)
00341                 nod[f()] = T();
00342 }
00343 
00344 template <typename K, typename W, typename T>
00345 void _base_graph<K, W, T>::add_node (const K& k)
00346 {
00353         if (nod.find(k) != nod.end())
00354                 throw std::string("_base_graph::add_node - node already exists");
00355         nod[k] = T();
00356 }
00357 
00358 template <typename K, typename W, typename T>
00359 void _base_graph<K, W, T>::add_node (const K& k, const T& t)
00360 {
00366         if (nod.find(k) != nod.end())
00367                 throw std::string("_base_graph::add_node - node already exists");
00368         nod[k] = t;
00369 }
00370 
00371 template <typename K, typename W, typename T>
00372 _base_graph<K, W, T>::iterator _base_graph<K, W, T>::begin ()
00373 {
00374         iterator i;
00375         i.begin = nod.begin();
00376         i.end = nod.end();
00377 
00378         i.it = i.begin;
00379 
00380         return i;
00381 }
00382 
00383 template <typename K, typename W, typename T>
00384 _base_graph<K, W, T>::edge_iterator _base_graph<K, W, T>::begin (const K& k)
00385 {
00386         edge_iterator i;
00387         i.begin = edg.begin();
00388         i.end = edg.end();
00389         i.key = k;
00390 
00391         i.it = i.begin;
00392         while (i.it != i.end && i.it->key1() != i.key && i.it->key2() != i.key) {
00393                 i.it++;
00394         }
00395 
00396         return i;
00397 }
00398 
00399 template <typename K, typename W, typename T>
00400 _base_graph<K, W, T>::iterator _base_graph<K, W, T>::end ()
00401 {
00402         iterator i;
00403         i.begin = nod.begin();
00404         i.end = nod.end();
00405 
00406         i.it = i.end;
00407 
00408         return i;
00409 }
00410 
00411 template <typename K, typename W, typename T>
00412 _base_graph<K, W, T>::edge_iterator _base_graph<K, W, T>::end (const K& k)
00413 {
00414         edge_iterator i;
00415         i.begin = edg.begin();
00416         i.end = edg.end();
00417         i.key = k;
00418 
00419         i.it = i.end;
00420 
00421         return i;
00422 }
00423 
00424 template <typename K, typename W, typename T>
00425 _base_graph<K, W, T>::iterator _base_graph<K, W, T>::find (const K& k)
00426 {
00427         iterator i;
00428         i.begin = nod.begin();
00429         i.end = nod.end();
00430         i.it = nod.find(k);
00431 
00432         return i;
00433 }
00434 
00435 template <typename K, typename W, typename T>
00436 template <typename F>
00437 F _base_graph<K, W, T>::BFS (const K& k, F f)
00438 {
00450          K cur;
00451          std::queue<K> q;
00452          std::set<K> v;
00453 
00454          q.push(k);
00455          v.insert(k);
00456 
00457          while (!q.empty()) {
00458 
00459                 cur = q.front();
00460                 q.pop();
00461                 f(cur);
00462 
00463                 for (iterator i = begin(); i != end(); i++)
00464                         if (is_edge(cur, i->first))
00465                                 if (v.find(i->first) == v.end()) {
00466                                         q.push(i->first);
00467                                         v.insert(i->first);
00468                                 }
00469          }
00470 
00471          return f;
00472 }
00473 
00474 template <typename K, typename W, typename T>
00475 template <typename F>
00476 F _base_graph<K, W, T>::DFS (const K& k, F f)
00477 {
00489         K cur = k;
00490         std::set<K> v;
00491         std::stack<K> s;
00492 
00493         do {
00494                 if (v.find(cur) == v.end()) {
00495                         f(cur);
00496                         s.push(cur);
00497                         v.insert(cur);
00498                 }
00499                 iterator i = begin();
00500                 while (i != end() && v.find(i->first) != v.end())
00501                         i++;
00502                 if (i != end())
00503                         cur = i->first;
00504                 else {
00505                         s.pop();
00506                         if (!s.empty())
00507                                 cur = s.top();
00508                 }
00509         } while (!s.empty());
00510 
00511         return f;
00512 }
00513 
00514 template <typename K, typename W, typename T>
00515 T& _base_graph<K, W, T>::operator[] (const K& k)
00516 {
00522         if (nod.find(k) == nod.end())
00523                 throw std::string("_base_graph::operator[] - node does not exist");
00524         return nod[k];
00525 }
00526 
00527 template <typename K, typename W, typename T>
00528 const K& _base_graph<K, W, T>::edge::key (const K& k)
00529 {
00530         if (k != key1() && k != key2())
00531                 throw std::string("graph::edge::key - key supplied is invalid");
00532 
00533         return k == key1() ? key2() : key1();
00534 }
00535 
00536 template <typename K, typename W, typename T>
00537 _base_graph<K, W, T>::edge_iterator& _base_graph<K, W, T>::edge_iterator::operator++ ()
00538 {
00539         ++it;
00540         while (it != end && it->key1() != key && it->key2() != key)
00541                 ++it;
00542 
00543         return *this;
00544 }
00545 
00546 template <typename K, typename W, typename T>
00547 _base_graph<K, W, T>::edge_iterator _base_graph<K, W, T>::edge_iterator::operator++ (int)
00548 {
00549         edge_iterator tmp = *this;
00550 
00551         ++it;
00552         while (it != end && it->key1() != key && it->key2() != key)
00553                 ++it;
00554 
00555         return tmp;
00556 }
00557 
00558 template <typename K, typename W, typename T>
00559 _base_graph<K, W, T>::edge_iterator& _base_graph<K, W, T>::edge_iterator::operator-- ()
00560 {
00561         --it;
00562         while (it != begin && it->key1() != key && it->key2() != key)
00563                 --it;
00564         if (it == begin)
00565                 while (it != end && it->key1() != key && it->key2() != key)
00566                         ++it;
00567 
00568         return *this;
00569 }
00570 
00571 template <typename K, typename W, typename T>
00572 _base_graph<K, W, T>::edge_iterator _base_graph<K, W, T>::edge_iterator::operator-- (int)
00573 {
00574         edge_iterator tmp = *this;
00575 
00576         --it;
00577         while (it != begin && it->key1() != key && it->key2() != key)
00578                 --it;
00579         if (it == begin)
00580                 while (it != end && it->key1() != key && it->key2() != key)
00581                         ++it;
00582 
00583         return tmp;
00584 }
00585 
00586 /*****************************************************************************
00587  * class graph                                                               *
00588  *****************************************************************************/
00589 
00591 
00599 template <typename K, typename T = void*>
00600 class graph : public _base_graph<K, void*, T> {
00601 
00602 public:
00604         graph () : _base_graph<K, void*, T>() {}
00605 
00607         graph (size_t n) : _base_graph<K, void*, T>(n) {}
00608 
00610         graph (size_t n, const K& k) : _base_graph<K, void*, T>(n, k) {}
00611 
00613         template <typename F>
00614         graph (size_t n, F f) : _base_graph<K, void*, T>(n, f) {}
00615 
00617         void add_edge (const K& k1, const K& k2);
00618 
00620         bool is_edge (const K& k1, const K& k2);
00621 
00623         void remove_edge (const K& k1, const K& k2);
00624 };
00625 
00626 template <typename K, typename T>
00627 void graph<K, T>::add_edge (const K& k1, const K& k2)
00628 {
00636         if (nod.find(k1) == nod.end() || nod.find(k2) == nod.end())
00637                 throw std::string("add_edge: Node does not exist");
00638 
00639         // Store lower key value in first key of edge
00640         if (k1 < k2)
00641                 edg.push_back(edge(k1, k2));
00642         else
00643                 edg.push_back(edge(k2, k1));
00644 }
00645 
00646 template <typename K, typename T>
00647 bool graph<K, T>::is_edge (const K& k1, const K& k2)
00648 {
00656         if (nod.find(k1) == nod.end() || nod.find(k2) == nod.end())
00657                 throw std::string("is_edge: Node does not exist");
00658 
00659         if (k1 < k2)
00660                 return std::find(edg.begin(), edg.end(), edge(k1, k2)) != edg.end();
00661         return std::find(edg.begin(), edg.end(), edge(k2, k1)) != edg.end();
00662 }
00663 
00664 template <typename K, typename T>
00665 void graph<K, T>::remove_edge (const K& k1, const K& k2)
00666 {
00673         if (nod.find(k1) == nod.end() || nod.find(k2) == nod.end())
00674                 throw std::string("add_edge: Node does not exist");
00675 
00676         if (k1 < k2)
00677                 edg.remove(edge(k1, k2));
00678         else
00679                 edg.remove(edge(k2, k1));
00680 }
00681 
00682 /*****************************************************************************
00683  * class wgraph                                                              *
00684  *****************************************************************************/
00685 
00687 
00696 template <typename K, typename W, typename T = void*>
00697 class wgraph : public _base_graph<K, W, T> {
00698 
00699 public:
00701         wgraph () : _base_graph<K, W, T>() {}
00702 
00704         wgraph (size_t n) : _base_graph<K, W, T>(n) {}
00705 
00707         wgraph (size_t n, const K& k) : _base_graph<K, W, T>(n, k) {}
00708 
00710         template <typename F>
00711         wgraph (size_t n, F f) : _base_graph<K, W, T>(n, f) {}
00712 
00714         void add_edge (const K& k1, const K& k2, const W& w);
00715 
00717         bool is_edge (const K& k1, const K& k2);
00718 
00720         void remove_edge (const K& k1, const K& k2);
00721 
00723         W& weight (const K& k1, const K& k2);
00724 };
00725 
00726 template <typename K, typename W, typename T>
00727 void wgraph<K, W, T>::add_edge (const K& k1, const K& k2, const W& w)
00728 {
00736         if (nod.find(k1) == nod.end() || nod.find(k2) == nod.end())
00737                 throw std::string("add_edge: Node does not exist");
00738 
00739         // Store lower key value in first key of edge
00740         if (k1 < k2)
00741                 edg.push_back(edge(k1, k2, w));
00742         else
00743                 edg.push_back(edge(k2, k1, w));
00744 }
00745 
00746 template <typename K, typename W, typename T>
00747 bool wgraph<K, W, T>::is_edge (const K& k1, const K& k2)
00748 {
00756         if (nod.find(k1) == nod.end() || nod.find(k2) == nod.end())
00757                 throw std::string("is_edge: Node does not exist");
00758 
00759         if (k1 < k2)
00760                 return std::find(edg.begin(), edg.end(), edge(k1, k2)) != edg.end();
00761         return std::find(edg.begin(), edg.end(), edge(k2, k1)) != edg.end();
00762 }
00763 
00764 template <typename K, typename W, typename T>
00765 void wgraph<K, W, T>::remove_edge (const K& k1, const K& k2)
00766 {
00773         if (nod.find(k1) == nod.end() || nod.find(k2) == nod.end())
00774                 throw std::string("add_edge: Node does not exist");
00775 
00776         if (k1 < k2)
00777                 edg.remove(edge(k1, k2));
00778         else
00779                 edg.remove(edge(k2, k1));
00780 }
00781 
00782 template <typename K, typename W, typename T>
00783 W& wgraph<K, W, T>::weight (const K& k1, const K& k2)
00784 {
00785         if (nod.find(k1) == nod.end() || nod.find(k2) == nod.end())
00786                 throw std::string("weight: Node does not exist");
00787         if (!is_edge(k1, k2))
00788                 throw std::string("weight: Edge does not exist");
00789 
00790         if (k1 < k2)
00791                 return std::find(edg.begin(), edg.end(), edge(k1, k2))->weight();
00792         return std::find(edg.begin(), edg.end(), edge(k2, k1))->weight();
00793 }
00794 
00795 /*****************************************************************************
00796  * class digraph                                                             *
00797  *****************************************************************************/
00798 
00800 
00808 template <typename K, typename T = void*>
00809 class digraph : public _base_graph<K, void*, T> {
00810 
00811 public:
00813         digraph () : _base_graph<K, void*, T>() {}
00814 
00816         digraph (size_t n) : _base_graph<K, void*, T>(n) {}
00817 
00819         digraph (size_t n, const K& k) : _base_graph<K, void*, T>(n, k) {}
00820 
00822         template <typename F>
00823         digraph (size_t n, F f) : _base_graph<K, void*, T>(n, f) {}
00824 
00826         void add_edge (const K& k1, const K& k2);
00827 
00829         bool is_edge (const K& k1, const K& k2);
00830 
00832         void remove_edge (const K& k1, const K& k2);
00833 };
00834 
00835 template <typename K, typename T>
00836 void digraph<K, T>::add_edge (const K& k1, const K& k2)
00837 {
00845         if (nod.find(k1) == nod.end() || nod.find(k2) == nod.end())
00846                 throw std::string("add_edge: Node does not exist");
00847 
00848         edg.push_back(edge(k1, k2));
00849 }
00850 
00851 template <typename K, typename T>
00852 bool digraph<K, T>::is_edge (const K& k1, const K& k2)
00853 {
00861         if (nod.find(k1) == nod.end() || nod.find(k2) == nod.end())
00862                 throw std::string("is_edge: Node does not exist");
00863 
00864         return std::find(edg.begin(), edg.end(), edge(k1, k2)) != edg.end();
00865 }
00866 
00867 template <typename K, typename T>
00868 void digraph<K, T>::remove_edge (const K& k1, const K& k2)
00869 {
00876         if (nod.find(k1) == nod.end() || nod.find(k2) == nod.end())
00877                 throw std::string("add_edge: Node does not exist");
00878 
00879         edg.remove(edge(k1, k2));
00880 }
00881 
00882 /*****************************************************************************
00883  * class wdigraph                                                            *
00884  *****************************************************************************/
00885 
00887 
00896 template <typename K, typename W, typename T = void*>
00897 class wdigraph : public _base_graph<K, W, T> {
00898 
00899 public:
00901         wdigraph () : _base_graph<K, W, T>() {}
00902 
00904         wdigraph (size_t n) : _base_graph<K, W, T>(n) {}
00905 
00907         wdigraph (size_t n, const K& k) : _base_graph<K, W, T>(n, k) {}
00908 
00910         template <typename F>
00911         wdigraph (size_t n, F f) : _base_graph<K, W, T>(n, f) {}
00912 
00914         void add_edge (const K& k1, const K& k2, const W& w);
00915 
00917         bool is_edge (const K& k1, const K& k2);
00918 
00920         void remove_edge (const K& k1, const K& k2);
00921 
00923         W& weight (const K& k1, const K& k2);
00924 };
00925 
00926 template <typename K, typename W, typename T>
00927 void wdigraph<K, W, T>::add_edge (const K& k1, const K& k2, const W& w)
00928 {
00936         if (nod.find(k1) == nod.end() || nod.find(k2) == nod.end())
00937                 throw std::string("add_edge: Node does not exist");
00938 
00939         edg.push_back(edge(k1, k2, w));
00940 }
00941 
00942 template <typename K, typename W, typename T>
00943 bool wdigraph<K, W, T>::is_edge (const K& k1, const K& k2)
00944 {
00952         if (nod.find(k1) == nod.end() || nod.find(k2) == nod.end())
00953                 throw std::string("is_edge: Node does not exist");
00954 
00955         return std::find(edg.begin(), edg.end(), edge(k1, k2)) != edg.end();
00956 }
00957 
00958 template <typename K, typename W, typename T>
00959 void wdigraph<K, W, T>::remove_edge (const K& k1, const K& k2)
00960 {
00967         if (nod.find(k1) == nod.end() || nod.find(k2) == nod.end())
00968                 throw std::string("add_edge: Node does not exist");
00969 
00970         edg.remove(edge(k1, k2));
00971 }
00972 
00973 template <typename K, typename W, typename T>
00974 W& wdigraph<K, W, T>::weight (const K& k1, const K& k2)
00975 {
00976         if (nod.find(k1) == nod.end() || nod.find(k2) == nod.end())
00977                 throw std::string("weight: Node does not exist");
00978         if (!is_edge(k1, k2))
00979                 throw std::string("weight: Edge does not exist");
00980 
00981         return std::find(edg.begin(), edg.end(), edge(k1, k2))->weight();
00982 }
00983 
00984 } // namespace gtc
00985 
00986 #endif

Generated on Thu Oct 16 10:50:08 2003 for C++ GTC by doxygen1.2.15