All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
presolve.c
Go to the documentation of this file.
21 /* all general presolving methods (not working on any specific kind of data(, e.g. consdata) should be implemented here */
23 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
36 /** collect variable bound information for a avraibel set reduction and global implication, only variable which have the
49 SCIP_Real* newbounds, /**< array of implied bounds(, size is two times number of variables, first
135 /* @todo if implvars[x] is aggregated, we could transform the variable into the active representation */
136 if( idx < 0 || SCIPisFeasEQ(scip, SCIPvarGetLbGlobal(implvars[w]), SCIPvarGetUbGlobal(implvars[w])) )
158 /* set variable 'var' with bound implies other set variable 'implvars[w]' with corresponding bound
163 SCIPdebugMessage("set variable <%s> %s %g implies other set variable <%s> %s %g\n", SCIPvarGetName(var), ">=", bounds[pos], SCIPvarGetName(implvars[w]), "<=", 0.0);
181 else if( SCIPisFeasLT(scip, implcoefs[w] * SCIPvarGetUbGlobal(implvars[w]) + implconsts[w], bounds[pos]) )
187 /* set variable 'var' with bound implies other set variable 'implvars[w]' with corresponding bound so
192 SCIPdebugMessage("set variable <%s> %s %g implies other set variable <%s> %s %g (%g)\n", SCIPvarGetName(var), ">=", bounds[pos], SCIPvarGetName(implvars[w]), "<=", newub, bounds[issetvar[idx] - 1] );
236 /* set variable 'var' with bound implies other set variable 'implvars[w]' with corresponding bound
241 SCIPdebugMessage("set variable <%s> %s %g implies other set variable <%s> %s %g\n", SCIPvarGetName(var), ">=", bounds[pos], SCIPvarGetName(implvars[w]), ">=", 1.0);
259 else if( SCIPisFeasLT(scip, implcoefs[w]*SCIPvarGetLbGlobal(implvars[w]) + implconsts[w], bounds[pos]) )
265 /* set variable 'var' with bound implies other set variable 'implvars[w]' with corresponding bound so
270 SCIPdebugMessage("set variable <%s> %s %g implies other set variable <%s> %s %g (%g)\n", SCIPvarGetName(var), ">=", bounds[pos], SCIPvarGetName(implvars[w]), ">=", newlb, bounds[issetvar[idx] - 1] );
333 /* @todo if implvars[x] is aggregated, we could transform the variable into the active representation */
334 if( idx < 0 || SCIPisFeasEQ(scip, SCIPvarGetLbGlobal(implvars[w]), SCIPvarGetUbGlobal(implvars[w])) )
356 SCIPdebugMessage("set variable <%s> %s %g implies other set variable <%s> %s %g\n", SCIPvarGetName(var), "<=", bounds[pos], SCIPvarGetName(implvars[w]), ">=", 1.0);
374 else if( SCIPisFeasGT(scip, implcoefs[w]*SCIPvarGetLbGlobal(implvars[w]) + implconsts[w], bounds[pos]) )
382 SCIPdebugMessage("set variable <%s> %s %g implies other set variable <%s> %s %g (%g)\n", SCIPvarGetName(var), "<=", bounds[pos], SCIPvarGetName(implvars[w]), ">=", newlb, bounds[issetvar[idx] - 1]);
430 SCIPdebugMessage("set variable <%s> %s %g implies other set variable <%s> %s %g\n", SCIPvarGetName(var), "<=", bounds[pos], SCIPvarGetName(implvars[w]), "<=", 0.0);
448 else if( SCIPisFeasGT(scip, implcoefs[w]*SCIPvarGetUbGlobal(implvars[w]) + implconsts[w], bounds[pos]) )
456 SCIPdebugMessage("set variable <%s> %s %g implies other set variable <%s> %s %g (%g)\n", SCIPvarGetName(var), "<=", bounds[pos], SCIPvarGetName(implvars[w]), "<=", newub, bounds[issetvar[idx] - 1]);
489 /** collect non-binary implication data for variable set reduction and global bound implications; only variable which
490 * have the vartype SCIP_VARTYPE_BINARY have implications, otherwise the implications are saved as variable bounds
503 SCIP_Real* newbounds, /**< array of implied bounds(, size is two times number of variables, first
580 /* @todo if implvars[x] is aggregated, we could transform the variable into the active representation */
581 if( idx < 0 || SCIPisFeasEQ(scip, SCIPvarGetLbGlobal(implvars[w]), SCIPvarGetUbGlobal(implvars[w])) )
590 /* set variable 'var' with bound implies other set variable 'implvars[w]' with a non-worse bound than the
595 SCIPdebugMessage("set variable <%s> %s %g implies other set variable <%s> %s %g (%g)\n", SCIPvarGetName(var), boundtypes[pos] ? "<=" : ">=", bounds[pos], SCIPvarGetName(implvars[w]), "<=", implbounds[w], bounds[issetvar[idx] - 1]);
608 /* the implied upper bound on a binary variable should not be trivial, otherwise we might globally fix
643 /* set variable 'var' with bound implies other set variable 'implvars[w]' with a non-worse bound than the
648 SCIPdebugMessage("set variable <%s> %s %g implies other set variable <%s> %s %g (%g)\n", SCIPvarGetName(var), boundtypes[pos] ? "<=" : ">=", bounds[pos], SCIPvarGetName(implvars[w]), ">=", implbounds[w], bounds[issetvar[idx] - 1]);
661 /* the implied lower bound on a binary variable should not be trivial, otherwise we might globally fix
664 * @note is is possible that the implied bound is greater than one, when the implied variable has
696 /** collect binary implication data for variable set reduction and global bound implications; only variable which have
697 * the vartype SCIP_VARTYPE_BINARY have binary implications, otherwise the implications are saved as variable bounds
709 SCIP_Real* newbounds, /**< array of implied bounds(, size is two times number of variables, first
722 int* foundbin, /**< pointer to store the lowest index of a binary implication variable when found */
774 /* set variable 'var' with bound implies other set variable 'implvars[w]' with corresponding bound so we can
779 SCIPdebugMessage("set variable <%s> %s %g implies other set variable <%s> %s %g\n", SCIPvarGetName(var), boundtypes[pos] ? "<=" : ">=", bounds[pos], SCIPvarGetName(implvars[w]), implboundtypes[w] ? "<=" : ">=", implboundtypes[w] ? 0.0 : 1.0);
798 /** collect clique data on binary variables for variable set reduction and global bound implications */
809 SCIP_Real* newbounds, /**< array of implied bounds(, size is two times number of variables, first
822 int* foundbin, /**< pointer to store the lowest index of a binary implication variable when found */
878 if( clqvars[w] == var || SCIPvarGetLbGlobal(clqvars[w]) > 0.5 || SCIPvarGetUbGlobal(clqvars[w]) < 0.5 )
889 /* set variable 'var' with bound implies other set variable 'clqvars[w]' with corresponding set bound so we can
894 SCIPdebugMessage("set variable <%s> %s %g implies other set variable <%s> %s %g\n", SCIPvarGetName(var), boundtypes[pos] ? "<=" : ">=", bounds[pos], SCIPvarGetName(clqvars[w]), clqvalues[w] ? "<=" : ">=", clqvalues[w] ? 0.0 : 1.0);
920 /** try to reduce the necessary variable in a set of variables with corresponding bounds and boundtypes for which one
929 * by (global) implication data (cliques, implications, and variable bounds) we have also the following implications
936 * Because of the last implication x4 is redundant, because x1 >= 1 would also be fulfilled in the variable set, so we
938 * Also, the both other implications and x3 >= 1 (in the given variable set) all implie exactly x3 >= 1, so we tighten
958 SCIP_Bool* setredundant, /**< pointer to store if we found a global reduction on a variable which
962 SCIP_Bool fullshortening /**< do we want to try the shortening procedure over the whole set (which
967 SCIP_Real* newbounds; /* array saving all overall implied global bounds, first nprobvars for lower bound, second
970 SCIP_Real* lastbounds;/* temporary array to remember last implied bounds before taken the current variable into
976 int* issetvar; /* array for mapping from a problem variable to the position in the variable set (,pos + 1 in
980 int* counts; /* array saving number of implication by set variables, first nprobvars for lower bound, second
983 int* implidx; /* temporary array to remember all indices of implied variables by the current set variable
1024 /* @todo need global memory because allocating and clearing can be expensive in presolving, i.e. calloc(memset) is
1025 * too expensive, might also consider other data structures like hashmaps for issetvar and counts
1049 /* check if implied binary variables exist, because for these variables the implications can be stored in the
1077 collectBinaryCliqueData(var, varidx, v, value, bounds, boundtypes, newbounds, counts, issetvar, nprobvars, &foundbin, implidx, &nimplidx);
1079 /* only variable which have the vartype SCIP_VARTYPE_BINARY have binary implications, otherwise the
1082 * @note if implications on two binary variables are stored in the clique data, the following if block can be deleted
1086 collectBinaryImplicationData(var, varidx, v, value, bounds, boundtypes, newbounds, counts, issetvar, nprobvars, &foundbin, implidx, &nimplidx);
1091 /* only variable which have the vartype SCIP_VARTYPE_BINARY have implications, otherwise the implications are
1094 * we only check binary to non-binary implications if we can detect further implications which either lead to
1097 if( SCIPvarGetType(var) == SCIP_VARTYPE_BINARY && ((usebin && implbinvarsexist) || usenonbin) )
1099 collectNonBinaryImplicationData(scip, var, varidx, v, value, bounds, boundtypes, newbounds, counts, issetvar, nprobvars, &foundbin, &foundnonbin, implidx, &nimplidx, lastbounds);
1103 * we only check the variable bounds if we can detect further implications which either lead to global reductions
1106 else if( SCIPvarGetType(var) != SCIP_VARTYPE_BINARY && ((usebin && implbinvarsexist) || usenonbin) )
1108 collectNonBinaryVBoundData(scip, var, varidx, v, bounds, boundtypes, newbounds, counts, issetvar, nprobvars, &foundbin, &foundnonbin, implidx, &nimplidx, lastbounds);
1111 /* reduce implication counters on all variables which are implied by a variable now marked as redundant */
1119 SCIPdebugMessage("marked variable <%s> as redundant variable in variable set\n", SCIPvarGetName(var));
1124 /* correct implication counters and bounds, if the redundant variable implies other variables we need to reduce
1142 if( !SCIPvarIsBinary(probvars[implidx[w] - nprobvars]) && lastbounds[w] != SCIP_INVALID )/*lint !e777*/
1151 /* check if we want to shorten the whole set of variables, or terminate early if we did not find any further
1212 SCIPdebugMessage("mark redundant variable <%s> to be removed from variable set\n", SCIPvarGetName(var));
1229 SCIPdebugMessage("variable set led to global reductions (in %s)\n", SCIPprobGetName(scip->transprob));
1249 SCIPdebugMessage("can fix variable %s [%g, %g] to 1.0\n", SCIPvarGetName(probvar), SCIPvarGetLbGlobal(probvar), SCIPvarGetUbGlobal(probvar));
1254 scip->transprob, scip->origprob, scip->tree, scip->lp, scip->branchcand, scip->eventqueue, probvar, 1.0,
1267 SCIPdebugMessage("can tighten lower bound variable %s [%g, %g] to %g\n", SCIPvarGetName(probvar), SCIPvarGetLbGlobal(probvar), SCIPvarGetUbGlobal(probvar), newbounds[v]);
1272 scip->transprob, scip->origprob, scip->tree, scip->lp, scip->branchcand, scip->eventqueue, probvar,
1286 SCIPdebugMessage("can fix variable %s [%g, %g] to 0.0\n", SCIPvarGetName(probvar), SCIPvarGetLbGlobal(probvar), SCIPvarGetUbGlobal(probvar));
1291 scip->transprob, scip->origprob, scip->tree, scip->lp, scip->branchcand, scip->eventqueue, probvar, 0.0,
1306 SCIPdebugMessage("can tighten upper bound variable %s [%g, %g] to %g\n", SCIPvarGetName(probvar), SCIPvarGetLbGlobal(probvar), SCIPvarGetUbGlobal(probvar), newbounds[idx]);
1311 scip->transprob, scip->origprob, scip->tree, scip->lp, scip->branchcand, scip->eventqueue, probvar,
|