<br><font size=2 face="sans-serif">I will put in rhsSide if you can define
it - what do want for ranged rows? &nbsp;</font>
<br>
<br><font size=2 face="sans-serif">Matt - I am sure there is a good reason
for your anti-Osi slant, but I can't see what it is. &nbsp;I can see about
not wanting a solver but it seems odd to duplicate OsiCuts - I can't really
see what you are going to do with cuts other than add them to a solver
and as you say it would just be a copy of the code.</font>
<br>
<br><font size=2 face="sans-serif">I will redo one of my cut generators
to see how it goes.</font>
<br>
<br><font size=2 face="sans-serif">John</font>
<br>
<br>
<br>
<table width=100%>
<tr valign=top>
<td width=40%><font size=1 face="sans-serif"><b>&quot;Matthew Galati&quot;
&lt;Matthew.Galati@sas.com&gt;</b> </font>
<p><font size=1 face="sans-serif">12/15/2006 09:21 AM</font>
<td width=59%>
<table width=100%>
<tr valign=top>
<td>
<div align=right><font size=1 face="sans-serif">To</font></div>
<td><font size=1 face="sans-serif">&lt;fmargot@andrew.cmu.edu&gt;, John
J Forrest/Watson/IBM@IBMUS</font>
<tr valign=top>
<td>
<div align=right><font size=1 face="sans-serif">cc</font></div>
<td><font size=1 face="sans-serif">&quot;cgl&quot; &lt;cgl@list.coin-or.org&gt;</font>
<tr valign=top>
<td>
<div align=right><font size=1 face="sans-serif">Subject</font></div>
<td><font size=1 face="sans-serif">RE: [Cgl] CGL Design - suggested CoinSnapshot</font></table>
<br>
<table>
<tr valign=top>
<td>
<td></table>
<br></table>
<br>
<br>
<br><tt><font size=2>Hi - <br>
<br>
I am fine with whatever you decide.<br>
<br>
&gt; generateCuts(const CoinSnapshot snap, OsiCuts &amp;cuts, const <br>
&gt; CglTreeInfo treeInfo)<br>
<br>
Just a quick note - if you want full independence from Osi, you need to
get rid of the OsiCuts reference in CGL. There really should be a CoinCut,
or more abstractly, a CoinRow. These are very generic objects. Then, for
backwards compatibility, have an Osi method that populates OsiCuts from
CoinCuts.<br>
<br>
If one has to point to Osi headers or link with Osi to build a CGL application,
then we don't yet have independence. <br>
<br>
To be honest, ideally, CGL should be able to be written independent of
CoinUtils too - using all raw data. That would make it most useful and
flexible. Then, provide interface methods from the other libraries. But,
this is probably more work than it is worth.<br>
<br>
Cheers,<br>
Matt<br>
<br>
&quot;CGL - revolt against the shackles of the OSI!&quot;<br>
 <br>
<br>
&gt; -----Original Message-----<br>
&gt; From: cgl-bounces@list.coin-or.org <br>
&gt; [mailto:cgl-bounces@list.coin-or.org] On Behalf Of <br>
&gt; fmargot@andrew.cmu.edu<br>
&gt; Sent: Friday, December 15, 2006 9:04 AM<br>
&gt; To: John J Forrest<br>
&gt; Cc: cgl<br>
&gt; Subject: Re: [Cgl] CGL Design - suggested CoinSnapshot<br>
&gt; <br>
&gt; <br>
&gt; John:<br>
&gt; <br>
&gt; I think that CoinSnapshot is perfect (maybe <br>
&gt; get/setRowRightHandSide() is missing) and if you think that <br>
&gt; its place is in CoinUtils, I have no problem with that.<br>
&gt; <br>
&gt; For ease of use of the generators through CoinSnapshot, it is <br>
&gt; maybe better to require that if the data a generator needs is <br>
&gt; available in CoinSnapshot, then a method<br>
&gt; <br>
&gt; generateCuts(const CoinSnapshot snap, OsiCuts &amp;cuts, const <br>
&gt; CglTreeInfo treeInfo)<br>
&gt; <br>
&gt; returning cuts should be available. If the data the generator <br>
&gt; needs is not in CoinSnapshot, then the method returns with 0 <br>
&gt; cuts and possibly a warning (i.e. no derived class of <br>
&gt; CoinSnapshot for a generator is allowed). <br>
&gt; This would allow to use one CoinSnapshot object to call all <br>
&gt; generators that can be called.<br>
&gt; <br>
&gt; Regarding CglParam, I agree that the instantiation with <br>
&gt; CglParam is a gadget and that including parameters directly <br>
&gt; in the CglCutGenerator class is a possibility (they would <br>
&gt; keep company to Aggressiveness, the only parameter currently <br>
&gt; in CglCutGenerator and ignored by all of them during cut <br>
&gt; generation, I believe). The advantage of having a class for <br>
&gt; the parameters is that it is self documenting. It is easy for <br>
&gt; a user to see what parameters are available. But we could <br>
&gt; obtain more or less the same benefit by requiring that the <br>
&gt; Doxygen documentation of a generator regroups in one <br>
&gt; &quot;Parameters&quot; section all the parameters of the generator
and <br>
&gt; that get/set methods for all parameters are available.<br>
&gt; <br>
&gt; Francois<br>
&gt; <br>
&gt; On Thu, 14 Dec 2006, John J Forrest wrote:<br>
&gt; <br>
&gt; &gt; Francois,<br>
&gt; &gt;<br>
&gt; &gt; I don't like things becoming more complicated than they are already
<br>
&gt; &gt; and I don't think it is going to help 99% of users, so I <br>
&gt; would like to <br>
&gt; &gt; mitigate the damage I think this will cause.<br>
&gt; &gt;<br>
&gt; &gt; 1) I don't think CglParam is really necessary. &nbsp;Different
cut <br>
&gt; &gt; generators would need different values e.g. getMAX_SUPPORT()
so I <br>
&gt; &gt; don't think a user would pass a common CglParam into different
<br>
&gt; &gt; generators. &nbsp;Therefore I think it would be much easier to
<br>
&gt; put common scalars into CglCutGenerator.<br>
&gt; &gt;<br>
&gt; &gt; 2) I don't like CglData being in Cgl. &nbsp;Osi does not know
<br>
&gt; about Cgl and <br>
&gt; &gt; I think it would be useful to have Osi methods to populate this
new <br>
&gt; &gt; data structure.<br>
&gt; &gt;<br>
&gt; &gt; I suggest something in CoinUtils. &nbsp;As a straw man I have
added (and <br>
&gt; &gt; will probably delete in a few days) CoinSnapshot.hpp and <br>
&gt; &gt; CoinSnapshot.cpp to CoinUtils branches/devel for people to <br>
&gt; look at. &nbsp;<br>
&gt; &gt; It has all the same method names as OsiSolverInterface to make
it <br>
&gt; &gt; easier to modify cut generators. &nbsp;It can either own arrays
<br>
&gt; and matrices or just point to them.<br>
&gt; &gt; If a solution along these lines is adopted then it would be <br>
&gt; trivial to <br>
&gt; &gt; put fillSnapshot into OsiSolverInterface to populate <br>
&gt; CoinSnapshot from <br>
&gt; &gt; a solver.<br>
&gt; &gt;<br>
&gt; &gt; John Forrest<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt; fmargot@andrew.cmu.edu<br>
&gt; &gt; 12/14/2006 08:44 AM<br>
&gt; &gt;<br>
&gt; &gt; To<br>
&gt; &gt; John J Forrest/Watson/IBM@IBMUS<br>
&gt; &gt; cc<br>
&gt; &gt; cgl &lt;cgl@list.coin-or.org&gt;<br>
&gt; &gt; Subject<br>
&gt; &gt; Re: [Cgl] CGL Design<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt; John:<br>
&gt; &gt;<br>
&gt; &gt; I agree that the solution of using an OsiCglSolverInterface <br>
&gt; instead of <br>
&gt; &gt; CglData has the big advantage of not requiring modifications
of the <br>
&gt; &gt; cut generators. However, as Lou pointed out, it creates an ugly
Osi <br>
&gt; &gt; class with most of the functionalities of a OsiSolverInterface
<br>
&gt; &gt; disabled and keeps users in the dark about what data each cut
<br>
&gt; &gt; generator needs.<br>
&gt; &gt;<br>
&gt; &gt; The modifications required for using CglData are not that <br>
&gt; difficult or <br>
&gt; &gt; dangerous to implement. This can be done by replacing the existing
<br>
&gt; &gt; method<br>
&gt; &gt;<br>
&gt; &gt; generateCuts(const OsiSolverInterface &amp; si, OsiCuts &amp;
cs, const <br>
&gt; &gt; CglTreeInfo info)<br>
&gt; &gt;<br>
&gt; &gt; by three methods:<br>
&gt; &gt;<br>
&gt; &gt; A) generateCuts(const OsiSolverInterface &amp; si, OsiCuts &amp;
cs, const <br>
&gt; &gt; CglTreeInfo info)<br>
&gt; &gt;<br>
&gt; &gt; B) generateCuts(const CglData data, OsiCuts &amp;cs, const CglTreeInfo
<br>
&gt; &gt; info)<br>
&gt; &gt;<br>
&gt; &gt; C) generateCuts(OsiCuts &amp;cs, const CglTreeInfo info)<br>
&gt; &gt;<br>
&gt; &gt; The first two are just wrappers that call the third one, which
<br>
&gt; &gt; contains the code currently in generateCuts(). The <br>
&gt; modifications to be <br>
&gt; &gt; done is to scan the code for reference to the OsiSolverInterface
si.<br>
&gt; &gt; Each line in C) (or other existing methods) of the form<br>
&gt; &gt;<br>
&gt; &gt; some = si.getSomething();<br>
&gt; &gt;<br>
&gt; &gt; is replaced by<br>
&gt; &gt;<br>
&gt; &gt; some = something;<br>
&gt; &gt;<br>
&gt; &gt; where something is a new member in the generator class and <br>
&gt; putting in <br>
&gt; &gt; method A):<br>
&gt; &gt;<br>
&gt; &gt; something = si.getSomething();<br>
&gt; &gt;<br>
&gt; &gt; and in method B):<br>
&gt; &gt;<br>
&gt; &gt; something = data.getSomething();<br>
&gt; &gt;<br>
&gt; &gt; While mistakes can of course be introduced by doing this, this
does <br>
&gt; &gt; not require a major rewriting of the code. For generators <br>
&gt; that have a <br>
&gt; &gt; const OsiSolverInterface si as parameter (and keep it that <br>
&gt; way), I do <br>
&gt; &gt; not see how serious mistakes can be introduced. For generators
that <br>
&gt; &gt; are tightly related to the optimal simplex tableau (Gomory, <br>
&gt; &gt; Lift-and-Project and others) keeping access to the <br>
&gt; OsiSolver is an option.<br>
&gt; &gt;<br>
&gt; &gt; Francois<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt; On Tue, 12 Dec 2006, John J Forrest wrote:<br>
&gt; &gt;<br>
&gt; &gt;&gt; Francois suggested I might modify the cut generators for
<br>
&gt; which I was <br>
&gt; &gt;&gt; responsible to use CglData classes, so I looked more closely
at the<br>
&gt; &gt; ideas<br>
&gt; &gt;&gt; put forward by Francois and Matt - and I strongly dislike
them - <br>
&gt; &gt;&gt; there must be a better way.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; Matt said he wanted to be independent of any solver or <br>
&gt; solver interface.<br>
&gt; &gt; I<br>
&gt; &gt;&gt; have no problem with the first, but I have with the <br>
&gt; second. &nbsp;Instead <br>
&gt; &gt;&gt; of<br>
&gt; &gt; a<br>
&gt; &gt;&gt; known interface OsiSolverInterface it seems that a new CglData
<br>
&gt; &gt;&gt; interface is being proposed which has less functionality
and a <br>
&gt; &gt;&gt; totally different interface. &nbsp;The idea of a simple data
<br>
&gt; object where <br>
&gt; &gt;&gt; there is no virtual overhead for getting arrays such as <br>
&gt; bounds is a <br>
&gt; &gt;&gt; good idea. &nbsp;In fact Laci and I are using such a class
so <br>
&gt; that we can <br>
&gt; &gt;&gt; share coding between Cbc and BCP. &nbsp;Our attempt <br>
&gt; &gt;&gt; (OsiBranchingInformation hidden in file<br>
&gt; &gt;&gt; OsiBranchingObject.hpp) has practically the same <br>
&gt; information as CglData.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; I would suggest a new OsiXxxSolverInterface class derived
from <br>
&gt; &gt;&gt; OsiSolverInterface. &nbsp;It could be filled from an OsiSolverInterface<br>
&gt; &gt; (either<br>
&gt; &gt;&gt; owning arrays or not as the user wanted) and would throw
<br>
&gt; an exception <br>
&gt; &gt;&gt; if you try and solve anything. &nbsp;It could be extended
to have data <br>
&gt; &gt;&gt; that is necessary for cuts and for using in a branch and
<br>
&gt; bound code. &nbsp;<br>
&gt; &gt;&gt; In that<br>
&gt; &gt; way<br>
&gt; &gt;&gt; the existing cut generators could be used without re-writing
which <br>
&gt; &gt;&gt; could lead to the introduction of bugs.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; John Forrest<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; fmargot@andrew.cmu.edu<br>
&gt; &gt;&gt; Sent by: cgl-bounces@list.coin-or.org<br>
&gt; &gt;&gt; 12/04/2006 09:38 AM<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; To<br>
&gt; &gt;&gt; Matthew Galati &lt;Matthew.Galati@sas.com&gt; cc cgl <br>
&gt; &lt;cgl@list.coin-or.org&gt; <br>
&gt; &gt;&gt; Subject<br>
&gt; &gt;&gt; Re: [Cgl] CGL Design<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; I have implemented something similar to what Matt <br>
&gt; suggested below for <br>
&gt; &gt;&gt; getting rid of the dependence on the solver. Currently it
applies <br>
&gt; &gt;&gt; only to the CglRedSplit generator. What I suggest is to <br>
&gt; have a class <br>
&gt; &gt;&gt; CglData containing the following members:<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; &nbsp; // Number of constraints<br>
&gt; &gt;&gt; &nbsp; int nrow;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; &nbsp; // Number of variables.<br>
&gt; &gt;&gt; &nbsp; int ncol;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; &nbsp; // Pointer on matrix of coefficients (ordered by columns).<br>
&gt; &gt;&gt; &nbsp; CoinPackedMatrix const *matrixByCol;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; &nbsp; // Pointer on matrix of coefficients (ordered by rows).<br>
&gt; &gt;&gt; &nbsp; CoinPackedMatrix const *matrixByRow;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; &nbsp; // Pointer on vector of objective coefficients.<br>
&gt; &gt;&gt; &nbsp; const double *obj;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; &nbsp; // Pointer on vector of lower bounds on variables.<br>
&gt; &gt;&gt; &nbsp; const double *colLower;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; &nbsp; // Pointer on vector of upper bounds for variables.<br>
&gt; &gt;&gt; &nbsp; const double *colUpper;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; &nbsp; // Pointer on vector of lower bounds for constraints.<br>
&gt; &gt;&gt; &nbsp; const double *rowLower;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; &nbsp; // Pointer on vector of upper bounds for constraints.<br>
&gt; &gt;&gt; &nbsp; const double *rowUpper;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; &nbsp; // Pointer on vector of upper bounds for constraints.<br>
&gt; &gt;&gt; &nbsp; const double *rowRhs;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; &nbsp; // Pointer on vector of activity of constraints (i.e.
<br>
&gt; coefficient <br>
&gt; &gt;&gt; matrix<br>
&gt; &gt;&gt; &nbsp; // times separateThis)..<br>
&gt; &gt;&gt; &nbsp; const double *rowActivity;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; &nbsp; /** Pointer on vector of characters for columns types.<br>
&gt; &gt;&gt; &nbsp; &nbsp; &nbsp; colType[i] can have values<br>
&gt; &gt;&gt; &nbsp; &nbsp; &nbsp; &lt;UL&gt;<br>
&gt; &gt;&gt; &nbsp; &nbsp; &nbsp; &lt;LI&gt; 'C' : continuous<br>
&gt; &gt;&gt; &nbsp; &nbsp; &nbsp; &lt;LI&gt; 'B' : binary<br>
&gt; &gt;&gt; &nbsp; &nbsp; &nbsp; &lt;LI&gt; 'I' : integer<br>
&gt; &gt;&gt; &nbsp; &nbsp; &nbsp; &lt;/UL&gt;<br>
&gt; &gt;&gt; &nbsp; */<br>
&gt; &gt;&gt; &nbsp; const char *colType;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; &nbsp; // Pointer on vector for point to separate.<br>
&gt; &gt;&gt; &nbsp; const double *separateThis;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; &nbsp; // Pointer on tree information.<br>
&gt; &gt;&gt; &nbsp; const CglTreeInfo *treeInfo;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; &nbsp; /// Pointer on vector for point that should not be
cut; only for<br>
&gt; &gt; debug.<br>
&gt; &gt;&gt; &nbsp; const double *doNotSeparateThis;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; Each generator may derive a class (as I did with <br>
&gt; CglRedSplitData) to <br>
&gt; &gt;&gt; add additional data needed by the generator. If a <br>
&gt; generator does not <br>
&gt; &gt;&gt; require one of the members, the corresponding pointer may
be NULL.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; Then there are two ways to call the generator:<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; &nbsp; &nbsp;// Use the following for calling the cut generator
<br>
&gt; where rsdat is<br>
&gt; &gt;&gt; &nbsp; &nbsp;// a CglRedSplitData object<br>
&gt; &gt;&gt; &nbsp; &nbsp; cutGen.generateCuts(rsdat, cuts);<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; &nbsp; &nbsp; // Use the following for standard way to call
the cut generator<br>
&gt; &gt; where<br>
&gt; &gt;&gt; &nbsp; &nbsp; // clp is an OsiSolverInterface<br>
&gt; &gt;&gt; &nbsp; &nbsp; &nbsp;cutGen.generateCuts(*clp, cuts);<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; What seemed simplest to me was to define private data members
in <br>
&gt; &gt;&gt; CglRedSplit to store pointers on the data needed by the generator.
<br>
&gt; &gt;&gt; Each time generateCuts is called, all these data members
are set, <br>
&gt; &gt;&gt; using either the information from the OsiSolverInterface
or the <br>
&gt; &gt;&gt; information from the CglRedSplitData<br>
&gt; &gt; object.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; Then, there is a private method CglRedSplit::generateCuts(OsiCuts
<br>
&gt; &gt;&gt; &amp;cs) that does the actual cut generation based on the
data <br>
&gt; members in <br>
&gt; &gt;&gt; CglRedSplit.<br>
&gt; &gt;&gt; This seem quite easy to implement and will not disturb any
existing<br>
&gt; &gt; code.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; I have also put a driver in <br>
&gt; trunk/Cgl/example/cgl_data_test.cpp that <br>
&gt; &gt;&gt; can be compiled from build/Cgl/examples/ using<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; make DRIVER=cgl_data_test<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; and run from that directory for example on p0033.mps as<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; ./cgl_data_test ../../Data/Sample/p0033.mps<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; The code shows how to use either methods to call generateCuts().<br>
&gt; &gt;&gt; Comments are welcome.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; One thing I do not like is the colType member in CglData.
<br>
&gt; While it is <br>
&gt; &gt;&gt; useful, I could not find an Osi method returning a pointer
on that <br>
&gt; &gt;&gt; vector, implying that it must be constructed by the <br>
&gt; calling method. <br>
&gt; &gt;&gt; If we could replace<br>
&gt; &gt; it<br>
&gt; &gt;&gt; with something equivalent existing in Osi, that would be
better.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; Francois<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; On Sat, 11 Nov 2006, Matthew Galati wrote:<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;&gt; At Informs, I spoke briefly with Francois Margot about
the CGL <br>
&gt; &gt;&gt;&gt; design<br>
&gt; &gt;&gt; that I had suggested a while back (see old thread:<br>
&gt; &gt;&gt; <br>
&gt; http://list.coin-or.org/pipermail/coin-discuss/2006-March/001875.html<br>
&gt; &gt;&gt; )<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; Here is a little more about what I had in mind. I have
not tried<br>
&gt; &gt;&gt; anything like this, nor have I really worked out any <br>
&gt; details - just <br>
&gt; &gt;&gt; thinking out loud. Let me know what you think.<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; The main idea, is that I want to make CGL independent
of <br>
&gt; any solver <br>
&gt; &gt;&gt;&gt; or<br>
&gt; &gt;&gt; solver interface. In fact, a cut generator to me, is something
that<br>
&gt; &gt; solves<br>
&gt; &gt;&gt; a separation problem - that is, find a separating hyperplane
that <br>
&gt; &gt;&gt; cuts<br>
&gt; &gt; off<br>
&gt; &gt;&gt; a particular point, and is valid to the feasible region defined
by <br>
&gt; &gt;&gt; some model. Except for (simplex-based cuts, like Gomory and
<br>
&gt; &gt;&gt; LiftandProject), there is no need to assume anything about
<br>
&gt; where the <br>
&gt; &gt;&gt; point is coming<br>
&gt; &gt; from.<br>
&gt; &gt;&gt; I propose that CGL have a base class which is completely
<br>
&gt; independent <br>
&gt; &gt;&gt; of OSI. This would also allow the CGL library to be used
<br>
&gt; by others, <br>
&gt; &gt;&gt; without the burden of needing OSI.<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; It would also be nice to have a &quot;raw&quot; version
of generateCuts that<br>
&gt; &gt;&gt; depends on no other COIN libs - but, given most cut <br>
&gt; implementations <br>
&gt; &gt;&gt; will make use of CoinUtils anyway, it is probably fine to
use <br>
&gt; &gt;&gt; CoinUtils<br>
&gt; &gt; methods<br>
&gt; &gt;&gt; and objects. But, this forces Cgl dependence on Coin.<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; Example prototype:<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; class CglCutGenerator{<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; &nbsp;//---<br>
&gt; &gt;&gt;&gt; &nbsp;//--- Input : (1) a description of the feasible
region<br>
&gt; &gt;&gt;&gt; &nbsp;//--- &nbsp; &nbsp; &nbsp; &nbsp; (2) a point to
separate<br>
&gt; &gt;&gt;&gt; &nbsp;//--- Output: (1) a list of separating hyperplanes<br>
&gt; &gt;&gt;&gt; &nbsp;//---<br>
&gt; &gt;&gt;&gt; &nbsp;virtual int generateCuts(const CoinPackedMatrix
&amp; matrix,<br>
&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const double &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; * collb,<br>
&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const double &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; * colub,<br>
&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const double &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; * obj,<br>
&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const double &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; * rowlb,<br>
&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const double &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; * rowub,<br>
&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const char &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; * coltype,<br>
&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const double &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; * currSol,<br>
&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vector&lt;CoinCut&gt; &nbsp; &nbsp;
&nbsp; &nbsp;&amp; cuts,<br>
&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const CglTreeInfo &nbsp; &nbsp; &nbsp;
&nbsp;info =<br>
&gt; &gt; CglTreeInfo())<br>
&gt; &gt;&gt; = 0;<br>
&gt; &gt;&gt;&gt; }<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; For this, the only new thing we'd need is CoinCut - which
<br>
&gt; can just <br>
&gt; &gt;&gt;&gt; be a<br>
&gt; &gt;&gt; replacement for OsiCut - it should not be tied to Osi, <br>
&gt; since it has <br>
&gt; &gt;&gt; nothing specific about any solver. A CoinModel could also
<br>
&gt; help make <br>
&gt; &gt;&gt; this cleaner.<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; &nbsp;//or... force them to use something like CoinModel<br>
&gt; &gt;&gt;&gt; &nbsp;virtual int generateCuts(const CoinModel &nbsp;
&nbsp; &nbsp; &nbsp;&amp; model,<br>
&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const double &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; * currSol,<br>
&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vector&lt;CoinCut&gt; &nbsp; &nbsp;
&nbsp; &nbsp;&amp; cuts,<br>
&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const CglTreeInfo &nbsp; &nbsp; &nbsp;
&nbsp;info =<br>
&gt; &gt; CglTreeInfo())<br>
&gt; &gt;&gt; = 0;<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; All the non-solver specific cuts will be derived from
<br>
&gt; &gt;&gt;&gt; CglCutGenerator<br>
&gt; &gt;&gt; (as before) - just remove any dependence on Osi. This includes
<br>
&gt; &gt;&gt; clique, knapsack, flowcover, etc.<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; Then, for deriving solver specific cuts (like Gomory)
- <br>
&gt; we can have <br>
&gt; &gt;&gt;&gt; a<br>
&gt; &gt;&gt; separate library. One that does depend on Osi (and Cgl).
Call it <br>
&gt; &gt;&gt; libCglOsi. This can also include &quot;wrapper classes&quot;
for the <br>
&gt; base cuts <br>
&gt; &gt;&gt; clique, knapsack, etc - so that CglOsi users will have <br>
&gt; uniformity - <br>
&gt; &gt;&gt; as they did before.<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; //---<br>
&gt; &gt;&gt;&gt; //--- &nbsp; Cgl &nbsp; &nbsp;depends on Coin (NOT on
Osi)<br>
&gt; &gt;&gt;&gt; //--- &nbsp; CglOsi depends on Coin, Cgl and Osi<br>
&gt; &gt;&gt;&gt; //---<br>
&gt; &gt;&gt;&gt; class CglOsiCutGenerator {<br>
&gt; &gt;&gt;&gt; private:<br>
&gt; &gt;&gt;&gt; &nbsp;OsiSolverInterface * si;<br>
&gt; &gt;&gt;&gt; ...<br>
&gt; &gt;&gt;&gt; &nbsp;virtual void generateCuts(const OsiSolverInterface
&amp; si,<br>
&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;OsiCuts &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&amp; cuts,<br>
&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const <br>
&gt; CglTreeInfo<br>
&gt; &gt;&gt; info = CglTreeInfo())=0;<br>
&gt; &gt;&gt;&gt; }<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; So, an example derivation:<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; class CglOsiGomory : public CglOsiCutGenerator { &nbsp;//this
<br>
&gt; is exactly <br>
&gt; &gt;&gt;&gt; the same as before, it is dependent on Osi &nbsp;...<br>
&gt; &gt;&gt;&gt; };<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; class CglClique : public CglCutGenerator { &nbsp;//this
is exactly the <br>
&gt; &gt;&gt;&gt; same as before, but no dependence on Osi &nbsp;...<br>
&gt; &gt;&gt;&gt; };<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; class CglOsiClique : public CglOsiCutGenerator { &nbsp;<br>
&gt; //CglOsiClique is <br>
&gt; &gt;&gt;&gt; just a wrapper class for CglClique.<br>
&gt; &gt;&gt;&gt; private:<br>
&gt; &gt;&gt;&gt; &nbsp;CglClique cglClique;<br>
&gt; &gt;&gt;&gt; ...<br>
&gt; &gt;&gt;&gt; &nbsp;virtual void generateCuts(const OsiSolverInterface
&amp; si,<br>
&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;OsiCuts &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&amp; cuts,<br>
&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const <br>
&gt; CglTreeInfo<br>
&gt; &gt;&gt; info = CglTreeInfo()){<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; &nbsp; &nbsp;cglClique.generateCuts(si.getMatrixByRow(),<br>
&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; si.getColLowerBound(),<br>
&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; si.getColUpperBound(),<br>
&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ...<br>
&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ...<br>
&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; );<br>
&gt; &gt;&gt;&gt; &nbsp;}<br>
&gt; &gt;&gt;&gt; }<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; In this way, the old users still can just &quot;add cut
generators&quot; - <br>
&gt; &gt;&gt;&gt; this<br>
&gt; &gt;&gt; time, they are CglOsiCutGenerator(s), but non-OSI users still
have<br>
&gt; &gt; access<br>
&gt; &gt;&gt; to cliques, knapsack, etc, via the base classes CglCutGenerator(s).<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; Thanks,<br>
&gt; &gt;&gt;&gt; Matt<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; Matthew Galati - Optimization Developer SAS Institute
- <br>
&gt; Analytical <br>
&gt; &gt;&gt;&gt; Solutions Phone 919-531-0332, R5327<br>
&gt; &gt;&gt;&gt; Fax &nbsp; 919-677-4444<br>
&gt; &gt;&gt;&gt; http://coral.ie.lehigh.edu/~magh<br>
&gt; &gt;&gt;&gt; http://www.sas.com/technologies/analytics/optimization/<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt; _______________________________________________<br>
&gt; &gt;&gt; Cgl mailing list<br>
&gt; &gt;&gt; Cgl@list.coin-or.org<br>
&gt; &gt;&gt; http://list.coin-or.org/mailman/listinfo/cgl<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; _______________________________________________<br>
&gt; Cgl mailing list<br>
&gt; Cgl@list.coin-or.org<br>
&gt; http://list.coin-or.org/mailman/listinfo/cgl<br>
&gt; <br>
</font></tt>
<br>