klao@959: /* -*- C++ -*- klao@959: * alpar@1956: * This file is a part of LEMON, a generic C++ optimization library alpar@1956: * alpar@1956: * Copyright (C) 2003-2006 alpar@1956: * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport alpar@1359: * (Egervary Research Group on Combinatorial Optimization, EGRES). klao@959: * klao@959: * Permission to use, modify and distribute this software is granted klao@959: * provided that this copyright notice appears in all copies. For klao@959: * precise terms see the accompanying LICENSE file. klao@959: * klao@959: * This software is provided "AS IS" with no warranty of any kind, klao@959: * express or implied, and with no claim as to its suitability for any klao@959: * purpose. klao@959: * klao@959: */ klao@959: klao@959: ///\ingroup concept klao@959: ///\file klao@959: ///\brief Classes for representing paths in graphs. alpar@1151: /// alpar@1151: ///\todo Iterators have obsolete style klao@959: klao@959: #ifndef LEMON_CONCEPT_PATH_H klao@959: #define LEMON_CONCEPT_PATH_H klao@959: deba@1993: #include alpar@1643: #include klao@959: klao@959: namespace lemon { klao@959: namespace concept { klao@959: /// \addtogroup concept klao@959: /// @{ klao@959: klao@959: alpar@967: //! \brief A skeleton structure for representing directed paths in a graph. klao@959: //! klao@959: //! A skeleton structure for representing directed paths in a graph. deba@2247: //! \param _Graph The graph type in which the path is. klao@959: //! jacint@1270: //! In a sense, the path can be treated as a graph, for it has \c NodeIt klao@959: //! and \c EdgeIt with the same usage. These types converts to the \c Node klao@959: //! and \c Edge of the original graph. deba@2247: template klao@959: class Path { klao@959: public: klao@959: klao@959: /// Type of the underlying graph. deba@2247: typedef _Graph Graph; klao@959: /// Edge type of the underlying graph. deba@2247: typedef typename Graph::Edge Edge; klao@959: /// Node type of the underlying graph. deba@2247: typedef typename Graph::Node Node; deba@2247: klao@959: class NodeIt; klao@959: class EdgeIt; klao@959: alpar@1624: /// \param _g The graph in which the path is. klao@959: /// alpar@1643: Path(const Graph &_g) { alpar@1643: ignore_unused_variable_warning(_g); alpar@1643: } klao@959: deba@2247: /// Length of the path ie. the number of edges in the path. alpar@1282: int length() const {return 0;} deba@2247: klao@959: /// Returns whether the path is empty. klao@959: bool empty() const { return true;} klao@959: klao@959: /// Resets the path to an empty path. klao@959: void clear() {} klao@959: klao@959: /// \brief Starting point of the path. klao@959: /// klao@959: /// Starting point of the path. klao@959: /// Returns INVALID if the path is empty. deba@2247: Node target() const {return INVALID;} klao@959: /// \brief End point of the path. klao@959: /// klao@959: /// End point of the path. klao@959: /// Returns INVALID if the path is empty. deba@2247: Node source() const {return INVALID;} klao@959: alpar@986: /// \brief The target of an edge. klao@959: /// alpar@986: /// Returns node iterator pointing to the target node of the klao@959: /// given edge iterator. alpar@1367: NodeIt target(const EdgeIt&) const {return INVALID;} klao@959: alpar@986: /// \brief The source of an edge. klao@959: /// alpar@986: /// Returns node iterator pointing to the source node of the klao@959: /// given edge iterator. alpar@1367: NodeIt source(const EdgeIt&) const {return INVALID;} klao@959: deba@2247: /// \brief Iterator class to iterate on the nodes of the paths deba@2247: /// deba@2247: /// This class is used to iterate on the nodes of the paths deba@2247: /// deba@2247: /// Of course it converts to Graph::Node. klao@959: class NodeIt { klao@959: public: klao@959: /// Default constructor klao@959: NodeIt() {} klao@959: /// Invalid constructor klao@959: NodeIt(Invalid) {} klao@959: /// Constructor with starting point alpar@1367: NodeIt(const Path &) {} klao@959: klao@959: ///Conversion to Graph::Node deba@2247: operator Node() const { return INVALID; } klao@959: /// Next node klao@959: NodeIt& operator++() {return *this;} klao@959: klao@959: /// Comparison operator alpar@1367: bool operator==(const NodeIt&) const {return true;} klao@959: /// Comparison operator alpar@1367: bool operator!=(const NodeIt&) const {return true;} deba@2247: /// Comparison operator deba@2247: bool operator<(const NodeIt&) const {return false;} klao@959: klao@959: }; klao@959: deba@2247: /// \brief Iterator class to iterate on the edges of the paths deba@2247: /// deba@2247: /// This class is used to iterate on the edges of the paths deba@2247: /// deba@2247: /// Of course it converts to Graph::Edge deba@2247: class EdgeIt { deba@2247: public: deba@2247: /// Default constructor deba@2247: EdgeIt() {} deba@2247: /// Invalid constructor deba@2247: EdgeIt(Invalid) {} deba@2247: /// Constructor with starting point deba@2247: EdgeIt(const Path &) {} deba@2247: deba@2247: operator Edge() const { return INVALID; } deba@2247: deba@2247: /// Next edge deba@2247: EdgeIt& operator++() {return *this;} deba@2247: deba@2247: /// Comparison operator deba@2247: bool operator==(const EdgeIt&) const {return true;} deba@2247: /// Comparison operator deba@2247: bool operator!=(const EdgeIt&) const {return true;} deba@2247: /// Comparison operator deba@2247: bool operator<(const EdgeIt&) const {return false;} deba@2247: deba@2247: }; deba@2247: deba@2247: klao@959: friend class Builder; klao@959: deba@2247: /// \brief Class to build paths deba@2247: /// deba@2247: /// This class is used to fill a path with edges. deba@2247: /// deba@2247: /// You can push new edges to the front and to the back of the path in deba@2247: /// arbitrary order then you should commit these changes to the graph. deba@2247: /// deba@2247: /// While the builder is active (after the first modifying deba@2247: /// operation and until the call of \ref commit()) the deba@2247: /// underlining Path is in a "transitional" state (operations on deba@2247: /// it have undefined result). klao@959: class Builder { klao@959: public: klao@959: deba@2247: /// Constructor klao@959: deba@2247: /// Constructor deba@2247: /// \param _path the path you want to fill in. klao@959: /// alpar@1228: deba@2247: Builder(Path &_path) { ignore_unused_variable_warning(_path); } klao@959: klao@959: /// Sets the starting node of the path. klao@959: klao@959: /// Sets the starting node of the path. Edge added to the path klao@959: /// afterwards have to be incident to this node. jacint@1270: /// You \em must start building an empty path with these functions. klao@959: /// (And you \em must \em not use it later). klao@959: /// \sa pushFront() klao@959: /// \sa pushBack() deba@2247: void setStartNode(const Node &) {} klao@959: klao@959: ///Push a new edge to the front of the path klao@959: klao@959: ///Push a new edge to the front of the path. klao@959: ///If the path is empty, you \em must call \ref setStartNode() before klao@959: ///the first use of \ref pushFront(). deba@2247: void pushFront(const Edge&) {} klao@959: klao@959: ///Push a new edge to the back of the path klao@959: klao@959: ///Push a new edge to the back of the path. klao@959: ///If the path is empty, you \em must call \ref setStartNode() before klao@959: ///the first use of \ref pushBack(). deba@2247: void pushBack(const Edge&) {} klao@959: klao@959: ///Commit the changes to the path. deba@2247: deba@2247: ///Commit the changes to the path. deba@2247: /// klao@959: void commit() {} klao@959: klao@959: ///Reserve (front) storage for the builder in advance. klao@959: jacint@1270: ///If you know a reasonable upper bound on the number of the edges klao@959: ///to add to the front of the path, klao@959: ///using this function you may speed up the building. alpar@1367: void reserveFront(size_t) {} klao@959: ///Reserve (back) storage for the builder in advance. klao@959: jacint@1270: ///If you know a reasonable upper bound on the number of the edges klao@959: ///to add to the back of the path, klao@959: ///using this function you may speed up the building. alpar@1367: void reserveBack(size_t) {} klao@959: }; deba@2247: deba@2247: template deba@2247: struct Constraints { deba@2247: void constraints() { deba@2247: typedef typename _Path::Node Node; deba@2247: typedef typename _Path::NodeIt NodeIt; deba@2247: typedef typename Graph::Node GraphNode; deba@2247: deba@2247: typedef typename _Path::Edge Edge; deba@2247: typedef typename _Path::EdgeIt EdgeIt; deba@2247: typedef typename Graph::Edge GraphEdge; deba@2247: deba@2247: typedef typename _Path::Builder Builder; deba@2247: deba@2247: path = _Path(graph); deba@2247: deba@2247: bool b = cpath.empty(); deba@2247: int l = cpath.length(); deba@2247: deba@2247: Node gn; deba@2247: Edge ge; deba@2247: gn = cpath.source(); deba@2247: gn = cpath.target(); deba@2247: deba@2247: NodeIt nit; deba@2247: EdgeIt eit(INVALID); deba@2247: nit = path.source(eit); deba@2247: nit = path.target(eit); deba@2247: deba@2247: nit = NodeIt(); deba@2247: nit = NodeIt(cpath); deba@2247: nit = INVALID; deba@2247: gn = nit; deba@2247: ++nit; deba@2247: b = nit == nit; deba@2247: b = nit != nit; deba@2247: b = nit < nit; deba@2247: deba@2247: eit = EdgeIt(); deba@2247: eit = EdgeIt(cpath); deba@2247: eit = INVALID; deba@2247: ge = eit; deba@2247: ++eit; deba@2247: b = eit == eit; deba@2247: b = eit != eit; deba@2247: b = eit < eit; deba@2247: deba@2247: size_t st = 0; deba@2247: deba@2247: Builder builder(path); deba@2247: builder.setStartNode(gn); deba@2247: builder.pushFront(ge); deba@2247: builder.pushBack(ge); deba@2247: builder.commit(); deba@2247: builder.reserveFront(st); deba@2247: builder.reserveBack(st); deba@2247: deba@2247: ignore_unused_variable_warning(l); deba@2247: ignore_unused_variable_warning(b); deba@2247: } deba@2247: deba@2247: const Graph& graph; deba@2247: const _Path& cpath; deba@2247: _Path& path; deba@2247: }; deba@2247: klao@959: }; klao@959: klao@959: ///@} klao@959: } klao@959: klao@959: } // namespace lemon klao@959: klao@959: #endif // LEMON_CONCEPT_PATH_H