[Lemon-commits] [lemon_svn] athos: r2037 - in hugo/trunk: lemon test

Lemon SVN svn at lemon.cs.elte.hu
Mon Nov 6 20:49:41 CET 2006


Author: athos
Date: Thu Jul  7 17:00:04 2005
New Revision: 2037

Modified:
   hugo/trunk/lemon/lp_base.h
   hugo/trunk/lemon/lp_cplex.cc
   hugo/trunk/test/lp_test.cc

Log:
Some testing of the LP interface: bugs got fixed.

Modified: hugo/trunk/lemon/lp_base.h
==============================================================================
--- hugo/trunk/lemon/lp_base.h	(original)
+++ hugo/trunk/lemon/lp_base.h	Thu Jul  7 17:00:04 2005
@@ -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<int> 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
 

Modified: hugo/trunk/lemon/lp_cplex.cc
==============================================================================
--- hugo/trunk/lemon/lp_cplex.cc	(original)
+++ hugo/trunk/lemon/lp_cplex.cc	Thu Jul  7 17:00:04 2005
@@ -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

Modified: hugo/trunk/test/lp_test.cc
==============================================================================
--- hugo/trunk/test/lp_test.cc	(original)
+++ hugo/trunk/test/lp_test.cc	Thu Jul  7 17:00:04 2005
@@ -1,6 +1,7 @@
 #include<lemon/lp_skeleton.h>
 #include "test_tools.h"
 
+
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #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 = "<<lp.primalValue()
-	     << " (error = " << lp.primalValue()-opt
-	     << "); x1 = "<<lp.primal(x1)
-	     << "; x2 = "<<lp.primal(x2)
-	     <<std::endl;
-    
-  }
-  else{
-    std::cout<<"Optimal solution not found!"<<std::endl;
-  }
+  //Minimization
+  lp.min();
+  expected_opt=0;
+  solveAndCheck(lp, LpSolverBase::OPTIMAL, expected_opt);
+  
+  //Vertex (-1,0) instead of (0,0)
+  lp.colLowerBound(x1, -LpSolverBase::INF);
+  expected_opt=-1;
+  solveAndCheck(lp, LpSolverBase::OPTIMAL, expected_opt);
 
-  check(lp.primalStatus()==LpSolverBase::OPTIMAL,"Primalstatus should be OPTIMAL");
+  //Erase one constraint and return to maximization
+  lp.eraseRow(upright);
+  lp.max();
+  expected_opt=LpSolverBase::INF;
+  solveAndCheck(lp, LpSolverBase::INFINITE, expected_opt);
 
-  check(std::abs(lp.primalValue()-opt)<1e-3,
-	"Wrong optimal value: the right optimum is 122/9 (13.555555...)");
+  //Infeasibilty
+  lp.addRow(x1+x2 <=-2);  
+  solveAndCheck(lp, LpSolverBase::INFEASIBLE, expected_opt);
+
+  //Change problem and forget to solve
+  lp.min();
+  check(lp.primalStatus()==LpSolverBase::UNDEFINED,"Primalstatus should be UNDEFINED");
+
+//   lp.solve();
+//   if (lp.primalStatus()==LpSolverBase::OPTIMAL){
+//     std::cout<< "Z = "<<lp.primalValue()
+// 	     << " (error = " << lp.primalValue()-expected_opt
+// 	     << "); x1 = "<<lp.primal(x1)
+// 	     << "; x2 = "<<lp.primal(x2)
+// 	     <<std::endl;
+    
+//   }
+//   else{
+//     std::cout<<lp.primalStatus()<<std::endl;
+//     std::cout<<"Optimal solution not found!"<<std::endl;
+//   }
 
+ 
 
 }
 



More information about the Lemon-commits mailing list