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 {