COIN-OR::LEMON - Graph Library

Changeset 2335:27aa03cd3121 in lemon-0.x for lemon/concepts


Ignore:
Timestamp:
01/08/07 11:39:59 (19 years ago)
Author:
Balazs Dezso
Branch:
default
Phase:
public
Convert:
svn:c9d7d8f5-90d6-0310-b91f-818b3a526b0e/lemon/trunk@3123
Message:

New path concept and path structures

TODO: BellmanFord::negativeCycle()

File:
1 edited

Legend:

Unmodified
Added
Removed
  • lemon/concepts/path.h

    r2260 r2335  
    2727
    2828#include <lemon/bits/invalid.h>
     29#include <lemon/bits/utility.h>
    2930#include <lemon/concept_check.h>
    3031
    3132namespace lemon {
    3233  namespace concepts {
     34
    3335    /// \addtogroup concept
    3436    /// @{
    3537
    36 
    37     //! \brief A skeleton structure for representing directed paths in a graph.
    38     //!
    39     //! A skeleton structure for representing directed paths in a graph.
    40     //! \param _Graph The graph type in which the path is.
    41     //!
    42     //! In a sense, the path can be treated as a graph, for it has \c NodeIt
    43     //! and \c EdgeIt with the same usage. These types converts to the \c Node
    44     //! and \c Edge of the original graph.
    45     template<typename _Graph>
     38    /// \brief A skeleton structure for representing directed paths in
     39    /// a graph.
     40    ///
     41    /// A skeleton structure for representing directed paths in a
     42    /// graph. 
     43    /// \param _Graph The graph type in which the path is.
     44    ///
     45    /// In a sense, the path can be treated as a list of edges. The
     46    /// lemon path type stores just this list. As a consequence it
     47    /// cannot enumerate the nodes in the path and the zero length
     48    /// paths cannot store the source.
     49    ///
     50    template <typename _Graph>
    4651    class Path {
    4752    public:
     
    5156      /// Edge type of the underlying graph.
    5257      typedef typename Graph::Edge Edge;
    53       /// Node type of the underlying graph.
    54       typedef typename Graph::Node Node;
    55 
    56       class NodeIt;
     58
    5759      class EdgeIt;
    5860
    59       /// \param _g The graph in which the path is.
    60       ///
    61       Path(const Graph &_g) {
    62         ignore_unused_variable_warning(_g);
    63       }
     61      /// \brief Default constructor
     62      Path() {}
     63
     64      /// \brief Template constructor
     65      template <typename CPath>
     66      Path(const CPath& cpath) {}
     67
     68      /// \brief Template assigment
     69      template <typename CPath>
     70      Path& operator=(const CPath& cpath) {}
    6471
    6572      /// Length of the path ie. the number of edges in the path.
    66       int length() const {return 0;}
     73      int length() const { return 0;}
    6774
    6875      /// Returns whether the path is empty.
     
    7279      void clear() {}
    7380
    74       /// \brief Starting point of the path.
     81      /// \brief Lemon style iterator for path edges
    7582      ///
    76       /// Starting point of the path.
    77       /// Returns INVALID if the path is empty.
    78       Node target() const {return INVALID;}
    79       /// \brief End point of the path.
    80       ///
    81       /// End point of the path.
    82       /// Returns INVALID if the path is empty.
    83       Node source() const {return INVALID;}
    84 
    85       /// \brief The target of an edge.
    86       ///
    87       /// Returns node iterator pointing to the target node of the
    88       /// given edge iterator.
    89       NodeIt target(const EdgeIt&) const {return INVALID;}
    90 
    91       /// \brief The source of an edge.
    92       ///
    93       /// Returns node iterator pointing to the source node of the
    94       /// given edge iterator.
    95       NodeIt source(const EdgeIt&) const {return INVALID;}
    96 
    97       /// \brief Iterator class to iterate on the nodes of the paths
    98       ///
    99       /// This class is used to iterate on the nodes of the paths
    100       ///
    101       /// Of course it converts to Graph::Node.
    102       class NodeIt {
    103       public:
    104         /// Default constructor
    105         NodeIt() {}
    106         /// Invalid constructor
    107         NodeIt(Invalid) {}
    108         /// Constructor with starting point
    109         NodeIt(const Path &) {}
    110 
    111         ///Conversion to Graph::Node
    112         operator Node() const { return INVALID; }
    113         /// Next node
    114         NodeIt& operator++() {return *this;}
    115 
    116         /// Comparison operator
    117         bool operator==(const NodeIt&) const {return true;}
    118         /// Comparison operator
    119         bool operator!=(const NodeIt&) const {return true;}
    120         /// Comparison operator
    121         bool operator<(const NodeIt&) const {return false;}
    122 
    123       };
    124 
    125       /// \brief Iterator class to iterate on the edges of the paths
    126       ///
    127       /// This class is used to iterate on the edges of the paths
    128       ///
    129       /// Of course it converts to Graph::Edge
     83      /// This class is used to iterate on the edges of the paths.
    13084      class EdgeIt {
    13185      public:
     
    13488        /// Invalid constructor
    13589        EdgeIt(Invalid) {}
    136         /// Constructor with starting point
     90        /// Constructor for first edge
    13791        EdgeIt(const Path &) {}
    13892
     93        /// Conversion to Edge
    13994        operator Edge() const { return INVALID; }
    14095
     
    151106      };
    152107
    153 
    154       friend class Builder;
    155 
    156       /// \brief Class to build paths
    157       ///
    158       /// This class is used to fill a path with edges.
    159       ///
    160       /// You can push new edges to the front and to the back of the path in
    161       /// arbitrary order then you should commit these changes to the graph.
    162       ///
    163       /// While the builder is active (after the first modifying
    164       /// operation and until the call of \ref commit()) the
    165       /// underlining Path is in a "transitional" state (operations on
    166       /// it have undefined result).
    167       class Builder {
    168       public:
    169 
    170         /// Constructor
    171 
    172         /// Constructor
    173         /// \param _path the path you want to fill in.
    174         ///
    175 
    176         Builder(Path &_path) { ignore_unused_variable_warning(_path); }
    177 
    178         /// Sets the starting node of the path.
    179 
    180         /// Sets the starting node of the path. Edge added to the path
    181         /// afterwards have to be incident to this node.
    182         /// You \em must start building an empty path with these functions.
    183         /// (And you \em must \em not use it later).
    184         /// \sa pushFront()
    185         /// \sa pushBack()
    186         void setStartNode(const Node &) {}
    187 
    188         ///Push a new edge to the front of the path
    189 
    190         ///Push a new edge to the front of the path.
    191         ///If the path is empty, you \em must call \ref setStartNode() before
    192         ///the first use of \ref pushFront().
    193         void pushFront(const Edge&) {}
    194 
    195         ///Push a new edge to the back of the path
    196 
    197         ///Push a new edge to the back of the path.
    198         ///If the path is empty, you \em must call \ref setStartNode() before
    199         ///the first use of \ref pushBack().
    200         void pushBack(const Edge&) {}
    201 
    202         ///Commit the changes to the path.
    203 
    204         ///Commit the changes to the path.
    205         ///
    206         void commit() {}
    207 
    208         ///Reserve (front) storage for the builder in advance.
    209 
    210         ///If you know a reasonable upper bound on the number of the edges
    211         ///to add to the front of the path,
    212         ///using this function you may speed up the building.
    213         void reserveFront(size_t) {}
    214         ///Reserve (back) storage for the builder in advance.
    215 
    216         ///If you know a reasonable upper bound on the number of the edges
    217         ///to add to the back of the path,
    218         ///using this function you may speed up the building.
    219         void reserveBack(size_t) {}
    220       };
    221 
    222108      template <typename _Path>
    223109      struct Constraints {
    224         void constraints() {
    225           typedef typename _Path::Node Node;
    226           typedef typename _Path::NodeIt NodeIt;
    227           typedef typename Graph::Node GraphNode;
    228 
    229           typedef typename _Path::Edge Edge;
    230           typedef typename _Path::EdgeIt EdgeIt;
    231           typedef typename Graph::Edge GraphEdge;
    232 
    233           typedef typename _Path::Builder Builder;
    234 
    235           path = _Path(graph);
    236 
    237           bool b = cpath.empty();
    238           int l = cpath.length();
    239 
    240           Node gn;
    241           Edge ge;
    242           gn = cpath.source();
    243           gn = cpath.target();
    244 
    245           NodeIt nit;
    246           EdgeIt eit(INVALID);
    247           nit = path.source(eit);
    248           nit = path.target(eit);
    249          
    250           nit = NodeIt();
    251           nit = NodeIt(cpath);
    252           nit = INVALID;
    253           gn = nit;
    254           ++nit;
    255           b = nit == nit;
    256           b = nit != nit;
    257           b = nit < nit;
    258 
    259           eit = EdgeIt();
    260           eit = EdgeIt(cpath);
    261           eit = INVALID;
    262           ge = eit;
    263           ++eit;
    264           b = eit == eit;
    265           b = eit != eit;
    266           b = eit < eit;
    267 
    268           size_t st = 0;
    269 
    270           Builder builder(path);
    271           builder.setStartNode(gn);
    272           builder.pushFront(ge);
    273           builder.pushBack(ge);
    274           builder.commit();
    275           builder.reserveFront(st);
    276           builder.reserveBack(st);
    277          
     110        void constraints() {
     111          Path<Graph> pc;
     112          _Path p, pp(pc);
     113          int l = p.length();
     114          int e = p.empty();
     115          p.clear();
     116
     117          p = pc;
     118
     119          typename _Path::EdgeIt id, ii(INVALID), i(p);
     120
     121          ++i;
     122          typename Graph::Edge ed = i;
     123
     124          e = (i == ii);
     125          e = (i != ii);
     126          e = (i < ii);
     127
    278128          ignore_unused_variable_warning(l);
    279           ignore_unused_variable_warning(b);
    280         }
    281 
    282         const Graph& graph;
    283         const _Path& cpath;
    284         _Path& path;
     129          ignore_unused_variable_warning(pp);
     130          ignore_unused_variable_warning(e);
     131          ignore_unused_variable_warning(id);
     132          ignore_unused_variable_warning(ii);
     133          ignore_unused_variable_warning(ed);
     134        }
    285135      };
    286136
    287137    };
    288138
    289   ///@}
     139    namespace _path_bits {
     140     
     141      template <typename _Graph, typename _Path, typename RevPathTag = void>
     142      struct PathDumperConstraints {
     143        void constraints() {
     144          int l = p.length();
     145          int e = p.empty();
     146
     147          typename _Path::EdgeIt id, ii(INVALID), i(p);
     148
     149          ++i;
     150          typename _Graph::Edge ed = i;
     151
     152          e = (i == ii);
     153          e = (i != ii);
     154          e = (i < ii);
     155
     156          ignore_unused_variable_warning(l);
     157          ignore_unused_variable_warning(e);
     158          ignore_unused_variable_warning(id);
     159          ignore_unused_variable_warning(ii);
     160          ignore_unused_variable_warning(ed);
     161        }
     162        _Path& p;
     163      };
     164
     165      template <typename _Graph, typename _Path>
     166      struct PathDumperConstraints<
     167        _Graph, _Path,
     168        typename enable_if<typename _Path::RevPathTag, void>::type
     169      > {
     170        void constraints() {
     171          int l = p.length();
     172          int e = p.empty();
     173
     174          typename _Path::RevIt id, ii(INVALID), i(p);
     175
     176          ++i;
     177          typename _Graph::Edge ed = i;
     178
     179          e = (i == ii);
     180          e = (i != ii);
     181          e = (i < ii);
     182
     183          ignore_unused_variable_warning(l);
     184          ignore_unused_variable_warning(e);
     185          ignore_unused_variable_warning(id);
     186          ignore_unused_variable_warning(ii);
     187          ignore_unused_variable_warning(ed);
     188        }
     189        _Path& p;
     190      };
     191   
     192    }
     193
     194
     195    /// \brief A skeleton structure for path dumpers.
     196    ///
     197    /// A skeleton structure for path dumpers. The path dumpers are
     198    /// the generalization of the paths. The path dumpers can
     199    /// enumerate the edges of the path wheter in forward or in
     200    /// backward order.  In most time these classes are not used
     201    /// directly rather it used to assign a dumped class to a real
     202    /// path type.
     203    ///
     204    /// The main purpose of this concept is that the shortest path
     205    /// algorithms can enumerate easily the edges in reverse order.
     206    /// If we would like to give back a real path from these
     207    /// algorithms then we should create a temporarly path object. In
     208    /// Lemon such algorithms gives back a path dumper what can
     209    /// assigned to a real path and the dumpers can be implemented as
     210    /// an adaptor class to the predecessor map.
     211
     212    /// \param _Graph  The graph type in which the path is.
     213    ///
     214    /// The paths can be constructed from any path type by a
     215    /// template constructor or a template assignment operator.
     216    ///
     217    template <typename _Graph>
     218    class PathDumper {
     219    public:
     220
     221      /// Type of the underlying graph.
     222      typedef _Graph Graph;
     223      /// Edge type of the underlying graph.
     224      typedef typename Graph::Edge Edge;
     225
     226      /// Length of the path ie. the number of edges in the path.
     227      int length() const { return 0;}
     228
     229      /// Returns whether the path is empty.
     230      bool empty() const { return true;}
     231
     232      /// \brief Forward or reverse dumping
     233      ///
     234      /// If the RevPathTag is defined and true then reverse dumping
     235      /// is provided in the path proxy. In this case instead of the
     236      /// EdgeIt the RevIt iterator should be implemented in the
     237      /// proxy.
     238      typedef False RevPathTag;
     239
     240      /// \brief Lemon style iterator for path edges
     241      ///
     242      /// This class is used to iterate on the edges of the paths.
     243      class EdgeIt {
     244      public:
     245        /// Default constructor
     246        EdgeIt() {}
     247        /// Invalid constructor
     248        EdgeIt(Invalid) {}
     249        /// Constructor for first edge
     250        EdgeIt(const PathDumper&) {}
     251
     252        /// Conversion to Edge
     253        operator Edge() const { return INVALID; }
     254
     255        /// Next edge
     256        EdgeIt& operator++() {return *this;}
     257
     258        /// Comparison operator
     259        bool operator==(const EdgeIt&) const {return true;}
     260        /// Comparison operator
     261        bool operator!=(const EdgeIt&) const {return true;}
     262        /// Comparison operator
     263        bool operator<(const EdgeIt&) const {return false;}
     264
     265      };
     266
     267      /// \brief Lemon style iterator for path edges
     268      ///
     269      /// This class is used to iterate on the edges of the paths in
     270      /// reverse direction.
     271      class RevIt {
     272      public:
     273        /// Default constructor
     274        RevIt() {}
     275        /// Invalid constructor
     276        RevIt(Invalid) {}
     277        /// Constructor for first edge
     278        RevIt(const PathDumper &) {}
     279
     280        /// Conversion to Edge
     281        operator Edge() const { return INVALID; }
     282
     283        /// Next edge
     284        RevIt& operator++() {return *this;}
     285
     286        /// Comparison operator
     287        bool operator==(const RevIt&) const {return true;}
     288        /// Comparison operator
     289        bool operator!=(const RevIt&) const {return true;}
     290        /// Comparison operator
     291        bool operator<(const RevIt&) const {return false;}
     292
     293      };
     294
     295      template <typename _Path>
     296      struct Constraints {
     297        void constraints() {
     298          function_requires<_path_bits::
     299            PathDumperConstraints<Graph, _Path> >();
     300        }
     301      };
     302
     303    };
     304
     305
     306    ///@}
    290307  }
    291308
Note: See TracChangeset for help on using the changeset viewer.