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