lemon/concepts/path.h
author alpar
Tue, 24 Oct 2006 17:19:16 +0000
changeset 2260 4274224f8a7d
child 2335 27aa03cd3121
permissions -rw-r--r--
concept -> concepts (namespace & directory)
alpar@2260
     1
/* -*- C++ -*-
alpar@2260
     2
 *
alpar@2260
     3
 * This file is a part of LEMON, a generic C++ optimization library
alpar@2260
     4
 *
alpar@2260
     5
 * Copyright (C) 2003-2006
alpar@2260
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@2260
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@2260
     8
 *
alpar@2260
     9
 * Permission to use, modify and distribute this software is granted
alpar@2260
    10
 * provided that this copyright notice appears in all copies. For
alpar@2260
    11
 * precise terms see the accompanying LICENSE file.
alpar@2260
    12
 *
alpar@2260
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@2260
    14
 * express or implied, and with no claim as to its suitability for any
alpar@2260
    15
 * purpose.
alpar@2260
    16
 *
alpar@2260
    17
 */
alpar@2260
    18
alpar@2260
    19
///\ingroup concept
alpar@2260
    20
///\file
alpar@2260
    21
///\brief Classes for representing paths in graphs.
alpar@2260
    22
///
alpar@2260
    23
///\todo Iterators have obsolete style
alpar@2260
    24
alpar@2260
    25
#ifndef LEMON_CONCEPT_PATH_H
alpar@2260
    26
#define LEMON_CONCEPT_PATH_H
alpar@2260
    27
alpar@2260
    28
#include <lemon/bits/invalid.h>
alpar@2260
    29
#include <lemon/concept_check.h>
alpar@2260
    30
alpar@2260
    31
namespace lemon {
alpar@2260
    32
  namespace concepts {
alpar@2260
    33
    /// \addtogroup concept
alpar@2260
    34
    /// @{
alpar@2260
    35
alpar@2260
    36
alpar@2260
    37
    //! \brief A skeleton structure for representing directed paths in a graph.
alpar@2260
    38
    //!
alpar@2260
    39
    //! A skeleton structure for representing directed paths in a graph.
alpar@2260
    40
    //! \param _Graph The graph type in which the path is.
alpar@2260
    41
    //!
alpar@2260
    42
    //! In a sense, the path can be treated as a graph, for it has \c NodeIt
alpar@2260
    43
    //! and \c EdgeIt with the same usage. These types converts to the \c Node
alpar@2260
    44
    //! and \c Edge of the original graph.
alpar@2260
    45
    template<typename _Graph>
alpar@2260
    46
    class Path {
alpar@2260
    47
    public:
alpar@2260
    48
alpar@2260
    49
      /// Type of the underlying graph.
alpar@2260
    50
      typedef _Graph Graph;
alpar@2260
    51
      /// Edge type of the underlying graph.
alpar@2260
    52
      typedef typename Graph::Edge Edge;
alpar@2260
    53
      /// Node type of the underlying graph.
alpar@2260
    54
      typedef typename Graph::Node Node;
alpar@2260
    55
alpar@2260
    56
      class NodeIt;
alpar@2260
    57
      class EdgeIt;
alpar@2260
    58
alpar@2260
    59
      /// \param _g The graph in which the path is.
alpar@2260
    60
      ///
alpar@2260
    61
      Path(const Graph &_g) {
alpar@2260
    62
	ignore_unused_variable_warning(_g);
alpar@2260
    63
      }
alpar@2260
    64
alpar@2260
    65
      /// Length of the path ie. the number of edges in the path.
alpar@2260
    66
      int length() const {return 0;}
alpar@2260
    67
alpar@2260
    68
      /// Returns whether the path is empty.
alpar@2260
    69
      bool empty() const { return true;}
alpar@2260
    70
alpar@2260
    71
      /// Resets the path to an empty path.
alpar@2260
    72
      void clear() {}
alpar@2260
    73
alpar@2260
    74
      /// \brief Starting point of the path.
alpar@2260
    75
      ///
alpar@2260
    76
      /// Starting point of the path.
alpar@2260
    77
      /// Returns INVALID if the path is empty.
alpar@2260
    78
      Node target() const {return INVALID;}
alpar@2260
    79
      /// \brief End point of the path.
alpar@2260
    80
      ///
alpar@2260
    81
      /// End point of the path.
alpar@2260
    82
      /// Returns INVALID if the path is empty.
alpar@2260
    83
      Node source() const {return INVALID;}
alpar@2260
    84
alpar@2260
    85
      /// \brief The target of an edge.
alpar@2260
    86
      ///
alpar@2260
    87
      /// Returns node iterator pointing to the target node of the
alpar@2260
    88
      /// given edge iterator.
alpar@2260
    89
      NodeIt target(const EdgeIt&) const {return INVALID;}
alpar@2260
    90
alpar@2260
    91
      /// \brief The source of an edge.
alpar@2260
    92
      ///
alpar@2260
    93
      /// Returns node iterator pointing to the source node of the
alpar@2260
    94
      /// given edge iterator.
alpar@2260
    95
      NodeIt source(const EdgeIt&) const {return INVALID;}
alpar@2260
    96
alpar@2260
    97
      /// \brief Iterator class to iterate on the nodes of the paths
alpar@2260
    98
      ///
alpar@2260
    99
      /// This class is used to iterate on the nodes of the paths
alpar@2260
   100
      ///
alpar@2260
   101
      /// Of course it converts to Graph::Node.
alpar@2260
   102
      class NodeIt {
alpar@2260
   103
      public:
alpar@2260
   104
	/// Default constructor
alpar@2260
   105
	NodeIt() {}
alpar@2260
   106
	/// Invalid constructor
alpar@2260
   107
	NodeIt(Invalid) {}
alpar@2260
   108
	/// Constructor with starting point
alpar@2260
   109
	NodeIt(const Path &) {}
alpar@2260
   110
alpar@2260
   111
	///Conversion to Graph::Node
alpar@2260
   112
	operator Node() const { return INVALID; }
alpar@2260
   113
	/// Next node
alpar@2260
   114
	NodeIt& operator++() {return *this;}
alpar@2260
   115
alpar@2260
   116
	/// Comparison operator
alpar@2260
   117
	bool operator==(const NodeIt&) const {return true;}
alpar@2260
   118
	/// Comparison operator
alpar@2260
   119
	bool operator!=(const NodeIt&) const {return true;}
alpar@2260
   120
 	/// Comparison operator
alpar@2260
   121
 	bool operator<(const NodeIt&) const {return false;}
alpar@2260
   122
alpar@2260
   123
      };
alpar@2260
   124
alpar@2260
   125
      /// \brief Iterator class to iterate on the edges of the paths
alpar@2260
   126
      ///
alpar@2260
   127
      /// This class is used to iterate on the edges of the paths
alpar@2260
   128
      ///
alpar@2260
   129
      /// Of course it converts to Graph::Edge
alpar@2260
   130
      class EdgeIt {
alpar@2260
   131
      public:
alpar@2260
   132
	/// Default constructor
alpar@2260
   133
	EdgeIt() {}
alpar@2260
   134
	/// Invalid constructor
alpar@2260
   135
	EdgeIt(Invalid) {}
alpar@2260
   136
	/// Constructor with starting point
alpar@2260
   137
	EdgeIt(const Path &) {}
alpar@2260
   138
alpar@2260
   139
	operator Edge() const { return INVALID; }
alpar@2260
   140
alpar@2260
   141
	/// Next edge
alpar@2260
   142
	EdgeIt& operator++() {return *this;}
alpar@2260
   143
alpar@2260
   144
	/// Comparison operator
alpar@2260
   145
	bool operator==(const EdgeIt&) const {return true;}
alpar@2260
   146
	/// Comparison operator
alpar@2260
   147
	bool operator!=(const EdgeIt&) const {return true;}
alpar@2260
   148
 	/// Comparison operator
alpar@2260
   149
 	bool operator<(const EdgeIt&) const {return false;}
alpar@2260
   150
alpar@2260
   151
      };
alpar@2260
   152
alpar@2260
   153
alpar@2260
   154
      friend class Builder;
alpar@2260
   155
alpar@2260
   156
      /// \brief Class to build paths
alpar@2260
   157
      ///
alpar@2260
   158
      /// This class is used to fill a path with edges.
alpar@2260
   159
      ///
alpar@2260
   160
      /// You can push new edges to the front and to the back of the path in
alpar@2260
   161
      /// arbitrary order then you should commit these changes to the graph.
alpar@2260
   162
      ///
alpar@2260
   163
      /// While the builder is active (after the first modifying
alpar@2260
   164
      /// operation and until the call of \ref commit()) the
alpar@2260
   165
      /// underlining Path is in a "transitional" state (operations on
alpar@2260
   166
      /// it have undefined result).
alpar@2260
   167
      class Builder {
alpar@2260
   168
      public:
alpar@2260
   169
alpar@2260
   170
        /// Constructor
alpar@2260
   171
alpar@2260
   172
        /// Constructor
alpar@2260
   173
	/// \param _path the path you want to fill in.
alpar@2260
   174
	///
alpar@2260
   175
alpar@2260
   176
	Builder(Path &_path) { ignore_unused_variable_warning(_path); }
alpar@2260
   177
alpar@2260
   178
	/// Sets the starting node of the path.
alpar@2260
   179
alpar@2260
   180
	/// Sets the starting node of the path. Edge added to the path
alpar@2260
   181
	/// afterwards have to be incident to this node.
alpar@2260
   182
	/// You \em must start building an empty path with these functions.
alpar@2260
   183
	/// (And you \em must \em not use it later).
alpar@2260
   184
	/// \sa pushFront()
alpar@2260
   185
	/// \sa pushBack()
alpar@2260
   186
	void setStartNode(const Node &) {}
alpar@2260
   187
alpar@2260
   188
	///Push a new edge to the front of the path
alpar@2260
   189
alpar@2260
   190
	///Push a new edge to the front of the path.
alpar@2260
   191
	///If the path is empty, you \em must call \ref setStartNode() before
alpar@2260
   192
	///the first use of \ref pushFront().
alpar@2260
   193
	void pushFront(const Edge&) {}
alpar@2260
   194
alpar@2260
   195
	///Push a new edge to the back of the path
alpar@2260
   196
alpar@2260
   197
	///Push a new edge to the back of the path.
alpar@2260
   198
	///If the path is empty, you \em must call \ref setStartNode() before
alpar@2260
   199
	///the first use of \ref pushBack().
alpar@2260
   200
	void pushBack(const Edge&) {}
alpar@2260
   201
alpar@2260
   202
	///Commit the changes to the path.
alpar@2260
   203
alpar@2260
   204
	///Commit the changes to the path.
alpar@2260
   205
        ///
alpar@2260
   206
	void commit() {}
alpar@2260
   207
alpar@2260
   208
	///Reserve (front) storage for the builder in advance.
alpar@2260
   209
alpar@2260
   210
	///If you know a reasonable upper bound on the number of the edges
alpar@2260
   211
	///to add to the front of the path,
alpar@2260
   212
	///using this function you may speed up the building.
alpar@2260
   213
	void reserveFront(size_t) {}
alpar@2260
   214
	///Reserve (back) storage for the builder in advance.
alpar@2260
   215
alpar@2260
   216
	///If you know a reasonable upper bound on the number of the edges
alpar@2260
   217
	///to add to the back of the path,
alpar@2260
   218
	///using this function you may speed up the building.
alpar@2260
   219
	void reserveBack(size_t) {}
alpar@2260
   220
      };
alpar@2260
   221
alpar@2260
   222
      template <typename _Path>
alpar@2260
   223
      struct Constraints {
alpar@2260
   224
	void constraints() {
alpar@2260
   225
          typedef typename _Path::Node Node;
alpar@2260
   226
          typedef typename _Path::NodeIt NodeIt;
alpar@2260
   227
          typedef typename Graph::Node GraphNode;
alpar@2260
   228
alpar@2260
   229
          typedef typename _Path::Edge Edge;
alpar@2260
   230
          typedef typename _Path::EdgeIt EdgeIt;
alpar@2260
   231
          typedef typename Graph::Edge GraphEdge;
alpar@2260
   232
alpar@2260
   233
          typedef typename _Path::Builder Builder;
alpar@2260
   234
alpar@2260
   235
          path = _Path(graph);
alpar@2260
   236
alpar@2260
   237
          bool b = cpath.empty();
alpar@2260
   238
          int l = cpath.length();
alpar@2260
   239
alpar@2260
   240
          Node gn;
alpar@2260
   241
          Edge ge;
alpar@2260
   242
          gn = cpath.source();
alpar@2260
   243
          gn = cpath.target();
alpar@2260
   244
alpar@2260
   245
          NodeIt nit;
alpar@2260
   246
          EdgeIt eit(INVALID);
alpar@2260
   247
          nit = path.source(eit);
alpar@2260
   248
          nit = path.target(eit);
alpar@2260
   249
          
alpar@2260
   250
          nit = NodeIt();
alpar@2260
   251
          nit = NodeIt(cpath);
alpar@2260
   252
          nit = INVALID;
alpar@2260
   253
          gn = nit;
alpar@2260
   254
          ++nit;
alpar@2260
   255
          b = nit == nit;
alpar@2260
   256
          b = nit != nit;
alpar@2260
   257
          b = nit < nit;
alpar@2260
   258
alpar@2260
   259
          eit = EdgeIt();
alpar@2260
   260
          eit = EdgeIt(cpath);
alpar@2260
   261
          eit = INVALID;
alpar@2260
   262
          ge = eit;
alpar@2260
   263
          ++eit;
alpar@2260
   264
          b = eit == eit;
alpar@2260
   265
          b = eit != eit;
alpar@2260
   266
          b = eit < eit;
alpar@2260
   267
alpar@2260
   268
          size_t st = 0;
alpar@2260
   269
alpar@2260
   270
          Builder builder(path); 
alpar@2260
   271
          builder.setStartNode(gn);
alpar@2260
   272
          builder.pushFront(ge);
alpar@2260
   273
          builder.pushBack(ge);
alpar@2260
   274
          builder.commit();
alpar@2260
   275
          builder.reserveFront(st);
alpar@2260
   276
          builder.reserveBack(st);
alpar@2260
   277
          
alpar@2260
   278
          ignore_unused_variable_warning(l);
alpar@2260
   279
          ignore_unused_variable_warning(b);
alpar@2260
   280
	}
alpar@2260
   281
alpar@2260
   282
        const Graph& graph;
alpar@2260
   283
        const _Path& cpath;
alpar@2260
   284
        _Path& path;
alpar@2260
   285
      };
alpar@2260
   286
alpar@2260
   287
    };
alpar@2260
   288
alpar@2260
   289
  ///@}
alpar@2260
   290
  }
alpar@2260
   291
alpar@2260
   292
} // namespace lemon
alpar@2260
   293
alpar@2260
   294
#endif // LEMON_CONCEPT_PATH_H