25 #include "absl/status/status.h"
26 #include "absl/status/statusor.h"
27 #include "absl/strings/string_view.h"
28 #include "absl/log/check.h"
47 constexpr
double kInf = std::numeric_limits<double>::infinity();
53 return std::make_unique<Model>(std::move(
storage));
60 : storage_(std::move(storage)) {}
63 const std::optional<absl::string_view> new_name)
const {
64 return std::make_unique<Model>(storage_->Clone(new_name));
81 std::vector<Variable> result;
83 for (
const VariableId var_id :
storage()->variables()) {
90 std::vector<Variable> result =
Variables();
91 std::sort(result.begin(), result.end(),
93 return l.typed_id() < r.typed_id();
101 std::vector<LinearConstraint> result;
102 for (
const LinearConstraintId constraint :
111 CheckModel(constraint.
storage());
112 std::vector<Variable> result;
121 std::vector<LinearConstraint> result;
131 std::sort(result.begin(), result.end(),
133 return l.typed_id() < r.typed_id();
139 const bool is_maximize) {
140 CheckOptionalModel(objective.
storage());
150 const bool is_maximize) {
151 CheckOptionalModel(objective.
storage());
165 CheckOptionalModel(objective_terms.
storage());
175 CheckOptionalModel(objective_terms.
storage());
184 vars.first, vars.second,
185 coef +
storage()->quadratic_objective_coefficient(vars.first,
191 CHECK_EQ(
storage()->num_quadratic_objective_terms(), 0)
192 <<
"The objective function contains quadratic terms and cannot be "
193 "represented as a LinearExpression";
195 for (
const auto& [v,
coef] :
storage()->linear_objective()) {
203 for (
const auto& [v,
coef] :
storage()->linear_objective()) {
206 for (
const auto& [v1, v2,
coef] :
storage()->quadratic_objective_terms()) {
216 return std::make_unique<UpdateTracker>(storage_);
225 if (!
model.name().empty()) ostr <<
" " <<
model.name();
228 ostr <<
" Objective:\n"
229 << (
model.is_maximize() ?
" maximize " :
" minimize ")
230 <<
model.ObjectiveAsQuadraticExpression() <<
"\n";
232 ostr <<
" Linear constraints:\n";
234 ostr <<
" " << constraint <<
": " << constraint.AsBoundedLinearExpression()
238 if (
model.num_quadratic_constraints() > 0) {
239 ostr <<
" Quadratic constraints:\n";
241 model.SortedQuadraticConstraints()) {
242 ostr <<
" " << constraint <<
": "
243 << constraint.AsBoundedQuadraticExpression() <<
"\n";
247 if (
model.num_sos1_constraints() > 0) {
248 ostr <<
" SOS1 constraints:\n";
250 ostr <<
" " << constraint <<
": " << constraint.ToString() <<
"\n";
254 if (
model.num_sos2_constraints() > 0) {
255 ostr <<
" SOS2 constraints:\n";
257 ostr <<
" " << constraint <<
": " << constraint.ToString() <<
"\n";
261 if (
model.num_indicator_constraints() > 0) {
262 ostr <<
" Indicator constraints:\n";
264 model.SortedIndicatorConstraints()) {
265 ostr <<
" " << constraint <<
": " << constraint.ToString() <<
"\n";
269 ostr <<
" Variables:\n";
272 if (v.is_integer()) {
273 if (v.lower_bound() == 0 && v.upper_bound() == 1) {
274 ostr <<
" (binary)\n";
277 ostr <<
" (integer)";
280 if (v.lower_bound() == -
kInf) {
286 if (v.upper_bound() ==
kInf) {
300 const absl::string_view
name) {
304 linear_terms.
set(
var.typed_id(), coeff);
307 for (
const auto& [var_ids, coeff] :
309 quadratic_terms.
set(var_ids.first, var_ids.second, coeff);
311 const QuadraticConstraintId
id =
315 .linear_terms = std::move(linear_terms),
316 .quadratic_terms = std::move(quadratic_terms),
317 .name = std::string(
name),
326 template <
typename SosData>
327 SosData MakeSosData(
const std::vector<LinearExpression>& expressions,
328 std::vector<double> weights,
const absl::string_view
name) {
329 std::vector<typename SosData::LinearExpression> storage_expressions;
330 storage_expressions.reserve(expressions.size());
332 typename SosData::LinearExpression& storage_expr =
333 storage_expressions.emplace_back();
334 storage_expr.offset = expr.offset();
335 for (
const auto [
var, coeff] : expr.raw_terms()) {
336 storage_expr.terms[
var] = coeff;
339 return SosData(std::move(storage_expressions), std::move(weights),
346 const std::vector<LinearExpression>& expressions,
347 std::vector<double> weights,
const absl::string_view
name) {
349 CheckOptionalModel(expr.storage());
352 MakeSosData<Sos1ConstraintData>(expressions, std::move(weights),
name));
359 const std::vector<LinearExpression>& expressions,
360 std::vector<double> weights,
const absl::string_view
name) {
362 CheckOptionalModel(expr.storage());
365 MakeSosData<Sos2ConstraintData>(expressions, std::move(weights),
name));
374 const bool activate_on_zero,
const absl::string_view
name) {
375 CheckModel(indicator_variable.
storage());
380 const IndicatorConstraintId
id =
384 .linear_terms = std::move(expr),
385 .indicator = indicator_variable.
typed_id(),
386 .activate_on_zero = activate_on_zero,
387 .name = std::string(
name),
#define ASSIGN_OR_RETURN(lhs, rexpr)
LinearConstraintId typed_id() const
const ModelStorage * storage() const
const absl::flat_hash_map< VariableId, double > & raw_terms() const
const ModelStorage * storage() const
static absl::StatusOr< std::unique_ptr< Model > > FromModelProto(const ModelProto &model_proto)
std::unique_ptr< Model > Clone(std::optional< absl::string_view > new_name=std::nullopt) const
const std::string & name() const
int num_linear_constraints() const
void SetObjective(double objective, bool is_maximize)
std::unique_ptr< UpdateTracker > NewUpdateTracker()
LinearExpression ObjectiveAsLinearExpression() const
Model(absl::string_view name="")
std::vector< LinearConstraint > ColumnNonzeros(Variable variable) const
Variable variable(int64_t id) const
int num_variables() const
LinearConstraint AddLinearConstraint(absl::string_view name="")
double objective_offset() const
absl::Status ApplyUpdateProto(const ModelUpdateProto &update_proto)
QuadraticConstraint AddQuadraticConstraint(const BoundedQuadraticExpression &bounded_expr, absl::string_view name="")
void AddToObjective(double objective)
double upper_bound(Variable variable) const
ModelProto ExportModel() const
QuadraticExpression ObjectiveAsQuadraticExpression() const
const ModelStorage * storage() const
std::vector< Variable > Variables() const
Sos1Constraint AddSos1Constraint(const std::vector< LinearExpression > &expressions, std::vector< double > weights={}, absl::string_view name="")
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={})
std::vector< Variable > SortedVariables() 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)
void set_linear_objective_coefficient(VariableId variable, double value)
ConstraintData::IdType AddAtomicConstraint(ConstraintData data)
double objective_offset() const
absl::Status ApplyUpdateProto(const ModelUpdateProto &update_proto)
void set_linear_constraint_coefficient(LinearConstraintId constraint, VariableId variable, double value)
ModelProto ExportModel() const
void set_is_maximize(bool is_maximize)
LinearConstraintId AddLinearConstraint(absl::string_view name="")
void set_objective_offset(double value)
const VariableMap< double > & linear_terms() const
const absl::flat_hash_map< QuadraticProductId, double > & raw_quadratic_terms() const
const absl::flat_hash_map< VariableId, double > & raw_linear_terms() const
const ModelStorage * storage() const
bool set(const VariableId id, const double coeff)
bool set(VariableId first, VariableId second, double value)
const ModelStorage * storage() const
VariableId typed_id() const
CpModelProto const * model_proto
std::pair< SparseCoefficientMap, double > FromLinearExpression(const LinearExpression &expression)
std::ostream & operator<<(std::ostream &ostr, const IndicatorConstraint &constraint)
Collection of objects used to extend the Constraint Solver library.
double upper_bound_minus_offset() const
LinearExpression expression
double lower_bound_minus_offset() const
double upper_bound_minus_offset() const
QuadraticExpression expression
double lower_bound_minus_offset() const