alpar@1381: /* -*- C++ -*- alpar@1381: * src/lemon/lp_cplex.cc alpar@1381: * - Part of LEMON, a generic C++ optimization library alpar@1381: * alpar@1381: * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport alpar@1381: * (Egervary Research Group on Combinatorial Optimization, EGRES). alpar@1381: * alpar@1381: * Permission to use, modify and distribute this software is granted alpar@1381: * provided that this copyright notice appears in all copies. For alpar@1381: * precise terms see the accompanying LICENSE file. alpar@1381: * alpar@1381: * This software is provided "AS IS" with no warranty of any kind, alpar@1381: * express or implied, and with no claim as to its suitability for any alpar@1381: * purpose. alpar@1381: * alpar@1381: */ athos@1405: #include athos@1405: #include alpar@1381: alpar@1381: ///\file alpar@1381: ///\brief Implementation of the LEMON-CPLEX lp solver interface. alpar@1381: namespace lemon { alpar@1381: alpar@1381: LpCplex::LpCplex() : LpSolverBase() { alpar@1381: env = NULL; alpar@1381: lp = NULL; alpar@1381: env = CPXopenCPLEXdevelop(&status); alpar@1381: // if (Env == NULL) alpar@1381: // { alpar@1381: // fprintf(stderr,"A CPLEX környezet megnyitása sikertelen.\n"); alpar@1381: // CPXgeterrorstring(Env, Status, ErrorMsg); alpar@1381: // fprintf(stderr,"%s",ErrorMsg); alpar@1381: // goto Terminate; alpar@1381: // } alpar@1381: alpar@1381: // *** A problema létrehozása *** alpar@1381: lp = CPXcreateprob(env, &status, "LP problem"); alpar@1381: alpar@1381: // if (Problem == NULL) alpar@1381: // { alpar@1381: // fprintf(stderr,"Az LP létrehozása sikertelen"); alpar@1381: // goto Terminate; alpar@1381: // } alpar@1381: alpar@1381: } alpar@1381: alpar@1381: LpCplex::~LpCplex() { alpar@1381: status = CPXfreeprob(env,&lp); alpar@1381: // if (Status != 0) alpar@1381: // { alpar@1381: // fprintf(stderr,"A CPLEX feladat törlése sikertelen.\n"); alpar@1381: // CPXgeterrorstring(Env, Status, ErrorMsg); alpar@1381: // fprintf(stderr,"%s",ErrorMsg); alpar@1381: // goto Terminate; alpar@1381: // } alpar@1381: alpar@1381: status = CPXcloseCPLEX(&env); alpar@1381: // if (Status != 0) alpar@1381: // { alpar@1381: // fprintf(stderr,"A CPLEX környezet bezárása sikertelen.\n"); alpar@1381: // CPXgeterrorstring(Env, Status, ErrorMsg); alpar@1381: // fprintf(stderr,"%s",ErrorMsg); alpar@1381: // goto Terminate; alpar@1381: // } alpar@1381: alpar@1381: } alpar@1381: athos@1405: LpSolverBase &LpCplex::_newLp() athos@1405: { athos@1405: return *(LpSolverBase*)0; athos@1405: } athos@1405: LpSolverBase &LpCplex::_copyLp() { athos@1405: return *(LpSolverBase*)0; athos@1405: //Ez lesz majd CPXcloneprob (env, lp, &status); athos@1405: } alpar@1381: alpar@1381: int LpCplex::_addCol() alpar@1381: { alpar@1381: int i = CPXgetnumcols (env, lp); alpar@1381: Value lb[1],ub[1]; alpar@1381: lb[0]=-INF;//-CPX_INFBOUND; alpar@1381: ub[0]=INF;//CPX_INFBOUND; alpar@1381: status = CPXnewcols (env, lp, 1, NULL, lb, ub, NULL, NULL); alpar@1381: return i; alpar@1381: } alpar@1381: alpar@1381: int LpCplex::_addRow() alpar@1381: { alpar@1381: //We want a row that is not constrained alpar@1381: char sense[1]; alpar@1381: sense[0]='L';//<= constraint alpar@1381: Value rhs[1]; alpar@1381: rhs[0]=INF; alpar@1381: int i = CPXgetnumrows (env, lp); alpar@1381: status = CPXnewrows (env, lp, 1, rhs, sense, NULL, NULL); alpar@1381: return i; alpar@1381: } alpar@1381: alpar@1381: ///\warning Data at index 0 is ignored in the arrays. alpar@1381: void LpCplex::_setRowCoeffs(int i, alpar@1381: int length, alpar@1381: int const * indices, alpar@1381: Value const * values ) alpar@1381: { alpar@1381: int rowlist[length+1]; alpar@1381: int* p=rowlist; alpar@1381: for (int k=1;k<=length;++k){ alpar@1381: rowlist[k]=i; alpar@1381: } alpar@1381: status = CPXchgcoeflist(env, lp, alpar@1381: length, alpar@1381: p+1, alpar@1381: const_cast(indices+1), alpar@1381: const_cast(values+1)); alpar@1381: } alpar@1381: alpar@1381: void LpCplex::_setColCoeffs(int i, alpar@1381: int length, alpar@1381: int const * indices, alpar@1381: Value const * values) alpar@1381: { alpar@1381: int collist[length+1]; alpar@1381: int* p=collist; alpar@1381: for (int k=1;k<=length;++k){ alpar@1381: collist[k]=i; alpar@1381: } alpar@1381: status = CPXchgcoeflist(env, lp, alpar@1381: length, alpar@1381: const_cast(indices+1), alpar@1381: p+1, alpar@1381: const_cast(values+1)); alpar@1381: } alpar@1381: alpar@1381: void LpCplex::_setColLowerBound(int i, Value value) alpar@1381: { alpar@1381: int indices[1]; alpar@1381: indices[0]=i; alpar@1381: char lu[1]; alpar@1381: lu[0]='L'; alpar@1381: Value bd[1]; alpar@1381: bd[0]=value; alpar@1381: status = CPXchgbds (env, lp, 1, indices, lu, bd); alpar@1381: alpar@1381: } alpar@1381: alpar@1381: void LpCplex::_setColUpperBound(int i, Value value) alpar@1381: { alpar@1381: int indices[1]; alpar@1381: indices[0]=i; alpar@1381: char lu[1]; alpar@1381: lu[0]='U'; alpar@1381: Value bd[1]; alpar@1381: bd[0]=value; alpar@1381: status = CPXchgbds (env, lp, 1, indices, lu, bd); alpar@1381: } alpar@1381: alpar@1381: //This will be easier to implement alpar@1381: void LpCplex::_setRowBounds(int i, Value lb, Value ub) alpar@1381: { alpar@1381: //Bad parameter alpar@1381: if (lb==INF || ub==-INF) { alpar@1381: //FIXME error alpar@1381: } athos@1405: alpar@1381: int cnt=1; alpar@1381: int indices[1]; alpar@1381: indices[0]=i; alpar@1381: char sense[1]; alpar@1381: alpar@1381: if (lb==-INF){ alpar@1381: sense[0]='L'; alpar@1381: CPXchgsense (env, lp, cnt, indices, sense); alpar@1381: CPXchgcoef (env, lp, i, -1, ub); athos@1405: alpar@1381: } alpar@1381: else{ alpar@1381: if (ub==INF){ alpar@1381: sense[0]='G'; alpar@1381: CPXchgsense (env, lp, cnt, indices, sense); alpar@1381: CPXchgcoef (env, lp, i, -1, lb); alpar@1381: } alpar@1381: else{ alpar@1381: if (lb == ub){ alpar@1381: sense[0]='E'; alpar@1381: CPXchgsense (env, lp, cnt, indices, sense); alpar@1381: CPXchgcoef (env, lp, i, -1, lb); alpar@1381: } alpar@1381: else{ alpar@1381: sense[0]='R'; alpar@1381: CPXchgsense (env, lp, cnt, indices, sense); alpar@1381: CPXchgcoef (env, lp, i, -1, lb); alpar@1381: CPXchgcoef (env, lp, i, -2, ub-lb); alpar@1381: } alpar@1381: } alpar@1381: } alpar@1381: } alpar@1381: athos@1405: // void LpCplex::_setRowLowerBound(int i, Value value) athos@1405: // { athos@1405: // //Not implemented, obsolete athos@1405: // } alpar@1381: athos@1405: // void LpCplex::_setRowUpperBound(int i, Value value) athos@1405: // { athos@1405: // //Not implemented, obsolete athos@1405: // // //TODO Ezt kell meg megirni athos@1405: // // //type of the problem athos@1405: // // char sense[1]; athos@1405: // // status = CPXgetsense (env, lp, sense, i, i); athos@1405: // // Value rhs[1]; athos@1405: // // status = CPXgetrhs (env, lp, rhs, i, i); alpar@1381: athos@1405: // // switch (sense[0]) { athos@1405: // // case 'L'://<= constraint athos@1405: // // break; athos@1405: // // case 'E'://= constraint athos@1405: // // break; athos@1405: // // case 'G'://>= constraint athos@1405: // // break; athos@1405: // // case 'R'://ranged constraint athos@1405: // // break; athos@1405: // // default: ; athos@1405: // // //FIXME error athos@1405: // // } alpar@1381: athos@1405: // // status = CPXchgcoef (env, lp, i, -2, value_rng); athos@1405: // } alpar@1381: alpar@1381: void LpCplex::_setObjCoeff(int i, Value obj_coef) alpar@1381: { alpar@1381: CPXchgcoef (env, lp, -1, i, obj_coef); alpar@1381: } alpar@1381: alpar@1381: void LpCplex::_clearObj() alpar@1381: { alpar@1381: for (int i=0;i< CPXgetnumcols (env, lp);++i){ alpar@1381: CPXchgcoef (env, lp, -1, i, 0); alpar@1381: } alpar@1381: alpar@1381: } alpar@1381: alpar@1381: LpCplex::SolveExitStatus LpCplex::_solve() alpar@1381: { alpar@1381: alpar@1381: status = CPXlpopt (env, lp); alpar@1381: if (status == 0){ alpar@1381: return SOLVED; alpar@1381: } alpar@1381: else{ alpar@1381: return UNSOLVED; alpar@1381: } alpar@1381: // int i= lpx_simplex(lp); alpar@1381: // switch (i) { alpar@1381: // case LPX_E_OK: alpar@1381: // return SOLVED; alpar@1381: // break; alpar@1381: // default: alpar@1381: // return UNSOLVED; alpar@1381: // } alpar@1381: } alpar@1381: alpar@1381: LpCplex::SolutionStatus LpCplex::_getPrimalStatus() alpar@1381: { athos@1405: // CPX_STAT_ABORT_DUAL_OBJ_LIM athos@1405: // CPX_STAT_ABORT_IT_LIM athos@1405: // CPX_STAT_ABORT_OBJ_LIM athos@1405: // CPX_STAT_ABORT_PRIM_OBJ_LIM athos@1405: // CPX_STAT_ABORT_TIME_LIM athos@1405: // CPX_STAT_ABORT_USER athos@1405: // CPX_STAT_FEASIBLE_RELAXED athos@1405: // CPX_STAT_INFEASIBLE athos@1405: // CPX_STAT_INForUNBD athos@1405: // CPX_STAT_NUM_BEST athos@1405: // CPX_STAT_OPTIMAL athos@1405: // CPX_STAT_OPTIMAL_FACE_UNBOUNDED athos@1405: // CPX_STAT_OPTIMAL_INFEAS athos@1405: // CPX_STAT_OPTIMAL_RELAXED athos@1405: // CPX_STAT_UNBOUNDED athos@1405: alpar@1381: //Unimplemented athos@1405: int stat = CPXgetstat (env, lp); athos@1405: switch (stat) { athos@1405: case CPX_STAT_OPTIMAL://Optimal athos@1405: return OPTIMAL; athos@1405: break; athos@1405: case CPX_STAT_INFEASIBLE://Infeasible athos@1405: return INFEASIBLE; athos@1405: break; athos@1405: case CPX_STAT_UNBOUNDED://Unbounded athos@1405: return INFINITE; athos@1405: break; athos@1405: case CPX_STAT_NUM_BEST://Feasible athos@1405: return FEASIBLE; athos@1405: break; athos@1405: default: athos@1405: return UNDEFINED; //Everything else comes here athos@1405: //FIXME error athos@1405: } alpar@1381: } alpar@1381: alpar@1381: LpCplex::Value LpCplex::_getPrimal(int i) alpar@1381: { alpar@1381: Value x; alpar@1381: CPXgetx (env, lp, &x, i, i); alpar@1381: return x; alpar@1381: } alpar@1381: alpar@1381: LpCplex::Value LpCplex::_getPrimalValue() alpar@1381: { athos@1405: Value objval; athos@1405: //method = CPXgetmethod (env, lp); athos@1405: status = CPXgetobjval (env, lp, &objval); athos@1405: return objval; alpar@1381: } alpar@1381: alpar@1381: alpar@1381: alpar@1381: alpar@1381: void LpCplex::_setMax() alpar@1381: { alpar@1381: CPXchgobjsen (env, lp, CPX_MAX); alpar@1381: } alpar@1381: void LpCplex::_setMin() alpar@1381: { alpar@1381: CPXchgobjsen (env, lp, CPX_MIN); alpar@1381: } alpar@1381: alpar@1381: } //namespace lemon alpar@1381: