Antares Xpansion
Investment simulations for Antares studies
Loading...
Searching...
No Matches
BendersBase.h
1#pragma once
2
3#include <execution>
4#include <filesystem>
5#include <optional>
6#include <regex>
7#include <tbb/tbb.h>
8
9#include "BendersMathLogger.h"
10#include "BendersStructsDatas.h"
11#include "CriterionComputation.h"
12#include "SimulationOptions.h"
13#include "SubproblemCut.h"
14#include "SubproblemWorker.h"
15#include "Worker.h"
16#include "WorkerMaster.h"
17#include "antares-xpansion/helpers/Timer.h"
18#include "antares-xpansion/xpansion_interfaces/ILogger.h"
19#include "common.h"
20
26template<class lambda>
27auto selectPolicy(lambda f, bool shouldParallelize)
28{
29 if (shouldParallelize)
30 {
31 return f(std::execution::par_unseq);
32 }
33 else
34 {
35 return f(std::execution::seq);
36 }
37}
38
40{
41public:
42 virtual ~BendersBase() = default;
44 Logger logger,
45 std::shared_ptr<Output::OutputWriter> writer,
46 std::shared_ptr<MathLoggerDriver> mathLoggerDriver);
47 virtual void launch() = 0;
48 void set_solver_log_file(const std::filesystem::path& log_file);
49
50 [[nodiscard]] std::filesystem::path solver_log_file() const
51 {
52 return solver_log_file_;
53 }
54
55 double execution_time() const;
56 virtual std::string BendersName() const = 0;
57 // TODO rename to be consistent with data that it hold
58 // ref of value?
59 WorkerMasterDataVect AllCuts() const;
60 // BendersCuts CutsBestIteration() const;
61 // void Clean();
62 LogData GetBestIterationData() const;
63 void set_input_map(const CouplingMap& coupling_map);
64 int MasterRowIndex(const std::string& row_name) const;
65 void MasterChangeRhs(int id_row, double val) const;
66 // for test
67 void MasterGetRhs(double& rhs, int id_row) const;
68
69 const VariableMap& MasterVariables() const
70 {
71 return master_variable_map_;
72 }
73
74 std::vector<double> MasterObjectiveFunctionCoeffs() const;
75 void MasterRowsCoeffs(std::vector<int>& mstart,
76 std::vector<int>& mclind,
77 std::vector<double>& dmatval,
78 int size,
79 std::vector<int>& nels,
80 int first,
81 int last) const;
82 int MasterGetNElems() const;
83 void MasterAddRows(const std::vector<char>& qrtype_p,
84 const std::vector<double>& rhs_p,
85 const std::vector<double>& range_p,
86 const std::vector<int>& mstart_p,
87 const std::vector<int>& mclind_p,
88 const std::vector<double>& dmatval_p,
89 const std::vector<std::string>& row_names = {}) const;
90 void MasterGetRowType(std::vector<char>& qrtype, int first, int last) const;
91 void ResetMasterFromLastIteration();
92 std::filesystem::path LastMasterPath() const;
93 bool MasterIsEmpty() const;
94
95 void DoFreeProblems(bool free_problems)
96 {
97 free_problems_ = free_problems;
98 }
99
100 int MasterGetnrows() const;
101 int MasterGetncols() const;
102 WorkerMasterData BestIterationWorkerMaster() const;
103 void SetMasterObjectiveFunctionCoeffsToZeros() const;
104 void SetMasterObjectiveFunction(const double* coeffs, int first, int last) const;
105 virtual void InitializeProblems() = 0;
106
107 void SetMaxIteration(int max_iteration)
108 {
109 _options.MAX_ITERATIONS = max_iteration;
110 }
111
112 BendersBaseOptions Options() const
113 {
114 return _options;
115 }
116
117 virtual void free() = 0;
118
119 int GetBendersRunNumber() const
120 {
121 return _data.criteria_current_iteration_data.benders_num_run;
122 }
123
124 CurrentIterationData GetCurrentIterationData() const;
125
126 CriteriaCurrentIterationData GetOuterLoopData() const;
127
128 std::vector<double> GetOuterLoopCriterionAtBestBenders() const;
129 virtual void init_data();
130 void init_data(double external_loop_lambda,
131 double external_loop_lambda_min,
132 double external_loop_lambda_max);
133 Output::SolutionData GetOuterLoopSolution() const;
134 void SaveOuterLoopSolutionInOutputFile() const;
135 void SaveCurrentOuterLoopIterationInOutputFile() const;
136 void SetBilevelBestub(double bilevel_best_ub);
137 void UpdateOuterLoopSolution();
138
139 bool isExceptionRaised() const;
140 void UpdateOverallCosts();
141 Logger _logger;
142 std::shared_ptr<Output::OutputWriter> _writer;
143 std::shared_ptr<MathLoggerDriver> mathLoggerDriver_;
144 void setCriterionComputationInputs(
145 const Benders::Criterion::CriterionInputData& criterion_input_data);
146
147protected:
148 bool exception_raised_ = false;
150 WorkerMasterDataVect workerMasterDataVect_;
151 // BendersCuts best_iteration_cuts_;
152 // BendersCuts current_iteration_cuts_;
153 VariableMap master_variable_map_;
154 CouplingMap coupling_map_;
156 bool init_data_ = true;
157 bool init_problems_ = true;
158 bool free_problems_ = true;
159
160 std::vector<std::vector<double>> criteria_vector_for_each_iteration_;
161 bool is_bilevel_check_all_ = false;
162
163 virtual void Run() = 0;
164 void update_best_ub();
165 bool ShouldBendersStop();
166 bool is_initial_relaxation_requested() const;
167 bool SwitchToIntegerMaster(bool is_relaxed) const;
168 virtual void UpdateTrace();
169 virtual void ComputeXCut();
170 void ComputeInvestCost();
171 virtual void compute_ub();
172 virtual void get_master_value();
173 void GetSubproblemCut(SubProblemDataMap& subproblem_data_map);
174 virtual void post_run_actions() const;
175 void BuildCutFull(const SubProblemDataMap& subproblem_data_map);
176 virtual void DeactivateIntegrityConstraints() const;
177 virtual void ActivateIntegrityConstraints() const;
178 virtual void SetDataPreRelaxation();
179 virtual void ResetDataPostRelaxation();
180 [[nodiscard]] std::filesystem::path GetSubproblemPath(const std::string& subproblem_name) const;
181 [[nodiscard]] double SubproblemWeight(int subproblem_count, const std::string& name) const;
182 [[nodiscard]] std::filesystem::path get_master_path() const;
183 [[nodiscard]] std::filesystem::path get_structure_path() const;
184 [[nodiscard]] LogData bendersDataToLogData(const CurrentIterationData& data) const;
185
186 template<typename T, typename... Args>
187 void reset_master(Args&&... args)
188 {
189 _master = std::make_shared<T>(std::forward<Args>(args)...);
190 master_is_empty_ = false;
191 }
192
193 void free_master();
194 void free_subproblems();
195 void AddSubproblem(const std::pair<std::string, VariableMap>& kvp);
196 [[nodiscard]] virtual WorkerMasterPtr get_master() const;
197 void MatchProblemToId();
198 void AddSubproblemName(const std::string& name);
199 [[nodiscard]] std::string get_master_name() const;
200 [[nodiscard]] std::string get_solver_name() const;
201 [[nodiscard]] int get_log_level() const;
202 [[nodiscard]] bool is_trace() const;
203 [[nodiscard]] Point get_x_cut() const;
204 void set_x_cut(const Point& x0);
205 [[nodiscard]] Point get_x_out() const;
206 void set_x_out(const Point& x0);
207 [[nodiscard]] double GetSubproblemCost() const;
208 void SetSubproblemCost(const double& subproblem_cost);
209 bool IsResumeMode() const;
210
211 std::filesystem::path LastIterationFile() const
212 {
213 return std::filesystem::path(_options.LAST_ITERATION_JSON_FILE);
214 }
215
216 void UpdateMaxNumberIterationResumeMode(int nb_iteration_done);
217 void SaveCurrentIterationInOutputFile() const;
218 void SaveSolutionInOutputFile() const;
219 void PrintCurrentIterationCsv();
220 void OpenCsvFile();
221 void CloseCsvFile();
222 void ChecksResumeMode();
223 virtual void SaveCurrentBendersData();
224 void ClearCurrentIterationCutTrace();
225 virtual void EndWritingInOutputFile() const;
226
227 [[nodiscard]] int GetNumIterationsBeforeRestart() const
228 {
229 return iterations_before_resume;
230 }
231
232 double GetBendersTime() const;
233 virtual void write_basis() const;
234
235 // SubproblemsMapPtr GetSubProblemsMapPtr() { return subproblem_map; }
236 SubproblemsMapPtr GetSubProblemMap() const
237 {
238 return subproblem_map;
239 }
240
241 StrVector GetSubProblemNames() const
242 {
243 return subproblems;
244 }
245
246 double AbsoluteGap() const
247 {
248 return _options.ABSOLUTE_GAP;
249 }
250
251 double RelativeGap() const
252 {
253 return _options.RELATIVE_GAP;
254 }
255
256 double RelaxedGap() const
257 {
258 return _options.RELAXED_GAP;
259 }
260
261 DblVector GetAlpha_i() const
262 {
263 return _data.single_subpb_costs_under_approx;
264 }
265
266 void SetAlpha_i(const DblVector& single_subpb_costs_under_approx)
267 {
268 _data.single_subpb_costs_under_approx = single_subpb_costs_under_approx;
269 }
270
271 int ProblemToId(const std::string& problem_name) const
272 {
273 return _problem_to_id.at(problem_name);
274 }
275
276 virtual void UpdateStoppingCriterion();
277 virtual bool ShouldRelaxationStop() const;
278
279 int GetNumOfSubProblemsSolvedBeforeResume()
280 {
281 return cumulative_number_of_subproblem_resolved_before_resume;
282 }
283
284 void BoundSimplexIterations(int subproblem_iteration);
285 void ResetSimplexIterationsBounds();
286
287 SubproblemsMapPtr subproblem_map;
288 SolverLogManager solver_log_manager_;
289
290 virtual void SolveSubproblem(PlainData::SubProblemData& subproblem_data,
291 const std::string& name,
292 const std::shared_ptr<SubproblemWorker>& worker);
293
294 Benders::Criterion::CriterionComputation criterion_computation_;
304 // Search for variables in sub problems that satisfy patterns
305 // var_indices is a vector(for each patterns p) of vector (var indices related
306 // to p)
308
309private:
310 void print_master_and_cut(std::ostream& file,
311 int ite,
312 WorkerMasterData& trace,
313 const Point& xopt);
314 void print_master_csv(std::ostream& stream,
315 const WorkerMasterData& trace,
316 const Point& xopt) const;
317 void check_status(const SubProblemDataMap& subproblem_data_map) const;
318 [[nodiscard]] LogData build_log_data_from_data() const;
319 [[nodiscard]] Output::SolutionData solution() const;
320 [[nodiscard]] Output::SolutionData BendersSolution() const;
321 [[nodiscard]] std::string status_from_criterion() const;
322 void compute_cut_aggregate(const SubProblemDataMap& subproblem_data_map);
323 void compute_cut(const SubProblemDataMap& subproblem_data_map);
324 [[nodiscard]] std::map<std::string, int> get_master_variable_map(
325 const std::map<std::string, std::map<std::string, int>>& input_map) const;
326 [[nodiscard]] virtual bool shouldParallelize() const = 0;
327 Output::Iteration iteration(const WorkerMasterData& masterDataPtr_l) const;
328 LogData FinalLogData() const;
329 void FillWorkerMasterData(WorkerMasterData& workerMasterData);
330 bool master_is_empty_ = true;
331 BendersBaseOptions _options;
332 int _totalNbProblems = 0;
333 std::filesystem::path solver_log_file_ = "";
334 WorkerMasterPtr _master;
335 VariableMap _problem_to_id;
336 StrVector subproblems;
337 std::ofstream _csv_file;
338 std::filesystem::path _csv_file_path;
339 LogData best_iteration_data;
340 int iterations_before_resume = 0;
341 int cumulative_number_of_subproblem_resolved_before_resume = 0;
342 Timer benders_timer;
343 Output::SolutionData outer_loop_solution_data_;
344};
345
346using pBendersBase = std::shared_ptr<BendersBase>;
Definition BendersBase.h:40
std::filesystem::path GetSubproblemPath(const std::string &subproblem_name) const
Get path to subproblem mps file from options.
Definition BendersBase.cpp:764
virtual void get_master_value()
Solve and get optimal variables of the Master Problem.
Definition BendersBase.cpp:343
void BoundSimplexIterations(int subproblem_iteration)
Definition BendersBase.cpp:970
virtual void UpdateStoppingCriterion()
Update stopping criterion.
Definition BendersBase.cpp:223
void GetSubproblemCut(SubProblemDataMap &subproblem_data_map)
Solve and store optimal variables of all Subproblem Problems.
Definition BendersBase.cpp:428
void SetSubproblemsVariablesIndices()
Definition BendersBase.cpp:479
virtual void init_data()
Initialize set of data used in the loop.
Definition BendersBase.cpp:30
std::filesystem::path get_master_path() const
Get path to master problem mps file from options.
Definition BendersBase.cpp:796
void set_input_map(const CouplingMap &coupling_map)
set the input
Definition BendersBase.cpp:844
virtual bool ShouldRelaxationStop() const
Check if initial relaxation should stop.
Definition BendersBase.cpp:211
double SubproblemWeight(int subproblem_count, const std::string &name) const
Return subproblem weight value.
Definition BendersBase.cpp:776
virtual void UpdateTrace()
Update trace of the Benders for the current iteration.
Definition BendersBase.cpp:274
void update_best_ub()
Update best upper bound and best optimal variables.
Definition BendersBase.cpp:191
void BuildCutFull(const SubProblemDataMap &subproblem_data_map)
Add cuts in master problem.
Definition BendersBase.cpp:559
Definition CriterionComputation.h:10
this class contains all data read from user input file
Definition CriterionInputDataReader.h:84
Definition SolverAbstract.h:17
Definition Timer.h:10
Class use to store trace information during the algorithm run.
Definition BendersStructsDatas.h:75
Definition launch.py:1
Definition common.h:208
Definition BendersStructsDatas.h:101
Definition BendersStructsDatas.h:9
Definition BendersStructsDatas.h:27
Definition ILogger.h:51
Definition OutputWriter.h:40
struct saves some entries to be later written to the json file
Definition OutputWriter.h:64
Definition SubproblemCut.h:12