31 #define HEUR_NAME "multistart" 32 #define HEUR_DESC "multistart heuristic for convex and nonconvex MINLPs" 33 #define HEUR_DISPCHAR 'm' 34 #define HEUR_PRIORITY -2100000 36 #define HEUR_FREQOFS 0 37 #define HEUR_MAXDEPTH -1 38 #define HEUR_TIMING SCIP_HEURTIMING_AFTERNODE 39 #define HEUR_USESSUBSCIP TRUE 41 #define DEFAULT_RANDSEED 131 42 #define DEFAULT_NRNDPOINTS 100 43 #define DEFAULT_MAXBOUNDSIZE 2e+4 44 #define DEFAULT_MAXITER 300 45 #define DEFAULT_MINIMPRFAC 0.05 46 #define DEFAULT_MINIMPRITER 10 47 #define DEFAULT_MAXRELDIST 0.15 48 #define DEFAULT_NLPMINIMPR 0.00 49 #define DEFAULT_GRADLIMIT 5e+6 50 #define DEFAULT_MAXNCLUSTER 3 51 #define DEFAULT_ONLYNLPS TRUE 55 #define MINIMPRFAC 0.95 57 #define GRADCOSTFAC_LINEAR 1.0 58 #define GRADCOSTFAC_QUAD 2.0 59 #define GRADCOSTFAC_NONLINEAR 3.0 99 assert(varindex !=
NULL);
106 #define getVarIndex(varindex,var) ((int)(size_t)SCIPhashmapGetImage((varindex), (void*)(var))) 132 assert(scip !=
NULL);
133 assert(rndpoints !=
NULL);
134 assert(nmaxrndpoints > 0);
135 assert(maxboundsize > 0.0);
136 assert(randnumgen !=
NULL);
137 assert(nstored !=
NULL);
145 for( niter = 0; niter < 3 * nmaxrndpoints && *nstored < nmaxrndpoints; ++niter )
147 for( i = 0; i < nvars; ++i )
153 val = (lb + ub) / 2.0;
181 assert(*nstored <= nmaxrndpoints);
182 SCIPdebugMsg(scip,
"found %d randomly generated points\n", *nstored);
202 assert(scip !=
NULL);
204 assert(minfeas !=
NULL);
205 assert(nlrows !=
NULL);
210 for( i = 0; i < nnlrows; ++i )
212 assert(nlrows[i] !=
NULL);
215 *minfeas =
MIN(*minfeas, tmp);
237 assert(scip !=
NULL);
238 assert(nlrow !=
NULL);
239 assert(varindex !=
NULL);
240 assert(exprint !=
NULL);
242 assert(norm !=
NULL);
316 *norm += SQR(grad[i]);
346 assert(varindex !=
NULL);
347 assert(exprinterpreter !=
NULL);
348 assert(point !=
NULL);
350 assert(minfeas !=
NULL);
351 assert(nlrows !=
NULL);
353 assert(nlrowgradcosts !=
NULL);
354 assert(gradcosts !=
NULL);
359 #ifdef SCIP_DEBUG_IMPROVEPOINT 360 printf(
"start minfeas = %e\n", *minfeas);
366 #ifdef SCIP_DEBUG_IMPROVEPOINT 367 printf(
"start point is feasible");
372 lastminfeas = *minfeas;
380 for( r = 0; r < maxiter &&
SCIPisFeasLT(scip, *minfeas, 0.0); ++r )
391 for( i = 0; i < nnlrows; ++i )
408 *gradcosts += nlrowgradcosts[i];
413 #ifdef SCIP_DEBUG_IMPROVEPOINT 414 printf(
"gradient vanished at current point -> stop\n");
420 scale = -feasibility / nlrownorm;
428 for( j = 0; j < nvars; ++j )
429 updatevec[j] += scale * grad[j];
431 assert(nviolnlrows > 0);
433 for( i = 0; i < nvars; ++i )
436 updatevec[i] =
SCIPgetSolVal(scip, point, vars[i]) + updatevec[i] / nviolnlrows;
447 if( r % minimpriter == 0 && r > 0 )
450 || (*minfeas-lastminfeas) /
MAX(
REALABS(*minfeas),
REALABS(lastminfeas)) < minimprfac )
452 lastminfeas = *minfeas;
457 #ifdef SCIP_DEBUG_IMPROVEPOINT 458 printf(
"niter=%d minfeas=%e\n", r, *minfeas);
483 assert(points !=
NULL);
484 assert(feasibilities !=
NULL);
486 assert(nusefulpoints !=
NULL);
490 minfeas = feasibilities[
npoints - 1];
505 assert(feasibilities[i] - minfeas + 1.0 > 0.0);
506 meanfeas *=
pow(feasibilities[i] - minfeas + 1.0, 1.0 /
npoints);
508 meanfeas += minfeas - 1.0;
515 && (feasibilities[i] <= 1.05 * meanfeas ||
SCIPisLE(scip, feasibilities[i],
MINFEAS)) )
558 lb = -maxboundsize / 2.0;
559 ub = +maxboundsize / 2.0;
563 lb = ub - maxboundsize;
567 ub = lb + maxboundsize;
571 solx =
MIN(
MAX(solx, lb), ub);
572 soly =
MIN(
MAX(soly, lb), ub);
574 distance +=
REALABS(solx - soly) /
MAX(1.0, ub - lb);
595 assert(points !=
NULL);
597 assert(clusteridx !=
NULL);
598 assert(ncluster !=
NULL);
599 assert(maxreldist >= 0.0);
600 assert(maxncluster >= 0);
604 clusteridx[i] = INT_MAX;
608 for( i = 0; i <
npoints && (*ncluster < maxncluster); ++i )
613 if( clusteridx[i] != INT_MAX )
617 clusteridx[i] = *ncluster;
619 for( j = i + 1; j <
npoints; ++j )
621 if( clusteridx[j] == INT_MAX &&
getRelDistance(scip, points[i], points[j], maxboundsize) <= maxreldist )
622 clusteridx[j] = *ncluster;
631 assert(clusteridx[i] >= 0);
632 assert(clusteridx[i] < *ncluster || clusteridx[i] == INT_MAX);
662 assert(points !=
NULL);
671 for( i = 0; i < nvars; ++i )
679 assert(points[p] !=
NULL);
688 SCIPdebugMsg(scip,
"rounding of refpoint successfully? %u\n", *success);
693 for( i = 0; i < nbinvars + nintvars; ++i )
733 assert(expr !=
NULL);
790 assert(scip !=
NULL);
791 assert(heur !=
NULL);
792 assert(result !=
NULL);
793 assert(heurdata !=
NULL);
801 if( heurdata->exprinterpreter ==
NULL )
819 for( i = 0; i < nnlrows; ++i )
830 bestobj, &nrndpoints) );
831 assert(nrndpoints >= 0);
833 if( nrndpoints == 0 )
839 gradlimit = heurdata->gradlimit == 0.0 ?
SCIPinfinity(scip) : heurdata->gradlimit;
845 heurdata->maxiter, heurdata->minimprfac, heurdata->minimpriter, &feasibilities[npoints], nlrowgradcosts,
848 gradlimit -= gradcosts;
849 SCIPdebugMsg(scip,
"improve point %d / %d gradlimit = %g\n", npoints, nrndpoints, gradlimit);
860 assert(nusefulpoints >= 0);
861 SCIPdebugMsg(scip,
"nusefulpoints = %d\n", nusefulpoints);
863 if( nusefulpoints == 0 )
867 heurdata->maxreldist, heurdata->maxncluster) );
868 assert(ncluster >= 0 && ncluster <= heurdata->maxncluster);
877 while( start < nusefulpoints && clusteridx[start] != INT_MAX && !
SCIPisStopped(scip) )
884 while( end < nusefulpoints && clusteridx[start] == clusteridx[end] )
887 assert(end - start > 0);
894 if( timelimit <= 1.0 )
896 SCIPdebugMsg(scip,
"not enough time left! (%g)\n", timelimit);
901 SCIP_CALL(
solveNLP(scip, heur, heurdata->heursubnlp, &points[start], end - start, -1LL, timelimit,
902 heurdata->nlpminimpr, &success) );
914 for( i = nrndpoints - 1; i >= 0 ; --i )
916 assert(points[i] !=
NULL);
954 if( heurdata->exprinterpreter !=
NULL )
971 assert( heur !=
NULL );
974 assert(heurdata !=
NULL);
991 assert( heur !=
NULL );
994 assert(heurdata !=
NULL);
995 assert(heurdata->randnumgen !=
NULL);
1008 assert( heur !=
NULL );
1011 assert(heurdata !=
NULL);
1051 assert(heur !=
NULL);
1061 "number of random points generated per execution call",
1065 "maximum variable domain size for unbounded variables",
1069 "number of iterations to reduce the maximum violation of a point",
1073 "minimum required improving factor to proceed in improvement of a single point",
1077 "number of iteration when checking the minimum improvement",
1081 "maximum distance between two points in the same cluster",
1085 "factor by which heuristic should at least improve the incumbent",
1089 "limit for gradient computations for all improvePoint() calls (0 for no limit)",
1093 "maximum number of considered clusters per heuristic call",
1097 "should the heuristic run only on continuous problems?",
enum SCIP_Result SCIP_RESULT
int SCIPgetNIntVars(SCIP *scip)
SCIP_RETCODE SCIPrandomCreate(SCIP_RANDNUMGEN **randnumgen, BMS_BLKMEM *blkmem, unsigned int initialseed)
int SCIPgetNNLPNlRows(SCIP *scip)
SCIP_Real SCIPgetSolvingTime(SCIP *scip)
SCIP_Bool SCIPisNLPConstructed(SCIP *scip)
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
methods to interpret (evaluate) an expression tree "fast"
#define DEFAULT_NLPMINIMPR
SCIP_Bool SCIPisFeasLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_RETCODE SCIPgetRealParam(SCIP *scip, const char *name, SCIP_Real *value)
static SCIP_RETCODE computeGradient(SCIP *scip, SCIP_NLROW *nlrow, SCIP_EXPRINT *exprint, SCIP_SOL *sol, SCIP_HASHMAP *varindex, SCIP_Real *grad, SCIP_Real *norm)
SCIPInterval pow(const SCIPInterval &x, const SCIPInterval &y)
static int getVarIndex(SCIP_HASHMAP *varindex, SCIP_VAR *var)
SCIP_RETCODE SCIPsetHeurExit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXIT((*heurexit)))
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
void SCIPsortDownRealPtr(SCIP_Real *realarray, void **ptrarray, int len)
#define DEFAULT_MAXNCLUSTER
SCIP_Real SCIPfeasRound(SCIP *scip, SCIP_Real val)
static SCIP_DECL_HEURINIT(heurInitMultistart)
SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
static SCIP_RETCODE improvePoint(SCIP *scip, SCIP_NLROW **nlrows, int nnlrows, SCIP_HASHMAP *varindex, SCIP_EXPRINT *exprinterpreter, SCIP_SOL *point, int maxiter, SCIP_Real minimprfac, int minimpriter, SCIP_Real *minfeas, SCIP_Real *nlrowgradcosts, SCIP_Real *gradcosts)
#define DEFAULT_MAXBOUNDSIZE
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
SCIP_Real SCIPinfinity(SCIP *scip)
enum SCIP_Retcode SCIP_RETCODE
SCIP_RETCODE SCIPexprintCompile(SCIP_EXPRINT *exprint, SCIP_EXPRTREE *tree)
int SCIPnlrowGetNQuadVars(SCIP_NLROW *nlrow)
SCIP_Real SCIPnlrowGetRhs(SCIP_NLROW *nlrow)
static SCIP_DECL_HEUREXEC(heurExecMultistart)
int SCIPnlrowGetNLinearVars(SCIP_NLROW *nlrow)
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)
SCIP_RETCODE SCIPgetNlRowSolActivity(SCIP *scip, SCIP_NLROW *nlrow, SCIP_SOL *sol, SCIP_Real *activity)
void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
static SCIP_RETCODE getMinFeas(SCIP *scip, SCIP_NLROW **nlrows, int nnlrows, SCIP_SOL *sol, SCIP_Real *minfeas)
#define SCIPfreeBufferArray(scip, ptr)
void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
#define SCIPallocBlockMemory(scip, ptr)
static SCIP_DECL_HEURCOPY(heurCopyMultistart)
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_VAR ** SCIPexprtreeGetVars(SCIP_EXPRTREE *tree)
SCIP_NLROW ** SCIPgetNLPNlRows(SCIP *scip)
int SCIPnlrowGetNQuadElems(SCIP_NLROW *nlrow)
static SCIP_DECL_HEURFREE(heurFreeMultistart)
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
void SCIPsortIntPtr(int *intarray, void **ptrarray, int len)
void SCIPrandomFree(SCIP_RANDNUMGEN **randnumgen)
SCIP_RETCODE SCIPcreateSolCopy(SCIP *scip, SCIP_SOL **sol, SCIP_SOL *sourcesol)
SCIP_VAR ** SCIPnlrowGetQuadVars(SCIP_NLROW *nlrow)
const char * SCIPheurGetName(SCIP_HEUR *heur)
SCIP_HEUR * SCIPfindHeur(SCIP *scip, const char *name)
#define DEFAULT_NRNDPOINTS
#define DEFAULT_MINIMPRFAC
static SCIP_RETCODE applyHeur(SCIP *scip, SCIP_HEUR *heur, SCIP_HEURDATA *heurdata, SCIP_RESULT *result)
SCIP_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURFREE((*heurfree)))
SCIP_RETCODE SCIPexprintCreate(BMS_BLKMEM *blkmem, SCIP_EXPRINT **exprint)
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
static int getExprtreeSize(SCIP_EXPRTREE *tree)
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
SCIP_Real SCIPgetSolTransObj(SCIP *scip, SCIP_SOL *sol)
int SCIPgetNNlpis(SCIP *scip)
static int getExprSize(SCIP_EXPR *expr)
int SCIPexprtreeGetNVars(SCIP_EXPRTREE *tree)
SCIP_QUADELEM * SCIPnlrowGetQuadElems(SCIP_NLROW *nlrow)
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
#define GRADCOSTFAC_LINEAR
static SCIP_DECL_HEUREXIT(heurExitMultistart)
SCIP_EXPR * SCIPexprtreeGetRoot(SCIP_EXPRTREE *tree)
#define GRADCOSTFAC_NONLINEAR
SCIP_Bool SCIPisHugeValue(SCIP *scip, SCIP_Real val)
static SCIP_RETCODE filterPoints(SCIP *scip, SCIP_SOL **points, SCIP_Real *feasibilities, int npoints, int *nusefulpoints)
#define SCIPallocBufferArray(scip, ptr, num)
SCIP_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
SCIP_EXPR ** SCIPexprGetChildren(SCIP_EXPR *expr)
SCIP_RETCODE SCIProundSol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *success)
SCIP_EXPRINTDATA * SCIPexprtreeGetInterpreterData(SCIP_EXPRTREE *tree)
int SCIPexprGetNChildren(SCIP_EXPR *expr)
unsigned int SCIPinitializeRandomSeed(SCIP *scip, int initialseedvalue)
#define DEFAULT_MINIMPRITER
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
static SCIP_RETCODE sampleRandomPoints(SCIP *scip, SCIP_SOL **rndpoints, int nmaxrndpoints, SCIP_Real maxboundsize, SCIP_RANDNUMGEN *randnumgen, SCIP_Real bestobj, int *nstored)
int SCIPgetNSols(SCIP *scip)
SCIP_RETCODE SCIPapplyHeurSubNlp(SCIP *scip, SCIP_HEUR *heur, SCIP_RESULT *result, SCIP_SOL *refpoint, SCIP_Longint itercontingent, SCIP_Real timelimit, SCIP_Real minimprove, SCIP_Longint *iterused, SCIP_SOL *resultsol)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
#define BMSclearMemory(ptr)
SCIP_RETCODE SCIPexprintGrad(SCIP_EXPRINT *exprint, SCIP_EXPRTREE *tree, SCIP_Real *varvals, SCIP_Bool new_varvals, SCIP_Real *val, SCIP_Real *gradient)
int SCIPgetNBinVars(SCIP *scip)
SCIP_Real SCIPrandomGetReal(SCIP_RANDNUMGEN *randnumgen, SCIP_Real minrandval, SCIP_Real maxrandval)
int SCIPgetNVars(SCIP *scip)
SCIP_EXPRTREE * SCIPnlrowGetExprtree(SCIP_NLROW *nlrow)
static SCIP_Real getRelDistance(SCIP *scip, SCIP_SOL *x, SCIP_SOL *y, SCIP_Real maxboundsize)
SCIP_SOL * SCIPgetBestSol(SCIP *scip)
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_RETCODE SCIPgetNlRowSolFeasibility(SCIP *scip, SCIP_NLROW *nlrow, SCIP_SOL *sol, SCIP_Real *feasibility)
NLP local search primal heuristic using sub-SCIPs.
SCIP_RETCODE SCIPsetHeurInit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURINIT((*heurinit)))
SCIP_VAR ** SCIPgetVars(SCIP *scip)
SCIP_Bool SCIPisStopped(SCIP *scip)
#define DEFAULT_GRADLIMIT
static SCIP_RETCODE clusterPointsGreedy(SCIP *scip, SCIP_SOL **points, int npoints, int *clusteridx, int *ncluster, SCIP_Real maxboundsize, SCIP_Real maxreldist, int maxncluster)
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_RETCODE SCIPincludeHeurMultistart(SCIP *scip)
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real * SCIPnlrowGetLinearCoefs(SCIP_NLROW *nlrow)
SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURCOPY((*heurcopy)))
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
SCIP_VAR ** SCIPnlrowGetLinearVars(SCIP_NLROW *nlrow)
SCIP_RETCODE SCIPexprintFree(SCIP_EXPRINT **exprint)
SCIP_RETCODE SCIPhashmapInsert(SCIP_HASHMAP *hashmap, void *origin, void *image)
#define BMSclearMemoryArray(ptr, num)
SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
#define DEFAULT_MAXRELDIST
SCIP_Real SCIPround(SCIP *scip, SCIP_Real val)
static SCIP_RETCODE solveNLP(SCIP *scip, SCIP_HEUR *heur, SCIP_HEUR *nlpheur, SCIP_SOL **points, int npoints, SCIP_Longint itercontingent, SCIP_Real timelimit, SCIP_Real minimprove, SCIP_Bool *success)
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 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)
multistart heuristic for convex and nonconvex MINLPs
SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)