OR-Tools  9.0
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 
22 #include "ortools/base/logging.h"
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"
27 #include "ortools/base/int_type.h"
28 #include "ortools/math_opt/callback.pb.h"
33 #include "ortools/math_opt/solution.pb.h"
34 #include "ortools/math_opt/sparse_containers.pb.h"
36 #include "absl/status/status.h"
37 #include "ortools/base/protoutil.h"
38 
39 namespace operations_research {
40 namespace math_opt {
41 namespace {
42 
43 std::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.
57 template <typename Container>
58 IndexedModel* 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 
98 CallbackRegistrationProto 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 
120 CallbackResultProto 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:705
#define CHECK_OK(x)
Definition: base/logging.h:42
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