55 assert( scip !=
NULL );
56 assert( permvars !=
NULL );
57 assert( perms !=
NULL );
59 assert( npermvars > 0 );
60 assert( orbits !=
NULL );
61 assert( orbitbegins !=
NULL );
62 assert( norbits !=
NULL );
68 for (i = 0; i < npermvars; ++i)
73 for (i = 0; i < npermvars; ++i)
83 beginorbitidx = orbitidx;
84 orbits[orbitidx++] = i;
89 while ( j < orbitidx )
97 for (p = 0; p < nperms; ++p)
99 image = perms[p][curelem];
102 if ( ! varadded[image] )
104 orbits[orbitidx++] = image;
105 assert( orbitidx <= npermvars );
106 varadded[image] =
TRUE;
113 if ( orbitidx <= beginorbitidx + 1 )
114 orbitidx = beginorbitidx;
116 orbitbegins[(*norbits)++] = beginorbitidx;
120 assert( *norbits < npermvars );
121 orbitbegins[*norbits] = orbitidx;
124 printf(
"Orbits (total number: %d):\n", *norbits);
125 for (i = 0; i < *norbits; ++i)
130 for (j = orbitbegins[i]; j < orbitbegins[i+1]; ++j)
131 printf(
"%d ", orbits[j]);
165 int* componentbegins,
169 unsigned* componentblocked,
181 assert( scip !=
NULL );
182 assert( permstrans !=
NULL );
183 assert( nperms > 0 );
184 assert( npermvars > 0 );
185 assert( inactiveperms !=
NULL );
186 assert( orbits !=
NULL );
187 assert( orbitbegins !=
NULL );
188 assert( norbits !=
NULL );
189 assert( components !=
NULL );
190 assert( componentbegins !=
NULL );
191 assert( vartocomponent !=
NULL );
192 assert( ncomponents > 0 );
193 assert( nmovedpermvars > 0 );
199 for (i = 0; i < npermvars; ++i)
204 for (i = 0; i < npermvars; ++i)
211 componentidx = vartocomponent[i];
212 if ( componentidx < 0 || componentblocked[componentidx] )
220 beginorbitidx = orbitidx;
221 orbits[orbitidx++] = i;
227 while ( j < orbitidx )
236 pt = permstrans[curelem];
237 for (p = componentbegins[componentidx]; p < componentbegins[componentidx + 1]; ++p)
241 perm = components[p];
243 if ( ! inactiveperms[perm] )
246 assert( vartocomponent[image] == componentidx );
249 if ( ! varadded[image] )
251 orbits[orbitidx++] = image;
252 assert( orbitidx <= npermvars );
253 varadded[image] =
TRUE;
262 if ( orbitidx <= beginorbitidx + 1 )
263 orbitidx = beginorbitidx;
265 orbitbegins[(*norbits)++] = beginorbitidx;
268 if ( nvaradded >= nmovedpermvars )
273 assert( *norbits < npermvars );
274 orbitbegins[*norbits] = orbitidx;
277 printf(
"Orbits (total number: %d):\n", *norbits);
278 for (i = 0; i < *norbits; ++i)
283 for (j = orbitbegins[i]; j < orbitbegins[i+1]; ++j)
284 printf(
"%d ", orbits[j]);
308 int* componentbegins,
323 assert( scip !=
NULL );
324 assert( perms !=
NULL || permstrans !=
NULL );
325 assert( components !=
NULL );
326 assert( componentbegins !=
NULL );
327 assert( ignoredvars !=
NULL );
328 assert( orbit !=
NULL );
329 assert( orbitsize !=
NULL );
330 assert( 0 <= varidx && varidx < npermvars );
331 assert( component >= 0 );
332 assert( npermvars > 0 );
340 varstotest[0] = varidx;
343 varadded[varidx] =
TRUE;
345 if ( varfound !=
NULL )
346 varfound[varidx] =
TRUE;
350 while ( j < nvarstotest )
354 currvar = varstotest[j++];
356 for (p = componentbegins[component]; p < componentbegins[component+1]; ++p)
361 comp = components[p];
364 image = perms[comp][currvar];
366 image = permstrans[currvar][comp];
369 if ( ! varadded[image] )
371 varstotest[nvarstotest++] = image;
372 varadded[image] =
TRUE;
374 if ( ! ignoredvars[image] )
376 orbit[(*orbitsize)++] = image;
378 if ( varfound !=
NULL )
379 varfound[image] =
TRUE;
408 int* componentbegins,
422 assert( scip !=
NULL );
423 assert( permstrans !=
NULL );
424 assert( nperms > 0 );
425 assert( npermvars > 0 );
426 assert( components !=
NULL );
427 assert( componentbegins !=
NULL );
428 assert( vartocomponent !=
NULL );
429 assert( ncomponents > 0 );
430 assert( orbits !=
NULL );
431 assert( orbitbegins !=
NULL );
432 assert( norbits !=
NULL );
433 assert( varorbitmap !=
NULL );
439 for (i = 0; i < npermvars; ++i)
447 for (i = 0; i < npermvars; ++i)
454 componentidx = vartocomponent[i];
455 if ( componentidx < 0 )
463 beginorbitidx = orbitidx;
464 orbits[orbitidx++] = i;
466 varorbitmap[i] = *norbits;
470 while ( j < orbitidx )
479 pt = permstrans[curelem];
480 for (p = componentbegins[componentidx]; p < componentbegins[componentidx + 1]; ++p)
484 perm = components[p];
486 assert( vartocomponent[image] == componentidx );
489 if ( ! varadded[image] )
491 orbits[orbitidx++] = image;
492 assert( orbitidx <= npermvars );
493 varadded[image] =
TRUE;
494 varorbitmap[image] = *norbits;
501 if ( orbitidx <= beginorbitidx + 1 )
503 orbitidx = beginorbitidx;
507 orbitbegins[(*norbits)++] = beginorbitidx;
511 assert( *norbits < npermvars );
512 orbitbegins[*norbits] = orbitidx;
536 assert( perm !=
NULL );
537 assert( vars !=
NULL );
538 assert( ntwocyclesperm !=
NULL );
539 assert( nbincyclesperm !=
NULL );
543 for (i = 0; i < nvars; ++i)
545 assert( 0 <= perm[i] && perm[i] < nvars );
551 if ( perm[perm[i]] == i )
555 else if ( earlytermination )
568 *ntwocyclesperm = ntwocycles;
588 assert( scip !=
NULL );
589 assert( perms !=
NULL );
590 assert( nperms > 0 );
591 assert( permvars !=
NULL );
592 assert( npermvars > 0 );
593 assert( nvarsaffected !=
NULL );
600 for (p = 0; p < nperms; ++p)
602 for (i = 0; i < npermvars; ++i)
607 if ( perms[p][i] != i )
641 int nintersections = 0;
646 assert( suborbitope !=
NULL );
648 assert( nfilledcols > 0 );
649 assert( coltoextend >= 0 );
650 assert( perm !=
NULL );
651 assert( nusedelems !=
NULL );
652 assert( permvars !=
NULL );
653 assert( success !=
NULL );
654 assert( infeasible !=
NULL );
661 if ( nfilledcols == 2 )
664 for (row = 0; row < nrows; ++row)
666 idx1 = suborbitope[row][0];
667 idx2 = suborbitope[row][1];
670 if ( idx1 != perm[idx1] )
673 if ( ! leftextension )
675 suborbitope[row][0] = idx2;
676 suborbitope[row][1] = idx1;
678 assert( rowisbinary ==
NULL || rowisbinary[row] ==
SCIPvarIsBinary(permvars[perm[idx1]]) );
680 suborbitope[row][2] = perm[idx1];
683 ++(*nusedelems)[idx1];
684 ++(*nusedelems)[perm[idx1]];
687 if ( (*nusedelems)[idx1] > 2 || (*nusedelems)[perm[idx1]] > 2 )
693 else if ( idx2 != perm[idx2] )
698 suborbitope[row][0] = idx2;
699 suborbitope[row][1] = idx1;
701 assert( rowisbinary ==
NULL || rowisbinary[row] ==
SCIPvarIsBinary(permvars[perm[idx1]]) );
703 suborbitope[row][2] = perm[idx2];
706 ++(*nusedelems)[idx2];
707 ++(*nusedelems)[perm[idx2]];
710 if ( (*nusedelems)[idx2] > 2 || (*nusedelems)[perm[idx2]] > 2 )
721 for (row = 0; row < nrows; ++row)
723 idx1 = suborbitope[row][coltoextend];
726 if ( idx1 != perm[idx1] )
728 assert( rowisbinary ==
NULL || rowisbinary[row] ==
SCIPvarIsBinary(permvars[perm[idx1]]) );
730 suborbitope[row][nfilledcols] = perm[idx1];
733 ++(*nusedelems)[idx1];
734 ++(*nusedelems)[perm[idx1]];
737 if ( (*nusedelems)[idx1] > 2 || (*nusedelems)[perm[idx1]] > 2 )
747 if ( nintersections > 0 && nintersections < nrows )
749 else if ( nintersections == nrows )
766 int** componentbegins,
768 int** vartocomponent,
770 unsigned** componentblocked,
777 int* permtocomponent;
782 assert( scip !=
NULL );
783 assert( permvars !=
NULL );
784 assert( npermvars > 0 );
785 assert( perms !=
NULL );
786 assert( components !=
NULL );
787 assert( componentbegins !=
NULL );
788 assert( vartocomponent !=
NULL );
789 assert( componentblocked !=
NULL );
790 assert( ncomponents !=
NULL );
796 *ncomponents = npermvars;
800 for (p = 0; p < nperms; ++p)
801 permtovarcomp[p] = -1;
805 for (i = 0; i < npermvars; ++i)
807 (*vartocomponent)[i] = -1;
809 for (p = 0; p < nperms; ++p)
813 img = transposed ? perms[i][p] : perms[p][i];
824 (*vartocomponent)[i] = p;
825 (*vartocomponent)[img] = p;
828 if ( component2 < component1 )
833 component1 = component2;
838 if ( permtovarcomp[p] == -1 )
840 permtovarcomp[p] = component1;
841 representative = component1;
846 representative = permtovarcomp[p];
850 if ( component1 != component2 )
858 if ( representative != component1 && representative != component2 )
860 if ( representative > component1 )
863 permtovarcomp[p] = component1;
869 else if ( representative > component1 )
871 assert( representative == component2 );
872 permtovarcomp[p] = component1;
878 if ( (*vartocomponent)[i] == -1 )
881 assert( *ncomponents > 0 );
884 for (p = 0; p < nperms; ++p)
889 for (p = 0; p < nperms; ++p)
890 (*components)[p] = p;
899 (*componentbegins)[0] = 0;
900 permtocomponent[(*components)[0]] = 0;
903 for (p = 1; p < nperms; ++p)
905 if ( permtovarcomp[p] > permtovarcomp[p - 1] )
906 (*componentbegins)[++idx] = p;
908 assert( (*components)[p] >= 0 );
909 assert( (*components)[p] < nperms );
910 permtocomponent[(*components)[p]] = idx;
912 assert( *ncomponents == idx + 1 );
913 (*componentbegins)[++idx] = nperms;
916 for (i = 0; i < npermvars; ++i)
919 permidx = (*vartocomponent)[i];
920 assert( -1 <= permidx && permidx < nperms );
924 assert( 0 <= permtocomponent[permidx] );
925 assert( permtocomponent[permidx] < *ncomponents );
927 (*vartocomponent)[i] = permtocomponent[permidx];
933 for (i = 0; i < *ncomponents; ++i)
934 (*componentblocked)[i] = 0;
941 printf(
"number of components: %d\n", propdata->ncomponents);
942 for (i = 0; i < *ncomponents; ++i)
944 printf(
"Component %d contains the following permutations:\n\t", i);
945 for (p = (*componentbegins)[i]; p < (*componentbegins)[i + 1]; ++p)
947 printf(
"%d, ", (*components)[p]);
968 int** orbitopevaridx,
983 int nvarsorderold = 0;
985 assert( vars !=
NULL );
988 assert( permvars !=
NULL );
989 assert( npermvars > 0 );
990 assert( orbitopevaridx !=
NULL );
991 assert( columnorder !=
NULL );
992 assert( nusedelems !=
NULL );
993 assert( infeasible !=
NULL );
994 assert( ! storelexorder || lexorder !=
NULL );
995 assert( ! storelexorder || nvarsorder !=
NULL );
996 assert( ! storelexorder || maxnvarsorder !=
NULL );
1002 if ( storelexorder )
1004 assert( *nvarsorder == *maxnvarsorder );
1005 assert( lexorder !=
NULL );
1007 *maxnvarsorder += nrows * ncols;
1008 nvarsorderold = *nvarsorder;
1010 if ( *lexorder ==
NULL )
1020 curcolumn = ncols - 1;
1023 while ( curcolumn >= 0 && columnorder[curcolumn] >= 0 && ! *infeasible )
1026 for (i = 0; i < nrows; ++i)
1029 if ( rowisbinary !=
NULL && ! rowisbinary[i] )
1032 assert( 0 <= orbitopevaridx[i][curcolumn] && orbitopevaridx[i][curcolumn] < npermvars );
1036 if ( nfilledcols == 0 && nusedelems[orbitopevaridx[i][curcolumn]] > 1 )
1039 assert( ! storelexorder );
1043 if ( storelexorder )
1045 (*lexorder)[nvarsorderold + nrows * nfilledcols + cnt] = orbitopevaridx[i][curcolumn];
1048 (*vars)[cnt++][nfilledcols] = permvars[orbitopevaridx[i][curcolumn]];
1060 assert( curcolumn > 1 || (curcolumn < 0 && nfilledcols == ncols) );
1062 if ( curcolumn > 1 && ! *infeasible )
1066 for (i = 0; i < nrows; ++i)
1069 if ( rowisbinary !=
NULL && ! rowisbinary[i] )
1072 assert( orbitopevaridx[i][1] < npermvars );
1075 if ( storelexorder )
1077 (*lexorder)[nvarsorderold + nrows * nfilledcols + cnt] = orbitopevaridx[i][1];
1080 (*vars)[cnt++][nfilledcols] = permvars[orbitopevaridx[i][1]];
1086 for (i = 0; i < nrows; ++i)
1089 if ( rowisbinary !=
NULL && ! rowisbinary[i] )
1092 assert( orbitopevaridx[i][0] < npermvars );
1095 if ( storelexorder )
1097 (*lexorder)[nvarsorderold + nrows * nfilledcols + cnt] = orbitopevaridx[i][0];
1100 (*vars)[cnt++][nfilledcols] = permvars[orbitopevaridx[i][0]];
1105 if ( nfilledcols < ncols )
1107 assert( ncols > 2 );
1110 while ( nfilledcols < ncols && ! *infeasible )
1112 assert( columnorder[curcolumn] < 0 );
1115 for (i = 0; i < nrows; ++i)
1118 if ( rowisbinary !=
NULL && ! rowisbinary[i] )
1121 assert( orbitopevaridx[i][curcolumn] < npermvars );
1125 if ( nfilledcols == ncols - 1 && nusedelems[orbitopevaridx[i][curcolumn]] > 1 )
1128 assert( ! storelexorder );
1132 if ( storelexorder )
1134 (*lexorder)[nvarsorderold + nrows * nfilledcols + cnt] = orbitopevaridx[i][curcolumn];
1137 (*vars)[cnt++][nfilledcols] = permvars[orbitopevaridx[i][curcolumn]];
1170 int* rowcoveragesetppc;
1178 assert( scip !=
NULL );
1179 assert( vars !=
NULL );
1180 assert( vars !=
NULL );
1181 assert( nrows > 0 );
1182 assert( ncols > 0 );
1183 assert( type !=
NULL );
1186 if ( npprows !=
NULL )
1190 if ( setppcconshdlr ==
NULL )
1200 if ( nsetppcconss == 0 || (nsetppcconss < nrows && npprows ==
NULL ))
1202 assert( setppcconss !=
NULL );
1214 for (i = 0; i < nprobvars; ++i)
1217 for (i = 0; i < nrows; ++i)
1219 for (j = 0; j < ncols; ++j)
1238 for (c = 0; c < nsetppcconss && ncoveredpart < ncols; ++c)
1242 int nrowintersect = 0;
1243 int nvarsinorbitope;
1253 if ( nsetppcvars < ncols )
1257 assert( setppcvars !=
NULL );
1260 nvarsinorbitope = nsetppcvars;
1266 for (i = 0; i < nsetppcvars && nvarsinorbitope >= ncols; ++i)
1272 var = setppcvars[i];
1275 assert( 0 <= idx && idx < nprobvars );
1277 rowidx = rowidxvar[idx];
1287 if ( covered[rowidx] == 2 || (covered[rowidx] == 1 && (nsetppcvars > ncols || nrowintersect > 1)) )
1294 if ( rowcoveragesetppc[rowidx] == 0 )
1295 rowsinsetppc[nrowintersect++] = rowidx;
1296 ++(rowcoveragesetppc[rowidx]);
1301 if ( nsetppcvars - nrowintersect < ncols - 1 )
1309 && nrowintersect == 1 && rowcoveragesetppc[rowsinsetppc[0]] == ncols && nsetppcvars == ncols )
1311 if ( covered[rowsinsetppc[0]] == 1 )
1313 covered[rowsinsetppc[0]] = 2;
1319 for (i = 0; i < nrowintersect; ++i)
1321 if ( covered[rowsinsetppc[i]] == 0 && rowcoveragesetppc[rowsinsetppc[i]] >= ncols )
1323 covered[rowsinsetppc[i]] = 1;
1330 for (i = 0; i < nrowintersect; ++i)
1331 rowcoveragesetppc[rowsinsetppc[i]] = 0;
1335 if ( ncovered == nrows )
1337 if ( ncoveredpart == nrows )
1343 if ( npprows !=
NULL )
1344 *npprows = ncovered;
1346 if ( pprows !=
NULL )
1349 for (i = 0; i < nrows; ++i)
1350 (*pprows)[i] = covered[i] > 0 ? 1 : 0;
SCIP_RETCODE SCIPcomputeComponentsSym(SCIP *scip, int **perms, int nperms, SCIP_VAR **permvars, int npermvars, SCIP_Bool transposed, int **components, int **componentbegins, int **vartocomponent, unsigned **componentblocked, int *ncomponents)
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
#define SCIPallocBlockMemoryArray(scip, ptr, num)
enum SCIP_OrbitopeType SCIP_ORBITOPETYPE
void SCIPdisjointsetUnion(SCIP_DISJOINTSET *djset, int p, int q, SCIP_Bool forcerepofp)
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
int SCIPgetNVarsSetppc(SCIP *scip, SCIP_CONS *cons)
#define SCIPallocClearBufferArray(scip, ptr, num)
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
SCIP_RETCODE SCIPcomputeOrbitsSym(SCIP *scip, SCIP_VAR **permvars, int npermvars, int **perms, int nperms, int *orbits, int *orbitbegins, int *norbits)
SCIP_RETCODE SCIPcomputeOrbitsFilterSym(SCIP *scip, int npermvars, int **permstrans, int nperms, SCIP_Shortbool *inactiveperms, int *orbits, int *orbitbegins, int *norbits, int *components, int *componentbegins, int *vartocomponent, unsigned *componentblocked, int ncomponents, int nmovedpermvars)
SCIP_CONS ** SCIPconshdlrGetConss(SCIP_CONSHDLR *conshdlr)
enum SCIP_Retcode SCIP_RETCODE
#define SCIPfreeBufferArray(scip, ptr)
Constraint handler for the set partitioning / packing / covering constraints .
#define SCIPallocCleanBufferArray(scip, ptr, num)
void SCIPsortIntInt(int *intarray1, int *intarray2, int len)
void SCIPdisjointsetFree(SCIP_DISJOINTSET **djset, BMS_BLKMEM *blkmem)
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
SCIP_RETCODE SCIPisPackingPartitioningOrbitope(SCIP *scip, SCIP_VAR ***vars, int nrows, int ncols, SCIP_Bool **pprows, int *npprows, SCIP_ORBITOPETYPE *type)
internal miscellaneous methods
int SCIPdisjointsetFind(SCIP_DISJOINTSET *djset, int element)
int SCIPgetNTotalVars(SCIP *scip)
int SCIPconshdlrGetNConss(SCIP_CONSHDLR *conshdlr)
#define SCIPallocBufferArray(scip, ptr, num)
SCIP_RETCODE SCIPdetermineNVarsAffectedSym(SCIP *scip, int **perms, int nperms, SCIP_VAR **permvars, int npermvars, int *nvarsaffected)
SCIP_SETPPCTYPE SCIPgetTypeSetppc(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPisInvolutionPerm(int *perm, SCIP_VAR **vars, int nvars, int *ntwocyclesperm, int *nbincyclesperm, SCIP_Bool earlytermination)
SCIP_RETCODE SCIPgenerateOrbitopeVarsMatrix(SCIP *scip, SCIP_VAR ****vars, int nrows, int ncols, SCIP_VAR **permvars, int npermvars, int **orbitopevaridx, int *columnorder, int *nusedelems, SCIP_Shortbool *rowisbinary, SCIP_Bool *infeasible, SCIP_Bool storelexorder, int **lexorder, int *nvarsorder, int *maxnvarsorder)
SCIP_RETCODE SCIPextendSubOrbitope(int **suborbitope, int nrows, int nfilledcols, int coltoextend, int *perm, SCIP_Bool leftextension, int **nusedelems, SCIP_VAR **permvars, SCIP_Shortbool *rowisbinary, SCIP_Bool *success, SCIP_Bool *infeasible)
SCIP_VAR ** SCIPgetVarsSetppc(SCIP *scip, SCIP_CONS *cons)
type definitions for symmetry computations
methods for handling symmetries
SCIP_RETCODE SCIPcomputeOrbitVar(SCIP *scip, int npermvars, int **perms, int **permstrans, int *components, int *componentbegins, SCIP_Shortbool *ignoredvars, SCIP_Shortbool *varfound, int varidx, int component, int *orbit, int *orbitsize)
SCIP_RETCODE SCIPcomputeOrbitsComponentsSym(SCIP *scip, int npermvars, int **permstrans, int nperms, int *components, int *componentbegins, int *vartocomponent, int ncomponents, int *orbits, int *orbitbegins, int *norbits, int *varorbitmap)
#define SCIPfreeCleanBufferArray(scip, ptr)
int SCIPvarGetIndex(SCIP_VAR *var)
SCIP_RETCODE SCIPdisjointsetCreate(SCIP_DISJOINTSET **djset, BMS_BLKMEM *blkmem, int ncomponents)