gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Improve arc mixing in NS and enable it by default (#391)
0 1 0
default
1 file changed with 7 insertions and 6 deletions:
↑ Collapse diff ↑
Ignore white space 768 line context
... ...
@@ -255,1069 +255,1070 @@
255 255
      const CostVector &_pi;
256 256
      int &_in_arc;
257 257
      int _search_arc_num;
258 258

	
259 259
      // Pivot rule data
260 260
      int _next_arc;
261 261

	
262 262
    public:
263 263

	
264 264
      // Constructor
265 265
      FirstEligiblePivotRule(NetworkSimplex &ns) :
266 266
        _source(ns._source), _target(ns._target),
267 267
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
268 268
        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
269 269
        _next_arc(0)
270 270
      {}
271 271

	
272 272
      // Find next entering arc
273 273
      bool findEnteringArc() {
274 274
        Cost c;
275 275
        for (int e = _next_arc; e != _search_arc_num; ++e) {
276 276
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
277 277
          if (c < 0) {
278 278
            _in_arc = e;
279 279
            _next_arc = e + 1;
280 280
            return true;
281 281
          }
282 282
        }
283 283
        for (int e = 0; e != _next_arc; ++e) {
284 284
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
285 285
          if (c < 0) {
286 286
            _in_arc = e;
287 287
            _next_arc = e + 1;
288 288
            return true;
289 289
          }
290 290
        }
291 291
        return false;
292 292
      }
293 293

	
294 294
    }; //class FirstEligiblePivotRule
295 295

	
296 296

	
297 297
    // Implementation of the Best Eligible pivot rule
298 298
    class BestEligiblePivotRule
299 299
    {
300 300
    private:
301 301

	
302 302
      // References to the NetworkSimplex class
303 303
      const IntVector  &_source;
304 304
      const IntVector  &_target;
305 305
      const CostVector &_cost;
306 306
      const CharVector &_state;
307 307
      const CostVector &_pi;
308 308
      int &_in_arc;
309 309
      int _search_arc_num;
310 310

	
311 311
    public:
312 312

	
313 313
      // Constructor
314 314
      BestEligiblePivotRule(NetworkSimplex &ns) :
315 315
        _source(ns._source), _target(ns._target),
316 316
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
317 317
        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num)
318 318
      {}
319 319

	
320 320
      // Find next entering arc
321 321
      bool findEnteringArc() {
322 322
        Cost c, min = 0;
323 323
        for (int e = 0; e != _search_arc_num; ++e) {
324 324
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
325 325
          if (c < min) {
326 326
            min = c;
327 327
            _in_arc = e;
328 328
          }
329 329
        }
330 330
        return min < 0;
331 331
      }
332 332

	
333 333
    }; //class BestEligiblePivotRule
334 334

	
335 335

	
336 336
    // Implementation of the Block Search pivot rule
337 337
    class BlockSearchPivotRule
338 338
    {
339 339
    private:
340 340

	
341 341
      // References to the NetworkSimplex class
342 342
      const IntVector  &_source;
343 343
      const IntVector  &_target;
344 344
      const CostVector &_cost;
345 345
      const CharVector &_state;
346 346
      const CostVector &_pi;
347 347
      int &_in_arc;
348 348
      int _search_arc_num;
349 349

	
350 350
      // Pivot rule data
351 351
      int _block_size;
352 352
      int _next_arc;
353 353

	
354 354
    public:
355 355

	
356 356
      // Constructor
357 357
      BlockSearchPivotRule(NetworkSimplex &ns) :
358 358
        _source(ns._source), _target(ns._target),
359 359
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
360 360
        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
361 361
        _next_arc(0)
362 362
      {
363 363
        // The main parameters of the pivot rule
364 364
        const double BLOCK_SIZE_FACTOR = 1.0;
365 365
        const int MIN_BLOCK_SIZE = 10;
366 366

	
367 367
        _block_size = std::max( int(BLOCK_SIZE_FACTOR *
368 368
                                    std::sqrt(double(_search_arc_num))),
369 369
                                MIN_BLOCK_SIZE );
370 370
      }
371 371

	
372 372
      // Find next entering arc
373 373
      bool findEnteringArc() {
374 374
        Cost c, min = 0;
375 375
        int cnt = _block_size;
376 376
        int e;
377 377
        for (e = _next_arc; e != _search_arc_num; ++e) {
378 378
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
379 379
          if (c < min) {
380 380
            min = c;
381 381
            _in_arc = e;
382 382
          }
383 383
          if (--cnt == 0) {
384 384
            if (min < 0) goto search_end;
385 385
            cnt = _block_size;
386 386
          }
387 387
        }
388 388
        for (e = 0; e != _next_arc; ++e) {
389 389
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
390 390
          if (c < min) {
391 391
            min = c;
392 392
            _in_arc = e;
393 393
          }
394 394
          if (--cnt == 0) {
395 395
            if (min < 0) goto search_end;
396 396
            cnt = _block_size;
397 397
          }
398 398
        }
399 399
        if (min >= 0) return false;
400 400

	
401 401
      search_end:
402 402
        _next_arc = e;
403 403
        return true;
404 404
      }
405 405

	
406 406
    }; //class BlockSearchPivotRule
407 407

	
408 408

	
409 409
    // Implementation of the Candidate List pivot rule
410 410
    class CandidateListPivotRule
411 411
    {
412 412
    private:
413 413

	
414 414
      // References to the NetworkSimplex class
415 415
      const IntVector  &_source;
416 416
      const IntVector  &_target;
417 417
      const CostVector &_cost;
418 418
      const CharVector &_state;
419 419
      const CostVector &_pi;
420 420
      int &_in_arc;
421 421
      int _search_arc_num;
422 422

	
423 423
      // Pivot rule data
424 424
      IntVector _candidates;
425 425
      int _list_length, _minor_limit;
426 426
      int _curr_length, _minor_count;
427 427
      int _next_arc;
428 428

	
429 429
    public:
430 430

	
431 431
      /// Constructor
432 432
      CandidateListPivotRule(NetworkSimplex &ns) :
433 433
        _source(ns._source), _target(ns._target),
434 434
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
435 435
        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
436 436
        _next_arc(0)
437 437
      {
438 438
        // The main parameters of the pivot rule
439 439
        const double LIST_LENGTH_FACTOR = 0.25;
440 440
        const int MIN_LIST_LENGTH = 10;
441 441
        const double MINOR_LIMIT_FACTOR = 0.1;
442 442
        const int MIN_MINOR_LIMIT = 3;
443 443

	
444 444
        _list_length = std::max( int(LIST_LENGTH_FACTOR *
445 445
                                     std::sqrt(double(_search_arc_num))),
446 446
                                 MIN_LIST_LENGTH );
447 447
        _minor_limit = std::max( int(MINOR_LIMIT_FACTOR * _list_length),
448 448
                                 MIN_MINOR_LIMIT );
449 449
        _curr_length = _minor_count = 0;
450 450
        _candidates.resize(_list_length);
451 451
      }
452 452

	
453 453
      /// Find next entering arc
454 454
      bool findEnteringArc() {
455 455
        Cost min, c;
456 456
        int e;
457 457
        if (_curr_length > 0 && _minor_count < _minor_limit) {
458 458
          // Minor iteration: select the best eligible arc from the
459 459
          // current candidate list
460 460
          ++_minor_count;
461 461
          min = 0;
462 462
          for (int i = 0; i < _curr_length; ++i) {
463 463
            e = _candidates[i];
464 464
            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
465 465
            if (c < min) {
466 466
              min = c;
467 467
              _in_arc = e;
468 468
            }
469 469
            else if (c >= 0) {
470 470
              _candidates[i--] = _candidates[--_curr_length];
471 471
            }
472 472
          }
473 473
          if (min < 0) return true;
474 474
        }
475 475

	
476 476
        // Major iteration: build a new candidate list
477 477
        min = 0;
478 478
        _curr_length = 0;
479 479
        for (e = _next_arc; e != _search_arc_num; ++e) {
480 480
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
481 481
          if (c < 0) {
482 482
            _candidates[_curr_length++] = e;
483 483
            if (c < min) {
484 484
              min = c;
485 485
              _in_arc = e;
486 486
            }
487 487
            if (_curr_length == _list_length) goto search_end;
488 488
          }
489 489
        }
490 490
        for (e = 0; e != _next_arc; ++e) {
491 491
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
492 492
          if (c < 0) {
493 493
            _candidates[_curr_length++] = e;
494 494
            if (c < min) {
495 495
              min = c;
496 496
              _in_arc = e;
497 497
            }
498 498
            if (_curr_length == _list_length) goto search_end;
499 499
          }
500 500
        }
501 501
        if (_curr_length == 0) return false;
502 502

	
503 503
      search_end:
504 504
        _minor_count = 1;
505 505
        _next_arc = e;
506 506
        return true;
507 507
      }
508 508

	
509 509
    }; //class CandidateListPivotRule
510 510

	
511 511

	
512 512
    // Implementation of the Altering Candidate List pivot rule
513 513
    class AlteringListPivotRule
514 514
    {
515 515
    private:
516 516

	
517 517
      // References to the NetworkSimplex class
518 518
      const IntVector  &_source;
519 519
      const IntVector  &_target;
520 520
      const CostVector &_cost;
521 521
      const CharVector &_state;
522 522
      const CostVector &_pi;
523 523
      int &_in_arc;
524 524
      int _search_arc_num;
525 525

	
526 526
      // Pivot rule data
527 527
      int _block_size, _head_length, _curr_length;
528 528
      int _next_arc;
529 529
      IntVector _candidates;
530 530
      CostVector _cand_cost;
531 531

	
532 532
      // Functor class to compare arcs during sort of the candidate list
533 533
      class SortFunc
534 534
      {
535 535
      private:
536 536
        const CostVector &_map;
537 537
      public:
538 538
        SortFunc(const CostVector &map) : _map(map) {}
539 539
        bool operator()(int left, int right) {
540 540
          return _map[left] > _map[right];
541 541
        }
542 542
      };
543 543

	
544 544
      SortFunc _sort_func;
545 545

	
546 546
    public:
547 547

	
548 548
      // Constructor
549 549
      AlteringListPivotRule(NetworkSimplex &ns) :
550 550
        _source(ns._source), _target(ns._target),
551 551
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
552 552
        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
553 553
        _next_arc(0), _cand_cost(ns._search_arc_num), _sort_func(_cand_cost)
554 554
      {
555 555
        // The main parameters of the pivot rule
556 556
        const double BLOCK_SIZE_FACTOR = 1.0;
557 557
        const int MIN_BLOCK_SIZE = 10;
558 558
        const double HEAD_LENGTH_FACTOR = 0.1;
559 559
        const int MIN_HEAD_LENGTH = 3;
560 560

	
561 561
        _block_size = std::max( int(BLOCK_SIZE_FACTOR *
562 562
                                    std::sqrt(double(_search_arc_num))),
563 563
                                MIN_BLOCK_SIZE );
564 564
        _head_length = std::max( int(HEAD_LENGTH_FACTOR * _block_size),
565 565
                                 MIN_HEAD_LENGTH );
566 566
        _candidates.resize(_head_length + _block_size);
567 567
        _curr_length = 0;
568 568
      }
569 569

	
570 570
      // Find next entering arc
571 571
      bool findEnteringArc() {
572 572
        // Check the current candidate list
573 573
        int e;
574 574
        Cost c;
575 575
        for (int i = 0; i != _curr_length; ++i) {
576 576
          e = _candidates[i];
577 577
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
578 578
          if (c < 0) {
579 579
            _cand_cost[e] = c;
580 580
          } else {
581 581
            _candidates[i--] = _candidates[--_curr_length];
582 582
          }
583 583
        }
584 584

	
585 585
        // Extend the list
586 586
        int cnt = _block_size;
587 587
        int limit = _head_length;
588 588

	
589 589
        for (e = _next_arc; e != _search_arc_num; ++e) {
590 590
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
591 591
          if (c < 0) {
592 592
            _cand_cost[e] = c;
593 593
            _candidates[_curr_length++] = e;
594 594
          }
595 595
          if (--cnt == 0) {
596 596
            if (_curr_length > limit) goto search_end;
597 597
            limit = 0;
598 598
            cnt = _block_size;
599 599
          }
600 600
        }
601 601
        for (e = 0; e != _next_arc; ++e) {
602 602
          _cand_cost[e] = _state[e] *
603 603
            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
604 604
          if (_cand_cost[e] < 0) {
605 605
            _candidates[_curr_length++] = e;
606 606
          }
607 607
          if (--cnt == 0) {
608 608
            if (_curr_length > limit) goto search_end;
609 609
            limit = 0;
610 610
            cnt = _block_size;
611 611
          }
612 612
        }
613 613
        if (_curr_length == 0) return false;
614 614

	
615 615
      search_end:
616 616

	
617 617
        // Make heap of the candidate list (approximating a partial sort)
618 618
        make_heap( _candidates.begin(), _candidates.begin() + _curr_length,
619 619
                   _sort_func );
620 620

	
621 621
        // Pop the first element of the heap
622 622
        _in_arc = _candidates[0];
623 623
        _next_arc = e;
624 624
        pop_heap( _candidates.begin(), _candidates.begin() + _curr_length,
625 625
                  _sort_func );
626 626
        _curr_length = std::min(_head_length, _curr_length - 1);
627 627
        return true;
628 628
      }
629 629

	
630 630
    }; //class AlteringListPivotRule
631 631

	
632 632
  public:
633 633

	
634 634
    /// \brief Constructor.
635 635
    ///
636 636
    /// The constructor of the class.
637 637
    ///
638 638
    /// \param graph The digraph the algorithm runs on.
639
    /// \param arc_mixing Indicate if the arcs have to be stored in a
639
    /// \param arc_mixing Indicate if the arcs will be stored in a
640 640
    /// mixed order in the internal data structure.
641
    /// In special cases, it could lead to better overall performance,
642
    /// but it is usually slower. Therefore it is disabled by default.
643
    NetworkSimplex(const GR& graph, bool arc_mixing = false) :
641
    /// In general, it leads to similar performance as using the original
642
    /// arc order, but it makes the algorithm more robust and in special
643
    /// cases, even significantly faster. Therefore, it is enabled by default.
644
    NetworkSimplex(const GR& graph, bool arc_mixing = true) :
644 645
      _graph(graph), _node_id(graph), _arc_id(graph),
645 646
      _arc_mixing(arc_mixing),
646 647
      MAX(std::numeric_limits<Value>::max()),
647 648
      INF(std::numeric_limits<Value>::has_infinity ?
648 649
          std::numeric_limits<Value>::infinity() : MAX)
649 650
    {
650 651
      // Check the number types
651 652
      LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
652 653
        "The flow type of NetworkSimplex must be signed");
653 654
      LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
654 655
        "The cost type of NetworkSimplex must be signed");
655 656

	
656 657
      // Reset data structures
657 658
      reset();
658 659
    }
659 660

	
660 661
    /// \name Parameters
661 662
    /// The parameters of the algorithm can be specified using these
662 663
    /// functions.
663 664

	
664 665
    /// @{
665 666

	
666 667
    /// \brief Set the lower bounds on the arcs.
667 668
    ///
668 669
    /// This function sets the lower bounds on the arcs.
669 670
    /// If it is not used before calling \ref run(), the lower bounds
670 671
    /// will be set to zero on all arcs.
671 672
    ///
672 673
    /// \param map An arc map storing the lower bounds.
673 674
    /// Its \c Value type must be convertible to the \c Value type
674 675
    /// of the algorithm.
675 676
    ///
676 677
    /// \return <tt>(*this)</tt>
677 678
    template <typename LowerMap>
678 679
    NetworkSimplex& lowerMap(const LowerMap& map) {
679 680
      _have_lower = true;
680 681
      for (ArcIt a(_graph); a != INVALID; ++a) {
681 682
        _lower[_arc_id[a]] = map[a];
682 683
      }
683 684
      return *this;
684 685
    }
685 686

	
686 687
    /// \brief Set the upper bounds (capacities) on the arcs.
687 688
    ///
688 689
    /// This function sets the upper bounds (capacities) on the arcs.
689 690
    /// If it is not used before calling \ref run(), the upper bounds
690 691
    /// will be set to \ref INF on all arcs (i.e. the flow value will be
691 692
    /// unbounded from above).
692 693
    ///
693 694
    /// \param map An arc map storing the upper bounds.
694 695
    /// Its \c Value type must be convertible to the \c Value type
695 696
    /// of the algorithm.
696 697
    ///
697 698
    /// \return <tt>(*this)</tt>
698 699
    template<typename UpperMap>
699 700
    NetworkSimplex& upperMap(const UpperMap& map) {
700 701
      for (ArcIt a(_graph); a != INVALID; ++a) {
701 702
        _upper[_arc_id[a]] = map[a];
702 703
      }
703 704
      return *this;
704 705
    }
705 706

	
706 707
    /// \brief Set the costs of the arcs.
707 708
    ///
708 709
    /// This function sets the costs of the arcs.
709 710
    /// If it is not used before calling \ref run(), the costs
710 711
    /// will be set to \c 1 on all arcs.
711 712
    ///
712 713
    /// \param map An arc map storing the costs.
713 714
    /// Its \c Value type must be convertible to the \c Cost type
714 715
    /// of the algorithm.
715 716
    ///
716 717
    /// \return <tt>(*this)</tt>
717 718
    template<typename CostMap>
718 719
    NetworkSimplex& costMap(const CostMap& map) {
719 720
      for (ArcIt a(_graph); a != INVALID; ++a) {
720 721
        _cost[_arc_id[a]] = map[a];
721 722
      }
722 723
      return *this;
723 724
    }
724 725

	
725 726
    /// \brief Set the supply values of the nodes.
726 727
    ///
727 728
    /// This function sets the supply values of the nodes.
728 729
    /// If neither this function nor \ref stSupply() is used before
729 730
    /// calling \ref run(), the supply of each node will be set to zero.
730 731
    ///
731 732
    /// \param map A node map storing the supply values.
732 733
    /// Its \c Value type must be convertible to the \c Value type
733 734
    /// of the algorithm.
734 735
    ///
735 736
    /// \return <tt>(*this)</tt>
736 737
    template<typename SupplyMap>
737 738
    NetworkSimplex& supplyMap(const SupplyMap& map) {
738 739
      for (NodeIt n(_graph); n != INVALID; ++n) {
739 740
        _supply[_node_id[n]] = map[n];
740 741
      }
741 742
      return *this;
742 743
    }
743 744

	
744 745
    /// \brief Set single source and target nodes and a supply value.
745 746
    ///
746 747
    /// This function sets a single source node and a single target node
747 748
    /// and the required flow value.
748 749
    /// If neither this function nor \ref supplyMap() is used before
749 750
    /// calling \ref run(), the supply of each node will be set to zero.
750 751
    ///
751 752
    /// Using this function has the same effect as using \ref supplyMap()
752 753
    /// with such a map in which \c k is assigned to \c s, \c -k is
753 754
    /// assigned to \c t and all other nodes have zero supply value.
754 755
    ///
755 756
    /// \param s The source node.
756 757
    /// \param t The target node.
757 758
    /// \param k The required amount of flow from node \c s to node \c t
758 759
    /// (i.e. the supply of \c s and the demand of \c t).
759 760
    ///
760 761
    /// \return <tt>(*this)</tt>
761 762
    NetworkSimplex& stSupply(const Node& s, const Node& t, Value k) {
762 763
      for (int i = 0; i != _node_num; ++i) {
763 764
        _supply[i] = 0;
764 765
      }
765 766
      _supply[_node_id[s]] =  k;
766 767
      _supply[_node_id[t]] = -k;
767 768
      return *this;
768 769
    }
769 770

	
770 771
    /// \brief Set the type of the supply constraints.
771 772
    ///
772 773
    /// This function sets the type of the supply/demand constraints.
773 774
    /// If it is not used before calling \ref run(), the \ref GEQ supply
774 775
    /// type will be used.
775 776
    ///
776 777
    /// For more information, see \ref SupplyType.
777 778
    ///
778 779
    /// \return <tt>(*this)</tt>
779 780
    NetworkSimplex& supplyType(SupplyType supply_type) {
780 781
      _stype = supply_type;
781 782
      return *this;
782 783
    }
783 784

	
784 785
    /// @}
785 786

	
786 787
    /// \name Execution Control
787 788
    /// The algorithm can be executed using \ref run().
788 789

	
789 790
    /// @{
790 791

	
791 792
    /// \brief Run the algorithm.
792 793
    ///
793 794
    /// This function runs the algorithm.
794 795
    /// The paramters can be specified using functions \ref lowerMap(),
795 796
    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(),
796 797
    /// \ref supplyType().
797 798
    /// For example,
798 799
    /// \code
799 800
    ///   NetworkSimplex<ListDigraph> ns(graph);
800 801
    ///   ns.lowerMap(lower).upperMap(upper).costMap(cost)
801 802
    ///     .supplyMap(sup).run();
802 803
    /// \endcode
803 804
    ///
804 805
    /// This function can be called more than once. All the given parameters
805 806
    /// are kept for the next call, unless \ref resetParams() or \ref reset()
806 807
    /// is used, thus only the modified parameters have to be set again.
807 808
    /// If the underlying digraph was also modified after the construction
808 809
    /// of the class (or the last \ref reset() call), then the \ref reset()
809 810
    /// function must be called.
810 811
    ///
811 812
    /// \param pivot_rule The pivot rule that will be used during the
812 813
    /// algorithm. For more information, see \ref PivotRule.
813 814
    ///
814 815
    /// \return \c INFEASIBLE if no feasible flow exists,
815 816
    /// \n \c OPTIMAL if the problem has optimal solution
816 817
    /// (i.e. it is feasible and bounded), and the algorithm has found
817 818
    /// optimal flow and node potentials (primal and dual solutions),
818 819
    /// \n \c UNBOUNDED if the objective function of the problem is
819 820
    /// unbounded, i.e. there is a directed cycle having negative total
820 821
    /// cost and infinite upper bound.
821 822
    ///
822 823
    /// \see ProblemType, PivotRule
823 824
    /// \see resetParams(), reset()
824 825
    ProblemType run(PivotRule pivot_rule = BLOCK_SEARCH) {
825 826
      if (!init()) return INFEASIBLE;
826 827
      return start(pivot_rule);
827 828
    }
828 829

	
829 830
    /// \brief Reset all the parameters that have been given before.
830 831
    ///
831 832
    /// This function resets all the paramaters that have been given
832 833
    /// before using functions \ref lowerMap(), \ref upperMap(),
833 834
    /// \ref costMap(), \ref supplyMap(), \ref stSupply(), \ref supplyType().
834 835
    ///
835 836
    /// It is useful for multiple \ref run() calls. Basically, all the given
836 837
    /// parameters are kept for the next \ref run() call, unless
837 838
    /// \ref resetParams() or \ref reset() is used.
838 839
    /// If the underlying digraph was also modified after the construction
839 840
    /// of the class or the last \ref reset() call, then the \ref reset()
840 841
    /// function must be used, otherwise \ref resetParams() is sufficient.
841 842
    ///
842 843
    /// For example,
843 844
    /// \code
844 845
    ///   NetworkSimplex<ListDigraph> ns(graph);
845 846
    ///
846 847
    ///   // First run
847 848
    ///   ns.lowerMap(lower).upperMap(upper).costMap(cost)
848 849
    ///     .supplyMap(sup).run();
849 850
    ///
850 851
    ///   // Run again with modified cost map (resetParams() is not called,
851 852
    ///   // so only the cost map have to be set again)
852 853
    ///   cost[e] += 100;
853 854
    ///   ns.costMap(cost).run();
854 855
    ///
855 856
    ///   // Run again from scratch using resetParams()
856 857
    ///   // (the lower bounds will be set to zero on all arcs)
857 858
    ///   ns.resetParams();
858 859
    ///   ns.upperMap(capacity).costMap(cost)
859 860
    ///     .supplyMap(sup).run();
860 861
    /// \endcode
861 862
    ///
862 863
    /// \return <tt>(*this)</tt>
863 864
    ///
864 865
    /// \see reset(), run()
865 866
    NetworkSimplex& resetParams() {
866 867
      for (int i = 0; i != _node_num; ++i) {
867 868
        _supply[i] = 0;
868 869
      }
869 870
      for (int i = 0; i != _arc_num; ++i) {
870 871
        _lower[i] = 0;
871 872
        _upper[i] = INF;
872 873
        _cost[i] = 1;
873 874
      }
874 875
      _have_lower = false;
875 876
      _stype = GEQ;
876 877
      return *this;
877 878
    }
878 879

	
879 880
    /// \brief Reset the internal data structures and all the parameters
880 881
    /// that have been given before.
881 882
    ///
882 883
    /// This function resets the internal data structures and all the
883 884
    /// paramaters that have been given before using functions \ref lowerMap(),
884 885
    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(),
885 886
    /// \ref supplyType().
886 887
    ///
887 888
    /// It is useful for multiple \ref run() calls. Basically, all the given
888 889
    /// parameters are kept for the next \ref run() call, unless
889 890
    /// \ref resetParams() or \ref reset() is used.
890 891
    /// If the underlying digraph was also modified after the construction
891 892
    /// of the class or the last \ref reset() call, then the \ref reset()
892 893
    /// function must be used, otherwise \ref resetParams() is sufficient.
893 894
    ///
894 895
    /// See \ref resetParams() for examples.
895 896
    ///
896 897
    /// \return <tt>(*this)</tt>
897 898
    ///
898 899
    /// \see resetParams(), run()
899 900
    NetworkSimplex& reset() {
900 901
      // Resize vectors
901 902
      _node_num = countNodes(_graph);
902 903
      _arc_num = countArcs(_graph);
903 904
      int all_node_num = _node_num + 1;
904 905
      int max_arc_num = _arc_num + 2 * _node_num;
905 906

	
906 907
      _source.resize(max_arc_num);
907 908
      _target.resize(max_arc_num);
908 909

	
909 910
      _lower.resize(_arc_num);
910 911
      _upper.resize(_arc_num);
911 912
      _cap.resize(max_arc_num);
912 913
      _cost.resize(max_arc_num);
913 914
      _supply.resize(all_node_num);
914 915
      _flow.resize(max_arc_num);
915 916
      _pi.resize(all_node_num);
916 917

	
917 918
      _parent.resize(all_node_num);
918 919
      _pred.resize(all_node_num);
919 920
      _pred_dir.resize(all_node_num);
920 921
      _thread.resize(all_node_num);
921 922
      _rev_thread.resize(all_node_num);
922 923
      _succ_num.resize(all_node_num);
923 924
      _last_succ.resize(all_node_num);
924 925
      _state.resize(max_arc_num);
925 926

	
926 927
      // Copy the graph
927 928
      int i = 0;
928 929
      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
929 930
        _node_id[n] = i;
930 931
      }
931 932
      if (_arc_mixing) {
932 933
        // Store the arcs in a mixed order
933
        int k = std::max(int(std::sqrt(double(_arc_num))), 10);
934
        const int skip = std::max(_arc_num / _node_num, 3);
934 935
        int i = 0, j = 0;
935 936
        for (ArcIt a(_graph); a != INVALID; ++a) {
936 937
          _arc_id[a] = i;
937 938
          _source[i] = _node_id[_graph.source(a)];
938 939
          _target[i] = _node_id[_graph.target(a)];
939
          if ((i += k) >= _arc_num) i = ++j;
940
          if ((i += skip) >= _arc_num) i = ++j;
940 941
        }
941 942
      } else {
942 943
        // Store the arcs in the original order
943 944
        int i = 0;
944 945
        for (ArcIt a(_graph); a != INVALID; ++a, ++i) {
945 946
          _arc_id[a] = i;
946 947
          _source[i] = _node_id[_graph.source(a)];
947 948
          _target[i] = _node_id[_graph.target(a)];
948 949
        }
949 950
      }
950 951

	
951 952
      // Reset parameters
952 953
      resetParams();
953 954
      return *this;
954 955
    }
955 956

	
956 957
    /// @}
957 958

	
958 959
    /// \name Query Functions
959 960
    /// The results of the algorithm can be obtained using these
960 961
    /// functions.\n
961 962
    /// The \ref run() function must be called before using them.
962 963

	
963 964
    /// @{
964 965

	
965 966
    /// \brief Return the total cost of the found flow.
966 967
    ///
967 968
    /// This function returns the total cost of the found flow.
968 969
    /// Its complexity is O(e).
969 970
    ///
970 971
    /// \note The return type of the function can be specified as a
971 972
    /// template parameter. For example,
972 973
    /// \code
973 974
    ///   ns.totalCost<double>();
974 975
    /// \endcode
975 976
    /// It is useful if the total cost cannot be stored in the \c Cost
976 977
    /// type of the algorithm, which is the default return type of the
977 978
    /// function.
978 979
    ///
979 980
    /// \pre \ref run() must be called before using this function.
980 981
    template <typename Number>
981 982
    Number totalCost() const {
982 983
      Number c = 0;
983 984
      for (ArcIt a(_graph); a != INVALID; ++a) {
984 985
        int i = _arc_id[a];
985 986
        c += Number(_flow[i]) * Number(_cost[i]);
986 987
      }
987 988
      return c;
988 989
    }
989 990

	
990 991
#ifndef DOXYGEN
991 992
    Cost totalCost() const {
992 993
      return totalCost<Cost>();
993 994
    }
994 995
#endif
995 996

	
996 997
    /// \brief Return the flow on the given arc.
997 998
    ///
998 999
    /// This function returns the flow on the given arc.
999 1000
    ///
1000 1001
    /// \pre \ref run() must be called before using this function.
1001 1002
    Value flow(const Arc& a) const {
1002 1003
      return _flow[_arc_id[a]];
1003 1004
    }
1004 1005

	
1005 1006
    /// \brief Return the flow map (the primal solution).
1006 1007
    ///
1007 1008
    /// This function copies the flow value on each arc into the given
1008 1009
    /// map. The \c Value type of the algorithm must be convertible to
1009 1010
    /// the \c Value type of the map.
1010 1011
    ///
1011 1012
    /// \pre \ref run() must be called before using this function.
1012 1013
    template <typename FlowMap>
1013 1014
    void flowMap(FlowMap &map) const {
1014 1015
      for (ArcIt a(_graph); a != INVALID; ++a) {
1015 1016
        map.set(a, _flow[_arc_id[a]]);
1016 1017
      }
1017 1018
    }
1018 1019

	
1019 1020
    /// \brief Return the potential (dual value) of the given node.
1020 1021
    ///
1021 1022
    /// This function returns the potential (dual value) of the
1022 1023
    /// given node.
1023 1024
    ///
1024 1025
    /// \pre \ref run() must be called before using this function.
1025 1026
    Cost potential(const Node& n) const {
1026 1027
      return _pi[_node_id[n]];
1027 1028
    }
1028 1029

	
1029 1030
    /// \brief Return the potential map (the dual solution).
1030 1031
    ///
1031 1032
    /// This function copies the potential (dual value) of each node
1032 1033
    /// into the given map.
1033 1034
    /// The \c Cost type of the algorithm must be convertible to the
1034 1035
    /// \c Value type of the map.
1035 1036
    ///
1036 1037
    /// \pre \ref run() must be called before using this function.
1037 1038
    template <typename PotentialMap>
1038 1039
    void potentialMap(PotentialMap &map) const {
1039 1040
      for (NodeIt n(_graph); n != INVALID; ++n) {
1040 1041
        map.set(n, _pi[_node_id[n]]);
1041 1042
      }
1042 1043
    }
1043 1044

	
1044 1045
    /// @}
1045 1046

	
1046 1047
  private:
1047 1048

	
1048 1049
    // Initialize internal data structures
1049 1050
    bool init() {
1050 1051
      if (_node_num == 0) return false;
1051 1052

	
1052 1053
      // Check the sum of supply values
1053 1054
      _sum_supply = 0;
1054 1055
      for (int i = 0; i != _node_num; ++i) {
1055 1056
        _sum_supply += _supply[i];
1056 1057
      }
1057 1058
      if ( !((_stype == GEQ && _sum_supply <= 0) ||
1058 1059
             (_stype == LEQ && _sum_supply >= 0)) ) return false;
1059 1060

	
1060 1061
      // Remove non-zero lower bounds
1061 1062
      if (_have_lower) {
1062 1063
        for (int i = 0; i != _arc_num; ++i) {
1063 1064
          Value c = _lower[i];
1064 1065
          if (c >= 0) {
1065 1066
            _cap[i] = _upper[i] < MAX ? _upper[i] - c : INF;
1066 1067
          } else {
1067 1068
            _cap[i] = _upper[i] < MAX + c ? _upper[i] - c : INF;
1068 1069
          }
1069 1070
          _supply[_source[i]] -= c;
1070 1071
          _supply[_target[i]] += c;
1071 1072
        }
1072 1073
      } else {
1073 1074
        for (int i = 0; i != _arc_num; ++i) {
1074 1075
          _cap[i] = _upper[i];
1075 1076
        }
1076 1077
      }
1077 1078

	
1078 1079
      // Initialize artifical cost
1079 1080
      Cost ART_COST;
1080 1081
      if (std::numeric_limits<Cost>::is_exact) {
1081 1082
        ART_COST = std::numeric_limits<Cost>::max() / 2 + 1;
1082 1083
      } else {
1083 1084
        ART_COST = 0;
1084 1085
        for (int i = 0; i != _arc_num; ++i) {
1085 1086
          if (_cost[i] > ART_COST) ART_COST = _cost[i];
1086 1087
        }
1087 1088
        ART_COST = (ART_COST + 1) * _node_num;
1088 1089
      }
1089 1090

	
1090 1091
      // Initialize arc maps
1091 1092
      for (int i = 0; i != _arc_num; ++i) {
1092 1093
        _flow[i] = 0;
1093 1094
        _state[i] = STATE_LOWER;
1094 1095
      }
1095 1096

	
1096 1097
      // Set data for the artificial root node
1097 1098
      _root = _node_num;
1098 1099
      _parent[_root] = -1;
1099 1100
      _pred[_root] = -1;
1100 1101
      _thread[_root] = 0;
1101 1102
      _rev_thread[0] = _root;
1102 1103
      _succ_num[_root] = _node_num + 1;
1103 1104
      _last_succ[_root] = _root - 1;
1104 1105
      _supply[_root] = -_sum_supply;
1105 1106
      _pi[_root] = 0;
1106 1107

	
1107 1108
      // Add artificial arcs and initialize the spanning tree data structure
1108 1109
      if (_sum_supply == 0) {
1109 1110
        // EQ supply constraints
1110 1111
        _search_arc_num = _arc_num;
1111 1112
        _all_arc_num = _arc_num + _node_num;
1112 1113
        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
1113 1114
          _parent[u] = _root;
1114 1115
          _pred[u] = e;
1115 1116
          _thread[u] = u + 1;
1116 1117
          _rev_thread[u + 1] = u;
1117 1118
          _succ_num[u] = 1;
1118 1119
          _last_succ[u] = u;
1119 1120
          _cap[e] = INF;
1120 1121
          _state[e] = STATE_TREE;
1121 1122
          if (_supply[u] >= 0) {
1122 1123
            _pred_dir[u] = DIR_UP;
1123 1124
            _pi[u] = 0;
1124 1125
            _source[e] = u;
1125 1126
            _target[e] = _root;
1126 1127
            _flow[e] = _supply[u];
1127 1128
            _cost[e] = 0;
1128 1129
          } else {
1129 1130
            _pred_dir[u] = DIR_DOWN;
1130 1131
            _pi[u] = ART_COST;
1131 1132
            _source[e] = _root;
1132 1133
            _target[e] = u;
1133 1134
            _flow[e] = -_supply[u];
1134 1135
            _cost[e] = ART_COST;
1135 1136
          }
1136 1137
        }
1137 1138
      }
1138 1139
      else if (_sum_supply > 0) {
1139 1140
        // LEQ supply constraints
1140 1141
        _search_arc_num = _arc_num + _node_num;
1141 1142
        int f = _arc_num + _node_num;
1142 1143
        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
1143 1144
          _parent[u] = _root;
1144 1145
          _thread[u] = u + 1;
1145 1146
          _rev_thread[u + 1] = u;
1146 1147
          _succ_num[u] = 1;
1147 1148
          _last_succ[u] = u;
1148 1149
          if (_supply[u] >= 0) {
1149 1150
            _pred_dir[u] = DIR_UP;
1150 1151
            _pi[u] = 0;
1151 1152
            _pred[u] = e;
1152 1153
            _source[e] = u;
1153 1154
            _target[e] = _root;
1154 1155
            _cap[e] = INF;
1155 1156
            _flow[e] = _supply[u];
1156 1157
            _cost[e] = 0;
1157 1158
            _state[e] = STATE_TREE;
1158 1159
          } else {
1159 1160
            _pred_dir[u] = DIR_DOWN;
1160 1161
            _pi[u] = ART_COST;
1161 1162
            _pred[u] = f;
1162 1163
            _source[f] = _root;
1163 1164
            _target[f] = u;
1164 1165
            _cap[f] = INF;
1165 1166
            _flow[f] = -_supply[u];
1166 1167
            _cost[f] = ART_COST;
1167 1168
            _state[f] = STATE_TREE;
1168 1169
            _source[e] = u;
1169 1170
            _target[e] = _root;
1170 1171
            _cap[e] = INF;
1171 1172
            _flow[e] = 0;
1172 1173
            _cost[e] = 0;
1173 1174
            _state[e] = STATE_LOWER;
1174 1175
            ++f;
1175 1176
          }
1176 1177
        }
1177 1178
        _all_arc_num = f;
1178 1179
      }
1179 1180
      else {
1180 1181
        // GEQ supply constraints
1181 1182
        _search_arc_num = _arc_num + _node_num;
1182 1183
        int f = _arc_num + _node_num;
1183 1184
        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
1184 1185
          _parent[u] = _root;
1185 1186
          _thread[u] = u + 1;
1186 1187
          _rev_thread[u + 1] = u;
1187 1188
          _succ_num[u] = 1;
1188 1189
          _last_succ[u] = u;
1189 1190
          if (_supply[u] <= 0) {
1190 1191
            _pred_dir[u] = DIR_DOWN;
1191 1192
            _pi[u] = 0;
1192 1193
            _pred[u] = e;
1193 1194
            _source[e] = _root;
1194 1195
            _target[e] = u;
1195 1196
            _cap[e] = INF;
1196 1197
            _flow[e] = -_supply[u];
1197 1198
            _cost[e] = 0;
1198 1199
            _state[e] = STATE_TREE;
1199 1200
          } else {
1200 1201
            _pred_dir[u] = DIR_UP;
1201 1202
            _pi[u] = -ART_COST;
1202 1203
            _pred[u] = f;
1203 1204
            _source[f] = u;
1204 1205
            _target[f] = _root;
1205 1206
            _cap[f] = INF;
1206 1207
            _flow[f] = _supply[u];
1207 1208
            _state[f] = STATE_TREE;
1208 1209
            _cost[f] = ART_COST;
1209 1210
            _source[e] = _root;
1210 1211
            _target[e] = u;
1211 1212
            _cap[e] = INF;
1212 1213
            _flow[e] = 0;
1213 1214
            _cost[e] = 0;
1214 1215
            _state[e] = STATE_LOWER;
1215 1216
            ++f;
1216 1217
          }
1217 1218
        }
1218 1219
        _all_arc_num = f;
1219 1220
      }
1220 1221

	
1221 1222
      return true;
1222 1223
    }
1223 1224

	
1224 1225
    // Find the join node
1225 1226
    void findJoinNode() {
1226 1227
      int u = _source[in_arc];
1227 1228
      int v = _target[in_arc];
1228 1229
      while (u != v) {
1229 1230
        if (_succ_num[u] < _succ_num[v]) {
1230 1231
          u = _parent[u];
1231 1232
        } else {
1232 1233
          v = _parent[v];
1233 1234
        }
1234 1235
      }
1235 1236
      join = u;
1236 1237
    }
1237 1238

	
1238 1239
    // Find the leaving arc of the cycle and returns true if the
1239 1240
    // leaving arc is not the same as the entering arc
1240 1241
    bool findLeavingArc() {
1241 1242
      // Initialize first and second nodes according to the direction
1242 1243
      // of the cycle
1243 1244
      int first, second;
1244 1245
      if (_state[in_arc] == STATE_LOWER) {
1245 1246
        first  = _source[in_arc];
1246 1247
        second = _target[in_arc];
1247 1248
      } else {
1248 1249
        first  = _target[in_arc];
1249 1250
        second = _source[in_arc];
1250 1251
      }
1251 1252
      delta = _cap[in_arc];
1252 1253
      int result = 0;
1253 1254
      Value c, d;
1254 1255
      int e;
1255 1256

	
1256 1257
      // Search the cycle form the first node to the join node
1257 1258
      for (int u = first; u != join; u = _parent[u]) {
1258 1259
        e = _pred[u];
1259 1260
        d = _flow[e];
1260 1261
        if (_pred_dir[u] == DIR_DOWN) {
1261 1262
          c = _cap[e];
1262 1263
          d = c >= MAX ? INF : c - d;
1263 1264
        }
1264 1265
        if (d < delta) {
1265 1266
          delta = d;
1266 1267
          u_out = u;
1267 1268
          result = 1;
1268 1269
        }
1269 1270
      }
1270 1271

	
1271 1272
      // Search the cycle form the second node to the join node
1272 1273
      for (int u = second; u != join; u = _parent[u]) {
1273 1274
        e = _pred[u];
1274 1275
        d = _flow[e];
1275 1276
        if (_pred_dir[u] == DIR_UP) {
1276 1277
          c = _cap[e];
1277 1278
          d = c >= MAX ? INF : c - d;
1278 1279
        }
1279 1280
        if (d <= delta) {
1280 1281
          delta = d;
1281 1282
          u_out = u;
1282 1283
          result = 2;
1283 1284
        }
1284 1285
      }
1285 1286

	
1286 1287
      if (result == 1) {
1287 1288
        u_in = first;
1288 1289
        v_in = second;
1289 1290
      } else {
1290 1291
        u_in = second;
1291 1292
        v_in = first;
1292 1293
      }
1293 1294
      return result != 0;
1294 1295
    }
1295 1296

	
1296 1297
    // Change _flow and _state vectors
1297 1298
    void changeFlow(bool change) {
1298 1299
      // Augment along the cycle
1299 1300
      if (delta > 0) {
1300 1301
        Value val = _state[in_arc] * delta;
1301 1302
        _flow[in_arc] += val;
1302 1303
        for (int u = _source[in_arc]; u != join; u = _parent[u]) {
1303 1304
          _flow[_pred[u]] -= _pred_dir[u] * val;
1304 1305
        }
1305 1306
        for (int u = _target[in_arc]; u != join; u = _parent[u]) {
1306 1307
          _flow[_pred[u]] += _pred_dir[u] * val;
1307 1308
        }
1308 1309
      }
1309 1310
      // Update the state of the entering and leaving arcs
1310 1311
      if (change) {
1311 1312
        _state[in_arc] = STATE_TREE;
1312 1313
        _state[_pred[u_out]] =
1313 1314
          (_flow[_pred[u_out]] == 0) ? STATE_LOWER : STATE_UPPER;
1314 1315
      } else {
1315 1316
        _state[in_arc] = -_state[in_arc];
1316 1317
      }
1317 1318
    }
1318 1319

	
1319 1320
    // Update the tree structure
1320 1321
    void updateTreeStructure() {
1321 1322
      int old_rev_thread = _rev_thread[u_out];
1322 1323
      int old_succ_num = _succ_num[u_out];
1323 1324
      int old_last_succ = _last_succ[u_out];
0 comments (0 inline)