14 #ifndef OR_TOOLS_MATH_OPT_CONSTRAINTS_SOS_STORAGE_H_
15 #define OR_TOOLS_MATH_OPT_CONSTRAINTS_SOS_STORAGE_H_
20 #include <type_traits>
24 #include "absl/container/flat_hash_map.h"
25 #include "absl/container/flat_hash_set.h"
26 #include "absl/log/check.h"
28 #include "ortools/math_opt/model.pb.h"
29 #include "ortools/math_opt/model_update.pb.h"
30 #include "ortools/math_opt/sparse_containers.pb.h"
42 template <
typename Constra
intId>
50 std::disjunction_v<std::is_same<ConstraintId, Sos1ConstraintId>,
51 std::is_same<ConstraintId, Sos2ConstraintId>>,
52 "ID type may only be Sos1ConstraintId or Sos2ConstraintId");
55 absl::flat_hash_map<VariableId, double>
terms;
62 std::vector<double> weights, std::string
name)
63 : expressions_(std::move(expressions)), name_(std::move(
name)) {
64 if (!weights.empty()) {
65 CHECK_EQ(weights.size(), expressions_.size());
66 weights_ = std::move(weights);
80 AssertInbounds(
index);
81 return weights_.has_value() ? (*weights_)[
index] :
index + 1;
84 AssertInbounds(
index);
85 return expressions_[
index];
88 const std::string&
name()
const {
return name_; }
92 void AssertInbounds(
const int index)
const {
94 CHECK_LT(
index, expressions_.size());
98 std::optional<std::vector<double>> weights_;
99 std::vector<LinearExpression> expressions_;
124 template <
typename Constra
intId>
127 const int num_expressions = in_proto.expressions_size();
129 data.name_ = in_proto.name();
130 for (
int i = 0; i < num_expressions; ++i) {
132 const LinearExpressionProto& proto_expression = in_proto.expressions(i);
133 expression.
offset = proto_expression.offset();
134 for (
int j = 0; j < proto_expression.ids_size(); ++j) {
135 expression.
terms.insert({VariableId(proto_expression.ids(j)),
136 proto_expression.coefficients(j)});
140 if (!in_proto.weights().empty()) {
141 data.weights_.emplace().reserve(num_expressions);
142 for (
int i = 0; i < num_expressions; ++i) {
143 data.weights_->push_back(in_proto.weights(i));
149 template <
typename Constra
intId>
153 constraint.set_name(
name());
154 for (
int i = 0; i < num_expressions(); ++i) {
156 LinearExpressionProto& proto_expr = *constraint.add_expressions();
157 proto_expr.set_offset(expr.
offset);
159 proto_expr.add_ids(
id.
value());
160 proto_expr.add_coefficients(expr.
terms.at(
id));
163 if (weights_.has_value()) {
164 for (
int i = 0; i < num_expressions(); ++i) {
165 constraint.add_weights(
weight(i));
171 template <
typename Constra
intId>
174 absl::flat_hash_set<VariableId> vars;
176 for (
const auto [
var, _] : expression.terms) {
180 return std::vector<VariableId>(vars.begin(), vars.end());
183 template <
typename Constra
intId>
186 expression.terms.erase(
var);
double weight(const int index) const
void DeleteVariable(VariableId var)
static SosConstraintData FromProto(const ProtoType &in_proto)
int64_t num_expressions() const
std::vector< VariableId > RelatedVariables() const
SosConstraintUpdatesProto UpdatesProtoType
SosConstraintProto ProtoType
const std::string & name() const
SosConstraintData(std::vector< LinearExpression > expressions, std::vector< double > weights, std::string name)
const LinearExpression & expression(const int index) const
internal::SosConstraintData< Sos1ConstraintId > Sos1ConstraintData
std::vector< K > SortedMapKeys(const absl::flat_hash_map< K, V > &in_map)
internal::SosConstraintData< Sos2ConstraintId > Sos2ConstraintData
absl::flat_hash_map< VariableId, double > terms