cutsel_ensemble.c
Go to the documentation of this file.
30 * @todo separator hard limit on density is inappropriate for MINLP. Need to relax hard limit in case of all cuts dense
31 * @todo penalising via parallelism is overly costly if many cuts. Hash cuts before and find appropriate groups?
34 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
53 #define DEFAULT_DIRCUTOFFDISTWEIGHT 0.0 /**< weight of normed-directed cutoff distance in score calculation */
55 #define DEFAULT_INTSUPPORTWEIGHT 0.45 /**< weight of integral support in cut score calculation */
56 #define DEFAULT_EXPIMPROVWEIGHT 0.1 /**< weight of normed-expected improvement in cut score calculation */
57 #define DEFAULT_PSCOSTWEIGHT 0.75 /**< weight of normalised pseudo-costs in cut score calculation */
58 #define DEFAULT_NLOCKSWEIGHT 0.25 /**< weight of normalised number of locks in cut score calculation */
60 #define DEFAULT_SPARSITYENDBONUS 0.2 /**< the density at which a cut no longer receives additional score */
62 #define DEFAULT_MAXCOEFRATIOBONUS 10000 /**< maximum coefficient ratio of cut for which numeric bonus is given */
63 #define DEFAULT_PENALISELOCKS TRUE /**< whether having less locks should be rewarded instead of more */
64 #define DEFAULT_PENALISEOBJPARAL TRUE /**< whether objective parallelism should be penalised not rewarded */
65 #define DEFAULT_FILTERPARALCUTS FALSE /**< should cuts be filtered so no two parallel cuts are added */
66 #define DEFAULT_MAXPARAL 0.95 /**< threshold for when two cuts are considered parallel to each other */
67 #define DEFAULT_PENALISEPARALCUTS TRUE /**< should two parallel cuts be penalised instead of outright filtered */
68 #define DEFAULT_PARALPENALTY 0.25 /**< penalty for weaker of two parallel cuts if penalising parallel cuts */
69 #define DEFAULT_FILTERDENSECUTS TRUE /**< should cuts over a given density threshold be filtered */
71 #define DEFAULT_MAXNONZEROROOTROUND 4.5 /**< max nonzeros per round (root). Gets multiplied by num LP cols */
72 #define DEFAULT_MAXNONZEROTREEROUND 9.5 /**< max nonzeros per round (tree). Gets multiplied by num LP cols */
73 #define DEFAULT_MAXCUTS 200 /**< maximum number of cuts that can be considered by this cut selector */
74 #define DEFAULT_MAXNUMVARS 50000 /**< maximum number of variables that a problem can have while calling this cut selector */
87 SCIP_Real dircutoffdistweight;/**< weight of normed-directed cutoff distance in cut score calculation */
88 SCIP_Real expimprovweight; /**< weight of normed-expected improvement in cut score calculation */
96 SCIP_Real paralpenalty; /**< penalty for weaker of two parallel cuts if penalising parallel cuts */
98 SCIP_Real maxnonzerorootround;/**< max nonzeros per round (root). Gets multiplied by num LP cols */
99 SCIP_Real maxnonzerotreeround;/**< max nonzeros per round (tree). Gets multiplied by num LP cols */
101 SCIP_Bool penaliseparalcuts; /**< should two parallel cuts be penalised instead of outright filtered */
103 SCIP_Bool penaliselocks; /**< whether the number of locks should be penalised instead of rewarded */
107 int maxnumvars; /**< maximum number of variables that a problem can have while calling this cut selector */
115 /** returns the maximum score of cuts; if scores is not NULL, then stores the individual score of each cut in scores */
140 /* Get the solution that we use for directed cutoff distance calculations. Get the number of columns too */
188 /* Get the L1 distance from the projection onto the cut and the LP solution in the variable direction */
214 /* Get the arrays / maximums of directed cutoff distance, efficacy, and expected improvement values. */
274 dynamism = cutseldata->maxcoefratiobonus >= maxcutval / mincutval ? cutseldata->goodnumericsbonus : 0.0;
282 scaleddcd = cutseldata->dircutoffdistweight * SQR(LOG1P(dcds[i]) / LOG1P(maxdcd)); /*lint !e666*/
303 scaledeff = (cutseldata->efficacyweight + cutseldata->dircutoffdistweight) * SQR(LOG1P(effs[i]) / LOG1P(maxeff)); /*lint !e666*/
307 score = scaledeff + scaleddcd + scaledexp + objparallelism + intsupport + density + dynamism + pscost + cutlock;
325 /** move the cut with the highest score to the first position in the array; there must be at least one cut */
357 * w.r.t the given cut; moves filtered cuts to the end of the array and returns number of selected cuts */
397 SCIP_Real paralpenalty /**< penalty for weaker of two parallel cuts if penalising parallel cuts */
567 SCIP_CALL( SCIPincludeCutselBasic(scip, &cutsel, CUTSEL_NAME, CUTSEL_DESC, CUTSEL_PRIORITY, cutselSelectEnsemble,
580 SCIP_CALL( SCIPaddRealParam(scip, "cutselection/" CUTSEL_NAME "/efficacyweight", "weight of normed-efficacy in cut "
581 "score calculation", &cutseldata->efficacyweight, FALSE, DEFAULT_EFFICACYWEIGHT, 0.0, SCIP_INVALID/10.0, NULL,
584 SCIP_CALL( SCIPaddRealParam(scip, "cutselection/" CUTSEL_NAME "/dircutoffdistweight", "weight of normed-directed "
588 SCIP_CALL( SCIPaddRealParam(scip, "cutselection/" CUTSEL_NAME "/objparalweight", "weight of objective parallelism "
589 "in cut score calculation", &cutseldata->objparalweight, FALSE, DEFAULT_OBJPARALWEIGHT, 0.0, SCIP_INVALID/10.0,
592 SCIP_CALL( SCIPaddRealParam(scip, "cutselection/" CUTSEL_NAME "/intsupportweight", "weight of integral support in "
596 SCIP_CALL( SCIPaddRealParam(scip, "cutselection/" CUTSEL_NAME "/expimprovweight", "weight of normed-expected obj "
597 "improvement in cut score calculation", &cutseldata->expimprovweight, FALSE, DEFAULT_EXPIMPROVWEIGHT, 0.0,
600 SCIP_CALL( SCIPaddRealParam(scip, "cutselection/" CUTSEL_NAME "/minscore", "minimum score s.t. a cut can be added",
601 &cutseldata->minscore, FALSE, DEFAULT_MINSCORE, -SCIP_INVALID/10.0, SCIP_INVALID/10.0, NULL, NULL) );
603 SCIP_CALL( SCIPaddRealParam(scip, "cutselection/" CUTSEL_NAME "/pscostweight", "weight of normed-pseudo-costs in "
604 "cut score calculation", &cutseldata->pscostweight, FALSE, DEFAULT_PSCOSTWEIGHT, 0.0, SCIP_INVALID/10.0, NULL,
607 SCIP_CALL( SCIPaddRealParam(scip, "cutselection/" CUTSEL_NAME "/locksweight", "weight of normed-num-locks in cut "
608 "score calculation", &cutseldata->locksweight, FALSE, DEFAULT_NLOCKSWEIGHT, 0.0, SCIP_INVALID/10.0, NULL,
611 SCIP_CALL( SCIPaddRealParam(scip, "cutselection/" CUTSEL_NAME "/maxsparsitybonus", "weight of maximum sparsity "
612 "reward in cut score calculation", &cutseldata->maxsparsitybonus, FALSE, DEFAULT_MAXSPARSITYBONUS, 0.0,
615 SCIP_CALL( SCIPaddRealParam(scip, "cutselection/" CUTSEL_NAME "/goodnumericsbonus", "weight of good numerics bonus "
619 SCIP_CALL( SCIPaddRealParam(scip, "cutselection/" CUTSEL_NAME "/endsparsitybonus", "max sparsity value for which a "
620 "bonus is applied in cut score calculation", &cutseldata->endsparsitybonus, FALSE, DEFAULT_SPARSITYENDBONUS,
623 SCIP_CALL( SCIPaddRealParam(scip, "cutselection/" CUTSEL_NAME "/maxparal", "threshold for when two cuts are "
624 "considered parallel to each other", &cutseldata->maxparal, FALSE, DEFAULT_MAXPARAL, 0.0, 1.0, NULL, NULL) );
626 SCIP_CALL( SCIPaddRealParam(scip, "cutselection/" CUTSEL_NAME "/paralpenalty", "penalty for weaker of two parallel "
630 SCIP_CALL( SCIPaddRealParam(scip, "cutselection/" CUTSEL_NAME "/maxcutdensity", "max allowed cut density if "
631 "filtering dense cuts", &cutseldata->maxcutdensity, TRUE, DEFAULT_MAXCUTDENSITY, 0.0, 1.0, NULL, NULL) );
633 SCIP_CALL( SCIPaddRealParam(scip, "cutselection/" CUTSEL_NAME "/maxnonzerorootround", "max non-zeros per round "
637 SCIP_CALL( SCIPaddRealParam(scip, "cutselection/" CUTSEL_NAME "/maxnonzerotreeround", "max non-zeros per round "
641 SCIP_CALL( SCIPaddBoolParam(scip, "cutselection/" CUTSEL_NAME "/filterparalcuts", "should cuts be filtered so no "
642 "two parallel cuts are added", &cutseldata->filterparalcuts, FALSE, DEFAULT_FILTERPARALCUTS, NULL, NULL) );
644 SCIP_CALL( SCIPaddBoolParam(scip, "cutselection/" CUTSEL_NAME "/penaliseparalcuts", "should two parallel cuts be "
645 "penalised instead of outright filtered", &cutseldata->penaliseparalcuts, TRUE, DEFAULT_PENALISEPARALCUTS,
648 SCIP_CALL( SCIPaddBoolParam(scip, "cutselection/" CUTSEL_NAME "/filterdensecuts", "should cuts over a given density "
649 "threshold be filtered", &cutseldata->filterdensecuts, TRUE, DEFAULT_FILTERDENSECUTS, NULL, NULL) );
651 SCIP_CALL( SCIPaddBoolParam(scip, "cutselection/" CUTSEL_NAME "/penaliselocks", "should the number of locks be "
652 "penalised instead of rewarded", &cutseldata->penaliselocks, TRUE, DEFAULT_PENALISELOCKS, NULL, NULL) );
654 SCIP_CALL( SCIPaddBoolParam(scip, "cutselection/" CUTSEL_NAME "/penaliseobjparal", "should objective parallelism "
655 "be penalised instead of rewarded", &cutseldata->penaliseobjparal, TRUE, DEFAULT_PENALISEOBJPARAL, NULL, NULL)
658 SCIP_CALL( SCIPaddIntParam(scip, "cutselection/" CUTSEL_NAME "/maxcoefratiobonus", "max coefficient ratio for "
659 "which numeric bonus is applied.", &cutseldata->maxcoefratiobonus, TRUE, DEFAULT_MAXCOEFRATIOBONUS, 1, 1000000,
662 SCIP_CALL( SCIPaddIntParam(scip, "cutselection/" CUTSEL_NAME "/maxcuts", "max number of cuts such that cut "
665 SCIP_CALL( SCIPaddIntParam(scip, "cutselection/" CUTSEL_NAME "/maxnumvars", "max number of variables such that cut "
666 "selector is applied.", &cutseldata->maxnumvars, TRUE, DEFAULT_MAXNUMVARS, 1, 1000000, NULL, NULL) );
673 * This is the selection method of the ensemble cut selector. It uses a weighted sum of normalised efficacy,
676 * In addition to the weighted sum score, there are optionally parallelism-based filtering and penalties,
679 * The input cuts array gets re-sorted such that the selected cuts come first and the remaining ones are the end.
729 ncuts = penaliseWithParallelism(scip, forcedcuts[i], cuts, scores, ncuts, cutseldata->maxparal, cutseldata->paralpenalty);
743 /* if the best cut of the remaining cuts is considered bad, we discard it and all remaining cuts */
756 /* move the pointers to the next position and filter the remaining cuts to enforce the maximum parallelism constraint */
764 ncuts = penaliseWithParallelism(scip, selectedcut, cuts, scores, ncuts, cutseldata->maxparal, cutseldata->paralpenalty);
SCIP_RETCODE SCIPsetCutselExit(SCIP *scip, SCIP_CUTSEL *cutsel, SCIP_DECL_CUTSELEXIT((*cutselexit)))
Definition: scip_cutsel.c:173
void SCIPfreeRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen)
Definition: scip_randnumgen.c:79
Definition: struct_scip.h:69
Definition: type_result.h:58
Definition: struct_var.h:207
Definition: struct_misc.h:268
SCIP_RETCODE SCIPselectCutsEnsemble(SCIP *scip, SCIP_ROW **cuts, SCIP_ROW **forcedcuts, SCIP_CUTSELDATA *cutseldata, SCIP_Bool root, int ncuts, int nforcedcuts, int maxselectedcuts, int *nselectedcuts)
Definition: cutsel_ensemble.c:681
SCIP_Real SCIPgetCutLPSolCutoffDistance(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *cut)
Definition: scip_cut.c:72
void SCIPcutselSetData(SCIP_CUTSEL *cutsel, SCIP_CUTSELDATA *cutseldata)
Definition: cutsel.c:429
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)
Definition: scip_param.c:83
SCIP_Real SCIPgetRowFeasibility(SCIP *scip, SCIP_ROW *row)
Definition: scip_lp.c:2124
SCIP_Real SCIPgetVarPseudocostScore(SCIP *scip, SCIP_VAR *var, SCIP_Real solval)
Definition: scip_var.c:9102
static SCIP_DECL_CUTSELCOPY(cutselCopyEnsemble)
Definition: cutsel_ensemble.c:466
Definition: struct_lp.h:135
Definition: struct_sol.h:73
Definition: type_result.h:44
static int filterWithDensity(SCIP *scip, SCIP_ROW **cuts, SCIP_Real maxdensity, int ncuts)
Definition: cutsel_ensemble.c:429
SCIP_RETCODE SCIPsetCutselCopy(SCIP *scip, SCIP_CUTSEL *cutsel, SCIP_DECL_CUTSELCOPY((*cutselcopy)))
Definition: scip_cutsel.c:125
static SCIP_DECL_CUTSELSELECT(cutselSelectEnsemble)
Definition: cutsel_ensemble.c:526
Definition: type_retcode.h:42
ensemble cut selector
static SCIP_RETCODE scoring(SCIP *scip, SCIP_ROW **cuts, SCIP_CUTSELDATA *cutseldata, SCIP_Real *scores, SCIP_Bool root, int ncuts)
Definition: cutsel_ensemble.c:117
SCIP_RETCODE SCIPcreateRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen, unsigned int initialseed, SCIP_Bool useglobalseed)
Definition: scip_randnumgen.c:56
SCIP_RETCODE SCIPsetCutselInit(SCIP *scip, SCIP_CUTSEL *cutsel, SCIP_DECL_CUTSELINIT((*cutselinit)))
Definition: scip_cutsel.c:157
static int penaliseWithParallelism(SCIP *scip, SCIP_ROW *cut, SCIP_ROW **cuts, SCIP_Real *scores, int ncuts, SCIP_Real maxparallel, SCIP_Real paralpenalty)
Definition: cutsel_ensemble.c:390
SCIP_Real SCIPgetRowObjParallelism(SCIP *scip, SCIP_ROW *row)
Definition: scip_lp.c:2190
public methods for cut selector plugins
SCIP_RETCODE SCIPincludeCutselEnsemble(SCIP *scip)
Definition: cutsel_ensemble.c:556
SCIP_Bool SCIPisSumLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip_numerics.c:705
Definition: struct_lp.h:201
SCIP_Real SCIPgetCutEfficacy(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *cut)
Definition: scip_cut.c:94
public methods for cuts and aggregation rows
static void selectBestCut(SCIP_ROW **cuts, SCIP_Real *scores, int ncuts)
Definition: cutsel_ensemble.c:327
SCIP_Real SCIPrandomGetReal(SCIP_RANDNUMGEN *randnumgen, SCIP_Real minrandval, SCIP_Real maxrandval)
Definition: misc.c:10130
public methods for the LP relaxation, rows and columns
static SCIP_DECL_CUTSELFREE(cutselFreeEnsemble)
Definition: cutsel_ensemble.c:481
SCIP_Real SCIProwGetParallelism(SCIP_ROW *row1, SCIP_ROW *row2, char orthofunc)
Definition: lp.c:7724
public methods for random numbers
SCIP_RETCODE SCIPsetCutselFree(SCIP *scip, SCIP_CUTSEL *cutsel, SCIP_DECL_CUTSELFREE((*cutselfree)))
Definition: scip_cutsel.c:141
static int filterWithParallelism(SCIP_ROW *cut, SCIP_ROW **cuts, SCIP_Real *scores, int ncuts, SCIP_Real maxparallel)
Definition: cutsel_ensemble.c:359
Definition: struct_cutsel.h:46
static SCIP_DECL_CUTSELINIT(cutselInitEnsemble)
Definition: cutsel_ensemble.c:497
Definition: objbenders.h:43
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)
Definition: scip_param.c:139
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)
Definition: scip_param.c:57
static SCIP_DECL_CUTSELEXIT(cutselExitEnsemble)
Definition: cutsel_ensemble.c:511
SCIP_RETCODE SCIPincludeCutselBasic(SCIP *scip, SCIP_CUTSEL **cutsel, const char *name, const char *desc, int priority, SCIP_DECL_CUTSELSELECT((*cutselselect)), SCIP_CUTSELDATA *cutseldata)
Definition: scip_cutsel.c:92