Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

path.h

Go to the documentation of this file.
00001 /* -*- C++ -*-
00002  * lemon/path.h - Part of LEMON, a generic C++ optimization library
00003  *
00004  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
00005  * (Egervary Research Group on Combinatorial Optimization, EGRES).
00006  *
00007  * Permission to use, modify and distribute this software is granted
00008  * provided that this copyright notice appears in all copies. For
00009  * precise terms see the accompanying LICENSE file.
00010  *
00011  * This software is provided "AS IS" with no warranty of any kind,
00012  * express or implied, and with no claim as to its suitability for any
00013  * purpose.
00014  *
00015  */
00016 
00033 
00034 
00035 
00036 
00037 
00038 
00039 #ifndef LEMON_PATH_H
00040 #define LEMON_PATH_H
00041 
00042 #include <deque>
00043 #include <vector>
00044 #include <algorithm>
00045 
00046 #include <lemon/invalid.h>
00047 
00048 namespace lemon {
00049 
00052 
00053 
00065   template<typename Graph>
00066   class DirPath {
00067   public:
00069     typedef typename Graph::Edge GraphEdge;
00071     typedef typename Graph::Node GraphNode;
00072     class NodeIt;
00073     class EdgeIt;
00074 
00075   protected:
00076     const Graph *gr;
00077     typedef std::vector<GraphEdge> Container;
00078     Container edges;
00079 
00080   public:
00081 
00084     DirPath(const Graph &_G) : gr(&_G) {}
00085 
00090     DirPath(const DirPath &P, const NodeIt &a, const NodeIt &b) {
00091       gr = P.gr;
00092       edges.insert(edges.end(), P.edges.begin()+a.idx, P.edges.begin()+b.idx);
00093     }
00094 
00099     DirPath(const DirPath &P, const EdgeIt &a, const EdgeIt &b) {
00100       gr = P.gr;
00101       edges.insert(edges.end(), P.edges.begin()+a.idx, P.edges.begin()+b.idx);
00102     }
00103 
00105     int length() const { return edges.size(); }
00107     bool empty() const { return edges.empty(); }
00108 
00110     void clear() { edges.clear(); }
00111 
00116     GraphNode source() const {
00117       return empty() ? INVALID : gr->source(edges[0]);
00118     }
00123     GraphNode target() const {
00124       return empty() ? INVALID : gr->target(edges[length()-1]);
00125     }
00126 
00131     template<typename It>
00132     It& first(It &i) const { return i=It(*this); }
00133 
00135     NodeIt& nth(NodeIt &i, int n) const {
00136       return i=NodeIt(*this, n);
00137     }
00138 
00140     EdgeIt& nth(EdgeIt &i, int n) const {
00141       return i=EdgeIt(*this, n);
00142     }
00143 
00146     NodeIt target(const EdgeIt& e) const {
00147       return NodeIt(*this, e.idx+1);
00148     }
00149 
00152     NodeIt source(const EdgeIt& e) const {
00153       return NodeIt(*this, e.idx);
00154     }
00155 
00156 
00157     /* Iterator classes */
00158 
00167     class EdgeIt {
00168       friend class DirPath;
00169 
00170       int idx;
00171       const DirPath *p;
00172     public:
00174       EdgeIt() {}
00176       EdgeIt(Invalid) : idx(-1), p(0) {}
00178       EdgeIt(const DirPath &_p, int _idx = 0) :
00179         idx(_idx), p(&_p) { validate(); }
00180 
00182       bool valid() const { return idx!=-1; }
00183 
00185       operator GraphEdge () const {
00186         return valid() ? p->edges[idx] : INVALID;
00187       }
00188 
00190       EdgeIt& operator++() { ++idx; validate(); return *this; }
00191 
00193       bool operator==(const EdgeIt& e) const { return idx==e.idx; }
00195       bool operator!=(const EdgeIt& e) const { return idx!=e.idx; }
00197       bool operator<(const EdgeIt& e) const { return idx<e.idx; }
00198 
00199     private:
00200       void validate() { if(idx >= p->length() ) idx=-1; }
00201     };
00202 
00211     class NodeIt {
00212       friend class DirPath;
00213 
00214       int idx;
00215       const DirPath *p;
00216     public:
00218       NodeIt() {}
00220       NodeIt(Invalid) : idx(-1), p(0) {}
00222       NodeIt(const DirPath &_p, int _idx = 0) :
00223         idx(_idx), p(&_p) { validate(); }
00224 
00226       bool valid() const { return idx!=-1; }
00227 
00229       operator const GraphNode& () const {
00230         if(idx >= p->length())
00231           return p->target();
00232         else if(idx >= 0)
00233           return p->gr->source(p->edges[idx]);
00234         else
00235           return INVALID;
00236       }
00238       NodeIt& operator++() { ++idx; validate(); return *this; }
00239 
00241       bool operator==(const NodeIt& e) const { return idx==e.idx; }
00243       bool operator!=(const NodeIt& e) const { return idx!=e.idx; }
00245       bool operator<(const NodeIt& e) const { return idx<e.idx; }
00246 
00247     private:
00248       void validate() { if(idx > p->length() ) idx=-1; }
00249     };
00250 
00251     friend class Builder;
00252 
00268     class Builder {
00269       DirPath &P;
00270       Container front, back;
00271 
00272     public:
00275       Builder(DirPath &_p) : P(_p) {}
00276 
00278 
00284       void setStartNode(const GraphNode &) {}
00285 
00287 
00290       void pushFront(const GraphEdge& e) {
00291         front.push_back(e);
00292       }
00293 
00295 
00298       void pushBack(const GraphEdge& e) {
00299         back.push_back(e);
00300       }
00301 
00303       void commit() {
00304         if( !front.empty() || !back.empty() ) {
00305           Container tmp;
00306           tmp.reserve(front.size()+back.size()+P.length());
00307           tmp.insert(tmp.end(), front.rbegin(), front.rend());
00308           tmp.insert(tmp.end(), P.edges.begin(), P.edges.end());
00309           tmp.insert(tmp.end(), back.begin(), back.end());
00310           P.edges.swap(tmp);
00311           front.clear();
00312           back.clear();
00313         }
00314       }
00315 
00317 
00320 
00321       void reserveFront(size_t r) {front.reserve(r);}
00322 
00324 
00327 
00328       void reserveBack(size_t r) {back.reserve(r);}
00329 
00330     private:
00331       bool empty() {
00332         return front.empty() && back.empty() && P.empty();
00333       }
00334 
00335       GraphNode source() const {
00336         if( ! front.empty() )
00337           return P.gr->source(front[front.size()-1]);
00338         else if( ! P.empty() )
00339           return P.gr->source(P.edges[0]);
00340         else if( ! back.empty() )
00341           return P.gr->source(back[0]);
00342         else
00343           return INVALID;
00344       }
00345       GraphNode target() const {
00346         if( ! back.empty() )
00347           return P.gr->target(back[back.size()-1]);
00348         else if( ! P.empty() )
00349           return P.gr->target(P.edges[P.length()-1]);
00350         else if( ! front.empty() )
00351           return P.gr->target(front[0]);
00352         else
00353           return INVALID;
00354       }
00355 
00356     };
00357 
00358   };
00359 
00360 
00361 
00362 
00363 
00364 
00365 
00366 
00367 
00368 
00369   /**********************************************************************/
00370 
00371 
00386   template<typename Graph>
00387   class UndirPath {
00388   public:
00390     typedef typename Graph::Edge GraphEdge;
00392    typedef typename Graph::Node GraphNode;
00393     class NodeIt;
00394     class EdgeIt;
00395 
00396   protected:
00397     const Graph *gr;
00398     typedef std::vector<GraphEdge> Container;
00399     Container edges;
00400 
00401   public:
00402 
00405     UndirPath(const Graph &_G) : gr(&_G) {}
00406 
00411     UndirPath(const UndirPath &P, const NodeIt &a, const NodeIt &b) {
00412       gr = P.gr;
00413       edges.insert(edges.end(), P.edges.begin()+a.idx, P.edges.begin()+b.idx);
00414     }
00415 
00420     UndirPath(const UndirPath &P, const EdgeIt &a, const EdgeIt &b) {
00421       gr = P.gr;
00422       edges.insert(edges.end(), P.edges.begin()+a.idx, P.edges.begin()+b.idx);
00423     }
00424 
00426     size_t length() const { return edges.size(); }
00428     bool empty() const { return edges.empty(); }
00429 
00431     void clear() { edges.clear(); }
00432 
00437     GraphNode source() const {
00438       return empty() ? INVALID : gr->source(edges[0]);
00439     }
00444     GraphNode target() const {
00445       return empty() ? INVALID : gr->target(edges[length()-1]);
00446     }
00447 
00452     template<typename It>
00453     It& first(It &i) const { return i=It(*this); }
00454 
00456     NodeIt& nth(NodeIt &i, int n) const {
00457       return i=NodeIt(*this, n);
00458     }
00459 
00461     EdgeIt& nth(EdgeIt &i, int n) const {
00462       return i=EdgeIt(*this, n);
00463     }
00464 
00466     template<typename It>
00467     static
00468     bool valid(const It &i) { return i.valid(); }
00469 
00471     template<typename It>
00472     static
00473     It& next(It &e) {
00474       return ++e;
00475     }
00476 
00479     NodeIt target(const EdgeIt& e) const {
00480       return NodeIt(*this, e.idx+1);
00481     }
00482 
00485     NodeIt source(const EdgeIt& e) const {
00486       return NodeIt(*this, e.idx);
00487     }
00488 
00489 
00490 
00501     class EdgeIt {
00502       friend class UndirPath;
00503 
00504       int idx;
00505       const UndirPath *p;
00506     public:
00508       EdgeIt() {}
00510       EdgeIt(Invalid) : idx(-1), p(0) {}
00512       EdgeIt(const UndirPath &_p, int _idx = 0) :
00513         idx(_idx), p(&_p) { validate(); }
00514 
00516       bool valid() const { return idx!=-1; }
00517 
00519       operator GraphEdge () const {
00520         return valid() ? p->edges[idx] : INVALID;
00521       }
00523      EdgeIt& operator++() { ++idx; validate(); return *this; }
00524 
00526       bool operator==(const EdgeIt& e) const { return idx==e.idx; }
00528       bool operator!=(const EdgeIt& e) const { return idx!=e.idx; }
00530       bool operator<(const EdgeIt& e) const { return idx<e.idx; }
00531 
00532     private:
00533       // FIXME: comparison between signed and unsigned...
00534       // Jo ez igy? Vagy esetleg legyen a length() int?
00535       void validate() { if( size_t(idx) >= p->length() ) idx=-1; }
00536     };
00537 
00548     class NodeIt {
00549       friend class UndirPath;
00550 
00551       int idx;
00552       const UndirPath *p;
00553     public:
00555       NodeIt() {}
00557       NodeIt(Invalid) : idx(-1), p(0) {}
00559       NodeIt(const UndirPath &_p, int _idx = 0) :
00560         idx(_idx), p(&_p) { validate(); }
00561 
00563       bool valid() const { return idx!=-1; }
00564 
00566       operator const GraphNode& () const {
00567         if(idx >= p->length())
00568           return p->target();
00569         else if(idx >= 0)
00570           return p->gr->source(p->edges[idx]);
00571         else
00572           return INVALID;
00573       }
00575       NodeIt& operator++() { ++idx; validate(); return *this; }
00576 
00578       bool operator==(const NodeIt& e) const { return idx==e.idx; }
00580       bool operator!=(const NodeIt& e) const { return idx!=e.idx; }
00582      bool operator<(const NodeIt& e) const { return idx<e.idx; }
00583 
00584     private:
00585       void validate() { if( size_t(idx) > p->length() ) idx=-1; }
00586     };
00587 
00588     friend class Builder;
00589 
00605     class Builder {
00606       UndirPath &P;
00607       Container front, back;
00608 
00609     public:
00612       Builder(UndirPath &_p) : P(_p) {}
00613 
00615 
00621       void setStartNode(const GraphNode &) {}
00622 
00624 
00627       void pushFront(const GraphEdge& e) {
00628         front.push_back(e);
00629       }
00630 
00632 
00635       void pushBack(const GraphEdge& e) {
00636         back.push_back(e);
00637       }
00638 
00640       void commit() {
00641         if( !(front.empty() && back.empty()) ) {
00642           Container tmp;
00643           tmp.reserve(front.size()+back.size()+P.length());
00644           tmp.insert(tmp.end(), front.rbegin(), front.rend());
00645           tmp.insert(tmp.end(), P.edges.begin(), P.edges.end());
00646           tmp.insert(tmp.end(), back.begin(), back.end());
00647           P.edges.swap(tmp);
00648           front.clear();
00649           back.clear();
00650         }
00651       }
00652 
00653 
00655 
00658 
00659       void reserveFront(size_t r) {front.reserve(r);}
00660 
00662 
00665 
00666       void reserveBack(size_t r) {back.reserve(r);}
00667 
00668     private:
00669       bool empty() {
00670         return front.empty() && back.empty() && P.empty();
00671       }
00672 
00673       GraphNode source() const {
00674         if( ! front.empty() )
00675           return P.gr->source(front[front.size()-1]);
00676         else if( ! P.empty() )
00677           return P.gr->source(P.edges[0]);
00678         else if( ! back.empty() )
00679           return P.gr->source(back[0]);
00680         else
00681           return INVALID;
00682       }
00683       GraphNode target() const {
00684         if( ! back.empty() )
00685           return P.gr->target(back[back.size()-1]);
00686         else if( ! P.empty() )
00687           return P.gr->target(P.edges[P.length()-1]);
00688         else if( ! front.empty() )
00689           return P.gr->target(front[0]);
00690         else
00691           return INVALID;
00692       }
00693 
00694     };
00695 
00696   };
00697 
00698 
00700 
00701 } // namespace lemon
00702 
00703 #endif // LEMON_PATH_H

Generated on Sat Aug 27 14:14:54 2005 for LEMON by  doxygen 1.4.4