20#include "gtest/gtest.h"
36 <<
", supports_primal_only_warm_starts: "
45constexpr double kInf = std::numeric_limits<double>::infinity();
78 : x1(model.AddContinuousVariable(0,
kInf,
"x1")),
79 x2(model.AddContinuousVariable(0,
kInf,
"x2")),
80 y1(model.AddLinearConstraint(x1 + x2 >= 1,
"y1")),
81 y2(model.AddLinearConstraint(x1 + 4 * x2 >= 2,
"y2")) {
82 model.Minimize(2 * x1 + x2);
88 const LinearConstraint y1;
89 const LinearConstraint y2;
113 : x1(model.AddContinuousVariable(0,
kInf,
"x1")),
114 x2(model.AddContinuousVariable(0,
kInf,
"x2")),
115 y1(model.AddLinearConstraint(x1 + x2 >= 1,
"y1")),
116 y2(model.AddLinearConstraint(x2 <= 0,
"y2")) {
117 model.Maximize(2 * x1 - x2);
123 const LinearConstraint y1;
124 const LinearConstraint y2;
159 : x1(model.AddContinuousVariable(0,
kInf,
"x1")),
160 x2(model.AddContinuousVariable(-
kInf,
kInf,
"x2")),
161 y1(model.AddLinearConstraint(x1 <= -2,
"y1")),
162 y2(model.AddLinearConstraint(x2 <= 3,
"y2")) {
163 model.Minimize(x1 - x2);
169 const LinearConstraint y1;
170 const LinearConstraint y2;
174 if (!GetParam().exact_zeros) {
176 <<
"Solver " << GetParam().solver_type
177 <<
" does not reliably return exact zeros; this test is disabled.";
182 .parameters = GetParam().parameters,
183 .model_parameters = {
184 .variable_values_filter = {.skip_zero_values =
true}}};
186 Solve(lp.model, GetParam().solver_type, args));
189 if (GetParam().supports_duals) {
191 .dual_values = {{lp.y1, 1.0}, {lp.y2, 0.0}},
192 .reduced_costs = {{lp.x1, 1.0}, {lp.x2, 0.0}},
193 .objective_value = 1.0,
201 if (!GetParam().exact_zeros) {
203 <<
"Solver " << GetParam().solver_type
204 <<
" does not reliably return exact zeros; this test is disabled.";
206 if (!GetParam().supports_duals) {
207 GTEST_SKIP() <<
"Solver " << GetParam().solver_type
208 <<
" can't produce dual solutions; this test is disabled.";
212 .parameters = GetParam().parameters,
213 .model_parameters = {.reduced_costs_filter = {.skip_zero_values =
true}}};
215 Solve(lp.model, GetParam().solver_type, args));
219 .dual_values = {{lp.y1, 1.0}, {lp.y2, 0.0}},
220 .reduced_costs = {{lp.x1, 1.0}},
221 .objective_value = 1.0,
227 if (!GetParam().exact_zeros) {
229 <<
"Solver " << GetParam().solver_type
230 <<
" does not reliably return exact zeros; this test is disabled.";
232 if (!GetParam().supports_duals) {
233 GTEST_SKIP() <<
"Solver " << GetParam().solver_type
234 <<
" can't produce dual solutions; this test is disabled.";
239 .parameters = GetParam().parameters,
240 .model_parameters = {.dual_values_filter = {.skip_zero_values =
true}}};
242 Solve(lp.model, GetParam().solver_type, args));
246 .dual_values = {{lp.y1, 1.0}},
247 .reduced_costs = {{lp.x1, 1.0}, {lp.x2, 0.0}},
248 .objective_value = 1.0,
259 .parameters = GetParam().parameters,
260 .model_parameters = {
265 Solve(lp.model, GetParam().solver_type, args));
268 if (GetParam().supports_duals) {
270 .dual_values = {{lp.y2, 0.0}},
271 .reduced_costs = {{lp.x2, 0.0}},
272 .objective_value = 1.0,
279 if (!GetParam().exact_zeros) {
281 <<
"Solver " << GetParam().solver_type
282 <<
" does not reliably return exact zeros; this test is disabled.";
287 .model_parameters = {.variable_values_filter = {
288 .skip_zero_values =
true}}};
291 GTEST_SKIP() <<
"Solver " << GetParam().solver_type
292 <<
" can't produce primal rays; this test is disabled.";
296 Solve(lp.model, GetParam().solver_type, args));
307 .model_parameters = {.variable_values_filter =
311 GTEST_SKIP() <<
"Solver " << GetParam().solver_type
312 <<
" can't produce primal rays; this test is disabled.";
316 Solve(lp.model, GetParam().solver_type, args));
324 if (!GetParam().exact_zeros) {
326 <<
"Solver " << GetParam().solver_type
327 <<
" does not reliably return exact zeros; this test is disabled.";
332 .parameters = GetParam().parameters,
333 .model_parameters = {.dual_values_filter = {.skip_zero_values =
true}}};
336 GTEST_SKIP() <<
"Solver " << GetParam().solver_type
337 <<
" can't produce dual rays; this test is disabled.";
341 Solve(lp.model, GetParam().solver_type, args));
343 const DualRay expected = {.dual_values = {{lp.y1, -1.0}},
344 .reduced_costs = {{lp.x1, 1.0}, {lp.x2, 0.0}}};
349 if (!GetParam().exact_zeros) {
351 <<
"Solver " << GetParam().solver_type
352 <<
" does not reliably return exact zeros; this test is disabled.";
357 .parameters = GetParam().parameters,
358 .model_parameters = {.reduced_costs_filter = {.skip_zero_values =
true}}};
361 GTEST_SKIP() <<
"Solver " << GetParam().solver_type
362 <<
" can't produce dual rays; this test is disabled.";
366 Solve(lp.model, GetParam().solver_type, args));
368 const DualRay expected = {.dual_values = {{lp.y1, -1.0}, {lp.y2, 0.0}},
369 .reduced_costs = {{lp.x1, 1.0}}};
377 .parameters = GetParam().parameters,
378 .model_parameters = {
383 GTEST_SKIP() <<
"Solver " << GetParam().solver_type
384 <<
" can't produce dual rays; this test is disabled.";
388 Solve(lp.model, GetParam().solver_type, args));
390 const DualRay expected = {.dual_values = {{lp.y2, 0.0}},
391 .reduced_costs = {{lp.x2, 0.0}}};
396 constexpr int n = 10;
398 int baseline_num_iters = 0;
401 Solve(*model, GetParam().solver_type,
402 {.parameters = GetParam().parameters}));
404 baseline_num_iters = result.solve_stats.simplex_iterations +
405 result.solve_stats.barrier_iterations +
406 result.solve_stats.first_order_iterations;
411 for (
const Variable var : model->Variables()) {
412 warm_start.variable_values[var] = 1.0 / 2.0;
416 Solve(*model, GetParam().solver_type,
417 {.parameters = GetParam().parameters,
418 .model_parameters = {.solution_hints = {warm_start}}}));
420 const int actual_num_iters = result.solve_stats.simplex_iterations +
421 result.solve_stats.barrier_iterations +
422 result.solve_stats.first_order_iterations;
423 if (!GetParam().supports_primal_only_warm_starts) {
424 EXPECT_EQ(actual_num_iters, baseline_num_iters);
427 EXPECT_LT(actual_num_iters, baseline_num_iters);
An object oriented wrapper for quadratic constraints in ModelStorage.
EXPECT_THAT(ComputeInfeasibleSubsystem(model, GetParam().solver_type), IsOkAndHolds(IsInfeasible(true, ModelSubset{ .variable_bounds={{x, ModelSubset::Bounds{.lower=false,.upper=true}}},.linear_constraints={ {c, ModelSubset::Bounds{.lower=true,.upper=false}}}})))
Matcher< SolveResult > HasPrimalRay(PrimalRay expected, const double tolerance)
TEST_P(InfeasibleSubsystemTest, CanComputeInfeasibleSubsystem)
@ kInfeasible
The primal problem has no feasible solutions.
ASSERT_THAT(solver->Update(), IsOkAndHolds(DidUpdate()))
Matcher< SolveResult > TerminatesWithOneOf(const std::vector< TerminationReason > &allowed)
Checks that the result has one of the allowed termination reasons.
bool ActivatePrimalRay(SolverType solver_type, SolveParameters ¶ms)
absl::StatusOr< SolveResult > Solve(const Model &model, const SolverType solver_type, const SolveArguments &solve_args, const SolverInitArguments &init_args)
std::ostream & operator<<(std::ostream &ostr, const IndicatorConstraint &constraint)
@ kFeasible
Solver claims the solution is feasible.
Matcher< SolveResult > HasDualRay(DualRay expected, const double tolerance)
Matcher< SolveResult > TerminatesWith(const TerminationReason expected)
std::unique_ptr< Model > IndependentSetCompleteGraph(const bool integer, const int n)
Matcher< VariableMap< double > > IsNear(VariableMap< double > expected, const double tolerance)
MapFilter< ValueType > MakeKeepKeysFilter(const Collection &keys)
Matcher< SolveResult > HasDualSolution(DualSolution expected, const double tolerance)
bool ActivateDualRay(SolverType solver_type, SolveParameters ¶ms)
Matcher< SolveResult > IsOptimal(const std::optional< double > expected_primal_objective, const double tolerance)
In SWIG mode, we don't want anything besides these top-level includes.
std::string ProtobufShortDebugString(const P &message)
#define ASSERT_OK_AND_ASSIGN(lhs, rexpr)
SolveParameters parameters
bool supports_primal_only_warm_starts
True if the solver supports warm starts on the primal solution only.
LpModelSolveParametersTestParameters(const SolverType solver_type, const bool exact_zeros, const bool supports_duals, const bool supports_primal_only_warm_starts, SolveParameters parameters={})
SolveParametersProto Proto() const