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