lemon/concepts/path.h
author Peter Kovacs <kpeter@inf.elte.hu>
Fri, 03 Apr 2009 18:59:15 +0200
changeset 608 6ac5d9ae1d3d
parent 440 88ed40ad0d4f
child 559 c5fd2d996909
permissions -rw-r--r--
Support real types + numerical stability fix in NS (#254)

- Real types are supported by appropriate inicialization.
- A feature of the XTI spanning tree structure is removed to ensure
numerical stability (could cause problems using integer types).
The node potentials are updated always on the lower subtree,
in order to prevent overflow problems.
The former method isn't notably faster during to our tests.
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@440
     5
 * Copyright (C) 2003-2009
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
alpar@96
    21
///\brief Classes for representing paths in digraphs.
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>
alpar@96
    29
alpar@96
    30
namespace lemon {
alpar@96
    31
  namespace concepts {
alpar@96
    32
alpar@96
    33
    /// \addtogroup concept
alpar@96
    34
    /// @{
alpar@96
    35
alpar@96
    36
    /// \brief A skeleton structure for representing directed paths in
alpar@96
    37
    /// a digraph.
alpar@96
    38
    ///
alpar@96
    39
    /// A skeleton structure for representing directed paths in a
alpar@209
    40
    /// digraph.
kpeter@157
    41
    /// \tparam _Digraph The digraph type in which the path is.
alpar@96
    42
    ///
alpar@96
    43
    /// In a sense, the path can be treated as a list of arcs. The
alpar@96
    44
    /// lemon path type stores just this list. As a consequence it
alpar@96
    45
    /// cannot enumerate the nodes in the path and the zero length
alpar@96
    46
    /// paths cannot store the source.
alpar@96
    47
    ///
alpar@96
    48
    template <typename _Digraph>
alpar@96
    49
    class Path {
alpar@96
    50
    public:
alpar@96
    51
alpar@96
    52
      /// Type of the underlying digraph.
alpar@96
    53
      typedef _Digraph Digraph;
alpar@96
    54
      /// Arc type of the underlying digraph.
alpar@96
    55
      typedef typename Digraph::Arc Arc;
alpar@96
    56
alpar@96
    57
      class ArcIt;
alpar@96
    58
alpar@96
    59
      /// \brief Default constructor
alpar@96
    60
      Path() {}
alpar@96
    61
alpar@96
    62
      /// \brief Template constructor
alpar@96
    63
      template <typename CPath>
alpar@96
    64
      Path(const CPath& cpath) {}
alpar@96
    65
alpar@96
    66
      /// \brief Template assigment
alpar@96
    67
      template <typename CPath>
kpeter@278
    68
      Path& operator=(const CPath& cpath) {
kpeter@278
    69
        ignore_unused_variable_warning(cpath);
kpeter@278
    70
        return *this;
kpeter@278
    71
      }
alpar@96
    72
alpar@96
    73
      /// Length of the path ie. the number of arcs in the path.
alpar@96
    74
      int length() const { return 0;}
alpar@96
    75
alpar@96
    76
      /// Returns whether the path is empty.
alpar@96
    77
      bool empty() const { return true;}
alpar@96
    78
alpar@96
    79
      /// Resets the path to an empty path.
alpar@96
    80
      void clear() {}
alpar@96
    81
ladanyi@236
    82
      /// \brief LEMON style iterator for path arcs
alpar@96
    83
      ///
alpar@96
    84
      /// This class is used to iterate on the arcs of the paths.
alpar@96
    85
      class ArcIt {
alpar@96
    86
      public:
alpar@209
    87
        /// Default constructor
alpar@209
    88
        ArcIt() {}
alpar@209
    89
        /// Invalid constructor
alpar@209
    90
        ArcIt(Invalid) {}
alpar@209
    91
        /// Constructor for first arc
alpar@209
    92
        ArcIt(const Path &) {}
alpar@96
    93
alpar@96
    94
        /// Conversion to Arc
alpar@209
    95
        operator Arc() const { return INVALID; }
alpar@96
    96
alpar@209
    97
        /// Next arc
alpar@209
    98
        ArcIt& operator++() {return *this;}
alpar@96
    99
alpar@209
   100
        /// Comparison operator
alpar@209
   101
        bool operator==(const ArcIt&) const {return true;}
alpar@209
   102
        /// Comparison operator
alpar@209
   103
        bool operator!=(const ArcIt&) const {return true;}
kpeter@212
   104
        /// Comparison operator
kpeter@212
   105
        bool operator<(const ArcIt&) const {return false;}
alpar@96
   106
alpar@96
   107
      };
alpar@96
   108
alpar@96
   109
      template <typename _Path>
alpar@96
   110
      struct Constraints {
alpar@96
   111
        void constraints() {
alpar@96
   112
          Path<Digraph> pc;
alpar@96
   113
          _Path p, pp(pc);
alpar@96
   114
          int l = p.length();
alpar@96
   115
          int e = p.empty();
alpar@96
   116
          p.clear();
alpar@96
   117
alpar@96
   118
          p = pc;
alpar@96
   119
alpar@96
   120
          typename _Path::ArcIt id, ii(INVALID), i(p);
alpar@96
   121
alpar@96
   122
          ++i;
alpar@96
   123
          typename Digraph::Arc ed = i;
alpar@96
   124
alpar@96
   125
          e = (i == ii);
alpar@96
   126
          e = (i != ii);
alpar@96
   127
          e = (i < ii);
alpar@96
   128
alpar@96
   129
          ignore_unused_variable_warning(l);
alpar@96
   130
          ignore_unused_variable_warning(pp);
alpar@96
   131
          ignore_unused_variable_warning(e);
alpar@96
   132
          ignore_unused_variable_warning(id);
alpar@96
   133
          ignore_unused_variable_warning(ii);
alpar@96
   134
          ignore_unused_variable_warning(ed);
alpar@96
   135
        }
alpar@96
   136
      };
alpar@96
   137
alpar@96
   138
    };
alpar@96
   139
alpar@96
   140
    namespace _path_bits {
alpar@209
   141
alpar@96
   142
      template <typename _Digraph, typename _Path, typename RevPathTag = void>
alpar@96
   143
      struct PathDumperConstraints {
alpar@96
   144
        void constraints() {
alpar@96
   145
          int l = p.length();
alpar@96
   146
          int e = p.empty();
alpar@96
   147
alpar@96
   148
          typename _Path::ArcIt id, i(p);
alpar@96
   149
alpar@96
   150
          ++i;
alpar@96
   151
          typename _Digraph::Arc ed = i;
alpar@96
   152
alpar@96
   153
          e = (i == INVALID);
alpar@96
   154
          e = (i != INVALID);
alpar@96
   155
alpar@96
   156
          ignore_unused_variable_warning(l);
alpar@96
   157
          ignore_unused_variable_warning(e);
alpar@96
   158
          ignore_unused_variable_warning(id);
alpar@96
   159
          ignore_unused_variable_warning(ed);
alpar@96
   160
        }
alpar@96
   161
        _Path& p;
alpar@96
   162
      };
alpar@96
   163
alpar@96
   164
      template <typename _Digraph, typename _Path>
alpar@96
   165
      struct PathDumperConstraints<
alpar@209
   166
        _Digraph, _Path,
alpar@96
   167
        typename enable_if<typename _Path::RevPathTag, void>::type
alpar@96
   168
      > {
alpar@96
   169
        void constraints() {
alpar@96
   170
          int l = p.length();
alpar@96
   171
          int e = p.empty();
alpar@96
   172
alpar@96
   173
          typename _Path::RevArcIt id, i(p);
alpar@96
   174
alpar@96
   175
          ++i;
alpar@96
   176
          typename _Digraph::Arc ed = i;
alpar@96
   177
alpar@96
   178
          e = (i == INVALID);
alpar@96
   179
          e = (i != INVALID);
alpar@96
   180
alpar@96
   181
          ignore_unused_variable_warning(l);
alpar@96
   182
          ignore_unused_variable_warning(e);
alpar@96
   183
          ignore_unused_variable_warning(id);
alpar@96
   184
          ignore_unused_variable_warning(ed);
alpar@96
   185
        }
alpar@96
   186
        _Path& p;
alpar@96
   187
      };
alpar@209
   188
alpar@96
   189
    }
alpar@96
   190
alpar@96
   191
alpar@96
   192
    /// \brief A skeleton structure for path dumpers.
alpar@96
   193
    ///
alpar@96
   194
    /// A skeleton structure for path dumpers. The path dumpers are
alpar@96
   195
    /// the generalization of the paths. The path dumpers can
alpar@96
   196
    /// enumerate the arcs of the path wheter in forward or in
alpar@96
   197
    /// backward order.  In most time these classes are not used
alpar@96
   198
    /// directly rather it used to assign a dumped class to a real
alpar@96
   199
    /// path type.
alpar@96
   200
    ///
alpar@96
   201
    /// The main purpose of this concept is that the shortest path
alpar@96
   202
    /// algorithms can enumerate easily the arcs in reverse order.
alpar@96
   203
    /// If we would like to give back a real path from these
alpar@96
   204
    /// algorithms then we should create a temporarly path object. In
ladanyi@236
   205
    /// LEMON such algorithms gives back a path dumper what can
alpar@96
   206
    /// assigned to a real path and the dumpers can be implemented as
alpar@96
   207
    /// an adaptor class to the predecessor map.
alpar@96
   208
kpeter@157
   209
    /// \tparam _Digraph  The digraph type in which the path is.
alpar@96
   210
    ///
alpar@96
   211
    /// The paths can be constructed from any path type by a
alpar@96
   212
    /// template constructor or a template assignment operator.
alpar@209
   213
    ///
alpar@96
   214
    template <typename _Digraph>
alpar@96
   215
    class PathDumper {
alpar@96
   216
    public:
alpar@96
   217
alpar@96
   218
      /// Type of the underlying digraph.
alpar@96
   219
      typedef _Digraph Digraph;
alpar@96
   220
      /// Arc type of the underlying digraph.
alpar@96
   221
      typedef typename Digraph::Arc Arc;
alpar@96
   222
alpar@96
   223
      /// Length of the path ie. the number of arcs in the path.
alpar@96
   224
      int length() const { return 0;}
alpar@96
   225
alpar@96
   226
      /// Returns whether the path is empty.
alpar@96
   227
      bool empty() const { return true;}
alpar@96
   228
alpar@96
   229
      /// \brief Forward or reverse dumping
alpar@96
   230
      ///
alpar@96
   231
      /// If the RevPathTag is defined and true then reverse dumping
alpar@96
   232
      /// is provided in the path dumper. In this case instead of the
alpar@96
   233
      /// ArcIt the RevArcIt iterator should be implemented in the
alpar@96
   234
      /// dumper.
alpar@96
   235
      typedef False RevPathTag;
alpar@96
   236
ladanyi@236
   237
      /// \brief LEMON style iterator for path arcs
alpar@96
   238
      ///
alpar@96
   239
      /// This class is used to iterate on the arcs of the paths.
alpar@96
   240
      class ArcIt {
alpar@96
   241
      public:
alpar@209
   242
        /// Default constructor
alpar@209
   243
        ArcIt() {}
alpar@209
   244
        /// Invalid constructor
alpar@209
   245
        ArcIt(Invalid) {}
alpar@209
   246
        /// Constructor for first arc
alpar@209
   247
        ArcIt(const PathDumper&) {}
alpar@96
   248
alpar@96
   249
        /// Conversion to Arc
alpar@209
   250
        operator Arc() const { return INVALID; }
alpar@96
   251
alpar@209
   252
        /// Next arc
alpar@209
   253
        ArcIt& operator++() {return *this;}
alpar@96
   254
alpar@209
   255
        /// Comparison operator
alpar@209
   256
        bool operator==(const ArcIt&) const {return true;}
alpar@209
   257
        /// Comparison operator
alpar@209
   258
        bool operator!=(const ArcIt&) const {return true;}
kpeter@212
   259
        /// Comparison operator
kpeter@212
   260
        bool operator<(const ArcIt&) const {return false;}
alpar@96
   261
alpar@96
   262
      };
alpar@96
   263
ladanyi@236
   264
      /// \brief LEMON style iterator for path arcs
alpar@96
   265
      ///
alpar@96
   266
      /// This class is used to iterate on the arcs of the paths in
alpar@96
   267
      /// reverse direction.
alpar@96
   268
      class RevArcIt {
alpar@96
   269
      public:
alpar@209
   270
        /// Default constructor
alpar@209
   271
        RevArcIt() {}
alpar@209
   272
        /// Invalid constructor
alpar@209
   273
        RevArcIt(Invalid) {}
alpar@209
   274
        /// Constructor for first arc
alpar@209
   275
        RevArcIt(const PathDumper &) {}
alpar@96
   276
alpar@96
   277
        /// Conversion to Arc
alpar@209
   278
        operator Arc() const { return INVALID; }
alpar@96
   279
alpar@209
   280
        /// Next arc
alpar@209
   281
        RevArcIt& operator++() {return *this;}
alpar@96
   282
alpar@209
   283
        /// Comparison operator
alpar@209
   284
        bool operator==(const RevArcIt&) const {return true;}
alpar@209
   285
        /// Comparison operator
alpar@209
   286
        bool operator!=(const RevArcIt&) const {return true;}
kpeter@212
   287
        /// Comparison operator
kpeter@212
   288
        bool operator<(const RevArcIt&) const {return false;}
alpar@96
   289
alpar@96
   290
      };
alpar@96
   291
alpar@96
   292
      template <typename _Path>
alpar@96
   293
      struct Constraints {
alpar@96
   294
        void constraints() {
alpar@96
   295
          function_requires<_path_bits::
alpar@96
   296
            PathDumperConstraints<Digraph, _Path> >();
alpar@96
   297
        }
alpar@96
   298
      };
alpar@96
   299
alpar@96
   300
    };
alpar@96
   301
alpar@96
   302
alpar@96
   303
    ///@}
alpar@96
   304
  }
alpar@96
   305
alpar@96
   306
} // namespace lemon
alpar@96
   307
deba@529
   308
#endif