gravatar
deba@inf.elte.hu
deba@inf.elte.hu
Fix multiple execution bug in weighted matchings (#356) This chgset also redoes the fix of [28c7ad6f8d91] and its backpont to 1.1, [268a052c3043].
0 2 0
default
2 files changed with 74 insertions and 5 deletions:
↑ Collapse diff ↑
Show white space 384 line context
... ...
@@ -616,419 +616,438 @@
616 616
    /// This function returns the \ref Status "status" of the given node
617 617
    /// in the Edmonds-Gallai decomposition.
618 618
    Status status(const Node& n) const {
619 619
      return (*_status)[n];
620 620
    }
621 621

	
622 622
    /// \brief Return a const reference to the status map, which stores
623 623
    /// the Edmonds-Gallai decomposition.
624 624
    ///
625 625
    /// This function returns a const reference to a node map that stores the
626 626
    /// \ref Status "status" of each node in the Edmonds-Gallai decomposition.
627 627
    const StatusMap& statusMap() const {
628 628
      return *_status;
629 629
    }
630 630

	
631 631
    /// \brief Return \c true if the given node is in the barrier.
632 632
    ///
633 633
    /// This function returns \c true if the given node is in the barrier.
634 634
    bool barrier(const Node& n) const {
635 635
      return (*_status)[n] == ODD;
636 636
    }
637 637

	
638 638
    /// @}
639 639

	
640 640
  };
641 641

	
642 642
  /// \ingroup matching
643 643
  ///
644 644
  /// \brief Weighted matching in general graphs
645 645
  ///
646 646
  /// This class provides an efficient implementation of Edmond's
647 647
  /// maximum weighted matching algorithm. The implementation is based
648 648
  /// on extensive use of priority queues and provides
649 649
  /// \f$O(nm\log n)\f$ time complexity.
650 650
  ///
651 651
  /// The maximum weighted matching problem is to find a subset of the 
652 652
  /// edges in an undirected graph with maximum overall weight for which 
653 653
  /// each node has at most one incident edge.
654 654
  /// It can be formulated with the following linear program.
655 655
  /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
656 656
  /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2}
657 657
      \quad \forall B\in\mathcal{O}\f] */
658 658
  /// \f[x_e \ge 0\quad \forall e\in E\f]
659 659
  /// \f[\max \sum_{e\in E}x_ew_e\f]
660 660
  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
661 661
  /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in
662 662
  /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality
663 663
  /// subsets of the nodes.
664 664
  ///
665 665
  /// The algorithm calculates an optimal matching and a proof of the
666 666
  /// optimality. The solution of the dual problem can be used to check
667 667
  /// the result of the algorithm. The dual linear problem is the
668 668
  /// following.
669 669
  /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)}
670 670
      z_B \ge w_{uv} \quad \forall uv\in E\f] */
671 671
  /// \f[y_u \ge 0 \quad \forall u \in V\f]
672 672
  /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f]
673 673
  /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
674 674
      \frac{\vert B \vert - 1}{2}z_B\f] */
675 675
  ///
676 676
  /// The algorithm can be executed with the run() function. 
677 677
  /// After it the matching (the primal solution) and the dual solution
678 678
  /// can be obtained using the query functions and the 
679 679
  /// \ref MaxWeightedMatching::BlossomIt "BlossomIt" nested class, 
680 680
  /// which is able to iterate on the nodes of a blossom. 
681 681
  /// If the value type is integer, then the dual solution is multiplied
682 682
  /// by \ref MaxWeightedMatching::dualScale "4".
683 683
  ///
684 684
  /// \tparam GR The undirected graph type the algorithm runs on.
685 685
  /// \tparam WM The type edge weight map. The default type is 
686 686
  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
687 687
#ifdef DOXYGEN
688 688
  template <typename GR, typename WM>
689 689
#else
690 690
  template <typename GR,
691 691
            typename WM = typename GR::template EdgeMap<int> >
692 692
#endif
693 693
  class MaxWeightedMatching {
694 694
  public:
695 695

	
696 696
    /// The graph type of the algorithm
697 697
    typedef GR Graph;
698 698
    /// The type of the edge weight map
699 699
    typedef WM WeightMap;
700 700
    /// The value type of the edge weights
701 701
    typedef typename WeightMap::Value Value;
702 702

	
703 703
    /// The type of the matching map
704 704
    typedef typename Graph::template NodeMap<typename Graph::Arc>
705 705
    MatchingMap;
706 706

	
707 707
    /// \brief Scaling factor for dual solution
708 708
    ///
709 709
    /// Scaling factor for dual solution. It is equal to 4 or 1
710 710
    /// according to the value type.
711 711
    static const int dualScale =
712 712
      std::numeric_limits<Value>::is_integer ? 4 : 1;
713 713

	
714 714
  private:
715 715

	
716 716
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
717 717

	
718 718
    typedef typename Graph::template NodeMap<Value> NodePotential;
719 719
    typedef std::vector<Node> BlossomNodeList;
720 720

	
721 721
    struct BlossomVariable {
722 722
      int begin, end;
723 723
      Value value;
724 724

	
725 725
      BlossomVariable(int _begin, int _end, Value _value)
726 726
        : begin(_begin), end(_end), value(_value) {}
727 727

	
728 728
    };
729 729

	
730 730
    typedef std::vector<BlossomVariable> BlossomPotential;
731 731

	
732 732
    const Graph& _graph;
733 733
    const WeightMap& _weight;
734 734

	
735 735
    MatchingMap* _matching;
736 736

	
737 737
    NodePotential* _node_potential;
738 738

	
739 739
    BlossomPotential _blossom_potential;
740 740
    BlossomNodeList _blossom_node_list;
741 741

	
742 742
    int _node_num;
743 743
    int _blossom_num;
744 744

	
745 745
    typedef RangeMap<int> IntIntMap;
746 746

	
747 747
    enum Status {
748 748
      EVEN = -1, MATCHED = 0, ODD = 1, UNMATCHED = -2
749 749
    };
750 750

	
751 751
    typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
752 752
    struct BlossomData {
753 753
      int tree;
754 754
      Status status;
755 755
      Arc pred, next;
756 756
      Value pot, offset;
757 757
      Node base;
758 758
    };
759 759

	
760 760
    IntNodeMap *_blossom_index;
761 761
    BlossomSet *_blossom_set;
762 762
    RangeMap<BlossomData>* _blossom_data;
763 763

	
764 764
    IntNodeMap *_node_index;
765 765
    IntArcMap *_node_heap_index;
766 766

	
767 767
    struct NodeData {
768 768

	
769 769
      NodeData(IntArcMap& node_heap_index)
770 770
        : heap(node_heap_index) {}
771 771

	
772 772
      int blossom;
773 773
      Value pot;
774 774
      BinHeap<Value, IntArcMap> heap;
775 775
      std::map<int, Arc> heap_index;
776 776

	
777 777
      int tree;
778 778
    };
779 779

	
780 780
    RangeMap<NodeData>* _node_data;
781 781

	
782 782
    typedef ExtendFindEnum<IntIntMap> TreeSet;
783 783

	
784 784
    IntIntMap *_tree_set_index;
785 785
    TreeSet *_tree_set;
786 786

	
787 787
    IntNodeMap *_delta1_index;
788 788
    BinHeap<Value, IntNodeMap> *_delta1;
789 789

	
790 790
    IntIntMap *_delta2_index;
791 791
    BinHeap<Value, IntIntMap> *_delta2;
792 792

	
793 793
    IntEdgeMap *_delta3_index;
794 794
    BinHeap<Value, IntEdgeMap> *_delta3;
795 795

	
796 796
    IntIntMap *_delta4_index;
797 797
    BinHeap<Value, IntIntMap> *_delta4;
798 798

	
799 799
    Value _delta_sum;
800 800

	
801 801
    void createStructures() {
802 802
      _node_num = countNodes(_graph);
803 803
      _blossom_num = _node_num * 3 / 2;
804 804

	
805 805
      if (!_matching) {
806 806
        _matching = new MatchingMap(_graph);
807 807
      }
808

	
808 809
      if (!_node_potential) {
809 810
        _node_potential = new NodePotential(_graph);
810 811
      }
812

	
811 813
      if (!_blossom_set) {
812 814
        _blossom_index = new IntNodeMap(_graph);
813 815
        _blossom_set = new BlossomSet(*_blossom_index);
814 816
        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
817
      } else if (_blossom_data->size() != _blossom_num) {
818
        delete _blossom_data;
819
        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
815 820
      }
816 821

	
817 822
      if (!_node_index) {
818 823
        _node_index = new IntNodeMap(_graph);
819 824
        _node_heap_index = new IntArcMap(_graph);
820 825
        _node_data = new RangeMap<NodeData>(_node_num,
821 826
                                              NodeData(*_node_heap_index));
827
      } else {
828
        delete _node_data;
829
        _node_data = new RangeMap<NodeData>(_node_num,
830
                                            NodeData(*_node_heap_index));
822 831
      }
823 832

	
824 833
      if (!_tree_set) {
825 834
        _tree_set_index = new IntIntMap(_blossom_num);
826 835
        _tree_set = new TreeSet(*_tree_set_index);
827
      }
836
      } else {
837
        _tree_set_index->resize(_blossom_num);
838
      }
839

	
828 840
      if (!_delta1) {
829 841
        _delta1_index = new IntNodeMap(_graph);
830 842
        _delta1 = new BinHeap<Value, IntNodeMap>(*_delta1_index);
831 843
      }
844

	
832 845
      if (!_delta2) {
833 846
        _delta2_index = new IntIntMap(_blossom_num);
834 847
        _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
835
      }
848
      } else {
849
        _delta2_index->resize(_blossom_num);
850
      }
851

	
836 852
      if (!_delta3) {
837 853
        _delta3_index = new IntEdgeMap(_graph);
838 854
        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
839 855
      }
856

	
840 857
      if (!_delta4) {
841 858
        _delta4_index = new IntIntMap(_blossom_num);
842 859
        _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
860
      } else {
861
        _delta4_index->resize(_blossom_num);
843 862
      }
844 863
    }
845 864

	
846 865
    void destroyStructures() {
847 866
      _node_num = countNodes(_graph);
848 867
      _blossom_num = _node_num * 3 / 2;
849 868

	
850 869
      if (_matching) {
851 870
        delete _matching;
852 871
      }
853 872
      if (_node_potential) {
854 873
        delete _node_potential;
855 874
      }
856 875
      if (_blossom_set) {
857 876
        delete _blossom_index;
858 877
        delete _blossom_set;
859 878
        delete _blossom_data;
860 879
      }
861 880

	
862 881
      if (_node_index) {
863 882
        delete _node_index;
864 883
        delete _node_heap_index;
865 884
        delete _node_data;
866 885
      }
867 886

	
868 887
      if (_tree_set) {
869 888
        delete _tree_set_index;
870 889
        delete _tree_set;
871 890
      }
872 891
      if (_delta1) {
873 892
        delete _delta1_index;
874 893
        delete _delta1;
875 894
      }
876 895
      if (_delta2) {
877 896
        delete _delta2_index;
878 897
        delete _delta2;
879 898
      }
880 899
      if (_delta3) {
881 900
        delete _delta3_index;
882 901
        delete _delta3;
883 902
      }
884 903
      if (_delta4) {
885 904
        delete _delta4_index;
886 905
        delete _delta4;
887 906
      }
888 907
    }
889 908

	
890 909
    void matchedToEven(int blossom, int tree) {
891 910
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
892 911
        _delta2->erase(blossom);
893 912
      }
894 913

	
895 914
      if (!_blossom_set->trivial(blossom)) {
896 915
        (*_blossom_data)[blossom].pot -=
897 916
          2 * (_delta_sum - (*_blossom_data)[blossom].offset);
898 917
      }
899 918

	
900 919
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
901 920
           n != INVALID; ++n) {
902 921

	
903 922
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
904 923
        int ni = (*_node_index)[n];
905 924

	
906 925
        (*_node_data)[ni].heap.clear();
907 926
        (*_node_data)[ni].heap_index.clear();
908 927

	
909 928
        (*_node_data)[ni].pot += _delta_sum - (*_blossom_data)[blossom].offset;
910 929

	
911 930
        _delta1->push(n, (*_node_data)[ni].pot);
912 931

	
913 932
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
914 933
          Node v = _graph.source(e);
915 934
          int vb = _blossom_set->find(v);
916 935
          int vi = (*_node_index)[v];
917 936

	
918 937
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
919 938
            dualScale * _weight[e];
920 939

	
921 940
          if ((*_blossom_data)[vb].status == EVEN) {
922 941
            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
923 942
              _delta3->push(e, rw / 2);
924 943
            }
925 944
          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
926 945
            if (_delta3->state(e) != _delta3->IN_HEAP) {
927 946
              _delta3->push(e, rw);
928 947
            }
929 948
          } else {
930 949
            typename std::map<int, Arc>::iterator it =
931 950
              (*_node_data)[vi].heap_index.find(tree);
932 951

	
933 952
            if (it != (*_node_data)[vi].heap_index.end()) {
934 953
              if ((*_node_data)[vi].heap[it->second] > rw) {
935 954
                (*_node_data)[vi].heap.replace(it->second, e);
936 955
                (*_node_data)[vi].heap.decrease(e, rw);
937 956
                it->second = e;
938 957
              }
939 958
            } else {
940 959
              (*_node_data)[vi].heap.push(e, rw);
941 960
              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
942 961
            }
943 962

	
944 963
            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
945 964
              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
946 965

	
947 966
              if ((*_blossom_data)[vb].status == MATCHED) {
948 967
                if (_delta2->state(vb) != _delta2->IN_HEAP) {
949 968
                  _delta2->push(vb, _blossom_set->classPrio(vb) -
950 969
                               (*_blossom_data)[vb].offset);
951 970
                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
952 971
                           (*_blossom_data)[vb].offset){
953 972
                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
954 973
                                   (*_blossom_data)[vb].offset);
955 974
                }
956 975
              }
957 976
            }
958 977
          }
959 978
        }
960 979
      }
961 980
      (*_blossom_data)[blossom].offset = 0;
962 981
    }
963 982

	
964 983
    void matchedToOdd(int blossom) {
965 984
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
966 985
        _delta2->erase(blossom);
967 986
      }
968 987
      (*_blossom_data)[blossom].offset += _delta_sum;
969 988
      if (!_blossom_set->trivial(blossom)) {
970 989
        _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
971 990
                     (*_blossom_data)[blossom].offset);
972 991
      }
973 992
    }
974 993

	
975 994
    void evenToMatched(int blossom, int tree) {
976 995
      if (!_blossom_set->trivial(blossom)) {
977 996
        (*_blossom_data)[blossom].pot += 2 * _delta_sum;
978 997
      }
979 998

	
980 999
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
981 1000
           n != INVALID; ++n) {
982 1001
        int ni = (*_node_index)[n];
983 1002
        (*_node_data)[ni].pot -= _delta_sum;
984 1003

	
985 1004
        _delta1->erase(n);
986 1005

	
987 1006
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
988 1007
          Node v = _graph.source(e);
989 1008
          int vb = _blossom_set->find(v);
990 1009
          int vi = (*_node_index)[v];
991 1010

	
992 1011
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
993 1012
            dualScale * _weight[e];
994 1013

	
995 1014
          if (vb == blossom) {
996 1015
            if (_delta3->state(e) == _delta3->IN_HEAP) {
997 1016
              _delta3->erase(e);
998 1017
            }
999 1018
          } else if ((*_blossom_data)[vb].status == EVEN) {
1000 1019

	
1001 1020
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1002 1021
              _delta3->erase(e);
1003 1022
            }
1004 1023

	
1005 1024
            int vt = _tree_set->find(vb);
1006 1025

	
1007 1026
            if (vt != tree) {
1008 1027

	
1009 1028
              Arc r = _graph.oppositeArc(e);
1010 1029

	
1011 1030
              typename std::map<int, Arc>::iterator it =
1012 1031
                (*_node_data)[ni].heap_index.find(vt);
1013 1032

	
1014 1033
              if (it != (*_node_data)[ni].heap_index.end()) {
1015 1034
                if ((*_node_data)[ni].heap[it->second] > rw) {
1016 1035
                  (*_node_data)[ni].heap.replace(it->second, r);
1017 1036
                  (*_node_data)[ni].heap.decrease(r, rw);
1018 1037
                  it->second = r;
1019 1038
                }
1020 1039
              } else {
1021 1040
                (*_node_data)[ni].heap.push(r, rw);
1022 1041
                (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
1023 1042
              }
1024 1043

	
1025 1044
              if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
1026 1045
                _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
1027 1046

	
1028 1047
                if (_delta2->state(blossom) != _delta2->IN_HEAP) {
1029 1048
                  _delta2->push(blossom, _blossom_set->classPrio(blossom) -
1030 1049
                               (*_blossom_data)[blossom].offset);
1031 1050
                } else if ((*_delta2)[blossom] >
1032 1051
                           _blossom_set->classPrio(blossom) -
1033 1052
                           (*_blossom_data)[blossom].offset){
1034 1053
                  _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
... ...
@@ -1496,408 +1515,420 @@
1496 1515
      int ib = -1, id = -1;
1497 1516
      for (int i = 0; i < int(subblossoms.size()); ++i) {
1498 1517
        if (subblossoms[i] == b) ib = i;
1499 1518
        if (subblossoms[i] == d) id = i;
1500 1519

	
1501 1520
        (*_blossom_data)[subblossoms[i]].offset = offset;
1502 1521
        if (!_blossom_set->trivial(subblossoms[i])) {
1503 1522
          (*_blossom_data)[subblossoms[i]].pot -= 2 * offset;
1504 1523
        }
1505 1524
        if (_blossom_set->classPrio(subblossoms[i]) !=
1506 1525
            std::numeric_limits<Value>::max()) {
1507 1526
          _delta2->push(subblossoms[i],
1508 1527
                        _blossom_set->classPrio(subblossoms[i]) -
1509 1528
                        (*_blossom_data)[subblossoms[i]].offset);
1510 1529
        }
1511 1530
      }
1512 1531

	
1513 1532
      if (id > ib ? ((id - ib) % 2 == 0) : ((ib - id) % 2 == 1)) {
1514 1533
        for (int i = (id + 1) % subblossoms.size();
1515 1534
             i != ib; i = (i + 2) % subblossoms.size()) {
1516 1535
          int sb = subblossoms[i];
1517 1536
          int tb = subblossoms[(i + 1) % subblossoms.size()];
1518 1537
          (*_blossom_data)[sb].next =
1519 1538
            _graph.oppositeArc((*_blossom_data)[tb].next);
1520 1539
        }
1521 1540

	
1522 1541
        for (int i = ib; i != id; i = (i + 2) % subblossoms.size()) {
1523 1542
          int sb = subblossoms[i];
1524 1543
          int tb = subblossoms[(i + 1) % subblossoms.size()];
1525 1544
          int ub = subblossoms[(i + 2) % subblossoms.size()];
1526 1545

	
1527 1546
          (*_blossom_data)[sb].status = ODD;
1528 1547
          matchedToOdd(sb);
1529 1548
          _tree_set->insert(sb, tree);
1530 1549
          (*_blossom_data)[sb].pred = pred;
1531 1550
          (*_blossom_data)[sb].next =
1532 1551
                           _graph.oppositeArc((*_blossom_data)[tb].next);
1533 1552

	
1534 1553
          pred = (*_blossom_data)[ub].next;
1535 1554

	
1536 1555
          (*_blossom_data)[tb].status = EVEN;
1537 1556
          matchedToEven(tb, tree);
1538 1557
          _tree_set->insert(tb, tree);
1539 1558
          (*_blossom_data)[tb].pred = (*_blossom_data)[tb].next;
1540 1559
        }
1541 1560

	
1542 1561
        (*_blossom_data)[subblossoms[id]].status = ODD;
1543 1562
        matchedToOdd(subblossoms[id]);
1544 1563
        _tree_set->insert(subblossoms[id], tree);
1545 1564
        (*_blossom_data)[subblossoms[id]].next = next;
1546 1565
        (*_blossom_data)[subblossoms[id]].pred = pred;
1547 1566

	
1548 1567
      } else {
1549 1568

	
1550 1569
        for (int i = (ib + 1) % subblossoms.size();
1551 1570
             i != id; i = (i + 2) % subblossoms.size()) {
1552 1571
          int sb = subblossoms[i];
1553 1572
          int tb = subblossoms[(i + 1) % subblossoms.size()];
1554 1573
          (*_blossom_data)[sb].next =
1555 1574
            _graph.oppositeArc((*_blossom_data)[tb].next);
1556 1575
        }
1557 1576

	
1558 1577
        for (int i = id; i != ib; i = (i + 2) % subblossoms.size()) {
1559 1578
          int sb = subblossoms[i];
1560 1579
          int tb = subblossoms[(i + 1) % subblossoms.size()];
1561 1580
          int ub = subblossoms[(i + 2) % subblossoms.size()];
1562 1581

	
1563 1582
          (*_blossom_data)[sb].status = ODD;
1564 1583
          matchedToOdd(sb);
1565 1584
          _tree_set->insert(sb, tree);
1566 1585
          (*_blossom_data)[sb].next = next;
1567 1586
          (*_blossom_data)[sb].pred =
1568 1587
            _graph.oppositeArc((*_blossom_data)[tb].next);
1569 1588

	
1570 1589
          (*_blossom_data)[tb].status = EVEN;
1571 1590
          matchedToEven(tb, tree);
1572 1591
          _tree_set->insert(tb, tree);
1573 1592
          (*_blossom_data)[tb].pred =
1574 1593
            (*_blossom_data)[tb].next =
1575 1594
            _graph.oppositeArc((*_blossom_data)[ub].next);
1576 1595
          next = (*_blossom_data)[ub].next;
1577 1596
        }
1578 1597

	
1579 1598
        (*_blossom_data)[subblossoms[ib]].status = ODD;
1580 1599
        matchedToOdd(subblossoms[ib]);
1581 1600
        _tree_set->insert(subblossoms[ib], tree);
1582 1601
        (*_blossom_data)[subblossoms[ib]].next = next;
1583 1602
        (*_blossom_data)[subblossoms[ib]].pred = pred;
1584 1603
      }
1585 1604
      _tree_set->erase(blossom);
1586 1605
    }
1587 1606

	
1588 1607
    void extractBlossom(int blossom, const Node& base, const Arc& matching) {
1589 1608
      if (_blossom_set->trivial(blossom)) {
1590 1609
        int bi = (*_node_index)[base];
1591 1610
        Value pot = (*_node_data)[bi].pot;
1592 1611

	
1593 1612
        (*_matching)[base] = matching;
1594 1613
        _blossom_node_list.push_back(base);
1595 1614
        (*_node_potential)[base] = pot;
1596 1615
      } else {
1597 1616

	
1598 1617
        Value pot = (*_blossom_data)[blossom].pot;
1599 1618
        int bn = _blossom_node_list.size();
1600 1619

	
1601 1620
        std::vector<int> subblossoms;
1602 1621
        _blossom_set->split(blossom, std::back_inserter(subblossoms));
1603 1622
        int b = _blossom_set->find(base);
1604 1623
        int ib = -1;
1605 1624
        for (int i = 0; i < int(subblossoms.size()); ++i) {
1606 1625
          if (subblossoms[i] == b) { ib = i; break; }
1607 1626
        }
1608 1627

	
1609 1628
        for (int i = 1; i < int(subblossoms.size()); i += 2) {
1610 1629
          int sb = subblossoms[(ib + i) % subblossoms.size()];
1611 1630
          int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
1612 1631

	
1613 1632
          Arc m = (*_blossom_data)[tb].next;
1614 1633
          extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
1615 1634
          extractBlossom(tb, _graph.source(m), m);
1616 1635
        }
1617 1636
        extractBlossom(subblossoms[ib], base, matching);
1618 1637

	
1619 1638
        int en = _blossom_node_list.size();
1620 1639

	
1621 1640
        _blossom_potential.push_back(BlossomVariable(bn, en, pot));
1622 1641
      }
1623 1642
    }
1624 1643

	
1625 1644
    void extractMatching() {
1626 1645
      std::vector<int> blossoms;
1627 1646
      for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
1628 1647
        blossoms.push_back(c);
1629 1648
      }
1630 1649

	
1631 1650
      for (int i = 0; i < int(blossoms.size()); ++i) {
1632 1651
        if ((*_blossom_data)[blossoms[i]].status == MATCHED) {
1633 1652

	
1634 1653
          Value offset = (*_blossom_data)[blossoms[i]].offset;
1635 1654
          (*_blossom_data)[blossoms[i]].pot += 2 * offset;
1636 1655
          for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
1637 1656
               n != INVALID; ++n) {
1638 1657
            (*_node_data)[(*_node_index)[n]].pot -= offset;
1639 1658
          }
1640 1659

	
1641 1660
          Arc matching = (*_blossom_data)[blossoms[i]].next;
1642 1661
          Node base = _graph.source(matching);
1643 1662
          extractBlossom(blossoms[i], base, matching);
1644 1663
        } else {
1645 1664
          Node base = (*_blossom_data)[blossoms[i]].base;
1646 1665
          extractBlossom(blossoms[i], base, INVALID);
1647 1666
        }
1648 1667
      }
1649 1668
    }
1650 1669

	
1651 1670
  public:
1652 1671

	
1653 1672
    /// \brief Constructor
1654 1673
    ///
1655 1674
    /// Constructor.
1656 1675
    MaxWeightedMatching(const Graph& graph, const WeightMap& weight)
1657 1676
      : _graph(graph), _weight(weight), _matching(0),
1658 1677
        _node_potential(0), _blossom_potential(), _blossom_node_list(),
1659 1678
        _node_num(0), _blossom_num(0),
1660 1679

	
1661 1680
        _blossom_index(0), _blossom_set(0), _blossom_data(0),
1662 1681
        _node_index(0), _node_heap_index(0), _node_data(0),
1663 1682
        _tree_set_index(0), _tree_set(0),
1664 1683

	
1665 1684
        _delta1_index(0), _delta1(0),
1666 1685
        _delta2_index(0), _delta2(0),
1667 1686
        _delta3_index(0), _delta3(0),
1668 1687
        _delta4_index(0), _delta4(0),
1669 1688

	
1670 1689
        _delta_sum() {}
1671 1690

	
1672 1691
    ~MaxWeightedMatching() {
1673 1692
      destroyStructures();
1674 1693
    }
1675 1694

	
1676 1695
    /// \name Execution Control
1677 1696
    /// The simplest way to execute the algorithm is to use the
1678 1697
    /// \ref run() member function.
1679 1698

	
1680 1699
    ///@{
1681 1700

	
1682 1701
    /// \brief Initialize the algorithm
1683 1702
    ///
1684 1703
    /// This function initializes the algorithm.
1685 1704
    void init() {
1686 1705
      createStructures();
1687 1706

	
1707
      _blossom_node_list.clear();
1708
      _blossom_potential.clear();
1709

	
1688 1710
      for (ArcIt e(_graph); e != INVALID; ++e) {
1689 1711
        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
1690 1712
      }
1691 1713
      for (NodeIt n(_graph); n != INVALID; ++n) {
1692 1714
        (*_delta1_index)[n] = _delta1->PRE_HEAP;
1693 1715
      }
1694 1716
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1695 1717
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
1696 1718
      }
1697 1719
      for (int i = 0; i < _blossom_num; ++i) {
1698 1720
        (*_delta2_index)[i] = _delta2->PRE_HEAP;
1699 1721
        (*_delta4_index)[i] = _delta4->PRE_HEAP;
1700 1722
      }
1701 1723

	
1724
      _delta1->clear();
1725
      _delta2->clear();
1726
      _delta3->clear();
1727
      _delta4->clear();
1728
      _blossom_set->clear();
1729
      _tree_set->clear();
1730

	
1702 1731
      int index = 0;
1703 1732
      for (NodeIt n(_graph); n != INVALID; ++n) {
1704 1733
        Value max = 0;
1705 1734
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
1706 1735
          if (_graph.target(e) == n) continue;
1707 1736
          if ((dualScale * _weight[e]) / 2 > max) {
1708 1737
            max = (dualScale * _weight[e]) / 2;
1709 1738
          }
1710 1739
        }
1711 1740
        (*_node_index)[n] = index;
1741
        (*_node_data)[index].heap_index.clear();
1742
        (*_node_data)[index].heap.clear();
1712 1743
        (*_node_data)[index].pot = max;
1713 1744
        _delta1->push(n, max);
1714 1745
        int blossom =
1715 1746
          _blossom_set->insert(n, std::numeric_limits<Value>::max());
1716 1747

	
1717 1748
        _tree_set->insert(blossom);
1718 1749

	
1719 1750
        (*_blossom_data)[blossom].status = EVEN;
1720 1751
        (*_blossom_data)[blossom].pred = INVALID;
1721 1752
        (*_blossom_data)[blossom].next = INVALID;
1722 1753
        (*_blossom_data)[blossom].pot = 0;
1723 1754
        (*_blossom_data)[blossom].offset = 0;
1724 1755
        ++index;
1725 1756
      }
1726 1757
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1727 1758
        int si = (*_node_index)[_graph.u(e)];
1728 1759
        int ti = (*_node_index)[_graph.v(e)];
1729 1760
        if (_graph.u(e) != _graph.v(e)) {
1730 1761
          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
1731 1762
                            dualScale * _weight[e]) / 2);
1732 1763
        }
1733 1764
      }
1734 1765
    }
1735 1766

	
1736 1767
    /// \brief Start the algorithm
1737 1768
    ///
1738 1769
    /// This function starts the algorithm.
1739 1770
    ///
1740 1771
    /// \pre \ref init() must be called before using this function.
1741 1772
    void start() {
1742 1773
      enum OpType {
1743 1774
        D1, D2, D3, D4
1744 1775
      };
1745 1776

	
1746 1777
      int unmatched = _node_num;
1747 1778
      while (unmatched > 0) {
1748 1779
        Value d1 = !_delta1->empty() ?
1749 1780
          _delta1->prio() : std::numeric_limits<Value>::max();
1750 1781

	
1751 1782
        Value d2 = !_delta2->empty() ?
1752 1783
          _delta2->prio() : std::numeric_limits<Value>::max();
1753 1784

	
1754 1785
        Value d3 = !_delta3->empty() ?
1755 1786
          _delta3->prio() : std::numeric_limits<Value>::max();
1756 1787

	
1757 1788
        Value d4 = !_delta4->empty() ?
1758 1789
          _delta4->prio() : std::numeric_limits<Value>::max();
1759 1790

	
1760 1791
        _delta_sum = d1; OpType ot = D1;
1761 1792
        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
1762 1793
        if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
1763 1794
        if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
1764 1795

	
1765 1796

	
1766 1797
        switch (ot) {
1767 1798
        case D1:
1768 1799
          {
1769 1800
            Node n = _delta1->top();
1770 1801
            unmatchNode(n);
1771 1802
            --unmatched;
1772 1803
          }
1773 1804
          break;
1774 1805
        case D2:
1775 1806
          {
1776 1807
            int blossom = _delta2->top();
1777 1808
            Node n = _blossom_set->classTop(blossom);
1778 1809
            Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
1779 1810
            extendOnArc(e);
1780 1811
          }
1781 1812
          break;
1782 1813
        case D3:
1783 1814
          {
1784 1815
            Edge e = _delta3->top();
1785 1816

	
1786 1817
            int left_blossom = _blossom_set->find(_graph.u(e));
1787 1818
            int right_blossom = _blossom_set->find(_graph.v(e));
1788 1819

	
1789 1820
            if (left_blossom == right_blossom) {
1790 1821
              _delta3->pop();
1791 1822
            } else {
1792 1823
              int left_tree;
1793 1824
              if ((*_blossom_data)[left_blossom].status == EVEN) {
1794 1825
                left_tree = _tree_set->find(left_blossom);
1795 1826
              } else {
1796 1827
                left_tree = -1;
1797 1828
                ++unmatched;
1798 1829
              }
1799 1830
              int right_tree;
1800 1831
              if ((*_blossom_data)[right_blossom].status == EVEN) {
1801 1832
                right_tree = _tree_set->find(right_blossom);
1802 1833
              } else {
1803 1834
                right_tree = -1;
1804 1835
                ++unmatched;
1805 1836
              }
1806 1837

	
1807 1838
              if (left_tree == right_tree) {
1808 1839
                shrinkOnEdge(e, left_tree);
1809 1840
              } else {
1810 1841
                augmentOnEdge(e);
1811 1842
                unmatched -= 2;
1812 1843
              }
1813 1844
            }
1814 1845
          } break;
1815 1846
        case D4:
1816 1847
          splitBlossom(_delta4->top());
1817 1848
          break;
1818 1849
        }
1819 1850
      }
1820 1851
      extractMatching();
1821 1852
    }
1822 1853

	
1823 1854
    /// \brief Run the algorithm.
1824 1855
    ///
1825 1856
    /// This method runs the \c %MaxWeightedMatching algorithm.
1826 1857
    ///
1827 1858
    /// \note mwm.run() is just a shortcut of the following code.
1828 1859
    /// \code
1829 1860
    ///   mwm.init();
1830 1861
    ///   mwm.start();
1831 1862
    /// \endcode
1832 1863
    void run() {
1833 1864
      init();
1834 1865
      start();
1835 1866
    }
1836 1867

	
1837 1868
    /// @}
1838 1869

	
1839 1870
    /// \name Primal Solution
1840 1871
    /// Functions to get the primal solution, i.e. the maximum weighted 
1841 1872
    /// matching.\n
1842 1873
    /// Either \ref run() or \ref start() function should be called before
1843 1874
    /// using them.
1844 1875

	
1845 1876
    /// @{
1846 1877

	
1847 1878
    /// \brief Return the weight of the matching.
1848 1879
    ///
1849 1880
    /// This function returns the weight of the found matching.
1850 1881
    ///
1851 1882
    /// \pre Either run() or start() must be called before using this function.
1852 1883
    Value matchingWeight() const {
1853 1884
      Value sum = 0;
1854 1885
      for (NodeIt n(_graph); n != INVALID; ++n) {
1855 1886
        if ((*_matching)[n] != INVALID) {
1856 1887
          sum += _weight[(*_matching)[n]];
1857 1888
        }
1858 1889
      }
1859 1890
      return sum /= 2;
1860 1891
    }
1861 1892

	
1862 1893
    /// \brief Return the size (cardinality) of the matching.
1863 1894
    ///
1864 1895
    /// This function returns the size (cardinality) of the found matching.
1865 1896
    ///
1866 1897
    /// \pre Either run() or start() must be called before using this function.
1867 1898
    int matchingSize() const {
1868 1899
      int num = 0;
1869 1900
      for (NodeIt n(_graph); n != INVALID; ++n) {
1870 1901
        if ((*_matching)[n] != INVALID) {
1871 1902
          ++num;
1872 1903
        }
1873 1904
      }
1874 1905
      return num /= 2;
1875 1906
    }
1876 1907

	
1877 1908
    /// \brief Return \c true if the given edge is in the matching.
1878 1909
    ///
1879 1910
    /// This function returns \c true if the given edge is in the found 
1880 1911
    /// matching.
1881 1912
    ///
1882 1913
    /// \pre Either run() or start() must be called before using this function.
1883 1914
    bool matching(const Edge& edge) const {
1884 1915
      return edge == (*_matching)[_graph.u(edge)];
1885 1916
    }
1886 1917

	
1887 1918
    /// \brief Return the matching arc (or edge) incident to the given node.
1888 1919
    ///
1889 1920
    /// This function returns the matching arc (or edge) incident to the
1890 1921
    /// given node in the found matching or \c INVALID if the node is 
1891 1922
    /// not covered by the matching.
1892 1923
    ///
1893 1924
    /// \pre Either run() or start() must be called before using this function.
1894 1925
    Arc matching(const Node& node) const {
1895 1926
      return (*_matching)[node];
1896 1927
    }
1897 1928

	
1898 1929
    /// \brief Return a const reference to the matching map.
1899 1930
    ///
1900 1931
    /// This function returns a const reference to a node map that stores
1901 1932
    /// the matching arc (or edge) incident to each node.
1902 1933
    const MatchingMap& matchingMap() const {
1903 1934
      return *_matching;
... ...
@@ -2009,415 +2040,433 @@
2009 2040
        return _algorithm->_blossom_node_list[_index];
2010 2041
      }
2011 2042

	
2012 2043
      /// \brief Increment operator.
2013 2044
      ///
2014 2045
      /// Increment operator.
2015 2046
      BlossomIt& operator++() {
2016 2047
        ++_index;
2017 2048
        return *this;
2018 2049
      }
2019 2050

	
2020 2051
      /// \brief Validity checking
2021 2052
      ///
2022 2053
      /// Checks whether the iterator is invalid.
2023 2054
      bool operator==(Invalid) const { return _index == _last; }
2024 2055

	
2025 2056
      /// \brief Validity checking
2026 2057
      ///
2027 2058
      /// Checks whether the iterator is valid.
2028 2059
      bool operator!=(Invalid) const { return _index != _last; }
2029 2060

	
2030 2061
    private:
2031 2062
      const MaxWeightedMatching* _algorithm;
2032 2063
      int _last;
2033 2064
      int _index;
2034 2065
    };
2035 2066

	
2036 2067
    /// @}
2037 2068

	
2038 2069
  };
2039 2070

	
2040 2071
  /// \ingroup matching
2041 2072
  ///
2042 2073
  /// \brief Weighted perfect matching in general graphs
2043 2074
  ///
2044 2075
  /// This class provides an efficient implementation of Edmond's
2045 2076
  /// maximum weighted perfect matching algorithm. The implementation
2046 2077
  /// is based on extensive use of priority queues and provides
2047 2078
  /// \f$O(nm\log n)\f$ time complexity.
2048 2079
  ///
2049 2080
  /// The maximum weighted perfect matching problem is to find a subset of 
2050 2081
  /// the edges in an undirected graph with maximum overall weight for which 
2051 2082
  /// each node has exactly one incident edge.
2052 2083
  /// It can be formulated with the following linear program.
2053 2084
  /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\f]
2054 2085
  /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2}
2055 2086
      \quad \forall B\in\mathcal{O}\f] */
2056 2087
  /// \f[x_e \ge 0\quad \forall e\in E\f]
2057 2088
  /// \f[\max \sum_{e\in E}x_ew_e\f]
2058 2089
  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
2059 2090
  /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in
2060 2091
  /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality
2061 2092
  /// subsets of the nodes.
2062 2093
  ///
2063 2094
  /// The algorithm calculates an optimal matching and a proof of the
2064 2095
  /// optimality. The solution of the dual problem can be used to check
2065 2096
  /// the result of the algorithm. The dual linear problem is the
2066 2097
  /// following.
2067 2098
  /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)}z_B \ge
2068 2099
      w_{uv} \quad \forall uv\in E\f] */
2069 2100
  /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f]
2070 2101
  /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
2071 2102
      \frac{\vert B \vert - 1}{2}z_B\f] */
2072 2103
  ///
2073 2104
  /// The algorithm can be executed with the run() function. 
2074 2105
  /// After it the matching (the primal solution) and the dual solution
2075 2106
  /// can be obtained using the query functions and the 
2076 2107
  /// \ref MaxWeightedPerfectMatching::BlossomIt "BlossomIt" nested class, 
2077 2108
  /// which is able to iterate on the nodes of a blossom. 
2078 2109
  /// If the value type is integer, then the dual solution is multiplied
2079 2110
  /// by \ref MaxWeightedMatching::dualScale "4".
2080 2111
  ///
2081 2112
  /// \tparam GR The undirected graph type the algorithm runs on.
2082 2113
  /// \tparam WM The type edge weight map. The default type is 
2083 2114
  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
2084 2115
#ifdef DOXYGEN
2085 2116
  template <typename GR, typename WM>
2086 2117
#else
2087 2118
  template <typename GR,
2088 2119
            typename WM = typename GR::template EdgeMap<int> >
2089 2120
#endif
2090 2121
  class MaxWeightedPerfectMatching {
2091 2122
  public:
2092 2123

	
2093 2124
    /// The graph type of the algorithm
2094 2125
    typedef GR Graph;
2095 2126
    /// The type of the edge weight map
2096 2127
    typedef WM WeightMap;
2097 2128
    /// The value type of the edge weights
2098 2129
    typedef typename WeightMap::Value Value;
2099 2130

	
2100 2131
    /// \brief Scaling factor for dual solution
2101 2132
    ///
2102 2133
    /// Scaling factor for dual solution, it is equal to 4 or 1
2103 2134
    /// according to the value type.
2104 2135
    static const int dualScale =
2105 2136
      std::numeric_limits<Value>::is_integer ? 4 : 1;
2106 2137

	
2107 2138
    /// The type of the matching map
2108 2139
    typedef typename Graph::template NodeMap<typename Graph::Arc>
2109 2140
    MatchingMap;
2110 2141

	
2111 2142
  private:
2112 2143

	
2113 2144
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
2114 2145

	
2115 2146
    typedef typename Graph::template NodeMap<Value> NodePotential;
2116 2147
    typedef std::vector<Node> BlossomNodeList;
2117 2148

	
2118 2149
    struct BlossomVariable {
2119 2150
      int begin, end;
2120 2151
      Value value;
2121 2152

	
2122 2153
      BlossomVariable(int _begin, int _end, Value _value)
2123 2154
        : begin(_begin), end(_end), value(_value) {}
2124 2155

	
2125 2156
    };
2126 2157

	
2127 2158
    typedef std::vector<BlossomVariable> BlossomPotential;
2128 2159

	
2129 2160
    const Graph& _graph;
2130 2161
    const WeightMap& _weight;
2131 2162

	
2132 2163
    MatchingMap* _matching;
2133 2164

	
2134 2165
    NodePotential* _node_potential;
2135 2166

	
2136 2167
    BlossomPotential _blossom_potential;
2137 2168
    BlossomNodeList _blossom_node_list;
2138 2169

	
2139 2170
    int _node_num;
2140 2171
    int _blossom_num;
2141 2172

	
2142 2173
    typedef RangeMap<int> IntIntMap;
2143 2174

	
2144 2175
    enum Status {
2145 2176
      EVEN = -1, MATCHED = 0, ODD = 1
2146 2177
    };
2147 2178

	
2148 2179
    typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
2149 2180
    struct BlossomData {
2150 2181
      int tree;
2151 2182
      Status status;
2152 2183
      Arc pred, next;
2153 2184
      Value pot, offset;
2154 2185
    };
2155 2186

	
2156 2187
    IntNodeMap *_blossom_index;
2157 2188
    BlossomSet *_blossom_set;
2158 2189
    RangeMap<BlossomData>* _blossom_data;
2159 2190

	
2160 2191
    IntNodeMap *_node_index;
2161 2192
    IntArcMap *_node_heap_index;
2162 2193

	
2163 2194
    struct NodeData {
2164 2195

	
2165 2196
      NodeData(IntArcMap& node_heap_index)
2166 2197
        : heap(node_heap_index) {}
2167 2198

	
2168 2199
      int blossom;
2169 2200
      Value pot;
2170 2201
      BinHeap<Value, IntArcMap> heap;
2171 2202
      std::map<int, Arc> heap_index;
2172 2203

	
2173 2204
      int tree;
2174 2205
    };
2175 2206

	
2176 2207
    RangeMap<NodeData>* _node_data;
2177 2208

	
2178 2209
    typedef ExtendFindEnum<IntIntMap> TreeSet;
2179 2210

	
2180 2211
    IntIntMap *_tree_set_index;
2181 2212
    TreeSet *_tree_set;
2182 2213

	
2183 2214
    IntIntMap *_delta2_index;
2184 2215
    BinHeap<Value, IntIntMap> *_delta2;
2185 2216

	
2186 2217
    IntEdgeMap *_delta3_index;
2187 2218
    BinHeap<Value, IntEdgeMap> *_delta3;
2188 2219

	
2189 2220
    IntIntMap *_delta4_index;
2190 2221
    BinHeap<Value, IntIntMap> *_delta4;
2191 2222

	
2192 2223
    Value _delta_sum;
2193 2224

	
2194 2225
    void createStructures() {
2195 2226
      _node_num = countNodes(_graph);
2196 2227
      _blossom_num = _node_num * 3 / 2;
2197 2228

	
2198 2229
      if (!_matching) {
2199 2230
        _matching = new MatchingMap(_graph);
2200 2231
      }
2232

	
2201 2233
      if (!_node_potential) {
2202 2234
        _node_potential = new NodePotential(_graph);
2203 2235
      }
2236

	
2204 2237
      if (!_blossom_set) {
2205 2238
        _blossom_index = new IntNodeMap(_graph);
2206 2239
        _blossom_set = new BlossomSet(*_blossom_index);
2207 2240
        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
2241
      } else if (_blossom_data->size() != _blossom_num) {
2242
        delete _blossom_data;
2243
        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
2208 2244
      }
2209 2245

	
2210 2246
      if (!_node_index) {
2211 2247
        _node_index = new IntNodeMap(_graph);
2212 2248
        _node_heap_index = new IntArcMap(_graph);
2213 2249
        _node_data = new RangeMap<NodeData>(_node_num,
2214 2250
                                            NodeData(*_node_heap_index));
2251
      } else if (_node_data->size() != _node_num) {
2252
        delete _node_data;
2253
        _node_data = new RangeMap<NodeData>(_node_num,
2254
                                            NodeData(*_node_heap_index));
2215 2255
      }
2216 2256

	
2217 2257
      if (!_tree_set) {
2218 2258
        _tree_set_index = new IntIntMap(_blossom_num);
2219 2259
        _tree_set = new TreeSet(*_tree_set_index);
2220
      }
2260
      } else {
2261
        _tree_set_index->resize(_blossom_num);
2262
      }
2263

	
2221 2264
      if (!_delta2) {
2222 2265
        _delta2_index = new IntIntMap(_blossom_num);
2223 2266
        _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
2224
      }
2267
      } else {
2268
        _delta2_index->resize(_blossom_num);
2269
      }
2270

	
2225 2271
      if (!_delta3) {
2226 2272
        _delta3_index = new IntEdgeMap(_graph);
2227 2273
        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
2228 2274
      }
2275

	
2229 2276
      if (!_delta4) {
2230 2277
        _delta4_index = new IntIntMap(_blossom_num);
2231 2278
        _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
2279
      } else {
2280
        _delta4_index->resize(_blossom_num);
2232 2281
      }
2233 2282
    }
2234 2283

	
2235 2284
    void destroyStructures() {
2236 2285
      _node_num = countNodes(_graph);
2237 2286
      _blossom_num = _node_num * 3 / 2;
2238 2287

	
2239 2288
      if (_matching) {
2240 2289
        delete _matching;
2241 2290
      }
2242 2291
      if (_node_potential) {
2243 2292
        delete _node_potential;
2244 2293
      }
2245 2294
      if (_blossom_set) {
2246 2295
        delete _blossom_index;
2247 2296
        delete _blossom_set;
2248 2297
        delete _blossom_data;
2249 2298
      }
2250 2299

	
2251 2300
      if (_node_index) {
2252 2301
        delete _node_index;
2253 2302
        delete _node_heap_index;
2254 2303
        delete _node_data;
2255 2304
      }
2256 2305

	
2257 2306
      if (_tree_set) {
2258 2307
        delete _tree_set_index;
2259 2308
        delete _tree_set;
2260 2309
      }
2261 2310
      if (_delta2) {
2262 2311
        delete _delta2_index;
2263 2312
        delete _delta2;
2264 2313
      }
2265 2314
      if (_delta3) {
2266 2315
        delete _delta3_index;
2267 2316
        delete _delta3;
2268 2317
      }
2269 2318
      if (_delta4) {
2270 2319
        delete _delta4_index;
2271 2320
        delete _delta4;
2272 2321
      }
2273 2322
    }
2274 2323

	
2275 2324
    void matchedToEven(int blossom, int tree) {
2276 2325
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
2277 2326
        _delta2->erase(blossom);
2278 2327
      }
2279 2328

	
2280 2329
      if (!_blossom_set->trivial(blossom)) {
2281 2330
        (*_blossom_data)[blossom].pot -=
2282 2331
          2 * (_delta_sum - (*_blossom_data)[blossom].offset);
2283 2332
      }
2284 2333

	
2285 2334
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
2286 2335
           n != INVALID; ++n) {
2287 2336

	
2288 2337
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
2289 2338
        int ni = (*_node_index)[n];
2290 2339

	
2291 2340
        (*_node_data)[ni].heap.clear();
2292 2341
        (*_node_data)[ni].heap_index.clear();
2293 2342

	
2294 2343
        (*_node_data)[ni].pot += _delta_sum - (*_blossom_data)[blossom].offset;
2295 2344

	
2296 2345
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
2297 2346
          Node v = _graph.source(e);
2298 2347
          int vb = _blossom_set->find(v);
2299 2348
          int vi = (*_node_index)[v];
2300 2349

	
2301 2350
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
2302 2351
            dualScale * _weight[e];
2303 2352

	
2304 2353
          if ((*_blossom_data)[vb].status == EVEN) {
2305 2354
            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
2306 2355
              _delta3->push(e, rw / 2);
2307 2356
            }
2308 2357
          } else {
2309 2358
            typename std::map<int, Arc>::iterator it =
2310 2359
              (*_node_data)[vi].heap_index.find(tree);
2311 2360

	
2312 2361
            if (it != (*_node_data)[vi].heap_index.end()) {
2313 2362
              if ((*_node_data)[vi].heap[it->second] > rw) {
2314 2363
                (*_node_data)[vi].heap.replace(it->second, e);
2315 2364
                (*_node_data)[vi].heap.decrease(e, rw);
2316 2365
                it->second = e;
2317 2366
              }
2318 2367
            } else {
2319 2368
              (*_node_data)[vi].heap.push(e, rw);
2320 2369
              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
2321 2370
            }
2322 2371

	
2323 2372
            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
2324 2373
              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
2325 2374

	
2326 2375
              if ((*_blossom_data)[vb].status == MATCHED) {
2327 2376
                if (_delta2->state(vb) != _delta2->IN_HEAP) {
2328 2377
                  _delta2->push(vb, _blossom_set->classPrio(vb) -
2329 2378
                               (*_blossom_data)[vb].offset);
2330 2379
                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
2331 2380
                           (*_blossom_data)[vb].offset){
2332 2381
                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
2333 2382
                                   (*_blossom_data)[vb].offset);
2334 2383
                }
2335 2384
              }
2336 2385
            }
2337 2386
          }
2338 2387
        }
2339 2388
      }
2340 2389
      (*_blossom_data)[blossom].offset = 0;
2341 2390
    }
2342 2391

	
2343 2392
    void matchedToOdd(int blossom) {
2344 2393
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
2345 2394
        _delta2->erase(blossom);
2346 2395
      }
2347 2396
      (*_blossom_data)[blossom].offset += _delta_sum;
2348 2397
      if (!_blossom_set->trivial(blossom)) {
2349 2398
        _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
2350 2399
                     (*_blossom_data)[blossom].offset);
2351 2400
      }
2352 2401
    }
2353 2402

	
2354 2403
    void evenToMatched(int blossom, int tree) {
2355 2404
      if (!_blossom_set->trivial(blossom)) {
2356 2405
        (*_blossom_data)[blossom].pot += 2 * _delta_sum;
2357 2406
      }
2358 2407

	
2359 2408
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
2360 2409
           n != INVALID; ++n) {
2361 2410
        int ni = (*_node_index)[n];
2362 2411
        (*_node_data)[ni].pot -= _delta_sum;
2363 2412

	
2364 2413
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
2365 2414
          Node v = _graph.source(e);
2366 2415
          int vb = _blossom_set->find(v);
2367 2416
          int vi = (*_node_index)[v];
2368 2417

	
2369 2418
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
2370 2419
            dualScale * _weight[e];
2371 2420

	
2372 2421
          if (vb == blossom) {
2373 2422
            if (_delta3->state(e) == _delta3->IN_HEAP) {
2374 2423
              _delta3->erase(e);
2375 2424
            }
2376 2425
          } else if ((*_blossom_data)[vb].status == EVEN) {
2377 2426

	
2378 2427
            if (_delta3->state(e) == _delta3->IN_HEAP) {
2379 2428
              _delta3->erase(e);
2380 2429
            }
2381 2430

	
2382 2431
            int vt = _tree_set->find(vb);
2383 2432

	
2384 2433
            if (vt != tree) {
2385 2434

	
2386 2435
              Arc r = _graph.oppositeArc(e);
2387 2436

	
2388 2437
              typename std::map<int, Arc>::iterator it =
2389 2438
                (*_node_data)[ni].heap_index.find(vt);
2390 2439

	
2391 2440
              if (it != (*_node_data)[ni].heap_index.end()) {
2392 2441
                if ((*_node_data)[ni].heap[it->second] > rw) {
2393 2442
                  (*_node_data)[ni].heap.replace(it->second, r);
2394 2443
                  (*_node_data)[ni].heap.decrease(r, rw);
2395 2444
                  it->second = r;
2396 2445
                }
2397 2446
              } else {
2398 2447
                (*_node_data)[ni].heap.push(r, rw);
2399 2448
                (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
2400 2449
              }
2401 2450

	
2402 2451
              if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
2403 2452
                _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
2404 2453

	
2405 2454
                if (_delta2->state(blossom) != _delta2->IN_HEAP) {
2406 2455
                  _delta2->push(blossom, _blossom_set->classPrio(blossom) -
2407 2456
                               (*_blossom_data)[blossom].offset);
2408 2457
                } else if ((*_delta2)[blossom] >
2409 2458
                           _blossom_set->classPrio(blossom) -
2410 2459
                           (*_blossom_data)[blossom].offset){
2411 2460
                  _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
2412 2461
                                   (*_blossom_data)[blossom].offset);
2413 2462
                }
2414 2463
              }
2415 2464
            }
2416 2465
          } else {
2417 2466

	
2418 2467
            typename std::map<int, Arc>::iterator it =
2419 2468
              (*_node_data)[vi].heap_index.find(tree);
2420 2469

	
2421 2470
            if (it != (*_node_data)[vi].heap_index.end()) {
2422 2471
              (*_node_data)[vi].heap.erase(it->second);
2423 2472
              (*_node_data)[vi].heap_index.erase(it);
... ...
@@ -2737,405 +2786,416 @@
2737 2786
      _blossom_set->split(blossom, std::back_inserter(subblossoms));
2738 2787

	
2739 2788
      Value offset = (*_blossom_data)[blossom].offset;
2740 2789
      int b = _blossom_set->find(_graph.source(pred));
2741 2790
      int d = _blossom_set->find(_graph.source(next));
2742 2791

	
2743 2792
      int ib = -1, id = -1;
2744 2793
      for (int i = 0; i < int(subblossoms.size()); ++i) {
2745 2794
        if (subblossoms[i] == b) ib = i;
2746 2795
        if (subblossoms[i] == d) id = i;
2747 2796

	
2748 2797
        (*_blossom_data)[subblossoms[i]].offset = offset;
2749 2798
        if (!_blossom_set->trivial(subblossoms[i])) {
2750 2799
          (*_blossom_data)[subblossoms[i]].pot -= 2 * offset;
2751 2800
        }
2752 2801
        if (_blossom_set->classPrio(subblossoms[i]) !=
2753 2802
            std::numeric_limits<Value>::max()) {
2754 2803
          _delta2->push(subblossoms[i],
2755 2804
                        _blossom_set->classPrio(subblossoms[i]) -
2756 2805
                        (*_blossom_data)[subblossoms[i]].offset);
2757 2806
        }
2758 2807
      }
2759 2808

	
2760 2809
      if (id > ib ? ((id - ib) % 2 == 0) : ((ib - id) % 2 == 1)) {
2761 2810
        for (int i = (id + 1) % subblossoms.size();
2762 2811
             i != ib; i = (i + 2) % subblossoms.size()) {
2763 2812
          int sb = subblossoms[i];
2764 2813
          int tb = subblossoms[(i + 1) % subblossoms.size()];
2765 2814
          (*_blossom_data)[sb].next =
2766 2815
            _graph.oppositeArc((*_blossom_data)[tb].next);
2767 2816
        }
2768 2817

	
2769 2818
        for (int i = ib; i != id; i = (i + 2) % subblossoms.size()) {
2770 2819
          int sb = subblossoms[i];
2771 2820
          int tb = subblossoms[(i + 1) % subblossoms.size()];
2772 2821
          int ub = subblossoms[(i + 2) % subblossoms.size()];
2773 2822

	
2774 2823
          (*_blossom_data)[sb].status = ODD;
2775 2824
          matchedToOdd(sb);
2776 2825
          _tree_set->insert(sb, tree);
2777 2826
          (*_blossom_data)[sb].pred = pred;
2778 2827
          (*_blossom_data)[sb].next =
2779 2828
                           _graph.oppositeArc((*_blossom_data)[tb].next);
2780 2829

	
2781 2830
          pred = (*_blossom_data)[ub].next;
2782 2831

	
2783 2832
          (*_blossom_data)[tb].status = EVEN;
2784 2833
          matchedToEven(tb, tree);
2785 2834
          _tree_set->insert(tb, tree);
2786 2835
          (*_blossom_data)[tb].pred = (*_blossom_data)[tb].next;
2787 2836
        }
2788 2837

	
2789 2838
        (*_blossom_data)[subblossoms[id]].status = ODD;
2790 2839
        matchedToOdd(subblossoms[id]);
2791 2840
        _tree_set->insert(subblossoms[id], tree);
2792 2841
        (*_blossom_data)[subblossoms[id]].next = next;
2793 2842
        (*_blossom_data)[subblossoms[id]].pred = pred;
2794 2843

	
2795 2844
      } else {
2796 2845

	
2797 2846
        for (int i = (ib + 1) % subblossoms.size();
2798 2847
             i != id; i = (i + 2) % subblossoms.size()) {
2799 2848
          int sb = subblossoms[i];
2800 2849
          int tb = subblossoms[(i + 1) % subblossoms.size()];
2801 2850
          (*_blossom_data)[sb].next =
2802 2851
            _graph.oppositeArc((*_blossom_data)[tb].next);
2803 2852
        }
2804 2853

	
2805 2854
        for (int i = id; i != ib; i = (i + 2) % subblossoms.size()) {
2806 2855
          int sb = subblossoms[i];
2807 2856
          int tb = subblossoms[(i + 1) % subblossoms.size()];
2808 2857
          int ub = subblossoms[(i + 2) % subblossoms.size()];
2809 2858

	
2810 2859
          (*_blossom_data)[sb].status = ODD;
2811 2860
          matchedToOdd(sb);
2812 2861
          _tree_set->insert(sb, tree);
2813 2862
          (*_blossom_data)[sb].next = next;
2814 2863
          (*_blossom_data)[sb].pred =
2815 2864
            _graph.oppositeArc((*_blossom_data)[tb].next);
2816 2865

	
2817 2866
          (*_blossom_data)[tb].status = EVEN;
2818 2867
          matchedToEven(tb, tree);
2819 2868
          _tree_set->insert(tb, tree);
2820 2869
          (*_blossom_data)[tb].pred =
2821 2870
            (*_blossom_data)[tb].next =
2822 2871
            _graph.oppositeArc((*_blossom_data)[ub].next);
2823 2872
          next = (*_blossom_data)[ub].next;
2824 2873
        }
2825 2874

	
2826 2875
        (*_blossom_data)[subblossoms[ib]].status = ODD;
2827 2876
        matchedToOdd(subblossoms[ib]);
2828 2877
        _tree_set->insert(subblossoms[ib], tree);
2829 2878
        (*_blossom_data)[subblossoms[ib]].next = next;
2830 2879
        (*_blossom_data)[subblossoms[ib]].pred = pred;
2831 2880
      }
2832 2881
      _tree_set->erase(blossom);
2833 2882
    }
2834 2883

	
2835 2884
    void extractBlossom(int blossom, const Node& base, const Arc& matching) {
2836 2885
      if (_blossom_set->trivial(blossom)) {
2837 2886
        int bi = (*_node_index)[base];
2838 2887
        Value pot = (*_node_data)[bi].pot;
2839 2888

	
2840 2889
        (*_matching)[base] = matching;
2841 2890
        _blossom_node_list.push_back(base);
2842 2891
        (*_node_potential)[base] = pot;
2843 2892
      } else {
2844 2893

	
2845 2894
        Value pot = (*_blossom_data)[blossom].pot;
2846 2895
        int bn = _blossom_node_list.size();
2847 2896

	
2848 2897
        std::vector<int> subblossoms;
2849 2898
        _blossom_set->split(blossom, std::back_inserter(subblossoms));
2850 2899
        int b = _blossom_set->find(base);
2851 2900
        int ib = -1;
2852 2901
        for (int i = 0; i < int(subblossoms.size()); ++i) {
2853 2902
          if (subblossoms[i] == b) { ib = i; break; }
2854 2903
        }
2855 2904

	
2856 2905
        for (int i = 1; i < int(subblossoms.size()); i += 2) {
2857 2906
          int sb = subblossoms[(ib + i) % subblossoms.size()];
2858 2907
          int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
2859 2908

	
2860 2909
          Arc m = (*_blossom_data)[tb].next;
2861 2910
          extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
2862 2911
          extractBlossom(tb, _graph.source(m), m);
2863 2912
        }
2864 2913
        extractBlossom(subblossoms[ib], base, matching);
2865 2914

	
2866 2915
        int en = _blossom_node_list.size();
2867 2916

	
2868 2917
        _blossom_potential.push_back(BlossomVariable(bn, en, pot));
2869 2918
      }
2870 2919
    }
2871 2920

	
2872 2921
    void extractMatching() {
2873 2922
      std::vector<int> blossoms;
2874 2923
      for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
2875 2924
        blossoms.push_back(c);
2876 2925
      }
2877 2926

	
2878 2927
      for (int i = 0; i < int(blossoms.size()); ++i) {
2879 2928

	
2880 2929
        Value offset = (*_blossom_data)[blossoms[i]].offset;
2881 2930
        (*_blossom_data)[blossoms[i]].pot += 2 * offset;
2882 2931
        for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
2883 2932
             n != INVALID; ++n) {
2884 2933
          (*_node_data)[(*_node_index)[n]].pot -= offset;
2885 2934
        }
2886 2935

	
2887 2936
        Arc matching = (*_blossom_data)[blossoms[i]].next;
2888 2937
        Node base = _graph.source(matching);
2889 2938
        extractBlossom(blossoms[i], base, matching);
2890 2939
      }
2891 2940
    }
2892 2941

	
2893 2942
  public:
2894 2943

	
2895 2944
    /// \brief Constructor
2896 2945
    ///
2897 2946
    /// Constructor.
2898 2947
    MaxWeightedPerfectMatching(const Graph& graph, const WeightMap& weight)
2899 2948
      : _graph(graph), _weight(weight), _matching(0),
2900 2949
        _node_potential(0), _blossom_potential(), _blossom_node_list(),
2901 2950
        _node_num(0), _blossom_num(0),
2902 2951

	
2903 2952
        _blossom_index(0), _blossom_set(0), _blossom_data(0),
2904 2953
        _node_index(0), _node_heap_index(0), _node_data(0),
2905 2954
        _tree_set_index(0), _tree_set(0),
2906 2955

	
2907 2956
        _delta2_index(0), _delta2(0),
2908 2957
        _delta3_index(0), _delta3(0),
2909 2958
        _delta4_index(0), _delta4(0),
2910 2959

	
2911 2960
        _delta_sum() {}
2912 2961

	
2913 2962
    ~MaxWeightedPerfectMatching() {
2914 2963
      destroyStructures();
2915 2964
    }
2916 2965

	
2917 2966
    /// \name Execution Control
2918 2967
    /// The simplest way to execute the algorithm is to use the
2919 2968
    /// \ref run() member function.
2920 2969

	
2921 2970
    ///@{
2922 2971

	
2923 2972
    /// \brief Initialize the algorithm
2924 2973
    ///
2925 2974
    /// This function initializes the algorithm.
2926 2975
    void init() {
2927 2976
      createStructures();
2928 2977

	
2978
      _blossom_node_list.clear();
2979
      _blossom_potential.clear();
2980

	
2929 2981
      for (ArcIt e(_graph); e != INVALID; ++e) {
2930 2982
        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
2931 2983
      }
2932 2984
      for (EdgeIt e(_graph); e != INVALID; ++e) {
2933 2985
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
2934 2986
      }
2935 2987
      for (int i = 0; i < _blossom_num; ++i) {
2936 2988
        (*_delta2_index)[i] = _delta2->PRE_HEAP;
2937 2989
        (*_delta4_index)[i] = _delta4->PRE_HEAP;
2938 2990
      }
2939 2991

	
2992
      _delta2->clear();
2993
      _delta3->clear();
2994
      _delta4->clear();
2995
      _blossom_set->clear();
2996
      _tree_set->clear();
2997

	
2940 2998
      int index = 0;
2941 2999
      for (NodeIt n(_graph); n != INVALID; ++n) {
2942 3000
        Value max = - std::numeric_limits<Value>::max();
2943 3001
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
2944 3002
          if (_graph.target(e) == n) continue;
2945 3003
          if ((dualScale * _weight[e]) / 2 > max) {
2946 3004
            max = (dualScale * _weight[e]) / 2;
2947 3005
          }
2948 3006
        }
2949 3007
        (*_node_index)[n] = index;
3008
        (*_node_data)[index].heap_index.clear();
3009
        (*_node_data)[index].heap.clear();
2950 3010
        (*_node_data)[index].pot = max;
2951 3011
        int blossom =
2952 3012
          _blossom_set->insert(n, std::numeric_limits<Value>::max());
2953 3013

	
2954 3014
        _tree_set->insert(blossom);
2955 3015

	
2956 3016
        (*_blossom_data)[blossom].status = EVEN;
2957 3017
        (*_blossom_data)[blossom].pred = INVALID;
2958 3018
        (*_blossom_data)[blossom].next = INVALID;
2959 3019
        (*_blossom_data)[blossom].pot = 0;
2960 3020
        (*_blossom_data)[blossom].offset = 0;
2961 3021
        ++index;
2962 3022
      }
2963 3023
      for (EdgeIt e(_graph); e != INVALID; ++e) {
2964 3024
        int si = (*_node_index)[_graph.u(e)];
2965 3025
        int ti = (*_node_index)[_graph.v(e)];
2966 3026
        if (_graph.u(e) != _graph.v(e)) {
2967 3027
          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
2968 3028
                            dualScale * _weight[e]) / 2);
2969 3029
        }
2970 3030
      }
2971 3031
    }
2972 3032

	
2973 3033
    /// \brief Start the algorithm
2974 3034
    ///
2975 3035
    /// This function starts the algorithm.
2976 3036
    ///
2977 3037
    /// \pre \ref init() must be called before using this function.
2978 3038
    bool start() {
2979 3039
      enum OpType {
2980 3040
        D2, D3, D4
2981 3041
      };
2982 3042

	
2983 3043
      int unmatched = _node_num;
2984 3044
      while (unmatched > 0) {
2985 3045
        Value d2 = !_delta2->empty() ?
2986 3046
          _delta2->prio() : std::numeric_limits<Value>::max();
2987 3047

	
2988 3048
        Value d3 = !_delta3->empty() ?
2989 3049
          _delta3->prio() : std::numeric_limits<Value>::max();
2990 3050

	
2991 3051
        Value d4 = !_delta4->empty() ?
2992 3052
          _delta4->prio() : std::numeric_limits<Value>::max();
2993 3053

	
2994 3054
        _delta_sum = d2; OpType ot = D2;
2995 3055
        if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
2996 3056
        if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
2997 3057

	
2998 3058
        if (_delta_sum == std::numeric_limits<Value>::max()) {
2999 3059
          return false;
3000 3060
        }
3001 3061

	
3002 3062
        switch (ot) {
3003 3063
        case D2:
3004 3064
          {
3005 3065
            int blossom = _delta2->top();
3006 3066
            Node n = _blossom_set->classTop(blossom);
3007 3067
            Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
3008 3068
            extendOnArc(e);
3009 3069
          }
3010 3070
          break;
3011 3071
        case D3:
3012 3072
          {
3013 3073
            Edge e = _delta3->top();
3014 3074

	
3015 3075
            int left_blossom = _blossom_set->find(_graph.u(e));
3016 3076
            int right_blossom = _blossom_set->find(_graph.v(e));
3017 3077

	
3018 3078
            if (left_blossom == right_blossom) {
3019 3079
              _delta3->pop();
3020 3080
            } else {
3021 3081
              int left_tree = _tree_set->find(left_blossom);
3022 3082
              int right_tree = _tree_set->find(right_blossom);
3023 3083

	
3024 3084
              if (left_tree == right_tree) {
3025 3085
                shrinkOnEdge(e, left_tree);
3026 3086
              } else {
3027 3087
                augmentOnEdge(e);
3028 3088
                unmatched -= 2;
3029 3089
              }
3030 3090
            }
3031 3091
          } break;
3032 3092
        case D4:
3033 3093
          splitBlossom(_delta4->top());
3034 3094
          break;
3035 3095
        }
3036 3096
      }
3037 3097
      extractMatching();
3038 3098
      return true;
3039 3099
    }
3040 3100

	
3041 3101
    /// \brief Run the algorithm.
3042 3102
    ///
3043 3103
    /// This method runs the \c %MaxWeightedPerfectMatching algorithm.
3044 3104
    ///
3045 3105
    /// \note mwpm.run() is just a shortcut of the following code.
3046 3106
    /// \code
3047 3107
    ///   mwpm.init();
3048 3108
    ///   mwpm.start();
3049 3109
    /// \endcode
3050 3110
    bool run() {
3051 3111
      init();
3052 3112
      return start();
3053 3113
    }
3054 3114

	
3055 3115
    /// @}
3056 3116

	
3057 3117
    /// \name Primal Solution
3058 3118
    /// Functions to get the primal solution, i.e. the maximum weighted 
3059 3119
    /// perfect matching.\n
3060 3120
    /// Either \ref run() or \ref start() function should be called before
3061 3121
    /// using them.
3062 3122

	
3063 3123
    /// @{
3064 3124

	
3065 3125
    /// \brief Return the weight of the matching.
3066 3126
    ///
3067 3127
    /// This function returns the weight of the found matching.
3068 3128
    ///
3069 3129
    /// \pre Either run() or start() must be called before using this function.
3070 3130
    Value matchingWeight() const {
3071 3131
      Value sum = 0;
3072 3132
      for (NodeIt n(_graph); n != INVALID; ++n) {
3073 3133
        if ((*_matching)[n] != INVALID) {
3074 3134
          sum += _weight[(*_matching)[n]];
3075 3135
        }
3076 3136
      }
3077 3137
      return sum /= 2;
3078 3138
    }
3079 3139

	
3080 3140
    /// \brief Return \c true if the given edge is in the matching.
3081 3141
    ///
3082 3142
    /// This function returns \c true if the given edge is in the found 
3083 3143
    /// matching.
3084 3144
    ///
3085 3145
    /// \pre Either run() or start() must be called before using this function.
3086 3146
    bool matching(const Edge& edge) const {
3087 3147
      return static_cast<const Edge&>((*_matching)[_graph.u(edge)]) == edge;
3088 3148
    }
3089 3149

	
3090 3150
    /// \brief Return the matching arc (or edge) incident to the given node.
3091 3151
    ///
3092 3152
    /// This function returns the matching arc (or edge) incident to the
3093 3153
    /// given node in the found matching or \c INVALID if the node is 
3094 3154
    /// not covered by the matching.
3095 3155
    ///
3096 3156
    /// \pre Either run() or start() must be called before using this function.
3097 3157
    Arc matching(const Node& node) const {
3098 3158
      return (*_matching)[node];
3099 3159
    }
3100 3160

	
3101 3161
    /// \brief Return a const reference to the matching map.
3102 3162
    ///
3103 3163
    /// This function returns a const reference to a node map that stores
3104 3164
    /// the matching arc (or edge) incident to each node.
3105 3165
    const MatchingMap& matchingMap() const {
3106 3166
      return *_matching;
3107 3167
    }
3108 3168

	
3109 3169
    /// \brief Return the mate of the given node.
3110 3170
    ///
3111 3171
    /// This function returns the mate of the given node in the found 
3112 3172
    /// matching or \c INVALID if the node is not covered by the matching.
3113 3173
    ///
3114 3174
    /// \pre Either run() or start() must be called before using this function.
3115 3175
    Node mate(const Node& node) const {
3116 3176
      return _graph.target((*_matching)[node]);
3117 3177
    }
3118 3178

	
3119 3179
    /// @}
3120 3180

	
3121 3181
    /// \name Dual Solution
3122 3182
    /// Functions to get the dual solution.\n
3123 3183
    /// Either \ref run() or \ref start() function should be called before
3124 3184
    /// using them.
3125 3185

	
3126 3186
    /// @{
3127 3187

	
3128 3188
    /// \brief Return the value of the dual solution.
3129 3189
    ///
3130 3190
    /// This function returns the value of the dual solution. 
3131 3191
    /// It should be equal to the primal value scaled by \ref dualScale 
3132 3192
    /// "dual scale".
3133 3193
    ///
3134 3194
    /// \pre Either run() or start() must be called before using this function.
3135 3195
    Value dualValue() const {
3136 3196
      Value sum = 0;
3137 3197
      for (NodeIt n(_graph); n != INVALID; ++n) {
3138 3198
        sum += nodeValue(n);
3139 3199
      }
3140 3200
      for (int i = 0; i < blossomNum(); ++i) {
3141 3201
        sum += blossomValue(i) * (blossomSize(i) / 2);
Show white space 384 line context
... ...
@@ -550,385 +550,385 @@
550 550

	
551 551
    private:
552 552
      const UnionFindEnum* unionFind;
553 553
      int cdx;
554 554
    };
555 555

	
556 556
    /// \brief LEMON style iterator for the items of a component.
557 557
    ///
558 558
    /// ClassIt is a lemon style iterator for the components. It iterates
559 559
    /// on the items of a class. By example if you want to iterate on
560 560
    /// each items of each classes then you may write the next code.
561 561
    ///\code
562 562
    /// for (ClassIt cit(ufe); cit != INVALID; ++cit) {
563 563
    ///   std::cout << "Class: ";
564 564
    ///   for (ItemIt iit(ufe, cit); iit != INVALID; ++iit) {
565 565
    ///     std::cout << toString(iit) << ' ' << std::endl;
566 566
    ///   }
567 567
    ///   std::cout << std::endl;
568 568
    /// }
569 569
    ///\endcode
570 570
    class ItemIt {
571 571
    public:
572 572
      /// \brief Constructor of the iterator
573 573
      ///
574 574
      /// Constructor of the iterator. The iterator iterates
575 575
      /// on the class of the \c item.
576 576
      ItemIt(const UnionFindEnum& ufe, int cls) : unionFind(&ufe) {
577 577
        fdx = idx = unionFind->classes[cls].firstItem;
578 578
      }
579 579

	
580 580
      /// \brief Constructor to get invalid iterator
581 581
      ///
582 582
      /// Constructor to get invalid iterator
583 583
      ItemIt(Invalid) : unionFind(0), idx(-1) {}
584 584

	
585 585
      /// \brief Increment operator
586 586
      ///
587 587
      /// It steps to the next item in the class.
588 588
      ItemIt& operator++() {
589 589
        idx = unionFind->items[idx].next;
590 590
        if (idx == fdx) idx = -1;
591 591
        return *this;
592 592
      }
593 593

	
594 594
      /// \brief Conversion operator
595 595
      ///
596 596
      /// It converts the iterator to the current item.
597 597
      operator const Item&() const {
598 598
        return unionFind->items[idx].item;
599 599
      }
600 600

	
601 601
      /// \brief Equality operator
602 602
      ///
603 603
      /// Equality operator
604 604
      bool operator==(const ItemIt& i) {
605 605
        return i.idx == idx;
606 606
      }
607 607

	
608 608
      /// \brief Inequality operator
609 609
      ///
610 610
      /// Inequality operator
611 611
      bool operator!=(const ItemIt& i) {
612 612
        return i.idx != idx;
613 613
      }
614 614

	
615 615
    private:
616 616
      const UnionFindEnum* unionFind;
617 617
      int idx, fdx;
618 618
    };
619 619

	
620 620
  };
621 621

	
622 622
  /// \ingroup auxdat
623 623
  ///
624 624
  /// \brief A \e Extend-Find data structure implementation which
625 625
  /// is able to enumerate the components.
626 626
  ///
627 627
  /// The class implements an \e Extend-Find data structure which is
628 628
  /// able to enumerate the components and the items in a
629 629
  /// component. The data structure is a simplification of the
630 630
  /// Union-Find structure, and it does not allow to merge two components.
631 631
  ///
632 632
  /// \pre You need to add all the elements by the \ref insert()
633 633
  /// method.
634 634
  template <typename IM>
635 635
  class ExtendFindEnum {
636 636
  public:
637 637

	
638 638
    ///\e
639 639
    typedef IM ItemIntMap;
640 640
    ///\e
641 641
    typedef typename ItemIntMap::Key Item;
642 642

	
643 643
  private:
644 644

	
645 645
    ItemIntMap& index;
646 646

	
647 647
    struct ItemT {
648 648
      int cls;
649 649
      Item item;
650 650
      int next, prev;
651 651
    };
652 652

	
653 653
    std::vector<ItemT> items;
654 654
    int firstFreeItem;
655 655

	
656 656
    struct ClassT {
657 657
      int firstItem;
658 658
      int next, prev;
659 659
    };
660 660

	
661 661
    std::vector<ClassT> classes;
662 662

	
663 663
    int firstClass, firstFreeClass;
664 664

	
665 665
    int newClass() {
666 666
      if (firstFreeClass != -1) {
667 667
        int cdx = firstFreeClass;
668 668
        firstFreeClass = classes[cdx].next;
669 669
        return cdx;
670 670
      } else {
671 671
        classes.push_back(ClassT());
672 672
        return classes.size() - 1;
673 673
      }
674 674
    }
675 675

	
676 676
    int newItem() {
677 677
      if (firstFreeItem != -1) {
678 678
        int idx = firstFreeItem;
679 679
        firstFreeItem = items[idx].next;
680 680
        return idx;
681 681
      } else {
682 682
        items.push_back(ItemT());
683 683
        return items.size() - 1;
684 684
      }
685 685
    }
686 686

	
687 687
  public:
688 688

	
689 689
    /// \brief Constructor
690 690
    ExtendFindEnum(ItemIntMap& _index)
691 691
      : index(_index), items(), firstFreeItem(-1),
692 692
        classes(), firstClass(-1), firstFreeClass(-1) {}
693 693

	
694 694
    /// \brief Inserts the given element into a new component.
695 695
    ///
696 696
    /// This method creates a new component consisting only of the
697 697
    /// given element.
698 698
    int insert(const Item& item) {
699 699
      int cdx = newClass();
700 700
      classes[cdx].prev = -1;
701 701
      classes[cdx].next = firstClass;
702 702
      if (firstClass != -1) {
703 703
        classes[firstClass].prev = cdx;
704 704
      }
705 705
      firstClass = cdx;
706 706

	
707 707
      int idx = newItem();
708 708
      items[idx].item = item;
709 709
      items[idx].cls = cdx;
710 710
      items[idx].prev = idx;
711 711
      items[idx].next = idx;
712 712

	
713 713
      classes[cdx].firstItem = idx;
714 714

	
715 715
      index.set(item, idx);
716 716

	
717 717
      return cdx;
718 718
    }
719 719

	
720 720
    /// \brief Inserts the given element into the given component.
721 721
    ///
722 722
    /// This methods inserts the element \e item a into the \e cls class.
723 723
    void insert(const Item& item, int cls) {
724 724
      int idx = newItem();
725 725
      int rdx = classes[cls].firstItem;
726 726
      items[idx].item = item;
727 727
      items[idx].cls = cls;
728 728

	
729 729
      items[idx].prev = rdx;
730 730
      items[idx].next = items[rdx].next;
731 731
      items[items[rdx].next].prev = idx;
732 732
      items[rdx].next = idx;
733 733

	
734 734
      index.set(item, idx);
735 735
    }
736 736

	
737 737
    /// \brief Clears the union-find data structure
738 738
    ///
739 739
    /// Erase each item from the data structure.
740 740
    void clear() {
741 741
      items.clear();
742
      classes.clear;
742
      classes.clear();
743 743
      firstClass = firstFreeClass = firstFreeItem = -1;
744 744
    }
745 745

	
746 746
    /// \brief Gives back the class of the \e item.
747 747
    ///
748 748
    /// Gives back the class of the \e item.
749 749
    int find(const Item &item) const {
750 750
      return items[index[item]].cls;
751 751
    }
752 752

	
753 753
    /// \brief Gives back a representant item of the component.
754 754
    ///
755 755
    /// Gives back a representant item of the component.
756 756
    Item item(int cls) const {
757 757
      return items[classes[cls].firstItem].item;
758 758
    }
759 759

	
760 760
    /// \brief Removes the given element from the structure.
761 761
    ///
762 762
    /// Removes the element from its component and if the component becomes
763 763
    /// empty then removes that component from the component list.
764 764
    ///
765 765
    /// \warning It is an error to remove an element which is not in
766 766
    /// the structure.
767 767
    void erase(const Item &item) {
768 768
      int idx = index[item];
769 769
      int cdx = items[idx].cls;
770 770

	
771 771
      if (idx == items[idx].next) {
772 772
        if (classes[cdx].prev != -1) {
773 773
          classes[classes[cdx].prev].next = classes[cdx].next;
774 774
        } else {
775 775
          firstClass = classes[cdx].next;
776 776
        }
777 777
        if (classes[cdx].next != -1) {
778 778
          classes[classes[cdx].next].prev = classes[cdx].prev;
779 779
        }
780 780
        classes[cdx].next = firstFreeClass;
781 781
        firstFreeClass = cdx;
782 782
      } else {
783 783
        classes[cdx].firstItem = items[idx].next;
784 784
        items[items[idx].next].prev = items[idx].prev;
785 785
        items[items[idx].prev].next = items[idx].next;
786 786
      }
787 787
      items[idx].next = firstFreeItem;
788 788
      firstFreeItem = idx;
789 789

	
790 790
    }
791 791

	
792 792

	
793 793
    /// \brief Removes the component of the given element from the structure.
794 794
    ///
795 795
    /// Removes the component of the given element from the structure.
796 796
    ///
797 797
    /// \warning It is an error to give an element which is not in the
798 798
    /// structure.
799 799
    void eraseClass(int cdx) {
800 800
      int idx = classes[cdx].firstItem;
801 801
      items[items[idx].prev].next = firstFreeItem;
802 802
      firstFreeItem = idx;
803 803

	
804 804
      if (classes[cdx].prev != -1) {
805 805
        classes[classes[cdx].prev].next = classes[cdx].next;
806 806
      } else {
807 807
        firstClass = classes[cdx].next;
808 808
      }
809 809
      if (classes[cdx].next != -1) {
810 810
        classes[classes[cdx].next].prev = classes[cdx].prev;
811 811
      }
812 812
      classes[cdx].next = firstFreeClass;
813 813
      firstFreeClass = cdx;
814 814
    }
815 815

	
816 816
    /// \brief LEMON style iterator for the classes.
817 817
    ///
818 818
    /// ClassIt is a lemon style iterator for the components. It iterates
819 819
    /// on the ids of classes.
820 820
    class ClassIt {
821 821
    public:
822 822
      /// \brief Constructor of the iterator
823 823
      ///
824 824
      /// Constructor of the iterator
825 825
      ClassIt(const ExtendFindEnum& ufe) : extendFind(&ufe) {
826 826
        cdx = extendFind->firstClass;
827 827
      }
828 828

	
829 829
      /// \brief Constructor to get invalid iterator
830 830
      ///
831 831
      /// Constructor to get invalid iterator
832 832
      ClassIt(Invalid) : extendFind(0), cdx(-1) {}
833 833

	
834 834
      /// \brief Increment operator
835 835
      ///
836 836
      /// It steps to the next representant item.
837 837
      ClassIt& operator++() {
838 838
        cdx = extendFind->classes[cdx].next;
839 839
        return *this;
840 840
      }
841 841

	
842 842
      /// \brief Conversion operator
843 843
      ///
844 844
      /// It converts the iterator to the current class id.
845 845
      operator int() const {
846 846
        return cdx;
847 847
      }
848 848

	
849 849
      /// \brief Equality operator
850 850
      ///
851 851
      /// Equality operator
852 852
      bool operator==(const ClassIt& i) {
853 853
        return i.cdx == cdx;
854 854
      }
855 855

	
856 856
      /// \brief Inequality operator
857 857
      ///
858 858
      /// Inequality operator
859 859
      bool operator!=(const ClassIt& i) {
860 860
        return i.cdx != cdx;
861 861
      }
862 862

	
863 863
    private:
864 864
      const ExtendFindEnum* extendFind;
865 865
      int cdx;
866 866
    };
867 867

	
868 868
    /// \brief LEMON style iterator for the items of a component.
869 869
    ///
870 870
    /// ClassIt is a lemon style iterator for the components. It iterates
871 871
    /// on the items of a class. By example if you want to iterate on
872 872
    /// each items of each classes then you may write the next code.
873 873
    ///\code
874 874
    /// for (ClassIt cit(ufe); cit != INVALID; ++cit) {
875 875
    ///   std::cout << "Class: ";
876 876
    ///   for (ItemIt iit(ufe, cit); iit != INVALID; ++iit) {
877 877
    ///     std::cout << toString(iit) << ' ' << std::endl;
878 878
    ///   }
879 879
    ///   std::cout << std::endl;
880 880
    /// }
881 881
    ///\endcode
882 882
    class ItemIt {
883 883
    public:
884 884
      /// \brief Constructor of the iterator
885 885
      ///
886 886
      /// Constructor of the iterator. The iterator iterates
887 887
      /// on the class of the \c item.
888 888
      ItemIt(const ExtendFindEnum& ufe, int cls) : extendFind(&ufe) {
889 889
        fdx = idx = extendFind->classes[cls].firstItem;
890 890
      }
891 891

	
892 892
      /// \brief Constructor to get invalid iterator
893 893
      ///
894 894
      /// Constructor to get invalid iterator
895 895
      ItemIt(Invalid) : extendFind(0), idx(-1) {}
896 896

	
897 897
      /// \brief Increment operator
898 898
      ///
899 899
      /// It steps to the next item in the class.
900 900
      ItemIt& operator++() {
901 901
        idx = extendFind->items[idx].next;
902 902
        if (fdx == idx) idx = -1;
903 903
        return *this;
904 904
      }
905 905

	
906 906
      /// \brief Conversion operator
907 907
      ///
908 908
      /// It converts the iterator to the current item.
909 909
      operator const Item&() const {
910 910
        return extendFind->items[idx].item;
911 911
      }
912 912

	
913 913
      /// \brief Equality operator
914 914
      ///
915 915
      /// Equality operator
916 916
      bool operator==(const ItemIt& i) {
917 917
        return i.idx == idx;
918 918
      }
919 919

	
920 920
      /// \brief Inequality operator
921 921
      ///
922 922
      /// Inequality operator
923 923
      bool operator!=(const ItemIt& i) {
924 924
        return i.idx != idx;
925 925
      }
926 926

	
927 927
    private:
928 928
      const ExtendFindEnum* extendFind;
929 929
      int idx, fdx;
930 930
    };
931 931

	
932 932
  };
933 933

	
934 934
  /// \ingroup auxdat
... ...
@@ -1099,384 +1099,393 @@
1099 1099
          nodes[kd].right = jd;
1100 1100
          nodes[kd].size += 1;
1101 1101
        }
1102 1102
      }
1103 1103
      nodes[jd].next = nodes[id].next;
1104 1104
      nodes[jd].prev = id;
1105 1105
      nodes[id].next = jd;
1106 1106
      nodes[jd].parent = kd;
1107 1107
    }
1108 1108

	
1109 1109
    void pushRight(int id, int jd) {
1110 1110
      nodes[id].size += 1;
1111 1111
      nodes[jd].prev = nodes[id].right;
1112 1112
      nodes[jd].next = -1;
1113 1113
      nodes[nodes[id].right].next = jd;
1114 1114
      nodes[id].right = jd;
1115 1115
      nodes[jd].parent = id;
1116 1116
    }
1117 1117

	
1118 1118
    void popRight(int id) {
1119 1119
      nodes[id].size -= 1;
1120 1120
      int jd = nodes[id].right;
1121 1121
      nodes[nodes[jd].prev].next = -1;
1122 1122
      nodes[id].right = nodes[jd].prev;
1123 1123
    }
1124 1124

	
1125 1125
    void splice(int id, int jd) {
1126 1126
      nodes[id].size += nodes[jd].size;
1127 1127
      nodes[nodes[id].right].next = nodes[jd].left;
1128 1128
      nodes[nodes[jd].left].prev = nodes[id].right;
1129 1129
      int kd = nodes[jd].left;
1130 1130
      while (kd != -1) {
1131 1131
        nodes[kd].parent = id;
1132 1132
        kd = nodes[kd].next;
1133 1133
      }
1134 1134
      nodes[id].right = nodes[jd].right;
1135 1135
    }
1136 1136

	
1137 1137
    void split(int id, int jd) {
1138 1138
      int kd = nodes[id].parent;
1139 1139
      nodes[kd].right = nodes[id].prev;
1140 1140
      nodes[nodes[id].prev].next = -1;
1141 1141

	
1142 1142
      nodes[jd].left = id;
1143 1143
      nodes[id].prev = -1;
1144 1144
      int num = 0;
1145 1145
      while (id != -1) {
1146 1146
        nodes[id].parent = jd;
1147 1147
        nodes[jd].right = id;
1148 1148
        id = nodes[id].next;
1149 1149
        ++num;
1150 1150
      }
1151 1151
      nodes[kd].size -= num;
1152 1152
      nodes[jd].size = num;
1153 1153
    }
1154 1154

	
1155 1155
    void pushLeft(int id, int jd) {
1156 1156
      nodes[id].size += 1;
1157 1157
      nodes[jd].next = nodes[id].left;
1158 1158
      nodes[jd].prev = -1;
1159 1159
      nodes[nodes[id].left].prev = jd;
1160 1160
      nodes[id].left = jd;
1161 1161
      nodes[jd].parent = id;
1162 1162
    }
1163 1163

	
1164 1164
    void popLeft(int id) {
1165 1165
      nodes[id].size -= 1;
1166 1166
      int jd = nodes[id].left;
1167 1167
      nodes[nodes[jd].next].prev = -1;
1168 1168
      nodes[id].left = nodes[jd].next;
1169 1169
    }
1170 1170

	
1171 1171
    void repairLeft(int id) {
1172 1172
      int jd = ~(classes[id].parent);
1173 1173
      while (nodes[jd].left != -1) {
1174 1174
        int kd = nodes[jd].left;
1175 1175
        if (nodes[jd].size == 1) {
1176 1176
          if (nodes[jd].parent < 0) {
1177 1177
            classes[id].parent = ~kd;
1178 1178
            classes[id].depth -= 1;
1179 1179
            nodes[kd].parent = ~id;
1180 1180
            deleteNode(jd);
1181 1181
            jd = kd;
1182 1182
          } else {
1183 1183
            int pd = nodes[jd].parent;
1184 1184
            if (nodes[nodes[jd].next].size < cmax) {
1185 1185
              pushLeft(nodes[jd].next, nodes[jd].left);
1186 1186
              if (less(jd, nodes[jd].next) ||
1187 1187
                  nodes[jd].item == nodes[pd].item) {
1188 1188
                nodes[nodes[jd].next].prio = nodes[jd].prio;
1189 1189
                nodes[nodes[jd].next].item = nodes[jd].item;
1190 1190
              }
1191 1191
              popLeft(pd);
1192 1192
              deleteNode(jd);
1193 1193
              jd = pd;
1194 1194
            } else {
1195 1195
              int ld = nodes[nodes[jd].next].left;
1196 1196
              popLeft(nodes[jd].next);
1197 1197
              pushRight(jd, ld);
1198 1198
              if (less(ld, nodes[jd].left) ||
1199 1199
                  nodes[ld].item == nodes[pd].item) {
1200 1200
                nodes[jd].item = nodes[ld].item;
1201 1201
                nodes[jd].prio = nodes[ld].prio;
1202 1202
              }
1203 1203
              if (nodes[nodes[jd].next].item == nodes[ld].item) {
1204 1204
                setPrio(nodes[jd].next);
1205 1205
              }
1206 1206
              jd = nodes[jd].left;
1207 1207
            }
1208 1208
          }
1209 1209
        } else {
1210 1210
          jd = nodes[jd].left;
1211 1211
        }
1212 1212
      }
1213 1213
    }
1214 1214

	
1215 1215
    void repairRight(int id) {
1216 1216
      int jd = ~(classes[id].parent);
1217 1217
      while (nodes[jd].right != -1) {
1218 1218
        int kd = nodes[jd].right;
1219 1219
        if (nodes[jd].size == 1) {
1220 1220
          if (nodes[jd].parent < 0) {
1221 1221
            classes[id].parent = ~kd;
1222 1222
            classes[id].depth -= 1;
1223 1223
            nodes[kd].parent = ~id;
1224 1224
            deleteNode(jd);
1225 1225
            jd = kd;
1226 1226
          } else {
1227 1227
            int pd = nodes[jd].parent;
1228 1228
            if (nodes[nodes[jd].prev].size < cmax) {
1229 1229
              pushRight(nodes[jd].prev, nodes[jd].right);
1230 1230
              if (less(jd, nodes[jd].prev) ||
1231 1231
                  nodes[jd].item == nodes[pd].item) {
1232 1232
                nodes[nodes[jd].prev].prio = nodes[jd].prio;
1233 1233
                nodes[nodes[jd].prev].item = nodes[jd].item;
1234 1234
              }
1235 1235
              popRight(pd);
1236 1236
              deleteNode(jd);
1237 1237
              jd = pd;
1238 1238
            } else {
1239 1239
              int ld = nodes[nodes[jd].prev].right;
1240 1240
              popRight(nodes[jd].prev);
1241 1241
              pushLeft(jd, ld);
1242 1242
              if (less(ld, nodes[jd].right) ||
1243 1243
                  nodes[ld].item == nodes[pd].item) {
1244 1244
                nodes[jd].item = nodes[ld].item;
1245 1245
                nodes[jd].prio = nodes[ld].prio;
1246 1246
              }
1247 1247
              if (nodes[nodes[jd].prev].item == nodes[ld].item) {
1248 1248
                setPrio(nodes[jd].prev);
1249 1249
              }
1250 1250
              jd = nodes[jd].right;
1251 1251
            }
1252 1252
          }
1253 1253
        } else {
1254 1254
          jd = nodes[jd].right;
1255 1255
        }
1256 1256
      }
1257 1257
    }
1258 1258

	
1259 1259

	
1260 1260
    bool less(int id, int jd) const {
1261 1261
      return comp(nodes[id].prio, nodes[jd].prio);
1262 1262
    }
1263 1263

	
1264 1264
  public:
1265 1265

	
1266 1266
    /// \brief Returns true when the given class is alive.
1267 1267
    ///
1268 1268
    /// Returns true when the given class is alive, ie. the class is
1269 1269
    /// not nested into other class.
1270 1270
    bool alive(int cls) const {
1271 1271
      return classes[cls].parent < 0;
1272 1272
    }
1273 1273

	
1274 1274
    /// \brief Returns true when the given class is trivial.
1275 1275
    ///
1276 1276
    /// Returns true when the given class is trivial, ie. the class
1277 1277
    /// contains just one item directly.
1278 1278
    bool trivial(int cls) const {
1279 1279
      return classes[cls].left == -1;
1280 1280
    }
1281 1281

	
1282 1282
    /// \brief Constructs the union-find.
1283 1283
    ///
1284 1284
    /// Constructs the union-find.
1285 1285
    /// \brief _index The index map of the union-find. The data
1286 1286
    /// structure uses internally for store references.
1287 1287
    HeapUnionFind(ItemIntMap& _index)
1288 1288
      : index(_index), first_class(-1),
1289 1289
        first_free_class(-1), first_free_node(-1) {}
1290 1290

	
1291
    /// \brief Clears the union-find data structure
1292
    ///
1293
    /// Erase each item from the data structure.
1294
    void clear() {
1295
      nodes.clear();
1296
      classes.clear();
1297
      first_free_node = first_free_class = first_class = -1;
1298
    }
1299

	
1291 1300
    /// \brief Insert a new node into a new component.
1292 1301
    ///
1293 1302
    /// Insert a new node into a new component.
1294 1303
    /// \param item The item of the new node.
1295 1304
    /// \param prio The priority of the new node.
1296 1305
    /// \return The class id of the one-item-heap.
1297 1306
    int insert(const Item& item, const Value& prio) {
1298 1307
      int id = newNode();
1299 1308
      nodes[id].item = item;
1300 1309
      nodes[id].prio = prio;
1301 1310
      nodes[id].size = 0;
1302 1311

	
1303 1312
      nodes[id].prev = -1;
1304 1313
      nodes[id].next = -1;
1305 1314

	
1306 1315
      nodes[id].left = -1;
1307 1316
      nodes[id].right = -1;
1308 1317

	
1309 1318
      nodes[id].item = item;
1310 1319
      index[item] = id;
1311 1320

	
1312 1321
      int class_id = newClass();
1313 1322
      classes[class_id].parent = ~id;
1314 1323
      classes[class_id].depth = 0;
1315 1324

	
1316 1325
      classes[class_id].left = -1;
1317 1326
      classes[class_id].right = -1;
1318 1327

	
1319 1328
      if (first_class != -1) {
1320 1329
        classes[first_class].prev = class_id;
1321 1330
      }
1322 1331
      classes[class_id].next = first_class;
1323 1332
      classes[class_id].prev = -1;
1324 1333
      first_class = class_id;
1325 1334

	
1326 1335
      nodes[id].parent = ~class_id;
1327 1336

	
1328 1337
      return class_id;
1329 1338
    }
1330 1339

	
1331 1340
    /// \brief The class of the item.
1332 1341
    ///
1333 1342
    /// \return The alive class id of the item, which is not nested into
1334 1343
    /// other classes.
1335 1344
    ///
1336 1345
    /// The time complexity is O(log(n)).
1337 1346
    int find(const Item& item) const {
1338 1347
      return findClass(index[item]);
1339 1348
    }
1340 1349

	
1341 1350
    /// \brief Joins the classes.
1342 1351
    ///
1343 1352
    /// The current function joins the given classes. The parameter is
1344 1353
    /// an STL range which should be contains valid class ids. The
1345 1354
    /// time complexity is O(log(n)*k) where n is the overall number
1346 1355
    /// of the joined nodes and k is the number of classes.
1347 1356
    /// \return The class of the joined classes.
1348 1357
    /// \pre The range should contain at least two class ids.
1349 1358
    template <typename Iterator>
1350 1359
    int join(Iterator begin, Iterator end) {
1351 1360
      std::vector<int> cs;
1352 1361
      for (Iterator it = begin; it != end; ++it) {
1353 1362
        cs.push_back(*it);
1354 1363
      }
1355 1364

	
1356 1365
      int class_id = newClass();
1357 1366
      { // creation union-find
1358 1367

	
1359 1368
        if (first_class != -1) {
1360 1369
          classes[first_class].prev = class_id;
1361 1370
        }
1362 1371
        classes[class_id].next = first_class;
1363 1372
        classes[class_id].prev = -1;
1364 1373
        first_class = class_id;
1365 1374

	
1366 1375
        classes[class_id].depth = classes[cs[0]].depth;
1367 1376
        classes[class_id].parent = classes[cs[0]].parent;
1368 1377
        nodes[~(classes[class_id].parent)].parent = ~class_id;
1369 1378

	
1370 1379
        int l = cs[0];
1371 1380

	
1372 1381
        classes[class_id].left = l;
1373 1382
        classes[class_id].right = l;
1374 1383

	
1375 1384
        if (classes[l].next != -1) {
1376 1385
          classes[classes[l].next].prev = classes[l].prev;
1377 1386
        }
1378 1387
        classes[classes[l].prev].next = classes[l].next;
1379 1388

	
1380 1389
        classes[l].prev = -1;
1381 1390
        classes[l].next = -1;
1382 1391

	
1383 1392
        classes[l].depth = leftNode(l);
1384 1393
        classes[l].parent = class_id;
1385 1394

	
1386 1395
      }
1387 1396

	
1388 1397
      { // merging of heap
1389 1398
        int l = class_id;
1390 1399
        for (int ci = 1; ci < int(cs.size()); ++ci) {
1391 1400
          int r = cs[ci];
1392 1401
          int rln = leftNode(r);
1393 1402
          if (classes[l].depth > classes[r].depth) {
1394 1403
            int id = ~(classes[l].parent);
1395 1404
            for (int i = classes[r].depth + 1; i < classes[l].depth; ++i) {
1396 1405
              id = nodes[id].right;
1397 1406
            }
1398 1407
            while (id >= 0 && nodes[id].size == cmax) {
1399 1408
              int new_id = newNode();
1400 1409
              int right_id = nodes[id].right;
1401 1410

	
1402 1411
              popRight(id);
1403 1412
              if (nodes[id].item == nodes[right_id].item) {
1404 1413
                setPrio(id);
1405 1414
              }
1406 1415
              push(new_id, right_id);
1407 1416
              pushRight(new_id, ~(classes[r].parent));
1408 1417

	
1409 1418
              if (less(~classes[r].parent, right_id)) {
1410 1419
                nodes[new_id].item = nodes[~classes[r].parent].item;
1411 1420
                nodes[new_id].prio = nodes[~classes[r].parent].prio;
1412 1421
              } else {
1413 1422
                nodes[new_id].item = nodes[right_id].item;
1414 1423
                nodes[new_id].prio = nodes[right_id].prio;
1415 1424
              }
1416 1425

	
1417 1426
              id = nodes[id].parent;
1418 1427
              classes[r].parent = ~new_id;
1419 1428
            }
1420 1429
            if (id < 0) {
1421 1430
              int new_parent = newNode();
1422 1431
              nodes[new_parent].next = -1;
1423 1432
              nodes[new_parent].prev = -1;
1424 1433
              nodes[new_parent].parent = ~l;
1425 1434

	
1426 1435
              push(new_parent, ~(classes[l].parent));
1427 1436
              pushRight(new_parent, ~(classes[r].parent));
1428 1437
              setPrio(new_parent);
1429 1438

	
1430 1439
              classes[l].parent = ~new_parent;
1431 1440
              classes[l].depth += 1;
1432 1441
            } else {
1433 1442
              pushRight(id, ~(classes[r].parent));
1434 1443
              while (id >= 0 && less(~(classes[r].parent), id)) {
1435 1444
                nodes[id].prio = nodes[~(classes[r].parent)].prio;
1436 1445
                nodes[id].item = nodes[~(classes[r].parent)].item;
1437 1446
                id = nodes[id].parent;
1438 1447
              }
1439 1448
            }
1440 1449
          } else if (classes[r].depth > classes[l].depth) {
1441 1450
            int id = ~(classes[r].parent);
1442 1451
            for (int i = classes[l].depth + 1; i < classes[r].depth; ++i) {
1443 1452
              id = nodes[id].left;
1444 1453
            }
1445 1454
            while (id >= 0 && nodes[id].size == cmax) {
1446 1455
              int new_id = newNode();
1447 1456
              int left_id = nodes[id].left;
1448 1457

	
1449 1458
              popLeft(id);
1450 1459
              if (nodes[id].prio == nodes[left_id].prio) {
1451 1460
                setPrio(id);
1452 1461
              }
1453 1462
              push(new_id, left_id);
1454 1463
              pushLeft(new_id, ~(classes[l].parent));
1455 1464

	
1456 1465
              if (less(~classes[l].parent, left_id)) {
1457 1466
                nodes[new_id].item = nodes[~classes[l].parent].item;
1458 1467
                nodes[new_id].prio = nodes[~classes[l].parent].prio;
1459 1468
              } else {
1460 1469
                nodes[new_id].item = nodes[left_id].item;
1461 1470
                nodes[new_id].prio = nodes[left_id].prio;
1462 1471
              }
1463 1472

	
1464 1473
              id = nodes[id].parent;
1465 1474
              classes[l].parent = ~new_id;
1466 1475

	
1467 1476
            }
1468 1477
            if (id < 0) {
1469 1478
              int new_parent = newNode();
1470 1479
              nodes[new_parent].next = -1;
1471 1480
              nodes[new_parent].prev = -1;
1472 1481
              nodes[new_parent].parent = ~l;
1473 1482

	
1474 1483
              push(new_parent, ~(classes[r].parent));
1475 1484
              pushLeft(new_parent, ~(classes[l].parent));
1476 1485
              setPrio(new_parent);
1477 1486

	
1478 1487
              classes[r].parent = ~new_parent;
1479 1488
              classes[r].depth += 1;
1480 1489
            } else {
1481 1490
              pushLeft(id, ~(classes[l].parent));
1482 1491
              while (id >= 0 && less(~(classes[l].parent), id)) {
0 comments (0 inline)