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 71 insertions and 2 deletions:
↑ Collapse diff ↑
Ignore white space 192 line context
... ...
@@ -712,227 +712,246 @@
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
                                              NodeData(*_node_heap_index));
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);
836
      } else {
837
        _tree_set_index->resize(_blossom_num);
827 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);
848
      } else {
849
        _delta2_index->resize(_blossom_num);
835 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
              }
... ...
@@ -1592,216 +1611,228 @@
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
      }
1723
      
1724
      _delta1->clear();
1725
      _delta2->clear();
1726
      _delta3->clear();
1727
      _delta4->clear();
1728
      _blossom_set->clear();
1729
      _tree_set->clear();
1701 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) {
... ...
@@ -2105,223 +2136,241 @@
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);
2260
      } else {
2261
        _tree_set_index->resize(_blossom_num);
2220 2262
      }
2263

	
2221 2264
      if (!_delta2) {
2222 2265
        _delta2_index = new IntIntMap(_blossom_num);
2223 2266
        _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
2267
      } else {
2268
        _delta2_index->resize(_blossom_num);
2224 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) {
... ...
@@ -2833,213 +2882,224 @@
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.
Ignore white space 192 line context
... ...
@@ -646,193 +646,193 @@
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;
... ...
@@ -1195,192 +1195,201 @@
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
      }
0 comments (0 inline)