lemon/concepts/path.h
author Balazs Dezso <deba@google.com>
Fri, 22 Jan 2021 10:55:32 +0100
changeset 1208 c6aa2cc1af04
parent 1130 0759d974de81
parent 1197 f179aa1045a4
permissions -rw-r--r--
Factor out recursion from weighted matching algorithms (#638)
alpar@209
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
alpar@96
     2
 *
alpar@209
     3
 * This file is a part of LEMON, a generic C++ optimization library.
alpar@96
     4
 *
alpar@1092
     5
 * Copyright (C) 2003-2013
alpar@96
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@96
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@96
     8
 *
alpar@96
     9
 * Permission to use, modify and distribute this software is granted
alpar@96
    10
 * provided that this copyright notice appears in all copies. For
alpar@96
    11
 * precise terms see the accompanying LICENSE file.
alpar@96
    12
 *
alpar@96
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@96
    14
 * express or implied, and with no claim as to its suitability for any
alpar@96
    15
 * purpose.
alpar@96
    16
 *
alpar@96
    17
 */
alpar@96
    18
alpar@96
    19
///\ingroup concept
alpar@96
    20
///\file
kpeter@785
    21
///\brief The concept of paths
alpar@96
    22
///
alpar@96
    23
deba@529
    24
#ifndef LEMON_CONCEPTS_PATH_H
deba@529
    25
#define LEMON_CONCEPTS_PATH_H
alpar@96
    26
deba@220
    27
#include <lemon/core.h>
alpar@96
    28
#include <lemon/concept_check.h>
ggab90@1130
    29
#include <lemon/bits/stl_iterators.h>
alpar@96
    30
alpar@96
    31
namespace lemon {
alpar@96
    32
  namespace concepts {
alpar@96
    33
alpar@96
    34
    /// \addtogroup concept
alpar@96
    35
    /// @{
alpar@96
    36
alpar@96
    37
    /// \brief A skeleton structure for representing directed paths in
alpar@96
    38
    /// a digraph.
alpar@96
    39
    ///
alpar@96
    40
    /// A skeleton structure for representing directed paths in a
alpar@209
    41
    /// digraph.
kpeter@785
    42
    /// In a sense, a path can be treated as a list of arcs.
kpeter@785
    43
    /// LEMON path types just store this list. As a consequence, they cannot
kpeter@785
    44
    /// enumerate the nodes on the path directly and a zero length path
kpeter@785
    45
    /// cannot store its source node.
kpeter@785
    46
    ///
kpeter@785
    47
    /// The arcs of a path should be stored in the order of their directions,
kpeter@785
    48
    /// i.e. the target node of each arc should be the same as the source
kpeter@785
    49
    /// node of the next arc. This consistency could be checked using
kpeter@785
    50
    /// \ref checkPath().
kpeter@785
    51
    /// The source and target nodes of a (consistent) path can be obtained
kpeter@785
    52
    /// using \ref pathSource() and \ref pathTarget().
kpeter@785
    53
    ///
kpeter@785
    54
    /// A path can be constructed from another path of any type using the
kpeter@785
    55
    /// copy constructor or the assignment operator.
kpeter@785
    56
    ///
kpeter@559
    57
    /// \tparam GR The digraph type in which the path is.
kpeter@559
    58
    template <typename GR>
alpar@96
    59
    class Path {
alpar@96
    60
    public:
alpar@96
    61
alpar@96
    62
      /// Type of the underlying digraph.
kpeter@559
    63
      typedef GR Digraph;
alpar@96
    64
      /// Arc type of the underlying digraph.
alpar@96
    65
      typedef typename Digraph::Arc Arc;
alpar@96
    66
alpar@96
    67
      class ArcIt;
alpar@96
    68
alpar@96
    69
      /// \brief Default constructor
alpar@96
    70
      Path() {}
alpar@96
    71
kpeter@785
    72
      /// \brief Template copy constructor
alpar@96
    73
      template <typename CPath>
kpeter@1197
    74
      Path(const CPath& cpath) {
kpeter@1197
    75
        ::lemon::ignore_unused_variable_warning(cpath);
kpeter@1197
    76
      }
alpar@96
    77
kpeter@785
    78
      /// \brief Template assigment operator
alpar@96
    79
      template <typename CPath>
kpeter@278
    80
      Path& operator=(const CPath& cpath) {
alpar@1083
    81
        ::lemon::ignore_unused_variable_warning(cpath);
kpeter@278
    82
        return *this;
kpeter@278
    83
      }
alpar@96
    84
kpeter@785
    85
      /// Length of the path, i.e. the number of arcs on the path.
alpar@96
    86
      int length() const { return 0;}
alpar@96
    87
alpar@96
    88
      /// Returns whether the path is empty.
alpar@96
    89
      bool empty() const { return true;}
alpar@96
    90
alpar@96
    91
      /// Resets the path to an empty path.
alpar@96
    92
      void clear() {}
alpar@96
    93
kpeter@785
    94
      /// \brief LEMON style iterator for enumerating the arcs of a path.
alpar@96
    95
      ///
kpeter@785
    96
      /// LEMON style iterator class for enumerating the arcs of a path.
alpar@96
    97
      class ArcIt {
alpar@96
    98
      public:
alpar@209
    99
        /// Default constructor
alpar@209
   100
        ArcIt() {}
alpar@209
   101
        /// Invalid constructor
alpar@209
   102
        ArcIt(Invalid) {}
kpeter@785
   103
        /// Sets the iterator to the first arc of the given path
alpar@209
   104
        ArcIt(const Path &) {}
alpar@96
   105
kpeter@785
   106
        /// Conversion to \c Arc
alpar@209
   107
        operator Arc() const { return INVALID; }
alpar@96
   108
alpar@209
   109
        /// Next arc
alpar@209
   110
        ArcIt& operator++() {return *this;}
alpar@96
   111
alpar@209
   112
        /// Comparison operator
alpar@209
   113
        bool operator==(const ArcIt&) const {return true;}
alpar@209
   114
        /// Comparison operator
alpar@209
   115
        bool operator!=(const ArcIt&) const {return true;}
kpeter@212
   116
        /// Comparison operator
kpeter@212
   117
        bool operator<(const ArcIt&) const {return false;}
alpar@96
   118
alpar@96
   119
      };
alpar@96
   120
ggab90@1130
   121
      /// \brief Gets the collection of the arcs of the path.
ggab90@1130
   122
      ///
ggab90@1130
   123
      /// This function can be used for iterating on the
ggab90@1130
   124
      /// arcs of the path. It returns a wrapped
ggab90@1130
   125
      /// ArcIt, which looks like an STL container
ggab90@1130
   126
      /// (by having begin() and end()) which you can use in range-based
ggab90@1130
   127
      /// for loops, STL algorithms, etc.
ggab90@1130
   128
      /// For example you can write:
ggab90@1130
   129
      ///\code
ggab90@1130
   130
      /// for(auto a: p.arcs())
ggab90@1130
   131
      ///   doSomething(a);
ggab90@1130
   132
      ///\endcode
ggab90@1130
   133
      LemonRangeWrapper1<ArcIt, Path> arcs() const {
ggab90@1130
   134
        return LemonRangeWrapper1<ArcIt, Path>(*this);
ggab90@1130
   135
      }
ggab90@1130
   136
ggab90@1130
   137
alpar@96
   138
      template <typename _Path>
alpar@96
   139
      struct Constraints {
alpar@96
   140
        void constraints() {
alpar@96
   141
          Path<Digraph> pc;
alpar@96
   142
          _Path p, pp(pc);
alpar@96
   143
          int l = p.length();
alpar@96
   144
          int e = p.empty();
alpar@96
   145
          p.clear();
alpar@96
   146
alpar@96
   147
          p = pc;
alpar@96
   148
alpar@96
   149
          typename _Path::ArcIt id, ii(INVALID), i(p);
alpar@96
   150
alpar@96
   151
          ++i;
alpar@96
   152
          typename Digraph::Arc ed = i;
alpar@96
   153
alpar@96
   154
          e = (i == ii);
alpar@96
   155
          e = (i != ii);
alpar@96
   156
          e = (i < ii);
alpar@96
   157
alpar@1083
   158
          ::lemon::ignore_unused_variable_warning(l);
alpar@1083
   159
          ::lemon::ignore_unused_variable_warning(pp);
alpar@1083
   160
          ::lemon::ignore_unused_variable_warning(e);
alpar@1083
   161
          ::lemon::ignore_unused_variable_warning(id);
alpar@1083
   162
          ::lemon::ignore_unused_variable_warning(ii);
alpar@1083
   163
          ::lemon::ignore_unused_variable_warning(ed);
alpar@96
   164
        }
alpar@96
   165
      };
alpar@96
   166
alpar@96
   167
    };
alpar@96
   168
alpar@96
   169
    namespace _path_bits {
alpar@209
   170
alpar@96
   171
      template <typename _Digraph, typename _Path, typename RevPathTag = void>
alpar@96
   172
      struct PathDumperConstraints {
alpar@96
   173
        void constraints() {
alpar@96
   174
          int l = p.length();
alpar@96
   175
          int e = p.empty();
alpar@96
   176
alpar@96
   177
          typename _Path::ArcIt id, i(p);
alpar@96
   178
alpar@96
   179
          ++i;
alpar@96
   180
          typename _Digraph::Arc ed = i;
alpar@96
   181
alpar@96
   182
          e = (i == INVALID);
alpar@96
   183
          e = (i != INVALID);
alpar@96
   184
alpar@1083
   185
          ::lemon::ignore_unused_variable_warning(l);
alpar@1083
   186
          ::lemon::ignore_unused_variable_warning(e);
alpar@1083
   187
          ::lemon::ignore_unused_variable_warning(id);
alpar@1083
   188
          ::lemon::ignore_unused_variable_warning(ed);
alpar@96
   189
        }
alpar@96
   190
        _Path& p;
alpar@975
   191
        PathDumperConstraints() {}
alpar@96
   192
      };
alpar@96
   193
alpar@96
   194
      template <typename _Digraph, typename _Path>
alpar@96
   195
      struct PathDumperConstraints<
alpar@209
   196
        _Digraph, _Path,
alpar@96
   197
        typename enable_if<typename _Path::RevPathTag, void>::type
alpar@96
   198
      > {
alpar@96
   199
        void constraints() {
alpar@96
   200
          int l = p.length();
alpar@96
   201
          int e = p.empty();
alpar@96
   202
alpar@96
   203
          typename _Path::RevArcIt id, i(p);
alpar@96
   204
alpar@96
   205
          ++i;
alpar@96
   206
          typename _Digraph::Arc ed = i;
alpar@96
   207
alpar@96
   208
          e = (i == INVALID);
alpar@96
   209
          e = (i != INVALID);
alpar@96
   210
alpar@1083
   211
          ::lemon::ignore_unused_variable_warning(l);
alpar@1083
   212
          ::lemon::ignore_unused_variable_warning(e);
alpar@1083
   213
          ::lemon::ignore_unused_variable_warning(id);
alpar@1083
   214
          ::lemon::ignore_unused_variable_warning(ed);
alpar@96
   215
        }
alpar@96
   216
        _Path& p;
alpar@975
   217
        PathDumperConstraints() {}
alpar@96
   218
      };
alpar@209
   219
alpar@96
   220
    }
alpar@96
   221
alpar@96
   222
alpar@96
   223
    /// \brief A skeleton structure for path dumpers.
alpar@96
   224
    ///
alpar@96
   225
    /// A skeleton structure for path dumpers. The path dumpers are
kpeter@785
   226
    /// the generalization of the paths, they can enumerate the arcs
kpeter@785
   227
    /// of the path either in forward or in backward order.
kpeter@785
   228
    /// These classes are typically not used directly, they are rather
kpeter@785
   229
    /// used to be assigned to a real path type.
alpar@96
   230
    ///
alpar@96
   231
    /// The main purpose of this concept is that the shortest path
kpeter@785
   232
    /// algorithms can enumerate the arcs easily in reverse order.
kpeter@785
   233
    /// In LEMON, such algorithms give back a (reverse) path dumper that
kpeter@785
   234
    /// can be assigned to a real path. The dumpers can be implemented as
alpar@96
   235
    /// an adaptor class to the predecessor map.
kpeter@559
   236
    ///
kpeter@559
   237
    /// \tparam GR The digraph type in which the path is.
kpeter@559
   238
    template <typename GR>
alpar@96
   239
    class PathDumper {
alpar@96
   240
    public:
alpar@96
   241
alpar@96
   242
      /// Type of the underlying digraph.
kpeter@559
   243
      typedef GR Digraph;
alpar@96
   244
      /// Arc type of the underlying digraph.
alpar@96
   245
      typedef typename Digraph::Arc Arc;
alpar@96
   246
kpeter@785
   247
      /// Length of the path, i.e. the number of arcs on the path.
alpar@96
   248
      int length() const { return 0;}
alpar@96
   249
alpar@96
   250
      /// Returns whether the path is empty.
alpar@96
   251
      bool empty() const { return true;}
alpar@96
   252
alpar@96
   253
      /// \brief Forward or reverse dumping
alpar@96
   254
      ///
kpeter@785
   255
      /// If this tag is defined to be \c True, then reverse dumping
kpeter@785
   256
      /// is provided in the path dumper. In this case, \c RevArcIt
kpeter@785
   257
      /// iterator should be implemented instead of \c ArcIt iterator.
alpar@96
   258
      typedef False RevPathTag;
alpar@96
   259
kpeter@785
   260
      /// \brief LEMON style iterator for enumerating the arcs of a path.
alpar@96
   261
      ///
kpeter@785
   262
      /// LEMON style iterator class for enumerating the arcs of a path.
alpar@96
   263
      class ArcIt {
alpar@96
   264
      public:
alpar@209
   265
        /// Default constructor
alpar@209
   266
        ArcIt() {}
alpar@209
   267
        /// Invalid constructor
alpar@209
   268
        ArcIt(Invalid) {}
kpeter@785
   269
        /// Sets the iterator to the first arc of the given path
alpar@209
   270
        ArcIt(const PathDumper&) {}
alpar@96
   271
kpeter@785
   272
        /// Conversion to \c Arc
alpar@209
   273
        operator Arc() const { return INVALID; }
alpar@96
   274
alpar@209
   275
        /// Next arc
alpar@209
   276
        ArcIt& operator++() {return *this;}
alpar@96
   277
alpar@209
   278
        /// Comparison operator
alpar@209
   279
        bool operator==(const ArcIt&) const {return true;}
alpar@209
   280
        /// Comparison operator
alpar@209
   281
        bool operator!=(const ArcIt&) const {return true;}
kpeter@212
   282
        /// Comparison operator
kpeter@212
   283
        bool operator<(const ArcIt&) const {return false;}
alpar@96
   284
alpar@96
   285
      };
alpar@96
   286
ggab90@1130
   287
      /// \brief Gets the collection of the arcs of the path.
ggab90@1130
   288
      ///
ggab90@1130
   289
      /// This function can be used for iterating on the
ggab90@1130
   290
      /// arcs of the path. It returns a wrapped
ggab90@1130
   291
      /// ArcIt, which looks like an STL container
ggab90@1130
   292
      /// (by having begin() and end()) which you can use in range-based
ggab90@1130
   293
      /// for loops, STL algorithms, etc.
ggab90@1130
   294
      /// For example you can write:
ggab90@1130
   295
      ///\code
ggab90@1130
   296
      /// for(auto a: p.arcs())
ggab90@1130
   297
      ///   doSomething(a);
ggab90@1130
   298
      ///\endcode
ggab90@1130
   299
      LemonRangeWrapper1<ArcIt, PathDumper> arcs() const {
ggab90@1130
   300
        return LemonRangeWrapper1<ArcIt, PathDumper>(*this);
ggab90@1130
   301
      }
ggab90@1130
   302
ggab90@1130
   303
kpeter@785
   304
      /// \brief LEMON style iterator for enumerating the arcs of a path
kpeter@785
   305
      /// in reverse direction.
alpar@96
   306
      ///
kpeter@785
   307
      /// LEMON style iterator class for enumerating the arcs of a path
kpeter@785
   308
      /// in reverse direction.
alpar@96
   309
      class RevArcIt {
alpar@96
   310
      public:
alpar@209
   311
        /// Default constructor
alpar@209
   312
        RevArcIt() {}
alpar@209
   313
        /// Invalid constructor
alpar@209
   314
        RevArcIt(Invalid) {}
kpeter@785
   315
        /// Sets the iterator to the last arc of the given path
alpar@209
   316
        RevArcIt(const PathDumper &) {}
alpar@96
   317
kpeter@785
   318
        /// Conversion to \c Arc
alpar@209
   319
        operator Arc() const { return INVALID; }
alpar@96
   320
alpar@209
   321
        /// Next arc
alpar@209
   322
        RevArcIt& operator++() {return *this;}
alpar@96
   323
alpar@209
   324
        /// Comparison operator
alpar@209
   325
        bool operator==(const RevArcIt&) const {return true;}
alpar@209
   326
        /// Comparison operator
alpar@209
   327
        bool operator!=(const RevArcIt&) const {return true;}
kpeter@212
   328
        /// Comparison operator
kpeter@212
   329
        bool operator<(const RevArcIt&) const {return false;}
alpar@96
   330
alpar@96
   331
      };
alpar@96
   332
ggab90@1130
   333
      /// \brief Gets the collection of the arcs of the path
ggab90@1130
   334
      /// in reverse direction.
ggab90@1130
   335
      ///
ggab90@1130
   336
      /// This function can be used for iterating on the
ggab90@1130
   337
      /// arcs of the path in reverse direction. It returns a wrapped
ggab90@1130
   338
      /// RevArcIt, which looks like an STL container
ggab90@1130
   339
      /// (by having begin() and end()) which you can use in range-based
ggab90@1130
   340
      /// for loops, STL algorithms, etc.
ggab90@1130
   341
      /// For example you can write:
ggab90@1130
   342
      ///\code
ggab90@1130
   343
      /// for(auto a: p.revArcs())
ggab90@1130
   344
      ///   doSomething(a);
ggab90@1130
   345
      ///\endcode
ggab90@1130
   346
      LemonRangeWrapper1<RevArcIt, PathDumper> revArcs() const {
ggab90@1130
   347
        return LemonRangeWrapper1<RevArcIt, PathDumper>(*this);
ggab90@1130
   348
      }
ggab90@1130
   349
ggab90@1130
   350
alpar@96
   351
      template <typename _Path>
alpar@96
   352
      struct Constraints {
alpar@96
   353
        void constraints() {
alpar@96
   354
          function_requires<_path_bits::
alpar@96
   355
            PathDumperConstraints<Digraph, _Path> >();
alpar@96
   356
        }
alpar@96
   357
      };
alpar@96
   358
alpar@96
   359
    };
alpar@96
   360
alpar@96
   361
alpar@96
   362
    ///@}
alpar@96
   363
  }
alpar@96
   364
alpar@96
   365
} // namespace lemon
alpar@96
   366
deba@529
   367
#endif