diff --git a/lib/include/idol/mixed-integer/modeling/constraints/CtrVersion.h b/lib/include/idol/mixed-integer/modeling/constraints/CtrVersion.h index bfe1e144..487c3357 100644 --- a/lib/include/idol/mixed-integer/modeling/constraints/CtrVersion.h +++ b/lib/include/idol/mixed-integer/modeling/constraints/CtrVersion.h @@ -56,7 +56,7 @@ class idol::CtrVersion : public Version { void set_row(LinExpr&& t_row) { m_lhs = std::make_unique>(std::move(t_row)); } - bool has_row() const { return m_lhs != nullptr; } + bool has_row() const { return m_lhs.operator bool(); } void set_row(const LinExpr& t_row) { m_lhs = std::make_unique>(t_row); } diff --git a/lib/include/idol/mixed-integer/modeling/variables/VarVersion.h b/lib/include/idol/mixed-integer/modeling/variables/VarVersion.h index 51783902..fb61c04c 100644 --- a/lib/include/idol/mixed-integer/modeling/variables/VarVersion.h +++ b/lib/include/idol/mixed-integer/modeling/variables/VarVersion.h @@ -50,7 +50,7 @@ class idol::VarVersion : public Version { void set_column(LinExpr&& t_column) { m_column = std::make_unique>(std::move(t_column)); } - bool has_column() const { return m_column != nullptr; } + bool has_column() const { return m_column.operator bool(); } void set_column(const LinExpr& t_column) { m_column = std::make_unique>(t_column); } diff --git a/lib/src/bilevel/optimizers/StrongDuality/StrongDuality.cpp b/lib/src/bilevel/optimizers/StrongDuality/StrongDuality.cpp index 587aab03..6ea90a13 100644 --- a/lib/src/bilevel/optimizers/StrongDuality/StrongDuality.cpp +++ b/lib/src/bilevel/optimizers/StrongDuality/StrongDuality.cpp @@ -1,6 +1,7 @@ // // Created by henri on 29.11.24. // +#include #include "idol/bilevel/optimizers/StrongDuality/StrongDuality.h" #include "idol/bilevel/optimizers/StrongDuality/Optimizers_StrongDuality.h" #include "idol/mixed-integer/modeling/models/KKT.h" diff --git a/lib/src/mixed-integer/modeling/models/KKT.cpp b/lib/src/mixed-integer/modeling/models/KKT.cpp index 4fe175bf..2c212038 100644 --- a/lib/src/mixed-integer/modeling/models/KKT.cpp +++ b/lib/src/mixed-integer/modeling/models/KKT.cpp @@ -338,13 +338,13 @@ void idol::Reformulators::KKT::create_dual_constraints() { std::move(dual_constraint_expression.affine().linear()), Equal, -dual_constraint_expression.affine().constant()), - "dual_constraint_" + var.name()); + "dual_" + var.name()); } else { m_dual_constraints[index] = QCtr(env, TempQCtr( std::move(dual_constraint_expression), Equal), - "dual_constraint_" + var.name()); + "dual_" + var.name()); } } @@ -533,9 +533,9 @@ void idol::Reformulators::KKT::add_strong_duality_reformulation(idol::Model &t_d auto duality_gap = m_primal_objective - m_dual_objective; if (duality_gap.has_quadratic()) { - t_destination.add_qctr(std::move(duality_gap), LessOrEqual); + t_destination.add_qctr(std::move(duality_gap), LessOrEqual, "strong_duality"); } else { - t_destination.add_ctr(std::move(duality_gap.affine()) <= 0); + t_destination.add_ctr(std::move(duality_gap.affine()) <= 0, "strong_duality"); } } diff --git a/lib/src/mixed-integer/modeling/models/Model.cpp b/lib/src/mixed-integer/modeling/models/Model.cpp index 72cad86e..fb6b38ef 100644 --- a/lib/src/mixed-integer/modeling/models/Model.cpp +++ b/lib/src/mixed-integer/modeling/models/Model.cpp @@ -13,6 +13,7 @@ idol::Model::Model(idol::Model && t_src) noexcept m_sense(t_src.m_sense), m_variables(std::move(t_src.m_variables)), m_constraints(std::move(t_src.m_constraints)), + m_qconstraints(std::move(t_src.m_qconstraints)), m_optimizer_factory(std::move(t_src.m_optimizer_factory)), m_objective(std::move(t_src.m_objective)), m_rhs(std::move(t_src.m_rhs)), diff --git a/lib/src/mixed-integer/optimizers/padm/Formulation.cpp b/lib/src/mixed-integer/optimizers/padm/Formulation.cpp index fd7d28bf..1a3bfd2b 100644 --- a/lib/src/mixed-integer/optimizers/padm/Formulation.cpp +++ b/lib/src/mixed-integer/optimizers/padm/Formulation.cpp @@ -10,6 +10,7 @@ #include "idol/mixed-integer/modeling/constraints/TempCtr.h" #include +#include idol::ADM::Formulation::Formulation(const Model& t_src_model, Annotation t_decomposition, @@ -251,8 +252,6 @@ void idol::ADM::Formulation::set_penalty_in_all_sub_problems(const Var &t_var, d void idol::ADM::Formulation::initialize_penalty_parameters(bool t_use_inverse_penalties) { - const unsigned int n_sub_problems = m_sub_problems.size(); - for (auto& sub_problem : m_sub_problems) { for (const auto& var : sub_problem.l1_epigraph_vars) { @@ -417,32 +416,41 @@ void idol::ADM::Formulation::dispatch_qctr(const idol::Model &t_src_model, } auto& sub_problem = m_sub_problems[t_sub_problem_id]; + std::optional new_linear_ctr; if (!full_row) { // here, we are still on RHS fixation if (rhs_quad.empty_all()) { - sub_problem.model.add_ctr(TempCtr(LinExpr(lhs), type, rhs_quad.affine().constant()), t_ctr.name()); + new_linear_ctr = sub_problem.model.add_ctr(TempCtr(LinExpr(lhs), type, rhs_quad.affine().constant()), t_ctr.name()); } else { - const auto c = sub_problem.model.add_ctr(TempCtr(std::move(lhs), type, 0), t_ctr.name()); - sub_problem.rhs_fixations.emplace_back(c, std::move(rhs_quad)); + new_linear_ctr = sub_problem.model.add_ctr(TempCtr(std::move(lhs), type, 0), t_ctr.name()); + sub_problem.rhs_fixations.emplace_back(*new_linear_ctr, std::move(rhs_quad)); } - return; - } + } else { - // here, we are on LHS fixation + // here, we are on LHS fixation + + if (full_row->has_quadratic()) { + // we have to add a quadratic constraint here + throw Exception("Quadratic constraints in fixed problems are not implemented"); + } + + new_linear_ctr = sub_problem.model.add_ctr(TempCtr(LinExpr(), type, 0.), t_ctr.name()); + sub_problem.row_fixations.emplace_back(*new_linear_ctr, std::move(*full_row)); - if (full_row->has_quadratic()) { - // we have to add a quadratic constraint here - throw Exception("Quadratic constraints in fixed problems are not implemented"); } - const auto c = sub_problem.model.add_ctr(TempCtr(LinExpr(), type, 0.), t_ctr.name()); - sub_problem.row_fixations.emplace_back(c, std::move(*full_row)); + assert(new_linear_ctr.has_value()); + + if (m_initial_penalty_parameters.has_value()) { + new_linear_ctr->set(*m_initial_penalty_parameters, t_ctr.get(*m_initial_penalty_parameters)); + } } + double idol::ADM::Formulation::evaluate(const QuadExpr& t_expr, const std::vector>& t_primals) { double result = t_expr.affine().constant(); for (const auto& [var, coeff] : t_expr.affine().linear()) { @@ -479,7 +487,7 @@ idol::LinExpr idol::ADM::Formulation::add_l1_vars(unsigned int t_ctr_ if (const auto it = m_l1_epigraph_vars.find(t_ctr_id) ; it != m_l1_epigraph_vars.end()) { var = it->second; } else { - var = Var(model.env(), 0, Inf, Continuous, 0); + var = Var(model.env(), 0, Inf, Continuous, 0, "l1_epigraph_" + std::to_string(t_ctr_id)); var->set(*m_initial_penalty_parameters, t_initial_penalty_parameter); m_l1_epigraph_vars.emplace_hint(it, t_ctr_id, *var); m_sub_problems[t_sub_problem_id].l1_epigraph_vars.emplace_back(*var); diff --git a/lib/src/mixed-integer/optimizers/padm/Optimizers_PADM.cpp b/lib/src/mixed-integer/optimizers/padm/Optimizers_PADM.cpp index 27a3971c..1920e28c 100644 --- a/lib/src/mixed-integer/optimizers/padm/Optimizers_PADM.cpp +++ b/lib/src/mixed-integer/optimizers/padm/Optimizers_PADM.cpp @@ -380,11 +380,12 @@ idol::Optimizers::PADM::solve_sub_problem(unsigned int t_sub_problem_id) { auto& sub_problem = m_formulation.sub_problem(t_sub_problem_id); + + //sub_problem.model.write("sub_problem_" + std::to_string(t_sub_problem_id) + "_" + std::to_string(m_outer_loop_iteration) + "_" + std::to_string(m_inner_loop_iterations) + ".lp"); + sub_problem.model.optimizer().set_param_time_limit(get_remaining_time()); sub_problem.model.optimize(); - //sub_problem.model.write("iter_" + std::to_string(m_outer_loop_iteration) + "_" + std::to_string(m_inner_loop_iterations) + ".sub_problem_" + std::to_string(t_sub_problem_id) + ".lp"); - const auto status = sub_problem.model.get_status(); if (status != Optimal && status != Feasible) {