src/lemon/lp_cplex.cc
changeset 1435 8e85e6bbefdf
parent 1431 ad44b1dd8013
equal deleted inserted replaced
4:32a642a18c13 -1:000000000000
     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 #include <iostream>
       
    18 #include<lemon/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() 
       
    69   {
       
    70     return *(LpSolverBase*)0;
       
    71   }
       
    72   LpSolverBase &LpCplex::_copyLp() {
       
    73     return *(LpSolverBase*)0;
       
    74     //Ez lesz majd CPXcloneprob (env, lp, &status);
       
    75   }
       
    76 
       
    77   int LpCplex::_addCol()
       
    78   {
       
    79     int i = CPXgetnumcols (env, lp);
       
    80     Value lb[1],ub[1];
       
    81     lb[0]=-INF;//-CPX_INFBOUND;
       
    82     ub[0]=INF;//CPX_INFBOUND;
       
    83     status = CPXnewcols (env, lp, 1, NULL, lb, ub, NULL, NULL);
       
    84     return i;
       
    85   }
       
    86   
       
    87   int LpCplex::_addRow() 
       
    88   {
       
    89     //We want a row that is not constrained
       
    90     char sense[1];
       
    91     sense[0]='L';//<= constraint
       
    92     Value rhs[1];
       
    93     rhs[0]=INF;
       
    94     int i = CPXgetnumrows (env, lp);
       
    95     status = CPXnewrows (env, lp, 1, rhs, sense, NULL, NULL);
       
    96     return i;
       
    97   }
       
    98 
       
    99 
       
   100   void LpCplex::_eraseCol(int i) {
       
   101     ///\todo Not implemented yet
       
   102   }
       
   103   
       
   104   void LpCplex::_eraseRow(int i) {
       
   105     ///\todo Not implemented yet
       
   106   }
       
   107 
       
   108   
       
   109   ///\warning Data at index 0 is ignored in the arrays.
       
   110   void LpCplex::_setRowCoeffs(int i, 
       
   111 			      int length,
       
   112 			      int  const * indices, 
       
   113 			      Value  const * values )
       
   114   {
       
   115     int rowlist[length+1];
       
   116     int* p=rowlist;
       
   117     for (int k=1;k<=length;++k){
       
   118       rowlist[k]=i;
       
   119     }
       
   120     status = CPXchgcoeflist(env, lp, 
       
   121 			    length, 
       
   122 			    p+1, 
       
   123 			    const_cast<int * >(indices+1), 
       
   124 			    const_cast<Value * >(values+1));
       
   125   }
       
   126   
       
   127   void LpCplex::_setColCoeffs(int i, 
       
   128 			      int length,
       
   129 			      int  const * indices, 
       
   130 			      Value  const * values)
       
   131   {
       
   132     int collist[length+1];
       
   133     int* p=collist;
       
   134     for (int k=1;k<=length;++k){
       
   135       collist[k]=i;
       
   136     }
       
   137     status = CPXchgcoeflist(env, lp, 
       
   138 			    length, 
       
   139 			    const_cast<int * >(indices+1), 
       
   140 			    p+1, 
       
   141 			    const_cast<Value * >(values+1));
       
   142   }
       
   143   
       
   144   void LpCplex::_setCoeff(int row, int col, Value value) 
       
   145   {
       
   146     CPXchgcoef (env, lp, row, col, value);
       
   147   }
       
   148 
       
   149   void LpCplex::_setColLowerBound(int i, Value value)
       
   150   {
       
   151     int indices[1];
       
   152     indices[0]=i;
       
   153     char lu[1];
       
   154     lu[0]='L';
       
   155     Value bd[1];
       
   156     bd[0]=value;
       
   157     status = CPXchgbds (env, lp, 1, indices, lu, bd);
       
   158  
       
   159   }
       
   160   
       
   161   void LpCplex::_setColUpperBound(int i, Value value)
       
   162   {
       
   163     int indices[1];
       
   164     indices[0]=i;
       
   165     char lu[1];
       
   166     lu[0]='U';
       
   167     Value bd[1];
       
   168     bd[0]=value;
       
   169     status = CPXchgbds (env, lp, 1, indices, lu, bd);
       
   170   }
       
   171 
       
   172   //This will be easier to implement
       
   173   void LpCplex::_setRowBounds(int i, Value lb, Value ub)
       
   174   {
       
   175     //Bad parameter
       
   176     if (lb==INF || ub==-INF) {
       
   177       //FIXME error
       
   178     }
       
   179     
       
   180     int cnt=1;
       
   181     int indices[1];
       
   182     indices[0]=i;
       
   183     char sense[1];
       
   184 
       
   185     if (lb==-INF){
       
   186       sense[0]='L';
       
   187       CPXchgsense (env, lp, cnt, indices, sense);
       
   188       CPXchgcoef (env, lp, i, -1, ub);
       
   189       
       
   190     }
       
   191     else{
       
   192       if (ub==INF){
       
   193 	sense[0]='G';
       
   194 	CPXchgsense (env, lp, cnt, indices, sense);
       
   195 	CPXchgcoef (env, lp, i, -1, lb);
       
   196       }
       
   197       else{
       
   198 	if (lb == ub){
       
   199 	  sense[0]='E';
       
   200 	  CPXchgsense (env, lp, cnt, indices, sense);
       
   201 	  CPXchgcoef (env, lp, i, -1, lb);
       
   202 	}
       
   203 	else{
       
   204 	  sense[0]='R';
       
   205 	  CPXchgsense (env, lp, cnt, indices, sense);
       
   206 	  CPXchgcoef (env, lp, i, -1, lb);
       
   207 	  CPXchgcoef (env, lp, i, -2, ub-lb);	  
       
   208 	}
       
   209       }
       
   210     }
       
   211   }
       
   212 
       
   213 //   void LpCplex::_setRowLowerBound(int i, Value value)
       
   214 //   {
       
   215 //     //Not implemented, obsolete
       
   216 //   }
       
   217   
       
   218 //   void LpCplex::_setRowUpperBound(int i, Value value)
       
   219 //   {
       
   220 //     //Not implemented, obsolete
       
   221 // //     //TODO Ezt kell meg megirni
       
   222 // //     //type of the problem
       
   223 // //     char sense[1];
       
   224 // //     status = CPXgetsense (env, lp, sense, i, i);
       
   225 // //     Value rhs[1];
       
   226 // //     status = CPXgetrhs (env, lp, rhs, i, i);
       
   227 
       
   228 // //     switch (sense[0]) {
       
   229 // //     case 'L'://<= constraint
       
   230 // //       break;
       
   231 // //     case 'E'://= constraint
       
   232 // //       break;
       
   233 // //     case 'G'://>= constraint
       
   234 // //       break;
       
   235 // //     case 'R'://ranged constraint
       
   236 // //       break;
       
   237 // //     default: ;
       
   238 // //       //FIXME error
       
   239 // //     }
       
   240 
       
   241 // //     status = CPXchgcoef (env, lp, i, -2, value_rng);
       
   242 //   }
       
   243   
       
   244   void LpCplex::_setObjCoeff(int i, Value obj_coef)
       
   245   {
       
   246     CPXchgcoef (env, lp, -1, i, obj_coef);
       
   247   }
       
   248 
       
   249   void LpCplex::_clearObj()
       
   250   {
       
   251     for (int i=0;i< CPXgetnumcols (env, lp);++i){
       
   252       CPXchgcoef (env, lp, -1, i, 0);
       
   253     }
       
   254     
       
   255   }
       
   256 
       
   257   LpCplex::SolveExitStatus LpCplex::_solve()
       
   258   {
       
   259     
       
   260     status = CPXlpopt (env, lp);
       
   261     if (status == 0){
       
   262       return SOLVED;
       
   263     }
       
   264     else{
       
   265       return UNSOLVED;
       
   266     }
       
   267 //     int i=  lpx_simplex(lp);
       
   268 //     switch (i) {
       
   269 //     case LPX_E_OK: 
       
   270 //       return SOLVED;
       
   271 //       break;
       
   272 //     default:
       
   273 //       return UNSOLVED;
       
   274 //     }
       
   275   }
       
   276 
       
   277   LpCplex::SolutionStatus LpCplex::_getPrimalStatus()
       
   278   {
       
   279 //7.5-os cplex statusai
       
   280 // #define CPX_OPTIMAL                      1
       
   281 // #define CPX_INFEASIBLE                   2
       
   282 // #define CPX_UNBOUNDED                    3
       
   283 // #define CPX_OBJ_LIM                      4
       
   284 // #define CPX_IT_LIM_FEAS                  5
       
   285 // #define CPX_IT_LIM_INFEAS                6
       
   286 // #define CPX_TIME_LIM_FEAS                7
       
   287 // #define CPX_TIME_LIM_INFEAS              8
       
   288 // #define CPX_NUM_BEST_FEAS                9
       
   289 // #define CPX_NUM_BEST_INFEAS             10
       
   290 // #define CPX_OPTIMAL_INFEAS              11
       
   291 // #define CPX_ABORT_FEAS                  12
       
   292 // #define CPX_ABORT_INFEAS                13
       
   293 // #define CPX_ABORT_DUAL_INFEAS           14
       
   294 // #define CPX_ABORT_PRIM_INFEAS           15
       
   295 // #define CPX_ABORT_PRIM_DUAL_INFEAS      16
       
   296 // #define CPX_ABORT_PRIM_DUAL_FEAS        17
       
   297 // #define CPX_ABORT_CROSSOVER             18
       
   298 // #define CPX_INForUNBD                   19
       
   299 // #define CPX_PIVOT                       20
       
   300 
       
   301 //     Ezeket hova tegyem:
       
   302 // ??case CPX_ABORT_DUAL_INFEAS           
       
   303 // ??case CPX_ABORT_CROSSOVER             
       
   304 // ??case CPX_INForUNBD                   
       
   305 // ??case CPX_PIVOT                       
       
   306 
       
   307     int stat = CPXgetstat (env, lp);
       
   308     switch (stat) {
       
   309     case 0:
       
   310       return UNDEFINED; //Undefined
       
   311       break;      
       
   312     case CPX_OPTIMAL://Optimal
       
   313       return OPTIMAL;
       
   314       break;
       
   315     case CPX_UNBOUNDED://Unbounded
       
   316       return INFINITE;
       
   317       break;
       
   318     case CPX_INFEASIBLE://Infeasible 
       
   319     case CPX_IT_LIM_INFEAS:
       
   320     case CPX_TIME_LIM_INFEAS:
       
   321     case CPX_NUM_BEST_INFEAS:             
       
   322     case CPX_OPTIMAL_INFEAS:              
       
   323     case CPX_ABORT_INFEAS:                
       
   324     case CPX_ABORT_PRIM_INFEAS:           
       
   325     case CPX_ABORT_PRIM_DUAL_INFEAS:      
       
   326       return INFEASIBLE;
       
   327       break;
       
   328     case CPX_OBJ_LIM:                    
       
   329     case CPX_IT_LIM_FEAS:             
       
   330     case CPX_TIME_LIM_FEAS:                
       
   331     case CPX_NUM_BEST_FEAS:                
       
   332     case CPX_ABORT_FEAS:                  
       
   333     case CPX_ABORT_PRIM_DUAL_FEAS:        
       
   334       return FEASIBLE;
       
   335       break;
       
   336     default:
       
   337       return UNDEFINED; //Everything else comes here
       
   338       //FIXME error
       
   339     }
       
   340 
       
   341 
       
   342     //Nem tudom, hanyas cplex verzio statusai
       
   343 // CPX_STAT_ABORT_DUAL_OBJ_LIM
       
   344 // CPX_STAT_ABORT_IT_LIM
       
   345 // CPX_STAT_ABORT_OBJ_LIM
       
   346 // CPX_STAT_ABORT_PRIM_OBJ_LIM
       
   347 // CPX_STAT_ABORT_TIME_LIM
       
   348 // CPX_STAT_ABORT_USER
       
   349 // CPX_STAT_FEASIBLE_RELAXED
       
   350 // CPX_STAT_INFEASIBLE
       
   351 // CPX_STAT_INForUNBD
       
   352 // CPX_STAT_NUM_BEST
       
   353 // CPX_STAT_OPTIMAL
       
   354 // CPX_STAT_OPTIMAL_FACE_UNBOUNDED
       
   355 // CPX_STAT_OPTIMAL_INFEAS
       
   356 // CPX_STAT_OPTIMAL_RELAXED
       
   357 // CPX_STAT_UNBOUNDED
       
   358 
       
   359 //     int stat = CPXgetstat (env, lp);
       
   360 //     switch (stat) {
       
   361 //     case CPX_STAT_OPTIMAL://Optimal
       
   362 //       return OPTIMAL;
       
   363 //       break;
       
   364 //     case CPX_STAT_INFEASIBLE://Infeasible 
       
   365 //       return INFEASIBLE;
       
   366 //       break;
       
   367 //     case CPX_STAT_UNBOUNDED://Unbounded
       
   368 //       return INFINITE;
       
   369 //       break;
       
   370 //     case CPX_STAT_NUM_BEST://Feasible
       
   371 //       return FEASIBLE;
       
   372 //       break;
       
   373 //     default:
       
   374 //       return UNDEFINED; //Everything else comes here
       
   375 //       //FIXME error
       
   376 //     }
       
   377 
       
   378   }
       
   379 
       
   380   LpCplex::Value LpCplex::_getPrimal(int i)
       
   381   {
       
   382     Value x;
       
   383     CPXgetx (env, lp, &x, i, i);
       
   384     return x;
       
   385   }
       
   386   
       
   387   LpCplex::Value LpCplex::_getPrimalValue()
       
   388   {
       
   389     Value objval;
       
   390     //method = CPXgetmethod (env, lp);
       
   391     status = CPXgetobjval (env, lp, &objval);
       
   392     return objval;
       
   393   }
       
   394   
       
   395  
       
   396 
       
   397 
       
   398   void LpCplex::_setMax()
       
   399   {
       
   400     CPXchgobjsen (env, lp, CPX_MAX);
       
   401    }
       
   402   void LpCplex::_setMin()
       
   403   {
       
   404     CPXchgobjsen (env, lp, CPX_MIN);
       
   405    }
       
   406   
       
   407 } //namespace lemon
       
   408