Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
general_constraint_to_mip.cc
Go to the documentation of this file.
1// Copyright 2010-2024 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 <limits>
17
18#include "absl/status/status.h"
19#include "absl/strings/str_format.h"
22
24
25constexpr double kInf = std::numeric_limits<double>::infinity();
26
28 Model& model, const IndicatorConstraint indicator_constraint) {
29 if (indicator_constraint.storage() != model.storage()) {
30 return absl::InvalidArgumentError(
31 absl::StrFormat("Indicator constraint %s is associated with wrong "
32 "model (expected: %s, actual: %s)",
33 indicator_constraint.name(), model.name(),
34 indicator_constraint.storage()->name()));
35 }
36 if (!indicator_constraint.indicator_variable()) {
37 model.DeleteIndicatorConstraint(indicator_constraint);
38 return absl::OkStatus();
39 }
40 const Variable indicator_variable =
41 *indicator_constraint.indicator_variable();
42 if (!indicator_variable.is_integer() ||
43 indicator_variable.lower_bound() < 0 ||
44 indicator_variable.upper_bound() > 1) {
45 return absl::InvalidArgumentError(absl::StrFormat(
46 "In indicator constraint %s: indicator variable %s is "
47 "not a binary variable",
48 indicator_constraint.name(), indicator_variable.name()));
49 }
50 const BoundedLinearExpression implied_constraint =
51 indicator_constraint.ImpliedConstraint();
52 // One if the implied constraint should hold; zero otherwise.
53 const LinearExpression activated_expr =
54 indicator_constraint.activate_on_zero() ? 1 - indicator_variable
55 : indicator_variable;
56 if (implied_constraint.lower_bound > -kInf) {
57 const double expr_lower_bound = LowerBound(implied_constraint.expression);
58 if (expr_lower_bound == -kInf) {
59 return absl::InvalidArgumentError(
60 absl::StrFormat("In indicator constraint %s: cannot prove that "
61 "implied constraint is unbounded from below",
62 indicator_constraint.name()));
63 }
64 model.AddLinearConstraint(
65 implied_constraint.expression >=
66 expr_lower_bound + (implied_constraint.lower_bound - expr_lower_bound) *
67 activated_expr);
68 }
69 if (implied_constraint.upper_bound < kInf) {
70 const double expr_upper_bound = UpperBound(implied_constraint.expression);
71 if (expr_upper_bound == kInf) {
72 return absl::InvalidArgumentError(
73 absl::StrFormat("In indicator constraint %s: cannot prove that "
74 "implied constraint is unbounded from above",
75 indicator_constraint.name()));
76 }
77 model.AddLinearConstraint(
78 implied_constraint.expression <=
79 expr_upper_bound + (implied_constraint.upper_bound - expr_upper_bound) *
80 activated_expr);
81 }
82 model.DeleteIndicatorConstraint(indicator_constraint);
83 return absl::OkStatus();
84}
85
86} // namespace operations_research::math_opt
bool activate_on_zero() const
The value the indicator variable takes to activate the implied constraint.
GRBmodel * model
An object oriented wrapper for quadratic constraints in ModelStorage.
Definition gurobi_isv.cc:28
double LowerBound(const LinearExpression &linear_expression)
absl::Status FormulateIndicatorConstraintAsMip(Model &model, const IndicatorConstraint indicator_constraint)
double UpperBound(const LinearExpression &linear_expression)
A LinearExpression with upper and lower bounds.