1.1 --- a/lemon/clp.cc Thu Feb 26 09:39:02 2009 +0000
1.2 +++ b/lemon/clp.cc Thu Feb 26 07:39:16 2009 +0000
1.3 @@ -56,12 +56,12 @@
1.4 }
1.5 }
1.6
1.7 - ClpLp* ClpLp::_newSolver() const {
1.8 + ClpLp* ClpLp::newSolver() const {
1.9 ClpLp* newlp = new ClpLp;
1.10 return newlp;
1.11 }
1.12
1.13 - ClpLp* ClpLp::_cloneSolver() const {
1.14 + ClpLp* ClpLp::cloneSolver() const {
1.15 ClpLp* copylp = new ClpLp(*this);
1.16 return copylp;
1.17 }
2.1 --- a/lemon/clp.h Thu Feb 26 09:39:02 2009 +0000
2.2 +++ b/lemon/clp.h Thu Feb 26 07:39:16 2009 +0000
2.3 @@ -56,6 +56,11 @@
2.4 /// \e
2.5 ~ClpLp();
2.6
2.7 + /// \e
2.8 + virtual ClpLp* newSolver() const;
2.9 + /// \e
2.10 + virtual ClpLp* cloneSolver() const;
2.11 +
2.12 protected:
2.13
2.14 mutable double* _primal_ray;
2.15 @@ -66,9 +71,6 @@
2.16
2.17 protected:
2.18
2.19 - virtual ClpLp* _newSolver() const;
2.20 - virtual ClpLp* _cloneSolver() const;
2.21 -
2.22 virtual const char* _solverName() const;
2.23
2.24 virtual int _addCol();
3.1 --- a/lemon/cplex.cc Thu Feb 26 09:39:02 2009 +0000
3.2 +++ b/lemon/cplex.cc Thu Feb 26 07:39:16 2009 +0000
3.3 @@ -451,8 +451,8 @@
3.4
3.5 CplexLp::~CplexLp() {}
3.6
3.7 - CplexLp* CplexLp::_newSolver() const { return new CplexLp; }
3.8 - CplexLp* CplexLp::_cloneSolver() const {return new CplexLp(*this); }
3.9 + CplexLp* CplexLp::newSolver() const { return new CplexLp; }
3.10 + CplexLp* CplexLp::cloneSolver() const {return new CplexLp(*this); }
3.11
3.12 const char* CplexLp::_solverName() const { return "CplexLp"; }
3.13
3.14 @@ -823,8 +823,8 @@
3.15
3.16 CplexMip::~CplexMip() {}
3.17
3.18 - CplexMip* CplexMip::_newSolver() const { return new CplexMip; }
3.19 - CplexMip* CplexMip::_cloneSolver() const {return new CplexMip(*this); }
3.20 + CplexMip* CplexMip::newSolver() const { return new CplexMip; }
3.21 + CplexMip* CplexMip::cloneSolver() const {return new CplexMip(*this); }
3.22
3.23 const char* CplexMip::_solverName() const { return "CplexMip"; }
3.24
4.1 --- a/lemon/cplex.h Thu Feb 26 09:39:02 2009 +0000
4.2 +++ b/lemon/cplex.h Thu Feb 26 07:39:16 2009 +0000
4.3 @@ -160,7 +160,7 @@
4.4 ///
4.5 /// This class implements an interface for the CPLEX LP solver.
4.6 ///\ingroup lp_group
4.7 - class CplexLp : public CplexBase, public LpSolver {
4.8 + class CplexLp : public LpSolver, public CplexBase {
4.9 public:
4.10 /// \e
4.11 CplexLp();
4.12 @@ -171,6 +171,11 @@
4.13 /// \e
4.14 virtual ~CplexLp();
4.15
4.16 + /// \e
4.17 + virtual CplexLp* cloneSolver() const;
4.18 + /// \e
4.19 + virtual CplexLp* newSolver() const;
4.20 +
4.21 private:
4.22
4.23 // these values cannot retrieved element by element
4.24 @@ -186,9 +191,6 @@
4.25
4.26 protected:
4.27
4.28 - virtual CplexLp* _cloneSolver() const;
4.29 - virtual CplexLp* _newSolver() const;
4.30 -
4.31 virtual const char* _solverName() const;
4.32
4.33 virtual SolveExitStatus _solve();
4.34 @@ -222,7 +224,7 @@
4.35 ///
4.36 /// This class implements an interface for the CPLEX MIP solver.
4.37 ///\ingroup lp_group
4.38 - class CplexMip : public CplexBase, public MipSolver {
4.39 + class CplexMip : public MipSolver, public CplexBase {
4.40 public:
4.41 /// \e
4.42 CplexMip();
5.1 --- a/lemon/glpk.cc Thu Feb 26 09:39:02 2009 +0000
5.2 +++ b/lemon/glpk.cc Thu Feb 26 07:39:16 2009 +0000
5.3 @@ -534,8 +534,8 @@
5.4 messageLevel(MESSAGE_NO_OUTPUT);
5.5 }
5.6
5.7 - GlpkLp* GlpkLp::_newSolver() const { return new GlpkLp; }
5.8 - GlpkLp* GlpkLp::_cloneSolver() const { return new GlpkLp(*this); }
5.9 + GlpkLp* GlpkLp::newSolver() const { return new GlpkLp; }
5.10 + GlpkLp* GlpkLp::cloneSolver() const { return new GlpkLp(*this); }
5.11
5.12 const char* GlpkLp::_solverName() const { return "GlpkLp"; }
5.13
5.14 @@ -940,8 +940,8 @@
5.15 return glp_mip_obj_val(lp);
5.16 }
5.17
5.18 - GlpkMip* GlpkMip::_newSolver() const { return new GlpkMip; }
5.19 - GlpkMip* GlpkMip::_cloneSolver() const {return new GlpkMip(*this); }
5.20 + GlpkMip* GlpkMip::newSolver() const { return new GlpkMip; }
5.21 + GlpkMip* GlpkMip::cloneSolver() const {return new GlpkMip(*this); }
5.22
5.23 const char* GlpkMip::_solverName() const { return "GlpkMip"; }
5.24
6.1 --- a/lemon/glpk.h Thu Feb 26 09:39:02 2009 +0000
6.2 +++ b/lemon/glpk.h Thu Feb 26 07:39:16 2009 +0000
6.3 @@ -119,7 +119,7 @@
6.4 ///
6.5 /// This class implements an interface for the GLPK LP solver.
6.6 ///\ingroup lp_group
6.7 - class GlpkLp : public GlpkBase, public LpSolver {
6.8 + class GlpkLp : public LpSolver, public GlpkBase {
6.9 public:
6.10
6.11 ///\e
6.12 @@ -127,6 +127,11 @@
6.13 ///\e
6.14 GlpkLp(const GlpkLp&);
6.15
6.16 + ///\e
6.17 + virtual GlpkLp* cloneSolver() const;
6.18 + ///\e
6.19 + virtual GlpkLp* newSolver() const;
6.20 +
6.21 private:
6.22
6.23 mutable std::vector<double> _primal_ray;
6.24 @@ -136,9 +141,6 @@
6.25
6.26 protected:
6.27
6.28 - virtual GlpkLp* _cloneSolver() const;
6.29 - virtual GlpkLp* _newSolver() const;
6.30 -
6.31 virtual const char* _solverName() const;
6.32
6.33 virtual SolveExitStatus _solve();
6.34 @@ -203,7 +205,7 @@
6.35 ///
6.36 /// This class implements an interface for the GLPK MIP solver.
6.37 ///\ingroup lp_group
6.38 - class GlpkMip : public GlpkBase, public MipSolver {
6.39 + class GlpkMip : public MipSolver, public GlpkBase {
6.40 public:
6.41
6.42 ///\e
6.43 @@ -211,11 +213,11 @@
6.44 ///\e
6.45 GlpkMip(const GlpkMip&);
6.46
6.47 + virtual GlpkMip* cloneSolver() const;
6.48 + virtual GlpkMip* newSolver() const;
6.49 +
6.50 protected:
6.51
6.52 - virtual GlpkMip* _cloneSolver() const;
6.53 - virtual GlpkMip* _newSolver() const;
6.54 -
6.55 virtual const char* _solverName() const;
6.56
6.57 virtual ColTypes _getColType(int col) const;
7.1 --- a/lemon/lp_base.h Thu Feb 26 09:39:02 2009 +0000
7.2 +++ b/lemon/lp_base.h Thu Feb 26 07:39:16 2009 +0000
7.3 @@ -918,8 +918,6 @@
7.4 protected:
7.5
7.6 //Abstract virtual functions
7.7 - virtual LpBase* _newSolver() const = 0;
7.8 - virtual LpBase* _cloneSolver() const = 0;
7.9
7.10 virtual int _addColId(int col) { return cols.addIndex(col); }
7.11 virtual int _addRowId(int row) { return rows.addIndex(row); }
7.12 @@ -987,11 +985,6 @@
7.13 /// Virtual destructor
7.14 virtual ~LpBase() {}
7.15
7.16 - ///Creates a new LP problem
7.17 - LpBase* newSolver() {return _newSolver();}
7.18 - ///Makes a copy of the LP problem
7.19 - LpBase* cloneSolver() {return _cloneSolver();}
7.20 -
7.21 ///Gives back the name of the solver.
7.22 const char* solverName() const {return _solverName();}
7.23
7.24 @@ -1821,6 +1814,11 @@
7.25
7.26 public:
7.27
7.28 + ///Allocate a new LP problem instance
7.29 + virtual LpSolver* newSolver() const = 0;
7.30 + ///Make a copy of the LP problem
7.31 + virtual LpSolver* cloneSolver() const = 0;
7.32 +
7.33 ///\name Solve the LP
7.34
7.35 ///@{
7.36 @@ -1935,13 +1933,8 @@
7.37 Value primal() const { return _getPrimalValue()+obj_const_comp;}
7.38 ///@}
7.39
7.40 - LpSolver* newSolver() {return _newSolver();}
7.41 - LpSolver* cloneSolver() {return _cloneSolver();}
7.42 -
7.43 protected:
7.44
7.45 - virtual LpSolver* _newSolver() const = 0;
7.46 - virtual LpSolver* _cloneSolver() const = 0;
7.47 };
7.48
7.49
7.50 @@ -1975,6 +1968,11 @@
7.51 UNBOUNDED = 4
7.52 };
7.53
7.54 + ///Allocate a new MIP problem instance
7.55 + virtual MipSolver* newSolver() const = 0;
7.56 + ///Make a copy of the MIP problem
7.57 + virtual MipSolver* cloneSolver() const = 0;
7.58 +
7.59 ///\name Solve the MIP
7.60
7.61 ///@{
7.62 @@ -2062,15 +2060,6 @@
7.63 virtual Value _getSol(int i) const = 0;
7.64 virtual Value _getSolValue() const = 0;
7.65
7.66 - public:
7.67 -
7.68 - MipSolver* newSolver() {return _newSolver();}
7.69 - MipSolver* cloneSolver() {return _cloneSolver();}
7.70 -
7.71 - protected:
7.72 -
7.73 - virtual MipSolver* _newSolver() const = 0;
7.74 - virtual MipSolver* _cloneSolver() const = 0;
7.75 };
7.76
7.77
8.1 --- a/lemon/lp_skeleton.cc Thu Feb 26 09:39:02 2009 +0000
8.2 +++ b/lemon/lp_skeleton.cc Thu Feb 26 07:39:16 2009 +0000
8.3 @@ -105,10 +105,10 @@
8.4 LpSkeleton::VarStatus LpSkeleton::_getRowStatus(int) const
8.5 { return BASIC; }
8.6
8.7 - LpSkeleton* LpSkeleton::_newSolver() const
8.8 + LpSkeleton* LpSkeleton::newSolver() const
8.9 { return static_cast<LpSkeleton*>(0); }
8.10
8.11 - LpSkeleton* LpSkeleton::_cloneSolver() const
8.12 + LpSkeleton* LpSkeleton::cloneSolver() const
8.13 { return static_cast<LpSkeleton*>(0); }
8.14
8.15 const char* LpSkeleton::_solverName() const { return "LpSkeleton"; }
8.16 @@ -122,10 +122,10 @@
8.17 MipSkeleton::ProblemType MipSkeleton::_getType() const
8.18 { return UNDEFINED; }
8.19
8.20 - MipSkeleton* MipSkeleton::_newSolver() const
8.21 + MipSkeleton* MipSkeleton::newSolver() const
8.22 { return static_cast<MipSkeleton*>(0); }
8.23
8.24 - MipSkeleton* MipSkeleton::_cloneSolver() const
8.25 + MipSkeleton* MipSkeleton::cloneSolver() const
8.26 { return static_cast<MipSkeleton*>(0); }
8.27
8.28 const char* MipSkeleton::_solverName() const { return "MipSkeleton"; }
9.1 --- a/lemon/lp_skeleton.h Thu Feb 26 09:39:02 2009 +0000
9.2 +++ b/lemon/lp_skeleton.h Thu Feb 26 07:39:16 2009 +0000
9.3 @@ -22,10 +22,16 @@
9.4 #include <lemon/lp_base.h>
9.5
9.6 ///\file
9.7 -///\brief A skeleton file to implement LP solver interfaces
9.8 +///\brief Skeleton file to implement LP/MIP solver interfaces
9.9 +///
9.10 +///The classes in this file do nothing, but they can serve as skeletons when
9.11 +///implementing an interface to new solvers.
9.12 namespace lemon {
9.13
9.14 - ///A skeleton class to implement LP solver interfaces
9.15 + ///A skeleton class to implement LP/MIP solver base interface
9.16 +
9.17 + ///This class does nothing, but it can serve as a skeleton when
9.18 + ///implementing an interface to new solvers.
9.19 class SkeletonSolverBase : public virtual LpBase {
9.20 int col_num,row_num;
9.21
9.22 @@ -136,14 +142,20 @@
9.23
9.24 };
9.25
9.26 - /// \brief Interface for a skeleton LP solver
9.27 + /// \brief Skeleton class for an LP solver interface
9.28 ///
9.29 - /// This class implements an interface for a skeleton LP solver.
9.30 + ///This class does nothing, but it can serve as a skeleton when
9.31 + ///implementing an interface to new solvers.
9.32 +
9.33 ///\ingroup lp_group
9.34 - class LpSkeleton : public SkeletonSolverBase, public LpSolver {
9.35 + class LpSkeleton : public LpSolver, public SkeletonSolverBase {
9.36 public:
9.37 - LpSkeleton() : SkeletonSolverBase(), LpSolver() {}
9.38 -
9.39 + ///\e
9.40 + LpSkeleton() : LpSolver(), SkeletonSolverBase() {}
9.41 + ///\e
9.42 + virtual LpSkeleton* newSolver() const;
9.43 + ///\e
9.44 + virtual LpSkeleton* cloneSolver() const;
9.45 protected:
9.46
9.47 ///\e
9.48 @@ -173,21 +185,23 @@
9.49 virtual VarStatus _getRowStatus(int i) const;
9.50
9.51 ///\e
9.52 - virtual LpSkeleton* _newSolver() const;
9.53 - ///\e
9.54 - virtual LpSkeleton* _cloneSolver() const;
9.55 - ///\e
9.56 virtual const char* _solverName() const;
9.57
9.58 };
9.59
9.60 - /// \brief Interface for a skeleton MIP solver
9.61 + /// \brief Skeleton class for a MIP solver interface
9.62 ///
9.63 - /// This class implements an interface for a skeleton MIP solver.
9.64 + ///This class does nothing, but it can serve as a skeleton when
9.65 + ///implementing an interface to new solvers.
9.66 ///\ingroup lp_group
9.67 - class MipSkeleton : public SkeletonSolverBase, public MipSolver {
9.68 + class MipSkeleton : public MipSolver, public SkeletonSolverBase {
9.69 public:
9.70 - MipSkeleton() : SkeletonSolverBase(), MipSolver() {}
9.71 + ///\e
9.72 + MipSkeleton() : MipSolver(), SkeletonSolverBase() {}
9.73 + ///\e
9.74 + virtual MipSkeleton* newSolver() const;
9.75 + ///\e
9.76 + virtual MipSkeleton* cloneSolver() const;
9.77
9.78 protected:
9.79 ///\e
9.80 @@ -215,13 +229,7 @@
9.81 virtual ProblemType _getType() const;
9.82
9.83 ///\e
9.84 - virtual MipSkeleton* _newSolver() const;
9.85 -
9.86 - ///\e
9.87 - virtual MipSkeleton* _cloneSolver() const;
9.88 - ///\e
9.89 virtual const char* _solverName() const;
9.90 -
9.91 };
9.92
9.93 } //namespace lemon
10.1 --- a/lemon/soplex.cc Thu Feb 26 09:39:02 2009 +0000
10.2 +++ b/lemon/soplex.cc Thu Feb 26 07:39:16 2009 +0000
10.3 @@ -54,12 +54,12 @@
10.4 _dual_values.clear();
10.5 }
10.6
10.7 - SoplexLp* SoplexLp::_newSolver() const {
10.8 + SoplexLp* SoplexLp::newSolver() const {
10.9 SoplexLp* newlp = new SoplexLp();
10.10 return newlp;
10.11 }
10.12
10.13 - SoplexLp* SoplexLp::_cloneSolver() const {
10.14 + SoplexLp* SoplexLp::cloneSolver() const {
10.15 SoplexLp* newlp = new SoplexLp(*this);
10.16 return newlp;
10.17 }
11.1 --- a/lemon/soplex.h Thu Feb 26 09:39:02 2009 +0000
11.2 +++ b/lemon/soplex.h Thu Feb 26 07:39:16 2009 +0000
11.3 @@ -73,12 +73,13 @@
11.4 SoplexLp(const SoplexLp&);
11.5 /// \e
11.6 ~SoplexLp();
11.7 + /// \e
11.8 + virtual SoplexLp* newSolver() const;
11.9 + /// \e
11.10 + virtual SoplexLp* cloneSolver() const;
11.11
11.12 protected:
11.13
11.14 - virtual SoplexLp* _newSolver() const;
11.15 - virtual SoplexLp* _cloneSolver() const;
11.16 -
11.17 virtual const char* _solverName() const;
11.18
11.19 virtual int _addCol();
12.1 --- a/test/lp_test.cc Thu Feb 26 09:39:02 2009 +0000
12.2 +++ b/test/lp_test.cc Thu Feb 26 07:39:16 2009 +0000
12.3 @@ -197,6 +197,11 @@
12.4 buf << "Coeff. of p2 should be 0";
12.5 check(const_cast<const LpSolver::Expr&>(e)[p2]==0, buf.str());
12.6
12.7 + //Test for clone/new
12.8 + LP* lpnew = lp.newSolver();
12.9 + LP* lpclone = lp.cloneSolver();
12.10 + delete lpnew;
12.11 + delete lpclone;
12.12
12.13 }
12.14
12.15 @@ -247,7 +252,8 @@
12.16
12.17 if (stat == LpSolver::OPTIMAL) {
12.18 std::ostringstream sbuf;
12.19 - sbuf << "Wrong optimal value: the right optimum is " << exp_opt;
12.20 + sbuf << "Wrong optimal value (" << lp.primal() <<") with "
12.21 + << lp.solverName() <<"\n the right optimum is " << exp_opt;
12.22 check(std::abs(lp.primal()-exp_opt) < 1e-3, sbuf.str());
12.23 }
12.24 }
12.25 @@ -355,6 +361,19 @@
12.26
12.27 }
12.28
12.29 +template<class LP>
12.30 +void cloneTest()
12.31 +{
12.32 + //Test for clone/new
12.33 +
12.34 + LP* lp = new LP();
12.35 + LP* lpnew = lp->newSolver();
12.36 + LP* lpclone = lp->cloneSolver();
12.37 + delete lp;
12.38 + delete lpnew;
12.39 + delete lpclone;
12.40 +}
12.41 +
12.42 int main()
12.43 {
12.44 LpSkeleton lp_skel;
12.45 @@ -365,6 +384,7 @@
12.46 GlpkLp lp_glpk1,lp_glpk2;
12.47 lpTest(lp_glpk1);
12.48 aTest(lp_glpk2);
12.49 + cloneTest<GlpkLp>();
12.50 }
12.51 #endif
12.52
12.53 @@ -381,6 +401,7 @@
12.54 std::cerr << "Cplex license check failed, lp check skipped" << std::endl;
12.55 #endif
12.56 }
12.57 + cloneTest<CplexLp>();
12.58 #endif
12.59
12.60 #ifdef HAVE_SOPLEX
12.61 @@ -388,6 +409,7 @@
12.62 SoplexLp lp_soplex1,lp_soplex2;
12.63 lpTest(lp_soplex1);
12.64 aTest(lp_soplex2);
12.65 + cloneTest<SoplexLp>();
12.66 }
12.67 #endif
12.68
12.69 @@ -396,6 +418,7 @@
12.70 ClpLp lp_clp1,lp_clp2;
12.71 lpTest(lp_clp1);
12.72 aTest(lp_clp2);
12.73 + cloneTest<ClpLp>();
12.74 }
12.75 #endif
12.76
13.1 --- a/test/mip_test.cc Thu Feb 26 09:39:02 2009 +0000
13.2 +++ b/test/mip_test.cc Thu Feb 26 07:39:16 2009 +0000
13.3 @@ -106,6 +106,17 @@
13.4
13.5 }
13.6
13.7 +template<class MIP>
13.8 +void cloneTest()
13.9 +{
13.10 +
13.11 + MIP* mip = new MIP();
13.12 + MIP* mipnew = mip->newSolver();
13.13 + MIP* mipclone = mip->cloneSolver();
13.14 + delete mip;
13.15 + delete mipnew;
13.16 + delete mipclone;
13.17 +}
13.18
13.19 int main()
13.20 {
13.21 @@ -114,6 +125,7 @@
13.22 {
13.23 GlpkMip mip1;
13.24 aTest(mip1);
13.25 + cloneTest<GlpkMip>();
13.26 }
13.27 #endif
13.28
13.29 @@ -129,6 +141,7 @@
13.30 std::cerr << "Cplex license check failed, lp check skipped" << std::endl;
13.31 #endif
13.32 }
13.33 + cloneTest<CplexMip>();
13.34 #endif
13.35
13.36 return 0;