Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
sat_interface.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
14#include <atomic>
15#include <cstdint>
16#include <optional>
17#include <string>
18#include <utility>
19#include <vector>
20
21#include "absl/base/attributes.h"
22#include "absl/status/status.h"
23#include "absl/status/statusor.h"
26#include "ortools/linear_solver/linear_solver.pb.h"
30#include "ortools/sat/cp_model.pb.h"
33
34namespace operations_research {
35
37 public:
38 explicit SatInterface(MPSolver* solver);
39 ~SatInterface() override;
40
41 // ----- Solve -----
42 MPSolver::ResultStatus Solve(const MPSolverParameters& param) override;
43 bool InterruptSolve() override;
44
45 // ----- Directly solve proto is supported ---
46 bool SupportsDirectlySolveProto(std::atomic<bool>* interrupt) const override {
47 return true;
48 }
50 std::atomic<bool>* interrupt) override {
51 return SatSolveProto(std::move(request), interrupt);
52 }
53
54 // ----- Model modifications and extraction -----
55 void Reset() override;
56 void SetOptimizationDirection(bool maximize) override;
57 void SetVariableBounds(int index, double lb, double ub) override;
58 void SetVariableInteger(int index, bool integer) override;
59 void SetConstraintBounds(int index, double lb, double ub) override;
60 void AddRowConstraint(MPConstraint* ct) override;
61 void AddVariable(MPVariable* var) override;
62 void SetCoefficient(MPConstraint* constraint, const MPVariable* variable,
63 double new_value, double old_value) override;
64 void ClearConstraint(MPConstraint* constraint) override;
65 void SetObjectiveCoefficient(const MPVariable* variable,
66 double coefficient) override;
67 void SetObjectiveOffset(double value) override;
68 void ClearObjective() override;
69
70 bool AddIndicatorConstraint(MPConstraint* const ct) override { return true; }
71
72 // ------ Query statistics on the solution and the solve ------
73 int64_t iterations() const override;
74 int64_t nodes() const override;
76 MPSolver::BasisStatus column_status(int variable_index) const override;
77
78 // ----- Misc -----
79 bool IsContinuous() const override;
80 bool IsLP() const override;
81 bool IsMIP() const override;
82
83 std::string SolverVersion() const override;
84 void* underlying_solver() override;
85
86 void ExtractNewVariables() override;
87 void ExtractNewConstraints() override;
88 void ExtractObjective() override;
89
90 void SetParameters(const MPSolverParameters& param) override;
91 void SetRelativeMipGap(double value) override;
92 void SetPrimalTolerance(double value) override;
93 void SetDualTolerance(double value) override;
94 void SetPresolveMode(int value) override;
95 void SetScalingMode(int value) override;
96 void SetLpAlgorithm(int value) override;
98 const std::string& parameters) override;
99 absl::Status SetNumThreads(int num_threads) override;
100
101 private:
102 void NonIncrementalChange();
103
104 std::atomic<bool> interrupt_solve_;
105 sat::SatParameters parameters_;
106 int num_threads_ = 0;
107};
108
110 : MPSolverInterface(solver), interrupt_solve_(false) {}
111
113
115 interrupt_solve_ = false;
116
117 // Reset extraction as this interface is not incremental yet.
118 Reset();
119 ExtractModel();
120
121 SetParameters(param);
123 solver_->solver_specific_parameter_string_);
124
125 // Time limit.
126 if (solver_->time_limit()) {
127 VLOG(1) << "Setting time limit = " << solver_->time_limit() << " ms.";
128 parameters_.set_max_time_in_seconds(
129 static_cast<double>(solver_->time_limit()) / 1000.0);
130 }
131
132 // Mark variables and constraints as extracted.
133 for (int i = 0; i < solver_->variables_.size(); ++i) {
135 }
136 for (int i = 0; i < solver_->constraints_.size(); ++i) {
138 }
139
140 MPModelRequest request;
141 solver_->ExportModelToProto(request.mutable_model());
142 request.set_solver_specific_parameters(EncodeParametersAsString(parameters_));
143 request.set_enable_internal_solver_output(!quiet_);
144
145 const MPSolutionResponse response =
146 SatSolveProto(std::move(request), &interrupt_solve_);
147
148 // The solution must be marked as synchronized even when no solution exists.
150 result_status_ = static_cast<MPSolver::ResultStatus>(response.status());
151
152 if (response.status() == MPSOLVER_FEASIBLE ||
153 response.status() == MPSOLVER_OPTIMAL) {
154 const absl::Status result = solver_->LoadSolutionFromProto(response);
155 if (!result.ok()) {
156 LOG(ERROR) << "LoadSolutionFromProto failed: " << result;
157 }
158 }
159
160 return result_status_;
161}
162
164 interrupt_solve_ = true;
165 return true;
166}
167
169
171 NonIncrementalChange();
172}
173
174void SatInterface::SetVariableBounds(int index, double lb, double ub) {
175 NonIncrementalChange();
176}
177
179 NonIncrementalChange();
180}
181
182void SatInterface::SetConstraintBounds(int index, double lb, double ub) {
183 NonIncrementalChange();
184}
185
187 NonIncrementalChange();
188}
189
191 NonIncrementalChange();
192}
193
195 const MPVariable* const variable,
196 double new_value, double old_value) {
197 NonIncrementalChange();
198}
199
201 NonIncrementalChange();
202}
203
205 double coefficient) {
206 NonIncrementalChange();
207}
208
209void SatInterface::SetObjectiveOffset(double value) { NonIncrementalChange(); }
210
211void SatInterface::ClearObjective() { NonIncrementalChange(); }
212
214 return 0; // FIXME
215}
216
217int64_t SatInterface::nodes() const { return 0; }
218
222
224 return MPSolver::BasisStatus::FREE; // FIXME
225}
226
227bool SatInterface::IsContinuous() const { return false; }
228bool SatInterface::IsLP() const { return false; }
229bool SatInterface::IsMIP() const { return true; }
230
231std::string SatInterface::SolverVersion() const {
233}
234
235void* SatInterface::underlying_solver() { return nullptr; }
236
237void SatInterface::ExtractNewVariables() { NonIncrementalChange(); }
238
239void SatInterface::ExtractNewConstraints() { NonIncrementalChange(); }
240
241void SatInterface::ExtractObjective() { NonIncrementalChange(); }
242
244 parameters_.Clear();
245 parameters_.set_num_workers(num_threads_);
246 SetCommonParameters(param);
247}
248
249absl::Status SatInterface::SetNumThreads(int num_threads) {
250 num_threads_ = num_threads;
251 return absl::OkStatus();
252}
253
254// All these have no effect.
260
261// TODO(user): Implement me.
263
268
269void SatInterface::NonIncrementalChange() {
270 // The current implementation is not incremental.
272}
273
274// Register Sat in the global linear solver factory.
276 return new SatInterface(solver);
277}
278
279} // namespace operations_research
void set_variable_as_extracted(int var_index, bool extracted)
void set_constraint_as_extracted(int ct_index, bool extracted)
void ResetExtractionInformation()
Resets the extraction information.
void ExtractModel()
Extracts model stored in MPSolver.
bool quiet_
Boolean indicator for the verbosity of the solver output.
void SetCommonParameters(const MPSolverParameters &param)
Sets parameters common to LP and MIP in the underlying solver.
SynchronizationStatus sync_status_
Indicates whether the model and the solution are synchronized.
bool SetSolverSpecificParametersAsString(const std::string &parameters)
void ExportModelToProto(MPModelProto *output_model) const
Exports model to protocol buffer.
absl::Status LoadSolutionFromProto(const MPSolutionResponse &response, double tolerance=std::numeric_limits< double >::infinity())
The class for variables of a Mathematical Programming (MP) model.
void SetRelativeMipGap(double value) override
Sets each parameter in the underlying solver.
void AddVariable(MPVariable *var) override
Add a variable.
void SetObjectiveOffset(double value) override
Changes the constant term in the linear objective.
void SetCoefficient(MPConstraint *constraint, const MPVariable *variable, double new_value, double old_value) override
Changes a coefficient in a constraint.
void SetVariableBounds(int index, double lb, double ub) override
Modifies bounds of an extracted variable.
bool SupportsDirectlySolveProto(std::atomic< bool > *interrupt) const override
--— Directly solve proto is supported —
absl::Status SetNumThreads(int num_threads) override
Sets the number of threads to be used by the solver.
void * underlying_solver() override
Returns the underlying solver.
void ExtractObjective() override
Extracts the objective.
void SetObjectiveCoefficient(const MPVariable *variable, double coefficient) override
Changes a coefficient in the linear objective.
void AddRowConstraint(MPConstraint *ct) override
Adds a linear constraint.
void Reset() override
--— Model modifications and extraction --—
MPSolver::ResultStatus Solve(const MPSolverParameters &param) override
--— Solve --—
void SetScalingMode(int value) override
Sets the scaling mode.
void SetVariableInteger(int index, bool integer) override
Modifies integrality of an extracted variable.
void ClearConstraint(MPConstraint *constraint) override
Clears a constraint from all its terms.
int64_t nodes() const override
void ExtractNewConstraints() override
Extracts the constraints that have not been extracted yet.
bool IsContinuous() const override
--— Misc --—
bool IsMIP() const override
Returns true if the problem is discrete and linear.
void SetPresolveMode(int value) override
std::string SolverVersion() const override
Returns a string describing the underlying solver and its version.
void SetDualTolerance(double value) override
void SetOptimizationDirection(bool maximize) override
Sets the optimization direction (min/max).
void ExtractNewVariables() override
Extracts the variables that have not been extracted yet.
bool IsLP() const override
Returns true if the problem is continuous and linear.
int64_t iterations() const override
---— Query statistics on the solution and the solve ---—
bool SetSolverSpecificParametersAsString(const std::string &parameters) override
bool AddIndicatorConstraint(MPConstraint *const ct) override
MPSolutionResponse DirectlySolveProto(LazyMutableCopy< MPModelRequest > request, std::atomic< bool > *interrupt) override
void SetConstraintBounds(int index, double lb, double ub) override
Modify bounds of an extracted variable.
void ClearObjective() override
Clears the objective from all its terms.
MPSolver::BasisStatus column_status(int variable_index) const override
Returns the basis status of a constraint.
void SetPrimalTolerance(double value) override
All these have no effect.
MPSolver::BasisStatus row_status(int constraint_index) const override
Returns the basis status of a row.
void SetLpAlgorithm(int value) override
void SetParameters(const MPSolverParameters &param) override
Sets all parameters in the underlying solver.
SatParameters parameters
const Constraint * ct
int64_t value
IntVar * var
int constraint_index
int index
std::string CpSatSolverVersion()
Returns a string that describes the version of the solver.
In SWIG mode, we don't want anything besides these top-level includes.
MPSolutionResponse SatSolveProto(LazyMutableCopy< MPModelRequest > request, std::atomic< bool > *interrupt_solve, std::function< void(const std::string &)> logging_callback, std::function< void(const MPSolution &)> solution_callback)
std::string EncodeParametersAsString(const P &parameters)
Definition proto_utils.h:75
MPSolverInterface * BuildSatInterface(MPSolver *const solver)
Register Sat in the global linear solver factory.
bool ProtobufTextFormatMergeFromString(absl::string_view proto_text_string, ProtoType *proto)
Definition proto_utils.h:66
int64_t coefficient