# HG changeset patch # User athos # Date 1120748404 0 # Node ID 0219ee65ffcc64034998007f22067370fdfc3685 # Parent 305ce06287c97f795c02f836125a16ea7e65380e Some testing of the LP interface: bugs got fixed. diff -r 305ce06287c9 -r 0219ee65ffcc lemon/lp_base.h --- a/lemon/lp_base.h Thu Jul 07 09:04:39 2005 +0000 +++ b/lemon/lp_base.h Thu Jul 07 15:00:04 2005 +0000 @@ -138,19 +138,19 @@ INFINITE = 4 }; - ///\e The type of the investigated LP problem - enum ProblemTypes { - ///Primal-dual feasible - PRIMAL_DUAL_FEASIBLE = 0, - ///Primal feasible dual infeasible - PRIMAL_FEASIBLE_DUAL_INFEASIBLE = 1, - ///Primal infeasible dual feasible - PRIMAL_INFEASIBLE_DUAL_FEASIBLE = 2, - ///Primal-dual infeasible - PRIMAL_DUAL_INFEASIBLE = 3, - ///Could not determine so far - UNKNOWN = 4 - }; + ///\e The type of the investigated LP problem + enum ProblemTypes { + ///Primal-dual feasible + PRIMAL_DUAL_FEASIBLE = 0, + ///Primal feasible dual infeasible + PRIMAL_FEASIBLE_DUAL_INFEASIBLE = 1, + ///Primal infeasible dual feasible + PRIMAL_INFEASIBLE_DUAL_FEASIBLE = 2, + ///Primal-dual infeasible + PRIMAL_DUAL_INFEASIBLE = 3, + ///Could not determine so far + UNKNOWN = 4 + }; ///The floating point type used by the solver typedef double Value; @@ -552,6 +552,8 @@ virtual int _addCol() = 0; virtual int _addRow() = 0; + virtual void _eraseCol(int col) = 0; + virtual void _eraseRow(int row) = 0; virtual void _setRowCoeffs(int i, int length, int const * indices, @@ -680,7 +682,7 @@ ///\param c is the column to be modified ///\param e is a dual linear expression (see \ref DualExpr) - ///\bug This is a temportary function. The interface will change to + ///\bug This is a temporary function. The interface will change to ///a better one. void setCol(Col c,const DualExpr &e) { std::vector indices; @@ -717,8 +719,8 @@ ///\return The created row Row addRow() { Row r; r.id=rows.insert(_addRow()); return r;} - ///\brief Adds several new row - ///(i.e a variables) at once + ///\brief Add several new rows + ///(i.e a constraints) at once /// ///This magic function takes a container as its argument ///and fills its elements @@ -843,6 +845,22 @@ setRow(r,c); return r; } + ///Erase a coloumn (i.e a variable) from the LP + + ///\param c is the coloumn to be deleted + ///\todo Please check this + void eraseCol(Col c) { + _eraseCol(cols.floatingId(c.id)); + cols.erase(c.id); + } + ///Erase a row (i.e a constraint) from the LP + + ///\param r is the row to be deleted + ///\todo Please check this + void eraseRow(Row r) { + _eraseRow(rows.floatingId(r.id)); + rows.erase(r.id); + } ///Set an element of the coefficient matrix of the LP diff -r 305ce06287c9 -r 0219ee65ffcc lemon/lp_cplex.cc --- a/lemon/lp_cplex.cc Thu Jul 07 09:04:39 2005 +0000 +++ b/lemon/lp_cplex.cc Thu Jul 07 15:00:04 2005 +0000 @@ -242,6 +242,7 @@ { //CPX_PARAM_LPMETHOD status = CPXlpopt(env, lp); + //status = CPXprimopt(env, lp); if (status == 0){ //We want to exclude some cases switch (CPXgetstat(env, lp)){ @@ -327,11 +328,40 @@ // ??case CPX_ABORT_DUAL_INFEAS // ??case CPX_ABORT_CROSSOVER // ??case CPX_INForUNBD -// ??case CPX_PIVOT +// ??case CPX_PIVOT + +//Some more interesting stuff: + +// CPX_PARAM_LPMETHOD 1062 int LPMETHOD +// 0 Automatic +// 1 Primal Simplex +// 2 Dual Simplex +// 3 Network Simplex +// 4 Standard Barrier +// Default: 0 +// Description: Method for linear optimization. +// 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 + //Hulye cplex + void statusSwitch(CPXENVptr env,int& stat){ + int lpmethod; + CPXgetintparam (env,CPX_PARAM_LPMETHOD,&lpmethod); + if (lpmethod==2){ + if (stat==CPX_UNBOUNDED){ + stat=CPX_INFEASIBLE; + } + else{ + if (stat==CPX_INFEASIBLE) + stat=CPX_UNBOUNDED; + } + } + } LpCplex::SolutionStatus LpCplex::_getPrimalStatus() { + int stat = CPXgetstat(env, lp); + statusSwitch(env,stat); + //CPXgetstat(env, lp); //printf("A primal status: %d, CPX_OPTIMAL=%d \n",stat,CPX_OPTIMAL); switch (stat) { case 0: @@ -339,7 +369,8 @@ case CPX_OPTIMAL://Optimal return OPTIMAL; case CPX_UNBOUNDED://Unbounded - return INFINITE; + return INFEASIBLE;//In case of dual simplex + //return INFINITE; case CPX_INFEASIBLE://Infeasible // case CPX_IT_LIM_INFEAS: // case CPX_TIME_LIM_INFEAS: @@ -348,7 +379,8 @@ // case CPX_ABORT_INFEAS: // case CPX_ABORT_PRIM_INFEAS: // case CPX_ABORT_PRIM_DUAL_INFEAS: - return INFEASIBLE; + return INFINITE;//In case of dual simplex + //return INFEASIBLE; // case CPX_OBJ_LIM: // case CPX_IT_LIM_FEAS: // case CPX_TIME_LIM_FEAS: @@ -383,6 +415,7 @@ LpCplex::SolutionStatus LpCplex::_getDualStatus() { int stat = CPXgetstat(env, lp); + statusSwitch(env,stat); switch (stat) { case 0: return UNDEFINED; //Undefined diff -r 305ce06287c9 -r 0219ee65ffcc test/lp_test.cc --- a/test/lp_test.cc Thu Jul 07 09:04:39 2005 +0000 +++ b/test/lp_test.cc Thu Jul 07 15:00:04 2005 +0000 @@ -1,6 +1,7 @@ #include #include "test_tools.h" + #ifdef HAVE_CONFIG_H #include #endif @@ -182,11 +183,26 @@ #endif } +void solveAndCheck(LpSolverBase& lp, LpSolverBase::SolutionStatus stat, + double exp_opt){ + lp.solve(); + //int decimal,sign; + std::string buf1; + // itoa(stat,buf1, 10); + check(lp.primalStatus()==stat,"Primalstatus should be "+buf1); + + if (stat == LpSolverBase::OPTIMAL){ + check(std::abs(lp.primalValue()-exp_opt)<1e-3, + "Wrong optimal value: the right optimum is "); + //+ecvt(exp_opt,2) + } +} + void aTest(LpSolverBase & lp) { typedef LpSolverBase LP; - //The following example is taken from the book by Gáspár and Temesi, page 39. + //The following example is very simple typedef LpSolverBase::Row Row; typedef LpSolverBase::Col Col; @@ -197,38 +213,62 @@ //Constraints - lp.addRow(3*x1+2*x2 >=6); - lp.addRow(-1*x1+x2<=4); - lp.addRow(5*x1+8*x2<=40); - lp.addRow(x1-2*x2<=4); + Row upright=lp.addRow(x1+x2 <=1); + lp.addRow(x1+x2 >=-1); + lp.addRow(x1-x2 <=1); + lp.addRow(x1-x2 >=-1); //Nonnegativity of the variables lp.colLowerBound(x1, 0); lp.colLowerBound(x2, 0); //Objective function - lp.setObj(2*x1+x2); + lp.setObj(x1+x2); lp.max(); - lp.solve(); - double opt=122.0/9.0; + //Maximization of x1+x2 + //over the triangle with vertices (0,0) (0,1) (1,0) + double expected_opt=1; + solveAndCheck(lp, LpSolverBase::OPTIMAL, expected_opt); - if (lp.primalStatus()==LpSolverBase::OPTIMAL){ - std::cout<< "Z = "<