gravatar
deba@inf.elte.hu
deba@inf.elte.hu
Fix multiple executions in matchings (fract. mathcings) (#356)
0 2 0
default
2 files changed with 32 insertions and 0 deletions:
↑ Collapse diff ↑
Ignore white space 192 line context
... ...
@@ -1073,192 +1073,197 @@
1073 1073
              left_path.push_back(nca);
1074 1074
              nca = _graph.target((*_pred)[nca]);
1075 1075
              left_path.push_back(nca);
1076 1076
            }
1077 1077
          }
1078 1078
        }
1079 1079
      }
1080 1080

	
1081 1081
      alternatePath(nca, tree);
1082 1082
      Arc prev;
1083 1083

	
1084 1084
      prev = _graph.direct(edge, true);
1085 1085
      for (int i = 0; left_path[i] != nca; i += 2) {
1086 1086
        _matching->set(left_path[i], prev);
1087 1087
        _status->set(left_path[i], MATCHED);
1088 1088
        evenToMatched(left_path[i], tree);
1089 1089

	
1090 1090
        prev = _graph.oppositeArc((*_pred)[left_path[i + 1]]);
1091 1091
        _status->set(left_path[i + 1], MATCHED);
1092 1092
        oddToMatched(left_path[i + 1]);
1093 1093
      }
1094 1094
      _matching->set(nca, prev);
1095 1095

	
1096 1096
      for (int i = 0; right_path[i] != nca; i += 2) {
1097 1097
        _status->set(right_path[i], MATCHED);
1098 1098
        evenToMatched(right_path[i], tree);
1099 1099

	
1100 1100
        _matching->set(right_path[i + 1], (*_pred)[right_path[i + 1]]);
1101 1101
        _status->set(right_path[i + 1], MATCHED);
1102 1102
        oddToMatched(right_path[i + 1]);
1103 1103
      }
1104 1104

	
1105 1105
      destroyTree(tree);
1106 1106
    }
1107 1107

	
1108 1108
    void extractCycle(const Arc &arc) {
1109 1109
      Node left = _graph.source(arc);
1110 1110
      Node odd = _graph.target((*_matching)[left]);
1111 1111
      Arc prev;
1112 1112
      while (odd != left) {
1113 1113
        Node even = _graph.target((*_matching)[odd]);
1114 1114
        prev = (*_matching)[odd];
1115 1115
        odd = _graph.target((*_matching)[even]);
1116 1116
        _matching->set(even, _graph.oppositeArc(prev));
1117 1117
      }
1118 1118
      _matching->set(left, arc);
1119 1119

	
1120 1120
      Node right = _graph.target(arc);
1121 1121
      int right_tree = _tree_set->find(right);
1122 1122
      alternatePath(right, right_tree);
1123 1123
      destroyTree(right_tree);
1124 1124
      _matching->set(right, _graph.oppositeArc(arc));
1125 1125
    }
1126 1126

	
1127 1127
  public:
1128 1128

	
1129 1129
    /// \brief Constructor
1130 1130
    ///
1131 1131
    /// Constructor.
1132 1132
    MaxWeightedFractionalMatching(const Graph& graph, const WeightMap& weight,
1133 1133
                                  bool allow_loops = true)
1134 1134
      : _graph(graph), _weight(weight), _matching(0),
1135 1135
      _node_potential(0), _node_num(0), _allow_loops(allow_loops),
1136 1136
      _status(0),  _pred(0),
1137 1137
      _tree_set_index(0), _tree_set(0),
1138 1138

	
1139 1139
      _delta1_index(0), _delta1(0),
1140 1140
      _delta2_index(0), _delta2(0),
1141 1141
      _delta3_index(0), _delta3(0),
1142 1142

	
1143 1143
      _delta_sum() {}
1144 1144

	
1145 1145
    ~MaxWeightedFractionalMatching() {
1146 1146
      destroyStructures();
1147 1147
    }
1148 1148

	
1149 1149
    /// \name Execution Control
1150 1150
    /// The simplest way to execute the algorithm is to use the
1151 1151
    /// \ref run() member function.
1152 1152

	
1153 1153
    ///@{
1154 1154

	
1155 1155
    /// \brief Initialize the algorithm
1156 1156
    ///
1157 1157
    /// This function initializes the algorithm.
1158 1158
    void init() {
1159 1159
      createStructures();
1160 1160

	
1161 1161
      for (NodeIt n(_graph); n != INVALID; ++n) {
1162 1162
        (*_delta1_index)[n] = _delta1->PRE_HEAP;
1163 1163
        (*_delta2_index)[n] = _delta2->PRE_HEAP;
1164 1164
      }
1165 1165
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1166 1166
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
1167 1167
      }
1168 1168

	
1169
      _delta1->clear();
1170
      _delta2->clear();
1171
      _delta3->clear();
1172
      _tree_set->clear();
1173

	
1169 1174
      for (NodeIt n(_graph); n != INVALID; ++n) {
1170 1175
        Value max = 0;
1171 1176
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
1172 1177
          if (_graph.target(e) == n && !_allow_loops) continue;
1173 1178
          if ((dualScale * _weight[e]) / 2 > max) {
1174 1179
            max = (dualScale * _weight[e]) / 2;
1175 1180
          }
1176 1181
        }
1177 1182
        _node_potential->set(n, max);
1178 1183
        _delta1->push(n, max);
1179 1184

	
1180 1185
        _tree_set->insert(n);
1181 1186

	
1182 1187
        _matching->set(n, INVALID);
1183 1188
        _status->set(n, EVEN);
1184 1189
      }
1185 1190

	
1186 1191
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1187 1192
        Node left = _graph.u(e);
1188 1193
        Node right = _graph.v(e);
1189 1194
        if (left == right && !_allow_loops) continue;
1190 1195
        _delta3->push(e, ((*_node_potential)[left] +
1191 1196
                          (*_node_potential)[right] -
1192 1197
                          dualScale * _weight[e]) / 2);
1193 1198
      }
1194 1199
    }
1195 1200

	
1196 1201
    /// \brief Start the algorithm
1197 1202
    ///
1198 1203
    /// This function starts the algorithm.
1199 1204
    ///
1200 1205
    /// \pre \ref init() must be called before using this function.
1201 1206
    void start() {
1202 1207
      enum OpType {
1203 1208
        D1, D2, D3
1204 1209
      };
1205 1210

	
1206 1211
      int unmatched = _node_num;
1207 1212
      while (unmatched > 0) {
1208 1213
        Value d1 = !_delta1->empty() ?
1209 1214
          _delta1->prio() : std::numeric_limits<Value>::max();
1210 1215

	
1211 1216
        Value d2 = !_delta2->empty() ?
1212 1217
          _delta2->prio() : std::numeric_limits<Value>::max();
1213 1218

	
1214 1219
        Value d3 = !_delta3->empty() ?
1215 1220
          _delta3->prio() : std::numeric_limits<Value>::max();
1216 1221

	
1217 1222
        _delta_sum = d3; OpType ot = D3;
1218 1223
        if (d1 < _delta_sum) { _delta_sum = d1; ot = D1; }
1219 1224
        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
1220 1225

	
1221 1226
        switch (ot) {
1222 1227
        case D1:
1223 1228
          {
1224 1229
            Node n = _delta1->top();
1225 1230
            unmatchNode(n);
1226 1231
            --unmatched;
1227 1232
          }
1228 1233
          break;
1229 1234
        case D2:
1230 1235
          {
1231 1236
            Node n = _delta2->top();
1232 1237
            Arc a = (*_pred)[n];
1233 1238
            if ((*_matching)[n] == INVALID) {
1234 1239
              augmentOnArc(a);
1235 1240
              --unmatched;
1236 1241
            } else {
1237 1242
              Node v = _graph.target((*_matching)[n]);
1238 1243
              if ((*_matching)[n] !=
1239 1244
                  _graph.oppositeArc((*_matching)[v])) {
1240 1245
                extractCycle(a);
1241 1246
                --unmatched;
1242 1247
              } else {
1243 1248
                extendOnArc(a);
1244 1249
              }
1245 1250
            }
1246 1251
          } break;
1247 1252
        case D3:
1248 1253
          {
1249 1254
            Edge e = _delta3->top();
1250 1255

	
1251 1256
            Node left = _graph.u(e);
1252 1257
            Node right = _graph.v(e);
1253 1258

	
1254 1259
            int left_tree = _tree_set->find(left);
1255 1260
            int right_tree = _tree_set->find(right);
1256 1261

	
1257 1262
            if (left_tree == right_tree) {
1258 1263
              cycleOnEdge(e, left_tree);
1259 1264
              --unmatched;
1260 1265
            } else {
1261 1266
              augmentOnEdge(e);
1262 1267
              unmatched -= 2;
1263 1268
            }
1264 1269
          } break;
... ...
@@ -1812,192 +1817,196 @@
1812 1817
              nca = _graph.target((*_matching)[nca]);
1813 1818
              left_path.push_back(nca);
1814 1819
              nca = _graph.target((*_pred)[nca]);
1815 1820
              left_path.push_back(nca);
1816 1821
            }
1817 1822
          }
1818 1823
        }
1819 1824
      }
1820 1825

	
1821 1826
      alternatePath(nca, tree);
1822 1827
      Arc prev;
1823 1828

	
1824 1829
      prev = _graph.direct(edge, true);
1825 1830
      for (int i = 0; left_path[i] != nca; i += 2) {
1826 1831
        _matching->set(left_path[i], prev);
1827 1832
        _status->set(left_path[i], MATCHED);
1828 1833
        evenToMatched(left_path[i], tree);
1829 1834

	
1830 1835
        prev = _graph.oppositeArc((*_pred)[left_path[i + 1]]);
1831 1836
        _status->set(left_path[i + 1], MATCHED);
1832 1837
        oddToMatched(left_path[i + 1]);
1833 1838
      }
1834 1839
      _matching->set(nca, prev);
1835 1840

	
1836 1841
      for (int i = 0; right_path[i] != nca; i += 2) {
1837 1842
        _status->set(right_path[i], MATCHED);
1838 1843
        evenToMatched(right_path[i], tree);
1839 1844

	
1840 1845
        _matching->set(right_path[i + 1], (*_pred)[right_path[i + 1]]);
1841 1846
        _status->set(right_path[i + 1], MATCHED);
1842 1847
        oddToMatched(right_path[i + 1]);
1843 1848
      }
1844 1849

	
1845 1850
      destroyTree(tree);
1846 1851
    }
1847 1852

	
1848 1853
    void extractCycle(const Arc &arc) {
1849 1854
      Node left = _graph.source(arc);
1850 1855
      Node odd = _graph.target((*_matching)[left]);
1851 1856
      Arc prev;
1852 1857
      while (odd != left) {
1853 1858
        Node even = _graph.target((*_matching)[odd]);
1854 1859
        prev = (*_matching)[odd];
1855 1860
        odd = _graph.target((*_matching)[even]);
1856 1861
        _matching->set(even, _graph.oppositeArc(prev));
1857 1862
      }
1858 1863
      _matching->set(left, arc);
1859 1864

	
1860 1865
      Node right = _graph.target(arc);
1861 1866
      int right_tree = _tree_set->find(right);
1862 1867
      alternatePath(right, right_tree);
1863 1868
      destroyTree(right_tree);
1864 1869
      _matching->set(right, _graph.oppositeArc(arc));
1865 1870
    }
1866 1871

	
1867 1872
  public:
1868 1873

	
1869 1874
    /// \brief Constructor
1870 1875
    ///
1871 1876
    /// Constructor.
1872 1877
    MaxWeightedPerfectFractionalMatching(const Graph& graph,
1873 1878
                                         const WeightMap& weight,
1874 1879
                                         bool allow_loops = true)
1875 1880
      : _graph(graph), _weight(weight), _matching(0),
1876 1881
      _node_potential(0), _node_num(0), _allow_loops(allow_loops),
1877 1882
      _status(0),  _pred(0),
1878 1883
      _tree_set_index(0), _tree_set(0),
1879 1884

	
1880 1885
      _delta2_index(0), _delta2(0),
1881 1886
      _delta3_index(0), _delta3(0),
1882 1887

	
1883 1888
      _delta_sum() {}
1884 1889

	
1885 1890
    ~MaxWeightedPerfectFractionalMatching() {
1886 1891
      destroyStructures();
1887 1892
    }
1888 1893

	
1889 1894
    /// \name Execution Control
1890 1895
    /// The simplest way to execute the algorithm is to use the
1891 1896
    /// \ref run() member function.
1892 1897

	
1893 1898
    ///@{
1894 1899

	
1895 1900
    /// \brief Initialize the algorithm
1896 1901
    ///
1897 1902
    /// This function initializes the algorithm.
1898 1903
    void init() {
1899 1904
      createStructures();
1900 1905

	
1901 1906
      for (NodeIt n(_graph); n != INVALID; ++n) {
1902 1907
        (*_delta2_index)[n] = _delta2->PRE_HEAP;
1903 1908
      }
1904 1909
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1905 1910
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
1906 1911
      }
1907 1912

	
1913
      _delta2->clear();
1914
      _delta3->clear();
1915
      _tree_set->clear();
1916

	
1908 1917
      for (NodeIt n(_graph); n != INVALID; ++n) {
1909 1918
        Value max = - std::numeric_limits<Value>::max();
1910 1919
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
1911 1920
          if (_graph.target(e) == n && !_allow_loops) continue;
1912 1921
          if ((dualScale * _weight[e]) / 2 > max) {
1913 1922
            max = (dualScale * _weight[e]) / 2;
1914 1923
          }
1915 1924
        }
1916 1925
        _node_potential->set(n, max);
1917 1926

	
1918 1927
        _tree_set->insert(n);
1919 1928

	
1920 1929
        _matching->set(n, INVALID);
1921 1930
        _status->set(n, EVEN);
1922 1931
      }
1923 1932

	
1924 1933
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1925 1934
        Node left = _graph.u(e);
1926 1935
        Node right = _graph.v(e);
1927 1936
        if (left == right && !_allow_loops) continue;
1928 1937
        _delta3->push(e, ((*_node_potential)[left] +
1929 1938
                          (*_node_potential)[right] -
1930 1939
                          dualScale * _weight[e]) / 2);
1931 1940
      }
1932 1941
    }
1933 1942

	
1934 1943
    /// \brief Start the algorithm
1935 1944
    ///
1936 1945
    /// This function starts the algorithm.
1937 1946
    ///
1938 1947
    /// \pre \ref init() must be called before using this function.
1939 1948
    bool start() {
1940 1949
      enum OpType {
1941 1950
        D2, D3
1942 1951
      };
1943 1952

	
1944 1953
      int unmatched = _node_num;
1945 1954
      while (unmatched > 0) {
1946 1955
        Value d2 = !_delta2->empty() ?
1947 1956
          _delta2->prio() : std::numeric_limits<Value>::max();
1948 1957

	
1949 1958
        Value d3 = !_delta3->empty() ?
1950 1959
          _delta3->prio() : std::numeric_limits<Value>::max();
1951 1960

	
1952 1961
        _delta_sum = d3; OpType ot = D3;
1953 1962
        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
1954 1963

	
1955 1964
        if (_delta_sum == std::numeric_limits<Value>::max()) {
1956 1965
          return false;
1957 1966
        }
1958 1967

	
1959 1968
        switch (ot) {
1960 1969
        case D2:
1961 1970
          {
1962 1971
            Node n = _delta2->top();
1963 1972
            Arc a = (*_pred)[n];
1964 1973
            if ((*_matching)[n] == INVALID) {
1965 1974
              augmentOnArc(a);
1966 1975
              --unmatched;
1967 1976
            } else {
1968 1977
              Node v = _graph.target((*_matching)[n]);
1969 1978
              if ((*_matching)[n] !=
1970 1979
                  _graph.oppositeArc((*_matching)[v])) {
1971 1980
                extractCycle(a);
1972 1981
                --unmatched;
1973 1982
              } else {
1974 1983
                extendOnArc(a);
1975 1984
              }
1976 1985
            }
1977 1986
          } break;
1978 1987
        case D3:
1979 1988
          {
1980 1989
            Edge e = _delta3->top();
1981 1990

	
1982 1991
            Node left = _graph.u(e);
1983 1992
            Node right = _graph.v(e);
1984 1993

	
1985 1994
            int left_tree = _tree_set->find(left);
1986 1995
            int right_tree = _tree_set->find(right);
1987 1996

	
1988 1997
            if (left_tree == right_tree) {
1989 1998
              cycleOnEdge(e, left_tree);
1990 1999
              --unmatched;
1991 2000
            } else {
1992 2001
              augmentOnEdge(e);
1993 2002
              unmatched -= 2;
1994 2003
            }
1995 2004
          } break;
1996 2005
        }
1997 2006
      }
1998 2007
      return true;
1999 2008
    }
2000 2009

	
2001 2010
    /// \brief Run the algorithm.
2002 2011
    ///
2003 2012
    /// This method runs the \c %MaxWeightedPerfectFractionalMatching 
Ignore white space 192 line context
... ...
@@ -1582,219 +1582,231 @@
1582 1582
        _delta2_index(0), _delta2(0),
1583 1583
        _delta3_index(0), _delta3(0),
1584 1584
        _delta4_index(0), _delta4(0),
1585 1585

	
1586 1586
        _delta_sum(), _unmatched(0),
1587 1587

	
1588 1588
        _fractional(0)
1589 1589
    {}
1590 1590

	
1591 1591
    ~MaxWeightedMatching() {
1592 1592
      destroyStructures();
1593 1593
      if (_fractional) {
1594 1594
        delete _fractional;
1595 1595
      }
1596 1596
    }
1597 1597

	
1598 1598
    /// \name Execution Control
1599 1599
    /// The simplest way to execute the algorithm is to use the
1600 1600
    /// \ref run() member function.
1601 1601

	
1602 1602
    ///@{
1603 1603

	
1604 1604
    /// \brief Initialize the algorithm
1605 1605
    ///
1606 1606
    /// This function initializes the algorithm.
1607 1607
    void init() {
1608 1608
      createStructures();
1609 1609

	
1610 1610
      _blossom_node_list.clear();
1611 1611
      _blossom_potential.clear();
1612 1612

	
1613 1613
      for (ArcIt e(_graph); e != INVALID; ++e) {
1614 1614
        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
1615 1615
      }
1616 1616
      for (NodeIt n(_graph); n != INVALID; ++n) {
1617 1617
        (*_delta1_index)[n] = _delta1->PRE_HEAP;
1618 1618
      }
1619 1619
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1620 1620
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
1621 1621
      }
1622 1622
      for (int i = 0; i < _blossom_num; ++i) {
1623 1623
        (*_delta2_index)[i] = _delta2->PRE_HEAP;
1624 1624
        (*_delta4_index)[i] = _delta4->PRE_HEAP;
1625 1625
      }
1626 1626
      
1627 1627
      _unmatched = _node_num;
1628 1628

	
1629 1629
      _delta1->clear();
1630 1630
      _delta2->clear();
1631 1631
      _delta3->clear();
1632 1632
      _delta4->clear();
1633 1633
      _blossom_set->clear();
1634 1634
      _tree_set->clear();
1635 1635

	
1636 1636
      int index = 0;
1637 1637
      for (NodeIt n(_graph); n != INVALID; ++n) {
1638 1638
        Value max = 0;
1639 1639
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
1640 1640
          if (_graph.target(e) == n) continue;
1641 1641
          if ((dualScale * _weight[e]) / 2 > max) {
1642 1642
            max = (dualScale * _weight[e]) / 2;
1643 1643
          }
1644 1644
        }
1645 1645
        (*_node_index)[n] = index;
1646 1646
        (*_node_data)[index].heap_index.clear();
1647 1647
        (*_node_data)[index].heap.clear();
1648 1648
        (*_node_data)[index].pot = max;
1649 1649
        _delta1->push(n, max);
1650 1650
        int blossom =
1651 1651
          _blossom_set->insert(n, std::numeric_limits<Value>::max());
1652 1652

	
1653 1653
        _tree_set->insert(blossom);
1654 1654

	
1655 1655
        (*_blossom_data)[blossom].status = EVEN;
1656 1656
        (*_blossom_data)[blossom].pred = INVALID;
1657 1657
        (*_blossom_data)[blossom].next = INVALID;
1658 1658
        (*_blossom_data)[blossom].pot = 0;
1659 1659
        (*_blossom_data)[blossom].offset = 0;
1660 1660
        ++index;
1661 1661
      }
1662 1662
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1663 1663
        int si = (*_node_index)[_graph.u(e)];
1664 1664
        int ti = (*_node_index)[_graph.v(e)];
1665 1665
        if (_graph.u(e) != _graph.v(e)) {
1666 1666
          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
1667 1667
                            dualScale * _weight[e]) / 2);
1668 1668
        }
1669 1669
      }
1670 1670
    }
1671 1671

	
1672 1672
    /// \brief Initialize the algorithm with fractional matching
1673 1673
    ///
1674 1674
    /// This function initializes the algorithm with a fractional
1675 1675
    /// matching. This initialization is also called jumpstart heuristic.
1676 1676
    void fractionalInit() {
1677 1677
      createStructures();
1678

	
1679
      _blossom_node_list.clear();
1680
      _blossom_potential.clear();
1678 1681
      
1679 1682
      if (_fractional == 0) {
1680 1683
        _fractional = new FractionalMatching(_graph, _weight, false);
1681 1684
      }
1682 1685
      _fractional->run();
1683 1686

	
1684 1687
      for (ArcIt e(_graph); e != INVALID; ++e) {
1685 1688
        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
1686 1689
      }
1687 1690
      for (NodeIt n(_graph); n != INVALID; ++n) {
1688 1691
        (*_delta1_index)[n] = _delta1->PRE_HEAP;
1689 1692
      }
1690 1693
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1691 1694
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
1692 1695
      }
1693 1696
      for (int i = 0; i < _blossom_num; ++i) {
1694 1697
        (*_delta2_index)[i] = _delta2->PRE_HEAP;
1695 1698
        (*_delta4_index)[i] = _delta4->PRE_HEAP;
1696 1699
      }
1697 1700

	
1698 1701
      _unmatched = 0;
1699 1702

	
1703
      _delta1->clear();
1704
      _delta2->clear();
1705
      _delta3->clear();
1706
      _delta4->clear();
1707
      _blossom_set->clear();
1708
      _tree_set->clear();
1709

	
1700 1710
      int index = 0;
1701 1711
      for (NodeIt n(_graph); n != INVALID; ++n) {
1702 1712
        Value pot = _fractional->nodeValue(n);
1703 1713
        (*_node_index)[n] = index;
1704 1714
        (*_node_data)[index].pot = pot;
1715
        (*_node_data)[index].heap_index.clear();
1716
        (*_node_data)[index].heap.clear();
1705 1717
        int blossom =
1706 1718
          _blossom_set->insert(n, std::numeric_limits<Value>::max());
1707 1719

	
1708 1720
        (*_blossom_data)[blossom].status = MATCHED;
1709 1721
        (*_blossom_data)[blossom].pred = INVALID;
1710 1722
        (*_blossom_data)[blossom].next = _fractional->matching(n);
1711 1723
        if (_fractional->matching(n) == INVALID) {
1712 1724
          (*_blossom_data)[blossom].base = n;
1713 1725
        }
1714 1726
        (*_blossom_data)[blossom].pot = 0;
1715 1727
        (*_blossom_data)[blossom].offset = 0;
1716 1728
        ++index;
1717 1729
      }
1718 1730

	
1719 1731
      typename Graph::template NodeMap<bool> processed(_graph, false);
1720 1732
      for (NodeIt n(_graph); n != INVALID; ++n) {
1721 1733
        if (processed[n]) continue;
1722 1734
        processed[n] = true;
1723 1735
        if (_fractional->matching(n) == INVALID) continue;
1724 1736
        int num = 1;
1725 1737
        Node v = _graph.target(_fractional->matching(n));
1726 1738
        while (n != v) {
1727 1739
          processed[v] = true;
1728 1740
          v = _graph.target(_fractional->matching(v));
1729 1741
          ++num;
1730 1742
        }
1731 1743

	
1732 1744
        if (num % 2 == 1) {
1733 1745
          std::vector<int> subblossoms(num);
1734 1746

	
1735 1747
          subblossoms[--num] = _blossom_set->find(n);
1736 1748
          _delta1->push(n, _fractional->nodeValue(n));
1737 1749
          v = _graph.target(_fractional->matching(n));
1738 1750
          while (n != v) {
1739 1751
            subblossoms[--num] = _blossom_set->find(v);
1740 1752
            _delta1->push(v, _fractional->nodeValue(v));
1741 1753
            v = _graph.target(_fractional->matching(v));            
1742 1754
          }
1743 1755
          
1744 1756
          int surface = 
1745 1757
            _blossom_set->join(subblossoms.begin(), subblossoms.end());
1746 1758
          (*_blossom_data)[surface].status = EVEN;
1747 1759
          (*_blossom_data)[surface].pred = INVALID;
1748 1760
          (*_blossom_data)[surface].next = INVALID;
1749 1761
          (*_blossom_data)[surface].pot = 0;
1750 1762
          (*_blossom_data)[surface].offset = 0;
1751 1763
          
1752 1764
          _tree_set->insert(surface);
1753 1765
          ++_unmatched;
1754 1766
        }
1755 1767
      }
1756 1768

	
1757 1769
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1758 1770
        int si = (*_node_index)[_graph.u(e)];
1759 1771
        int sb = _blossom_set->find(_graph.u(e));
1760 1772
        int ti = (*_node_index)[_graph.v(e)];
1761 1773
        int tb = _blossom_set->find(_graph.v(e));
1762 1774
        if ((*_blossom_data)[sb].status == EVEN &&
1763 1775
            (*_blossom_data)[tb].status == EVEN && sb != tb) {
1764 1776
          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
1765 1777
                            dualScale * _weight[e]) / 2);
1766 1778
        }
1767 1779
      }
1768 1780

	
1769 1781
      for (NodeIt n(_graph); n != INVALID; ++n) {
1770 1782
        int nb = _blossom_set->find(n);
1771 1783
        if ((*_blossom_data)[nb].status != MATCHED) continue;
1772 1784
        int ni = (*_node_index)[n];
1773 1785

	
1774 1786
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
1775 1787
          Node v = _graph.target(e);
1776 1788
          int vb = _blossom_set->find(v);
1777 1789
          int vi = (*_node_index)[v];
1778 1790

	
1779 1791
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
1780 1792
            dualScale * _weight[e];
1781 1793

	
1782 1794
          if ((*_blossom_data)[vb].status == EVEN) {
1783 1795

	
1784 1796
            int vt = _tree_set->find(vb);
1785 1797

	
1786 1798
            typename std::map<int, Arc>::iterator it =
1787 1799
              (*_node_data)[ni].heap_index.find(vt);
1788 1800

	
1789 1801
            if (it != (*_node_data)[ni].heap_index.end()) {
1790 1802
              if ((*_node_data)[ni].heap[it->second] > rw) {
1791 1803
                (*_node_data)[ni].heap.replace(it->second, e);
1792 1804
                (*_node_data)[ni].heap.decrease(e, rw);
1793 1805
                it->second = e;
1794 1806
              }
1795 1807
            } else {
1796 1808
              (*_node_data)[ni].heap.push(e, rw);
1797 1809
              (*_node_data)[ni].heap_index.insert(std::make_pair(vt, e));
1798 1810
            }
1799 1811
          }
1800 1812
        }
... ...
@@ -2987,219 +2999,230 @@
2987 2999

	
2988 3000
        _blossom_index(0), _blossom_set(0), _blossom_data(0),
2989 3001
        _node_index(0), _node_heap_index(0), _node_data(0),
2990 3002
        _tree_set_index(0), _tree_set(0),
2991 3003

	
2992 3004
        _delta2_index(0), _delta2(0),
2993 3005
        _delta3_index(0), _delta3(0),
2994 3006
        _delta4_index(0), _delta4(0),
2995 3007

	
2996 3008
        _delta_sum(), _unmatched(0),
2997 3009

	
2998 3010
        _fractional(0)
2999 3011
    {}
3000 3012

	
3001 3013
    ~MaxWeightedPerfectMatching() {
3002 3014
      destroyStructures();
3003 3015
      if (_fractional) {
3004 3016
        delete _fractional;
3005 3017
      }
3006 3018
    }
3007 3019

	
3008 3020
    /// \name Execution Control
3009 3021
    /// The simplest way to execute the algorithm is to use the
3010 3022
    /// \ref run() member function.
3011 3023

	
3012 3024
    ///@{
3013 3025

	
3014 3026
    /// \brief Initialize the algorithm
3015 3027
    ///
3016 3028
    /// This function initializes the algorithm.
3017 3029
    void init() {
3018 3030
      createStructures();
3019 3031

	
3020 3032
      _blossom_node_list.clear();
3021 3033
      _blossom_potential.clear();
3022 3034

	
3023 3035
      for (ArcIt e(_graph); e != INVALID; ++e) {
3024 3036
        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
3025 3037
      }
3026 3038
      for (EdgeIt e(_graph); e != INVALID; ++e) {
3027 3039
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
3028 3040
      }
3029 3041
      for (int i = 0; i < _blossom_num; ++i) {
3030 3042
        (*_delta2_index)[i] = _delta2->PRE_HEAP;
3031 3043
        (*_delta4_index)[i] = _delta4->PRE_HEAP;
3032 3044
      }
3033 3045

	
3034 3046
      _unmatched = _node_num;
3035 3047

	
3036 3048
      _delta2->clear();
3037 3049
      _delta3->clear();
3038 3050
      _delta4->clear();
3039 3051
      _blossom_set->clear();
3040 3052
      _tree_set->clear();
3041 3053

	
3042 3054
      int index = 0;
3043 3055
      for (NodeIt n(_graph); n != INVALID; ++n) {
3044 3056
        Value max = - std::numeric_limits<Value>::max();
3045 3057
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
3046 3058
          if (_graph.target(e) == n) continue;
3047 3059
          if ((dualScale * _weight[e]) / 2 > max) {
3048 3060
            max = (dualScale * _weight[e]) / 2;
3049 3061
          }
3050 3062
        }
3051 3063
        (*_node_index)[n] = index;
3052 3064
        (*_node_data)[index].heap_index.clear();
3053 3065
        (*_node_data)[index].heap.clear();
3054 3066
        (*_node_data)[index].pot = max;
3055 3067
        int blossom =
3056 3068
          _blossom_set->insert(n, std::numeric_limits<Value>::max());
3057 3069

	
3058 3070
        _tree_set->insert(blossom);
3059 3071

	
3060 3072
        (*_blossom_data)[blossom].status = EVEN;
3061 3073
        (*_blossom_data)[blossom].pred = INVALID;
3062 3074
        (*_blossom_data)[blossom].next = INVALID;
3063 3075
        (*_blossom_data)[blossom].pot = 0;
3064 3076
        (*_blossom_data)[blossom].offset = 0;
3065 3077
        ++index;
3066 3078
      }
3067 3079
      for (EdgeIt e(_graph); e != INVALID; ++e) {
3068 3080
        int si = (*_node_index)[_graph.u(e)];
3069 3081
        int ti = (*_node_index)[_graph.v(e)];
3070 3082
        if (_graph.u(e) != _graph.v(e)) {
3071 3083
          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
3072 3084
                            dualScale * _weight[e]) / 2);
3073 3085
        }
3074 3086
      }
3075 3087
    }
3076 3088

	
3077 3089
    /// \brief Initialize the algorithm with fractional matching
3078 3090
    ///
3079 3091
    /// This function initializes the algorithm with a fractional
3080 3092
    /// matching. This initialization is also called jumpstart heuristic.
3081 3093
    void fractionalInit() {
3082 3094
      createStructures();
3095

	
3096
      _blossom_node_list.clear();
3097
      _blossom_potential.clear();
3083 3098
      
3084 3099
      if (_fractional == 0) {
3085 3100
        _fractional = new FractionalMatching(_graph, _weight, false);
3086 3101
      }
3087 3102
      if (!_fractional->run()) {
3088 3103
        _unmatched = -1;
3089 3104
        return;
3090 3105
      }
3091 3106

	
3092 3107
      for (ArcIt e(_graph); e != INVALID; ++e) {
3093 3108
        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
3094 3109
      }
3095 3110
      for (EdgeIt e(_graph); e != INVALID; ++e) {
3096 3111
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
3097 3112
      }
3098 3113
      for (int i = 0; i < _blossom_num; ++i) {
3099 3114
        (*_delta2_index)[i] = _delta2->PRE_HEAP;
3100 3115
        (*_delta4_index)[i] = _delta4->PRE_HEAP;
3101 3116
      }
3102 3117

	
3103 3118
      _unmatched = 0;
3104 3119

	
3120
      _delta2->clear();
3121
      _delta3->clear();
3122
      _delta4->clear();
3123
      _blossom_set->clear();
3124
      _tree_set->clear();
3125

	
3105 3126
      int index = 0;
3106 3127
      for (NodeIt n(_graph); n != INVALID; ++n) {
3107 3128
        Value pot = _fractional->nodeValue(n);
3108 3129
        (*_node_index)[n] = index;
3109 3130
        (*_node_data)[index].pot = pot;
3131
        (*_node_data)[index].heap_index.clear();
3132
        (*_node_data)[index].heap.clear();
3110 3133
        int blossom =
3111 3134
          _blossom_set->insert(n, std::numeric_limits<Value>::max());
3112 3135

	
3113 3136
        (*_blossom_data)[blossom].status = MATCHED;
3114 3137
        (*_blossom_data)[blossom].pred = INVALID;
3115 3138
        (*_blossom_data)[blossom].next = _fractional->matching(n);
3116 3139
        (*_blossom_data)[blossom].pot = 0;
3117 3140
        (*_blossom_data)[blossom].offset = 0;
3118 3141
        ++index;
3119 3142
      }
3120 3143

	
3121 3144
      typename Graph::template NodeMap<bool> processed(_graph, false);
3122 3145
      for (NodeIt n(_graph); n != INVALID; ++n) {
3123 3146
        if (processed[n]) continue;
3124 3147
        processed[n] = true;
3125 3148
        if (_fractional->matching(n) == INVALID) continue;
3126 3149
        int num = 1;
3127 3150
        Node v = _graph.target(_fractional->matching(n));
3128 3151
        while (n != v) {
3129 3152
          processed[v] = true;
3130 3153
          v = _graph.target(_fractional->matching(v));
3131 3154
          ++num;
3132 3155
        }
3133 3156

	
3134 3157
        if (num % 2 == 1) {
3135 3158
          std::vector<int> subblossoms(num);
3136 3159

	
3137 3160
          subblossoms[--num] = _blossom_set->find(n);
3138 3161
          v = _graph.target(_fractional->matching(n));
3139 3162
          while (n != v) {
3140 3163
            subblossoms[--num] = _blossom_set->find(v);
3141 3164
            v = _graph.target(_fractional->matching(v));            
3142 3165
          }
3143 3166
          
3144 3167
          int surface = 
3145 3168
            _blossom_set->join(subblossoms.begin(), subblossoms.end());
3146 3169
          (*_blossom_data)[surface].status = EVEN;
3147 3170
          (*_blossom_data)[surface].pred = INVALID;
3148 3171
          (*_blossom_data)[surface].next = INVALID;
3149 3172
          (*_blossom_data)[surface].pot = 0;
3150 3173
          (*_blossom_data)[surface].offset = 0;
3151 3174
          
3152 3175
          _tree_set->insert(surface);
3153 3176
          ++_unmatched;
3154 3177
        }
3155 3178
      }
3156 3179

	
3157 3180
      for (EdgeIt e(_graph); e != INVALID; ++e) {
3158 3181
        int si = (*_node_index)[_graph.u(e)];
3159 3182
        int sb = _blossom_set->find(_graph.u(e));
3160 3183
        int ti = (*_node_index)[_graph.v(e)];
3161 3184
        int tb = _blossom_set->find(_graph.v(e));
3162 3185
        if ((*_blossom_data)[sb].status == EVEN &&
3163 3186
            (*_blossom_data)[tb].status == EVEN && sb != tb) {
3164 3187
          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
3165 3188
                            dualScale * _weight[e]) / 2);
3166 3189
        }
3167 3190
      }
3168 3191

	
3169 3192
      for (NodeIt n(_graph); n != INVALID; ++n) {
3170 3193
        int nb = _blossom_set->find(n);
3171 3194
        if ((*_blossom_data)[nb].status != MATCHED) continue;
3172 3195
        int ni = (*_node_index)[n];
3173 3196

	
3174 3197
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
3175 3198
          Node v = _graph.target(e);
3176 3199
          int vb = _blossom_set->find(v);
3177 3200
          int vi = (*_node_index)[v];
3178 3201

	
3179 3202
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
3180 3203
            dualScale * _weight[e];
3181 3204

	
3182 3205
          if ((*_blossom_data)[vb].status == EVEN) {
3183 3206

	
3184 3207
            int vt = _tree_set->find(vb);
3185 3208

	
3186 3209
            typename std::map<int, Arc>::iterator it =
3187 3210
              (*_node_data)[ni].heap_index.find(vt);
3188 3211

	
3189 3212
            if (it != (*_node_data)[ni].heap_index.end()) {
3190 3213
              if ((*_node_data)[ni].heap[it->second] > rw) {
3191 3214
                (*_node_data)[ni].heap.replace(it->second, e);
3192 3215
                (*_node_data)[ni].heap.decrease(e, rw);
3193 3216
                it->second = e;
3194 3217
              }
3195 3218
            } else {
3196 3219
              (*_node_data)[ni].heap.push(e, rw);
3197 3220
              (*_node_data)[ni].heap_index.insert(std::make_pair(vt, e));
3198 3221
            }
3199 3222
          }
3200 3223
        }
3201 3224
            
3202 3225
        if (!(*_node_data)[ni].heap.empty()) {
3203 3226
          _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
3204 3227
          _delta2->push(nb, _blossom_set->classPrio(nb));
3205 3228
        }
0 comments (0 inline)