lemon/lp_cplex.cc
author deba
Thu, 15 Feb 2007 13:06:23 +0000
changeset 2362 eb37b9774ef6
parent 2328 b4931ae52069
child 2363 2aabce558574
permissions -rw-r--r--
Small changes
alpar@1381
     1
/* -*- C++ -*-
alpar@1381
     2
 *
alpar@1956
     3
 * This file is a part of LEMON, a generic C++ optimization library
alpar@1956
     4
 *
alpar@1956
     5
 * Copyright (C) 2003-2006
alpar@1956
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@1381
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@1381
     8
 *
alpar@1381
     9
 * Permission to use, modify and distribute this software is granted
alpar@1381
    10
 * provided that this copyright notice appears in all copies. For
alpar@1381
    11
 * precise terms see the accompanying LICENSE file.
alpar@1381
    12
 *
alpar@1381
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@1381
    14
 * express or implied, and with no claim as to its suitability for any
alpar@1381
    15
 * purpose.
alpar@1381
    16
 *
alpar@1381
    17
 */
alpar@1956
    18
athos@1405
    19
#include <iostream>
athos@1405
    20
#include<lemon/lp_cplex.h>
alpar@1381
    21
alpar@1381
    22
///\file
alpar@1381
    23
///\brief Implementation of the LEMON-CPLEX lp solver interface.
alpar@1381
    24
namespace lemon {
alpar@1381
    25
  
alpar@1381
    26
  LpCplex::LpCplex() : LpSolverBase() {
athos@1436
    27
athos@1436
    28
    //    env = CPXopenCPLEXdevelop(&status);     
athos@1436
    29
    env = CPXopenCPLEX(&status);     
alpar@1381
    30
    lp = CPXcreateprob(env, &status, "LP problem");
alpar@1381
    31
  }
alpar@1381
    32
  
alpar@1381
    33
  LpCplex::~LpCplex() {
athos@1436
    34
    CPXfreeprob(env,&lp); 
athos@1436
    35
    CPXcloseCPLEX(&env); 
alpar@1381
    36
  }
alpar@1381
    37
  
athos@1405
    38
  LpSolverBase &LpCplex::_newLp() 
athos@1405
    39
  {
athos@1436
    40
    //The first approach opens a new environment
athos@1436
    41
    LpCplex* newlp=new LpCplex();
athos@1436
    42
    return *newlp;
athos@1405
    43
  }
athos@1436
    44
athos@1405
    45
  LpSolverBase &LpCplex::_copyLp() {
athos@2328
    46
    ///\bug FixID data is not copied!
athos@1436
    47
    //The first approach opens a new environment
athos@1436
    48
    LpCplex* newlp=new LpCplex();
athos@1436
    49
    //The routine CPXcloneprob can be used to create a new CPLEX problem 
athos@1436
    50
    //object and copy all the problem data from an existing problem 
athos@1436
    51
    //object to it. Solution and starting information is not copied.
athos@1508
    52
    newlp->lp = CPXcloneprob(env, lp, &status);
athos@1436
    53
    return *newlp;
athos@1405
    54
  }
alpar@1381
    55
alpar@1381
    56
  int LpCplex::_addCol()
alpar@1381
    57
  {
athos@1508
    58
    int i = CPXgetnumcols(env, lp);
alpar@1381
    59
    Value lb[1],ub[1];
alpar@1381
    60
    lb[0]=-INF;//-CPX_INFBOUND;
alpar@1381
    61
    ub[0]=INF;//CPX_INFBOUND;
athos@1508
    62
    status = CPXnewcols(env, lp, 1, NULL, lb, ub, NULL, NULL);
alpar@1381
    63
    return i;
alpar@1381
    64
  }
athos@1436
    65
alpar@1381
    66
  
alpar@1381
    67
  int LpCplex::_addRow() 
alpar@1381
    68
  {
alpar@1381
    69
    //We want a row that is not constrained
alpar@1381
    70
    char sense[1];
alpar@1381
    71
    sense[0]='L';//<= constraint
alpar@1381
    72
    Value rhs[1];
alpar@1381
    73
    rhs[0]=INF;
athos@1508
    74
    int i = CPXgetnumrows(env, lp);
athos@1508
    75
    status = CPXnewrows(env, lp, 1, rhs, sense, NULL, NULL);
alpar@1381
    76
    return i;
alpar@1381
    77
  }
athos@1432
    78
athos@1432
    79
athos@1432
    80
  void LpCplex::_eraseCol(int i) {
athos@1508
    81
    CPXdelcols(env, lp, i, i);
athos@1432
    82
  }
athos@1432
    83
  
athos@1432
    84
  void LpCplex::_eraseRow(int i) {
athos@1508
    85
    CPXdelrows(env, lp, i, i);
athos@1432
    86
  }
alpar@1895
    87
  
alpar@1895
    88
  void LpCplex::_getColName(int col, std::string &name)
alpar@1895
    89
  {
klao@1950
    90
    ///\bug Untested
klao@1950
    91
    int storespace;
klao@1950
    92
    CPXgetcolname(env, lp, 0, 0, 0, &storespace, col, col);
klao@1950
    93
klao@1950
    94
    storespace *= -1;
klao@1950
    95
    char buf[storespace];
klao@1950
    96
    char *names[1];
klao@1950
    97
    int dontcare;
klao@1950
    98
    ///\bug return code unchecked for error
klao@1950
    99
    CPXgetcolname(env, lp, names, buf, storespace, &dontcare, col, col);
klao@1950
   100
    name = names[0];
alpar@1895
   101
  }
alpar@1895
   102
  
alpar@1895
   103
  void LpCplex::_setColName(int col, const std::string &name)
alpar@1895
   104
  {
alpar@1895
   105
    ///\bug Untested
klao@1950
   106
    char *names[1];
klao@1950
   107
    names[0] = const_cast<char*>(name.c_str());
klao@1950
   108
    ///\bug return code unchecked for error
klao@1950
   109
    CPXchgcolname(env, lp, 1, &col, names);    
alpar@1895
   110
  }
alpar@1381
   111
  
alpar@1381
   112
  ///\warning Data at index 0 is ignored in the arrays.
deba@2312
   113
  void LpCplex::_setRowCoeffs(int i, LpRowIterator b, LpRowIterator e)
alpar@1381
   114
  {
deba@2312
   115
    std::vector<int> indices;
deba@2312
   116
    std::vector<int> rowlist;
deba@2312
   117
    std::vector<Value> values;
deba@2312
   118
deba@2312
   119
    for(LpRowIterator it=b; it!=e; ++it) {
deba@2312
   120
      indices.push_back(it->first);
deba@2312
   121
      values.push_back(it->second);
deba@2312
   122
      rowlist.push_back(i);
alpar@1381
   123
    }
deba@2312
   124
deba@2312
   125
    status = CPXchgcoeflist(env, lp, values.size(), 
deba@2312
   126
			    &rowlist[0], &indices[0], &values[0]); 
alpar@1381
   127
  }
alpar@1381
   128
  
deba@2312
   129
  void LpCplex::_setColCoeffs(int i, LpColIterator b, LpColIterator e)
alpar@1381
   130
  {
deba@2312
   131
    std::vector<int> indices;
deba@2312
   132
    std::vector<int> collist;
deba@2312
   133
    std::vector<Value> values;
deba@2312
   134
deba@2312
   135
    for(LpColIterator it=b; it!=e; ++it) {
deba@2312
   136
      indices.push_back(it->first);
deba@2312
   137
      values.push_back(it->second);
deba@2312
   138
      collist.push_back(i);
alpar@1381
   139
    }
deba@2312
   140
deba@2312
   141
    status = CPXchgcoeflist(env, lp, values.size(), 
deba@2312
   142
			    &indices[0], &collist[0], &values[0]); 
alpar@1381
   143
  }
alpar@1381
   144
  
athos@1431
   145
  void LpCplex::_setCoeff(int row, int col, Value value) 
athos@1431
   146
  {
athos@1508
   147
    CPXchgcoef(env, lp, row, col, value);
athos@1431
   148
  }
athos@1431
   149
athos@2361
   150
  LpCplex::Value LpCplex::_getCoeff(int row, int col) 
athos@2361
   151
  {
athos@2361
   152
    LpCplex::Value value;
athos@2361
   153
    CPXgetcoef(env, lp, row, col, &value);
athos@2361
   154
    return value;
athos@2361
   155
  }
athos@2361
   156
alpar@1381
   157
  void LpCplex::_setColLowerBound(int i, Value value)
alpar@1381
   158
  {
alpar@1381
   159
    int indices[1];
alpar@1381
   160
    indices[0]=i;
alpar@1381
   161
    char lu[1];
alpar@1381
   162
    lu[0]='L';
alpar@1381
   163
    Value bd[1];
alpar@1381
   164
    bd[0]=value;
athos@1508
   165
    status = CPXchgbds(env, lp, 1, indices, lu, bd);
alpar@1381
   166
 
alpar@1381
   167
  }
athos@2361
   168
athos@2361
   169
  LpCplex::Value LpCplex::_getColLowerBound(int i)
athos@2361
   170
  {
athos@2361
   171
    LpCplex::Value x;
athos@2361
   172
    CPXgetlb (env, lp, &x, i, i);
athos@2361
   173
    return x;
athos@2361
   174
  }
alpar@1381
   175
  
alpar@1381
   176
  void LpCplex::_setColUpperBound(int i, Value value)
alpar@1381
   177
  {
alpar@1381
   178
    int indices[1];
alpar@1381
   179
    indices[0]=i;
alpar@1381
   180
    char lu[1];
alpar@1381
   181
    lu[0]='U';
alpar@1381
   182
    Value bd[1];
alpar@1381
   183
    bd[0]=value;
athos@1508
   184
    status = CPXchgbds(env, lp, 1, indices, lu, bd);
alpar@1381
   185
  }
alpar@1381
   186
athos@2361
   187
  LpCplex::Value LpCplex::_getColUpperBound(int i)
athos@2361
   188
  {
athos@2361
   189
    LpCplex::Value x;
athos@2361
   190
    CPXgetub (env, lp, &x, i, i);
athos@2361
   191
    return x;
athos@2361
   192
  }
athos@2361
   193
alpar@1381
   194
  //This will be easier to implement
alpar@1381
   195
  void LpCplex::_setRowBounds(int i, Value lb, Value ub)
alpar@1381
   196
  {
alpar@1381
   197
    //Bad parameter
alpar@1381
   198
    if (lb==INF || ub==-INF) {
alpar@1381
   199
      //FIXME error
alpar@1381
   200
    }
athos@1405
   201
    
alpar@1381
   202
    int cnt=1;
alpar@1381
   203
    int indices[1];
alpar@1381
   204
    indices[0]=i;
alpar@1381
   205
    char sense[1];
alpar@1381
   206
alpar@1381
   207
    if (lb==-INF){
alpar@1381
   208
      sense[0]='L';
athos@1508
   209
      CPXchgsense(env, lp, cnt, indices, sense);
athos@1508
   210
      CPXchgcoef(env, lp, i, -1, ub);
athos@1405
   211
      
alpar@1381
   212
    }
alpar@1381
   213
    else{
alpar@1381
   214
      if (ub==INF){
alpar@1381
   215
	sense[0]='G';
athos@1508
   216
	CPXchgsense(env, lp, cnt, indices, sense);
athos@1508
   217
	CPXchgcoef(env, lp, i, -1, lb);
alpar@1381
   218
      }
alpar@1381
   219
      else{
alpar@1381
   220
	if (lb == ub){
alpar@1381
   221
	  sense[0]='E';
athos@1508
   222
	  CPXchgsense(env, lp, cnt, indices, sense);
athos@1508
   223
	  CPXchgcoef(env, lp, i, -1, lb);
alpar@1381
   224
	}
alpar@1381
   225
	else{
alpar@1381
   226
	  sense[0]='R';
athos@1508
   227
	  CPXchgsense(env, lp, cnt, indices, sense);
athos@1508
   228
	  CPXchgcoef(env, lp, i, -1, lb);
athos@1508
   229
	  CPXchgcoef(env, lp, i, -2, ub-lb);	  
alpar@1381
   230
	}
alpar@1381
   231
      }
alpar@1381
   232
    }
alpar@1381
   233
  }
alpar@1381
   234
athos@1405
   235
//   void LpCplex::_setRowLowerBound(int i, Value value)
athos@1405
   236
//   {
athos@1405
   237
//     //Not implemented, obsolete
athos@1405
   238
//   }
alpar@1381
   239
  
athos@1405
   240
//   void LpCplex::_setRowUpperBound(int i, Value value)
athos@1405
   241
//   {
athos@1405
   242
//     //Not implemented, obsolete
athos@1405
   243
// //     //TODO Ezt kell meg megirni
athos@1405
   244
// //     //type of the problem
athos@1405
   245
// //     char sense[1];
athos@1508
   246
// //     status = CPXgetsense(env, lp, sense, i, i);
athos@1405
   247
// //     Value rhs[1];
athos@1508
   248
// //     status = CPXgetrhs(env, lp, rhs, i, i);
alpar@1381
   249
athos@1405
   250
// //     switch (sense[0]) {
athos@1405
   251
// //     case 'L'://<= constraint
athos@1405
   252
// //       break;
athos@1405
   253
// //     case 'E'://= constraint
athos@1405
   254
// //       break;
athos@1405
   255
// //     case 'G'://>= constraint
athos@1405
   256
// //       break;
athos@1405
   257
// //     case 'R'://ranged constraint
athos@1405
   258
// //       break;
athos@1405
   259
// //     default: ;
athos@1405
   260
// //       //FIXME error
athos@1405
   261
// //     }
alpar@1381
   262
athos@1508
   263
// //     status = CPXchgcoef(env, lp, i, -2, value_rng);
athos@1405
   264
//   }
alpar@1381
   265
  
athos@2361
   266
  void LpCplex::_getRowBounds(int i, Value &lb, Value &ub)
athos@2361
   267
  {
athos@2361
   268
    char sense;
athos@2361
   269
    CPXgetsense(env, lp, &sense,i,i);
athos@2361
   270
    lb=-INF;
athos@2361
   271
    ub=INF;
athos@2361
   272
    switch (sense)
athos@2361
   273
      {
athos@2361
   274
      case 'L':
athos@2361
   275
	CPXgetcoef(env, lp, i, -1, &ub);
athos@2361
   276
	break;
athos@2361
   277
      case 'G':
athos@2361
   278
	CPXgetcoef(env, lp, i, -1, &lb);
athos@2361
   279
	break;
athos@2361
   280
      case 'E':
athos@2361
   281
	CPXgetcoef(env, lp, i, -1, &lb);
athos@2361
   282
	ub=lb;
athos@2361
   283
	break;
athos@2361
   284
      case 'R':
athos@2361
   285
	CPXgetcoef(env, lp, i, -1, &lb);
athos@2361
   286
	Value x;
athos@2361
   287
	CPXgetcoef(env, lp, i, -2, &x);
athos@2361
   288
	ub=lb+x;
athos@2361
   289
	break;
athos@2361
   290
      }
athos@2361
   291
  }
athos@2361
   292
alpar@1381
   293
  void LpCplex::_setObjCoeff(int i, Value obj_coef)
alpar@1381
   294
  {
athos@1508
   295
    CPXchgcoef(env, lp, -1, i, obj_coef);
alpar@1381
   296
  }
alpar@1381
   297
athos@2361
   298
  LpCplex::Value LpCplex::_getObjCoeff(int i)
athos@2361
   299
  {
athos@2361
   300
    Value x;
athos@2361
   301
    CPXgetcoef(env, lp, -1, i, &x);
athos@2361
   302
    return x;
athos@2361
   303
  }
athos@2361
   304
alpar@1381
   305
  void LpCplex::_clearObj()
alpar@1381
   306
  {
athos@1508
   307
    for (int i=0;i< CPXgetnumcols(env, lp);++i){
athos@1508
   308
      CPXchgcoef(env, lp, -1, i, 0);
alpar@1381
   309
    }
alpar@1381
   310
    
alpar@1381
   311
  }
athos@1458
   312
  // The routine returns zero unless an error occurred during the
athos@1458
   313
  // optimization. Examples of errors include exhausting available
athos@1458
   314
  // memory (CPXERR_NO_MEMORY) or encountering invalid data in the
athos@1458
   315
  // CPLEX problem object (CPXERR_NO_PROBLEM). Exceeding a
athos@1458
   316
  // user-specified CPLEX limit, or proving the model infeasible or
athos@1458
   317
  // unbounded, are not considered errors. Note that a zero return
athos@1458
   318
  // value does not necessarily mean that a solution exists. Use query
athos@1458
   319
  // routines CPXsolninfo, CPXgetstat, and CPXsolution to obtain
athos@1458
   320
  // further information about the status of the optimization.
alpar@1381
   321
  LpCplex::SolveExitStatus LpCplex::_solve()
alpar@1381
   322
  {
athos@1458
   323
    //CPX_PARAM_LPMETHOD 
athos@1508
   324
    status = CPXlpopt(env, lp);
athos@1542
   325
    //status = CPXprimopt(env, lp);
athos@2218
   326
#if CPX_VERSION >= 800
ladanyi@2168
   327
    if (status)
ladanyi@2168
   328
    {
ladanyi@2168
   329
      return UNSOLVED;
ladanyi@2168
   330
    }
ladanyi@2168
   331
    else
ladanyi@2168
   332
    {
ladanyi@2168
   333
      switch (CPXgetstat(env, lp))
ladanyi@2168
   334
      {
ladanyi@2168
   335
        case CPX_STAT_OPTIMAL:
ladanyi@2168
   336
        case CPX_STAT_INFEASIBLE:
ladanyi@2168
   337
        case CPX_STAT_UNBOUNDED:
ladanyi@2168
   338
          return SOLVED;
ladanyi@2168
   339
        default:
ladanyi@2168
   340
          return UNSOLVED;
ladanyi@2168
   341
      }
ladanyi@2168
   342
    }
ladanyi@2168
   343
#else
alpar@1381
   344
    if (status == 0){
athos@1458
   345
      //We want to exclude some cases
athos@1508
   346
      switch (CPXgetstat(env, lp)){
athos@1458
   347
      case CPX_OBJ_LIM:
athos@1458
   348
      case CPX_IT_LIM_FEAS:
athos@1458
   349
      case CPX_IT_LIM_INFEAS:               
athos@1458
   350
      case CPX_TIME_LIM_FEAS:
athos@1458
   351
      case CPX_TIME_LIM_INFEAS:
athos@1458
   352
	return UNSOLVED;
athos@1458
   353
      default:
athos@1458
   354
	return SOLVED; 
athos@1458
   355
      }
alpar@1381
   356
    }
alpar@1381
   357
    else{
alpar@1381
   358
      return UNSOLVED;
alpar@1381
   359
    }
ladanyi@2168
   360
#endif
alpar@1381
   361
  }
alpar@1381
   362
athos@1460
   363
  LpCplex::Value LpCplex::_getPrimal(int i)
athos@1460
   364
  {
athos@1460
   365
    Value x;
athos@1508
   366
    CPXgetx(env, lp, &x, i, i);
athos@1460
   367
    return x;
athos@1460
   368
  }
marci@1787
   369
marci@1787
   370
  LpCplex::Value LpCplex::_getDual(int i)
marci@1787
   371
  {
marci@1787
   372
    Value y;
klao@1798
   373
    CPXgetpi(env, lp, &y, i, i);
marci@1787
   374
    return y;
marci@1787
   375
  }
athos@1460
   376
  
athos@1460
   377
  LpCplex::Value LpCplex::_getPrimalValue()
athos@1460
   378
  {
athos@1460
   379
    Value objval;
athos@1460
   380
    //method = CPXgetmethod (env, lp);
athos@1508
   381
    //printf("CPXgetprobtype %d \n",CPXgetprobtype(env,lp));
athos@1508
   382
    status = CPXgetobjval(env, lp, &objval);
athos@1508
   383
    //printf("Objective value: %g \n",objval);
athos@1460
   384
    return objval;
athos@1460
   385
  }
marci@1840
   386
  bool LpCplex::_isBasicCol(int i) {
marci@1841
   387
    int cstat[CPXgetnumcols(env, lp)];
marci@1841
   388
    CPXgetbase(env, lp, cstat, NULL);
marci@1841
   389
    return (cstat[i]==CPX_BASIC);
marci@1840
   390
  }  
athos@1407
   391
athos@1458
   392
//7.5-os cplex statusai (Vigyazat: a 9.0-asei masok!)
athos@1458
   393
// This table lists the statuses, returned by the CPXgetstat() routine, for solutions to LP problems or mixed integer problems. If no solution exists, the return value is zero.
athos@1458
   394
athos@1458
   395
// For Simplex, Barrier  
athos@1458
   396
// 1  	CPX_OPTIMAL  
athos@1458
   397
// 	 Optimal solution found  
athos@1458
   398
// 2  	CPX_INFEASIBLE  
athos@1458
   399
// 	 Problem infeasible  
athos@1458
   400
// 3    CPX_UNBOUNDED  
athos@1458
   401
// 	 Problem unbounded  
athos@1458
   402
// 4  	CPX_OBJ_LIM  
athos@1458
   403
// 	 Objective limit exceeded in Phase II  
athos@1458
   404
// 5  	CPX_IT_LIM_FEAS  
athos@1458
   405
// 	 Iteration limit exceeded in Phase II  
athos@1458
   406
// 6  	CPX_IT_LIM_INFEAS  
athos@1458
   407
// 	 Iteration limit exceeded in Phase I  
athos@1458
   408
// 7  	CPX_TIME_LIM_FEAS  
athos@1458
   409
// 	 Time limit exceeded in Phase II  
athos@1458
   410
// 8  	CPX_TIME_LIM_INFEAS  
athos@1458
   411
// 	 Time limit exceeded in Phase I  
athos@1458
   412
// 9  	CPX_NUM_BEST_FEAS  
athos@1458
   413
// 	 Problem non-optimal, singularities in Phase II  
athos@1458
   414
// 10 	CPX_NUM_BEST_INFEAS  
athos@1458
   415
// 	 Problem non-optimal, singularities in Phase I  
athos@1458
   416
// 11 	CPX_OPTIMAL_INFEAS  
athos@1458
   417
// 	 Optimal solution found, unscaled infeasibilities  
athos@1458
   418
// 12 	CPX_ABORT_FEAS  
athos@1458
   419
// 	 Aborted in Phase II  
athos@1458
   420
// 13 	CPX_ABORT_INFEAS  
athos@1458
   421
// 	 Aborted in Phase I  
athos@1458
   422
// 14  	CPX_ABORT_DUAL_INFEAS  
athos@1458
   423
// 	 Aborted in barrier, dual infeasible  
athos@1458
   424
// 15  	CPX_ABORT_PRIM_INFEAS  
athos@1458
   425
// 	 Aborted in barrier, primal infeasible  
athos@1458
   426
// 16  	CPX_ABORT_PRIM_DUAL_INFEAS  
athos@1458
   427
// 	 Aborted in barrier, primal and dual infeasible  
athos@1458
   428
// 17  	CPX_ABORT_PRIM_DUAL_FEAS  
athos@1458
   429
// 	 Aborted in barrier, primal and dual feasible  
athos@1458
   430
// 18  	CPX_ABORT_CROSSOVER  
athos@1458
   431
// 	 Aborted in crossover  
athos@1458
   432
// 19  	CPX_INForUNBD  
athos@1458
   433
// 	 Infeasible or unbounded  
athos@1458
   434
// 20   CPX_PIVOT
athos@1458
   435
//       User pivot used
athos@1458
   436
//
athos@1407
   437
//     Ezeket hova tegyem:
athos@1407
   438
// ??case CPX_ABORT_DUAL_INFEAS           
athos@1407
   439
// ??case CPX_ABORT_CROSSOVER             
athos@1407
   440
// ??case CPX_INForUNBD                   
athos@1542
   441
// ??case CPX_PIVOT              
athos@1542
   442
         
athos@1542
   443
//Some more interesting stuff:
athos@1542
   444
athos@1542
   445
// CPX_PARAM_LPMETHOD  1062  int  LPMETHOD
athos@1542
   446
// 0 Automatic 
athos@1542
   447
// 1 Primal Simplex 
athos@1542
   448
// 2 Dual Simplex 
athos@1542
   449
// 3 Network Simplex 
athos@1542
   450
// 4 Standard Barrier 
athos@1542
   451
// Default: 0 
athos@1542
   452
// Description: Method for linear optimization. 
athos@1542
   453
// Determines which algorithm is used when CPXlpopt() (or "optimize" in the Interactive Optimizer) is called. Currently the behavior of the "Automatic" setting is that CPLEX simply invokes the dual simplex method, but this capability may be expanded in the future so that CPLEX chooses the method based on problem characteristics 
athos@1542
   454
  //Hulye cplex
athos@1542
   455
  void statusSwitch(CPXENVptr env,int& stat){
ladanyi@2168
   456
#if CPX_VERSION < 900
athos@1542
   457
    int lpmethod;
athos@1542
   458
    CPXgetintparam (env,CPX_PARAM_LPMETHOD,&lpmethod);
athos@1542
   459
    if (lpmethod==2){
athos@1542
   460
      if (stat==CPX_UNBOUNDED){
athos@1542
   461
	stat=CPX_INFEASIBLE;
athos@1542
   462
      }
athos@1542
   463
      else{
athos@1542
   464
	if (stat==CPX_INFEASIBLE)
athos@1542
   465
	  stat=CPX_UNBOUNDED;
athos@1542
   466
      }
athos@1542
   467
    }
ladanyi@2168
   468
#endif
athos@1542
   469
  }
athos@1407
   470
athos@1458
   471
  LpCplex::SolutionStatus LpCplex::_getPrimalStatus()
athos@1458
   472
  {
athos@2218
   473
    //Unboundedness not treated well: the following is from cplex 9.0 doc
athos@2218
   474
    // About Unboundedness
athos@2218
   475
athos@2218
   476
    // The treatment of models that are unbounded involves a few
athos@2218
   477
    // subtleties. Specifically, a declaration of unboundedness means that
athos@2218
   478
    // ILOG CPLEX has determined that the model has an unbounded
athos@2218
   479
    // ray. Given any feasible solution x with objective z, a multiple of
athos@2218
   480
    // the unbounded ray can be added to x to give a feasible solution
athos@2218
   481
    // with objective z-1 (or z+1 for maximization models). Thus, if a
athos@2218
   482
    // feasible solution exists, then the optimal objective is
athos@2218
   483
    // unbounded. Note that ILOG CPLEX has not necessarily concluded that
athos@2218
   484
    // a feasible solution exists. Users can call the routine CPXsolninfo
athos@2218
   485
    // to determine whether ILOG CPLEX has also concluded that the model
athos@2218
   486
    // has a feasible solution.
athos@2218
   487
athos@1508
   488
    int stat = CPXgetstat(env, lp);
athos@2218
   489
#if CPX_VERSION >= 800
ladanyi@2168
   490
    switch (stat)
ladanyi@2168
   491
    {
ladanyi@2168
   492
      case CPX_STAT_OPTIMAL:
ladanyi@2168
   493
        return OPTIMAL;
ladanyi@2168
   494
      case CPX_STAT_UNBOUNDED:
ladanyi@2168
   495
        return INFINITE;
ladanyi@2168
   496
      case CPX_STAT_INFEASIBLE:
ladanyi@2168
   497
        return INFEASIBLE;
ladanyi@2168
   498
      default:
ladanyi@2168
   499
        return UNDEFINED;
ladanyi@2168
   500
    }
ladanyi@2168
   501
#else
athos@1542
   502
    statusSwitch(env,stat);
athos@1542
   503
    //CPXgetstat(env, lp);
athos@1508
   504
    //printf("A primal status: %d, CPX_OPTIMAL=%d \n",stat,CPX_OPTIMAL);
athos@1407
   505
    switch (stat) {
athos@1407
   506
    case 0:
athos@1407
   507
      return UNDEFINED; //Undefined
athos@1407
   508
    case CPX_OPTIMAL://Optimal
athos@1407
   509
      return OPTIMAL;
athos@1407
   510
    case CPX_UNBOUNDED://Unbounded
athos@1542
   511
      return INFEASIBLE;//In case of dual simplex
athos@1542
   512
      //return INFINITE;
athos@1407
   513
    case CPX_INFEASIBLE://Infeasible 
athos@1458
   514
 //    case CPX_IT_LIM_INFEAS:
athos@1458
   515
//     case CPX_TIME_LIM_INFEAS:
athos@1458
   516
//     case CPX_NUM_BEST_INFEAS:             
athos@1458
   517
//     case CPX_OPTIMAL_INFEAS:              
athos@1458
   518
//     case CPX_ABORT_INFEAS:                
athos@1458
   519
//     case CPX_ABORT_PRIM_INFEAS:           
athos@1458
   520
//     case CPX_ABORT_PRIM_DUAL_INFEAS:      
athos@1542
   521
      return INFINITE;//In case of dual simplex
athos@1542
   522
      //return INFEASIBLE;
athos@1458
   523
//     case CPX_OBJ_LIM:                    
athos@1458
   524
//     case CPX_IT_LIM_FEAS:             
athos@1458
   525
//     case CPX_TIME_LIM_FEAS:                
athos@1458
   526
//     case CPX_NUM_BEST_FEAS:                
athos@1458
   527
//     case CPX_ABORT_FEAS:                  
athos@1458
   528
//     case CPX_ABORT_PRIM_DUAL_FEAS:        
athos@1458
   529
//       return FEASIBLE;
athos@1407
   530
    default:
athos@1407
   531
      return UNDEFINED; //Everything else comes here
athos@1407
   532
      //FIXME error
athos@1407
   533
    }
ladanyi@2168
   534
#endif
athos@1458
   535
  }
athos@1407
   536
athos@1458
   537
//9.0-as cplex verzio statusai
athos@1405
   538
// CPX_STAT_ABORT_DUAL_OBJ_LIM
athos@1405
   539
// CPX_STAT_ABORT_IT_LIM
athos@1405
   540
// CPX_STAT_ABORT_OBJ_LIM
athos@1405
   541
// CPX_STAT_ABORT_PRIM_OBJ_LIM
athos@1405
   542
// CPX_STAT_ABORT_TIME_LIM
athos@1405
   543
// CPX_STAT_ABORT_USER
athos@1405
   544
// CPX_STAT_FEASIBLE_RELAXED
athos@1405
   545
// CPX_STAT_INFEASIBLE
athos@1405
   546
// CPX_STAT_INForUNBD
athos@1405
   547
// CPX_STAT_NUM_BEST
athos@1405
   548
// CPX_STAT_OPTIMAL
athos@1405
   549
// CPX_STAT_OPTIMAL_FACE_UNBOUNDED
athos@1405
   550
// CPX_STAT_OPTIMAL_INFEAS
athos@1405
   551
// CPX_STAT_OPTIMAL_RELAXED
athos@1405
   552
// CPX_STAT_UNBOUNDED
athos@1405
   553
athos@1458
   554
  LpCplex::SolutionStatus LpCplex::_getDualStatus()
athos@1458
   555
  {
athos@1508
   556
    int stat = CPXgetstat(env, lp);
athos@2218
   557
#if CPX_VERSION >= 800
ladanyi@2168
   558
    switch (stat)
ladanyi@2168
   559
    {
ladanyi@2168
   560
      case CPX_STAT_OPTIMAL:
ladanyi@2168
   561
        return OPTIMAL;
ladanyi@2168
   562
      case CPX_STAT_UNBOUNDED:
ladanyi@2168
   563
        return INFEASIBLE;
ladanyi@2168
   564
      default:
ladanyi@2168
   565
        return UNDEFINED;
ladanyi@2168
   566
    }
ladanyi@2168
   567
#else
athos@1542
   568
    statusSwitch(env,stat);
athos@1458
   569
    switch (stat) {
athos@1458
   570
    case 0:
athos@1458
   571
      return UNDEFINED; //Undefined
athos@1458
   572
    case CPX_OPTIMAL://Optimal
athos@1458
   573
      return OPTIMAL;
athos@1458
   574
    case CPX_UNBOUNDED:
athos@1458
   575
     return INFEASIBLE;
athos@1458
   576
    default:
athos@1458
   577
      return UNDEFINED; //Everything else comes here
athos@1458
   578
      //FIXME error
athos@1458
   579
    }
ladanyi@2168
   580
#endif
athos@1473
   581
  }
alpar@1381
   582
athos@1460
   583
  LpCplex::ProblemTypes LpCplex::_getProblemType()
alpar@1381
   584
  {
athos@1508
   585
    int stat = CPXgetstat(env, lp);
athos@2218
   586
#if CPX_VERSION >= 800
ladanyi@2168
   587
    switch (stat)
ladanyi@2168
   588
    {
ladanyi@2168
   589
      case CPX_STAT_OPTIMAL:
ladanyi@2168
   590
	return PRIMAL_DUAL_FEASIBLE;
ladanyi@2168
   591
      case CPX_STAT_UNBOUNDED:
ladanyi@2168
   592
 	return PRIMAL_FEASIBLE_DUAL_INFEASIBLE;
ladanyi@2168
   593
      default:
ladanyi@2168
   594
        return UNKNOWN;
ladanyi@2168
   595
    }
ladanyi@2168
   596
#else
athos@1460
   597
    switch (stat) {
athos@1460
   598
    case CPX_OPTIMAL://Optimal
athos@1460
   599
	return PRIMAL_DUAL_FEASIBLE;
athos@1460
   600
    case CPX_UNBOUNDED:
athos@1460
   601
 	return PRIMAL_FEASIBLE_DUAL_INFEASIBLE;
athos@1460
   602
// 	return PRIMAL_INFEASIBLE_DUAL_FEASIBLE;
athos@1460
   603
// 	return PRIMAL_DUAL_INFEASIBLE;
athos@1460
   604
athos@1460
   605
//Seems to be that this is all we can say for sure
athos@1460
   606
    default:
athos@1460
   607
	//In all other cases
athos@1460
   608
	return UNKNOWN;
athos@1460
   609
      //FIXME error
athos@1460
   610
    }
ladanyi@2168
   611
#endif
athos@1473
   612
  }
alpar@1381
   613
alpar@1381
   614
  void LpCplex::_setMax()
alpar@1381
   615
  {
athos@1508
   616
    CPXchgobjsen(env, lp, CPX_MAX);
alpar@1381
   617
   }
alpar@1381
   618
  void LpCplex::_setMin()
alpar@1381
   619
  {
athos@1508
   620
    CPXchgobjsen(env, lp, CPX_MIN);
alpar@1381
   621
   }
athos@2361
   622
athos@2361
   623
  bool LpCplex::_isMax()
athos@2361
   624
  {
athos@2361
   625
    if (CPXgetobjsen(env, lp)==CPX_MAX)
athos@2361
   626
      return true;
athos@2361
   627
    else
athos@2361
   628
      return false;
athos@2361
   629
  }
alpar@1381
   630
  
alpar@1381
   631
} //namespace lemon
alpar@1381
   632