lemon/concepts/path.h
author Peter Kovacs <kpeter@inf.elte.hu>
Thu, 06 Aug 2009 20:12:43 +0200
changeset 760 83ce7ce39f21
parent 529 f5bc148f7e1f
child 785 9ae88e7c04a7
child 975 b873350e6258
permissions -rw-r--r--
Rework and fix the implementation of MinMeanCycle (#179)

- Fix the handling of the cycle means.
- Many implementation improvements:
- More efficient data storage for the strongly connected
components.
- Better handling of BFS queues.
- Merge consecutive BFS searches (perform two BFS searches
instead of three).

This version is about two times faster on average and an order of
magnitude faster if there are a lot of strongly connected components.
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@559
    41
    /// \tparam GR 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
    ///
kpeter@559
    48
    template <typename GR>
alpar@96
    49
    class Path {
alpar@96
    50
    public:
alpar@96
    51
alpar@96
    52
      /// Type of the underlying digraph.
kpeter@559
    53
      typedef GR 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.
kpeter@559
   208
    ///
kpeter@559
   209
    /// \tparam GR 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.
kpeter@559
   213
    template <typename GR>
alpar@96
   214
    class PathDumper {
alpar@96
   215
    public:
alpar@96
   216
alpar@96
   217
      /// Type of the underlying digraph.
kpeter@559
   218
      typedef GR Digraph;
alpar@96
   219
      /// Arc type of the underlying digraph.
alpar@96
   220
      typedef typename Digraph::Arc Arc;
alpar@96
   221
alpar@96
   222
      /// Length of the path ie. the number of arcs in the path.
alpar@96
   223
      int length() const { return 0;}
alpar@96
   224
alpar@96
   225
      /// Returns whether the path is empty.
alpar@96
   226
      bool empty() const { return true;}
alpar@96
   227
alpar@96
   228
      /// \brief Forward or reverse dumping
alpar@96
   229
      ///
alpar@96
   230
      /// If the RevPathTag is defined and true then reverse dumping
alpar@96
   231
      /// is provided in the path dumper. In this case instead of the
alpar@96
   232
      /// ArcIt the RevArcIt iterator should be implemented in the
alpar@96
   233
      /// dumper.
alpar@96
   234
      typedef False RevPathTag;
alpar@96
   235
ladanyi@236
   236
      /// \brief LEMON style iterator for path arcs
alpar@96
   237
      ///
alpar@96
   238
      /// This class is used to iterate on the arcs of the paths.
alpar@96
   239
      class ArcIt {
alpar@96
   240
      public:
alpar@209
   241
        /// Default constructor
alpar@209
   242
        ArcIt() {}
alpar@209
   243
        /// Invalid constructor
alpar@209
   244
        ArcIt(Invalid) {}
alpar@209
   245
        /// Constructor for first arc
alpar@209
   246
        ArcIt(const PathDumper&) {}
alpar@96
   247
alpar@96
   248
        /// Conversion to Arc
alpar@209
   249
        operator Arc() const { return INVALID; }
alpar@96
   250
alpar@209
   251
        /// Next arc
alpar@209
   252
        ArcIt& operator++() {return *this;}
alpar@96
   253
alpar@209
   254
        /// Comparison operator
alpar@209
   255
        bool operator==(const ArcIt&) const {return true;}
alpar@209
   256
        /// Comparison operator
alpar@209
   257
        bool operator!=(const ArcIt&) const {return true;}
kpeter@212
   258
        /// Comparison operator
kpeter@212
   259
        bool operator<(const ArcIt&) const {return false;}
alpar@96
   260
alpar@96
   261
      };
alpar@96
   262
ladanyi@236
   263
      /// \brief LEMON style iterator for path arcs
alpar@96
   264
      ///
alpar@96
   265
      /// This class is used to iterate on the arcs of the paths in
alpar@96
   266
      /// reverse direction.
alpar@96
   267
      class RevArcIt {
alpar@96
   268
      public:
alpar@209
   269
        /// Default constructor
alpar@209
   270
        RevArcIt() {}
alpar@209
   271
        /// Invalid constructor
alpar@209
   272
        RevArcIt(Invalid) {}
alpar@209
   273
        /// Constructor for first arc
alpar@209
   274
        RevArcIt(const PathDumper &) {}
alpar@96
   275
alpar@96
   276
        /// Conversion to Arc
alpar@209
   277
        operator Arc() const { return INVALID; }
alpar@96
   278
alpar@209
   279
        /// Next arc
alpar@209
   280
        RevArcIt& operator++() {return *this;}
alpar@96
   281
alpar@209
   282
        /// Comparison operator
alpar@209
   283
        bool operator==(const RevArcIt&) const {return true;}
alpar@209
   284
        /// Comparison operator
alpar@209
   285
        bool operator!=(const RevArcIt&) const {return true;}
kpeter@212
   286
        /// Comparison operator
kpeter@212
   287
        bool operator<(const RevArcIt&) const {return false;}
alpar@96
   288
alpar@96
   289
      };
alpar@96
   290
alpar@96
   291
      template <typename _Path>
alpar@96
   292
      struct Constraints {
alpar@96
   293
        void constraints() {
alpar@96
   294
          function_requires<_path_bits::
alpar@96
   295
            PathDumperConstraints<Digraph, _Path> >();
alpar@96
   296
        }
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
} // namespace lemon
alpar@96
   306
deba@529
   307
#endif