OR-Tools  9.0
solver.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 <stdint.h>
17 
18 #include <functional>
19 #include <memory>
20 #include <string>
21 #include <utility>
22 
23 #include "absl/memory/memory.h"
24 #include "absl/status/status.h"
25 #include "absl/status/statusor.h"
26 #include "absl/types/span.h"
28 #include "ortools/base/logging.h"
30 #include "ortools/math_opt/callback.pb.h"
31 #include "ortools/math_opt/model.pb.h"
32 #include "ortools/math_opt/model_parameters.pb.h"
34 #include "ortools/math_opt/model_update.pb.h"
35 #include "ortools/math_opt/parameters.pb.h"
36 #include "ortools/math_opt/result.pb.h"
43 
44 namespace operations_research {
45 namespace math_opt {
46 
47 namespace {
48 
49 template <typename IdNameContainer>
50 void UpdateIdNameMap(const absl::Span<const int64_t> deleted_ids,
51  const IdNameContainer& container, IdNameBiMap& bimap) {
52  for (const int64_t deleted_id : deleted_ids) {
53  bimap.Erase(deleted_id);
54  }
55  for (int i = 0; i < container.ids_size(); ++i) {
56  std::string name;
57  if (!container.names().empty()) {
58  name = container.names(i);
59  }
60  bimap.Insert(container.ids(i), std::move(name));
61  }
62 }
63 
64 ModelSummary MakeSummary(const ModelProto& model) {
65  ModelSummary summary;
66  UpdateIdNameMap<VariablesProto>({}, model.variables(), summary.variables);
67  UpdateIdNameMap<LinearConstraintsProto>({}, model.linear_constraints(),
68  summary.linear_constraints);
69  return summary;
70 }
71 
72 void UpdateSummaryFromModelUpdate(const ModelUpdateProto& model_update,
73  ModelSummary& summary) {
74  UpdateIdNameMap<VariablesProto>(model_update.deleted_variable_ids(),
75  model_update.new_variables(),
76  summary.variables);
77  UpdateIdNameMap<LinearConstraintsProto>(
78  model_update.deleted_linear_constraint_ids(),
79  model_update.new_linear_constraints(), summary.linear_constraints);
80 }
81 
82 // Returns an InternalError with the input status message if the input status is
83 // not OK.
84 absl::Status ToInternalError(const absl::Status original) {
85  if (original.ok()) {
86  return original;
87  }
88 
89  return absl::InternalError(original.message());
90 }
91 
92 } // namespace
93 
94 Solver::Solver(std::unique_ptr<SolverInterface> underlying_solver,
95  ModelSummary model_summary)
96  : underlying_solver_(std::move(underlying_solver)),
97  model_summary_(std::move(model_summary)) {
98  CHECK(underlying_solver_ != nullptr);
99 }
100 
101 absl::StatusOr<std::unique_ptr<Solver>> Solver::New(
102  const SolverType solver_type, const ModelProto& model,
103  const SolverInitializerProto& initializer) {
106  auto underlying_solver,
107  AllSolversRegistry::Instance()->Create(solver_type, model, initializer));
108  auto result = absl::WrapUnique(
109  new Solver(std::move(underlying_solver), MakeSummary(model)));
110  return result;
111 }
112 
113 absl::StatusOr<SolveResultProto> Solver::Solve(
114  const SolveParametersProto& parameters,
115  const ModelSolveParametersProto& model_parameters,
116  const CallbackRegistrationProto& callback_registration,
117  const Callback user_cb) {
118  // TODO(b/168037341): we should validate the result maths. Since the result
119  // can be filtered, this should be included in the solver_interface
120  // implementations.
121 
122  RETURN_IF_ERROR(ValidateSolverParameters(parameters)) << "invalid parameters";
124  ValidateModelSolveParameters(model_parameters, model_summary_))
125  << "invalid model_parameters";
126 
127  SolverInterface::Callback cb = nullptr;
128  if (user_cb != nullptr) {
130  ValidateCallbackRegistration(callback_registration, model_summary_));
131  cb = [&](const CallbackDataProto& callback_data)
132  -> absl::StatusOr<CallbackResultProto> {
134  callback_data, callback_registration, model_summary_));
135  auto callback_result = user_cb(callback_data);
137  ValidateCallbackResultProto(callback_result, callback_data.event(),
138  callback_registration, model_summary_));
139  return callback_result;
140  };
141  }
142 
143  ASSIGN_OR_RETURN(const SolveResultProto result,
144  underlying_solver_->Solve(parameters, model_parameters,
145  callback_registration, cb));
146 
147  // We consider errors in `result` to be internal errors, but
148  // `ValidateResult()` will return an InvalidArgumentError. So here we convert
149  // the error.
150  RETURN_IF_ERROR(ToInternalError(
151  ValidateResult(result, model_parameters, model_summary_)));
152 
153  return result;
154 }
155 
156 absl::StatusOr<bool> Solver::Update(const ModelUpdateProto& model_update) {
157  RETURN_IF_ERROR(ValidateModelUpdateAndSummary(model_update, model_summary_));
158  if (!underlying_solver_->CanUpdate(model_update)) {
159  return false;
160  }
161  UpdateSummaryFromModelUpdate(model_update, model_summary_);
162  RETURN_IF_ERROR(underlying_solver_->Update(model_update));
163  return true;
164 }
165 
166 } // namespace math_opt
167 } // namespace operations_research
#define CHECK(condition)
Definition: base/logging.h:498
std::function< CallbackResultProto(const CallbackDataProto &)> Callback
Definition: solver.h:61
std::function< absl::StatusOr< CallbackResultProto >(const CallbackDataProto &)> Callback
SatParameters parameters
const std::string name
GRBmodel * model
absl::Status ValidateResult(const SolveResultProto &result, const ModelSolveParametersProto &parameters, const ModelSummary &model_summary)
absl::Status ValidateModelUpdateAndSummary(const ModelUpdateProto &model_update, const ModelSummary &model_summary, const bool check_names)
absl::Status ValidateCallbackResultProto(const CallbackResultProto &callback_result, const CallbackEventProto callback_event, const CallbackRegistrationProto &callback_registration, const ModelSummary &model_summary)
absl::Status ValidateCallbackDataProto(const CallbackDataProto &cb_data, const CallbackRegistrationProto &callback_registration, const ModelSummary &model_summary)
absl::Status ValidateCallbackRegistration(const CallbackRegistrationProto &callback_registration, const ModelSummary &model_summary)
absl::Status ValidateSolverParameters(const SolveParametersProto &parameters)
absl::Status ValidateModelSolveParameters(const ModelSolveParametersProto &parameters, const ModelSummary &model_summary)
absl::Status ValidateModel(const ModelProto &model, const bool check_names)
CpSolverResponse Solve(const CpModelProto &model_proto)
Solves the given CpModelProto and returns an instance of CpSolverResponse.
Collection of objects used to extend the Constraint Solver library.
#define ASSIGN_OR_RETURN(lhs, rexpr)
Definition: status_macros.h:55
#define RETURN_IF_ERROR(expr)
Definition: status_macros.h:29