SCIP

    Solving Constraint Integer Programs

    cons_orbitope_full.c
    Go to the documentation of this file.
    1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    2/* */
    3/* This file is part of the program and library */
    4/* SCIP --- Solving Constraint Integer Programs */
    5/* */
    6/* Copyright (c) 2002-2026 Zuse Institute Berlin (ZIB) */
    7/* */
    8/* Licensed under the Apache License, Version 2.0 (the "License"); */
    9/* you may not use this file except in compliance with the License. */
    10/* You may obtain a copy of the License at */
    11/* */
    12/* http://www.apache.org/licenses/LICENSE-2.0 */
    13/* */
    14/* Unless required by applicable law or agreed to in writing, software */
    15/* distributed under the License is distributed on an "AS IS" BASIS, */
    16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
    17/* See the License for the specific language governing permissions and */
    18/* limitations under the License. */
    19/* */
    20/* You should have received a copy of the Apache-2.0 license */
    21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
    22/* */
    23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    24
    25/**@file cons_orbitope_full.c
    26 * @ingroup DEFPLUGINS_CONS
    27 * @brief constraint handler for full orbitope constraints w.r.t. the full symmetric group
    28 * @author Timo Berthold
    29 * @author Marc Pfetsch
    30 * @author Christopher Hojny
    31 *
    32 * The type of constraints of this constraint handler is described in cons_orbitope_full.h.
    33 * When creating the constraint, users can decide whether it is a constraint defining the model
    34 * or "just" use to handle symmetries. In the latter case, symmetry reductions are only performed
    35 * by the constraint handler if strong dual reductions are permitted.
    36 *
    37 * The details of the method implemented here are described in the following papers.
    38 *
    39 * Orbitopal fixing for the full (sub-)orbitope and application to the Unit Commitment Problem@n
    40 * Pascale Bendotti, Pierre Fouilhoux, and Cecile Rottner,@n
    41 * Optimization Online: http://www.optimization-online.org/DB_HTML/2017/10/6301.html
    42 *
    43 * Two linear time propagation algorithms for full orbitopes are described in this paper, a static
    44 * version and a dynamic one. While the static version uses a fixed variable order, the dynamic
    45 * version determines the variable order during the solving process via branching descisions.
    46 * We only implemented the static version, because constraints should define the model and should
    47 * not be changed during the solving process. Instead, a dynamic version of orbitopal fixing has
    48 * been implemented as a routine in prop_symmetry.c.
    49 *
    50 * Polytopes associated with symmetry handling@n
    51 * Christopher Hojny and Marc E. Pfetsch,@n
    52 * Math. Program. (2018)
    53 *
    54 * In this paper, a linear time separation algorithm for orbisacks (full orbitopes with two columnes)
    55 * is described. We use this algorithm for every pair of adjacent columns within the orbitope.
    56 */
    57
    58/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    59
    61#include "scip/cons_orbisack.h"
    63#include "scip/cons_setppc.h"
    64#include "scip/pub_cons.h"
    65#include "scip/pub_message.h"
    66#include "scip/pub_var.h"
    67#include "scip/scip.h"
    68#include "scip/scip_branch.h"
    69#include "scip/scip_conflict.h"
    70#include "scip/scip_cons.h"
    71#include "scip/scip_copy.h"
    72#include "scip/scip_cut.h"
    73#include "scip/scip_general.h"
    74#include "scip/scip_lp.h"
    75#include "scip/scip_mem.h"
    76#include "scip/scip_message.h"
    77#include "scip/scip_numerics.h"
    78#include "scip/scip_param.h"
    79#include "scip/scip_prob.h"
    80#include "scip/scip_probing.h"
    81#include "scip/scip_sol.h"
    82#include "scip/scip_var.h"
    83#include "scip/symmetry.h"
    85
    86/* constraint handler properties */
    87#define CONSHDLR_NAME "orbitope_full"
    88#define CONSHDLR_DESC "symmetry breaking constraint handler relying on full orbitopes"
    89#define CONSHDLR_SEPAPRIORITY +40100 /**< priority of the constraint handler for separation */
    90#define CONSHDLR_ENFOPRIORITY -1005200 /**< priority of the constraint handler for constraint enforcing */
    91#define CONSHDLR_CHECKPRIORITY -1005200 /**< priority of the constraint handler for checking feasibility */
    92#define CONSHDLR_SEPAFREQ -1 /**< frequency for separating cuts; zero means to separate only in the root node */
    93#define CONSHDLR_PROPFREQ 1 /**< frequency for propagating domains; zero means only preprocessing propagation */
    94#define CONSHDLR_EAGERFREQ -1 /**< frequency for using all instead of only the useful constraints in separation,
    95 * propagation and enforcement, -1 for no eager evaluations, 0 for first only */
    96#define CONSHDLR_MAXPREROUNDS -1 /**< maximal number of presolving rounds the constraint handler participates in (-1: no limit) */
    97#define CONSHDLR_DELAYSEPA FALSE /**< should separation method be delayed, if other separators found cuts? */
    98#define CONSHDLR_DELAYPROP FALSE /**< should propagation method be delayed, if other propagators found reductions? */
    99#define CONSHDLR_NEEDSCONS TRUE /**< should the constraint handler be skipped, if no constraints are available? */
    100
    101#define CONSHDLR_PROP_TIMING SCIP_PROPTIMING_BEFORELP /**< propagation timing mask of the constraint handler */
    102#define CONSHDLR_PRESOLTIMING SCIP_PRESOLTIMING_MEDIUM /**< presolving timing of the constraint handler (fast, medium, or exhaustive) */
    103
    104#define DEFAULT_FORCECONSCOPY FALSE /**< whether orbitope constraints should be forced to be copied to sub SCIPs */
    105
    106/*
    107 * Data structures
    108 */
    109
    110/** constraint handler data */
    111struct SCIP_ConshdlrData
    112{
    113 SCIP_Bool forceconscopy; /**< whether orbitope constraints should be forced to be copied to sub SCIPs */
    114};
    115
    116/** constraint data for orbitope constraints */
    117struct SCIP_ConsData
    118{
    119 SCIP_VAR*** vars; /**< matrix of variables on which the symmetry acts */
    120 int nrows; /**< number of rows */
    121 int ncols; /**< number of columns*/
    122 SCIP_Bool resolveprop; /**< should propagation be resolved? */
    123 SCIP_Bool ismodelcons; /**< whether the orbitope is a model constraint */
    124};
    125
    126
    127/*
    128 * Local methods
    129 */
    130
    131/** frees an orbitope constraint data */
    132static
    134 SCIP* scip, /**< SCIP data structure */
    135 SCIP_CONSDATA** consdata /**< pointer to orbitope constraint data */
    136 )
    137{
    138 int i;
    139 int j;
    140 int nrows;
    141 int ncols;
    142
    143 assert( consdata != NULL );
    144 assert( *consdata != NULL );
    145
    146 nrows = (*consdata)->nrows;
    147 ncols = (*consdata)->ncols;
    148 for (i = 0; i < nrows; ++i)
    149 {
    150 /* release variables in vars array */
    151 for (j = 0; j < ncols; ++j)
    152 {
    153 assert( (*consdata)->vars[i] != NULL );
    154 SCIP_CALL( SCIPreleaseVar(scip, &(*consdata)->vars[i][j]) );
    155 }
    156
    157 SCIPfreeBlockMemoryArrayNull(scip, &((*consdata)->vars[i]), ncols); /*lint !e866*/
    158 }
    159
    160 SCIPfreeBlockMemoryArrayNull(scip, &((*consdata)->vars), nrows);
    161
    162 SCIPfreeBlockMemory(scip, consdata);
    163
    164 return SCIP_OKAY;
    165}
    166
    167
    168/** creates orbitope constraint data */
    169static
    171 SCIP* scip, /**< SCIP data structure */
    172 SCIP_CONSDATA** consdata, /**< pointer to store constraint data */
    173 SCIP_VAR*** vars, /**< variables array, must have size nrows x ncols*/
    174 int nrows, /**< number of rows */
    175 int ncols, /**< number of columns */
    176 SCIP_Bool resolveprop, /**< should propagation be resolved? */
    177 SCIP_Bool ismodelcons /**< whether the orbitope is a model constraint */
    178 )
    179{
    180 int i;
    181 int j;
    182
    183 assert(consdata != NULL);
    184
    185 SCIP_CALL( SCIPallocBlockMemory(scip, consdata) );
    186
    187 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(*consdata)->vars, nrows) );
    188
    189 for (i = 0; i < nrows; ++i)
    190 {
    191 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vars[i], vars[i], ncols) ); /*lint !e866*/
    192 }
    193
    194 (*consdata)->nrows = nrows;
    195 (*consdata)->ncols = ncols;
    196 (*consdata)->resolveprop = resolveprop;
    197 (*consdata)->ismodelcons = ismodelcons;
    198
    199 /* get transformed variables, if we are in the transformed problem */
    200 if ( SCIPisTransformed(scip) )
    201 {
    202 for (i = 0; i < nrows; ++i)
    203 {
    204 /* make sure that no variable gets multiaggregated (cannot be handled by cons_orbitope, since one cannot easily
    205 * eliminate single variables from an orbitope constraint).
    206 */
    207 for (j = 0; j < ncols; ++j)
    208 {
    209 SCIP_CALL( SCIPgetTransformedVar(scip, (*consdata)->vars[i][j], &(*consdata)->vars[i][j]) );
    210 SCIP_CALL( SCIPmarkDoNotMultaggrVar(scip, (*consdata)->vars[i][j]) );
    211 }
    212 }
    213 }
    214
    215 /* capture vars contained in vars array */
    216 for (i = 0; i < nrows; ++i)
    217 {
    218 for (j = 0; j < ncols; ++j)
    219 {
    220 assert( (*consdata)->vars[i][j] != NULL );
    221 SCIP_CALL( SCIPcaptureVar(scip, (*consdata)->vars[i][j]) );
    222 }
    223 }
    224
    225 return SCIP_OKAY;
    226}
    227
    228
    229/** Compute lexicographically minimal face of the hypercube w.r.t. some coordinate fixing */
    230static
    232 SCIP_VAR*** vars, /**< variable matrix */
    233 int** lexminfixes, /**< fixings characterzing lex-min face */
    234 int* minfixedrowlexmin, /**< index of minimum fixed row for each column or NULL (if in prop) */
    235 SCIP_Bool* infeasible, /**< pointer to store whether infeasibility has been detected or NULL (if in resprop) */
    236 int nrows, /**< number of rows in vars */
    237 int ncols, /**< number of columns in vars */
    238 SCIP_Bool resprop /**< whether we are in resprop (TRUE) or prop (FALSE) */
    239 )
    240{
    241 int i;
    242 int j;
    243
    244 *infeasible = FALSE;
    245
    246 assert( vars != NULL );
    247 assert( lexminfixes != NULL );
    248 assert( !resprop || minfixedrowlexmin != NULL );
    249 assert( nrows > 0 );
    250 assert( ncols > 0 );
    251 assert( infeasible != NULL );
    252
    253 /* iterate over columns in reverse order and find the lexicographically minimal face
    254 * of the hypercube containing lexminfixes
    255 */
    256 for (j = ncols - 2; j >= 0; --j)
    257 {
    258 int maxdiscriminating;
    259 int minfixed = -1;
    260
    261 maxdiscriminating = nrows;
    262
    263 /* fix free entries in column j to the corresponding value in column j + 1 and collect some information */
    264 for (i = 0; i < nrows; ++i)
    265 {
    266 /* is row i j-discriminating? */
    267 if ( minfixed == -1 && lexminfixes[i][j] != 0 && lexminfixes[i][j + 1] != 1 )
    268 {
    269 assert( lexminfixes[i][j + 1] == 0 );
    270
    271 maxdiscriminating = i;
    272 }
    273
    274 /* is row i j-fixed? */
    275 if ( minfixed == -1 && lexminfixes[i][j] != lexminfixes[i][j + 1] && lexminfixes[i][j] != 2 )
    276 {
    277 assert( lexminfixes[i][j + 1] != 2 );
    278
    279 minfixed = i;
    280
    281 /* detect infeasibility */
    282 if ( maxdiscriminating > minfixed )
    283 {
    284 *infeasible = TRUE;
    285
    286 return SCIP_OKAY;
    287 }
    288 }
    289 }
    290
    291 /* ensure that column j is lexicographically not smaller than column j + 1 */
    292 for (i = 0; i < nrows; ++i)
    293 {
    294 if ( lexminfixes[i][j] == 2 )
    295 {
    296 if ( i < maxdiscriminating || minfixed == -1 )
    297 lexminfixes[i][j] = lexminfixes[i][j + 1];
    298 else if ( i == maxdiscriminating )
    299 lexminfixes[i][j] = 1;
    300 else
    301 lexminfixes[i][j] = 0;
    302 }
    303 }
    304
    305 if ( resprop )
    306 {
    307 assert( minfixedrowlexmin != NULL );
    308
    309 /* store minimum fixed row */
    310 if ( minfixed == -1 )
    311 minfixedrowlexmin[j] = nrows - 1;
    312 else
    313 minfixedrowlexmin[j] = minfixed;
    314
    315 /* columns 1, ..., n-2 are contained in two columns (take the minimum) and
    316 * the minimum fixed row of column n-1 is determined by column n-2 */
    317 if ( minfixedrowlexmin[j + 1] < minfixedrowlexmin[j] )
    318 minfixedrowlexmin[j + 1] = minfixedrowlexmin[j];
    319 }
    320 }
    321
    322 return SCIP_OKAY;
    323}
    324
    325
    326/** Compute lexicographically maximal face of the hypercube w.r.t. some coordinate fixing */
    327static
    329 SCIP_VAR*** vars, /**< variable matrix */
    330 int** lexmaxfixes, /**< fixings characterzing lex-max face */
    331 int* minfixedrowlexmax, /**< index of minimum fixed row for each column or NULL (if in prop) */
    332 SCIP_Bool* infeasible, /**< pointer to store whether infeasibility has been detected or NULL (if in resprop) */
    333 int nrows, /**< number of rows in vars */
    334 int ncols, /**< number of columns in vars */
    335 SCIP_Bool resprop /**< whether we are in resprop (TRUE) or prop (FALSE) */
    336 )
    337{
    338 int i;
    339 int j;
    340
    341 *infeasible = FALSE;
    342
    343 assert( vars != NULL );
    344 assert( lexmaxfixes != NULL );
    345 assert( !resprop || minfixedrowlexmax != NULL );
    346 assert( nrows > 0 );
    347 assert( ncols > 0 );
    348 assert( infeasible != NULL );
    349
    350 for (j = 1; j < ncols; ++j)
    351 {
    352 int maxdiscriminating;
    353 int minfixed = -1;
    354
    355 maxdiscriminating = nrows;
    356
    357 /* fix free entries in column j to the corresponding value in column j - 1 and collect some information */
    358 for (i = 0; i < nrows; ++i)
    359 {
    360 /* is row i j-discriminating? */
    361 if ( minfixed == -1 && lexmaxfixes[i][j - 1] != 0 && lexmaxfixes[i][j] != 1 )
    362 {
    363 assert( lexmaxfixes[i][j - 1] == 1 );
    364
    365 maxdiscriminating = i;
    366 }
    367
    368 /* is row i j-fixed? */
    369 if ( minfixed == -1 && lexmaxfixes[i][j - 1] != lexmaxfixes[i][j] && lexmaxfixes[i][j] != 2 )
    370 {
    371 assert( lexmaxfixes[i][j - 1] != 2 );
    372
    373 minfixed = i;
    374
    375 /* detect infeasibility */
    376 if ( maxdiscriminating > minfixed )
    377 {
    378 *infeasible = TRUE;
    379
    380 return SCIP_OKAY;
    381 }
    382 }
    383 }
    384
    385 /* ensure that column j is lexicographically not greater than column j - 1 */
    386 for (i = 0; i < nrows; ++i)
    387 {
    388 if ( lexmaxfixes[i][j] == 2 )
    389 {
    390 if ( i < maxdiscriminating || minfixed == -1 )
    391 lexmaxfixes[i][j] = lexmaxfixes[i][j - 1];
    392 else if ( i == maxdiscriminating )
    393 lexmaxfixes[i][j] = 0;
    394 else
    395 lexmaxfixes[i][j] = 1;
    396 }
    397 }
    398
    399 if ( resprop )
    400 {
    401 assert( minfixedrowlexmax != NULL );
    402
    403 /* store minimum fixed row */
    404 if ( minfixed == -1 )
    405 minfixedrowlexmax[j] = nrows - 1;
    406 else
    407 minfixedrowlexmax[j] = minfixed;
    408
    409 /* columns 1, ..., n-2 are contained in two columns (take the minimum) and
    410 * the minimum fixed row of column 0 is determined by column 1 */
    411 if ( minfixedrowlexmax[j - 1] < minfixedrowlexmax[j] )
    412 minfixedrowlexmax[j - 1] = minfixedrowlexmax[j];
    413 }
    414 }
    415
    416 return SCIP_OKAY;
    417}
    418
    419
    420/** propagation method for a single full orbitope constraint */
    421static
    423 SCIP* scip, /**< SCIP data structure */
    424 SCIP_CONS* cons, /**< constraint to be processed */
    425 SCIP_Bool* infeasible, /**< pointer to store TRUE, if the node can be cut off */
    426 int* nfixedvars /**< pointer to add up the number of found domain reductions */
    427 )
    428{
    429 SCIP_CONSDATA* consdata;
    430 SCIP_VAR*** vars;
    431 int** lexminfixes;
    432 int** lexmaxfixes;
    433 int i;
    434 int j;
    435 int nrows;
    436 int ncols;
    437
    438 assert( scip != NULL );
    439 assert( cons != NULL );
    440 assert( infeasible != NULL );
    441 assert( nfixedvars != NULL );
    442
    443 consdata = SCIPconsGetData(cons);
    444 assert( consdata != NULL );
    445
    446 *nfixedvars = 0;
    447 *infeasible = FALSE;
    448
    449 /* if the constraint is not a model constraint, check whether symmetry reductions are permitted */
    450 if ( !consdata->ismodelcons && !SCIPallowStrongDualReds(scip) )
    451 return SCIP_OKAY;
    452
    453 assert( consdata->nrows > 0 );
    454 assert( consdata->ncols > 0 );
    455 assert( consdata->vars != NULL );
    456
    457 nrows = consdata->nrows;
    458 ncols = consdata->ncols;
    459 vars = consdata->vars;
    460
    461 /* Initialize lexicographically minimal matrix by fixed entries at the current node.
    462 * Free entries in the last column are set to 0.
    463 */
    464 SCIP_CALL( SCIPallocBufferArray(scip, &lexminfixes, nrows) );
    465 for (i = 0; i < nrows; ++i)
    466 {
    467 SCIP_CALL( SCIPallocBufferArray(scip, &lexminfixes[i], ncols) ); /*lint !e866*/
    468 }
    469
    470 for (i = 0; i < nrows; ++i)
    471 {
    472 for (j = 0; j < ncols; ++j)
    473 {
    474 if ( SCIPvarGetLbLocal(vars[i][j]) > 0.5 )
    475 lexminfixes[i][j] = 1;
    476 else if ( SCIPvarGetUbLocal(vars[i][j]) < 0.5 || j == ncols - 1 )
    477 lexminfixes[i][j] = 0;
    478 else
    479 lexminfixes[i][j] = 2;
    480 }
    481 }
    482
    483 /* find lexicographically minimal face of hypercube containing lexmin fixes */
    484 SCIP_CALL( findLexMinFace(vars, lexminfixes, NULL, infeasible, nrows, ncols, FALSE) );
    485
    486 if ( *infeasible == TRUE )
    487 goto FREELEXMIN;
    488
    489 /* Initialize lexicographically maximal matrix by fixed entries at the current node.
    490 * Free entries in the first column are set to 1.
    491 */
    492 SCIP_CALL( SCIPallocBufferArray(scip, &lexmaxfixes, nrows) );
    493 for (i = 0; i < nrows; ++i)
    494 {
    495 SCIP_CALL( SCIPallocBufferArray(scip, &lexmaxfixes[i], ncols) ); /*lint !e866*/
    496 }
    497
    498 for (i = 0; i < nrows; ++i)
    499 {
    500 for (j = 0; j < ncols; ++j)
    501 {
    502 if ( SCIPvarGetUbLocal(vars[i][j]) < 0.5 )
    503 lexmaxfixes[i][j] = 0;
    504 else if ( SCIPvarGetLbLocal(vars[i][j]) > 0.5 || j == 0 )
    505 lexmaxfixes[i][j] = 1;
    506 else
    507 lexmaxfixes[i][j] = 2;
    508 }
    509 }
    510
    511 /* find lexicographically maximal face of hypercube containing lexmax fixes */
    512 SCIP_CALL( findLexMaxFace(vars, lexmaxfixes, NULL, infeasible, nrows, ncols, FALSE) );
    513
    514 if ( *infeasible )
    515 goto FREELEXMAX;
    516
    517 /* Find for each column j the minimal row in which lexminfixes and lexmaxfixes differ. Fix all entries above this
    518 * row to the corresponding value in lexminfixes (or lexmaxfixes).
    519 */
    520 for (j = 0; j < ncols; ++j)
    521 {
    522 for (i = 0; i < nrows; ++i)
    523 {
    524 if ( lexminfixes[i][j] != lexmaxfixes[i][j] )
    525 break;
    526
    527 if ( SCIPvarGetLbLocal(vars[i][j]) < 0.5 && SCIPvarGetUbLocal(vars[i][j]) > 0.5 )
    528 {
    529 SCIP_Bool success;
    530
    531 SCIP_CALL( SCIPinferBinvarCons(scip, vars[i][j], (SCIP_Bool) lexminfixes[i][j],
    532 cons, 0, infeasible, &success) );
    533
    534 if ( success )
    535 *nfixedvars += 1;
    536 }
    537 }
    538 }
    539
    540 FREELEXMAX:
    541 for (i = nrows - 1; i >= 0; --i)
    542 SCIPfreeBufferArray(scip, &lexmaxfixes[i]);
    543 SCIPfreeBufferArray(scip, &lexmaxfixes);
    544
    545 FREELEXMIN:
    546 for (i = nrows - 1; i >= 0; --i)
    547 SCIPfreeBufferArray(scip, &lexminfixes[i]);
    548 SCIPfreeBufferArray(scip, &lexminfixes);
    549
    550 return SCIP_OKAY;
    551}
    552
    553
    554/** Propagation conflict resolving method of propagator
    555 *
    556 * In this function we use that all variable reductions that can be found by the propagation algorithm
    557 * are only due to the fixed variables that are in or above the minimum fixed row of each pair of adjacent
    558 * columns of the lexmin and lexmax matrices.
    559 *
    560 * Since the storage of an integer is not enough to store the complete information about the fixing,
    561 * we have to use the linear time algorithm for finding the lexmin and lexmax
    562 * matrices and determine from this the minimum fixed rows.
    563 */
    564static
    566 SCIP* scip, /**< SCIP data structure */
    567 SCIP_CONSHDLR* conshdlr, /**< constraint handler of the corresponding constraint */
    568 SCIP_CONS* cons, /**< constraint that inferred the bound change */
    569 int inferinfo, /**< inference information */
    570 SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
    571 SCIP_RESULT* result /**< pointer to store the result of the propagation conflict resolving call */
    572 )
    573{ /*lint --e{715}*/
    574 SCIP_CONSDATA* consdata;
    575 SCIP_VAR*** vars;
    576 int** lexminfixes;
    577 int** lexmaxfixes;
    578 int* minfixedrowlexmin;
    579 int* minfixedrowlexmax;
    580 int i;
    581 int j;
    582 int nrows;
    583 int ncols;
    584 SCIP_Bool terminate;
    585
    586 *result = SCIP_DIDNOTFIND;
    587
    588 assert( scip != NULL );
    589 assert( conshdlr != NULL );
    590 assert( cons != NULL );
    591 assert( result != NULL );
    592
    593 consdata = SCIPconsGetData(cons);
    594 assert( consdata != NULL );
    595 assert( consdata->nrows > 0 );
    596 assert( consdata->ncols > 0 );
    597 assert( consdata->vars != NULL );
    598
    599 nrows = consdata->nrows;
    600 ncols = consdata->ncols;
    601 vars = consdata->vars;
    602
    603 assert( inferinfo <= consdata->nrows );
    604
    605 /* Initialize lexicographically minimal matrix by fixed entries at the current node.
    606 * Free entries in the last column are set to 0.
    607 */
    608 SCIP_CALL( SCIPallocBufferArray(scip, &lexminfixes, nrows) );
    609 for (i = 0; i < nrows; ++i)
    610 {
    611 SCIP_CALL( SCIPallocBufferArray(scip, &lexminfixes[i], ncols) ); /*lint !e866*/
    612 }
    613
    614 /* store minimum fixed row for each column */
    615 SCIP_CALL( SCIPallocBufferArray(scip, &minfixedrowlexmin, ncols) );
    616 minfixedrowlexmin[ncols - 1] = -1;
    617
    618 for (i = 0; i < nrows; ++i)
    619 {
    620 for (j = 0; j < ncols; ++j)
    621 {
    622 if ( SCIPgetVarLbAtIndex(scip, vars[i][j], bdchgidx, FALSE) > 0.5 )
    623 lexminfixes[i][j] = 1;
    624 else if ( SCIPgetVarUbAtIndex(scip, vars[i][j], bdchgidx, FALSE) < 0.5 || j == ncols - 1 )
    625 lexminfixes[i][j] = 0;
    626 else
    627 lexminfixes[i][j] = 2;
    628 }
    629 }
    630
    631 /* find lexicographically minimal face of hypercube containing lexmin fixes */
    632 SCIP_CALL( findLexMinFace(vars, lexminfixes, minfixedrowlexmin, &terminate, nrows, ncols, TRUE) );
    633
    634 if ( terminate )
    635 goto FREELEXMIN;
    636
    637 /* Initialize lexicographically maximal matrix by fixed entries at the current node.
    638 * Free entries in the first column are set to 1.
    639 */
    640 SCIP_CALL( SCIPallocBufferArray(scip, &lexmaxfixes, nrows) );
    641 for (i = 0; i < nrows; ++i)
    642 {
    643 SCIP_CALL( SCIPallocBufferArray(scip, &lexmaxfixes[i], ncols) ); /*lint !e866*/
    644 }
    645
    646 /* store minimum fixed row for each column */
    647 SCIP_CALL( SCIPallocBufferArray(scip, &minfixedrowlexmax, ncols) );
    648 minfixedrowlexmax[0] = -1;
    649
    650 for (i = 0; i < nrows; ++i)
    651 {
    652 for (j = 0; j < ncols; ++j)
    653 {
    654 if ( SCIPgetVarUbAtIndex(scip, vars[i][j], bdchgidx, FALSE) < 0.5 )
    655 lexmaxfixes[i][j] = 0;
    656 else if ( SCIPgetVarLbAtIndex(scip, vars[i][j], bdchgidx, FALSE) > 0.5 || j == 0 )
    657 lexmaxfixes[i][j] = 1;
    658 else
    659 lexmaxfixes[i][j] = 2;
    660 }
    661 }
    662
    663 /* find lexicographically maximal face of hypercube containing lexmax fixes */
    664 SCIP_CALL( findLexMaxFace(vars, lexmaxfixes, minfixedrowlexmax, &terminate, nrows, ncols, TRUE) );
    665
    666 if ( terminate )
    667 goto FREELEXMAX;
    668
    669 /* Find for each column j the minimal row in which lexminfixes and lexmaxfixes differ. Fix all entries above this
    670 * row to the corresponding value in lexminfixes (or lexmaxfixes).
    671 */
    672 for (j = 0; j < ncols; ++j)
    673 {
    674 int ub = MAX(minfixedrowlexmin[j], minfixedrowlexmax[j]);
    675
    676 for (i = 0; i <= ub; ++i)
    677 {
    678 if ( SCIPgetVarLbAtIndex(scip, vars[i][j], bdchgidx, FALSE) > 0.5 ||
    679 SCIPgetVarUbAtIndex(scip, vars[i][j], bdchgidx, FALSE) < 0.5 )
    680 {
    681 SCIP_CALL( SCIPaddConflictBinvar(scip, vars[i][j]) );
    682 *result = SCIP_SUCCESS;
    683 }
    684 }
    685 }
    686
    687 FREELEXMAX:
    688 SCIPfreeBufferArray(scip, &minfixedrowlexmax);
    689 for (i = nrows - 1; i >= 0; --i)
    690 SCIPfreeBufferArray(scip, &lexmaxfixes[i]);
    691 SCIPfreeBufferArray(scip, &lexmaxfixes);
    692
    693 FREELEXMIN:
    694 SCIPfreeBufferArray(scip, &minfixedrowlexmin);
    695 for (i = nrows - 1; i >= 0; --i)
    696 SCIPfreeBufferArray(scip, &lexminfixes[i]);
    697 SCIPfreeBufferArray(scip, &lexminfixes);
    698
    699 return SCIP_OKAY;
    700}
    701
    702
    703/** check full orbitope solution for feasibility */
    704static
    706 SCIP* scip, /**< SCIP data structure */
    707 SCIP_CONS* cons, /**< constraint to process */
    708 SCIP_SOL* sol, /**< solution to be checked */
    709 SCIP_Bool printreason, /**< whether reason for infeasibility should be printed */
    710 SCIP_Bool* feasible /**< memory address to store whether solution is feasible */
    711 )
    712{
    713 SCIP_CONSDATA* consdata;
    714 SCIP_VAR*** vars;
    715 SCIP_VAR** vars1;
    716 SCIP_VAR** vars2;
    717 int nrows;
    718 int ncols;
    719 int j;
    720 int i;
    721
    722 assert( scip != NULL );
    723 assert( cons != NULL );
    724 assert( feasible != NULL );
    725
    726 consdata = SCIPconsGetData(cons);
    727
    728 assert( consdata != NULL );
    729 assert( consdata->vars != NULL );
    730 assert( consdata->nrows > 0 );
    731 assert( consdata->ncols > 0 );
    732 assert( ! consdata->ismodelcons ); /* non-model constraints are never checked */
    733
    734 vars = consdata->vars;
    735 nrows = consdata->nrows;
    736 ncols = consdata->ncols;
    737
    738 SCIP_CALL( SCIPallocBufferArray(scip, &vars1, nrows) );
    739 SCIP_CALL( SCIPallocBufferArray(scip, &vars2, nrows) );
    740
    741 /* iterate over adjacent columns of orbitope and check whether the first column in this
    742 * column pair is lexicographically not smaller than the second column in the pair */
    743 *feasible = TRUE;
    744 for (j = 1; j < ncols && *feasible; ++j)
    745 {
    746 for (i = 0; i < nrows; ++i)
    747 {
    748 vars1[i] = vars[i][j - 1];
    749 vars2[i] = vars[i][j];
    750 }
    751
    752 SCIP_CALL( SCIPcheckSolutionOrbisack(scip, sol, vars1, vars2, nrows, printreason, feasible) );
    753 }
    754
    755 SCIPfreeBufferArray(scip, &vars2);
    756 SCIPfreeBufferArray(scip, &vars1);
    757
    758 return SCIP_OKAY;
    759}
    760
    761
    762/** separate orbisack cover inequalities */
    763static
    765 SCIP* scip, /**< SCIP data structure */
    766 SCIP_CONS* cons, /**< constraint to process */
    767 SCIP_SOL* sol, /**< solution to separate (NULL for the LP solution) */
    768 int* ngen, /**< pointer to store number of generated cuts */
    769 SCIP_Bool* infeasible /**< pointer to store whether infeasibility has been detected */
    770 )
    771{
    772 SCIP_CONSDATA* consdata;
    773 SCIP_VAR*** vars;
    774 int nrows;
    775 int ncols;
    776 int i;
    777 int j;
    778 SCIP_Real rhs = 0.0;
    779 SCIP_Real lhs = 0.0;
    780 SCIP_Real* coeffs1;
    781 SCIP_Real* coeffs2;
    782
    783 assert( scip != NULL );
    784 assert( cons != NULL );
    785 assert( ngen != NULL );
    786 assert( infeasible != NULL );
    787
    788 *ngen = 0;
    789 *infeasible = FALSE;
    790
    791 /* get basic data */
    792 consdata = SCIPconsGetData(cons);
    793 assert( consdata != NULL );
    794
    795 vars = consdata->vars;
    796 nrows = consdata->nrows;
    797 ncols = consdata->ncols;
    798
    799 /* allocate memory for cover inequalities */
    800 SCIP_CALL( SCIPallocBufferArray(scip, &coeffs1, nrows) );
    801 SCIP_CALL( SCIPallocBufferArray(scip, &coeffs2, nrows) );
    802
    803 /* separate orbisack cover inequalities for adjacent columns */
    804 for (j = 0; j < ncols - 1 && ! *infeasible; ++j)
    805 {
    806 SCIP_Real rowval;
    807
    808 for (i = 0; i < nrows; ++i)
    809 {
    810 rowval = SCIPgetSolVal(scip, sol, vars[i][j + 1]) - SCIPgetSolVal(scip, sol, vars[i][j]);
    811
    812 /* check whether cover inequality is violated */
    813 if ( SCIPisEfficacious(scip, rowval + lhs - rhs) )
    814 {
    815 SCIP_ROW* row;
    816 int k;
    817
    818 /* set coefficients for current inequality */
    819 coeffs1[i] = -1.0;
    820 coeffs2[i] = 1.0;
    821
    822 /* add violated orbisack cover inequality */
    823 SCIP_CALL( SCIPcreateEmptyRowCons(scip, &row, cons, "orbisackcover", -SCIPinfinity(scip), rhs,
    824 FALSE, FALSE, TRUE) );
    826
    827 for (k = 0; k <= i; ++k)
    828 {
    829 SCIP_CALL( SCIPaddVarToRow(scip, row, vars[k][j], coeffs1[k]) );
    830 SCIP_CALL( SCIPaddVarToRow(scip, row, vars[k][j + 1], coeffs2[k]) );
    831 }
    833
    834 SCIP_CALL( SCIPaddRow(scip, row, FALSE, infeasible) );
    835#ifdef SCIP_DEBUG
    837#endif
    838 SCIP_CALL( SCIPreleaseRow(scip, &row) );
    839
    840 ++(*ngen);
    841 if ( *infeasible )
    842 break;
    843
    844 /* reset coefficients for next inequality */
    845 coeffs1[i] = 0.0;
    846 coeffs2[i] = 0.0;
    847 }
    848
    849 /* add argmax( 1 - vals[i][0], vals[i][1] ) as coefficient and ensure that both vars1[0] and vars2[0] are
    850 * contained in the LIFTED cover inequality */
    851 rowval = SCIPgetSolVal(scip, sol, vars[i][j]) + SCIPgetSolVal(scip, sol, vars[i][j + 1]);
    852 if ( SCIPisEfficacious(scip, 1.0 - rowval) )
    853 {
    854 coeffs1[i] = -1.0;
    855 coeffs2[i] = 0.0;
    856 lhs -= SCIPgetSolVal(scip, sol, vars[i][j]);
    857
    858 /* apply lifting? */
    859 if ( i == 0 )
    860 {
    861 coeffs2[i] = 1.0;
    862 lhs += SCIPgetSolVal(scip, sol, vars[i][j + 1]);
    863 }
    864 }
    865 else
    866 {
    867 coeffs1[i] = 0.0;
    868 coeffs2[i] = 1.0;
    869 lhs += SCIPgetSolVal(scip, sol, vars[i][j]);
    870 rhs += 1.0;
    871
    872 /* apply lifting? */
    873 if ( i == 0 )
    874 {
    875 coeffs1[i] = -1.0;
    876 lhs -= SCIPgetSolVal(scip, sol, vars[i][j]);
    877 rhs -= 1.0;
    878 }
    879 }
    880 }
    881 }
    882
    883 SCIPfreeBufferArray(scip, &coeffs1);
    884 SCIPfreeBufferArray(scip, &coeffs2);
    885
    886 return SCIP_OKAY;
    887}
    888
    889
    890/** separate or enforce constraints */
    891static
    893 SCIP* scip, /**< SCIP data structure */
    894 SCIP_CONSHDLR* conshdlr, /**< constraint handler */
    895 SCIP_CONS** conss, /**< constraints to process */
    896 int nconss, /**< number of constraints */
    897 int nusefulconss, /**< number of useful (non-obsolete) constraints to process */
    898 SCIP_SOL* sol, /**< solution to separate (NULL for the LP solution) */
    899 SCIP_RESULT* result, /**< pointer to store the result (should be initialized) */
    900 SCIP_Bool enforce /**< whether we enforce orbitope constraints */
    901 )
    902{
    903 SCIP_Bool infeasible = FALSE;
    904 int ncuts = 0;
    905 int c;
    906
    907 assert( scip != NULL );
    908 assert( conshdlr != NULL );
    909 assert( result != NULL );
    910
    912
    913 /* loop through constraints */
    914 for (c = 0; c < nconss && ! infeasible; c++)
    915 {
    916 SCIP_CONSDATA* consdata;
    917 int nconscuts = 0;
    918
    919 assert( conss[c] != NULL );
    920
    921 /* get data of constraint */
    922 consdata = SCIPconsGetData(conss[c]);
    923 assert( consdata != NULL );
    924
    925 /* skip non-model constraints if strong dual reductions are not permitted */
    926 if ( !consdata->ismodelcons && !SCIPallowStrongDualReds(scip) )
    927 continue;
    928
    929 /* do not enforce non-model constraints */
    930 if ( enforce && !consdata->ismodelcons )
    931 continue;
    932
    933 SCIP_CALL( separateCoversOrbisack(scip, conss[c], sol, &nconscuts, &infeasible) );
    934 ncuts += nconscuts;
    935
    936 /* stop after the useful constraints if we found cuts */
    937 if ( c >= nusefulconss && ncuts > 0 )
    938 break;
    939 }
    940
    941 if ( infeasible )
    942 {
    943 SCIPdebugMsg(scip, "Infeasible node.\n");
    944 *result = SCIP_CUTOFF;
    945 }
    946 else if ( ncuts > 0 )
    947 {
    948 SCIPdebugMsg(scip, "Separated %dinequalities.\n", ncuts);
    949 *result = SCIP_SEPARATED;
    950 }
    951 else
    952 {
    953 SCIPdebugMsg(scip, "No violated inequality found during separation.\n");
    954 }
    955
    956 return SCIP_OKAY;
    957}
    958
    959
    960/** check whether all variables in an orbitope constraint are fixed */
    961static
    963 SCIP* scip, /**< SCIP data structure */
    964 SCIP_CONS* cons, /**< constraint to be processed */
    965 SCIP_Bool* redundant /**< pointer to store whether constraint is redundant (contains no active vars) */
    966 )
    967{
    968 SCIP_CONSDATA* consdata;
    969 SCIP_VAR*** vars;
    970 int i;
    971 int j;
    972 int nrows;
    973 int ncols;
    974
    975 assert( scip != NULL );
    976 assert( cons != NULL );
    977 assert( redundant != NULL );
    978
    979 *redundant = FALSE;
    980
    981 consdata = SCIPconsGetData(cons);
    982 assert( consdata != NULL );
    983 assert( consdata->vars != NULL );
    984 assert( consdata->nrows > 0 );
    985 assert( consdata->ncols > 0 );
    986
    987 vars = consdata->vars;
    988 nrows = consdata->nrows;
    989 ncols = consdata->ncols;
    990
    991 /* check whether there exists an active variable in the orbitope */
    992 for (i = 0; i < nrows; ++i)
    993 {
    994 for (j = 0; j < ncols; ++j)
    995 {
    996 if ( SCIPvarIsActive(vars[i][j]) )
    997 return SCIP_OKAY;
    998 }
    999 }
    1000 *redundant = TRUE;
    1001
    1002 return SCIP_OKAY;
    1003}
    1004
    1005
    1006/** replace aggregated variables by active variables */
    1007static
    1009 SCIP* scip, /**< SCIP data structure */
    1010 SCIP_CONS* cons /**< constraint to be processed */
    1011 )
    1012{
    1013 SCIP_CONSDATA* consdata;
    1014 SCIP_VAR*** vars;
    1015 int i;
    1016 int j;
    1017 int nrows;
    1018 int ncols;
    1019
    1020 assert( scip != NULL );
    1021 assert( cons != NULL );
    1022
    1023 consdata = SCIPconsGetData(cons);
    1024 assert( consdata != NULL );
    1025 assert( consdata->vars != NULL );
    1026 assert( consdata->nrows > 0 );
    1027 assert( consdata->ncols > 0 );
    1028
    1029 vars = consdata->vars;
    1030 nrows = consdata->nrows;
    1031 ncols = consdata->ncols;
    1032
    1033 /* check whether there exists an aggregated variable in the orbitope */
    1034 for (i = 0; i < nrows; ++i)
    1035 {
    1036 for (j = 0; j < ncols; ++j)
    1037 {
    1038 SCIP_VAR* var;
    1039 SCIP_Bool negated;
    1040
    1041 assert( SCIPvarGetStatus(vars[i][j]) != SCIP_VARSTATUS_MULTAGGR ); /* variables are marked as not to be multi-aggregated */
    1042
    1043 SCIP_CALL( SCIPgetBinvarRepresentative(scip, vars[i][j], &var, &negated) );
    1044 SCIP_UNUSED( negated );
    1046 if ( var != vars[i][j] )
    1047 {
    1048 SCIP_CALL( SCIPunlockVarCons(scip, vars[i][j], cons, TRUE, TRUE) );
    1049 SCIP_CALL( SCIPreleaseVar(scip, &vars[i][j]) );
    1050 vars[i][j] = var;
    1051 SCIP_CALL( SCIPlockVarCons(scip, vars[i][j], cons, TRUE, TRUE) );
    1052 SCIP_CALL( SCIPcaptureVar(scip, var) );
    1053 }
    1054 }
    1055 }
    1056
    1057 return SCIP_OKAY;
    1058}
    1059
    1060
    1061/*
    1062 * Callback methods of constraint handler
    1063 */
    1064
    1065/** copy method for constraint handler plugins (called when SCIP copies plugins) */
    1066static
    1067SCIP_DECL_CONSHDLRCOPY(conshdlrCopyOrbitopeFull)
    1068{ /*lint --e{715}*/
    1069 assert(scip != NULL);
    1070 assert(conshdlr != NULL);
    1071 assert(valid != NULL);
    1072
    1074
    1075 /* call inclusion method of constraint handler */
    1077
    1078 *valid = TRUE;
    1079
    1080 return SCIP_OKAY;
    1081}
    1082
    1083/** frees constraint handler */
    1084static
    1085SCIP_DECL_CONSFREE(consFreeOrbitopeFull)
    1086{ /*lint --e{715}*/
    1087 SCIP_CONSHDLRDATA* conshdlrdata;
    1088
    1089 assert( scip != 0 );
    1090 assert( conshdlr != 0 );
    1091
    1093
    1094 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    1095 assert( conshdlrdata != NULL );
    1096
    1097 SCIPfreeBlockMemory(scip, &conshdlrdata);
    1098
    1099 return SCIP_OKAY;
    1100}
    1101
    1102/** frees specific constraint data */
    1103static
    1104SCIP_DECL_CONSDELETE(consDeleteOrbitopeFull)
    1105{ /*lint --e{715}*/
    1106 assert(conshdlr != NULL);
    1107
    1109
    1110 SCIP_CALL( consdataFree(scip, consdata) );
    1111
    1112 return SCIP_OKAY;
    1113}
    1114
    1115/** transforms constraint data into data belonging to the transformed problem */
    1116static
    1117SCIP_DECL_CONSTRANS(consTransOrbitopeFull)
    1118{ /*lint --e{715}*/
    1119 SCIP_CONSDATA* sourcedata;
    1120 SCIP_CONSDATA* targetdata;
    1121
    1122 assert(conshdlr != NULL);
    1124 assert(sourcecons != NULL);
    1125 assert(targetcons != NULL);
    1126
    1128
    1129 sourcedata = SCIPconsGetData(sourcecons);
    1130 assert(sourcedata != NULL);
    1131
    1132 /* create linear constraint data for target constraint */
    1133 SCIP_CALL( consdataCreate(scip, &targetdata, sourcedata->vars, sourcedata->nrows, sourcedata->ncols,
    1134 sourcedata->resolveprop, sourcedata->ismodelcons) );
    1135
    1136 /* create target constraint */
    1137 SCIP_CALL( SCIPcreateCons(scip, targetcons, SCIPconsGetName(sourcecons), conshdlr, targetdata,
    1138 SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
    1139 SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons),
    1140 SCIPconsIsLocal(sourcecons), SCIPconsIsModifiable(sourcecons),
    1141 SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons), SCIPconsIsStickingAtNode(sourcecons)) );
    1142
    1143 return SCIP_OKAY;
    1144}
    1145
    1146/** separation method of constraint handler for LP solutions */
    1147static
    1148SCIP_DECL_CONSSEPALP(consSepalpOrbitopeFull)
    1149{ /*lint --e{715}*/
    1150 assert( scip != NULL );
    1151 assert( result != NULL );
    1152
    1153 SCIPdebugMsg(scip, "Separation of full orbitope constraint handler <%s> for LP solution.\n",
    1154 SCIPconshdlrGetName(conshdlr));
    1155
    1156 *result = SCIP_DIDNOTRUN;
    1157
    1158 /* if solution is integer, skip separation */
    1159 if ( SCIPgetNLPBranchCands(scip) <= 0 )
    1160 return SCIP_OKAY;
    1161
    1162 *result = SCIP_DIDNOTFIND;
    1163
    1164 /* separate constraints */
    1165 SCIP_CALL( separateConstraints(scip, conshdlr, conss, nconss, nusefulconss, NULL, result, FALSE) );
    1166
    1167 return SCIP_OKAY;
    1168}
    1169
    1170/** separation method of constraint handler for arbitrary primal solutions */
    1171static
    1172SCIP_DECL_CONSSEPASOL(consSepasolOrbitopeFull)
    1173{ /*lint --e{715}*/
    1174 assert( scip != NULL );
    1175 assert( result != NULL );
    1176
    1177 SCIPdebugMsg(scip, "Separation of full orbitope constraint handler <%s> for primal solution.\n",
    1178 SCIPconshdlrGetName(conshdlr));
    1179
    1180 *result = SCIP_DIDNOTFIND;
    1181
    1182 /* separate constraints */
    1183 SCIP_CALL( separateConstraints(scip, conshdlr, conss, nconss, nusefulconss, sol, result, FALSE) );
    1184
    1185 return SCIP_OKAY;
    1186}
    1187
    1188/** constraint enforcing method of constraint handler for LP solutions */
    1189static
    1190SCIP_DECL_CONSENFOLP(consEnfolpOrbitopeFull)
    1191{ /*lint --e{715}*/
    1192 assert( scip != NULL );
    1193 assert( result != NULL );
    1194
    1195 /* we have a negative priority, so we should come after the integrality conshdlr */
    1196 assert( SCIPgetNLPBranchCands(scip) == 0 );
    1197
    1198 SCIPdebugMsg(scip, "Enforcement for full orbitope constraint handler <%s> for LP solution.\n",
    1199 SCIPconshdlrGetName(conshdlr));
    1200
    1201 *result = SCIP_FEASIBLE;
    1202
    1203 /* separate constraints */
    1204 SCIP_CALL( separateConstraints(scip, conshdlr, conss, nconss, nusefulconss, NULL, result, TRUE) );
    1205
    1206 return SCIP_OKAY;
    1207}
    1208
    1209/** constraint enforcing method of constraint handler for relaxation solutions */
    1210static
    1211SCIP_DECL_CONSENFORELAX(consEnforelaxOrbitopeFull)
    1212{ /*lint --e{715}*/
    1213 assert( result != NULL );
    1214 assert( scip != NULL );
    1215
    1216 SCIPdebugMsg(scip, "Enforcement for full orbitope constraint handler <%s> for relaxation solution.\n",
    1217 SCIPconshdlrGetName(conshdlr));
    1218
    1219 *result = SCIP_FEASIBLE;
    1220
    1221 /* separate constraints */
    1222 SCIP_CALL( separateConstraints(scip, conshdlr, conss, nconss, nusefulconss, sol, result, TRUE) );
    1223
    1224 return SCIP_OKAY;
    1225}
    1226
    1227/** constraint enforcing method of constraint handler for pseudo solutions */
    1228static
    1229SCIP_DECL_CONSENFOPS(consEnfopsOrbitopeFull)
    1230{ /*lint --e{715}*/
    1231 int c;
    1232
    1233 assert( scip != NULL );
    1234 assert( conshdlr != NULL );
    1235 assert( result != NULL );
    1236
    1238
    1239 *result = SCIP_FEASIBLE;
    1240 if ( objinfeasible || solinfeasible )
    1241 return SCIP_OKAY;
    1242
    1243 /* loop through constraints */
    1244 for (c = 0; c < nconss && *result == SCIP_FEASIBLE; ++c)
    1245 {
    1246 SCIP_CONSDATA* consdata;
    1247 SCIP_Bool feasible;
    1248
    1249 /* get data of constraint */
    1250 assert( conss[c] != NULL );
    1251 consdata = SCIPconsGetData(conss[c]);
    1252 assert( consdata != NULL );
    1253
    1254 /* do not enforce non-model constraints */
    1255 if ( !consdata->ismodelcons )
    1256 continue;
    1257
    1258 SCIP_CALL( checkFullOrbitopeSolution(scip, conss[c], NULL, FALSE, &feasible) );
    1259
    1260 if ( ! feasible )
    1261 *result = SCIP_INFEASIBLE;
    1262 }
    1263
    1264 return SCIP_OKAY;
    1265}
    1266
    1267
    1268/** feasibility check method of constraint handler for integral solutions */
    1269static
    1270SCIP_DECL_CONSCHECK(consCheckOrbitopeFull)
    1271{ /*lint --e{715}*/
    1272 int c;
    1273
    1274 assert( scip != NULL );
    1275 assert( conshdlr != NULL );
    1276 assert( result != NULL );
    1277
    1279
    1280 *result = SCIP_FEASIBLE;
    1281
    1282 /* loop through constraints */
    1283 for( c = 0; c < nconss && (*result == SCIP_FEASIBLE || completely); ++c )
    1284 {
    1285 SCIP_CONSDATA* consdata;
    1286 SCIP_Bool feasible;
    1287
    1288 assert( conss[c] != 0 );
    1289 consdata = SCIPconsGetData(conss[c]);
    1290 assert( consdata != NULL );
    1291
    1292 /* do not check non-model constraints */
    1293 if ( !consdata->ismodelcons )
    1294 continue;
    1295
    1296 SCIP_CALL( checkFullOrbitopeSolution(scip, conss[c], sol, printreason, &feasible) );
    1297
    1298 if ( ! feasible )
    1299 *result = SCIP_INFEASIBLE;
    1300 }
    1301
    1302 if( *result == SCIP_FEASIBLE )
    1303 {
    1304 SCIPdebugMsg(scip, "Solution is feasible.\n");
    1305 }
    1306 else
    1307 {
    1308 SCIPdebugMsg(scip, "Solution is infeasible.\n");
    1309 }
    1310
    1311 return SCIP_OKAY;
    1312}
    1313
    1314
    1315/** domain propagation method of constraint handler */
    1316static
    1317SCIP_DECL_CONSPROP(consPropOrbitopeFull)
    1318{ /*lint --e{715}*/
    1319 SCIP_Bool infeasible = FALSE;
    1320 int nfixedvars = 0;
    1321 int c;
    1322
    1323 assert( scip != NULL );
    1324 assert( conshdlr != NULL );
    1325 assert( result != NULL );
    1326
    1328
    1329 *result = SCIP_DIDNOTRUN;
    1330
    1331 /* propagate all useful constraints */
    1332 for (c = 0; c < nusefulconss && !infeasible; ++c)
    1333 {
    1334 int nfixed;
    1335 assert( conss[c] != 0 );
    1336
    1337 SCIPdebugMsg(scip, "Propagation of full orbitope constraint <%s> ...\n", SCIPconsGetName(conss[c]));
    1338
    1339 SCIP_CALL( propagateCons(scip, conss[c], &infeasible, &nfixed) );
    1340 nfixedvars += nfixed;
    1341 }
    1342
    1343 /* return the correct result */
    1344 if ( infeasible )
    1345 {
    1346 *result = SCIP_CUTOFF;
    1347 SCIPdebugMsg(scip, "Propagation via orbitopal fixing proved node to be infeasible.\n");
    1348 }
    1349 else if ( nfixedvars > 0 )
    1350 {
    1351 *result = SCIP_REDUCEDDOM;
    1352 SCIPdebugMsg(scip, "Propagated %d variables via orbitopal fixing.\n", nfixedvars);
    1353 }
    1354 else if ( nusefulconss > 0 )
    1355 {
    1356 *result = SCIP_DIDNOTFIND;
    1357 SCIPdebugMsg(scip, "Propagation via orbitopal fixing did not find anything.\n");
    1358 }
    1359
    1360 return SCIP_OKAY;
    1361}
    1362
    1363
    1364/** presolving method of constraint handler */
    1365static
    1366SCIP_DECL_CONSPRESOL(consPresolOrbitopeFull)
    1367{ /*lint --e{715}*/
    1368 SCIP_Bool infeasible = FALSE;
    1369 int noldfixedvars;
    1370 int c;
    1371 SCIP_Bool redundant;
    1372
    1373 assert( scip != NULL );
    1374 assert( conshdlr != NULL );
    1375 assert( result != NULL );
    1376
    1378
    1379 *result = SCIP_DIDNOTRUN;
    1380 noldfixedvars = *nfixedvars;
    1381
    1382 /* propagate all useful constraints
    1383 *
    1384 * @todo use an event handler to only propagate if a variable in the orbitope has been fixed
    1385 */
    1386 for (c = 0; c < nconss && !infeasible; ++c)
    1387 {
    1388 int nfixed = 0;
    1389
    1390 assert( conss[c] != 0 );
    1391
    1392 SCIPdebugMsg(scip, "Presolving of full orbitope constraint <%s> ...\n", SCIPconsGetName(conss[c]));
    1393
    1394 /* first propagate */
    1395 SCIP_CALL( propagateCons(scip, conss[c], &infeasible, &nfixed) );
    1396 *nfixedvars += nfixed;
    1397
    1398 if ( ! infeasible )
    1399 {
    1400 SCIP_CALL( checkRedundantCons(scip, conss[c], &redundant) );
    1401
    1402 if ( redundant )
    1403 {
    1404 SCIPdebugMsg(scip, "Full orbitope constraint <%s> is redundant: it does not contain active variables\n",
    1405 SCIPconsGetName(conss[c]));
    1406 SCIP_CALL( SCIPdelCons(scip, conss[c]) );
    1407 assert( ! SCIPconsIsActive(conss[c]) );
    1408 (*ndelconss)++;
    1409 continue;
    1410 }
    1411 }
    1412 }
    1413
    1414 if ( infeasible )
    1415 {
    1416 *result = SCIP_CUTOFF;
    1417 SCIPdebugMsg(scip, "Presolving detected infeasibility.\n");
    1418 }
    1419 else if ( *nfixedvars > noldfixedvars )
    1420 {
    1421 *result = SCIP_SUCCESS;
    1422 }
    1423 else if ( nconss > 0 )
    1424 {
    1425 *result = SCIP_DIDNOTFIND;
    1426 SCIPdebugMsg(scip, "Presolving via orbitopal fixing did not find anything.\n");
    1427 }
    1428
    1429 return SCIP_OKAY;
    1430}
    1431
    1432
    1433/** propagation conflict resolving method of constraint handler */
    1434static
    1435SCIP_DECL_CONSRESPROP(consRespropOrbitopeFull)
    1436{ /*lint --e{715}*/
    1437 assert( scip != NULL );
    1438 assert( cons != NULL );
    1439 assert( infervar != NULL );
    1440 assert( bdchgidx != NULL );
    1441 assert( result != NULL );
    1442
    1443 SCIP_CALL( resolvePropagationFullOrbitope(scip, conshdlr, cons, inferinfo, bdchgidx, result) );
    1444
    1445 return SCIP_OKAY;
    1446}
    1447
    1448
    1449/** presolving deinitialization method of constraint handler (called after presolving has been finished) */
    1450static
    1451SCIP_DECL_CONSEXITPRE(consExitpreOrbitopeFull)
    1452{
    1453 int c;
    1454
    1455 assert( scip != NULL );
    1456 assert( conshdlr != NULL );
    1457
    1459
    1460 for (c = 0; c < nconss; ++c)
    1461 {
    1462 /* replace aggregated variables by active variables */
    1464 }
    1465 return SCIP_OKAY;
    1466}
    1467
    1468
    1469/** variable rounding lock method of constraint handler */
    1470static
    1471SCIP_DECL_CONSLOCK(consLockOrbitopeFull)
    1472{ /*lint --e{715}*/
    1473 SCIP_CONSDATA* consdata;
    1474 SCIP_VAR*** vars;
    1475 int i;
    1476 int j;
    1477 int nrows;
    1478 int ncols;
    1479
    1480 assert( scip != NULL );
    1481 assert( conshdlr != NULL );
    1482 assert( cons != NULL );
    1483 assert( locktype == SCIP_LOCKTYPE_MODEL );
    1484
    1486
    1487 consdata = SCIPconsGetData(cons);
    1488 assert( consdata != NULL );
    1489 assert( consdata->nrows > 0 );
    1490 assert( consdata->ncols > 0 );
    1491 assert( consdata->vars != NULL );
    1492
    1493 SCIPdebugMsg(scip, "Locking method for full orbitope constraint handler\n");
    1494
    1495 nrows = consdata->nrows;
    1496 ncols = consdata->ncols;
    1497 vars = consdata->vars;
    1498
    1499 /* add up locks and down locks on each variable */
    1500 for (i = 0; i < nrows; ++i)
    1501 {
    1502 for (j = 0; j < ncols; ++j)
    1503 {
    1504 SCIP_CALL( SCIPaddVarLocksType(scip, vars[i][j], locktype, nlockspos + nlocksneg, nlockspos + nlocksneg) );
    1505 }
    1506 }
    1507
    1508 return SCIP_OKAY;
    1509}
    1510
    1511
    1512/** constraint display method of constraint handler */
    1513static
    1514SCIP_DECL_CONSPRINT(consPrintOrbitopeFull)
    1515{
    1516 SCIP_CONSDATA* consdata;
    1517 SCIP_VAR*** vars;
    1518 int i;
    1519 int j;
    1520 int nrows;
    1521 int ncols;
    1522
    1523 assert( scip != NULL );
    1524 assert( conshdlr != NULL );
    1525 assert( cons != NULL );
    1526
    1528
    1529 consdata = SCIPconsGetData(cons);
    1530 assert( consdata != NULL );
    1531 assert( consdata->nrows > 0 );
    1532 assert( consdata->ncols > 0 );
    1533 assert( consdata->vars != NULL );
    1534
    1535 nrows = consdata->nrows;
    1536 ncols = consdata->ncols;
    1537 vars = consdata->vars;
    1538
    1539 SCIPdebugMsg(scip, "Printing method for full orbitope constraint handler\n");
    1540
    1541 SCIPinfoMessage(scip, file, "fullOrbitope(");
    1542
    1543 for (i = 0; i < nrows; ++i)
    1544 {
    1545 for (j = 0; j < ncols; ++j)
    1546 {
    1547 if ( j > 0 )
    1548 SCIPinfoMessage(scip, file, ",");
    1549 SCIP_CALL( SCIPwriteVarName(scip, file, vars[i][j], TRUE) );
    1550 }
    1551 if ( i < nrows - 1 )
    1552 SCIPinfoMessage(scip, file, ".");
    1553 }
    1554 SCIPinfoMessage(scip, file, ")");
    1555
    1556 return SCIP_OKAY;
    1557}
    1558
    1559
    1560/** constraint copying method of constraint handler */
    1561static
    1562SCIP_DECL_CONSCOPY(consCopyOrbitopeFull)
    1563{
    1564 SCIP_CONSHDLRDATA* conshdlrdata;
    1565 SCIP_CONSDATA* sourcedata;
    1566 SCIP_VAR*** sourcevars;
    1567 SCIP_VAR*** vars;
    1568 int nrows;
    1569 int ncols;
    1570 int i;
    1571 int k;
    1572 int j;
    1573
    1574 assert( scip != NULL );
    1575 assert( cons != NULL );
    1576 assert( sourcescip != NULL );
    1577 assert( sourceconshdlr != NULL );
    1578 assert( sourcecons != NULL );
    1579 assert( varmap != NULL );
    1580 assert( valid != NULL );
    1581
    1583
    1584 *valid = TRUE;
    1585
    1586 SCIPdebugMsg(scip, "Copying method for full orbitope constraint handler.\n");
    1587
    1588 sourcedata = SCIPconsGetData(sourcecons);
    1589 assert( sourcedata != NULL );
    1590 assert( sourcedata->nrows > 0 );
    1591 assert( sourcedata->ncols > 0 );
    1592 assert( sourcedata->vars != NULL );
    1593
    1594 conshdlrdata = SCIPconshdlrGetData(sourceconshdlr);
    1595 assert( conshdlrdata != NULL );
    1596
    1597 /* do not copy non-model constraints */
    1598 if ( !sourcedata->ismodelcons && !conshdlrdata->forceconscopy )
    1599 {
    1600 *valid = FALSE;
    1601
    1602 return SCIP_OKAY;
    1603 }
    1604
    1605 nrows = sourcedata->nrows;
    1606 ncols = sourcedata->ncols;
    1607 sourcevars = sourcedata->vars;
    1608
    1609 SCIP_CALL( SCIPallocBufferArray(scip, &vars, nrows) );
    1610 for (i = 0; i < nrows && *valid; ++i)
    1611 {
    1612 SCIP_CALL( SCIPallocBufferArray(scip, &(vars[i]), ncols) ); /*lint !e866*/
    1613
    1614 for (j = 0; j < ncols && *valid; ++j)
    1615 {
    1616 SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, sourcevars[i][j], &(vars[i][j]), varmap, consmap, global, valid) );
    1617 assert( !(*valid) || vars[i][j] != NULL );
    1618 }
    1619 }
    1620
    1621 /* only create the target constraint, if all variables could be copied */
    1622 if ( *valid )
    1623 {
    1624 /* create copied constraint */
    1625 if ( name == NULL )
    1626 name = SCIPconsGetName(sourcecons);
    1627
    1628 SCIP_CALL( SCIPcreateConsOrbitopeFull(scip, cons, name, vars, nrows, ncols,
    1629 sourcedata->resolveprop, sourcedata->ismodelcons,
    1630 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
    1631 }
    1632
    1633 /* free space; only up to row i if copying failed */
    1634 assert( 0 <= i && i <= nrows );
    1635 for (k = i - 1; k >= 0; --k)
    1636 SCIPfreeBufferArray(scip, &vars[k]);
    1637 SCIPfreeBufferArray(scip, &vars);
    1638
    1639 return SCIP_OKAY;
    1640}
    1641
    1642
    1643/** constraint parsing method of constraint handler */
    1644static
    1645SCIP_DECL_CONSPARSE(consParseOrbitopeFull)
    1646{ /*lint --e{715}*/
    1647 const char* s;
    1648 char* endptr;
    1649 SCIP_VAR*** vars;
    1650 SCIP_VAR* var;
    1651 int nrows;
    1652 int maxnrows;
    1653 int ncols;
    1654 int maxncols;
    1655 int k;
    1656 int j;
    1657
    1658 assert( success != NULL );
    1659
    1660 *success = TRUE;
    1661 s = str;
    1662
    1663 /* skip white space */
    1664 SCIP_CALL( SCIPskipSpace((char**)&s) );
    1665
    1666 if( strncmp(s, "fullOrbitope(", 13) != 0 )
    1667 {
    1668 SCIPerrorMessage("Syntax error - expected \"fullOrbitope(\": %s\n", s);
    1669 *success = FALSE;
    1670 return SCIP_OKAY;
    1671 }
    1672 s += 13;
    1673
    1674 /* loop through string */
    1675 nrows = 0;
    1676 ncols = 0;
    1677 maxnrows = 10;
    1678 maxncols = 10;
    1679
    1680 SCIP_CALL( SCIPallocBufferArray(scip, &vars, maxnrows) );
    1681
    1682 j = 0;
    1683 do
    1684 {
    1685 /* parse variable name */
    1686 SCIP_CALL( SCIPparseVarName(scip, s, &var, &endptr) );
    1687
    1688 if( var == NULL )
    1689 {
    1690 endptr = strchr(endptr, ')');
    1691
    1692 if( endptr == NULL || j > 0 )
    1693 {
    1694 SCIPerrorMessage("not enough variables.\n");
    1695 *success = FALSE;
    1696 }
    1697
    1698 break;
    1699 }
    1700
    1701 s = endptr;
    1702 assert( s != NULL );
    1703
    1704 /* skip white space */
    1705 SCIP_CALL( SCIPskipSpace((char**)&s) );
    1706
    1707 /* begin new row if required */
    1708 if( j == 0 )
    1709 {
    1710 ++nrows;
    1711
    1712 if( nrows > maxnrows )
    1713 {
    1714 maxnrows = SCIPcalcMemGrowSize(scip, nrows);
    1715 SCIP_CALL( SCIPreallocBufferArray(scip, &vars, maxnrows) );
    1716 assert( nrows <= maxnrows );
    1717 }
    1718
    1719 SCIP_CALL( SCIPallocBufferArray(scip, &(vars[nrows-1]), nrows == 1 ? maxncols : ncols) ); /*lint !e866*/
    1720 }
    1721
    1722 /* determine number of columns */
    1723 if( nrows == 1 )
    1724 {
    1725 ncols = j + 1;
    1726
    1727 if( *s == '.' || *s == ')' )
    1728 SCIP_CALL( SCIPreallocBufferArray(scip, &(vars[nrows-1]), ncols) ); /*lint !e866*/
    1729 else if( ncols > maxncols )
    1730 {
    1731 maxncols = SCIPcalcMemGrowSize(scip, ncols);
    1732 SCIP_CALL( SCIPreallocBufferArray(scip, &(vars[nrows-1]), maxncols) ); /*lint !e866*/
    1733 assert( ncols <= maxncols );
    1734 }
    1735 }
    1736 else if( ( j < ncols-1 ) == ( *s == '.' || *s == ')' ) )
    1737 {
    1738 SCIPerrorMessage("variables per row do not match.\n");
    1739 *success = FALSE;
    1740 break;
    1741 }
    1742
    1743 vars[nrows-1][j] = var;
    1744
    1745 if( *s == '.' )
    1746 j = 0;
    1747 else
    1748 ++j;
    1749
    1750 /* skip ',' or '.' */
    1751 if( *s == ',' || *s == '.' )
    1752 ++s;
    1753 }
    1754 while( *s != ')' );
    1755
    1756 if( *success )
    1757 {
    1758 SCIP_CALL( SCIPcreateConsOrbitopeFull(scip, cons, name, vars, nrows, ncols, TRUE, TRUE,
    1759 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
    1760 }
    1761
    1762 for( k = nrows - 1; k >= 0; --k )
    1763 SCIPfreeBufferArray(scip, &vars[k]);
    1764 SCIPfreeBufferArray(scip, &vars);
    1765
    1766 return SCIP_OKAY;
    1767}
    1768
    1769
    1770/** constraint method of constraint handler which returns the variables (if possible) */
    1771static
    1772SCIP_DECL_CONSGETVARS(consGetVarsOrbitopeFull)
    1773{ /*lint --e{715}*/
    1774 SCIP_CONSDATA* consdata;
    1775
    1776 assert( cons != NULL );
    1777 assert( success != NULL );
    1778 assert( vars != NULL );
    1779
    1780 consdata = SCIPconsGetData(cons);
    1781 assert( consdata != NULL );
    1782
    1783 if ( varssize < consdata->ncols * consdata->nrows )
    1784 *success = FALSE;
    1785 else
    1786 {
    1787 int cnt = 0;
    1788 int i;
    1789 int j;
    1790
    1791 for (i = 0; i < consdata->nrows; ++i)
    1792 {
    1793 for (j = 0; j < consdata->ncols; ++j)
    1794 vars[cnt++] = consdata->vars[i][j];
    1795 }
    1796 *success = TRUE;
    1797 }
    1798
    1799 return SCIP_OKAY;
    1800}
    1801
    1802
    1803/** constraint method of constraint handler which returns the number of variables (if possible) */
    1804static
    1805SCIP_DECL_CONSGETNVARS(consGetNVarsOrbitopeFull)
    1806{ /*lint --e{715}*/
    1807 SCIP_CONSDATA* consdata;
    1808
    1809 assert( cons != NULL );
    1810
    1811 consdata = SCIPconsGetData(cons);
    1812 assert( consdata != NULL );
    1813
    1814 *nvars = consdata->ncols * consdata->nrows;
    1815 *success = TRUE;
    1816
    1817 return SCIP_OKAY;
    1818}
    1819
    1820
    1821/*
    1822 * constraint specific interface methods
    1823 */
    1824
    1825/** creates the handler for orbitope constraints and includes it in SCIP */
    1827 SCIP* scip /**< SCIP data structure */
    1828 )
    1829{
    1830 SCIP_CONSHDLRDATA* conshdlrdata;
    1831 SCIP_CONSHDLR* conshdlr;
    1832
    1833 /* create orbitope constraint handler data */
    1834 SCIP_CALL( SCIPallocBlockMemory(scip, &conshdlrdata) );
    1835
    1836 /* include constraint handler */
    1840 consEnfolpOrbitopeFull, consEnfopsOrbitopeFull, consCheckOrbitopeFull, consLockOrbitopeFull,
    1841 conshdlrdata) );
    1842 assert(conshdlr != NULL);
    1843
    1844 /* set non-fundamental callbacks via specific setter functions */
    1845 SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyOrbitopeFull, consCopyOrbitopeFull) );
    1846 SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeOrbitopeFull) );
    1847 SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteOrbitopeFull) );
    1848 SCIP_CALL( SCIPsetConshdlrGetVars(scip, conshdlr, consGetVarsOrbitopeFull) );
    1849 SCIP_CALL( SCIPsetConshdlrGetNVars(scip, conshdlr, consGetNVarsOrbitopeFull) );
    1850 SCIP_CALL( SCIPsetConshdlrParse(scip, conshdlr, consParseOrbitopeFull) );
    1851 SCIP_CALL( SCIPsetConshdlrPresol(scip, conshdlr, consPresolOrbitopeFull,
    1853 SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintOrbitopeFull) );
    1854 SCIP_CALL( SCIPsetConshdlrProp(scip, conshdlr, consPropOrbitopeFull, CONSHDLR_PROPFREQ, CONSHDLR_DELAYPROP,
    1856 SCIP_CALL( SCIPsetConshdlrResprop(scip, conshdlr, consRespropOrbitopeFull) );
    1857 SCIP_CALL( SCIPsetConshdlrExitpre(scip, conshdlr, consExitpreOrbitopeFull) );
    1858 SCIP_CALL( SCIPsetConshdlrSepa(scip, conshdlr, consSepalpOrbitopeFull, consSepasolOrbitopeFull, CONSHDLR_SEPAFREQ,
    1860 SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransOrbitopeFull) );
    1861 SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxOrbitopeFull) );
    1862
    1863 SCIP_CALL( SCIPaddBoolParam(scip, "constraints/" CONSHDLR_NAME "/forceconscopy",
    1864 "Whether orbitope constraints should be forced to be copied to sub SCIPs.",
    1865 &conshdlrdata->forceconscopy, TRUE, DEFAULT_FORCECONSCOPY, NULL, NULL) );
    1866
    1867 return SCIP_OKAY;
    1868}
    1869
    1870
    1871/** creates and captures a full orbitope constraint
    1872 *
    1873 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
    1874 */
    1876 SCIP* scip, /**< SCIP data structure */
    1877 SCIP_CONS** cons, /**< pointer to hold the created constraint */
    1878 const char* name, /**< name of constraint */
    1879 SCIP_VAR*** vars, /**< matrix of variables on which the symmetry acts */
    1880 int nrows, /**< number of set partitioning/packing constraints <=> p */
    1881 int ncols, /**< number of symmetric variable blocks <=> q */
    1882 SCIP_Bool resolveprop, /**< should propagation be resolved? */
    1883 SCIP_Bool ismodelcons, /**< whether the orbitope is a model constraint */
    1884 SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
    1885 * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
    1886 SCIP_Bool separate, /**< should the constraint be separated during LP processing?
    1887 * Usually set to TRUE. */
    1888 SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
    1889 * TRUE for model constraints, FALSE for additional, redundant constraints. */
    1890 SCIP_Bool check, /**< should the constraint be checked for feasibility?
    1891 * TRUE for model constraints, FALSE for additional, redundant constraints. */
    1892 SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
    1893 * Usually set to TRUE. */
    1894 SCIP_Bool local, /**< is constraint only valid locally?
    1895 * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
    1896 SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
    1897 * Usually set to FALSE. In column generation applications, set to TRUE if pricing
    1898 * adds coefficients to this constraint. */
    1899 SCIP_Bool dynamic, /**< is constraint subject to aging?
    1900 * Usually set to FALSE. Set to TRUE for own cuts which
    1901 * are separated as constraints. */
    1902 SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
    1903 * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
    1904 SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
    1905 * if it may be moved to a more global node?
    1906 * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
    1907 )
    1908{
    1909 SCIP_CONSHDLR* conshdlr;
    1910 SCIP_CONSDATA* consdata;
    1911
    1912 /* find the orbitope constraint handler */
    1913 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
    1914 if ( conshdlr == NULL )
    1915 {
    1916 SCIPerrorMessage("full orbitope constraint handler not found\n");
    1917 return SCIP_PLUGINNOTFOUND;
    1918 }
    1919
    1920 assert( nrows > 0 );
    1921 assert( ncols > 0 );
    1922
    1923 /* run some checks */
    1924#ifndef NDEBUG
    1925 {
    1926 SCIP_Real obj;
    1927 int i;
    1928 int j;
    1929 for (i = 0; i < nrows; ++i)
    1930 {
    1931 /* initialize obj to infinity */
    1932 obj = SCIPinfinity(scip);
    1933 for (j = 0; j < ncols; ++j)
    1934 {
    1935 SCIP_Bool fixedZero;
    1936 SCIP_VAR* var;
    1937
    1938 var = vars[i][j];
    1939 assert(var != NULL);
    1940
    1941 if ( SCIPvarIsNegated(var) )
    1942 var = SCIPvarGetNegatedVar(var);
    1943
    1944 /* all variables need to be binary */
    1945 assert( SCIPvarIsBinary(var) );
    1946
    1947 /* fixed variables have obj = 0; for variables fixed to 0, we assume that there is no
    1948 problem (but we cannot always check it, e.g., when in the original problem
    1949 variables were fixed and this problem was copied.) */
    1950 fixedZero = ( SCIPisZero(scip, SCIPvarGetLbGlobal(var)) && SCIPisZero(scip, SCIPvarGetUbGlobal(var)) );
    1951
    1952 /* @todo adapt correctness of the following check for sub-scips */
    1953 if ( SCIPgetSubscipDepth(scip) == 0 )
    1954 {
    1955 /* check whether all variables in a row have the same objective */
    1956 if ( ! fixedZero && SCIPisInfinity(scip, obj) )
    1957 obj = SCIPvarGetObj(var);
    1958 else
    1959 {
    1960 assert( fixedZero || ! SCIPvarIsActive(var) || SCIPisEQ(scip, obj, SCIPvarGetObj(var)) );
    1961 }
    1962 }
    1963 }
    1964 }
    1965 }
    1966#endif
    1967
    1968 /* create constraint data */
    1969 SCIP_CALL( consdataCreate(scip, &consdata, vars, nrows, ncols, resolveprop, ismodelcons) );
    1970
    1971 /* create constraint */
    1972 SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, initial, separate, enforce, check, propagate,
    1973 local, modifiable, dynamic, removable, stickingatnode) );
    1974
    1975 return SCIP_OKAY;
    1976}
    1977
    1978/** creates and captures a full orbitope constraint in its most basic variant, i. e., with all constraint flags set to
    1979 * their default values, which can be set afterwards using SCIPsetConsFLAGNAME()
    1980 *
    1981 * @see SCIPcreateConsOrbitopeFull() for the default constraint flag configuration
    1982 *
    1983 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
    1984 */
    1986 SCIP* scip, /**< SCIP data structure */
    1987 SCIP_CONS** cons, /**< pointer to hold the created constraint */
    1988 const char* name, /**< name of constraint */
    1989 SCIP_VAR*** vars, /**< matrix of variables on which the symmetry acts */
    1990 int nrows, /**< number of set partitioning/packing constraints <=> p */
    1991 int ncols, /**< number of symmetric variable blocks <=> q */
    1992 SCIP_Bool resolveprop, /**< should propagation be resolved? */
    1993 SCIP_Bool ismodelcons /**< whether the orbitope is a model constraint */
    1994 )
    1995{
    1996 SCIP_CALL( SCIPcreateConsOrbitopeFull(scip, cons, name, vars, nrows, ncols,
    1997 resolveprop, ismodelcons, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE) );
    1998
    1999 return SCIP_OKAY;
    2000}
    constraint handler for orbisack constraints
    static SCIP_RETCODE checkRedundantCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *redundant)
    #define CONSHDLR_NEEDSCONS
    #define CONSHDLR_SEPAFREQ
    static SCIP_RETCODE checkFullOrbitopeSolution(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_Bool printreason, SCIP_Bool *feasible)
    #define CONSHDLR_CHECKPRIORITY
    #define CONSHDLR_DESC
    static SCIP_RETCODE separateConstraints(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS **conss, int nconss, int nusefulconss, SCIP_SOL *sol, SCIP_RESULT *result, SCIP_Bool enforce)
    #define CONSHDLR_PROP_TIMING
    #define DEFAULT_FORCECONSCOPY
    #define CONSHDLR_MAXPREROUNDS
    static SCIP_DECL_CONSLOCK(consLockOrbitopeFull)
    #define CONSHDLR_SEPAPRIORITY
    static SCIP_RETCODE propagateCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *infeasible, int *nfixedvars)
    static SCIP_DECL_CONSPRESOL(consPresolOrbitopeFull)
    static SCIP_DECL_CONSENFORELAX(consEnforelaxOrbitopeFull)
    static SCIP_RETCODE resolvePropagationFullOrbitope(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS *cons, int inferinfo, SCIP_BDCHGIDX *bdchgidx, SCIP_RESULT *result)
    static SCIP_DECL_CONSPRINT(consPrintOrbitopeFull)
    static SCIP_DECL_CONSENFOPS(consEnfopsOrbitopeFull)
    static SCIP_DECL_CONSCOPY(consCopyOrbitopeFull)
    static SCIP_DECL_CONSGETNVARS(consGetNVarsOrbitopeFull)
    static SCIP_DECL_CONSCHECK(consCheckOrbitopeFull)
    static SCIP_RETCODE findLexMaxFace(SCIP_VAR ***vars, int **lexmaxfixes, int *minfixedrowlexmax, SCIP_Bool *infeasible, int nrows, int ncols, SCIP_Bool resprop)
    static SCIP_DECL_CONSSEPALP(consSepalpOrbitopeFull)
    static SCIP_DECL_CONSEXITPRE(consExitpreOrbitopeFull)
    static SCIP_DECL_CONSENFOLP(consEnfolpOrbitopeFull)
    static SCIP_DECL_CONSTRANS(consTransOrbitopeFull)
    #define CONSHDLR_PROPFREQ
    static SCIP_RETCODE separateCoversOrbisack(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, int *ngen, SCIP_Bool *infeasible)
    static SCIP_DECL_CONSSEPASOL(consSepasolOrbitopeFull)
    static SCIP_DECL_CONSPARSE(consParseOrbitopeFull)
    #define CONSHDLR_PRESOLTIMING
    static SCIP_RETCODE consdataFree(SCIP *scip, SCIP_CONSDATA **consdata)
    #define CONSHDLR_EAGERFREQ
    #define CONSHDLR_ENFOPRIORITY
    static SCIP_DECL_CONSPROP(consPropOrbitopeFull)
    static SCIP_RETCODE findLexMinFace(SCIP_VAR ***vars, int **lexminfixes, int *minfixedrowlexmin, SCIP_Bool *infeasible, int nrows, int ncols, SCIP_Bool resprop)
    #define CONSHDLR_DELAYSEPA
    static SCIP_RETCODE consdataCreate(SCIP *scip, SCIP_CONSDATA **consdata, SCIP_VAR ***vars, int nrows, int ncols, SCIP_Bool resolveprop, SCIP_Bool ismodelcons)
    #define CONSHDLR_NAME
    static SCIP_DECL_CONSRESPROP(consRespropOrbitopeFull)
    static SCIP_RETCODE replaceAggregatedVarsOrbitopeFull(SCIP *scip, SCIP_CONS *cons)
    static SCIP_DECL_CONSFREE(consFreeOrbitopeFull)
    static SCIP_DECL_CONSGETVARS(consGetVarsOrbitopeFull)
    #define CONSHDLR_DELAYPROP
    static SCIP_DECL_CONSDELETE(consDeleteOrbitopeFull)
    static SCIP_DECL_CONSHDLRCOPY(conshdlrCopyOrbitopeFull)
    constraint handler for full orbitope constraints w.r.t. the full symmetric group
    Constraint handler for the set partitioning / packing / covering constraints .
    #define NULL
    Definition: def.h:257
    #define SCIP_UNUSED(x)
    Definition: def.h:418
    #define SCIP_Bool
    Definition: def.h:100
    #define SCIP_STRINGEQ(name, reference, retcode)
    Definition: def.h:454
    #define SCIP_Real
    Definition: def.h:165
    #define TRUE
    Definition: def.h:102
    #define FALSE
    Definition: def.h:103
    #define MAX(x, y)
    Definition: def.h:229
    #define SCIP_CALL(x)
    Definition: def.h:364
    SCIP_RETCODE SCIPcheckSolutionOrbisack(SCIP *scip, SCIP_SOL *sol, SCIP_VAR **vars1, SCIP_VAR **vars2, int nrows, SCIP_Bool printreason, SCIP_Bool *feasible)
    SCIP_RETCODE SCIPcreateConsBasicOrbitopeFull(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR ***vars, int nrows, int ncols, SCIP_Bool resolveprop, SCIP_Bool ismodelcons)
    SCIP_RETCODE SCIPcreateConsOrbitopeFull(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR ***vars, int nrows, int ncols, SCIP_Bool resolveprop, SCIP_Bool ismodelcons, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    SCIP_RETCODE SCIPincludeConshdlrOrbitopeFull(SCIP *scip)
    int SCIPgetSubscipDepth(SCIP *scip)
    Definition: scip_copy.c:2589
    SCIP_RETCODE SCIPgetVarCopy(SCIP *sourcescip, SCIP *targetscip, SCIP_VAR *sourcevar, SCIP_VAR **targetvar, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool global, SCIP_Bool *success)
    Definition: scip_copy.c:713
    SCIP_Bool SCIPisTransformed(SCIP *scip)
    Definition: scip_general.c:655
    SCIP_STAGE SCIPgetStage(SCIP *scip)
    Definition: scip_general.c:444
    SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_prob.c:3420
    void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:208
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:57
    int SCIPgetNLPBranchCands(SCIP *scip)
    Definition: scip_branch.c:436
    SCIP_RETCODE SCIPaddConflictBinvar(SCIP *scip, SCIP_VAR *var)
    SCIP_RETCODE SCIPsetConshdlrParse(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPARSE((*consparse)))
    Definition: scip_cons.c:808
    SCIP_RETCODE SCIPsetConshdlrPresol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRESOL((*conspresol)), int maxprerounds, SCIP_PRESOLTIMING presoltiming)
    Definition: scip_cons.c:540
    SCIP_RETCODE SCIPsetConshdlrGetVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETVARS((*consgetvars)))
    Definition: scip_cons.c:831
    SCIP_RETCODE SCIPsetConshdlrSepa(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSSEPALP((*conssepalp)), SCIP_DECL_CONSSEPASOL((*conssepasol)), int sepafreq, int sepapriority, SCIP_Bool delaysepa)
    Definition: scip_cons.c:235
    SCIP_RETCODE SCIPsetConshdlrProp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPROP((*consprop)), int propfreq, SCIP_Bool delayprop, SCIP_PROPTIMING proptiming)
    Definition: scip_cons.c:281
    SCIP_RETCODE SCIPincludeConshdlrBasic(SCIP *scip, SCIP_CONSHDLR **conshdlrptr, const char *name, const char *desc, int enfopriority, int chckpriority, int eagerfreq, SCIP_Bool needscons, SCIP_DECL_CONSENFOLP((*consenfolp)), SCIP_DECL_CONSENFOPS((*consenfops)), SCIP_DECL_CONSCHECK((*conscheck)), SCIP_DECL_CONSLOCK((*conslock)), SCIP_CONSHDLRDATA *conshdlrdata)
    Definition: scip_cons.c:181
    SCIP_RETCODE SCIPsetConshdlrDelete(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDELETE((*consdelete)))
    Definition: scip_cons.c:578
    SCIP_RETCODE SCIPsetConshdlrFree(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSFREE((*consfree)))
    Definition: scip_cons.c:372
    SCIP_RETCODE SCIPsetConshdlrEnforelax(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSENFORELAX((*consenforelax)))
    Definition: scip_cons.c:323
    const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4320
    SCIP_RETCODE SCIPsetConshdlrExitpre(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXITPRE((*consexitpre)))
    Definition: scip_cons.c:516
    SCIP_RETCODE SCIPsetConshdlrCopy(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)), SCIP_DECL_CONSCOPY((*conscopy)))
    Definition: scip_cons.c:347
    SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
    Definition: scip_cons.c:940
    SCIP_CONSHDLRDATA * SCIPconshdlrGetData(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4340
    SCIP_RETCODE SCIPsetConshdlrTrans(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSTRANS((*constrans)))
    Definition: scip_cons.c:601
    SCIP_RETCODE SCIPsetConshdlrResprop(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSRESPROP((*consresprop)))
    Definition: scip_cons.c:647
    SCIP_RETCODE SCIPsetConshdlrGetNVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETNVARS((*consgetnvars)))
    Definition: scip_cons.c:854
    SCIP_RETCODE SCIPsetConshdlrPrint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRINT((*consprint)))
    Definition: scip_cons.c:785
    SCIP_CONSDATA * SCIPconsGetData(SCIP_CONS *cons)
    Definition: cons.c:8423
    SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
    Definition: cons.c:8652
    SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
    Definition: cons.c:8562
    SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
    Definition: cons.c:8592
    SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
    Definition: cons.c:8582
    SCIP_Bool SCIPconsIsActive(SCIP_CONS *cons)
    Definition: cons.c:8454
    SCIP_RETCODE SCIPcreateCons(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_CONSHDLR *conshdlr, SCIP_CONSDATA *consdata, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    Definition: scip_cons.c:997
    SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
    Definition: cons.c:8612
    SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
    Definition: cons.c:8632
    const char * SCIPconsGetName(SCIP_CONS *cons)
    Definition: cons.c:8393
    SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
    Definition: cons.c:8642
    SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
    Definition: cons.c:8672
    SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
    Definition: cons.c:8572
    SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
    Definition: cons.c:8662
    SCIP_Bool SCIPisEfficacious(SCIP *scip, SCIP_Real efficacy)
    Definition: scip_cut.c:135
    SCIP_RETCODE SCIPaddRow(SCIP *scip, SCIP_ROW *row, SCIP_Bool forcecut, SCIP_Bool *infeasible)
    Definition: scip_cut.c:225
    int SCIPcalcMemGrowSize(SCIP *scip, int num)
    Definition: scip_mem.c:139
    #define SCIPallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:124
    #define SCIPreallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:128
    #define SCIPfreeBufferArray(scip, ptr)
    Definition: scip_mem.h:136
    #define SCIPallocBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:93
    #define SCIPfreeBlockMemory(scip, ptr)
    Definition: scip_mem.h:108
    #define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
    Definition: scip_mem.h:111
    #define SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    #define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
    Definition: scip_mem.h:105
    SCIP_RETCODE SCIPcacheRowExtensions(SCIP *scip, SCIP_ROW *row)
    Definition: scip_lp.c:1581
    SCIP_RETCODE SCIPcreateEmptyRowCons(SCIP *scip, SCIP_ROW **row, SCIP_CONS *cons, const char *name, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool removable)
    Definition: scip_lp.c:1398
    SCIP_RETCODE SCIPflushRowExtensions(SCIP *scip, SCIP_ROW *row)
    Definition: scip_lp.c:1604
    SCIP_RETCODE SCIPaddVarToRow(SCIP *scip, SCIP_ROW *row, SCIP_VAR *var, SCIP_Real val)
    Definition: scip_lp.c:1646
    SCIP_RETCODE SCIPprintRow(SCIP *scip, SCIP_ROW *row, FILE *file)
    Definition: scip_lp.c:2176
    SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
    Definition: scip_lp.c:1508
    SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
    Definition: scip_sol.c:1763
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
    SCIP_RETCODE SCIPlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
    Definition: scip_var.c:5210
    SCIP_VAR * SCIPvarGetNegatedVar(SCIP_VAR *var)
    Definition: var.c:23900
    SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
    Definition: var.c:23674
    SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
    Definition: var.c:23510
    SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
    Definition: var.c:23418
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24300
    SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
    Definition: var.c:23932
    SCIP_RETCODE SCIPparseVarName(SCIP *scip, const char *str, SCIP_VAR **var, char **endptr)
    Definition: scip_var.c:728
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24174
    SCIP_RETCODE SCIPaddVarLocksType(SCIP *scip, SCIP_VAR *var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
    Definition: scip_var.c:5118
    SCIP_RETCODE SCIPunlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
    Definition: scip_var.c:5296
    SCIP_Real SCIPgetVarUbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
    Definition: scip_var.c:2872
    SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
    Definition: scip_var.c:1887
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24266
    SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
    Definition: var.c:23475
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24152
    SCIP_RETCODE SCIPmarkDoNotMultaggrVar(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:11057
    SCIP_Real SCIPgetVarLbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
    Definition: scip_var.c:2736
    SCIP_RETCODE SCIPinferBinvarCons(SCIP *scip, SCIP_VAR *var, SCIP_Bool fixedval, SCIP_CONS *infercons, int inferinfo, SCIP_Bool *infeasible, SCIP_Bool *tightened)
    Definition: scip_var.c:7412
    SCIP_RETCODE SCIPwriteVarName(SCIP *scip, FILE *file, SCIP_VAR *var, SCIP_Bool type)
    Definition: scip_var.c:361
    SCIP_RETCODE SCIPgetBinvarRepresentative(SCIP *scip, SCIP_VAR *var, SCIP_VAR **repvar, SCIP_Bool *negated)
    Definition: scip_var.c:2236
    SCIP_RETCODE SCIPgetTransformedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
    Definition: scip_var.c:2078
    SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:1853
    SCIP_Bool SCIPallowStrongDualReds(SCIP *scip)
    Definition: scip_var.c:10984
    SCIP_RETCODE SCIPskipSpace(char **s)
    Definition: misc.c:10816
    memory allocation routines
    public methods for managing constraints
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    public methods for problem variables
    SCIP callable library.
    public methods for branching rule plugins and branching
    public methods for conflict handler plugins and conflict analysis
    public methods for constraint handler plugins and constraints
    public methods for problem copies
    public methods for cuts and aggregation rows
    general public methods
    public methods for the LP relaxation, rows and columns
    public methods for memory management
    public methods for message handling
    public methods for numerical tolerances
    public methods for SCIP parameter handling
    public methods for global and local (sub)problems
    public methods for the probing mode
    public methods for solutions
    public methods for SCIP variables
    static SCIP_RETCODE separate(SCIP *scip, SCIP_SEPA *sepa, SCIP_SOL *sol, SCIP_RESULT *result)
    Main separation function.
    Definition: sepa_flower.c:1219
    methods for handling symmetries
    struct SCIP_ConshdlrData SCIP_CONSHDLRDATA
    Definition: type_cons.h:64
    struct SCIP_ConsData SCIP_CONSDATA
    Definition: type_cons.h:65
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_CUTOFF
    Definition: type_result.h:48
    @ SCIP_FEASIBLE
    Definition: type_result.h:45
    @ SCIP_REDUCEDDOM
    Definition: type_result.h:51
    @ SCIP_DIDNOTFIND
    Definition: type_result.h:44
    @ SCIP_SEPARATED
    Definition: type_result.h:49
    @ SCIP_SUCCESS
    Definition: type_result.h:58
    @ SCIP_INFEASIBLE
    Definition: type_result.h:46
    enum SCIP_Result SCIP_RESULT
    Definition: type_result.h:61
    @ SCIP_PLUGINNOTFOUND
    Definition: type_retcode.h:54
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_INVALIDCALL
    Definition: type_retcode.h:51
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_STAGE_TRANSFORMING
    Definition: type_set.h:46
    type definitions for symmetry computations
    @ SCIP_VARSTATUS_FIXED
    Definition: type_var.h:54
    @ SCIP_VARSTATUS_MULTAGGR
    Definition: type_var.h:56
    @ SCIP_VARSTATUS_NEGATED
    Definition: type_var.h:57
    @ SCIP_LOCKTYPE_MODEL
    Definition: type_var.h:141