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: */ alpar@1381: alpar@1381: #include"lp_cplex.h" 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: alpar@1381: LpSolverBase &LpCplex::_newLp() {return *(LpSolverBase*)0;} alpar@1381: LpSolverBase &LpCplex::_copyLp() {return *(LpSolverBase*)0;} 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: } alpar@1381: 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); 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: alpar@1381: void LpCplex::_setRowLowerBound(int i, Value value) alpar@1381: { alpar@1381: //Not implemented, obsolete alpar@1381: } alpar@1381: alpar@1381: void LpCplex::_setRowUpperBound(int i, Value value) alpar@1381: { alpar@1381: //Not implemented, obsolete alpar@1381: // //TODO Ezt kell meg megirni alpar@1381: // //type of the problem alpar@1381: // char sense[1]; alpar@1381: // status = CPXgetsense (env, lp, sense, i, i); alpar@1381: // Value rhs[1]; alpar@1381: // status = CPXgetrhs (env, lp, rhs, i, i); alpar@1381: alpar@1381: // switch (sense[0]) { alpar@1381: // case 'L'://<= constraint alpar@1381: // break; alpar@1381: // case 'E'://= constraint alpar@1381: // break; alpar@1381: // case 'G'://>= constraint alpar@1381: // break; alpar@1381: // case 'R'://ranged constraint alpar@1381: // break; alpar@1381: // default: ; alpar@1381: // //FIXME error alpar@1381: // } alpar@1381: alpar@1381: // status = CPXchgcoef (env, lp, i, -2, value_rng); alpar@1381: } 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: { alpar@1381: //Unimplemented alpar@1381: return OPTIMAL; alpar@1381: // int stat= lpx_get_status(lp); alpar@1381: // switch (stat) { alpar@1381: // case LPX_UNDEF://Undefined (no solve has been run yet) alpar@1381: // return UNDEFINED; alpar@1381: // break; alpar@1381: // case LPX_NOFEAS://There is no feasible solution (primal, I guess) alpar@1381: // case LPX_INFEAS://Infeasible alpar@1381: // return INFEASIBLE; alpar@1381: // break; alpar@1381: // case LPX_UNBND://Unbounded alpar@1381: // return INFINITE; alpar@1381: // break; alpar@1381: // case LPX_FEAS://Feasible alpar@1381: // return FEASIBLE; alpar@1381: // break; alpar@1381: // case LPX_OPT://Feasible alpar@1381: // return OPTIMAL; alpar@1381: // break; alpar@1381: // default: alpar@1381: // return UNDEFINED; //to avoid gcc warning alpar@1381: // //FIXME error alpar@1381: // } 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: { alpar@1381: //Unimplemented alpar@1381: return 0; 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: