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