diff --git a/cpp/test_mwmatching.cpp b/cpp/test_mwmatching.cpp index 418ee20..4969e86 100644 --- a/cpp/test_mwmatching.cpp +++ b/cpp/test_mwmatching.cpp @@ -497,3 +497,129 @@ BOOST_AUTO_TEST_CASE(test41_maxcard) } BOOST_AUTO_TEST_SUITE_END() + + +/* ********** Test verification ********** */ + +BOOST_AUTO_TEST_SUITE(test_verification) + +BOOST_AUTO_TEST_CASE(test_success) +{ + using mwmatching::impl::NO_VERTEX; + EdgeVectorLong edges = {{0, 1, 10}, {1, 2, 11}}; + mwmatching::impl::MatchingContext ctx(edges); + ctx.vertex_mate = {NO_VERTEX, 2, 1}; + ctx.vertex_dual = {0, 20, 2}; + ctx.nontrivial_blossom.clear(); + mwmatching::impl::MatchingVerifier verifier(ctx); + BOOST_TEST(verifier.verify() == true); +} + +BOOST_AUTO_TEST_CASE(test_asymmetric_matching) +{ + using mwmatching::impl::NO_VERTEX; + EdgeVectorLong edges = {{0, 1, 10}, {1, 2, 11}}; + mwmatching::impl::MatchingContext ctx(edges); + ctx.vertex_mate = {NO_VERTEX, 2, 0}; + ctx.vertex_dual = {0, 20, 2}; + ctx.nontrivial_blossom.clear(); + mwmatching::impl::MatchingVerifier verifier(ctx); + BOOST_TEST(verifier.verify() == false); +} + +BOOST_AUTO_TEST_CASE(test_nonexistent_matched_edge) +{ + using mwmatching::impl::NO_VERTEX; + EdgeVectorLong edges = {{0, 1, 10}, {1, 2, 11}}; + mwmatching::impl::MatchingContext ctx(edges); + ctx.vertex_mate = {2, NO_VERTEX, 0}; + ctx.vertex_dual = {11, 11, 11}; + ctx.nontrivial_blossom.clear(); + mwmatching::impl::MatchingVerifier verifier(ctx); + BOOST_TEST(verifier.verify() == false); +} + +BOOST_AUTO_TEST_CASE(test_negative_vertex_dual) +{ + using mwmatching::impl::NO_VERTEX; + EdgeVectorLong edges = {{0, 1, 10}, {1, 2, 11}}; + mwmatching::impl::MatchingContext ctx(edges); + ctx.vertex_mate = {NO_VERTEX, 2, 1}; + ctx.vertex_dual = {-2, 22, 0}; + ctx.nontrivial_blossom.clear(); + mwmatching::impl::MatchingVerifier verifier(ctx); + BOOST_TEST(verifier.verify() == false); +} + +BOOST_AUTO_TEST_CASE(test_unmatched_nonzero_dual) +{ + using mwmatching::impl::NO_VERTEX; + EdgeVectorLong edges = {{0, 1, 10}, {1, 2, 11}}; + mwmatching::impl::MatchingContext ctx(edges); + ctx.vertex_mate = {NO_VERTEX, 2, 1}; + ctx.vertex_dual = {9, 11, 11}; + ctx.nontrivial_blossom.clear(); + mwmatching::impl::MatchingVerifier verifier(ctx); + BOOST_TEST(verifier.verify() == false); +} + +BOOST_AUTO_TEST_CASE(test_negative_edge_slack) +{ + using mwmatching::impl::NO_VERTEX; + EdgeVectorLong edges = {{0, 1, 10}, {1, 2, 11}}; + mwmatching::impl::MatchingContext ctx(edges); + ctx.vertex_mate = {NO_VERTEX, 2, 1}; + ctx.vertex_dual = {0, 11, 11}; + ctx.nontrivial_blossom.clear(); + mwmatching::impl::MatchingVerifier verifier(ctx); + BOOST_TEST(verifier.verify() == false); +} + +BOOST_AUTO_TEST_CASE(test_matched_edge_slack) +{ + using mwmatching::impl::NO_VERTEX; + EdgeVectorLong edges = {{0, 1, 10}, {1, 2, 11}}; + mwmatching::impl::MatchingContext ctx(edges); + ctx.vertex_mate = {NO_VERTEX, 2, 1}; + ctx.vertex_dual = {0, 20, 11}; + ctx.nontrivial_blossom.clear(); + mwmatching::impl::MatchingVerifier verifier(ctx); + BOOST_TEST(verifier.verify() == false); +} + +BOOST_AUTO_TEST_CASE(test_negative_blossom_dual) +{ + EdgeVectorLong edges = {{0, 1, 7}, {0, 2, 8}, {1, 2, 9}, {2, 3, 6}}; + mwmatching::impl::MatchingContext ctx(edges); + ctx.vertex_mate = {1, 0, 3, 2}; + ctx.vertex_dual = {4, 6, 8, 4}; + mwmatching::impl::Blossom b0(0); + mwmatching::impl::Blossom b1(1); + mwmatching::impl::Blossom b2(2); + ctx.nontrivial_blossom.emplace_back( + std::vector*>{&b0, &b1, &b2}, + std::deque{{0, 1}, {1, 2}, {2, 0}}); + ctx.nontrivial_blossom.front().dual_var = -2; + mwmatching::impl::MatchingVerifier verifier(ctx); + BOOST_TEST(verifier.verify() == false); +} + +BOOST_AUTO_TEST_CASE(test_blossom_not_full) +{ + using mwmatching::impl::NO_VERTEX; + EdgeVectorLong edges = {{0, 1, 7}, {0, 2, 2}, {1, 2, 5}, {0, 3, 8}, {1, 4, 8}}; + mwmatching::impl::MatchingContext ctx(edges); + ctx.vertex_mate = {3, 4, NO_VERTEX, 0, 1}; + ctx.vertex_dual = {4, 10, 0, 12, 6}; + mwmatching::impl::Blossom b0(0); + mwmatching::impl::Blossom b1(1); + mwmatching::impl::Blossom b2(2); + ctx.nontrivial_blossom.emplace_back( + std::vector*>{&b0, &b1, &b2}, + std::deque{{0, 1}, {1, 2}, {2, 0}}); + ctx.nontrivial_blossom.front().dual_var = 2; + mwmatching::impl::MatchingVerifier verifier(ctx); + BOOST_TEST(verifier.verify() == false); +} + +BOOST_AUTO_TEST_SUITE_END()