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