OR-Tools  9.2
callback.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 <algorithm>
17#include <optional>
18#include <utility>
19#include <vector>
20
22#include "absl/container/flat_hash_set.h"
23#include "absl/status/statusor.h"
24#include "absl/strings/string_view.h"
25#include "absl/time/time.h"
26#include "absl/types/span.h"
28#include "ortools/math_opt/callback.pb.h"
34#include "ortools/math_opt/solution.pb.h"
35#include "ortools/math_opt/sparse_containers.pb.h"
36#include "absl/status/status.h"
38
39namespace operations_research {
40namespace math_opt {
41namespace {
42
43std::vector<std::pair<VariableId, double>> SortedVariableValues(
44 const VariableMap<double>& var_map) {
45 std::vector<std::pair<VariableId, double>> result(var_map.raw_map().begin(),
46 var_map.raw_map().end());
47 std::sort(result.begin(), result.end());
48 return result;
49}
50
51// Container must be an iterable on some type T where
52// const ModelStorage* T::storage() const
53// is defined.
54//
55// CHECKs that the non-null model storages are the same, and returns the unique
56// non-null model storage if it exists, otherwise null.
57template <typename Container>
58const ModelStorage* ConsistentModelStorage(
59 const Container& model_items,
60 const ModelStorage* const init_model = nullptr) {
61 const ModelStorage* result = init_model;
62 for (const auto& item : model_items) {
63 const ModelStorage* const storage = item.storage();
64 if (storage != nullptr) {
65 if (result == nullptr) {
66 result = storage;
67 } else {
69 }
70 }
71 }
72 return result;
73}
74
75} // namespace
76
77std::optional<absl::string_view> Enum<CallbackEvent>::ToOptString(
79 switch (value) {
81 return "presolve";
83 return "simplex";
85 return "mip";
87 return "mip_solution";
89 return "mip_node";
91 return "barrier";
92 }
93 return std::nullopt;
94}
95
96absl::Span<const CallbackEvent> Enum<CallbackEvent>::AllValues() {
97 static constexpr CallbackEvent kCallbackEventValues[] = {
101 };
102 return absl::MakeConstSpan(kCallbackEventValues);
103}
104
106 const CallbackDataProto& proto)
107 // iOS 11 does not support .value() hence we use operator* here and CHECK
108 // below that we have a value.
109 : event(*EnumFromProto(proto.event())),
110 presolve_stats(proto.presolve_stats()),
111 simplex_stats(proto.simplex_stats()),
112 barrier_stats(proto.barrier_stats()),
113 mip_stats(proto.mip_stats()) {
114 CHECK(EnumFromProto(proto.event()).has_value());
115 if (proto.has_primal_solution_vector()) {
117 storage, MakeView(proto.primal_solution_vector()).as_map<VariableId>());
118 }
119 auto maybe_time = util_time::DecodeGoogleApiProto(proto.runtime());
120 CHECK_OK(maybe_time.status());
121 runtime = *maybe_time;
122}
123
126 {mip_node_filter.storage(), mip_solution_filter.storage()});
127}
128
129CallbackRegistrationProto CallbackRegistration::Proto() const {
130 // Ensure that the underlying ModelStorage is consistent (or CHECK fail).
131 storage();
132
133 CallbackRegistrationProto result;
134 for (const CallbackEvent event : events) {
135 result.add_request_registration(EnumToProto(event));
136 }
137 std::sort(result.mutable_request_registration()->begin(),
138 result.mutable_request_registration()->end());
139 *result.mutable_mip_solution_filter() = mip_solution_filter.Proto();
140 *result.mutable_mip_node_filter() = mip_node_filter.Proto();
141 result.set_add_lazy_constraints(add_lazy_constraints);
142 result.set_add_cuts(add_cuts);
143 return result;
144}
145
149}
150
151CallbackResultProto CallbackResult::Proto() const {
152 // Ensure that the underlying ModelStorage is consistent (or CHECK fail).
153 storage();
154
155 CallbackResultProto result;
156 result.set_terminate(terminate);
157 for (const VariableMap<double>& solution : suggested_solutions) {
158 SparseDoubleVectorProto* solution_vector = result.add_suggested_solutions();
159 for (const auto& [typed_id, value] : SortedVariableValues(solution)) {
160 solution_vector->add_ids(typed_id.value());
161 solution_vector->add_values(value);
162 }
163 }
164 for (const GeneratedLinearConstraint& constraint : new_constraints) {
165 CallbackResultProto::GeneratedLinearConstraint* constraint_proto =
166 result.add_cuts();
167 constraint_proto->set_is_lazy(constraint.is_lazy);
168 constraint_proto->set_lower_bound(
169 constraint.linear_constraint.lower_bound_minus_offset());
170 constraint_proto->set_upper_bound(
171 constraint.linear_constraint.upper_bound_minus_offset());
172 for (const auto& [typed_id, value] : SortedVariableValues(
173 constraint.linear_constraint.expression.terms())) {
174 constraint_proto->mutable_linear_expression()->add_ids(typed_id.value());
175 constraint_proto->mutable_linear_expression()->add_values(value);
176 }
177 }
178 return result;
179}
180
181} // namespace math_opt
182} // namespace operations_research
#define CHECK(condition)
Definition: base/logging.h:495
#define CHECK_EQ(val1, val2)
Definition: base/logging.h:702
#define CHECK_OK(x)
Definition: base/logging.h:44
CpModelProto proto
int64_t value
const ModelStorage * ConsistentModelStorage(std::initializer_list< const ModelStorage * > storages)
Definition: key_types.h:61
constexpr absl::string_view kObjectsFromOtherModelStorage
Definition: key_types.h:56
SparseVectorView< T > MakeView(absl::Span< const int64_t > ids, const Collection &values)
std::optional< typename EnumProto< P >::Cpp > EnumFromProto(const P proto_value)
Definition: enums.h:275
Enum< E >::Proto EnumToProto(const std::optional< E > value)
Definition: enums.h:264
Collection of objects used to extend the Constraint Solver library.
inline ::absl::StatusOr< absl::Duration > DecodeGoogleApiProto(const google::protobuf::Duration &proto)
Definition: protoutil.h:42
CallbackData(const ModelStorage *storage, const CallbackDataProto &proto)
Definition: callback.cc:105
std::optional< VariableMap< double > > solution
Definition: callback.h:201
CallbackRegistrationProto Proto() const
Definition: callback.cc:129
absl::flat_hash_set< CallbackEvent > events
Definition: callback.h:161
std::vector< VariableMap< double > > suggested_solutions
Definition: callback.h:264
CallbackResultProto Proto() const
Definition: callback.cc:151
const ModelStorage * storage() const
Definition: callback.cc:146
std::vector< GeneratedLinearConstraint > new_constraints
Definition: callback.h:261
static std::optional< absl::string_view > ToOptString(E value)
Definition: callback.cc:77
static absl::Span< const E > AllValues()
Definition: callback.cc:96