src/lemon/lp_cplex.cc
changeset 1396 56f9a4ba9149
child 1405 3626c7f10f14
equal deleted inserted replaced
-1:000000000000 0:e920226fe141
       
     1 /* -*- C++ -*-
       
     2  * src/lemon/lp_cplex.cc
       
     3  * - Part of LEMON, a generic C++ optimization library
       
     4  *
       
     5  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
       
     6  * (Egervary Research Group on Combinatorial Optimization, EGRES).
       
     7  *
       
     8  * Permission to use, modify and distribute this software is granted
       
     9  * provided that this copyright notice appears in all copies. For
       
    10  * precise terms see the accompanying LICENSE file.
       
    11  *
       
    12  * This software is provided "AS IS" with no warranty of any kind,
       
    13  * express or implied, and with no claim as to its suitability for any
       
    14  * purpose.
       
    15  *
       
    16  */
       
    17 
       
    18 #include"lp_cplex.h"
       
    19 
       
    20 ///\file
       
    21 ///\brief Implementation of the LEMON-CPLEX lp solver interface.
       
    22 namespace lemon {
       
    23   
       
    24   LpCplex::LpCplex() : LpSolverBase() {
       
    25     env = NULL;
       
    26     lp = NULL;
       
    27     env = CPXopenCPLEXdevelop(&status);     
       
    28 //     if (Env == NULL)
       
    29 //     {
       
    30 //          fprintf(stderr,"A CPLEX környezet megnyitása sikertelen.\n");
       
    31 // 	 CPXgeterrorstring(Env, Status, ErrorMsg);
       
    32 // 	 fprintf(stderr,"%s",ErrorMsg);
       
    33 // 	 goto Terminate;
       
    34 //     }
       
    35     
       
    36     // *** A problema létrehozása ***
       
    37     lp = CPXcreateprob(env, &status, "LP problem");
       
    38     
       
    39     //    if (Problem == NULL)
       
    40 //     {
       
    41 // 	fprintf(stderr,"Az LP létrehozása sikertelen");
       
    42 // 	goto Terminate;
       
    43 //     }
       
    44     
       
    45   }
       
    46   
       
    47   LpCplex::~LpCplex() {
       
    48     status = CPXfreeprob(env,&lp); 
       
    49     //       if (Status != 0)
       
    50     // 	{
       
    51 // 	  fprintf(stderr,"A CPLEX feladat törlése sikertelen.\n");
       
    52 // 	  CPXgeterrorstring(Env, Status, ErrorMsg);
       
    53 // 	  fprintf(stderr,"%s",ErrorMsg);
       
    54 // 	  goto Terminate;
       
    55 // 	}
       
    56        
       
    57     status = CPXcloseCPLEX(&env); 
       
    58     //       if (Status != 0)
       
    59     // 	{
       
    60     // 	  fprintf(stderr,"A CPLEX környezet bezárása sikertelen.\n");
       
    61 // 	  CPXgeterrorstring(Env, Status, ErrorMsg);
       
    62 // 	  fprintf(stderr,"%s",ErrorMsg);
       
    63 // 	  goto Terminate;
       
    64 // 	}
       
    65       
       
    66   }
       
    67   
       
    68   LpSolverBase &LpCplex::_newLp() {return *(LpSolverBase*)0;}
       
    69   LpSolverBase &LpCplex::_copyLp() {return *(LpSolverBase*)0;}
       
    70 
       
    71   int LpCplex::_addCol()
       
    72   {
       
    73     int i = CPXgetnumcols (env, lp);
       
    74     Value lb[1],ub[1];
       
    75     lb[0]=-INF;//-CPX_INFBOUND;
       
    76     ub[0]=INF;//CPX_INFBOUND;
       
    77     status = CPXnewcols (env, lp, 1, NULL, lb, ub, NULL, NULL);
       
    78     return i;
       
    79   }
       
    80   
       
    81   int LpCplex::_addRow() 
       
    82   {
       
    83     //We want a row that is not constrained
       
    84     char sense[1];
       
    85     sense[0]='L';//<= constraint
       
    86     Value rhs[1];
       
    87     rhs[0]=INF;
       
    88     int i = CPXgetnumrows (env, lp);
       
    89     status = CPXnewrows (env, lp, 1, rhs, sense, NULL, NULL);
       
    90     return i;
       
    91   }
       
    92   
       
    93   ///\warning Data at index 0 is ignored in the arrays.
       
    94   void LpCplex::_setRowCoeffs(int i, 
       
    95 			      int length,
       
    96 			      int  const * indices, 
       
    97 			      Value  const * values )
       
    98   {
       
    99     int rowlist[length+1];
       
   100     int* p=rowlist;
       
   101     for (int k=1;k<=length;++k){
       
   102       rowlist[k]=i;
       
   103     }
       
   104     status = CPXchgcoeflist(env, lp, 
       
   105 			    length, 
       
   106 			    p+1, 
       
   107 			    const_cast<int * >(indices+1), 
       
   108 			    const_cast<Value * >(values+1));
       
   109   }
       
   110   
       
   111   void LpCplex::_setColCoeffs(int i, 
       
   112 			      int length,
       
   113 			      int  const * indices, 
       
   114 			      Value  const * values)
       
   115   {
       
   116     int collist[length+1];
       
   117     int* p=collist;
       
   118     for (int k=1;k<=length;++k){
       
   119       collist[k]=i;
       
   120     }
       
   121     status = CPXchgcoeflist(env, lp, 
       
   122 			    length, 
       
   123 			    const_cast<int * >(indices+1), 
       
   124 			    p+1, 
       
   125 			    const_cast<Value * >(values+1));
       
   126   }
       
   127   
       
   128   void LpCplex::_setColLowerBound(int i, Value value)
       
   129   {
       
   130     int indices[1];
       
   131     indices[0]=i;
       
   132     char lu[1];
       
   133     lu[0]='L';
       
   134     Value bd[1];
       
   135     bd[0]=value;
       
   136     status = CPXchgbds (env, lp, 1, indices, lu, bd);
       
   137  
       
   138   }
       
   139   
       
   140   void LpCplex::_setColUpperBound(int i, Value value)
       
   141   {
       
   142     int indices[1];
       
   143     indices[0]=i;
       
   144     char lu[1];
       
   145     lu[0]='U';
       
   146     Value bd[1];
       
   147     bd[0]=value;
       
   148     status = CPXchgbds (env, lp, 1, indices, lu, bd);
       
   149   }
       
   150 
       
   151   //This will be easier to implement
       
   152   void LpCplex::_setRowBounds(int i, Value lb, Value ub)
       
   153   {
       
   154     //Bad parameter
       
   155     if (lb==INF || ub==-INF) {
       
   156       //FIXME error
       
   157     }
       
   158 
       
   159     int cnt=1;
       
   160     int indices[1];
       
   161     indices[0]=i;
       
   162     char sense[1];
       
   163 
       
   164     if (lb==-INF){
       
   165       sense[0]='L';
       
   166       CPXchgsense (env, lp, cnt, indices, sense);
       
   167       CPXchgcoef (env, lp, i, -1, ub);
       
   168     }
       
   169     else{
       
   170       if (ub==INF){
       
   171 	sense[0]='G';
       
   172 	CPXchgsense (env, lp, cnt, indices, sense);
       
   173 	CPXchgcoef (env, lp, i, -1, lb);
       
   174       }
       
   175       else{
       
   176 	if (lb == ub){
       
   177 	  sense[0]='E';
       
   178 	  CPXchgsense (env, lp, cnt, indices, sense);
       
   179 	  CPXchgcoef (env, lp, i, -1, lb);
       
   180 	}
       
   181 	else{
       
   182 	  sense[0]='R';
       
   183 	  CPXchgsense (env, lp, cnt, indices, sense);
       
   184 	  CPXchgcoef (env, lp, i, -1, lb);
       
   185 	  CPXchgcoef (env, lp, i, -2, ub-lb);	  
       
   186 	}
       
   187       }
       
   188     }
       
   189   }
       
   190 
       
   191   void LpCplex::_setRowLowerBound(int i, Value value)
       
   192   {
       
   193     //Not implemented, obsolete
       
   194   }
       
   195   
       
   196   void LpCplex::_setRowUpperBound(int i, Value value)
       
   197   {
       
   198     //Not implemented, obsolete
       
   199 //     //TODO Ezt kell meg megirni
       
   200 //     //type of the problem
       
   201 //     char sense[1];
       
   202 //     status = CPXgetsense (env, lp, sense, i, i);
       
   203 //     Value rhs[1];
       
   204 //     status = CPXgetrhs (env, lp, rhs, i, i);
       
   205 
       
   206 //     switch (sense[0]) {
       
   207 //     case 'L'://<= constraint
       
   208 //       break;
       
   209 //     case 'E'://= constraint
       
   210 //       break;
       
   211 //     case 'G'://>= constraint
       
   212 //       break;
       
   213 //     case 'R'://ranged constraint
       
   214 //       break;
       
   215 //     default: ;
       
   216 //       //FIXME error
       
   217 //     }
       
   218 
       
   219 //     status = CPXchgcoef (env, lp, i, -2, value_rng);
       
   220   }
       
   221   
       
   222   void LpCplex::_setObjCoeff(int i, Value obj_coef)
       
   223   {
       
   224     CPXchgcoef (env, lp, -1, i, obj_coef);
       
   225   }
       
   226 
       
   227   void LpCplex::_clearObj()
       
   228   {
       
   229     for (int i=0;i< CPXgetnumcols (env, lp);++i){
       
   230       CPXchgcoef (env, lp, -1, i, 0);
       
   231     }
       
   232     
       
   233   }
       
   234 
       
   235   LpCplex::SolveExitStatus LpCplex::_solve()
       
   236   {
       
   237     
       
   238     status = CPXlpopt (env, lp);
       
   239     if (status == 0){
       
   240       return SOLVED;
       
   241     }
       
   242     else{
       
   243       return UNSOLVED;
       
   244     }
       
   245 //     int i=  lpx_simplex(lp);
       
   246 //     switch (i) {
       
   247 //     case LPX_E_OK: 
       
   248 //       return SOLVED;
       
   249 //       break;
       
   250 //     default:
       
   251 //       return UNSOLVED;
       
   252 //     }
       
   253   }
       
   254 
       
   255   LpCplex::SolutionStatus LpCplex::_getPrimalStatus()
       
   256   {
       
   257     //Unimplemented
       
   258     return OPTIMAL;
       
   259 //     int stat=  lpx_get_status(lp);
       
   260 //     switch (stat) {
       
   261 //     case LPX_UNDEF://Undefined (no solve has been run yet)
       
   262 //       return UNDEFINED;
       
   263 //       break;
       
   264 //     case LPX_NOFEAS://There is no feasible solution (primal, I guess)
       
   265 //     case LPX_INFEAS://Infeasible 
       
   266 //       return INFEASIBLE;
       
   267 //       break;
       
   268 //     case LPX_UNBND://Unbounded
       
   269 //       return INFINITE;
       
   270 //       break;
       
   271 //     case LPX_FEAS://Feasible
       
   272 //       return FEASIBLE;
       
   273 //       break;
       
   274 //     case LPX_OPT://Feasible
       
   275 //       return OPTIMAL;
       
   276 //       break;
       
   277 //     default:
       
   278 //       return UNDEFINED; //to avoid gcc warning
       
   279 //       //FIXME error
       
   280 //     }
       
   281   }
       
   282 
       
   283   LpCplex::Value LpCplex::_getPrimal(int i)
       
   284   {
       
   285     Value x;
       
   286     CPXgetx (env, lp, &x, i, i);
       
   287     return x;
       
   288   }
       
   289   
       
   290   LpCplex::Value LpCplex::_getPrimalValue()
       
   291   {
       
   292     //Unimplemented
       
   293     return 0;
       
   294   }
       
   295   
       
   296  
       
   297 
       
   298 
       
   299   void LpCplex::_setMax()
       
   300   {
       
   301     CPXchgobjsen (env, lp, CPX_MAX);
       
   302    }
       
   303   void LpCplex::_setMin()
       
   304   {
       
   305     CPXchgobjsen (env, lp, CPX_MIN);
       
   306    }
       
   307   
       
   308 } //namespace lemon
       
   309