src/lemon/lp_cplex.cc
author ladanyi
Sun, 24 Apr 2005 22:30:54 +0000
changeset 1386 324c291a8daf
child 1405 3626c7f10f14
permissions -rw-r--r--
This way it works also when both GLPK and CPLEX are enabled.
alpar@1381
     1
/* -*- C++ -*-
alpar@1381
     2
 * src/lemon/lp_cplex.cc
alpar@1381
     3
 * - Part of LEMON, a generic C++ optimization library
alpar@1381
     4
 *
alpar@1381
     5
 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@1381
     6
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@1381
     7
 *
alpar@1381
     8
 * Permission to use, modify and distribute this software is granted
alpar@1381
     9
 * provided that this copyright notice appears in all copies. For
alpar@1381
    10
 * precise terms see the accompanying LICENSE file.
alpar@1381
    11
 *
alpar@1381
    12
 * This software is provided "AS IS" with no warranty of any kind,
alpar@1381
    13
 * express or implied, and with no claim as to its suitability for any
alpar@1381
    14
 * purpose.
alpar@1381
    15
 *
alpar@1381
    16
 */
alpar@1381
    17
alpar@1381
    18
#include"lp_cplex.h"
alpar@1381
    19
alpar@1381
    20
///\file
alpar@1381
    21
///\brief Implementation of the LEMON-CPLEX lp solver interface.
alpar@1381
    22
namespace lemon {
alpar@1381
    23
  
alpar@1381
    24
  LpCplex::LpCplex() : LpSolverBase() {
alpar@1381
    25
    env = NULL;
alpar@1381
    26
    lp = NULL;
alpar@1381
    27
    env = CPXopenCPLEXdevelop(&status);     
alpar@1381
    28
//     if (Env == NULL)
alpar@1381
    29
//     {
alpar@1381
    30
//          fprintf(stderr,"A CPLEX környezet megnyitása sikertelen.\n");
alpar@1381
    31
// 	 CPXgeterrorstring(Env, Status, ErrorMsg);
alpar@1381
    32
// 	 fprintf(stderr,"%s",ErrorMsg);
alpar@1381
    33
// 	 goto Terminate;
alpar@1381
    34
//     }
alpar@1381
    35
    
alpar@1381
    36
    // *** A problema létrehozása ***
alpar@1381
    37
    lp = CPXcreateprob(env, &status, "LP problem");
alpar@1381
    38
    
alpar@1381
    39
    //    if (Problem == NULL)
alpar@1381
    40
//     {
alpar@1381
    41
// 	fprintf(stderr,"Az LP létrehozása sikertelen");
alpar@1381
    42
// 	goto Terminate;
alpar@1381
    43
//     }
alpar@1381
    44
    
alpar@1381
    45
  }
alpar@1381
    46
  
alpar@1381
    47
  LpCplex::~LpCplex() {
alpar@1381
    48
    status = CPXfreeprob(env,&lp); 
alpar@1381
    49
    //       if (Status != 0)
alpar@1381
    50
    // 	{
alpar@1381
    51
// 	  fprintf(stderr,"A CPLEX feladat törlése sikertelen.\n");
alpar@1381
    52
// 	  CPXgeterrorstring(Env, Status, ErrorMsg);
alpar@1381
    53
// 	  fprintf(stderr,"%s",ErrorMsg);
alpar@1381
    54
// 	  goto Terminate;
alpar@1381
    55
// 	}
alpar@1381
    56
       
alpar@1381
    57
    status = CPXcloseCPLEX(&env); 
alpar@1381
    58
    //       if (Status != 0)
alpar@1381
    59
    // 	{
alpar@1381
    60
    // 	  fprintf(stderr,"A CPLEX környezet bezárása sikertelen.\n");
alpar@1381
    61
// 	  CPXgeterrorstring(Env, Status, ErrorMsg);
alpar@1381
    62
// 	  fprintf(stderr,"%s",ErrorMsg);
alpar@1381
    63
// 	  goto Terminate;
alpar@1381
    64
// 	}
alpar@1381
    65
      
alpar@1381
    66
  }
alpar@1381
    67
  
alpar@1381
    68
  LpSolverBase &LpCplex::_newLp() {return *(LpSolverBase*)0;}
alpar@1381
    69
  LpSolverBase &LpCplex::_copyLp() {return *(LpSolverBase*)0;}
alpar@1381
    70
alpar@1381
    71
  int LpCplex::_addCol()
alpar@1381
    72
  {
alpar@1381
    73
    int i = CPXgetnumcols (env, lp);
alpar@1381
    74
    Value lb[1],ub[1];
alpar@1381
    75
    lb[0]=-INF;//-CPX_INFBOUND;
alpar@1381
    76
    ub[0]=INF;//CPX_INFBOUND;
alpar@1381
    77
    status = CPXnewcols (env, lp, 1, NULL, lb, ub, NULL, NULL);
alpar@1381
    78
    return i;
alpar@1381
    79
  }
alpar@1381
    80
  
alpar@1381
    81
  int LpCplex::_addRow() 
alpar@1381
    82
  {
alpar@1381
    83
    //We want a row that is not constrained
alpar@1381
    84
    char sense[1];
alpar@1381
    85
    sense[0]='L';//<= constraint
alpar@1381
    86
    Value rhs[1];
alpar@1381
    87
    rhs[0]=INF;
alpar@1381
    88
    int i = CPXgetnumrows (env, lp);
alpar@1381
    89
    status = CPXnewrows (env, lp, 1, rhs, sense, NULL, NULL);
alpar@1381
    90
    return i;
alpar@1381
    91
  }
alpar@1381
    92
  
alpar@1381
    93
  ///\warning Data at index 0 is ignored in the arrays.
alpar@1381
    94
  void LpCplex::_setRowCoeffs(int i, 
alpar@1381
    95
			      int length,
alpar@1381
    96
			      int  const * indices, 
alpar@1381
    97
			      Value  const * values )
alpar@1381
    98
  {
alpar@1381
    99
    int rowlist[length+1];
alpar@1381
   100
    int* p=rowlist;
alpar@1381
   101
    for (int k=1;k<=length;++k){
alpar@1381
   102
      rowlist[k]=i;
alpar@1381
   103
    }
alpar@1381
   104
    status = CPXchgcoeflist(env, lp, 
alpar@1381
   105
			    length, 
alpar@1381
   106
			    p+1, 
alpar@1381
   107
			    const_cast<int * >(indices+1), 
alpar@1381
   108
			    const_cast<Value * >(values+1));
alpar@1381
   109
  }
alpar@1381
   110
  
alpar@1381
   111
  void LpCplex::_setColCoeffs(int i, 
alpar@1381
   112
			      int length,
alpar@1381
   113
			      int  const * indices, 
alpar@1381
   114
			      Value  const * values)
alpar@1381
   115
  {
alpar@1381
   116
    int collist[length+1];
alpar@1381
   117
    int* p=collist;
alpar@1381
   118
    for (int k=1;k<=length;++k){
alpar@1381
   119
      collist[k]=i;
alpar@1381
   120
    }
alpar@1381
   121
    status = CPXchgcoeflist(env, lp, 
alpar@1381
   122
			    length, 
alpar@1381
   123
			    const_cast<int * >(indices+1), 
alpar@1381
   124
			    p+1, 
alpar@1381
   125
			    const_cast<Value * >(values+1));
alpar@1381
   126
  }
alpar@1381
   127
  
alpar@1381
   128
  void LpCplex::_setColLowerBound(int i, Value value)
alpar@1381
   129
  {
alpar@1381
   130
    int indices[1];
alpar@1381
   131
    indices[0]=i;
alpar@1381
   132
    char lu[1];
alpar@1381
   133
    lu[0]='L';
alpar@1381
   134
    Value bd[1];
alpar@1381
   135
    bd[0]=value;
alpar@1381
   136
    status = CPXchgbds (env, lp, 1, indices, lu, bd);
alpar@1381
   137
 
alpar@1381
   138
  }
alpar@1381
   139
  
alpar@1381
   140
  void LpCplex::_setColUpperBound(int i, Value value)
alpar@1381
   141
  {
alpar@1381
   142
    int indices[1];
alpar@1381
   143
    indices[0]=i;
alpar@1381
   144
    char lu[1];
alpar@1381
   145
    lu[0]='U';
alpar@1381
   146
    Value bd[1];
alpar@1381
   147
    bd[0]=value;
alpar@1381
   148
    status = CPXchgbds (env, lp, 1, indices, lu, bd);
alpar@1381
   149
  }
alpar@1381
   150
alpar@1381
   151
  //This will be easier to implement
alpar@1381
   152
  void LpCplex::_setRowBounds(int i, Value lb, Value ub)
alpar@1381
   153
  {
alpar@1381
   154
    //Bad parameter
alpar@1381
   155
    if (lb==INF || ub==-INF) {
alpar@1381
   156
      //FIXME error
alpar@1381
   157
    }
alpar@1381
   158
alpar@1381
   159
    int cnt=1;
alpar@1381
   160
    int indices[1];
alpar@1381
   161
    indices[0]=i;
alpar@1381
   162
    char sense[1];
alpar@1381
   163
alpar@1381
   164
    if (lb==-INF){
alpar@1381
   165
      sense[0]='L';
alpar@1381
   166
      CPXchgsense (env, lp, cnt, indices, sense);
alpar@1381
   167
      CPXchgcoef (env, lp, i, -1, ub);
alpar@1381
   168
    }
alpar@1381
   169
    else{
alpar@1381
   170
      if (ub==INF){
alpar@1381
   171
	sense[0]='G';
alpar@1381
   172
	CPXchgsense (env, lp, cnt, indices, sense);
alpar@1381
   173
	CPXchgcoef (env, lp, i, -1, lb);
alpar@1381
   174
      }
alpar@1381
   175
      else{
alpar@1381
   176
	if (lb == ub){
alpar@1381
   177
	  sense[0]='E';
alpar@1381
   178
	  CPXchgsense (env, lp, cnt, indices, sense);
alpar@1381
   179
	  CPXchgcoef (env, lp, i, -1, lb);
alpar@1381
   180
	}
alpar@1381
   181
	else{
alpar@1381
   182
	  sense[0]='R';
alpar@1381
   183
	  CPXchgsense (env, lp, cnt, indices, sense);
alpar@1381
   184
	  CPXchgcoef (env, lp, i, -1, lb);
alpar@1381
   185
	  CPXchgcoef (env, lp, i, -2, ub-lb);	  
alpar@1381
   186
	}
alpar@1381
   187
      }
alpar@1381
   188
    }
alpar@1381
   189
  }
alpar@1381
   190
alpar@1381
   191
  void LpCplex::_setRowLowerBound(int i, Value value)
alpar@1381
   192
  {
alpar@1381
   193
    //Not implemented, obsolete
alpar@1381
   194
  }
alpar@1381
   195
  
alpar@1381
   196
  void LpCplex::_setRowUpperBound(int i, Value value)
alpar@1381
   197
  {
alpar@1381
   198
    //Not implemented, obsolete
alpar@1381
   199
//     //TODO Ezt kell meg megirni
alpar@1381
   200
//     //type of the problem
alpar@1381
   201
//     char sense[1];
alpar@1381
   202
//     status = CPXgetsense (env, lp, sense, i, i);
alpar@1381
   203
//     Value rhs[1];
alpar@1381
   204
//     status = CPXgetrhs (env, lp, rhs, i, i);
alpar@1381
   205
alpar@1381
   206
//     switch (sense[0]) {
alpar@1381
   207
//     case 'L'://<= constraint
alpar@1381
   208
//       break;
alpar@1381
   209
//     case 'E'://= constraint
alpar@1381
   210
//       break;
alpar@1381
   211
//     case 'G'://>= constraint
alpar@1381
   212
//       break;
alpar@1381
   213
//     case 'R'://ranged constraint
alpar@1381
   214
//       break;
alpar@1381
   215
//     default: ;
alpar@1381
   216
//       //FIXME error
alpar@1381
   217
//     }
alpar@1381
   218
alpar@1381
   219
//     status = CPXchgcoef (env, lp, i, -2, value_rng);
alpar@1381
   220
  }
alpar@1381
   221
  
alpar@1381
   222
  void LpCplex::_setObjCoeff(int i, Value obj_coef)
alpar@1381
   223
  {
alpar@1381
   224
    CPXchgcoef (env, lp, -1, i, obj_coef);
alpar@1381
   225
  }
alpar@1381
   226
alpar@1381
   227
  void LpCplex::_clearObj()
alpar@1381
   228
  {
alpar@1381
   229
    for (int i=0;i< CPXgetnumcols (env, lp);++i){
alpar@1381
   230
      CPXchgcoef (env, lp, -1, i, 0);
alpar@1381
   231
    }
alpar@1381
   232
    
alpar@1381
   233
  }
alpar@1381
   234
alpar@1381
   235
  LpCplex::SolveExitStatus LpCplex::_solve()
alpar@1381
   236
  {
alpar@1381
   237
    
alpar@1381
   238
    status = CPXlpopt (env, lp);
alpar@1381
   239
    if (status == 0){
alpar@1381
   240
      return SOLVED;
alpar@1381
   241
    }
alpar@1381
   242
    else{
alpar@1381
   243
      return UNSOLVED;
alpar@1381
   244
    }
alpar@1381
   245
//     int i=  lpx_simplex(lp);
alpar@1381
   246
//     switch (i) {
alpar@1381
   247
//     case LPX_E_OK: 
alpar@1381
   248
//       return SOLVED;
alpar@1381
   249
//       break;
alpar@1381
   250
//     default:
alpar@1381
   251
//       return UNSOLVED;
alpar@1381
   252
//     }
alpar@1381
   253
  }
alpar@1381
   254
alpar@1381
   255
  LpCplex::SolutionStatus LpCplex::_getPrimalStatus()
alpar@1381
   256
  {
alpar@1381
   257
    //Unimplemented
alpar@1381
   258
    return OPTIMAL;
alpar@1381
   259
//     int stat=  lpx_get_status(lp);
alpar@1381
   260
//     switch (stat) {
alpar@1381
   261
//     case LPX_UNDEF://Undefined (no solve has been run yet)
alpar@1381
   262
//       return UNDEFINED;
alpar@1381
   263
//       break;
alpar@1381
   264
//     case LPX_NOFEAS://There is no feasible solution (primal, I guess)
alpar@1381
   265
//     case LPX_INFEAS://Infeasible 
alpar@1381
   266
//       return INFEASIBLE;
alpar@1381
   267
//       break;
alpar@1381
   268
//     case LPX_UNBND://Unbounded
alpar@1381
   269
//       return INFINITE;
alpar@1381
   270
//       break;
alpar@1381
   271
//     case LPX_FEAS://Feasible
alpar@1381
   272
//       return FEASIBLE;
alpar@1381
   273
//       break;
alpar@1381
   274
//     case LPX_OPT://Feasible
alpar@1381
   275
//       return OPTIMAL;
alpar@1381
   276
//       break;
alpar@1381
   277
//     default:
alpar@1381
   278
//       return UNDEFINED; //to avoid gcc warning
alpar@1381
   279
//       //FIXME error
alpar@1381
   280
//     }
alpar@1381
   281
  }
alpar@1381
   282
alpar@1381
   283
  LpCplex::Value LpCplex::_getPrimal(int i)
alpar@1381
   284
  {
alpar@1381
   285
    Value x;
alpar@1381
   286
    CPXgetx (env, lp, &x, i, i);
alpar@1381
   287
    return x;
alpar@1381
   288
  }
alpar@1381
   289
  
alpar@1381
   290
  LpCplex::Value LpCplex::_getPrimalValue()
alpar@1381
   291
  {
alpar@1381
   292
    //Unimplemented
alpar@1381
   293
    return 0;
alpar@1381
   294
  }
alpar@1381
   295
  
alpar@1381
   296
 
alpar@1381
   297
alpar@1381
   298
alpar@1381
   299
  void LpCplex::_setMax()
alpar@1381
   300
  {
alpar@1381
   301
    CPXchgobjsen (env, lp, CPX_MAX);
alpar@1381
   302
   }
alpar@1381
   303
  void LpCplex::_setMin()
alpar@1381
   304
  {
alpar@1381
   305
    CPXchgobjsen (env, lp, CPX_MIN);
alpar@1381
   306
   }
alpar@1381
   307
  
alpar@1381
   308
} //namespace lemon
alpar@1381
   309