OR-Tools  9.6
map_filter.h
Go to the documentation of this file.
1 // Copyright 2010-2022 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 <algorithm>
21 #include <initializer_list>
22 #include <optional>
23 
25 #include "ortools/math_opt/sparse_containers.pb.h"
27 
28 namespace operations_research {
29 namespace math_opt {
30 
31 // A filter that only keeps some specific key-value pairs of a map.
32 //
33 // It is used to limit the quantity of data returned in a SolveResult or in a
34 // CallbackResult when the models are huge and the user is only interested in
35 // the values of a subset of the keys.
36 //
37 // The keys, the type KeyType, should match the definition of "key types" given
38 // in key_types.h.
39 //
40 // A filter is composed of two sub-filters that act as a veto system: a
41 // key-value pair is kept only when it is kept by both filters. Those filters
42 // are:
43 // - skip_zero_values: when true, only keep pairs if the value is non zero (if
44 // the value is boolean, keep only pairs with true value).
45 // - filtered_keys: when set, only keep pairs which keys are in the provided
46 // list. If this list is empty, no pairs are returned. When unset, keep all
47 // pairs.
48 //
49 // See the MakeSkipAllFilter(), MakeSkipZerosFilter() and MakeKeepKeysFilter()
50 // functions below that provide shortcuts for making filters.
51 //
52 // This class is a factory of SparseVectorFilterProto.
53 template <typename KeyType>
54 struct MapFilter {
55  // If true, omits the pairs with zero values (the pairs with false value for
56  // bool vectors).
57  //
58  // Default is false, pairs with zero (or false) value are kept.
59  //
60  // Prefer using MakeSkipZerosFilter() when appropriate.
61  bool skip_zero_values = false;
62 
63  // The set of keys of pairs to keep. When unset, all pairs are kept
64  // (at least the ones with non-zero values, when skip_zero_values() is true).
65  //
66  // Default is unset, all pairs are kept.
67  //
68  // Example:
69  // MapFilter<Variable> filter = ...;
70  //
71  // // Unset the filter.
72  // filter.filtered_keys.reset();
73  // // alternatively:
74  // filter.filtered_keys = std::nullopt;
75  //
76  // // Set the filter with an empty list of keys (filtering out all pairs).
77  // //
78  // // Note that here `= {}` would NOT work since it would unset the
79  // // filtered_keys optional (i.e. like calling reset()).
80  // filter.filtered_keys.emplace();
81  //
82  // // Set the filter to a fix set of variables.
83  // const Variable x = ...;
84  // const Variable y = ...;
85  // filter.filtered_keys = {x, y};
86  //
87  // // Set the filter from a collection of variables.
88  // std::vector<Variable> decision_vars = {...};
89  // filter.emplace(decision_vars.begin(), decision_vars.end());
90  //
91  // Prefer using MakeSkipAllFilter() or MakeKeepKeysFilter() when appropriate.
92  std::optional<IdSet<KeyType>> filtered_keys;
93 
94  // Returns the model of filtered keys. It returns a non-null value if and only
95  // if the filtered_keys is set and non-empty.
96  inline const ModelStorage* storage() const;
97 
98  // Returns the proto corresponding to this filter.
99  SparseVectorFilterProto Proto() const;
100 };
101 
102 // Returns a filter that skips all key-value pairs.
103 //
104 // This is typically used to disable the dual data in SolveResult when these are
105 // ignored by the user.
106 //
107 // Example:
108 // const auto filter = MakeSkipAllFilter<Variable>();
109 template <typename KeyType>
111  MapFilter<KeyType> ret;
112  ret.filtered_keys.emplace();
113  return ret;
114 }
115 
116 // Returns a filter that skips all key-value pairs with zero values (or false
117 // values for bool).
118 //
119 // Example:
120 // const auto filter = MakeSkipZerosFilter<Variable>();
121 template <typename KeyType>
123  MapFilter<KeyType> ret;
124  ret.skip_zero_values = true;
125  return ret;
126 }
127 
128 // Returns a filter that keeps the key-value pairs with the given keys.
129 //
130 // Example:
131 // std::vector<Variable> decision_vars = ...;
132 // const auto filter = MakeKeepKeysFilter(decision_vars);
133 template <typename Collection,
134  typename ValueType = typename Collection::value_type>
135 MapFilter<ValueType> MakeKeepKeysFilter(const Collection& keys) {
137  ret.filtered_keys.emplace(keys.begin(), keys.end());
138  return ret;
139 }
140 
141 // Returns a filter that keeps the key-value pairs with the given keys.
142 //
143 // This overload is necessary since C++ does not automatically deduce the type
144 // when using the previous one.
145 //
146 // Example:
147 // const Variable x = ...;
148 // const Variable y = ...;
149 // const auto filter = MakeKeepKeysFilter({x, y});
150 template <typename KeyType>
151 MapFilter<KeyType> MakeKeepKeysFilter(std::initializer_list<KeyType> keys) {
152  MapFilter<KeyType> ret;
153  ret.filtered_keys = keys;
154  return ret;
155 }
156 
158 // Inline functions implementations.
160 
161 template <typename KeyType>
163  return filtered_keys ? filtered_keys->storage() : nullptr;
164 }
165 
166 template <typename KeyType>
167 SparseVectorFilterProto MapFilter<KeyType>::Proto() const {
168  SparseVectorFilterProto ret;
169  ret.set_skip_zero_values(skip_zero_values);
170  if (filtered_keys) {
171  ret.set_filter_by_ids(true);
172  const auto filtered_ids = ret.mutable_filtered_ids();
173  filtered_ids->Reserve(filtered_keys->size());
174  for (const auto id : filtered_keys->raw_set()) {
175  filtered_ids->Add(id.value());
176  }
177  // Iteration on the set is random but we want the proto to be stable.
178  std::sort(filtered_ids->begin(), filtered_ids->end());
179  }
180  return ret;
181 }
182 
183 } // namespace math_opt
184 } // namespace operations_research
185 
186 #endif // OR_TOOLS_MATH_OPT_CPP_MAP_FILTER_H_
int64_t value
MapFilter< KeyType > MakeSkipAllFilter()
Definition: map_filter.h:110
MapFilter< ValueType > MakeKeepKeysFilter(const Collection &keys)
Definition: map_filter.h:135
MapFilter< KeyType > MakeSkipZerosFilter()
Definition: map_filter.h:122
Collection of objects used to extend the Constraint Solver library.
std::optional< IdSet< KeyType > > filtered_keys
Definition: map_filter.h:92
SparseVectorFilterProto Proto() const
Definition: map_filter.h:167
const ModelStorage * storage() const
Definition: map_filter.h:162