Skip to content

Commit

Permalink
add example for ADR
Browse files Browse the repository at this point in the history
  • Loading branch information
hlefebvr committed Nov 28, 2024
1 parent 80b3fda commit 24ad40b
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 41 deletions.
3 changes: 2 additions & 1 deletion examples/robust/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
add_example(robust-facility-location)
add_example(robust-facility-location)
add_example(adr-facility-location)
41 changes: 41 additions & 0 deletions examples/robust/adr-facility-location.data.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
10 20
109.6 131.484
169.498 103.513
24.7946 41.8319
150.331 156.535
140.651 128.462
68.8231 66.0825
5.40097 33.6793
123.19 113.974
118.503 152.262
27.5682 125.587
36.1992
5.60365
10.0339
20.1965
17.4686
35.8237
14.8866
2.75196
36.7471
2.76135
12.0892
16.2641
11.3815
8.96618
32.1548
13.7501
0.631599
26.9407
36.4762
10.0098
0.674345 0.377274 0.60077 0.725902 0.347025 0.648906 0.635155 0.607522 0.333549 0.300607 0.416598 0.628605 0.753687 0.644812 0.405533 0.152511 0.424802 0.261078 0.50283 0.403443
0.79483 0.0798539 0.347963 0.756363 0.654002 0.484362 0.663717 0.820894 0.220568 0.548021 0.218845 0.779403 0.804299 0.507375 0.592223 0.172742 0.63654 0.0894973 0.819295 0.712606
0.988408 0.473435 0.741449 1.02582 0.420089 0.859221 0.932609 0.913111 0.206479 0.606641 0.592807 0.943148 1.05883 0.871605 0.719628 0.296455 0.735305 0.405338 0.70923 0.472351
0.801213 0.930165 1.12413 0.970236 0.281743 1.11036 0.911725 0.579372 0.840547 0.467774 0.937797 0.721997 0.961574 1.08599 0.57822 0.70739 0.533045 0.812734 0.148052 0.238144
0.033511 0.742563 0.729705 0.21527 0.807152 0.579068 0.209073 0.232984 0.91811 0.384516 0.620859 0.0675881 0.187979 0.528276 0.248045 0.699975 0.263439 0.677736 0.632054 0.831136
0.379508 0.394834 0.402656 0.338167 0.703938 0.315728 0.243857 0.475284 0.607753 0.336413 0.270847 0.38184 0.381389 0.285442 0.271919 0.405371 0.331478 0.346229 0.681973 0.748633
1.01954 0.586318 0.852622 1.08059 0.340762 0.955962 0.989606 0.914744 0.331927 0.616543 0.693984 0.966318 1.10785 0.963435 0.742256 0.385068 0.74801 0.505968 0.654321 0.385256
0.124851 0.647767 0.637432 0.198938 0.766693 0.495492 0.15157 0.278676 0.831333 0.339767 0.525301 0.137635 0.200255 0.446836 0.203461 0.614955 0.238989 0.585824 0.629149 0.796432
0.822042 0.611747 0.850139 0.920143 0.113758 0.898665 0.836445 0.683577 0.462689 0.406345 0.66767 0.759121 0.93636 0.891583 0.542633 0.376275 0.534339 0.501362 0.400407 0.172095
0.728693 0.27883 0.523355 0.749647 0.439242 0.602651 0.655937 0.692852 0.235195 0.391798 0.348472 0.692708 0.785082 0.607712 0.47688 0.0436219 0.506139 0.16976 0.61561 0.497567
100 changes: 100 additions & 0 deletions examples/robust/adr-facility-location.example.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
//
// Created by henri on 28.11.24.
//
#include <iostream>
#include "idol/modeling.h"
#include "idol/mixed-integer/problems/facility-location-problem/FLP_Instance.h"
#include "idol/mixed-integer/optimizers/branch-and-bound/BranchAndBound.h"
#include "idol/mixed-integer/optimizers/branch-and-bound/branching-rules/factories/PseudoCost.h"
#include "idol/mixed-integer/optimizers/branch-and-bound/node-selection-rules/factories/BestEstimate.h"
#include "idol/mixed-integer/optimizers/wrappers/HiGHS/HiGHS.h"
#include "idol/mixed-integer/optimizers/wrappers/GLPK/GLPK.h"
#include "idol/mixed-integer/optimizers/wrappers/Gurobi/Gurobi.h"
#include "idol/mixed-integer/optimizers/branch-and-bound/node-selection-rules/factories/BestBound.h"
#include "idol/mixed-integer/optimizers/branch-and-bound/branching-rules/factories/MostInfeasible.h"
#include "idol/mixed-integer/optimizers/callbacks/ReducedCostFixing.h"
#include "idol/robust/modeling/Description.h"
#include "idol/robust/optimizers/deterministic/Deterministic.h"
#include "idol/robust/optimizers/affine-decision-rule/AffineDecisionRule.h"

using namespace idol;

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

Env env;

// Read instance
const auto instance = Problems::FLP::read_instance_1991_Cornuejols_et_al("adr-facility-location.data.txt");
const unsigned int n_customers = instance.n_customers();
const unsigned int n_facilities = instance.n_facilities();

// Uncertainty set
Model uncertainty_set(env);
const double Gamma = 1;
const auto xi = uncertainty_set.add_vars(Dim<1>(n_customers), 0., 1., Continuous, 0., "xi");
uncertainty_set.add_ctr(idol_Sum(i, Range(n_customers), xi[i]) <= Gamma);

// Make model
Model model(env);
Robust::Description description(uncertainty_set);

auto x = model.add_vars(Dim<1>(n_facilities), 0., 1., Binary, 0., "x");
auto y = model.add_vars(Dim<2>(n_facilities, n_customers), 0., 1., Continuous, 0., "y");

for (unsigned int i = 0 ; i < n_facilities ; ++i) {
model.add_ctr(idol_Sum(j, Range(n_customers), instance.demand(j) * y[i][j]) <= instance.capacity(i));
}

for (unsigned int j = 0 ; j < n_customers ; ++j) {
model.add_ctr(idol_Sum(i, Range(n_facilities), y[i][j]) >= 1);
}

for (unsigned int i = 0 ; i < n_facilities ; ++i) {
for (unsigned int j = 0 ; j < n_customers ; ++j) {
model.add_ctr(y[i][j] <= x[i]);
}
}

model.set_obj_expr(idol_Sum(i, Range(n_facilities),
instance.fixed_cost(i) * x[i]
+ idol_Sum(j, Range(n_customers),
instance.per_unit_transportation_cost(i, j) *
instance.demand(j) *
y[i][j]
)
)
);

for (unsigned int i = 0 ; i < n_facilities ; ++i) {
for (unsigned int j = 0; j < n_customers; ++j) {
const auto c = model.add_ctr(y[i][j] <= 1);
description.set_uncertain_rhs(c, -xi[j]); // models y_ij <= 1 - xi_j
description.set_stage(y[i][j], 1); // models y_ij as a second-stage variable
}
}

/*
* const auto deterministic_model = Robust::AffineDecisionRule::make_model(model, description);
* std::cout << Robust::Description::View(model, description) << std::endl;
*/

model.use(Gurobi());
model.optimize();
std::cout << "Deterministic Problem has value: " << model.get_best_obj() << std::endl;

model.use(
Robust::AffineDecisionRule(description)
.with_deterministic_optimizer(Gurobi())
);
model.optimize();
std::cout << "Affine Decision Rule Problem has value: " << model.get_best_obj() << std::endl;

model.use(
Robust::Deterministic(description)
.with_deterministic_optimizer(GLPK())
);
model.optimize();
std::cout << "Robust Problem has value: " << model.get_best_obj() << std::endl;

return 0;
}
3 changes: 0 additions & 3 deletions examples/robust/robust-facility-location.example.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
//
// Created by henri on 28.11.24.
//
//
// Created by henri on 06/04/23.
//
#include <iostream>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace idol::Optimizers::Robust {
class idol::Optimizers::Robust::AffineDecisionRule : public Algorithm {
const idol::Robust::Description& m_description;
std::unique_ptr<OptimizerFactory> m_deterministic_optimizer;
std::unique_ptr<idol::Robust::AffineDecisionRule::Result> m_deterministic_model;
std::unique_ptr<idol::Robust::AffineDecisionRule::Result> m_adr_result;

void throw_if_no_deterministic_model() const;
public:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,144 +19,144 @@ std::string idol::Optimizers::Robust::AffineDecisionRule::name() const {

double idol::Optimizers::Robust::AffineDecisionRule::get_var_primal(const idol::Var &t_var) const {
throw_if_no_deterministic_model();
return m_deterministic_model->model.get_var_primal(t_var);
return m_adr_result->model.get_var_primal(t_var);
}

double idol::Optimizers::Robust::AffineDecisionRule::get_var_reduced_cost(const idol::Var &t_var) const {
throw_if_no_deterministic_model();
return m_deterministic_model->model.get_var_reduced_cost(t_var);
return m_adr_result->model.get_var_reduced_cost(t_var);
}

double idol::Optimizers::Robust::AffineDecisionRule::get_var_ray(const idol::Var &t_var) const {
throw_if_no_deterministic_model();
return m_deterministic_model->model.get_var_ray(t_var);
return m_adr_result->model.get_var_ray(t_var);
}

double idol::Optimizers::Robust::AffineDecisionRule::get_ctr_dual(const idol::Ctr &t_ctr) const {
throw_if_no_deterministic_model();
return m_deterministic_model->model.get_ctr_dual(t_ctr);
return m_adr_result->model.get_ctr_dual(t_ctr);
}

double idol::Optimizers::Robust::AffineDecisionRule::get_ctr_farkas(const idol::Ctr &t_ctr) const {
throw_if_no_deterministic_model();
return m_deterministic_model->model.get_ctr_farkas(t_ctr);
return m_adr_result->model.get_ctr_farkas(t_ctr);
}

unsigned int idol::Optimizers::Robust::AffineDecisionRule::get_n_solutions() const {
throw_if_no_deterministic_model();
return m_deterministic_model->model.get_n_solutions();
return m_adr_result->model.get_n_solutions();
}

unsigned int idol::Optimizers::Robust::AffineDecisionRule::get_solution_index() const {
throw_if_no_deterministic_model();
return m_deterministic_model->model.get_solution_index();
return m_adr_result->model.get_solution_index();
}

void idol::Optimizers::Robust::AffineDecisionRule::add(const idol::Var &t_var) {
m_deterministic_model.reset();
m_adr_result.reset();
}

void idol::Optimizers::Robust::AffineDecisionRule::add(const idol::Ctr &t_ctr) {
m_deterministic_model.reset();
m_adr_result.reset();
}

void idol::Optimizers::Robust::AffineDecisionRule::add(const idol::QCtr &t_ctr) {
m_deterministic_model.reset();
m_adr_result.reset();
}

void idol::Optimizers::Robust::AffineDecisionRule::remove(const idol::Var &t_var) {
m_deterministic_model.reset();
m_adr_result.reset();
}

void idol::Optimizers::Robust::AffineDecisionRule::remove(const idol::Ctr &t_ctr) {
m_deterministic_model.reset();
m_adr_result.reset();
}

void idol::Optimizers::Robust::AffineDecisionRule::remove(const idol::QCtr &t_ctr) {
m_deterministic_model.reset();
m_adr_result.reset();
}

void idol::Optimizers::Robust::AffineDecisionRule::update() {
m_deterministic_model.reset();
m_adr_result.reset();
}

void idol::Optimizers::Robust::AffineDecisionRule::write(const std::string &t_name) {
throw_if_no_deterministic_model();
m_deterministic_model->model.write(t_name);
m_adr_result->model.write(t_name);
}

void idol::Optimizers::Robust::AffineDecisionRule::hook_optimize() {

if (!m_deterministic_model) {
if (!m_adr_result) {

m_deterministic_model = std::make_unique<idol::Robust::AffineDecisionRule::Result>(
m_adr_result = std::make_unique<idol::Robust::AffineDecisionRule::Result>(
idol::Robust::AffineDecisionRule::make_model(parent(), m_description)
);

m_deterministic_model->model.use(
idol::Robust::Deterministic(m_deterministic_model->description)
m_adr_result->model.use(
idol::Robust::Deterministic(m_adr_result->description)
.with_deterministic_optimizer(*m_deterministic_optimizer)
);

}

m_deterministic_model->model.optimize();
m_adr_result->model.optimize();

}

void idol::Optimizers::Robust::AffineDecisionRule::set_solution_index(unsigned int t_index) {
throw_if_no_deterministic_model();
m_deterministic_model->model.set_solution_index(t_index);
m_adr_result->model.set_solution_index(t_index);
}

void idol::Optimizers::Robust::AffineDecisionRule::update_obj_sense() {
m_deterministic_model.reset();
m_adr_result.reset();
}

void idol::Optimizers::Robust::AffineDecisionRule::update_obj() {
m_deterministic_model.reset();
m_adr_result.reset();
}

void idol::Optimizers::Robust::AffineDecisionRule::update_rhs() {
m_deterministic_model.reset();
m_adr_result.reset();
}

void idol::Optimizers::Robust::AffineDecisionRule::update_obj_constant() {
throw_if_no_deterministic_model();
m_deterministic_model->model.set_obj_const(parent().get_obj_expr().affine().constant());
m_adr_result->model.set_obj_const(parent().get_obj_expr().affine().constant());
}

void idol::Optimizers::Robust::AffineDecisionRule::update_mat_coeff(const idol::Ctr &t_ctr, const idol::Var &t_var) {
m_deterministic_model.reset();
m_adr_result.reset();
}

void idol::Optimizers::Robust::AffineDecisionRule::update_ctr_type(const idol::Ctr &t_ctr) {
m_deterministic_model.reset();
m_adr_result.reset();
}

void idol::Optimizers::Robust::AffineDecisionRule::update_ctr_rhs(const idol::Ctr &t_ctr) {
throw_if_no_deterministic_model();
m_deterministic_model->model.set_ctr_rhs(t_ctr, parent().get_ctr_rhs(t_ctr));
m_adr_result->model.set_ctr_rhs(t_ctr, parent().get_ctr_rhs(t_ctr));
}

void idol::Optimizers::Robust::AffineDecisionRule::update_var_type(const idol::Var &t_var) {
throw_if_no_deterministic_model();
m_deterministic_model->model.set_var_type(t_var, parent().get_var_type(t_var));
m_adr_result->model.set_var_type(t_var, parent().get_var_type(t_var));
}

void idol::Optimizers::Robust::AffineDecisionRule::update_var_lb(const idol::Var &t_var) {
throw_if_no_deterministic_model();
m_deterministic_model->model.set_var_lb(t_var, parent().get_var_lb(t_var));
m_adr_result->model.set_var_lb(t_var, parent().get_var_lb(t_var));
}

void idol::Optimizers::Robust::AffineDecisionRule::update_var_ub(const idol::Var &t_var) {
throw_if_no_deterministic_model();
m_deterministic_model->model.set_var_ub(t_var, parent().get_var_ub(t_var));
m_adr_result->model.set_var_ub(t_var, parent().get_var_ub(t_var));
}

void idol::Optimizers::Robust::AffineDecisionRule::update_var_obj(const idol::Var &t_var) {
throw_if_no_deterministic_model();
m_deterministic_model->model.set_var_obj(t_var, parent().get_var_obj(t_var));
m_adr_result->model.set_var_obj(t_var, parent().get_var_obj(t_var));
}

void idol::Optimizers::Robust::AffineDecisionRule::throw_if_no_deterministic_model() const {
Expand All @@ -167,20 +167,20 @@ void idol::Optimizers::Robust::AffineDecisionRule::throw_if_no_deterministic_mod

idol::SolutionStatus idol::Optimizers::Robust::AffineDecisionRule::get_status() const {
throw_if_no_deterministic_model();
return m_deterministic_model->model.get_status();
return m_adr_result->model.get_status();
}

idol::SolutionReason idol::Optimizers::Robust::AffineDecisionRule::get_reason() const {
throw_if_no_deterministic_model();
return m_deterministic_model->model.get_reason();
return m_adr_result->model.get_reason();
}

double idol::Optimizers::Robust::AffineDecisionRule::get_best_obj() const {
throw_if_no_deterministic_model();
return m_deterministic_model->model.get_best_obj();
return m_adr_result->model.get_best_obj();
}

double idol::Optimizers::Robust::AffineDecisionRule::get_best_bound() const {
throw_if_no_deterministic_model();
return m_deterministic_model->model.get_best_bound();
return m_adr_result->model.get_best_bound();
}

0 comments on commit 24ad40b

Please sign in to comment.