lemon/lp_cplex.cc
author athos
Thu, 26 May 2005 15:33:16 +0000
changeset 1438 826bdac3525a
parent 1435 8e85e6bbefdf
child 1458 7a483c1d38b5
permissions -rw-r--r--
Some documentation got revised.
     1 /* -*- C++ -*-
     2  * lemon/lp_cplex.cc - Part of LEMON, a generic C++ optimization library
     3  *
     4  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     5  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     6  *
     7  * Permission to use, modify and distribute this software is granted
     8  * provided that this copyright notice appears in all copies. For
     9  * precise terms see the accompanying LICENSE file.
    10  *
    11  * This software is provided "AS IS" with no warranty of any kind,
    12  * express or implied, and with no claim as to its suitability for any
    13  * purpose.
    14  *
    15  */
    16 #include <iostream>
    17 #include<lemon/lp_cplex.h>
    18 
    19 ///\file
    20 ///\brief Implementation of the LEMON-CPLEX lp solver interface.
    21 namespace lemon {
    22   
    23   LpCplex::LpCplex() : LpSolverBase() {
    24 
    25     //    env = CPXopenCPLEXdevelop(&status);     
    26     env = CPXopenCPLEX(&status);     
    27     lp = CPXcreateprob(env, &status, "LP problem");
    28     //CPXmsg (cpxresults, "Hello-bello\n");
    29   }
    30   
    31   LpCplex::~LpCplex() {
    32     CPXfreeprob(env,&lp); 
    33     CPXcloseCPLEX(&env); 
    34   }
    35   
    36   LpSolverBase &LpCplex::_newLp() 
    37   {
    38     //The first approach opens a new environment
    39     LpCplex* newlp=new LpCplex();
    40     return *newlp;
    41   }
    42 
    43   LpSolverBase &LpCplex::_copyLp() {
    44     //The first approach opens a new environment
    45     LpCplex* newlp=new LpCplex();
    46     //The routine CPXcloneprob can be used to create a new CPLEX problem 
    47     //object and copy all the problem data from an existing problem 
    48     //object to it. Solution and starting information is not copied.
    49     newlp->lp = CPXcloneprob (env, lp, &status);
    50     return *newlp;
    51   }
    52 
    53   int LpCplex::_addCol()
    54   {
    55     int i = CPXgetnumcols (env, lp);
    56     Value lb[1],ub[1];
    57     lb[0]=-INF;//-CPX_INFBOUND;
    58     ub[0]=INF;//CPX_INFBOUND;
    59     status = CPXnewcols (env, lp, 1, NULL, lb, ub, NULL, NULL);
    60     return i;
    61   }
    62 
    63   
    64   int LpCplex::_addRow() 
    65   {
    66     //We want a row that is not constrained
    67     char sense[1];
    68     sense[0]='L';//<= constraint
    69     Value rhs[1];
    70     rhs[0]=INF;
    71     int i = CPXgetnumrows (env, lp);
    72     status = CPXnewrows (env, lp, 1, rhs, sense, NULL, NULL);
    73     return i;
    74   }
    75 
    76 
    77   void LpCplex::_eraseCol(int i) {
    78     CPXdelcols (env, lp, i, i);
    79   }
    80   
    81   void LpCplex::_eraseRow(int i) {
    82     CPXdelrows (env, lp, i, i);
    83   }
    84 
    85   
    86   ///\warning Data at index 0 is ignored in the arrays.
    87   void LpCplex::_setRowCoeffs(int i, 
    88 			      int length,
    89 			      int  const * indices, 
    90 			      Value  const * values )
    91   {
    92     int rowlist[length+1];
    93     int* p=rowlist;
    94     for (int k=1;k<=length;++k){
    95       rowlist[k]=i;
    96     }
    97     status = CPXchgcoeflist(env, lp, 
    98 			    length, 
    99 			    p+1, 
   100 			    const_cast<int * >(indices+1), 
   101 			    const_cast<Value * >(values+1));
   102   }
   103   
   104   void LpCplex::_setColCoeffs(int i, 
   105 			      int length,
   106 			      int  const * indices, 
   107 			      Value  const * values)
   108   {
   109     int collist[length+1];
   110     int* p=collist;
   111     for (int k=1;k<=length;++k){
   112       collist[k]=i;
   113     }
   114     status = CPXchgcoeflist(env, lp, 
   115 			    length, 
   116 			    const_cast<int * >(indices+1), 
   117 			    p+1, 
   118 			    const_cast<Value * >(values+1));
   119   }
   120   
   121   void LpCplex::_setCoeff(int row, int col, Value value) 
   122   {
   123     CPXchgcoef (env, lp, row, col, value);
   124   }
   125 
   126   void LpCplex::_setColLowerBound(int i, Value value)
   127   {
   128     int indices[1];
   129     indices[0]=i;
   130     char lu[1];
   131     lu[0]='L';
   132     Value bd[1];
   133     bd[0]=value;
   134     status = CPXchgbds (env, lp, 1, indices, lu, bd);
   135  
   136   }
   137   
   138   void LpCplex::_setColUpperBound(int i, Value value)
   139   {
   140     int indices[1];
   141     indices[0]=i;
   142     char lu[1];
   143     lu[0]='U';
   144     Value bd[1];
   145     bd[0]=value;
   146     status = CPXchgbds (env, lp, 1, indices, lu, bd);
   147   }
   148 
   149   //This will be easier to implement
   150   void LpCplex::_setRowBounds(int i, Value lb, Value ub)
   151   {
   152     //Bad parameter
   153     if (lb==INF || ub==-INF) {
   154       //FIXME error
   155     }
   156     
   157     int cnt=1;
   158     int indices[1];
   159     indices[0]=i;
   160     char sense[1];
   161 
   162     if (lb==-INF){
   163       sense[0]='L';
   164       CPXchgsense (env, lp, cnt, indices, sense);
   165       CPXchgcoef (env, lp, i, -1, ub);
   166       
   167     }
   168     else{
   169       if (ub==INF){
   170 	sense[0]='G';
   171 	CPXchgsense (env, lp, cnt, indices, sense);
   172 	CPXchgcoef (env, lp, i, -1, lb);
   173       }
   174       else{
   175 	if (lb == ub){
   176 	  sense[0]='E';
   177 	  CPXchgsense (env, lp, cnt, indices, sense);
   178 	  CPXchgcoef (env, lp, i, -1, lb);
   179 	}
   180 	else{
   181 	  sense[0]='R';
   182 	  CPXchgsense (env, lp, cnt, indices, sense);
   183 	  CPXchgcoef (env, lp, i, -1, lb);
   184 	  CPXchgcoef (env, lp, i, -2, ub-lb);	  
   185 	}
   186       }
   187     }
   188   }
   189 
   190 //   void LpCplex::_setRowLowerBound(int i, Value value)
   191 //   {
   192 //     //Not implemented, obsolete
   193 //   }
   194   
   195 //   void LpCplex::_setRowUpperBound(int i, Value value)
   196 //   {
   197 //     //Not implemented, obsolete
   198 // //     //TODO Ezt kell meg megirni
   199 // //     //type of the problem
   200 // //     char sense[1];
   201 // //     status = CPXgetsense (env, lp, sense, i, i);
   202 // //     Value rhs[1];
   203 // //     status = CPXgetrhs (env, lp, rhs, i, i);
   204 
   205 // //     switch (sense[0]) {
   206 // //     case 'L'://<= constraint
   207 // //       break;
   208 // //     case 'E'://= constraint
   209 // //       break;
   210 // //     case 'G'://>= constraint
   211 // //       break;
   212 // //     case 'R'://ranged constraint
   213 // //       break;
   214 // //     default: ;
   215 // //       //FIXME error
   216 // //     }
   217 
   218 // //     status = CPXchgcoef (env, lp, i, -2, value_rng);
   219 //   }
   220   
   221   void LpCplex::_setObjCoeff(int i, Value obj_coef)
   222   {
   223     CPXchgcoef (env, lp, -1, i, obj_coef);
   224   }
   225 
   226   void LpCplex::_clearObj()
   227   {
   228     for (int i=0;i< CPXgetnumcols (env, lp);++i){
   229       CPXchgcoef (env, lp, -1, i, 0);
   230     }
   231     
   232   }
   233 
   234   LpCplex::SolveExitStatus LpCplex::_solve()
   235   {
   236     
   237     status = CPXlpopt (env, lp);
   238     if (status == 0){
   239       return SOLVED;
   240     }
   241     else{
   242       return UNSOLVED;
   243     }
   244 //     int i=  lpx_simplex(lp);
   245 //     switch (i) {
   246 //     case LPX_E_OK: 
   247 //       return SOLVED;
   248 //       break;
   249 //     default:
   250 //       return UNSOLVED;
   251 //     }
   252   }
   253 
   254   LpCplex::SolutionStatus LpCplex::_getPrimalStatus()
   255   {
   256 //7.5-os cplex statusai
   257 // #define CPX_OPTIMAL                      1
   258 // #define CPX_INFEASIBLE                   2
   259 // #define CPX_UNBOUNDED                    3
   260 // #define CPX_OBJ_LIM                      4
   261 // #define CPX_IT_LIM_FEAS                  5
   262 // #define CPX_IT_LIM_INFEAS                6
   263 // #define CPX_TIME_LIM_FEAS                7
   264 // #define CPX_TIME_LIM_INFEAS              8
   265 // #define CPX_NUM_BEST_FEAS                9
   266 // #define CPX_NUM_BEST_INFEAS             10
   267 // #define CPX_OPTIMAL_INFEAS              11
   268 // #define CPX_ABORT_FEAS                  12
   269 // #define CPX_ABORT_INFEAS                13
   270 // #define CPX_ABORT_DUAL_INFEAS           14
   271 // #define CPX_ABORT_PRIM_INFEAS           15
   272 // #define CPX_ABORT_PRIM_DUAL_INFEAS      16
   273 // #define CPX_ABORT_PRIM_DUAL_FEAS        17
   274 // #define CPX_ABORT_CROSSOVER             18
   275 // #define CPX_INForUNBD                   19
   276 // #define CPX_PIVOT                       20
   277 
   278 //     Ezeket hova tegyem:
   279 // ??case CPX_ABORT_DUAL_INFEAS           
   280 // ??case CPX_ABORT_CROSSOVER             
   281 // ??case CPX_INForUNBD                   
   282 // ??case CPX_PIVOT                       
   283 
   284     int stat = CPXgetstat (env, lp);
   285     switch (stat) {
   286     case 0:
   287       return UNDEFINED; //Undefined
   288       break;      
   289     case CPX_OPTIMAL://Optimal
   290       return OPTIMAL;
   291       break;
   292     case CPX_UNBOUNDED://Unbounded
   293       return INFINITE;
   294       break;
   295     case CPX_INFEASIBLE://Infeasible 
   296     case CPX_IT_LIM_INFEAS:
   297     case CPX_TIME_LIM_INFEAS:
   298     case CPX_NUM_BEST_INFEAS:             
   299     case CPX_OPTIMAL_INFEAS:              
   300     case CPX_ABORT_INFEAS:                
   301     case CPX_ABORT_PRIM_INFEAS:           
   302     case CPX_ABORT_PRIM_DUAL_INFEAS:      
   303       return INFEASIBLE;
   304       break;
   305     case CPX_OBJ_LIM:                    
   306     case CPX_IT_LIM_FEAS:             
   307     case CPX_TIME_LIM_FEAS:                
   308     case CPX_NUM_BEST_FEAS:                
   309     case CPX_ABORT_FEAS:                  
   310     case CPX_ABORT_PRIM_DUAL_FEAS:        
   311       return FEASIBLE;
   312       break;
   313     default:
   314       return UNDEFINED; //Everything else comes here
   315       //FIXME error
   316     }
   317 
   318 
   319     //Nem tudom, hanyas cplex verzio statusai
   320 // CPX_STAT_ABORT_DUAL_OBJ_LIM
   321 // CPX_STAT_ABORT_IT_LIM
   322 // CPX_STAT_ABORT_OBJ_LIM
   323 // CPX_STAT_ABORT_PRIM_OBJ_LIM
   324 // CPX_STAT_ABORT_TIME_LIM
   325 // CPX_STAT_ABORT_USER
   326 // CPX_STAT_FEASIBLE_RELAXED
   327 // CPX_STAT_INFEASIBLE
   328 // CPX_STAT_INForUNBD
   329 // CPX_STAT_NUM_BEST
   330 // CPX_STAT_OPTIMAL
   331 // CPX_STAT_OPTIMAL_FACE_UNBOUNDED
   332 // CPX_STAT_OPTIMAL_INFEAS
   333 // CPX_STAT_OPTIMAL_RELAXED
   334 // CPX_STAT_UNBOUNDED
   335 
   336 //     int stat = CPXgetstat (env, lp);
   337 //     switch (stat) {
   338 //     case CPX_STAT_OPTIMAL://Optimal
   339 //       return OPTIMAL;
   340 //       break;
   341 //     case CPX_STAT_INFEASIBLE://Infeasible 
   342 //       return INFEASIBLE;
   343 //       break;
   344 //     case CPX_STAT_UNBOUNDED://Unbounded
   345 //       return INFINITE;
   346 //       break;
   347 //     case CPX_STAT_NUM_BEST://Feasible
   348 //       return FEASIBLE;
   349 //       break;
   350 //     default:
   351 //       return UNDEFINED; //Everything else comes here
   352 //       //FIXME error
   353 //     }
   354 
   355   }
   356 
   357   LpCplex::Value LpCplex::_getPrimal(int i)
   358   {
   359     Value x;
   360     CPXgetx (env, lp, &x, i, i);
   361     return x;
   362   }
   363   
   364   LpCplex::Value LpCplex::_getPrimalValue()
   365   {
   366     Value objval;
   367     //method = CPXgetmethod (env, lp);
   368     status = CPXgetobjval (env, lp, &objval);
   369     return objval;
   370   }
   371   
   372  
   373 
   374 
   375   void LpCplex::_setMax()
   376   {
   377     CPXchgobjsen (env, lp, CPX_MAX);
   378    }
   379   void LpCplex::_setMin()
   380   {
   381     CPXchgobjsen (env, lp, CPX_MIN);
   382    }
   383   
   384 } //namespace lemon
   385