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