13 #include "CglCutGenerator.hpp"
15 #include "CoinPackedMatrix.hpp"
20 #define MIN_DENOM 1.e-10
43 register const void *t2) {
49 return ((a1 < a2) ? -1 :
64 register const void *p2) {
70 return ((i1 < i2) ? -1 :
102 *ind1 =
new int [n1],
103 *ind2 =
new int [n2];
106 *a1 =
new double [n1],
107 *a2 =
new double [n2];
117 for (
int i=0; i<n1; i++) {
118 pairs [i]. index = ind1c [i];
119 pairs [i]. position = i;
127 for (
int i=0; i<n1; i++) {
129 int rightpos = pairs [i]. position;
131 ind1 [i] = ind1c [rightpos];
132 a1 [i] = a1c [rightpos];
137 for (
int i=0; i<n2; i++) {
138 pairs [i]. index = ind2c [i];
139 pairs [i]. position = i;
144 for (
int i=0; i<n2; i++) {
146 int rightpos = pairs [i]. position;
148 ind2 [i] = ind2c [rightpos];
149 a2 [i] = a2c [rightpos];
170 printf (
"here are the two ineqs (sign=%d):\n", sign);
171 printf (
" 1: %g <=", l1);
for (
int i=0; i<n1; i++) printf (
" %+g x%d", a1 [i], ind1 [i]);
172 printf (
"<= %g\n 2: %g <=", u1, l2);
for (
int i=0; i<n2; i++) printf (
" %+g x%d", signA * a2 [i], ind2 [i]); printf (
"<= %g\n", u2);
189 if (i1 < n1 && (i2 == n2 || ind1 [i1] < ind2 [i2])) {
191 curalpha ->
alpha = 1.;
192 curalpha -> sign = (a1 [i1] < 0.) ?
NEG :
POS;
193 curalpha -> indVar = ind1 [i1];
198 }
else if (i2 < n2 && (i1 == n1 || ind2 [i2] < ind1 [i1])) {
200 curalpha ->
alpha = 0.;
201 curalpha -> sign = (signA * a2 [i2] < 0.) ?
NEG :
POS;
202 curalpha -> indVar = ind2 [i2];
212 double a2i2 = signA * a2 [i2];
217 - a2i2 / (a1 [i1] - a2i2);
219 if (curalpha ->
alpha <= 0. ||
220 curalpha ->
alpha >= 1.)
222 curalpha -> sign = (a1 [i1] > 0.) ?
POS :
NEG;
228 ((a1 [i1] < 0.) ?
NEG :
POS) :
229 ((a1 [i1] < 0.) ?
DN :
UP);
231 curalpha -> indVar = ind1 [i1];
233 if (curalpha ->
alpha > 0. &&
234 curalpha ->
alpha < 1.)
235 inalphas [incnt++] = curalpha;
243 printf (
"(%d,%g,%s) ",
246 (curalpha -> sign ==
NEG) ?
"NEG" :
247 (curalpha -> sign ==
POS) ?
"POS" :
248 (curalpha -> sign ==
DN) ?
"DN" :
"UP");
287 printf (
"--sorted: ");
288 for (
int i = 0; i < incnt; i++)
289 printf (
"(%d,%g,%s) ",
290 inalphas [i] -> indVar,
291 inalphas [i] ->
alpha,
292 (inalphas [i] -> sign ==
NEG) ?
"NEG" :
293 (inalphas [i] -> sign ==
POS) ?
"POS" :
294 (inalphas [i] -> sign ==
DN) ?
"DN" :
"UP");
321 minSum1 = 0., minSum2 = 0.,
322 maxSum1 = 0., maxSum2 = 0.;
334 for (
int i=0; i<n1; i++) {
336 int indVar1 = ind1 [i];
341 clb1 = clb [indVar1],
342 cub1 = cub [indVar1];
351 else if (fabs (a2i) < 1
e-10)
352 printf (
"\nNumerics in a2i\n\n");
357 bool zeroA = (fabs (sa2 [indVar1]) == 0.);
359 if (cub1 >
COUENNE_INFINITY/10) {
if (zeroA) mInfs ++;}
else minSum1 += a1i * cub1;
360 if (clb1 < -
COUENNE_INFINITY/10) {
if (zeroA) pInfs ++;}
else maxSum1 += a1i * clb1;
362 }
else if (a2i > 0.) {
364 bool zeroA = (fabs (sa2 [indVar1]) == 0.);
366 if (clb1 < -
COUENNE_INFINITY/10) {
if (zeroA) mInfs ++;}
else minSum1 += a1i * clb1;
367 if (cub1 >
COUENNE_INFINITY/10) {
if (zeroA) pInfs ++;}
else maxSum1 += a1i * cub1;
373 for (
int i=0; i<n2; i++) {
375 int indVar2 = ind2 [i];
378 a2i = a2 [i] * signA,
379 clb2 = clb [indVar2],
380 cub2 = cub [indVar2];
401 printf (
" at alpha=zero, m[in,ax]sum[12] = (1:(%g,%g), 2:(%g,%g)), %d mInf, %d pInf\n",
411 std::vector <std::pair <int, double> >
420 for (
int j=0;
j < n1;
j++) printf (
"x%d [%g,%g] ", ind1 [
j], clb [ind1 [j]], cub [ind1 [j]]); printf (
"--- ");
421 for (
int j=0; j < n2; j++) printf (
"x%d [%g,%g] ", ind2 [j], clb [ind2 [j]], cub [ind2 [j]]); printf (
"\n");
424 for (
int i = 0; i < incnt; i++) {
429 printf (
" looking at %d: (%d,%g,%s)\n", i,
430 inalphas [i] -> indVar,
431 inalphas [i] ->
alpha,
432 (inalphas [i] -> sign ==
NEG) ?
"NEG" :
433 (inalphas [i] -> sign ==
POS) ?
"POS" :
434 (inalphas [i] -> sign ==
DN) ?
"DN" :
"UP");
452 inalpha = inalphas [i];
455 signalpha = inalpha -> sign,
456 indVar = inalpha -> indVar;
465 if (fabs (clbi) > 0.) {
469 if (signalpha ==
DN) {pInfs++; mInfs--;}
470 else {pInfs--; mInfs++;}
475 sa1ic = sa1 [indVar] * clbi,
476 sa2ic = sa2 [indVar] * clbi;
478 if (signalpha ==
DN) {
480 minSum1 -= sa1ic; minSum2 -= sa2ic;
481 maxSum1 += sa1ic; maxSum2 += sa2ic;
485 minSum1 += sa1ic; minSum2 += sa2ic;
486 maxSum1 -= sa1ic; maxSum2 -= sa2ic;
493 if (fabs (cubi) > 0.) {
497 if (signalpha ==
DN) {pInfs--; mInfs++;}
498 else {pInfs++; mInfs--;}
503 sa1ic = sa1 [indVar] * cubi,
504 sa2ic = sa2 [indVar] * cubi;
506 if (signalpha ==
DN) {
508 minSum1 += sa1ic; minSum2 += sa2ic;
509 maxSum1 -= sa1ic; maxSum2 -= sa2ic;
513 minSum1 -= sa1ic; minSum2 -= sa2ic;
514 maxSum1 += sa1ic; maxSum2 += sa2ic;
520 (inalphas [i+1] -> alpha == alpha)) ++i;
525 printf (
" at alpha=%g, m[in,ax]sum[12] = (1:(%g,%g), 2:(%g,%g)), %d mInf, %d pInf\n",
526 inalphas [i] -> alpha,
532 for (
int j=0; j<n1+n2; j++) {
540 if (j >= n1 && sa1 [ind2 [j - n1]] != 0.)
544 indVar = ((j < n1) ? ind1 [j] : ind2 [j - n1]),
551 ci = alpha * sa1i + (1. -
alpha) * sa2i;
566 subMin1 = 0., subMin2 = 0.,
567 subMax1 = 0., subMax2 = 0.;
570 printf (
" now tightening x%d\n denominator: %g * %g + %g * %g = %g\n",
571 (j < n1) ? ind1 [j] : ind2 [j-n1],
572 alpha, sa1i, 1-alpha, sa2i, ci);
585 if (ci > 0.) tickMin++;
592 subMin1 = sa1i * clbi;
593 subMin2 = sa2i * clbi;
597 subMax1 = sa1i * clbi;
598 subMax2 = sa2i * clbi;
608 if (ci > 0.) tickMax++;
615 subMax1 = sa1i * cubi;
616 subMax2 = sa2i * cubi;
620 subMin1 = sa1i * cubi;
621 subMin2 = sa2i * cubi;
631 (pInfs == tickMax)) {
633 newL = ((l1 - l2 - (maxSum1 - maxSum2) + (subMax1 - subMax2)) * alpha + l2 - maxSum2 + subMax2) / ci;
637 attempting newL = ((l1 - l2 - (maxSum1 - maxSum2) + (subMax1 - subMax2)) * alpha + l2 - maxSum2 + subMax2) / ci\n \
638 ((%g - %g - (%g - %g) + (%g - %g)) * %g + %g - %g + %g) / %g = %g\n",
639 l1, l2, maxSum1, maxSum2, subMax1, subMax2, alpha, l2, maxSum2, subMax2, ci, newL);
645 (mInfs == tickMin)) {
647 newU = ((u1 - u2 - (minSum1 - minSum2) + (subMin1 - subMin2)) * alpha + u2 - minSum2 + subMin2) / ci;
651 attempting newU = ((u1 - u2 - (minSum1 - minSum2) + (subMin1 - subMin2)) * alpha + u2 - minSum2 + subMin2) / ci\n \
652 ((%g - %g - (%g - %g) + (%g - %g)) * %g + %g - %g + %g) / %g = %g\n",
653 u1, u2, minSum1, minSum2, subMin1, subMin2, alpha, u2, minSum2, subMin2, ci, newU);
660 printf (
" swap'em: %g, %g\n", newL, newU);
669 printf (
" final: %g, %g\n", newL, newU);
674 printf (
" bounds for x_%d: [%g,%g] vs [%g,%g]\n", indVar, newL, newU, clb [indVar], cub [indVar]);
686 printf (
"infeasible\n");
692 if (p -> bestSol () &&
693 ((p -> bestSol () [indVar] > newU +
COUENNE_EPS) ||
694 (p -> bestSol () [indVar] < newL -
COUENNE_EPS)) &&
695 (p -> bestSol () [indVar] >= clbi) &&
696 (p -> bestSol () [indVar] <= cubi))
698 printf (
"optimum violated: %g not in [%g,%g]\n", p -> bestSol () [indVar], newL, newU);
709 newLB. push_back (std::pair <int, double> (indVar, newL));
712 printf (
" new lower bound: x%d >= %g [%g]\n", indVar, newL, clb [indVar]);
720 newUB. push_back (std::pair <int, double> (indVar, newU));
723 printf (
" new upper bound: x%d <= %g [%g]\n", indVar, newU, cub [indVar]);
730 printf (
"===================================\n");
733 for (std::vector <std::pair <int, double> >::iterator i = newLB. begin (); i != newLB.
end (); ++i) {
735 if (isInteger [i -> first]) i -> second = ceil (i -> second -
COUENNE_EPS);
737 if (i -> second > clb [i -> first])
738 Lb [i -> first] = clb [i -> first] = i -> second;
741 for (std::vector <std::pair <int, double> >::iterator i = newUB. begin (); i != newUB.
end (); ++i) {
743 if (isInteger [i -> first]) i -> second = floor (i -> second +
COUENNE_EPS);
745 if (i -> second < cub [i -> first])
746 Ub [i -> first] = cub [i -> first] = i -> second;
int combine(CouenneProblem *p, int n1, int n2, const int *ind1, const int *ind2, double *sa1, double *sa2, const double *a1, const double *a2, double *clb, double *cub, double l1, double l2, double u1, double u2, bool *isInteger, int sign)
int compPair(register const void *p1, register const void *p2)
void fint fint fint real fint real real real real real real real real real * e
Class for MINLP problems with symbolic information.
int compthres(register const void *t1, register const void *t2)
double CouNumber
main number type in Couenne
bool isInteger(CouNumber x)
is this number integer?