COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/lp_soplex.cc @ 2364:3a5e67bd42d2

Last change on this file since 2364:3a5e67bd42d2 was 2364:3a5e67bd42d2, checked in by Balazs Dezso, 17 years ago

Lp row and col getter function
lp section reader and writer for lemon IO

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