OR-Tools  9.1
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
25#include "absl/memory/memory.h"
26#include "absl/status/status.h"
27#include "absl/status/statusor.h"
28#include "absl/types/span.h"
29#include "ortools/math_opt/callback.pb.h"
32#include "ortools/math_opt/model.pb.h"
33#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
44namespace operations_research {
45namespace math_opt {
46
47namespace {
48
49template <typename IdNameContainer>
50void 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
64ModelSummary 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
72void 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.
84absl::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
94Solver::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
101absl::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
113absl::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
156absl::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:491
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.
STL namespace.
#define ASSIGN_OR_RETURN(lhs, rexpr)
Definition: status_macros.h:55
#define RETURN_IF_ERROR(expr)
Definition: status_macros.h:29