lemon/clp.cc
author Peter Kovacs <kpeter@inf.elte.hu>
Thu, 12 Nov 2009 23:26:13 +0100
changeset 806 fa6f37d7a25b
parent 576 745e182d0139
child 877 141f9c0db4a3
permissions -rw-r--r--
Entirely rework CapacityScaling (#180)

- Use the new interface similarly to NetworkSimplex.
- Rework the implementation using an efficient internal structure
for handling the residual network. This improvement made the
code much faster (up to 2-5 times faster on large graphs).
- Handle GEQ supply type (LEQ is not supported).
- Handle negative costs for arcs of finite capacity.
(Note that this algorithm cannot handle arcs of negative cost
and infinite upper bound, thus it returns UNBOUNDED if such
an arc exists.)
- Extend the documentation.
alpar@461
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
alpar@461
     2
 *
alpar@461
     3
 * This file is a part of LEMON, a generic C++ optimization library.
alpar@461
     4
 *
alpar@461
     5
 * Copyright (C) 2003-2008
alpar@461
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@461
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@461
     8
 *
alpar@461
     9
 * Permission to use, modify and distribute this software is granted
alpar@461
    10
 * provided that this copyright notice appears in all copies. For
alpar@461
    11
 * precise terms see the accompanying LICENSE file.
alpar@461
    12
 *
alpar@461
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@461
    14
 * express or implied, and with no claim as to its suitability for any
alpar@461
    15
 * purpose.
alpar@461
    16
 *
alpar@461
    17
 */
alpar@461
    18
alpar@461
    19
#include <lemon/clp.h>
alpar@461
    20
#include <coin/ClpSimplex.hpp>
alpar@461
    21
alpar@461
    22
namespace lemon {
alpar@461
    23
alpar@462
    24
  ClpLp::ClpLp() {
alpar@461
    25
    _prob = new ClpSimplex();
alpar@461
    26
    _init_temporals();
deba@576
    27
    messageLevel(MESSAGE_NOTHING);
alpar@461
    28
  }
alpar@461
    29
alpar@462
    30
  ClpLp::ClpLp(const ClpLp& other) {
alpar@461
    31
    _prob = new ClpSimplex(*other._prob);
alpar@461
    32
    rows = other.rows;
alpar@461
    33
    cols = other.cols;
alpar@461
    34
    _init_temporals();
deba@576
    35
    messageLevel(MESSAGE_NOTHING);
alpar@461
    36
  }
alpar@461
    37
alpar@462
    38
  ClpLp::~ClpLp() {
alpar@461
    39
    delete _prob;
alpar@461
    40
    _clear_temporals();
alpar@461
    41
  }
alpar@461
    42
alpar@462
    43
  void ClpLp::_init_temporals() {
alpar@461
    44
    _primal_ray = 0;
alpar@461
    45
    _dual_ray = 0;
alpar@461
    46
  }
alpar@461
    47
alpar@462
    48
  void ClpLp::_clear_temporals() {
alpar@461
    49
    if (_primal_ray) {
alpar@461
    50
      delete[] _primal_ray;
alpar@461
    51
      _primal_ray = 0;
alpar@461
    52
    }
alpar@461
    53
    if (_dual_ray) {
alpar@461
    54
      delete[] _dual_ray;
alpar@461
    55
      _dual_ray = 0;
alpar@461
    56
    }
alpar@461
    57
  }
alpar@461
    58
alpar@540
    59
  ClpLp* ClpLp::newSolver() const {
alpar@462
    60
    ClpLp* newlp = new ClpLp;
alpar@461
    61
    return newlp;
alpar@461
    62
  }
alpar@461
    63
alpar@540
    64
  ClpLp* ClpLp::cloneSolver() const {
alpar@462
    65
    ClpLp* copylp = new ClpLp(*this);
alpar@461
    66
    return copylp;
alpar@461
    67
  }
alpar@461
    68
alpar@462
    69
  const char* ClpLp::_solverName() const { return "ClpLp"; }
alpar@461
    70
alpar@462
    71
  int ClpLp::_addCol() {
alpar@461
    72
    _prob->addColumn(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX, 0.0);
alpar@461
    73
    return _prob->numberColumns() - 1;
alpar@461
    74
  }
alpar@461
    75
alpar@462
    76
  int ClpLp::_addRow() {
alpar@461
    77
    _prob->addRow(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX);
alpar@461
    78
    return _prob->numberRows() - 1;
alpar@461
    79
  }
alpar@461
    80
deba@746
    81
  int ClpLp::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
deba@746
    82
    std::vector<int> indexes;
deba@746
    83
    std::vector<Value> values;
deba@746
    84
deba@746
    85
    for(ExprIterator it = b; it != e; ++it) {
deba@746
    86
      indexes.push_back(it->first);
deba@746
    87
      values.push_back(it->second);
deba@746
    88
    }
deba@746
    89
deba@746
    90
    _prob->addRow(values.size(), &indexes.front(), &values.front(), l, u);
deba@746
    91
    return _prob->numberRows() - 1;
deba@746
    92
  }
deba@746
    93
alpar@461
    94
alpar@462
    95
  void ClpLp::_eraseCol(int c) {
alpar@461
    96
    _col_names_ref.erase(_prob->getColumnName(c));
alpar@461
    97
    _prob->deleteColumns(1, &c);
alpar@461
    98
  }
alpar@461
    99
alpar@462
   100
  void ClpLp::_eraseRow(int r) {
alpar@461
   101
    _row_names_ref.erase(_prob->getRowName(r));
alpar@461
   102
    _prob->deleteRows(1, &r);
alpar@461
   103
  }
alpar@461
   104
alpar@462
   105
  void ClpLp::_eraseColId(int i) {
alpar@461
   106
    cols.eraseIndex(i);
alpar@461
   107
    cols.shiftIndices(i);
alpar@461
   108
  }
alpar@461
   109
alpar@462
   110
  void ClpLp::_eraseRowId(int i) {
alpar@461
   111
    rows.eraseIndex(i);
alpar@461
   112
    rows.shiftIndices(i);
alpar@461
   113
  }
alpar@461
   114
alpar@462
   115
  void ClpLp::_getColName(int c, std::string& name) const {
alpar@461
   116
    name = _prob->getColumnName(c);
alpar@461
   117
  }
alpar@461
   118
alpar@462
   119
  void ClpLp::_setColName(int c, const std::string& name) {
alpar@461
   120
    _prob->setColumnName(c, const_cast<std::string&>(name));
alpar@461
   121
    _col_names_ref[name] = c;
alpar@461
   122
  }
alpar@461
   123
alpar@462
   124
  int ClpLp::_colByName(const std::string& name) const {
alpar@461
   125
    std::map<std::string, int>::const_iterator it = _col_names_ref.find(name);
alpar@461
   126
    return it != _col_names_ref.end() ? it->second : -1;
alpar@461
   127
  }
alpar@461
   128
alpar@462
   129
  void ClpLp::_getRowName(int r, std::string& name) const {
alpar@461
   130
    name = _prob->getRowName(r);
alpar@461
   131
  }
alpar@461
   132
alpar@462
   133
  void ClpLp::_setRowName(int r, const std::string& name) {
alpar@461
   134
    _prob->setRowName(r, const_cast<std::string&>(name));
alpar@461
   135
    _row_names_ref[name] = r;
alpar@461
   136
  }
alpar@461
   137
alpar@462
   138
  int ClpLp::_rowByName(const std::string& name) const {
alpar@461
   139
    std::map<std::string, int>::const_iterator it = _row_names_ref.find(name);
alpar@461
   140
    return it != _row_names_ref.end() ? it->second : -1;
alpar@461
   141
  }
alpar@461
   142
alpar@461
   143
alpar@462
   144
  void ClpLp::_setRowCoeffs(int ix, ExprIterator b, ExprIterator e) {
alpar@461
   145
    std::map<int, Value> coeffs;
alpar@461
   146
alpar@461
   147
    int n = _prob->clpMatrix()->getNumCols();
alpar@461
   148
alpar@461
   149
    const int* indices = _prob->clpMatrix()->getIndices();
alpar@461
   150
    const double* elements = _prob->clpMatrix()->getElements();
alpar@461
   151
alpar@461
   152
    for (int i = 0; i < n; ++i) {
alpar@461
   153
      CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[i];
alpar@461
   154
      CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[i];
alpar@461
   155
alpar@461
   156
      const int* it = std::lower_bound(indices + begin, indices + end, ix);
alpar@461
   157
      if (it != indices + end && *it == ix && elements[it - indices] != 0.0) {
alpar@461
   158
        coeffs[i] = 0.0;
alpar@461
   159
      }
alpar@461
   160
    }
alpar@461
   161
alpar@461
   162
    for (ExprIterator it = b; it != e; ++it) {
alpar@461
   163
      coeffs[it->first] = it->second;
alpar@461
   164
    }
alpar@461
   165
alpar@461
   166
    for (std::map<int, Value>::iterator it = coeffs.begin();
alpar@461
   167
         it != coeffs.end(); ++it) {
alpar@461
   168
      _prob->modifyCoefficient(ix, it->first, it->second);
alpar@461
   169
    }
alpar@461
   170
  }
alpar@461
   171
alpar@462
   172
  void ClpLp::_getRowCoeffs(int ix, InsertIterator b) const {
alpar@461
   173
    int n = _prob->clpMatrix()->getNumCols();
alpar@461
   174
alpar@461
   175
    const int* indices = _prob->clpMatrix()->getIndices();
alpar@461
   176
    const double* elements = _prob->clpMatrix()->getElements();
alpar@461
   177
alpar@461
   178
    for (int i = 0; i < n; ++i) {
alpar@461
   179
      CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[i];
alpar@461
   180
      CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[i];
alpar@461
   181
alpar@461
   182
      const int* it = std::lower_bound(indices + begin, indices + end, ix);
alpar@461
   183
      if (it != indices + end && *it == ix) {
alpar@461
   184
        *b = std::make_pair(i, elements[it - indices]);
alpar@461
   185
      }
alpar@461
   186
    }
alpar@461
   187
  }
alpar@461
   188
alpar@462
   189
  void ClpLp::_setColCoeffs(int ix, ExprIterator b, ExprIterator e) {
alpar@461
   190
    std::map<int, Value> coeffs;
alpar@461
   191
alpar@461
   192
    CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix];
alpar@461
   193
    CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix];
alpar@461
   194
alpar@461
   195
    const int* indices = _prob->clpMatrix()->getIndices();
alpar@461
   196
    const double* elements = _prob->clpMatrix()->getElements();
alpar@461
   197
alpar@461
   198
    for (CoinBigIndex i = begin; i != end; ++i) {
alpar@461
   199
      if (elements[i] != 0.0) {
alpar@461
   200
        coeffs[indices[i]] = 0.0;
alpar@461
   201
      }
alpar@461
   202
    }
alpar@461
   203
    for (ExprIterator it = b; it != e; ++it) {
alpar@461
   204
      coeffs[it->first] = it->second;
alpar@461
   205
    }
alpar@461
   206
    for (std::map<int, Value>::iterator it = coeffs.begin();
alpar@461
   207
         it != coeffs.end(); ++it) {
alpar@461
   208
      _prob->modifyCoefficient(it->first, ix, it->second);
alpar@461
   209
    }
alpar@461
   210
  }
alpar@461
   211
alpar@462
   212
  void ClpLp::_getColCoeffs(int ix, InsertIterator b) const {
alpar@461
   213
    CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix];
alpar@461
   214
    CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix];
alpar@461
   215
alpar@461
   216
    const int* indices = _prob->clpMatrix()->getIndices();
alpar@461
   217
    const double* elements = _prob->clpMatrix()->getElements();
alpar@461
   218
alpar@461
   219
    for (CoinBigIndex i = begin; i != end; ++i) {
alpar@461
   220
      *b = std::make_pair(indices[i], elements[i]);
alpar@461
   221
      ++b;
alpar@461
   222
    }
alpar@461
   223
  }
alpar@461
   224
alpar@462
   225
  void ClpLp::_setCoeff(int ix, int jx, Value value) {
alpar@461
   226
    _prob->modifyCoefficient(ix, jx, value);
alpar@461
   227
  }
alpar@461
   228
alpar@462
   229
  ClpLp::Value ClpLp::_getCoeff(int ix, int jx) const {
alpar@461
   230
    CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix];
alpar@461
   231
    CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix];
alpar@461
   232
alpar@461
   233
    const int* indices = _prob->clpMatrix()->getIndices();
alpar@461
   234
    const double* elements = _prob->clpMatrix()->getElements();
alpar@461
   235
alpar@461
   236
    const int* it = std::lower_bound(indices + begin, indices + end, jx);
alpar@461
   237
    if (it != indices + end && *it == jx) {
alpar@461
   238
      return elements[it - indices];
alpar@461
   239
    } else {
alpar@461
   240
      return 0.0;
alpar@461
   241
    }
alpar@461
   242
  }
alpar@461
   243
alpar@462
   244
  void ClpLp::_setColLowerBound(int i, Value lo) {
alpar@461
   245
    _prob->setColumnLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
alpar@461
   246
  }
alpar@461
   247
alpar@462
   248
  ClpLp::Value ClpLp::_getColLowerBound(int i) const {
alpar@461
   249
    double val = _prob->getColLower()[i];
alpar@461
   250
    return val == - COIN_DBL_MAX ? - INF : val;
alpar@461
   251
  }
alpar@461
   252
alpar@462
   253
  void ClpLp::_setColUpperBound(int i, Value up) {
alpar@461
   254
    _prob->setColumnUpper(i, up == INF ? COIN_DBL_MAX : up);
alpar@461
   255
  }
alpar@461
   256
alpar@462
   257
  ClpLp::Value ClpLp::_getColUpperBound(int i) const {
alpar@461
   258
    double val = _prob->getColUpper()[i];
alpar@461
   259
    return val == COIN_DBL_MAX ? INF : val;
alpar@461
   260
  }
alpar@461
   261
alpar@462
   262
  void ClpLp::_setRowLowerBound(int i, Value lo) {
alpar@461
   263
    _prob->setRowLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
alpar@461
   264
  }
alpar@461
   265
alpar@462
   266
  ClpLp::Value ClpLp::_getRowLowerBound(int i) const {
alpar@461
   267
    double val = _prob->getRowLower()[i];
alpar@461
   268
    return val == - COIN_DBL_MAX ? - INF : val;
alpar@461
   269
  }
alpar@461
   270
alpar@462
   271
  void ClpLp::_setRowUpperBound(int i, Value up) {
alpar@461
   272
    _prob->setRowUpper(i, up == INF ? COIN_DBL_MAX : up);
alpar@461
   273
  }
alpar@461
   274
alpar@462
   275
  ClpLp::Value ClpLp::_getRowUpperBound(int i) const {
alpar@461
   276
    double val = _prob->getRowUpper()[i];
alpar@461
   277
    return val == COIN_DBL_MAX ? INF : val;
alpar@461
   278
  }
alpar@461
   279
alpar@462
   280
  void ClpLp::_setObjCoeffs(ExprIterator b, ExprIterator e) {
alpar@461
   281
    int num = _prob->clpMatrix()->getNumCols();
alpar@461
   282
    for (int i = 0; i < num; ++i) {
alpar@461
   283
      _prob->setObjectiveCoefficient(i, 0.0);
alpar@461
   284
    }
alpar@461
   285
    for (ExprIterator it = b; it != e; ++it) {
alpar@461
   286
      _prob->setObjectiveCoefficient(it->first, it->second);
alpar@461
   287
    }
alpar@461
   288
  }
alpar@461
   289
alpar@462
   290
  void ClpLp::_getObjCoeffs(InsertIterator b) const {
alpar@461
   291
    int num = _prob->clpMatrix()->getNumCols();
alpar@461
   292
    for (int i = 0; i < num; ++i) {
alpar@461
   293
      Value coef = _prob->getObjCoefficients()[i];
alpar@461
   294
      if (coef != 0.0) {
alpar@461
   295
        *b = std::make_pair(i, coef);
alpar@461
   296
        ++b;
alpar@461
   297
      }
alpar@461
   298
    }
alpar@461
   299
  }
alpar@461
   300
alpar@462
   301
  void ClpLp::_setObjCoeff(int i, Value obj_coef) {
alpar@461
   302
    _prob->setObjectiveCoefficient(i, obj_coef);
alpar@461
   303
  }
alpar@461
   304
alpar@462
   305
  ClpLp::Value ClpLp::_getObjCoeff(int i) const {
alpar@461
   306
    return _prob->getObjCoefficients()[i];
alpar@461
   307
  }
alpar@461
   308
alpar@462
   309
  ClpLp::SolveExitStatus ClpLp::_solve() {
alpar@461
   310
    return _prob->primal() >= 0 ? SOLVED : UNSOLVED;
alpar@461
   311
  }
alpar@461
   312
alpar@462
   313
  ClpLp::SolveExitStatus ClpLp::solvePrimal() {
alpar@461
   314
    return _prob->primal() >= 0 ? SOLVED : UNSOLVED;
alpar@461
   315
  }
alpar@461
   316
alpar@462
   317
  ClpLp::SolveExitStatus ClpLp::solveDual() {
alpar@461
   318
    return _prob->dual() >= 0 ? SOLVED : UNSOLVED;
alpar@461
   319
  }
alpar@461
   320
alpar@462
   321
  ClpLp::SolveExitStatus ClpLp::solveBarrier() {
alpar@461
   322
    return _prob->barrier() >= 0 ? SOLVED : UNSOLVED;
alpar@461
   323
  }
alpar@461
   324
alpar@462
   325
  ClpLp::Value ClpLp::_getPrimal(int i) const {
alpar@461
   326
    return _prob->primalColumnSolution()[i];
alpar@461
   327
  }
alpar@462
   328
  ClpLp::Value ClpLp::_getPrimalValue() const {
alpar@461
   329
    return _prob->objectiveValue();
alpar@461
   330
  }
alpar@461
   331
alpar@462
   332
  ClpLp::Value ClpLp::_getDual(int i) const {
alpar@461
   333
    return _prob->dualRowSolution()[i];
alpar@461
   334
  }
alpar@461
   335
alpar@462
   336
  ClpLp::Value ClpLp::_getPrimalRay(int i) const {
alpar@461
   337
    if (!_primal_ray) {
alpar@461
   338
      _primal_ray = _prob->unboundedRay();
alpar@461
   339
      LEMON_ASSERT(_primal_ray != 0, "Primal ray is not provided");
alpar@461
   340
    }
alpar@461
   341
    return _primal_ray[i];
alpar@461
   342
  }
alpar@461
   343
alpar@462
   344
  ClpLp::Value ClpLp::_getDualRay(int i) const {
alpar@461
   345
    if (!_dual_ray) {
alpar@461
   346
      _dual_ray = _prob->infeasibilityRay();
alpar@461
   347
      LEMON_ASSERT(_dual_ray != 0, "Dual ray is not provided");
alpar@461
   348
    }
alpar@461
   349
    return _dual_ray[i];
alpar@461
   350
  }
alpar@461
   351
alpar@462
   352
  ClpLp::VarStatus ClpLp::_getColStatus(int i) const {
alpar@461
   353
    switch (_prob->getColumnStatus(i)) {
alpar@461
   354
    case ClpSimplex::basic:
alpar@461
   355
      return BASIC;
alpar@461
   356
    case ClpSimplex::isFree:
alpar@461
   357
      return FREE;
alpar@461
   358
    case ClpSimplex::atUpperBound:
alpar@461
   359
      return UPPER;
alpar@461
   360
    case ClpSimplex::atLowerBound:
alpar@461
   361
      return LOWER;
alpar@461
   362
    case ClpSimplex::isFixed:
alpar@461
   363
      return FIXED;
alpar@461
   364
    case ClpSimplex::superBasic:
alpar@461
   365
      return FREE;
alpar@461
   366
    default:
alpar@461
   367
      LEMON_ASSERT(false, "Wrong column status");
alpar@461
   368
      return VarStatus();
alpar@461
   369
    }
alpar@461
   370
  }
alpar@461
   371
alpar@462
   372
  ClpLp::VarStatus ClpLp::_getRowStatus(int i) const {
alpar@461
   373
    switch (_prob->getColumnStatus(i)) {
alpar@461
   374
    case ClpSimplex::basic:
alpar@461
   375
      return BASIC;
alpar@461
   376
    case ClpSimplex::isFree:
alpar@461
   377
      return FREE;
alpar@461
   378
    case ClpSimplex::atUpperBound:
alpar@461
   379
      return UPPER;
alpar@461
   380
    case ClpSimplex::atLowerBound:
alpar@461
   381
      return LOWER;
alpar@461
   382
    case ClpSimplex::isFixed:
alpar@461
   383
      return FIXED;
alpar@461
   384
    case ClpSimplex::superBasic:
alpar@461
   385
      return FREE;
alpar@461
   386
    default:
alpar@461
   387
      LEMON_ASSERT(false, "Wrong row status");
alpar@461
   388
      return VarStatus();
alpar@461
   389
    }
alpar@461
   390
  }
alpar@461
   391
alpar@461
   392
alpar@462
   393
  ClpLp::ProblemType ClpLp::_getPrimalType() const {
alpar@461
   394
    if (_prob->isProvenOptimal()) {
alpar@461
   395
      return OPTIMAL;
alpar@461
   396
    } else if (_prob->isProvenPrimalInfeasible()) {
alpar@461
   397
      return INFEASIBLE;
alpar@461
   398
    } else if (_prob->isProvenDualInfeasible()) {
alpar@461
   399
      return UNBOUNDED;
alpar@461
   400
    } else {
alpar@461
   401
      return UNDEFINED;
alpar@461
   402
    }
alpar@461
   403
  }
alpar@461
   404
alpar@462
   405
  ClpLp::ProblemType ClpLp::_getDualType() const {
alpar@461
   406
    if (_prob->isProvenOptimal()) {
alpar@461
   407
      return OPTIMAL;
alpar@461
   408
    } else if (_prob->isProvenDualInfeasible()) {
alpar@461
   409
      return INFEASIBLE;
alpar@461
   410
    } else if (_prob->isProvenPrimalInfeasible()) {
alpar@461
   411
      return INFEASIBLE;
alpar@461
   412
    } else {
alpar@461
   413
      return UNDEFINED;
alpar@461
   414
    }
alpar@461
   415
  }
alpar@461
   416
alpar@462
   417
  void ClpLp::_setSense(ClpLp::Sense sense) {
alpar@461
   418
    switch (sense) {
alpar@461
   419
    case MIN:
alpar@461
   420
      _prob->setOptimizationDirection(1);
alpar@461
   421
      break;
alpar@461
   422
    case MAX:
alpar@461
   423
      _prob->setOptimizationDirection(-1);
alpar@461
   424
      break;
alpar@461
   425
    }
alpar@461
   426
  }
alpar@461
   427
alpar@462
   428
  ClpLp::Sense ClpLp::_getSense() const {
alpar@461
   429
    double dir = _prob->optimizationDirection();
alpar@461
   430
    if (dir > 0.0) {
alpar@461
   431
      return MIN;
alpar@461
   432
    } else {
alpar@461
   433
      return MAX;
alpar@461
   434
    }
alpar@461
   435
  }
alpar@461
   436
alpar@462
   437
  void ClpLp::_clear() {
alpar@461
   438
    delete _prob;
alpar@461
   439
    _prob = new ClpSimplex();
alpar@461
   440
    rows.clear();
alpar@461
   441
    cols.clear();
alpar@461
   442
    _col_names_ref.clear();
alpar@461
   443
    _clear_temporals();
alpar@461
   444
  }
alpar@461
   445
deba@576
   446
  void ClpLp::_messageLevel(MessageLevel level) {
deba@576
   447
    switch (level) {
deba@576
   448
    case MESSAGE_NOTHING:
deba@576
   449
      _prob->setLogLevel(0);
deba@576
   450
      break;
deba@576
   451
    case MESSAGE_ERROR:
deba@576
   452
      _prob->setLogLevel(1);
deba@576
   453
      break;
deba@576
   454
    case MESSAGE_WARNING:
deba@576
   455
      _prob->setLogLevel(2);
deba@576
   456
      break;
deba@576
   457
    case MESSAGE_NORMAL:
deba@576
   458
      _prob->setLogLevel(3);
deba@576
   459
      break;
deba@576
   460
    case MESSAGE_VERBOSE:
deba@576
   461
      _prob->setLogLevel(4);
deba@576
   462
      break;
deba@576
   463
    }
alpar@461
   464
  }
alpar@461
   465
alpar@461
   466
} //END OF NAMESPACE LEMON