OR-Tools  8.0
sat_interface.cc
Go to the documentation of this file.
1 // Copyright 2010-2018 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 <string>
16 #include <vector>
17 
18 #include "absl/status/status.h"
19 #include "ortools/base/hash.h"
21 #include "ortools/base/logging.h"
22 #include "ortools/base/statusor.h"
29 #include "ortools/sat/lp_utils.h"
30 #include "ortools/sat/model.h"
32 
33 namespace operations_research {
34 
35 #if defined(PROTOBUF_INTERNAL_IMPL)
36 using google::protobuf::Message;
37 #else
38 using google::protobuf::Message;
39 #endif
40 
42  public:
43  explicit SatInterface(MPSolver* const solver);
44  ~SatInterface() override;
45 
46  // ----- Solve -----
47  MPSolver::ResultStatus Solve(const MPSolverParameters& param) override;
48  bool InterruptSolve() override;
49 
50  // ----- Model modifications and extraction -----
51  void Reset() override;
52  void SetOptimizationDirection(bool maximize) override;
53  void SetVariableBounds(int index, double lb, double ub) override;
54  void SetVariableInteger(int index, bool integer) override;
55  void SetConstraintBounds(int index, double lb, double ub) override;
56  void AddRowConstraint(MPConstraint* const ct) override;
57  void AddVariable(MPVariable* const var) override;
58  void SetCoefficient(MPConstraint* const constraint,
59  const MPVariable* const variable, double new_value,
60  double old_value) override;
61  void ClearConstraint(MPConstraint* const constraint) override;
62  void SetObjectiveCoefficient(const MPVariable* const variable,
63  double coefficient) override;
64  void SetObjectiveOffset(double value) override;
65  void ClearObjective() override;
66 
67  bool AddIndicatorConstraint(MPConstraint* const ct) override { return true; }
68 
69  // ------ Query statistics on the solution and the solve ------
70  int64 iterations() const override;
71  int64 nodes() const override;
72  double best_objective_bound() const override;
73  MPSolver::BasisStatus row_status(int constraint_index) const override;
74  MPSolver::BasisStatus column_status(int variable_index) const override;
75 
76  // ----- Misc -----
77  bool IsContinuous() const override;
78  bool IsLP() const override;
79  bool IsMIP() const override;
80 
81  std::string SolverVersion() const override;
82  void* underlying_solver() override;
83 
84  void ExtractNewVariables() override;
85  void ExtractNewConstraints() override;
86  void ExtractObjective() override;
87 
88  void SetParameters(const MPSolverParameters& param) override;
89  void SetRelativeMipGap(double value) override;
90  void SetPrimalTolerance(double value) override;
91  void SetDualTolerance(double value) override;
92  void SetPresolveMode(int value) override;
93  void SetScalingMode(int value) override;
94  void SetLpAlgorithm(int value) override;
96  const std::string& parameters) override;
97  absl::Status SetNumThreads(int num_threads) override;
98 
99  private:
100  void NonIncrementalChange();
101 
102  std::atomic<bool> interrupt_solve_;
103  sat::SatParameters parameters_;
104  int num_threads_ = 8;
105  double best_objective_bound_ = 0.0;
106 };
107 
109  : MPSolverInterface(solver), interrupt_solve_(false) {}
110 
112 
114  interrupt_solve_ = false;
115 
116  // Reset extraction as this interface is not incremental yet.
117  Reset();
118  ExtractModel();
119 
120  SetParameters(param);
122  solver_->solver_specific_parameter_string_);
123 
124  // Time limit.
125  if (solver_->time_limit()) {
126  VLOG(1) << "Setting time limit = " << solver_->time_limit() << " ms.";
127  parameters_.set_max_time_in_seconds(
128  static_cast<double>(solver_->time_limit()) / 1000.0);
129  }
130 
131  // Mark variables and constraints as extracted.
132  for (int i = 0; i < solver_->variables_.size(); ++i) {
133  set_variable_as_extracted(i, true);
134  }
135  for (int i = 0; i < solver_->constraints_.size(); ++i) {
137  }
138 
139  MPModelRequest request;
140  solver_->ExportModelToProto(request.mutable_model());
141  // If sat::SatParameters is compiled with proto-lite (go/mobile-cpp-protos),
142  // then serialize as non-human readable string. This is because proto-lite
143  // does not support reflection mechanism, which is a prerequisite for method
144  // like `ShortDebugString`.
146  request.set_solver_specific_parameters(parameters_.SerializeAsString());
147  } else {
148  request.set_solver_specific_parameters(parameters_.ShortDebugString());
149  }
150  request.set_enable_internal_solver_output(!quiet_);
151  const absl::StatusOr<MPSolutionResponse> status_or =
152  SatSolveProto(std::move(request), &interrupt_solve_);
153 
154  if (!status_or.ok()) return MPSolver::ABNORMAL;
155  const MPSolutionResponse& response = status_or.value();
156 
157  // The solution must be marked as synchronized even when no solution exists.
159  switch (response.status()) {
160  case MPSOLVER_OPTIMAL:
162  break;
163  case MPSOLVER_FEASIBLE:
165  break;
166  case MPSOLVER_INFEASIBLE:
168  break;
171  break;
172  default:
174  break;
175  }
176 
177  // TODO(user): Just use LoadSolutionFromProto(), but fix that function first
178  // to load everything and not just the solution.
179  if (response.status() == MPSOLVER_FEASIBLE ||
180  response.status() == MPSOLVER_OPTIMAL) {
181  objective_value_ = response.objective_value();
182  best_objective_bound_ = response.best_objective_bound();
183  const size_t num_vars = solver_->variables_.size();
184  for (int var_id = 0; var_id < num_vars; ++var_id) {
185  MPVariable* const var = solver_->variables_[var_id];
186  var->set_solution_value(response.variable_value(var_id));
187  }
188  }
189 
190  return result_status_;
191 }
192 
194  interrupt_solve_ = true;
195  return true;
196 }
197 
199 
201  NonIncrementalChange();
202 }
203 
204 void SatInterface::SetVariableBounds(int index, double lb, double ub) {
205  NonIncrementalChange();
206 }
207 
208 void SatInterface::SetVariableInteger(int index, bool integer) {
209  NonIncrementalChange();
210 }
211 
212 void SatInterface::SetConstraintBounds(int index, double lb, double ub) {
213  NonIncrementalChange();
214 }
215 
217  NonIncrementalChange();
218 }
219 
221  NonIncrementalChange();
222 }
223 
225  const MPVariable* const variable,
226  double new_value, double old_value) {
227  NonIncrementalChange();
228 }
229 
231  NonIncrementalChange();
232 }
233 
235  double coefficient) {
236  NonIncrementalChange();
237 }
238 
239 void SatInterface::SetObjectiveOffset(double value) { NonIncrementalChange(); }
240 
241 void SatInterface::ClearObjective() { NonIncrementalChange(); }
242 
244  return 0; // FIXME
245 }
246 
247 int64 SatInterface::nodes() const { return 0; }
248 
252  }
253  return best_objective_bound_;
254 }
255 
256 MPSolver::BasisStatus SatInterface::row_status(int constraint_index) const {
257  return MPSolver::BasisStatus::FREE; // FIXME
258 }
259 
261  return MPSolver::BasisStatus::FREE; // FIXME
262 }
263 
264 bool SatInterface::IsContinuous() const { return false; }
265 bool SatInterface::IsLP() const { return false; }
266 bool SatInterface::IsMIP() const { return true; }
267 
268 std::string SatInterface::SolverVersion() const {
269  return "SAT Based MIP Solver";
270 }
271 
272 void* SatInterface::underlying_solver() { return nullptr; }
273 
274 void SatInterface::ExtractNewVariables() { NonIncrementalChange(); }
275 
276 void SatInterface::ExtractNewConstraints() { NonIncrementalChange(); }
277 
278 void SatInterface::ExtractObjective() { NonIncrementalChange(); }
279 
281  // By default, we use 8 threads as it allows to try a good set of orthogonal
282  // parameters. This can be overridden by the user.
283  parameters_.set_num_search_workers(num_threads_);
284  parameters_.set_log_search_progress(!quiet_);
285  SetCommonParameters(param);
286 }
287 
288 absl::Status SatInterface::SetNumThreads(int num_threads) {
289  num_threads_ = num_threads;
290  return absl::OkStatus();
291 }
292 
293 // All these have no effect.
299 
300 // TODO(user): Implement me.
302 
304  const std::string& parameters) {
305  return ProtobufTextFormatMergeFromString(parameters, &parameters_);
306 }
307 
308 void SatInterface::NonIncrementalChange() {
309  // The current implementation is not incremental.
311 }
312 
313 // Register Sat in the global linear solver factory.
315  return new SatInterface(solver);
316 }
317 
318 } // namespace operations_research
var
IntVar * var
Definition: expr_array.cc:1858
response
SharedResponseManager * response
Definition: cp_model_solver.cc:2065
integral_types.h
cp_model.pb.h
operations_research::SatInterface::SetNumThreads
absl::Status SetNumThreads(int num_threads) override
Definition: sat_interface.cc:288
time_limit.h
operations_research::SatInterface::IsMIP
bool IsMIP() const override
Definition: sat_interface.cc:266
operations_research::SatInterface::AddIndicatorConstraint
bool AddIndicatorConstraint(MPConstraint *const ct) override
Definition: sat_interface.cc:67
absl::StatusOr::ok
bool ok() const
Definition: statusor.h:35
operations_research::SatInterface::AddVariable
void AddVariable(MPVariable *const var) override
Definition: sat_interface.cc:220
operations_research::SatInterface::SetPresolveMode
void SetPresolveMode(int value) override
Definition: sat_interface.cc:301
linear_solver.pb.h
operations_research::MPSolver::OPTIMAL
@ OPTIMAL
optimal.
Definition: linear_solver.h:427
operations_research::MPSolverInterface::trivial_worst_objective_bound
double trivial_worst_objective_bound() const
Definition: linear_solver.cc:1682
proto_utils.h
logging.h
operations_research::MPSolverInterface::quiet_
bool quiet_
Definition: linear_solver.h:1736
operations_research::MPSolver
This mathematical programming (MP) solver class is the main class though which users build and solve ...
Definition: linear_solver.h:177
operations_research::SatInterface::SetSolverSpecificParametersAsString
bool SetSolverSpecificParametersAsString(const std::string &parameters) override
Definition: sat_interface.cc:303
operations_research::SatInterface::SetVariableBounds
void SetVariableBounds(int index, double lb, double ub) override
Definition: sat_interface.cc:204
value
int64 value
Definition: demon_profiler.cc:43
operations_research::SatInterface::nodes
int64 nodes() const override
Definition: sat_interface.cc:247
statusor.h
model.h
operations_research::MPSolverInterface::CheckBestObjectiveBoundExists
virtual bool CheckBestObjectiveBoundExists() const
Definition: linear_solver.cc:1672
operations_research::SatInterface::SetOptimizationDirection
void SetOptimizationDirection(bool maximize) override
Definition: sat_interface.cc:200
operations_research
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
Definition: dense_doubly_linked_list.h:21
operations_research::MPSolver::MODEL_INVALID
@ MODEL_INVALID
the model is trivially invalid (NaN coefficients, etc).
Definition: linear_solver.h:437
operations_research::MPSolverInterface
Definition: linear_solver.h:1514
operations_research::SatInterface::ClearConstraint
void ClearConstraint(MPConstraint *const constraint) override
Definition: sat_interface.cc:230
operations_research::SatInterface::SetCoefficient
void SetCoefficient(MPConstraint *const constraint, const MPVariable *const variable, double new_value, double old_value) override
Definition: sat_interface.cc:224
operations_research::MPSolver::ABNORMAL
@ ABNORMAL
abnormal, i.e., error of some kind.
Definition: linear_solver.h:435
int64
int64_t int64
Definition: integral_types.h:34
sat_proto_solver.h
index
int index
Definition: pack.cc:508
operations_research::MPSolverParameters
This class stores parameter settings for LP and MIP solvers.
Definition: linear_solver.h:1358
operations_research::MPConstraint
The class for constraints of a Mathematical Programming (MP) model.
Definition: linear_solver.h:1175
operations_research::SatInterface::InterruptSolve
bool InterruptSolve() override
Definition: sat_interface.cc:193
operations_research::SatInterface::SolverVersion
std::string SolverVersion() const override
Definition: sat_interface.cc:268
operations_research::BuildSatInterface
MPSolverInterface * BuildSatInterface(MPSolver *const solver)
Definition: sat_interface.cc:314
operations_research::MPSolverInterface::objective_value_
double objective_value_
Definition: linear_solver.h:1733
operations_research::MPSOLVER_FEASIBLE
@ MPSOLVER_FEASIBLE
Definition: linear_solver.pb.h:230
operations_research::SatInterface::SetScalingMode
void SetScalingMode(int value) override
Definition: sat_interface.cc:296
operations_research::SatInterface::SetRelativeMipGap
void SetRelativeMipGap(double value) override
Definition: sat_interface.cc:298
operations_research::MPSolverInterface::ResetExtractionInformation
void ResetExtractionInformation()
Definition: linear_solver.cc:1640
operations_research::MPSolverInterface::solver_
MPSolver *const solver_
Definition: linear_solver.h:1718
operations_research::SatInterface::IsContinuous
bool IsContinuous() const override
Definition: sat_interface.cc:264
operations_research::MPSolver::NOT_SOLVED
@ NOT_SOLVED
not been solved yet.
Definition: linear_solver.h:439
operations_research::MPSolver::SetSolverSpecificParametersAsString
bool SetSolverSpecificParametersAsString(const std::string &parameters)
Advanced usage: pass solver specific parameters in text format.
Definition: linear_solver.cc:345
operations_research::MPSolverInterface::SOLUTION_SYNCHRONIZED
@ SOLUTION_SYNCHRONIZED
Definition: linear_solver.h:1526
operations_research::SatInterface::SetPrimalTolerance
void SetPrimalTolerance(double value) override
Definition: sat_interface.cc:294
operations_research::SatInterface::SetConstraintBounds
void SetConstraintBounds(int index, double lb, double ub) override
Definition: sat_interface.cc:212
operations_research::MPSolver::time_limit
int64 time_limit() const
Definition: linear_solver.h:777
operations_research::SatInterface::SetDualTolerance
void SetDualTolerance(double value) override
Definition: sat_interface.cc:295
operations_research::MPSolver::BasisStatus
BasisStatus
Advanced usage: possible basis status values for a variable and the slack variable of a linear constr...
Definition: linear_solver.h:640
operations_research::SatInterface::AddRowConstraint
void AddRowConstraint(MPConstraint *const ct) override
Definition: sat_interface.cc:216
absl::StatusOr::value
const T & value() const
Definition: statusor.h:36
operations_research::SatInterface::Solve
MPSolver::ResultStatus Solve(const MPSolverParameters &param) override
Definition: sat_interface.cc:113
ct
const Constraint * ct
Definition: demon_profiler.cc:42
operations_research::SatInterface::ExtractNewConstraints
void ExtractNewConstraints() override
Definition: sat_interface.cc:276
operations_research::MPSolverInterface::sync_status_
SynchronizationStatus sync_status_
Definition: linear_solver.h:1720
operations_research::SatInterface
Definition: sat_interface.cc:41
absl::StatusOr
Definition: statusor.h:24
operations_research::SatInterface::SetObjectiveOffset
void SetObjectiveOffset(double value) override
Definition: sat_interface.cc:239
operations_research::MPSolver::ResultStatus
ResultStatus
The status of solving the problem.
Definition: linear_solver.h:425
operations_research::SatInterface::Reset
void Reset() override
Definition: sat_interface.cc:198
operations_research::SatInterface::~SatInterface
~SatInterface() override
Definition: sat_interface.cc:111
operations_research::SatInterface::IsLP
bool IsLP() const override
Definition: sat_interface.cc:265
operations_research::MPSolverInterface::ExtractModel
void ExtractModel()
Definition: linear_solver.cc:1612
operations_research::SatInterface::ExtractNewVariables
void ExtractNewVariables() override
Definition: sat_interface.cc:274
operations_research::MPSOLVER_MODEL_INVALID
@ MPSOLVER_MODEL_INVALID
Definition: linear_solver.pb.h:237
operations_research::MPSolverInterface::set_variable_as_extracted
void set_variable_as_extracted(int var_index, bool extracted)
Definition: linear_solver.h:1661
coefficient
int64 coefficient
Definition: routing_search.cc:973
operations_research::SatInterface::iterations
int64 iterations() const override
Definition: sat_interface.cc:243
operations_research::SatInterface::underlying_solver
void * underlying_solver() override
Definition: sat_interface.cc:272
operations_research::SatInterface::ClearObjective
void ClearObjective() override
Definition: sat_interface.cc:241
operations_research::MPSOLVER_INFEASIBLE
@ MPSOLVER_INFEASIBLE
Definition: linear_solver.pb.h:231
operations_research::SatInterface::best_objective_bound
double best_objective_bound() const override
Definition: sat_interface.cc:249
operations_research::MPVariable
The class for variables of a Mathematical Programming (MP) model.
Definition: linear_solver.h:1050
hash.h
operations_research::MPSolver::ExportModelToProto
void ExportModelToProto(MPModelProto *output_model) const
Exports model to protocol buffer.
Definition: linear_solver.cc:884
linear_solver.h
A C++ wrapper that provides a simple and unified interface to several linear programming and mixed in...
lp_utils.h
operations_research::MPSOLVER_OPTIMAL
@ MPSOLVER_OPTIMAL
Definition: linear_solver.pb.h:229
operations_research::MPSolverInterface::SetCommonParameters
void SetCommonParameters(const MPSolverParameters &param)
Definition: linear_solver.cc:1707
operations_research::SatInterface::SetVariableInteger
void SetVariableInteger(int index, bool integer) override
Definition: sat_interface.cc:208
operations_research::MPSolver::INFEASIBLE
@ INFEASIBLE
proven infeasible.
Definition: linear_solver.h:431
cp_model_solver.h
operations_research::ProtobufTextFormatMergeFromString
bool ProtobufTextFormatMergeFromString(const std::string &proto_text_string, ProtoType *proto)
Definition: port/proto_utils.h:75
operations_research::SatInterface::SetLpAlgorithm
void SetLpAlgorithm(int value) override
Definition: sat_interface.cc:297
operations_research::MPSolverInterface::MUST_RELOAD
@ MUST_RELOAD
Definition: linear_solver.h:1519
operations_research::MPSolverInterface::CheckSolutionIsSynchronized
bool CheckSolutionIsSynchronized() const
Definition: linear_solver.cc:1648
operations_research::MPSolverInterface::result_status_
MPSolver::ResultStatus result_status_
Definition: linear_solver.h:1723
operations_research::MPSolverInterface::set_constraint_as_extracted
void set_constraint_as_extracted(int ct_index, bool extracted)
Definition: linear_solver.h:1667
operations_research::SatInterface::SetObjectiveCoefficient
void SetObjectiveCoefficient(const MPVariable *const variable, double coefficient) override
Definition: sat_interface.cc:234
parameters
SatParameters parameters
Definition: cp_model_fz_solver.cc:107
operations_research::SatInterface::SetParameters
void SetParameters(const MPSolverParameters &param) override
Definition: sat_interface.cc:280
operations_research::SatInterface::row_status
MPSolver::BasisStatus row_status(int constraint_index) const override
Definition: sat_interface.cc:256
operations_research::SatInterface::SatInterface
SatInterface(MPSolver *const solver)
Definition: sat_interface.cc:108
operations_research::MPSolver::FEASIBLE
@ FEASIBLE
feasible, or stopped by limit.
Definition: linear_solver.h:429
operations_research::SatInterface::column_status
MPSolver::BasisStatus column_status(int variable_index) const override
Definition: sat_interface.cc:260
operations_research::SatInterface::ExtractObjective
void ExtractObjective() override
Definition: sat_interface.cc:278
operations_research::SatSolveProto
absl::StatusOr< MPSolutionResponse > SatSolveProto(MPModelRequest request, std::atomic< bool > *interrupt_solve)
Definition: sat_proto_solver.cc:59