Skip to content

Commit

Permalink
define addition with strong duality
Browse files Browse the repository at this point in the history
  • Loading branch information
hlefebvr committed Nov 29, 2024
1 parent fba2b6e commit 5cfd973
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 39 deletions.
58 changes: 24 additions & 34 deletions examples/bilevel/padm.example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include "idol/mixed-integer/modeling/models/KKT.h"
#include "idol/mixed-integer/optimizers/wrappers/GLPK/GLPK.h"
#include "idol/mixed-integer/optimizers/wrappers/HiGHS/HiGHS.h"
#include "idol/bilevel/optimizers/KKT/KKT.h"
#include "idol/bilevel/optimizers/StrongDuality/StrongDuality.h"

int main(int t_argc, const char** t_argv) {

Expand All @@ -34,26 +36,8 @@ int main(int t_argc, const char** t_argv) {
description.make_lower_level(c);
description.set_lower_level_obj(-2 * x - y);

Reformulators::KKT reformulator(model, description);

Model single_level(env);
reformulator.add_coupling_variables(single_level);
reformulator.add_strong_duality_reformulation(single_level);
reformulator.add_coupling_constraints(single_level);
single_level.set_obj_expr(single_level.get_obj_expr());

std::cout << model << std::endl;
std::cout << single_level << std::endl;

single_level.use(Gurobi());
single_level.optimize();

std::cout << save_primal(single_level) << std::endl;

Annotation<unsigned int> decomposition(env, "sub_problem");
for (const auto& var : single_level.vars()) {
var.set(decomposition, var.id() == delta.id());
}
Annotation<unsigned int> decomposition(env, "sub_problem", 0);
delta.set(decomposition, 1);

/*
* All constraints will be penalized.
Expand All @@ -62,23 +46,29 @@ int main(int t_argc, const char** t_argv) {
*/
Annotation<double> initial_penalties(env, "initial_penalties", 1e2);

Point<Var> initial_point;
const auto strong_duality = Bilevel::StrongDuality(description);

const auto padm = PADM(decomposition, initial_penalties)
.with_default_sub_problem_spec(
ADM::SubProblem()
.with_optimizer(Gurobi().with_external_param(GRB_IntParam_NonConvex, 0))
)
.with_penalty_update(PenaltyUpdates::Multiplicative(2))
.with_rescaling_threshold(1e4)
.with_logs(true);

single_level.use(
PADM(decomposition, initial_penalties)
.with_default_sub_problem_spec(
ADM::SubProblem()
.with_optimizer(Gurobi())
.with_initial_point(initial_point)
)
.with_penalty_update(PenaltyUpdates::Multiplicative(2))
.with_rescaling_threshold(1e4)
.with_logs(true)
);
model.use(strong_duality + padm);

single_level.optimize();
model.optimize();

std::cout << save_primal(single_level) << std::endl;
std::cout << save_primal(model) << std::endl;

/**
* Alternatively, you can use:
* const Model strong_duality = Bilevel::StrongDuality::make_model(description);
* strong_duality.use(padm);
* strong_duality.optimize();
*/

return 0;
}
10 changes: 10 additions & 0 deletions lib/include/idol/bilevel/optimizers/StrongDuality/StrongDuality.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,17 @@ class idol::Bilevel::StrongDuality : public OptimizerFactoryWithDefaultParameter

StrongDuality& with_single_level_optimizer(const OptimizerFactory& t_deterministic_optimizer);

StrongDuality& operator+=(const OptimizerFactory& t_optimizer) { return with_single_level_optimizer(t_optimizer); }

static Model make_model(const Model& t_model, const Bilevel::Description& t_description);
};

namespace idol {
static Bilevel::StrongDuality operator+(const Bilevel::StrongDuality& t_strong_duality, const OptimizerFactory& t_optimizer) {
Bilevel::StrongDuality result(t_strong_duality);
result += t_optimizer;
return result;
}
}

#endif //IDOL_BILEVEL_STRONG_DUALITY_H
6 changes: 1 addition & 5 deletions lib/src/bilevel/optimizers/StrongDuality/StrongDuality.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ idol::Bilevel::StrongDuality::with_single_level_optimizer(const idol::OptimizerF
idol::Bilevel::StrongDuality::StrongDuality(const idol::Bilevel::StrongDuality &t_src)
: OptimizerFactoryWithDefaultParameters<StrongDuality>(t_src),
m_description(t_src.m_description),
m_single_level_optimizer(t_src.m_single_level_optimizer->clone()) {
m_single_level_optimizer(t_src.m_single_level_optimizer ? t_src.m_single_level_optimizer->clone() : nullptr) {

}

Expand All @@ -49,10 +49,6 @@ idol::Bilevel::StrongDuality::make_model(const idol::Model &t_model, const idol:
throw Exception("Only minimization problems are supported.");
}

if (t_model.qctrs().size() > 0) {
throw Exception("Quadratic constraints are not supported.");
}

auto& env = t_model.env();

Reformulators::KKT reformulator(t_model, t_description);
Expand Down

0 comments on commit 5cfd973

Please sign in to comment.