lemon/lp_cplex.cc
author deba
Thu, 15 Feb 2007 14:22:08 +0000
changeset 2363 2aabce558574
parent 2361 f2ef1aa8189a
child 2364 3a5e67bd42d2
permissions -rw-r--r--
Changes on the LP interface

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