lemon/lp_soplex.cc
changeset 2363 2aabce558574
parent 2313 d9daf826e28a
child 2364 3a5e67bd42d2
     1.1 --- a/lemon/lp_soplex.cc	Thu Feb 15 13:06:23 2007 +0000
     1.2 +++ b/lemon/lp_soplex.cc	Thu Feb 15 14:22:08 2007 +0000
     1.3 @@ -27,7 +27,10 @@
     1.4  namespace lemon {
     1.5    
     1.6    LpSoplex::LpSoplex() : LpSolverBase() {
     1.7 +    rows.setIdHandler(relocateIdHandler);
     1.8 +    cols.setIdHandler(relocateIdHandler);
     1.9      soplex = new soplex::SoPlex;
    1.10 +    solved = false;
    1.11    }
    1.12    
    1.13    LpSoplex::~LpSoplex() {
    1.14 @@ -47,19 +50,25 @@
    1.15  
    1.16    int LpSoplex::_addCol() {
    1.17      soplex::LPCol col;
    1.18 +    col.setLower(-soplex::infinity);
    1.19 +    col.setUpper(soplex::infinity);
    1.20      soplex->addCol(col);
    1.21  
    1.22      colNames.push_back(std::string());
    1.23 -    primal.push_back(0.0);
    1.24 +    primal_value.push_back(0.0);
    1.25 +    solved = false;
    1.26  
    1.27      return soplex->nCols() - 1;
    1.28    }
    1.29  
    1.30    int LpSoplex::_addRow() {
    1.31      soplex::LPRow row;
    1.32 +    row.setLhs(-soplex::infinity);
    1.33 +    row.setRhs(soplex::infinity);
    1.34      soplex->addRow(row);
    1.35  
    1.36 -    dual.push_back(0.0);
    1.37 +    dual_value.push_back(0.0);
    1.38 +    solved = false;
    1.39  
    1.40      return soplex->nRows() - 1;
    1.41    }
    1.42 @@ -67,14 +76,18 @@
    1.43  
    1.44    void LpSoplex::_eraseCol(int i) {
    1.45      soplex->removeCol(i);
    1.46 -    primal[i] = primal.back();
    1.47 -    primal.pop_back();
    1.48 +    colNames[i] = colNames.back();
    1.49 +    colNames.pop_back();
    1.50 +    primal_value[i] = primal_value.back();
    1.51 +    primal_value.pop_back();
    1.52 +    solved = false;
    1.53    }
    1.54    
    1.55    void LpSoplex::_eraseRow(int i) {
    1.56      soplex->removeRow(i);
    1.57 -    dual[i] = dual.back();
    1.58 -    dual.pop_back();
    1.59 +    dual_value[i] = dual_value.back();
    1.60 +    dual_value.pop_back();
    1.61 +    solved = false;
    1.62    }
    1.63    
    1.64    void LpSoplex::_getColName(int col, std::string &name) {
    1.65 @@ -93,6 +106,7 @@
    1.66      for(LpRowIterator it = b; it != e; ++it) {
    1.67        soplex->changeElement(i, it->first, it->second);
    1.68      }
    1.69 +    solved = false;
    1.70    }
    1.71    
    1.72    void LpSoplex::_setColCoeffs(int j, LpColIterator b, LpColIterator e) {
    1.73 @@ -102,47 +116,80 @@
    1.74      for(LpColIterator it = b; it != e; ++it) {
    1.75        soplex->changeElement(it->first, j, it->second);
    1.76      }
    1.77 +    solved = false;
    1.78    }
    1.79    
    1.80 -  void LpSoplex::_setCoeff(int row, int col, Value value) {
    1.81 -    soplex->changeElement(row, col, value);
    1.82 +  void LpSoplex::_setCoeff(int i, int j, Value value) {
    1.83 +    soplex->changeElement(i, j, value);
    1.84 +    solved = false;
    1.85 +  }
    1.86 +
    1.87 +  LpSoplex::Value LpSoplex::_getCoeff(int i, int j) {
    1.88 +    return soplex->rowVector(i)[j];
    1.89    }
    1.90  
    1.91    void LpSoplex::_setColLowerBound(int i, Value value) {
    1.92 -    soplex->changeLower(i, value); 
    1.93 +    soplex->changeLower(i, value != -INF ? value : -soplex::infinity); 
    1.94 +    solved = false;
    1.95    }
    1.96    
    1.97 +  LpSoplex::Value LpSoplex::_getColLowerBound(int i) {
    1.98 +    double value = soplex->lower(i);
    1.99 +    return value != -soplex::infinity ? value : -INF;
   1.100 +  }
   1.101 +
   1.102    void LpSoplex::_setColUpperBound(int i, Value value) {
   1.103 -    soplex->changeUpper(i, value); 
   1.104 +    soplex->changeUpper(i, value != INF ? value : soplex::infinity); 
   1.105 +    solved = false;
   1.106 +  }
   1.107 +
   1.108 +  LpSoplex::Value LpSoplex::_getColUpperBound(int i) {
   1.109 +    double value = soplex->upper(i);
   1.110 +    return value != soplex::infinity ? value : INF;
   1.111    }
   1.112  
   1.113    void LpSoplex::_setRowBounds(int i, Value lb, Value ub) {
   1.114 -    soplex->changeRange(i, lb, ub);
   1.115 +    soplex->changeRange(i, lb != -INF ? lb : -soplex::infinity,
   1.116 +                        ub != INF ? ub : soplex::infinity);
   1.117 +    solved = false;
   1.118 +  }
   1.119 +  void LpSoplex::_getRowBounds(int i, Value &lower, Value &upper) {
   1.120 +    lower = soplex->lhs(i);
   1.121 +    if (lower == -soplex::infinity) lower = -INF;
   1.122 +    upper = soplex->rhs(i);
   1.123 +    if (upper == -soplex::infinity) upper = INF;
   1.124    }
   1.125  
   1.126    void LpSoplex::_setObjCoeff(int i, Value obj_coef) {
   1.127      soplex->changeObj(i, obj_coef);
   1.128 +    solved = false;
   1.129 +  }
   1.130 +
   1.131 +  LpSoplex::Value LpSoplex::_getObjCoeff(int i) {
   1.132 +    return soplex->obj(i);
   1.133    }
   1.134  
   1.135    void LpSoplex::_clearObj() {
   1.136      for (int i = 0; i < soplex->nCols(); ++i) {
   1.137        soplex->changeObj(i, 0.0);
   1.138      }
   1.139 +    solved = false;
   1.140    }
   1.141  
   1.142    LpSoplex::SolveExitStatus LpSoplex::_solve() {
   1.143      soplex::SPxSolver::Status status = soplex->solve();
   1.144  
   1.145 -    soplex::Vector pv(primal.size(), &primal[0]);
   1.146 +    soplex::Vector pv(primal_value.size(), &primal_value[0]);
   1.147      soplex->getPrimal(pv);
   1.148  
   1.149 -    soplex::Vector dv(dual.size(), &dual[0]);
   1.150 +    soplex::Vector dv(dual_value.size(), &dual_value[0]);
   1.151      soplex->getDual(dv);
   1.152  
   1.153      switch (status) {
   1.154      case soplex::SPxSolver::OPTIMAL:
   1.155      case soplex::SPxSolver::INFEASIBLE:
   1.156      case soplex::SPxSolver::UNBOUNDED:
   1.157 +      solved = true;
   1.158        return SOLVED;
   1.159      default:
   1.160        return UNSOLVED;
   1.161 @@ -150,11 +197,11 @@
   1.162    }
   1.163  
   1.164    LpSoplex::Value LpSoplex::_getPrimal(int i) {
   1.165 -    return primal[i];
   1.166 +    return primal_value[i];
   1.167    }
   1.168  
   1.169    LpSoplex::Value LpSoplex::_getDual(int i) {
   1.170 -    return dual[i];
   1.171 +    return dual_value[i];
   1.172    }
   1.173    
   1.174    LpSoplex::Value LpSoplex::_getPrimalValue() {
   1.175 @@ -166,6 +213,7 @@
   1.176    }  
   1.177  
   1.178    LpSoplex::SolutionStatus LpSoplex::_getPrimalStatus() {
   1.179 +    if (!solved) return UNDEFINED;
   1.180      switch (soplex->status()) {
   1.181      case soplex::SPxSolver::OPTIMAL:
   1.182        return OPTIMAL;
   1.183 @@ -179,30 +227,41 @@
   1.184    }
   1.185  
   1.186    LpSoplex::SolutionStatus LpSoplex::_getDualStatus() {
   1.187 -    switch (0) {
   1.188 -    case 0:
   1.189 -      return UNDEFINED;
   1.190 +    if (!solved) return UNDEFINED;
   1.191 +    switch (soplex->status()) {
   1.192 +    case soplex::SPxSolver::OPTIMAL:
   1.193        return OPTIMAL;
   1.194 +    case soplex::SPxSolver::UNBOUNDED:
   1.195        return INFEASIBLE;
   1.196 +    default:
   1.197        return UNDEFINED;
   1.198      }
   1.199    }
   1.200  
   1.201    LpSoplex::ProblemTypes LpSoplex::_getProblemType() {
   1.202 -    switch (0) {
   1.203 -    case 0:
   1.204 +    if (!solved) return UNKNOWN;
   1.205 +    switch (soplex->status()) {
   1.206 +    case soplex::SPxSolver::OPTIMAL:
   1.207        return PRIMAL_DUAL_FEASIBLE;
   1.208 +    case soplex::SPxSolver::UNBOUNDED:
   1.209        return PRIMAL_FEASIBLE_DUAL_INFEASIBLE;
   1.210 +    default:
   1.211        return UNKNOWN;
   1.212      }
   1.213    }
   1.214  
   1.215    void LpSoplex::_setMax() {
   1.216      soplex->changeSense(soplex::SPxSolver::MAXIMIZE);
   1.217 +    solved = false;
   1.218    }
   1.219    void LpSoplex::_setMin() {
   1.220      soplex->changeSense(soplex::SPxSolver::MINIMIZE);
   1.221 +    solved = false;
   1.222    }
   1.223 +  bool LpSoplex::_isMax() {
   1.224 +    return soplex->spxSense() == soplex::SPxSolver::MAXIMIZE;
   1.225 +  }
   1.226 +
   1.227    
   1.228  } //namespace lemon
   1.229