All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
heur_vbounds.c
Go to the documentation of this file.
17 * @brief LNS heuristic uses the variable lower and upper bounds to determine the search neighborhood
23 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
34 #define HEUR_DESC "LNS heuristic uses the variable lower and upper bounds to determine the search neighborhood"
44 #define DEFAULT_MINFIXINGRATE 0.5 /* minimum percentage of integer variables that have to be fixed */
45 #define DEFAULT_MINIMPROVE 0.01 /* factor by which vbounds heuristic should at least improve the incumbent */
48 #define DEFAULT_NODESQUOT 0.1 /* subproblem nodes in relation to nodes of the original problem */
50 #define DEFAULT_COPYCUTS TRUE /**< should all active cuts from the cutpool of the original scip be copied to
64 SCIP_VAR** impvars; /**< topological sorted variables with respect to the variable lower and upper
76 SCIP_Real minimprove; /**< factor by which vbounds heuristic should at least improve the incumbent */
159 /** perform depth-first-search from the given variable using the variable lower or upper bounds of the variable */
164 SCIP_HASHMAP* varPosMap, /**< mapping a variable to its position in the (used) variable array, or NULL */
169 int* nsortedvars, /**< pointer to store the number of already collects variables in the sorted variables array */
170 SCIP_Bool lowerbound /**< depth-first-search with respect to the variable lower bounds, otherwise variable upper bound */
209 /* we could not resolve the variable bound variable to one active variable, therefore, ignore this variable bound */
213 /* insert variable bound variable into the hash table since they are involved in later propagation */
216 SCIPdebugMessage("insert variable <%s> with position %d into the hash map\n", SCIPvarGetName(vbvar), *nusedvars);
226 SCIP_CALL( depthFirstSearch(scip, vbvar, varPosMap, usedvars, nusedvars, connected, sortedvars, nsortedvars, lowerbound) );
234 /* insert variable bound variable into the hash table since they are involve in the later propagation */
237 SCIPdebugMessage("insert variable <%s> with position %d into the hash map\n", SCIPvarGetName(var), *nusedvars);
246 /** create a topological sorted variable array of the given variables and stores if (needed) the involved variables into
249 * @note: for all arrays and the hash map (if requested) you need to allocate enough memory before calling this method
256 SCIP_HASHMAP* varPosMap, /**< mapping a variable to its position in the (used) variable array, or NULL */
261 SCIP_Bool lowerbound /**< topological sorted with respect to the variable lower bounds, otherwise variable upper bound */
279 SCIPdebugMessage("create topological sorted variable array with respect to variables %s bounds\n",
293 SCIP_CALL( SCIPhashtableCreate(&connected, SCIPblkmem(scip), hashsize, SCIPvarGetHashkey, SCIPvarIsHashkeyEq, SCIPvarGetHashkeyVal, NULL) );
295 /* detect isolated variables; mark all variables which have at least one entering or leaving arc as connected */
326 /* loop over all "connected" variable and find for each connected component a "almost" topological sorted version */
335 /* use depth first search to get a "almost" topological sorted variables for the connected component which
339 SCIP_CALL( depthFirstSearch(scip, vars[v], varPosMap, usedvars, nusedvars, connected, sortedvars, &nsortedvars, lowerbound) );
403 SCIP_CALL( createTopoSortedVars(scip, allvars, nallvars, NULL, vars, &nvars, lbvars, &nlbvars, TRUE) );
406 SCIP_CALL( createTopoSortedVars(scip, allvars, nallvars, NULL, vars, &nvars, ubvars, &nubvars, FALSE) );
409 SCIP_CALL( SCIPhashtableCreate(&collectedvars, SCIPblkmem(scip), SCIPcalcHashtableSize(nallvars), hashGetKeyVar, hashKeyEqVar, hashKeyValVar, NULL) );
425 if( SCIPisLE(scip, SCIPvarGetObj(ubvars[v]), 0.0) && !SCIPhashtableExists(collectedvars, ubvars[v]) )
461 if( nlbvars > nlbimpvars && nubvars > nubimpvars && nlbimpvars + nubimpvars >= heurdata->minfixingrate * nallvars )
464 SCIP_CALL( SCIPduplicateMemoryArray(scip, &heurdata->impvars, impvars, nlbimpvars + nubimpvars) );
509 /* for each variable in topological order: start at best bound (MINIMIZE: neg coeff --> ub, pos coeff: lb) */
546 SCIPdebugMessage("vbound heuristic found roundable primal solution: obj=%g\n", SCIPgetSolOrigObj(scip, sol));
569 /** creates a new solution for the original problem by copying the solution of the subproblem */
592 /* sub-SCIP may have more variables than the number of active (transformed) variables in the main SCIP
593 * since constraint copying may have required the copy of variables that are fixed in the main SCIP
650 nstallnodes = (SCIP_Longint)(nstallnodes * 3.0 * (SCIPheurGetNBestSolsFound(heur)+1.0)/(SCIPheurGetNCalls(heur) + 1.0));
651 nstallnodes -= 100 * SCIPheurGetNCalls(heur); /* count the setup costs for the sub-MIP as 100 nodes */
661 SCIPdebugMessage("skipping "HEUR_NAME": nstallnodes=%"SCIP_LONGINT_FORMAT", minnodes=%"SCIP_LONGINT_FORMAT"\n", nstallnodes, heurdata->minnodes);
668 SCIPdebugMessage("apply variable bounds heuristic at node %lld on %d variable lower bound and %d variable upper bounds\n",
678 SCIP_CALL( applyVboundsFixings(scip, heurdata, probvars, nlbvars, nubvars, newsol, &infeasible, result) );
725 /* substract the memory already used by the main SCIP and the estimated memory usage of external software */
732 /* abort if no time is left or not enough memory to create a copy of SCIP, including external memory usage */
763 /* employ a limit on the number of enforcement rounds in the quadratic constraint handlers; this fixes the issue that
764 * sometimes the quadratic constraint handler needs hundreds or thousands of enforcement rounds to determine the
765 * feasibility status of a single node without fractional branching candidates by separation (namely for uflquad
766 * instances); however, the solution status of the sub-SCIP might get corrupted by this; hence no decutions shall be
769 if( SCIPfindConshdlr(subscip, "quadratic") != NULL && !SCIPisParamFixed(subscip, "constraints/quadratic/enfolplimit") )
803 /* Errors in the LP solver should not kill the overall solving process, if the LP is just needed for a heuristic.
804 * Hence in optimized mode, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
812 SCIPwarningMessage(scip, "Error while presolving subMIP in vbounds heuristic; sub-SCIP terminated with code <%d>\n", retstat);
819 SCIPdebugMessage("vbounds heuristic presolved subproblem: %d vars, %d cons\n", SCIPgetNVars(subscip), SCIPgetNConss(subscip));
821 /* after presolving, we should have at least reached a certain fixing rate over ALL variables (including continuous)
830 SCIPdebugMessage("solving subproblem: nstallnodes=%"SCIP_LONGINT_FORMAT", maxnodes=%"SCIP_LONGINT_FORMAT"\n", nstallnodes, heurdata->maxnodes);
838 SCIPwarningMessage(scip, "Error while solving subMIP in vbounds heuristic; sub-SCIP terminated with code <%d>\n",retstat);
845 /* check, whether a solution was found; due to numerics, it might happen that not all solutions are feasible ->
914 /** solving process deinitialization method of primal heuristic (called before branch and bound process data is freed) */
980 SCIP_CALL( applyVbounds(scip, heur, heurdata, heurdata->impvars, heurdata->nlbimpvars, heurdata->nubimpvars, result) );
983 SCIP_CALL( applyVbounds(scip, heur, heurdata, heurdata->lbvars, heurdata->nlbvars, 0, result) );
986 SCIP_CALL( applyVbounds(scip, heur, heurdata, heurdata->ubvars, 0, heurdata->nubvars, result) );
|