OR-Tools  9.3
math_opt/cpp/model.cc
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
15
16#include <algorithm>
17#include <memory>
18#include <utility>
19#include <vector>
20
21#include "absl/container/flat_hash_map.h"
22#include "absl/memory/memory.h"
23#include "absl/status/status.h"
24#include "absl/status/statusor.h"
25#include "absl/strings/string_view.h"
30
31namespace operations_research {
32namespace math_opt {
33
34absl::StatusOr<std::unique_ptr<Model>> Model::FromModelProto(
35 const ModelProto& model_proto) {
36 ASSIGN_OR_RETURN(std::unique_ptr<ModelStorage> storage,
38 return std::make_unique<Model>(std::move(storage));
39}
40
41Model::Model(const absl::string_view name)
42 : storage_(std::make_shared<ModelStorage>(name)) {}
43
44Model::Model(std::unique_ptr<ModelStorage> storage)
45 : storage_(std::move(storage)) {}
46
47std::unique_ptr<Model> Model::Clone() const {
48 return std::make_unique<Model>(storage_->Clone());
49}
50
52 const BoundedLinearExpression& bounded_expr, absl::string_view name) {
53 CheckOptionalModel(bounded_expr.expression.storage());
54
55 const LinearConstraintId constraint = storage()->AddLinearConstraint(
56 bounded_expr.lower_bound_minus_offset(),
57 bounded_expr.upper_bound_minus_offset(), name);
58 for (auto [variable, coef] : bounded_expr.expression.raw_terms()) {
60 }
61 return LinearConstraint(storage(), constraint);
62}
63
64std::vector<Variable> Model::Variables() const {
65 std::vector<Variable> result;
66 result.reserve(storage()->num_variables());
67 for (const VariableId var_id : storage()->variables()) {
68 result.push_back(Variable(storage(), var_id));
69 }
70 return result;
71}
72
73std::vector<Variable> Model::SortedVariables() const {
74 std::vector<Variable> result = Variables();
75 std::sort(result.begin(), result.end(),
76 [](const Variable& l, const Variable& r) {
77 return l.typed_id() < r.typed_id();
78 });
79 return result;
80}
81
82std::vector<LinearConstraint> Model::ColumnNonzeros(const Variable variable) {
83 CheckModel(variable.storage());
84 std::vector<LinearConstraint> result;
85 for (const LinearConstraintId constraint :
86 storage()->linear_constraints_with_variable(variable.typed_id())) {
87 result.push_back(LinearConstraint(storage(), constraint));
88 }
89 return result;
90}
91
92std::vector<Variable> Model::RowNonzeros(const LinearConstraint constraint) {
93 CheckModel(constraint.storage());
94 std::vector<Variable> result;
95 for (const VariableId variable :
96 storage()->variables_in_linear_constraint(constraint.typed_id())) {
97 result.push_back(Variable(storage(), variable));
98 }
99 return result;
100}
101
103 const LinearConstraint constraint) {
104 CheckModel(constraint.storage());
105 LinearExpression terms;
106 for (const VariableId var :
107 storage()->variables_in_linear_constraint(constraint.typed_id())) {
108 terms +=
109 Variable(storage(), var) *
111 }
112 return storage()->linear_constraint_lower_bound(constraint.typed_id()) <=
113 std::move(terms) <=
115}
116
117std::vector<LinearConstraint> Model::LinearConstraints() const {
118 std::vector<LinearConstraint> result;
119 result.reserve(storage()->num_linear_constraints());
120 for (const LinearConstraintId lin_con_id : storage()->linear_constraints()) {
121 result.push_back(LinearConstraint(storage(), lin_con_id));
122 }
123 return result;
124}
125
126std::vector<LinearConstraint> Model::SortedLinearConstraints() const {
127 std::vector<LinearConstraint> result = LinearConstraints();
128 std::sort(result.begin(), result.end(),
129 [](const LinearConstraint& l, const LinearConstraint& r) {
130 return l.typed_id() < r.typed_id();
131 });
132 return result;
133}
134
136 const bool is_maximize) {
137 CheckOptionalModel(objective.storage());
140 storage()->set_objective_offset(objective.offset());
141 for (auto [var, coef] : objective.raw_terms()) {
143 }
144}
145
147 const bool is_maximize) {
148 CheckOptionalModel(objective.storage());
151 storage()->set_objective_offset(objective.offset());
152 for (auto [var, coef] : objective.raw_linear_terms()) {
154 }
155 for (auto [vars, coef] : objective.raw_quadratic_terms()) {
156 storage()->set_quadratic_objective_coefficient(vars.first, vars.second,
157 coef);
158 }
159}
160
161void Model::AddToObjective(const LinearExpression& objective_terms) {
162 CheckOptionalModel(objective_terms.storage());
163 storage()->set_objective_offset(objective_terms.offset() +
165 for (auto [var, coef] : objective_terms.raw_terms()) {
167 var, coef + storage()->linear_objective_coefficient(var));
168 }
169}
170
171void Model::AddToObjective(const QuadraticExpression& objective_terms) {
172 CheckOptionalModel(objective_terms.storage());
173 storage()->set_objective_offset(objective_terms.offset() +
175 for (auto [var, coef] : objective_terms.raw_linear_terms()) {
177 var, coef + storage()->linear_objective_coefficient(var));
178 }
179 for (auto [vars, coef] : objective_terms.raw_quadratic_terms()) {
181 vars.first, vars.second,
182 coef + storage()->quadratic_objective_coefficient(vars.first,
183 vars.second));
184 }
185}
186
188 CHECK(storage()->quadratic_objective().empty())
189 << "The objective function contains quadratic terms and cannot be "
190 "represented as a LinearExpression";
192 for (const auto& [v, coef] : storage()->linear_objective()) {
193 result += Variable(storage(), v) * coef;
194 }
195 return result;
196}
197
200 for (const auto& [v, coef] : storage()->linear_objective()) {
201 result += Variable(storage(), v) * coef;
202 }
203 for (const auto& [vars, coef] : storage()->quadratic_objective()) {
204 result += QuadraticTerm(Variable(storage(), vars.first),
205 Variable(storage(), vars.second), coef);
206 }
207 return result;
208}
209
210ModelProto Model::ExportModel() const { return storage()->ExportModel(); }
211
212std::unique_ptr<UpdateTracker> Model::NewUpdateTracker() {
213 return std::make_unique<UpdateTracker>(storage_);
214}
215
216absl::Status Model::ApplyUpdateProto(const ModelUpdateProto& update_proto) {
217 return storage()->ApplyUpdateProto(update_proto);
218}
219
220} // namespace math_opt
221} // namespace operations_research
#define CHECK(condition)
Definition: base/logging.h:495
#define ASSIGN_OR_RETURN(lhs, rexpr)
const absl::flat_hash_map< VariableId, double > & raw_terms() const
static absl::StatusOr< std::unique_ptr< Model > > FromModelProto(const ModelProto &model_proto)
std::vector< Variable > RowNonzeros(LinearConstraint constraint)
const std::string & name() 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
LinearConstraint AddLinearConstraint(absl::string_view name="")
absl::Status ApplyUpdateProto(const ModelUpdateProto &update_proto)
std::unique_ptr< Model > Clone() const
QuadraticExpression ObjectiveAsQuadraticExpression() const
std::vector< Variable > Variables() const
std::vector< LinearConstraint > ColumnNonzeros(Variable variable)
std::vector< LinearConstraint > LinearConstraints() const
std::vector< LinearConstraint > SortedLinearConstraints() const
std::vector< Variable > SortedVariables() const
const ModelStorage * storage() const
void set_quadratic_objective_coefficient(VariableId first_variable, VariableId second_variable, double value)
static absl::StatusOr< std::unique_ptr< ModelStorage > > FromModelProto(const ModelProto &model_proto)
double linear_constraint_coefficient(LinearConstraintId constraint, VariableId variable) const
void set_linear_objective_coefficient(VariableId variable, double value)
double linear_constraint_lower_bound(LinearConstraintId id) const
absl::Status ApplyUpdateProto(const ModelUpdateProto &update_proto)
void set_linear_constraint_coefficient(LinearConstraintId constraint, VariableId variable, double value)
double linear_constraint_upper_bound(LinearConstraintId id) const
LinearConstraintId AddLinearConstraint(absl::string_view name="")
const absl::flat_hash_map< QuadraticProductId, double > & raw_quadratic_terms() const
const absl::flat_hash_map< VariableId, double > & raw_linear_terms() const
CpModelProto const * model_proto
const std::string name
IntVar * var
Definition: expr_array.cc:1874
int64_t coef
Definition: expr_array.cc:1875
Collection of objects used to extend the Constraint Solver library.
STL namespace.