improvement to PDLP, remove most GLPK from tests, add py.typed for CP-SAT and model_builder python modules: fix #3993

This commit is contained in:
Laurent Perron
2023-11-22 11:43:44 +01:00
parent e3801a8526
commit 6136a47c99
5 changed files with 55 additions and 11 deletions

View File

@@ -53,8 +53,6 @@ public final class LinearSolverTest {
@Test
public void testMPSolver_basicCtor() {
runBasicCtor(MPSolver.OptimizationProblemType.GLOP_LINEAR_PROGRAMMING);
runBasicCtor(MPSolver.OptimizationProblemType.GLPK_LINEAR_PROGRAMMING);
runBasicCtor(MPSolver.OptimizationProblemType.GLPK_MIXED_INTEGER_PROGRAMMING);
runBasicCtor(MPSolver.OptimizationProblemType.CLP_LINEAR_PROGRAMMING);
runBasicCtor(MPSolver.OptimizationProblemType.CBC_MIXED_INTEGER_PROGRAMMING);
}
@@ -129,10 +127,12 @@ public final class LinearSolverTest {
public void testMPSolver_linearSolver() {
runLinearSolver(MPSolver.OptimizationProblemType.GLOP_LINEAR_PROGRAMMING, false);
runLinearSolver(MPSolver.OptimizationProblemType.CLP_LINEAR_PROGRAMMING, false);
runLinearSolver(MPSolver.OptimizationProblemType.GLPK_LINEAR_PROGRAMMING, false);
// TODO(b/312134897): Uncomment this.
// runLinearSolver(MPSolver.OptimizationProblemType.GLPK_LINEAR_PROGRAMMING, false);
runLinearSolver(MPSolver.OptimizationProblemType.CBC_MIXED_INTEGER_PROGRAMMING, true);
runLinearSolver(MPSolver.OptimizationProblemType.GLPK_MIXED_INTEGER_PROGRAMMING, true);
// TODO(b/312134897): Uncomment this.
// runLinearSolver(MPSolver.OptimizationProblemType.GLPK_MIXED_INTEGER_PROGRAMMING, true);
runLinearSolver(MPSolver.OptimizationProblemType.SCIP_MIXED_INTEGER_PROGRAMMING, true);
}
@@ -224,7 +224,8 @@ public final class LinearSolverTest {
public void testMPSolver_firstLinearExample() {
runFirstLinearExample(MPSolver.OptimizationProblemType.GLOP_LINEAR_PROGRAMMING);
runFirstLinearExample(MPSolver.OptimizationProblemType.CLP_LINEAR_PROGRAMMING);
runFirstLinearExample(MPSolver.OptimizationProblemType.GLPK_LINEAR_PROGRAMMING);
// TODO(b/312134897): Uncomment this.
// runFirstLinearExample(MPSolver.OptimizationProblemType.GLPK_LINEAR_PROGRAMMING);
runFirstLinearExample(MPSolver.OptimizationProblemType.GUROBI_LINEAR_PROGRAMMING);
}
@@ -266,7 +267,8 @@ public final class LinearSolverTest {
public void testMPSolver_firstMIPExample() {
runFirstMIPExample(MPSolver.OptimizationProblemType.BOP_INTEGER_PROGRAMMING);
runFirstMIPExample(MPSolver.OptimizationProblemType.CBC_MIXED_INTEGER_PROGRAMMING);
runFirstMIPExample(MPSolver.OptimizationProblemType.GLPK_MIXED_INTEGER_PROGRAMMING);
// TODO(b/312134897): Uncomment this.
// runFirstMIPExample(MPSolver.OptimizationProblemType.GLPK_MIXED_INTEGER_PROGRAMMING);
runFirstMIPExample(MPSolver.OptimizationProblemType.SCIP_MIXED_INTEGER_PROGRAMMING);
runFirstMIPExample(MPSolver.OptimizationProblemType.SAT_INTEGER_PROGRAMMING);
runFirstMIPExample(MPSolver.OptimizationProblemType.GUROBI_MIXED_INTEGER_PROGRAMMING);
@@ -318,11 +320,13 @@ public final class LinearSolverTest {
public void testMPSolver_successiveObjectives() {
runSuccessiveObjectives(MPSolver.OptimizationProblemType.GLOP_LINEAR_PROGRAMMING);
runSuccessiveObjectives(MPSolver.OptimizationProblemType.CLP_LINEAR_PROGRAMMING);
runSuccessiveObjectives(MPSolver.OptimizationProblemType.GLPK_LINEAR_PROGRAMMING);
// TODO(b/312134897): Uncomment this.
// runSuccessiveObjectives(MPSolver.OptimizationProblemType.GLPK_LINEAR_PROGRAMMING);
runSuccessiveObjectives(MPSolver.OptimizationProblemType.GUROBI_LINEAR_PROGRAMMING);
runSuccessiveObjectives(MPSolver.OptimizationProblemType.CBC_MIXED_INTEGER_PROGRAMMING);
runSuccessiveObjectives(MPSolver.OptimizationProblemType.GLPK_MIXED_INTEGER_PROGRAMMING);
// TODO(b/312134897): Uncomment this.
// runSuccessiveObjectives(MPSolver.OptimizationProblemType.GLPK_MIXED_INTEGER_PROGRAMMING);
runSuccessiveObjectives(MPSolver.OptimizationProblemType.SCIP_MIXED_INTEGER_PROGRAMMING);
runSuccessiveObjectives(MPSolver.OptimizationProblemType.SAT_INTEGER_PROGRAMMING);
runSuccessiveObjectives(MPSolver.OptimizationProblemType.GUROBI_MIXED_INTEGER_PROGRAMMING);
@@ -375,11 +379,13 @@ public final class LinearSolverTest {
public void testMPSolver_objectiveOffset() {
runObjectiveOffset(MPSolver.OptimizationProblemType.GLOP_LINEAR_PROGRAMMING);
runObjectiveOffset(MPSolver.OptimizationProblemType.CLP_LINEAR_PROGRAMMING);
runObjectiveOffset(MPSolver.OptimizationProblemType.GLPK_LINEAR_PROGRAMMING);
// TODO(b/312134897): Uncomment this.
// runObjectiveOffset(MPSolver.OptimizationProblemType.GLPK_LINEAR_PROGRAMMING);
runObjectiveOffset(MPSolver.OptimizationProblemType.GUROBI_LINEAR_PROGRAMMING);
runObjectiveOffset(MPSolver.OptimizationProblemType.CBC_MIXED_INTEGER_PROGRAMMING);
runObjectiveOffset(MPSolver.OptimizationProblemType.GLPK_MIXED_INTEGER_PROGRAMMING);
// TODO(b/312134897): Uncomment this.
// runObjectiveOffset(MPSolver.OptimizationProblemType.GLPK_MIXED_INTEGER_PROGRAMMING);
runObjectiveOffset(MPSolver.OptimizationProblemType.SCIP_MIXED_INTEGER_PROGRAMMING);
runObjectiveOffset(MPSolver.OptimizationProblemType.SAT_INTEGER_PROGRAMMING);
runObjectiveOffset(MPSolver.OptimizationProblemType.GUROBI_MIXED_INTEGER_PROGRAMMING);

View File

View File

@@ -1459,7 +1459,9 @@ PreprocessSolver::UpdateIterationStatsAndCheckTermination(
POINT_TYPE_AVERAGE_ITERATE, last_primal_start_point,
last_dual_start_point, stats);
}
if (working_primal_delta != nullptr && working_dual_delta != nullptr) {
// Undoing presolve doesn't work for iterate differences.
if (!presolve_info_.has_value() && working_primal_delta != nullptr &&
working_dual_delta != nullptr) {
ComputeConvergenceAndInfeasibilityFromWorkingSolution(
params, *working_primal_delta, *working_dual_delta,
POINT_TYPE_ITERATE_DIFFERENCE, nullptr,
@@ -1531,6 +1533,9 @@ void PreprocessSolver::ComputeConvergenceAndInfeasibilityFromWorkingSolution(
EpsilonRatio(criteria.eps_optimal_dual_residual_absolute(),
criteria.eps_optimal_dual_residual_relative());
if (presolve_info_.has_value()) {
// Undoing presolve doesn't make sense for iterate differences.
CHECK_NE(candidate_type, POINT_TYPE_ITERATE_DIFFERENCE);
PrimalAndDualSolution original = RecoverOriginalSolution(
{.primal_solution = working_primal, .dual_solution = working_dual});
if (convergence_information != nullptr) {

View File

@@ -1610,6 +1610,39 @@ TEST(PrimalDualHybridGradientTest, DetailedTerminationCriteria) {
EigenArrayNear<double>({0.0, 1.5, -3.5, 0.0}, 1.0e-4));
}
// Regression test for b/311455838. Note that this test only fails in debug
// mode, when an infeasible primal variable (from the iterate differences)
// violates presolve's assumptions and triggers a DCHECK() failure.
TEST(PrimalDualHybridGradientTest, IterateDifferenceBoundsInPresolve) {
// A trivial (but very badly scaled) LP found by fuzzing.
QuadraticProgram lp(2, 1);
lp.objective_offset = -3.0e+23;
lp.objective_vector =
VectorXd{{2.7369110631344083e-48, -3.0517578125211636e-05}};
lp.constraint_lower_bounds = VectorXd{{-2.7369110631344083e-48}};
lp.constraint_upper_bounds = VectorXd{{0}};
lp.variable_lower_bounds = VectorXd{{1.8446744073709552e+21, -1.0}};
lp.variable_upper_bounds = VectorXd{{kInfinity, 1.8446744073709552e+21}};
lp.constraint_matrix.coeffRef(0, 0) = -2.7369110631344083e-48;
lp.constraint_matrix.coeffRef(0, 1) = 1.0;
lp.constraint_matrix.makeCompressed();
PrimalDualHybridGradientParams params;
params.mutable_termination_criteria()->set_iteration_limit(40);
auto& presolve_options = *params.mutable_presolve_options();
presolve_options.set_use_glop(true);
presolve_options.mutable_glop_parameters()->set_solve_dual_problem(
operations_research::glop::GlopParameters::LET_SOLVER_DECIDE);
presolve_options.mutable_glop_parameters()->set_dualizer_threshold(
1.3574141825331e-312);
params.set_infinite_constraint_bound_threshold(1.34785525461908e-312);
SolverResult output = PrimalDualHybridGradient(lp, params);
EXPECT_THAT(
output.solve_log.termination_reason(),
AnyOf(TERMINATION_REASON_ITERATION_LIMIT, TERMINATION_REASON_OPTIMAL));
}
// `FeasibilityPolishingTest` sets `params_` for feasibility polishing, and to
// avoid PDLP features that disrupt a simple analysis of the performance with
// and without feasibility polishing (primal weight adjustments, dynamic step

View File