OR-Tools  9.6
sat_solver_utils.cc
Go to the documentation of this file.
1 // Copyright 2010-2022 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 <memory>
17 #include <string>
18 #include <utility>
19 #include <vector>
20 
21 #include "absl/memory/memory.h"
22 #include "ortools/glop/parameters.pb.h"
25 
26 namespace operations_research {
27 
28 #define ADD_LP_PREPROCESSOR(name) \
29  names.push_back(#name); \
30  lp_preprocessors.push_back(std::make_unique<name>(&glop_params));
31 
33  const glop::GlopParameters& glop_params, MPModelProto* model,
34  std::vector<std::unique_ptr<glop::Preprocessor>>* for_postsolve,
35  SolverLogger* logger) {
36  CHECK(model != nullptr);
37 
38  // TODO(user): General constraints are currently not supported.
39  if (!model->general_constraint().empty()) {
41  }
42 
43  // We need to copy the hint because LinearProgramToMPModelProto() loose it.
44  const bool hint_is_present = model->has_solution_hint();
45  const auto copy_of_hint = model->solution_hint();
46 
47  // TODO(user): Remove this back and forth conversion. We could convert
48  // the LinearProgram directly to a CpModelProto, or we could have a custom
49  // implementation of these presolve steps.
52 
53  // These presolve might change the problem size.
54  //
55  // TODO(user): transform the hint instead of disabling presolve.
56  if (!hint_is_present) {
57  const std::string header =
58  "Running basic LP presolve, initial problem dimensions: ";
59  SOLVER_LOG(logger, "");
60  SOLVER_LOG(logger, header, lp.GetDimensionString());
61  std::vector<std::string> names;
62  std::vector<std::unique_ptr<glop::Preprocessor>> lp_preprocessors;
67 
68  // TODO(user): Usually it is good to run the ImpliedFreePreprocessor before
69  // this one. However this seems to cause problem on atm20-100.mps. Moreover,
70  // for the conversion, it is better to have tight bounds even if the bound
71  // propagator is supposed to undo what this presolve would have done.
73 
74  for (int i = 0; i < lp_preprocessors.size(); ++i) {
75  auto& preprocessor = lp_preprocessors[i];
77  const bool need_postsolve = preprocessor->Run(&lp);
78  names[i].resize(header.size(), ' '); // padding.
79  SOLVER_LOG(logger, names[i], lp.GetDimensionString());
82  if (need_postsolve) for_postsolve->push_back(std::move(preprocessor));
83  }
84  }
85 
86  // Finally, we make sure all domains contain zero.
87  if (!hint_is_present) {
88  auto shift_bounds =
89  std::make_unique<glop::ShiftVariableBoundsPreprocessor>(&glop_params);
90  shift_bounds->UseInMipContext();
91  const bool need_postsolve = shift_bounds->Run(&lp);
92  if (shift_bounds->status() != glop::ProblemStatus::INIT) {
93  return shift_bounds->status();
94  }
95  if (need_postsolve) {
96  for_postsolve->push_back(std::move(shift_bounds));
97  }
98  }
99 
101 
102  // Restore the hint, note that none of the presolve steps we run here change
103  // the number of variables in the model.
104  if (hint_is_present) {
105  *model->mutable_solution_hint() = copy_of_hint;
106  }
107 
109 }
110 
111 #undef ADD_LP_PREPROCESSOR
112 
113 } // namespace operations_research
std::string GetDimensionString() const
Definition: lp_data.cc:426
absl::Status status
Definition: g_gurobi.cc:41
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