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 48 line context
... ...
@@ -784,83 +784,102 @@
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
      }
... ...
@@ -1664,72 +1683,84 @@
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

	
... ...
@@ -2177,79 +2208,97 @@
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
      }
... ...
@@ -2905,69 +2954,80 @@
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
Ignore white space 6 line context
... ...
@@ -718,49 +718,49 @@
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.
... ...
@@ -1267,48 +1267,57 @@
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;
0 comments (0 inline)