Skip to content

Commit

Permalink
improvement to PDLP, remove most GLPK from tests, add py.typed for CP…
Browse files Browse the repository at this point in the history
…-SAT and model_builder python modules: fix #3993
  • Loading branch information
lperron committed Nov 22, 2023
1 parent e3801a8 commit 6136a47
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 11 deletions.
26 changes: 16 additions & 10 deletions ortools/linear_solver/java/LinearSolverTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ private void runBasicCtor(MPSolver.OptimizationProblemType solverType) {
@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);
}
Expand Down Expand Up @@ -129,10 +127,12 @@ private void runLinearSolver(
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);
}

Expand Down Expand Up @@ -224,7 +224,8 @@ private void runFirstLinearExample(MPSolver.OptimizationProblemType problemType)
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);
}

Expand Down Expand Up @@ -266,7 +267,8 @@ private void runFirstMIPExample(MPSolver.OptimizationProblemType problemType) {
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);
Expand Down Expand Up @@ -318,11 +320,13 @@ private void runSuccessiveObjectives(MPSolver.OptimizationProblemType problemTyp
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);
Expand Down Expand Up @@ -375,11 +379,13 @@ private void runObjectiveOffset(MPSolver.OptimizationProblemType problemType) {
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);
Expand Down
Empty file.
7 changes: 6 additions & 1 deletion ortools/pdlp/primal_dual_hybrid_gradient.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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) {
Expand Down
33 changes: 33 additions & 0 deletions ortools/pdlp/primal_dual_hybrid_gradient_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Empty file added ortools/sat/python/py.typed
Empty file.

0 comments on commit 6136a47

Please sign in to comment.