All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
heur_zirounding.c
Go to the documentation of this file.
21 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
30 #define HEUR_DESC "LP rounding heuristic as suggested by C. Wallace taking row slacks and bounds into account"
39 #define DEFAULT_MAXROUNDINGLOOPS 2 /**< delimits the number of main loops, can be set to -1 for no limit */
41 #define DEFAULT_STOPPERCENTAGE 0.02 /**< the tolerance percentage after which zirounding will not be executed anymore */
94 /* allocate memory if heuristic data arrays are NULL pointers, or extend them in case of a low capacity */
112 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &heurdata->slackvars, heurdata->nmemrows, nlprows) );
113 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &heurdata->upslacks, heurdata->nmemrows, nlprows) );
114 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &heurdata->downslacks, heurdata->nmemrows, nlprows) );
115 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &heurdata->slackvarcoeffs, heurdata->nmemrows, nlprows) );
116 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &heurdata->rowneedsslackvar, heurdata->nmemrows, nlprows) );
117 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &heurdata->activities, heurdata->nmemrows, nlprows) );
124 /** returns the fractionality of a value x, which is calculated as zivalue(x) = min(x-floor(x), ceil(x)-x) */
148 SCIP_Real* upperbound, /**< pointer to store the calculated upper bound on the variable shift */
149 SCIP_Real* lowerbound, /**< pointer to store the calculated lower bound on the variable shift */
150 SCIP_Real* upslacks, /**< array that contains the slacks between row activities and the right hand sides of the rows */
182 /* initialize the bounds on the shift to be the gap of the current solution value to the bounds of the variable */
193 /* go through every nonzero row coefficient corresponding to var to determine bounds for shifting
196 * if one of these values is significantly < 0.0, this will cause the abort of execution of the heuristic so that
213 /* all bounds and slacks as they are calculated in zirounding always have to be greater equal zero.
214 * It might however be due to numerical issues, e.g. with scaling, that they are not. Better abort in this case.
223 SCIPdebugMessage("colval: %15.8f, downslack: %15.8f, upslack: %5.2f, lb: %5.2f, ub: %5.2f\n", colvals[i], downslacks[rowpos], upslacks[rowpos],
226 /* if coefficient > 0, rounding up might violate up slack and rounding down might violate down slack
234 upslack = MAX(upslacks[rowpos], 0.0); /* avoid errors due to numerically slightly infeasible rows */
241 downslack = MAX(downslacks[rowpos], 0.0); /* avoid errors due to numerically slightly infeasible rows */
252 upslack = MAX(upslacks[rowpos], 0.0); /* avoid errors due to numerically slightly infeasible rows */
259 downslack = MAX(downslacks[rowpos], 0.0); /* avoid errors due to numerically slightly infeasible rows */
266 /** when a variable is shifted, the activities and slacks of all rows it appears in have to be updated */
330 assert(SCIPisFeasGE(scip, slackvarsolval + slackvarshiftval, SCIPvarGetLbGlobal(slackvars[rowpos])));
331 assert(SCIPisFeasLE(scip, slackvarsolval + slackvarshiftval, SCIPvarGetUbGlobal(slackvars[rowpos])));
335 else if( !SCIPisInfinity(scip, -activities[rowpos]) && !SCIPisInfinity(scip, activities[rowpos]) )
376 /* iterate over the row variables. Stop after the first unfixed continuous variable was found. */
391 SCIPdebugMessage(" slack variable for row %s found: %s\n", SCIProwGetName(row), SCIPvarGetName(colvar));
482 assert( heurdata->nmemrows == 0 || (heurdata->slackvars != NULL && heurdata-> activities != NULL) );
507 /** solving process initialization method of primal heuristic (called when branch and bound process is about to begin) */
578 /* Do not call heuristic if deactivation check is enabled and percentage of found solutions in relation
592 SCIP_CALL( SCIPgetLPBranchCands(scip, &lpcands, &lpcandssol, NULL, &nlpcands, NULL, &nimplfracs) );
644 /* loop over fractional variables and involved LP rows to find all rows which require a slack variable */
672 SCIPdebugMessage(" Row %s needs slack variable for variable %s\n", SCIProwGetName(candrows[r]), SCIPvarGetName(cand));
677 /* calculate row slacks for every every row that belongs to the current LP and ensure, that the current solution
678 * has no violated constraint -- if any constraint is violated, i.e. a slack is significantly smaller than zero,
679 * this will cause the termination of the heuristic because Zirounding does not provide feasibility recovering
709 SCIPdebugMessage("lhs:%5.2f <= act:%5.2f <= rhs:%5.2f --> down: %5.2f, up:%5.2f\n", lhs, activities[i], rhs, downslacks[i], upslacks[i]);
722 SCIPdebugMessage("No slack variable found for equation %s, terminating ZI Round heuristic\n", SCIProwGetName(row));
772 SCIPdebugMessage(" Slack variable for row %s at pos %d: %g <= %s = %g <= %g; Coeff %g, upslack = %g, downslack = %g \n",
773 SCIProwGetName(row), SCIProwGetLPPos(row), lbslackvar, SCIPvarGetName(slackvars[i]), solvalslackvar, ubslackvar, coeffslackvar,
791 while( currentlpcands > 0 && improvementfound && (heurdata->maxroundingloops == -1 || nroundings < heurdata->maxroundingloops) )
795 SCIPdebugMessage("zirounding enters while loop for %d time with %d candidates left. \n", nroundings, currentlpcands);
797 /* check for every remaining fractional variable if a shifting decreases ZI-value of the variable */
823 calculateBounds(scip, var, oldsolval, &upperbound, &lowerbound, upslacks, downslacks, nslacks, &numericalerror);
832 /* if the variable is integer or implicit binary, do not shift further than the nearest integer */
874 /* since at least one improvement has been found, heuristic will enter main loop for another time because the improvement
875 * might affect many LP rows and their current slacks and thus make further rounding steps possible */
880 * variable is put at the end of remaining candidates array so as not to be considered in future loops
958 "flag to determine if Zirounding is deactivated after a certain percentage of unsuccessful calls",
|