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 96 line context
... ...
@@ -760,131 +760,150 @@
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) {
... ...
@@ -1640,120 +1659,132 @@
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

	
... ...
@@ -2153,127 +2184,145 @@
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

	
... ...
@@ -2881,117 +2930,128 @@
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

	
Ignore white space 6 line context
... ...
@@ -694,97 +694,97 @@
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
    }
... ...
@@ -1243,96 +1243,105 @@
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]);
0 comments (0 inline)