lemon/lp_cplex.cc
changeset 2605 852361980706
parent 2591 3b4d5bc3b4fb
     1.1 --- a/lemon/lp_cplex.cc	Tue Apr 08 15:16:16 2008 +0000
     1.2 +++ b/lemon/lp_cplex.cc	Tue Apr 08 16:01:28 2008 +0000
     1.3 @@ -17,47 +17,47 @@
     1.4   */
     1.5  
     1.6  #include <iostream>
     1.7 +#include <vector>
     1.8  #include<lemon/lp_cplex.h>
     1.9  
    1.10  ///\file
    1.11  ///\brief Implementation of the LEMON-CPLEX lp solver interface.
    1.12  namespace lemon {
    1.13    
    1.14 -  LpCplex::LpCplex() : LpSolverBase() {
    1.15 +  LpCplex::LpCplex() {
    1.16      //    env = CPXopenCPLEXdevelop(&status);     
    1.17      env = CPXopenCPLEX(&status);     
    1.18      lp = CPXcreateprob(env, &status, "LP problem");
    1.19    }
    1.20 +
    1.21 +  LpCplex::LpCplex(const LpCplex& cplex) : LpSolverBase() {
    1.22 +    env = CPXopenCPLEX(&status);     
    1.23 +    lp = CPXcloneprob(env, cplex.lp, &status);
    1.24 +    rows = cplex.rows;
    1.25 +    cols = cplex.cols;
    1.26 +  }
    1.27    
    1.28    LpCplex::~LpCplex() {
    1.29 -    CPXfreeprob(env,&lp); 
    1.30 -    CPXcloseCPLEX(&env); 
    1.31 +    CPXfreeprob(env,&lp);
    1.32 +    CPXcloseCPLEX(&env);
    1.33    }
    1.34    
    1.35 -  LpSolverBase &LpCplex::_newLp() 
    1.36 +  LpSolverBase* LpCplex::_newLp() 
    1.37    {
    1.38      //The first approach opens a new environment
    1.39 -    LpCplex* newlp=new LpCplex();
    1.40 -    return *newlp;
    1.41 +    return new LpCplex();
    1.42    }
    1.43  
    1.44 -  LpSolverBase &LpCplex::_copyLp() {
    1.45 -    ///\bug FixID data is not copied!
    1.46 -    //The first approach opens a new environment
    1.47 -    LpCplex* newlp=new LpCplex();
    1.48 -    //The routine CPXcloneprob can be used to create a new CPLEX problem 
    1.49 -    //object and copy all the problem data from an existing problem 
    1.50 -    //object to it. Solution and starting information is not copied.
    1.51 -    newlp->lp = CPXcloneprob(env, lp, &status);
    1.52 -    return *newlp;
    1.53 +  LpSolverBase* LpCplex::_copyLp() {
    1.54 +    return new LpCplex(*this);
    1.55    }
    1.56  
    1.57    int LpCplex::_addCol()
    1.58    {
    1.59      int i = CPXgetnumcols(env, lp);
    1.60      Value lb[1],ub[1];
    1.61 -    lb[0]=-INF;//-CPX_INFBOUND;
    1.62 -    ub[0]=INF;//CPX_INFBOUND;
    1.63 +    lb[0]=-INF;
    1.64 +    ub[0]=INF;
    1.65      status = CPXnewcols(env, lp, 1, NULL, lb, ub, NULL, NULL);
    1.66      return i;
    1.67    }
    1.68 @@ -89,7 +89,11 @@
    1.69      ///\bug Untested
    1.70      int storespace;
    1.71      CPXgetcolname(env, lp, 0, 0, 0, &storespace, col, col);
    1.72 -
    1.73 +    if (storespace == 0) {
    1.74 +      name.clear();
    1.75 +      return;
    1.76 +    }
    1.77 +    
    1.78      storespace *= -1;
    1.79      std::vector<char> buf(storespace);
    1.80      char *names[1];
    1.81 @@ -136,6 +140,21 @@
    1.82    }
    1.83  
    1.84    void LpCplex::_getRowCoeffs(int i, RowIterator b) const {
    1.85 +    int tmp1, tmp2, tmp3, length;
    1.86 +    CPXgetrows(env, lp, &tmp1, &tmp2, 0, 0, 0, &length, i, i);
    1.87 +    
    1.88 +    length = -length;
    1.89 +    std::vector<int> indices(length);
    1.90 +    std::vector<double> values(length);
    1.91 +
    1.92 +    CPXgetrows(env, lp, &tmp1, &tmp2, &indices[0], &values[0], 
    1.93 +	       length, &tmp3, i, i);
    1.94 +    
    1.95 +    for (int i = 0; i < length; ++i) {
    1.96 +      *b = std::make_pair(indices[i], values[i]);
    1.97 +      ++b;
    1.98 +    }
    1.99 +    
   1.100      /// \todo implement
   1.101    }
   1.102    
   1.103 @@ -156,7 +175,22 @@
   1.104    }
   1.105  
   1.106    void LpCplex::_getColCoeffs(int i, ColIterator b) const {
   1.107 -    /// \todo implement
   1.108 +
   1.109 +    int tmp1, tmp2, tmp3, length;
   1.110 +    CPXgetcols(env, lp, &tmp1, &tmp2, 0, 0, 0, &length, i, i);
   1.111 +    
   1.112 +    length = -length;
   1.113 +    std::vector<int> indices(length);
   1.114 +    std::vector<double> values(length);
   1.115 +
   1.116 +    CPXgetcols(env, lp, &tmp1, &tmp2, &indices[0], &values[0], 
   1.117 +	       length, &tmp3, i, i);
   1.118 +    
   1.119 +    for (int i = 0; i < length; ++i) {
   1.120 +      *b = std::make_pair(indices[i], values[i]);
   1.121 +      ++b;
   1.122 +    }
   1.123 +    
   1.124    }
   1.125    
   1.126    void LpCplex::_setCoeff(int row, int col, Value value) 
   1.127 @@ -187,6 +221,7 @@
   1.128    {
   1.129      LpCplex::Value x;
   1.130      CPXgetlb (env, lp, &x, i, i);
   1.131 +    if (x <= -CPX_INFBOUND) x = -INF;
   1.132      return x;
   1.133    }
   1.134    
   1.135 @@ -205,6 +240,7 @@
   1.136    {
   1.137      LpCplex::Value x;
   1.138      CPXgetub (env, lp, &x, i, i);
   1.139 +    if (x >= CPX_INFBOUND) x = INF;
   1.140      return x;
   1.141    }
   1.142  
   1.143 @@ -469,8 +505,8 @@
   1.144  // Default: 0 
   1.145  // Description: Method for linear optimization. 
   1.146  // Determines which algorithm is used when CPXlpopt() (or "optimize" in the Interactive Optimizer) is called. Currently the behavior of the "Automatic" setting is that CPLEX simply invokes the dual simplex method, but this capability may be expanded in the future so that CPLEX chooses the method based on problem characteristics 
   1.147 +#if CPX_VERSION < 900
   1.148    void statusSwitch(CPXENVptr env,int& stat){
   1.149 -#if CPX_VERSION < 900
   1.150      int lpmethod;
   1.151      CPXgetintparam (env,CPX_PARAM_LPMETHOD,&lpmethod);
   1.152      if (lpmethod==2){
   1.153 @@ -482,8 +518,10 @@
   1.154  	  stat=CPX_UNBOUNDED;
   1.155        }
   1.156      }
   1.157 +  }
   1.158 +#else
   1.159 +  void statusSwitch(CPXENVptr,int&){}
   1.160  #endif
   1.161 -  }
   1.162  
   1.163    LpCplex::SolutionStatus LpCplex::_getPrimalStatus() const
   1.164    {