prop_symmetry.c
Go to the documentation of this file.
35 * - It allows to compute symmetries of the problem and to store this information in adequate form. The symmetry
39 * - (dynamic) orbitopal reduction, which generalizes (dynamic) orbital fixing. See symmetry_orbitopal.c
40 * - static orbitopal fixing (for binary variable domains) for full orbitopes. See cons_orbitope.c
41 * - static orbitopal fixing (for binary variable domains) for packing-partitioning orbitopes. See cons_orbitope.c
43 * - static lexicographic fixing for binary variable domains (i.e., symresack propagation). See cons_symresack.c
44 * - static lexicographic fixing for binary variable domains on involutions (i.e., orbisacks). See cons_orbisack.c
52 * We do not copy symmetry information, since it is not clear how this information transfers. Moreover, copying
53 * symmetry might inhibit heuristics. But note that solving a sub-SCIP might then happen without symmetry information!
58 * Many common methods are captured by a framework that dynamifies symmetry handling constraints. The ideas are
63 * This paper shows that various symmetry handling methods are compatible under certain conditions, and provides
64 * generalizations to common symmetry handling constraints from binary variable domains to arbitrary variable domains.
65 * This includes symresack propagation, orbitopal fixing, and orbital fixing, that are generalized to
66 * lexicographic reduction, orbitopal reduction and orbital reduction, respectively. For a description and
67 * implementation, see symmetry_lexred.c, symmetry_orbitopal.c and symmetry_orbital.c, respectively.
68 * The static counterparts on binary variable domains are cons_symresack.c and cons_orbisack.c for lexicographic
69 * reduction (cf. symresack propagation), and cons_orbitope.c and cons_orbisack.c for orbitopal reduction
70 * (cf. orbitopal fixing). We refer to the description of tryAddSymmetryHandlingMethods for the order in which these
76 * D. Salvagnin: Symmetry Breaking Inequalities from the Schreier-Sims table. CPAIOR 2018 Proceedings, 521-529, 2018.
78 * These inequalities are computed as follows. Throughout these procedure a set of so-called leaders is maintained.
79 * Initially the set of leaders is empty. In a first step, select a variable \f$x_i\f$ and compute its orbit w.r.t.
80 * the symmetry group of the mixed-integer program. For each variable \f$x_j\f$ in the orbit of \f$x_i\f$, the
81 * inequality \f$x_i \geq x_j\f$ is a valid symmetry handling inequality, which can be added to the mixed-integer
82 * program. We call \f$x_i\f$ the leader of this inequality. Add the leader \f$x_i\f$ to the set of leaders and
83 * compute the pointwise stabilizer of the leader set. In the next step, select a new variable, compute its orbit
84 * w.r.t. the stabilizer group of the leaders, add the inequalities based on this orbit, and add the new leader
85 * to the set of leaders. This procedure is iterated until the pointwise stabilizer group of the leaders has become
96 * @todo Order rows of orbitopes (in particular packing/partitioning) w.r.t. cliques in conflict graph.
104/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
146#define PROP_DELAY FALSE /**< should propagation method be delayed, if other propagators found reductions? */
148#define PROP_PRESOL_PRIORITY -10000000 /**< priority of the presolving method (>= 0: before, < 0: after constraint handlers) */
149#define PROP_PRESOLTIMING SCIP_PRESOLTIMING_EXHAUSTIVE /* timing of the presolving method (fast, medium, or exhaustive) */
150#define PROP_PRESOL_MAXROUNDS -1 /**< maximal number of presolving rounds the presolver participates in (-1: no limit) */
154#define DEFAULT_MAXGENERATORS 1500 /**< limit on the number of generators that should be produced within symmetry detection (0 = no limit) */
155#define DEFAULT_CHECKSYMMETRIES FALSE /**< Should all symmetries be checked after computation? */
156#define DEFAULT_DISPLAYNORBITVARS FALSE /**< Should the number of variables affected by some symmetry be displayed? */
157#define DEFAULT_USECOLUMNSPARSITY FALSE /**< Should the number of conss a variable is contained in be exploited in symmetry detection? */
159#define DEFAULT_COMPRESSSYMMETRIES TRUE /**< Should non-affected variables be removed from permutation to save memory? */
160#define DEFAULT_COMPRESSTHRESHOLD 0.5 /**< Compression is used if percentage of moved vars is at most the threshold. */
162#define DEFAULT_ENFORCECOMPUTESYMMETRY FALSE /**< always compute symmetries, even if they cannot be handled */
166#define DEFAULT_CONSSADDLP TRUE /**< Should the symmetry breaking constraints be added to the LP? */
168#define DEFAULT_DETECTDOUBLELEX TRUE /**< Should we check whether the components of the symmetry group can be handled by double lex matrices? */
169#define DEFAULT_DETECTORBITOPES TRUE /**< Should we check whether the components of the symmetry group can be handled by orbitopes? */
170#define DEFAULT_DETECTSUBGROUPS TRUE /**< Should we try to detect orbitopes in subgroups of the symmetry group? */
171#define DEFAULT_ADDWEAKSBCS TRUE /**< Should we add weak SBCs for enclosing orbit of symmetric subgroups? */
172#define DEFAULT_ADDSTRONGSBCS FALSE /**< Should we add strong SBCs for enclosing orbit of symmetric subgroups if orbitopes are not used? */
173#define DEFAULT_ADDCONSSTIMING 2 /**< timing of adding constraints (0 = before presolving, 1 = during presolving, 2 = after presolving) */
174#define DEFAULT_MAXNCONSSSUBGROUP 500000 /**< Maximum number of constraints up to which subgroup structures are detected */
175#define DEFAULT_USEDYNAMICPROP TRUE /**< whether dynamic propagation should be used for full orbitopes */
176#define DEFAULT_PREFERLESSROWS TRUE /**< Shall orbitopes with less rows be preferred in detection? */
179#define DEFAULT_SYMCOMPTIMING 2 /**< timing of symmetry computation (0 = before presolving, 1 = during presolving, 2 = at first call) */
180#define DEFAULT_PERFORMPRESOLVING 0 /**< Run orbital fixing during presolving? (disabled parameter) */
181#define DEFAULT_RECOMPUTERESTART 0 /**< Recompute symmetries after a restart has occurred? (0 = never) */
184#define DEFAULT_SSTTIEBREAKRULE 1 /**< index of tie break rule for selecting orbit for Schreier Sims constraints? */
185#define DEFAULT_SSTLEADERRULE 0 /**< index of rule for selecting leader variables for Schreier Sims constraints? */
186#define DEFAULT_SSTLEADERVARTYPE 14 /**< bitset encoding which variable types can be leaders (1: binary; 2: integer; 4: impl. int; 8: continuous);
188#define DEFAULT_ADDCONFLICTCUTS TRUE /**< Should Schreier Sims constraints be added if we use a conflict based rule? */
190#define DEFAULT_SSTMIXEDCOMPONENTS TRUE /**< Should Schreier Sims constraints be added if a symmetry component contains variables of different types? */
196#define TABLE_EARLIEST_SYMMETRY SCIP_STAGE_SOLVING /**< output of the statistics table is only printed from this stage onwards */
200#define MAXGENNUMERATOR 64000000 /**< determine maximal number of generators by dividing this number by the number of variables */
201#define COMPRESSNVARSLB 25000 /**< lower bound on the number of variables above which compression could be performed */
202#define DEFAULT_NAUTYMAXNCELLS 100000 /**< terminate symmetry detection using Nauty when number of cells in color refinment is at least this number
204#define DEFAULT_NAUTYMAXNNODES 10000000 /**< terminate symmetry detection using Nauty when its search tree has at least this number of nodes */
205/*@todo investigate why the Nauty works well for some large instances (miplib2010/mspp16.mps) but not for PB instances (e.g., normalized-celar6-sub0_wcsp.wbo) */
231 int** permstrans; /**< pointer to store transposed permutation generators as (npermvars x nperms) matrix */
236 int nmovedimplintpermvars; /**< number of implicitly integer variables moved by any permutation */
241 SCIP_Real* permvardomaincenter; /**< center of variable domains (needed for signed permutations) */
252 unsigned* componentblocked; /**< array to store which symmetry methods have been applied to a component using
254 SCIP_Bool* componenthassignedperm; /**< array to indicate whether a component has a signed permutation */
262 int maxgenerators; /**< limit on the number of generators that should be produced within symmetry detection (0 = no limit) */
264 SCIP_Bool displaynorbitvars; /**< Whether the number of variables in non-trivial orbits shall be computed */
265 SCIP_Bool compresssymmetries; /**< Should non-affected variables be removed from permutation to save memory? */
266 SCIP_Real compressthreshold; /**< Compression is used if percentage of moved vars is at most the threshold. */
270 SCIP_Bool usecolumnsparsity; /**< Should the number of conss a variable is contained in be exploited in symmetry detection? */
272 SCIP_Bool enforcecomputesymmetry; /**< always compute symmetries, even if they cannot be handled */
273 int symtiming; /**< timing of computing and handling symmetries (0 = before presolving, 1 = during presolving, 2 = after presolving) */
286 SCIP_Bool detectdoublelex; /**< Should we check whether the components of the symmetry group can be handled by double lex matrices? */
287 SCIP_Bool detectorbitopes; /**< Should we check whether the components of the symmetry group can be handled by orbitopes? */
288 SCIP_Bool detectsubgroups; /**< Should we try to detect orbitopes in subgroups of the symmetry group? */
289 SCIP_Bool addweaksbcs; /**< Should we add weak SBCs for enclosing orbit of symmetric subgroups? */
290 SCIP_Bool addstrongsbcs; /**< Should we add strong SBCs for enclosing orbit of symmetric subgroups if orbitopes are not used? */
294 int maxnconsssubgroup; /**< maximum number of constraints up to which subgroup structures are detected */
299 int recomputerestart; /**< Recompute symmetries after a restart has occurred? (0 = never, 1 = always, 2 = if symmetry reduction found) */
301 SCIP_Bool symfoundreduction; /**< whether symmetry handling propagation has found a reduction since the last time computing symmetries */
314 SCIP_Bool addconflictcuts; /**< Should Schreier Sims constraints be added if we use a conflict based rule? */
316 SCIP_Bool sstmixedcomponents; /**< Should Schreier Sims constraints be added if a symmetry component contains variables of different types? */
360 SCIP_DECL_SORTPTRCOMP((*compfunc)) /**< comparator function that was used to sort arr1 and arr2; must define a total ordering */
493 SCIPinfoMessage(scip, NULL, "Display permutations as signed permutations (allowing translations)\n");
504 SCIP_CALL( displayCycleOfSymmetry(scip, perm, symtype, i, covered, npermvars, propdata->permvars) );
552 SCIPinfoMessage(scip, NULL, " Symmetries are displayed as signed permutations (allowing translations).\n");
558 for (p = propdata->componentbegins[c], cnt = 0; p < propdata->componentbegins[c + 1]; ++p, ++cnt)
565 SCIP_CALL( displayCycleOfSymmetry(scip, perm, symtype, i, covered, npermvars, propdata->permvars) );
592 SCIPinfoMessage(scip, NULL, "Cannot display symmetries. Symmetries have not been computed yet.\n");
647 SCIP_CALL( SCIPorbitopalReductionGetStatistics(scip, tabledata->propdata->orbitopalreddata, &nred, &ncutoff) );
648 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, file, " orbitopal red. : %10d reductions applied,"
653 SCIP_CALL( SCIPorbitalReductionGetStatistics(scip, tabledata->propdata->orbitalreddata, &nred, &ncutoff) );
654 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, file, " orbital reduction: %10d reductions applied,"
659 SCIP_CALL( SCIPlexicographicReductionGetStatistics(scip, tabledata->propdata->lexreddata, &nred, &ncutoff) );
660 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, file, " lexicographic red: %10d reductions applied,"
665 time = SCIPgetShadowTreeEventHandlerExecutionTime(scip, tabledata->propdata->shadowtreeeventhdlr);
1095/** makes sure that the constraint array (potentially NULL) of given array size is sufficiently large */
1150 int* nmovedvars, /**< pointer to store number of vars affected by symmetry (if usecompression) or NULL */
1151 SCIP_Bool* binvaraffected, /**< pointer to store whether a binary variable is affected by symmetry */
1153 SCIP_Real compressthreshold, /**< if percentage of moved vars is at most threshold, compression is done */
1225 /* iterate over labels and adapt permutation (possibly taking signed permutations into account) */
1271 /* detect whether binary variable is affected by symmetry and count number of binary permvars */
1318/** returns whether all constraint handlers with constraints can provide symmetry information */
1339 if ( ! conshdlrCanProvideSymInformation(conshdlr, symtype) && SCIPconshdlrGetNConss(conshdlr) > 0 )
1349 " Symmetry detection interrupted: constraints of type %s do not provide symmetry information.\n"
1391 SCIPwarningMessage(scip, "Expression handler %s does not implement the EXPRGETSYMDATA callback.\n"
1392 "Computed symmetries might be incorrect if the expression uses different constants or assigns\n"
1608 SCIP_CALL( displayCycleOfSymmetry(scip, perms[p], symtype, i, covered, npermvars, SCIPgetVars(scip)) );
1646 SCIPinfoMessage(scip, NULL, "\tconstraint is %ssymmetric to constraint %d\n\t", !found ? "not " : "", d);
1687 SCIP_Bool compresssymmetries, /**< Should non-affected variables be removed from permutation to save memory? */
1688 SCIP_Real compressthreshold, /**< if percentage of moved vars is at most threshold, compression is done */
1702 SCIP_Bool* binvaraffected, /**< pointer to store whether a binary variable is affected by symmetry */
1796 || (symtype == SYM_SYMTYPE_SIGNPERM && SCIPgetSymgraphNVarcolors(graph) == 2 * SCIPgetNVars(scip)) )
1810 SCIP_CALL( checkSymmetriesAreSymmetries(scip, symtype, *perms, *nperms, SCIPgetNVars(scip), fixedtype) );
1820 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &vars, SCIPgetVars(scip), nvars) ); /*lint !e666*/
1822 SCIP_CALL( setSymmetryData(scip, symtype, vars, nvars, SCIPgetNBinVars(scip), permvars, npermvars, nbinpermvars,
1893 SCIP_CALL( SCIPallocClearBlockMemoryArray(scip, &(propdata->componenthassignedperm), ncomponents) );
1904 if ( isNonstandardPerm(scip, propdata->perms[components[i]], propdata->permvars, propdata->npermvars) )
1939 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, " (%.1fs) component computation started\n", SCIPgetSolvingTime(scip));
1942 SCIP_CALL( SCIPcomputeComponentsSym(scip, (SYM_SYMTYPE) propdata->symtype, propdata->perms, propdata->nperms,
1943 propdata->permvars, propdata->npermvars, FALSE, &propdata->components, &propdata->componentbegins,
1947 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, " (%.1fs) component computation finished\n", SCIPgetSolvingTime(scip));
2089/** returns whether any allowed symmetry handling method is effective for the problem instance */
2121 if ( ISSSTIMPLINTACTIVE(propdata->sstleadervartype) && SCIPgetNImplVars(scip) > 0 ) /*lint !e641*/
2123 if ( ISSSTCONTACTIVE(propdata->sstleadervartype) && SCIPgetNContVars(scip) > 0 ) /*lint !e641*/
2143 SYM_SPEC symspecrequire, /**< symmetry specification for which we need to compute symmetries */
2144 SYM_SPEC symspecrequirefixed /**< symmetry specification of variables which must be fixed by symmetries */
2170 " Deactivated symmetry handling methods, since SCIP was built without symmetry detector (SYM=none).\n");
2193 /* count implicit integer variables as real variables, since we cannot currently handle integral variables well */
2201 " (%.1fs) symmetry computation skipped: type (bin %c, int %c, cont %c) does not match requirements (bin %c, int %c, cont %c).\n",
2225 " (%.1fs) symmetry computation started: requiring (bin %c, int %c, cont %c), (fixed: bin %c, int %c, cont %c)\n",
2261 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, " (%.1fs) could not compute symmetry\n", SCIPgetSolvingTime(scip));
2270 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, " (%.1fs) no symmetry present (symcode time: %.2f)\n", SCIPgetSolvingTime(scip), symcodetime);
2278 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, " (%.1fs) symmetry computation finished: %d generators found (max: ",
2288 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, ", log10 of symmetry group size: %.1f", propdata->log10groupsize);
2294 SCIP_CALL( SCIPdetermineNVarsAffectedSym(scip, propdata->perms, propdata->nperms, propdata->permvars,
2297 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, ", number of affected variables: %d)\n", propdata->nmovedvars);
2316/** Checks whether given set of 2-cycle permutations forms an orbitope and if so, builds the variable index matrix.
2318 * If @p activevars == NULL, then the function assumes all permutations of the component are active and therefore all
2321 * We need to keep track of the number of generated columns, because we might not be able to detect all orbitopes.
2322 * For example (1,2), (2,3), (3,4), (3,5) defines the symmetric group on {1,2,3,4,5}, but the generators we expect
2417 /* in the subgroup case it might happen that a generator has less than ntwocycles many 2-cyles */
2460 j = 0; /*lint !e850*/ /* reset j since previous permutations can now intersect with the latest added column */
2497 j = 0; /*lint !e850*/ /* reset j since previous permutations can now intersect with the latest added column */
2520 int* ntwocycleperms /**< pointer to store the number of 2-cycle permutations in component compidx */
2562 SCIP_CALL( SCIPisInvolutionPerm(perm, propdata->permvars, npermvars, &(ntwocycles[i]), &nbincycles, FALSE) );
2588 * After execution, @p graphcomponents contains all permvars sorted by their color and component,
2589 * @p graphcompbegins points to the indices where new components in @p graphcomponents start and
2599 int** graphcomponents, /**< buffer to store the components of the graph (ordered var indices) */
2672 /* iteratively handle each swap of perm until an invalid one is found or all edges have been added */
2692 /* another permutation has already merged these variables into one component; store its color */
2711 /* a generator is not allowed to connect two components of the same color, since they depend on each other */
2779 assert( SCIPdisjointsetFind(comptocolor, SCIPdisjointsetFind(vartocomponent, k)) == firstcolor );
2780 assert( SCIPdisjointsetFind(comptocolor, SCIPdisjointsetFind(vartocomponent, img)) == firstcolor );
2790 * disjoint sets to the arrays graphcomponents, graphcompbegins, and compcolorbegins (see above).
2876 SCIP_Bool mayinteract, /**< whether orbitope's symmetries might interact with other symmetries */
2969 /* it might happen that we cannot detect the orbitope if it is generated by permutations with different
3009 for (k = compcolorbegins[graphcoloridx]; k < compcolorbegins[graphcoloridx+1] && (*compidxfirstrow) < 0; ++k)
3021 /* iterate over all columns (elements in orbit), because we cannot see from ngencols which columns
3051 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "suborbitope_%d_%d", graphcoloridx, propdata->norbitopes);
3054 SCIP_ORBITOPETYPE_FULL, nrows, ngencols, FALSE, mayinteract, FALSE, FALSE, propdata->conssaddlp,
3087 SCIP_Bool storelexorder, /**< whether the lexicographic order induced by the orbitope shall be stored */
3140 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "strong_sbcs_%s_%s", SCIPvarGetName(vars[0]), SCIPvarGetName(vars[1]));
3176 SCIP_Bool storelexorder, /**< whether the lexicographic order induced by the orbitope shall be stored */
3233 assert( ! SCIPhashmapExists(varsinlexorder, (void*) (size_t) (*lexorder)[k]) ); /* Use int as pointer */
3238 /* We will store the newest and the largest orbit and activeorb will be used to mark at which entry of the array
3261 /* if the first variable was already contained in another orbit or if there are no variables left anyway, skip the
3310 SCIPdebugMsg(scip, " adding %d weak sbcs for enclosing orbit of color %d.\n", orbitsize[activeorb]-1, chosencolor);
3322 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "weak_sbcs_%d_%s_%s", symgrpcompidx, SCIPvarGetName(vars[0]), SCIPvarGetName(vars[1]));
3365 /* the leader of the weak inequalities has to be the first element in the lexicographic order */
3413 SCIP_VAR** modifiedpermvars, /**< memory for array of permutation vars w.r.t. new variable ordering */
3449 /* Iterate over leaders and put the l-th leader to the l-th position of the lexicographic order.
3450 * We do this by swapping the l-th leader with the element at position l of the current permvars array. */
3635 /* create arrays for modified permutations in case we adapt the lexicographic order because of suborbitopes */
3654 /* set the first npermsincomp entries of genorder; the others are not used for this component */
3663 SCIPdebugMsg(scip, "component %d has %d permutations consisting of 2-cycles\n", cidx, ntwocycleperms);
3691 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "(%s,", SCIPvarGetName(propdata->permvars[k]));
3695 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "%s,", SCIPvarGetName(propdata->permvars[j]));
3722 SCIPdebugMsg(scip, " created subgroup detection graph using %d of the permutations\n", nusedperms);
3763 norbitopesincomp = getNOrbitopesInComp(propdata->permvars, graphcomponents, graphcompbegins, compcolorbegins,
3766 /* if there is just one orbitope satisfying the requirements, handle the full component by symresacks */
3827 SCIPdebugMsg(scip, " color %d has %d components with overall %d variables\n", j, compcolorbegins[j+1] - compcolorbegins[j],
3879 SCIPdebugMsg(scip, " affected types (bin,int,cont): (%d,%d,%d)\n", binaffected, intaffected, contaffected);
3892 SCIPdebugMsg(scip, " detected an orbitope with %d rows and %d columns\n", nbinarycomps, largestcompsize);
3899 * It might happen that we cannot generate the orbitope matrix if the orbitope is not generated by permutations
3900 * all having the same number of 2-cycles, e.g., the orbitope generated by (1,2)(4,5), (2,3), (5,6).
3913 /* adapt the first variable per color to be compatible with the created orbiope (upper left variable) */
3953 SCIP_CALL( addStrongSBCsSubgroup(scip, propdata, graphcompbegins, graphcomponents, largestcolorcomp,
3957 if ( ! SCIPvarIsBinary(propdata->permvars[graphcomponents[graphcompbegins[largestcolorcomp]]]) )
4004 SCIPdebugMsg(scip, " don't add weak sbcs because all generators were used or the settings forbid it\n");
4006 /* if suborbitopes or strong group actions have been found, potentially add symresacks adapted to
4057 SCIPdebugMsg(scip, " add symresack for permutation %d of component %d adapted to suborbitope lexorder\n", k, cidx);
4162 * These lists are sorted (by the address of the constraint), so we only need to check for each i, j in the orbit
4183 /* Check if i and j are overlapping in some clique, where only one of the two could have value 1.
4186 * @todo A better sorted order would be: First constraints with large variables (higher hitting probability)
4286 SCIPdebugMsg(scip, "\tIdentify edges for clique ID: %u; Index: %d).\n", SCIPcliqueGetId(clique),
4313 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(*varconflicts)[i].cliques, (*varconflicts)[i].ncliques) );
4356 /* sort the variable cliques by the address, so checkSortedArraysHaveOverlappingEntry can detect intersections */
4359 SCIPsortPtr((void**)(*varconflicts)[i].cliques, sortByPointerValue, (*varconflicts)[i].ncliques);
4372 SCIPdebugMsg(scip, "Construction of conflict graph terminated; %d variable-clique combinations detected.\n",
4470 /* adapt natural variable order to a variable order that is compatible with Schreier Sims constraints */
4483 SCIP_CALL( adaptSymmetryDataSST(scip, perms, modifiedperms, nperms, permvars, modifiedpermvars, npermvars,
4505 SCIP_CALL( SCIPcreateSymbreakCons(scip, &cons, name, modifiedperms[permidx], modifiedpermvars, npermvars, FALSE,
4510 SCIP_CALL( SCIPcreateSymbreakCons(scip, &cons, name, perms[permidx], permvars, npermvars, FALSE,
4554 SCIP_Shortbool* orbitvarinconflict, /**< indicator whether orbitvar is in conflict with orbit leader */
4586 /* variables in conflict with leader are fixed and not treated by a cut; trailing -1 to not count the leader */
4699 SCIP_CONFLICTDATA* varconflicts, /**< variable conflicts structure, or NULL if we do not use it */
4710 SCIP_Shortbool* orbitvarinconflict, /**< array to store whether a var in the orbit is conflicting with leader */
4711 int* norbitvarinconflict,/**< pointer to store number of vars in the orbit in conflict with leader */
4745 if ( leaderrule == (int) SCIP_LEADERRULE_FIRSTINORBIT || leaderrule == (int) SCIP_LEADERRULE_LASTINORBIT )
4943 SCIP_Bool onlywithcontvars, /**< only handle components that contain continuous variables with SST */
5091 /* loop terminated naturally, so component does not have continuous or implicitly integer variables. */
5123 /* initialize array indicating whether permutations shall not be considered for orbit permutations */
5167 SCIP_CALL( updateSymInfoConflictGraphSST(scip, varconflicts, permvars, npermvars, orbits, orbitbegins,
5174 if ( leaderrule == SCIP_LEADERRULE_MAXCONFLICTSINORBIT && selectedtype != SCIP_VARTYPE_BINARY )
5178 if ( tiebreakrule == SCIP_LEADERTIEBREAKRULE_MAXCONFLICTSINORBIT && selectedtype != SCIP_VARTYPE_BINARY )
5182 SCIP_CALL( selectOrbitLeaderSSTConss(scip, varconflicts, permvars, npermvars, orbits, orbitbegins,
5183 norbits, propdata->sstleaderrule, propdata->ssttiebreakrule, selectedtype, &orbitidx, &orbitleaderidx,
5190 assert( 0 <= orbitleaderidx && orbitleaderidx < orbitbegins[orbitidx + 1] - orbitbegins[orbitidx] );
5191 SCIPdebugMsg(scip, "%d\t\t%d\t\t%d\n", orbitidx, orbitleaderidx, orbitbegins[orbitidx + 1] - orbitbegins[orbitidx]);
5195 orbits, orbitbegins, orbitidx, orbitleaderidx, orbitvarinconflict, norbitvarinconflict, &nchanges) );
5217 /* if Schreier Sims constraints have been added, store that Schreier Sims has been used for this component */
5288 SCIP_CALL( SCIPcreateConsLinear(scip, &cons, name, 2, consvars, conscoefs, -SCIPinfinity(scip), 0.0,
5289 propdata->conssaddlp, propdata->conssaddlp, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE ) );
5299 /* for only 2 columns, the the component can be completely handled by lexicographic reduction */
5324 SCIP_CALL( SCIPisPackingPartitioningOrbitope(scip, varmatrix, nrows, ncols, &pprows, &npprows, &type) );
5352 SCIP_CALL( SCIPcreateConsOrbitope(scip, &cons, name, ppvarsarrayonlypprows, SCIP_ORBITOPETYPE_PACKING,
5361 /* @todo we add orbitopes to the dynamically sized array `genlinconss` instead of `genorbconss` to ensure
5410/** applies pp-orbitope upgrade if at least 50% of the permutations in a component correspond to pp-orbisacks */
5485 /* For each permvar, introduce an array of setppc constraints (initially NULL) for each variable,
5486 * and populate it with the setppc constraints that it contains. This array follows the ordering by cons ptr address.
5511 &(permvarssetppcconss[varid]), &maxnpermvarssetppcconss[varid], npermvarssetppcconss[varid] + 1) );
5518 /* for all permutations, test involutions on binary variables and test if they are captured by setppc conss */
5542 /* i and j are a two-cycle, so we find this once for i and once for j. Only handle this once for i < j. */
5546 if ( !checkSortedArraysHaveOverlappingEntry((void**) permvarssetppcconss[i], npermvarssetppcconss[i],