Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Ant-2380] improving maintainability #965

Merged
merged 20 commits into from
Nov 26, 2024
Merged
2 changes: 1 addition & 1 deletion docs/user-guide/get-started/adequacy-criterion.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,5 @@ Several log files are written:

- `reportbenders.txt` gives information on the progress of the algorithm with an operational perspective,
- `benders_solver.log` contains more detailed information on all data of interest to follow the progress of the algorithm (`lambda_min`, `lambda_max`, detailed solving times, ...).
- The file `criterions.txt` under `lp/` dir stores adequacy criterions for all valid patterns (area+criterion)
- The file `LOLD.txt` under `lp/` dir stores adequacy criteria for all valid patterns (area+criterion)
- The file `PositiveUnsuppliedEnergy.txt` under `lp/` dir stores the amount of unsupplied energy for all valid patterns (area+criterion)
2 changes: 1 addition & 1 deletion src/cpp/benders/benders_by_batch/BendersByBatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ void BendersByBatch::SeparationLoop() {
SolveBatches();

if (Rank() == rank_0) {
outer_loop_criterion_.push_back(_data.outer_loop_current_iteration_data.outer_loop_criterion);
criteria_vector_for_each_iteration_.push_back(_data.criteria_current_iteration_data.criteria);
// TODO
// UpdateOuterLoopMaxCriterionArea();
UpdateTrace();
Expand Down
58 changes: 28 additions & 30 deletions src/cpp/benders/benders_core/BendersBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,6 @@ BendersBase::BendersBase(const BendersBaseOptions &options, Logger logger,
mathLoggerDriver_(std::move(mathLoggerDriver)) {
}

std::filesystem::path BendersBase::OuterloopOptionsFile() const {
return std::filesystem::path(_options.INPUTROOT) /
_options.EXTERNAL_LOOP_OPTIONS.OUTER_LOOP_OPTION_FILE;
}

/*!
* \brief Initialize set of data used in the loop
*/
Expand All @@ -47,7 +42,7 @@ void BendersBase::init_data() {
_data.iteration_time = 0;
_data.timer_master = 0;
_data.subproblems_walltime = 0;
outer_loop_criterion_.clear();
criteria_vector_for_each_iteration_.clear();
}

void BendersBase::OpenCsvFile() {
Expand Down Expand Up @@ -173,10 +168,10 @@ void BendersBase::update_best_ub() {
_data.best_ub = _data.ub;
_data.best_it = _data.it;
FillWorkerMasterData(relevantIterationData_.best);
_data.outer_loop_current_iteration_data.max_criterion_best_it =
_data.outer_loop_current_iteration_data.max_criterion;
_data.outer_loop_current_iteration_data.max_criterion_area_best_it =
_data.outer_loop_current_iteration_data.max_criterion_area;
_data.criteria_current_iteration_data.max_criterion_best_it =
_data.criteria_current_iteration_data.max_criterion;
_data.criteria_current_iteration_data.max_criterion_area_best_it =
_data.criteria_current_iteration_data.max_criterion_area;
relevantIterationData_.best._cut_trace = relevantIterationData_.last._cut_trace;
best_iteration_data = bendersDataToLogData(_data);
}
Expand Down Expand Up @@ -417,7 +412,7 @@ void BendersBase::SetSubproblemsVariablesIndices() {
if (!subproblem_map.empty()) {
auto subproblem = subproblem_map.begin();

criterions_computation_->SearchVariables(
criterion_computation_.SearchVariables(
subproblem->second->_solver->get_col_names());
}
}
Expand Down Expand Up @@ -539,7 +534,7 @@ void BendersBase::SaveCurrentOuterLoopIterationInOutputFile() const {
if (LastWorkerMasterData._valid) {
_writer->write_iteration(
iteration(LastWorkerMasterData),
_data.outer_loop_current_iteration_data.benders_num_run);
_data.criteria_current_iteration_data.benders_num_run);
_writer->dump();
}
}
Expand Down Expand Up @@ -599,7 +594,7 @@ Output::SolutionData BendersBase::solution() const {
void BendersBase::UpdateOuterLoopSolution() {
outer_loop_solution_data_ = BendersSolution();
outer_loop_solution_data_.best_it =
_data.outer_loop_current_iteration_data.benders_num_run;
_data.criteria_current_iteration_data.benders_num_run;
}

Output::SolutionData BendersBase::GetOuterLoopSolution() const {
Expand Down Expand Up @@ -1000,39 +995,40 @@ WorkerMasterData BendersBase::BestIterationWorkerMaster() const {
CurrentIterationData BendersBase::GetCurrentIterationData() const {
return _data;
}
OuterLoopCurrentIterationData BendersBase::GetOuterLoopData() const {
return _data.outer_loop_current_iteration_data;
CriteriaCurrentIterationData BendersBase::GetOuterLoopData() const {
return _data.criteria_current_iteration_data;
}
std::vector<double> BendersBase::GetOuterLoopCriterionAtBestBenders() const {
return ((outer_loop_criterion_.empty())
return ((criteria_vector_for_each_iteration_.empty())
? std::vector<double>()
: outer_loop_criterion_[_data.best_it - 1]);
: criteria_vector_for_each_iteration_[_data.best_it - 1]);
}

void BendersBase::init_data(double external_loop_lambda,
double external_loop_lambda_min,
double external_loop_lambda_max) {
benders_timer.restart();
auto benders_num_run =
_data.outer_loop_current_iteration_data.benders_num_run;
_data.criteria_current_iteration_data.benders_num_run;
auto outer_loop_bilevel_best_ub =
_data.outer_loop_current_iteration_data.outer_loop_bilevel_best_ub;
_data.criteria_current_iteration_data.outer_loop_bilevel_best_ub;
init_data();
_data.outer_loop_current_iteration_data.outer_loop_criterion.clear();
_data.outer_loop_current_iteration_data.benders_num_run = benders_num_run;
_data.outer_loop_current_iteration_data.outer_loop_bilevel_best_ub =
_data.criteria_current_iteration_data.criteria.clear();
_data.criteria_current_iteration_data.benders_num_run = benders_num_run;
_data.criteria_current_iteration_data.outer_loop_bilevel_best_ub =
outer_loop_bilevel_best_ub;
_data.outer_loop_current_iteration_data.external_loop_lambda =
_data.criteria_current_iteration_data.lambda =
external_loop_lambda;
_data.outer_loop_current_iteration_data.external_loop_lambda_min =
_data.criteria_current_iteration_data.lambda_min =
external_loop_lambda_min;
_data.outer_loop_current_iteration_data.external_loop_lambda_max =
_data.criteria_current_iteration_data.lambda_max =
external_loop_lambda_max;
}



bool BendersBase::isExceptionRaised() const { return exception_raised_; }

/*
* after the 1st loop of the outer loop, we must re-build the objective
* function and costs
Expand All @@ -1046,12 +1042,14 @@ void BendersBase::UpdateOverallCosts() {

relevantIterationData_.best._invest_cost = _data.invest_cost;
}

void BendersBase::SetBilevelBestub(double bilevel_best_ub) {
_data.outer_loop_current_iteration_data.outer_loop_bilevel_best_ub =
_data.criteria_current_iteration_data.outer_loop_bilevel_best_ub =
bilevel_best_ub;
}
void BendersBase::setCriterionsComputation(
std::shared_ptr<Benders::Criterion::CriterionComputation>
criterionsComputation) {
criterions_computation_ = criterionsComputation;

void BendersBase::setCriterionComputationInputs(
const Benders::Criterion::CriterionInputData &criterion_input_data) {
criterion_computation_ =
Benders::Criterion::CriterionComputation(criterion_input_data);
}
14 changes: 7 additions & 7 deletions src/cpp/benders/benders_core/BendersMathLogger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,29 +216,29 @@ void PrintExternalLoopData(LogDestination& log_destination,
const HEADERSTYPE& type,
const BENDERSMETHOD& method) {
log_destination.InsertDelimiter();
log_destination << data.outer_loop_current_iteration_data.benders_num_run;
log_destination << data.criteria_current_iteration_data.benders_num_run;
log_destination.InsertDelimiter();
log_destination << std::scientific << std::setprecision(10)
<< data.outer_loop_current_iteration_data.max_criterion;
<< data.criteria_current_iteration_data.max_criterion;
log_destination.InsertDelimiter();
log_destination << data.outer_loop_current_iteration_data.max_criterion_area;
log_destination << data.criteria_current_iteration_data.max_criterion_area;
log_destination.InsertDelimiter();

log_destination
<< std::scientific << std::setprecision(10)
<< data.outer_loop_current_iteration_data.outer_loop_bilevel_best_ub;
<< data.criteria_current_iteration_data.outer_loop_bilevel_best_ub;
log_destination.InsertDelimiter();
log_destination
<< std::scientific << std::setprecision(10)
<< data.outer_loop_current_iteration_data.external_loop_lambda;
<< data.criteria_current_iteration_data.lambda;
log_destination.InsertDelimiter();
log_destination
<< std::scientific << std::setprecision(10)
<< data.outer_loop_current_iteration_data.external_loop_lambda_min;
<< data.criteria_current_iteration_data.lambda_min;
log_destination.InsertDelimiter();
log_destination
<< std::scientific << std::setprecision(10)
<< data.outer_loop_current_iteration_data.external_loop_lambda_max;
<< data.criteria_current_iteration_data.lambda_max;
PrintBendersData(log_destination, data, type, method);
}
void MathLoggerBaseExternalLoop::Print(const CurrentIterationData& data) {
Expand Down
7 changes: 4 additions & 3 deletions src/cpp/benders/benders_core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ target_sources(benders_core PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/WorkerMaster.cpp
${CMAKE_CURRENT_SOURCE_DIR}/common.cpp
${CMAKE_CURRENT_SOURCE_DIR}/CriterionComputation.cpp
${CMAKE_CURRENT_SOURCE_DIR}/OuterLoopInputDataReader.cpp
${CMAKE_CURRENT_SOURCE_DIR}/CriterionInputDataReader.cpp
${CMAKE_CURRENT_SOURCE_DIR}/VariablesGroup.cpp
${CMAKE_CURRENT_SOURCE_DIR}/CouplingMapGenerator.cpp
${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/benders/benders_core/BendersBase.h
${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/benders/benders_core/BendersMathLogger.h
${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/benders/benders_core/BendersStructsDatas.h
Expand All @@ -41,13 +42,13 @@ target_sources(benders_core PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/benders/benders_core/WorkerMaster.h
${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/benders/benders_core/common.h
${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/benders/benders_core/CriterionComputation.h
${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/benders/benders_core/OuterLoopInputDataReader.h
${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/benders/benders_core/CriterionInputDataReader.h
${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/benders/benders_core/VariablesGroup.h
${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/benders/benders_core/CouplingMapGenerator.h
)

add_library(antaresXpansion::benders_core ALIAS benders_core)


target_include_directories(benders_core
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
Expand Down
52 changes: 52 additions & 0 deletions src/cpp/benders/benders_core/CouplingMapGenerator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#include <antares-xpansion/benders/benders_core/CouplingMapGenerator.h>
#include <antares-xpansion/xpansion_interfaces/LoggerUtils.h>

struct InvalidStructureFile : LogUtils::XpansionError<std::runtime_error> {
using LogUtils::XpansionError<std::runtime_error>::XpansionError;
};

/*!
* \brief Build the input from the structure file
*
* Function to build the map linking each problem name to its variables and
*their id
*
* \param root : root of the structure file
*
* \param summary_name : name of the structure file
*
* \param coupling_map : empty map to increment
*
* \note The id in the coupling_map is that of the variable in the solver
*responsible for the creation of the structure file.
*/
CouplingMap CouplingMapGenerator::BuildInput(
const std::filesystem::path& structure_path,
std::shared_ptr<ILoggerXpansion> logger, const std::string& context) {
CouplingMap coupling_map;
std::ifstream summary(structure_path, std::ios::in);
if (!summary) {
auto log_location = LOGLOCATION;
std::ostringstream msg;
msg << "Cannot open structure file " << structure_path << std::endl;
logger->display_message(msg.str(), LogUtils::LOGLEVEL::FATAL, log_location);
throw InvalidStructureFile(
PrefixMessage(LogUtils::LOGLEVEL::FATAL, context), msg.str(),
log_location);
}
std::string line;

while (std::getline(summary, line)) {
std::stringstream buffer(line);
std::string problem_name;
std::string variable_name;
int variable_id;
buffer >> problem_name;
buffer >> variable_name;
buffer >> variable_id;
coupling_map[problem_name][variable_name] = variable_id;
}

summary.close();
return coupling_map;
}
52 changes: 26 additions & 26 deletions src/cpp/benders/benders_core/CriterionComputation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,46 @@

namespace Benders::Criterion {

void CriterionComputation::ComputeOuterLoopCriterion(
void CriterionComputation::ComputeCriterion(
double subproblem_weight, const std::vector<double> &sub_problem_solution,
std::vector<double> &outerLoopCriterions,
std::vector<double> &outerLoopPatternsValues) {
auto outer_loop_input_size = var_indices_.size(); // num of patterns
outerLoopCriterions.resize(outer_loop_input_size, 0.);
outerLoopPatternsValues.resize(outer_loop_input_size, 0.);

double criterion_count_threshold =
outer_loop_input_data_.CriterionCountThreshold();

for (int pattern_index(0); pattern_index < outer_loop_input_size;
++pattern_index) {
auto pattern_variables_indices = var_indices_[pattern_index];
for (auto variables_index : pattern_variables_indices) {
const auto &solution = sub_problem_solution[variables_index];
outerLoopPatternsValues[pattern_index] += solution;
if (solution > criterion_count_threshold)
// 1h of no supplied energy
outerLoopCriterions[pattern_index] += subproblem_weight;
std::vector<double> &criteria,
std::vector<double> &patterns_values) {
auto criteria_input_size = var_indices_.size(); // num of patterns
criteria.resize(criteria_input_size, 0.);
patterns_values.resize(criteria_input_size, 0.);

double criterion_count_threshold =
criterion_input_data_.CriterionCountThreshold();

for (int pattern_index(0); pattern_index < criteria_input_size;
++pattern_index) {
auto pattern_variables_indices = var_indices_[pattern_index];
for (auto variables_index: pattern_variables_indices) {
const auto &solution = sub_problem_solution[variables_index];
patterns_values[pattern_index] += solution;
if (solution > criterion_count_threshold)
// 1h of no supplied energy
criteria[pattern_index] += subproblem_weight;
}
}
}
}

void CriterionComputation::SearchVariables(
const std::vector<std::string> &variables) {
Benders::Criterion::VariablesGroup variablesGroup(
variables, outer_loop_input_data_.OuterLoopData());
variables, criterion_input_data_.Criteria());
var_indices_ = variablesGroup.Indices();
}

const OuterLoopInputData &CriterionComputation::getOuterLoopInputData() const {
return outer_loop_input_data_;
const CriterionInputData &CriterionComputation::getCriterionInputData() const {
return criterion_input_data_;
}

std::vector<std::vector<int>> &CriterionComputation::getVarIndices() {
return var_indices_;
}
CriterionComputation::CriterionComputation(
const OuterLoopInputData &outer_loop_input_data)
: outer_loop_input_data_(outer_loop_input_data) {}

const CriterionInputData &criterion_input_data)
: criterion_input_data_(criterion_input_data) {
}
} // namespace Benders::Criterion
Loading
Loading