All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
presol_components.c
Go to the documentation of this file.
29 * @todo solve all components with less than given size, count number of components with nodelimit reached;
30 * if all components could be solved within nodelimit (or all but x), continue solving components in
34 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
42 #define PRESOL_PRIORITY -9200000 /**< priority of the presolver (>= 0: before, < 0: after constraint handlers); combined with propagators */
43 #define PRESOL_MAXROUNDS -1 /**< maximal number of presolving rounds the presolver participates in (-1: no limit) */
44 #define PRESOL_DELAY TRUE /**< should presolver be delayed, if other presolvers found reductions? */
46 #define DEFAULT_WRITEPROBLEMS FALSE /**< should the single components be written as an .lp-file? */
47 #define DEFAULT_MAXINTVARS 500 /**< maximum number of integer (or binary) variables to solve a subproblem directly (-1: no solving) */
49 #define DEFAULT_INTFACTOR 1.0 /**< the weight of an integer variable compared to binary variables */
50 #define DEFAULT_RELDECREASE 0.2 /**< percentage by which the number of variables has to be decreased after the last component solving
52 #define DEFAULT_FEASTOLFACTOR 1.0 /**< default value for parameter to increase the feasibility tolerance in all sub-SCIPs */
69 SCIP_Real reldecrease; /** percentage by which the number of variables has to be decreased after the last component solving
75 int maxintvars; /** maximum number of integer (or binary) variables to solve a subproblem directly (-1: no solving) */
138 /** statistics: categorize the component with the given number of binary and integer variables */
153 /* check into which category the component belongs by looking at the number of discrete variables */
163 /* number of discrete variables greater than all limits, so component belongs to last category */
221 /** copies a connected component consisting of the given constraints and variables into a sub-SCIP
264 SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, "build sub-SCIP for component %d: %d vars (%d bin, %d int, %d cont), %d conss\n",
267 SCIPdebugMessage("build sub-SCIP for component %d: %d vars (%d bin, %d int, %d cont), %d conss\n",
271 /* stop if the problem has too many integer variables; only if the problems should be written we have to build it anyway */
272 if( presoldata->maxintvars != -1 && (nbinvars + presoldata->intfactor * nintvars > presoldata->maxintvars)
276 SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, "--> not created (too many integer variables)\n");
290 /* substract the memory already used by the main SCIP and the estimated memory usage of external software */
297 /* abort if no time is left or not enough memory to create a copy of SCIP, including external memory usage */
298 if( timelimit <= 0.0 || memorylimit <= (1.0 * nvars / SCIPgetNVars(scip)) * (1.0 * nconss / SCIPgetNConss(scip)) *
311 /* copy plugins, we omit pricers (because we do not run if there are active pricers) and dialogs */
358 SCIP_CALL( SCIPsetRealParam(subscip, "numerics/feastol", feastol * presoldata->feastolfactor) );
402 SCIP_CALL( SCIPgetConsCopy(scip, subscip, conss[i], &newcons, SCIPconsGetHdlr(conss[i]), varmap, consmap, name,
421 /* the following asserts are not true, because some aggregations in the original scip instance could not get resolved
422 * inside some constraints, so the copy (subscip) will have also some inactive variables which were copied
425 /* there might be less variables in the subscip, because variables might be cancelled out during copying constraint
432 /* In extended debug mode, we want to be informed if the number of variables was reduced during copying.
433 * This might happen, since the components presolver uses SCIPgetConsVars() and then SCIPgetActiveVars() to get the
434 * active representation, while SCIPgetConsCopy() might use SCIPgetProbvarLinearSum() and this might cancel out some
435 * of the active variables and cannot be avoided. However, we want to notice it and check whether the constraint
441 SCIPinfoMessage(scip, NULL, "copying component %d reduced number of variables: %d -> %d\n", compnr, nvars, SCIPgetNVars(subscip));
445 if( presoldata->maxintvars == -1 || (SCIPgetNBinVars(subscip) + presoldata->intfactor * SCIPgetNIntVars(subscip) <= presoldata->maxintvars) )
474 SCIPdebugMessage("--> solved to optimality: time=%.2f, solution is%s feasible\n", SCIPgetSolvingTime(subscip), feasible ? "" : " not");
498 /* checking a solution is done with a relative tolerance of feasibility epsilon, if we really want to
499 * change the bounds of the variables by fixing them, the old bounds must not be violated by more than
500 * the absolute epsilon; therefore, we change the fixing values, if needed, and mark that the solution
538 /* the solution value of at least one variable is feasible with a relative tolerance of feasibility epsilon,
539 * but infeasible with an absolute tolerance of epsilon; try to set the variables to the bounds and check
546 SCIPdebugMessage("solution violates bounds by more than epsilon, check the corrected solution...\n");
562 /* check the solution; integrality and bounds should be fulfilled and do not have to be checked */
578 SCIPdebugMessage("--> corrected solution has a different objective value (old=%16.9g, corrected=%16.9g)\n",
617 else if( SCIPgetStatus(subscip) == SCIP_STATUS_UNBOUNDED || SCIPgetStatus(subscip) == SCIP_STATUS_INFORUNBD )
627 /* transfer global fixings to the original problem; we can only do this, if we did not find a solution in the
628 * subproblem, because otherwise, the primal bound might lead to dual reductions that cannot be transferred to
629 * the original problem without also transferring the possibly suboptimal solution (which is currently not
644 SCIP_CALL( SCIPtightenVarLb(scip, vars[i], SCIPvarGetLbGlobal((SCIP_VAR*)SCIPhashmapGetImage(varmap, vars[i])), FALSE,
650 SCIP_CALL( SCIPtightenVarUb(scip, vars[i], SCIPvarGetUbGlobal((SCIP_VAR*)SCIPhashmapGetImage(varmap, vars[i])), FALSE,
656 SCIPdebugMessage("--> tightened %d bounds of variables due to global bounds in the sub-SCIP\n", ntightened);
678 int* firstvaridxpercons, /**< array to store for each constraint the index in the local vars array
747 /* it looks strange if returning the number of variables was successful but not returning the variables */
748 SCIPwarningMessage(scip, "constraint <%s> returned number of variables but returning variables failed\n", SCIPconsGetName(conss[c]));
754 /* check if returned variables are consistent with the number of variables that were returned */
783 /* we add only one directed edge, because the other direction is automatically added for component computation */
851 assert(v == 0 || conscomponents[v] == conscomponents[v-1] || conscomponents[v] == conscomponents[v-1]+1);
866 /* define file name depending on instance name, number of presolver calls and number of components */
880 SCIPinfoMessage(scip, file, "set terminal pdf\nset output \"%s.pdf\"\nunset xtics\nunset ytics\n\n", outname);
881 SCIPinfoMessage(scip, file, "unset border\nunset key\nset style fill solid 1.0 noborder\nset size ratio -1\n");
914 SCIPinfoMessage(scip, file, "%d %d 0.5\n", nvars - varidx[SCIPvarGetProbindex(var)], nconss - c);
947 int* firstvaridxpercons, /**< array with index of first variable in vars array for each constraint */
979 /* hashmap mapping from original constraints to constraints in the sub-SCIPs (for performance reasons) */
995 SCIP_CALL( printStructure(scip, vars, conss, components, conscomponent, nvars, nconss, ncomponents) );
1042 /* there is no constraint to connect variables, so there should be only one variable in the component */
1061 SCIPinfoMessage(scip, NULL, "presol components: fix variable <%s>[%g,%g] (locks [%d, %d]) to %g because it occurs in no constraint\n",
1065 SCIPdebugMessage("presol components: fix variable <%s>[%g,%g] (locks [%d, %d]) to %g because it occurs in no constraint\n",
1082 SCIPdebugMessage("strange?! components with single variable variable <%s>[%g,%g] (locks [%d, %d]) that won't be fixed due to locks\n",
1100 SCIPinfoMessage(scip, NULL, "presol component detected component with a single constraint:\n");
1107 SCIP_CALL( copyAndSolveComponent(scip, presoldata, consmap, comp, compconss, ncompconss, compvars,
1179 /* the presolver should be executed only if it didn't run so far or the number of variables was significantly reduced
1238 * that value is used as an estimate of the number of arcs incident to the variable's node in the digraph
1294 compsize[c] = (int)((1000 * (nbinvars + presoldata->intfactor * nintvars) + (950.0 * ncontvars)/nvars));
1300 /* now, we need the reverse direction, i.e., for each component number, we store its new number
1310 /* create subproblems from independent components and solve them in dependence of their size */
1311 SCIP_CALL( splitProblem(scip, presoldata, conss, vars, fixvals, nconss, nvars, components, ncomponents, firstvaridxpercons,
1343 SCIPdebugMessage("%d components, %d solved, %d deleted constraints, %d deleted variables, result = %d\n",
1346 SCIPstatisticMessage("%d components, %d solved, %d deleted constraints, %d deleted variables, result = %d\n",
1441 SCIP_CALL( SCIPincludePresolBasic(scip, &presol, PRESOL_NAME, PRESOL_DESC, PRESOL_PRIORITY, PRESOL_MAXROUNDS,
1444 /* currently, the components presolver is not copied; if a copy callback is added, we need to avoid recursion
1462 "maximum number of integer (or binary) variables to solve a subproblem directly (-1: unlimited)",
1474 "percentage by which the number of variables has to be decreased after the last component solving to allow running again (1.0: do not run again)",
|