cleanup, new logs

This commit is contained in:
Laurent Perron
2023-04-21 12:46:52 +02:00
parent dfdf042f6b
commit c08f1b7e79
5 changed files with 47 additions and 12 deletions

View File

@@ -118,11 +118,13 @@ cc_library(
"//ortools/lp_data",
"//ortools/lp_data:base",
"//ortools/lp_data:proto_utils",
"@com_google_absl//absl/algorithm:container",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/strings:str_format",
"@com_google_absl//absl/time",
"@com_google_protobuf//:protobuf",
"@eigen//:eigen3",
],
)

View File

@@ -27,6 +27,7 @@
#include "Eigen/Core"
#include "Eigen/SparseCore"
#include "absl/algorithm/container.h"
#include "absl/log/check.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
@@ -35,6 +36,7 @@
#include "absl/strings/string_view.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
#include "google/protobuf/repeated_ptr_field.h"
#include "ortools/base/logging.h"
#include "ortools/base/mathutil.h"
#include "ortools/base/timer.h"
@@ -800,29 +802,39 @@ std::optional<SolverResult> CheckProblemStats(
<< " and smallest non-zero absolute value "
<< problem_stats.combined_bounds_min() << "; performance may suffer.";
}
if (std::isnan(problem_stats.variable_bound_gaps_l2_norm())) {
if (std::isnan(problem_stats.combined_variable_bounds_l2_norm())) {
return ErrorSolverResult(TERMINATION_REASON_INVALID_PROBLEM,
"Variable bounds vector has a NAN.");
}
if (problem_stats.variable_bound_gaps_max() > kExcessiveInputValue) {
if (problem_stats.combined_variable_bounds_max() > kExcessiveInputValue) {
return ErrorSolverResult(
TERMINATION_REASON_INVALID_PROBLEM,
absl::StrCat("Variable bound gaps vector has a finite non-zero with "
absl::StrCat("Combined variable bounds vector has a non-zero with "
"absolute value ",
problem_stats.variable_bound_gaps_max(),
problem_stats.combined_variable_bounds_max(),
" which exceeds limit of ", kExcessiveInputValue, "."));
}
if (check_excessively_small_values &&
problem_stats.variable_bound_gaps_min() > 0 &&
problem_stats.variable_bound_gaps_min() < kExcessivelySmallInputValue) {
problem_stats.combined_variable_bounds_min() > 0 &&
problem_stats.combined_variable_bounds_min() <
kExcessivelySmallInputValue) {
return ErrorSolverResult(
TERMINATION_REASON_INVALID_PROBLEM,
absl::StrCat("Variable bound gaps vector has a finite non-zero with "
absl::StrCat("Combined variable bounds vector has a non-zero with "
"absolute value ",
problem_stats.variable_bound_gaps_min(),
problem_stats.combined_variable_bounds_min(),
" which is less than the limit of ",
kExcessivelySmallInputValue, "."));
}
if (problem_stats.combined_variable_bounds_max() >
kMaxDynamicRange * problem_stats.combined_variable_bounds_min()) {
LOG(WARNING)
<< "Combined variable bounds vector has largest absolute value "
<< problem_stats.combined_variable_bounds_max()
<< " and smallest non-zero absolute value "
<< problem_stats.combined_variable_bounds_min()
<< "; performance may suffer.";
}
if (problem_stats.variable_bound_gaps_max() >
kMaxDynamicRange * problem_stats.variable_bound_gaps_min()) {
LOG(WARNING) << "Variable bound gap vector has largest absolute value "
@@ -1707,7 +1719,7 @@ Solver::NextSolutionAndDelta Solver::ComputeNextDualSolution(
extrapolation_factor * shard(next_primal_solution.delta));
});
// TODO(user): Refactor this multiplication so that we only do one matrix
// vector mutiply for the primal variable. This only applies to Malitsky and
// vector multiply for the primal variable. This only applies to Malitsky and
// Pock and not to the adaptive step size rule.
ShardedWorkingQp().TransposedConstraintMatrixSharder().ParallelForEachShard(
[&](const Sharder::Shard& shard) {

View File

@@ -1193,7 +1193,7 @@ TEST(PrimalDualHybridGradientTest, DetectsNanInVariableBound) {
TERMINATION_REASON_INVALID_PROBLEM);
}
TEST(PrimalDualHybridGradientTest, DetectsExcessiveVariableBoundGap) {
TEST(PrimalDualHybridGradientTest, DetectsExcessiveVariableBound) {
QuadraticProgram qp = TestLp();
qp.variable_lower_bounds[3] = -1.0e60;
SolverResult output =
@@ -1203,7 +1203,7 @@ TEST(PrimalDualHybridGradientTest, DetectsExcessiveVariableBoundGap) {
}
TEST(PrimalDualHybridGradientTest,
ExcessivelySmallVariableBoundGapOkWithoutPresolve) {
ExcessivelySmallVariableBoundOkWithoutPresolve) {
QuadraticProgram qp = TestLp();
qp.variable_lower_bounds[1] = 0.0;
qp.variable_upper_bounds[1] = 1.0e-60;
@@ -1213,7 +1213,7 @@ TEST(PrimalDualHybridGradientTest,
}
TEST(PrimalDualHybridGradientTest,
DetectsExcessivelySmallVariableBoundGapWithPresolve) {
DetectsExcessivelySmallVariableBoundWithPresolve) {
QuadraticProgram qp = TestLp();
qp.variable_lower_bounds[1] = 0.0;
qp.variable_upper_bounds[1] = 1.0e-60;

View File

@@ -285,6 +285,9 @@ QuadraticProgramStats ComputeStats(
VectorInfo combined_bounds_info = CombinedBoundsInfo(
qp.Qp().constraint_lower_bounds, qp.Qp().constraint_upper_bounds,
qp.DualSharder(), infinite_constraint_bound_threshold);
VectorInfo combined_variable_bounds_info = CombinedBoundsInfo(
qp.Qp().variable_lower_bounds, qp.Qp().variable_upper_bounds,
qp.PrimalSharder(), kInfinity);
VectorInfo obj_vec_info =
ComputeVectorInfo(qp.Qp().objective_vector, qp.PrimalSharder());
VectorInfo gaps_info =
@@ -307,6 +310,14 @@ QuadraticProgramStats ComputeStats(
program_stats.set_combined_bounds_min(combined_bounds_info.smallest);
program_stats.set_combined_bounds_avg(combined_bounds_info.average);
program_stats.set_combined_bounds_l2_norm(combined_bounds_info.l2_norm);
program_stats.set_combined_variable_bounds_max(
combined_variable_bounds_info.largest);
program_stats.set_combined_variable_bounds_min(
combined_variable_bounds_info.smallest);
program_stats.set_combined_variable_bounds_avg(
combined_variable_bounds_info.average);
program_stats.set_combined_variable_bounds_l2_norm(
combined_variable_bounds_info.l2_norm);
program_stats.set_variable_bound_gaps_num_finite(
gaps_info.num_finite_nonzero + gaps_info.num_zero);
program_stats.set_variable_bound_gaps_max(gaps_info.largest);

View File

@@ -57,6 +57,16 @@ message QuadraticProgramStats {
optional double combined_bounds_avg = 11;
optional double combined_bounds_l2_norm = 24;
// Statistics of the combined vector of the variable lower and upper bounds.
// See the comment before `combined_bounds_max` for a description of the
// "combined bounds" vector. The min is over the nonzero combined bounds. If
// there are no variables, the values returned are 0 for the maximum, minimum,
// and l2 norm and NaN for the average.
optional double combined_variable_bounds_max = 28;
optional double combined_variable_bounds_min = 29;
optional double combined_variable_bounds_avg = 30;
optional double combined_variable_bounds_l2_norm = 31;
// Number of finite variable bound gaps, which are the elementwise difference
// between the upper and lower bounds on primal feasible solutions.
optional int64 variable_bound_gaps_num_finite = 12;