13 #include "OsiSolverInterface.hpp"
15 #include "CoinPackedVector.hpp"
16 #include "CoinPackedMatrix.hpp"
17 #include "CoinHelperFunctions.hpp"
25 using namespace Ipopt;
26 using namespace Couenne;
30 int CouenneDisjCuts::OsiCuts2MatrVec (OsiSolverInterface *cglp,
36 nrcuts = cuts -> sizeRowCuts (),
37 nccuts = cuts -> sizeColCuts (),
38 ncgrow = cglp -> getNumRows () - 1,
42 if (!(nrcuts || nccuts))
46 for (
int i=nrcuts; i--;) {
48 OsiRowCut *cut = cuts -> rowCutPtr (i);
50 if ((cut -> sense () ==
'E') ||
51 (cut -> sense () ==
'R')) {
53 nnzR += 2 * cut -> row (). getNumElements ();
56 }
else nnzR += cut -> row (). getNumElements ();
60 for (
int i=nccuts; i--;) {
61 OsiColCut *cut = cuts -> colCutPtr (i);
63 cut -> lbs ().getNumElements () +
64 cut -> ubs ().getNumElements ();
68 nnz = 2 * (nnzR + 2*nrcuts + 3*ncC),
69 *indices =
new int [nnz],
70 *start =
new int [nrcuts + ncC + 1],
72 nCuts = 2*(nrcuts + ncC);
75 *elements =
new double [
nnz],
76 *collb =
new double [nCuts],
77 *colub =
new double [nCuts],
78 *obj =
new double [nCuts];
81 CoinFillN (collb, nCuts, 0.);
82 CoinFillN (colub, nCuts, 1.);
83 CoinFillN (obj, nCuts, 0.);
87 double *saveEl = elements;
88 int *saveInd = indices;
90 for (
int i = nccuts; i--;) {
92 OsiColCut *cut = cuts -> colCutPtr (i);
94 const CoinPackedVector
100 *lind = lbs. getIndices (),
101 nlcc = lbs. getNumElements ();
102 const double *lele = lbs. getElements ();
104 for (
int j = nlcc;
j--; lind++, lele++)
106 if (couenneCG_ -> Problem () -> Var (*lind) -> Multiplicity () > 0) {
108 *elements++ = -1.; *indices++ = displRow + *lind;
110 {*elements++ = -*lele; *indices++ = displRhs; curel++;}
111 *elements++ = 1.; *indices++ = ncgrow;
117 *uind = ubs. getIndices (),
118 nucc = ubs. getNumElements ();
119 const double *uele = ubs. getElements ();
121 for (
int j = nucc;
j--; uind++, uele++)
122 if (couenneCG_ -> Problem () -> Var (*uind) -> Multiplicity () > 0) {
124 *elements++ = 1.; *indices++ = displRow + *uind;
126 {*elements++ = *uele; *indices++ = displRhs; curel++;}
127 *elements++ = 1.; *indices++ = ncgrow;
131 ncols += nlcc + nucc;
141 start [ncols] = curel;
143 if (jnlst_ -> ProduceOutput (J_MATRIX,
J_DISJCUTS)) {
144 printf (
"%d cuts, have %d cols and cur el is %d. Now for the %d row cuts\n",
145 nccuts, ncols, curel, nrcuts);
147 printf (
"matrix (.. %d) %d elements:\n", ncols, curel);
149 printf (
"start: ");
for (
int i=0; i<=ncols; i++) printf (
"%d ", start [i]);
151 printf (
"\nElements:\n");
152 for (
int i=0,
j=0; i<ncols; i++) {
153 for (
int k=0;
k<start[i+1] - start[i];
k++,
j++)
154 printf (
"(%d %g) ", indices [
j], elements [j]);
161 for (
int i = cuts -> sizeRowCuts (); i--;) {
163 OsiRowCut *cut = cuts -> rowCutPtr (i);
165 const CoinPackedVector &row = cut -> row ();
169 rng = cut -> range (),
170 *rowEl = row. getElements ();
173 *rowIn = row. getIndices (),
174 rowNE = row. getNumElements ();
176 switch (cut -> sense ()) {
180 start [ncols++] = curel;
182 CoinCopyN (rowEl, rowNE, elements + curel);
184 if (fabs (rhs) >
COUENNE_EPS) {indices [curel] = displRhs; elements [curel++] = rhs;}
185 indices [curel] = ncgrow; elements [curel++] = 1.;
192 start [ncols++] = curel;
194 CoinCopyN (rowEl, rowNE, elements + curel);
196 if (fabs (rhs+rng) >
COUENNE_EPS) {indices [curel] = displRhs; elements [curel++] = rhs + rng;}
198 indices [curel] = ncgrow; elements [curel++] = 1.;
200 start [ncols++] = curel;
202 CoinInvN (rowEl, rowNE, elements + curel);
204 if (fabs (rhs) >
COUENNE_EPS) {indices [curel] = displRhs; elements [curel++] = -rhs;}
205 indices [curel] = ncgrow; elements [curel++] = 1.;
210 start [ncols++] = curel;
212 CoinInvN (rowEl, rowNE, elements + curel);
214 if (fabs (rhs) >
COUENNE_EPS) {indices [curel] = displRhs; elements [curel++] = -rhs;}
215 indices [curel] = ncgrow; elements [curel++] = 1.;
219 default: printf (
"Unknown type of cut:");
221 printf (
"Aborting.\n");
226 start [ncols] = curel;
237 if (jnlst_ -> ProduceOutput (J_MATRIX,
J_DISJCUTS)) {
238 printf (
"===================\nmatrix (.. %d) %d elements:\n", ncols, curel);
240 printf (
"start: ");
for (
int i=0; i<=ncols; i++) printf (
"%d ", start [i]);
242 printf (
"\nElements:\n");
243 for (
int i=0,
j=0; i<ncols; i++) {
244 for (
int k=0;
k<start[i+1] - start[i];
k++,
j++)
245 printf (
"(%d %g) ", indices [
j], elements [j]);
250 if (jnlst_ -> ProduceOutput (J_MATRIX,
J_DISJCUTS)) {
252 const CoinPackedMatrix *
m = cglp->getMatrixByCol();
254 printf (
"before: size_ = %d, start [%d] = %d\n",
255 m -> getNumElements (),
256 m -> getSizeVectorLengths(),
257 m -> getVectorStarts () [m -> getSizeVectorLengths()]);
260 cglp -> addCols (ncols, start,
265 if (jnlst_ -> ProduceOutput (J_MATRIX,
J_DISJCUTS)) {
267 const CoinPackedMatrix *
m = cglp->getMatrixByCol();
268 printf (
"after: size_ = %d, start [%d] = %d\n",
269 m -> getNumElements (),
270 m -> getSizeVectorLengths(),
271 m -> getVectorStarts () [m -> getSizeVectorLengths()]);
void CoinInvN(register const double *orig, register int n, register double *inverted)
invert all contents
const Ipopt::EJournalCategory J_DISJCUTS(Ipopt::J_USER6)
void CoinCopyDisp(register const int *src, register int num, register int *dst, register int displacement)
a CoinCopyN with a += on each element
int nnz
ATTENTION: Filter expect the jacobian to be ordered by row.