src/lemon/lp_cplex.cc
author athos
Thu, 05 May 2005 15:43:43 +0000
changeset 1405 3626c7f10f14
parent 1381 998e8def9676
child 1407 7152559e3d08
permissions -rw-r--r--
Deleted _setRowLowerBound() and _setRowUpperBound() functions. Cplex worked (now it does not because of _getPrimalStatus()).
     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 // CPX_STAT_ABORT_DUAL_OBJ_LIM
   265 // CPX_STAT_ABORT_IT_LIM
   266 // CPX_STAT_ABORT_OBJ_LIM
   267 // CPX_STAT_ABORT_PRIM_OBJ_LIM
   268 // CPX_STAT_ABORT_TIME_LIM
   269 // CPX_STAT_ABORT_USER
   270 // CPX_STAT_FEASIBLE_RELAXED
   271 // CPX_STAT_INFEASIBLE
   272 // CPX_STAT_INForUNBD
   273 // CPX_STAT_NUM_BEST
   274 // CPX_STAT_OPTIMAL
   275 // CPX_STAT_OPTIMAL_FACE_UNBOUNDED
   276 // CPX_STAT_OPTIMAL_INFEAS
   277 // CPX_STAT_OPTIMAL_RELAXED
   278 // CPX_STAT_UNBOUNDED
   279 
   280     //Unimplemented
   281     int stat = CPXgetstat (env, lp);
   282     switch (stat) {
   283     case CPX_STAT_OPTIMAL://Optimal
   284       return OPTIMAL;
   285       break;
   286     case CPX_STAT_INFEASIBLE://Infeasible 
   287       return INFEASIBLE;
   288       break;
   289     case CPX_STAT_UNBOUNDED://Unbounded
   290       return INFINITE;
   291       break;
   292     case CPX_STAT_NUM_BEST://Feasible
   293       return FEASIBLE;
   294       break;
   295     default:
   296       return UNDEFINED; //Everything else comes here
   297       //FIXME error
   298     }
   299   }
   300 
   301   LpCplex::Value LpCplex::_getPrimal(int i)
   302   {
   303     Value x;
   304     CPXgetx (env, lp, &x, i, i);
   305     return x;
   306   }
   307   
   308   LpCplex::Value LpCplex::_getPrimalValue()
   309   {
   310     Value objval;
   311     //method = CPXgetmethod (env, lp);
   312     status = CPXgetobjval (env, lp, &objval);
   313     return objval;
   314   }
   315   
   316  
   317 
   318 
   319   void LpCplex::_setMax()
   320   {
   321     CPXchgobjsen (env, lp, CPX_MAX);
   322    }
   323   void LpCplex::_setMin()
   324   {
   325     CPXchgobjsen (env, lp, CPX_MIN);
   326    }
   327   
   328 } //namespace lemon
   329