SCIP

    Solving Constraint Integer Programs

    prop_probing.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 prop_probing.c
    26 * @ingroup DEFPLUGINS_PROP
    27 * @brief probing propagator
    28 * @author Tobias Achterberg
    29 * @author Matthias Miltenberger
    30 * @author Michael Winkler
    31 */
    32
    33/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    34
    36#include "scip/prop_probing.h"
    37#include "scip/pub_message.h"
    38#include "scip/pub_misc.h"
    39#include "scip/pub_misc_sort.h"
    40#include "scip/pub_prop.h"
    41#include "scip/pub_tree.h"
    42#include "scip/pub_var.h"
    43#include "scip/scip_branch.h"
    44#include "scip/scip_general.h"
    45#include "scip/scip_lp.h"
    46#include "scip/scip_mem.h"
    47#include "scip/scip_message.h"
    48#include "scip/scip_numerics.h"
    49#include "scip/scip_param.h"
    50#include "scip/scip_prob.h"
    51#include "scip/scip_probing.h"
    52#include "scip/scip_prop.h"
    55#include "scip/scip_timing.h"
    56#include "scip/scip_tree.h"
    57#include "scip/scip_var.h"
    58
    59
    60#define PROP_NAME "probing"
    61#define PROP_DESC "probing propagator on binary variables"
    62#define PROP_TIMING SCIP_PROPTIMING_AFTERLPLOOP
    63#define PROP_PRIORITY -100000 /**< propagation priority */
    64#define PROP_FREQ -1 /**< propagation frequency */
    65#define PROP_DELAY TRUE /**< should propagation method be delayed, if other propagators found
    66 * reductions? */
    67#define PROP_PRESOL_PRIORITY -100000 /**< priority of the presolving method (>= 0: before, < 0: after constraint handlers); combined with presolvers */
    68#define PROP_PRESOLTIMING SCIP_PRESOLTIMING_EXHAUSTIVE /* timing of the presolving method (fast, medium, or exhaustive) */
    69#define PROP_PRESOL_MAXROUNDS -1 /**< maximal number of presolving rounds the presolver participates in (-1: no
    70 * limit) */
    71#define MAXDNOM 10000LL /**< maximal denominator for simple rational fixed values */
    72
    73
    74/* @todo check for restricting the maximal number of implications that can be added by probing */
    75
    76/* sorting of probing variables, two different variants are implemeneted */
    77/* #define VARIANT_B */
    78
    79
    80/*
    81 * Default parameter settings
    82 */
    83
    84#define DEFAULT_MAXRUNS 1 /**< maximal number of runs, probing participates in (-1: no limit) */
    85#define DEFAULT_PROPROUNDS -1 /**< maximal number of propagation rounds in probing subproblems */
    86#define DEFAULT_MAXFIXINGS 25 /**< maximal number of fixings found, until probing is interrupted
    87 * (0: don't interrupt) */
    88#define DEFAULT_MAXUSELESS 1000 /**< maximal number of successive probings without fixings,
    89 * until probing is aborted (0: don't abort) */
    90#define DEFAULT_MAXTOTALUSELESS 50 /**< maximal number of successive probings without fixings, bound changes,
    91 * and implications, until probing is aborted (0: don't abort) */
    92#define DEFAULT_MAXSUMUSELESS 0 /**< maximal number of probings without fixings, until probing is aborted
    93 * (0: don't abort) */
    94#define DEFAULT_MAXDEPTH -1 /**< maximal depth until propagation is executed(-1: no limit) */
    95#define DEFAULT_RANDSEED 59 /**< random initial seed */
    96
    97/*
    98 * Data structures
    99 */
    100
    101/** propagator data */
    102struct SCIP_PropData
    103{
    104 SCIP_VAR** sortedvars; /**< problem variables sorted by number of rounding locks, used in presolving */
    105 int* nprobed; /**< array of numbers how often we already probed on each variables */
    106 int noldtotalvars; /**< number of total variables in problem */
    107 int nsortedvars; /**< number of problem variables, used in presolving */
    108 int nsortedbinvars; /**< number of binary problem variables, used in presolving */
    109 int maxruns; /**< maximal number of runs, probing participates in (-1: no limit) */
    110 int proprounds; /**< maximal number of propagation rounds in probing subproblems */
    111 int maxfixings; /**< maximal number of fixings found, until probing is interrupted
    112 * (0: don't interrupt) */
    113 int maxuseless; /**< maximal number of successive probings without fixings,
    114 * until probing is aborted (0: don't abort) */
    115 int maxtotaluseless; /**< maximal number of successive probings without fixings, bound changes,
    116 * and implications, until probing is aborted (0: don't abort) */
    117 int maxsumuseless; /**< maximal number of probings without fixings, until probing is aborted
    118 * (0: don't abort) */
    119 int startidx; /**< starting variable index of next call, used in presolving */
    120 int lastsortstartidx; /**< last starting variable index where the variables have been sorted, used in presolving */
    121 int nfixings; /**< total number of fixings found in probing */
    122 int naggregations; /**< total number of aggregations found in probing */
    123 int nimplications; /**< total number of implications found in probing */
    124 int nbdchgs; /**< total number of bound changes found in probing */
    125 int nuseless; /**< current number of successive useless probings */
    126 int ntotaluseless; /**< current number of successive totally useless probings */
    127 int nsumuseless; /**< current number of useless probings */
    128 int maxdepth; /**< maximal depth until propagation is executed */
    129 SCIP_Longint lastnode; /**< last node where probing was applied, or -1 for presolving, and -2 for not applied yet */
    130 SCIP_RANDNUMGEN* randnumgen; /**< random number generator */
    131};
    132
    133
    134/*
    135 * Local methods
    136 */
    137/** initializes the propagator data */
    138static
    140 SCIP_PROPDATA* propdata /**< propagator data */
    141 )
    142{
    143 assert(propdata != NULL);
    144
    145 propdata->sortedvars = NULL;
    146 propdata->nprobed = NULL;
    147 propdata->noldtotalvars = 0;
    148 propdata->nsortedvars = 0;
    149 propdata->nsortedbinvars = 0;
    150 propdata->startidx = 0;
    151 propdata->lastsortstartidx = -1;
    152 propdata->nfixings = 0;
    153 propdata->naggregations = 0;
    154 propdata->nimplications = 0;
    155 propdata->nbdchgs = 0;
    156 propdata->nuseless = 0;
    157 propdata->ntotaluseless = 0;
    158 propdata->nsumuseless = 0;
    159 propdata->lastnode = -2;
    160 propdata->randnumgen = NULL;
    161
    162 return SCIP_OKAY;
    163}
    164
    165/** frees the sorted vars array */
    166static
    168 SCIP* scip, /**< SCIP data structure */
    169 SCIP_PROPDATA* propdata /**< propagator data */
    170 )
    171{
    172 assert(propdata != NULL);
    173
    174 if( propdata->sortedvars != NULL )
    175 {
    176 int i;
    177
    178 /* release variables */
    179 for( i = 0; i < propdata->nsortedvars; ++i )
    180 {
    181 SCIP_CALL( SCIPreleaseVar(scip, &propdata->sortedvars[i]) );
    182 }
    183 SCIPfreeMemoryArray(scip, &propdata->sortedvars);
    184 propdata->nsortedvars = 0;
    185 propdata->nsortedbinvars = 0;
    186 }
    187
    188 SCIPfreeMemoryArrayNull(scip, &propdata->nprobed);
    189 propdata->noldtotalvars = 0;
    190
    191 return SCIP_OKAY;
    192}
    193
    194/** sorts the binary variables starting with the given index by rounding locks and implications */
    195static
    197 SCIP* scip, /**< SCIP data structure */
    198 SCIP_PROPDATA* propdata, /**< propagator data */
    199 SCIP_VAR** vars, /**< problem variables to be sorted */
    200 int nvars, /**< number of problem variables to be sorted */
    201 int firstidx /**< first index that should be subject to sorting */
    202 )
    203{
    204 SCIP_VAR** sortedvars;
    205 int nsortedvars;
    206 SCIP_Real* scores;
    207 int i;
    208 int minnprobings;
    209 SCIP_Real maxscore;
    210 int nlocksdown;
    211 int nlocksup;
    212 int nimplzero;
    213 int nimplone;
    214 int nclqzero;
    215 int nclqone;
    216
    217 assert(propdata != NULL);
    218 assert(propdata->nprobed != NULL);
    219
    220 assert(vars != NULL || nvars == 0);
    221
    222 nsortedvars = nvars - firstidx;
    223 if( nsortedvars <= 0 )
    224 return SCIP_OKAY;
    225
    226 assert(vars != NULL);
    227
    228 sortedvars = &(vars[firstidx]);
    229
    230 SCIPdebugMsg(scip, "resorting probing variables %d to %d\n", firstidx, nvars-1);
    231
    232 /* sort the variables by number of rounding locks and implications */
    233 SCIP_CALL( SCIPallocBufferArray(scip, &scores, nsortedvars) );
    234
    235 maxscore = -1.0;
    236 minnprobings = INT_MAX;
    237
    238 /* determine maximal possible score and minimal number of probings over all variables */
    239 for( i = 0; i < nvars; ++i )
    240 {
    241 SCIP_VAR* var;
    242 SCIP_Real tmp;
    243
    244 var = vars[i];
    245
    246 assert(SCIPvarIsBinary(var));
    247 assert(propdata->noldtotalvars > SCIPvarGetIndex(var));
    248 assert(propdata->nprobed[SCIPvarGetIndex(var)] >= 0);
    249
    250 if( SCIPvarIsActive(var) )
    251 {
    254 nimplzero = SCIPvarGetNImpls(var, FALSE);
    255 nimplone = SCIPvarGetNImpls(var, TRUE);
    256 nclqzero = SCIPvarGetNCliques(var, FALSE);
    257 nclqone = SCIPvarGetNCliques(var, TRUE);
    258
    259#ifndef VARIANT_B
    260 tmp = -MAX(nlocksdown, nlocksup)
    261 + 10.0 * MIN(nimplzero, nimplone)
    262 + 100.0 * MIN(nclqzero, nclqone);
    263#else
    264 tmp = - ABS(nlocksdown - nlocksup)
    265 + MIN(nlocksdown, nlocksup)
    266 + 500.0 * nimplzero + 50.0 * nimplone
    267 + 50000.0 * nclqzero + 5000.0 * nclqone;
    268#endif
    269
    270 if( tmp > maxscore )
    271 maxscore = tmp;
    272 if( propdata->nprobed[SCIPvarGetIndex(var)] < minnprobings )
    273 minnprobings = propdata->nprobed[SCIPvarGetIndex(var)];
    274 }
    275 }
    276
    277 /* correct number of probings on each variable by minimal number of probings */
    278 if( minnprobings > 0 )
    279 {
    280 for( i = 0; i < nvars; ++i )
    281 {
    282 SCIP_VAR* var;
    283
    284 var = vars[i];
    285
    286 if( SCIPvarIsActive(var) )
    287 propdata->nprobed[SCIPvarGetIndex(var)] -= minnprobings;
    288 }
    289 }
    290
    291 for( i = 0; i < nsortedvars; ++i )
    292 {
    293 SCIP_VAR* var;
    294 var = sortedvars[i];
    295
    296 assert(SCIPvarIsBinary(var));
    297
    298 /* prefer variables that we did not already probe on */
    299 if( SCIPvarIsActive(var) )
    300 {
    301 SCIP_Real randomoffset;
    304 nimplzero = SCIPvarGetNImpls(var, FALSE);
    305 nimplone = SCIPvarGetNImpls(var, TRUE);
    306 nclqzero = SCIPvarGetNCliques(var, FALSE);
    307 nclqone = SCIPvarGetNCliques(var, TRUE);
    308
    309 assert(propdata->noldtotalvars > SCIPvarGetIndex(var));
    310 assert(propdata->nprobed[SCIPvarGetIndex(var)] >= 0);
    311
    312 /* use a random offset to break possible ties arbitrarily */
    313 randomoffset = SCIPrandomGetReal(propdata->randnumgen, 0.0, 0.5);
    314
    315#ifndef VARIANT_B
    316 scores[i] = -maxscore * propdata->nprobed[SCIPvarGetIndex(var)]
    317 - MAX(nlocksdown, nlocksup)
    318 + 10.0 * MIN(nimplzero, nimplone)
    319 + 100.0 * MIN(nclqzero, nclqone) /*lint !e790*/
    320 - randomoffset; /* to break ties randomly */
    321#else
    322 scores[i] = -maxscore * propdata->nprobed[SCIPvarGetIndex(var)]
    323 - ABS(nlocksdown - nlocksup)
    324 + MIN(nlocksdown, nlocksup)
    325 + 500.0 * nimplzero + 50.0 * nimplone /*lint !e790*/
    326 + 50000.0 * nclqzero + 5000.0 * nclqone /*lint !e790*/
    327 - randomoffset; /* to break ties randomly */
    328#endif
    329 }
    330 else
    331 scores[i] = -SCIPinfinity(scip);
    332 }
    333
    334 SCIPsortDownRealPtr(scores, (void**) sortedvars, nsortedvars);
    335
    336 SCIPfreeBufferArray(scip, &scores);
    337
    338 return SCIP_OKAY;
    339}
    340
    341/** the main probing loop */
    342static
    344 SCIP* scip, /**< SCIP data structure */
    345 SCIP_PROPDATA* propdata, /**< propagator data */
    346 SCIP_VAR** vars, /**< problem variables */
    347 int nvars, /**< number of problem variables */
    348 int nbinvars, /**< number of binary variables */
    349 int* startidx, /**< pointer to store starting variable index of next call */
    350 int* nfixedvars, /**< pointer to store number of fixed variables */
    351 int* naggrvars, /**< pointer to store number of aggregated variables */
    352 int* nchgbds, /**< pointer to store number of changed bounds */
    353 int oldnfixedvars, /**< number of previously fixed variables */
    354 int oldnaggrvars, /**< number of previously aggregated variables */
    355 SCIP_Bool* delay, /**< pointer to store whether propagator should be delayed */
    356 SCIP_Bool* cutoff /**< pointer to store whether cutoff occurred */
    357 )
    358{
    359 SCIP_Real* zeroimpllbs;
    360 SCIP_Real* zeroimplubs;
    361 SCIP_Real* zeroproplbs;
    362 SCIP_Real* zeropropubs;
    363 SCIP_Real* oneimpllbs;
    364 SCIP_Real* oneimplubs;
    365 SCIP_Real* oneproplbs;
    366 SCIP_Real* onepropubs;
    367 int localnfixedvars;
    368 int localnaggrvars;
    369 int localnchgbds;
    370 int localnimplications;
    371 int maxfixings;
    372 int maxuseless;
    373 int maxtotaluseless;
    374 int maxsumuseless;
    375 int i;
    376 int oldstartidx;
    377 SCIP_Bool aborted;
    378 SCIP_Bool looped;
    379
    380 assert(vars != NULL);
    381 assert(nbinvars > 0);
    382
    383 maxfixings = (propdata->maxfixings > 0 ? propdata->maxfixings : INT_MAX);
    384 maxuseless = (propdata->maxuseless > 0 ? propdata->maxuseless : INT_MAX);
    385 maxtotaluseless = (propdata->maxtotaluseless > 0 ? propdata->maxtotaluseless : INT_MAX);
    386 maxsumuseless = (propdata->maxsumuseless > 0 ? propdata->maxsumuseless : INT_MAX);
    387 aborted = FALSE;
    388 looped = FALSE;
    389 oldstartidx = *startidx;
    390 i = *startidx;
    391
    392 /* get temporary memory for storing probing results */
    393 SCIP_CALL( SCIPallocBufferArray(scip, &zeroimpllbs, nvars) );
    394 SCIP_CALL( SCIPallocBufferArray(scip, &zeroimplubs, nvars) );
    395 SCIP_CALL( SCIPallocBufferArray(scip, &zeroproplbs, nvars) );
    396 SCIP_CALL( SCIPallocBufferArray(scip, &zeropropubs, nvars) );
    397 SCIP_CALL( SCIPallocBufferArray(scip, &oneimpllbs, nvars) );
    398 SCIP_CALL( SCIPallocBufferArray(scip, &oneimplubs, nvars) );
    399 SCIP_CALL( SCIPallocBufferArray(scip, &oneproplbs, nvars) );
    400 SCIP_CALL( SCIPallocBufferArray(scip, &onepropubs, nvars) );
    401
    402 /* for each binary variable, probe fixing the variable to zero and one */
    403 *delay = FALSE;
    404 *cutoff = FALSE;
    405 do
    406 {
    407 for( ; i < nbinvars && !(*cutoff); ++i )
    408 {
    409 SCIP_Bool localcutoff;
    410 SCIP_Bool probingzero;
    411 SCIP_Bool probingone;
    412
    413 /* check whether probing should be aborted */
    414 if( propdata->nuseless >= maxuseless || propdata->ntotaluseless >= maxtotaluseless || propdata->nsumuseless >= maxsumuseless || SCIPisStopped(scip) )
    415 {
    417 " (%.1fs) probing: %d/%d (%.1f%%) - %d fixings, %d aggregations, %d implications, %d bound changes\n",
    418 SCIPgetSolvingTime(scip), i+1, nbinvars, 100.0*(SCIP_Real)(i+1)/(SCIP_Real)nbinvars,
    419 propdata->nfixings, propdata->naggregations, propdata->nimplications, propdata->nbdchgs);
    420
    421 aborted = TRUE;
    422
    423 if( propdata->nuseless >= maxuseless )
    424 {
    426 " (%.1fs) probing aborted: %d/%d successive useless probings\n", SCIPgetSolvingTime(scip),
    427 propdata->nuseless, maxuseless);
    428 }
    429 else if( propdata->ntotaluseless >= maxtotaluseless )
    430 {
    432 " (%.1fs) probing aborted: %d/%d successive totally useless probings\n", SCIPgetSolvingTime(scip),
    433 propdata->ntotaluseless, maxtotaluseless);
    434 }
    435 else if( propdata->nsumuseless >= maxsumuseless )
    436 {
    438 " (%.1fs) probing aborted: %d/%d useless probings in total\n", SCIPgetSolvingTime(scip),
    439 propdata->nsumuseless, maxsumuseless);
    440 }
    441 else
    442 {
    443 assert(SCIPisStopped(scip));
    445 " (%.1fs) probing aborted: solving stopped\n", SCIPgetSolvingTime(scip));
    446 }
    447 break;
    448 }
    449
    450 /* check if we already fixed enough variables for this round, or probed on all variables */
    451 if( *nfixedvars - oldnfixedvars + *naggrvars - oldnaggrvars >= maxfixings || (looped && oldstartidx == i) )
    452 {
    453 if( *nfixedvars - oldnfixedvars + *naggrvars - oldnaggrvars > 0 )
    454 *delay = TRUE;
    455 else
    456 aborted = TRUE;
    457 break;
    458 }
    459
    460 /* display probing status */
    461 if( SCIPgetStage(scip) == SCIP_STAGE_PRESOLVING && (i+1) % 100 == 0 )
    462 {
    463 SCIP_VERBLEVEL verblevel;
    464
    465 verblevel = ((i+1) % 1000 == 0 ? SCIP_VERBLEVEL_HIGH : SCIP_VERBLEVEL_FULL);
    466 SCIPverbMessage(scip, verblevel, NULL,
    467 " (%.1fs) probing: %d/%d (%.1f%%) - %d fixings, %d aggregations, %d implications, %d bound changes\n",
    468 SCIPgetSolvingTime(scip), i+1, nbinvars, 100.0*(SCIP_Real)(i+1)/(SCIP_Real)nbinvars,
    469 propdata->nfixings, propdata->naggregations, propdata->nimplications, propdata->nbdchgs);
    470 }
    471
    472 /* ignore variables, that were fixed, aggregated, or deleted in prior probings */
    473 if( !SCIPvarIsActive(vars[i]) || SCIPvarIsDeleted(vars[i])
    474 || SCIPvarGetLbLocal(vars[i]) > 0.5 || SCIPvarGetUbLocal(vars[i]) < 0.5 )
    475 continue;
    476
    477 if( propdata->nuseless > 0 )
    478 propdata->nsumuseless++;
    479 else
    480 propdata->nsumuseless = MAX(propdata->nsumuseless-1, 0);
    481 propdata->nuseless++;
    482 propdata->ntotaluseless++;
    483
    484 /* determine whether one probing should happen */
    485 probingone = TRUE;
    487 probingone = FALSE;
    488
    489 if( probingone )
    490 {
    491 /* apply probing for fixing the variable to one */
    492 SCIP_CALL( SCIPapplyProbingVar(scip, vars, nvars, i, SCIP_BOUNDTYPE_LOWER, 1.0, propdata->proprounds,
    493 oneimpllbs, oneimplubs, oneproplbs, onepropubs, &localcutoff) );
    494
    495 if( localcutoff )
    496 {
    497 SCIP_Bool fixed;
    498
    500 {
    501 /* the variable can be fixed to FALSE */
    502 SCIP_CALL( SCIPfixVar(scip, vars[i], 0.0, cutoff, &fixed) );
    503 assert(fixed);
    504 }
    505 else
    506 {
    507 SCIP_CALL( SCIPtightenVarUb(scip, vars[i], 0.0, TRUE, cutoff, &fixed) );
    508 }
    509
    510 if( fixed )
    511 {
    512 SCIPdebugMsg(scip, "fixed probing variable <%s> to 0.0, nlocks=(%d/%d)\n",
    515 (*nfixedvars)++;
    516 propdata->nfixings++;
    517 propdata->nuseless = 0;
    518 propdata->ntotaluseless = 0;
    519 }
    520 else if( *cutoff )
    521 {
    522 SCIPdebugMsg(scip, "tightening upper bound of probing variable <%s> to 0.0 led to a cutoff\n",
    523 SCIPvarGetName(vars[i]));
    524 }
    525 continue; /* don't try downwards direction, because the variable is already fixed */
    526 }
    527
    528 /* ignore variables, that were fixed, aggregated, or deleted in prior probings
    529 * (propagators in one-probe might have found global fixings but did not trigger the localcutoff)
    530 */
    531 if( !SCIPvarIsActive(vars[i]) || SCIPvarIsDeleted(vars[i])
    532 || SCIPvarGetLbLocal(vars[i]) > 0.5 || SCIPvarGetUbLocal(vars[i]) < 0.5 )
    533 continue;
    534 }
    535
    536 /* determine whether zero probing should happen */
    537 probingzero = TRUE;
    539 probingzero = FALSE;
    540
    541 if( probingzero )
    542 {
    543 /* apply probing for fixing the variable to zero */
    544 SCIP_CALL( SCIPapplyProbingVar(scip, vars, nvars, i, SCIP_BOUNDTYPE_UPPER, 0.0, propdata->proprounds,
    545 zeroimpllbs, zeroimplubs, zeroproplbs, zeropropubs, &localcutoff) );
    546
    547 if( localcutoff )
    548 {
    549 SCIP_Bool fixed;
    550
    552 {
    553 /* the variable can be fixed to TRUE */
    554 SCIP_CALL( SCIPfixVar(scip, vars[i], 1.0, cutoff, &fixed) );
    555 }
    556 else
    557 {
    558 SCIP_CALL( SCIPtightenVarLb(scip, vars[i], 1.0, TRUE, cutoff, &fixed) );
    559 }
    560
    561 if( fixed )
    562 {
    563 SCIPdebugMsg(scip, "fixed probing variable <%s> to 1.0, nlocks=(%d/%d)\n",
    566 (*nfixedvars)++;
    567 propdata->nfixings++;
    568 propdata->nuseless = 0;
    569 propdata->ntotaluseless = 0;
    570 }
    571 else if( *cutoff )
    572 {
    573 SCIPdebugMsg(scip, "tightening lower bound of probing variable <%s> to 1.0 led to a cutoff\n",
    574 SCIPvarGetName(vars[i]));
    575 }
    576 continue; /* don't analyze probing deductions, because the variable is already fixed */
    577 }
    578 }
    579
    580 /* not have to check deductions if only one probing direction has been checked */
    581 if( !probingzero || !probingone )
    582 continue;
    583
    584 assert(propdata->noldtotalvars > SCIPvarGetIndex(vars[i]));
    585
    586 /* count number of probings on each variable */
    587 propdata->nprobed[SCIPvarGetIndex(vars[i])] += 1;
    588
    589 /* analyze probing deductions */
    590 localnfixedvars = 0;
    591 localnaggrvars = 0;
    592 localnimplications = 0;
    593 localnchgbds = 0;
    594 SCIP_CALL( SCIPanalyzeDeductionsProbing(scip, vars[i], 0.0, 1.0,
    595 nvars, vars, zeroimpllbs, zeroimplubs, zeroproplbs, zeropropubs, oneimpllbs, oneimplubs, oneproplbs, onepropubs,
    596 &localnfixedvars, &localnaggrvars, &localnimplications, &localnchgbds, cutoff) );
    597
    598 *nfixedvars += localnfixedvars;
    599 *naggrvars += localnaggrvars;
    600 *nchgbds += localnchgbds;
    601 propdata->nfixings += localnfixedvars;
    602 propdata->naggregations += localnaggrvars;
    603 propdata->nbdchgs += localnchgbds;
    604 propdata->nimplications += localnimplications;
    605
    606 if( localnfixedvars > 0 || localnaggrvars > 0 )
    607 {
    608 SCIPdebugMsg(scip, "probing on <%s> led to %d fixed and %d aggregated variables\n", SCIPvarGetName(vars[i]),
    609 localnfixedvars, localnaggrvars);
    610 propdata->nuseless = 0;
    611 propdata->ntotaluseless = 0;
    612 }
    613 if( localnimplications > 0 || localnchgbds > 0 )
    614 propdata->ntotaluseless = 0;
    615 }
    616
    617 looped = TRUE;
    618
    619 /* check if we reached the end of all binary variables but did not stop, so we start from the beginning */
    620 if( i == nbinvars && !(*cutoff) && !(*delay) && !aborted )
    621 {
    623 " (%.1fs) probing cycle finished: starting next cycle\n", SCIPgetSolvingTime(scip));
    624 i = 0;
    625
    627 {
    628 SCIP_VAR** newvars;
    629 int nnewvars;
    630 int nnewbinvars;
    631 int nnewintvars;
    632 int nnewimplvars;
    633 int lastidx;
    634 int v;
    635
    636 assert(vars == propdata->sortedvars);
    637 assert(nbinvars == propdata->nsortedbinvars);
    638
    639 /* release old variables and free memory */
    640 for( v = propdata->nsortedvars - 1; v >= 0; --v )
    641 {
    642 SCIP_CALL( SCIPreleaseVar(scip, &propdata->sortedvars[v]) );
    643 }
    644 SCIPfreeMemoryArray(scip, &propdata->sortedvars);
    645 propdata->nsortedvars = 0;
    646 propdata->nsortedbinvars = 0;
    647
    648 /* get new variables */
    649 nnewvars = SCIPgetNVars(scip);
    650 newvars = SCIPgetVars(scip);
    651 SCIP_CALL( SCIPduplicateMemoryArray(scip, &(propdata->sortedvars), newvars, nnewvars) ); /*lint !e666*/
    652 propdata->nsortedvars = nnewvars;
    653
    654 nnewbinvars = SCIPgetNBinVars(scip);
    655 nnewintvars = SCIPgetNIntVars(scip);
    656 nnewimplvars = SCIPgetNImplVars(scip);
    657
    658 /* determine implicit binary variables */
    659 lastidx = nnewbinvars + nnewintvars + nnewimplvars;
    660 for( v = nnewbinvars; v < lastidx; ++v )
    661 {
    662 if( SCIPvarIsBinary(propdata->sortedvars[v]) )
    663 {
    664 SCIPswapPointers((void**) &(propdata->sortedvars[nnewbinvars]), (void**) &(propdata->sortedvars[v]));
    665 ++nnewbinvars;
    666 }
    667 }
    668 propdata->nsortedbinvars = nnewbinvars;
    669
    670 nbinvars = nnewbinvars;
    671 vars = propdata->sortedvars;
    672 nvars = propdata->nsortedvars;
    673
    674 SCIP_CALL( SCIPreallocBufferArray(scip, &zeroimpllbs, nvars) );
    675 SCIP_CALL( SCIPreallocBufferArray(scip, &zeroimplubs, nvars) );
    676 SCIP_CALL( SCIPreallocBufferArray(scip, &zeroproplbs, nvars) );
    677 SCIP_CALL( SCIPreallocBufferArray(scip, &zeropropubs, nvars) );
    678 SCIP_CALL( SCIPreallocBufferArray(scip, &oneimpllbs, nvars) );
    679 SCIP_CALL( SCIPreallocBufferArray(scip, &oneimplubs, nvars) );
    680 SCIP_CALL( SCIPreallocBufferArray(scip, &oneproplbs, nvars) );
    681 SCIP_CALL( SCIPreallocBufferArray(scip, &onepropubs, nvars) );
    682
    683 /* correct oldstartidx which is used for early termination */
    684 if( oldstartidx >= nbinvars )
    685 oldstartidx = nbinvars - 1;
    686
    687 /* capture variables to make sure, the variables are not deleted */
    688 for( v = propdata->nsortedvars - 1; v >= 0; --v )
    689 {
    690 SCIP_CALL( SCIPcaptureVar(scip, propdata->sortedvars[v]) );
    691 }
    692
    693 if( nnewbinvars == 0 )
    694 {
    695 *startidx = 0;
    696 propdata->lastsortstartidx = -1;
    697 propdata->nuseless = 0;
    698 propdata->ntotaluseless = 0;
    699
    700 goto TERMINATE;
    701 }
    702
    703 /* resorting here might lead to probing a second time on the same variable */
    704 SCIP_CALL( sortVariables(scip, propdata, propdata->sortedvars, propdata->nsortedbinvars, 0) );
    705 propdata->lastsortstartidx = 0;
    706 }
    707 }
    708 }
    709 while( i == 0 && !(*cutoff) && !(*delay) && !aborted );
    710
    711 *startidx = i;
    712
    713 TERMINATE:
    714 /* free temporary memory */
    715 SCIPfreeBufferArray(scip, &onepropubs);
    716 SCIPfreeBufferArray(scip, &oneproplbs);
    717 SCIPfreeBufferArray(scip, &oneimplubs);
    718 SCIPfreeBufferArray(scip, &oneimpllbs);
    719 SCIPfreeBufferArray(scip, &zeropropubs);
    720 SCIPfreeBufferArray(scip, &zeroproplbs);
    721 SCIPfreeBufferArray(scip, &zeroimplubs);
    722 SCIPfreeBufferArray(scip, &zeroimpllbs);
    723
    724 return SCIP_OKAY;
    725}
    726
    727
    728/*
    729 * Callback methods of propagator
    730 */
    731
    732/** copy method for constraint handler plugins (called when SCIP copies plugins) */
    733static
    734SCIP_DECL_PROPCOPY(propCopyProbing)
    735{ /*lint --e{715}*/
    736 assert(scip != NULL);
    737 assert(prop != NULL);
    738
    740
    741 /* call inclusion method for propagator */
    743
    744 return SCIP_OKAY;
    745}
    746
    747
    748/** destructor of propagator to free user data (called when SCIP is exiting) */
    749static
    750SCIP_DECL_PROPFREE(propFreeProbing)
    751{ /*lint --e{715}*/
    752 SCIP_PROPDATA* propdata;
    753
    754 /* free propagator data */
    755 propdata = SCIPpropGetData(prop);
    756 assert(propdata != NULL);
    757 assert(propdata->sortedvars == NULL);
    758 assert(propdata->nsortedvars == 0);
    759 assert(propdata->nsortedbinvars == 0);
    760
    761 SCIPfreeBlockMemory(scip, &propdata);
    762 SCIPpropSetData(prop, NULL);
    763
    764 return SCIP_OKAY;
    765}
    766
    767
    768/** initialization method of propagator (called after problem was transformed) */
    769static
    770SCIP_DECL_PROPINIT(propInitProbing)
    771{ /*lint --e{715}*/
    772 SCIP_PROPDATA* propdata;
    773
    774 propdata = SCIPpropGetData(prop);
    775 assert(propdata != NULL);
    776
    777 SCIP_CALL( initPropdata(propdata) );
    778
    779 /* create random number generator */
    780 SCIP_CALL( SCIPcreateRandom(scip, &propdata->randnumgen,
    782
    783 return SCIP_OKAY;
    784}
    785
    786
    787/** deinitialization method of propagator (called before transformed problem is freed) */
    788static
    789SCIP_DECL_PROPEXIT(propExitProbing)
    790{ /*lint --e{715}*/
    791 SCIP_PROPDATA* propdata;
    792
    793 propdata = SCIPpropGetData(prop);
    794 assert(propdata != NULL);
    795
    796 SCIP_CALL( freeSortedvars(scip, propdata) );
    797 assert(propdata->sortedvars == NULL);
    798 assert(propdata->nsortedvars == 0);
    799 assert(propdata->nsortedbinvars == 0);
    800
    801 /* free random number generator */
    802 SCIPfreeRandom(scip, &propdata->randnumgen);
    803
    804 return SCIP_OKAY;
    805}
    806
    807/** presolving initialization method of propagator (called when presolving is about to begin) */
    808static
    809SCIP_DECL_PROPINITPRE(propInitpreProbing)
    810{ /*lint --e{715}*/
    811 SCIP_PROPDATA* propdata;
    812
    813 propdata = SCIPpropGetData(prop);
    814 assert(propdata != NULL);
    815
    816 propdata->lastnode = -2;
    817
    818 return SCIP_OKAY;
    819}
    820
    821
    822/** presolving deinitialization method of propagator (called after presolving has been finished) */
    823static
    824SCIP_DECL_PROPEXITPRE(propExitpreProbing)
    825{ /*lint --e{715}*/
    826 SCIP_PROPDATA* propdata;
    827
    828 propdata = SCIPpropGetData(prop);
    829 assert(propdata != NULL);
    830
    831 /* delete the vars array, if the maximal number of runs are exceeded */
    832 if( propdata->maxruns >= 0 && SCIPgetNRuns(scip) >= propdata->maxruns )
    833 {
    834 SCIP_CALL( freeSortedvars(scip, propdata) );
    835 assert(propdata->sortedvars == NULL);
    836 assert(propdata->nsortedvars == 0);
    837 assert(propdata->nsortedbinvars == 0);
    838 }
    839
    840 return SCIP_OKAY;
    841}
    842
    843
    844/** solving process initialization method of propagator (called when branch and bound process is about to begin) */
    845static
    846SCIP_DECL_PROPINITSOL(propInitsolProbing)
    847{
    848 /*lint --e{715}*/
    849 SCIP_PROPDATA* propdata;
    850
    851 propdata = SCIPpropGetData(prop);
    852 assert(propdata != NULL);
    853
    854 /* reset all propdata elements for stopping propagation earlier */
    855 propdata->nuseless = 0;
    856 propdata->ntotaluseless = 0;
    857 propdata->nsumuseless = 0;
    858
    859 return SCIP_OKAY;
    860}
    861
    862
    863/** presolve method of propagator */
    864static
    865SCIP_DECL_PROPPRESOL(propPresolProbing)
    866{ /*lint --e{715}*/
    867 SCIP_PROPDATA* propdata;
    868 int nvars;
    869 int nbinvars;
    870 int nintvars;
    871 int nimplvars;
    872 int oldnfixedvars;
    873 int oldnaggrvars;
    874 int oldnchgbds;
    875 int oldnimplications;
    876 int ntotalvars;
    877 SCIP_Bool delay;
    878 SCIP_Bool cutoff;
    879
    880 assert(result != NULL);
    881
    882 *result = SCIP_DIDNOTRUN;
    883
    884 nbinvars = SCIPgetNBinVars(scip);
    885 nintvars = SCIPgetNIntVars(scip);
    886 nimplvars = SCIPgetNImplVars(scip);
    887
    888 /* if we have no binary variable anymore, we stop probing */
    889 if( nbinvars + nintvars + nimplvars == 0 )
    890 return SCIP_OKAY;
    891
    892 /* get propagator data */
    893 propdata = SCIPpropGetData(prop);
    894 assert(propdata != NULL);
    895
    896 /* check, if probing should be applied in the current run */
    897 if( propdata->maxruns >= 0 && SCIPgetNRuns(scip) > propdata->maxruns )
    898 return SCIP_OKAY;
    899
    900 /* if no domains changed since the last call, we don't need to probe */
    901 if( propdata->lastnode == -1 && nnewfixedvars == 0 && nnewaggrvars == 0 && nnewchgbds == 0 && nnewholes == 0 )
    902 return SCIP_OKAY;
    903
    904 SCIPdebugMsg(scip, "executing probing (used %.1f sec)\n", SCIPpropGetTime(prop));
    905
    906 *result = SCIP_DIDNOTFIND;
    907
    908 /* allow some additional probings */
    909 propdata->nuseless -= propdata->nuseless/10;
    910 propdata->ntotaluseless -= propdata->ntotaluseless/10;
    911
    912 /* get variable data */
    913 if( propdata->sortedvars == NULL )
    914 {
    915 SCIP_VAR** vars = SCIPgetVars(scip);
    916 int lastidx;
    917 int v;
    918
    919 assert(propdata->startidx == 0);
    920
    921 nvars = SCIPgetNVars(scip);
    922
    923 SCIP_CALL( SCIPduplicateMemoryArray(scip, &(propdata->sortedvars), vars, nvars) );
    924 propdata->nsortedvars = nvars;
    925
    926 /* determine implicit binary variables */
    927 lastidx = nbinvars + nintvars + nimplvars;
    928 for( v = nbinvars; v < lastidx; ++v )
    929 {
    930 if( SCIPvarIsBinary(propdata->sortedvars[v]) )
    931 {
    932 SCIPswapPointers((void**) &(propdata->sortedvars[nbinvars]), (void**) &(propdata->sortedvars[v]));
    933 ++nbinvars;
    934 }
    935 }
    936 propdata->nsortedbinvars = nbinvars;
    937
    938 /* capture variables to make sure, the variables are not deleted */
    939 for( v = propdata->nsortedvars - 1; v >= 0 ; --v )
    940 {
    941 SCIP_CALL( SCIPcaptureVar(scip, propdata->sortedvars[v]) );
    942 }
    943 }
    944
    945 if( propdata->nsortedbinvars == 0 )
    946 return SCIP_OKAY;
    947
    948 /* number of total variables is not decreasing, and we can identify every variable by their index, so allocate
    949 * enough space
    950 */
    951 ntotalvars = SCIPgetNTotalVars(scip);
    952 if( propdata->noldtotalvars < ntotalvars )
    953 {
    954 SCIP_CALL( SCIPreallocMemoryArray(scip, &propdata->nprobed, ntotalvars) );
    955 BMSclearMemoryArray(&(propdata->nprobed[propdata->noldtotalvars]), ntotalvars - propdata->noldtotalvars); /*lint !e866*/
    956 propdata->noldtotalvars = ntotalvars;
    957 }
    958
    959 propdata->lastnode = -1;
    960
    961 /* sort the binary variables by number of rounding locks, if at least 100 variables were probed since last sort */
    962 if( propdata->lastsortstartidx < 0 || propdata->startidx - propdata->lastsortstartidx >= 100 )
    963 {
    964 SCIP_CALL( sortVariables(scip, propdata, propdata->sortedvars, propdata->nsortedbinvars, propdata->startidx) );
    965 propdata->lastsortstartidx = propdata->startidx;
    966 }
    967
    968 oldnfixedvars = *nfixedvars;
    969 oldnaggrvars = *naggrvars;
    970 oldnchgbds = *nchgbds;
    971 oldnimplications = propdata->nimplications;
    972
    973 /* start probing on variables */
    974 SCIP_CALL( applyProbing(scip, propdata, propdata->sortedvars, propdata->nsortedvars, propdata->nsortedbinvars,
    975 &(propdata->startidx), nfixedvars, naggrvars, nchgbds, oldnfixedvars, oldnaggrvars, &delay, &cutoff) );
    976
    977 /* adjust result code */
    978 if( cutoff )
    979 *result = SCIP_CUTOFF;
    980 else
    981 {
    982 if( delay )
    983 {
    984 /* probing was interrupted because it reached the maximal fixings parameter, so we want to rerun it at the next call */
    985 propdata->lastnode = -2;
    986 }
    987
    988 if( *nfixedvars > oldnfixedvars || *naggrvars > oldnaggrvars || *nchgbds > oldnchgbds
    989 || propdata->nimplications > oldnimplications )
    990 *result = SCIP_SUCCESS;
    991 }
    992
    993 return SCIP_OKAY;
    994}
    995
    996
    997/** execution method of propagator */
    998static
    999SCIP_DECL_PROPEXEC(propExecProbing)
    1000{ /*lint --e{715}*/
    1001 SCIP_PROPDATA* propdata;
    1002 SCIP_VAR** vars;
    1003 SCIP_VAR** binvars;
    1004 int nvars;
    1005 int nbinvars;
    1006 int i;
    1007 int nfixedvars;
    1008 int naggrvars;
    1009 int nchgbds;
    1010 int oldnfixedvars;
    1011 int oldnaggrvars;
    1012 int oldnchgbds;
    1013 SCIPdebug( int oldnimplications; )
    1014 int startidx;
    1015 int ntotalvars;
    1016 SCIP_Bool delay;
    1017 SCIP_Bool cutoff;
    1018
    1019 assert(result != NULL);
    1020
    1021 *result = SCIP_DIDNOTRUN;
    1022
    1023 /* avoid recursive infinity loop */
    1024 if( SCIPinProbing(scip) )
    1025 return SCIP_OKAY;
    1026
    1027 /* only call propagation on branching candidates, if an optimal LP solution is at hand */
    1029 return SCIP_OKAY;
    1030
    1031 /* get propagator data */
    1032 propdata = SCIPpropGetData(prop);
    1033 assert(propdata != NULL);
    1034
    1035 /* if already called stop */
    1036 if( propdata->lastnode == SCIPnodeGetNumber(SCIPgetCurrentNode(scip)) )
    1037 return SCIP_OKAY;
    1038
    1039 /* if maximal depth for propagation is reached, stop */
    1040 if( propdata->maxdepth >= 0 && propdata->maxdepth < SCIPgetDepth(scip) )
    1041 return SCIP_OKAY;
    1042
    1043 propdata->lastnode = SCIPnodeGetNumber(SCIPgetCurrentNode(scip));
    1044
    1045 /* get (number of) fractional variables that should be integral */
    1046 /* todo check if integrating fractional implicit integer variables is beneficial for probing */
    1047 SCIP_CALL( SCIPgetLPBranchCands(scip, &vars, NULL, NULL, &nvars, NULL, NULL) );
    1048 nbinvars = 0;
    1049
    1050 /* alloc array for fractional binary variables */
    1051 SCIP_CALL( SCIPallocBufferArray(scip, &binvars, nvars) );
    1052
    1053 /* copy binary variables to array binvars */
    1054 for( i = 0; i < nvars; ++i )
    1055 {
    1056 SCIP_VAR* var;
    1057 var = vars[i];
    1058
    1059 assert(var != NULL);
    1060 if( SCIPvarIsBinary(var) )
    1061 {
    1062 assert(SCIPvarGetLbLocal(var) < 0.5);
    1063 assert(SCIPvarGetUbLocal(var) > 0.5);
    1064
    1065 binvars[nbinvars] = var;
    1066 ++nbinvars;
    1067 }
    1068 }
    1069 SCIPdebugMsg(scip, "problem <%s> node %" SCIP_LONGINT_FORMAT " probing propagation found %d of %d possible probing candidates\n", SCIPgetProbName(scip), SCIPnodeGetNumber(SCIPgetCurrentNode(scip)), nbinvars, nvars);
    1070
    1071 if( nbinvars == 0 )
    1072 {
    1073 *result = SCIP_DIDNOTFIND;
    1074 goto TERMINATE;
    1075 }
    1076
    1077 /* number of total variables is not decreasing, and we can identify every variable by their index, so allocate
    1078 * enough space
    1079 */
    1080 ntotalvars = SCIPgetNTotalVars(scip);
    1081 if( propdata->noldtotalvars < ntotalvars )
    1082 {
    1083 SCIP_CALL( SCIPreallocMemoryArray(scip, &propdata->nprobed, ntotalvars) );
    1084 BMSclearMemoryArray(&(propdata->nprobed[propdata->noldtotalvars]), ntotalvars - propdata->noldtotalvars); /*lint !e866*/
    1085 propdata->noldtotalvars = ntotalvars;
    1086 }
    1087
    1088 /* sort binary variables */
    1089 SCIP_CALL( sortVariables(scip, propdata, binvars, nbinvars, 0) );
    1090
    1091 oldnfixedvars = 0;
    1092 oldnaggrvars = 0;
    1093 oldnchgbds = 0;
    1094 nfixedvars = 0;
    1095 naggrvars = 0;
    1096 nchgbds = 0;
    1097 startidx = 0;
    1098 SCIPdebug( oldnimplications = propdata->nimplications; )
    1099
    1100 /* start probing on found variables */
    1101 SCIP_CALL( applyProbing(scip, propdata, binvars, nbinvars, nbinvars, &startidx, &nfixedvars, &naggrvars, &nchgbds, oldnfixedvars, oldnaggrvars, &delay, &cutoff) );
    1102 SCIPdebug( SCIPdebugMsg(scip, "probing propagation found %d fixings, %d aggregation, %d nchgbds, and %d implications\n",
    1103 nfixedvars, naggrvars, nchgbds, (propdata->nimplications) - oldnimplications); )
    1104
    1105 if( delay )
    1106 {
    1107 /* probing was interrupted because it reached the maximal fixings parameter, so we want to rerun it at the next call */
    1108 propdata->lastnode = -2;
    1109 }
    1110
    1111 /* adjust result code */
    1112 if( cutoff )
    1113 *result = SCIP_CUTOFF;
    1114 else if( nfixedvars > oldnfixedvars || naggrvars > oldnaggrvars || nchgbds > oldnchgbds )
    1115 *result = SCIP_REDUCEDDOM;
    1116
    1117 TERMINATE:
    1118 SCIPfreeBufferArray(scip, &binvars);
    1119
    1120 return SCIP_OKAY; /*lint !e438*/
    1121}
    1122
    1123
    1124/** propagation conflict resolving method of propagator */
    1125static
    1126SCIP_DECL_PROPRESPROP(propRespropProbing)
    1127{ /*lint --e{715}*/
    1128 *result = SCIP_DIDNOTRUN;
    1129
    1130 return SCIP_OKAY;
    1131}
    1132
    1133
    1134/*
    1135 * propagator specific interface methods
    1136 */
    1137
    1138/** creates the probing propagator and includes it in SCIP */
    1140 SCIP* scip /**< SCIP data structure */
    1141 )
    1142{
    1143 SCIP_PROPDATA* propdata;
    1144 SCIP_PROP* prop;
    1145
    1146 /* create probing propagator data */
    1147 SCIP_CALL( SCIPallocBlockMemory(scip, &propdata) );
    1148 SCIP_CALL( initPropdata(propdata) );
    1149
    1150 /* include propagator */
    1152 propExecProbing, propdata) );
    1153
    1154 assert(prop != NULL);
    1155
    1156 /* set optional callbacks via setter functions */
    1157 SCIP_CALL( SCIPsetPropCopy(scip, prop, propCopyProbing) );
    1158 SCIP_CALL( SCIPsetPropFree(scip, prop, propFreeProbing) );
    1159 SCIP_CALL( SCIPsetPropInit(scip, prop, propInitProbing) );
    1160 SCIP_CALL( SCIPsetPropExit(scip, prop, propExitProbing) );
    1161 SCIP_CALL( SCIPsetPropInitsol(scip, prop, propInitsolProbing) );
    1162 SCIP_CALL( SCIPsetPropInitpre(scip, prop, propInitpreProbing) );
    1163 SCIP_CALL( SCIPsetPropExitpre(scip, prop, propExitpreProbing) );
    1166 SCIP_CALL( SCIPsetPropResprop(scip, prop, propRespropProbing) );
    1167
    1168 /* add probing propagator parameters */
    1170 "propagating/" PROP_NAME "/maxruns",
    1171 "maximal number of runs, probing participates in (-1: no limit)",
    1172 &propdata->maxruns, FALSE, DEFAULT_MAXRUNS, -1, INT_MAX, NULL, NULL) );
    1174 "propagating/" PROP_NAME "/proprounds",
    1175 "maximal number of propagation rounds in probing subproblems (-1: no limit, 0: auto)",
    1176 &propdata->proprounds, TRUE, DEFAULT_PROPROUNDS, -1, INT_MAX, NULL, NULL) );
    1178 "propagating/" PROP_NAME "/maxfixings",
    1179 "maximal number of fixings found, until probing is interrupted (0: don't iterrupt)",
    1180 &propdata->maxfixings, TRUE, DEFAULT_MAXFIXINGS, 0, INT_MAX, NULL, NULL) );
    1182 "propagating/" PROP_NAME "/maxuseless",
    1183 "maximal number of successive probings without fixings, until probing is aborted (0: don't abort)",
    1184 &propdata->maxuseless, TRUE, DEFAULT_MAXUSELESS, 0, INT_MAX, NULL, NULL) );
    1186 "propagating/" PROP_NAME "/maxtotaluseless",
    1187 "maximal number of successive probings without fixings, bound changes, and implications, until probing is aborted (0: don't abort)",
    1188 &propdata->maxtotaluseless, TRUE, DEFAULT_MAXTOTALUSELESS, 0, INT_MAX, NULL, NULL) );
    1190 "propagating/" PROP_NAME "/maxsumuseless",
    1191 "maximal number of probings without fixings, until probing is aborted (0: don't abort)",
    1192 &propdata->maxsumuseless, TRUE, DEFAULT_MAXSUMUSELESS, 0, INT_MAX, NULL, NULL) );
    1194 "propagating/" PROP_NAME "/maxdepth",
    1195 "maximal depth until propagation is executed(-1: no limit)",
    1196 &propdata->maxdepth, TRUE, DEFAULT_MAXDEPTH, -1, INT_MAX, NULL, NULL) );
    1197
    1198 return SCIP_OKAY;
    1199}
    1200
    1201
    1202/** applies and evaluates probing of a single variable in the given direction and bound */
    1204 SCIP* scip, /**< SCIP data structure */
    1205 SCIP_VAR** vars, /**< problem variables */
    1206 int nvars, /**< number of problem variables */
    1207 int probingpos, /**< variable number to apply probing on */
    1208 SCIP_BOUNDTYPE boundtype, /**< which bound should be changed */
    1209 SCIP_Real bound, /**< which bound should be set */
    1210 int maxproprounds, /**< maximal number of propagation rounds (-1: no limit, 0: parameter settings) */
    1211 SCIP_Real* impllbs, /**< array to store lower bounds after applying implications and cliques */
    1212 SCIP_Real* implubs, /**< array to store upper bounds after applying implications and cliques */
    1213 SCIP_Real* proplbs, /**< array to store lower bounds after full propagation */
    1214 SCIP_Real* propubs, /**< array to store upper bounds after full propagation */
    1215 SCIP_Bool* cutoff /**< pointer to store whether the probing direction is infeasible */
    1216 )
    1217{
    1218 assert(impllbs != NULL);
    1219 assert(implubs != NULL);
    1220 assert(proplbs != NULL);
    1221 assert(propubs != NULL);
    1222 assert(cutoff != NULL);
    1223 assert(0 <= probingpos && probingpos < nvars);
    1224 assert(SCIPisGE(scip, bound, SCIPvarGetLbLocal(vars[probingpos])));
    1225 assert(SCIPisLE(scip, bound, SCIPvarGetUbLocal(vars[probingpos])));
    1226
    1227 SCIPdebugMsg(scip, "applying probing on variable <%s> %s %g (nlocks=%d/%d, impls=%d/%d, clqs=%d/%d)\n",
    1228 SCIPvarGetName(vars[probingpos]), boundtype == SCIP_BOUNDTYPE_UPPER ? "<=" : ">=", bound,
    1231 SCIPvarGetNImpls(vars[probingpos], FALSE), SCIPvarGetNImpls(vars[probingpos], TRUE),
    1232 SCIPvarGetNCliques(vars[probingpos], FALSE), SCIPvarGetNCliques(vars[probingpos], TRUE));
    1233
    1234 /* in debug mode we assert above that this trivial infeasibility does not occur (for performance reasons), but in
    1235 * optimized mode we return safely
    1236 */
    1237 if( SCIPisLT(scip, bound, SCIPvarGetLbLocal(vars[probingpos]))
    1238 || SCIPisGT(scip, bound, SCIPvarGetUbLocal(vars[probingpos])) )
    1239 {
    1240 SCIPdebugMsg(scip, " -> trivial infeasibility detected\n");
    1241 *cutoff = TRUE;
    1242 return SCIP_OKAY;
    1243 }
    1244
    1245 /* start probing mode */
    1247
    1248 /* enables collection of variable statistics during probing */
    1250
    1251 /* fix variable */
    1252 if( boundtype == SCIP_BOUNDTYPE_UPPER )
    1253 {
    1254 SCIP_CALL( SCIPchgVarUbProbing(scip, vars[probingpos], bound) );
    1255 }
    1256 else
    1257 {
    1258 assert(boundtype == SCIP_BOUNDTYPE_LOWER);
    1259 SCIP_CALL( SCIPchgVarLbProbing(scip, vars[probingpos], bound) );
    1260 }
    1261
    1262 /* @todo it might pay off to catch the bounds-tightened event on all variables and then only get the implied and
    1263 * propagated bounds on those variables which where really changed on propagation
    1264 */
    1265
    1266 /* apply propagation of implication graph and clique table */
    1268 if( !(*cutoff) )
    1269 {
    1270 int i;
    1271
    1272 for( i = 0; i < nvars; ++i )
    1273 {
    1274 impllbs[i] = SCIPvarGetLbLocal(vars[i]);
    1275 implubs[i] = SCIPvarGetUbLocal(vars[i]);
    1276 }
    1277
    1278 /* apply propagation */
    1279 SCIP_CALL( SCIPpropagateProbing(scip, maxproprounds, cutoff, NULL) );
    1280 }
    1281 else
    1282 {
    1283 SCIPdebugMsg(scip, "propagating probing implications after <%s> to %g led to a cutoff\n",
    1284 SCIPvarGetName(vars[probingpos]), bound);
    1285 }
    1286
    1287 /* evaluate propagation */
    1288 if( !(*cutoff) )
    1289 {
    1290 int i;
    1291
    1292 for( i = 0; i < nvars; ++i )
    1293 {
    1294 proplbs[i] = SCIPvarGetLbLocal(vars[i]);
    1295 propubs[i] = SCIPvarGetUbLocal(vars[i]);
    1296 }
    1297 }
    1298
    1299 /* exit probing mode */
    1301
    1302 return SCIP_OKAY;
    1303}
    1304
    1305/** analyses boundchanges resulting from probing on a variable and performs deduced fixations, aggregations, and domain tightenings
    1306 * Given a variable probingvar with domain [l,u] and bound tightening results from reducing the domain
    1307 * once to [l,leftub] and once to [rightlb,u], the method computes and applies resulting variable fixations, aggregations,
    1308 * implications, and bound changes. Variable probingvar does not need to be binary.
    1309 * The whole domain of probingvar need to be covered by the left and right branches, i.e.,
    1310 * we assume leftub >= rightlb for continuous variables or floor(leftub) >= ceil(rightlb)-1 for discrete variables.
    1311 * Bounds after applying implications and cliques do not need to be provided, but if they are omitted and probingvar is a binary variable,
    1312 * then already existing implications may be added.
    1313 */
    1315 SCIP* scip, /**< SCIP data structure */
    1316 SCIP_VAR* probingvar, /**< the probing variable */
    1317 SCIP_Real leftub, /**< upper bound of probing variable in left branch */
    1318 SCIP_Real rightlb, /**< lower bound of probing variable in right branch */
    1319 int nvars, /**< number of variables which bound changes should be analyzed */
    1320 SCIP_VAR** vars, /**< variables which bound changes should be analyzed */
    1321 SCIP_Real* leftimpllbs, /**< lower bounds after applying implications and cliques in left branch, or NULL */
    1322 SCIP_Real* leftimplubs, /**< upper bounds after applying implications and cliques in left branch, or NULL */
    1323 SCIP_Real* leftproplbs, /**< lower bounds after applying domain propagation in left branch */
    1324 SCIP_Real* leftpropubs, /**< upper bounds after applying domain propagation in left branch */
    1325 SCIP_Real* rightimpllbs, /**< lower bounds after applying implications and cliques in right branch, or NULL */
    1326 SCIP_Real* rightimplubs, /**< upper bounds after applying implications and cliques in right branch, or NULL */
    1327 SCIP_Real* rightproplbs, /**< lower bounds after applying domain propagation in right branch */
    1328 SCIP_Real* rightpropubs, /**< upper bounds after applying domain propagation in right branch */
    1329 int* nfixedvars, /**< pointer to counter which is increased by the number of deduced variable fixations */
    1330 int* naggrvars, /**< pointer to counter which is increased by the number of deduced variable aggregations */
    1331 int* nimplications, /**< pointer to counter which is increased by the number of deduced implications */
    1332 int* nchgbds, /**< pointer to counter which is increased by the number of deduced bound tightenings */
    1333 SCIP_Bool* cutoff /**< buffer to store whether a cutoff is detected */
    1334 )
    1335{
    1336 SCIP_Bool fixedleft;
    1337 SCIP_Bool fixedright;
    1338 SCIP_Bool probingvarisbinary;
    1339 SCIP_Bool probingvarisinteger;
    1340 int j;
    1341
    1342 assert(scip != NULL);
    1343 assert(probingvar != NULL);
    1344 assert(SCIPisGE(scip, leftub, SCIPvarGetLbLocal(probingvar))); /* left branch should not be empty by default */
    1345 assert(SCIPisLE(scip, rightlb, SCIPvarGetUbLocal(probingvar))); /* right branch should not be empty by default */
    1346 assert(vars != NULL || nvars == 0);
    1347 assert(leftproplbs != NULL);
    1348 assert(leftpropubs != NULL);
    1349 assert(rightproplbs != NULL);
    1350 assert(rightpropubs != NULL);
    1351 assert(nfixedvars != NULL);
    1352 assert(naggrvars != NULL);
    1353 assert(nimplications != NULL);
    1354 assert(nchgbds != NULL);
    1355 assert(cutoff != NULL);
    1356
    1357 /* @todo the asserts below could be relaxed by taking domain holes into account */
    1358 if( SCIPvarIsIntegral(probingvar) )
    1359 {
    1360 /* adjust bounds to actually used ones */
    1361 leftub = SCIPfloor(scip, leftub);
    1362 rightlb = SCIPceil(scip, rightlb);
    1363
    1364 probingvarisinteger = TRUE;
    1365 probingvarisbinary = SCIPvarIsBinary(probingvar);
    1366 }
    1367 else
    1368 {
    1369 /* assert dichotomy in case of continuous var: leftub >= rightlb */
    1370 assert(SCIPisGE(scip, leftub, rightlb));
    1371 probingvarisbinary = FALSE;
    1372 probingvarisinteger = FALSE;
    1373 }
    1374
    1375 /* check if probing variable was fixed in the branches */
    1376 fixedleft = SCIPisEQ(scip, SCIPvarGetLbLocal(probingvar), leftub);
    1377 fixedright = SCIPisEQ(scip, SCIPvarGetUbLocal(probingvar), rightlb);
    1378
    1379 *cutoff = FALSE;
    1380
    1381 for( j = 0; j < nvars && !*cutoff; ++j )
    1382 {
    1383 SCIP_VAR* var;
    1384 SCIP_Bool varisinteger;
    1385 SCIP_Real newlb;
    1386 SCIP_Real newub;
    1387
    1388 assert(vars != NULL); /* for flexelint */
    1389
    1390 var = vars[j];
    1391 assert(var != NULL);
    1392
    1393 /* @todo: add holes, and even add holes if x was the probing variable and it followed a better bound on x itself */
    1394 /* @todo: check if we probed on an integer variable, that this maybe led to aggregation on two other variables, i.e
    1395 * probing on x <= 1 and x >= 2 led to y = 1, z = 1 and y = 0, z = 0 resp., which means y = Z
    1396 */
    1397
    1398 /* if probing variable is binary, then there is nothing we could deduce here (variable should be fixed in both branches)
    1399 * if it is not binary, we want to see if we found bound tightenings, even though it seems quite unlikely */
    1400 if( var == probingvar && probingvarisbinary )
    1401 continue;
    1402
    1403 /* new bounds of the variable is the union of the propagated bounds of the left and right case */
    1404 newlb = MIN(leftproplbs[j], rightproplbs[j]);
    1405 newub = MAX(leftpropubs[j], rightpropubs[j]);
    1406 varisinteger = SCIPvarIsIntegral(var);
    1407
    1408 /* check for fixed variables */
    1409 if( SCIPisEQ(scip, newlb, newub) )
    1410 {
    1411 SCIP_Real fixval;
    1412 SCIP_Bool fixed;
    1413
    1414 if( !varisinteger )
    1415 {
    1416 /* in both probings, variable j is deduced to the same value: fix variable to this value */
    1417 fixval = SCIPselectSimpleValue(newlb - 0.9 * SCIPepsilon(scip), newub + 0.9 * SCIPepsilon(scip), MAXDNOM);
    1418 }
    1419 else
    1420 {
    1421 fixval = newlb;
    1422 }
    1423
    1425 {
    1426 SCIP_CALL( SCIPfixVar(scip, var, fixval, cutoff, &fixed) );
    1427 }
    1428 else
    1429 {
    1430 SCIP_CALL( SCIPtightenVarLb(scip, var, fixval, TRUE, cutoff, &fixed) );
    1431 if( !*cutoff )
    1432 {
    1433 SCIP_Bool tightened;
    1434
    1435 SCIP_CALL( SCIPtightenVarUb(scip, var, fixval, TRUE, cutoff, &tightened) );
    1436 fixed &= tightened;
    1437 }
    1438 }
    1439
    1440 if( fixed )
    1441 {
    1442 SCIPdebugMsg(scip, "fixed variable <%s> to %g due to probing on <%s> with nlocks=(%d/%d)\n",
    1443 SCIPvarGetName(var), fixval,
    1446 (*nfixedvars)++;
    1447 }
    1448 else if( *cutoff )
    1449 {
    1450 SCIPdebugMsg(scip, "analyzing probing deduction of <%s> led to an infeasible fixing of variable <%s> to %g\n",
    1451 SCIPvarGetName(probingvar), SCIPvarGetName(var), fixval);
    1452 }
    1453
    1454 continue;
    1455 }
    1456 else
    1457 {
    1458 /* check for bound tightenings */
    1459 SCIP_Real oldlb;
    1460 SCIP_Real oldub;
    1461 SCIP_Bool tightened;
    1462 SCIP_Bool tightenlb;
    1463 SCIP_Bool tightenub;
    1464 SCIP_Bool force;
    1465
    1466 oldlb = SCIPvarGetLbLocal(var);
    1467 oldub = SCIPvarGetUbLocal(var);
    1468
    1469 if( varisinteger )
    1470 {
    1471 force = TRUE;
    1472 tightenlb = (newlb > oldlb + 0.5);
    1473 tightenub = (newub < oldub - 0.5);
    1474 }
    1475 else
    1476 {
    1477 force = TRUE;
    1478 tightenlb = SCIPisLbBetter(scip, newlb, oldlb, oldub);
    1479 tightenub = SCIPisUbBetter(scip, newub, oldlb, oldub);
    1480 }
    1481
    1482 if( tightenlb )
    1483 {
    1484 /* in both probings, variable j is deduced to be at least newlb: tighten lower bound */
    1485 SCIP_CALL( SCIPtightenVarLb(scip, var, newlb, force, cutoff, &tightened) );
    1486 if( tightened )
    1487 {
    1488 SCIPdebugMsg(scip, "tightened lower bound of variable <%s>[%g,%g] to %g due to probing on <%s> with nlocks=(%d/%d)\n",
    1489 SCIPvarGetName(var), oldlb, oldub, newlb,
    1492 (*nchgbds)++;
    1493 }
    1494 else if( *cutoff )
    1495 {
    1496 SCIPdebugMsg(scip, "analyzing probing deduction of <%s> led to an infeasible new lower bound of variable <%s> to %g\n",
    1497 SCIPvarGetName(probingvar), SCIPvarGetName(var), newlb);
    1498 }
    1499 }
    1500
    1501 if( tightenub && !*cutoff )
    1502 {
    1503 /* in both probings, variable j is deduced to be at most newub: tighten upper bound */
    1504 SCIP_CALL( SCIPtightenVarUb(scip, var, newub, force, cutoff, &tightened) );
    1505 if( tightened )
    1506 {
    1507 SCIPdebugMsg(scip, "tightened upper bound of variable <%s>[%g,%g] to %g due to probing on <%s> with nlocks=(%d/%d)\n",
    1508 SCIPvarGetName(var), oldlb, oldub, newub,
    1511 (*nchgbds)++;
    1512 }
    1513 else if( *cutoff )
    1514 {
    1515 SCIPdebugMsg(scip, "analyzing probing deduction of <%s> led to an infeasible new lower bound of variable <%s> to %g\n",
    1516 SCIPvarGetName(probingvar), SCIPvarGetName(var), newub);
    1517 }
    1518 }
    1519 if( *cutoff )
    1520 break;
    1521 }
    1522
    1523 /* below we add aggregations and implications between probingvar and var,
    1524 * we don't want this if both variables are the same
    1525 */
    1526 if( var == probingvar )
    1527 continue;
    1528
    1529 /* check for aggregations and implications */
    1530 if( fixedleft && fixedright &&
    1531 SCIPisEQ(scip, leftproplbs[j], leftpropubs[j]) && SCIPisEQ(scip, rightproplbs[j], rightpropubs[j]) )
    1532 {
    1533 /* var is fixed whenever probingvar is fixed, i.e.,
    1534 * var = leftproplbs[j] + (rightproplbs[j] - leftproplbs[j]) / (rightlb - leftub) * (probingvar - leftub)
    1535 * -> both variables can be aggregated:
    1536 * (rightlb - leftub) * (var - leftproplbs[j]) = (rightproplbs[j] - leftproplbs[j]) * (probingvar - leftub)
    1537 * -> (rightlb - leftub) * var - (rightproplbs[j] - leftproplbs[j]) * probingvar = leftproplbs[j] * rightlb - rightproplbs[j] * leftub
    1538 *
    1539 * check for case where both variables are binary: leftub = 1, rightlb = 0
    1540 * case leftproplbs[j] = 0, rightproplbs[j] = 1, i.e., var and probingvar are fixed to same value
    1541 * -> aggregation is 1 * var - 1 * probingvar = 0 * 1 - 1 * 0 = 0 -> correct
    1542 * case leftproplbs[j] = 1, rightproblbs[j] = 0, i.e., var and probingvar are fixed to opposite values
    1543 * -> aggregation is 1 * var + 1 * probingvar = 1 * 1 - 0 * 0 = 0 -> correct
    1544 */
    1546 {
    1547 SCIP_Bool aggregated;
    1548 SCIP_Bool redundant;
    1549
    1550 SCIP_CALL( SCIPaggregateVars(scip, var, probingvar,
    1551 rightlb - leftub, -(rightproplbs[j] - leftproplbs[j]), leftproplbs[j] * rightlb - rightproplbs[j] * leftub,
    1552 cutoff, &redundant, &aggregated) );
    1553
    1554 if( aggregated )
    1555 {
    1556 SCIPdebugMsg(scip, "aggregated variables %g<%s> - %g<%s> == %g, nlocks=(%d/%d)\n",
    1557 rightlb - leftub, SCIPvarGetName(var),
    1558 rightproplbs[j] - leftproplbs[j], SCIPvarGetName(probingvar),
    1559 leftproplbs[j] * rightlb - rightproplbs[j] * leftub,
    1562 (*naggrvars)++;
    1563 }
    1564 if( *cutoff )
    1565 {
    1566 SCIPdebugMsg(scip, "analyzing probing deduction of <%s> led to an infeasible aggregation: %g<%s> - %g<%s> == %g\n",
    1567 SCIPvarGetName(probingvar), rightlb - leftub, SCIPvarGetName(var),
    1568 rightproplbs[j] - leftproplbs[j], SCIPvarGetName(probingvar),
    1569 leftproplbs[j] * rightlb - rightproplbs[j] * leftub);
    1570 }
    1571 }
    1572 else if( probingvarisinteger && SCIPnodeGetDepth(SCIPgetCurrentNode(scip)) == 0 )
    1573 {
    1574 /* if we are not in presolving, then we cannot do aggregations
    1575 * but we can use variable bounds to code the same equality
    1576 * var == ((leftproplbs[j] * rightlb - rightproplbs[j] * leftub) + (rightproplbs[j] - leftproplbs[j]) * probingvar) / (rightlb - leftub)
    1577 */
    1578 int nboundchanges;
    1579
    1580 assert(!SCIPisEQ(scip, leftub, rightlb));
    1581
    1582 SCIP_CALL( SCIPaddVarVlb(scip, var, probingvar, (rightproplbs[j] - leftproplbs[j]) / (rightlb - leftub), (leftproplbs[j] * rightlb - rightproplbs[j] * leftub) / (rightlb - leftub), cutoff, &nboundchanges) );
    1583 (*nchgbds) += nboundchanges;
    1584
    1585 if( *cutoff )
    1586 {
    1587 SCIPdebugMsg(scip, "analyzing probing deduction of <%s> led to an infeasible vlb: %g<%s> - %g<%s> == %g\n",
    1588 SCIPvarGetName(probingvar), rightlb - leftub, SCIPvarGetName(var),
    1589 rightproplbs[j] - leftproplbs[j], SCIPvarGetName(probingvar),
    1590 leftproplbs[j] * rightlb - rightproplbs[j] * leftub);
    1591 }
    1592 else
    1593 {
    1594 SCIP_CALL( SCIPaddVarVub(scip, var, probingvar, (rightproplbs[j] - leftproplbs[j]) / (rightlb - leftub), (leftproplbs[j] * rightlb - rightproplbs[j] * leftub) / (rightlb - leftub), cutoff, &nboundchanges) );
    1595 (*nchgbds) += nboundchanges;
    1596
    1597 if( *cutoff )
    1598 {
    1599 SCIPdebugMsg(scip, "analyzing probing deduction of <%s> led to an infeasible vub: %g<%s> - %g<%s> == %g\n",
    1600 SCIPvarGetName(probingvar), rightlb - leftub, SCIPvarGetName(var),
    1601 rightproplbs[j] - leftproplbs[j], SCIPvarGetName(probingvar),
    1602 leftproplbs[j] * rightlb - rightproplbs[j] * leftub);
    1603 }
    1604 }
    1605 (*nimplications)++;
    1606 }
    1607 /* if probingvar is continuous and we are in solving stage, then we do nothing, but it's unlikely that we get
    1608 * here (fixedleft && fixedright) with a continuous variable
    1609 */
    1610 }
    1611 /* @todo: check if we can add variable lowerbounds/upperbounds on integer variables */
    1612 /* can only add implications on binary variables which are globally valid */
    1613 else if( probingvarisbinary && (SCIPgetStage(scip) != SCIP_STAGE_SOLVING || SCIPnodeGetDepth(SCIPgetCurrentNode(scip)) == 0) )
    1614 {
    1615 /* implications can be added only for binary variables */
    1616 int nboundchanges;
    1617
    1618 /* since probing var is binary variable, probing should have fixed variable in both branches,
    1619 * which is to 0.0 in the left branch and to 1.0 in the right branch */
    1620 assert(fixedleft);
    1621 assert(fixedright);
    1622 assert(SCIPisZero(scip, leftub));
    1623 assert(SCIPisEQ(scip, rightlb, 1.0));
    1624
    1625 if( SCIPisEQ(scip, newlb, leftpropubs[j]) && (leftimplubs == NULL || leftimplubs[j] > leftpropubs[j]) )
    1626 {
    1627 /* var is fixed to lower bound whenever probingvar is fixed to 0.0
    1628 * and implication is not already known
    1629 * -> insert implication: probingvar == 0 => var <= leftpropubs[j]
    1630 */
    1631 /*SCIPdebugMsg(scip, "found implication <%s> == 0 => <%s> == %g\n",
    1632 SCIPvarGetName(probingvar), SCIPvarGetName(var), leftpropubs[j]);*/
    1633 SCIP_CALL( SCIPaddVarImplication(scip, probingvar, FALSE, var, SCIP_BOUNDTYPE_UPPER, leftpropubs[j],
    1634 cutoff, &nboundchanges) );
    1635 (*nimplications)++;
    1636 (*nchgbds) += nboundchanges;
    1637
    1638 if( *cutoff )
    1639 {
    1640 SCIPdebugMsg(scip, "analyzing probing deduction of <%s> led to an infeasible implication <%s> == 0 => <%s> == %g\n",
    1641 SCIPvarGetName(probingvar), SCIPvarGetName(probingvar), SCIPvarGetName(var), leftpropubs[j]);
    1642 }
    1643 }
    1644 else if( SCIPisEQ(scip, newub, leftproplbs[j]) && (leftimpllbs == NULL || leftimpllbs[j] < leftproplbs[j]) )
    1645 {
    1646 /* var is fixed to upper bound whenever probingvar is fixed to 0.0
    1647 * and implication is not already known
    1648 * -> insert implication: probingvar == 0 => var >= leftproplbs[j]
    1649 */
    1650 /*SCIPdebugMsg(scip, "found implication <%s> == 0 => <%s> == %g\n",
    1651 SCIPvarGetName(probingvar), SCIPvarGetName(var), leftproplbs[j]);*/
    1652 SCIP_CALL( SCIPaddVarImplication(scip, probingvar, FALSE, var, SCIP_BOUNDTYPE_LOWER, leftproplbs[j],
    1653 cutoff, &nboundchanges) );
    1654 (*nimplications)++;
    1655 (*nchgbds) += nboundchanges;
    1656
    1657 if( *cutoff )
    1658 {
    1659 SCIPdebugMsg(scip, "analyzing probing deduction of <%s> led to an infeasible implication <%s> == 0 => <%s> == %g\n",
    1660 SCIPvarGetName(probingvar), SCIPvarGetName(probingvar), SCIPvarGetName(var), leftproplbs[j]);
    1661 }
    1662 }
    1663 /* we can do an else here, since the case where var is fixed for both fixings of probingvar had been handled as aggregation */
    1664 else if( SCIPisEQ(scip, newlb, rightpropubs[j]) && (rightimplubs == NULL || rightimplubs[j] > rightpropubs[j]) )
    1665 {
    1666 /* var is fixed to lower bound whenever probingvar is fixed to 1.0
    1667 * and implication is not already known
    1668 * -> insert implication: probingvar == 1 => var <= rightpropubs[j]
    1669 */
    1670 /*SCIPdebugMsg(scip, "found implication <%s> == 1 => <%s> == %g\n",
    1671 SCIPvarGetName(probingvar), SCIPvarGetName(var), rightpropubs[j]);*/
    1672 SCIP_CALL( SCIPaddVarImplication(scip, probingvar, TRUE, var, SCIP_BOUNDTYPE_UPPER, rightpropubs[j],
    1673 cutoff, &nboundchanges) );
    1674 (*nimplications)++;
    1675 (*nchgbds) += nboundchanges;
    1676
    1677 if( *cutoff )
    1678 {
    1679 SCIPdebugMsg(scip, "analyzing probing deduction of <%s> led to an infeasible implication <%s> == 1 => <%s> == %g\n",
    1680 SCIPvarGetName(probingvar), SCIPvarGetName(probingvar), SCIPvarGetName(var), rightpropubs[j]);
    1681 }
    1682 }
    1683 else if( SCIPisEQ(scip, newub, rightproplbs[j]) && (rightimpllbs == NULL || rightimpllbs[j] < rightproplbs[j]) )
    1684 {
    1685 /* var is fixed to upper bound whenever probingvar is fixed to 1.0
    1686 * and implication is not already known
    1687 * -> insert implication: probingvar == 1 => var >= leftproplbs[j]
    1688 */
    1689 /*SCIPdebugMsg(scip, "found implication <%s> == 1 => <%s> == %g\n",
    1690 SCIPvarGetName(probingvar), SCIPvarGetName(var), rightproplbs[j]);*/
    1691 SCIP_CALL( SCIPaddVarImplication(scip, probingvar, TRUE, var, SCIP_BOUNDTYPE_LOWER, rightproplbs[j],
    1692 cutoff, &nboundchanges) );
    1693 (*nimplications)++;
    1694 (*nchgbds) += nboundchanges;
    1695
    1696 if( *cutoff )
    1697 {
    1698 SCIPdebugMsg(scip, "analyzing probing deduction of <%s> led to an infeasible implication <%s> == 1 => <%s> == %g\n",
    1699 SCIPvarGetName(probingvar), SCIPvarGetName(probingvar), SCIPvarGetName(var), rightproplbs[j]);
    1700 }
    1701 }
    1703 {
    1704 /* check for implications for lower or upper bounds (only store implications with bounds tightened at least by 0.5)
    1705 * in case of binary variables, this should have been handled in the previous cases, since every boundchange also fixes the variable
    1706 */
    1707 if( leftpropubs[j] < newub - 0.5 && (leftimplubs == NULL || leftpropubs[j] < leftimplubs[j]) )
    1708 {
    1709 /* insert implication: probingvar == 0 => var <= leftpropubs[j] */
    1710 /*SCIPdebugMsg(scip, "found implication <%s> == 0 => <%s>[%g,%g] <= %g\n",
    1711 SCIPvarGetName(probingvar), SCIPvarGetName(var), newlb, newub, leftpropubs[j]);*/
    1712 SCIP_CALL( SCIPaddVarImplication(scip, probingvar, FALSE, var, SCIP_BOUNDTYPE_UPPER, leftpropubs[j],
    1713 cutoff, &nboundchanges) );
    1714 (*nimplications)++;
    1715 (*nchgbds) += nboundchanges;
    1716
    1717 if( *cutoff )
    1718 {
    1719 SCIPdebugMsg(scip, "analyzing probing deduction of <%s> led to an infeasible implication <%s> == 0 => <%s> <= %g\n",
    1720 SCIPvarGetName(probingvar), SCIPvarGetName(probingvar), SCIPvarGetName(var), leftpropubs[j]);
    1721 }
    1722 }
    1723 if( leftproplbs[j] > newlb + 0.5 && (leftimpllbs == NULL || leftproplbs[j] > leftimpllbs[j]) && !*cutoff )
    1724 {
    1725 /* insert implication: probingvar == 0 => var >= leftproplbs[j] */
    1726 /*SCIPdebugMsg(scip, "found implication <%s> == 0 => <%s>[%g,%g] >= %g\n",
    1727 SCIPvarGetName(probingvar), SCIPvarGetName(var), newlb, newub, leftproplbs[j]);*/
    1728 SCIP_CALL( SCIPaddVarImplication(scip, probingvar, FALSE, var, SCIP_BOUNDTYPE_LOWER, leftproplbs[j],
    1729 cutoff, &nboundchanges) );
    1730 (*nimplications)++;
    1731 (*nchgbds) += nboundchanges;
    1732
    1733 if( *cutoff )
    1734 {
    1735 SCIPdebugMsg(scip, "analyzing probing deduction of <%s> led to an infeasible implication <%s> == 0 => <%s> >= %g\n",
    1736 SCIPvarGetName(probingvar), SCIPvarGetName(probingvar), SCIPvarGetName(var), leftproplbs[j]);
    1737 }
    1738 }
    1739 if( rightpropubs[j] < newub - 0.5 && (rightimplubs == NULL || rightpropubs[j] < rightimplubs[j]) && !*cutoff )
    1740 {
    1741 /* insert implication: probingvar == 1 => var <= rightpropubs[j] */
    1742 /*SCIPdebugMsg(scip, "found implication <%s> == 1 => <%s>[%g,%g] <= %g\n",
    1743 SCIPvarGetName(probingvar), SCIPvarGetName(var), newlb, newub, rightpropubs[j]);*/
    1744 SCIP_CALL( SCIPaddVarImplication(scip, probingvar, TRUE, var, SCIP_BOUNDTYPE_UPPER, rightpropubs[j],
    1745 cutoff, &nboundchanges) );
    1746 (*nimplications)++;
    1747 (*nchgbds) += nboundchanges;
    1748
    1749 if( *cutoff )
    1750 {
    1751 SCIPdebugMsg(scip, "analyzing probing deduction of <%s> led to an infeasible implication <%s> == 1 => <%s> <= %g\n",
    1752 SCIPvarGetName(probingvar), SCIPvarGetName(probingvar), SCIPvarGetName(var), rightpropubs[j]);
    1753 }
    1754 }
    1755 if( rightproplbs[j] > newlb + 0.5 && (rightimpllbs == NULL || rightproplbs[j] > rightimpllbs[j]) && !*cutoff )
    1756 {
    1757 /* insert implication: probingvar == 1 => var >= rightproplbs[j] */
    1758 /*SCIPdebugMsg(scip, "found implication <%s> == 1 => <%s>[%g,%g] >= %g\n",
    1759 SCIPvarGetName(probingvar), SCIPvarGetName(var), newlb, newub, rightproplbs[j]);*/
    1760 SCIP_CALL( SCIPaddVarImplication(scip, probingvar, TRUE, var, SCIP_BOUNDTYPE_LOWER, rightproplbs[j],
    1761 cutoff, &nboundchanges) );
    1762 (*nimplications)++;
    1763 (*nchgbds) += nboundchanges;
    1764
    1765 if( *cutoff )
    1766 {
    1767 SCIPdebugMsg(scip, "analyzing probing deduction of <%s> led to an infeasible implication <%s> == 1 => <%s> <= %g\n",
    1768 SCIPvarGetName(probingvar), SCIPvarGetName(probingvar), SCIPvarGetName(var), rightproplbs[j]);
    1769 }
    1770 }
    1771 }
    1772 }
    1773 }
    1774
    1775 return SCIP_OKAY;
    1776}
    static long bound
    #define NULL
    Definition: def.h:257
    #define SCIP_Longint
    Definition: def.h:150
    #define SCIP_Bool
    Definition: def.h:100
    #define MIN(x, y)
    Definition: def.h:233
    #define SCIP_STRINGEQ(name, reference, retcode)
    Definition: def.h:454
    #define SCIP_Real
    Definition: def.h:165
    #define ABS(x)
    Definition: def.h:225
    #define TRUE
    Definition: def.h:102
    #define FALSE
    Definition: def.h:103
    #define MAX(x, y)
    Definition: def.h:229
    #define SCIP_LONGINT_FORMAT
    Definition: def.h:157
    #define SCIP_CALL(x)
    Definition: def.h:364
    SCIP_Bool SCIPisStopped(SCIP *scip)
    Definition: scip_general.c:767
    SCIP_STAGE SCIPgetStage(SCIP *scip)
    Definition: scip_general.c:444
    int SCIPgetNIntVars(SCIP *scip)
    Definition: scip_prob.c:2340
    int SCIPgetNImplVars(SCIP *scip)
    Definition: scip_prob.c:2387
    const char * SCIPgetProbName(SCIP *scip)
    Definition: scip_prob.c:1242
    int SCIPgetNVars(SCIP *scip)
    Definition: scip_prob.c:2246
    SCIP_VAR ** SCIPgetVars(SCIP *scip)
    Definition: scip_prob.c:2201
    int SCIPgetNBinVars(SCIP *scip)
    Definition: scip_prob.c:2293
    int SCIPgetNTotalVars(SCIP *scip)
    Definition: scip_prob.c:3064
    void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:225
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    SCIP_Real SCIPselectSimpleValue(SCIP_Real lb, SCIP_Real ub, SCIP_Longint maxdnom)
    Definition: misc.c:10041
    SCIP_RETCODE SCIPapplyProbingVar(SCIP *scip, SCIP_VAR **vars, int nvars, int probingpos, SCIP_BOUNDTYPE boundtype, SCIP_Real bound, int maxproprounds, SCIP_Real *impllbs, SCIP_Real *implubs, SCIP_Real *proplbs, SCIP_Real *propubs, SCIP_Bool *cutoff)
    SCIP_RETCODE SCIPanalyzeDeductionsProbing(SCIP *scip, SCIP_VAR *probingvar, SCIP_Real leftub, SCIP_Real rightlb, int nvars, SCIP_VAR **vars, SCIP_Real *leftimpllbs, SCIP_Real *leftimplubs, SCIP_Real *leftproplbs, SCIP_Real *leftpropubs, SCIP_Real *rightimpllbs, SCIP_Real *rightimplubs, SCIP_Real *rightproplbs, SCIP_Real *rightpropubs, int *nfixedvars, int *naggrvars, int *nimplications, int *nchgbds, SCIP_Bool *cutoff)
    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
    void SCIPswapPointers(void **pointer1, void **pointer2)
    Definition: misc.c:10511
    SCIP_RETCODE SCIPincludePropProbing(SCIP *scip)
    SCIP_RETCODE SCIPgetLPBranchCands(SCIP *scip, SCIP_VAR ***lpcands, SCIP_Real **lpcandssol, SCIP_Real **lpcandsfrac, int *nlpcands, int *npriolpcands, int *nfracimplvars)
    Definition: scip_branch.c:402
    SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
    Definition: scip_lp.c:174
    #define SCIPfreeMemoryArrayNull(scip, ptr)
    Definition: scip_mem.h:81
    #define SCIPreallocMemoryArray(scip, ptr, newnum)
    Definition: scip_mem.h:70
    #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 SCIPduplicateMemoryArray(scip, ptr, source, num)
    Definition: scip_mem.h:76
    #define SCIPfreeMemoryArray(scip, ptr)
    Definition: scip_mem.h:80
    #define SCIPfreeBlockMemory(scip, ptr)
    Definition: scip_mem.h:108
    #define SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    SCIP_Longint SCIPnodeGetNumber(SCIP_NODE *node)
    Definition: tree.c:8513
    int SCIPnodeGetDepth(SCIP_NODE *node)
    Definition: tree.c:8523
    SCIP_RETCODE SCIPchgVarUbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
    Definition: scip_probing.c:346
    SCIP_RETCODE SCIPchgVarLbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
    Definition: scip_probing.c:302
    SCIP_RETCODE SCIPpropagateProbing(SCIP *scip, int maxproprounds, SCIP_Bool *cutoff, SCIP_Longint *ndomredsfound)
    Definition: scip_probing.c:581
    SCIP_Bool SCIPinProbing(SCIP *scip)
    Definition: scip_probing.c:98
    SCIP_RETCODE SCIPstartProbing(SCIP *scip)
    Definition: scip_probing.c:120
    SCIP_RETCODE SCIPpropagateProbingImplications(SCIP *scip, SCIP_Bool *cutoff)
    Definition: scip_probing.c:690
    SCIP_RETCODE SCIPendProbing(SCIP *scip)
    Definition: scip_probing.c:261
    void SCIPpropSetData(SCIP_PROP *prop, SCIP_PROPDATA *propdata)
    Definition: prop.c:801
    SCIP_RETCODE SCIPsetPropInitsol(SCIP *scip, SCIP_PROP *prop, SCIP_DECL_PROPINITSOL((*propinitsol)))
    Definition: scip_prop.c:219
    SCIP_RETCODE SCIPsetPropResprop(SCIP *scip, SCIP_PROP *prop, SCIP_DECL_PROPRESPROP((*propresprop)))
    Definition: scip_prop.c:316
    SCIP_PROPDATA * SCIPpropGetData(SCIP_PROP *prop)
    Definition: prop.c:791
    SCIP_RETCODE SCIPsetPropPresol(SCIP *scip, SCIP_PROP *prop, SCIP_DECL_PROPPRESOL((*proppresol)), int presolpriority, int presolmaxrounds, SCIP_PRESOLTIMING presoltiming)
    Definition: scip_prop.c:283
    SCIP_RETCODE SCIPsetPropExitpre(SCIP *scip, SCIP_PROP *prop, SCIP_DECL_PROPEXITPRE((*propexitpre)))
    Definition: scip_prop.c:267
    const char * SCIPpropGetName(SCIP_PROP *prop)
    Definition: prop.c:951
    SCIP_RETCODE SCIPsetPropExit(SCIP *scip, SCIP_PROP *prop, SCIP_DECL_PROPEXIT((*propexit)))
    Definition: scip_prop.c:203
    SCIP_RETCODE SCIPsetPropInit(SCIP *scip, SCIP_PROP *prop, SCIP_DECL_PROPINIT((*propinit)))
    Definition: scip_prop.c:187
    SCIP_RETCODE SCIPsetPropInitpre(SCIP *scip, SCIP_PROP *prop, SCIP_DECL_PROPINITPRE((*propinitpre)))
    Definition: scip_prop.c:251
    SCIP_Real SCIPpropGetTime(SCIP_PROP *prop)
    Definition: prop.c:1066
    SCIP_RETCODE SCIPsetPropFree(SCIP *scip, SCIP_PROP *prop, SCIP_DECL_PROPFREE((*propfree)))
    Definition: scip_prop.c:171
    SCIP_RETCODE SCIPsetPropCopy(SCIP *scip, SCIP_PROP *prop, SCIP_DECL_PROPCOPY((*propcopy)))
    Definition: scip_prop.c:155
    SCIP_RETCODE SCIPincludePropBasic(SCIP *scip, SCIP_PROP **propptr, const char *name, const char *desc, int priority, int freq, SCIP_Bool delay, SCIP_PROPTIMING timingmask, SCIP_DECL_PROPEXEC((*propexec)), SCIP_PROPDATA *propdata)
    Definition: scip_prop.c:118
    int SCIPgetNRuns(SCIP *scip)
    SCIP_Real SCIPgetSolvingTime(SCIP *scip)
    Definition: scip_timing.c:378
    SCIP_Bool SCIPisUbBetter(SCIP *scip, SCIP_Real newub, SCIP_Real oldlb, SCIP_Real oldub)
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisLbBetter(SCIP *scip, SCIP_Real newlb, SCIP_Real oldlb, SCIP_Real oldub)
    SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPceil(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_Real SCIPepsilon(SCIP *scip)
    SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    int SCIPgetDepth(SCIP *scip)
    Definition: scip_tree.c:672
    SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
    Definition: scip_tree.c:91
    SCIP_RETCODE SCIPtightenVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
    Definition: scip_var.c:6401
    SCIP_Bool SCIPvarIsDeleted(SCIP_VAR *var)
    Definition: var.c:23566
    SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
    Definition: var.c:23674
    SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
    Definition: var.c:23510
    int SCIPvarGetNImpls(SCIP_VAR *var, SCIP_Bool varfixing)
    Definition: var.c:24600
    int SCIPvarGetNLocksUpType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
    Definition: var.c:4380
    SCIP_Bool SCIPvarIsImpliedIntegral(SCIP_VAR *var)
    Definition: var.c:23530
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24300
    SCIP_RETCODE SCIPaggregateVars(SCIP *scip, SCIP_VAR *varx, SCIP_VAR *vary, SCIP_Real scalarx, SCIP_Real scalary, SCIP_Real rhs, SCIP_Bool *infeasible, SCIP_Bool *redundant, SCIP_Bool *aggregated)
    Definition: scip_var.c:10550
    SCIP_RETCODE SCIPtightenVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
    Definition: scip_var.c:6651
    SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
    Definition: var.c:23485
    SCIP_RETCODE SCIPaddVarVub(SCIP *scip, SCIP_VAR *var, SCIP_VAR *vubvar, SCIP_Real vubcoef, SCIP_Real vubconstant, SCIP_Bool *infeasible, int *nbdchgs)
    Definition: scip_var.c:8680
    int SCIPvarGetIndex(SCIP_VAR *var)
    Definition: var.c:23684
    SCIP_RETCODE SCIPaddVarVlb(SCIP *scip, SCIP_VAR *var, SCIP_VAR *vlbvar, SCIP_Real vlbcoef, SCIP_Real vlbconstant, SCIP_Bool *infeasible, int *nbdchgs)
    Definition: scip_var.c:8621
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23299
    SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
    Definition: scip_var.c:1887
    SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
    Definition: var.c:23522
    SCIP_RETCODE SCIPaddVarImplication(SCIP *scip, SCIP_VAR *var, SCIP_Bool varfixing, SCIP_VAR *implvar, SCIP_BOUNDTYPE impltype, SCIP_Real implbound, SCIP_Bool *infeasible, int *nbdchgs)
    Definition: scip_var.c:8740
    int SCIPvarGetNCliques(SCIP_VAR *var, SCIP_Bool varfixing)
    Definition: var.c:24674
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24266
    SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
    Definition: scip_var.c:10318
    int SCIPvarGetNLocksDownType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
    Definition: var.c:4322
    void SCIPenableVarHistory(SCIP *scip)
    Definition: scip_var.c:11083
    SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:1853
    void SCIPfreeRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen)
    SCIP_Real SCIPrandomGetReal(SCIP_RANDNUMGEN *randnumgen, SCIP_Real minrandval, SCIP_Real maxrandval)
    Definition: misc.c:10245
    SCIP_RETCODE SCIPcreateRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen, unsigned int initialseed, SCIP_Bool useglobalseed)
    void SCIPsortDownRealPtr(SCIP_Real *realarray, void **ptrarray, int len)
    memory allocation routines
    #define BMSclearMemoryArray(ptr, num)
    Definition: memory.h:130
    #define PROP_PRESOL_MAXROUNDS
    Definition: prop_probing.c:69
    #define PROP_PRESOLTIMING
    Definition: prop_probing.c:68
    #define PROP_DESC
    Definition: prop_probing.c:61
    static SCIP_DECL_PROPINIT(propInitProbing)
    Definition: prop_probing.c:770
    #define MAXDNOM
    Definition: prop_probing.c:71
    #define PROP_NAME
    Definition: prop_probing.c:60
    static SCIP_DECL_PROPCOPY(propCopyProbing)
    Definition: prop_probing.c:734
    static SCIP_DECL_PROPEXIT(propExitProbing)
    Definition: prop_probing.c:789
    static SCIP_DECL_PROPEXITPRE(propExitpreProbing)
    Definition: prop_probing.c:824
    #define DEFAULT_MAXUSELESS
    Definition: prop_probing.c:88
    static SCIP_DECL_PROPINITSOL(propInitsolProbing)
    Definition: prop_probing.c:846
    static SCIP_DECL_PROPFREE(propFreeProbing)
    Definition: prop_probing.c:750
    static SCIP_DECL_PROPPRESOL(propPresolProbing)
    Definition: prop_probing.c:865
    #define DEFAULT_MAXDEPTH
    Definition: prop_probing.c:94
    #define DEFAULT_MAXTOTALUSELESS
    Definition: prop_probing.c:90
    #define PROP_DELAY
    Definition: prop_probing.c:65
    static SCIP_RETCODE applyProbing(SCIP *scip, SCIP_PROPDATA *propdata, SCIP_VAR **vars, int nvars, int nbinvars, int *startidx, int *nfixedvars, int *naggrvars, int *nchgbds, int oldnfixedvars, int oldnaggrvars, SCIP_Bool *delay, SCIP_Bool *cutoff)
    Definition: prop_probing.c:343
    #define DEFAULT_PROPROUNDS
    Definition: prop_probing.c:85
    static SCIP_RETCODE initPropdata(SCIP_PROPDATA *propdata)
    Definition: prop_probing.c:139
    #define PROP_TIMING
    Definition: prop_probing.c:62
    static SCIP_RETCODE freeSortedvars(SCIP *scip, SCIP_PROPDATA *propdata)
    Definition: prop_probing.c:167
    static SCIP_DECL_PROPEXEC(propExecProbing)
    Definition: prop_probing.c:999
    #define DEFAULT_RANDSEED
    Definition: prop_probing.c:95
    #define DEFAULT_MAXSUMUSELESS
    Definition: prop_probing.c:92
    static SCIP_RETCODE sortVariables(SCIP *scip, SCIP_PROPDATA *propdata, SCIP_VAR **vars, int nvars, int firstidx)
    Definition: prop_probing.c:196
    #define DEFAULT_MAXRUNS
    Definition: prop_probing.c:84
    #define PROP_FREQ
    Definition: prop_probing.c:64
    static SCIP_DECL_PROPINITPRE(propInitpreProbing)
    Definition: prop_probing.c:809
    #define PROP_PRIORITY
    Definition: prop_probing.c:63
    static SCIP_DECL_PROPRESPROP(propRespropProbing)
    #define PROP_PRESOL_PRIORITY
    Definition: prop_probing.c:67
    #define DEFAULT_MAXFIXINGS
    Definition: prop_probing.c:86
    probing propagator
    public methods for message output
    #define SCIPdebug(x)
    Definition: pub_message.h:93
    public data structures and miscellaneous methods
    methods for sorting joint arrays of various types
    public methods for propagators
    public methods for branch and bound tree
    public methods for problem variables
    public methods for branching rule plugins and branching
    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 propagator plugins
    public methods for random numbers
    public methods for querying solving statistics
    public methods for timing
    public methods for the branch-and-bound tree
    public methods for SCIP variables
    @ SCIP_BOUNDTYPE_UPPER
    Definition: type_lp.h:58
    @ SCIP_BOUNDTYPE_LOWER
    Definition: type_lp.h:57
    enum SCIP_BoundType SCIP_BOUNDTYPE
    Definition: type_lp.h:60
    @ SCIP_LPSOLSTAT_OPTIMAL
    Definition: type_lp.h:44
    enum SCIP_VerbLevel SCIP_VERBLEVEL
    Definition: type_message.h:64
    @ SCIP_VERBLEVEL_HIGH
    Definition: type_message.h:61
    @ SCIP_VERBLEVEL_FULL
    Definition: type_message.h:62
    struct SCIP_PropData SCIP_PROPDATA
    Definition: type_prop.h:52
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_CUTOFF
    Definition: type_result.h:48
    @ SCIP_REDUCEDDOM
    Definition: type_result.h:51
    @ SCIP_DIDNOTFIND
    Definition: type_result.h:44
    @ SCIP_SUCCESS
    Definition: type_result.h:58
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_INVALIDCALL
    Definition: type_retcode.h:51
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_STAGE_PRESOLVING
    Definition: type_set.h:49
    @ SCIP_STAGE_SOLVING
    Definition: type_set.h:53
    @ SCIP_VARTYPE_BINARY
    Definition: type_var.h:64
    @ SCIP_LOCKTYPE_MODEL
    Definition: type_var.h:141