COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/lp_soplex.cc @ 2363:2aabce558574

Last change on this file since 2363:2aabce558574 was 2363:2aabce558574, checked in by Balazs Dezso, 17 years ago

Changes on the LP interface

_FixId => LpId?

  • handling of not common ids soplex

LpGlpk? row and col erase bug fix

  • calling lpx_std_basis before simplex

LpSoplex?

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