56 #define SEPA_NAME "gomory" 57 #define SEPA_DESC "Gomory MIR cuts separator" 58 #define SEPA_PRIORITY -1000 60 #define SEPA_MAXBOUNDDIST 1.0 61 #define SEPA_USESSUBSCIP FALSE 62 #define SEPA_DELAY FALSE 64 #define DEFAULT_MAXROUNDS 5 65 #define DEFAULT_MAXROUNDSROOT 10 66 #define DEFAULT_MAXSEPACUTS 50 67 #define DEFAULT_MAXSEPACUTSROOT 200 68 #define DEFAULT_MAXRANK -1 69 #define DEFAULT_MAXRANKINTEGRAL -1 70 #define DEFAULT_DYNAMICCUTS TRUE 71 #define DEFAULT_AWAY 0.01 72 #define DEFAULT_MAKEINTEGRAL FALSE 73 #define DEFAULT_FORCECUTS TRUE 74 #define DEFAULT_SEPARATEROWS TRUE 75 #define DEFAULT_DELAYEDCUTS FALSE 76 #define DEFAULT_SIDETYPEBASIS TRUE 77 #define DEFAULT_RANDSEED 53 79 #define BOUNDSWITCH 0.9999 80 #define POSTPROCESS TRUE 82 #define FIXINTEGRALRHS FALSE 83 #define MAKECONTINTEGRAL FALSE 85 #define MAXAGGRLEN(nvars) (0.1*(nvars)+1000) 122 madeintegral =
FALSE;
131 if( !madeintegral && !sepadata->forcecuts )
141 if( madeintegral && sepadata->maxrankintegral != -1 && (
SCIProwGetRank(cut) > sepadata->maxrankintegral) )
145 if( !madeintegral && (sepadata->maxrank != -1) && (
SCIProwGetRank(cut) > sepadata->maxrank) )
162 assert(
scip != NULL);
163 assert(sepa != NULL);
183 assert(sepadata != NULL);
200 assert(sepadata != NULL);
215 assert(sepadata != NULL);
256 assert(sepa != NULL);
258 assert(
scip != NULL);
259 assert(result != NULL);
264 assert(sepadata != NULL);
269 minfrac = sepadata->away;
270 maxfrac = 1.0 - sepadata->away;
277 if( (depth == 0 && sepadata->maxroundsroot >= 0 && ncalls >= sepadata->maxroundsroot)
278 || (depth > 0 && sepadata->maxrounds >= 0 && ncalls >= sepadata->maxrounds) )
299 if( ncols == 0 || nrows == 0 )
303 if( ncols >= 50*nrows )
306 if( ncols >= 5*nrows )
313 sepadata->lastncutsfound = ncutsfound;
330 else if( depth <= maxdepth/4 )
335 else if( depth <= maxdepth/2 )
359 for( i = 0; i < nrows; ++i )
376 frac = MIN(frac, 1.0 - frac);
379 else if( sepadata->separaterows )
383 assert(0 <= -c-1 && -c-1 < nrows);
388 frac = MIN(frac, 1.0 - frac);
392 if( frac >= minfrac )
408 maxsepacuts = sepadata->maxsepacutsroot;
410 maxsepacuts = sepadata->maxsepacuts;
412 SCIPdebugMsg(
scip,
"searching gomory cuts: %d cols, %d rows, maxdnom=%" SCIP_LONGINT_FORMAT
", maxscale=%g, maxcuts=%d\n",
413 ncols, nrows, maxdnom, maxscale, maxsepacuts);
419 for( i = 0; i < nrows && naddedcuts < maxsepacuts && !
SCIPisStopped(
scip) && !cutoff; ++i )
429 if( basisfrac[i] == 0.0 )
440 sepadata->sidetypebasis, allowlocal, 2, (
int)
MAXAGGRLEN(nvars), &success) );
445 SCIP_CALL(
SCIPcalcMIR(
scip, NULL,
POSTPROCESS,
BOUNDSWITCH,
USEVBDS, allowlocal,
FIXINTEGRALRHS, NULL, NULL, minfrac, maxfrac,
446 1.0, aggrrow, cutcoefs, &cutrhs, cutinds, &cutnnz, &cutefficacy, &cutrank, &cutislocal, &success) );
448 assert(allowlocal || !cutislocal);
455 SCIPdebugMsg(
scip,
" -> success=%u, rhs=%g, efficacy=%g\n", success, cutrhs, cutefficacy);
462 SCIPdebugMsg(
scip,
" -> gomory cut detected infeasibility with cut 0 <= %f\n", cutrhs);
482 cutislocal,
FALSE, sepadata->dynamiccuts) );
491 for( v = 0; v < cutnnz; ++v )
511 assert(success ==
TRUE);
517 cutrhs, cutefficacy);
523 SCIPdebugMsg(
scip,
" -> found gomory cut <%s>: act=%f, rhs=%f, norm=%f, eff=%f, min=%f, max=%f (range=%f)\n",
537 if( sepadata->delayedcuts )
572 SCIPdebugMsg(
scip,
"end searching gomory cuts: found %d cuts\n", naddedcuts);
579 else if ( naddedcuts > 0 )
602 sepadata->lastncutsfound = 0;
607 sepaExeclpGomory, NULL,
610 assert(sepa != NULL);
620 "separating/gomory/maxrounds",
621 "maximal number of gomory separation rounds per node (-1: unlimited)",
624 "separating/gomory/maxroundsroot",
625 "maximal number of gomory separation rounds in the root node (-1: unlimited)",
628 "separating/gomory/maxsepacuts",
629 "maximal number of gomory cuts separated per separation round",
632 "separating/gomory/maxsepacutsroot",
633 "maximal number of gomory cuts separated per separation round in the root node",
636 "separating/gomory/maxrank",
637 "maximal rank of a gomory cut that could not be scaled to integral coefficients (-1: unlimited)",
640 "separating/gomory/maxrankintegral",
641 "maximal rank of a gomory cut that could be scaled to integral coefficients (-1: unlimited)",
644 "separating/gomory/away",
645 "minimal integrality violation of a basis variable in order to try Gomory cut",
648 "separating/gomory/dynamiccuts",
649 "should generated cuts be removed from the LP if they are no longer tight?",
652 "separating/gomory/makeintegral",
653 "try to scale cuts to integral coefficients",
656 "separating/gomory/forcecuts",
657 "if conversion to integral coefficients failed still consider the cut",
660 "separating/gomory/separaterows",
661 "separate rows with integral slack",
664 "separating/gomory/delayedcuts",
665 "should cuts be added to the delayed cut pool?",
668 "separating/gomory/sidetypebasis",
669 "choose side types of row (lhs/rhs) based on basis information?",
void SCIPfreeRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen)
#define DEFAULT_MAXSEPACUTSROOT
void SCIPaggrRowFree(SCIP *scip, SCIP_AGGRROW **aggrrow)
SCIP_RETCODE SCIPgetLPBInvRow(SCIP *scip, int r, SCIP_Real *coefs, int *inds, int *ninds)
SCIP_RETCODE SCIPincludeSepaGomory(SCIP *scip)
SCIP_RETCODE SCIPcacheRowExtensions(SCIP *scip, SCIP_ROW *row)
static SCIP_RETCODE evaluateCutNumerics(SCIP *scip, SCIP_SEPADATA *sepadata, SCIP_ROW *cut, SCIP_Longint maxdnom, SCIP_Real maxscale, SCIP_Bool *useful)
SCIP_RETCODE SCIPflushRowExtensions(SCIP *scip, SCIP_ROW *row)
SCIP_RETCODE SCIPcreateRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen, unsigned int initialseed)
SCIP_RETCODE SCIPaddVarToRow(SCIP *scip, SCIP_ROW *row, SCIP_VAR *var, SCIP_Real val)
int SCIProwGetNNonz(SCIP_ROW *row)
#define DEFAULT_MAXROUNDSROOT
const char * SCIProwGetName(SCIP_ROW *row)
SCIP_Bool SCIPisFeasNegative(SCIP *scip, SCIP_Real val)
SCIP_RETCODE SCIPaddDelayedPoolCut(SCIP *scip, SCIP_ROW *row)
int SCIPgetMaxDepth(SCIP *scip)
#define DEFAULT_DELAYEDCUTS
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
#define DEFAULT_MAXROUNDS
#define SEPA_MAXBOUNDDIST
SCIP_Real SCIPinfinity(SCIP *scip)
int SCIPsnprintf(char *t, int len, const char *s,...)
const char * SCIPsepaGetName(SCIP_SEPA *sepa)
enum SCIP_Retcode SCIP_RETCODE
static SCIP_DECL_SEPAEXIT(sepaExitGomory)
#define DEFAULT_MAKEINTEGRAL
#define SCIPfreeBlockMemory(scip, ptr)
void SCIPsortDownRealInt(SCIP_Real *realarray, int *intarray, int len)
SCIP_Real SCIPfeasFrac(SCIP *scip, SCIP_Real val)
#define SCIPfreeBufferArray(scip, ptr)
#define SCIPallocBlockMemory(scip, ptr)
SCIP_RETCODE SCIPgetLPColsData(SCIP *scip, SCIP_COL ***cols, int *ncols)
int SCIPgetNLPBranchCands(SCIP *scip)
SCIP_RETCODE SCIPsetSepaCopy(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPACOPY((*sepacopy)))
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 SCIPepsilon(SCIP *scip)
SCIP_Real SCIPgetRowMaxCoef(SCIP *scip, SCIP_ROW *row)
SCIP_SEPADATA * SCIPsepaGetData(SCIP_SEPA *sepa)
#define DEFAULT_MAXRANKINTEGRAL
static SCIP_DECL_SEPAEXECLP(sepaExeclpGomory)
SCIP_Bool SCIPisLPSolBasic(SCIP *scip)
SCIP_Real SCIPcolGetPrimsol(SCIP_COL *col)
SCIP_Real SCIPgetRowMinCoef(SCIP *scip, SCIP_ROW *row)
#define DEFAULT_MAXSEPACUTS
int SCIPgetNCutsFound(SCIP *scip)
SCIP_RETCODE SCIPsetSepaExit(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPAEXIT((*sepaexit)))
int SCIPsepaGetNCallsAtNode(SCIP_SEPA *sepa)
SCIP_Bool SCIPisEfficacious(SCIP *scip, SCIP_Real efficacy)
#define DEFAULT_FORCECUTS
const char * SCIPvarGetName(SCIP_VAR *var)
SCIP_Bool SCIProwIsIntegral(SCIP_ROW *row)
void SCIPsepaSetData(SCIP_SEPA *sepa, SCIP_SEPADATA *sepadata)
#define DEFAULT_SEPARATEROWS
#define DEFAULT_SIDETYPEBASIS
static SCIP_DECL_SEPAINIT(sepaInitGomory)
SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
SCIP_Real SCIPgetRowLPActivity(SCIP *scip, SCIP_ROW *row)
SCIP_RETCODE SCIPaddRow(SCIP *scip, SCIP_ROW *row, SCIP_Bool forcecut, SCIP_Bool *infeasible)
SCIP_Bool SCIProwIsModifiable(SCIP_ROW *row)
#define DEFAULT_DYNAMICCUTS
SCIP_RETCODE SCIPincludeSepaBasic(SCIP *scip, SCIP_SEPA **sepa, const char *name, const char *desc, int priority, int freq, SCIP_Real maxbounddist, SCIP_Bool usessubscip, SCIP_Bool delay, SCIP_DECL_SEPAEXECLP((*sepaexeclp)), SCIP_DECL_SEPAEXECSOL((*sepaexecsol)), SCIP_SEPADATA *sepadata)
SCIP_Bool SCIPsepaWasLPDelayed(SCIP_SEPA *sepa)
SCIP_RETCODE SCIPcalcMIR(SCIP *scip, SCIP_SOL *sol, SCIP_Bool postprocess, SCIP_Real boundswitch, SCIP_Bool usevbds, SCIP_Bool allowlocal, SCIP_Bool fixintegralrhs, int *boundsfortrans, SCIP_BOUNDTYPE *boundtypesfortrans, SCIP_Real minfrac, SCIP_Real maxfrac, SCIP_Real scale, SCIP_AGGRROW *aggrrow, SCIP_Real *cutcoefs, SCIP_Real *cutrhs, int *cutinds, int *cutnnz, SCIP_Real *cutefficacy, int *cutrank, SCIP_Bool *cutislocal, SCIP_Bool *success)
#define SCIPallocBufferArray(scip, ptr, num)
public data structures and miscellaneous methods
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
int SCIPgetDepth(SCIP *scip)
int SCIPgetRowNumIntCols(SCIP *scip, SCIP_ROW *row)
SCIP_RETCODE SCIPaddPoolCut(SCIP *scip, SCIP_ROW *row)
public methods for LP management
SCIP_RETCODE SCIPcreateEmptyRowSepa(SCIP *scip, SCIP_ROW **row, SCIP_SEPA *sepa, const char *name, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool removable)
SCIP_Real SCIPgetCutEfficacy(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *cut)
SCIP_RETCODE SCIPgetLPBasisInd(SCIP *scip, int *basisind)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisCutNew(SCIP *scip, SCIP_ROW *row)
#define MAXAGGRLEN(nvars)
SCIP_Real SCIPrandomGetReal(SCIP_RANDNUMGEN *randnumgen, SCIP_Real minrandval, SCIP_Real maxrandval)
int SCIProwGetRank(SCIP_ROW *row)
static SCIP_DECL_SEPACOPY(sepaCopyGomory)
SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
SCIP_RETCODE SCIPsetSepaFree(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPAFREE((*sepafree)))
SCIP_RETCODE SCIPsetSepaInit(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPAINIT((*sepainit)))
SCIP_RETCODE SCIPaggrRowSumRows(SCIP *scip, SCIP_AGGRROW *aggrrow, SCIP_Real *weights, int *rowinds, int nrowinds, SCIP_Bool sidetypebasis, SCIP_Bool allowlocal, int negslack, int maxaggrlen, SCIP_Bool *valid)
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
void SCIProwChgRank(SCIP_ROW *row, int rank)
SCIP_Bool SCIPisStopped(SCIP *scip)
SCIP_RETCODE SCIPaggrRowCreate(SCIP *scip, SCIP_AGGRROW **aggrrow)
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
static SCIP_DECL_SEPAFREE(sepaFreeGomory)
SCIP_Real SCIPsumepsilon(SCIP *scip)
SCIP_RETCODE SCIPgetLPRowsData(SCIP *scip, SCIP_ROW ***rows, int *nrows)
SCIP_Longint SCIPgetNLPs(SCIP *scip)
SCIP_RETCODE SCIPmakeRowIntegral(SCIP *scip, SCIP_ROW *row, SCIP_Real mindelta, SCIP_Real maxdelta, SCIP_Longint maxdnom, SCIP_Real maxscale, SCIP_Bool usecontvars, SCIP_Bool *success)
SCIP_Real SCIProwGetNorm(SCIP_ROW *row)
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)
struct SCIP_SepaData SCIP_SEPADATA
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_Real SCIPgetRowActivity(SCIP *scip, SCIP_ROW *row)