Opened 18 years ago
Closed 17 years ago
#44 closed task (fixed)
Port the LP interface
| Reported by: | Alpar Juttner | Owned by: | Balazs Dezso |
|---|---|---|---|
| Priority: | critical | Milestone: | LEMON 1.1 release |
| Component: | core | Version: | |
| Keywords: | Cc: | ||
| Revision id: |
Description (last modified by )
The following files are affected:
- lemon/lp_base.h
- lemon/lp_base.cc
- lemon/lp.h
- lemon/lp_skeleton.h
- lemon/lp_skeleton.cc
- lemon/bits/lp_id.h
- lemon/lp_utils.cc
- lemon/lp_utils.h
- lemon/lp_glpk.h
- lemon/mip_glpk.h
- lemon/lp_glpk.cc
- lemon/mip_glpk.cc
- lemon/lp_cplex.h
- lemon/mip_cplex.h
- lemon/lp_cplex.cc
- lemon/mip_cplex.cc
- lemon/lp_soplex.h
- lemon/lp_soplex.cc
- test/lp_test.cc
- test/mip_test.cc
- m4/lx_check_soplex.m4 (already ported)
- m4/lx_check_cplex.m4 (already ported)
- m4/lx_check_glpk.m4 (already ported)
- demo/lp_maxflow_demo.cc
- demo/lp_demo.cc
We should also consider restructuring these files.
Attachments (8)
Change History (38)
comment:1 Changed 18 years ago by
| Description: | modified (diff) |
|---|
comment:2 Changed 18 years ago by
| Description: | modified (diff) |
|---|
comment:3 Changed 18 years ago by
| Milestone: | LEMON 1.0 release → Post 1.0 |
|---|
comment:4 Changed 18 years ago by
comment:5 Changed 18 years ago by
| Owner: | changed from Alpar Juttner to Balazs Dezso |
|---|
comment:6 Changed 17 years ago by
| Priority: | major → critical |
|---|
comment:7 follow-ups: 8 9 Changed 17 years ago by
The patch [aa6dff56b2e1] contains a working version of LP port, however it is heavily under development. Unfortunately, I forgot to create the basic port revision, but I will do it with some reverse engineering.
Currently a lot of things changed:
- The class structure
- The ID handling
- The expressions
- The basic interface
- Some result retrieving functions
- Some setting functions
- Cplex env handling
- etc....
So please comment the current changes, and advice what could be made better way?
I have also some troubles, where I cannot decide.
- An LP problem can be categorized into classes, and similarly the primal problem and the dual problem have a type. In addition, the current solution status also can be described. What is the best interface to get type and/or status?
- How to handle such situations, where the solver does not provide the whole information need by the interface? For example the rays cannot be computed with every solver, assertion, exception should be used? In this case, the ray can be computed with a new optimization problem.
- With which versions of solvers have to be compatible, for example older cplex, and glpk versions?
- The documentation should be also improved.
comment:8 follow-up: 10 Changed 17 years ago by
Replying to deba:
The patch [aa6dff56b2e1] contains a working version of LP port,
For me it does not compile:
g++ -DHAVE_CONFIG_H -I. -I. -g -O2 -Wall -W -Wall -W -Wunused -Wformat=2 -Wctor-dtor-privacy -Wnon-virtual-dtor -Wno-char-subscripts -Wwrite-strings -Wno-char-subscripts -Wreturn-type -Wcast-qual -Wcast-align -Wsign-promo -Woverloaded-virtual -Woverloaded-virtual -ansi -fno-strict-aliasing -Wold-style-cast -Wno-unknown-pragmas -MT lemon/lemon_libemon_la-lp_glpk.lo -MD -MP -MF lemon/.deps/lemon_libemon_la-lp_glpk.Tpo -c lemon/lp_glpk.cc -o lemon/lemon_libemon_la-lp_glpk.o lemon/lp_glpk.cc: In copy constructor ‘lemon::GlpkSolverBase::GlpkSolverBase(const lemon::GlpkSolverBase&)’: lemon/lp_glpk.cc:38: error: ‘glp_copy_prob’ was not declared in this scope lemon/lp_glpk.cc: In member function ‘virtual double lemon::LpGlpk::_getPrimalRay(int) const’: lemon/lp_glpk.cc:655: error: ‘glp_get_unbnd_ray’ was not declared in this scope lemon/lp_glpk.cc: In member function ‘virtual double lemon::LpGlpk::_getDualRay(int) const’: lemon/lp_glpk.cc:706: error: ‘glp_get_unbnd_ray’ was not declared in this scope make: *** [lemon/lemon_libemon_la-lp_glpk.lo] Error 1 make: *** Waiting for unfinished jobs....
comment:9 follow-up: 12 Changed 17 years ago by
Replying to deba:
The patch [aa6dff56b2e1] contains a working version of LP port, however it is heavily under development.
Here is some naive observations:
- I find the name of
SolverBasetoo general. What about calling itLpBaseorLpSolverBaseinstead? - I miss a solve() method (or something similar) from the class
SolverBase. Is that intentional - I can't find an interface for querying the solution neither in
SolverBasenor in e.g.LpGlpk - I find the
MipSolverBaseinterface a bit bloated. Do we really need all the three way for declaring that a variable is integer or not?
comment:10 follow-up: 11 Changed 17 years ago by
Replying to alpar:
Replying to deba:
The patch [aa6dff56b2e1] contains a working version of LP port,
For me it does not compile:
g++ -DHAVE_CONFIG_H -I. -I. -g -O2 -Wall -W -Wall -W -Wunused -Wformat=2 -Wctor-dtor-privacy -Wnon-virtual-dtor -Wno-char-subscripts -Wwrite-strings -Wno-char-subscripts -Wreturn-type -Wcast-qual -Wcast-align -Wsign-promo -Woverloaded-virtual -Woverloaded-virtual -ansi -fno-strict-aliasing -Wold-style-cast -Wno-unknown-pragmas -MT lemon/lemon_libemon_la-lp_glpk.lo -MD -MP -MF lemon/.deps/lemon_libemon_la-lp_glpk.Tpo -c lemon/lp_glpk.cc -o lemon/lemon_libemon_la-lp_glpk.o lemon/lp_glpk.cc: In copy constructor ‘lemon::GlpkSolverBase::GlpkSolverBase(const lemon::GlpkSolverBase&)’: lemon/lp_glpk.cc:38: error: ‘glp_copy_prob’ was not declared in this scope lemon/lp_glpk.cc: In member function ‘virtual double lemon::LpGlpk::_getPrimalRay(int) const’: lemon/lp_glpk.cc:655: error: ‘glp_get_unbnd_ray’ was not declared in this scope lemon/lp_glpk.cc: In member function ‘virtual double lemon::LpGlpk::_getDualRay(int) const’: lemon/lp_glpk.cc:706: error: ‘glp_get_unbnd_ray’ was not declared in this scope make: *** [lemon/lemon_libemon_la-lp_glpk.lo] Error 1 make: *** Waiting for unfinished jobs....
These functions are quite new in glpk, it comes from 4.33 version.
comment:11 Changed 17 years ago by
Replying to deba:
These functions are quite new in glpk, it comes from 4.33 version.
The glpk version should be checked by the configure script.
Changed 17 years ago by
| Attachment: | lp_inheritance.png added |
|---|
comment:12 follow-up: 13 Changed 17 years ago by
Replying to alpar:
- I find the name of
SolverBasetoo general. What about calling itLpBaseorLpSolverBaseinstead?- I miss a solve() method (or something similar) from the class
SolverBase. Is that intentional- I can't find an interface for querying the solution neither in
SolverBasenor in e.g.LpGlpk
The lp_inheritance.png shows the class design of the current implementation (the names are slightly differ). The SolverBase? contain the common part of Mip and Lp interface, while separate classes contain the specialized parts. If you would like to use a general lp solver in an algorithm, currently the LpBase?(LpSolverBase?) reference should be passed as parameter, similarly MipBase?(MipSolverBase?) instead of SolverBase?. The advantage of this solution is that the Mip solver does not contain Lp related functions (primal-dual solution, basis access, etc.). We have one more choice, the SolverBase? also could contain some solver and solution retrieving function(basically one solve() function and getting the column results and objective value result), however I'm not sure that it is a good decision. What is your opinion?
- I find the
MipSolverBaseinterface a bit bloated. Do we really need all the three way for declaring that a variable is integer or not?
Ok, I think we can hold just the colType() functions.
Changed 17 years ago by
| Attachment: | lp-classes.png added |
|---|
comment:13 follow-up: 14 Changed 17 years ago by
Replying to deba:
The lp_inheritance.png shows the class design of the current implementation (the names are slightly differ). The SolverBase? contain the common part of Mip and Lp interface, while separate classes contain the specialized parts. If you would like to use a general lp solver in an algorithm, currently the LpBase?(LpSolverBase?)
I'm confused now. There is neither LpBase nor LpSolverBase in the port you sent ([aa6dff56b2e1]), see lp-classes.png showing the generated class inheritance diagram.
Anyhow, then name of SolverBase is just too general. There are so many other "solvers" beyond LP/MIP, which need completely different interfaces.
comment:14 follow-up: 15 Changed 17 years ago by
Replying to alpar:
I'm confused now. There is neither
LpBasenorLpSolverBasein the port you sent ([aa6dff56b2e1]), see lp-classes.png showing the generated class inheritance diagram.
Balazs wrote wrong (but similar) class names on the image. He used the names LpBase, MipBase, GlpkBase instead of LpSolverBase, MipSolverBase and GlpkSolverBase, respectively, and used GlpkLp, GlpkMip instead of LpGlpk and MipGlpk respectively.
I copied the following lines from his changeset:
class LpSolverBase : virtual public SolverBaseclass MipSolverBase : virtual public SolverBaseclass GlpkSolverBase : virtual public SolverBaseclass LpGlpk : public GlpkSolverBase, public LpSolverBaseclass MipGlpk : public GlpkSolverBase, public MipSolverBase
It is the same as your inheritance diagram with the exception that LpSolverBase class is somehow missing from the diagram. (The relation noted in the first line of the above list is missing from the diagram, but it can be found at line 1568 in lp_base.h in [aa6dff56b2e1]).
comment:15 follow-up: 17 Changed 17 years ago by
Replying to kpeter:
Replying to alpar:
I'm confused now. There is neither
LpBasenorLpSolverBasein the port you sent ([aa6dff56b2e1]), see lp-classes.png showing the generated class inheritance diagram.Balazs wrote wrong (but similar) class names on the image. He used the names
LpBase,MipBase,GlpkBaseinstead ofLpSolverBase,MipSolverBaseandGlpkSolverBase, respectively, and usedGlpkLp,GlpkMipinstead ofLpGlpkandMipGlpkrespectively.I copied the following lines from his changeset:
class LpSolverBase : virtual public SolverBaseclass MipSolverBase : virtual public SolverBaseclass GlpkSolverBase : virtual public SolverBaseclass LpGlpk : public GlpkSolverBase, public LpSolverBaseclass MipGlpk : public GlpkSolverBase, public MipSolverBaseIt is the same as your inheritance diagram with the exception that
LpSolverBaseclass is somehow missing from the diagram.
I typically read only the documentation for the very first review, and I would like to keep this habit. So, if the doxygen tell me that LpSolverBase is not there, then I consider it to be missing from the commits.
The same applies to the missing part of the interface (the solve() method (or something similar) from the class SolverBase and the interface for querying the solution either in SolverBase or in e.g. LpGlpk)
comment:16 Changed 17 years ago by
| Status: | new → assigned |
|---|
comment:17 follow-up: 18 Changed 17 years ago by
Balazs, could you fix the doc so that all relevant classes and member functions will be visible in the doc?
comment:18 follow-up: 19 Changed 17 years ago by
Replying to alpar:
Balazs, could you fix the doc so that all relevant classes and member functions will be visible in the doc?
I made it in the lp.bundle. The bundle contains also the basic port of the lp related stuffs. I also renamed some classes. I hope, the basic structure and the naming convention of the solvers are acceptable, and just the documentation and some details should be polished yet.
comment:19 follow-up: 20 Changed 17 years ago by
Replying to deba:
I made it in the lp.bundle. The bundle contains also the basic port of the lp related stuffs. I also renamed some classes. I hope, the basic structure and the naming convention of the solvers are acceptable, and just the documentation and some details should be polished yet.
Two short comments:
- I still dislike to the name
SolverBase, as it is too general. There are much more "solvers" than the LP/MIP related ones. - Now operator*() is used to obtain the constant component of an
Expr. I don't like it either. Instead, I would use (the binary version) operator*(Expr, Expr) for computing the dot product of two expressions. For example, in this way you could substitute a solution into a constraint. Syntactically, this would not conflict the current usage of operator*, but I find it confusing. If you don't, then we can keep it.
comment:20 follow-up: 22 Changed 17 years ago by
Replying to alpar:
Two short comments:
- I still dislike to the name
SolverBase, as it is too general. There are much more "solvers" than the LP/MIP related ones.
I agree. A more specific name would be better. What about LinearSolverBase or LpMipSolverBase or LpMipBase?
- Now operator*() is used to obtain the constant component of an
Expr. I don't like it either.
It is strange for me, too.
Another suggestion (according to our email discussion): in SolverBase::Expr using ColIt and ConstColIt would be better than MapIt and ConstMapIt. Similarly DualExpr::(Const)MapIt --> DualExpr::(Const)RowIt.
comment:21 Changed 17 years ago by
Btw. we should collect the all the renamings related to the LP tools in order to extend the migration guide and script.
comment:22 follow-up: 23 Changed 17 years ago by
Replying to kpeter:
Replying to alpar:
Two short comments:
- I still dislike to the name
SolverBase, as it is too general. There are much more "solvers" than the LP/MIP related ones.I agree. A more specific name would be better. What about
LinearSolverBaseorLpMipSolverBaseorLpMipBase?
I suggest the following renaming: SolverBase? -> LpBase?, LpBase? -> LpSolver?, MipBase? -> MipSolver?. What is your opinion? I like only the LinearSolverBase? from the suggested names, but maybe the newly proposed names are better.
- Now operator*() is used to obtain the constant component of an
Expr. I don't like it either.It is strange for me, too.
I had the idea, that the expressions are similar to the arrays. For the arrays, we can get the 0th item with operator*(), which could be the constant component of the expression. Maybe it was a bad idea.
Another suggestion (according to our email discussion): in
SolverBase::ExprusingColItandConstColItwould be better thanMapItandConstMapIt. SimilarlyDualExpr::(Const)MapIt-->DualExpr::(Const)RowIt.
I like rather the CoeffIt? and ConstCoeffIt?.
Other question, the SolverBase? don't contain solve() and problem retrieving functions, don't we need it?
comment:23 follow-up: 24 Changed 17 years ago by
Replying to deba:
I suggest the following renaming: SolverBase? -> LpBase?, LpBase? -> LpSolver?, MipBase? -> MipSolver?. What is your opinion? I like only the LinearSolverBase? from the suggested names, but maybe the newly proposed names are better.
And what about the "default LP" typedef? How would you call it?
- Now operator*() is used to obtain the constant component of an
Expr. I don't like it either.It is strange for me, too.
I had the idea, that the expressions are similar to the arrays. For the arrays, we can get the 0th item with operator*(), which could be the constant component of the expression. Maybe it was a bad idea.
Not necessarily. My concern was that it may conflict (semantically) with the other (future) meaning of operator*(). What do you think of it?
On the other hand, we can also use operator() for the dot product, (i.e. is c and x are expressions, then c(x) (and x(c) would mean the dot product of them).
Other question, the SolverBase? don't contain solve() and problem retrieving functions, don't we need it?
solve() should return something indicating the type of the obtained solution. Can it be of the same type for LP and MIP?
comment:24 Changed 17 years ago by
Replying to alpar:
Replying to deba:
I suggest the following renaming: SolverBase? -> LpBase?, LpBase? -> LpSolver?, MipBase? -> MipSolver?. What is your opinion? I like only the LinearSolverBase? from the suggested names, but maybe the newly proposed names are better.
And what about the "default LP" typedef? How would you call it?
It could remain Lp and Mip, as they are in the SVN releases.
- Now operator*() is used to obtain the constant component of an
Expr. I don't like it either.It is strange for me, too.
I had the idea, that the expressions are similar to the arrays. For the arrays, we can get the 0th item with operator*(), which could be the constant component of the expression. Maybe it was a bad idea.
Not necessarily. My concern was that it may conflict (semantically) with the other (future) meaning of operator*(). What do you think of it?
On the other hand, we can also use operator() for the dot product, (i.e. is
candxare expressions, thenc(x)(andx(c)would mean the dot product of them).Other question, the SolverBase? don't contain solve() and problem retrieving functions, don't we need it?
solve()should return something indicating the type of the obtained solution. Can it be of the same type for LP and MIP?
The solve() functions return now SolveExitStatus?, which gives back whether the solving were successful, or not. It can be common for both solver type. In addtion, the sol() and the solValue() functions can be synonyms for primal() and primalValue() in the LP side.
comment:25 Changed 17 years ago by
I have uploaded a new patch [9347462c3106]. It contains renamings, improvements and bug fixes.
comment:26 follow-up: 27 Changed 17 years ago by
I have uploaded the patch [473d56c5aec8], which contains lot of documentation improvements, and a minor bug fix, and some interface change (see commit log).
comment:27 follow-ups: 28 29 Changed 17 years ago by
Replying to deba:
I have uploaded the patch [473d56c5aec8], which contains lot of documentation improvements, and a minor bug fix, and some interface change (see commit log).
The patches do not compile as lemon/bits/solver_bits.h seems to be missing.
comment:28 Changed 17 years ago by
Replying to alpar:
The patches do not compile as
lemon/bits/solver_bits.hseems to be missing.
Could we fix it? It would be important to push these changesets to the main branch as soon as it possible.
Changed 17 years ago by
| Attachment: | lp-3aca3bcdf9e1.patch added |
|---|
comment:29 Changed 17 years ago by
Replying to alpar:
The patches do not compile as
lemon/bits/solver_bits.hseems to be missing.
[3aca3bcdf9e1] adds the missing file, so the patches can be compiled.
comment:30 Changed 17 years ago by
| Resolution: | → fixed |
|---|---|
| Status: | assigned → closed |
The port and the reworked version went to the main, reorganized to [7afc121e0689] and [ed54c0d13df0]. In addition [76ec7bd57026] bypasses warnings with emitted by gcc 4.3.
Finally, [08d495d48089] renames the header files by removing the lp_ prefixes and [9b082b3fb33f] changes Lp*/Mip* to *Lp/*Mip.
I guess I can close the ticket.


The LP and MIP structure should be organized different way:
The new structure would provide more flexible and cleaner structure: