Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
sat_solver_utils.cc
Go to the documentation of this file.
1// Copyright 2010-2024 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/log/check.h"
22#include "ortools/glop/parameters.pb.h"
29
30namespace operations_research {
31
32#define ADD_LP_PREPROCESSOR(name) \
33 names.push_back(#name); \
34 lp_preprocessors.push_back(std::make_unique<name>(&glop_params));
35
37 const glop::GlopParameters& glop_params, MPModelProto* model,
38 std::vector<std::unique_ptr<glop::Preprocessor>>* for_postsolve,
39 SolverLogger* logger) {
40 CHECK(model != nullptr);
41
42 // TODO(user): General constraints are currently not supported.
43 if (!model->general_constraint().empty()) {
45 }
46
47 // We need to copy the hint because LinearProgramToMPModelProto() loose it.
48 const bool hint_is_present = model->has_solution_hint();
49 const auto copy_of_hint = model->solution_hint();
50
51 std::unique_ptr<TimeLimit> time_limit =
52 TimeLimit::FromParameters(glop_params);
53
54 // TODO(user): Remove this back and forth conversion. We could convert
55 // the LinearProgram directly to a CpModelProto, or we could have a custom
56 // implementation of these presolve steps.
59
60 // These presolve might change the problem size.
61 //
62 // TODO(user): transform the hint instead of disabling presolve.
63 if (!hint_is_present) {
64 const std::string header =
65 "Running basic LP presolve, initial problem dimensions: ";
66 SOLVER_LOG(logger, "");
67 SOLVER_LOG(logger, header, lp.GetDimensionString());
68 std::vector<std::string> names;
69 std::vector<std::unique_ptr<glop::Preprocessor>> lp_preprocessors;
74
75 // TODO(user): Usually it is good to run the ImpliedFreePreprocessor before
76 // this one. However this seems to cause problem on atm20-100.mps. Moreover,
77 // for the conversion, it is better to have tight bounds even if the bound
78 // propagator is supposed to undo what this presolve would have done.
80
81 for (int i = 0; i < lp_preprocessors.size(); ++i) {
82 if (time_limit->LimitReached()) break;
83 auto& preprocessor = lp_preprocessors[i];
86 const bool need_postsolve = preprocessor->Run(&lp);
87 names[i].resize(header.size(), ' '); // padding.
88 SOLVER_LOG(logger, names[i], lp.GetDimensionString());
91 if (need_postsolve) for_postsolve->push_back(std::move(preprocessor));
92 }
93 }
94
95 // Finally, we make sure all domains contain zero.
96 if (!hint_is_present) {
97 auto shift_bounds =
98 std::make_unique<glop::ShiftVariableBoundsPreprocessor>(&glop_params);
99 shift_bounds->UseInMipContext();
100 const bool need_postsolve = shift_bounds->Run(&lp);
101 if (shift_bounds->status() != glop::ProblemStatus::INIT) {
102 return shift_bounds->status();
103 }
104 if (need_postsolve) {
105 for_postsolve->push_back(std::move(shift_bounds));
106 }
107 }
108
110
111 // Restore the hint, note that none of the presolve steps we run here change
112 // the number of variables in the model.
113 if (hint_is_present) {
114 *model->mutable_solution_hint() = copy_of_hint;
115 }
116
118}
119
120#undef ADD_LP_PREPROCESSOR
121
122} // namespace operations_research
static std::unique_ptr< TimeLimit > FromParameters(const Parameters &parameters)
Definition time_limit.h:140
Removes the fixed variables from the problem.
Removes the constraints with no bounds from the problem.
std::string GetDimensionString() const
A short string with the problem dimension.
Definition lp_data.cc:434
void SetTimeLimit(TimeLimit *time_limit)
absl::Status status
Definition g_gurobi.cc:44
GRBmodel * model
time_limit
Definition solve.cc:22
void LinearProgramToMPModelProto(const LinearProgram &input, MPModelProto *output)
Converts a LinearProgram to a MPModelProto.
ProblemStatus
Different statuses for a given problem.
Definition lp_types.h:107
@ INIT
The solver didn't had a chance to prove anything.
void MPModelProtoToLinearProgram(const MPModelProto &input, LinearProgram *output)
Converts a MPModelProto to a LinearProgram.
In SWIG mode, we don't want anything besides these top-level includes.
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 logging.h:109