Google OR-Tools v9.14
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
attributes.h
Go to the documentation of this file.
1// Copyright 2010-2025 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_ELEMENTAL_ATTRIBUTES_H_
15#define OR_TOOLS_MATH_OPT_ELEMENTAL_ATTRIBUTES_H_
16
17#include <array>
18#include <cstdint>
19#include <limits>
20#include <ostream>
21#include <tuple>
22#include <type_traits>
23
24#include "absl/strings/string_view.h"
25#include "ortools/base/array.h"
29
31
32// A base class for all attribute type descriptors.
33// `ValueTypeT` is the attribute value type, and `n` is the number of key
34// elements (e.g. `Double2` attribute has `ValueType` == `double` and `n` == 2).
35// This uses
36// [CRTP](https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern) in
37// `Impl` to deduce common descriptor properties from `Impl`. `Impl` must
38// inherit from `AttrTypeDescriptor` and define the following entities:
39// - `static constexpr absl::string_view kName`: The name of the attribute
40// type.
41// - `enum class AttrType`: The attribute type, with `k` enumerators
42// corresponding to attributes for this type. Enumerators must be numbered
43// `0..(k-1)` (a good way to do this is to leave them unnumbered).
44// - `std::array<AttrDescriptor, k> kAttrDescriptors`: A descriptor for each
45// of the `k` attributes for this type.
46template <typename ValueTypeT, int n, typename SymmetryT, typename Impl>
48 // The type of attribute values (e.g. `bool`, `int64_t`, `double`).
49 using ValueType = ValueTypeT;
50
51 // The number of key elements.
52 static constexpr int kNumKeyElements = n;
53
54 // The key symmetry. For example, this can be used to enforce that
55 // quadratic objective coefficients are the same for `(i, j)` and `(j, i)`
56 // (see `kObjQuadCoef` below).
57 using Symmetry = SymmetryT;
58
59 // A descriptor of an attribute of this attribute type.
60 // E.g., this could describe the attribute `DoubleAttr1::kVarLb`.
62 // The name of the attribute value.
63 absl::string_view name;
64 // The default value.
66 // The types of the `n` key elements.
67 std::array<ElementType, n> key_types;
68 };
69
70 // Returns the number of attributes of this attribute type.
71 static constexpr int NumAttrs() { return Impl::kAttrDescriptors.size(); }
72
73 // Returns an array with all attributes of this attribute type.
74 static constexpr auto Enumerate() {
75 std::array<typename Impl::AttrType, NumAttrs()> result;
76 for (int i = 0; i < NumAttrs(); ++i) {
77 result[i] = {static_cast<typename Impl::AttrType>(i)};
78 }
79 return result;
80 }
81};
82
84 : public AttrTypeDescriptor<bool, 0, NoSymmetry, BoolAttr0TypeDescriptor> {
85 static constexpr absl::string_view kName = "BoolAttr0";
86
87 enum class AttrType { kMaximize };
88
90 {{.name = "maximize", .default_value = false, .key_types = {}}});
91};
92
94 : public AttrTypeDescriptor<bool, 1, NoSymmetry, BoolAttr1TypeDescriptor> {
95 static constexpr absl::string_view kName = "BoolAttr1";
96
102
104 {{.name = "variable_integer",
105 .default_value = false,
106 .key_types = {ElementType::kVariable}},
107 {.name = "auxiliary_objective_maximize",
108 .default_value = false,
109 .key_types = {ElementType::kAuxiliaryObjective}},
110 {.name = "indicator_constraint_activate_on_zero",
111 .default_value = false,
112 .key_types = {ElementType::kIndicatorConstraint}}});
113};
114
116 : public AttrTypeDescriptor<int64_t, 0, NoSymmetry,
117 IntAttr0TypeDescriptor> {
118 static constexpr absl::string_view kName = "IntAttr0";
119
120 enum class AttrType {
122 };
123
125 {.name = "objective_priority", .default_value = 0, .key_types = {}},
126 });
127};
128
130 : public AttrTypeDescriptor<int64_t, 1, NoSymmetry,
131 IntAttr1TypeDescriptor> {
132 static constexpr absl::string_view kName = "IntAttr1";
133
134 enum class AttrType {
136 };
137
139 {.name = "auxiliary_objective_priority",
140 .default_value = 0,
141 .key_types = {ElementType::kAuxiliaryObjective}},
142 });
143};
144
146 : public AttrTypeDescriptor<double, 0, NoSymmetry,
147 DoubleAttr0TypeDescriptor> {
148 static constexpr absl::string_view kName = "DoubleAttr0";
149
150 enum class AttrType { kObjOffset };
151
153 {{.name = "objective_offset", .default_value = 0.0, .key_types = {}}});
154};
155
157 : public AttrTypeDescriptor<double, 1, NoSymmetry,
158 DoubleAttr1TypeDescriptor> {
159 static constexpr absl::string_view kName = "DoubleAttr1";
160
173
175 {.name = "variable_lower_bound",
176 .default_value = -std::numeric_limits<double>::infinity(),
177 .key_types = {ElementType::kVariable}},
178 {.name = "variable_upper_bound",
179 .default_value = std::numeric_limits<double>::infinity(),
180 .key_types = {ElementType::kVariable}},
181 {.name = "objective_linear_coefficient",
182 .default_value = 0.0,
183 .key_types = {ElementType::kVariable}},
184 {.name = "linear_constraint_lower_bound",
185 .default_value = -std::numeric_limits<double>::infinity(),
186 .key_types = {ElementType::kLinearConstraint}},
187 {.name = "linear_constraint_upper_bound",
188 .default_value = std::numeric_limits<double>::infinity(),
189 .key_types = {ElementType::kLinearConstraint}},
190 {.name = "auxiliary_objective_offset",
191 .default_value = 0.0,
192 .key_types = {ElementType::kAuxiliaryObjective}},
193 {.name = "quadratic_constraint_lower_bound",
194 .default_value = -std::numeric_limits<double>::infinity(),
195 .key_types = {ElementType::kQuadraticConstraint}},
196 {.name = "quadratic_constraint_upper_bound",
197 .default_value = std::numeric_limits<double>::infinity(),
198 .key_types = {ElementType::kQuadraticConstraint}},
199 {.name = "indicator_constraint_lower_bound",
200 .default_value = -std::numeric_limits<double>::infinity(),
201 .key_types = {ElementType::kIndicatorConstraint}},
202 {.name = "indicator_constraint_upper_bound",
203 .default_value = std::numeric_limits<double>::infinity(),
204 .key_types = {ElementType::kIndicatorConstraint}},
205 });
206};
207
209 : public AttrTypeDescriptor<double, 2, NoSymmetry,
210 DoubleAttr2TypeDescriptor> {
211 static constexpr absl::string_view kName = "DoubleAttr2";
212
219
221 {.name = "linear_constraint_coefficient",
222 .default_value = 0.0,
224 {.name = "auxiliary_objective_linear_coefficient",
225 .default_value = 0.0,
227 {.name = "quadratic_constraint_linear_coefficient",
228 .default_value = 0.0,
231 {.name = "indicator_constraint_linear_coefficient",
232 .default_value = 0.0,
235 });
236};
237
239 : public AttrTypeDescriptor<double, 2, ElementSymmetry<0, 1>,
240 SymmetricDoubleAttr2TypeDescriptor> {
241 static constexpr absl::string_view kName = "SymmetricDoubleAttr2";
242
243 enum class AttrType {
245 };
246
248 {.name = "objective_quadratic_coefficient",
249 .default_value = 0.0,
251 });
252};
253
254// Note: For this type, we pick the symmetric elements to be the last 2 elements
255// of the key (index 1 and 2).
257 : public AttrTypeDescriptor<double, 3, ElementSymmetry<1, 2>,
258 SymmetricDoubleAttr3TypeDescriptor> {
259 static constexpr absl::string_view kName = "SymmetricDoubleAttr3";
260
261 enum class AttrType {
263 };
264
266 {.name = "quadratic_constraint_quadratic_coefficient",
267 .default_value = 0.0,
270 });
271};
272
274 : public AttrTypeDescriptor<VariableId, 1, NoSymmetry,
275 VariableAttr1TypeDescriptor> {
276 static constexpr absl::string_view kName = "VariableAttr1";
277
278 enum class AttrType {
280 };
281
283 {.name = "indicator_constraint_indicator",
284 .default_value = VariableId(),
285 .key_types = {ElementType::kIndicatorConstraint}},
286 });
287};
288
289// The list of all available attribute descriptors. This is typically
290// manipulated using the `AllAttrs` helper in `derived_data.h`.
297
298// Aliases for types.
309
310// Returns the index of `AttrT` in `AllAttrTypes` if `AttrT` is an attribute
311// type, -1 otherwise.
312template <typename AttrT>
313static constexpr int GetIndexIfAttr() {
314 using Tuple = AllAttrTypeDescriptors;
315 // NOLINTNEXTLINE(clang-diagnostic-pre-c++20-compat)
316 return ApplyOnIndexRange<std::tuple_size_v<Tuple>>([]<int... i>() {
317 return ((std::is_same_v<std::remove_cv_t<std::remove_reference_t<AttrT>>,
318 typename std::tuple_element_t<i, Tuple>::AttrType>
319 ? (i + 1)
320 : 0) +
321 ... + -1);
322 });
323}
324
325template <typename AttrT,
326 typename = std::enable_if_t<(GetIndexIfAttr<AttrT>() >= 0)>>
327absl::string_view ToString(const AttrT attr) {
328 using Descriptor =
329 std::tuple_element_t<GetIndexIfAttr<AttrT>(), AllAttrTypeDescriptors>;
330 const int attr_index = static_cast<int>(attr);
331 return Descriptor::kAttrDescriptors[attr_index].name;
332}
333
334template <typename Sink, typename AttrT,
335 typename = std::enable_if_t<(GetIndexIfAttr<AttrT>() >= 0)>>
336void AbslStringify(Sink& sink, const AttrT attr_type) {
337 sink.Append(ToString(attr_type));
338}
339
340template <typename AttrT>
341std::enable_if_t<(GetIndexIfAttr<AttrT>() >= 0), std::ostream&> operator<<(
342 std::ostream& ostr, AttrT attr) {
343 ostr << ToString(attr);
344 return ostr;
345}
346
347} // namespace operations_research::math_opt
348
349#endif // OR_TOOLS_MATH_OPT_ELEMENTAL_ATTRIBUTES_H_
constexpr std::array< std::remove_cv_t< T >, N > to_array(T(&ts)[N])
Definition array.h:40
An object oriented wrapper for quadratic constraints in ModelStorage.
Definition gurobi_isv.cc:28
constexpr decltype(auto) ApplyOnIndexRange(Fn &&fn)
Definition arrays.h:38
SymmetricDoubleAttr2TypeDescriptor::AttrType SymmetricDoubleAttr2
Definition attributes.h:306
DoubleAttr0TypeDescriptor::AttrType DoubleAttr0
Definition attributes.h:303
BoolAttr1TypeDescriptor::AttrType BoolAttr1
Definition attributes.h:300
VariableAttr1TypeDescriptor::AttrType VariableAttr1
Definition attributes.h:308
IntAttr1TypeDescriptor::AttrType IntAttr1
Definition attributes.h:302
ElementId< ElementType::kVariable > VariableId
Definition elements.h:264
DoubleAttr1TypeDescriptor::AttrType DoubleAttr1
Definition attributes.h:304
void AbslStringify(Sink &sink, const AttrT attr_type)
Definition attributes.h:336
DoubleAttr2TypeDescriptor::AttrType DoubleAttr2
Definition attributes.h:305
SymmetricDoubleAttr3TypeDescriptor::AttrType SymmetricDoubleAttr3
Definition attributes.h:307
absl::string_view ToString(const AttrT attr)
Definition attributes.h:327
std::tuple< BoolAttr0TypeDescriptor, BoolAttr1TypeDescriptor, IntAttr0TypeDescriptor, IntAttr1TypeDescriptor, DoubleAttr0TypeDescriptor, DoubleAttr1TypeDescriptor, DoubleAttr2TypeDescriptor, SymmetricDoubleAttr2TypeDescriptor, SymmetricDoubleAttr3TypeDescriptor, VariableAttr1TypeDescriptor > AllAttrTypeDescriptors
Definition attributes.h:291
static constexpr int GetIndexIfAttr()
Definition attributes.h:313
BoolAttr0TypeDescriptor::AttrType BoolAttr0
Aliases for types.
Definition attributes.h:299
IntAttr0TypeDescriptor::AttrType IntAttr0
Definition attributes.h:301
std::array< ElementType, n > key_types
The types of the n key elements.
Definition attributes.h:67
absl::string_view name
The name of the attribute value.
Definition attributes.h:63
static constexpr auto Enumerate()
Returns an array with all attributes of this attribute type.
Definition attributes.h:74
static constexpr int kNumKeyElements
The number of key elements.
Definition attributes.h:52
static constexpr int NumAttrs()
Returns the number of attributes of this attribute type.
Definition attributes.h:71
ValueTypeT ValueType
The type of attribute values (e.g. bool, int64_t, double).
Definition attributes.h:49
static constexpr absl::string_view kName
Definition attributes.h:85
static constexpr absl::string_view kName
Definition attributes.h:95
static constexpr absl::string_view kName
Definition attributes.h:118
static constexpr absl::string_view kName
Definition attributes.h:132