[Coin-discuss] Osi redesign

Laszlo Ladanyi ladanyi at us.ibm.com
Mon Nov 12 18:10:46 EST 2001


Hi all,

First of all, I'd like to thank everyone who showed up at the Open Source
track at the INFORMS meeting. I think it was successful.

Second, I'll try now to recapture what we were discussing after the workshop.
We were trying to decide how Osi could be redesigned to allow for a much wider
variety of solvers (the current solver interface is really targeted to LP
solvers). So, here is what I remember:

The whole class structure should be very hierarchical with the constraint
types and objective types on the bottom:
OsiLinearConstraint, OsiLinearObjective, OsiQuadraticObjective, etc.
These classes define the constraint structure and the objective structure and
define how to modify them.

>From these one can piece together other classes:
class OsiLP : public OsiLinearConstraint, public OsiLinearObjective;
class OsiQP : public OsiLinearConstraint, public OsiQuadraticObjective;
These classes contain what can be done with an LP; most likely, it'll be the
solve() method :-).

If there are possibilities for further specialization then further classes are
created:
class OsiLPSimplex : public OsiLP;
class OsiLPBarrier : public OsiLP;
class OsiLPVolume : public OsiLP;

class OsiLPSimplexPrimal : public OsiLPSimplex;
class OsiLPSimplexDual : public OsiLPSimplex;

Along these inheritances each class would declare only those methods that any
object of that type should know. Say, getting a row of the tableau works for
both primal and dual simplex, but getting a primal ray not necessarily. Many
(if not all) of the methods will be pure virtual.

Finally the implementation is done on the top creating nice diamonds in the
inheritance tree:
OsiCplex : public OsiLPSimplexPrimal,
           public OsiLPSimplexDual,
           public OsiLPSimplexBarrier;

The trouble comes when we want to do a solve() method, or getting the solution
or anything that is defined in multiple classes. If several parallel class
defines a solve method how will it be decided which solve is used? There are
three possibilities: 
1) There should not be no name clashes, and call the mthods
   solveSimplexDual(), etc.
2) We don't care about name clashes and if the solve method is invoked it has
   to be specified which one we want. E.g.:
      OsiLP* solver = new OsiCplex;
      /* at this point all we know about 'solver' is that it solves LPs */
      OsiLPBarrier* bsolver = dynamic_cast<OsiLPBarrier*>(solver);
      bsolver->OsiLPBarrier::solve()
      /* no we have selected to solve the LP with barrier */
Obviously 1) and 2) are sort of equivalent.
3) Have a parameter that specifies from which class we want to pick a method
if it is ambiguous. This solution would effectively hide 1) or 2) from the
user. On the other hand this does require some coordination among totally
independent classes (or some serious juggling with typeid information). 

If these problems wouldn't be enough then we also have to consider
integerality, so there will be another pillar on the bottom: OsiInteger, which
contains nothing but integrality info on the data. Then we can have class
OsiMILP : public OsiLP, public OsiInteger;
etc. all rising to the top.

So, I'd like to solicit comments on this (e.g., did I remember correctly :-).
Once we come to a consensus how it should be done, I'll create a development
branch for Osi and would be very happy if someone would voluteer to make the
transition :-). If noone has the time now I'll do it eventually, but I doubt
I'll have time before sometime in December.

Cheers,
--Laci




More information about the Coin-discuss mailing list