Antares Xpansion
Investment simulations for Antares studies
Loading...
Searching...
No Matches
SolverAbstract.h
1#pragma once
2
3#include <cstdio>
4#include <filesystem>
5#include <iomanip>
6#include <iostream>
7#include <list>
8#include <memory>
9#include <mutex>
10#include <shared_mutex>
11#include <span>
12#include <sstream>
13#include <stdexcept>
14#include <string>
15#include <vector>
16
17#include "antares-xpansion/xpansion_interfaces/LogUtils.h"
18
20{
21public:
22 explicit SolverLogManager() = default;
23
24 explicit SolverLogManager(const SolverLogManager& other):
25 SolverLogManager(other.log_file_path)
26 {
27 }
28
29 explicit SolverLogManager(const std::filesystem::path& log_file):
30 log_file_path(log_file)
31 {
32 init();
33 }
34
35 SolverLogManager& operator=(const SolverLogManager& other)
36 {
37 if (this == &other)
38 {
39 return *this;
40 }
41 log_file_path = other.log_file_path;
42 init();
43 return *this;
44 }
45
46 void init()
47 {
48#ifdef __linux__
49 if (log_file_path.empty()
50 || (log_file_ptr = fopen(log_file_path.string().c_str(), "a+")) == nullptr)
51#elif _WIN32
52 if (log_file_path.empty()
53 || (log_file_ptr = _fsopen(log_file_path.string().c_str(), "a+", _SH_DENYNO))
54 == nullptr)
55#endif
56 {
57 std::cout << "Invalid log file name passed as parameter: "
58 << std::quoted(log_file_path.string()) << std::endl;
59 }
60 else
61 {
62 setvbuf(log_file_ptr, nullptr, _IONBF, 0);
63 }
64 }
65
66 virtual ~SolverLogManager()
67 {
68 if (log_file_ptr)
69 {
70 fclose(log_file_ptr);
71 log_file_ptr = nullptr;
72 }
73 }
74
75 FILE* log_file_ptr = nullptr;
76 std::filesystem::path log_file_path = "";
77};
78
79class InvalidStatusException: public LogUtils::XpansionError<std::runtime_error>
80{
81public:
82 InvalidStatusException(int status, const std::string& action, const std::string& log_message):
83 LogUtils::XpansionError<std::runtime_error>("Failed to " + action + ": invalid status "
84 + std::to_string(status) + " (0 expected)",
85 log_message)
86 {
87 }
88};
89
90class InvalidRowSizeException: public LogUtils::XpansionError<std::runtime_error>
91{
92public:
93 InvalidRowSizeException(int expected_size, int actual_size, const std::string& log_location):
94 LogUtils::XpansionError<std::runtime_error>(
95 "Invalid row size for solver. " + std::to_string(actual_size) + " rows available ("
96 + std::to_string(expected_size) + " expected)",
97 log_location)
98 {
99 }
100};
101
102class InvalidColSizeException: public LogUtils::XpansionError<std::runtime_error>
103{
104public:
105 InvalidColSizeException(int expected_size, int actual_size, const std::string& log_location):
106 LogUtils::XpansionError<std::runtime_error>(
107 "Invalid col size for solver. " + std::to_string(actual_size) + " cols available ("
108 + std::to_string(expected_size) + " expected)",
109 log_location)
110 {
111 }
112};
113
114class InvalidBoundTypeException: public LogUtils::XpansionError<std::runtime_error>
115{
116public:
117 InvalidBoundTypeException(char qbtype, const std::string& log_location):
118 LogUtils::XpansionError<std::runtime_error>(std::string("Invalid bound type ") + qbtype
119 + " for solver.",
120 log_location)
121 {
122 }
123};
124
125class InvalidColTypeException: public LogUtils::XpansionError<std::runtime_error>
126{
127public:
128 InvalidColTypeException(char qctype, const std::string& log_location):
129 LogUtils::XpansionError<std::runtime_error>(std::string("Invalid col type ") + qctype
130 + " for solver.",
131 log_location)
132 {
133 }
134};
135
136class InvalidSolverOptionException: public LogUtils::XpansionError<std::runtime_error>
137{
138public:
139 InvalidSolverOptionException(const std::string& option, const std::string& log_location):
140 LogUtils::XpansionError<std::runtime_error>(std::string("Invalid option '") + option
141 + "' for solver.",
142 log_location)
143 {
144 }
145};
146
147class InvalidSolverForCopyException: public LogUtils::XpansionError<std::runtime_error>
148{
149public:
150 InvalidSolverForCopyException(const std::string& from_solver,
151 const std::string& to_solver,
152 const std::string& log_location):
153 LogUtils::XpansionError<std::runtime_error>("Can't copy " + from_solver + "solver from "
154 + to_solver,
155 log_location)
156 {
157 }
158};
159
160class InvalidSolverNameException: public LogUtils::XpansionError<std::runtime_error>
161{
162public:
163 InvalidSolverNameException(const std::string& solver_name, const std::string& log_location):
164 LogUtils::XpansionError<std::runtime_error>("Solver '" + solver_name + "' not supported",
165 log_location)
166 {
167 }
168};
169
170class GenericSolverException: public std::runtime_error
171{
172public:
173 explicit GenericSolverException(const std::string& message):
174 std::runtime_error(message)
175 {
176 }
177};
178
179class NotImplementedFeatureSolverException: public std::runtime_error
180{
181public:
182 explicit NotImplementedFeatureSolverException(const std::string& message):
183 std::runtime_error(message)
184 {
185 }
186};
187
188// Definition of optimality codes
189enum SOLVER_STATUS
190{
191 OPTIMAL,
192 INFEASIBLE,
193 UNBOUNDED,
194 INForUNBOUND,
195 UNKNOWN,
196};
197
203{
204public:
205 std::vector<std::string> SOLVER_STRING_STATUS = {"OPTIMAL",
206 "INFEASIBLE",
207 "UNBOUNDED",
208 "INForUNBOUND",
209 "UNKNOWN"};
210
211 /*************************************************************************************************
212 ---------------------------------------- ATTRIBUTES
213 ---------------------------------------
214 *************************************************************************************************/
215
216public:
217 std::string _name;
218 mutable std::list<std::ostream*>
221 /*************************************************************************************************
222 ----------------------------------- Constructor/Desctructor
223 --------------------------------
224 *************************************************************************************************/
225
226public:
230 virtual ~SolverAbstract() = default;
231 virtual SolverAbstract* clone() const = 0;
235 virtual int get_number_of_instances() = 0;
236
240 virtual std::string get_solver_name() const = 0;
241
242 /*************************************************************************************************
243 ----------------------------------- Output stream management
244 ------------------------------
245 *************************************************************************************************/
246
247public:
251 std::list<std::ostream*>& get_stream() const;
252
253 FILE* _fp = nullptr;
254 std::filesystem::path _log_file = "";
255
261 void add_stream(std::ostream& stream)
262 {
263 get_stream().push_back(&stream);
264 }
265
266 void set_fp(FILE* fp)
267 {
268 _fp = fp;
269 }
270
279 static void zero_status_check(int status,
280 const std::string& action_failed,
281 const std::string& log_location)
282 {
283 if (status != 0)
284 {
285 throw InvalidStatusException(status, action_failed, log_location);
286 }
287 }
288
289 /*************************************************************************************************
290 ------ Destruction or creation of inner strctures and datas, closing
291 environments ----------
292 *************************************************************************************************/
293
294public:
298 virtual void init() = 0;
299
303 virtual void free() = 0;
304
305 /*************************************************************************************************
306 ------------------------------- Reading & Writing problems
307 -------------------------------
308 *************************************************************************************************/
309
310public:
316 virtual void write_prob_mps(const std::filesystem::path& filename) = 0;
317
323 virtual void write_prob_lp(const std::filesystem::path& filename) = 0;
324
332 virtual void save_prob(const std::filesystem::path& filename) = 0;
333
340 virtual void write_basis(const std::filesystem::path& filename) = 0;
341
347 virtual void read_prob_mps(const std::filesystem::path& filename) = 0;
348
354 virtual void read_prob_lp(const std::filesystem::path& filename) = 0;
355
363 virtual void restore_prob(const std::filesystem::path& filename) = 0;
364
371 virtual void read_basis(const std::filesystem::path& filename) = 0;
372
373 virtual void set_basis(std::span<int> rstatus, std::span<int> cstatus) = 0;
374
375 /*************************************************************************************************
376 ----------------------- Get general informations about problem
377 ----------------------------
378 *************************************************************************************************/
379
380public:
384 virtual int get_ncols() const = 0;
385
389 virtual int get_nrows() const = 0;
390
395 virtual int get_nelems() const = 0;
396
400 virtual int get_n_integer_vars() const = 0;
401
406 virtual void get_obj(double* obj, int first, int last) const = 0;
407
411 virtual void set_obj_to_zero() = 0;
412
417 virtual void set_obj(const double* obj, int first, int last) = 0;
418
434 virtual void get_rows(int* mstart,
435 int* mclind,
436 double* dmatval,
437 int size,
438 int* nels,
439 int first,
440 int last) const
441 = 0;
442
451 virtual void get_row_type(char* qrtype, int first, int last) const = 0;
452
461 virtual void get_rhs(double* rhs, int first, int last) const = 0;
462
472 virtual void get_rhs_range(double* range, int first, int last) const = 0;
473
489 virtual void get_cols(int* mstart,
490 int* mrwind,
491 double* dmatval,
492 int size,
493 int* nels,
494 int first,
495 int last) const
496 = 0;
497
507 virtual void get_col_type(char* coltype, int first, int last) const = 0;
508
517 virtual void get_lb(double* lb, int fisrt, int last) const = 0;
518
527 virtual void get_ub(double* ub, int fisrt, int last) const = 0;
528
534 virtual int get_row_index(const std::string& name) = 0;
535
541 virtual int get_col_index(const std::string& name) = 0;
542
551 virtual std::vector<std::string> get_row_names(int first, int last) const = 0;
552
557 virtual std::vector<std::string> get_row_names() = 0;
558
567 virtual std::vector<std::string> get_col_names(int first, int last) const = 0;
568
573 virtual std::vector<std::string> get_col_names() = 0;
574
575 /*************************************************************************************************
576 ------------------------------ Methods to modify problem
577 ----------------------------------
578 *************************************************************************************************/
579
580public:
587 virtual void del_rows(int first, int last) = 0;
588
595 virtual void del_cols(int first, int last) = 0;
596
618 virtual void add_rows(int newrows,
619 int newnz,
620 const char* qrtype,
621 const double* rhs,
622 const double* range,
623 const int* mstart,
624 const int* mclind,
625 const double* dmatval,
626 const std::vector<std::string>& row_names)
627 = 0;
628
649 virtual void add_cols(int newcol,
650 int newnz,
651 const double* objx,
652 const int* mstart,
653 const int* mrwind,
654 const double* dmatval,
655 const double* bdl,
656 const double* bdu,
657 const std::vector<std::string>& col_names)
658 = 0;
659
668 virtual void add_name(int type, const char* cnames, int indice) = 0;
669
670 virtual void add_names(int type, const std::vector<std::string>& cnames, int first, int end)
671 = 0;
672
679 virtual void chg_obj(const std::vector<int>& mindex, const std::vector<double>& obj) = 0;
680
687 virtual void chg_obj_direction(const bool minimize) = 0;
688
698 virtual void chg_bounds(const std::vector<int>& mindex,
699 const std::vector<char>& qbtype,
700 const std::vector<double>& bnd)
701 = 0;
702
710 virtual void chg_col_type(const std::vector<int>& mindex, const std::vector<char>& qctype) = 0;
711
718 virtual void chg_rhs(int id_row, double val) = 0;
719
727 virtual void chg_coef(int id_row, int id_col, double val) = 0;
728
735 virtual void chg_row_name(int id_row, const std::string& name) = 0;
736
743 virtual void chg_col_name(int id_col, const std::string& name) = 0;
744
745 /*************************************************************************************************
746 ----------------------------- Methods to solve the problem
747 ---------------------------------
748 *************************************************************************************************/
749
750public:
756 virtual int solve_lp() = 0;
757
763 virtual int solve_mip() = 0;
764
765 /*************************************************************************************************
766 ------------------------- Methods to get solutions information
767 -----------------------------
768 *************************************************************************************************/
769
770public:
782 virtual void get_basis(int* rstatus, int* cstatus) const = 0;
783
790 virtual double get_mip_value() const = 0;
791
798 virtual double get_lp_value() const = 0;
799
807 virtual int get_splex_num_of_ite_last() const = 0;
808
816 virtual void get_lp_sol(double* primals, double* duals, double* reduced_costs) const = 0;
817
823 virtual void get_mip_sol(double* primals) = 0;
824
825 /*************************************************************************************************
826 ------------------------ Methods to set algorithm or logs levels
827 ---------------------------
828 *************************************************************************************************/
829
830public:
836 virtual void set_output_log_level(int loglevel) = 0;
837
843 virtual void set_algorithm(const std::string& algo) = 0;
844
850 virtual void set_threads(int n_threads) = 0;
851
857 virtual void set_optimality_gap(double gap) = 0;
858
864 virtual void set_simplex_iter(int iter) = 0;
865
869 virtual void mark_indices_to_keep_presolve(int nrows, int ncols, int* rowind, int* colind) = 0;
870
874 virtual void presolve_only() = 0;
875
879 virtual void get_presolve_map(int* rowmap, int* colmap) const = 0;
880
881 bool operator==(const SolverAbstract&) const;
882};
Definition SolverAbstract.h:171
Definition SolverAbstract.h:115
Definition SolverAbstract.h:103
Definition SolverAbstract.h:126
Definition SolverAbstract.h:91
Definition SolverAbstract.h:148
Definition SolverAbstract.h:161
Definition SolverAbstract.h:137
Definition SolverAbstract.h:80
Definition SolverAbstract.h:180
Definition SolverAbstract.h:203
virtual int get_row_index(const std::string &name)=0
Returns the index of row named "name".
virtual void chg_col_type(const std::vector< int > &mindex, const std::vector< char > &qctype)=0
Change type of some columns.
virtual void read_prob_lp(const std::filesystem::path &filename)=0
reads an optimization problem contained in a MPS file
virtual void get_ub(double *ub, int fisrt, int last) const =0
Returns the upper bounds for variables in a given range.
virtual int get_nrows() const =0
returns number of rows of the problem
virtual void get_rhs_range(double *range, int first, int last) const =0
Returns the right hand side range values for the rows in a given range.
virtual int get_nelems() const =0
returns number of non zeros elements in the matrix, excluding objective
virtual void set_algorithm(const std::string &algo)=0
Sets algorithm used by solver to solve LP's.
virtual int solve_lp()=0
Solves a problem as LP.
virtual void free()=0
Frees all the datas contained in the Solver environment.
virtual void set_output_log_level(int loglevel)=0
Sets log level of the solver.
virtual int get_n_integer_vars() const =0
returns number of integer variables in the problem
virtual void del_rows(int first, int last)=0
Deletes rows between index first and last.
virtual std::vector< std::string > get_col_names(int first, int last) const =0
Returns the names of columns from index first to last cannot be declared as const because of some sol...
virtual ~SolverAbstract()=default
destructor of SolverAbstract class : does nothing
virtual void get_lp_sol(double *primals, double *duals, double *reduced_costs) const =0
Get LP solution of a problem (available after method "solve_lp")
virtual void init()=0
Initializes a problem.
virtual void get_obj(double *obj, int first, int last) const =0
returns the objective function coefficients for the columns in a given range
virtual int get_col_index(const std::string &name)=0
Returns the index of column named "name".
void add_stream(std::ostream &stream)
add a stream to the list of streams used by the solver instance
Definition SolverAbstract.h:261
virtual void chg_obj_direction(const bool minimize)=0
Change the problem's objective function sense to minimize or maximize.
virtual double get_lp_value() const =0
Get the optimal value of a LP problem (available after method "solve_lp" )
std::string _name
Definition SolverAbstract.h:217
std::list< std::ostream * > _streams
Definition SolverAbstract.h:219
virtual int get_number_of_instances()=0
Returns number of instances of solver currently in memory.
virtual std::vector< std::string > get_col_names()=0
Returns the names of columns.
virtual void write_prob_mps(const std::filesystem::path &filename)=0
writes an optimization problem in a MPS file
virtual void chg_bounds(const std::vector< int > &mindex, const std::vector< char > &qbtype, const std::vector< double > &bnd)=0
Change bounds of some variables.
virtual void write_basis(const std::filesystem::path &filename)=0
Writes the current basis to a file for later input into the optimizer.
virtual void set_obj(const double *obj, int first, int last)=0
Set the objective function coefficients for the columns in a given range.
virtual std::vector< std::string > get_row_names(int first, int last) const =0
Returns the names of row from index first to last cannot be declared as const because of some solver ...
virtual void restore_prob(const std::filesystem::path &filename)=0
read an optimisation problem from a file
virtual void set_optimality_gap(double gap)=0
Sets the optimality gap.
virtual void chg_obj(const std::vector< int > &mindex, const std::vector< double > &obj)=0
Change coefficients in objective function.
virtual void get_lb(double *lb, int fisrt, int last) const =0
Returns the lower bounds for variables in a given range.
virtual std::vector< std::string > get_row_names()=0
Returns the names of rows.
virtual void get_presolve_map(int *rowmap, int *colmap) const =0
Get the presolve map (to be implemented by derived classes)
virtual void get_rows(int *mstart, int *mclind, double *dmatval, int size, int *nels, int first, int last) const =0
get coefficients of rows from index first to last
virtual void mark_indices_to_keep_presolve(int nrows, int ncols, int *rowind, int *colind)=0
Mark indices to keep during presolve (to be implemented by derived classes)
virtual void get_cols(int *mstart, int *mrwind, double *dmatval, int size, int *nels, int first, int last) const =0
get coefficients of cols from index first to last
virtual int get_ncols() const =0
returns number of columns of the problem
virtual void set_simplex_iter(int iter)=0
Sets the maximum number of simplex iterations the solver can perform.
virtual double get_mip_value() const =0
Get the optimal value of a MIP problem (available after method "solve_mip")
virtual void get_basis(int *rstatus, int *cstatus) const =0
Returns the current basis into the user's data arrays.
virtual void add_cols(int newcol, int newnz, const double *objx, const int *mstart, const int *mrwind, const double *dmatval, const double *bdl, const double *bdu, const std::vector< std::string > &col_names)=0
Adds new columns to the problem.
virtual void del_cols(int first, int last)=0
Deletes col at index first and last.
virtual void chg_col_name(int id_col, const std::string &name)=0
Change the name of a variable.
virtual void get_col_type(char *coltype, int first, int last) const =0
Returns the column types for the columns in a given range.
virtual void set_threads(int n_threads)=0
Sets the maximum number of threads used to perform optimization.
virtual void read_prob_mps(const std::filesystem::path &filename)=0
reads an optimization problem contained in a MPS file
virtual int solve_mip()=0
Solves a problem as MIP.
virtual void read_basis(const std::filesystem::path &filename)=0
Instructs the optimizer to read in a previously saved basis from a file.
virtual void add_rows(int newrows, int newnz, const char *qrtype, const double *rhs, const double *range, const int *mstart, const int *mclind, const double *dmatval, const std::vector< std::string > &row_names)=0
Adds rows to the problem.
virtual void presolve_only()=0
Presolve the problem (to be implemented by derived classes)
std::list< std::ostream * > & get_stream() const
returns the list of streams used by the solver instance
Definition SolverAbstract.cpp:132
virtual void get_rhs(double *rhs, int first, int last) const =0
Returns the right-hand sides of the rows in a given range.
virtual void chg_rhs(int id_row, double val)=0
Change rhs of a row.
virtual void save_prob(const std::filesystem::path &filename)=0
write an optimisation problem in a file
virtual void chg_coef(int id_row, int id_col, double val)=0
Change a coefficient in the matrix.
virtual void chg_row_name(int id_row, const std::string &name)=0
Change the name of a constraint.
virtual void set_obj_to_zero()=0
Set the objective function coefficients to zero.
static void zero_status_check(int status, const std::string &action_failed, const std::string &log_location)
Check if a status code is different to 0, throw InvalidStatusException if it occurs.
Definition SolverAbstract.h:279
virtual void get_mip_sol(double *primals)=0
Get MIP solution of a problem (available after method "solve_mip")
virtual std::string get_solver_name() const =0
Returns the solver used.
virtual int get_splex_num_of_ite_last() const =0
Get the number of simplex iterations done in the last resolution of the problem.
virtual void get_row_type(char *qrtype, int first, int last) const =0
Returns the row types for the rows in a given range.
virtual void add_name(int type, const char *cnames, int indice)=0
Adds a name to a row or a column.
virtual void write_prob_lp(const std::filesystem::path &filename)=0
writes an optimization problem in a LP file
Definition SolverAbstract.h:20