Skip to content

Commit

Permalink
Merge branch '3669-error-in-symmetry-test-under-windows' into 'v90-bu…
Browse files Browse the repository at this point in the history
…gfix'

Resolve "Error in symmetry test under windows"

See merge request integer/scip!3312
  • Loading branch information
svigerske committed Feb 5, 2024
2 parents 1428419 + a1c6dd6 commit a7f4801
Showing 1 changed file with 75 additions and 11 deletions.
86 changes: 75 additions & 11 deletions src/scip/prop_symmetry.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
*/
/* #define SCIP_OUTPUT */
/* #define SCIP_OUTPUT_COMPONENT */
/* #define SCIP_DISPLAY_SYM_CHECK */

/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/

Expand Down Expand Up @@ -735,6 +736,7 @@ SCIP_DECL_SORTINDCOMP(SYMsortGraphCompVars)
*/
static
int compareSymgraphs(
SCIP* scip, /**< SCIP pointer (or NULL) */
SYM_GRAPH* G1, /**< first graph in comparison */
SYM_GRAPH* G2 /**< second graph in comparison */
)
Expand All @@ -760,15 +762,31 @@ int compareSymgraphs(
if ( SCIPconsGetHdlr(G1->conss[perm1]) > SCIPconsGetHdlr(G2->conss[perm2]) )
return 1;

if ( G1->lhs[perm1] < G2->lhs[perm2] )
return -1;
if ( G1->lhs[perm1] > G2->lhs[perm2] )
return 1;

if ( G1->rhs[perm1] < G2->rhs[perm2] )
return -1;
if ( G1->rhs[perm1] > G2->rhs[perm2] )
return 1;
/* compare using SCIP functions when SCIP is available */
if ( scip != NULL )
{
if ( SCIPisLT(scip, G1->lhs[perm1], G2->lhs[perm2]) )
return -1;
if ( SCIPisGT(scip, G1->lhs[perm1], G2->lhs[perm2]) )
return 1;

if ( SCIPisLT(scip, G1->rhs[perm1], G2->rhs[perm2]) )
return -1;
if ( SCIPisGT(scip, G1->rhs[perm1], G2->rhs[perm2]) )
return 1;
}
else
{
if ( G1->lhs[perm1] < G2->lhs[perm2] )
return -1;
if ( G1->lhs[perm1] > G2->lhs[perm2] )
return 1;

if ( G1->rhs[perm1] < G2->rhs[perm2] )
return -1;
if ( G1->rhs[perm1] > G2->rhs[perm2] )
return 1;
}
}

/* compare number of remaining node types */
Expand Down Expand Up @@ -817,7 +835,7 @@ SCIP_DECL_SORTINDCOMP(SYMsortSymgraphs)
G1 = data[ind1];
G2 = data[ind2];

return compareSymgraphs(G1, G2);
return compareSymgraphs(NULL, G1, G2);
}

/*
Expand Down Expand Up @@ -1501,6 +1519,10 @@ SCIP_RETCODE checkSymmetriesAreSymmetries(
int p;
int c;
int g;
#ifdef SCIP_DISPLAY_SYM_CHECK
int permlen;
SCIP_Bool* covered;
#endif

assert( scip != NULL );
assert( perms != NULL );
Expand Down Expand Up @@ -1550,7 +1572,7 @@ SCIP_RETCODE checkSymmetriesAreSymmetries(
groupbegins[0] = 0;
for (c = 1; c < nconss; ++c)
{
if ( compareSymgraphs(graphs[graphperm[c]], graphs[graphperm[c-1]]) != 0 )
if ( compareSymgraphs(scip, graphs[graphperm[c]], graphs[graphperm[c-1]]) != 0 )
groupbegins[ngroups++] = c;
}
groupbegins[ngroups] = nconss;
Expand All @@ -1561,43 +1583,85 @@ SCIP_RETCODE checkSymmetriesAreSymmetries(
SCIP_CALL( SCIPfreeSymgraphConsnodeperm(scip, graphs[c]) );
}

#ifdef SCIP_DISPLAY_SYM_CHECK
permlen = symtype == SYM_SYMTYPE_SIGNPERM ? 2 * npermvars : npermvars;
SCIP_CALL( SCIPallocClearBufferArray(scip, &covered, permlen) );
#endif

/* iterate over all permutations and check whether they define symmetries */
for (p = 0; p < nperms; ++p)
{
SYM_GRAPH* graph;
SCIP_Bool found = TRUE;
int d;
#ifdef SCIP_DISPLAY_SYM_CHECK
int i;

SCIPinfoMessage(scip, NULL, "Check whether permutation %d is a symmetry:\n", p);
for (i = 0; i < permlen; ++i)
{
SCIP_CALL( displayCycleOfSymmetry(scip, perms[p], symtype, i, covered, npermvars, SCIPgetVars(scip)) );
}

for (i = 0; i < permlen; ++i)
covered[i] = FALSE;
SCIPinfoMessage(scip, NULL, "Check whether every constraint has a symmetric counterpart.\n");
#endif

/* for every constraint, create permuted graph by copying nodes and edges */
for (g = 0; g < ngroups; ++g)
{
for (c = groupbegins[g]; c < groupbegins[g+1]; ++c)
{
#ifdef SCIP_DISPLAY_SYM_CHECK
SCIPinfoMessage(scip, NULL, "Check whether constraint %d has a symmetric counterpart:\n",
graphperm[c]);
SCIP_CALL( SCIPprintCons(scip, conss[graphperm[c]], NULL) );
SCIPinfoMessage(scip, NULL, "\n");
#endif
SCIP_CALL( SCIPcopySymgraph(scip, &graph, graphs[graphperm[c]], perms[p], fixedtype) );

/* if adapted graph is equivalent to original graph, we don't need to check further graphs */
if ( SYMcheckGraphsAreIdentical(scip, symtype, graph, graphs[graphperm[c]]) )
{
#ifdef SCIP_DISPLAY_SYM_CHECK
SCIPinfoMessage(scip, NULL, "\tconstraint is symmetric to itself\n");
#endif
SCIP_CALL( SCIPfreeSymgraph(scip, &graph) );
continue;
}

/* check whether graph has an isomorphic counterpart */
found = FALSE;
for (d = groupbegins[g]; d < groupbegins[g+1] && ! found; ++d)
{
found = SYMcheckGraphsAreIdentical(scip, symtype, graph, graphs[graphperm[d]]);

#ifdef SCIP_DISPLAY_SYM_CHECK
SCIPinfoMessage(scip, NULL, "\tconstraint is %ssymmetric to constraint %d\n\t", !found ? "not " : "", d);
SCIP_CALL( SCIPprintCons(scip, conss[graphperm[d]], NULL) );
SCIPinfoMessage(scip, NULL, "\n");
#endif
}

SCIP_CALL( SCIPfreeSymgraph(scip, &graph) );

if ( ! found )
{
#ifdef SCIP_DISPLAY_SYM_CHECK
SCIPfreeBufferArray(scip, &covered);
#endif
SCIPerrorMessage("permutation %d is not a symmetry\n", p);
return SCIP_ERROR;
}
}
}
}

#ifdef SCIP_DISPLAY_SYM_CHECK
SCIPfreeBufferArray(scip, &covered);
#endif

SCIPfreeBufferArray(scip, &groupbegins);
SCIPfreeBufferArray(scip, &graphperm);

Expand Down

0 comments on commit a7f4801

Please sign in to comment.