gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Path related files ported from svn -r3435 but ItemReader/Writer for Path (originally belonging to path_utils.h) hasn't ported yet.
0 2 4
default
6 files changed with 1463 insertions and 0 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
1
/* -*- C++ -*-
2
 *
3
 * This file is a part of LEMON, a generic C++ optimization library
4
 *
5
 * Copyright (C) 2003-2008
6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8
 *
9
 * Permission to use, modify and distribute this software is granted
10
 * provided that this copyright notice appears in all copies. For
11
 * precise terms see the accompanying LICENSE file.
12
 *
13
 * This software is provided "AS IS" with no warranty of any kind,
14
 * express or implied, and with no claim as to its suitability for any
15
 * purpose.
16
 *
17
 */
18

	
19
///\ingroup concept
20
///\file
21
///\brief Classes for representing paths in digraphs.
22
///
23
///\todo Iterators have obsolete style
24

	
25
#ifndef LEMON_CONCEPT_PATH_H
26
#define LEMON_CONCEPT_PATH_H
27

	
28
#include <lemon/bits/invalid.h>
29
#include <lemon/bits/utility.h>
30
#include <lemon/concept_check.h>
31

	
32
namespace lemon {
33
  namespace concepts {
34

	
35
    /// \addtogroup concept
36
    /// @{
37

	
38
    /// \brief A skeleton structure for representing directed paths in
39
    /// a digraph.
40
    ///
41
    /// A skeleton structure for representing directed paths in a
42
    /// digraph.  
43
    /// \param _Digraph The digraph type in which the path is.
44
    ///
45
    /// In a sense, the path can be treated as a list of arcs. The
46
    /// lemon path type stores just this list. As a consequence it
47
    /// cannot enumerate the nodes in the path and the zero length
48
    /// paths cannot store the source.
49
    ///
50
    template <typename _Digraph>
51
    class Path {
52
    public:
53

	
54
      /// Type of the underlying digraph.
55
      typedef _Digraph Digraph;
56
      /// Arc type of the underlying digraph.
57
      typedef typename Digraph::Arc Arc;
58

	
59
      class ArcIt;
60

	
61
      /// \brief Default constructor
62
      Path() {}
63

	
64
      /// \brief Template constructor
65
      template <typename CPath>
66
      Path(const CPath& cpath) {}
67

	
68
      /// \brief Template assigment
69
      template <typename CPath>
70
      Path& operator=(const CPath& cpath) {}
71

	
72
      /// Length of the path ie. the number of arcs in the path.
73
      int length() const { return 0;}
74

	
75
      /// Returns whether the path is empty.
76
      bool empty() const { return true;}
77

	
78
      /// Resets the path to an empty path.
79
      void clear() {}
80

	
81
      /// \brief Lemon style iterator for path arcs
82
      ///
83
      /// This class is used to iterate on the arcs of the paths.
84
      class ArcIt {
85
      public:
86
	/// Default constructor
87
	ArcIt() {}
88
	/// Invalid constructor
89
	ArcIt(Invalid) {}
90
	/// Constructor for first arc
91
	ArcIt(const Path &) {}
92

	
93
        /// Conversion to Arc
94
	operator Arc() const { return INVALID; }
95

	
96
	/// Next arc
97
	ArcIt& operator++() {return *this;}
98

	
99
	/// Comparison operator
100
	bool operator==(const ArcIt&) const {return true;}
101
	/// Comparison operator
102
	bool operator!=(const ArcIt&) const {return true;}
103
 	/// Comparison operator
104
 	bool operator<(const ArcIt&) const {return false;}
105

	
106
      };
107

	
108
      template <typename _Path>
109
      struct Constraints {
110
        void constraints() {
111
          Path<Digraph> pc;
112
          _Path p, pp(pc);
113
          int l = p.length();
114
          int e = p.empty();
115
          p.clear();
116

	
117
          p = pc;
118

	
119
          typename _Path::ArcIt id, ii(INVALID), i(p);
120

	
121
          ++i;
122
          typename Digraph::Arc ed = i;
123

	
124
          e = (i == ii);
125
          e = (i != ii);
126
          e = (i < ii);
127

	
128
          ignore_unused_variable_warning(l);
129
          ignore_unused_variable_warning(pp);
130
          ignore_unused_variable_warning(e);
131
          ignore_unused_variable_warning(id);
132
          ignore_unused_variable_warning(ii);
133
          ignore_unused_variable_warning(ed);
134
        }
135
      };
136

	
137
    };
138

	
139
    namespace _path_bits {
140
      
141
      template <typename _Digraph, typename _Path, typename RevPathTag = void>
142
      struct PathDumperConstraints {
143
        void constraints() {
144
          int l = p.length();
145
          int e = p.empty();
146

	
147
          typename _Path::ArcIt id, i(p);
148

	
149
          ++i;
150
          typename _Digraph::Arc ed = i;
151

	
152
          e = (i == INVALID);
153
          e = (i != INVALID);
154

	
155
          ignore_unused_variable_warning(l);
156
          ignore_unused_variable_warning(e);
157
          ignore_unused_variable_warning(id);
158
          ignore_unused_variable_warning(ed);
159
        }
160
        _Path& p;
161
      };
162

	
163
      template <typename _Digraph, typename _Path>
164
      struct PathDumperConstraints<
165
        _Digraph, _Path, 
166
        typename enable_if<typename _Path::RevPathTag, void>::type
167
      > {
168
        void constraints() {
169
          int l = p.length();
170
          int e = p.empty();
171

	
172
          typename _Path::RevArcIt id, i(p);
173

	
174
          ++i;
175
          typename _Digraph::Arc ed = i;
176

	
177
          e = (i == INVALID);
178
          e = (i != INVALID);
179

	
180
          ignore_unused_variable_warning(l);
181
          ignore_unused_variable_warning(e);
182
          ignore_unused_variable_warning(id);
183
          ignore_unused_variable_warning(ed);
184
        }
185
        _Path& p;
186
      };
187
    
188
    }
189

	
190

	
191
    /// \brief A skeleton structure for path dumpers.
192
    ///
193
    /// A skeleton structure for path dumpers. The path dumpers are
194
    /// the generalization of the paths. The path dumpers can
195
    /// enumerate the arcs of the path wheter in forward or in
196
    /// backward order.  In most time these classes are not used
197
    /// directly rather it used to assign a dumped class to a real
198
    /// path type.
199
    ///
200
    /// The main purpose of this concept is that the shortest path
201
    /// algorithms can enumerate easily the arcs in reverse order.
202
    /// If we would like to give back a real path from these
203
    /// algorithms then we should create a temporarly path object. In
204
    /// Lemon such algorithms gives back a path dumper what can
205
    /// assigned to a real path and the dumpers can be implemented as
206
    /// an adaptor class to the predecessor map.
207

	
208
    /// \param _Digraph  The digraph type in which the path is.
209
    ///
210
    /// The paths can be constructed from any path type by a
211
    /// template constructor or a template assignment operator.
212
    /// 
213
    template <typename _Digraph>
214
    class PathDumper {
215
    public:
216

	
217
      /// Type of the underlying digraph.
218
      typedef _Digraph Digraph;
219
      /// Arc type of the underlying digraph.
220
      typedef typename Digraph::Arc Arc;
221

	
222
      /// Length of the path ie. the number of arcs in the path.
223
      int length() const { return 0;}
224

	
225
      /// Returns whether the path is empty.
226
      bool empty() const { return true;}
227

	
228
      /// \brief Forward or reverse dumping
229
      ///
230
      /// If the RevPathTag is defined and true then reverse dumping
231
      /// is provided in the path dumper. In this case instead of the
232
      /// ArcIt the RevArcIt iterator should be implemented in the
233
      /// dumper.
234
      typedef False RevPathTag;
235

	
236
      /// \brief Lemon style iterator for path arcs
237
      ///
238
      /// This class is used to iterate on the arcs of the paths.
239
      class ArcIt {
240
      public:
241
	/// Default constructor
242
	ArcIt() {}
243
	/// Invalid constructor
244
	ArcIt(Invalid) {}
245
	/// Constructor for first arc
246
	ArcIt(const PathDumper&) {}
247

	
248
        /// Conversion to Arc
249
	operator Arc() const { return INVALID; }
250

	
251
	/// Next arc
252
	ArcIt& operator++() {return *this;}
253

	
254
	/// Comparison operator
255
	bool operator==(const ArcIt&) const {return true;}
256
	/// Comparison operator
257
	bool operator!=(const ArcIt&) const {return true;}
258
 	/// Comparison operator
259
 	bool operator<(const ArcIt&) const {return false;}
260

	
261
      };
262

	
263
      /// \brief Lemon style iterator for path arcs
264
      ///
265
      /// This class is used to iterate on the arcs of the paths in
266
      /// reverse direction.
267
      class RevArcIt {
268
      public:
269
	/// Default constructor
270
	RevArcIt() {}
271
	/// Invalid constructor
272
	RevArcIt(Invalid) {}
273
	/// Constructor for first arc
274
	RevArcIt(const PathDumper &) {}
275

	
276
        /// Conversion to Arc
277
	operator Arc() const { return INVALID; }
278

	
279
	/// Next arc
280
	RevArcIt& operator++() {return *this;}
281

	
282
	/// Comparison operator
283
	bool operator==(const RevArcIt&) const {return true;}
284
	/// Comparison operator
285
	bool operator!=(const RevArcIt&) const {return true;}
286
 	/// Comparison operator
287
 	bool operator<(const RevArcIt&) const {return false;}
288

	
289
      };
290

	
291
      template <typename _Path>
292
      struct Constraints {
293
        void constraints() {
294
          function_requires<_path_bits::
295
            PathDumperConstraints<Digraph, _Path> >();
296
        }
297
      };
298

	
299
    };
300

	
301

	
302
    ///@}
303
  }
304

	
305
} // namespace lemon
306

	
307
#endif // LEMON_CONCEPT_PATH_H
Ignore white space 6 line context
1
/* -*- C++ -*-
2
 *
3
 * This file is a part of LEMON, a generic C++ optimization library
4
 *
5
 * Copyright (C) 2003-2008
6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8
 *
9
 * Permission to use, modify and distribute this software is granted
10
 * provided that this copyright notice appears in all copies. For
11
 * precise terms see the accompanying LICENSE file.
12
 *
13
 * This software is provided "AS IS" with no warranty of any kind,
14
 * express or implied, and with no claim as to its suitability for any
15
 * purpose.
16
 *
17
 */
18

	
19
///\ingroup paths
20
///\file
21
///\brief Classes for representing paths in digraphs.
22
///
23

	
24
#ifndef LEMON_PATH_H
25
#define LEMON_PATH_H
26

	
27
#include <vector>
28
#include <algorithm>
29

	
30
#include <lemon/path_utils.h>
31
#include <lemon/error.h>
32
#include <lemon/bits/invalid.h>
33

	
34
namespace lemon {
35

	
36
  /// \addtogroup paths
37
  /// @{
38

	
39

	
40
  /// \brief A structure for representing directed paths in a digraph.
41
  ///
42
  /// A structure for representing directed path in a digraph.
43
  /// \param Digraph The digraph type in which the path is.
44
  ///
45
  /// In a sense, the path can be treated as a list of arcs. The
46
  /// lemon path type stores just this list. As a consequence it
47
  /// cannot enumerate the nodes in the path and the zero length paths
48
  /// cannot store the source.
49
  ///
50
  /// This implementation is a back and front insertable and erasable
51
  /// path type. It can be indexed in O(1) time. The front and back
52
  /// insertion and erasure is amortized O(1) time. The
53
  /// impelementation is based on two opposite organized vectors.
54
  template <typename _Digraph>
55
  class Path {
56
  public:
57

	
58
    typedef _Digraph Digraph;
59
    typedef typename Digraph::Arc Arc;
60

	
61
    /// \brief Default constructor
62
    ///
63
    /// Default constructor
64
    Path() {}
65

	
66
    /// \brief Template copy constructor
67
    ///
68
    /// This path can be initialized with any other path type. It just
69
    /// makes a copy of the given path.
70
    template <typename CPath>
71
    Path(const CPath& cpath) {
72
      copyPath(*this, cpath);
73
    }
74

	
75
    /// \brief Template copy assignment
76
    ///
77
    /// This path can be initialized with any other path type. It just
78
    /// makes a copy of the given path.
79
    template <typename CPath>
80
    Path& operator=(const CPath& cpath) {
81
      copyPath(*this, cpath);
82
      return *this;
83
    }
84

	
85
    /// \brief Lemon style iterator for path arcs
86
    ///
87
    /// This class is used to iterate on the arcs of the paths.
88
    class ArcIt {
89
      friend class Path;
90
    public:
91
      /// \brief Default constructor
92
      ArcIt() {}
93
      /// \brief Invalid constructor
94
      ArcIt(Invalid) : path(0), idx(-1) {}
95
      /// \brief Initializate the constructor to the first arc of path
96
      ArcIt(const Path &_path) 
97
        : path(&_path), idx(_path.empty() ? -1 : 0) {}
98

	
99
    private:
100

	
101
      ArcIt(const Path &_path, int _idx) 
102
        : path(&_path), idx(_idx) {}
103

	
104
    public:
105

	
106
      /// \brief Conversion to Arc
107
      operator const Arc&() const {
108
        return path->nth(idx);
109
      }
110

	
111
      /// \brief Next arc
112
      ArcIt& operator++() { 
113
        ++idx;
114
        if (idx >= path->length()) idx = -1; 
115
        return *this; 
116
      }
117

	
118
      /// \brief Comparison operator
119
      bool operator==(const ArcIt& e) const { return idx==e.idx; }
120
      /// \brief Comparison operator
121
      bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
122
      /// \brief Comparison operator
123
      bool operator<(const ArcIt& e) const { return idx<e.idx; }
124

	
125
    private:
126
      const Path *path;
127
      int idx;
128
    };
129

	
130
    /// \brief Length of the path.
131
    int length() const { return head.size() + tail.size(); }
132
    /// \brief Returns whether the path is empty.
133
    bool empty() const { return head.empty() && tail.empty(); }
134

	
135
    /// \brief Resets the path to an empty path.
136
    void clear() { head.clear(); tail.clear(); }
137

	
138
    /// \brief Gives back the nth arc.
139
    ///
140
    /// \pre n is in the [0..length() - 1] range
141
    const Arc& nth(int n) const {
142
      return n < int(head.size()) ? *(head.rbegin() + n) :
143
        *(tail.begin() + (n - head.size()));
144
    }
145

	
146
    /// \brief Initializes arc iterator to point to the nth arc
147
    ///
148
    /// \pre n is in the [0..length() - 1] range
149
    ArcIt nthIt(int n) const {
150
      return ArcIt(*this, n);
151
    }
152

	
153
    /// \brief Gives back the first arc of the path
154
    const Arc& front() const {
155
      return head.empty() ? tail.front() : head.back();
156
    }
157

	
158
    /// \brief Add a new arc before the current path
159
    void addFront(const Arc& arc) {
160
      head.push_back(arc);
161
    }
162

	
163
    /// \brief Erase the first arc of the path
164
    void eraseFront() {
165
      if (!head.empty()) {
166
        head.pop_back();
167
      } else {
168
        head.clear();
169
        int halfsize = tail.size() / 2;
170
        head.resize(halfsize);
171
        std::copy(tail.begin() + 1, tail.begin() + halfsize + 1,
172
                  head.rbegin());
173
        std::copy(tail.begin() + halfsize + 1, tail.end(), tail.begin());
174
        tail.resize(tail.size() - halfsize - 1);
175
      }
176
    }
177

	
178
    /// \brief Gives back the last arc of the path
179
    const Arc& back() const {
180
      return tail.empty() ? head.front() : tail.back();
181
    }
182

	
183
    /// \brief Add a new arc behind the current path
184
    void addBack(const Arc& arc) {
185
      tail.push_back(arc);
186
    }
187

	
188
    /// \brief Erase the last arc of the path
189
    void eraseBack() {
190
      if (!tail.empty()) {
191
        tail.pop_back();
192
      } else {
193
        int halfsize = head.size() / 2;
194
        tail.resize(halfsize);
195
        std::copy(head.begin() + 1, head.begin() + halfsize + 1,
196
                  tail.rbegin());
197
        std::copy(head.begin() + halfsize + 1, head.end(), head.begin());
198
        head.resize(head.size() - halfsize - 1);
199
      }
200
    }
201

	
202

	
203

	
204
    typedef True BuildTag;
205

	
206
    template <typename CPath>
207
    void build(const CPath& path) {
208
      int len = path.length();
209
      tail.reserve(len);
210
      for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
211
        tail.push_back(it);
212
      }
213
    }
214

	
215
    template <typename CPath>
216
    void buildRev(const CPath& path) {
217
      int len = path.length();
218
      head.reserve(len);
219
      for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
220
        head.push_back(it);
221
      }
222
    }
223

	
224
  protected:
225
    typedef std::vector<Arc> Container;
226
    Container head, tail;
227

	
228
  };
229

	
230
  /// \brief A structure for representing directed paths in a digraph.
231
  ///
232
  /// A structure for representing directed path in a digraph.
233
  /// \param Digraph The digraph type in which the path is.
234
  ///
235
  /// In a sense, the path can be treated as a list of arcs. The
236
  /// lemon path type stores just this list. As a consequence it
237
  /// cannot enumerate the nodes in the path and the zero length paths
238
  /// cannot store the source.
239
  ///
240
  /// This implementation is a just back insertable and erasable path
241
  /// type. It can be indexed in O(1) time. The back insertion and
242
  /// erasure is amortized O(1) time. This implementation is faster
243
  /// then the \c Path type because it use just one vector for the
244
  /// arcs.
245
  template <typename _Digraph>
246
  class SimplePath {
247
  public:
248

	
249
    typedef _Digraph Digraph;
250
    typedef typename Digraph::Arc Arc;
251

	
252
    /// \brief Default constructor
253
    ///
254
    /// Default constructor
255
    SimplePath() {}
256

	
257
    /// \brief Template copy constructor
258
    ///
259
    /// This path can be initialized with any other path type. It just
260
    /// makes a copy of the given path.
261
    template <typename CPath>
262
    SimplePath(const CPath& cpath) {
263
      copyPath(*this, cpath);
264
    }
265

	
266
    /// \brief Template copy assignment
267
    ///
268
    /// This path can be initialized with any other path type. It just
269
    /// makes a copy of the given path.
270
    template <typename CPath>
271
    SimplePath& operator=(const CPath& cpath) {
272
      copyPath(*this, cpath);
273
      return *this;
274
    }
275

	
276
    /// \brief Iterator class to iterate on the arcs of the paths
277
    ///
278
    /// This class is used to iterate on the arcs of the paths
279
    ///
280
    /// Of course it converts to Digraph::Arc
281
    class ArcIt {
282
      friend class SimplePath;
283
    public:
284
      /// Default constructor
285
      ArcIt() {}
286
      /// Invalid constructor
287
      ArcIt(Invalid) : path(0), idx(-1) {}
288
      /// \brief Initializate the constructor to the first arc of path
289
      ArcIt(const SimplePath &_path) 
290
        : path(&_path), idx(_path.empty() ? -1 : 0) {}
291

	
292
    private:
293

	
294
      /// Constructor with starting point
295
      ArcIt(const SimplePath &_path, int _idx) 
296
        : idx(_idx), path(&_path) {}
297

	
298
    public:
299

	
300
      ///Conversion to Digraph::Arc
301
      operator const Arc&() const {
302
        return path->nth(idx);
303
      }
304

	
305
      /// Next arc
306
      ArcIt& operator++() { 
307
        ++idx;
308
        if (idx >= path->length()) idx = -1; 
309
        return *this; 
310
      }
311

	
312
      /// Comparison operator
313
      bool operator==(const ArcIt& e) const { return idx==e.idx; }
314
      /// Comparison operator
315
      bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
316
      /// Comparison operator
317
      bool operator<(const ArcIt& e) const { return idx<e.idx; }
318

	
319
    private:
320
      const SimplePath *path;
321
      int idx;
322
    };
323

	
324
    /// \brief Length of the path.
325
    int length() const { return data.size(); }
326
    /// \brief Returns whether the path is empty.
327
    bool empty() const { return data.empty(); }
328

	
329
    /// \brief Resets the path to an empty path.
330
    void clear() { data.clear(); }
331

	
332
    /// \brief Gives back the nth arc.
333
    ///
334
    /// \pre n is in the [0..length() - 1] range
335
    const Arc& nth(int n) const {
336
      return data[n];
337
    }
338

	
339
    /// \brief  Initializes arc iterator to point to the nth arc.
340
    ArcIt nthIt(int n) const {
341
      return ArcIt(*this, n);
342
    }
343

	
344
    /// \brief Gives back the first arc of the path.
345
    const Arc& front() const {
346
      return data.front();
347
    }
348

	
349
    /// \brief Gives back the last arc of the path.
350
    const Arc& back() const {
351
      return data.back();
352
    }
353

	
354
    /// \brief Add a new arc behind the current path.
355
    void addBack(const Arc& arc) {
356
      data.push_back(arc);
357
    }
358

	
359
    /// \brief Erase the last arc of the path
360
    void eraseBack() {
361
      data.pop_back();
362
    }
363

	
364
    typedef True BuildTag;
365

	
366
    template <typename CPath>
367
    void build(const CPath& path) {
368
      int len = path.length();
369
      data.resize(len);
370
      int index = 0;
371
      for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
372
        data[index] = it;;
373
        ++index;
374
      }
375
    }
376

	
377
    template <typename CPath>
378
    void buildRev(const CPath& path) {
379
      int len = path.length();
380
      data.resize(len);
381
      int index = len;
382
      for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
383
        --index;
384
        data[index] = it;;
385
      }
386
    }
387

	
388
  protected:
389
    typedef std::vector<Arc> Container;
390
    Container data;
391

	
392
  };
393

	
394
  /// \brief A structure for representing directed paths in a digraph.
395
  ///
396
  /// A structure for representing directed path in a digraph.
397
  /// \param Digraph The digraph type in which the path is.
398
  ///
399
  /// In a sense, the path can be treated as a list of arcs. The
400
  /// lemon path type stores just this list. As a consequence it
401
  /// cannot enumerate the nodes in the path and the zero length paths
402
  /// cannot store the source.
403
  ///
404
  /// This implementation is a back and front insertable and erasable
405
  /// path type. It can be indexed in O(k) time, where k is the rank
406
  /// of the arc in the path. The length can be computed in O(n)
407
  /// time. The front and back insertion and erasure is O(1) time
408
  /// and it can be splited and spliced in O(1) time.
409
  template <typename _Digraph>
410
  class ListPath {
411
  public:
412

	
413
    typedef _Digraph Digraph;
414
    typedef typename Digraph::Arc Arc;
415

	
416
  protected:
417

	
418
    // the std::list<> is incompatible 
419
    // hard to create invalid iterator
420
    struct Node {
421
      Arc arc;
422
      Node *next, *prev;
423
    };
424

	
425
    Node *first, *last;
426

	
427
    std::allocator<Node> alloc;
428

	
429
  public:
430
 
431
    /// \brief Default constructor
432
    ///
433
    /// Default constructor
434
    ListPath() : first(0), last(0) {}
435

	
436
    /// \brief Template copy constructor
437
    ///
438
    /// This path can be initialized with any other path type. It just
439
    /// makes a copy of the given path.
440
    template <typename CPath>
441
    ListPath(const CPath& cpath) : first(0), last(0) {
442
      copyPath(*this, cpath);
443
    }
444

	
445
    /// \brief Destructor of the path
446
    ///
447
    /// Destructor of the path
448
    ~ListPath() {
449
      clear();
450
    }
451

	
452
    /// \brief Template copy assignment
453
    ///
454
    /// This path can be initialized with any other path type. It just
455
    /// makes a copy of the given path.
456
    template <typename CPath>
457
    ListPath& operator=(const CPath& cpath) {
458
      copyPath(*this, cpath);
459
      return *this;
460
    }
461

	
462
    /// \brief Iterator class to iterate on the arcs of the paths
463
    ///
464
    /// This class is used to iterate on the arcs of the paths
465
    ///
466
    /// Of course it converts to Digraph::Arc
467
    class ArcIt {
468
      friend class ListPath;
469
    public:
470
      /// Default constructor
471
      ArcIt() {}
472
      /// Invalid constructor
473
      ArcIt(Invalid) : path(0), node(0) {}
474
      /// \brief Initializate the constructor to the first arc of path
475
      ArcIt(const ListPath &_path) 
476
        : path(&_path), node(_path.first) {}
477

	
478
    protected:
479

	
480
      ArcIt(const ListPath &_path, Node *_node) 
481
        : path(&_path), node(_node) {}
482

	
483

	
484
    public:
485

	
486
      ///Conversion to Digraph::Arc
487
      operator const Arc&() const {
488
        return node->arc;
489
      }
490

	
491
      /// Next arc
492
      ArcIt& operator++() { 
493
        node = node->next;
494
        return *this; 
495
      }
496

	
497
      /// Comparison operator
498
      bool operator==(const ArcIt& e) const { return node==e.node; }
499
      /// Comparison operator
500
      bool operator!=(const ArcIt& e) const { return node!=e.node; }
501
      /// Comparison operator
502
      bool operator<(const ArcIt& e) const { return node<e.node; }
503

	
504
    private:
505
      const ListPath *path;
506
      Node *node;
507
    };
508

	
509
    /// \brief Gives back the nth arc.
510
    ///
511
    /// Gives back the nth arc in O(n) time.
512
    /// \pre n is in the [0..length() - 1] range
513
    const Arc& nth(int n) const {
514
      Node *node = first;
515
      for (int i = 0; i < n; ++i) {
516
        node = node->next;
517
      }
518
      return node->arc;
519
    }
520

	
521
    /// \brief Initializes arc iterator to point to the nth arc.
522
    ArcIt nthIt(int n) const {
523
      Node *node = first;
524
      for (int i = 0; i < n; ++i) {
525
        node = node->next;
526
      }
527
      return ArcIt(*this, node);
528
    }
529

	
530
    /// \brief Length of the path.
531
    int length() const {
532
      int len = 0;
533
      Node *node = first;
534
      while (node != 0) {
535
        node = node->next;
536
        ++len;
537
      }
538
      return len;
539
    }
540

	
541
    /// \brief Returns whether the path is empty.
542
    bool empty() const { return first == 0; }
543

	
544
    /// \brief Resets the path to an empty path.
545
    void clear() {
546
      while (first != 0) {
547
        last = first->next;
548
        alloc.destroy(first);
549
        alloc.deallocate(first, 1);
550
        first = last;
551
      }
552
    }
553

	
554
    /// \brief Gives back the first arc of the path
555
    const Arc& front() const {
556
      return first->arc;
557
    }
558

	
559
    /// \brief Add a new arc before the current path
560
    void addFront(const Arc& arc) {
561
      Node *node = alloc.allocate(1);
562
      alloc.construct(node, Node());
563
      node->prev = 0;
564
      node->next = first;
565
      node->arc = arc;
566
      if (first) {
567
        first->prev = node;
568
        first = node;
569
      } else {
570
        first = last = node;
571
      }
572
    }
573

	
574
    /// \brief Erase the first arc of the path
575
    void eraseFront() {
576
      Node *node = first;
577
      first = first->next;
578
      if (first) {
579
        first->prev = 0;
580
      } else {
581
        last = 0;
582
      }
583
      alloc.destroy(node);
584
      alloc.deallocate(node, 1);
585
    }
586

	
587
    /// \brief Gives back the last arc of the path.
588
    const Arc& back() const {
589
      return last->arc;
590
    }
591

	
592
    /// \brief Add a new arc behind the current path.
593
    void addBack(const Arc& arc) {
594
      Node *node = alloc.allocate(1);
595
      alloc.construct(node, Node());
596
      node->next = 0;
597
      node->prev = last;
598
      node->arc = arc;
599
      if (last) {
600
        last->next = node;
601
        last = node;
602
      } else {
603
        last = first = node;
604
      }
605
    }
606

	
607
    /// \brief Erase the last arc of the path
608
    void eraseBack() {
609
      Node *node = last;
610
      last = last->prev;
611
      if (last) {
612
        last->next = 0;
613
      } else {
614
        first = 0;
615
      }
616
      alloc.destroy(node);
617
      alloc.deallocate(node, 1);
618
    }
619

	
620
    /// \brief Splicing the given path to the current path.
621
    ///
622
    /// It splices the \c tpath to the back of the current path and \c
623
    /// tpath becomes empty. The time complexity of this function is
624
    /// O(1).
625
    void spliceBack(ListPath& tpath) {
626
      if (first) {
627
        if (tpath.first) {
628
          last->next = tpath.first;
629
          tpath.first->prev = last;
630
          last = tpath.last;
631
        }
632
      } else {
633
        first = tpath.first;
634
        last = tpath.last;
635
      }
636
      tpath.first = tpath.last = 0;
637
    }
638

	
639
    /// \brief Splicing the given path to the current path.
640
    ///
641
    /// It splices the \c tpath before the current path and \c tpath
642
    /// becomes empty. The time complexity of this function
643
    /// is O(1).
644
    void spliceFront(ListPath& tpath) {
645
      if (first) {
646
        if (tpath.first) {
647
          first->prev = tpath.last;
648
          tpath.last->next = first;
649
          first = tpath.first;
650
        }
651
      } else {
652
        first = tpath.first;
653
        last = tpath.last;
654
      }
655
      tpath.first = tpath.last = 0;
656
    }
657

	
658
    /// \brief Splicing the given path into the current path.
659
    ///
660
    /// It splices the \c tpath into the current path before the
661
    /// position of \c it iterator and \c tpath becomes empty. The
662
    /// time complexity of this function is O(1). If the \c it is \c
663
    /// INVALID then it will splice behind the current path.
664
    void splice(ArcIt it, ListPath& tpath) {
665
      if (it.node) {
666
        if (tpath.first) {
667
          tpath.first->prev = it.node->prev;
668
          if (it.node->prev) {
669
            it.node->prev->next = tpath.first;
670
          } else {
671
            first = tpath.first;
672
          }
673
          it.node->prev = tpath.last;
674
          tpath.last->next = it.node;
675
        }
676
      } else {
677
        if (first) {
678
          if (tpath.first) {
679
            last->next = tpath.first;
680
            tpath.first->prev = last;
681
            last = tpath.last;
682
          }
683
        } else {
684
          first = tpath.first;
685
          last = tpath.last;
686
        }
687
      }
688
      tpath.first = tpath.last = 0;
689
    }
690

	
691
    /// \brief Spliting the current path.
692
    ///
693
    /// It splits the current path into two parts. The part before \c
694
    /// it iterator will remain in the current path and the part from
695
    /// the it will put into the \c tpath. If the \c tpath had arcs
696
    /// before the operation they will be removed first.  The time
697
    /// complexity of this function is O(1) plus the clearing of \c
698
    /// tpath. If the \c it is \c INVALID then it just clears \c
699
    /// tpath.
700
    void split(ArcIt it, ListPath& tpath) {
701
      tpath.clear();
702
      if (it.node) {
703
        tpath.first = it.node;
704
        tpath.last = last;
705
        if (it.node->prev) {
706
          last = it.node->prev;
707
          last->next = 0;
708
        } else {
709
          first = last = 0;
710
        }
711
        it.node->prev = 0;
712
      }
713
    }
714

	
715

	
716
    typedef True BuildTag;
717

	
718
    template <typename CPath>
719
    void build(const CPath& path) {
720
      for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
721
        addBack(it);
722
      }
723
    }
724

	
725
    template <typename CPath>
726
    void buildRev(const CPath& path) {
727
      for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
728
        addFront(it);
729
      }
730
    }
731

	
732
  };
733

	
734
  /// \brief A structure for representing directed paths in a digraph.
735
  ///
736
  /// A structure for representing directed path in a digraph.
737
  /// \param Digraph The digraph type in which the path is.
738
  ///
739
  /// In a sense, the path can be treated as a list of arcs. The
740
  /// lemon path type stores just this list. As a consequence it
741
  /// cannot enumerate the nodes in the path and the zero length paths
742
  /// cannot store the source.
743
  ///
744
  /// This implementation is completly static, so it cannot be
745
  /// modified exclude the assign an other path. It is intented to be
746
  /// used when you want to store a large number of paths because it is
747
  /// the most memory efficient path type in the lemon.
748
  template <typename _Digraph>
749
  class StaticPath {
750
  public:
751

	
752
    typedef _Digraph Digraph;
753
    typedef typename Digraph::Arc Arc;
754

	
755
    /// \brief Default constructor
756
    ///
757
    /// Default constructor
758
    StaticPath() : len(0), arcs(0) {}
759
    
760
    /// \brief Template copy constructor
761
    ///
762
    /// This path can be initialized with any other path type. It just
763
    /// makes a copy of the given path.
764
    template <typename CPath>
765
    StaticPath(const CPath& cpath) : arcs(0) {
766
      copyPath(*this, cpath);
767
    }
768

	
769
    /// \brief Destructor of the path
770
    ///
771
    /// Destructor of the path
772
    ~StaticPath() {
773
      if (arcs) delete[] arcs;
774
    }
775

	
776
    /// \brief Template copy assignment
777
    ///
778
    /// This path can be initialized with any other path type. It just
779
    /// makes a copy of the given path.
780
    template <typename CPath>
781
    StaticPath& operator=(const CPath& cpath) {
782
      copyPath(*this, cpath);
783
      return *this;
784
    }
785

	
786
    /// \brief Iterator class to iterate on the arcs of the paths
787
    ///
788
    /// This class is used to iterate on the arcs of the paths
789
    ///
790
    /// Of course it converts to Digraph::Arc
791
    class ArcIt {
792
      friend class StaticPath;
793
    public:
794
      /// Default constructor
795
      ArcIt() {}
796
      /// Invalid constructor
797
      ArcIt(Invalid) : path(0), idx(-1) {}
798
      /// Initializate the constructor to the first arc of path
799
      ArcIt(const StaticPath &_path) 
800
        : path(&_path), idx(_path.empty() ? -1 : 0) {}
801

	
802
    private:
803

	
804
      /// Constructor with starting point
805
      ArcIt(const StaticPath &_path, int _idx) 
806
        : idx(_idx), path(&_path) {}
807

	
808
    public:
809

	
810
      ///Conversion to Digraph::Arc
811
      operator const Arc&() const {
812
        return path->nth(idx);
813
      }
814

	
815
      /// Next arc
816
      ArcIt& operator++() { 
817
        ++idx;
818
        if (idx >= path->length()) idx = -1; 
819
        return *this; 
820
      }
821

	
822
      /// Comparison operator
823
      bool operator==(const ArcIt& e) const { return idx==e.idx; }
824
      /// Comparison operator
825
      bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
826
      /// Comparison operator
827
      bool operator<(const ArcIt& e) const { return idx<e.idx; }
828

	
829
    private:
830
      const StaticPath *path;
831
      int idx;
832
    };
833

	
834
    /// \brief Gives back the nth arc.
835
    ///
836
    /// \pre n is in the [0..length() - 1] range
837
    const Arc& nth(int n) const {
838
      return arcs[n];
839
    }
840

	
841
    /// \brief Initializes arc iterator to point to the nth arc.
842
    ArcIt nthIt(int n) const {
843
      return ArcIt(*this, n);
844
    }
845

	
846
    /// \brief Gives back the length of the path.
847
    int length() const { return len; }
848

	
849
    /// \brief Returns true when the path is empty.
850
    int empty() const { return len == 0; }
851

	
852
    /// \break Erase all arc in the digraph.
853
    void clear() {
854
      len = 0;
855
      if (arcs) delete[] arcs;
856
      arcs = 0;
857
    }
858

	
859
    /// \brief Gives back the first arc of the path.
860
    const Arc& front() const {
861
      return arcs[0];
862
    }
863

	
864
    /// \brief Gives back the last arc of the path.
865
    const Arc& back() const {
866
      return arcs[len - 1];
867
    }
868

	
869

	
870
    typedef True BuildTag;
871

	
872
    template <typename CPath>
873
    void build(const CPath& path) {
874
      len = path.length();
875
      arcs = new Arc[len];
876
      int index = 0;
877
      for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
878
        arcs[index] = it;
879
        ++index;
880
      }
881
    }
882

	
883
    template <typename CPath>
884
    void buildRev(const CPath& path) {
885
      len = path.length();
886
      arcs = new Arc[len];
887
      int index = len;
888
      for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
889
        --index;
890
        arcs[index] = it;
891
      }
892
    }
893

	
894
  private:
895
    int len;
896
    Arc* arcs;
897
  };
898

	
899
  ///@}
900

	
901
} // namespace lemon
902

	
903
#endif // LEMON_PATH_H
Ignore white space 6 line context
1
/* -*- C++ -*-
2
 *
3
 * This file is a part of LEMON, a generic C++ optimization library
4
 *
5
 * Copyright (C) 2003-2008
6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8
 *
9
 * Permission to use, modify and distribute this software is granted
10
 * provided that this copyright notice appears in all copies. For
11
 * precise terms see the accompanying LICENSE file.
12
 *
13
 * This software is provided "AS IS" with no warranty of any kind,
14
 * express or implied, and with no claim as to its suitability for any
15
 * purpose.
16
 *
17
 */
18

	
19
///\ingroup paths
20
///\file
21
///\brief Classes for representing paths in digraphs.
22
///
23

	
24
#ifndef LEMON_PATH_UTILS_H
25
#define LEMON_PATH_UTILS_H
26

	
27
#include <lemon/concepts/path.h>
28

	
29
namespace lemon {
30

	
31
  namespace _path_bits {
32

	
33
    template <typename Path, typename Enable = void>
34
    struct RevTagIndicator {
35
      static const bool value = false;
36
    };
37

	
38
    template <typename Digraph>
39
    struct RevTagIndicator<
40
      Digraph, 
41
      typename enable_if<typename Digraph::RevTag, void>::type
42
    > {
43
      static const bool value = true;
44
    };
45

	
46
    template <typename Target, typename Source,
47
              typename BuildEnable = void, typename RevEnable = void>
48
    struct PathCopySelector {
49
      static void copy(Target& target, const Source& source) {
50
        target.clear();
51
        for (typename Source::ArcIt it(source); it != INVALID; ++it) {
52
          target.addBack(it);
53
        }
54
      }
55
    };
56

	
57
    template <typename Target, typename Source, typename BuildEnable>
58
    struct PathCopySelector<
59
      Target, Source, BuildEnable, 
60
      typename enable_if<typename Source::RevPathTag, void>::type> {
61
      static void copy(Target& target, const Source& source) {
62
        target.clear();
63
        for (typename Source::RevArcIt it(source); it != INVALID; ++it) {
64
          target.addFront(it);
65
        }
66
      }
67
    };
68

	
69
    template <typename Target, typename Source, typename RevEnable>
70
    struct PathCopySelector<
71
      Target, Source, 
72
      typename enable_if<typename Target::BuildTag, void>::type, RevEnable> {
73
      static void copy(Target& target, const Source& source) {
74
        target.clear();
75
        target.build(source);
76
      }
77
    };
78

	
79
    template <typename Target, typename Source>
80
    struct PathCopySelector<
81
      Target, Source, 
82
      typename enable_if<typename Target::BuildTag, void>::type,
83
      typename enable_if<typename Source::RevPathTag, void>::type> {
84
      static void copy(Target& target, const Source& source) {
85
        target.clear();
86
        target.buildRev(source);
87
      }
88
    };
89

	
90
  }
91

	
92

	
93
  /// \brief Make of copy of a path.
94
  ///
95
  ///  Make of copy of a path.
96
  template <typename Target, typename Source>
97
  void copyPath(Target& target, const Source& source) {
98
    checkConcept<concepts::PathDumper<typename Source::Digraph>, Source>();
99
    _path_bits::PathCopySelector<Target, Source>::copy(target, source);
100
  }
101

	
102
  /// \brief Checks the path's consistency.
103
  ///
104
  /// Checks that each arc's target is the next's source. 
105
  /// 
106
  template <typename Digraph, typename Path>
107
  bool checkPath(const Digraph& digraph, const Path& path) {
108
    typename Path::ArcIt it(path);
109
    if (it == INVALID) return true;
110
    typename Digraph::Node node = digraph.target(it);
111
    ++it;
112
    while (it != INVALID) {
113
      if (digraph.source(it) != node) return false;
114
      node = digraph.target(it);
115
      ++it;
116
    }
117
    return true;
118
  }
119

	
120
  /// \brief Gives back the source of the path
121
  ///
122
  /// Gives back the source of the path.
123
  template <typename Digraph, typename Path>
124
  typename Digraph::Node pathSource(const Digraph& digraph, const Path& path) {
125
    return digraph.source(path.front());
126
  }
127

	
128
  /// \brief Gives back the target of the path
129
  ///
130
  /// Gives back the target of the path.
131
  template <typename Digraph, typename Path>
132
  typename Digraph::Node pathTarget(const Digraph& digraph, const Path& path) {
133
    return digraph.target(path.back());
134
  }
135

	
136
  /// \brief Class which helps to iterate the nodes of a path
137
  ///
138
  /// In a sense, the path can be treated as a list of arcs. The
139
  /// lemon path type stores just this list. As a consequence it
140
  /// cannot enumerate the nodes in the path and the zero length paths
141
  /// cannot store the node.
142
  ///
143
  /// This class implements the node iterator of a path structure. To
144
  /// provide this feature, the underlying digraph should be given to
145
  /// the constructor of the iterator.
146
  template <typename Path>
147
  class PathNodeIt {
148
  private:
149
    const typename Path::Digraph *_digraph;
150
    typename Path::ArcIt _it;
151
    typename Path::Digraph::Node _nd;
152

	
153
  public:
154

	
155
    typedef typename Path::Digraph Digraph;
156
    typedef typename Digraph::Node Node;
157
    
158
    /// Default constructor
159
    PathNodeIt() {}
160
    /// Invalid constructor
161
    PathNodeIt(Invalid) 
162
      : _digraph(0), _it(INVALID), _nd(INVALID) {}
163
    /// Constructor
164
    PathNodeIt(const Digraph& digraph, const Path& path) 
165
      : _digraph(&digraph), _it(path) {
166
      _nd = (_it != INVALID ? _digraph->source(_it) : INVALID);
167
    }
168
    /// Constructor
169
    PathNodeIt(const Digraph& digraph, const Path& path, const Node& src) 
170
      : _digraph(&digraph), _it(path), _nd(src) {}
171

	
172
    ///Conversion to Digraph::Node
173
    operator Node() const {
174
      return _nd;
175
    }
176

	
177
    /// Next node
178
    PathNodeIt& operator++() {
179
      if (_it == INVALID) _nd = INVALID;
180
      else {
181
	_nd = _digraph->target(_it);
182
	++_it;
183
      }
184
      return *this;
185
    }
186

	
187
    /// Comparison operator
188
    bool operator==(const PathNodeIt& n) const { 
189
      return _it == n._it && _nd == n._nd; 
190
    }
191
    /// Comparison operator
192
    bool operator!=(const PathNodeIt& n) const { 
193
      return _it != n._it || _nd != n._nd; 
194
    }
195
    /// Comparison operator
196
    bool operator<(const PathNodeIt& n) const { 
197
      return (_it < n._it && _nd != INVALID);
198
    }
199
    
200
  };
201
  
202
}
203

	
204
#endif
Ignore white space 6 line context
1
/* -*- C++ -*-
2
 *
3
 * This file is a part of LEMON, a generic C++ optimization library
4
 *
5
 * Copyright (C) 2003-2008
6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8
 *
9
 * Permission to use, modify and distribute this software is granted
10
 * provided that this copyright notice appears in all copies. For
11
 * precise terms see the accompanying LICENSE file.
12
 *
13
 * This software is provided "AS IS" with no warranty of any kind,
14
 * express or implied, and with no claim as to its suitability for any
15
 * purpose.
16
 *
17
 */
18

	
19
#include <string>
20
#include <iostream>
21

	
22
#include <lemon/concepts/path.h>
23
#include <lemon/concepts/digraph.h>
24

	
25
#include <lemon/path.h>
26
#include <lemon/list_graph.h>
27

	
28
#include "test_tools.h"
29

	
30
using namespace std;
31
using namespace lemon;
32

	
33
void check_concepts() {
34
  checkConcept<concepts::Path<ListDigraph>, concepts::Path<ListDigraph> >();
35
  checkConcept<concepts::Path<ListDigraph>, Path<ListDigraph> >();
36
  checkConcept<concepts::Path<ListDigraph>, SimplePath<ListDigraph> >();
37
  checkConcept<concepts::Path<ListDigraph>, StaticPath<ListDigraph> >();
38
  checkConcept<concepts::Path<ListDigraph>, ListPath<ListDigraph> >();
39
}
40

	
41
int main() {
42
  check_concepts();  
43
  return 0;
44
}
Ignore white space 6 line context
... ...
@@ -14,12 +14,14 @@
14 14
lemon_libemon_la_CXXFLAGS = $(GLPK_CFLAGS) $(CPLEX_CFLAGS) $(SOPLEX_CXXFLAGS)
15 15
lemon_libemon_la_LDFLAGS = $(GLPK_LIBS) $(CPLEX_LIBS) $(SOPLEX_LIBS)
16 16

	
17 17
lemon_HEADERS += \
18 18
        lemon/dim2.h \
19 19
	lemon/maps.h \
20
	lemon/path.h \
21
	lemon/path_utils.h \
20 22
        lemon/random.h \
21 23
	lemon/list_graph.h \
22 24
        lemon/tolerance.h
23 25

	
24 26
bits_HEADERS += \
25 27
	lemon/bits/alteration_notifier.h \
... ...
@@ -35,7 +37,8 @@
35 37

	
36 38
concept_HEADERS += \
37 39
	lemon/concept_check.h \
38 40
	lemon/concepts/digraph.h \
39 41
	lemon/concepts/graph.h \
40 42
	lemon/concepts/maps.h \
43
	lemon/concepts/path.h \
41 44
	lemon/concepts/graph_components.h
Ignore white space 12 line context
... ...
@@ -8,18 +8,20 @@
8 8

	
9 9
check_PROGRAMS += \
10 10
	test/digraph_test \
11 11
        test/dim_test \
12 12
	test/graph_test \
13 13
        test/random_test \
14
        test/path_test \
14 15
        test/test_tools_fail \
15 16
        test/test_tools_pass
16 17

	
17 18
TESTS += $(check_PROGRAMS)
18 19
XFAIL_TESTS += test/test_tools_fail$(EXEEXT)
19 20

	
20 21
test_digraph_test_SOURCES = test/digraph_test.cc
21 22
test_dim_test_SOURCES = test/dim_test.cc
22 23
test_graph_test_SOURCES = test/graph_test.cc
24
test_path_test_SOURCES = test/path_test.cc
23 25
test_random_test_SOURCES = test/random_test.cc
24 26
test_test_tools_fail_SOURCES = test/test_tools_fail.cc
25 27
test_test_tools_pass_SOURCES = test/test_tools_pass.cc
0 comments (0 inline)