Skip to content

Commit

Permalink
Merge branch 'sb/cutadd_cutapply_nums_dependency' into 'master'
Browse files Browse the repository at this point in the history
Independent Number of Cuts Generated and Number of Cuts Applied Limits

See merge request integer/scip!3126
  • Loading branch information
Mathieu Besançon committed Jul 28, 2023
2 parents 0dac105 + 0364eb2 commit 1863c3b
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 10 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ Interface changes

### New parameters

- separating/maxcutsgen and separating/maxcutsrootgen for limits on the number of cuts generated (which used to be a
factor of separating/maxcuts and separating/maxcutsroot)
- expr/pow/expandmaxexponent to specify limit on exponent when to expand power of sum
- expr/pow/distribfracexponent to enable expanding power of products with fractional exponents
- expr/product/expandalways to enable expanding any product with sums as factor (that is, also when more than two factors)
Expand Down
2 changes: 2 additions & 0 deletions src/scip/paramset.c
Original file line number Diff line number Diff line change
Expand Up @@ -3523,6 +3523,7 @@ SCIP_RETCODE paramsetSetSeparatingDefault(
SCIP_CALL( SCIPparamsetSetToDefault(paramset, set, messagehdlr, "cutselection/hybrid/minorthoroot") );
SCIP_CALL( SCIPparamsetSetToDefault(paramset, set, messagehdlr, "separating/maxroundsrootsubrun") );
SCIP_CALL( SCIPparamsetSetToDefault(paramset, set, messagehdlr, "separating/maxaddrounds") );
SCIP_CALL( SCIPparamsetSetToDefault(paramset, set, messagehdlr, "separating/maxcutsrootgen") );
SCIP_CALL( SCIPparamsetSetToDefault(paramset, set, messagehdlr, "separating/maxcutsroot") );
SCIP_CALL( SCIPparamsetSetToDefault(paramset, set, messagehdlr, "separating/poolfreq") );
SCIP_CALL( SCIPparamsetSetToDefault(paramset, set, messagehdlr, "separating/aggregation/maxfailsroot") );
Expand Down Expand Up @@ -3682,6 +3683,7 @@ SCIP_RETCODE paramsetSetSeparatingAggressive(
SCIP_CALL( paramSetReal(paramset, set, messagehdlr, "cutselection/hybrid/minorthoroot", 0.1, quiet) );
SCIP_CALL( paramSetInt(paramset, set, messagehdlr, "separating/maxroundsrootsubrun", 5, quiet) );
SCIP_CALL( paramSetInt(paramset, set, messagehdlr, "separating/maxaddrounds", 5, quiet) );
SCIP_CALL( paramSetInt(paramset, set, messagehdlr, "separating/maxcutsroot", 10000, quiet) );
SCIP_CALL( paramSetInt(paramset, set, messagehdlr, "separating/maxcutsroot", 5000, quiet) );
SCIP_CALL( paramSetInt(paramset, set, messagehdlr, "separating/poolfreq", 10, quiet) );

Expand Down
26 changes: 26 additions & 0 deletions src/scip/set.c
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,8 @@
* or integrality improvement in the root node (-1: no additional restriction) */
#define SCIP_DEFAULT_SEPA_MAXSTALLROUNDS 1 /**< maximal number of consecutive separation rounds without objective
* or integrality improvement in local nodes (-1: no additional restriction) */
#define SCIP_DEFAULT_SEPA_MAXCUTSGEN 200 /**< maximal number of cuts generated per separation round */
#define SCIP_DEFAULT_SEPA_MAXCUTSROOTGEN 4000 /**< maximal generated cuts at the root node */
#define SCIP_DEFAULT_SEPA_MAXCUTS 100 /**< maximal number of cuts separated per separation round */
#define SCIP_DEFAULT_SEPA_MAXCUTSROOT 2000 /**< maximal separated cuts at the root node */
#define SCIP_DEFAULT_SEPA_CUTAGELIMIT 80 /**< maximum age a cut can reach before it is deleted from global cut pool
Expand Down Expand Up @@ -2514,6 +2516,16 @@ SCIP_RETCODE SCIPsetCreate(
"maximal number of consecutive separation rounds without objective or integrality improvement in the root node (-1: no additional restriction)",
&(*set)->sepa_maxstallroundsroot, FALSE, SCIP_DEFAULT_SEPA_MAXSTALLROUNDSROOT, -1, INT_MAX,
NULL, NULL) );
SCIP_CALL( SCIPsetAddIntParam(*set, messagehdlr, blkmem,
"separating/maxcutsgen",
"maximal number of cuts generated per separation round (0: disable local separation)",
&(*set)->sepa_maxcutsgen, FALSE, SCIP_DEFAULT_SEPA_MAXCUTSGEN, 0, INT_MAX,
NULL, NULL) );
SCIP_CALL( SCIPsetAddIntParam(*set, messagehdlr, blkmem,
"separating/maxcutsrootgen",
"maximal number of generated cuts at the root node (0: disable root node separation)",
&(*set)->sepa_maxcutsrootgen, FALSE, SCIP_DEFAULT_SEPA_MAXCUTSROOTGEN, 0, INT_MAX,
NULL, NULL) );
SCIP_CALL( SCIPsetAddIntParam(*set, messagehdlr, blkmem,
"separating/maxcuts",
"maximal number of cuts separated per separation round (0: disable local separation)",
Expand Down Expand Up @@ -5877,6 +5889,20 @@ int SCIPsetGetPriceMaxvars(
return set->price_maxvars;
}

/** returns the maximal number of cuts that can be generated per round */
int SCIPsetGetSepaMaxcutsGen(
SCIP_SET* set, /**< global SCIP settings */
SCIP_Bool root /**< are we at the root node? */
)
{
assert(set != NULL);

if( root )
return set->sepa_maxcutsrootgen;
else
return set->sepa_maxcutsgen;
}

/** returns the maximal number of cuts separated per round */
int SCIPsetGetSepaMaxcuts(
SCIP_SET* set, /**< global SCIP settings */
Expand Down
6 changes: 6 additions & 0 deletions src/scip/set.h
Original file line number Diff line number Diff line change
Expand Up @@ -1044,6 +1044,12 @@ int SCIPsetGetPriceMaxvars(
SCIP_Bool root /**< are we at the root node? */
);

/** returns the maximal number of cuts generated per round */
int SCIPsetGetSepaMaxcutsGen(
SCIP_SET* set, /**< global SCIP settings */
SCIP_Bool root /**< are we at the root node? */
);

/** returns the maximal number of cuts separated per round */
int SCIPsetGetSepaMaxcuts(
SCIP_SET* set, /**< global SCIP settings */
Expand Down
96 changes: 86 additions & 10 deletions src/scip/solve.c
Original file line number Diff line number Diff line change
Expand Up @@ -1639,7 +1639,10 @@ SCIP_RETCODE separationRoundLP(

root = (actdepth == 0);
*delayed = FALSE;
*enoughcuts = (SCIPsepastoreGetNCuts(sepastore) >= 2 * (SCIP_Longint)SCIPsetGetSepaMaxcuts(set, root));
if( SCIPsetGetSepaMaxcuts(set, root) > 0 )
*enoughcuts = (SCIPsepastoreGetNCuts(sepastore) >= (SCIP_Longint)SCIPsetGetSepaMaxcutsGen(set, root));
else
*enoughcuts = (SCIPsepastoreGetNCuts(sepastore) >= 0);
*lperror = FALSE;
consadded = FALSE;

Expand Down Expand Up @@ -1675,7 +1678,16 @@ SCIP_RETCODE separationRoundLP(
#endif
*cutoff = *cutoff || (result == SCIP_CUTOFF);
consadded = consadded || (result == SCIP_CONSADDED);
*enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= 2 * (SCIP_Longint)SCIPsetGetSepaMaxcuts(set, root)) || (result == SCIP_NEWROUND);
if( SCIPsetGetSepaMaxcuts(set, root) > 0 )
{
*enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= (SCIP_Longint)SCIPsetGetSepaMaxcutsGen(set, root))
|| (result == SCIP_NEWROUND);
}
else
{
*enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= 0) || (result == SCIP_NEWROUND);
}

*delayed = *delayed || (result == SCIP_DELAYED);

if( !(*cutoff) )
Expand Down Expand Up @@ -1712,7 +1724,15 @@ SCIP_RETCODE separationRoundLP(

*cutoff = *cutoff || (result == SCIP_CUTOFF);
consadded = consadded || (result == SCIP_CONSADDED);
*enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= 2 * (SCIP_Longint)SCIPsetGetSepaMaxcuts(set, root)) || (result == SCIP_NEWROUND);
if( SCIPsetGetSepaMaxcuts(set, root) > 0 )
{
*enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= (SCIP_Longint)SCIPsetGetSepaMaxcutsGen(set, root))
|| (result == SCIP_NEWROUND);
}
else
{
*enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= 0) || (result == SCIP_NEWROUND);
}
*delayed = *delayed || (result == SCIP_DELAYED);

if( !(*cutoff) )
Expand Down Expand Up @@ -1752,7 +1772,15 @@ SCIP_RETCODE separationRoundLP(

*cutoff = *cutoff || (result == SCIP_CUTOFF);
consadded = consadded || (result == SCIP_CONSADDED);
*enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= 2 * (SCIP_Longint)SCIPsetGetSepaMaxcuts(set, root)) || (result == SCIP_NEWROUND);
if( SCIPsetGetSepaMaxcuts(set, root) > 0 )
{
*enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= (SCIP_Longint)SCIPsetGetSepaMaxcutsGen(set, root))
|| (result == SCIP_NEWROUND);
}
else
{
*enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= 0) || (result == SCIP_NEWROUND);
}
*delayed = *delayed || (result == SCIP_DELAYED);

if( !(*cutoff) )
Expand Down Expand Up @@ -1791,7 +1819,15 @@ SCIP_RETCODE separationRoundLP(

*cutoff = *cutoff || (result == SCIP_CUTOFF);
consadded = consadded || (result == SCIP_CONSADDED);
*enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= 2 * (SCIP_Longint)SCIPsetGetSepaMaxcuts(set, root)) || (result == SCIP_NEWROUND);
if( SCIPsetGetSepaMaxcuts(set, root) > 0 )
{
*enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= (SCIP_Longint)SCIPsetGetSepaMaxcutsGen(set, root))
|| (result == SCIP_NEWROUND);
}
else
{
*enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= 0) || (result == SCIP_NEWROUND);
}
*delayed = *delayed || (result == SCIP_DELAYED);

if( !(*cutoff) )
Expand Down Expand Up @@ -1861,7 +1897,15 @@ SCIP_RETCODE separationRoundSol(
SCIP_CALL( SCIPsepaExecSol(set->sepas[i], set, stat, sepastore, sol, actdepth, allowlocal, onlydelayed, &result) );
*cutoff = *cutoff || (result == SCIP_CUTOFF);
consadded = consadded || (result == SCIP_CONSADDED);
*enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= 2 * (SCIP_Longint)SCIPsetGetSepaMaxcuts(set, root)) || (result == SCIP_NEWROUND);
if( SCIPsetGetSepaMaxcuts(set, root) > 0 )
{
*enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= (SCIP_Longint)SCIPsetGetSepaMaxcutsGen(set, root))
|| (result == SCIP_NEWROUND);
}
else
{
*enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= 0) || (result == SCIP_NEWROUND);
}
*delayed = *delayed || (result == SCIP_DELAYED);
if( *cutoff )
{
Expand All @@ -1886,7 +1930,15 @@ SCIP_RETCODE separationRoundSol(
&result) );
*cutoff = *cutoff || (result == SCIP_CUTOFF);
consadded = consadded || (result == SCIP_CONSADDED);
*enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= 2 * (SCIP_Longint)SCIPsetGetSepaMaxcuts(set, root)) || (result == SCIP_NEWROUND);
if( SCIPsetGetSepaMaxcuts(set, root) > 0 )
{
*enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= (SCIP_Longint)SCIPsetGetSepaMaxcutsGen(set, root))
|| (result == SCIP_NEWROUND);
}
else
{
*enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= 0) || (result == SCIP_NEWROUND);
}
*delayed = *delayed || (result == SCIP_DELAYED);
if( *cutoff )
{
Expand Down Expand Up @@ -1914,7 +1966,15 @@ SCIP_RETCODE separationRoundSol(
SCIP_CALL( SCIPsepaExecSol(set->sepas[i], set, stat, sepastore, sol, actdepth, allowlocal, onlydelayed, &result) );
*cutoff = *cutoff || (result == SCIP_CUTOFF);
consadded = consadded || (result == SCIP_CONSADDED);
*enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= 2 * (SCIP_Longint)SCIPsetGetSepaMaxcuts(set, root)) || (result == SCIP_NEWROUND);
if( SCIPsetGetSepaMaxcuts(set, root) > 0 )
{
*enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= (SCIP_Longint)SCIPsetGetSepaMaxcutsGen(set, root))
|| (result == SCIP_NEWROUND);
}
else
{
*enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= 0) || (result == SCIP_NEWROUND);
}
*delayed = *delayed || (result == SCIP_DELAYED);
if( *cutoff )
{
Expand All @@ -1940,7 +2000,15 @@ SCIP_RETCODE separationRoundSol(
SCIP_CALL( SCIPconshdlrSeparateSol(set->conshdlrs_sepa[i], blkmem, set, stat, sepastore, sol, actdepth, onlydelayed, &result) );
*cutoff = *cutoff || (result == SCIP_CUTOFF);
consadded = consadded || (result == SCIP_CONSADDED);
*enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= 2 * (SCIP_Longint)SCIPsetGetSepaMaxcuts(set, root)) || (result == SCIP_NEWROUND);
if( SCIPsetGetSepaMaxcuts(set, root) > 0 )
{
*enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= (SCIP_Longint)SCIPsetGetSepaMaxcutsGen(set, root))
|| (result == SCIP_NEWROUND);
}
else
{
*enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= 0) || (result == SCIP_NEWROUND);
}
*delayed = *delayed || (result == SCIP_DELAYED);
if( *cutoff )
{
Expand Down Expand Up @@ -2250,7 +2318,15 @@ SCIP_RETCODE cutpoolSeparate(

SCIP_CALL( SCIPcutpoolSeparate(cutpool, blkmem, set, stat, eventqueue, eventfilter, lp, sepastore, NULL, cutpoolisdelayed, root, &result) );
*cutoff = *cutoff || (result == SCIP_CUTOFF);
*enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= 2 * (SCIP_Longint)SCIPsetGetSepaMaxcuts(set, root)) || (result == SCIP_NEWROUND);
if( SCIPsetGetSepaMaxcuts(set, root) > 0 )
{
*enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= (SCIP_Longint)SCIPsetGetSepaMaxcutsGen(set, root))
|| (result == SCIP_NEWROUND);
}
else
{
*enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= 0) || (result == SCIP_NEWROUND);
}
}

return SCIP_OKAY;
Expand Down
2 changes: 2 additions & 0 deletions src/scip/struct_set.h
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,8 @@ struct SCIP_Set
* or integrality improvement (-1: no additional restriction) */
int sepa_maxstallroundsroot;/**< maximal number of consecutive separation rounds without objective
* or integrality improvement (-1: no additional restriction) */
int sepa_maxcutsgen; /**< maximal number of cuts generated per separation round */
int sepa_maxcutsrootgen; /**< maximal number of generated cuts at the root node */
int sepa_maxcuts; /**< maximal number of cuts separated per separation round */
int sepa_maxcutsroot; /**< maximal number of separated cuts at the root node */
int sepa_cutagelimit; /**< maximum age a cut can reach before it is deleted from the global cut pool */
Expand Down

0 comments on commit 1863c3b

Please sign in to comment.