All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
sepa_cmir.c
Go to the documentation of this file.
22 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
37 #define SEPA_DELAY FALSE /**< should separation method be delayed, if other separators found cuts? */
39 #define DEFAULT_MAXROUNDS 3 /**< maximal number of cmir separation rounds per node (-1: unlimited) */
40 #define DEFAULT_MAXROUNDSROOT 10 /**< maximal number of cmir separation rounds in the root node (-1: unlimited) */
41 #define DEFAULT_MAXTRIES 100 /**< maximal number of rows to start aggregation with per separation round
43 #define DEFAULT_MAXTRIESROOT -1 /**< maximal number of rows to start aggregation with per round in the root node
45 #define DEFAULT_MAXFAILS 20 /**< maximal number of consecutive unsuccessful aggregation tries (-1: unlimited) */
46 #define DEFAULT_MAXFAILSROOT 100 /**< maximal number of consecutive unsuccessful aggregation tries in the root node
48 #define DEFAULT_MAXAGGRS 3 /**< maximal number of aggregations for each row per separation round */
49 #define DEFAULT_MAXAGGRSROOT 6 /**< maximal number of aggregations for each row per round in the root node */
50 #define DEFAULT_MAXSEPACUTS 100 /**< maximal number of cmir cuts separated per separation round */
51 #define DEFAULT_MAXSEPACUTSROOT 500 /**< maximal number of cmir cuts separated per separation round in root node */
53 #define DEFAULT_MAXSLACKROOT 0.1 /**< maximal slack of rows to be used in aggregation in the root node */
54 #define DEFAULT_DENSITYSCORE 1e-04 /**< weight of row density in the aggregation scoring of the rows */
58 #define DEFAULT_DENSITYOFFSET 100 /**< additional number of variables allowed in row on top of density */
60 #define DEFAULT_MAXTESTDELTA -1 /**< maximal number of different deltas to try (-1: unlimited) */
61 #define DEFAULT_MAXCONTS 10 /**< maximal number of active continuous variables in aggregated row */
62 #define DEFAULT_MAXCONTSROOT 10 /**< maximal number of active continuous variables in aggregated row in the root */
63 #define DEFAULT_AGGRTOL 0.1 /**< aggregation heuristic: tolerance for bound distances used to select real
66 #define DEFAULT_FIXINTEGRALRHS TRUE /**< should an additional variable be complemented if f0 = 0? */
67 #define DEFAULT_DYNAMICCUTS TRUE /**< should generated cuts be removed from the LP if they are no longer tight? */
96 int maxroundsroot; /**< maximal number of cmir separation rounds in the root node (-1: unlimited) */
99 int maxtriesroot; /**< maximal number of rows to start aggregation with per round in the root node
106 int maxaggrsroot; /**< maximal number of aggregations for each row per round in the root node */
108 int maxsepacutsroot; /**< maximal number of cmir cuts separated per separation round in root node */
112 int maxcontsroot; /**< maximal number of active continuous variables in aggregated row in the root */
115 SCIP_Bool dynamiccuts; /**< should generated cuts be removed from the LP if they are no longer tight? */
123 /** stores nonzero elements of dense coefficient vector as sparse vector, and calculates activity and norm */
226 (void) SCIPsnprintf(cutname, SCIP_MAXSTRLEN, "%s%d_%d", cutclassname, SCIPgetNLPs(scip), *ncuts);
238 /* try to scale the cut to integral values, but only if the scaling is small; otherwise keep the fractional cut */
254 SCIPdebugMessage(" -> found %s cut <%s>: act=%f, rhs=%f, norm=%f, eff=%f, rank=%d, min=%f, max=%f (range=%g)\n",
255 cutclassname, cutname, cutact, cutrhs, cutnorm, SCIPgetCutEfficacy(scip, sol, cut), SCIProwGetRank(cut),
284 SCIP_Real* bestcontlbs, /**< best lower (variable or standard) bounds of continuous variables */
285 SCIP_Real* bestcontubs, /**< best upper (variable or standard) bounds of continuous variables */
331 /** calculates the c-MIR cut for the given rowweights and delta value, and updates testeddeltas, bestdelta, and
341 SCIP_Real* mksetcoefs, /**< array to store mixed knapsack set coefficients: size nvars; or NULL */
342 SCIP_Bool* mksetcoefsvalid, /**< pointer to store whether mixed knapsack set coefficients are valid; or NULL */
346 SCIP_Real boundswitch, /**< fraction of domain up to which lower bound is used in transformation */
348 SCIP_Bool allowlocal, /**< should local information allowed to be used, resulting in a local cut? */
349 SCIP_Bool fixintegralrhs, /**< should complementation tried to be adjusted such that rhs gets fractional? */
351 SCIP_Real maxweightrange, /**< maximal valid range max(|weights|)/min(|weights|) of row weights */
385 SCIP_CALL( SCIPcalcMIR(scip, sol, boundswitch, usevbds, allowlocal, fixintegralrhs, NULL, NULL, maxmksetcoefs,
386 maxweightrange, minfrac, maxfrac, rowweights, NULL, delta, mksetcoefs, mksetcoefsvalid, cutcoefs, &cutrhs, &cutact,
390 delta, success, success ? cutact : 0.0, success ? cutrhs : 0.0, success ? cutact - cutrhs : 0.0);
417 /** Performs the cut generation heuristic of the c-MIR separation algorithm, i.e., tries to generate a c-MIR cut which is
418 * valid for the mixed knapsack set corresponding to the current aggregated constraint. Cuts will only be added here if
428 SCIP_Real boundswitch, /**< fraction of domain up to which lower bound is used in transformation */
430 SCIP_Bool allowlocal, /**< should local information allowed to be used, resulting in a local cut? */
431 SCIP_Bool fixintegralrhs, /**< should complementation tried to be adjusted such that rhs gets fractional? */
433 SCIP_Real maxweightrange, /**< maximal valid range max(|weights|)/min(|weights|) of row weights */
482 /* As in Marchand's version. Use the absolute value of the coefficients of the integer variables (lying
488 * delta = coefficient of integer variable in constructed mixed knapsack set which lies between its bounds
496 /* try delta = 1 and get the coefficients of all variables in the constructed mixed knapsack set;
497 * if the aggregated row contains too many nonzero elements the generation of the c-MIR cut is aborted,
498 * in this case, mksetcoefs is not valid and we can abort the separation heuristic (as the number of nonzeros
501 SCIP_CALL( tryDelta(scip, sol, nvars, rowweights, cutcoefs, mksetcoefs, &mksetcoefsvalid, testeddeltas, &ntesteddeltas,
502 1.0, boundswitch, usevbds, allowlocal, fixintegralrhs, maxmksetcoefs, maxweightrange, minfrac, maxfrac, &bestdelta,
506 SCIP_CALL( tryDelta(scip, sol, nvars, rowweights, cutcoefs, NULL, NULL, testeddeltas, &ntesteddeltas, -1.0,
507 boundswitch, usevbds, allowlocal, fixintegralrhs, maxmksetcoefs, maxweightrange, minfrac, maxfrac,
511 /* find mult in { +1, -1 } and delta in the corresponding set N* leading to the most violated c-MIR cut */
546 SCIP_CALL( tryDelta(scip, sol, nvars, rowweights, cutcoefs, NULL, NULL, testeddeltas, &ntesteddeltas,
547 1.0/absmksetcoef, boundswitch, usevbds, allowlocal, fixintegralrhs, maxmksetcoefs, maxweightrange, minfrac,
551 SCIP_CALL( tryDelta(scip, sol, nvars, rowweights, cutcoefs, NULL, NULL, testeddeltas, &ntesteddeltas,
552 -1.0/absmksetcoef, boundswitch, usevbds, allowlocal, fixintegralrhs, maxmksetcoefs, maxweightrange,
561 SCIP_CALL( tryDelta(scip, sol, nvars, rowweights, cutcoefs, NULL, NULL, testeddeltas, &ntesteddeltas,
562 1.0/(maxabsmksetcoef+1.0), boundswitch, usevbds, allowlocal, fixintegralrhs, maxmksetcoefs, maxweightrange,
566 SCIP_CALL( tryDelta(scip, sol, nvars, rowweights, cutcoefs, NULL, NULL, testeddeltas, &ntesteddeltas,
567 -1.0/(maxabsmksetcoef+1.0), boundswitch, usevbds, allowlocal, fixintegralrhs, maxmksetcoefs, maxweightrange,
588 SCIP_CALL( tryDelta(scip, sol, nvars, rowweights, cutcoefs, NULL, NULL, testeddeltas, &ntesteddeltas,
589 currentdelta, boundswitch, usevbds, allowlocal, fixintegralrhs, maxmksetcoefs, maxweightrange, minfrac,
593 /* if no pointer to store delta is given, add cut here (zerohalf cuts will be stored in a separate cut pool first) */
598 maxmksetcoefs, maxweightrange, minfrac, maxfrac, rowweights, NULL, bestdelta, NULL, NULL, cutcoefs,
604 SCIP_CALL( addCut(scip, sepa, sol, varsolvals, cutcoefs, cutrhs, cutislocal, cutremovable, cutrank, cutclassname, cutoff, ncuts) );
644 SCIP_Real* bestcontlbs, /**< best lower (variable or standard) bounds of continuous variables */
645 SCIP_Real* bestcontubs, /**< best upper (variable or standard) bounds of continuous variables */
676 /** aggregates different single mixed integer constraints by taking linear combinations of the rows of the LP */
684 SCIP_Real* bestcontlbs, /**< best lower (variable or standard) bounds of continuous variables */
685 SCIP_Real* bestcontubs, /**< best upper (variable or standard) bounds of continuous variables */
686 SCIP_Real* contvarscorebounds, /**< bounds on the maximal rowlhsscores and rowrhsscores the variable is contained in */
750 SCIPdebugMessage("start c-MIR aggregation with row <%s> (%d/%d)\n", SCIProwGetName(rows[startrow]), startrow, nrows);
796 updateNActiveConts(scip, varsolvals, bestcontlbs, bestcontubs, nintvars, var, +1, &nactiveconts);
800 SCIPsortedvecInsertDownRealInt(aggrcontnonzbounddists, aggrcontnonzposs, bounddist, pos, &naggrcontnonzs, NULL);
830 while( nactiveconts <= maxconts && naggrs <= maxaggrs && naggrcontnonzs + naggrintnonzs <= maxaggrnonzs )
848 SCIPdebugMessage("aggregation of startrow %d and %d additional rows with %d integer and %d continuous variables (%d active):\n",
863 SCIP_CALL( SCIPcutGenerationHeuristicCmir(scip, sepa, sol, varsolvals, sepadata->maxtestdelta, rowweights, BOUNDSWITCH,
864 USEVBDS, ALLOWLOCAL, sepadata->fixintegralrhs, (int) MAXAGGRLEN(nvars), sepadata->maxrowfac, MINFRAC, MAXFRAC,
884 SCIPdebugMessage(" -> abort aggregation: %s\n", nactiveconts == 0 ? "no more active continuous variables"
896 * - of those with large bound distance, prefer variables that can be eliminated with a row of high score
919 assert(SCIPisEQ(scip, bounddist, getBounddist(scip, nintvars, varsolvals, bestcontlbs, bestcontubs, var)));
964 SCIPdebugMessage(" -> r=%d row <%s>: weight=%g, pos=%d, alpha_j=%g, a^r_j=%g, factor=%g, %g <= %g <= %g\n",
1013 SCIPvarGetName(SCIPcolGetVar(bestcol)), aggrfac, SCIProwGetName(bestrow), bestbounddist, score);
1048 bestcontubs[SCIPvarGetProbindex(var) - nintvars], varsolvals[SCIPvarGetProbindex(var)], bounddist);
1050 assert(SCIPisEQ(scip, bounddist, getBounddist(scip, nintvars, varsolvals, bestcontlbs, bestcontubs, var)));
1111 updateNActiveConts(scip, varsolvals, bestcontlbs, bestcontubs, nintvars, var, -1, &nactiveconts);
1128 SCIPsortedvecInsertDownRealInt(aggrcontnonzbounddists, aggrcontnonzposs, bounddist, pos, &naggrcontnonzs, NULL);
1130 updateNActiveConts(scip, varsolvals, bestcontlbs, bestcontubs, nintvars, var, +1, &nactiveconts);
1163 SCIPdebugMessage(" -> %d continuous variables left (%d/%d active), %d/%d nonzeros, %d/%d aggregations\n",
1164 naggrcontnonzs, nactiveconts, maxconts, naggrcontnonzs + naggrintnonzs, maxaggrnonzs, naggrs, maxaggrs);
1169 SCIPdebugMessage(" -> abort aggregation: %d/%d active continuous variables\n", nactiveconts, maxconts);
1173 SCIPdebugMessage(" -> abort aggregation: %d/%d nonzeros\n", naggrcontnonzs + naggrintnonzs, maxaggrnonzs);
1334 /* calculate aggregation scores for both sides of all rows, and sort rows by nonincreasing maximal score */
1405 SCIPdebugMessage(" -> row %d <%s>: lhsscore=%g rhsscore=%g maxscore=%g\n", r, SCIProwGetName(rows[r]),
1416 maxfails += maxfails - 2*SCIPgetNSepaRounds(scip); /* allow up to double as many fails in early separounds of root node */
1419 for( r = 0; r < nrows && ntries < maxtries && ncuts < maxsepacuts && rowscores[roworder[r]] > 0.0
1426 SCIP_CALL( aggregation(scip, sepa, sepadata, sol, varsolvals, bestcontlbs, bestcontubs, contvarscorebounds,
1427 rowlhsscores, rowrhsscores, roworder[r], maxaggrs, maxslack, maxconts, &wastried, &cutoff, &ncuts) );
1554 SCIP_CALL( SCIPincludeSepaBasic(scip, &sepa, SEPA_NAME, SEPA_DESC, SEPA_PRIORITY, SEPA_FREQ, SEPA_MAXBOUNDDIST,
1580 "maximal number of rows to start aggregation with per separation round in the root node (-1: unlimited)",
1588 "maximal number of consecutive unsuccessful aggregation tries in the root node (-1: unlimited)",
|