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