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