gravatar
deba@inf.elte.hu
deba@inf.elte.hu
General improvements in weighted matching algorithms (#314) - Fix include guard - Uniform handling of MATCHED and UNMATCHED blossoms - Prefer operations which decrease the number of trees - Fix improper use of '/=' The solved problems did not cause wrong solution.
0 1 0
default
1 file changed with 38 insertions and 157 deletions:
↑ Collapse diff ↑
Show white space 24 line context
... ...
@@ -7,26 +7,26 @@
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19
#ifndef LEMON_MAX_MATCHING_H
20
#define LEMON_MAX_MATCHING_H
19
#ifndef LEMON_MATCHING_H
20
#define LEMON_MATCHING_H
21 21

	
22 22
#include <vector>
23 23
#include <queue>
24 24
#include <set>
25 25
#include <limits>
26 26

	
27 27
#include <lemon/core.h>
28 28
#include <lemon/unionfind.h>
29 29
#include <lemon/bin_heap.h>
30 30
#include <lemon/maps.h>
31 31

	
32 32
///\ingroup matching
... ...
@@ -736,25 +736,25 @@
736 736

	
737 737
    NodePotential* _node_potential;
738 738

	
739 739
    BlossomPotential _blossom_potential;
740 740
    BlossomNodeList _blossom_node_list;
741 741

	
742 742
    int _node_num;
743 743
    int _blossom_num;
744 744

	
745 745
    typedef RangeMap<int> IntIntMap;
746 746

	
747 747
    enum Status {
748
      EVEN = -1, MATCHED = 0, ODD = 1, UNMATCHED = -2
748
      EVEN = -1, MATCHED = 0, ODD = 1
749 749
    };
750 750

	
751 751
    typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
752 752
    struct BlossomData {
753 753
      int tree;
754 754
      Status status;
755 755
      Arc pred, next;
756 756
      Value pot, offset;
757 757
      Node base;
758 758
    };
759 759

	
760 760
    IntNodeMap *_blossom_index;
... ...
@@ -835,27 +835,24 @@
835 835
      }
836 836
      if (!_delta3) {
837 837
        _delta3_index = new IntEdgeMap(_graph);
838 838
        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
839 839
      }
840 840
      if (!_delta4) {
841 841
        _delta4_index = new IntIntMap(_blossom_num);
842 842
        _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
843 843
      }
844 844
    }
845 845

	
846 846
    void destroyStructures() {
847
      _node_num = countNodes(_graph);
848
      _blossom_num = _node_num * 3 / 2;
849

	
850 847
      if (_matching) {
851 848
        delete _matching;
852 849
      }
853 850
      if (_node_potential) {
854 851
        delete _node_potential;
855 852
      }
856 853
      if (_blossom_set) {
857 854
        delete _blossom_index;
858 855
        delete _blossom_set;
859 856
        delete _blossom_data;
860 857
      }
861 858

	
... ...
@@ -913,28 +910,24 @@
913 910
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
914 911
          Node v = _graph.source(e);
915 912
          int vb = _blossom_set->find(v);
916 913
          int vi = (*_node_index)[v];
917 914

	
918 915
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
919 916
            dualScale * _weight[e];
920 917

	
921 918
          if ((*_blossom_data)[vb].status == EVEN) {
922 919
            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
923 920
              _delta3->push(e, rw / 2);
924 921
            }
925
          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
926
            if (_delta3->state(e) != _delta3->IN_HEAP) {
927
              _delta3->push(e, rw);
928
            }
929 922
          } else {
930 923
            typename std::map<int, Arc>::iterator it =
931 924
              (*_node_data)[vi].heap_index.find(tree);
932 925

	
933 926
            if (it != (*_node_data)[vi].heap_index.end()) {
934 927
              if ((*_node_data)[vi].heap[it->second] > rw) {
935 928
                (*_node_data)[vi].heap.replace(it->second, e);
936 929
                (*_node_data)[vi].heap.decrease(e, rw);
937 930
                it->second = e;
938 931
              }
939 932
            } else {
940 933
              (*_node_data)[vi].heap.push(e, rw);
... ...
@@ -1027,29 +1020,24 @@
1027 1020

	
1028 1021
                if (_delta2->state(blossom) != _delta2->IN_HEAP) {
1029 1022
                  _delta2->push(blossom, _blossom_set->classPrio(blossom) -
1030 1023
                               (*_blossom_data)[blossom].offset);
1031 1024
                } else if ((*_delta2)[blossom] >
1032 1025
                           _blossom_set->classPrio(blossom) -
1033 1026
                           (*_blossom_data)[blossom].offset){
1034 1027
                  _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
1035 1028
                                   (*_blossom_data)[blossom].offset);
1036 1029
                }
1037 1030
              }
1038 1031
            }
1039

	
1040
          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
1041
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1042
              _delta3->erase(e);
1043
            }
1044 1032
          } else {
1045 1033

	
1046 1034
            typename std::map<int, Arc>::iterator it =
1047 1035
              (*_node_data)[vi].heap_index.find(tree);
1048 1036

	
1049 1037
            if (it != (*_node_data)[vi].heap_index.end()) {
1050 1038
              (*_node_data)[vi].heap.erase(it->second);
1051 1039
              (*_node_data)[vi].heap_index.erase(it);
1052 1040
              if ((*_node_data)[vi].heap.empty()) {
1053 1041
                _blossom_set->increase(v, std::numeric_limits<Value>::max());
1054 1042
              } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
1055 1043
                _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
... ...
@@ -1108,28 +1096,24 @@
1108 1096
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
1109 1097
          Node v = _graph.source(e);
1110 1098
          int vb = _blossom_set->find(v);
1111 1099
          int vi = (*_node_index)[v];
1112 1100

	
1113 1101
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
1114 1102
            dualScale * _weight[e];
1115 1103

	
1116 1104
          if ((*_blossom_data)[vb].status == EVEN) {
1117 1105
            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
1118 1106
              _delta3->push(e, rw / 2);
1119 1107
            }
1120
          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
1121
            if (_delta3->state(e) != _delta3->IN_HEAP) {
1122
              _delta3->push(e, rw);
1123
            }
1124 1108
          } else {
1125 1109

	
1126 1110
            typename std::map<int, Arc>::iterator it =
1127 1111
              (*_node_data)[vi].heap_index.find(tree);
1128 1112

	
1129 1113
            if (it != (*_node_data)[vi].heap_index.end()) {
1130 1114
              if ((*_node_data)[vi].heap[it->second] > rw) {
1131 1115
                (*_node_data)[vi].heap.replace(it->second, e);
1132 1116
                (*_node_data)[vi].heap.decrease(e, rw);
1133 1117
                it->second = e;
1134 1118
              }
1135 1119
            } else {
... ...
@@ -1148,119 +1132,24 @@
1148 1132
                           (*_blossom_data)[vb].offset) {
1149 1133
                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
1150 1134
                                   (*_blossom_data)[vb].offset);
1151 1135
                }
1152 1136
              }
1153 1137
            }
1154 1138
          }
1155 1139
        }
1156 1140
      }
1157 1141
      (*_blossom_data)[blossom].offset = 0;
1158 1142
    }
1159 1143

	
1160

	
1161
    void matchedToUnmatched(int blossom) {
1162
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
1163
        _delta2->erase(blossom);
1164
      }
1165

	
1166
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
1167
           n != INVALID; ++n) {
1168
        int ni = (*_node_index)[n];
1169

	
1170
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
1171

	
1172
        (*_node_data)[ni].heap.clear();
1173
        (*_node_data)[ni].heap_index.clear();
1174

	
1175
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
1176
          Node v = _graph.target(e);
1177
          int vb = _blossom_set->find(v);
1178
          int vi = (*_node_index)[v];
1179

	
1180
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
1181
            dualScale * _weight[e];
1182

	
1183
          if ((*_blossom_data)[vb].status == EVEN) {
1184
            if (_delta3->state(e) != _delta3->IN_HEAP) {
1185
              _delta3->push(e, rw);
1186
            }
1187
          }
1188
        }
1189
      }
1190
    }
1191

	
1192
    void unmatchedToMatched(int blossom) {
1193
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
1194
           n != INVALID; ++n) {
1195
        int ni = (*_node_index)[n];
1196

	
1197
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
1198
          Node v = _graph.source(e);
1199
          int vb = _blossom_set->find(v);
1200
          int vi = (*_node_index)[v];
1201

	
1202
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
1203
            dualScale * _weight[e];
1204

	
1205
          if (vb == blossom) {
1206
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1207
              _delta3->erase(e);
1208
            }
1209
          } else if ((*_blossom_data)[vb].status == EVEN) {
1210

	
1211
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1212
              _delta3->erase(e);
1213
            }
1214

	
1215
            int vt = _tree_set->find(vb);
1216

	
1217
            Arc r = _graph.oppositeArc(e);
1218

	
1219
            typename std::map<int, Arc>::iterator it =
1220
              (*_node_data)[ni].heap_index.find(vt);
1221

	
1222
            if (it != (*_node_data)[ni].heap_index.end()) {
1223
              if ((*_node_data)[ni].heap[it->second] > rw) {
1224
                (*_node_data)[ni].heap.replace(it->second, r);
1225
                (*_node_data)[ni].heap.decrease(r, rw);
1226
                it->second = r;
1227
              }
1228
            } else {
1229
              (*_node_data)[ni].heap.push(r, rw);
1230
              (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
1231
            }
1232

	
1233
            if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
1234
              _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
1235

	
1236
              if (_delta2->state(blossom) != _delta2->IN_HEAP) {
1237
                _delta2->push(blossom, _blossom_set->classPrio(blossom) -
1238
                             (*_blossom_data)[blossom].offset);
1239
              } else if ((*_delta2)[blossom] > _blossom_set->classPrio(blossom)-
1240
                         (*_blossom_data)[blossom].offset){
1241
                _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
1242
                                 (*_blossom_data)[blossom].offset);
1243
              }
1244
            }
1245

	
1246
          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
1247
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1248
              _delta3->erase(e);
1249
            }
1250
          }
1251
        }
1252
      }
1253
    }
1254

	
1255 1144
    void alternatePath(int even, int tree) {
1256 1145
      int odd;
1257 1146

	
1258 1147
      evenToMatched(even, tree);
1259 1148
      (*_blossom_data)[even].status = MATCHED;
1260 1149

	
1261 1150
      while ((*_blossom_data)[even].pred != INVALID) {
1262 1151
        odd = _blossom_set->find(_graph.target((*_blossom_data)[even].pred));
1263 1152
        (*_blossom_data)[odd].status = MATCHED;
1264 1153
        oddToMatched(odd);
1265 1154
        (*_blossom_data)[odd].next = (*_blossom_data)[odd].pred;
1266 1155

	
... ...
@@ -1285,57 +1174,60 @@
1285 1174
      }
1286 1175
      _tree_set->eraseClass(tree);
1287 1176
    }
1288 1177

	
1289 1178

	
1290 1179
    void unmatchNode(const Node& node) {
1291 1180
      int blossom = _blossom_set->find(node);
1292 1181
      int tree = _tree_set->find(blossom);
1293 1182

	
1294 1183
      alternatePath(blossom, tree);
1295 1184
      destroyTree(tree);
1296 1185

	
1297
      (*_blossom_data)[blossom].status = UNMATCHED;
1298 1186
      (*_blossom_data)[blossom].base = node;
1299
      matchedToUnmatched(blossom);
1300
    }
1301

	
1187
      (*_blossom_data)[blossom].next = INVALID;
1188
    }
1302 1189

	
1303 1190
    void augmentOnEdge(const Edge& edge) {
1304 1191

	
1305 1192
      int left = _blossom_set->find(_graph.u(edge));
1306 1193
      int right = _blossom_set->find(_graph.v(edge));
1307 1194

	
1308
      if ((*_blossom_data)[left].status == EVEN) {
1309 1195
        int left_tree = _tree_set->find(left);
1310 1196
        alternatePath(left, left_tree);
1311 1197
        destroyTree(left_tree);
1312
      } else {
1313
        (*_blossom_data)[left].status = MATCHED;
1314
        unmatchedToMatched(left);
1315
      }
1316

	
1317
      if ((*_blossom_data)[right].status == EVEN) {
1198

	
1318 1199
        int right_tree = _tree_set->find(right);
1319 1200
        alternatePath(right, right_tree);
1320 1201
        destroyTree(right_tree);
1321
      } else {
1322
        (*_blossom_data)[right].status = MATCHED;
1323
        unmatchedToMatched(right);
1324
      }
1325 1202

	
1326 1203
      (*_blossom_data)[left].next = _graph.direct(edge, true);
1327 1204
      (*_blossom_data)[right].next = _graph.direct(edge, false);
1328 1205
    }
1329 1206

	
1207
    void augmentOnArc(const Arc& arc) {
1208

	
1209
      int left = _blossom_set->find(_graph.source(arc));
1210
      int right = _blossom_set->find(_graph.target(arc));
1211

	
1212
      (*_blossom_data)[left].status = MATCHED;
1213

	
1214
      int right_tree = _tree_set->find(right);
1215
      alternatePath(right, right_tree);
1216
      destroyTree(right_tree);
1217

	
1218
      (*_blossom_data)[left].next = arc;
1219
      (*_blossom_data)[right].next = _graph.oppositeArc(arc);
1220
    }
1221

	
1330 1222
    void extendOnArc(const Arc& arc) {
1331 1223
      int base = _blossom_set->find(_graph.target(arc));
1332 1224
      int tree = _tree_set->find(base);
1333 1225

	
1334 1226
      int odd = _blossom_set->find(_graph.source(arc));
1335 1227
      _tree_set->insert(odd, tree);
1336 1228
      (*_blossom_data)[odd].status = ODD;
1337 1229
      matchedToOdd(odd);
1338 1230
      (*_blossom_data)[odd].pred = arc;
1339 1231

	
1340 1232
      int even = _blossom_set->find(_graph.target((*_blossom_data)[odd].next));
1341 1233
      (*_blossom_data)[even].pred = (*_blossom_data)[even].next;
... ...
@@ -1620,25 +1512,25 @@
1620 1512

	
1621 1513
        _blossom_potential.push_back(BlossomVariable(bn, en, pot));
1622 1514
      }
1623 1515
    }
1624 1516

	
1625 1517
    void extractMatching() {
1626 1518
      std::vector<int> blossoms;
1627 1519
      for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
1628 1520
        blossoms.push_back(c);
1629 1521
      }
1630 1522

	
1631 1523
      for (int i = 0; i < int(blossoms.size()); ++i) {
1632
        if ((*_blossom_data)[blossoms[i]].status == MATCHED) {
1524
        if ((*_blossom_data)[blossoms[i]].next != INVALID) {
1633 1525

	
1634 1526
          Value offset = (*_blossom_data)[blossoms[i]].offset;
1635 1527
          (*_blossom_data)[blossoms[i]].pot += 2 * offset;
1636 1528
          for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
1637 1529
               n != INVALID; ++n) {
1638 1530
            (*_node_data)[(*_node_index)[n]].pot -= offset;
1639 1531
          }
1640 1532

	
1641 1533
          Arc matching = (*_blossom_data)[blossoms[i]].next;
1642 1534
          Node base = _graph.source(matching);
1643 1535
          extractBlossom(blossoms[i], base, matching);
1644 1536
        } else {
... ...
@@ -1748,70 +1640,62 @@
1748 1640
        Value d1 = !_delta1->empty() ?
1749 1641
          _delta1->prio() : std::numeric_limits<Value>::max();
1750 1642

	
1751 1643
        Value d2 = !_delta2->empty() ?
1752 1644
          _delta2->prio() : std::numeric_limits<Value>::max();
1753 1645

	
1754 1646
        Value d3 = !_delta3->empty() ?
1755 1647
          _delta3->prio() : std::numeric_limits<Value>::max();
1756 1648

	
1757 1649
        Value d4 = !_delta4->empty() ?
1758 1650
          _delta4->prio() : std::numeric_limits<Value>::max();
1759 1651

	
1760
        _delta_sum = d1; OpType ot = D1;
1652
        _delta_sum = d3; OpType ot = D3;
1653
        if (d1 < _delta_sum) { _delta_sum = d1; ot = D1; }
1761 1654
        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
1762
        if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
1763 1655
        if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
1764 1656

	
1765

	
1766 1657
        switch (ot) {
1767 1658
        case D1:
1768 1659
          {
1769 1660
            Node n = _delta1->top();
1770 1661
            unmatchNode(n);
1771 1662
            --unmatched;
1772 1663
          }
1773 1664
          break;
1774 1665
        case D2:
1775 1666
          {
1776 1667
            int blossom = _delta2->top();
1777 1668
            Node n = _blossom_set->classTop(blossom);
1778
            Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
1779
            extendOnArc(e);
1669
            Arc a = (*_node_data)[(*_node_index)[n]].heap.top();
1670
            if ((*_blossom_data)[blossom].next == INVALID) {
1671
              augmentOnArc(a);
1672
              --unmatched;
1673
            } else {
1674
              extendOnArc(a);
1675
            }
1780 1676
          }
1781 1677
          break;
1782 1678
        case D3:
1783 1679
          {
1784 1680
            Edge e = _delta3->top();
1785 1681

	
1786 1682
            int left_blossom = _blossom_set->find(_graph.u(e));
1787 1683
            int right_blossom = _blossom_set->find(_graph.v(e));
1788 1684

	
1789 1685
            if (left_blossom == right_blossom) {
1790 1686
              _delta3->pop();
1791 1687
            } else {
1792
              int left_tree;
1793
              if ((*_blossom_data)[left_blossom].status == EVEN) {
1794
                left_tree = _tree_set->find(left_blossom);
1795
              } else {
1796
                left_tree = -1;
1797
                ++unmatched;
1798
              }
1799
              int right_tree;
1800
              if ((*_blossom_data)[right_blossom].status == EVEN) {
1801
                right_tree = _tree_set->find(right_blossom);
1802
              } else {
1803
                right_tree = -1;
1804
                ++unmatched;
1805
              }
1688
              int left_tree = _tree_set->find(left_blossom);
1689
              int right_tree = _tree_set->find(right_blossom);
1806 1690

	
1807 1691
              if (left_tree == right_tree) {
1808 1692
                shrinkOnEdge(e, left_tree);
1809 1693
              } else {
1810 1694
                augmentOnEdge(e);
1811 1695
                unmatched -= 2;
1812 1696
              }
1813 1697
            }
1814 1698
          } break;
1815 1699
        case D4:
1816 1700
          splitBlossom(_delta4->top());
1817 1701
          break;
... ...
@@ -1847,25 +1731,25 @@
1847 1731
    /// \brief Return the weight of the matching.
1848 1732
    ///
1849 1733
    /// This function returns the weight of the found matching.
1850 1734
    ///
1851 1735
    /// \pre Either run() or start() must be called before using this function.
1852 1736
    Value matchingWeight() const {
1853 1737
      Value sum = 0;
1854 1738
      for (NodeIt n(_graph); n != INVALID; ++n) {
1855 1739
        if ((*_matching)[n] != INVALID) {
1856 1740
          sum += _weight[(*_matching)[n]];
1857 1741
        }
1858 1742
      }
1859
      return sum /= 2;
1743
      return sum / 2;
1860 1744
    }
1861 1745

	
1862 1746
    /// \brief Return the size (cardinality) of the matching.
1863 1747
    ///
1864 1748
    /// This function returns the size (cardinality) of the found matching.
1865 1749
    ///
1866 1750
    /// \pre Either run() or start() must be called before using this function.
1867 1751
    int matchingSize() const {
1868 1752
      int num = 0;
1869 1753
      for (NodeIt n(_graph); n != INVALID; ++n) {
1870 1754
        if ((*_matching)[n] != INVALID) {
1871 1755
          ++num;
... ...
@@ -2224,27 +2108,24 @@
2224 2108
      }
2225 2109
      if (!_delta3) {
2226 2110
        _delta3_index = new IntEdgeMap(_graph);
2227 2111
        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
2228 2112
      }
2229 2113
      if (!_delta4) {
2230 2114
        _delta4_index = new IntIntMap(_blossom_num);
2231 2115
        _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
2232 2116
      }
2233 2117
    }
2234 2118

	
2235 2119
    void destroyStructures() {
2236
      _node_num = countNodes(_graph);
2237
      _blossom_num = _node_num * 3 / 2;
2238

	
2239 2120
      if (_matching) {
2240 2121
        delete _matching;
2241 2122
      }
2242 2123
      if (_node_potential) {
2243 2124
        delete _node_potential;
2244 2125
      }
2245 2126
      if (_blossom_set) {
2246 2127
        delete _blossom_index;
2247 2128
        delete _blossom_set;
2248 2129
        delete _blossom_data;
2249 2130
      }
2250 2131

	
... ...
@@ -2982,26 +2863,26 @@
2982 2863

	
2983 2864
      int unmatched = _node_num;
2984 2865
      while (unmatched > 0) {
2985 2866
        Value d2 = !_delta2->empty() ?
2986 2867
          _delta2->prio() : std::numeric_limits<Value>::max();
2987 2868

	
2988 2869
        Value d3 = !_delta3->empty() ?
2989 2870
          _delta3->prio() : std::numeric_limits<Value>::max();
2990 2871

	
2991 2872
        Value d4 = !_delta4->empty() ?
2992 2873
          _delta4->prio() : std::numeric_limits<Value>::max();
2993 2874

	
2994
        _delta_sum = d2; OpType ot = D2;
2995
        if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
2875
        _delta_sum = d3; OpType ot = D3;
2876
        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
2996 2877
        if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
2997 2878

	
2998 2879
        if (_delta_sum == std::numeric_limits<Value>::max()) {
2999 2880
          return false;
3000 2881
        }
3001 2882

	
3002 2883
        switch (ot) {
3003 2884
        case D2:
3004 2885
          {
3005 2886
            int blossom = _delta2->top();
3006 2887
            Node n = _blossom_set->classTop(blossom);
3007 2888
            Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
... ...
@@ -3065,25 +2946,25 @@
3065 2946
    /// \brief Return the weight of the matching.
3066 2947
    ///
3067 2948
    /// This function returns the weight of the found matching.
3068 2949
    ///
3069 2950
    /// \pre Either run() or start() must be called before using this function.
3070 2951
    Value matchingWeight() const {
3071 2952
      Value sum = 0;
3072 2953
      for (NodeIt n(_graph); n != INVALID; ++n) {
3073 2954
        if ((*_matching)[n] != INVALID) {
3074 2955
          sum += _weight[(*_matching)[n]];
3075 2956
        }
3076 2957
      }
3077
      return sum /= 2;
2958
      return sum / 2;
3078 2959
    }
3079 2960

	
3080 2961
    /// \brief Return \c true if the given edge is in the matching.
3081 2962
    ///
3082 2963
    /// This function returns \c true if the given edge is in the found 
3083 2964
    /// matching.
3084 2965
    ///
3085 2966
    /// \pre Either run() or start() must be called before using this function.
3086 2967
    bool matching(const Edge& edge) const {
3087 2968
      return static_cast<const Edge&>((*_matching)[_graph.u(edge)]) == edge;
3088 2969
    }
3089 2970

	
... ...
@@ -3232,13 +3113,13 @@
3232 3113
    private:
3233 3114
      const MaxWeightedPerfectMatching* _algorithm;
3234 3115
      int _last;
3235 3116
      int _index;
3236 3117
    };
3237 3118

	
3238 3119
    /// @}
3239 3120

	
3240 3121
  };
3241 3122

	
3242 3123
} //END OF NAMESPACE LEMON
3243 3124

	
3244
#endif //LEMON_MAX_MATCHING_H
3125
#endif //LEMON_MATCHING_H
0 comments (0 inline)