Skip to content

Commit

Permalink
add RENS heuristic
Browse files Browse the repository at this point in the history
  • Loading branch information
hlefebvr committed Oct 16, 2023
1 parent b8cb26a commit fd39bd2
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 2 deletions.
6 changes: 6 additions & 0 deletions documentation/api/heuristics/RENS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.. _api_Heuristics_RENS:

RENS (Relaxation Enforced Neighbourhood Search)
===============================================

.. doxygenclass:: idol::Heuristics::RENS
1 change: 1 addition & 0 deletions documentation/api/heuristics/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ Heuristics

SimpleRounding
IntegerMaster
RENS
10 changes: 9 additions & 1 deletion examples/knapsack-problem/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "optimizers/branch-and-bound/node-selection-rules/factories/BestBound.h"
#include "optimizers/branch-and-bound/cutting-planes/CoverCuts.h"
#include "optimizers/callbacks/SimpleRounding.h"
#include "optimizers/callbacks/RENS.h"

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

Expand Down Expand Up @@ -41,7 +42,14 @@ int main(int t_argc, const char** t_argv) {
.with_node_selection_rule(BestBound())
//.with_cutting_planes(CoverCuts().with_optimizer(Gurobi()))
.with_callback(
Heuristics::SimpleRounding()
Heuristics::RENS()
.with_optimizer(
BranchAndBound()
.with_node_optimizer(Gurobi::ContinuousRelaxation())
.with_branching_rule(MostInfeasible())
.with_node_selection_rule(BestBound())
.with_log_level(Info, Green)
)
)
.with_log_level(Info, Blue)
.with_log_frequency(1)
Expand Down
4 changes: 3 additions & 1 deletion lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ add_library(idol STATIC include/modeling/numericals.h include/containers/Optiona
src/modeling/numericals.cpp
include/optimizers/callbacks/SimpleRounding.h
src/optimizers/callbacks/SimpleRounding.cpp
src/modeling/expressions/operations/operators.cpp)
src/modeling/expressions/operations/operators.cpp
include/optimizers/callbacks/RENS.h
src/optimizers/callbacks/RENS.cpp)

find_package(OpenMP REQUIRED)
target_link_libraries(idol PUBLIC OpenMP::OpenMP_CXX)
Expand Down
55 changes: 55 additions & 0 deletions lib/include/optimizers/callbacks/RENS.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//
// Created by henri on 16.10.23.
//

#ifndef IDOL_RENS_H
#define IDOL_RENS_H

#include "CallbackFactory.h"
#include "Callback.h"
#include "optimizers/OptimizerFactory.h"

namespace idol::Heuristics {
class RENS;
}

class idol::Heuristics::RENS : public CallbackFactory {

std::unique_ptr<OptimizerFactory> m_optimizer_factory;
double m_minimum_ratio_of_integer_variables_to_fix = .5;
double m_minimum_ratio_of_variables_to_fix = .25;

RENS(const RENS& t_src);
public:
RENS() = default;

class Strategy : public Callback {
double m_minimum_ratio_of_integer_variables_to_fix;
double m_minimum_ratio_of_variables_to_fix;
std::unique_ptr<OptimizerFactory> m_optimizer_factory;
protected:
void operator()(CallbackEvent t_event) override;
public:
Strategy(double t_minimum_ratio_of_integer_variables_to_fix,
double t_minimum_ratio_of_variables_to_fix,
OptimizerFactory* t_optimizer_factory);
};

Callback *operator()() override {

auto* result = new Strategy(m_minimum_ratio_of_integer_variables_to_fix,
m_minimum_ratio_of_variables_to_fix,
m_optimizer_factory->clone());

return result;
}

[[nodiscard]] CallbackFactory *clone() const override {
return new RENS(*this);
}

RENS& with_optimizer(const OptimizerFactory& t_optimizer_factory);

};

#endif //IDOL_RENS_H
1 change: 1 addition & 0 deletions lib/include/optimizers/callbacks/SimpleRounding.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,5 @@ class idol::Heuristics::SimpleRounding : public CallbackFactory {
}

};

#endif //IDOL_SIMPLEROUNDING_H
84 changes: 84 additions & 0 deletions lib/src/optimizers/callbacks/RENS.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
//
// Created by henri on 16.10.23.
//
#include "optimizers/callbacks/RENS.h"
#include "modeling/models/Model.h"

idol::Heuristics::RENS::RENS(const RENS& t_src)
: m_optimizer_factory(t_src.m_optimizer_factory->clone()),
m_minimum_ratio_of_variables_to_fix(t_src.m_minimum_ratio_of_variables_to_fix),
m_minimum_ratio_of_integer_variables_to_fix(t_src.m_minimum_ratio_of_integer_variables_to_fix)
{

}

idol::Heuristics::RENS &idol::Heuristics::RENS::with_optimizer(const idol::OptimizerFactory& t_optimizer_factory) {

if (m_optimizer_factory) {
throw Exception("An optimizer for RENS has already been given.");
}

m_optimizer_factory.reset(t_optimizer_factory.clone());

return *this;
}

idol::Heuristics::RENS::Strategy::Strategy(double t_minimum_ratio_of_integer_variables_to_fix,
double t_minimum_ratio_of_variables_to_fix,
OptimizerFactory* t_optimizer_factory)
: m_minimum_ratio_of_integer_variables_to_fix(t_minimum_ratio_of_integer_variables_to_fix),
m_minimum_ratio_of_variables_to_fix(t_minimum_ratio_of_variables_to_fix),
m_optimizer_factory(t_optimizer_factory) {

}

void idol::Heuristics::RENS::Strategy::operator()(idol::CallbackEvent t_event) {

if (t_event != InvalidSolution) {
return;
}

const auto& primal_solution = this->primal_solution();

std::unique_ptr<Model> model(original_model().clone());

model->unuse();

unsigned int n_fixed_variables = 0;
unsigned int n_integer_variables = 0;
for (const auto& var : model->vars()) {

if (model->get_var_type(var) == Continuous) {
continue;
}

++n_integer_variables;

const double value = primal_solution.get(var);

if (is_integer(value, Tolerance::Integer)) {
++n_fixed_variables;
}

model->set_var_lb(var, std::floor(value));
model->set_var_ub(var, std::ceil(value));

}

if (n_fixed_variables < m_minimum_ratio_of_integer_variables_to_fix * n_integer_variables
|| n_fixed_variables < m_minimum_ratio_of_variables_to_fix * model->vars().size() ) {
return;
}

model->use(*m_optimizer_factory);

model->optimize();

if (const auto status = model->get_status() ; status != Optimal && status != Feasible) {
return;
}

submit_heuristic_solution(save_primal(*model));

}

0 comments on commit fd39bd2

Please sign in to comment.