OR-Tools  9.6
math_opt/cpp/model.h
Go to the documentation of this file.
1 // Copyright 2010-2022 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 // IWYU pragma: private, include "ortools/math_opt/cpp/math_opt.h"
15 // IWYU pragma: friend "ortools/math_opt/cpp/.*"
16 
17 #ifndef OR_TOOLS_MATH_OPT_CPP_MODEL_H_
18 #define OR_TOOLS_MATH_OPT_CPP_MODEL_H_
19 
20 #include <cstdint>
21 #include <memory>
22 #include <optional>
23 #include <ostream>
24 #include <string>
25 #include <vector>
26 
27 #include "absl/status/status.h"
28 #include "absl/status/statusor.h"
29 #include "absl/strings/string_view.h"
30 #include "absl/log/check.h"
35 #include "ortools/math_opt/constraints/sos/sos1_constraint.h" // IWYU pragma: export
36 #include "ortools/math_opt/constraints/sos/sos2_constraint.h" // IWYU pragma: export
39 #include "ortools/math_opt/cpp/linear_constraint.h" // IWYU pragma: export
40 #include "ortools/math_opt/cpp/update_tracker.h" // IWYU pragma: export
41 #include "ortools/math_opt/cpp/variable_and_expressions.h" // IWYU pragma: export
42 #include "ortools/math_opt/model.pb.h" // IWYU pragma: export
43 #include "ortools/math_opt/model_update.pb.h" // IWYU pragma: export
45 #include "ortools/math_opt/storage/model_storage_types.h" // IWYU pragma: export
46 
47 namespace operations_research {
48 namespace math_opt {
49 
50 // A C++ API for building optimization problems.
51 //
52 // Warning: Variable and LinearConstraint (along with all other constraint
53 // objects) are value types, see "Memory Model" below.
54 //
55 // A simple example:
56 //
57 // Model the problem:
58 // max 2.0 * x + y
59 // s.t. x + y <= 1.5
60 // x in {0.0, 1.0}
61 // y in [0.0, 2.5]
62 //
63 // math_opt::Model model("my_model");
64 // const math_opt::Variable x = model.AddBinaryVariable("x");
65 // const math_opt::Variable y = model.AddContinuousVariable(0.0, 2.5, "y");
66 // // We can directly use linear combinations of variables ...
67 // model.AddLinearConstraint(x + y <= 1.5, "c");
68 // // ... or build them incrementally.
69 // math_opt::LinearExpression objective_expression;
70 // objective_expression += 2 * x;
71 // objective_expression += y;
72 // model.Maximize(objective_expression);
73 // ASSIGN_OR_RETURN(const math_opt::SolveResult result,
74 // Solve(model, math_opt::SolverType::kGscip));
75 // switch (result.termination.reason) {
76 // case math_opt::TerminationReason::kOptimal:
77 // case math_opt::TerminationReason::kFeasible:
78 // std::cout << "objective value: " << result.objective_value() << std::endl
79 // << "value for variable x: " << result.variable_values().at(x)
80 // << std::endl;
81 // return absl::OkStatus();
82 // default:
83 // return util::InternalErrorBuilder()
84 // << "model failed to solve: " << result.termination;
85 // }
86 //
87 // Memory model:
88 //
89 // Variable, LinearConstraint, QuadraticConstraint, etc. are value types that
90 // represent references to the underlying Model object. They don't hold any of
91 // the actual model data, they can be copied, and they should be passed by
92 // value. They can be regenerated arbitrarily from Model. Model holds all the
93 // data.
94 //
95 // As a consequence of Variable and LinearConstraint holding back pointers,
96 // Model is not copyable or movable. Users needing to copy a Model can call
97 // Model::Clone() (this will create a new Model with no update trackers), and
98 // users needing to move a Model should wrap it in a std::unique_ptr.
99 //
100 // Performance:
101 //
102 // This class is a thin wrapper around ModelStorage (for incrementally building
103 // the model and reading it back, and producing the Model proto). Operations for
104 // building/reading/modifying the problem typically run in O(read/write size)
105 // and rely on hashing, see the ModelStorage documentation for details. At
106 // solve time (if you are solving locally) beware that there will be (at least)
107 // three copies of the model in memory, ModelStorage, the Model proto, and the
108 // underlying solver's copy(/ies). Note that the Model proto is reclaimed before
109 // the underlying solver begins solving.
110 class Model {
111  public:
112  // Returns a model from the input proto. Returns a failure status if the input
113  // proto is invalid.
114  //
115  // On top of loading a model from a MathOpt ModelProto, this function can also
116  // be used to load a model from other formats using the functions in
117  // math_opt/io/ like ReadMpsFile().
118  //
119  // See ExportModel() to get the proto of a Model. See ApplyUpdateProto() to
120  // apply an update to the model.
121  //
122  // Usage example reading an MPS file:
123  // ASSIGN_OR_RETURN(const ModelProto model_proto, ReadMpsFile(path));
124  // ASSIGN_OR_RETURN(const std::unique_ptr<Model> model,
125  // Model::FromModelProto(model_proto));
126  static absl::StatusOr<std::unique_ptr<Model>> FromModelProto(
127  const ModelProto& model_proto);
128 
129  // Creates an empty minimization problem.
130  explicit Model(absl::string_view name = "");
131 
132  // Creates a model from the existing model storage.
133  //
134  // This constructor is used when loading a model, for example from a
135  // ModelProto or an MPS file. Note that in those cases the FromModelProto()
136  // should be used.
137  explicit Model(std::unique_ptr<ModelStorage> storage);
138 
139  Model(const Model&) = delete;
140  Model& operator=(const Model&) = delete;
141 
142  // Returns a clone of this model, optionally changing the model's name.
143  //
144  // The variables and constraints have the same integer ids. The clone will
145  // also not reused any id of variable/constraint that was deleted in the
146  // original.
147  //
148  // That said, the Variable and LinearConstraint reference objects are model
149  // specific. Hence the ones linked to the original model must NOT be used with
150  // the clone. The Variable and LinearConstraint reference objects for the
151  // clone can be obtained using:
152  // * the variable() and linear_constraint() methods on the ids from the old
153  // Variable and LinearConstraint objects.
154  // * in increasing id order using SortedVariables() and
155  // SortedLinearConstraints()
156  // * in an arbitrary order using Variables() and LinearConstraints().
157  //
158  // Note that the returned model does not have any update tracker.
159  std::unique_ptr<Model> Clone(
160  std::optional<absl::string_view> new_name = std::nullopt) const;
161 
162  inline const std::string& name() const;
163 
165  // Variable methods
167 
168  // Adds a variable to the model and returns a reference to it.
169  inline Variable AddVariable(double lower_bound, double upper_bound,
170  bool is_integer, absl::string_view name = "");
171 
172  // Adds a continuous unbounded variable to the model.
173  inline Variable AddVariable(absl::string_view name = "");
174 
175  // Adds an variable to the model with domain {0, 1}.
176  inline Variable AddBinaryVariable(absl::string_view name = "");
177 
178  // Adds a variable to the model with domain [lower_bound, upper_bound].
180  absl::string_view name = "");
181 
182  // Adds a variable to the model that can take integer values between
183  // lower_bound and upper_bound (inclusive).
184  inline Variable AddIntegerVariable(double lower_bound, double upper_bound,
185  absl::string_view name = "");
186 
187  // Removes a variable from the model.
188  //
189  // It is an error to use any reference to this variable after this operation.
190  // Runs in O(#constraints containing the variable).
191  inline void DeleteVariable(Variable variable);
192 
193  // The number of variables in the model.
194  //
195  // Equal to the number of variables created minus the number of variables
196  // deleted.
197  inline int num_variables() const;
198 
199  // The returned id of the next call to AddVariable.
200  //
201  // Equal to the number of variables created.
202  inline int64_t next_variable_id() const;
203 
204  // Returns true if this id has been created and not yet deleted.
205  inline bool has_variable(int64_t id) const;
206 
207  // Returns true if this id has been created and not yet deleted.
208  inline bool has_variable(VariableId id) const;
209 
210  // Will CHECK if has_variable(id) is false.
211  inline Variable variable(int64_t id) const;
212 
213  // Will CHECK if has_variable(id) is false.
214  inline Variable variable(VariableId id) const;
215 
216  // Returns the variable name.
217  inline const std::string& name(Variable variable) const;
218 
219  // Sets a variable lower bound.
220  inline void set_lower_bound(Variable variable, double lower_bound);
221 
222  // Returns a variable lower bound.
223  inline double lower_bound(Variable variable) const;
224 
225  // Sets a variable upper bound.
226  inline void set_upper_bound(Variable variable, double upper_bound);
227 
228  // Returns a variable upper bound.
229  inline double upper_bound(Variable variable) const;
230 
231  // Sets the integrality of a variable.
232  inline void set_is_integer(Variable variable, bool is_integer);
233 
234  // Makes the input variable integer.
235  inline void set_integer(Variable variable);
236 
237  // Makes the input variable continuous.
238  inline void set_continuous(Variable variable);
239 
240  // Returns the integrality of a variable.
241  inline bool is_integer(Variable variable) const;
242 
243  // Returns all the existing (created and not deleted) variables in the model
244  // in an arbitrary order.
245  std::vector<Variable> Variables() const;
246 
247  // Returns all the existing (created and not deleted) variables in the model,
248  // sorted by id.
249  std::vector<Variable> SortedVariables() const;
250 
251  // Returns an error if `variable` is from another model or the id is not in
252  // this model (typically, if it was deleted).
253  inline absl::Status ValidateExistingVariableOfThisModel(
254  Variable variable) const;
255 
256  std::vector<LinearConstraint> ColumnNonzeros(Variable variable) const;
257 
259  // LinearConstraint methods
261 
262  // Adds a linear constraint to the model with bounds [-inf, +inf].
263  inline LinearConstraint AddLinearConstraint(absl::string_view name = "");
264 
265  // Adds a linear constraint with bounds [lower_bound, upper_bound].
267  double upper_bound,
268  absl::string_view name = "");
269 
270  // Adds a linear constraint from the given bounded linear expression.
271  //
272  // Usage:
273  // Model model = ...;
274  // const Variable x = ...;
275  // const Variable y = ...;
276  // model.AddLinearConstraint(3 <= 2 * x + y + 1 <= 5, "c");
277  // // The new constraint formula is:
278  // // 3 - 1 <= 2 * x + y <= 5 - 1
279  // // Which is:
280  // // 2 <= 2 * x + y <= 4
281  // // since the offset has been removed from bounds.
282  //
283  // model.AddLinearConstraint(2 * x + y == x + 5 * z + 3);
284  // model.AddLinearConstraint(x >= 5);
286  const BoundedLinearExpression& bounded_expr, absl::string_view name = "");
287 
288  // Removes a linear constraint from the model.
289  //
290  // It is an error to use any reference to this linear constraint after this
291  // operation. Runs in O(#variables in the linear constraint).
292  inline void DeleteLinearConstraint(LinearConstraint constraint);
293 
294  // The number of linear constraints in the model.
295  //
296  // Equal to the number of linear constraints created minus the number of
297  // linear constraints deleted.
298  inline int num_linear_constraints() const;
299 
300  // The returned id of the next call to AddLinearConstraint.
301  //
302  // Equal to the number of linear constraints created.
303  inline int64_t next_linear_constraint_id() const;
304 
305  // Returns true if this id has been created and not yet deleted.
306  inline bool has_linear_constraint(int64_t id) const;
307 
308  // Returns true if this id has been created and not yet deleted.
309  inline bool has_linear_constraint(LinearConstraintId id) const;
310 
311  // Will CHECK if has_linear_constraint(id) is false.
312  inline LinearConstraint linear_constraint(int64_t id) const;
313 
314  // Will CHECK if has_linear_constraint(id) is false.
315  inline LinearConstraint linear_constraint(LinearConstraintId id) const;
316 
317  // Returns the linear constraint name.
318  inline const std::string& name(LinearConstraint constraint) const;
319 
320  // Sets a linear constraint lower bound.
321  inline void set_lower_bound(LinearConstraint constraint, double lower_bound);
322 
323  // Returns a linear constraint lower bound.
324  inline double lower_bound(LinearConstraint constraint) const;
325 
326  // Sets a linear constraint upper bound.
327  inline void set_upper_bound(LinearConstraint constraint, double upper_bound);
328 
329  // Returns a linear constraint upper bound.
330  inline double upper_bound(LinearConstraint constraint) const;
331 
332  // Setting a value to 0.0 will delete the {constraint, variable} pair from the
333  // underlying sparse matrix representation (and has no effect if the pair is
334  // not present).
335  inline void set_coefficient(LinearConstraint constraint, Variable variable,
336  double value);
337 
338  // Returns 0.0 if the variable is not used in the constraint.
339  inline double coefficient(LinearConstraint constraint,
340  Variable variable) const;
341 
342  inline bool is_coefficient_nonzero(LinearConstraint constraint,
343  Variable variable) const;
344 
345  std::vector<Variable> RowNonzeros(LinearConstraint constraint) const;
346 
347  // Returns all the existing (created and not deleted) linear constraints in
348  // the model in an arbitrary order.
349  std::vector<LinearConstraint> LinearConstraints() const;
350 
351  // Returns all the existing (created and not deleted) linear constraints in
352  // the model sorted by id.
353  std::vector<LinearConstraint> SortedLinearConstraints() const;
354 
355  // Returns an error if `linear_constraint` is from another model or the id is
356  // not in this model (typically, if it was deleted).
359 
361  // QuadraticConstraint methods
363 
364  // Adds a quadratic constraint from the given bounded quadratic expression.
365  //
366  // Usage:
367  // Model model = ...;
368  // const Variable x = ...;
369  // const Variable y = ...;
370  // model.AddQuadraticConstraint(2 * x * x + y + 1 <= 5, "q");
371  // model.AddQuadraticConstraint(2 * x * x + y * y == x + 5 * z + 3);
372  // model.AddQuadraticConstraint(x * y >= 5);
374  const BoundedQuadraticExpression& bounded_expr,
375  absl::string_view name = "");
376 
377  // Removes a quadratic constraint from the model.
378  //
379  // It is an error to use any reference to this quadratic constraint after this
380  // operation. Runs in O(#linear or quadratic terms appearing in constraint).
381  inline void DeleteQuadraticConstraint(QuadraticConstraint constraint);
382 
383  // The number of quadratic constraints in the model.
384  //
385  // Equal to the number of quadratic constraints created minus the number of
386  // quadratic constraints deleted.
387  inline int64_t num_quadratic_constraints() const;
388 
389  // The returned id of the next call to AddQuadraticConstraint.
390  inline int64_t next_quadratic_constraint_id() const;
391 
392  // Returns true if this id has been created and not yet deleted.
393  inline bool has_quadratic_constraint(int64_t id) const;
394 
395  // Returns true if this id has been created and not yet deleted.
396  inline bool has_quadratic_constraint(QuadraticConstraintId id) const;
397 
398  // Will CHECK if has_quadratic_constraint(id) is false.
399  inline QuadraticConstraint quadratic_constraint(int64_t id) const;
400 
401  // Will CHECK if has_quadratic_constraint(id) is false.
403  QuadraticConstraintId id) const;
404 
405  // Returns all the existing (created and not deleted) quadratic constraints in
406  // the model in an arbitrary order.
407  inline std::vector<QuadraticConstraint> QuadraticConstraints() const;
408 
409  // Returns all the existing (created and not deleted) quadratic constraints in
410  // the model sorted by id.
411  inline std::vector<QuadraticConstraint> SortedQuadraticConstraints() const;
412 
414  // Sos1Constraint methods
416 
417  // Adds an SOS1 constraint to the model: at most one of the `expressions` may
418  // take a nonzero value.
419  //
420  // The `weights` are an implementation detail in the solver used to order the
421  // `expressions`; see the Gurobi documentation for more detail:
422  // https://www.gurobi.com/documentation/9.5/refman/constraints.html#subsubsection:SOSConstraints
423  //
424  // These `weights` must either be empty or the same length as `expressions`.
425  // If it is empty, default weights of 1, 2, ... will be used.
426  //
427  // Usage:
428  // Model model = ...;
429  // const Variable x = ...;
430  // const Variable y = ...;
431  // model.AddSos1Constraint({x, y}, {}, "c");
432  // model.AddSos1Constraint({1 - 2 * x, y}, {3, 2});
434  const std::vector<LinearExpression>& expressions,
435  std::vector<double> weights = {}, absl::string_view name = "");
436 
437  // Removes an SOS1 constraint from the model.
438  //
439  // It is an error to use any reference to this SOS1 constraint after this
440  // operation. Runs in O(#terms in all expressions).
441  inline void DeleteSos1Constraint(Sos1Constraint constraint);
442 
443  // The number of SOS1 constraints in the model.
444  //
445  // Equal to the number of SOS1 constraints created minus the number of SOS1
446  // constraints deleted.
447  inline int64_t num_sos1_constraints() const;
448 
449  // The returned id of the next call to AddSos1Constraint.
450  inline int64_t next_sos1_constraint_id() const;
451 
452  // Returns true if this id has been created and not yet deleted.
453  inline bool has_sos1_constraint(int64_t id) const;
454 
455  // Returns true if this id has been created and not yet deleted.
456  inline bool has_sos1_constraint(Sos1ConstraintId id) const;
457 
458  // Will CHECK if has_sos1_constraint(id) is false.
459  inline Sos1Constraint sos1_constraint(int64_t id) const;
460 
461  // Will CHECK if has_sos1_constraint(id) is false.
462  inline Sos1Constraint sos1_constraint(Sos1ConstraintId id) const;
463 
464  // Returns all the existing (created and not deleted) SOS1 constraints in the
465  // model in an arbitrary order.
466  inline std::vector<Sos1Constraint> Sos1Constraints() const;
467 
468  // Returns all the existing (created and not deleted) SOS1 constraints in the
469  // model sorted by id.
470  inline std::vector<Sos1Constraint> SortedSos1Constraints() const;
471 
473  // Sos2Constraint methods
475 
476  // Adds an SOS2 constraint to the model: at most two of the `expressions` may
477  // take a nonzero value, and they must be adjacent in their ordering.
478  //
479  // The `weights` are an implementation detail in the solver used to order the
480  // `expressions`; see the Gurobi documentation for more detail:
481  // https://www.gurobi.com/documentation/9.5/refman/constraints.html#subsubsection:SOSConstraints
482  //
483  // These `weights` must either be empty or the same length as `expressions`.
484  // If it is empty, default weights of 1, 2, ... will be used.
485  //
486  // Usage:
487  // Model model = ...;
488  // const Variable x = ...;
489  // const Variable y = ...;
490  // model.AddSos2Constraint({x, y}, {}, "c");
491  // model.AddSos2Constraint({1 - 2 * x, y}, {3, 2});
493  const std::vector<LinearExpression>& expressions,
494  std::vector<double> weights = {}, absl::string_view name = "");
495 
496  // Removes an SOS2 constraint from the model.
497  //
498  // It is an error to use any reference to this SOS2 constraint after this
499  // operation. Runs in O(#terms in all expressions).
500  inline void DeleteSos2Constraint(Sos2Constraint constraint);
501 
502  // The number of SOS2 constraints in the model.
503  //
504  // Equal to the number of SOS2 constraints created minus the number of SOS2
505  // constraints deleted.
506  inline int64_t num_sos2_constraints() const;
507 
508  // The returned id of the next call to AddSos2Constraint.
509  inline int64_t next_sos2_constraint_id() const;
510 
511  // Returns true if this id has been created and not yet deleted.
512  inline bool has_sos2_constraint(int64_t id) const;
513 
514  // Returns true if this id has been created and not yet deleted.
515  inline bool has_sos2_constraint(Sos2ConstraintId id) const;
516 
517  // Will CHECK if has_sos2_constraint(id) is false.
518  inline Sos2Constraint sos2_constraint(int64_t id) const;
519 
520  // Will CHECK if has_sos2_constraint(id) is false.
521  inline Sos2Constraint sos2_constraint(Sos2ConstraintId id) const;
522 
523  // Returns all the existing (created and not deleted) SOS2 constraints in the
524  // model in an arbitrary order.
525  inline std::vector<Sos2Constraint> Sos2Constraints() const;
526 
527  // Returns all the existing (created and not deleted) SOS2 constraints in the
528  // model sorted by id.
529  inline std::vector<Sos2Constraint> SortedSos2Constraints() const;
530 
532  // IndicatorConstraint methods
534 
535  // Adds an indicator constraint to the model.
536  //
537  // Assume for the moment that `activate_on_zero == false` (the default value).
538  // * If `indicator_variable == 1`, then `implied_constraint` must hold.
539  // * If `indicator_variable == 0`, then `implied_constraint` need not hold.
540  // Alternatively, if `activate_on_zero = true`, flip the 1 and 0 above.
541  //
542  // The `indicator_variable` is expected to be a binary variable in the model.
543  // If this is not the case, the solver may elect to either implicitly add the
544  // binary constraint, or reject the model.
545  //
546  // Usage:
547  // Model model = ...;
548  // const Variable x = model.AddBinaryVariable("x");
549  // const Variable y = model.AddBinaryVariable("y");
550  // model.AddIndicatorConstraint(x, y <= 0);
551  // model.AddIndicatorConstraint(y, x >= 2, true, "c");
552  IndicatorConstraint AddIndicatorConstraint(
553  Variable indicator_variable,
554  const BoundedLinearExpression& implied_constraint,
555  bool activate_on_zero = false, absl::string_view name = {});
556 
557  // Removes an indicator constraint from the model.
558  //
559  // It is an error to use any reference to this indicator constraint after this
560  // operation. Runs in O(#terms in implied constraint).
561  inline void DeleteIndicatorConstraint(IndicatorConstraint constraint);
562 
563  // The number of indicator constraints in the model.
564  //
565  // Equal to the number of indicator constraints created minus the number of
566  // indicator constraints deleted.
567  inline int64_t num_indicator_constraints() const;
568 
569  // The returned id of the next call to AddIndicatorConstraint.
570  inline int64_t next_indicator_constraint_id() const;
571 
572  // Returns true if this id has been created and not yet deleted.
573  inline bool has_indicator_constraint(int64_t id) const;
574 
575  // Returns true if this id has been created and not yet deleted.
576  inline bool has_indicator_constraint(IndicatorConstraintId id) const;
577 
578  // Will CHECK if has_indicator_constraint(id) is false.
579  inline IndicatorConstraint indicator_constraint(int64_t id) const;
580 
581  // Will CHECK if has_indicator_constraint(id) is false.
582  inline IndicatorConstraint indicator_constraint(
583  IndicatorConstraintId id) const;
584 
585  // Returns all the existing (created and not deleted) indicator constraints in
586  // the model in an arbitrary order.
587  inline std::vector<IndicatorConstraint> IndicatorConstraints() const;
588 
589  // Returns all the existing (created and not deleted) indicator constraints in
590  // the model sorted by id.
591  inline std::vector<IndicatorConstraint> SortedIndicatorConstraints() const;
592 
594  // Objective methods
596 
597  // Sets the objective to maximize the provided expression.
598  inline void Maximize(double objective);
599  // Sets the objective to maximize the provided expression.
600  inline void Maximize(Variable objective);
601  // Sets the objective to maximize the provided expression.
602  inline void Maximize(LinearTerm objective);
603  // Sets the objective to maximize the provided expression.
604  inline void Maximize(const LinearExpression& objective);
605  // Sets the objective to maximize the provided expression.
606  inline void Maximize(const QuadraticExpression& objective);
607 
608  // Sets the objective to minimize the provided expression.
609  inline void Minimize(double objective);
610  // Sets the objective to minimize the provided expression.
611  inline void Minimize(Variable objective);
612  // Sets the objective to minimize the provided expression.
613  inline void Minimize(LinearTerm objective);
614  // Sets the objective to minimize the provided expression.
615  inline void Minimize(const LinearExpression& objective);
616  // Sets the objective to minimize the provided expression.
617  inline void Minimize(const QuadraticExpression& objective);
618 
619  // Sets the objective to optimize the provided expression.
620  inline void SetObjective(double objective, bool is_maximize);
621  // Sets the objective to optimize the provided expression.
622  inline void SetObjective(Variable objective, bool is_maximize);
623  // Sets the objective to optimize the provided expression.
624  inline void SetObjective(LinearTerm objective, bool is_maximize);
625  // Sets the objective to optimize the provided expression.
626  void SetObjective(const LinearExpression& objective, bool is_maximize);
627  // Sets the objective to optimize the provided expression.
628  void SetObjective(const QuadraticExpression& objective, bool is_maximize);
629 
630  // Adds the provided expression terms to the objective.
631  inline void AddToObjective(double objective);
632  // Adds the provided expression terms to the objective.
633  inline void AddToObjective(Variable objective);
634  // Adds the provided expression terms to the objective.
635  inline void AddToObjective(LinearTerm objective);
636  // Adds the provided expression terms to the objective.
637  void AddToObjective(const LinearExpression& objective);
638  // Adds the provided expression terms to the objective.
639  void AddToObjective(const QuadraticExpression& objective);
640 
641  // NOTE: This will CHECK fail if the objective has quadratic terms.
642  LinearExpression ObjectiveAsLinearExpression() const;
643  QuadraticExpression ObjectiveAsQuadraticExpression() const;
644 
645  // Returns 0.0 if this variable has no linear objective coefficient.
646  inline double objective_coefficient(Variable variable) const;
647 
648  // Returns 0.0 if this variable pair has no quadratic objective coefficient.
649  // The order of the variables does not matter.
650  inline double objective_coefficient(Variable first_variable,
651  Variable second_variable) const;
652 
653  // Setting a value to 0.0 will delete the variable from the underlying sparse
654  // representation (and has no effect if the variable is not present).
655  inline void set_objective_coefficient(Variable variable, double value);
656 
657  // Set quadratic objective terms for the product of two variables. Setting a
658  // value to 0.0 will delete the variable pair from the underlying sparse
659  // representation (and has no effect if the pair is not present). The order of
660  // the variables does not matter.
661  inline void set_objective_coefficient(Variable first_variable,
662  Variable second_variable, double value);
663 
664  // Equivalent to calling set_linear_coefficient(v, 0.0) for every variable
665  // with nonzero objective coefficient.
666  //
667  // Runs in O(#linear and quadratic objective terms with nonzero coefficient).
668  inline void clear_objective();
669 
670  inline bool is_objective_coefficient_nonzero(Variable variable) const;
671  inline bool is_objective_coefficient_nonzero(Variable first_variable,
672  Variable second_variable) const;
673 
674  inline double objective_offset() const;
675 
676  inline void set_objective_offset(double value);
677 
678  inline bool is_maximize() const;
679 
680  inline void set_maximize();
681  inline void set_minimize();
682 
683  // Prefer set_maximize() and set_minimize() above for more readable code.
684  inline void set_is_maximize(bool is_maximize);
685 
686  // Returns a proto representation of the optimization model.
687  //
688  // See FromModelProto() to build a Model from a proto.
689  ModelProto ExportModel() const;
690 
691  // Returns a tracker that can be used to generate a ModelUpdateProto with the
692  // updates that happened since the last checkpoint. The tracker initial
693  // checkpoint corresponds to the current state of the model.
694  //
695  // The returned UpdateTracker keeps a reference to this model. See the
696  // implications in the documentation of the UpdateTracker class.
697  //
698  // Thread-safety: this method must not be used while modifying the model
699  // (variables, constraints, ...). The user is expected to use proper
700  // synchronization primitive to serialize changes to the model and the use of
701  // this method.
702  std::unique_ptr<UpdateTracker> NewUpdateTracker();
703 
704  // Apply the provided update to this model. Returns a failure if the update is
705  // not valid.
706  //
707  // As with FromModelProto(), duplicated names are ignored.
708  //
709  // Note that it takes O(num_variables + num_constraints) extra memory and
710  // execution to apply the update (due to the need to build a ModelSummary). So
711  // even a small update will have some cost.
712  absl::Status ApplyUpdateProto(const ModelUpdateProto& update_proto);
713 
714  // TODO(user): expose a way to efficiently iterate through the nonzeros of
715  // the linear constraint matrix.
716 
717  // Returns a pointer to the underlying model storage.
718  //
719  // This API is for internal use only and regular users should have no need for
720  // it.
721  const ModelStorage* storage() const { return storage_.get(); }
722 
723  // Returns a pointer to the underlying model storage.
724  //
725  // This API is for internal use only and regular users should have no need for
726  // it.
727  ModelStorage* storage() { return storage_.get(); }
728 
729  // Prints the objective, the constraints and the variables of the model over
730  // several lines in a human-readable way. Includes a new line at the end of
731  // the model.
732  friend std::ostream& operator<<(std::ostream& ostr, const Model& model);
733 
734  private:
735  // Asserts (with CHECK) that the input pointer is either nullptr or that it
736  // points to the same model as storage_.
737  //
738  // Use CheckModel() when nullptr is not a valid value.
739  inline void CheckOptionalModel(const ModelStorage* other_storage) const;
740 
741  // Asserts (with CHECK) that the input pointer is the same as storage_.
742  //
743  // Use CheckOptionalModel() if nullptr is a valid value too.
744  inline void CheckModel(const ModelStorage* other_storage) const;
745 
746  // Don't use storage_ directly; prefer to use storage() so that const member
747  // functions don't have modifying access to the underlying storage.
748  //
749  // We use a shared_ptr here so that the UpdateTracker class can have a
750  // weak_ptr on the ModelStorage. This let it have a destructor that don't
751  // crash when called after the destruction of the associated Model.
752  const std::shared_ptr<ModelStorage> storage_;
753 };
754 
756 // Inline function implementations
758 
759 // ------------------------------- Variables -----------------------------------
760 
761 const std::string& Model::name() const { return storage()->name(); }
762 
763 Variable Model::AddVariable(const absl::string_view name) {
764  return Variable(storage(), storage()->AddVariable(name));
765 }
767  const bool is_integer,
768  const absl::string_view name) {
770  is_integer, name));
771 }
772 
773 Variable Model::AddBinaryVariable(const absl::string_view name) {
774  return AddVariable(0.0, 1.0, true, name);
775 }
776 
778  const double upper_bound,
779  const absl::string_view name) {
780  return AddVariable(lower_bound, upper_bound, false, name);
781 }
782 
784  const double upper_bound,
785  const absl::string_view name) {
786  return AddVariable(lower_bound, upper_bound, true, name);
787 }
788 
789 void Model::DeleteVariable(const Variable variable) {
790  CheckModel(variable.storage());
792 }
793 
794 int Model::num_variables() const { return storage()->num_variables(); }
795 
796 int64_t Model::next_variable_id() const {
797  return storage()->next_variable_id().value();
798 }
799 
800 bool Model::has_variable(const int64_t id) const {
801  return has_variable(VariableId(id));
802 }
803 
804 bool Model::has_variable(const VariableId id) const {
805  return storage()->has_variable(id);
806 }
807 
808 Variable Model::variable(const int64_t id) const {
809  return variable(VariableId(id));
810 }
811 
812 Variable Model::variable(const VariableId id) const {
813  CHECK(has_variable(id)) << "No variable with id: " << id.value();
814  return Variable(storage(), id);
815 }
816 
817 const std::string& Model::name(const Variable variable) const {
818  CheckModel(variable.storage());
819  return storage()->variable_name(variable.typed_id());
820 }
821 
822 void Model::set_lower_bound(const Variable variable, double lower_bound) {
823  CheckModel(variable.storage());
825 }
826 
827 double Model::lower_bound(const Variable variable) const {
828  CheckModel(variable.storage());
830 }
831 
832 void Model::set_upper_bound(const Variable variable, double upper_bound) {
833  CheckModel(variable.storage());
835 }
836 
837 double Model::upper_bound(const Variable variable) const {
838  CheckModel(variable.storage());
840 }
841 
842 void Model::set_is_integer(const Variable variable, bool is_integer) {
843  CheckModel(variable.storage());
845 }
846 
847 void Model::set_integer(const Variable variable) {
848  set_is_integer(variable, true);
849 }
850 
851 void Model::set_continuous(const Variable variable) {
852  set_is_integer(variable, false);
853 }
854 
855 bool Model::is_integer(const Variable variable) const {
856  CheckModel(variable.storage());
858 }
859 
860 // -------------------------- Linear constraints -------------------------------
861 
863  Variable variable) const {
864  // TODO(b/239810718): use << for Variable once it does not CHECK.
865  if (storage_.get() != variable.storage()) {
867  << "variable with id " << variable.id()
868  << " is from a different model";
869  }
870  if (!has_variable(variable.typed_id())) {
872  << "variable with id " << variable.id()
873  << " is not found in this model (it was probably deleted)";
874  }
875  return absl::OkStatus();
876 }
877 
880 }
882  const double upper_bound,
883  const absl::string_view name) {
886 }
887 
889  CheckModel(constraint.storage());
890  storage()->DeleteLinearConstraint(constraint.typed_id());
891 }
892 
894  return storage()->num_linear_constraints();
895 }
896 
898  return storage()->next_linear_constraint_id().value();
899 }
900 
901 bool Model::has_linear_constraint(const int64_t id) const {
902  return has_linear_constraint(LinearConstraintId(id));
903 }
904 
905 bool Model::has_linear_constraint(const LinearConstraintId id) const {
906  return storage()->has_linear_constraint(id);
907 }
908 
910  return linear_constraint(LinearConstraintId(id));
911 }
912 
913 LinearConstraint Model::linear_constraint(const LinearConstraintId id) const {
914  CHECK(has_linear_constraint(id))
915  << "No linear constraint with id: " << id.value();
916  return LinearConstraint(storage(), id);
917 }
918 
919 const std::string& Model::name(const LinearConstraint constraint) const {
920  CheckModel(constraint.storage());
921  return storage()->linear_constraint_name(constraint.typed_id());
922 }
923 
925  double lower_bound) {
926  CheckModel(constraint.storage());
928  lower_bound);
929 }
930 
931 double Model::lower_bound(const LinearConstraint constraint) const {
932  CheckModel(constraint.storage());
933  return storage()->linear_constraint_lower_bound(constraint.typed_id());
934 }
935 
937  const double upper_bound) {
938  CheckModel(constraint.storage());
940  upper_bound);
941 }
942 
943 double Model::upper_bound(const LinearConstraint constraint) const {
944  CheckModel(constraint.storage());
945  return storage()->linear_constraint_upper_bound(constraint.typed_id());
946 }
947 
949  LinearConstraint linear_constraint) const {
950  // TODO(b/239810718): use << for LinearConstraint once it does not CHECK.
951  if (storage_.get() != linear_constraint.storage()) {
953  << "linear constraint with id " << linear_constraint.id()
954  << " is from a different model";
955  }
958  << "linear constraint with id " << linear_constraint.id()
959  << " is not found in this model (it was probably deleted)";
960  }
961  return absl::OkStatus();
962 }
963 
965  const Variable variable, const double value) {
966  CheckModel(constraint.storage());
967  CheckModel(variable.storage());
969  variable.typed_id(), value);
970 }
971 
972 double Model::coefficient(const LinearConstraint constraint,
973  const Variable variable) const {
974  CheckModel(constraint.storage());
975  CheckModel(variable.storage());
976  return storage()->linear_constraint_coefficient(constraint.typed_id(),
977  variable.typed_id());
978 }
979 
981  const Variable variable) const {
982  CheckModel(constraint.storage());
983  CheckModel(variable.storage());
985  constraint.typed_id(), variable.typed_id());
986 }
987 
988 // ------------------------- Quadratic constraints -----------------------------
989 
991  CheckModel(constraint.storage());
992  storage()->DeleteAtomicConstraint(constraint.typed_id());
993 }
994 
996  return storage()->num_constraints<QuadraticConstraintId>();
997 }
998 
1000  return storage()->next_constraint_id<QuadraticConstraintId>().value();
1001 }
1002 
1003 bool Model::has_quadratic_constraint(const int64_t id) const {
1004  return has_quadratic_constraint(QuadraticConstraintId(id));
1005 }
1006 
1007 bool Model::has_quadratic_constraint(const QuadraticConstraintId id) const {
1008  return storage()->has_constraint(id);
1009 }
1010 
1012  return quadratic_constraint(QuadraticConstraintId(id));
1013 }
1014 
1016  const QuadraticConstraintId id) const {
1017  CHECK(has_quadratic_constraint(id))
1018  << "No quadratic constraint with id: " << id.value();
1019  return QuadraticConstraint(storage(), id);
1020 }
1021 
1022 std::vector<QuadraticConstraint> Model::QuadraticConstraints() const {
1023  return AtomicConstraints<QuadraticConstraint>(*storage());
1024 }
1025 
1026 std::vector<QuadraticConstraint> Model::SortedQuadraticConstraints() const {
1027  return SortedAtomicConstraints<QuadraticConstraint>(*storage());
1028 }
1029 
1030 // --------------------------- SOS1 constraints --------------------------------
1031 
1033  CheckModel(constraint.storage());
1034  storage()->DeleteAtomicConstraint(constraint.typed_id());
1035 }
1036 
1038  return storage()->num_constraints<Sos1ConstraintId>();
1039 }
1040 
1042  return storage()->next_constraint_id<Sos1ConstraintId>().value();
1043 }
1044 
1045 bool Model::has_sos1_constraint(const int64_t id) const {
1046  return has_sos1_constraint(Sos1ConstraintId(id));
1047 }
1048 
1049 bool Model::has_sos1_constraint(const Sos1ConstraintId id) const {
1050  return storage()->has_constraint(id);
1051 }
1052 
1053 Sos1Constraint Model::sos1_constraint(const int64_t id) const {
1054  return sos1_constraint(Sos1ConstraintId(id));
1055 }
1056 
1057 Sos1Constraint Model::sos1_constraint(const Sos1ConstraintId id) const {
1058  CHECK(has_sos1_constraint(id))
1059  << "No SOS1 constraint with id: " << id.value();
1060  return Sos1Constraint(storage(), id);
1061 }
1062 
1063 std::vector<Sos1Constraint> Model::Sos1Constraints() const {
1064  return AtomicConstraints<Sos1Constraint>(*storage());
1065 }
1066 
1067 std::vector<Sos1Constraint> Model::SortedSos1Constraints() const {
1068  return SortedAtomicConstraints<Sos1Constraint>(*storage());
1069 }
1070 
1071 // --------------------------- SOS2 constraints --------------------------------
1072 
1074  CheckModel(constraint.storage());
1075  storage()->DeleteAtomicConstraint(constraint.typed_id());
1076 }
1077 
1079  return storage()->num_constraints<Sos2ConstraintId>();
1080 }
1081 
1083  return storage()->next_constraint_id<Sos2ConstraintId>().value();
1084 }
1085 
1086 bool Model::has_sos2_constraint(const int64_t id) const {
1087  return has_sos2_constraint(Sos2ConstraintId(id));
1088 }
1089 
1090 bool Model::has_sos2_constraint(const Sos2ConstraintId id) const {
1091  return storage()->has_constraint(id);
1092 }
1093 
1094 Sos2Constraint Model::sos2_constraint(const int64_t id) const {
1095  return sos2_constraint(Sos2ConstraintId(id));
1096 }
1097 
1098 Sos2Constraint Model::sos2_constraint(const Sos2ConstraintId id) const {
1099  CHECK(has_sos2_constraint(id))
1100  << "No SOS2 constraint with id: " << id.value();
1101  return Sos2Constraint(storage(), id);
1102 }
1103 
1104 std::vector<Sos2Constraint> Model::Sos2Constraints() const {
1105  return AtomicConstraints<Sos2Constraint>(*storage());
1106 }
1107 
1108 std::vector<Sos2Constraint> Model::SortedSos2Constraints() const {
1109  return SortedAtomicConstraints<Sos2Constraint>(*storage());
1110 }
1111 
1112 // --------------------------- Indicator constraints ---------------------------
1113 
1115  CheckModel(constraint.storage());
1116  storage()->DeleteAtomicConstraint(constraint.typed_id());
1117 }
1118 
1120  return storage()->num_constraints<IndicatorConstraintId>();
1121 }
1122 
1124  return storage()->next_constraint_id<IndicatorConstraintId>().value();
1125 }
1126 
1127 bool Model::has_indicator_constraint(const int64_t id) const {
1128  return has_indicator_constraint(IndicatorConstraintId(id));
1129 }
1130 
1131 bool Model::has_indicator_constraint(const IndicatorConstraintId id) const {
1132  return storage()->has_constraint(id);
1133 }
1134 
1136  return indicator_constraint(IndicatorConstraintId(id));
1137 }
1138 
1140  const IndicatorConstraintId id) const {
1141  CHECK(has_indicator_constraint(id))
1142  << "No indicator constraint with id: " << id.value();
1143  return IndicatorConstraint(storage(), id);
1144 }
1145 
1146 std::vector<IndicatorConstraint> Model::IndicatorConstraints() const {
1147  return AtomicConstraints<IndicatorConstraint>(*storage());
1148 }
1149 
1150 std::vector<IndicatorConstraint> Model::SortedIndicatorConstraints() const {
1151  return SortedAtomicConstraints<IndicatorConstraint>(*storage());
1152 }
1153 
1154 // ------------------------------- Objective -----------------------------------
1155 
1156 void Model::Maximize(const double objective) {
1157  SetObjective(LinearExpression(objective), /*is_maximize=*/true);
1158 }
1159 void Model::Maximize(const Variable objective) {
1160  SetObjective(LinearExpression(objective), /*is_maximize=*/true);
1161 }
1162 void Model::Maximize(const LinearTerm objective) {
1163  SetObjective(LinearExpression(objective), /*is_maximize=*/true);
1164 }
1165 void Model::Maximize(const LinearExpression& objective) {
1166  SetObjective(objective, /*is_maximize=*/true);
1167 }
1168 void Model::Maximize(const QuadraticExpression& objective) {
1169  SetObjective(objective, /*is_maximize=*/true);
1170 }
1171 
1172 void Model::Minimize(const double objective) {
1173  SetObjective(LinearExpression(objective), /*is_maximize=*/false);
1174 }
1175 void Model::Minimize(const Variable objective) {
1176  SetObjective(LinearExpression(objective), /*is_maximize=*/false);
1177 }
1178 void Model::Minimize(const LinearTerm objective) {
1179  SetObjective(LinearExpression(objective), /*is_maximize=*/false);
1180 }
1181 void Model::Minimize(const LinearExpression& objective) {
1182  SetObjective(objective, /*is_maximize=*/false);
1183 }
1184 void Model::Minimize(const QuadraticExpression& objective) {
1185  SetObjective(objective, /*is_maximize=*/false);
1186 }
1187 
1188 void Model::SetObjective(const double objective, const bool is_maximize) {
1189  SetObjective(LinearExpression(objective), /*is_maximize=*/is_maximize);
1190 }
1191 void Model::SetObjective(const Variable objective, const bool is_maximize) {
1192  SetObjective(LinearExpression(objective), /*is_maximize=*/is_maximize);
1193 }
1194 void Model::SetObjective(const LinearTerm objective, const bool is_maximize) {
1195  SetObjective(LinearExpression(objective), /*is_maximize=*/is_maximize);
1196 }
1197 
1198 void Model::AddToObjective(const double objective) {
1199  AddToObjective(LinearExpression(objective));
1200 }
1201 void Model::AddToObjective(const Variable objective) {
1202  AddToObjective(LinearExpression(objective));
1203 }
1204 void Model::AddToObjective(const LinearTerm objective) {
1205  AddToObjective(LinearExpression(objective));
1206 }
1207 
1208 double Model::objective_coefficient(const Variable variable) const {
1209  CheckModel(variable.storage());
1211 }
1212 
1213 double Model::objective_coefficient(const Variable first_variable,
1214  const Variable second_variable) const {
1215  CheckModel(first_variable.storage());
1216  CheckModel(second_variable.storage());
1217  return storage()->quadratic_objective_coefficient(first_variable.typed_id(),
1218  second_variable.typed_id());
1219 }
1220 
1222  const double value) {
1223  CheckModel(variable.storage());
1225 }
1226 
1227 void Model::set_objective_coefficient(const Variable first_variable,
1228  const Variable second_variable,
1229  const double value) {
1230  CheckModel(first_variable.storage());
1231  CheckModel(second_variable.storage());
1233  first_variable.typed_id(), second_variable.typed_id(), value);
1234 }
1235 
1237 
1239  CheckModel(variable.storage());
1241  variable.typed_id());
1242 }
1243 
1245  const Variable first_variable, const Variable second_variable) const {
1246  CheckModel(first_variable.storage());
1247  CheckModel(second_variable.storage());
1249  first_variable.typed_id(), second_variable.typed_id());
1250 }
1251 
1252 double Model::objective_offset() const { return storage()->objective_offset(); }
1253 
1256 }
1257 
1258 bool Model::is_maximize() const { return storage()->is_maximize(); }
1259 
1261 
1263 
1264 void Model::set_is_maximize(const bool is_maximize) {
1266 }
1267 
1268 void Model::CheckOptionalModel(const ModelStorage* const other_storage) const {
1269  if (other_storage != nullptr) {
1270  CHECK_EQ(other_storage, storage())
1272  }
1273 }
1274 
1275 void Model::CheckModel(const ModelStorage* const other_storage) const {
1276  CHECK_EQ(other_storage, storage()) << internal::kObjectsFromOtherModelStorage;
1277 }
1278 
1279 } // namespace math_opt
1280 } // namespace operations_research
1281 
1282 #endif // OR_TOOLS_MATH_OPT_CPP_MODEL_H_
std::vector< IndicatorConstraint > IndicatorConstraints() const
static absl::StatusOr< std::unique_ptr< Model > > FromModelProto(const ModelProto &model_proto)
void DeleteIndicatorConstraint(IndicatorConstraint constraint)
Variable AddBinaryVariable(absl::string_view name="")
double objective_coefficient(Variable variable) const
std::unique_ptr< Model > Clone(std::optional< absl::string_view > new_name=std::nullopt) const
LinearConstraint linear_constraint(int64_t id) const
void DeleteQuadraticConstraint(QuadraticConstraint constraint)
std::vector< Sos2Constraint > SortedSos2Constraints() const
const std::string & name() const
Model & operator=(const Model &)=delete
absl::Status ValidateExistingVariableOfThisModel(Variable variable) const
double coefficient(LinearConstraint constraint, Variable variable) const
double lower_bound(Variable variable) const
void DeleteSos2Constraint(Sos2Constraint constraint)
void SetObjective(double objective, bool is_maximize)
std::unique_ptr< UpdateTracker > NewUpdateTracker()
QuadraticConstraint quadratic_constraint(int64_t id) const
LinearExpression ObjectiveAsLinearExpression() const
std::vector< LinearConstraint > ColumnNonzeros(Variable variable) const
Variable variable(int64_t id) const
Variable AddIntegerVariable(double lower_bound, double upper_bound, absl::string_view name="")
std::vector< Sos2Constraint > Sos2Constraints() const
std::vector< IndicatorConstraint > SortedIndicatorConstraints() const
LinearConstraint AddLinearConstraint(absl::string_view name="")
absl::Status ValidateExistingLinearConstraintOfThisModel(LinearConstraint linear_constraint) const
void DeleteSos1Constraint(Sos1Constraint constraint)
absl::Status ApplyUpdateProto(const ModelUpdateProto &update_proto)
std::vector< QuadraticConstraint > QuadraticConstraints() const
void set_coefficient(LinearConstraint constraint, Variable variable, double value)
QuadraticConstraint AddQuadraticConstraint(const BoundedQuadraticExpression &bounded_expr, absl::string_view name="")
bool has_linear_constraint(int64_t id) const
bool is_objective_coefficient_nonzero(Variable variable) const
std::vector< Sos1Constraint > SortedSos1Constraints() const
bool has_quadratic_constraint(int64_t id) const
std::vector< Sos1Constraint > Sos1Constraints() const
double upper_bound(Variable variable) const
bool is_coefficient_nonzero(LinearConstraint constraint, Variable variable) const
Sos1Constraint sos1_constraint(int64_t id) const
void set_is_integer(Variable variable, bool is_integer)
bool has_indicator_constraint(int64_t id) const
QuadraticExpression ObjectiveAsQuadraticExpression() const
const ModelStorage * storage() const
void DeleteLinearConstraint(LinearConstraint constraint)
std::vector< Variable > Variables() const
void set_upper_bound(Variable variable, double upper_bound)
IndicatorConstraint indicator_constraint(int64_t id) const
bool is_integer(Variable variable) const
Sos1Constraint AddSos1Constraint(const std::vector< LinearExpression > &expressions, std::vector< double > weights={}, absl::string_view name="")
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< Variable > RowNonzeros(LinearConstraint constraint) const
Sos2Constraint AddSos2Constraint(const std::vector< LinearExpression > &expressions, std::vector< double > weights={}, absl::string_view name="")
std::vector< LinearConstraint > SortedLinearConstraints() const
IndicatorConstraint AddIndicatorConstraint(Variable indicator_variable, const BoundedLinearExpression &implied_constraint, bool activate_on_zero=false, absl::string_view name={})
void set_objective_coefficient(Variable variable, double value)
friend std::ostream & operator<<(std::ostream &ostr, const Model &model)
std::vector< QuadraticConstraint > SortedQuadraticConstraints() const
std::vector< Variable > SortedVariables() const
Variable AddVariable(double lower_bound, double upper_bound, bool is_integer, absl::string_view name="")
Sos2Constraint sos2_constraint(int64_t id) const
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
GRBmodel * model
constexpr absl::string_view kObjectsFromOtherModelStorage
Definition: key_types.h:57
Collection of objects used to extend the Constraint Solver library.
StatusBuilder InvalidArgumentErrorBuilder()
IntVar * upper_bound
Definition: routing.cc:1087
IntVar * lower_bound
Definition: routing.cc:1086