COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/lp_soplex.cc @ 2367:041878e6f388

Last change on this file since 2367:041878e6f388 was 2366:bfbdded3763a, checked in by Balazs Dezso, 17 years ago

Using const in lp interface
colByName functionality

File size: 7.5 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    colNames[i] = colNames.back();
80    colNames.pop_back();
81    primal_value[i] = primal_value.back();
82    primal_value.pop_back();
83    solved = false;
84  }
85 
86  void LpSoplex::_eraseRow(int i) {
87    soplex->removeRow(i);
88    dual_value[i] = dual_value.back();
89    dual_value.pop_back();
90    solved = false;
91  }
92 
93  void LpSoplex::_getColName(int col, std::string &name) const {
94    name = colNames[col];
95  }
96 
97  void LpSoplex::_setColName(int col, const std::string &name) {
98    invColNames.erase(colNames[col]);
99    colNames[col] = name;
100    if (!name.empty()) {
101      invColNames.insert(std::make_pair(name, col));
102    }
103  }
104
105  int LpSoplex::_colByName(const std::string& name) const {
106    std::map<std::string, int>::const_iterator it =
107      invColNames.find(name);
108    if (it != invColNames.end()) {
109      return it->second;
110    } else {
111      return -1;
112    }
113  }
114 
115
116  void LpSoplex::_setRowCoeffs(int i, ConstRowIterator b, ConstRowIterator e) {
117    for (int j = 0; j < soplex->nCols(); ++j) {
118      soplex->changeElement(i, j, 0.0);
119    }
120    for(ConstRowIterator it = b; it != e; ++it) {
121      soplex->changeElement(i, it->first, it->second);
122    }
123    solved = false;
124  }
125
126  void LpSoplex::_getRowCoeffs(int i, RowIterator b) const {
127    const soplex::SVector& vec = soplex->rowVector(i);
128    for (int k = 0; k < vec.size(); ++k) {
129      *b = std::make_pair(vec.index(k), vec.value(k));
130      ++b;
131    }
132  }
133 
134  void LpSoplex::_setColCoeffs(int j, ConstColIterator b, ConstColIterator e) {
135    for (int i = 0; i < soplex->nRows(); ++i) {
136      soplex->changeElement(i, j, 0.0);
137    }
138    for(ConstColIterator it = b; it != e; ++it) {
139      soplex->changeElement(it->first, j, it->second);
140    }
141    solved = false;
142  }
143
144  void LpSoplex::_getColCoeffs(int i, ColIterator b) const {
145    const soplex::SVector& vec = soplex->colVector(i);
146    for (int k = 0; k < vec.size(); ++k) {
147      *b = std::make_pair(vec.index(k), vec.value(k));
148      ++b;
149    }
150  }
151 
152  void LpSoplex::_setCoeff(int i, int j, Value value) {
153    soplex->changeElement(i, j, value);
154    solved = false;
155  }
156
157  LpSoplex::Value LpSoplex::_getCoeff(int i, int j) const {
158    return soplex->rowVector(i)[j];
159  }
160
161  void LpSoplex::_setColLowerBound(int i, Value value) {
162    soplex->changeLower(i, value != -INF ? value : -soplex::infinity);
163    solved = false;
164  }
165 
166  LpSoplex::Value LpSoplex::_getColLowerBound(int i) const {
167    double value = soplex->lower(i);
168    return value != -soplex::infinity ? value : -INF;
169  }
170
171  void LpSoplex::_setColUpperBound(int i, Value value) {
172    soplex->changeUpper(i, value != INF ? value : soplex::infinity);
173    solved = false;
174  }
175
176  LpSoplex::Value LpSoplex::_getColUpperBound(int i) const {
177    double value = soplex->upper(i);
178    return value != soplex::infinity ? value : INF;
179  }
180
181  void LpSoplex::_setRowBounds(int i, Value lb, Value ub) {
182    soplex->changeRange(i, lb != -INF ? lb : -soplex::infinity,
183                        ub != INF ? ub : soplex::infinity);
184    solved = false;
185  }
186  void LpSoplex::_getRowBounds(int i, Value &lower, Value &upper) const {
187    lower = soplex->lhs(i);
188    if (lower == -soplex::infinity) lower = -INF;
189    upper = soplex->rhs(i);
190    if (upper == -soplex::infinity) upper = INF;
191  }
192
193  void LpSoplex::_setObjCoeff(int i, Value obj_coef) {
194    soplex->changeObj(i, obj_coef);
195    solved = false;
196  }
197
198  LpSoplex::Value LpSoplex::_getObjCoeff(int i) const {
199    return soplex->obj(i);
200  }
201
202  void LpSoplex::_clearObj() {
203    for (int i = 0; i < soplex->nCols(); ++i) {
204      soplex->changeObj(i, 0.0);
205    }
206    solved = false;
207  }
208
209  LpSoplex::SolveExitStatus LpSoplex::_solve() {
210    soplex::SPxSolver::Status status = soplex->solve();
211
212    soplex::Vector pv(primal_value.size(), &primal_value[0]);
213    soplex->getPrimal(pv);
214
215    soplex::Vector dv(dual_value.size(), &dual_value[0]);
216    soplex->getDual(dv);
217
218    switch (status) {
219    case soplex::SPxSolver::OPTIMAL:
220    case soplex::SPxSolver::INFEASIBLE:
221    case soplex::SPxSolver::UNBOUNDED:
222      solved = true;
223      return SOLVED;
224    default:
225      return UNSOLVED;
226    }
227  }
228
229  LpSoplex::Value LpSoplex::_getPrimal(int i) const {
230    return primal_value[i];
231  }
232
233  LpSoplex::Value LpSoplex::_getDual(int i) const {
234    return dual_value[i];
235  }
236 
237  LpSoplex::Value LpSoplex::_getPrimalValue() const {
238    return soplex->objValue();
239  }
240
241  bool LpSoplex::_isBasicCol(int i) const {
242    return soplex->getBasisColStatus(i) == soplex::SPxSolver::BASIC;
243  } 
244
245  LpSoplex::SolutionStatus LpSoplex::_getPrimalStatus() const {
246    if (!solved) return UNDEFINED;
247    switch (soplex->status()) {
248    case soplex::SPxSolver::OPTIMAL:
249      return OPTIMAL;
250    case soplex::SPxSolver::UNBOUNDED:
251      return INFINITE;
252    case soplex::SPxSolver::INFEASIBLE:
253      return INFEASIBLE;
254    default:
255      return UNDEFINED;
256    }
257  }
258
259  LpSoplex::SolutionStatus LpSoplex::_getDualStatus() const {
260    if (!solved) return UNDEFINED;
261    switch (soplex->status()) {
262    case soplex::SPxSolver::OPTIMAL:
263      return OPTIMAL;
264    case soplex::SPxSolver::UNBOUNDED:
265      return INFEASIBLE;
266    default:
267      return UNDEFINED;
268    }
269  }
270
271  LpSoplex::ProblemTypes LpSoplex::_getProblemType() const {
272    if (!solved) return UNKNOWN;
273    switch (soplex->status()) {
274    case soplex::SPxSolver::OPTIMAL:
275      return PRIMAL_DUAL_FEASIBLE;
276    case soplex::SPxSolver::UNBOUNDED:
277      return PRIMAL_FEASIBLE_DUAL_INFEASIBLE;
278    default:
279      return UNKNOWN;
280    }
281  }
282
283  void LpSoplex::_setMax() {
284    soplex->changeSense(soplex::SPxSolver::MAXIMIZE);
285    solved = false;
286  }
287  void LpSoplex::_setMin() {
288    soplex->changeSense(soplex::SPxSolver::MINIMIZE);
289    solved = false;
290  }
291  bool LpSoplex::_isMax() const {
292    return soplex->spxSense() == soplex::SPxSolver::MAXIMIZE;
293  }
294
295 
296} //namespace lemon
297
Note: See TracBrowser for help on using the repository browser.