Models a pessimistic bilevel problem taken from Zeng (2025) and solves it via the KKT single-level reformulation of its optimistic equivalent reformulation.
#include <iostream>
#include "idol/modeling.h"
#include "idol/bilevel/modeling/Description.h"
#include "idol/bilevel/optimizers/PessimisticAsOptimistic/PessimisticAsOptimistic.h"
#include "idol/bilevel/optimizers/KKT/KKT.h"
#include "idol/mixed-integer/optimizers/wrappers/Gurobi/Gurobi.h"
using namespace idol;
int main(int t_argc, const char** t_argv) {
Model high_point_relaxation(env);
auto x = high_point_relaxation.add_vars(
Dim<1>(3), 0, Inf, Continuous, 0,
"x");
auto y = high_point_relaxation.add_vars(
Dim<1>(4), 0, Inf, Continuous, 0,
"y");
auto leader_c = high_point_relaxation.add_ctr(x[0] + x[1] <= 10, "leader_c");
auto follower_c1 = high_point_relaxation.add_ctr(y[0] + y[1] + y[2] + y[3] <= 10 - x[0] - x[1], "follower_c1");
auto follower_c2 = high_point_relaxation.add_ctr(-y[0] + y[3] <= 0.8 * x[0] + 0.8 * x[1], "follower_c2");
auto follower_c3 = high_point_relaxation.add_ctr(y[1] + y[3] <= 4 * x[1], "follower_c3");
high_point_relaxation.set_obj_expr(-8 * x[0] - 6 * x[1] - 25 * y[0] - 30 * y[1] + 2 * y[2] + 16 * y[3]);
description.set_lower_level_obj(-10 * y[0] - 10 * y[1] - 10 * y[2] - 10 * y[3]);
description.make_lower_level<1>(y);
description.make_lower_level(follower_c1);
description.make_lower_level(follower_c2);
description.make_lower_level(follower_c3);
auto [opt_model, opt_description] = Bilevel::PessimisticAsOptimistic::make_model(high_point_relaxation, description);
opt_model.optimize();
std::cout << save_primal(opt_model) << std::endl;
return 0;
}