65#include "absl/container/flat_hash_map.h"
66#include "absl/types/span.h"
75constexpr double kInf = std::numeric_limits<double>::infinity();
77class RobustConstraintDualizer {
79 RobustConstraintDualizer(
80 const Model& uncertainty_model, Variable rhs,
81 absl::Span<
const std::pair<LinearExpression, Variable>>
82 uncertain_coefficients,
90 LinearExpression objective_expression_;
92 absl::flat_hash_map<LinearConstraint, LinearExpression> y_;
94 absl::flat_hash_map<Variable, LinearExpression> r_;
120LinearExpression RobustConstraintDualizer::AddDualizedVariable(
145absl::flat_hash_map<Variable, LinearExpression> TransposeUncertainCoefficients(
146 absl::Span<
const std::pair<LinearExpression, Variable>>
147 uncertain_coefficients) {
148 absl::flat_hash_map<Variable, LinearExpression> result;
149 for (
const auto& [expression, main_model_variable] : uncertain_coefficients) {
150 for (
const auto [v,
coefficient] : expression.terms()) {
157RobustConstraintDualizer::RobustConstraintDualizer(
158 const Model& uncertainty_model,
const Variable rhs,
159 absl::Span<
const std::pair<LinearExpression, Variable>>
160 uncertain_coefficients,
162 : main_model_(main_model) {
163 const std::vector<Variable> uncertainty_variables =
164 uncertainty_model.SortedVariables();
165 const std::vector<LinearConstraint> uncertainty_constraints =
166 uncertainty_model.SortedLinearConstraints();
167 for (
const LinearConstraint c : uncertainty_constraints) {
170 for (
const Variable v : uncertainty_variables) {
171 r_.insert({v, AddDualizedVariable(v.lower_bound(), v.upper_bound())});
176 LinearExpression offset_expression;
177 for (
const auto& [expression, variable] : uncertain_coefficients) {
178 offset_expression += expression.offset() * variable;
180 main_model_.AddLinearConstraint(objective_expression_ + offset_expression <=
184 const absl::flat_hash_map<Variable, LinearExpression>
185 equality_rhs_expressions =
186 TransposeUncertainCoefficients(uncertain_coefficients);
187 for (
const Variable v : uncertainty_variables) {
188 LinearExpression equality_lhs_expression = r_.at(v);
189 for (
const LinearConstraint c : uncertainty_model.ColumnNonzeros(v)) {
192 main_model_.AddLinearConstraint(
193 equality_lhs_expression ==
202 absl::Span<
const std::pair<LinearExpression, Variable>>
203 uncertain_coefficients,
205 RobustConstraintDualizer dualizer(uncertainty_model, rhs,
206 uncertain_coefficients, main_model);
double upper_bound() const
double lower_bound() const
double coefficient(Variable variable) const
Returns 0.0 if the variable is not used in the constraint.
Variable AddContinuousVariable(double lower_bound, double upper_bound, absl::string_view name="")
Adds a variable to the model with domain [lower_bound, upper_bound].
const MapUtilMappedT< Collection > & FindWithDefault(const Collection &collection, const KeyType &key, const MapUtilMappedT< Collection > &value)
void AddRobustConstraint(const Model &uncertainty_model, const Variable rhs, absl::Span< const std::pair< LinearExpression, Variable > > uncertain_coefficients, Model &main_model)
In SWIG mode, we don't want anything besides these top-level includes.