1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/lemon/lp_soplex.cc Wed Nov 29 17:30:21 2006 +0000
1.3 @@ -0,0 +1,208 @@
1.4 +/* -*- C++ -*-
1.5 + *
1.6 + * This file is a part of LEMON, a generic C++ optimization library
1.7 + *
1.8 + * Copyright (C) 2003-2006
1.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
1.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
1.11 + *
1.12 + * Permission to use, modify and distribute this software is granted
1.13 + * provided that this copyright notice appears in all copies. For
1.14 + * precise terms see the accompanying LICENSE file.
1.15 + *
1.16 + * This software is provided "AS IS" with no warranty of any kind,
1.17 + * express or implied, and with no claim as to its suitability for any
1.18 + * purpose.
1.19 + *
1.20 + */
1.21 +
1.22 +#include<iostream>
1.23 +#include<lemon/lp_soplex.h>
1.24 +
1.25 +#include <soplex/soplex.h>
1.26 +
1.27 +
1.28 +///\file
1.29 +///\brief Implementation of the LEMON-SOPLEX lp solver interface.
1.30 +namespace lemon {
1.31 +
1.32 + LpSoplex::LpSoplex() : LpSolverBase() {
1.33 + soplex = new soplex::SoPlex;
1.34 + }
1.35 +
1.36 + LpSoplex::~LpSoplex() {
1.37 + delete soplex;
1.38 + }
1.39 +
1.40 + LpSolverBase &LpSoplex::_newLp() {
1.41 + LpSoplex* newlp = new LpSoplex();
1.42 + return *newlp;
1.43 + }
1.44 +
1.45 + LpSolverBase &LpSoplex::_copyLp() {
1.46 + LpSoplex* newlp = new LpSoplex();
1.47 + ((soplex::SPxLP&)*(newlp->soplex)) = *soplex;
1.48 + return *newlp;
1.49 + }
1.50 +
1.51 + int LpSoplex::_addCol() {
1.52 + soplex::LPCol col;
1.53 + soplex->addCol(col);
1.54 +
1.55 + colNames.push_back(std::string());
1.56 + primal.push_back(0.0);
1.57 +
1.58 + return soplex->nCols() - 1;
1.59 + }
1.60 +
1.61 + int LpSoplex::_addRow() {
1.62 + soplex::LPRow row;
1.63 + soplex->addRow(row);
1.64 +
1.65 + dual.push_back(0.0);
1.66 +
1.67 + return soplex->nRows() - 1;
1.68 + }
1.69 +
1.70 +
1.71 + void LpSoplex::_eraseCol(int i) {
1.72 + soplex->removeCol(i);
1.73 + primal[i] = primal.back();
1.74 + primal.pop_back();
1.75 + }
1.76 +
1.77 + void LpSoplex::_eraseRow(int i) {
1.78 + soplex->removeRow(i);
1.79 + dual[i] = dual.back();
1.80 + dual.pop_back();
1.81 + }
1.82 +
1.83 + void LpSoplex::_getColName(int col, std::string &name) {
1.84 + name = colNames[col];
1.85 + }
1.86 +
1.87 + void LpSoplex::_setColName(int col, const std::string &name) {
1.88 + colNames[col] = name;
1.89 + }
1.90 +
1.91 +
1.92 + void LpSoplex::_setRowCoeffs(int i, LpRowIterator b, LpRowIterator e) {
1.93 + for (int j = 0; j < soplex->nCols(); ++j) {
1.94 + soplex->changeElement(i, j, 0.0);
1.95 + }
1.96 + for(LpRowIterator it = b; it != e; ++it) {
1.97 + soplex->changeElement(i, it->first, it->second);
1.98 + }
1.99 + }
1.100 +
1.101 + void LpSoplex::_setColCoeffs(int j, LpColIterator b, LpColIterator e) {
1.102 + for (int i = 0; i < soplex->nRows(); ++i) {
1.103 + soplex->changeElement(i, j, 0.0);
1.104 + }
1.105 + for(LpColIterator it = b; it != e; ++it) {
1.106 + soplex->changeElement(it->first, j, it->second);
1.107 + }
1.108 + }
1.109 +
1.110 + void LpSoplex::_setCoeff(int row, int col, Value value) {
1.111 + soplex->changeElement(row, col, value);
1.112 + }
1.113 +
1.114 + void LpSoplex::_setColLowerBound(int i, Value value) {
1.115 + soplex->changeLower(i, value);
1.116 + }
1.117 +
1.118 + void LpSoplex::_setColUpperBound(int i, Value value) {
1.119 + soplex->changeUpper(i, value);
1.120 + }
1.121 +
1.122 + void LpSoplex::_setRowBounds(int i, Value lb, Value ub) {
1.123 + soplex->changeRange(i, lb, ub);
1.124 + }
1.125 +
1.126 + void LpSoplex::_setObjCoeff(int i, Value obj_coef) {
1.127 + soplex->changeObj(i, obj_coef);
1.128 + }
1.129 +
1.130 + void LpSoplex::_clearObj() {
1.131 + for (int i = 0; i < soplex->nCols(); ++i) {
1.132 + soplex->changeObj(i, 0.0);
1.133 + }
1.134 + }
1.135 +
1.136 + LpSoplex::SolveExitStatus LpSoplex::_solve() {
1.137 + soplex::SPxSolver::Status status = soplex->solve();
1.138 +
1.139 + soplex::Vector pv(primal.size(), &primal[0]);
1.140 + soplex->getPrimal(pv);
1.141 +
1.142 + soplex::Vector dv(dual.size(), &dual[0]);
1.143 + soplex->getDual(dv);
1.144 +
1.145 + switch (status) {
1.146 + case soplex::SPxSolver::OPTIMAL:
1.147 + case soplex::SPxSolver::INFEASIBLE:
1.148 + case soplex::SPxSolver::UNBOUNDED:
1.149 + return SOLVED;
1.150 + default:
1.151 + return UNSOLVED;
1.152 + }
1.153 + }
1.154 +
1.155 + LpSoplex::Value LpSoplex::_getPrimal(int i) {
1.156 + return primal[i];
1.157 + }
1.158 +
1.159 + LpSoplex::Value LpSoplex::_getDual(int i) {
1.160 + return dual[i];
1.161 + }
1.162 +
1.163 + LpSoplex::Value LpSoplex::_getPrimalValue() {
1.164 + return soplex->objValue();
1.165 + }
1.166 +
1.167 + bool LpSoplex::_isBasicCol(int i) {
1.168 + return soplex->getBasisColStatus(i) == soplex::SPxSolver::BASIC;
1.169 + }
1.170 +
1.171 + LpSoplex::SolutionStatus LpSoplex::_getPrimalStatus() {
1.172 + switch (soplex->status()) {
1.173 + case soplex::SPxSolver::OPTIMAL:
1.174 + return OPTIMAL;
1.175 + case soplex::SPxSolver::UNBOUNDED:
1.176 + return INFINITE;
1.177 + case soplex::SPxSolver::INFEASIBLE:
1.178 + return INFEASIBLE;
1.179 + default:
1.180 + return UNDEFINED;
1.181 + }
1.182 + }
1.183 +
1.184 + LpSoplex::SolutionStatus LpSoplex::_getDualStatus() {
1.185 + switch (0) {
1.186 + case 0:
1.187 + return UNDEFINED;
1.188 + return OPTIMAL;
1.189 + return INFEASIBLE;
1.190 + return UNDEFINED;
1.191 + }
1.192 + }
1.193 +
1.194 + LpSoplex::ProblemTypes LpSoplex::_getProblemType() {
1.195 + switch (0) {
1.196 + case 0:
1.197 + return PRIMAL_DUAL_FEASIBLE;
1.198 + return PRIMAL_FEASIBLE_DUAL_INFEASIBLE;
1.199 + return UNKNOWN;
1.200 + }
1.201 + }
1.202 +
1.203 + void LpSoplex::_setMax() {
1.204 + soplex->changeSense(soplex::SPxSolver::MAXIMIZE);
1.205 + }
1.206 + void LpSoplex::_setMin() {
1.207 + soplex->changeSense(soplex::SPxSolver::MINIMIZE);
1.208 + }
1.209 +
1.210 +} //namespace lemon
1.211 +