SCIP

    Solving Constraint Integer Programs

    sepa_mixing.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 sepa_mixing.c
    26 * @ingroup DEFPLUGINS_SEPA
    27 * @brief mixing/star inequality separator
    28 * @author Weikun Chen
    29 * @author Marc Pfetsch
    30 *
    31 * This separator generates cuts based on the mixing set
    32 * \f[
    33 * X = \{ (x,y) \in \{0,1\}^{N \cup M} \times \mathbb{R} \, : \, y \geq a_i x_i, \, \textrm{for} \, i \in N, \,
    34 * y \leq u - a_i x_i, \, \textrm{for} \, i \in M, \, 0 \leq y \leq u \},
    35 * \f]
    36 * where \f$0 \leq a_i \leq u\f$ for all \f$i\f$. This information can be obtained directly from the variable bounds data
    37 * structure. The separator will generate three classes of cuts.
    38 *
    39 * VLB: Let \f$T\f$ be a subset of \f$N\f$, wlog, \f$T = \{1,\ldots,r\}\f$ with \f$a_1 \leq a_2 \leq \ldots \leq a_r\f$.
    40 * Let \f$a_0 = 0\f$. The mixing/star VLB cut is of the form \f$ y \geq \sum_{i=1}^r (a_i - a_{i-1})x_i \f$.
    41 *
    42 * VUB: Let \f$T\f$ be a subset of \f$M\f$, wlog, \f$T = \{1,\ldots,r\}\f$ with \f$a_1 \leq a_2 \leq \ldots \leq a_r\f$.
    43 * Let \f$a_0 = 0\f$. The mixing/star VUB cut is of the form \f$ y \leq u - \sum_{i=1}^r (a_i - a_{i-1})x_i \f$.
    44 *
    45 * CONFLICT: Consider \f$i \in N\f$ and \f$j \in M\f$ with \f$a_i + a_j > u\f$. The conflict cut is
    46 * \f$x_i + x_j \leq 1\f$.
    47 *
    48 * A small example is described in the following to see the generated cuts.
    49 * \f[
    50 * Y = \{ (x,y) \in \{0,1\}^{4} \times \mathbb{R} \, : \, y \geq 2x_1, \, y \geq 3x_2, \, y \leq 4 - x_3, \,
    51 * y \leq 4 - 2 x_4, \, 0 \leq y \leq 4 \}.
    52 * \f]
    53 * In this small example, the mixing/star cuts \f$y \geq 2x_1 + x_2\f$ (VLB) and \f$y \leq 4 - x_3 - x_4\f$ (VUB) will be
    54 * considered to be generated. Besides the mixing cuts, we also consider the conflict cut \f$x_1 + x_3 \leq 1\f$ (CONFLICT).
    55 *
    56 *
    57 * For an overview see:
    58 * Atamturk, A., Nemhauser, G.L. and Savelsbergh, M.W.,@n
    59 * The mixed vertex packing problem.@n
    60 * Mathematical Programming, 89(1), 35-53, 2000.
    61 *
    62 * Some remarks:
    63 * - Besides the mixing inequality, we also add the conflict inequality.
    64 * - Currently, the performance is bad on the neos-565672 instance.
    65 * The reason is that, after adding the separator, SCIP spends a lot of time at the stage of cutting plane generation.
    66 * - We do not consider sparsity of the cuts as we aim to find a most violated cut.
    67 * - Besides the most violated cut we consider, we also add an additional variable to make the cut be the strongest one,
    68 * even the additional variable does not contribute any to the violation.
    69 *
    70 */
    71
    72/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    73
    75#include "scip/pub_implics.h"
    76#include "scip/pub_lp.h"
    77#include "scip/pub_message.h"
    78#include "scip/pub_misc.h"
    79#include "scip/pub_sepa.h"
    80#include "scip/pub_var.h"
    81#include "scip/scip_branch.h"
    82#include "scip/scip_cut.h"
    83#include "scip/scip_lp.h"
    84#include "scip/scip_mem.h"
    85#include "scip/scip_message.h"
    86#include "scip/scip_numerics.h"
    87#include "scip/scip_param.h"
    88#include "scip/scip_prob.h"
    89#include "scip/scip_sepa.h"
    90#include "scip/scip_sol.h"
    92#include "scip/scip_var.h"
    93#include "scip/sepa_mixing.h"
    94#include "scip/scip_tree.h"
    95#include "scip/sepa_mixing.h"
    96
    97
    98#define SEPA_NAME "mixing"
    99#define SEPA_DESC "mixing inequality separator"
    100#define DEFAULT_MAXROUNDS -1 /**< maximal number of mixing separation rounds per node (-1: unlimited) */
    101#define DEFAULT_MAXROUNDSROOT -1 /**< maximal number of mixing separation rounds in the root node (-1: unlimited) */
    102#define SEPA_PRIORITY -50
    103#define SEPA_FREQ 10
    104#define SEPA_MAXBOUNDDIST 1.0
    105#define SEPA_USESSUBSCIP FALSE /**< does the separator use a secondary SCIP instance? */
    106#define SEPA_DELAY FALSE /**< should separation method be delayed, if other separators found cuts? */
    107
    108#define DEFAULT_USELOCALBOUNDS FALSE /**< should local bounds be used? */
    109#define DEFAULT_ISCUTSONINTS FALSE /**< should general/implicit integer variables be used to generate cuts? */
    110#define DEFAULT_MAXNUNSUCCESSFUL 10 /**< maximal number of consecutive unsuccessful iterations */
    111
    112/** separator-specific data for the mixing separator */
    113struct SCIP_SepaData
    114{
    115 SCIP_Bool uselocalbounds; /**< should local bounds be used? */
    116 SCIP_Bool iscutsonints; /**< should general/implicit integer variables be used to generate cuts? */
    117 int maxrounds; /**< maximal number of mixing separation rounds per node (-1: unlimited) */
    118 int maxroundsroot; /**< maximal number of mixing separation rounds in the root node (-1: unlimited) */
    119 int nunsuccessful; /**< number of consecutive unsuccessful iterations */
    120 int maxnunsuccessful; /**< maximal number of consecutive unsuccessful iterations */
    121};
    122
    123/*
    124 * local methods
    125 */
    126
    127/** adds the given cut */
    128static
    130 SCIP* scip, /**< SCIP data structure */
    131 SCIP_SEPA* sepa, /**< separator */
    132 SCIP_SOL* sol, /**< the solution that should be separated, or NULL for LP solution */
    133 SCIP_Real* cutcoefs, /**< coefficients of active variables in cut */
    134 int* cutinds, /**< problem indices of variables in cut */
    135 int cutnnz, /**< number of non-zeros in cut */
    136 SCIP_Real cutrhs, /**< right hand side of cut */
    137 SCIP_Bool cutislocal, /**< Is the cut only locally valid? */
    138 SCIP_Bool* cutoff, /**< pointer to store whether a cutoff has been detected */
    139 int* ncuts /**< pointer to update number of cuts added */
    140 )
    141{
    142 char cutname[SCIP_MAXSTRLEN];
    143 SCIP_VAR** vars;
    144 SCIP_ROW* cut;
    145 int v;
    146
    147 assert(cutcoefs != NULL);
    148 assert(cutinds != NULL);
    149 assert(ncuts != NULL);
    150 assert(cutoff != NULL);
    151
    152 *cutoff = FALSE;
    153
    154 /* get active problem variables */
    155 vars = SCIPgetVars(scip);
    156
    157 /* construct cut name */
    158 (void) SCIPsnprintf(cutname, SCIP_MAXSTRLEN, "mix%" SCIP_LONGINT_FORMAT "_x%d", SCIPgetNLPs(scip), *ncuts);
    159
    160 /* create empty cut */
    161 SCIP_CALL( SCIPcreateEmptyRowSepa(scip, &cut, sepa, cutname, -SCIPinfinity(scip), cutrhs,
    162 cutislocal, FALSE, TRUE) );
    163
    164 /* cache the row extension and only flush them if the cut gets added */
    166
    167 /* collect all non-zero coefficients */
    168 for( v = 0; v < cutnnz; ++v )
    169 {
    170 SCIP_CALL( SCIPaddVarToRow(scip, cut, vars[cutinds[v]], cutcoefs[v]) );
    171 }
    172
    173 /* flush all changes before adding the cut */
    175
    176 if( SCIPisCutEfficacious(scip, sol, cut) )
    177 {
    178 /* set cut rank */
    179 SCIProwChgRank(cut, 1);
    180
    181#ifdef SCIP_DEBUG
    182 SCIPdebugMsg(scip, "-> found cut (eff: %f): ", SCIPgetCutEfficacy(scip, sol, cut));
    184#endif
    185
    186 if( cutislocal )
    187 {
    188 /* local cuts are added to the sepastore */
    189 SCIP_CALL( SCIPaddRow(scip, cut, FALSE, cutoff) );
    190 }
    191 else
    192 {
    194 }
    195 (*ncuts)++;
    196 }
    197
    198 /* release the row */
    199 SCIP_CALL( SCIPreleaseRow(scip, &cut) );
    200
    201 return SCIP_OKAY;
    202}
    203
    204/** searches and adds mixing cuts that are violated by the given solution value array
    205 *
    206 * This function implements a separation heuristic that runs in linear time in comparison to the quadratic exact
    207 * algorithm in Atamturk et al.:
    208 * - Lower and upper bounds are considered separately. Then possible conflict cuts.
    209 * - Variable lower/upper bounds data are collected, i.e., the corresponding binary variables and coefficients.
    210 * - These lists are sorted non-increasingly according to the solution values.
    211 * - Then binary variables are added in turn as long as their coefficients increase in order to make the coefficients
    212 * nonnegative. This clearly makes the cuts heuristic, since it is order dependent, but also sparser.
    213 * - The procedure stops as soon as it reaches 0 solution values.
    214 * - If the cut is efficious it is added.
    215 *
    216 * @todo Check whether one wants to sort according to the quotient of solution values and coefficients to increase the
    217 * chance of having smaller coefficients in the front.
    218 */
    219static
    221 SCIP* scip, /**< SCIP data structure */
    222 SCIP_SEPA* sepa, /**< separator */
    223 SCIP_SOL* sol, /**< the solution that should be separated, or NULL for LP solution */
    224 SCIP_Bool* cutoff, /**< whether a cutoff has been detected */
    225 int* ncuts /**< pointer to store the number of generated cuts */
    226 )
    227{
    228 SCIP_SEPADATA* sepadata;
    229 SCIP_VAR* var;
    230 SCIP_VAR** vars;
    231 SCIP_Real* vlbmixcoefs;
    232 SCIP_Real* vlbmixsols;
    233 SCIP_Real* vubmixcoefs;
    234 SCIP_Real* vubmixsols;
    235 SCIP_Real* cutcoefs;
    236 SCIP_Real cutrhs;
    237 int* vlbmixinds;
    238 int* vubmixinds;
    239 int* cutinds;
    240 int* vlbmixsigns;
    241 int* vubmixsigns;
    242 int firstvar;
    243 int nmaxvars;
    244 int nvars;
    245 int i;
    246 int k;
    247
    248 assert(sepa != NULL);
    249 assert(cutoff != NULL);
    250 assert(ncuts != NULL);
    251
    252 *cutoff = FALSE;
    253 *ncuts = 0;
    254
    255 /* exit if there are no binary variables - ignore integer variables that have 0/1 bounds */
    256 nmaxvars = SCIPgetNBinVars(scip);
    257 if( nmaxvars <= 0 )
    258 return SCIP_OKAY;
    259
    260 sepadata = SCIPsepaGetData(sepa);
    261 assert(sepadata != NULL);
    262
    263 /* get the index of the first considered variable */
    264 if( sepadata->iscutsonints )
    265 {
    266 /* generate cuts based on all nonbinary variabels */
    267 firstvar = SCIPgetNBinVars(scip);
    268 }
    269 else
    270 {
    271 /* only generate cuts based on continuous variables */
    273 }
    274 nvars = SCIPgetNVars(scip);
    275 if( firstvar == nvars )
    276 return SCIP_OKAY;
    277
    278 vars = SCIPgetVars(scip);
    279
    280 /* allocate temporary memory */
    281 SCIP_CALL( SCIPallocBufferArray(scip, &vlbmixcoefs, nmaxvars) );
    282 SCIP_CALL( SCIPallocBufferArray(scip, &vlbmixsols, nmaxvars) );
    283 SCIP_CALL( SCIPallocBufferArray(scip, &vlbmixinds, nmaxvars) );
    284 SCIP_CALL( SCIPallocBufferArray(scip, &vlbmixsigns, nmaxvars) );
    285 SCIP_CALL( SCIPallocBufferArray(scip, &vubmixcoefs, nmaxvars) );
    286 SCIP_CALL( SCIPallocBufferArray(scip, &vubmixsols, nmaxvars) );
    287 SCIP_CALL( SCIPallocBufferArray(scip, &vubmixinds, nmaxvars) );
    288 SCIP_CALL( SCIPallocBufferArray(scip, &vubmixsigns, nmaxvars) );
    289 SCIP_CALL( SCIPallocBufferArray(scip, &cutcoefs, nmaxvars + 1) );
    290 SCIP_CALL( SCIPallocBufferArray(scip, &cutinds, nmaxvars + 1) );
    291
    292 for( i = firstvar; i < nvars; i++ )
    293 {
    294 SCIP_VAR** vlbvars;
    295 SCIP_Real* vlbcoefs;
    296 SCIP_Real* vlbconsts;
    297 SCIP_VAR** vubvars;
    298 SCIP_Real* vubcoefs;
    299 SCIP_Real* vubconsts;
    300 SCIP_Real maxabscoef;
    301 SCIP_Real activity;
    302 SCIP_Real lastcoef;
    303 SCIP_Real varsolval;
    306 SCIP_Bool islocallb = FALSE; /* Is it a local lower bound or global lower bound? */
    307 SCIP_Bool islocalub = FALSE; /* Is it a local upper bound or global upper bound? */
    308 SCIP_Bool cutislocal; /* Is it a local cut or global cut? */
    309 int vlbmixsize = 0;
    310 int vubmixsize = 0;
    311 int cutnnz = 0;
    312 int maxabsind;
    313 int maxabssign;
    314 int nvlb;
    315 int nvub;
    316 int j;
    317
    318 var = vars[i];
    320
    321 if( SCIPvarGetProbindex(var) < 0 )
    322 continue;
    323
    324 nvlb = SCIPvarGetNVlbs(var);
    325 nvub = SCIPvarGetNVubs(var);
    326
    327 if( nvlb == 0 && nvub == 0 )
    328 continue;
    329
    330 /* skip lower bound if the LP solution value is equal to the upper bound of the continuous variable */
    331 varsolval = SCIPgetSolVal(scip, sol, var);
    332 if( SCIPisFeasEQ(scip, SCIPvarGetUbLocal(var), varsolval) )
    333 goto VUB;
    334
    335 if( nvlb == 0 )
    336 goto VUB;
    337
    338 /* get variable lower variable bounds information */
    339 vlbvars = SCIPvarGetVlbVars(var);
    340 vlbcoefs = SCIPvarGetVlbCoefs(var);
    341 vlbconsts = SCIPvarGetVlbConstants(var);
    342
    343 maxabscoef = 0.0;
    344 maxabsind = -1;
    345 maxabssign = 0;
    346
    347 lb = SCIPvarGetLbGlobal(var);
    348 if( sepadata->uselocalbounds && SCIPisLT(scip, lb, SCIPvarGetLbLocal(var)) )
    349 {
    350 /* this is a lcoal cut */
    351 islocallb = TRUE;
    352 lb = SCIPvarGetLbLocal(var);
    353 }
    354
    355#ifdef SCIP_DEBUG
    356 for( j = 0; j < nvlb; j++ )
    357 {
    358 SCIP_Real tmplb;
    359
    360 if( SCIPvarIsBinary(vlbvars[j]) && SCIPvarGetProbindex(vlbvars[j]) >= 0 )
    361 {
    362 tmplb = (vlbcoefs[j] > 0) ? vlbconsts[j] : (vlbconsts[j] + vlbcoefs[j]);
    363 assert( SCIPisFeasLE(scip, tmplb, lb) );
    364 }
    365 }
    366#endif
    367
    368 assert( SCIPisFeasLE(scip, lb, SCIPvarGetUbLocal(var)) );
    369
    370 /* extract the useful variable bounds information (binary and nonredundant) */
    371 for( j = 0; j < nvlb; j++ )
    372 {
    373 /* consider only active and binary variables */
    374 if( SCIPvarIsBinary(vlbvars[j]) && SCIPvarGetProbindex(vlbvars[j]) >= 0 )
    375 {
    376 SCIP_Real maxactivity;
    377 SCIP_Real coef;
    378
    379 maxactivity = (vlbcoefs[j] > 0) ? (vlbconsts[j] + vlbcoefs[j]) : vlbconsts[j];
    380
    381 /* skip redundant variable bound constraints */
    382 if( SCIPisFeasLE(scip, maxactivity, lb) )
    383 continue;
    384
    385 if( vlbcoefs[j] > 0 )
    386 {
    387 coef = maxactivity - lb;
    388 vlbmixsigns[vlbmixsize] = 0;
    389 }
    390 else
    391 {
    392 coef = lb - maxactivity;
    393 vlbmixsigns[vlbmixsize] = 1;
    394 }
    395 assert(vlbmixsize <= nvars);
    396
    397 vlbmixcoefs[vlbmixsize] = REALABS(coef);
    398 vlbmixinds[vlbmixsize] = SCIPvarGetProbindex(vlbvars[j]);
    399 vlbmixsols[vlbmixsize] = (! vlbmixsigns[vlbmixsize]) ? SCIPgetSolVal(scip, sol, vlbvars[j]) : (1.0 - SCIPgetSolVal(scip, sol, vlbvars[j]));
    400
    401 /* update the maximal coefficient if needed */
    402 if( maxabscoef < vlbmixcoefs[vlbmixsize] )
    403 {
    404 maxabscoef = vlbmixcoefs[vlbmixsize];
    405 maxabsind = vlbmixinds[vlbmixsize];
    406 maxabssign = vlbmixsigns[vlbmixsize];
    407 }
    408
    409 ++vlbmixsize;
    410
    411 /* stop if size is exceeded; possibly ignore redundant variable bounds */
    412 if( vlbmixsize >= nmaxvars )
    413 break;
    414 }
    415 }
    416 assert( vlbmixsize <= nmaxvars );
    417
    418 /* stop if no variable lower bounds information exists */
    419 if( vlbmixsize == 0 )
    420 goto VUB;
    421
    422 /* stop if the current solution value of the transformed continuous variable is larger than the maximal coefficient */
    423 if( SCIPisFeasGT(scip, varsolval - lb, maxabscoef) )
    424 goto VUB;
    425
    426 /* sort the solution values in non-increasing order */
    427 SCIPsortDownRealRealIntInt(vlbmixsols, vlbmixcoefs, vlbmixinds, vlbmixsigns, vlbmixsize);
    428
    429 /* add the continuous variable */
    430 cutcoefs[cutnnz] = -1;
    431 cutinds[cutnnz] = SCIPvarGetProbindex(var);
    432 cutrhs = -lb;
    433 cutnnz++;
    434
    435 activity = -(varsolval - lb);
    436 lastcoef = 0.0;
    437
    438 /* loop over the variables and add the variable to the cut if its coefficient is larger than that of the last variable */
    439 for( j = 0; j < vlbmixsize; j++ )
    440 {
    441 SCIP_Real solval;
    442
    443 solval = vlbmixsols[j];
    444
    445 /* stop if we can not find a violated cut or we reached 0 solution values */
    446 if( activity + solval * (maxabscoef - lastcoef) < 0.0 || SCIPisFeasZero(scip, solval) )
    447 break;
    448 else
    449 {
    450 /* skip if we have already added a variable with bigger coefficient */
    451 if( SCIPisLE(scip, vlbmixcoefs[j], lastcoef) )
    452 continue;
    453 else
    454 {
    455 activity += (vlbmixcoefs[j] - lastcoef) * solval;
    456 if( vlbmixsigns[j] )
    457 {
    458 cutcoefs[cutnnz] = lastcoef - vlbmixcoefs[j];
    459 cutrhs -= vlbmixcoefs[j] - lastcoef;
    460 }
    461 else
    462 cutcoefs[cutnnz] = vlbmixcoefs[j] - lastcoef;
    463 cutinds[cutnnz++] = vlbmixinds[j];
    464 lastcoef = vlbmixcoefs[j];
    465 }
    466 }
    467 }
    468
    469 /* add the variable with maximal coefficient to make sure the cut is strong enough */
    470 if( SCIPisGT(scip, maxabscoef, lastcoef) )
    471 {
    472 /* do not update activity: either the corresponding solval is 0.0 or the cut will not become efficious */
    473 if( maxabssign )
    474 {
    475 cutcoefs[cutnnz] = lastcoef - maxabscoef;
    476 cutrhs -= maxabscoef - lastcoef;
    477 }
    478 else
    479 cutcoefs[cutnnz] = maxabscoef - lastcoef;
    480 cutinds[cutnnz++] = maxabsind;
    481 }
    482 assert( cutnnz <= nmaxvars + 1 );
    483
    484 /* add the cut if the violtion is good enough and the number of nonzero coefficients is larger than 2 */
    485 if( SCIPisEfficacious(scip, activity) && cutnnz > 2 )
    486 {
    487 SCIP_CALL( addCut(scip, sepa, sol, cutcoefs, cutinds, cutnnz, cutrhs, islocallb, cutoff, ncuts) );
    488 }
    489
    490 VUB:
    491 if( nvub == 0 )
    492 goto CONFLICT;
    493
    494 /* get variable upper bounds information */
    495 vubvars = SCIPvarGetVubVars(var);
    496 vubcoefs = SCIPvarGetVubCoefs(var);
    497 vubconsts = SCIPvarGetVubConstants(var);
    498
    499 maxabscoef = 0.0;
    500 maxabsind = -1;
    501 maxabssign = 0;
    502
    503 /* stop if the lower bound is equal to the solution value of the continuous variable */
    504 if( SCIPisFeasEQ(scip, SCIPvarGetLbLocal(var), varsolval) )
    505 goto CONFLICT;
    506
    507 ub = SCIPvarGetUbGlobal(var);
    508 if( sepadata->uselocalbounds && SCIPisGT(scip, ub, SCIPvarGetUbLocal(var)) )
    509 {
    510 /* this is a lcoal cut */
    511 islocalub = TRUE;
    512 ub = SCIPvarGetUbLocal(var);
    513 }
    514
    515#ifdef SCIP_DEBUG
    516 for( j = 0; j < nvub; j++ )
    517 {
    518 SCIP_Real tmpub;
    519
    520 if( SCIPvarIsBinary(vubvars[j]) && SCIPvarGetProbindex(vubvars[j]) >= 0 )
    521 {
    522 tmpub = (vubcoefs[j] < 0) ? vubconsts[j] : (vubconsts[j] + vubcoefs[j]);
    523 assert( SCIPisFeasGE(scip, tmpub, ub) );
    524 }
    525 }
    526#endif
    527
    528 assert( SCIPisFeasLE(scip, SCIPvarGetLbLocal(var), ub) );
    529
    530 /* extract the useful variable bounds information (binary and nonredundant) */
    531 for( j = 0; j < nvub; j++ )
    532 {
    533 /* consider only active and binary variables */
    534 if( SCIPvarIsBinary(vubvars[j]) && SCIPvarGetProbindex(vubvars[j]) >= 0 )
    535 {
    536 SCIP_Real minactivity;
    537 SCIP_Real coef;
    538
    539 minactivity = (vubcoefs[j] < 0) ? (vubconsts[j] + vubcoefs[j]) : vubconsts[j];
    540
    541 /* skip redundant variable bound constraints */
    542 if( SCIPisFeasLE(scip, ub, minactivity) )
    543 continue;
    544
    545 if( vubcoefs[j] > 0 )
    546 {
    547 coef = ub - minactivity;
    548 vubmixsigns[vubmixsize] = 1;
    549 }
    550 else
    551 {
    552 coef = minactivity - ub;
    553 vubmixsigns[vubmixsize] = 0;
    554 }
    555
    556 vubmixcoefs[vubmixsize] = REALABS(coef);
    557 vubmixinds[vubmixsize] = SCIPvarGetProbindex(vubvars[j]);
    558 vubmixsols[vubmixsize] = (! vubmixsigns[vubmixsize]) ? SCIPgetSolVal(scip, sol, vubvars[j]): (1.0 - SCIPgetSolVal(scip, sol, vubvars[j]));
    559
    560 /* update the maximal coefficient if needed */
    561 if( maxabscoef < vubmixcoefs[vubmixsize] )
    562 {
    563 maxabscoef = vubmixcoefs[vubmixsize];
    564 maxabsind = vubmixinds[vubmixsize];
    565 maxabssign = vubmixsigns[vubmixsize];
    566 }
    567
    568 ++vubmixsize;
    569
    570 /* stop if size is exceeded; possibly ignore redundant variable bounds */
    571 if( vubmixsize >= nmaxvars )
    572 break;
    573 }
    574 }
    575 assert( vubmixsize <= nmaxvars );
    576
    577 /* stop if no variable upper bounds information exists */
    578 if( vubmixsize == 0 )
    579 goto CONFLICT;
    580
    581 /* stop if the current solution value of transformed continuous variable is larger than the maximal coefficient */
    582 if( SCIPisFeasGT(scip, ub - varsolval, maxabscoef) )
    583 goto CONFLICT;
    584
    585 /* sort the solution values in non-increasing order */
    586 SCIPsortDownRealRealIntInt(vubmixsols, vubmixcoefs, vubmixinds, vubmixsigns, vubmixsize);
    587
    588 /* add the continuous variables */
    589 cutnnz = 0;
    590 cutcoefs[cutnnz] = 1;
    591 cutinds[cutnnz] = SCIPvarGetProbindex(var);
    592 cutrhs = ub;
    593 cutnnz++;
    594
    595 activity = varsolval - ub;
    596 lastcoef = 0.0;
    597
    598 for( j = 0; j < vubmixsize; j++ )
    599 {
    600 SCIP_Real solval;
    601
    602 solval = vubmixsols[j];
    603
    604 /* stop if we can not find a violated cut or we reached 0 solution values */
    605 if( activity + solval * (maxabscoef - lastcoef) < 0.0 || SCIPisFeasZero(scip, solval) )
    606 break;
    607 else
    608 {
    609 /* skip if we have already added a variable with bigger coefficient */
    610 if( SCIPisLE(scip, vubmixcoefs[j], lastcoef) )
    611 continue;
    612 else
    613 {
    614 activity += (vubmixcoefs[j] - lastcoef) * solval;
    615 if( vubmixsigns[j] )
    616 {
    617 cutcoefs[cutnnz] = lastcoef - vubmixcoefs[j];
    618 cutrhs -= vubmixcoefs[j] - lastcoef;
    619 }
    620 else
    621 cutcoefs[cutnnz] = vubmixcoefs[j] - lastcoef;
    622 cutinds[cutnnz++] = vubmixinds[j];
    623 lastcoef = vubmixcoefs[j];
    624 }
    625 }
    626 }
    627
    628 /* add the variable with maximal coefficient if needed */
    629 if( SCIPisGT(scip, maxabscoef, lastcoef) )
    630 {
    631 /* do not update activity: either the corresponding solval is 0.0 or the cut will not become efficious */
    632 if( maxabssign )
    633 {
    634 cutcoefs[cutnnz] = lastcoef - maxabscoef;
    635 cutrhs -= maxabscoef - lastcoef;
    636 }
    637 else
    638 cutcoefs[cutnnz] = maxabscoef - lastcoef;
    639 cutinds[cutnnz++] = maxabsind;
    640 }
    641 assert( cutnnz <= nmaxvars + 1 );
    642
    643 /* add the cut if the violtion is good enough and the number of nonzero coefficients is larger than 2 */
    644 if( SCIPisEfficacious(scip, activity) && cutnnz > 2 )
    645 {
    646 SCIP_CALL( addCut(scip, sepa, sol, cutcoefs, cutinds, cutnnz, cutrhs, islocalub, cutoff, ncuts) );
    647 }
    648
    649 CONFLICT:
    650 /* combine the variable lower bounds information and upper bounds information together to generate cuts */
    651 /* stop if no useful variable lower (or upper) bounds information exists */
    652 if( vlbmixsize == 0 || vubmixsize == 0 )
    653 continue;
    654
    655 assert( lb != SCIP_INVALID ); /*lint !e777*/
    656 assert( ub != SCIP_INVALID ); /*lint !e777*/
    657
    658 cutislocal = islocallb || islocalub;
    659 for( j = 0; j < vlbmixsize; j++ )
    660 {
    661 SCIP_Real solval;
    662
    663 solval = vlbmixsols[j];
    664
    665 /* stop if no violated cut exists */
    666 if( ! SCIPisEfficacious(scip, solval + vubmixsols[0] - 1.0) )
    667 break;
    668
    669 for( k = 0; k < vubmixsize; k++ )
    670 {
    671 /* only consider the inequality if its violation is good enough */
    672 if( SCIPisEfficacious(scip, solval + vubmixsols[k] - 1.0) )
    673 {
    674 SCIP_Real tmp;
    675
    676 tmp = lb + vlbmixcoefs[j] + vubmixcoefs[k] - ub;
    677
    678 /* add the cut if it is valid */
    679 if( SCIPisEfficacious(scip, tmp) )
    680 {
    681 cutnnz = 2;
    682 cutrhs = 1.0;
    683 cutcoefs[0] = vlbmixsigns[j] ? -1.0 : 1.0;
    684 cutcoefs[1] = vubmixsigns[k] ? -1.0 : 1.0;
    685 cutinds[0] = vlbmixinds[j];
    686 cutinds[1] = vubmixinds[k];
    687 cutrhs = vlbmixsigns[j] ? (cutrhs - 1.0) : cutrhs;
    688 cutrhs = vubmixsigns[k] ? (cutrhs - 1.0) : cutrhs;
    689 SCIP_CALL( addCut(scip, sepa, sol, cutcoefs, cutinds, cutnnz, cutrhs, cutislocal, cutoff, ncuts) );
    690 }
    691 }
    692 else
    693 break;
    694 }
    695 }
    696 }
    697
    698 /* free temporary memory */
    699 SCIPfreeBufferArray(scip, &cutinds);
    700 SCIPfreeBufferArray(scip, &cutcoefs);
    701 SCIPfreeBufferArray(scip, &vubmixsigns);
    702 SCIPfreeBufferArray(scip, &vubmixinds);
    703 SCIPfreeBufferArray(scip, &vubmixsols);
    704 SCIPfreeBufferArray(scip, &vubmixcoefs);
    705 SCIPfreeBufferArray(scip, &vlbmixsigns);
    706 SCIPfreeBufferArray(scip, &vlbmixinds);
    707 SCIPfreeBufferArray(scip, &vlbmixsols);
    708 SCIPfreeBufferArray(scip, &vlbmixcoefs);
    709
    710 return SCIP_OKAY;
    711}
    712
    713
    714/*
    715 * Callback methods of separator
    716 */
    717
    718/** copy method for separator plugins (called when SCIP copies plugins) */
    719static
    720SCIP_DECL_SEPACOPY(sepaCopyMixing)
    721{ /*lint --e{715}*/
    722 assert(scip != NULL);
    723 assert(sepa != NULL);
    724
    726
    727 /* call inclusion method of separator */
    729
    730 return SCIP_OKAY;
    731}
    732
    733/** destructor of separator to free user data (called when SCIP is exiting) */
    734static
    735SCIP_DECL_SEPAFREE(sepaFreeMixing)
    736{ /*lint --e{715}*/
    737 SCIP_SEPADATA* sepadata;
    738
    739 assert(scip != NULL);
    740 assert(sepa != NULL);
    741
    743
    744 /* get separation data and free it */
    745 sepadata = SCIPsepaGetData(sepa);
    746 assert(sepadata != NULL);
    747 SCIPfreeBlockMemory(scip, &sepadata);
    748
    749 /* reset data pointer to NULL */
    750 SCIPsepaSetData(sepa, NULL);
    751
    752 return SCIP_OKAY;
    753}
    754
    755
    756/** LP solution separation method of separator */
    757static
    758SCIP_DECL_SEPAEXECLP(sepaExeclpMixing)
    759{ /*lint --e{715}*/
    760 SCIP_SEPADATA* sepadata;
    761 SCIP_Bool cutoff;
    762 int nbinvars;
    763 int nvars;
    764 int ncuts;
    765 int ncalls;
    766
    767 assert(sepa != NULL);
    768 assert(scip != NULL);
    769 assert(result != NULL);
    770
    771 *result = SCIP_DIDNOTRUN;
    772 ncalls = SCIPsepaGetNCallsAtNode(sepa);
    773 sepadata = SCIPsepaGetData(sepa);
    774 assert(sepadata != NULL);
    775
    776 /* only call the mixing cut separator a given number of times at each node */
    777 if( (depth == 0 && sepadata->maxroundsroot >= 0 && ncalls >= sepadata->maxroundsroot)
    778 || (depth > 0 && sepadata->maxrounds >= 0 && ncalls >= sepadata->maxrounds) )
    779 return SCIP_OKAY;
    780
    781 /* gets numver of active problem variables and number of binary variables */
    782 SCIP_CALL( SCIPgetVarsData(scip, NULL, &nvars, &nbinvars, NULL, NULL, NULL) );
    783
    784 /* if all the active problem variables are binary, stop */
    785 if( nvars == nbinvars )
    786 return SCIP_OKAY;
    787
    788 /* call the cut separation */
    789 SCIP_CALL( separateCuts(scip, sepa, NULL, &cutoff, &ncuts) );
    790
    791 /* adjust result code */
    792 if( cutoff )
    793 *result = SCIP_CUTOFF;
    794 else if( ncuts > 0 )
    795 {
    796 SCIPdebugMsg(scip, "mixing separator generated %d cuts.\n", ncuts);
    797 *result = SCIP_SEPARATED;
    798 }
    799 else
    800 *result = SCIP_DIDNOTFIND;
    801
    802 return SCIP_OKAY;
    803}
    804
    805/** arbitrary primal solution separation method of separator */
    806static
    807SCIP_DECL_SEPAEXECSOL(sepaExecSolMixing)
    808{ /*lint --e{715}*/
    809 SCIP_SEPADATA* sepadata;
    810 SCIP_Bool cutoff;
    811 int nbinvars;
    812 int nvars;
    813 int ncuts;
    814 int ncalls;
    815
    816 assert(sepa != NULL);
    817 assert(scip != NULL);
    818 assert(result != NULL);
    819
    820 *result = SCIP_DIDNOTRUN;
    821 sepadata = SCIPsepaGetData(sepa);
    822 assert(sepadata != NULL);
    823
    824 /* do not run if we have reached the maximal number of consecutive unsuccessful calls */
    825 if( sepadata->nunsuccessful >= sepadata->maxnunsuccessful )
    826 return SCIP_OKAY;
    827
    828 /* only call the mixing cut separator a given number of times at each node */
    829 ncalls = SCIPsepaGetNCallsAtNode(sepa);
    830 if( (depth == 0 && sepadata->maxroundsroot >= 0 && ncalls >= sepadata->maxroundsroot)
    831 || (depth > 0 && sepadata->maxrounds >= 0 && ncalls >= sepadata->maxrounds) )
    832 return SCIP_OKAY;
    833
    834 /* gets numver of active problem variables and number of binary variables */
    835 nvars = SCIPgetNVars(scip);
    836 nbinvars = SCIPgetNBinVars(scip);
    837
    838 /* if all the active problem variables are binary, stop */
    839 if( nvars == nbinvars )
    840 return SCIP_OKAY;
    841
    842 /* call the cut separation */
    843 SCIP_CALL( separateCuts(scip, sepa, sol, &cutoff, &ncuts) );
    844
    845 /* adjust result code */
    846 if( cutoff )
    847 {
    848 sepadata->nunsuccessful = 0;
    849 *result = SCIP_CUTOFF;
    850 }
    851 else if( ncuts > 0 )
    852 {
    853 SCIPdebugMsg(scip, "mixing separator generated %d cuts.\n", ncuts);
    854 sepadata->nunsuccessful = 0;
    855 *result = SCIP_SEPARATED;
    856 }
    857 else
    858 {
    859 ++sepadata->nunsuccessful;
    860 *result = SCIP_DIDNOTFIND;
    861 }
    862
    863 return SCIP_OKAY;
    864}
    865
    866
    867/*
    868 * separator specific interface methods
    869 */
    870
    871/** creates the mixing separator and includes it in SCIP */
    873 SCIP* scip /**< SCIP data structure */
    874 )
    875{
    876 SCIP_SEPADATA* sepadata;
    877 SCIP_SEPA* sepa;
    878
    879 /* create mixing separator data */
    880 SCIP_CALL( SCIPallocBlockMemory(scip, &sepadata) );
    881 assert(sepadata != NULL);
    882 sepadata->nunsuccessful = 0;
    883
    884 /* include separator */
    887 sepaExeclpMixing, sepaExecSolMixing,
    888 sepadata) );
    889 assert(sepa != NULL);
    890
    891 /* set non-NULL pointers to callback methods */
    892 SCIP_CALL( SCIPsetSepaCopy(scip, sepa, sepaCopyMixing) );
    893 SCIP_CALL( SCIPsetSepaFree(scip, sepa, sepaFreeMixing) );
    894
    895 /* add separator parameters */
    896 SCIP_CALL( SCIPaddBoolParam(scip, "separating/mixing/uselocalbounds",
    897 "Should local bounds be used?",
    898 &sepadata->uselocalbounds, TRUE, DEFAULT_USELOCALBOUNDS, NULL, NULL) );
    899
    900 SCIP_CALL( SCIPaddBoolParam(scip, "separating/mixing/iscutsonints",
    901 "Should general integer variables be used to generate cuts?",
    902 &sepadata->iscutsonints, TRUE, DEFAULT_ISCUTSONINTS, NULL, NULL) );
    903
    904 SCIP_CALL( SCIPaddIntParam(scip, "separating/mixing/maxrounds",
    905 "maximal number of mixing separation rounds per node (-1: unlimited)",
    906 &sepadata->maxrounds, FALSE, DEFAULT_MAXROUNDS, -1, INT_MAX, NULL, NULL) );
    907
    908 SCIP_CALL( SCIPaddIntParam(scip, "separating/mixing/maxroundsroot",
    909 "maximal number of mixing separation rounds in the root node (-1: unlimited)",
    910 &sepadata->maxroundsroot, FALSE, DEFAULT_MAXROUNDSROOT, -1, INT_MAX, NULL, NULL) );
    911
    912 SCIP_CALL( SCIPaddIntParam(scip, "separating/mixing/maxnunsuccessful",
    913 "maximal number of consecutive unsuccessful iterations",
    914 &sepadata->maxnunsuccessful, FALSE, DEFAULT_MAXNUNSUCCESSFUL, -1, INT_MAX, NULL, NULL) );
    915
    916 return SCIP_OKAY;
    917}
    #define NULL
    Definition: def.h:257
    #define SCIP_MAXSTRLEN
    Definition: def.h:278
    #define SCIP_INVALID
    Definition: def.h:187
    #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 SCIP_LONGINT_FORMAT
    Definition: def.h:157
    #define REALABS(x)
    Definition: def.h:191
    #define SCIP_CALL(x)
    Definition: def.h:364
    int SCIPgetNIntVars(SCIP *scip)
    Definition: scip_prob.c:2340
    int SCIPgetNBinImplVars(SCIP *scip)
    Definition: scip_prob.c:2432
    SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
    Definition: scip_prob.c:2115
    int SCIPgetNVars(SCIP *scip)
    Definition: scip_prob.c:2246
    SCIP_VAR ** SCIPgetVars(SCIP *scip)
    Definition: scip_prob.c:2201
    int SCIPgetNIntImplVars(SCIP *scip)
    Definition: scip_prob.c:2477
    int SCIPgetNBinVars(SCIP *scip)
    Definition: scip_prob.c:2293
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:83
    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
    SCIP_RETCODE SCIPaddPoolCut(SCIP *scip, SCIP_ROW *row)
    Definition: scip_cut.c:336
    SCIP_Real SCIPgetCutEfficacy(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *cut)
    Definition: scip_cut.c:94
    SCIP_Bool SCIPisCutEfficacious(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *cut)
    Definition: scip_cut.c:117
    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
    #define SCIPallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:124
    #define SCIPfreeBufferArray(scip, ptr)
    Definition: scip_mem.h:136
    #define SCIPfreeBlockMemory(scip, ptr)
    Definition: scip_mem.h:108
    #define SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    SCIP_RETCODE SCIPcacheRowExtensions(SCIP *scip, SCIP_ROW *row)
    Definition: scip_lp.c:1581
    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_RETCODE SCIPcreateEmptyRowSepa(SCIP *scip, SCIP_ROW **row, SCIP_SEPA *sepa, const char *name, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool removable)
    Definition: scip_lp.c:1429
    void SCIProwChgRank(SCIP_ROW *row, int rank)
    Definition: lp.c:17928
    SCIP_RETCODE SCIPincludeSepaBasic(SCIP *scip, SCIP_SEPA **sepa, const char *name, const char *desc, int priority, int freq, SCIP_Real maxbounddist, SCIP_Bool usessubscip, SCIP_Bool delay, SCIP_DECL_SEPAEXECLP((*sepaexeclp)), SCIP_DECL_SEPAEXECSOL((*sepaexecsol)), SCIP_SEPADATA *sepadata)
    Definition: scip_sepa.c:115
    const char * SCIPsepaGetName(SCIP_SEPA *sepa)
    Definition: sepa.c:746
    int SCIPsepaGetNCallsAtNode(SCIP_SEPA *sepa)
    Definition: sepa.c:893
    SCIP_RETCODE SCIPsetSepaFree(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPAFREE((*sepafree)))
    Definition: scip_sepa.c:173
    SCIP_SEPADATA * SCIPsepaGetData(SCIP_SEPA *sepa)
    Definition: sepa.c:636
    void SCIPsepaSetData(SCIP_SEPA *sepa, SCIP_SEPADATA *sepadata)
    Definition: sepa.c:646
    SCIP_RETCODE SCIPsetSepaCopy(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPACOPY((*sepacopy)))
    Definition: scip_sepa.c:157
    SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
    Definition: scip_sol.c:1763
    SCIP_Longint SCIPgetNLPs(SCIP *scip)
    SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    int SCIPvarGetNVlbs(SCIP_VAR *var)
    Definition: var.c:24514
    SCIP_Real * SCIPvarGetVlbCoefs(SCIP_VAR *var)
    Definition: var.c:24536
    SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
    Definition: var.c:23510
    SCIP_Bool SCIPvarIsImpliedIntegral(SCIP_VAR *var)
    Definition: var.c:23530
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24300
    SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
    Definition: var.c:23485
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24174
    int SCIPvarGetProbindex(SCIP_VAR *var)
    Definition: var.c:23694
    SCIP_Real * SCIPvarGetVlbConstants(SCIP_VAR *var)
    Definition: var.c:24546
    int SCIPvarGetNVubs(SCIP_VAR *var)
    Definition: var.c:24556
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24266
    SCIP_VAR ** SCIPvarGetVlbVars(SCIP_VAR *var)
    Definition: var.c:24526
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24152
    SCIP_Real * SCIPvarGetVubConstants(SCIP_VAR *var)
    Definition: var.c:24588
    SCIP_VAR ** SCIPvarGetVubVars(SCIP_VAR *var)
    Definition: var.c:24568
    SCIP_Real * SCIPvarGetVubCoefs(SCIP_VAR *var)
    Definition: var.c:24578
    SCIP_RETCODE SCIPincludeSepaMixing(SCIP *scip)
    Definition: sepa_mixing.c:872
    void SCIPsortDownRealRealIntInt(SCIP_Real *realarray1, SCIP_Real *realarray2, int *intarray1, int *intarray2, int len)
    int SCIPsnprintf(char *t, int len, const char *s,...)
    Definition: misc.c:10827
    memory allocation routines
    public methods for implications, variable bounds, and cliques
    public methods for LP management
    public methods for message output
    public data structures and miscellaneous methods
    public methods for separators
    public methods for problem variables
    public methods for branching rule plugins and branching
    public methods for cuts and aggregation rows
    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 separator plugins
    public methods for solutions
    public methods for querying solving statistics
    public methods for the branch-and-bound tree
    public methods for SCIP variables
    #define SEPA_PRIORITY
    Definition: sepa_mixing.c:102
    #define SEPA_DELAY
    Definition: sepa_mixing.c:106
    static SCIP_RETCODE addCut(SCIP *scip, SCIP_SEPA *sepa, SCIP_SOL *sol, SCIP_Real *cutcoefs, int *cutinds, int cutnnz, SCIP_Real cutrhs, SCIP_Bool cutislocal, SCIP_Bool *cutoff, int *ncuts)
    Definition: sepa_mixing.c:129
    #define SEPA_DESC
    Definition: sepa_mixing.c:99
    static SCIP_DECL_SEPAEXECSOL(sepaExecSolMixing)
    Definition: sepa_mixing.c:807
    #define DEFAULT_MAXNUNSUCCESSFUL
    Definition: sepa_mixing.c:110
    #define DEFAULT_MAXROUNDSROOT
    Definition: sepa_mixing.c:101
    #define SEPA_USESSUBSCIP
    Definition: sepa_mixing.c:105
    static SCIP_RETCODE separateCuts(SCIP *scip, SCIP_SEPA *sepa, SCIP_SOL *sol, SCIP_Bool *cutoff, int *ncuts)
    Definition: sepa_mixing.c:220
    static SCIP_DECL_SEPACOPY(sepaCopyMixing)
    Definition: sepa_mixing.c:720
    #define DEFAULT_USELOCALBOUNDS
    Definition: sepa_mixing.c:108
    static SCIP_DECL_SEPAEXECLP(sepaExeclpMixing)
    Definition: sepa_mixing.c:758
    #define SEPA_MAXBOUNDDIST
    Definition: sepa_mixing.c:104
    #define SEPA_FREQ
    Definition: sepa_mixing.c:103
    #define SEPA_NAME
    Definition: sepa_mixing.c:98
    #define DEFAULT_ISCUTSONINTS
    Definition: sepa_mixing.c:109
    #define DEFAULT_MAXROUNDS
    Definition: sepa_mixing.c:100
    static SCIP_DECL_SEPAFREE(sepaFreeMixing)
    Definition: sepa_mixing.c:735
    mixing cuts separator
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_CUTOFF
    Definition: type_result.h:48
    @ SCIP_DIDNOTFIND
    Definition: type_result.h:44
    @ SCIP_SEPARATED
    Definition: type_result.h:49
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_INVALIDCALL
    Definition: type_retcode.h:51
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    struct SCIP_SepaData SCIP_SEPADATA
    Definition: type_sepa.h:52
    @ SCIP_VARTYPE_BINARY
    Definition: type_var.h:64