32 #define HEUR_NAME "localbranching" 33 #define HEUR_DESC "local branching heuristic by Fischetti and Lodi" 34 #define HEUR_DISPCHAR 'L' 35 #define HEUR_PRIORITY -1102000 37 #define HEUR_FREQOFS 0 38 #define HEUR_MAXDEPTH -1 39 #define HEUR_TIMING SCIP_HEURTIMING_AFTERNODE 40 #define HEUR_USESSUBSCIP TRUE 42 #define DEFAULT_NEIGHBORHOODSIZE 18 43 #define DEFAULT_NODESOFS 1000 44 #define DEFAULT_MAXNODES 10000 45 #define DEFAULT_MINIMPROVE 0.01 46 #define DEFAULT_MINNODES 1000 47 #define DEFAULT_NODESQUOT 0.05 48 #define DEFAULT_LPLIMFAC 1.5 49 #define DEFAULT_NWAITINGNODES 200 50 #define DEFAULT_USELPROWS FALSE 52 #define DEFAULT_COPYCUTS TRUE 55 #define DEFAULT_BESTSOLLIMIT 3 56 #define DEFAULT_USEUCT FALSE 59 #define EVENTHDLR_NAME "Localbranching" 60 #define EVENTHDLR_DESC "LP event handler for " HEUR_NAME " heuristic" 64 #define WAITFORNEWSOL 1 86 int curneighborhoodsize;
88 int emptyneighborhoodsize;
128 assert( bestsol != NULL );
135 lhs = (
SCIP_Real)heurdata->emptyneighborhoodsize + 1.0;
136 rhs = (
SCIP_Real)heurdata->curneighborhoodsize;
139 for( i = 0; i < nbinvars; i++ )
155 consvars[i] = subvars[i];
161 lhs, rhs,
TRUE,
TRUE,
TRUE,
TRUE,
TRUE,
FALSE,
FALSE,
TRUE,
TRUE,
FALSE) );
189 assert( scip != NULL );
190 assert( subscip != NULL );
191 assert( subvars != NULL );
192 assert( subsol != NULL );
229 assert(eventhdlr != NULL);
230 assert(eventdata != NULL);
232 assert(event != NULL);
236 assert(heurdata != NULL);
257 assert(
scip != NULL);
258 assert(heur != NULL);
273 assert( heur != NULL );
274 assert(
scip != NULL );
278 assert( heurdata != NULL );
294 assert( heur != NULL );
295 assert(
scip != NULL );
299 assert( heurdata != NULL );
303 heurdata->lastsol = NULL;
304 heurdata->usednodes = 0;
305 heurdata->curneighborhoodsize = heurdata->neighborhoodsize;
306 heurdata->curminnodes = heurdata->minnodes;
307 heurdata->emptyneighborhoodsize = 0;
336 assert(scip != NULL);
337 assert(subscip != NULL);
338 assert(heur != NULL);
341 assert(heurdata != NULL);
352 heurdata->copycuts, &success, NULL) );
354 SCIPdebugMsg(scip,
"Copying SCIP was %ssuccessful.\n", success ?
"" :
"not ");
366 if( eventhdlr == NULL )
376 for (i = 0; i < nvars; ++i)
397 heurdata->nodelimit = nsubnodes;
474 cutoff = MIN(upperbound, cutoff );
478 if( !heurdata->uselprows )
480 assert(eventhdlr != NULL);
487 SCIPdebugMsg(scip,
"solving local branching subproblem with neighborhoodsize %d and maxnodes %" SCIP_LONGINT_FORMAT
"\n",
488 heurdata->curneighborhoodsize, nsubnodes);
497 if( !heurdata->uselprows )
499 assert(eventhdlr != NULL);
508 SCIPdebugMsg(scip,
"local branching used %" SCIP_LONGINT_FORMAT
"/%" SCIP_LONGINT_FORMAT
" nodes\n",
523 for( i = 0; i < nsubsols && !success; ++i )
546 heurdata->callstatus =
EXECUTE;
547 heurdata->curneighborhoodsize = (heurdata->emptyneighborhoodsize + heurdata->curneighborhoodsize)/2;
548 heurdata->curminnodes *= 2;
549 SCIPdebugMsg(scip,
" -> node limit reached: reduced neighborhood to %d, increased minnodes to %d\n",
550 heurdata->curneighborhoodsize, heurdata->curminnodes);
551 if( heurdata->curneighborhoodsize <= heurdata->emptyneighborhoodsize )
554 SCIPdebugMsg(scip,
" -> new neighborhood was already proven to be empty: wait for new solution\n");
560 heurdata->emptyneighborhoodsize = heurdata->curneighborhoodsize;
561 heurdata->curneighborhoodsize += heurdata->curneighborhoodsize/2;
562 heurdata->curneighborhoodsize =
MAX(heurdata->curneighborhoodsize, heurdata->emptyneighborhoodsize + 2);
563 heurdata->callstatus =
EXECUTE;
564 SCIPdebugMsg(scip,
" -> neighborhood is empty: increased neighborhood to %d\n", heurdata->curneighborhoodsize);
604 assert(heur != NULL);
605 assert(
scip != NULL);
606 assert(result != NULL);
612 assert( heurdata != NULL );
625 assert(bestsol != NULL);
640 if( heurdata->lastsol != bestsol )
642 heurdata->curneighborhoodsize = heurdata->neighborhoodsize;
643 heurdata->curminnodes = heurdata->minnodes;
644 heurdata->emptyneighborhoodsize = 0;
645 heurdata->callstatus =
EXECUTE;
646 heurdata->lastsol = bestsol;
661 maxnnodes += heurdata->nodesofs;
664 nsubnodes = maxnnodes - heurdata->usednodes;
665 nsubnodes = MIN(nsubnodes, heurdata->maxnodes);
668 if( nsubnodes < heurdata->curminnodes )
715 assert(heur != NULL);
724 "number of nodes added to the contingent of the total nodes",
728 "radius (using Manhattan metric) of the incumbent's neighborhood to be searched",
732 "contingent of sub problem nodes in relation to the number of nodes of the original problem",
736 "factor by which the limit on the number of LP depends on the node limit",
740 "minimum number of nodes required to start the subproblem",
744 "maximum number of nodes to regard in the subproblem",
748 "number of nodes without incumbent change that heuristic should wait",
752 "factor by which localbranching should at least improve the incumbent",
756 "should subproblem be created out of the rows in the LP rows?",
760 "if uselprows == FALSE, should all active cuts from cutpool be copied to constraints in subproblem?",
764 "limit on number of improving incumbent solutions in sub-CIP",
768 "should uct node selection be used at the beginning of the search?",
enum SCIP_Result SCIP_RESULT
SCIP_Bool SCIPsolIsOriginal(SCIP_SOL *sol)
#define SCIP_EVENTTYPE_LPSOLVED
SCIP_RETCODE SCIPsetSeparating(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
#define DEFAULT_NODESQUOT
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
SCIP_Longint SCIPheurGetNBestSolsFound(SCIP_HEUR *heur)
int SCIPgetNOrigVars(SCIP *scip)
static SCIP_RETCODE addLocalBranchingConstraint(SCIP *scip, SCIP *subscip, SCIP_VAR **subvars, SCIP_HEURDATA *heurdata)
SCIP_RETCODE SCIPincludeEventhdlrBasic(SCIP *scip, SCIP_EVENTHDLR **eventhdlrptr, const char *name, const char *desc, SCIP_DECL_EVENTEXEC((*eventexec)), SCIP_EVENTHDLRDATA *eventhdlrdata)
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
SCIP_SOL ** SCIPgetSols(SCIP *scip)
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
#define DEFAULT_NWAITINGNODES
SCIP_RETCODE SCIPcopyLimits(SCIP *sourcescip, SCIP *targetscip)
int SCIPsnprintf(char *t, int len, const char *s,...)
enum SCIP_Retcode SCIP_RETCODE
SCIP_RETCODE SCIPsetPresolving(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
SCIP_BRANCHRULE * SCIPfindBranchrule(SCIP *scip, const char *name)
static SCIP_DECL_HEURINIT(heurInitLocalbranching)
struct SCIP_HeurData SCIP_HEURDATA
SCIP_RETCODE SCIPincludeHeurLocalbranching(SCIP *scip)
#define SCIPfreeBlockMemory(scip, ptr)
SCIP_RETCODE SCIPincludeHeurBasic(SCIP *scip, SCIP_HEUR **heur, const char *name, const char *desc, char dispchar, int priority, int freq, int freqofs, int maxdepth, SCIP_HEURTIMING timingmask, SCIP_Bool usessubscip, SCIP_DECL_HEUREXEC((*heurexec)), SCIP_HEURDATA *heurdata)
#define DEFAULT_BESTSOLLIMIT
void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
static SCIP_DECL_HEUREXEC(heurExecLocalbranching)
#define SCIPfreeBufferArray(scip, ptr)
SCIP_RETCODE SCIPcreate(SCIP **scip)
void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
#define SCIPallocBlockMemory(scip, ptr)
SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
SCIP_RETCODE SCIPprintStatistics(SCIP *scip, FILE *file)
const char * SCIPgetProbName(SCIP *scip)
SCIP_RETCODE SCIPsolve(SCIP *scip)
const char * SCIPheurGetName(SCIP_HEUR *heur)
SCIP_Bool SCIPisParamFixed(SCIP *scip, const char *name)
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURFREE((*heurfree)))
SCIP_RETCODE SCIPgetSolVals(SCIP *scip, SCIP_SOL *sol, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
static SCIP_RETCODE setupAndSolveSubscipLocalbranching(SCIP *scip, SCIP *subscip, SCIP_HEUR *heur, SCIP_Longint nsubnodes, SCIP_RESULT *result)
SCIP_RETCODE SCIPsetBoolParam(SCIP *scip, const char *name, SCIP_Bool value)
SCIP_STATUS SCIPgetStatus(SCIP *scip)
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Local branching heuristic according to Fischetti and Lodi.
struct SCIP_EventData SCIP_EVENTDATA
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
SCIP_HEUR * SCIPsolGetHeur(SCIP_SOL *sol)
SCIP_Real SCIPgetLowerbound(SCIP *scip)
#define DEFAULT_NEIGHBORHOODSIZE
SCIP_Longint SCIPheurGetNCalls(SCIP_HEUR *heur)
#define SCIPallocBufferArray(scip, ptr, num)
public data structures and miscellaneous methods
SCIP_RETCODE SCIPcatchEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
static SCIP_RETCODE createNewSol(SCIP *scip, SCIP *subscip, SCIP_VAR **subvars, SCIP_HEUR *heur, SCIP_SOL *subsol, SCIP_Bool *success)
SCIP_RETCODE SCIPsetObjlimit(SCIP *scip, SCIP_Real objlimit)
#define DEFAULT_MINIMPROVE
SCIP_RETCODE SCIPtrySolFree(SCIP *scip, SCIP_SOL **sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
SCIP_RETCODE SCIPsetIntParam(SCIP *scip, const char *name, int value)
SCIP_RETCODE SCIPdropEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
int SCIPgetNSols(SCIP *scip)
SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
Constraint handler for linear constraints in their most general form, .
static SCIP_DECL_HEURFREE(heurFreeLocalbranching)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
int SCIPgetNBinVars(SCIP *scip)
SCIP_RETCODE SCIPsetCharParam(SCIP *scip, const char *name, char value)
SCIP_RETCODE SCIPcreateConsLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
static SCIP_DECL_EVENTEXEC(eventExecLocalbranching)
SCIP_SOL * SCIPgetBestSol(SCIP *scip)
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
SCIP_RETCODE SCIPsetHeurInit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURINIT((*heurinit)))
SCIP_NODESEL * SCIPfindNodesel(SCIP *scip, const char *name)
SCIP_RETCODE SCIPcopyLargeNeighborhoodSearch(SCIP *sourcescip, SCIP *subscip, SCIP_HASHMAP *varmap, const char *suffix, SCIP_VAR **fixedvars, SCIP_Real *fixedvals, int nfixedvars, SCIP_Bool uselprows, SCIP_Bool copycuts, SCIP_Bool *success, SCIP_Bool *valid)
SCIP_Bool SCIPisStopped(SCIP *scip)
static SCIP_DECL_HEURCOPY(heurCopyLocalbranching)
SCIP_RETCODE SCIPcheckCopyLimits(SCIP *sourcescip, SCIP_Bool *success)
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
SCIP_RETCODE SCIPsetSolVals(SCIP *scip, SCIP_SOL *sol, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
SCIP_RETCODE SCIPtransformProb(SCIP *scip)
SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURCOPY((*heurcopy)))
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPsumepsilon(SCIP *scip)
SCIP_RETCODE SCIPinterruptSolve(SCIP *scip)
SCIP_Real SCIPgetUpperbound(SCIP *scip)
#define DEFAULT_USELPROWS
#define SCIP_CALL_ABORT(x)
SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
SCIP_Longint SCIPgetNNodes(SCIP *scip)
SCIP_Longint SCIPgetNLPs(SCIP *scip)
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
SCIP_RETCODE SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
SCIP_RETCODE SCIPsetSubscipsOff(SCIP *scip, SCIP_Bool quiet)
SCIP_RETCODE SCIPsetLongintParam(SCIP *scip, const char *name, SCIP_Longint value)
SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
SCIP_RETCODE SCIPfree(SCIP **scip)
SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
SCIP_Longint SCIPgetSolNodenum(SCIP *scip, SCIP_SOL *sol)