diff -r d8475431bbbb -r 8e85e6bbefdf lemon/lp_cplex.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lemon/lp_cplex.cc Mon May 23 04:48:14 2005 +0000 @@ -0,0 +1,407 @@ +/* -*- C++ -*- + * lemon/lp_cplex.cc - Part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ +#include +#include + +///\file +///\brief Implementation of the LEMON-CPLEX lp solver interface. +namespace lemon { + + LpCplex::LpCplex() : LpSolverBase() { + env = NULL; + lp = NULL; + env = CPXopenCPLEXdevelop(&status); +// if (Env == NULL) +// { +// fprintf(stderr,"A CPLEX környezet megnyitása sikertelen.\n"); +// CPXgeterrorstring(Env, Status, ErrorMsg); +// fprintf(stderr,"%s",ErrorMsg); +// goto Terminate; +// } + + // *** A problema létrehozása *** + lp = CPXcreateprob(env, &status, "LP problem"); + + // if (Problem == NULL) +// { +// fprintf(stderr,"Az LP létrehozása sikertelen"); +// goto Terminate; +// } + + } + + LpCplex::~LpCplex() { + status = CPXfreeprob(env,&lp); + // if (Status != 0) + // { +// fprintf(stderr,"A CPLEX feladat törlése sikertelen.\n"); +// CPXgeterrorstring(Env, Status, ErrorMsg); +// fprintf(stderr,"%s",ErrorMsg); +// goto Terminate; +// } + + status = CPXcloseCPLEX(&env); + // if (Status != 0) + // { + // fprintf(stderr,"A CPLEX környezet bezárása sikertelen.\n"); +// CPXgeterrorstring(Env, Status, ErrorMsg); +// fprintf(stderr,"%s",ErrorMsg); +// goto Terminate; +// } + + } + + LpSolverBase &LpCplex::_newLp() + { + return *(LpSolverBase*)0; + } + LpSolverBase &LpCplex::_copyLp() { + return *(LpSolverBase*)0; + //Ez lesz majd CPXcloneprob (env, lp, &status); + } + + int LpCplex::_addCol() + { + int i = CPXgetnumcols (env, lp); + Value lb[1],ub[1]; + lb[0]=-INF;//-CPX_INFBOUND; + ub[0]=INF;//CPX_INFBOUND; + status = CPXnewcols (env, lp, 1, NULL, lb, ub, NULL, NULL); + return i; + } + + int LpCplex::_addRow() + { + //We want a row that is not constrained + char sense[1]; + sense[0]='L';//<= constraint + Value rhs[1]; + rhs[0]=INF; + int i = CPXgetnumrows (env, lp); + status = CPXnewrows (env, lp, 1, rhs, sense, NULL, NULL); + return i; + } + + + void LpCplex::_eraseCol(int i) { + ///\todo Not implemented yet + } + + void LpCplex::_eraseRow(int i) { + ///\todo Not implemented yet + } + + + ///\warning Data at index 0 is ignored in the arrays. + void LpCplex::_setRowCoeffs(int i, + int length, + int const * indices, + Value const * values ) + { + int rowlist[length+1]; + int* p=rowlist; + for (int k=1;k<=length;++k){ + rowlist[k]=i; + } + status = CPXchgcoeflist(env, lp, + length, + p+1, + const_cast(indices+1), + const_cast(values+1)); + } + + void LpCplex::_setColCoeffs(int i, + int length, + int const * indices, + Value const * values) + { + int collist[length+1]; + int* p=collist; + for (int k=1;k<=length;++k){ + collist[k]=i; + } + status = CPXchgcoeflist(env, lp, + length, + const_cast(indices+1), + p+1, + const_cast(values+1)); + } + + void LpCplex::_setCoeff(int row, int col, Value value) + { + CPXchgcoef (env, lp, row, col, value); + } + + void LpCplex::_setColLowerBound(int i, Value value) + { + int indices[1]; + indices[0]=i; + char lu[1]; + lu[0]='L'; + Value bd[1]; + bd[0]=value; + status = CPXchgbds (env, lp, 1, indices, lu, bd); + + } + + void LpCplex::_setColUpperBound(int i, Value value) + { + int indices[1]; + indices[0]=i; + char lu[1]; + lu[0]='U'; + Value bd[1]; + bd[0]=value; + status = CPXchgbds (env, lp, 1, indices, lu, bd); + } + + //This will be easier to implement + void LpCplex::_setRowBounds(int i, Value lb, Value ub) + { + //Bad parameter + if (lb==INF || ub==-INF) { + //FIXME error + } + + int cnt=1; + int indices[1]; + indices[0]=i; + char sense[1]; + + if (lb==-INF){ + sense[0]='L'; + CPXchgsense (env, lp, cnt, indices, sense); + CPXchgcoef (env, lp, i, -1, ub); + + } + else{ + if (ub==INF){ + sense[0]='G'; + CPXchgsense (env, lp, cnt, indices, sense); + CPXchgcoef (env, lp, i, -1, lb); + } + else{ + if (lb == ub){ + sense[0]='E'; + CPXchgsense (env, lp, cnt, indices, sense); + CPXchgcoef (env, lp, i, -1, lb); + } + else{ + sense[0]='R'; + CPXchgsense (env, lp, cnt, indices, sense); + CPXchgcoef (env, lp, i, -1, lb); + CPXchgcoef (env, lp, i, -2, ub-lb); + } + } + } + } + +// void LpCplex::_setRowLowerBound(int i, Value value) +// { +// //Not implemented, obsolete +// } + +// void LpCplex::_setRowUpperBound(int i, Value value) +// { +// //Not implemented, obsolete +// // //TODO Ezt kell meg megirni +// // //type of the problem +// // char sense[1]; +// // status = CPXgetsense (env, lp, sense, i, i); +// // Value rhs[1]; +// // status = CPXgetrhs (env, lp, rhs, i, i); + +// // switch (sense[0]) { +// // case 'L'://<= constraint +// // break; +// // case 'E'://= constraint +// // break; +// // case 'G'://>= constraint +// // break; +// // case 'R'://ranged constraint +// // break; +// // default: ; +// // //FIXME error +// // } + +// // status = CPXchgcoef (env, lp, i, -2, value_rng); +// } + + void LpCplex::_setObjCoeff(int i, Value obj_coef) + { + CPXchgcoef (env, lp, -1, i, obj_coef); + } + + void LpCplex::_clearObj() + { + for (int i=0;i< CPXgetnumcols (env, lp);++i){ + CPXchgcoef (env, lp, -1, i, 0); + } + + } + + LpCplex::SolveExitStatus LpCplex::_solve() + { + + status = CPXlpopt (env, lp); + if (status == 0){ + return SOLVED; + } + else{ + return UNSOLVED; + } +// int i= lpx_simplex(lp); +// switch (i) { +// case LPX_E_OK: +// return SOLVED; +// break; +// default: +// return UNSOLVED; +// } + } + + LpCplex::SolutionStatus LpCplex::_getPrimalStatus() + { +//7.5-os cplex statusai +// #define CPX_OPTIMAL 1 +// #define CPX_INFEASIBLE 2 +// #define CPX_UNBOUNDED 3 +// #define CPX_OBJ_LIM 4 +// #define CPX_IT_LIM_FEAS 5 +// #define CPX_IT_LIM_INFEAS 6 +// #define CPX_TIME_LIM_FEAS 7 +// #define CPX_TIME_LIM_INFEAS 8 +// #define CPX_NUM_BEST_FEAS 9 +// #define CPX_NUM_BEST_INFEAS 10 +// #define CPX_OPTIMAL_INFEAS 11 +// #define CPX_ABORT_FEAS 12 +// #define CPX_ABORT_INFEAS 13 +// #define CPX_ABORT_DUAL_INFEAS 14 +// #define CPX_ABORT_PRIM_INFEAS 15 +// #define CPX_ABORT_PRIM_DUAL_INFEAS 16 +// #define CPX_ABORT_PRIM_DUAL_FEAS 17 +// #define CPX_ABORT_CROSSOVER 18 +// #define CPX_INForUNBD 19 +// #define CPX_PIVOT 20 + +// Ezeket hova tegyem: +// ??case CPX_ABORT_DUAL_INFEAS +// ??case CPX_ABORT_CROSSOVER +// ??case CPX_INForUNBD +// ??case CPX_PIVOT + + int stat = CPXgetstat (env, lp); + switch (stat) { + case 0: + return UNDEFINED; //Undefined + break; + case CPX_OPTIMAL://Optimal + return OPTIMAL; + break; + case CPX_UNBOUNDED://Unbounded + return INFINITE; + break; + case CPX_INFEASIBLE://Infeasible + case CPX_IT_LIM_INFEAS: + case CPX_TIME_LIM_INFEAS: + case CPX_NUM_BEST_INFEAS: + case CPX_OPTIMAL_INFEAS: + case CPX_ABORT_INFEAS: + case CPX_ABORT_PRIM_INFEAS: + case CPX_ABORT_PRIM_DUAL_INFEAS: + return INFEASIBLE; + break; + case CPX_OBJ_LIM: + case CPX_IT_LIM_FEAS: + case CPX_TIME_LIM_FEAS: + case CPX_NUM_BEST_FEAS: + case CPX_ABORT_FEAS: + case CPX_ABORT_PRIM_DUAL_FEAS: + return FEASIBLE; + break; + default: + return UNDEFINED; //Everything else comes here + //FIXME error + } + + + //Nem tudom, hanyas cplex verzio statusai +// CPX_STAT_ABORT_DUAL_OBJ_LIM +// CPX_STAT_ABORT_IT_LIM +// CPX_STAT_ABORT_OBJ_LIM +// CPX_STAT_ABORT_PRIM_OBJ_LIM +// CPX_STAT_ABORT_TIME_LIM +// CPX_STAT_ABORT_USER +// CPX_STAT_FEASIBLE_RELAXED +// CPX_STAT_INFEASIBLE +// CPX_STAT_INForUNBD +// CPX_STAT_NUM_BEST +// CPX_STAT_OPTIMAL +// CPX_STAT_OPTIMAL_FACE_UNBOUNDED +// CPX_STAT_OPTIMAL_INFEAS +// CPX_STAT_OPTIMAL_RELAXED +// CPX_STAT_UNBOUNDED + +// int stat = CPXgetstat (env, lp); +// switch (stat) { +// case CPX_STAT_OPTIMAL://Optimal +// return OPTIMAL; +// break; +// case CPX_STAT_INFEASIBLE://Infeasible +// return INFEASIBLE; +// break; +// case CPX_STAT_UNBOUNDED://Unbounded +// return INFINITE; +// break; +// case CPX_STAT_NUM_BEST://Feasible +// return FEASIBLE; +// break; +// default: +// return UNDEFINED; //Everything else comes here +// //FIXME error +// } + + } + + LpCplex::Value LpCplex::_getPrimal(int i) + { + Value x; + CPXgetx (env, lp, &x, i, i); + return x; + } + + LpCplex::Value LpCplex::_getPrimalValue() + { + Value objval; + //method = CPXgetmethod (env, lp); + status = CPXgetobjval (env, lp, &objval); + return objval; + } + + + + + void LpCplex::_setMax() + { + CPXchgobjsen (env, lp, CPX_MAX); + } + void LpCplex::_setMin() + { + CPXchgobjsen (env, lp, CPX_MIN); + } + +} //namespace lemon +