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 <string>
19#include <utility>
20#include <vector>
21
23#include "absl/container/flat_hash_set.h"
24#include "absl/status/status.h"
25#include "absl/status/statusor.h"
26#include "absl/time/time.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// IndexedModel* T::model() const
53// is defined.
54//
55// CHECKs that the non-null models the same, and returns the unique non-null
56// model if it exists, otherwise null.
57template <typename Container>
58IndexedModel* ConsistentModel(const Container& model_items,
59 IndexedModel* const init_model = nullptr) {
60 IndexedModel* result = init_model;
61 for (const auto& item : model_items) {
62 IndexedModel* const model = item.model();
63 if (model != nullptr) {
64 if (result == nullptr) {
65 result = model;
66 } else {
68 }
69 }
70 }
71 return result;
72}
73
74} // namespace
75
77 : event(proto.event()),
78 messages(proto.messages().begin(), proto.messages().end()),
79 presolve_stats(proto.presolve_stats()),
80 simplex_stats(proto.simplex_stats()),
81 barrier_stats(proto.barrier_stats()),
82 mip_stats(proto.mip_stats()) {
83 if (proto.has_primal_solution()) {
85 model, MakeView(proto.primal_solution().variable_values())
86 .as_map<VariableId>());
87 }
88 auto maybe_time = util_time::DecodeGoogleApiProto(proto.runtime());
89 CHECK_OK(maybe_time.status());
90 runtime = *maybe_time;
91}
92
95 {mip_node_filter.model(), mip_solution_filter.model()});
96}
97
98CallbackRegistrationProto CallbackRegistration::Proto() const {
99 // Ensure that the underlying IndexedModel is consistent (or CHECK fail).
100 model();
101
102 CallbackRegistrationProto result;
103 for (const CallbackEventProto event : events) {
104 result.add_request_registration(event);
105 }
106 std::sort(result.mutable_request_registration()->begin(),
107 result.mutable_request_registration()->end());
108 *result.mutable_mip_solution_filter() = mip_solution_filter.Proto();
109 *result.mutable_mip_node_filter() = mip_node_filter.Proto();
110 result.set_add_lazy_constraints(add_lazy_constraints);
111 result.set_add_cuts(add_cuts);
112 return result;
113}
114
117 return ConsistentModel(suggested_solutions, result);
118}
119
120CallbackResultProto CallbackResult::Proto() const {
121 // Ensure that the underlying IndexedModel is consistent (or CHECK fail).
122 model();
123
124 CallbackResultProto result;
125 result.set_terminate(terminate);
126 for (const VariableMap<double>& solution : suggested_solutions) {
127 PrimalSolutionProto* solution_proto = result.add_suggested_solution();
128 for (const auto& [typed_id, value] : SortedVariableValues(solution)) {
129 solution_proto->mutable_variable_values()->add_ids(typed_id.value());
130 solution_proto->mutable_variable_values()->add_values(value);
131 }
132 }
133 for (const GeneratedLinearConstraint& constraint : new_constraints) {
134 CallbackResultProto::GeneratedLinearConstraint* constraint_proto =
135 result.add_cuts();
136 constraint_proto->set_is_lazy(constraint.is_lazy);
137 constraint_proto->set_lower_bound(
138 constraint.linear_constraint.lower_bound_minus_offset());
139 constraint_proto->set_upper_bound(
140 constraint.linear_constraint.upper_bound_minus_offset());
141 for (const auto& [typed_id, value] : SortedVariableValues(
142 constraint.linear_constraint.expression.terms())) {
143 constraint_proto->mutable_linear_expression()->add_ids(typed_id.value());
144 constraint_proto->mutable_linear_expression()->add_values(value);
145 }
146 }
147 return result;
148}
149
150} // namespace math_opt
151} // namespace operations_research
#define CHECK_EQ(val1, val2)
Definition: base/logging.h:699
#define CHECK_OK(x)
Definition: base/logging.h:43
CpModelProto proto
int64_t value
GRBmodel * model
constexpr absl::string_view kObjectsFromOtherIndexedModel
Definition: key_types.h:56
IndexedModel * ConsistentModel(std::initializer_list< IndexedModel * > models)
Definition: key_types.h:61
SparseVectorView< T > MakeView(absl::Span< const int64_t > ids, const Collection &values)
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
absl::optional< VariableMap< double > > solution
Definition: callback.h:100
CallbackRegistrationProto Proto() const
Definition: callback.cc:98
absl::flat_hash_set< CallbackEventProto > events
Definition: callback.h:138
std::vector< VariableMap< double > > suggested_solutions
Definition: callback.h:200
CallbackResultProto Proto() const
Definition: callback.cc:120
std::vector< GeneratedLinearConstraint > new_constraints
Definition: callback.h:197