gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge
0 3 0
merge default
1 file changed with 32 insertions and 18 deletions:
↑ Collapse diff ↑
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
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
#include <lemon/maps.h>
34 34
#include <lemon/circulation.h>
35 35
#include <lemon/adaptors.h>
36 36

	
37 37
namespace lemon {
38 38

	
39 39
  /// \addtogroup min_cost_flow
40 40
  /// @{
41 41

	
42 42
  /// \brief Implementation of the primal Network Simplex algorithm
43 43
  /// for finding a \ref min_cost_flow "minimum cost flow".
44 44
  ///
45 45
  /// \ref NetworkSimplex implements the primal Network Simplex algorithm
46 46
  /// for finding a \ref min_cost_flow "minimum cost flow".
47 47
  /// This algorithm is a specialized version of the linear programming
48 48
  /// simplex method directly for the minimum cost flow problem.
49 49
  /// It is one of the most efficient solution methods.
50 50
  ///
51 51
  /// In general this class is the fastest implementation available
52 52
  /// in LEMON for the minimum cost flow problem.
53 53
  /// Moreover it supports both direction of the supply/demand inequality
54 54
  /// constraints. For more information see \ref ProblemType.
55 55
  ///
56 56
  /// \tparam GR The digraph type the algorithm runs on.
57 57
  /// \tparam F The value type used for flow amounts, capacity bounds
58 58
  /// and supply values in the algorithm. By default it is \c int.
59 59
  /// \tparam C The value type used for costs and potentials in the
60 60
  /// algorithm. By default it is the same as \c F.
61 61
  ///
62 62
  /// \warning Both value types must be signed and all input data must
63 63
  /// be integer.
64 64
  ///
65 65
  /// \note %NetworkSimplex provides five different pivot rule
66 66
  /// implementations, from which the most efficient one is used
67 67
  /// by default. For more information see \ref PivotRule.
68 68
  template <typename GR, typename F = int, typename C = F>
69 69
  class NetworkSimplex
70 70
  {
71 71
  public:
72 72

	
73 73
    /// The flow type of the algorithm
74 74
    typedef F Flow;
75 75
    /// The cost type of the algorithm
76 76
    typedef C Cost;
77 77
#ifdef DOXYGEN
78 78
    /// The type of the flow map
79 79
    typedef GR::ArcMap<Flow> FlowMap;
80 80
    /// The type of the potential map
81 81
    typedef GR::NodeMap<Cost> PotentialMap;
82 82
#else
83 83
    /// The type of the flow map
84 84
    typedef typename GR::template ArcMap<Flow> FlowMap;
85 85
    /// The type of the potential map
86 86
    typedef typename GR::template NodeMap<Cost> PotentialMap;
87 87
#endif
88 88

	
89 89
  public:
90 90

	
91 91
    /// \brief Enum type for selecting the pivot rule.
92 92
    ///
93 93
    /// Enum type for selecting the pivot rule for the \ref run()
94 94
    /// function.
95 95
    ///
96 96
    /// \ref NetworkSimplex provides five different pivot rule
97 97
    /// implementations that significantly affect the running time
98 98
    /// of the algorithm.
99 99
    /// By default \ref BLOCK_SEARCH "Block Search" is used, which
100 100
    /// proved to be the most efficient and the most robust on various
101 101
    /// test inputs according to our benchmark tests.
102 102
    /// However another pivot rule can be selected using the \ref run()
103 103
    /// function with the proper parameter.
104 104
    enum PivotRule {
105 105

	
106 106
      /// The First Eligible pivot rule.
107 107
      /// The next eligible arc is selected in a wraparound fashion
108 108
      /// in every iteration.
109 109
      FIRST_ELIGIBLE,
110 110

	
111 111
      /// The Best Eligible pivot rule.
112 112
      /// The best eligible arc is selected in every iteration.
113 113
      BEST_ELIGIBLE,
114 114

	
115 115
      /// The Block Search pivot rule.
116 116
      /// A specified number of arcs are examined in every iteration
117 117
      /// in a wraparound fashion and the best eligible arc is selected
118 118
      /// from this block.
119 119
      BLOCK_SEARCH,
120 120

	
121 121
      /// The Candidate List pivot rule.
122 122
      /// In a major iteration a candidate list is built from eligible arcs
123 123
      /// in a wraparound fashion and in the following minor iterations
124 124
      /// the best eligible arc is selected from this list.
125 125
      CANDIDATE_LIST,
126 126

	
127 127
      /// The Altering Candidate List pivot rule.
128 128
      /// It is a modified version of the Candidate List method.
129 129
      /// It keeps only the several best eligible arcs from the former
130 130
      /// candidate list and extends this list in every iteration.
131 131
      ALTERING_LIST
132 132
    };
133 133
    
134 134
    /// \brief Enum type for selecting the problem type.
135 135
    ///
136 136
    /// Enum type for selecting the problem type, i.e. the direction of
137 137
    /// the inequalities in the supply/demand constraints of the
138 138
    /// \ref min_cost_flow "minimum cost flow problem".
139 139
    ///
140 140
    /// The default problem type is \c GEQ, since this form is supported
141 141
    /// by other minimum cost flow algorithms and the \ref Circulation
142 142
    /// algorithm as well.
143 143
    /// The \c LEQ problem type can be selected using the \ref problemType()
144 144
    /// function.
145 145
    ///
146 146
    /// Note that the equality form is a special case of both problem type.
147 147
    enum ProblemType {
148 148

	
149 149
      /// This option means that there are "<em>greater or equal</em>"
150 150
      /// constraints in the defintion, i.e. the exact formulation of the
151 151
      /// problem is the following.
152 152
      /**
153 153
          \f[ \min\sum_{uv\in A} f(uv) \cdot cost(uv) \f]
154 154
          \f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \geq
155 155
              sup(u) \quad \forall u\in V \f]
156 156
          \f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f]
157 157
      */
158 158
      /// It means that the total demand must be greater or equal to the 
159 159
      /// total supply (i.e. \f$\sum_{u\in V} sup(u)\f$ must be zero or
160 160
      /// negative) and all the supplies have to be carried out from 
161 161
      /// the supply nodes, but there could be demands that are not 
162 162
      /// satisfied.
163 163
      GEQ,
164 164
      /// It is just an alias for the \c GEQ option.
165 165
      CARRY_SUPPLIES = GEQ,
166 166

	
167 167
      /// This option means that there are "<em>less or equal</em>"
168 168
      /// constraints in the defintion, i.e. the exact formulation of the
169 169
      /// problem is the following.
170 170
      /**
171 171
          \f[ \min\sum_{uv\in A} f(uv) \cdot cost(uv) \f]
172 172
          \f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \leq
173 173
              sup(u) \quad \forall u\in V \f]
174 174
          \f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f]
175 175
      */
176 176
      /// It means that the total demand must be less or equal to the 
177 177
      /// total supply (i.e. \f$\sum_{u\in V} sup(u)\f$ must be zero or
178 178
      /// positive) and all the demands have to be satisfied, but there
179 179
      /// could be supplies that are not carried out from the supply
180 180
      /// nodes.
181 181
      LEQ,
182 182
      /// It is just an alias for the \c LEQ option.
183 183
      SATISFY_DEMANDS = LEQ
184 184
    };
185 185

	
186 186
  private:
187 187

	
188 188
    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
189 189

	
190 190
    typedef typename GR::template ArcMap<Flow> FlowArcMap;
191 191
    typedef typename GR::template ArcMap<Cost> CostArcMap;
192 192
    typedef typename GR::template NodeMap<Flow> FlowNodeMap;
193 193

	
194 194
    typedef std::vector<Arc> ArcVector;
195 195
    typedef std::vector<Node> NodeVector;
196 196
    typedef std::vector<int> IntVector;
197 197
    typedef std::vector<bool> BoolVector;
198 198
    typedef std::vector<Flow> FlowVector;
199 199
    typedef std::vector<Cost> CostVector;
200 200

	
201 201
    // State constants for arcs
202 202
    enum ArcStateEnum {
203 203
      STATE_UPPER = -1,
204 204
      STATE_TREE  =  0,
205 205
      STATE_LOWER =  1
206 206
    };
207 207

	
208 208
  private:
209 209

	
210 210
    // Data related to the underlying digraph
211 211
    const GR &_graph;
212 212
    int _node_num;
213 213
    int _arc_num;
214 214

	
215 215
    // Parameters of the problem
216 216
    FlowArcMap *_plower;
217 217
    FlowArcMap *_pupper;
218 218
    CostArcMap *_pcost;
219 219
    FlowNodeMap *_psupply;
220 220
    bool _pstsup;
221 221
    Node _psource, _ptarget;
222 222
    Flow _pstflow;
223 223
    ProblemType _ptype;
224 224

	
225 225
    // Result maps
226 226
    FlowMap *_flow_map;
227 227
    PotentialMap *_potential_map;
228 228
    bool _local_flow;
229 229
    bool _local_potential;
230 230

	
231 231
    // Data structures for storing the digraph
232 232
    IntNodeMap _node_id;
233 233
    ArcVector _arc_ref;
234 234
    IntVector _source;
235 235
    IntVector _target;
236 236

	
237 237
    // Node and arc data
238 238
    FlowVector _cap;
239 239
    CostVector _cost;
240 240
    FlowVector _supply;
241 241
    FlowVector _flow;
242 242
    CostVector _pi;
243 243

	
244 244
    // Data for storing the spanning tree structure
245 245
    IntVector _parent;
246 246
    IntVector _pred;
247 247
    IntVector _thread;
248 248
    IntVector _rev_thread;
249 249
    IntVector _succ_num;
250 250
    IntVector _last_succ;
251 251
    IntVector _dirty_revs;
252 252
    BoolVector _forward;
253 253
    IntVector _state;
254 254
    int _root;
255 255

	
256 256
    // Temporary data used in the current pivot iteration
257 257
    int in_arc, join, u_in, v_in, u_out, v_out;
258 258
    int first, second, right, last;
259 259
    int stem, par_stem, new_stem;
260 260
    Flow delta;
261 261

	
262 262
  private:
263 263

	
264 264
    // Implementation of the First Eligible pivot rule
265 265
    class FirstEligiblePivotRule
266 266
    {
267 267
    private:
268 268

	
269 269
      // References to the NetworkSimplex class
270 270
      const IntVector  &_source;
271 271
      const IntVector  &_target;
272 272
      const CostVector &_cost;
273 273
      const IntVector  &_state;
274 274
      const CostVector &_pi;
275 275
      int &_in_arc;
276 276
      int _arc_num;
277 277

	
278 278
      // Pivot rule data
279 279
      int _next_arc;
280 280

	
281 281
    public:
282 282

	
283 283
      // Constructor
284 284
      FirstEligiblePivotRule(NetworkSimplex &ns) :
285 285
        _source(ns._source), _target(ns._target),
286 286
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
287 287
        _in_arc(ns.in_arc), _arc_num(ns._arc_num), _next_arc(0)
288 288
      {}
289 289

	
290 290
      // Find next entering arc
291 291
      bool findEnteringArc() {
292 292
        Cost c;
293 293
        for (int e = _next_arc; e < _arc_num; ++e) {
294 294
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
295 295
          if (c < 0) {
296 296
            _in_arc = e;
297 297
            _next_arc = e + 1;
298 298
            return true;
299 299
          }
300 300
        }
301 301
        for (int e = 0; e < _next_arc; ++e) {
302 302
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
303 303
          if (c < 0) {
304 304
            _in_arc = e;
305 305
            _next_arc = e + 1;
306 306
            return true;
307 307
          }
308 308
        }
309 309
        return false;
310 310
      }
311 311

	
312 312
    }; //class FirstEligiblePivotRule
313 313

	
314 314

	
315 315
    // Implementation of the Best Eligible pivot rule
316 316
    class BestEligiblePivotRule
317 317
    {
318 318
    private:
319 319

	
320 320
      // References to the NetworkSimplex class
321 321
      const IntVector  &_source;
322 322
      const IntVector  &_target;
323 323
      const CostVector &_cost;
324 324
      const IntVector  &_state;
325 325
      const CostVector &_pi;
326 326
      int &_in_arc;
327 327
      int _arc_num;
328 328

	
329 329
    public:
330 330

	
331 331
      // Constructor
332 332
      BestEligiblePivotRule(NetworkSimplex &ns) :
333 333
        _source(ns._source), _target(ns._target),
334 334
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
335 335
        _in_arc(ns.in_arc), _arc_num(ns._arc_num)
336 336
      {}
337 337

	
338 338
      // Find next entering arc
339 339
      bool findEnteringArc() {
340 340
        Cost c, min = 0;
341 341
        for (int e = 0; e < _arc_num; ++e) {
342 342
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
343 343
          if (c < min) {
344 344
            min = c;
345 345
            _in_arc = e;
346 346
          }
347 347
        }
348 348
        return min < 0;
349 349
      }
350 350

	
351 351
    }; //class BestEligiblePivotRule
352 352

	
353 353

	
354 354
    // Implementation of the Block Search pivot rule
355 355
    class BlockSearchPivotRule
356 356
    {
357 357
    private:
358 358

	
359 359
      // References to the NetworkSimplex class
360 360
      const IntVector  &_source;
361 361
      const IntVector  &_target;
362 362
      const CostVector &_cost;
363 363
      const IntVector  &_state;
364 364
      const CostVector &_pi;
365 365
      int &_in_arc;
366 366
      int _arc_num;
367 367

	
368 368
      // Pivot rule data
369 369
      int _block_size;
370 370
      int _next_arc;
371 371

	
372 372
    public:
373 373

	
374 374
      // Constructor
375 375
      BlockSearchPivotRule(NetworkSimplex &ns) :
376 376
        _source(ns._source), _target(ns._target),
377 377
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
378 378
        _in_arc(ns.in_arc), _arc_num(ns._arc_num), _next_arc(0)
379 379
      {
380 380
        // The main parameters of the pivot rule
381 381
        const double BLOCK_SIZE_FACTOR = 2.0;
382 382
        const int MIN_BLOCK_SIZE = 10;
383 383

	
384 384
        _block_size = std::max( int(BLOCK_SIZE_FACTOR *
385 385
                                    std::sqrt(double(_arc_num))),
386 386
                                MIN_BLOCK_SIZE );
387 387
      }
388 388

	
389 389
      // Find next entering arc
390 390
      bool findEnteringArc() {
391 391
        Cost c, min = 0;
392 392
        int cnt = _block_size;
393 393
        int e, min_arc = _next_arc;
394 394
        for (e = _next_arc; e < _arc_num; ++e) {
395 395
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
396 396
          if (c < min) {
397 397
            min = c;
398 398
            min_arc = e;
399 399
          }
400 400
          if (--cnt == 0) {
401 401
            if (min < 0) break;
402 402
            cnt = _block_size;
403 403
          }
404 404
        }
405 405
        if (min == 0 || cnt > 0) {
406 406
          for (e = 0; e < _next_arc; ++e) {
407 407
            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
408 408
            if (c < min) {
409 409
              min = c;
410 410
              min_arc = e;
411 411
            }
412 412
            if (--cnt == 0) {
413 413
              if (min < 0) break;
414 414
              cnt = _block_size;
415 415
            }
416 416
          }
417 417
        }
418 418
        if (min >= 0) return false;
419 419
        _in_arc = min_arc;
420 420
        _next_arc = e;
421 421
        return true;
422 422
      }
423 423

	
424 424
    }; //class BlockSearchPivotRule
425 425

	
426 426

	
427 427
    // Implementation of the Candidate List pivot rule
428 428
    class CandidateListPivotRule
429 429
    {
430 430
    private:
431 431

	
432 432
      // References to the NetworkSimplex class
433 433
      const IntVector  &_source;
434 434
      const IntVector  &_target;
435 435
      const CostVector &_cost;
436 436
      const IntVector  &_state;
437 437
      const CostVector &_pi;
438 438
      int &_in_arc;
439 439
      int _arc_num;
440 440

	
441 441
      // Pivot rule data
442 442
      IntVector _candidates;
443 443
      int _list_length, _minor_limit;
444 444
      int _curr_length, _minor_count;
445 445
      int _next_arc;
446 446

	
447 447
    public:
448 448

	
449 449
      /// Constructor
450 450
      CandidateListPivotRule(NetworkSimplex &ns) :
451 451
        _source(ns._source), _target(ns._target),
452 452
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
453 453
        _in_arc(ns.in_arc), _arc_num(ns._arc_num), _next_arc(0)
454 454
      {
455 455
        // The main parameters of the pivot rule
456 456
        const double LIST_LENGTH_FACTOR = 1.0;
457 457
        const int MIN_LIST_LENGTH = 10;
458 458
        const double MINOR_LIMIT_FACTOR = 0.1;
459 459
        const int MIN_MINOR_LIMIT = 3;
460 460

	
461 461
        _list_length = std::max( int(LIST_LENGTH_FACTOR *
462 462
                                     std::sqrt(double(_arc_num))),
463 463
                                 MIN_LIST_LENGTH );
464 464
        _minor_limit = std::max( int(MINOR_LIMIT_FACTOR * _list_length),
465 465
                                 MIN_MINOR_LIMIT );
466 466
        _curr_length = _minor_count = 0;
467 467
        _candidates.resize(_list_length);
468 468
      }
469 469

	
470 470
      /// Find next entering arc
471 471
      bool findEnteringArc() {
472 472
        Cost min, c;
473 473
        int e, min_arc = _next_arc;
474 474
        if (_curr_length > 0 && _minor_count < _minor_limit) {
475 475
          // Minor iteration: select the best eligible arc from the
476 476
          // current candidate list
477 477
          ++_minor_count;
478 478
          min = 0;
479 479
          for (int i = 0; i < _curr_length; ++i) {
480 480
            e = _candidates[i];
481 481
            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
482 482
            if (c < min) {
483 483
              min = c;
484 484
              min_arc = e;
485 485
            }
486 486
            if (c >= 0) {
487 487
              _candidates[i--] = _candidates[--_curr_length];
488 488
            }
489 489
          }
490 490
          if (min < 0) {
491 491
            _in_arc = min_arc;
492 492
            return true;
493 493
          }
494 494
        }
495 495

	
496 496
        // Major iteration: build a new candidate list
497 497
        min = 0;
498 498
        _curr_length = 0;
499 499
        for (e = _next_arc; e < _arc_num; ++e) {
500 500
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
501 501
          if (c < 0) {
502 502
            _candidates[_curr_length++] = e;
503 503
            if (c < min) {
504 504
              min = c;
505 505
              min_arc = e;
506 506
            }
507 507
            if (_curr_length == _list_length) break;
508 508
          }
509 509
        }
510 510
        if (_curr_length < _list_length) {
511 511
          for (e = 0; e < _next_arc; ++e) {
512 512
            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
513 513
            if (c < 0) {
514 514
              _candidates[_curr_length++] = e;
515 515
              if (c < min) {
516 516
                min = c;
517 517
                min_arc = e;
518 518
              }
519 519
              if (_curr_length == _list_length) break;
520 520
            }
521 521
          }
522 522
        }
523 523
        if (_curr_length == 0) return false;
524 524
        _minor_count = 1;
525 525
        _in_arc = min_arc;
526 526
        _next_arc = e;
527 527
        return true;
528 528
      }
529 529

	
530 530
    }; //class CandidateListPivotRule
531 531

	
532 532

	
533 533
    // Implementation of the Altering Candidate List pivot rule
534 534
    class AlteringListPivotRule
535 535
    {
536 536
    private:
537 537

	
538 538
      // References to the NetworkSimplex class
539 539
      const IntVector  &_source;
540 540
      const IntVector  &_target;
541 541
      const CostVector &_cost;
542 542
      const IntVector  &_state;
543 543
      const CostVector &_pi;
544 544
      int &_in_arc;
545 545
      int _arc_num;
546 546

	
547 547
      // Pivot rule data
548 548
      int _block_size, _head_length, _curr_length;
549 549
      int _next_arc;
550 550
      IntVector _candidates;
551 551
      CostVector _cand_cost;
552 552

	
553 553
      // Functor class to compare arcs during sort of the candidate list
554 554
      class SortFunc
555 555
      {
556 556
      private:
557 557
        const CostVector &_map;
558 558
      public:
559 559
        SortFunc(const CostVector &map) : _map(map) {}
560 560
        bool operator()(int left, int right) {
561 561
          return _map[left] > _map[right];
562 562
        }
563 563
      };
564 564

	
565 565
      SortFunc _sort_func;
566 566

	
567 567
    public:
568 568

	
569 569
      // Constructor
570 570
      AlteringListPivotRule(NetworkSimplex &ns) :
571 571
        _source(ns._source), _target(ns._target),
572 572
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
573 573
        _in_arc(ns.in_arc), _arc_num(ns._arc_num),
574 574
        _next_arc(0), _cand_cost(ns._arc_num), _sort_func(_cand_cost)
575 575
      {
576 576
        // The main parameters of the pivot rule
577 577
        const double BLOCK_SIZE_FACTOR = 1.5;
578 578
        const int MIN_BLOCK_SIZE = 10;
579 579
        const double HEAD_LENGTH_FACTOR = 0.1;
580 580
        const int MIN_HEAD_LENGTH = 3;
581 581

	
582 582
        _block_size = std::max( int(BLOCK_SIZE_FACTOR *
583 583
                                    std::sqrt(double(_arc_num))),
584 584
                                MIN_BLOCK_SIZE );
585 585
        _head_length = std::max( int(HEAD_LENGTH_FACTOR * _block_size),
586 586
                                 MIN_HEAD_LENGTH );
587 587
        _candidates.resize(_head_length + _block_size);
588 588
        _curr_length = 0;
589 589
      }
590 590

	
591 591
      // Find next entering arc
592 592
      bool findEnteringArc() {
593 593
        // Check the current candidate list
594 594
        int e;
595 595
        for (int i = 0; i < _curr_length; ++i) {
596 596
          e = _candidates[i];
597 597
          _cand_cost[e] = _state[e] *
598 598
            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
599 599
          if (_cand_cost[e] >= 0) {
600 600
            _candidates[i--] = _candidates[--_curr_length];
601 601
          }
602 602
        }
603 603

	
604 604
        // Extend the list
605 605
        int cnt = _block_size;
606 606
        int last_arc = 0;
607 607
        int limit = _head_length;
608 608

	
609 609
        for (int e = _next_arc; e < _arc_num; ++e) {
610 610
          _cand_cost[e] = _state[e] *
611 611
            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
612 612
          if (_cand_cost[e] < 0) {
613 613
            _candidates[_curr_length++] = e;
614 614
            last_arc = e;
615 615
          }
616 616
          if (--cnt == 0) {
617 617
            if (_curr_length > limit) break;
618 618
            limit = 0;
619 619
            cnt = _block_size;
620 620
          }
621 621
        }
622 622
        if (_curr_length <= limit) {
623 623
          for (int e = 0; e < _next_arc; ++e) {
624 624
            _cand_cost[e] = _state[e] *
625 625
              (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
626 626
            if (_cand_cost[e] < 0) {
627 627
              _candidates[_curr_length++] = e;
628 628
              last_arc = e;
629 629
            }
630 630
            if (--cnt == 0) {
631 631
              if (_curr_length > limit) break;
632 632
              limit = 0;
633 633
              cnt = _block_size;
634 634
            }
635 635
          }
636 636
        }
637 637
        if (_curr_length == 0) return false;
638 638
        _next_arc = last_arc + 1;
639 639

	
640 640
        // Make heap of the candidate list (approximating a partial sort)
641 641
        make_heap( _candidates.begin(), _candidates.begin() + _curr_length,
642 642
                   _sort_func );
643 643

	
644 644
        // Pop the first element of the heap
645 645
        _in_arc = _candidates[0];
646 646
        pop_heap( _candidates.begin(), _candidates.begin() + _curr_length,
647 647
                  _sort_func );
648 648
        _curr_length = std::min(_head_length, _curr_length - 1);
649 649
        return true;
650 650
      }
651 651

	
652 652
    }; //class AlteringListPivotRule
653 653

	
654 654
  public:
655 655

	
656 656
    /// \brief Constructor.
657 657
    ///
658 658
    /// The constructor of the class.
659 659
    ///
660 660
    /// \param graph The digraph the algorithm runs on.
661 661
    NetworkSimplex(const GR& graph) :
662 662
      _graph(graph),
663 663
      _plower(NULL), _pupper(NULL), _pcost(NULL),
664 664
      _psupply(NULL), _pstsup(false), _ptype(GEQ),
665 665
      _flow_map(NULL), _potential_map(NULL),
666 666
      _local_flow(false), _local_potential(false),
667 667
      _node_id(graph)
668 668
    {
669 669
      LEMON_ASSERT(std::numeric_limits<Flow>::is_integer &&
670 670
                   std::numeric_limits<Flow>::is_signed,
671 671
        "The flow type of NetworkSimplex must be signed integer");
672 672
      LEMON_ASSERT(std::numeric_limits<Cost>::is_integer &&
673 673
                   std::numeric_limits<Cost>::is_signed,
674 674
        "The cost type of NetworkSimplex must be signed integer");
675 675
    }
676 676

	
677 677
    /// Destructor.
678 678
    ~NetworkSimplex() {
679 679
      if (_local_flow) delete _flow_map;
680 680
      if (_local_potential) delete _potential_map;
681 681
    }
682 682

	
683 683
    /// \name Parameters
684 684
    /// The parameters of the algorithm can be specified using these
685 685
    /// functions.
686 686

	
687 687
    /// @{
688 688

	
689 689
    /// \brief Set the lower bounds on the arcs.
690 690
    ///
691 691
    /// This function sets the lower bounds on the arcs.
692 692
    /// If neither this function nor \ref boundMaps() is used before
693 693
    /// calling \ref run(), the lower bounds will be set to zero
694 694
    /// on all arcs.
695 695
    ///
696 696
    /// \param map An arc map storing the lower bounds.
697 697
    /// Its \c Value type must be convertible to the \c Flow type
698 698
    /// of the algorithm.
699 699
    ///
700 700
    /// \return <tt>(*this)</tt>
701 701
    template <typename LOWER>
702 702
    NetworkSimplex& lowerMap(const LOWER& map) {
703 703
      delete _plower;
704 704
      _plower = new FlowArcMap(_graph);
705 705
      for (ArcIt a(_graph); a != INVALID; ++a) {
706 706
        (*_plower)[a] = map[a];
707 707
      }
708 708
      return *this;
709 709
    }
710 710

	
711 711
    /// \brief Set the upper bounds (capacities) on the arcs.
712 712
    ///
713 713
    /// This function sets the upper bounds (capacities) on the arcs.
714 714
    /// If none of the functions \ref upperMap(), \ref capacityMap()
715 715
    /// and \ref boundMaps() is used before calling \ref run(),
716 716
    /// the upper bounds (capacities) will be set to
717 717
    /// \c std::numeric_limits<Flow>::max() on all arcs.
718 718
    ///
719 719
    /// \param map An arc map storing the upper bounds.
720 720
    /// Its \c Value type must be convertible to the \c Flow type
721 721
    /// of the algorithm.
722 722
    ///
723 723
    /// \return <tt>(*this)</tt>
724 724
    template<typename UPPER>
725 725
    NetworkSimplex& upperMap(const UPPER& map) {
726 726
      delete _pupper;
727 727
      _pupper = new FlowArcMap(_graph);
728 728
      for (ArcIt a(_graph); a != INVALID; ++a) {
729 729
        (*_pupper)[a] = map[a];
730 730
      }
731 731
      return *this;
732 732
    }
733 733

	
734 734
    /// \brief Set the upper bounds (capacities) on the arcs.
735 735
    ///
736 736
    /// This function sets the upper bounds (capacities) on the arcs.
737 737
    /// It is just an alias for \ref upperMap().
738 738
    ///
739 739
    /// \return <tt>(*this)</tt>
740 740
    template<typename CAP>
741 741
    NetworkSimplex& capacityMap(const CAP& map) {
742 742
      return upperMap(map);
743 743
    }
744 744

	
745 745
    /// \brief Set the lower and upper bounds on the arcs.
746 746
    ///
747 747
    /// This function sets the lower and upper bounds on the arcs.
748 748
    /// If neither this function nor \ref lowerMap() is used before
749 749
    /// calling \ref run(), the lower bounds will be set to zero
750 750
    /// on all arcs.
751 751
    /// If none of the functions \ref upperMap(), \ref capacityMap()
752 752
    /// and \ref boundMaps() is used before calling \ref run(),
753 753
    /// the upper bounds (capacities) will be set to
754 754
    /// \c std::numeric_limits<Flow>::max() on all arcs.
755 755
    ///
756 756
    /// \param lower An arc map storing the lower bounds.
757 757
    /// \param upper An arc map storing the upper bounds.
758 758
    ///
759 759
    /// The \c Value type of the maps must be convertible to the
760 760
    /// \c Flow type of the algorithm.
761 761
    ///
762 762
    /// \note This function is just a shortcut of calling \ref lowerMap()
763 763
    /// and \ref upperMap() separately.
764 764
    ///
765 765
    /// \return <tt>(*this)</tt>
766 766
    template <typename LOWER, typename UPPER>
767 767
    NetworkSimplex& boundMaps(const LOWER& lower, const UPPER& upper) {
768 768
      return lowerMap(lower).upperMap(upper);
769 769
    }
770 770

	
771 771
    /// \brief Set the costs of the arcs.
772 772
    ///
773 773
    /// This function sets the costs of the arcs.
774 774
    /// If it is not used before calling \ref run(), the costs
775 775
    /// will be set to \c 1 on all arcs.
776 776
    ///
777 777
    /// \param map An arc map storing the costs.
778 778
    /// Its \c Value type must be convertible to the \c Cost type
779 779
    /// of the algorithm.
780 780
    ///
781 781
    /// \return <tt>(*this)</tt>
782 782
    template<typename COST>
783 783
    NetworkSimplex& costMap(const COST& map) {
784 784
      delete _pcost;
785 785
      _pcost = new CostArcMap(_graph);
786 786
      for (ArcIt a(_graph); a != INVALID; ++a) {
787 787
        (*_pcost)[a] = map[a];
788 788
      }
789 789
      return *this;
790 790
    }
791 791

	
792 792
    /// \brief Set the supply values of the nodes.
793 793
    ///
794 794
    /// This function sets the supply values of the nodes.
795 795
    /// If neither this function nor \ref stSupply() is used before
796 796
    /// calling \ref run(), the supply of each node will be set to zero.
797 797
    /// (It makes sense only if non-zero lower bounds are given.)
798 798
    ///
799 799
    /// \param map A node map storing the supply values.
800 800
    /// Its \c Value type must be convertible to the \c Flow type
801 801
    /// of the algorithm.
802 802
    ///
803 803
    /// \return <tt>(*this)</tt>
804 804
    template<typename SUP>
805 805
    NetworkSimplex& supplyMap(const SUP& map) {
806 806
      delete _psupply;
807 807
      _pstsup = false;
808 808
      _psupply = new FlowNodeMap(_graph);
809 809
      for (NodeIt n(_graph); n != INVALID; ++n) {
810 810
        (*_psupply)[n] = map[n];
811 811
      }
812 812
      return *this;
813 813
    }
814 814

	
815 815
    /// \brief Set single source and target nodes and a supply value.
816 816
    ///
817 817
    /// This function sets a single source node and a single target node
818 818
    /// and the required flow value.
819 819
    /// If neither this function nor \ref supplyMap() is used before
820 820
    /// calling \ref run(), the supply of each node will be set to zero.
821 821
    /// (It makes sense only if non-zero lower bounds are given.)
822 822
    ///
823 823
    /// \param s The source node.
824 824
    /// \param t The target node.
825 825
    /// \param k The required amount of flow from node \c s to node \c t
826 826
    /// (i.e. the supply of \c s and the demand of \c t).
827 827
    ///
828 828
    /// \return <tt>(*this)</tt>
829 829
    NetworkSimplex& stSupply(const Node& s, const Node& t, Flow k) {
830 830
      delete _psupply;
831 831
      _psupply = NULL;
832 832
      _pstsup = true;
833 833
      _psource = s;
834 834
      _ptarget = t;
835 835
      _pstflow = k;
836 836
      return *this;
837 837
    }
838 838
    
839 839
    /// \brief Set the problem type.
840 840
    ///
841 841
    /// This function sets the problem type for the algorithm.
842 842
    /// If it is not used before calling \ref run(), the \ref GEQ problem
843 843
    /// type will be used.
844 844
    ///
845 845
    /// For more information see \ref ProblemType.
846 846
    ///
847 847
    /// \return <tt>(*this)</tt>
848 848
    NetworkSimplex& problemType(ProblemType problem_type) {
849 849
      _ptype = problem_type;
850 850
      return *this;
851 851
    }
852 852

	
853 853
    /// \brief Set the flow map.
854 854
    ///
855 855
    /// This function sets the flow map.
856 856
    /// If it is not used before calling \ref run(), an instance will
857 857
    /// be allocated automatically. The destructor deallocates this
858 858
    /// automatically allocated map, of course.
859 859
    ///
860 860
    /// \return <tt>(*this)</tt>
861 861
    NetworkSimplex& flowMap(FlowMap& map) {
862 862
      if (_local_flow) {
863 863
        delete _flow_map;
864 864
        _local_flow = false;
865 865
      }
866 866
      _flow_map = &map;
867 867
      return *this;
868 868
    }
869 869

	
870 870
    /// \brief Set the potential map.
871 871
    ///
872 872
    /// This function sets the potential map, which is used for storing
873 873
    /// the dual solution.
874 874
    /// If it is not used before calling \ref run(), an instance will
875 875
    /// be allocated automatically. The destructor deallocates this
876 876
    /// automatically allocated map, of course.
877 877
    ///
878 878
    /// \return <tt>(*this)</tt>
879 879
    NetworkSimplex& potentialMap(PotentialMap& map) {
880 880
      if (_local_potential) {
881 881
        delete _potential_map;
882 882
        _local_potential = false;
883 883
      }
884 884
      _potential_map = &map;
885 885
      return *this;
886 886
    }
887 887
    
888 888
    /// @}
889 889

	
890 890
    /// \name Execution Control
891 891
    /// The algorithm can be executed using \ref run().
892 892

	
893 893
    /// @{
894 894

	
895 895
    /// \brief Run the algorithm.
896 896
    ///
897 897
    /// This function runs the algorithm.
898 898
    /// The paramters can be specified using functions \ref lowerMap(),
899 899
    /// \ref upperMap(), \ref capacityMap(), \ref boundMaps(),
900 900
    /// \ref costMap(), \ref supplyMap(), \ref stSupply(), 
901 901
    /// \ref problemType(), \ref flowMap() and \ref potentialMap().
902 902
    /// For example,
903 903
    /// \code
904 904
    ///   NetworkSimplex<ListDigraph> ns(graph);
905 905
    ///   ns.boundMaps(lower, upper).costMap(cost)
906 906
    ///     .supplyMap(sup).run();
907 907
    /// \endcode
908 908
    ///
909 909
    /// This function can be called more than once. All the parameters
910 910
    /// that have been given are kept for the next call, unless
911 911
    /// \ref reset() is called, thus only the modified parameters
912 912
    /// have to be set again. See \ref reset() for examples.
913 913
    ///
914 914
    /// \param pivot_rule The pivot rule that will be used during the
915 915
    /// algorithm. For more information see \ref PivotRule.
916 916
    ///
917 917
    /// \return \c true if a feasible flow can be found.
918 918
    bool run(PivotRule pivot_rule = BLOCK_SEARCH) {
919 919
      return init() && start(pivot_rule);
920 920
    }
921 921

	
922 922
    /// \brief Reset all the parameters that have been given before.
923 923
    ///
924 924
    /// This function resets all the paramaters that have been given
925 925
    /// before using functions \ref lowerMap(), \ref upperMap(),
926 926
    /// \ref capacityMap(), \ref boundMaps(), \ref costMap(),
927 927
    /// \ref supplyMap(), \ref stSupply(), \ref problemType(), 
928 928
    /// \ref flowMap() and \ref potentialMap().
929 929
    ///
930 930
    /// It is useful for multiple run() calls. If this function is not
931 931
    /// used, all the parameters given before are kept for the next
932 932
    /// \ref run() call.
933 933
    ///
934 934
    /// For example,
935 935
    /// \code
936 936
    ///   NetworkSimplex<ListDigraph> ns(graph);
937 937
    ///
938 938
    ///   // First run
939 939
    ///   ns.lowerMap(lower).capacityMap(cap).costMap(cost)
940 940
    ///     .supplyMap(sup).run();
941 941
    ///
942 942
    ///   // Run again with modified cost map (reset() is not called,
943 943
    ///   // so only the cost map have to be set again)
944 944
    ///   cost[e] += 100;
945 945
    ///   ns.costMap(cost).run();
946 946
    ///
947 947
    ///   // Run again from scratch using reset()
948 948
    ///   // (the lower bounds will be set to zero on all arcs)
949 949
    ///   ns.reset();
950 950
    ///   ns.capacityMap(cap).costMap(cost)
951 951
    ///     .supplyMap(sup).run();
952 952
    /// \endcode
953 953
    ///
954 954
    /// \return <tt>(*this)</tt>
955 955
    NetworkSimplex& reset() {
956 956
      delete _plower;
957 957
      delete _pupper;
958 958
      delete _pcost;
959 959
      delete _psupply;
960 960
      _plower = NULL;
961 961
      _pupper = NULL;
962 962
      _pcost = NULL;
963 963
      _psupply = NULL;
964 964
      _pstsup = false;
965 965
      _ptype = GEQ;
966 966
      if (_local_flow) delete _flow_map;
967 967
      if (_local_potential) delete _potential_map;
968 968
      _flow_map = NULL;
969 969
      _potential_map = NULL;
970 970
      _local_flow = false;
971 971
      _local_potential = false;
972 972

	
973 973
      return *this;
974 974
    }
975 975

	
976 976
    /// @}
977 977

	
978 978
    /// \name Query Functions
979 979
    /// The results of the algorithm can be obtained using these
980 980
    /// functions.\n
981 981
    /// The \ref run() function must be called before using them.
982 982

	
983 983
    /// @{
984 984

	
985 985
    /// \brief Return the total cost of the found flow.
986 986
    ///
987 987
    /// This function returns the total cost of the found flow.
988 988
    /// The complexity of the function is O(e).
989 989
    ///
990 990
    /// \note The return type of the function can be specified as a
991 991
    /// template parameter. For example,
992 992
    /// \code
993 993
    ///   ns.totalCost<double>();
994 994
    /// \endcode
995 995
    /// It is useful if the total cost cannot be stored in the \c Cost
996 996
    /// type of the algorithm, which is the default return type of the
997 997
    /// function.
998 998
    ///
999 999
    /// \pre \ref run() must be called before using this function.
1000 1000
    template <typename Num>
1001 1001
    Num totalCost() const {
1002 1002
      Num c = 0;
1003 1003
      if (_pcost) {
1004 1004
        for (ArcIt e(_graph); e != INVALID; ++e)
1005 1005
          c += (*_flow_map)[e] * (*_pcost)[e];
1006 1006
      } else {
1007 1007
        for (ArcIt e(_graph); e != INVALID; ++e)
1008 1008
          c += (*_flow_map)[e];
1009 1009
      }
1010 1010
      return c;
1011 1011
    }
1012 1012

	
1013 1013
#ifndef DOXYGEN
1014 1014
    Cost totalCost() const {
1015 1015
      return totalCost<Cost>();
1016 1016
    }
1017 1017
#endif
1018 1018

	
1019 1019
    /// \brief Return the flow on the given arc.
1020 1020
    ///
1021 1021
    /// This function returns the flow on the given arc.
1022 1022
    ///
1023 1023
    /// \pre \ref run() must be called before using this function.
1024 1024
    Flow flow(const Arc& a) const {
1025 1025
      return (*_flow_map)[a];
1026 1026
    }
1027 1027

	
1028 1028
    /// \brief Return a const reference to the flow map.
1029 1029
    ///
1030 1030
    /// This function returns a const reference to an arc map storing
1031 1031
    /// the found flow.
1032 1032
    ///
1033 1033
    /// \pre \ref run() must be called before using this function.
1034 1034
    const FlowMap& flowMap() const {
1035 1035
      return *_flow_map;
1036 1036
    }
1037 1037

	
1038 1038
    /// \brief Return the potential (dual value) of the given node.
1039 1039
    ///
1040 1040
    /// This function returns the potential (dual value) of the
1041 1041
    /// given node.
1042 1042
    ///
1043 1043
    /// \pre \ref run() must be called before using this function.
1044 1044
    Cost potential(const Node& n) const {
1045 1045
      return (*_potential_map)[n];
1046 1046
    }
1047 1047

	
1048 1048
    /// \brief Return a const reference to the potential map
1049 1049
    /// (the dual solution).
1050 1050
    ///
1051 1051
    /// This function returns a const reference to a node map storing
1052 1052
    /// the found potentials, which form the dual solution of the
1053 1053
    /// \ref min_cost_flow "minimum cost flow" problem.
1054 1054
    ///
1055 1055
    /// \pre \ref run() must be called before using this function.
1056 1056
    const PotentialMap& potentialMap() const {
1057 1057
      return *_potential_map;
1058 1058
    }
1059 1059

	
1060 1060
    /// @}
1061 1061

	
1062 1062
  private:
1063 1063

	
1064 1064
    // Initialize internal data structures
1065 1065
    bool init() {
1066 1066
      // Initialize result maps
1067 1067
      if (!_flow_map) {
1068 1068
        _flow_map = new FlowMap(_graph);
1069 1069
        _local_flow = true;
1070 1070
      }
1071 1071
      if (!_potential_map) {
1072 1072
        _potential_map = new PotentialMap(_graph);
1073 1073
        _local_potential = true;
1074 1074
      }
1075 1075

	
1076 1076
      // Initialize vectors
1077 1077
      _node_num = countNodes(_graph);
1078 1078
      _arc_num = countArcs(_graph);
1079 1079
      int all_node_num = _node_num + 1;
1080 1080
      int all_arc_num = _arc_num + _node_num;
1081 1081
      if (_node_num == 0) return false;
1082 1082

	
1083 1083
      _arc_ref.resize(_arc_num);
1084 1084
      _source.resize(all_arc_num);
1085 1085
      _target.resize(all_arc_num);
1086 1086

	
1087 1087
      _cap.resize(all_arc_num);
1088 1088
      _cost.resize(all_arc_num);
1089 1089
      _supply.resize(all_node_num);
1090 1090
      _flow.resize(all_arc_num);
1091 1091
      _pi.resize(all_node_num);
1092 1092

	
1093 1093
      _parent.resize(all_node_num);
1094 1094
      _pred.resize(all_node_num);
1095 1095
      _forward.resize(all_node_num);
1096 1096
      _thread.resize(all_node_num);
1097 1097
      _rev_thread.resize(all_node_num);
1098 1098
      _succ_num.resize(all_node_num);
1099 1099
      _last_succ.resize(all_node_num);
1100 1100
      _state.resize(all_arc_num);
1101 1101

	
1102 1102
      // Initialize node related data
1103 1103
      bool valid_supply = true;
1104 1104
      Flow sum_supply = 0;
1105 1105
      if (!_pstsup && !_psupply) {
1106 1106
        _pstsup = true;
1107 1107
        _psource = _ptarget = NodeIt(_graph);
1108 1108
        _pstflow = 0;
1109 1109
      }
1110 1110
      if (_psupply) {
1111 1111
        int i = 0;
1112 1112
        for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
1113 1113
          _node_id[n] = i;
1114 1114
          _supply[i] = (*_psupply)[n];
1115 1115
          sum_supply += _supply[i];
1116 1116
        }
1117 1117
        valid_supply = (_ptype == GEQ && sum_supply <= 0) ||
1118 1118
                       (_ptype == LEQ && sum_supply >= 0);
1119 1119
      } else {
1120 1120
        int i = 0;
1121 1121
        for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
1122 1122
          _node_id[n] = i;
1123 1123
          _supply[i] = 0;
1124 1124
        }
1125 1125
        _supply[_node_id[_psource]] =  _pstflow;
1126 1126
        _supply[_node_id[_ptarget]] = -_pstflow;
1127 1127
      }
1128 1128
      if (!valid_supply) return false;
1129 1129

	
1130 1130
      // Infinite capacity value
1131 1131
      Flow inf_cap =
1132 1132
        std::numeric_limits<Flow>::has_infinity ?
1133 1133
        std::numeric_limits<Flow>::infinity() :
1134 1134
        std::numeric_limits<Flow>::max();
1135 1135

	
1136 1136
      // Initialize artifical cost
1137 1137
      Cost art_cost;
1138 1138
      if (std::numeric_limits<Cost>::is_exact) {
1139 1139
        art_cost = std::numeric_limits<Cost>::max() / 4 + 1;
1140 1140
      } else {
1141 1141
        art_cost = std::numeric_limits<Cost>::min();
1142 1142
        for (int i = 0; i != _arc_num; ++i) {
1143 1143
          if (_cost[i] > art_cost) art_cost = _cost[i];
1144 1144
        }
1145 1145
        art_cost = (art_cost + 1) * _node_num;
1146 1146
      }
1147 1147

	
1148 1148
      // Run Circulation to check if a feasible solution exists
1149 1149
      typedef ConstMap<Arc, Flow> ConstArcMap;
1150
      ConstArcMap zero_arc_map(0), inf_arc_map(inf_cap);
1150 1151
      FlowNodeMap *csup = NULL;
1151 1152
      bool local_csup = false;
1152 1153
      if (_psupply) {
1153 1154
        csup = _psupply;
1154 1155
      } else {
1155 1156
        csup = new FlowNodeMap(_graph, 0);
1156 1157
        (*csup)[_psource] =  _pstflow;
1157 1158
        (*csup)[_ptarget] = -_pstflow;
1158 1159
        local_csup = true;
1159 1160
      }
1160 1161
      bool circ_result = false;
1161 1162
      if (_ptype == GEQ || (_ptype == LEQ && sum_supply == 0)) {
1162 1163
        // GEQ problem type
1163 1164
        if (_plower) {
1164 1165
          if (_pupper) {
1165 1166
            Circulation<GR, FlowArcMap, FlowArcMap, FlowNodeMap>
1166 1167
              circ(_graph, *_plower, *_pupper, *csup);
1167 1168
            circ_result = circ.run();
1168 1169
          } else {
1169 1170
            Circulation<GR, FlowArcMap, ConstArcMap, FlowNodeMap>
1170
              circ(_graph, *_plower, ConstArcMap(inf_cap), *csup);
1171
              circ(_graph, *_plower, inf_arc_map, *csup);
1171 1172
            circ_result = circ.run();
1172 1173
          }
1173 1174
        } else {
1174 1175
          if (_pupper) {
1175 1176
            Circulation<GR, ConstArcMap, FlowArcMap, FlowNodeMap>
1176
              circ(_graph, ConstArcMap(0), *_pupper, *csup);
1177
              circ(_graph, zero_arc_map, *_pupper, *csup);
1177 1178
            circ_result = circ.run();
1178 1179
          } else {
1179 1180
            Circulation<GR, ConstArcMap, ConstArcMap, FlowNodeMap>
1180
              circ(_graph, ConstArcMap(0), ConstArcMap(inf_cap), *csup);
1181
              circ(_graph, zero_arc_map, inf_arc_map, *csup);
1181 1182
            circ_result = circ.run();
1182 1183
          }
1183 1184
        }
1184 1185
      } else {
1185 1186
        // LEQ problem type
1186 1187
        typedef ReverseDigraph<const GR> RevGraph;
1187 1188
        typedef NegMap<FlowNodeMap> NegNodeMap;
1188 1189
        RevGraph rgraph(_graph);
1189 1190
        NegNodeMap neg_csup(*csup);
1190 1191
        if (_plower) {
1191 1192
          if (_pupper) {
1192 1193
            Circulation<RevGraph, FlowArcMap, FlowArcMap, NegNodeMap>
1193 1194
              circ(rgraph, *_plower, *_pupper, neg_csup);
1194 1195
            circ_result = circ.run();
1195 1196
          } else {
1196 1197
            Circulation<RevGraph, FlowArcMap, ConstArcMap, NegNodeMap>
1197
              circ(rgraph, *_plower, ConstArcMap(inf_cap), neg_csup);
1198
              circ(rgraph, *_plower, inf_arc_map, neg_csup);
1198 1199
            circ_result = circ.run();
1199 1200
          }
1200 1201
        } else {
1201 1202
          if (_pupper) {
1202 1203
            Circulation<RevGraph, ConstArcMap, FlowArcMap, NegNodeMap>
1203
              circ(rgraph, ConstArcMap(0), *_pupper, neg_csup);
1204
              circ(rgraph, zero_arc_map, *_pupper, neg_csup);
1204 1205
            circ_result = circ.run();
1205 1206
          } else {
1206 1207
            Circulation<RevGraph, ConstArcMap, ConstArcMap, NegNodeMap>
1207
              circ(rgraph, ConstArcMap(0), ConstArcMap(inf_cap), neg_csup);
1208
              circ(rgraph, zero_arc_map, inf_arc_map, neg_csup);
1208 1209
            circ_result = circ.run();
1209 1210
          }
1210 1211
        }
1211 1212
      }
1212 1213
      if (local_csup) delete csup;
1213 1214
      if (!circ_result) return false;
1214 1215

	
1215 1216
      // Set data for the artificial root node
1216 1217
      _root = _node_num;
1217 1218
      _parent[_root] = -1;
1218 1219
      _pred[_root] = -1;
1219 1220
      _thread[_root] = 0;
1220 1221
      _rev_thread[0] = _root;
1221 1222
      _succ_num[_root] = all_node_num;
1222 1223
      _last_succ[_root] = _root - 1;
1223 1224
      _supply[_root] = -sum_supply;
1224 1225
      if (sum_supply < 0) {
1225 1226
        _pi[_root] = -art_cost;
1226 1227
      } else {
1227 1228
        _pi[_root] = art_cost;
1228 1229
      }
1229 1230

	
1230 1231
      // Store the arcs in a mixed order
1231 1232
      int k = std::max(int(std::sqrt(double(_arc_num))), 10);
1232 1233
      int i = 0;
1233 1234
      for (ArcIt e(_graph); e != INVALID; ++e) {
1234 1235
        _arc_ref[i] = e;
1235 1236
        if ((i += k) >= _arc_num) i = (i % k) + 1;
1236 1237
      }
1237 1238

	
1238 1239
      // Initialize arc maps
1239 1240
      if (_pupper && _pcost) {
1240 1241
        for (int i = 0; i != _arc_num; ++i) {
1241 1242
          Arc e = _arc_ref[i];
1242 1243
          _source[i] = _node_id[_graph.source(e)];
1243 1244
          _target[i] = _node_id[_graph.target(e)];
1244 1245
          _cap[i] = (*_pupper)[e];
1245 1246
          _cost[i] = (*_pcost)[e];
1246 1247
          _flow[i] = 0;
1247 1248
          _state[i] = STATE_LOWER;
1248 1249
        }
1249 1250
      } else {
1250 1251
        for (int i = 0; i != _arc_num; ++i) {
1251 1252
          Arc e = _arc_ref[i];
1252 1253
          _source[i] = _node_id[_graph.source(e)];
1253 1254
          _target[i] = _node_id[_graph.target(e)];
1254 1255
          _flow[i] = 0;
1255 1256
          _state[i] = STATE_LOWER;
1256 1257
        }
1257 1258
        if (_pupper) {
1258 1259
          for (int i = 0; i != _arc_num; ++i)
1259 1260
            _cap[i] = (*_pupper)[_arc_ref[i]];
1260 1261
        } else {
1261 1262
          for (int i = 0; i != _arc_num; ++i)
1262 1263
            _cap[i] = inf_cap;
1263 1264
        }
1264 1265
        if (_pcost) {
1265 1266
          for (int i = 0; i != _arc_num; ++i)
1266 1267
            _cost[i] = (*_pcost)[_arc_ref[i]];
1267 1268
        } else {
1268 1269
          for (int i = 0; i != _arc_num; ++i)
1269 1270
            _cost[i] = 1;
1270 1271
        }
1271 1272
      }
1272 1273
      
1273 1274
      // Remove non-zero lower bounds
1274 1275
      if (_plower) {
1275 1276
        for (int i = 0; i != _arc_num; ++i) {
1276 1277
          Flow c = (*_plower)[_arc_ref[i]];
1277 1278
          if (c != 0) {
1278 1279
            _cap[i] -= c;
1279 1280
            _supply[_source[i]] -= c;
1280 1281
            _supply[_target[i]] += c;
1281 1282
          }
1282 1283
        }
1283 1284
      }
1284 1285

	
1285 1286
      // Add artificial arcs and initialize the spanning tree data structure
1286 1287
      for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
1287 1288
        _thread[u] = u + 1;
1288 1289
        _rev_thread[u + 1] = u;
1289 1290
        _succ_num[u] = 1;
1290 1291
        _last_succ[u] = u;
1291 1292
        _parent[u] = _root;
1292 1293
        _pred[u] = e;
1293 1294
        _cost[e] = art_cost;
1294 1295
        _cap[e] = inf_cap;
1295 1296
        _state[e] = STATE_TREE;
1296 1297
        if (_supply[u] > 0 || (_supply[u] == 0 && sum_supply <= 0)) {
1297 1298
          _flow[e] = _supply[u];
1298 1299
          _forward[u] = true;
1299 1300
          _pi[u] = -art_cost + _pi[_root];
1300 1301
        } else {
1301 1302
          _flow[e] = -_supply[u];
1302 1303
          _forward[u] = false;
1303 1304
          _pi[u] = art_cost + _pi[_root];
1304 1305
        }
1305 1306
      }
1306 1307

	
1307 1308
      return true;
1308 1309
    }
1309 1310

	
1310 1311
    // Find the join node
1311 1312
    void findJoinNode() {
1312 1313
      int u = _source[in_arc];
1313 1314
      int v = _target[in_arc];
1314 1315
      while (u != v) {
1315 1316
        if (_succ_num[u] < _succ_num[v]) {
1316 1317
          u = _parent[u];
1317 1318
        } else {
1318 1319
          v = _parent[v];
1319 1320
        }
1320 1321
      }
1321 1322
      join = u;
1322 1323
    }
1323 1324

	
1324 1325
    // Find the leaving arc of the cycle and returns true if the
1325 1326
    // leaving arc is not the same as the entering arc
1326 1327
    bool findLeavingArc() {
1327 1328
      // Initialize first and second nodes according to the direction
1328 1329
      // of the cycle
1329 1330
      if (_state[in_arc] == STATE_LOWER) {
1330 1331
        first  = _source[in_arc];
1331 1332
        second = _target[in_arc];
1332 1333
      } else {
1333 1334
        first  = _target[in_arc];
1334 1335
        second = _source[in_arc];
1335 1336
      }
1336 1337
      delta = _cap[in_arc];
1337 1338
      int result = 0;
1338 1339
      Flow d;
1339 1340
      int e;
1340 1341

	
1341 1342
      // Search the cycle along the path form the first node to the root
1342 1343
      for (int u = first; u != join; u = _parent[u]) {
1343 1344
        e = _pred[u];
1344 1345
        d = _forward[u] ? _flow[e] : _cap[e] - _flow[e];
1345 1346
        if (d < delta) {
1346 1347
          delta = d;
1347 1348
          u_out = u;
1348 1349
          result = 1;
1349 1350
        }
1350 1351
      }
1351 1352
      // Search the cycle along the path form the second node to the root
1352 1353
      for (int u = second; u != join; u = _parent[u]) {
1353 1354
        e = _pred[u];
1354 1355
        d = _forward[u] ? _cap[e] - _flow[e] : _flow[e];
1355 1356
        if (d <= delta) {
1356 1357
          delta = d;
1357 1358
          u_out = u;
1358 1359
          result = 2;
1359 1360
        }
1360 1361
      }
1361 1362

	
1362 1363
      if (result == 1) {
1363 1364
        u_in = first;
1364 1365
        v_in = second;
1365 1366
      } else {
1366 1367
        u_in = second;
1367 1368
        v_in = first;
1368 1369
      }
1369 1370
      return result != 0;
1370 1371
    }
1371 1372

	
1372 1373
    // Change _flow and _state vectors
1373 1374
    void changeFlow(bool change) {
1374 1375
      // Augment along the cycle
1375 1376
      if (delta > 0) {
1376 1377
        Flow val = _state[in_arc] * delta;
1377 1378
        _flow[in_arc] += val;
1378 1379
        for (int u = _source[in_arc]; u != join; u = _parent[u]) {
1379 1380
          _flow[_pred[u]] += _forward[u] ? -val : val;
1380 1381
        }
1381 1382
        for (int u = _target[in_arc]; u != join; u = _parent[u]) {
1382 1383
          _flow[_pred[u]] += _forward[u] ? val : -val;
1383 1384
        }
1384 1385
      }
1385 1386
      // Update the state of the entering and leaving arcs
1386 1387
      if (change) {
1387 1388
        _state[in_arc] = STATE_TREE;
1388 1389
        _state[_pred[u_out]] =
1389 1390
          (_flow[_pred[u_out]] == 0) ? STATE_LOWER : STATE_UPPER;
1390 1391
      } else {
1391 1392
        _state[in_arc] = -_state[in_arc];
1392 1393
      }
1393 1394
    }
1394 1395

	
1395 1396
    // Update the tree structure
1396 1397
    void updateTreeStructure() {
1397 1398
      int u, w;
1398 1399
      int old_rev_thread = _rev_thread[u_out];
1399 1400
      int old_succ_num = _succ_num[u_out];
1400 1401
      int old_last_succ = _last_succ[u_out];
1401 1402
      v_out = _parent[u_out];
1402 1403

	
1403 1404
      u = _last_succ[u_in];  // the last successor of u_in
1404 1405
      right = _thread[u];    // the node after it
1405 1406

	
1406 1407
      // Handle the case when old_rev_thread equals to v_in
1407 1408
      // (it also means that join and v_out coincide)
1408 1409
      if (old_rev_thread == v_in) {
1409 1410
        last = _thread[_last_succ[u_out]];
1410 1411
      } else {
1411 1412
        last = _thread[v_in];
1412 1413
      }
1413 1414

	
1414 1415
      // Update _thread and _parent along the stem nodes (i.e. the nodes
1415 1416
      // between u_in and u_out, whose parent have to be changed)
1416 1417
      _thread[v_in] = stem = u_in;
1417 1418
      _dirty_revs.clear();
1418 1419
      _dirty_revs.push_back(v_in);
1419 1420
      par_stem = v_in;
1420 1421
      while (stem != u_out) {
1421 1422
        // Insert the next stem node into the thread list
1422 1423
        new_stem = _parent[stem];
1423 1424
        _thread[u] = new_stem;
1424 1425
        _dirty_revs.push_back(u);
1425 1426

	
1426 1427
        // Remove the subtree of stem from the thread list
1427 1428
        w = _rev_thread[stem];
1428 1429
        _thread[w] = right;
1429 1430
        _rev_thread[right] = w;
1430 1431

	
1431 1432
        // Change the parent node and shift stem nodes
1432 1433
        _parent[stem] = par_stem;
1433 1434
        par_stem = stem;
1434 1435
        stem = new_stem;
1435 1436

	
1436 1437
        // Update u and right
1437 1438
        u = _last_succ[stem] == _last_succ[par_stem] ?
1438 1439
          _rev_thread[par_stem] : _last_succ[stem];
1439 1440
        right = _thread[u];
1440 1441
      }
1441 1442
      _parent[u_out] = par_stem;
1442 1443
      _thread[u] = last;
1443 1444
      _rev_thread[last] = u;
1444 1445
      _last_succ[u_out] = u;
1445 1446

	
1446 1447
      // Remove the subtree of u_out from the thread list except for
1447 1448
      // the case when old_rev_thread equals to v_in
1448 1449
      // (it also means that join and v_out coincide)
1449 1450
      if (old_rev_thread != v_in) {
1450 1451
        _thread[old_rev_thread] = right;
1451 1452
        _rev_thread[right] = old_rev_thread;
1452 1453
      }
1453 1454

	
1454 1455
      // Update _rev_thread using the new _thread values
1455 1456
      for (int i = 0; i < int(_dirty_revs.size()); ++i) {
1456 1457
        u = _dirty_revs[i];
1457 1458
        _rev_thread[_thread[u]] = u;
1458 1459
      }
1459 1460

	
1460 1461
      // Update _pred, _forward, _last_succ and _succ_num for the
1461 1462
      // stem nodes from u_out to u_in
1462 1463
      int tmp_sc = 0, tmp_ls = _last_succ[u_out];
1463 1464
      u = u_out;
1464 1465
      while (u != u_in) {
1465 1466
        w = _parent[u];
1466 1467
        _pred[u] = _pred[w];
1467 1468
        _forward[u] = !_forward[w];
1468 1469
        tmp_sc += _succ_num[u] - _succ_num[w];
1469 1470
        _succ_num[u] = tmp_sc;
1470 1471
        _last_succ[w] = tmp_ls;
1471 1472
        u = w;
1472 1473
      }
1473 1474
      _pred[u_in] = in_arc;
1474 1475
      _forward[u_in] = (u_in == _source[in_arc]);
1475 1476
      _succ_num[u_in] = old_succ_num;
1476 1477

	
1477 1478
      // Set limits for updating _last_succ form v_in and v_out
1478 1479
      // towards the root
1479 1480
      int up_limit_in = -1;
1480 1481
      int up_limit_out = -1;
1481 1482
      if (_last_succ[join] == v_in) {
1482 1483
        up_limit_out = join;
1483 1484
      } else {
1484 1485
        up_limit_in = join;
1485 1486
      }
1486 1487

	
1487 1488
      // Update _last_succ from v_in towards the root
1488 1489
      for (u = v_in; u != up_limit_in && _last_succ[u] == v_in;
1489 1490
           u = _parent[u]) {
1490 1491
        _last_succ[u] = _last_succ[u_out];
1491 1492
      }
1492 1493
      // Update _last_succ from v_out towards the root
1493 1494
      if (join != old_rev_thread && v_in != old_rev_thread) {
1494 1495
        for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
1495 1496
             u = _parent[u]) {
1496 1497
          _last_succ[u] = old_rev_thread;
1497 1498
        }
1498 1499
      } else {
1499 1500
        for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
1500 1501
             u = _parent[u]) {
1501 1502
          _last_succ[u] = _last_succ[u_out];
1502 1503
        }
1503 1504
      }
1504 1505

	
1505 1506
      // Update _succ_num from v_in to join
1506 1507
      for (u = v_in; u != join; u = _parent[u]) {
1507 1508
        _succ_num[u] += old_succ_num;
1508 1509
      }
1509 1510
      // Update _succ_num from v_out to join
1510 1511
      for (u = v_out; u != join; u = _parent[u]) {
1511 1512
        _succ_num[u] -= old_succ_num;
1512 1513
      }
1513 1514
    }
1514 1515

	
1515 1516
    // Update potentials
1516 1517
    void updatePotential() {
1517 1518
      Cost sigma = _forward[u_in] ?
1518 1519
        _pi[v_in] - _pi[u_in] - _cost[_pred[u_in]] :
1519 1520
        _pi[v_in] - _pi[u_in] + _cost[_pred[u_in]];
1520 1521
      // Update potentials in the subtree, which has been moved
1521 1522
      int end = _thread[_last_succ[u_in]];
1522 1523
      for (int u = u_in; u != end; u = _thread[u]) {
1523 1524
        _pi[u] += sigma;
1524 1525
      }
1525 1526
    }
1526 1527

	
1527 1528
    // Execute the algorithm
1528 1529
    bool start(PivotRule pivot_rule) {
1529 1530
      // Select the pivot rule implementation
1530 1531
      switch (pivot_rule) {
1531 1532
        case FIRST_ELIGIBLE:
1532 1533
          return start<FirstEligiblePivotRule>();
1533 1534
        case BEST_ELIGIBLE:
1534 1535
          return start<BestEligiblePivotRule>();
1535 1536
        case BLOCK_SEARCH:
1536 1537
          return start<BlockSearchPivotRule>();
1537 1538
        case CANDIDATE_LIST:
1538 1539
          return start<CandidateListPivotRule>();
1539 1540
        case ALTERING_LIST:
1540 1541
          return start<AlteringListPivotRule>();
1541 1542
      }
1542 1543
      return false;
1543 1544
    }
1544 1545

	
1545 1546
    template <typename PivotRuleImpl>
1546 1547
    bool start() {
1547 1548
      PivotRuleImpl pivot(*this);
1548 1549

	
1549 1550
      // Execute the Network Simplex algorithm
1550 1551
      while (pivot.findEnteringArc()) {
1551 1552
        findJoinNode();
1552 1553
        bool change = findLeavingArc();
1553 1554
        changeFlow(change);
1554 1555
        if (change) {
1555 1556
          updateTreeStructure();
1556 1557
          updatePotential();
1557 1558
        }
1558 1559
      }
1559 1560

	
1560 1561
      // Copy flow values to _flow_map
1561 1562
      if (_plower) {
1562 1563
        for (int i = 0; i != _arc_num; ++i) {
1563 1564
          Arc e = _arc_ref[i];
1564 1565
          _flow_map->set(e, (*_plower)[e] + _flow[i]);
1565 1566
        }
1566 1567
      } else {
1567 1568
        for (int i = 0; i != _arc_num; ++i) {
1568 1569
          _flow_map->set(_arc_ref[i], _flow[i]);
1569 1570
        }
1570 1571
      }
1571 1572
      // Copy potential values to _potential_map
1572 1573
      for (NodeIt n(_graph); n != INVALID; ++n) {
1573 1574
        _potential_map->set(n, _pi[_node_id[n]]);
1574 1575
      }
1575 1576

	
1576 1577
      return true;
1577 1578
    }
1578 1579

	
1579 1580
  }; //class NetworkSimplex
1580 1581

	
1581 1582
  ///@}
1582 1583

	
1583 1584
} //namespace lemon
1584 1585

	
1585 1586
#endif //LEMON_NETWORK_SIMPLEX_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
#include <iostream>
20 20
#include <fstream>
21 21

	
22 22
#include <lemon/list_graph.h>
23 23
#include <lemon/lgf_reader.h>
24 24

	
25 25
#include <lemon/network_simplex.h>
26 26

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

	
30 30
#include "test_tools.h"
31 31

	
32 32
using namespace lemon;
33 33

	
34 34
char test_lgf[] =
35 35
  "@nodes\n"
36 36
  "label  sup1 sup2 sup3 sup4 sup5\n"
37 37
  "    1    20   27    0   20   30\n"
38 38
  "    2    -4    0    0   -8   -3\n"
39 39
  "    3     0    0    0    0    0\n"
40 40
  "    4     0    0    0    0    0\n"
41 41
  "    5     9    0    0    6   11\n"
42 42
  "    6    -6    0    0   -5   -6\n"
43 43
  "    7     0    0    0    0    0\n"
44 44
  "    8     0    0    0    0    3\n"
45 45
  "    9     3    0    0    0    0\n"
46 46
  "   10    -2    0    0   -7   -2\n"
47 47
  "   11     0    0    0  -10    0\n"
48 48
  "   12   -20  -27    0  -30  -20\n"
49 49
  "\n"
50 50
  "@arcs\n"
51 51
  "       cost  cap low1 low2\n"
52 52
  " 1  2    70   11    0    8\n"
53 53
  " 1  3   150    3    0    1\n"
54 54
  " 1  4    80   15    0    2\n"
55 55
  " 2  8    80   12    0    0\n"
56 56
  " 3  5   140    5    0    3\n"
57 57
  " 4  6    60   10    0    1\n"
58 58
  " 4  7    80    2    0    0\n"
59 59
  " 4  8   110    3    0    0\n"
60 60
  " 5  7    60   14    0    0\n"
61 61
  " 5 11   120   12    0    0\n"
62 62
  " 6  3     0    3    0    0\n"
63 63
  " 6  9   140    4    0    0\n"
64 64
  " 6 10    90    8    0    0\n"
65 65
  " 7  1    30    5    0    0\n"
66 66
  " 8 12    60   16    0    4\n"
67 67
  " 9 12    50    6    0    0\n"
68 68
  "10 12    70   13    0    5\n"
69 69
  "10  2   100    7    0    0\n"
70 70
  "10  7    60   10    0    0\n"
71 71
  "11 10    20   14    0    6\n"
72 72
  "12 11    30   10    0    0\n"
73 73
  "\n"
74 74
  "@attributes\n"
75 75
  "source 1\n"
76 76
  "target 12\n";
77 77

	
78 78

	
79 79
enum ProblemType {
80 80
  EQ,
81 81
  GEQ,
82 82
  LEQ
83 83
};
84 84

	
85 85
// Check the interface of an MCF algorithm
86 86
template <typename GR, typename Flow, typename Cost>
87 87
class McfClassConcept
88 88
{
89 89
public:
90 90

	
91 91
  template <typename MCF>
92 92
  struct Constraints {
93 93
    void constraints() {
94 94
      checkConcept<concepts::Digraph, GR>();
95 95

	
96 96
      MCF mcf(g);
97 97

	
98 98
      b = mcf.reset()
99 99
             .lowerMap(lower)
100 100
             .upperMap(upper)
101 101
             .capacityMap(upper)
102 102
             .boundMaps(lower, upper)
103 103
             .costMap(cost)
104 104
             .supplyMap(sup)
105 105
             .stSupply(n, n, k)
106 106
             .flowMap(flow)
107 107
             .potentialMap(pot)
108 108
             .run();
109 109
      
110 110
      const MCF& const_mcf = mcf;
111 111

	
112 112
      const typename MCF::FlowMap &fm = const_mcf.flowMap();
113 113
      const typename MCF::PotentialMap &pm = const_mcf.potentialMap();
114 114

	
115 115
      v = const_mcf.totalCost();
116 116
      double x = const_mcf.template totalCost<double>();
117 117
      v = const_mcf.flow(a);
118 118
      v = const_mcf.potential(n);
119 119

	
120 120
      ignore_unused_variable_warning(fm);
121 121
      ignore_unused_variable_warning(pm);
122 122
      ignore_unused_variable_warning(x);
123 123
    }
124 124

	
125 125
    typedef typename GR::Node Node;
126 126
    typedef typename GR::Arc Arc;
127 127
    typedef concepts::ReadMap<Node, Flow> NM;
128 128
    typedef concepts::ReadMap<Arc, Flow> FAM;
129 129
    typedef concepts::ReadMap<Arc, Cost> CAM;
130 130

	
131 131
    const GR &g;
132 132
    const FAM &lower;
133 133
    const FAM &upper;
134 134
    const CAM &cost;
135 135
    const NM &sup;
136 136
    const Node &n;
137 137
    const Arc &a;
138 138
    const Flow &k;
139 139
    Flow v;
140 140
    bool b;
141 141

	
142 142
    typename MCF::FlowMap &flow;
143 143
    typename MCF::PotentialMap &pot;
144 144
  };
145 145

	
146 146
};
147 147

	
148 148

	
149 149
// Check the feasibility of the given flow (primal soluiton)
150 150
template < typename GR, typename LM, typename UM,
151 151
           typename SM, typename FM >
152 152
bool checkFlow( const GR& gr, const LM& lower, const UM& upper,
153 153
                const SM& supply, const FM& flow,
154 154
                ProblemType type = EQ )
155 155
{
156 156
  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
157 157

	
158 158
  for (ArcIt e(gr); e != INVALID; ++e) {
159 159
    if (flow[e] < lower[e] || flow[e] > upper[e]) return false;
160 160
  }
161 161

	
162 162
  for (NodeIt n(gr); n != INVALID; ++n) {
163 163
    typename SM::Value sum = 0;
164 164
    for (OutArcIt e(gr, n); e != INVALID; ++e)
165 165
      sum += flow[e];
166 166
    for (InArcIt e(gr, n); e != INVALID; ++e)
167 167
      sum -= flow[e];
168 168
    bool b = (type ==  EQ && sum == supply[n]) ||
169 169
             (type == GEQ && sum >= supply[n]) ||
170 170
             (type == LEQ && sum <= supply[n]);
171 171
    if (!b) return false;
172 172
  }
173 173

	
174 174
  return true;
175 175
}
176 176

	
177 177
// Check the feasibility of the given potentials (dual soluiton)
178 178
// using the "Complementary Slackness" optimality condition
179 179
template < typename GR, typename LM, typename UM,
180 180
           typename CM, typename SM, typename FM, typename PM >
181 181
bool checkPotential( const GR& gr, const LM& lower, const UM& upper,
182 182
                     const CM& cost, const SM& supply, const FM& flow, 
183 183
                     const PM& pi )
184 184
{
185 185
  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
186 186

	
187 187
  bool opt = true;
188 188
  for (ArcIt e(gr); opt && e != INVALID; ++e) {
189 189
    typename CM::Value red_cost =
190 190
      cost[e] + pi[gr.source(e)] - pi[gr.target(e)];
191 191
    opt = red_cost == 0 ||
192 192
          (red_cost > 0 && flow[e] == lower[e]) ||
193 193
          (red_cost < 0 && flow[e] == upper[e]);
194 194
  }
195 195
  
196 196
  for (NodeIt n(gr); opt && n != INVALID; ++n) {
197 197
    typename SM::Value sum = 0;
198 198
    for (OutArcIt e(gr, n); e != INVALID; ++e)
199 199
      sum += flow[e];
200 200
    for (InArcIt e(gr, n); e != INVALID; ++e)
201 201
      sum -= flow[e];
202 202
    opt = (sum == supply[n]) || (pi[n] == 0);
203 203
  }
204 204
  
205 205
  return opt;
206 206
}
207 207

	
208 208
// Run a minimum cost flow algorithm and check the results
209 209
template < typename MCF, typename GR,
210 210
           typename LM, typename UM,
211 211
           typename CM, typename SM >
212 212
void checkMcf( const MCF& mcf, bool mcf_result,
213 213
               const GR& gr, const LM& lower, const UM& upper,
214 214
               const CM& cost, const SM& supply,
215 215
               bool result, typename CM::Value total,
216 216
               const std::string &test_id = "",
217 217
               ProblemType type = EQ )
218 218
{
219 219
  check(mcf_result == result, "Wrong result " + test_id);
220 220
  if (result) {
221 221
    check(checkFlow(gr, lower, upper, supply, mcf.flowMap(), type),
222 222
          "The flow is not feasible " + test_id);
223 223
    check(mcf.totalCost() == total, "The flow is not optimal " + test_id);
224 224
    check(checkPotential(gr, lower, upper, cost, supply, mcf.flowMap(),
225 225
                         mcf.potentialMap()),
226 226
          "Wrong potentials " + test_id);
227 227
  }
228 228
}
229 229

	
230 230
int main()
231 231
{
232 232
  // Check the interfaces
233 233
  {
234 234
    typedef int Flow;
235 235
    typedef int Cost;
236
    // TODO: This typedef should be enabled if the standard maps are
237
    // reference maps in the graph concepts (See #190).
238
/**/
239
    //typedef concepts::Digraph GR;
240
    typedef ListDigraph GR;
241
/**/
236
    typedef concepts::Digraph GR;
242 237
    checkConcept< McfClassConcept<GR, Flow, Cost>,
243 238
                  NetworkSimplex<GR, Flow, Cost> >();
244 239
  }
245 240

	
246 241
  // Run various MCF tests
247 242
  typedef ListDigraph Digraph;
248 243
  DIGRAPH_TYPEDEFS(ListDigraph);
249 244

	
250 245
  // Read the test digraph
251 246
  Digraph gr;
252 247
  Digraph::ArcMap<int> c(gr), l1(gr), l2(gr), u(gr);
253 248
  Digraph::NodeMap<int> s1(gr), s2(gr), s3(gr), s4(gr), s5(gr);
254 249
  ConstMap<Arc, int> cc(1), cu(std::numeric_limits<int>::max());
255 250
  Node v, w;
256 251

	
257 252
  std::istringstream input(test_lgf);
258 253
  DigraphReader<Digraph>(gr, input)
259 254
    .arcMap("cost", c)
260 255
    .arcMap("cap", u)
261 256
    .arcMap("low1", l1)
262 257
    .arcMap("low2", l2)
263 258
    .nodeMap("sup1", s1)
264 259
    .nodeMap("sup2", s2)
265 260
    .nodeMap("sup3", s3)
266 261
    .nodeMap("sup4", s4)
267 262
    .nodeMap("sup5", s5)
268 263
    .node("source", v)
269 264
    .node("target", w)
270 265
    .run();
271 266

	
272 267
  // A. Test NetworkSimplex with the default pivot rule
273 268
  {
274 269
    NetworkSimplex<Digraph> mcf(gr);
275 270

	
276 271
    // Check the equality form
277 272
    mcf.upperMap(u).costMap(c);
278 273
    checkMcf(mcf, mcf.supplyMap(s1).run(),
279 274
             gr, l1, u, c, s1, true,  5240, "#A1");
280 275
    checkMcf(mcf, mcf.stSupply(v, w, 27).run(),
281 276
             gr, l1, u, c, s2, true,  7620, "#A2");
282 277
    mcf.lowerMap(l2);
283 278
    checkMcf(mcf, mcf.supplyMap(s1).run(),
284 279
             gr, l2, u, c, s1, true,  5970, "#A3");
285 280
    checkMcf(mcf, mcf.stSupply(v, w, 27).run(),
286 281
             gr, l2, u, c, s2, true,  8010, "#A4");
287 282
    mcf.reset();
288 283
    checkMcf(mcf, mcf.supplyMap(s1).run(),
289 284
             gr, l1, cu, cc, s1, true,  74, "#A5");
290 285
    checkMcf(mcf, mcf.lowerMap(l2).stSupply(v, w, 27).run(),
291 286
             gr, l2, cu, cc, s2, true,  94, "#A6");
292 287
    mcf.reset();
293 288
    checkMcf(mcf, mcf.run(),
294 289
             gr, l1, cu, cc, s3, true,   0, "#A7");
295 290
    checkMcf(mcf, mcf.boundMaps(l2, u).run(),
296 291
             gr, l2, u, cc, s3, false,   0, "#A8");
297 292

	
298 293
    // Check the GEQ form
299 294
    mcf.reset().upperMap(u).costMap(c).supplyMap(s4);
300 295
    checkMcf(mcf, mcf.run(),
301 296
             gr, l1, u, c, s4, true,  3530, "#A9", GEQ);
302 297
    mcf.problemType(mcf.GEQ);
303 298
    checkMcf(mcf, mcf.lowerMap(l2).run(),
304 299
             gr, l2, u, c, s4, true,  4540, "#A10", GEQ);
305 300
    mcf.problemType(mcf.CARRY_SUPPLIES).supplyMap(s5);
306 301
    checkMcf(mcf, mcf.run(),
307 302
             gr, l2, u, c, s5, false,    0, "#A11", GEQ);
308 303

	
309 304
    // Check the LEQ form
310 305
    mcf.reset().problemType(mcf.LEQ);
311 306
    mcf.upperMap(u).costMap(c).supplyMap(s5);
312 307
    checkMcf(mcf, mcf.run(),
313 308
             gr, l1, u, c, s5, true,  5080, "#A12", LEQ);
314 309
    checkMcf(mcf, mcf.lowerMap(l2).run(),
315 310
             gr, l2, u, c, s5, true,  5930, "#A13", LEQ);
316 311
    mcf.problemType(mcf.SATISFY_DEMANDS).supplyMap(s4);
317 312
    checkMcf(mcf, mcf.run(),
318 313
             gr, l2, u, c, s4, false,    0, "#A14", LEQ);
319 314
  }
320 315

	
321 316
  // B. Test NetworkSimplex with each pivot rule
322 317
  {
323 318
    NetworkSimplex<Digraph> mcf(gr);
324 319
    mcf.supplyMap(s1).costMap(c).capacityMap(u).lowerMap(l2);
325 320

	
326 321
    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::FIRST_ELIGIBLE),
327 322
             gr, l2, u, c, s1, true,  5970, "#B1");
328 323
    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::BEST_ELIGIBLE),
329 324
             gr, l2, u, c, s1, true,  5970, "#B2");
330 325
    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::BLOCK_SEARCH),
331 326
             gr, l2, u, c, s1, true,  5970, "#B3");
332 327
    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::CANDIDATE_LIST),
333 328
             gr, l2, u, c, s1, true,  5970, "#B4");
334 329
    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::ALTERING_LIST),
335 330
             gr, l2, u, c, s1, true,  5970, "#B5");
336 331
  }
337 332

	
338 333
  return 0;
339 334
}
Ignore white space 16384 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 tools
20 20
///\file
21 21
///\brief DIMACS problem solver.
22 22
///
23 23
/// This program solves various problems given in DIMACS format.
24 24
///
25 25
/// See
26 26
/// \code
27 27
///   dimacs-solver --help
28 28
/// \endcode
29 29
/// for more info on usage.
30 30

	
31 31
#include <iostream>
32 32
#include <fstream>
33 33
#include <cstring>
34 34

	
35 35
#include <lemon/smart_graph.h>
36 36
#include <lemon/dimacs.h>
37 37
#include <lemon/lgf_writer.h>
38 38
#include <lemon/time_measure.h>
39 39

	
40 40
#include <lemon/arg_parser.h>
41 41
#include <lemon/error.h>
42 42

	
43 43
#include <lemon/dijkstra.h>
44 44
#include <lemon/preflow.h>
45 45
#include <lemon/matching.h>
46 46
#include <lemon/network_simplex.h>
47 47

	
48 48
using namespace lemon;
49 49
typedef SmartDigraph Digraph;
50 50
DIGRAPH_TYPEDEFS(Digraph);
51 51
typedef SmartGraph Graph;
52 52

	
53 53
template<class Value>
54 54
void solve_sp(ArgParser &ap, std::istream &is, std::ostream &,
55 55
              DimacsDescriptor &desc)
56 56
{
57 57
  bool report = !ap.given("q");
58 58
  Digraph g;
59 59
  Node s;
60 60
  Digraph::ArcMap<Value> len(g);
61 61
  Timer t;
62 62
  t.restart();
63 63
  readDimacsSp(is, g, len, s, desc);
64 64
  if(report) std::cerr << "Read the file: " << t << '\n';
65 65
  t.restart();
66 66
  Dijkstra<Digraph, Digraph::ArcMap<Value> > dij(g,len);
67 67
  if(report) std::cerr << "Setup Dijkstra class: " << t << '\n';
68 68
  t.restart();
69 69
  dij.run(s);
70 70
  if(report) std::cerr << "Run Dijkstra: " << t << '\n';
71 71
}
72 72

	
73 73
template<class Value>
74 74
void solve_max(ArgParser &ap, std::istream &is, std::ostream &,
75 75
               Value infty, DimacsDescriptor &desc)
76 76
{
77 77
  bool report = !ap.given("q");
78 78
  Digraph g;
79 79
  Node s,t;
80 80
  Digraph::ArcMap<Value> cap(g);
81 81
  Timer ti;
82 82
  ti.restart();
83 83
  readDimacsMax(is, g, cap, s, t, infty, desc);
84 84
  if(report) std::cerr << "Read the file: " << ti << '\n';
85 85
  ti.restart();
86 86
  Preflow<Digraph, Digraph::ArcMap<Value> > pre(g,cap,s,t);
87 87
  if(report) std::cerr << "Setup Preflow class: " << ti << '\n';
88 88
  ti.restart();
89 89
  pre.run();
90 90
  if(report) std::cerr << "Run Preflow: " << ti << '\n';
91 91
  if(report) std::cerr << "\nMax flow value: " << pre.flowValue() << '\n';  
92 92
}
93 93

	
94 94
template<class Value>
95 95
void solve_min(ArgParser &ap, std::istream &is, std::ostream &,
96
               DimacsDescriptor &desc)
96
               Value infty, DimacsDescriptor &desc)
97 97
{
98 98
  bool report = !ap.given("q");
99 99
  Digraph g;
100 100
  Digraph::ArcMap<Value> lower(g), cap(g), cost(g);
101 101
  Digraph::NodeMap<Value> sup(g);
102 102
  Timer ti;
103

	
103 104
  ti.restart();
104
  readDimacsMin(is, g, lower, cap, cost, sup, 0, desc);
105
  readDimacsMin(is, g, lower, cap, cost, sup, infty, desc);
106
  ti.stop();
107
  Value sum_sup = 0;
108
  for (Digraph::NodeIt n(g); n != INVALID; ++n) {
109
    sum_sup += sup[n];
110
  }
111
  if (report) {
112
    std::cerr << "Sum of supply values: " << sum_sup << "\n";
113
    if (sum_sup <= 0)
114
      std::cerr << "GEQ supply contraints are used for NetworkSimplex\n\n";
115
    else
116
      std::cerr << "LEQ supply contraints are used for NetworkSimplex\n\n";
117
  }
105 118
  if (report) std::cerr << "Read the file: " << ti << '\n';
119

	
106 120
  ti.restart();
107 121
  NetworkSimplex<Digraph, Value> ns(g);
108 122
  ns.lowerMap(lower).capacityMap(cap).costMap(cost).supplyMap(sup);
123
  if (sum_sup > 0) ns.problemType(ns.LEQ);
109 124
  if (report) std::cerr << "Setup NetworkSimplex class: " << ti << '\n';
110 125
  ti.restart();
111
  ns.run();
112
  if (report) std::cerr << "Run NetworkSimplex: " << ti << '\n';
113
  if (report) std::cerr << "\nMin flow cost: " << ns.totalCost() << '\n';
126
  bool res = ns.run();
127
  if (report) {
128
    std::cerr << "Run NetworkSimplex: " << ti << "\n\n";
129
    std::cerr << "Feasible flow: " << (res ? "found" : "not found") << '\n';
130
    if (res) std::cerr << "Min flow cost: " << ns.totalCost() << '\n';
131
  }
114 132
}
115 133

	
116 134
void solve_mat(ArgParser &ap, std::istream &is, std::ostream &,
117 135
              DimacsDescriptor &desc)
118 136
{
119 137
  bool report = !ap.given("q");
120 138
  Graph g;
121 139
  Timer ti;
122 140
  ti.restart();
123 141
  readDimacsMat(is, g, desc);
124 142
  if(report) std::cerr << "Read the file: " << ti << '\n';
125 143
  ti.restart();
126 144
  MaxMatching<Graph> mat(g);
127 145
  if(report) std::cerr << "Setup MaxMatching class: " << ti << '\n';
128 146
  ti.restart();
129 147
  mat.run();
130 148
  if(report) std::cerr << "Run MaxMatching: " << ti << '\n';
131 149
  if(report) std::cerr << "\nCardinality of max matching: "
132 150
                       << mat.matchingSize() << '\n';  
133 151
}
134 152

	
135 153

	
136 154
template<class Value>
137 155
void solve(ArgParser &ap, std::istream &is, std::ostream &os,
138 156
           DimacsDescriptor &desc)
139 157
{
140 158
  std::stringstream iss(static_cast<std::string>(ap["infcap"]));
141 159
  Value infty;
142 160
  iss >> infty;
143 161
  if(iss.fail())
144 162
    {
145 163
      std::cerr << "Cannot interpret '"
146 164
                << static_cast<std::string>(ap["infcap"]) << "' as infinite"
147 165
                << std::endl;
148 166
      exit(1);
149 167
    }
150 168
  
151 169
  switch(desc.type)
152 170
    {
153 171
    case DimacsDescriptor::MIN:
154
      solve_min<Value>(ap,is,os,desc);
172
      solve_min<Value>(ap,is,os,infty,desc);
155 173
      break;
156 174
    case DimacsDescriptor::MAX:
157 175
      solve_max<Value>(ap,is,os,infty,desc);
158 176
      break;
159 177
    case DimacsDescriptor::SP:
160 178
      solve_sp<Value>(ap,is,os,desc);
161 179
      break;
162 180
    case DimacsDescriptor::MAT:
163 181
      solve_mat(ap,is,os,desc);
164 182
      break;
165 183
    default:
166 184
      break;
167 185
    }
168 186
}
169 187

	
170 188
int main(int argc, const char *argv[]) {
171 189
  typedef SmartDigraph Digraph;
172 190

	
173 191
  typedef Digraph::Arc Arc;
174 192

	
175 193
  std::string inputName;
176 194
  std::string outputName;
177 195

	
178 196
  ArgParser ap(argc, argv);
179 197
  ap.other("[INFILE [OUTFILE]]",
180 198
           "If either the INFILE or OUTFILE file is missing the standard\n"
181 199
           "     input/output will be used instead.")
182 200
    .boolOption("q", "Do not print any report")
183 201
    .boolOption("int","Use 'int' for capacities, costs etc. (default)")
184 202
    .optionGroup("datatype","int")
185 203
#ifdef HAVE_LONG_LONG
186 204
    .boolOption("long","Use 'long long' for capacities, costs etc.")
187 205
    .optionGroup("datatype","long")
188 206
#endif
189 207
    .boolOption("double","Use 'double' for capacities, costs etc.")
190 208
    .optionGroup("datatype","double")
191 209
    .boolOption("ldouble","Use 'long double' for capacities, costs etc.")
192 210
    .optionGroup("datatype","ldouble")
193 211
    .onlyOneGroup("datatype")
194 212
    .stringOption("infcap","Value used for 'very high' capacities","0")
195 213
    .run();
196 214

	
197 215
  std::ifstream input;
198 216
  std::ofstream output;
199 217

	
200 218
  switch(ap.files().size())
201 219
    {
202 220
    case 2:
203 221
      output.open(ap.files()[1].c_str());
204 222
      if (!output) {
205 223
        throw IoError("Cannot open the file for writing", ap.files()[1]);
206 224
      }
207 225
    case 1:
208 226
      input.open(ap.files()[0].c_str());
209 227
      if (!input) {
210 228
        throw IoError("File cannot be found", ap.files()[0]);
211 229
      }
212 230
    case 0:
213 231
      break;
214 232
    default:
215 233
      std::cerr << ap.commandName() << ": too many arguments\n";
216 234
      return 1;
217 235
    }
218 236
  std::istream& is = (ap.files().size()<1 ? std::cin : input);
219 237
  std::ostream& os = (ap.files().size()<2 ? std::cout : output);
220 238

	
221 239
  DimacsDescriptor desc = dimacsType(is);
222 240
  
223 241
  if(!ap.given("q"))
224 242
    {
225 243
      std::cout << "Problem type: ";
226 244
      switch(desc.type)
227 245
        {
228 246
        case DimacsDescriptor::MIN:
229 247
          std::cout << "min";
230 248
          break;
231 249
        case DimacsDescriptor::MAX:
232 250
          std::cout << "max";
233 251
          break;
234 252
        case DimacsDescriptor::SP:
235 253
          std::cout << "sp";
236 254
        case DimacsDescriptor::MAT:
237 255
          std::cout << "mat";
238 256
          break;
239 257
        default:
240 258
          exit(1);
241 259
          break;
242 260
        }
243 261
      std::cout << "\nNum of nodes: " << desc.nodeNum;
244 262
      std::cout << "\nNum of arcs:  " << desc.edgeNum;
245 263
      std::cout << "\n\n";
246 264
    }
247 265
    
248 266
  if(ap.given("double"))
249 267
    solve<double>(ap,is,os,desc);
250 268
  else if(ap.given("ldouble"))
251 269
    solve<long double>(ap,is,os,desc);
252 270
#ifdef HAVE_LONG_LONG
253 271
  else if(ap.given("long"))
254 272
    solve<long long>(ap,is,os,desc);
255 273
#endif
256 274
  else solve<int>(ap,is,os,desc);
257 275

	
258 276
  return 0;
259 277
}
0 comments (0 inline)