/home/coin/SVN-release/OS-2.4.0/Couenne/src/disjunctive/OsiCuts2MatrVec.cpp

Go to the documentation of this file.
00001 /* $Id: OsiCuts2MatrVec.cpp 694 2011-06-18 20:13:17Z stefan $
00002  *
00003  * Name:    OsiCuts2MatrVec.cpp
00004  * Author:  Pietro Belotti
00005  * Purpose: turn OsiCuts objects into coefficient matrix and rhs vector
00006  *
00007  * (C) Carnegie-Mellon University, 2008. 
00008  * This file is licensed under the Eclipse Public License (EPL)
00009  */
00010 
00011 #include "CouenneDisjCuts.hpp"
00012 
00013 #include "OsiSolverInterface.hpp"
00014 
00015 #include "CoinPackedVector.hpp"
00016 #include "CoinPackedMatrix.hpp"
00017 #include "CoinHelperFunctions.hpp"
00018 
00019 #include "CouenneCutGenerator.hpp"
00020 
00021 #include "CouennePrecisions.hpp"
00022 #include "CouenneProblem.hpp"
00023 #include "CouenneExprVar.hpp"
00024 
00025 using namespace Ipopt;
00026 using namespace Couenne;
00027 
00028 // add CGLP columns to solver interface; return number of columns
00029 // added (for later removal)
00030 int CouenneDisjCuts::OsiCuts2MatrVec (OsiSolverInterface *cglp,
00031                                       OsiCuts *cuts,
00032                                       int displRow,
00033                                       int displRhs) const {
00034   int
00035     ncols  = 0,
00036     nrcuts = cuts -> sizeRowCuts (),
00037     nccuts = cuts -> sizeColCuts (),
00038     ncgrow = cglp -> getNumRows  () - 1,
00039     nnzR   = 0,
00040     ncC    = 0;
00041 
00042   if (!(nrcuts || nccuts))
00043     return 0;
00044 
00045   // count nonzero in row cuts
00046   for (int i=nrcuts; i--;) {
00047 
00048     OsiRowCut *cut = cuts -> rowCutPtr (i);
00049 
00050     if ((cut -> sense () == 'E') ||
00051         (cut -> sense () == 'R')) {
00052 
00053       nnzR += 2 * cut -> row (). getNumElements ();
00054       nrcuts++; // can increase as not used
00055 
00056     } else nnzR += cut -> row (). getNumElements ();
00057   }
00058 
00059   // count bound constraints in column cuts
00060   for (int i=nccuts; i--;) {
00061     OsiColCut *cut = cuts -> colCutPtr (i);
00062     ncC += 
00063       cut -> lbs ().getNumElements () + 
00064       cut -> ubs ().getNumElements ();
00065   }
00066 
00067   int 
00068      nnz     = 2 * (nnzR + 2*nrcuts + 3*ncC),
00069     *indices = new int [nnz],
00070     *start   = new int [nrcuts + ncC + 1],
00071      curel   = 0,
00072      nCuts   = 2*(nrcuts + ncC);
00073 
00074   double 
00075     *elements = new double [nnz],    // for row cuts + col cuts
00076     *collb    = new double [nCuts],  // lower bounds for new columns
00077     *colub    = new double [nCuts],  // upper 
00078     *obj      = new double [nCuts];  // objective coefficient (zero)
00079 
00080   // trivial, lower/upper bounds and objective coefficients
00081   CoinFillN (collb, nCuts, 0.);
00082   CoinFillN (colub, nCuts, 1.);
00083   CoinFillN (obj,   nCuts, 0.);
00084 
00085   // scan OsiColCuts ////////////////////////////////////////
00086 
00087   double *saveEl  = elements;
00088   int    *saveInd = indices;
00089 
00090   for (int i = nccuts; i--;) {
00091 
00092     OsiColCut *cut = cuts -> colCutPtr (i);
00093 
00094     const CoinPackedVector
00095       &lbs = cut -> lbs (),
00096       &ubs = cut -> ubs ();
00097 
00098     // lower bounds
00099     const int
00100       *lind = lbs. getIndices (), 
00101        nlcc = lbs. getNumElements ();
00102     const double *lele = lbs. getElements ();
00103 
00104     for (int j = nlcc; j--; lind++, lele++)
00105 
00106       if (couenneCG_ -> Problem () -> Var (*lind) -> Multiplicity () > 0) {
00107         *start++ = curel;
00108         *elements++ = -1.;           *indices++ = displRow + *lind;
00109         if (fabs (*lele) > COUENNE_EPS) 
00110           {*elements++ = -*lele;     *indices++ = displRhs; curel++;}
00111         *elements++ =  1.;           *indices++ = ncgrow;
00112         curel += 2;
00113       }
00114 
00115     // upper bounds
00116     const int
00117       *uind = ubs. getIndices (), 
00118        nucc = ubs. getNumElements ();
00119     const double *uele = ubs. getElements ();
00120 
00121     for (int j = nucc; j--; uind++, uele++)
00122       if (couenneCG_ -> Problem () -> Var (*uind) -> Multiplicity () > 0) {
00123         *start++ = curel;
00124         *elements++ =  1.;          *indices++ = displRow + *uind;
00125         if (fabs (*uele) > COUENNE_EPS) 
00126           {*elements++ = *uele;     *indices++ = displRhs; curel++;}
00127         *elements++ =  1.;          *indices++ = ncgrow;
00128         curel += 2;
00129       }
00130 
00131     ncols += nlcc + nucc;
00132   }
00133 
00134   elements = saveEl;
00135   indices  = saveInd;
00136     
00137   //elements -= (3 * ncols);
00138   //indices  -= (3 * ncols);
00139   start    -= ncols;
00140 
00141   start [ncols] = curel; // may go
00142 
00143   if (jnlst_ -> ProduceOutput (J_MATRIX, J_DISJCUTS)) {
00144     printf ("%d cuts, have %d cols and cur el is %d. Now for the %d row cuts\n",
00145             nccuts, ncols, curel, nrcuts);
00146 
00147     printf ("matrix (.. %d) %d elements:\n", ncols, curel);
00148 
00149     printf ("start: "); for (int i=0; i<=ncols; i++) printf ("%d ", start [i]);
00150 
00151     printf ("\nElements:\n"); 
00152     for (int i=0, j=0; i<ncols; i++) {
00153       for (int k=0; k<start[i+1] - start[i]; k++, j++) 
00154         printf ("(%d %g) ", indices [j], elements [j]);
00155       printf ("\n");
00156     }
00157   }
00158 
00159   // scan OsiRowCuts /////////////////////////////////////////////
00160 
00161   for (int i = cuts -> sizeRowCuts (); i--;) {
00162 
00163     OsiRowCut *cut = cuts -> rowCutPtr (i);
00164 
00165     const CoinPackedVector &row = cut -> row ();
00166 
00167     const double 
00168       rhs    = cut -> rhs   (),
00169       rng    = cut -> range (),
00170       *rowEl = row. getElements ();
00171 
00172     const int 
00173       *rowIn = row. getIndices (),
00174       rowNE  = row. getNumElements ();
00175 
00176     switch (cut -> sense ()) {
00177 
00178     case 'L': 
00179 
00180       start [ncols++] = curel;
00181       CoinCopyDisp (rowIn, rowNE, indices  + curel, displRow);
00182       CoinCopyN    (rowEl, rowNE, elements + curel);
00183       curel += rowNE;
00184       if (fabs (rhs) > COUENNE_EPS) {indices  [curel] = displRhs;  elements [curel++] = rhs;}
00185       indices  [curel] = ncgrow;    elements [curel++] = 1.;
00186 
00187       break;
00188 
00189     case 'E':
00190     case 'R':
00191 
00192       start [ncols++] = curel;
00193       CoinCopyDisp (rowIn, rowNE, indices  + curel, displRow);
00194       CoinCopyN    (rowEl, rowNE, elements + curel);
00195       curel += rowNE;
00196       if (fabs (rhs+rng) > COUENNE_EPS) {indices  [curel] = displRhs; elements [curel++] = rhs + rng;}
00197       // rng only used here, zero for 'E'
00198       indices  [curel] = ncgrow;   elements [curel++] = 1.;
00199 
00200       start [ncols++] = curel;
00201       CoinCopyDisp (rowIn, rowNE, indices  + curel, displRow);
00202       CoinInvN     (rowEl, rowNE, elements + curel);
00203       curel += rowNE;
00204       if (fabs (rhs) > COUENNE_EPS) {indices  [curel] = displRhs;  elements [curel++] = -rhs;}
00205       indices  [curel] = ncgrow;    elements [curel++] = 1.;
00206 
00207       break;
00208 
00209     case 'G':
00210       start [ncols++] = curel;
00211       CoinCopyDisp (rowIn, rowNE, indices  + curel, displRow);
00212       CoinInvN     (rowEl, rowNE, elements + curel);
00213       curel += rowNE;
00214       if (fabs (rhs) > COUENNE_EPS) {indices  [curel] = displRhs;  elements [curel++] = -rhs;}
00215       indices  [curel] = ncgrow;    elements [curel++] = 1.;
00216 
00217       break;
00218 
00219     default: printf ("Unknown type of cut:");
00220       cut -> print ();
00221       printf ("Aborting.\n");
00222       exit (-1);
00223     }
00224   }
00225 
00226   start [ncols] = curel;
00227 
00228   //  ncols=1;start[1]=3;
00229   /*  *start=0; start[1]=1;
00230   *indices=0;
00231   *elements=4.55;
00232   *collb=-3;
00233   *colub=+3;
00234   *obj=4;*/
00235 
00236 
00237   if (jnlst_ -> ProduceOutput (J_MATRIX, J_DISJCUTS)) {
00238     printf ("===================\nmatrix (.. %d) %d elements:\n", ncols, curel);
00239 
00240     printf ("start: "); for (int i=0; i<=ncols; i++) printf ("%d ", start [i]);
00241 
00242     printf ("\nElements:\n"); 
00243     for (int i=0, j=0; i<ncols; i++) {
00244       for (int k=0; k<start[i+1] - start[i]; k++, j++) 
00245         printf ("(%d %g) ", indices [j], elements [j]);
00246       printf ("\n");
00247     }
00248   }
00249 
00250   if (jnlst_ -> ProduceOutput (J_MATRIX, J_DISJCUTS)) {
00251 
00252     const CoinPackedMatrix *m = cglp->getMatrixByCol();
00253 
00254     printf ("before: size_ = %d, start [%d] = %d\n", 
00255             m -> getNumElements (), 
00256             m -> getSizeVectorLengths(),
00257             m -> getVectorStarts () [m -> getSizeVectorLengths()]);
00258   }
00259 
00260   cglp -> addCols (ncols,    start,
00261                    indices,  elements,
00262                    collb,    colub,   
00263                    obj);
00264 
00265   if (jnlst_ -> ProduceOutput (J_MATRIX, J_DISJCUTS)) {
00266 
00267     const CoinPackedMatrix *m = cglp->getMatrixByCol();
00268     printf ("after: size_ = %d, start [%d] = %d\n", 
00269             m -> getNumElements (), 
00270             m -> getSizeVectorLengths(),
00271             m -> getVectorStarts () [m -> getSizeVectorLengths()]);
00272   }
00273 
00274   delete [] elements;
00275   delete [] collb;
00276   delete [] colub;
00277   delete [] obj;
00278 
00279   delete [] indices;
00280   delete [] start;
00281 
00282   return ncols;
00283 }

Generated on Thu Sep 22 03:05:57 2011 by  doxygen 1.4.7