Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/v9-minor'
Browse files Browse the repository at this point in the history
  • Loading branch information
svigerske committed Dec 3, 2024
2 parents 959072b + 922f346 commit 8d07066
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 59 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,11 @@ Interface changes
### New and changed callbacks

### New API functions
- SCIPdisplaySymmetryGenerators() and SCIPdialogExecDisplaySymmetry() to display generators of symmetry group

### Command line interface
- the implementation of interactive shell functionality `display symmetry` has been moved
from `prop_symmetry.c` to `dialog_default.c`

### Interfaces to external software

Expand All @@ -160,6 +163,7 @@ Fixed bugs
- check variable cancellation in SCIPvarAddVlb() and SCIPvarAddVub() to avert wrong infeasibility
- SCIPfreeReoptSolve now also clears the partial solutions
- fixed bug in calculation of "fractionality score" for spatial branching candidates in cons_nonlinear
- fixed bug with installing symmetry dialog in sub-SCIPs
- add copy callbacks for default plugins presolver dualagg, presolver redvub, branchrule lookahead, branchrule cloud, heuristic dualval, heuristic repair, propagator nlobbt, separator gauge, and separator convexproj missing in SCIPsetCopyPlugins()

Unit tests
Expand Down
3 changes: 3 additions & 0 deletions doc/xternal.c
Original file line number Diff line number Diff line change
Expand Up @@ -8451,6 +8451,9 @@
* Moreover, symmetries can also be detected in code containing customized constraints.
* To this end, a suitable callback needs to be implemented, see \ref SYMDETECTCUSTOM.
*
* The (generators of the) symmetry group detected by SCIP can be printed to the terminal
* by querying <code>display symmetry</code> in SCIP's interactive shell.
*
* @subsection SYMPROCESS Processing symmetry information
*
* After symmetries have been computed, SCIP has access to a list \f$\gamma_1,\dots,\gamma_m\f$ of
Expand Down
36 changes: 36 additions & 0 deletions src/scip/dialog_default.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
#include "scip/scip_solvingstats.h"
#include "scip/scip_validation.h"
#include "scip/scip_var.h"
#include "scip/prop_symmetry.h"
#include <stdlib.h>
#include <string.h>

Expand Down Expand Up @@ -1862,6 +1863,30 @@ SCIP_DECL_DIALOGEXEC(SCIPdialogExecDisplayStatistics)
return SCIP_OKAY;
}

/** dialog execution method for the display symmetry command */
SCIP_DECL_DIALOGEXEC(SCIPdialogExecDisplaySymmetry)
{ /*lint --e{715}*/
SCIP_PROP* prop;
assert(scip != NULL);

SCIP_CALL( SCIPdialoghdlrAddHistory(dialoghdlr, dialog, NULL, FALSE) );

SCIPdialogMessage(scip, NULL, "\n");
prop = SCIPfindProp(scip, "symmetry");
if( prop == NULL )
{
SCIPinfoMessage(scip, NULL, "Cannot display symmetries. Symmetry propagator has not been included.\n");
return SCIP_OKAY;
}
SCIP_CALL( SCIPdisplaySymmetryGenerators(scip, prop) );

SCIPdialogMessage(scip, NULL, "\n");

*nextdialog = SCIPdialoghdlrGetRoot(dialoghdlr);

return SCIP_OKAY;
}

/** dialog execution method for the display reoptstatistics command */
SCIP_DECL_DIALOGEXEC(SCIPdialogExecDisplayReoptStatistics)
{ /*lint --e{715}*/
Expand Down Expand Up @@ -4452,6 +4477,17 @@ SCIP_RETCODE SCIPincludeDialogDefaultBasic(
SCIP_CALL( SCIPreleaseDialog(scip, &dialog) );
}

/* display symmetry information */
if( !SCIPdialogHasEntry(submenu, "symmetry") )
{
SCIP_CALL( SCIPincludeDialog(scip, &dialog,
NULL,
SCIPdialogExecDisplaySymmetry, NULL, NULL,
"symmetry", "display generators of symmetry group in cycle notation, if available", FALSE, NULL) );
SCIP_CALL( SCIPaddDialogEntry(scip, submenu, dialog) );
SCIP_CALL( SCIPreleaseDialog(scip, &dialog) );
}

/* display reoptimization statistics */
if( !SCIPdialogHasEntry(submenu, "reoptstatistics") )
{
Expand Down
4 changes: 4 additions & 0 deletions src/scip/dialog_default.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,10 @@ SCIP_DECL_DIALOGEXEC(SCIPdialogExecDisplaySubSolution);
SCIP_EXPORT
SCIP_DECL_DIALOGEXEC(SCIPdialogExecDisplayStatistics);

/** dialog execution method for the display symmetry command */
SCIP_EXPORT
SCIP_DECL_DIALOGEXEC(SCIPdialogExecDisplaySymmetry);

/** dialog execution method for the display reoptstatistics command */
SCIP_EXPORT
SCIP_DECL_DIALOGEXEC(SCIPdialogExecDisplayReoptStatistics);
Expand Down
101 changes: 42 additions & 59 deletions src/scip/prop_symmetry.c
Original file line number Diff line number Diff line change
Expand Up @@ -550,15 +550,17 @@ SCIP_RETCODE displaySymmetriesWithComponents(

SCIP_CALL( SCIPallocClearBufferArray(scip, &covered, permlen) );

if ( symtype == SYM_SYMTYPE_PERM )
SCIPinfoMessage(scip, NULL, " Symmetries of different components are displayed as permutations.\n\n");
else
SCIPinfoMessage(scip, NULL, " Symmetries of different components are displayed as permutations,\n"
" or signed permutations (allowing translations) if the component has signed permutations.\n\n");
for (c = 0; c < propdata->ncomponents; ++c)
{
int cnt;

SCIPinfoMessage(scip, NULL, "Display symmetries of component %d.\n", c);
if ( propdata->componenthassignedperm[c] )
SCIPinfoMessage(scip, NULL, " Symmetries are displayed as signed permutations (allowing translations).\n");
else
SCIPinfoMessage(scip, NULL, " Symmetries are displayed as permutations.\n");
SCIPinfoMessage(scip, NULL, "Display symmetries of component %d%s.\n", c,
propdata->componenthassignedperm[c] ? " as signed permutations" : "");

comppermlen = propdata->componenthassignedperm[c] ? 2 * npermvars : npermvars;

Expand All @@ -582,41 +584,6 @@ SCIP_RETCODE displaySymmetriesWithComponents(
return SCIP_OKAY;
}

/** dialog execution method for the display symmetry information command */
static
SCIP_DECL_DIALOGEXEC(dialogExecDisplaySymmetry)
{ /*lint --e{715}*/
SCIP_PROPDATA* propdata;

/* add your dialog to history of dialogs that have been executed */
SCIP_CALL( SCIPdialoghdlrAddHistory(dialoghdlr, dialog, NULL, FALSE) );

propdata = (SCIP_PROPDATA*)SCIPdialogGetData(dialog);
assert( propdata != NULL );

if ( propdata->nperms == -1 )
{
SCIPinfoMessage(scip, NULL, "Cannot display symmetries. Symmetries have not been computed yet.\n");
}
else if ( propdata->nperms == 0 )
{
SCIPinfoMessage(scip, NULL, "Cannot display symmetries. No symmetries detected.\n");
}
else if ( propdata->ncomponents < 0 )
{
SCIP_CALL( displaySymmetriesWithoutComponents(scip, propdata) );
}
else
{
SCIP_CALL( displaySymmetriesWithComponents(scip, propdata) );
}

/* next dialog will be root dialog again */
*nextdialog = SCIPdialoghdlrGetRoot(dialoghdlr);

return SCIP_OKAY;
}

/*
* Methods for printing symmetry information
*/
Expand Down Expand Up @@ -7811,9 +7778,6 @@ SCIP_RETCODE SCIPincludePropSymmetry(
SCIP_TABLEDATA* tabledata;
SCIP_PROPDATA* propdata = NULL;
SCIP_PROP* prop = NULL;
SCIP_DIALOG* rootdialog;
SCIP_DIALOG* displaymenu;
SCIP_DIALOG* dialog;

SCIP_CALL( SCIPallocBlockMemory(scip, &propdata) );
assert( propdata != NULL );
Expand Down Expand Up @@ -7893,22 +7857,6 @@ SCIP_RETCODE SCIPincludePropSymmetry(
NULL, tableFreeSymmetry, NULL, NULL, NULL, NULL, tableOutputSymmetry,
tabledata, TABLE_POSITION_SYMMETRY, TABLE_EARLIEST_SYMMETRY) );

/* include display dialog */
rootdialog = SCIPgetRootDialog(scip);
assert(rootdialog != NULL);
if( SCIPdialogFindEntry(rootdialog, "display", &displaymenu) != 1 )
{
SCIPerrorMessage("display sub menu not found\n");
return SCIP_PLUGINNOTFOUND;
}
assert( ! SCIPdialogHasEntry(displaymenu, "symmetries") );
SCIP_CALL( SCIPincludeDialog(scip, &dialog,
NULL, dialogExecDisplaySymmetry, NULL, NULL,
"symmetry", "display generators of symmetry group in cycle notation, if available",
FALSE, (SCIP_DIALOGDATA*)propdata) );
SCIP_CALL( SCIPaddDialogEntry(scip, displaymenu, dialog) );
SCIP_CALL( SCIPreleaseDialog(scip, &dialog) );

/* add parameters for computing symmetry */
SCIP_CALL( SCIPaddIntParam(scip,
"propagating/" PROP_NAME "/maxgenerators",
Expand Down Expand Up @@ -8246,6 +8194,41 @@ int SCIPgetSymmetryNGenerators(
return propdata->nperms;
}

/** displays generators of symmetry group, if available */
SCIP_RETCODE SCIPdisplaySymmetryGenerators(
SCIP* scip, /**< SCIP data structure */
SCIP_PROP* prop /**< symmetry propagator or NULL */
)
{ /*lint --e{715}*/
SCIP_PROPDATA* propdata;

if ( prop == NULL )
prop = SCIPfindProp(scip, PROP_NAME);
assert( prop != NULL );

propdata = SCIPpropGetData(prop);
assert( propdata != NULL );

if ( propdata->nperms == -1 )
{
SCIPinfoMessage(scip, NULL, "Cannot display symmetries. Symmetries have not been computed yet.\n");
}
else if ( propdata->nperms == 0 )
{
SCIPinfoMessage(scip, NULL, "Cannot display symmetries. No symmetries detected.\n");
}
else if ( propdata->ncomponents < 0 )
{
SCIP_CALL( displaySymmetriesWithoutComponents(scip, propdata) );
}
else
{
SCIP_CALL( displaySymmetriesWithComponents(scip, propdata) );
}

return SCIP_OKAY;
}

/** creates new operator node type (used for symmetry detection) and returns its representation
*
* If the operator node already exists, the function terminates with SCIP_INVALIDDATA.
Expand Down
7 changes: 7 additions & 0 deletions src/scip/prop_symmetry.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,13 @@ int SCIPgetSymmetryNGenerators(
SCIP* scip /**< SCIP data structure */
);

/** displays generators of symmetry group, if available */
SCIP_EXPORT
SCIP_RETCODE SCIPdisplaySymmetryGenerators(
SCIP* scip, /**< SCIP data structure */
SCIP_PROP* prop /**< symmetry propagator or NULL */
);

/** creates new operator node type (used for symmetry detection) and returns its representation
*
* If the operator node already exists, the function terminates with SCIP_INVALIDDATA.
Expand Down

0 comments on commit 8d07066

Please sign in to comment.