00001
00002
00003
00004
00005
00006
00007
00008
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
00029
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
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++;
00055
00056 } else nnzR += cut -> row (). getNumElements ();
00057 }
00058
00059
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],
00076 *collb = new double [nCuts],
00077 *colub = new double [nCuts],
00078 *obj = new double [nCuts];
00079
00080
00081 CoinFillN (collb, nCuts, 0.);
00082 CoinFillN (colub, nCuts, 1.);
00083 CoinFillN (obj, nCuts, 0.);
00084
00085
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
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
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
00138
00139 start -= ncols;
00140
00141 start [ncols] = curel;
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
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
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
00229
00230
00231
00232
00233
00234
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 }