43#define CUTSEL_NAME "ensemble"
44#define CUTSEL_DESC "weighted sum of many terms with optional filtering and penalties"
45#define CUTSEL_PRIORITY 7000
47#define RANDSEED 0x5EED
49#define DEFAULT_MINSCORE 0.0
50#define DEFAULT_EFFICACYWEIGHT 0.75
51#define DEFAULT_DIRCUTOFFDISTWEIGHT 0.0
52#define DEFAULT_OBJPARALWEIGHT 0.25
53#define DEFAULT_INTSUPPORTWEIGHT 0.45
54#define DEFAULT_EXPIMPROVWEIGHT 0.1
55#define DEFAULT_PSCOSTWEIGHT 0.75
56#define DEFAULT_NLOCKSWEIGHT 0.25
57#define DEFAULT_MAXSPARSITYBONUS 0.5
58#define DEFAULT_SPARSITYENDBONUS 0.2
59#define DEFAULT_GOODNUMERICBONUS 0.0
60#define DEFAULT_MAXCOEFRATIOBONUS 10000
61#define DEFAULT_PENALISELOCKS TRUE
62#define DEFAULT_PENALISEOBJPARAL TRUE
63#define DEFAULT_FILTERPARALCUTS FALSE
64#define DEFAULT_MAXPARAL 0.95
65#define DEFAULT_PENALISEPARALCUTS TRUE
66#define DEFAULT_PARALPENALTY 0.25
67#define DEFAULT_FILTERDENSECUTS TRUE
68#define DEFAULT_MAXCUTDENSITY 0.425
69#define DEFAULT_MAXNONZEROROOTROUND 4.5
70#define DEFAULT_MAXNONZEROTREEROUND 9.5
71#define DEFAULT_MAXCUTS 200
72#define DEFAULT_MAXNUMVARS 50000
103 int maxcoefratiobonus;
151 for (
int i = 0;
i < ncuts; ++
i )
164 cutdensities[
i] = ncutcols / ncols;
168 for (
int j = 0; j < (int) ncutcols; ++j )
187 l1dist =
ABS(colval - (cutalpha * cutvals[j]));
190 cutlocks[
i] = cutlocks[
i] / ncutcols;
192 if( cutlocks[
i] > maxlocks )
193 maxlocks = cutlocks[
i];
195 if( pscosts[
i] > maxpscost )
196 maxpscost = pscosts[
i];
201 maxlocks =
MAX(maxlocks, 1);
203 for (
int i = 0;
i < ncuts;
i++ )
205 cutlocks[
i] = cutlocks[
i] / maxlocks;
207 if( cutseldata->penaliselocks )
208 cutlocks[
i] = 1 - cutlocks[
i];
209 pscosts[
i] = pscosts[
i] / maxpscost;
215 for (
int i = 0;
i < ncuts;
i++ )
218 maxdcd =
MAX(maxdcd, dcds[
i]);
222 for (
int i = 0;
i < ncuts; ++
i )
226 maxeff =
MAX(maxeff, effs[
i]);
227 maxexp =
MAX(maxexp, exps[
i]);
231 for (
int i = 0;
i < ncuts; ++
i )
248 intsupport *= cutseldata->intsupportweight;
251 if( ! cutseldata->penaliseobjparal )
257 density = (cutseldata->maxsparsitybonus / cutseldata->endsparsitybonus) * -1 * cutdensities[
i];
258 density += cutseldata->maxsparsitybonus;
265 pscost = cutseldata->pscostweight * pscosts[
i];
266 cutlock = cutseldata->locksweight * cutlocks[
i];
271 mincutval = mincutval > 0.0 ? mincutval : 1.0;
272 dynamism = cutseldata->maxcoefratiobonus >= maxcutval / mincutval ? cutseldata->goodnumericsbonus : 0.0;
280 scaleddcd = cutseldata->dircutoffdistweight *
SQR(
LOG1P(dcds[
i]) /
LOG1P(maxdcd));
290 scaledexp = cutseldata->expimprovweight *
SQR(
LOG1P(exps[
i]) /
LOG1P(maxexp));
299 scaledeff = cutseldata->efficacyweight *
SQR(
LOG1P(effs[
i]) /
LOG1P(maxeff));
301 scaledeff = (cutseldata->efficacyweight + cutseldata->dircutoffdistweight) *
SQR(
LOG1P(effs[
i]) /
LOG1P(maxeff));
305 score = scaledeff + scaleddcd + scaledexp + objparallelism + intsupport +
density + dynamism + pscost + cutlock;
338 bestscore = scores[0];
341 for(
int i = 1;
i < ncuts; ++
i )
343 if( scores[
i] > bestscore )
346 bestscore = scores[
i];
369 for(
int i = ncuts - 1;
i >= 0; --
i )
375 if( thisparallel > maxparallel )
402 for(
int i = ncuts - 1;
i >= 0; --
i )
415 else if( thisparallel > maxparallel )
417 scores[
i] -= paralpenalty;
440 for(
int i = ncuts - 1;
i >= 0; --
i )
446 if( maxdensity < nvals / ncols )
535 if( ncuts > cutseldata->maxcuts ||
SCIPgetNVars(
scip) > cutseldata->maxnumvars )
544 maxnselectedcuts, nselectedcuts) );
584 "cutoff distance in cut score calculation", &cutseldata->dircutoffdistweight,
FALSE,
615 "(ratio of coefficients) in cut score calculation", &cutseldata->goodnumericsbonus,
FALSE,
633 "applied cuts (root). multiple num LP cols.", &cutseldata->maxnonzerorootround,
FALSE,
637 "applied cuts (tree). multiple num LP cols.", &cutseldata->maxnonzerotreeround,
FALSE,
699 assert(forcedcuts !=
NULL || nforcedcuts == 0);
706 if( cutseldata->filterdensecuts )
715 origscoresptr = scores;
725 if( cutseldata->filterparalcuts )
727 else if( cutseldata->penaliseparalcuts )
732 nonzerobudget = root ? cutseldata->maxnonzerorootround : cutseldata->maxnonzerotreeround;
740 selectedcut = cuts[0];
743 if( scores[0] < cutseldata->minscore )
749 if( *nselectedcuts == maxselectedcuts )
760 if( cutseldata->filterparalcuts && ncuts > 0)
762 else if( cutseldata->penaliseparalcuts && ncuts > 0 )
766 if( nonzerobudget - budgettaken < 1 && ncuts > 0 )
#define DEFAULT_EFFICACYWEIGHT
#define DEFAULT_INTSUPPORTWEIGHT
#define DEFAULT_PSCOSTWEIGHT
#define DEFAULT_OBJPARALWEIGHT
#define DEFAULT_DIRCUTOFFDISTWEIGHT
#define DEFAULT_SPARSITYENDBONUS
#define DEFAULT_MAXNONZEROTREEROUND
#define DEFAULT_FILTERDENSECUTS
#define DEFAULT_MAXSPARSITYBONUS
#define DEFAULT_PARALPENALTY
#define DEFAULT_PENALISEPARALCUTS
#define DEFAULT_GOODNUMERICBONUS
#define DEFAULT_PENALISELOCKS
#define DEFAULT_NLOCKSWEIGHT
static SCIP_RETCODE scoring(SCIP *scip, SCIP_ROW **cuts, SCIP_CUTSELDATA *cutseldata, SCIP_Real *scores, SCIP_Bool root, int ncuts)
static void selectBestCut(SCIP_ROW **cuts, SCIP_Real *scores, int ncuts)
static int filterWithDensity(SCIP *scip, SCIP_ROW **cuts, SCIP_Real maxdensity, int ncuts)
static int penaliseWithParallelism(SCIP *scip, SCIP_ROW *cut, SCIP_ROW **cuts, SCIP_Real *scores, int ncuts, SCIP_Real maxparallel, SCIP_Real paralpenalty)
static int filterWithParallelism(SCIP_ROW *cut, SCIP_ROW **cuts, SCIP_Real *scores, int ncuts, SCIP_Real maxparallel)
#define DEFAULT_EXPIMPROVWEIGHT
#define DEFAULT_MAXCOEFRATIOBONUS
#define DEFAULT_MAXCUTDENSITY
#define DEFAULT_MAXNONZEROROOTROUND
#define DEFAULT_PENALISEOBJPARAL
#define DEFAULT_MAXNUMVARS
#define DEFAULT_FILTERPARALCUTS
#define SCIP_STRINGEQ(name, reference, retcode)
static const SCIP_Real density
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)
SCIP_RETCODE SCIPincludeCutselEnsemble(SCIP *scip)
int SCIPgetNVars(SCIP *scip)
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 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)
void SCIPswapPointers(void **pointer1, void **pointer2)
void SCIPswapReals(SCIP_Real *value1, SCIP_Real *value2)
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
SCIP_Real SCIPcolGetPrimsol(SCIP_COL *col)
SCIP_Real SCIPgetCutEfficacy(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *cut)
SCIP_Real SCIPgetCutLPSolCutoffDistance(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *cut)
SCIP_RETCODE SCIPsetCutselInit(SCIP *scip, SCIP_CUTSEL *cutsel,)
SCIP_RETCODE SCIPincludeCutselBasic(SCIP *scip, SCIP_CUTSEL **cutsel, const char *name, const char *desc, int priority, SCIP_DECL_CUTSELSELECT((*cutselselect)), SCIP_CUTSELDATA *cutseldata)
SCIP_RETCODE SCIPsetCutselCopy(SCIP *scip, SCIP_CUTSEL *cutsel,)
SCIP_RETCODE SCIPsetCutselExit(SCIP *scip, SCIP_CUTSEL *cutsel,)
SCIP_CUTSELDATA * SCIPcutselGetData(SCIP_CUTSEL *cutsel)
void SCIPcutselSetData(SCIP_CUTSEL *cutsel, SCIP_CUTSELDATA *cutseldata)
const char * SCIPcutselGetName(SCIP_CUTSEL *cutsel)
SCIP_RETCODE SCIPsetCutselFree(SCIP *scip, SCIP_CUTSEL *cutsel,)
int SCIPgetNLPCols(SCIP *scip)
#define SCIPallocBufferArray(scip, ptr, num)
#define SCIPfreeBufferArray(scip, ptr)
#define SCIPfreeBlockMemory(scip, ptr)
#define SCIPallocBlockMemory(scip, ptr)
SCIP_Real SCIPgetRowMaxCoef(SCIP *scip, SCIP_ROW *row)
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
SCIP_Real SCIPgetRowMinCoef(SCIP *scip, SCIP_ROW *row)
SCIP_Real SCIPgetRowFeasibility(SCIP *scip, SCIP_ROW *row)
SCIP_Real SCIProwGetParallelism(SCIP_ROW *row1, SCIP_ROW *row2, char orthofunc)
int SCIProwGetNNonz(SCIP_ROW *row)
SCIP_COL ** SCIProwGetCols(SCIP_ROW *row)
SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
SCIP_Real SCIProwGetNorm(SCIP_ROW *row)
SCIP_Real SCIPgetRowObjParallelism(SCIP *scip, SCIP_ROW *row)
int SCIPgetRowNumIntCols(SCIP *scip, SCIP_ROW *row)
SCIP_Real * SCIProwGetVals(SCIP_ROW *row)
SCIP_SOL * SCIPgetBestSol(SCIP *scip)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPepsilon(SCIP *scip)
SCIP_Real SCIPsumepsilon(SCIP *scip)
SCIP_Bool SCIPisSumLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
int SCIPvarGetNLocksDown(SCIP_VAR *var)
int SCIPvarGetNLocksUp(SCIP_VAR *var)
SCIP_Real SCIPgetVarPseudocostScore(SCIP *scip, SCIP_VAR *var, SCIP_Real solval)
SCIP_Real SCIPrandomGetReal(SCIP_RANDNUMGEN *randnumgen, SCIP_Real minrandval, SCIP_Real maxrandval)
SCIPfreeRandom(scip, &heurdata->randnumgen)
SCIPcreateRandom(scip, &heurdata->randnumgen, DEFAULT_RANDSEED, TRUE))
assert(minobj< SCIPgetCutoffbound(scip))
#define BMSclearMemory(ptr)
public methods for cuts and aggregation rows
public methods for cut selector plugins
public methods for the LP relaxation, rows and columns
public methods for random numbers
#define SCIP_DECL_CUTSELEXIT(x)
#define SCIP_DECL_CUTSELSELECT(x)
#define SCIP_DECL_CUTSELFREE(x)
struct SCIP_Cutsel SCIP_CUTSEL
struct SCIP_CutselData SCIP_CUTSELDATA
#define SCIP_DECL_CUTSELINIT(x)
#define SCIP_DECL_CUTSELCOPY(x)
struct SCIP_RandNumGen SCIP_RANDNUMGEN
enum SCIP_Retcode SCIP_RETCODE