Skip to content

Commit

Permalink
Round subproblem subgradient to avoid master numerical issues
Browse files Browse the repository at this point in the history
  • Loading branch information
tbittar committed Jan 16, 2025
1 parent 8dc6041 commit 61f98ed
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 10 deletions.
8 changes: 3 additions & 5 deletions src/cpp/benders/benders_core/BendersBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -454,8 +454,8 @@ void compute_cut_val(const Point &var_name_subgradient, const Point &x_cut,
* Method to add aggregated cut from subproblems to Master Problem and store
* it in a map linking each subproblem to its set of non-aggregated cut
*
* \param all_package : vector storing all cuts information for each
* subproblem problem
* \param subproblem_data_map : map storing all cuts information for each
* subproblem
*/
void BendersBase::compute_cut_aggregate(
const SubProblemDataMap &subproblem_data_map) {
Expand All @@ -476,9 +476,7 @@ void BendersBase::compute_cut_aggregate(
/*!
* \brief Add cuts in master problem
*
* Add cuts in master problem according to the selected option
*
* \param all_package : storage of every subproblem information
* \param subproblem_data_map : storage of every subproblem information
*/
void BendersBase::BuildCutFull(const SubProblemDataMap &subproblem_data_map) {
check_status(subproblem_data_map);
Expand Down
10 changes: 10 additions & 0 deletions src/cpp/benders/benders_core/SubproblemWorker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,15 @@ void SubproblemWorker::fix_to(Point const &x0) const {
solver_chgbounds(_solver, indexes, bndtypes, values);
}

static double INTTOL = 1e-4;
void SubproblemWorker::roundIfWithinTolerance(std::vector<double> &values,
double tolerance) const {
std::transform(values.begin(), values.end(), values.begin(),
[tolerance](double value) -> double {
return std::abs(value) < tolerance ? 0 : value;
});
}

/*!
* \brief Get LP solution value of a problem
*
Expand All @@ -62,6 +71,7 @@ void SubproblemWorker::get_subgradient(Point &s) const {
s.clear();
std::vector<double> ptr(_solver->get_ncols());
solver_getlpreducedcost(_solver, ptr);
roundIfWithinTolerance(ptr, INTTOL);
for (auto const &kvp : _id_to_name) {
s[kvp.second] = +ptr[kvp.first];
}
Expand Down
6 changes: 3 additions & 3 deletions src/cpp/benders/benders_core/WorkerMaster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ WorkerMaster::WorkerMaster(VariableMap const &variable_map,

// Tolerance to which a value is considered zero or integral
// TODO : Allow to parametrize this constant from the options file
int INTTOL = 1e-6;
static double INTTOL = 1e-4;
void WorkerMaster::roundXVarIfWithinTolerance(std::vector<double> &values,
double tolerance) {
int nb_candidates = _id_to_name.size();
Expand All @@ -64,10 +64,10 @@ void WorkerMaster::roundXVarIfWithinTolerance(std::vector<double> &values,
values[kvp.first] = lb[kvp.first];
}
// Case integer variable
else if (col_type[kvp.first] == 'I') {
else if (col_type[kvp.first] == 'B' || col_type[kvp.first] == 'I') {
int rounded = std::round(value);
values[kvp.first] =
std::abs(value - std::round(value)) <= tolerance ? rounded : value;
std::abs(value - std::round(value)) < tolerance ? rounded : value;
}
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ class SubproblemWorker : public Worker {
SubproblemWorker(VariableMap const &variable_map,
const std::filesystem::path &path_to_mps,
double const &slave_weight, const std::string &solver_name,
const int log_level,
SolverLogManager&solver_log_manager,
const int log_level, SolverLogManager &solver_log_manager,
Logger logger);
virtual ~SubproblemWorker() = default;
void get_solution(std::vector<double> &solution) const;
void roundIfWithinTolerance(std::vector<double> &values,
double tolerance) const;

public:
void fix_to(Point const &x0) const;
Expand Down

0 comments on commit 61f98ed

Please sign in to comment.