1.1 --- a/test/lp_test.cc Tue Dec 02 21:40:33 2008 +0100
1.2 +++ b/test/lp_test.cc Tue Dec 02 22:48:28 2008 +0100
1.3 @@ -37,14 +37,16 @@
1.4 #include <lemon/lp_soplex.h>
1.5 #endif
1.6
1.7 +#ifdef HAVE_CLP
1.8 +#include <lemon/lp_clp.h>
1.9 +#endif
1.10 +
1.11 using namespace lemon;
1.12
1.13 -void lpTest(LpSolverBase & lp)
1.14 +void lpTest(LpSolver& lp)
1.15 {
1.16
1.17 -
1.18 -
1.19 - typedef LpSolverBase LP;
1.20 + typedef LpSolver LP;
1.21
1.22 std::vector<LP::Col> x(10);
1.23 // for(int i=0;i<10;i++) x.push_back(lp.addCol());
1.24 @@ -52,7 +54,6 @@
1.25 lp.colLowerBound(x,1);
1.26 lp.colUpperBound(x,1);
1.27 lp.colBounds(x,1,2);
1.28 -#ifndef GYORSITAS
1.29
1.30 std::vector<LP::Col> y(10);
1.31 lp.addColSet(y);
1.32 @@ -86,11 +87,11 @@
1.33 p5=lp.addCol();
1.34
1.35 e[p1]=2;
1.36 - e.constComp()=12;
1.37 + *e=12;
1.38 e[p1]+=2;
1.39 - e.constComp()+=12;
1.40 + *e+=12;
1.41 e[p1]-=2;
1.42 - e.constComp()-=12;
1.43 + *e-=12;
1.44
1.45 e=2;
1.46 e=2.2;
1.47 @@ -170,11 +171,11 @@
1.48 e[x[3]]=2;
1.49 e[x[3]]=4;
1.50 e[x[3]]=1;
1.51 - e.constComp()=12;
1.52 + *e=12;
1.53
1.54 - lp.addRow(LP::INF,e,23);
1.55 - lp.addRow(LP::INF,3.0*(x[1]+x[2]/2)-x[3],23);
1.56 - lp.addRow(LP::INF,3.0*(x[1]+x[2]*2-5*x[3]+12-x[4]/3)+2*x[4]-4,23);
1.57 + lp.addRow(-LP::INF,e,23);
1.58 + lp.addRow(-LP::INF,3.0*(x[1]+x[2]/2)-x[3],23);
1.59 + lp.addRow(-LP::INF,3.0*(x[1]+x[2]*2-5*x[3]+12-x[4]/3)+2*x[4]-4,23);
1.60
1.61 lp.addRow(x[1]+x[3]<=x[5]-3);
1.62 lp.addRow(-7<=x[1]+x[3]-12<=3);
1.63 @@ -183,21 +184,6 @@
1.64 std::ostringstream buf;
1.65
1.66
1.67 - //Checking the simplify function
1.68 -
1.69 -// //How to check the simplify function? A map gives no information
1.70 -// //on the question whether a given key is or is not stored in it, or
1.71 -// //it does?
1.72 -// Yes, it does, using the find() function.
1.73 - e=((p1+p2)+(p1-p2));
1.74 - e.simplify();
1.75 - buf << "Coeff. of p2 should be 0";
1.76 - // std::cout<<e[p1]<<e[p2]<<e[p3]<<std::endl;
1.77 - check(e.find(p2)==e.end(), buf.str());
1.78 -
1.79 -
1.80 -
1.81 -
1.82 e=((p1+p2)+(p1-0.99*p2));
1.83 //e.prettyPrint(std::cout);
1.84 //(e<=2).prettyPrint(std::cout);
1.85 @@ -209,7 +195,7 @@
1.86 tolerance=0.02;
1.87 e.simplify(tolerance);
1.88 buf << "Coeff. of p2 should be 0";
1.89 - check(e.find(p2)==e.end(), buf.str());
1.90 + check(const_cast<const LpSolver::Expr&>(e)[p2]==0, buf.str());
1.91
1.92
1.93 }
1.94 @@ -247,36 +233,33 @@
1.95 );
1.96 }
1.97
1.98 -#endif
1.99 }
1.100
1.101 -void solveAndCheck(LpSolverBase& lp, LpSolverBase::SolutionStatus stat,
1.102 +void solveAndCheck(LpSolver& lp, LpSolver::ProblemType stat,
1.103 double exp_opt) {
1.104 using std::string;
1.105 lp.solve();
1.106 - //int decimal,sign;
1.107 +
1.108 std::ostringstream buf;
1.109 - buf << "Primalstatus should be: " << int(stat);
1.110 + buf << "PrimalType should be: " << int(stat) << int(lp.primalType());
1.111
1.112 - // itoa(stat,buf1, 10);
1.113 - check(lp.primalStatus()==stat, buf.str());
1.114 + check(lp.primalType()==stat, buf.str());
1.115
1.116 - if (stat == LpSolverBase::OPTIMAL) {
1.117 + if (stat == LpSolver::OPTIMAL) {
1.118 std::ostringstream sbuf;
1.119 sbuf << "Wrong optimal value: the right optimum is " << exp_opt;
1.120 - check(std::abs(lp.primalValue()-exp_opt) < 1e-3, sbuf.str());
1.121 - //+ecvt(exp_opt,2)
1.122 + check(std::abs(lp.primal()-exp_opt) < 1e-3, sbuf.str());
1.123 }
1.124 }
1.125
1.126 -void aTest(LpSolverBase & lp)
1.127 +void aTest(LpSolver & lp)
1.128 {
1.129 - typedef LpSolverBase LP;
1.130 + typedef LpSolver LP;
1.131
1.132 //The following example is very simple
1.133
1.134 - typedef LpSolverBase::Row Row;
1.135 - typedef LpSolverBase::Col Col;
1.136 + typedef LpSolver::Row Row;
1.137 + typedef LpSolver::Col Col;
1.138
1.139
1.140 Col x1 = lp.addCol();
1.141 @@ -284,7 +267,7 @@
1.142
1.143
1.144 //Constraints
1.145 - Row upright=lp.addRow(x1+x2 <=1);
1.146 + Row upright=lp.addRow(x1+2*x2 <=1);
1.147 lp.addRow(x1+x2 >=-1);
1.148 lp.addRow(x1-x2 <=1);
1.149 lp.addRow(x1-x2 >=-1);
1.150 @@ -294,129 +277,126 @@
1.151 //Objective function
1.152 lp.obj(x1+x2);
1.153
1.154 - lp.max();
1.155 + lp.sense(lp.MAX);
1.156
1.157 //Testing the problem retrieving routines
1.158 check(lp.objCoeff(x1)==1,"First term should be 1 in the obj function!");
1.159 - check(lp.isMax(),"This is a maximization!");
1.160 + check(lp.sense() == lp.MAX,"This is a maximization!");
1.161 check(lp.coeff(upright,x1)==1,"The coefficient in question is 1!");
1.162 - // std::cout<<lp.colLowerBound(x1)<<std::endl;
1.163 - check( lp.colLowerBound(x1)==0,
1.164 - "The lower bound for variable x1 should be 0.");
1.165 - check( lp.colUpperBound(x1)==LpSolverBase::INF,
1.166 - "The upper bound for variable x1 should be infty.");
1.167 - LpSolverBase::Value lb,ub;
1.168 - lp.getRowBounds(upright,lb,ub);
1.169 - check( lb==-LpSolverBase::INF,
1.170 - "The lower bound for the first row should be -infty.");
1.171 - check( ub==1,"The upper bound for the first row should be 1.");
1.172 - LpSolverBase::Expr e = lp.row(upright);
1.173 - check( e.size() == 2, "The row retrieval gives back wrong expression.");
1.174 - check( e[x1] == 1, "The first coefficient should 1.");
1.175 - check( e[x2] == 1, "The second coefficient should 1.");
1.176 + check(lp.colLowerBound(x1)==0,
1.177 + "The lower bound for variable x1 should be 0.");
1.178 + check(lp.colUpperBound(x1)==LpSolver::INF,
1.179 + "The upper bound for variable x1 should be infty.");
1.180 + check(lp.rowLowerBound(upright) == -LpSolver::INF,
1.181 + "The lower bound for the first row should be -infty.");
1.182 + check(lp.rowUpperBound(upright)==1,
1.183 + "The upper bound for the first row should be 1.");
1.184 + LpSolver::Expr e = lp.row(upright);
1.185 + check(e[x1] == 1, "The first coefficient should 1.");
1.186 + check(e[x2] == 2, "The second coefficient should 1.");
1.187
1.188 - LpSolverBase::DualExpr de = lp.col(x1);
1.189 - check( de.size() == 4, "The col retrieval gives back wrong expression.");
1.190 + lp.row(upright, x1+x2 <=1);
1.191 + e = lp.row(upright);
1.192 + check(e[x1] == 1, "The first coefficient should 1.");
1.193 + check(e[x2] == 1, "The second coefficient should 1.");
1.194 +
1.195 + LpSolver::DualExpr de = lp.col(x1);
1.196 check( de[upright] == 1, "The first coefficient should 1.");
1.197
1.198 - LpSolverBase* clp = lp.copyLp();
1.199 + LpSolver* clp = lp.cloneSolver();
1.200
1.201 //Testing the problem retrieving routines
1.202 check(clp->objCoeff(x1)==1,"First term should be 1 in the obj function!");
1.203 - check(clp->isMax(),"This is a maximization!");
1.204 + check(clp->sense() == clp->MAX,"This is a maximization!");
1.205 check(clp->coeff(upright,x1)==1,"The coefficient in question is 1!");
1.206 // std::cout<<lp.colLowerBound(x1)<<std::endl;
1.207 - check( clp->colLowerBound(x1)==0,
1.208 - "The lower bound for variable x1 should be 0.");
1.209 - check( clp->colUpperBound(x1)==LpSolverBase::INF,
1.210 - "The upper bound for variable x1 should be infty.");
1.211 + check(clp->colLowerBound(x1)==0,
1.212 + "The lower bound for variable x1 should be 0.");
1.213 + check(clp->colUpperBound(x1)==LpSolver::INF,
1.214 + "The upper bound for variable x1 should be infty.");
1.215
1.216 - clp->getRowBounds(upright,lb,ub);
1.217 - check( lb==-LpSolverBase::INF,
1.218 - "The lower bound for the first row should be -infty.");
1.219 - check( ub==1,"The upper bound for the first row should be 1.");
1.220 + check(lp.rowLowerBound(upright)==-LpSolver::INF,
1.221 + "The lower bound for the first row should be -infty.");
1.222 + check(lp.rowUpperBound(upright)==1,
1.223 + "The upper bound for the first row should be 1.");
1.224 e = clp->row(upright);
1.225 - check( e.size() == 2, "The row retrieval gives back wrong expression.");
1.226 - check( e[x1] == 1, "The first coefficient should 1.");
1.227 - check( e[x2] == 1, "The second coefficient should 1.");
1.228 + check(e[x1] == 1, "The first coefficient should 1.");
1.229 + check(e[x2] == 1, "The second coefficient should 1.");
1.230
1.231 de = clp->col(x1);
1.232 - check( de.size() == 4, "The col retrieval gives back wrong expression.");
1.233 - check( de[upright] == 1, "The first coefficient should 1.");
1.234 + check(de[upright] == 1, "The first coefficient should 1.");
1.235
1.236 delete clp;
1.237
1.238 //Maximization of x1+x2
1.239 //over the triangle with vertices (0,0) (0,1) (1,0)
1.240 double expected_opt=1;
1.241 - solveAndCheck(lp, LpSolverBase::OPTIMAL, expected_opt);
1.242 + solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
1.243
1.244 //Minimization
1.245 - lp.min();
1.246 + lp.sense(lp.MIN);
1.247 expected_opt=0;
1.248 - solveAndCheck(lp, LpSolverBase::OPTIMAL, expected_opt);
1.249 + solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
1.250
1.251 //Vertex (-1,0) instead of (0,0)
1.252 - lp.colLowerBound(x1, -LpSolverBase::INF);
1.253 + lp.colLowerBound(x1, -LpSolver::INF);
1.254 expected_opt=-1;
1.255 - solveAndCheck(lp, LpSolverBase::OPTIMAL, expected_opt);
1.256 + solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
1.257
1.258 //Erase one constraint and return to maximization
1.259 - lp.eraseRow(upright);
1.260 - lp.max();
1.261 - expected_opt=LpSolverBase::INF;
1.262 - solveAndCheck(lp, LpSolverBase::INFINITE, expected_opt);
1.263 + lp.erase(upright);
1.264 + lp.sense(lp.MAX);
1.265 + expected_opt=LpSolver::INF;
1.266 + solveAndCheck(lp, LpSolver::UNBOUNDED, expected_opt);
1.267
1.268 //Infeasibilty
1.269 lp.addRow(x1+x2 <=-2);
1.270 - solveAndCheck(lp, LpSolverBase::INFEASIBLE, expected_opt);
1.271 -
1.272 - //Change problem and forget to solve
1.273 - lp.min();
1.274 - check(lp.primalStatus()==LpSolverBase::UNDEFINED,
1.275 - "Primalstatus should be UNDEFINED");
1.276 -
1.277 -
1.278 -// lp.solve();
1.279 -// if (lp.primalStatus()==LpSolverBase::OPTIMAL){
1.280 -// std::cout<< "Z = "<<lp.primalValue()
1.281 -// << " (error = " << lp.primalValue()-expected_opt
1.282 -// << "); x1 = "<<lp.primal(x1)
1.283 -// << "; x2 = "<<lp.primal(x2)
1.284 -// <<std::endl;
1.285 -
1.286 -// }
1.287 -// else{
1.288 -// std::cout<<lp.primalStatus()<<std::endl;
1.289 -// std::cout<<"Optimal solution not found!"<<std::endl;
1.290 -// }
1.291 -
1.292 -
1.293 + solveAndCheck(lp, LpSolver::INFEASIBLE, expected_opt);
1.294
1.295 }
1.296
1.297 -
1.298 int main()
1.299 {
1.300 LpSkeleton lp_skel;
1.301 lpTest(lp_skel);
1.302
1.303 #ifdef HAVE_GLPK
1.304 - LpGlpk lp_glpk1,lp_glpk2;
1.305 - lpTest(lp_glpk1);
1.306 - aTest(lp_glpk2);
1.307 + {
1.308 + LpGlpk lp_glpk1,lp_glpk2;
1.309 + lpTest(lp_glpk1);
1.310 + aTest(lp_glpk2);
1.311 + }
1.312 #endif
1.313
1.314 #ifdef HAVE_CPLEX
1.315 - LpCplex lp_cplex1,lp_cplex2;
1.316 - lpTest(lp_cplex1);
1.317 - aTest(lp_cplex2);
1.318 + try {
1.319 + LpCplex lp_cplex1,lp_cplex2;
1.320 + lpTest(lp_cplex1);
1.321 + aTest(lp_cplex2);
1.322 + } catch (CplexEnv::LicenseError& error) {
1.323 +#ifdef LEMON_FORCE_CPLEX_CHECK
1.324 + check(false, error.what());
1.325 +#else
1.326 + std::cerr << error.what() << std::endl;
1.327 + std::cerr << "Cplex license check failed, lp check skipped" << std::endl;
1.328 +#endif
1.329 + }
1.330 #endif
1.331
1.332 #ifdef HAVE_SOPLEX
1.333 - LpSoplex lp_soplex1,lp_soplex2;
1.334 - lpTest(lp_soplex1);
1.335 - aTest(lp_soplex2);
1.336 + {
1.337 + LpSoplex lp_soplex1,lp_soplex2;
1.338 + lpTest(lp_soplex1);
1.339 + aTest(lp_soplex2);
1.340 + }
1.341 +#endif
1.342 +
1.343 +#ifdef HAVE_CLP
1.344 + {
1.345 + LpClp lp_clp1,lp_clp2;
1.346 + lpTest(lp_clp1);
1.347 + aTest(lp_clp2);
1.348 + }
1.349 #endif
1.350
1.351 return 0;