OR-Tools  9.2
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
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
28namespace operations_research {
29namespace math_opt {
30
31inline int NumVariables(const VariablesProto& variables) {
32 return variables.ids_size();
33}
34
35inline int NumConstraints(const LinearConstraintsProto& linear_constraints) {
36 return linear_constraints.ids_size();
37}
38
39inline 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.
50void 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.
90absl::flat_hash_set<CallbackEventProto> EventSet(
91 const CallbackRegistrationProto& callback_registration);
92
94// Inline functions implementations.
96
97template <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:703
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:1673
Collection of objects used to extend the Constraint Solver library.