39#define NLHDLR_NAME "bilinear"
40#define NLHDLR_DESC "bilinear handler for expressions"
41#define NLHDLR_DETECTPRIORITY -10
42#define NLHDLR_ENFOPRIORITY -10
44#define MIN_INTERIORITY 0.01
45#define MIN_ABSBOUNDSIZE 0.1
48#define TABLE_NAME_BILINEAR "nlhdlr_bilinear"
49#define TABLE_DESC_BILINEAR "bilinear nlhdlr statistics table"
50#define TABLE_POSITION_BILINEAR 14800
51#define TABLE_EARLIEST_STAGE_BILINEAR SCIP_STAGE_INITSOLVE
59struct SCIP_NlhdlrExprData
66 int nseparoundslastnode;
80 int maxseparoundsroot;
107 norm = sqrt(
SQR(xcoef) +
SQR(ycoef));
110 if( xcoef * ycoef >= 0 )
155 interiority = 2.0*
MIN(interiorityx, interiorityy);
194 assert(nineqs >= 0 && nineqs <= 2);
220 for(
i = 0;
i < nineqs; ++
i )
222 constshift[
i] =
MAX(0.0, ineqs[3*
i] * refx - ineqs[3*
i+1] * refy - ineqs[3*
i+2]);
229 SCIPcomputeBilinEnvelope2(
scip, bilincoef, lbx, ubx, refx, lby, uby, refy, overestimate, ineqs[0], ineqs[1],
230 ineqs[2] + constshift[0], ineqs[3], ineqs[4], ineqs[5] + constshift[1], &xcoef, &ycoef, &constant, &update);
234 SCIP_Real val = xcoef * refx + ycoef * refy + constant;
235 SCIP_Real relimpr = 1.0 - (
REALABS(val - bilincoef * refx * refy) + 1e-4) / (
REALABS(*bestval - bilincoef * refx * refy) + 1e-4);
239 if( relimpr > 0.05 && absimpr > 1e-3 && ((overestimate &&
SCIPisRelLT(
scip, val, *bestval))
244 *bestconst = constant;
252 for(
i = 0;
i < nineqs; ++
i )
254 SCIPcomputeBilinEnvelope1(
scip, bilincoef, lbx, ubx, refx, lby, uby, refy, overestimate, ineqs[3*
i], ineqs[3*
i+1],
255 ineqs[3*
i+2] + constshift[
i], &xcoef, &ycoef, &constant, &update);
259 SCIP_Real val = xcoef * refx + ycoef * refy + constant;
261 / (
REALABS(mccormickval - bilincoef * refx * refy) + 1e-4);
265 if( relimpr > 0.05 && absimpr > 1e-3 && ((overestimate &&
SCIPisRelLT(
scip, val, *bestval))
270 *bestconst = constant;
303 for(
i = 0;
i < nineqs; ++
i )
360 assert(noverineqs + nunderineqs > 0);
361 assert(noverineqs + nunderineqs <= 4);
366 for(
i = 0;
i < noverineqs; ++
i )
368 SCIPdebugMsg(
scip,
"over-inequality %d: %g*x <= %g*y + %g\n",
i, overineqs[3*
i], overineqs[3*
i+1], overineqs[3*
i+2]);
369 ineqs[3*nineqs] = overineqs[3*
i];
370 ineqs[3*nineqs+1] = overineqs[3*
i+1];
371 ineqs[3*nineqs+2] = overineqs[3*
i+2];
374 for(
i = 0;
i < nunderineqs; ++
i )
376 SCIPdebugMsg(
scip,
"under-inequality %d: %g*x <= %g*y + %g 0\n",
i, underineqs[3*
i], underineqs[3*
i+1], underineqs[3*
i+2]);
377 ineqs[3*nineqs] = underineqs[3*
i];
378 ineqs[3*nineqs+1] = underineqs[3*
i+1];
379 ineqs[3*nineqs+2] = underineqs[3*
i+2];
382 assert(nineqs == noverineqs + nunderineqs);
415 for(
i = 0;
i < 4; ++
i )
420 SCIPdebugMsg(
scip,
"corner point (%g,%g) feasible? %u\n", cx, cy,
isPointFeasible(
scip, cx, cy, lbx, ubx, lby, uby, ineqs, nineqs));
431 for(
i = 0;
i < nineqs; ++
i )
436 SCIP_Real px[5] = {lbx, ubx, (coefy*lby + constant)/coefx, (coefy*uby + constant)/coefx, 0.0};
437 SCIP_Real py[5] = {(coefx*lbx - constant)/coefy, (coefx*ubx - constant)/coefy, lby, uby, 0.0};
441 py[4] = (-constant) / (2.0 * coefy);
442 px[4] = constant / (2.0 * coefx);
444 for( j = 0; j < 5; ++j )
446 SCIPdebugMsg(
scip,
"intersection point (%g,%g) feasible? %u\n", px[j], py[j],
isPointFeasible(
scip, px[j], py[j], lbx, ubx, lby, uby, ineqs, nineqs));
449 xs[*npoints] = px[j];
450 ys[*npoints] = py[j];
457 for(
i = 0;
i < nineqs - 1; ++
i )
464 for( j =
i + 1; j < nineqs; ++j )
476 py = (constant2 * coefx1 - constant1 * coefx2)/ (coefx2 * coefy1 - coefx1 * coefy2);
477 px = (coefy1 * py + constant1) / coefx1;
503 for(
i = 0;
i < 2; ++
i )
505 SCIP_Real vals[4] = {lbx, ubx, lby, uby};
510 val = (
i == 0) ? exprbounds.
inf : exprbounds.
sup;
513 for( k = 0; k < 4; ++k )
525 xs[*npoints] = vals[k];
530 else if( k >= 2 &&
isPointFeasible(
scip, res, vals[k], lbx, ubx, lby, uby, ineqs, nineqs) )
533 ys[*npoints] = vals[k];
541 for(
i = 0;
i < nineqs; ++
i )
560 for( k = 0; k < 2; ++k )
580 px = (coefy * py + constant) / coefx;
593 px = (coefy * py + constant) / coefx;
630 assert(noverineqs + nunderineqs <= 4);
633 if( noverineqs == 0 && nunderineqs == 0 )
649 noverineqs,
FALSE, xs, ys, &npoints);
661 SCIPdebugMsg(
scip,
"point 0: (%g,%g) -> inf = sup = %g\n", xs[0], ys[0], inf);
662 for(
i = 1;
i < npoints; ++
i )
664 inf =
MIN(inf, xs[
i] * ys[
i]);
665 sup =
MAX(sup, xs[
i] * ys[
i]);
666 SCIPdebugMsg(
scip,
"point %d: (%g,%g) -> inf = %g, sup = %g\n",
i, xs[
i], ys[
i], inf, sup);
712 assert(noverineqs + nunderineqs > 0);
720 noverineqs,
TRUE, xs, ys, &npoints);
727 exprinf = exprbounds.
inf;
728 exprsup = exprbounds.
sup;
731 for(
i = 0;
i < npoints; ++
i )
762 (*intervalx).inf =
MIN((*intervalx).inf, xs[
i]);
763 (*intervalx).sup =
MAX((*intervalx).sup, xs[
i]);
764 (*intervaly).inf =
MIN((*intervaly).inf, ys[
i]);
765 (*intervaly).sup =
MAX((*intervaly).sup, ys[
i]);
768 SCIPdebugMsg(
scip,
"consider points (%g,%g)=%g for reverse propagation\n", xs[
i], ys[
i], val);
936 assert(mi < 0.0 && mj < 0.0);
939 computeBilinEnvelope2(
scip, -
x,
y, -mi, qi, -mj, qj, xi, yi, xj, yj, xcoef, ycoef, constant);
945 *constant = -(*constant);
973 for(
c = 0;
c < nlhdlrdata->nexprs; ++
c )
998 for(
c = 0;
c < nlhdlrdata->nexprs; ++
c )
1009 if( nlhdlrexprdata->nunderineqs > 0 || nlhdlrexprdata->noverineqs > 0 )
1061 for(
c = 0;
c < nlhdlrdata->nexprs; ++
c )
1086 for(
c = 0;
c < nlhdlrdata->nexprs; ++
c )
1097 if( nlhdlrexprdata->nunderineqs > 0 || nlhdlrexprdata->noverineqs > 0 )
1137 assert((*nlhdlrdata)->nexprs == 0);
1139 if( (*nlhdlrdata)->exprmap !=
NULL )
1162 assert(nlhdlrdata->nexprs > 0);
1168 assert(pos >= 0 && pos < nlhdlrdata->nexprs);
1169 assert(nlhdlrdata->exprs[pos] == expr);
1172 if( nlhdlrdata->nexprs > 0 && pos != nlhdlrdata->nexprs - 1 )
1174 SCIP_EXPR* lastexpr = nlhdlrdata->exprs[nlhdlrdata->nexprs - 1];
1175 assert(expr != lastexpr);
1178 nlhdlrdata->exprs[pos] = lastexpr;
1179 nlhdlrdata->exprs[nlhdlrdata->nexprs - 1] =
NULL;
1186 --nlhdlrdata->nexprs;
1195#define nlhdlrInitBilinear NULL
1237 for(
c = 0;
c < 2; ++
c )
1252 (*nlhdlrexprdata)->lastnodeid = -1;
1255 if( nlhdlrdata->exprsize < nlhdlrdata->nexprs + 1 )
1258 assert(newsize > nlhdlrdata->exprsize);
1261 nlhdlrdata->exprsize = newsize;
1265 if( nlhdlrdata->exprmap ==
NULL )
1274 for(
i = 0;
i < nlhdlrdata->nexprs; ++
i )
1275 assert(nlhdlrdata->exprs[
i] != expr);
1280 nlhdlrdata->exprs[nlhdlrdata->nexprs] = expr;
1283 ++nlhdlrdata->nexprs;
1287 || nlhdlrdata->usereverseprop,
TRUE,
TRUE) );
1289 || nlhdlrdata->usereverseprop,
TRUE,
TRUE) );
1293 if( *nlhdlrexprdata !=
NULL )
1297 if( nlhdlrdata->useinteval || nlhdlrdata->usereverseprop )
1302 if( *participating )
1336#define nlhdlrInitSepaBilinear NULL
1339#define nlhdlrExitSepaBilinear NULL
1342#define nlhdlrEnfoBilinear NULL
1365 *addedbranchscores =
FALSE;
1368 if( nlhdlrexprdata->noverineqs == 0 && nlhdlrexprdata->nunderineqs == 0 )
1377 if( nlhdlrexprdata->lastnodeid != nodeid )
1379 nlhdlrexprdata->lastnodeid = nodeid;
1380 nlhdlrexprdata->nseparoundslastnode = 0;
1384 ++nlhdlrexprdata->nseparoundslastnode;
1387 if( (
SCIPgetDepth(
scip) == 0 && nlhdlrexprdata->nseparoundslastnode > nlhdlrdata->maxseparoundsroot)
1388 || (
SCIPgetDepth(
scip) > 0 && nlhdlrexprdata->nseparoundslastnode > nlhdlrdata->maxseparounds)
1416 violation = lincoefx * refpointx + lincoefy * refpointy + linconstant -
SCIPgetSolVal(
scip,
sol, auxvar);
1418 violation = -violation;
1424 SCIP_Real mccormickval = lincoefx * refpointx + lincoefy * refpointy + linconstant;
1430 bestval = mccormickval;
1433 if( useoverestineq )
1435 ineqs = nlhdlrexprdata->overineqs;
1436 nineqs = nlhdlrexprdata->noverineqs;
1440 ineqs = nlhdlrexprdata->underineqs;
1441 nineqs = nlhdlrexprdata->nunderineqs;
1447 refpointx, refpointy, ineqs, nineqs, mccormickval,
1448 &lincoefx, &lincoefy, &linconstant, &bestval,
1484 if( nlhdlrdata->useinteval && nlhdlrexprdata->nunderineqs + nlhdlrexprdata->noverineqs > 0 )
1487 nlhdlrexprdata->overineqs, nlhdlrexprdata->noverineqs);
1508 if( nlhdlrdata->usereverseprop && nlhdlrexprdata->nunderineqs + nlhdlrexprdata->noverineqs > 0 )
1525 nlhdlrexprdata->overineqs, nlhdlrexprdata->noverineqs, &intervalx, &intervaly);
1530 intervalx.
inf, intervalx.
sup);
1535 if( !(*infeasible) )
1540 intervaly.
inf, intervaly.
sup);
1542 infeasible, nreductions) );
1581 "whether to use the interval evaluation callback of the nlhdlr",
1585 "whether to use the reverse propagation callback of the nlhdlr",
1589 "maximum number of separation rounds in the root node",
1590 &nlhdlrdata->maxseparoundsroot,
FALSE, 10, 0, INT_MAX,
NULL,
NULL) );
1593 "maximum number of separation rounds in a local node",
1594 &nlhdlrdata->maxseparounds,
FALSE, 1, 0, INT_MAX,
NULL,
NULL) );
1597 "maximum depth to apply separation",
1598 &nlhdlrdata->maxsepadepth,
FALSE, INT_MAX, 0, INT_MAX,
NULL,
NULL) );
1624 return nlhdlrdata->exprs;
1641 return nlhdlrdata->nexprs;
1681 if( nlhdlrexprdata ==
NULL )
1684 "Skip SCIPaddConsExprExprProductBilinearIneq()\n");
1708 underestimate = xcoef * ycoef > 0;
1710 SCIPdebugMsg(
scip,
"add inequality for a bilinear term: %g %s <= %g %s + %g (underestimate=%u)\n", xcoef,
1723 ineqs = nlhdlrexprdata->underineqs;
1724 nineqs = nlhdlrexprdata->nunderineqs;
1728 ineqs = nlhdlrexprdata->overineqs;
1729 nineqs = nlhdlrexprdata->noverineqs;
1733 assert( 3 * nineqs <= 6 );
1736 for(
i = 0;
i < nineqs; ++
i )
1747 for(
i = 0;
i < nineqs; ++
i )
1752 getIneqViol(
x,
y, ineqs[3*
i], ineqs[3*
i+1], ineqs[3*
i+2], &ineqviol1, &ineqviol2);
1766 ineqs[3*
i+1] = ycoef;
1767 ineqs[3*
i+2] = constant;
1775 ineqs[3*nineqs] = xcoef;
1776 ineqs[3*nineqs + 1] = ycoef;
1777 ineqs[3*nineqs + 2] = constant;
1783 ++(nlhdlrexprdata->nunderineqs);
1785 ++(nlhdlrexprdata->noverineqs);
1821 if( bilincoef == 0.0 )
1834 constant = -bilincoef * refpointx * refpointy;
1843 *lincoefx += bilincoef * refpointy;
1844 *lincoefy += bilincoef * refpointx;
1845 *linconstant += constant;
1885 if( bilincoef == 0.0 )
1889 bilincoef = -bilincoef;
1909 if( bilincoef < 0.0 )
1910 constant = bilincoef *
MAX(
MAX(cand1, cand2),
MAX(cand3, cand4) );
1912 constant = bilincoef *
MIN(
MIN(cand1, cand2),
MIN(cand3, cand4) );
1914 else if( bilincoef > 0.0 )
1919 || (uby - refpointy) * (ubx - refpointx) >= (refpointy - lby) * (refpointx - lbx)) )
1925 coefy = bilincoef * lbx;
1926 constant = bilincoef * (lby < 0.0 ? (ubx-lbx) * lby : 0.0);
1931 coefx = bilincoef * lby;
1933 constant = bilincoef * (lbx < 0.0 ? (uby-lby) * lbx : 0.0);
1937 coefx = bilincoef * lby;
1938 coefy = bilincoef * lbx;
1939 constant = -bilincoef * lbx * lby;
1948 coefy = bilincoef * ubx;
1949 constant = bilincoef * (uby > 0.0 ? (lbx - ubx) * uby : 0.0);
1954 coefx = bilincoef * uby;
1956 constant = bilincoef * (ubx > 0.0 ? (lby - uby) * ubx : 0.0);
1960 coefx = bilincoef * uby;
1961 coefy = bilincoef * ubx;
1962 constant = -bilincoef * ubx * uby;
1976 || (ubx - lbx) * (refpointy - lby) <= (uby - lby) * (refpointx - lbx)) )
1982 coefy = bilincoef * ubx;
1983 constant = bilincoef * (lby < 0.0 ? (lbx - ubx) * lby : 0.0);
1988 coefx = bilincoef * lby;
1990 constant = bilincoef * (ubx > 0.0 ? (uby - lby) * ubx : 0.0);
1994 coefx = bilincoef * lby;
1995 coefy = bilincoef * ubx;
1996 constant = -bilincoef * ubx * lby;
2005 coefy = bilincoef * lbx;
2006 constant = bilincoef * (uby > 0.0 ? (ubx - lbx) * uby : 0.0);
2011 coefx = bilincoef * uby;
2013 constant = bilincoef * (lbx < 0.0 ? (lby - uby) * lbx : 0.0);
2017 coefx = bilincoef * uby;
2018 coefy = bilincoef * lbx;
2019 constant = -bilincoef * lbx * uby;
2040 constant = -constant;
2043 SCIPdebugMsg(
scip,
"%.15g * x[%.15g,%.15g] * y[%.15g,%.15g] %c= %.15g * x %+.15g * y %+.15g\n", bilincoef, lbx, ubx,
2044 lby, uby, overestimate ?
'<' :
'>', coefx, coefy, constant);
2048 *linconstant += constant;
2111 assert(xcoef == 0.0 || xcoef == -1.0 || xcoef == 1.0);
2121 if(
SCIPisFeasGT(
scip, xcoef * refpointx - ycoef * refpointy - constant, 0.0) )
2125 minx = lbx + 0.01 * (ubx-lbx);
2126 maxx = ubx - 0.01 * (ubx-lbx);
2127 miny = lby + 0.01 * (uby-lby);
2128 maxy = uby - 0.01 * (uby-lby);
2136 if( bilincoef < 0.0 )
2137 overestimate = !overestimate;
2160 for(
i = 0;
i < 2; ++
i )
2162 SCIP_Real activity = xcoef * xs[
i] - ycoef * ys[
i] - constant;
2255 *success =
SCIPisFeasEQ(
scip, (*lincoefx)*vx + (*lincoefy)*vy + (*linconstant), bilincoef*vx*vy)
2261 SCIP_Real activity = (*lincoefx)*refpointx + (*lincoefy)*refpointy + (*linconstant);
2264 if( bilincoef < 0.0 )
2265 overestimate = !overestimate;
2303 SCIP_Real mi, mj, qi, qj, xi, xj, yi, yj;
2335 if(
SCIPisFeasGT(
scip, xcoef1 * refpointx - ycoef1 * refpointy - constant1, 0.0)
2336 ||
SCIPisFeasGT(
scip, xcoef2 * refpointx - ycoef2 * refpointy - constant2, 0.0) )
2340 minx = lbx + 0.01 * (ubx-lbx);
2341 maxx = ubx - 0.01 * (ubx-lbx);
2342 miny = lby + 0.01 * (uby-lby);
2343 maxy = uby - 0.01 * (uby-lby);
2353 if( (xcoef1 > 0) == (xcoef2 > 0) )
2357 if( bilincoef < 0.0 )
2358 overestimate = !overestimate;
2361 mi = xcoef1 / ycoef1;
2362 qi = -constant1 / ycoef1;
2363 mj = xcoef2 / ycoef2;
2364 qj = -constant2 / ycoef2;
2371 computeBilinEnvelope2(
scip, refpointx, refpointy, mi, qi, mj, qj, &xi, &yi, &xj, &yj, &xcoef, &ycoef, &constant);
2385 *lincoefx = bilincoef * xcoef;
2386 *lincoefy = bilincoef * ycoef;
2387 *linconstant = bilincoef * constant;
2390 *success =
SCIPisFeasEQ(
scip, (*lincoefx)*xi + (*lincoefy)*yi + (*linconstant), bilincoef*xi*yi)
2391 &&
SCIPisFeasEQ(
scip, (*lincoefx)*xj + (*lincoefy)*yj + (*linconstant), bilincoef*xj*yj);
2395 SCIP_Real activity = (*lincoefx)*refpointx + (*lincoefy)*refpointy + (*linconstant);
2398 if( bilincoef < 0.0 )
2399 overestimate = !overestimate;
constraint handler for nonlinear constraints specified by algebraic expressions
#define SCIPquadprecDivQD(r, a, b)
#define SCIPquadprecDivQQ(r, a, b)
#define SCIPquadprecSqrtQ(r, a)
#define SCIPquadprecProdDD(r, a, b)
#define SCIPquadprecProdQD(r, a, b)
#define SCIPquadprecProdQQ(r, a, b)
#define SCIPquadprecSumQD(r, a, b)
#define SCIPquadprecSquareQ(r, a)
#define SCIPquadprecSumDD(r, a, b)
#define SCIPquadprecSumQQ(r, a, b)
#define SCIPquadprecDivDD(r, a, b)
#define SCIP_INTERVAL_INFINITY
#define SCIP_STRINGEQ(name, reference, retcode)
product expression handler
variable expression handler
SCIP_RETCODE SCIPmarkExprPropagateNonlinear(SCIP *scip, SCIP_EXPR *expr)
unsigned int SCIPgetExprNAuxvarUsesNonlinear(SCIP_EXPR *expr)
SCIP_VAR * SCIPgetExprAuxVarNonlinear(SCIP_EXPR *expr)
SCIP_EXPR * SCIPgetExprNonlinear(SCIP_CONS *cons)
SCIP_RETCODE SCIPtightenExprIntervalNonlinear(SCIP *scip, SCIP_EXPR *expr, SCIP_INTERVAL newbounds, SCIP_Bool *cutoff, int *ntightenings)
SCIP_RETCODE SCIPregisterExprUsageNonlinear(SCIP *scip, SCIP_EXPR *expr, SCIP_Bool useauxvar, SCIP_Bool useactivityforprop, SCIP_Bool useactivityforsepabelow, SCIP_Bool useactivityforsepaabove)
SCIP_INTERVAL SCIPgetExprBoundsNonlinear(SCIP *scip, SCIP_EXPR *expr)
SCIP_STAGE SCIPgetStage(SCIP *scip)
int SCIPgetNVars(SCIP *scip)
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
int SCIPhashmapGetImageInt(SCIP_HASHMAP *hashmap, void *origin)
int SCIPhashmapGetNElements(SCIP_HASHMAP *hashmap)
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
SCIP_RETCODE SCIPhashmapInsertInt(SCIP_HASHMAP *hashmap, void *origin, int image)
SCIP_RETCODE SCIPhashmapRemove(SCIP_HASHMAP *hashmap, void *origin)
SCIP_RETCODE SCIPhashmapSetImageInt(SCIP_HASHMAP *hashmap, void *origin, int image)
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
int SCIPgetNExprsBilinear(SCIP_NLHDLR *nlhdlr)
void SCIPcomputeBilinEnvelope2(SCIP *scip, SCIP_Real bilincoef, SCIP_Real lbx, SCIP_Real ubx, SCIP_Real refpointx, SCIP_Real lby, SCIP_Real uby, SCIP_Real refpointy, SCIP_Bool overestimate, SCIP_Real xcoef1, SCIP_Real ycoef1, SCIP_Real constant1, SCIP_Real xcoef2, SCIP_Real ycoef2, SCIP_Real constant2, SCIP_Real *RESTRICT lincoefx, SCIP_Real *RESTRICT lincoefy, SCIP_Real *RESTRICT linconstant, SCIP_Bool *RESTRICT success)
void SCIPaddBilinMcCormick(SCIP *scip, SCIP_Real bilincoef, SCIP_Real lbx, SCIP_Real ubx, SCIP_Real refpointx, SCIP_Real lby, SCIP_Real uby, SCIP_Real refpointy, SCIP_Bool overestimate, SCIP_Real *lincoefx, SCIP_Real *lincoefy, SCIP_Real *linconstant, SCIP_Bool *success)
void SCIPcomputeBilinEnvelope1(SCIP *scip, SCIP_Real bilincoef, SCIP_Real lbx, SCIP_Real ubx, SCIP_Real refpointx, SCIP_Real lby, SCIP_Real uby, SCIP_Real refpointy, SCIP_Bool overestimate, SCIP_Real xcoef, SCIP_Real ycoef, SCIP_Real constant, SCIP_Real *RESTRICT lincoefx, SCIP_Real *RESTRICT lincoefy, SCIP_Real *RESTRICT linconstant, SCIP_Bool *RESTRICT success)
SCIP_RETCODE SCIPaddIneqBilinear(SCIP *scip, SCIP_NLHDLR *nlhdlr, SCIP_EXPR *expr, SCIP_Real xcoef, SCIP_Real ycoef, SCIP_Real constant, SCIP_Bool *success)
void SCIPaddBilinLinearization(SCIP *scip, SCIP_Real bilincoef, SCIP_Real refpointx, SCIP_Real refpointy, SCIP_Real *lincoefx, SCIP_Real *lincoefy, SCIP_Real *linconstant, SCIP_Bool *success)
SCIP_EXPR ** SCIPgetExprsBilinear(SCIP_NLHDLR *nlhdlr)
SCIP_RETCODE SCIPincludeNlhdlrBilinear(SCIP *scip)
SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
int SCIPconshdlrGetNConss(SCIP_CONSHDLR *conshdlr)
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
SCIP_CONS ** SCIPconshdlrGetConss(SCIP_CONSHDLR *conshdlr)
SCIP_RETCODE SCIPinsertDatatreeInt(SCIP *scip, SCIP_DATATREE *datatree, const char *name, int value)
SCIP_RETCODE SCIPsetPtrarrayVal(SCIP *scip, SCIP_PTRARRAY *ptrarray, int idx, void *val)
int SCIPexprGetNChildren(SCIP_EXPR *expr)
SCIP_Bool SCIPisExprProduct(SCIP *scip, SCIP_EXPR *expr)
SCIP_Bool SCIPexpriterIsEnd(SCIP_EXPRITER *iterator)
SCIP_Real SCIPgetCoefExprProduct(SCIP_EXPR *expr)
SCIP_RETCODE SCIPreleaseExpr(SCIP *scip, SCIP_EXPR **expr)
SCIP_EXPR * SCIPexpriterGetCurrent(SCIP_EXPRITER *iterator)
SCIP_Bool SCIPisExprVar(SCIP *scip, SCIP_EXPR *expr)
SCIP_RETCODE SCIPcreateExpriter(SCIP *scip, SCIP_EXPRITER **iterator)
SCIP_RETCODE SCIPprintExpr(SCIP *scip, SCIP_EXPR *expr, FILE *file)
SCIP_EXPR * SCIPexpriterGetNext(SCIP_EXPRITER *iterator)
SCIP_EXPR ** SCIPexprGetChildren(SCIP_EXPR *expr)
SCIP_VAR * SCIPgetVarExprVar(SCIP_EXPR *expr)
SCIP_INTERVAL SCIPexprGetActivity(SCIP_EXPR *expr)
void SCIPfreeExpriter(SCIP_EXPRITER **iterator)
void SCIPcaptureExpr(SCIP_EXPR *expr)
SCIP_RETCODE SCIPexpriterInit(SCIP_EXPRITER *iterator, SCIP_EXPR *expr, SCIP_EXPRITER_TYPE type, SCIP_Bool allowrevisit)
SCIP_Real SCIPintervalGetInf(SCIP_INTERVAL interval)
void SCIPintervalSetEntire(SCIP_Real infinity, SCIP_INTERVAL *resultant)
void SCIPintervalSolveUnivariateQuadExpression(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL sqrcoeff, SCIP_INTERVAL lincoeff, SCIP_INTERVAL rhs, SCIP_INTERVAL xbnds)
void SCIPintervalIntersect(SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
void SCIPintervalSet(SCIP_INTERVAL *resultant, SCIP_Real value)
SCIP_Bool SCIPintervalIsEmpty(SCIP_Real infinity, SCIP_INTERVAL operand)
void SCIPintervalSetBounds(SCIP_INTERVAL *resultant, SCIP_Real inf, SCIP_Real sup)
struct SCIP_Interval SCIP_INTERVAL
void SCIPintervalMulScalar(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_Real operand2)
SCIP_Real SCIPintervalGetSup(SCIP_INTERVAL interval)
void SCIPintervalSetEmpty(SCIP_INTERVAL *resultant)
#define SCIPallocClearBlockMemory(scip, ptr)
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
int SCIPcalcMemGrowSize(SCIP *scip, int num)
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
#define SCIPfreeBlockMemory(scip, ptr)
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
#define SCIPfreeBlockMemoryNull(scip, ptr)
#define SCIPallocBlockMemory(scip, ptr)
void SCIPnlhdlrSetInitExit(SCIP_NLHDLR *nlhdlr, SCIP_DECL_NLHDLRINIT((*init)),)
SCIP_NLHDLRDATA * SCIPnlhdlrGetData(SCIP_NLHDLR *nlhdlr)
void SCIPnlhdlrSetFreeExprData(SCIP_NLHDLR *nlhdlr,)
SCIP_NLHDLREXPRDATA * SCIPgetNlhdlrExprDataNonlinear(SCIP_NLHDLR *nlhdlr, SCIP_EXPR *expr)
const char * SCIPnlhdlrGetName(SCIP_NLHDLR *nlhdlr)
SCIP_NLHDLR * SCIPfindNlhdlrNonlinear(SCIP_CONSHDLR *conshdlr, const char *name)
void SCIPnlhdlrSetSepa(SCIP_NLHDLR *nlhdlr, SCIP_DECL_NLHDLRINITSEPA((*initsepa)), SCIP_DECL_NLHDLRENFO((*enfo)), SCIP_DECL_NLHDLRESTIMATE((*estimate)),)
void SCIPnlhdlrSetFreeHdlrData(SCIP_NLHDLR *nlhdlr,)
void SCIPnlhdlrSetCopyHdlr(SCIP_NLHDLR *nlhdlr,)
SCIP_RETCODE SCIPincludeNlhdlrNonlinear(SCIP *scip, SCIP_NLHDLR **nlhdlr, const char *name, const char *desc, int detectpriority, int enfopriority, SCIP_DECL_NLHDLRDETECT((*detect)), SCIP_DECL_NLHDLREVALAUX((*evalaux)), SCIP_NLHDLRDATA *nlhdlrdata)
void SCIPnlhdlrSetProp(SCIP_NLHDLR *nlhdlr, SCIP_DECL_NLHDLRINTEVAL((*inteval)),)
SCIP_Longint SCIPnodeGetNumber(SCIP_NODE *node)
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
SCIP_TABLE * SCIPfindTable(SCIP *scip, const char *name)
SCIP_RETCODE SCIPincludeTable(SCIP *scip, const char *name, const char *desc, SCIP_Bool active, SCIP_DECL_TABLECOPY((*tablecopy)), SCIP_DECL_TABLEFREE((*tablefree)), SCIP_DECL_TABLEINIT((*tableinit)), SCIP_DECL_TABLEEXIT((*tableexit)), SCIP_DECL_TABLEINITSOL((*tableinitsol)), SCIP_DECL_TABLEEXITSOL((*tableexitsol)), SCIP_DECL_TABLEOUTPUT((*tableoutput)), SCIP_DECL_TABLECOLLECT((*tablecollect)), SCIP_TABLEDATA *tabledata, int position, SCIP_STAGE earlieststage)
SCIP_Bool SCIPisRelEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisRelLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisRelLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisRelGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisRelGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIPfeastol(SCIP *scip)
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisNegative(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPepsilon(SCIP *scip)
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
int SCIPgetDepth(SCIP *scip)
SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
const char * SCIPvarGetName(SCIP_VAR *var)
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
SCIP_RETCODE SCIPensureRowprepSize(SCIP *scip, SCIP_ROWPREP *rowprep, int size)
void SCIProwprepAddConstant(SCIP_ROWPREP *rowprep, SCIP_Real constant)
SCIP_RETCODE SCIPaddRowprepTerm(SCIP *scip, SCIP_ROWPREP *rowprep, SCIP_VAR *var, SCIP_Real coef)
SCIP_RETCODE SCIPcreateRowprep(SCIP *scip, SCIP_ROWPREP **rowprep, SCIP_SIDETYPE sidetype, SCIP_Bool local)
assert(minobj< SCIPgetCutoffbound(scip))
#define BMSclearMemory(ptr)
#define NLHDLR_DETECTPRIORITY
#define TABLE_DESC_BILINEAR
#define TABLE_EARLIEST_STAGE_BILINEAR
static void updateBilinearRelaxation(SCIP *scip, SCIP_VAR *RESTRICT x, SCIP_VAR *RESTRICT y, SCIP_Real bilincoef, SCIP_SIDETYPE violside, SCIP_Real refx, SCIP_Real refy, SCIP_Real *RESTRICT ineqs, int nineqs, SCIP_Real mccormickval, SCIP_Real *RESTRICT bestcoefx, SCIP_Real *RESTRICT bestcoefy, SCIP_Real *RESTRICT bestconst, SCIP_Real *RESTRICT bestval, SCIP_Bool *success)
#define NLHDLR_ENFOPRIORITY
static void reversePropBilinear(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_EXPR *expr, SCIP_INTERVAL exprbounds, SCIP_Real *underineqs, int nunderineqs, SCIP_Real *overineqs, int noverineqs, SCIP_INTERVAL *intervalx, SCIP_INTERVAL *intervaly)
#define TABLE_POSITION_BILINEAR
static void computeBilinEnvelope2(SCIP *scip, SCIP_Real x, SCIP_Real y, SCIP_Real mi, SCIP_Real qi, SCIP_Real mj, SCIP_Real qj, SCIP_Real *RESTRICT xi, SCIP_Real *RESTRICT yi, SCIP_Real *RESTRICT xj, SCIP_Real *RESTRICT yj, SCIP_Real *RESTRICT xcoef, SCIP_Real *RESTRICT ycoef, SCIP_Real *RESTRICT constant)
#define nlhdlrExitSepaBilinear
static SCIP_INTERVAL intevalBilinear(SCIP *scip, SCIP_EXPR *expr, SCIP_Real *underineqs, int nunderineqs, SCIP_Real *overineqs, int noverineqs)
#define nlhdlrInitBilinear
#define TABLE_NAME_BILINEAR
#define nlhdlrInitSepaBilinear
#define nlhdlrEnfoBilinear
static SCIP_Bool isPointFeasible(SCIP *scip, SCIP_Real x, SCIP_Real y, SCIP_Real lbx, SCIP_Real ubx, SCIP_Real lby, SCIP_Real uby, SCIP_Real *ineqs, int nineqs)
static SCIP_Bool useBilinIneqs(SCIP *scip, SCIP_VAR *x, SCIP_VAR *y, SCIP_Real refx, SCIP_Real refy)
static void getFeasiblePointsBilinear(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_EXPR *expr, SCIP_INTERVAL exprbounds, SCIP_Real *underineqs, int nunderineqs, SCIP_Real *overineqs, int noverineqs, SCIP_Bool levelset, SCIP_Real *xs, SCIP_Real *ys, int *npoints)
static void getIneqViol(SCIP_VAR *x, SCIP_VAR *y, SCIP_Real xcoef, SCIP_Real ycoef, SCIP_Real constant, SCIP_Real *viol1, SCIP_Real *viol2)
bilinear nonlinear handler
struct SCIP_Cons SCIP_CONS
struct SCIP_Conshdlr SCIP_CONSHDLR
struct SCIP_Expr SCIP_EXPR
struct SCIP_ExprIter SCIP_EXPRITER
enum SCIP_SideType SCIP_SIDETYPE
struct SCIP_RowPrep SCIP_ROWPREP
struct SCIP_HashMap SCIP_HASHMAP
#define SCIP_DECL_NLHDLREVALAUX(x)
#define SCIP_DECL_NLHDLRESTIMATE(x)
struct SCIP_NlhdlrData SCIP_NLHDLRDATA
#define SCIP_NLHDLR_METHOD_SEPABOTH
#define SCIP_DECL_NLHDLRCOPYHDLR(x)
#define SCIP_NLHDLR_METHOD_ACTIVITY
#define SCIP_DECL_NLHDLREXIT(x)
#define SCIP_DECL_NLHDLRFREEEXPRDATA(x)
#define SCIP_DECL_NLHDLRDETECT(x)
struct SCIP_Nlhdlr SCIP_NLHDLR
#define SCIP_DECL_NLHDLRFREEHDLRDATA(x)
struct SCIP_NlhdlrExprData SCIP_NLHDLREXPRDATA
#define SCIP_DECL_NLHDLRREVERSEPROP(x)
#define SCIP_DECL_NLHDLRINTEVAL(x)
enum SCIP_Retcode SCIP_RETCODE
#define SCIP_DECL_TABLEOUTPUT(x)
#define SCIP_DECL_TABLECOLLECT(x)