Google OR-Tools v9.14
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
model.cc
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
15
16#include <algorithm>
17#include <limits>
18#include <memory>
19#include <optional>
20#include <ostream>
21#include <string>
22#include <utility>
23#include <vector>
24
25#include "absl/base/nullability.h"
26#include "absl/log/check.h"
27#include "absl/log/die_if_null.h"
28#include "absl/status/status.h"
29#include "absl/status/statusor.h"
30#include "absl/strings/string_view.h"
31#include "absl/types/span.h"
50
51namespace operations_research {
52namespace math_opt {
53
54constexpr double kInf = std::numeric_limits<double>::infinity();
55
56absl::StatusOr<std::unique_ptr<Model>> Model::FromModelProto(
57 const ModelProto& model_proto) {
58 ASSIGN_OR_RETURN(absl::Nonnull<std::unique_ptr<ModelStorage>> storage,
59 ModelStorage::FromModelProto(model_proto));
60 return std::make_unique<Model>(std::move(storage));
61}
62
63Model::Model(const absl::string_view name)
64 : storage_(std::make_shared<ModelStorage>(name)) {}
65
66Model::Model(absl::Nonnull<std::unique_ptr<ModelStorage>> storage)
67 : storage_(ABSL_DIE_IF_NULL(std::move(storage))) {}
68
69absl::Nonnull<std::unique_ptr<Model>> Model::Clone(
70 const std::optional<absl::string_view> new_name) const {
71 return std::make_unique<Model>(storage_->Clone(new_name));
72}
73
75 const BoundedLinearExpression& bounded_expr, absl::string_view name) {
76 CheckOptionalModel(bounded_expr.expression.storage());
77
78 const LinearConstraintId constraint = storage()->AddLinearConstraint(
79 bounded_expr.lower_bound_minus_offset(),
80 bounded_expr.upper_bound_minus_offset(), name);
81 for (const auto& [variable, coef] : bounded_expr.expression.terms()) {
82 storage()->set_linear_constraint_coefficient(constraint,
83 variable.typed_id(), coef);
84 }
85 return LinearConstraint(storage(), constraint);
86}
87
88std::vector<Variable> Model::Variables() const {
89 std::vector<Variable> result;
90 result.reserve(storage()->num_variables());
91 for (const VariableId var_id : storage()->variables()) {
92 result.push_back(Variable(storage(), var_id));
93 }
94 return result;
95}
96
97std::vector<Variable> Model::SortedVariables() const {
98 std::vector<Variable> result = Variables();
99 std::sort(result.begin(), result.end(),
100 [](const Variable& l, const Variable& r) {
101 return l.typed_id() < r.typed_id();
102 });
103 return result;
104}
105
106std::vector<LinearConstraint> Model::ColumnNonzeros(
107 const Variable variable) const {
108 CheckModel(variable.storage());
109 std::vector<LinearConstraint> result;
110 for (const LinearConstraintId constraint :
111 storage()->linear_constraints_with_variable(variable.typed_id())) {
112 result.push_back(LinearConstraint(storage(), constraint));
113 }
114 return result;
115}
116
117std::vector<Variable> Model::RowNonzeros(
118 const LinearConstraint constraint) const {
119 CheckModel(constraint.storage());
120 std::vector<Variable> result;
121 for (const VariableId variable :
122 storage()->variables_in_linear_constraint(constraint.typed_id())) {
123 result.push_back(Variable(storage(), variable));
124 }
125 return result;
126}
127
128std::vector<LinearConstraint> Model::LinearConstraints() const {
129 std::vector<LinearConstraint> result;
130 result.reserve(storage()->num_linear_constraints());
131 for (const LinearConstraintId lin_con_id : storage()->LinearConstraints()) {
132 result.push_back(LinearConstraint(storage(), lin_con_id));
133 }
134 return result;
135}
136
137std::vector<LinearConstraint> Model::SortedLinearConstraints() const {
138 std::vector<LinearConstraint> result = LinearConstraints();
139 std::sort(result.begin(), result.end(),
140 [](const LinearConstraint& l, const LinearConstraint& r) {
141 return l.typed_id() < r.typed_id();
142 });
143 return result;
144}
145
147 const bool is_maximize) {
148 CheckOptionalModel(objective.storage());
149 storage()->clear_objective(kPrimaryObjectiveId);
150 storage()->set_is_maximize(kPrimaryObjectiveId, is_maximize);
151 storage()->set_objective_offset(kPrimaryObjectiveId, objective.offset());
152 for (const auto& [var, coef] : objective.terms()) {
153 storage()->set_linear_objective_coefficient(kPrimaryObjectiveId,
154 var.typed_id(), coef);
155 }
156}
157
159 const bool is_maximize) {
160 CheckOptionalModel(objective.storage());
161 storage()->clear_objective(kPrimaryObjectiveId);
162 storage()->set_is_maximize(kPrimaryObjectiveId, is_maximize);
163 storage()->set_objective_offset(kPrimaryObjectiveId, objective.offset());
164 for (const auto& [var, coef] : objective.linear_terms()) {
165 storage()->set_linear_objective_coefficient(kPrimaryObjectiveId,
166 var.typed_id(), coef);
167 }
168 for (const auto& [vars, coef] : objective.quadratic_terms()) {
169 storage()->set_quadratic_objective_coefficient(
170 kPrimaryObjectiveId, vars.typed_id().first, vars.typed_id().second,
171 coef);
172 }
173}
174
175void Model::AddToObjective(const LinearExpression& objective_terms) {
176 CheckOptionalModel(objective_terms.storage());
177 storage()->set_objective_offset(
179 objective_terms.offset() +
181 for (const auto& [var, coef] : objective_terms.terms()) {
182 storage()->set_linear_objective_coefficient(
183 kPrimaryObjectiveId, var.typed_id(),
184 coef + storage()->linear_objective_coefficient(kPrimaryObjectiveId,
185 var.typed_id()));
186 }
187}
188
189void Model::AddToObjective(const QuadraticExpression& objective_terms) {
190 CheckOptionalModel(objective_terms.storage());
191 storage()->set_objective_offset(
193 objective_terms.offset() +
195 for (const auto& [var, coef] : objective_terms.linear_terms()) {
196 storage()->set_linear_objective_coefficient(
197 kPrimaryObjectiveId, var.typed_id(),
198 coef + storage()->linear_objective_coefficient(kPrimaryObjectiveId,
199 var.typed_id()));
200 }
201 for (const auto& [vars, coef] : objective_terms.quadratic_terms()) {
202 storage()->set_quadratic_objective_coefficient(
203 kPrimaryObjectiveId, vars.typed_id().first, vars.typed_id().second,
204 coef + storage()->quadratic_objective_coefficient(
205 kPrimaryObjectiveId, vars.typed_id().first,
206 vars.typed_id().second));
207 }
208}
209
211 CHECK_EQ(storage()->num_quadratic_objective_terms(kPrimaryObjectiveId), 0)
212 << "The objective function contains quadratic terms and cannot be "
213 "represented as a LinearExpression";
214 LinearExpression result = storage()->objective_offset(kPrimaryObjectiveId);
215 for (const auto& [v, coef] :
216 storage()->linear_objective(kPrimaryObjectiveId)) {
217 result += Variable(storage(), v) * coef;
218 }
219 return result;
220}
221
223 QuadraticExpression result = storage()->objective_offset(kPrimaryObjectiveId);
224 for (const auto& [v, coef] :
225 storage()->linear_objective(kPrimaryObjectiveId)) {
226 result += Variable(storage(), v) * coef;
227 }
228 for (const auto& [v1, v2, coef] :
229 storage()->quadratic_objective_terms(kPrimaryObjectiveId)) {
230 result +=
231 QuadraticTerm(Variable(storage(), v1), Variable(storage(), v2), coef);
232 }
233 return result;
234}
235
236std::vector<Objective> Model::AuxiliaryObjectives() const {
237 std::vector<Objective> result;
238 result.reserve(num_auxiliary_objectives());
239 for (const AuxiliaryObjectiveId id : storage()->AuxiliaryObjectives()) {
240 result.push_back(auxiliary_objective(id));
241 }
242 return result;
243}
244
245std::vector<Objective> Model::SortedAuxiliaryObjectives() const {
246 std::vector<Objective> result = AuxiliaryObjectives();
247 std::sort(result.begin(), result.end(),
248 [](const Objective& l, const Objective& r) {
249 return l.typed_id() < r.typed_id();
250 });
251 return result;
252}
253
254void Model::SetObjective(const Objective objective,
255 const LinearExpression& expression,
256 const bool is_maximize) {
257 CheckModel(objective.storage());
258 CheckOptionalModel(expression.storage());
259 storage()->clear_objective(objective.typed_id());
260 set_is_maximize(objective, is_maximize);
261 set_objective_offset(objective, expression.offset());
262 for (const auto [var, coef] : expression.terms()) {
263 set_objective_coefficient(objective, var, coef);
264 }
265}
266
267void Model::AddToObjective(const Objective objective,
268 const LinearExpression& expression) {
269 CheckModel(objective.storage());
270 CheckOptionalModel(expression.storage());
271 set_objective_offset(objective, objective.offset() + expression.offset());
272 for (const auto [var, coef] : expression.terms()) {
273 set_objective_coefficient(objective, var,
274 objective.coefficient(var) + coef);
275 }
276}
277
279 const Objective objective) const {
280 CheckModel(objective.storage());
281 std::vector<Variable> result;
282 result.reserve(storage()->num_linear_objective_terms(objective.typed_id()));
283 for (const auto [var_id, unused] :
284 storage()->linear_objective(objective.typed_id())) {
285 result.push_back(Variable(storage(), var_id));
286 }
287 return result;
288}
289
290std::vector<Variable> Model::NonzeroVariablesInQuadraticObjective() const {
291 std::vector<Variable> result;
292 for (const auto& [var_id1, var_id2, unused] :
293 storage()->quadratic_objective_terms(kPrimaryObjectiveId)) {
294 result.push_back(Variable(storage(), var_id1));
295 result.push_back(Variable(storage(), var_id2));
296 }
297 return result;
298}
299
300ModelProto Model::ExportModel(const bool remove_names) const {
301 return storage()->ExportModel(remove_names);
302}
303
304std::unique_ptr<UpdateTracker> Model::NewUpdateTracker() {
305 return std::make_unique<UpdateTracker>(storage_);
306}
307
308absl::Status Model::ApplyUpdateProto(const ModelUpdateProto& update_proto) {
309 return storage()->ApplyUpdateProto(update_proto);
310}
311
312std::ostream& operator<<(std::ostream& ostr, const Model& model) {
313 ostr << "Model";
314 if (!model.name().empty()) ostr << " " << model.name();
315 ostr << ":\n";
316
317 if (model.num_auxiliary_objectives() == 0) {
318 ostr << " Objective:\n"
319 << (model.is_maximize() ? " maximize " : " minimize ")
320 << model.ObjectiveAsQuadraticExpression() << "\n";
321 } else {
322 ostr << " Objectives:\n";
323 const auto stream_objective = [](std::ostream& ostr, const Objective obj) {
324 ostr << " " << obj << " (priority " << obj.priority()
325 << "): " << (obj.maximize() ? "maximize " : "minimize ")
326 << obj.AsQuadraticExpression() << "\n";
327 };
328 stream_objective(ostr, model.primary_objective());
329 for (const Objective obj : model.SortedAuxiliaryObjectives()) {
330 stream_objective(ostr, obj);
331 }
332 }
333
334 ostr << " Linear constraints:\n";
335 for (const LinearConstraint constraint : model.SortedLinearConstraints()) {
336 ostr << " " << constraint << ": " << constraint.AsBoundedLinearExpression()
337 << "\n";
338 }
339
340 if (model.num_quadratic_constraints() > 0) {
341 ostr << " Quadratic constraints:\n";
342 for (const QuadraticConstraint constraint :
344 ostr << " " << constraint << ": "
345 << constraint.AsBoundedQuadraticExpression() << "\n";
346 }
347 }
348
349 if (model.num_second_order_cone_constraints() > 0) {
350 ostr << " Second-order cone constraints:\n";
351 for (const SecondOrderConeConstraint constraint :
353 ostr << " " << constraint << ": " << constraint.ToString() << "\n";
354 }
355 }
356
357 if (model.num_sos1_constraints() > 0) {
358 ostr << " SOS1 constraints:\n";
359 for (const Sos1Constraint constraint : model.SortedSos1Constraints()) {
360 ostr << " " << constraint << ": " << constraint.ToString() << "\n";
361 }
362 }
363
364 if (model.num_sos2_constraints() > 0) {
365 ostr << " SOS2 constraints:\n";
366 for (const Sos2Constraint constraint : model.SortedSos2Constraints()) {
367 ostr << " " << constraint << ": " << constraint.ToString() << "\n";
368 }
369 }
370
371 if (model.num_indicator_constraints() > 0) {
372 ostr << " Indicator constraints:\n";
373 for (const IndicatorConstraint constraint :
375 ostr << " " << constraint << ": " << constraint.ToString() << "\n";
376 }
377 }
378
379 ostr << " Variables:\n";
380 for (const Variable v : model.SortedVariables()) {
381 ostr << " " << v;
382 if (v.is_integer()) {
383 if (v.lower_bound() == 0 && v.upper_bound() == 1) {
384 ostr << " (binary)\n";
385 continue;
386 }
387 ostr << " (integer)";
388 }
389 ostr << " in ";
390 if (v.lower_bound() == -kInf) {
391 ostr << "(-∞";
392 } else {
393 ostr << "[" << RoundTripDoubleFormat(v.lower_bound());
394 }
395 ostr << ", ";
396 if (v.upper_bound() == kInf) {
397 ostr << "+∞)";
398 } else {
399 ostr << RoundTripDoubleFormat(v.upper_bound()) << "]";
400 }
401 ostr << "\n";
402 }
403 return ostr;
404}
405
406// ------------------------- Quadratic constraints -----------------------------
407
409 const BoundedQuadraticExpression& bounded_expr,
410 const absl::string_view name) {
411 CheckOptionalModel(bounded_expr.expression.storage());
412 SparseCoefficientMap linear_terms;
413 for (const auto [var, coeff] : bounded_expr.expression.linear_terms()) {
414 linear_terms.set(var.typed_id(), coeff);
415 }
416 SparseSymmetricMatrix quadratic_terms;
417 for (const auto& [var_ids, coeff] :
418 bounded_expr.expression.quadratic_terms()) {
419 quadratic_terms.set(var_ids.typed_id().first, var_ids.typed_id().second,
420 coeff);
421 }
422 const QuadraticConstraintId id =
423 storage()->AddAtomicConstraint(QuadraticConstraintData{
424 .lower_bound = bounded_expr.lower_bound_minus_offset(),
425 .upper_bound = bounded_expr.upper_bound_minus_offset(),
426 .linear_terms = std::move(linear_terms),
427 .quadratic_terms = std::move(quadratic_terms),
428 .name = std::string(name),
429 });
430 return QuadraticConstraint(storage(), id);
431}
432
433// --------------------- Second-order cone constraints -------------------------
434
436 absl::Span<const LinearExpression> arguments_to_norm,
437 const LinearExpression& upper_bound, const absl::string_view name) {
438 CheckOptionalModel(upper_bound.storage());
439 std::vector<LinearExpressionData> arguments_to_norm_data;
440 arguments_to_norm_data.reserve(arguments_to_norm.size());
441 for (const LinearExpression& expr : arguments_to_norm) {
442 CheckOptionalModel(expr.storage());
443 arguments_to_norm_data.push_back(FromLinearExpression(expr));
444 }
445 const SecondOrderConeConstraintId id =
446 storage()->AddAtomicConstraint(SecondOrderConeConstraintData{
447 .upper_bound = FromLinearExpression(upper_bound),
448 .arguments_to_norm = std::move(arguments_to_norm_data),
449 .name = std::string(name),
450 });
452}
453
454// --------------------------- SOS1 constraints --------------------------------
455
456namespace {
457
458template <typename SosData>
459SosData MakeSosData(const std::vector<LinearExpression>& expressions,
460 std::vector<double> weights, const absl::string_view name) {
461 std::vector<LinearExpressionData> storage_expressions;
462 storage_expressions.reserve(expressions.size());
463 for (const LinearExpression& expr : expressions) {
464 LinearExpressionData& storage_expr = storage_expressions.emplace_back();
465 storage_expr.offset = expr.offset();
466 for (const auto& [var, coeff] : expr.terms()) {
467 storage_expr.coeffs.set(var.typed_id(), coeff);
468 }
469 }
470 return SosData(std::move(storage_expressions), std::move(weights),
471 std::string(name));
472}
473
474} // namespace
475
477 const std::vector<LinearExpression>& expressions,
478 std::vector<double> weights, const absl::string_view name) {
479 for (const LinearExpression& expr : expressions) {
480 CheckOptionalModel(expr.storage());
481 }
482 const Sos1ConstraintId id = storage()->AddAtomicConstraint(
483 MakeSosData<Sos1ConstraintData>(expressions, std::move(weights), name));
484 return Sos1Constraint(storage(), id);
485}
486
487// --------------------------- SOS2 constraints --------------------------------
488
490 const std::vector<LinearExpression>& expressions,
491 std::vector<double> weights, const absl::string_view name) {
492 for (const LinearExpression& expr : expressions) {
493 CheckOptionalModel(expr.storage());
494 }
495 const Sos2ConstraintId id = storage()->AddAtomicConstraint(
496 MakeSosData<Sos2ConstraintData>(expressions, std::move(weights), name));
497 return Sos2Constraint(storage(), id);
498}
499
500// --------------------------- Indicator constraints ---------------------------
501
503 const Variable indicator_variable,
504 const BoundedLinearExpression& implied_constraint,
505 const bool activate_on_zero, const absl::string_view name) {
506 CheckModel(indicator_variable.storage());
507 CheckOptionalModel(implied_constraint.expression.storage());
508 // We ignore the offset while unpacking here; instead, we account for it below
509 // by using the `{lower,upper}_bound_minus_offset` member functions.
510 auto [expr, _] = FromLinearExpression(implied_constraint.expression);
511 const IndicatorConstraintId id =
512 storage()->AddAtomicConstraint(IndicatorConstraintData{
513 .lower_bound = implied_constraint.lower_bound_minus_offset(),
514 .upper_bound = implied_constraint.upper_bound_minus_offset(),
515 .linear_terms = std::move(expr),
516 .indicator = indicator_variable.typed_id(),
517 .activate_on_zero = activate_on_zero,
518 .name = std::string(name),
519 });
520 return IndicatorConstraint(storage(), id);
521}
522
523} // namespace math_opt
524} // namespace operations_research
#define ASSIGN_OR_RETURN(lhs, rexpr)
const VariableMap< double > & terms() const
Returns the terms in this expression.
Sos1Constraint AddSos1Constraint(const std::vector< LinearExpression > &expressions, std::vector< double > weights={}, absl::string_view name="")
Definition model.cc:476
std::vector< IndicatorConstraint > SortedIndicatorConstraints() const
Definition model.h:1399
Objective auxiliary_objective(int64_t id) const
Will CHECK if has_auxiliary_objective(id) is false.
Definition model.h:1592
int64_t num_sos2_constraints() const
Definition model.h:1327
QuadraticConstraint AddQuadraticConstraint(const BoundedQuadraticExpression &bounded_expr, absl::string_view name="")
----------------------— Quadratic constraints --------------------------—
Definition model.cc:408
Sos2Constraint AddSos2Constraint(const std::vector< LinearExpression > &expressions, std::vector< double > weights={}, absl::string_view name="")
------------------------— SOS2 constraints -----------------------------—
Definition model.cc:489
ModelProto ExportModel(bool remove_names=false) const
Definition model.cc:300
static absl::StatusOr< std::unique_ptr< Model > > FromModelProto(const ModelProto &model_proto)
Definition model.cc:56
std::vector< Sos2Constraint > SortedSos2Constraints() const
Definition model.h:1357
std::vector< Sos1Constraint > SortedSos1Constraints() const
Definition model.h:1316
absl::string_view name() const
----------------------------— Variables --------------------------------—
Definition model.h:959
std::vector< QuadraticConstraint > SortedQuadraticConstraints() const
Definition model.h:1226
SecondOrderConeConstraint AddSecondOrderConeConstraint(absl::Span< const LinearExpression > arguments_to_norm, const LinearExpression &upper_bound, absl::string_view name="")
------------------— Second-order cone constraints ----------------------—
Definition model.cc:435
std::vector< Variable > NonzeroVariablesInLinearObjective() const
Definition model.h:1532
std::vector< SecondOrderConeConstraint > SortedSecondOrderConeConstraints() const
Definition model.h:1274
std::vector< Objective > AuxiliaryObjectives() const
Definition model.cc:236
int64_t num_second_order_cone_constraints() const
Definition model.h:1238
std::unique_ptr< UpdateTracker > NewUpdateTracker()
Definition model.cc:304
std::vector< LinearConstraint > SortedLinearConstraints() const
Definition model.cc:137
void set_is_maximize(bool is_maximize)
Prefer set_maximize() and set_minimize() above for more readable code.
Definition model.h:1528
int64_t num_sos1_constraints() const
Definition model.h:1286
Variable variable(int64_t id) const
Will CHECK if has_variable(id) is false.
Definition model.h:1006
QuadraticExpression ObjectiveAsQuadraticExpression() const
Definition model.cc:222
void AddToObjective(double objective)
Adds the provided expression terms to the objective.
Definition model.h:1447
ModelStorageCPtr storage() const
Definition model.h:917
void set_objective_offset(double value)
Definition model.h:1516
absl::Status ApplyUpdateProto(const ModelUpdateProto &update_proto)
Definition model.cc:308
std::vector< LinearConstraint > ColumnNonzeros(Variable variable) const
Definition model.cc:106
int64_t num_indicator_constraints() const
Definition model.h:1368
std::vector< LinearConstraint > LinearConstraints() const
Definition model.cc:128
std::vector< Objective > SortedAuxiliaryObjectives() const
Definition model.cc:245
int64_t num_auxiliary_objectives() const
Definition model.h:1576
void set_objective_coefficient(Variable variable, double value)
Definition model.h:1476
double upper_bound(Variable variable) const
Returns a variable upper bound.
Definition model.h:1035
std::vector< Variable > Variables() const
Definition model.cc:88
std::vector< Variable > NonzeroVariablesInQuadraticObjective() const
Definition model.cc:290
absl::Nonnull< std::unique_ptr< Model > > Clone(std::optional< absl::string_view > new_name=std::nullopt) const
Definition model.cc:69
std::vector< Variable > SortedVariables() const
Definition model.cc:97
Model(absl::string_view name="")
Creates an empty minimization problem.
Definition model.cc:63
Objective primary_objective() const
Definition model.h:1457
LinearExpression ObjectiveAsLinearExpression() const
Definition model.cc:210
int64_t num_quadratic_constraints() const
Definition model.h:1194
void SetObjective(double objective, bool is_maximize)
Sets the objective to optimize the provided expression.
Definition model.h:1437
IndicatorConstraint AddIndicatorConstraint(Variable indicator_variable, const BoundedLinearExpression &implied_constraint, bool activate_on_zero=false, absl::string_view name={})
------------------------— Indicator constraints ------------------------—
Definition model.cc:502
LinearConstraint AddLinearConstraint(absl::string_view name="")
Adds a linear constraint to the model with bounds [-inf, +inf].
Definition model.h:1076
std::vector< Variable > RowNonzeros(LinearConstraint constraint) const
Definition model.cc:117
double coefficient(Variable variable) const
Returns the linear coefficient for the variable in the model.
Definition objective.h:166
double offset() const
Returns the constant offset of the objective.
Definition objective.h:156
const QuadraticTermMap< double > & quadratic_terms() const
bool set(VariableId id, double coeff)
Returns true if the stored value changes.
bool set(VariableId first, VariableId second, double value)
An object oriented wrapper for quadratic constraints in ModelStorage.
Definition gurobi_isv.cc:28
ElementId< ElementType::kAuxiliaryObjective > AuxiliaryObjectiveId
Definition elements.h:266
ElementId< ElementType::kVariable > VariableId
Definition elements.h:264
constexpr ObjectiveId kPrimaryObjectiveId
ElementId< ElementType::kQuadraticConstraint > QuadraticConstraintId
Definition elements.h:267
std::ostream & operator<<(std::ostream &ostr, const SecondOrderConeConstraint &constraint)
ElementId< ElementType::kLinearConstraint > LinearConstraintId
Definition elements.h:265
LinearExpressionData FromLinearExpression(const LinearExpression &expression)
Converts a LinearExpression to the associated "raw ID" format.
Definition model_util.cc:34
ElementId< ElementType::kIndicatorConstraint > IndicatorConstraintId
Definition elements.h:268
In SWIG mode, we don't want anything besides these top-level includes.
STL namespace.
A LinearExpression with upper and lower bounds.
A QuadraticExpression with upper and lower bounds.