Skip to content

Commit 05c362a

Browse files
committed
[GLOP] honor time limits better
1 parent 3a73fa1 commit 05c362a

File tree

4 files changed

+20
-2
lines changed

4 files changed

+20
-2
lines changed

ortools/glop/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ cc_library(
265265
"//ortools/lp_data:lp_utils",
266266
"//ortools/lp_data:scattered_vector",
267267
"//ortools/util:stats",
268+
"//ortools/util:time_limit",
268269
],
269270
)
270271

@@ -330,6 +331,7 @@ cc_library(
330331
"//ortools/lp_data:lp_utils",
331332
"//ortools/lp_data:scattered_vector",
332333
"//ortools/util:stats",
334+
"//ortools/util:time_limit",
333335
],
334336
)
335337

ortools/glop/dual_edge_norms.cc

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ void DualEdgeNorms::UpdateBeforeBasisPivot(
105105

106106
// Avoid 0.0 norms (The 1e-4 is the value used by Koberstein).
107107
// TODO(user): use a more precise lower bound depending on the column norm?
108-
// We can do that with Cauchy-Swartz inequality:
108+
// We can do that with Cauchy-Schwarz inequality:
109109
// (edge . leaving_column)^2 = 1.0 < ||edge||^2 * ||leaving_column||^2
110110
const Fractional kLowerBound = 1e-4;
111111
if (output[e.row()] < kLowerBound) {
@@ -121,13 +121,23 @@ void DualEdgeNorms::UpdateBeforeBasisPivot(
121121
void DualEdgeNorms::ComputeEdgeSquaredNorms() {
122122
SCOPED_TIME_STAT(&stats_);
123123

124+
// time_limit_->LimitReached() can be costly sometimes, so we only do that
125+
// if we feel this will be slow anyway.
126+
const bool test_limit = (time_limit_ != nullptr) &&
127+
basis_factorization_.NumberOfEntriesInLU() > 10'000;
128+
124129
// Since we will do a lot of inversions, it is better to be as efficient and
125130
// precise as possible by having a refactorized basis.
126131
DCHECK(basis_factorization_.IsRefactorized());
127132
const RowIndex num_rows = basis_factorization_.GetNumberOfRows();
128-
edge_squared_norms_.resize(num_rows, 0.0);
133+
edge_squared_norms_.resize(num_rows, 1.0);
129134
for (RowIndex row(0); row < num_rows; ++row) {
130135
edge_squared_norms_[row] = basis_factorization_.DualEdgeSquaredNorm(row);
136+
137+
// This operation can be costly, and we abort if we are stuck here.
138+
// Note that we still mark edges as "recomputed" otherwise we can runs into
139+
// some DCHECK before we actually abort the solve.
140+
if (test_limit && time_limit_->LimitReached()) break;
131141
}
132142
recompute_edge_squared_norms_ = false;
133143
}

ortools/glop/dual_edge_norms.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "ortools/lp_data/permutation.h"
2424
#include "ortools/lp_data/scattered_vector.h"
2525
#include "ortools/util/stats.h"
26+
#include "ortools/util/time_limit.h"
2627

2728
namespace operations_research {
2829
namespace glop {
@@ -102,6 +103,8 @@ class DualEdgeNorms {
102103
parameters_ = parameters;
103104
}
104105

106+
void SetTimeLimit(TimeLimit* time_limit) { time_limit_ = time_limit; }
107+
105108
// Stats related functions.
106109
std::string StatString() const { return stats_.StatString(); }
107110

@@ -130,6 +133,7 @@ class DualEdgeNorms {
130133

131134
// Parameters.
132135
GlopParameters parameters_;
136+
TimeLimit* time_limit_ = nullptr;
133137

134138
// Problem data that should be updated from outside.
135139
const BasisFactorization& basis_factorization_;

ortools/glop/revised_simplex.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,8 @@ ABSL_MUST_USE_RESULT Status RevisedSimplex::SolveInternal(
221221

222222
SOLVER_LOG(logger_, "");
223223
primal_edge_norms_.SetTimeLimit(time_limit);
224+
dual_edge_norms_.SetTimeLimit(time_limit);
225+
224226
if (logger_->LoggingIsEnabled()) {
225227
DisplayBasicVariableStatistics();
226228
}

0 commit comments

Comments
 (0)