OR-Tools  9.1
math_opt_proto_utils.h
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 
14 #ifndef OR_TOOLS_MATH_OPT_CORE_MATH_OPT_PROTO_UTILS_H_
15 #define OR_TOOLS_MATH_OPT_CORE_MATH_OPT_PROTO_UTILS_H_
16 
17 #include <algorithm>
18 #include <cstdint>
19 
21 #include "ortools/base/logging.h"
22 #include "absl/container/flat_hash_set.h"
23 #include "ortools/math_opt/callback.pb.h"
24 #include "ortools/math_opt/model.pb.h"
25 #include "ortools/math_opt/model_update.pb.h"
26 #include "ortools/math_opt/sparse_containers.pb.h"
27 
28 namespace operations_research {
29 namespace math_opt {
30 
31 inline int NumVariables(const VariablesProto& variables) {
32  return variables.ids_size();
33 }
34 
35 inline int NumConstraints(const LinearConstraintsProto& linear_constraints) {
36  return linear_constraints.ids_size();
37 }
38 
39 inline int NumMatrixNonzeros(const SparseDoubleMatrixProto& matrix) {
40  return matrix.row_ids_size();
41 }
42 
43 // Removes the items in the sparse double vector for all indices whose value is
44 // exactly 0.0.
45 //
46 // NaN values are kept in place.
47 //
48 // The function asserts that input is a valid sparse vector, i.e. that the
49 // number of values and ids match.
50 void RemoveSparseDoubleVectorZeros(SparseDoubleVectorProto& sparse_vector);
51 
52 // A utility class that tests if a pair (id, value) should be filtered based on
53 // an input SparseVectorFilterProto.
54 //
55 // This predicate expects the input is sorted by ids. In non-optimized builds,
56 // it will check that this is the case.
58  public:
59  // Builds a predicate based on the input filter. A reference to this filter is
60  // kept so the caller must make sure this filter outlives the predicate.
61  //
62  // The filter.filtered_ids is expected to be sorted and not contain
63  // duplicates. In non-optimized builds, it will be CHECKed.
64  explicit SparseVectorFilterPredicate(const SparseVectorFilterProto& filter);
65 
66  // Returns true if the input value should be kept, false if it should be
67  // ignored since it is not selected by the filter.
68  //
69  // This function is expected to be called with strictly increasing ids. In
70  // non-optimized builds it will CHECK that this is the case. It updates an
71  // internal counter when filtering by ids.
72  template <typename Value>
73  bool AcceptsAndUpdate(const int64_t id, const Value& value);
74 
75  private:
76  const SparseVectorFilterProto& filter_;
77 
78  // Index of the next element to consider in filter_.filtered_ids().
79  int next_filtered_id_index_ = 0;
80 
81 #ifndef NDEBUG
82  // Invariant: next input id must be >= next_input_id_lower_bound_.
83  //
84  // The initial value is 0 since all ids are expected to be non-negative.
85  int next_input_id_lower_bound_ = 0;
86 #endif // NDEBUG
87 };
88 
89 // Returns the callback_registration.request_registration as a set of enums.
90 absl::flat_hash_set<CallbackEventProto> EventSet(
91  const CallbackRegistrationProto& callback_registration);
92 
94 // Inline functions implementations.
96 
97 template <typename Value>
99  const Value& value) {
100 #ifndef NDEBUG
101  CHECK_GE(id, next_input_id_lower_bound_)
102  << "This function must be called with strictly increasing ids.";
103 
104  // Update the range of the next expected id. We expect input to be strictly
105  // increasing.
106  next_input_id_lower_bound_ = id + 1;
107 #endif // NDEBUG
108 
109  // For this predicate we use `0` as the zero to test with since as of today we
110  // only have SparseDoubleVectorProto and SparseBoolVectorProto. The `bool`
111  // type is an integral type so the comparison with 0 will indeed be equivalent
112  // to keeping only `true` values.
113  if (filter_.skip_zero_values() && value == 0) {
114  return false;
115  }
116 
117  if (!filter_.filter_by_ids()) {
118  return true;
119  }
120 
121  // Skip all filtered_ids that are smaller than the input id.
122  while (next_filtered_id_index_ < filter_.filtered_ids_size() &&
123  filter_.filtered_ids(next_filtered_id_index_) < id) {
124  ++next_filtered_id_index_;
125  }
126 
127  if (next_filtered_id_index_ == filter_.filtered_ids_size()) {
128  // We filter by ids and there are no more ids that should pass.
129  return false;
130  }
131 
132  // The previous loop ensured that the element at next_filtered_id_index_ is
133  // the first element greater or equal to id.
134  return id == filter_.filtered_ids(next_filtered_id_index_);
135 }
136 
137 } // namespace math_opt
138 } // namespace operations_research
139 
140 #endif // OR_TOOLS_MATH_OPT_CORE_MATH_OPT_PROTO_UTILS_H_
#define CHECK_GE(val1, val2)
Definition: base/logging.h:702
bool AcceptsAndUpdate(const int64_t id, const Value &value)
SparseVectorFilterPredicate(const SparseVectorFilterProto &filter)
int NumMatrixNonzeros(const SparseDoubleMatrixProto &matrix)
int NumVariables(const VariablesProto &variables)
std::function< int64_t(const Model &)> Value(IntegerVariable v)
Definition: integer.h:1544
int NumConstraints(const LinearConstraintsProto &linear_constraints)
absl::flat_hash_set< CallbackEventProto > EventSet(const CallbackRegistrationProto &callback_registration)
void RemoveSparseDoubleVectorZeros(SparseDoubleVectorProto &sparse_vector)
Collection of objects used to extend the Constraint Solver library.
int64_t value