OR-Tools  9.3
math_opt/cpp/model.h
Go to the documentation of this file.
1// Copyright 2010-2021 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_CPP_MODEL_H_
15#define OR_TOOLS_MATH_OPT_CPP_MODEL_H_
16
17#include <memory>
18#include <string>
19#include <vector>
20
21#include "absl/status/status.h"
22#include "absl/status/statusor.h"
23#include "absl/strings/string_view.h"
27#include "ortools/math_opt/cpp/linear_constraint.h" // IWYU pragma: export
28#include "ortools/math_opt/cpp/update_tracker.h" // IWYU pragma: export
29#include "ortools/math_opt/cpp/variable_and_expressions.h" // IWYU pragma: export
30#include "ortools/math_opt/model.pb.h" // IWYU pragma: export
31#include "ortools/math_opt/model_update.pb.h" // IWYU pragma: export
32
33namespace operations_research {
34namespace math_opt {
35
36// A C++ API for building optimization problems.
37//
38// Warning: Variable and LinearConstraint are value types, see "Memory Model"
39// below.
40//
41// A simple example:
42//
43// Model the problem:
44// max 2.0 * x + y
45// s.t. x + y <= 1.5
46// x in {0.0, 1.0}
47// y in [0.0, 2.5]
48//
49// math_opt::Model model("my_model");
50// const math_opt::Variable x = model.AddBinaryVariable("x");
51// const math_opt::Variable y = model.AddContinuousVariable(0.0, 2.5, "y");
52// // We can directly use linear combinations of variables ...
53// model.AddLinearConstraint(x + y <= 1.5, "c");
54// // ... or build them incrementally.
55// math_opt::LinearExpression objective_expression;
56// objective_expression += 2 * x;
57// objective_expression += y;
58// model.Maximize(objective_expression);
59// ASSIGN_OR_RETURN(const math_opt::SolveResult result,
60// Solve(model, math_opt::SolverType::kGscip));
61// switch (result.termination.reason) {
62// case math_opt::TerminationReason::kOptimal:
63// case math_opt::TerminationReason::kFeasible:
64// std::cout << "objective value: " << result.objective_value() << std::endl
65// << "value for variable x: " << result.variable_values().at(x)
66// << std::endl;
67// return absl::OkStatus();
68// default:
69// return util::InternalErrorBuilder()
70// << "model failed to solve: " << result.termination;
71// }
72//
73// Memory model:
74//
75// Variable and LinearConstraint are value types that represent references to
76// the underlying Model object. They don't hold any of the actual model data,
77// they can be copied, and they should be passed by value. They can be
78// regenerated arbitrarily from Model. Model holds all the data.
79//
80// Performance:
81//
82// This class is a thin wrapper around ModelStorage (for incrementally building
83// the model and reading it back, and producing the Model proto) and Solver (for
84// consuming the Model proto to solve the optimization problem). Operations for
85// building/reading/modifying the problem typically run in O(read/write size)
86// and rely on hashing, see the indexed model documentation for details. At
87// solve time (if you are solving locally) beware that there will be (at least)
88// three copies of the model in memory, ModelStorage, the Model proto, and the
89// underlying solver's copy(/ies). Note that the Model proto is reclaimed before
90// the underlying solver begins solving.
91class Model {
92 public:
93 // Returns a model from the input proto. Returns a failure status if the input
94 // proto is invalid.
95 //
96 // On top of loading a model from a MathOpt ModelProto, this function can also
97 // be used to load a model from other formats using the functions in
98 // math_opt/io/ like ReadMpsFile().
99 //
100 // See ExportModel() to get the proto of a Model. See ApplyUpdateProto() to
101 // apply an update to the model.
102 //
103 // Usage example reading an MPS file:
104 // ASSIGN_OR_RETURN(const ModelProto model_proto, ReadMpsFile(path));
105 // ASSIGN_OR_RETURN(const std::unique_ptr<Model> model,
106 // Model::FromModelProto(model_proto));
107 static absl::StatusOr<std::unique_ptr<Model>> FromModelProto(
108 const ModelProto& model_proto);
109
110 // Creates an empty minimization problem.
111 explicit Model(absl::string_view name = "");
112
113 // Creates a model from the existing model storage.
114 //
115 // This constructor is used when loading a model, for example from a
116 // ModelProto or an MPS file. Note that in those cases the FromModelProto()
117 // should be used.
118 explicit Model(std::unique_ptr<ModelStorage> storage);
119
120 Model(const Model&) = delete;
121 Model& operator=(const Model&) = delete;
122
123 // Returns a clone of this model.
124 //
125 // The variables and constraints have the same integer ids. The clone will
126 // also not reused any id of variable/constraint that was deleted in the
127 // original.
128 //
129 // That said, the Variable and LinearConstraint reference objects are model
130 // specific. Hence the ones linked to the original model must NOT be used with
131 // the clone. The Variable and LinearConstraint reference objects for the
132 // clone can be obtained using:
133 // * the variable() and linear_constraint() methods on the ids from the old
134 // Variable and LinearConstraint objects.
135 // * in increasing id order using SortedVariables() and
136 // SortedLinearConstraints()
137 // * in an arbitrary order using Variables() and LinearConstraints().
138 //
139 // Note that the returned model does not have any update tracker.
140 std::unique_ptr<Model> Clone() const;
141
142 inline const std::string& name() const;
143
144 // Adds a variable to the model and returns a reference to it.
145 inline Variable AddVariable(double lower_bound, double upper_bound,
146 bool is_integer, absl::string_view name = "");
147
148 // Adds a continuous unbounded variable to the model.
149 inline Variable AddVariable(absl::string_view name = "");
150
151 // Adds an variable to the model with domain {0, 1}.
152 inline Variable AddBinaryVariable(absl::string_view name = "");
153
154 // Adds a variable to the model with domain [lower_bound, upper_bound].
156 absl::string_view name = "");
157
158 // Adds a variable to the model that can take integer values between
159 // lower_bound and upper_bound (inclusive).
161 absl::string_view name = "");
162
163 // Removes a variable from the model.
164 //
165 // It is an error to use any reference to this variable after this operation.
166 // Runs in O(#constraints containing the variable).
167 inline void DeleteVariable(Variable variable);
168
169 // The number of variables in the model.
170 //
171 // Equal to the number of variables created minus the number of variables
172 // deleted.
173 inline int num_variables() const;
174
175 // The returned id of the next call to AddVariable.
176 //
177 // Equal to the number of variables created.
178 inline int64_t next_variable_id() const;
179
180 // Returns true if this id has been created and not yet deleted.
181 inline bool has_variable(int64_t id) const;
182
183 // Returns true if this id has been created and not yet deleted.
184 inline bool has_variable(VariableId id) const;
185
186 // Will CHECK if has_variable(id) is false.
187 inline Variable variable(int64_t id) const;
188
189 // Will CHECK if has_variable(id) is false.
190 inline Variable variable(VariableId id) const;
191
192 // Returns the variable name.
193 inline const std::string& name(Variable variable) const;
194
195 // Sets a variable lower bound.
196 inline void set_lower_bound(Variable variable, double lower_bound);
197
198 // Returns a variable lower bound.
199 inline double lower_bound(Variable variable) const;
200
201 // Sets a variable upper bound.
202 inline void set_upper_bound(Variable variable, double upper_bound);
203
204 // Returns a variable upper bound.
205 inline double upper_bound(Variable variable) const;
206
207 // Sets the integrality of a variable.
208 inline void set_is_integer(Variable variable, bool is_integer);
209
210 // Makes the input variable integer.
211 inline void set_integer(Variable variable);
212
213 // Makes the input variable continuous.
214 inline void set_continuous(Variable variable);
215
216 // Returns the integrality of a variable.
217 inline bool is_integer(Variable variable) const;
218
219 // Returns all the existing (created and not deleted) variables in the model
220 // in an arbitrary order.
221 std::vector<Variable> Variables() const;
222
223 // Returns all the existing (created and not deleted) variables in the model,
224 // sorted by id.
225 std::vector<Variable> SortedVariables() const;
226
227 std::vector<LinearConstraint> ColumnNonzeros(Variable variable);
228
229 // Adds a linear constraint to the model with bounds [-inf, +inf].
230 inline LinearConstraint AddLinearConstraint(absl::string_view name = "");
231
232 // Adds a linear constraint with bounds [lower_bound, upper_bound].
234 double upper_bound,
235 absl::string_view name = "");
236
237 // Adds a linear constraint from the given bounded linear expression.
238 //
239 // Usage:
240 // Model model = ...;
241 // const Variable x = ...;
242 // const Variable y = ...;
243 // model.AddLinearConstraint(3 <= 2 * x + y + 1 <= 5, "c");
244 // // The new constraint formula is:
245 // // 3 - 1 <= 2 * x + y <= 5 - 1
246 // // Which is:
247 // // 2 <= 2 * x + y <= 4
248 // // since the offset has been removed from bounds.
249 //
250 // model.AddLinearConstraint(2 * x + y == x + 5 * z + 3);
251 // model.AddLinearConstraint(x >= 5);
253 const BoundedLinearExpression& bounded_expr, absl::string_view name = "");
254
255 // Removes a linear constraint from the model.
256 //
257 // It is an error to use any reference to this linear constraint after this
258 // operation. Runs in O(#variables in the linear constraint).
259 inline void DeleteLinearConstraint(LinearConstraint constraint);
260
261 // The number of linear constraints in the model.
262 //
263 // Equal to the number of linear constraints created minus the number of
264 // linear constraints deleted.
265 inline int num_linear_constraints() const;
266
267 // The returned id of the next call to AddLinearConstraint.
268 //
269 // Equal to the number of linear constraints created.
270 inline int64_t next_linear_constraint_id() const;
271
272 // Returns true if this id has been created and not yet deleted.
273 inline bool has_linear_constraint(int64_t id) const;
274
275 // Returns true if this id has been created and not yet deleted.
276 inline bool has_linear_constraint(LinearConstraintId id) const;
277
278 // Will CHECK if has_linear_constraint(id) is false.
279 inline LinearConstraint linear_constraint(int64_t id) const;
280
281 // Will CHECK if has_linear_constraint(id) is false.
282 inline LinearConstraint linear_constraint(LinearConstraintId id) const;
283
284 // Returns the linear constraint name.
285 inline const std::string& name(LinearConstraint constraint) const;
286
287 // Sets a linear constraint lower bound.
288 inline void set_lower_bound(LinearConstraint constraint, double lower_bound);
289
290 // Returns a linear constraint lower bound.
291 inline double lower_bound(LinearConstraint constraint) const;
292
293 // Sets a linear constraint upper bound.
294 inline void set_upper_bound(LinearConstraint constraint, double upper_bound);
295
296 // Returns a linear constraint upper bound.
297 inline double upper_bound(LinearConstraint constraint) const;
298
299 // Setting a value to 0.0 will delete the {constraint, variable} pair from the
300 // underlying sparse matrix representation (and has no effect if the pair is
301 // not present).
302 inline void set_coefficient(LinearConstraint constraint, Variable variable,
303 double value);
304
305 // Returns 0.0 if the variable is not used in the constraint.
306 inline double coefficient(LinearConstraint constraint,
307 Variable variable) const;
308
309 inline bool is_coefficient_nonzero(LinearConstraint constraint,
310 Variable variable) const;
311
312 // This method modifies some internal structures of the model and thus is not
313 // const.
314 std::vector<Variable> RowNonzeros(LinearConstraint constraint);
315
316 // This method modifies some internal structures of the model and thus is not
317 // const.
319 LinearConstraint constraint);
320
321 // Returns all the existing (created and not deleted) linear constraints in
322 // the model in an arbitrary order.
323 std::vector<LinearConstraint> LinearConstraints() const;
324
325 // Returns all the existing (created and not deleted) linear constraints in
326 // the model sorted by id.
327 std::vector<LinearConstraint> SortedLinearConstraints() const;
328
329 // Sets the objective to maximize the provided expression.
330 inline void Maximize(double objective);
331 // Sets the objective to maximize the provided expression.
332 inline void Maximize(Variable objective);
333 // Sets the objective to maximize the provided expression.
334 inline void Maximize(LinearTerm objective);
335 // Sets the objective to maximize the provided expression.
336 inline void Maximize(const LinearExpression& objective);
337 // Sets the objective to maximize the provided expression.
338 inline void Maximize(const QuadraticExpression& objective);
339
340 // Sets the objective to minimize the provided expression.
341 inline void Minimize(double objective);
342 // Sets the objective to minimize the provided expression.
343 inline void Minimize(Variable objective);
344 // Sets the objective to minimize the provided expression.
345 inline void Minimize(LinearTerm objective);
346 // Sets the objective to minimize the provided expression.
347 inline void Minimize(const LinearExpression& objective);
348 // Sets the objective to minimize the provided expression.
349 inline void Minimize(const QuadraticExpression& objective);
350
351 // Sets the objective to optimize the provided expression.
352 inline void SetObjective(double objective, bool is_maximize);
353 // Sets the objective to optimize the provided expression.
354 inline void SetObjective(Variable objective, bool is_maximize);
355 // Sets the objective to optimize the provided expression.
356 inline void SetObjective(LinearTerm objective, bool is_maximize);
357 // Sets the objective to optimize the provided expression.
358 void SetObjective(const LinearExpression& objective, bool is_maximize);
359 // Sets the objective to optimize the provided expression.
360 void SetObjective(const QuadraticExpression& objective, bool is_maximize);
361
362 // Adds the provided expression terms to the objective.
363 inline void AddToObjective(double objective);
364 // Adds the provided expression terms to the objective.
365 inline void AddToObjective(Variable objective);
366 // Adds the provided expression terms to the objective.
367 inline void AddToObjective(LinearTerm objective);
368 // Adds the provided expression terms to the objective.
369 void AddToObjective(const LinearExpression& objective);
370 // Adds the provided expression terms to the objective.
371 void AddToObjective(const QuadraticExpression& objective);
372
373 // NOTE: This will CHECK fail if the objective has quadratic terms.
376
377 // Returns 0.0 if this variable has no linear objective coefficient.
378 inline double objective_coefficient(Variable variable) const;
379
380 // Returns 0.0 if this variable pair has no quadratic objective coefficient.
381 // The order of the variables does not matter.
382 inline double objective_coefficient(Variable first_variable,
383 Variable second_variable) const;
384
385 // Setting a value to 0.0 will delete the variable from the underlying sparse
386 // representation (and has no effect if the variable is not present).
388
389 // Set quadratic objective terms for the product of two variables. Setting a
390 // value to 0.0 will delete the variable pair from the underlying sparse
391 // representation (and has no effect if the pair is not present). The order of
392 // the variables does not matter.
393 inline void set_objective_coefficient(Variable first_variable,
394 Variable second_variable, double value);
395
396 // Equivalent to calling set_linear_coefficient(v, 0.0) for every variable
397 // with nonzero objective coefficient.
398 //
399 // Runs in O(#linear and quadratic objective terms with nonzero coefficient).
400 inline void clear_objective();
401
403 inline bool is_objective_coefficient_nonzero(Variable first_variable,
404 Variable second_variable) const;
405
406 inline double objective_offset() const;
407
408 inline void set_objective_offset(double value);
409
410 inline bool is_maximize() const;
411
412 inline void set_maximize();
413 inline void set_minimize();
414
415 // Prefer set_maximize() and set_minimize() above for more readable code.
416 inline void set_is_maximize(bool is_maximize);
417
418 // Returns a proto representation of the optimization model.
419 //
420 // See FromModelProto() to build a Model from a proto.
421 ModelProto ExportModel() const;
422
423 // Returns a tracker that can be used to generate a ModelUpdateProto with the
424 // updates that happened since the last checkpoint. The tracker initial
425 // checkpoint corresponds to the current state of the model.
426 //
427 // The returned UpdateTracker keeps a reference to this model. See the
428 // implications in the documentation of the UpdateTracker class.
429 //
430 // Thread-safety: this method must not be used while modifying the model
431 // (variables, constraints, ...). The user is expected to use proper
432 // synchronization primitive to serialize changes to the model and the use of
433 // this method.
434 std::unique_ptr<UpdateTracker> NewUpdateTracker();
435
436 // Apply the provided update to this model. Returns a failure if the update is
437 // not valid.
438 //
439 // As with FromModelProto(), duplicated names are ignored.
440 //
441 // Note that it takes O(num_variables + num_constraints) extra memory and
442 // execution to apply the update (due to the need to build a ModelSummary). So
443 // even a small update will have some cost.
444 absl::Status ApplyUpdateProto(const ModelUpdateProto& update_proto);
445
446 // TODO(user): expose a way to efficiently iterate through the nonzeros of
447 // the linear constraint matrix.
448
449 // Returns a pointer to the underlying model storage.
450 //
451 // This API is for internal use only and regular users should have no need for
452 // it.
453 const ModelStorage* storage() const { return storage_.get(); }
454
455 // Returns a pointer to the underlying model storage.
456 //
457 // This API is for internal use only and regular users should have no need for
458 // it.
459 ModelStorage* storage() { return storage_.get(); }
460
461 private:
462 // Asserts (with CHECK) that the input pointer is either nullptr or that it
463 // points to the same model as storage_.
464 //
465 // Use CheckModel() when nullptr is not a valid value.
466 inline void CheckOptionalModel(const ModelStorage* other_storage) const;
467
468 // Asserts (with CHECK) that the input pointer is the same as storage_.
469 //
470 // Use CheckOptionalModel() if nullptr is a valid value too.
471 inline void CheckModel(const ModelStorage* other_storage) const;
472
473 // Don't use storage_ directly; prefer to use storage() so that const member
474 // functions don't have modifying access to the underlying storage.
475 //
476 // We use a shared_ptr here so that the UpdateTracker class can have a
477 // weak_ptr on the ModelStorage. This let it have a destructor that don't
478 // crash when called after the destruction of the associated Model.
479 const std::shared_ptr<ModelStorage> storage_;
480};
481
483// Inline function implementations
485
486const std::string& Model::name() const { return storage()->name(); }
487
488Variable Model::AddVariable(const absl::string_view name) {
489 return Variable(storage(), storage()->AddVariable(name));
490}
492 const bool is_integer,
493 const absl::string_view name) {
495 is_integer, name));
496}
497
498Variable Model::AddBinaryVariable(const absl::string_view name) {
499 return AddVariable(0.0, 1.0, true, name);
500}
501
503 const double upper_bound,
504 const absl::string_view name) {
505 return AddVariable(lower_bound, upper_bound, false, name);
506}
507
509 const double upper_bound,
510 const absl::string_view name) {
511 return AddVariable(lower_bound, upper_bound, true, name);
512}
513
514void Model::DeleteVariable(const Variable variable) {
515 CheckModel(variable.storage());
517}
518
519int Model::num_variables() const { return storage()->num_variables(); }
520
521int64_t Model::next_variable_id() const {
522 return storage()->next_variable_id().value();
523}
524
525bool Model::has_variable(const int64_t id) const {
526 return has_variable(VariableId(id));
527}
528
529bool Model::has_variable(const VariableId id) const {
530 return storage()->has_variable(id);
531}
532
533Variable Model::variable(const int64_t id) const {
534 return variable(VariableId(id));
535}
536
537Variable Model::variable(const VariableId id) const {
538 CHECK(has_variable(id)) << "No variable with id: " << id.value();
539 return Variable(storage(), id);
540}
541
542const std::string& Model::name(const Variable variable) const {
543 CheckModel(variable.storage());
545}
546
547void Model::set_lower_bound(const Variable variable, double lower_bound) {
548 CheckModel(variable.storage());
550}
551
552double Model::lower_bound(const Variable variable) const {
553 CheckModel(variable.storage());
555}
556
557void Model::set_upper_bound(const Variable variable, double upper_bound) {
558 CheckModel(variable.storage());
560}
561
562double Model::upper_bound(const Variable variable) const {
563 CheckModel(variable.storage());
565}
566
567void Model::set_is_integer(const Variable variable, bool is_integer) {
568 CheckModel(variable.storage());
570}
571
572void Model::set_integer(const Variable variable) {
574}
575
576void Model::set_continuous(const Variable variable) {
577 set_is_integer(variable, false);
578}
579
580bool Model::is_integer(const Variable variable) const {
581 CheckModel(variable.storage());
583}
584
587}
589 const double upper_bound,
590 const absl::string_view name) {
593}
594
596 CheckModel(constraint.storage());
597 storage()->DeleteLinearConstraint(constraint.typed_id());
598}
599
602}
603
605 return storage()->next_linear_constraint_id().value();
606}
607
608bool Model::has_linear_constraint(const int64_t id) const {
609 return has_linear_constraint(LinearConstraintId(id));
610}
611
612bool Model::has_linear_constraint(const LinearConstraintId id) const {
613 return storage()->has_linear_constraint(id);
614}
615
617 return linear_constraint(LinearConstraintId(id));
618}
619
620LinearConstraint Model::linear_constraint(const LinearConstraintId id) const {
622 << "No linear constraint with id: " << id.value();
623 return LinearConstraint(storage(), id);
624}
625
626const std::string& Model::name(const LinearConstraint constraint) const {
627 CheckModel(constraint.storage());
628 return storage()->linear_constraint_name(constraint.typed_id());
629}
630
632 double lower_bound) {
633 CheckModel(constraint.storage());
636}
637
638double Model::lower_bound(const LinearConstraint constraint) const {
639 CheckModel(constraint.storage());
640 return storage()->linear_constraint_lower_bound(constraint.typed_id());
641}
642
644 const double upper_bound) {
645 CheckModel(constraint.storage());
648}
649
650double Model::upper_bound(const LinearConstraint constraint) const {
651 CheckModel(constraint.storage());
652 return storage()->linear_constraint_upper_bound(constraint.typed_id());
653}
654
656 const Variable variable, const double value) {
657 CheckModel(constraint.storage());
658 CheckModel(variable.storage());
661}
662
663double Model::coefficient(const LinearConstraint constraint,
664 const Variable variable) const {
665 CheckModel(constraint.storage());
666 CheckModel(variable.storage());
667 return storage()->linear_constraint_coefficient(constraint.typed_id(),
669}
670
672 const Variable variable) const {
673 CheckModel(constraint.storage());
674 CheckModel(variable.storage());
676 constraint.typed_id(), variable.typed_id());
677}
678
679void Model::Maximize(const double objective) {
680 SetObjective(LinearExpression(objective), /*is_maximize=*/true);
681}
682void Model::Maximize(const Variable objective) {
683 SetObjective(LinearExpression(objective), /*is_maximize=*/true);
684}
685void Model::Maximize(const LinearTerm objective) {
686 SetObjective(LinearExpression(objective), /*is_maximize=*/true);
687}
688void Model::Maximize(const LinearExpression& objective) {
689 SetObjective(objective, /*is_maximize=*/true);
690}
691void Model::Maximize(const QuadraticExpression& objective) {
692 SetObjective(objective, /*is_maximize=*/true);
693}
694
695void Model::Minimize(const double objective) {
696 SetObjective(LinearExpression(objective), /*is_maximize=*/false);
697}
698void Model::Minimize(const Variable objective) {
699 SetObjective(LinearExpression(objective), /*is_maximize=*/false);
700}
701void Model::Minimize(const LinearTerm objective) {
702 SetObjective(LinearExpression(objective), /*is_maximize=*/false);
703}
704void Model::Minimize(const LinearExpression& objective) {
705 SetObjective(objective, /*is_maximize=*/false);
706}
707void Model::Minimize(const QuadraticExpression& objective) {
708 SetObjective(objective, /*is_maximize=*/false);
709}
710
711void Model::SetObjective(const double objective, const bool is_maximize) {
712 SetObjective(LinearExpression(objective), /*is_maximize=*/is_maximize);
713}
714void Model::SetObjective(const Variable objective, const bool is_maximize) {
715 SetObjective(LinearExpression(objective), /*is_maximize=*/is_maximize);
716}
717void Model::SetObjective(const LinearTerm objective, const bool is_maximize) {
718 SetObjective(LinearExpression(objective), /*is_maximize=*/is_maximize);
719}
720
721void Model::AddToObjective(const double objective) {
723}
724void Model::AddToObjective(const Variable objective) {
726}
727void Model::AddToObjective(const LinearTerm objective) {
729}
730
731double Model::objective_coefficient(const Variable variable) const {
732 CheckModel(variable.storage());
734}
735
736double Model::objective_coefficient(const Variable first_variable,
737 const Variable second_variable) const {
738 CheckModel(first_variable.storage());
739 CheckModel(second_variable.storage());
740 return storage()->quadratic_objective_coefficient(first_variable.typed_id(),
741 second_variable.typed_id());
742}
743
745 const double value) {
746 CheckModel(variable.storage());
748}
749
751 const Variable second_variable,
752 const double value) {
753 CheckModel(first_variable.storage());
754 CheckModel(second_variable.storage());
756 first_variable.typed_id(), second_variable.typed_id(), value);
757}
758
760
762 CheckModel(variable.storage());
765}
766
768 const Variable first_variable, const Variable second_variable) const {
769 CheckModel(first_variable.storage());
770 CheckModel(second_variable.storage());
772 first_variable.typed_id(), second_variable.typed_id());
773}
774
775double Model::objective_offset() const { return storage()->objective_offset(); }
776
779}
780
781bool Model::is_maximize() const { return storage()->is_maximize(); }
782
784
786
787void Model::set_is_maximize(const bool is_maximize) {
789}
790
791void Model::CheckOptionalModel(const ModelStorage* const other_storage) const {
792 if (other_storage != nullptr) {
793 CHECK_EQ(other_storage, storage())
795 }
796}
797
798void Model::CheckModel(const ModelStorage* const other_storage) const {
800}
801
802} // namespace math_opt
803} // namespace operations_research
804
805#endif // OR_TOOLS_MATH_OPT_CPP_MODEL_H_
#define CHECK(condition)
Definition: base/logging.h:495
#define CHECK_EQ(val1, val2)
Definition: base/logging.h:703
static absl::StatusOr< std::unique_ptr< Model > > FromModelProto(const ModelProto &model_proto)
Variable AddBinaryVariable(absl::string_view name="")
double objective_coefficient(Variable variable) const
LinearConstraint linear_constraint(int64_t id) const
std::vector< Variable > RowNonzeros(LinearConstraint constraint)
const std::string & name() const
double coefficient(LinearConstraint constraint, Variable variable) const
Model & operator=(const Model &)=delete
double lower_bound(Variable variable) const
BoundedLinearExpression AsBoundedLinearExpression(LinearConstraint constraint)
void SetObjective(double objective, bool is_maximize)
std::unique_ptr< UpdateTracker > NewUpdateTracker()
LinearExpression ObjectiveAsLinearExpression() const
Variable variable(int64_t id) const
Variable AddIntegerVariable(double lower_bound, double upper_bound, absl::string_view name="")
LinearConstraint AddLinearConstraint(absl::string_view name="")
absl::Status ApplyUpdateProto(const ModelUpdateProto &update_proto)
void set_coefficient(LinearConstraint constraint, Variable variable, double value)
bool has_linear_constraint(int64_t id) const
bool is_objective_coefficient_nonzero(Variable variable) const
double upper_bound(Variable variable) const
bool is_coefficient_nonzero(LinearConstraint constraint, Variable variable) const
void set_is_integer(Variable variable, bool is_integer)
std::unique_ptr< Model > Clone() const
QuadraticExpression ObjectiveAsQuadraticExpression() const
void DeleteLinearConstraint(LinearConstraint constraint)
std::vector< Variable > Variables() const
std::vector< LinearConstraint > ColumnNonzeros(Variable variable)
void set_upper_bound(Variable variable, double upper_bound)
bool is_integer(Variable variable) const
Variable AddContinuousVariable(double lower_bound, double upper_bound, absl::string_view name="")
void set_lower_bound(Variable variable, double lower_bound)
std::vector< LinearConstraint > LinearConstraints() const
std::vector< LinearConstraint > SortedLinearConstraints() const
void set_objective_coefficient(Variable variable, double value)
std::vector< Variable > SortedVariables() const
const ModelStorage * storage() const
Variable AddVariable(double lower_bound, double upper_bound, bool is_integer, absl::string_view name="")
LinearConstraintId next_linear_constraint_id() const
void set_quadratic_objective_coefficient(VariableId first_variable, VariableId second_variable, double value)
double linear_objective_coefficient(VariableId variable) const
double linear_constraint_coefficient(LinearConstraintId constraint, VariableId variable) const
void DeleteLinearConstraint(LinearConstraintId id)
void set_linear_objective_coefficient(VariableId variable, double value)
double linear_constraint_lower_bound(LinearConstraintId id) const
bool is_quadratic_objective_coefficient_nonzero(VariableId first_variable, VariableId second_variable) const
void set_linear_constraint_coefficient(LinearConstraintId constraint, VariableId variable, double value)
void set_variable_upper_bound(VariableId id, double upper_bound)
void set_variable_is_integer(VariableId id, bool is_integer)
bool has_linear_constraint(LinearConstraintId id) const
const std::string & variable_name(VariableId id) const
void set_linear_constraint_upper_bound(LinearConstraintId id, double upper_bound)
double quadratic_objective_coefficient(VariableId first_variable, VariableId second_variable) const
void set_linear_constraint_lower_bound(LinearConstraintId id, double lower_bound)
double linear_constraint_upper_bound(LinearConstraintId id) const
double variable_lower_bound(VariableId id) const
bool is_linear_constraint_coefficient_nonzero(LinearConstraintId constraint, VariableId variable) const
bool is_variable_integer(VariableId id) const
const std::string & linear_constraint_name(LinearConstraintId id) const
bool is_linear_objective_coefficient_nonzero(VariableId variable) const
double variable_upper_bound(VariableId id) const
void set_variable_lower_bound(VariableId id, double lower_bound)
CpModelProto const * model_proto
const std::string name
int64_t value
double upper_bound
double lower_bound
constexpr absl::string_view kObjectsFromOtherModelStorage
Definition: key_types.h:56
Collection of objects used to extend the Constraint Solver library.