gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Fix newSolver()/cloneSolver() API in LP tools + doc improvements (#230) - More logical structure for newSolver()/cloneSolver() - Fix compilation problem with gcc-3.3 - Doc improvements
0 13 0
default
13 files changed with 118 insertions and 78 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
... ...
@@ -56,12 +56,12 @@
56 56
    }
57 57
  }
58 58

	
59
  ClpLp* ClpLp::_newSolver() const {
59
  ClpLp* ClpLp::newSolver() const {
60 60
    ClpLp* newlp = new ClpLp;
61 61
    return newlp;
62 62
  }
63 63

	
64
  ClpLp* ClpLp::_cloneSolver() const {
64
  ClpLp* ClpLp::cloneSolver() const {
65 65
    ClpLp* copylp = new ClpLp(*this);
66 66
    return copylp;
67 67
  }
Ignore white space 6 line context
... ...
@@ -56,6 +56,11 @@
56 56
    /// \e
57 57
    ~ClpLp();
58 58

	
59
    /// \e
60
    virtual ClpLp* newSolver() const;
61
    /// \e
62
    virtual ClpLp* cloneSolver() const;
63

	
59 64
  protected:
60 65

	
61 66
    mutable double* _primal_ray;
... ...
@@ -66,9 +71,6 @@
66 71

	
67 72
  protected:
68 73

	
69
    virtual ClpLp* _newSolver() const;
70
    virtual ClpLp* _cloneSolver() const;
71

	
72 74
    virtual const char* _solverName() const;
73 75

	
74 76
    virtual int _addCol();
Ignore white space 6 line context
... ...
@@ -451,8 +451,8 @@
451 451

	
452 452
  CplexLp::~CplexLp() {}
453 453

	
454
  CplexLp* CplexLp::_newSolver() const { return new CplexLp; }
455
  CplexLp* CplexLp::_cloneSolver() const {return new CplexLp(*this); }
454
  CplexLp* CplexLp::newSolver() const { return new CplexLp; }
455
  CplexLp* CplexLp::cloneSolver() const {return new CplexLp(*this); }
456 456

	
457 457
  const char* CplexLp::_solverName() const { return "CplexLp"; }
458 458

	
... ...
@@ -823,8 +823,8 @@
823 823

	
824 824
  CplexMip::~CplexMip() {}
825 825

	
826
  CplexMip* CplexMip::_newSolver() const { return new CplexMip; }
827
  CplexMip* CplexMip::_cloneSolver() const {return new CplexMip(*this); }
826
  CplexMip* CplexMip::newSolver() const { return new CplexMip; }
827
  CplexMip* CplexMip::cloneSolver() const {return new CplexMip(*this); }
828 828

	
829 829
  const char* CplexMip::_solverName() const { return "CplexMip"; }
830 830

	
Ignore white space 6 line context
... ...
@@ -160,7 +160,7 @@
160 160
  ///
161 161
  /// This class implements an interface for the CPLEX LP solver.
162 162
  ///\ingroup lp_group
163
  class CplexLp : public CplexBase, public LpSolver {
163
  class CplexLp : public LpSolver, public CplexBase {
164 164
  public:
165 165
    /// \e
166 166
    CplexLp();
... ...
@@ -171,6 +171,11 @@
171 171
    /// \e
172 172
    virtual ~CplexLp();
173 173

	
174
    /// \e
175
    virtual CplexLp* cloneSolver() const;
176
    /// \e
177
    virtual CplexLp* newSolver() const;
178

	
174 179
  private:
175 180

	
176 181
    // these values cannot retrieved element by element
... ...
@@ -186,9 +191,6 @@
186 191

	
187 192
  protected:
188 193

	
189
    virtual CplexLp* _cloneSolver() const;
190
    virtual CplexLp* _newSolver() const;
191

	
192 194
    virtual const char* _solverName() const;
193 195

	
194 196
    virtual SolveExitStatus _solve();
... ...
@@ -222,7 +224,7 @@
222 224
  ///
223 225
  /// This class implements an interface for the CPLEX MIP solver.
224 226
  ///\ingroup lp_group
225
  class CplexMip : public CplexBase, public MipSolver {
227
  class CplexMip : public MipSolver, public CplexBase {
226 228
  public:
227 229
    /// \e
228 230
    CplexMip();
Ignore white space 6 line context
... ...
@@ -534,8 +534,8 @@
534 534
    messageLevel(MESSAGE_NO_OUTPUT);
535 535
  }
536 536

	
537
  GlpkLp* GlpkLp::_newSolver() const { return new GlpkLp; }
538
  GlpkLp* GlpkLp::_cloneSolver() const { return new GlpkLp(*this); }
537
  GlpkLp* GlpkLp::newSolver() const { return new GlpkLp; }
538
  GlpkLp* GlpkLp::cloneSolver() const { return new GlpkLp(*this); }
539 539

	
540 540
  const char* GlpkLp::_solverName() const { return "GlpkLp"; }
541 541

	
... ...
@@ -940,8 +940,8 @@
940 940
    return glp_mip_obj_val(lp);
941 941
  }
942 942

	
943
  GlpkMip* GlpkMip::_newSolver() const { return new GlpkMip; }
944
  GlpkMip* GlpkMip::_cloneSolver() const {return new GlpkMip(*this); }
943
  GlpkMip* GlpkMip::newSolver() const { return new GlpkMip; }
944
  GlpkMip* GlpkMip::cloneSolver() const {return new GlpkMip(*this); }
945 945

	
946 946
  const char* GlpkMip::_solverName() const { return "GlpkMip"; }
947 947

	
Ignore white space 6 line context
... ...
@@ -119,7 +119,7 @@
119 119
  ///
120 120
  /// This class implements an interface for the GLPK LP solver.
121 121
  ///\ingroup lp_group
122
  class GlpkLp : public GlpkBase, public LpSolver {
122
  class GlpkLp : public LpSolver, public GlpkBase {
123 123
  public:
124 124

	
125 125
    ///\e
... ...
@@ -127,6 +127,11 @@
127 127
    ///\e
128 128
    GlpkLp(const GlpkLp&);
129 129

	
130
    ///\e
131
    virtual GlpkLp* cloneSolver() const;
132
    ///\e
133
    virtual GlpkLp* newSolver() const;
134

	
130 135
  private:
131 136

	
132 137
    mutable std::vector<double> _primal_ray;
... ...
@@ -136,9 +141,6 @@
136 141

	
137 142
  protected:
138 143

	
139
    virtual GlpkLp* _cloneSolver() const;
140
    virtual GlpkLp* _newSolver() const;
141

	
142 144
    virtual const char* _solverName() const;
143 145

	
144 146
    virtual SolveExitStatus _solve();
... ...
@@ -203,7 +205,7 @@
203 205
  ///
204 206
  /// This class implements an interface for the GLPK MIP solver.
205 207
  ///\ingroup lp_group
206
  class GlpkMip : public GlpkBase, public MipSolver {
208
  class GlpkMip : public MipSolver, public GlpkBase {
207 209
  public:
208 210

	
209 211
    ///\e
... ...
@@ -211,11 +213,11 @@
211 213
    ///\e
212 214
    GlpkMip(const GlpkMip&);
213 215

	
216
    virtual GlpkMip* cloneSolver() const;
217
    virtual GlpkMip* newSolver() const;
218

	
214 219
  protected:
215 220

	
216
    virtual GlpkMip* _cloneSolver() const;
217
    virtual GlpkMip* _newSolver() const;
218

	
219 221
    virtual const char* _solverName() const;
220 222

	
221 223
    virtual ColTypes _getColType(int col) const;
Ignore white space 6 line context
... ...
@@ -918,8 +918,6 @@
918 918
  protected:
919 919

	
920 920
    //Abstract virtual functions
921
    virtual LpBase* _newSolver() const = 0;
922
    virtual LpBase* _cloneSolver() const = 0;
923 921

	
924 922
    virtual int _addColId(int col) { return cols.addIndex(col); }
925 923
    virtual int _addRowId(int row) { return rows.addIndex(row); }
... ...
@@ -987,11 +985,6 @@
987 985
    /// Virtual destructor
988 986
    virtual ~LpBase() {}
989 987

	
990
    ///Creates a new LP problem
991
    LpBase* newSolver() {return _newSolver();}
992
    ///Makes a copy of the LP problem
993
    LpBase* cloneSolver() {return _cloneSolver();}
994

	
995 988
    ///Gives back the name of the solver.
996 989
    const char* solverName() const {return _solverName();}
997 990

	
... ...
@@ -1821,6 +1814,11 @@
1821 1814

	
1822 1815
  public:
1823 1816

	
1817
    ///Allocate a new LP problem instance
1818
    virtual LpSolver* newSolver() const = 0;
1819
    ///Make a copy of the LP problem
1820
    virtual LpSolver* cloneSolver() const = 0;
1821

	
1824 1822
    ///\name Solve the LP
1825 1823

	
1826 1824
    ///@{
... ...
@@ -1935,13 +1933,8 @@
1935 1933
    Value primal() const { return _getPrimalValue()+obj_const_comp;}
1936 1934
    ///@}
1937 1935

	
1938
    LpSolver* newSolver() {return _newSolver();}
1939
    LpSolver* cloneSolver() {return _cloneSolver();}
1940

	
1941 1936
  protected:
1942 1937

	
1943
    virtual LpSolver* _newSolver() const = 0;
1944
    virtual LpSolver* _cloneSolver() const = 0;
1945 1938
  };
1946 1939

	
1947 1940

	
... ...
@@ -1975,6 +1968,11 @@
1975 1968
      UNBOUNDED = 4
1976 1969
    };
1977 1970

	
1971
    ///Allocate a new MIP problem instance
1972
    virtual MipSolver* newSolver() const = 0;
1973
    ///Make a copy of the MIP problem
1974
    virtual MipSolver* cloneSolver() const = 0;
1975

	
1978 1976
    ///\name Solve the MIP
1979 1977

	
1980 1978
    ///@{
... ...
@@ -2062,15 +2060,6 @@
2062 2060
    virtual Value _getSol(int i) const = 0;
2063 2061
    virtual Value _getSolValue() const = 0;
2064 2062

	
2065
  public:
2066

	
2067
    MipSolver* newSolver() {return _newSolver();}
2068
    MipSolver* cloneSolver() {return _cloneSolver();}
2069

	
2070
  protected:
2071

	
2072
    virtual MipSolver* _newSolver() const = 0;
2073
    virtual MipSolver* _cloneSolver() const = 0;
2074 2063
  };
2075 2064

	
2076 2065

	
Ignore white space 6 line context
... ...
@@ -105,10 +105,10 @@
105 105
  LpSkeleton::VarStatus LpSkeleton::_getRowStatus(int) const
106 106
  { return BASIC; }
107 107

	
108
  LpSkeleton* LpSkeleton::_newSolver() const
108
  LpSkeleton* LpSkeleton::newSolver() const
109 109
  { return static_cast<LpSkeleton*>(0); }
110 110

	
111
  LpSkeleton* LpSkeleton::_cloneSolver() const
111
  LpSkeleton* LpSkeleton::cloneSolver() const
112 112
  { return static_cast<LpSkeleton*>(0); }
113 113

	
114 114
  const char* LpSkeleton::_solverName() const { return "LpSkeleton"; }
... ...
@@ -122,10 +122,10 @@
122 122
  MipSkeleton::ProblemType MipSkeleton::_getType() const
123 123
  { return UNDEFINED; }
124 124

	
125
  MipSkeleton* MipSkeleton::_newSolver() const
125
  MipSkeleton* MipSkeleton::newSolver() const
126 126
  { return static_cast<MipSkeleton*>(0); }
127 127

	
128
  MipSkeleton* MipSkeleton::_cloneSolver() const
128
  MipSkeleton* MipSkeleton::cloneSolver() const
129 129
  { return static_cast<MipSkeleton*>(0); }
130 130

	
131 131
  const char* MipSkeleton::_solverName() const { return "MipSkeleton"; }
Ignore white space 6 line context
... ...
@@ -22,10 +22,16 @@
22 22
#include <lemon/lp_base.h>
23 23

	
24 24
///\file
25
///\brief A skeleton file to implement LP solver interfaces
25
///\brief Skeleton file to implement LP/MIP solver interfaces
26
///  
27
///The classes in this file do nothing, but they can serve as skeletons when
28
///implementing an interface to new solvers.
26 29
namespace lemon {
27 30

	
28
  ///A skeleton class to implement LP solver interfaces
31
  ///A skeleton class to implement LP/MIP solver base interface
32
  
33
  ///This class does nothing, but it can serve as a skeleton when
34
  ///implementing an interface to new solvers.
29 35
  class SkeletonSolverBase : public virtual LpBase {
30 36
    int col_num,row_num;
31 37

	
... ...
@@ -136,14 +142,20 @@
136 142

	
137 143
  };
138 144

	
139
  /// \brief Interface for a skeleton LP solver
145
  /// \brief Skeleton class for an LP solver interface
140 146
  ///
141
  /// This class implements an interface for a skeleton LP solver.
147
  ///This class does nothing, but it can serve as a skeleton when
148
  ///implementing an interface to new solvers.
149

	
142 150
  ///\ingroup lp_group
143
  class LpSkeleton : public SkeletonSolverBase, public LpSolver {
151
  class LpSkeleton : public LpSolver, public SkeletonSolverBase {
144 152
  public:
145
    LpSkeleton() : SkeletonSolverBase(), LpSolver() {}
146

	
153
    ///\e
154
    LpSkeleton() : LpSolver(), SkeletonSolverBase() {}
155
    ///\e
156
    virtual LpSkeleton* newSolver() const;
157
    ///\e
158
    virtual LpSkeleton* cloneSolver() const;
147 159
  protected:
148 160

	
149 161
    ///\e
... ...
@@ -173,21 +185,23 @@
173 185
    virtual VarStatus _getRowStatus(int i) const;
174 186

	
175 187
    ///\e
176
    virtual LpSkeleton* _newSolver() const;
177
    ///\e
178
    virtual LpSkeleton* _cloneSolver() const;
179
    ///\e
180 188
    virtual const char* _solverName() const;
181 189

	
182 190
  };
183 191

	
184
  /// \brief Interface for a skeleton MIP solver
192
  /// \brief Skeleton class for a MIP solver interface
185 193
  ///
186
  /// This class implements an interface for a skeleton MIP solver.
194
  ///This class does nothing, but it can serve as a skeleton when
195
  ///implementing an interface to new solvers.
187 196
  ///\ingroup lp_group
188
  class MipSkeleton : public SkeletonSolverBase, public MipSolver {
197
  class MipSkeleton : public MipSolver, public SkeletonSolverBase {
189 198
  public:
190
    MipSkeleton() : SkeletonSolverBase(), MipSolver() {}
199
    ///\e
200
    MipSkeleton() : MipSolver(), SkeletonSolverBase() {}
201
    ///\e
202
    virtual MipSkeleton* newSolver() const;
203
    ///\e
204
    virtual MipSkeleton* cloneSolver() const;
191 205

	
192 206
  protected:
193 207
    ///\e
... ...
@@ -215,13 +229,7 @@
215 229
    virtual ProblemType _getType() const;
216 230

	
217 231
    ///\e
218
    virtual MipSkeleton* _newSolver() const;
219

	
220
    ///\e
221
    virtual MipSkeleton* _cloneSolver() const;
222
    ///\e
223 232
    virtual const char* _solverName() const;
224

	
225 233
  };
226 234

	
227 235
} //namespace lemon
Ignore white space 6 line context
... ...
@@ -54,12 +54,12 @@
54 54
    _dual_values.clear();
55 55
  }
56 56

	
57
  SoplexLp* SoplexLp::_newSolver() const {
57
  SoplexLp* SoplexLp::newSolver() const {
58 58
    SoplexLp* newlp = new SoplexLp();
59 59
    return newlp;
60 60
  }
61 61

	
62
  SoplexLp* SoplexLp::_cloneSolver() const {
62
  SoplexLp* SoplexLp::cloneSolver() const {
63 63
    SoplexLp* newlp = new SoplexLp(*this);
64 64
    return newlp;
65 65
  }
Ignore white space 6 line context
... ...
@@ -73,12 +73,13 @@
73 73
    SoplexLp(const SoplexLp&);
74 74
    /// \e
75 75
    ~SoplexLp();
76
    /// \e
77
    virtual SoplexLp* newSolver() const;
78
    /// \e
79
    virtual SoplexLp* cloneSolver() const;
76 80

	
77 81
  protected:
78 82

	
79
    virtual SoplexLp* _newSolver() const;
80
    virtual SoplexLp* _cloneSolver() const;
81

	
82 83
    virtual const char* _solverName() const;
83 84

	
84 85
    virtual int _addCol();
Ignore white space 6 line context
... ...
@@ -197,6 +197,11 @@
197 197
    buf << "Coeff. of p2 should be 0";
198 198
    check(const_cast<const LpSolver::Expr&>(e)[p2]==0, buf.str());
199 199

	
200
    //Test for clone/new
201
    LP* lpnew = lp.newSolver();
202
    LP* lpclone = lp.cloneSolver();
203
    delete lpnew;
204
    delete lpclone;
200 205

	
201 206
  }
202 207

	
... ...
@@ -247,7 +252,8 @@
247 252

	
248 253
  if (stat ==  LpSolver::OPTIMAL) {
249 254
    std::ostringstream sbuf;
250
    sbuf << "Wrong optimal value: the right optimum is " << exp_opt;
255
    sbuf << "Wrong optimal value (" << lp.primal() <<") with "
256
         << lp.solverName() <<"\n     the right optimum is " << exp_opt;
251 257
    check(std::abs(lp.primal()-exp_opt) < 1e-3, sbuf.str());
252 258
  }
253 259
}
... ...
@@ -355,6 +361,19 @@
355 361

	
356 362
}
357 363

	
364
template<class LP>
365
void cloneTest()
366
{
367
  //Test for clone/new
368
  
369
  LP* lp = new LP();
370
  LP* lpnew = lp->newSolver();
371
  LP* lpclone = lp->cloneSolver();
372
  delete lp;
373
  delete lpnew;
374
  delete lpclone;
375
}
376

	
358 377
int main()
359 378
{
360 379
  LpSkeleton lp_skel;
... ...
@@ -365,6 +384,7 @@
365 384
    GlpkLp lp_glpk1,lp_glpk2;
366 385
    lpTest(lp_glpk1);
367 386
    aTest(lp_glpk2);
387
    cloneTest<GlpkLp>();
368 388
  }
369 389
#endif
370 390

	
... ...
@@ -381,6 +401,7 @@
381 401
    std::cerr << "Cplex license check failed, lp check skipped" << std::endl;
382 402
#endif
383 403
  }
404
    cloneTest<CplexLp>();
384 405
#endif
385 406

	
386 407
#ifdef HAVE_SOPLEX
... ...
@@ -388,6 +409,7 @@
388 409
    SoplexLp lp_soplex1,lp_soplex2;
389 410
    lpTest(lp_soplex1);
390 411
    aTest(lp_soplex2);
412
    cloneTest<SoplexLp>();
391 413
  }
392 414
#endif
393 415

	
... ...
@@ -396,6 +418,7 @@
396 418
    ClpLp lp_clp1,lp_clp2;
397 419
    lpTest(lp_clp1);
398 420
    aTest(lp_clp2);
421
    cloneTest<ClpLp>();
399 422
  }
400 423
#endif
401 424

	
Ignore white space 6 line context
... ...
@@ -106,6 +106,17 @@
106 106

	
107 107
}
108 108

	
109
template<class MIP>
110
void cloneTest()
111
{
112
  
113
  MIP* mip = new MIP();
114
  MIP* mipnew = mip->newSolver();
115
  MIP* mipclone = mip->cloneSolver();
116
  delete mip;
117
  delete mipnew;
118
  delete mipclone;
119
}
109 120

	
110 121
int main()
111 122
{
... ...
@@ -114,6 +125,7 @@
114 125
  {
115 126
    GlpkMip mip1;
116 127
    aTest(mip1);
128
    cloneTest<GlpkMip>();
117 129
  }
118 130
#endif
119 131

	
... ...
@@ -129,6 +141,7 @@
129 141
    std::cerr << "Cplex license check failed, lp check skipped" << std::endl;
130 142
#endif
131 143
  }
144
  cloneTest<CplexMip>();
132 145
#endif
133 146

	
134 147
  return 0;
0 comments (0 inline)