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 384 line context
... ...
@@ -977,384 +977,389 @@
977 977
      int right_tree = _tree_set->find(right);
978 978

	
979 979
      alternatePath(right, right_tree);
980 980
      destroyTree(right_tree);
981 981
      _matching->set(right, _graph.direct(edge, false));
982 982
    }
983 983

	
984 984
    void augmentOnArc(const Arc& arc) {
985 985
      Node left = _graph.source(arc);
986 986
      _status->set(left, MATCHED);
987 987
      _matching->set(left, arc);
988 988
      _pred->set(left, arc);
989 989

	
990 990
      Node right = _graph.target(arc);
991 991
      int right_tree = _tree_set->find(right);
992 992

	
993 993
      alternatePath(right, right_tree);
994 994
      destroyTree(right_tree);
995 995
      _matching->set(right, _graph.oppositeArc(arc));
996 996
    }
997 997

	
998 998
    void extendOnArc(const Arc& arc) {
999 999
      Node base = _graph.target(arc);
1000 1000
      int tree = _tree_set->find(base);
1001 1001

	
1002 1002
      Node odd = _graph.source(arc);
1003 1003
      _tree_set->insert(odd, tree);
1004 1004
      _status->set(odd, ODD);
1005 1005
      matchedToOdd(odd, tree);
1006 1006
      _pred->set(odd, arc);
1007 1007

	
1008 1008
      Node even = _graph.target((*_matching)[odd]);
1009 1009
      _tree_set->insert(even, tree);
1010 1010
      _status->set(even, EVEN);
1011 1011
      matchedToEven(even, tree);
1012 1012
    }
1013 1013

	
1014 1014
    void cycleOnEdge(const Edge& edge, int tree) {
1015 1015
      Node nca = INVALID;
1016 1016
      std::vector<Node> left_path, right_path;
1017 1017

	
1018 1018
      {
1019 1019
        std::set<Node> left_set, right_set;
1020 1020
        Node left = _graph.u(edge);
1021 1021
        left_path.push_back(left);
1022 1022
        left_set.insert(left);
1023 1023

	
1024 1024
        Node right = _graph.v(edge);
1025 1025
        right_path.push_back(right);
1026 1026
        right_set.insert(right);
1027 1027

	
1028 1028
        while (true) {
1029 1029

	
1030 1030
          if (left_set.find(right) != left_set.end()) {
1031 1031
            nca = right;
1032 1032
            break;
1033 1033
          }
1034 1034

	
1035 1035
          if ((*_matching)[left] == INVALID) break;
1036 1036

	
1037 1037
          left = _graph.target((*_matching)[left]);
1038 1038
          left_path.push_back(left);
1039 1039
          left = _graph.target((*_pred)[left]);
1040 1040
          left_path.push_back(left);
1041 1041

	
1042 1042
          left_set.insert(left);
1043 1043

	
1044 1044
          if (right_set.find(left) != right_set.end()) {
1045 1045
            nca = left;
1046 1046
            break;
1047 1047
          }
1048 1048

	
1049 1049
          if ((*_matching)[right] == INVALID) break;
1050 1050

	
1051 1051
          right = _graph.target((*_matching)[right]);
1052 1052
          right_path.push_back(right);
1053 1053
          right = _graph.target((*_pred)[right]);
1054 1054
          right_path.push_back(right);
1055 1055

	
1056 1056
          right_set.insert(right);
1057 1057

	
1058 1058
        }
1059 1059

	
1060 1060
        if (nca == INVALID) {
1061 1061
          if ((*_matching)[left] == INVALID) {
1062 1062
            nca = right;
1063 1063
            while (left_set.find(nca) == left_set.end()) {
1064 1064
              nca = _graph.target((*_matching)[nca]);
1065 1065
              right_path.push_back(nca);
1066 1066
              nca = _graph.target((*_pred)[nca]);
1067 1067
              right_path.push_back(nca);
1068 1068
            }
1069 1069
          } else {
1070 1070
            nca = left;
1071 1071
            while (right_set.find(nca) == right_set.end()) {
1072 1072
              nca = _graph.target((*_matching)[nca]);
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;
1265 1270
        }
1266 1271
      }
1267 1272
    }
1268 1273

	
1269 1274
    /// \brief Run the algorithm.
1270 1275
    ///
1271 1276
    /// This method runs the \c %MaxWeightedFractionalMatching algorithm.
1272 1277
    ///
1273 1278
    /// \note mwfm.run() is just a shortcut of the following code.
1274 1279
    /// \code
1275 1280
    ///   mwfm.init();
1276 1281
    ///   mwfm.start();
1277 1282
    /// \endcode
1278 1283
    void run() {
1279 1284
      init();
1280 1285
      start();
1281 1286
    }
1282 1287

	
1283 1288
    /// @}
1284 1289

	
1285 1290
    /// \name Primal Solution
1286 1291
    /// Functions to get the primal solution, i.e. the maximum weighted
1287 1292
    /// matching.\n
1288 1293
    /// Either \ref run() or \ref start() function should be called before
1289 1294
    /// using them.
1290 1295

	
1291 1296
    /// @{
1292 1297

	
1293 1298
    /// \brief Return the weight of the matching.
1294 1299
    ///
1295 1300
    /// This function returns the weight of the found matching. This
1296 1301
    /// value is scaled by \ref primalScale "primal scale".
1297 1302
    ///
1298 1303
    /// \pre Either run() or start() must be called before using this function.
1299 1304
    Value matchingWeight() const {
1300 1305
      Value sum = 0;
1301 1306
      for (NodeIt n(_graph); n != INVALID; ++n) {
1302 1307
        if ((*_matching)[n] != INVALID) {
1303 1308
          sum += _weight[(*_matching)[n]];
1304 1309
        }
1305 1310
      }
1306 1311
      return sum * primalScale / 2;
1307 1312
    }
1308 1313

	
1309 1314
    /// \brief Return the number of covered nodes in the matching.
1310 1315
    ///
1311 1316
    /// This function returns the number of covered nodes in the matching.
1312 1317
    ///
1313 1318
    /// \pre Either run() or start() must be called before using this function.
1314 1319
    int matchingSize() const {
1315 1320
      int num = 0;
1316 1321
      for (NodeIt n(_graph); n != INVALID; ++n) {
1317 1322
        if ((*_matching)[n] != INVALID) {
1318 1323
          ++num;
1319 1324
        }
1320 1325
      }
1321 1326
      return num;
1322 1327
    }
1323 1328

	
1324 1329
    /// \brief Return \c true if the given edge is in the matching.
1325 1330
    ///
1326 1331
    /// This function returns \c true if the given edge is in the
1327 1332
    /// found matching. The result is scaled by \ref primalScale
1328 1333
    /// "primal scale".
1329 1334
    ///
1330 1335
    /// \pre Either run() or start() must be called before using this function.
1331 1336
    int matching(const Edge& edge) const {
1332 1337
      return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0)
1333 1338
        + (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
1334 1339
    }
1335 1340

	
1336 1341
    /// \brief Return the fractional matching arc (or edge) incident
1337 1342
    /// to the given node.
1338 1343
    ///
1339 1344
    /// This function returns one of the fractional matching arc (or
1340 1345
    /// edge) incident to the given node in the found matching or \c
1341 1346
    /// INVALID if the node is not covered by the matching or if the
1342 1347
    /// node is on an odd length cycle then it is the successor edge
1343 1348
    /// on the cycle.
1344 1349
    ///
1345 1350
    /// \pre Either run() or start() must be called before using this function.
1346 1351
    Arc matching(const Node& node) const {
1347 1352
      return (*_matching)[node];
1348 1353
    }
1349 1354

	
1350 1355
    /// \brief Return a const reference to the matching map.
1351 1356
    ///
1352 1357
    /// This function returns a const reference to a node map that stores
1353 1358
    /// the matching arc (or edge) incident to each node.
1354 1359
    const MatchingMap& matchingMap() const {
1355 1360
      return *_matching;
1356 1361
    }
1357 1362

	
1358 1363
    /// @}
1359 1364

	
1360 1365
    /// \name Dual Solution
... ...
@@ -1716,384 +1721,388 @@
1716 1721
      Node right = _graph.v(edge);
1717 1722
      int right_tree = _tree_set->find(right);
1718 1723

	
1719 1724
      alternatePath(right, right_tree);
1720 1725
      destroyTree(right_tree);
1721 1726
      _matching->set(right, _graph.direct(edge, false));
1722 1727
    }
1723 1728

	
1724 1729
    void augmentOnArc(const Arc& arc) {
1725 1730
      Node left = _graph.source(arc);
1726 1731
      _status->set(left, MATCHED);
1727 1732
      _matching->set(left, arc);
1728 1733
      _pred->set(left, arc);
1729 1734

	
1730 1735
      Node right = _graph.target(arc);
1731 1736
      int right_tree = _tree_set->find(right);
1732 1737

	
1733 1738
      alternatePath(right, right_tree);
1734 1739
      destroyTree(right_tree);
1735 1740
      _matching->set(right, _graph.oppositeArc(arc));
1736 1741
    }
1737 1742

	
1738 1743
    void extendOnArc(const Arc& arc) {
1739 1744
      Node base = _graph.target(arc);
1740 1745
      int tree = _tree_set->find(base);
1741 1746

	
1742 1747
      Node odd = _graph.source(arc);
1743 1748
      _tree_set->insert(odd, tree);
1744 1749
      _status->set(odd, ODD);
1745 1750
      matchedToOdd(odd, tree);
1746 1751
      _pred->set(odd, arc);
1747 1752

	
1748 1753
      Node even = _graph.target((*_matching)[odd]);
1749 1754
      _tree_set->insert(even, tree);
1750 1755
      _status->set(even, EVEN);
1751 1756
      matchedToEven(even, tree);
1752 1757
    }
1753 1758

	
1754 1759
    void cycleOnEdge(const Edge& edge, int tree) {
1755 1760
      Node nca = INVALID;
1756 1761
      std::vector<Node> left_path, right_path;
1757 1762

	
1758 1763
      {
1759 1764
        std::set<Node> left_set, right_set;
1760 1765
        Node left = _graph.u(edge);
1761 1766
        left_path.push_back(left);
1762 1767
        left_set.insert(left);
1763 1768

	
1764 1769
        Node right = _graph.v(edge);
1765 1770
        right_path.push_back(right);
1766 1771
        right_set.insert(right);
1767 1772

	
1768 1773
        while (true) {
1769 1774

	
1770 1775
          if (left_set.find(right) != left_set.end()) {
1771 1776
            nca = right;
1772 1777
            break;
1773 1778
          }
1774 1779

	
1775 1780
          if ((*_matching)[left] == INVALID) break;
1776 1781

	
1777 1782
          left = _graph.target((*_matching)[left]);
1778 1783
          left_path.push_back(left);
1779 1784
          left = _graph.target((*_pred)[left]);
1780 1785
          left_path.push_back(left);
1781 1786

	
1782 1787
          left_set.insert(left);
1783 1788

	
1784 1789
          if (right_set.find(left) != right_set.end()) {
1785 1790
            nca = left;
1786 1791
            break;
1787 1792
          }
1788 1793

	
1789 1794
          if ((*_matching)[right] == INVALID) break;
1790 1795

	
1791 1796
          right = _graph.target((*_matching)[right]);
1792 1797
          right_path.push_back(right);
1793 1798
          right = _graph.target((*_pred)[right]);
1794 1799
          right_path.push_back(right);
1795 1800

	
1796 1801
          right_set.insert(right);
1797 1802

	
1798 1803
        }
1799 1804

	
1800 1805
        if (nca == INVALID) {
1801 1806
          if ((*_matching)[left] == INVALID) {
1802 1807
            nca = right;
1803 1808
            while (left_set.find(nca) == left_set.end()) {
1804 1809
              nca = _graph.target((*_matching)[nca]);
1805 1810
              right_path.push_back(nca);
1806 1811
              nca = _graph.target((*_pred)[nca]);
1807 1812
              right_path.push_back(nca);
1808 1813
            }
1809 1814
          } else {
1810 1815
            nca = left;
1811 1816
            while (right_set.find(nca) == right_set.end()) {
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 
2004 2013
    /// algorithm.
2005 2014
    ///
2006 2015
    /// \note mwfm.run() is just a shortcut of the following code.
2007 2016
    /// \code
2008 2017
    ///   mwpfm.init();
2009 2018
    ///   mwpfm.start();
2010 2019
    /// \endcode
2011 2020
    bool run() {
2012 2021
      init();
2013 2022
      return start();
2014 2023
    }
2015 2024

	
2016 2025
    /// @}
2017 2026

	
2018 2027
    /// \name Primal Solution
2019 2028
    /// Functions to get the primal solution, i.e. the maximum weighted
2020 2029
    /// matching.\n
2021 2030
    /// Either \ref run() or \ref start() function should be called before
2022 2031
    /// using them.
2023 2032

	
2024 2033
    /// @{
2025 2034

	
2026 2035
    /// \brief Return the weight of the matching.
2027 2036
    ///
2028 2037
    /// This function returns the weight of the found matching. This
2029 2038
    /// value is scaled by \ref primalScale "primal scale".
2030 2039
    ///
2031 2040
    /// \pre Either run() or start() must be called before using this function.
2032 2041
    Value matchingWeight() const {
2033 2042
      Value sum = 0;
2034 2043
      for (NodeIt n(_graph); n != INVALID; ++n) {
2035 2044
        if ((*_matching)[n] != INVALID) {
2036 2045
          sum += _weight[(*_matching)[n]];
2037 2046
        }
2038 2047
      }
2039 2048
      return sum * primalScale / 2;
2040 2049
    }
2041 2050

	
2042 2051
    /// \brief Return the number of covered nodes in the matching.
2043 2052
    ///
2044 2053
    /// This function returns the number of covered nodes in the matching.
2045 2054
    ///
2046 2055
    /// \pre Either run() or start() must be called before using this function.
2047 2056
    int matchingSize() const {
2048 2057
      int num = 0;
2049 2058
      for (NodeIt n(_graph); n != INVALID; ++n) {
2050 2059
        if ((*_matching)[n] != INVALID) {
2051 2060
          ++num;
2052 2061
        }
2053 2062
      }
2054 2063
      return num;
2055 2064
    }
2056 2065

	
2057 2066
    /// \brief Return \c true if the given edge is in the matching.
2058 2067
    ///
2059 2068
    /// This function returns \c true if the given edge is in the
2060 2069
    /// found matching. The result is scaled by \ref primalScale
2061 2070
    /// "primal scale".
2062 2071
    ///
2063 2072
    /// \pre Either run() or start() must be called before using this function.
2064 2073
    int matching(const Edge& edge) const {
2065 2074
      return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0)
2066 2075
        + (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
2067 2076
    }
2068 2077

	
2069 2078
    /// \brief Return the fractional matching arc (or edge) incident
2070 2079
    /// to the given node.
2071 2080
    ///
2072 2081
    /// This function returns one of the fractional matching arc (or
2073 2082
    /// edge) incident to the given node in the found matching or \c
2074 2083
    /// INVALID if the node is not covered by the matching or if the
2075 2084
    /// node is on an odd length cycle then it is the successor edge
2076 2085
    /// on the cycle.
2077 2086
    ///
2078 2087
    /// \pre Either run() or start() must be called before using this function.
2079 2088
    Arc matching(const Node& node) const {
2080 2089
      return (*_matching)[node];
2081 2090
    }
2082 2091

	
2083 2092
    /// \brief Return a const reference to the matching map.
2084 2093
    ///
2085 2094
    /// This function returns a const reference to a node map that stores
2086 2095
    /// the matching arc (or edge) incident to each node.
2087 2096
    const MatchingMap& matchingMap() const {
2088 2097
      return *_matching;
2089 2098
    }
2090 2099

	
2091 2100
    /// @}
2092 2101

	
2093 2102
    /// \name Dual Solution
2094 2103
    /// Functions to get the dual solution.\n
2095 2104
    /// Either \ref run() or \ref start() function should be called before
2096 2105
    /// using them.
2097 2106

	
2098 2107
    /// @{
2099 2108

	
Ignore white space 384 line context
... ...
@@ -1486,411 +1486,423 @@
1486 1486
          (*_blossom_data)[tb].status = EVEN;
1487 1487
          matchedToEven(tb, tree);
1488 1488
          _tree_set->insert(tb, tree);
1489 1489
          (*_blossom_data)[tb].pred =
1490 1490
            (*_blossom_data)[tb].next =
1491 1491
            _graph.oppositeArc((*_blossom_data)[ub].next);
1492 1492
          next = (*_blossom_data)[ub].next;
1493 1493
        }
1494 1494

	
1495 1495
        (*_blossom_data)[subblossoms[ib]].status = ODD;
1496 1496
        matchedToOdd(subblossoms[ib]);
1497 1497
        _tree_set->insert(subblossoms[ib], tree);
1498 1498
        (*_blossom_data)[subblossoms[ib]].next = next;
1499 1499
        (*_blossom_data)[subblossoms[ib]].pred = pred;
1500 1500
      }
1501 1501
      _tree_set->erase(blossom);
1502 1502
    }
1503 1503

	
1504 1504
    void extractBlossom(int blossom, const Node& base, const Arc& matching) {
1505 1505
      if (_blossom_set->trivial(blossom)) {
1506 1506
        int bi = (*_node_index)[base];
1507 1507
        Value pot = (*_node_data)[bi].pot;
1508 1508

	
1509 1509
        (*_matching)[base] = matching;
1510 1510
        _blossom_node_list.push_back(base);
1511 1511
        (*_node_potential)[base] = pot;
1512 1512
      } else {
1513 1513

	
1514 1514
        Value pot = (*_blossom_data)[blossom].pot;
1515 1515
        int bn = _blossom_node_list.size();
1516 1516

	
1517 1517
        std::vector<int> subblossoms;
1518 1518
        _blossom_set->split(blossom, std::back_inserter(subblossoms));
1519 1519
        int b = _blossom_set->find(base);
1520 1520
        int ib = -1;
1521 1521
        for (int i = 0; i < int(subblossoms.size()); ++i) {
1522 1522
          if (subblossoms[i] == b) { ib = i; break; }
1523 1523
        }
1524 1524

	
1525 1525
        for (int i = 1; i < int(subblossoms.size()); i += 2) {
1526 1526
          int sb = subblossoms[(ib + i) % subblossoms.size()];
1527 1527
          int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
1528 1528

	
1529 1529
          Arc m = (*_blossom_data)[tb].next;
1530 1530
          extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
1531 1531
          extractBlossom(tb, _graph.source(m), m);
1532 1532
        }
1533 1533
        extractBlossom(subblossoms[ib], base, matching);
1534 1534

	
1535 1535
        int en = _blossom_node_list.size();
1536 1536

	
1537 1537
        _blossom_potential.push_back(BlossomVariable(bn, en, pot));
1538 1538
      }
1539 1539
    }
1540 1540

	
1541 1541
    void extractMatching() {
1542 1542
      std::vector<int> blossoms;
1543 1543
      for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
1544 1544
        blossoms.push_back(c);
1545 1545
      }
1546 1546

	
1547 1547
      for (int i = 0; i < int(blossoms.size()); ++i) {
1548 1548
        if ((*_blossom_data)[blossoms[i]].next != INVALID) {
1549 1549

	
1550 1550
          Value offset = (*_blossom_data)[blossoms[i]].offset;
1551 1551
          (*_blossom_data)[blossoms[i]].pot += 2 * offset;
1552 1552
          for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
1553 1553
               n != INVALID; ++n) {
1554 1554
            (*_node_data)[(*_node_index)[n]].pot -= offset;
1555 1555
          }
1556 1556

	
1557 1557
          Arc matching = (*_blossom_data)[blossoms[i]].next;
1558 1558
          Node base = _graph.source(matching);
1559 1559
          extractBlossom(blossoms[i], base, matching);
1560 1560
        } else {
1561 1561
          Node base = (*_blossom_data)[blossoms[i]].base;
1562 1562
          extractBlossom(blossoms[i], base, INVALID);
1563 1563
        }
1564 1564
      }
1565 1565
    }
1566 1566

	
1567 1567
  public:
1568 1568

	
1569 1569
    /// \brief Constructor
1570 1570
    ///
1571 1571
    /// Constructor.
1572 1572
    MaxWeightedMatching(const Graph& graph, const WeightMap& weight)
1573 1573
      : _graph(graph), _weight(weight), _matching(0),
1574 1574
        _node_potential(0), _blossom_potential(), _blossom_node_list(),
1575 1575
        _node_num(0), _blossom_num(0),
1576 1576

	
1577 1577
        _blossom_index(0), _blossom_set(0), _blossom_data(0),
1578 1578
        _node_index(0), _node_heap_index(0), _node_data(0),
1579 1579
        _tree_set_index(0), _tree_set(0),
1580 1580

	
1581 1581
        _delta1_index(0), _delta1(0),
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
        }
1801 1813
            
1802 1814
        if (!(*_node_data)[ni].heap.empty()) {
1803 1815
          _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
1804 1816
          _delta2->push(nb, _blossom_set->classPrio(nb));
1805 1817
        }
1806 1818
      }
1807 1819
    }
1808 1820

	
1809 1821
    /// \brief Start the algorithm
1810 1822
    ///
1811 1823
    /// This function starts the algorithm.
1812 1824
    ///
1813 1825
    /// \pre \ref init() or \ref fractionalInit() must be called
1814 1826
    /// before using this function.
1815 1827
    void start() {
1816 1828
      enum OpType {
1817 1829
        D1, D2, D3, D4
1818 1830
      };
1819 1831

	
1820 1832
      while (_unmatched > 0) {
1821 1833
        Value d1 = !_delta1->empty() ?
1822 1834
          _delta1->prio() : std::numeric_limits<Value>::max();
1823 1835

	
1824 1836
        Value d2 = !_delta2->empty() ?
1825 1837
          _delta2->prio() : std::numeric_limits<Value>::max();
1826 1838

	
1827 1839
        Value d3 = !_delta3->empty() ?
1828 1840
          _delta3->prio() : std::numeric_limits<Value>::max();
1829 1841

	
1830 1842
        Value d4 = !_delta4->empty() ?
1831 1843
          _delta4->prio() : std::numeric_limits<Value>::max();
1832 1844

	
1833 1845
        _delta_sum = d3; OpType ot = D3;
1834 1846
        if (d1 < _delta_sum) { _delta_sum = d1; ot = D1; }
1835 1847
        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
1836 1848
        if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
1837 1849

	
1838 1850
        switch (ot) {
1839 1851
        case D1:
1840 1852
          {
1841 1853
            Node n = _delta1->top();
1842 1854
            unmatchNode(n);
1843 1855
            --_unmatched;
1844 1856
          }
1845 1857
          break;
1846 1858
        case D2:
1847 1859
          {
1848 1860
            int blossom = _delta2->top();
1849 1861
            Node n = _blossom_set->classTop(blossom);
1850 1862
            Arc a = (*_node_data)[(*_node_index)[n]].heap.top();
1851 1863
            if ((*_blossom_data)[blossom].next == INVALID) {
1852 1864
              augmentOnArc(a);
1853 1865
              --_unmatched;
1854 1866
            } else {
1855 1867
              extendOnArc(a);
1856 1868
            }
1857 1869
          }
1858 1870
          break;
1859 1871
        case D3:
1860 1872
          {
1861 1873
            Edge e = _delta3->top();
1862 1874

	
1863 1875
            int left_blossom = _blossom_set->find(_graph.u(e));
1864 1876
            int right_blossom = _blossom_set->find(_graph.v(e));
1865 1877

	
1866 1878
            if (left_blossom == right_blossom) {
1867 1879
              _delta3->pop();
1868 1880
            } else {
1869 1881
              int left_tree = _tree_set->find(left_blossom);
1870 1882
              int right_tree = _tree_set->find(right_blossom);
1871 1883

	
1872 1884
              if (left_tree == right_tree) {
1873 1885
                shrinkOnEdge(e, left_tree);
1874 1886
              } else {
1875 1887
                augmentOnEdge(e);
1876 1888
                _unmatched -= 2;
1877 1889
              }
1878 1890
            }
1879 1891
          } break;
1880 1892
        case D4:
1881 1893
          splitBlossom(_delta4->top());
1882 1894
          break;
1883 1895
        }
1884 1896
      }
1885 1897
      extractMatching();
1886 1898
    }
1887 1899

	
1888 1900
    /// \brief Run the algorithm.
1889 1901
    ///
1890 1902
    /// This method runs the \c %MaxWeightedMatching algorithm.
1891 1903
    ///
1892 1904
    /// \note mwm.run() is just a shortcut of the following code.
1893 1905
    /// \code
1894 1906
    ///   mwm.fractionalInit();
1895 1907
    ///   mwm.start();
1896 1908
    /// \endcode
... ...
@@ -2891,411 +2903,422 @@
2891 2903
          int sb = subblossoms[i];
2892 2904
          int tb = subblossoms[(i + 1) % subblossoms.size()];
2893 2905
          int ub = subblossoms[(i + 2) % subblossoms.size()];
2894 2906

	
2895 2907
          (*_blossom_data)[sb].status = ODD;
2896 2908
          matchedToOdd(sb);
2897 2909
          _tree_set->insert(sb, tree);
2898 2910
          (*_blossom_data)[sb].next = next;
2899 2911
          (*_blossom_data)[sb].pred =
2900 2912
            _graph.oppositeArc((*_blossom_data)[tb].next);
2901 2913

	
2902 2914
          (*_blossom_data)[tb].status = EVEN;
2903 2915
          matchedToEven(tb, tree);
2904 2916
          _tree_set->insert(tb, tree);
2905 2917
          (*_blossom_data)[tb].pred =
2906 2918
            (*_blossom_data)[tb].next =
2907 2919
            _graph.oppositeArc((*_blossom_data)[ub].next);
2908 2920
          next = (*_blossom_data)[ub].next;
2909 2921
        }
2910 2922

	
2911 2923
        (*_blossom_data)[subblossoms[ib]].status = ODD;
2912 2924
        matchedToOdd(subblossoms[ib]);
2913 2925
        _tree_set->insert(subblossoms[ib], tree);
2914 2926
        (*_blossom_data)[subblossoms[ib]].next = next;
2915 2927
        (*_blossom_data)[subblossoms[ib]].pred = pred;
2916 2928
      }
2917 2929
      _tree_set->erase(blossom);
2918 2930
    }
2919 2931

	
2920 2932
    void extractBlossom(int blossom, const Node& base, const Arc& matching) {
2921 2933
      if (_blossom_set->trivial(blossom)) {
2922 2934
        int bi = (*_node_index)[base];
2923 2935
        Value pot = (*_node_data)[bi].pot;
2924 2936

	
2925 2937
        (*_matching)[base] = matching;
2926 2938
        _blossom_node_list.push_back(base);
2927 2939
        (*_node_potential)[base] = pot;
2928 2940
      } else {
2929 2941

	
2930 2942
        Value pot = (*_blossom_data)[blossom].pot;
2931 2943
        int bn = _blossom_node_list.size();
2932 2944

	
2933 2945
        std::vector<int> subblossoms;
2934 2946
        _blossom_set->split(blossom, std::back_inserter(subblossoms));
2935 2947
        int b = _blossom_set->find(base);
2936 2948
        int ib = -1;
2937 2949
        for (int i = 0; i < int(subblossoms.size()); ++i) {
2938 2950
          if (subblossoms[i] == b) { ib = i; break; }
2939 2951
        }
2940 2952

	
2941 2953
        for (int i = 1; i < int(subblossoms.size()); i += 2) {
2942 2954
          int sb = subblossoms[(ib + i) % subblossoms.size()];
2943 2955
          int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
2944 2956

	
2945 2957
          Arc m = (*_blossom_data)[tb].next;
2946 2958
          extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
2947 2959
          extractBlossom(tb, _graph.source(m), m);
2948 2960
        }
2949 2961
        extractBlossom(subblossoms[ib], base, matching);
2950 2962

	
2951 2963
        int en = _blossom_node_list.size();
2952 2964

	
2953 2965
        _blossom_potential.push_back(BlossomVariable(bn, en, pot));
2954 2966
      }
2955 2967
    }
2956 2968

	
2957 2969
    void extractMatching() {
2958 2970
      std::vector<int> blossoms;
2959 2971
      for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
2960 2972
        blossoms.push_back(c);
2961 2973
      }
2962 2974

	
2963 2975
      for (int i = 0; i < int(blossoms.size()); ++i) {
2964 2976

	
2965 2977
        Value offset = (*_blossom_data)[blossoms[i]].offset;
2966 2978
        (*_blossom_data)[blossoms[i]].pot += 2 * offset;
2967 2979
        for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
2968 2980
             n != INVALID; ++n) {
2969 2981
          (*_node_data)[(*_node_index)[n]].pot -= offset;
2970 2982
        }
2971 2983

	
2972 2984
        Arc matching = (*_blossom_data)[blossoms[i]].next;
2973 2985
        Node base = _graph.source(matching);
2974 2986
        extractBlossom(blossoms[i], base, matching);
2975 2987
      }
2976 2988
    }
2977 2989

	
2978 2990
  public:
2979 2991

	
2980 2992
    /// \brief Constructor
2981 2993
    ///
2982 2994
    /// Constructor.
2983 2995
    MaxWeightedPerfectMatching(const Graph& graph, const WeightMap& weight)
2984 2996
      : _graph(graph), _weight(weight), _matching(0),
2985 2997
        _node_potential(0), _blossom_potential(), _blossom_node_list(),
2986 2998
        _node_num(0), _blossom_num(0),
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
        }
3206 3229
      }
3207 3230
    }
3208 3231

	
3209 3232
    /// \brief Start the algorithm
3210 3233
    ///
3211 3234
    /// This function starts the algorithm.
3212 3235
    ///
3213 3236
    /// \pre \ref init() or \ref fractionalInit() must be called before
3214 3237
    /// using this function.
3215 3238
    bool start() {
3216 3239
      enum OpType {
3217 3240
        D2, D3, D4
3218 3241
      };
3219 3242

	
3220 3243
      if (_unmatched == -1) return false;
3221 3244

	
3222 3245
      while (_unmatched > 0) {
3223 3246
        Value d2 = !_delta2->empty() ?
3224 3247
          _delta2->prio() : std::numeric_limits<Value>::max();
3225 3248

	
3226 3249
        Value d3 = !_delta3->empty() ?
3227 3250
          _delta3->prio() : std::numeric_limits<Value>::max();
3228 3251

	
3229 3252
        Value d4 = !_delta4->empty() ?
3230 3253
          _delta4->prio() : std::numeric_limits<Value>::max();
3231 3254

	
3232 3255
        _delta_sum = d3; OpType ot = D3;
3233 3256
        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
3234 3257
        if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
3235 3258

	
3236 3259
        if (_delta_sum == std::numeric_limits<Value>::max()) {
3237 3260
          return false;
3238 3261
        }
3239 3262

	
3240 3263
        switch (ot) {
3241 3264
        case D2:
3242 3265
          {
3243 3266
            int blossom = _delta2->top();
3244 3267
            Node n = _blossom_set->classTop(blossom);
3245 3268
            Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
3246 3269
            extendOnArc(e);
3247 3270
          }
3248 3271
          break;
3249 3272
        case D3:
3250 3273
          {
3251 3274
            Edge e = _delta3->top();
3252 3275

	
3253 3276
            int left_blossom = _blossom_set->find(_graph.u(e));
3254 3277
            int right_blossom = _blossom_set->find(_graph.v(e));
3255 3278

	
3256 3279
            if (left_blossom == right_blossom) {
3257 3280
              _delta3->pop();
3258 3281
            } else {
3259 3282
              int left_tree = _tree_set->find(left_blossom);
3260 3283
              int right_tree = _tree_set->find(right_blossom);
3261 3284

	
3262 3285
              if (left_tree == right_tree) {
3263 3286
                shrinkOnEdge(e, left_tree);
3264 3287
              } else {
3265 3288
                augmentOnEdge(e);
3266 3289
                _unmatched -= 2;
3267 3290
              }
3268 3291
            }
3269 3292
          } break;
3270 3293
        case D4:
3271 3294
          splitBlossom(_delta4->top());
3272 3295
          break;
3273 3296
        }
3274 3297
      }
3275 3298
      extractMatching();
3276 3299
      return true;
3277 3300
    }
3278 3301

	
3279 3302
    /// \brief Run the algorithm.
3280 3303
    ///
3281 3304
    /// This method runs the \c %MaxWeightedPerfectMatching algorithm.
3282 3305
    ///
3283 3306
    /// \note mwpm.run() is just a shortcut of the following code.
3284 3307
    /// \code
3285 3308
    ///   mwpm.fractionalInit();
3286 3309
    ///   mwpm.start();
3287 3310
    /// \endcode
3288 3311
    bool run() {
3289 3312
      fractionalInit();
3290 3313
      return start();
3291 3314
    }
3292 3315

	
3293 3316
    /// @}
3294 3317

	
3295 3318
    /// \name Primal Solution
3296 3319
    /// Functions to get the primal solution, i.e. the maximum weighted
3297 3320
    /// perfect matching.\n
3298 3321
    /// Either \ref run() or \ref start() function should be called before
3299 3322
    /// using them.
3300 3323

	
3301 3324
    /// @{
0 comments (0 inline)