1
0
Fork 0

Fix bug in C++ matching code

This commit is contained in:
Joris van Rantwijk 2023-05-12 00:43:57 +02:00
parent 61cb309082
commit a4da35d3aa
3 changed files with 35 additions and 11 deletions

View File

@ -1204,12 +1204,12 @@ struct MatchingContext
blossom->subblossoms, blossom->subblossoms,
entry_it, entry_it,
sub_end); sub_end);
// Update the base vertex.
// We can pull the new base vertex from the entry sub-blossom
// since its augmentation has already finished.
blossom->base_vertex = entry->base_vertex;
} }
// Update the base vertex.
// We can pull the new base vertex from the entry sub-blossom
// since its augmentation has already finished.
blossom->base_vertex = entry->base_vertex;
} }
/** /**
@ -1259,12 +1259,8 @@ struct MatchingContext
{ {
// Check that the path starts and ends in an unmatched blossom. // Check that the path starts and ends in an unmatched blossom.
assert(path.edges.size() % 2 == 1); assert(path.edges.size() % 2 == 1);
assert(vertex_mate[ assert(vertex_mate[vertex_top_blossom[path.edges.front().first]->base_vertex] == NO_VERTEX);
vertex_top_blossom[path.edges.front().first]->base_vertex] assert(vertex_mate[vertex_top_blossom[path.edges.back().second]->base_vertex] == NO_VERTEX);
== NO_VERTEX);
assert(vertex_mate[
vertex_top_blossom[path.edges.back().second]->base_vertex]
== NO_VERTEX);
// Process the unmatched edges on the augmenting path. // Process the unmatched edges on the augmenting path.
auto edge_it = path.edges.begin(); auto edge_it = path.edges.begin();

View File

@ -310,6 +310,21 @@ BOOST_AUTO_TEST_CASE(test48_expand_unlabeled_nested)
BOOST_TEST(mwmatching::maximum_weight_matching(edges) == expect); BOOST_TEST(mwmatching::maximum_weight_matching(edges) == expect);
} }
BOOST_AUTO_TEST_CASE(test51_augment_blossom_nested)
{
/*
* 19--[1]--17--[4]--11--[7]
* / | |
* [3]--15--[2] 19 18
* \ | |
* 21--[5]--19--[6]
*/
EdgeVectorLong edges = {
{1, 2, 19}, {1, 4, 17}, {1, 5, 19}, {2, 3, 15}, {2, 5, 21}, {4, 6, 18}, {4, 7, 11}, {5, 6, 19}};
Matching expect = {{1, 5}, {2, 3}, {4, 6}};
BOOST_TEST(mwmatching::maximum_weight_matching(edges) == expect);
}
BOOST_AUTO_TEST_CASE(test_fail_bad_input) BOOST_AUTO_TEST_CASE(test_fail_bad_input)
{ {
EdgeVectorDouble inf_weight = {{1, 2, std::numeric_limits<double>::infinity()}}; EdgeVectorDouble inf_weight = {{1, 2, std::numeric_limits<double>::infinity()}};

View File

@ -230,6 +230,19 @@ class TestMaximumWeightMatching(unittest.TestCase):
mwm([(1,2,12), (1,4,11), (1,5,11), (2,4,12), (2,6,11), (3,4,14), (3,7,14), (4,7,11)]), mwm([(1,2,12), (1,4,11), (1,5,11), (2,4,12), (2,6,11), (3,4,14), (3,7,14), (4,7,11)]),
[(1,5), (2,4), (3,7)]) [(1,5), (2,4), (3,7)])
def test51_augment_blossom_nested(self):
"""augment nested blossoms with common base vertex"""
#
# 19--[1]--17--[4]--11--[7]
# / | |
# [3]--15--[2] 19 18
# \ | |
# 21--[5]--19--[6]
#
self.assertEqual(
mwm([(1,2,19), (1,4,17), (1,5,19), (2,3,15), (2,5,21), (4,6,18), (4,7,11), (5,6,19)]),
[(1,5), (2,3), (4,6)])
def test_fail_bad_input(self): def test_fail_bad_input(self):
"""bad input values""" """bad input values"""
with self.assertRaises(TypeError): with self.assertRaises(TypeError):