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*/
72 * as otherwise certain reductions may break. So it is currently not safe to run implied integrality detection
74#define PRESOL_PRIORITY -900000 /**< priority of the presolver (>= 0: before, < 0: after constraint handlers); combined with propagators */
75#define PRESOL_MAXROUNDS 0 /**< maximal number of presolving rounds the presolver participates in (-1: no limit) */
76#define PRESOL_TIMING SCIP_PRESOLTIMING_EXHAUSTIVE /* timing of the presolver (fast, medium, or exhaustive) */
78#define DEFAULT_CONVERTINTEGERS FALSE /**< should implied integrality also be detected for enforced integral variables? */
79#define DEFAULT_COLUMNROWRATIO 50.0 /**< use the network row addition algorithm when the column to row ratio becomes larger than this threshold */
80#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 */
86 SCIP_Bool convertintegers; /**< should implied integrality also be detected for enforced integral variables? */
87 SCIP_Real columnrowratio; /**< use the network row addition algorithm when the column to row ratio
89 SCIP_Real numericslimit; /**< a row that contains variables with coefficients that are greater in
133/** struct that contains information about the blocks/components of the submatrix given by the continuous columns */
153 SCIP_Bool* rowintegral; /**< Are all row entries of non-continuous columns and the row sides integral? */
155 SCIP_Bool* rowbadnumerics; /**< Does the row contain large entries that make numerics difficult? */
163/** struct that contains some information for each integer variable that is a candidate for implied integrality detection */
168 int numContNetworkEntries; /**< The number of nonzeros that have a row in a pure network component */
169 int numContTransNetworkEntries; /**< The number of nonzeroes that have a row in a pure transposed network component */
391/** transforms given variables, scalars and constant to the corresponding active variables, scalars and constant */
411 SCIP_CALL( SCIPgetProbvarLinearSum(scip, *vars, *scalars, nvars, *nvars, constant, &requiredsize) );
419 SCIP_CALL( SCIPgetProbvarLinearSum(scip, *vars, *scalars, nvars, requiredsize, constant, &requiredsize) );
474/** transforms the weighted sum to active variables and then adds the given linear constraint to the matrix */
548/** adds the linearization of a given AND constraint or OR constraint to the constraint matrix */
675 SCIP_CALL( addLinearConstraint(scip, matrix, operands, vals, noperands, -SCIPinfinity(scip), rhs, cons) );
681 SCIP_CALL( addLinearConstraint(scip, matrix, operands, vals, noperands, -SCIPinfinity(scip), 2.0 - rhs * noperands, cons) );
692 /* long XOR constraints are represented nonlinearly, so the relevant active variables are marked non-linear */
702 /* we can transform all variables together in the sum because the constraint can be interpreted as a nonlinear
703 * constraint of the form sum(operands) % 2 = rhs. Thus, it is okay if we have cancellations in the sum.
800/* @todo: skip construction of integral constraints if we do not run detection on integer variables */
832 /* loop over all constraint handlers and collect the number of checked constraints that contribute rows
854 /* the linearization of AND constraints is modelled using n + 1 inequalities on n + 1 variables */
866 /* the linearization of OR constraints is modelled using n + 1 inequalities on n + 1 variables */
878 /* the relaxation of XOR constraints is handled differently depending on the integer variable and size:
880 * without integer variable and three variables, the convex hull of the constraint is added with four rows;
881 * otherwise, the constraint is considered nonlinear because the convex hull representation is exponential
898 /* @todo: support symmetry, linking, sos1, sos2, bounddisjunction, nonlinear, indicator, superindicator conshdlrs */
911 * this counts nonzeros in equalities twice, but can be at most two times as high as the exact number
914 nnonzstmp += SCIPvarGetNLocksDownType(vars[i], SCIP_LOCKTYPE_MODEL) + SCIPvarGetNLocksUpType(vars[i], SCIP_LOCKTYPE_MODEL);
984 SCIP_CALL( addLinearConstraint(scip, matrix, SCIPgetVarsLinear(scip, cons), SCIPgetValsLinear(scip, cons),
985 SCIPgetNVarsLinear(scip, cons), SCIPgetLhsLinear(scip, cons), SCIPgetRhsLinear(scip, cons), cons) );
1015 SCIP_CALL( addLinearConstraint(scip, matrix, SCIPgetVarsKnapsack(scip, cons), consvals, nrowvars,
1105 SCIP_CALL( addLinearConstraint(scip, matrix, consvars, consvals, 2, SCIPgetLhsVarbound(scip, cons),
1159 SCIP_CALL( addXorLinearization(scip, matrix, cons, SCIPgetVarsXor(scip, cons), SCIPgetNVarsXor(scip, cons),
1255 MATRIX_COMPONENTS** pmatrixcomponents /**< Pointer to create the matrix components data structure */
1295 MATRIX_COMPONENTS** pmatrixcomponents /**< Pointer to the allocated matrix components data structure */
1343 * The provided elements to be merged must be representative (i.e. returned by disjointSetFind()).
1358 * The rank is an upper bound on the height of the tree. We want the new root to be the one with 'largest' rank,
1359 * so smallest number. This way, we ensure that the tree remains shallow. If they are equal, we decrement.
1382 MATRIX_COMPONENTS* comp, /**< the connected components data structure to store the components in */
1394 /* let columns and rows share an index by mapping row index i to artificial column index i + nmatrixcols */
1401 if( matrixColIsIntegral(matrix, col) && ( !includeimplints || !matrixColIsImpliedIntegral(matrix, col) ) )
1420 SCIP_CALL( SCIPallocBufferArray(scip, &representativecomponent, comp->nmatrixcols + comp->nmatrixrows) );
1428 if( matrixColIsIntegral(matrix,col) && ( !includeimplints || !matrixColIsImpliedIntegral(matrix, col) ) )
1568 stats->rowequality[i] = !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && SCIPisEQ(scip, lhs, rhs);
1642 * Given the continuous components and statistics on the matrix, each component is checked if the associated matrix
1643 * describes either a network or a transposed network (or both, in which case it is represented by a planar graph) and
1645 * We choose to check if it is a (transposed) network matrix either in a row-wise or in a column-wise fashion,
1646 * depending on the size of the component. Finally, every variable that is in a network matrix or transposed network
1666 SCIP_Bool runintdetection = presoldata->convertintegers && SCIPgetNBinVars(scip) + SCIPgetNIntVars(scip) >= 1;
1675 * For example, make sure that there exist some +-1 candidate columns exist before performing these allocations.
1677 SCIP_CALL( SCIPnetmatdecCreate(SCIPblkmem(scip), &dec, comp->nmatrixrows, comp->nmatrixcols) );
1678 SCIP_CALL( SCIPnetmatdecCreate(SCIPblkmem(scip), &transdec, comp->nmatrixcols, comp->nmatrixrows) );
1680 /* Because the rows may also contain non-continuous columns, we need to remove these from the array that we
1681 * pass to the network matrix decomposition method. We use these working arrays for this purpose.
1698 if( stats->rowncontinuous[row] != stats->rowncontinuouspmone[row] || !stats->rowintegral[row] || stats->rowbadnumerics[row] )
1736 /* We use the row-wise algorithm only if the number of columns is much larger than the number of rows.
1737 * Generally, the column-wise algorithm will be faster, but in these extreme cases, the row algorithm is faster.
1763 SCIP_CALL( SCIPnetmatdecTryAddRow(dec, row, tempIdxArray, tempValArray, contnnonzs, &componentnetwork) );
1780 SCIPnetmatdecRemoveComponent(dec, &comp->componentrows[startrow], nrows, &comp->componentcols[startcol], ncols);
1784 /* we don't need to check if component is both network and transposed network in case we do not want to extend
1795 /* for the transposed matrix, the situation is exactly reversed because the row/column algorithms are swapped */
1819 SCIP_CALL( SCIPnetmatdecTryAddCol(transdec, row, tempIdxArray, tempValArray, contnnonzs, &componenttransnetwork) );
1831 SCIP_CALL( SCIPnetmatdecTryAddRow(transdec, col, colrows, colvals, colnnonzs, &componenttransnetwork) );
1836 SCIPnetmatdecRemoveComponent(transdec, &comp->componentcols[startcol], ncols, &comp->componentrows[startrow], nrows);
1864 /* detect implied integrality for integer columns; first, we compute valid columns that have only +-1 entries in
1865 * rows that are integral; then, we sort these and greedily attempt to add them to the (transposed) network matrix
1873 /**@todo avoid work when there is no implied integer variables by taking the original components instead */
1959 /* try extending the network and transposed network by the implied integral columns of the component */
1976 /* If a column can not be added, this does not invalidate implied integrality but means that the
1977 * integrality constraints of adjacent columns may be required for a differnt reason. Thus, we do not need
1989 SCIP_CALL( SCIPnetmatdecTryAddRow(transdec, col, colrows, colvals, colnnonz, &componenttransnetwork) );
2005 /* candidates are non-implied integral columns with +- 1 entries without any nonzeros in bad rows */
2008 if( !SCIPvarIsNonimpliedIntegral(matrixGetVar(matrix, col)) || matrixColInNonlinearTerm(matrix, col) )
2072 /* we generally prefer to detect implied integrality of general integer variables over binary variables */
2084 /* @TODO detect when all columns only extend the network / transposed components, then we can take both */
2242 if( SCIPgetStage(scip) != SCIP_STAGE_PRESOLVING || SCIPinProbing(scip) || SCIPisNLPEnabled(scip) )
2245 /* skip implied integrality detection in branch-and-price, since it relies on rows being static */
2273 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, " (%.1fs) implied integrality detection started\n", starttime);
2280 " (%.1fs) implied integrality detection stopped because problem contains unsuitable constraints\n",
2337 SCIP_CALL( SCIPincludePresolBasic(scip, &presol, PRESOL_NAME, PRESOL_DESC, PRESOL_PRIORITY, PRESOL_MAXROUNDS,
2355 "use the network row addition algorithm when the column to row ratio becomes larger than this threshold",
2360 "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:13897
SCIP_Real SCIPgetVbdcoefVarbound(SCIP *scip, SCIP_CONS *cons)
Definition: cons_varbound.c:6004
int SCIPgetNVarsLogicor(SCIP *scip, SCIP_CONS *cons)
Definition: cons_logicor.c:5612
SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
Definition: cons_linear.c:18345
SCIP_VAR ** SCIPgetVarsLinear(SCIP *scip, SCIP_CONS *cons)
Definition: cons_linear.c:18417
SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
Definition: cons_linear.c:18326
int SCIPgetNVarsLinear(SCIP *scip, SCIP_CONS *cons)
Definition: cons_linear.c:18398
SCIP_VAR * SCIPgetResultantAnd(SCIP *scip, SCIP_CONS *cons)
Definition: cons_and.c:5238
SCIP_Real * SCIPgetValsLinear(SCIP *scip, SCIP_CONS *cons)
Definition: cons_linear.c:18436
SCIP_VAR * SCIPgetVbdvarVarbound(SCIP *scip, SCIP_CONS *cons)
Definition: cons_varbound.c:5986
SCIP_VAR * SCIPgetResultantOr(SCIP *scip, SCIP_CONS *cons)
Definition: cons_or.c:2345
SCIP_VAR ** SCIPgetVarsSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9701
SCIP_VAR * SCIPgetVarVarbound(SCIP *scip, SCIP_CONS *cons)
Definition: cons_varbound.c:5968
SCIP_Longint * SCIPgetWeightsKnapsack(SCIP *scip, SCIP_CONS *cons)
Definition: cons_knapsack.c:13933
SCIP_Longint SCIPgetCapacityKnapsack(SCIP *scip, SCIP_CONS *cons)
Definition: cons_knapsack.c:13849
SCIP_Real SCIPgetLhsVarbound(SCIP *scip, SCIP_CONS *cons)
Definition: cons_varbound.c:5932
SCIP_SETPPCTYPE SCIPgetTypeSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9719
SCIP_VAR ** SCIPgetVarsLogicor(SCIP *scip, SCIP_CONS *cons)
Definition: cons_logicor.c:5630
SCIP_Real SCIPgetRhsVarbound(SCIP *scip, SCIP_CONS *cons)
Definition: cons_varbound.c:5950
SCIP_VAR ** SCIPgetVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
Definition: cons_knapsack.c:13915
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:2326
int SCIPconshdlrGetNCheckConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4802
SCIP_CONS ** SCIPconshdlrGetCheckConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4759
#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:4380
SCIP_Bool SCIPvarIsNonimpliedIntegral(SCIP_VAR *var)
Definition: var.c:23538
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:4322
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:323
static SCIP_RETCODE findImpliedIntegers(SCIP *scip, SCIP_PRESOLDATA *presoldata, IMPLINT_MATRIX *matrix, MATRIX_COMPONENTS *comp, MATRIX_STATISTICS *stats, int *nchgvartypes)
Definition: presol_implint.c:1650
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:620
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:476
static SCIP_RETCODE createMatrixComponents(SCIP *scip, IMPLINT_MATRIX *matrix, MATRIX_COMPONENTS **pmatrixcomponents)
Definition: presol_implint.c:1252
static SCIP_Real matrixGetRowLhs(IMPLINT_MATRIX *matrix, int row)
Definition: presol_implint.c:365
static int matrixGetColumnNNonzs(IMPLINT_MATRIX *matrix, int column)
Definition: presol_implint.c:203
static SCIP_RETCODE matrixSetColumnMajor(SCIP *scip, IMPLINT_MATRIX *matrix)
Definition: presol_implint.c:737
static SCIP_Real matrixGetColUb(IMPLINT_MATRIX *matrix, int column)
Definition: presol_implint.c:351
static int disjointSetMerge(int *disjointset, int first, int second)
Definition: presol_implint.c:1346
static SCIP_Real matrixGetRowRhs(IMPLINT_MATRIX *matrix, int row)
Definition: presol_implint.c:379
static SCIP_RETCODE computeMatrixStatistics(SCIP *scip, IMPLINT_MATRIX *matrix, MATRIX_STATISTICS **pstats, SCIP_Real numericslimit)
Definition: presol_implint.c:1533
static SCIP_Bool matrixColIsImpliedIntegral(IMPLINT_MATRIX *matrix, int column)
Definition: presol_implint.c:309
static int * matrixGetRowInds(IMPLINT_MATRIX *matrix, int row)
Definition: presol_implint.c:231
static void freeMatrixComponents(SCIP *scip, MATRIX_COMPONENTS **pmatrixcomponents)
Definition: presol_implint.c:1293
static SCIP_RETCODE computeContinuousComponents(SCIP *scip, IMPLINT_MATRIX *matrix, MATRIX_COMPONENTS *comp, SCIP_Bool includeimplints)
Definition: presol_implint.c:1379
static SCIP_RETCODE matrixCreate(SCIP *scip, IMPLINT_MATRIX **pmatrix)
Definition: presol_implint.c:806
static void matrixFree(SCIP *scip, IMPLINT_MATRIX **pmatrix)
Definition: presol_implint.c:1197
static SCIP_Bool matrixColIsIntegral(IMPLINT_MATRIX *matrix, int column)
Definition: presol_implint.c:295
static SCIP_Real * matrixGetRowVals(IMPLINT_MATRIX *matrix, int row)
Definition: presol_implint.c:217
static int matrixGetRowNNonzs(IMPLINT_MATRIX *matrix, int row)
Definition: presol_implint.c:245
static SCIP_RETCODE getActiveVariables(SCIP *scip, SCIP_VAR ***vars, SCIP_Real **scalars, int *nvars, SCIP_Real *constant)
Definition: presol_implint.c:393
static SCIP_VAR * matrixGetVar(IMPLINT_MATRIX *matrix, int column)
Definition: presol_implint.c:281
static int * matrixGetColumnInds(IMPLINT_MATRIX *matrix, int column)
Definition: presol_implint.c:189
static SCIP_Real matrixGetColLb(IMPLINT_MATRIX *matrix, int column)
Definition: presol_implint.c:337
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:550
static SCIP_Real * matrixGetColumnVals(IMPLINT_MATRIX *matrix, int column)
Definition: presol_implint.c:175
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:428
static int disjointSetFind(int *disjointset, int ind)
Definition: presol_implint.c:1315
static void freeMatrixStatistics(SCIP *scip, MATRIX_STATISTICS **pstats)
Definition: presol_implint.c:1622
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:98
Definition: presol_implint.c:165
int numContNetworkEntries
Definition: presol_implint.c:168
int numContTransNetworkEntries
Definition: presol_implint.c:169
Definition: presol_implint.c:135
Definition: presol_implint.c:152
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