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