diff --git a/ortools/set_cover/python/set_cover.cc b/ortools/set_cover/python/set_cover.cc index cdc34787615..c89ffe53d93 100644 --- a/ortools/set_cover/python/set_cover.cc +++ b/ortools/set_cover/python/set_cover.cc @@ -71,7 +71,8 @@ using ::py::make_iterator; std::vector VectorIntToVectorSubsetIndex( absl::Span ints) { std::vector subs; - std::transform(ints.begin(), ints.end(), subs.begin(), + subs.reserve(ints.size()); + std::transform(ints.begin(), ints.end(), std::back_inserter(subs), [](int subset) -> SubsetIndex { return SubsetIndex(subset); }); return subs; } @@ -199,9 +200,11 @@ PYBIND11_MODULE(set_cover, m) { .def_property_readonly("all_subsets", [](SetCoverModel& model) -> std::vector { std::vector subsets; + subsets.reserve(model.all_subsets().size()); std::transform( model.all_subsets().begin(), - model.all_subsets().end(), subsets.begin(), + model.all_subsets().end(), + std::back_inserter(subsets), [](const SubsetIndex element) -> BaseInt { return element.value(); }); @@ -555,9 +558,9 @@ PYBIND11_MODULE(set_cover, m) { return heuristic.NextSolution( BoolVectorToSubsetBoolVector(in_focus)); }) - .def("get_lagrangian_factor", &GuidedTabuSearch::SetLagrangianFactor, + .def("set_lagrangian_factor", &GuidedTabuSearch::SetLagrangianFactor, arg("factor")) - .def("set_lagrangian_factor", &GuidedTabuSearch::GetLagrangianFactor) + .def("get_lagrangian_factor", &GuidedTabuSearch::GetLagrangianFactor) .def("set_epsilon", &GuidedTabuSearch::SetEpsilon, arg("r")) .def("get_epsilon", &GuidedTabuSearch::GetEpsilon) .def("set_penalty_factor", &GuidedTabuSearch::SetPenaltyFactor, diff --git a/ortools/set_cover/python/set_cover_test.py b/ortools/set_cover/python/set_cover_test.py index ee1ed4b9f54..b2ee29304ed 100644 --- a/ortools/set_cover/python/set_cover_test.py +++ b/ortools/set_cover/python/set_cover_test.py @@ -222,6 +222,35 @@ def test_knights_cover_trivial(self): inv.check_consistency(set_cover.consistency_level.FREE_AND_UNCOVERED) ) + def test_all_subsets_property(self): + model = create_knights_cover_model(4, 4) + all_subs = model.all_subsets + self.assertLen(all_subs, model.num_subsets) + self.assertEqual(all_subs, list(range(model.num_subsets))) + + def test_focus_based_next_solution(self): + model = create_knights_cover_model(8, 8) + self.assertTrue(model.compute_feasibility()) + inv = set_cover.SetCoverInvariant(model) + + focus = list(range(model.num_subsets)) + greedy = set_cover.GreedySolutionGenerator(inv) + self.assertTrue(greedy.next_solution(focus)) + self.assertEqual(inv.num_uncovered_elements(), 0) + + def test_guided_tabu_search_lagrangian_factor(self): + model = create_knights_cover_model(8, 8) + self.assertTrue(model.compute_feasibility()) + inv = set_cover.SetCoverInvariant(model) + + greedy = set_cover.GreedySolutionGenerator(inv) + self.assertTrue(greedy.next_solution()) + + gts = set_cover.GuidedTabuSearch(inv) + gts.initialize() + gts.set_lagrangian_factor(0.5) + self.assertAlmostEqual(gts.get_lagrangian_factor(), 0.5) + # TODO(user): KnightsCoverGreedyAndTabu, KnightsCoverGreedyRandomClear, # KnightsCoverElementDegreeRandomClear, KnightsCoverRandomClearMip, # KnightsCoverMip