↑ Collapse diff ↑
Ignore white space 6 line context
1
%%%%% Defining LEMON %%%%%
2

	
3
@misc{lemon,
4
  key =          {LEMON},
5
  title =        {{LEMON} -- {L}ibrary for {E}fficient {M}odeling and
6
                  {O}ptimization in {N}etworks},
7
  howpublished = {\url{http://lemon.cs.elte.hu/}},
8
  year =         2009
9
}
10

	
11
@misc{egres,
12
  key =          {EGRES},
13
  title =        {{EGRES} -- {E}gerv{\'a}ry {R}esearch {G}roup on
14
                  {C}ombinatorial {O}ptimization},
15
  url =          {http://www.cs.elte.hu/egres/}
16
}
17

	
18
@misc{coinor,
19
  key =          {COIN-OR},
20
  title =        {{COIN-OR} -- {C}omputational {I}nfrastructure for
21
                  {O}perations {R}esearch},
22
  url =          {http://www.coin-or.org/}
23
}
24

	
25

	
26
%%%%% Other libraries %%%%%%
27

	
28
@misc{boost,
29
  key =          {Boost},
30
  title =        {{B}oost {C++} {L}ibraries},
31
  url =          {http://www.boost.org/}
32
}
33

	
34
@book{bglbook,
35
  author =       {Jeremy G. Siek and Lee-Quan Lee and Andrew
36
                  Lumsdaine},
37
  title =        {The Boost Graph Library: User Guide and Reference
38
                  Manual},
39
  publisher =    {Addison-Wesley},
40
  year =         2002
41
}
42

	
43
@misc{leda,
44
  key =          {LEDA},
45
  title =        {{LEDA} -- {L}ibrary of {E}fficient {D}ata {T}ypes and
46
                  {A}lgorithms},
47
  url =          {http://www.algorithmic-solutions.com/}
48
}
49

	
50
@book{ledabook,
51
  author =       {Kurt Mehlhorn and Stefan N{\"a}her},
52
  title =        {{LEDA}: {A} platform for combinatorial and geometric
53
                  computing},
54
  isbn =         {0-521-56329-1},
55
  publisher =    {Cambridge University Press},
56
  address =      {New York, NY, USA},
57
  year =         1999
58
}
59

	
60

	
61
%%%%% Tools that LEMON depends on %%%%%
62

	
63
@misc{cmake,
64
  key =          {CMake},
65
  title =        {{CMake} -- {C}ross {P}latform {M}ake},
66
  url =          {http://www.cmake.org/}
67
}
68

	
69
@misc{doxygen,
70
  key =          {Doxygen},
71
  title =        {{Doxygen} -- {S}ource code documentation generator
72
                  tool},
73
  url =          {http://www.doxygen.org/}
74
}
75

	
76

	
77
%%%%% LP/MIP libraries %%%%%
78

	
79
@misc{glpk,
80
  key =          {GLPK},
81
  title =        {{GLPK} -- {GNU} {L}inear {P}rogramming {K}it},
82
  url =          {http://www.gnu.org/software/glpk/}
83
}
84

	
85
@misc{clp,
86
  key =          {Clp},
87
  title =        {{Clp} -- {Coin-Or} {L}inear {P}rogramming},
88
  url =          {http://projects.coin-or.org/Clp/}
89
}
90

	
91
@misc{cbc,
92
  key =          {Cbc},
93
  title =        {{Cbc} -- {Coin-Or} {B}ranch and {C}ut},
94
  url =          {http://projects.coin-or.org/Cbc/}
95
}
96

	
97
@misc{cplex,
98
  key =          {CPLEX},
99
  title =        {{ILOG} {CPLEX}},
100
  url =          {http://www.ilog.com/}
101
}
102

	
103
@misc{soplex,
104
  key =          {SoPlex},
105
  title =        {{SoPlex} -- {T}he {S}equential {O}bject-{O}riented
106
                  {S}implex},
107
  url =          {http://soplex.zib.de/}
108
}
109

	
110

	
111
%%%%% General books %%%%%
112

	
113
@book{amo93networkflows,
114
  author =       {Ravindra K. Ahuja and Thomas L. Magnanti and James
115
                  B. Orlin},
116
  title =        {Network Flows: Theory, Algorithms, and Applications},
117
  publisher =    {Prentice-Hall, Inc.},
118
  year =         1993,
119
  month =        feb,
120
  isbn =         {978-0136175490}
121
}
122

	
123
@book{schrijver03combinatorial,
124
  author =       {Alexander Schrijver},
125
  title =        {Combinatorial Optimization: Polyhedra and Efficiency},
126
  publisher =    {Springer-Verlag},
127
  year =         2003,
128
  isbn =         {978-3540443896}
129
}
130

	
131
@book{clrs01algorithms,
132
  author =       {Thomas H. Cormen and Charles E. Leiserson and Ronald
133
                  L. Rivest and Clifford Stein},
134
  title =        {Introduction to Algorithms},
135
  publisher =    {The MIT Press},
136
  year =         2001,
137
  edition =      {2nd}
138
}
139

	
140
@book{stroustrup00cpp,
141
  author =       {Bjarne Stroustrup},
142
  title =        {The C++ Programming Language},
143
  edition =      {3rd},
144
  publisher =    {Addison-Wesley Professional},
145
  isbn =         0201700735,
146
  month =        {February},
147
  year =         2000
148
}
149

	
150

	
151
%%%%% Maximum flow algorithms %%%%%
152

	
153
@article{edmondskarp72theoretical,
154
  author =       {Jack Edmonds and Richard M. Karp},
155
  title =        {Theoretical improvements in algorithmic efficiency
156
                  for network flow problems},
157
  journal =      {Journal of the ACM},
158
  year =         1972,
159
  volume =       19,
160
  number =       2,
161
  pages =        {248-264}
162
}
163

	
164
@article{goldberg88newapproach,
165
  author =       {Andrew V. Goldberg and Robert E. Tarjan},
166
  title =        {A new approach to the maximum flow problem},
167
  journal =      {Journal of the ACM},
168
  year =         1988,
169
  volume =       35,
170
  number =       4,
171
  pages =        {921-940}
172
}
173

	
174
@article{dinic70algorithm,
175
  author =       {E. A. Dinic},
176
  title =        {Algorithm for solution of a problem of maximum flow
177
                  in a network with power estimation},
178
  journal =      {Soviet Math. Doklady},
179
  year =         1970,
180
  volume =       11,
181
  pages =        {1277-1280}
182
}
183

	
184
@article{goldberg08partial,
185
  author =       {Andrew V. Goldberg},
186
  title =        {The Partial Augment-Relabel Algorithm for the
187
                  Maximum Flow Problem},
188
  journal =      {16th Annual European Symposium on Algorithms},
189
  year =         2008,
190
  pages =        {466-477}
191
}
192

	
193
@article{sleator83dynamic,
194
  author =       {Daniel D. Sleator and Robert E. Tarjan},
195
  title =        {A data structure for dynamic trees},
196
  journal =      {Journal of Computer and System Sciences},
197
  year =         1983,
198
  volume =       26,
199
  number =       3,
200
  pages =        {362-391}
201
}
202

	
203

	
204
%%%%% Minimum mean cycle algorithms %%%%%
205

	
206
@article{karp78characterization,
207
  author =       {Richard M. Karp},
208
  title =        {A characterization of the minimum cycle mean in a
209
                  digraph},
210
  journal =      {Discrete Math.},
211
  year =         1978,
212
  volume =       23,
213
  pages =        {309-311}
214
}
215

	
216
@article{dasdan98minmeancycle,
217
  author =       {Ali Dasdan and Rajesh K. Gupta},
218
  title =        {Faster Maximum and Minimum Mean Cycle Alogrithms for
219
                  System Performance Analysis},
220
  journal =      {IEEE Transactions on Computer-Aided Design of
221
                  Integrated Circuits and Systems},
222
  year =         1998,
223
  volume =       17,
224
  number =       10,
225
  pages =        {889-899}
226
}
227

	
228

	
229
%%%%% Minimum cost flow algorithms %%%%%
230

	
231
@article{klein67primal,
232
  author =       {Morton Klein},
233
  title =        {A primal method for minimal cost flows with
234
                  applications to the assignment and transportation
235
                  problems},
236
  journal =      {Management Science},
237
  year =         1967,
238
  volume =       14,
239
  pages =        {205-220}
240
}
241

	
242
@article{goldberg89cyclecanceling,
243
  author =       {Andrew V. Goldberg and Robert E. Tarjan},
244
  title =        {Finding minimum-cost circulations by canceling
245
                  negative cycles},
246
  journal =      {Journal of the ACM},
247
  year =         1989,
248
  volume =       36,
249
  number =       4,
250
  pages =        {873-886}
251
}
252

	
253
@article{goldberg90approximation,
254
  author =       {Andrew V. Goldberg and Robert E. Tarjan},
255
  title =        {Finding Minimum-Cost Circulations by Successive
256
                  Approximation},
257
  journal =      {Mathematics of Operations Research},
258
  year =         1990,
259
  volume =       15,
260
  number =       3,
261
  pages =        {430-466}
262
}
263

	
264
@article{goldberg97efficient,
265
  author =       {Andrew V. Goldberg},
266
  title =        {An Efficient Implementation of a Scaling
267
                  Minimum-Cost Flow Algorithm},
268
  journal =      {Journal of Algorithms},
269
  year =         1997,
270
  volume =       22,
271
  number =       1,
272
  pages =        {1-29}
273
}
274

	
275
@article{bunnagel98efficient,
276
  author =       {Ursula B{\"u}nnagel and Bernhard Korte and Jens
277
                  Vygen},
278
  title =        {Efficient implementation of the {G}oldberg-{T}arjan
279
                  minimum-cost flow algorithm},
280
  journal =      {Optimization Methods and Software},
281
  year =         1998,
282
  volume =       10,
283
  pages =        {157-174}
284
}
285

	
286
@book{dantzig63linearprog,
287
  author =       {George B. Dantzig},
288
  title =        {Linear Programming and Extensions},
289
  publisher =    {Princeton University Press},
290
  year =         1963
291
}
292

	
293
@mastersthesis{kellyoneill91netsimplex,
294
  author =       {Damian J. Kelly and Garrett M. O'Neill},
295
  title =        {The Minimum Cost Flow Problem and The Network
296
                  Simplex Method},
297
  school =       {University College},
298
  address =      {Dublin, Ireland},
299
  year =         1991,
300
  month =        sep,
301
}
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
#ifndef LEMON_HARTMANN_ORLIN_H
20
#define LEMON_HARTMANN_ORLIN_H
21

	
22
/// \ingroup min_mean_cycle
23
///
24
/// \file
25
/// \brief Hartmann-Orlin's algorithm for finding a minimum mean cycle.
26

	
27
#include <vector>
28
#include <limits>
29
#include <lemon/core.h>
30
#include <lemon/path.h>
31
#include <lemon/tolerance.h>
32
#include <lemon/connectivity.h>
33

	
34
namespace lemon {
35

	
36
  /// \brief Default traits class of HartmannOrlin algorithm.
37
  ///
38
  /// Default traits class of HartmannOrlin algorithm.
39
  /// \tparam GR The type of the digraph.
40
  /// \tparam LEN The type of the length map.
41
  /// It must conform to the \ref concepts::Rea_data "Rea_data" concept.
42
#ifdef DOXYGEN
43
  template <typename GR, typename LEN>
44
#else
45
  template <typename GR, typename LEN,
46
    bool integer = std::numeric_limits<typename LEN::Value>::is_integer>
47
#endif
48
  struct HartmannOrlinDefaultTraits
49
  {
50
    /// The type of the digraph
51
    typedef GR Digraph;
52
    /// The type of the length map
53
    typedef LEN LengthMap;
54
    /// The type of the arc lengths
55
    typedef typename LengthMap::Value Value;
56

	
57
    /// \brief The large value type used for internal computations
58
    ///
59
    /// The large value type used for internal computations.
60
    /// It is \c long \c long if the \c Value type is integer,
61
    /// otherwise it is \c double.
62
    /// \c Value must be convertible to \c LargeValue.
63
    typedef double LargeValue;
64

	
65
    /// The tolerance type used for internal computations
66
    typedef lemon::Tolerance<LargeValue> Tolerance;
67

	
68
    /// \brief The path type of the found cycles
69
    ///
70
    /// The path type of the found cycles.
71
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
72
    /// and it must have an \c addFront() function.
73
    typedef lemon::Path<Digraph> Path;
74
  };
75

	
76
  // Default traits class for integer value types
77
  template <typename GR, typename LEN>
78
  struct HartmannOrlinDefaultTraits<GR, LEN, true>
79
  {
80
    typedef GR Digraph;
81
    typedef LEN LengthMap;
82
    typedef typename LengthMap::Value Value;
83
#ifdef LEMON_HAVE_LONG_LONG
84
    typedef long long LargeValue;
85
#else
86
    typedef long LargeValue;
87
#endif
88
    typedef lemon::Tolerance<LargeValue> Tolerance;
89
    typedef lemon::Path<Digraph> Path;
90
  };
91

	
92

	
93
  /// \addtogroup min_mean_cycle
94
  /// @{
95

	
96
  /// \brief Implementation of the Hartmann-Orlin algorithm for finding
97
  /// a minimum mean cycle.
98
  ///
99
  /// This class implements the Hartmann-Orlin algorithm for finding
100
  /// a directed cycle of minimum mean length (cost) in a digraph
101
  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
102
  /// It is an improved version of \ref Karp "Karp"'s original algorithm,
103
  /// it applies an efficient early termination scheme.
104
  /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
105
  ///
106
  /// \tparam GR The type of the digraph the algorithm runs on.
107
  /// \tparam LEN The type of the length map. The default
108
  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
109
#ifdef DOXYGEN
110
  template <typename GR, typename LEN, typename TR>
111
#else
112
  template < typename GR,
113
             typename LEN = typename GR::template ArcMap<int>,
114
             typename TR = HartmannOrlinDefaultTraits<GR, LEN> >
115
#endif
116
  class HartmannOrlin
117
  {
118
  public:
119

	
120
    /// The type of the digraph
121
    typedef typename TR::Digraph Digraph;
122
    /// The type of the length map
123
    typedef typename TR::LengthMap LengthMap;
124
    /// The type of the arc lengths
125
    typedef typename TR::Value Value;
126

	
127
    /// \brief The large value type
128
    ///
129
    /// The large value type used for internal computations.
130
    /// Using the \ref HartmannOrlinDefaultTraits "default traits class",
131
    /// it is \c long \c long if the \c Value type is integer,
132
    /// otherwise it is \c double.
133
    typedef typename TR::LargeValue LargeValue;
134

	
135
    /// The tolerance type
136
    typedef typename TR::Tolerance Tolerance;
137

	
138
    /// \brief The path type of the found cycles
139
    ///
140
    /// The path type of the found cycles.
141
    /// Using the \ref HartmannOrlinDefaultTraits "default traits class",
142
    /// it is \ref lemon::Path "Path<Digraph>".
143
    typedef typename TR::Path Path;
144

	
145
    /// The \ref HartmannOrlinDefaultTraits "traits class" of the algorithm
146
    typedef TR Traits;
147

	
148
  private:
149

	
150
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
151

	
152
    // Data sturcture for path data
153
    struct PathData
154
    {
155
      LargeValue dist;
156
      Arc pred;
157
      PathData(LargeValue d, Arc p = INVALID) :
158
        dist(d), pred(p) {}
159
    };
160

	
161
    typedef typename Digraph::template NodeMap<std::vector<PathData> >
162
      PathDataNodeMap;
163

	
164
  private:
165

	
166
    // The digraph the algorithm runs on
167
    const Digraph &_gr;
168
    // The length of the arcs
169
    const LengthMap &_length;
170

	
171
    // Data for storing the strongly connected components
172
    int _comp_num;
173
    typename Digraph::template NodeMap<int> _comp;
174
    std::vector<std::vector<Node> > _comp_nodes;
175
    std::vector<Node>* _nodes;
176
    typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
177

	
178
    // Data for the found cycles
179
    bool _curr_found, _best_found;
180
    LargeValue _curr_length, _best_length;
181
    int _curr_size, _best_size;
182
    Node _curr_node, _best_node;
183
    int _curr_level, _best_level;
184

	
185
    Path *_cycle_path;
186
    bool _local_path;
187

	
188
    // Node map for storing path data
189
    PathDataNodeMap _data;
190
    // The processed nodes in the last round
191
    std::vector<Node> _process;
192

	
193
    Tolerance _tolerance;
194

	
195
    // Infinite constant
196
    const LargeValue INF;
197

	
198
  public:
199

	
200
    /// \name Named Template Parameters
201
    /// @{
202

	
203
    template <typename T>
204
    struct SetLargeValueTraits : public Traits {
205
      typedef T LargeValue;
206
      typedef lemon::Tolerance<T> Tolerance;
207
    };
208

	
209
    /// \brief \ref named-templ-param "Named parameter" for setting
210
    /// \c LargeValue type.
211
    ///
212
    /// \ref named-templ-param "Named parameter" for setting \c LargeValue
213
    /// type. It is used for internal computations in the algorithm.
214
    template <typename T>
215
    struct SetLargeValue
216
      : public HartmannOrlin<GR, LEN, SetLargeValueTraits<T> > {
217
      typedef HartmannOrlin<GR, LEN, SetLargeValueTraits<T> > Create;
218
    };
219

	
220
    template <typename T>
221
    struct SetPathTraits : public Traits {
222
      typedef T Path;
223
    };
224

	
225
    /// \brief \ref named-templ-param "Named parameter" for setting
226
    /// \c %Path type.
227
    ///
228
    /// \ref named-templ-param "Named parameter" for setting the \c %Path
229
    /// type of the found cycles.
230
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
231
    /// and it must have an \c addFront() function.
232
    template <typename T>
233
    struct SetPath
234
      : public HartmannOrlin<GR, LEN, SetPathTraits<T> > {
235
      typedef HartmannOrlin<GR, LEN, SetPathTraits<T> > Create;
236
    };
237

	
238
    /// @}
239

	
240
  public:
241

	
242
    /// \brief Constructor.
243
    ///
244
    /// The constructor of the class.
245
    ///
246
    /// \param digraph The digraph the algorithm runs on.
247
    /// \param length The lengths (costs) of the arcs.
248
    HartmannOrlin( const Digraph &digraph,
249
                   const LengthMap &length ) :
250
      _gr(digraph), _length(length), _comp(digraph), _out_arcs(digraph),
251
      _best_found(false), _best_length(0), _best_size(1),
252
      _cycle_path(NULL), _local_path(false), _data(digraph),
253
      INF(std::numeric_limits<LargeValue>::has_infinity ?
254
          std::numeric_limits<LargeValue>::infinity() :
255
          std::numeric_limits<LargeValue>::max())
256
    {}
257

	
258
    /// Destructor.
259
    ~HartmannOrlin() {
260
      if (_local_path) delete _cycle_path;
261
    }
262

	
263
    /// \brief Set the path structure for storing the found cycle.
264
    ///
265
    /// This function sets an external path structure for storing the
266
    /// found cycle.
267
    ///
268
    /// If you don't call this function before calling \ref run() or
269
    /// \ref findMinMean(), it will allocate a local \ref Path "path"
270
    /// structure. The destuctor deallocates this automatically
271
    /// allocated object, of course.
272
    ///
273
    /// \note The algorithm calls only the \ref lemon::Path::addFront()
274
    /// "addFront()" function of the given path structure.
275
    ///
276
    /// \return <tt>(*this)</tt>
277
    HartmannOrlin& cycle(Path &path) {
278
      if (_local_path) {
279
        delete _cycle_path;
280
        _local_path = false;
281
      }
282
      _cycle_path = &path;
283
      return *this;
284
    }
285

	
286
    /// \brief Set the tolerance used by the algorithm.
287
    ///
288
    /// This function sets the tolerance object used by the algorithm.
289
    ///
290
    /// \return <tt>(*this)</tt>
291
    HartmannOrlin& tolerance(const Tolerance& tolerance) {
292
      _tolerance = tolerance;
293
      return *this;
294
    }
295

	
296
    /// \brief Return a const reference to the tolerance.
297
    ///
298
    /// This function returns a const reference to the tolerance object
299
    /// used by the algorithm.
300
    const Tolerance& tolerance() const {
301
      return _tolerance;
302
    }
303

	
304
    /// \name Execution control
305
    /// The simplest way to execute the algorithm is to call the \ref run()
306
    /// function.\n
307
    /// If you only need the minimum mean length, you may call
308
    /// \ref findMinMean().
309

	
310
    /// @{
311

	
312
    /// \brief Run the algorithm.
313
    ///
314
    /// This function runs the algorithm.
315
    /// It can be called more than once (e.g. if the underlying digraph
316
    /// and/or the arc lengths have been modified).
317
    ///
318
    /// \return \c true if a directed cycle exists in the digraph.
319
    ///
320
    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
321
    /// \code
322
    ///   return mmc.findMinMean() && mmc.findCycle();
323
    /// \endcode
324
    bool run() {
325
      return findMinMean() && findCycle();
326
    }
327

	
328
    /// \brief Find the minimum cycle mean.
329
    ///
330
    /// This function finds the minimum mean length of the directed
331
    /// cycles in the digraph.
332
    ///
333
    /// \return \c true if a directed cycle exists in the digraph.
334
    bool findMinMean() {
335
      // Initialization and find strongly connected components
336
      init();
337
      findComponents();
338
      
339
      // Find the minimum cycle mean in the components
340
      for (int comp = 0; comp < _comp_num; ++comp) {
341
        if (!initComponent(comp)) continue;
342
        processRounds();
343
        
344
        // Update the best cycle (global minimum mean cycle)
345
        if ( _curr_found && (!_best_found || 
346
             _curr_length * _best_size < _best_length * _curr_size) ) {
347
          _best_found = true;
348
          _best_length = _curr_length;
349
          _best_size = _curr_size;
350
          _best_node = _curr_node;
351
          _best_level = _curr_level;
352
        }
353
      }
354
      return _best_found;
355
    }
356

	
357
    /// \brief Find a minimum mean directed cycle.
358
    ///
359
    /// This function finds a directed cycle of minimum mean length
360
    /// in the digraph using the data computed by findMinMean().
361
    ///
362
    /// \return \c true if a directed cycle exists in the digraph.
363
    ///
364
    /// \pre \ref findMinMean() must be called before using this function.
365
    bool findCycle() {
366
      if (!_best_found) return false;
367
      IntNodeMap reached(_gr, -1);
368
      int r = _best_level + 1;
369
      Node u = _best_node;
370
      while (reached[u] < 0) {
371
        reached[u] = --r;
372
        u = _gr.source(_data[u][r].pred);
373
      }
374
      r = reached[u];
375
      Arc e = _data[u][r].pred;
376
      _cycle_path->addFront(e);
377
      _best_length = _length[e];
378
      _best_size = 1;
379
      Node v;
380
      while ((v = _gr.source(e)) != u) {
381
        e = _data[v][--r].pred;
382
        _cycle_path->addFront(e);
383
        _best_length += _length[e];
384
        ++_best_size;
385
      }
386
      return true;
387
    }
388

	
389
    /// @}
390

	
391
    /// \name Query Functions
392
    /// The results of the algorithm can be obtained using these
393
    /// functions.\n
394
    /// The algorithm should be executed before using them.
395

	
396
    /// @{
397

	
398
    /// \brief Return the total length of the found cycle.
399
    ///
400
    /// This function returns the total length of the found cycle.
401
    ///
402
    /// \pre \ref run() or \ref findMinMean() must be called before
403
    /// using this function.
404
    LargeValue cycleLength() const {
405
      return _best_length;
406
    }
407

	
408
    /// \brief Return the number of arcs on the found cycle.
409
    ///
410
    /// This function returns the number of arcs on the found cycle.
411
    ///
412
    /// \pre \ref run() or \ref findMinMean() must be called before
413
    /// using this function.
414
    int cycleArcNum() const {
415
      return _best_size;
416
    }
417

	
418
    /// \brief Return the mean length of the found cycle.
419
    ///
420
    /// This function returns the mean length of the found cycle.
421
    ///
422
    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
423
    /// following code.
424
    /// \code
425
    ///   return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
426
    /// \endcode
427
    ///
428
    /// \pre \ref run() or \ref findMinMean() must be called before
429
    /// using this function.
430
    double cycleMean() const {
431
      return static_cast<double>(_best_length) / _best_size;
432
    }
433

	
434
    /// \brief Return the found cycle.
435
    ///
436
    /// This function returns a const reference to the path structure
437
    /// storing the found cycle.
438
    ///
439
    /// \pre \ref run() or \ref findCycle() must be called before using
440
    /// this function.
441
    const Path& cycle() const {
442
      return *_cycle_path;
443
    }
444

	
445
    ///@}
446

	
447
  private:
448

	
449
    // Initialization
450
    void init() {
451
      if (!_cycle_path) {
452
        _local_path = true;
453
        _cycle_path = new Path;
454
      }
455
      _cycle_path->clear();
456
      _best_found = false;
457
      _best_length = 0;
458
      _best_size = 1;
459
      _cycle_path->clear();
460
      for (NodeIt u(_gr); u != INVALID; ++u)
461
        _data[u].clear();
462
    }
463

	
464
    // Find strongly connected components and initialize _comp_nodes
465
    // and _out_arcs
466
    void findComponents() {
467
      _comp_num = stronglyConnectedComponents(_gr, _comp);
468
      _comp_nodes.resize(_comp_num);
469
      if (_comp_num == 1) {
470
        _comp_nodes[0].clear();
471
        for (NodeIt n(_gr); n != INVALID; ++n) {
472
          _comp_nodes[0].push_back(n);
473
          _out_arcs[n].clear();
474
          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
475
            _out_arcs[n].push_back(a);
476
          }
477
        }
478
      } else {
479
        for (int i = 0; i < _comp_num; ++i)
480
          _comp_nodes[i].clear();
481
        for (NodeIt n(_gr); n != INVALID; ++n) {
482
          int k = _comp[n];
483
          _comp_nodes[k].push_back(n);
484
          _out_arcs[n].clear();
485
          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
486
            if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
487
          }
488
        }
489
      }
490
    }
491

	
492
    // Initialize path data for the current component
493
    bool initComponent(int comp) {
494
      _nodes = &(_comp_nodes[comp]);
495
      int n = _nodes->size();
496
      if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
497
        return false;
498
      }      
499
      for (int i = 0; i < n; ++i) {
500
        _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
501
      }
502
      return true;
503
    }
504

	
505
    // Process all rounds of computing path data for the current component.
506
    // _data[v][k] is the length of a shortest directed walk from the root
507
    // node to node v containing exactly k arcs.
508
    void processRounds() {
509
      Node start = (*_nodes)[0];
510
      _data[start][0] = PathData(0);
511
      _process.clear();
512
      _process.push_back(start);
513

	
514
      int k, n = _nodes->size();
515
      int next_check = 4;
516
      bool terminate = false;
517
      for (k = 1; k <= n && int(_process.size()) < n && !terminate; ++k) {
518
        processNextBuildRound(k);
519
        if (k == next_check || k == n) {
520
          terminate = checkTermination(k);
521
          next_check = next_check * 3 / 2;
522
        }
523
      }
524
      for ( ; k <= n && !terminate; ++k) {
525
        processNextFullRound(k);
526
        if (k == next_check || k == n) {
527
          terminate = checkTermination(k);
528
          next_check = next_check * 3 / 2;
529
        }
530
      }
531
    }
532

	
533
    // Process one round and rebuild _process
534
    void processNextBuildRound(int k) {
535
      std::vector<Node> next;
536
      Node u, v;
537
      Arc e;
538
      LargeValue d;
539
      for (int i = 0; i < int(_process.size()); ++i) {
540
        u = _process[i];
541
        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
542
          e = _out_arcs[u][j];
543
          v = _gr.target(e);
544
          d = _data[u][k-1].dist + _length[e];
545
          if (_tolerance.less(d, _data[v][k].dist)) {
546
            if (_data[v][k].dist == INF) next.push_back(v);
547
            _data[v][k] = PathData(d, e);
548
          }
549
        }
550
      }
551
      _process.swap(next);
552
    }
553

	
554
    // Process one round using _nodes instead of _process
555
    void processNextFullRound(int k) {
556
      Node u, v;
557
      Arc e;
558
      LargeValue d;
559
      for (int i = 0; i < int(_nodes->size()); ++i) {
560
        u = (*_nodes)[i];
561
        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
562
          e = _out_arcs[u][j];
563
          v = _gr.target(e);
564
          d = _data[u][k-1].dist + _length[e];
565
          if (_tolerance.less(d, _data[v][k].dist)) {
566
            _data[v][k] = PathData(d, e);
567
          }
568
        }
569
      }
570
    }
571
    
572
    // Check early termination
573
    bool checkTermination(int k) {
574
      typedef std::pair<int, int> Pair;
575
      typename GR::template NodeMap<Pair> level(_gr, Pair(-1, 0));
576
      typename GR::template NodeMap<LargeValue> pi(_gr);
577
      int n = _nodes->size();
578
      LargeValue length;
579
      int size;
580
      Node u;
581
      
582
      // Search for cycles that are already found
583
      _curr_found = false;
584
      for (int i = 0; i < n; ++i) {
585
        u = (*_nodes)[i];
586
        if (_data[u][k].dist == INF) continue;
587
        for (int j = k; j >= 0; --j) {
588
          if (level[u].first == i && level[u].second > 0) {
589
            // A cycle is found
590
            length = _data[u][level[u].second].dist - _data[u][j].dist;
591
            size = level[u].second - j;
592
            if (!_curr_found || length * _curr_size < _curr_length * size) {
593
              _curr_length = length;
594
              _curr_size = size;
595
              _curr_node = u;
596
              _curr_level = level[u].second;
597
              _curr_found = true;
598
            }
599
          }
600
          level[u] = Pair(i, j);
601
          u = _gr.source(_data[u][j].pred);
602
        }
603
      }
604

	
605
      // If at least one cycle is found, check the optimality condition
606
      LargeValue d;
607
      if (_curr_found && k < n) {
608
        // Find node potentials
609
        for (int i = 0; i < n; ++i) {
610
          u = (*_nodes)[i];
611
          pi[u] = INF;
612
          for (int j = 0; j <= k; ++j) {
613
            if (_data[u][j].dist < INF) {
614
              d = _data[u][j].dist * _curr_size - j * _curr_length;
615
              if (_tolerance.less(d, pi[u])) pi[u] = d;
616
            }
617
          }
618
        }
619

	
620
        // Check the optimality condition for all arcs
621
        bool done = true;
622
        for (ArcIt a(_gr); a != INVALID; ++a) {
623
          if (_tolerance.less(_length[a] * _curr_size - _curr_length,
624
                              pi[_gr.target(a)] - pi[_gr.source(a)]) ) {
625
            done = false;
626
            break;
627
          }
628
        }
629
        return done;
630
      }
631
      return (k == n);
632
    }
633

	
634
  }; //class HartmannOrlin
635

	
636
  ///@}
637

	
638
} //namespace lemon
639

	
640
#endif //LEMON_HARTMANN_ORLIN_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
#ifndef LEMON_HOWARD_H
20
#define LEMON_HOWARD_H
21

	
22
/// \ingroup min_mean_cycle
23
///
24
/// \file
25
/// \brief Howard's algorithm for finding a minimum mean cycle.
26

	
27
#include <vector>
28
#include <limits>
29
#include <lemon/core.h>
30
#include <lemon/path.h>
31
#include <lemon/tolerance.h>
32
#include <lemon/connectivity.h>
33

	
34
namespace lemon {
35

	
36
  /// \brief Default traits class of Howard class.
37
  ///
38
  /// Default traits class of Howard class.
39
  /// \tparam GR The type of the digraph.
40
  /// \tparam LEN The type of the length map.
41
  /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
42
#ifdef DOXYGEN
43
  template <typename GR, typename LEN>
44
#else
45
  template <typename GR, typename LEN,
46
    bool integer = std::numeric_limits<typename LEN::Value>::is_integer>
47
#endif
48
  struct HowardDefaultTraits
49
  {
50
    /// The type of the digraph
51
    typedef GR Digraph;
52
    /// The type of the length map
53
    typedef LEN LengthMap;
54
    /// The type of the arc lengths
55
    typedef typename LengthMap::Value Value;
56

	
57
    /// \brief The large value type used for internal computations
58
    ///
59
    /// The large value type used for internal computations.
60
    /// It is \c long \c long if the \c Value type is integer,
61
    /// otherwise it is \c double.
62
    /// \c Value must be convertible to \c LargeValue.
63
    typedef double LargeValue;
64

	
65
    /// The tolerance type used for internal computations
66
    typedef lemon::Tolerance<LargeValue> Tolerance;
67

	
68
    /// \brief The path type of the found cycles
69
    ///
70
    /// The path type of the found cycles.
71
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
72
    /// and it must have an \c addBack() function.
73
    typedef lemon::Path<Digraph> Path;
74
  };
75

	
76
  // Default traits class for integer value types
77
  template <typename GR, typename LEN>
78
  struct HowardDefaultTraits<GR, LEN, true>
79
  {
80
    typedef GR Digraph;
81
    typedef LEN LengthMap;
82
    typedef typename LengthMap::Value Value;
83
#ifdef LEMON_HAVE_LONG_LONG
84
    typedef long long LargeValue;
85
#else
86
    typedef long LargeValue;
87
#endif
88
    typedef lemon::Tolerance<LargeValue> Tolerance;
89
    typedef lemon::Path<Digraph> Path;
90
  };
91

	
92

	
93
  /// \addtogroup min_mean_cycle
94
  /// @{
95

	
96
  /// \brief Implementation of Howard's algorithm for finding a minimum
97
  /// mean cycle.
98
  ///
99
  /// This class implements Howard's policy iteration algorithm for finding
100
  /// a directed cycle of minimum mean length (cost) in a digraph
101
  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
102
  /// This class provides the most efficient algorithm for the
103
  /// minimum mean cycle problem, though the best known theoretical
104
  /// bound on its running time is exponential.
105
  ///
106
  /// \tparam GR The type of the digraph the algorithm runs on.
107
  /// \tparam LEN The type of the length map. The default
108
  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
109
#ifdef DOXYGEN
110
  template <typename GR, typename LEN, typename TR>
111
#else
112
  template < typename GR,
113
             typename LEN = typename GR::template ArcMap<int>,
114
             typename TR = HowardDefaultTraits<GR, LEN> >
115
#endif
116
  class Howard
117
  {
118
  public:
119
  
120
    /// The type of the digraph
121
    typedef typename TR::Digraph Digraph;
122
    /// The type of the length map
123
    typedef typename TR::LengthMap LengthMap;
124
    /// The type of the arc lengths
125
    typedef typename TR::Value Value;
126

	
127
    /// \brief The large value type
128
    ///
129
    /// The large value type used for internal computations.
130
    /// Using the \ref HowardDefaultTraits "default traits class",
131
    /// it is \c long \c long if the \c Value type is integer,
132
    /// otherwise it is \c double.
133
    typedef typename TR::LargeValue LargeValue;
134

	
135
    /// The tolerance type
136
    typedef typename TR::Tolerance Tolerance;
137

	
138
    /// \brief The path type of the found cycles
139
    ///
140
    /// The path type of the found cycles.
141
    /// Using the \ref HowardDefaultTraits "default traits class",
142
    /// it is \ref lemon::Path "Path<Digraph>".
143
    typedef typename TR::Path Path;
144

	
145
    /// The \ref HowardDefaultTraits "traits class" of the algorithm
146
    typedef TR Traits;
147

	
148
  private:
149

	
150
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
151
  
152
    // The digraph the algorithm runs on
153
    const Digraph &_gr;
154
    // The length of the arcs
155
    const LengthMap &_length;
156

	
157
    // Data for the found cycles
158
    bool _curr_found, _best_found;
159
    LargeValue _curr_length, _best_length;
160
    int _curr_size, _best_size;
161
    Node _curr_node, _best_node;
162

	
163
    Path *_cycle_path;
164
    bool _local_path;
165

	
166
    // Internal data used by the algorithm
167
    typename Digraph::template NodeMap<Arc> _policy;
168
    typename Digraph::template NodeMap<bool> _reached;
169
    typename Digraph::template NodeMap<int> _level;
170
    typename Digraph::template NodeMap<LargeValue> _dist;
171

	
172
    // Data for storing the strongly connected components
173
    int _comp_num;
174
    typename Digraph::template NodeMap<int> _comp;
175
    std::vector<std::vector<Node> > _comp_nodes;
176
    std::vector<Node>* _nodes;
177
    typename Digraph::template NodeMap<std::vector<Arc> > _in_arcs;
178
    
179
    // Queue used for BFS search
180
    std::vector<Node> _queue;
181
    int _qfront, _qback;
182

	
183
    Tolerance _tolerance;
184
  
185
    // Infinite constant
186
    const LargeValue INF;
187

	
188
  public:
189
  
190
    /// \name Named Template Parameters
191
    /// @{
192

	
193
    template <typename T>
194
    struct SetLargeValueTraits : public Traits {
195
      typedef T LargeValue;
196
      typedef lemon::Tolerance<T> Tolerance;
197
    };
198

	
199
    /// \brief \ref named-templ-param "Named parameter" for setting
200
    /// \c LargeValue type.
201
    ///
202
    /// \ref named-templ-param "Named parameter" for setting \c LargeValue
203
    /// type. It is used for internal computations in the algorithm.
204
    template <typename T>
205
    struct SetLargeValue
206
      : public Howard<GR, LEN, SetLargeValueTraits<T> > {
207
      typedef Howard<GR, LEN, SetLargeValueTraits<T> > Create;
208
    };
209

	
210
    template <typename T>
211
    struct SetPathTraits : public Traits {
212
      typedef T Path;
213
    };
214

	
215
    /// \brief \ref named-templ-param "Named parameter" for setting
216
    /// \c %Path type.
217
    ///
218
    /// \ref named-templ-param "Named parameter" for setting the \c %Path
219
    /// type of the found cycles.
220
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
221
    /// and it must have an \c addBack() function.
222
    template <typename T>
223
    struct SetPath
224
      : public Howard<GR, LEN, SetPathTraits<T> > {
225
      typedef Howard<GR, LEN, SetPathTraits<T> > Create;
226
    };
227
    
228
    /// @}
229

	
230
  public:
231

	
232
    /// \brief Constructor.
233
    ///
234
    /// The constructor of the class.
235
    ///
236
    /// \param digraph The digraph the algorithm runs on.
237
    /// \param length The lengths (costs) of the arcs.
238
    Howard( const Digraph &digraph,
239
            const LengthMap &length ) :
240
      _gr(digraph), _length(length), _best_found(false),
241
      _best_length(0), _best_size(1), _cycle_path(NULL), _local_path(false),
242
      _policy(digraph), _reached(digraph), _level(digraph), _dist(digraph),
243
      _comp(digraph), _in_arcs(digraph),
244
      INF(std::numeric_limits<LargeValue>::has_infinity ?
245
          std::numeric_limits<LargeValue>::infinity() :
246
          std::numeric_limits<LargeValue>::max())
247
    {}
248

	
249
    /// Destructor.
250
    ~Howard() {
251
      if (_local_path) delete _cycle_path;
252
    }
253

	
254
    /// \brief Set the path structure for storing the found cycle.
255
    ///
256
    /// This function sets an external path structure for storing the
257
    /// found cycle.
258
    ///
259
    /// If you don't call this function before calling \ref run() or
260
    /// \ref findMinMean(), it will allocate a local \ref Path "path"
261
    /// structure. The destuctor deallocates this automatically
262
    /// allocated object, of course.
263
    ///
264
    /// \note The algorithm calls only the \ref lemon::Path::addBack()
265
    /// "addBack()" function of the given path structure.
266
    ///
267
    /// \return <tt>(*this)</tt>
268
    Howard& cycle(Path &path) {
269
      if (_local_path) {
270
        delete _cycle_path;
271
        _local_path = false;
272
      }
273
      _cycle_path = &path;
274
      return *this;
275
    }
276

	
277
    /// \brief Set the tolerance used by the algorithm.
278
    ///
279
    /// This function sets the tolerance object used by the algorithm.
280
    ///
281
    /// \return <tt>(*this)</tt>
282
    Howard& tolerance(const Tolerance& tolerance) {
283
      _tolerance = tolerance;
284
      return *this;
285
    }
286

	
287
    /// \brief Return a const reference to the tolerance.
288
    ///
289
    /// This function returns a const reference to the tolerance object
290
    /// used by the algorithm.
291
    const Tolerance& tolerance() const {
292
      return _tolerance;
293
    }
294

	
295
    /// \name Execution control
296
    /// The simplest way to execute the algorithm is to call the \ref run()
297
    /// function.\n
298
    /// If you only need the minimum mean length, you may call
299
    /// \ref findMinMean().
300

	
301
    /// @{
302

	
303
    /// \brief Run the algorithm.
304
    ///
305
    /// This function runs the algorithm.
306
    /// It can be called more than once (e.g. if the underlying digraph
307
    /// and/or the arc lengths have been modified).
308
    ///
309
    /// \return \c true if a directed cycle exists in the digraph.
310
    ///
311
    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
312
    /// \code
313
    ///   return mmc.findMinMean() && mmc.findCycle();
314
    /// \endcode
315
    bool run() {
316
      return findMinMean() && findCycle();
317
    }
318

	
319
    /// \brief Find the minimum cycle mean.
320
    ///
321
    /// This function finds the minimum mean length of the directed
322
    /// cycles in the digraph.
323
    ///
324
    /// \return \c true if a directed cycle exists in the digraph.
325
    bool findMinMean() {
326
      // Initialize and find strongly connected components
327
      init();
328
      findComponents();
329
      
330
      // Find the minimum cycle mean in the components
331
      for (int comp = 0; comp < _comp_num; ++comp) {
332
        // Find the minimum mean cycle in the current component
333
        if (!buildPolicyGraph(comp)) continue;
334
        while (true) {
335
          findPolicyCycle();
336
          if (!computeNodeDistances()) break;
337
        }
338
        // Update the best cycle (global minimum mean cycle)
339
        if ( _curr_found && (!_best_found ||
340
             _curr_length * _best_size < _best_length * _curr_size) ) {
341
          _best_found = true;
342
          _best_length = _curr_length;
343
          _best_size = _curr_size;
344
          _best_node = _curr_node;
345
        }
346
      }
347
      return _best_found;
348
    }
349

	
350
    /// \brief Find a minimum mean directed cycle.
351
    ///
352
    /// This function finds a directed cycle of minimum mean length
353
    /// in the digraph using the data computed by findMinMean().
354
    ///
355
    /// \return \c true if a directed cycle exists in the digraph.
356
    ///
357
    /// \pre \ref findMinMean() must be called before using this function.
358
    bool findCycle() {
359
      if (!_best_found) return false;
360
      _cycle_path->addBack(_policy[_best_node]);
361
      for ( Node v = _best_node;
362
            (v = _gr.target(_policy[v])) != _best_node; ) {
363
        _cycle_path->addBack(_policy[v]);
364
      }
365
      return true;
366
    }
367

	
368
    /// @}
369

	
370
    /// \name Query Functions
371
    /// The results of the algorithm can be obtained using these
372
    /// functions.\n
373
    /// The algorithm should be executed before using them.
374

	
375
    /// @{
376

	
377
    /// \brief Return the total length of the found cycle.
378
    ///
379
    /// This function returns the total length of the found cycle.
380
    ///
381
    /// \pre \ref run() or \ref findMinMean() must be called before
382
    /// using this function.
383
    LargeValue cycleLength() const {
384
      return _best_length;
385
    }
386

	
387
    /// \brief Return the number of arcs on the found cycle.
388
    ///
389
    /// This function returns the number of arcs on the found cycle.
390
    ///
391
    /// \pre \ref run() or \ref findMinMean() must be called before
392
    /// using this function.
393
    int cycleArcNum() const {
394
      return _best_size;
395
    }
396

	
397
    /// \brief Return the mean length of the found cycle.
398
    ///
399
    /// This function returns the mean length of the found cycle.
400
    ///
401
    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
402
    /// following code.
403
    /// \code
404
    ///   return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
405
    /// \endcode
406
    ///
407
    /// \pre \ref run() or \ref findMinMean() must be called before
408
    /// using this function.
409
    double cycleMean() const {
410
      return static_cast<double>(_best_length) / _best_size;
411
    }
412

	
413
    /// \brief Return the found cycle.
414
    ///
415
    /// This function returns a const reference to the path structure
416
    /// storing the found cycle.
417
    ///
418
    /// \pre \ref run() or \ref findCycle() must be called before using
419
    /// this function.
420
    const Path& cycle() const {
421
      return *_cycle_path;
422
    }
423

	
424
    ///@}
425

	
426
  private:
427

	
428
    // Initialize
429
    void init() {
430
      if (!_cycle_path) {
431
        _local_path = true;
432
        _cycle_path = new Path;
433
      }
434
      _queue.resize(countNodes(_gr));
435
      _best_found = false;
436
      _best_length = 0;
437
      _best_size = 1;
438
      _cycle_path->clear();
439
    }
440
    
441
    // Find strongly connected components and initialize _comp_nodes
442
    // and _in_arcs
443
    void findComponents() {
444
      _comp_num = stronglyConnectedComponents(_gr, _comp);
445
      _comp_nodes.resize(_comp_num);
446
      if (_comp_num == 1) {
447
        _comp_nodes[0].clear();
448
        for (NodeIt n(_gr); n != INVALID; ++n) {
449
          _comp_nodes[0].push_back(n);
450
          _in_arcs[n].clear();
451
          for (InArcIt a(_gr, n); a != INVALID; ++a) {
452
            _in_arcs[n].push_back(a);
453
          }
454
        }
455
      } else {
456
        for (int i = 0; i < _comp_num; ++i)
457
          _comp_nodes[i].clear();
458
        for (NodeIt n(_gr); n != INVALID; ++n) {
459
          int k = _comp[n];
460
          _comp_nodes[k].push_back(n);
461
          _in_arcs[n].clear();
462
          for (InArcIt a(_gr, n); a != INVALID; ++a) {
463
            if (_comp[_gr.source(a)] == k) _in_arcs[n].push_back(a);
464
          }
465
        }
466
      }
467
    }
468

	
469
    // Build the policy graph in the given strongly connected component
470
    // (the out-degree of every node is 1)
471
    bool buildPolicyGraph(int comp) {
472
      _nodes = &(_comp_nodes[comp]);
473
      if (_nodes->size() < 1 ||
474
          (_nodes->size() == 1 && _in_arcs[(*_nodes)[0]].size() == 0)) {
475
        return false;
476
      }
477
      for (int i = 0; i < int(_nodes->size()); ++i) {
478
        _dist[(*_nodes)[i]] = INF;
479
      }
480
      Node u, v;
481
      Arc e;
482
      for (int i = 0; i < int(_nodes->size()); ++i) {
483
        v = (*_nodes)[i];
484
        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
485
          e = _in_arcs[v][j];
486
          u = _gr.source(e);
487
          if (_length[e] < _dist[u]) {
488
            _dist[u] = _length[e];
489
            _policy[u] = e;
490
          }
491
        }
492
      }
493
      return true;
494
    }
495

	
496
    // Find the minimum mean cycle in the policy graph
497
    void findPolicyCycle() {
498
      for (int i = 0; i < int(_nodes->size()); ++i) {
499
        _level[(*_nodes)[i]] = -1;
500
      }
501
      LargeValue clength;
502
      int csize;
503
      Node u, v;
504
      _curr_found = false;
505
      for (int i = 0; i < int(_nodes->size()); ++i) {
506
        u = (*_nodes)[i];
507
        if (_level[u] >= 0) continue;
508
        for (; _level[u] < 0; u = _gr.target(_policy[u])) {
509
          _level[u] = i;
510
        }
511
        if (_level[u] == i) {
512
          // A cycle is found
513
          clength = _length[_policy[u]];
514
          csize = 1;
515
          for (v = u; (v = _gr.target(_policy[v])) != u; ) {
516
            clength += _length[_policy[v]];
517
            ++csize;
518
          }
519
          if ( !_curr_found ||
520
               (clength * _curr_size < _curr_length * csize) ) {
521
            _curr_found = true;
522
            _curr_length = clength;
523
            _curr_size = csize;
524
            _curr_node = u;
525
          }
526
        }
527
      }
528
    }
529

	
530
    // Contract the policy graph and compute node distances
531
    bool computeNodeDistances() {
532
      // Find the component of the main cycle and compute node distances
533
      // using reverse BFS
534
      for (int i = 0; i < int(_nodes->size()); ++i) {
535
        _reached[(*_nodes)[i]] = false;
536
      }
537
      _qfront = _qback = 0;
538
      _queue[0] = _curr_node;
539
      _reached[_curr_node] = true;
540
      _dist[_curr_node] = 0;
541
      Node u, v;
542
      Arc e;
543
      while (_qfront <= _qback) {
544
        v = _queue[_qfront++];
545
        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
546
          e = _in_arcs[v][j];
547
          u = _gr.source(e);
548
          if (_policy[u] == e && !_reached[u]) {
549
            _reached[u] = true;
550
            _dist[u] = _dist[v] + _length[e] * _curr_size - _curr_length;
551
            _queue[++_qback] = u;
552
          }
553
        }
554
      }
555

	
556
      // Connect all other nodes to this component and compute node
557
      // distances using reverse BFS
558
      _qfront = 0;
559
      while (_qback < int(_nodes->size())-1) {
560
        v = _queue[_qfront++];
561
        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
562
          e = _in_arcs[v][j];
563
          u = _gr.source(e);
564
          if (!_reached[u]) {
565
            _reached[u] = true;
566
            _policy[u] = e;
567
            _dist[u] = _dist[v] + _length[e] * _curr_size - _curr_length;
568
            _queue[++_qback] = u;
569
          }
570
        }
571
      }
572

	
573
      // Improve node distances
574
      bool improved = false;
575
      for (int i = 0; i < int(_nodes->size()); ++i) {
576
        v = (*_nodes)[i];
577
        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
578
          e = _in_arcs[v][j];
579
          u = _gr.source(e);
580
          LargeValue delta = _dist[v] + _length[e] * _curr_size - _curr_length;
581
          if (_tolerance.less(delta, _dist[u])) {
582
            _dist[u] = delta;
583
            _policy[u] = e;
584
            improved = true;
585
          }
586
        }
587
      }
588
      return improved;
589
    }
590

	
591
  }; //class Howard
592

	
593
  ///@}
594

	
595
} //namespace lemon
596

	
597
#endif //LEMON_HOWARD_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
#ifndef LEMON_KARP_H
20
#define LEMON_KARP_H
21

	
22
/// \ingroup min_mean_cycle
23
///
24
/// \file
25
/// \brief Karp's algorithm for finding a minimum mean cycle.
26

	
27
#include <vector>
28
#include <limits>
29
#include <lemon/core.h>
30
#include <lemon/path.h>
31
#include <lemon/tolerance.h>
32
#include <lemon/connectivity.h>
33

	
34
namespace lemon {
35

	
36
  /// \brief Default traits class of Karp algorithm.
37
  ///
38
  /// Default traits class of Karp algorithm.
39
  /// \tparam GR The type of the digraph.
40
  /// \tparam LEN The type of the length map.
41
  /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
42
#ifdef DOXYGEN
43
  template <typename GR, typename LEN>
44
#else
45
  template <typename GR, typename LEN,
46
    bool integer = std::numeric_limits<typename LEN::Value>::is_integer>
47
#endif
48
  struct KarpDefaultTraits
49
  {
50
    /// The type of the digraph
51
    typedef GR Digraph;
52
    /// The type of the length map
53
    typedef LEN LengthMap;
54
    /// The type of the arc lengths
55
    typedef typename LengthMap::Value Value;
56

	
57
    /// \brief The large value type used for internal computations
58
    ///
59
    /// The large value type used for internal computations.
60
    /// It is \c long \c long if the \c Value type is integer,
61
    /// otherwise it is \c double.
62
    /// \c Value must be convertible to \c LargeValue.
63
    typedef double LargeValue;
64

	
65
    /// The tolerance type used for internal computations
66
    typedef lemon::Tolerance<LargeValue> Tolerance;
67

	
68
    /// \brief The path type of the found cycles
69
    ///
70
    /// The path type of the found cycles.
71
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
72
    /// and it must have an \c addFront() function.
73
    typedef lemon::Path<Digraph> Path;
74
  };
75

	
76
  // Default traits class for integer value types
77
  template <typename GR, typename LEN>
78
  struct KarpDefaultTraits<GR, LEN, true>
79
  {
80
    typedef GR Digraph;
81
    typedef LEN LengthMap;
82
    typedef typename LengthMap::Value Value;
83
#ifdef LEMON_HAVE_LONG_LONG
84
    typedef long long LargeValue;
85
#else
86
    typedef long LargeValue;
87
#endif
88
    typedef lemon::Tolerance<LargeValue> Tolerance;
89
    typedef lemon::Path<Digraph> Path;
90
  };
91

	
92

	
93
  /// \addtogroup min_mean_cycle
94
  /// @{
95

	
96
  /// \brief Implementation of Karp's algorithm for finding a minimum
97
  /// mean cycle.
98
  ///
99
  /// This class implements Karp's algorithm for finding a directed
100
  /// cycle of minimum mean length (cost) in a digraph
101
  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
102
  /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
103
  ///
104
  /// \tparam GR The type of the digraph the algorithm runs on.
105
  /// \tparam LEN The type of the length map. The default
106
  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
107
#ifdef DOXYGEN
108
  template <typename GR, typename LEN, typename TR>
109
#else
110
  template < typename GR,
111
             typename LEN = typename GR::template ArcMap<int>,
112
             typename TR = KarpDefaultTraits<GR, LEN> >
113
#endif
114
  class Karp
115
  {
116
  public:
117

	
118
    /// The type of the digraph
119
    typedef typename TR::Digraph Digraph;
120
    /// The type of the length map
121
    typedef typename TR::LengthMap LengthMap;
122
    /// The type of the arc lengths
123
    typedef typename TR::Value Value;
124

	
125
    /// \brief The large value type
126
    ///
127
    /// The large value type used for internal computations.
128
    /// Using the \ref KarpDefaultTraits "default traits class",
129
    /// it is \c long \c long if the \c Value type is integer,
130
    /// otherwise it is \c double.
131
    typedef typename TR::LargeValue LargeValue;
132

	
133
    /// The tolerance type
134
    typedef typename TR::Tolerance Tolerance;
135

	
136
    /// \brief The path type of the found cycles
137
    ///
138
    /// The path type of the found cycles.
139
    /// Using the \ref KarpDefaultTraits "default traits class",
140
    /// it is \ref lemon::Path "Path<Digraph>".
141
    typedef typename TR::Path Path;
142

	
143
    /// The \ref KarpDefaultTraits "traits class" of the algorithm
144
    typedef TR Traits;
145

	
146
  private:
147

	
148
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
149

	
150
    // Data sturcture for path data
151
    struct PathData
152
    {
153
      LargeValue dist;
154
      Arc pred;
155
      PathData(LargeValue d, Arc p = INVALID) :
156
        dist(d), pred(p) {}
157
    };
158

	
159
    typedef typename Digraph::template NodeMap<std::vector<PathData> >
160
      PathDataNodeMap;
161

	
162
  private:
163

	
164
    // The digraph the algorithm runs on
165
    const Digraph &_gr;
166
    // The length of the arcs
167
    const LengthMap &_length;
168

	
169
    // Data for storing the strongly connected components
170
    int _comp_num;
171
    typename Digraph::template NodeMap<int> _comp;
172
    std::vector<std::vector<Node> > _comp_nodes;
173
    std::vector<Node>* _nodes;
174
    typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
175

	
176
    // Data for the found cycle
177
    LargeValue _cycle_length;
178
    int _cycle_size;
179
    Node _cycle_node;
180

	
181
    Path *_cycle_path;
182
    bool _local_path;
183

	
184
    // Node map for storing path data
185
    PathDataNodeMap _data;
186
    // The processed nodes in the last round
187
    std::vector<Node> _process;
188

	
189
    Tolerance _tolerance;
190
    
191
    // Infinite constant
192
    const LargeValue INF;
193

	
194
  public:
195

	
196
    /// \name Named Template Parameters
197
    /// @{
198

	
199
    template <typename T>
200
    struct SetLargeValueTraits : public Traits {
201
      typedef T LargeValue;
202
      typedef lemon::Tolerance<T> Tolerance;
203
    };
204

	
205
    /// \brief \ref named-templ-param "Named parameter" for setting
206
    /// \c LargeValue type.
207
    ///
208
    /// \ref named-templ-param "Named parameter" for setting \c LargeValue
209
    /// type. It is used for internal computations in the algorithm.
210
    template <typename T>
211
    struct SetLargeValue
212
      : public Karp<GR, LEN, SetLargeValueTraits<T> > {
213
      typedef Karp<GR, LEN, SetLargeValueTraits<T> > Create;
214
    };
215

	
216
    template <typename T>
217
    struct SetPathTraits : public Traits {
218
      typedef T Path;
219
    };
220

	
221
    /// \brief \ref named-templ-param "Named parameter" for setting
222
    /// \c %Path type.
223
    ///
224
    /// \ref named-templ-param "Named parameter" for setting the \c %Path
225
    /// type of the found cycles.
226
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
227
    /// and it must have an \c addFront() function.
228
    template <typename T>
229
    struct SetPath
230
      : public Karp<GR, LEN, SetPathTraits<T> > {
231
      typedef Karp<GR, LEN, SetPathTraits<T> > Create;
232
    };
233

	
234
    /// @}
235

	
236
  public:
237

	
238
    /// \brief Constructor.
239
    ///
240
    /// The constructor of the class.
241
    ///
242
    /// \param digraph The digraph the algorithm runs on.
243
    /// \param length The lengths (costs) of the arcs.
244
    Karp( const Digraph &digraph,
245
          const LengthMap &length ) :
246
      _gr(digraph), _length(length), _comp(digraph), _out_arcs(digraph),
247
      _cycle_length(0), _cycle_size(1), _cycle_node(INVALID),
248
      _cycle_path(NULL), _local_path(false), _data(digraph),
249
      INF(std::numeric_limits<LargeValue>::has_infinity ?
250
          std::numeric_limits<LargeValue>::infinity() :
251
          std::numeric_limits<LargeValue>::max())
252
    {}
253

	
254
    /// Destructor.
255
    ~Karp() {
256
      if (_local_path) delete _cycle_path;
257
    }
258

	
259
    /// \brief Set the path structure for storing the found cycle.
260
    ///
261
    /// This function sets an external path structure for storing the
262
    /// found cycle.
263
    ///
264
    /// If you don't call this function before calling \ref run() or
265
    /// \ref findMinMean(), it will allocate a local \ref Path "path"
266
    /// structure. The destuctor deallocates this automatically
267
    /// allocated object, of course.
268
    ///
269
    /// \note The algorithm calls only the \ref lemon::Path::addFront()
270
    /// "addFront()" function of the given path structure.
271
    ///
272
    /// \return <tt>(*this)</tt>
273
    Karp& cycle(Path &path) {
274
      if (_local_path) {
275
        delete _cycle_path;
276
        _local_path = false;
277
      }
278
      _cycle_path = &path;
279
      return *this;
280
    }
281

	
282
    /// \brief Set the tolerance used by the algorithm.
283
    ///
284
    /// This function sets the tolerance object used by the algorithm.
285
    ///
286
    /// \return <tt>(*this)</tt>
287
    Karp& tolerance(const Tolerance& tolerance) {
288
      _tolerance = tolerance;
289
      return *this;
290
    }
291

	
292
    /// \brief Return a const reference to the tolerance.
293
    ///
294
    /// This function returns a const reference to the tolerance object
295
    /// used by the algorithm.
296
    const Tolerance& tolerance() const {
297
      return _tolerance;
298
    }
299

	
300
    /// \name Execution control
301
    /// The simplest way to execute the algorithm is to call the \ref run()
302
    /// function.\n
303
    /// If you only need the minimum mean length, you may call
304
    /// \ref findMinMean().
305

	
306
    /// @{
307

	
308
    /// \brief Run the algorithm.
309
    ///
310
    /// This function runs the algorithm.
311
    /// It can be called more than once (e.g. if the underlying digraph
312
    /// and/or the arc lengths have been modified).
313
    ///
314
    /// \return \c true if a directed cycle exists in the digraph.
315
    ///
316
    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
317
    /// \code
318
    ///   return mmc.findMinMean() && mmc.findCycle();
319
    /// \endcode
320
    bool run() {
321
      return findMinMean() && findCycle();
322
    }
323

	
324
    /// \brief Find the minimum cycle mean.
325
    ///
326
    /// This function finds the minimum mean length of the directed
327
    /// cycles in the digraph.
328
    ///
329
    /// \return \c true if a directed cycle exists in the digraph.
330
    bool findMinMean() {
331
      // Initialization and find strongly connected components
332
      init();
333
      findComponents();
334
      
335
      // Find the minimum cycle mean in the components
336
      for (int comp = 0; comp < _comp_num; ++comp) {
337
        if (!initComponent(comp)) continue;
338
        processRounds();
339
        updateMinMean();
340
      }
341
      return (_cycle_node != INVALID);
342
    }
343

	
344
    /// \brief Find a minimum mean directed cycle.
345
    ///
346
    /// This function finds a directed cycle of minimum mean length
347
    /// in the digraph using the data computed by findMinMean().
348
    ///
349
    /// \return \c true if a directed cycle exists in the digraph.
350
    ///
351
    /// \pre \ref findMinMean() must be called before using this function.
352
    bool findCycle() {
353
      if (_cycle_node == INVALID) return false;
354
      IntNodeMap reached(_gr, -1);
355
      int r = _data[_cycle_node].size();
356
      Node u = _cycle_node;
357
      while (reached[u] < 0) {
358
        reached[u] = --r;
359
        u = _gr.source(_data[u][r].pred);
360
      }
361
      r = reached[u];
362
      Arc e = _data[u][r].pred;
363
      _cycle_path->addFront(e);
364
      _cycle_length = _length[e];
365
      _cycle_size = 1;
366
      Node v;
367
      while ((v = _gr.source(e)) != u) {
368
        e = _data[v][--r].pred;
369
        _cycle_path->addFront(e);
370
        _cycle_length += _length[e];
371
        ++_cycle_size;
372
      }
373
      return true;
374
    }
375

	
376
    /// @}
377

	
378
    /// \name Query Functions
379
    /// The results of the algorithm can be obtained using these
380
    /// functions.\n
381
    /// The algorithm should be executed before using them.
382

	
383
    /// @{
384

	
385
    /// \brief Return the total length of the found cycle.
386
    ///
387
    /// This function returns the total length of the found cycle.
388
    ///
389
    /// \pre \ref run() or \ref findMinMean() must be called before
390
    /// using this function.
391
    LargeValue cycleLength() const {
392
      return _cycle_length;
393
    }
394

	
395
    /// \brief Return the number of arcs on the found cycle.
396
    ///
397
    /// This function returns the number of arcs on the found cycle.
398
    ///
399
    /// \pre \ref run() or \ref findMinMean() must be called before
400
    /// using this function.
401
    int cycleArcNum() const {
402
      return _cycle_size;
403
    }
404

	
405
    /// \brief Return the mean length of the found cycle.
406
    ///
407
    /// This function returns the mean length of the found cycle.
408
    ///
409
    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
410
    /// following code.
411
    /// \code
412
    ///   return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
413
    /// \endcode
414
    ///
415
    /// \pre \ref run() or \ref findMinMean() must be called before
416
    /// using this function.
417
    double cycleMean() const {
418
      return static_cast<double>(_cycle_length) / _cycle_size;
419
    }
420

	
421
    /// \brief Return the found cycle.
422
    ///
423
    /// This function returns a const reference to the path structure
424
    /// storing the found cycle.
425
    ///
426
    /// \pre \ref run() or \ref findCycle() must be called before using
427
    /// this function.
428
    const Path& cycle() const {
429
      return *_cycle_path;
430
    }
431

	
432
    ///@}
433

	
434
  private:
435

	
436
    // Initialization
437
    void init() {
438
      if (!_cycle_path) {
439
        _local_path = true;
440
        _cycle_path = new Path;
441
      }
442
      _cycle_path->clear();
443
      _cycle_length = 0;
444
      _cycle_size = 1;
445
      _cycle_node = INVALID;
446
      for (NodeIt u(_gr); u != INVALID; ++u)
447
        _data[u].clear();
448
    }
449

	
450
    // Find strongly connected components and initialize _comp_nodes
451
    // and _out_arcs
452
    void findComponents() {
453
      _comp_num = stronglyConnectedComponents(_gr, _comp);
454
      _comp_nodes.resize(_comp_num);
455
      if (_comp_num == 1) {
456
        _comp_nodes[0].clear();
457
        for (NodeIt n(_gr); n != INVALID; ++n) {
458
          _comp_nodes[0].push_back(n);
459
          _out_arcs[n].clear();
460
          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
461
            _out_arcs[n].push_back(a);
462
          }
463
        }
464
      } else {
465
        for (int i = 0; i < _comp_num; ++i)
466
          _comp_nodes[i].clear();
467
        for (NodeIt n(_gr); n != INVALID; ++n) {
468
          int k = _comp[n];
469
          _comp_nodes[k].push_back(n);
470
          _out_arcs[n].clear();
471
          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
472
            if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
473
          }
474
        }
475
      }
476
    }
477

	
478
    // Initialize path data for the current component
479
    bool initComponent(int comp) {
480
      _nodes = &(_comp_nodes[comp]);
481
      int n = _nodes->size();
482
      if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
483
        return false;
484
      }      
485
      for (int i = 0; i < n; ++i) {
486
        _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
487
      }
488
      return true;
489
    }
490

	
491
    // Process all rounds of computing path data for the current component.
492
    // _data[v][k] is the length of a shortest directed walk from the root
493
    // node to node v containing exactly k arcs.
494
    void processRounds() {
495
      Node start = (*_nodes)[0];
496
      _data[start][0] = PathData(0);
497
      _process.clear();
498
      _process.push_back(start);
499

	
500
      int k, n = _nodes->size();
501
      for (k = 1; k <= n && int(_process.size()) < n; ++k) {
502
        processNextBuildRound(k);
503
      }
504
      for ( ; k <= n; ++k) {
505
        processNextFullRound(k);
506
      }
507
    }
508

	
509
    // Process one round and rebuild _process
510
    void processNextBuildRound(int k) {
511
      std::vector<Node> next;
512
      Node u, v;
513
      Arc e;
514
      LargeValue d;
515
      for (int i = 0; i < int(_process.size()); ++i) {
516
        u = _process[i];
517
        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
518
          e = _out_arcs[u][j];
519
          v = _gr.target(e);
520
          d = _data[u][k-1].dist + _length[e];
521
          if (_tolerance.less(d, _data[v][k].dist)) {
522
            if (_data[v][k].dist == INF) next.push_back(v);
523
            _data[v][k] = PathData(d, e);
524
          }
525
        }
526
      }
527
      _process.swap(next);
528
    }
529

	
530
    // Process one round using _nodes instead of _process
531
    void processNextFullRound(int k) {
532
      Node u, v;
533
      Arc e;
534
      LargeValue d;
535
      for (int i = 0; i < int(_nodes->size()); ++i) {
536
        u = (*_nodes)[i];
537
        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
538
          e = _out_arcs[u][j];
539
          v = _gr.target(e);
540
          d = _data[u][k-1].dist + _length[e];
541
          if (_tolerance.less(d, _data[v][k].dist)) {
542
            _data[v][k] = PathData(d, e);
543
          }
544
        }
545
      }
546
    }
547

	
548
    // Update the minimum cycle mean
549
    void updateMinMean() {
550
      int n = _nodes->size();
551
      for (int i = 0; i < n; ++i) {
552
        Node u = (*_nodes)[i];
553
        if (_data[u][n].dist == INF) continue;
554
        LargeValue length, max_length = 0;
555
        int size, max_size = 1;
556
        bool found_curr = false;
557
        for (int k = 0; k < n; ++k) {
558
          if (_data[u][k].dist == INF) continue;
559
          length = _data[u][n].dist - _data[u][k].dist;
560
          size = n - k;
561
          if (!found_curr || length * max_size > max_length * size) {
562
            found_curr = true;
563
            max_length = length;
564
            max_size = size;
565
          }
566
        }
567
        if ( found_curr && (_cycle_node == INVALID ||
568
             max_length * _cycle_size < _cycle_length * max_size) ) {
569
          _cycle_length = max_length;
570
          _cycle_size = max_size;
571
          _cycle_node = u;
572
        }
573
      }
574
    }
575

	
576
  }; //class Karp
577

	
578
  ///@}
579

	
580
} //namespace lemon
581

	
582
#endif //LEMON_KARP_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
#ifndef LEMON_STATIC_GRAPH_H
20
#define LEMON_STATIC_GRAPH_H
21

	
22
///\ingroup graphs
23
///\file
24
///\brief StaticDigraph class.
25

	
26
#include <lemon/core.h>
27
#include <lemon/bits/graph_extender.h>
28

	
29
namespace lemon {
30

	
31
  class StaticDigraphBase {
32
  public:
33

	
34
    StaticDigraphBase() 
35
      : built(false), node_num(0), arc_num(0), 
36
        node_first_out(NULL), node_first_in(NULL),
37
        arc_source(NULL), arc_target(NULL), 
38
        arc_next_in(NULL), arc_next_out(NULL) {}
39
    
40
    ~StaticDigraphBase() {
41
      if (built) {
42
        delete[] node_first_out;
43
        delete[] node_first_in;
44
        delete[] arc_source;
45
        delete[] arc_target;
46
        delete[] arc_next_out;
47
        delete[] arc_next_in;
48
      }
49
    }
50

	
51
    class Node {
52
      friend class StaticDigraphBase;
53
    protected:
54
      int id;
55
      Node(int _id) : id(_id) {}
56
    public:
57
      Node() {}
58
      Node (Invalid) : id(-1) {}
59
      bool operator==(const Node& node) const { return id == node.id; }
60
      bool operator!=(const Node& node) const { return id != node.id; }
61
      bool operator<(const Node& node) const { return id < node.id; }
62
    };
63

	
64
    class Arc {
65
      friend class StaticDigraphBase;      
66
    protected:
67
      int id;
68
      Arc(int _id) : id(_id) {}
69
    public:
70
      Arc() { }
71
      Arc (Invalid) : id(-1) {}
72
      bool operator==(const Arc& arc) const { return id == arc.id; }
73
      bool operator!=(const Arc& arc) const { return id != arc.id; }
74
      bool operator<(const Arc& arc) const { return id < arc.id; }
75
    };
76

	
77
    Node source(const Arc& e) const { return Node(arc_source[e.id]); }
78
    Node target(const Arc& e) const { return Node(arc_target[e.id]); }
79

	
80
    void first(Node& n) const { n.id = node_num - 1; }
81
    static void next(Node& n) { --n.id; }
82

	
83
    void first(Arc& e) const { e.id = arc_num - 1; }
84
    static void next(Arc& e) { --e.id; }
85

	
86
    void firstOut(Arc& e, const Node& n) const { 
87
      e.id = node_first_out[n.id] != node_first_out[n.id + 1] ? 
88
        node_first_out[n.id] : -1;
89
    }
90
    void nextOut(Arc& e) const { e.id = arc_next_out[e.id]; }
91

	
92
    void firstIn(Arc& e, const Node& n) const { e.id = node_first_in[n.id]; }
93
    void nextIn(Arc& e) const { e.id = arc_next_in[e.id]; }
94

	
95
    static int id(const Node& n) { return n.id; }
96
    static Node nodeFromId(int id) { return Node(id); }
97
    int maxNodeId() const { return node_num - 1; }
98

	
99
    static int id(const Arc& e) { return e.id; }
100
    static Arc arcFromId(int id) { return Arc(id); }
101
    int maxArcId() const { return arc_num - 1; }
102

	
103
    typedef True NodeNumTag;
104
    typedef True ArcNumTag;
105

	
106
    int nodeNum() const { return node_num; }
107
    int arcNum() const { return arc_num; }
108

	
109
  private:
110

	
111
    template <typename Digraph, typename NodeRefMap>
112
    class ArcLess {
113
    public:
114
      typedef typename Digraph::Arc Arc;
115

	
116
      ArcLess(const Digraph &_graph, const NodeRefMap& _nodeRef) 
117
        : digraph(_graph), nodeRef(_nodeRef) {}
118
      
119
      bool operator()(const Arc& left, const Arc& right) const {
120
	return nodeRef[digraph.target(left)] < nodeRef[digraph.target(right)];
121
      }
122
    private:
123
      const Digraph& digraph;
124
      const NodeRefMap& nodeRef;
125
    };
126
    
127
  public:
128

	
129
    typedef True BuildTag;
130
    
131
    void clear() {
132
      if (built) {
133
        delete[] node_first_out;
134
        delete[] node_first_in;
135
        delete[] arc_source;
136
        delete[] arc_target;
137
        delete[] arc_next_out;
138
        delete[] arc_next_in;
139
      }
140
      built = false;
141
      node_num = 0;
142
      arc_num = 0;
143
    }
144
    
145
    template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
146
    void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
147
      typedef typename Digraph::Node GNode;
148
      typedef typename Digraph::Arc GArc;
149

	
150
      built = true;
151

	
152
      node_num = countNodes(digraph);
153
      arc_num = countArcs(digraph);
154

	
155
      node_first_out = new int[node_num + 1];
156
      node_first_in = new int[node_num];
157

	
158
      arc_source = new int[arc_num];
159
      arc_target = new int[arc_num];
160
      arc_next_out = new int[arc_num];
161
      arc_next_in = new int[arc_num];
162

	
163
      int node_index = 0;
164
      for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
165
        nodeRef[n] = Node(node_index);
166
        node_first_in[node_index] = -1;
167
        ++node_index;
168
      }
169

	
170
      ArcLess<Digraph, NodeRefMap> arcLess(digraph, nodeRef);
171

	
172
      int arc_index = 0;
173
      for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
174
        int source = nodeRef[n].id;
175
        std::vector<GArc> arcs;
176
        for (typename Digraph::OutArcIt e(digraph, n); e != INVALID; ++e) {
177
          arcs.push_back(e);
178
        }
179
        if (!arcs.empty()) {
180
          node_first_out[source] = arc_index;
181
          std::sort(arcs.begin(), arcs.end(), arcLess);
182
          for (typename std::vector<GArc>::iterator it = arcs.begin();
183
               it != arcs.end(); ++it) {
184
            int target = nodeRef[digraph.target(*it)].id;
185
            arcRef[*it] = Arc(arc_index);
186
            arc_source[arc_index] = source; 
187
            arc_target[arc_index] = target;
188
            arc_next_in[arc_index] = node_first_in[target];
189
            node_first_in[target] = arc_index;
190
            arc_next_out[arc_index] = arc_index + 1;
191
            ++arc_index;
192
          }
193
          arc_next_out[arc_index - 1] = -1;
194
        } else {
195
          node_first_out[source] = arc_index;
196
        }
197
      }
198
      node_first_out[node_num] = arc_num;
199
    }
200
    
201
    template <typename ArcListIterator>
202
    void build(int n, ArcListIterator first, ArcListIterator last) {
203
      built = true;
204

	
205
      node_num = n;
206
      arc_num = std::distance(first, last);
207

	
208
      node_first_out = new int[node_num + 1];
209
      node_first_in = new int[node_num];
210

	
211
      arc_source = new int[arc_num];
212
      arc_target = new int[arc_num];
213
      arc_next_out = new int[arc_num];
214
      arc_next_in = new int[arc_num];
215
      
216
      for (int i = 0; i != node_num; ++i) {
217
        node_first_in[i] = -1;
218
      }      
219
      
220
      int arc_index = 0;
221
      for (int i = 0; i != node_num; ++i) {
222
        node_first_out[i] = arc_index;
223
        for ( ; first != last && (*first).first == i; ++first) {
224
          int j = (*first).second;
225
          LEMON_ASSERT(j >= 0 && j < node_num,
226
            "Wrong arc list for StaticDigraph::build()");
227
          arc_source[arc_index] = i;
228
          arc_target[arc_index] = j;
229
          arc_next_in[arc_index] = node_first_in[j];
230
          node_first_in[j] = arc_index;
231
          arc_next_out[arc_index] = arc_index + 1;
232
          ++arc_index;
233
        }
234
        if (arc_index > node_first_out[i])
235
          arc_next_out[arc_index - 1] = -1;
236
      }
237
      LEMON_ASSERT(first == last,
238
        "Wrong arc list for StaticDigraph::build()");
239
      node_first_out[node_num] = arc_num;
240
    }
241

	
242
  protected:
243

	
244
    void fastFirstOut(Arc& e, const Node& n) const {
245
      e.id = node_first_out[n.id];
246
    }
247

	
248
    static void fastNextOut(Arc& e) {
249
      ++e.id;
250
    }
251
    void fastLastOut(Arc& e, const Node& n) const {
252
      e.id = node_first_out[n.id + 1];
253
    }
254

	
255
  protected:
256
    bool built;
257
    int node_num;
258
    int arc_num;
259
    int *node_first_out;
260
    int *node_first_in;
261
    int *arc_source;
262
    int *arc_target;
263
    int *arc_next_in;
264
    int *arc_next_out;
265
  };
266

	
267
  typedef DigraphExtender<StaticDigraphBase> ExtendedStaticDigraphBase;
268

	
269

	
270
  /// \ingroup graphs
271
  ///
272
  /// \brief A static directed graph class.
273
  ///
274
  /// \ref StaticDigraph is a highly efficient digraph implementation,
275
  /// but it is fully static.
276
  /// It stores only two \c int values for each node and only four \c int
277
  /// values for each arc. Moreover it provides faster item iteration than
278
  /// \ref ListDigraph and \ref SmartDigraph, especially using \c OutArcIt
279
  /// iterators, since its arcs are stored in an appropriate order.
280
  /// However it only provides build() and clear() functions and does not
281
  /// support any other modification of the digraph.
282
  ///
283
  /// Since this digraph structure is completely static, its nodes and arcs
284
  /// can be indexed with integers from the ranges <tt>[0..nodeNum()-1]</tt>
285
  /// and <tt>[0..arcNum()-1]</tt>, respectively. 
286
  /// The index of an item is the same as its ID, it can be obtained
287
  /// using the corresponding \ref index() or \ref concepts::Digraph::id()
288
  /// "id()" function. A node or arc with a certain index can be obtained
289
  /// using node() or arc().
290
  ///
291
  /// This type fully conforms to the \ref concepts::Digraph "Digraph concept".
292
  /// Most of its member functions and nested classes are documented
293
  /// only in the concept class.
294
  ///
295
  /// \sa concepts::Digraph
296
  class StaticDigraph : public ExtendedStaticDigraphBase {
297
  public:
298

	
299
    typedef ExtendedStaticDigraphBase Parent;
300
  
301
  public:
302
  
303
    /// \brief Constructor
304
    ///
305
    /// Default constructor.
306
    StaticDigraph() : Parent() {}
307

	
308
    /// \brief The node with the given index.
309
    ///
310
    /// This function returns the node with the given index.
311
    /// \sa index()
312
    static Node node(int ix) { return Parent::nodeFromId(ix); }
313

	
314
    /// \brief The arc with the given index.
315
    ///
316
    /// This function returns the arc with the given index.
317
    /// \sa index()
318
    static Arc arc(int ix) { return Parent::arcFromId(ix); }
319

	
320
    /// \brief The index of the given node.
321
    ///
322
    /// This function returns the index of the the given node.
323
    /// \sa node()
324
    static int index(Node node) { return Parent::id(node); }
325

	
326
    /// \brief The index of the given arc.
327
    ///
328
    /// This function returns the index of the the given arc.
329
    /// \sa arc()
330
    static int index(Arc arc) { return Parent::id(arc); }
331

	
332
    /// \brief Number of nodes.
333
    ///
334
    /// This function returns the number of nodes.
335
    int nodeNum() const { return node_num; }
336

	
337
    /// \brief Number of arcs.
338
    ///
339
    /// This function returns the number of arcs.
340
    int arcNum() const { return arc_num; }
341

	
342
    /// \brief Build the digraph copying another digraph.
343
    ///
344
    /// This function builds the digraph copying another digraph of any
345
    /// kind. It can be called more than once, but in such case, the whole
346
    /// structure and all maps will be cleared and rebuilt.
347
    ///
348
    /// This method also makes possible to copy a digraph to a StaticDigraph
349
    /// structure using \ref DigraphCopy.
350
    /// 
351
    /// \param digraph An existing digraph to be copied.
352
    /// \param nodeRef The node references will be copied into this map.
353
    /// Its key type must be \c Digraph::Node and its value type must be
354
    /// \c StaticDigraph::Node.
355
    /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap"
356
    /// concept.
357
    /// \param arcRef The arc references will be copied into this map.
358
    /// Its key type must be \c Digraph::Arc and its value type must be
359
    /// \c StaticDigraph::Arc.
360
    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
361
    ///
362
    /// \note If you do not need the arc references, then you could use
363
    /// \ref NullMap for the last parameter. However the node references
364
    /// are required by the function itself, thus they must be readable
365
    /// from the map.
366
    template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
367
    void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
368
      if (built) Parent::clear();
369
      Parent::build(digraph, nodeRef, arcRef);
370
    }
371
  
372
    /// \brief Build the digraph from an arc list.
373
    ///
374
    /// This function builds the digraph from the given arc list.
375
    /// It can be called more than once, but in such case, the whole
376
    /// structure and all maps will be cleared and rebuilt.
377
    ///
378
    /// The list of the arcs must be given in the range <tt>[begin, end)</tt>
379
    /// specified by STL compatible itartors whose \c value_type must be
380
    /// <tt>std::pair<int,int></tt>.
381
    /// Each arc must be specified by a pair of integer indices
382
    /// from the range <tt>[0..n-1]</tt>. <i>The pairs must be in a
383
    /// non-decreasing order with respect to their first values.</i>
384
    /// If the k-th pair in the list is <tt>(i,j)</tt>, then
385
    /// <tt>arc(k-1)</tt> will connect <tt>node(i)</tt> to <tt>node(j)</tt>.
386
    ///
387
    /// \param n The number of nodes.
388
    /// \param begin An iterator pointing to the beginning of the arc list.
389
    /// \param end An iterator pointing to the end of the arc list.
390
    ///
391
    /// For example, a simple digraph can be constructed like this.
392
    /// \code
393
    ///   std::vector<std::pair<int,int> > arcs;
394
    ///   arcs.push_back(std::make_pair(0,1));
395
    ///   arcs.push_back(std::make_pair(0,2));
396
    ///   arcs.push_back(std::make_pair(1,3));
397
    ///   arcs.push_back(std::make_pair(1,2));
398
    ///   arcs.push_back(std::make_pair(3,0));
399
    ///   StaticDigraph gr;
400
    ///   gr.build(4, arcs.begin(), arcs.end());
401
    /// \endcode
402
    template <typename ArcListIterator>
403
    void build(int n, ArcListIterator begin, ArcListIterator end) {
404
      if (built) Parent::clear();
405
      StaticDigraphBase::build(n, begin, end);
406
      notifier(Node()).build();
407
      notifier(Arc()).build();
408
    }
409

	
410
    /// \brief Clear the digraph.
411
    ///
412
    /// This function erases all nodes and arcs from the digraph.
413
    void clear() {
414
      Parent::clear();
415
    }
416

	
417
  protected:
418

	
419
    using Parent::fastFirstOut;
420
    using Parent::fastNextOut;
421
    using Parent::fastLastOut;
422
    
423
  public:
424

	
425
    class OutArcIt : public Arc {
426
    public:
427

	
428
      OutArcIt() { }
429

	
430
      OutArcIt(Invalid i) : Arc(i) { }
431

	
432
      OutArcIt(const StaticDigraph& digraph, const Node& node) {
433
	digraph.fastFirstOut(*this, node);
434
	digraph.fastLastOut(last, node);
435
        if (last == *this) *this = INVALID;
436
      }
437

	
438
      OutArcIt(const StaticDigraph& digraph, const Arc& arc) : Arc(arc) {
439
        if (arc != INVALID) {
440
          digraph.fastLastOut(last, digraph.source(arc));
441
        }
442
      }
443

	
444
      OutArcIt& operator++() { 
445
        StaticDigraph::fastNextOut(*this);
446
        if (last == *this) *this = INVALID;
447
        return *this; 
448
      }
449

	
450
    private:
451
      Arc last;
452
    };
453

	
454
    Node baseNode(const OutArcIt &arc) const {
455
      return Parent::source(static_cast<const Arc&>(arc));
456
    }
457

	
458
    Node runningNode(const OutArcIt &arc) const {
459
      return Parent::target(static_cast<const Arc&>(arc));
460
    }
461

	
462
    Node baseNode(const InArcIt &arc) const {
463
      return Parent::target(static_cast<const Arc&>(arc));
464
    }
465

	
466
    Node runningNode(const InArcIt &arc) const {
467
      return Parent::source(static_cast<const Arc&>(arc));
468
    }
469

	
470
  };
471

	
472
}
473

	
474
#endif
Ignore white space 6 line context
1
#!/usr/bin/env /usr/local/Python/bin/python2.1
2
"""
3
  BibTeX to Doxygen converter
4
  Usage: python bib2dox.py bibfile.bib > bibfile.dox
5

	
6
  This code is the modification of the BibTeX to XML converter
7
  by Vidar Bronken Gundersen et al. See the original copyright notices below. 
8

	
9
  **********************************************************************
10

	
11
  Decoder for bibliographic data, BibTeX
12
  Usage: python bibtex2xml.py bibfile.bib > bibfile.xml
13

	
14
  v.8
15
  (c)2002-06-23 Vidar Bronken Gundersen
16
  http://bibtexml.sf.net/
17
  Reuse approved as long as this notification is kept.
18
  Licence: GPL.
19

	
20
  Contributions/thanks to:
21
  Egon Willighagen, http://sf.net/projects/jreferences/
22
  Richard Mahoney (for providing a test case)
23

	
24
  Editted by Sara Sprenkle to be more robust and handle more bibtex features.
25
  (c) 2003-01-15
26

	
27
  1.  Changed bibtex: tags to bibxml: tags.
28
  2.  Use xmlns:bibxml="http://bibtexml.sf.net/"
29
  3.  Allow spaces between @type and first {
30
  4.  "author" fields with multiple authors split by " and "
31
      are put in separate xml "bibxml:author" tags.
32
  5.  Option for Titles: words are capitalized
33
      only if first letter in title or capitalized inside braces
34
  6.  Removes braces from within field values
35
  7.  Ignores comments in bibtex file (including @comment{ or % )
36
  8.  Replaces some special latex tags, e.g., replaces ~ with '&#160;'
37
  9.  Handles bibtex @string abbreviations
38
        --> includes bibtex's default abbreviations for months
39
        --> does concatenation of abbr # " more " and " more " # abbr
40
  10. Handles @type( ... ) or @type{ ... }
41
  11. The keywords field is split on , or ; and put into separate xml
42
      "bibxml:keywords" tags
43
  12. Ignores @preamble
44

	
45
  Known Limitations
46
  1.  Does not transform Latex encoding like math mode and special
47
      latex symbols.
48
  2.  Does not parse author fields into first and last names.
49
      E.g., It does not do anything special to an author whose name is
50
      in the form LAST_NAME, FIRST_NAME
51
      In "author" tag, will show up as
52
      <bibxml:author>LAST_NAME, FIRST_NAME</bibxml:author>
53
  3.  Does not handle "crossref" fields other than to print
54
      <bibxml:crossref>...</bibxml:crossref>
55
  4.  Does not inform user of the input's format errors.  You just won't
56
      be able to transform the file later with XSL
57

	
58
  You will have to manually edit the XML output if you need to handle
59
  these (and unknown) limitations.
60

	
61
"""
62

	
63
import string, re
64

	
65
# set of valid name characters
66
valid_name_chars = '[\w\-:]'
67

	
68
#
69
# define global regular expression variables
70
#
71
author_rex = re.compile('\s+and\s+')
72
rembraces_rex = re.compile('[{}]')
73
capitalize_rex = re.compile('({[^}]*})')
74

	
75
# used by bibtexkeywords(data)
76
keywords_rex = re.compile('[,;]')
77

	
78
# used by concat_line(line)
79
concatsplit_rex = re.compile('\s*#\s*')
80

	
81
# split on {, }, or " in verify_out_of_braces
82
delimiter_rex = re.compile('([{}"])',re.I)
83

	
84
field_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
85
data_rex = re.compile('\s*(\w*)\s*=\s*([^,]*),?')
86

	
87
url_rex = re.compile('\\\url\{([^}]*)\}')
88

	
89
#
90
# styles for html formatting
91
#
92
divstyle = 'margin-top: -4ex; margin-left: 8em;'
93

	
94
#
95
# return the string parameter without braces
96
#
97
def transformurls(str):
98
    return url_rex.sub(r'<a href="\1">\1</a>', str)
99

	
100
#
101
# return the string parameter without braces
102
#
103
def removebraces(str):
104
    return rembraces_rex.sub('', str)
105

	
106
#
107
# latex-specific replacements
108
# (do this after braces were removed)
109
#
110
def latexreplacements(line):
111
    line = string.replace(line, '~', '&nbsp;')
112
    line = string.replace(line, '\\\'a', '&aacute;')
113
    line = string.replace(line, '\\"a', '&auml;')
114
    line = string.replace(line, '\\\'e', '&eacute;')
115
    line = string.replace(line, '\\"e', '&euml;')
116
    line = string.replace(line, '\\\'i', '&iacute;')
117
    line = string.replace(line, '\\"i', '&iuml;')
118
    line = string.replace(line, '\\\'o', '&oacute;')
119
    line = string.replace(line, '\\"o', '&ouml;')
120
    line = string.replace(line, '\\\'u', '&uacute;')
121
    line = string.replace(line, '\\"u', '&uuml;')
122
    line = string.replace(line, '\\H o', '&otilde;')
123
    line = string.replace(line, '\\H u', '&uuml;')   # &utilde; does not exist
124
    line = string.replace(line, '\\\'A', '&Aacute;')
125
    line = string.replace(line, '\\"A', '&Auml;')
126
    line = string.replace(line, '\\\'E', '&Eacute;')
127
    line = string.replace(line, '\\"E', '&Euml;')
128
    line = string.replace(line, '\\\'I', '&Iacute;')
129
    line = string.replace(line, '\\"I', '&Iuml;')
130
    line = string.replace(line, '\\\'O', '&Oacute;')
131
    line = string.replace(line, '\\"O', '&Ouml;')
132
    line = string.replace(line, '\\\'U', '&Uacute;')
133
    line = string.replace(line, '\\"U', '&Uuml;')
134
    line = string.replace(line, '\\H O', '&Otilde;')
135
    line = string.replace(line, '\\H U', '&Uuml;')   # &Utilde; does not exist
136

	
137
    return line
138

	
139
#
140
# copy characters form a string decoding html expressions (&xyz;)
141
#
142
def copychars(str, ifrom, count):
143
    result = ''
144
    i = ifrom
145
    c = 0
146
    html_spec = False
147
    while (i < len(str)) and (c < count):
148
        if str[i] == '&':
149
            html_spec = True;
150
            if i+1 < len(str):
151
                result += str[i+1]
152
            c += 1
153
            i += 2
154
        else:
155
            if not html_spec:
156
                if ((str[i] >= 'A') and (str[i] <= 'Z')) or \
157
                   ((str[i] >= 'a') and (str[i] <= 'z')):
158
                    result += str[i]
159
                    c += 1
160
            elif str[i] == ';':
161
                html_spec = False;
162
            i += 1
163
    
164
    return result
165

	
166

	
167
# 
168
# Handle a list of authors (separated by 'and').
169
# It gives back an array of the follwing values:
170
#  - num: the number of authors,
171
#  - list: the list of the author names,
172
#  - text: the bibtex text (separated by commas and/or 'and')
173
#  - abbrev: abbreviation that can be used for indicate the
174
#    bibliography entries
175
#
176
def bibtexauthor(data):
177
    result = {}
178
    bibtex = ''
179
    result['list'] = author_rex.split(data)
180
    result['num'] = len(result['list'])
181
    for i, author in enumerate(result['list']):
182
        # general transformations
183
        author = latexreplacements(removebraces(author.strip()))
184
        # transform "Xyz, A. B." to "A. B. Xyz"
185
        pos = author.find(',')
186
        if pos != -1:
187
            author = author[pos+1:].strip() + ' ' + author[:pos].strip()
188
        result['list'][i] = author
189
        bibtex += author + '#'
190
    bibtex = bibtex[:-1]
191
    if result['num'] > 1:
192
        ix = bibtex.rfind('#')
193
        if result['num'] == 2:
194
            bibtex = bibtex[:ix] + ' and ' + bibtex[ix+1:]
195
        else:
196
            bibtex = bibtex[:ix] + ', and ' + bibtex[ix+1:]
197
    bibtex = bibtex.replace('#', ', ')
198
    result['text'] = bibtex
199
    
200
    result['abbrev'] = ''
201
    for author in result['list']:
202
        pos = author.rfind(' ') + 1
203
        count = 1
204
        if result['num'] == 1:
205
            count = 3
206
        result['abbrev'] += copychars(author, pos, count)
207

	
208
    return result
209

	
210

	
211
#
212
# data = title string
213
# @return the capitalized title (first letter is capitalized), rest are capitalized
214
# only if capitalized inside braces
215
#
216
def capitalizetitle(data):
217
    title_list = capitalize_rex.split(data)
218
    title = ''
219
    count = 0
220
    for phrase in title_list:
221
         check = string.lstrip(phrase)
222

	
223
         # keep phrase's capitalization the same
224
         if check.find('{') == 0:
225
              title += removebraces(phrase)
226
         else:
227
         # first word --> capitalize first letter (after spaces)
228
              if count == 0:
229
                  title += check.capitalize()
230
              else:
231
                  title += phrase.lower()
232
         count = count + 1
233

	
234
    return title
235

	
236

	
237
#
238
# @return the bibtex for the title
239
# @param data --> title string
240
# braces are removed from title
241
#
242
def bibtextitle(data, entrytype):
243
    if entrytype in ('book', 'inbook'):
244
        title = removebraces(data.strip())
245
    else:
246
        title = removebraces(capitalizetitle(data.strip()))
247
    bibtex = title
248
    return bibtex
249

	
250

	
251
#
252
# function to compare entry lists
253
#
254
def entry_cmp(x, y):
255
    return cmp(x[0], y[0])
256

	
257

	
258
#
259
# print the XML for the transformed "filecont_source"
260
#
261
def bibtexdecoder(filecont_source):
262
    filecont = []
263
    file = []
264
    
265
    # want @<alphanumeric chars><spaces>{<spaces><any chars>,
266
    pubtype_rex = re.compile('@(\w*)\s*{\s*(.*),')
267
    endtype_rex = re.compile('}\s*$')
268
    endtag_rex = re.compile('^\s*}\s*$')
269

	
270
    bracefield_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
271
    bracedata_rex = re.compile('\s*(\w*)\s*=\s*{(.*)},?')
272

	
273
    quotefield_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
274
    quotedata_rex = re.compile('\s*(\w*)\s*=\s*"(.*)",?')
275

	
276
    for line in filecont_source:
277
        line = line[:-1]
278

	
279
        # encode character entities
280
        line = string.replace(line, '&', '&amp;')
281
        line = string.replace(line, '<', '&lt;')
282
        line = string.replace(line, '>', '&gt;')
283

	
284
        # start entry: publication type (store for later use)
285
        if pubtype_rex.match(line):
286
        # want @<alphanumeric chars><spaces>{<spaces><any chars>,
287
            entrycont = {}
288
            entry = []
289
            entrytype = pubtype_rex.sub('\g<1>',line)
290
            entrytype = string.lower(entrytype)
291
            entryid   = pubtype_rex.sub('\g<2>', line)
292

	
293
        # end entry if just a }
294
        elif endtype_rex.match(line):
295
            # generate doxygen code for the entry
296

	
297
            # enty type related formattings
298
            if entrytype in ('book', 'inbook'):
299
                entrycont['title'] = '<em>' + entrycont['title'] + '</em>'
300
                if not entrycont.has_key('author'):
301
                    entrycont['author'] = entrycont['editor']
302
                    entrycont['author']['text'] += ', editors'
303
            elif entrytype == 'article':
304
                entrycont['journal'] = '<em>' + entrycont['journal'] + '</em>'
305
            elif entrytype in ('inproceedings', 'incollection', 'conference'):
306
                entrycont['booktitle'] = '<em>' + entrycont['booktitle'] + '</em>'
307
            elif entrytype == 'techreport':
308
                if not entrycont.has_key('type'):
309
                    entrycont['type'] = 'Technical report'
310
            elif entrytype == 'mastersthesis':
311
                entrycont['type'] = 'Master\'s thesis'
312
            elif entrytype == 'phdthesis':
313
                entrycont['type'] = 'PhD thesis'
314

	
315
            for eline in entrycont:
316
                if eline != '':
317
                    eline = latexreplacements(eline)
318

	
319
            if entrycont.has_key('pages') and (entrycont['pages'] != ''):
320
                entrycont['pages'] = string.replace(entrycont['pages'], '--', '-')
321

	
322
            if entrycont.has_key('author') and (entrycont['author'] != ''):
323
                entry.append(entrycont['author']['text'] + '.')
324
            if entrycont.has_key('title') and (entrycont['title'] != ''):
325
                entry.append(entrycont['title'] + '.')
326
            if entrycont.has_key('journal') and (entrycont['journal'] != ''):
327
                entry.append(entrycont['journal'] + ',')
328
            if entrycont.has_key('booktitle') and (entrycont['booktitle'] != ''):
329
                entry.append('In ' + entrycont['booktitle'] + ',')
330
            if entrycont.has_key('type') and (entrycont['type'] != ''):
331
                eline = entrycont['type']
332
                if entrycont.has_key('number') and (entrycont['number'] != ''):
333
                    eline += ' ' + entrycont['number']
334
                eline += ','
335
                entry.append(eline)
336
            if entrycont.has_key('institution') and (entrycont['institution'] != ''):
337
                entry.append(entrycont['institution'] + ',')
338
            if entrycont.has_key('publisher') and (entrycont['publisher'] != ''):
339
                entry.append(entrycont['publisher'] + ',')
340
            if entrycont.has_key('school') and (entrycont['school'] != ''):
341
                entry.append(entrycont['school'] + ',')
342
            if entrycont.has_key('address') and (entrycont['address'] != ''):
343
                entry.append(entrycont['address'] + ',')
344
            if entrycont.has_key('edition') and (entrycont['edition'] != ''):
345
                entry.append(entrycont['edition'] + ' edition,')
346
            if entrycont.has_key('howpublished') and (entrycont['howpublished'] != ''):
347
                entry.append(entrycont['howpublished'] + ',')
348
            if entrycont.has_key('volume') and (entrycont['volume'] != ''):
349
                eline = entrycont['volume'];
350
                if entrycont.has_key('number') and (entrycont['number'] != ''):
351
                    eline += '(' + entrycont['number'] + ')'
352
                if entrycont.has_key('pages') and (entrycont['pages'] != ''):
353
                    eline += ':' + entrycont['pages']
354
                eline += ','
355
                entry.append(eline)
356
            else:
357
                if entrycont.has_key('pages') and (entrycont['pages'] != ''):
358
                    entry.append('pages ' + entrycont['pages'] + ',')
359
            if entrycont.has_key('year') and (entrycont['year'] != ''):
360
                if entrycont.has_key('month') and (entrycont['month'] != ''):
361
                    entry.append(entrycont['month'] + ' ' + entrycont['year'] + '.')
362
                else:
363
                    entry.append(entrycont['year'] + '.')
364
            if entrycont.has_key('note') and (entrycont['note'] != ''):
365
                entry.append(entrycont['note'] + '.')
366
            if entrycont.has_key('url') and (entrycont['url'] != ''):
367
                entry.append(entrycont['url'] + '.')
368

	
369
            # generate keys for sorting and for the output
370
            sortkey = ''
371
            bibkey = ''
372
            if entrycont.has_key('author'):
373
                for author in entrycont['author']['list']:
374
                    sortkey += copychars(author, author.rfind(' ')+1, len(author))
375
                bibkey = entrycont['author']['abbrev']
376
            else:
377
                bibkey = 'x'
378
            if entrycont.has_key('year'):
379
                sortkey += entrycont['year']
380
                bibkey += entrycont['year'][-2:]
381
            if entrycont.has_key('title'):
382
                sortkey += entrycont['title']
383
            if entrycont.has_key('key'):
384
                sortkey = entrycont['key'] + sortkey
385
                bibkey = entrycont['key']
386
            entry.insert(0, sortkey)
387
            entry.insert(1, bibkey)
388
            entry.insert(2, entryid)
389
           
390
            # add the entry to the file contents
391
            filecont.append(entry)
392

	
393
        else:
394
            # field, publication info
395
            field = ''
396
            data = ''
397
            
398
            # field = {data} entries
399
            if bracedata_rex.match(line):
400
                field = bracefield_rex.sub('\g<1>', line)
401
                field = string.lower(field)
402
                data =  bracedata_rex.sub('\g<2>', line)
403

	
404
            # field = "data" entries
405
            elif quotedata_rex.match(line):
406
                field = quotefield_rex.sub('\g<1>', line)
407
                field = string.lower(field)
408
                data =  quotedata_rex.sub('\g<2>', line)
409

	
410
            # field = data entries
411
            elif data_rex.match(line):
412
                field = field_rex.sub('\g<1>', line)
413
                field = string.lower(field)
414
                data =  data_rex.sub('\g<2>', line)
415

	
416
            if field == 'url':
417
                data = '\\url{' + data.strip() + '}'
418
            
419
            if field in ('author', 'editor'):
420
                entrycont[field] = bibtexauthor(data)
421
                line = ''
422
            elif field == 'title':
423
                line = bibtextitle(data, entrytype)
424
            elif field != '':
425
                line = removebraces(transformurls(data.strip()))
426

	
427
            if line != '':
428
                line = latexreplacements(line)
429
                entrycont[field] = line
430

	
431

	
432
    # sort entries
433
    filecont.sort(entry_cmp)
434
    
435
    # count the bibtex keys
436
    keytable = {}
437
    counttable = {}
438
    for entry in filecont:
439
        bibkey = entry[1]
440
        if not keytable.has_key(bibkey):
441
            keytable[bibkey] = 1
442
        else:
443
            keytable[bibkey] += 1
444

	
445
    for bibkey in keytable.keys():
446
        counttable[bibkey] = 0
447
    
448
    # generate output
449
    for entry in filecont:
450
        # generate output key form the bibtex key
451
        bibkey = entry[1]
452
        entryid = entry[2]
453
        if keytable[bibkey] == 1:
454
            outkey = bibkey
455
        else:
456
            outkey = bibkey + chr(97 + counttable[bibkey])
457
        counttable[bibkey] += 1
458
        
459
        # append the entry code to the output
460
        file.append('\\section ' + entryid + ' [' + outkey + ']')
461
        file.append('<div style="' + divstyle + '">')
462
        for line in entry[3:]:
463
            file.append(line)
464
        file.append('</div>')
465
        file.append('')
466

	
467
    return file
468

	
469

	
470
#
471
# return 1 iff abbr is in line but not inside braces or quotes
472
# assumes that abbr appears only once on the line (out of braces and quotes)
473
#
474
def verify_out_of_braces(line, abbr):
475

	
476
    phrase_split = delimiter_rex.split(line)
477

	
478
    abbr_rex = re.compile( '\\b' + abbr + '\\b', re.I)
479

	
480
    open_brace = 0
481
    open_quote = 0
482

	
483
    for phrase in phrase_split:
484
        if phrase == "{":
485
            open_brace = open_brace + 1
486
        elif phrase == "}":
487
            open_brace = open_brace - 1
488
        elif phrase == '"':
489
            if open_quote == 1:
490
                open_quote = 0
491
            else:
492
                open_quote = 1
493
        elif abbr_rex.search(phrase):
494
            if open_brace == 0 and open_quote == 0:
495
                return 1
496

	
497
    return 0
498

	
499

	
500
#
501
# a line in the form phrase1 # phrase2 # ... # phrasen
502
# is returned as phrase1 phrase2 ... phrasen
503
# with the correct punctuation
504
# Bug: Doesn't always work with multiple abbreviations plugged in
505
#
506
def concat_line(line):
507
    # only look at part after equals
508
    field = field_rex.sub('\g<1>',line)
509
    rest = field_rex.sub('\g<2>',line)
510

	
511
    concat_line = field + ' ='
512

	
513
    pound_split = concatsplit_rex.split(rest)
514

	
515
    phrase_count = 0
516
    length = len(pound_split)
517

	
518
    for phrase in pound_split:
519
        phrase = phrase.strip()
520
        if phrase_count != 0:
521
            if phrase.startswith('"') or phrase.startswith('{'):
522
                phrase = phrase[1:]
523
        elif phrase.startswith('"'):
524
            phrase = phrase.replace('"','{',1)
525

	
526
        if phrase_count != length-1:
527
            if phrase.endswith('"') or phrase.endswith('}'):
528
                phrase = phrase[:-1]
529
        else:
530
            if phrase.endswith('"'):
531
                phrase = phrase[:-1]
532
                phrase = phrase + "}"
533
            elif phrase.endswith('",'):
534
                phrase = phrase[:-2]
535
                phrase = phrase + "},"
536

	
537
        # if phrase did have \#, add the \# back
538
        if phrase.endswith('\\'):
539
            phrase = phrase + "#"
540
        concat_line = concat_line + ' ' + phrase
541

	
542
        phrase_count = phrase_count + 1
543

	
544
    return concat_line
545

	
546

	
547
#
548
# substitute abbreviations into filecont
549
# @param filecont_source - string of data from file
550
#
551
def bibtex_replace_abbreviations(filecont_source):
552
    filecont = filecont_source.splitlines()
553

	
554
    #  These are defined in bibtex, so we'll define them too
555
    abbr_list = ['jan','feb','mar','apr','may','jun',
556
                 'jul','aug','sep','oct','nov','dec']
557
    value_list = ['January','February','March','April',
558
                  'May','June','July','August','September',
559
                  'October','November','December']
560

	
561
    abbr_rex = []
562
    total_abbr_count = 0
563

	
564
    front = '\\b'
565
    back = '(,?)\\b'
566

	
567
    for x in abbr_list:
568
        abbr_rex.append( re.compile( front + abbr_list[total_abbr_count] + back, re.I ) )
569
        total_abbr_count = total_abbr_count + 1
570

	
571

	
572
    abbrdef_rex = re.compile('\s*@string\s*{\s*('+ valid_name_chars +'*)\s*=(.*)',
573
                             re.I)
574

	
575
    comment_rex = re.compile('@comment\s*{',re.I)
576
    preamble_rex = re.compile('@preamble\s*{',re.I)
577

	
578
    waiting_for_end_string = 0
579
    i = 0
580
    filecont2 = ''
581

	
582
    for line in filecont:
583
        if line == ' ' or line == '':
584
            continue
585

	
586
        if waiting_for_end_string:
587
            if re.search('}',line):
588
                waiting_for_end_string = 0
589
                continue
590

	
591
        if abbrdef_rex.search(line):
592
            abbr = abbrdef_rex.sub('\g<1>', line)
593

	
594
            if abbr_list.count(abbr) == 0:
595
                val = abbrdef_rex.sub('\g<2>', line)
596
                abbr_list.append(abbr)
597
                value_list.append(string.strip(val))
598
                abbr_rex.append( re.compile( front + abbr_list[total_abbr_count] + back, re.I ) )
599
                total_abbr_count = total_abbr_count + 1
600
            waiting_for_end_string = 1
601
            continue
602

	
603
        if comment_rex.search(line):
604
            waiting_for_end_string = 1
605
            continue
606

	
607
        if preamble_rex.search(line):
608
            waiting_for_end_string = 1
609
            continue
610

	
611

	
612
        # replace subsequent abbreviations with the value
613
        abbr_count = 0
614

	
615
        for x in abbr_list:
616

	
617
            if abbr_rex[abbr_count].search(line):
618
                if verify_out_of_braces(line,abbr_list[abbr_count]) == 1:
619
                    line = abbr_rex[abbr_count].sub( value_list[abbr_count] + '\g<1>', line)
620
                # Check for # concatenations
621
                if concatsplit_rex.search(line):
622
                    line = concat_line(line)
623
            abbr_count = abbr_count + 1
624

	
625

	
626
        filecont2 = filecont2 + line + '\n'
627
        i = i+1
628

	
629

	
630
    # Do one final pass over file
631

	
632
    # make sure that didn't end up with {" or }" after the substitution
633
    filecont2 = filecont2.replace('{"','{{')
634
    filecont2 = filecont2.replace('"}','}}')
635

	
636
    afterquotevalue_rex = re.compile('"\s*,\s*')
637
    afterbrace_rex = re.compile('"\s*}')
638
    afterbracevalue_rex = re.compile('(=\s*{[^=]*)},\s*')
639

	
640
    # add new lines to data that changed because of abbreviation substitutions
641
    filecont2 = afterquotevalue_rex.sub('",\n', filecont2)
642
    filecont2 = afterbrace_rex.sub('"\n}', filecont2)
643
    filecont2 = afterbracevalue_rex.sub('\g<1>},\n', filecont2)
644

	
645
    return filecont2
646

	
647
#
648
# convert @type( ... ) to @type{ ... }
649
#
650
def no_outer_parens(filecont):
651

	
652
    # do checking for open parens
653
    # will convert to braces
654
    paren_split = re.split('([(){}])',filecont)
655

	
656
    open_paren_count = 0
657
    open_type = 0
658
    look_next = 0
659

	
660
    # rebuild filecont
661
    filecont = ''
662

	
663
    at_rex = re.compile('@\w*')
664

	
665
    for phrase in paren_split:
666
        if look_next == 1:
667
            if phrase == '(':
668
                phrase = '{'
669
                open_paren_count = open_paren_count + 1
670
            else:
671
                open_type = 0
672
            look_next = 0
673

	
674
        if phrase == '(':
675
            open_paren_count = open_paren_count + 1
676

	
677
        elif phrase == ')':
678
            open_paren_count = open_paren_count - 1
679
            if open_type == 1 and open_paren_count == 0:
680
                phrase = '}'
681
                open_type = 0
682

	
683
        elif at_rex.search( phrase ):
684
            open_type = 1
685
            look_next = 1
686

	
687
        filecont = filecont + phrase
688

	
689
    return filecont
690

	
691

	
692
#
693
# make all whitespace into just one space
694
# format the bibtex file into a usable form.
695
#
696
def bibtexwasher(filecont_source):
697

	
698
    space_rex = re.compile('\s+')
699
    comment_rex = re.compile('\s*%')
700

	
701
    filecont = []
702

	
703
    # remove trailing and excessive whitespace
704
    # ignore comments
705
    for line in filecont_source:
706
        line = string.strip(line)
707
        line = space_rex.sub(' ', line)
708
        # ignore comments
709
        if not comment_rex.match(line) and line != '':
710
            filecont.append(' '+ line)
711

	
712
    filecont = string.join(filecont, '')
713

	
714
    # the file is in one long string
715

	
716
    filecont = no_outer_parens(filecont)
717

	
718
    #
719
    # split lines according to preferred syntax scheme
720
    #
721
    filecont = re.sub('(=\s*{[^=]*)},', '\g<1>},\n', filecont)
722

	
723
    # add new lines after commas that are after values
724
    filecont = re.sub('"\s*,', '",\n', filecont)
725
    filecont = re.sub('=\s*([\w\d]+)\s*,', '= \g<1>,\n', filecont)
726
    filecont = re.sub('(@\w*)\s*({(\s*)[^,\s]*)\s*,',
727
                          '\n\n\g<1>\g<2>,\n', filecont)
728

	
729
    # add new lines after }
730
    filecont = re.sub('"\s*}','"\n}\n', filecont)
731
    filecont = re.sub('}\s*,','},\n', filecont)
732

	
733

	
734
    filecont = re.sub('@(\w*)', '\n@\g<1>', filecont)
735

	
736
    # character encoding, reserved latex characters
737
    filecont = re.sub('{\\\&}', '&', filecont)
738
    filecont = re.sub('\\\&', '&', filecont)
739

	
740
    # do checking for open braces to get format correct
741
    open_brace_count = 0
742
    brace_split = re.split('([{}])',filecont)
743

	
744
    # rebuild filecont
745
    filecont = ''
746

	
747
    for phrase in brace_split:
748
        if phrase == '{':
749
            open_brace_count = open_brace_count + 1
750
        elif phrase == '}':
751
            open_brace_count = open_brace_count - 1
752
            if open_brace_count == 0:
753
                filecont = filecont + '\n'
754

	
755
        filecont = filecont + phrase
756

	
757
    filecont2 = bibtex_replace_abbreviations(filecont)
758

	
759
    # gather
760
    filecont = filecont2.splitlines()
761
    i=0
762
    j=0         # count the number of blank lines
763
    for line in filecont:
764
        # ignore blank lines
765
        if line == '' or line == ' ':
766
            j = j+1
767
            continue
768
        filecont[i] = line + '\n'
769
        i = i+1
770

	
771
    # get rid of the extra stuff at the end of the array
772
    # (The extra stuff are duplicates that are in the array because
773
    # blank lines were removed.)
774
    length = len( filecont)
775
    filecont[length-j:length] = []
776

	
777
    return filecont
778

	
779

	
780
def filehandler(filepath):
781
    try:
782
        fd = open(filepath, 'r')
783
        filecont_source = fd.readlines()
784
        fd.close()
785
    except:
786
        print 'Could not open file:', filepath
787
    washeddata = bibtexwasher(filecont_source)
788
    outdata = bibtexdecoder(washeddata)
789
    print '/**'
790
    print '\page references References'
791
    print
792
    for line in outdata:
793
        print line
794
    print '*/'
795

	
796

	
797
# main program
798

	
799
def main():
800
    import sys
801
    if sys.argv[1:]:
802
        filepath = sys.argv[1]
803
    else:
804
        print "No input file"
805
        sys.exit()
806
    filehandler(filepath)
807

	
808
if __name__ == "__main__": main()
809

	
810

	
811
# end python script
Ignore white space 6 line context
1
#!/bin/bash
2
#
3
# This file is a part of LEMON, a generic C++ optimization library.
4
#
5
# Copyright (C) 2003-2009
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
if [ ! -f ~/.lemon-bootstrap ]; then
19
    echo 'Create ~/.lemon-bootstrap'.
20
    cat >~/.lemon-bootstrap <<EOF
21
#
22
# Default settings for bootstraping the LEMON source code repository
23
#
24
EOF
25
fi
26

	
27
source ~/.lemon-bootstrap
28
if [ -f ../../../.lemon-bootstrap ]; then source ../../../.lemon-bootstrap; fi
29
if [ -f ../../.lemon-bootstrap ]; then source ../../.lemon-bootstrap; fi
30
if [ -f ../.lemon-bootstrap ]; then source ../.lemon-bootstrap; fi
31
if [ -f ./.lemon-bootstrap ]; then source ./.lemon-bootstrap; fi
32

	
33

	
34
function augment_config() { 
35
    if [ "x${!1}" == "x" ]; then
36
        eval $1=$2
37
        echo Add "'$1'" to '~/.lemon-bootstrap'.
38
        echo >>~/.lemon-bootstrap
39
        echo $3 >>~/.lemon-bootstrap
40
        echo $1=$2 >>~/.lemon-bootstrap
41
    fi
42
}
43

	
44
augment_config LEMON_INSTALL_PREFIX /usr/local \
45
    "# LEMON installation prefix"
46

	
47
augment_config COIN_OR_PREFIX /usr/local/coin-or \
48
    "# COIN-OR installation root prefix (used for CLP/CBC)"
49

	
50
augment_config SOPLEX_PREFIX /usr/local/soplex \
51
    "# Soplex build prefix"
52

	
53

	
54
function ask() {
55
echo -n "$1 [$2]? "
56
read _an
57
if [ "x$_an" == "x" ]; then
58
    ret="$2"
59
else
60
    ret=$_an
61
fi
62
}
63

	
64
function yesorno() {
65
    ret='rossz'
66
    while [ "$ret" != "y" -a "$ret" != "n" -a "$ret" != "yes" -a "$ret" != "no" ]; do
67
        ask "$1" "$2"
68
    done
69
    if [ "$ret" != "y" -a "$ret" != "yes" ]; then
70
        return 1
71
    else
72
        return 0
73
    fi
74
}
75

	
76
if yesorno "External build" "n"
77
then
78
    CONFIGURE_PATH=".."
79
else
80
    CONFIGURE_PATH="."
81
    if yesorno "Autoreconf" "y"
82
    then
83
        AUTORE=yes
84
    else
85
        AUTORE=no
86
    fi
87
fi
88

	
89
if yesorno "Optimize" "n" 
90
then
91
    opt_flags=' -O2'
92
else
93
    opt_flags=''
94
fi
95

	
96
if yesorno "Stop on warning" "y" 
97
then
98
    werror_flags=' -Werror'
99
else
100
    werror_flags=''
101
fi
102

	
103
cxx_flags="CXXFLAGS=-ggdb$opt_flags$werror_flags"
104

	
105
if [ -f ${COIN_OR_PREFIX}/include/coin/config_coinutils.h ]; then
106
    if yesorno "Use COIN-OR (CBC/CLP)" "n"
107
    then
108
        coin_flag="--with-coin=$COIN_OR_PREFIX"
109
    else
110
        coin_flag=""
111
    fi
112
else
113
    coin_flag=""        
114
fi
115

	
116
if [ -f ${SOPLEX_PREFIX}/src/soplex.h ]; then
117
    if yesorno "Use Soplex" "n"
118
    then
119
        soplex_flag="--with-soplex=$SOPLEX_PREFIX"
120
    else
121
        soplex_flag=""
122
    fi
123
else
124
    soplex_flag=""
125
fi
126

	
127
if [ "x$AUTORE" == "xyes" ]; then
128
    autoreconf -vif;
129
fi
130
${CONFIGURE_PATH}/configure --prefix=$LEMON_INSTALL_PREFIX \
131
"$cxx_flags" \
132
$coin_flag \
133
$soplex_flag \
134
$*
Ignore white space 6 line context
1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2
 *
3
 * This file is a part of LEMON, a generic C++ optimization library.
4
 *
5
 * Copyright (C) 2003-2009
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 <iostream>
20
#include <sstream>
21

	
22
#include <lemon/smart_graph.h>
23
#include <lemon/lgf_reader.h>
24
#include <lemon/path.h>
25
#include <lemon/concepts/digraph.h>
26
#include <lemon/concept_check.h>
27

	
28
#include <lemon/karp.h>
29
#include <lemon/hartmann_orlin.h>
30
#include <lemon/howard.h>
31

	
32
#include "test_tools.h"
33

	
34
using namespace lemon;
35

	
36
char test_lgf[] =
37
  "@nodes\n"
38
  "label\n"
39
  "1\n"
40
  "2\n"
41
  "3\n"
42
  "4\n"
43
  "5\n"
44
  "6\n"
45
  "7\n"
46
  "@arcs\n"
47
  "    len1 len2 len3 len4  c1 c2 c3 c4\n"
48
  "1 2    1    1    1    1   0  0  0  0\n"
49
  "2 4    5    5    5    5   1  0  0  0\n"
50
  "2 3    8    8    8    8   0  0  0  0\n"
51
  "3 2   -2    0    0    0   1  0  0  0\n"
52
  "3 4    4    4    4    4   0  0  0  0\n"
53
  "3 7   -4   -4   -4   -4   0  0  0  0\n"
54
  "4 1    2    2    2    2   0  0  0  0\n"
55
  "4 3    3    3    3    3   1  0  0  0\n"
56
  "4 4    3    3    0    0   0  0  1  0\n"
57
  "5 2    4    4    4    4   0  0  0  0\n"
58
  "5 6    3    3    3    3   0  1  0  0\n"
59
  "6 5    2    2    2    2   0  1  0  0\n"
60
  "6 4   -1   -1   -1   -1   0  0  0  0\n"
61
  "6 7    1    1    1    1   0  0  0  0\n"
62
  "7 7    4    4    4   -1   0  0  0  1\n";
63

	
64
                        
65
// Check the interface of an MMC algorithm
66
template <typename GR, typename Value>
67
struct MmcClassConcept
68
{
69
  template <typename MMC>
70
  struct Constraints {
71
    void constraints() {
72
      const Constraints& me = *this;
73

	
74
      typedef typename MMC
75
        ::template SetPath<ListPath<GR> >
76
        ::template SetLargeValue<Value>
77
        ::Create MmcAlg;
78
      MmcAlg mmc(me.g, me.length);
79
      const MmcAlg& const_mmc = mmc;
80
      
81
      typename MmcAlg::Tolerance tol = const_mmc.tolerance();
82
      mmc.tolerance(tol);
83
      
84
      b = mmc.cycle(p).run();
85
      b = mmc.findMinMean();
86
      b = mmc.findCycle();
87

	
88
      v = const_mmc.cycleLength();
89
      i = const_mmc.cycleArcNum();
90
      d = const_mmc.cycleMean();
91
      p = const_mmc.cycle();
92
    }
93

	
94
    typedef concepts::ReadMap<typename GR::Arc, Value> LM;
95
  
96
    GR g;
97
    LM length;
98
    ListPath<GR> p;
99
    Value v;
100
    int i;
101
    double d;
102
    bool b;
103
  };
104
};
105

	
106
// Perform a test with the given parameters
107
template <typename MMC>
108
void checkMmcAlg(const SmartDigraph& gr,
109
                 const SmartDigraph::ArcMap<int>& lm,
110
                 const SmartDigraph::ArcMap<int>& cm,
111
                 int length, int size) {
112
  MMC alg(gr, lm);
113
  alg.findMinMean();
114
  check(alg.cycleMean() == static_cast<double>(length) / size,
115
        "Wrong cycle mean");
116
  alg.findCycle();
117
  check(alg.cycleLength() == length && alg.cycleArcNum() == size,
118
        "Wrong path");
119
  SmartDigraph::ArcMap<int> cycle(gr, 0);
120
  for (typename MMC::Path::ArcIt a(alg.cycle()); a != INVALID; ++a) {
121
    ++cycle[a];
122
  }
123
  for (SmartDigraph::ArcIt a(gr); a != INVALID; ++a) {
124
    check(cm[a] == cycle[a], "Wrong path");
125
  }
126
}
127

	
128
// Class for comparing types
129
template <typename T1, typename T2>
130
struct IsSameType {
131
  static const int result = 0;
132
};
133

	
134
template <typename T>
135
struct IsSameType<T,T> {
136
  static const int result = 1;
137
};
138

	
139

	
140
int main() {
141
  #ifdef LEMON_HAVE_LONG_LONG
142
    typedef long long long_int;
143
  #else
144
    typedef long long_int;
145
  #endif
146

	
147
  // Check the interface
148
  {
149
    typedef concepts::Digraph GR;
150

	
151
    // Karp
152
    checkConcept< MmcClassConcept<GR, int>,
153
                  Karp<GR, concepts::ReadMap<GR::Arc, int> > >();
154
    checkConcept< MmcClassConcept<GR, float>,
155
                  Karp<GR, concepts::ReadMap<GR::Arc, float> > >();
156
    
157
    // HartmannOrlin
158
    checkConcept< MmcClassConcept<GR, int>,
159
                  HartmannOrlin<GR, concepts::ReadMap<GR::Arc, int> > >();
160
    checkConcept< MmcClassConcept<GR, float>,
161
                  HartmannOrlin<GR, concepts::ReadMap<GR::Arc, float> > >();
162
    
163
    // Howard
164
    checkConcept< MmcClassConcept<GR, int>,
165
                  Howard<GR, concepts::ReadMap<GR::Arc, int> > >();
166
    checkConcept< MmcClassConcept<GR, float>,
167
                  Howard<GR, concepts::ReadMap<GR::Arc, float> > >();
168

	
169
    if (IsSameType<Howard<GR, concepts::ReadMap<GR::Arc, int> >::LargeValue,
170
          long_int>::result == 0) check(false, "Wrong LargeValue type");
171
    if (IsSameType<Howard<GR, concepts::ReadMap<GR::Arc, float> >::LargeValue,
172
          double>::result == 0) check(false, "Wrong LargeValue type");
173
  }
174

	
175
  // Run various tests
176
  {
177
    typedef SmartDigraph GR;
178
    DIGRAPH_TYPEDEFS(GR);
179
    
180
    GR gr;
181
    IntArcMap l1(gr), l2(gr), l3(gr), l4(gr);
182
    IntArcMap c1(gr), c2(gr), c3(gr), c4(gr);
183
    
184
    std::istringstream input(test_lgf);
185
    digraphReader(gr, input).
186
      arcMap("len1", l1).
187
      arcMap("len2", l2).
188
      arcMap("len3", l3).
189
      arcMap("len4", l4).
190
      arcMap("c1", c1).
191
      arcMap("c2", c2).
192
      arcMap("c3", c3).
193
      arcMap("c4", c4).
194
      run();
195

	
196
    // Karp
197
    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l1, c1,  6, 3);
198
    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l2, c2,  5, 2);
199
    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l3, c3,  0, 1);
200
    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l4, c4, -1, 1);
201

	
202
    // HartmannOrlin
203
    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l1, c1,  6, 3);
204
    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l2, c2,  5, 2);
205
    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l3, c3,  0, 1);
206
    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l4, c4, -1, 1);
207

	
208
    // Howard
209
    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l1, c1,  6, 3);
210
    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l2, c2,  5, 2);
211
    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l3, c3,  0, 1);
212
    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l4, c4, -1, 1);
213
  }
214

	
215
  return 0;
216
}
Ignore white space 6 line context
1 1
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
2 2

	
3 3
SET(PROJECT_NAME "LEMON")
4 4
PROJECT(${PROJECT_NAME})
5 5

	
6 6
IF(EXISTS ${PROJECT_SOURCE_DIR}/cmake/version.cmake)
7 7
  INCLUDE(${PROJECT_SOURCE_DIR}/cmake/version.cmake)
8 8
ELSEIF(DEFINED ENV{LEMON_VERSION})
9 9
  SET(LEMON_VERSION $ENV{LEMON_VERSION} CACHE STRING "LEMON version string.")
10 10
ELSE()
11 11
  EXECUTE_PROCESS(
12 12
    COMMAND hg id -i
13 13
    WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
14 14
    OUTPUT_VARIABLE HG_REVISION
15 15
    ERROR_QUIET
16 16
    OUTPUT_STRIP_TRAILING_WHITESPACE
17 17
  )
18 18
  IF(HG_REVISION STREQUAL "")
19 19
    SET(HG_REVISION "hg-tip")
20 20
  ENDIF()
21 21
  SET(LEMON_VERSION ${HG_REVISION} CACHE STRING "LEMON version string.")
22 22
ENDIF()
23 23

	
24 24
SET(PROJECT_VERSION ${LEMON_VERSION})
25 25

	
26 26
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
27 27

	
28 28
FIND_PACKAGE(Doxygen)
29 29
FIND_PACKAGE(Ghostscript)
30 30
FIND_PACKAGE(GLPK 4.33)
31 31
FIND_PACKAGE(CPLEX)
32 32
FIND_PACKAGE(COIN)
33 33

	
34 34
INCLUDE(CheckTypeSize)
35 35
CHECK_TYPE_SIZE("long long" LONG_LONG)
36 36
SET(LEMON_HAVE_LONG_LONG ${HAVE_LONG_LONG})
37 37

	
38
INCLUDE(FindPythonInterp)
39

	
38 40
ENABLE_TESTING()
39 41

	
40 42
ADD_SUBDIRECTORY(lemon)
41 43
IF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR})
42 44
  ADD_SUBDIRECTORY(demo)
43 45
  ADD_SUBDIRECTORY(tools)
44 46
  ADD_SUBDIRECTORY(doc)
45 47
  ADD_SUBDIRECTORY(test)
46 48
ENDIF()
47 49

	
48 50
CONFIGURE_FILE(
49 51
  ${PROJECT_SOURCE_DIR}/cmake/LEMONConfig.cmake.in
50 52
  ${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake
51 53
  @ONLY
52 54
)
53 55
IF(UNIX)
54 56
  INSTALL(
55 57
    FILES ${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake
56 58
    DESTINATION share/lemon/cmake
57 59
  )
58 60
ELSEIF(WIN32)
59 61
  INSTALL(
60 62
    FILES ${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake
61 63
    DESTINATION cmake
62 64
  )
63 65
ENDIF()
64 66

	
65 67
IF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR} AND WIN32)
66 68
  SET(CPACK_PACKAGE_NAME ${PROJECT_NAME})
67 69
  SET(CPACK_PACKAGE_VENDOR "EGRES")
68 70
  SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY
69 71
    "LEMON - Library for Efficient Modeling and Optimization in Networks")
70 72
  SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
71 73

	
72 74
  SET(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
73 75

	
74 76
  SET(CPACK_PACKAGE_INSTALL_DIRECTORY
75 77
    "${PROJECT_NAME} ${PROJECT_VERSION}")
76 78
  SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY
77 79
    "${PROJECT_NAME} ${PROJECT_VERSION}")
78 80

	
79 81
  SET(CPACK_COMPONENTS_ALL headers library html_documentation bin)
80 82

	
81 83
  SET(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C++ headers")
82 84
  SET(CPACK_COMPONENT_LIBRARY_DISPLAY_NAME "Dynamic-link library")
83 85
  SET(CPACK_COMPONENT_BIN_DISPLAY_NAME "Command line utilities")
84 86
  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DISPLAY_NAME "HTML documentation")
85 87

	
86 88
  SET(CPACK_COMPONENT_HEADERS_DESCRIPTION
87 89
    "C++ header files")
88 90
  SET(CPACK_COMPONENT_LIBRARY_DESCRIPTION
89 91
    "DLL and import library")
90 92
  SET(CPACK_COMPONENT_BIN_DESCRIPTION
91 93
    "Command line utilities")
92 94
  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DESCRIPTION
93 95
    "Doxygen generated documentation")
94 96

	
95 97
  SET(CPACK_COMPONENT_HEADERS_DEPENDS library)
96 98

	
97 99
  SET(CPACK_COMPONENT_HEADERS_GROUP "Development")
98 100
  SET(CPACK_COMPONENT_LIBRARY_GROUP "Development")
99 101
  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_GROUP "Documentation")
100 102

	
101 103
  SET(CPACK_COMPONENT_GROUP_DEVELOPMENT_DESCRIPTION
Ignore white space 6 line context
1 1
ACLOCAL_AMFLAGS = -I m4
2 2

	
3 3
AM_CXXFLAGS = $(WARNINGCXXFLAGS)
4 4

	
5 5
AM_CPPFLAGS = -I$(top_srcdir) -I$(top_builddir)
6 6
LDADD = $(top_builddir)/lemon/libemon.la
7 7

	
8 8
EXTRA_DIST = \
9 9
	AUTHORS \
10 10
	LICENSE \
11 11
	m4/lx_check_cplex.m4 \
12 12
	m4/lx_check_glpk.m4 \
13 13
	m4/lx_check_soplex.m4 \
14 14
	m4/lx_check_coin.m4 \
15 15
	CMakeLists.txt \
16 16
	cmake/FindGhostscript.cmake \
17 17
	cmake/FindCPLEX.cmake \
18 18
	cmake/FindGLPK.cmake \
19 19
	cmake/FindCOIN.cmake \
20
	cmake/LEMONConfig.cmake.in \
20 21
	cmake/version.cmake.in \
21 22
	cmake/version.cmake \
22 23
	cmake/nsis/lemon.ico \
23 24
	cmake/nsis/uninstall.ico
24 25

	
25 26
pkgconfigdir = $(libdir)/pkgconfig
26 27
lemondir = $(pkgincludedir)
27 28
bitsdir = $(lemondir)/bits
28 29
conceptdir = $(lemondir)/concepts
29 30
pkgconfig_DATA =
30 31
lib_LTLIBRARIES =
31 32
lemon_HEADERS =
32 33
bits_HEADERS =
33 34
concept_HEADERS =
34 35
noinst_HEADERS =
35 36
noinst_PROGRAMS =
36 37
bin_PROGRAMS =
37 38
check_PROGRAMS =
38 39
dist_bin_SCRIPTS =
39 40
TESTS =
40 41
XFAIL_TESTS =
41 42

	
42 43
include lemon/Makefile.am
43 44
include test/Makefile.am
44 45
include doc/Makefile.am
45 46
include tools/Makefile.am
46 47

	
47 48
DIST_SUBDIRS = demo
48 49

	
49 50
demo:
50 51
	$(MAKE) $(AM_MAKEFLAGS) -C demo
51 52

	
52 53
MRPROPERFILES = \
53 54
	aclocal.m4 \
54 55
	config.h.in \
55 56
	config.h.in~ \
56 57
	configure \
57 58
	Makefile.in \
58 59
	build-aux/config.guess \
59 60
	build-aux/config.sub \
60 61
	build-aux/depcomp \
61 62
	build-aux/install-sh \
62 63
	build-aux/ltmain.sh \
63 64
	build-aux/missing \
64 65
	doc/doxygen.log
65 66

	
66 67
mrproper:
67 68
	$(MAKE) $(AM_MAKEFLAGS) maintainer-clean
68 69
	-rm -f $(MRPROPERFILES)
69 70

	
70 71
dist-bz2: dist
71 72
	zcat $(PACKAGE)-$(VERSION).tar.gz | \
72 73
	bzip2 --best -c > $(PACKAGE)-$(VERSION).tar.bz2
73 74

	
74 75
distcheck-bz2: distcheck
75 76
	zcat $(PACKAGE)-$(VERSION).tar.gz | \
76 77
	bzip2 --best -c > $(PACKAGE)-$(VERSION).tar.bz2
77 78

	
78 79
.PHONY: demo mrproper dist-bz2 distcheck-bz2
Ignore white space 6 line context
1 1
dnl Process this file with autoconf to produce a configure script.
2 2

	
3 3
dnl Version information.
4 4
m4_define([lemon_version_number],
5 5
          [m4_normalize(esyscmd([echo ${LEMON_VERSION}]))])
6 6
dnl m4_define([lemon_version_number], [])
7 7
m4_define([lemon_hg_path], [m4_normalize(esyscmd([./scripts/chg-len.py]))])
8 8
m4_define([lemon_hg_revision], [m4_normalize(esyscmd([hg id -i 2> /dev/null]))])
9 9
m4_define([lemon_version], [ifelse(lemon_version_number(),
10 10
                           [],
11 11
                           [ifelse(lemon_hg_revision(),
12 12
                           [],
13 13
                           [hg-tip],
14 14
                           [lemon_hg_path().lemon_hg_revision()])],
15 15
                           [lemon_version_number()])])
16 16

	
17 17
AC_PREREQ([2.59])
18 18
AC_INIT([LEMON], [lemon_version()], [lemon-user@lemon.cs.elte.hu], [lemon])
19 19
AC_CONFIG_AUX_DIR([build-aux])
20 20
AC_CONFIG_MACRO_DIR([m4])
21 21
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects nostdinc])
22 22
AC_CONFIG_SRCDIR([lemon/list_graph.h])
23 23
AC_CONFIG_HEADERS([config.h lemon/config.h])
24 24

	
25 25
AC_DEFINE([LEMON_VERSION], [lemon_version()], [The version string])
26 26

	
27 27
dnl Do compilation tests using the C++ compiler.
28 28
AC_LANG([C++])
29 29

	
30 30
dnl Check the existence of long long type.
31 31
AC_CHECK_TYPE(long long, [long_long_found=yes], [long_long_found=no])
32 32
if test x"$long_long_found" = x"yes"; then
33 33
  AC_DEFINE([LEMON_HAVE_LONG_LONG], [1], [Define to 1 if you have long long.])
34 34
fi
35 35

	
36 36
dnl Checks for programs.
37 37
AC_PROG_CXX
38 38
AC_PROG_CXXCPP
39 39
AC_PROG_INSTALL
40 40
AC_DISABLE_SHARED
41 41
AC_PROG_LIBTOOL
42 42

	
43 43
AC_CHECK_PROG([doxygen_found],[doxygen],[yes],[no])
44
AC_CHECK_PROG([python_found],[python],[yes],[no])
44 45
AC_CHECK_PROG([gs_found],[gs],[yes],[no])
45 46

	
46 47
dnl Detect Intel compiler.
47 48
AC_MSG_CHECKING([whether we are using the Intel C++ compiler])
48 49
AC_COMPILE_IFELSE([#ifndef __INTEL_COMPILER
49 50
choke me
50 51
#endif], [ICC=[yes]], [ICC=[no]])
51 52
if test x"$ICC" = x"yes"; then
52 53
  AC_MSG_RESULT([yes])
53 54
else
54 55
  AC_MSG_RESULT([no])
55 56
fi
56 57

	
57 58
dnl Set custom compiler flags when using g++.
58 59
if test "$GXX" = yes -a "$ICC" = no; then
59 60
  WARNINGCXXFLAGS="-Wall -W -Wall -W -Wunused -Wformat=2 -Wctor-dtor-privacy -Wnon-virtual-dtor -Wno-char-subscripts -Wwrite-strings -Wno-char-subscripts -Wreturn-type -Wcast-qual -Wcast-align -Wsign-promo -Woverloaded-virtual -ansi -fno-strict-aliasing -Wold-style-cast -Wno-unknown-pragmas"
60 61
fi
61 62
AC_SUBST([WARNINGCXXFLAGS])
62 63

	
63 64
dnl Checks for libraries.
64 65
LX_CHECK_GLPK
65 66
LX_CHECK_CPLEX
66 67
LX_CHECK_SOPLEX
67 68
LX_CHECK_COIN
68 69

	
69 70
AM_CONDITIONAL([HAVE_LP], [test x"$lx_lp_found" = x"yes"])
70 71
AM_CONDITIONAL([HAVE_MIP], [test x"$lx_mip_found" = x"yes"])
71 72

	
72 73
dnl Disable/enable building the binary tools.
73 74
AC_ARG_ENABLE([tools],
74 75
AS_HELP_STRING([--enable-tools], [build additional tools @<:@default@:>@])
75 76
AS_HELP_STRING([--disable-tools], [do not build additional tools]),
76 77
              [], [enable_tools=yes])
77 78
AC_MSG_CHECKING([whether to build the additional tools])
78 79
if test x"$enable_tools" != x"no"; then
79 80
  AC_MSG_RESULT([yes])
80 81
else
81 82
  AC_MSG_RESULT([no])
82 83
fi
83 84
AM_CONDITIONAL([WANT_TOOLS], [test x"$enable_tools" != x"no"])
84 85

	
85 86
dnl Checks for header files.
86 87
AC_CHECK_HEADERS(limits.h sys/time.h sys/times.h unistd.h)
87 88

	
88 89
dnl Checks for typedefs, structures, and compiler characteristics.
89 90
AC_C_CONST
90 91
AC_C_INLINE
91 92
AC_TYPE_SIZE_T
92 93
AC_HEADER_TIME
93 94
AC_STRUCT_TM
94 95

	
95 96
dnl Checks for library functions.
96 97
AC_HEADER_STDC
97 98
AC_CHECK_FUNCS(gettimeofday times ctime_r)
98 99

	
99 100
dnl Add dependencies on files generated by configure.
100 101
AC_SUBST([CONFIG_STATUS_DEPENDENCIES],
101 102
  ['$(top_srcdir)/doc/Doxyfile.in $(top_srcdir)/lemon/lemon.pc.in $(top_srcdir)/cmake/version.cmake.in'])
102 103

	
103 104
AC_CONFIG_FILES([
104 105
Makefile
105 106
demo/Makefile
106 107
cmake/version.cmake
107 108
doc/Doxyfile
Ignore white space 6 line context
1 1
SET(PACKAGE_NAME ${PROJECT_NAME})
2 2
SET(PACKAGE_VERSION ${PROJECT_VERSION})
3 3
SET(abs_top_srcdir ${PROJECT_SOURCE_DIR})
4 4
SET(abs_top_builddir ${PROJECT_BINARY_DIR})
5 5

	
6 6
CONFIGURE_FILE(
7 7
  ${PROJECT_SOURCE_DIR}/doc/Doxyfile.in
8 8
  ${PROJECT_BINARY_DIR}/doc/Doxyfile
9 9
  @ONLY
10 10
)
11 11

	
12
IF(DOXYGEN_EXECUTABLE AND GHOSTSCRIPT_EXECUTABLE)
12
IF(DOXYGEN_EXECUTABLE AND PYTHONINTERP_FOUND AND GHOSTSCRIPT_EXECUTABLE)
13 13
  FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/)
14 14
  SET(GHOSTSCRIPT_OPTIONS -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha)
15 15
  ADD_CUSTOM_TARGET(html
16 16
    COMMAND ${CMAKE_COMMAND} -E remove_directory gen-images
17 17
    COMMAND ${CMAKE_COMMAND} -E make_directory gen-images
18 18
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/bipartite_matching.png ${CMAKE_CURRENT_SOURCE_DIR}/images/bipartite_matching.eps
19 19
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/bipartite_partitions.png ${CMAKE_CURRENT_SOURCE_DIR}/images/bipartite_partitions.eps
20 20
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/connected_components.eps
21 21
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/edge_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/edge_biconnected_components.eps
22 22
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/grid_graph.png ${CMAKE_CURRENT_SOURCE_DIR}/images/grid_graph.eps
23 23
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/node_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/node_biconnected_components.eps
24 24
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_0.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_0.eps
25 25
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_1.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_1.eps
26 26
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_2.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_2.eps
27 27
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_3.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_3.eps
28 28
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_4.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_4.eps
29 29
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/strongly_connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/strongly_connected_components.eps
30 30
    COMMAND ${CMAKE_COMMAND} -E remove_directory html
31
    COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/bib2dox.py ${CMAKE_CURRENT_SOURCE_DIR}/references.bib >references.dox
31 32
    COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
32 33
    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
33 34
  )
34 35

	
35 36
  SET_TARGET_PROPERTIES(html PROPERTIES PROJECT_LABEL BUILD_DOC)
36 37

	
37 38
  IF(UNIX)
38 39
    INSTALL(
39 40
      DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/
40 41
      DESTINATION share/doc/lemon/html
41 42
      COMPONENT html_documentation
42 43
    )
43 44
  ELSEIF(WIN32)
44 45
    INSTALL(
45 46
      DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/
46 47
      DESTINATION doc
47 48
      COMPONENT html_documentation
48 49
    )
49 50
  ENDIF()
50 51

	
51 52
ENDIF()
Ignore white space 6 line context
1
# Doxyfile 1.5.7.1
1
# Doxyfile 1.5.9
2 2

	
3 3
#---------------------------------------------------------------------------
4 4
# Project related configuration options
5 5
#---------------------------------------------------------------------------
6 6
DOXYFILE_ENCODING      = UTF-8
7 7
PROJECT_NAME           = @PACKAGE_NAME@
8 8
PROJECT_NUMBER         = @PACKAGE_VERSION@
9 9
OUTPUT_DIRECTORY       = 
10 10
CREATE_SUBDIRS         = NO
11 11
OUTPUT_LANGUAGE        = English
12 12
BRIEF_MEMBER_DESC      = YES
13 13
REPEAT_BRIEF           = NO
14 14
ABBREVIATE_BRIEF       = 
15 15
ALWAYS_DETAILED_SEC    = NO
16 16
INLINE_INHERITED_MEMB  = NO
17 17
FULL_PATH_NAMES        = YES
18 18
STRIP_FROM_PATH        = "@abs_top_srcdir@"
19 19
STRIP_FROM_INC_PATH    = "@abs_top_srcdir@"
20 20
SHORT_NAMES            = YES
21 21
JAVADOC_AUTOBRIEF      = NO
22 22
QT_AUTOBRIEF           = NO
23 23
MULTILINE_CPP_IS_BRIEF = NO
24
DETAILS_AT_TOP         = YES
25 24
INHERIT_DOCS           = NO
26 25
SEPARATE_MEMBER_PAGES  = NO
27 26
TAB_SIZE               = 8
28 27
ALIASES                = 
29 28
OPTIMIZE_OUTPUT_FOR_C  = NO
30 29
OPTIMIZE_OUTPUT_JAVA   = NO
31 30
OPTIMIZE_FOR_FORTRAN   = NO
32 31
OPTIMIZE_OUTPUT_VHDL   = NO
33 32
BUILTIN_STL_SUPPORT    = YES
34 33
CPP_CLI_SUPPORT        = NO
35 34
SIP_SUPPORT            = NO
36 35
IDL_PROPERTY_SUPPORT   = YES
37 36
DISTRIBUTE_GROUP_DOC   = NO
38 37
SUBGROUPING            = YES
39 38
TYPEDEF_HIDES_STRUCT   = NO
40 39
SYMBOL_CACHE_SIZE      = 0
41 40
#---------------------------------------------------------------------------
42 41
# Build related configuration options
43 42
#---------------------------------------------------------------------------
44 43
EXTRACT_ALL            = NO
45 44
EXTRACT_PRIVATE        = YES
46 45
EXTRACT_STATIC         = YES
47 46
EXTRACT_LOCAL_CLASSES  = NO
48 47
EXTRACT_LOCAL_METHODS  = NO
49 48
EXTRACT_ANON_NSPACES   = NO
50 49
HIDE_UNDOC_MEMBERS     = YES
51 50
HIDE_UNDOC_CLASSES     = YES
52 51
HIDE_FRIEND_COMPOUNDS  = NO
53 52
HIDE_IN_BODY_DOCS      = NO
54 53
INTERNAL_DOCS          = NO
55 54
CASE_SENSE_NAMES       = YES
56 55
HIDE_SCOPE_NAMES       = YES
57 56
SHOW_INCLUDE_FILES     = YES
58 57
INLINE_INFO            = YES
59 58
SORT_MEMBER_DOCS       = NO
60 59
SORT_BRIEF_DOCS        = NO
61 60
SORT_GROUP_NAMES       = NO
62 61
SORT_BY_SCOPE_NAME     = NO
63 62
GENERATE_TODOLIST      = YES
64 63
GENERATE_TESTLIST      = YES
65 64
GENERATE_BUGLIST       = YES
66 65
GENERATE_DEPRECATEDLIST= YES
67 66
ENABLED_SECTIONS       = 
68 67
MAX_INITIALIZER_LINES  = 5
69 68
SHOW_USED_FILES        = NO
70 69
SHOW_DIRECTORIES       = YES
71 70
SHOW_FILES             = YES
72 71
SHOW_NAMESPACES        = YES
73 72
FILE_VERSION_FILTER    = 
74 73
LAYOUT_FILE            = DoxygenLayout.xml
75 74
#---------------------------------------------------------------------------
76 75
# configuration options related to warning and progress messages
77 76
#---------------------------------------------------------------------------
78 77
QUIET                  = NO
79 78
WARNINGS               = YES
80 79
WARN_IF_UNDOCUMENTED   = YES
81 80
WARN_IF_DOC_ERROR      = YES
82 81
WARN_NO_PARAMDOC       = NO
83 82
WARN_FORMAT            = "$file:$line: $text"
84 83
WARN_LOGFILE           = doxygen.log
85 84
#---------------------------------------------------------------------------
86 85
# configuration options related to the input files
87 86
#---------------------------------------------------------------------------
88 87
INPUT                  = "@abs_top_srcdir@/doc" \
89 88
                         "@abs_top_srcdir@/lemon" \
90 89
                         "@abs_top_srcdir@/lemon/bits" \
91 90
                         "@abs_top_srcdir@/lemon/concepts" \
92 91
                         "@abs_top_srcdir@/demo" \
93 92
                         "@abs_top_srcdir@/tools" \
94
                         "@abs_top_srcdir@/test/test_tools.h"
93
                         "@abs_top_srcdir@/test/test_tools.h" \
94
                         "@abs_top_builddir@/doc/references.dox"
95 95
INPUT_ENCODING         = UTF-8
96 96
FILE_PATTERNS          = *.h \
97 97
                         *.cc \
98 98
                         *.dox
99 99
RECURSIVE              = NO
100 100
EXCLUDE                = 
101 101
EXCLUDE_SYMLINKS       = NO
102 102
EXCLUDE_PATTERNS       = 
103 103
EXCLUDE_SYMBOLS        = 
104 104
EXAMPLE_PATH           = "@abs_top_srcdir@/demo" \
105 105
                         "@abs_top_srcdir@/LICENSE" \
106 106
                         "@abs_top_srcdir@/doc"
107 107
EXAMPLE_PATTERNS       = 
108 108
EXAMPLE_RECURSIVE      = NO
109 109
IMAGE_PATH             = "@abs_top_srcdir@/doc/images" \
110 110
                         "@abs_top_builddir@/doc/gen-images"
111 111
INPUT_FILTER           = 
112 112
FILTER_PATTERNS        = 
113 113
FILTER_SOURCE_FILES    = NO
114 114
#---------------------------------------------------------------------------
115 115
# configuration options related to source browsing
116 116
#---------------------------------------------------------------------------
117 117
SOURCE_BROWSER         = NO
118 118
INLINE_SOURCES         = NO
119 119
STRIP_CODE_COMMENTS    = YES
120 120
REFERENCED_BY_RELATION = NO
121 121
REFERENCES_RELATION    = NO
122 122
REFERENCES_LINK_SOURCE = YES
123 123
USE_HTAGS              = NO
124 124
VERBATIM_HEADERS       = NO
125 125
#---------------------------------------------------------------------------
126 126
# configuration options related to the alphabetical class index
127 127
#---------------------------------------------------------------------------
128 128
ALPHABETICAL_INDEX     = YES
129 129
COLS_IN_ALPHA_INDEX    = 2
130 130
IGNORE_PREFIX          = 
131 131
#---------------------------------------------------------------------------
132 132
# configuration options related to the HTML output
133 133
#---------------------------------------------------------------------------
134 134
GENERATE_HTML          = YES
135 135
HTML_OUTPUT            = html
136 136
HTML_FILE_EXTENSION    = .html
137 137
HTML_HEADER            = 
138 138
HTML_FOOTER            = 
139 139
HTML_STYLESHEET        = 
140 140
HTML_ALIGN_MEMBERS     = YES
141 141
HTML_DYNAMIC_SECTIONS  = NO
142 142
GENERATE_DOCSET        = NO
143 143
DOCSET_FEEDNAME        = "Doxygen generated docs"
144 144
DOCSET_BUNDLE_ID       = org.doxygen.Project
145 145
GENERATE_HTMLHELP      = NO
146 146
CHM_FILE               = 
147 147
HHC_LOCATION           = 
148 148
GENERATE_CHI           = NO
149 149
CHM_INDEX_ENCODING     = 
150 150
BINARY_TOC             = NO
151 151
TOC_EXPAND             = NO
152 152
GENERATE_QHP           = NO
153 153
QCH_FILE               = 
154 154
QHP_NAMESPACE          = org.doxygen.Project
155 155
QHP_VIRTUAL_FOLDER     = doc
156 156
QHG_LOCATION           = 
157 157
DISABLE_INDEX          = NO
158 158
ENUM_VALUES_PER_LINE   = 4
... ...
@@ -162,105 +162,105 @@
162 162
#---------------------------------------------------------------------------
163 163
# configuration options related to the LaTeX output
164 164
#---------------------------------------------------------------------------
165 165
GENERATE_LATEX         = NO
166 166
LATEX_OUTPUT           = latex
167 167
LATEX_CMD_NAME         = latex
168 168
MAKEINDEX_CMD_NAME     = makeindex
169 169
COMPACT_LATEX          = YES
170 170
PAPER_TYPE             = a4wide
171 171
EXTRA_PACKAGES         = amsmath \
172 172
                         amssymb
173 173
LATEX_HEADER           = 
174 174
PDF_HYPERLINKS         = YES
175 175
USE_PDFLATEX           = YES
176 176
LATEX_BATCHMODE        = NO
177 177
LATEX_HIDE_INDICES     = NO
178 178
#---------------------------------------------------------------------------
179 179
# configuration options related to the RTF output
180 180
#---------------------------------------------------------------------------
181 181
GENERATE_RTF           = NO
182 182
RTF_OUTPUT             = rtf
183 183
COMPACT_RTF            = NO
184 184
RTF_HYPERLINKS         = NO
185 185
RTF_STYLESHEET_FILE    = 
186 186
RTF_EXTENSIONS_FILE    = 
187 187
#---------------------------------------------------------------------------
188 188
# configuration options related to the man page output
189 189
#---------------------------------------------------------------------------
190 190
GENERATE_MAN           = NO
191 191
MAN_OUTPUT             = man
192 192
MAN_EXTENSION          = .3
193 193
MAN_LINKS              = NO
194 194
#---------------------------------------------------------------------------
195 195
# configuration options related to the XML output
196 196
#---------------------------------------------------------------------------
197 197
GENERATE_XML           = NO
198 198
XML_OUTPUT             = xml
199 199
XML_SCHEMA             = 
200 200
XML_DTD                = 
201 201
XML_PROGRAMLISTING     = YES
202 202
#---------------------------------------------------------------------------
203 203
# configuration options for the AutoGen Definitions output
204 204
#---------------------------------------------------------------------------
205 205
GENERATE_AUTOGEN_DEF   = NO
206 206
#---------------------------------------------------------------------------
207 207
# configuration options related to the Perl module output
208 208
#---------------------------------------------------------------------------
209 209
GENERATE_PERLMOD       = NO
210 210
PERLMOD_LATEX          = NO
211 211
PERLMOD_PRETTY         = YES
212 212
PERLMOD_MAKEVAR_PREFIX = 
213 213
#---------------------------------------------------------------------------
214 214
# Configuration options related to the preprocessor   
215 215
#---------------------------------------------------------------------------
216 216
ENABLE_PREPROCESSING   = YES
217 217
MACRO_EXPANSION        = NO
218 218
EXPAND_ONLY_PREDEF     = NO
219 219
SEARCH_INCLUDES        = YES
220 220
INCLUDE_PATH           = 
221 221
INCLUDE_FILE_PATTERNS  = 
222 222
PREDEFINED             = DOXYGEN
223 223
EXPAND_AS_DEFINED      = 
224 224
SKIP_FUNCTION_MACROS   = YES
225 225
#---------------------------------------------------------------------------
226
# Configuration::additions related to external references   
226
# Options related to the search engine   
227 227
#---------------------------------------------------------------------------
228 228
TAGFILES               = "@abs_top_srcdir@/doc/libstdc++.tag = http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/  "
229 229
GENERATE_TAGFILE       = html/lemon.tag
230 230
ALLEXTERNALS           = NO
231 231
EXTERNAL_GROUPS        = NO
232 232
PERL_PATH              = /usr/bin/perl
233 233
#---------------------------------------------------------------------------
234 234
# Configuration options related to the dot tool   
235 235
#---------------------------------------------------------------------------
236 236
CLASS_DIAGRAMS         = YES
237 237
MSCGEN_PATH            = 
238 238
HIDE_UNDOC_RELATIONS   = YES
239 239
HAVE_DOT               = YES
240 240
DOT_FONTNAME           = FreeSans
241 241
DOT_FONTSIZE           = 10
242 242
DOT_FONTPATH           = 
243 243
CLASS_GRAPH            = YES
244 244
COLLABORATION_GRAPH    = NO
245 245
GROUP_GRAPHS           = NO
246 246
UML_LOOK               = NO
247 247
TEMPLATE_RELATIONS     = NO
248 248
INCLUDE_GRAPH          = NO
249 249
INCLUDED_BY_GRAPH      = NO
250 250
CALL_GRAPH             = NO
251 251
CALLER_GRAPH           = NO
252 252
GRAPHICAL_HIERARCHY    = NO
253 253
DIRECTORY_GRAPH        = NO
254 254
DOT_IMAGE_FORMAT       = png
255 255
DOT_PATH               = 
256 256
DOTFILE_DIRS           = 
257 257
DOT_GRAPH_MAX_NODES    = 50
258 258
MAX_DOT_GRAPH_DEPTH    = 0
259 259
DOT_TRANSPARENT        = NO
260 260
DOT_MULTI_TARGETS      = NO
261 261
GENERATE_LEGEND        = YES
262 262
DOT_CLEANUP            = YES
263 263
#---------------------------------------------------------------------------
264 264
# Configuration::additions related to the search engine   
265 265
#---------------------------------------------------------------------------
266 266
SEARCHENGINE           = NO
Ignore white space 6 line context
... ...
@@ -5,105 +5,117 @@
5 5
	doc/dirs.dox \
6 6
	doc/groups.dox \
7 7
	doc/lgf.dox \
8 8
	doc/license.dox \
9 9
	doc/mainpage.dox \
10 10
	doc/migration.dox \
11 11
	doc/min_cost_flow.dox \
12 12
	doc/named-param.dox \
13 13
	doc/namespaces.dox \
14 14
	doc/html \
15 15
	doc/CMakeLists.txt
16 16

	
17 17
DOC_EPS_IMAGES18 = \
18 18
	grid_graph.eps \
19 19
	nodeshape_0.eps \
20 20
	nodeshape_1.eps \
21 21
	nodeshape_2.eps \
22 22
	nodeshape_3.eps \
23 23
	nodeshape_4.eps
24 24

	
25 25
DOC_EPS_IMAGES27 = \
26 26
	bipartite_matching.eps \
27 27
	bipartite_partitions.eps \
28 28
	connected_components.eps \
29 29
	edge_biconnected_components.eps \
30 30
	node_biconnected_components.eps \
31 31
	strongly_connected_components.eps
32 32

	
33 33
DOC_EPS_IMAGES = \
34 34
	$(DOC_EPS_IMAGES18) \
35 35
	$(DOC_EPS_IMAGES27)
36 36

	
37 37
DOC_PNG_IMAGES = \
38 38
	$(DOC_EPS_IMAGES:%.eps=doc/gen-images/%.png)
39 39

	
40 40
EXTRA_DIST += $(DOC_EPS_IMAGES:%=doc/images/%)
41 41

	
42 42
doc/html:
43 43
	$(MAKE) $(AM_MAKEFLAGS) html
44 44

	
45 45
GS_COMMAND=gs -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4
46 46

	
47 47
$(DOC_EPS_IMAGES18:%.eps=doc/gen-images/%.png): doc/gen-images/%.png: doc/images/%.eps
48 48
	-mkdir doc/gen-images
49 49
	if test ${gs_found} = yes; then \
50 50
	  $(GS_COMMAND) -sDEVICE=pngalpha -r18 -sOutputFile=$@ $<; \
51 51
	else \
52 52
	  echo; \
53 53
	  echo "Ghostscript not found."; \
54 54
	  echo; \
55 55
	  exit 1; \
56 56
	fi
57 57

	
58 58
$(DOC_EPS_IMAGES27:%.eps=doc/gen-images/%.png): doc/gen-images/%.png: doc/images/%.eps
59 59
	-mkdir doc/gen-images
60 60
	if test ${gs_found} = yes; then \
61 61
	  $(GS_COMMAND) -sDEVICE=pngalpha -r27 -sOutputFile=$@ $<; \
62 62
	else \
63 63
	  echo; \
64 64
	  echo "Ghostscript not found."; \
65 65
	  echo; \
66 66
	  exit 1; \
67 67
	fi
68 68

	
69
html-local: $(DOC_PNG_IMAGES)
69
references.dox: doc/references.bib
70
	if test ${python_found} = yes; then \
71
	  cd doc; \
72
	  python @abs_top_srcdir@/scripts/bib2dox.py @abs_top_builddir@/$< >$@; \
73
	  cd ..; \
74
	else \
75
	  echo; \
76
	  echo "Python not found."; \
77
	  echo; \
78
	  exit 1; \
79
	fi
80

	
81
html-local: $(DOC_PNG_IMAGES) references.dox
70 82
	if test ${doxygen_found} = yes; then \
71 83
	  cd doc; \
72 84
	  doxygen Doxyfile; \
73 85
	  cd ..; \
74 86
	else \
75 87
	  echo; \
76 88
	  echo "Doxygen not found."; \
77 89
	  echo; \
78 90
	  exit 1; \
79 91
	fi
80 92

	
81 93
clean-local:
82 94
	-rm -rf doc/html
83 95
	-rm -f doc/doxygen.log
84 96
	-rm -f $(DOC_PNG_IMAGES)
85 97
	-rm -rf doc/gen-images
86 98

	
87 99
update-external-tags:
88 100
	wget -O doc/libstdc++.tag.tmp http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/libstdc++.tag && \
89 101
	mv doc/libstdc++.tag.tmp doc/libstdc++.tag || \
90 102
	rm doc/libstdc++.tag.tmp
91 103

	
92 104
install-html-local: doc/html
93 105
	@$(NORMAL_INSTALL)
94 106
	$(mkinstalldirs) $(DESTDIR)$(htmldir)/html
95 107
	for p in doc/html/*.{html,css,png,map,gif,tag} ; do \
96 108
	  f="`echo $$p | sed -e 's|^.*/||'`"; \
97 109
	  echo " $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/html/$$f"; \
98 110
	  $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/html/$$f; \
99 111
	done
100 112

	
101 113
uninstall-local:
102 114
	@$(NORMAL_UNINSTALL)
103 115
	for p in doc/html/*.{html,css,png,map,gif,tag} ; do \
104 116
	  f="`echo $$p | sed -e 's|^.*/||'`"; \
105 117
	  echo " rm -f $(DESTDIR)$(htmldir)/html/$$f"; \
106 118
	  rm -f $(DESTDIR)$(htmldir)/html/$$f; \
107 119
	done
108 120

	
109 121
.PHONY: update-external-tags
Ignore white space 6 line context
... ...
@@ -255,353 +255,403 @@
255 255
The basic operations are adding and erasing items, changing the priority
256 256
of an item, etc.
257 257

	
258 258
Heaps are crucial in several algorithms, such as Dijkstra and Prim.
259 259
The heap implementations have the same interface, thus any of them can be
260 260
used easily in such algorithms.
261 261

	
262 262
\sa \ref concepts::Heap "Heap concept"
263 263
*/
264 264

	
265 265
/**
266 266
@defgroup matrices Matrices
267 267
@ingroup datas
268 268
\brief Two dimensional data storages implemented in LEMON.
269 269

	
270 270
This group contains two dimensional data storages implemented in LEMON.
271 271
*/
272 272

	
273 273
/**
274 274
@defgroup auxdat Auxiliary Data Structures
275 275
@ingroup datas
276 276
\brief Auxiliary data structures implemented in LEMON.
277 277

	
278 278
This group contains some data structures implemented in LEMON in
279 279
order to make it easier to implement combinatorial algorithms.
280 280
*/
281 281

	
282 282
/**
283 283
@defgroup geomdat Geometric Data Structures
284 284
@ingroup auxdat
285 285
\brief Geometric data structures implemented in LEMON.
286 286

	
287 287
This group contains geometric data structures implemented in LEMON.
288 288

	
289 289
 - \ref lemon::dim2::Point "dim2::Point" implements a two dimensional
290 290
   vector with the usual operations.
291 291
 - \ref lemon::dim2::Box "dim2::Box" can be used to determine the
292 292
   rectangular bounding box of a set of \ref lemon::dim2::Point
293 293
   "dim2::Point"'s.
294 294
*/
295 295

	
296 296
/**
297 297
@defgroup matrices Matrices
298 298
@ingroup auxdat
299 299
\brief Two dimensional data storages implemented in LEMON.
300 300

	
301 301
This group contains two dimensional data storages implemented in LEMON.
302 302
*/
303 303

	
304 304
/**
305 305
@defgroup algs Algorithms
306 306
\brief This group contains the several algorithms
307 307
implemented in LEMON.
308 308

	
309 309
This group contains the several algorithms
310 310
implemented in LEMON.
311 311
*/
312 312

	
313 313
/**
314 314
@defgroup search Graph Search
315 315
@ingroup algs
316 316
\brief Common graph search algorithms.
317 317

	
318 318
This group contains the common graph search algorithms, namely
319
\e breadth-first \e search (BFS) and \e depth-first \e search (DFS).
319
\e breadth-first \e search (BFS) and \e depth-first \e search (DFS)
320
\ref clrs01algorithms.
320 321
*/
321 322

	
322 323
/**
323 324
@defgroup shortest_path Shortest Path Algorithms
324 325
@ingroup algs
325 326
\brief Algorithms for finding shortest paths.
326 327

	
327
This group contains the algorithms for finding shortest paths in digraphs.
328
This group contains the algorithms for finding shortest paths in digraphs
329
\ref clrs01algorithms.
328 330

	
329 331
 - \ref Dijkstra algorithm for finding shortest paths from a source node
330 332
   when all arc lengths are non-negative.
331 333
 - \ref BellmanFord "Bellman-Ford" algorithm for finding shortest paths
332 334
   from a source node when arc lenghts can be either positive or negative,
333 335
   but the digraph should not contain directed cycles with negative total
334 336
   length.
335 337
 - \ref FloydWarshall "Floyd-Warshall" and \ref Johnson "Johnson" algorithms
336 338
   for solving the \e all-pairs \e shortest \e paths \e problem when arc
337 339
   lenghts can be either positive or negative, but the digraph should
338 340
   not contain directed cycles with negative total length.
339 341
 - \ref Suurballe A successive shortest path algorithm for finding
340 342
   arc-disjoint paths between two nodes having minimum total length.
341 343
*/
342 344

	
343 345
/**
344 346
@defgroup spantree Minimum Spanning Tree Algorithms
345 347
@ingroup algs
346 348
\brief Algorithms for finding minimum cost spanning trees and arborescences.
347 349

	
348 350
This group contains the algorithms for finding minimum cost spanning
349
trees and arborescences.
351
trees and arborescences \ref clrs01algorithms.
350 352
*/
351 353

	
352 354
/**
353 355
@defgroup max_flow Maximum Flow Algorithms
354 356
@ingroup algs
355 357
\brief Algorithms for finding maximum flows.
356 358

	
357 359
This group contains the algorithms for finding maximum flows and
358
feasible circulations.
360
feasible circulations \ref clrs01algorithms, \ref amo93networkflows.
359 361

	
360 362
The \e maximum \e flow \e problem is to find a flow of maximum value between
361 363
a single source and a single target. Formally, there is a \f$G=(V,A)\f$
362 364
digraph, a \f$cap: A\rightarrow\mathbf{R}^+_0\f$ capacity function and
363 365
\f$s, t \in V\f$ source and target nodes.
364 366
A maximum flow is an \f$f: A\rightarrow\mathbf{R}^+_0\f$ solution of the
365 367
following optimization problem.
366 368

	
367 369
\f[ \max\sum_{sv\in A} f(sv) - \sum_{vs\in A} f(vs) \f]
368 370
\f[ \sum_{uv\in A} f(uv) = \sum_{vu\in A} f(vu)
369 371
    \quad \forall u\in V\setminus\{s,t\} \f]
370 372
\f[ 0 \leq f(uv) \leq cap(uv) \quad \forall uv\in A \f]
371 373

	
372 374
LEMON contains several algorithms for solving maximum flow problems:
373
- \ref EdmondsKarp Edmonds-Karp algorithm.
374
- \ref Preflow Goldberg-Tarjan's preflow push-relabel algorithm.
375
- \ref DinitzSleatorTarjan Dinitz's blocking flow algorithm with dynamic trees.
376
- \ref GoldbergTarjan Preflow push-relabel algorithm with dynamic trees.
375
- \ref EdmondsKarp Edmonds-Karp algorithm
376
  \ref edmondskarp72theoretical.
377
- \ref Preflow Goldberg-Tarjan's preflow push-relabel algorithm
378
  \ref goldberg88newapproach.
379
- \ref DinitzSleatorTarjan Dinitz's blocking flow algorithm with dynamic trees
380
  \ref dinic70algorithm, \ref sleator83dynamic.
381
- \ref GoldbergTarjan !Preflow push-relabel algorithm with dynamic trees
382
  \ref goldberg88newapproach, \ref sleator83dynamic.
377 383

	
378
In most cases the \ref Preflow "Preflow" algorithm provides the
384
In most cases the \ref Preflow algorithm provides the
379 385
fastest method for computing a maximum flow. All implementations
380 386
also provide functions to query the minimum cut, which is the dual
381 387
problem of maximum flow.
382 388

	
383 389
\ref Circulation is a preflow push-relabel algorithm implemented directly 
384 390
for finding feasible circulations, which is a somewhat different problem,
385 391
but it is strongly related to maximum flow.
386 392
For more information, see \ref Circulation.
387 393
*/
388 394

	
389 395
/**
390 396
@defgroup min_cost_flow_algs Minimum Cost Flow Algorithms
391 397
@ingroup algs
392 398

	
393 399
\brief Algorithms for finding minimum cost flows and circulations.
394 400

	
395 401
This group contains the algorithms for finding minimum cost flows and
396
circulations. For more information about this problem and its dual
397
solution see \ref min_cost_flow "Minimum Cost Flow Problem".
402
circulations \ref amo93networkflows. For more information about this
403
problem and its dual solution, see \ref min_cost_flow
404
"Minimum Cost Flow Problem".
398 405

	
399 406
LEMON contains several algorithms for this problem.
400 407
 - \ref NetworkSimplex Primal Network Simplex algorithm with various
401
   pivot strategies.
408
   pivot strategies \ref dantzig63linearprog, \ref kellyoneill91netsimplex.
402 409
 - \ref CostScaling Push-Relabel and Augment-Relabel algorithms based on
403
   cost scaling.
410
   cost scaling \ref goldberg90approximation, \ref goldberg97efficient,
411
   \ref bunnagel98efficient.
404 412
 - \ref CapacityScaling Successive Shortest %Path algorithm with optional
405
   capacity scaling.
406
 - \ref CancelAndTighten The Cancel and Tighten algorithm.
407
 - \ref CycleCanceling Cycle-Canceling algorithms.
413
   capacity scaling \ref edmondskarp72theoretical.
414
 - \ref CancelAndTighten The Cancel and Tighten algorithm
415
   \ref goldberg89cyclecanceling.
416
 - \ref CycleCanceling Cycle-Canceling algorithms
417
   \ref klein67primal, \ref goldberg89cyclecanceling.
408 418

	
409 419
In general NetworkSimplex is the most efficient implementation,
410 420
but in special cases other algorithms could be faster.
411 421
For example, if the total supply and/or capacities are rather small,
412 422
CapacityScaling is usually the fastest algorithm (without effective scaling).
413 423
*/
414 424

	
415 425
/**
416 426
@defgroup min_cut Minimum Cut Algorithms
417 427
@ingroup algs
418 428

	
419 429
\brief Algorithms for finding minimum cut in graphs.
420 430

	
421 431
This group contains the algorithms for finding minimum cut in graphs.
422 432

	
423 433
The \e minimum \e cut \e problem is to find a non-empty and non-complete
424 434
\f$X\f$ subset of the nodes with minimum overall capacity on
425 435
outgoing arcs. Formally, there is a \f$G=(V,A)\f$ digraph, a
426 436
\f$cap: A\rightarrow\mathbf{R}^+_0\f$ capacity function. The minimum
427 437
cut is the \f$X\f$ solution of the next optimization problem:
428 438

	
429 439
\f[ \min_{X \subset V, X\not\in \{\emptyset, V\}}
430 440
    \sum_{uv\in A: u\in X, v\not\in X}cap(uv) \f]
431 441

	
432 442
LEMON contains several algorithms related to minimum cut problems:
433 443

	
434 444
- \ref HaoOrlin "Hao-Orlin algorithm" for calculating minimum cut
435 445
  in directed graphs.
436 446
- \ref NagamochiIbaraki "Nagamochi-Ibaraki algorithm" for
437 447
  calculating minimum cut in undirected graphs.
438 448
- \ref GomoryHu "Gomory-Hu tree computation" for calculating
439 449
  all-pairs minimum cut in undirected graphs.
440 450

	
441 451
If you want to find minimum cut just between two distinict nodes,
442 452
see the \ref max_flow "maximum flow problem".
443 453
*/
444 454

	
445 455
/**
456
@defgroup min_mean_cycle Minimum Mean Cycle Algorithms
457
@ingroup algs
458
\brief Algorithms for finding minimum mean cycles.
459

	
460
This group contains the algorithms for finding minimum mean cycles
461
\ref clrs01algorithms, \ref amo93networkflows.
462

	
463
The \e minimum \e mean \e cycle \e problem is to find a directed cycle
464
of minimum mean length (cost) in a digraph.
465
The mean length of a cycle is the average length of its arcs, i.e. the
466
ratio between the total length of the cycle and the number of arcs on it.
467

	
468
This problem has an important connection to \e conservative \e length
469
\e functions, too. A length function on the arcs of a digraph is called
470
conservative if and only if there is no directed cycle of negative total
471
length. For an arbitrary length function, the negative of the minimum
472
cycle mean is the smallest \f$\epsilon\f$ value so that increasing the
473
arc lengths uniformly by \f$\epsilon\f$ results in a conservative length
474
function.
475

	
476
LEMON contains three algorithms for solving the minimum mean cycle problem:
477
- \ref Karp "Karp"'s original algorithm \ref amo93networkflows,
478
  \ref dasdan98minmeancycle.
479
- \ref HartmannOrlin "Hartmann-Orlin"'s algorithm, which is an improved
480
  version of Karp's algorithm \ref dasdan98minmeancycle.
481
- \ref Howard "Howard"'s policy iteration algorithm
482
  \ref dasdan98minmeancycle.
483

	
484
In practice, the Howard algorithm proved to be by far the most efficient
485
one, though the best known theoretical bound on its running time is
486
exponential.
487
Both Karp and HartmannOrlin algorithms run in time O(ne) and use space
488
O(n<sup>2</sup>+e), but the latter one is typically faster due to the
489
applied early termination scheme.
490
*/
491

	
492
/**
446 493
@defgroup matching Matching Algorithms
447 494
@ingroup algs
448 495
\brief Algorithms for finding matchings in graphs and bipartite graphs.
449 496

	
450 497
This group contains the algorithms for calculating
451 498
matchings in graphs and bipartite graphs. The general matching problem is
452 499
finding a subset of the edges for which each node has at most one incident
453 500
edge.
454 501

	
455 502
There are several different algorithms for calculate matchings in
456 503
graphs.  The matching problems in bipartite graphs are generally
457 504
easier than in general graphs. The goal of the matching optimization
458 505
can be finding maximum cardinality, maximum weight or minimum cost
459 506
matching. The search can be constrained to find perfect or
460 507
maximum cardinality matching.
461 508

	
462 509
The matching algorithms implemented in LEMON:
463 510
- \ref MaxBipartiteMatching Hopcroft-Karp augmenting path algorithm
464 511
  for calculating maximum cardinality matching in bipartite graphs.
465 512
- \ref PrBipartiteMatching Push-relabel algorithm
466 513
  for calculating maximum cardinality matching in bipartite graphs.
467 514
- \ref MaxWeightedBipartiteMatching
468 515
  Successive shortest path algorithm for calculating maximum weighted
469 516
  matching and maximum weighted bipartite matching in bipartite graphs.
470 517
- \ref MinCostMaxBipartiteMatching
471 518
  Successive shortest path algorithm for calculating minimum cost maximum
472 519
  matching in bipartite graphs.
473 520
- \ref MaxMatching Edmond's blossom shrinking algorithm for calculating
474 521
  maximum cardinality matching in general graphs.
475 522
- \ref MaxWeightedMatching Edmond's blossom shrinking algorithm for calculating
476 523
  maximum weighted matching in general graphs.
477 524
- \ref MaxWeightedPerfectMatching
478 525
  Edmond's blossom shrinking algorithm for calculating maximum weighted
479 526
  perfect matching in general graphs.
480 527

	
481 528
\image html bipartite_matching.png
482 529
\image latex bipartite_matching.eps "Bipartite Matching" width=\textwidth
483 530
*/
484 531

	
485 532
/**
486 533
@defgroup graph_properties Connectivity and Other Graph Properties
487 534
@ingroup algs
488 535
\brief Algorithms for discovering the graph properties
489 536

	
490 537
This group contains the algorithms for discovering the graph properties
491 538
like connectivity, bipartiteness, euler property, simplicity etc.
492 539

	
493 540
\image html connected_components.png
494 541
\image latex connected_components.eps "Connected components" width=\textwidth
495 542
*/
496 543

	
497 544
/**
498 545
@defgroup planar Planarity Embedding and Drawing
499 546
@ingroup algs
500 547
\brief Algorithms for planarity checking, embedding and drawing
501 548

	
502 549
This group contains the algorithms for planarity checking,
503 550
embedding and drawing.
504 551

	
505 552
\image html planar.png
506 553
\image latex planar.eps "Plane graph" width=\textwidth
507 554
*/
508 555

	
509 556
/**
510 557
@defgroup approx Approximation Algorithms
511 558
@ingroup algs
512 559
\brief Approximation algorithms.
513 560

	
514 561
This group contains the approximation and heuristic algorithms
515 562
implemented in LEMON.
516 563
*/
517 564

	
518 565
/**
519 566
@defgroup auxalg Auxiliary Algorithms
520 567
@ingroup algs
521 568
\brief Auxiliary algorithms implemented in LEMON.
522 569

	
523 570
This group contains some algorithms implemented in LEMON
524 571
in order to make it easier to implement complex algorithms.
525 572
*/
526 573

	
527 574
/**
528 575
@defgroup gen_opt_group General Optimization Tools
529 576
\brief This group contains some general optimization frameworks
530 577
implemented in LEMON.
531 578

	
532 579
This group contains some general optimization frameworks
533 580
implemented in LEMON.
534 581
*/
535 582

	
536 583
/**
537
@defgroup lp_group Lp and Mip Solvers
584
@defgroup lp_group LP and MIP Solvers
538 585
@ingroup gen_opt_group
539
\brief Lp and Mip solver interfaces for LEMON.
586
\brief LP and MIP solver interfaces for LEMON.
540 587

	
541
This group contains Lp and Mip solver interfaces for LEMON. The
542
various LP solvers could be used in the same manner with this
543
interface.
588
This group contains LP and MIP solver interfaces for LEMON.
589
Various LP solvers could be used in the same manner with this
590
high-level interface.
591

	
592
The currently supported solvers are \ref glpk, \ref clp, \ref cbc,
593
\ref cplex, \ref soplex.
544 594
*/
545 595

	
546 596
/**
547 597
@defgroup lp_utils Tools for Lp and Mip Solvers
548 598
@ingroup lp_group
549 599
\brief Helper tools to the Lp and Mip solvers.
550 600

	
551 601
This group adds some helper tools to general optimization framework
552 602
implemented in LEMON.
553 603
*/
554 604

	
555 605
/**
556 606
@defgroup metah Metaheuristics
557 607
@ingroup gen_opt_group
558 608
\brief Metaheuristics for LEMON library.
559 609

	
560 610
This group contains some metaheuristic optimization tools.
561 611
*/
562 612

	
563 613
/**
564 614
@defgroup utils Tools and Utilities
565 615
\brief Tools and utilities for programming in LEMON
566 616

	
567 617
Tools and utilities for programming in LEMON.
568 618
*/
569 619

	
570 620
/**
571 621
@defgroup gutils Basic Graph Utilities
572 622
@ingroup utils
573 623
\brief Simple basic graph utilities.
574 624

	
575 625
This group contains some simple basic graph utilities.
576 626
*/
577 627

	
578 628
/**
579 629
@defgroup misc Miscellaneous Tools
580 630
@ingroup utils
581 631
\brief Tools for development, debugging and testing.
582 632

	
583 633
This group contains several useful tools for development,
584 634
debugging and testing.
585 635
*/
586 636

	
587 637
/**
588 638
@defgroup timecount Time Measuring and Counting
589 639
@ingroup misc
590 640
\brief Simple tools for measuring the performance of algorithms.
591 641

	
592 642
This group contains simple tools for measuring the performance
593 643
of algorithms.
594 644
*/
595 645

	
596 646
/**
597 647
@defgroup exceptions Exceptions
598 648
@ingroup utils
599 649
\brief Exceptions defined in LEMON.
600 650

	
601 651
This group contains the exceptions defined in LEMON.
602 652
*/
603 653

	
604 654
/**
605 655
@defgroup io_group Input-Output
606 656
\brief Graph Input-Output methods
607 657

	
... ...
@@ -618,98 +668,98 @@
618 668

	
619 669
This group contains methods for reading and writing
620 670
\ref lgf-format "LEMON Graph Format".
621 671
*/
622 672

	
623 673
/**
624 674
@defgroup eps_io Postscript Exporting
625 675
@ingroup io_group
626 676
\brief General \c EPS drawer and graph exporter
627 677

	
628 678
This group contains general \c EPS drawing methods and special
629 679
graph exporting tools.
630 680
*/
631 681

	
632 682
/**
633 683
@defgroup dimacs_group DIMACS Format
634 684
@ingroup io_group
635 685
\brief Read and write files in DIMACS format
636 686

	
637 687
Tools to read a digraph from or write it to a file in DIMACS format data.
638 688
*/
639 689

	
640 690
/**
641 691
@defgroup nauty_group NAUTY Format
642 692
@ingroup io_group
643 693
\brief Read \e Nauty format
644 694

	
645 695
Tool to read graphs from \e Nauty format data.
646 696
*/
647 697

	
648 698
/**
649 699
@defgroup concept Concepts
650 700
\brief Skeleton classes and concept checking classes
651 701

	
652 702
This group contains the data/algorithm skeletons and concept checking
653 703
classes implemented in LEMON.
654 704

	
655 705
The purpose of the classes in this group is fourfold.
656 706

	
657 707
- These classes contain the documentations of the %concepts. In order
658 708
  to avoid document multiplications, an implementation of a concept
659 709
  simply refers to the corresponding concept class.
660 710

	
661 711
- These classes declare every functions, <tt>typedef</tt>s etc. an
662 712
  implementation of the %concepts should provide, however completely
663 713
  without implementations and real data structures behind the
664 714
  interface. On the other hand they should provide nothing else. All
665 715
  the algorithms working on a data structure meeting a certain concept
666 716
  should compile with these classes. (Though it will not run properly,
667 717
  of course.) In this way it is easily to check if an algorithm
668 718
  doesn't use any extra feature of a certain implementation.
669 719

	
670 720
- The concept descriptor classes also provide a <em>checker class</em>
671 721
  that makes it possible to check whether a certain implementation of a
672 722
  concept indeed provides all the required features.
673 723

	
674 724
- Finally, They can serve as a skeleton of a new implementation of a concept.
675 725
*/
676 726

	
677 727
/**
678 728
@defgroup graph_concepts Graph Structure Concepts
679 729
@ingroup concept
680 730
\brief Skeleton and concept checking classes for graph structures
681 731

	
682
This group contains the skeletons and concept checking classes of LEMON's
683
graph structures and helper classes used to implement these.
732
This group contains the skeletons and concept checking classes of
733
graph structures.
684 734
*/
685 735

	
686 736
/**
687 737
@defgroup map_concepts Map Concepts
688 738
@ingroup concept
689 739
\brief Skeleton and concept checking classes for maps
690 740

	
691 741
This group contains the skeletons and concept checking classes of maps.
692 742
*/
693 743

	
694 744
/**
695 745
@defgroup tools Standalone Utility Applications
696 746

	
697 747
Some utility applications are listed here.
698 748

	
699 749
The standard compilation procedure (<tt>./configure;make</tt>) will compile
700 750
them, as well.
701 751
*/
702 752

	
703 753
/**
704 754
\anchor demoprograms
705 755

	
706 756
@defgroup demos Demo Programs
707 757

	
708 758
Some demo programs are listed here. Their full source codes can be found in
709 759
the \c demo subdirectory of the source tree.
710 760

	
711 761
In order to compile them, use the <tt>make demo</tt> or the
712 762
<tt>make check</tt> commands.
713 763
*/
714 764

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

	
19 19
/**
20 20
\mainpage LEMON Documentation
21 21

	
22 22
\section intro Introduction
23 23

	
24
\subsection whatis What is LEMON
25

	
26
LEMON stands for <b>L</b>ibrary for <b>E</b>fficient <b>M</b>odeling
27
and <b>O</b>ptimization in <b>N</b>etworks.
28
It is a C++ template
29
library aimed at combinatorial optimization tasks which
30
often involve in working
31
with graphs.
24
<b>LEMON</b> stands for <i><b>L</b>ibrary for <b>E</b>fficient <b>M</b>odeling
25
and <b>O</b>ptimization in <b>N</b>etworks</i>.
26
It is a C++ template library providing efficient implementation of common
27
data structures and algorithms with focus on combinatorial optimization
28
problems in graphs and networks.
32 29

	
33 30
<b>
34 31
LEMON is an <a class="el" href="http://opensource.org/">open&nbsp;source</a>
35 32
project.
36 33
You are free to use it in your commercial or
37 34
non-commercial applications under very permissive
38 35
\ref license "license terms".
39 36
</b>
40 37

	
41
\subsection howtoread How to read the documentation
38
The project is maintained by the 
39
<a href="http://www.cs.elte.hu/egres/">Egerv&aacute;ry Research Group on
40
Combinatorial Optimization</a> \ref egres
41
at the Operations Research Department of the
42
<a href="http://www.elte.hu/">E&ouml;tv&ouml;s Lor&aacute;nd University,
43
Budapest</a>, Hungary.
44
LEMON is also a member of the <a href="http://www.coin-or.org/">COIN-OR</a>
45
initiative \ref coinor.
46

	
47
\section howtoread How to Read the Documentation
42 48

	
43 49
If you would like to get to know the library, see
44 50
<a class="el" href="http://lemon.cs.elte.hu/pub/tutorial/">LEMON Tutorial</a>.
45 51

	
46 52
If you know what you are looking for, then try to find it under the
47 53
<a class="el" href="modules.html">Modules</a> section.
48 54

	
49 55
If you are a user of the old (0.x) series of LEMON, please check out the
50 56
\ref migration "Migration Guide" for the backward incompatibilities.
51 57
*/
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
namespace lemon {
20 20

	
21 21
/**
22 22
\page min_cost_flow Minimum Cost Flow Problem
23 23

	
24 24
\section mcf_def Definition (GEQ form)
25 25

	
26 26
The \e minimum \e cost \e flow \e problem is to find a feasible flow of
27 27
minimum total cost from a set of supply nodes to a set of demand nodes
28 28
in a network with capacity constraints (lower and upper bounds)
29
and arc costs.
29
and arc costs \ref amo93networkflows.
30 30

	
31 31
Formally, let \f$G=(V,A)\f$ be a digraph, \f$lower: A\rightarrow\mathbf{R}\f$,
32 32
\f$upper: A\rightarrow\mathbf{R}\cup\{+\infty\}\f$ denote the lower and
33 33
upper bounds for the flow values on the arcs, for which
34 34
\f$lower(uv) \leq upper(uv)\f$ must hold for all \f$uv\in A\f$,
35 35
\f$cost: A\rightarrow\mathbf{R}\f$ denotes the cost per unit flow
36 36
on the arcs and \f$sup: V\rightarrow\mathbf{R}\f$ denotes the
37 37
signed supply values of the nodes.
38 38
If \f$sup(u)>0\f$, then \f$u\f$ is a supply node with \f$sup(u)\f$
39 39
supply, if \f$sup(u)<0\f$, then \f$u\f$ is a demand node with
40 40
\f$-sup(u)\f$ demand.
41 41
A minimum cost flow is an \f$f: A\rightarrow\mathbf{R}\f$ solution
42 42
of the following optimization problem.
43 43

	
44 44
\f[ \min\sum_{uv\in A} f(uv) \cdot cost(uv) \f]
45 45
\f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \geq
46 46
    sup(u) \quad \forall u\in V \f]
47 47
\f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f]
48 48

	
49 49
The sum of the supply values, i.e. \f$\sum_{u\in V} sup(u)\f$ must be
50 50
zero or negative in order to have a feasible solution (since the sum
51 51
of the expressions on the left-hand side of the inequalities is zero).
52 52
It means that the total demand must be greater or equal to the total
53 53
supply and all the supplies have to be carried out from the supply nodes,
54 54
but there could be demands that are not satisfied.
55 55
If \f$\sum_{u\in V} sup(u)\f$ is zero, then all the supply/demand
56 56
constraints have to be satisfied with equality, i.e. all demands
57 57
have to be satisfied and all supplies have to be used.
58 58

	
59 59

	
60 60
\section mcf_algs Algorithms
61 61

	
62 62
LEMON contains several algorithms for solving this problem, for more
63 63
information see \ref min_cost_flow_algs "Minimum Cost Flow Algorithms".
64 64

	
65 65
A feasible solution for this problem can be found using \ref Circulation.
66 66

	
67 67

	
68 68
\section mcf_dual Dual Solution
69 69

	
70 70
The dual solution of the minimum cost flow problem is represented by
71 71
node potentials \f$\pi: V\rightarrow\mathbf{R}\f$.
72 72
An \f$f: A\rightarrow\mathbf{R}\f$ primal feasible solution is optimal
73 73
if and only if for some \f$\pi: V\rightarrow\mathbf{R}\f$ node potentials
74 74
the following \e complementary \e slackness optimality conditions hold.
75 75

	
76 76
 - For all \f$uv\in A\f$ arcs:
77 77
   - if \f$cost^\pi(uv)>0\f$, then \f$f(uv)=lower(uv)\f$;
78 78
   - if \f$lower(uv)<f(uv)<upper(uv)\f$, then \f$cost^\pi(uv)=0\f$;
79 79
   - if \f$cost^\pi(uv)<0\f$, then \f$f(uv)=upper(uv)\f$.
80 80
 - For all \f$u\in V\f$ nodes:
81 81
   - \f$\pi(u)<=0\f$;
82 82
   - if \f$\sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \neq sup(u)\f$,
83 83
     then \f$\pi(u)=0\f$.
84 84
 
85 85
Here \f$cost^\pi(uv)\f$ denotes the \e reduced \e cost of the arc
86 86
\f$uv\in A\f$ with respect to the potential function \f$\pi\f$, i.e.
87 87
\f[ cost^\pi(uv) = cost(uv) + \pi(u) - \pi(v).\f]
88 88

	
89 89
All algorithms provide dual solution (node potentials), as well,
90 90
if an optimal flow is found.
91 91

	
92 92

	
93 93
\section mcf_eq Equality Form
Ignore white space 6 line context
... ...
@@ -25,117 +25,121 @@
25 25
	$(SOPLEX_CXXFLAGS) \
26 26
	$(CLP_CXXFLAGS) \
27 27
	$(CBC_CXXFLAGS)
28 28

	
29 29
lemon_libemon_la_LDFLAGS = \
30 30
	$(GLPK_LIBS) \
31 31
	$(CPLEX_LIBS) \
32 32
	$(SOPLEX_LIBS) \
33 33
	$(CLP_LIBS) \
34 34
	$(CBC_LIBS)
35 35

	
36 36
if HAVE_GLPK
37 37
lemon_libemon_la_SOURCES += lemon/glpk.cc
38 38
endif
39 39

	
40 40
if HAVE_CPLEX
41 41
lemon_libemon_la_SOURCES += lemon/cplex.cc
42 42
endif
43 43

	
44 44
if HAVE_SOPLEX
45 45
lemon_libemon_la_SOURCES += lemon/soplex.cc
46 46
endif
47 47

	
48 48
if HAVE_CLP
49 49
lemon_libemon_la_SOURCES += lemon/clp.cc
50 50
endif
51 51

	
52 52
if HAVE_CBC
53 53
lemon_libemon_la_SOURCES += lemon/cbc.cc
54 54
endif
55 55

	
56 56
lemon_HEADERS += \
57 57
	lemon/adaptors.h \
58 58
	lemon/arg_parser.h \
59 59
	lemon/assert.h \
60 60
	lemon/bellman_ford.h \
61 61
	lemon/bfs.h \
62 62
	lemon/bin_heap.h \
63 63
	lemon/binom_heap.h \
64 64
	lemon/bucket_heap.h \
65 65
	lemon/cbc.h \
66 66
	lemon/circulation.h \
67 67
	lemon/clp.h \
68 68
	lemon/color.h \
69 69
	lemon/concept_check.h \
70 70
	lemon/connectivity.h \
71 71
	lemon/counter.h \
72 72
	lemon/core.h \
73 73
	lemon/cplex.h \
74 74
	lemon/dfs.h \
75 75
	lemon/dijkstra.h \
76 76
	lemon/dim2.h \
77 77
	lemon/dimacs.h \
78 78
	lemon/edge_set.h \
79 79
	lemon/elevator.h \
80 80
	lemon/error.h \
81 81
	lemon/euler.h \
82 82
	lemon/fib_heap.h \
83 83
	lemon/fourary_heap.h \
84 84
	lemon/full_graph.h \
85 85
	lemon/glpk.h \
86 86
	lemon/gomory_hu.h \
87 87
	lemon/graph_to_eps.h \
88 88
	lemon/grid_graph.h \
89
	lemon/hartmann_orlin.h \
90
	lemon/howard.h \
89 91
	lemon/hypercube_graph.h \
92
	lemon/karp.h \
90 93
	lemon/kary_heap.h \
91 94
	lemon/kruskal.h \
92 95
	lemon/hao_orlin.h \
93 96
	lemon/lgf_reader.h \
94 97
	lemon/lgf_writer.h \
95 98
	lemon/list_graph.h \
96 99
	lemon/lp.h \
97 100
	lemon/lp_base.h \
98 101
	lemon/lp_skeleton.h \
99 102
	lemon/maps.h \
100 103
	lemon/matching.h \
101 104
	lemon/math.h \
102 105
	lemon/min_cost_arborescence.h \
103 106
	lemon/nauty_reader.h \
104 107
	lemon/network_simplex.h \
105 108
	lemon/pairing_heap.h \
106 109
	lemon/path.h \
107 110
	lemon/preflow.h \
108 111
	lemon/radix_heap.h \
109 112
	lemon/radix_sort.h \
110 113
	lemon/random.h \
111 114
	lemon/smart_graph.h \
112 115
	lemon/soplex.h \
116
	lemon/static_graph.h \
113 117
	lemon/suurballe.h \
114 118
	lemon/time_measure.h \
115 119
	lemon/tolerance.h \
116 120
	lemon/unionfind.h \
117 121
	lemon/bits/windows.h
118 122

	
119 123
bits_HEADERS += \
120 124
	lemon/bits/alteration_notifier.h \
121 125
	lemon/bits/array_map.h \
122 126
	lemon/bits/bezier.h \
123 127
	lemon/bits/default_map.h \
124 128
	lemon/bits/edge_set_extender.h \
125 129
	lemon/bits/enable_if.h \
126 130
	lemon/bits/graph_adaptor_extender.h \
127 131
	lemon/bits/graph_extender.h \
128 132
	lemon/bits/map_extender.h \
129 133
	lemon/bits/path_dump.h \
130 134
	lemon/bits/solver_bits.h \
131 135
	lemon/bits/traits.h \
132 136
	lemon/bits/variant.h \
133 137
	lemon/bits/vector_map.h
134 138

	
135 139
concept_HEADERS += \
136 140
	lemon/concepts/digraph.h \
137 141
	lemon/concepts/graph.h \
138 142
	lemon/concepts/graph_components.h \
139 143
	lemon/concepts/heap.h \
140 144
	lemon/concepts/maps.h \
141 145
	lemon/concepts/path.h
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_BITS_GRAPH_EXTENDER_H
20 20
#define LEMON_BITS_GRAPH_EXTENDER_H
21 21

	
22 22
#include <lemon/core.h>
23 23

	
24 24
#include <lemon/bits/map_extender.h>
25 25
#include <lemon/bits/default_map.h>
26 26

	
27 27
#include <lemon/concept_check.h>
28 28
#include <lemon/concepts/maps.h>
29 29

	
30 30
//\ingroup graphbits
31 31
//\file
32 32
//\brief Extenders for the graph types
33 33
namespace lemon {
34 34

	
35 35
  // \ingroup graphbits
36 36
  //
37 37
  // \brief Extender for the digraph implementations
38 38
  template <typename Base>
39 39
  class DigraphExtender : public Base {
40 40
    typedef Base Parent;
41 41

	
42 42
  public:
43 43

	
44 44
    typedef DigraphExtender Digraph;
45 45

	
46 46
    // Base extensions
47 47

	
48 48
    typedef typename Parent::Node Node;
49 49
    typedef typename Parent::Arc Arc;
50 50

	
51 51
    int maxId(Node) const {
52 52
      return Parent::maxNodeId();
53 53
    }
54 54

	
55 55
    int maxId(Arc) const {
56 56
      return Parent::maxArcId();
57 57
    }
58 58

	
59
    Node fromId(int id, Node) const {
59
    static Node fromId(int id, Node) {
60 60
      return Parent::nodeFromId(id);
61 61
    }
62 62

	
63
    Arc fromId(int id, Arc) const {
63
    static Arc fromId(int id, Arc) {
64 64
      return Parent::arcFromId(id);
65 65
    }
66 66

	
67 67
    Node oppositeNode(const Node &node, const Arc &arc) const {
68 68
      if (node == Parent::source(arc))
69 69
        return Parent::target(arc);
70 70
      else if(node == Parent::target(arc))
71 71
        return Parent::source(arc);
72 72
      else
73 73
        return INVALID;
74 74
    }
75 75

	
76 76
    // Alterable extension
77 77

	
78 78
    typedef AlterationNotifier<DigraphExtender, Node> NodeNotifier;
79 79
    typedef AlterationNotifier<DigraphExtender, Arc> ArcNotifier;
80 80

	
81 81

	
82 82
  protected:
83 83

	
84 84
    mutable NodeNotifier node_notifier;
85 85
    mutable ArcNotifier arc_notifier;
86 86

	
87 87
  public:
88 88

	
89 89
    NodeNotifier& notifier(Node) const {
90 90
      return node_notifier;
91 91
    }
92 92

	
93 93
    ArcNotifier& notifier(Arc) const {
94 94
      return arc_notifier;
95 95
    }
96 96

	
97 97
    class NodeIt : public Node {
98 98
      const Digraph* _digraph;
99 99
    public:
100 100

	
101 101
      NodeIt() {}
102 102

	
103 103
      NodeIt(Invalid i) : Node(i) { }
104 104

	
105 105
      explicit NodeIt(const Digraph& digraph) : _digraph(&digraph) {
106 106
        _digraph->first(static_cast<Node&>(*this));
107 107
      }
108 108

	
109 109
      NodeIt(const Digraph& digraph, const Node& node)
110 110
        : Node(node), _digraph(&digraph) {}
111 111

	
112 112
      NodeIt& operator++() {
113 113
        _digraph->next(*this);
114 114
        return *this;
115 115
      }
116 116

	
117 117
    };
118 118

	
119 119

	
120 120
    class ArcIt : public Arc {
121 121
      const Digraph* _digraph;
122 122
    public:
123 123

	
124 124
      ArcIt() { }
125 125

	
126 126
      ArcIt(Invalid i) : Arc(i) { }
127 127

	
... ...
@@ -294,137 +294,137 @@
294 294
      Parent::firstOut(arc, node);
295 295
      while (arc != INVALID ) {
296 296
        erase(arc);
297 297
        Parent::firstOut(arc, node);
298 298
      }
299 299

	
300 300
      Parent::firstIn(arc, node);
301 301
      while (arc != INVALID ) {
302 302
        erase(arc);
303 303
        Parent::firstIn(arc, node);
304 304
      }
305 305

	
306 306
      notifier(Node()).erase(node);
307 307
      Parent::erase(node);
308 308
    }
309 309

	
310 310
    void erase(const Arc& arc) {
311 311
      notifier(Arc()).erase(arc);
312 312
      Parent::erase(arc);
313 313
    }
314 314

	
315 315
    DigraphExtender() {
316 316
      node_notifier.setContainer(*this);
317 317
      arc_notifier.setContainer(*this);
318 318
    }
319 319

	
320 320

	
321 321
    ~DigraphExtender() {
322 322
      arc_notifier.clear();
323 323
      node_notifier.clear();
324 324
    }
325 325
  };
326 326

	
327 327
  // \ingroup _graphbits
328 328
  //
329 329
  // \brief Extender for the Graphs
330 330
  template <typename Base>
331 331
  class GraphExtender : public Base {
332 332
    typedef Base Parent;
333 333

	
334 334
  public:
335 335

	
336 336
    typedef GraphExtender Graph;
337 337

	
338 338
    typedef True UndirectedTag;
339 339

	
340 340
    typedef typename Parent::Node Node;
341 341
    typedef typename Parent::Arc Arc;
342 342
    typedef typename Parent::Edge Edge;
343 343

	
344 344
    // Graph extension
345 345

	
346 346
    int maxId(Node) const {
347 347
      return Parent::maxNodeId();
348 348
    }
349 349

	
350 350
    int maxId(Arc) const {
351 351
      return Parent::maxArcId();
352 352
    }
353 353

	
354 354
    int maxId(Edge) const {
355 355
      return Parent::maxEdgeId();
356 356
    }
357 357

	
358
    Node fromId(int id, Node) const {
358
    static Node fromId(int id, Node) {
359 359
      return Parent::nodeFromId(id);
360 360
    }
361 361

	
362
    Arc fromId(int id, Arc) const {
362
    static Arc fromId(int id, Arc) {
363 363
      return Parent::arcFromId(id);
364 364
    }
365 365

	
366
    Edge fromId(int id, Edge) const {
366
    static Edge fromId(int id, Edge) {
367 367
      return Parent::edgeFromId(id);
368 368
    }
369 369

	
370 370
    Node oppositeNode(const Node &n, const Edge &e) const {
371 371
      if( n == Parent::u(e))
372 372
        return Parent::v(e);
373 373
      else if( n == Parent::v(e))
374 374
        return Parent::u(e);
375 375
      else
376 376
        return INVALID;
377 377
    }
378 378

	
379 379
    Arc oppositeArc(const Arc &arc) const {
380 380
      return Parent::direct(arc, !Parent::direction(arc));
381 381
    }
382 382

	
383 383
    using Parent::direct;
384 384
    Arc direct(const Edge &edge, const Node &node) const {
385 385
      return Parent::direct(edge, Parent::u(edge) == node);
386 386
    }
387 387

	
388 388
    // Alterable extension
389 389

	
390 390
    typedef AlterationNotifier<GraphExtender, Node> NodeNotifier;
391 391
    typedef AlterationNotifier<GraphExtender, Arc> ArcNotifier;
392 392
    typedef AlterationNotifier<GraphExtender, Edge> EdgeNotifier;
393 393

	
394 394

	
395 395
  protected:
396 396

	
397 397
    mutable NodeNotifier node_notifier;
398 398
    mutable ArcNotifier arc_notifier;
399 399
    mutable EdgeNotifier edge_notifier;
400 400

	
401 401
  public:
402 402

	
403 403
    NodeNotifier& notifier(Node) const {
404 404
      return node_notifier;
405 405
    }
406 406

	
407 407
    ArcNotifier& notifier(Arc) const {
408 408
      return arc_notifier;
409 409
    }
410 410

	
411 411
    EdgeNotifier& notifier(Edge) const {
412 412
      return edge_notifier;
413 413
    }
414 414

	
415 415

	
416 416

	
417 417
    class NodeIt : public Node {
418 418
      const Graph* _graph;
419 419
    public:
420 420

	
421 421
      NodeIt() {}
422 422

	
423 423
      NodeIt(Invalid i) : Node(i) { }
424 424

	
425 425
      explicit NodeIt(const Graph& graph) : _graph(&graph) {
426 426
        _graph->first(static_cast<Node&>(*this));
427 427
      }
428 428

	
429 429
      NodeIt(const Graph& graph, const Node& node)
430 430
        : Node(node), _graph(&graph) {}
Ignore white space 6 line context
... ...
@@ -33,128 +33,140 @@
33 33
#endif
34 34

	
35 35
#include "coin/CbcCutGenerator.hpp"
36 36
#include "coin/CbcHeuristicLocal.hpp"
37 37
#include "coin/CbcHeuristicGreedy.hpp"
38 38
#include "coin/CbcHeuristicFPump.hpp"
39 39
#include "coin/CbcHeuristicRINS.hpp"
40 40

	
41 41
#include "coin/CglGomory.hpp"
42 42
#include "coin/CglProbing.hpp"
43 43
#include "coin/CglKnapsackCover.hpp"
44 44
#include "coin/CglOddHole.hpp"
45 45
#include "coin/CglClique.hpp"
46 46
#include "coin/CglFlowCover.hpp"
47 47
#include "coin/CglMixedIntegerRounding.hpp"
48 48

	
49 49
#include "coin/CbcHeuristic.hpp"
50 50

	
51 51
namespace lemon {
52 52

	
53 53
  CbcMip::CbcMip() {
54 54
    _prob = new CoinModel();
55 55
    _prob->setProblemName("LEMON");
56 56
    _osi_solver = 0;
57 57
    _cbc_model = 0;
58 58
    messageLevel(MESSAGE_NOTHING);
59 59
  }
60 60

	
61 61
  CbcMip::CbcMip(const CbcMip& other) {
62 62
    _prob = new CoinModel(*other._prob);
63 63
    _prob->setProblemName("LEMON");
64 64
    _osi_solver = 0;
65 65
    _cbc_model = 0;
66 66
    messageLevel(MESSAGE_NOTHING);
67 67
  }
68 68

	
69 69
  CbcMip::~CbcMip() {
70 70
    delete _prob;
71 71
    if (_osi_solver) delete _osi_solver;
72 72
    if (_cbc_model) delete _cbc_model;
73 73
  }
74 74

	
75 75
  const char* CbcMip::_solverName() const { return "CbcMip"; }
76 76

	
77 77
  int CbcMip::_addCol() {
78 78
    _prob->addColumn(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX, 0.0, 0, false);
79 79
    return _prob->numberColumns() - 1;
80 80
  }
81 81

	
82 82
  CbcMip* CbcMip::newSolver() const {
83 83
    CbcMip* newlp = new CbcMip;
84 84
    return newlp;
85 85
  }
86 86

	
87 87
  CbcMip* CbcMip::cloneSolver() const {
88 88
    CbcMip* copylp = new CbcMip(*this);
89 89
    return copylp;
90 90
  }
91 91

	
92 92
  int CbcMip::_addRow() {
93 93
    _prob->addRow(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX);
94 94
    return _prob->numberRows() - 1;
95 95
  }
96 96

	
97
  int CbcMip::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
98
    std::vector<int> indexes;
99
    std::vector<Value> values;
100

	
101
    for(ExprIterator it = b; it != e; ++it) {
102
      indexes.push_back(it->first);
103
      values.push_back(it->second);
104
    }
105

	
106
    _prob->addRow(values.size(), &indexes.front(), &values.front(), l, u);
107
    return _prob->numberRows() - 1;
108
  }
97 109

	
98 110
  void CbcMip::_eraseCol(int i) {
99 111
    _prob->deleteColumn(i);
100 112
  }
101 113

	
102 114
  void CbcMip::_eraseRow(int i) {
103 115
    _prob->deleteRow(i);
104 116
  }
105 117

	
106 118
  void CbcMip::_eraseColId(int i) {
107 119
    cols.eraseIndex(i);
108 120
  }
109 121

	
110 122
  void CbcMip::_eraseRowId(int i) {
111 123
    rows.eraseIndex(i);
112 124
  }
113 125

	
114 126
  void CbcMip::_getColName(int c, std::string& name) const {
115 127
    name = _prob->getColumnName(c);
116 128
  }
117 129

	
118 130
  void CbcMip::_setColName(int c, const std::string& name) {
119 131
    _prob->setColumnName(c, name.c_str());
120 132
  }
121 133

	
122 134
  int CbcMip::_colByName(const std::string& name) const {
123 135
    return _prob->column(name.c_str());
124 136
  }
125 137

	
126 138
  void CbcMip::_getRowName(int r, std::string& name) const {
127 139
    name = _prob->getRowName(r);
128 140
  }
129 141

	
130 142
  void CbcMip::_setRowName(int r, const std::string& name) {
131 143
    _prob->setRowName(r, name.c_str());
132 144
  }
133 145

	
134 146
  int CbcMip::_rowByName(const std::string& name) const {
135 147
    return _prob->row(name.c_str());
136 148
  }
137 149

	
138 150
  void CbcMip::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) {
139 151
    for (ExprIterator it = b; it != e; ++it) {
140 152
      _prob->setElement(i, it->first, it->second);
141 153
    }
142 154
  }
143 155

	
144 156
  void CbcMip::_getRowCoeffs(int ix, InsertIterator b) const {
145 157
    int length = _prob->numberRows();
146 158

	
147 159
    std::vector<int> indices(length);
148 160
    std::vector<Value> values(length);
149 161

	
150 162
    length = _prob->getRow(ix, &indices[0], &values[0]);
151 163

	
152 164
    for (int i = 0; i < length; ++i) {
153 165
      *b = std::make_pair(indices[i], values[i]);
154 166
      ++b;
155 167
    }
156 168
  }
157 169

	
158 170
  void CbcMip::_setColCoeffs(int ix, ExprIterator b, ExprIterator e) {
159 171
    for (ExprIterator it = b; it != e; ++it) {
160 172
      _prob->setElement(it->first, ix, it->second);
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
// -*- C++ -*-
20 20
#ifndef LEMON_CBC_H
21 21
#define LEMON_CBC_H
22 22

	
23 23
///\file
24 24
///\brief Header of the LEMON-CBC mip solver interface.
25 25
///\ingroup lp_group
26 26

	
27 27
#include <lemon/lp_base.h>
28 28

	
29 29
class CoinModel;
30 30
class OsiSolverInterface;
31 31
class CbcModel;
32 32

	
33 33
namespace lemon {
34 34

	
35 35
  /// \brief Interface for the CBC MIP solver
36 36
  ///
37 37
  /// This class implements an interface for the CBC MIP solver.
38 38
  ///\ingroup lp_group
39 39
  class CbcMip : public MipSolver {
40 40
  protected:
41 41

	
42 42
    CoinModel *_prob;
43 43
    OsiSolverInterface *_osi_solver;
44 44
    CbcModel *_cbc_model;
45 45

	
46 46
  public:
47 47

	
48 48
    /// \e
49 49
    CbcMip();
50 50
    /// \e
51 51
    CbcMip(const CbcMip&);
52 52
    /// \e
53 53
    ~CbcMip();
54 54
    /// \e
55 55
    virtual CbcMip* newSolver() const;
56 56
    /// \e
57 57
    virtual CbcMip* cloneSolver() const;
58 58

	
59 59
  protected:
60 60

	
61 61
    virtual const char* _solverName() const;
62 62

	
63 63
    virtual int _addCol();
64 64
    virtual int _addRow();
65
    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
65 66

	
66 67
    virtual void _eraseCol(int i);
67 68
    virtual void _eraseRow(int i);
68 69

	
69 70
    virtual void _eraseColId(int i);
70 71
    virtual void _eraseRowId(int i);
71 72

	
72 73
    virtual void _getColName(int col, std::string& name) const;
73 74
    virtual void _setColName(int col, const std::string& name);
74 75
    virtual int _colByName(const std::string& name) const;
75 76

	
76 77
    virtual void _getRowName(int row, std::string& name) const;
77 78
    virtual void _setRowName(int row, const std::string& name);
78 79
    virtual int _rowByName(const std::string& name) const;
79 80

	
80 81
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
81 82
    virtual void _getRowCoeffs(int i, InsertIterator b) const;
82 83

	
83 84
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
84 85
    virtual void _getColCoeffs(int i, InsertIterator b) const;
85 86

	
86 87
    virtual void _setCoeff(int row, int col, Value value);
87 88
    virtual Value _getCoeff(int row, int col) const;
88 89

	
89 90
    virtual void _setColLowerBound(int i, Value value);
90 91
    virtual Value _getColLowerBound(int i) const;
91 92
    virtual void _setColUpperBound(int i, Value value);
92 93
    virtual Value _getColUpperBound(int i) const;
93 94

	
94 95
    virtual void _setRowLowerBound(int i, Value value);
95 96
    virtual Value _getRowLowerBound(int i) const;
96 97
    virtual void _setRowUpperBound(int i, Value value);
97 98
    virtual Value _getRowUpperBound(int i) const;
98 99

	
99 100
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
100 101
    virtual void _getObjCoeffs(InsertIterator b) const;
101 102

	
102 103
    virtual void _setObjCoeff(int i, Value obj_coef);
103 104
    virtual Value _getObjCoeff(int i) const;
104 105

	
105 106
    virtual void _setSense(Sense sense);
106 107
    virtual Sense _getSense() const;
107 108

	
108 109
    virtual ColTypes _getColType(int col) const;
109 110
    virtual void _setColType(int col, ColTypes col_type);
110 111

	
111 112
    virtual SolveExitStatus _solve();
112 113
    virtual ProblemType _getType() const;
113 114
    virtual Value _getSol(int i) const;
114 115
    virtual Value _getSolValue() const;
115 116

	
116 117
    virtual void _clear();
117 118

	
118 119
    virtual void _messageLevel(MessageLevel level);
119 120
    void _applyMessageLevel();
120 121

	
121 122
    int _message_level;
122 123

	
123 124
    
124 125

	
125 126
  };
126 127

	
127 128
}
128 129

	
Ignore white space 6 line context
... ...
@@ -17,128 +17,141 @@
17 17
 */
18 18

	
19 19
#include <lemon/clp.h>
20 20
#include <coin/ClpSimplex.hpp>
21 21

	
22 22
namespace lemon {
23 23

	
24 24
  ClpLp::ClpLp() {
25 25
    _prob = new ClpSimplex();
26 26
    _init_temporals();
27 27
    messageLevel(MESSAGE_NOTHING);
28 28
  }
29 29

	
30 30
  ClpLp::ClpLp(const ClpLp& other) {
31 31
    _prob = new ClpSimplex(*other._prob);
32 32
    rows = other.rows;
33 33
    cols = other.cols;
34 34
    _init_temporals();
35 35
    messageLevel(MESSAGE_NOTHING);
36 36
  }
37 37

	
38 38
  ClpLp::~ClpLp() {
39 39
    delete _prob;
40 40
    _clear_temporals();
41 41
  }
42 42

	
43 43
  void ClpLp::_init_temporals() {
44 44
    _primal_ray = 0;
45 45
    _dual_ray = 0;
46 46
  }
47 47

	
48 48
  void ClpLp::_clear_temporals() {
49 49
    if (_primal_ray) {
50 50
      delete[] _primal_ray;
51 51
      _primal_ray = 0;
52 52
    }
53 53
    if (_dual_ray) {
54 54
      delete[] _dual_ray;
55 55
      _dual_ray = 0;
56 56
    }
57 57
  }
58 58

	
59 59
  ClpLp* ClpLp::newSolver() const {
60 60
    ClpLp* newlp = new ClpLp;
61 61
    return newlp;
62 62
  }
63 63

	
64 64
  ClpLp* ClpLp::cloneSolver() const {
65 65
    ClpLp* copylp = new ClpLp(*this);
66 66
    return copylp;
67 67
  }
68 68

	
69 69
  const char* ClpLp::_solverName() const { return "ClpLp"; }
70 70

	
71 71
  int ClpLp::_addCol() {
72 72
    _prob->addColumn(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX, 0.0);
73 73
    return _prob->numberColumns() - 1;
74 74
  }
75 75

	
76 76
  int ClpLp::_addRow() {
77 77
    _prob->addRow(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX);
78 78
    return _prob->numberRows() - 1;
79 79
  }
80 80

	
81
  int ClpLp::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
82
    std::vector<int> indexes;
83
    std::vector<Value> values;
84

	
85
    for(ExprIterator it = b; it != e; ++it) {
86
      indexes.push_back(it->first);
87
      values.push_back(it->second);
88
    }
89

	
90
    _prob->addRow(values.size(), &indexes.front(), &values.front(), l, u);
91
    return _prob->numberRows() - 1;
92
  }
93

	
81 94

	
82 95
  void ClpLp::_eraseCol(int c) {
83 96
    _col_names_ref.erase(_prob->getColumnName(c));
84 97
    _prob->deleteColumns(1, &c);
85 98
  }
86 99

	
87 100
  void ClpLp::_eraseRow(int r) {
88 101
    _row_names_ref.erase(_prob->getRowName(r));
89 102
    _prob->deleteRows(1, &r);
90 103
  }
91 104

	
92 105
  void ClpLp::_eraseColId(int i) {
93 106
    cols.eraseIndex(i);
94 107
    cols.shiftIndices(i);
95 108
  }
96 109

	
97 110
  void ClpLp::_eraseRowId(int i) {
98 111
    rows.eraseIndex(i);
99 112
    rows.shiftIndices(i);
100 113
  }
101 114

	
102 115
  void ClpLp::_getColName(int c, std::string& name) const {
103 116
    name = _prob->getColumnName(c);
104 117
  }
105 118

	
106 119
  void ClpLp::_setColName(int c, const std::string& name) {
107 120
    _prob->setColumnName(c, const_cast<std::string&>(name));
108 121
    _col_names_ref[name] = c;
109 122
  }
110 123

	
111 124
  int ClpLp::_colByName(const std::string& name) const {
112 125
    std::map<std::string, int>::const_iterator it = _col_names_ref.find(name);
113 126
    return it != _col_names_ref.end() ? it->second : -1;
114 127
  }
115 128

	
116 129
  void ClpLp::_getRowName(int r, std::string& name) const {
117 130
    name = _prob->getRowName(r);
118 131
  }
119 132

	
120 133
  void ClpLp::_setRowName(int r, const std::string& name) {
121 134
    _prob->setRowName(r, const_cast<std::string&>(name));
122 135
    _row_names_ref[name] = r;
123 136
  }
124 137

	
125 138
  int ClpLp::_rowByName(const std::string& name) const {
126 139
    std::map<std::string, int>::const_iterator it = _row_names_ref.find(name);
127 140
    return it != _row_names_ref.end() ? it->second : -1;
128 141
  }
129 142

	
130 143

	
131 144
  void ClpLp::_setRowCoeffs(int ix, ExprIterator b, ExprIterator e) {
132 145
    std::map<int, Value> coeffs;
133 146

	
134 147
    int n = _prob->clpMatrix()->getNumCols();
135 148

	
136 149
    const int* indices = _prob->clpMatrix()->getIndices();
137 150
    const double* elements = _prob->clpMatrix()->getElements();
138 151

	
139 152
    for (int i = 0; i < n; ++i) {
140 153
      CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[i];
141 154
      CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[i];
142 155

	
143 156
      const int* it = std::lower_bound(indices + begin, indices + end, ix);
144 157
      if (it != indices + end && *it == ix && elements[it - indices] != 0.0) {
Ignore white space 6 line context
... ...
@@ -14,128 +14,129 @@
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_CLP_H
20 20
#define LEMON_CLP_H
21 21

	
22 22
///\file
23 23
///\brief Header of the LEMON-CLP lp solver interface.
24 24

	
25 25
#include <vector>
26 26
#include <string>
27 27

	
28 28
#include <lemon/lp_base.h>
29 29

	
30 30
class ClpSimplex;
31 31

	
32 32
namespace lemon {
33 33

	
34 34
  /// \ingroup lp_group
35 35
  ///
36 36
  /// \brief Interface for the CLP solver
37 37
  ///
38 38
  /// This class implements an interface for the Clp LP solver.  The
39 39
  /// Clp library is an object oriented lp solver library developed at
40 40
  /// the IBM. The CLP is part of the COIN-OR package and it can be
41 41
  /// used with Common Public License.
42 42
  class ClpLp : public LpSolver {
43 43
  protected:
44 44

	
45 45
    ClpSimplex* _prob;
46 46

	
47 47
    std::map<std::string, int> _col_names_ref;
48 48
    std::map<std::string, int> _row_names_ref;
49 49

	
50 50
  public:
51 51

	
52 52
    /// \e
53 53
    ClpLp();
54 54
    /// \e
55 55
    ClpLp(const ClpLp&);
56 56
    /// \e
57 57
    ~ClpLp();
58 58

	
59 59
    /// \e
60 60
    virtual ClpLp* newSolver() const;
61 61
    /// \e
62 62
    virtual ClpLp* cloneSolver() const;
63 63

	
64 64
  protected:
65 65

	
66 66
    mutable double* _primal_ray;
67 67
    mutable double* _dual_ray;
68 68

	
69 69
    void _init_temporals();
70 70
    void _clear_temporals();
71 71

	
72 72
  protected:
73 73

	
74 74
    virtual const char* _solverName() const;
75 75

	
76 76
    virtual int _addCol();
77 77
    virtual int _addRow();
78
    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
78 79

	
79 80
    virtual void _eraseCol(int i);
80 81
    virtual void _eraseRow(int i);
81 82

	
82 83
    virtual void _eraseColId(int i);
83 84
    virtual void _eraseRowId(int i);
84 85

	
85 86
    virtual void _getColName(int col, std::string& name) const;
86 87
    virtual void _setColName(int col, const std::string& name);
87 88
    virtual int _colByName(const std::string& name) const;
88 89

	
89 90
    virtual void _getRowName(int row, std::string& name) const;
90 91
    virtual void _setRowName(int row, const std::string& name);
91 92
    virtual int _rowByName(const std::string& name) const;
92 93

	
93 94
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
94 95
    virtual void _getRowCoeffs(int i, InsertIterator b) const;
95 96

	
96 97
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
97 98
    virtual void _getColCoeffs(int i, InsertIterator b) const;
98 99

	
99 100
    virtual void _setCoeff(int row, int col, Value value);
100 101
    virtual Value _getCoeff(int row, int col) const;
101 102

	
102 103
    virtual void _setColLowerBound(int i, Value value);
103 104
    virtual Value _getColLowerBound(int i) const;
104 105
    virtual void _setColUpperBound(int i, Value value);
105 106
    virtual Value _getColUpperBound(int i) const;
106 107

	
107 108
    virtual void _setRowLowerBound(int i, Value value);
108 109
    virtual Value _getRowLowerBound(int i) const;
109 110
    virtual void _setRowUpperBound(int i, Value value);
110 111
    virtual Value _getRowUpperBound(int i) const;
111 112

	
112 113
    virtual void _setObjCoeffs(ExprIterator, ExprIterator);
113 114
    virtual void _getObjCoeffs(InsertIterator) const;
114 115

	
115 116
    virtual void _setObjCoeff(int i, Value obj_coef);
116 117
    virtual Value _getObjCoeff(int i) const;
117 118

	
118 119
    virtual void _setSense(Sense sense);
119 120
    virtual Sense _getSense() const;
120 121

	
121 122
    virtual SolveExitStatus _solve();
122 123

	
123 124
    virtual Value _getPrimal(int i) const;
124 125
    virtual Value _getDual(int i) const;
125 126

	
126 127
    virtual Value _getPrimalValue() const;
127 128

	
128 129
    virtual Value _getPrimalRay(int i) const;
129 130
    virtual Value _getDualRay(int i) const;
130 131

	
131 132
    virtual VarStatus _getColStatus(int i) const;
132 133
    virtual VarStatus _getRowStatus(int i) const;
133 134

	
134 135
    virtual ProblemType _getPrimalType() const;
135 136
    virtual ProblemType _getDualType() const;
136 137

	
137 138
    virtual void _clear();
138 139

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

	
19 19
#ifndef LEMON_CONCEPTS_DIGRAPH_H
20 20
#define LEMON_CONCEPTS_DIGRAPH_H
21 21

	
22 22
///\ingroup graph_concepts
23 23
///\file
24 24
///\brief The concept of directed graphs.
25 25

	
26 26
#include <lemon/core.h>
27 27
#include <lemon/concepts/maps.h>
28 28
#include <lemon/concept_check.h>
29 29
#include <lemon/concepts/graph_components.h>
30 30

	
31 31
namespace lemon {
32 32
  namespace concepts {
33 33

	
34 34
    /// \ingroup graph_concepts
35 35
    ///
36 36
    /// \brief Class describing the concept of directed graphs.
37 37
    ///
38
    /// This class describes the \ref concept "concept" of the
39
    /// immutable directed digraphs.
38
    /// This class describes the common interface of all directed
39
    /// graphs (digraphs).
40 40
    ///
41
    /// Note that actual digraph implementation like @ref ListDigraph or
42
    /// @ref SmartDigraph may have several additional functionality.
41
    /// Like all concept classes, it only provides an interface
42
    /// without any sensible implementation. So any general algorithm for
43
    /// directed graphs should compile with this class, but it will not
44
    /// run properly, of course.
45
    /// An actual digraph implementation like \ref ListDigraph or
46
    /// \ref SmartDigraph may have additional functionality.
43 47
    ///
44
    /// \sa concept
48
    /// \sa Graph
45 49
    class Digraph {
46 50
    private:
47
      ///Digraphs are \e not copy constructible. Use DigraphCopy() instead.
51
      /// Diraphs are \e not copy constructible. Use DigraphCopy instead.
52
      Digraph(const Digraph &) {}
53
      /// \brief Assignment of a digraph to another one is \e not allowed.
54
      /// Use DigraphCopy instead.
55
      void operator=(const Digraph &) {}
48 56

	
49
      ///Digraphs are \e not copy constructible. Use DigraphCopy() instead.
50
      ///
51
      Digraph(const Digraph &) {};
52
      ///\brief Assignment of \ref Digraph "Digraph"s to another ones are
53
      ///\e not allowed. Use DigraphCopy() instead.
57
    public:
58
      /// Default constructor.
59
      Digraph() { }
54 60

	
55
      ///Assignment of \ref Digraph "Digraph"s to another ones are
56
      ///\e not allowed.  Use DigraphCopy() instead.
57

	
58
      void operator=(const Digraph &) {}
59
    public:
60
      ///\e
61

	
62
      /// Defalult constructor.
63

	
64
      /// Defalult constructor.
65
      ///
66
      Digraph() { }
67
      /// Class for identifying a node of the digraph
61
      /// The node type of the digraph
68 62

	
69 63
      /// This class identifies a node of the digraph. It also serves
70 64
      /// as a base class of the node iterators,
71
      /// thus they will convert to this type.
65
      /// thus they convert to this type.
72 66
      class Node {
73 67
      public:
74 68
        /// Default constructor
75 69

	
76
        /// @warning The default constructor sets the iterator
77
        /// to an undefined value.
70
        /// Default constructor.
71
        /// \warning It sets the object to an undefined value.
78 72
        Node() { }
79 73
        /// Copy constructor.
80 74

	
81 75
        /// Copy constructor.
82 76
        ///
83 77
        Node(const Node&) { }
84 78

	
85
        /// Invalid constructor \& conversion.
79
        /// %Invalid constructor \& conversion.
86 80

	
87
        /// This constructor initializes the iterator to be invalid.
81
        /// Initializes the object to be invalid.
88 82
        /// \sa Invalid for more details.
89 83
        Node(Invalid) { }
90 84
        /// Equality operator
91 85

	
86
        /// Equality operator.
87
        ///
92 88
        /// Two iterators are equal if and only if they point to the
93
        /// same object or both are invalid.
89
        /// same object or both are \c INVALID.
94 90
        bool operator==(Node) const { return true; }
95 91

	
96 92
        /// Inequality operator
97 93

	
98
        /// \sa operator==(Node n)
99
        ///
94
        /// Inequality operator.
100 95
        bool operator!=(Node) const { return true; }
101 96

	
102 97
        /// Artificial ordering operator.
103 98

	
104
        /// To allow the use of digraph descriptors as key type in std::map or
105
        /// similar associative container we require this.
99
        /// Artificial ordering operator.
106 100
        ///
107
        /// \note This operator only have to define some strict ordering of
108
        /// the items; this order has nothing to do with the iteration
109
        /// ordering of the items.
101
        /// \note This operator only has to define some strict ordering of
102
        /// the nodes; this order has nothing to do with the iteration
103
        /// ordering of the nodes.
110 104
        bool operator<(Node) const { return false; }
111

	
112 105
      };
113 106

	
114
      /// This iterator goes through each node.
107
      /// Iterator class for the nodes.
115 108

	
116
      /// This iterator goes through each node.
109
      /// This iterator goes through each node of the digraph.
117 110
      /// Its usage is quite simple, for example you can count the number
118
      /// of nodes in digraph \c g of type \c Digraph like this:
111
      /// of nodes in a digraph \c g of type \c %Digraph like this:
119 112
      ///\code
120 113
      /// int count=0;
121 114
      /// for (Digraph::NodeIt n(g); n!=INVALID; ++n) ++count;
122 115
      ///\endcode
123 116
      class NodeIt : public Node {
124 117
      public:
125 118
        /// Default constructor
126 119

	
127
        /// @warning The default constructor sets the iterator
128
        /// to an undefined value.
120
        /// Default constructor.
121
        /// \warning It sets the iterator to an undefined value.
129 122
        NodeIt() { }
130 123
        /// Copy constructor.
131 124

	
132 125
        /// Copy constructor.
133 126
        ///
134 127
        NodeIt(const NodeIt& n) : Node(n) { }
135
        /// Invalid constructor \& conversion.
128
        /// %Invalid constructor \& conversion.
136 129

	
137
        /// Initialize the iterator to be invalid.
130
        /// Initializes the iterator to be invalid.
138 131
        /// \sa Invalid for more details.
139 132
        NodeIt(Invalid) { }
140 133
        /// Sets the iterator to the first node.
141 134

	
142
        /// Sets the iterator to the first node of \c g.
135
        /// Sets the iterator to the first node of the given digraph.
143 136
        ///
144
        NodeIt(const Digraph&) { }
145
        /// Node -> NodeIt conversion.
137
        explicit NodeIt(const Digraph&) { }
138
        /// Sets the iterator to the given node.
146 139

	
147
        /// Sets the iterator to the node of \c the digraph pointed by
148
        /// the trivial iterator.
149
        /// This feature necessitates that each time we
150
        /// iterate the arc-set, the iteration order is the same.
140
        /// Sets the iterator to the given node of the given digraph.
141
        ///
151 142
        NodeIt(const Digraph&, const Node&) { }
152 143
        /// Next node.
153 144

	
154 145
        /// Assign the iterator to the next node.
155 146
        ///
156 147
        NodeIt& operator++() { return *this; }
157 148
      };
158 149

	
159 150

	
160
      /// Class for identifying an arc of the digraph
151
      /// The arc type of the digraph
161 152

	
162 153
      /// This class identifies an arc of the digraph. It also serves
163 154
      /// as a base class of the arc iterators,
164 155
      /// thus they will convert to this type.
165 156
      class Arc {
166 157
      public:
167 158
        /// Default constructor
168 159

	
169
        /// @warning The default constructor sets the iterator
170
        /// to an undefined value.
160
        /// Default constructor.
161
        /// \warning It sets the object to an undefined value.
171 162
        Arc() { }
172 163
        /// Copy constructor.
173 164

	
174 165
        /// Copy constructor.
175 166
        ///
176 167
        Arc(const Arc&) { }
177
        /// Initialize the iterator to be invalid.
168
        /// %Invalid constructor \& conversion.
178 169

	
179
        /// Initialize the iterator to be invalid.
180
        ///
170
        /// Initializes the object to be invalid.
171
        /// \sa Invalid for more details.
181 172
        Arc(Invalid) { }
182 173
        /// Equality operator
183 174

	
175
        /// Equality operator.
176
        ///
184 177
        /// Two iterators are equal if and only if they point to the
185
        /// same object or both are invalid.
178
        /// same object or both are \c INVALID.
186 179
        bool operator==(Arc) const { return true; }
187 180
        /// Inequality operator
188 181

	
189
        /// \sa operator==(Arc n)
190
        ///
182
        /// Inequality operator.
191 183
        bool operator!=(Arc) const { return true; }
192 184

	
193 185
        /// Artificial ordering operator.
194 186

	
195
        /// To allow the use of digraph descriptors as key type in std::map or
196
        /// similar associative container we require this.
187
        /// Artificial ordering operator.
197 188
        ///
198
        /// \note This operator only have to define some strict ordering of
199
        /// the items; this order has nothing to do with the iteration
200
        /// ordering of the items.
189
        /// \note This operator only has to define some strict ordering of
190
        /// the arcs; this order has nothing to do with the iteration
191
        /// ordering of the arcs.
201 192
        bool operator<(Arc) const { return false; }
202 193
      };
203 194

	
204
      /// This iterator goes trough the outgoing arcs of a node.
195
      /// Iterator class for the outgoing arcs of a node.
205 196

	
206 197
      /// This iterator goes trough the \e outgoing arcs of a certain node
207 198
      /// of a digraph.
208 199
      /// Its usage is quite simple, for example you can count the number
209 200
      /// of outgoing arcs of a node \c n
210
      /// in digraph \c g of type \c Digraph as follows.
201
      /// in a digraph \c g of type \c %Digraph as follows.
211 202
      ///\code
212 203
      /// int count=0;
213
      /// for (Digraph::OutArcIt e(g, n); e!=INVALID; ++e) ++count;
204
      /// for (Digraph::OutArcIt a(g, n); a!=INVALID; ++a) ++count;
214 205
      ///\endcode
215

	
216 206
      class OutArcIt : public Arc {
217 207
      public:
218 208
        /// Default constructor
219 209

	
220
        /// @warning The default constructor sets the iterator
221
        /// to an undefined value.
210
        /// Default constructor.
211
        /// \warning It sets the iterator to an undefined value.
222 212
        OutArcIt() { }
223 213
        /// Copy constructor.
224 214

	
225 215
        /// Copy constructor.
226 216
        ///
227 217
        OutArcIt(const OutArcIt& e) : Arc(e) { }
228
        /// Initialize the iterator to be invalid.
218
        /// %Invalid constructor \& conversion.
229 219

	
230
        /// Initialize the iterator to be invalid.
220
        /// Initializes the iterator to be invalid.
221
        /// \sa Invalid for more details.
222
        OutArcIt(Invalid) { }
223
        /// Sets the iterator to the first outgoing arc.
224

	
225
        /// Sets the iterator to the first outgoing arc of the given node.
231 226
        ///
232
        OutArcIt(Invalid) { }
233
        /// This constructor sets the iterator to the first outgoing arc.
227
        OutArcIt(const Digraph&, const Node&) { }
228
        /// Sets the iterator to the given arc.
234 229

	
235
        /// This constructor sets the iterator to the first outgoing arc of
236
        /// the node.
237
        OutArcIt(const Digraph&, const Node&) { }
238
        /// Arc -> OutArcIt conversion
239

	
240
        /// Sets the iterator to the value of the trivial iterator.
241
        /// This feature necessitates that each time we
242
        /// iterate the arc-set, the iteration order is the same.
230
        /// Sets the iterator to the given arc of the given digraph.
231
        ///
243 232
        OutArcIt(const Digraph&, const Arc&) { }
244
        ///Next outgoing arc
233
        /// Next outgoing arc
245 234

	
246 235
        /// Assign the iterator to the next
247 236
        /// outgoing arc of the corresponding node.
248 237
        OutArcIt& operator++() { return *this; }
249 238
      };
250 239

	
251
      /// This iterator goes trough the incoming arcs of a node.
240
      /// Iterator class for the incoming arcs of a node.
252 241

	
253 242
      /// This iterator goes trough the \e incoming arcs of a certain node
254 243
      /// of a digraph.
255 244
      /// Its usage is quite simple, for example you can count the number
256
      /// of outgoing arcs of a node \c n
257
      /// in digraph \c g of type \c Digraph as follows.
245
      /// of incoming arcs of a node \c n
246
      /// in a digraph \c g of type \c %Digraph as follows.
258 247
      ///\code
259 248
      /// int count=0;
260
      /// for(Digraph::InArcIt e(g, n); e!=INVALID; ++e) ++count;
249
      /// for(Digraph::InArcIt a(g, n); a!=INVALID; ++a) ++count;
261 250
      ///\endcode
262

	
263 251
      class InArcIt : public Arc {
264 252
      public:
265 253
        /// Default constructor
266 254

	
267
        /// @warning The default constructor sets the iterator
268
        /// to an undefined value.
255
        /// Default constructor.
256
        /// \warning It sets the iterator to an undefined value.
269 257
        InArcIt() { }
270 258
        /// Copy constructor.
271 259

	
272 260
        /// Copy constructor.
273 261
        ///
274 262
        InArcIt(const InArcIt& e) : Arc(e) { }
275
        /// Initialize the iterator to be invalid.
263
        /// %Invalid constructor \& conversion.
276 264

	
277
        /// Initialize the iterator to be invalid.
265
        /// Initializes the iterator to be invalid.
266
        /// \sa Invalid for more details.
267
        InArcIt(Invalid) { }
268
        /// Sets the iterator to the first incoming arc.
269

	
270
        /// Sets the iterator to the first incoming arc of the given node.
278 271
        ///
279
        InArcIt(Invalid) { }
280
        /// This constructor sets the iterator to first incoming arc.
272
        InArcIt(const Digraph&, const Node&) { }
273
        /// Sets the iterator to the given arc.
281 274

	
282
        /// This constructor set the iterator to the first incoming arc of
283
        /// the node.
284
        InArcIt(const Digraph&, const Node&) { }
285
        /// Arc -> InArcIt conversion
286

	
287
        /// Sets the iterator to the value of the trivial iterator \c e.
288
        /// This feature necessitates that each time we
289
        /// iterate the arc-set, the iteration order is the same.
275
        /// Sets the iterator to the given arc of the given digraph.
276
        ///
290 277
        InArcIt(const Digraph&, const Arc&) { }
291 278
        /// Next incoming arc
292 279

	
293
        /// Assign the iterator to the next inarc of the corresponding node.
294
        ///
280
        /// Assign the iterator to the next
281
        /// incoming arc of the corresponding node.
295 282
        InArcIt& operator++() { return *this; }
296 283
      };
297
      /// This iterator goes through each arc.
298 284

	
299
      /// This iterator goes through each arc of a digraph.
285
      /// Iterator class for the arcs.
286

	
287
      /// This iterator goes through each arc of the digraph.
300 288
      /// Its usage is quite simple, for example you can count the number
301
      /// of arcs in a digraph \c g of type \c Digraph as follows:
289
      /// of arcs in a digraph \c g of type \c %Digraph as follows:
302 290
      ///\code
303 291
      /// int count=0;
304
      /// for(Digraph::ArcIt e(g); e!=INVALID; ++e) ++count;
292
      /// for(Digraph::ArcIt a(g); a!=INVALID; ++a) ++count;
305 293
      ///\endcode
306 294
      class ArcIt : public Arc {
307 295
      public:
308 296
        /// Default constructor
309 297

	
310
        /// @warning The default constructor sets the iterator
311
        /// to an undefined value.
298
        /// Default constructor.
299
        /// \warning It sets the iterator to an undefined value.
312 300
        ArcIt() { }
313 301
        /// Copy constructor.
314 302

	
315 303
        /// Copy constructor.
316 304
        ///
317 305
        ArcIt(const ArcIt& e) : Arc(e) { }
318
        /// Initialize the iterator to be invalid.
306
        /// %Invalid constructor \& conversion.
319 307

	
320
        /// Initialize the iterator to be invalid.
308
        /// Initializes the iterator to be invalid.
309
        /// \sa Invalid for more details.
310
        ArcIt(Invalid) { }
311
        /// Sets the iterator to the first arc.
312

	
313
        /// Sets the iterator to the first arc of the given digraph.
321 314
        ///
322
        ArcIt(Invalid) { }
323
        /// This constructor sets the iterator to the first arc.
315
        explicit ArcIt(const Digraph& g) { ignore_unused_variable_warning(g); }
316
        /// Sets the iterator to the given arc.
324 317

	
325
        /// This constructor sets the iterator to the first arc of \c g.
326
        ///@param g the digraph
327
        ArcIt(const Digraph& g) { ignore_unused_variable_warning(g); }
328
        /// Arc -> ArcIt conversion
329

	
330
        /// Sets the iterator to the value of the trivial iterator \c e.
331
        /// This feature necessitates that each time we
332
        /// iterate the arc-set, the iteration order is the same.
318
        /// Sets the iterator to the given arc of the given digraph.
319
        ///
333 320
        ArcIt(const Digraph&, const Arc&) { }
334
        ///Next arc
321
        /// Next arc
335 322

	
336 323
        /// Assign the iterator to the next arc.
324
        ///
337 325
        ArcIt& operator++() { return *this; }
338 326
      };
339
      ///Gives back the target node of an arc.
340 327

	
341
      ///Gives back the target node of an arc.
328
      /// \brief The source node of the arc.
342 329
      ///
343
      Node target(Arc) const { return INVALID; }
344
      ///Gives back the source node of an arc.
345

	
346
      ///Gives back the source node of an arc.
347
      ///
330
      /// Returns the source node of the given arc.
348 331
      Node source(Arc) const { return INVALID; }
349 332

	
350
      /// \brief Returns the ID of the node.
333
      /// \brief The target node of the arc.
334
      ///
335
      /// Returns the target node of the given arc.
336
      Node target(Arc) const { return INVALID; }
337

	
338
      /// \brief The ID of the node.
339
      ///
340
      /// Returns the ID of the given node.
351 341
      int id(Node) const { return -1; }
352 342

	
353
      /// \brief Returns the ID of the arc.
343
      /// \brief The ID of the arc.
344
      ///
345
      /// Returns the ID of the given arc.
354 346
      int id(Arc) const { return -1; }
355 347

	
356
      /// \brief Returns the node with the given ID.
348
      /// \brief The node with the given ID.
357 349
      ///
358
      /// \pre The argument should be a valid node ID in the graph.
350
      /// Returns the node with the given ID.
351
      /// \pre The argument should be a valid node ID in the digraph.
359 352
      Node nodeFromId(int) const { return INVALID; }
360 353

	
361
      /// \brief Returns the arc with the given ID.
354
      /// \brief The arc with the given ID.
362 355
      ///
363
      /// \pre The argument should be a valid arc ID in the graph.
356
      /// Returns the arc with the given ID.
357
      /// \pre The argument should be a valid arc ID in the digraph.
364 358
      Arc arcFromId(int) const { return INVALID; }
365 359

	
366
      /// \brief Returns an upper bound on the node IDs.
360
      /// \brief An upper bound on the node IDs.
361
      ///
362
      /// Returns an upper bound on the node IDs.
367 363
      int maxNodeId() const { return -1; }
368 364

	
369
      /// \brief Returns an upper bound on the arc IDs.
365
      /// \brief An upper bound on the arc IDs.
366
      ///
367
      /// Returns an upper bound on the arc IDs.
370 368
      int maxArcId() const { return -1; }
371 369

	
372 370
      void first(Node&) const {}
373 371
      void next(Node&) const {}
374 372

	
375 373
      void first(Arc&) const {}
376 374
      void next(Arc&) const {}
377 375

	
378 376

	
379 377
      void firstIn(Arc&, const Node&) const {}
380 378
      void nextIn(Arc&) const {}
381 379

	
382 380
      void firstOut(Arc&, const Node&) const {}
383 381
      void nextOut(Arc&) const {}
384 382

	
385 383
      // The second parameter is dummy.
386 384
      Node fromId(int, Node) const { return INVALID; }
387 385
      // The second parameter is dummy.
388 386
      Arc fromId(int, Arc) const { return INVALID; }
389 387

	
390 388
      // Dummy parameter.
391 389
      int maxId(Node) const { return -1; }
392 390
      // Dummy parameter.
393 391
      int maxId(Arc) const { return -1; }
394 392

	
393
      /// \brief The opposite node on the arc.
394
      ///
395
      /// Returns the opposite node on the given arc.
396
      Node oppositeNode(Node, Arc) const { return INVALID; }
397

	
395 398
      /// \brief The base node of the iterator.
396 399
      ///
397
      /// Gives back the base node of the iterator.
398
      /// It is always the target of the pointed arc.
399
      Node baseNode(const InArcIt&) const { return INVALID; }
400
      /// Returns the base node of the given outgoing arc iterator
401
      /// (i.e. the source node of the corresponding arc).
402
      Node baseNode(OutArcIt) const { return INVALID; }
400 403

	
401 404
      /// \brief The running node of the iterator.
402 405
      ///
403
      /// Gives back the running node of the iterator.
404
      /// It is always the source of the pointed arc.
405
      Node runningNode(const InArcIt&) const { return INVALID; }
406
      /// Returns the running node of the given outgoing arc iterator
407
      /// (i.e. the target node of the corresponding arc).
408
      Node runningNode(OutArcIt) const { return INVALID; }
406 409

	
407 410
      /// \brief The base node of the iterator.
408 411
      ///
409
      /// Gives back the base node of the iterator.
410
      /// It is always the source of the pointed arc.
411
      Node baseNode(const OutArcIt&) const { return INVALID; }
412
      /// Returns the base node of the given incomming arc iterator
413
      /// (i.e. the target node of the corresponding arc).
414
      Node baseNode(InArcIt) const { return INVALID; }
412 415

	
413 416
      /// \brief The running node of the iterator.
414 417
      ///
415
      /// Gives back the running node of the iterator.
416
      /// It is always the target of the pointed arc.
417
      Node runningNode(const OutArcIt&) const { return INVALID; }
418
      /// Returns the running node of the given incomming arc iterator
419
      /// (i.e. the source node of the corresponding arc).
420
      Node runningNode(InArcIt) const { return INVALID; }
418 421

	
419
      /// \brief The opposite node on the given arc.
422
      /// \brief Standard graph map type for the nodes.
420 423
      ///
421
      /// Gives back the opposite node on the given arc.
422
      Node oppositeNode(const Node&, const Arc&) const { return INVALID; }
423

	
424
      /// \brief Reference map of the nodes to type \c T.
425
      ///
426
      /// Reference map of the nodes to type \c T.
424
      /// Standard graph map type for the nodes.
425
      /// It conforms to the ReferenceMap concept.
427 426
      template<class T>
428 427
      class NodeMap : public ReferenceMap<Node, T, T&, const T&> {
429 428
      public:
430 429

	
431
        ///\e
432
        NodeMap(const Digraph&) { }
433
        ///\e
430
        /// Constructor
431
        explicit NodeMap(const Digraph&) { }
432
        /// Constructor with given initial value
434 433
        NodeMap(const Digraph&, T) { }
435 434

	
436 435
      private:
437 436
        ///Copy constructor
438 437
        NodeMap(const NodeMap& nm) : 
439 438
          ReferenceMap<Node, T, T&, const T&>(nm) { }
440 439
        ///Assignment operator
441 440
        template <typename CMap>
442 441
        NodeMap& operator=(const CMap&) {
443 442
          checkConcept<ReadMap<Node, T>, CMap>();
444 443
          return *this;
445 444
        }
446 445
      };
447 446

	
448
      /// \brief Reference map of the arcs to type \c T.
447
      /// \brief Standard graph map type for the arcs.
449 448
      ///
450
      /// Reference map of the arcs to type \c T.
449
      /// Standard graph map type for the arcs.
450
      /// It conforms to the ReferenceMap concept.
451 451
      template<class T>
452 452
      class ArcMap : public ReferenceMap<Arc, T, T&, const T&> {
453 453
      public:
454 454

	
455
        ///\e
456
        ArcMap(const Digraph&) { }
457
        ///\e
455
        /// Constructor
456
        explicit ArcMap(const Digraph&) { }
457
        /// Constructor with given initial value
458 458
        ArcMap(const Digraph&, T) { }
459

	
459 460
      private:
460 461
        ///Copy constructor
461 462
        ArcMap(const ArcMap& em) :
462 463
          ReferenceMap<Arc, T, T&, const T&>(em) { }
463 464
        ///Assignment operator
464 465
        template <typename CMap>
465 466
        ArcMap& operator=(const CMap&) {
466 467
          checkConcept<ReadMap<Arc, T>, CMap>();
467 468
          return *this;
468 469
        }
469 470
      };
470 471

	
471 472
      template <typename _Digraph>
472 473
      struct Constraints {
473 474
        void constraints() {
474 475
          checkConcept<BaseDigraphComponent, _Digraph>();
475 476
          checkConcept<IterableDigraphComponent<>, _Digraph>();
476 477
          checkConcept<IDableDigraphComponent<>, _Digraph>();
477 478
          checkConcept<MappableDigraphComponent<>, _Digraph>();
478 479
        }
479 480
      };
480 481

	
481 482
    };
482 483

	
483 484
  } //namespace concepts
484 485
} //namespace lemon
485 486

	
486 487

	
487 488

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

	
19 19
///\ingroup graph_concepts
20 20
///\file
21
///\brief The concept of Undirected Graphs.
21
///\brief The concept of undirected graphs.
22 22

	
23 23
#ifndef LEMON_CONCEPTS_GRAPH_H
24 24
#define LEMON_CONCEPTS_GRAPH_H
25 25

	
26 26
#include <lemon/concepts/graph_components.h>
27
#include <lemon/concepts/maps.h>
28
#include <lemon/concept_check.h>
27 29
#include <lemon/core.h>
28 30

	
29 31
namespace lemon {
30 32
  namespace concepts {
31 33

	
32 34
    /// \ingroup graph_concepts
33 35
    ///
34
    /// \brief Class describing the concept of Undirected Graphs.
36
    /// \brief Class describing the concept of undirected graphs.
35 37
    ///
36
    /// This class describes the common interface of all Undirected
37
    /// Graphs.
38
    /// This class describes the common interface of all undirected
39
    /// graphs.
38 40
    ///
39
    /// As all concept describing classes it provides only interface
40
    /// without any sensible implementation. So any algorithm for
41
    /// undirected graph should compile with this class, but it will not
41
    /// Like all concept classes, it only provides an interface
42
    /// without any sensible implementation. So any general algorithm for
43
    /// undirected graphs should compile with this class, but it will not
42 44
    /// run properly, of course.
45
    /// An actual graph implementation like \ref ListGraph or
46
    /// \ref SmartGraph may have additional functionality.    
43 47
    ///
44
    /// The LEMON undirected graphs also fulfill the concept of
45
    /// directed graphs (\ref lemon::concepts::Digraph "Digraph
46
    /// Concept"). Each edges can be seen as two opposite
47
    /// directed arc and consequently the undirected graph can be
48
    /// seen as the direceted graph of these directed arcs. The
49
    /// Graph has the Edge inner class for the edges and
50
    /// the Arc type for the directed arcs. The Arc type is
51
    /// convertible to Edge or inherited from it so from a directed
52
    /// arc we can get the represented edge.
48
    /// The undirected graphs also fulfill the concept of \ref Digraph
49
    /// "directed graphs", since each edge can also be regarded as two
50
    /// oppositely directed arcs.
51
    /// Undirected graphs provide an Edge type for the undirected edges and
52
    /// an Arc type for the directed arcs. The Arc type is convertible to
53
    /// Edge or inherited from it, i.e. the corresponding edge can be
54
    /// obtained from an arc.
55
    /// EdgeIt and EdgeMap classes can be used for the edges, while ArcIt
56
    /// and ArcMap classes can be used for the arcs (just like in digraphs).
57
    /// Both InArcIt and OutArcIt iterates on the same edges but with
58
    /// opposite direction. IncEdgeIt also iterates on the same edges
59
    /// as OutArcIt and InArcIt, but it is not convertible to Arc,
60
    /// only to Edge.
53 61
    ///
54
    /// In the sense of the LEMON each edge has a default
55
    /// direction (it should be in every computer implementation,
56
    /// because the order of edge's nodes defines an
57
    /// orientation). With the default orientation we can define that
58
    /// the directed arc is forward or backward directed. With the \c
59
    /// direction() and \c direct() function we can get the direction
60
    /// of the directed arc and we can direct an edge.
62
    /// In LEMON, each undirected edge has an inherent orientation.
63
    /// Thus it can defined if an arc is forward or backward oriented in
64
    /// an undirected graph with respect to this default oriantation of
65
    /// the represented edge.
66
    /// With the direction() and direct() functions the direction
67
    /// of an arc can be obtained and set, respectively.
61 68
    ///
62
    /// The EdgeIt is an iterator for the edges. We can use
63
    /// the EdgeMap to map values for the edges. The InArcIt and
64
    /// OutArcIt iterates on the same edges but with opposite
65
    /// direction. The IncEdgeIt iterates also on the same edges
66
    /// as the OutArcIt and InArcIt but it is not convertible to Arc just
67
    /// to Edge.
69
    /// Only nodes and edges can be added to or removed from an undirected
70
    /// graph and the corresponding arcs are added or removed automatically.
71
    ///
72
    /// \sa Digraph
68 73
    class Graph {
74
    private:
75
      /// Graphs are \e not copy constructible. Use DigraphCopy instead.
76
      Graph(const Graph&) {}
77
      /// \brief Assignment of a graph to another one is \e not allowed.
78
      /// Use DigraphCopy instead.
79
      void operator=(const Graph&) {}
80

	
69 81
    public:
70
      /// \brief The undirected graph should be tagged by the
71
      /// UndirectedTag.
82
      /// Default constructor.
83
      Graph() {}
84

	
85
      /// \brief Undirected graphs should be tagged with \c UndirectedTag.
72 86
      ///
73
      /// The undirected graph should be tagged by the UndirectedTag. This
74
      /// tag helps the enable_if technics to make compile time
87
      /// Undirected graphs should be tagged with \c UndirectedTag.
88
      /// 
89
      /// This tag helps the \c enable_if technics to make compile time
75 90
      /// specializations for undirected graphs.
76 91
      typedef True UndirectedTag;
77 92

	
78
      /// \brief The base type of node iterators,
79
      /// or in other words, the trivial node iterator.
80
      ///
81
      /// This is the base type of each node iterator,
82
      /// thus each kind of node iterator converts to this.
83
      /// More precisely each kind of node iterator should be inherited
84
      /// from the trivial node iterator.
93
      /// The node type of the graph
94

	
95
      /// This class identifies a node of the graph. It also serves
96
      /// as a base class of the node iterators,
97
      /// thus they convert to this type.
85 98
      class Node {
86 99
      public:
87 100
        /// Default constructor
88 101

	
89
        /// @warning The default constructor sets the iterator
90
        /// to an undefined value.
102
        /// Default constructor.
103
        /// \warning It sets the object to an undefined value.
91 104
        Node() { }
92 105
        /// Copy constructor.
93 106

	
94 107
        /// Copy constructor.
95 108
        ///
96 109
        Node(const Node&) { }
97 110

	
98
        /// Invalid constructor \& conversion.
111
        /// %Invalid constructor \& conversion.
99 112

	
100
        /// This constructor initializes the iterator to be invalid.
113
        /// Initializes the object to be invalid.
101 114
        /// \sa Invalid for more details.
102 115
        Node(Invalid) { }
103 116
        /// Equality operator
104 117

	
118
        /// Equality operator.
119
        ///
105 120
        /// Two iterators are equal if and only if they point to the
106
        /// same object or both are invalid.
121
        /// same object or both are \c INVALID.
107 122
        bool operator==(Node) const { return true; }
108 123

	
109 124
        /// Inequality operator
110 125

	
111
        /// \sa operator==(Node n)
112
        ///
126
        /// Inequality operator.
113 127
        bool operator!=(Node) const { return true; }
114 128

	
115 129
        /// Artificial ordering operator.
116 130

	
117
        /// To allow the use of graph descriptors as key type in std::map or
118
        /// similar associative container we require this.
131
        /// Artificial ordering operator.
119 132
        ///
120
        /// \note This operator only have to define some strict ordering of
133
        /// \note This operator only has to define some strict ordering of
121 134
        /// the items; this order has nothing to do with the iteration
122 135
        /// ordering of the items.
123 136
        bool operator<(Node) const { return false; }
124 137

	
125 138
      };
126 139

	
127
      /// This iterator goes through each node.
140
      /// Iterator class for the nodes.
128 141

	
129
      /// This iterator goes through each node.
142
      /// This iterator goes through each node of the graph.
130 143
      /// Its usage is quite simple, for example you can count the number
131
      /// of nodes in graph \c g of type \c Graph like this:
144
      /// of nodes in a graph \c g of type \c %Graph like this:
132 145
      ///\code
133 146
      /// int count=0;
134 147
      /// for (Graph::NodeIt n(g); n!=INVALID; ++n) ++count;
135 148
      ///\endcode
136 149
      class NodeIt : public Node {
137 150
      public:
138 151
        /// Default constructor
139 152

	
140
        /// @warning The default constructor sets the iterator
141
        /// to an undefined value.
153
        /// Default constructor.
154
        /// \warning It sets the iterator to an undefined value.
142 155
        NodeIt() { }
143 156
        /// Copy constructor.
144 157

	
145 158
        /// Copy constructor.
146 159
        ///
147 160
        NodeIt(const NodeIt& n) : Node(n) { }
148
        /// Invalid constructor \& conversion.
161
        /// %Invalid constructor \& conversion.
149 162

	
150
        /// Initialize the iterator to be invalid.
163
        /// Initializes the iterator to be invalid.
151 164
        /// \sa Invalid for more details.
152 165
        NodeIt(Invalid) { }
153 166
        /// Sets the iterator to the first node.
154 167

	
155
        /// Sets the iterator to the first node of \c g.
168
        /// Sets the iterator to the first node of the given digraph.
156 169
        ///
157
        NodeIt(const Graph&) { }
158
        /// Node -> NodeIt conversion.
170
        explicit NodeIt(const Graph&) { }
171
        /// Sets the iterator to the given node.
159 172

	
160
        /// Sets the iterator to the node of \c the graph pointed by
161
        /// the trivial iterator.
162
        /// This feature necessitates that each time we
163
        /// iterate the arc-set, the iteration order is the same.
173
        /// Sets the iterator to the given node of the given digraph.
174
        ///
164 175
        NodeIt(const Graph&, const Node&) { }
165 176
        /// Next node.
166 177

	
167 178
        /// Assign the iterator to the next node.
168 179
        ///
169 180
        NodeIt& operator++() { return *this; }
170 181
      };
171 182

	
172 183

	
173
      /// The base type of the edge iterators.
184
      /// The edge type of the graph
174 185

	
175
      /// The base type of the edge iterators.
176
      ///
186
      /// This class identifies an edge of the graph. It also serves
187
      /// as a base class of the edge iterators,
188
      /// thus they will convert to this type.
177 189
      class Edge {
178 190
      public:
179 191
        /// Default constructor
180 192

	
181
        /// @warning The default constructor sets the iterator
182
        /// to an undefined value.
193
        /// Default constructor.
194
        /// \warning It sets the object to an undefined value.
183 195
        Edge() { }
184 196
        /// Copy constructor.
185 197

	
186 198
        /// Copy constructor.
187 199
        ///
188 200
        Edge(const Edge&) { }
189
        /// Initialize the iterator to be invalid.
201
        /// %Invalid constructor \& conversion.
190 202

	
191
        /// Initialize the iterator to be invalid.
192
        ///
203
        /// Initializes the object to be invalid.
204
        /// \sa Invalid for more details.
193 205
        Edge(Invalid) { }
194 206
        /// Equality operator
195 207

	
208
        /// Equality operator.
209
        ///
196 210
        /// Two iterators are equal if and only if they point to the
197
        /// same object or both are invalid.
211
        /// same object or both are \c INVALID.
198 212
        bool operator==(Edge) const { return true; }
199 213
        /// Inequality operator
200 214

	
201
        /// \sa operator==(Edge n)
202
        ///
215
        /// Inequality operator.
203 216
        bool operator!=(Edge) const { return true; }
204 217

	
205 218
        /// Artificial ordering operator.
206 219

	
207
        /// To allow the use of graph descriptors as key type in std::map or
208
        /// similar associative container we require this.
220
        /// Artificial ordering operator.
209 221
        ///
210
        /// \note This operator only have to define some strict ordering of
211
        /// the items; this order has nothing to do with the iteration
212
        /// ordering of the items.
222
        /// \note This operator only has to define some strict ordering of
223
        /// the edges; this order has nothing to do with the iteration
224
        /// ordering of the edges.
213 225
        bool operator<(Edge) const { return false; }
214 226
      };
215 227

	
216
      /// This iterator goes through each edge.
228
      /// Iterator class for the edges.
217 229

	
218
      /// This iterator goes through each edge of a graph.
230
      /// This iterator goes through each edge of the graph.
219 231
      /// Its usage is quite simple, for example you can count the number
220
      /// of edges in a graph \c g of type \c Graph as follows:
232
      /// of edges in a graph \c g of type \c %Graph as follows:
221 233
      ///\code
222 234
      /// int count=0;
223 235
      /// for(Graph::EdgeIt e(g); e!=INVALID; ++e) ++count;
224 236
      ///\endcode
225 237
      class EdgeIt : public Edge {
226 238
      public:
227 239
        /// Default constructor
228 240

	
229
        /// @warning The default constructor sets the iterator
230
        /// to an undefined value.
241
        /// Default constructor.
242
        /// \warning It sets the iterator to an undefined value.
231 243
        EdgeIt() { }
232 244
        /// Copy constructor.
233 245

	
234 246
        /// Copy constructor.
235 247
        ///
236 248
        EdgeIt(const EdgeIt& e) : Edge(e) { }
237
        /// Initialize the iterator to be invalid.
249
        /// %Invalid constructor \& conversion.
238 250

	
239
        /// Initialize the iterator to be invalid.
251
        /// Initializes the iterator to be invalid.
252
        /// \sa Invalid for more details.
253
        EdgeIt(Invalid) { }
254
        /// Sets the iterator to the first edge.
255

	
256
        /// Sets the iterator to the first edge of the given graph.
240 257
        ///
241
        EdgeIt(Invalid) { }
242
        /// This constructor sets the iterator to the first edge.
258
        explicit EdgeIt(const Graph&) { }
259
        /// Sets the iterator to the given edge.
243 260

	
244
        /// This constructor sets the iterator to the first edge.
245
        EdgeIt(const Graph&) { }
246
        /// Edge -> EdgeIt conversion
247

	
248
        /// Sets the iterator to the value of the trivial iterator.
249
        /// This feature necessitates that each time we
250
        /// iterate the edge-set, the iteration order is the
251
        /// same.
261
        /// Sets the iterator to the given edge of the given graph.
262
        ///
252 263
        EdgeIt(const Graph&, const Edge&) { }
253 264
        /// Next edge
254 265

	
255 266
        /// Assign the iterator to the next edge.
267
        ///
256 268
        EdgeIt& operator++() { return *this; }
257 269
      };
258 270

	
259
      /// \brief This iterator goes trough the incident undirected
260
      /// arcs of a node.
261
      ///
262
      /// This iterator goes trough the incident edges
263
      /// of a certain node of a graph. You should assume that the
264
      /// loop arcs will be iterated twice.
265
      ///
271
      /// Iterator class for the incident edges of a node.
272

	
273
      /// This iterator goes trough the incident undirected edges
274
      /// of a certain node of a graph.
266 275
      /// Its usage is quite simple, for example you can compute the
267
      /// degree (i.e. count the number of incident arcs of a node \c n
268
      /// in graph \c g of type \c Graph as follows.
276
      /// degree (i.e. the number of incident edges) of a node \c n
277
      /// in a graph \c g of type \c %Graph as follows.
269 278
      ///
270 279
      ///\code
271 280
      /// int count=0;
272 281
      /// for(Graph::IncEdgeIt e(g, n); e!=INVALID; ++e) ++count;
273 282
      ///\endcode
283
      ///
284
      /// \warning Loop edges will be iterated twice.
274 285
      class IncEdgeIt : public Edge {
275 286
      public:
276 287
        /// Default constructor
277 288

	
278
        /// @warning The default constructor sets the iterator
279
        /// to an undefined value.
289
        /// Default constructor.
290
        /// \warning It sets the iterator to an undefined value.
280 291
        IncEdgeIt() { }
281 292
        /// Copy constructor.
282 293

	
283 294
        /// Copy constructor.
284 295
        ///
285 296
        IncEdgeIt(const IncEdgeIt& e) : Edge(e) { }
286
        /// Initialize the iterator to be invalid.
297
        /// %Invalid constructor \& conversion.
287 298

	
288
        /// Initialize the iterator to be invalid.
299
        /// Initializes the iterator to be invalid.
300
        /// \sa Invalid for more details.
301
        IncEdgeIt(Invalid) { }
302
        /// Sets the iterator to the first incident edge.
303

	
304
        /// Sets the iterator to the first incident edge of the given node.
289 305
        ///
290
        IncEdgeIt(Invalid) { }
291
        /// This constructor sets the iterator to first incident arc.
306
        IncEdgeIt(const Graph&, const Node&) { }
307
        /// Sets the iterator to the given edge.
292 308

	
293
        /// This constructor set the iterator to the first incident arc of
294
        /// the node.
295
        IncEdgeIt(const Graph&, const Node&) { }
296
        /// Edge -> IncEdgeIt conversion
309
        /// Sets the iterator to the given edge of the given graph.
310
        ///
311
        IncEdgeIt(const Graph&, const Edge&) { }
312
        /// Next incident edge
297 313

	
298
        /// Sets the iterator to the value of the trivial iterator \c e.
299
        /// This feature necessitates that each time we
300
        /// iterate the arc-set, the iteration order is the same.
301
        IncEdgeIt(const Graph&, const Edge&) { }
302
        /// Next incident arc
303

	
304
        /// Assign the iterator to the next incident arc
314
        /// Assign the iterator to the next incident edge
305 315
        /// of the corresponding node.
306 316
        IncEdgeIt& operator++() { return *this; }
307 317
      };
308 318

	
309
      /// The directed arc type.
319
      /// The arc type of the graph
310 320

	
311
      /// The directed arc type. It can be converted to the
312
      /// edge or it should be inherited from the undirected
313
      /// edge.
321
      /// This class identifies a directed arc of the graph. It also serves
322
      /// as a base class of the arc iterators,
323
      /// thus they will convert to this type.
314 324
      class Arc {
315 325
      public:
316 326
        /// Default constructor
317 327

	
318
        /// @warning The default constructor sets the iterator
319
        /// to an undefined value.
328
        /// Default constructor.
329
        /// \warning It sets the object to an undefined value.
320 330
        Arc() { }
321 331
        /// Copy constructor.
322 332

	
323 333
        /// Copy constructor.
324 334
        ///
325 335
        Arc(const Arc&) { }
326
        /// Initialize the iterator to be invalid.
336
        /// %Invalid constructor \& conversion.
327 337

	
328
        /// Initialize the iterator to be invalid.
329
        ///
338
        /// Initializes the object to be invalid.
339
        /// \sa Invalid for more details.
330 340
        Arc(Invalid) { }
331 341
        /// Equality operator
332 342

	
343
        /// Equality operator.
344
        ///
333 345
        /// Two iterators are equal if and only if they point to the
334
        /// same object or both are invalid.
346
        /// same object or both are \c INVALID.
335 347
        bool operator==(Arc) const { return true; }
336 348
        /// Inequality operator
337 349

	
338
        /// \sa operator==(Arc n)
339
        ///
350
        /// Inequality operator.
340 351
        bool operator!=(Arc) const { return true; }
341 352

	
342 353
        /// Artificial ordering operator.
343 354

	
344
        /// To allow the use of graph descriptors as key type in std::map or
345
        /// similar associative container we require this.
355
        /// Artificial ordering operator.
346 356
        ///
347
        /// \note This operator only have to define some strict ordering of
348
        /// the items; this order has nothing to do with the iteration
349
        /// ordering of the items.
357
        /// \note This operator only has to define some strict ordering of
358
        /// the arcs; this order has nothing to do with the iteration
359
        /// ordering of the arcs.
350 360
        bool operator<(Arc) const { return false; }
351 361

	
352
        /// Converison to Edge
362
        /// Converison to \c Edge
363
        
364
        /// Converison to \c Edge.
365
        ///
353 366
        operator Edge() const { return Edge(); }
354 367
      };
355
      /// This iterator goes through each directed arc.
356 368

	
357
      /// This iterator goes through each arc of a graph.
369
      /// Iterator class for the arcs.
370

	
371
      /// This iterator goes through each directed arc of the graph.
358 372
      /// Its usage is quite simple, for example you can count the number
359
      /// of arcs in a graph \c g of type \c Graph as follows:
373
      /// of arcs in a graph \c g of type \c %Graph as follows:
360 374
      ///\code
361 375
      /// int count=0;
362
      /// for(Graph::ArcIt e(g); e!=INVALID; ++e) ++count;
376
      /// for(Graph::ArcIt a(g); a!=INVALID; ++a) ++count;
363 377
      ///\endcode
364 378
      class ArcIt : public Arc {
365 379
      public:
366 380
        /// Default constructor
367 381

	
368
        /// @warning The default constructor sets the iterator
369
        /// to an undefined value.
382
        /// Default constructor.
383
        /// \warning It sets the iterator to an undefined value.
370 384
        ArcIt() { }
371 385
        /// Copy constructor.
372 386

	
373 387
        /// Copy constructor.
374 388
        ///
375 389
        ArcIt(const ArcIt& e) : Arc(e) { }
376
        /// Initialize the iterator to be invalid.
390
        /// %Invalid constructor \& conversion.
377 391

	
378
        /// Initialize the iterator to be invalid.
392
        /// Initializes the iterator to be invalid.
393
        /// \sa Invalid for more details.
394
        ArcIt(Invalid) { }
395
        /// Sets the iterator to the first arc.
396

	
397
        /// Sets the iterator to the first arc of the given graph.
379 398
        ///
380
        ArcIt(Invalid) { }
381
        /// This constructor sets the iterator to the first arc.
399
        explicit ArcIt(const Graph &g) { ignore_unused_variable_warning(g); }
400
        /// Sets the iterator to the given arc.
382 401

	
383
        /// This constructor sets the iterator to the first arc of \c g.
384
        ///@param g the graph
385
        ArcIt(const Graph &g) { ignore_unused_variable_warning(g); }
386
        /// Arc -> ArcIt conversion
387

	
388
        /// Sets the iterator to the value of the trivial iterator \c e.
389
        /// This feature necessitates that each time we
390
        /// iterate the arc-set, the iteration order is the same.
402
        /// Sets the iterator to the given arc of the given graph.
403
        ///
391 404
        ArcIt(const Graph&, const Arc&) { }
392
        ///Next arc
405
        /// Next arc
393 406

	
394 407
        /// Assign the iterator to the next arc.
408
        ///
395 409
        ArcIt& operator++() { return *this; }
396 410
      };
397 411

	
398
      /// This iterator goes trough the outgoing directed arcs of a node.
412
      /// Iterator class for the outgoing arcs of a node.
399 413

	
400
      /// This iterator goes trough the \e outgoing arcs of a certain node
401
      /// of a graph.
414
      /// This iterator goes trough the \e outgoing directed arcs of a
415
      /// certain node of a graph.
402 416
      /// Its usage is quite simple, for example you can count the number
403 417
      /// of outgoing arcs of a node \c n
404
      /// in graph \c g of type \c Graph as follows.
418
      /// in a graph \c g of type \c %Graph as follows.
405 419
      ///\code
406 420
      /// int count=0;
407
      /// for (Graph::OutArcIt e(g, n); e!=INVALID; ++e) ++count;
421
      /// for (Digraph::OutArcIt a(g, n); a!=INVALID; ++a) ++count;
408 422
      ///\endcode
409

	
410 423
      class OutArcIt : public Arc {
411 424
      public:
412 425
        /// Default constructor
413 426

	
414
        /// @warning The default constructor sets the iterator
415
        /// to an undefined value.
427
        /// Default constructor.
428
        /// \warning It sets the iterator to an undefined value.
416 429
        OutArcIt() { }
417 430
        /// Copy constructor.
418 431

	
419 432
        /// Copy constructor.
420 433
        ///
421 434
        OutArcIt(const OutArcIt& e) : Arc(e) { }
422
        /// Initialize the iterator to be invalid.
435
        /// %Invalid constructor \& conversion.
423 436

	
424
        /// Initialize the iterator to be invalid.
437
        /// Initializes the iterator to be invalid.
438
        /// \sa Invalid for more details.
439
        OutArcIt(Invalid) { }
440
        /// Sets the iterator to the first outgoing arc.
441

	
442
        /// Sets the iterator to the first outgoing arc of the given node.
425 443
        ///
426
        OutArcIt(Invalid) { }
427
        /// This constructor sets the iterator to the first outgoing arc.
428

	
429
        /// This constructor sets the iterator to the first outgoing arc of
430
        /// the node.
431
        ///@param n the node
432
        ///@param g the graph
433 444
        OutArcIt(const Graph& n, const Node& g) {
434 445
          ignore_unused_variable_warning(n);
435 446
          ignore_unused_variable_warning(g);
436 447
        }
437
        /// Arc -> OutArcIt conversion
448
        /// Sets the iterator to the given arc.
438 449

	
439
        /// Sets the iterator to the value of the trivial iterator.
440
        /// This feature necessitates that each time we
441
        /// iterate the arc-set, the iteration order is the same.
450
        /// Sets the iterator to the given arc of the given graph.
451
        ///
442 452
        OutArcIt(const Graph&, const Arc&) { }
443
        ///Next outgoing arc
453
        /// Next outgoing arc
444 454

	
445 455
        /// Assign the iterator to the next
446 456
        /// outgoing arc of the corresponding node.
447 457
        OutArcIt& operator++() { return *this; }
448 458
      };
449 459

	
450
      /// This iterator goes trough the incoming directed arcs of a node.
460
      /// Iterator class for the incoming arcs of a node.
451 461

	
452
      /// This iterator goes trough the \e incoming arcs of a certain node
453
      /// of a graph.
462
      /// This iterator goes trough the \e incoming directed arcs of a
463
      /// certain node of a graph.
454 464
      /// Its usage is quite simple, for example you can count the number
455
      /// of outgoing arcs of a node \c n
456
      /// in graph \c g of type \c Graph as follows.
465
      /// of incoming arcs of a node \c n
466
      /// in a graph \c g of type \c %Graph as follows.
457 467
      ///\code
458 468
      /// int count=0;
459
      /// for(Graph::InArcIt e(g, n); e!=INVALID; ++e) ++count;
469
      /// for (Digraph::InArcIt a(g, n); a!=INVALID; ++a) ++count;
460 470
      ///\endcode
461

	
462 471
      class InArcIt : public Arc {
463 472
      public:
464 473
        /// Default constructor
465 474

	
466
        /// @warning The default constructor sets the iterator
467
        /// to an undefined value.
475
        /// Default constructor.
476
        /// \warning It sets the iterator to an undefined value.
468 477
        InArcIt() { }
469 478
        /// Copy constructor.
470 479

	
471 480
        /// Copy constructor.
472 481
        ///
473 482
        InArcIt(const InArcIt& e) : Arc(e) { }
474
        /// Initialize the iterator to be invalid.
483
        /// %Invalid constructor \& conversion.
475 484

	
476
        /// Initialize the iterator to be invalid.
485
        /// Initializes the iterator to be invalid.
486
        /// \sa Invalid for more details.
487
        InArcIt(Invalid) { }
488
        /// Sets the iterator to the first incoming arc.
489

	
490
        /// Sets the iterator to the first incoming arc of the given node.
477 491
        ///
478
        InArcIt(Invalid) { }
479
        /// This constructor sets the iterator to first incoming arc.
480

	
481
        /// This constructor set the iterator to the first incoming arc of
482
        /// the node.
483
        ///@param n the node
484
        ///@param g the graph
485 492
        InArcIt(const Graph& g, const Node& n) {
486 493
          ignore_unused_variable_warning(n);
487 494
          ignore_unused_variable_warning(g);
488 495
        }
489
        /// Arc -> InArcIt conversion
496
        /// Sets the iterator to the given arc.
490 497

	
491
        /// Sets the iterator to the value of the trivial iterator \c e.
492
        /// This feature necessitates that each time we
493
        /// iterate the arc-set, the iteration order is the same.
498
        /// Sets the iterator to the given arc of the given graph.
499
        ///
494 500
        InArcIt(const Graph&, const Arc&) { }
495 501
        /// Next incoming arc
496 502

	
497
        /// Assign the iterator to the next inarc of the corresponding node.
498
        ///
503
        /// Assign the iterator to the next
504
        /// incoming arc of the corresponding node.
499 505
        InArcIt& operator++() { return *this; }
500 506
      };
501 507

	
502
      /// \brief Reference map of the nodes to type \c T.
508
      /// \brief Standard graph map type for the nodes.
503 509
      ///
504
      /// Reference map of the nodes to type \c T.
510
      /// Standard graph map type for the nodes.
511
      /// It conforms to the ReferenceMap concept.
505 512
      template<class T>
506 513
      class NodeMap : public ReferenceMap<Node, T, T&, const T&>
507 514
      {
508 515
      public:
509 516

	
510
        ///\e
511
        NodeMap(const Graph&) { }
512
        ///\e
517
        /// Constructor
518
        explicit NodeMap(const Graph&) { }
519
        /// Constructor with given initial value
513 520
        NodeMap(const Graph&, T) { }
514 521

	
515 522
      private:
516 523
        ///Copy constructor
517 524
        NodeMap(const NodeMap& nm) :
518 525
          ReferenceMap<Node, T, T&, const T&>(nm) { }
519 526
        ///Assignment operator
520 527
        template <typename CMap>
521 528
        NodeMap& operator=(const CMap&) {
522 529
          checkConcept<ReadMap<Node, T>, CMap>();
523 530
          return *this;
524 531
        }
525 532
      };
526 533

	
527
      /// \brief Reference map of the arcs to type \c T.
534
      /// \brief Standard graph map type for the arcs.
528 535
      ///
529
      /// Reference map of the arcs to type \c T.
536
      /// Standard graph map type for the arcs.
537
      /// It conforms to the ReferenceMap concept.
530 538
      template<class T>
531 539
      class ArcMap : public ReferenceMap<Arc, T, T&, const T&>
532 540
      {
533 541
      public:
534 542

	
535
        ///\e
536
        ArcMap(const Graph&) { }
537
        ///\e
543
        /// Constructor
544
        explicit ArcMap(const Graph&) { }
545
        /// Constructor with given initial value
538 546
        ArcMap(const Graph&, T) { }
547

	
539 548
      private:
540 549
        ///Copy constructor
541 550
        ArcMap(const ArcMap& em) :
542 551
          ReferenceMap<Arc, T, T&, const T&>(em) { }
543 552
        ///Assignment operator
544 553
        template <typename CMap>
545 554
        ArcMap& operator=(const CMap&) {
546 555
          checkConcept<ReadMap<Arc, T>, CMap>();
547 556
          return *this;
548 557
        }
549 558
      };
550 559

	
551
      /// Reference map of the edges to type \c T.
552

	
553
      /// Reference map of the edges to type \c T.
560
      /// \brief Standard graph map type for the edges.
561
      ///
562
      /// Standard graph map type for the edges.
563
      /// It conforms to the ReferenceMap concept.
554 564
      template<class T>
555 565
      class EdgeMap : public ReferenceMap<Edge, T, T&, const T&>
556 566
      {
557 567
      public:
558 568

	
559
        ///\e
560
        EdgeMap(const Graph&) { }
561
        ///\e
569
        /// Constructor
570
        explicit EdgeMap(const Graph&) { }
571
        /// Constructor with given initial value
562 572
        EdgeMap(const Graph&, T) { }
573

	
563 574
      private:
564 575
        ///Copy constructor
565 576
        EdgeMap(const EdgeMap& em) :
566 577
          ReferenceMap<Edge, T, T&, const T&>(em) {}
567 578
        ///Assignment operator
568 579
        template <typename CMap>
569 580
        EdgeMap& operator=(const CMap&) {
570 581
          checkConcept<ReadMap<Edge, T>, CMap>();
571 582
          return *this;
572 583
        }
573 584
      };
574 585

	
575
      /// \brief Direct the given edge.
586
      /// \brief The first node of the edge.
576 587
      ///
577
      /// Direct the given edge. The returned arc source
578
      /// will be the given node.
579
      Arc direct(const Edge&, const Node&) const {
580
        return INVALID;
581
      }
582

	
583
      /// \brief Direct the given edge.
588
      /// Returns the first node of the given edge.
584 589
      ///
585
      /// Direct the given edge. The returned arc
586
      /// represents the given edge and the direction comes
587
      /// from the bool parameter. The source of the edge and
588
      /// the directed arc is the same when the given bool is true.
589
      Arc direct(const Edge&, bool) const {
590
        return INVALID;
591
      }
592

	
593
      /// \brief Returns true if the arc has default orientation.
594
      ///
595
      /// Returns whether the given directed arc is same orientation as
596
      /// the corresponding edge's default orientation.
597
      bool direction(Arc) const { return true; }
598

	
599
      /// \brief Returns the opposite directed arc.
600
      ///
601
      /// Returns the opposite directed arc.
602
      Arc oppositeArc(Arc) const { return INVALID; }
603

	
604
      /// \brief Opposite node on an arc
605
      ///
606
      /// \return The opposite of the given node on the given edge.
607
      Node oppositeNode(Node, Edge) const { return INVALID; }
608

	
609
      /// \brief First node of the edge.
610
      ///
611
      /// \return The first node of the given edge.
612
      ///
613
      /// Naturally edges don't have direction and thus
614
      /// don't have source and target node. However we use \c u() and \c v()
615
      /// methods to query the two nodes of the arc. The direction of the
616
      /// arc which arises this way is called the inherent direction of the
617
      /// edge, and is used to define the "default" direction
618
      /// of the directed versions of the arcs.
590
      /// Edges don't have source and target nodes, however methods
591
      /// u() and v() are used to query the two end-nodes of an edge.
592
      /// The orientation of an edge that arises this way is called
593
      /// the inherent direction, it is used to define the default
594
      /// direction for the corresponding arcs.
619 595
      /// \sa v()
620 596
      /// \sa direction()
621 597
      Node u(Edge) const { return INVALID; }
622 598

	
623
      /// \brief Second node of the edge.
599
      /// \brief The second node of the edge.
624 600
      ///
625
      /// \return The second node of the given edge.
601
      /// Returns the second node of the given edge.
626 602
      ///
627
      /// Naturally edges don't have direction and thus
628
      /// don't have source and target node. However we use \c u() and \c v()
629
      /// methods to query the two nodes of the arc. The direction of the
630
      /// arc which arises this way is called the inherent direction of the
631
      /// edge, and is used to define the "default" direction
632
      /// of the directed versions of the arcs.
603
      /// Edges don't have source and target nodes, however methods
604
      /// u() and v() are used to query the two end-nodes of an edge.
605
      /// The orientation of an edge that arises this way is called
606
      /// the inherent direction, it is used to define the default
607
      /// direction for the corresponding arcs.
633 608
      /// \sa u()
634 609
      /// \sa direction()
635 610
      Node v(Edge) const { return INVALID; }
636 611

	
637
      /// \brief Source node of the directed arc.
612
      /// \brief The source node of the arc.
613
      ///
614
      /// Returns the source node of the given arc.
638 615
      Node source(Arc) const { return INVALID; }
639 616

	
640
      /// \brief Target node of the directed arc.
617
      /// \brief The target node of the arc.
618
      ///
619
      /// Returns the target node of the given arc.
641 620
      Node target(Arc) const { return INVALID; }
642 621

	
643
      /// \brief Returns the id of the node.
622
      /// \brief The ID of the node.
623
      ///
624
      /// Returns the ID of the given node.
644 625
      int id(Node) const { return -1; }
645 626

	
646
      /// \brief Returns the id of the edge.
627
      /// \brief The ID of the edge.
628
      ///
629
      /// Returns the ID of the given edge.
647 630
      int id(Edge) const { return -1; }
648 631

	
649
      /// \brief Returns the id of the arc.
632
      /// \brief The ID of the arc.
633
      ///
634
      /// Returns the ID of the given arc.
650 635
      int id(Arc) const { return -1; }
651 636

	
652
      /// \brief Returns the node with the given id.
637
      /// \brief The node with the given ID.
653 638
      ///
654
      /// \pre The argument should be a valid node id in the graph.
639
      /// Returns the node with the given ID.
640
      /// \pre The argument should be a valid node ID in the graph.
655 641
      Node nodeFromId(int) const { return INVALID; }
656 642

	
657
      /// \brief Returns the edge with the given id.
643
      /// \brief The edge with the given ID.
658 644
      ///
659
      /// \pre The argument should be a valid edge id in the graph.
645
      /// Returns the edge with the given ID.
646
      /// \pre The argument should be a valid edge ID in the graph.
660 647
      Edge edgeFromId(int) const { return INVALID; }
661 648

	
662
      /// \brief Returns the arc with the given id.
649
      /// \brief The arc with the given ID.
663 650
      ///
664
      /// \pre The argument should be a valid arc id in the graph.
651
      /// Returns the arc with the given ID.
652
      /// \pre The argument should be a valid arc ID in the graph.
665 653
      Arc arcFromId(int) const { return INVALID; }
666 654

	
667
      /// \brief Returns an upper bound on the node IDs.
655
      /// \brief An upper bound on the node IDs.
656
      ///
657
      /// Returns an upper bound on the node IDs.
668 658
      int maxNodeId() const { return -1; }
669 659

	
670
      /// \brief Returns an upper bound on the edge IDs.
660
      /// \brief An upper bound on the edge IDs.
661
      ///
662
      /// Returns an upper bound on the edge IDs.
671 663
      int maxEdgeId() const { return -1; }
672 664

	
673
      /// \brief Returns an upper bound on the arc IDs.
665
      /// \brief An upper bound on the arc IDs.
666
      ///
667
      /// Returns an upper bound on the arc IDs.
674 668
      int maxArcId() const { return -1; }
675 669

	
670
      /// \brief The direction of the arc.
671
      ///
672
      /// Returns \c true if the direction of the given arc is the same as
673
      /// the inherent orientation of the represented edge.
674
      bool direction(Arc) const { return true; }
675

	
676
      /// \brief Direct the edge.
677
      ///
678
      /// Direct the given edge. The returned arc
679
      /// represents the given edge and its direction comes
680
      /// from the bool parameter. If it is \c true, then the direction
681
      /// of the arc is the same as the inherent orientation of the edge.
682
      Arc direct(Edge, bool) const {
683
        return INVALID;
684
      }
685

	
686
      /// \brief Direct the edge.
687
      ///
688
      /// Direct the given edge. The returned arc represents the given
689
      /// edge and its source node is the given node.
690
      Arc direct(Edge, Node) const {
691
        return INVALID;
692
      }
693

	
694
      /// \brief The oppositely directed arc.
695
      ///
696
      /// Returns the oppositely directed arc representing the same edge.
697
      Arc oppositeArc(Arc) const { return INVALID; }
698

	
699
      /// \brief The opposite node on the edge.
700
      ///
701
      /// Returns the opposite node on the given edge.
702
      Node oppositeNode(Node, Edge) const { return INVALID; }
703

	
676 704
      void first(Node&) const {}
677 705
      void next(Node&) const {}
678 706

	
679 707
      void first(Edge&) const {}
680 708
      void next(Edge&) const {}
681 709

	
682 710
      void first(Arc&) const {}
683 711
      void next(Arc&) const {}
684 712

	
685 713
      void firstOut(Arc&, Node) const {}
686 714
      void nextOut(Arc&) const {}
687 715

	
688 716
      void firstIn(Arc&, Node) const {}
689 717
      void nextIn(Arc&) const {}
690 718

	
691 719
      void firstInc(Edge &, bool &, const Node &) const {}
692 720
      void nextInc(Edge &, bool &) const {}
693 721

	
694 722
      // The second parameter is dummy.
695 723
      Node fromId(int, Node) const { return INVALID; }
696 724
      // The second parameter is dummy.
697 725
      Edge fromId(int, Edge) const { return INVALID; }
698 726
      // The second parameter is dummy.
699 727
      Arc fromId(int, Arc) const { return INVALID; }
700 728

	
701 729
      // Dummy parameter.
702 730
      int maxId(Node) const { return -1; }
703 731
      // Dummy parameter.
704 732
      int maxId(Edge) const { return -1; }
705 733
      // Dummy parameter.
706 734
      int maxId(Arc) const { return -1; }
707 735

	
708
      /// \brief Base node of the iterator
736
      /// \brief The base node of the iterator.
709 737
      ///
710
      /// Returns the base node (the source in this case) of the iterator
711
      Node baseNode(OutArcIt e) const {
712
        return source(e);
713
      }
714
      /// \brief Running node of the iterator
738
      /// Returns the base node of the given incident edge iterator.
739
      Node baseNode(IncEdgeIt) const { return INVALID; }
740

	
741
      /// \brief The running node of the iterator.
715 742
      ///
716
      /// Returns the running node (the target in this case) of the
717
      /// iterator
718
      Node runningNode(OutArcIt e) const {
719
        return target(e);
720
      }
743
      /// Returns the running node of the given incident edge iterator.
744
      Node runningNode(IncEdgeIt) const { return INVALID; }
721 745

	
722
      /// \brief Base node of the iterator
746
      /// \brief The base node of the iterator.
723 747
      ///
724
      /// Returns the base node (the target in this case) of the iterator
725
      Node baseNode(InArcIt e) const {
726
        return target(e);
727
      }
728
      /// \brief Running node of the iterator
748
      /// Returns the base node of the given outgoing arc iterator
749
      /// (i.e. the source node of the corresponding arc).
750
      Node baseNode(OutArcIt) const { return INVALID; }
751

	
752
      /// \brief The running node of the iterator.
729 753
      ///
730
      /// Returns the running node (the source in this case) of the
731
      /// iterator
732
      Node runningNode(InArcIt e) const {
733
        return source(e);
734
      }
754
      /// Returns the running node of the given outgoing arc iterator
755
      /// (i.e. the target node of the corresponding arc).
756
      Node runningNode(OutArcIt) const { return INVALID; }
735 757

	
736
      /// \brief Base node of the iterator
758
      /// \brief The base node of the iterator.
737 759
      ///
738
      /// Returns the base node of the iterator
739
      Node baseNode(IncEdgeIt) const {
740
        return INVALID;
741
      }
760
      /// Returns the base node of the given incomming arc iterator
761
      /// (i.e. the target node of the corresponding arc).
762
      Node baseNode(InArcIt) const { return INVALID; }
742 763

	
743
      /// \brief Running node of the iterator
764
      /// \brief The running node of the iterator.
744 765
      ///
745
      /// Returns the running node of the iterator
746
      Node runningNode(IncEdgeIt) const {
747
        return INVALID;
748
      }
766
      /// Returns the running node of the given incomming arc iterator
767
      /// (i.e. the source node of the corresponding arc).
768
      Node runningNode(InArcIt) const { return INVALID; }
749 769

	
750 770
      template <typename _Graph>
751 771
      struct Constraints {
752 772
        void constraints() {
753 773
          checkConcept<BaseGraphComponent, _Graph>();
754 774
          checkConcept<IterableGraphComponent<>, _Graph>();
755 775
          checkConcept<IDableGraphComponent<>, _Graph>();
756 776
          checkConcept<MappableGraphComponent<>, _Graph>();
757 777
        }
758 778
      };
759 779

	
760 780
    };
761 781

	
762 782
  }
763 783

	
764 784
}
765 785

	
766 786
#endif
Ignore white space 6 line context
... ...
@@ -31,129 +31,129 @@
31 31
namespace lemon {
32 32
  namespace concepts {
33 33

	
34 34
    /// \brief Concept class for \c Node, \c Arc and \c Edge types.
35 35
    ///
36 36
    /// This class describes the concept of \c Node, \c Arc and \c Edge
37 37
    /// subtypes of digraph and graph types.
38 38
    ///
39 39
    /// \note This class is a template class so that we can use it to
40 40
    /// create graph skeleton classes. The reason for this is that \c Node
41 41
    /// and \c Arc (or \c Edge) types should \e not derive from the same 
42 42
    /// base class. For \c Node you should instantiate it with character
43 43
    /// \c 'n', for \c Arc with \c 'a' and for \c Edge with \c 'e'.
44 44
#ifndef DOXYGEN
45 45
    template <char sel = '0'>
46 46
#endif
47 47
    class GraphItem {
48 48
    public:
49 49
      /// \brief Default constructor.
50 50
      ///
51 51
      /// Default constructor.
52 52
      /// \warning The default constructor is not required to set
53 53
      /// the item to some well-defined value. So you should consider it
54 54
      /// as uninitialized.
55 55
      GraphItem() {}
56 56

	
57 57
      /// \brief Copy constructor.
58 58
      ///
59 59
      /// Copy constructor.
60 60
      GraphItem(const GraphItem &) {}
61 61

	
62 62
      /// \brief Constructor for conversion from \c INVALID.
63 63
      ///
64 64
      /// Constructor for conversion from \c INVALID.
65 65
      /// It initializes the item to be invalid.
66 66
      /// \sa Invalid for more details.
67 67
      GraphItem(Invalid) {}
68 68

	
69 69
      /// \brief Assignment operator.
70 70
      ///
71 71
      /// Assignment operator for the item.
72 72
      GraphItem& operator=(const GraphItem&) { return *this; }
73 73

	
74 74
      /// \brief Assignment operator for INVALID.
75 75
      ///
76 76
      /// This operator makes the item invalid.
77 77
      GraphItem& operator=(Invalid) { return *this; }
78 78

	
79 79
      /// \brief Equality operator.
80 80
      ///
81 81
      /// Equality operator.
82 82
      bool operator==(const GraphItem&) const { return false; }
83 83

	
84 84
      /// \brief Inequality operator.
85 85
      ///
86 86
      /// Inequality operator.
87 87
      bool operator!=(const GraphItem&) const { return false; }
88 88

	
89 89
      /// \brief Ordering operator.
90 90
      ///
91 91
      /// This operator defines an ordering of the items.
92 92
      /// It makes possible to use graph item types as key types in 
93 93
      /// associative containers (e.g. \c std::map).
94 94
      ///
95
      /// \note This operator only have to define some strict ordering of
95
      /// \note This operator only has to define some strict ordering of
96 96
      /// the items; this order has nothing to do with the iteration
97 97
      /// ordering of the items.
98 98
      bool operator<(const GraphItem&) const { return false; }
99 99

	
100 100
      template<typename _GraphItem>
101 101
      struct Constraints {
102 102
        void constraints() {
103 103
          _GraphItem i1;
104 104
          i1=INVALID;
105 105
          _GraphItem i2 = i1;
106 106
          _GraphItem i3 = INVALID;
107 107

	
108 108
          i1 = i2 = i3;
109 109

	
110 110
          bool b;
111 111
          b = (ia == ib) && (ia != ib);
112 112
          b = (ia == INVALID) && (ib != INVALID);
113 113
          b = (ia < ib);
114 114
        }
115 115

	
116 116
        const _GraphItem &ia;
117 117
        const _GraphItem &ib;
118 118
      };
119 119
    };
120 120

	
121 121
    /// \brief Base skeleton class for directed graphs.
122 122
    ///
123 123
    /// This class describes the base interface of directed graph types.
124 124
    /// All digraph %concepts have to conform to this class.
125 125
    /// It just provides types for nodes and arcs and functions 
126 126
    /// to get the source and the target nodes of arcs.
127 127
    class BaseDigraphComponent {
128 128
    public:
129 129

	
130 130
      typedef BaseDigraphComponent Digraph;
131 131

	
132 132
      /// \brief Node class of the digraph.
133 133
      ///
134 134
      /// This class represents the nodes of the digraph.
135 135
      typedef GraphItem<'n'> Node;
136 136

	
137 137
      /// \brief Arc class of the digraph.
138 138
      ///
139 139
      /// This class represents the arcs of the digraph.
140 140
      typedef GraphItem<'a'> Arc;
141 141

	
142 142
      /// \brief Return the source node of an arc.
143 143
      ///
144 144
      /// This function returns the source node of an arc.
145 145
      Node source(const Arc&) const { return INVALID; }
146 146

	
147 147
      /// \brief Return the target node of an arc.
148 148
      ///
149 149
      /// This function returns the target node of an arc.
150 150
      Node target(const Arc&) const { return INVALID; }
151 151

	
152 152
      /// \brief Return the opposite node on the given arc.
153 153
      ///
154 154
      /// This function returns the opposite node on the given arc.
155 155
      Node oppositeNode(const Node&, const Arc&) const {
156 156
        return INVALID;
157 157
      }
158 158

	
159 159
      template <typename _Digraph>
Ignore white space 6 line context
... ...
@@ -50,128 +50,161 @@
50 50

	
51 51
  CplexEnv::CplexEnv(const CplexEnv& other) {
52 52
    _env = other._env;
53 53
    _cnt = other._cnt;
54 54
    ++(*_cnt);
55 55
  }
56 56

	
57 57
  CplexEnv& CplexEnv::operator=(const CplexEnv& other) {
58 58
    _env = other._env;
59 59
    _cnt = other._cnt;
60 60
    ++(*_cnt);
61 61
    return *this;
62 62
  }
63 63

	
64 64
  CplexEnv::~CplexEnv() {
65 65
    --(*_cnt);
66 66
    if (*_cnt == 0) {
67 67
      delete _cnt;
68 68
      CPXcloseCPLEX(&_env);
69 69
    }
70 70
  }
71 71

	
72 72
  CplexBase::CplexBase() : LpBase() {
73 73
    int status;
74 74
    _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
75 75
    messageLevel(MESSAGE_NOTHING);
76 76
  }
77 77

	
78 78
  CplexBase::CplexBase(const CplexEnv& env)
79 79
    : LpBase(), _env(env) {
80 80
    int status;
81 81
    _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
82 82
    messageLevel(MESSAGE_NOTHING);
83 83
  }
84 84

	
85 85
  CplexBase::CplexBase(const CplexBase& cplex)
86 86
    : LpBase() {
87 87
    int status;
88 88
    _prob = CPXcloneprob(cplexEnv(), cplex._prob, &status);
89 89
    rows = cplex.rows;
90 90
    cols = cplex.cols;
91 91
    messageLevel(MESSAGE_NOTHING);
92 92
  }
93 93

	
94 94
  CplexBase::~CplexBase() {
95 95
    CPXfreeprob(cplexEnv(),&_prob);
96 96
  }
97 97

	
98 98
  int CplexBase::_addCol() {
99 99
    int i = CPXgetnumcols(cplexEnv(), _prob);
100 100
    double lb = -INF, ub = INF;
101 101
    CPXnewcols(cplexEnv(), _prob, 1, 0, &lb, &ub, 0, 0);
102 102
    return i;
103 103
  }
104 104

	
105 105

	
106 106
  int CplexBase::_addRow() {
107 107
    int i = CPXgetnumrows(cplexEnv(), _prob);
108 108
    const double ub = INF;
109 109
    const char s = 'L';
110 110
    CPXnewrows(cplexEnv(), _prob, 1, &ub, &s, 0, 0);
111 111
    return i;
112 112
  }
113 113

	
114
  int CplexBase::_addRow(Value lb, ExprIterator b, 
115
                         ExprIterator e, Value ub) {
116
    int i = CPXgetnumrows(cplexEnv(), _prob);
117
    if (lb == -INF) {
118
      const char s = 'L';
119
      CPXnewrows(cplexEnv(), _prob, 1, &ub, &s, 0, 0);
120
    } else if (ub == INF) {
121
      const char s = 'G';
122
      CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, 0, 0);
123
    } else if (lb == ub){
124
      const char s = 'E';
125
      CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, 0, 0);
126
    } else {
127
      const char s = 'R';
128
      double len = ub - lb;
129
      CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, &len, 0);
130
    }
131

	
132
    std::vector<int> indices;
133
    std::vector<int> rowlist;
134
    std::vector<Value> values;
135

	
136
    for(ExprIterator it=b; it!=e; ++it) {
137
      indices.push_back(it->first);
138
      values.push_back(it->second);
139
      rowlist.push_back(i);
140
    }
141

	
142
    CPXchgcoeflist(cplexEnv(), _prob, values.size(),
143
                   &rowlist.front(), &indices.front(), &values.front());
144

	
145
    return i;
146
  }
114 147

	
115 148
  void CplexBase::_eraseCol(int i) {
116 149
    CPXdelcols(cplexEnv(), _prob, i, i);
117 150
  }
118 151

	
119 152
  void CplexBase::_eraseRow(int i) {
120 153
    CPXdelrows(cplexEnv(), _prob, i, i);
121 154
  }
122 155

	
123 156
  void CplexBase::_eraseColId(int i) {
124 157
    cols.eraseIndex(i);
125 158
    cols.shiftIndices(i);
126 159
  }
127 160
  void CplexBase::_eraseRowId(int i) {
128 161
    rows.eraseIndex(i);
129 162
    rows.shiftIndices(i);
130 163
  }
131 164

	
132 165
  void CplexBase::_getColName(int col, std::string &name) const {
133 166
    int size;
134 167
    CPXgetcolname(cplexEnv(), _prob, 0, 0, 0, &size, col, col);
135 168
    if (size == 0) {
136 169
      name.clear();
137 170
      return;
138 171
    }
139 172

	
140 173
    size *= -1;
141 174
    std::vector<char> buf(size);
142 175
    char *cname;
143 176
    int tmp;
144 177
    CPXgetcolname(cplexEnv(), _prob, &cname, &buf.front(), size,
145 178
                  &tmp, col, col);
146 179
    name = cname;
147 180
  }
148 181

	
149 182
  void CplexBase::_setColName(int col, const std::string &name) {
150 183
    char *cname;
151 184
    cname = const_cast<char*>(name.c_str());
152 185
    CPXchgcolname(cplexEnv(), _prob, 1, &col, &cname);
153 186
  }
154 187

	
155 188
  int CplexBase::_colByName(const std::string& name) const {
156 189
    int index;
157 190
    if (CPXgetcolindex(cplexEnv(), _prob,
158 191
                       const_cast<char*>(name.c_str()), &index) == 0) {
159 192
      return index;
160 193
    }
161 194
    return -1;
162 195
  }
163 196

	
164 197
  void CplexBase::_getRowName(int row, std::string &name) const {
165 198
    int size;
166 199
    CPXgetrowname(cplexEnv(), _prob, 0, 0, 0, &size, row, row);
167 200
    if (size == 0) {
168 201
      name.clear();
169 202
      return;
170 203
    }
171 204

	
172 205
    size *= -1;
173 206
    std::vector<char> buf(size);
174 207
    char *cname;
175 208
    int tmp;
176 209
    CPXgetrowname(cplexEnv(), _prob, &cname, &buf.front(), size,
177 210
                  &tmp, row, row);
Ignore white space 6 line context
... ...
@@ -32,128 +32,129 @@
32 32
  /// \brief Reference counted wrapper around cpxenv pointer
33 33
  ///
34 34
  /// The cplex uses environment object which is responsible for
35 35
  /// checking the proper license usage. This class provides a simple
36 36
  /// interface for share the environment object between different
37 37
  /// problems.
38 38
  class CplexEnv {
39 39
    friend class CplexBase;
40 40
  private:
41 41
    cpxenv* _env;
42 42
    mutable int* _cnt;
43 43

	
44 44
  public:
45 45

	
46 46
    /// \brief This exception is thrown when the license check is not
47 47
    /// sufficient
48 48
    class LicenseError : public Exception {
49 49
      friend class CplexEnv;
50 50
    private:
51 51

	
52 52
      LicenseError(int status);
53 53
      char _message[510];
54 54

	
55 55
    public:
56 56

	
57 57
      /// The short error message
58 58
      virtual const char* what() const throw() {
59 59
        return _message;
60 60
      }
61 61
    };
62 62

	
63 63
    /// Constructor
64 64
    CplexEnv();
65 65
    /// Shallow copy constructor
66 66
    CplexEnv(const CplexEnv&);
67 67
    /// Shallow assignement
68 68
    CplexEnv& operator=(const CplexEnv&);
69 69
    /// Destructor
70 70
    virtual ~CplexEnv();
71 71

	
72 72
  protected:
73 73

	
74 74
    cpxenv* cplexEnv() { return _env; }
75 75
    const cpxenv* cplexEnv() const { return _env; }
76 76
  };
77 77

	
78 78
  /// \brief Base interface for the CPLEX LP and MIP solver
79 79
  ///
80 80
  /// This class implements the common interface of the CPLEX LP and
81 81
  /// MIP solvers.
82 82
  /// \ingroup lp_group
83 83
  class CplexBase : virtual public LpBase {
84 84
  protected:
85 85

	
86 86
    CplexEnv _env;
87 87
    cpxlp* _prob;
88 88

	
89 89
    CplexBase();
90 90
    CplexBase(const CplexEnv&);
91 91
    CplexBase(const CplexBase &);
92 92
    virtual ~CplexBase();
93 93

	
94 94
    virtual int _addCol();
95 95
    virtual int _addRow();
96
    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
96 97

	
97 98
    virtual void _eraseCol(int i);
98 99
    virtual void _eraseRow(int i);
99 100

	
100 101
    virtual void _eraseColId(int i);
101 102
    virtual void _eraseRowId(int i);
102 103

	
103 104
    virtual void _getColName(int col, std::string& name) const;
104 105
    virtual void _setColName(int col, const std::string& name);
105 106
    virtual int _colByName(const std::string& name) const;
106 107

	
107 108
    virtual void _getRowName(int row, std::string& name) const;
108 109
    virtual void _setRowName(int row, const std::string& name);
109 110
    virtual int _rowByName(const std::string& name) const;
110 111

	
111 112
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
112 113
    virtual void _getRowCoeffs(int i, InsertIterator b) const;
113 114

	
114 115
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
115 116
    virtual void _getColCoeffs(int i, InsertIterator b) const;
116 117

	
117 118
    virtual void _setCoeff(int row, int col, Value value);
118 119
    virtual Value _getCoeff(int row, int col) const;
119 120

	
120 121
    virtual void _setColLowerBound(int i, Value value);
121 122
    virtual Value _getColLowerBound(int i) const;
122 123

	
123 124
    virtual void _setColUpperBound(int i, Value value);
124 125
    virtual Value _getColUpperBound(int i) const;
125 126

	
126 127
  private:
127 128
    void _set_row_bounds(int i, Value lb, Value ub);
128 129
  protected:
129 130

	
130 131
    virtual void _setRowLowerBound(int i, Value value);
131 132
    virtual Value _getRowLowerBound(int i) const;
132 133

	
133 134
    virtual void _setRowUpperBound(int i, Value value);
134 135
    virtual Value _getRowUpperBound(int i) const;
135 136

	
136 137
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
137 138
    virtual void _getObjCoeffs(InsertIterator b) const;
138 139

	
139 140
    virtual void _setObjCoeff(int i, Value obj_coef);
140 141
    virtual Value _getObjCoeff(int i) const;
141 142

	
142 143
    virtual void _setSense(Sense sense);
143 144
    virtual Sense _getSense() const;
144 145

	
145 146
    virtual void _clear();
146 147

	
147 148
    virtual void _messageLevel(MessageLevel level);
148 149
    void _applyMessageLevel();
149 150

	
150 151
    bool _message_enabled;
151 152

	
152 153
  public:
153 154

	
154 155
    /// Returns the used \c CplexEnv instance
155 156
    const CplexEnv& env() const { return _env; }
156 157

	
157 158
    /// \brief Returns the const cpxenv pointer
158 159
    ///
159 160
    /// \note The cpxenv might be destructed with the solver.
Ignore white space 6 line context
... ...
@@ -806,129 +806,129 @@
806 806

	
807 807
    const GR* _graph;
808 808

	
809 809
    void initalize(const GR& graph, NodesImplBase& nodes) {
810 810
      _graph = &graph;
811 811
      _nodes = &nodes;
812 812
    }
813 813

	
814 814
  public:
815 815

	
816 816
    class Arc {
817 817
      friend class SmartArcSetBase<GR>;
818 818
    protected:
819 819
      Arc(int _id) : id(_id) {}
820 820
      int id;
821 821
    public:
822 822
      Arc() {}
823 823
      Arc(Invalid) : id(-1) {}
824 824
      bool operator==(const Arc& arc) const { return id == arc.id; }
825 825
      bool operator!=(const Arc& arc) const { return id != arc.id; }
826 826
      bool operator<(const Arc& arc) const { return id < arc.id; }
827 827
    };
828 828

	
829 829
    SmartArcSetBase() {}
830 830

	
831 831
    Node addNode() {
832 832
      LEMON_ASSERT(false,
833 833
        "This graph structure does not support node insertion");
834 834
      return INVALID; // avoid warning
835 835
    }
836 836

	
837 837
    Arc addArc(const Node& u, const Node& v) {
838 838
      int n = arcs.size();
839 839
      arcs.push_back(ArcT());
840 840
      arcs[n].next_in = (*_nodes)[v].first_in;
841 841
      (*_nodes)[v].first_in = n;
842 842
      arcs[n].next_out = (*_nodes)[u].first_out;
843 843
      (*_nodes)[u].first_out = n;
844 844
      arcs[n].source = u;
845 845
      arcs[n].target = v;
846 846
      return Arc(n);
847 847
    }
848 848

	
849 849
    void clear() {
850 850
      Node node;
851 851
      for (first(node); node != INVALID; next(node)) {
852 852
        (*_nodes)[node].first_in = -1;
853 853
        (*_nodes)[node].first_out = -1;
854 854
      }
855 855
      arcs.clear();
856 856
    }
857 857

	
858 858
    void first(Node& node) const {
859 859
      _graph->first(node);
860 860
    }
861 861

	
862 862
    void next(Node& node) const {
863 863
      _graph->next(node);
864 864
    }
865 865

	
866 866
    void first(Arc& arc) const {
867 867
      arc.id = arcs.size() - 1;
868 868
    }
869 869

	
870
    void next(Arc& arc) const {
870
    static void next(Arc& arc) {
871 871
      --arc.id;
872 872
    }
873 873

	
874 874
    void firstOut(Arc& arc, const Node& node) const {
875 875
      arc.id = (*_nodes)[node].first_out;
876 876
    }
877 877

	
878 878
    void nextOut(Arc& arc) const {
879 879
      arc.id = arcs[arc.id].next_out;
880 880
    }
881 881

	
882 882
    void firstIn(Arc& arc, const Node& node) const {
883 883
      arc.id = (*_nodes)[node].first_in;
884 884
    }
885 885

	
886 886
    void nextIn(Arc& arc) const {
887 887
      arc.id = arcs[arc.id].next_in;
888 888
    }
889 889

	
890 890
    int id(const Node& node) const { return _graph->id(node); }
891 891
    int id(const Arc& arc) const { return arc.id; }
892 892

	
893 893
    Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); }
894 894
    Arc arcFromId(int ix) const { return Arc(ix); }
895 895

	
896 896
    int maxNodeId() const { return _graph->maxNodeId(); };
897 897
    int maxArcId() const { return arcs.size() - 1; }
898 898

	
899 899
    Node source(const Arc& arc) const { return arcs[arc.id].source;}
900 900
    Node target(const Arc& arc) const { return arcs[arc.id].target;}
901 901

	
902 902
    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
903 903

	
904 904
    NodeNotifier& notifier(Node) const {
905 905
      return _graph->notifier(Node());
906 906
    }
907 907

	
908 908
    template <typename V>
909 909
    class NodeMap : public GR::template NodeMap<V> {
910 910
      typedef typename GR::template NodeMap<V> Parent;
911 911

	
912 912
    public:
913 913

	
914 914
      explicit NodeMap(const SmartArcSetBase<GR>& arcset)
915 915
        : Parent(*arcset._graph) { }
916 916

	
917 917
      NodeMap(const SmartArcSetBase<GR>& arcset, const V& value)
918 918
        : Parent(*arcset._graph, value) { }
919 919

	
920 920
      NodeMap& operator=(const NodeMap& cmap) {
921 921
        return operator=<NodeMap>(cmap);
922 922
      }
923 923

	
924 924
      template <typename CMap>
925 925
      NodeMap& operator=(const CMap& cmap) {
926 926
        Parent::operator=(cmap);
927 927
        return *this;
928 928
      }
929 929
    };
930 930

	
931 931
  };
932 932

	
933 933

	
934 934
  /// \ingroup graphs
... ...
@@ -1112,137 +1112,137 @@
1112 1112
      bool operator!=(const Edge& arc) const {return id != arc.id;}
1113 1113
      bool operator<(const Edge& arc) const {return id < arc.id;}
1114 1114
    };
1115 1115

	
1116 1116
    class Arc {
1117 1117
      friend class SmartEdgeSetBase;
1118 1118
    protected:
1119 1119
      Arc(int _id) : id(_id) {}
1120 1120
      int id;
1121 1121
    public:
1122 1122
      operator Edge() const { return edgeFromId(id / 2); }
1123 1123

	
1124 1124
      Arc() {}
1125 1125
      Arc(Invalid) : id(-1) {}
1126 1126
      bool operator==(const Arc& arc) const { return id == arc.id; }
1127 1127
      bool operator!=(const Arc& arc) const { return id != arc.id; }
1128 1128
      bool operator<(const Arc& arc) const { return id < arc.id; }
1129 1129
    };
1130 1130

	
1131 1131
    SmartEdgeSetBase() {}
1132 1132

	
1133 1133
    Node addNode() {
1134 1134
      LEMON_ASSERT(false,
1135 1135
        "This graph structure does not support node insertion");
1136 1136
      return INVALID; // avoid warning
1137 1137
    }
1138 1138

	
1139 1139
    Edge addEdge(const Node& u, const Node& v) {
1140 1140
      int n = arcs.size();
1141 1141
      arcs.push_back(ArcT());
1142 1142
      arcs.push_back(ArcT());
1143 1143

	
1144 1144
      arcs[n].target = u;
1145 1145
      arcs[n | 1].target = v;
1146 1146

	
1147 1147
      arcs[n].next_out = (*_nodes)[v].first_out;
1148 1148
      (*_nodes)[v].first_out = n;
1149 1149

	
1150 1150
      arcs[n | 1].next_out = (*_nodes)[u].first_out;
1151 1151
      (*_nodes)[u].first_out = (n | 1);
1152 1152

	
1153 1153
      return Edge(n / 2);
1154 1154
    }
1155 1155

	
1156 1156
    void clear() {
1157 1157
      Node node;
1158 1158
      for (first(node); node != INVALID; next(node)) {
1159 1159
        (*_nodes)[node].first_out = -1;
1160 1160
      }
1161 1161
      arcs.clear();
1162 1162
    }
1163 1163

	
1164 1164
    void first(Node& node) const {
1165 1165
      _graph->first(node);
1166 1166
    }
1167 1167

	
1168 1168
    void next(Node& node) const {
1169 1169
      _graph->next(node);
1170 1170
    }
1171 1171

	
1172 1172
    void first(Arc& arc) const {
1173 1173
      arc.id = arcs.size() - 1;
1174 1174
    }
1175 1175

	
1176
    void next(Arc& arc) const {
1176
    static void next(Arc& arc) {
1177 1177
      --arc.id;
1178 1178
    }
1179 1179

	
1180 1180
    void first(Edge& arc) const {
1181 1181
      arc.id = arcs.size() / 2 - 1;
1182 1182
    }
1183 1183

	
1184
    void next(Edge& arc) const {
1184
    static void next(Edge& arc) {
1185 1185
      --arc.id;
1186 1186
    }
1187 1187

	
1188 1188
    void firstOut(Arc& arc, const Node& node) const {
1189 1189
      arc.id = (*_nodes)[node].first_out;
1190 1190
    }
1191 1191

	
1192 1192
    void nextOut(Arc& arc) const {
1193 1193
      arc.id = arcs[arc.id].next_out;
1194 1194
    }
1195 1195

	
1196 1196
    void firstIn(Arc& arc, const Node& node) const {
1197 1197
      arc.id = (((*_nodes)[node].first_out) ^ 1);
1198 1198
      if (arc.id == -2) arc.id = -1;
1199 1199
    }
1200 1200

	
1201 1201
    void nextIn(Arc& arc) const {
1202 1202
      arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1);
1203 1203
      if (arc.id == -2) arc.id = -1;
1204 1204
    }
1205 1205

	
1206 1206
    void firstInc(Edge &arc, bool& dir, const Node& node) const {
1207 1207
      int de = (*_nodes)[node].first_out;
1208 1208
      if (de != -1 ) {
1209 1209
        arc.id = de / 2;
1210 1210
        dir = ((de & 1) == 1);
1211 1211
      } else {
1212 1212
        arc.id = -1;
1213 1213
        dir = true;
1214 1214
      }
1215 1215
    }
1216 1216
    void nextInc(Edge &arc, bool& dir) const {
1217 1217
      int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out);
1218 1218
      if (de != -1 ) {
1219 1219
        arc.id = de / 2;
1220 1220
        dir = ((de & 1) == 1);
1221 1221
      } else {
1222 1222
        arc.id = -1;
1223 1223
        dir = true;
1224 1224
      }
1225 1225
    }
1226 1226

	
1227 1227
    static bool direction(Arc arc) {
1228 1228
      return (arc.id & 1) == 1;
1229 1229
    }
1230 1230

	
1231 1231
    static Arc direct(Edge edge, bool dir) {
1232 1232
      return Arc(edge.id * 2 + (dir ? 1 : 0));
1233 1233
    }
1234 1234

	
1235 1235
    int id(Node node) const { return _graph->id(node); }
1236 1236
    static int id(Arc arc) { return arc.id; }
1237 1237
    static int id(Edge arc) { return arc.id; }
1238 1238

	
1239 1239
    Node nodeFromId(int id) const { return _graph->nodeFromId(id); }
1240 1240
    static Arc arcFromId(int id) { return Arc(id); }
1241 1241
    static Edge edgeFromId(int id) { return Edge(id);}
1242 1242

	
1243 1243
    int maxNodeId() const { return _graph->maxNodeId(); };
1244 1244
    int maxArcId() const { return arcs.size() - 1; }
1245 1245
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
1246 1246

	
1247 1247
    Node source(Arc e) const { return arcs[e.id ^ 1].target; }
1248 1248
    Node target(Arc e) const { return arcs[e.id].target; }
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_FULL_GRAPH_H
20 20
#define LEMON_FULL_GRAPH_H
21 21

	
22 22
#include <lemon/core.h>
23 23
#include <lemon/bits/graph_extender.h>
24 24

	
25 25
///\ingroup graphs
26 26
///\file
27
///\brief FullGraph and FullDigraph classes.
27
///\brief FullDigraph and FullGraph classes.
28 28

	
29 29
namespace lemon {
30 30

	
31 31
  class FullDigraphBase {
32 32
  public:
33 33

	
34 34
    typedef FullDigraphBase Digraph;
35 35

	
36 36
    class Node;
37 37
    class Arc;
38 38

	
39 39
  protected:
40 40

	
41 41
    int _node_num;
42 42
    int _arc_num;
43 43

	
44 44
    FullDigraphBase() {}
45 45

	
46 46
    void construct(int n) { _node_num = n; _arc_num = n * n; }
47 47

	
48 48
  public:
49 49

	
50 50
    typedef True NodeNumTag;
51 51
    typedef True ArcNumTag;
52 52

	
53 53
    Node operator()(int ix) const { return Node(ix); }
54
    int index(const Node& node) const { return node._id; }
54
    static int index(const Node& node) { return node._id; }
55 55

	
56 56
    Arc arc(const Node& s, const Node& t) const {
57 57
      return Arc(s._id * _node_num + t._id);
58 58
    }
59 59

	
60 60
    int nodeNum() const { return _node_num; }
61 61
    int arcNum() const { return _arc_num; }
62 62

	
63 63
    int maxNodeId() const { return _node_num - 1; }
64 64
    int maxArcId() const { return _arc_num - 1; }
65 65

	
66 66
    Node source(Arc arc) const { return arc._id / _node_num; }
67 67
    Node target(Arc arc) const { return arc._id % _node_num; }
68 68

	
69 69
    static int id(Node node) { return node._id; }
70 70
    static int id(Arc arc) { return arc._id; }
71 71

	
72 72
    static Node nodeFromId(int id) { return Node(id);}
73 73
    static Arc arcFromId(int id) { return Arc(id);}
74 74

	
75 75
    typedef True FindArcTag;
76 76

	
77 77
    Arc findArc(Node s, Node t, Arc prev = INVALID) const {
78 78
      return prev == INVALID ? arc(s, t) : INVALID;
79 79
    }
80 80

	
81 81
    class Node {
82 82
      friend class FullDigraphBase;
83 83

	
84 84
    protected:
85 85
      int _id;
86 86
      Node(int id) : _id(id) {}
87 87
    public:
88 88
      Node() {}
89 89
      Node (Invalid) : _id(-1) {}
90 90
      bool operator==(const Node node) const {return _id == node._id;}
91 91
      bool operator!=(const Node node) const {return _id != node._id;}
92 92
      bool operator<(const Node node) const {return _id < node._id;}
93 93
    };
94 94

	
95 95
    class Arc {
96 96
      friend class FullDigraphBase;
97 97

	
98 98
    protected:
99 99
      int _id;  // _node_num * source + target;
100 100

	
101 101
      Arc(int id) : _id(id) {}
102 102

	
103 103
    public:
104 104
      Arc() { }
105 105
      Arc (Invalid) { _id = -1; }
106 106
      bool operator==(const Arc arc) const {return _id == arc._id;}
107 107
      bool operator!=(const Arc arc) const {return _id != arc._id;}
108 108
      bool operator<(const Arc arc) const {return _id < arc._id;}
109 109
    };
110 110

	
111 111
    void first(Node& node) const {
112 112
      node._id = _node_num - 1;
113 113
    }
114 114

	
115 115
    static void next(Node& node) {
116 116
      --node._id;
117 117
    }
118 118

	
119 119
    void first(Arc& arc) const {
120 120
      arc._id = _arc_num - 1;
121 121
    }
122 122

	
123 123
    static void next(Arc& arc) {
124 124
      --arc._id;
125 125
    }
126 126

	
127 127
    void firstOut(Arc& arc, const Node& node) const {
128 128
      arc._id = (node._id + 1) * _node_num - 1;
129 129
    }
130 130

	
131 131
    void nextOut(Arc& arc) const {
132 132
      if (arc._id % _node_num == 0) arc._id = 0;
133 133
      --arc._id;
134 134
    }
135 135

	
136 136
    void firstIn(Arc& arc, const Node& node) const {
137 137
      arc._id = _arc_num + node._id - _node_num;
138 138
    }
139 139

	
140 140
    void nextIn(Arc& arc) const {
141 141
      arc._id -= _node_num;
142 142
      if (arc._id < 0) arc._id = -1;
143 143
    }
144 144

	
145 145
  };
146 146

	
147 147
  typedef DigraphExtender<FullDigraphBase> ExtendedFullDigraphBase;
148 148

	
149 149
  /// \ingroup graphs
150 150
  ///
151
  /// \brief A full digraph class.
151
  /// \brief A directed full graph class.
152 152
  ///
153
  /// This is a simple and fast directed full graph implementation.
154
  /// From each node go arcs to each node (including the source node),
155
  /// therefore the number of the arcs in the digraph is the square of
156
  /// the node number. This digraph type is completely static, so you
157
  /// can neither add nor delete either arcs or nodes, and it needs
158
  /// constant space in memory.
153
  /// FullDigraph is a simple and fast implmenetation of directed full
154
  /// (complete) graphs. It contains an arc from each node to each node
155
  /// (including a loop for each node), therefore the number of arcs
156
  /// is the square of the number of nodes.
157
  /// This class is completely static and it needs constant memory space.
158
  /// Thus you can neither add nor delete nodes or arcs, however
159
  /// the structure can be resized using resize().
159 160
  ///
160
  /// This class fully conforms to the \ref concepts::Digraph
161
  /// "Digraph concept".
161
  /// This type fully conforms to the \ref concepts::Digraph "Digraph concept".
162
  /// Most of its member functions and nested classes are documented
163
  /// only in the concept class.
162 164
  ///
163
  /// The \c FullDigraph and \c FullGraph classes are very similar,
165
  /// \note FullDigraph and FullGraph classes are very similar,
164 166
  /// but there are two differences. While this class conforms only
165
  /// to the \ref concepts::Digraph "Digraph" concept, the \c FullGraph
166
  /// class conforms to the \ref concepts::Graph "Graph" concept,
167
  /// moreover \c FullGraph does not contain a loop arc for each
168
  /// node as \c FullDigraph does.
167
  /// to the \ref concepts::Digraph "Digraph" concept, FullGraph
168
  /// conforms to the \ref concepts::Graph "Graph" concept,
169
  /// moreover FullGraph does not contain a loop for each
170
  /// node as this class does.
169 171
  ///
170 172
  /// \sa FullGraph
171 173
  class FullDigraph : public ExtendedFullDigraphBase {
172 174
    typedef ExtendedFullDigraphBase Parent;
173 175

	
174 176
  public:
175 177

	
176
    /// \brief Constructor
178
    /// \brief Default constructor.
179
    ///
180
    /// Default constructor. The number of nodes and arcs will be zero.
177 181
    FullDigraph() { construct(0); }
178 182

	
179 183
    /// \brief Constructor
180 184
    ///
181 185
    /// Constructor.
182 186
    /// \param n The number of the nodes.
183 187
    FullDigraph(int n) { construct(n); }
184 188

	
185 189
    /// \brief Resizes the digraph
186 190
    ///
187
    /// Resizes the digraph. The function will fully destroy and
188
    /// rebuild the digraph. This cause that the maps of the digraph will
191
    /// This function resizes the digraph. It fully destroys and
192
    /// rebuilds the structure, therefore the maps of the digraph will be
189 193
    /// reallocated automatically and the previous values will be lost.
190 194
    void resize(int n) {
191 195
      Parent::notifier(Arc()).clear();
192 196
      Parent::notifier(Node()).clear();
193 197
      construct(n);
194 198
      Parent::notifier(Node()).build();
195 199
      Parent::notifier(Arc()).build();
196 200
    }
197 201

	
198 202
    /// \brief Returns the node with the given index.
199 203
    ///
200
    /// Returns the node with the given index. Since it is a static
201
    /// digraph its nodes can be indexed with integers from the range
202
    /// <tt>[0..nodeNum()-1]</tt>.
204
    /// Returns the node with the given index. Since this structure is 
205
    /// completely static, the nodes can be indexed with integers from
206
    /// the range <tt>[0..nodeNum()-1]</tt>.
203 207
    /// \sa index()
204 208
    Node operator()(int ix) const { return Parent::operator()(ix); }
205 209

	
206 210
    /// \brief Returns the index of the given node.
207 211
    ///
208
    /// Returns the index of the given node. Since it is a static
209
    /// digraph its nodes can be indexed with integers from the range
210
    /// <tt>[0..nodeNum()-1]</tt>.
211
    /// \sa operator()
212
    int index(const Node& node) const { return Parent::index(node); }
212
    /// Returns the index of the given node. Since this structure is 
213
    /// completely static, the nodes can be indexed with integers from
214
    /// the range <tt>[0..nodeNum()-1]</tt>.
215
    /// \sa operator()()
216
    static int index(const Node& node) { return Parent::index(node); }
213 217

	
214 218
    /// \brief Returns the arc connecting the given nodes.
215 219
    ///
216 220
    /// Returns the arc connecting the given nodes.
217
    Arc arc(const Node& u, const Node& v) const {
221
    Arc arc(Node u, Node v) const {
218 222
      return Parent::arc(u, v);
219 223
    }
220 224

	
221 225
    /// \brief Number of nodes.
222 226
    int nodeNum() const { return Parent::nodeNum(); }
223 227
    /// \brief Number of arcs.
224 228
    int arcNum() const { return Parent::arcNum(); }
225 229
  };
226 230

	
227 231

	
228 232
  class FullGraphBase {
229 233
  public:
230 234

	
231 235
    typedef FullGraphBase Graph;
232 236

	
233 237
    class Node;
234 238
    class Arc;
235 239
    class Edge;
236 240

	
237 241
  protected:
238 242

	
239 243
    int _node_num;
240 244
    int _edge_num;
241 245

	
242 246
    FullGraphBase() {}
243 247

	
244 248
    void construct(int n) { _node_num = n; _edge_num = n * (n - 1) / 2; }
245 249

	
246 250
    int _uid(int e) const {
247 251
      int u = e / _node_num;
248 252
      int v = e % _node_num;
249 253
      return u < v ? u : _node_num - 2 - u;
250 254
    }
251 255

	
252 256
    int _vid(int e) const {
253 257
      int u = e / _node_num;
254 258
      int v = e % _node_num;
255 259
      return u < v ? v : _node_num - 1 - v;
256 260
    }
257 261

	
258 262
    void _uvid(int e, int& u, int& v) const {
259 263
      u = e / _node_num;
260 264
      v = e % _node_num;
261 265
      if  (u >= v) {
262 266
        u = _node_num - 2 - u;
263 267
        v = _node_num - 1 - v;
264 268
      }
265 269
    }
266 270

	
267 271
    void _stid(int a, int& s, int& t) const {
268 272
      if ((a & 1) == 1) {
269 273
        _uvid(a >> 1, s, t);
270 274
      } else {
271 275
        _uvid(a >> 1, t, s);
272 276
      }
273 277
    }
274 278

	
275 279
    int _eid(int u, int v) const {
276 280
      if (u < (_node_num - 1) / 2) {
277 281
        return u * _node_num + v;
278 282
      } else {
279 283
        return (_node_num - 1 - u) * _node_num - v - 1;
280 284
      }
281 285
    }
282 286

	
283 287
  public:
284 288

	
285 289
    Node operator()(int ix) const { return Node(ix); }
286
    int index(const Node& node) const { return node._id; }
290
    static int index(const Node& node) { return node._id; }
287 291

	
288 292
    Edge edge(const Node& u, const Node& v) const {
289 293
      if (u._id < v._id) {
290 294
        return Edge(_eid(u._id, v._id));
291 295
      } else if (u._id != v._id) {
292 296
        return Edge(_eid(v._id, u._id));
293 297
      } else {
294 298
        return INVALID;
295 299
      }
296 300
    }
297 301

	
298 302
    Arc arc(const Node& s, const Node& t) const {
299 303
      if (s._id < t._id) {
300 304
        return Arc((_eid(s._id, t._id) << 1) | 1);
301 305
      } else if (s._id != t._id) {
302 306
        return Arc(_eid(t._id, s._id) << 1);
303 307
      } else {
304 308
        return INVALID;
305 309
      }
306 310
    }
307 311

	
308 312
    typedef True NodeNumTag;
309 313
    typedef True ArcNumTag;
310 314
    typedef True EdgeNumTag;
311 315

	
312 316
    int nodeNum() const { return _node_num; }
313 317
    int arcNum() const { return 2 * _edge_num; }
314 318
    int edgeNum() const { return _edge_num; }
315 319

	
316 320
    static int id(Node node) { return node._id; }
317 321
    static int id(Arc arc) { return arc._id; }
318 322
    static int id(Edge edge) { return edge._id; }
319 323

	
320 324
    int maxNodeId() const { return _node_num-1; }
321 325
    int maxArcId() const { return 2 * _edge_num-1; }
322 326
    int maxEdgeId() const { return _edge_num-1; }
323 327

	
324 328
    static Node nodeFromId(int id) { return Node(id);}
325 329
    static Arc arcFromId(int id) { return Arc(id);}
326 330
    static Edge edgeFromId(int id) { return Edge(id);}
327 331

	
328 332
    Node u(Edge edge) const {
329 333
      return Node(_uid(edge._id));
330 334
    }
331 335

	
332 336
    Node v(Edge edge) const {
333 337
      return Node(_vid(edge._id));
334 338
    }
335 339

	
336 340
    Node source(Arc arc) const {
337 341
      return Node((arc._id & 1) == 1 ?
338 342
                  _uid(arc._id >> 1) : _vid(arc._id >> 1));
339 343
    }
340 344

	
341 345
    Node target(Arc arc) const {
342 346
      return Node((arc._id & 1) == 1 ?
343 347
                  _vid(arc._id >> 1) : _uid(arc._id >> 1));
344 348
    }
345 349

	
346 350
    typedef True FindEdgeTag;
347 351
    typedef True FindArcTag;
348 352

	
349 353
    Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
350 354
      return prev != INVALID ? INVALID : edge(u, v);
... ...
@@ -459,154 +463,158 @@
459 463
      }
460 464
    }
461 465

	
462 466
    void firstIn(Arc& arc, const Node& node) const {
463 467
      int s = _node_num - 1, t = node._id;
464 468
      if (s > t) {
465 469
        arc._id = (_eid(t, s) << 1);
466 470
      } else {
467 471
        --s;
468 472
        arc._id = (s != -1 ? (_eid(s, t) << 1) | 1 : -1);
469 473
      }
470 474
    }
471 475

	
472 476
    void nextIn(Arc& arc) const {
473 477
      int s, t;
474 478
      _stid(arc._id, s, t);
475 479
      --s;
476 480
      if (s > t) {
477 481
        arc._id = (_eid(t, s) << 1);
478 482
      } else {
479 483
        if (s == t) --s;
480 484
        arc._id = (s != -1 ? (_eid(s, t) << 1) | 1 : -1);
481 485
      }
482 486
    }
483 487

	
484 488
    void firstInc(Edge& edge, bool& dir, const Node& node) const {
485 489
      int u = node._id, v = _node_num - 1;
486 490
      if (u < v) {
487 491
        edge._id = _eid(u, v);
488 492
        dir = true;
489 493
      } else {
490 494
        --v;
491 495
        edge._id = (v != -1 ? _eid(v, u) : -1);
492 496
        dir = false;
493 497
      }
494 498
    }
495 499

	
496 500
    void nextInc(Edge& edge, bool& dir) const {
497 501
      int u, v;
498 502
      if (dir) {
499 503
        _uvid(edge._id, u, v);
500 504
        --v;
501 505
        if (u < v) {
502 506
          edge._id = _eid(u, v);
503 507
        } else {
504 508
          --v;
505 509
          edge._id = (v != -1 ? _eid(v, u) : -1);
506 510
          dir = false;
507 511
        }
508 512
      } else {
509 513
        _uvid(edge._id, v, u);
510 514
        --v;
511 515
        edge._id = (v != -1 ? _eid(v, u) : -1);
512 516
      }
513 517
    }
514 518

	
515 519
  };
516 520

	
517 521
  typedef GraphExtender<FullGraphBase> ExtendedFullGraphBase;
518 522

	
519 523
  /// \ingroup graphs
520 524
  ///
521 525
  /// \brief An undirected full graph class.
522 526
  ///
523
  /// This is a simple and fast undirected full graph
524
  /// implementation. From each node go edge to each other node,
525
  /// therefore the number of edges in the graph is \f$n(n-1)/2\f$.
526
  /// This graph type is completely static, so you can neither
527
  /// add nor delete either edges or nodes, and it needs constant
528
  /// space in memory.
527
  /// FullGraph is a simple and fast implmenetation of undirected full
528
  /// (complete) graphs. It contains an edge between every distinct pair
529
  /// of nodes, therefore the number of edges is <tt>n(n-1)/2</tt>.
530
  /// This class is completely static and it needs constant memory space.
531
  /// Thus you can neither add nor delete nodes or edges, however
532
  /// the structure can be resized using resize().
529 533
  ///
530
  /// This class fully conforms to the \ref concepts::Graph "Graph concept".
534
  /// This type fully conforms to the \ref concepts::Graph "Graph concept".
535
  /// Most of its member functions and nested classes are documented
536
  /// only in the concept class.
531 537
  ///
532
  /// The \c FullGraph and \c FullDigraph classes are very similar,
533
  /// but there are two differences. While the \c FullDigraph class
538
  /// \note FullDigraph and FullGraph classes are very similar,
539
  /// but there are two differences. While FullDigraph
534 540
  /// conforms only to the \ref concepts::Digraph "Digraph" concept,
535 541
  /// this class conforms to the \ref concepts::Graph "Graph" concept,
536
  /// moreover \c FullGraph does not contain a loop arc for each
537
  /// node as \c FullDigraph does.
542
  /// moreover this class does not contain a loop for each
543
  /// node as FullDigraph does.
538 544
  ///
539 545
  /// \sa FullDigraph
540 546
  class FullGraph : public ExtendedFullGraphBase {
541 547
    typedef ExtendedFullGraphBase Parent;
542 548

	
543 549
  public:
544 550

	
545
    /// \brief Constructor
551
    /// \brief Default constructor.
552
    ///
553
    /// Default constructor. The number of nodes and edges will be zero.
546 554
    FullGraph() { construct(0); }
547 555

	
548 556
    /// \brief Constructor
549 557
    ///
550 558
    /// Constructor.
551 559
    /// \param n The number of the nodes.
552 560
    FullGraph(int n) { construct(n); }
553 561

	
554 562
    /// \brief Resizes the graph
555 563
    ///
556
    /// Resizes the graph. The function will fully destroy and
557
    /// rebuild the graph. This cause that the maps of the graph will
564
    /// This function resizes the graph. It fully destroys and
565
    /// rebuilds the structure, therefore the maps of the graph will be
558 566
    /// reallocated automatically and the previous values will be lost.
559 567
    void resize(int n) {
560 568
      Parent::notifier(Arc()).clear();
561 569
      Parent::notifier(Edge()).clear();
562 570
      Parent::notifier(Node()).clear();
563 571
      construct(n);
564 572
      Parent::notifier(Node()).build();
565 573
      Parent::notifier(Edge()).build();
566 574
      Parent::notifier(Arc()).build();
567 575
    }
568 576

	
569 577
    /// \brief Returns the node with the given index.
570 578
    ///
571
    /// Returns the node with the given index. Since it is a static
572
    /// graph its nodes can be indexed with integers from the range
573
    /// <tt>[0..nodeNum()-1]</tt>.
579
    /// Returns the node with the given index. Since this structure is 
580
    /// completely static, the nodes can be indexed with integers from
581
    /// the range <tt>[0..nodeNum()-1]</tt>.
574 582
    /// \sa index()
575 583
    Node operator()(int ix) const { return Parent::operator()(ix); }
576 584

	
577 585
    /// \brief Returns the index of the given node.
578 586
    ///
579
    /// Returns the index of the given node. Since it is a static
580
    /// graph its nodes can be indexed with integers from the range
581
    /// <tt>[0..nodeNum()-1]</tt>.
582
    /// \sa operator()
583
    int index(const Node& node) const { return Parent::index(node); }
587
    /// Returns the index of the given node. Since this structure is 
588
    /// completely static, the nodes can be indexed with integers from
589
    /// the range <tt>[0..nodeNum()-1]</tt>.
590
    /// \sa operator()()
591
    static int index(const Node& node) { return Parent::index(node); }
584 592

	
585 593
    /// \brief Returns the arc connecting the given nodes.
586 594
    ///
587 595
    /// Returns the arc connecting the given nodes.
588
    Arc arc(const Node& s, const Node& t) const {
596
    Arc arc(Node s, Node t) const {
589 597
      return Parent::arc(s, t);
590 598
    }
591 599

	
592
    /// \brief Returns the edge connects the given nodes.
600
    /// \brief Returns the edge connecting the given nodes.
593 601
    ///
594
    /// Returns the edge connects the given nodes.
595
    Edge edge(const Node& u, const Node& v) const {
602
    /// Returns the edge connecting the given nodes.
603
    Edge edge(Node u, Node v) const {
596 604
      return Parent::edge(u, v);
597 605
    }
598 606

	
599 607
    /// \brief Number of nodes.
600 608
    int nodeNum() const { return Parent::nodeNum(); }
601 609
    /// \brief Number of arcs.
602 610
    int arcNum() const { return Parent::arcNum(); }
603 611
    /// \brief Number of edges.
604 612
    int edgeNum() const { return Parent::edgeNum(); }
605 613

	
606 614
  };
607 615

	
608 616

	
609 617
} //namespace lemon
610 618

	
611 619

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

	
19 19
///\file
20 20
///\brief Implementation of the LEMON GLPK LP and MIP solver interface.
21 21

	
22 22
#include <lemon/glpk.h>
23 23
#include <glpk.h>
24 24

	
25 25
#include <lemon/assert.h>
26 26

	
27 27
namespace lemon {
28 28

	
29 29
  // GlpkBase members
30 30

	
31 31
  GlpkBase::GlpkBase() : LpBase() {
32 32
    lp = glp_create_prob();
33 33
    glp_create_index(lp);
34 34
    messageLevel(MESSAGE_NOTHING);
35 35
  }
36 36

	
37 37
  GlpkBase::GlpkBase(const GlpkBase &other) : LpBase() {
38 38
    lp = glp_create_prob();
39 39
    glp_copy_prob(lp, other.lp, GLP_ON);
40 40
    glp_create_index(lp);
41 41
    rows = other.rows;
42 42
    cols = other.cols;
43 43
    messageLevel(MESSAGE_NOTHING);
44 44
  }
45 45

	
46 46
  GlpkBase::~GlpkBase() {
47 47
    glp_delete_prob(lp);
48 48
  }
49 49

	
50 50
  int GlpkBase::_addCol() {
51 51
    int i = glp_add_cols(lp, 1);
52 52
    glp_set_col_bnds(lp, i, GLP_FR, 0.0, 0.0);
53 53
    return i;
54 54
  }
55 55

	
56 56
  int GlpkBase::_addRow() {
57 57
    int i = glp_add_rows(lp, 1);
58 58
    glp_set_row_bnds(lp, i, GLP_FR, 0.0, 0.0);
59 59
    return i;
60 60
  }
61 61

	
62
  int GlpkBase::_addRow(Value lo, ExprIterator b, 
63
                        ExprIterator e, Value up) {
64
    int i = glp_add_rows(lp, 1);
65

	
66
    if (lo == -INF) {
67
      if (up == INF) {
68
        glp_set_row_bnds(lp, i, GLP_FR, lo, up);
69
      } else {
70
        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
71
      }    
72
    } else {
73
      if (up == INF) {
74
        glp_set_row_bnds(lp, i, GLP_LO, lo, up);
75
      } else if (lo != up) {        
76
        glp_set_row_bnds(lp, i, GLP_DB, lo, up);
77
      } else {
78
        glp_set_row_bnds(lp, i, GLP_FX, lo, up);
79
      }
80
    }
81

	
82
    std::vector<int> indexes;
83
    std::vector<Value> values;
84

	
85
    indexes.push_back(0);
86
    values.push_back(0);
87

	
88
    for(ExprIterator it = b; it != e; ++it) {
89
      indexes.push_back(it->first);
90
      values.push_back(it->second);
91
    }
92

	
93
    glp_set_mat_row(lp, i, values.size() - 1,
94
                    &indexes.front(), &values.front());
95
    return i;
96
  }
97

	
62 98
  void GlpkBase::_eraseCol(int i) {
63 99
    int ca[2];
64 100
    ca[1] = i;
65 101
    glp_del_cols(lp, 1, ca);
66 102
  }
67 103

	
68 104
  void GlpkBase::_eraseRow(int i) {
69 105
    int ra[2];
70 106
    ra[1] = i;
71 107
    glp_del_rows(lp, 1, ra);
72 108
  }
73 109

	
74 110
  void GlpkBase::_eraseColId(int i) {
75 111
    cols.eraseIndex(i);
76 112
    cols.shiftIndices(i);
77 113
  }
78 114

	
79 115
  void GlpkBase::_eraseRowId(int i) {
80 116
    rows.eraseIndex(i);
81 117
    rows.shiftIndices(i);
82 118
  }
83 119

	
84 120
  void GlpkBase::_getColName(int c, std::string& name) const {
85 121
    const char *str = glp_get_col_name(lp, c);
86 122
    if (str) name = str;
87 123
    else name.clear();
88 124
  }
89 125

	
90 126
  void GlpkBase::_setColName(int c, const std::string & name) {
91 127
    glp_set_col_name(lp, c, const_cast<char*>(name.c_str()));
92 128

	
93 129
  }
94 130

	
95 131
  int GlpkBase::_colByName(const std::string& name) const {
96 132
    int k = glp_find_col(lp, const_cast<char*>(name.c_str()));
97 133
    return k > 0 ? k : -1;
98 134
  }
99 135

	
100 136
  void GlpkBase::_getRowName(int r, std::string& name) const {
101 137
    const char *str = glp_get_row_name(lp, r);
102 138
    if (str) name = str;
103 139
    else name.clear();
104 140
  }
105 141

	
106 142
  void GlpkBase::_setRowName(int r, const std::string & name) {
107 143
    glp_set_row_name(lp, r, const_cast<char*>(name.c_str()));
108 144

	
109 145
  }
110 146

	
111 147
  int GlpkBase::_rowByName(const std::string& name) const {
112 148
    int k = glp_find_row(lp, const_cast<char*>(name.c_str()));
113 149
    return k > 0 ? k : -1;
114 150
  }
115 151

	
116 152
  void GlpkBase::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) {
117 153
    std::vector<int> indexes;
118 154
    std::vector<Value> values;
119 155

	
120 156
    indexes.push_back(0);
121 157
    values.push_back(0);
122 158

	
123 159
    for(ExprIterator it = b; it != e; ++it) {
124 160
      indexes.push_back(it->first);
125 161
      values.push_back(it->second);
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_GLPK_H
20 20
#define LEMON_GLPK_H
21 21

	
22 22
///\file
23 23
///\brief Header of the LEMON-GLPK lp solver interface.
24 24
///\ingroup lp_group
25 25

	
26 26
#include <lemon/lp_base.h>
27 27

	
28 28
// forward declaration
29 29
#if !defined _GLP_PROB && !defined GLP_PROB
30 30
#define _GLP_PROB
31 31
#define GLP_PROB
32 32
typedef struct { double _opaque_prob; } glp_prob;
33 33
/* LP/MIP problem object */
34 34
#endif
35 35

	
36 36
namespace lemon {
37 37

	
38 38

	
39 39
  /// \brief Base interface for the GLPK LP and MIP solver
40 40
  ///
41 41
  /// This class implements the common interface of the GLPK LP and MIP solver.
42 42
  /// \ingroup lp_group
43 43
  class GlpkBase : virtual public LpBase {
44 44
  protected:
45 45

	
46 46
    typedef glp_prob LPX;
47 47
    glp_prob* lp;
48 48

	
49 49
    GlpkBase();
50 50
    GlpkBase(const GlpkBase&);
51 51
    virtual ~GlpkBase();
52 52

	
53 53
  protected:
54 54

	
55 55
    virtual int _addCol();
56 56
    virtual int _addRow();
57
    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
57 58

	
58 59
    virtual void _eraseCol(int i);
59 60
    virtual void _eraseRow(int i);
60 61

	
61 62
    virtual void _eraseColId(int i);
62 63
    virtual void _eraseRowId(int i);
63 64

	
64 65
    virtual void _getColName(int col, std::string& name) const;
65 66
    virtual void _setColName(int col, const std::string& name);
66 67
    virtual int _colByName(const std::string& name) const;
67 68

	
68 69
    virtual void _getRowName(int row, std::string& name) const;
69 70
    virtual void _setRowName(int row, const std::string& name);
70 71
    virtual int _rowByName(const std::string& name) const;
71 72

	
72 73
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
73 74
    virtual void _getRowCoeffs(int i, InsertIterator b) const;
74 75

	
75 76
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
76 77
    virtual void _getColCoeffs(int i, InsertIterator b) const;
77 78

	
78 79
    virtual void _setCoeff(int row, int col, Value value);
79 80
    virtual Value _getCoeff(int row, int col) const;
80 81

	
81 82
    virtual void _setColLowerBound(int i, Value value);
82 83
    virtual Value _getColLowerBound(int i) const;
83 84

	
84 85
    virtual void _setColUpperBound(int i, Value value);
85 86
    virtual Value _getColUpperBound(int i) const;
86 87

	
87 88
    virtual void _setRowLowerBound(int i, Value value);
88 89
    virtual Value _getRowLowerBound(int i) const;
89 90

	
90 91
    virtual void _setRowUpperBound(int i, Value value);
91 92
    virtual Value _getRowUpperBound(int i) const;
92 93

	
93 94
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
94 95
    virtual void _getObjCoeffs(InsertIterator b) const;
95 96

	
96 97
    virtual void _setObjCoeff(int i, Value obj_coef);
97 98
    virtual Value _getObjCoeff(int i) const;
98 99

	
99 100
    virtual void _setSense(Sense);
100 101
    virtual Sense _getSense() const;
101 102

	
102 103
    virtual void _clear();
103 104

	
104 105
    virtual void _messageLevel(MessageLevel level);
105 106

	
106 107
  private:
107 108

	
108 109
    static void freeEnv();
109 110

	
110 111
    struct FreeEnvHelper {
111 112
      ~FreeEnvHelper() {
112 113
        freeEnv();
113 114
      }
114 115
    };
115 116
    
116 117
    static FreeEnvHelper freeEnvHelper;
117 118

	
118 119
  protected:
119 120
    
120 121
    int _message_level;
Ignore white space 6 line context
... ...
@@ -409,295 +409,289 @@
409 409
          dir = false;
410 410
          return;
411 411
        }
412 412
      } else {
413 413
        if (nid >= _edge_limit) {
414 414
          nid = (nid - _edge_limit) % (_width - 1) +
415 415
            (nid - _edge_limit) / (_width - 1) * _width + 1;
416 416
          if (nid >= _width) {
417 417
            edge._id = nid - _width;
418 418
            return;
419 419
          }
420 420
        }
421 421
      }
422 422
      edge._id = -1;
423 423
      dir = true;
424 424
    }
425 425

	
426 426
    Arc right(Node n) const {
427 427
      if (n._id % _width < _width - 1) {
428 428
        return Arc(((_edge_limit + n._id % _width +
429 429
                    (n._id / _width) * (_width - 1)) << 1) | 1);
430 430
      } else {
431 431
        return INVALID;
432 432
      }
433 433
    }
434 434

	
435 435
    Arc left(Node n) const {
436 436
      if (n._id % _width > 0) {
437 437
        return Arc((_edge_limit + n._id % _width +
438 438
                     (n._id / _width) * (_width - 1) - 1) << 1);
439 439
      } else {
440 440
        return INVALID;
441 441
      }
442 442
    }
443 443

	
444 444
    Arc up(Node n) const {
445 445
      if (n._id < _edge_limit) {
446 446
        return Arc((n._id << 1) | 1);
447 447
      } else {
448 448
        return INVALID;
449 449
      }
450 450
    }
451 451

	
452 452
    Arc down(Node n) const {
453 453
      if (n._id >= _width) {
454 454
        return Arc((n._id - _width) << 1);
455 455
      } else {
456 456
        return INVALID;
457 457
      }
458 458
    }
459 459

	
460 460
  private:
461 461
    int _width, _height;
462 462
    int _node_num, _edge_num;
463 463
    int _edge_limit;
464 464
  };
465 465

	
466 466

	
467 467
  typedef GraphExtender<GridGraphBase> ExtendedGridGraphBase;
468 468

	
469 469
  /// \ingroup graphs
470 470
  ///
471 471
  /// \brief Grid graph class
472 472
  ///
473
  /// This class implements a special graph type. The nodes of the
474
  /// graph can be indexed by two integer \c (i,j) value where \c i is
475
  /// in the \c [0..width()-1] range and j is in the \c
476
  /// [0..height()-1] range.  Two nodes are connected in the graph if
477
  /// the indexes differ exactly on one position and exactly one is
478
  /// the difference. The nodes of the graph can be indexed by position
479
  /// with the \c operator()() function. The positions of the nodes can be
480
  /// get with \c pos(), \c col() and \c row() members. The outgoing
473
  /// GridGraph implements a special graph type. The nodes of the
474
  /// graph can be indexed by two integer values \c (i,j) where \c i is
475
  /// in the range <tt>[0..width()-1]</tt> and j is in the range
476
  /// <tt>[0..height()-1]</tt>. Two nodes are connected in the graph if
477
  /// the indices differ exactly on one position and the difference is
478
  /// also exactly one. The nodes of the graph can be obtained by position
479
  /// using the \c operator()() function and the indices of the nodes can
480
  /// be obtained using \c pos(), \c col() and \c row() members. The outgoing
481 481
  /// arcs can be retrieved with the \c right(), \c up(), \c left()
482 482
  /// and \c down() functions, where the bottom-left corner is the
483 483
  /// origin.
484 484
  ///
485
  /// This class is completely static and it needs constant memory space.
486
  /// Thus you can neither add nor delete nodes or edges, however
487
  /// the structure can be resized using resize().
488
  ///
485 489
  /// \image html grid_graph.png
486 490
  /// \image latex grid_graph.eps "Grid graph" width=\textwidth
487 491
  ///
488 492
  /// A short example about the basic usage:
489 493
  ///\code
490 494
  /// GridGraph graph(rows, cols);
491 495
  /// GridGraph::NodeMap<int> val(graph);
492 496
  /// for (int i = 0; i < graph.width(); ++i) {
493 497
  ///   for (int j = 0; j < graph.height(); ++j) {
494 498
  ///     val[graph(i, j)] = i + j;
495 499
  ///   }
496 500
  /// }
497 501
  ///\endcode
498 502
  ///
499
  /// This graph type fully conforms to the \ref concepts::Graph
500
  /// "Graph concept".
503
  /// This type fully conforms to the \ref concepts::Graph "Graph concept".
504
  /// Most of its member functions and nested classes are documented
505
  /// only in the concept class.
501 506
  class GridGraph : public ExtendedGridGraphBase {
502 507
    typedef ExtendedGridGraphBase Parent;
503 508

	
504 509
  public:
505 510

	
506
    /// \brief Map to get the indices of the nodes as dim2::Point<int>.
511
    /// \brief Map to get the indices of the nodes as \ref dim2::Point
512
    /// "dim2::Point<int>".
507 513
    ///
508
    /// Map to get the indices of the nodes as dim2::Point<int>.
514
    /// Map to get the indices of the nodes as \ref dim2::Point
515
    /// "dim2::Point<int>".
509 516
    class IndexMap {
510 517
    public:
511 518
      /// \brief The key type of the map
512 519
      typedef GridGraph::Node Key;
513 520
      /// \brief The value type of the map
514 521
      typedef dim2::Point<int> Value;
515 522

	
516 523
      /// \brief Constructor
517
      ///
518
      /// Constructor
519 524
      IndexMap(const GridGraph& graph) : _graph(graph) {}
520 525

	
521 526
      /// \brief The subscript operator
522
      ///
523
      /// The subscript operator.
524 527
      Value operator[](Key key) const {
525 528
        return _graph.pos(key);
526 529
      }
527 530

	
528 531
    private:
529 532
      const GridGraph& _graph;
530 533
    };
531 534

	
532 535
    /// \brief Map to get the column of the nodes.
533 536
    ///
534 537
    /// Map to get the column of the nodes.
535 538
    class ColMap {
536 539
    public:
537 540
      /// \brief The key type of the map
538 541
      typedef GridGraph::Node Key;
539 542
      /// \brief The value type of the map
540 543
      typedef int Value;
541 544

	
542 545
      /// \brief Constructor
543
      ///
544
      /// Constructor
545 546
      ColMap(const GridGraph& graph) : _graph(graph) {}
546 547

	
547 548
      /// \brief The subscript operator
548
      ///
549
      /// The subscript operator.
550 549
      Value operator[](Key key) const {
551 550
        return _graph.col(key);
552 551
      }
553 552

	
554 553
    private:
555 554
      const GridGraph& _graph;
556 555
    };
557 556

	
558 557
    /// \brief Map to get the row of the nodes.
559 558
    ///
560 559
    /// Map to get the row of the nodes.
561 560
    class RowMap {
562 561
    public:
563 562
      /// \brief The key type of the map
564 563
      typedef GridGraph::Node Key;
565 564
      /// \brief The value type of the map
566 565
      typedef int Value;
567 566

	
568 567
      /// \brief Constructor
569
      ///
570
      /// Constructor
571 568
      RowMap(const GridGraph& graph) : _graph(graph) {}
572 569

	
573 570
      /// \brief The subscript operator
574
      ///
575
      /// The subscript operator.
576 571
      Value operator[](Key key) const {
577 572
        return _graph.row(key);
578 573
      }
579 574

	
580 575
    private:
581 576
      const GridGraph& _graph;
582 577
    };
583 578

	
584 579
    /// \brief Constructor
585 580
    ///
586
    /// Construct a grid graph with given size.
581
    /// Construct a grid graph with the given size.
587 582
    GridGraph(int width, int height) { construct(width, height); }
588 583

	
589
    /// \brief Resize the graph
584
    /// \brief Resizes the graph
590 585
    ///
591
    /// Resize the graph. The function will fully destroy and rebuild
592
    /// the graph.  This cause that the maps of the graph will
593
    /// reallocated automatically and the previous values will be
594
    /// lost.
586
    /// This function resizes the graph. It fully destroys and
587
    /// rebuilds the structure, therefore the maps of the graph will be
588
    /// reallocated automatically and the previous values will be lost.
595 589
    void resize(int width, int height) {
596 590
      Parent::notifier(Arc()).clear();
597 591
      Parent::notifier(Edge()).clear();
598 592
      Parent::notifier(Node()).clear();
599 593
      construct(width, height);
600 594
      Parent::notifier(Node()).build();
601 595
      Parent::notifier(Edge()).build();
602 596
      Parent::notifier(Arc()).build();
603 597
    }
604 598

	
605 599
    /// \brief The node on the given position.
606 600
    ///
607 601
    /// Gives back the node on the given position.
608 602
    Node operator()(int i, int j) const {
609 603
      return Parent::operator()(i, j);
610 604
    }
611 605

	
612
    /// \brief Gives back the column index of the node.
606
    /// \brief The column index of the node.
613 607
    ///
614 608
    /// Gives back the column index of the node.
615 609
    int col(Node n) const {
616 610
      return Parent::col(n);
617 611
    }
618 612

	
619
    /// \brief Gives back the row index of the node.
613
    /// \brief The row index of the node.
620 614
    ///
621 615
    /// Gives back the row index of the node.
622 616
    int row(Node n) const {
623 617
      return Parent::row(n);
624 618
    }
625 619

	
626
    /// \brief Gives back the position of the node.
620
    /// \brief The position of the node.
627 621
    ///
628 622
    /// Gives back the position of the node, ie. the <tt>(col,row)</tt> pair.
629 623
    dim2::Point<int> pos(Node n) const {
630 624
      return Parent::pos(n);
631 625
    }
632 626

	
633
    /// \brief Gives back the number of the columns.
627
    /// \brief The number of the columns.
634 628
    ///
635 629
    /// Gives back the number of the columns.
636 630
    int width() const {
637 631
      return Parent::width();
638 632
    }
639 633

	
640
    /// \brief Gives back the number of the rows.
634
    /// \brief The number of the rows.
641 635
    ///
642 636
    /// Gives back the number of the rows.
643 637
    int height() const {
644 638
      return Parent::height();
645 639
    }
646 640

	
647
    /// \brief Gives back the arc goes right from the node.
641
    /// \brief The arc goes right from the node.
648 642
    ///
649 643
    /// Gives back the arc goes right from the node. If there is not
650 644
    /// outgoing arc then it gives back INVALID.
651 645
    Arc right(Node n) const {
652 646
      return Parent::right(n);
653 647
    }
654 648

	
655
    /// \brief Gives back the arc goes left from the node.
649
    /// \brief The arc goes left from the node.
656 650
    ///
657 651
    /// Gives back the arc goes left from the node. If there is not
658 652
    /// outgoing arc then it gives back INVALID.
659 653
    Arc left(Node n) const {
660 654
      return Parent::left(n);
661 655
    }
662 656

	
663
    /// \brief Gives back the arc goes up from the node.
657
    /// \brief The arc goes up from the node.
664 658
    ///
665 659
    /// Gives back the arc goes up from the node. If there is not
666 660
    /// outgoing arc then it gives back INVALID.
667 661
    Arc up(Node n) const {
668 662
      return Parent::up(n);
669 663
    }
670 664

	
671
    /// \brief Gives back the arc goes down from the node.
665
    /// \brief The arc goes down from the node.
672 666
    ///
673 667
    /// Gives back the arc goes down from the node. If there is not
674 668
    /// outgoing arc then it gives back INVALID.
675 669
    Arc down(Node n) const {
676 670
      return Parent::down(n);
677 671
    }
678 672

	
679 673
    /// \brief Index map of the grid graph
680 674
    ///
681 675
    /// Just returns an IndexMap for the grid graph.
682 676
    IndexMap indexMap() const {
683 677
      return IndexMap(*this);
684 678
    }
685 679

	
686 680
    /// \brief Row map of the grid graph
687 681
    ///
688 682
    /// Just returns a RowMap for the grid graph.
689 683
    RowMap rowMap() const {
690 684
      return RowMap(*this);
691 685
    }
692 686

	
693 687
    /// \brief Column map of the grid graph
694 688
    ///
695 689
    /// Just returns a ColMap for the grid graph.
696 690
    ColMap colMap() const {
697 691
      return ColMap(*this);
698 692
    }
699 693

	
700 694
  };
701 695

	
702 696
}
703 697
#endif
Ignore white space 6 line context
... ...
@@ -201,204 +201,223 @@
201 201
          ((n._id >> (k+1)) << k) | (n._id & ((1 << k) - 1));
202 202
        dir = ((n._id >> k) & 1) == 0;
203 203
      } else {
204 204
        edge._id = -1;
205 205
        dir = true;
206 206
      }
207 207
    }
208 208

	
209 209
    void firstOut(Arc& arc, const Node& node) const {
210 210
      arc._id = ((node._id >> 1) << 1) | (~node._id & 1);
211 211
    }
212 212

	
213 213
    void nextOut(Arc& arc) const {
214 214
      Node n = (arc._id & 1) == 1 ? u(arc) : v(arc);
215 215
      int k = (arc._id >> _dim) + 1;
216 216
      if (k < _dim) {
217 217
        arc._id = (k << (_dim-1)) |
218 218
          ((n._id >> (k+1)) << k) | (n._id & ((1 << k) - 1));
219 219
        arc._id = (arc._id << 1) | (~(n._id >> k) & 1);
220 220
      } else {
221 221
        arc._id = -1;
222 222
      }
223 223
    }
224 224

	
225 225
    void firstIn(Arc& arc, const Node& node) const {
226 226
      arc._id = ((node._id >> 1) << 1) | (node._id & 1);
227 227
    }
228 228

	
229 229
    void nextIn(Arc& arc) const {
230 230
      Node n = (arc._id & 1) == 1 ? v(arc) : u(arc);
231 231
      int k = (arc._id >> _dim) + 1;
232 232
      if (k < _dim) {
233 233
        arc._id = (k << (_dim-1)) |
234 234
          ((n._id >> (k+1)) << k) | (n._id & ((1 << k) - 1));
235 235
        arc._id = (arc._id << 1) | ((n._id >> k) & 1);
236 236
      } else {
237 237
        arc._id = -1;
238 238
      }
239 239
    }
240 240

	
241 241
    static bool direction(Arc arc) {
242 242
      return (arc._id & 1) == 1;
243 243
    }
244 244

	
245 245
    static Arc direct(Edge edge, bool dir) {
246 246
      return Arc((edge._id << 1) | (dir ? 1 : 0));
247 247
    }
248 248

	
249 249
    int dimension() const {
250 250
      return _dim;
251 251
    }
252 252

	
253 253
    bool projection(Node node, int n) const {
254 254
      return static_cast<bool>(node._id & (1 << n));
255 255
    }
256 256

	
257 257
    int dimension(Edge edge) const {
258 258
      return edge._id >> (_dim-1);
259 259
    }
260 260

	
261 261
    int dimension(Arc arc) const {
262 262
      return arc._id >> _dim;
263 263
    }
264 264

	
265
    int index(Node node) const {
265
    static int index(Node node) {
266 266
      return node._id;
267 267
    }
268 268

	
269 269
    Node operator()(int ix) const {
270 270
      return Node(ix);
271 271
    }
272 272

	
273 273
  private:
274 274
    int _dim;
275 275
    int _node_num, _edge_num;
276 276
  };
277 277

	
278 278

	
279 279
  typedef GraphExtender<HypercubeGraphBase> ExtendedHypercubeGraphBase;
280 280

	
281 281
  /// \ingroup graphs
282 282
  ///
283 283
  /// \brief Hypercube graph class
284 284
  ///
285
  /// This class implements a special graph type. The nodes of the graph
286
  /// are indiced with integers with at most \c dim binary digits.
285
  /// HypercubeGraph implements a special graph type. The nodes of the
286
  /// graph are indexed with integers having at most \c dim binary digits.
287 287
  /// Two nodes are connected in the graph if and only if their indices
288 288
  /// differ only on one position in the binary form.
289
  /// This class is completely static and it needs constant memory space.
290
  /// Thus you can neither add nor delete nodes or edges, however 
291
  /// the structure can be resized using resize().
292
  ///
293
  /// This type fully conforms to the \ref concepts::Graph "Graph concept".
294
  /// Most of its member functions and nested classes are documented
295
  /// only in the concept class.
289 296
  ///
290 297
  /// \note The type of the indices is chosen to \c int for efficiency
291 298
  /// reasons. Thus the maximum dimension of this implementation is 26
292 299
  /// (assuming that the size of \c int is 32 bit).
293
  ///
294
  /// This graph type fully conforms to the \ref concepts::Graph
295
  /// "Graph concept".
296 300
  class HypercubeGraph : public ExtendedHypercubeGraphBase {
297 301
    typedef ExtendedHypercubeGraphBase Parent;
298 302

	
299 303
  public:
300 304

	
301 305
    /// \brief Constructs a hypercube graph with \c dim dimensions.
302 306
    ///
303 307
    /// Constructs a hypercube graph with \c dim dimensions.
304 308
    HypercubeGraph(int dim) { construct(dim); }
305 309

	
310
    /// \brief Resizes the graph
311
    ///
312
    /// This function resizes the graph. It fully destroys and
313
    /// rebuilds the structure, therefore the maps of the graph will be
314
    /// reallocated automatically and the previous values will be lost.
315
    void resize(int dim) {
316
      Parent::notifier(Arc()).clear();
317
      Parent::notifier(Edge()).clear();
318
      Parent::notifier(Node()).clear();
319
      construct(dim);
320
      Parent::notifier(Node()).build();
321
      Parent::notifier(Edge()).build();
322
      Parent::notifier(Arc()).build();
323
    }
324

	
306 325
    /// \brief The number of dimensions.
307 326
    ///
308 327
    /// Gives back the number of dimensions.
309 328
    int dimension() const {
310 329
      return Parent::dimension();
311 330
    }
312 331

	
313 332
    /// \brief Returns \c true if the n'th bit of the node is one.
314 333
    ///
315 334
    /// Returns \c true if the n'th bit of the node is one.
316 335
    bool projection(Node node, int n) const {
317 336
      return Parent::projection(node, n);
318 337
    }
319 338

	
320 339
    /// \brief The dimension id of an edge.
321 340
    ///
322 341
    /// Gives back the dimension id of the given edge.
323
    /// It is in the [0..dim-1] range.
342
    /// It is in the range <tt>[0..dim-1]</tt>.
324 343
    int dimension(Edge edge) const {
325 344
      return Parent::dimension(edge);
326 345
    }
327 346

	
328 347
    /// \brief The dimension id of an arc.
329 348
    ///
330 349
    /// Gives back the dimension id of the given arc.
331
    /// It is in the [0..dim-1] range.
350
    /// It is in the range <tt>[0..dim-1]</tt>.
332 351
    int dimension(Arc arc) const {
333 352
      return Parent::dimension(arc);
334 353
    }
335 354

	
336 355
    /// \brief The index of a node.
337 356
    ///
338 357
    /// Gives back the index of the given node.
339 358
    /// The lower bits of the integer describes the node.
340
    int index(Node node) const {
359
    static int index(Node node) {
341 360
      return Parent::index(node);
342 361
    }
343 362

	
344 363
    /// \brief Gives back a node by its index.
345 364
    ///
346 365
    /// Gives back a node by its index.
347 366
    Node operator()(int ix) const {
348 367
      return Parent::operator()(ix);
349 368
    }
350 369

	
351 370
    /// \brief Number of nodes.
352 371
    int nodeNum() const { return Parent::nodeNum(); }
353 372
    /// \brief Number of edges.
354 373
    int edgeNum() const { return Parent::edgeNum(); }
355 374
    /// \brief Number of arcs.
356 375
    int arcNum() const { return Parent::arcNum(); }
357 376

	
358 377
    /// \brief Linear combination map.
359 378
    ///
360 379
    /// This map makes possible to give back a linear combination
361 380
    /// for each node. It works like the \c std::accumulate function,
362 381
    /// so it accumulates the \c bf binary function with the \c fv first
363 382
    /// value. The map accumulates only on that positions (dimensions)
364 383
    /// where the index of the node is one. The values that have to be
365 384
    /// accumulated should be given by the \c begin and \c end iterators
366 385
    /// and the length of this range should be equal to the dimension
367 386
    /// number of the graph.
368 387
    ///
369 388
    ///\code
370 389
    /// const int DIM = 3;
371 390
    /// HypercubeGraph graph(DIM);
372 391
    /// dim2::Point<double> base[DIM];
373 392
    /// for (int k = 0; k < DIM; ++k) {
374 393
    ///   base[k].x = rnd();
375 394
    ///   base[k].y = rnd();
376 395
    /// }
377 396
    /// HypercubeGraph::HyperMap<dim2::Point<double> >
378 397
    ///   pos(graph, base, base + DIM, dim2::Point<double>(0.0, 0.0));
379 398
    ///\endcode
380 399
    ///
381 400
    /// \see HypercubeGraph
382 401
    template <typename T, typename BF = std::plus<T> >
383 402
    class HyperMap {
384 403
    public:
385 404

	
386 405
      /// \brief The key type of the map
387 406
      typedef Node Key;
388 407
      /// \brief The value type of the map
389 408
      typedef T Value;
390 409

	
391 410
      /// \brief Constructor for HyperMap.
392 411
      ///
393 412
      /// Construct a HyperMap for the given graph. The values that have
394 413
      /// to be accumulated should be given by the \c begin and \c end
395 414
      /// iterators and the length of this range should be equal to the
396 415
      /// dimension number of the graph.
397 416
      ///
398 417
      /// This map accumulates the \c bf binary function with the \c fv
399 418
      /// first value on that positions (dimensions) where the index of
400 419
      /// the node is one.
401 420
      template <typename It>
402 421
      HyperMap(const Graph& graph, It begin, It end,
403 422
               T fv = 0, const BF& bf = BF())
404 423
        : _graph(graph), _values(begin, end), _first_value(fv), _bin_func(bf)
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_LIST_GRAPH_H
20 20
#define LEMON_LIST_GRAPH_H
21 21

	
22 22
///\ingroup graphs
23 23
///\file
24
///\brief ListDigraph, ListGraph classes.
24
///\brief ListDigraph and ListGraph classes.
25 25

	
26 26
#include <lemon/core.h>
27 27
#include <lemon/error.h>
28 28
#include <lemon/bits/graph_extender.h>
29 29

	
30 30
#include <vector>
31 31
#include <list>
32 32

	
33 33
namespace lemon {
34 34

	
35
  class ListDigraph;
36

	
35 37
  class ListDigraphBase {
36 38

	
37 39
  protected:
38 40
    struct NodeT {
39 41
      int first_in, first_out;
40 42
      int prev, next;
41 43
    };
42 44

	
43 45
    struct ArcT {
44 46
      int target, source;
45 47
      int prev_in, prev_out;
46 48
      int next_in, next_out;
47 49
    };
48 50

	
49 51
    std::vector<NodeT> nodes;
50 52

	
51 53
    int first_node;
52 54

	
53 55
    int first_free_node;
54 56

	
55 57
    std::vector<ArcT> arcs;
56 58

	
57 59
    int first_free_arc;
58 60

	
59 61
  public:
60 62

	
61 63
    typedef ListDigraphBase Digraph;
62 64

	
63 65
    class Node {
64 66
      friend class ListDigraphBase;
67
      friend class ListDigraph;
65 68
    protected:
66 69

	
67 70
      int id;
68 71
      explicit Node(int pid) { id = pid;}
69 72

	
70 73
    public:
71 74
      Node() {}
72 75
      Node (Invalid) { id = -1; }
73 76
      bool operator==(const Node& node) const {return id == node.id;}
74 77
      bool operator!=(const Node& node) const {return id != node.id;}
75 78
      bool operator<(const Node& node) const {return id < node.id;}
76 79
    };
77 80

	
78 81
    class Arc {
79 82
      friend class ListDigraphBase;
83
      friend class ListDigraph;
80 84
    protected:
81 85

	
82 86
      int id;
83 87
      explicit Arc(int pid) { id = pid;}
84 88

	
85 89
    public:
86 90
      Arc() {}
87 91
      Arc (Invalid) { id = -1; }
88 92
      bool operator==(const Arc& arc) const {return id == arc.id;}
89 93
      bool operator!=(const Arc& arc) const {return id != arc.id;}
90 94
      bool operator<(const Arc& arc) const {return id < arc.id;}
91 95
    };
92 96

	
93 97

	
94 98

	
95 99
    ListDigraphBase()
96 100
      : nodes(), first_node(-1),
97 101
        first_free_node(-1), arcs(), first_free_arc(-1) {}
98 102

	
99 103

	
100 104
    int maxNodeId() const { return nodes.size()-1; }
101 105
    int maxArcId() const { return arcs.size()-1; }
102 106

	
103 107
    Node source(Arc e) const { return Node(arcs[e.id].source); }
104 108
    Node target(Arc e) const { return Node(arcs[e.id].target); }
105 109

	
106 110

	
107 111
    void first(Node& node) const {
108 112
      node.id = first_node;
109 113
    }
110 114

	
111 115
    void next(Node& node) const {
112 116
      node.id = nodes[node.id].next;
113 117
    }
114 118

	
115 119

	
116 120
    void first(Arc& arc) const {
117 121
      int n;
118 122
      for(n = first_node;
119
          n!=-1 && nodes[n].first_in == -1;
123
          n != -1 && nodes[n].first_out == -1;
120 124
          n = nodes[n].next) {}
121
      arc.id = (n == -1) ? -1 : nodes[n].first_in;
125
      arc.id = (n == -1) ? -1 : nodes[n].first_out;
122 126
    }
123 127

	
124 128
    void next(Arc& arc) const {
125
      if (arcs[arc.id].next_in != -1) {
126
        arc.id = arcs[arc.id].next_in;
129
      if (arcs[arc.id].next_out != -1) {
130
        arc.id = arcs[arc.id].next_out;
127 131
      } else {
128 132
        int n;
129
        for(n = nodes[arcs[arc.id].target].next;
130
            n!=-1 && nodes[n].first_in == -1;
133
        for(n = nodes[arcs[arc.id].source].next;
134
            n != -1 && nodes[n].first_out == -1;
131 135
            n = nodes[n].next) {}
132
        arc.id = (n == -1) ? -1 : nodes[n].first_in;
136
        arc.id = (n == -1) ? -1 : nodes[n].first_out;
133 137
      }
134 138
    }
135 139

	
136 140
    void firstOut(Arc &e, const Node& v) const {
137 141
      e.id = nodes[v.id].first_out;
138 142
    }
139 143
    void nextOut(Arc &e) const {
140 144
      e.id=arcs[e.id].next_out;
141 145
    }
142 146

	
143 147
    void firstIn(Arc &e, const Node& v) const {
144 148
      e.id = nodes[v.id].first_in;
145 149
    }
146 150
    void nextIn(Arc &e) const {
147 151
      e.id=arcs[e.id].next_in;
148 152
    }
149 153

	
150 154

	
151 155
    static int id(Node v) { return v.id; }
152 156
    static int id(Arc e) { return e.id; }
153 157

	
154 158
    static Node nodeFromId(int id) { return Node(id);}
155 159
    static Arc arcFromId(int id) { return Arc(id);}
156 160

	
157 161
    bool valid(Node n) const {
158 162
      return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
159 163
        nodes[n.id].prev != -2;
160 164
    }
161 165

	
162 166
    bool valid(Arc a) const {
163 167
      return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
164 168
        arcs[a.id].prev_in != -2;
165 169
    }
166 170

	
167 171
    Node addNode() {
168 172
      int n;
169 173

	
170 174
      if(first_free_node==-1) {
171 175
        n = nodes.size();
172 176
        nodes.push_back(NodeT());
173 177
      } else {
174 178
        n = first_free_node;
175 179
        first_free_node = nodes[n].next;
176 180
      }
177 181

	
178 182
      nodes[n].next = first_node;
179 183
      if(first_node != -1) nodes[first_node].prev = n;
180 184
      first_node = n;
181 185
      nodes[n].prev = -1;
182 186

	
183 187
      nodes[n].first_in = nodes[n].first_out = -1;
184 188

	
185 189
      return Node(n);
186 190
    }
187 191

	
188 192
    Arc addArc(Node u, Node v) {
189 193
      int n;
190 194

	
191 195
      if (first_free_arc == -1) {
192 196
        n = arcs.size();
193 197
        arcs.push_back(ArcT());
194 198
      } else {
195 199
        n = first_free_arc;
196 200
        first_free_arc = arcs[n].next_in;
... ...
@@ -250,357 +254,364 @@
250 254

	
251 255

	
252 256
      if(arcs[n].next_out!=-1) {
253 257
        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
254 258
      }
255 259

	
256 260
      if(arcs[n].prev_out!=-1) {
257 261
        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
258 262
      } else {
259 263
        nodes[arcs[n].source].first_out = arcs[n].next_out;
260 264
      }
261 265

	
262 266
      arcs[n].next_in = first_free_arc;
263 267
      first_free_arc = n;
264 268
      arcs[n].prev_in = -2;
265 269
    }
266 270

	
267 271
    void clear() {
268 272
      arcs.clear();
269 273
      nodes.clear();
270 274
      first_node = first_free_node = first_free_arc = -1;
271 275
    }
272 276

	
273 277
  protected:
274 278
    void changeTarget(Arc e, Node n)
275 279
    {
276 280
      if(arcs[e.id].next_in != -1)
277 281
        arcs[arcs[e.id].next_in].prev_in = arcs[e.id].prev_in;
278 282
      if(arcs[e.id].prev_in != -1)
279 283
        arcs[arcs[e.id].prev_in].next_in = arcs[e.id].next_in;
280 284
      else nodes[arcs[e.id].target].first_in = arcs[e.id].next_in;
281 285
      if (nodes[n.id].first_in != -1) {
282 286
        arcs[nodes[n.id].first_in].prev_in = e.id;
283 287
      }
284 288
      arcs[e.id].target = n.id;
285 289
      arcs[e.id].prev_in = -1;
286 290
      arcs[e.id].next_in = nodes[n.id].first_in;
287 291
      nodes[n.id].first_in = e.id;
288 292
    }
289 293
    void changeSource(Arc e, Node n)
290 294
    {
291 295
      if(arcs[e.id].next_out != -1)
292 296
        arcs[arcs[e.id].next_out].prev_out = arcs[e.id].prev_out;
293 297
      if(arcs[e.id].prev_out != -1)
294 298
        arcs[arcs[e.id].prev_out].next_out = arcs[e.id].next_out;
295 299
      else nodes[arcs[e.id].source].first_out = arcs[e.id].next_out;
296 300
      if (nodes[n.id].first_out != -1) {
297 301
        arcs[nodes[n.id].first_out].prev_out = e.id;
298 302
      }
299 303
      arcs[e.id].source = n.id;
300 304
      arcs[e.id].prev_out = -1;
301 305
      arcs[e.id].next_out = nodes[n.id].first_out;
302 306
      nodes[n.id].first_out = e.id;
303 307
    }
304 308

	
305 309
  };
306 310

	
307 311
  typedef DigraphExtender<ListDigraphBase> ExtendedListDigraphBase;
308 312

	
309 313
  /// \addtogroup graphs
310 314
  /// @{
311 315

	
312 316
  ///A general directed graph structure.
313 317

	
314
  ///\ref ListDigraph is a simple and fast <em>directed graph</em>
315
  ///implementation based on static linked lists that are stored in
318
  ///\ref ListDigraph is a versatile and fast directed graph
319
  ///implementation based on linked lists that are stored in
316 320
  ///\c std::vector structures.
317 321
  ///
318
  ///It conforms to the \ref concepts::Digraph "Digraph concept" and it
319
  ///also provides several useful additional functionalities.
320
  ///Most of the member functions and nested classes are documented
322
  ///This type fully conforms to the \ref concepts::Digraph "Digraph concept"
323
  ///and it also provides several useful additional functionalities.
324
  ///Most of its member functions and nested classes are documented
321 325
  ///only in the concept class.
322 326
  ///
323 327
  ///\sa concepts::Digraph
324

	
328
  ///\sa ListGraph
325 329
  class ListDigraph : public ExtendedListDigraphBase {
326 330
    typedef ExtendedListDigraphBase Parent;
327 331

	
328 332
  private:
329
    ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
330

	
331
    ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
332
    ///
333
    /// Digraphs are \e not copy constructible. Use DigraphCopy instead.
333 334
    ListDigraph(const ListDigraph &) :ExtendedListDigraphBase() {};
334
    ///\brief Assignment of ListDigraph to another one is \e not allowed.
335
    ///Use copyDigraph() instead.
336

	
337
    ///Assignment of ListDigraph to another one is \e not allowed.
338
    ///Use copyDigraph() instead.
335
    /// \brief Assignment of a digraph to another one is \e not allowed.
336
    /// Use DigraphCopy instead.
339 337
    void operator=(const ListDigraph &) {}
340 338
  public:
341 339

	
342 340
    /// Constructor
343 341

	
344 342
    /// Constructor.
345 343
    ///
346 344
    ListDigraph() {}
347 345

	
348 346
    ///Add a new node to the digraph.
349 347

	
350
    ///Add a new node to the digraph.
348
    ///This function adds a new node to the digraph.
351 349
    ///\return The new node.
352 350
    Node addNode() { return Parent::addNode(); }
353 351

	
354 352
    ///Add a new arc to the digraph.
355 353

	
356
    ///Add a new arc to the digraph with source node \c s
354
    ///This function adds a new arc to the digraph with source node \c s
357 355
    ///and target node \c t.
358 356
    ///\return The new arc.
359
    Arc addArc(const Node& s, const Node& t) {
357
    Arc addArc(Node s, Node t) {
360 358
      return Parent::addArc(s, t);
361 359
    }
362 360

	
363 361
    ///\brief Erase a node from the digraph.
364 362
    ///
365
    ///Erase a node from the digraph.
366
    ///
367
    void erase(const Node& n) { Parent::erase(n); }
363
    ///This function erases the given node from the digraph.
364
    void erase(Node n) { Parent::erase(n); }
368 365

	
369 366
    ///\brief Erase an arc from the digraph.
370 367
    ///
371
    ///Erase an arc from the digraph.
372
    ///
373
    void erase(const Arc& a) { Parent::erase(a); }
368
    ///This function erases the given arc from the digraph.
369
    void erase(Arc a) { Parent::erase(a); }
374 370

	
375 371
    /// Node validity check
376 372

	
377
    /// This function gives back true if the given node is valid,
378
    /// ie. it is a real node of the graph.
373
    /// This function gives back \c true if the given node is valid,
374
    /// i.e. it is a real node of the digraph.
379 375
    ///
380
    /// \warning A Node pointing to a removed item
381
    /// could become valid again later if new nodes are
382
    /// added to the graph.
376
    /// \warning A removed node could become valid again if new nodes are
377
    /// added to the digraph.
383 378
    bool valid(Node n) const { return Parent::valid(n); }
384 379

	
385 380
    /// Arc validity check
386 381

	
387
    /// This function gives back true if the given arc is valid,
388
    /// ie. it is a real arc of the graph.
382
    /// This function gives back \c true if the given arc is valid,
383
    /// i.e. it is a real arc of the digraph.
389 384
    ///
390
    /// \warning An Arc pointing to a removed item
391
    /// could become valid again later if new nodes are
392
    /// added to the graph.
385
    /// \warning A removed arc could become valid again if new arcs are
386
    /// added to the digraph.
393 387
    bool valid(Arc a) const { return Parent::valid(a); }
394 388

	
395
    /// Change the target of \c a to \c n
389
    /// Change the target node of an arc
396 390

	
397
    /// Change the target of \c a to \c n
391
    /// This function changes the target node of the given arc \c a to \c n.
398 392
    ///
399
    ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s referencing
400
    ///the changed arc remain valid. However <tt>InArcIt</tt>s are
401
    ///invalidated.
393
    ///\note \c ArcIt and \c OutArcIt iterators referencing the changed
394
    ///arc remain valid, however \c InArcIt iterators are invalidated.
402 395
    ///
403 396
    ///\warning This functionality cannot be used together with the Snapshot
404 397
    ///feature.
405 398
    void changeTarget(Arc a, Node n) {
406 399
      Parent::changeTarget(a,n);
407 400
    }
408
    /// Change the source of \c a to \c n
401
    /// Change the source node of an arc
409 402

	
410
    /// Change the source of \c a to \c n
403
    /// This function changes the source node of the given arc \c a to \c n.
411 404
    ///
412
    ///\note The <tt>InArcIt</tt>s referencing the changed arc remain
413
    ///valid. However the <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s are
414
    ///invalidated.
405
    ///\note \c InArcIt iterators referencing the changed arc remain
406
    ///valid, however \c ArcIt and \c OutArcIt iterators are invalidated.
415 407
    ///
416 408
    ///\warning This functionality cannot be used together with the Snapshot
417 409
    ///feature.
418 410
    void changeSource(Arc a, Node n) {
419 411
      Parent::changeSource(a,n);
420 412
    }
421 413

	
422
    /// Invert the direction of an arc.
414
    /// Reverse the direction of an arc.
423 415

	
424
    ///\note The <tt>ArcIt</tt>s referencing the changed arc remain
425
    ///valid. However <tt>OutArcIt</tt>s and <tt>InArcIt</tt>s are
426
    ///invalidated.
416
    /// This function reverses the direction of the given arc.
417
    ///\note \c ArcIt, \c OutArcIt and \c InArcIt iterators referencing
418
    ///the changed arc are invalidated.
427 419
    ///
428 420
    ///\warning This functionality cannot be used together with the Snapshot
429 421
    ///feature.
430
    void reverseArc(Arc e) {
431
      Node t=target(e);
432
      changeTarget(e,source(e));
433
      changeSource(e,t);
422
    void reverseArc(Arc a) {
423
      Node t=target(a);
424
      changeTarget(a,source(a));
425
      changeSource(a,t);
434 426
    }
435 427

	
436
    /// Reserve memory for nodes.
437

	
438
    /// Using this function it is possible to avoid the superfluous memory
439
    /// allocation: if you know that the digraph you want to build will
440
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
441
    /// then it is worth reserving space for this amount before starting
442
    /// to build the digraph.
443
    /// \sa reserveArc
444
    void reserveNode(int n) { nodes.reserve(n); };
445

	
446
    /// Reserve memory for arcs.
447

	
448
    /// Using this function it is possible to avoid the superfluous memory
449
    /// allocation: if you know that the digraph you want to build will
450
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
451
    /// then it is worth reserving space for this amount before starting
452
    /// to build the digraph.
453
    /// \sa reserveNode
454
    void reserveArc(int m) { arcs.reserve(m); };
455

	
456 428
    ///Contract two nodes.
457 429

	
458
    ///This function contracts two nodes.
459
    ///Node \p b will be removed but instead of deleting
460
    ///incident arcs, they will be joined to \p a.
461
    ///The last parameter \p r controls whether to remove loops. \c true
462
    ///means that loops will be removed.
430
    ///This function contracts the given two nodes.
431
    ///Node \c v is removed, but instead of deleting its
432
    ///incident arcs, they are joined to node \c u.
433
    ///If the last parameter \c r is \c true (this is the default value),
434
    ///then the newly created loops are removed.
463 435
    ///
464
    ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
465
    ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s
466
    ///may be invalidated.
436
    ///\note The moved arcs are joined to node \c u using changeSource()
437
    ///or changeTarget(), thus \c ArcIt and \c OutArcIt iterators are
438
    ///invalidated for the outgoing arcs of node \c v and \c InArcIt
439
    ///iterators are invalidated for the incomming arcs of \c v.
440
    ///Moreover all iterators referencing node \c v or the removed 
441
    ///loops are also invalidated. Other iterators remain valid.
467 442
    ///
468 443
    ///\warning This functionality cannot be used together with the Snapshot
469 444
    ///feature.
470
    void contract(Node a, Node b, bool r = true)
445
    void contract(Node u, Node v, bool r = true)
471 446
    {
472
      for(OutArcIt e(*this,b);e!=INVALID;) {
447
      for(OutArcIt e(*this,v);e!=INVALID;) {
473 448
        OutArcIt f=e;
474 449
        ++f;
475
        if(r && target(e)==a) erase(e);
476
        else changeSource(e,a);
450
        if(r && target(e)==u) erase(e);
451
        else changeSource(e,u);
477 452
        e=f;
478 453
      }
479
      for(InArcIt e(*this,b);e!=INVALID;) {
454
      for(InArcIt e(*this,v);e!=INVALID;) {
480 455
        InArcIt f=e;
481 456
        ++f;
482
        if(r && source(e)==a) erase(e);
483
        else changeTarget(e,a);
457
        if(r && source(e)==u) erase(e);
458
        else changeTarget(e,u);
484 459
        e=f;
485 460
      }
486
      erase(b);
461
      erase(v);
487 462
    }
488 463

	
489 464
    ///Split a node.
490 465

	
491
    ///This function splits a node. First a new node is added to the digraph,
492
    ///then the source of each outgoing arc of \c n is moved to this new node.
493
    ///If \c connect is \c true (this is the default value), then a new arc
494
    ///from \c n to the newly created node is also added.
466
    ///This function splits the given node. First, a new node is added
467
    ///to the digraph, then the source of each outgoing arc of node \c n
468
    ///is moved to this new node.
469
    ///If the second parameter \c connect is \c true (this is the default
470
    ///value), then a new arc from node \c n to the newly created node
471
    ///is also added.
495 472
    ///\return The newly created node.
496 473
    ///
497
    ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
498
    ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s may
499
    ///be invalidated.
474
    ///\note All iterators remain valid.
500 475
    ///
501
    ///\warning This functionality cannot be used in conjunction with the
476
    ///\warning This functionality cannot be used together with the
502 477
    ///Snapshot feature.
503 478
    Node split(Node n, bool connect = true) {
504 479
      Node b = addNode();
505
      for(OutArcIt e(*this,n);e!=INVALID;) {
506
        OutArcIt f=e;
507
        ++f;
508
        changeSource(e,b);
509
        e=f;
480
      nodes[b.id].first_out=nodes[n.id].first_out;
481
      nodes[n.id].first_out=-1;
482
      for(int i=nodes[b.id].first_out; i!=-1; i=arcs[i].next_out) {
483
        arcs[i].source=b.id;
510 484
      }
511 485
      if (connect) addArc(n,b);
512 486
      return b;
513 487
    }
514 488

	
515 489
    ///Split an arc.
516 490

	
517
    ///This function splits an arc. First a new node \c b is added to
518
    ///the digraph, then the original arc is re-targeted to \c
519
    ///b. Finally an arc from \c b to the original target is added.
491
    ///This function splits the given arc. First, a new node \c v is
492
    ///added to the digraph, then the target node of the original arc
493
    ///is set to \c v. Finally, an arc from \c v to the original target
494
    ///is added.
495
    ///\return The newly created node.
520 496
    ///
521
    ///\return The newly created node.
497
    ///\note \c InArcIt iterators referencing the original arc are
498
    ///invalidated. Other iterators remain valid.
522 499
    ///
523 500
    ///\warning This functionality cannot be used together with the
524 501
    ///Snapshot feature.
525
    Node split(Arc e) {
526
      Node b = addNode();
527
      addArc(b,target(e));
528
      changeTarget(e,b);
529
      return b;
502
    Node split(Arc a) {
503
      Node v = addNode();
504
      addArc(v,target(a));
505
      changeTarget(a,v);
506
      return v;
530 507
    }
531 508

	
509
    ///Clear the digraph.
510

	
511
    ///This function erases all nodes and arcs from the digraph.
512
    ///
513
    void clear() {
514
      Parent::clear();
515
    }
516

	
517
    /// Reserve memory for nodes.
518

	
519
    /// Using this function, it is possible to avoid superfluous memory
520
    /// allocation: if you know that the digraph you want to build will
521
    /// be large (e.g. it will contain millions of nodes and/or arcs),
522
    /// then it is worth reserving space for this amount before starting
523
    /// to build the digraph.
524
    /// \sa reserveArc()
525
    void reserveNode(int n) { nodes.reserve(n); };
526

	
527
    /// Reserve memory for arcs.
528

	
529
    /// Using this function, it is possible to avoid superfluous memory
530
    /// allocation: if you know that the digraph you want to build will
531
    /// be large (e.g. it will contain millions of nodes and/or arcs),
532
    /// then it is worth reserving space for this amount before starting
533
    /// to build the digraph.
534
    /// \sa reserveNode()
535
    void reserveArc(int m) { arcs.reserve(m); };
536

	
532 537
    /// \brief Class to make a snapshot of the digraph and restore
533 538
    /// it later.
534 539
    ///
535 540
    /// Class to make a snapshot of the digraph and restore it later.
536 541
    ///
537 542
    /// The newly added nodes and arcs can be removed using the
538 543
    /// restore() function.
539 544
    ///
540
    /// \warning Arc and node deletions and other modifications (e.g.
541
    /// contracting, splitting, reversing arcs or nodes) cannot be
545
    /// \note After a state is restored, you cannot restore a later state, 
546
    /// i.e. you cannot add the removed nodes and arcs again using
547
    /// another Snapshot instance.
548
    ///
549
    /// \warning Node and arc deletions and other modifications (e.g.
550
    /// reversing, contracting, splitting arcs or nodes) cannot be
542 551
    /// restored. These events invalidate the snapshot.
552
    /// However the arcs and nodes that were added to the digraph after
553
    /// making the current snapshot can be removed without invalidating it.
543 554
    class Snapshot {
544 555
    protected:
545 556

	
546 557
      typedef Parent::NodeNotifier NodeNotifier;
547 558

	
548 559
      class NodeObserverProxy : public NodeNotifier::ObserverBase {
549 560
      public:
550 561

	
551 562
        NodeObserverProxy(Snapshot& _snapshot)
552 563
          : snapshot(_snapshot) {}
553 564

	
554 565
        using NodeNotifier::ObserverBase::attach;
555 566
        using NodeNotifier::ObserverBase::detach;
556 567
        using NodeNotifier::ObserverBase::attached;
557 568

	
558 569
      protected:
559 570

	
560 571
        virtual void add(const Node& node) {
561 572
          snapshot.addNode(node);
562 573
        }
563 574
        virtual void add(const std::vector<Node>& nodes) {
564 575
          for (int i = nodes.size() - 1; i >= 0; ++i) {
565 576
            snapshot.addNode(nodes[i]);
566 577
          }
567 578
        }
568 579
        virtual void erase(const Node& node) {
569 580
          snapshot.eraseNode(node);
570 581
        }
571 582
        virtual void erase(const std::vector<Node>& nodes) {
572 583
          for (int i = 0; i < int(nodes.size()); ++i) {
573 584
            snapshot.eraseNode(nodes[i]);
574 585
          }
575 586
        }
576 587
        virtual void build() {
577 588
          Node node;
578 589
          std::vector<Node> nodes;
579 590
          for (notifier()->first(node); node != INVALID;
580 591
               notifier()->next(node)) {
581 592
            nodes.push_back(node);
582 593
          }
583 594
          for (int i = nodes.size() - 1; i >= 0; --i) {
584 595
            snapshot.addNode(nodes[i]);
585 596
          }
586 597
        }
587 598
        virtual void clear() {
588 599
          Node node;
589 600
          for (notifier()->first(node); node != INVALID;
590 601
               notifier()->next(node)) {
591 602
            snapshot.eraseNode(node);
592 603
          }
593 604
        }
594 605

	
595 606
        Snapshot& snapshot;
596 607
      };
597 608

	
598 609
      class ArcObserverProxy : public ArcNotifier::ObserverBase {
599 610
      public:
600 611

	
601 612
        ArcObserverProxy(Snapshot& _snapshot)
602 613
          : snapshot(_snapshot) {}
603 614

	
604 615
        using ArcNotifier::ObserverBase::attach;
605 616
        using ArcNotifier::ObserverBase::detach;
606 617
        using ArcNotifier::ObserverBase::attached;
... ...
@@ -648,269 +659,264 @@
648 659
      ListDigraph *digraph;
649 660

	
650 661
      NodeObserverProxy node_observer_proxy;
651 662
      ArcObserverProxy arc_observer_proxy;
652 663

	
653 664
      std::list<Node> added_nodes;
654 665
      std::list<Arc> added_arcs;
655 666

	
656 667

	
657 668
      void addNode(const Node& node) {
658 669
        added_nodes.push_front(node);
659 670
      }
660 671
      void eraseNode(const Node& node) {
661 672
        std::list<Node>::iterator it =
662 673
          std::find(added_nodes.begin(), added_nodes.end(), node);
663 674
        if (it == added_nodes.end()) {
664 675
          clear();
665 676
          arc_observer_proxy.detach();
666 677
          throw NodeNotifier::ImmediateDetach();
667 678
        } else {
668 679
          added_nodes.erase(it);
669 680
        }
670 681
      }
671 682

	
672 683
      void addArc(const Arc& arc) {
673 684
        added_arcs.push_front(arc);
674 685
      }
675 686
      void eraseArc(const Arc& arc) {
676 687
        std::list<Arc>::iterator it =
677 688
          std::find(added_arcs.begin(), added_arcs.end(), arc);
678 689
        if (it == added_arcs.end()) {
679 690
          clear();
680 691
          node_observer_proxy.detach();
681 692
          throw ArcNotifier::ImmediateDetach();
682 693
        } else {
683 694
          added_arcs.erase(it);
684 695
        }
685 696
      }
686 697

	
687 698
      void attach(ListDigraph &_digraph) {
688 699
        digraph = &_digraph;
689 700
        node_observer_proxy.attach(digraph->notifier(Node()));
690 701
        arc_observer_proxy.attach(digraph->notifier(Arc()));
691 702
      }
692 703

	
693 704
      void detach() {
694 705
        node_observer_proxy.detach();
695 706
        arc_observer_proxy.detach();
696 707
      }
697 708

	
698 709
      bool attached() const {
699 710
        return node_observer_proxy.attached();
700 711
      }
701 712

	
702 713
      void clear() {
703 714
        added_nodes.clear();
704 715
        added_arcs.clear();
705 716
      }
706 717

	
707 718
    public:
708 719

	
709 720
      /// \brief Default constructor.
710 721
      ///
711 722
      /// Default constructor.
712
      /// To actually make a snapshot you must call save().
723
      /// You have to call save() to actually make a snapshot.
713 724
      Snapshot()
714 725
        : digraph(0), node_observer_proxy(*this),
715 726
          arc_observer_proxy(*this) {}
716 727

	
717 728
      /// \brief Constructor that immediately makes a snapshot.
718 729
      ///
719
      /// This constructor immediately makes a snapshot of the digraph.
720
      /// \param _digraph The digraph we make a snapshot of.
721
      Snapshot(ListDigraph &_digraph)
730
      /// This constructor immediately makes a snapshot of the given digraph.
731
      Snapshot(ListDigraph &gr)
722 732
        : node_observer_proxy(*this),
723 733
          arc_observer_proxy(*this) {
724
        attach(_digraph);
734
        attach(gr);
725 735
      }
726 736

	
727 737
      /// \brief Make a snapshot.
728 738
      ///
729
      /// Make a snapshot of the digraph.
730
      ///
731
      /// This function can be called more than once. In case of a repeated
739
      /// This function makes a snapshot of the given digraph.
740
      /// It can be called more than once. In case of a repeated
732 741
      /// call, the previous snapshot gets lost.
733
      /// \param _digraph The digraph we make the snapshot of.
734
      void save(ListDigraph &_digraph) {
742
      void save(ListDigraph &gr) {
735 743
        if (attached()) {
736 744
          detach();
737 745
          clear();
738 746
        }
739
        attach(_digraph);
747
        attach(gr);
740 748
      }
741 749

	
742 750
      /// \brief Undo the changes until the last snapshot.
743
      //
744
      /// Undo the changes until the last snapshot created by save().
751
      ///
752
      /// This function undos the changes until the last snapshot
753
      /// created by save() or Snapshot(ListDigraph&).
754
      ///
755
      /// \warning This method invalidates the snapshot, i.e. repeated
756
      /// restoring is not supported unless you call save() again.
745 757
      void restore() {
746 758
        detach();
747 759
        for(std::list<Arc>::iterator it = added_arcs.begin();
748 760
            it != added_arcs.end(); ++it) {
749 761
          digraph->erase(*it);
750 762
        }
751 763
        for(std::list<Node>::iterator it = added_nodes.begin();
752 764
            it != added_nodes.end(); ++it) {
753 765
          digraph->erase(*it);
754 766
        }
755 767
        clear();
756 768
      }
757 769

	
758
      /// \brief Gives back true when the snapshot is valid.
770
      /// \brief Returns \c true if the snapshot is valid.
759 771
      ///
760
      /// Gives back true when the snapshot is valid.
772
      /// This function returns \c true if the snapshot is valid.
761 773
      bool valid() const {
762 774
        return attached();
763 775
      }
764 776
    };
765 777

	
766 778
  };
767 779

	
768 780
  ///@}
769 781

	
770 782
  class ListGraphBase {
771 783

	
772 784
  protected:
773 785

	
774 786
    struct NodeT {
775 787
      int first_out;
776 788
      int prev, next;
777 789
    };
778 790

	
779 791
    struct ArcT {
780 792
      int target;
781 793
      int prev_out, next_out;
782 794
    };
783 795

	
784 796
    std::vector<NodeT> nodes;
785 797

	
786 798
    int first_node;
787 799

	
788 800
    int first_free_node;
789 801

	
790 802
    std::vector<ArcT> arcs;
791 803

	
792 804
    int first_free_arc;
793 805

	
794 806
  public:
795 807

	
796 808
    typedef ListGraphBase Graph;
797 809

	
798
    class Node;
799
    class Arc;
800
    class Edge;
801

	
802 810
    class Node {
803 811
      friend class ListGraphBase;
804 812
    protected:
805 813

	
806 814
      int id;
807 815
      explicit Node(int pid) { id = pid;}
808 816

	
809 817
    public:
810 818
      Node() {}
811 819
      Node (Invalid) { id = -1; }
812 820
      bool operator==(const Node& node) const {return id == node.id;}
813 821
      bool operator!=(const Node& node) const {return id != node.id;}
814 822
      bool operator<(const Node& node) const {return id < node.id;}
815 823
    };
816 824

	
817 825
    class Edge {
818 826
      friend class ListGraphBase;
819 827
    protected:
820 828

	
821 829
      int id;
822 830
      explicit Edge(int pid) { id = pid;}
823 831

	
824 832
    public:
825 833
      Edge() {}
826 834
      Edge (Invalid) { id = -1; }
827 835
      bool operator==(const Edge& edge) const {return id == edge.id;}
828 836
      bool operator!=(const Edge& edge) const {return id != edge.id;}
829 837
      bool operator<(const Edge& edge) const {return id < edge.id;}
830 838
    };
831 839

	
832 840
    class Arc {
833 841
      friend class ListGraphBase;
834 842
    protected:
835 843

	
836 844
      int id;
837 845
      explicit Arc(int pid) { id = pid;}
838 846

	
839 847
    public:
840 848
      operator Edge() const {
841 849
        return id != -1 ? edgeFromId(id / 2) : INVALID;
842 850
      }
843 851

	
844 852
      Arc() {}
845 853
      Arc (Invalid) { id = -1; }
846 854
      bool operator==(const Arc& arc) const {return id == arc.id;}
847 855
      bool operator!=(const Arc& arc) const {return id != arc.id;}
848 856
      bool operator<(const Arc& arc) const {return id < arc.id;}
849 857
    };
850 858

	
851

	
852

	
853 859
    ListGraphBase()
854 860
      : nodes(), first_node(-1),
855 861
        first_free_node(-1), arcs(), first_free_arc(-1) {}
856 862

	
857 863

	
858 864
    int maxNodeId() const { return nodes.size()-1; }
859 865
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
860 866
    int maxArcId() const { return arcs.size()-1; }
861 867

	
862 868
    Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); }
863 869
    Node target(Arc e) const { return Node(arcs[e.id].target); }
864 870

	
865 871
    Node u(Edge e) const { return Node(arcs[2 * e.id].target); }
866 872
    Node v(Edge e) const { return Node(arcs[2 * e.id + 1].target); }
867 873

	
868 874
    static bool direction(Arc e) {
869 875
      return (e.id & 1) == 1;
870 876
    }
871 877

	
872 878
    static Arc direct(Edge e, bool d) {
873 879
      return Arc(e.id * 2 + (d ? 1 : 0));
874 880
    }
875 881

	
876 882
    void first(Node& node) const {
877 883
      node.id = first_node;
878 884
    }
879 885

	
880 886
    void next(Node& node) const {
881 887
      node.id = nodes[node.id].next;
882 888
    }
883 889

	
884 890
    void first(Arc& e) const {
885 891
      int n = first_node;
886 892
      while (n != -1 && nodes[n].first_out == -1) {
887 893
        n = nodes[n].next;
888 894
      }
889 895
      e.id = (n == -1) ? -1 : nodes[n].first_out;
890 896
    }
891 897

	
892 898
    void next(Arc& e) const {
893 899
      if (arcs[e.id].next_out != -1) {
894 900
        e.id = arcs[e.id].next_out;
895 901
      } else {
896 902
        int n = nodes[arcs[e.id ^ 1].target].next;
897 903
        while(n != -1 && nodes[n].first_out == -1) {
898 904
          n = nodes[n].next;
899 905
        }
900 906
        e.id = (n == -1) ? -1 : nodes[n].first_out;
901 907
      }
902 908
    }
903 909

	
904 910
    void first(Edge& e) const {
905 911
      int n = first_node;
906 912
      while (n != -1) {
907 913
        e.id = nodes[n].first_out;
908 914
        while ((e.id & 1) != 1) {
909 915
          e.id = arcs[e.id].next_out;
910 916
        }
911 917
        if (e.id != -1) {
912 918
          e.id /= 2;
913 919
          return;
914 920
        }
915 921
        n = nodes[n].next;
916 922
      }
... ...
@@ -1103,283 +1109,311 @@
1103 1109

	
1104 1110
    }
1105 1111

	
1106 1112
    void clear() {
1107 1113
      arcs.clear();
1108 1114
      nodes.clear();
1109 1115
      first_node = first_free_node = first_free_arc = -1;
1110 1116
    }
1111 1117

	
1112 1118
  protected:
1113 1119

	
1114 1120
    void changeV(Edge e, Node n) {
1115 1121
      if(arcs[2 * e.id].next_out != -1) {
1116 1122
        arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out;
1117 1123
      }
1118 1124
      if(arcs[2 * e.id].prev_out != -1) {
1119 1125
        arcs[arcs[2 * e.id].prev_out].next_out =
1120 1126
          arcs[2 * e.id].next_out;
1121 1127
      } else {
1122 1128
        nodes[arcs[(2 * e.id) | 1].target].first_out =
1123 1129
          arcs[2 * e.id].next_out;
1124 1130
      }
1125 1131

	
1126 1132
      if (nodes[n.id].first_out != -1) {
1127 1133
        arcs[nodes[n.id].first_out].prev_out = 2 * e.id;
1128 1134
      }
1129 1135
      arcs[(2 * e.id) | 1].target = n.id;
1130 1136
      arcs[2 * e.id].prev_out = -1;
1131 1137
      arcs[2 * e.id].next_out = nodes[n.id].first_out;
1132 1138
      nodes[n.id].first_out = 2 * e.id;
1133 1139
    }
1134 1140

	
1135 1141
    void changeU(Edge e, Node n) {
1136 1142
      if(arcs[(2 * e.id) | 1].next_out != -1) {
1137 1143
        arcs[arcs[(2 * e.id) | 1].next_out].prev_out =
1138 1144
          arcs[(2 * e.id) | 1].prev_out;
1139 1145
      }
1140 1146
      if(arcs[(2 * e.id) | 1].prev_out != -1) {
1141 1147
        arcs[arcs[(2 * e.id) | 1].prev_out].next_out =
1142 1148
          arcs[(2 * e.id) | 1].next_out;
1143 1149
      } else {
1144 1150
        nodes[arcs[2 * e.id].target].first_out =
1145 1151
          arcs[(2 * e.id) | 1].next_out;
1146 1152
      }
1147 1153

	
1148 1154
      if (nodes[n.id].first_out != -1) {
1149 1155
        arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
1150 1156
      }
1151 1157
      arcs[2 * e.id].target = n.id;
1152 1158
      arcs[(2 * e.id) | 1].prev_out = -1;
1153 1159
      arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out;
1154 1160
      nodes[n.id].first_out = ((2 * e.id) | 1);
1155 1161
    }
1156 1162

	
1157 1163
  };
1158 1164

	
1159 1165
  typedef GraphExtender<ListGraphBase> ExtendedListGraphBase;
1160 1166

	
1161 1167

	
1162 1168
  /// \addtogroup graphs
1163 1169
  /// @{
1164 1170

	
1165 1171
  ///A general undirected graph structure.
1166 1172

	
1167
  ///\ref ListGraph is a simple and fast <em>undirected graph</em>
1168
  ///implementation based on static linked lists that are stored in
1173
  ///\ref ListGraph is a versatile and fast undirected graph
1174
  ///implementation based on linked lists that are stored in
1169 1175
  ///\c std::vector structures.
1170 1176
  ///
1171
  ///It conforms to the \ref concepts::Graph "Graph concept" and it
1172
  ///also provides several useful additional functionalities.
1173
  ///Most of the member functions and nested classes are documented
1177
  ///This type fully conforms to the \ref concepts::Graph "Graph concept"
1178
  ///and it also provides several useful additional functionalities.
1179
  ///Most of its member functions and nested classes are documented
1174 1180
  ///only in the concept class.
1175 1181
  ///
1176 1182
  ///\sa concepts::Graph
1177

	
1183
  ///\sa ListDigraph
1178 1184
  class ListGraph : public ExtendedListGraphBase {
1179 1185
    typedef ExtendedListGraphBase Parent;
1180 1186

	
1181 1187
  private:
1182
    ///ListGraph is \e not copy constructible. Use copyGraph() instead.
1183

	
1184
    ///ListGraph is \e not copy constructible. Use copyGraph() instead.
1185
    ///
1188
    /// Graphs are \e not copy constructible. Use GraphCopy instead.
1186 1189
    ListGraph(const ListGraph &) :ExtendedListGraphBase()  {};
1187
    ///\brief Assignment of ListGraph to another one is \e not allowed.
1188
    ///Use copyGraph() instead.
1189

	
1190
    ///Assignment of ListGraph to another one is \e not allowed.
1191
    ///Use copyGraph() instead.
1190
    /// \brief Assignment of a graph to another one is \e not allowed.
1191
    /// Use GraphCopy instead.
1192 1192
    void operator=(const ListGraph &) {}
1193 1193
  public:
1194 1194
    /// Constructor
1195 1195

	
1196 1196
    /// Constructor.
1197 1197
    ///
1198 1198
    ListGraph() {}
1199 1199

	
1200 1200
    typedef Parent::OutArcIt IncEdgeIt;
1201 1201

	
1202 1202
    /// \brief Add a new node to the graph.
1203 1203
    ///
1204
    /// Add a new node to the graph.
1204
    /// This function adds a new node to the graph.
1205 1205
    /// \return The new node.
1206 1206
    Node addNode() { return Parent::addNode(); }
1207 1207

	
1208 1208
    /// \brief Add a new edge to the graph.
1209 1209
    ///
1210
    /// Add a new edge to the graph with source node \c s
1211
    /// and target node \c t.
1210
    /// This function adds a new edge to the graph between nodes
1211
    /// \c u and \c v with inherent orientation from node \c u to
1212
    /// node \c v.
1212 1213
    /// \return The new edge.
1213
    Edge addEdge(const Node& s, const Node& t) {
1214
      return Parent::addEdge(s, t);
1214
    Edge addEdge(Node u, Node v) {
1215
      return Parent::addEdge(u, v);
1215 1216
    }
1216 1217

	
1217
    /// \brief Erase a node from the graph.
1218
    ///\brief Erase a node from the graph.
1218 1219
    ///
1219
    /// Erase a node from the graph.
1220
    /// This function erases the given node from the graph.
1221
    void erase(Node n) { Parent::erase(n); }
1222

	
1223
    ///\brief Erase an edge from the graph.
1220 1224
    ///
1221
    void erase(const Node& n) { Parent::erase(n); }
1222

	
1223
    /// \brief Erase an edge from the graph.
1224
    ///
1225
    /// Erase an edge from the graph.
1226
    ///
1227
    void erase(const Edge& e) { Parent::erase(e); }
1225
    /// This function erases the given edge from the graph.
1226
    void erase(Edge e) { Parent::erase(e); }
1228 1227
    /// Node validity check
1229 1228

	
1230
    /// This function gives back true if the given node is valid,
1231
    /// ie. it is a real node of the graph.
1229
    /// This function gives back \c true if the given node is valid,
1230
    /// i.e. it is a real node of the graph.
1232 1231
    ///
1233
    /// \warning A Node pointing to a removed item
1234
    /// could become valid again later if new nodes are
1232
    /// \warning A removed node could become valid again if new nodes are
1235 1233
    /// added to the graph.
1236 1234
    bool valid(Node n) const { return Parent::valid(n); }
1235
    /// Edge validity check
1236

	
1237
    /// This function gives back \c true if the given edge is valid,
1238
    /// i.e. it is a real edge of the graph.
1239
    ///
1240
    /// \warning A removed edge could become valid again if new edges are
1241
    /// added to the graph.
1242
    bool valid(Edge e) const { return Parent::valid(e); }
1237 1243
    /// Arc validity check
1238 1244

	
1239
    /// This function gives back true if the given arc is valid,
1240
    /// ie. it is a real arc of the graph.
1245
    /// This function gives back \c true if the given arc is valid,
1246
    /// i.e. it is a real arc of the graph.
1241 1247
    ///
1242
    /// \warning An Arc pointing to a removed item
1243
    /// could become valid again later if new edges are
1248
    /// \warning A removed arc could become valid again if new edges are
1244 1249
    /// added to the graph.
1245 1250
    bool valid(Arc a) const { return Parent::valid(a); }
1246
    /// Edge validity check
1247 1251

	
1248
    /// This function gives back true if the given edge is valid,
1249
    /// ie. it is a real arc of the graph.
1252
    /// \brief Change the first node of an edge.
1250 1253
    ///
1251
    /// \warning A Edge pointing to a removed item
1252
    /// could become valid again later if new edges are
1253
    /// added to the graph.
1254
    bool valid(Edge e) const { return Parent::valid(e); }
1255
    /// \brief Change the end \c u of \c e to \c n
1254
    /// This function changes the first node of the given edge \c e to \c n.
1256 1255
    ///
1257
    /// This function changes the end \c u of \c e to node \c n.
1258
    ///
1259
    ///\note The <tt>EdgeIt</tt>s and <tt>ArcIt</tt>s referencing the
1260
    ///changed edge are invalidated and if the changed node is the
1261
    ///base node of an iterator then this iterator is also
1262
    ///invalidated.
1256
    ///\note \c EdgeIt and \c ArcIt iterators referencing the
1257
    ///changed edge are invalidated and all other iterators whose
1258
    ///base node is the changed node are also invalidated.
1263 1259
    ///
1264 1260
    ///\warning This functionality cannot be used together with the
1265 1261
    ///Snapshot feature.
1266 1262
    void changeU(Edge e, Node n) {
1267 1263
      Parent::changeU(e,n);
1268 1264
    }
1269
    /// \brief Change the end \c v of \c e to \c n
1265
    /// \brief Change the second node of an edge.
1270 1266
    ///
1271
    /// This function changes the end \c v of \c e to \c n.
1267
    /// This function changes the second node of the given edge \c e to \c n.
1272 1268
    ///
1273
    ///\note The <tt>EdgeIt</tt>s referencing the changed edge remain
1274
    ///valid, however <tt>ArcIt</tt>s and if the changed node is the
1275
    ///base node of an iterator then this iterator is invalidated.
1269
    ///\note \c EdgeIt iterators referencing the changed edge remain
1270
    ///valid, however \c ArcIt iterators referencing the changed edge and
1271
    ///all other iterators whose base node is the changed node are also
1272
    ///invalidated.
1276 1273
    ///
1277 1274
    ///\warning This functionality cannot be used together with the
1278 1275
    ///Snapshot feature.
1279 1276
    void changeV(Edge e, Node n) {
1280 1277
      Parent::changeV(e,n);
1281 1278
    }
1279

	
1282 1280
    /// \brief Contract two nodes.
1283 1281
    ///
1284
    /// This function contracts two nodes.
1285
    /// Node \p b will be removed but instead of deleting
1286
    /// its neighboring arcs, they will be joined to \p a.
1287
    /// The last parameter \p r controls whether to remove loops. \c true
1288
    /// means that loops will be removed.
1282
    /// This function contracts the given two nodes.
1283
    /// Node \c b is removed, but instead of deleting
1284
    /// its incident edges, they are joined to node \c a.
1285
    /// If the last parameter \c r is \c true (this is the default value),
1286
    /// then the newly created loops are removed.
1289 1287
    ///
1290
    /// \note The <tt>ArcIt</tt>s referencing a moved arc remain
1291
    /// valid.
1288
    /// \note The moved edges are joined to node \c a using changeU()
1289
    /// or changeV(), thus all edge and arc iterators whose base node is
1290
    /// \c b are invalidated.
1291
    /// Moreover all iterators referencing node \c b or the removed 
1292
    /// loops are also invalidated. Other iterators remain valid.
1292 1293
    ///
1293 1294
    ///\warning This functionality cannot be used together with the
1294 1295
    ///Snapshot feature.
1295 1296
    void contract(Node a, Node b, bool r = true) {
1296 1297
      for(IncEdgeIt e(*this, b); e!=INVALID;) {
1297 1298
        IncEdgeIt f = e; ++f;
1298 1299
        if (r && runningNode(e) == a) {
1299 1300
          erase(e);
1300 1301
        } else if (u(e) == b) {
1301 1302
          changeU(e, a);
1302 1303
        } else {
1303 1304
          changeV(e, a);
1304 1305
        }
1305 1306
        e = f;
1306 1307
      }
1307 1308
      erase(b);
1308 1309
    }
1309 1310

	
1311
    ///Clear the graph.
1312

	
1313
    ///This function erases all nodes and arcs from the graph.
1314
    ///
1315
    void clear() {
1316
      Parent::clear();
1317
    }
1318

	
1319
    /// Reserve memory for nodes.
1320

	
1321
    /// Using this function, it is possible to avoid superfluous memory
1322
    /// allocation: if you know that the graph you want to build will
1323
    /// be large (e.g. it will contain millions of nodes and/or edges),
1324
    /// then it is worth reserving space for this amount before starting
1325
    /// to build the graph.
1326
    /// \sa reserveEdge()
1327
    void reserveNode(int n) { nodes.reserve(n); };
1328

	
1329
    /// Reserve memory for edges.
1330

	
1331
    /// Using this function, it is possible to avoid superfluous memory
1332
    /// allocation: if you know that the graph you want to build will
1333
    /// be large (e.g. it will contain millions of nodes and/or edges),
1334
    /// then it is worth reserving space for this amount before starting
1335
    /// to build the graph.
1336
    /// \sa reserveNode()
1337
    void reserveEdge(int m) { arcs.reserve(2 * m); };
1310 1338

	
1311 1339
    /// \brief Class to make a snapshot of the graph and restore
1312 1340
    /// it later.
1313 1341
    ///
1314 1342
    /// Class to make a snapshot of the graph and restore it later.
1315 1343
    ///
1316 1344
    /// The newly added nodes and edges can be removed
1317 1345
    /// using the restore() function.
1318 1346
    ///
1319
    /// \warning Edge and node deletions and other modifications
1320
    /// (e.g. changing nodes of edges, contracting nodes) cannot be
1321
    /// restored. These events invalidate the snapshot.
1347
    /// \note After a state is restored, you cannot restore a later state, 
1348
    /// i.e. you cannot add the removed nodes and edges again using
1349
    /// another Snapshot instance.
1350
    ///
1351
    /// \warning Node and edge deletions and other modifications
1352
    /// (e.g. changing the end-nodes of edges or contracting nodes)
1353
    /// cannot be restored. These events invalidate the snapshot.
1354
    /// However the edges and nodes that were added to the graph after
1355
    /// making the current snapshot can be removed without invalidating it.
1322 1356
    class Snapshot {
1323 1357
    protected:
1324 1358

	
1325 1359
      typedef Parent::NodeNotifier NodeNotifier;
1326 1360

	
1327 1361
      class NodeObserverProxy : public NodeNotifier::ObserverBase {
1328 1362
      public:
1329 1363

	
1330 1364
        NodeObserverProxy(Snapshot& _snapshot)
1331 1365
          : snapshot(_snapshot) {}
1332 1366

	
1333 1367
        using NodeNotifier::ObserverBase::attach;
1334 1368
        using NodeNotifier::ObserverBase::detach;
1335 1369
        using NodeNotifier::ObserverBase::attached;
1336 1370

	
1337 1371
      protected:
1338 1372

	
1339 1373
        virtual void add(const Node& node) {
1340 1374
          snapshot.addNode(node);
1341 1375
        }
1342 1376
        virtual void add(const std::vector<Node>& nodes) {
1343 1377
          for (int i = nodes.size() - 1; i >= 0; ++i) {
1344 1378
            snapshot.addNode(nodes[i]);
1345 1379
          }
1346 1380
        }
1347 1381
        virtual void erase(const Node& node) {
1348 1382
          snapshot.eraseNode(node);
1349 1383
        }
1350 1384
        virtual void erase(const std::vector<Node>& nodes) {
1351 1385
          for (int i = 0; i < int(nodes.size()); ++i) {
1352 1386
            snapshot.eraseNode(nodes[i]);
1353 1387
          }
1354 1388
        }
1355 1389
        virtual void build() {
1356 1390
          Node node;
1357 1391
          std::vector<Node> nodes;
1358 1392
          for (notifier()->first(node); node != INVALID;
1359 1393
               notifier()->next(node)) {
1360 1394
            nodes.push_back(node);
1361 1395
          }
1362 1396
          for (int i = nodes.size() - 1; i >= 0; --i) {
1363 1397
            snapshot.addNode(nodes[i]);
1364 1398
          }
1365 1399
        }
1366 1400
        virtual void clear() {
1367 1401
          Node node;
1368 1402
          for (notifier()->first(node); node != INVALID;
1369 1403
               notifier()->next(node)) {
1370 1404
            snapshot.eraseNode(node);
1371 1405
          }
1372 1406
        }
1373 1407

	
1374 1408
        Snapshot& snapshot;
1375 1409
      };
1376 1410

	
1377 1411
      class EdgeObserverProxy : public EdgeNotifier::ObserverBase {
1378 1412
      public:
1379 1413

	
1380 1414
        EdgeObserverProxy(Snapshot& _snapshot)
1381 1415
          : snapshot(_snapshot) {}
1382 1416

	
1383 1417
        using EdgeNotifier::ObserverBase::attach;
1384 1418
        using EdgeNotifier::ObserverBase::detach;
1385 1419
        using EdgeNotifier::ObserverBase::attached;
... ...
@@ -1427,124 +1461,125 @@
1427 1461
      ListGraph *graph;
1428 1462

	
1429 1463
      NodeObserverProxy node_observer_proxy;
1430 1464
      EdgeObserverProxy edge_observer_proxy;
1431 1465

	
1432 1466
      std::list<Node> added_nodes;
1433 1467
      std::list<Edge> added_edges;
1434 1468

	
1435 1469

	
1436 1470
      void addNode(const Node& node) {
1437 1471
        added_nodes.push_front(node);
1438 1472
      }
1439 1473
      void eraseNode(const Node& node) {
1440 1474
        std::list<Node>::iterator it =
1441 1475
          std::find(added_nodes.begin(), added_nodes.end(), node);
1442 1476
        if (it == added_nodes.end()) {
1443 1477
          clear();
1444 1478
          edge_observer_proxy.detach();
1445 1479
          throw NodeNotifier::ImmediateDetach();
1446 1480
        } else {
1447 1481
          added_nodes.erase(it);
1448 1482
        }
1449 1483
      }
1450 1484

	
1451 1485
      void addEdge(const Edge& edge) {
1452 1486
        added_edges.push_front(edge);
1453 1487
      }
1454 1488
      void eraseEdge(const Edge& edge) {
1455 1489
        std::list<Edge>::iterator it =
1456 1490
          std::find(added_edges.begin(), added_edges.end(), edge);
1457 1491
        if (it == added_edges.end()) {
1458 1492
          clear();
1459 1493
          node_observer_proxy.detach();
1460 1494
          throw EdgeNotifier::ImmediateDetach();
1461 1495
        } else {
1462 1496
          added_edges.erase(it);
1463 1497
        }
1464 1498
      }
1465 1499

	
1466 1500
      void attach(ListGraph &_graph) {
1467 1501
        graph = &_graph;
1468 1502
        node_observer_proxy.attach(graph->notifier(Node()));
1469 1503
        edge_observer_proxy.attach(graph->notifier(Edge()));
1470 1504
      }
1471 1505

	
1472 1506
      void detach() {
1473 1507
        node_observer_proxy.detach();
1474 1508
        edge_observer_proxy.detach();
1475 1509
      }
1476 1510

	
1477 1511
      bool attached() const {
1478 1512
        return node_observer_proxy.attached();
1479 1513
      }
1480 1514

	
1481 1515
      void clear() {
1482 1516
        added_nodes.clear();
1483 1517
        added_edges.clear();
1484 1518
      }
1485 1519

	
1486 1520
    public:
1487 1521

	
1488 1522
      /// \brief Default constructor.
1489 1523
      ///
1490 1524
      /// Default constructor.
1491
      /// To actually make a snapshot you must call save().
1525
      /// You have to call save() to actually make a snapshot.
1492 1526
      Snapshot()
1493 1527
        : graph(0), node_observer_proxy(*this),
1494 1528
          edge_observer_proxy(*this) {}
1495 1529

	
1496 1530
      /// \brief Constructor that immediately makes a snapshot.
1497 1531
      ///
1498
      /// This constructor immediately makes a snapshot of the graph.
1499
      /// \param _graph The graph we make a snapshot of.
1500
      Snapshot(ListGraph &_graph)
1532
      /// This constructor immediately makes a snapshot of the given graph.
1533
      Snapshot(ListGraph &gr)
1501 1534
        : node_observer_proxy(*this),
1502 1535
          edge_observer_proxy(*this) {
1503
        attach(_graph);
1536
        attach(gr);
1504 1537
      }
1505 1538

	
1506 1539
      /// \brief Make a snapshot.
1507 1540
      ///
1508
      /// Make a snapshot of the graph.
1509
      ///
1510
      /// This function can be called more than once. In case of a repeated
1541
      /// This function makes a snapshot of the given graph.
1542
      /// It can be called more than once. In case of a repeated
1511 1543
      /// call, the previous snapshot gets lost.
1512
      /// \param _graph The graph we make the snapshot of.
1513
      void save(ListGraph &_graph) {
1544
      void save(ListGraph &gr) {
1514 1545
        if (attached()) {
1515 1546
          detach();
1516 1547
          clear();
1517 1548
        }
1518
        attach(_graph);
1549
        attach(gr);
1519 1550
      }
1520 1551

	
1521 1552
      /// \brief Undo the changes until the last snapshot.
1522
      //
1523
      /// Undo the changes until the last snapshot created by save().
1553
      ///
1554
      /// This function undos the changes until the last snapshot
1555
      /// created by save() or Snapshot(ListGraph&).
1556
      ///
1557
      /// \warning This method invalidates the snapshot, i.e. repeated
1558
      /// restoring is not supported unless you call save() again.
1524 1559
      void restore() {
1525 1560
        detach();
1526 1561
        for(std::list<Edge>::iterator it = added_edges.begin();
1527 1562
            it != added_edges.end(); ++it) {
1528 1563
          graph->erase(*it);
1529 1564
        }
1530 1565
        for(std::list<Node>::iterator it = added_nodes.begin();
1531 1566
            it != added_nodes.end(); ++it) {
1532 1567
          graph->erase(*it);
1533 1568
        }
1534 1569
        clear();
1535 1570
      }
1536 1571

	
1537
      /// \brief Gives back true when the snapshot is valid.
1572
      /// \brief Returns \c true if the snapshot is valid.
1538 1573
      ///
1539
      /// Gives back true when the snapshot is valid.
1574
      /// This function returns \c true if the snapshot is valid.
1540 1575
      bool valid() const {
1541 1576
        return attached();
1542 1577
      }
1543 1578
    };
1544 1579
  };
1545 1580

	
1546 1581
  /// @}
1547 1582
} //namespace lemon
1548 1583

	
1549 1584

	
1550 1585
#endif
Ignore white space 6 line context
... ...
@@ -882,128 +882,136 @@
882 882
    class ExprIterator {
883 883
    private:
884 884
      std::map<int, Value>::const_iterator _host_it;
885 885
      const _solver_bits::VarIndex& _index;
886 886
    public:
887 887

	
888 888
      typedef std::bidirectional_iterator_tag iterator_category;
889 889
      typedef std::ptrdiff_t difference_type;
890 890
      typedef const std::pair<int, Value> value_type;
891 891
      typedef value_type reference;
892 892

	
893 893
      class pointer {
894 894
      public:
895 895
        pointer(value_type& _value) : value(_value) {}
896 896
        value_type* operator->() { return &value; }
897 897
      private:
898 898
        value_type value;
899 899
      };
900 900

	
901 901
      ExprIterator(const std::map<int, Value>::const_iterator& host_it,
902 902
                   const _solver_bits::VarIndex& index)
903 903
        : _host_it(host_it), _index(index) {}
904 904

	
905 905
      reference operator*() {
906 906
        return std::make_pair(_index(_host_it->first), _host_it->second);
907 907
      }
908 908

	
909 909
      pointer operator->() {
910 910
        return pointer(operator*());
911 911
      }
912 912

	
913 913
      ExprIterator& operator++() { ++_host_it; return *this; }
914 914
      ExprIterator operator++(int) {
915 915
        ExprIterator tmp(*this); ++_host_it; return tmp;
916 916
      }
917 917

	
918 918
      ExprIterator& operator--() { --_host_it; return *this; }
919 919
      ExprIterator operator--(int) {
920 920
        ExprIterator tmp(*this); --_host_it; return tmp;
921 921
      }
922 922

	
923 923
      bool operator==(const ExprIterator& it) const {
924 924
        return _host_it == it._host_it;
925 925
      }
926 926

	
927 927
      bool operator!=(const ExprIterator& it) const {
928 928
        return _host_it != it._host_it;
929 929
      }
930 930

	
931 931
    };
932 932

	
933 933
  protected:
934 934

	
935 935
    //Abstract virtual functions
936 936

	
937 937
    virtual int _addColId(int col) { return cols.addIndex(col); }
938 938
    virtual int _addRowId(int row) { return rows.addIndex(row); }
939 939

	
940 940
    virtual void _eraseColId(int col) { cols.eraseIndex(col); }
941 941
    virtual void _eraseRowId(int row) { rows.eraseIndex(row); }
942 942

	
943 943
    virtual int _addCol() = 0;
944 944
    virtual int _addRow() = 0;
945 945

	
946
    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
947
      int row = _addRow();
948
      _setRowCoeffs(row, b, e);
949
      _setRowLowerBound(row, l);
950
      _setRowUpperBound(row, u);
951
      return row;
952
    }
953

	
946 954
    virtual void _eraseCol(int col) = 0;
947 955
    virtual void _eraseRow(int row) = 0;
948 956

	
949 957
    virtual void _getColName(int col, std::string& name) const = 0;
950 958
    virtual void _setColName(int col, const std::string& name) = 0;
951 959
    virtual int _colByName(const std::string& name) const = 0;
952 960

	
953 961
    virtual void _getRowName(int row, std::string& name) const = 0;
954 962
    virtual void _setRowName(int row, const std::string& name) = 0;
955 963
    virtual int _rowByName(const std::string& name) const = 0;
956 964

	
957 965
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e) = 0;
958 966
    virtual void _getRowCoeffs(int i, InsertIterator b) const = 0;
959 967

	
960 968
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e) = 0;
961 969
    virtual void _getColCoeffs(int i, InsertIterator b) const = 0;
962 970

	
963 971
    virtual void _setCoeff(int row, int col, Value value) = 0;
964 972
    virtual Value _getCoeff(int row, int col) const = 0;
965 973

	
966 974
    virtual void _setColLowerBound(int i, Value value) = 0;
967 975
    virtual Value _getColLowerBound(int i) const = 0;
968 976

	
969 977
    virtual void _setColUpperBound(int i, Value value) = 0;
970 978
    virtual Value _getColUpperBound(int i) const = 0;
971 979

	
972 980
    virtual void _setRowLowerBound(int i, Value value) = 0;
973 981
    virtual Value _getRowLowerBound(int i) const = 0;
974 982

	
975 983
    virtual void _setRowUpperBound(int i, Value value) = 0;
976 984
    virtual Value _getRowUpperBound(int i) const = 0;
977 985

	
978 986
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e) = 0;
979 987
    virtual void _getObjCoeffs(InsertIterator b) const = 0;
980 988

	
981 989
    virtual void _setObjCoeff(int i, Value obj_coef) = 0;
982 990
    virtual Value _getObjCoeff(int i) const = 0;
983 991

	
984 992
    virtual void _setSense(Sense) = 0;
985 993
    virtual Sense _getSense() const = 0;
986 994

	
987 995
    virtual void _clear() = 0;
988 996

	
989 997
    virtual const char* _solverName() const = 0;
990 998

	
991 999
    virtual void _messageLevel(MessageLevel level) = 0;
992 1000

	
993 1001
    //Own protected stuff
994 1002

	
995 1003
    //Constant component of the objective function
996 1004
    Value obj_const_comp;
997 1005

	
998 1006
    LpBase() : rows(), cols(), obj_const_comp(0) {}
999 1007

	
1000 1008
  public:
1001 1009

	
1002 1010
    /// Virtual destructor
1003 1011
    virtual ~LpBase() {}
1004 1012

	
1005 1013
    ///Gives back the name of the solver.
1006 1014
    const char* solverName() const {return _solverName();}
1007 1015

	
1008 1016
    ///\name Build Up and Modify the LP
1009 1017

	
... ...
@@ -1146,140 +1154,146 @@
1146 1154
    template<class T>
1147 1155
    typename enable_if<typename T::value_type::second_type::LpRow, int>::type
1148 1156
    addRowSet(T &t, dummy<1> = 1) {
1149 1157
      int s=0;
1150 1158
      for(typename T::iterator i=t.begin();i!=t.end();++i) {
1151 1159
        i->second=addRow();
1152 1160
        s++;
1153 1161
      }
1154 1162
      return s;
1155 1163
    }
1156 1164
    template<class T>
1157 1165
    typename enable_if<typename T::MapIt::Value::LpRow, int>::type
1158 1166
    addRowSet(T &t, dummy<2> = 2) {
1159 1167
      int s=0;
1160 1168
      for(typename T::MapIt i(t); i!=INVALID; ++i)
1161 1169
        {
1162 1170
          i.set(addRow());
1163 1171
          s++;
1164 1172
        }
1165 1173
      return s;
1166 1174
    }
1167 1175
#endif
1168 1176

	
1169 1177
    ///Set a row (i.e a constraint) of the LP
1170 1178

	
1171 1179
    ///\param r is the row to be modified
1172 1180
    ///\param l is lower bound (-\ref INF means no bound)
1173 1181
    ///\param e is a linear expression (see \ref Expr)
1174 1182
    ///\param u is the upper bound (\ref INF means no bound)
1175 1183
    void row(Row r, Value l, const Expr &e, Value u) {
1176 1184
      e.simplify();
1177 1185
      _setRowCoeffs(rows(id(r)), ExprIterator(e.comps.begin(), cols),
1178 1186
                    ExprIterator(e.comps.end(), cols));
1179 1187
      _setRowLowerBound(rows(id(r)),l - *e);
1180 1188
      _setRowUpperBound(rows(id(r)),u - *e);
1181 1189
    }
1182 1190

	
1183 1191
    ///Set a row (i.e a constraint) of the LP
1184 1192

	
1185 1193
    ///\param r is the row to be modified
1186 1194
    ///\param c is a linear expression (see \ref Constr)
1187 1195
    void row(Row r, const Constr &c) {
1188 1196
      row(r, c.lowerBounded()?c.lowerBound():-INF,
1189 1197
          c.expr(), c.upperBounded()?c.upperBound():INF);
1190 1198
    }
1191 1199

	
1192 1200

	
1193 1201
    ///Get a row (i.e a constraint) of the LP
1194 1202

	
1195 1203
    ///\param r is the row to get
1196 1204
    ///\return the expression associated to the row
1197 1205
    Expr row(Row r) const {
1198 1206
      Expr e;
1199 1207
      _getRowCoeffs(rows(id(r)), InsertIterator(e.comps, cols));
1200 1208
      return e;
1201 1209
    }
1202 1210

	
1203 1211
    ///Add a new row (i.e a new constraint) to the LP
1204 1212

	
1205 1213
    ///\param l is the lower bound (-\ref INF means no bound)
1206 1214
    ///\param e is a linear expression (see \ref Expr)
1207 1215
    ///\param u is the upper bound (\ref INF means no bound)
1208 1216
    ///\return The created row.
1209 1217
    Row addRow(Value l,const Expr &e, Value u) {
1210
      Row r=addRow();
1211
      row(r,l,e,u);
1218
      Row r;
1219
      e.simplify();
1220
      r._id = _addRowId(_addRow(l - *e, ExprIterator(e.comps.begin(), cols),
1221
                                ExprIterator(e.comps.end(), cols), u - *e));
1212 1222
      return r;
1213 1223
    }
1214 1224

	
1215 1225
    ///Add a new row (i.e a new constraint) to the LP
1216 1226

	
1217 1227
    ///\param c is a linear expression (see \ref Constr)
1218 1228
    ///\return The created row.
1219 1229
    Row addRow(const Constr &c) {
1220
      Row r=addRow();
1221
      row(r,c);
1230
      Row r;
1231
      c.expr().simplify();
1232
      r._id = _addRowId(_addRow(c.lowerBounded()?c.lowerBound():-INF, 
1233
                                ExprIterator(c.expr().comps.begin(), cols),
1234
                                ExprIterator(c.expr().comps.end(), cols),
1235
                                c.upperBounded()?c.upperBound():INF));
1222 1236
      return r;
1223 1237
    }
1224 1238
    ///Erase a column (i.e a variable) from the LP
1225 1239

	
1226 1240
    ///\param c is the column to be deleted
1227 1241
    void erase(Col c) {
1228 1242
      _eraseCol(cols(id(c)));
1229 1243
      _eraseColId(cols(id(c)));
1230 1244
    }
1231 1245
    ///Erase a row (i.e a constraint) from the LP
1232 1246

	
1233 1247
    ///\param r is the row to be deleted
1234 1248
    void erase(Row r) {
1235 1249
      _eraseRow(rows(id(r)));
1236 1250
      _eraseRowId(rows(id(r)));
1237 1251
    }
1238 1252

	
1239 1253
    /// Get the name of a column
1240 1254

	
1241 1255
    ///\param c is the coresponding column
1242 1256
    ///\return The name of the colunm
1243 1257
    std::string colName(Col c) const {
1244 1258
      std::string name;
1245 1259
      _getColName(cols(id(c)), name);
1246 1260
      return name;
1247 1261
    }
1248 1262

	
1249 1263
    /// Set the name of a column
1250 1264

	
1251 1265
    ///\param c is the coresponding column
1252 1266
    ///\param name The name to be given
1253 1267
    void colName(Col c, const std::string& name) {
1254 1268
      _setColName(cols(id(c)), name);
1255 1269
    }
1256 1270

	
1257 1271
    /// Get the column by its name
1258 1272

	
1259 1273
    ///\param name The name of the column
1260 1274
    ///\return the proper column or \c INVALID
1261 1275
    Col colByName(const std::string& name) const {
1262 1276
      int k = _colByName(name);
1263 1277
      return k != -1 ? Col(cols[k]) : Col(INVALID);
1264 1278
    }
1265 1279

	
1266 1280
    /// Get the name of a row
1267 1281

	
1268 1282
    ///\param r is the coresponding row
1269 1283
    ///\return The name of the row
1270 1284
    std::string rowName(Row r) const {
1271 1285
      std::string name;
1272 1286
      _getRowName(rows(id(r)), name);
1273 1287
      return name;
1274 1288
    }
1275 1289

	
1276 1290
    /// Set the name of a row
1277 1291

	
1278 1292
    ///\param r is the coresponding row
1279 1293
    ///\param name The name to be given
1280 1294
    void rowName(Row r, const std::string& name) {
1281 1295
      _setRowName(rows(id(r)), name);
1282 1296
    }
1283 1297

	
1284 1298
    /// Get the row by its name
1285 1299

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

	
19 19
#include <lemon/lp_skeleton.h>
20 20

	
21 21
///\file
22 22
///\brief A skeleton file to implement LP solver interfaces
23 23
namespace lemon {
24 24

	
25 25
  int SkeletonSolverBase::_addCol()
26 26
  {
27 27
    return ++col_num;
28 28
  }
29 29

	
30 30
  int SkeletonSolverBase::_addRow()
31 31
  {
32 32
    return ++row_num;
33 33
  }
34 34

	
35
  int SkeletonSolverBase::_addRow(Value, ExprIterator, ExprIterator, Value)
36
  {
37
    return ++row_num;
38
  }
39

	
35 40
  void SkeletonSolverBase::_eraseCol(int) {}
36 41
  void SkeletonSolverBase::_eraseRow(int) {}
37 42

	
38 43
  void SkeletonSolverBase::_getColName(int, std::string &) const {}
39 44
  void SkeletonSolverBase::_setColName(int, const std::string &) {}
40 45
  int SkeletonSolverBase::_colByName(const std::string&) const { return -1; }
41 46

	
42 47
  void SkeletonSolverBase::_getRowName(int, std::string &) const {}
43 48
  void SkeletonSolverBase::_setRowName(int, const std::string &) {}
44 49
  int SkeletonSolverBase::_rowByName(const std::string&) const { return -1; }
45 50

	
46 51
  void SkeletonSolverBase::_setRowCoeffs(int, ExprIterator, ExprIterator) {}
47 52
  void SkeletonSolverBase::_getRowCoeffs(int, InsertIterator) const {}
48 53

	
49 54
  void SkeletonSolverBase::_setColCoeffs(int, ExprIterator, ExprIterator) {}
50 55
  void SkeletonSolverBase::_getColCoeffs(int, InsertIterator) const {}
51 56

	
52 57
  void SkeletonSolverBase::_setCoeff(int, int, Value) {}
53 58
  SkeletonSolverBase::Value SkeletonSolverBase::_getCoeff(int, int) const
54 59
  { return 0; }
55 60

	
56 61
  void SkeletonSolverBase::_setColLowerBound(int, Value) {}
57 62
  SkeletonSolverBase::Value SkeletonSolverBase::_getColLowerBound(int) const
58 63
  {  return 0; }
59 64

	
60 65
  void SkeletonSolverBase::_setColUpperBound(int, Value) {}
61 66
  SkeletonSolverBase::Value SkeletonSolverBase::_getColUpperBound(int) const
62 67
  {  return 0; }
63 68

	
64 69
  void SkeletonSolverBase::_setRowLowerBound(int, Value) {}
65 70
  SkeletonSolverBase::Value SkeletonSolverBase::_getRowLowerBound(int) const
66 71
  {  return 0; }
67 72

	
68 73
  void SkeletonSolverBase::_setRowUpperBound(int, Value) {}
69 74
  SkeletonSolverBase::Value SkeletonSolverBase::_getRowUpperBound(int) const
70 75
  {  return 0; }
71 76

	
72 77
  void SkeletonSolverBase::_setObjCoeffs(ExprIterator, ExprIterator) {}
73 78
  void SkeletonSolverBase::_getObjCoeffs(InsertIterator) const {};
74 79

	
75 80
  void SkeletonSolverBase::_setObjCoeff(int, Value) {}
76 81
  SkeletonSolverBase::Value SkeletonSolverBase::_getObjCoeff(int) const
77 82
  {  return 0; }
78 83

	
79 84
  void SkeletonSolverBase::_setSense(Sense) {}
80 85
  SkeletonSolverBase::Sense SkeletonSolverBase::_getSense() const
81 86
  { return MIN; }
82 87

	
83 88
  void SkeletonSolverBase::_clear() {
84 89
    row_num = col_num = 0;
85 90
  }
86 91

	
87 92
  void SkeletonSolverBase::_messageLevel(MessageLevel) {}
88 93

	
89 94
  LpSkeleton::SolveExitStatus LpSkeleton::_solve() { return SOLVED; }
90 95

	
91 96
  LpSkeleton::Value LpSkeleton::_getPrimal(int) const { return 0; }
92 97
  LpSkeleton::Value LpSkeleton::_getDual(int) const { return 0; }
93 98
  LpSkeleton::Value LpSkeleton::_getPrimalValue() const { return 0; }
94 99

	
95 100
  LpSkeleton::Value LpSkeleton::_getPrimalRay(int) const { return 0; }
96 101
  LpSkeleton::Value LpSkeleton::_getDualRay(int) const { return 0; }
97 102

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

	
19 19
#ifndef LEMON_LP_SKELETON_H
20 20
#define LEMON_LP_SKELETON_H
21 21

	
22 22
#include <lemon/lp_base.h>
23 23

	
24 24
///\file
25 25
///\brief Skeleton file to implement LP/MIP solver interfaces
26 26
///  
27 27
///The classes in this file do nothing, but they can serve as skeletons when
28 28
///implementing an interface to new solvers.
29 29
namespace lemon {
30 30

	
31 31
  ///A skeleton class to implement LP/MIP solver base interface
32 32
  
33 33
  ///This class does nothing, but it can serve as a skeleton when
34 34
  ///implementing an interface to new solvers.
35 35
  class SkeletonSolverBase : public virtual LpBase {
36 36
    int col_num,row_num;
37 37

	
38 38
  protected:
39 39

	
40 40
    SkeletonSolverBase()
41 41
      : col_num(-1), row_num(-1) {}
42 42

	
43 43
    /// \e
44 44
    virtual int _addCol();
45 45
    /// \e
46 46
    virtual int _addRow();
47 47
    /// \e
48
    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
49
    /// \e
48 50
    virtual void _eraseCol(int i);
49 51
    /// \e
50 52
    virtual void _eraseRow(int i);
51 53

	
52 54
    /// \e
53 55
    virtual void _getColName(int col, std::string& name) const;
54 56
    /// \e
55 57
    virtual void _setColName(int col, const std::string& name);
56 58
    /// \e
57 59
    virtual int _colByName(const std::string& name) const;
58 60

	
59 61
    /// \e
60 62
    virtual void _getRowName(int row, std::string& name) const;
61 63
    /// \e
62 64
    virtual void _setRowName(int row, const std::string& name);
63 65
    /// \e
64 66
    virtual int _rowByName(const std::string& name) const;
65 67

	
66 68
    /// \e
67 69
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
68 70
    /// \e
69 71
    virtual void _getRowCoeffs(int i, InsertIterator b) const;
70 72
    /// \e
71 73
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
72 74
    /// \e
73 75
    virtual void _getColCoeffs(int i, InsertIterator b) const;
74 76

	
75 77
    /// Set one element of the coefficient matrix
76 78
    virtual void _setCoeff(int row, int col, Value value);
77 79

	
78 80
    /// Get one element of the coefficient matrix
79 81
    virtual Value _getCoeff(int row, int col) const;
80 82

	
81 83
    /// The lower bound of a variable (column) have to be given by an
82 84
    /// extended number of type Value, i.e. a finite number of type
83 85
    /// Value or -\ref INF.
84 86
    virtual void _setColLowerBound(int i, Value value);
85 87
    /// \e
86 88

	
87 89
    /// The lower bound of a variable (column) is an
88 90
    /// extended number of type Value, i.e. a finite number of type
89 91
    /// Value or -\ref INF.
90 92
    virtual Value _getColLowerBound(int i) const;
91 93

	
92 94
    /// The upper bound of a variable (column) have to be given by an
93 95
    /// extended number of type Value, i.e. a finite number of type
94 96
    /// Value or \ref INF.
95 97
    virtual void _setColUpperBound(int i, Value value);
96 98
    /// \e
97 99

	
98 100
    /// The upper bound of a variable (column) is an
99 101
    /// extended number of type Value, i.e. a finite number of type
100 102
    /// Value or \ref INF.
101 103
    virtual Value _getColUpperBound(int i) const;
102 104

	
103 105
    /// The lower bound of a constraint (row) have to be given by an
104 106
    /// extended number of type Value, i.e. a finite number of type
105 107
    /// Value or -\ref INF.
106 108
    virtual void _setRowLowerBound(int i, Value value);
107 109
    /// \e
108 110

	
109 111
    /// The lower bound of a constraint (row) is an
110 112
    /// extended number of type Value, i.e. a finite number of type
111 113
    /// Value or -\ref INF.
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_NETWORK_SIMPLEX_H
20 20
#define LEMON_NETWORK_SIMPLEX_H
21 21

	
22 22
/// \ingroup min_cost_flow_algs
23 23
///
24 24
/// \file
25 25
/// \brief Network Simplex algorithm for finding a minimum cost flow.
26 26

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

	
31 31
#include <lemon/core.h>
32 32
#include <lemon/math.h>
33 33

	
34 34
namespace lemon {
35 35

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

	
39 39
  /// \brief Implementation of the primal Network Simplex algorithm
40 40
  /// for finding a \ref min_cost_flow "minimum cost flow".
41 41
  ///
42 42
  /// \ref NetworkSimplex implements the primal Network Simplex algorithm
43
  /// for finding a \ref min_cost_flow "minimum cost flow".
43
  /// for finding a \ref min_cost_flow "minimum cost flow"
44
  /// \ref amo93networkflows, \ref dantzig63linearprog,
45
  /// \ref kellyoneill91netsimplex.
44 46
  /// This algorithm is a specialized version of the linear programming
45 47
  /// simplex method directly for the minimum cost flow problem.
46 48
  /// It is one of the most efficient solution methods.
47 49
  ///
48 50
  /// In general this class is the fastest implementation available
49 51
  /// in LEMON for the minimum cost flow problem.
50 52
  /// Moreover it supports both directions of the supply/demand inequality
51 53
  /// constraints. For more information see \ref SupplyType.
52 54
  ///
53 55
  /// Most of the parameters of the problem (except for the digraph)
54 56
  /// can be given using separate functions, and the algorithm can be
55 57
  /// executed using the \ref run() function. If some parameters are not
56 58
  /// specified, then default values will be used.
57 59
  ///
58 60
  /// \tparam GR The digraph type the algorithm runs on.
59 61
  /// \tparam V The value type used for flow amounts, capacity bounds
60 62
  /// and supply values in the algorithm. By default it is \c int.
61 63
  /// \tparam C The value type used for costs and potentials in the
62 64
  /// algorithm. By default it is the same as \c V.
63 65
  ///
64 66
  /// \warning Both value types must be signed and all input data must
65 67
  /// be integer.
66 68
  ///
67 69
  /// \note %NetworkSimplex provides five different pivot rule
68 70
  /// implementations, from which the most efficient one is used
69 71
  /// by default. For more information see \ref PivotRule.
70 72
  template <typename GR, typename V = int, typename C = V>
71 73
  class NetworkSimplex
72 74
  {
73 75
  public:
74 76

	
75 77
    /// The type of the flow amounts, capacity bounds and supply values
76 78
    typedef V Value;
77 79
    /// The type of the arc costs
78 80
    typedef C Cost;
79 81

	
80 82
  public:
81 83

	
82 84
    /// \brief Problem type constants for the \c run() function.
83 85
    ///
84 86
    /// Enum type containing the problem type constants that can be
85 87
    /// returned by the \ref run() function of the algorithm.
86 88
    enum ProblemType {
87 89
      /// The problem has no feasible solution (flow).
88 90
      INFEASIBLE,
89 91
      /// The problem has optimal solution (i.e. it is feasible and
90 92
      /// bounded), and the algorithm has found optimal flow and node
91 93
      /// potentials (primal and dual solutions).
92 94
      OPTIMAL,
93 95
      /// The objective function of the problem is unbounded, i.e.
94 96
      /// there is a directed cycle having negative total cost and
95 97
      /// infinite upper bound.
96 98
      UNBOUNDED
97 99
    };
98 100
    
99 101
    /// \brief Constants for selecting the type of the supply constraints.
100 102
    ///
101 103
    /// Enum type containing constants for selecting the supply type,
102 104
    /// i.e. the direction of the inequalities in the supply/demand
103 105
    /// constraints of the \ref min_cost_flow "minimum cost flow problem".
104 106
    ///
105 107
    /// The default supply type is \c GEQ, the \c LEQ type can be
106 108
    /// selected using \ref supplyType().
107 109
    /// The equality form is a special case of both supply types.
Ignore white space 6 line context
... ...
@@ -954,140 +954,142 @@
954 954
        target.clear();
955 955
        for (typename Source::RevArcIt it(source); it != INVALID; ++it) {
956 956
          target.addFront(it);
957 957
        }
958 958
      }
959 959
    };
960 960

	
961 961
    template <typename Target, typename Source>
962 962
    struct PathCopySelectorBackward<Target, Source, true> {
963 963
      static void copy(Target& target, const Source& source) {
964 964
        target.clear();
965 965
        target.buildRev(source);
966 966
      }
967 967
    };
968 968

	
969 969
    
970 970
    template <typename Target, typename Source,
971 971
              bool revEnable = RevPathTagIndicator<Source>::value>
972 972
    struct PathCopySelector {
973 973
      static void copy(Target& target, const Source& source) {
974 974
        PathCopySelectorForward<Target, Source>::copy(target, source);
975 975
      }      
976 976
    };
977 977

	
978 978
    template <typename Target, typename Source>
979 979
    struct PathCopySelector<Target, Source, true> {
980 980
      static void copy(Target& target, const Source& source) {
981 981
        PathCopySelectorBackward<Target, Source>::copy(target, source);
982 982
      }      
983 983
    };
984 984

	
985 985
  }
986 986

	
987 987

	
988 988
  /// \brief Make a copy of a path.
989 989
  ///
990 990
  ///  This function makes a copy of a path.
991 991
  template <typename Target, typename Source>
992 992
  void copyPath(Target& target, const Source& source) {
993 993
    checkConcept<concepts::PathDumper<typename Source::Digraph>, Source>();
994 994
    _path_bits::PathCopySelector<Target, Source>::copy(target, source);
995 995
  }
996 996

	
997 997
  /// \brief Check the consistency of a path.
998 998
  ///
999 999
  /// This function checks that the target of each arc is the same
1000 1000
  /// as the source of the next one.
1001 1001
  ///
1002 1002
  template <typename Digraph, typename Path>
1003 1003
  bool checkPath(const Digraph& digraph, const Path& path) {
1004 1004
    typename Path::ArcIt it(path);
1005 1005
    if (it == INVALID) return true;
1006 1006
    typename Digraph::Node node = digraph.target(it);
1007 1007
    ++it;
1008 1008
    while (it != INVALID) {
1009 1009
      if (digraph.source(it) != node) return false;
1010 1010
      node = digraph.target(it);
1011 1011
      ++it;
1012 1012
    }
1013 1013
    return true;
1014 1014
  }
1015 1015

	
1016 1016
  /// \brief The source of a path
1017 1017
  ///
1018
  /// This function returns the source of the given path.
1018
  /// This function returns the source node of the given path.
1019
  /// If the path is empty, then it returns \c INVALID.
1019 1020
  template <typename Digraph, typename Path>
1020 1021
  typename Digraph::Node pathSource(const Digraph& digraph, const Path& path) {
1021
    return digraph.source(path.front());
1022
    return path.empty() ? INVALID : digraph.source(path.front());
1022 1023
  }
1023 1024

	
1024 1025
  /// \brief The target of a path
1025 1026
  ///
1026
  /// This function returns the target of the given path.
1027
  /// This function returns the target node of the given path.
1028
  /// If the path is empty, then it returns \c INVALID.
1027 1029
  template <typename Digraph, typename Path>
1028 1030
  typename Digraph::Node pathTarget(const Digraph& digraph, const Path& path) {
1029
    return digraph.target(path.back());
1031
    return path.empty() ? INVALID : digraph.target(path.back());
1030 1032
  }
1031 1033

	
1032 1034
  /// \brief Class which helps to iterate through the nodes of a path
1033 1035
  ///
1034 1036
  /// In a sense, the path can be treated as a list of arcs. The
1035 1037
  /// lemon path type stores only this list. As a consequence, it
1036 1038
  /// cannot enumerate the nodes in the path and the zero length paths
1037 1039
  /// cannot have a source node.
1038 1040
  ///
1039 1041
  /// This class implements the node iterator of a path structure. To
1040 1042
  /// provide this feature, the underlying digraph should be passed to
1041 1043
  /// the constructor of the iterator.
1042 1044
  template <typename Path>
1043 1045
  class PathNodeIt {
1044 1046
  private:
1045 1047
    const typename Path::Digraph *_digraph;
1046 1048
    typename Path::ArcIt _it;
1047 1049
    typename Path::Digraph::Node _nd;
1048 1050

	
1049 1051
  public:
1050 1052

	
1051 1053
    typedef typename Path::Digraph Digraph;
1052 1054
    typedef typename Digraph::Node Node;
1053 1055

	
1054 1056
    /// Default constructor
1055 1057
    PathNodeIt() {}
1056 1058
    /// Invalid constructor
1057 1059
    PathNodeIt(Invalid)
1058 1060
      : _digraph(0), _it(INVALID), _nd(INVALID) {}
1059 1061
    /// Constructor
1060 1062
    PathNodeIt(const Digraph& digraph, const Path& path)
1061 1063
      : _digraph(&digraph), _it(path) {
1062 1064
      _nd = (_it != INVALID ? _digraph->source(_it) : INVALID);
1063 1065
    }
1064 1066
    /// Constructor
1065 1067
    PathNodeIt(const Digraph& digraph, const Path& path, const Node& src)
1066 1068
      : _digraph(&digraph), _it(path), _nd(src) {}
1067 1069

	
1068 1070
    ///Conversion to Digraph::Node
1069 1071
    operator Node() const {
1070 1072
      return _nd;
1071 1073
    }
1072 1074

	
1073 1075
    /// Next node
1074 1076
    PathNodeIt& operator++() {
1075 1077
      if (_it == INVALID) _nd = INVALID;
1076 1078
      else {
1077 1079
        _nd = _digraph->target(_it);
1078 1080
        ++_it;
1079 1081
      }
1080 1082
      return *this;
1081 1083
    }
1082 1084

	
1083 1085
    /// Comparison operator
1084 1086
    bool operator==(const PathNodeIt& n) const {
1085 1087
      return _it == n._it && _nd == n._nd;
1086 1088
    }
1087 1089
    /// Comparison operator
1088 1090
    bool operator!=(const PathNodeIt& n) const {
1089 1091
      return _it != n._it || _nd != n._nd;
1090 1092
    }
1091 1093
    /// Comparison operator
1092 1094
    bool operator<(const PathNodeIt& n) const {
1093 1095
      return (_it < n._it && _nd != INVALID);
Ignore white space 6 line context
... ...
@@ -41,129 +41,130 @@
41 41

	
42 42
    /// \brief The type of the map that stores the arc capacities.
43 43
    ///
44 44
    /// The type of the map that stores the arc capacities.
45 45
    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
46 46
    typedef CAP CapacityMap;
47 47

	
48 48
    /// \brief The type of the flow values.
49 49
    typedef typename CapacityMap::Value Value;
50 50

	
51 51
    /// \brief The type of the map that stores the flow values.
52 52
    ///
53 53
    /// The type of the map that stores the flow values.
54 54
    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
55 55
#ifdef DOXYGEN
56 56
    typedef GR::ArcMap<Value> FlowMap;
57 57
#else
58 58
    typedef typename Digraph::template ArcMap<Value> FlowMap;
59 59
#endif
60 60

	
61 61
    /// \brief Instantiates a FlowMap.
62 62
    ///
63 63
    /// This function instantiates a \ref FlowMap.
64 64
    /// \param digraph The digraph for which we would like to define
65 65
    /// the flow map.
66 66
    static FlowMap* createFlowMap(const Digraph& digraph) {
67 67
      return new FlowMap(digraph);
68 68
    }
69 69

	
70 70
    /// \brief The elevator type used by Preflow algorithm.
71 71
    ///
72 72
    /// The elevator type used by Preflow algorithm.
73 73
    ///
74 74
    /// \sa Elevator, LinkedElevator
75 75
#ifdef DOXYGEN
76 76
    typedef lemon::Elevator<GR, GR::Node> Elevator;
77 77
#else
78 78
    typedef lemon::Elevator<Digraph, typename Digraph::Node> Elevator;
79 79
#endif
80 80

	
81 81
    /// \brief Instantiates an Elevator.
82 82
    ///
83 83
    /// This function instantiates an \ref Elevator.
84 84
    /// \param digraph The digraph for which we would like to define
85 85
    /// the elevator.
86 86
    /// \param max_level The maximum level of the elevator.
87 87
    static Elevator* createElevator(const Digraph& digraph, int max_level) {
88 88
      return new Elevator(digraph, max_level);
89 89
    }
90 90

	
91 91
    /// \brief The tolerance used by the algorithm
92 92
    ///
93 93
    /// The tolerance used by the algorithm to handle inexact computation.
94 94
    typedef lemon::Tolerance<Value> Tolerance;
95 95

	
96 96
  };
97 97

	
98 98

	
99 99
  /// \ingroup max_flow
100 100
  ///
101 101
  /// \brief %Preflow algorithm class.
102 102
  ///
103 103
  /// This class provides an implementation of Goldberg-Tarjan's \e preflow
104 104
  /// \e push-relabel algorithm producing a \ref max_flow
105
  /// "flow of maximum value" in a digraph.
105
  /// "flow of maximum value" in a digraph \ref clrs01algorithms,
106
  /// \ref amo93networkflows, \ref goldberg88newapproach.
106 107
  /// The preflow algorithms are the fastest known maximum
107 108
  /// flow algorithms. The current implementation uses a mixture of the
108 109
  /// \e "highest label" and the \e "bound decrease" heuristics.
109 110
  /// The worst case time complexity of the algorithm is \f$O(n^2\sqrt{e})\f$.
110 111
  ///
111 112
  /// The algorithm consists of two phases. After the first phase
112 113
  /// the maximum flow value and the minimum cut is obtained. The
113 114
  /// second phase constructs a feasible maximum flow on each arc.
114 115
  ///
115 116
  /// \tparam GR The type of the digraph the algorithm runs on.
116 117
  /// \tparam CAP The type of the capacity map. The default map
117 118
  /// type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
118 119
#ifdef DOXYGEN
119 120
  template <typename GR, typename CAP, typename TR>
120 121
#else
121 122
  template <typename GR,
122 123
            typename CAP = typename GR::template ArcMap<int>,
123 124
            typename TR = PreflowDefaultTraits<GR, CAP> >
124 125
#endif
125 126
  class Preflow {
126 127
  public:
127 128

	
128 129
    ///The \ref PreflowDefaultTraits "traits class" of the algorithm.
129 130
    typedef TR Traits;
130 131
    ///The type of the digraph the algorithm runs on.
131 132
    typedef typename Traits::Digraph Digraph;
132 133
    ///The type of the capacity map.
133 134
    typedef typename Traits::CapacityMap CapacityMap;
134 135
    ///The type of the flow values.
135 136
    typedef typename Traits::Value Value;
136 137

	
137 138
    ///The type of the flow map.
138 139
    typedef typename Traits::FlowMap FlowMap;
139 140
    ///The type of the elevator.
140 141
    typedef typename Traits::Elevator Elevator;
141 142
    ///The type of the tolerance.
142 143
    typedef typename Traits::Tolerance Tolerance;
143 144

	
144 145
  private:
145 146

	
146 147
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
147 148

	
148 149
    const Digraph& _graph;
149 150
    const CapacityMap* _capacity;
150 151

	
151 152
    int _node_num;
152 153

	
153 154
    Node _source, _target;
154 155

	
155 156
    FlowMap* _flow;
156 157
    bool _local_flow;
157 158

	
158 159
    Elevator* _level;
159 160
    bool _local_level;
160 161

	
161 162
    typedef typename Digraph::template NodeMap<Value> ExcessMap;
162 163
    ExcessMap* _excess;
163 164

	
164 165
    Tolerance _tolerance;
165 166

	
166 167
    bool _phase;
167 168

	
168 169

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

	
19 19
#ifndef LEMON_SMART_GRAPH_H
20 20
#define LEMON_SMART_GRAPH_H
21 21

	
22 22
///\ingroup graphs
23 23
///\file
24 24
///\brief SmartDigraph and SmartGraph classes.
25 25

	
26 26
#include <vector>
27 27

	
28 28
#include <lemon/core.h>
29 29
#include <lemon/error.h>
30 30
#include <lemon/bits/graph_extender.h>
31 31

	
32 32
namespace lemon {
33 33

	
34 34
  class SmartDigraph;
35
  ///Base of SmartDigraph
36 35

	
37
  ///Base of SmartDigraph
38
  ///
39 36
  class SmartDigraphBase {
40 37
  protected:
41 38

	
42 39
    struct NodeT
43 40
    {
44 41
      int first_in, first_out;
45 42
      NodeT() {}
46 43
    };
47 44
    struct ArcT
48 45
    {
49 46
      int target, source, next_in, next_out;
50 47
      ArcT() {}
51 48
    };
52 49

	
53 50
    std::vector<NodeT> nodes;
54 51
    std::vector<ArcT> arcs;
55 52

	
56 53
  public:
57 54

	
58 55
    typedef SmartDigraphBase Digraph;
59 56

	
60 57
    class Node;
61 58
    class Arc;
62 59

	
63 60
  public:
64 61

	
65 62
    SmartDigraphBase() : nodes(), arcs() { }
66 63
    SmartDigraphBase(const SmartDigraphBase &_g)
67 64
      : nodes(_g.nodes), arcs(_g.arcs) { }
68 65

	
69 66
    typedef True NodeNumTag;
70 67
    typedef True ArcNumTag;
71 68

	
72 69
    int nodeNum() const { return nodes.size(); }
73 70
    int arcNum() const { return arcs.size(); }
74 71

	
75 72
    int maxNodeId() const { return nodes.size()-1; }
76 73
    int maxArcId() const { return arcs.size()-1; }
77 74

	
78 75
    Node addNode() {
79 76
      int n = nodes.size();
80 77
      nodes.push_back(NodeT());
81 78
      nodes[n].first_in = -1;
82 79
      nodes[n].first_out = -1;
83 80
      return Node(n);
84 81
    }
85 82

	
86 83
    Arc addArc(Node u, Node v) {
87 84
      int n = arcs.size();
88 85
      arcs.push_back(ArcT());
89 86
      arcs[n].source = u._id;
90 87
      arcs[n].target = v._id;
91 88
      arcs[n].next_out = nodes[u._id].first_out;
92 89
      arcs[n].next_in = nodes[v._id].first_in;
93 90
      nodes[u._id].first_out = nodes[v._id].first_in = n;
94 91

	
95 92
      return Arc(n);
96 93
    }
97 94

	
98 95
    void clear() {
99 96
      arcs.clear();
100 97
      nodes.clear();
101 98
    }
102 99

	
... ...
@@ -126,686 +123,691 @@
126 123
    public:
127 124
      Node() {}
128 125
      Node (Invalid) : _id(-1) {}
129 126
      bool operator==(const Node i) const {return _id == i._id;}
130 127
      bool operator!=(const Node i) const {return _id != i._id;}
131 128
      bool operator<(const Node i) const {return _id < i._id;}
132 129
    };
133 130

	
134 131

	
135 132
    class Arc {
136 133
      friend class SmartDigraphBase;
137 134
      friend class SmartDigraph;
138 135

	
139 136
    protected:
140 137
      int _id;
141 138
      explicit Arc(int id) : _id(id) {}
142 139
    public:
143 140
      Arc() { }
144 141
      Arc (Invalid) : _id(-1) {}
145 142
      bool operator==(const Arc i) const {return _id == i._id;}
146 143
      bool operator!=(const Arc i) const {return _id != i._id;}
147 144
      bool operator<(const Arc i) const {return _id < i._id;}
148 145
    };
149 146

	
150 147
    void first(Node& node) const {
151 148
      node._id = nodes.size() - 1;
152 149
    }
153 150

	
154 151
    static void next(Node& node) {
155 152
      --node._id;
156 153
    }
157 154

	
158 155
    void first(Arc& arc) const {
159 156
      arc._id = arcs.size() - 1;
160 157
    }
161 158

	
162 159
    static void next(Arc& arc) {
163 160
      --arc._id;
164 161
    }
165 162

	
166 163
    void firstOut(Arc& arc, const Node& node) const {
167 164
      arc._id = nodes[node._id].first_out;
168 165
    }
169 166

	
170 167
    void nextOut(Arc& arc) const {
171 168
      arc._id = arcs[arc._id].next_out;
172 169
    }
173 170

	
174 171
    void firstIn(Arc& arc, const Node& node) const {
175 172
      arc._id = nodes[node._id].first_in;
176 173
    }
177 174

	
178 175
    void nextIn(Arc& arc) const {
179 176
      arc._id = arcs[arc._id].next_in;
180 177
    }
181 178

	
182 179
  };
183 180

	
184 181
  typedef DigraphExtender<SmartDigraphBase> ExtendedSmartDigraphBase;
185 182

	
186 183
  ///\ingroup graphs
187 184
  ///
188 185
  ///\brief A smart directed graph class.
189 186
  ///
190
  ///This is a simple and fast digraph implementation.
191
  ///It is also quite memory efficient, but at the price
192
  ///that <b> it does support only limited (only stack-like)
193
  ///node and arc deletions</b>.
194
  ///It fully conforms to the \ref concepts::Digraph "Digraph concept".
187
  ///\ref SmartDigraph is a simple and fast digraph implementation.
188
  ///It is also quite memory efficient but at the price
189
  ///that it does not support node and arc deletion 
190
  ///(except for the Snapshot feature).
195 191
  ///
196
  ///\sa concepts::Digraph.
192
  ///This type fully conforms to the \ref concepts::Digraph "Digraph concept"
193
  ///and it also provides some additional functionalities.
194
  ///Most of its member functions and nested classes are documented
195
  ///only in the concept class.
196
  ///
197
  ///\sa concepts::Digraph
198
  ///\sa SmartGraph
197 199
  class SmartDigraph : public ExtendedSmartDigraphBase {
198 200
    typedef ExtendedSmartDigraphBase Parent;
199 201

	
200 202
  private:
201

	
202
    ///SmartDigraph is \e not copy constructible. Use DigraphCopy() instead.
203

	
204
    ///SmartDigraph is \e not copy constructible. Use DigraphCopy() instead.
205
    ///
203
    /// Digraphs are \e not copy constructible. Use DigraphCopy instead.
206 204
    SmartDigraph(const SmartDigraph &) : ExtendedSmartDigraphBase() {};
207
    ///\brief Assignment of SmartDigraph to another one is \e not allowed.
208
    ///Use DigraphCopy() instead.
209

	
210
    ///Assignment of SmartDigraph to another one is \e not allowed.
211
    ///Use DigraphCopy() instead.
205
    /// \brief Assignment of a digraph to another one is \e not allowed.
206
    /// Use DigraphCopy instead.
212 207
    void operator=(const SmartDigraph &) {}
213 208

	
214 209
  public:
215 210

	
216 211
    /// Constructor
217 212

	
218 213
    /// Constructor.
219 214
    ///
220 215
    SmartDigraph() {};
221 216

	
222 217
    ///Add a new node to the digraph.
223 218

	
224
    /// Add a new node to the digraph.
225
    /// \return The new node.
219
    ///This function adds a new node to the digraph.
220
    ///\return The new node.
226 221
    Node addNode() { return Parent::addNode(); }
227 222

	
228 223
    ///Add a new arc to the digraph.
229 224

	
230
    ///Add a new arc to the digraph with source node \c s
225
    ///This function adds a new arc to the digraph with source node \c s
231 226
    ///and target node \c t.
232 227
    ///\return The new arc.
233
    Arc addArc(const Node& s, const Node& t) {
228
    Arc addArc(Node s, Node t) {
234 229
      return Parent::addArc(s, t);
235 230
    }
236 231

	
237
    /// \brief Using this it is possible to avoid the superfluous memory
238
    /// allocation.
239

	
240
    /// Using this it is possible to avoid the superfluous memory
241
    /// allocation: if you know that the digraph you want to build will
242
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
243
    /// then it is worth reserving space for this amount before starting
244
    /// to build the digraph.
245
    /// \sa reserveArc
246
    void reserveNode(int n) { nodes.reserve(n); };
247

	
248
    /// \brief Using this it is possible to avoid the superfluous memory
249
    /// allocation.
250

	
251
    /// Using this it is possible to avoid the superfluous memory
252
    /// allocation: if you know that the digraph you want to build will
253
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
254
    /// then it is worth reserving space for this amount before starting
255
    /// to build the digraph.
256
    /// \sa reserveNode
257
    void reserveArc(int m) { arcs.reserve(m); };
258

	
259 232
    /// \brief Node validity check
260 233
    ///
261
    /// This function gives back true if the given node is valid,
262
    /// ie. it is a real node of the graph.
234
    /// This function gives back \c true if the given node is valid,
235
    /// i.e. it is a real node of the digraph.
263 236
    ///
264 237
    /// \warning A removed node (using Snapshot) could become valid again
265
    /// when new nodes are added to the graph.
238
    /// if new nodes are added to the digraph.
266 239
    bool valid(Node n) const { return Parent::valid(n); }
267 240

	
268 241
    /// \brief Arc validity check
269 242
    ///
270
    /// This function gives back true if the given arc is valid,
271
    /// ie. it is a real arc of the graph.
243
    /// This function gives back \c true if the given arc is valid,
244
    /// i.e. it is a real arc of the digraph.
272 245
    ///
273 246
    /// \warning A removed arc (using Snapshot) could become valid again
274
    /// when new arcs are added to the graph.
247
    /// if new arcs are added to the graph.
275 248
    bool valid(Arc a) const { return Parent::valid(a); }
276 249

	
277
    ///Clear the digraph.
278

	
279
    ///Erase all the nodes and arcs from the digraph.
280
    ///
281
    void clear() {
282
      Parent::clear();
283
    }
284

	
285 250
    ///Split a node.
286 251

	
287
    ///This function splits a node. First a new node is added to the digraph,
288
    ///then the source of each outgoing arc of \c n is moved to this new node.
289
    ///If \c connect is \c true (this is the default value), then a new arc
290
    ///from \c n to the newly created node is also added.
252
    ///This function splits the given node. First, a new node is added
253
    ///to the digraph, then the source of each outgoing arc of node \c n
254
    ///is moved to this new node.
255
    ///If the second parameter \c connect is \c true (this is the default
256
    ///value), then a new arc from node \c n to the newly created node
257
    ///is also added.
291 258
    ///\return The newly created node.
292 259
    ///
293
    ///\note The <tt>Arc</tt>s
294
    ///referencing a moved arc remain
295
    ///valid. However <tt>InArc</tt>'s and <tt>OutArc</tt>'s
296
    ///may be invalidated.
260
    ///\note All iterators remain valid.
261
    ///
297 262
    ///\warning This functionality cannot be used together with the Snapshot
298 263
    ///feature.
299 264
    Node split(Node n, bool connect = true)
300 265
    {
301 266
      Node b = addNode();
302 267
      nodes[b._id].first_out=nodes[n._id].first_out;
303 268
      nodes[n._id].first_out=-1;
304 269
      for(int i=nodes[b._id].first_out; i!=-1; i=arcs[i].next_out) {
305 270
        arcs[i].source=b._id;
306 271
      }
307 272
      if(connect) addArc(n,b);
308 273
      return b;
309 274
    }
310 275

	
276
    ///Clear the digraph.
277

	
278
    ///This function erases all nodes and arcs from the digraph.
279
    ///
280
    void clear() {
281
      Parent::clear();
282
    }
283

	
284
    /// Reserve memory for nodes.
285

	
286
    /// Using this function, it is possible to avoid superfluous memory
287
    /// allocation: if you know that the digraph you want to build will
288
    /// be large (e.g. it will contain millions of nodes and/or arcs),
289
    /// then it is worth reserving space for this amount before starting
290
    /// to build the digraph.
291
    /// \sa reserveArc()
292
    void reserveNode(int n) { nodes.reserve(n); };
293

	
294
    /// Reserve memory for arcs.
295

	
296
    /// Using this function, it is possible to avoid superfluous memory
297
    /// allocation: if you know that the digraph you want to build will
298
    /// be large (e.g. it will contain millions of nodes and/or arcs),
299
    /// then it is worth reserving space for this amount before starting
300
    /// to build the digraph.
301
    /// \sa reserveNode()
302
    void reserveArc(int m) { arcs.reserve(m); };
303

	
311 304
  public:
312 305

	
313 306
    class Snapshot;
314 307

	
315 308
  protected:
316 309

	
317 310
    void restoreSnapshot(const Snapshot &s)
318 311
    {
319 312
      while(s.arc_num<arcs.size()) {
320 313
        Arc arc = arcFromId(arcs.size()-1);
321 314
        Parent::notifier(Arc()).erase(arc);
322 315
        nodes[arcs.back().source].first_out=arcs.back().next_out;
323 316
        nodes[arcs.back().target].first_in=arcs.back().next_in;
324 317
        arcs.pop_back();
325 318
      }
326 319
      while(s.node_num<nodes.size()) {
327 320
        Node node = nodeFromId(nodes.size()-1);
328 321
        Parent::notifier(Node()).erase(node);
329 322
        nodes.pop_back();
330 323
      }
331 324
    }
332 325

	
333 326
  public:
334 327

	
335
    ///Class to make a snapshot of the digraph and to restrore to it later.
328
    ///Class to make a snapshot of the digraph and to restore it later.
336 329

	
337
    ///Class to make a snapshot of the digraph and to restrore to it later.
330
    ///Class to make a snapshot of the digraph and to restore it later.
338 331
    ///
339 332
    ///The newly added nodes and arcs can be removed using the
340
    ///restore() function.
341
    ///\note After you restore a state, you cannot restore
342
    ///a later state, in other word you cannot add again the arcs deleted
343
    ///by restore() using another one Snapshot instance.
333
    ///restore() function. This is the only way for deleting nodes and/or
334
    ///arcs from a SmartDigraph structure.
344 335
    ///
345
    ///\warning If you do not use correctly the snapshot that can cause
346
    ///either broken program, invalid state of the digraph, valid but
347
    ///not the restored digraph or no change. Because the runtime performance
348
    ///the validity of the snapshot is not stored.
336
    ///\note After a state is restored, you cannot restore a later state, 
337
    ///i.e. you cannot add the removed nodes and arcs again using
338
    ///another Snapshot instance.
339
    ///
340
    ///\warning Node splitting cannot be restored.
341
    ///\warning The validity of the snapshot is not stored due to
342
    ///performance reasons. If you do not use the snapshot correctly,
343
    ///it can cause broken program, invalid or not restored state of
344
    ///the digraph or no change.
349 345
    class Snapshot
350 346
    {
351 347
      SmartDigraph *_graph;
352 348
    protected:
353 349
      friend class SmartDigraph;
354 350
      unsigned int node_num;
355 351
      unsigned int arc_num;
356 352
    public:
357 353
      ///Default constructor.
358 354

	
359 355
      ///Default constructor.
360
      ///To actually make a snapshot you must call save().
361
      ///
356
      ///You have to call save() to actually make a snapshot.
362 357
      Snapshot() : _graph(0) {}
363 358
      ///Constructor that immediately makes a snapshot
364 359

	
365
      ///This constructor immediately makes a snapshot of the digraph.
366
      ///\param graph The digraph we make a snapshot of.
367
      Snapshot(SmartDigraph &graph) : _graph(&graph) {
360
      ///This constructor immediately makes a snapshot of the given digraph.
361
      ///
362
      Snapshot(SmartDigraph &gr) : _graph(&gr) {
368 363
        node_num=_graph->nodes.size();
369 364
        arc_num=_graph->arcs.size();
370 365
      }
371 366

	
372 367
      ///Make a snapshot.
373 368

	
374
      ///Make a snapshot of the digraph.
375
      ///
376
      ///This function can be called more than once. In case of a repeated
369
      ///This function makes a snapshot of the given digraph.
370
      ///It can be called more than once. In case of a repeated
377 371
      ///call, the previous snapshot gets lost.
378
      ///\param graph The digraph we make the snapshot of.
379
      void save(SmartDigraph &graph)
380
      {
381
        _graph=&graph;
372
      void save(SmartDigraph &gr) {
373
        _graph=&gr;
382 374
        node_num=_graph->nodes.size();
383 375
        arc_num=_graph->arcs.size();
384 376
      }
385 377

	
386 378
      ///Undo the changes until a snapshot.
387 379

	
388
      ///Undo the changes until a snapshot created by save().
389
      ///
390
      ///\note After you restored a state, you cannot restore
391
      ///a later state, in other word you cannot add again the arcs deleted
392
      ///by restore().
380
      ///This function undos the changes until the last snapshot
381
      ///created by save() or Snapshot(SmartDigraph&).
393 382
      void restore()
394 383
      {
395 384
        _graph->restoreSnapshot(*this);
396 385
      }
397 386
    };
398 387
  };
399 388

	
400 389

	
401 390
  class SmartGraphBase {
402 391

	
403 392
  protected:
404 393

	
405 394
    struct NodeT {
406 395
      int first_out;
407 396
    };
408 397

	
409 398
    struct ArcT {
410 399
      int target;
411 400
      int next_out;
412 401
    };
413 402

	
414 403
    std::vector<NodeT> nodes;
415 404
    std::vector<ArcT> arcs;
416 405

	
417 406
    int first_free_arc;
418 407

	
419 408
  public:
420 409

	
421 410
    typedef SmartGraphBase Graph;
422 411

	
423 412
    class Node;
424 413
    class Arc;
425 414
    class Edge;
426 415

	
427 416
    class Node {
428 417
      friend class SmartGraphBase;
429 418
    protected:
430 419

	
431 420
      int _id;
432 421
      explicit Node(int id) { _id = id;}
433 422

	
434 423
    public:
435 424
      Node() {}
436 425
      Node (Invalid) { _id = -1; }
437 426
      bool operator==(const Node& node) const {return _id == node._id;}
438 427
      bool operator!=(const Node& node) const {return _id != node._id;}
439 428
      bool operator<(const Node& node) const {return _id < node._id;}
440 429
    };
441 430

	
442 431
    class Edge {
443 432
      friend class SmartGraphBase;
444 433
    protected:
445 434

	
446 435
      int _id;
447 436
      explicit Edge(int id) { _id = id;}
448 437

	
449 438
    public:
450 439
      Edge() {}
451 440
      Edge (Invalid) { _id = -1; }
452 441
      bool operator==(const Edge& arc) const {return _id == arc._id;}
453 442
      bool operator!=(const Edge& arc) const {return _id != arc._id;}
454 443
      bool operator<(const Edge& arc) const {return _id < arc._id;}
455 444
    };
456 445

	
457 446
    class Arc {
458 447
      friend class SmartGraphBase;
459 448
    protected:
460 449

	
461 450
      int _id;
462 451
      explicit Arc(int id) { _id = id;}
463 452

	
464 453
    public:
465 454
      operator Edge() const {
466 455
        return _id != -1 ? edgeFromId(_id / 2) : INVALID;
467 456
      }
468 457

	
469 458
      Arc() {}
470 459
      Arc (Invalid) { _id = -1; }
471 460
      bool operator==(const Arc& arc) const {return _id == arc._id;}
472 461
      bool operator!=(const Arc& arc) const {return _id != arc._id;}
473 462
      bool operator<(const Arc& arc) const {return _id < arc._id;}
474 463
    };
475 464

	
476 465

	
477 466

	
478 467
    SmartGraphBase()
479 468
      : nodes(), arcs() {}
480 469

	
481 470
    typedef True NodeNumTag;
482 471
    typedef True EdgeNumTag;
483 472
    typedef True ArcNumTag;
484 473

	
485 474
    int nodeNum() const { return nodes.size(); }
486 475
    int edgeNum() const { return arcs.size() / 2; }
487 476
    int arcNum() const { return arcs.size(); }
488 477

	
489 478
    int maxNodeId() const { return nodes.size()-1; }
490 479
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
491 480
    int maxArcId() const { return arcs.size()-1; }
492 481

	
493 482
    Node source(Arc e) const { return Node(arcs[e._id ^ 1].target); }
494 483
    Node target(Arc e) const { return Node(arcs[e._id].target); }
495 484

	
496 485
    Node u(Edge e) const { return Node(arcs[2 * e._id].target); }
497 486
    Node v(Edge e) const { return Node(arcs[2 * e._id + 1].target); }
498 487

	
499 488
    static bool direction(Arc e) {
500 489
      return (e._id & 1) == 1;
501 490
    }
502 491

	
503 492
    static Arc direct(Edge e, bool d) {
504 493
      return Arc(e._id * 2 + (d ? 1 : 0));
505 494
    }
506 495

	
507 496
    void first(Node& node) const {
508 497
      node._id = nodes.size() - 1;
509 498
    }
510 499

	
511
    void next(Node& node) const {
500
    static void next(Node& node) {
512 501
      --node._id;
513 502
    }
514 503

	
515 504
    void first(Arc& arc) const {
516 505
      arc._id = arcs.size() - 1;
517 506
    }
518 507

	
519
    void next(Arc& arc) const {
508
    static void next(Arc& arc) {
520 509
      --arc._id;
521 510
    }
522 511

	
523 512
    void first(Edge& arc) const {
524 513
      arc._id = arcs.size() / 2 - 1;
525 514
    }
526 515

	
527
    void next(Edge& arc) const {
516
    static void next(Edge& arc) {
528 517
      --arc._id;
529 518
    }
530 519

	
531 520
    void firstOut(Arc &arc, const Node& v) const {
532 521
      arc._id = nodes[v._id].first_out;
533 522
    }
534 523
    void nextOut(Arc &arc) const {
535 524
      arc._id = arcs[arc._id].next_out;
536 525
    }
537 526

	
538 527
    void firstIn(Arc &arc, const Node& v) const {
539 528
      arc._id = ((nodes[v._id].first_out) ^ 1);
540 529
      if (arc._id == -2) arc._id = -1;
541 530
    }
542 531
    void nextIn(Arc &arc) const {
543 532
      arc._id = ((arcs[arc._id ^ 1].next_out) ^ 1);
544 533
      if (arc._id == -2) arc._id = -1;
545 534
    }
546 535

	
547 536
    void firstInc(Edge &arc, bool& d, const Node& v) const {
548 537
      int de = nodes[v._id].first_out;
549 538
      if (de != -1) {
550 539
        arc._id = de / 2;
551 540
        d = ((de & 1) == 1);
552 541
      } else {
553 542
        arc._id = -1;
554 543
        d = true;
555 544
      }
556 545
    }
557 546
    void nextInc(Edge &arc, bool& d) const {
558 547
      int de = (arcs[(arc._id * 2) | (d ? 1 : 0)].next_out);
559 548
      if (de != -1) {
560 549
        arc._id = de / 2;
561 550
        d = ((de & 1) == 1);
562 551
      } else {
563 552
        arc._id = -1;
564 553
        d = true;
565 554
      }
566 555
    }
567 556

	
568 557
    static int id(Node v) { return v._id; }
569 558
    static int id(Arc e) { return e._id; }
570 559
    static int id(Edge e) { return e._id; }
571 560

	
572 561
    static Node nodeFromId(int id) { return Node(id);}
573 562
    static Arc arcFromId(int id) { return Arc(id);}
574 563
    static Edge edgeFromId(int id) { return Edge(id);}
575 564

	
576 565
    bool valid(Node n) const {
577 566
      return n._id >= 0 && n._id < static_cast<int>(nodes.size());
578 567
    }
579 568
    bool valid(Arc a) const {
580 569
      return a._id >= 0 && a._id < static_cast<int>(arcs.size());
581 570
    }
582 571
    bool valid(Edge e) const {
583 572
      return e._id >= 0 && 2 * e._id < static_cast<int>(arcs.size());
584 573
    }
585 574

	
586 575
    Node addNode() {
587 576
      int n = nodes.size();
588 577
      nodes.push_back(NodeT());
589 578
      nodes[n].first_out = -1;
590 579

	
591 580
      return Node(n);
592 581
    }
593 582

	
594 583
    Edge addEdge(Node u, Node v) {
595 584
      int n = arcs.size();
596 585
      arcs.push_back(ArcT());
597 586
      arcs.push_back(ArcT());
598 587

	
599 588
      arcs[n].target = u._id;
600 589
      arcs[n | 1].target = v._id;
601 590

	
602 591
      arcs[n].next_out = nodes[v._id].first_out;
603 592
      nodes[v._id].first_out = n;
604 593

	
605 594
      arcs[n | 1].next_out = nodes[u._id].first_out;
606 595
      nodes[u._id].first_out = (n | 1);
607 596

	
608 597
      return Edge(n / 2);
609 598
    }
610 599

	
611 600
    void clear() {
612 601
      arcs.clear();
613 602
      nodes.clear();
614 603
    }
615 604

	
616 605
  };
617 606

	
618 607
  typedef GraphExtender<SmartGraphBase> ExtendedSmartGraphBase;
619 608

	
620 609
  /// \ingroup graphs
621 610
  ///
622 611
  /// \brief A smart undirected graph class.
623 612
  ///
624
  /// This is a simple and fast graph implementation.
625
  /// It is also quite memory efficient, but at the price
626
  /// that <b> it does support only limited (only stack-like)
627
  /// node and arc deletions</b>.
628
  /// It fully conforms to the \ref concepts::Graph "Graph concept".
613
  /// \ref SmartGraph is a simple and fast graph implementation.
614
  /// It is also quite memory efficient but at the price
615
  /// that it does not support node and edge deletion 
616
  /// (except for the Snapshot feature).
629 617
  ///
630
  /// \sa concepts::Graph.
618
  /// This type fully conforms to the \ref concepts::Graph "Graph concept"
619
  /// and it also provides some additional functionalities.
620
  /// Most of its member functions and nested classes are documented
621
  /// only in the concept class.
622
  ///
623
  /// \sa concepts::Graph
624
  /// \sa SmartDigraph
631 625
  class SmartGraph : public ExtendedSmartGraphBase {
632 626
    typedef ExtendedSmartGraphBase Parent;
633 627

	
634 628
  private:
635

	
636
    ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
637

	
638
    ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
639
    ///
629
    /// Graphs are \e not copy constructible. Use GraphCopy instead.
640 630
    SmartGraph(const SmartGraph &) : ExtendedSmartGraphBase() {};
641

	
642
    ///\brief Assignment of SmartGraph to another one is \e not allowed.
643
    ///Use GraphCopy() instead.
644

	
645
    ///Assignment of SmartGraph to another one is \e not allowed.
646
    ///Use GraphCopy() instead.
631
    /// \brief Assignment of a graph to another one is \e not allowed.
632
    /// Use GraphCopy instead.
647 633
    void operator=(const SmartGraph &) {}
648 634

	
649 635
  public:
650 636

	
651 637
    /// Constructor
652 638

	
653 639
    /// Constructor.
654 640
    ///
655 641
    SmartGraph() {}
656 642

	
657
    ///Add a new node to the graph.
658

	
659
    /// Add a new node to the graph.
643
    /// \brief Add a new node to the graph.
644
    ///
645
    /// This function adds a new node to the graph.
660 646
    /// \return The new node.
661 647
    Node addNode() { return Parent::addNode(); }
662 648

	
663
    ///Add a new edge to the graph.
664

	
665
    ///Add a new edge to the graph with node \c s
666
    ///and \c t.
667
    ///\return The new edge.
668
    Edge addEdge(const Node& s, const Node& t) {
669
      return Parent::addEdge(s, t);
649
    /// \brief Add a new edge to the graph.
650
    ///
651
    /// This function adds a new edge to the graph between nodes
652
    /// \c u and \c v with inherent orientation from node \c u to
653
    /// node \c v.
654
    /// \return The new edge.
655
    Edge addEdge(Node u, Node v) {
656
      return Parent::addEdge(u, v);
670 657
    }
671 658

	
672 659
    /// \brief Node validity check
673 660
    ///
674
    /// This function gives back true if the given node is valid,
675
    /// ie. it is a real node of the graph.
661
    /// This function gives back \c true if the given node is valid,
662
    /// i.e. it is a real node of the graph.
676 663
    ///
677 664
    /// \warning A removed node (using Snapshot) could become valid again
678
    /// when new nodes are added to the graph.
665
    /// if new nodes are added to the graph.
679 666
    bool valid(Node n) const { return Parent::valid(n); }
680 667

	
668
    /// \brief Edge validity check
669
    ///
670
    /// This function gives back \c true if the given edge is valid,
671
    /// i.e. it is a real edge of the graph.
672
    ///
673
    /// \warning A removed edge (using Snapshot) could become valid again
674
    /// if new edges are added to the graph.
675
    bool valid(Edge e) const { return Parent::valid(e); }
676

	
681 677
    /// \brief Arc validity check
682 678
    ///
683
    /// This function gives back true if the given arc is valid,
684
    /// ie. it is a real arc of the graph.
679
    /// This function gives back \c true if the given arc is valid,
680
    /// i.e. it is a real arc of the graph.
685 681
    ///
686 682
    /// \warning A removed arc (using Snapshot) could become valid again
687
    /// when new edges are added to the graph.
683
    /// if new edges are added to the graph.
688 684
    bool valid(Arc a) const { return Parent::valid(a); }
689 685

	
690
    /// \brief Edge validity check
691
    ///
692
    /// This function gives back true if the given edge is valid,
693
    /// ie. it is a real edge of the graph.
694
    ///
695
    /// \warning A removed edge (using Snapshot) could become valid again
696
    /// when new edges are added to the graph.
697
    bool valid(Edge e) const { return Parent::valid(e); }
698

	
699 686
    ///Clear the graph.
700 687

	
701
    ///Erase all the nodes and edges from the graph.
688
    ///This function erases all nodes and arcs from the graph.
702 689
    ///
703 690
    void clear() {
704 691
      Parent::clear();
705 692
    }
706 693

	
694
    /// Reserve memory for nodes.
695

	
696
    /// Using this function, it is possible to avoid superfluous memory
697
    /// allocation: if you know that the graph you want to build will
698
    /// be large (e.g. it will contain millions of nodes and/or edges),
699
    /// then it is worth reserving space for this amount before starting
700
    /// to build the graph.
701
    /// \sa reserveEdge()
702
    void reserveNode(int n) { nodes.reserve(n); };
703

	
704
    /// Reserve memory for edges.
705

	
706
    /// Using this function, it is possible to avoid superfluous memory
707
    /// allocation: if you know that the graph you want to build will
708
    /// be large (e.g. it will contain millions of nodes and/or edges),
709
    /// then it is worth reserving space for this amount before starting
710
    /// to build the graph.
711
    /// \sa reserveNode()
712
    void reserveEdge(int m) { arcs.reserve(2 * m); };
713

	
707 714
  public:
708 715

	
709 716
    class Snapshot;
710 717

	
711 718
  protected:
712 719

	
713 720
    void saveSnapshot(Snapshot &s)
714 721
    {
715 722
      s._graph = this;
716 723
      s.node_num = nodes.size();
717 724
      s.arc_num = arcs.size();
718 725
    }
719 726

	
720 727
    void restoreSnapshot(const Snapshot &s)
721 728
    {
722 729
      while(s.arc_num<arcs.size()) {
723 730
        int n=arcs.size()-1;
724 731
        Edge arc=edgeFromId(n/2);
725 732
        Parent::notifier(Edge()).erase(arc);
726 733
        std::vector<Arc> dir;
727 734
        dir.push_back(arcFromId(n));
728 735
        dir.push_back(arcFromId(n-1));
729 736
        Parent::notifier(Arc()).erase(dir);
730 737
        nodes[arcs[n-1].target].first_out=arcs[n].next_out;
731 738
        nodes[arcs[n].target].first_out=arcs[n-1].next_out;
732 739
        arcs.pop_back();
733 740
        arcs.pop_back();
734 741
      }
735 742
      while(s.node_num<nodes.size()) {
736 743
        int n=nodes.size()-1;
737 744
        Node node = nodeFromId(n);
738 745
        Parent::notifier(Node()).erase(node);
739 746
        nodes.pop_back();
740 747
      }
741 748
    }
742 749

	
743 750
  public:
744 751

	
745
    ///Class to make a snapshot of the digraph and to restrore to it later.
752
    ///Class to make a snapshot of the graph and to restore it later.
746 753

	
747
    ///Class to make a snapshot of the digraph and to restrore to it later.
754
    ///Class to make a snapshot of the graph and to restore it later.
748 755
    ///
749
    ///The newly added nodes and arcs can be removed using the
750
    ///restore() function.
756
    ///The newly added nodes and edges can be removed using the
757
    ///restore() function. This is the only way for deleting nodes and/or
758
    ///edges from a SmartGraph structure.
751 759
    ///
752
    ///\note After you restore a state, you cannot restore
753
    ///a later state, in other word you cannot add again the arcs deleted
754
    ///by restore() using another one Snapshot instance.
760
    ///\note After a state is restored, you cannot restore a later state, 
761
    ///i.e. you cannot add the removed nodes and edges again using
762
    ///another Snapshot instance.
755 763
    ///
756
    ///\warning If you do not use correctly the snapshot that can cause
757
    ///either broken program, invalid state of the digraph, valid but
758
    ///not the restored digraph or no change. Because the runtime performance
759
    ///the validity of the snapshot is not stored.
764
    ///\warning The validity of the snapshot is not stored due to
765
    ///performance reasons. If you do not use the snapshot correctly,
766
    ///it can cause broken program, invalid or not restored state of
767
    ///the graph or no change.
760 768
    class Snapshot
761 769
    {
762 770
      SmartGraph *_graph;
763 771
    protected:
764 772
      friend class SmartGraph;
765 773
      unsigned int node_num;
766 774
      unsigned int arc_num;
767 775
    public:
768 776
      ///Default constructor.
769 777

	
770 778
      ///Default constructor.
771
      ///To actually make a snapshot you must call save().
772
      ///
779
      ///You have to call save() to actually make a snapshot.
773 780
      Snapshot() : _graph(0) {}
774 781
      ///Constructor that immediately makes a snapshot
775 782

	
776
      ///This constructor immediately makes a snapshot of the digraph.
777
      ///\param graph The digraph we make a snapshot of.
778
      Snapshot(SmartGraph &graph) {
779
        graph.saveSnapshot(*this);
783
      /// This constructor immediately makes a snapshot of the given graph.
784
      ///
785
      Snapshot(SmartGraph &gr) {
786
        gr.saveSnapshot(*this);
780 787
      }
781 788

	
782 789
      ///Make a snapshot.
783 790

	
784
      ///Make a snapshot of the graph.
785
      ///
786
      ///This function can be called more than once. In case of a repeated
791
      ///This function makes a snapshot of the given graph.
792
      ///It can be called more than once. In case of a repeated
787 793
      ///call, the previous snapshot gets lost.
788
      ///\param graph The digraph we make the snapshot of.
789
      void save(SmartGraph &graph)
794
      void save(SmartGraph &gr)
790 795
      {
791
        graph.saveSnapshot(*this);
796
        gr.saveSnapshot(*this);
792 797
      }
793 798

	
794
      ///Undo the changes until a snapshot.
799
      ///Undo the changes until the last snapshot.
795 800

	
796
      ///Undo the changes until a snapshot created by save().
797
      ///
798
      ///\note After you restored a state, you cannot restore
799
      ///a later state, in other word you cannot add again the arcs deleted
800
      ///by restore().
801
      ///This function undos the changes until the last snapshot
802
      ///created by save() or Snapshot(SmartGraph&).
801 803
      void restore()
802 804
      {
803 805
        _graph->restoreSnapshot(*this);
804 806
      }
805 807
    };
806 808
  };
807 809

	
808 810
} //namespace lemon
809 811

	
810 812

	
811 813
#endif //LEMON_SMART_GRAPH_H
Ignore white space 6 line context
... ...
@@ -30,128 +30,141 @@
30 30
  SoplexLp::SoplexLp() {
31 31
    soplex = new soplex::SoPlex;
32 32
    messageLevel(MESSAGE_NOTHING);
33 33
  }
34 34

	
35 35
  SoplexLp::~SoplexLp() {
36 36
    delete soplex;
37 37
  }
38 38

	
39 39
  SoplexLp::SoplexLp(const SoplexLp& lp) {
40 40
    rows = lp.rows;
41 41
    cols = lp.cols;
42 42

	
43 43
    soplex = new soplex::SoPlex;
44 44
    (*static_cast<soplex::SPxLP*>(soplex)) = *(lp.soplex);
45 45

	
46 46
    _col_names = lp._col_names;
47 47
    _col_names_ref = lp._col_names_ref;
48 48

	
49 49
    _row_names = lp._row_names;
50 50
    _row_names_ref = lp._row_names_ref;
51 51

	
52 52
    messageLevel(MESSAGE_NOTHING);
53 53
  }
54 54

	
55 55
  void SoplexLp::_clear_temporals() {
56 56
    _primal_values.clear();
57 57
    _dual_values.clear();
58 58
  }
59 59

	
60 60
  SoplexLp* SoplexLp::newSolver() const {
61 61
    SoplexLp* newlp = new SoplexLp();
62 62
    return newlp;
63 63
  }
64 64

	
65 65
  SoplexLp* SoplexLp::cloneSolver() const {
66 66
    SoplexLp* newlp = new SoplexLp(*this);
67 67
    return newlp;
68 68
  }
69 69

	
70 70
  const char* SoplexLp::_solverName() const { return "SoplexLp"; }
71 71

	
72 72
  int SoplexLp::_addCol() {
73 73
    soplex::LPCol c;
74 74
    c.setLower(-soplex::infinity);
75 75
    c.setUpper(soplex::infinity);
76 76
    soplex->addCol(c);
77 77

	
78 78
    _col_names.push_back(std::string());
79 79

	
80 80
    return soplex->nCols() - 1;
81 81
  }
82 82

	
83 83
  int SoplexLp::_addRow() {
84 84
    soplex::LPRow r;
85 85
    r.setLhs(-soplex::infinity);
86 86
    r.setRhs(soplex::infinity);
87 87
    soplex->addRow(r);
88 88

	
89 89
    _row_names.push_back(std::string());
90 90

	
91 91
    return soplex->nRows() - 1;
92 92
  }
93 93

	
94
  int SoplexLp::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
95
    soplex::DSVector v;
96
    for (ExprIterator it = b; it != e; ++it) {
97
      v.add(it->first, it->second);
98
    }
99
    soplex::LPRow r(l, v, u);
100
    soplex->addRow(r);
101

	
102
    _row_names.push_back(std::string());
103

	
104
    return soplex->nRows() - 1;
105
  }
106

	
94 107

	
95 108
  void SoplexLp::_eraseCol(int i) {
96 109
    soplex->removeCol(i);
97 110
    _col_names_ref.erase(_col_names[i]);
98 111
    _col_names[i] = _col_names.back();
99 112
    _col_names_ref[_col_names.back()] = i;
100 113
    _col_names.pop_back();
101 114
  }
102 115

	
103 116
  void SoplexLp::_eraseRow(int i) {
104 117
    soplex->removeRow(i);
105 118
    _row_names_ref.erase(_row_names[i]);
106 119
    _row_names[i] = _row_names.back();
107 120
    _row_names_ref[_row_names.back()] = i;
108 121
    _row_names.pop_back();
109 122
  }
110 123

	
111 124
  void SoplexLp::_eraseColId(int i) {
112 125
    cols.eraseIndex(i);
113 126
    cols.relocateIndex(i, cols.maxIndex());
114 127
  }
115 128
  void SoplexLp::_eraseRowId(int i) {
116 129
    rows.eraseIndex(i);
117 130
    rows.relocateIndex(i, rows.maxIndex());
118 131
  }
119 132

	
120 133
  void SoplexLp::_getColName(int c, std::string &name) const {
121 134
    name = _col_names[c];
122 135
  }
123 136

	
124 137
  void SoplexLp::_setColName(int c, const std::string &name) {
125 138
    _col_names_ref.erase(_col_names[c]);
126 139
    _col_names[c] = name;
127 140
    if (!name.empty()) {
128 141
      _col_names_ref.insert(std::make_pair(name, c));
129 142
    }
130 143
  }
131 144

	
132 145
  int SoplexLp::_colByName(const std::string& name) const {
133 146
    std::map<std::string, int>::const_iterator it =
134 147
      _col_names_ref.find(name);
135 148
    if (it != _col_names_ref.end()) {
136 149
      return it->second;
137 150
    } else {
138 151
      return -1;
139 152
    }
140 153
  }
141 154

	
142 155
  void SoplexLp::_getRowName(int r, std::string &name) const {
143 156
    name = _row_names[r];
144 157
  }
145 158

	
146 159
  void SoplexLp::_setRowName(int r, const std::string &name) {
147 160
    _row_names_ref.erase(_row_names[r]);
148 161
    _row_names[r] = name;
149 162
    if (!name.empty()) {
150 163
      _row_names_ref.insert(std::make_pair(name, r));
151 164
    }
152 165
  }
153 166

	
154 167
  int SoplexLp::_rowByName(const std::string& name) const {
155 168
    std::map<std::string, int>::const_iterator it =
156 169
      _row_names_ref.find(name);
157 170
    if (it != _row_names_ref.end()) {
Ignore white space 6 line context
... ...
@@ -23,128 +23,129 @@
23 23
///\brief Header of the LEMON-SOPLEX lp solver interface.
24 24

	
25 25
#include <vector>
26 26
#include <string>
27 27

	
28 28
#include <lemon/lp_base.h>
29 29

	
30 30
// Forward declaration
31 31
namespace soplex {
32 32
  class SoPlex;
33 33
}
34 34

	
35 35
namespace lemon {
36 36

	
37 37
  /// \ingroup lp_group
38 38
  ///
39 39
  /// \brief Interface for the SOPLEX solver
40 40
  ///
41 41
  /// This class implements an interface for the SoPlex LP solver.
42 42
  /// The SoPlex library is an object oriented lp solver library
43 43
  /// developed at the Konrad-Zuse-Zentrum f�r Informationstechnik
44 44
  /// Berlin (ZIB). You can find detailed information about it at the
45 45
  /// <tt>http://soplex.zib.de</tt> address.
46 46
  class SoplexLp : public LpSolver {
47 47
  private:
48 48

	
49 49
    soplex::SoPlex* soplex;
50 50

	
51 51
    std::vector<std::string> _col_names;
52 52
    std::map<std::string, int> _col_names_ref;
53 53

	
54 54
    std::vector<std::string> _row_names;
55 55
    std::map<std::string, int> _row_names_ref;
56 56

	
57 57
  private:
58 58

	
59 59
    // these values cannot be retrieved element by element
60 60
    mutable std::vector<Value> _primal_values;
61 61
    mutable std::vector<Value> _dual_values;
62 62

	
63 63
    mutable std::vector<Value> _primal_ray;
64 64
    mutable std::vector<Value> _dual_ray;
65 65

	
66 66
    void _clear_temporals();
67 67

	
68 68
  public:
69 69

	
70 70
    /// \e
71 71
    SoplexLp();
72 72
    /// \e
73 73
    SoplexLp(const SoplexLp&);
74 74
    /// \e
75 75
    ~SoplexLp();
76 76
    /// \e
77 77
    virtual SoplexLp* newSolver() const;
78 78
    /// \e
79 79
    virtual SoplexLp* cloneSolver() const;
80 80

	
81 81
  protected:
82 82

	
83 83
    virtual const char* _solverName() const;
84 84

	
85 85
    virtual int _addCol();
86 86
    virtual int _addRow();
87
    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
87 88

	
88 89
    virtual void _eraseCol(int i);
89 90
    virtual void _eraseRow(int i);
90 91

	
91 92
    virtual void _eraseColId(int i);
92 93
    virtual void _eraseRowId(int i);
93 94

	
94 95
    virtual void _getColName(int col, std::string& name) const;
95 96
    virtual void _setColName(int col, const std::string& name);
96 97
    virtual int _colByName(const std::string& name) const;
97 98

	
98 99
    virtual void _getRowName(int row, std::string& name) const;
99 100
    virtual void _setRowName(int row, const std::string& name);
100 101
    virtual int _rowByName(const std::string& name) const;
101 102

	
102 103
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
103 104
    virtual void _getRowCoeffs(int i, InsertIterator b) const;
104 105

	
105 106
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
106 107
    virtual void _getColCoeffs(int i, InsertIterator b) const;
107 108

	
108 109
    virtual void _setCoeff(int row, int col, Value value);
109 110
    virtual Value _getCoeff(int row, int col) const;
110 111

	
111 112
    virtual void _setColLowerBound(int i, Value value);
112 113
    virtual Value _getColLowerBound(int i) const;
113 114
    virtual void _setColUpperBound(int i, Value value);
114 115
    virtual Value _getColUpperBound(int i) const;
115 116

	
116 117
    virtual void _setRowLowerBound(int i, Value value);
117 118
    virtual Value _getRowLowerBound(int i) const;
118 119
    virtual void _setRowUpperBound(int i, Value value);
119 120
    virtual Value _getRowUpperBound(int i) const;
120 121

	
121 122
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
122 123
    virtual void _getObjCoeffs(InsertIterator b) const;
123 124

	
124 125
    virtual void _setObjCoeff(int i, Value obj_coef);
125 126
    virtual Value _getObjCoeff(int i) const;
126 127

	
127 128
    virtual void _setSense(Sense sense);
128 129
    virtual Sense _getSense() const;
129 130

	
130 131
    virtual SolveExitStatus _solve();
131 132
    virtual Value _getPrimal(int i) const;
132 133
    virtual Value _getDual(int i) const;
133 134

	
134 135
    virtual Value _getPrimalValue() const;
135 136

	
136 137
    virtual Value _getPrimalRay(int i) const;
137 138
    virtual Value _getDualRay(int i) const;
138 139

	
139 140
    virtual VarStatus _getColStatus(int i) const;
140 141
    virtual VarStatus _getRowStatus(int i) const;
141 142

	
142 143
    virtual ProblemType _getPrimalType() const;
143 144
    virtual ProblemType _getDualType() const;
144 145

	
145 146
    virtual void _clear();
146 147

	
147 148
    void _messageLevel(MessageLevel m);
148 149
    void _applyMessageLevel();
149 150

	
150 151
    int _message_level;
Ignore white space 6 line context
... ...
@@ -27,110 +27,110 @@
27 27
      CLP_LDFLAGS="-L$with_coin_libdir"
28 28
    elif test x"$with_coin" != x"yes"; then
29 29
      CLP_LDFLAGS="-L$with_coin/lib"
30 30
    fi
31 31
    CLP_LIBS="-lClp -lCoinUtils -lm"
32 32

	
33 33
    lx_save_cxxflags="$CXXFLAGS"
34 34
    lx_save_ldflags="$LDFLAGS"
35 35
    lx_save_libs="$LIBS"
36 36
    CXXFLAGS="$CLP_CXXFLAGS"
37 37
    LDFLAGS="$CLP_LDFLAGS"
38 38
    LIBS="$CLP_LIBS"
39 39

	
40 40
    lx_clp_test_prog='
41 41
      #include <coin/ClpModel.hpp>
42 42

	
43 43
      int main(int argc, char** argv)
44 44
      {
45 45
        ClpModel clp;
46 46
        return 0;
47 47
      }'
48 48

	
49 49
    AC_LANG_PUSH(C++)
50 50
    AC_LINK_IFELSE([$lx_clp_test_prog], [lx_clp_found=yes], [lx_clp_found=no])
51 51
    AC_LANG_POP(C++)
52 52

	
53 53
    CXXFLAGS="$lx_save_cxxflags"
54 54
    LDFLAGS="$lx_save_ldflags"
55 55
    LIBS="$lx_save_libs"
56 56

	
57 57
    if test x"$lx_clp_found" = x"yes"; then
58 58
      AC_DEFINE([LEMON_HAVE_CLP], [1], [Define to 1 if you have CLP.])
59 59
      lx_lp_found=yes
60 60
      AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
61 61
      AC_MSG_RESULT([yes])
62 62
    else
63 63
      CLP_CXXFLAGS=""
64 64
      CLP_LDFLAGS=""
65 65
      CLP_LIBS=""
66 66
      AC_MSG_RESULT([no])
67 67
    fi
68 68
  fi
69 69
  CLP_LIBS="$CLP_LDFLAGS $CLP_LIBS"
70 70
  AC_SUBST(CLP_CXXFLAGS)
71 71
  AC_SUBST(CLP_LIBS)
72 72
  AM_CONDITIONAL([HAVE_CLP], [test x"$lx_clp_found" = x"yes"])
73 73

	
74 74

	
75 75
  lx_cbc_found=no
76 76
  if test x"$lx_clp_found" = x"yes"; then
77 77
    if test x"$with_coin" != x"no"; then
78 78
      AC_MSG_CHECKING([for CBC])
79 79

	
80 80
      if test x"$with_coin_includedir" != x"no"; then
81 81
        CBC_CXXFLAGS="-I$with_coin_includedir"
82 82
      elif test x"$with_coin" != x"yes"; then
83 83
        CBC_CXXFLAGS="-I$with_coin/include"
84 84
      fi
85 85

	
86 86
      if test x"$with_coin_libdir" != x"no"; then
87 87
        CBC_LDFLAGS="-L$with_coin_libdir"
88 88
      elif test x"$with_coin" != x"yes"; then
89 89
        CBC_LDFLAGS="-L$with_coin/lib"
90 90
      fi
91
      CBC_LIBS="-lOsi -lCbc -lOsiCbc -lCbcSolver -lClp -lOsiClp -lCoinUtils -lVol -lOsiVol -lCgl -lm -llapack -lblas"
91
      CBC_LIBS="-lOsi -lCbc -lCbcSolver -lClp -lOsiClp -lCoinUtils -lVol -lOsiVol -lCgl -lm -llapack -lblas"
92 92

	
93 93
      lx_save_cxxflags="$CXXFLAGS"
94 94
      lx_save_ldflags="$LDFLAGS"
95 95
      lx_save_libs="$LIBS"
96 96
      CXXFLAGS="$CBC_CXXFLAGS"
97 97
      LDFLAGS="$CBC_LDFLAGS"
98 98
      LIBS="$CBC_LIBS"
99 99

	
100 100
      lx_cbc_test_prog='
101 101
        #include <coin/CbcModel.hpp>
102 102

	
103 103
        int main(int argc, char** argv)
104 104
        {
105 105
          CbcModel cbc;
106 106
          return 0;
107 107
        }'
108 108

	
109 109
      AC_LANG_PUSH(C++)
110 110
      AC_LINK_IFELSE([$lx_cbc_test_prog], [lx_cbc_found=yes], [lx_cbc_found=no])
111 111
      AC_LANG_POP(C++)
112 112

	
113 113
      CXXFLAGS="$lx_save_cxxflags"
114 114
      LDFLAGS="$lx_save_ldflags"
115 115
      LIBS="$lx_save_libs"
116 116

	
117 117
      if test x"$lx_cbc_found" = x"yes"; then
118 118
        AC_DEFINE([LEMON_HAVE_CBC], [1], [Define to 1 if you have CBC.])
119 119
        lx_lp_found=yes
120 120
        AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
121 121
        lx_mip_found=yes
122 122
        AC_DEFINE([LEMON_HAVE_MIP], [1], [Define to 1 if you have any MIP solver.])
123 123
        AC_MSG_RESULT([yes])
124 124
      else
125 125
        CBC_CXXFLAGS=""
126 126
        CBC_LDFLAGS=""
127 127
        CBC_LIBS=""
128 128
        AC_MSG_RESULT([no])
129 129
      fi
130 130
    fi
131 131
  fi
132 132
  CBC_LIBS="$CBC_LDFLAGS $CBC_LIBS"
133 133
  AC_SUBST(CBC_CXXFLAGS)
134 134
  AC_SUBST(CBC_LIBS)
135 135
  AM_CONDITIONAL([HAVE_CBC], [test x"$lx_cbc_found" = x"yes"])
136 136
])
Ignore white space 6 line context
1 1
#! /usr/bin/env python
2
#
3
# This file is a part of LEMON, a generic C++ optimization library.
4
#
5
# Copyright (C) 2003-2009
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.
2 16

	
3 17
import sys
4 18

	
5 19
from mercurial import ui, hg
6 20
from mercurial import util
7 21

	
8 22
util.rcpath = lambda : []
9 23

	
10 24
if len(sys.argv)>1 and sys.argv[1] in ["-h","--help"]:
11 25
    print """
12 26
This utility just prints the length of the longest path
13 27
in the revision graph from revison 0 to the current one.
14 28
"""
15 29
    exit(0)
16 30

	
17 31
u = ui.ui()
18 32
r = hg.repository(u, ".")
19 33
N = r.changectx(".").rev()
20 34
lengths=[0]*(N+1)
21 35
for i in range(N+1):
22 36
    p=r.changectx(i).parents()
23 37
    if p[0]:
24 38
        p0=lengths[p[0].rev()]
25 39
    else:
26 40
        p0=-1
27 41
    if len(p)>1 and p[1]:
28 42
        p1=lengths[p[1].rev()]
29 43
    else:
30 44
        p1=-1
31 45
    lengths[i]=max(p0,p1)+1
32 46
print lengths[N]
Ignore white space 6 line context
1 1
#!/bin/bash
2
#
3
# This file is a part of LEMON, a generic C++ optimization library.
4
#
5
# Copyright (C) 2003-2009
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.
2 16

	
3 17
set -e
4 18

	
5 19
if [ $# = 0 ]; then
6 20
    echo "Usage: $0 release-id"
7 21
    exit 1
8 22
else
9 23
    export LEMON_VERSION=$1
10 24
fi
11 25

	
12 26
echo '*****************************************************************'
13 27
echo ' Start making release tarballs for version '${LEMON_VERSION}
14 28
echo '*****************************************************************'
15 29

	
16 30
autoreconf -vif
17 31
./configure
18 32

	
19 33
make
20 34
make html
21 35
make distcheck
22 36
tar xf lemon-${LEMON_VERSION}.tar.gz
23 37
zip -r lemon-${LEMON_VERSION}.zip lemon-${LEMON_VERSION}
24 38
mv lemon-${LEMON_VERSION}/doc/html lemon-doc-${LEMON_VERSION}
25 39
tar czf lemon-doc-${LEMON_VERSION}.tar.gz lemon-doc-${LEMON_VERSION}
26 40
zip -r lemon-doc-${LEMON_VERSION}.zip lemon-doc-${LEMON_VERSION}
27 41
tar czf lemon-nodoc-${LEMON_VERSION}.tar.gz lemon-${LEMON_VERSION}
28 42
zip -r lemon-nodoc-${LEMON_VERSION}.zip lemon-${LEMON_VERSION}
29 43
hg tag -m 'LEMON '${LEMON_VERSION}' released ('$(hg par --template="{node|short}")' tagged as r'${LEMON_VERSION}')' r${LEMON_VERSION}
30 44

	
31 45
rm -rf lemon-${LEMON_VERSION} lemon-doc-${LEMON_VERSION}
32 46

	
33 47
echo '*****************************************************************'
34 48
echo '  Release '${LEMON_VERSION}' has been created' 
35 49
echo '*****************************************************************'
Ignore white space 6 line context
1 1
#!/bin/bash
2
#
3
# This file is a part of LEMON, a generic C++ optimization library.
4
#
5
# Copyright (C) 2003-2009
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.
2 16

	
3 17
YEAR=`date +%Y`
4 18
HGROOT=`hg root`
5 19

	
6 20
function hg_year() {
7 21
    if [ -n "$(hg st $1)" ]; then
8 22
        echo $YEAR
9 23
    else
10 24
        hg log -l 1 --template='{date|isodate}\n' $1 |
11 25
        cut -d '-' -f 1
12 26
    fi
13 27
}
14 28

	
15 29
# file enumaration modes
16 30

	
17 31
function all_files() {
18 32
    hg status -a -m -c |
19 33
    cut -d ' ' -f 2 | grep -E '(\.(cc|h|dox)$|Makefile\.am$)' |
20 34
    while read file; do echo $HGROOT/$file; done
21 35
}
22 36

	
23 37
function modified_files() {
24 38
    hg status -a -m |
25 39
    cut -d ' ' -f 2 | grep -E  '(\.(cc|h|dox)$|Makefile\.am$)' |
26 40
    while read file; do echo $HGROOT/$file; done
27 41
}
28 42

	
29 43
function changed_files() {
30 44
    {
31 45
        if [ -n "$HG_PARENT1" ]
32 46
        then
33 47
            hg status --rev $HG_PARENT1:$HG_NODE -a -m
34 48
        fi
35 49
        if [ -n "$HG_PARENT2" ]
36 50
        then
37 51
            hg status --rev $HG_PARENT2:$HG_NODE -a -m
38 52
        fi
39 53
    } | cut -d ' ' -f 2 | grep -E '(\.(cc|h|dox)$|Makefile\.am$)' | 
40 54
    sort | uniq |
41 55
    while read file; do echo $HGROOT/$file; done
42 56
}
43 57

	
44 58
function given_files() {
45 59
    for file in $GIVEN_FILES
46 60
    do
47 61
	echo $file
48 62
    done
49 63
}
50 64

	
51 65
# actions
52 66

	
53 67
function update_action() {
54 68
    if ! diff -q $1 $2 >/dev/null
55 69
    then
56 70
	echo -n " [$3 updated]"
57 71
	rm $2
58 72
	mv $1 $2
59 73
	CHANGED=YES
60 74
    fi
61 75
}
62 76

	
63 77
function update_warning() {
64 78
    echo -n " [$2 warning]"
65 79
    WARNED=YES
Ignore white space 128 line context
1 1
INCLUDE_DIRECTORIES(
2 2
  ${PROJECT_SOURCE_DIR}
3 3
  ${PROJECT_BINARY_DIR}
4 4
)
5 5

	
6 6
LINK_DIRECTORIES(
7 7
  ${PROJECT_BINARY_DIR}/lemon
8 8
)
9 9

	
10 10
SET(TESTS
11 11
  adaptors_test
12 12
  bellman_ford_test
13 13
  bfs_test
14 14
  circulation_test
15 15
  connectivity_test
16 16
  counter_test
17 17
  dfs_test
18 18
  digraph_test
19 19
  dijkstra_test
20 20
  dim_test
21 21
  edge_set_test
22 22
  error_test
23 23
  euler_test
24 24
  gomory_hu_test
25 25
  graph_copy_test
26 26
  graph_test
27 27
  graph_utils_test
28 28
  hao_orlin_test
29 29
  heap_test
30 30
  kruskal_test
31 31
  maps_test
32 32
  matching_test
33 33
  min_cost_arborescence_test
34 34
  min_cost_flow_test
35
  min_mean_cycle_test
35 36
  path_test
36 37
  preflow_test
37 38
  radix_sort_test
38 39
  random_test
39 40
  suurballe_test
40 41
  time_measure_test
41 42
  unionfind_test
42 43
)
43 44

	
44 45
IF(LEMON_HAVE_LP)
45 46
  ADD_EXECUTABLE(lp_test lp_test.cc)
46 47
  SET(LP_TEST_LIBS lemon)
47 48

	
48 49
  IF(LEMON_HAVE_GLPK)
49 50
    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${GLPK_LIBRARIES})
50 51
  ENDIF()
51 52
  IF(LEMON_HAVE_CPLEX)
52 53
    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${CPLEX_LIBRARIES})
53 54
  ENDIF()
54 55
  IF(LEMON_HAVE_CLP)
55 56
    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${COIN_CLP_LIBRARIES})
56 57
  ENDIF()
57 58

	
58 59
  TARGET_LINK_LIBRARIES(lp_test ${LP_TEST_LIBS})
59 60
  ADD_TEST(lp_test lp_test)
60 61

	
61 62
  IF(WIN32 AND LEMON_HAVE_GLPK)
62 63
    GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
63 64
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
64 65
    ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
65 66
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
66 67
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
67 68
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
68 69
    )
69 70
  ENDIF()
70 71

	
71 72
  IF(WIN32 AND LEMON_HAVE_CPLEX)
72 73
    GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
73 74
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
74 75
    ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
75 76
      COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex91.dll ${TARGET_PATH}
76 77
    )
77 78
  ENDIF()
78 79
ENDIF()
79 80

	
80 81
IF(LEMON_HAVE_MIP)
81 82
  ADD_EXECUTABLE(mip_test mip_test.cc)
82 83
  SET(MIP_TEST_LIBS lemon)
83 84

	
84 85
  IF(LEMON_HAVE_GLPK)
85 86
    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${GLPK_LIBRARIES})
86 87
  ENDIF()
87 88
  IF(LEMON_HAVE_CPLEX)
88 89
    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${CPLEX_LIBRARIES})
89 90
  ENDIF()
90 91
  IF(LEMON_HAVE_CBC)
91 92
    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${COIN_CBC_LIBRARIES})
92 93
  ENDIF()
93 94

	
94 95
  TARGET_LINK_LIBRARIES(mip_test ${MIP_TEST_LIBS})
95 96
  ADD_TEST(mip_test mip_test)
96 97

	
97 98
  IF(WIN32 AND LEMON_HAVE_GLPK)
98 99
    GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
Ignore white space 6 line context
1 1
EXTRA_DIST += \
2 2
	test/CMakeLists.txt
3 3

	
4 4
noinst_HEADERS += \
5 5
	test/graph_test.h \
6 6
	test/test_tools.h
7 7

	
8 8
check_PROGRAMS += \
9 9
	test/adaptors_test \
10 10
	test/bellman_ford_test \
11 11
	test/bfs_test \
12 12
	test/circulation_test \
13 13
	test/connectivity_test \
14 14
	test/counter_test \
15 15
	test/dfs_test \
16 16
	test/digraph_test \
17 17
	test/dijkstra_test \
18 18
	test/dim_test \
19 19
	test/edge_set_test \
20 20
	test/error_test \
21 21
	test/euler_test \
22 22
	test/gomory_hu_test \
23 23
	test/graph_copy_test \
24 24
	test/graph_test \
25 25
	test/graph_utils_test \
26 26
	test/hao_orlin_test \
27 27
	test/heap_test \
28 28
	test/kruskal_test \
29 29
	test/maps_test \
30 30
	test/matching_test \
31 31
	test/min_cost_arborescence_test \
32 32
	test/min_cost_flow_test \
33
	test/min_mean_cycle_test \
33 34
	test/path_test \
34 35
	test/preflow_test \
35 36
	test/radix_sort_test \
36 37
	test/random_test \
37 38
	test/suurballe_test \
38 39
	test/test_tools_fail \
39 40
	test/test_tools_pass \
40 41
	test/time_measure_test \
41 42
	test/unionfind_test
42 43

	
43 44
test_test_tools_pass_DEPENDENCIES = demo
44 45

	
45 46
if HAVE_LP
46 47
check_PROGRAMS += test/lp_test
47 48
endif HAVE_LP
48 49
if HAVE_MIP
49 50
check_PROGRAMS += test/mip_test
50 51
endif HAVE_MIP
51 52

	
52 53
TESTS += $(check_PROGRAMS)
53 54
XFAIL_TESTS += test/test_tools_fail$(EXEEXT)
54 55

	
55 56
test_adaptors_test_SOURCES = test/adaptors_test.cc
56 57
test_bellman_ford_test_SOURCES = test/bellman_ford_test.cc
57 58
test_bfs_test_SOURCES = test/bfs_test.cc
58 59
test_circulation_test_SOURCES = test/circulation_test.cc
59 60
test_counter_test_SOURCES = test/counter_test.cc
60 61
test_connectivity_test_SOURCES = test/connectivity_test.cc
61 62
test_dfs_test_SOURCES = test/dfs_test.cc
62 63
test_digraph_test_SOURCES = test/digraph_test.cc
63 64
test_dijkstra_test_SOURCES = test/dijkstra_test.cc
64 65
test_dim_test_SOURCES = test/dim_test.cc
65 66
test_edge_set_test_SOURCES = test/edge_set_test.cc
66 67
test_error_test_SOURCES = test/error_test.cc
67 68
test_euler_test_SOURCES = test/euler_test.cc
68 69
test_gomory_hu_test_SOURCES = test/gomory_hu_test.cc
69 70
test_graph_copy_test_SOURCES = test/graph_copy_test.cc
70 71
test_graph_test_SOURCES = test/graph_test.cc
71 72
test_graph_utils_test_SOURCES = test/graph_utils_test.cc
72 73
test_heap_test_SOURCES = test/heap_test.cc
73 74
test_kruskal_test_SOURCES = test/kruskal_test.cc
74 75
test_hao_orlin_test_SOURCES = test/hao_orlin_test.cc
75 76
test_lp_test_SOURCES = test/lp_test.cc
76 77
test_maps_test_SOURCES = test/maps_test.cc
77 78
test_mip_test_SOURCES = test/mip_test.cc
78 79
test_matching_test_SOURCES = test/matching_test.cc
79 80
test_min_cost_arborescence_test_SOURCES = test/min_cost_arborescence_test.cc
80 81
test_min_cost_flow_test_SOURCES = test/min_cost_flow_test.cc
82
test_min_mean_cycle_test_SOURCES = test/min_mean_cycle_test.cc
81 83
test_path_test_SOURCES = test/path_test.cc
82 84
test_preflow_test_SOURCES = test/preflow_test.cc
83 85
test_radix_sort_test_SOURCES = test/radix_sort_test.cc
84 86
test_suurballe_test_SOURCES = test/suurballe_test.cc
85 87
test_random_test_SOURCES = test/random_test.cc
86 88
test_test_tools_fail_SOURCES = test/test_tools_fail.cc
87 89
test_test_tools_pass_SOURCES = test/test_tools_pass.cc
88 90
test_time_measure_test_SOURCES = test/time_measure_test.cc
89 91
test_unionfind_test_SOURCES = test/unionfind_test.cc
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <lemon/concepts/digraph.h>
20 20
#include <lemon/list_graph.h>
21 21
#include <lemon/smart_graph.h>
22
#include <lemon/static_graph.h>
22 23
#include <lemon/full_graph.h>
23 24

	
24 25
#include "test_tools.h"
25 26
#include "graph_test.h"
26 27

	
27 28
using namespace lemon;
28 29
using namespace lemon::concepts;
29 30

	
30 31
template <class Digraph>
31 32
void checkDigraphBuild() {
32 33
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
33 34
  Digraph G;
34 35

	
35 36
  checkGraphNodeList(G, 0);
36 37
  checkGraphArcList(G, 0);
37 38

	
39
  G.reserveNode(3);
40
  G.reserveArc(4);
41

	
38 42
  Node
39 43
    n1 = G.addNode(),
40 44
    n2 = G.addNode(),
41 45
    n3 = G.addNode();
42 46
  checkGraphNodeList(G, 3);
43 47
  checkGraphArcList(G, 0);
44 48

	
45 49
  Arc a1 = G.addArc(n1, n2);
46 50
  check(G.source(a1) == n1 && G.target(a1) == n2, "Wrong arc");
47 51
  checkGraphNodeList(G, 3);
48 52
  checkGraphArcList(G, 1);
49 53

	
50 54
  checkGraphOutArcList(G, n1, 1);
51 55
  checkGraphOutArcList(G, n2, 0);
52 56
  checkGraphOutArcList(G, n3, 0);
53 57

	
54 58
  checkGraphInArcList(G, n1, 0);
55 59
  checkGraphInArcList(G, n2, 1);
56 60
  checkGraphInArcList(G, n3, 0);
57 61

	
58 62
  checkGraphConArcList(G, 1);
59 63

	
60 64
  Arc a2 = G.addArc(n2, n1),
61 65
      a3 = G.addArc(n2, n3),
62 66
      a4 = G.addArc(n2, n3);
63 67

	
64 68
  checkGraphNodeList(G, 3);
65 69
  checkGraphArcList(G, 4);
66 70

	
67 71
  checkGraphOutArcList(G, n1, 1);
68 72
  checkGraphOutArcList(G, n2, 3);
69 73
  checkGraphOutArcList(G, n3, 0);
70 74

	
71 75
  checkGraphInArcList(G, n1, 1);
72 76
  checkGraphInArcList(G, n2, 1);
73 77
  checkGraphInArcList(G, n3, 2);
74 78

	
75 79
  checkGraphConArcList(G, 4);
76 80

	
77 81
  checkNodeIds(G);
78 82
  checkArcIds(G);
79 83
  checkGraphNodeMap(G);
80 84
  checkGraphArcMap(G);
81 85
}
82 86

	
83 87
template <class Digraph>
84 88
void checkDigraphSplit() {
85 89
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
86 90

	
87 91
  Digraph G;
88 92
  Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
89 93
  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1),
90 94
      a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
91 95

	
92 96
  Node n4 = G.split(n2);
93 97

	
94 98
  check(G.target(OutArcIt(G, n2)) == n4 &&
95 99
        G.source(InArcIt(G, n4)) == n2,
96 100
        "Wrong split.");
97 101

	
98 102
  checkGraphNodeList(G, 4);
99 103
  checkGraphArcList(G, 5);
100 104

	
101 105
  checkGraphOutArcList(G, n1, 1);
... ...
@@ -222,210 +226,337 @@
222 226
  // Check node deletion
223 227
  G.erase(n4);
224 228

	
225 229
  checkGraphNodeList(G, 3);
226 230
  checkGraphArcList(G, 1);
227 231

	
228 232
  checkGraphOutArcList(G, n1, 0);
229 233
  checkGraphOutArcList(G, n2, 0);
230 234
  checkGraphOutArcList(G, n3, 1);
231 235
  checkGraphOutArcList(G, n4, 0);
232 236

	
233 237
  checkGraphInArcList(G, n1, 1);
234 238
  checkGraphInArcList(G, n2, 0);
235 239
  checkGraphInArcList(G, n3, 0);
236 240
  checkGraphInArcList(G, n4, 0);
237 241

	
238 242
  checkGraphConArcList(G, 1);
239 243
}
240 244

	
241 245

	
242 246
template <class Digraph>
243 247
void checkDigraphSnapshot() {
244 248
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
245 249

	
246 250
  Digraph G;
247 251
  Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
248 252
  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1),
249 253
      a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
250 254

	
251 255
  typename Digraph::Snapshot snapshot(G);
252 256

	
253 257
  Node n = G.addNode();
254 258
  G.addArc(n3, n);
255 259
  G.addArc(n, n3);
256 260

	
257 261
  checkGraphNodeList(G, 4);
258 262
  checkGraphArcList(G, 6);
259 263

	
260 264
  snapshot.restore();
261 265

	
262 266
  checkGraphNodeList(G, 3);
263 267
  checkGraphArcList(G, 4);
264 268

	
265 269
  checkGraphOutArcList(G, n1, 1);
266 270
  checkGraphOutArcList(G, n2, 3);
267 271
  checkGraphOutArcList(G, n3, 0);
268 272

	
269 273
  checkGraphInArcList(G, n1, 1);
270 274
  checkGraphInArcList(G, n2, 1);
271 275
  checkGraphInArcList(G, n3, 2);
272 276

	
273 277
  checkGraphConArcList(G, 4);
274 278

	
275 279
  checkNodeIds(G);
276 280
  checkArcIds(G);
277 281
  checkGraphNodeMap(G);
278 282
  checkGraphArcMap(G);
279 283

	
280 284
  G.addNode();
281 285
  snapshot.save(G);
282 286

	
283 287
  G.addArc(G.addNode(), G.addNode());
284 288

	
285 289
  snapshot.restore();
290
  snapshot.save(G);
291

	
292
  checkGraphNodeList(G, 4);
293
  checkGraphArcList(G, 4);
294

	
295
  G.addArc(G.addNode(), G.addNode());
296

	
297
  snapshot.restore();
286 298

	
287 299
  checkGraphNodeList(G, 4);
288 300
  checkGraphArcList(G, 4);
289 301
}
290 302

	
291 303
void checkConcepts() {
292 304
  { // Checking digraph components
293 305
    checkConcept<BaseDigraphComponent, BaseDigraphComponent >();
294 306

	
295 307
    checkConcept<IDableDigraphComponent<>,
296 308
      IDableDigraphComponent<> >();
297 309

	
298 310
    checkConcept<IterableDigraphComponent<>,
299 311
      IterableDigraphComponent<> >();
300 312

	
301 313
    checkConcept<MappableDigraphComponent<>,
302 314
      MappableDigraphComponent<> >();
303 315
  }
304 316
  { // Checking skeleton digraph
305 317
    checkConcept<Digraph, Digraph>();
306 318
  }
307 319
  { // Checking ListDigraph
308 320
    checkConcept<Digraph, ListDigraph>();
309 321
    checkConcept<AlterableDigraphComponent<>, ListDigraph>();
310 322
    checkConcept<ExtendableDigraphComponent<>, ListDigraph>();
311 323
    checkConcept<ClearableDigraphComponent<>, ListDigraph>();
312 324
    checkConcept<ErasableDigraphComponent<>, ListDigraph>();
313 325
  }
314 326
  { // Checking SmartDigraph
315 327
    checkConcept<Digraph, SmartDigraph>();
316 328
    checkConcept<AlterableDigraphComponent<>, SmartDigraph>();
317 329
    checkConcept<ExtendableDigraphComponent<>, SmartDigraph>();
318 330
    checkConcept<ClearableDigraphComponent<>, SmartDigraph>();
319 331
  }
332
  { // Checking StaticDigraph
333
    checkConcept<Digraph, StaticDigraph>();
334
    checkConcept<ClearableDigraphComponent<>, StaticDigraph>();
335
  }
320 336
  { // Checking FullDigraph
321 337
    checkConcept<Digraph, FullDigraph>();
322 338
  }
323 339
}
324 340

	
325 341
template <typename Digraph>
326 342
void checkDigraphValidity() {
327 343
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
328 344
  Digraph g;
329 345

	
330 346
  Node
331 347
    n1 = g.addNode(),
332 348
    n2 = g.addNode(),
333 349
    n3 = g.addNode();
334 350

	
335 351
  Arc
336 352
    e1 = g.addArc(n1, n2),
337 353
    e2 = g.addArc(n2, n3);
338 354

	
339 355
  check(g.valid(n1), "Wrong validity check");
340 356
  check(g.valid(e1), "Wrong validity check");
341 357

	
342 358
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
343 359
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
344 360
}
345 361

	
346 362
template <typename Digraph>
347 363
void checkDigraphValidityErase() {
348 364
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
349 365
  Digraph g;
350 366

	
351 367
  Node
352 368
    n1 = g.addNode(),
353 369
    n2 = g.addNode(),
354 370
    n3 = g.addNode();
355 371

	
356 372
  Arc
357 373
    e1 = g.addArc(n1, n2),
358 374
    e2 = g.addArc(n2, n3);
359 375

	
360 376
  check(g.valid(n1), "Wrong validity check");
361 377
  check(g.valid(e1), "Wrong validity check");
362 378

	
363 379
  g.erase(n1);
364 380

	
365 381
  check(!g.valid(n1), "Wrong validity check");
366 382
  check(g.valid(n2), "Wrong validity check");
367 383
  check(g.valid(n3), "Wrong validity check");
368 384
  check(!g.valid(e1), "Wrong validity check");
369 385
  check(g.valid(e2), "Wrong validity check");
370 386

	
371 387
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
372 388
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
373 389
}
374 390

	
391
void checkStaticDigraph() {
392
  SmartDigraph g;
393
  SmartDigraph::NodeMap<StaticDigraph::Node> nref(g);
394
  SmartDigraph::ArcMap<StaticDigraph::Arc> aref(g);
395
  
396
  StaticDigraph G;
397
  
398
  checkGraphNodeList(G, 0);
399
  checkGraphArcList(G, 0);
400

	
401
  G.build(g, nref, aref);
402

	
403
  checkGraphNodeList(G, 0);
404
  checkGraphArcList(G, 0);
405

	
406
  SmartDigraph::Node
407
    n1 = g.addNode(),
408
    n2 = g.addNode(),
409
    n3 = g.addNode();
410

	
411
  G.build(g, nref, aref);
412

	
413
  checkGraphNodeList(G, 3);
414
  checkGraphArcList(G, 0);
415

	
416
  SmartDigraph::Arc a1 = g.addArc(n1, n2);
417

	
418
  G.build(g, nref, aref);
419

	
420
  check(G.source(aref[a1]) == nref[n1] && G.target(aref[a1]) == nref[n2],
421
        "Wrong arc or wrong references");
422
  checkGraphNodeList(G, 3);
423
  checkGraphArcList(G, 1);
424

	
425
  checkGraphOutArcList(G, nref[n1], 1);
426
  checkGraphOutArcList(G, nref[n2], 0);
427
  checkGraphOutArcList(G, nref[n3], 0);
428

	
429
  checkGraphInArcList(G, nref[n1], 0);
430
  checkGraphInArcList(G, nref[n2], 1);
431
  checkGraphInArcList(G, nref[n3], 0);
432

	
433
  checkGraphConArcList(G, 1);
434

	
435
  SmartDigraph::Arc
436
    a2 = g.addArc(n2, n1),
437
    a3 = g.addArc(n2, n3),
438
    a4 = g.addArc(n2, n3);
439

	
440
  digraphCopy(g, G).nodeRef(nref).run();
441

	
442
  checkGraphNodeList(G, 3);
443
  checkGraphArcList(G, 4);
444

	
445
  checkGraphOutArcList(G, nref[n1], 1);
446
  checkGraphOutArcList(G, nref[n2], 3);
447
  checkGraphOutArcList(G, nref[n3], 0);
448

	
449
  checkGraphInArcList(G, nref[n1], 1);
450
  checkGraphInArcList(G, nref[n2], 1);
451
  checkGraphInArcList(G, nref[n3], 2);
452

	
453
  checkGraphConArcList(G, 4);
454

	
455
  std::vector<std::pair<int,int> > arcs;
456
  arcs.push_back(std::make_pair(0,1));
457
  arcs.push_back(std::make_pair(0,2));
458
  arcs.push_back(std::make_pair(1,3));
459
  arcs.push_back(std::make_pair(1,2));
460
  arcs.push_back(std::make_pair(3,0));
461
  arcs.push_back(std::make_pair(3,3));
462
  arcs.push_back(std::make_pair(4,2));
463
  arcs.push_back(std::make_pair(4,3));
464
  arcs.push_back(std::make_pair(4,1));
465

	
466
  G.build(6, arcs.begin(), arcs.end());
467
  
468
  checkGraphNodeList(G, 6);
469
  checkGraphArcList(G, 9);
470

	
471
  checkGraphOutArcList(G, G.node(0), 2);
472
  checkGraphOutArcList(G, G.node(1), 2);
473
  checkGraphOutArcList(G, G.node(2), 0);
474
  checkGraphOutArcList(G, G.node(3), 2);
475
  checkGraphOutArcList(G, G.node(4), 3);
476
  checkGraphOutArcList(G, G.node(5), 0);
477

	
478
  checkGraphInArcList(G, G.node(0), 1);
479
  checkGraphInArcList(G, G.node(1), 2);
480
  checkGraphInArcList(G, G.node(2), 3);
481
  checkGraphInArcList(G, G.node(3), 3);
482
  checkGraphInArcList(G, G.node(4), 0);
483
  checkGraphInArcList(G, G.node(5), 0);
484

	
485
  checkGraphConArcList(G, 9);
486

	
487
  checkNodeIds(G);
488
  checkArcIds(G);
489
  checkGraphNodeMap(G);
490
  checkGraphArcMap(G);
491
  
492
  int n = G.nodeNum();
493
  int m = G.arcNum();
494
  check(G.index(G.node(n-1)) == n-1, "Wrong index.");
495
  check(G.index(G.arc(m-1)) == m-1, "Wrong index.");
496
}
497

	
375 498
void checkFullDigraph(int num) {
376 499
  typedef FullDigraph Digraph;
377 500
  DIGRAPH_TYPEDEFS(Digraph);
501

	
378 502
  Digraph G(num);
503
  check(G.nodeNum() == num && G.arcNum() == num * num, "Wrong size");
504

	
505
  G.resize(num);
506
  check(G.nodeNum() == num && G.arcNum() == num * num, "Wrong size");
379 507

	
380 508
  checkGraphNodeList(G, num);
381 509
  checkGraphArcList(G, num * num);
382 510

	
383 511
  for (NodeIt n(G); n != INVALID; ++n) {
384 512
    checkGraphOutArcList(G, n, num);
385 513
    checkGraphInArcList(G, n, num);
386 514
  }
387 515

	
388 516
  checkGraphConArcList(G, num * num);
389 517

	
390 518
  checkNodeIds(G);
391 519
  checkArcIds(G);
392 520
  checkGraphNodeMap(G);
393 521
  checkGraphArcMap(G);
394 522

	
395 523
  for (int i = 0; i < G.nodeNum(); ++i) {
396 524
    check(G.index(G(i)) == i, "Wrong index");
397 525
  }
398 526

	
399 527
  for (NodeIt s(G); s != INVALID; ++s) {
400 528
    for (NodeIt t(G); t != INVALID; ++t) {
401 529
      Arc a = G.arc(s, t);
402 530
      check(G.source(a) == s && G.target(a) == t, "Wrong arc lookup");
403 531
    }
404 532
  }
405 533
}
406 534

	
407 535
void checkDigraphs() {
408 536
  { // Checking ListDigraph
409 537
    checkDigraphBuild<ListDigraph>();
410 538
    checkDigraphSplit<ListDigraph>();
411 539
    checkDigraphAlter<ListDigraph>();
412 540
    checkDigraphErase<ListDigraph>();
413 541
    checkDigraphSnapshot<ListDigraph>();
414 542
    checkDigraphValidityErase<ListDigraph>();
415 543
  }
416 544
  { // Checking SmartDigraph
417 545
    checkDigraphBuild<SmartDigraph>();
418 546
    checkDigraphSplit<SmartDigraph>();
419 547
    checkDigraphSnapshot<SmartDigraph>();
420 548
    checkDigraphValidity<SmartDigraph>();
421 549
  }
550
  { // Checking StaticDigraph
551
    checkStaticDigraph();
552
  }
422 553
  { // Checking FullDigraph
423 554
    checkFullDigraph(8);
424 555
  }
425 556
}
426 557

	
427 558
int main() {
428 559
  checkDigraphs();
429 560
  checkConcepts();
430 561
  return 0;
431 562
}
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <lemon/concepts/graph.h>
20 20
#include <lemon/list_graph.h>
21 21
#include <lemon/smart_graph.h>
22 22
#include <lemon/full_graph.h>
23 23
#include <lemon/grid_graph.h>
24 24
#include <lemon/hypercube_graph.h>
25 25

	
26 26
#include "test_tools.h"
27 27
#include "graph_test.h"
28 28

	
29 29
using namespace lemon;
30 30
using namespace lemon::concepts;
31 31

	
32 32
template <class Graph>
33 33
void checkGraphBuild() {
34 34
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
35 35

	
36 36
  Graph G;
37 37
  checkGraphNodeList(G, 0);
38 38
  checkGraphEdgeList(G, 0);
39 39
  checkGraphArcList(G, 0);
40 40

	
41
  G.reserveNode(3);
42
  G.reserveEdge(3);
43

	
41 44
  Node
42 45
    n1 = G.addNode(),
43 46
    n2 = G.addNode(),
44 47
    n3 = G.addNode();
45 48
  checkGraphNodeList(G, 3);
46 49
  checkGraphEdgeList(G, 0);
47 50
  checkGraphArcList(G, 0);
48 51

	
49 52
  Edge e1 = G.addEdge(n1, n2);
50 53
  check((G.u(e1) == n1 && G.v(e1) == n2) || (G.u(e1) == n2 && G.v(e1) == n1),
51 54
        "Wrong edge");
52 55

	
53 56
  checkGraphNodeList(G, 3);
54 57
  checkGraphEdgeList(G, 1);
55 58
  checkGraphArcList(G, 2);
56 59

	
57 60
  checkGraphIncEdgeArcLists(G, n1, 1);
58 61
  checkGraphIncEdgeArcLists(G, n2, 1);
59 62
  checkGraphIncEdgeArcLists(G, n3, 0);
60 63

	
61 64
  checkGraphConEdgeList(G, 1);
62 65
  checkGraphConArcList(G, 2);
63 66

	
64 67
  Edge e2 = G.addEdge(n2, n1),
65 68
       e3 = G.addEdge(n2, n3);
66 69

	
67 70
  checkGraphNodeList(G, 3);
68 71
  checkGraphEdgeList(G, 3);
69 72
  checkGraphArcList(G, 6);
70 73

	
71 74
  checkGraphIncEdgeArcLists(G, n1, 2);
72 75
  checkGraphIncEdgeArcLists(G, n2, 3);
73 76
  checkGraphIncEdgeArcLists(G, n3, 1);
74 77

	
75 78
  checkGraphConEdgeList(G, 3);
76 79
  checkGraphConArcList(G, 6);
77 80

	
78 81
  checkArcDirections(G);
79 82

	
80 83
  checkNodeIds(G);
81 84
  checkArcIds(G);
82 85
  checkEdgeIds(G);
83 86
  checkGraphNodeMap(G);
84 87
  checkGraphArcMap(G);
85 88
  checkGraphEdgeMap(G);
86 89
}
87 90

	
88 91
template <class Graph>
89 92
void checkGraphAlter() {
90 93
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
91 94

	
92 95
  Graph G;
93 96
  Node n1 = G.addNode(), n2 = G.addNode(),
94 97
       n3 = G.addNode(), n4 = G.addNode();
95 98
  Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
96 99
       e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4),
97 100
       e5 = G.addEdge(n4, n3);
98 101

	
99 102
  checkGraphNodeList(G, 4);
100 103
  checkGraphEdgeList(G, 5);
101 104
  checkGraphArcList(G, 10);
102 105

	
103 106
  // Check changeU() and changeV()
104 107
  if (G.u(e2) == n2) {
... ...
@@ -195,139 +198,155 @@
195 198

	
196 199
  checkGraphNodeList(G, 3);
197 200
  checkGraphEdgeList(G, 2);
198 201
  checkGraphArcList(G, 4);
199 202

	
200 203
  checkGraphIncEdgeArcLists(G, n1, 2);
201 204
  checkGraphIncEdgeArcLists(G, n2, 1);
202 205
  checkGraphIncEdgeArcLists(G, n4, 1);
203 206

	
204 207
  checkGraphConEdgeList(G, 2);
205 208
  checkGraphConArcList(G, 4);
206 209
}
207 210

	
208 211

	
209 212
template <class Graph>
210 213
void checkGraphSnapshot() {
211 214
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
212 215

	
213 216
  Graph G;
214 217
  Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
215 218
  Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
216 219
       e3 = G.addEdge(n2, n3);
217 220

	
218 221
  checkGraphNodeList(G, 3);
219 222
  checkGraphEdgeList(G, 3);
220 223
  checkGraphArcList(G, 6);
221 224

	
222 225
  typename Graph::Snapshot snapshot(G);
223 226

	
224 227
  Node n = G.addNode();
225 228
  G.addEdge(n3, n);
226 229
  G.addEdge(n, n3);
227 230
  G.addEdge(n3, n2);
228 231

	
229 232
  checkGraphNodeList(G, 4);
230 233
  checkGraphEdgeList(G, 6);
231 234
  checkGraphArcList(G, 12);
232 235

	
233 236
  snapshot.restore();
234 237

	
235 238
  checkGraphNodeList(G, 3);
236 239
  checkGraphEdgeList(G, 3);
237 240
  checkGraphArcList(G, 6);
238 241

	
239 242
  checkGraphIncEdgeArcLists(G, n1, 2);
240 243
  checkGraphIncEdgeArcLists(G, n2, 3);
241 244
  checkGraphIncEdgeArcLists(G, n3, 1);
242 245

	
243 246
  checkGraphConEdgeList(G, 3);
244 247
  checkGraphConArcList(G, 6);
245 248

	
246 249
  checkNodeIds(G);
247 250
  checkEdgeIds(G);
248 251
  checkArcIds(G);
249 252
  checkGraphNodeMap(G);
250 253
  checkGraphEdgeMap(G);
251 254
  checkGraphArcMap(G);
252 255

	
253 256
  G.addNode();
254 257
  snapshot.save(G);
255 258

	
256 259
  G.addEdge(G.addNode(), G.addNode());
257 260

	
258 261
  snapshot.restore();
262
  snapshot.save(G);
263

	
264
  checkGraphNodeList(G, 4);
265
  checkGraphEdgeList(G, 3);
266
  checkGraphArcList(G, 6);
267
  
268
  G.addEdge(G.addNode(), G.addNode());
269

	
270
  snapshot.restore();
259 271

	
260 272
  checkGraphNodeList(G, 4);
261 273
  checkGraphEdgeList(G, 3);
262 274
  checkGraphArcList(G, 6);
263 275
}
264 276

	
265 277
void checkFullGraph(int num) {
266 278
  typedef FullGraph Graph;
267 279
  GRAPH_TYPEDEFS(Graph);
268 280

	
269 281
  Graph G(num);
282
  check(G.nodeNum() == num && G.edgeNum() == num * (num - 1) / 2,
283
        "Wrong size");
284

	
285
  G.resize(num);
286
  check(G.nodeNum() == num && G.edgeNum() == num * (num - 1) / 2,
287
        "Wrong size");
288

	
270 289
  checkGraphNodeList(G, num);
271 290
  checkGraphEdgeList(G, num * (num - 1) / 2);
272 291

	
273 292
  for (NodeIt n(G); n != INVALID; ++n) {
274 293
    checkGraphOutArcList(G, n, num - 1);
275 294
    checkGraphInArcList(G, n, num - 1);
276 295
    checkGraphIncEdgeList(G, n, num - 1);
277 296
  }
278 297

	
279 298
  checkGraphConArcList(G, num * (num - 1));
280 299
  checkGraphConEdgeList(G, num * (num - 1) / 2);
281 300

	
282 301
  checkArcDirections(G);
283 302

	
284 303
  checkNodeIds(G);
285 304
  checkArcIds(G);
286 305
  checkEdgeIds(G);
287 306
  checkGraphNodeMap(G);
288 307
  checkGraphArcMap(G);
289 308
  checkGraphEdgeMap(G);
290 309

	
291 310

	
292 311
  for (int i = 0; i < G.nodeNum(); ++i) {
293 312
    check(G.index(G(i)) == i, "Wrong index");
294 313
  }
295 314

	
296 315
  for (NodeIt u(G); u != INVALID; ++u) {
297 316
    for (NodeIt v(G); v != INVALID; ++v) {
298 317
      Edge e = G.edge(u, v);
299 318
      Arc a = G.arc(u, v);
300 319
      if (u == v) {
301 320
        check(e == INVALID, "Wrong edge lookup");
302 321
        check(a == INVALID, "Wrong arc lookup");
303 322
      } else {
304 323
        check((G.u(e) == u && G.v(e) == v) ||
305 324
              (G.u(e) == v && G.v(e) == u), "Wrong edge lookup");
306 325
        check(G.source(a) == u && G.target(a) == v, "Wrong arc lookup");
307 326
      }
308 327
    }
309 328
  }
310 329
}
311 330

	
312 331
void checkConcepts() {
313 332
  { // Checking graph components
314 333
    checkConcept<BaseGraphComponent, BaseGraphComponent >();
315 334

	
316 335
    checkConcept<IDableGraphComponent<>,
317 336
      IDableGraphComponent<> >();
318 337

	
319 338
    checkConcept<IterableGraphComponent<>,
320 339
      IterableGraphComponent<> >();
321 340

	
322 341
    checkConcept<MappableGraphComponent<>,
323 342
      MappableGraphComponent<> >();
324 343
  }
325 344
  { // Checking skeleton graph
326 345
    checkConcept<Graph, Graph>();
327 346
  }
328 347
  { // Checking ListGraph
329 348
    checkConcept<Graph, ListGraph>();
330 349
    checkConcept<AlterableGraphComponent<>, ListGraph>();
331 350
    checkConcept<ExtendableGraphComponent<>, ListGraph>();
332 351
    checkConcept<ClearableGraphComponent<>, ListGraph>();
333 352
    checkConcept<ErasableGraphComponent<>, ListGraph>();
... ...
@@ -350,203 +369,212 @@
350 369
}
351 370

	
352 371
template <typename Graph>
353 372
void checkGraphValidity() {
354 373
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
355 374
  Graph g;
356 375

	
357 376
  Node
358 377
    n1 = g.addNode(),
359 378
    n2 = g.addNode(),
360 379
    n3 = g.addNode();
361 380

	
362 381
  Edge
363 382
    e1 = g.addEdge(n1, n2),
364 383
    e2 = g.addEdge(n2, n3);
365 384

	
366 385
  check(g.valid(n1), "Wrong validity check");
367 386
  check(g.valid(e1), "Wrong validity check");
368 387
  check(g.valid(g.direct(e1, true)), "Wrong validity check");
369 388

	
370 389
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
371 390
  check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
372 391
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
373 392
}
374 393

	
375 394
template <typename Graph>
376 395
void checkGraphValidityErase() {
377 396
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
378 397
  Graph g;
379 398

	
380 399
  Node
381 400
    n1 = g.addNode(),
382 401
    n2 = g.addNode(),
383 402
    n3 = g.addNode();
384 403

	
385 404
  Edge
386 405
    e1 = g.addEdge(n1, n2),
387 406
    e2 = g.addEdge(n2, n3);
388 407

	
389 408
  check(g.valid(n1), "Wrong validity check");
390 409
  check(g.valid(e1), "Wrong validity check");
391 410
  check(g.valid(g.direct(e1, true)), "Wrong validity check");
392 411

	
393 412
  g.erase(n1);
394 413

	
395 414
  check(!g.valid(n1), "Wrong validity check");
396 415
  check(g.valid(n2), "Wrong validity check");
397 416
  check(g.valid(n3), "Wrong validity check");
398 417
  check(!g.valid(e1), "Wrong validity check");
399 418
  check(g.valid(e2), "Wrong validity check");
400 419

	
401 420
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
402 421
  check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
403 422
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
404 423
}
405 424

	
406 425
void checkGridGraph(int width, int height) {
407 426
  typedef GridGraph Graph;
408 427
  GRAPH_TYPEDEFS(Graph);
409 428
  Graph G(width, height);
410 429

	
411 430
  check(G.width() == width, "Wrong column number");
412 431
  check(G.height() == height, "Wrong row number");
413 432

	
433
  G.resize(width, height);
434
  check(G.width() == width, "Wrong column number");
435
  check(G.height() == height, "Wrong row number");
436

	
414 437
  for (int i = 0; i < width; ++i) {
415 438
    for (int j = 0; j < height; ++j) {
416 439
      check(G.col(G(i, j)) == i, "Wrong column");
417 440
      check(G.row(G(i, j)) == j, "Wrong row");
418 441
      check(G.pos(G(i, j)).x == i, "Wrong column");
419 442
      check(G.pos(G(i, j)).y == j, "Wrong row");
420 443
    }
421 444
  }
422 445

	
423 446
  for (int j = 0; j < height; ++j) {
424 447
    for (int i = 0; i < width - 1; ++i) {
425 448
      check(G.source(G.right(G(i, j))) == G(i, j), "Wrong right");
426 449
      check(G.target(G.right(G(i, j))) == G(i + 1, j), "Wrong right");
427 450
    }
428 451
    check(G.right(G(width - 1, j)) == INVALID, "Wrong right");
429 452
  }
430 453

	
431 454
  for (int j = 0; j < height; ++j) {
432 455
    for (int i = 1; i < width; ++i) {
433 456
      check(G.source(G.left(G(i, j))) == G(i, j), "Wrong left");
434 457
      check(G.target(G.left(G(i, j))) == G(i - 1, j), "Wrong left");
435 458
    }
436 459
    check(G.left(G(0, j)) == INVALID, "Wrong left");
437 460
  }
438 461

	
439 462
  for (int i = 0; i < width; ++i) {
440 463
    for (int j = 0; j < height - 1; ++j) {
441 464
      check(G.source(G.up(G(i, j))) == G(i, j), "Wrong up");
442 465
      check(G.target(G.up(G(i, j))) == G(i, j + 1), "Wrong up");
443 466
    }
444 467
    check(G.up(G(i, height - 1)) == INVALID, "Wrong up");
445 468
  }
446 469

	
447 470
  for (int i = 0; i < width; ++i) {
448 471
    for (int j = 1; j < height; ++j) {
449 472
      check(G.source(G.down(G(i, j))) == G(i, j), "Wrong down");
450 473
      check(G.target(G.down(G(i, j))) == G(i, j - 1), "Wrong down");
451 474
    }
452 475
    check(G.down(G(i, 0)) == INVALID, "Wrong down");
453 476
  }
454 477

	
455 478
  checkGraphNodeList(G, width * height);
456 479
  checkGraphEdgeList(G, width * (height - 1) + (width - 1) * height);
457 480
  checkGraphArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
458 481

	
459 482
  for (NodeIt n(G); n != INVALID; ++n) {
460 483
    int nb = 4;
461 484
    if (G.col(n) == 0) --nb;
462 485
    if (G.col(n) == width - 1) --nb;
463 486
    if (G.row(n) == 0) --nb;
464 487
    if (G.row(n) == height - 1) --nb;
465 488

	
466 489
    checkGraphOutArcList(G, n, nb);
467 490
    checkGraphInArcList(G, n, nb);
468 491
    checkGraphIncEdgeList(G, n, nb);
469 492
  }
470 493

	
471 494
  checkArcDirections(G);
472 495

	
473 496
  checkGraphConArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
474 497
  checkGraphConEdgeList(G, width * (height - 1) + (width - 1) * height);
475 498

	
476 499
  checkNodeIds(G);
477 500
  checkArcIds(G);
478 501
  checkEdgeIds(G);
479 502
  checkGraphNodeMap(G);
480 503
  checkGraphArcMap(G);
481 504
  checkGraphEdgeMap(G);
482 505

	
483 506
}
484 507

	
485 508
void checkHypercubeGraph(int dim) {
486 509
  GRAPH_TYPEDEFS(HypercubeGraph);
487 510

	
488 511
  HypercubeGraph G(dim);
512
  check(G.dimension() == dim, "Wrong dimension");
513

	
514
  G.resize(dim);
515
  check(G.dimension() == dim, "Wrong dimension");
516
  
489 517
  checkGraphNodeList(G, 1 << dim);
490 518
  checkGraphEdgeList(G, dim * (1 << (dim-1)));
491 519
  checkGraphArcList(G, dim * (1 << dim));
492 520

	
493 521
  Node n = G.nodeFromId(dim);
494 522

	
495 523
  for (NodeIt n(G); n != INVALID; ++n) {
496 524
    checkGraphIncEdgeList(G, n, dim);
497 525
    for (IncEdgeIt e(G, n); e != INVALID; ++e) {
498 526
      check( (G.u(e) == n &&
499 527
              G.id(G.v(e)) == (G.id(n) ^ (1 << G.dimension(e)))) ||
500 528
             (G.v(e) == n &&
501 529
              G.id(G.u(e)) == (G.id(n) ^ (1 << G.dimension(e)))),
502 530
             "Wrong edge or wrong dimension");
503 531
    }
504 532

	
505 533
    checkGraphOutArcList(G, n, dim);
506 534
    for (OutArcIt a(G, n); a != INVALID; ++a) {
507 535
      check(G.source(a) == n &&
508 536
            G.id(G.target(a)) == (G.id(n) ^ (1 << G.dimension(a))),
509 537
            "Wrong arc or wrong dimension");
510 538
    }
511 539

	
512 540
    checkGraphInArcList(G, n, dim);
513 541
    for (InArcIt a(G, n); a != INVALID; ++a) {
514 542
      check(G.target(a) == n &&
515 543
            G.id(G.source(a)) == (G.id(n) ^ (1 << G.dimension(a))),
516 544
            "Wrong arc or wrong dimension");
517 545
    }
518 546
  }
519 547

	
520 548
  checkGraphConArcList(G, (1 << dim) * dim);
521 549
  checkGraphConEdgeList(G, dim * (1 << (dim-1)));
522 550

	
523 551
  checkArcDirections(G);
524 552

	
525 553
  checkNodeIds(G);
526 554
  checkArcIds(G);
527 555
  checkEdgeIds(G);
528 556
  checkGraphNodeMap(G);
529 557
  checkGraphArcMap(G);
530 558
  checkGraphEdgeMap(G);
531 559
}
532 560

	
533 561
void checkGraphs() {
534 562
  { // Checking ListGraph
535 563
    checkGraphBuild<ListGraph>();
536 564
    checkGraphAlter<ListGraph>();
537 565
    checkGraphErase<ListGraph>();
538 566
    checkGraphSnapshot<ListGraph>();
539 567
    checkGraphValidityErase<ListGraph>();
540 568
  }
541 569
  { // Checking SmartGraph
542 570
    checkGraphBuild<SmartGraph>();
543 571
    checkGraphSnapshot<SmartGraph>();
544 572
    checkGraphValidity<SmartGraph>();
545 573
  }
546 574
  { // Checking FullGraph
547 575
    checkFullGraph(7);
548 576
    checkFullGraph(8);
549 577
  }
550 578
  { // Checking GridGraph
551 579
    checkGridGraph(5, 8);
552 580
    checkGridGraph(8, 5);
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include "test_tools.h"
20 20

	
21 21
#include <lemon/config.h>
22 22

	
23 23
#ifdef LEMON_HAVE_CPLEX
24 24
#include <lemon/cplex.h>
25 25
#endif
26 26

	
27 27
#ifdef LEMON_HAVE_GLPK
28 28
#include <lemon/glpk.h>
29 29
#endif
30 30

	
31 31
#ifdef LEMON_HAVE_CBC
32 32
#include <lemon/cbc.h>
33 33
#endif
34 34

	
35 35

	
36 36
using namespace lemon;
37 37

	
38 38
void solveAndCheck(MipSolver& mip, MipSolver::ProblemType stat,
39 39
                   double exp_opt) {
40 40
  using std::string;
41 41

	
42 42
  mip.solve();
43 43
  //int decimal,sign;
44 44
  std::ostringstream buf;
45 45
  buf << "Type should be: " << int(stat)<<" and it is "<<int(mip.type());
46 46

	
47 47

	
48 48
  //  itoa(stat,buf1, 10);
49 49
  check(mip.type()==stat, buf.str());
50 50

	
51 51
  if (stat ==  MipSolver::OPTIMAL) {
52 52
    std::ostringstream sbuf;
53
    buf << "Wrong optimal value: the right optimum is " << exp_opt;
53
    sbuf << "Wrong optimal value ("<< mip.solValue()
54
         <<" instead of " << exp_opt << ")";
54 55
    check(std::abs(mip.solValue()-exp_opt) < 1e-3, sbuf.str());
55 56
    //+ecvt(exp_opt,2)
56 57
  }
57 58
}
58 59

	
59 60
void aTest(MipSolver& mip)
60 61
{
61 62
  //The following example is very simple
62 63

	
63 64

	
64 65
  typedef MipSolver::Row Row;
65 66
  typedef MipSolver::Col Col;
66 67

	
67 68

	
68 69
  Col x1 = mip.addCol();
69 70
  Col x2 = mip.addCol();
70 71

	
71 72

	
72 73
  //Objective function
73 74
  mip.obj(x1);
74 75

	
75 76
  mip.max();
76 77

	
77 78
  //Unconstrained optimization
78 79
  mip.solve();
79 80
  //Check it out!
80 81

	
81 82
  //Constraints
82 83
  mip.addRow(2 * x1 + x2 <= 2);
83 84
  Row y2 = mip.addRow(x1 - 2 * x2 <= 0);
84 85

	
85 86
  //Nonnegativity of the variable x1
86 87
  mip.colLowerBound(x1, 0);
87 88

	
88 89

	
89 90
  //Maximization of x1
90 91
  //over the triangle with vertices (0,0),(4/5,2/5),(0,2)
91 92
  double expected_opt=4.0/5.0;
92 93
  solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
93 94

	
94 95

	
95 96
  //Restrict x2 to integer
96 97
  mip.colType(x2,MipSolver::INTEGER);
97 98
  expected_opt=1.0/2.0;
98 99
  solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
99 100

	
100 101

	
101 102
  //Restrict both to integer
102 103
  mip.colType(x1,MipSolver::INTEGER);
103 104
  expected_opt=0;
104 105
  solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
105 106

	
106 107
  //Erase a variable
107 108
  mip.erase(x2);
108 109
  mip.rowUpperBound(y2, 8);
109 110
  expected_opt=1;
110 111
  solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
111 112

	
112 113
}
113 114

	
114 115

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

	
19 19
#ifndef LEMON_TEST_TEST_TOOLS_H
20 20
#define LEMON_TEST_TEST_TOOLS_H
21 21

	
22 22
///\ingroup misc
23 23
///\file
24 24
///\brief Some utilities to write test programs.
25 25

	
26 26
#include <iostream>
27 27
#include <stdlib.h>
28 28

	
29 29
///If \c rc is fail, writes an error message and exits.
30 30

	
31 31
///If \c rc is fail, writes an error message and exits.
32 32
///The error message contains the file name and the line number of the
33 33
///source code in a standard from, which makes it possible to go there
34 34
///using good source browsers like e.g. \c emacs.
35 35
///
36 36
///For example
37 37
///\code check(0==1,"This is obviously false.");\endcode will
38 38
///print something like this (and then exits).
39 39
///\verbatim file_name.cc:123: error: This is obviously false. \endverbatim
40
#define check(rc, msg) \
41
  if(!(rc)) { \
42
    std::cerr << __FILE__ ":" << __LINE__ << ": error: " << msg << std::endl; \
43
    abort(); \
44
  } else { } \
40
#define check(rc, msg)                                                  \
41
  {                                                                     \
42
    if(!(rc)) {                                                         \
43
      std::cerr << __FILE__ ":" << __LINE__ << ": error: "              \
44
                << msg << std::endl;                                    \
45
      abort();                                                          \
46
    } else { }                                                          \
47
  }                                                                     \
48
    
45 49

	
46 50
#endif
0 comments (0 inline)