All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
prop_pseudoobj.c
Go to the documentation of this file.
21 * This propagator propagates the objective function using the cutoff bound and the pseudo objective value. The pseudo
22 * objective value can be seen as minimum activity of the linear objective function. Using this, this propagator checks
23 * if variables with non-zero objective coefficients can exceed the cutoff bound. If this is the case the corresponding
29 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
39 #define PROP_TIMING SCIP_PROPTIMING_BEFORELP | SCIP_PROPTIMING_AFTERLPLOOP | SCIP_PROPTIMING_DURINGLPLOOP
42 #define PROP_DELAY FALSE /**< should propagation method be delayed, if other propagators found reductions? */
43 #define PROP_PRESOL_PRIORITY +6000000 /**< priority of the presolving method (>= 0: before, < 0: after constraint handlers); combined with presolvers */
44 #define PROP_PRESOL_DELAY FALSE /**< should presolving be delay, if other presolvers found reductions? */
45 #define PROP_PRESOL_MAXROUNDS -1 /**< maximal number of presolving rounds the presolver participates in (-1: no
51 #define DEFAULT_MINUSELESS 100 /**< minimal number of successive none binary variable propagator whithout a
53 #define DEFAULT_MAXVARSFRAC 0.1 /**< maximal fraction of none binary variables with non-zero objective
55 #define DEFAULT_PROPFULLINROOT TRUE /**< do we want to propagate all non-binary variables if we are propagating the root node? */
57 #define DEFAULT_FORCE FALSE /**< should the propagator be forced even active pricer are present? Note that
61 #define DEFAULT_MAXNEWVARS 1000 /**< number of variable added after the propagator is reinitialized? */
62 #define DEFAULT_PROPUSEIMPLICS TRUE /**< use implications to strengthen the propagation of binary variable (increasing the objective change)? */
63 #define DEFAULT_RESPROPUSEIMPLICS TRUE /**< use implications to strengthen the resolve propagation of binary variable (increasing the objective change)? */
64 #define DEFAULT_MAXIMPLVARS 50000 /**< maximum number of binary variables the implications are used if turned on (-1: unlimited)? */
76 SCIP_Real maxobjchg; /**< maximum objective contribution if variables x is fixed to zero or one */
81 typedef struct SCIP_ObjImplics SCIP_OBJIMPLICS; /**< implications in the form x == 0 or x == 1 ==> y == 0 or y == 1 for (x and y binary) */
88 SCIP_VAR** minactvars; /**< binary variables with non-zero objective contribution w.r.t. minimum activity of the objective function */
89 SCIP_OBJIMPLICS** minactimpls; /**< implication data structure for the binary variables w.r.t. minimum activity */
90 SCIP_VAR** maxactvars; /**< binary variables with non-zero objective contribution w.r.t. maximum activity of the objective function */
94 SCIP_HASHTABLE* addedvars; /**< hash table used during resolving of a bound change (conflict analysis) */
101 int maxpseudoobjactinf; /**< number of coefficients contributing with infinite value to maxpseudoobjact */
102 int nminactvars; /**< number of binary variables with non-zero objective contribution w.r.t. minimum activity of the objective function */
103 int nmaxactvars; /**< number of binary variables with non-zero objective contribution w.r.t. maximum activity of the objective function */
108 int glbfirstnonfixed; /**< index of first globally non-fixed binary variable in minactvars array */
109 int maxactfirstnonfixed;/**< index of first globally non-fixed binary variable in maxctvars array */
113 int maximplvars; /**< maximum number of binary variables the implications are used if turned on (-1: unlimited)? */
115 SCIP_Bool propfullinroot; /**< do we want to propagate all non-binary variables if we are propagating the root node */
119 SCIP_Bool propuseimplics; /**< use implications to strengthen the propagation of binary variable (increasing the objective change)? */
120 SCIP_Bool respropuseimplics; /**< use implications to strengthen the resolve propagation of binary variable (increasing the objective change)? */
229 * (ii) the locks which indicate most effect -- for the variables with a positive (negative) objective coefficient the
230 * down (up) lock is used since this lock indicates that tightened of the upper (lower) bound will triegger
319 /** creates an objective implication data structure, fixes (globally) variables which are implied by lower and upper
327 SCIP_HASHMAP* binobjvarmap, /**< hash map mapping binary variables with none-zero objective to position in collected variables arrays, or NULL */
328 SCIP_Bool* collectedlbvars, /**< temporary buffer to mark collected variables for lower bound fixing, or NULL */
329 SCIP_Bool* collectedubvars, /**< temporary buffer to mark collected variables for upper bound fixing, or NULL */
509 objimplics->objvars[objimplics->nlbimpls] = objimplics->objvars[objimplics->nlbimpls + objimplics->nubimpls];
532 /** catch bound change events if the variable has a non-zero objective coefficient to check if the maximum activity of
554 SCIP_CALL( SCIPcatchVarEvent(scip, var, SCIP_EVENTTYPE_GUBCHANGED, eventhdlr, (SCIP_EVENTDATA*)propdata, NULL) );
558 SCIP_CALL( SCIPcatchVarEvent(scip, var, SCIP_EVENTTYPE_GLBCHANGED, eventhdlr, (SCIP_EVENTDATA*)propdata, NULL) );
586 SCIP_CALL( SCIPdropVarEvent(scip, var, SCIP_EVENTTYPE_GUBCHANGED, eventhdlr, (SCIP_EVENTDATA*)propdata, -1) );
590 SCIP_CALL( SCIPdropVarEvent(scip, var, SCIP_EVENTTYPE_GLBCHANGED, eventhdlr, (SCIP_EVENTDATA*)propdata, -1) );
620 /* drop bound relax event which is caught for all binary variables which are used for propagation the objective
623 SCIP_CALL( SCIPdropVarEvent(scip, var, SCIP_EVENTTYPE_BOUNDRELAXED, eventhdlr, (SCIP_EVENTDATA*)propdata, -1) );
636 /* drop events which are needed for evaluating the maximum activity of the objective function */
649 /* drop events which are needed for evaluating the maximum activity of the objective function */
741 /** returns the objective change provided by the implication variable by fixing it to the given bound
742 * w.r.t. minimum activity of the objective function; additionally it collects all contributors for that objective
749 SCIP_HASHMAP* binobjvarmap, /**< hash map mapping binary variables with none-zero objective to position in collected variables arrays */
797 /** returns the objective change provided by the implications of the given variable by fixing it to the given bound
798 * w.r.t. minimum activity of the objective function; additionally it collects all contributors for that objective
801 * Let I(0) and I(1) be all implications of the given variable which follow by fixing it to given bound and evaluate to
802 * fixing the implication variable to zero (I(0)) or one (I(1)), respectively. The objective change provided by the
807 * sum_{x\in I(1)} (1 - \mbox{bestbound}(x)) \cdot \mbox{objval}(x) - sum_{x\in I(1)} \mbox{bestbound}(x) \cdot \mbox{objval}(x)
809 * sum_{x\in I(0) \cup I(1)} (\mbox{impliedbound}(x) - \mbox{bestbound}(x)) \cdot \mbox{objval}(x)
817 SCIP_HASHMAP* binobjvarmap, /**< hash map mapping binary variables with none-zero objective to position in collected variables arrays */
822 int* ncontributors, /**< pointer to store number of contributor to the objective contribution */
870 /* check if the clique was previously detected to be useless with respect to minimum activity */
907 (*objchg) += collectMinactImplicVar(scip, implvar, binobjvarmap, collectedvars, nbinobjvars, contributors, ncontributors);
931 (*objchg) += collectMinactImplicVar(scip, vars[v], binobjvarmap, collectedvars, nbinobjvars, contributors, ncontributors);
938 /** returns the objective change provided by the implications of the given variable by fixing it to the given bound
941 * Let I(0) and I(1) be all implications of the given variable which follow by fixing it to given bound and evaluate to
942 * fixing the implication variable to zero (I(0)) or one (I(1)), respectively. The objective change provided by the
947 * sum_{x\in I(1)} (1 - \mbox{bestbound}(x)) \cdot \mbox{objval}(x) - sum_{x\in I(1)} \mbox{bestbound}(x) \cdot \mbox{objval}(x)
949 * sum_{x\in I(0) \cup I(1)} (\mbox{impliedbound}(x) - \mbox{bestbound}(x)) \cdot \mbox{objval}(x)
952 * This can be done w.r.t. global variable bounds (local == FALSE), w.r.t. local variable bounds (local == TRUE &&
960 SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node, or NULL */
1015 /* check if variable is global fixed; if so remove it from the objective implication data structure and
1026 assert(SCIPvarGetObj(implvar) > 0.0 || SCIPvarsHaveCommonClique(var, (SCIP_Bool) bound, implvar, TRUE, TRUE));
1027 assert(SCIPvarGetObj(implvar) < 0.0 || SCIPvarsHaveCommonClique(var, (SCIP_Bool) bound, implvar, FALSE, TRUE));
1037 /** computes for the given binary variable the objective contribution by fixing it to given bound w.r.t. minimum
1038 * activity of the objective function; additionally it collects all contributors for that objective change;
1045 SCIP_HASHMAP* binobjvarmap, /**< hash map mapping binary variables with none-zero objective to position in collected variables arrays */
1050 int* ncontributors, /**< pointer to store number of contributor to the objective contribution */
1064 SCIP_CALL( collectMinactImplicVars(scip, var, bound, binobjvarmap, collectedvars, nbinobjvars, contributors, uselesscliques, ncontributors, objchg) );
1069 /** computes for the given binary variable the objective contribution by fixing it to given bound w.r.t. minimum
1070 * activity of the objective function; this can be done w.r.t. global variable bounds (local == FALSE), w.r.t. local
1071 * variable bounds (local == TRUE && bdchgidx == NULL), and w.r.t. given time stamp (local == TRUE && bdchgidx != NULL)
1078 SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node, or NULL */
1095 /** returns the global (that means w.r.t. global bounds of the variables) objective change provided by the implication of
1096 * the given variable by fixing it to the given bound w.r.t. maximum activity of the objective function
1098 * Let I(0) and I(1) be all implications of the given variable which follow by fixing it to given bound and evaluate to
1099 * fixing the implication variable to zero (I(0)) or one (I(1)), respectively. The objective change provided by the
1104 * sum_{x\in I(1)} (1 - \mbox{worstbound}(x)) \cdot \mbox{objval}(x) - sum_{x\in I(1)} \mbox{worst}(x) \cdot \mbox{objval}(x)
1106 * sum_{x\in I(0) \cup I(1)} (\mbox{impliedbound}(x) - \mbox{worstbound}(x)) \cdot \mbox{objval}(x)
1152 /** computes for the given binary variable the gloabl (that means w.r.t. global bounds of the variables) objective
1169 /* check if the implications should be used to increase the objective contribution for given variable */
1182 SCIP_HASHMAP* binobjvarmap, /**< hash map mapping binary variables with none-zero objective to position in collected variables arrays */
1183 SCIP_Bool* collectedvars, /**< temporary buffer to mark collected variables which should be reset */
1209 SCIP_OBJIMPLICS** objimplics, /**< pointer to store the objective implication data structure w.r.t. minimum activity */
1211 SCIP_HASHMAP* binobjvarmap, /**< hash map mapping binary variables with none-zero objective to position in collected variables arrays */
1212 SCIP_Bool* collectedlbvars, /**< temporary buffer to mark collected variables for lower bound fixing */
1213 SCIP_Bool* collectedubvars, /**< temporary buffer to mark collected variables for upper bound fixing */
1253 /* get contribution of variable by fixing it to its lower bound w.r.t. minimum activity of the objective function */
1254 SCIP_CALL( collectMinactObjchg(scip, var, SCIP_BOUNDTYPE_LOWER, binobjvarmap, collectedlbvars, nbinobjvars,
1259 SCIP_BOUNDTYPE_LOWER, SCIPvarGetNBinImpls(var, (SCIP_Bool)SCIP_BOUNDTYPE_LOWER), nlbcontributors);
1261 /* ignore implications if the variable has a zero objective coefficient and implications only one variable, since
1273 /* get contribution of variable by fixing it to its upper bound w.r.t. minimum activity of the objective function */
1274 SCIP_CALL( collectMinactObjchg(scip, var, SCIP_BOUNDTYPE_UPPER, binobjvarmap, collectedubvars, nbinobjvars,
1279 SCIP_BOUNDTYPE_UPPER, SCIPvarGetNBinImpls(var, (SCIP_Bool)SCIP_BOUNDTYPE_UPPER), nubcontributors);
1281 /* ignore implications if the variable has a zero objective coefficient and implications only one variable, since
1287 resetContributors(binobjvarmap, collectedubvars, &contributors[nlbcontributors], nubcontributors);
1295 /* creates an objective implication data structure, fixes (globally) variables which are implied by lower and upper
1298 SCIP_CALL( objimplicsCreate(scip, objimplics, contributors, binobjvarmap, collectedlbvars, collectedubvars, lbobjchg, ubobjchg, nlbcontributors, nubcontributors) );
1307 resetContributors(binobjvarmap, collectedubvars, &contributors[nlbcontributors], nubcontributors);
1319 SCIP_CALL( objimplicsCreate(scip, objimplics, NULL, NULL, NULL, NULL, lbobjchg, ubobjchg, 0, 0) );
1337 /* get contribution of variable by fixing it to its lower bound w.r.t. maximum activity of the objective function */
1341 /* get contribution of variable by fixing it to its upper bound w.r.t. maximum activity of the objective function */
1387 SCIP_CALL( SCIPhashmapCreate(&binobjvarmap, SCIPblkmem(scip), SCIPcalcHashtableSize(SCIPgetNObjVars(scip) * 5)) );
1389 /* count and collect variable problem indices of variables with non-zero objective coefficient */
1455 SCIP_CALL( SCIPhashtableCreate(&uselesscliques, SCIPblkmem(scip), SCIPcalcHashtableSize(ncliques),
1469 /* collect the variables with non-zero objective contribution and catch global bound tighten events that decrease the
1485 /* check that the binary implications are applied for binary variables which are globally fixed */
1492 SCIP_CALL( collectMinactVar(scip, var, &objimplics, useimplics, binobjvarmap, collectedlbvars, collectedubvars,
1506 /* catch bound relax event for the binary variable to handel the firstnonfixed index correctly */
1507 SCIP_CALL( SCIPcatchVarEvent(scip, var, SCIP_EVENTTYPE_BOUNDRELAXED, eventhdlr, (SCIP_EVENTDATA*)propdata, NULL) );
1528 /* catch bound change events if the variable has a non-zero objective coefficient to check if the maximum
1551 /* catch bound change events if the variable has a non-zero objective coefficient to check if the maximum
1580 /* sort binary variables with respect to the absolute value of their maximal potential objective contribution for
1583 SCIPsortDownPtrPtr((void**)propdata->minactimpls, (void**)propdata->minactvars, objimplicsComp, nminactvars);
1585 SCIPdebugMessage("%d binary variables with non-zero objective contribution w.r.t. the minimum activity of the objective function\n", nminactvars);
1597 /* sort binary variables with respect to the absolute value of their maximal potential objective contribution for
1602 SCIPdebugMessage("%d binary variables with non-zero objective contribution w.r.t. the maximum activity of the objective function\n", nmaxactvars);
1615 /* sort continuous variables with respect to the absolute value of their objective coefficient */
1616 SCIPsortDownPtr((void**)(&propdata->objintvars[nobjintvars - nobjcontvars]), varCompObj, nobjcontvars);
1618 SCIPdebugMessage("%d integer variables and %d continuous variables with non-zero objective contribution\n",
1641 /* due to scaling after presolving we need to update the global pseudoactivity and the cutoffbound */
1645 assert(SCIPgetDepth(scip) > 0 || SCIPisFeasEQ(scip, propdata->glbpseudoobjval, SCIPgetPseudoObjval(scip)));
1650 SCIP_CALL( SCIPhashtableCreate(&propdata->addedvars, SCIPblkmem(scip), SCIPcalcHashtableSize(5*nvars),
1660 /** adds for the given none binary variable a conflict bound depending on its objective contribution */
1665 SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
1666 SCIP_Real* reqpseudoobjval /**< pointer to store the remaining minimum activity which has to be proven */
1683 /* check if the local lower bound (at time stamp bdchgidx) is larger than the global lower bound */
1702 /* check if the local upper bound (at time stamp bdchgidx) is smaller than the global upper bound */
1716 /** check for the given implication variables of they also contribute to the required minimum activity */
1723 SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
1724 SCIP_HASHTABLE* addedvars, /**< hash table containing variables which are already add directly or implicitly due to implications */
1725 SCIP_Real* reqpseudoobjval, /**< pointer to store the remaining minimum activity which has to be proven */
1749 SCIPdebugMessage(" implicated variables <%s>[%g] bdchgidx [%g,%g] -> remaining <%g>\n", SCIPvarGetName(var), SCIPvarGetObj(var), lb, ub, *reqpseudoobjval);
1760 /** adds for the given binary variable a conflict bound depending on its objective contribution */
1765 SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
1767 SCIP_HASHTABLE* addedvars, /**< hash table containing variables which are already add directly or implicitly due to implications */
1769 SCIP_Real* reqpseudoobjval /**< pointer to store the remaining minimum activity which has to be proven */
1793 SCIP_CALL( getConflictImplics(scip, objimplics->objvars, objimplics->nlbimpls, objimplics->nlbimpls + objimplics->nubimpls,
1797 /* check if the binary variable has a positive contribution (positive objective coefficient since it is fixed to
1802 SCIPdebugMessage(" add bound change <%s>[%g] >= <%g> bdchgidx [%g,%g]\n", SCIPvarGetName(var), objval, lb, lb, ub);
1822 /* check if the binary variable has a positive contribution (negative objective coefficient since it is fixed to
1827 SCIPdebugMessage(" add bound change <%s>[%g] <= <%g> bdchgidx=[%g,%g]\n", SCIPvarGetName(var), objval, ub, lb, ub);
1844 /** resolves a propagation by supplying the variables whose bound changes increased the pseudo objective value above the
1854 SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
1855 SCIP_HASHTABLE* addedvars, /**< hash table which contains variable which are already added or implict given as reason for the resolve, or NULL */
1869 assert(SCIPisEQ(scip, SCIPvarGetLbAtIndex(var, bdchgidx, TRUE), SCIPvarGetUbAtIndex(var, bdchgidx, TRUE)));
1878 /* get the objective contribution if we would fix the binray inference variable to its other bound */
1893 SCIP_CALL( getConflictImplics(scip, objimplics->objvars, start, end, bdchgidx, addedvars, cutoffbound, &foundimplics) );
1916 /* in case the variable is integral we just need to prove the newbound plus/minus (1 - epsilon) since the this bound
1927 /* adjust the cutoff bound by the portion the inference variable contributes to the presudo objective activitiy
1938 /** resolves a propagation by supplying the variables whose bound changes increased the pseudo objective value above the
1946 SCIP_VAR* infervar, /**< variable that was deduced, or NULL for conflict analysis initialization */
1949 SCIP_BDCHGIDX* bdchgidx /**< bound change index (time stamp of bound change), or NULL for current time */
1967 * @note The global pseudo objective activity can be minus infinity. In that case all variable are part of the
1970 * @note If the global pseudo objective activity is greater than the required minactivity, the local bound change
1971 * which has to explained is actually (now) a global one. That means, the reason/explanation is empty
1982 /* clear hash table for storing variables which are not needed to add the reason due to global implications or
1993 SCIP_CALL( adjustCutoffbound(scip, propdata, infervar, inferinfo, boundtype, bdchgidx, addedvars, &cutoffbound) );
1999 SCIPdebugMessage("resolve propagation global pseudo objective <%g>, cutoff bounda <%g>, required minactivity <%g>\n",
2006 * collect all variables which contribute positively to the pseudo objective value (minimum activity) until we
2027 /* if the required minimum activity is minus infinity, we have to add all variables which contribute the local
2061 SCIP_CALL( addConflictBinvar(scip, var, bdchgidx, minactimpls[v], addedvars, propdata->respropuseimplics, &reqpseudoobjval) );
2129 /* depending on the objective contribution we can try to tighten the lower or upper bound of the variable */
2136 SCIP_CALL( SCIPinferVarUbProp(scip, var, newbd, prop, inferinfo, FALSE, &infeasible, tightened) );
2141 SCIPdebugMessage(" -> new (local) upper bound of variable <%s>[%g,%g]: %g, objective change <%g>, pseudo objective <%g>, cutoff bound <%g>\n",
2152 SCIPdebugMessage(" -> new (global) upper bound of variable <%s>[%g,%g]: %g, objective change <%g>, pseudo objective <%g>, cutoff bound <%g>\n",
2163 SCIP_CALL( SCIPinferVarLbProp(scip, var, newbd, prop, inferinfo, FALSE, &infeasible, tightened) );
2168 SCIPdebugMessage(" -> new (local) lower bound of variable <%s>[%g,%g]: %g, objective change <%g>, pseudo objective <%g>, cutoff bound <%g>\n",
2179 SCIPdebugMessage(" -> new (global) lower bound of variable <%s>[%g,%g]: %g, objective change <%g>, pseudo objective <%g>, cutoff bound <%g>\n",
2217 SCIP_CALL( getMinactObjchg(scip, var, objimplics, NULL, SCIP_BOUNDTYPE_LOWER, local, &lbobjchg) );
2221 SCIP_CALL( getMinactObjchg(scip, var, objimplics, NULL, SCIP_BOUNDTYPE_UPPER, local, &ubobjchg) );
2230 /* if the lbobjchg and ubobjchg are both able to fix the variable to its upper (1.0) or lower (0.0) bound,
2233 * @note There is no need to use SCIPisFeasLT() in case the objective is integral since the cutoff bound in that case
2234 * is the upper bound minus 1 plus the SCIPcutoffbounddelta() (which is MIN(100.0 * feastol, 0.0001)). However,
2235 * if the objective is not integral we have to check w.r.t. an epsilon to avoid numerical problems.
2237 if( SCIPisFeasLT(scip, cutoffbound, pseudoobjval + ubobjchg) && SCIPisFeasLT(scip, cutoffbound, pseudoobjval + lbobjchg) )
2247 /* add all variable whose best bound changes increased the pseudo objective value above to cutoff bound */
2248 SCIP_CALL( resolvePropagation(scip, propdata, pseudoobjval, NULL, -1, SCIP_BOUNDTYPE_UPPER, NULL) );
2264 SCIP_CALL( propagateCutoffboundVar(scip, prop, var, pos, objchg, cutoffbound, pseudoobjval, local, tightened) );
2270 /** globally propagates if a new cutoff bound or global pseudo objective value (minimum activity of the objective
2292 /* this method should not be called in the root node of the search tree since the standard propagation already does
2307 /* check if the global pseudo objective value (minimum activity of the objective function) is greater or equal to
2333 /* check if the variables is already globally fixed; if so continue with the potential candidate */
2338 SCIP_CALL( propagateCutoffboundBinvar(scip, prop, var, v, cutoffbound, pseudoobjval, &tightened, cutoff, FALSE) );
2340 /* the binary variables are sorted in non-increasing manner w.r.t. the absolute value of their objective
2341 * contribution w.r.t. minimum activity (pseudo objective value) of the objective function; these values are the
2342 * increase in the pseudo objective activity we would get if we fix the variable to its worse bound; hence, we can
2347 SCIPdebugMessage("interrupt global pseudo objective propagation w.r.t. cutoff bound <%.15g> for binary variables after %d from %d binary variables\n",
2355 /* @note The variable might not be globally fixed right away since this would destroy the local internal
2356 * data structure of a search node; the bound change is in that case pending; hence we cannot assert
2365 for( ; v < nminactvars && cutoffbound - pseudoobjval < propdata->minactimpls[v]->maxobjchg; ++v )
2370 /* check if the variables is already globally fixed; if so continue with the potential candidate */
2375 SCIP_CALL( propagateCutoffboundBinvar(scip, prop, var, v, cutoffbound, pseudoobjval, &tightened, cutoff, FALSE) );
2395 /* check if the variable is already locally fixed; in that case we just continue with the next potential
2402 SCIP_CALL( propagateCutoffboundBinvar(scip, prop, var, v, cutoffbound, pseudoobjval, &tightened, cutoff, FALSE) );
2417 SCIP_CALL( propagateCutoffboundVar(scip, NULL, var, -1, SCIPvarGetObj(var), cutoffbound, pseudoobjval, FALSE, &tightened) );
2454 /* always propagate the binary variables completely; note that the variables before the firstnonfixed indexed are
2479 /* check if the variable is already locally fixed; in that case we just continue with the next potential
2486 SCIP_CALL( propagateCutoffboundBinvar(scip, prop, var, v, cutoffbound, pseudoobjval, &tightened, cutoff, TRUE) );
2488 /* the binary variables are sorted in non-increasing manner w.r.t. the absolute value of their objective
2489 * contribution w.r.t. minimum activity of the objective function; These values are the increase in the pseudo
2490 * objective activity (minimum activity of the objective function) we would get if we fix the variable to its
2491 * worse bound; hence, we can stop if for a variable this potential increase is not enough too exceed the cutoff
2496 SCIPdebugMessage("interrupt local pseudo objective propagation w.r.t. cutoff bound <%.15g> for binary variables after %d from %d binary variables\n",
2511 for( ; v < nminactvars && cutoffbound - pseudoobjval < propdata->minactimpls[v]->maxobjchg; ++v )
2516 /* check if the variable is already locally fixed; in that case we just continue with the next potential
2523 SCIP_CALL( propagateCutoffboundBinvar(scip, prop, var, v, cutoffbound, pseudoobjval, &tightened, cutoff, TRUE) );
2545 /* check if the variable is already locally fixed; in that case we just continue with the next potential
2552 SCIP_CALL( propagateCutoffboundBinvar(scip, prop, var, v, cutoffbound, pseudoobjval, &tightened, cutoff, TRUE) );
2584 /* get current pseudo objective value (minimum activity of the objective function) and cutoff bound */
2592 /* @note A new global pseudo objective value could be used to retrive global fixings. There is, however, no need to
2593 * check if a new global pseudo objective value is available. This is the case since a new (better) global
2594 * pseudo activity implicis that a global bound change was performed. That causes that the root node of the
2595 * search tree get marked for repropagation. That will result in propagation call of the pseudo objective
2612 * @note there is no need to propagate the cutoff bound if we are in the root node since this will be done by the
2622 /* we are done with solving since a global pseudo activity is greater or equal to the cutoff bound */
2637 /* check if the pseudo objective value (minimum activity of the objective function) is greater or equal to the cutoff
2642 SCIPdebugMessage("pseudo objective value <%g> exceeds cutoff bound <%g>\n", pseudoobjval, cutoffbound);
2652 /* add all variable whose best bound changes increased the pseudo objective value above to cutoff bound */
2653 SCIP_CALL( resolvePropagation(scip, propdata, cutoffbound, NULL, -1, SCIP_BOUNDTYPE_UPPER, NULL) );
2663 SCIPdebugMessage("propagating pseudo objective function (pseudoobj: %g, cutoffbound: %g)\n", pseudoobjval, cutoffbound);
2666 SCIP_CALL( propagateCutoffboundBinvars(scip, prop, cutoffbound, pseudoobjval, &nchgbds, &cutoff) );
2674 /* tighten domains of none binary variables, if they would increase the pseudo objective value above the cutoff
2699 SCIP_CALL( propagateCutoffboundVar(scip, NULL, var, -1, objval, cutoffbound, pseudoobjval, FALSE, &tightened) );
2740 SCIP_CALL( propagateCutoffboundVar(scip, prop, var, -1, objval, cutoffbound, pseudoobjval, TRUE, &tightened) );
2905 /** propagates the global domain of the given binary variable against the lower bound (c*x >= lowerbound) */
2924 /*@todo Instead of running always over all implications use SCIP_OBJIMPLICS in the same way as for the propagation of
2928 /* get contribution of variable by fixing it to its lower bound w.r.t. maximum activity of the objective function */
2932 /* get contribution of variable by fixing it to its upper bound w.r.t. maximum activity of the objective function */
2939 /* if the maximum activity of the objective function without the contribution of the given variable shrinks below the
2940 * global lower bound, the contribution of the variable is need; hence, we can fix it to corresponding bound globally
2942 if( SCIPisFeasLT(scip, maxpseudoobjact + lbobjchg, lowerbound) && SCIPisFeasLT(scip, maxpseudoobjact + ubobjchg, lowerbound) )
2944 /* fixing the variable to zero or one leads to decreases of the maximum activity below the lower bound, hence, we
2961 /** propagates the global domains of the given variable with non-zero objective coefficient against the lower bound
2983 /* get residual pseudo objective activity, that is the pseudo objective activity without the given variable */
3058 /* if the lower bound did not change since the last propagation as well as the global bounds of the variables with a
3061 if( SCIPisLE(scip, lowerbound, propdata->lastlowerbound) && propdata->maxpseudoobjact < SCIP_INVALID )
3067 /* if more than one variable contributes an infinity to the maximal pseudo activity we can do nothing */
3080 /* if the maximum pseudo objective activity is smaller than the lower bound the problem is infeasible */
3106 /* check if the variables is already globally fixed; if so continue with the next potential candidate */
3111 SCIP_CALL( propagateLowerboundBinvar(scip, var, lowerbound, maxpseudoobjact, propdata->propuseimplics, &cutoff, &tightened) );
3113 /* the binary variables are sorted in non-increasing manner w.r.t. the absolute value of their objective
3114 * contribution w.r.t. maximum activity of the objective function; These values are the decrease we would
3115 * get with the maximum pseudo objective activity if we fix the variable to its best bound; hence, we can
3116 * stop if for a variable this potential decrease is not enough anymore too fall below the lower bound.
3118 * @note In case a fixing was performed. The variable might not be globally fixed right away since this would
3119 * destroy the local internal data structure of a search node; the bound change is in that case pending;
3125 SCIPdebugMessage("interrupt pseudo objective propagation w.r.t. lower bound <%.15g> for binary variables after %d from %d binary variables\n",
3133 /* update maximum pseudo activity since the previous global bound change might invalidated the maximum
3144 for( ; v < nmaxactvars && maxpseudoobjact - lowerbound < propdata->maxactchgs[v] && !cutoff; ++v )
3150 /* check if the variables is already globally fixed; if so continue with the potential candidate */
3155 SCIP_CALL( propagateLowerboundBinvar(scip, var, lowerbound, maxpseudoobjact, propdata->propuseimplics, &cutoff, &tightened) );
3159 /* update maximum pseudo activity since the previous global bound change might invalidated the maximum
3176 /* check if the variables is already globally fixed; if so continue with the next potential candidate */
3181 SCIP_CALL( propagateLowerboundBinvar(scip, var, lowerbound, maxpseudoobjact, propdata->propuseimplics, &cutoff, &tightened) );
3258 /** solving process initialization method of propagator (called when branch and bound process is about to begin) */
3275 SCIP_CALL( SCIPcatchEvent(scip, SCIP_EVENTTYPE_VARADDED, propdata->eventhdlr, (SCIP_EVENTDATA*)propdata, NULL) );
3282 /** solving process deinitialization method of propagator (called before branch and bound process data is freed) */
3294 SCIP_CALL( SCIPdropEvent(scip, SCIP_EVENTTYPE_VARADDED, propdata->eventhdlr, (SCIP_EVENTDATA*)propdata, -1) );
3357 * (loop backwards, since a variable fixing can change the current and the subsequent slots in the vars array)
3366 SCIP_CALL( propagateCutoffboundVar(scip, NULL, vars[v], -1, objval, cutoffbound, pseudoobjval, FALSE, &tightened) );
3406 /* check if enough new variable are added (due to column generatition to reinitialized the propgator data) */
3423 if( (*result) != SCIP_CUTOFF && (propdata->nmaxactvars > 0 || propdata->nobjintvars > 0) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
3453 SCIPdebugMessage("resolve bound change <%s> %s <%g>(%g), cutoff bound <%g>\n", SCIPvarGetName(infervar),
3454 boundtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", SCIPvarGetLbAtIndex(infervar, bdchgidx, TRUE),
3458 SCIP_CALL( resolvePropagation(scip, propdata, cutoffbound, infervar, inferinfo, boundtype, bdchgidx) );
3529 /* include event handler for gloabl bound change events and variable added event (in case of pricing) */
3530 SCIP_CALL( SCIPincludeEventhdlrBasic(scip, &propdata->eventhdlr, EVENTHDLR_NAME, EVENTHDLR_DESC,
3540 SCIP_CALL( SCIPincludePropBasic(scip, &prop, PROP_NAME, PROP_DESC, PROP_PRIORITY, PROP_FREQ, PROP_DELAY, PROP_TIMING,
3550 SCIP_CALL( SCIPsetPropPresol(scip, prop, propPresolPseudoobj, PROP_PRESOL_PRIORITY, PROP_PRESOL_MAXROUNDS, PROP_PRESOL_DELAY) );
3556 "minimal number of successive none binary variable propagator whithout a bound reduction before aborted",
3561 "maximal fraction of none binary variables with non-zero objective without a bound reduction before aborted",
3586 "use implications to strengthen the propagation of binary variable (increasing the objective change)?",
3591 "use implications to strengthen the resolve propagation of binary variable (increasing the objective change)?",
3616 SCIP_CALL( propagateCutoffboundVar(scip, prop, var, -1, objval, cutoffbound, pseudoobjval, TRUE, tightened) );
|