diff --git a/examples/cpp/BUILD.bazel b/examples/cpp/BUILD.bazel index f027ec9e838..80ca3e7e500 100644 --- a/examples/cpp/BUILD.bazel +++ b/examples/cpp/BUILD.bazel @@ -771,6 +771,18 @@ cc_binary( ], ) +cc_test( + name = "strawberry_fields_with_column_generation_test", + srcs = ["strawberry_fields_with_column_generation.cc"], + size = "large", + args = ["--colgen_instance=4"], + deps = [ + "//ortools/base", + "//ortools/linear_solver", + "@com_google_absl//absl/strings:str_format", + ], +) + # Dimacs assignment problems cc_library( name = "print_dimacs_assignment", diff --git a/examples/cpp/strawberry_fields_with_column_generation.cc b/examples/cpp/strawberry_fields_with_column_generation.cc index 5726ef7affa..dc663161473 100644 --- a/examples/cpp/strawberry_fields_with_column_generation.cc +++ b/examples/cpp/strawberry_fields_with_column_generation.cc @@ -301,7 +301,7 @@ class CoveringProblem { // Grid is a row-major string of length width*height with '@' for an // occupied cell (strawberry) and '.' for an empty cell. Solver is // not owned. - CoveringProblem(MPSolver* const solver, const Instance& instance) + CoveringProblem(MPSolver* solver, const Instance& instance) : solver_(solver), max_boxes_(instance.max_boxes), width_(instance.width), @@ -547,15 +547,18 @@ class CoveringProblem { // Solves iteratively using delayed column generation, up to maximum // number of steps. -void SolveInstance(const Instance& instance, - MPSolver::OptimizationProblemType solver_type) { - // Prepares the solver. - MPSolver solver("ColumnGeneration", solver_type); - solver.SuppressOutput(); - solver.MutableObjective()->SetMinimization(); +void SolveInstance(const Instance& instance, std::string solver_name) { + // Prepares the solver-> + std::unique_ptr solver(MPSolver::CreateSolver(solver_name)); + if (!solver) { + LOG(INFO) << "Solver type '" << solver_name << "' not supported, or not linked in"; + return; + } + solver->SuppressOutput(); + solver->MutableObjective()->SetMinimization(); // Construct problem. - CoveringProblem problem(&solver, instance); + CoveringProblem problem(solver.get(), instance); CHECK(problem.Init()); LOG(INFO) << "Initial problem:\n" << problem.PrintGrid(); @@ -566,7 +569,7 @@ void SolveInstance(const Instance& instance, } // Solve with existing columns. - CHECK_EQ(MPSolver::OPTIMAL, solver.Solve()); + CHECK_EQ(MPSolver::OPTIMAL, solver->Solve()); if (absl::GetFlag(FLAGS_colgen_verbose)) { LOG(INFO) << problem.PrintCovering(); } @@ -590,7 +593,7 @@ void SolveInstance(const Instance& instance, if (step_number >= absl::GetFlag(FLAGS_colgen_max_iterations)) { // Solve one last time with all generated columns. - CHECK_EQ(MPSolver::OPTIMAL, solver.Solve()); + CHECK_EQ(MPSolver::OPTIMAL, solver->Solve()); } LOG(INFO) << step_number << " columns added"; @@ -604,40 +607,8 @@ int main(int argc, char** argv) { usage += " --colgen_max_iterations max columns to generate\n"; usage += " --colgen_complete generate all columns at start\n"; + absl::SetFlag(&FLAGS_stderrthreshold, 0); InitGoogle(usage.c_str(), &argc, &argv, true); - - operations_research::MPSolver::OptimizationProblemType solver_type; - bool found = false; -#if defined(USE_CLP) - if (absl::GetFlag(FLAGS_colgen_solver) == "clp") { - solver_type = operations_research::MPSolver::CLP_LINEAR_PROGRAMMING; - found = true; - } -#endif // USE_CLP -#if defined(USE_GLOP) - if (absl::GetFlag(FLAGS_colgen_solver) == "glop") { - solver_type = operations_research::MPSolver::GLOP_LINEAR_PROGRAMMING; - found = true; - } -#endif // USE_GLOP -#if defined(USE_XPRESS) - if (absl::GetFlag(FLAGS_colgen_solver) == "xpress") { - solver_type = operations_research::MPSolver::XPRESS_LINEAR_PROGRAMMING; - // solver_type = operations_research::MPSolver::CPLEX_LINEAR_PROGRAMMING; - found = true; - } -#endif -#if defined(USE_CPLEX) - if (absl::GetFlag(FLAGS_colgen_solver) == "cplex") { - solver_type = operations_research::MPSolver::CPLEX_LINEAR_PROGRAMMING; - found = true; - } -#endif - if (!found) { - LOG(ERROR) << "Unknown solver " << absl::GetFlag(FLAGS_colgen_solver); - return 1; - } - LOG(INFO) << "Chosen solver: " << absl::GetFlag(FLAGS_colgen_solver) << std::endl; @@ -645,7 +616,7 @@ int main(int argc, char** argv) { for (int i = 0; i < operations_research::kInstanceCount; ++i) { const operations_research::Instance& instance = operations_research::kInstances[i]; - operations_research::SolveInstance(instance, solver_type); + operations_research::SolveInstance(instance, absl::GetFlag(FLAGS_colgen_solver)); } } else { CHECK_GE(absl::GetFlag(FLAGS_colgen_instance), 0); @@ -653,7 +624,7 @@ int main(int argc, char** argv) { operations_research::kInstanceCount); const operations_research::Instance& instance = operations_research::kInstances[absl::GetFlag(FLAGS_colgen_instance)]; - operations_research::SolveInstance(instance, solver_type); + operations_research::SolveInstance(instance, absl::GetFlag(FLAGS_colgen_solver)); } return EXIT_SUCCESS; }