84 absl::Span<const GScipLinearExpr> terms,
85 absl::string_view name) {
94 std::vector<SCIP_VAR*> indicators;
95 for (
int i = 0; i < terms.size(); ++i) {
96 auto z = gscip->AddVariable(0.0, 1.0, 0.0, GScipVarType::kInteger,
97 MaybeExtendName(name, absl::StrCat(
"z_", i)));
99 indicators.push_back(*z);
102 for (
int i = 0; i < terms.size(); ++i) {
106 ->AddLinearConstraint(
107 GScipLe(terms.at(i), resultant),
108 MaybeExtendName(name, absl::StrCat(
"x_", i,
"_le_y")))
112 GScipLinearRange y_less_x =
GScipLe(resultant, terms.at(i));
113 CHECK_EQ(y_less_x.lower_bound, -std::numeric_limits<double>::infinity());
114 GScipIndicatorConstraint ind;
115 ind.indicator_variable = indicators.at(i);
116 ind.variables = y_less_x.variables;
117 ind.coefficients = y_less_x.coefficients;
118 ind.upper_bound = y_less_x.upper_bound;
121 ->AddIndicatorConstraint(
122 ind, MaybeExtendName(
123 name, absl::StrCat(
"y_le__x_", i,
"_if_z_", i)))
129 GScipLinearRange z_use;
130 z_use.upper_bound = 1.0;
131 z_use.lower_bound = 1.0;
132 z_use.variables = indicators;
133 z_use.coefficients = std::vector<double>(indicators.size(), 1.0);
135 return gscip->AddLinearConstraint(z_use, MaybeExtendName(name,
"one_z"))
151 GScip* gscip, std::vector<SCIP_Var*> quadratic_variables1,
152 std::vector<SCIP_Var*> quadratic_variables2,
153 std::vector<double> quadratic_coefficients, absl::string_view name) {
154 constexpr double kInf = std::numeric_limits<double>::infinity();
156 gscip->AddVariable(-kInf, kInf, 1.0, GScipVarType::kContinuous,
157 MaybeExtendName(name,
"obj"));
159 GScipQuadraticRange range;
160 range.quadratic_variables1 = quadratic_variables1;
161 range.quadratic_variables2 = quadratic_variables2;
162 range.quadratic_coefficients = quadratic_coefficients;
163 range.linear_coefficients = {-1.0};
164 range.linear_variables = {*obj_term};
165 if (gscip->ObjectiveIsMaximize()) {
169 range.lower_bound = 0.0;
174 range.upper_bound = 0.0;
176 return gscip->AddQuadraticConstraint(range, MaybeExtendName(name,
"cons"))
182 absl::string_view name,
const GScipConstraintOptions& options) {
183 if (std::isfinite(indicator_range.
range.upper_bound)) {
184 GScipIndicatorConstraint ub_constraint;
185 ub_constraint.upper_bound = indicator_range.
range.upper_bound;
186 ub_constraint.variables = indicator_range.
range.variables;
187 ub_constraint.coefficients = indicator_range.
range.coefficients;
191 ->AddIndicatorConstraint(
192 ub_constraint, MaybeExtendName(name,
"ub"), options)
195 if (std::isfinite(indicator_range.
range.lower_bound)) {
198 GScipIndicatorConstraint lb_constraint;
199 lb_constraint.upper_bound = -indicator_range.
range.lower_bound;
200 lb_constraint.variables = indicator_range.
range.variables;
201 for (
const double c : indicator_range.
range.coefficients) {
202 lb_constraint.coefficients.push_back(-c);
207 ->AddIndicatorConstraint(
208 lb_constraint, MaybeExtendName(name,
"lb"), options)
211 return absl::OkStatus();
absl::Status GScipCreateIndicatorRange(GScip *gscip, const GScipIndicatorRangeConstraint &indicator_range, absl::string_view name, const GScipConstraintOptions &options)
Supports unbounded variables in indicator_range.range.variables.
absl::Status GScipAddQuadraticObjectiveTerm(GScip *gscip, std::vector< SCIP_Var * > quadratic_variables1, std::vector< SCIP_Var * > quadratic_variables2, std::vector< double > quadratic_coefficients, absl::string_view name)