gravatar
deba@inf.elte.hu
deba@inf.elte.hu
Faster add row operation (#203) One virtual function call instead of more
0 13 0
default
13 files changed with 137 insertions and 4 deletions:
↑ Collapse diff ↑
Show white space 512 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-2009
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
///\file
20 20
///\brief Implementation of the CBC MIP solver interface.
21 21

	
22 22
#include "cbc.h"
23 23

	
24 24
#include <coin/CoinModel.hpp>
25 25
#include <coin/CbcModel.hpp>
26 26
#include <coin/OsiSolverInterface.hpp>
27 27

	
28 28
#ifdef COIN_HAS_CLP
29 29
#include "coin/OsiClpSolverInterface.hpp"
30 30
#endif
31 31
#ifdef COIN_HAS_OSL
32 32
#include "coin/OsiOslSolverInterface.hpp"
33 33
#endif
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 58
    messageLevel(MESSAGE_NOTHING);
59 59
  }
60 60

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

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

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

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

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

	
87 87
  CbcMip* CbcMip::cloneSolver() const {
88 88
    CbcMip* copylp = new CbcMip(*this);
89 89
    return copylp;
90 90
  }
91 91

	
92 92
  int CbcMip::_addRow() {
93 93
    _prob->addRow(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX);
94 94
    return _prob->numberRows() - 1;
95 95
  }
96 96

	
97
  int CbcMip::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
98
    std::vector<int> indexes;
99
    std::vector<Value> values;
100

	
101
    for(ExprIterator it = b; it != e; ++it) {
102
      indexes.push_back(it->first);
103
      values.push_back(it->second);
104
    }
105

	
106
    _prob->addRow(values.size(), &indexes.front(), &values.front(), l, u);
107
    return _prob->numberRows() - 1;
108
  }
97 109

	
98 110
  void CbcMip::_eraseCol(int i) {
99 111
    _prob->deleteColumn(i);
100 112
  }
101 113

	
102 114
  void CbcMip::_eraseRow(int i) {
103 115
    _prob->deleteRow(i);
104 116
  }
105 117

	
106 118
  void CbcMip::_eraseColId(int i) {
107 119
    cols.eraseIndex(i);
108 120
  }
109 121

	
110 122
  void CbcMip::_eraseRowId(int i) {
111 123
    rows.eraseIndex(i);
112 124
  }
113 125

	
114 126
  void CbcMip::_getColName(int c, std::string& name) const {
115 127
    name = _prob->getColumnName(c);
116 128
  }
117 129

	
118 130
  void CbcMip::_setColName(int c, const std::string& name) {
119 131
    _prob->setColumnName(c, name.c_str());
120 132
  }
121 133

	
122 134
  int CbcMip::_colByName(const std::string& name) const {
123 135
    return _prob->column(name.c_str());
124 136
  }
125 137

	
126 138
  void CbcMip::_getRowName(int r, std::string& name) const {
127 139
    name = _prob->getRowName(r);
128 140
  }
129 141

	
130 142
  void CbcMip::_setRowName(int r, const std::string& name) {
131 143
    _prob->setRowName(r, name.c_str());
132 144
  }
133 145

	
134 146
  int CbcMip::_rowByName(const std::string& name) const {
135 147
    return _prob->row(name.c_str());
136 148
  }
137 149

	
138 150
  void CbcMip::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) {
139 151
    for (ExprIterator it = b; it != e; ++it) {
140 152
      _prob->setElement(i, it->first, it->second);
141 153
    }
142 154
  }
143 155

	
144 156
  void CbcMip::_getRowCoeffs(int ix, InsertIterator b) const {
145 157
    int length = _prob->numberRows();
146 158

	
147 159
    std::vector<int> indices(length);
148 160
    std::vector<Value> values(length);
149 161

	
150 162
    length = _prob->getRow(ix, &indices[0], &values[0]);
151 163

	
152 164
    for (int i = 0; i < length; ++i) {
153 165
      *b = std::make_pair(indices[i], values[i]);
154 166
      ++b;
155 167
    }
156 168
  }
157 169

	
158 170
  void CbcMip::_setColCoeffs(int ix, ExprIterator b, ExprIterator e) {
159 171
    for (ExprIterator it = b; it != e; ++it) {
160 172
      _prob->setElement(it->first, ix, it->second);
161 173
    }
162 174
  }
163 175

	
164 176
  void CbcMip::_getColCoeffs(int ix, InsertIterator b) const {
165 177
    int length = _prob->numberColumns();
166 178

	
167 179
    std::vector<int> indices(length);
168 180
    std::vector<Value> values(length);
169 181

	
170 182
    length = _prob->getColumn(ix, &indices[0], &values[0]);
171 183

	
172 184
    for (int i = 0; i < length; ++i) {
173 185
      *b = std::make_pair(indices[i], values[i]);
174 186
      ++b;
175 187
    }
176 188
  }
177 189

	
178 190
  void CbcMip::_setCoeff(int ix, int jx, Value value) {
179 191
    _prob->setElement(ix, jx, value);
180 192
  }
181 193

	
182 194
  CbcMip::Value CbcMip::_getCoeff(int ix, int jx) const {
183 195
    return _prob->getElement(ix, jx);
184 196
  }
185 197

	
186 198

	
187 199
  void CbcMip::_setColLowerBound(int i, Value lo) {
188 200
    LEMON_ASSERT(lo != INF, "Invalid bound");
189 201
    _prob->setColumnLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
190 202
  }
191 203

	
192 204
  CbcMip::Value CbcMip::_getColLowerBound(int i) const {
193 205
    double val = _prob->getColumnLower(i);
194 206
    return val == - COIN_DBL_MAX ? - INF : val;
195 207
  }
196 208

	
197 209
  void CbcMip::_setColUpperBound(int i, Value up) {
198 210
    LEMON_ASSERT(up != -INF, "Invalid bound");
199 211
    _prob->setColumnUpper(i, up == INF ? COIN_DBL_MAX : up);
200 212
  }
201 213

	
202 214
  CbcMip::Value CbcMip::_getColUpperBound(int i) const {
203 215
    double val = _prob->getColumnUpper(i);
204 216
    return val == COIN_DBL_MAX ? INF : val;
205 217
  }
206 218

	
207 219
  void CbcMip::_setRowLowerBound(int i, Value lo) {
208 220
    LEMON_ASSERT(lo != INF, "Invalid bound");
209 221
    _prob->setRowLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
210 222
  }
211 223

	
212 224
  CbcMip::Value CbcMip::_getRowLowerBound(int i) const {
213 225
    double val = _prob->getRowLower(i);
214 226
    return val == - COIN_DBL_MAX ? - INF : val;
215 227
  }
216 228

	
217 229
  void CbcMip::_setRowUpperBound(int i, Value up) {
218 230
    LEMON_ASSERT(up != -INF, "Invalid bound");
219 231
    _prob->setRowUpper(i, up == INF ? COIN_DBL_MAX : up);
220 232
  }
221 233

	
222 234
  CbcMip::Value CbcMip::_getRowUpperBound(int i) const {
223 235
    double val = _prob->getRowUpper(i);
224 236
    return val == COIN_DBL_MAX ? INF : val;
225 237
  }
226 238

	
227 239
  void CbcMip::_setObjCoeffs(ExprIterator b, ExprIterator e) {
228 240
    int num = _prob->numberColumns();
229 241
    for (int i = 0; i < num; ++i) {
230 242
      _prob->setColumnObjective(i, 0.0);
231 243
    }
232 244
    for (ExprIterator it = b; it != e; ++it) {
233 245
      _prob->setColumnObjective(it->first, it->second);
234 246
    }
235 247
  }
236 248

	
237 249
  void CbcMip::_getObjCoeffs(InsertIterator b) const {
238 250
    int num = _prob->numberColumns();
239 251
    for (int i = 0; i < num; ++i) {
240 252
      Value coef = _prob->getColumnObjective(i);
241 253
      if (coef != 0.0) {
242 254
        *b = std::make_pair(i, coef);
243 255
        ++b;
244 256
      }
245 257
    }
246 258
  }
247 259

	
248 260
  void CbcMip::_setObjCoeff(int i, Value obj_coef) {
249 261
    _prob->setColumnObjective(i, obj_coef);
250 262
  }
251 263

	
252 264
  CbcMip::Value CbcMip::_getObjCoeff(int i) const {
253 265
    return _prob->getColumnObjective(i);
254 266
  }
255 267

	
256 268
  CbcMip::SolveExitStatus CbcMip::_solve() {
257 269

	
258 270
    if (_osi_solver) {
259 271
      delete _osi_solver;
260 272
    }
261 273
#ifdef COIN_HAS_CLP
262 274
    _osi_solver = new OsiClpSolverInterface();
263 275
#elif COIN_HAS_OSL
264 276
    _osi_solver = new OsiOslSolverInterface();
265 277
#else
266 278
#error Cannot instantiate Osi solver
267 279
#endif
268 280

	
269 281
    _osi_solver->loadFromCoinModel(*_prob);
270 282

	
271 283
    if (_cbc_model) {
272 284
      delete _cbc_model;
273 285
    }
274 286
    _cbc_model= new CbcModel(*_osi_solver);
275 287

	
276 288
    _osi_solver->messageHandler()->setLogLevel(_message_level);
277 289
    _cbc_model->setLogLevel(_message_level);
278 290

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

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

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

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

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

	
302 314
      CglOddHole generator4;
303 315
      generator4.setMinimumViolation(0.005);
304 316
      generator4.setMinimumViolationPer(0.00002);
305 317
      generator4.setMaximumEntries(200);
306 318
      _cbc_model->addCutGenerator(&generator4, -1, "OddHole");
307 319

	
308 320
      CglClique generator5;
309 321
      generator5.setStarCliqueReport(false);
310 322
      generator5.setRowCliqueReport(false);
311 323
      _cbc_model->addCutGenerator(&generator5, -1, "Clique");
312 324

	
313 325
      CglMixedIntegerRounding mixedGen;
314 326
      _cbc_model->addCutGenerator(&mixedGen, -1, "MixedIntegerRounding");
315 327

	
316 328
      CglFlowCover flowGen;
317 329
      _cbc_model->addCutGenerator(&flowGen, -1, "FlowCover");
318 330

	
319 331
#ifdef COIN_HAS_CLP
320 332
      OsiClpSolverInterface* osiclp =
321 333
        dynamic_cast<OsiClpSolverInterface*>(_cbc_model->solver());
322 334
      if (osiclp->getNumRows() < 300 && osiclp->getNumCols() < 500) {
323 335
        osiclp->setupForRepeatedUse(2, 0);
324 336
      }
325 337
#endif
326 338

	
327 339
      CbcRounding heuristic1(*_cbc_model);
328 340
      heuristic1.setWhen(3);
329 341
      _cbc_model->addHeuristic(&heuristic1);
330 342

	
331 343
      CbcHeuristicLocal heuristic2(*_cbc_model);
332 344
      heuristic2.setWhen(3);
333 345
      _cbc_model->addHeuristic(&heuristic2);
334 346

	
335 347
      CbcHeuristicGreedyCover heuristic3(*_cbc_model);
336 348
      heuristic3.setAlgorithm(11);
337 349
      heuristic3.setWhen(3);
338 350
      _cbc_model->addHeuristic(&heuristic3);
339 351

	
340 352
      CbcHeuristicFPump heuristic4(*_cbc_model);
341 353
      heuristic4.setWhen(3);
342 354
      _cbc_model->addHeuristic(&heuristic4);
343 355

	
344 356
      CbcHeuristicRINS heuristic5(*_cbc_model);
345 357
      heuristic5.setWhen(3);
346 358
      _cbc_model->addHeuristic(&heuristic5);
347 359

	
348 360
      if (_cbc_model->getNumCols() < 500) {
349 361
        _cbc_model->setMaximumCutPassesAtRoot(-100);
350 362
      } else if (_cbc_model->getNumCols() < 5000) {
351 363
        _cbc_model->setMaximumCutPassesAtRoot(100);
352 364
      } else {
Show white space 512 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-2009
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
// -*- C++ -*-
20 20
#ifndef LEMON_CBC_H
21 21
#define LEMON_CBC_H
22 22

	
23 23
///\file
24 24
///\brief Header of the LEMON-CBC mip solver interface.
25 25
///\ingroup lp_group
26 26

	
27 27
#include <lemon/lp_base.h>
28 28

	
29 29
class CoinModel;
30 30
class OsiSolverInterface;
31 31
class CbcModel;
32 32

	
33 33
namespace lemon {
34 34

	
35 35
  /// \brief Interface for the CBC MIP solver
36 36
  ///
37 37
  /// This class implements an interface for the CBC MIP solver.
38 38
  ///\ingroup lp_group
39 39
  class CbcMip : public MipSolver {
40 40
  protected:
41 41

	
42 42
    CoinModel *_prob;
43 43
    OsiSolverInterface *_osi_solver;
44 44
    CbcModel *_cbc_model;
45 45

	
46 46
  public:
47 47

	
48 48
    /// \e
49 49
    CbcMip();
50 50
    /// \e
51 51
    CbcMip(const CbcMip&);
52 52
    /// \e
53 53
    ~CbcMip();
54 54
    /// \e
55 55
    virtual CbcMip* newSolver() const;
56 56
    /// \e
57 57
    virtual CbcMip* cloneSolver() const;
58 58

	
59 59
  protected:
60 60

	
61 61
    virtual const char* _solverName() const;
62 62

	
63 63
    virtual int _addCol();
64 64
    virtual int _addRow();
65
    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
65 66

	
66 67
    virtual void _eraseCol(int i);
67 68
    virtual void _eraseRow(int i);
68 69

	
69 70
    virtual void _eraseColId(int i);
70 71
    virtual void _eraseRowId(int i);
71 72

	
72 73
    virtual void _getColName(int col, std::string& name) const;
73 74
    virtual void _setColName(int col, const std::string& name);
74 75
    virtual int _colByName(const std::string& name) const;
75 76

	
76 77
    virtual void _getRowName(int row, std::string& name) const;
77 78
    virtual void _setRowName(int row, const std::string& name);
78 79
    virtual int _rowByName(const std::string& name) const;
79 80

	
80 81
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
81 82
    virtual void _getRowCoeffs(int i, InsertIterator b) const;
82 83

	
83 84
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
84 85
    virtual void _getColCoeffs(int i, InsertIterator b) const;
85 86

	
86 87
    virtual void _setCoeff(int row, int col, Value value);
87 88
    virtual Value _getCoeff(int row, int col) const;
88 89

	
89 90
    virtual void _setColLowerBound(int i, Value value);
90 91
    virtual Value _getColLowerBound(int i) const;
91 92
    virtual void _setColUpperBound(int i, Value value);
92 93
    virtual Value _getColUpperBound(int i) const;
93 94

	
94 95
    virtual void _setRowLowerBound(int i, Value value);
95 96
    virtual Value _getRowLowerBound(int i) const;
96 97
    virtual void _setRowUpperBound(int i, Value value);
97 98
    virtual Value _getRowUpperBound(int i) const;
98 99

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

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

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

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

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

	
116 117
    virtual void _clear();
117 118

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

	
121 122
    int _message_level;
122 123

	
123 124
    
124 125

	
125 126
  };
126 127

	
127 128
}
128 129

	
129 130
#endif
Show white space 512 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 <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 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 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 {
60 60
    ClpLp* newlp = new ClpLp;
61 61
    return newlp;
62 62
  }
63 63

	
64 64
  ClpLp* ClpLp::cloneSolver() const {
65 65
    ClpLp* copylp = new ClpLp(*this);
66 66
    return copylp;
67 67
  }
68 68

	
69 69
  const char* ClpLp::_solverName() const { return "ClpLp"; }
70 70

	
71 71
  int ClpLp::_addCol() {
72 72
    _prob->addColumn(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX, 0.0);
73 73
    return _prob->numberColumns() - 1;
74 74
  }
75 75

	
76 76
  int ClpLp::_addRow() {
77 77
    _prob->addRow(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX);
78 78
    return _prob->numberRows() - 1;
79 79
  }
80 80

	
81
  int ClpLp::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
82
    std::vector<int> indexes;
83
    std::vector<Value> values;
84

	
85
    for(ExprIterator it = b; it != e; ++it) {
86
      indexes.push_back(it->first);
87
      values.push_back(it->second);
88
    }
89

	
90
    _prob->addRow(values.size(), &indexes.front(), &values.front(), l, u);
91
    return _prob->numberRows() - 1;
92
  }
93

	
81 94

	
82 95
  void ClpLp::_eraseCol(int c) {
83 96
    _col_names_ref.erase(_prob->getColumnName(c));
84 97
    _prob->deleteColumns(1, &c);
85 98
  }
86 99

	
87 100
  void ClpLp::_eraseRow(int r) {
88 101
    _row_names_ref.erase(_prob->getRowName(r));
89 102
    _prob->deleteRows(1, &r);
90 103
  }
91 104

	
92 105
  void ClpLp::_eraseColId(int i) {
93 106
    cols.eraseIndex(i);
94 107
    cols.shiftIndices(i);
95 108
  }
96 109

	
97 110
  void ClpLp::_eraseRowId(int i) {
98 111
    rows.eraseIndex(i);
99 112
    rows.shiftIndices(i);
100 113
  }
101 114

	
102 115
  void ClpLp::_getColName(int c, std::string& name) const {
103 116
    name = _prob->getColumnName(c);
104 117
  }
105 118

	
106 119
  void ClpLp::_setColName(int c, const std::string& name) {
107 120
    _prob->setColumnName(c, const_cast<std::string&>(name));
108 121
    _col_names_ref[name] = c;
109 122
  }
110 123

	
111 124
  int ClpLp::_colByName(const std::string& name) const {
112 125
    std::map<std::string, int>::const_iterator it = _col_names_ref.find(name);
113 126
    return it != _col_names_ref.end() ? it->second : -1;
114 127
  }
115 128

	
116 129
  void ClpLp::_getRowName(int r, std::string& name) const {
117 130
    name = _prob->getRowName(r);
118 131
  }
119 132

	
120 133
  void ClpLp::_setRowName(int r, const std::string& name) {
121 134
    _prob->setRowName(r, const_cast<std::string&>(name));
122 135
    _row_names_ref[name] = r;
123 136
  }
124 137

	
125 138
  int ClpLp::_rowByName(const std::string& name) const {
126 139
    std::map<std::string, int>::const_iterator it = _row_names_ref.find(name);
127 140
    return it != _row_names_ref.end() ? it->second : -1;
128 141
  }
129 142

	
130 143

	
131 144
  void ClpLp::_setRowCoeffs(int ix, ExprIterator b, ExprIterator e) {
132 145
    std::map<int, Value> coeffs;
133 146

	
134 147
    int n = _prob->clpMatrix()->getNumCols();
135 148

	
136 149
    const int* indices = _prob->clpMatrix()->getIndices();
137 150
    const double* elements = _prob->clpMatrix()->getElements();
138 151

	
139 152
    for (int i = 0; i < n; ++i) {
140 153
      CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[i];
141 154
      CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[i];
142 155

	
143 156
      const int* it = std::lower_bound(indices + begin, indices + end, ix);
144 157
      if (it != indices + end && *it == ix && elements[it - indices] != 0.0) {
145 158
        coeffs[i] = 0.0;
146 159
      }
147 160
    }
148 161

	
149 162
    for (ExprIterator it = b; it != e; ++it) {
150 163
      coeffs[it->first] = it->second;
151 164
    }
152 165

	
153 166
    for (std::map<int, Value>::iterator it = coeffs.begin();
154 167
         it != coeffs.end(); ++it) {
155 168
      _prob->modifyCoefficient(ix, it->first, it->second);
156 169
    }
157 170
  }
158 171

	
159 172
  void ClpLp::_getRowCoeffs(int ix, InsertIterator b) const {
160 173
    int n = _prob->clpMatrix()->getNumCols();
161 174

	
162 175
    const int* indices = _prob->clpMatrix()->getIndices();
163 176
    const double* elements = _prob->clpMatrix()->getElements();
164 177

	
165 178
    for (int i = 0; i < n; ++i) {
166 179
      CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[i];
167 180
      CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[i];
168 181

	
169 182
      const int* it = std::lower_bound(indices + begin, indices + end, ix);
170 183
      if (it != indices + end && *it == ix) {
171 184
        *b = std::make_pair(i, elements[it - indices]);
172 185
      }
173 186
    }
174 187
  }
175 188

	
176 189
  void ClpLp::_setColCoeffs(int ix, ExprIterator b, ExprIterator e) {
177 190
    std::map<int, Value> coeffs;
178 191

	
179 192
    CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix];
180 193
    CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix];
181 194

	
182 195
    const int* indices = _prob->clpMatrix()->getIndices();
183 196
    const double* elements = _prob->clpMatrix()->getElements();
184 197

	
185 198
    for (CoinBigIndex i = begin; i != end; ++i) {
186 199
      if (elements[i] != 0.0) {
187 200
        coeffs[indices[i]] = 0.0;
188 201
      }
189 202
    }
190 203
    for (ExprIterator it = b; it != e; ++it) {
191 204
      coeffs[it->first] = it->second;
192 205
    }
193 206
    for (std::map<int, Value>::iterator it = coeffs.begin();
194 207
         it != coeffs.end(); ++it) {
195 208
      _prob->modifyCoefficient(it->first, ix, it->second);
196 209
    }
197 210
  }
198 211

	
199 212
  void ClpLp::_getColCoeffs(int ix, InsertIterator b) const {
200 213
    CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix];
201 214
    CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix];
202 215

	
203 216
    const int* indices = _prob->clpMatrix()->getIndices();
204 217
    const double* elements = _prob->clpMatrix()->getElements();
205 218

	
206 219
    for (CoinBigIndex i = begin; i != end; ++i) {
207 220
      *b = std::make_pair(indices[i], elements[i]);
208 221
      ++b;
209 222
    }
210 223
  }
211 224

	
212 225
  void ClpLp::_setCoeff(int ix, int jx, Value value) {
213 226
    _prob->modifyCoefficient(ix, jx, value);
214 227
  }
215 228

	
216 229
  ClpLp::Value ClpLp::_getCoeff(int ix, int jx) const {
217 230
    CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix];
218 231
    CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix];
219 232

	
220 233
    const int* indices = _prob->clpMatrix()->getIndices();
221 234
    const double* elements = _prob->clpMatrix()->getElements();
222 235

	
223 236
    const int* it = std::lower_bound(indices + begin, indices + end, jx);
224 237
    if (it != indices + end && *it == jx) {
225 238
      return elements[it - indices];
226 239
    } else {
227 240
      return 0.0;
228 241
    }
229 242
  }
230 243

	
231 244
  void ClpLp::_setColLowerBound(int i, Value lo) {
232 245
    _prob->setColumnLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
233 246
  }
234 247

	
235 248
  ClpLp::Value ClpLp::_getColLowerBound(int i) const {
236 249
    double val = _prob->getColLower()[i];
237 250
    return val == - COIN_DBL_MAX ? - INF : val;
238 251
  }
239 252

	
240 253
  void ClpLp::_setColUpperBound(int i, Value up) {
241 254
    _prob->setColumnUpper(i, up == INF ? COIN_DBL_MAX : up);
242 255
  }
243 256

	
244 257
  ClpLp::Value ClpLp::_getColUpperBound(int i) const {
245 258
    double val = _prob->getColUpper()[i];
246 259
    return val == COIN_DBL_MAX ? INF : val;
247 260
  }
248 261

	
249 262
  void ClpLp::_setRowLowerBound(int i, Value lo) {
250 263
    _prob->setRowLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
251 264
  }
252 265

	
253 266
  ClpLp::Value ClpLp::_getRowLowerBound(int i) const {
254 267
    double val = _prob->getRowLower()[i];
255 268
    return val == - COIN_DBL_MAX ? - INF : val;
256 269
  }
257 270

	
258 271
  void ClpLp::_setRowUpperBound(int i, Value up) {
259 272
    _prob->setRowUpper(i, up == INF ? COIN_DBL_MAX : up);
260 273
  }
261 274

	
262 275
  ClpLp::Value ClpLp::_getRowUpperBound(int i) const {
263 276
    double val = _prob->getRowUpper()[i];
264 277
    return val == COIN_DBL_MAX ? INF : val;
265 278
  }
266 279

	
267 280
  void ClpLp::_setObjCoeffs(ExprIterator b, ExprIterator e) {
268 281
    int num = _prob->clpMatrix()->getNumCols();
269 282
    for (int i = 0; i < num; ++i) {
270 283
      _prob->setObjectiveCoefficient(i, 0.0);
271 284
    }
272 285
    for (ExprIterator it = b; it != e; ++it) {
273 286
      _prob->setObjectiveCoefficient(it->first, it->second);
274 287
    }
275 288
  }
276 289

	
277 290
  void ClpLp::_getObjCoeffs(InsertIterator b) const {
278 291
    int num = _prob->clpMatrix()->getNumCols();
279 292
    for (int i = 0; i < num; ++i) {
280 293
      Value coef = _prob->getObjCoefficients()[i];
281 294
      if (coef != 0.0) {
282 295
        *b = std::make_pair(i, coef);
283 296
        ++b;
284 297
      }
285 298
    }
286 299
  }
287 300

	
288 301
  void ClpLp::_setObjCoeff(int i, Value obj_coef) {
289 302
    _prob->setObjectiveCoefficient(i, obj_coef);
290 303
  }
291 304

	
292 305
  ClpLp::Value ClpLp::_getObjCoeff(int i) const {
293 306
    return _prob->getObjCoefficients()[i];
294 307
  }
295 308

	
296 309
  ClpLp::SolveExitStatus ClpLp::_solve() {
297 310
    return _prob->primal() >= 0 ? SOLVED : UNSOLVED;
298 311
  }
299 312

	
300 313
  ClpLp::SolveExitStatus ClpLp::solvePrimal() {
301 314
    return _prob->primal() >= 0 ? SOLVED : UNSOLVED;
302 315
  }
303 316

	
304 317
  ClpLp::SolveExitStatus ClpLp::solveDual() {
305 318
    return _prob->dual() >= 0 ? SOLVED : UNSOLVED;
306 319
  }
307 320

	
308 321
  ClpLp::SolveExitStatus ClpLp::solveBarrier() {
309 322
    return _prob->barrier() >= 0 ? SOLVED : UNSOLVED;
310 323
  }
311 324

	
312 325
  ClpLp::Value ClpLp::_getPrimal(int i) const {
313 326
    return _prob->primalColumnSolution()[i];
314 327
  }
315 328
  ClpLp::Value ClpLp::_getPrimalValue() const {
316 329
    return _prob->objectiveValue();
317 330
  }
318 331

	
319 332
  ClpLp::Value ClpLp::_getDual(int i) const {
320 333
    return _prob->dualRowSolution()[i];
321 334
  }
322 335

	
323 336
  ClpLp::Value ClpLp::_getPrimalRay(int i) const {
324 337
    if (!_primal_ray) {
325 338
      _primal_ray = _prob->unboundedRay();
326 339
      LEMON_ASSERT(_primal_ray != 0, "Primal ray is not provided");
327 340
    }
328 341
    return _primal_ray[i];
329 342
  }
330 343

	
331 344
  ClpLp::Value ClpLp::_getDualRay(int i) const {
332 345
    if (!_dual_ray) {
333 346
      _dual_ray = _prob->infeasibilityRay();
334 347
      LEMON_ASSERT(_dual_ray != 0, "Dual ray is not provided");
335 348
    }
336 349
    return _dual_ray[i];
Show white space 512 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
#ifndef LEMON_CLP_H
20 20
#define LEMON_CLP_H
21 21

	
22 22
///\file
23 23
///\brief Header of the LEMON-CLP lp solver interface.
24 24

	
25 25
#include <vector>
26 26
#include <string>
27 27

	
28 28
#include <lemon/lp_base.h>
29 29

	
30 30
class ClpSimplex;
31 31

	
32 32
namespace lemon {
33 33

	
34 34
  /// \ingroup lp_group
35 35
  ///
36 36
  /// \brief Interface for the CLP solver
37 37
  ///
38 38
  /// This class implements an interface for the Clp LP solver.  The
39 39
  /// Clp library is an object oriented lp solver library developed at
40 40
  /// the IBM. The CLP is part of the COIN-OR package and it can be
41 41
  /// used with Common Public License.
42 42
  class ClpLp : public LpSolver {
43 43
  protected:
44 44

	
45 45
    ClpSimplex* _prob;
46 46

	
47 47
    std::map<std::string, int> _col_names_ref;
48 48
    std::map<std::string, int> _row_names_ref;
49 49

	
50 50
  public:
51 51

	
52 52
    /// \e
53 53
    ClpLp();
54 54
    /// \e
55 55
    ClpLp(const ClpLp&);
56 56
    /// \e
57 57
    ~ClpLp();
58 58

	
59 59
    /// \e
60 60
    virtual ClpLp* newSolver() const;
61 61
    /// \e
62 62
    virtual ClpLp* cloneSolver() const;
63 63

	
64 64
  protected:
65 65

	
66 66
    mutable double* _primal_ray;
67 67
    mutable double* _dual_ray;
68 68

	
69 69
    void _init_temporals();
70 70
    void _clear_temporals();
71 71

	
72 72
  protected:
73 73

	
74 74
    virtual const char* _solverName() const;
75 75

	
76 76
    virtual int _addCol();
77 77
    virtual int _addRow();
78
    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
78 79

	
79 80
    virtual void _eraseCol(int i);
80 81
    virtual void _eraseRow(int i);
81 82

	
82 83
    virtual void _eraseColId(int i);
83 84
    virtual void _eraseRowId(int i);
84 85

	
85 86
    virtual void _getColName(int col, std::string& name) const;
86 87
    virtual void _setColName(int col, const std::string& name);
87 88
    virtual int _colByName(const std::string& name) const;
88 89

	
89 90
    virtual void _getRowName(int row, std::string& name) const;
90 91
    virtual void _setRowName(int row, const std::string& name);
91 92
    virtual int _rowByName(const std::string& name) const;
92 93

	
93 94
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
94 95
    virtual void _getRowCoeffs(int i, InsertIterator b) const;
95 96

	
96 97
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
97 98
    virtual void _getColCoeffs(int i, InsertIterator b) const;
98 99

	
99 100
    virtual void _setCoeff(int row, int col, Value value);
100 101
    virtual Value _getCoeff(int row, int col) const;
101 102

	
102 103
    virtual void _setColLowerBound(int i, Value value);
103 104
    virtual Value _getColLowerBound(int i) const;
104 105
    virtual void _setColUpperBound(int i, Value value);
105 106
    virtual Value _getColUpperBound(int i) const;
106 107

	
107 108
    virtual void _setRowLowerBound(int i, Value value);
108 109
    virtual Value _getRowLowerBound(int i) const;
109 110
    virtual void _setRowUpperBound(int i, Value value);
110 111
    virtual Value _getRowUpperBound(int i) const;
111 112

	
112 113
    virtual void _setObjCoeffs(ExprIterator, ExprIterator);
113 114
    virtual void _getObjCoeffs(InsertIterator) const;
114 115

	
115 116
    virtual void _setObjCoeff(int i, Value obj_coef);
116 117
    virtual Value _getObjCoeff(int i) const;
117 118

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

	
121 122
    virtual SolveExitStatus _solve();
122 123

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

	
126 127
    virtual Value _getPrimalValue() const;
127 128

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

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

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

	
137 138
    virtual void _clear();
138 139

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

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

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

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

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

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

	
158 159
  };
159 160

	
160 161
} //END OF NAMESPACE LEMON
161 162

	
162 163
#endif //LEMON_CLP_H
163 164

	
Show white space 512 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-2009
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 <vector>
21 21
#include <cstring>
22 22

	
23 23
#include <lemon/cplex.h>
24 24

	
25 25
extern "C" {
26 26
#include <ilcplex/cplex.h>
27 27
}
28 28

	
29 29

	
30 30
///\file
31 31
///\brief Implementation of the LEMON-CPLEX lp solver interface.
32 32
namespace lemon {
33 33

	
34 34
  CplexEnv::LicenseError::LicenseError(int status) {
35 35
    if (!CPXgeterrorstring(0, status, _message)) {
36 36
      std::strcpy(_message, "Cplex unknown error");
37 37
    }
38 38
  }
39 39

	
40 40
  CplexEnv::CplexEnv() {
41 41
    int status;
42 42
    _cnt = new int;
43 43
    _env = CPXopenCPLEX(&status);
44 44
    if (_env == 0) {
45 45
      delete _cnt;
46 46
      _cnt = 0;
47 47
      throw LicenseError(status);
48 48
    }
49 49
  }
50 50

	
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 75
    messageLevel(MESSAGE_NOTHING);
76 76
  }
77 77

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

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

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

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

	
105 105

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

	
114
  int CplexBase::_addRow(Value lb, ExprIterator b, 
115
                         ExprIterator e, Value ub) {
116
    int i = CPXgetnumrows(cplexEnv(), _prob);
117
    if (lb == -INF) {
118
      const char s = 'L';
119
      CPXnewrows(cplexEnv(), _prob, 1, &ub, &s, 0, 0);
120
    } else if (ub == INF) {
121
      const char s = 'G';
122
      CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, 0, 0);
123
    } else if (lb == ub){
124
      const char s = 'E';
125
      CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, 0, 0);
126
    } else {
127
      const char s = 'R';
128
      double len = ub - lb;
129
      CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, &len, 0);
130
    }
131

	
132
    std::vector<int> indices;
133
    std::vector<int> rowlist;
134
    std::vector<Value> values;
135

	
136
    for(ExprIterator it=b; it!=e; ++it) {
137
      indices.push_back(it->first);
138
      values.push_back(it->second);
139
      rowlist.push_back(i);
140
    }
141

	
142
    CPXchgcoeflist(cplexEnv(), _prob, values.size(),
143
                   &rowlist.front(), &indices.front(), &values.front());
144

	
145
    return i;
146
  }
114 147

	
115 148
  void CplexBase::_eraseCol(int i) {
116 149
    CPXdelcols(cplexEnv(), _prob, i, i);
117 150
  }
118 151

	
119 152
  void CplexBase::_eraseRow(int i) {
120 153
    CPXdelrows(cplexEnv(), _prob, i, i);
121 154
  }
122 155

	
123 156
  void CplexBase::_eraseColId(int i) {
124 157
    cols.eraseIndex(i);
125 158
    cols.shiftIndices(i);
126 159
  }
127 160
  void CplexBase::_eraseRowId(int i) {
128 161
    rows.eraseIndex(i);
129 162
    rows.shiftIndices(i);
130 163
  }
131 164

	
132 165
  void CplexBase::_getColName(int col, std::string &name) const {
133 166
    int size;
134 167
    CPXgetcolname(cplexEnv(), _prob, 0, 0, 0, &size, col, col);
135 168
    if (size == 0) {
136 169
      name.clear();
137 170
      return;
138 171
    }
139 172

	
140 173
    size *= -1;
141 174
    std::vector<char> buf(size);
142 175
    char *cname;
143 176
    int tmp;
144 177
    CPXgetcolname(cplexEnv(), _prob, &cname, &buf.front(), size,
145 178
                  &tmp, col, col);
146 179
    name = cname;
147 180
  }
148 181

	
149 182
  void CplexBase::_setColName(int col, const std::string &name) {
150 183
    char *cname;
151 184
    cname = const_cast<char*>(name.c_str());
152 185
    CPXchgcolname(cplexEnv(), _prob, 1, &col, &cname);
153 186
  }
154 187

	
155 188
  int CplexBase::_colByName(const std::string& name) const {
156 189
    int index;
157 190
    if (CPXgetcolindex(cplexEnv(), _prob,
158 191
                       const_cast<char*>(name.c_str()), &index) == 0) {
159 192
      return index;
160 193
    }
161 194
    return -1;
162 195
  }
163 196

	
164 197
  void CplexBase::_getRowName(int row, std::string &name) const {
165 198
    int size;
166 199
    CPXgetrowname(cplexEnv(), _prob, 0, 0, 0, &size, row, row);
167 200
    if (size == 0) {
168 201
      name.clear();
169 202
      return;
170 203
    }
171 204

	
172 205
    size *= -1;
173 206
    std::vector<char> buf(size);
174 207
    char *cname;
175 208
    int tmp;
176 209
    CPXgetrowname(cplexEnv(), _prob, &cname, &buf.front(), size,
177 210
                  &tmp, row, row);
178 211
    name = cname;
179 212
  }
180 213

	
181 214
  void CplexBase::_setRowName(int row, const std::string &name) {
182 215
    char *cname;
183 216
    cname = const_cast<char*>(name.c_str());
184 217
    CPXchgrowname(cplexEnv(), _prob, 1, &row, &cname);
185 218
  }
186 219

	
187 220
  int CplexBase::_rowByName(const std::string& name) const {
188 221
    int index;
189 222
    if (CPXgetrowindex(cplexEnv(), _prob,
190 223
                       const_cast<char*>(name.c_str()), &index) == 0) {
191 224
      return index;
192 225
    }
193 226
    return -1;
194 227
  }
195 228

	
196 229
  void CplexBase::_setRowCoeffs(int i, ExprIterator b,
197 230
                                      ExprIterator e)
198 231
  {
199 232
    std::vector<int> indices;
200 233
    std::vector<int> rowlist;
201 234
    std::vector<Value> values;
202 235

	
203 236
    for(ExprIterator it=b; it!=e; ++it) {
204 237
      indices.push_back(it->first);
205 238
      values.push_back(it->second);
206 239
      rowlist.push_back(i);
207 240
    }
208 241

	
209 242
    CPXchgcoeflist(cplexEnv(), _prob, values.size(),
210 243
                   &rowlist.front(), &indices.front(), &values.front());
211 244
  }
212 245

	
213 246
  void CplexBase::_getRowCoeffs(int i, InsertIterator b) const {
214 247
    int tmp1, tmp2, tmp3, length;
215 248
    CPXgetrows(cplexEnv(), _prob, &tmp1, &tmp2, 0, 0, 0, &length, i, i);
216 249

	
217 250
    length = -length;
218 251
    std::vector<int> indices(length);
219 252
    std::vector<double> values(length);
220 253

	
221 254
    CPXgetrows(cplexEnv(), _prob, &tmp1, &tmp2,
222 255
               &indices.front(), &values.front(),
223 256
               length, &tmp3, i, i);
224 257

	
225 258
    for (int i = 0; i < length; ++i) {
226 259
      *b = std::make_pair(indices[i], values[i]);
227 260
      ++b;
228 261
    }
229 262
  }
230 263

	
231 264
  void CplexBase::_setColCoeffs(int i, ExprIterator b, ExprIterator e) {
232 265
    std::vector<int> indices;
233 266
    std::vector<int> collist;
234 267
    std::vector<Value> values;
235 268

	
236 269
    for(ExprIterator it=b; it!=e; ++it) {
237 270
      indices.push_back(it->first);
238 271
      values.push_back(it->second);
239 272
      collist.push_back(i);
240 273
    }
241 274

	
242 275
    CPXchgcoeflist(cplexEnv(), _prob, values.size(),
243 276
                   &indices.front(), &collist.front(), &values.front());
244 277
  }
245 278

	
246 279
  void CplexBase::_getColCoeffs(int i, InsertIterator b) const {
247 280

	
248 281
    int tmp1, tmp2, tmp3, length;
249 282
    CPXgetcols(cplexEnv(), _prob, &tmp1, &tmp2, 0, 0, 0, &length, i, i);
250 283

	
251 284
    length = -length;
252 285
    std::vector<int> indices(length);
253 286
    std::vector<double> values(length);
254 287

	
255 288
    CPXgetcols(cplexEnv(), _prob, &tmp1, &tmp2,
256 289
               &indices.front(), &values.front(),
257 290
               length, &tmp3, i, i);
258 291

	
259 292
    for (int i = 0; i < length; ++i) {
260 293
      *b = std::make_pair(indices[i], values[i]);
261 294
      ++b;
262 295
    }
263 296

	
264 297
  }
265 298

	
266 299
  void CplexBase::_setCoeff(int row, int col, Value value) {
267 300
    CPXchgcoef(cplexEnv(), _prob, row, col, value);
268 301
  }
269 302

	
270 303
  CplexBase::Value CplexBase::_getCoeff(int row, int col) const {
271 304
    CplexBase::Value value;
272 305
    CPXgetcoef(cplexEnv(), _prob, row, col, &value);
273 306
    return value;
274 307
  }
275 308

	
276 309
  void CplexBase::_setColLowerBound(int i, Value value) {
277 310
    const char s = 'L';
278 311
    CPXchgbds(cplexEnv(), _prob, 1, &i, &s, &value);
279 312
  }
280 313

	
281 314
  CplexBase::Value CplexBase::_getColLowerBound(int i) const {
282 315
    CplexBase::Value res;
283 316
    CPXgetlb(cplexEnv(), _prob, &res, i, i);
284 317
    return res <= -CPX_INFBOUND ? -INF : res;
285 318
  }
286 319

	
287 320
  void CplexBase::_setColUpperBound(int i, Value value)
288 321
  {
289 322
    const char s = 'U';
290 323
    CPXchgbds(cplexEnv(), _prob, 1, &i, &s, &value);
291 324
  }
292 325

	
293 326
  CplexBase::Value CplexBase::_getColUpperBound(int i) const {
294 327
    CplexBase::Value res;
295 328
    CPXgetub(cplexEnv(), _prob, &res, i, i);
296 329
    return res >= CPX_INFBOUND ? INF : res;
297 330
  }
298 331

	
299 332
  CplexBase::Value CplexBase::_getRowLowerBound(int i) const {
300 333
    char s;
301 334
    CPXgetsense(cplexEnv(), _prob, &s, i, i);
302 335
    CplexBase::Value res;
303 336

	
304 337
    switch (s) {
305 338
    case 'G':
306 339
    case 'R':
307 340
    case 'E':
308 341
      CPXgetrhs(cplexEnv(), _prob, &res, i, i);
309 342
      return res <= -CPX_INFBOUND ? -INF : res;
310 343
    default:
311 344
      return -INF;
312 345
    }
313 346
  }
314 347

	
315 348
  CplexBase::Value CplexBase::_getRowUpperBound(int i) const {
316 349
    char s;
317 350
    CPXgetsense(cplexEnv(), _prob, &s, i, i);
318 351
    CplexBase::Value res;
319 352

	
320 353
    switch (s) {
321 354
    case 'L':
322 355
    case 'E':
323 356
      CPXgetrhs(cplexEnv(), _prob, &res, i, i);
324 357
      return res >= CPX_INFBOUND ? INF : res;
325 358
    case 'R':
326 359
      CPXgetrhs(cplexEnv(), _prob, &res, i, i);
327 360
      {
328 361
        double rng;
329 362
        CPXgetrngval(cplexEnv(), _prob, &rng, i, i);
330 363
        res += rng;
331 364
      }
332 365
      return res >= CPX_INFBOUND ? INF : res;
333 366
    default:
334 367
      return INF;
335 368
    }
336 369
  }
337 370

	
338 371
  //This is easier to implement
339 372
  void CplexBase::_set_row_bounds(int i, Value lb, Value ub) {
340 373
    if (lb == -INF) {
341 374
      const char s = 'L';
342 375
      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
343 376
      CPXchgrhs(cplexEnv(), _prob, 1, &i, &ub);
344 377
    } else if (ub == INF) {
345 378
      const char s = 'G';
346 379
      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
347 380
      CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
348 381
    } else if (lb == ub){
349 382
      const char s = 'E';
350 383
      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
351 384
      CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
352 385
    } else {
353 386
      const char s = 'R';
354 387
      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
355 388
      CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
356 389
      double len = ub - lb;
357 390
      CPXchgrngval(cplexEnv(), _prob, 1, &i, &len);
358 391
    }
359 392
  }
360 393

	
361 394
  void CplexBase::_setRowLowerBound(int i, Value lb)
362 395
  {
363 396
    LEMON_ASSERT(lb != INF, "Invalid bound");
364 397
    _set_row_bounds(i, lb, CplexBase::_getRowUpperBound(i));
365 398
  }
366 399

	
367 400
  void CplexBase::_setRowUpperBound(int i, Value ub)
368 401
  {
369 402

	
Show white space 512 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-2009
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
#ifndef LEMON_CPLEX_H
20 20
#define LEMON_CPLEX_H
21 21

	
22 22
///\file
23 23
///\brief Header of the LEMON-CPLEX lp solver interface.
24 24

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

	
27 27
struct cpxenv;
28 28
struct cpxlp;
29 29

	
30 30
namespace lemon {
31 31

	
32 32
  /// \brief Reference counted wrapper around cpxenv pointer
33 33
  ///
34 34
  /// The cplex uses environment object which is responsible for
35 35
  /// checking the proper license usage. This class provides a simple
36 36
  /// interface for share the environment object between different
37 37
  /// problems.
38 38
  class CplexEnv {
39 39
    friend class CplexBase;
40 40
  private:
41 41
    cpxenv* _env;
42 42
    mutable int* _cnt;
43 43

	
44 44
  public:
45 45

	
46 46
    /// \brief This exception is thrown when the license check is not
47 47
    /// sufficient
48 48
    class LicenseError : public Exception {
49 49
      friend class CplexEnv;
50 50
    private:
51 51

	
52 52
      LicenseError(int status);
53 53
      char _message[510];
54 54

	
55 55
    public:
56 56

	
57 57
      /// The short error message
58 58
      virtual const char* what() const throw() {
59 59
        return _message;
60 60
      }
61 61
    };
62 62

	
63 63
    /// Constructor
64 64
    CplexEnv();
65 65
    /// Shallow copy constructor
66 66
    CplexEnv(const CplexEnv&);
67 67
    /// Shallow assignement
68 68
    CplexEnv& operator=(const CplexEnv&);
69 69
    /// Destructor
70 70
    virtual ~CplexEnv();
71 71

	
72 72
  protected:
73 73

	
74 74
    cpxenv* cplexEnv() { return _env; }
75 75
    const cpxenv* cplexEnv() const { return _env; }
76 76
  };
77 77

	
78 78
  /// \brief Base interface for the CPLEX LP and MIP solver
79 79
  ///
80 80
  /// This class implements the common interface of the CPLEX LP and
81 81
  /// MIP solvers.
82 82
  /// \ingroup lp_group
83 83
  class CplexBase : virtual public LpBase {
84 84
  protected:
85 85

	
86 86
    CplexEnv _env;
87 87
    cpxlp* _prob;
88 88

	
89 89
    CplexBase();
90 90
    CplexBase(const CplexEnv&);
91 91
    CplexBase(const CplexBase &);
92 92
    virtual ~CplexBase();
93 93

	
94 94
    virtual int _addCol();
95 95
    virtual int _addRow();
96
    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
96 97

	
97 98
    virtual void _eraseCol(int i);
98 99
    virtual void _eraseRow(int i);
99 100

	
100 101
    virtual void _eraseColId(int i);
101 102
    virtual void _eraseRowId(int i);
102 103

	
103 104
    virtual void _getColName(int col, std::string& name) const;
104 105
    virtual void _setColName(int col, const std::string& name);
105 106
    virtual int _colByName(const std::string& name) const;
106 107

	
107 108
    virtual void _getRowName(int row, std::string& name) const;
108 109
    virtual void _setRowName(int row, const std::string& name);
109 110
    virtual int _rowByName(const std::string& name) const;
110 111

	
111 112
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
112 113
    virtual void _getRowCoeffs(int i, InsertIterator b) const;
113 114

	
114 115
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
115 116
    virtual void _getColCoeffs(int i, InsertIterator b) const;
116 117

	
117 118
    virtual void _setCoeff(int row, int col, Value value);
118 119
    virtual Value _getCoeff(int row, int col) const;
119 120

	
120 121
    virtual void _setColLowerBound(int i, Value value);
121 122
    virtual Value _getColLowerBound(int i) const;
122 123

	
123 124
    virtual void _setColUpperBound(int i, Value value);
124 125
    virtual Value _getColUpperBound(int i) const;
125 126

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

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

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

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

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

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

	
145 146
    virtual void _clear();
146 147

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

	
150 151
    bool _message_enabled;
151 152

	
152 153
  public:
153 154

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

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

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

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

	
172 173
  };
173 174

	
174 175
  /// \brief Interface for the CPLEX LP solver
175 176
  ///
176 177
  /// This class implements an interface for the CPLEX LP solver.
177 178
  ///\ingroup lp_group
178 179
  class CplexLp : public LpSolver, public CplexBase {
179 180
  public:
180 181
    /// \e
181 182
    CplexLp();
182 183
    /// \e
183 184
    CplexLp(const CplexEnv&);
184 185
    /// \e
185 186
    CplexLp(const CplexLp&);
186 187
    /// \e
187 188
    virtual ~CplexLp();
188 189

	
189 190
    /// \e
190 191
    virtual CplexLp* cloneSolver() const;
191 192
    /// \e
192 193
    virtual CplexLp* newSolver() const;
193 194

	
194 195
  private:
195 196

	
196 197
    // these values cannot retrieved element by element
197 198
    mutable std::vector<int> _col_status;
198 199
    mutable std::vector<int> _row_status;
199 200

	
200 201
    mutable std::vector<Value> _primal_ray;
201 202
    mutable std::vector<Value> _dual_ray;
202 203

	
203 204
    void _clear_temporals();
204 205

	
205 206
    SolveExitStatus convertStatus(int status);
206 207

	
207 208
  protected:
208 209

	
209 210
    virtual const char* _solverName() const;
210 211

	
211 212
    virtual SolveExitStatus _solve();
212 213
    virtual Value _getPrimal(int i) const;
213 214
    virtual Value _getDual(int i) const;
214 215
    virtual Value _getPrimalValue() const;
215 216

	
216 217
    virtual VarStatus _getColStatus(int i) const;
217 218
    virtual VarStatus _getRowStatus(int i) const;
218 219

	
219 220
    virtual Value _getPrimalRay(int i) const;
220 221
    virtual Value _getDualRay(int i) const;
221 222

	
222 223
    virtual ProblemType _getPrimalType() const;
223 224
    virtual ProblemType _getDualType() const;
224 225

	
225 226
  public:
226 227

	
227 228
    /// Solve with primal simplex method
228 229
    SolveExitStatus solvePrimal();
229 230

	
230 231
    /// Solve with dual simplex method
231 232
    SolveExitStatus solveDual();
232 233

	
233 234
    /// Solve with barrier method
234 235
    SolveExitStatus solveBarrier();
235 236

	
236 237
  };
237 238

	
238 239
  /// \brief Interface for the CPLEX MIP solver
239 240
  ///
240 241
  /// This class implements an interface for the CPLEX MIP solver.
241 242
  ///\ingroup lp_group
242 243
  class CplexMip : public MipSolver, public CplexBase {
243 244
  public:
244 245
    /// \e
245 246
    CplexMip();
246 247
    /// \e
247 248
    CplexMip(const CplexEnv&);
248 249
    /// \e
249 250
    CplexMip(const CplexMip&);
250 251
    /// \e
251 252
    virtual ~CplexMip();
252 253

	
253 254
    /// \e
254 255
    virtual CplexMip* cloneSolver() const;
255 256
    /// \e
256 257
    virtual CplexMip* newSolver() const;
257 258

	
258 259
  protected:
259 260

	
260 261

	
261 262
    virtual const char* _solverName() const;
262 263

	
263 264
    virtual ColTypes _getColType(int col) const;
264 265
    virtual void _setColType(int col, ColTypes col_type);
265 266

	
266 267
    virtual SolveExitStatus _solve();
267 268
    virtual ProblemType _getType() const;
268 269
    virtual Value _getSol(int i) const;
269 270
    virtual Value _getSolValue() const;
270 271

	
271 272
  };
272 273

	
273 274
} //END OF NAMESPACE LEMON
274 275

	
275 276
#endif //LEMON_CPLEX_H
276 277

	
Show white space 512 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-2009
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
///\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 34
    messageLevel(MESSAGE_NOTHING);
35 35
  }
36 36

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

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

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

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

	
62
  int GlpkBase::_addRow(Value lo, ExprIterator b, 
63
                        ExprIterator e, Value up) {
64
    int i = glp_add_rows(lp, 1);
65

	
66
    if (lo == -INF) {
67
      if (up == INF) {
68
        glp_set_row_bnds(lp, i, GLP_FR, lo, up);
69
      } else {
70
        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
71
      }    
72
    } else {
73
      if (up == INF) {
74
        glp_set_row_bnds(lp, i, GLP_LO, lo, up);
75
      } else if (lo != up) {        
76
        glp_set_row_bnds(lp, i, GLP_DB, lo, up);
77
      } else {
78
        glp_set_row_bnds(lp, i, GLP_FX, lo, up);
79
      }
80
    }
81

	
82
    std::vector<int> indexes;
83
    std::vector<Value> values;
84

	
85
    indexes.push_back(0);
86
    values.push_back(0);
87

	
88
    for(ExprIterator it = b; it != e; ++it) {
89
      indexes.push_back(it->first);
90
      values.push_back(it->second);
91
    }
92

	
93
    glp_set_mat_row(lp, i, values.size() - 1,
94
                    &indexes.front(), &values.front());
95
    return i;
96
  }
97

	
62 98
  void GlpkBase::_eraseCol(int i) {
63 99
    int ca[2];
64 100
    ca[1] = i;
65 101
    glp_del_cols(lp, 1, ca);
66 102
  }
67 103

	
68 104
  void GlpkBase::_eraseRow(int i) {
69 105
    int ra[2];
70 106
    ra[1] = i;
71 107
    glp_del_rows(lp, 1, ra);
72 108
  }
73 109

	
74 110
  void GlpkBase::_eraseColId(int i) {
75 111
    cols.eraseIndex(i);
76 112
    cols.shiftIndices(i);
77 113
  }
78 114

	
79 115
  void GlpkBase::_eraseRowId(int i) {
80 116
    rows.eraseIndex(i);
81 117
    rows.shiftIndices(i);
82 118
  }
83 119

	
84 120
  void GlpkBase::_getColName(int c, std::string& name) const {
85 121
    const char *str = glp_get_col_name(lp, c);
86 122
    if (str) name = str;
87 123
    else name.clear();
88 124
  }
89 125

	
90 126
  void GlpkBase::_setColName(int c, const std::string & name) {
91 127
    glp_set_col_name(lp, c, const_cast<char*>(name.c_str()));
92 128

	
93 129
  }
94 130

	
95 131
  int GlpkBase::_colByName(const std::string& name) const {
96 132
    int k = glp_find_col(lp, const_cast<char*>(name.c_str()));
97 133
    return k > 0 ? k : -1;
98 134
  }
99 135

	
100 136
  void GlpkBase::_getRowName(int r, std::string& name) const {
101 137
    const char *str = glp_get_row_name(lp, r);
102 138
    if (str) name = str;
103 139
    else name.clear();
104 140
  }
105 141

	
106 142
  void GlpkBase::_setRowName(int r, const std::string & name) {
107 143
    glp_set_row_name(lp, r, const_cast<char*>(name.c_str()));
108 144

	
109 145
  }
110 146

	
111 147
  int GlpkBase::_rowByName(const std::string& name) const {
112 148
    int k = glp_find_row(lp, const_cast<char*>(name.c_str()));
113 149
    return k > 0 ? k : -1;
114 150
  }
115 151

	
116 152
  void GlpkBase::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) {
117 153
    std::vector<int> indexes;
118 154
    std::vector<Value> values;
119 155

	
120 156
    indexes.push_back(0);
121 157
    values.push_back(0);
122 158

	
123 159
    for(ExprIterator it = b; it != e; ++it) {
124 160
      indexes.push_back(it->first);
125 161
      values.push_back(it->second);
126 162
    }
127 163

	
128 164
    glp_set_mat_row(lp, i, values.size() - 1,
129 165
                    &indexes.front(), &values.front());
130 166
  }
131 167

	
132 168
  void GlpkBase::_getRowCoeffs(int ix, InsertIterator b) const {
133 169
    int length = glp_get_mat_row(lp, ix, 0, 0);
134 170

	
135 171
    std::vector<int> indexes(length + 1);
136 172
    std::vector<Value> values(length + 1);
137 173

	
138 174
    glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
139 175

	
140 176
    for (int i = 1; i <= length; ++i) {
141 177
      *b = std::make_pair(indexes[i], values[i]);
142 178
      ++b;
143 179
    }
144 180
  }
145 181

	
146 182
  void GlpkBase::_setColCoeffs(int ix, ExprIterator b,
147 183
                                     ExprIterator e) {
148 184

	
149 185
    std::vector<int> indexes;
150 186
    std::vector<Value> values;
151 187

	
152 188
    indexes.push_back(0);
153 189
    values.push_back(0);
154 190

	
155 191
    for(ExprIterator it = b; it != e; ++it) {
156 192
      indexes.push_back(it->first);
157 193
      values.push_back(it->second);
158 194
    }
159 195

	
160 196
    glp_set_mat_col(lp, ix, values.size() - 1,
161 197
                    &indexes.front(), &values.front());
162 198
  }
163 199

	
164 200
  void GlpkBase::_getColCoeffs(int ix, InsertIterator b) const {
165 201
    int length = glp_get_mat_col(lp, ix, 0, 0);
166 202

	
167 203
    std::vector<int> indexes(length + 1);
168 204
    std::vector<Value> values(length + 1);
169 205

	
170 206
    glp_get_mat_col(lp, ix, &indexes.front(), &values.front());
171 207

	
172 208
    for (int i = 1; i  <= length; ++i) {
173 209
      *b = std::make_pair(indexes[i], values[i]);
174 210
      ++b;
175 211
    }
176 212
  }
177 213

	
178 214
  void GlpkBase::_setCoeff(int ix, int jx, Value value) {
179 215

	
180 216
    if (glp_get_num_cols(lp) < glp_get_num_rows(lp)) {
181 217

	
182 218
      int length = glp_get_mat_row(lp, ix, 0, 0);
183 219

	
184 220
      std::vector<int> indexes(length + 2);
185 221
      std::vector<Value> values(length + 2);
186 222

	
187 223
      glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
188 224

	
189 225
      //The following code does not suppose that the elements of the
190 226
      //array indexes are sorted
191 227
      bool found = false;
192 228
      for (int i = 1; i  <= length; ++i) {
193 229
        if (indexes[i] == jx) {
194 230
          found = true;
195 231
          values[i] = value;
196 232
          break;
197 233
        }
198 234
      }
199 235
      if (!found) {
200 236
        ++length;
201 237
        indexes[length] = jx;
202 238
        values[length] = value;
203 239
      }
204 240

	
205 241
      glp_set_mat_row(lp, ix, length, &indexes.front(), &values.front());
206 242

	
207 243
    } else {
208 244

	
209 245
      int length = glp_get_mat_col(lp, jx, 0, 0);
210 246

	
211 247
      std::vector<int> indexes(length + 2);
212 248
      std::vector<Value> values(length + 2);
213 249

	
214 250
      glp_get_mat_col(lp, jx, &indexes.front(), &values.front());
215 251

	
216 252
      //The following code does not suppose that the elements of the
217 253
      //array indexes are sorted
218 254
      bool found = false;
219 255
      for (int i = 1; i <= length; ++i) {
220 256
        if (indexes[i] == ix) {
221 257
          found = true;
222 258
          values[i] = value;
223 259
          break;
224 260
        }
225 261
      }
226 262
      if (!found) {
227 263
        ++length;
228 264
        indexes[length] = ix;
229 265
        values[length] = value;
230 266
      }
231 267

	
232 268
      glp_set_mat_col(lp, jx, length, &indexes.front(), &values.front());
233 269
    }
234 270

	
235 271
  }
236 272

	
237 273
  GlpkBase::Value GlpkBase::_getCoeff(int ix, int jx) const {
238 274

	
239 275
    int length = glp_get_mat_row(lp, ix, 0, 0);
240 276

	
241 277
    std::vector<int> indexes(length + 1);
242 278
    std::vector<Value> values(length + 1);
243 279

	
244 280
    glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
245 281

	
246 282
    for (int i = 1; i  <= length; ++i) {
247 283
      if (indexes[i] == jx) {
248 284
        return values[i];
249 285
      }
250 286
    }
251 287

	
252 288
    return 0;
253 289
  }
254 290

	
255 291
  void GlpkBase::_setColLowerBound(int i, Value lo) {
256 292
    LEMON_ASSERT(lo != INF, "Invalid bound");
257 293

	
258 294
    int b = glp_get_col_type(lp, i);
259 295
    double up = glp_get_col_ub(lp, i);
260 296
    if (lo == -INF) {
261 297
      switch (b) {
262 298
      case GLP_FR:
263 299
      case GLP_LO:
264 300
        glp_set_col_bnds(lp, i, GLP_FR, lo, up);
265 301
        break;
266 302
      case GLP_UP:
267 303
        break;
268 304
      case GLP_DB:
269 305
      case GLP_FX:
270 306
        glp_set_col_bnds(lp, i, GLP_UP, lo, up);
271 307
        break;
272 308
      default:
273 309
        break;
274 310
      }
275 311
    } else {
276 312
      switch (b) {
277 313
      case GLP_FR:
278 314
      case GLP_LO:
279 315
        glp_set_col_bnds(lp, i, GLP_LO, lo, up);
280 316
        break;
281 317
      case GLP_UP:
282 318
      case GLP_DB:
283 319
      case GLP_FX:
284 320
        if (lo == up)
285 321
          glp_set_col_bnds(lp, i, GLP_FX, lo, up);
286 322
        else
287 323
          glp_set_col_bnds(lp, i, GLP_DB, lo, up);
288 324
        break;
289 325
      default:
290 326
        break;
291 327
      }
292 328
    }
293 329
  }
294 330

	
295 331
  GlpkBase::Value GlpkBase::_getColLowerBound(int i) const {
296 332
    int b = glp_get_col_type(lp, i);
297 333
    switch (b) {
298 334
    case GLP_LO:
299 335
    case GLP_DB:
300 336
    case GLP_FX:
301 337
      return glp_get_col_lb(lp, i);
302 338
    default:
303 339
      return -INF;
304 340
    }
305 341
  }
306 342

	
307 343
  void GlpkBase::_setColUpperBound(int i, Value up) {
308 344
    LEMON_ASSERT(up != -INF, "Invalid bound");
309 345

	
310 346
    int b = glp_get_col_type(lp, i);
311 347
    double lo = glp_get_col_lb(lp, i);
312 348
    if (up == INF) {
313 349
      switch (b) {
314 350
      case GLP_FR:
315 351
      case GLP_LO:
316 352
        break;
317 353
      case GLP_UP:
Show white space 512 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
#ifndef LEMON_GLPK_H
20 20
#define LEMON_GLPK_H
21 21

	
22 22
///\file
23 23
///\brief Header of the LEMON-GLPK lp solver interface.
24 24
///\ingroup lp_group
25 25

	
26 26
#include <lemon/lp_base.h>
27 27

	
28 28
// forward declaration
29 29
#if !defined _GLP_PROB && !defined GLP_PROB
30 30
#define _GLP_PROB
31 31
#define GLP_PROB
32 32
typedef struct { double _opaque_prob; } glp_prob;
33 33
/* LP/MIP problem object */
34 34
#endif
35 35

	
36 36
namespace lemon {
37 37

	
38 38

	
39 39
  /// \brief Base interface for the GLPK LP and MIP solver
40 40
  ///
41 41
  /// This class implements the common interface of the GLPK LP and MIP solver.
42 42
  /// \ingroup lp_group
43 43
  class GlpkBase : virtual public LpBase {
44 44
  protected:
45 45

	
46 46
    typedef glp_prob LPX;
47 47
    glp_prob* lp;
48 48

	
49 49
    GlpkBase();
50 50
    GlpkBase(const GlpkBase&);
51 51
    virtual ~GlpkBase();
52 52

	
53 53
  protected:
54 54

	
55 55
    virtual int _addCol();
56 56
    virtual int _addRow();
57
    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
57 58

	
58 59
    virtual void _eraseCol(int i);
59 60
    virtual void _eraseRow(int i);
60 61

	
61 62
    virtual void _eraseColId(int i);
62 63
    virtual void _eraseRowId(int i);
63 64

	
64 65
    virtual void _getColName(int col, std::string& name) const;
65 66
    virtual void _setColName(int col, const std::string& name);
66 67
    virtual int _colByName(const std::string& name) const;
67 68

	
68 69
    virtual void _getRowName(int row, std::string& name) const;
69 70
    virtual void _setRowName(int row, const std::string& name);
70 71
    virtual int _rowByName(const std::string& name) const;
71 72

	
72 73
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
73 74
    virtual void _getRowCoeffs(int i, InsertIterator b) const;
74 75

	
75 76
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
76 77
    virtual void _getColCoeffs(int i, InsertIterator b) const;
77 78

	
78 79
    virtual void _setCoeff(int row, int col, Value value);
79 80
    virtual Value _getCoeff(int row, int col) const;
80 81

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

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

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

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

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

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

	
99 100
    virtual void _setSense(Sense);
100 101
    virtual Sense _getSense() const;
101 102

	
102 103
    virtual void _clear();
103 104

	
104 105
    virtual void _messageLevel(MessageLevel level);
105 106

	
106 107
  private:
107 108

	
108 109
    static void freeEnv();
109 110

	
110 111
    struct FreeEnvHelper {
111 112
      ~FreeEnvHelper() {
112 113
        freeEnv();
113 114
      }
114 115
    };
115 116
    
116 117
    static FreeEnvHelper freeEnvHelper;
117 118

	
118 119
  protected:
119 120
    
120 121
    int _message_level;
121 122
    
122 123
  public:
123 124

	
124 125
    ///Pointer to the underlying GLPK data structure.
125 126
    LPX *lpx() {return lp;}
126 127
    ///Const pointer to the underlying GLPK data structure.
127 128
    const LPX *lpx() const {return lp;}
128 129

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

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

	
135 136
  };
136 137

	
137 138
  /// \brief Interface for the GLPK LP solver
138 139
  ///
139 140
  /// This class implements an interface for the GLPK LP solver.
140 141
  ///\ingroup lp_group
141 142
  class GlpkLp : public LpSolver, public GlpkBase {
142 143
  public:
143 144

	
144 145
    ///\e
145 146
    GlpkLp();
146 147
    ///\e
147 148
    GlpkLp(const GlpkLp&);
148 149

	
149 150
    ///\e
150 151
    virtual GlpkLp* cloneSolver() const;
151 152
    ///\e
152 153
    virtual GlpkLp* newSolver() const;
153 154

	
154 155
  private:
155 156

	
156 157
    mutable std::vector<double> _primal_ray;
157 158
    mutable std::vector<double> _dual_ray;
158 159

	
159 160
    void _clear_temporals();
160 161

	
161 162
  protected:
162 163

	
163 164
    virtual const char* _solverName() const;
164 165

	
165 166
    virtual SolveExitStatus _solve();
166 167
    virtual Value _getPrimal(int i) const;
167 168
    virtual Value _getDual(int i) const;
168 169

	
169 170
    virtual Value _getPrimalValue() const;
170 171

	
171 172
    virtual VarStatus _getColStatus(int i) const;
172 173
    virtual VarStatus _getRowStatus(int i) const;
173 174

	
174 175
    virtual Value _getPrimalRay(int i) const;
175 176
    virtual Value _getDualRay(int i) const;
176 177

	
177 178
    virtual ProblemType _getPrimalType() const;
178 179
    virtual ProblemType _getDualType() const;
179 180

	
180 181
  public:
181 182

	
182 183
    ///Solve with primal simplex
183 184
    SolveExitStatus solvePrimal();
184 185

	
185 186
    ///Solve with dual simplex
186 187
    SolveExitStatus solveDual();
187 188

	
188 189
  private:
189 190

	
190 191
    bool _presolve;
191 192

	
192 193
  public:
193 194

	
194 195
    ///Turns on or off the presolver
195 196

	
196 197
    ///Turns on (\c b is \c true) or off (\c b is \c false) the presolver
197 198
    ///
198 199
    ///The presolver is off by default.
199 200
    void presolver(bool presolve);
200 201

	
201 202
  };
202 203

	
203 204
  /// \brief Interface for the GLPK MIP solver
204 205
  ///
205 206
  /// This class implements an interface for the GLPK MIP solver.
206 207
  ///\ingroup lp_group
207 208
  class GlpkMip : public MipSolver, public GlpkBase {
208 209
  public:
209 210

	
210 211
    ///\e
211 212
    GlpkMip();
212 213
    ///\e
213 214
    GlpkMip(const GlpkMip&);
214 215

	
215 216
    virtual GlpkMip* cloneSolver() const;
216 217
    virtual GlpkMip* newSolver() const;
217 218

	
218 219
  protected:
219 220

	
220 221
    virtual const char* _solverName() const;
221 222

	
222 223
    virtual ColTypes _getColType(int col) const;
223 224
    virtual void _setColType(int col, ColTypes col_type);
224 225

	
225 226
    virtual SolveExitStatus _solve();
226 227
    virtual ProblemType _getType() const;
227 228
    virtual Value _getSol(int i) const;
228 229
    virtual Value _getSolValue() const;
229 230

	
230 231
  };
231 232

	
232 233

	
233 234
} //END OF NAMESPACE LEMON
234 235

	
235 236
#endif //LEMON_GLPK_H
236 237

	
Show white space 512 line context
... ...
@@ -690,788 +690,802 @@
690 690
        std::map<int, Value>::const_iterator it = comps.find(id(r));
691 691
        if (it != comps.end()) {
692 692
          return it->second;
693 693
        } else {
694 694
          return 0;
695 695
        }
696 696
      }
697 697
      /// Returns the coefficient of the row
698 698
      Value& operator[](const Row& r) {
699 699
        return comps[id(r)];
700 700
      }
701 701
      /// Sets the coefficient of the row
702 702
      void set(const Row &r, const Value &v) {
703 703
        if (v != 0.0) {
704 704
          typedef std::map<int, Value>::value_type pair_type;
705 705
          comps.insert(pair_type(id(r), v));
706 706
        } else {
707 707
          comps.erase(id(r));
708 708
        }
709 709
      }
710 710
      /// \brief Removes the coefficients which's absolute value does
711 711
      /// not exceed \c epsilon. 
712 712
      void simplify(Value epsilon = 0.0) {
713 713
        std::map<int, Value>::iterator it=comps.begin();
714 714
        while (it != comps.end()) {
715 715
          std::map<int, Value>::iterator jt=it;
716 716
          ++jt;
717 717
          if (std::fabs((*it).second) <= epsilon) comps.erase(it);
718 718
          it=jt;
719 719
        }
720 720
      }
721 721

	
722 722
      void simplify(Value epsilon = 0.0) const {
723 723
        const_cast<DualExpr*>(this)->simplify(epsilon);
724 724
      }
725 725

	
726 726
      ///Sets all coefficients to 0.
727 727
      void clear() {
728 728
        comps.clear();
729 729
      }
730 730
      ///Compound assignment
731 731
      DualExpr &operator+=(const DualExpr &e) {
732 732
        for (std::map<int, Value>::const_iterator it=e.comps.begin();
733 733
             it!=e.comps.end(); ++it)
734 734
          comps[it->first]+=it->second;
735 735
        return *this;
736 736
      }
737 737
      ///Compound assignment
738 738
      DualExpr &operator-=(const DualExpr &e) {
739 739
        for (std::map<int, Value>::const_iterator it=e.comps.begin();
740 740
             it!=e.comps.end(); ++it)
741 741
          comps[it->first]-=it->second;
742 742
        return *this;
743 743
      }
744 744
      ///Multiply with a constant
745 745
      DualExpr &operator*=(const Value &v) {
746 746
        for (std::map<int, Value>::iterator it=comps.begin();
747 747
             it!=comps.end(); ++it)
748 748
          it->second*=v;
749 749
        return *this;
750 750
      }
751 751
      ///Division with a constant
752 752
      DualExpr &operator/=(const Value &v) {
753 753
        for (std::map<int, Value>::iterator it=comps.begin();
754 754
             it!=comps.end(); ++it)
755 755
          it->second/=v;
756 756
        return *this;
757 757
      }
758 758

	
759 759
      ///Iterator over the expression
760 760
      
761 761
      ///The iterator iterates over the terms of the expression. 
762 762
      /// 
763 763
      ///\code
764 764
      ///double s=0;
765 765
      ///for(LpBase::DualExpr::CoeffIt i(e);i!=INVALID;++i)
766 766
      ///  s+= *i * dual(i);
767 767
      ///\endcode
768 768
      class CoeffIt {
769 769
      private:
770 770

	
771 771
        std::map<int, Value>::iterator _it, _end;
772 772

	
773 773
      public:
774 774

	
775 775
        /// Sets the iterator to the first term
776 776
        
777 777
        /// Sets the iterator to the first term of the expression.
778 778
        ///
779 779
        CoeffIt(DualExpr& e)
780 780
          : _it(e.comps.begin()), _end(e.comps.end()){}
781 781

	
782 782
        /// Convert the iterator to the row of the term
783 783
        operator Row() const {
784 784
          return rowFromId(_it->first);
785 785
        }
786 786

	
787 787
        /// Returns the coefficient of the term
788 788
        Value& operator*() { return _it->second; }
789 789

	
790 790
        /// Returns the coefficient of the term
791 791
        const Value& operator*() const { return _it->second; }
792 792

	
793 793
        /// Next term
794 794
        
795 795
        /// Assign the iterator to the next term.
796 796
        ///
797 797
        CoeffIt& operator++() { ++_it; return *this; }
798 798

	
799 799
        /// Equality operator
800 800
        bool operator==(Invalid) const { return _it == _end; }
801 801
        /// Inequality operator
802 802
        bool operator!=(Invalid) const { return _it != _end; }
803 803
      };
804 804

	
805 805
      ///Iterator over the expression
806 806
      
807 807
      ///The iterator iterates over the terms of the expression. 
808 808
      /// 
809 809
      ///\code
810 810
      ///double s=0;
811 811
      ///for(LpBase::DualExpr::ConstCoeffIt i(e);i!=INVALID;++i)
812 812
      ///  s+= *i * dual(i);
813 813
      ///\endcode
814 814
      class ConstCoeffIt {
815 815
      private:
816 816

	
817 817
        std::map<int, Value>::const_iterator _it, _end;
818 818

	
819 819
      public:
820 820

	
821 821
        /// Sets the iterator to the first term
822 822
        
823 823
        /// Sets the iterator to the first term of the expression.
824 824
        ///
825 825
        ConstCoeffIt(const DualExpr& e)
826 826
          : _it(e.comps.begin()), _end(e.comps.end()){}
827 827

	
828 828
        /// Convert the iterator to the row of the term
829 829
        operator Row() const {
830 830
          return rowFromId(_it->first);
831 831
        }
832 832

	
833 833
        /// Returns the coefficient of the term
834 834
        const Value& operator*() const { return _it->second; }
835 835

	
836 836
        /// Next term
837 837
        
838 838
        /// Assign the iterator to the next term.
839 839
        ///
840 840
        ConstCoeffIt& operator++() { ++_it; return *this; }
841 841

	
842 842
        /// Equality operator
843 843
        bool operator==(Invalid) const { return _it == _end; }
844 844
        /// Inequality operator
845 845
        bool operator!=(Invalid) const { return _it != _end; }
846 846
      };
847 847
    };
848 848

	
849 849

	
850 850
  protected:
851 851

	
852 852
    class InsertIterator {
853 853
    private:
854 854

	
855 855
      std::map<int, Value>& _host;
856 856
      const _solver_bits::VarIndex& _index;
857 857

	
858 858
    public:
859 859

	
860 860
      typedef std::output_iterator_tag iterator_category;
861 861
      typedef void difference_type;
862 862
      typedef void value_type;
863 863
      typedef void reference;
864 864
      typedef void pointer;
865 865

	
866 866
      InsertIterator(std::map<int, Value>& host,
867 867
                   const _solver_bits::VarIndex& index)
868 868
        : _host(host), _index(index) {}
869 869

	
870 870
      InsertIterator& operator=(const std::pair<int, Value>& value) {
871 871
        typedef std::map<int, Value>::value_type pair_type;
872 872
        _host.insert(pair_type(_index[value.first], value.second));
873 873
        return *this;
874 874
      }
875 875

	
876 876
      InsertIterator& operator*() { return *this; }
877 877
      InsertIterator& operator++() { return *this; }
878 878
      InsertIterator operator++(int) { return *this; }
879 879

	
880 880
    };
881 881

	
882 882
    class ExprIterator {
883 883
    private:
884 884
      std::map<int, Value>::const_iterator _host_it;
885 885
      const _solver_bits::VarIndex& _index;
886 886
    public:
887 887

	
888 888
      typedef std::bidirectional_iterator_tag iterator_category;
889 889
      typedef std::ptrdiff_t difference_type;
890 890
      typedef const std::pair<int, Value> value_type;
891 891
      typedef value_type reference;
892 892

	
893 893
      class pointer {
894 894
      public:
895 895
        pointer(value_type& _value) : value(_value) {}
896 896
        value_type* operator->() { return &value; }
897 897
      private:
898 898
        value_type value;
899 899
      };
900 900

	
901 901
      ExprIterator(const std::map<int, Value>::const_iterator& host_it,
902 902
                   const _solver_bits::VarIndex& index)
903 903
        : _host_it(host_it), _index(index) {}
904 904

	
905 905
      reference operator*() {
906 906
        return std::make_pair(_index(_host_it->first), _host_it->second);
907 907
      }
908 908

	
909 909
      pointer operator->() {
910 910
        return pointer(operator*());
911 911
      }
912 912

	
913 913
      ExprIterator& operator++() { ++_host_it; return *this; }
914 914
      ExprIterator operator++(int) {
915 915
        ExprIterator tmp(*this); ++_host_it; return tmp;
916 916
      }
917 917

	
918 918
      ExprIterator& operator--() { --_host_it; return *this; }
919 919
      ExprIterator operator--(int) {
920 920
        ExprIterator tmp(*this); --_host_it; return tmp;
921 921
      }
922 922

	
923 923
      bool operator==(const ExprIterator& it) const {
924 924
        return _host_it == it._host_it;
925 925
      }
926 926

	
927 927
      bool operator!=(const ExprIterator& it) const {
928 928
        return _host_it != it._host_it;
929 929
      }
930 930

	
931 931
    };
932 932

	
933 933
  protected:
934 934

	
935 935
    //Abstract virtual functions
936 936

	
937 937
    virtual int _addColId(int col) { return cols.addIndex(col); }
938 938
    virtual int _addRowId(int row) { return rows.addIndex(row); }
939 939

	
940 940
    virtual void _eraseColId(int col) { cols.eraseIndex(col); }
941 941
    virtual void _eraseRowId(int row) { rows.eraseIndex(row); }
942 942

	
943 943
    virtual int _addCol() = 0;
944 944
    virtual int _addRow() = 0;
945 945

	
946
    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
947
      int row = _addRow();
948
      _setRowCoeffs(row, b, e);
949
      _setRowLowerBound(row, l);
950
      _setRowUpperBound(row, u);
951
      return row;
952
    }
953

	
946 954
    virtual void _eraseCol(int col) = 0;
947 955
    virtual void _eraseRow(int row) = 0;
948 956

	
949 957
    virtual void _getColName(int col, std::string& name) const = 0;
950 958
    virtual void _setColName(int col, const std::string& name) = 0;
951 959
    virtual int _colByName(const std::string& name) const = 0;
952 960

	
953 961
    virtual void _getRowName(int row, std::string& name) const = 0;
954 962
    virtual void _setRowName(int row, const std::string& name) = 0;
955 963
    virtual int _rowByName(const std::string& name) const = 0;
956 964

	
957 965
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e) = 0;
958 966
    virtual void _getRowCoeffs(int i, InsertIterator b) const = 0;
959 967

	
960 968
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e) = 0;
961 969
    virtual void _getColCoeffs(int i, InsertIterator b) const = 0;
962 970

	
963 971
    virtual void _setCoeff(int row, int col, Value value) = 0;
964 972
    virtual Value _getCoeff(int row, int col) const = 0;
965 973

	
966 974
    virtual void _setColLowerBound(int i, Value value) = 0;
967 975
    virtual Value _getColLowerBound(int i) const = 0;
968 976

	
969 977
    virtual void _setColUpperBound(int i, Value value) = 0;
970 978
    virtual Value _getColUpperBound(int i) const = 0;
971 979

	
972 980
    virtual void _setRowLowerBound(int i, Value value) = 0;
973 981
    virtual Value _getRowLowerBound(int i) const = 0;
974 982

	
975 983
    virtual void _setRowUpperBound(int i, Value value) = 0;
976 984
    virtual Value _getRowUpperBound(int i) const = 0;
977 985

	
978 986
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e) = 0;
979 987
    virtual void _getObjCoeffs(InsertIterator b) const = 0;
980 988

	
981 989
    virtual void _setObjCoeff(int i, Value obj_coef) = 0;
982 990
    virtual Value _getObjCoeff(int i) const = 0;
983 991

	
984 992
    virtual void _setSense(Sense) = 0;
985 993
    virtual Sense _getSense() const = 0;
986 994

	
987 995
    virtual void _clear() = 0;
988 996

	
989 997
    virtual const char* _solverName() const = 0;
990 998

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

	
993 1001
    //Own protected stuff
994 1002

	
995 1003
    //Constant component of the objective function
996 1004
    Value obj_const_comp;
997 1005

	
998 1006
    LpBase() : rows(), cols(), obj_const_comp(0) {}
999 1007

	
1000 1008
  public:
1001 1009

	
1002 1010
    /// Virtual destructor
1003 1011
    virtual ~LpBase() {}
1004 1012

	
1005 1013
    ///Gives back the name of the solver.
1006 1014
    const char* solverName() const {return _solverName();}
1007 1015

	
1008 1016
    ///\name Build Up and Modify the LP
1009 1017

	
1010 1018
    ///@{
1011 1019

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

	
1015 1023
    ///\brief Adds several new columns (i.e variables) at once
1016 1024
    ///
1017 1025
    ///This magic function takes a container as its argument and fills
1018 1026
    ///its elements with new columns (i.e. variables)
1019 1027
    ///\param t can be
1020 1028
    ///- a standard STL compatible iterable container with
1021 1029
    ///\ref Col as its \c values_type like
1022 1030
    ///\code
1023 1031
    ///std::vector<LpBase::Col>
1024 1032
    ///std::list<LpBase::Col>
1025 1033
    ///\endcode
1026 1034
    ///- a standard STL compatible iterable container with
1027 1035
    ///\ref Col as its \c mapped_type like
1028 1036
    ///\code
1029 1037
    ///std::map<AnyType,LpBase::Col>
1030 1038
    ///\endcode
1031 1039
    ///- an iterable lemon \ref concepts::WriteMap "write map" like
1032 1040
    ///\code
1033 1041
    ///ListGraph::NodeMap<LpBase::Col>
1034 1042
    ///ListGraph::ArcMap<LpBase::Col>
1035 1043
    ///\endcode
1036 1044
    ///\return The number of the created column.
1037 1045
#ifdef DOXYGEN
1038 1046
    template<class T>
1039 1047
    int addColSet(T &t) { return 0;}
1040 1048
#else
1041 1049
    template<class T>
1042 1050
    typename enable_if<typename T::value_type::LpCol,int>::type
1043 1051
    addColSet(T &t,dummy<0> = 0) {
1044 1052
      int s=0;
1045 1053
      for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addCol();s++;}
1046 1054
      return s;
1047 1055
    }
1048 1056
    template<class T>
1049 1057
    typename enable_if<typename T::value_type::second_type::LpCol,
1050 1058
                       int>::type
1051 1059
    addColSet(T &t,dummy<1> = 1) {
1052 1060
      int s=0;
1053 1061
      for(typename T::iterator i=t.begin();i!=t.end();++i) {
1054 1062
        i->second=addCol();
1055 1063
        s++;
1056 1064
      }
1057 1065
      return s;
1058 1066
    }
1059 1067
    template<class T>
1060 1068
    typename enable_if<typename T::MapIt::Value::LpCol,
1061 1069
                       int>::type
1062 1070
    addColSet(T &t,dummy<2> = 2) {
1063 1071
      int s=0;
1064 1072
      for(typename T::MapIt i(t); i!=INVALID; ++i)
1065 1073
        {
1066 1074
          i.set(addCol());
1067 1075
          s++;
1068 1076
        }
1069 1077
      return s;
1070 1078
    }
1071 1079
#endif
1072 1080

	
1073 1081
    ///Set a column (i.e a dual constraint) of the LP
1074 1082

	
1075 1083
    ///\param c is the column to be modified
1076 1084
    ///\param e is a dual linear expression (see \ref DualExpr)
1077 1085
    ///a better one.
1078 1086
    void col(Col c, const DualExpr &e) {
1079 1087
      e.simplify();
1080 1088
      _setColCoeffs(cols(id(c)), ExprIterator(e.comps.begin(), rows),
1081 1089
                    ExprIterator(e.comps.end(), rows));
1082 1090
    }
1083 1091

	
1084 1092
    ///Get a column (i.e a dual constraint) of the LP
1085 1093

	
1086 1094
    ///\param c is the column to get
1087 1095
    ///\return the dual expression associated to the column
1088 1096
    DualExpr col(Col c) const {
1089 1097
      DualExpr e;
1090 1098
      _getColCoeffs(cols(id(c)), InsertIterator(e.comps, rows));
1091 1099
      return e;
1092 1100
    }
1093 1101

	
1094 1102
    ///Add a new column to the LP
1095 1103

	
1096 1104
    ///\param e is a dual linear expression (see \ref DualExpr)
1097 1105
    ///\param o is the corresponding component of the objective
1098 1106
    ///function. It is 0 by default.
1099 1107
    ///\return The created column.
1100 1108
    Col addCol(const DualExpr &e, Value o = 0) {
1101 1109
      Col c=addCol();
1102 1110
      col(c,e);
1103 1111
      objCoeff(c,o);
1104 1112
      return c;
1105 1113
    }
1106 1114

	
1107 1115
    ///Add a new empty row (i.e a new constraint) to the LP
1108 1116

	
1109 1117
    ///This function adds a new empty row (i.e a new constraint) to the LP.
1110 1118
    ///\return The created row
1111 1119
    Row addRow() { Row r; r._id = _addRowId(_addRow()); return r;}
1112 1120

	
1113 1121
    ///\brief Add several new rows (i.e constraints) at once
1114 1122
    ///
1115 1123
    ///This magic function takes a container as its argument and fills
1116 1124
    ///its elements with new row (i.e. variables)
1117 1125
    ///\param t can be
1118 1126
    ///- a standard STL compatible iterable container with
1119 1127
    ///\ref Row as its \c values_type like
1120 1128
    ///\code
1121 1129
    ///std::vector<LpBase::Row>
1122 1130
    ///std::list<LpBase::Row>
1123 1131
    ///\endcode
1124 1132
    ///- a standard STL compatible iterable container with
1125 1133
    ///\ref Row as its \c mapped_type like
1126 1134
    ///\code
1127 1135
    ///std::map<AnyType,LpBase::Row>
1128 1136
    ///\endcode
1129 1137
    ///- an iterable lemon \ref concepts::WriteMap "write map" like
1130 1138
    ///\code
1131 1139
    ///ListGraph::NodeMap<LpBase::Row>
1132 1140
    ///ListGraph::ArcMap<LpBase::Row>
1133 1141
    ///\endcode
1134 1142
    ///\return The number of rows created.
1135 1143
#ifdef DOXYGEN
1136 1144
    template<class T>
1137 1145
    int addRowSet(T &t) { return 0;}
1138 1146
#else
1139 1147
    template<class T>
1140 1148
    typename enable_if<typename T::value_type::LpRow,int>::type
1141 1149
    addRowSet(T &t, dummy<0> = 0) {
1142 1150
      int s=0;
1143 1151
      for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addRow();s++;}
1144 1152
      return s;
1145 1153
    }
1146 1154
    template<class T>
1147 1155
    typename enable_if<typename T::value_type::second_type::LpRow, int>::type
1148 1156
    addRowSet(T &t, dummy<1> = 1) {
1149 1157
      int s=0;
1150 1158
      for(typename T::iterator i=t.begin();i!=t.end();++i) {
1151 1159
        i->second=addRow();
1152 1160
        s++;
1153 1161
      }
1154 1162
      return s;
1155 1163
    }
1156 1164
    template<class T>
1157 1165
    typename enable_if<typename T::MapIt::Value::LpRow, int>::type
1158 1166
    addRowSet(T &t, dummy<2> = 2) {
1159 1167
      int s=0;
1160 1168
      for(typename T::MapIt i(t); i!=INVALID; ++i)
1161 1169
        {
1162 1170
          i.set(addRow());
1163 1171
          s++;
1164 1172
        }
1165 1173
      return s;
1166 1174
    }
1167 1175
#endif
1168 1176

	
1169 1177
    ///Set a row (i.e a constraint) of the LP
1170 1178

	
1171 1179
    ///\param r is the row to be modified
1172 1180
    ///\param l is lower bound (-\ref INF means no bound)
1173 1181
    ///\param e is a linear expression (see \ref Expr)
1174 1182
    ///\param u is the upper bound (\ref INF means no bound)
1175 1183
    void row(Row r, Value l, const Expr &e, Value u) {
1176 1184
      e.simplify();
1177 1185
      _setRowCoeffs(rows(id(r)), ExprIterator(e.comps.begin(), cols),
1178 1186
                    ExprIterator(e.comps.end(), cols));
1179 1187
      _setRowLowerBound(rows(id(r)),l - *e);
1180 1188
      _setRowUpperBound(rows(id(r)),u - *e);
1181 1189
    }
1182 1190

	
1183 1191
    ///Set a row (i.e a constraint) of the LP
1184 1192

	
1185 1193
    ///\param r is the row to be modified
1186 1194
    ///\param c is a linear expression (see \ref Constr)
1187 1195
    void row(Row r, const Constr &c) {
1188 1196
      row(r, c.lowerBounded()?c.lowerBound():-INF,
1189 1197
          c.expr(), c.upperBounded()?c.upperBound():INF);
1190 1198
    }
1191 1199

	
1192 1200

	
1193 1201
    ///Get a row (i.e a constraint) of the LP
1194 1202

	
1195 1203
    ///\param r is the row to get
1196 1204
    ///\return the expression associated to the row
1197 1205
    Expr row(Row r) const {
1198 1206
      Expr e;
1199 1207
      _getRowCoeffs(rows(id(r)), InsertIterator(e.comps, cols));
1200 1208
      return e;
1201 1209
    }
1202 1210

	
1203 1211
    ///Add a new row (i.e a new constraint) to the LP
1204 1212

	
1205 1213
    ///\param l is the lower bound (-\ref INF means no bound)
1206 1214
    ///\param e is a linear expression (see \ref Expr)
1207 1215
    ///\param u is the upper bound (\ref INF means no bound)
1208 1216
    ///\return The created row.
1209 1217
    Row addRow(Value l,const Expr &e, Value u) {
1210
      Row r=addRow();
1211
      row(r,l,e,u);
1218
      Row r;
1219
      e.simplify();
1220
      r._id = _addRowId(_addRow(l - *e, ExprIterator(e.comps.begin(), cols),
1221
                                ExprIterator(e.comps.end(), cols), u - *e));
1212 1222
      return r;
1213 1223
    }
1214 1224

	
1215 1225
    ///Add a new row (i.e a new constraint) to the LP
1216 1226

	
1217 1227
    ///\param c is a linear expression (see \ref Constr)
1218 1228
    ///\return The created row.
1219 1229
    Row addRow(const Constr &c) {
1220
      Row r=addRow();
1221
      row(r,c);
1230
      Row r;
1231
      c.expr().simplify();
1232
      r._id = _addRowId(_addRow(c.lowerBounded()?c.lowerBound():-INF, 
1233
                                ExprIterator(c.expr().comps.begin(), cols),
1234
                                ExprIterator(c.expr().comps.end(), cols),
1235
                                c.upperBounded()?c.upperBound():INF));
1222 1236
      return r;
1223 1237
    }
1224 1238
    ///Erase a column (i.e a variable) from the LP
1225 1239

	
1226 1240
    ///\param c is the column to be deleted
1227 1241
    void erase(Col c) {
1228 1242
      _eraseCol(cols(id(c)));
1229 1243
      _eraseColId(cols(id(c)));
1230 1244
    }
1231 1245
    ///Erase a row (i.e a constraint) from the LP
1232 1246

	
1233 1247
    ///\param r is the row to be deleted
1234 1248
    void erase(Row r) {
1235 1249
      _eraseRow(rows(id(r)));
1236 1250
      _eraseRowId(rows(id(r)));
1237 1251
    }
1238 1252

	
1239 1253
    /// Get the name of a column
1240 1254

	
1241 1255
    ///\param c is the coresponding column
1242 1256
    ///\return The name of the colunm
1243 1257
    std::string colName(Col c) const {
1244 1258
      std::string name;
1245 1259
      _getColName(cols(id(c)), name);
1246 1260
      return name;
1247 1261
    }
1248 1262

	
1249 1263
    /// Set the name of a column
1250 1264

	
1251 1265
    ///\param c is the coresponding column
1252 1266
    ///\param name The name to be given
1253 1267
    void colName(Col c, const std::string& name) {
1254 1268
      _setColName(cols(id(c)), name);
1255 1269
    }
1256 1270

	
1257 1271
    /// Get the column by its name
1258 1272

	
1259 1273
    ///\param name The name of the column
1260 1274
    ///\return the proper column or \c INVALID
1261 1275
    Col colByName(const std::string& name) const {
1262 1276
      int k = _colByName(name);
1263 1277
      return k != -1 ? Col(cols[k]) : Col(INVALID);
1264 1278
    }
1265 1279

	
1266 1280
    /// Get the name of a row
1267 1281

	
1268 1282
    ///\param r is the coresponding row
1269 1283
    ///\return The name of the row
1270 1284
    std::string rowName(Row r) const {
1271 1285
      std::string name;
1272 1286
      _getRowName(rows(id(r)), name);
1273 1287
      return name;
1274 1288
    }
1275 1289

	
1276 1290
    /// Set the name of a row
1277 1291

	
1278 1292
    ///\param r is the coresponding row
1279 1293
    ///\param name The name to be given
1280 1294
    void rowName(Row r, const std::string& name) {
1281 1295
      _setRowName(rows(id(r)), name);
1282 1296
    }
1283 1297

	
1284 1298
    /// Get the row by its name
1285 1299

	
1286 1300
    ///\param name The name of the row
1287 1301
    ///\return the proper row or \c INVALID
1288 1302
    Row rowByName(const std::string& name) const {
1289 1303
      int k = _rowByName(name);
1290 1304
      return k != -1 ? Row(rows[k]) : Row(INVALID);
1291 1305
    }
1292 1306

	
1293 1307
    /// Set an element of the coefficient matrix of the LP
1294 1308

	
1295 1309
    ///\param r is the row of the element to be modified
1296 1310
    ///\param c is the column of the element to be modified
1297 1311
    ///\param val is the new value of the coefficient
1298 1312
    void coeff(Row r, Col c, Value val) {
1299 1313
      _setCoeff(rows(id(r)),cols(id(c)), val);
1300 1314
    }
1301 1315

	
1302 1316
    /// Get an element of the coefficient matrix of the LP
1303 1317

	
1304 1318
    ///\param r is the row of the element
1305 1319
    ///\param c is the column of the element
1306 1320
    ///\return the corresponding coefficient
1307 1321
    Value coeff(Row r, Col c) const {
1308 1322
      return _getCoeff(rows(id(r)),cols(id(c)));
1309 1323
    }
1310 1324

	
1311 1325
    /// Set the lower bound of a column (i.e a variable)
1312 1326

	
1313 1327
    /// The lower bound of a variable (column) has to be given by an
1314 1328
    /// extended number of type Value, i.e. a finite number of type
1315 1329
    /// Value or -\ref INF.
1316 1330
    void colLowerBound(Col c, Value value) {
1317 1331
      _setColLowerBound(cols(id(c)),value);
1318 1332
    }
1319 1333

	
1320 1334
    /// Get the lower bound of a column (i.e a variable)
1321 1335

	
1322 1336
    /// This function returns the lower bound for column (variable) \c c
1323 1337
    /// (this might be -\ref INF as well).
1324 1338
    ///\return The lower bound for column \c c
1325 1339
    Value colLowerBound(Col c) const {
1326 1340
      return _getColLowerBound(cols(id(c)));
1327 1341
    }
1328 1342

	
1329 1343
    ///\brief Set the lower bound of  several columns
1330 1344
    ///(i.e variables) at once
1331 1345
    ///
1332 1346
    ///This magic function takes a container as its argument
1333 1347
    ///and applies the function on all of its elements.
1334 1348
    ///The lower bound of a variable (column) has to be given by an
1335 1349
    ///extended number of type Value, i.e. a finite number of type
1336 1350
    ///Value or -\ref INF.
1337 1351
#ifdef DOXYGEN
1338 1352
    template<class T>
1339 1353
    void colLowerBound(T &t, Value value) { return 0;}
1340 1354
#else
1341 1355
    template<class T>
1342 1356
    typename enable_if<typename T::value_type::LpCol,void>::type
1343 1357
    colLowerBound(T &t, Value value,dummy<0> = 0) {
1344 1358
      for(typename T::iterator i=t.begin();i!=t.end();++i) {
1345 1359
        colLowerBound(*i, value);
1346 1360
      }
1347 1361
    }
1348 1362
    template<class T>
1349 1363
    typename enable_if<typename T::value_type::second_type::LpCol,
1350 1364
                       void>::type
1351 1365
    colLowerBound(T &t, Value value,dummy<1> = 1) {
1352 1366
      for(typename T::iterator i=t.begin();i!=t.end();++i) {
1353 1367
        colLowerBound(i->second, value);
1354 1368
      }
1355 1369
    }
1356 1370
    template<class T>
1357 1371
    typename enable_if<typename T::MapIt::Value::LpCol,
1358 1372
                       void>::type
1359 1373
    colLowerBound(T &t, Value value,dummy<2> = 2) {
1360 1374
      for(typename T::MapIt i(t); i!=INVALID; ++i){
1361 1375
        colLowerBound(*i, value);
1362 1376
      }
1363 1377
    }
1364 1378
#endif
1365 1379

	
1366 1380
    /// Set the upper bound of a column (i.e a variable)
1367 1381

	
1368 1382
    /// The upper bound of a variable (column) has to be given by an
1369 1383
    /// extended number of type Value, i.e. a finite number of type
1370 1384
    /// Value or \ref INF.
1371 1385
    void colUpperBound(Col c, Value value) {
1372 1386
      _setColUpperBound(cols(id(c)),value);
1373 1387
    };
1374 1388

	
1375 1389
    /// Get the upper bound of a column (i.e a variable)
1376 1390

	
1377 1391
    /// This function returns the upper bound for column (variable) \c c
1378 1392
    /// (this might be \ref INF as well).
1379 1393
    /// \return The upper bound for column \c c
1380 1394
    Value colUpperBound(Col c) const {
1381 1395
      return _getColUpperBound(cols(id(c)));
1382 1396
    }
1383 1397

	
1384 1398
    ///\brief Set the upper bound of  several columns
1385 1399
    ///(i.e variables) at once
1386 1400
    ///
1387 1401
    ///This magic function takes a container as its argument
1388 1402
    ///and applies the function on all of its elements.
1389 1403
    ///The upper bound of a variable (column) has to be given by an
1390 1404
    ///extended number of type Value, i.e. a finite number of type
1391 1405
    ///Value or \ref INF.
1392 1406
#ifdef DOXYGEN
1393 1407
    template<class T>
1394 1408
    void colUpperBound(T &t, Value value) { return 0;}
1395 1409
#else
1396 1410
    template<class T1>
1397 1411
    typename enable_if<typename T1::value_type::LpCol,void>::type
1398 1412
    colUpperBound(T1 &t, Value value,dummy<0> = 0) {
1399 1413
      for(typename T1::iterator i=t.begin();i!=t.end();++i) {
1400 1414
        colUpperBound(*i, value);
1401 1415
      }
1402 1416
    }
1403 1417
    template<class T1>
1404 1418
    typename enable_if<typename T1::value_type::second_type::LpCol,
1405 1419
                       void>::type
1406 1420
    colUpperBound(T1 &t, Value value,dummy<1> = 1) {
1407 1421
      for(typename T1::iterator i=t.begin();i!=t.end();++i) {
1408 1422
        colUpperBound(i->second, value);
1409 1423
      }
1410 1424
    }
1411 1425
    template<class T1>
1412 1426
    typename enable_if<typename T1::MapIt::Value::LpCol,
1413 1427
                       void>::type
1414 1428
    colUpperBound(T1 &t, Value value,dummy<2> = 2) {
1415 1429
      for(typename T1::MapIt i(t); i!=INVALID; ++i){
1416 1430
        colUpperBound(*i, value);
1417 1431
      }
1418 1432
    }
1419 1433
#endif
1420 1434

	
1421 1435
    /// Set the lower and the upper bounds of a column (i.e a variable)
1422 1436

	
1423 1437
    /// The lower and the upper bounds of
1424 1438
    /// a variable (column) have to be given by an
1425 1439
    /// extended number of type Value, i.e. a finite number of type
1426 1440
    /// Value, -\ref INF or \ref INF.
1427 1441
    void colBounds(Col c, Value lower, Value upper) {
1428 1442
      _setColLowerBound(cols(id(c)),lower);
1429 1443
      _setColUpperBound(cols(id(c)),upper);
1430 1444
    }
1431 1445

	
1432 1446
    ///\brief Set the lower and the upper bound of several columns
1433 1447
    ///(i.e variables) at once
1434 1448
    ///
1435 1449
    ///This magic function takes a container as its argument
1436 1450
    ///and applies the function on all of its elements.
1437 1451
    /// The lower and the upper bounds of
1438 1452
    /// a variable (column) have to be given by an
1439 1453
    /// extended number of type Value, i.e. a finite number of type
1440 1454
    /// Value, -\ref INF or \ref INF.
1441 1455
#ifdef DOXYGEN
1442 1456
    template<class T>
1443 1457
    void colBounds(T &t, Value lower, Value upper) { return 0;}
1444 1458
#else
1445 1459
    template<class T2>
1446 1460
    typename enable_if<typename T2::value_type::LpCol,void>::type
1447 1461
    colBounds(T2 &t, Value lower, Value upper,dummy<0> = 0) {
1448 1462
      for(typename T2::iterator i=t.begin();i!=t.end();++i) {
1449 1463
        colBounds(*i, lower, upper);
1450 1464
      }
1451 1465
    }
1452 1466
    template<class T2>
1453 1467
    typename enable_if<typename T2::value_type::second_type::LpCol, void>::type
1454 1468
    colBounds(T2 &t, Value lower, Value upper,dummy<1> = 1) {
1455 1469
      for(typename T2::iterator i=t.begin();i!=t.end();++i) {
1456 1470
        colBounds(i->second, lower, upper);
1457 1471
      }
1458 1472
    }
1459 1473
    template<class T2>
1460 1474
    typename enable_if<typename T2::MapIt::Value::LpCol, void>::type
1461 1475
    colBounds(T2 &t, Value lower, Value upper,dummy<2> = 2) {
1462 1476
      for(typename T2::MapIt i(t); i!=INVALID; ++i){
1463 1477
        colBounds(*i, lower, upper);
1464 1478
      }
1465 1479
    }
1466 1480
#endif
1467 1481

	
1468 1482
    /// Set the lower bound of a row (i.e a constraint)
1469 1483

	
1470 1484
    /// The lower bound of a constraint (row) has to be given by an
1471 1485
    /// extended number of type Value, i.e. a finite number of type
1472 1486
    /// Value or -\ref INF.
1473 1487
    void rowLowerBound(Row r, Value value) {
1474 1488
      _setRowLowerBound(rows(id(r)),value);
1475 1489
    }
1476 1490

	
1477 1491
    /// Get the lower bound of a row (i.e a constraint)
Show white space 512 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 <lemon/lp_skeleton.h>
20 20

	
21 21
///\file
22 22
///\brief A skeleton file to implement LP solver interfaces
23 23
namespace lemon {
24 24

	
25 25
  int SkeletonSolverBase::_addCol()
26 26
  {
27 27
    return ++col_num;
28 28
  }
29 29

	
30 30
  int SkeletonSolverBase::_addRow()
31 31
  {
32 32
    return ++row_num;
33 33
  }
34 34

	
35
  int SkeletonSolverBase::_addRow(Value, ExprIterator, ExprIterator, Value)
36
  {
37
    return ++row_num;
38
  }
39

	
35 40
  void SkeletonSolverBase::_eraseCol(int) {}
36 41
  void SkeletonSolverBase::_eraseRow(int) {}
37 42

	
38 43
  void SkeletonSolverBase::_getColName(int, std::string &) const {}
39 44
  void SkeletonSolverBase::_setColName(int, const std::string &) {}
40 45
  int SkeletonSolverBase::_colByName(const std::string&) const { return -1; }
41 46

	
42 47
  void SkeletonSolverBase::_getRowName(int, std::string &) const {}
43 48
  void SkeletonSolverBase::_setRowName(int, const std::string &) {}
44 49
  int SkeletonSolverBase::_rowByName(const std::string&) const { return -1; }
45 50

	
46 51
  void SkeletonSolverBase::_setRowCoeffs(int, ExprIterator, ExprIterator) {}
47 52
  void SkeletonSolverBase::_getRowCoeffs(int, InsertIterator) const {}
48 53

	
49 54
  void SkeletonSolverBase::_setColCoeffs(int, ExprIterator, ExprIterator) {}
50 55
  void SkeletonSolverBase::_getColCoeffs(int, InsertIterator) const {}
51 56

	
52 57
  void SkeletonSolverBase::_setCoeff(int, int, Value) {}
53 58
  SkeletonSolverBase::Value SkeletonSolverBase::_getCoeff(int, int) const
54 59
  { return 0; }
55 60

	
56 61
  void SkeletonSolverBase::_setColLowerBound(int, Value) {}
57 62
  SkeletonSolverBase::Value SkeletonSolverBase::_getColLowerBound(int) const
58 63
  {  return 0; }
59 64

	
60 65
  void SkeletonSolverBase::_setColUpperBound(int, Value) {}
61 66
  SkeletonSolverBase::Value SkeletonSolverBase::_getColUpperBound(int) const
62 67
  {  return 0; }
63 68

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

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

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

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

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

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

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

	
89 94
  LpSkeleton::SolveExitStatus LpSkeleton::_solve() { return SOLVED; }
90 95

	
91 96
  LpSkeleton::Value LpSkeleton::_getPrimal(int) const { return 0; }
92 97
  LpSkeleton::Value LpSkeleton::_getDual(int) const { return 0; }
93 98
  LpSkeleton::Value LpSkeleton::_getPrimalValue() const { return 0; }
94 99

	
95 100
  LpSkeleton::Value LpSkeleton::_getPrimalRay(int) const { return 0; }
96 101
  LpSkeleton::Value LpSkeleton::_getDualRay(int) const { return 0; }
97 102

	
98 103
  LpSkeleton::ProblemType LpSkeleton::_getPrimalType() const
99 104
  { return UNDEFINED; }
100 105

	
101 106
  LpSkeleton::ProblemType LpSkeleton::_getDualType() const
102 107
  { return UNDEFINED; }
103 108

	
104 109
  LpSkeleton::VarStatus LpSkeleton::_getColStatus(int) const
105 110
  { return BASIC; }
106 111

	
107 112
  LpSkeleton::VarStatus LpSkeleton::_getRowStatus(int) const
108 113
  { return BASIC; }
109 114

	
110 115
  LpSkeleton* LpSkeleton::newSolver() const
111 116
  { return static_cast<LpSkeleton*>(0); }
112 117

	
113 118
  LpSkeleton* LpSkeleton::cloneSolver() const
114 119
  { return static_cast<LpSkeleton*>(0); }
115 120

	
116 121
  const char* LpSkeleton::_solverName() const { return "LpSkeleton"; }
117 122

	
118 123
  MipSkeleton::SolveExitStatus MipSkeleton::_solve()
119 124
  { return SOLVED; }
120 125

	
121 126
  MipSkeleton::Value MipSkeleton::_getSol(int) const { return 0; }
122 127
  MipSkeleton::Value MipSkeleton::_getSolValue() const { return 0; }
123 128

	
124 129
  MipSkeleton::ProblemType MipSkeleton::_getType() const
125 130
  { return UNDEFINED; }
126 131

	
127 132
  MipSkeleton* MipSkeleton::newSolver() const
128 133
  { return static_cast<MipSkeleton*>(0); }
129 134

	
130 135
  MipSkeleton* MipSkeleton::cloneSolver() const
131 136
  { return static_cast<MipSkeleton*>(0); }
132 137

	
133 138
  const char* MipSkeleton::_solverName() const { return "MipSkeleton"; }
134 139

	
135 140
} //namespace lemon
136 141

	
Show white space 512 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
#ifndef LEMON_LP_SKELETON_H
20 20
#define LEMON_LP_SKELETON_H
21 21

	
22 22
#include <lemon/lp_base.h>
23 23

	
24 24
///\file
25 25
///\brief Skeleton file to implement LP/MIP solver interfaces
26 26
///  
27 27
///The classes in this file do nothing, but they can serve as skeletons when
28 28
///implementing an interface to new solvers.
29 29
namespace lemon {
30 30

	
31 31
  ///A skeleton class to implement LP/MIP solver base interface
32 32
  
33 33
  ///This class does nothing, but it can serve as a skeleton when
34 34
  ///implementing an interface to new solvers.
35 35
  class SkeletonSolverBase : public virtual LpBase {
36 36
    int col_num,row_num;
37 37

	
38 38
  protected:
39 39

	
40 40
    SkeletonSolverBase()
41 41
      : col_num(-1), row_num(-1) {}
42 42

	
43 43
    /// \e
44 44
    virtual int _addCol();
45 45
    /// \e
46 46
    virtual int _addRow();
47 47
    /// \e
48
    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
49
    /// \e
48 50
    virtual void _eraseCol(int i);
49 51
    /// \e
50 52
    virtual void _eraseRow(int i);
51 53

	
52 54
    /// \e
53 55
    virtual void _getColName(int col, std::string& name) const;
54 56
    /// \e
55 57
    virtual void _setColName(int col, const std::string& name);
56 58
    /// \e
57 59
    virtual int _colByName(const std::string& name) const;
58 60

	
59 61
    /// \e
60 62
    virtual void _getRowName(int row, std::string& name) const;
61 63
    /// \e
62 64
    virtual void _setRowName(int row, const std::string& name);
63 65
    /// \e
64 66
    virtual int _rowByName(const std::string& name) const;
65 67

	
66 68
    /// \e
67 69
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
68 70
    /// \e
69 71
    virtual void _getRowCoeffs(int i, InsertIterator b) const;
70 72
    /// \e
71 73
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
72 74
    /// \e
73 75
    virtual void _getColCoeffs(int i, InsertIterator b) const;
74 76

	
75 77
    /// Set one element of the coefficient matrix
76 78
    virtual void _setCoeff(int row, int col, Value value);
77 79

	
78 80
    /// Get one element of the coefficient matrix
79 81
    virtual Value _getCoeff(int row, int col) const;
80 82

	
81 83
    /// The lower bound of a variable (column) have to be given by an
82 84
    /// extended number of type Value, i.e. a finite number of type
83 85
    /// Value or -\ref INF.
84 86
    virtual void _setColLowerBound(int i, Value value);
85 87
    /// \e
86 88

	
87 89
    /// The lower bound of a variable (column) is an
88 90
    /// extended number of type Value, i.e. a finite number of type
89 91
    /// Value or -\ref INF.
90 92
    virtual Value _getColLowerBound(int i) const;
91 93

	
92 94
    /// The upper bound of a variable (column) have to be given by an
93 95
    /// extended number of type Value, i.e. a finite number of type
94 96
    /// Value or \ref INF.
95 97
    virtual void _setColUpperBound(int i, Value value);
96 98
    /// \e
97 99

	
98 100
    /// The upper bound of a variable (column) is an
99 101
    /// extended number of type Value, i.e. a finite number of type
100 102
    /// Value or \ref INF.
101 103
    virtual Value _getColUpperBound(int i) const;
102 104

	
103 105
    /// The lower bound of a constraint (row) have to be given by an
104 106
    /// extended number of type Value, i.e. a finite number of type
105 107
    /// Value or -\ref INF.
106 108
    virtual void _setRowLowerBound(int i, Value value);
107 109
    /// \e
108 110

	
109 111
    /// The lower bound of a constraint (row) is an
110 112
    /// extended number of type Value, i.e. a finite number of type
111 113
    /// Value or -\ref INF.
112 114
    virtual Value _getRowLowerBound(int i) const;
113 115

	
114 116
    /// The upper bound of a constraint (row) have to be given by an
115 117
    /// extended number of type Value, i.e. a finite number of type
116 118
    /// Value or \ref INF.
117 119
    virtual void _setRowUpperBound(int i, Value value);
118 120
    /// \e
119 121

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

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

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

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

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

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

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

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

	
163 165
    ///\e
164 166
    virtual SolveExitStatus _solve();
165 167

	
166 168
    ///\e
167 169
    virtual Value _getPrimal(int i) const;
168 170
    ///\e
169 171
    virtual Value _getDual(int i) const;
170 172

	
171 173
    ///\e
172 174
    virtual Value _getPrimalValue() const;
173 175

	
174 176
    ///\e
175 177
    virtual Value _getPrimalRay(int i) const;
176 178
    ///\e
177 179
    virtual Value _getDualRay(int i) const;
178 180

	
179 181
    ///\e
180 182
    virtual ProblemType _getPrimalType() const;
181 183
    ///\e
182 184
    virtual ProblemType _getDualType() const;
183 185

	
184 186
    ///\e
185 187
    virtual VarStatus _getColStatus(int i) const;
186 188
    ///\e
187 189
    virtual VarStatus _getRowStatus(int i) const;
188 190

	
189 191
    ///\e
190 192
    virtual const char* _solverName() const;
191 193

	
192 194
  };
193 195

	
194 196
  /// \brief Skeleton class for a MIP solver interface
195 197
  ///
196 198
  ///This class does nothing, but it can serve as a skeleton when
197 199
  ///implementing an interface to new solvers.
198 200
  ///\ingroup lp_group
199 201
  class MipSkeleton : public MipSolver, public SkeletonSolverBase {
200 202
  public:
201 203
    ///\e
202 204
    MipSkeleton() : MipSolver(), SkeletonSolverBase() {}
203 205
    ///\e
204 206
    virtual MipSkeleton* newSolver() const;
205 207
    ///\e
206 208
    virtual MipSkeleton* cloneSolver() const;
207 209

	
208 210
  protected:
209 211
    ///\e
210 212
    virtual SolveExitStatus _solve();
211 213

	
212 214
    ///\e
213 215
    virtual Value _getSol(int i) const;
214 216

	
215 217
    ///\e
216 218
    virtual Value _getSolValue() const;
217 219

	
218 220
    ///\e
219 221
    virtual ProblemType _getType() const;
220 222

	
221 223
    ///\e
222 224
    virtual const char* _solverName() const;
223 225
  };
224 226

	
225 227
} //namespace lemon
226 228

	
227 229
#endif
Show white space 512 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 23
#include <spxout.h>
24 24

	
25 25

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

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

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

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

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

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

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

	
52 52
    messageLevel(MESSAGE_NOTHING);
53 53
  }
54 54

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

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

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

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

	
72 72
  int SoplexLp::_addCol() {
73 73
    soplex::LPCol c;
74 74
    c.setLower(-soplex::infinity);
75 75
    c.setUpper(soplex::infinity);
76 76
    soplex->addCol(c);
77 77

	
78 78
    _col_names.push_back(std::string());
79 79

	
80 80
    return soplex->nCols() - 1;
81 81
  }
82 82

	
83 83
  int SoplexLp::_addRow() {
84 84
    soplex::LPRow r;
85 85
    r.setLhs(-soplex::infinity);
86 86
    r.setRhs(soplex::infinity);
87 87
    soplex->addRow(r);
88 88

	
89 89
    _row_names.push_back(std::string());
90 90

	
91 91
    return soplex->nRows() - 1;
92 92
  }
93 93

	
94
  int SoplexLp::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
95
    soplex::DSVector v;
96
    for (ExprIterator it = b; it != e; ++it) {
97
      v.add(it->first, it->second);
98
    }
99
    soplex::LPRow r(l, v, u);
100
    soplex->addRow(r);
101

	
102
    _row_names.push_back(std::string());
103

	
104
    return soplex->nRows() - 1;
105
  }
106

	
94 107

	
95 108
  void SoplexLp::_eraseCol(int i) {
96 109
    soplex->removeCol(i);
97 110
    _col_names_ref.erase(_col_names[i]);
98 111
    _col_names[i] = _col_names.back();
99 112
    _col_names_ref[_col_names.back()] = i;
100 113
    _col_names.pop_back();
101 114
  }
102 115

	
103 116
  void SoplexLp::_eraseRow(int i) {
104 117
    soplex->removeRow(i);
105 118
    _row_names_ref.erase(_row_names[i]);
106 119
    _row_names[i] = _row_names.back();
107 120
    _row_names_ref[_row_names.back()] = i;
108 121
    _row_names.pop_back();
109 122
  }
110 123

	
111 124
  void SoplexLp::_eraseColId(int i) {
112 125
    cols.eraseIndex(i);
113 126
    cols.relocateIndex(i, cols.maxIndex());
114 127
  }
115 128
  void SoplexLp::_eraseRowId(int i) {
116 129
    rows.eraseIndex(i);
117 130
    rows.relocateIndex(i, rows.maxIndex());
118 131
  }
119 132

	
120 133
  void SoplexLp::_getColName(int c, std::string &name) const {
121 134
    name = _col_names[c];
122 135
  }
123 136

	
124 137
  void SoplexLp::_setColName(int c, const std::string &name) {
125 138
    _col_names_ref.erase(_col_names[c]);
126 139
    _col_names[c] = name;
127 140
    if (!name.empty()) {
128 141
      _col_names_ref.insert(std::make_pair(name, c));
129 142
    }
130 143
  }
131 144

	
132 145
  int SoplexLp::_colByName(const std::string& name) const {
133 146
    std::map<std::string, int>::const_iterator it =
134 147
      _col_names_ref.find(name);
135 148
    if (it != _col_names_ref.end()) {
136 149
      return it->second;
137 150
    } else {
138 151
      return -1;
139 152
    }
140 153
  }
141 154

	
142 155
  void SoplexLp::_getRowName(int r, std::string &name) const {
143 156
    name = _row_names[r];
144 157
  }
145 158

	
146 159
  void SoplexLp::_setRowName(int r, const std::string &name) {
147 160
    _row_names_ref.erase(_row_names[r]);
148 161
    _row_names[r] = name;
149 162
    if (!name.empty()) {
150 163
      _row_names_ref.insert(std::make_pair(name, r));
151 164
    }
152 165
  }
153 166

	
154 167
  int SoplexLp::_rowByName(const std::string& name) const {
155 168
    std::map<std::string, int>::const_iterator it =
156 169
      _row_names_ref.find(name);
157 170
    if (it != _row_names_ref.end()) {
158 171
      return it->second;
159 172
    } else {
160 173
      return -1;
161 174
    }
162 175
  }
163 176

	
164 177

	
165 178
  void SoplexLp::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) {
166 179
    for (int j = 0; j < soplex->nCols(); ++j) {
167 180
      soplex->changeElement(i, j, 0.0);
168 181
    }
169 182
    for(ExprIterator it = b; it != e; ++it) {
170 183
      soplex->changeElement(i, it->first, it->second);
171 184
    }
172 185
  }
173 186

	
174 187
  void SoplexLp::_getRowCoeffs(int i, InsertIterator b) const {
175 188
    const soplex::SVector& vec = soplex->rowVector(i);
176 189
    for (int k = 0; k < vec.size(); ++k) {
177 190
      *b = std::make_pair(vec.index(k), vec.value(k));
178 191
      ++b;
179 192
    }
180 193
  }
181 194

	
182 195
  void SoplexLp::_setColCoeffs(int j, ExprIterator b, ExprIterator e) {
183 196
    for (int i = 0; i < soplex->nRows(); ++i) {
184 197
      soplex->changeElement(i, j, 0.0);
185 198
    }
186 199
    for(ExprIterator it = b; it != e; ++it) {
187 200
      soplex->changeElement(it->first, j, it->second);
188 201
    }
189 202
  }
190 203

	
191 204
  void SoplexLp::_getColCoeffs(int i, InsertIterator b) const {
192 205
    const soplex::SVector& vec = soplex->colVector(i);
193 206
    for (int k = 0; k < vec.size(); ++k) {
194 207
      *b = std::make_pair(vec.index(k), vec.value(k));
195 208
      ++b;
196 209
    }
197 210
  }
198 211

	
199 212
  void SoplexLp::_setCoeff(int i, int j, Value value) {
200 213
    soplex->changeElement(i, j, value);
201 214
  }
202 215

	
203 216
  SoplexLp::Value SoplexLp::_getCoeff(int i, int j) const {
204 217
    return soplex->rowVector(i)[j];
205 218
  }
206 219

	
207 220
  void SoplexLp::_setColLowerBound(int i, Value value) {
208 221
    LEMON_ASSERT(value != INF, "Invalid bound");
209 222
    soplex->changeLower(i, value != -INF ? value : -soplex::infinity);
210 223
  }
211 224

	
212 225
  SoplexLp::Value SoplexLp::_getColLowerBound(int i) const {
213 226
    double value = soplex->lower(i);
214 227
    return value != -soplex::infinity ? value : -INF;
215 228
  }
216 229

	
217 230
  void SoplexLp::_setColUpperBound(int i, Value value) {
218 231
    LEMON_ASSERT(value != -INF, "Invalid bound");
219 232
    soplex->changeUpper(i, value != INF ? value : soplex::infinity);
220 233
  }
221 234

	
222 235
  SoplexLp::Value SoplexLp::_getColUpperBound(int i) const {
223 236
    double value = soplex->upper(i);
224 237
    return value != soplex::infinity ? value : INF;
225 238
  }
226 239

	
227 240
  void SoplexLp::_setRowLowerBound(int i, Value lb) {
228 241
    LEMON_ASSERT(lb != INF, "Invalid bound");
229 242
    soplex->changeRange(i, lb != -INF ? lb : -soplex::infinity, soplex->rhs(i));
230 243
  }
231 244

	
232 245
  SoplexLp::Value SoplexLp::_getRowLowerBound(int i) const {
233 246
    double res = soplex->lhs(i);
234 247
    return res == -soplex::infinity ? -INF : res;
235 248
  }
236 249

	
237 250
  void SoplexLp::_setRowUpperBound(int i, Value ub) {
238 251
    LEMON_ASSERT(ub != -INF, "Invalid bound");
239 252
    soplex->changeRange(i, soplex->lhs(i), ub != INF ? ub : soplex::infinity);
240 253
  }
241 254

	
242 255
  SoplexLp::Value SoplexLp::_getRowUpperBound(int i) const {
243 256
    double res = soplex->rhs(i);
244 257
    return res == soplex::infinity ? INF : res;
245 258
  }
246 259

	
247 260
  void SoplexLp::_setObjCoeffs(ExprIterator b, ExprIterator e) {
248 261
    for (int j = 0; j < soplex->nCols(); ++j) {
249 262
      soplex->changeObj(j, 0.0);
250 263
    }
251 264
    for (ExprIterator it = b; it != e; ++it) {
252 265
      soplex->changeObj(it->first, it->second);
253 266
    }
254 267
  }
255 268

	
256 269
  void SoplexLp::_getObjCoeffs(InsertIterator b) const {
257 270
    for (int j = 0; j < soplex->nCols(); ++j) {
258 271
      Value coef = soplex->obj(j);
259 272
      if (coef != 0.0) {
260 273
        *b = std::make_pair(j, coef);
261 274
        ++b;
262 275
      }
263 276
    }
264 277
  }
265 278

	
266 279
  void SoplexLp::_setObjCoeff(int i, Value obj_coef) {
267 280
    soplex->changeObj(i, obj_coef);
268 281
  }
269 282

	
270 283
  SoplexLp::Value SoplexLp::_getObjCoeff(int i) const {
271 284
    return soplex->obj(i);
272 285
  }
273 286

	
274 287
  SoplexLp::SolveExitStatus SoplexLp::_solve() {
275 288

	
276 289
    _clear_temporals();
277 290
    
278 291
    _applyMessageLevel();
279 292

	
280 293
    soplex::SPxSolver::Status status = soplex->solve();
281 294

	
282 295
    switch (status) {
283 296
    case soplex::SPxSolver::OPTIMAL:
284 297
    case soplex::SPxSolver::INFEASIBLE:
285 298
    case soplex::SPxSolver::UNBOUNDED:
286 299
      return SOLVED;
287 300
    default:
288 301
      return UNSOLVED;
289 302
    }
290 303
  }
291 304

	
292 305
  SoplexLp::Value SoplexLp::_getPrimal(int i) const {
293 306
    if (_primal_values.empty()) {
294 307
      _primal_values.resize(soplex->nCols());
295 308
      soplex::Vector pv(_primal_values.size(), &_primal_values.front());
296 309
      soplex->getPrimal(pv);
297 310
    }
298 311
    return _primal_values[i];
299 312
  }
300 313

	
301 314
  SoplexLp::Value SoplexLp::_getDual(int i) const {
302 315
    if (_dual_values.empty()) {
303 316
      _dual_values.resize(soplex->nRows());
304 317
      soplex::Vector dv(_dual_values.size(), &_dual_values.front());
305 318
      soplex->getDual(dv);
306 319
    }
307 320
    return _dual_values[i];
308 321
  }
309 322

	
310 323
  SoplexLp::Value SoplexLp::_getPrimalValue() const {
311 324
    return soplex->objValue();
312 325
  }
313 326

	
314 327
  SoplexLp::VarStatus SoplexLp::_getColStatus(int i) const {
315 328
    switch (soplex->getBasisColStatus(i)) {
316 329
    case soplex::SPxSolver::BASIC:
317 330
      return BASIC;
318 331
    case soplex::SPxSolver::ON_UPPER:
319 332
      return UPPER;
320 333
    case soplex::SPxSolver::ON_LOWER:
321 334
      return LOWER;
322 335
    case soplex::SPxSolver::FIXED:
323 336
      return FIXED;
324 337
    case soplex::SPxSolver::ZERO:
325 338
      return FREE;
326 339
    default:
327 340
      LEMON_ASSERT(false, "Wrong column status");
328 341
      return VarStatus();
329 342
    }
330 343
  }
331 344

	
332 345
  SoplexLp::VarStatus SoplexLp::_getRowStatus(int i) const {
333 346
    switch (soplex->getBasisRowStatus(i)) {
334 347
    case soplex::SPxSolver::BASIC:
335 348
      return BASIC;
336 349
    case soplex::SPxSolver::ON_UPPER:
337 350
      return UPPER;
338 351
    case soplex::SPxSolver::ON_LOWER:
339 352
      return LOWER;
340 353
    case soplex::SPxSolver::FIXED:
341 354
      return FIXED;
342 355
    case soplex::SPxSolver::ZERO:
343 356
      return FREE;
344 357
    default:
345 358
      LEMON_ASSERT(false, "Wrong row status");
346 359
      return VarStatus();
347 360
    }
348 361
  }
349 362

	
Show white space 512 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
#ifndef LEMON_SOPLEX_H
20 20
#define LEMON_SOPLEX_H
21 21

	
22 22
///\file
23 23
///\brief Header of the LEMON-SOPLEX lp solver interface.
24 24

	
25 25
#include <vector>
26 26
#include <string>
27 27

	
28 28
#include <lemon/lp_base.h>
29 29

	
30 30
// Forward declaration
31 31
namespace soplex {
32 32
  class SoPlex;
33 33
}
34 34

	
35 35
namespace lemon {
36 36

	
37 37
  /// \ingroup lp_group
38 38
  ///
39 39
  /// \brief Interface for the SOPLEX solver
40 40
  ///
41 41
  /// This class implements an interface for the SoPlex LP solver.
42 42
  /// The SoPlex library is an object oriented lp solver library
43 43
  /// developed at the Konrad-Zuse-Zentrum f�r Informationstechnik
44 44
  /// Berlin (ZIB). You can find detailed information about it at the
45 45
  /// <tt>http://soplex.zib.de</tt> address.
46 46
  class SoplexLp : public LpSolver {
47 47
  private:
48 48

	
49 49
    soplex::SoPlex* soplex;
50 50

	
51 51
    std::vector<std::string> _col_names;
52 52
    std::map<std::string, int> _col_names_ref;
53 53

	
54 54
    std::vector<std::string> _row_names;
55 55
    std::map<std::string, int> _row_names_ref;
56 56

	
57 57
  private:
58 58

	
59 59
    // these values cannot be retrieved element by element
60 60
    mutable std::vector<Value> _primal_values;
61 61
    mutable std::vector<Value> _dual_values;
62 62

	
63 63
    mutable std::vector<Value> _primal_ray;
64 64
    mutable std::vector<Value> _dual_ray;
65 65

	
66 66
    void _clear_temporals();
67 67

	
68 68
  public:
69 69

	
70 70
    /// \e
71 71
    SoplexLp();
72 72
    /// \e
73 73
    SoplexLp(const SoplexLp&);
74 74
    /// \e
75 75
    ~SoplexLp();
76 76
    /// \e
77 77
    virtual SoplexLp* newSolver() const;
78 78
    /// \e
79 79
    virtual SoplexLp* cloneSolver() const;
80 80

	
81 81
  protected:
82 82

	
83 83
    virtual const char* _solverName() const;
84 84

	
85 85
    virtual int _addCol();
86 86
    virtual int _addRow();
87
    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
87 88

	
88 89
    virtual void _eraseCol(int i);
89 90
    virtual void _eraseRow(int i);
90 91

	
91 92
    virtual void _eraseColId(int i);
92 93
    virtual void _eraseRowId(int i);
93 94

	
94 95
    virtual void _getColName(int col, std::string& name) const;
95 96
    virtual void _setColName(int col, const std::string& name);
96 97
    virtual int _colByName(const std::string& name) const;
97 98

	
98 99
    virtual void _getRowName(int row, std::string& name) const;
99 100
    virtual void _setRowName(int row, const std::string& name);
100 101
    virtual int _rowByName(const std::string& name) const;
101 102

	
102 103
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
103 104
    virtual void _getRowCoeffs(int i, InsertIterator b) const;
104 105

	
105 106
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
106 107
    virtual void _getColCoeffs(int i, InsertIterator b) const;
107 108

	
108 109
    virtual void _setCoeff(int row, int col, Value value);
109 110
    virtual Value _getCoeff(int row, int col) const;
110 111

	
111 112
    virtual void _setColLowerBound(int i, Value value);
112 113
    virtual Value _getColLowerBound(int i) const;
113 114
    virtual void _setColUpperBound(int i, Value value);
114 115
    virtual Value _getColUpperBound(int i) const;
115 116

	
116 117
    virtual void _setRowLowerBound(int i, Value value);
117 118
    virtual Value _getRowLowerBound(int i) const;
118 119
    virtual void _setRowUpperBound(int i, Value value);
119 120
    virtual Value _getRowUpperBound(int i) const;
120 121

	
121 122
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
122 123
    virtual void _getObjCoeffs(InsertIterator b) const;
123 124

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

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

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

	
134 135
    virtual Value _getPrimalValue() const;
135 136

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

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

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

	
145 146
    virtual void _clear();
146 147

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

	
150 151
    int _message_level;
151 152

	
152 153
  };
153 154

	
154 155
} //END OF NAMESPACE LEMON
155 156

	
156 157
#endif //LEMON_SOPLEX_H
157 158

	
0 comments (0 inline)