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