OR-Tools  9.3
sat_solver_utils.cc
Go to the documentation of this file.
1// Copyright 2010-2021 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
15
16#include "absl/memory/memory.h"
17#include "ortools/glop/parameters.pb.h"
20
21namespace operations_research {
22
23#define ADD_LP_PREPROCESSOR(name) \
24 names.push_back(#name); \
25 lp_preprocessors.push_back(absl::make_unique<name>(&glop_params));
26
28 const glop::GlopParameters& glop_params, MPModelProto* model,
29 std::vector<std::unique_ptr<glop::Preprocessor>>* for_postsolve,
30 SolverLogger* logger) {
31 CHECK(model != nullptr);
32
33 // TODO(user): General constraints are currently not supported.
34 if (!model->general_constraint().empty()) {
36 }
37
38 // We need to copy the hint because LinearProgramToMPModelProto() loose it.
39 const bool hint_is_present = model->has_solution_hint();
40 const auto copy_of_hint = model->solution_hint();
41
42 // TODO(user): Remove this back and forth conversion. We could convert
43 // the LinearProgram directly to a CpModelProto, or we could have a custom
44 // implementation of these presolve steps.
47
48 // These presolve might change the problem size.
49 //
50 // TODO(user): transform the hint instead of disabling presolve.
51 if (!hint_is_present) {
52 const std::string header =
53 "Running basic LP presolve, initial problem dimensions: ";
54 SOLVER_LOG(logger, "");
55 SOLVER_LOG(logger, header, lp.GetDimensionString());
56 std::vector<std::string> names;
57 std::vector<std::unique_ptr<glop::Preprocessor>> lp_preprocessors;
62
63 // TODO(user): Usually it is good to run the ImpliedFreePreprocessor before
64 // this one. However this seems to cause problem on atm20-100.mps. Moreover,
65 // for the conversion, it is better to have tight bounds even if the bound
66 // propagator is supposed to undo what this presolve would have done.
68
69 for (int i = 0; i < lp_preprocessors.size(); ++i) {
70 auto& preprocessor = lp_preprocessors[i];
72 const bool need_postsolve = preprocessor->Run(&lp);
73 names[i].resize(header.size(), ' '); // padding.
74 SOLVER_LOG(logger, names[i], lp.GetDimensionString());
77 if (need_postsolve) for_postsolve->push_back(std::move(preprocessor));
78 }
79 }
80
81 // Finally, we make sure all domains contain zero.
82 if (!hint_is_present) {
83 auto shift_bounds =
84 absl::make_unique<glop::ShiftVariableBoundsPreprocessor>(&glop_params);
85 shift_bounds->UseInMipContext();
86 const bool need_postsolve = shift_bounds->Run(&lp);
87 if (shift_bounds->status() != glop::ProblemStatus::INIT) {
88 return shift_bounds->status();
89 }
90 if (need_postsolve) {
91 for_postsolve->push_back(std::move(shift_bounds));
92 }
93 }
94
96
97 // Restore the hint, note that none of the presolve steps we run here change
98 // the number of variables in the model.
99 if (hint_is_present) {
100 *model->mutable_solution_hint() = copy_of_hint;
101 }
102
104}
105
106#undef ADD_LP_PREPROCESSOR
107
108} // namespace operations_research
#define CHECK(condition)
Definition: base/logging.h:495
std::string GetDimensionString() const
Definition: lp_data.cc:425
absl::Status status
Definition: g_gurobi.cc:35
GRBmodel * model
void MPModelProtoToLinearProgram(const MPModelProto &input, LinearProgram *output)
Definition: proto_utils.cc:51
void LinearProgramToMPModelProto(const LinearProgram &input, MPModelProto *output)
Definition: proto_utils.cc:20
Collection of objects used to extend the Constraint Solver library.
glop::ProblemStatus ApplyMipPresolveSteps(const glop::GlopParameters &glop_params, MPModelProto *model, std::vector< std::unique_ptr< glop::Preprocessor > > *for_postsolve, SolverLogger *logger)
glop::MainLpPreprocessor preprocessor
#define ADD_LP_PREPROCESSOR(name)
#define SOLVER_LOG(logger,...)
Definition: util/logging.h:69