COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/lp_soplex.cc @ 2368:6b2e8b734ae7

Last change on this file since 2368:6b2e8b734ae7 was 2368:6b2e8b734ae7, checked in by Balazs Dezso, 13 years ago

Bug fixes
Documentation

File size: 7.6 KB
Line 
1/* -*- C++ -*-
2 *
3 * This file is a part of LEMON, a generic C++ optimization library
4 *
5 * Copyright (C) 2003-2006
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 *
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
12 *
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
15 * purpose.
16 *
17 */
18
19#include<iostream>
20#include<lemon/lp_soplex.h>
21
22#include <soplex/soplex.h>
23
24
25///\file
26///\brief Implementation of the LEMON-SOPLEX lp solver interface.
27namespace lemon {
28 
29  LpSoplex::LpSoplex() : LpSolverBase() {
30    rows.setIdHandler(relocateIdHandler);
31    cols.setIdHandler(relocateIdHandler);
32    soplex = new soplex::SoPlex;
33    solved = false;
34  }
35 
36  LpSoplex::~LpSoplex() {
37    delete soplex;
38  }
39 
40  LpSolverBase &LpSoplex::_newLp() {
41    LpSoplex* newlp = new LpSoplex();
42    return *newlp;
43  }
44
45  LpSolverBase &LpSoplex::_copyLp() {
46    LpSoplex* newlp = new LpSoplex();
47    ((soplex::SPxLP&)*(newlp->soplex)) = *soplex;
48    return *newlp;
49  }
50
51  int LpSoplex::_addCol() {
52    soplex::LPCol col;
53    col.setLower(-soplex::infinity);
54    col.setUpper(soplex::infinity);
55    soplex->addCol(col);
56
57    colNames.push_back(std::string());
58    primal_value.push_back(0.0);
59    solved = false;
60
61    return soplex->nCols() - 1;
62  }
63
64  int LpSoplex::_addRow() {
65    soplex::LPRow row;
66    row.setLhs(-soplex::infinity);
67    row.setRhs(soplex::infinity);
68    soplex->addRow(row);
69
70    dual_value.push_back(0.0);
71    solved = false;
72
73    return soplex->nRows() - 1;
74  }
75
76
77  void LpSoplex::_eraseCol(int i) {
78    soplex->removeCol(i);
79    invColNames.erase(colNames[i]);
80    colNames[i] = colNames.back();
81    invColNames[colNames.back()] = i;
82    colNames.pop_back();
83    primal_value[i] = primal_value.back();
84    primal_value.pop_back();
85    solved = false;
86  }
87 
88  void LpSoplex::_eraseRow(int i) {
89    soplex->removeRow(i);
90    dual_value[i] = dual_value.back();
91    dual_value.pop_back();
92    solved = false;
93  }
94 
95  void LpSoplex::_getColName(int col, std::string &name) const {
96    name = colNames[col];
97  }
98 
99  void LpSoplex::_setColName(int col, const std::string &name) {
100    invColNames.erase(colNames[col]);
101    colNames[col] = name;
102    if (!name.empty()) {
103      invColNames.insert(std::make_pair(name, col));
104    }
105  }
106
107  int LpSoplex::_colByName(const std::string& name) const {
108    std::map<std::string, int>::const_iterator it =
109      invColNames.find(name);
110    if (it != invColNames.end()) {
111      return it->second;
112    } else {
113      return -1;
114    }
115  }
116 
117
118  void LpSoplex::_setRowCoeffs(int i, ConstRowIterator b, ConstRowIterator e) {
119    for (int j = 0; j < soplex->nCols(); ++j) {
120      soplex->changeElement(i, j, 0.0);
121    }
122    for(ConstRowIterator it = b; it != e; ++it) {
123      soplex->changeElement(i, it->first, it->second);
124    }
125    solved = false;
126  }
127
128  void LpSoplex::_getRowCoeffs(int i, RowIterator b) const {
129    const soplex::SVector& vec = soplex->rowVector(i);
130    for (int k = 0; k < vec.size(); ++k) {
131      *b = std::make_pair(vec.index(k), vec.value(k));
132      ++b;
133    }
134  }
135 
136  void LpSoplex::_setColCoeffs(int j, ConstColIterator b, ConstColIterator e) {
137    for (int i = 0; i < soplex->nRows(); ++i) {
138      soplex->changeElement(i, j, 0.0);
139    }
140    for(ConstColIterator it = b; it != e; ++it) {
141      soplex->changeElement(it->first, j, it->second);
142    }
143    solved = false;
144  }
145
146  void LpSoplex::_getColCoeffs(int i, ColIterator b) const {
147    const soplex::SVector& vec = soplex->colVector(i);
148    for (int k = 0; k < vec.size(); ++k) {
149      *b = std::make_pair(vec.index(k), vec.value(k));
150      ++b;
151    }
152  }
153 
154  void LpSoplex::_setCoeff(int i, int j, Value value) {
155    soplex->changeElement(i, j, value);
156    solved = false;
157  }
158
159  LpSoplex::Value LpSoplex::_getCoeff(int i, int j) const {
160    return soplex->rowVector(i)[j];
161  }
162
163  void LpSoplex::_setColLowerBound(int i, Value value) {
164    soplex->changeLower(i, value != -INF ? value : -soplex::infinity);
165    solved = false;
166  }
167 
168  LpSoplex::Value LpSoplex::_getColLowerBound(int i) const {
169    double value = soplex->lower(i);
170    return value != -soplex::infinity ? value : -INF;
171  }
172
173  void LpSoplex::_setColUpperBound(int i, Value value) {
174    soplex->changeUpper(i, value != INF ? value : soplex::infinity);
175    solved = false;
176  }
177
178  LpSoplex::Value LpSoplex::_getColUpperBound(int i) const {
179    double value = soplex->upper(i);
180    return value != soplex::infinity ? value : INF;
181  }
182
183  void LpSoplex::_setRowBounds(int i, Value lb, Value ub) {
184    soplex->changeRange(i, lb != -INF ? lb : -soplex::infinity,
185                        ub != INF ? ub : soplex::infinity);
186    solved = false;
187  }
188  void LpSoplex::_getRowBounds(int i, Value &lower, Value &upper) const {
189    lower = soplex->lhs(i);
190    if (lower == -soplex::infinity) lower = -INF;
191    upper = soplex->rhs(i);
192    if (upper == -soplex::infinity) upper = INF;
193  }
194
195  void LpSoplex::_setObjCoeff(int i, Value obj_coef) {
196    soplex->changeObj(i, obj_coef);
197    solved = false;
198  }
199
200  LpSoplex::Value LpSoplex::_getObjCoeff(int i) const {
201    return soplex->obj(i);
202  }
203
204  void LpSoplex::_clearObj() {
205    for (int i = 0; i < soplex->nCols(); ++i) {
206      soplex->changeObj(i, 0.0);
207    }
208    solved = false;
209  }
210
211  LpSoplex::SolveExitStatus LpSoplex::_solve() {
212    soplex::SPxSolver::Status status = soplex->solve();
213
214    soplex::Vector pv(primal_value.size(), &primal_value[0]);
215    soplex->getPrimal(pv);
216
217    soplex::Vector dv(dual_value.size(), &dual_value[0]);
218    soplex->getDual(dv);
219
220    switch (status) {
221    case soplex::SPxSolver::OPTIMAL:
222    case soplex::SPxSolver::INFEASIBLE:
223    case soplex::SPxSolver::UNBOUNDED:
224      solved = true;
225      return SOLVED;
226    default:
227      return UNSOLVED;
228    }
229  }
230
231  LpSoplex::Value LpSoplex::_getPrimal(int i) const {
232    return primal_value[i];
233  }
234
235  LpSoplex::Value LpSoplex::_getDual(int i) const {
236    return dual_value[i];
237  }
238 
239  LpSoplex::Value LpSoplex::_getPrimalValue() const {
240    return soplex->objValue();
241  }
242
243  bool LpSoplex::_isBasicCol(int i) const {
244    return soplex->getBasisColStatus(i) == soplex::SPxSolver::BASIC;
245  } 
246
247  LpSoplex::SolutionStatus LpSoplex::_getPrimalStatus() const {
248    if (!solved) return UNDEFINED;
249    switch (soplex->status()) {
250    case soplex::SPxSolver::OPTIMAL:
251      return OPTIMAL;
252    case soplex::SPxSolver::UNBOUNDED:
253      return INFINITE;
254    case soplex::SPxSolver::INFEASIBLE:
255      return INFEASIBLE;
256    default:
257      return UNDEFINED;
258    }
259  }
260
261  LpSoplex::SolutionStatus LpSoplex::_getDualStatus() const {
262    if (!solved) return UNDEFINED;
263    switch (soplex->status()) {
264    case soplex::SPxSolver::OPTIMAL:
265      return OPTIMAL;
266    case soplex::SPxSolver::UNBOUNDED:
267      return INFEASIBLE;
268    default:
269      return UNDEFINED;
270    }
271  }
272
273  LpSoplex::ProblemTypes LpSoplex::_getProblemType() const {
274    if (!solved) return UNKNOWN;
275    switch (soplex->status()) {
276    case soplex::SPxSolver::OPTIMAL:
277      return PRIMAL_DUAL_FEASIBLE;
278    case soplex::SPxSolver::UNBOUNDED:
279      return PRIMAL_FEASIBLE_DUAL_INFEASIBLE;
280    default:
281      return UNKNOWN;
282    }
283  }
284
285  void LpSoplex::_setMax() {
286    soplex->changeSense(soplex::SPxSolver::MAXIMIZE);
287    solved = false;
288  }
289  void LpSoplex::_setMin() {
290    soplex->changeSense(soplex::SPxSolver::MINIMIZE);
291    solved = false;
292  }
293  bool LpSoplex::_isMax() const {
294    return soplex->spxSense() == soplex::SPxSolver::MAXIMIZE;
295  }
296
297 
298} //namespace lemon
299
Note: See TracBrowser for help on using the repository browser.