presol_implint.c
Go to the documentation of this file.
31/* TODO: support more constraint types: cons_nonlinear, cons_indicator and symmetry constraints */
32/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
74 * as otherwise certain reductions may break. So it is currently not safe to run implied integrality detection
76#define PRESOL_PRIORITY -900000 /**< priority of the presolver (>= 0: before, < 0: after constraint handlers); combined with propagators */
77#define PRESOL_MAXROUNDS 0 /**< maximal number of presolving rounds the presolver participates in (-1: no limit) */
78#define PRESOL_TIMING SCIP_PRESOLTIMING_EXHAUSTIVE /* timing of the presolver (fast, medium, or exhaustive) */
80#define DEFAULT_CONVERTINTEGERS FALSE /**< should implied integrality also be detected for enforced integral variables? */
81#define DEFAULT_COLUMNROWRATIO 50.0 /**< use the network row addition algorithm when the column to row ratio becomes larger than this threshold */
82#define DEFAULT_NUMERICSLIMIT 1e8 /**< a row that contains variables with coefficients that are greater in absolute value than this limit is not considered for implied integrality detection */
88 SCIP_Bool convertintegers; /**< should implied integrality also be detected for enforced integral variables? */
89 SCIP_Real columnrowratio; /**< use the network row addition algorithm when the column to row ratio
91 SCIP_Real numericslimit; /**< a row that contains variables with coefficients that are greater in
135/** struct that contains information about the blocks/components of the submatrix given by the continuous columns */
155 SCIP_Bool* rowintegral; /**< Are all row entries of non-continuous columns and the row sides integral? */
157 SCIP_Bool* rowbadnumerics; /**< Does the row contain large entries that make numerics difficult? */
165/** struct that contains some information for each integer variable that is a candidate for implied integrality detection */
170 int numContNetworkEntries; /**< The number of nonzeros that have a row in a pure network component */
171 int numContTransNetworkEntries; /**< The number of nonzeroes that have a row in a pure transposed network component */
393/** transforms given variables, scalars and constant to the corresponding active variables, scalars and constant */
413 SCIP_CALL( SCIPgetProbvarLinearSum(scip, *vars, *scalars, nvars, *nvars, constant, &requiredsize) );
421 SCIP_CALL( SCIPgetProbvarLinearSum(scip, *vars, *scalars, nvars, requiredsize, constant, &requiredsize) );
476/** transforms the weighted sum to active variables and then adds the given linear constraint to the matrix */
550/** adds the linearization of a given AND constraint or OR constraint to the constraint matrix */
677 SCIP_CALL( addLinearConstraint(scip, matrix, operands, vals, noperands, -SCIPinfinity(scip), rhs, cons) );
683 SCIP_CALL( addLinearConstraint(scip, matrix, operands, vals, noperands, -SCIPinfinity(scip), 2.0 - rhs * noperands, cons) );
694 /* long XOR constraints are represented nonlinearly, so the relevant active variables are marked non-linear */
704 /* we can transform all variables together in the sum because the constraint can be interpreted as a nonlinear
705 * constraint of the form sum(operands) % 2 = rhs. Thus, it is okay if we have cancellations in the sum.
802/* @todo: skip construction of integral constraints if we do not run detection on integer variables */
834 /* loop over all constraint handlers and collect the number of checked constraints that contribute rows
856 /* the linearization of AND constraints is modelled using n + 1 inequalities on n + 1 variables */
868 /* the linearization of OR constraints is modelled using n + 1 inequalities on n + 1 variables */
880 /* the relaxation of XOR constraints is handled differently depending on the integer variable and size:
882 * without integer variable and three variables, the convex hull of the constraint is added with four rows;
883 * otherwise, the constraint is considered nonlinear because the convex hull representation is exponential
900 /* @todo: support symmetry, linking, sos1, sos2, bounddisjunction, nonlinear, indicator, superindicator conshdlrs */
913 * this counts nonzeros in equalities twice, but can be at most two times as high as the exact number
916 nnonzstmp += SCIPvarGetNLocksDownType(vars[i], SCIP_LOCKTYPE_MODEL) + SCIPvarGetNLocksUpType(vars[i], SCIP_LOCKTYPE_MODEL);
986 SCIP_CALL( addLinearConstraint(scip, matrix, SCIPgetVarsLinear(scip, cons), SCIPgetValsLinear(scip, cons),
987 SCIPgetNVarsLinear(scip, cons), SCIPgetLhsLinear(scip, cons), SCIPgetRhsLinear(scip, cons), cons) );
1017 SCIP_CALL( addLinearConstraint(scip, matrix, SCIPgetVarsKnapsack(scip, cons), consvals, nrowvars,
1107 SCIP_CALL( addLinearConstraint(scip, matrix, consvars, consvals, 2, SCIPgetLhsVarbound(scip, cons),
1161 SCIP_CALL( addXorLinearization(scip, matrix, cons, SCIPgetVarsXor(scip, cons), SCIPgetNVarsXor(scip, cons),
1257 MATRIX_COMPONENTS** pmatrixcomponents /**< Pointer to create the matrix components data structure */
1297 MATRIX_COMPONENTS** pmatrixcomponents /**< Pointer to the allocated matrix components data structure */
1345 * The provided elements to be merged must be representative (i.e. returned by disjointSetFind()).
1360 * The rank is an upper bound on the height of the tree. We want the new root to be the one with 'largest' rank,
1361 * so smallest number. This way, we ensure that the tree remains shallow. If they are equal, we decrement.
1384 MATRIX_COMPONENTS* comp, /**< the connected components data structure to store the components in */
1396 /* let columns and rows share an index by mapping row index i to artificial column index i + nmatrixcols */
1403 if( matrixColIsIntegral(matrix, col) && ( !includeimplints || !matrixColIsImpliedIntegral(matrix, col) ) )
1422 SCIP_CALL( SCIPallocBufferArray(scip, &representativecomponent, comp->nmatrixcols + comp->nmatrixrows) );
1430 if( matrixColIsIntegral(matrix,col) && ( !includeimplints || !matrixColIsImpliedIntegral(matrix, col) ) )
1570 stats->rowequality[i] = !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && SCIPisEQ(scip, lhs, rhs);
1644 * Given the continuous components and statistics on the matrix, each component is checked if the associated matrix
1645 * describes either a network or a transposed network (or both, in which case it is represented by a planar graph) and
1647 * We choose to check if it is a (transposed) network matrix either in a row-wise or in a column-wise fashion,
1648 * depending on the size of the component. Finally, every variable that is in a network matrix or transposed network
1668 SCIP_Bool runintdetection = presoldata->convertintegers && SCIPgetNBinVars(scip) + SCIPgetNIntVars(scip) >= 1;
1677 * For example, make sure that there exist some +-1 candidate columns exist before performing these allocations.
1679 SCIP_CALL( SCIPnetmatdecCreate(SCIPblkmem(scip), &dec, comp->nmatrixrows, comp->nmatrixcols) );
1680 SCIP_CALL( SCIPnetmatdecCreate(SCIPblkmem(scip), &transdec, comp->nmatrixcols, comp->nmatrixrows) );
1682 /* Because the rows may also contain non-continuous columns, we need to remove these from the array that we
1683 * pass to the network matrix decomposition method. We use these working arrays for this purpose.
1700 if( stats->rowncontinuous[row] != stats->rowncontinuouspmone[row] || !stats->rowintegral[row] || stats->rowbadnumerics[row] )
1738 /* We use the row-wise algorithm only if the number of columns is much larger than the number of rows.
1739 * Generally, the column-wise algorithm will be faster, but in these extreme cases, the row algorithm is faster.
1765 SCIP_CALL( SCIPnetmatdecTryAddRow(dec, row, tempIdxArray, tempValArray, contnnonzs, &componentnetwork) );
1782 SCIPnetmatdecRemoveComponent(dec, &comp->componentrows[startrow], nrows, &comp->componentcols[startcol], ncols);
1786 /* we don't need to check if component is both network and transposed network in case we do not want to extend
1797 /* for the transposed matrix, the situation is exactly reversed because the row/column algorithms are swapped */
1821 SCIP_CALL( SCIPnetmatdecTryAddCol(transdec, row, tempIdxArray, tempValArray, contnnonzs, &componenttransnetwork) );
1833 SCIP_CALL( SCIPnetmatdecTryAddRow(transdec, col, colrows, colvals, colnnonzs, &componenttransnetwork) );
1838 SCIPnetmatdecRemoveComponent(transdec, &comp->componentcols[startcol], ncols, &comp->componentrows[startrow], nrows);
1866 /* detect implied integrality for integer columns; first, we compute valid columns that have only +-1 entries in
1867 * rows that are integral; then, we sort these and greedily attempt to add them to the (transposed) network matrix
1875 /**@todo avoid work when there is no implied integer variables by taking the original components instead */
1961 /* try extending the network and transposed network by the implied integral columns of the component */
1978 /* If a column can not be added, this does not invalidate implied integrality but means that the
1979 * integrality constraints of adjacent columns may be required for a differnt reason. Thus, we do not need
1991 SCIP_CALL( SCIPnetmatdecTryAddRow(transdec, col, colrows, colvals, colnnonz, &componenttransnetwork) );
2007 /* candidates are non-implied integral columns with +- 1 entries without any nonzeros in bad rows */
2010 if( !SCIPvarIsNonimpliedIntegral(matrixGetVar(matrix, col)) || matrixColInNonlinearTerm(matrix, col) )
2074 /* we generally prefer to detect implied integrality of general integer variables over binary variables */
2086 /* @TODO detect when all columns only extend the network / transposed components, then we can take both */
2243 if( SCIPgetStage(scip) != SCIP_STAGE_PRESOLVING || SCIPinProbing(scip) || SCIPisNLPEnabled(scip) )
2246 /* skip implied integrality detection in branch-and-price, since it relies on rows being static */
2274 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, " (%.1fs) implied integrality detection started\n", starttime);
2281 " (%.1fs) implied integrality detection stopped because problem contains unsuitable constraints\n",
2338 SCIP_CALL( SCIPincludePresolBasic(scip, &presol, PRESOL_NAME, PRESOL_DESC, PRESOL_PRIORITY, PRESOL_MAXROUNDS,
2356 "use the network row addition algorithm when the column to row ratio becomes larger than this threshold",
2361 "a row that contains variables with coefficients that are greater in absolute value than this limit is not considered for implied integrality detection",
Constraint handler for AND constraints, .
Constraint handler for knapsack constraints of the form , x binary and .
Constraint handler for linear constraints in their most general form, .
Constraint handler for logicor constraints (equivalent to set covering, but algorithms are suited fo...
Constraint handler for "or" constraints, .
Constraint handler for the set partitioning / packing / covering constraints .
Constraint handler for variable bound constraints .
Constraint handler for XOR constraints, .
int SCIPgetNVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
Definition: cons_knapsack.c:13845
SCIP_Real SCIPgetVbdcoefVarbound(SCIP *scip, SCIP_CONS *cons)
Definition: cons_varbound.c:5970
int SCIPgetNVarsLogicor(SCIP *scip, SCIP_CONS *cons)
Definition: cons_logicor.c:5549
SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
Definition: cons_linear.c:18346
SCIP_VAR ** SCIPgetVarsLinear(SCIP *scip, SCIP_CONS *cons)
Definition: cons_linear.c:18433
SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
Definition: cons_linear.c:18322
int SCIPgetNVarsLinear(SCIP *scip, SCIP_CONS *cons)
Definition: cons_linear.c:18409
SCIP_VAR * SCIPgetResultantAnd(SCIP *scip, SCIP_CONS *cons)
Definition: cons_and.c:5248
SCIP_Real * SCIPgetValsLinear(SCIP *scip, SCIP_CONS *cons)
Definition: cons_linear.c:18457
SCIP_VAR * SCIPgetVbdvarVarbound(SCIP *scip, SCIP_CONS *cons)
Definition: cons_varbound.c:5947
SCIP_VAR * SCIPgetResultantOr(SCIP *scip, SCIP_CONS *cons)
Definition: cons_or.c:2355
SCIP_VAR ** SCIPgetVarsSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9619
SCIP_VAR * SCIPgetVarVarbound(SCIP *scip, SCIP_CONS *cons)
Definition: cons_varbound.c:5924
SCIP_Longint * SCIPgetWeightsKnapsack(SCIP *scip, SCIP_CONS *cons)
Definition: cons_knapsack.c:13891
SCIP_Longint SCIPgetCapacityKnapsack(SCIP *scip, SCIP_CONS *cons)
Definition: cons_knapsack.c:13788
SCIP_Real SCIPgetLhsVarbound(SCIP *scip, SCIP_CONS *cons)
Definition: cons_varbound.c:5878
SCIP_SETPPCTYPE SCIPgetTypeSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9642
SCIP_VAR ** SCIPgetVarsLogicor(SCIP *scip, SCIP_CONS *cons)
Definition: cons_logicor.c:5572
SCIP_Real SCIPgetRhsVarbound(SCIP *scip, SCIP_CONS *cons)
Definition: cons_varbound.c:5901
SCIP_VAR ** SCIPgetVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
Definition: cons_knapsack.c:13868
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: scip_message.c:225
SCIP_Bool SCIPnetmatdecContainsRow(SCIP_NETMATDEC *dec, int row)
Definition: network.c:11651
void SCIPnetmatdecRemoveComponent(SCIP_NETMATDEC *dec, int *componentrows, int nrows, int *componentcols, int ncols)
Definition: network.c:11667
SCIP_Bool SCIPnetmatdecContainsColumn(SCIP_NETMATDEC *dec, int column)
Definition: network.c:11659
SCIP_RETCODE SCIPnetmatdecTryAddRow(SCIP_NETMATDEC *dec, int row, int *nonzcols, double *nonzvals, int nnonzs, SCIP_Bool *success)
Definition: network.c:11627
SCIP_RETCODE SCIPnetmatdecCreate(BMS_BLKMEM *blkmem, SCIP_NETMATDEC **pdec, int nrows, int ncols)
Definition: network.c:11566
SCIP_RETCODE SCIPnetmatdecTryAddCol(SCIP_NETMATDEC *dec, int column, int *nonzrows, double *nonzvals, int nnonzs, SCIP_Bool *success)
Definition: network.c:11603
SCIP_RETCODE SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:139
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)
Definition: scip_param.c:57
SCIP_RETCODE SCIPincludePresolImplint(SCIP *scip)
Definition: presol_implint.c:2327
int SCIPconshdlrGetNCheckConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4798
SCIP_CONS ** SCIPconshdlrGetCheckConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4755
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip_mem.h:132
void SCIPpresolSetData(SCIP_PRESOL *presol, SCIP_PRESOLDATA *presoldata)
Definition: presol.c:538
SCIP_RETCODE SCIPsetPresolFree(SCIP *scip, SCIP_PRESOL *presol, SCIP_DECL_PRESOLFREE((*presolfree)))
Definition: scip_presol.c:164
SCIP_PRESOL * SCIPfindPresol(SCIP *scip, const char *name)
Definition: scip_presol.c:244
SCIP_RETCODE SCIPsetPresolCopy(SCIP *scip, SCIP_PRESOL *presol, SCIP_DECL_PRESOLCOPY((*presolcopy)))
Definition: scip_presol.c:148
SCIP_RETCODE SCIPincludePresolBasic(SCIP *scip, SCIP_PRESOL **presolptr, const char *name, const char *desc, int priority, int maxrounds, SCIP_PRESOLTIMING timing, SCIP_DECL_PRESOLEXEC((*presolexec)), SCIP_PRESOLDATA *presoldata)
Definition: scip_presol.c:113
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip_numerics.c:462
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip_numerics.c:436
int SCIPvarGetNLocksUpType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
Definition: var.c:4386
SCIP_Bool SCIPvarIsNonimpliedIntegral(SCIP_VAR *var)
Definition: var.c:23506
SCIP_RETCODE SCIPchgVarImplType(SCIP *scip, SCIP_VAR *var, SCIP_IMPLINTTYPE impltype, SCIP_Bool *infeasible)
Definition: scip_var.c:10218
SCIP_RETCODE SCIPgetProbvarLinearSum(SCIP *scip, SCIP_VAR **vars, SCIP_Real *scalars, int *nvars, int varssize, SCIP_Real *constant, int *requiredsize)
Definition: scip_var.c:2378
int SCIPvarGetNLocksDownType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
Definition: var.c:4328
void SCIPsortDownRealInt(SCIP_Real *realarray, int *intarray, int len)
Definition: multiprecision.hpp:66
static SCIP_Bool matrixColInNonlinearTerm(IMPLINT_MATRIX *matrix, int column)
Definition: presol_implint.c:325
static SCIP_RETCODE findImpliedIntegers(SCIP *scip, SCIP_PRESOLDATA *presoldata, IMPLINT_MATRIX *matrix, MATRIX_COMPONENTS *comp, MATRIX_STATISTICS *stats, int *nchgvartypes)
Definition: presol_implint.c:1652
static SCIP_RETCODE addXorLinearization(SCIP *scip, IMPLINT_MATRIX *matrix, SCIP_CONS *cons, SCIP_VAR **operands, int noperands, SCIP_VAR *intvar, SCIP_Real rhs)
Definition: presol_implint.c:622
static SCIP_RETCODE addLinearConstraint(SCIP *scip, IMPLINT_MATRIX *matrix, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_Real lhs, SCIP_Real rhs, SCIP_CONS *cons)
Definition: presol_implint.c:478
static SCIP_RETCODE createMatrixComponents(SCIP *scip, IMPLINT_MATRIX *matrix, MATRIX_COMPONENTS **pmatrixcomponents)
Definition: presol_implint.c:1254
static SCIP_Real matrixGetRowLhs(IMPLINT_MATRIX *matrix, int row)
Definition: presol_implint.c:367
static int matrixGetColumnNNonzs(IMPLINT_MATRIX *matrix, int column)
Definition: presol_implint.c:205
static SCIP_RETCODE matrixSetColumnMajor(SCIP *scip, IMPLINT_MATRIX *matrix)
Definition: presol_implint.c:739
static SCIP_Real matrixGetColUb(IMPLINT_MATRIX *matrix, int column)
Definition: presol_implint.c:353
static int disjointSetMerge(int *disjointset, int first, int second)
Definition: presol_implint.c:1348
static SCIP_Real matrixGetRowRhs(IMPLINT_MATRIX *matrix, int row)
Definition: presol_implint.c:381
static SCIP_RETCODE computeMatrixStatistics(SCIP *scip, IMPLINT_MATRIX *matrix, MATRIX_STATISTICS **pstats, SCIP_Real numericslimit)
Definition: presol_implint.c:1535
static SCIP_Bool matrixColIsImpliedIntegral(IMPLINT_MATRIX *matrix, int column)
Definition: presol_implint.c:311
static int * matrixGetRowInds(IMPLINT_MATRIX *matrix, int row)
Definition: presol_implint.c:233
static void freeMatrixComponents(SCIP *scip, MATRIX_COMPONENTS **pmatrixcomponents)
Definition: presol_implint.c:1295
static SCIP_RETCODE computeContinuousComponents(SCIP *scip, IMPLINT_MATRIX *matrix, MATRIX_COMPONENTS *comp, SCIP_Bool includeimplints)
Definition: presol_implint.c:1381
static SCIP_RETCODE matrixCreate(SCIP *scip, IMPLINT_MATRIX **pmatrix)
Definition: presol_implint.c:808
static void matrixFree(SCIP *scip, IMPLINT_MATRIX **pmatrix)
Definition: presol_implint.c:1199
static SCIP_Bool matrixColIsIntegral(IMPLINT_MATRIX *matrix, int column)
Definition: presol_implint.c:297
static SCIP_Real * matrixGetRowVals(IMPLINT_MATRIX *matrix, int row)
Definition: presol_implint.c:219
static int matrixGetRowNNonzs(IMPLINT_MATRIX *matrix, int row)
Definition: presol_implint.c:247
static SCIP_RETCODE getActiveVariables(SCIP *scip, SCIP_VAR ***vars, SCIP_Real **scalars, int *nvars, SCIP_Real *constant)
Definition: presol_implint.c:395
static SCIP_VAR * matrixGetVar(IMPLINT_MATRIX *matrix, int column)
Definition: presol_implint.c:283
static int * matrixGetColumnInds(IMPLINT_MATRIX *matrix, int column)
Definition: presol_implint.c:191
static SCIP_Real matrixGetColLb(IMPLINT_MATRIX *matrix, int column)
Definition: presol_implint.c:339
static SCIP_RETCODE addAndOrLinearization(SCIP *scip, IMPLINT_MATRIX *matrix, SCIP_CONS *cons, SCIP_VAR **operands, int noperands, SCIP_VAR *resultant, SCIP_Bool isAndCons)
Definition: presol_implint.c:552
static SCIP_Real * matrixGetColumnVals(IMPLINT_MATRIX *matrix, int column)
Definition: presol_implint.c:177
static SCIP_RETCODE matrixAddRow(SCIP *scip, IMPLINT_MATRIX *matrix, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_Real lhs, SCIP_Real rhs, SCIP_CONS *cons)
Definition: presol_implint.c:430
static int disjointSetFind(int *disjointset, int ind)
Definition: presol_implint.c:1317
static void freeMatrixStatistics(SCIP *scip, MATRIX_STATISTICS **pstats)
Definition: presol_implint.c:1624
Presolver that detects implicit integer variables.
public methods for managing constraints
public methods for message output
public data structures and miscellaneous methods
Methods for detecting network matrices.
public methods for presolvers
public methods for problem variables
public methods for constraint handler plugins and constraints
general public methods
public methods for memory management
public methods for message handling
public methods for nonlinear relaxation
public methods for numerical tolerances
public methods for SCIP parameter handling
public methods for presolving plugins
public methods for variable pricer plugins
public methods for global and local (sub)problems
public methods for the probing mode
public methods for timing
public methods for SCIP variables
Definition: presol_implint.c:100
Definition: presol_implint.c:167
int numContNetworkEntries
Definition: presol_implint.c:170
int numContTransNetworkEntries
Definition: presol_implint.c:171
Definition: presol_implint.c:137
Definition: presol_implint.c:154
Definition: struct_cons.h:47
Definition: struct_cons.h:128
Definition: network.c:11560
Definition: struct_presol.h:47
Definition: struct_var.h:262
Definition: struct_scip.h:72