All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
heur_shiftandpropagate.c
Go to the documentation of this file.
22 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
29 #define HEUR_DESC "Pre-root heuristic to expand an auxiliary branch-and-bound tree and apply propagation techniques"
42 #define DEFAULT_ONLYWITHOUTSOL TRUE /**< Should heuristic only be executed if no primal solution was found, yet? */
43 #define DEFAULT_NPROPROUNDS 10 /**< The default number of propagation rounds for each propagation used */
45 #define DEFAULT_CUTOFFBREAKER 15 /**< fixed maximum number of allowed cutoffs before the heuristic stops */
49 #define DEFAULT_COLLECTSTATS TRUE /**< should variable statistics be collected during probing? */
50 #define DEFAULT_STOPAFTERFEASIBLE TRUE /**< Should the heuristic stop calculating optimal shift values when no more rows are violated? */
52 #define SORTKEYS "nrtuv"/**< options sorting key: (n)orms down, norms (u)p, (v)iolated rows decreasing,
54 #define DEFAULT_NOZEROFIXING FALSE /**< should variables with a zero shifting value be delayed instead of being fixed? */
55 #define DEFAULT_FIXBINLOCKS TRUE /**< should binary variables with no locks in one direction be fixed to that direction? */
56 #define DEFAULT_NORMALIZE TRUE /**< should coefficients and left/right hand sides be normalized by max row coeff? */
57 #define DEFAULT_UPDATEWEIGHTS FALSE /**< should row weight be increased every time the row is violated? */
58 #define DEFAULT_IMPLISCONTINUOUS TRUE /**< should implicit integer variables be treated as continuous variables? */
74 SCIP_Bool onlywithoutsol; /**< Should heuristic only be executed if no primal solution was found, yet? */
77 int cutoffbreaker; /**< the number of cutoffs before heuristic execution is stopped, or -1 for no
85 SCIP_Bool stopafterfeasible; /**< Should the heuristic stop calculating optimal shift values when no
88 SCIP_Bool nozerofixing; /**< should variables with a zero shifting value be delayed instead of being fixed? */
89 SCIP_Bool fixbinlocks; /**< should binary variables with no locks in one direction be fixed to that direction? */
90 SCIP_Bool normalize; /**< should coefficients and left/right hand sides be normalized by max row coeff? */
92 SCIP_Bool impliscontinuous; /**< should implicit integer variables be treated as continuous variables? */
123 TRANSFORMSTATUS* transformstatus; /**< information about transform status of every discrete variable */
127 SCIP_Real* upperbounds; /**< the upper bounds of every non-continuous variable after transformation*/
128 SCIP_Real* transformshiftvals; /**< values by which original discrete variable bounds were shifted */
154 /** returns whether a given variable is counted as discrete, depending on the parameter impliscontinuous */
161 return SCIPvarIsIntegral(var) && (SCIPvarGetType(var) != SCIP_VARTYPE_IMPLINT || !impliscontinuous);
164 /** returns whether a given column is counted as discrete, depending on the parameter impliscontinuous */
171 return SCIPcolIsIntegral(col) && (!impliscontinuous || SCIPvarGetType(SCIPcolGetVar(col)) != SCIP_VARTYPE_IMPLINT);
377 /* if both lower and upper bound are -infinity and infinity, resp., this is reflected by a free transform status.
378 * If the lower bound is already zero, this is reflected by identity transform status. In both cases, none of the
407 /* determine the upper bound for this variable in heuristic transformation (lower bound is implicit; always 0) */
448 SCIPdebugMessage("Variable <%s> at colpos %d transformed. LB <%g> --> <%g>, UB <%g> --> <%g>\n",
452 /** initializes copy of the original coefficient matrix and applies heuristic specific adjustments: normalizing row
453 * vectors, transforming variable domains such that lower bound is zero, and relaxing continuous variables.
562 SCIPdebugMessage(" %s : lhs=%g, rhs=%g, maxval=%g \n", SCIProwGetName(row), matrix->lhs[i], matrix->rhs[i], maxval);
568 /* modify the lhs and rhs w.r.t to the rows constant and normalize by 1-norm, i.e divide the lhs and rhs by the
582 * Maxval may be zero if the constraint contains no variables but is modifiable, hence not redundant
593 /* in case of empty rows with a 0 < lhs <= 0.0 or 0.0 <= rhs < 0 we deduce the infeasibility of the problem */
594 if( nrowlpnonz == 0 && (SCIPisFeasPositive(scip, matrix->lhs[i]) || SCIPisFeasNegative(scip, matrix->rhs[i])) )
649 /* loop over all rows with nonzero coefficients in the column, transform them and add them to the heuristic matrix */
701 SCIPdebugMessage("Matrix initialized for %d discrete variables with %d cols, %d rows and %d nonzero entries\n",
819 assert((violatedrowpos[i] == -1 && SCIPisFeasGE(scip, rhs[i], 0.0) && SCIPisFeasGE(scip, -lhs[i], 0.0))
820 || (violatedrowpos[i] >= 0 &&(SCIPisFeasLT(scip, rhs[i], 0.0) || SCIPisFeasLT(scip, -lhs[i], 0.0))));
845 /* check if original variable has different bounds and transform solution value correspondingly */
861 * @todo if there is already an incumbent solution, try considering the objective cutoff as additional constraint */
924 /* for a feasible row, determine the minimum integer value within the bounds of the variable by which it has to be
934 * i.e. a positive coefficient for a "<="-constraint, a negative coefficient for a ">="-constraint.
941 /* if the variable has no lock in the current row, it can still help to increase the slack of this row;
949 /* check if the least violating shift lies within variable bounds and set corresponding array values */
962 /* for a violated row, determine the minimum integral value within the bounds of the variable by which it has to be
971 /* if coefficient has the right sign to make row feasible, determine the minimum integer to shift variable
979 /* check if the minimum feasibility recovery shift lies within variable bounds and set corresponding array
996 /* in case that the variable cannot affect the feasibility of any row, in particular it cannot violate
1012 /* best shifting step is calculated by summing up the violation changes for each relevant step and
1013 * taking the one which leads to the minimum sum. This sum measures the balance of feasibility recovering and
1015 * note, the sums for smaller steps have to be taken into account for all bigger steps, i.e., the sums can be
1022 /* if we reached the last entry for the current step value, we have finished computing its sum and
1056 if( SCIPisFeasLT(scip, -(matrix->lhs[rowindex]), 0.0) || SCIPisFeasLT(scip, matrix->rhs[rowindex], 0.0) )
1086 /** updates transformation of a given variable by taking into account current local bounds. if the bounds have changed
1087 * since last update, updating the heuristic specific upper bound of the variable, its current transformed solution value
1096 SCIP_Real* transformshiftval, /**< value, by which the variable has been shifted during transformation */
1164 assert(SCIPisFeasLE(scip, ABS(lb), ABS(ub)) || matrix->transformstatus[varindex] == TRANSFORMSTATUS_NEG);
1168 /* if the bound, by which the variable was shifted, has changed, deltashift is different from zero, which requires
1181 /* go through rows, update the rows w.r.t. the influence of the changed transformation of the variable */
1207 updateViolations(scip, matrix, rows[i], violatedrows, violatedrowpos, nviolatedrows, heurdata->rowweights, heurdata->updateweights);
1304 " SHIFTANDPROPAGATE PROBING : %d probings, %lld domain reductions, ncutoffs: %d , LP iterations: %lld \n ",
1314 /** initialization method of primal heuristic(called after problem was transformed). We only need this method for
1486 /* we have to collect the number of different variable types before we start probing since during probing variable
1528 SCIP_CALL( initMatrix(scip, matrix, heurdata, heurdata->normalize, &nmaxrows, heurdata->relax, &initialized, &infeasible) );
1537 /* the number of discrete LP column variables can be less than the actual number of variables, if, e.g., there
1542 SCIPdebugMessage(" Not all discrete variables are in the current LP. Shiftandpropagate execution terminated\n");
1601 checkViolations(scip, matrix, violatedrows, violatedrowpos, &nviolatedrows, &nredundantrows, violatedvarrows);
1604 /* sort variables w.r.t. the sorting key parameter. Sorting is indirect, all matrix column data
1673 SCIPdebugMessage("Variables sorted (upwards) w.r.t their number of currently infeasible rows!\n");
1682 SCIPpermuteIntArray(&permutation[nbinvars], nbinvars - 1, ndiscvars - nbinvars - 1, &heurdata->randseed);
1713 SCIP_CALL( SCIPcatchVarEvent(scip, var, SCIP_EVENTTYPE_BOUNDCHANGED, eventhdlr, eventdatas[c], NULL) );
1721 SCIPdebugMessage("SHIFT_AND_PROPAGATE heuristic starts main loop with %d violations and %d remaining variables!\n",
1726 /* loop over variables, shift them according to shifting criteria and try to reduce the global infeasibility */
1759 updateTransformation(scip, matrix, heurdata, permutedvarindex, &(matrix->transformshiftvals[permutedvarindex]),
1780 /* check whether the variable is binary and has no locks in one direction, so that we want to fix it to the
1783 if( heurdata->fixbinlocks && SCIPvarIsBinary(var) && (SCIPvarGetNLocksUp(var) == 0 || SCIPvarGetNLocksDown(var) == 0) )
1795 /* only apply the computationally expensive best shift selection, if there is a violated row left */
1799 SCIP_CALL( getOptimalShiftingValue(scip, matrix, permutedvarindex, 1, heurdata->rowweights, steps, violationchange,
1811 SCIP_CALL( getOptimalShiftingValue(scip, matrix, permutedvarindex, -1, heurdata->rowweights, steps, violationchange,
1826 /* if zero optimal shift values are forbidden by the user parameter, delay the variable by marking it suspicious */
1840 /* if propagation is enabled, fix the variable to the new solution value and propagate the fixation
1849 SCIPdebugMessage(" Shift %g(%g originally) is optimal, propagate solution\n", optimalshiftvalue, origsolval);
1854 SCIPdebugMessage("Propagation finished! <%lld> domain reductions %s, <%d> probing depth\n", ndomredsfound, cutoff ? "CUTOFF" : "",
1877 /* if the variable were to be set to one of its bounds, repropagate by tightening this bound by 1.0
1890 /* if the tightened bound again leads to a cutoff, both subproblems are proven infeasible and the heuristic
1907 /* if the tightened bound again leads to a cutoff, both subproblems are proven infeasible and the heuristic
1925 SCIPdebugMessage(" Suspicious variable! Postponed from pos <%d> to position <%d>\n", c, lastindexofsusp);
1942 SCIPdebugMessage("Heuristic finished with %d remaining violations and %d remaining variables!\n",
1945 /* if constructed solution might be feasible, go through the queue of suspicious variables and set the solution
1963 /* update the transformation of the variable, since the bound might have changed after the last update. */
1965 updateTransformation(scip, matrix, heurdata, permutedvarindex, &(matrix->transformshiftvals[permutedvarindex]),
1968 /* retransform the solution value from the heuristic transformed space, set the solution value accordingly */
1974 SCIP_CALL( SCIPfixVarProbing(scip, var, origsolval) ); /* only to ensure that some assertions can be made later */
1976 SCIPdebugMessage(" Remaining variable <%s> set to <%g>; %d Violations\n", SCIPvarGetName(var), origsolval,
2008 SCIPdebugMessage(" -> old LP iterations: %"SCIP_LONGINT_FORMAT"\n", SCIPgetNLPIterations(scip));
2011 * errors in the LP solver should not kill the overall solving process, if the LP is just needed for a heuristic.
2012 * hence in optimized mode, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
2020 SCIPwarningMessage(scip, "Error while solving LP in SHIFTANDPROPAGATE heuristic; LP solve terminated with code <%d>\n",
2028 SCIPdebugMessage(" -> new LP iterations: %"SCIP_LONGINT_FORMAT"\n", SCIPgetNLPIterations(scip));
2051 /* @todo: maybe bounds don't need to be checked, in this case put an assert concerning stored ?????????? */
2059 SCIPstatisticMessage(" Shiftandpropagate solution value: %16.9g \n", SCIPgetSolOrigObj(scip, sol));
2083 SCIP_CALL( SCIPdropVarEvent(scip, var, SCIP_EVENTTYPE_BOUNDCHANGED, eventhdlr, eventdatas[c], -1) );
2158 updateTransformation(scip, matrix, eventhdlrdata->heurdata, colpos, &(matrix->transformshiftvals[colpos]),
2159 lb, ub, eventhdlrdata->violatedrows, eventhdlrdata->violatedrowpos, eventhdlrdata->nviolatedrows);
2208 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/"HEUR_NAME"/nproprounds", "The number of propagation rounds used for each propagation",
2210 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/shiftandpropagate/relax", "Should continuous variables be relaxed?",
2212 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/shiftandpropagate/probing", "Should domains be reduced by probing?",
2214 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/shiftandpropagate/onlywithoutsol", "Should heuristic only be executed if no primal solution was found, yet?",
2216 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/"HEUR_NAME"/cutoffbreaker", "The number of cutoffs before heuristic stops",
2218 SCIP_CALL( SCIPaddCharParam(scip, "heuristics/"HEUR_NAME"/sortkey", "the key for variable sorting: (n)orms down, norms (u)p, (v)iolations down, viola(t)ions up, or (r)andom",
2220 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/shiftandpropagate/sortvars", "Should variables be sorted for the heuristic?",
2222 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/"HEUR_NAME"/collectstats", "should variable statistics be collected during probing?",
2224 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/shiftandpropagate/stopafterfeasible", "Should the heuristic stop calculating optimal shift values when no more rows are violated?",
2226 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/shiftandpropagate/preferbinaries", "Should binary variables be shifted first?",
2228 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/shiftandpropagate/nozerofixing", "should variables with a zero shifting value be delayed instead of being fixed?",
2230 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/shiftandpropagate/fixbinlocks", "should binary variables with no locks in one direction be fixed to that direction?",
2232 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/shiftandpropagate/normalize", "should coefficients and left/right hand sides be normalized by max row coeff?",
2234 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/shiftandpropagate/updateweights", "should row weight be increased every time the row is violated?",
2236 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/shiftandpropagate/impliscontinuous", "should implicit integer variables be treated as continuous variables?",
|