All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
cons_superindicator.c
Go to the documentation of this file.
23 /**@todo implement more upgrades, e.g., for nonlinear, quadratic, logicor slack constraints; upgrades could also help to
27 /**@todo enforce by branching on binary variable if slack constraint only returns SCIP_INFEASIBLE */
28 /**@todo consider enforcing by adding slack constraint (or copy of it) locally if binary variable is fixed to 1
32 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
45 #define CONSHDLR_DESC "constraint handler for indicator constraints over arbitrary constraint types"
47 #define CONSHDLR_ENFOPRIORITY -5000000 /**< priority of the constraint handler for constraint enforcing */
48 #define CONSHDLR_CHECKPRIORITY -5000000 /**< priority of the constraint handler for checking feasibility */
49 #define CONSHDLR_SEPAFREQ -1 /**< frequency for separating cuts; zero means to separate only in the root node */
50 #define CONSHDLR_PROPFREQ 1 /**< frequency for propagating domains; zero means only preprocessing propagation */
51 #define CONSHDLR_EAGERFREQ 100 /**< frequency for using all instead of only the useful constraints in separation,
55 #define CONSHDLR_DELAYSEPA FALSE /**< should separation method be delayed, if other separators found cuts? */
56 #define CONSHDLR_DELAYPROP FALSE /**< should propagation method be delayed, if other propagators found reductions? */
57 #define CONSHDLR_DELAYPRESOL FALSE /**< should presolving method be delayed, if other presolvers found reductions? */
58 #define CONSHDLR_NEEDSCONS TRUE /**< should the constraint handler be skipped, if no constraints are available? */
60 #define CONSHDLR_PROP_TIMING SCIP_PROPTIMING_BEFORELP /**< propagation timing mask of the constraint handler*/
62 #define DEFAULT_CHECKSLACKTYPE TRUE /**< should type of slack constraint be checked when creating superindicator constraint? */
63 #define DEFAULT_UPGDPRIOINDICATOR 1 /**< priority for upgrading to an indicator constraint (-1: never) */
64 #define DEFAULT_UPGDPRIOLINEAR 2 /**< priority for upgrading to a linear constraint (-1: never) */
65 #define DEFAULT_MAXUPGDCOEFLINEAR 1e4 /**< maximum big-M coefficient of binary variable in upgrade to a linear constraint
83 SCIP_Bool checkslacktype; /**< should type of slack constraint be checked when creating superindicator constraint? */
84 SCIP_Real maxupgdcoeflinear; /**< maximum big-M coefficient of binary variable in upgrade to a linear constraint
115 /* do not capture the slack constraint when scip is in transformed mode; this automatically happens in
125 /* we need to capture the constraint to avoid that SCIP deletes them since they are not (yet) added to the problem */
168 SCIP_CALL( SCIPcheckCons(scip, consdata->slackcons, sol, checkintegrality, checklprows, printreason, result) );
172 SCIPinfoMessage(scip, NULL, "violation: SCIPcheckCons() for slack constraint <%s> returns infeasible while binvar <%s> == 1\n",
182 SCIP_CALL( SCIPcheckCons(scip, consdata->slackcons, sol, checkintegrality, TRUE, TRUE, &testresultnotintegrality) );
183 SCIP_CALL( SCIPcheckCons(scip, consdata->slackcons, sol, TRUE, checklprows, TRUE, &testresultnotlprows) );
203 /** computes the minactivity, maxactivity, and minimal absolute value of nonzero coefficients of a linear constraint
241 /* we loop over all the coefficients of the constraint and we cannot end if the minactivity is infinite as we
255 ismininfinity = ismininfinity || (val > 0.0 && (SCIPisInfinity(scip, lb) || SCIPisInfinity(scip, -lb)))
258 ismaxinfinity = ismaxinfinity || (val > 0.0 && (SCIPisInfinity(scip, ub) || SCIPisInfinity(scip, -ub)))
337 SCIPdebugMessage("constraint <%s> deleted because of free slack constraint\n", SCIPconsGetName(cons));
347 SCIP_CALL( SCIPcreateConsIndicator(scip, &indcons, name, consdata->binvar, SCIPgetNVarsLinear(scip, consdata->slackcons),
348 SCIPgetVarsLinear(scip, consdata->slackcons), SCIPgetValsLinear(scip, consdata->slackcons), rhs,
349 SCIPconsIsInitial(cons), SCIPconsIsSeparated(cons), SCIPconsIsEnforced(cons), SCIPconsIsChecked(cons),
350 SCIPconsIsPropagated(cons), SCIPconsIsLocal(cons), SCIPconsIsDynamic(cons), SCIPconsIsRemovable(cons),
378 SCIPconsIsInitial(cons), SCIPconsIsSeparated(cons), SCIPconsIsEnforced(cons), SCIPconsIsChecked(cons),
379 SCIPconsIsPropagated(cons), SCIPconsIsLocal(cons), SCIPconsIsDynamic(cons), SCIPconsIsRemovable(cons),
468 SCIPdebugMessage("constraint <%s> deleted because of free slack constraint\n", SCIPconsGetName(cons));
473 /* if linear slack constraint is redundant due to bounded activities we can delete the superindicator constraint */
478 if( (SCIPisInfinity(scip, -lhs) || SCIPisLE(scip, lhs, minact)) && (SCIPisInfinity(scip, rhs) || SCIPisGE(scip, rhs, maxact)) )
483 SCIPdebugMessage("constraint <%s> deleted because of redundant slack constraint\n", SCIPconsGetName(cons));
488 /* if the big-M coefficient is too large compared to the coefficients of the slack constraint, we do not upgrade to
493 if( (!SCIPisInfinity(scip, rhs) && (SCIPisInfinity(scip, maxact) || SCIPisInfinity(scip, maxact - rhs) ||
495 (!SCIPisInfinity(scip, -lhs) && (SCIPisInfinity(scip, -minact) || SCIPisInfinity(scip, lhs - minact) ||
498 SCIPdebugMessage("constraint <%s> not upgraded to a linear constraint due to large big-M coefficient\n",
546 SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, name, nvars+1, newvars, newvals, -SCIPinfinity(scip), maxact,
547 SCIPconsIsInitial(cons), SCIPconsIsSeparated(cons), SCIPconsIsEnforced(cons), SCIPconsIsChecked(cons),
548 SCIPconsIsPropagated(cons), SCIPconsIsLocal(cons), SCIPconsIsModifiable(cons), SCIPconsIsDynamic(cons),
577 SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, name, nvars+1, newvars, newvals, minact, SCIPinfinity(scip),
578 SCIPconsIsInitial(cons), SCIPconsIsSeparated(cons), SCIPconsIsEnforced(cons), SCIPconsIsChecked(cons),
579 SCIPconsIsPropagated(cons), SCIPconsIsLocal(cons), SCIPconsIsModifiable(cons), SCIPconsIsDynamic(cons),
671 /** destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
694 /** presolving initialization method of constraint handler (called when presolving is about to begin) */
727 /* we have to release the slack constraint also in case we transformed it manually since it is captured automatically
753 SCIP_CALL( consdataCreateSuperindicator(scip, &targetdata, sourcedata->binvar, sourcedata->slackcons) );
759 SCIPconsIsModifiable(sourcecons), SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons),
1066 SCIPdebugPrintf(" --> %slocresult=%d\n", locresult == SCIP_FEASIBLE ? "satisfied, " : "", locresult);
1071 SCIP_CALL( consdataCheckSuperindicator(scip, consdata, NULL, TRUE, FALSE, FALSE, &locresult) );
1175 SCIP_CALL( SCIPenfopsCons(scip, consdata->slackcons, solinfeasible, objinfeasible, &locresult) );
1177 SCIPdebugPrintf(" --> %slocresult=%d\n", locresult == SCIP_FEASIBLE ? "satisfied, " : "", locresult);
1182 SCIP_CALL( consdataCheckSuperindicator(scip, consdata, NULL, TRUE, FALSE, FALSE, &locresult) );
1280 SCIP_CALL( consdataCheckSuperindicator(scip, consdata, sol, checkintegrality, checklprows, printreason, result) );
1283 SCIPdebugMessage("checked solution from <%s> (checkintegrality=%u, checklprows=%u) --> result=%d (%sfeasible)\n",
1284 SCIPsolGetHeur(sol) == NULL ? "NULL" : SCIPheurGetName(SCIPsolGetHeur(sol)), checkintegrality, checklprows,
1320 SCIPdebugMessage("binvar <%s> == 1 globally --> deleting superindicator and adding slack constraint <%s>\n",
1340 /**@todo else propagate the domain of the binvar as well: start probing mode, fix binvar to one, propagate
1341 * constraint, and see whether we become infeasible; if this is implemented, the resprop callback must be
1350 /* if propagation of one constraint is delayed, we want to propagate again unless the node is cut off */
1407 /**@todo check whether the slack constraint is added to SCIP; in this case the superindicator can be deleted */
1411 /* if binvar is globally fixed to 1, we add the slack constraint and remove the superindicator */
1416 SCIPdebugMessage("binvar <%s> == 1 globally --> deleting superindicator and adding slack constraint <%s>\n",
1439 /**@todo mark if upgrading failed to avoid trying too often; however, since upgrading might fail only due to
1446 /**@todo else propagate the domain of the binvar as well: start probing mode, fix binvar to one, propagate
1455 /* if presolving of one constraint is delayed, we want to run again unless the result is cutoff */
1522 SCIP_CALL( SCIPrespropCons(scip, consdata->slackcons, infervar, inferinfo, boundtype, bdchgidx, relaxedbd, result) );
1617 SCIPdebugMessage("copying superindicator constraint <%s> to <%s>\n", SCIPconsGetName(sourcecons), consname);
1621 SCIPwarningMessage(scip, "cannot create modifiable superindicator constraint when trying to copy constraint <%s>\n",
1640 SCIP_CALL( SCIPcreateConsLinear(scip, &targetslackcons, "dummy", 0, NULL, NULL, 0.0, SCIPinfinity(scip),
1651 /* if copying scip after transforming the original instance before presolving, we need to correct the slack
1668 SCIP_CALL( SCIPgetConsCopy(sourcescip, scip, sourceslackcons, &targetslackcons, conshdlrslack, varmap, consmap,
1669 SCIPconsGetName(sourceslackcons), SCIPconsIsInitial(sourceslackcons), SCIPconsIsSeparated(sourceslackcons),
1670 SCIPconsIsEnforced(sourceslackcons), SCIPconsIsChecked(sourceslackcons), SCIPconsIsPropagated(sourceslackcons),
1671 SCIPconsIsLocal(sourceslackcons), SCIPconsIsModifiable(sourceslackcons), SCIPconsIsDynamic(sourceslackcons),
1672 SCIPconsIsRemovable(sourceslackcons), SCIPconsIsStickingAtNode(sourceslackcons), global, valid) );
1683 SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, sourcebinvar, &targetbinvar, varmap, consmap, global, valid) );
1707 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "could not copy superindicator constraint <%s>\n", SCIPconsGetName(sourcecons));
1737 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "Syntax error: expected the following form: <var> = [0|1] -> <cons>\n");
1747 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "Syntax error: expected the following form: <var> = [0|1] -> <cons>\n");
1756 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "Syntax error: expected the following form: <var> = [0|1] -> <cons>\n");
1777 /**@todo get slack constraint name and check whether constraint already exists; however, using only SCIPfindCons() is
1778 * not sufficient since slack constraints are not added to the problem; do we need something like
1779 * SCIPfindConsInConshdlr()?; currently, if there are two superindicator constraints with same slack constraint
1780 * (binvars may be different), then after writing and reading, the slack constraint will be created twice with
1785 SCIP_CALL( SCIPparseCons(scip, &slackcons, slackstr, initial, separate, enforce, check, propagate, local, modifiable,
1797 /* the new superindicator constraint captured the slack constraint, so we can release it now */
1828 /** constraint method of constraint handler which returns the number of variables (if possible) */
1871 consEnfolpSuperindicator, consEnfopsSuperindicator, consCheckSuperindicator, consLockSuperindicator,
1877 SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopySuperindicator, consCopySuperindicator) );
1885 SCIP_CALL( SCIPsetConshdlrPresol(scip, conshdlr, consPresolSuperindicator, CONSHDLR_MAXPREROUNDS, CONSHDLR_DELAYPRESOL) );
1887 SCIP_CALL( SCIPsetConshdlrProp(scip, conshdlr, consPropSuperindicator, CONSHDLR_PROPFREQ, CONSHDLR_DELAYPROP, CONSHDLR_PROP_TIMING) );
1889 SCIP_CALL( SCIPsetConshdlrSepa(scip, conshdlr, consSepalpSuperindicator, consSepasolSuperindicator, CONSHDLR_SEPAFREQ, CONSHDLR_SEPAPRIORITY, CONSHDLR_DELAYSEPA) );
1921 "minuc", "transforms the current problem into a MinUC problem minimizing the number of unsatisfied constraints",
1935 "maximum big-M coefficient of binary variable in upgrade to a linear constraint (relative to smallest coefficient)",
1953 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
1976 SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
1978 SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
2032 SCIPwarningMessage(scip, "rejected creation of superindicator with slack constraint <%s> of type <%s> "
2052 SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, initial, separate, enforce, check, propagate,
2059 * in its most basic version, i. e., all constraint flags are set to their basic value as explained for the
2060 * method SCIPcreateConsSuperindicator(); all flags can be set via SCIPsetConsFLAGNAME-methods in scip.h
2062 * @see SCIPcreateConsSuperindicator() for information about the basic constraint flag configuration
2064 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
2116 /** transforms the current problem into a MinUC problem (minimizing the number of unsatisfied constraints),
2164 /* transform each constraint to slack constraint in a newly created superindicator constraint; note that we also need
2192 SCIPconsIsInitial(cons), SCIPconsIsSeparated(cons), SCIPconsIsEnforced(cons), SCIPconsIsChecked(cons),
2193 SCIPconsIsPropagated(cons), SCIPconsIsLocal(cons), SCIPconsIsDynamic(cons), SCIPconsIsRemovable(cons),
2216 SCIPdebugMessage("constraint <%s> of type <%s> could not be transformed to superindicator and was removed\n",
2222 /* delete slack constraint; this is necessary, because, e.g., the indicator expects its linear slack constraint
2223 * present in the problem, but this has just be transformed; hence, it cannot function any more and we have to
2273 SCIPdialogMessage(scip, NULL, "some constraints could not be transformed to superindicator constraints and were removed\n");
2277 SCIPdialogMessage(scip, NULL, "changed problem has %d variables (%d bin, %d int, %d impl, %d cont) and %d constraints\n",
2278 SCIPgetNVars(scip), SCIPgetNBinVars(scip), SCIPgetNIntVars(scip), SCIPgetNImplVars(scip), SCIPgetNContVars(scip),
|