Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
storage.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#ifndef OR_TOOLS_MATH_OPT_CONSTRAINTS_SOS_STORAGE_H_
15#define OR_TOOLS_MATH_OPT_CONSTRAINTS_SOS_STORAGE_H_
16
17#include <cstdint>
18#include <optional>
19#include <string>
20#include <type_traits>
21#include <utility>
22#include <vector>
23
24#include "absl/container/flat_hash_set.h"
25#include "absl/log/check.h"
27#include "ortools/math_opt/model.pb.h"
28#include "ortools/math_opt/model_update.pb.h"
32
34namespace internal {
35
36// Internal storage representation for a single SOS constraint.
37//
38// Implements the interface specified for the `ConstraintData` parameter of
39// `AtomicConstraintStorage`.
40template <typename ConstraintId>
42 public:
43 using IdType = ConstraintId;
44 using ProtoType = SosConstraintProto;
45 using UpdatesProtoType = SosConstraintUpdatesProto;
46
47 static_assert(
48 std::disjunction_v<std::is_same<ConstraintId, Sos1ConstraintId>,
49 std::is_same<ConstraintId, Sos2ConstraintId>>,
50 "ID type may only be Sos1ConstraintId or Sos2ConstraintId");
51
52 // `weights` must either be empty or the same length as `expressions`. If it
53 // is empty, default weights of 1, 2, ... will be used.
54 SosConstraintData(std::vector<LinearExpressionData> expressions,
55 std::vector<double> weights, std::string name)
56 : expressions_(std::move(expressions)), name_(std::move(name)) {
57 if (!weights.empty()) {
58 CHECK_EQ(weights.size(), expressions_.size());
59 weights_ = std::move(weights);
60 }
61 }
62
63 // The `in_proto` must be in a valid state; see the inline comments on
64 // `SosConstraintProto` for details.
65 static SosConstraintData FromProto(const ProtoType& in_proto);
66 ProtoType Proto() const;
67 std::vector<VariableId> RelatedVariables() const;
68 void DeleteVariable(VariableId var);
69
70 bool has_weights() const { return weights_.has_value(); }
71
72 double weight(const int index) const {
73 AssertInbounds(index);
74 return weights_.has_value() ? (*weights_)[index] : index + 1;
75 }
76 const LinearExpressionData& expression(const int index) const {
77 AssertInbounds(index);
78 return expressions_[index];
79 }
80 int64_t num_expressions() const { return expressions_.size(); }
81 const std::string& name() const { return name_; }
82
83 private:
84 SosConstraintData() = default;
85 void AssertInbounds(const int index) const {
86 CHECK_GE(index, 0);
87 CHECK_LT(index, expressions_.size());
88 }
89 // If present, length must be the same as that of `expressions_`.
90 // If absent, default weights of 1, 2, ... are used.
91 std::optional<std::vector<double>> weights_;
92 std::vector<LinearExpressionData> expressions_;
93 std::string name_;
94};
95
96} // namespace internal
97
100
101template <>
102struct AtomicConstraintTraits<Sos1ConstraintId> {
104};
105
106template <>
107struct AtomicConstraintTraits<Sos2ConstraintId> {
109};
110
112// Inline implementations
114
115namespace internal {
116
117template <typename ConstraintId>
118SosConstraintData<ConstraintId> SosConstraintData<ConstraintId>::FromProto(
119 const ProtoType& in_proto) {
120 const int num_expressions = in_proto.expressions_size();
122 data.name_ = in_proto.name();
123 for (int i = 0; i < num_expressions; ++i) {
124 data.expressions_.push_back(
125 LinearExpressionData::FromProto(in_proto.expressions(i)));
126 }
127 // Otherwise proto has default weights, so leave data.weights_ as unset.
128 if (!in_proto.weights().empty()) {
129 data.weights_.emplace().reserve(num_expressions);
130 for (int i = 0; i < num_expressions; ++i) {
131 data.weights_->push_back(in_proto.weights(i));
132 }
133 }
134 return data;
135}
136
137template <typename ConstraintId>
140 ProtoType constraint;
141 constraint.set_name(name());
142 for (int i = 0; i < num_expressions(); ++i) {
143 *constraint.add_expressions() = expression(i).Proto();
144 }
145 if (weights_.has_value()) {
146 for (int i = 0; i < num_expressions(); ++i) {
147 constraint.add_weights(weight(i));
148 }
149 }
150 return constraint;
151}
152
153template <typename ConstraintId>
155 const {
156 absl::flat_hash_set<VariableId> vars;
157 for (const LinearExpressionData& expression : expressions_) {
158 for (const auto [var, _] : expression.coeffs.terms()) {
159 vars.insert(var);
160 }
161 }
162 return std::vector<VariableId>(vars.begin(), vars.end());
163}
164
165template <typename ConstraintId>
167 for (LinearExpressionData& expression : expressions_) {
168 expression.coeffs.erase(var);
169 }
170}
171
172} // namespace internal
173} // namespace operations_research::math_opt
174
175#endif // OR_TOOLS_MATH_OPT_CONSTRAINTS_SOS_STORAGE_H_
const LinearExpressionData & expression(const int index) const
Definition storage.h:76
static SosConstraintData FromProto(const ProtoType &in_proto)
Definition storage.h:120
std::vector< VariableId > RelatedVariables() const
Definition storage.h:156
SosConstraintData(std::vector< LinearExpressionData > expressions, std::vector< double > weights, std::string name)
Definition storage.h:54
const std::string name
A name for logging purposes.
IntVar * var
int index
An object oriented wrapper for quadratic constraints in ModelStorage.
Definition gurobi_isv.cc:28
internal::SosConstraintData< Sos1ConstraintId > Sos1ConstraintData
Definition storage.h:98
internal::SosConstraintData< Sos2ConstraintId > Sos2ConstraintData
Definition storage.h:99
STL namespace.
int64_t weight
Definition pack.cc:510
static LinearExpressionData FromProto(const LinearExpressionProto &expr_proto)