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