Scippy

    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-2025 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( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
    910 assert( result != NULL );
    911
    912 /* loop through constraints */
    913 for (c = 0; c < nconss && ! infeasible; c++)
    914 {
    915 SCIP_CONSDATA* consdata;
    916 int nconscuts = 0;
    917
    918 assert( conss[c] != NULL );
    919
    920 /* get data of constraint */
    921 consdata = SCIPconsGetData(conss[c]);
    922 assert( consdata != NULL );
    923
    924 /* skip non-model constraints if strong dual reductions are not permitted */
    925 if ( !consdata->ismodelcons && !SCIPallowStrongDualReds(scip) )
    926 continue;
    927
    928 /* do not enforce non-model constraints */
    929 if ( enforce && !consdata->ismodelcons )
    930 continue;
    931
    932 SCIP_CALL( separateCoversOrbisack(scip, conss[c], sol, &nconscuts, &infeasible) );
    933 ncuts += nconscuts;
    934
    935 /* stop after the useful constraints if we found cuts */
    936 if ( c >= nusefulconss && ncuts > 0 )
    937 break;
    938 }
    939
    940 if ( infeasible )
    941 {
    942 SCIPdebugMsg(scip, "Infeasible node.\n");
    943 *result = SCIP_CUTOFF;
    944 }
    945 else if ( ncuts > 0 )
    946 {
    947 SCIPdebugMsg(scip, "Separated %dinequalities.\n", ncuts);
    948 *result = SCIP_SEPARATED;
    949 }
    950 else
    951 {
    952 SCIPdebugMsg(scip, "No violated inequality found during separation.\n");
    953 }
    954
    955 return SCIP_OKAY;
    956}
    957
    958
    959/** check whether all variables in an orbitope constraint are fixed */
    960static
    962 SCIP* scip, /**< SCIP data structure */
    963 SCIP_CONS* cons, /**< constraint to be processed */
    964 SCIP_Bool* redundant /**< pointer to store whether constraint is redundant (contains no active vars) */
    965 )
    966{
    967 SCIP_CONSDATA* consdata;
    968 SCIP_VAR*** vars;
    969 int i;
    970 int j;
    971 int nrows;
    972 int ncols;
    973
    974 assert( scip != NULL );
    975 assert( cons != NULL );
    976 assert( redundant != NULL );
    977
    978 *redundant = FALSE;
    979
    980 consdata = SCIPconsGetData(cons);
    981 assert( consdata != NULL );
    982 assert( consdata->vars != NULL );
    983 assert( consdata->nrows > 0 );
    984 assert( consdata->ncols > 0 );
    985
    986 vars = consdata->vars;
    987 nrows = consdata->nrows;
    988 ncols = consdata->ncols;
    989
    990 /* check whether there exists an active variable in the orbitope */
    991 for (i = 0; i < nrows; ++i)
    992 {
    993 for (j = 0; j < ncols; ++j)
    994 {
    995 if ( SCIPvarIsActive(vars[i][j]) )
    996 return SCIP_OKAY;
    997 }
    998 }
    999 *redundant = TRUE;
    1000
    1001 return SCIP_OKAY;
    1002}
    1003
    1004
    1005/** replace aggregated variables by active variables */
    1006static
    1008 SCIP* scip, /**< SCIP data structure */
    1009 SCIP_CONS* cons /**< constraint to be processed */
    1010 )
    1011{
    1012 SCIP_CONSDATA* consdata;
    1013 SCIP_VAR*** vars;
    1014 int i;
    1015 int j;
    1016 int nrows;
    1017 int ncols;
    1018
    1019 assert( scip != NULL );
    1020 assert( cons != NULL );
    1021
    1022 consdata = SCIPconsGetData(cons);
    1023 assert( consdata != NULL );
    1024 assert( consdata->vars != NULL );
    1025 assert( consdata->nrows > 0 );
    1026 assert( consdata->ncols > 0 );
    1027
    1028 vars = consdata->vars;
    1029 nrows = consdata->nrows;
    1030 ncols = consdata->ncols;
    1031
    1032 /* check whether there exists an aggregated variable in the orbitope */
    1033 for (i = 0; i < nrows; ++i)
    1034 {
    1035 for (j = 0; j < ncols; ++j)
    1036 {
    1037 SCIP_VAR* var;
    1038 SCIP_Bool negated;
    1039
    1040 assert( SCIPvarGetStatus(vars[i][j]) != SCIP_VARSTATUS_MULTAGGR ); /* variables are marked as not to be multi-aggregated */
    1041
    1042 SCIP_CALL( SCIPgetBinvarRepresentative(scip, vars[i][j], &var, &negated) );
    1043 SCIP_UNUSED( negated );
    1045 if ( var != vars[i][j] )
    1046 {
    1047 SCIP_CALL( SCIPreleaseVar(scip, &vars[i][j]) );
    1048 vars[i][j] = var;
    1049 SCIP_CALL( SCIPcaptureVar(scip, var) );
    1050 }
    1051 }
    1052 }
    1053
    1054 return SCIP_OKAY;
    1055}
    1056
    1057
    1058/*
    1059 * Callback methods of constraint handler
    1060 */
    1061
    1062/** copy method for constraint handler plugins (called when SCIP copies plugins) */
    1063static
    1064SCIP_DECL_CONSHDLRCOPY(conshdlrCopyOrbitopeFull)
    1065{ /*lint --e{715}*/
    1066 assert(scip != NULL);
    1067 assert(conshdlr != NULL);
    1068 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    1069 assert(valid != NULL);
    1070
    1071 /* call inclusion method of constraint handler */
    1073
    1074 *valid = TRUE;
    1075
    1076 return SCIP_OKAY;
    1077}
    1078
    1079/** frees constraint handler */
    1080static
    1081SCIP_DECL_CONSFREE(consFreeOrbitopeFull)
    1082{ /*lint --e{715}*/
    1083 SCIP_CONSHDLRDATA* conshdlrdata;
    1084
    1085 assert( scip != 0 );
    1086 assert( conshdlr != 0 );
    1087 assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
    1088
    1089 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    1090 assert( conshdlrdata != NULL );
    1091
    1092 SCIPfreeBlockMemory(scip, &conshdlrdata);
    1093
    1094 return SCIP_OKAY;
    1095}
    1096
    1097/** frees specific constraint data */
    1098static
    1099SCIP_DECL_CONSDELETE(consDeleteOrbitopeFull)
    1100{ /*lint --e{715}*/
    1101 assert(conshdlr != NULL);
    1102 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    1103
    1104 SCIP_CALL( consdataFree(scip, consdata) );
    1105
    1106 return SCIP_OKAY;
    1107}
    1108
    1109/** transforms constraint data into data belonging to the transformed problem */
    1110static
    1111SCIP_DECL_CONSTRANS(consTransOrbitopeFull)
    1112{ /*lint --e{715}*/
    1113 SCIP_CONSDATA* sourcedata;
    1114 SCIP_CONSDATA* targetdata;
    1115
    1116 assert(conshdlr != NULL);
    1117 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    1119 assert(sourcecons != NULL);
    1120 assert(targetcons != NULL);
    1121
    1122 sourcedata = SCIPconsGetData(sourcecons);
    1123 assert(sourcedata != NULL);
    1124
    1125 /* create linear constraint data for target constraint */
    1126 SCIP_CALL( consdataCreate(scip, &targetdata, sourcedata->vars, sourcedata->nrows, sourcedata->ncols,
    1127 sourcedata->resolveprop, sourcedata->ismodelcons) );
    1128
    1129 /* create target constraint */
    1130 SCIP_CALL( SCIPcreateCons(scip, targetcons, SCIPconsGetName(sourcecons), conshdlr, targetdata,
    1131 SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
    1132 SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons),
    1133 SCIPconsIsLocal(sourcecons), SCIPconsIsModifiable(sourcecons),
    1134 SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons), SCIPconsIsStickingAtNode(sourcecons)) );
    1135
    1136 return SCIP_OKAY;
    1137}
    1138
    1139/** separation method of constraint handler for LP solutions */
    1140static
    1141SCIP_DECL_CONSSEPALP(consSepalpOrbitopeFull)
    1142{ /*lint --e{715}*/
    1143 assert( scip != NULL );
    1144 assert( result != NULL );
    1145
    1146 SCIPdebugMsg(scip, "Separation of full orbitope constraint handler <%s> for LP solution.\n",
    1147 SCIPconshdlrGetName(conshdlr));
    1148
    1149 *result = SCIP_DIDNOTRUN;
    1150
    1151 /* if solution is integer, skip separation */
    1152 if ( SCIPgetNLPBranchCands(scip) <= 0 )
    1153 return SCIP_OKAY;
    1154
    1155 *result = SCIP_DIDNOTFIND;
    1156
    1157 /* separate constraints */
    1158 SCIP_CALL( separateConstraints(scip, conshdlr, conss, nconss, nusefulconss, NULL, result, FALSE) );
    1159
    1160 return SCIP_OKAY;
    1161}
    1162
    1163/** separation method of constraint handler for arbitrary primal solutions */
    1164static
    1165SCIP_DECL_CONSSEPASOL(consSepasolOrbitopeFull)
    1166{ /*lint --e{715}*/
    1167 assert( scip != NULL );
    1168 assert( result != NULL );
    1169
    1170 SCIPdebugMsg(scip, "Separation of full orbitope constraint handler <%s> for primal solution.\n",
    1171 SCIPconshdlrGetName(conshdlr));
    1172
    1173 *result = SCIP_DIDNOTFIND;
    1174
    1175 /* separate constraints */
    1176 SCIP_CALL( separateConstraints(scip, conshdlr, conss, nconss, nusefulconss, sol, result, FALSE) );
    1177
    1178 return SCIP_OKAY;
    1179}
    1180
    1181/** constraint enforcing method of constraint handler for LP solutions */
    1182static
    1183SCIP_DECL_CONSENFOLP(consEnfolpOrbitopeFull)
    1184{ /*lint --e{715}*/
    1185 assert( scip != NULL );
    1186 assert( result != NULL );
    1187
    1188 /* we have a negative priority, so we should come after the integrality conshdlr */
    1189 assert( SCIPgetNLPBranchCands(scip) == 0 );
    1190
    1191 SCIPdebugMsg(scip, "Enforcement for full orbitope constraint handler <%s> for LP solution.\n",
    1192 SCIPconshdlrGetName(conshdlr));
    1193
    1194 *result = SCIP_FEASIBLE;
    1195
    1196 /* separate constraints */
    1197 SCIP_CALL( separateConstraints(scip, conshdlr, conss, nconss, nusefulconss, NULL, result, TRUE) );
    1198
    1199 return SCIP_OKAY;
    1200}
    1201
    1202/** constraint enforcing method of constraint handler for relaxation solutions */
    1203static
    1204SCIP_DECL_CONSENFORELAX(consEnforelaxOrbitopeFull)
    1205{ /*lint --e{715}*/
    1206 assert( result != NULL );
    1207 assert( scip != NULL );
    1208
    1209 SCIPdebugMsg(scip, "Enforcement for full orbitope constraint handler <%s> for relaxation solution.\n",
    1210 SCIPconshdlrGetName(conshdlr));
    1211
    1212 *result = SCIP_FEASIBLE;
    1213
    1214 /* separate constraints */
    1215 SCIP_CALL( separateConstraints(scip, conshdlr, conss, nconss, nusefulconss, sol, result, TRUE) );
    1216
    1217 return SCIP_OKAY;
    1218}
    1219
    1220/** constraint enforcing method of constraint handler for pseudo solutions */
    1221static
    1222SCIP_DECL_CONSENFOPS(consEnfopsOrbitopeFull)
    1223{ /*lint --e{715}*/
    1224 int c;
    1225
    1226 assert( scip != NULL );
    1227 assert( conshdlr != NULL );
    1228 assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
    1229 assert( result != NULL );
    1230
    1231 *result = SCIP_FEASIBLE;
    1232 if ( objinfeasible || solinfeasible )
    1233 return SCIP_OKAY;
    1234
    1235 /* loop through constraints */
    1236 for (c = 0; c < nconss && *result == SCIP_FEASIBLE; ++c)
    1237 {
    1238 SCIP_CONSDATA* consdata;
    1239 SCIP_Bool feasible;
    1240
    1241 /* get data of constraint */
    1242 assert( conss[c] != NULL );
    1243 consdata = SCIPconsGetData(conss[c]);
    1244 assert( consdata != NULL );
    1245
    1246 /* do not enforce non-model constraints */
    1247 if ( !consdata->ismodelcons )
    1248 continue;
    1249
    1250 SCIP_CALL( checkFullOrbitopeSolution(scip, conss[c], NULL, FALSE, &feasible) );
    1251
    1252 if ( ! feasible )
    1253 *result = SCIP_INFEASIBLE;
    1254 }
    1255
    1256 return SCIP_OKAY;
    1257}
    1258
    1259
    1260/** feasibility check method of constraint handler for integral solutions */
    1261static
    1262SCIP_DECL_CONSCHECK(consCheckOrbitopeFull)
    1263{ /*lint --e{715}*/
    1264 int c;
    1265
    1266 assert( scip != NULL );
    1267 assert( conshdlr != NULL );
    1268 assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
    1269 assert( result != NULL );
    1270
    1271 *result = SCIP_FEASIBLE;
    1272
    1273 /* loop through constraints */
    1274 for( c = 0; c < nconss && (*result == SCIP_FEASIBLE || completely); ++c )
    1275 {
    1276 SCIP_CONSDATA* consdata;
    1277 SCIP_Bool feasible;
    1278
    1279 assert( conss[c] != 0 );
    1280 consdata = SCIPconsGetData(conss[c]);
    1281 assert( consdata != NULL );
    1282
    1283 /* do not check non-model constraints */
    1284 if ( !consdata->ismodelcons )
    1285 continue;
    1286
    1287 SCIP_CALL( checkFullOrbitopeSolution(scip, conss[c], sol, printreason, &feasible) );
    1288
    1289 if ( ! feasible )
    1290 *result = SCIP_INFEASIBLE;
    1291 }
    1292
    1293 if( *result == SCIP_FEASIBLE )
    1294 {
    1295 SCIPdebugMsg(scip, "Solution is feasible.\n");
    1296 }
    1297 else
    1298 {
    1299 SCIPdebugMsg(scip, "Solution is infeasible.\n");
    1300 }
    1301
    1302 return SCIP_OKAY;
    1303}
    1304
    1305
    1306/** domain propagation method of constraint handler */
    1307static
    1308SCIP_DECL_CONSPROP(consPropOrbitopeFull)
    1309{ /*lint --e{715}*/
    1310 SCIP_Bool infeasible = FALSE;
    1311 int nfixedvars = 0;
    1312 int c;
    1313
    1314 assert( scip != NULL );
    1315 assert( conshdlr != NULL );
    1316 assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
    1317 assert( result != NULL );
    1318
    1319 *result = SCIP_DIDNOTRUN;
    1320
    1321 /* propagate all useful constraints */
    1322 for (c = 0; c < nusefulconss && !infeasible; ++c)
    1323 {
    1324 int nfixed;
    1325 assert( conss[c] != 0 );
    1326
    1327 SCIPdebugMsg(scip, "Propagation of full orbitope constraint <%s> ...\n", SCIPconsGetName(conss[c]));
    1328
    1329 SCIP_CALL( propagateCons(scip, conss[c], &infeasible, &nfixed) );
    1330 nfixedvars += nfixed;
    1331 }
    1332
    1333 /* return the correct result */
    1334 if ( infeasible )
    1335 {
    1336 *result = SCIP_CUTOFF;
    1337 SCIPdebugMsg(scip, "Propagation via orbitopal fixing proved node to be infeasible.\n");
    1338 }
    1339 else if ( nfixedvars > 0 )
    1340 {
    1341 *result = SCIP_REDUCEDDOM;
    1342 SCIPdebugMsg(scip, "Propagated %d variables via orbitopal fixing.\n", nfixedvars);
    1343 }
    1344 else if ( nusefulconss > 0 )
    1345 {
    1346 *result = SCIP_DIDNOTFIND;
    1347 SCIPdebugMsg(scip, "Propagation via orbitopal fixing did not find anything.\n");
    1348 }
    1349
    1350 return SCIP_OKAY;
    1351}
    1352
    1353
    1354/** presolving method of constraint handler */
    1355static
    1356SCIP_DECL_CONSPRESOL(consPresolOrbitopeFull)
    1357{ /*lint --e{715}*/
    1358 SCIP_Bool infeasible = FALSE;
    1359 int noldfixedvars;
    1360 int c;
    1361 SCIP_Bool redundant;
    1362
    1363 assert( scip != NULL );
    1364 assert( conshdlr != NULL );
    1365 assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
    1366 assert( result != NULL );
    1367
    1368 *result = SCIP_DIDNOTRUN;
    1369 noldfixedvars = *nfixedvars;
    1370
    1371 /* propagate all useful constraints
    1372 *
    1373 * @todo use an event handler to only propagate if a variable in the orbitope has been fixed
    1374 */
    1375 for (c = 0; c < nconss && !infeasible; ++c)
    1376 {
    1377 int nfixed = 0;
    1378
    1379 assert( conss[c] != 0 );
    1380
    1381 SCIPdebugMsg(scip, "Presolving of full orbitope constraint <%s> ...\n", SCIPconsGetName(conss[c]));
    1382
    1383 /* first propagate */
    1384 SCIP_CALL( propagateCons(scip, conss[c], &infeasible, &nfixed) );
    1385 *nfixedvars += nfixed;
    1386
    1387 if ( ! infeasible )
    1388 {
    1389 SCIP_CALL( checkRedundantCons(scip, conss[c], &redundant) );
    1390
    1391 if ( redundant )
    1392 {
    1393 SCIPdebugMsg(scip, "Full orbitope constraint <%s> is redundant: it does not contain active variables\n",
    1394 SCIPconsGetName(conss[c]));
    1395 SCIP_CALL( SCIPdelCons(scip, conss[c]) );
    1396 assert( ! SCIPconsIsActive(conss[c]) );
    1397 (*ndelconss)++;
    1398 continue;
    1399 }
    1400 }
    1401 }
    1402
    1403 if ( infeasible )
    1404 {
    1405 *result = SCIP_CUTOFF;
    1406 SCIPdebugMsg(scip, "Presolving detected infeasibility.\n");
    1407 }
    1408 else if ( *nfixedvars > noldfixedvars )
    1409 {
    1410 *result = SCIP_SUCCESS;
    1411 }
    1412 else if ( nconss > 0 )
    1413 {
    1414 *result = SCIP_DIDNOTFIND;
    1415 SCIPdebugMsg(scip, "Presolving via orbitopal fixing did not find anything.\n");
    1416 }
    1417
    1418 return SCIP_OKAY;
    1419}
    1420
    1421
    1422/** propagation conflict resolving method of constraint handler */
    1423static
    1424SCIP_DECL_CONSRESPROP(consRespropOrbitopeFull)
    1425{ /*lint --e{715}*/
    1426 assert( scip != NULL );
    1427 assert( cons != NULL );
    1428 assert( infervar != NULL );
    1429 assert( bdchgidx != NULL );
    1430 assert( result != NULL );
    1431
    1432 SCIP_CALL( resolvePropagationFullOrbitope(scip, conshdlr, cons, inferinfo, bdchgidx, result) );
    1433
    1434 return SCIP_OKAY;
    1435}
    1436
    1437
    1438/** presolving deinitialization method of constraint handler (called after presolving has been finished) */
    1439static
    1440SCIP_DECL_CONSEXITPRE(consExitpreOrbitopeFull)
    1441{
    1442 int c;
    1443
    1444 assert( scip != NULL );
    1445 assert( conshdlr != NULL );
    1446 assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
    1447
    1448 for (c = 0; c < nconss; ++c)
    1449 {
    1450 /* replace aggregated variables by active variables */
    1452 }
    1453 return SCIP_OKAY;
    1454}
    1455
    1456
    1457/** variable rounding lock method of constraint handler */
    1458static
    1459SCIP_DECL_CONSLOCK(consLockOrbitopeFull)
    1460{ /*lint --e{715}*/
    1461 SCIP_CONSDATA* consdata;
    1462 SCIP_VAR*** vars;
    1463 int i;
    1464 int j;
    1465 int nrows;
    1466 int ncols;
    1467
    1468 assert( scip != NULL );
    1469 assert( conshdlr != NULL );
    1470 assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
    1471 assert( cons != NULL );
    1472 assert( locktype == SCIP_LOCKTYPE_MODEL );
    1473
    1474 consdata = SCIPconsGetData(cons);
    1475 assert( consdata != NULL );
    1476 assert( consdata->nrows > 0 );
    1477 assert( consdata->ncols > 0 );
    1478 assert( consdata->vars != NULL );
    1479
    1480 SCIPdebugMsg(scip, "Locking method for full orbitope constraint handler\n");
    1481
    1482 nrows = consdata->nrows;
    1483 ncols = consdata->ncols;
    1484 vars = consdata->vars;
    1485
    1486 /* add up locks and down locks on each variable */
    1487 for (i = 0; i < nrows; ++i)
    1488 {
    1489 for (j = 0; j < ncols; ++j)
    1490 {
    1491 SCIP_CALL( SCIPaddVarLocksType(scip, vars[i][j], locktype, nlockspos + nlocksneg, nlockspos + nlocksneg) );
    1492 }
    1493 }
    1494
    1495 return SCIP_OKAY;
    1496}
    1497
    1498
    1499/** constraint display method of constraint handler */
    1500static
    1501SCIP_DECL_CONSPRINT(consPrintOrbitopeFull)
    1502{
    1503 SCIP_CONSDATA* consdata;
    1504 SCIP_VAR*** vars;
    1505 int i;
    1506 int j;
    1507 int nrows;
    1508 int ncols;
    1509
    1510 assert( scip != NULL );
    1511 assert( conshdlr != NULL );
    1512 assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
    1513 assert( cons != NULL );
    1514
    1515 consdata = SCIPconsGetData(cons);
    1516 assert( consdata != NULL );
    1517 assert( consdata->nrows > 0 );
    1518 assert( consdata->ncols > 0 );
    1519 assert( consdata->vars != NULL );
    1520
    1521 nrows = consdata->nrows;
    1522 ncols = consdata->ncols;
    1523 vars = consdata->vars;
    1524
    1525 SCIPdebugMsg(scip, "Printing method for full orbitope constraint handler\n");
    1526
    1527 SCIPinfoMessage(scip, file, "fullOrbitope(");
    1528
    1529 for (i = 0; i < nrows; ++i)
    1530 {
    1531 for (j = 0; j < ncols; ++j)
    1532 {
    1533 if ( j > 0 )
    1534 SCIPinfoMessage(scip, file, ",");
    1535 SCIP_CALL( SCIPwriteVarName(scip, file, vars[i][j], TRUE) );
    1536 }
    1537 if ( i < nrows - 1 )
    1538 SCIPinfoMessage(scip, file, ".");
    1539 }
    1540 SCIPinfoMessage(scip, file, ")");
    1541
    1542 return SCIP_OKAY;
    1543}
    1544
    1545
    1546/** constraint copying method of constraint handler */
    1547static
    1548SCIP_DECL_CONSCOPY(consCopyOrbitopeFull)
    1549{
    1550 SCIP_CONSHDLRDATA* conshdlrdata;
    1551 SCIP_CONSDATA* sourcedata;
    1552 SCIP_VAR*** sourcevars;
    1553 SCIP_VAR*** vars;
    1554 int nrows;
    1555 int ncols;
    1556 int i;
    1557 int k;
    1558 int j;
    1559
    1560 assert( scip != NULL );
    1561 assert( cons != NULL );
    1562 assert( sourcescip != NULL );
    1563 assert( sourceconshdlr != NULL );
    1564 assert( strcmp(SCIPconshdlrGetName(sourceconshdlr), CONSHDLR_NAME) == 0 );
    1565 assert( sourcecons != NULL );
    1566 assert( varmap != NULL );
    1567 assert( valid != NULL );
    1568
    1569 *valid = TRUE;
    1570
    1571 SCIPdebugMsg(scip, "Copying method for full orbitope constraint handler.\n");
    1572
    1573 sourcedata = SCIPconsGetData(sourcecons);
    1574 assert( sourcedata != NULL );
    1575 assert( sourcedata->nrows > 0 );
    1576 assert( sourcedata->ncols > 0 );
    1577 assert( sourcedata->vars != NULL );
    1578
    1579 conshdlrdata = SCIPconshdlrGetData(sourceconshdlr);
    1580 assert( conshdlrdata != NULL );
    1581
    1582 /* do not copy non-model constraints */
    1583 if ( !sourcedata->ismodelcons && !conshdlrdata->forceconscopy )
    1584 {
    1585 *valid = FALSE;
    1586
    1587 return SCIP_OKAY;
    1588 }
    1589
    1590 nrows = sourcedata->nrows;
    1591 ncols = sourcedata->ncols;
    1592 sourcevars = sourcedata->vars;
    1593
    1594 SCIP_CALL( SCIPallocBufferArray(scip, &vars, nrows) );
    1595 for (i = 0; i < nrows && *valid; ++i)
    1596 {
    1597 SCIP_CALL( SCIPallocBufferArray(scip, &(vars[i]), ncols) ); /*lint !e866*/
    1598
    1599 for (j = 0; j < ncols && *valid; ++j)
    1600 {
    1601 SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, sourcevars[i][j], &(vars[i][j]), varmap, consmap, global, valid) );
    1602 assert( !(*valid) || vars[i][j] != NULL );
    1603 }
    1604 }
    1605
    1606 /* only create the target constraint, if all variables could be copied */
    1607 if ( *valid )
    1608 {
    1609 /* create copied constraint */
    1610 if ( name == NULL )
    1611 name = SCIPconsGetName(sourcecons);
    1612
    1613 SCIP_CALL( SCIPcreateConsOrbitopeFull(scip, cons, name, vars, nrows, ncols,
    1614 sourcedata->resolveprop, sourcedata->ismodelcons,
    1615 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
    1616 }
    1617
    1618 /* free space; only up to row i if copying failed */
    1619 assert( 0 <= i && i <= nrows );
    1620 for (k = i - 1; k >= 0; --k)
    1621 SCIPfreeBufferArray(scip, &vars[k]);
    1622 SCIPfreeBufferArray(scip, &vars);
    1623
    1624 return SCIP_OKAY;
    1625}
    1626
    1627
    1628/** constraint parsing method of constraint handler */
    1629static
    1630SCIP_DECL_CONSPARSE(consParseOrbitopeFull)
    1631{ /*lint --e{715}*/
    1632 const char* s;
    1633 char* endptr;
    1634 SCIP_VAR*** vars;
    1635 SCIP_VAR* var;
    1636 int nrows;
    1637 int maxnrows;
    1638 int ncols;
    1639 int maxncols;
    1640 int k;
    1641 int j;
    1642
    1643 assert( success != NULL );
    1644
    1645 *success = TRUE;
    1646 s = str;
    1647
    1648 /* skip white space */
    1649 SCIP_CALL( SCIPskipSpace((char**)&s) );
    1650
    1651 if( strncmp(s, "fullOrbitope(", 13) != 0 )
    1652 {
    1653 SCIPerrorMessage("Syntax error - expected \"fullOrbitope(\": %s\n", s);
    1654 *success = FALSE;
    1655 return SCIP_OKAY;
    1656 }
    1657 s += 13;
    1658
    1659 /* loop through string */
    1660 nrows = 0;
    1661 ncols = 0;
    1662 maxnrows = 10;
    1663 maxncols = 10;
    1664
    1665 SCIP_CALL( SCIPallocBufferArray(scip, &vars, maxnrows) );
    1666
    1667 j = 0;
    1668 do
    1669 {
    1670 /* parse variable name */
    1671 SCIP_CALL( SCIPparseVarName(scip, s, &var, &endptr) );
    1672
    1673 if( var == NULL )
    1674 {
    1675 endptr = strchr(endptr, ')');
    1676
    1677 if( endptr == NULL || j > 0 )
    1678 {
    1679 SCIPerrorMessage("not enough variables.\n");
    1680 *success = FALSE;
    1681 }
    1682
    1683 break;
    1684 }
    1685
    1686 s = endptr;
    1687 assert( s != NULL );
    1688
    1689 /* skip white space */
    1690 SCIP_CALL( SCIPskipSpace((char**)&s) );
    1691
    1692 /* begin new row if required */
    1693 if( j == 0 )
    1694 {
    1695 ++nrows;
    1696
    1697 if( nrows > maxnrows )
    1698 {
    1699 maxnrows = SCIPcalcMemGrowSize(scip, nrows);
    1700 SCIP_CALL( SCIPreallocBufferArray(scip, &vars, maxnrows) );
    1701 assert( nrows <= maxnrows );
    1702 }
    1703
    1704 SCIP_CALL( SCIPallocBufferArray(scip, &(vars[nrows-1]), nrows == 1 ? maxncols : ncols) ); /*lint !e866*/
    1705 }
    1706
    1707 /* determine number of columns */
    1708 if( nrows == 1 )
    1709 {
    1710 ncols = j + 1;
    1711
    1712 if( *s == '.' || *s == ')' )
    1713 SCIP_CALL( SCIPreallocBufferArray(scip, &(vars[nrows-1]), ncols) ); /*lint !e866*/
    1714 else if( ncols > maxncols )
    1715 {
    1716 maxncols = SCIPcalcMemGrowSize(scip, ncols);
    1717 SCIP_CALL( SCIPreallocBufferArray(scip, &(vars[nrows-1]), maxncols) ); /*lint !e866*/
    1718 assert( ncols <= maxncols );
    1719 }
    1720 }
    1721 else if( ( j < ncols-1 ) == ( *s == '.' || *s == ')' ) )
    1722 {
    1723 SCIPerrorMessage("variables per row do not match.\n");
    1724 *success = FALSE;
    1725 break;
    1726 }
    1727
    1728 vars[nrows-1][j] = var;
    1729
    1730 if( *s == '.' )
    1731 j = 0;
    1732 else
    1733 ++j;
    1734
    1735 /* skip ',' or '.' */
    1736 if( *s == ',' || *s == '.' )
    1737 ++s;
    1738 }
    1739 while( *s != ')' );
    1740
    1741 if( *success )
    1742 {
    1743 SCIP_CALL( SCIPcreateConsOrbitopeFull(scip, cons, name, vars, nrows, ncols, TRUE, TRUE,
    1744 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
    1745 }
    1746
    1747 for( k = nrows - 1; k >= 0; --k )
    1748 SCIPfreeBufferArray(scip, &vars[k]);
    1749 SCIPfreeBufferArray(scip, &vars);
    1750
    1751 return SCIP_OKAY;
    1752}
    1753
    1754
    1755/** constraint method of constraint handler which returns the variables (if possible) */
    1756static
    1757SCIP_DECL_CONSGETVARS(consGetVarsOrbitopeFull)
    1758{ /*lint --e{715}*/
    1759 SCIP_CONSDATA* consdata;
    1760
    1761 assert( cons != NULL );
    1762 assert( success != NULL );
    1763 assert( vars != NULL );
    1764
    1765 consdata = SCIPconsGetData(cons);
    1766 assert( consdata != NULL );
    1767
    1768 if ( varssize < consdata->ncols * consdata->nrows )
    1769 *success = FALSE;
    1770 else
    1771 {
    1772 int cnt = 0;
    1773 int i;
    1774 int j;
    1775
    1776 for (i = 0; i < consdata->nrows; ++i)
    1777 {
    1778 for (j = 0; j < consdata->ncols; ++j)
    1779 vars[cnt++] = consdata->vars[i][j];
    1780 }
    1781 *success = TRUE;
    1782 }
    1783
    1784 return SCIP_OKAY;
    1785}
    1786
    1787
    1788/** constraint method of constraint handler which returns the number of variables (if possible) */
    1789static
    1790SCIP_DECL_CONSGETNVARS(consGetNVarsOrbitopeFull)
    1791{ /*lint --e{715}*/
    1792 SCIP_CONSDATA* consdata;
    1793
    1794 assert( cons != NULL );
    1795
    1796 consdata = SCIPconsGetData(cons);
    1797 assert( consdata != NULL );
    1798
    1799 *nvars = consdata->ncols * consdata->nrows;
    1800 *success = TRUE;
    1801
    1802 return SCIP_OKAY;
    1803}
    1804
    1805
    1806/*
    1807 * constraint specific interface methods
    1808 */
    1809
    1810/** creates the handler for orbitope constraints and includes it in SCIP */
    1812 SCIP* scip /**< SCIP data structure */
    1813 )
    1814{
    1815 SCIP_CONSHDLRDATA* conshdlrdata;
    1816 SCIP_CONSHDLR* conshdlr;
    1817
    1818 /* create orbitope constraint handler data */
    1819 SCIP_CALL( SCIPallocBlockMemory(scip, &conshdlrdata) );
    1820
    1821 /* include constraint handler */
    1825 consEnfolpOrbitopeFull, consEnfopsOrbitopeFull, consCheckOrbitopeFull, consLockOrbitopeFull,
    1826 conshdlrdata) );
    1827 assert(conshdlr != NULL);
    1828
    1829 /* set non-fundamental callbacks via specific setter functions */
    1830 SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyOrbitopeFull, consCopyOrbitopeFull) );
    1831 SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeOrbitopeFull) );
    1832 SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteOrbitopeFull) );
    1833 SCIP_CALL( SCIPsetConshdlrGetVars(scip, conshdlr, consGetVarsOrbitopeFull) );
    1834 SCIP_CALL( SCIPsetConshdlrGetNVars(scip, conshdlr, consGetNVarsOrbitopeFull) );
    1835 SCIP_CALL( SCIPsetConshdlrParse(scip, conshdlr, consParseOrbitopeFull) );
    1836 SCIP_CALL( SCIPsetConshdlrPresol(scip, conshdlr, consPresolOrbitopeFull,
    1838 SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintOrbitopeFull) );
    1839 SCIP_CALL( SCIPsetConshdlrProp(scip, conshdlr, consPropOrbitopeFull, CONSHDLR_PROPFREQ, CONSHDLR_DELAYPROP,
    1841 SCIP_CALL( SCIPsetConshdlrResprop(scip, conshdlr, consRespropOrbitopeFull) );
    1842 SCIP_CALL( SCIPsetConshdlrExitpre(scip, conshdlr, consExitpreOrbitopeFull) );
    1843 SCIP_CALL( SCIPsetConshdlrSepa(scip, conshdlr, consSepalpOrbitopeFull, consSepasolOrbitopeFull, CONSHDLR_SEPAFREQ,
    1845 SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransOrbitopeFull) );
    1846 SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxOrbitopeFull) );
    1847
    1848 SCIP_CALL( SCIPaddBoolParam(scip, "constraints/" CONSHDLR_NAME "/forceconscopy",
    1849 "Whether orbitope constraints should be forced to be copied to sub SCIPs.",
    1850 &conshdlrdata->forceconscopy, TRUE, DEFAULT_FORCECONSCOPY, NULL, NULL) );
    1851
    1852 return SCIP_OKAY;
    1853}
    1854
    1855
    1856/** creates and captures a full orbitope constraint
    1857 *
    1858 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
    1859 */
    1861 SCIP* scip, /**< SCIP data structure */
    1862 SCIP_CONS** cons, /**< pointer to hold the created constraint */
    1863 const char* name, /**< name of constraint */
    1864 SCIP_VAR*** vars, /**< matrix of variables on which the symmetry acts */
    1865 int nrows, /**< number of set partitioning/packing constraints <=> p */
    1866 int ncols, /**< number of symmetric variable blocks <=> q */
    1867 SCIP_Bool resolveprop, /**< should propagation be resolved? */
    1868 SCIP_Bool ismodelcons, /**< whether the orbitope is a model constraint */
    1869 SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
    1870 * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
    1871 SCIP_Bool separate, /**< should the constraint be separated during LP processing?
    1872 * Usually set to TRUE. */
    1873 SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
    1874 * TRUE for model constraints, FALSE for additional, redundant constraints. */
    1875 SCIP_Bool check, /**< should the constraint be checked for feasibility?
    1876 * TRUE for model constraints, FALSE for additional, redundant constraints. */
    1877 SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
    1878 * Usually set to TRUE. */
    1879 SCIP_Bool local, /**< is constraint only valid locally?
    1880 * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
    1881 SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
    1882 * Usually set to FALSE. In column generation applications, set to TRUE if pricing
    1883 * adds coefficients to this constraint. */
    1884 SCIP_Bool dynamic, /**< is constraint subject to aging?
    1885 * Usually set to FALSE. Set to TRUE for own cuts which
    1886 * are separated as constraints. */
    1887 SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
    1888 * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
    1889 SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
    1890 * if it may be moved to a more global node?
    1891 * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
    1892 )
    1893{
    1894 SCIP_CONSHDLR* conshdlr;
    1895 SCIP_CONSDATA* consdata;
    1896
    1897 /* find the orbitope constraint handler */
    1898 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
    1899 if ( conshdlr == NULL )
    1900 {
    1901 SCIPerrorMessage("full orbitope constraint handler not found\n");
    1902 return SCIP_PLUGINNOTFOUND;
    1903 }
    1904
    1905 assert( nrows > 0 );
    1906 assert( ncols > 0 );
    1907
    1908 /* run some checks */
    1909#ifndef NDEBUG
    1910 {
    1911 SCIP_Real obj;
    1912 int i;
    1913 int j;
    1914 for (i = 0; i < nrows; ++i)
    1915 {
    1916 /* initialize obj to infinity */
    1917 obj = SCIPinfinity(scip);
    1918 for (j = 0; j < ncols; ++j)
    1919 {
    1920 SCIP_Bool fixedZero;
    1921 SCIP_VAR* var;
    1922
    1923 var = vars[i][j];
    1924 assert(var != NULL);
    1925
    1926 if ( SCIPvarIsNegated(var) )
    1927 var = SCIPvarGetNegatedVar(var);
    1928
    1929 /* all variables need to be binary */
    1930 assert( SCIPvarIsBinary(var) );
    1931
    1932 /* fixed variables have obj = 0; for variables fixed to 0, we assume that there is no
    1933 problem (but we cannot always check it, e.g., when in the original problem
    1934 variables were fixed and this problem was copied.) */
    1935 fixedZero = ( SCIPisZero(scip, SCIPvarGetLbGlobal(var)) && SCIPisZero(scip, SCIPvarGetUbGlobal(var)) );
    1936
    1937 /* @todo adapt correctness of the following check for sub-scips */
    1938 if ( SCIPgetSubscipDepth(scip) == 0 )
    1939 {
    1940 /* check whether all variables in a row have the same objective */
    1941 if ( ! fixedZero && SCIPisInfinity(scip, obj) )
    1942 obj = SCIPvarGetObj(var);
    1943 else
    1944 {
    1945 assert( fixedZero || ! SCIPvarIsActive(var) || SCIPisEQ(scip, obj, SCIPvarGetObj(var)) );
    1946 }
    1947 }
    1948 }
    1949 }
    1950 }
    1951#endif
    1952
    1953 /* create constraint data */
    1954 SCIP_CALL( consdataCreate(scip, &consdata, vars, nrows, ncols, resolveprop, ismodelcons) );
    1955
    1956 /* create constraint */
    1957 SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, initial, separate, enforce, check, propagate,
    1958 local, modifiable, dynamic, removable, stickingatnode) );
    1959
    1960 return SCIP_OKAY;
    1961}
    1962
    1963/** creates and captures a full orbitope constraint in its most basic variant, i. e., with all constraint flags set to
    1964 * their default values, which can be set afterwards using SCIPsetConsFLAGNAME()
    1965 *
    1966 * @see SCIPcreateConsOrbitopeFull() for the default constraint flag configuration
    1967 *
    1968 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
    1969 */
    1971 SCIP* scip, /**< SCIP data structure */
    1972 SCIP_CONS** cons, /**< pointer to hold the created constraint */
    1973 const char* name, /**< name of constraint */
    1974 SCIP_VAR*** vars, /**< matrix of variables on which the symmetry acts */
    1975 int nrows, /**< number of set partitioning/packing constraints <=> p */
    1976 int ncols, /**< number of symmetric variable blocks <=> q */
    1977 SCIP_Bool resolveprop, /**< should propagation be resolved? */
    1978 SCIP_Bool ismodelcons /**< whether the orbitope is a model constraint */
    1979 )
    1980{
    1981 SCIP_CALL( SCIPcreateConsOrbitopeFull(scip, cons, name, vars, nrows, ncols,
    1982 resolveprop, ismodelcons, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE) );
    1983
    1984 return SCIP_OKAY;
    1985}
    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:248
    #define SCIP_UNUSED(x)
    Definition: def.h:409
    #define SCIP_Bool
    Definition: def.h:91
    #define SCIP_Real
    Definition: def.h:156
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define MAX(x, y)
    Definition: def.h:220
    #define SCIP_CALL(x)
    Definition: def.h:355
    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:2588
    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:647
    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:4316
    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:4336
    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:8419
    SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
    Definition: cons.c:8648
    SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
    Definition: cons.c:8558
    SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
    Definition: cons.c:8588
    SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
    Definition: cons.c:8578
    SCIP_Bool SCIPconsIsActive(SCIP_CONS *cons)
    Definition: cons.c:8450
    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:8608
    SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
    Definition: cons.c:8628
    const char * SCIPconsGetName(SCIP_CONS *cons)
    Definition: cons.c:8389
    SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
    Definition: cons.c:8638
    SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
    Definition: cons.c:8668
    SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
    Definition: cons.c:8568
    SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
    Definition: cons.c:8658
    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:1765
    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_VAR * SCIPvarGetNegatedVar(SCIP_VAR *var)
    Definition: var.c:23868
    SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
    Definition: var.c:23642
    SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
    Definition: var.c:23478
    SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
    Definition: var.c:23386
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24268
    SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
    Definition: var.c:23900
    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:24142
    SCIP_RETCODE SCIPaddVarLocksType(SCIP *scip, SCIP_VAR *var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
    Definition: scip_var.c:5118
    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:24234
    SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
    Definition: var.c:23443
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24120
    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:1221
    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
    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