lemon/lp_cplex.cc
author deba
Mon, 18 Dec 2006 10:12:07 +0000
changeset 2330 9dccb1abc721
parent 2312 07e46cbb7d85
child 2361 f2ef1aa8189a
permissions -rw-r--r--
Better handling of inexact computation.
We do not use tolerance for excess, just for edges
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
alpar@1381
   150
  void LpCplex::_setColLowerBound(int i, Value value)
alpar@1381
   151
  {
alpar@1381
   152
    int indices[1];
alpar@1381
   153
    indices[0]=i;
alpar@1381
   154
    char lu[1];
alpar@1381
   155
    lu[0]='L';
alpar@1381
   156
    Value bd[1];
alpar@1381
   157
    bd[0]=value;
athos@1508
   158
    status = CPXchgbds(env, lp, 1, indices, lu, bd);
alpar@1381
   159
 
alpar@1381
   160
  }
alpar@1381
   161
  
alpar@1381
   162
  void LpCplex::_setColUpperBound(int i, Value value)
alpar@1381
   163
  {
alpar@1381
   164
    int indices[1];
alpar@1381
   165
    indices[0]=i;
alpar@1381
   166
    char lu[1];
alpar@1381
   167
    lu[0]='U';
alpar@1381
   168
    Value bd[1];
alpar@1381
   169
    bd[0]=value;
athos@1508
   170
    status = CPXchgbds(env, lp, 1, indices, lu, bd);
alpar@1381
   171
  }
alpar@1381
   172
alpar@1381
   173
  //This will be easier to implement
alpar@1381
   174
  void LpCplex::_setRowBounds(int i, Value lb, Value ub)
alpar@1381
   175
  {
alpar@1381
   176
    //Bad parameter
alpar@1381
   177
    if (lb==INF || ub==-INF) {
alpar@1381
   178
      //FIXME error
alpar@1381
   179
    }
athos@1405
   180
    
alpar@1381
   181
    int cnt=1;
alpar@1381
   182
    int indices[1];
alpar@1381
   183
    indices[0]=i;
alpar@1381
   184
    char sense[1];
alpar@1381
   185
alpar@1381
   186
    if (lb==-INF){
alpar@1381
   187
      sense[0]='L';
athos@1508
   188
      CPXchgsense(env, lp, cnt, indices, sense);
athos@1508
   189
      CPXchgcoef(env, lp, i, -1, ub);
athos@1405
   190
      
alpar@1381
   191
    }
alpar@1381
   192
    else{
alpar@1381
   193
      if (ub==INF){
alpar@1381
   194
	sense[0]='G';
athos@1508
   195
	CPXchgsense(env, lp, cnt, indices, sense);
athos@1508
   196
	CPXchgcoef(env, lp, i, -1, lb);
alpar@1381
   197
      }
alpar@1381
   198
      else{
alpar@1381
   199
	if (lb == ub){
alpar@1381
   200
	  sense[0]='E';
athos@1508
   201
	  CPXchgsense(env, lp, cnt, indices, sense);
athos@1508
   202
	  CPXchgcoef(env, lp, i, -1, lb);
alpar@1381
   203
	}
alpar@1381
   204
	else{
alpar@1381
   205
	  sense[0]='R';
athos@1508
   206
	  CPXchgsense(env, lp, cnt, indices, sense);
athos@1508
   207
	  CPXchgcoef(env, lp, i, -1, lb);
athos@1508
   208
	  CPXchgcoef(env, lp, i, -2, ub-lb);	  
alpar@1381
   209
	}
alpar@1381
   210
      }
alpar@1381
   211
    }
alpar@1381
   212
  }
alpar@1381
   213
athos@1405
   214
//   void LpCplex::_setRowLowerBound(int i, Value value)
athos@1405
   215
//   {
athos@1405
   216
//     //Not implemented, obsolete
athos@1405
   217
//   }
alpar@1381
   218
  
athos@1405
   219
//   void LpCplex::_setRowUpperBound(int i, Value value)
athos@1405
   220
//   {
athos@1405
   221
//     //Not implemented, obsolete
athos@1405
   222
// //     //TODO Ezt kell meg megirni
athos@1405
   223
// //     //type of the problem
athos@1405
   224
// //     char sense[1];
athos@1508
   225
// //     status = CPXgetsense(env, lp, sense, i, i);
athos@1405
   226
// //     Value rhs[1];
athos@1508
   227
// //     status = CPXgetrhs(env, lp, rhs, i, i);
alpar@1381
   228
athos@1405
   229
// //     switch (sense[0]) {
athos@1405
   230
// //     case 'L'://<= constraint
athos@1405
   231
// //       break;
athos@1405
   232
// //     case 'E'://= constraint
athos@1405
   233
// //       break;
athos@1405
   234
// //     case 'G'://>= constraint
athos@1405
   235
// //       break;
athos@1405
   236
// //     case 'R'://ranged constraint
athos@1405
   237
// //       break;
athos@1405
   238
// //     default: ;
athos@1405
   239
// //       //FIXME error
athos@1405
   240
// //     }
alpar@1381
   241
athos@1508
   242
// //     status = CPXchgcoef(env, lp, i, -2, value_rng);
athos@1405
   243
//   }
alpar@1381
   244
  
alpar@1381
   245
  void LpCplex::_setObjCoeff(int i, Value obj_coef)
alpar@1381
   246
  {
athos@1508
   247
    CPXchgcoef(env, lp, -1, i, obj_coef);
alpar@1381
   248
  }
alpar@1381
   249
alpar@1381
   250
  void LpCplex::_clearObj()
alpar@1381
   251
  {
athos@1508
   252
    for (int i=0;i< CPXgetnumcols(env, lp);++i){
athos@1508
   253
      CPXchgcoef(env, lp, -1, i, 0);
alpar@1381
   254
    }
alpar@1381
   255
    
alpar@1381
   256
  }
athos@1458
   257
  // The routine returns zero unless an error occurred during the
athos@1458
   258
  // optimization. Examples of errors include exhausting available
athos@1458
   259
  // memory (CPXERR_NO_MEMORY) or encountering invalid data in the
athos@1458
   260
  // CPLEX problem object (CPXERR_NO_PROBLEM). Exceeding a
athos@1458
   261
  // user-specified CPLEX limit, or proving the model infeasible or
athos@1458
   262
  // unbounded, are not considered errors. Note that a zero return
athos@1458
   263
  // value does not necessarily mean that a solution exists. Use query
athos@1458
   264
  // routines CPXsolninfo, CPXgetstat, and CPXsolution to obtain
athos@1458
   265
  // further information about the status of the optimization.
alpar@1381
   266
  LpCplex::SolveExitStatus LpCplex::_solve()
alpar@1381
   267
  {
athos@1458
   268
    //CPX_PARAM_LPMETHOD 
athos@1508
   269
    status = CPXlpopt(env, lp);
athos@1542
   270
    //status = CPXprimopt(env, lp);
athos@2218
   271
#if CPX_VERSION >= 800
ladanyi@2168
   272
    if (status)
ladanyi@2168
   273
    {
ladanyi@2168
   274
      return UNSOLVED;
ladanyi@2168
   275
    }
ladanyi@2168
   276
    else
ladanyi@2168
   277
    {
ladanyi@2168
   278
      switch (CPXgetstat(env, lp))
ladanyi@2168
   279
      {
ladanyi@2168
   280
        case CPX_STAT_OPTIMAL:
ladanyi@2168
   281
        case CPX_STAT_INFEASIBLE:
ladanyi@2168
   282
        case CPX_STAT_UNBOUNDED:
ladanyi@2168
   283
          return SOLVED;
ladanyi@2168
   284
        default:
ladanyi@2168
   285
          return UNSOLVED;
ladanyi@2168
   286
      }
ladanyi@2168
   287
    }
ladanyi@2168
   288
#else
alpar@1381
   289
    if (status == 0){
athos@1458
   290
      //We want to exclude some cases
athos@1508
   291
      switch (CPXgetstat(env, lp)){
athos@1458
   292
      case CPX_OBJ_LIM:
athos@1458
   293
      case CPX_IT_LIM_FEAS:
athos@1458
   294
      case CPX_IT_LIM_INFEAS:               
athos@1458
   295
      case CPX_TIME_LIM_FEAS:
athos@1458
   296
      case CPX_TIME_LIM_INFEAS:
athos@1458
   297
	return UNSOLVED;
athos@1458
   298
      default:
athos@1458
   299
	return SOLVED; 
athos@1458
   300
      }
alpar@1381
   301
    }
alpar@1381
   302
    else{
alpar@1381
   303
      return UNSOLVED;
alpar@1381
   304
    }
ladanyi@2168
   305
#endif
alpar@1381
   306
  }
alpar@1381
   307
athos@1460
   308
  LpCplex::Value LpCplex::_getPrimal(int i)
athos@1460
   309
  {
athos@1460
   310
    Value x;
athos@1508
   311
    CPXgetx(env, lp, &x, i, i);
athos@1460
   312
    return x;
athos@1460
   313
  }
marci@1787
   314
marci@1787
   315
  LpCplex::Value LpCplex::_getDual(int i)
marci@1787
   316
  {
marci@1787
   317
    Value y;
klao@1798
   318
    CPXgetpi(env, lp, &y, i, i);
marci@1787
   319
    return y;
marci@1787
   320
  }
athos@1460
   321
  
athos@1460
   322
  LpCplex::Value LpCplex::_getPrimalValue()
athos@1460
   323
  {
athos@1460
   324
    Value objval;
athos@1460
   325
    //method = CPXgetmethod (env, lp);
athos@1508
   326
    //printf("CPXgetprobtype %d \n",CPXgetprobtype(env,lp));
athos@1508
   327
    status = CPXgetobjval(env, lp, &objval);
athos@1508
   328
    //printf("Objective value: %g \n",objval);
athos@1460
   329
    return objval;
athos@1460
   330
  }
marci@1840
   331
  bool LpCplex::_isBasicCol(int i) {
marci@1841
   332
    int cstat[CPXgetnumcols(env, lp)];
marci@1841
   333
    CPXgetbase(env, lp, cstat, NULL);
marci@1841
   334
    return (cstat[i]==CPX_BASIC);
marci@1840
   335
  }  
athos@1407
   336
athos@1458
   337
//7.5-os cplex statusai (Vigyazat: a 9.0-asei masok!)
athos@1458
   338
// 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
   339
athos@1458
   340
// For Simplex, Barrier  
athos@1458
   341
// 1  	CPX_OPTIMAL  
athos@1458
   342
// 	 Optimal solution found  
athos@1458
   343
// 2  	CPX_INFEASIBLE  
athos@1458
   344
// 	 Problem infeasible  
athos@1458
   345
// 3    CPX_UNBOUNDED  
athos@1458
   346
// 	 Problem unbounded  
athos@1458
   347
// 4  	CPX_OBJ_LIM  
athos@1458
   348
// 	 Objective limit exceeded in Phase II  
athos@1458
   349
// 5  	CPX_IT_LIM_FEAS  
athos@1458
   350
// 	 Iteration limit exceeded in Phase II  
athos@1458
   351
// 6  	CPX_IT_LIM_INFEAS  
athos@1458
   352
// 	 Iteration limit exceeded in Phase I  
athos@1458
   353
// 7  	CPX_TIME_LIM_FEAS  
athos@1458
   354
// 	 Time limit exceeded in Phase II  
athos@1458
   355
// 8  	CPX_TIME_LIM_INFEAS  
athos@1458
   356
// 	 Time limit exceeded in Phase I  
athos@1458
   357
// 9  	CPX_NUM_BEST_FEAS  
athos@1458
   358
// 	 Problem non-optimal, singularities in Phase II  
athos@1458
   359
// 10 	CPX_NUM_BEST_INFEAS  
athos@1458
   360
// 	 Problem non-optimal, singularities in Phase I  
athos@1458
   361
// 11 	CPX_OPTIMAL_INFEAS  
athos@1458
   362
// 	 Optimal solution found, unscaled infeasibilities  
athos@1458
   363
// 12 	CPX_ABORT_FEAS  
athos@1458
   364
// 	 Aborted in Phase II  
athos@1458
   365
// 13 	CPX_ABORT_INFEAS  
athos@1458
   366
// 	 Aborted in Phase I  
athos@1458
   367
// 14  	CPX_ABORT_DUAL_INFEAS  
athos@1458
   368
// 	 Aborted in barrier, dual infeasible  
athos@1458
   369
// 15  	CPX_ABORT_PRIM_INFEAS  
athos@1458
   370
// 	 Aborted in barrier, primal infeasible  
athos@1458
   371
// 16  	CPX_ABORT_PRIM_DUAL_INFEAS  
athos@1458
   372
// 	 Aborted in barrier, primal and dual infeasible  
athos@1458
   373
// 17  	CPX_ABORT_PRIM_DUAL_FEAS  
athos@1458
   374
// 	 Aborted in barrier, primal and dual feasible  
athos@1458
   375
// 18  	CPX_ABORT_CROSSOVER  
athos@1458
   376
// 	 Aborted in crossover  
athos@1458
   377
// 19  	CPX_INForUNBD  
athos@1458
   378
// 	 Infeasible or unbounded  
athos@1458
   379
// 20   CPX_PIVOT
athos@1458
   380
//       User pivot used
athos@1458
   381
//
athos@1407
   382
//     Ezeket hova tegyem:
athos@1407
   383
// ??case CPX_ABORT_DUAL_INFEAS           
athos@1407
   384
// ??case CPX_ABORT_CROSSOVER             
athos@1407
   385
// ??case CPX_INForUNBD                   
athos@1542
   386
// ??case CPX_PIVOT              
athos@1542
   387
         
athos@1542
   388
//Some more interesting stuff:
athos@1542
   389
athos@1542
   390
// CPX_PARAM_LPMETHOD  1062  int  LPMETHOD
athos@1542
   391
// 0 Automatic 
athos@1542
   392
// 1 Primal Simplex 
athos@1542
   393
// 2 Dual Simplex 
athos@1542
   394
// 3 Network Simplex 
athos@1542
   395
// 4 Standard Barrier 
athos@1542
   396
// Default: 0 
athos@1542
   397
// Description: Method for linear optimization. 
athos@1542
   398
// 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
   399
  //Hulye cplex
athos@1542
   400
  void statusSwitch(CPXENVptr env,int& stat){
ladanyi@2168
   401
#if CPX_VERSION < 900
athos@1542
   402
    int lpmethod;
athos@1542
   403
    CPXgetintparam (env,CPX_PARAM_LPMETHOD,&lpmethod);
athos@1542
   404
    if (lpmethod==2){
athos@1542
   405
      if (stat==CPX_UNBOUNDED){
athos@1542
   406
	stat=CPX_INFEASIBLE;
athos@1542
   407
      }
athos@1542
   408
      else{
athos@1542
   409
	if (stat==CPX_INFEASIBLE)
athos@1542
   410
	  stat=CPX_UNBOUNDED;
athos@1542
   411
      }
athos@1542
   412
    }
ladanyi@2168
   413
#endif
athos@1542
   414
  }
athos@1407
   415
athos@1458
   416
  LpCplex::SolutionStatus LpCplex::_getPrimalStatus()
athos@1458
   417
  {
athos@2218
   418
    //Unboundedness not treated well: the following is from cplex 9.0 doc
athos@2218
   419
    // About Unboundedness
athos@2218
   420
athos@2218
   421
    // The treatment of models that are unbounded involves a few
athos@2218
   422
    // subtleties. Specifically, a declaration of unboundedness means that
athos@2218
   423
    // ILOG CPLEX has determined that the model has an unbounded
athos@2218
   424
    // ray. Given any feasible solution x with objective z, a multiple of
athos@2218
   425
    // the unbounded ray can be added to x to give a feasible solution
athos@2218
   426
    // with objective z-1 (or z+1 for maximization models). Thus, if a
athos@2218
   427
    // feasible solution exists, then the optimal objective is
athos@2218
   428
    // unbounded. Note that ILOG CPLEX has not necessarily concluded that
athos@2218
   429
    // a feasible solution exists. Users can call the routine CPXsolninfo
athos@2218
   430
    // to determine whether ILOG CPLEX has also concluded that the model
athos@2218
   431
    // has a feasible solution.
athos@2218
   432
athos@1508
   433
    int stat = CPXgetstat(env, lp);
athos@2218
   434
#if CPX_VERSION >= 800
ladanyi@2168
   435
    switch (stat)
ladanyi@2168
   436
    {
ladanyi@2168
   437
      case CPX_STAT_OPTIMAL:
ladanyi@2168
   438
        return OPTIMAL;
ladanyi@2168
   439
      case CPX_STAT_UNBOUNDED:
ladanyi@2168
   440
        return INFINITE;
ladanyi@2168
   441
      case CPX_STAT_INFEASIBLE:
ladanyi@2168
   442
        return INFEASIBLE;
ladanyi@2168
   443
      default:
ladanyi@2168
   444
        return UNDEFINED;
ladanyi@2168
   445
    }
ladanyi@2168
   446
#else
athos@1542
   447
    statusSwitch(env,stat);
athos@1542
   448
    //CPXgetstat(env, lp);
athos@1508
   449
    //printf("A primal status: %d, CPX_OPTIMAL=%d \n",stat,CPX_OPTIMAL);
athos@1407
   450
    switch (stat) {
athos@1407
   451
    case 0:
athos@1407
   452
      return UNDEFINED; //Undefined
athos@1407
   453
    case CPX_OPTIMAL://Optimal
athos@1407
   454
      return OPTIMAL;
athos@1407
   455
    case CPX_UNBOUNDED://Unbounded
athos@1542
   456
      return INFEASIBLE;//In case of dual simplex
athos@1542
   457
      //return INFINITE;
athos@1407
   458
    case CPX_INFEASIBLE://Infeasible 
athos@1458
   459
 //    case CPX_IT_LIM_INFEAS:
athos@1458
   460
//     case CPX_TIME_LIM_INFEAS:
athos@1458
   461
//     case CPX_NUM_BEST_INFEAS:             
athos@1458
   462
//     case CPX_OPTIMAL_INFEAS:              
athos@1458
   463
//     case CPX_ABORT_INFEAS:                
athos@1458
   464
//     case CPX_ABORT_PRIM_INFEAS:           
athos@1458
   465
//     case CPX_ABORT_PRIM_DUAL_INFEAS:      
athos@1542
   466
      return INFINITE;//In case of dual simplex
athos@1542
   467
      //return INFEASIBLE;
athos@1458
   468
//     case CPX_OBJ_LIM:                    
athos@1458
   469
//     case CPX_IT_LIM_FEAS:             
athos@1458
   470
//     case CPX_TIME_LIM_FEAS:                
athos@1458
   471
//     case CPX_NUM_BEST_FEAS:                
athos@1458
   472
//     case CPX_ABORT_FEAS:                  
athos@1458
   473
//     case CPX_ABORT_PRIM_DUAL_FEAS:        
athos@1458
   474
//       return FEASIBLE;
athos@1407
   475
    default:
athos@1407
   476
      return UNDEFINED; //Everything else comes here
athos@1407
   477
      //FIXME error
athos@1407
   478
    }
ladanyi@2168
   479
#endif
athos@1458
   480
  }
athos@1407
   481
athos@1458
   482
//9.0-as cplex verzio statusai
athos@1405
   483
// CPX_STAT_ABORT_DUAL_OBJ_LIM
athos@1405
   484
// CPX_STAT_ABORT_IT_LIM
athos@1405
   485
// CPX_STAT_ABORT_OBJ_LIM
athos@1405
   486
// CPX_STAT_ABORT_PRIM_OBJ_LIM
athos@1405
   487
// CPX_STAT_ABORT_TIME_LIM
athos@1405
   488
// CPX_STAT_ABORT_USER
athos@1405
   489
// CPX_STAT_FEASIBLE_RELAXED
athos@1405
   490
// CPX_STAT_INFEASIBLE
athos@1405
   491
// CPX_STAT_INForUNBD
athos@1405
   492
// CPX_STAT_NUM_BEST
athos@1405
   493
// CPX_STAT_OPTIMAL
athos@1405
   494
// CPX_STAT_OPTIMAL_FACE_UNBOUNDED
athos@1405
   495
// CPX_STAT_OPTIMAL_INFEAS
athos@1405
   496
// CPX_STAT_OPTIMAL_RELAXED
athos@1405
   497
// CPX_STAT_UNBOUNDED
athos@1405
   498
athos@1458
   499
  LpCplex::SolutionStatus LpCplex::_getDualStatus()
athos@1458
   500
  {
athos@1508
   501
    int stat = CPXgetstat(env, lp);
athos@2218
   502
#if CPX_VERSION >= 800
ladanyi@2168
   503
    switch (stat)
ladanyi@2168
   504
    {
ladanyi@2168
   505
      case CPX_STAT_OPTIMAL:
ladanyi@2168
   506
        return OPTIMAL;
ladanyi@2168
   507
      case CPX_STAT_UNBOUNDED:
ladanyi@2168
   508
        return INFEASIBLE;
ladanyi@2168
   509
      default:
ladanyi@2168
   510
        return UNDEFINED;
ladanyi@2168
   511
    }
ladanyi@2168
   512
#else
athos@1542
   513
    statusSwitch(env,stat);
athos@1458
   514
    switch (stat) {
athos@1458
   515
    case 0:
athos@1458
   516
      return UNDEFINED; //Undefined
athos@1458
   517
    case CPX_OPTIMAL://Optimal
athos@1458
   518
      return OPTIMAL;
athos@1458
   519
    case CPX_UNBOUNDED:
athos@1458
   520
     return INFEASIBLE;
athos@1458
   521
    default:
athos@1458
   522
      return UNDEFINED; //Everything else comes here
athos@1458
   523
      //FIXME error
athos@1458
   524
    }
ladanyi@2168
   525
#endif
athos@1473
   526
  }
alpar@1381
   527
athos@1460
   528
  LpCplex::ProblemTypes LpCplex::_getProblemType()
alpar@1381
   529
  {
athos@1508
   530
    int stat = CPXgetstat(env, lp);
athos@2218
   531
#if CPX_VERSION >= 800
ladanyi@2168
   532
    switch (stat)
ladanyi@2168
   533
    {
ladanyi@2168
   534
      case CPX_STAT_OPTIMAL:
ladanyi@2168
   535
	return PRIMAL_DUAL_FEASIBLE;
ladanyi@2168
   536
      case CPX_STAT_UNBOUNDED:
ladanyi@2168
   537
 	return PRIMAL_FEASIBLE_DUAL_INFEASIBLE;
ladanyi@2168
   538
      default:
ladanyi@2168
   539
        return UNKNOWN;
ladanyi@2168
   540
    }
ladanyi@2168
   541
#else
athos@1460
   542
    switch (stat) {
athos@1460
   543
    case CPX_OPTIMAL://Optimal
athos@1460
   544
	return PRIMAL_DUAL_FEASIBLE;
athos@1460
   545
    case CPX_UNBOUNDED:
athos@1460
   546
 	return PRIMAL_FEASIBLE_DUAL_INFEASIBLE;
athos@1460
   547
// 	return PRIMAL_INFEASIBLE_DUAL_FEASIBLE;
athos@1460
   548
// 	return PRIMAL_DUAL_INFEASIBLE;
athos@1460
   549
athos@1460
   550
//Seems to be that this is all we can say for sure
athos@1460
   551
    default:
athos@1460
   552
	//In all other cases
athos@1460
   553
	return UNKNOWN;
athos@1460
   554
      //FIXME error
athos@1460
   555
    }
ladanyi@2168
   556
#endif
athos@1473
   557
  }
alpar@1381
   558
alpar@1381
   559
  void LpCplex::_setMax()
alpar@1381
   560
  {
athos@1508
   561
    CPXchgobjsen(env, lp, CPX_MAX);
alpar@1381
   562
   }
alpar@1381
   563
  void LpCplex::_setMin()
alpar@1381
   564
  {
athos@1508
   565
    CPXchgobjsen(env, lp, CPX_MIN);
alpar@1381
   566
   }
alpar@1381
   567
  
alpar@1381
   568
} //namespace lemon
alpar@1381
   569