Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
map_filter.h
Go to the documentation of this file.
1// Copyright 2010-2024 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// IWYU pragma: private, include "ortools/math_opt/cpp/math_opt.h"
15// IWYU pragma: friend "ortools/math_opt/cpp/.*"
16
17#ifndef OR_TOOLS_MATH_OPT_CPP_MAP_FILTER_H_
18#define OR_TOOLS_MATH_OPT_CPP_MAP_FILTER_H_
19
20#include <initializer_list>
21#include <optional>
22
23#include "absl/algorithm/container.h"
24#include "absl/container/flat_hash_set.h"
25#include "absl/status/status.h"
26#include "absl/status/statusor.h"
32#include "ortools/math_opt/sparse_containers.pb.h"
34
36
37// A filter that only keeps some specific key-value pairs of a map.
38//
39// It is used to limit the quantity of data returned in a SolveResult or in a
40// CallbackResult when the models are huge and the user is only interested in
41// the values of a subset of the keys.
42//
43// The keys, the type KeyType, should match the definition of "key types" given
44// in key_types.h.
45//
46// A filter is composed of two sub-filters that act as a veto system: a
47// key-value pair is kept only when it is kept by both filters. Those filters
48// are:
49// - skip_zero_values: when true, only keep pairs if the value is non zero (if
50// the value is boolean, keep only pairs with true value).
51// - filtered_keys: when set, only keep pairs which keys are in the provided
52// list. If this list is empty, no pairs are returned. When unset, keep all
53// pairs.
54//
55// See the MakeSkipAllFilter(), MakeSkipZerosFilter() and MakeKeepKeysFilter()
56// functions below that provide shortcuts for making filters.
57//
58// This class is a factory of SparseVectorFilterProto.
59template <typename KeyType>
60struct MapFilter {
61 // If true, omits the pairs with zero values (the pairs with false value for
62 // bool vectors).
63 //
64 // Default is false, pairs with zero (or false) value are kept.
65 //
66 // Prefer using MakeSkipZerosFilter() when appropriate.
67 bool skip_zero_values = false;
68
69 // The set of keys of pairs to keep. When unset, all pairs are kept
70 // (at least the ones with non-zero values, when skip_zero_values() is true).
71 //
72 // Default is unset, all pairs are kept.
73 //
74 // Example:
75 // MapFilter<Variable> filter = ...;
76 //
77 // // Unset the filter.
78 // filter.filtered_keys.reset();
79 // // alternatively:
80 // filter.filtered_keys = std::nullopt;
81 //
82 // // Set the filter with an empty list of keys (filtering out all pairs).
83 // //
84 // // Note that here `= {}` would NOT work since it would unset the
85 // // filtered_keys optional (i.e. like calling reset()).
86 // filter.filtered_keys.emplace();
87 //
88 // // Set the filter to a fix set of variables.
89 // const Variable x = ...;
90 // const Variable y = ...;
91 // filter.filtered_keys = {x, y};
92 //
93 // // Set the filter from a collection of variables.
94 // std::vector<Variable> decision_vars = {...};
95 // filter.emplace(decision_vars.begin(), decision_vars.end());
96 //
97 // Prefer using MakeSkipAllFilter() or MakeKeepKeysFilter() when appropriate.
98 std::optional<absl::flat_hash_set<KeyType>> filtered_keys;
99
100 // Returns a failure if the keys don't belong to the input expected_storage
101 // (which must not be nullptr).
102 inline absl::Status CheckModelStorage(
103 const ModelStorage* expected_storage) const;
104
105 // Returns the proto corresponding to this filter.
106 //
107 // The caller should use CheckModelStorage() as this function does not check
108 // internal consistency of the referenced variables and constraints.
109 SparseVectorFilterProto Proto() const;
110};
111
112// Returns the MapFilter<Variable> equivalent to `proto`.
113//
114// Requires that (or returns a status error):
115// * proto.filtered_ids has elements that are variables in `model`.
116absl::StatusOr<MapFilter<Variable>> VariableFilterFromProto(
117 const Model& model, const SparseVectorFilterProto& proto);
118
119// Returns the MapFilter<LinearConstraint> equivalent to `proto`.
120//
121// Requires that (or returns a status error):
122// * proto.filtered_ids has elements that are linear constraints in `model`.
123absl::StatusOr<MapFilter<LinearConstraint>> LinearConstraintFilterFromProto(
124 const Model& model, const SparseVectorFilterProto& proto);
125
126// Returns the MapFilter<QuadraticConstraint> equivalent to `proto`.
127//
128// Requires that (or returns a status error):
129// * proto.filtered_ids has elements that are quadratic constraints in `model`.
130absl::StatusOr<MapFilter<QuadraticConstraint>>
132 const SparseVectorFilterProto& proto);
133
134// Returns a filter that skips all key-value pairs.
135//
136// This is typically used to disable the dual data in SolveResult when these are
137// ignored by the user.
138//
139// Example:
140// const auto filter = MakeSkipAllFilter<Variable>();
141template <typename KeyType>
144 ret.filtered_keys.emplace();
145 return ret;
146}
147
148// Returns a filter that skips all key-value pairs with zero values (or false
149// values for bool).
150//
151// Example:
152// const auto filter = MakeSkipZerosFilter<Variable>();
153template <typename KeyType>
156 ret.skip_zero_values = true;
157 return ret;
158}
159
160// Returns a filter that keeps the key-value pairs with the given keys.
161//
162// Example:
163// std::vector<Variable> decision_vars = ...;
164// const auto filter = MakeKeepKeysFilter(decision_vars);
165template <typename Collection,
166 typename ValueType = typename Collection::value_type>
169 ret.filtered_keys.emplace(keys.begin(), keys.end());
170 return ret;
171}
172
173// Returns a filter that keeps the key-value pairs with the given keys.
174//
175// This overload is necessary since C++ does not automatically deduce the type
176// when using the previous one.
177//
178// Example:
179// const Variable x = ...;
180// const Variable y = ...;
181// const auto filter = MakeKeepKeysFilter({x, y});
182template <typename KeyType>
183MapFilter<KeyType> MakeKeepKeysFilter(std::initializer_list<KeyType> keys) {
185 ret.filtered_keys = keys;
186 return ret;
187}
188
190// Inline functions implementations.
192
193template <typename KeyType>
195 const ModelStorage* expected_storage) const {
196 if (!filtered_keys.has_value()) {
197 return absl::OkStatus();
198 }
199 for (const KeyType& k : filtered_keys.value()) {
201 /*storage=*/k.storage(),
202 /*expected_storage=*/expected_storage));
203 }
204 return absl::OkStatus();
205}
206
207template <typename KeyType>
208SparseVectorFilterProto MapFilter<KeyType>::Proto() const {
209 SparseVectorFilterProto ret;
210 ret.set_skip_zero_values(skip_zero_values);
211 if (filtered_keys.has_value()) {
212 ret.set_filter_by_ids(true);
213 auto& filtered_ids = *ret.mutable_filtered_ids();
214 filtered_ids.Reserve(static_cast<int>(filtered_keys.value().size()));
215 for (const auto k : filtered_keys.value()) {
216 filtered_ids.Add(k.typed_id().value());
217 }
218 // Iteration on the set is random but we want the proto to be stable.
219 absl::c_sort(filtered_ids);
220 }
221 return ret;
222}
223
224} // namespace operations_research::math_opt
225
226#endif // OR_TOOLS_MATH_OPT_CPP_MAP_FILTER_H_
#define RETURN_IF_ERROR(expr)
CpModelProto proto
The output proto.
GRBmodel * model
absl::Status CheckModelStorage(const ModelStorage *const storage, const ModelStorage *const expected_storage)
Definition key_types.h:168
An object oriented wrapper for quadratic constraints in ModelStorage.
Definition gurobi_isv.cc:28
MapFilter< KeyType > MakeSkipAllFilter()
Definition map_filter.h:142
absl::StatusOr< MapFilter< LinearConstraint > > LinearConstraintFilterFromProto(const Model &model, const SparseVectorFilterProto &proto)
Definition map_filter.cc:46
MapFilter< ValueType > MakeKeepKeysFilter(const Collection &keys)
Definition map_filter.h:167
absl::StatusOr< MapFilter< QuadraticConstraint > > QuadraticConstraintFilterFromProto(const Model &model, const SparseVectorFilterProto &proto)
Definition map_filter.cc:67
MapFilter< KeyType > MakeSkipZerosFilter()
Definition map_filter.h:154
absl::StatusOr< MapFilter< Variable > > VariableFilterFromProto(const Model &model, const SparseVectorFilterProto &proto)
Definition map_filter.cc:28
absl::Status CheckModelStorage(const ModelStorage *expected_storage) const
Definition map_filter.h:196
std::optional< absl::flat_hash_set< KeyType > > filtered_keys
Definition map_filter.h:98
SparseVectorFilterProto Proto() const
Definition map_filter.h:210