gravatar
deba@inf.elte.hu
deba@inf.elte.hu
Unified message handling for LP and MIP solvers (#9)
0 13 0
default
13 files changed with 184 insertions and 189 deletions:
↑ Collapse diff ↑
Ignore white space 48 line context
... ...
@@ -34,54 +34,57 @@
34 34

	
35 35
#include "coin/CbcCutGenerator.hpp"
36 36
#include "coin/CbcHeuristicLocal.hpp"
37 37
#include "coin/CbcHeuristicGreedy.hpp"
38 38
#include "coin/CbcHeuristicFPump.hpp"
39 39
#include "coin/CbcHeuristicRINS.hpp"
40 40

	
41 41
#include "coin/CglGomory.hpp"
42 42
#include "coin/CglProbing.hpp"
43 43
#include "coin/CglKnapsackCover.hpp"
44 44
#include "coin/CglOddHole.hpp"
45 45
#include "coin/CglClique.hpp"
46 46
#include "coin/CglFlowCover.hpp"
47 47
#include "coin/CglMixedIntegerRounding.hpp"
48 48

	
49 49
#include "coin/CbcHeuristic.hpp"
50 50

	
51 51
namespace lemon {
52 52

	
53 53
  CbcMip::CbcMip() {
54 54
    _prob = new CoinModel();
55 55
    _prob->setProblemName("LEMON");
56 56
    _osi_solver = 0;
57 57
    _cbc_model = 0;
58
    messageLevel(MESSAGE_NOTHING);
58 59
  }
59 60

	
60 61
  CbcMip::CbcMip(const CbcMip& other) {
61 62
    _prob = new CoinModel(*other._prob);
63
    _prob->setProblemName("LEMON");
62 64
    _osi_solver = 0;
63 65
    _cbc_model = 0;
66
    messageLevel(MESSAGE_NOTHING);
64 67
  }
65 68

	
66 69
  CbcMip::~CbcMip() {
67 70
    delete _prob;
68 71
    if (_osi_solver) delete _osi_solver;
69 72
    if (_cbc_model) delete _cbc_model;
70 73
  }
71 74

	
72 75
  const char* CbcMip::_solverName() const { return "CbcMip"; }
73 76

	
74 77
  int CbcMip::_addCol() {
75 78
    _prob->addColumn(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX, 0.0, 0, false);
76 79
    return _prob->numberColumns() - 1;
77 80
  }
78 81

	
79 82
  CbcMip* CbcMip::newSolver() const {
80 83
    CbcMip* newlp = new CbcMip;
81 84
    return newlp;
82 85
  }
83 86

	
84 87
  CbcMip* CbcMip::cloneSolver() const {
85 88
    CbcMip* copylp = new CbcMip(*this);
86 89
    return copylp;
87 90
  }
... ...
@@ -249,66 +252,50 @@
249 252
  CbcMip::Value CbcMip::_getObjCoeff(int i) const {
250 253
    return _prob->getColumnObjective(i);
251 254
  }
252 255

	
253 256
  CbcMip::SolveExitStatus CbcMip::_solve() {
254 257

	
255 258
    if (_osi_solver) {
256 259
      delete _osi_solver;
257 260
    }
258 261
#ifdef COIN_HAS_CLP
259 262
    _osi_solver = new OsiClpSolverInterface();
260 263
#elif COIN_HAS_OSL
261 264
    _osi_solver = new OsiOslSolverInterface();
262 265
#else
263 266
#error Cannot instantiate Osi solver
264 267
#endif
265 268

	
266 269
    _osi_solver->loadFromCoinModel(*_prob);
267 270

	
268 271
    if (_cbc_model) {
269 272
      delete _cbc_model;
270 273
    }
271 274
    _cbc_model= new CbcModel(*_osi_solver);
272 275

	
273
    switch (_message_level) {
274
    case MESSAGE_NO_OUTPUT:
275
      _osi_solver->messageHandler()->setLogLevel(0);
276
      _cbc_model->setLogLevel(0);
277
      break;
278
    case MESSAGE_ERROR_MESSAGE:
279
      _osi_solver->messageHandler()->setLogLevel(1);
280
      _cbc_model->setLogLevel(1);
281
      break;
282
    case MESSAGE_NORMAL_OUTPUT:
283
      _osi_solver->messageHandler()->setLogLevel(2);
284
      _cbc_model->setLogLevel(2);
285
      break;
286
    case MESSAGE_FULL_OUTPUT:
287
      _osi_solver->messageHandler()->setLogLevel(3);
288
      _cbc_model->setLogLevel(3);
289
      break;
290
    }
276
    _osi_solver->messageHandler()->setLogLevel(_message_level);
277
    _cbc_model->setLogLevel(_message_level);
291 278

	
292 279
    _cbc_model->initialSolve();
293 280
    _cbc_model->solver()->setHintParam(OsiDoReducePrint, true, OsiHintTry);
294 281

	
295 282
    if (!_cbc_model->isInitialSolveAbandoned() &&
296 283
        _cbc_model->isInitialSolveProvenOptimal() &&
297 284
        !_cbc_model->isInitialSolveProvenPrimalInfeasible() &&
298 285
        !_cbc_model->isInitialSolveProvenDualInfeasible()) {
299 286

	
300 287
      CglProbing generator1;
301 288
      generator1.setUsingObjective(true);
302 289
      generator1.setMaxPass(3);
303 290
      generator1.setMaxProbe(100);
304 291
      generator1.setMaxLook(50);
305 292
      generator1.setRowCuts(3);
306 293
      _cbc_model->addCutGenerator(&generator1, -1, "Probing");
307 294

	
308 295
      CglGomory generator2;
309 296
      generator2.setLimit(300);
310 297
      _cbc_model->addCutGenerator(&generator2, -1, "Gomory");
311 298

	
312 299
      CglKnapsackCover generator3;
313 300
      _cbc_model->addCutGenerator(&generator3, -1, "Knapsack");
314 301

	
... ...
@@ -432,29 +419,45 @@
432 419
      LEMON_ASSERT(false, "Wrong sense");
433 420
    }
434 421
  }
435 422

	
436 423
  CbcMip::ColTypes CbcMip::_getColType(int i) const {
437 424
    return _prob->getColumnIsInteger(i) ? INTEGER : REAL;
438 425
  }
439 426

	
440 427
  void CbcMip::_clear() {
441 428
    delete _prob;
442 429
    if (_osi_solver) {
443 430
      delete _osi_solver;
444 431
      _osi_solver = 0;
445 432
    }
446 433
    if (_cbc_model) {
447 434
      delete _cbc_model;
448 435
      _cbc_model = 0;
449 436
    }
450 437

	
451 438
    _prob = new CoinModel();
452 439
    rows.clear();
453 440
    cols.clear();
454 441
  }
455 442

	
456
  void CbcMip::messageLevel(MessageLevel m) {
457
    _message_level = m;
443
  void CbcMip::_messageLevel(MessageLevel level) {
444
    switch (level) {
445
    case MESSAGE_NOTHING:
446
      _message_level = 0;
447
      break;
448
    case MESSAGE_ERROR:
449
      _message_level = 1;
450
      break;
451
    case MESSAGE_WARNING:
452
      _message_level = 1;
453
      break;
454
    case MESSAGE_NORMAL:
455
      _message_level = 2;
456
      break;
457
    case MESSAGE_VERBOSE:
458
      _message_level = 3;
459
      break;
460
    }
458 461
  }
459 462

	
460 463
} //END OF NAMESPACE LEMON
Ignore white space 48 line context
... ...
@@ -94,57 +94,36 @@
94 94
    virtual void _setRowLowerBound(int i, Value value);
95 95
    virtual Value _getRowLowerBound(int i) const;
96 96
    virtual void _setRowUpperBound(int i, Value value);
97 97
    virtual Value _getRowUpperBound(int i) const;
98 98

	
99 99
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
100 100
    virtual void _getObjCoeffs(InsertIterator b) const;
101 101

	
102 102
    virtual void _setObjCoeff(int i, Value obj_coef);
103 103
    virtual Value _getObjCoeff(int i) const;
104 104

	
105 105
    virtual void _setSense(Sense sense);
106 106
    virtual Sense _getSense() const;
107 107

	
108 108
    virtual ColTypes _getColType(int col) const;
109 109
    virtual void _setColType(int col, ColTypes col_type);
110 110

	
111 111
    virtual SolveExitStatus _solve();
112 112
    virtual ProblemType _getType() const;
113 113
    virtual Value _getSol(int i) const;
114 114
    virtual Value _getSolValue() const;
115 115

	
116 116
    virtual void _clear();
117 117

	
118
  public:
118
    virtual void _messageLevel(MessageLevel level);
119
    void _applyMessageLevel();
119 120

	
120
    ///Enum for \c messageLevel() parameter
121
    enum MessageLevel {
122
      /// no output (default value)
123
      MESSAGE_NO_OUTPUT = 0,
124
      /// error messages only
125
      MESSAGE_ERROR_MESSAGE = 1,
126
      /// normal output
127
      MESSAGE_NORMAL_OUTPUT = 2,
128
      /// full output (includes informational messages)
129
      MESSAGE_FULL_OUTPUT = 3
130
    };
121
    int _message_level;
131 122

	
132
  private:
133

	
134
    MessageLevel _message_level;
135

	
136
  public:
137

	
138
    ///Set the verbosity of the messages
139

	
140
    ///Set the verbosity of the messages
141
    ///
142
    ///\param m is the level of the messages output by the solver routines.
143
    void messageLevel(MessageLevel m);
144

	
123
    
145 124

	
146 125
  };
147 126

	
148 127
}
149 128

	
150 129
#endif
Ignore white space 48 line context
... ...
@@ -3,57 +3,57 @@
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <lemon/clp.h>
20 20
#include <coin/ClpSimplex.hpp>
21 21

	
22 22
namespace lemon {
23 23

	
24 24
  ClpLp::ClpLp() {
25 25
    _prob = new ClpSimplex();
26 26
    _init_temporals();
27
    messageLevel(MESSAGE_NO_OUTPUT);
27
    messageLevel(MESSAGE_NOTHING);
28 28
  }
29 29

	
30 30
  ClpLp::ClpLp(const ClpLp& other) {
31 31
    _prob = new ClpSimplex(*other._prob);
32 32
    rows = other.rows;
33 33
    cols = other.cols;
34 34
    _init_temporals();
35
    messageLevel(MESSAGE_NO_OUTPUT);
35
    messageLevel(MESSAGE_NOTHING);
36 36
  }
37 37

	
38 38
  ClpLp::~ClpLp() {
39 39
    delete _prob;
40 40
    _clear_temporals();
41 41
  }
42 42

	
43 43
  void ClpLp::_init_temporals() {
44 44
    _primal_ray = 0;
45 45
    _dual_ray = 0;
46 46
  }
47 47

	
48 48
  void ClpLp::_clear_temporals() {
49 49
    if (_primal_ray) {
50 50
      delete[] _primal_ray;
51 51
      _primal_ray = 0;
52 52
    }
53 53
    if (_dual_ray) {
54 54
      delete[] _dual_ray;
55 55
      _dual_ray = 0;
56 56
    }
57 57
  }
58 58

	
59 59
  ClpLp* ClpLp::newSolver() const {
... ...
@@ -409,29 +409,45 @@
409 409
    case MAX:
410 410
      _prob->setOptimizationDirection(-1);
411 411
      break;
412 412
    }
413 413
  }
414 414

	
415 415
  ClpLp::Sense ClpLp::_getSense() const {
416 416
    double dir = _prob->optimizationDirection();
417 417
    if (dir > 0.0) {
418 418
      return MIN;
419 419
    } else {
420 420
      return MAX;
421 421
    }
422 422
  }
423 423

	
424 424
  void ClpLp::_clear() {
425 425
    delete _prob;
426 426
    _prob = new ClpSimplex();
427 427
    rows.clear();
428 428
    cols.clear();
429 429
    _col_names_ref.clear();
430 430
    _clear_temporals();
431 431
  }
432 432

	
433
  void ClpLp::messageLevel(MessageLevel m) {
434
    _prob->setLogLevel(static_cast<int>(m));
433
  void ClpLp::_messageLevel(MessageLevel level) {
434
    switch (level) {
435
    case MESSAGE_NOTHING:
436
      _prob->setLogLevel(0);
437
      break;
438
    case MESSAGE_ERROR:
439
      _prob->setLogLevel(1);
440
      break;
441
    case MESSAGE_WARNING:
442
      _prob->setLogLevel(2);
443
      break;
444
    case MESSAGE_NORMAL:
445
      _prob->setLogLevel(3);
446
      break;
447
    case MESSAGE_VERBOSE:
448
      _prob->setLogLevel(4);
449
      break;
450
    }
435 451
  }
436 452

	
437 453
} //END OF NAMESPACE LEMON
Ignore white space 48 line context
... ...
@@ -115,67 +115,49 @@
115 115
    virtual void _setObjCoeff(int i, Value obj_coef);
116 116
    virtual Value _getObjCoeff(int i) const;
117 117

	
118 118
    virtual void _setSense(Sense sense);
119 119
    virtual Sense _getSense() const;
120 120

	
121 121
    virtual SolveExitStatus _solve();
122 122

	
123 123
    virtual Value _getPrimal(int i) const;
124 124
    virtual Value _getDual(int i) const;
125 125

	
126 126
    virtual Value _getPrimalValue() const;
127 127

	
128 128
    virtual Value _getPrimalRay(int i) const;
129 129
    virtual Value _getDualRay(int i) const;
130 130

	
131 131
    virtual VarStatus _getColStatus(int i) const;
132 132
    virtual VarStatus _getRowStatus(int i) const;
133 133

	
134 134
    virtual ProblemType _getPrimalType() const;
135 135
    virtual ProblemType _getDualType() const;
136 136

	
137 137
    virtual void _clear();
138 138

	
139
    virtual void _messageLevel(MessageLevel);
140
    
139 141
  public:
140 142

	
141 143
    ///Solves LP with primal simplex method.
142 144
    SolveExitStatus solvePrimal();
143 145

	
144 146
    ///Solves LP with dual simplex method.
145 147
    SolveExitStatus solveDual();
146 148

	
147 149
    ///Solves LP with barrier method.
148 150
    SolveExitStatus solveBarrier();
149 151

	
150 152
    ///Returns the constraint identifier understood by CLP.
151 153
    int clpRow(Row r) const { return rows(id(r)); }
152 154

	
153 155
    ///Returns the variable identifier understood by CLP.
154 156
    int clpCol(Col c) const { return cols(id(c)); }
155 157

	
156
    ///Enum for \c messageLevel() parameter
157
    enum MessageLevel {
158
      /// no output (default value)
159
      MESSAGE_NO_OUTPUT = 0,
160
      /// print final solution
161
      MESSAGE_FINAL_SOLUTION = 1,
162
      /// print factorization
163
      MESSAGE_FACTORIZATION = 2,
164
      /// normal output
165
      MESSAGE_NORMAL_OUTPUT = 3,
166
      /// verbose output
167
      MESSAGE_VERBOSE_OUTPUT = 4
168
    };
169
    ///Set the verbosity of the messages
170

	
171
    ///Set the verbosity of the messages
172
    ///
173
    ///\param m is the level of the messages output by the solver routines.
174
    void messageLevel(MessageLevel m);
175

	
176 158
  };
177 159

	
178 160
} //END OF NAMESPACE LEMON
179 161

	
180 162
#endif //LEMON_CLP_H
181 163

	
Ignore white space 48 line context
... ...
@@ -51,62 +51,65 @@
51 51
  CplexEnv::CplexEnv(const CplexEnv& other) {
52 52
    _env = other._env;
53 53
    _cnt = other._cnt;
54 54
    ++(*_cnt);
55 55
  }
56 56

	
57 57
  CplexEnv& CplexEnv::operator=(const CplexEnv& other) {
58 58
    _env = other._env;
59 59
    _cnt = other._cnt;
60 60
    ++(*_cnt);
61 61
    return *this;
62 62
  }
63 63

	
64 64
  CplexEnv::~CplexEnv() {
65 65
    --(*_cnt);
66 66
    if (*_cnt == 0) {
67 67
      delete _cnt;
68 68
      CPXcloseCPLEX(&_env);
69 69
    }
70 70
  }
71 71

	
72 72
  CplexBase::CplexBase() : LpBase() {
73 73
    int status;
74 74
    _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
75
    messageLevel(MESSAGE_NOTHING);
75 76
  }
76 77

	
77 78
  CplexBase::CplexBase(const CplexEnv& env)
78 79
    : LpBase(), _env(env) {
79 80
    int status;
80 81
    _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
82
    messageLevel(MESSAGE_NOTHING);
81 83
  }
82 84

	
83 85
  CplexBase::CplexBase(const CplexBase& cplex)
84 86
    : LpBase() {
85 87
    int status;
86 88
    _prob = CPXcloneprob(cplexEnv(), cplex._prob, &status);
87 89
    rows = cplex.rows;
88 90
    cols = cplex.cols;
91
    messageLevel(MESSAGE_NOTHING);
89 92
  }
90 93

	
91 94
  CplexBase::~CplexBase() {
92 95
    CPXfreeprob(cplexEnv(),&_prob);
93 96
  }
94 97

	
95 98
  int CplexBase::_addCol() {
96 99
    int i = CPXgetnumcols(cplexEnv(), _prob);
97 100
    double lb = -INF, ub = INF;
98 101
    CPXnewcols(cplexEnv(), _prob, 1, 0, &lb, &ub, 0, 0);
99 102
    return i;
100 103
  }
101 104

	
102 105

	
103 106
  int CplexBase::_addRow() {
104 107
    int i = CPXgetnumrows(cplexEnv(), _prob);
105 108
    const double ub = INF;
106 109
    const char s = 'L';
107 110
    CPXnewrows(cplexEnv(), _prob, 1, &ub, &s, 0, 0);
108 111
    return i;
109 112
  }
110 113

	
111 114

	
112 115
  void CplexBase::_eraseCol(int i) {
... ...
@@ -417,48 +420,67 @@
417 420
      break;
418 421
    }
419 422
  }
420 423

	
421 424
  CplexBase::Sense CplexBase::_getSense() const {
422 425
    switch (CPXgetobjsen(cplexEnv(), _prob)) {
423 426
    case CPX_MIN:
424 427
      return MIN;
425 428
    case CPX_MAX:
426 429
      return MAX;
427 430
    default:
428 431
      LEMON_ASSERT(false, "Invalid sense");
429 432
      return CplexBase::Sense();
430 433
    }
431 434
  }
432 435

	
433 436
  void CplexBase::_clear() {
434 437
    CPXfreeprob(cplexEnv(),&_prob);
435 438
    int status;
436 439
    _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
437 440
    rows.clear();
438 441
    cols.clear();
439 442
  }
440 443

	
444
  void CplexBase::_messageLevel(MessageLevel level) {
445
    switch (level) {
446
    case MESSAGE_NOTHING:
447
      _message_enabled = false;
448
      break;
449
    case MESSAGE_ERROR:
450
    case MESSAGE_WARNING:
451
    case MESSAGE_NORMAL:
452
    case MESSAGE_VERBOSE:
453
      _message_enabled = true;
454
      break;
455
    }
456
  }
457

	
458
  void CplexBase::_applyMessageLevel() {
459
    CPXsetintparam(cplexEnv(), CPX_PARAM_SCRIND, 
460
                   _message_enabled ? CPX_ON : CPX_OFF);
461
  }
462

	
441 463
  // CplexLp members
442 464

	
443 465
  CplexLp::CplexLp()
444 466
    : LpBase(), LpSolver(), CplexBase() {}
445 467

	
446 468
  CplexLp::CplexLp(const CplexEnv& env)
447 469
    : LpBase(), LpSolver(), CplexBase(env) {}
448 470

	
449 471
  CplexLp::CplexLp(const CplexLp& other)
450 472
    : LpBase(), LpSolver(), CplexBase(other) {}
451 473

	
452 474
  CplexLp::~CplexLp() {}
453 475

	
454 476
  CplexLp* CplexLp::newSolver() const { return new CplexLp; }
455 477
  CplexLp* CplexLp::cloneSolver() const {return new CplexLp(*this); }
456 478

	
457 479
  const char* CplexLp::_solverName() const { return "CplexLp"; }
458 480

	
459 481
  void CplexLp::_clear_temporals() {
460 482
    _col_status.clear();
461 483
    _row_status.clear();
462 484
    _primal_ray.clear();
463 485
    _dual_ray.clear();
464 486
  }
... ...
@@ -486,63 +508,67 @@
486 508
    } else {
487 509
      return UNSOLVED;
488 510
    }
489 511
#else
490 512
    if (status == 0) {
491 513
      //We want to exclude some cases
492 514
      switch (CPXgetstat(cplexEnv(), _prob)) {
493 515
      case CPX_OBJ_LIM:
494 516
      case CPX_IT_LIM_FEAS:
495 517
      case CPX_IT_LIM_INFEAS:
496 518
      case CPX_TIME_LIM_FEAS:
497 519
      case CPX_TIME_LIM_INFEAS:
498 520
        return UNSOLVED;
499 521
      default:
500 522
        return SOLVED;
501 523
      }
502 524
    } else {
503 525
      return UNSOLVED;
504 526
    }
505 527
#endif
506 528
  }
507 529

	
508 530
  CplexLp::SolveExitStatus CplexLp::_solve() {
509 531
    _clear_temporals();
532
    _applyMessageLevel();
510 533
    return convertStatus(CPXlpopt(cplexEnv(), _prob));
511 534
  }
512 535

	
513 536
  CplexLp::SolveExitStatus CplexLp::solvePrimal() {
514 537
    _clear_temporals();
538
    _applyMessageLevel();
515 539
    return convertStatus(CPXprimopt(cplexEnv(), _prob));
516 540
  }
517 541

	
518 542
  CplexLp::SolveExitStatus CplexLp::solveDual() {
519 543
    _clear_temporals();
544
    _applyMessageLevel();
520 545
    return convertStatus(CPXdualopt(cplexEnv(), _prob));
521 546
  }
522 547

	
523 548
  CplexLp::SolveExitStatus CplexLp::solveBarrier() {
524 549
    _clear_temporals();
550
    _applyMessageLevel();
525 551
    return convertStatus(CPXbaropt(cplexEnv(), _prob));
526 552
  }
527 553

	
528 554
  CplexLp::Value CplexLp::_getPrimal(int i) const {
529 555
    Value x;
530 556
    CPXgetx(cplexEnv(), _prob, &x, i, i);
531 557
    return x;
532 558
  }
533 559

	
534 560
  CplexLp::Value CplexLp::_getDual(int i) const {
535 561
    Value y;
536 562
    CPXgetpi(cplexEnv(), _prob, &y, i, i);
537 563
    return y;
538 564
  }
539 565

	
540 566
  CplexLp::Value CplexLp::_getPrimalValue() const {
541 567
    Value objval;
542 568
    CPXgetobjval(cplexEnv(), _prob, &objval);
543 569
    return objval;
544 570
  }
545 571

	
546 572
  CplexLp::VarStatus CplexLp::_getColStatus(int i) const {
547 573
    if (_col_status.empty()) {
548 574
      _col_status.resize(CPXgetnumcols(cplexEnv(), _prob));
... ...
@@ -579,96 +605,96 @@
579 605
      }
580 606
    case CPX_AT_UPPER:
581 607
      return UPPER;
582 608
    default:
583 609
      LEMON_ASSERT(false, "Wrong row status");
584 610
      return CplexLp::VarStatus();
585 611
    }
586 612
  }
587 613

	
588 614
  CplexLp::Value CplexLp::_getPrimalRay(int i) const {
589 615
    if (_primal_ray.empty()) {
590 616
      _primal_ray.resize(CPXgetnumcols(cplexEnv(), _prob));
591 617
      CPXgetray(cplexEnv(), _prob, &_primal_ray.front());
592 618
    }
593 619
    return _primal_ray[i];
594 620
  }
595 621

	
596 622
  CplexLp::Value CplexLp::_getDualRay(int i) const {
597 623
    if (_dual_ray.empty()) {
598 624

	
599 625
    }
600 626
    return _dual_ray[i];
601 627
  }
602 628

	
603
  //7.5-os cplex statusai (Vigyazat: a 9.0-asei masok!)
629
  // Cplex 7.0 status values
604 630
  // This table lists the statuses, returned by the CPXgetstat()
605 631
  // routine, for solutions to LP problems or mixed integer problems. If
606 632
  // no solution exists, the return value is zero.
607 633

	
608 634
  // For Simplex, Barrier
609 635
  // 1          CPX_OPTIMAL
610 636
  //          Optimal solution found
611 637
  // 2          CPX_INFEASIBLE
612 638
  //          Problem infeasible
613 639
  // 3    CPX_UNBOUNDED
614 640
  //          Problem unbounded
615 641
  // 4          CPX_OBJ_LIM
616 642
  //          Objective limit exceeded in Phase II
617 643
  // 5          CPX_IT_LIM_FEAS
618 644
  //          Iteration limit exceeded in Phase II
619 645
  // 6          CPX_IT_LIM_INFEAS
620 646
  //          Iteration limit exceeded in Phase I
621 647
  // 7          CPX_TIME_LIM_FEAS
622 648
  //          Time limit exceeded in Phase II
623 649
  // 8          CPX_TIME_LIM_INFEAS
624 650
  //          Time limit exceeded in Phase I
625 651
  // 9          CPX_NUM_BEST_FEAS
626 652
  //          Problem non-optimal, singularities in Phase II
627 653
  // 10         CPX_NUM_BEST_INFEAS
628 654
  //          Problem non-optimal, singularities in Phase I
629 655
  // 11         CPX_OPTIMAL_INFEAS
630 656
  //          Optimal solution found, unscaled infeasibilities
631 657
  // 12         CPX_ABORT_FEAS
632 658
  //          Aborted in Phase II
633 659
  // 13         CPX_ABORT_INFEAS
634 660
  //          Aborted in Phase I
635 661
  // 14          CPX_ABORT_DUAL_INFEAS
636 662
  //          Aborted in barrier, dual infeasible
637 663
  // 15          CPX_ABORT_PRIM_INFEAS
638 664
  //          Aborted in barrier, primal infeasible
639 665
  // 16          CPX_ABORT_PRIM_DUAL_INFEAS
640 666
  //          Aborted in barrier, primal and dual infeasible
641 667
  // 17          CPX_ABORT_PRIM_DUAL_FEAS
642 668
  //          Aborted in barrier, primal and dual feasible
643 669
  // 18          CPX_ABORT_CROSSOVER
644 670
  //          Aborted in crossover
645 671
  // 19          CPX_INForUNBD
646 672
  //          Infeasible or unbounded
647 673
  // 20   CPX_PIVOT
648 674
  //       User pivot used
649 675
  //
650
  //     Ezeket hova tegyem:
676
  // Pending return values
651 677
  // ??case CPX_ABORT_DUAL_INFEAS
652 678
  // ??case CPX_ABORT_CROSSOVER
653 679
  // ??case CPX_INForUNBD
654 680
  // ??case CPX_PIVOT
655 681

	
656 682
  //Some more interesting stuff:
657 683

	
658 684
  // CPX_PARAM_PROBMETHOD  1062  int  LPMETHOD
659 685
  // 0 Automatic
660 686
  // 1 Primal Simplex
661 687
  // 2 Dual Simplex
662 688
  // 3 Network Simplex
663 689
  // 4 Standard Barrier
664 690
  // Default: 0
665 691
  // Description: Method for linear optimization.
666 692
  // Determines which algorithm is used when CPXlpopt() (or "optimize"
667 693
  // in the Interactive Optimizer) is called. Currently the behavior of
668 694
  // the "Automatic" setting is that CPLEX simply invokes the dual
669 695
  // simplex method, but this capability may be expanded in the future
670 696
  // so that CPLEX chooses the method based on problem characteristics
671 697
#if CPX_VERSION < 900
672 698
  void statusSwitch(CPXENVptr cplexEnv(),int& stat){
673 699
    int lpmethod;
674 700
    CPXgetintparam (cplexEnv(),CPX_PARAM_PROBMETHOD,&lpmethod);
... ...
@@ -697,82 +723,81 @@
697 723
    // the unbounded ray can be added to x to give a feasible solution
698 724
    // with objective z-1 (or z+1 for maximization models). Thus, if a
699 725
    // feasible solution exists, then the optimal objective is
700 726
    // unbounded. Note that ILOG CPLEX has not necessarily concluded that
701 727
    // a feasible solution exists. Users can call the routine CPXsolninfo
702 728
    // to determine whether ILOG CPLEX has also concluded that the model
703 729
    // has a feasible solution.
704 730

	
705 731
    int stat = CPXgetstat(cplexEnv(), _prob);
706 732
#if CPX_VERSION >= 800
707 733
    switch (stat)
708 734
      {
709 735
      case CPX_STAT_OPTIMAL:
710 736
        return OPTIMAL;
711 737
      case CPX_STAT_UNBOUNDED:
712 738
        return UNBOUNDED;
713 739
      case CPX_STAT_INFEASIBLE:
714 740
        return INFEASIBLE;
715 741
      default:
716 742
        return UNDEFINED;
717 743
      }
718 744
#else
719 745
    statusSwitch(cplexEnv(),stat);
720 746
    //CPXgetstat(cplexEnv(), _prob);
721
    //printf("A primal status: %d, CPX_OPTIMAL=%d \n",stat,CPX_OPTIMAL);
722 747
    switch (stat) {
723 748
    case 0:
724 749
      return UNDEFINED; //Undefined
725 750
    case CPX_OPTIMAL://Optimal
726 751
      return OPTIMAL;
727 752
    case CPX_UNBOUNDED://Unbounded
728 753
      return INFEASIBLE;//In case of dual simplex
729 754
      //return UNBOUNDED;
730 755
    case CPX_INFEASIBLE://Infeasible
731 756
      //    case CPX_IT_LIM_INFEAS:
732 757
      //     case CPX_TIME_LIM_INFEAS:
733 758
      //     case CPX_NUM_BEST_INFEAS:
734 759
      //     case CPX_OPTIMAL_INFEAS:
735 760
      //     case CPX_ABORT_INFEAS:
736 761
      //     case CPX_ABORT_PRIM_INFEAS:
737 762
      //     case CPX_ABORT_PRIM_DUAL_INFEAS:
738 763
      return UNBOUNDED;//In case of dual simplex
739 764
      //return INFEASIBLE;
740 765
      //     case CPX_OBJ_LIM:
741 766
      //     case CPX_IT_LIM_FEAS:
742 767
      //     case CPX_TIME_LIM_FEAS:
743 768
      //     case CPX_NUM_BEST_FEAS:
744 769
      //     case CPX_ABORT_FEAS:
745 770
      //     case CPX_ABORT_PRIM_DUAL_FEAS:
746 771
      //       return FEASIBLE;
747 772
    default:
748 773
      return UNDEFINED; //Everything else comes here
749 774
      //FIXME error
750 775
    }
751 776
#endif
752 777
  }
753 778

	
754
  //9.0-as cplex verzio statusai
779
  // Cplex 9.0 status values
755 780
  // CPX_STAT_ABORT_DUAL_OBJ_LIM
756 781
  // CPX_STAT_ABORT_IT_LIM
757 782
  // CPX_STAT_ABORT_OBJ_LIM
758 783
  // CPX_STAT_ABORT_PRIM_OBJ_LIM
759 784
  // CPX_STAT_ABORT_TIME_LIM
760 785
  // CPX_STAT_ABORT_USER
761 786
  // CPX_STAT_FEASIBLE_RELAXED
762 787
  // CPX_STAT_INFEASIBLE
763 788
  // CPX_STAT_INForUNBD
764 789
  // CPX_STAT_NUM_BEST
765 790
  // CPX_STAT_OPTIMAL
766 791
  // CPX_STAT_OPTIMAL_FACE_UNBOUNDED
767 792
  // CPX_STAT_OPTIMAL_INFEAS
768 793
  // CPX_STAT_OPTIMAL_RELAXED
769 794
  // CPX_STAT_UNBOUNDED
770 795

	
771 796
  CplexLp::ProblemType CplexLp::_getDualType() const {
772 797
    int stat = CPXgetstat(cplexEnv(), _prob);
773 798
#if CPX_VERSION >= 800
774 799
    switch (stat) {
775 800
    case CPX_STAT_OPTIMAL:
776 801
      return OPTIMAL;
777 802
    case CPX_STAT_UNBOUNDED:
778 803
      return INFEASIBLE;
... ...
@@ -843,48 +868,49 @@
843 868
      CPXchgctype (cplexEnv(), _prob, 1, &i, &t);
844 869
    } break;
845 870
    default:
846 871
      break;
847 872
    }
848 873
  }
849 874

	
850 875
  CplexMip::ColTypes CplexMip::_getColType(int i) const {
851 876
    char t;
852 877
    CPXgetctype (cplexEnv(), _prob, &t, i, i);
853 878
    switch (t) {
854 879
    case 'I':
855 880
      return INTEGER;
856 881
    case 'C':
857 882
      return REAL;
858 883
    default:
859 884
      LEMON_ASSERT(false, "Invalid column type");
860 885
      return ColTypes();
861 886
    }
862 887

	
863 888
  }
864 889

	
865 890
  CplexMip::SolveExitStatus CplexMip::_solve() {
866 891
    int status;
892
    _applyMessageLevel();
867 893
    status = CPXmipopt (cplexEnv(), _prob);
868 894
    if (status==0)
869 895
      return SOLVED;
870 896
    else
871 897
      return UNSOLVED;
872 898

	
873 899
  }
874 900

	
875 901

	
876 902
  CplexMip::ProblemType CplexMip::_getType() const {
877 903

	
878 904
    int stat = CPXgetstat(cplexEnv(), _prob);
879 905

	
880 906
    //Fortunately, MIP statuses did not change for cplex 8.0
881 907
    switch (stat) {
882 908
    case CPXMIP_OPTIMAL:
883 909
      // Optimal integer solution has been found.
884 910
    case CPXMIP_OPTIMAL_TOL:
885 911
      // Optimal soluton with the tolerance defined by epgap or epagap has
886 912
      // been found.
887 913
      return OPTIMAL;
888 914
      //This also exists in later issues
889 915
      //    case CPXMIP_UNBOUNDED:
890 916
      //return UNBOUNDED;
Ignore white space 48 line context
... ...
@@ -123,56 +123,71 @@
123 123
    virtual void _setColUpperBound(int i, Value value);
124 124
    virtual Value _getColUpperBound(int i) const;
125 125

	
126 126
  private:
127 127
    void _set_row_bounds(int i, Value lb, Value ub);
128 128
  protected:
129 129

	
130 130
    virtual void _setRowLowerBound(int i, Value value);
131 131
    virtual Value _getRowLowerBound(int i) const;
132 132

	
133 133
    virtual void _setRowUpperBound(int i, Value value);
134 134
    virtual Value _getRowUpperBound(int i) const;
135 135

	
136 136
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
137 137
    virtual void _getObjCoeffs(InsertIterator b) const;
138 138

	
139 139
    virtual void _setObjCoeff(int i, Value obj_coef);
140 140
    virtual Value _getObjCoeff(int i) const;
141 141

	
142 142
    virtual void _setSense(Sense sense);
143 143
    virtual Sense _getSense() const;
144 144

	
145 145
    virtual void _clear();
146 146

	
147
    virtual void _messageLevel(MessageLevel level);
148
    void _applyMessageLevel();
149

	
150
    bool _message_enabled;
151

	
147 152
  public:
148 153

	
149 154
    /// Returns the used \c CplexEnv instance
150 155
    const CplexEnv& env() const { return _env; }
156

	
157
    /// \brief Returns the const cpxenv pointer
151 158
    ///
159
    /// \note The cpxenv might be destructed with the solver.
152 160
    const cpxenv* cplexEnv() const { return _env.cplexEnv(); }
153 161

	
162
    /// \brief Returns the const cpxenv pointer
163
    ///
164
    /// \note The cpxenv might be destructed with the solver.
165
    cpxenv* cplexEnv() { return _env.cplexEnv(); }
166

	
167
    /// Returns the cplex problem object
154 168
    cpxlp* cplexLp() { return _prob; }
169
    /// Returns the cplex problem object
155 170
    const cpxlp* cplexLp() const { return _prob; }
156 171

	
157 172
  };
158 173

	
159 174
  /// \brief Interface for the CPLEX LP solver
160 175
  ///
161 176
  /// This class implements an interface for the CPLEX LP solver.
162 177
  ///\ingroup lp_group
163 178
  class CplexLp : public LpSolver, public CplexBase {
164 179
  public:
165 180
    /// \e
166 181
    CplexLp();
167 182
    /// \e
168 183
    CplexLp(const CplexEnv&);
169 184
    /// \e
170 185
    CplexLp(const CplexLp&);
171 186
    /// \e
172 187
    virtual ~CplexLp();
173 188

	
174 189
    /// \e
175 190
    virtual CplexLp* cloneSolver() const;
176 191
    /// \e
177 192
    virtual CplexLp* newSolver() const;
178 193

	
Ignore white space 48 line context
... ...
@@ -10,56 +10,58 @@
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
///\file
20 20
///\brief Implementation of the LEMON GLPK LP and MIP solver interface.
21 21

	
22 22
#include <lemon/glpk.h>
23 23
#include <glpk.h>
24 24

	
25 25
#include <lemon/assert.h>
26 26

	
27 27
namespace lemon {
28 28

	
29 29
  // GlpkBase members
30 30

	
31 31
  GlpkBase::GlpkBase() : LpBase() {
32 32
    lp = glp_create_prob();
33 33
    glp_create_index(lp);
34
    messageLevel(MESSAGE_NOTHING);
34 35
  }
35 36

	
36 37
  GlpkBase::GlpkBase(const GlpkBase &other) : LpBase() {
37 38
    lp = glp_create_prob();
38 39
    glp_copy_prob(lp, other.lp, GLP_ON);
39 40
    glp_create_index(lp);
40 41
    rows = other.rows;
41 42
    cols = other.cols;
43
    messageLevel(MESSAGE_NOTHING);
42 44
  }
43 45

	
44 46
  GlpkBase::~GlpkBase() {
45 47
    glp_delete_prob(lp);
46 48
  }
47 49

	
48 50
  int GlpkBase::_addCol() {
49 51
    int i = glp_add_cols(lp, 1);
50 52
    glp_set_col_bnds(lp, i, GLP_FR, 0.0, 0.0);
51 53
    return i;
52 54
  }
53 55

	
54 56
  int GlpkBase::_addRow() {
55 57
    int i = glp_add_rows(lp, 1);
56 58
    glp_set_row_bnds(lp, i, GLP_FR, 0.0, 0.0);
57 59
    return i;
58 60
  }
59 61

	
60 62
  void GlpkBase::_eraseCol(int i) {
61 63
    int ca[2];
62 64
    ca[1] = i;
63 65
    glp_del_cols(lp, 1, ca);
64 66
  }
65 67

	
... ...
@@ -505,140 +507,132 @@
505 507
  }
506 508

	
507 509
  GlpkBase::Sense GlpkBase::_getSense() const {
508 510
    switch(glp_get_obj_dir(lp)) {
509 511
    case GLP_MIN:
510 512
      return MIN;
511 513
    case GLP_MAX:
512 514
      return MAX;
513 515
    default:
514 516
      LEMON_ASSERT(false, "Wrong sense");
515 517
      return GlpkBase::Sense();
516 518
    }
517 519
  }
518 520

	
519 521
  void GlpkBase::_clear() {
520 522
    glp_erase_prob(lp);
521 523
    rows.clear();
522 524
    cols.clear();
523 525
  }
524 526

	
525 527
  void GlpkBase::freeEnv() {
526 528
    glp_free_env();
527 529
  }
528 530

	
531
  void GlpkBase::_messageLevel(MessageLevel level) {
532
    switch (level) {
533
    case MESSAGE_NOTHING:
534
      _message_level = GLP_MSG_OFF;
535
      break;
536
    case MESSAGE_ERROR:
537
      _message_level = GLP_MSG_ERR;
538
      break;
539
    case MESSAGE_WARNING:
540
      _message_level = GLP_MSG_ERR;
541
      break;
542
    case MESSAGE_NORMAL:
543
      _message_level = GLP_MSG_ON;
544
      break;
545
    case MESSAGE_VERBOSE:
546
      _message_level = GLP_MSG_ALL;
547
      break;
548
    }
549
  }
550

	
529 551
  GlpkBase::FreeEnvHelper GlpkBase::freeEnvHelper;
530 552

	
531 553
  // GlpkLp members
532 554

	
533 555
  GlpkLp::GlpkLp()
534 556
    : LpBase(), LpSolver(), GlpkBase() {
535
    messageLevel(MESSAGE_NO_OUTPUT);
536 557
    presolver(false);
537 558
  }
538 559

	
539 560
  GlpkLp::GlpkLp(const GlpkLp& other)
540 561
    : LpBase(other), LpSolver(other), GlpkBase(other) {
541
    messageLevel(MESSAGE_NO_OUTPUT);
542 562
    presolver(false);
543 563
  }
544 564

	
545 565
  GlpkLp* GlpkLp::newSolver() const { return new GlpkLp; }
546 566
  GlpkLp* GlpkLp::cloneSolver() const { return new GlpkLp(*this); }
547 567

	
548 568
  const char* GlpkLp::_solverName() const { return "GlpkLp"; }
549 569

	
550 570
  void GlpkLp::_clear_temporals() {
551 571
    _primal_ray.clear();
552 572
    _dual_ray.clear();
553 573
  }
554 574

	
555 575
  GlpkLp::SolveExitStatus GlpkLp::_solve() {
556 576
    return solvePrimal();
557 577
  }
558 578

	
559 579
  GlpkLp::SolveExitStatus GlpkLp::solvePrimal() {
560 580
    _clear_temporals();
561 581

	
562 582
    glp_smcp smcp;
563 583
    glp_init_smcp(&smcp);
564 584

	
565
    switch (_message_level) {
566
    case MESSAGE_NO_OUTPUT:
567
      smcp.msg_lev = GLP_MSG_OFF;
568
      break;
569
    case MESSAGE_ERROR_MESSAGE:
570
      smcp.msg_lev = GLP_MSG_ERR;
571
      break;
572
    case MESSAGE_NORMAL_OUTPUT:
573
      smcp.msg_lev = GLP_MSG_ON;
574
      break;
575
    case MESSAGE_FULL_OUTPUT:
576
      smcp.msg_lev = GLP_MSG_ALL;
577
      break;
578
    }
585
    smcp.msg_lev = _message_level;
579 586
    smcp.presolve = _presolve;
580 587

	
581 588
    // If the basis is not valid we get an error return value.
582 589
    // In this case we can try to create a new basis.
583 590
    switch (glp_simplex(lp, &smcp)) {
584 591
    case 0:
585 592
      break;
586 593
    case GLP_EBADB:
587 594
    case GLP_ESING:
588 595
    case GLP_ECOND:
589 596
      glp_term_out(false);
590 597
      glp_adv_basis(lp, 0);
591 598
      glp_term_out(true);
592 599
      if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
593 600
      break;
594 601
    default:
595 602
      return UNSOLVED;
596 603
    }
597 604

	
598 605
    return SOLVED;
599 606
  }
600 607

	
601 608
  GlpkLp::SolveExitStatus GlpkLp::solveDual() {
602 609
    _clear_temporals();
603 610

	
604 611
    glp_smcp smcp;
605 612
    glp_init_smcp(&smcp);
606 613

	
607
    switch (_message_level) {
608
    case MESSAGE_NO_OUTPUT:
609
      smcp.msg_lev = GLP_MSG_OFF;
610
      break;
611
    case MESSAGE_ERROR_MESSAGE:
612
      smcp.msg_lev = GLP_MSG_ERR;
613
      break;
614
    case MESSAGE_NORMAL_OUTPUT:
615
      smcp.msg_lev = GLP_MSG_ON;
616
      break;
617
    case MESSAGE_FULL_OUTPUT:
618
      smcp.msg_lev = GLP_MSG_ALL;
619
      break;
620
    }
614
    smcp.msg_lev = _message_level;
621 615
    smcp.meth = GLP_DUAL;
622 616
    smcp.presolve = _presolve;
623 617

	
624 618
    // If the basis is not valid we get an error return value.
625 619
    // In this case we can try to create a new basis.
626 620
    switch (glp_simplex(lp, &smcp)) {
627 621
    case 0:
628 622
      break;
629 623
    case GLP_EBADB:
630 624
    case GLP_ESING:
631 625
    case GLP_ECOND:
632 626
      glp_term_out(false);
633 627
      glp_adv_basis(lp, 0);
634 628
      glp_term_out(true);
635 629
      if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
636 630
      break;
637 631
    default:
638 632
      return UNSOLVED;
639 633
    }
640 634
    return SOLVED;
641 635
  }
642 636

	
643 637
  GlpkLp::Value GlpkLp::_getPrimal(int i) const {
644 638
    return glp_get_col_prim(lp, i);
... ...
@@ -837,142 +831,110 @@
837 831
    if (glp_get_status(lp) == GLP_OPT)
838 832
      return OPTIMAL;
839 833
    switch (glp_get_dual_stat(lp)) {
840 834
    case GLP_UNDEF:
841 835
      return UNDEFINED;
842 836
    case GLP_FEAS:
843 837
    case GLP_INFEAS:
844 838
      if (glp_get_prim_stat(lp) == GLP_NOFEAS) {
845 839
        return UNBOUNDED;
846 840
      } else {
847 841
        return UNDEFINED;
848 842
      }
849 843
    case GLP_NOFEAS:
850 844
      return INFEASIBLE;
851 845
    default:
852 846
      LEMON_ASSERT(false, "Wrong primal type");
853 847
      return  GlpkLp::ProblemType();
854 848
    }
855 849
  }
856 850

	
857 851
  void GlpkLp::presolver(bool presolve) {
858 852
    _presolve = presolve;
859 853
  }
860 854

	
861
  void GlpkLp::messageLevel(MessageLevel m) {
862
    _message_level = m;
863
  }
864

	
865 855
  // GlpkMip members
866 856

	
867 857
  GlpkMip::GlpkMip()
868 858
    : LpBase(), MipSolver(), GlpkBase() {
869
    messageLevel(MESSAGE_NO_OUTPUT);
870 859
  }
871 860

	
872 861
  GlpkMip::GlpkMip(const GlpkMip& other)
873 862
    : LpBase(), MipSolver(), GlpkBase(other) {
874
    messageLevel(MESSAGE_NO_OUTPUT);
875 863
  }
876 864

	
877 865
  void GlpkMip::_setColType(int i, GlpkMip::ColTypes col_type) {
878 866
    switch (col_type) {
879 867
    case INTEGER:
880 868
      glp_set_col_kind(lp, i, GLP_IV);
881 869
      break;
882 870
    case REAL:
883 871
      glp_set_col_kind(lp, i, GLP_CV);
884 872
      break;
885 873
    }
886 874
  }
887 875

	
888 876
  GlpkMip::ColTypes GlpkMip::_getColType(int i) const {
889 877
    switch (glp_get_col_kind(lp, i)) {
890 878
    case GLP_IV:
891 879
    case GLP_BV:
892 880
      return INTEGER;
893 881
    default:
894 882
      return REAL;
895 883
    }
896 884

	
897 885
  }
898 886

	
899 887
  GlpkMip::SolveExitStatus GlpkMip::_solve() {
900 888
    glp_smcp smcp;
901 889
    glp_init_smcp(&smcp);
902 890

	
903
    switch (_message_level) {
904
    case MESSAGE_NO_OUTPUT:
905
      smcp.msg_lev = GLP_MSG_OFF;
906
      break;
907
    case MESSAGE_ERROR_MESSAGE:
908
      smcp.msg_lev = GLP_MSG_ERR;
909
      break;
910
    case MESSAGE_NORMAL_OUTPUT:
911
      smcp.msg_lev = GLP_MSG_ON;
912
      break;
913
    case MESSAGE_FULL_OUTPUT:
914
      smcp.msg_lev = GLP_MSG_ALL;
915
      break;
916
    }
891
    smcp.msg_lev = _message_level;
917 892
    smcp.meth = GLP_DUAL;
918 893

	
919 894
    // If the basis is not valid we get an error return value.
920 895
    // In this case we can try to create a new basis.
921 896
    switch (glp_simplex(lp, &smcp)) {
922 897
    case 0:
923 898
      break;
924 899
    case GLP_EBADB:
925 900
    case GLP_ESING:
926 901
    case GLP_ECOND:
927 902
      glp_term_out(false);
928 903
      glp_adv_basis(lp, 0);
929 904
      glp_term_out(true);
930 905
      if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
931 906
      break;
932 907
    default:
933 908
      return UNSOLVED;
934 909
    }
935 910

	
936 911
    if (glp_get_status(lp) != GLP_OPT) return SOLVED;
937 912

	
938 913
    glp_iocp iocp;
939 914
    glp_init_iocp(&iocp);
940 915

	
941
    switch (_message_level) {
942
    case MESSAGE_NO_OUTPUT:
943
      iocp.msg_lev = GLP_MSG_OFF;
944
      break;
945
    case MESSAGE_ERROR_MESSAGE:
946
      iocp.msg_lev = GLP_MSG_ERR;
947
      break;
948
    case MESSAGE_NORMAL_OUTPUT:
949
      iocp.msg_lev = GLP_MSG_ON;
950
      break;
951
    case MESSAGE_FULL_OUTPUT:
952
      iocp.msg_lev = GLP_MSG_ALL;
953
      break;
954
    }
916
    iocp.msg_lev = _message_level;
955 917

	
956 918
    if (glp_intopt(lp, &iocp) != 0) return UNSOLVED;
957 919
    return SOLVED;
958 920
  }
959 921

	
960 922

	
961 923
  GlpkMip::ProblemType GlpkMip::_getType() const {
962 924
    switch (glp_get_status(lp)) {
963 925
    case GLP_OPT:
964 926
      switch (glp_mip_status(lp)) {
965 927
      case GLP_UNDEF:
966 928
        return UNDEFINED;
967 929
      case GLP_NOFEAS:
968 930
        return INFEASIBLE;
969 931
      case GLP_FEAS:
970 932
        return FEASIBLE;
971 933
      case GLP_OPT:
972 934
        return OPTIMAL;
973 935
      default:
974 936
        LEMON_ASSERT(false, "Wrong problem type.");
975 937
        return GlpkMip::ProblemType();
976 938
      }
977 939
    case GLP_NOFEAS:
978 940
      return INFEASIBLE;
... ...
@@ -981,29 +943,25 @@
981 943
      if (glp_get_dual_stat(lp) == GLP_NOFEAS) {
982 944
        return UNBOUNDED;
983 945
      } else {
984 946
        return UNDEFINED;
985 947
      }
986 948
    default:
987 949
      LEMON_ASSERT(false, "Wrong problem type.");
988 950
      return GlpkMip::ProblemType();
989 951
    }
990 952
  }
991 953

	
992 954
  GlpkMip::Value GlpkMip::_getSol(int i) const {
993 955
    return glp_mip_col_val(lp, i);
994 956
  }
995 957

	
996 958
  GlpkMip::Value GlpkMip::_getSolValue() const {
997 959
    return glp_mip_obj_val(lp);
998 960
  }
999 961

	
1000 962
  GlpkMip* GlpkMip::newSolver() const { return new GlpkMip; }
1001 963
  GlpkMip* GlpkMip::cloneSolver() const {return new GlpkMip(*this); }
1002 964

	
1003 965
  const char* GlpkMip::_solverName() const { return "GlpkMip"; }
1004 966

	
1005
  void GlpkMip::messageLevel(MessageLevel m) {
1006
    _message_level = m;
1007
  }
1008

	
1009 967
} //END OF NAMESPACE LEMON
Ignore white space 48 line context
... ...
@@ -79,59 +79,65 @@
79 79

	
80 80
    virtual void _setColLowerBound(int i, Value value);
81 81
    virtual Value _getColLowerBound(int i) const;
82 82

	
83 83
    virtual void _setColUpperBound(int i, Value value);
84 84
    virtual Value _getColUpperBound(int i) const;
85 85

	
86 86
    virtual void _setRowLowerBound(int i, Value value);
87 87
    virtual Value _getRowLowerBound(int i) const;
88 88

	
89 89
    virtual void _setRowUpperBound(int i, Value value);
90 90
    virtual Value _getRowUpperBound(int i) const;
91 91

	
92 92
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
93 93
    virtual void _getObjCoeffs(InsertIterator b) const;
94 94

	
95 95
    virtual void _setObjCoeff(int i, Value obj_coef);
96 96
    virtual Value _getObjCoeff(int i) const;
97 97

	
98 98
    virtual void _setSense(Sense);
99 99
    virtual Sense _getSense() const;
100 100

	
101 101
    virtual void _clear();
102 102

	
103
    virtual void _messageLevel(MessageLevel level);
104

	
103 105
  private:
104 106

	
105 107
    static void freeEnv();
106 108

	
107 109
    struct FreeEnvHelper {
108 110
      ~FreeEnvHelper() {
109 111
        freeEnv();
110 112
      }
111 113
    };
112 114
    
113 115
    static FreeEnvHelper freeEnvHelper;
116

	
117
  protected:
118
    
119
    int _message_level;
114 120
    
115 121
  public:
116 122

	
117 123
    ///Pointer to the underlying GLPK data structure.
118 124
    LPX *lpx() {return lp;}
119 125
    ///Const pointer to the underlying GLPK data structure.
120 126
    const LPX *lpx() const {return lp;}
121 127

	
122 128
    ///Returns the constraint identifier understood by GLPK.
123 129
    int lpxRow(Row r) const { return rows(id(r)); }
124 130

	
125 131
    ///Returns the variable identifier understood by GLPK.
126 132
    int lpxCol(Col c) const { return cols(id(c)); }
127 133

	
128 134
  };
129 135

	
130 136
  /// \brief Interface for the GLPK LP solver
131 137
  ///
132 138
  /// This class implements an interface for the GLPK LP solver.
133 139
  ///\ingroup lp_group
134 140
  class GlpkLp : public LpSolver, public GlpkBase {
135 141
  public:
136 142

	
137 143
    ///\e
... ...
@@ -170,108 +176,60 @@
170 176
    virtual ProblemType _getPrimalType() const;
171 177
    virtual ProblemType _getDualType() const;
172 178

	
173 179
  public:
174 180

	
175 181
    ///Solve with primal simplex
176 182
    SolveExitStatus solvePrimal();
177 183

	
178 184
    ///Solve with dual simplex
179 185
    SolveExitStatus solveDual();
180 186

	
181 187
  private:
182 188

	
183 189
    bool _presolve;
184 190

	
185 191
  public:
186 192

	
187 193
    ///Turns on or off the presolver
188 194

	
189 195
    ///Turns on (\c b is \c true) or off (\c b is \c false) the presolver
190 196
    ///
191 197
    ///The presolver is off by default.
192 198
    void presolver(bool presolve);
193 199

	
194
    ///Enum for \c messageLevel() parameter
195
    enum MessageLevel {
196
      /// no output (default value)
197
      MESSAGE_NO_OUTPUT = 0,
198
      /// error messages only
199
      MESSAGE_ERROR_MESSAGE = 1,
200
      /// normal output
201
      MESSAGE_NORMAL_OUTPUT = 2,
202
      /// full output (includes informational messages)
203
      MESSAGE_FULL_OUTPUT = 3
204
    };
205

	
206
  private:
207

	
208
    MessageLevel _message_level;
209

	
210
  public:
211

	
212
    ///Set the verbosity of the messages
213

	
214
    ///Set the verbosity of the messages
215
    ///
216
    ///\param m is the level of the messages output by the solver routines.
217
    void messageLevel(MessageLevel m);
218 200
  };
219 201

	
220 202
  /// \brief Interface for the GLPK MIP solver
221 203
  ///
222 204
  /// This class implements an interface for the GLPK MIP solver.
223 205
  ///\ingroup lp_group
224 206
  class GlpkMip : public MipSolver, public GlpkBase {
225 207
  public:
226 208

	
227 209
    ///\e
228 210
    GlpkMip();
229 211
    ///\e
230 212
    GlpkMip(const GlpkMip&);
231 213

	
232 214
    virtual GlpkMip* cloneSolver() const;
233 215
    virtual GlpkMip* newSolver() const;
234 216

	
235 217
  protected:
236 218

	
237 219
    virtual const char* _solverName() const;
238 220

	
239 221
    virtual ColTypes _getColType(int col) const;
240 222
    virtual void _setColType(int col, ColTypes col_type);
241 223

	
242 224
    virtual SolveExitStatus _solve();
243 225
    virtual ProblemType _getType() const;
244 226
    virtual Value _getSol(int i) const;
245 227
    virtual Value _getSolValue() const;
246 228

	
247
    ///Enum for \c messageLevel() parameter
248
    enum MessageLevel {
249
      /// no output (default value)
250
      MESSAGE_NO_OUTPUT = 0,
251
      /// error messages only
252
      MESSAGE_ERROR_MESSAGE = 1,
253
      /// normal output
254
      MESSAGE_NORMAL_OUTPUT = 2,
255
      /// full output (includes informational messages)
256
      MESSAGE_FULL_OUTPUT = 3
257
    };
258

	
259
  private:
260

	
261
    MessageLevel _message_level;
262

	
263
  public:
264

	
265
    ///Set the verbosity of the messages
266

	
267
    ///Set the verbosity of the messages
268
    ///
269
    ///\param m is the level of the messages output by the solver routines.
270
    void messageLevel(MessageLevel m);
271 229
  };
272 230

	
273 231

	
274 232
} //END OF NAMESPACE LEMON
275 233

	
276 234
#endif //LEMON_GLPK_H
277 235

	
Ignore white space 48 line context
... ...
@@ -48,48 +48,63 @@
48 48
    _solver_bits::VarIndex rows;
49 49
    _solver_bits::VarIndex cols;
50 50

	
51 51
  public:
52 52

	
53 53
    ///Possible outcomes of an LP solving procedure
54 54
    enum SolveExitStatus {
55 55
      ///This means that the problem has been successfully solved: either
56 56
      ///an optimal solution has been found or infeasibility/unboundedness
57 57
      ///has been proved.
58 58
      SOLVED = 0,
59 59
      ///Any other case (including the case when some user specified
60 60
      ///limit has been exceeded)
61 61
      UNSOLVED = 1
62 62
    };
63 63

	
64 64
    ///Direction of the optimization
65 65
    enum Sense {
66 66
      /// Minimization
67 67
      MIN,
68 68
      /// Maximization
69 69
      MAX
70 70
    };
71 71

	
72
    ///Enum for \c messageLevel() parameter
73
    enum MessageLevel {
74
      /// no output (default value)
75
      MESSAGE_NOTHING,
76
      /// error messages only
77
      MESSAGE_ERROR,
78
      /// warnings
79
      MESSAGE_WARNING,
80
      /// normal output
81
      MESSAGE_NORMAL,
82
      /// verbose output
83
      MESSAGE_VERBOSE
84
    };
85
    
86

	
72 87
    ///The floating point type used by the solver
73 88
    typedef double Value;
74 89
    ///The infinity constant
75 90
    static const Value INF;
76 91
    ///The not a number constant
77 92
    static const Value NaN;
78 93

	
79 94
    friend class Col;
80 95
    friend class ColIt;
81 96
    friend class Row;
82 97
    friend class RowIt;
83 98

	
84 99
    ///Refer to a column of the LP.
85 100

	
86 101
    ///This type is used to refer to a column of the LP.
87 102
    ///
88 103
    ///Its value remains valid and correct even after the addition or erase of
89 104
    ///other columns.
90 105
    ///
91 106
    ///\note This class is similar to other Item types in LEMON, like
92 107
    ///Node and Arc types in digraph.
93 108
    class Col {
94 109
      friend class LpBase;
95 110
    protected:
... ...
@@ -952,48 +967,50 @@
952 967
    virtual Value _getColLowerBound(int i) const = 0;
953 968

	
954 969
    virtual void _setColUpperBound(int i, Value value) = 0;
955 970
    virtual Value _getColUpperBound(int i) const = 0;
956 971

	
957 972
    virtual void _setRowLowerBound(int i, Value value) = 0;
958 973
    virtual Value _getRowLowerBound(int i) const = 0;
959 974

	
960 975
    virtual void _setRowUpperBound(int i, Value value) = 0;
961 976
    virtual Value _getRowUpperBound(int i) const = 0;
962 977

	
963 978
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e) = 0;
964 979
    virtual void _getObjCoeffs(InsertIterator b) const = 0;
965 980

	
966 981
    virtual void _setObjCoeff(int i, Value obj_coef) = 0;
967 982
    virtual Value _getObjCoeff(int i) const = 0;
968 983

	
969 984
    virtual void _setSense(Sense) = 0;
970 985
    virtual Sense _getSense() const = 0;
971 986

	
972 987
    virtual void _clear() = 0;
973 988

	
974 989
    virtual const char* _solverName() const = 0;
975 990

	
991
    virtual void _messageLevel(MessageLevel level) = 0;
992

	
976 993
    //Own protected stuff
977 994

	
978 995
    //Constant component of the objective function
979 996
    Value obj_const_comp;
980 997

	
981 998
    LpBase() : rows(), cols(), obj_const_comp(0) {}
982 999

	
983 1000
  public:
984 1001

	
985 1002
    /// Virtual destructor
986 1003
    virtual ~LpBase() {}
987 1004

	
988 1005
    ///Gives back the name of the solver.
989 1006
    const char* solverName() const {return _solverName();}
990 1007

	
991 1008
    ///\name Build up and modify the LP
992 1009

	
993 1010
    ///@{
994 1011

	
995 1012
    ///Add a new empty column (i.e a new variable) to the LP
996 1013
    Col addCol() { Col c; c._id = _addColId(_addCol()); return c;}
997 1014

	
998 1015
    ///\brief Adds several new columns (i.e variables) at once
999 1016
    ///
... ...
@@ -1506,48 +1523,51 @@
1506 1523
    ///Expr.
1507 1524
    Expr obj() const {
1508 1525
      Expr e;
1509 1526
      _getObjCoeffs(InsertIterator(e.comps, cols));
1510 1527
      *e = obj_const_comp;
1511 1528
      return e;
1512 1529
    }
1513 1530

	
1514 1531

	
1515 1532
    ///Set the direction of optimization
1516 1533
    void sense(Sense sense) { _setSense(sense); }
1517 1534

	
1518 1535
    ///Query the direction of the optimization
1519 1536
    Sense sense() const {return _getSense(); }
1520 1537

	
1521 1538
    ///Set the sense to maximization
1522 1539
    void max() { _setSense(MAX); }
1523 1540

	
1524 1541
    ///Set the sense to maximization
1525 1542
    void min() { _setSense(MIN); }
1526 1543

	
1527 1544
    ///Clears the problem
1528 1545
    void clear() { _clear(); }
1529 1546

	
1547
    /// Sets the message level of the solver
1548
    void messageLevel(MessageLevel level) { _messageLevel(level); }
1549

	
1530 1550
    ///@}
1531 1551

	
1532 1552
  };
1533 1553

	
1534 1554
  /// Addition
1535 1555

	
1536 1556
  ///\relates LpBase::Expr
1537 1557
  ///
1538 1558
  inline LpBase::Expr operator+(const LpBase::Expr &a, const LpBase::Expr &b) {
1539 1559
    LpBase::Expr tmp(a);
1540 1560
    tmp+=b;
1541 1561
    return tmp;
1542 1562
  }
1543 1563
  ///Substraction
1544 1564

	
1545 1565
  ///\relates LpBase::Expr
1546 1566
  ///
1547 1567
  inline LpBase::Expr operator-(const LpBase::Expr &a, const LpBase::Expr &b) {
1548 1568
    LpBase::Expr tmp(a);
1549 1569
    tmp-=b;
1550 1570
    return tmp;
1551 1571
  }
1552 1572
  ///Multiply with constant
1553 1573

	
Ignore white space 48 line context
... ...
@@ -63,48 +63,50 @@
63 63

	
64 64
  void SkeletonSolverBase::_setRowLowerBound(int, Value) {}
65 65
  SkeletonSolverBase::Value SkeletonSolverBase::_getRowLowerBound(int) const
66 66
  {  return 0; }
67 67

	
68 68
  void SkeletonSolverBase::_setRowUpperBound(int, Value) {}
69 69
  SkeletonSolverBase::Value SkeletonSolverBase::_getRowUpperBound(int) const
70 70
  {  return 0; }
71 71

	
72 72
  void SkeletonSolverBase::_setObjCoeffs(ExprIterator, ExprIterator) {}
73 73
  void SkeletonSolverBase::_getObjCoeffs(InsertIterator) const {};
74 74

	
75 75
  void SkeletonSolverBase::_setObjCoeff(int, Value) {}
76 76
  SkeletonSolverBase::Value SkeletonSolverBase::_getObjCoeff(int) const
77 77
  {  return 0; }
78 78

	
79 79
  void SkeletonSolverBase::_setSense(Sense) {}
80 80
  SkeletonSolverBase::Sense SkeletonSolverBase::_getSense() const
81 81
  { return MIN; }
82 82

	
83 83
  void SkeletonSolverBase::_clear() {
84 84
    row_num = col_num = 0;
85 85
  }
86 86

	
87
  void SkeletonSolverBase::_messageLevel(MessageLevel) {}
88

	
87 89
  LpSkeleton::SolveExitStatus LpSkeleton::_solve() { return SOLVED; }
88 90

	
89 91
  LpSkeleton::Value LpSkeleton::_getPrimal(int) const { return 0; }
90 92
  LpSkeleton::Value LpSkeleton::_getDual(int) const { return 0; }
91 93
  LpSkeleton::Value LpSkeleton::_getPrimalValue() const { return 0; }
92 94

	
93 95
  LpSkeleton::Value LpSkeleton::_getPrimalRay(int) const { return 0; }
94 96
  LpSkeleton::Value LpSkeleton::_getDualRay(int) const { return 0; }
95 97

	
96 98
  LpSkeleton::ProblemType LpSkeleton::_getPrimalType() const
97 99
  { return UNDEFINED; }
98 100

	
99 101
  LpSkeleton::ProblemType LpSkeleton::_getDualType() const
100 102
  { return UNDEFINED; }
101 103

	
102 104
  LpSkeleton::VarStatus LpSkeleton::_getColStatus(int) const
103 105
  { return BASIC; }
104 106

	
105 107
  LpSkeleton::VarStatus LpSkeleton::_getRowStatus(int) const
106 108
  { return BASIC; }
107 109

	
108 110
  LpSkeleton* LpSkeleton::newSolver() const
109 111
  { return static_cast<LpSkeleton*>(0); }
110 112

	
Ignore white space 48 line context
... ...
@@ -119,48 +119,50 @@
119 119

	
120 120
    /// The upper bound of a constraint (row) is an
121 121
    /// extended number of type Value, i.e. a finite number of type
122 122
    /// Value or \ref INF.
123 123
    virtual Value _getRowUpperBound(int i) const;
124 124

	
125 125
    /// \e
126 126
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
127 127
    /// \e
128 128
    virtual void _getObjCoeffs(InsertIterator b) const;
129 129

	
130 130
    /// \e
131 131
    virtual void _setObjCoeff(int i, Value obj_coef);
132 132
    /// \e
133 133
    virtual Value _getObjCoeff(int i) const;
134 134

	
135 135
    ///\e
136 136
    virtual void _setSense(Sense);
137 137
    ///\e
138 138
    virtual Sense _getSense() const;
139 139

	
140 140
    ///\e
141 141
    virtual void _clear();
142 142

	
143
    ///\e
144
    virtual void _messageLevel(MessageLevel);
143 145
  };
144 146

	
145 147
  /// \brief Skeleton class for an LP solver interface
146 148
  ///
147 149
  ///This class does nothing, but it can serve as a skeleton when
148 150
  ///implementing an interface to new solvers.
149 151

	
150 152
  ///\ingroup lp_group
151 153
  class LpSkeleton : public LpSolver, public SkeletonSolverBase {
152 154
  public:
153 155
    ///\e
154 156
    LpSkeleton() : LpSolver(), SkeletonSolverBase() {}
155 157
    ///\e
156 158
    virtual LpSkeleton* newSolver() const;
157 159
    ///\e
158 160
    virtual LpSkeleton* cloneSolver() const;
159 161
  protected:
160 162

	
161 163
    ///\e
162 164
    virtual SolveExitStatus _solve();
163 165

	
164 166
    ///\e
165 167
    virtual Value _getPrimal(int i) const;
166 168
    ///\e
Ignore white space 48 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <iostream>
20 20
#include <lemon/soplex.h>
21 21

	
22 22
#include <soplex.h>
23
#include <spxout.h>
23 24

	
24 25

	
25 26
///\file
26 27
///\brief Implementation of the LEMON-SOPLEX lp solver interface.
27 28
namespace lemon {
28 29

	
29 30
  SoplexLp::SoplexLp() {
30 31
    soplex = new soplex::SoPlex;
32
    messageLevel(MESSAGE_NOTHING);
31 33
  }
32 34

	
33 35
  SoplexLp::~SoplexLp() {
34 36
    delete soplex;
35 37
  }
36 38

	
37 39
  SoplexLp::SoplexLp(const SoplexLp& lp) {
38 40
    rows = lp.rows;
39 41
    cols = lp.cols;
40 42

	
41 43
    soplex = new soplex::SoPlex;
42 44
    (*static_cast<soplex::SPxLP*>(soplex)) = *(lp.soplex);
43 45

	
44 46
    _col_names = lp._col_names;
45 47
    _col_names_ref = lp._col_names_ref;
46 48

	
47 49
    _row_names = lp._row_names;
48 50
    _row_names_ref = lp._row_names_ref;
49 51

	
52
    messageLevel(MESSAGE_NOTHING);
50 53
  }
51 54

	
52 55
  void SoplexLp::_clear_temporals() {
53 56
    _primal_values.clear();
54 57
    _dual_values.clear();
55 58
  }
56 59

	
57 60
  SoplexLp* SoplexLp::newSolver() const {
58 61
    SoplexLp* newlp = new SoplexLp();
59 62
    return newlp;
60 63
  }
61 64

	
62 65
  SoplexLp* SoplexLp::cloneSolver() const {
63 66
    SoplexLp* newlp = new SoplexLp(*this);
64 67
    return newlp;
65 68
  }
66 69

	
67 70
  const char* SoplexLp::_solverName() const { return "SoplexLp"; }
68 71

	
69 72
  int SoplexLp::_addCol() {
70 73
    soplex::LPCol c;
71 74
    c.setLower(-soplex::infinity);
72 75
    c.setUpper(soplex::infinity);
73 76
    soplex->addCol(c);
... ...
@@ -250,48 +253,50 @@
250 253
    }
251 254
  }
252 255

	
253 256
  void SoplexLp::_getObjCoeffs(InsertIterator b) const {
254 257
    for (int j = 0; j < soplex->nCols(); ++j) {
255 258
      Value coef = soplex->obj(j);
256 259
      if (coef != 0.0) {
257 260
        *b = std::make_pair(j, coef);
258 261
        ++b;
259 262
      }
260 263
    }
261 264
  }
262 265

	
263 266
  void SoplexLp::_setObjCoeff(int i, Value obj_coef) {
264 267
    soplex->changeObj(i, obj_coef);
265 268
  }
266 269

	
267 270
  SoplexLp::Value SoplexLp::_getObjCoeff(int i) const {
268 271
    return soplex->obj(i);
269 272
  }
270 273

	
271 274
  SoplexLp::SolveExitStatus SoplexLp::_solve() {
272 275

	
273 276
    _clear_temporals();
277
    
278
    _applyMessageLevel();
274 279

	
275 280
    soplex::SPxSolver::Status status = soplex->solve();
276 281

	
277 282
    switch (status) {
278 283
    case soplex::SPxSolver::OPTIMAL:
279 284
    case soplex::SPxSolver::INFEASIBLE:
280 285
    case soplex::SPxSolver::UNBOUNDED:
281 286
      return SOLVED;
282 287
    default:
283 288
      return UNSOLVED;
284 289
    }
285 290
  }
286 291

	
287 292
  SoplexLp::Value SoplexLp::_getPrimal(int i) const {
288 293
    if (_primal_values.empty()) {
289 294
      _primal_values.resize(soplex->nCols());
290 295
      soplex::Vector pv(_primal_values.size(), &_primal_values.front());
291 296
      soplex->getPrimal(pv);
292 297
    }
293 298
    return _primal_values[i];
294 299
  }
295 300

	
296 301
  SoplexLp::Value SoplexLp::_getDual(int i) const {
297 302
    if (_dual_values.empty()) {
... ...
@@ -398,26 +403,50 @@
398 403

	
399 404
  SoplexLp::Sense SoplexLp::_getSense() const {
400 405
    switch (soplex->spxSense()) {
401 406
    case soplex::SPxSolver::MAXIMIZE:
402 407
      return MAX;
403 408
    case soplex::SPxSolver::MINIMIZE:
404 409
      return MIN;
405 410
    default:
406 411
      LEMON_ASSERT(false, "Wrong sense.");
407 412
      return SoplexLp::Sense();
408 413
    }
409 414
  }
410 415

	
411 416
  void SoplexLp::_clear() {
412 417
    soplex->clear();
413 418
    _col_names.clear();
414 419
    _col_names_ref.clear();
415 420
    _row_names.clear();
416 421
    _row_names_ref.clear();
417 422
    cols.clear();
418 423
    rows.clear();
419 424
    _clear_temporals();
420 425
  }
421 426

	
427
  void SoplexLp::_messageLevel(MessageLevel level) {
428
    switch (level) {
429
    case MESSAGE_NOTHING:
430
      _message_level = -1;
431
      break;
432
    case MESSAGE_ERROR:
433
      _message_level = soplex::SPxOut::ERROR;
434
      break;
435
    case MESSAGE_WARNING:
436
      _message_level = soplex::SPxOut::WARNING;
437
      break;
438
    case MESSAGE_NORMAL:
439
      _message_level = soplex::SPxOut::INFO2;
440
      break;
441
    case MESSAGE_VERBOSE:
442
      _message_level = soplex::SPxOut::DEBUG;
443
      break;
444
    }
445
  }
446

	
447
  void SoplexLp::_applyMessageLevel() {
448
    soplex::Param::setVerbose(_message_level);
449
  }
450

	
422 451
} //namespace lemon
423 452

	
Ignore white space 48 line context
... ...
@@ -123,30 +123,35 @@
123 123

	
124 124
    virtual void _setObjCoeff(int i, Value obj_coef);
125 125
    virtual Value _getObjCoeff(int i) const;
126 126

	
127 127
    virtual void _setSense(Sense sense);
128 128
    virtual Sense _getSense() const;
129 129

	
130 130
    virtual SolveExitStatus _solve();
131 131
    virtual Value _getPrimal(int i) const;
132 132
    virtual Value _getDual(int i) const;
133 133

	
134 134
    virtual Value _getPrimalValue() const;
135 135

	
136 136
    virtual Value _getPrimalRay(int i) const;
137 137
    virtual Value _getDualRay(int i) const;
138 138

	
139 139
    virtual VarStatus _getColStatus(int i) const;
140 140
    virtual VarStatus _getRowStatus(int i) const;
141 141

	
142 142
    virtual ProblemType _getPrimalType() const;
143 143
    virtual ProblemType _getDualType() const;
144 144

	
145 145
    virtual void _clear();
146 146

	
147
    void _messageLevel(MessageLevel m);
148
    void _applyMessageLevel();
149

	
150
    int _message_level;
151

	
147 152
  };
148 153

	
149 154
} //END OF NAMESPACE LEMON
150 155

	
151 156
#endif //LEMON_SOPLEX_H
152 157

	
0 comments (0 inline)