19 #include <lemon/clp.h> |
19 #include <lemon/clp.h> |
20 #include <coin/ClpSimplex.hpp> |
20 #include <coin/ClpSimplex.hpp> |
21 |
21 |
22 namespace lemon { |
22 namespace lemon { |
23 |
23 |
24 LpClp::LpClp() { |
24 ClpLp::ClpLp() { |
25 _prob = new ClpSimplex(); |
25 _prob = new ClpSimplex(); |
26 _init_temporals(); |
26 _init_temporals(); |
27 messageLevel(MESSAGE_NO_OUTPUT); |
27 messageLevel(MESSAGE_NO_OUTPUT); |
28 } |
28 } |
29 |
29 |
30 LpClp::LpClp(const LpClp& other) { |
30 ClpLp::ClpLp(const ClpLp& other) { |
31 _prob = new ClpSimplex(*other._prob); |
31 _prob = new ClpSimplex(*other._prob); |
32 rows = other.rows; |
32 rows = other.rows; |
33 cols = other.cols; |
33 cols = other.cols; |
34 _init_temporals(); |
34 _init_temporals(); |
35 messageLevel(MESSAGE_NO_OUTPUT); |
35 messageLevel(MESSAGE_NO_OUTPUT); |
36 } |
36 } |
37 |
37 |
38 LpClp::~LpClp() { |
38 ClpLp::~ClpLp() { |
39 delete _prob; |
39 delete _prob; |
40 _clear_temporals(); |
40 _clear_temporals(); |
41 } |
41 } |
42 |
42 |
43 void LpClp::_init_temporals() { |
43 void ClpLp::_init_temporals() { |
44 _primal_ray = 0; |
44 _primal_ray = 0; |
45 _dual_ray = 0; |
45 _dual_ray = 0; |
46 } |
46 } |
47 |
47 |
48 void LpClp::_clear_temporals() { |
48 void ClpLp::_clear_temporals() { |
49 if (_primal_ray) { |
49 if (_primal_ray) { |
50 delete[] _primal_ray; |
50 delete[] _primal_ray; |
51 _primal_ray = 0; |
51 _primal_ray = 0; |
52 } |
52 } |
53 if (_dual_ray) { |
53 if (_dual_ray) { |
54 delete[] _dual_ray; |
54 delete[] _dual_ray; |
55 _dual_ray = 0; |
55 _dual_ray = 0; |
56 } |
56 } |
57 } |
57 } |
58 |
58 |
59 LpClp* LpClp::_newSolver() const { |
59 ClpLp* ClpLp::_newSolver() const { |
60 LpClp* newlp = new LpClp; |
60 ClpLp* newlp = new ClpLp; |
61 return newlp; |
61 return newlp; |
62 } |
62 } |
63 |
63 |
64 LpClp* LpClp::_cloneSolver() const { |
64 ClpLp* ClpLp::_cloneSolver() const { |
65 LpClp* copylp = new LpClp(*this); |
65 ClpLp* copylp = new ClpLp(*this); |
66 return copylp; |
66 return copylp; |
67 } |
67 } |
68 |
68 |
69 const char* LpClp::_solverName() const { return "LpClp"; } |
69 const char* ClpLp::_solverName() const { return "ClpLp"; } |
70 |
70 |
71 int LpClp::_addCol() { |
71 int ClpLp::_addCol() { |
72 _prob->addColumn(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX, 0.0); |
72 _prob->addColumn(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX, 0.0); |
73 return _prob->numberColumns() - 1; |
73 return _prob->numberColumns() - 1; |
74 } |
74 } |
75 |
75 |
76 int LpClp::_addRow() { |
76 int ClpLp::_addRow() { |
77 _prob->addRow(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX); |
77 _prob->addRow(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX); |
78 return _prob->numberRows() - 1; |
78 return _prob->numberRows() - 1; |
79 } |
79 } |
80 |
80 |
81 |
81 |
82 void LpClp::_eraseCol(int c) { |
82 void ClpLp::_eraseCol(int c) { |
83 _col_names_ref.erase(_prob->getColumnName(c)); |
83 _col_names_ref.erase(_prob->getColumnName(c)); |
84 _prob->deleteColumns(1, &c); |
84 _prob->deleteColumns(1, &c); |
85 } |
85 } |
86 |
86 |
87 void LpClp::_eraseRow(int r) { |
87 void ClpLp::_eraseRow(int r) { |
88 _row_names_ref.erase(_prob->getRowName(r)); |
88 _row_names_ref.erase(_prob->getRowName(r)); |
89 _prob->deleteRows(1, &r); |
89 _prob->deleteRows(1, &r); |
90 } |
90 } |
91 |
91 |
92 void LpClp::_eraseColId(int i) { |
92 void ClpLp::_eraseColId(int i) { |
93 cols.eraseIndex(i); |
93 cols.eraseIndex(i); |
94 cols.shiftIndices(i); |
94 cols.shiftIndices(i); |
95 } |
95 } |
96 |
96 |
97 void LpClp::_eraseRowId(int i) { |
97 void ClpLp::_eraseRowId(int i) { |
98 rows.eraseIndex(i); |
98 rows.eraseIndex(i); |
99 rows.shiftIndices(i); |
99 rows.shiftIndices(i); |
100 } |
100 } |
101 |
101 |
102 void LpClp::_getColName(int c, std::string& name) const { |
102 void ClpLp::_getColName(int c, std::string& name) const { |
103 name = _prob->getColumnName(c); |
103 name = _prob->getColumnName(c); |
104 } |
104 } |
105 |
105 |
106 void LpClp::_setColName(int c, const std::string& name) { |
106 void ClpLp::_setColName(int c, const std::string& name) { |
107 _prob->setColumnName(c, const_cast<std::string&>(name)); |
107 _prob->setColumnName(c, const_cast<std::string&>(name)); |
108 _col_names_ref[name] = c; |
108 _col_names_ref[name] = c; |
109 } |
109 } |
110 |
110 |
111 int LpClp::_colByName(const std::string& name) const { |
111 int ClpLp::_colByName(const std::string& name) const { |
112 std::map<std::string, int>::const_iterator it = _col_names_ref.find(name); |
112 std::map<std::string, int>::const_iterator it = _col_names_ref.find(name); |
113 return it != _col_names_ref.end() ? it->second : -1; |
113 return it != _col_names_ref.end() ? it->second : -1; |
114 } |
114 } |
115 |
115 |
116 void LpClp::_getRowName(int r, std::string& name) const { |
116 void ClpLp::_getRowName(int r, std::string& name) const { |
117 name = _prob->getRowName(r); |
117 name = _prob->getRowName(r); |
118 } |
118 } |
119 |
119 |
120 void LpClp::_setRowName(int r, const std::string& name) { |
120 void ClpLp::_setRowName(int r, const std::string& name) { |
121 _prob->setRowName(r, const_cast<std::string&>(name)); |
121 _prob->setRowName(r, const_cast<std::string&>(name)); |
122 _row_names_ref[name] = r; |
122 _row_names_ref[name] = r; |
123 } |
123 } |
124 |
124 |
125 int LpClp::_rowByName(const std::string& name) const { |
125 int ClpLp::_rowByName(const std::string& name) const { |
126 std::map<std::string, int>::const_iterator it = _row_names_ref.find(name); |
126 std::map<std::string, int>::const_iterator it = _row_names_ref.find(name); |
127 return it != _row_names_ref.end() ? it->second : -1; |
127 return it != _row_names_ref.end() ? it->second : -1; |
128 } |
128 } |
129 |
129 |
130 |
130 |
131 void LpClp::_setRowCoeffs(int ix, ExprIterator b, ExprIterator e) { |
131 void ClpLp::_setRowCoeffs(int ix, ExprIterator b, ExprIterator e) { |
132 std::map<int, Value> coeffs; |
132 std::map<int, Value> coeffs; |
133 |
133 |
134 int n = _prob->clpMatrix()->getNumCols(); |
134 int n = _prob->clpMatrix()->getNumCols(); |
135 |
135 |
136 const int* indices = _prob->clpMatrix()->getIndices(); |
136 const int* indices = _prob->clpMatrix()->getIndices(); |
226 } else { |
226 } else { |
227 return 0.0; |
227 return 0.0; |
228 } |
228 } |
229 } |
229 } |
230 |
230 |
231 void LpClp::_setColLowerBound(int i, Value lo) { |
231 void ClpLp::_setColLowerBound(int i, Value lo) { |
232 _prob->setColumnLower(i, lo == - INF ? - COIN_DBL_MAX : lo); |
232 _prob->setColumnLower(i, lo == - INF ? - COIN_DBL_MAX : lo); |
233 } |
233 } |
234 |
234 |
235 LpClp::Value LpClp::_getColLowerBound(int i) const { |
235 ClpLp::Value ClpLp::_getColLowerBound(int i) const { |
236 double val = _prob->getColLower()[i]; |
236 double val = _prob->getColLower()[i]; |
237 return val == - COIN_DBL_MAX ? - INF : val; |
237 return val == - COIN_DBL_MAX ? - INF : val; |
238 } |
238 } |
239 |
239 |
240 void LpClp::_setColUpperBound(int i, Value up) { |
240 void ClpLp::_setColUpperBound(int i, Value up) { |
241 _prob->setColumnUpper(i, up == INF ? COIN_DBL_MAX : up); |
241 _prob->setColumnUpper(i, up == INF ? COIN_DBL_MAX : up); |
242 } |
242 } |
243 |
243 |
244 LpClp::Value LpClp::_getColUpperBound(int i) const { |
244 ClpLp::Value ClpLp::_getColUpperBound(int i) const { |
245 double val = _prob->getColUpper()[i]; |
245 double val = _prob->getColUpper()[i]; |
246 return val == COIN_DBL_MAX ? INF : val; |
246 return val == COIN_DBL_MAX ? INF : val; |
247 } |
247 } |
248 |
248 |
249 void LpClp::_setRowLowerBound(int i, Value lo) { |
249 void ClpLp::_setRowLowerBound(int i, Value lo) { |
250 _prob->setRowLower(i, lo == - INF ? - COIN_DBL_MAX : lo); |
250 _prob->setRowLower(i, lo == - INF ? - COIN_DBL_MAX : lo); |
251 } |
251 } |
252 |
252 |
253 LpClp::Value LpClp::_getRowLowerBound(int i) const { |
253 ClpLp::Value ClpLp::_getRowLowerBound(int i) const { |
254 double val = _prob->getRowLower()[i]; |
254 double val = _prob->getRowLower()[i]; |
255 return val == - COIN_DBL_MAX ? - INF : val; |
255 return val == - COIN_DBL_MAX ? - INF : val; |
256 } |
256 } |
257 |
257 |
258 void LpClp::_setRowUpperBound(int i, Value up) { |
258 void ClpLp::_setRowUpperBound(int i, Value up) { |
259 _prob->setRowUpper(i, up == INF ? COIN_DBL_MAX : up); |
259 _prob->setRowUpper(i, up == INF ? COIN_DBL_MAX : up); |
260 } |
260 } |
261 |
261 |
262 LpClp::Value LpClp::_getRowUpperBound(int i) const { |
262 ClpLp::Value ClpLp::_getRowUpperBound(int i) const { |
263 double val = _prob->getRowUpper()[i]; |
263 double val = _prob->getRowUpper()[i]; |
264 return val == COIN_DBL_MAX ? INF : val; |
264 return val == COIN_DBL_MAX ? INF : val; |
265 } |
265 } |
266 |
266 |
267 void LpClp::_setObjCoeffs(ExprIterator b, ExprIterator e) { |
267 void ClpLp::_setObjCoeffs(ExprIterator b, ExprIterator e) { |
268 int num = _prob->clpMatrix()->getNumCols(); |
268 int num = _prob->clpMatrix()->getNumCols(); |
269 for (int i = 0; i < num; ++i) { |
269 for (int i = 0; i < num; ++i) { |
270 _prob->setObjectiveCoefficient(i, 0.0); |
270 _prob->setObjectiveCoefficient(i, 0.0); |
271 } |
271 } |
272 for (ExprIterator it = b; it != e; ++it) { |
272 for (ExprIterator it = b; it != e; ++it) { |
273 _prob->setObjectiveCoefficient(it->first, it->second); |
273 _prob->setObjectiveCoefficient(it->first, it->second); |
274 } |
274 } |
275 } |
275 } |
276 |
276 |
277 void LpClp::_getObjCoeffs(InsertIterator b) const { |
277 void ClpLp::_getObjCoeffs(InsertIterator b) const { |
278 int num = _prob->clpMatrix()->getNumCols(); |
278 int num = _prob->clpMatrix()->getNumCols(); |
279 for (int i = 0; i < num; ++i) { |
279 for (int i = 0; i < num; ++i) { |
280 Value coef = _prob->getObjCoefficients()[i]; |
280 Value coef = _prob->getObjCoefficients()[i]; |
281 if (coef != 0.0) { |
281 if (coef != 0.0) { |
282 *b = std::make_pair(i, coef); |
282 *b = std::make_pair(i, coef); |
283 ++b; |
283 ++b; |
284 } |
284 } |
285 } |
285 } |
286 } |
286 } |
287 |
287 |
288 void LpClp::_setObjCoeff(int i, Value obj_coef) { |
288 void ClpLp::_setObjCoeff(int i, Value obj_coef) { |
289 _prob->setObjectiveCoefficient(i, obj_coef); |
289 _prob->setObjectiveCoefficient(i, obj_coef); |
290 } |
290 } |
291 |
291 |
292 LpClp::Value LpClp::_getObjCoeff(int i) const { |
292 ClpLp::Value ClpLp::_getObjCoeff(int i) const { |
293 return _prob->getObjCoefficients()[i]; |
293 return _prob->getObjCoefficients()[i]; |
294 } |
294 } |
295 |
295 |
296 LpClp::SolveExitStatus LpClp::_solve() { |
296 ClpLp::SolveExitStatus ClpLp::_solve() { |
297 return _prob->primal() >= 0 ? SOLVED : UNSOLVED; |
297 return _prob->primal() >= 0 ? SOLVED : UNSOLVED; |
298 } |
298 } |
299 |
299 |
300 LpClp::SolveExitStatus LpClp::solvePrimal() { |
300 ClpLp::SolveExitStatus ClpLp::solvePrimal() { |
301 return _prob->primal() >= 0 ? SOLVED : UNSOLVED; |
301 return _prob->primal() >= 0 ? SOLVED : UNSOLVED; |
302 } |
302 } |
303 |
303 |
304 LpClp::SolveExitStatus LpClp::solveDual() { |
304 ClpLp::SolveExitStatus ClpLp::solveDual() { |
305 return _prob->dual() >= 0 ? SOLVED : UNSOLVED; |
305 return _prob->dual() >= 0 ? SOLVED : UNSOLVED; |
306 } |
306 } |
307 |
307 |
308 LpClp::SolveExitStatus LpClp::solveBarrier() { |
308 ClpLp::SolveExitStatus ClpLp::solveBarrier() { |
309 return _prob->barrier() >= 0 ? SOLVED : UNSOLVED; |
309 return _prob->barrier() >= 0 ? SOLVED : UNSOLVED; |
310 } |
310 } |
311 |
311 |
312 LpClp::Value LpClp::_getPrimal(int i) const { |
312 ClpLp::Value ClpLp::_getPrimal(int i) const { |
313 return _prob->primalColumnSolution()[i]; |
313 return _prob->primalColumnSolution()[i]; |
314 } |
314 } |
315 LpClp::Value LpClp::_getPrimalValue() const { |
315 ClpLp::Value ClpLp::_getPrimalValue() const { |
316 return _prob->objectiveValue(); |
316 return _prob->objectiveValue(); |
317 } |
317 } |
318 |
318 |
319 LpClp::Value LpClp::_getDual(int i) const { |
319 ClpLp::Value ClpLp::_getDual(int i) const { |
320 return _prob->dualRowSolution()[i]; |
320 return _prob->dualRowSolution()[i]; |
321 } |
321 } |
322 |
322 |
323 LpClp::Value LpClp::_getPrimalRay(int i) const { |
323 ClpLp::Value ClpLp::_getPrimalRay(int i) const { |
324 if (!_primal_ray) { |
324 if (!_primal_ray) { |
325 _primal_ray = _prob->unboundedRay(); |
325 _primal_ray = _prob->unboundedRay(); |
326 LEMON_ASSERT(_primal_ray != 0, "Primal ray is not provided"); |
326 LEMON_ASSERT(_primal_ray != 0, "Primal ray is not provided"); |
327 } |
327 } |
328 return _primal_ray[i]; |
328 return _primal_ray[i]; |
329 } |
329 } |
330 |
330 |
331 LpClp::Value LpClp::_getDualRay(int i) const { |
331 ClpLp::Value ClpLp::_getDualRay(int i) const { |
332 if (!_dual_ray) { |
332 if (!_dual_ray) { |
333 _dual_ray = _prob->infeasibilityRay(); |
333 _dual_ray = _prob->infeasibilityRay(); |
334 LEMON_ASSERT(_dual_ray != 0, "Dual ray is not provided"); |
334 LEMON_ASSERT(_dual_ray != 0, "Dual ray is not provided"); |
335 } |
335 } |
336 return _dual_ray[i]; |
336 return _dual_ray[i]; |
337 } |
337 } |
338 |
338 |
339 LpClp::VarStatus LpClp::_getColStatus(int i) const { |
339 ClpLp::VarStatus ClpLp::_getColStatus(int i) const { |
340 switch (_prob->getColumnStatus(i)) { |
340 switch (_prob->getColumnStatus(i)) { |
341 case ClpSimplex::basic: |
341 case ClpSimplex::basic: |
342 return BASIC; |
342 return BASIC; |
343 case ClpSimplex::isFree: |
343 case ClpSimplex::isFree: |
344 return FREE; |
344 return FREE; |