28 #define HEUR_NAME "rootsoldiving" 29 #define HEUR_DESC "LP diving heuristic that changes variable's objective values using root LP solution as guide" 30 #define HEUR_DISPCHAR 'S' 31 #define HEUR_PRIORITY -1005000 33 #define HEUR_FREQOFS 5 34 #define HEUR_MAXDEPTH -1 35 #define HEUR_TIMING SCIP_HEURTIMING_AFTERLPPLUNGE 36 #define HEUR_USESSUBSCIP FALSE 43 #define DEFAULT_MINRELDEPTH 0.0 44 #define DEFAULT_MAXRELDEPTH 1.0 45 #define DEFAULT_MAXLPITERQUOT 0.01 46 #define DEFAULT_MAXLPITEROFS 1000 47 #define DEFAULT_MAXSOLS -1 49 #define DEFAULT_DEPTHFAC 0.5 50 #define DEFAULT_DEPTHFACNOSOL 2.0 52 #define MINLPITER 10000 53 #define DEFAULT_ALPHA 0.9 100 assert(
scip != NULL);
104 assert(heurdata != NULL);
118 assert(heur != NULL);
123 assert(heurdata != NULL);
129 heurdata->nlpiterations = 0;
130 heurdata->nsuccess = 0;
142 assert(heur != NULL);
147 assert(heurdata != NULL);
190 assert(heur != NULL);
192 assert(
scip != NULL);
193 assert(result != NULL);
222 assert(heurdata != NULL);
231 maxdepth =
MAX(maxdepth, 30);
232 if( depth < heurdata->minreldepth*maxdepth || depth > heurdata->maxreldepth*maxdepth )
239 maxnlpiterations = (
SCIP_Longint)((1.0 + 10.0*(nsolsfound+1.0)/(ncalls+1.0)) * heurdata->maxlpiterquot * nlpiterations);
240 maxnlpiterations += heurdata->maxlpiterofs;
243 if( heurdata->nlpiterations >= maxnlpiterations )
247 maxnlpiterations =
MAX(maxnlpiterations, heurdata->nlpiterations +
MINLPITER);
259 maxdivedepth = (int)(heurdata->depthfacnosol * nvars);
261 maxdivedepth = (int)(heurdata->depthfac * nvars);
262 maxdivedepth =
MAX(maxdivedepth, 10);
271 for( i = 0; i < nbinvars + nintvars; i++ )
276 absstartobjval = ABS(absstartobjval);
277 absstartobjval =
MAX(absstartobjval, 1.0);
278 objstep = absstartobjval / 10.0;
292 SCIPdebugMsg(
scip,
"(node %" SCIP_LONGINT_FORMAT
") executing rootsoldiving heuristic: depth=%d, %d fractionals, dualbound=%g, maxnlpiterations=%" SCIP_LONGINT_FORMAT
", maxdivedepth=%d, LPobj=%g, objstep=%g\n",
299 alpha = heurdata->alpha;
302 startnlpcands = nlpcands;
305 || nlpcands <= startnlpcands - divedepth/2
306 || (divedepth < maxdivedepth && heurdata->nlpiterations < maxnlpiterations))
338 hardroundingidx = -1;
340 hardroundingoldbd = 0.0;
341 hardroundingnewbd = 0.0;
342 boundschanged =
FALSE;
344 SCIPdebugMsg(
scip,
"dive %d/%d, LP iter %" SCIP_LONGINT_FORMAT
"/%" SCIP_LONGINT_FORMAT
":\n", divedepth, maxdivedepth, heurdata->nlpiterations, maxnlpiterations);
354 for( i = 0; i < nbinvars + nintvars; i++ )
370 if( softroundings[i] != 0 && lpsolchanged )
380 boundschanged =
TRUE;
384 newobj = alpha * oldobj;
386 else if( solval <= rootsol[i] )
392 if( softroundings[i] <= -10 && hardroundingidx == -1 )
397 hardroundingdir = -1;
401 boundschanged =
TRUE;
404 newobj = alpha * oldobj + objstep;
412 if( softroundings[i] >= +10 && hardroundingidx == -1 )
417 hardroundingdir = +1;
421 boundschanged =
TRUE;
424 newobj = alpha * oldobj - objstep;
428 objchgvals[i] = newobj;
435 for( i = 0; i < nbinvars + nintvars; ++i )
440 SCIPdebugMsg(
scip,
" -> i=%d var <%s>, solval=%g, rootsol=%g, oldobj=%g, newobj=%g\n",
447 for( i = nbinvars + nintvars; i < nvars; i++ )
453 newobj = alpha * oldobj;
480 SCIPwarningMessage(
scip,
"Error while solving LP in Rootsoldiving heuristic; LP solve terminated with code <%d>\n", retcode);
494 else if( !boundschanged )
502 var = vars[hardroundingidx];
505 if( hardroundingdir == -1 )
517 hardroundingidx = -1;
525 SCIPdebugMsg(
scip,
"---> diving finished: lpsolstat = %d, depth %d/%d, LP iter %" SCIP_LONGINT_FORMAT
"/%" SCIP_LONGINT_FORMAT
"\n",
526 lpsolstat, divedepth, maxdivedepth, heurdata->nlpiterations, maxnlpiterations);
552 heurdata->nsuccess++;
586 assert(heur != NULL);
596 "heuristics/rootsoldiving/minreldepth",
597 "minimal relative depth to start diving",
600 "heuristics/rootsoldiving/maxreldepth",
601 "maximal relative depth to start diving",
604 "heuristics/rootsoldiving/maxlpiterquot",
605 "maximal fraction of diving LP iterations compared to node LP iterations",
608 "heuristics/rootsoldiving/maxlpiterofs",
609 "additional number of allowed LP iterations",
612 "heuristics/rootsoldiving/maxsols",
613 "total number of feasible solutions found up to which heuristic is called (-1: no limit)",
616 "heuristics/rootsoldiving/depthfac",
617 "maximal diving depth: number of binary/integer variables times depthfac",
620 "heuristics/rootsoldiving/depthfacnosol",
621 "maximal diving depth factor if no feasible solution was found yet",
624 "heuristics/rootsoldiving/alpha",
625 "soft rounding factor to fade out objective coefficients",
int SCIPgetNIntVars(SCIP *scip)
SCIP_RETCODE SCIPlinkLPSol(SCIP *scip, SCIP_SOL *sol)
SCIP_Longint SCIPgetNLPIterations(SCIP *scip)
SCIP_Real SCIPgetCutoffbound(SCIP *scip)
SCIP_Longint SCIPheurGetNBestSolsFound(SCIP_HEUR *heur)
SCIP_Longint SCIPgetNSolsFound(SCIP *scip)
#define DEFAULT_MAXRELDEPTH
SCIP_RETCODE SCIPsetHeurExit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXIT((*heurexit)))
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_RETCODE SCIPincludeHeurRootsoldiving(SCIP *scip)
SCIP_Real SCIPvarGetRootSol(SCIP_VAR *var)
int SCIPgetMaxDepth(SCIP *scip)
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
enum SCIP_Retcode SCIP_RETCODE
SCIP_RETCODE SCIPchgVarLbDive(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
struct SCIP_HeurData SCIP_HEURDATA
#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 SCIPfreeBufferArray(scip, ptr)
enum SCIP_LPSolStat SCIP_LPSOLSTAT
void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
#define SCIPallocBlockMemory(scip, ptr)
int SCIPgetNLPBranchCands(SCIP *scip)
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
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_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
#define DEFAULT_MAXLPITEROFS
SCIP_Bool SCIPisLPSolBasic(SCIP *scip)
SCIP_Real SCIPgetVarUbDive(SCIP *scip, SCIP_VAR *var)
static SCIP_DECL_HEUREXEC(heurExecRootsoldiving)
const char * SCIPheurGetName(SCIP_HEUR *heur)
SCIP_RETCODE SCIPsolveDiveLP(SCIP *scip, int itlim, SCIP_Bool *lperror, SCIP_Bool *cutoff)
SCIP_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURFREE((*heurfree)))
SCIP_Real SCIPgetDualbound(SCIP *scip)
const char * SCIPvarGetName(SCIP_VAR *var)
SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
SCIP_Longint SCIPheurGetNCalls(SCIP_HEUR *heur)
SCIP_Bool SCIPhasCurrentNodeLP(SCIP *scip)
#define DEFAULT_MINRELDEPTH
SCIP_Longint SCIPgetLastDivenode(SCIP *scip)
SCIP_Longint SCIPgetNNodeLPIterations(SCIP *scip)
#define SCIPallocBufferArray(scip, ptr, num)
LP diving heuristic that changes variables' objective values using root LP solution as guide...
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
static SCIP_DECL_HEURFREE(heurFreeRootsoldiving)
SCIP_RETCODE SCIProundSol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *success)
int SCIPgetDepth(SCIP *scip)
SCIP_RETCODE SCIPchgVarUbDive(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
static SCIP_DECL_HEUREXIT(heurExitRootsoldiving)
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
SCIP_RETCODE SCIPtrySol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
int SCIPgetNBinVars(SCIP *scip)
SCIP_Real SCIPgetLPObjval(SCIP *scip)
SCIP_RETCODE SCIPchgVarObjDive(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
#define DEFAULT_MAXLPITERQUOT
SCIP_RETCODE SCIPsetHeurInit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURINIT((*heurinit)))
SCIP_Bool SCIPisStopped(SCIP *scip)
SCIP_Real SCIPgetVarLbDive(SCIP *scip, SCIP_VAR *var)
SCIP_RETCODE SCIPstartDive(SCIP *scip)
static SCIP_DECL_HEURCOPY(heurCopyRootsoldiving)
SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURCOPY((*heurcopy)))
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
#define BMSclearMemoryArray(ptr, num)
SCIP_RETCODE SCIPendDive(SCIP *scip)
SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
SCIP_Longint SCIPgetNNodes(SCIP *scip)
SCIP_Real SCIPgetVarObjDive(SCIP *scip, 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_Real SCIPfloor(SCIP *scip, SCIP_Real val)
static SCIP_DECL_HEURINIT(heurInitRootsoldiving)
#define DEFAULT_DEPTHFACNOSOL
SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)