62 #define GLP_PROB_DEFINED 64 #include <glpk/glpk.h> 71 :
meilp_solver(), lp(nullptr), scp(nullptr), iocp(nullptr), bfcp(nullptr), mip_solution(
false)
103 lp = glp_create_prob();
106 bfcp =
new glp_bfcp();
111 scp =
new glp_smcp();
113 scp->presolve = GLP_ON;
116 iocp =
new glp_iocp();
118 iocp->presolve = GLP_ON;
122 bfcp->msg_lev =
iocp->msg_lev =
scp->msg_lev = GLP_MSG_OFF;
126 bfcp->msg_lev =
iocp->msg_lev =
scp->msg_lev = GLP_MSG_ERR;
130 bfcp->msg_lev =
iocp->msg_lev =
scp->msg_lev = GLP_MSG_ALL;
144 glp_add_cols(
lp, nvars);
164 scp->meth = GLP_DUALP;
165 scp->pricing = GLP_PT_STD;
166 scp->r_test = GLP_RT_HAR;
167 scp->presolve = GLP_ON;
168 scp->tol_bnd = double(1e-7);
169 scp->tol_dj = double(1e-7);
170 scp->tol_piv = double(1e-10);
171 scp->obj_ll = DBL_MIN;
172 scp->obj_ul = DBL_MAX;
178 scp->presolve = GLP_OFF;
180 int simplex_res = glp_simplex(
lp,
scp);
221 PRINT_MSG(
"*** SUCCESS! The LP problem instance has been successfully solved! ***");
226 PRINT_MSG(
"ERROR: Unable to start the search, because the initial basis specified in the problem" 227 " object is invalid the number of basic (auxiliary and structural) variables is not the" 228 " same as the number of rows in the problem object");
233 PRINT_MSG(
"ERROR: Unable to start the search, because the basis matrix corresponding to the initial basis" 234 " is singular within the working precision");
239 PRINT_MSG(
"ERROR: Unable to start the search, because the basis matrix corresponding to the initial" 240 " basis is ill-conditioned, i.e. its condition number is too large");
245 PRINT_MSG(
"ERROR: Unable to start the search, because some double-bounded (auxiliary or structural)" 246 " variables have incorrect bounds");
251 PRINT_MSG(
"ERROR: The search was prematurely terminated due to the solver failure");
256 PRINT_MSG(
"ERROR: The search was prematurely terminated, because the objective function being" 257 " maximized has reached its lower limit and continues decreasing (the dual simplex only)");
262 PRINT_MSG(
"ERROR: The search was prematurely terminated, because the objective function being" 263 " minimized has reached its upper limit and continues increasing (the dual simplex only)");
268 PRINT_MSG(
"ERROR: The search was prematurely terminated, because the simplex iteration limit" 269 " has been exceeded");
274 PRINT_MSG(
"ERROR: The search was prematurely terminated, because the time limit has been exceeded");
279 PRINT_MSG(
"The LP problem instance has no primal feasible solution (only if the LP presolver is used)");
284 PRINT_MSG(
"The LP problem instance has no dual feasible solution (only if the LP presolver is used)");
288 PRINT_MSG(
"ERROR: unknown glp_solve return code");
291 int status = glp_get_status(
lp);
306 PRINT_MSG(
"SUCCESS: PROBLEM SOLUTION IS OPTIMAL");
311 PRINT_MSG(
"SUCCESS: PROBLEM SOLUTION IS FEASIBLE");
316 PRINT_MSG(
"FAILURE: PROBLEM SOLUTION IS INFEASIBLE");
321 PRINT_MSG(
"FAILURE: PROBLEM HAS NO FEASIBLE SOLUTION");
326 PRINT_MSG(
"FAILURE: PROBLEM HAS UNBOUNDED SOLUTION");
331 PRINT_MSG(
"FAILURE: PROBLEM SOLUTION IS UNDEFINED");
335 PRINT_MSG(
"ERROR: unknown glp_get_status return code");
338 int prim_stat = glp_get_prim_stat(
lp);
351 PRINT_MSG(
"FAILURE: Primal solution is undefined");
356 PRINT_MSG(
"SUCCESS: Primal solution is feasible");
361 PRINT_MSG(
"FAILURE: Primal solution is infeasible");
366 PRINT_MSG(
"FAILURE: No Primal feasible solution exists");
370 PRINT_MSG(
"ERROR: unknown glp_get_prim_stat return code");
373 return (simplex_res == 0 && status == GLP_OPT && prim_stat == GLP_FEAS) ? 0 : 1;
391 glp_scale_prob(
lp, GLP_SF_AUTO);
396 glp_adv_basis(
lp, 0);
401 int simplex_res = glp_simplex(
lp,
scp);
411 PRINT_MSG(
"ERROR: Unable to start the search, because the initial basis specified in the problem" 412 " object is invalid the number of basic (auxiliary and structural) variables is not the" 413 " same as the number of rows in the problem object");
418 PRINT_MSG(
"ERROR: Unable to start the search, because the basis matrix corresponding to the initial basis" 419 " is singular within the working precision");
424 PRINT_MSG(
"ERROR: Unable to start the search, because the basis matrix corresponding to the initial" 425 " basis is ill-conditioned, i.e. its condition number is too large");
430 PRINT_MSG(
"ERROR: Unable to start the search, because some double-bounded (auxiliary or structural)" 431 " variables have incorrect bounds");
436 PRINT_MSG(
"ERROR: The search was prematurely terminated due to the solver failure");
441 PRINT_MSG(
"ERROR: The search was prematurely terminated, because the objective function being" 442 " maximized has reached its lower limit and continues decreasing (the dual simplex only)");
447 PRINT_MSG(
"ERROR: The search was prematurely terminated, because the objective function being" 448 " minimized has reached its upper limit and continues increasing (the dual simplex only)");
453 PRINT_MSG(
"ERROR: The search was prematurely terminated, because the simplex iteration limit" 454 " has been exceeded");
459 PRINT_MSG(
"ERROR: The search was prematurely terminated, because the time limit has been exceeded");
473 PRINT_MSG(
"ERROR: unknown glp_solve return code");
476 int intopt_res = glp_intopt(
lp,
iocp);
519 PRINT_MSG(
"ERROR: Unable to start the search, because some double-bounded" 520 " (auxiliary or structural) variables have incorrect bounds");
525 PRINT_MSG(
"ERROR: Unable to start the search, because optimal basis for initial" 526 " LP relaxation is not provided");
537 PRINT_MSG(
"Unable to start the search, because LP relaxation of the" 538 " MIP problem instance has no dual feasible solution. In" 539 " other word, this code means that if the LP relaxation has" 540 " at least one primal feasible solution, its optimal solution is" 541 " unbounded, so if the MIP problem has at least one integer" 542 " feasible solution, its (integer) optimal solution is also un" 548 PRINT_MSG(
"ERROR: The search was prematurely terminated due to the solver failure");
553 PRINT_MSG(
"ERROR: The search was prematurely terminated, because the rela" 554 " tive mip gap tolerance has been reached");
559 PRINT_MSG(
"ERROR: The search was prematurely terminated, because the time limit has been exceeded");
564 PRINT_MSG(
"ERROR: The search was prematurely terminated by application");
568 PRINT_MSG(
"ERROR: unknown glp_intopt return code");
571 int status = glp_mip_status(
lp);
589 PRINT_MSG(
"SUCCESS: PROBLEM SOLUTION IS FEASIBLE");
594 PRINT_MSG(
"FAILURE: PROBLEM HAS NO FEASIBLE SOLUTION");
599 PRINT_MSG(
"FAILURE: PROBLEM SOLUTION IS UNDEFINED");
603 PRINT_MSG(
"ERROR: unknown glp_get_status return code");
605 return (intopt_res == 0 && status == GLP_OPT) ? 0 : 1;
616 int row_index = glp_add_rows(
lp, 1);
617 if(name.length() < 255)
619 glp_set_row_name(
lp, row_index, const_cast<char*>(name.c_str()));
623 glp_set_row_name(
lp, row_index, const_cast<char*>((name.substr(0, 252) +
"...").c_str()));
629 glp_set_row_bnds(
lp, row_index, GLP_FX, i_rhs, i_rhs);
632 glp_set_row_bnds(
lp, row_index, GLP_UP, 0, i_rhs);
635 glp_set_row_bnds(
lp, row_index, GLP_LO, i_rhs, 0);
644 return glp_get_num_rows(
lp);
649 return glp_get_num_cols(
lp);
658 glp_set_obj_dir(
lp, GLP_MIN);
661 glp_set_obj_dir(
lp, GLP_MAX);
667 auto i_end = i_coeffs.end();
668 for(
auto i = i_coeffs.begin(); i != i_end; ++i)
670 glp_set_obj_coef(
lp, i->first + 1, i->second);
680 glp_write_sol(
lp,
"glp_sol.txt");
681 glp_write_mps(
lp, GLP_MPS_FILE,
nullptr,
"glpk.mps");
682 glp_write_lp(
lp,
nullptr,
"glpk.lp");
691 glp_write_sol(
lp, (file_name +
".txt").c_str());
692 glp_write_mps(
lp, GLP_MPS_FILE,
nullptr, (file_name +
".mps").c_str());
693 glp_write_lp(
lp,
nullptr, (file_name +
".lp").c_str());
698 glp_set_col_kind(
lp, i + 1, GLP_IV);
704 int nc = glp_get_num_cols(
lp);
705 for(
int i = 0; i < nc; i++)
709 vars[i] = glp_mip_col_val(
lp, i + 1);
713 vars[i] = glp_get_col_prim(
lp, i + 1);
720 std::string ost = name +
"_" + std::to_string(var);
721 glp_set_col_name(
lp, var + 1, const_cast<char*>(ost.c_str()));
726 return std::string(glp_get_col_name(
lp, var + 1));
731 return glp_add_cols(
lp, 1) - 1;
745 int nc = glp_get_num_cols(
lp);
746 for(
int i = 0; i < nc; i++)
749 switch(glp_get_col_type(
lp, var))
752 glp_set_col_bnds(
lp, var, GLP_FR, 0, 0);
754 [[gnu::fallthrough]];
764 THROW_ERROR(
"Lower bounded variable, but lower bound can't be found in lower_bounds");
798 THROW_ERROR(
"Fixed bounded variable, but either upper or lower bound can't be found in vectors or " 799 "bounds are different");
811 THROW_ERROR(
"Upper bounded variable, but upper bound can't be found in upper_bounds");
821 std::to_string(glp_get_col_ub(
lp, var)));
826 THROW_ERROR(
"Double bounded variable, but either lower or upper bound can't be found in bounds");
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
virtual void copy(const std::map< int, double > &i_coeffs)
File containing functions and utilities to support the printing of debug messagges.
int solve() override
Solve the linear problem.
void set_all_bounds() override
Set the lower and upper of the variables using lower_bounds and upper_bounds.
#define DEBUG_LEVEL_PEDANTIC
very verbose debugging print is performed.
glp_iocp * iocp
integer solver control parameter
CustomUnorderedMap< int, double > upper_bounds
The upper bound of the variables. They will be really set by solve method.
void objective_add(std::map< int, double > &i_coeffs, ilp_dir dir) override
Set the objective function.
CustomUnorderedMap< int, double > lower_bounds
The lower bound of the variables. They will be really set by solve method.
int solve_ilp() override
Solve the integer linear problem.
int add_empty_column() override
Add an empty column ???
void set_col_name(int var, const std::string &name) override
Set name of a variable (column)
exceptions managed by PandA
redefinition of map to manage ordered/unordered structures
bool mip_solution
it is true when solve_ilp() has been executed, false otherwise
void print(std::ostream &os) override
Print the problem.
void print_to_file(const std::string &file_name) override
Print the problem.
ilp_dir
Type of objective function.
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
void set_int(int i) override
Set a variable to have only integer values.
int debug_level
debug_level
glp_bfcp * bfcp
basis factorization control parameters
int get_number_constraints() const override
Return the number of constraints.
int glpk_print_hook(void *DEBUG_PARAMETER(info), const char *DEBUG_PARAMETER(msg))
int * int_buffer
indexes in the constraint buffer
void make(int nvars) override
???
glp_smcp * scp
simplex_control_params
Base class providing several methods to encapsulate the interface to several ilp solver.
std::string get_col_name(int var) override
Get name of a variable (column)
This file collects some utility functions and macros.
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
float float3 __attribute__((vector_size(16)))
#define DEBUG_PARAMETER(parameter)
macro used to solve problem of parameters used only in not-release
int MAX_time
Time-out value.
void get_vars_solution(std::map< int, double > &vars) const override
Return the solution of the problem.
ilp_sign
Possible operator in constraints.
int get_number_variables() const override
Return the number of variables.
double * real_buffer
values in the constraint buffer
#define DEBUG_LEVEL_VERBOSE
verbose debugging print is performed.
void add_row(std::map< int, double > &i_coeffs, double i_rhs, ilp_sign i_sign, const std::string &name) override
Add a constraint to the ilp formulation.
Linear Programming solver according to the newer syntax (from version 4.35) of the GLPK solver...
#define DEBUG_LEVEL_MINIMUM
minimum debugging print is performed.
This class provide an interface to different solvers.
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...