lemon/path.h
author deba
Mon, 17 Dec 2007 09:54:26 +0000
changeset 2542 faaa54ec4520
parent 2419 6a567c0f1214
child 2553 bfced05fa852
permissions -rw-r--r--
Bug fix
alpar@906
     1
/* -*- C++ -*-
alpar@906
     2
 *
alpar@1956
     3
 * This file is a part of LEMON, a generic C++ optimization library
alpar@1956
     4
 *
alpar@2391
     5
 * Copyright (C) 2003-2007
alpar@1956
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@1359
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@906
     8
 *
alpar@906
     9
 * Permission to use, modify and distribute this software is granted
alpar@906
    10
 * provided that this copyright notice appears in all copies. For
alpar@906
    11
 * precise terms see the accompanying LICENSE file.
alpar@906
    12
 *
alpar@906
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@906
    14
 * express or implied, and with no claim as to its suitability for any
alpar@906
    15
 * purpose.
alpar@906
    16
 *
alpar@906
    17
 */
hegyi@819
    18
hegyi@819
    19
///\ingroup paths
hegyi@819
    20
///\file
hegyi@819
    21
///\brief Classes for representing paths in graphs.
alpar@1151
    22
///
hegyi@819
    23
alpar@921
    24
#ifndef LEMON_PATH_H
alpar@921
    25
#define LEMON_PATH_H
hegyi@819
    26
hegyi@819
    27
#include <vector>
hegyi@819
    28
#include <algorithm>
hegyi@819
    29
deba@2335
    30
#include <lemon/path_utils.h>
deba@2247
    31
#include <lemon/error.h>
deba@1993
    32
#include <lemon/bits/invalid.h>
hegyi@819
    33
alpar@921
    34
namespace lemon {
hegyi@819
    35
hegyi@819
    36
  /// \addtogroup paths
hegyi@819
    37
  /// @{
hegyi@819
    38
hegyi@819
    39
deba@2335
    40
  /// \brief A structure for representing directed paths in a graph.
deba@2335
    41
  ///
deba@2335
    42
  /// A structure for representing directed path in a graph.
deba@2335
    43
  /// \param Graph The graph type in which the path is.
deba@2335
    44
  ///
deba@2335
    45
  /// In a sense, the path can be treated as a list of edges. The
deba@2335
    46
  /// lemon path type stores just this list. As a consequence it
deba@2335
    47
  /// cannot enumerate the nodes in the path and the zero length paths
deba@2335
    48
  /// cannot store the source.
deba@2335
    49
  ///
deba@2335
    50
  /// This implementation is a back and front insertable and erasable
deba@2335
    51
  /// path type. It can be indexed in O(1) time. The front and back
deba@2335
    52
  /// insertion and erasure is amortized O(1) time. The
deba@2335
    53
  /// impelementation is based on two opposite organized vectors.
deba@2335
    54
  template <typename _Graph>
deba@2247
    55
  class Path {
hegyi@819
    56
  public:
deba@2335
    57
deba@2335
    58
    typedef _Graph Graph;
deba@2247
    59
    typedef typename Graph::Edge Edge;
deba@2247
    60
deba@2335
    61
    /// \brief Default constructor
deba@2335
    62
    ///
deba@2335
    63
    /// Default constructor
deba@2335
    64
    Path() {}
hegyi@819
    65
deba@2335
    66
    /// \brief Template copy constructor
deba@2247
    67
    ///
deba@2335
    68
    /// This path can be initialized with any other path type. It just
deba@2335
    69
    /// makes a copy of the given path.
deba@2335
    70
    template <typename CPath>
deba@2335
    71
    Path(const CPath& cpath) {
deba@2335
    72
      copyPath(*this, cpath);
hegyi@819
    73
    }
hegyi@819
    74
deba@2335
    75
    /// \brief Template copy assignment
hegyi@819
    76
    ///
deba@2335
    77
    /// This path can be initialized with any other path type. It just
deba@2335
    78
    /// makes a copy of the given path.
deba@2335
    79
    template <typename CPath>
deba@2335
    80
    Path& operator=(const CPath& cpath) {
deba@2335
    81
      copyPath(*this, cpath);
deba@2335
    82
      return *this;
hegyi@819
    83
    }
hegyi@819
    84
deba@2335
    85
    /// \brief Lemon style iterator for path edges
deba@2247
    86
    ///
deba@2335
    87
    /// This class is used to iterate on the edges of the paths.
deba@2335
    88
    class EdgeIt {
deba@2247
    89
      friend class Path;
deba@2247
    90
    public:
deba@2335
    91
      /// \brief Default constructor
deba@2335
    92
      EdgeIt() {}
deba@2335
    93
      /// \brief Invalid constructor
deba@2335
    94
      EdgeIt(Invalid) : path(0), idx(-1) {}
deba@2335
    95
      /// \brief Initializate the constructor to the first edge of path
deba@2335
    96
      EdgeIt(const Path &_path) 
deba@2335
    97
        : path(&_path), idx(_path.empty() ? -1 : 0) {}
hegyi@819
    98
deba@2335
    99
    private:
hegyi@819
   100
deba@2335
   101
      EdgeIt(const Path &_path, int _idx) 
ladanyi@2523
   102
        : path(&_path), idx(_idx) {}
deba@2247
   103
deba@2335
   104
    public:
deba@2335
   105
deba@2335
   106
      /// \brief Conversion to Edge
deba@2335
   107
      operator const Edge&() const {
deba@2335
   108
        return path->nth(idx);
deba@2247
   109
      }
deba@2247
   110
deba@2335
   111
      /// \brief Next edge
deba@2335
   112
      EdgeIt& operator++() { 
deba@2335
   113
        ++idx;
deba@2335
   114
        if (idx >= path->length()) idx = -1; 
deba@2247
   115
        return *this; 
deba@2247
   116
      }
deba@2247
   117
deba@2247
   118
      /// \brief Comparison operator
deba@2335
   119
      bool operator==(const EdgeIt& e) const { return idx==e.idx; }
deba@2247
   120
      /// \brief Comparison operator
deba@2335
   121
      bool operator!=(const EdgeIt& e) const { return idx!=e.idx; }
deba@2247
   122
      /// \brief Comparison operator
deba@2335
   123
      bool operator<(const EdgeIt& e) const { return idx<e.idx; }
deba@2247
   124
deba@2247
   125
    private:
deba@2247
   126
      const Path *path;
deba@2335
   127
      int idx;
deba@2247
   128
    };
deba@2247
   129
deba@2335
   130
    /// \brief Length of the path.
deba@2335
   131
    int length() const { return head.size() + tail.size(); }
deba@2335
   132
    /// \brief Returns whether the path is empty.
deba@2335
   133
    bool empty() const { return head.empty() && tail.empty(); }
deba@2335
   134
deba@2335
   135
    /// \brief Resets the path to an empty path.
deba@2335
   136
    void clear() { head.clear(); tail.clear(); }
deba@2335
   137
deba@2335
   138
    /// \brief Gives back the nth edge.
deba@2335
   139
    ///
deba@2335
   140
    /// \pre n is in the [0..length() - 1] range
deba@2335
   141
    const Edge& nth(int n) const {
deba@2386
   142
      return n < int(head.size()) ? *(head.rbegin() + n) :
deba@2335
   143
        *(tail.begin() + (n - head.size()));
deba@2335
   144
    }
deba@2335
   145
deba@2335
   146
    /// \brief Initializes edge iterator to point to the nth edge
deba@2335
   147
    ///
deba@2335
   148
    /// \pre n is in the [0..length() - 1] range
deba@2335
   149
    EdgeIt nthIt(int n) const {
deba@2335
   150
      return EdgeIt(*this, n);
deba@2335
   151
    }
deba@2335
   152
deba@2335
   153
    /// \brief Gives back the first edge of the path
deba@2335
   154
    const Edge& front() const {
deba@2335
   155
      return head.empty() ? tail.front() : head.back();
deba@2335
   156
    }
deba@2335
   157
deba@2335
   158
    /// \brief Add a new edge before the current path
deba@2335
   159
    void addFront(const Edge& edge) {
deba@2335
   160
      head.push_back(edge);
deba@2335
   161
    }
deba@2335
   162
deba@2335
   163
    /// \brief Erase the first edge of the path
deba@2335
   164
    void eraseFront() {
deba@2335
   165
      if (!head.empty()) {
deba@2335
   166
        head.pop_back();
deba@2335
   167
      } else {
deba@2335
   168
        head.clear();
deba@2335
   169
        int halfsize = tail.size() / 2;
deba@2335
   170
        head.resize(halfsize);
deba@2335
   171
        std::copy(tail.begin() + 1, tail.begin() + halfsize + 1,
deba@2335
   172
                  head.rbegin());
deba@2335
   173
        std::copy(tail.begin() + halfsize + 1, tail.end(), tail.begin());
deba@2335
   174
        tail.resize(tail.size() - halfsize - 1);
deba@2335
   175
      }
deba@2335
   176
    }
deba@2335
   177
deba@2335
   178
    /// \brief Gives back the last edge of the path
deba@2335
   179
    const Edge& back() const {
deba@2335
   180
      return tail.empty() ? head.front() : tail.back();
deba@2335
   181
    }
deba@2335
   182
deba@2335
   183
    /// \brief Add a new edge behind the current path
deba@2335
   184
    void addBack(const Edge& edge) {
deba@2335
   185
      tail.push_back(edge);
deba@2335
   186
    }
deba@2335
   187
deba@2335
   188
    /// \brief Erase the last edge of the path
deba@2335
   189
    void eraseBack() {
deba@2335
   190
      if (!tail.empty()) {
deba@2335
   191
        tail.pop_back();
deba@2335
   192
      } else {
deba@2335
   193
        int halfsize = head.size() / 2;
deba@2335
   194
        tail.resize(halfsize);
deba@2335
   195
        std::copy(head.begin() + 1, head.begin() + halfsize + 1,
deba@2335
   196
                  tail.rbegin());
deba@2335
   197
        std::copy(head.begin() + halfsize + 1, head.end(), head.begin());
deba@2335
   198
        head.resize(head.size() - halfsize - 1);
deba@2335
   199
      }
deba@2335
   200
    }
deba@2335
   201
deba@2335
   202
deba@2335
   203
deba@2335
   204
    typedef True BuildTag;
deba@2335
   205
deba@2335
   206
    template <typename CPath>
deba@2335
   207
    void build(const CPath& path) {
deba@2335
   208
      int len = path.length();
deba@2335
   209
      tail.reserve(len);
deba@2335
   210
      for (typename CPath::EdgeIt it(path); it != INVALID; ++it) {
deba@2335
   211
        tail.push_back(it);
deba@2335
   212
      }
deba@2335
   213
    }
deba@2335
   214
deba@2335
   215
    template <typename CPath>
deba@2335
   216
    void buildRev(const CPath& path) {
deba@2335
   217
      int len = path.length();
deba@2335
   218
      head.reserve(len);
deba@2357
   219
      for (typename CPath::RevEdgeIt it(path); it != INVALID; ++it) {
deba@2335
   220
        head.push_back(it);
deba@2335
   221
      }
deba@2335
   222
    }
deba@2335
   223
deba@2335
   224
  protected:
deba@2335
   225
    typedef std::vector<Edge> Container;
deba@2335
   226
    Container head, tail;
deba@2335
   227
deba@2335
   228
  };
deba@2335
   229
deba@2335
   230
  /// \brief A structure for representing directed paths in a graph.
deba@2335
   231
  ///
deba@2335
   232
  /// A structure for representing directed path in a graph.
deba@2335
   233
  /// \param Graph The graph type in which the path is.
deba@2335
   234
  ///
deba@2335
   235
  /// In a sense, the path can be treated as a list of edges. The
deba@2335
   236
  /// lemon path type stores just this list. As a consequence it
deba@2335
   237
  /// cannot enumerate the nodes in the path and the zero length paths
deba@2335
   238
  /// cannot store the source.
deba@2335
   239
  ///
deba@2335
   240
  /// This implementation is a just back insertable and erasable path
deba@2335
   241
  /// type. It can be indexed in O(1) time. The back insertion and
deba@2335
   242
  /// erasure is amortized O(1) time. This implementation is faster
deba@2335
   243
  /// then the \c Path type because it use just one vector for the
deba@2335
   244
  /// edges.
deba@2335
   245
  template <typename _Graph>
deba@2335
   246
  class SimplePath {
deba@2335
   247
  public:
deba@2335
   248
deba@2335
   249
    typedef _Graph Graph;
deba@2335
   250
    typedef typename Graph::Edge Edge;
deba@2335
   251
deba@2335
   252
    /// \brief Default constructor
deba@2335
   253
    ///
deba@2335
   254
    /// Default constructor
deba@2335
   255
    SimplePath() {}
deba@2335
   256
deba@2335
   257
    /// \brief Template copy constructor
deba@2335
   258
    ///
deba@2335
   259
    /// This path can be initialized with any other path type. It just
deba@2335
   260
    /// makes a copy of the given path.
deba@2335
   261
    template <typename CPath>
deba@2335
   262
    SimplePath(const CPath& cpath) {
deba@2335
   263
      copyPath(*this, cpath);
deba@2335
   264
    }
deba@2335
   265
deba@2335
   266
    /// \brief Template copy assignment
deba@2335
   267
    ///
deba@2335
   268
    /// This path can be initialized with any other path type. It just
deba@2335
   269
    /// makes a copy of the given path.
deba@2335
   270
    template <typename CPath>
deba@2335
   271
    SimplePath& operator=(const CPath& cpath) {
deba@2335
   272
      copyPath(*this, cpath);
deba@2335
   273
      return *this;
deba@2335
   274
    }
deba@2335
   275
deba@2247
   276
    /// \brief Iterator class to iterate on the edges of the paths
deba@2247
   277
    ///
deba@2247
   278
    /// This class is used to iterate on the edges of the paths
deba@2335
   279
    ///
deba@2247
   280
    /// Of course it converts to Graph::Edge
hegyi@819
   281
    class EdgeIt {
deba@2335
   282
      friend class SimplePath;
deba@2335
   283
    public:
deba@2335
   284
      /// Default constructor
deba@2335
   285
      EdgeIt() {}
deba@2335
   286
      /// Invalid constructor
deba@2335
   287
      EdgeIt(Invalid) : path(0), idx(-1) {}
deba@2335
   288
      /// \brief Initializate the constructor to the first edge of path
deba@2335
   289
      EdgeIt(const SimplePath &_path) 
deba@2335
   290
        : path(&_path), idx(_path.empty() ? -1 : 0) {}
deba@2335
   291
deba@2335
   292
    private:
deba@2335
   293
deba@2335
   294
      /// Constructor with starting point
deba@2335
   295
      EdgeIt(const SimplePath &_path, int _idx) 
deba@2335
   296
        : idx(_idx), path(&_path) {}
deba@2335
   297
deba@2247
   298
    public:
hegyi@819
   299
deba@2335
   300
      ///Conversion to Graph::Edge
deba@2335
   301
      operator const Edge&() const {
deba@2335
   302
        return path->nth(idx);
hegyi@819
   303
      }
hegyi@819
   304
deba@2335
   305
      /// Next edge
deba@2247
   306
      EdgeIt& operator++() { 
deba@2335
   307
        ++idx;
deba@2335
   308
        if (idx >= path->length()) idx = -1; 
deba@2247
   309
        return *this; 
deba@2247
   310
      }
deba@2247
   311
hegyi@819
   312
      /// Comparison operator
deba@2335
   313
      bool operator==(const EdgeIt& e) const { return idx==e.idx; }
deba@2335
   314
      /// Comparison operator
deba@2335
   315
      bool operator!=(const EdgeIt& e) const { return idx!=e.idx; }
deba@2335
   316
      /// Comparison operator
deba@2335
   317
      bool operator<(const EdgeIt& e) const { return idx<e.idx; }
deba@2247
   318
deba@2335
   319
    private:
deba@2335
   320
      const SimplePath *path;
deba@2335
   321
      int idx;
deba@2335
   322
    };
deba@2335
   323
deba@2335
   324
    /// \brief Length of the path.
deba@2335
   325
    int length() const { return data.size(); }
deba@2335
   326
    /// \brief Returns whether the path is empty.
deba@2335
   327
    bool empty() const { return data.empty(); }
deba@2335
   328
deba@2335
   329
    /// \brief Resets the path to an empty path.
deba@2335
   330
    void clear() { data.clear(); }
deba@2335
   331
deba@2335
   332
    /// \brief Gives back the nth edge.
deba@2335
   333
    ///
deba@2335
   334
    /// \pre n is in the [0..length() - 1] range
deba@2335
   335
    const Edge& nth(int n) const {
deba@2335
   336
      return data[n];
deba@2335
   337
    }
deba@2335
   338
deba@2335
   339
    /// \brief  Initializes edge iterator to point to the nth edge.
deba@2335
   340
    EdgeIt nthIt(int n) const {
deba@2335
   341
      return EdgeIt(*this, n);
deba@2335
   342
    }
deba@2335
   343
ladanyi@2419
   344
    /// \brief Gives back the first edge of the path.
ladanyi@2419
   345
    const Edge& front() const {
ladanyi@2419
   346
      return data.front();
ladanyi@2419
   347
    }
ladanyi@2419
   348
deba@2335
   349
    /// \brief Gives back the last edge of the path.
deba@2335
   350
    const Edge& back() const {
deba@2335
   351
      return data.back();
deba@2335
   352
    }
deba@2335
   353
deba@2335
   354
    /// \brief Add a new edge behind the current path.
deba@2335
   355
    void addBack(const Edge& edge) {
deba@2335
   356
      data.push_back(edge);
deba@2335
   357
    }
deba@2335
   358
deba@2335
   359
    /// \brief Erase the last edge of the path
deba@2335
   360
    void eraseBack() {
deba@2335
   361
      data.pop_back();
deba@2335
   362
    }
deba@2335
   363
deba@2335
   364
    typedef True BuildTag;
deba@2335
   365
deba@2335
   366
    template <typename CPath>
deba@2335
   367
    void build(const CPath& path) {
deba@2335
   368
      int len = path.length();
deba@2335
   369
      data.resize(len);
deba@2335
   370
      int index = 0;
deba@2335
   371
      for (typename CPath::EdgeIt it(path); it != INVALID; ++it) {
deba@2335
   372
        data[index] = it;;
deba@2335
   373
        ++index;
deba@2335
   374
      }
deba@2335
   375
    }
deba@2335
   376
deba@2335
   377
    template <typename CPath>
deba@2335
   378
    void buildRev(const CPath& path) {
deba@2335
   379
      int len = path.length();
deba@2335
   380
      data.resize(len);
deba@2335
   381
      int index = len;
deba@2357
   382
      for (typename CPath::RevEdgeIt it(path); it != INVALID; ++it) {
deba@2335
   383
        --index;
deba@2335
   384
        data[index] = it;;
deba@2335
   385
      }
deba@2335
   386
    }
deba@2335
   387
deba@2335
   388
  protected:
deba@2335
   389
    typedef std::vector<Edge> Container;
deba@2335
   390
    Container data;
deba@2335
   391
deba@2335
   392
  };
deba@2335
   393
deba@2335
   394
  /// \brief A structure for representing directed paths in a graph.
deba@2335
   395
  ///
deba@2335
   396
  /// A structure for representing directed path in a graph.
deba@2335
   397
  /// \param Graph The graph type in which the path is.
deba@2335
   398
  ///
deba@2335
   399
  /// In a sense, the path can be treated as a list of edges. The
deba@2335
   400
  /// lemon path type stores just this list. As a consequence it
deba@2335
   401
  /// cannot enumerate the nodes in the path and the zero length paths
deba@2335
   402
  /// cannot store the source.
deba@2335
   403
  ///
deba@2335
   404
  /// This implementation is a back and front insertable and erasable
deba@2335
   405
  /// path type. It can be indexed in O(k) time, where k is the rank
deba@2335
   406
  /// of the edge in the path. The length can be computed in O(n)
deba@2335
   407
  /// time. The front and back insertion and erasure is O(1) time
deba@2335
   408
  /// and it can be splited and spliced in O(1) time.
deba@2335
   409
  template <typename _Graph>
deba@2335
   410
  class ListPath {
deba@2335
   411
  public:
deba@2335
   412
deba@2335
   413
    typedef _Graph Graph;
deba@2335
   414
    typedef typename Graph::Edge Edge;
deba@2335
   415
deba@2335
   416
  protected:
deba@2335
   417
deba@2335
   418
    // the std::list<> is incompatible 
deba@2335
   419
    // hard to create invalid iterator
deba@2335
   420
    struct Node {
deba@2335
   421
      Edge edge;
deba@2335
   422
      Node *next, *prev;
deba@2335
   423
    };
deba@2335
   424
deba@2335
   425
    Node *first, *last;
deba@2335
   426
deba@2335
   427
    std::allocator<Node> alloc;
deba@2335
   428
deba@2335
   429
  public:
deba@2335
   430
 
deba@2335
   431
    /// \brief Default constructor
deba@2335
   432
    ///
deba@2335
   433
    /// Default constructor
deba@2335
   434
    ListPath() : first(0), last(0) {}
deba@2335
   435
deba@2335
   436
    /// \brief Template copy constructor
deba@2335
   437
    ///
deba@2335
   438
    /// This path can be initialized with any other path type. It just
deba@2335
   439
    /// makes a copy of the given path.
deba@2335
   440
    template <typename CPath>
deba@2335
   441
    ListPath(const CPath& cpath) : first(0), last(0) {
deba@2335
   442
      copyPath(*this, cpath);
deba@2335
   443
    }
deba@2335
   444
deba@2335
   445
    /// \brief Destructor of the path
deba@2335
   446
    ///
deba@2335
   447
    /// Destructor of the path
deba@2335
   448
    ~ListPath() {
deba@2335
   449
      clear();
deba@2335
   450
    }
deba@2335
   451
deba@2335
   452
    /// \brief Template copy assignment
deba@2335
   453
    ///
deba@2335
   454
    /// This path can be initialized with any other path type. It just
deba@2335
   455
    /// makes a copy of the given path.
deba@2335
   456
    template <typename CPath>
deba@2335
   457
    ListPath& operator=(const CPath& cpath) {
deba@2335
   458
      copyPath(*this, cpath);
deba@2335
   459
      return *this;
deba@2335
   460
    }
deba@2335
   461
deba@2335
   462
    /// \brief Iterator class to iterate on the edges of the paths
deba@2335
   463
    ///
deba@2335
   464
    /// This class is used to iterate on the edges of the paths
deba@2335
   465
    ///
deba@2335
   466
    /// Of course it converts to Graph::Edge
deba@2335
   467
    class EdgeIt {
deba@2335
   468
      friend class ListPath;
deba@2335
   469
    public:
deba@2335
   470
      /// Default constructor
deba@2335
   471
      EdgeIt() {}
deba@2335
   472
      /// Invalid constructor
deba@2335
   473
      EdgeIt(Invalid) : path(0), node(0) {}
deba@2335
   474
      /// \brief Initializate the constructor to the first edge of path
deba@2335
   475
      EdgeIt(const ListPath &_path) 
deba@2335
   476
        : path(&_path), node(_path.first) {}
deba@2335
   477
deba@2335
   478
    protected:
deba@2335
   479
deba@2335
   480
      EdgeIt(const ListPath &_path, Node *_node) 
deba@2335
   481
        : path(&_path), node(_node) {}
deba@2335
   482
deba@2335
   483
deba@2335
   484
    public:
deba@2335
   485
deba@2335
   486
      ///Conversion to Graph::Edge
deba@2335
   487
      operator const Edge&() const {
deba@2335
   488
        return node->edge;
deba@2335
   489
      }
deba@2335
   490
deba@2335
   491
      /// Next edge
deba@2335
   492
      EdgeIt& operator++() { 
deba@2335
   493
        node = node->next;
deba@2335
   494
        return *this; 
deba@2335
   495
      }
deba@2335
   496
hegyi@819
   497
      /// Comparison operator
deba@2335
   498
      bool operator==(const EdgeIt& e) const { return node==e.node; }
deba@2335
   499
      /// Comparison operator
deba@2335
   500
      bool operator!=(const EdgeIt& e) const { return node!=e.node; }
deba@2335
   501
      /// Comparison operator
deba@2335
   502
      bool operator<(const EdgeIt& e) const { return node<e.node; }
deba@2247
   503
deba@2335
   504
    private:
deba@2335
   505
      const ListPath *path;
deba@2335
   506
      Node *node;
deba@2335
   507
    };
deba@2335
   508
deba@2335
   509
    /// \brief Gives back the nth edge.
deba@2335
   510
    ///
deba@2335
   511
    /// Gives back the nth edge in O(n) time.
deba@2335
   512
    /// \pre n is in the [0..length() - 1] range
deba@2335
   513
    const Edge& nth(int n) const {
deba@2335
   514
      Node *node = first;
deba@2335
   515
      for (int i = 0; i < n; ++i) {
deba@2335
   516
        node = node->next;
deba@2335
   517
      }
deba@2335
   518
      return node->edge;
deba@2335
   519
    }
deba@2335
   520
deba@2335
   521
    /// \brief Initializes edge iterator to point to the nth edge.
deba@2335
   522
    EdgeIt nthIt(int n) const {
deba@2335
   523
      Node *node = first;
deba@2335
   524
      for (int i = 0; i < n; ++i) {
deba@2335
   525
        node = node->next;
deba@2335
   526
      }
deba@2335
   527
      return EdgeIt(*this, node);
deba@2335
   528
    }
deba@2335
   529
deba@2335
   530
    /// \brief Length of the path.
deba@2335
   531
    int length() const {
deba@2335
   532
      int len = 0;
deba@2335
   533
      Node *node = first;
deba@2335
   534
      while (node != 0) {
deba@2335
   535
        node = node->next;
deba@2335
   536
        ++len;
deba@2335
   537
      }
deba@2335
   538
      return len;
deba@2335
   539
    }
deba@2335
   540
deba@2335
   541
    /// \brief Returns whether the path is empty.
deba@2335
   542
    bool empty() const { return first == 0; }
deba@2335
   543
deba@2335
   544
    /// \brief Resets the path to an empty path.
deba@2335
   545
    void clear() {
deba@2335
   546
      while (first != 0) {
deba@2335
   547
        last = first->next;
deba@2335
   548
        alloc.destroy(first);
deba@2335
   549
        alloc.deallocate(first, 1);
deba@2335
   550
        first = last;
deba@2335
   551
      }
deba@2335
   552
    }
deba@2335
   553
deba@2335
   554
    /// \brief Gives back the first edge of the path
deba@2335
   555
    const Edge& front() const {
deba@2335
   556
      return first->edge;
deba@2335
   557
    }
deba@2335
   558
deba@2335
   559
    /// \brief Add a new edge before the current path
deba@2335
   560
    void addFront(const Edge& edge) {
deba@2335
   561
      Node *node = alloc.allocate(1);
deba@2335
   562
      alloc.construct(node, Node());
deba@2335
   563
      node->prev = 0;
deba@2335
   564
      node->next = first;
deba@2335
   565
      node->edge = edge;
deba@2335
   566
      if (first) {
deba@2335
   567
        first->prev = node;
deba@2335
   568
        first = node;
deba@2335
   569
      } else {
deba@2335
   570
        first = last = node;
deba@2335
   571
      }
deba@2335
   572
    }
deba@2335
   573
deba@2335
   574
    /// \brief Erase the first edge of the path
deba@2335
   575
    void eraseFront() {
deba@2335
   576
      Node *node = first;
deba@2335
   577
      first = first->next;
deba@2335
   578
      if (first) {
deba@2335
   579
        first->prev = 0;
deba@2335
   580
      } else {
deba@2335
   581
        last = 0;
deba@2335
   582
      }
deba@2335
   583
      alloc.destroy(node);
deba@2335
   584
      alloc.deallocate(node, 1);
deba@2335
   585
    }
deba@2335
   586
deba@2335
   587
    /// \brief Gives back the last edge of the path.
deba@2335
   588
    const Edge& back() const {
deba@2335
   589
      return last->edge;
deba@2335
   590
    }
deba@2335
   591
deba@2335
   592
    /// \brief Add a new edge behind the current path.
deba@2335
   593
    void addBack(const Edge& edge) {
deba@2335
   594
      Node *node = alloc.allocate(1);
deba@2335
   595
      alloc.construct(node, Node());
deba@2335
   596
      node->next = 0;
deba@2335
   597
      node->prev = last;
deba@2335
   598
      node->edge = edge;
deba@2335
   599
      if (last) {
deba@2335
   600
        last->next = node;
deba@2335
   601
        last = node;
deba@2335
   602
      } else {
deba@2335
   603
        last = first = node;
deba@2335
   604
      }
deba@2335
   605
    }
deba@2335
   606
deba@2335
   607
    /// \brief Erase the last edge of the path
deba@2335
   608
    void eraseBack() {
deba@2335
   609
      Node *node = last;
deba@2335
   610
      last = last->prev;
deba@2335
   611
      if (last) {
deba@2335
   612
        last->next = 0;
deba@2335
   613
      } else {
deba@2335
   614
        first = 0;
deba@2335
   615
      }
deba@2335
   616
      alloc.destroy(node);
deba@2335
   617
      alloc.deallocate(node, 1);
deba@2335
   618
    }
deba@2335
   619
deba@2335
   620
    /// \brief Splicing the given path to the current path.
deba@2335
   621
    ///
deba@2335
   622
    /// It splices the \c tpath to the back of the current path and \c
deba@2335
   623
    /// tpath becomes empty. The time complexity of this function is
deba@2335
   624
    /// O(1).
deba@2335
   625
    void spliceBack(ListPath& tpath) {
deba@2335
   626
      if (first) {
deba@2335
   627
        if (tpath.first) {
deba@2335
   628
          last->next = tpath.first;
deba@2335
   629
          tpath.first->prev = last;
deba@2335
   630
          last = tpath.last;
deba@2335
   631
        }
deba@2335
   632
      } else {
deba@2335
   633
        first = tpath.first;
deba@2335
   634
        last = tpath.last;
deba@2335
   635
      }
deba@2335
   636
      tpath.first = tpath.last = 0;
deba@2335
   637
    }
deba@2335
   638
deba@2335
   639
    /// \brief Splicing the given path to the current path.
deba@2335
   640
    ///
deba@2335
   641
    /// It splices the \c tpath before the current path and \c tpath
deba@2335
   642
    /// becomes empty. The time complexity of this function
deba@2335
   643
    /// is O(1).
deba@2335
   644
    void spliceFront(ListPath& tpath) {
deba@2335
   645
      if (first) {
deba@2335
   646
        if (tpath.first) {
deba@2335
   647
          first->prev = tpath.last;
deba@2335
   648
          tpath.last->next = first;
deba@2335
   649
          first = tpath.first;
deba@2335
   650
        }
deba@2335
   651
      } else {
deba@2335
   652
        first = tpath.first;
deba@2335
   653
        last = tpath.last;
deba@2335
   654
      }
deba@2335
   655
      tpath.first = tpath.last = 0;
deba@2335
   656
    }
deba@2335
   657
deba@2335
   658
    /// \brief Splicing the given path into the current path.
deba@2335
   659
    ///
deba@2335
   660
    /// It splices the \c tpath into the current path before the
deba@2335
   661
    /// position of \c it iterator and \c tpath becomes empty. The
deba@2335
   662
    /// time complexity of this function is O(1). If the \c it is \c
deba@2335
   663
    /// INVALID then it will splice behind the current path.
deba@2335
   664
    void splice(EdgeIt it, ListPath& tpath) {
deba@2335
   665
      if (it.node) {
deba@2335
   666
        if (tpath.first) {
deba@2335
   667
          tpath.first->prev = it.node->prev;
deba@2335
   668
          if (it.node->prev) {
deba@2335
   669
            it.node->prev->next = tpath.first;
deba@2335
   670
          } else {
deba@2335
   671
            first = tpath.first;
deba@2335
   672
          }
deba@2335
   673
          it.node->prev = tpath.last;
deba@2335
   674
          tpath.last->next = it.node;
deba@2335
   675
        }
deba@2335
   676
      } else {
deba@2335
   677
        if (first) {
deba@2335
   678
          if (tpath.first) {
deba@2335
   679
            last->next = tpath.first;
deba@2335
   680
            tpath.first->prev = last;
deba@2335
   681
            last = tpath.last;
deba@2335
   682
          }
deba@2335
   683
        } else {
deba@2335
   684
          first = tpath.first;
deba@2335
   685
          last = tpath.last;
deba@2335
   686
        }
deba@2335
   687
      }
deba@2335
   688
      tpath.first = tpath.last = 0;
deba@2335
   689
    }
deba@2335
   690
deba@2335
   691
    /// \brief Spliting the current path.
deba@2335
   692
    ///
deba@2335
   693
    /// It splits the current path into two parts. The part before \c
deba@2335
   694
    /// it iterator will remain in the current path and the part from
deba@2335
   695
    /// the it will put into the \c tpath. If the \c tpath had edges
deba@2335
   696
    /// before the operation they will be removed first.  The time
deba@2335
   697
    /// complexity of this function is O(1) plus the clearing of \c
deba@2335
   698
    /// tpath. If the \c it is \c INVALID then it just clears \c
deba@2335
   699
    /// tpath.
deba@2335
   700
    void split(EdgeIt it, ListPath& tpath) {
deba@2335
   701
      tpath.clear();
deba@2335
   702
      if (it.node) {
deba@2335
   703
        tpath.first = it.node;
deba@2335
   704
        tpath.last = last;
deba@2335
   705
        if (it.node->prev) {
deba@2335
   706
          last = it.node->prev;
deba@2335
   707
          last->next = 0;
deba@2335
   708
        } else {
deba@2335
   709
          first = last = 0;
deba@2335
   710
        }
deba@2335
   711
        it.node->prev = 0;
deba@2335
   712
      }
deba@2335
   713
    }
deba@2335
   714
deba@2335
   715
deba@2335
   716
    typedef True BuildTag;
deba@2335
   717
deba@2335
   718
    template <typename CPath>
deba@2335
   719
    void build(const CPath& path) {
deba@2335
   720
      for (typename CPath::EdgeIt it(path); it != INVALID; ++it) {
deba@2335
   721
        addBack(it);
deba@2335
   722
      }
deba@2335
   723
    }
deba@2335
   724
deba@2335
   725
    template <typename CPath>
deba@2335
   726
    void buildRev(const CPath& path) {
deba@2357
   727
      for (typename CPath::RevEdgeIt it(path); it != INVALID; ++it) {
deba@2335
   728
        addFront(it);
deba@2335
   729
      }
deba@2335
   730
    }
deba@2335
   731
deba@2335
   732
  };
deba@2335
   733
deba@2335
   734
  /// \brief A structure for representing directed paths in a graph.
deba@2335
   735
  ///
deba@2335
   736
  /// A structure for representing directed path in a graph.
deba@2335
   737
  /// \param Graph The graph type in which the path is.
deba@2335
   738
  ///
deba@2335
   739
  /// In a sense, the path can be treated as a list of edges. The
deba@2335
   740
  /// lemon path type stores just this list. As a consequence it
deba@2335
   741
  /// cannot enumerate the nodes in the path and the zero length paths
deba@2335
   742
  /// cannot store the source.
deba@2335
   743
  ///
deba@2335
   744
  /// This implementation is completly static, so it cannot be
deba@2335
   745
  /// modified exclude the assign an other path. It is intented to be
athos@2336
   746
  /// used when you want to store a large number of paths because it is
deba@2335
   747
  /// the most memory efficient path type in the lemon.
deba@2335
   748
  template <typename _Graph>
deba@2335
   749
  class StaticPath {
deba@2335
   750
  public:
deba@2335
   751
deba@2335
   752
    typedef _Graph Graph;
deba@2335
   753
    typedef typename Graph::Edge Edge;
deba@2335
   754
deba@2335
   755
    /// \brief Default constructor
deba@2335
   756
    ///
deba@2335
   757
    /// Default constructor
deba@2335
   758
    StaticPath() : len(0), edges(0) {}
deba@2335
   759
    
deba@2335
   760
    /// \brief Template copy constructor
deba@2335
   761
    ///
deba@2335
   762
    /// This path can be initialized with any other path type. It just
deba@2335
   763
    /// makes a copy of the given path.
deba@2335
   764
    template <typename CPath>
deba@2335
   765
    StaticPath(const CPath& cpath) : edges(0) {
deba@2335
   766
      copyPath(*this, cpath);
deba@2335
   767
    }
deba@2335
   768
deba@2335
   769
    /// \brief Destructor of the path
deba@2335
   770
    ///
deba@2335
   771
    /// Destructor of the path
deba@2335
   772
    ~StaticPath() {
deba@2335
   773
      if (edges) delete[] edges;
deba@2335
   774
    }
deba@2335
   775
deba@2335
   776
    /// \brief Template copy assignment
deba@2335
   777
    ///
deba@2335
   778
    /// This path can be initialized with any other path type. It just
deba@2335
   779
    /// makes a copy of the given path.
deba@2335
   780
    template <typename CPath>
deba@2335
   781
    StaticPath& operator=(const CPath& cpath) {
deba@2335
   782
      copyPath(*this, cpath);
deba@2335
   783
      return *this;
deba@2335
   784
    }
deba@2335
   785
deba@2335
   786
    /// \brief Iterator class to iterate on the edges of the paths
deba@2335
   787
    ///
deba@2335
   788
    /// This class is used to iterate on the edges of the paths
deba@2335
   789
    ///
deba@2335
   790
    /// Of course it converts to Graph::Edge
deba@2335
   791
    class EdgeIt {
deba@2335
   792
      friend class StaticPath;
deba@2335
   793
    public:
deba@2335
   794
      /// Default constructor
deba@2335
   795
      EdgeIt() {}
deba@2335
   796
      /// Invalid constructor
deba@2335
   797
      EdgeIt(Invalid) : path(0), idx(-1) {}
deba@2335
   798
      /// Initializate the constructor to the first edge of path
deba@2335
   799
      EdgeIt(const StaticPath &_path) 
deba@2335
   800
        : path(&_path), idx(_path.empty() ? -1 : 0) {}
hegyi@819
   801
hegyi@819
   802
    private:
deba@2247
   803
deba@2335
   804
      /// Constructor with starting point
deba@2335
   805
      EdgeIt(const StaticPath &_path, int _idx) 
deba@2335
   806
        : idx(_idx), path(&_path) {}
deba@2335
   807
deba@2335
   808
    public:
deba@2335
   809
deba@2335
   810
      ///Conversion to Graph::Edge
deba@2335
   811
      operator const Edge&() const {
deba@2335
   812
        return path->nth(idx);
deba@2335
   813
      }
deba@2335
   814
deba@2335
   815
      /// Next edge
deba@2335
   816
      EdgeIt& operator++() { 
deba@2335
   817
        ++idx;
deba@2335
   818
        if (idx >= path->length()) idx = -1; 
deba@2335
   819
        return *this; 
deba@2335
   820
      }
deba@2335
   821
deba@2335
   822
      /// Comparison operator
deba@2335
   823
      bool operator==(const EdgeIt& e) const { return idx==e.idx; }
deba@2335
   824
      /// Comparison operator
deba@2335
   825
      bool operator!=(const EdgeIt& e) const { return idx!=e.idx; }
deba@2335
   826
      /// Comparison operator
deba@2335
   827
      bool operator<(const EdgeIt& e) const { return idx<e.idx; }
deba@2335
   828
deba@2335
   829
    private:
deba@2335
   830
      const StaticPath *path;
deba@2335
   831
      int idx;
hegyi@819
   832
    };
hegyi@819
   833
deba@2335
   834
    /// \brief Gives back the nth edge.
deba@2335
   835
    ///
deba@2335
   836
    /// \pre n is in the [0..length() - 1] range
deba@2335
   837
    const Edge& nth(int n) const {
deba@2335
   838
      return edges[n];
deba@2335
   839
    }
hegyi@819
   840
deba@2335
   841
    /// \brief Initializes edge iterator to point to the nth edge.
deba@2335
   842
    EdgeIt nthIt(int n) const {
deba@2335
   843
      return EdgeIt(*this, n);
deba@2335
   844
    }
hegyi@819
   845
deba@2335
   846
    /// \brief Gives back the length of the path.
deba@2335
   847
    int length() const { return len; }
hegyi@819
   848
deba@2335
   849
    /// \brief Returns true when the path is empty.
deba@2335
   850
    int empty() const { return len == 0; }
hegyi@819
   851
deba@2335
   852
    /// \break Erase all edge in the graph.
deba@2335
   853
    void clear() {
deba@2335
   854
      len = 0;
deba@2335
   855
      if (edges) delete[] edges;
deba@2335
   856
      edges = 0;
deba@2335
   857
    }
hegyi@819
   858
deba@2335
   859
    /// \brief Gives back the first edge of the path.
deba@2335
   860
    const Edge& front() const {
deba@2335
   861
      return edges[0];
deba@2335
   862
    }
hegyi@819
   863
deba@2335
   864
    /// \brief Gives back the last edge of the path.
deba@2335
   865
    const Edge& back() const {
deba@2335
   866
      return edges[len - 1];
deba@2335
   867
    }
deba@2335
   868
deba@2335
   869
deba@2335
   870
    typedef True BuildTag;
deba@2335
   871
deba@2335
   872
    template <typename CPath>
deba@2335
   873
    void build(const CPath& path) {
deba@2335
   874
      len = path.length();
deba@2335
   875
      edges = new Edge[len];
deba@2335
   876
      int index = 0;
deba@2335
   877
      for (typename CPath::EdgeIt it(path); it != INVALID; ++it) {
deba@2335
   878
        edges[index] = it;
deba@2335
   879
        ++index;
deba@2247
   880
      }
deba@2335
   881
    }
hegyi@819
   882
deba@2335
   883
    template <typename CPath>
deba@2335
   884
    void buildRev(const CPath& path) {
deba@2335
   885
      len = path.length();
deba@2335
   886
      edges = new Edge[len];
deba@2335
   887
      int index = len;
deba@2357
   888
      for (typename CPath::RevEdgeIt it(path); it != INVALID; ++it) {
deba@2335
   889
        --index;
deba@2335
   890
        edges[index] = it;
deba@2247
   891
      }
deba@2335
   892
    }
hegyi@837
   893
deba@2335
   894
  private:
deba@2335
   895
    int len;
deba@2335
   896
    Edge* edges;
hegyi@819
   897
  };
hegyi@819
   898
hegyi@819
   899
  ///@}
hegyi@819
   900
alpar@921
   901
} // namespace lemon
hegyi@819
   902
alpar@921
   903
#endif // LEMON_PATH_H