gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Minor improvements in CostScaling (#417)
0 1 0
default
1 file changed with 49 insertions and 37 deletions:
↑ Collapse diff ↑
Ignore white space 384 line context
... ...
@@ -386,871 +386,883 @@
386 386

	
387 387
    /// \brief Set the upper bounds (capacities) on the arcs.
388 388
    ///
389 389
    /// This function sets the upper bounds (capacities) on the arcs.
390 390
    /// If it is not used before calling \ref run(), the upper bounds
391 391
    /// will be set to \ref INF on all arcs (i.e. the flow value will be
392 392
    /// unbounded from above).
393 393
    ///
394 394
    /// \param map An arc map storing the upper bounds.
395 395
    /// Its \c Value type must be convertible to the \c Value type
396 396
    /// of the algorithm.
397 397
    ///
398 398
    /// \return <tt>(*this)</tt>
399 399
    template<typename UpperMap>
400 400
    CostScaling& upperMap(const UpperMap& map) {
401 401
      for (ArcIt a(_graph); a != INVALID; ++a) {
402 402
        _upper[_arc_idf[a]] = map[a];
403 403
      }
404 404
      return *this;
405 405
    }
406 406

	
407 407
    /// \brief Set the costs of the arcs.
408 408
    ///
409 409
    /// This function sets the costs of the arcs.
410 410
    /// If it is not used before calling \ref run(), the costs
411 411
    /// will be set to \c 1 on all arcs.
412 412
    ///
413 413
    /// \param map An arc map storing the costs.
414 414
    /// Its \c Value type must be convertible to the \c Cost type
415 415
    /// of the algorithm.
416 416
    ///
417 417
    /// \return <tt>(*this)</tt>
418 418
    template<typename CostMap>
419 419
    CostScaling& costMap(const CostMap& map) {
420 420
      for (ArcIt a(_graph); a != INVALID; ++a) {
421 421
        _scost[_arc_idf[a]] =  map[a];
422 422
        _scost[_arc_idb[a]] = -map[a];
423 423
      }
424 424
      return *this;
425 425
    }
426 426

	
427 427
    /// \brief Set the supply values of the nodes.
428 428
    ///
429 429
    /// This function sets the supply values of the nodes.
430 430
    /// If neither this function nor \ref stSupply() is used before
431 431
    /// calling \ref run(), the supply of each node will be set to zero.
432 432
    ///
433 433
    /// \param map A node map storing the supply values.
434 434
    /// Its \c Value type must be convertible to the \c Value type
435 435
    /// of the algorithm.
436 436
    ///
437 437
    /// \return <tt>(*this)</tt>
438 438
    template<typename SupplyMap>
439 439
    CostScaling& supplyMap(const SupplyMap& map) {
440 440
      for (NodeIt n(_graph); n != INVALID; ++n) {
441 441
        _supply[_node_id[n]] = map[n];
442 442
      }
443 443
      return *this;
444 444
    }
445 445

	
446 446
    /// \brief Set single source and target nodes and a supply value.
447 447
    ///
448 448
    /// This function sets a single source node and a single target node
449 449
    /// and the required flow value.
450 450
    /// If neither this function nor \ref supplyMap() is used before
451 451
    /// calling \ref run(), the supply of each node will be set to zero.
452 452
    ///
453 453
    /// Using this function has the same effect as using \ref supplyMap()
454 454
    /// with a map in which \c k is assigned to \c s, \c -k is
455 455
    /// assigned to \c t and all other nodes have zero supply value.
456 456
    ///
457 457
    /// \param s The source node.
458 458
    /// \param t The target node.
459 459
    /// \param k The required amount of flow from node \c s to node \c t
460 460
    /// (i.e. the supply of \c s and the demand of \c t).
461 461
    ///
462 462
    /// \return <tt>(*this)</tt>
463 463
    CostScaling& stSupply(const Node& s, const Node& t, Value k) {
464 464
      for (int i = 0; i != _res_node_num; ++i) {
465 465
        _supply[i] = 0;
466 466
      }
467 467
      _supply[_node_id[s]] =  k;
468 468
      _supply[_node_id[t]] = -k;
469 469
      return *this;
470 470
    }
471 471

	
472 472
    /// @}
473 473

	
474 474
    /// \name Execution control
475 475
    /// The algorithm can be executed using \ref run().
476 476

	
477 477
    /// @{
478 478

	
479 479
    /// \brief Run the algorithm.
480 480
    ///
481 481
    /// This function runs the algorithm.
482 482
    /// The paramters can be specified using functions \ref lowerMap(),
483 483
    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply().
484 484
    /// For example,
485 485
    /// \code
486 486
    ///   CostScaling<ListDigraph> cs(graph);
487 487
    ///   cs.lowerMap(lower).upperMap(upper).costMap(cost)
488 488
    ///     .supplyMap(sup).run();
489 489
    /// \endcode
490 490
    ///
491 491
    /// This function can be called more than once. All the given parameters
492 492
    /// are kept for the next call, unless \ref resetParams() or \ref reset()
493 493
    /// is used, thus only the modified parameters have to be set again.
494 494
    /// If the underlying digraph was also modified after the construction
495 495
    /// of the class (or the last \ref reset() call), then the \ref reset()
496 496
    /// function must be called.
497 497
    ///
498 498
    /// \param method The internal method that will be used in the
499 499
    /// algorithm. For more information, see \ref Method.
500 500
    /// \param factor The cost scaling factor. It must be larger than one.
501 501
    ///
502 502
    /// \return \c INFEASIBLE if no feasible flow exists,
503 503
    /// \n \c OPTIMAL if the problem has optimal solution
504 504
    /// (i.e. it is feasible and bounded), and the algorithm has found
505 505
    /// optimal flow and node potentials (primal and dual solutions),
506 506
    /// \n \c UNBOUNDED if the digraph contains an arc of negative cost
507 507
    /// and infinite upper bound. It means that the objective function
508 508
    /// is unbounded on that arc, however, note that it could actually be
509 509
    /// bounded over the feasible flows, but this algroithm cannot handle
510 510
    /// these cases.
511 511
    ///
512 512
    /// \see ProblemType, Method
513 513
    /// \see resetParams(), reset()
514 514
    ProblemType run(Method method = PARTIAL_AUGMENT, int factor = 8) {
515 515
      _alpha = factor;
516 516
      ProblemType pt = init();
517 517
      if (pt != OPTIMAL) return pt;
518 518
      start(method);
519 519
      return OPTIMAL;
520 520
    }
521 521

	
522 522
    /// \brief Reset all the parameters that have been given before.
523 523
    ///
524 524
    /// This function resets all the paramaters that have been given
525 525
    /// before using functions \ref lowerMap(), \ref upperMap(),
526 526
    /// \ref costMap(), \ref supplyMap(), \ref stSupply().
527 527
    ///
528 528
    /// It is useful for multiple \ref run() calls. Basically, all the given
529 529
    /// parameters are kept for the next \ref run() call, unless
530 530
    /// \ref resetParams() or \ref reset() is used.
531 531
    /// If the underlying digraph was also modified after the construction
532 532
    /// of the class or the last \ref reset() call, then the \ref reset()
533 533
    /// function must be used, otherwise \ref resetParams() is sufficient.
534 534
    ///
535 535
    /// For example,
536 536
    /// \code
537 537
    ///   CostScaling<ListDigraph> cs(graph);
538 538
    ///
539 539
    ///   // First run
540 540
    ///   cs.lowerMap(lower).upperMap(upper).costMap(cost)
541 541
    ///     .supplyMap(sup).run();
542 542
    ///
543 543
    ///   // Run again with modified cost map (resetParams() is not called,
544 544
    ///   // so only the cost map have to be set again)
545 545
    ///   cost[e] += 100;
546 546
    ///   cs.costMap(cost).run();
547 547
    ///
548 548
    ///   // Run again from scratch using resetParams()
549 549
    ///   // (the lower bounds will be set to zero on all arcs)
550 550
    ///   cs.resetParams();
551 551
    ///   cs.upperMap(capacity).costMap(cost)
552 552
    ///     .supplyMap(sup).run();
553 553
    /// \endcode
554 554
    ///
555 555
    /// \return <tt>(*this)</tt>
556 556
    ///
557 557
    /// \see reset(), run()
558 558
    CostScaling& resetParams() {
559 559
      for (int i = 0; i != _res_node_num; ++i) {
560 560
        _supply[i] = 0;
561 561
      }
562 562
      int limit = _first_out[_root];
563 563
      for (int j = 0; j != limit; ++j) {
564 564
        _lower[j] = 0;
565 565
        _upper[j] = INF;
566 566
        _scost[j] = _forward[j] ? 1 : -1;
567 567
      }
568 568
      for (int j = limit; j != _res_arc_num; ++j) {
569 569
        _lower[j] = 0;
570 570
        _upper[j] = INF;
571 571
        _scost[j] = 0;
572 572
        _scost[_reverse[j]] = 0;
573 573
      }
574 574
      _have_lower = false;
575 575
      return *this;
576 576
    }
577 577

	
578
    /// \brief Reset all the parameters that have been given before.
578
    /// \brief Reset the internal data structures and all the parameters
579
    /// that have been given before.
579 580
    ///
580
    /// This function resets all the paramaters that have been given
581
    /// before using functions \ref lowerMap(), \ref upperMap(),
582
    /// \ref costMap(), \ref supplyMap(), \ref stSupply().
581
    /// This function resets the internal data structures and all the
582
    /// paramaters that have been given before using functions \ref lowerMap(),
583
    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply().
583 584
    ///
584
    /// It is useful for multiple run() calls. If this function is not
585
    /// used, all the parameters given before are kept for the next
586
    /// \ref run() call.
587
    /// However, the underlying digraph must not be modified after this
588
    /// class have been constructed, since it copies and extends the graph.
585
    /// It is useful for multiple \ref run() calls. By default, all the given
586
    /// parameters are kept for the next \ref run() call, unless
587
    /// \ref resetParams() or \ref reset() is used.
588
    /// If the underlying digraph was also modified after the construction
589
    /// of the class or the last \ref reset() call, then the \ref reset()
590
    /// function must be used, otherwise \ref resetParams() is sufficient.
591
    ///
592
    /// See \ref resetParams() for examples.
593
    ///
589 594
    /// \return <tt>(*this)</tt>
595
    ///
596
    /// \see resetParams(), run()
590 597
    CostScaling& reset() {
591 598
      // Resize vectors
592 599
      _node_num = countNodes(_graph);
593 600
      _arc_num = countArcs(_graph);
594 601
      _res_node_num = _node_num + 1;
595 602
      _res_arc_num = 2 * (_arc_num + _node_num);
596 603
      _root = _node_num;
597 604

	
598 605
      _first_out.resize(_res_node_num + 1);
599 606
      _forward.resize(_res_arc_num);
600 607
      _source.resize(_res_arc_num);
601 608
      _target.resize(_res_arc_num);
602 609
      _reverse.resize(_res_arc_num);
603 610

	
604 611
      _lower.resize(_res_arc_num);
605 612
      _upper.resize(_res_arc_num);
606 613
      _scost.resize(_res_arc_num);
607 614
      _supply.resize(_res_node_num);
608 615

	
609 616
      _res_cap.resize(_res_arc_num);
610 617
      _cost.resize(_res_arc_num);
611 618
      _pi.resize(_res_node_num);
612 619
      _excess.resize(_res_node_num);
613 620
      _next_out.resize(_res_node_num);
614 621

	
615 622
      _arc_vec.reserve(_res_arc_num);
616 623
      _cost_vec.reserve(_res_arc_num);
617 624

	
618 625
      // Copy the graph
619 626
      int i = 0, j = 0, k = 2 * _arc_num + _node_num;
620 627
      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
621 628
        _node_id[n] = i;
622 629
      }
623 630
      i = 0;
624 631
      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
625 632
        _first_out[i] = j;
626 633
        for (OutArcIt a(_graph, n); a != INVALID; ++a, ++j) {
627 634
          _arc_idf[a] = j;
628 635
          _forward[j] = true;
629 636
          _source[j] = i;
630 637
          _target[j] = _node_id[_graph.runningNode(a)];
631 638
        }
632 639
        for (InArcIt a(_graph, n); a != INVALID; ++a, ++j) {
633 640
          _arc_idb[a] = j;
634 641
          _forward[j] = false;
635 642
          _source[j] = i;
636 643
          _target[j] = _node_id[_graph.runningNode(a)];
637 644
        }
638 645
        _forward[j] = false;
639 646
        _source[j] = i;
640 647
        _target[j] = _root;
641 648
        _reverse[j] = k;
642 649
        _forward[k] = true;
643 650
        _source[k] = _root;
644 651
        _target[k] = i;
645 652
        _reverse[k] = j;
646 653
        ++j; ++k;
647 654
      }
648 655
      _first_out[i] = j;
649 656
      _first_out[_res_node_num] = k;
650 657
      for (ArcIt a(_graph); a != INVALID; ++a) {
651 658
        int fi = _arc_idf[a];
652 659
        int bi = _arc_idb[a];
653 660
        _reverse[fi] = bi;
654 661
        _reverse[bi] = fi;
655 662
      }
656 663

	
657 664
      // Reset parameters
658 665
      resetParams();
659 666
      return *this;
660 667
    }
661 668

	
662 669
    /// @}
663 670

	
664 671
    /// \name Query Functions
665 672
    /// The results of the algorithm can be obtained using these
666 673
    /// functions.\n
667 674
    /// The \ref run() function must be called before using them.
668 675

	
669 676
    /// @{
670 677

	
671 678
    /// \brief Return the total cost of the found flow.
672 679
    ///
673 680
    /// This function returns the total cost of the found flow.
674 681
    /// Its complexity is O(e).
675 682
    ///
676 683
    /// \note The return type of the function can be specified as a
677 684
    /// template parameter. For example,
678 685
    /// \code
679 686
    ///   cs.totalCost<double>();
680 687
    /// \endcode
681 688
    /// It is useful if the total cost cannot be stored in the \c Cost
682 689
    /// type of the algorithm, which is the default return type of the
683 690
    /// function.
684 691
    ///
685 692
    /// \pre \ref run() must be called before using this function.
686 693
    template <typename Number>
687 694
    Number totalCost() const {
688 695
      Number c = 0;
689 696
      for (ArcIt a(_graph); a != INVALID; ++a) {
690 697
        int i = _arc_idb[a];
691 698
        c += static_cast<Number>(_res_cap[i]) *
692 699
             (-static_cast<Number>(_scost[i]));
693 700
      }
694 701
      return c;
695 702
    }
696 703

	
697 704
#ifndef DOXYGEN
698 705
    Cost totalCost() const {
699 706
      return totalCost<Cost>();
700 707
    }
701 708
#endif
702 709

	
703 710
    /// \brief Return the flow on the given arc.
704 711
    ///
705 712
    /// This function returns the flow on the given arc.
706 713
    ///
707 714
    /// \pre \ref run() must be called before using this function.
708 715
    Value flow(const Arc& a) const {
709 716
      return _res_cap[_arc_idb[a]];
710 717
    }
711 718

	
712 719
    /// \brief Return the flow map (the primal solution).
713 720
    ///
714 721
    /// This function copies the flow value on each arc into the given
715 722
    /// map. The \c Value type of the algorithm must be convertible to
716 723
    /// the \c Value type of the map.
717 724
    ///
718 725
    /// \pre \ref run() must be called before using this function.
719 726
    template <typename FlowMap>
720 727
    void flowMap(FlowMap &map) const {
721 728
      for (ArcIt a(_graph); a != INVALID; ++a) {
722 729
        map.set(a, _res_cap[_arc_idb[a]]);
723 730
      }
724 731
    }
725 732

	
726 733
    /// \brief Return the potential (dual value) of the given node.
727 734
    ///
728 735
    /// This function returns the potential (dual value) of the
729 736
    /// given node.
730 737
    ///
731 738
    /// \pre \ref run() must be called before using this function.
732 739
    Cost potential(const Node& n) const {
733 740
      return static_cast<Cost>(_pi[_node_id[n]]);
734 741
    }
735 742

	
736 743
    /// \brief Return the potential map (the dual solution).
737 744
    ///
738 745
    /// This function copies the potential (dual value) of each node
739 746
    /// into the given map.
740 747
    /// The \c Cost type of the algorithm must be convertible to the
741 748
    /// \c Value type of the map.
742 749
    ///
743 750
    /// \pre \ref run() must be called before using this function.
744 751
    template <typename PotentialMap>
745 752
    void potentialMap(PotentialMap &map) const {
746 753
      for (NodeIt n(_graph); n != INVALID; ++n) {
747 754
        map.set(n, static_cast<Cost>(_pi[_node_id[n]]));
748 755
      }
749 756
    }
750 757

	
751 758
    /// @}
752 759

	
753 760
  private:
754 761

	
755 762
    // Initialize the algorithm
756 763
    ProblemType init() {
757 764
      if (_res_node_num <= 1) return INFEASIBLE;
758 765

	
759 766
      // Check the sum of supply values
760 767
      _sum_supply = 0;
761 768
      for (int i = 0; i != _root; ++i) {
762 769
        _sum_supply += _supply[i];
763 770
      }
764 771
      if (_sum_supply > 0) return INFEASIBLE;
765 772

	
766 773

	
767 774
      // Initialize vectors
768 775
      for (int i = 0; i != _res_node_num; ++i) {
769 776
        _pi[i] = 0;
770 777
        _excess[i] = _supply[i];
771 778
      }
772 779

	
773 780
      // Remove infinite upper bounds and check negative arcs
774 781
      const Value MAX = std::numeric_limits<Value>::max();
775 782
      int last_out;
776 783
      if (_have_lower) {
777 784
        for (int i = 0; i != _root; ++i) {
778 785
          last_out = _first_out[i+1];
779 786
          for (int j = _first_out[i]; j != last_out; ++j) {
780 787
            if (_forward[j]) {
781 788
              Value c = _scost[j] < 0 ? _upper[j] : _lower[j];
782 789
              if (c >= MAX) return UNBOUNDED;
783 790
              _excess[i] -= c;
784 791
              _excess[_target[j]] += c;
785 792
            }
786 793
          }
787 794
        }
788 795
      } else {
789 796
        for (int i = 0; i != _root; ++i) {
790 797
          last_out = _first_out[i+1];
791 798
          for (int j = _first_out[i]; j != last_out; ++j) {
792 799
            if (_forward[j] && _scost[j] < 0) {
793 800
              Value c = _upper[j];
794 801
              if (c >= MAX) return UNBOUNDED;
795 802
              _excess[i] -= c;
796 803
              _excess[_target[j]] += c;
797 804
            }
798 805
          }
799 806
        }
800 807
      }
801 808
      Value ex, max_cap = 0;
802 809
      for (int i = 0; i != _res_node_num; ++i) {
803 810
        ex = _excess[i];
804 811
        _excess[i] = 0;
805 812
        if (ex < 0) max_cap -= ex;
806 813
      }
807 814
      for (int j = 0; j != _res_arc_num; ++j) {
808 815
        if (_upper[j] >= MAX) _upper[j] = max_cap;
809 816
      }
810 817

	
811 818
      // Initialize the large cost vector and the epsilon parameter
812 819
      _epsilon = 0;
813 820
      LargeCost lc;
814 821
      for (int i = 0; i != _root; ++i) {
815 822
        last_out = _first_out[i+1];
816 823
        for (int j = _first_out[i]; j != last_out; ++j) {
817 824
          lc = static_cast<LargeCost>(_scost[j]) * _res_node_num * _alpha;
818 825
          _cost[j] = lc;
819 826
          if (lc > _epsilon) _epsilon = lc;
820 827
        }
821 828
      }
822 829
      _epsilon /= _alpha;
823 830

	
824 831
      // Initialize maps for Circulation and remove non-zero lower bounds
825 832
      ConstMap<Arc, Value> low(0);
826 833
      typedef typename Digraph::template ArcMap<Value> ValueArcMap;
827 834
      typedef typename Digraph::template NodeMap<Value> ValueNodeMap;
828 835
      ValueArcMap cap(_graph), flow(_graph);
829 836
      ValueNodeMap sup(_graph);
830 837
      for (NodeIt n(_graph); n != INVALID; ++n) {
831 838
        sup[n] = _supply[_node_id[n]];
832 839
      }
833 840
      if (_have_lower) {
834 841
        for (ArcIt a(_graph); a != INVALID; ++a) {
835 842
          int j = _arc_idf[a];
836 843
          Value c = _lower[j];
837 844
          cap[a] = _upper[j] - c;
838 845
          sup[_graph.source(a)] -= c;
839 846
          sup[_graph.target(a)] += c;
840 847
        }
841 848
      } else {
842 849
        for (ArcIt a(_graph); a != INVALID; ++a) {
843 850
          cap[a] = _upper[_arc_idf[a]];
844 851
        }
845 852
      }
846 853

	
847 854
      _sup_node_num = 0;
848 855
      for (NodeIt n(_graph); n != INVALID; ++n) {
849 856
        if (sup[n] > 0) ++_sup_node_num;
850 857
      }
851 858

	
852 859
      // Find a feasible flow using Circulation
853 860
      Circulation<Digraph, ConstMap<Arc, Value>, ValueArcMap, ValueNodeMap>
854 861
        circ(_graph, low, cap, sup);
855 862
      if (!circ.flowMap(flow).run()) return INFEASIBLE;
856 863

	
857 864
      // Set residual capacities and handle GEQ supply type
858 865
      if (_sum_supply < 0) {
859 866
        for (ArcIt a(_graph); a != INVALID; ++a) {
860 867
          Value fa = flow[a];
861 868
          _res_cap[_arc_idf[a]] = cap[a] - fa;
862 869
          _res_cap[_arc_idb[a]] = fa;
863 870
          sup[_graph.source(a)] -= fa;
864 871
          sup[_graph.target(a)] += fa;
865 872
        }
866 873
        for (NodeIt n(_graph); n != INVALID; ++n) {
867 874
          _excess[_node_id[n]] = sup[n];
868 875
        }
869 876
        for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
870 877
          int u = _target[a];
871 878
          int ra = _reverse[a];
872 879
          _res_cap[a] = -_sum_supply + 1;
873 880
          _res_cap[ra] = -_excess[u];
874 881
          _cost[a] = 0;
875 882
          _cost[ra] = 0;
876 883
          _excess[u] = 0;
877 884
        }
878 885
      } else {
879 886
        for (ArcIt a(_graph); a != INVALID; ++a) {
880 887
          Value fa = flow[a];
881 888
          _res_cap[_arc_idf[a]] = cap[a] - fa;
882 889
          _res_cap[_arc_idb[a]] = fa;
883 890
        }
884 891
        for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
885 892
          int ra = _reverse[a];
886 893
          _res_cap[a] = 0;
887 894
          _res_cap[ra] = 0;
888 895
          _cost[a] = 0;
889 896
          _cost[ra] = 0;
890 897
        }
891 898
      }
892 899

	
893
      return OPTIMAL;
894
    }
895

	
896
    // Execute the algorithm and transform the results
897
    void start(Method method) {
898
      // Maximum path length for partial augment
899
      const int MAX_PATH_LENGTH = 4;
900

	
901 900
      // Initialize data structures for buckets
902 901
      _max_rank = _alpha * _res_node_num;
903 902
      _buckets.resize(_max_rank);
904 903
      _bucket_next.resize(_res_node_num + 1);
905 904
      _bucket_prev.resize(_res_node_num + 1);
906 905
      _rank.resize(_res_node_num + 1);
907 906

	
908
      // Execute the algorithm
907
      return OPTIMAL;
908
    }
909

	
910
    // Execute the algorithm and transform the results
911
    void start(Method method) {
912
      const int MAX_PARTIAL_PATH_LENGTH = 4;
913

	
909 914
      switch (method) {
910 915
        case PUSH:
911 916
          startPush();
912 917
          break;
913 918
        case AUGMENT:
914 919
          startAugment(_res_node_num - 1);
915 920
          break;
916 921
        case PARTIAL_AUGMENT:
917
          startAugment(MAX_PATH_LENGTH);
922
          startAugment(MAX_PARTIAL_PATH_LENGTH);
918 923
          break;
919 924
      }
920 925

	
921 926
      // Compute node potentials for the original costs
922 927
      _arc_vec.clear();
923 928
      _cost_vec.clear();
924 929
      for (int j = 0; j != _res_arc_num; ++j) {
925 930
        if (_res_cap[j] > 0) {
926 931
          _arc_vec.push_back(IntPair(_source[j], _target[j]));
927 932
          _cost_vec.push_back(_scost[j]);
928 933
        }
929 934
      }
930 935
      _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end());
931 936

	
932 937
      typename BellmanFord<StaticDigraph, LargeCostArcMap>
933 938
        ::template SetDistMap<LargeCostNodeMap>::Create bf(_sgr, _cost_map);
934 939
      bf.distMap(_pi_map);
935 940
      bf.init(0);
936 941
      bf.start();
937 942

	
938 943
      // Handle non-zero lower bounds
939 944
      if (_have_lower) {
940 945
        int limit = _first_out[_root];
941 946
        for (int j = 0; j != limit; ++j) {
942 947
          if (!_forward[j]) _res_cap[j] += _lower[j];
943 948
        }
944 949
      }
945 950
    }
946 951

	
947 952
    // Initialize a cost scaling phase
948 953
    void initPhase() {
949 954
      // Saturate arcs not satisfying the optimality condition
950 955
      for (int u = 0; u != _res_node_num; ++u) {
951 956
        int last_out = _first_out[u+1];
952 957
        LargeCost pi_u = _pi[u];
953 958
        for (int a = _first_out[u]; a != last_out; ++a) {
954
          int v = _target[a];
955
          if (_res_cap[a] > 0 && _cost[a] + pi_u - _pi[v] < 0) {
956
            Value delta = _res_cap[a];
957
            _excess[u] -= delta;
958
            _excess[v] += delta;
959
            _res_cap[a] = 0;
960
            _res_cap[_reverse[a]] += delta;
959
          Value delta = _res_cap[a];
960
          if (delta > 0) {
961
            int v = _target[a];
962
            if (_cost[a] + pi_u - _pi[v] < 0) {
963
              _excess[u] -= delta;
964
              _excess[v] += delta;
965
              _res_cap[a] = 0;
966
              _res_cap[_reverse[a]] += delta;
967
            }
961 968
          }
962 969
        }
963 970
      }
964 971

	
965 972
      // Find active nodes (i.e. nodes with positive excess)
966 973
      for (int u = 0; u != _res_node_num; ++u) {
967 974
        if (_excess[u] > 0) _active_nodes.push_back(u);
968 975
      }
969 976

	
970 977
      // Initialize the next arcs
971 978
      for (int u = 0; u != _res_node_num; ++u) {
972 979
        _next_out[u] = _first_out[u];
973 980
      }
974 981
    }
975 982

	
976 983
    // Early termination heuristic
977 984
    bool earlyTermination() {
978 985
      const double EARLY_TERM_FACTOR = 3.0;
979 986

	
980 987
      // Build a static residual graph
981 988
      _arc_vec.clear();
982 989
      _cost_vec.clear();
983 990
      for (int j = 0; j != _res_arc_num; ++j) {
984 991
        if (_res_cap[j] > 0) {
985 992
          _arc_vec.push_back(IntPair(_source[j], _target[j]));
986 993
          _cost_vec.push_back(_cost[j] + 1);
987 994
        }
988 995
      }
989 996
      _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end());
990 997

	
991 998
      // Run Bellman-Ford algorithm to check if the current flow is optimal
992 999
      BellmanFord<StaticDigraph, LargeCostArcMap> bf(_sgr, _cost_map);
993 1000
      bf.init(0);
994 1001
      bool done = false;
995 1002
      int K = int(EARLY_TERM_FACTOR * std::sqrt(double(_res_node_num)));
996 1003
      for (int i = 0; i < K && !done; ++i) {
997 1004
        done = bf.processNextWeakRound();
998 1005
      }
999 1006
      return done;
1000 1007
    }
1001 1008

	
1002 1009
    // Global potential update heuristic
1003 1010
    void globalUpdate() {
1004
      int bucket_end = _root + 1;
1011
      const int bucket_end = _root + 1;
1005 1012

	
1006 1013
      // Initialize buckets
1007 1014
      for (int r = 0; r != _max_rank; ++r) {
1008 1015
        _buckets[r] = bucket_end;
1009 1016
      }
1010 1017
      Value total_excess = 0;
1018
      int b0 = bucket_end;
1011 1019
      for (int i = 0; i != _res_node_num; ++i) {
1012 1020
        if (_excess[i] < 0) {
1013 1021
          _rank[i] = 0;
1014
          _bucket_next[i] = _buckets[0];
1015
          _bucket_prev[_buckets[0]] = i;
1016
          _buckets[0] = i;
1022
          _bucket_next[i] = b0;
1023
          _bucket_prev[b0] = i;
1024
          b0 = i;
1017 1025
        } else {
1018 1026
          total_excess += _excess[i];
1019 1027
          _rank[i] = _max_rank;
1020 1028
        }
1021 1029
      }
1022 1030
      if (total_excess == 0) return;
1031
      _buckets[0] = b0;
1023 1032

	
1024 1033
      // Search the buckets
1025 1034
      int r = 0;
1026 1035
      for ( ; r != _max_rank; ++r) {
1027 1036
        while (_buckets[r] != bucket_end) {
1028 1037
          // Remove the first node from the current bucket
1029 1038
          int u = _buckets[r];
1030 1039
          _buckets[r] = _bucket_next[u];
1031 1040

	
1032 1041
          // Search the incomming arcs of u
1033 1042
          LargeCost pi_u = _pi[u];
1034 1043
          int last_out = _first_out[u+1];
1035 1044
          for (int a = _first_out[u]; a != last_out; ++a) {
1036 1045
            int ra = _reverse[a];
1037 1046
            if (_res_cap[ra] > 0) {
1038 1047
              int v = _source[ra];
1039 1048
              int old_rank_v = _rank[v];
1040 1049
              if (r < old_rank_v) {
1041 1050
                // Compute the new rank of v
1042 1051
                LargeCost nrc = (_cost[ra] + _pi[v] - pi_u) / _epsilon;
1043 1052
                int new_rank_v = old_rank_v;
1044
                if (nrc < LargeCost(_max_rank))
1045
                  new_rank_v = r + 1 + int(nrc);
1053
                if (nrc < LargeCost(_max_rank)) {
1054
                  new_rank_v = r + 1 + static_cast<int>(nrc);
1055
                }
1046 1056

	
1047 1057
                // Change the rank of v
1048 1058
                if (new_rank_v < old_rank_v) {
1049 1059
                  _rank[v] = new_rank_v;
1050 1060
                  _next_out[v] = _first_out[v];
1051 1061

	
1052 1062
                  // Remove v from its old bucket
1053 1063
                  if (old_rank_v < _max_rank) {
1054 1064
                    if (_buckets[old_rank_v] == v) {
1055 1065
                      _buckets[old_rank_v] = _bucket_next[v];
1056 1066
                    } else {
1057
                      _bucket_next[_bucket_prev[v]] = _bucket_next[v];
1058
                      _bucket_prev[_bucket_next[v]] = _bucket_prev[v];
1067
                      int pv = _bucket_prev[v], nv = _bucket_next[v];
1068
                      _bucket_next[pv] = nv;
1069
                      _bucket_prev[nv] = pv;
1059 1070
                    }
1060 1071
                  }
1061 1072

	
1062
                  // Insert v to its new bucket
1063
                  _bucket_next[v] = _buckets[new_rank_v];
1064
                  _bucket_prev[_buckets[new_rank_v]] = v;
1073
                  // Insert v into its new bucket
1074
                  int nv = _buckets[new_rank_v];
1075
                  _bucket_next[v] = nv;
1076
                  _bucket_prev[nv] = v;
1065 1077
                  _buckets[new_rank_v] = v;
1066 1078
                }
1067 1079
              }
1068 1080
            }
1069 1081
          }
1070 1082

	
1071 1083
          // Finish search if there are no more active nodes
1072 1084
          if (_excess[u] > 0) {
1073 1085
            total_excess -= _excess[u];
1074 1086
            if (total_excess <= 0) break;
1075 1087
          }
1076 1088
        }
1077 1089
        if (total_excess <= 0) break;
1078 1090
      }
1079 1091

	
1080 1092
      // Relabel nodes
1081 1093
      for (int u = 0; u != _res_node_num; ++u) {
1082 1094
        int k = std::min(_rank[u], r);
1083 1095
        if (k > 0) {
1084 1096
          _pi[u] -= _epsilon * k;
1085 1097
          _next_out[u] = _first_out[u];
1086 1098
        }
1087 1099
      }
1088 1100
    }
1089 1101

	
1090 1102
    /// Execute the algorithm performing augment and relabel operations
1091 1103
    void startAugment(int max_length) {
1092 1104
      // Paramters for heuristics
1093 1105
      const int EARLY_TERM_EPSILON_LIMIT = 1000;
1094 1106
      const double GLOBAL_UPDATE_FACTOR = 3.0;
1095 1107

	
1096 1108
      const int global_update_freq = int(GLOBAL_UPDATE_FACTOR *
1097 1109
        (_res_node_num + _sup_node_num * _sup_node_num));
1098 1110
      int next_update_limit = global_update_freq;
1099 1111

	
1100 1112
      int relabel_cnt = 0;
1101 1113

	
1102 1114
      // Perform cost scaling phases
1103 1115
      std::vector<int> path;
1104 1116
      for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
1105 1117
                                        1 : _epsilon / _alpha )
1106 1118
      {
1107 1119
        // Early termination heuristic
1108 1120
        if (_epsilon <= EARLY_TERM_EPSILON_LIMIT) {
1109 1121
          if (earlyTermination()) break;
1110 1122
        }
1111 1123

	
1112 1124
        // Initialize current phase
1113 1125
        initPhase();
1114 1126

	
1115 1127
        // Perform partial augment and relabel operations
1116 1128
        while (true) {
1117 1129
          // Select an active node (FIFO selection)
1118 1130
          while (_active_nodes.size() > 0 &&
1119 1131
                 _excess[_active_nodes.front()] <= 0) {
1120 1132
            _active_nodes.pop_front();
1121 1133
          }
1122 1134
          if (_active_nodes.size() == 0) break;
1123 1135
          int start = _active_nodes.front();
1124 1136

	
1125 1137
          // Find an augmenting path from the start node
1126 1138
          path.clear();
1127 1139
          int tip = start;
1128 1140
          while (_excess[tip] >= 0 && int(path.size()) < max_length) {
1129 1141
            int u;
1130 1142
            LargeCost min_red_cost, rc, pi_tip = _pi[tip];
1131 1143
            int last_out = _first_out[tip+1];
1132 1144
            for (int a = _next_out[tip]; a != last_out; ++a) {
1133 1145
              u = _target[a];
1134 1146
              if (_res_cap[a] > 0 && _cost[a] + pi_tip - _pi[u] < 0) {
1135 1147
                path.push_back(a);
1136 1148
                _next_out[tip] = a;
1137 1149
                tip = u;
1138 1150
                goto next_step;
1139 1151
              }
1140 1152
            }
1141 1153

	
1142 1154
            // Relabel tip node
1143 1155
            min_red_cost = std::numeric_limits<LargeCost>::max();
1144 1156
            if (tip != start) {
1145 1157
              int ra = _reverse[path.back()];
1146 1158
              min_red_cost = _cost[ra] + pi_tip - _pi[_target[ra]];
1147 1159
            }
1148 1160
            for (int a = _first_out[tip]; a != last_out; ++a) {
1149 1161
              rc = _cost[a] + pi_tip - _pi[_target[a]];
1150 1162
              if (_res_cap[a] > 0 && rc < min_red_cost) {
1151 1163
                min_red_cost = rc;
1152 1164
              }
1153 1165
            }
1154 1166
            _pi[tip] -= min_red_cost + _epsilon;
1155 1167
            _next_out[tip] = _first_out[tip];
1156 1168
            ++relabel_cnt;
1157 1169

	
1158 1170
            // Step back
1159 1171
            if (tip != start) {
1160 1172
              tip = _source[path.back()];
1161 1173
              path.pop_back();
1162 1174
            }
1163 1175

	
1164 1176
          next_step: ;
1165 1177
          }
1166 1178

	
1167 1179
          // Augment along the found path (as much flow as possible)
1168 1180
          Value delta;
1169 1181
          int pa, u, v = start;
1170 1182
          for (int i = 0; i != int(path.size()); ++i) {
1171 1183
            pa = path[i];
1172 1184
            u = v;
1173 1185
            v = _target[pa];
1174 1186
            delta = std::min(_res_cap[pa], _excess[u]);
1175 1187
            _res_cap[pa] -= delta;
1176 1188
            _res_cap[_reverse[pa]] += delta;
1177 1189
            _excess[u] -= delta;
1178 1190
            _excess[v] += delta;
1179 1191
            if (_excess[v] > 0 && _excess[v] <= delta)
1180 1192
              _active_nodes.push_back(v);
1181 1193
          }
1182 1194

	
1183 1195
          // Global update heuristic
1184 1196
          if (relabel_cnt >= next_update_limit) {
1185 1197
            globalUpdate();
1186 1198
            next_update_limit += global_update_freq;
1187 1199
          }
1188 1200
        }
1189 1201
      }
1190 1202
    }
1191 1203

	
1192 1204
    /// Execute the algorithm performing push and relabel operations
1193 1205
    void startPush() {
1194 1206
      // Paramters for heuristics
1195 1207
      const int EARLY_TERM_EPSILON_LIMIT = 1000;
1196 1208
      const double GLOBAL_UPDATE_FACTOR = 2.0;
1197 1209

	
1198 1210
      const int global_update_freq = int(GLOBAL_UPDATE_FACTOR *
1199 1211
        (_res_node_num + _sup_node_num * _sup_node_num));
1200 1212
      int next_update_limit = global_update_freq;
1201 1213

	
1202 1214
      int relabel_cnt = 0;
1203 1215

	
1204 1216
      // Perform cost scaling phases
1205 1217
      BoolVector hyper(_res_node_num, false);
1206 1218
      LargeCostVector hyper_cost(_res_node_num);
1207 1219
      for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
1208 1220
                                        1 : _epsilon / _alpha )
1209 1221
      {
1210 1222
        // Early termination heuristic
1211 1223
        if (_epsilon <= EARLY_TERM_EPSILON_LIMIT) {
1212 1224
          if (earlyTermination()) break;
1213 1225
        }
1214 1226

	
1215 1227
        // Initialize current phase
1216 1228
        initPhase();
1217 1229

	
1218 1230
        // Perform push and relabel operations
1219 1231
        while (_active_nodes.size() > 0) {
1220 1232
          LargeCost min_red_cost, rc, pi_n;
1221 1233
          Value delta;
1222 1234
          int n, t, a, last_out = _res_arc_num;
1223 1235

	
1224 1236
        next_node:
1225 1237
          // Select an active node (FIFO selection)
1226 1238
          n = _active_nodes.front();
1227 1239
          last_out = _first_out[n+1];
1228 1240
          pi_n = _pi[n];
1229 1241

	
1230 1242
          // Perform push operations if there are admissible arcs
1231 1243
          if (_excess[n] > 0) {
1232 1244
            for (a = _next_out[n]; a != last_out; ++a) {
1233 1245
              if (_res_cap[a] > 0 &&
1234 1246
                  _cost[a] + pi_n - _pi[_target[a]] < 0) {
1235 1247
                delta = std::min(_res_cap[a], _excess[n]);
1236 1248
                t = _target[a];
1237 1249

	
1238 1250
                // Push-look-ahead heuristic
1239 1251
                Value ahead = -_excess[t];
1240 1252
                int last_out_t = _first_out[t+1];
1241 1253
                LargeCost pi_t = _pi[t];
1242 1254
                for (int ta = _next_out[t]; ta != last_out_t; ++ta) {
1243 1255
                  if (_res_cap[ta] > 0 &&
1244 1256
                      _cost[ta] + pi_t - _pi[_target[ta]] < 0)
1245 1257
                    ahead += _res_cap[ta];
1246 1258
                  if (ahead >= delta) break;
1247 1259
                }
1248 1260
                if (ahead < 0) ahead = 0;
1249 1261

	
1250 1262
                // Push flow along the arc
1251 1263
                if (ahead < delta && !hyper[t]) {
1252 1264
                  _res_cap[a] -= ahead;
1253 1265
                  _res_cap[_reverse[a]] += ahead;
1254 1266
                  _excess[n] -= ahead;
1255 1267
                  _excess[t] += ahead;
1256 1268
                  _active_nodes.push_front(t);
0 comments (0 inline)