Scippy

    SCIP

    Solving Constraint Integer Programs

    scip_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-2025 Zuse Institute Berlin (ZIB) */
    7/* */
    8/* Licensed under the Apache License, Version 2.0 (the "License"); */
    9/* you may not use this file except in compliance with the License. */
    10/* You may obtain a copy of the License at */
    11/* */
    12/* http://www.apache.org/licenses/LICENSE-2.0 */
    13/* */
    14/* Unless required by applicable law or agreed to in writing, software */
    15/* distributed under the License is distributed on an "AS IS" BASIS, */
    16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
    17/* See the License for the specific language governing permissions and */
    18/* limitations under the License. */
    19/* */
    20/* You should have received a copy of the Apache-2.0 license */
    21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
    22/* */
    23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    24
    25/**@file scip_probing.c
    26 * @ingroup OTHER_CFILES
    27 * @brief public methods for the probing mode
    28 * @author Tobias Achterberg
    29 * @author Timo Berthold
    30 * @author Gerald Gamrath
    31 * @author Leona Gottwald
    32 * @author Stefan Heinz
    33 * @author Gregor Hendel
    34 * @author Thorsten Koch
    35 * @author Alexander Martin
    36 * @author Marc Pfetsch
    37 * @author Michael Winkler
    38 * @author Kati Wolter
    39 *
    40 * @todo check all SCIP_STAGE_* switches, and include the new stages TRANSFORMED and INITSOLVE
    41 */
    42
    43/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    44
    46#include "scip/conflict.h"
    47#include "scip/cons.h"
    48#include "scip/debug.h"
    49#include "scip/heur.h"
    50#include "scip/lp.h"
    51#include "scip/prob.h"
    52#include "scip/pub_message.h"
    53#include "scip/pub_misc.h"
    54#include "scip/pub_relax.h"
    55#include "scip/pub_tree.h"
    56#include "scip/pub_var.h"
    57#include "scip/relax.h"
    58#include "scip/scip_exact.h"
    59#include "scip/scip_general.h"
    60#include "scip/scip_lp.h"
    61#include "scip/scip_mem.h"
    62#include "scip/scip_message.h"
    63#include "scip/scip_numerics.h"
    64#include "scip/scip_prob.h"
    65#include "scip/scip_probing.h"
    67#include "scip/scip_tree.h"
    68#include "scip/sepastore.h"
    69#include "scip/set.h"
    70#include "scip/solve.h"
    71#include "scip/stat.h"
    72#include "scip/struct_lp.h"
    73#include "scip/struct_mem.h"
    74#include "scip/struct_scip.h"
    75#include "scip/struct_set.h"
    76#include "scip/struct_stat.h"
    77#include "scip/struct_tree.h"
    78#include "scip/struct_var.h"
    79#include "scip/tree.h"
    80#include "scip/var.h"
    81
    82/** returns whether we are in probing mode; probing mode is activated via SCIPstartProbing() and stopped
    83 * via SCIPendProbing()
    84 *
    85 * @return TRUE, if SCIP is currently in probing mode, otherwise FALSE
    86 *
    87 * @pre This method can be called if @p scip is in one of the following stages:
    88 * - \ref SCIP_STAGE_TRANSFORMED
    89 * - \ref SCIP_STAGE_INITPRESOLVE
    90 * - \ref SCIP_STAGE_PRESOLVING
    91 * - \ref SCIP_STAGE_EXITPRESOLVE
    92 * - \ref SCIP_STAGE_PRESOLVED
    93 * - \ref SCIP_STAGE_INITSOLVE
    94 * - \ref SCIP_STAGE_SOLVING
    95 * - \ref SCIP_STAGE_SOLVED
    96 * - \ref SCIP_STAGE_EXITSOLVE
    97 */
    99 SCIP* scip /**< SCIP data structure */
    100 )
    101{
    103
    104 return SCIPtreeProbing(scip->tree);
    105}
    106
    107/** initiates probing, making methods SCIPnewProbingNode(), SCIPbacktrackProbing(), SCIPchgVarLbProbing(),
    108 * SCIPchgVarUbProbing(), SCIPfixVarProbing(), SCIPpropagateProbing(), and SCIPsolveProbingLP() available
    109 *
    110 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    111 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    112 *
    113 * @pre This method can be called if @p scip is in one of the following stages:
    114 * - \ref SCIP_STAGE_PRESOLVING
    115 * - \ref SCIP_STAGE_SOLVING
    116 *
    117 * @note The collection of variable statistics is turned off during probing. If these statistics should be collected
    118 * during probing use the method SCIPenableVarHistory() to turn the collection explicitly on.
    119 */
    121 SCIP* scip /**< SCIP data structure */
    122 )
    123{
    125
    126 if( SCIPtreeProbing(scip->tree) )
    127 {
    128 SCIPerrorMessage("already in probing mode\n");
    129 return SCIP_INVALIDCALL;
    130 }
    131
    132 if( scip->lp != NULL && SCIPlpDiving(scip->lp) )
    133 {
    134 SCIPerrorMessage("cannot start probing while in diving mode\n");
    135 return SCIP_INVALIDCALL;
    136 }
    137
    138 /* use a different separation storage for probing mode; otherwise SCIP will remove the cuts that are currently in the
    139 * separation storage after solving an LP in probing mode
    140 */
    141 if( scip->sepastore != NULL )
    142 {
    143 assert(scip->sepastoreprobing != NULL);
    144 SCIPswapPointers((void**)&scip->sepastore, (void**)&scip->sepastoreprobing);
    145 }
    146
    147 SCIP_CALL( SCIPtreeStartProbing(scip->tree, scip->mem->probmem, scip->set, scip->lp, scip->relaxation, scip->transprob, FALSE) );
    148
    149 /* disables the collection of any statistic for a variable */
    151
    152 return SCIP_OKAY;
    153}
    154
    155/** creates a new probing sub node, whose changes can be undone by backtracking to a higher node in the probing path
    156 * with a call to SCIPbacktrackProbing();
    157 * using a sub node for each set of probing bound changes can improve conflict analysis
    158 *
    159 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    160 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    161 *
    162 * @pre This method can be called if @p scip is in one of the following stages:
    163 * - \ref SCIP_STAGE_PRESOLVING
    164 * - \ref SCIP_STAGE_SOLVING
    165 */
    167 SCIP* scip /**< SCIP data structure */
    168 )
    169{
    170 SCIP_RETCODE retcode;
    171
    173
    174 if( !SCIPtreeProbing(scip->tree) )
    175 {
    176 SCIPerrorMessage("not in probing mode\n");
    177 return SCIP_INVALIDCALL;
    178 }
    179
    180 retcode = SCIPtreeCreateProbingNode(scip->tree, scip->mem->probmem, scip->set, scip->lp);
    181
    182 if( retcode == SCIP_MAXDEPTHLEVEL )
    183 {
    184 SCIPwarningMessage(scip, "probing reached maximal depth; it should be stopped\n");
    185 }
    186 SCIP_CALL( retcode );
    187
    188 return SCIP_OKAY;
    189}
    190
    191/** returns the current probing depth
    192 *
    193 * @return the probing depth, i.e. the number of probing sub nodes existing in the probing path
    194 *
    195 * @pre This method can be called if @p scip is in one of the following stages:
    196 * - \ref SCIP_STAGE_PRESOLVING
    197 * - \ref SCIP_STAGE_SOLVING
    198 */
    200 SCIP* scip /**< SCIP data structure */
    201 )
    202{
    204
    205 if( !SCIPtreeProbing(scip->tree) )
    206 {
    207 SCIPerrorMessage("not in probing mode\n");
    208 SCIPABORT();
    209 return -1; /*lint !e527*/
    210 }
    211
    212 return SCIPtreeGetProbingDepth(scip->tree);
    213}
    214
    215/** undoes all changes to the problem applied in probing up to the given probing depth;
    216 * the changes of the probing node of the given probing depth are the last ones that remain active;
    217 * changes that were applied before calling SCIPnewProbingNode() cannot be undone
    218 *
    219 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    220 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    221 *
    222 * @pre This method can be called if @p scip is in one of the following stages:
    223 * - \ref SCIP_STAGE_PRESOLVING
    224 * - \ref SCIP_STAGE_SOLVING
    225 */
    227 SCIP* scip, /**< SCIP data structure */
    228 int probingdepth /**< probing depth of the node in the probing path that should be reactivated */
    229 )
    230{
    231 SCIP_CALL( SCIPcheckStage(scip, "SCIPbacktrackProbing", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
    232
    233 if( !SCIPtreeProbing(scip->tree) )
    234 {
    235 SCIPerrorMessage("not in probing mode\n");
    236 return SCIP_INVALIDCALL;
    237 }
    238 if( probingdepth < 0 || probingdepth > SCIPtreeGetProbingDepth(scip->tree) )
    239 {
    240 SCIPerrorMessage("backtracking probing depth %d out of current probing range [0,%d]\n",
    241 probingdepth, SCIPtreeGetProbingDepth(scip->tree));
    242 return SCIP_INVALIDDATA;
    243 }
    244
    245 SCIP_CALL( SCIPtreeBacktrackProbing(scip->tree, scip->reopt, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
    246 scip->origprob, scip->lp, scip->primal, scip->branchcand, scip->eventqueue, scip->eventfilter,
    247 scip->cliquetable, probingdepth) );
    248
    249 return SCIP_OKAY;
    250}
    251
    252/** quits probing and resets bounds and constraints to the focus node's environment
    253 *
    254 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    255 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    256 *
    257 * @pre This method can be called if @p scip is in one of the following stages:
    258 * - \ref SCIP_STAGE_PRESOLVING
    259 * - \ref SCIP_STAGE_SOLVING
    260 */
    262 SCIP* scip /**< SCIP data structure */
    263 )
    264{
    266
    267 if( !SCIPtreeProbing(scip->tree) )
    268 {
    269 SCIPerrorMessage("not in probing mode\n");
    270 return SCIP_INVALIDCALL;
    271 }
    272
    273 /* switch back from probing to normal operation mode and restore variables and constraints to focus node */
    274 SCIP_CALL( SCIPtreeEndProbing(scip->tree, scip->reopt, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
    275 scip->transprob, scip->origprob, scip->lp, scip->relaxation, scip->primal,
    276 scip->branchcand, scip->eventqueue, scip->eventfilter, scip->cliquetable) );
    277
    278 /* enables the collection of statistics for a variable */
    280
    281 /* switch to the original separation storage */
    282 if( scip->sepastore != NULL )
    283 {
    284 assert(scip->sepastoreprobing != NULL);
    285 SCIPswapPointers((void**)&scip->sepastore, (void**)&scip->sepastoreprobing);
    286 assert(SCIPsepastoreGetNCuts(scip->sepastoreprobing) == 0);
    287 }
    288
    289 return SCIP_OKAY;
    290}
    291
    292/** injects a change of variable's lower bound into current probing node; the same can also be achieved with a call to
    293 * SCIPchgVarLb(), but in this case, the bound change would be treated like a deduction instead of a branching decision
    294 *
    295 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    296 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    297 *
    298 * @pre This method can be called if @p scip is in one of the following stages:
    299 * - \ref SCIP_STAGE_PRESOLVING
    300 * - \ref SCIP_STAGE_SOLVING
    301 */
    303 SCIP* scip, /**< SCIP data structure */
    304 SCIP_VAR* var, /**< variable to change the bound for */
    305 SCIP_Real newbound /**< new value for bound */
    306 )
    307{
    309
    310 if( !SCIPtreeProbing(scip->tree) )
    311 {
    312 SCIPerrorMessage("not in probing mode\n");
    313 return SCIP_INVALIDCALL;
    314 }
    316
    317 SCIPvarAdjustLb(var, scip->set, &newbound);
    318
    319 /* ignore tightenings of lower bounds to +infinity during solving process */
    321 {
    322#ifndef NDEBUG
    323 SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
    324 SCIPvarGetLbLocal(var));
    325#endif
    326 return SCIP_OKAY;
    327 }
    328
    329 SCIP_CALL( SCIPnodeAddBoundchg(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
    330 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
    331 scip->eventfilter, scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, TRUE) );
    332
    333 return SCIP_OKAY;
    334}
    335
    336/** injects a change of variable's upper bound into current probing node; the same can also be achieved with a call to
    337 * SCIPchgVarUb(), but in this case, the bound change would be treated like a deduction instead of a branching decision
    338 *
    339 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    340 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    341 *
    342 * @pre This method can be called if @p scip is in one of the following stages:
    343 * - \ref SCIP_STAGE_PRESOLVING
    344 * - \ref SCIP_STAGE_SOLVING
    345 */
    347 SCIP* scip, /**< SCIP data structure */
    348 SCIP_VAR* var, /**< variable to change the bound for */
    349 SCIP_Real newbound /**< new value for bound */
    350 )
    351{
    353
    354 if( !SCIPtreeProbing(scip->tree) )
    355 {
    356 SCIPerrorMessage("not in probing mode\n");
    357 return SCIP_INVALIDCALL;
    358 }
    360
    361 SCIPvarAdjustUb(var, scip->set, &newbound);
    362
    363 /* ignore tightenings of upper bounds to -infinity during solving process */
    365 {
    366#ifndef NDEBUG
    367 SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
    368 SCIPvarGetUbLocal(var));
    369#endif
    370 return SCIP_OKAY;
    371 }
    372
    373 SCIP_CALL( SCIPnodeAddBoundchg(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
    374 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
    375 scip->eventfilter, scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, TRUE) );
    376
    377 return SCIP_OKAY;
    378}
    379
    380/** gets variable's objective value in current probing
    381 *
    382 * @return the variable's objective value in current probing.
    383 *
    384 * @pre This method can be called if @p scip is in one of the following stages:
    385 * - \ref SCIP_STAGE_SOLVING
    386 *
    387 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
    388 */
    390 SCIP* scip, /**< SCIP data structure */
    391 SCIP_VAR* var /**< variable to get the bound for */
    392 )
    393{
    394 assert(scip != NULL);
    395 assert(var != NULL);
    396
    398
    399 if( !SCIPtreeProbing(scip->tree) )
    400 {
    401 SCIPerrorMessage("not in probing mode\n");
    402 return SCIP_INVALID;
    403 }
    404
    405 return SCIPvarGetObjLP(var);
    406}
    407
    408/** injects a change of variable's bounds into current probing node to fix the variable to the specified value;
    409 * the same can also be achieved with a call to SCIPfixVar(), but in this case, the bound changes would be treated
    410 * like deductions instead of branching decisions
    411 *
    412 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    413 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    414 *
    415 * @pre This method can be called if @p scip is in one of the following stages:
    416 * - \ref SCIP_STAGE_PRESOLVING
    417 * - \ref SCIP_STAGE_SOLVING
    418 */
    420 SCIP* scip, /**< SCIP data structure */
    421 SCIP_VAR* var, /**< variable to change the bound for */
    422 SCIP_Real fixedval /**< value to fix variable to */
    423 )
    424{
    425 SCIP_Real fixlb;
    426 SCIP_Real fixub;
    427
    429
    430 if( !SCIPtreeProbing(scip->tree) )
    431 {
    432 SCIPerrorMessage("not in probing mode\n");
    433 return SCIP_INVALIDCALL;
    434 }
    436
    437 /* we adjust the fixing value here and compare the old bound with the adjusted values because otherwise,
    438 * it might happen that the unadjusted value is better and we add the boundchange,
    439 * but within SCIPnodeAddBoundchg() the bounds are adjusted - using the feasibility epsilon for integer variables -
    440 * and it is asserted, that the bound is still better than the old one which might then be incorrect.
    441 */
    442 fixlb = fixedval;
    443 fixub = fixedval;
    444 SCIPvarAdjustLb(var, scip->set, &fixlb);
    445 SCIPvarAdjustUb(var, scip->set, &fixub);
    446 assert(SCIPsetIsEQ(scip->set, fixlb, fixub));
    447
    448 if( SCIPsetIsGT(scip->set, fixlb, SCIPvarGetLbLocal(var)) )
    449 {
    450 SCIP_CALL( SCIPnodeAddBoundchg(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
    451 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
    452 scip->eventfilter, scip->cliquetable, var, fixlb, SCIP_BOUNDTYPE_LOWER, TRUE) );
    453 }
    454 if( SCIPsetIsLT(scip->set, fixub, SCIPvarGetUbLocal(var)) )
    455 {
    456 SCIP_CALL( SCIPnodeAddBoundchg(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
    457 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
    458 scip->eventfilter, scip->cliquetable, var, fixub, SCIP_BOUNDTYPE_UPPER, TRUE) );
    459 }
    460
    461 return SCIP_OKAY;
    462}
    463
    464/** changes (column) variable's objective value during probing mode
    465 *
    466 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    467 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    468 *
    469 * @pre This method can be called if @p scip is in one of the following stages:
    470 * - \ref SCIP_STAGE_PRESOLVING
    471 * - \ref SCIP_STAGE_SOLVING
    472 *
    473 * @pre The variable needs to be a column variable.
    474 */
    476 SCIP* scip, /**< SCIP data structure */
    477 SCIP_VAR* var, /**< variable to change the objective for */
    478 SCIP_Real newobj /**< new objective function value */
    479 )
    480{
    481 SCIP_NODE* node;
    482 SCIP_Real oldobj;
    483
    484 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarObjProbing", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
    485
    486 if( !SCIPtreeProbing(scip->tree) )
    487 {
    488 SCIPerrorMessage("not in probing mode\n");
    489 return SCIP_INVALIDCALL;
    490 }
    491
    492 /* get current probing node */
    493 node = SCIPtreeGetCurrentNode(scip->tree);
    495
    496 /* get old objective function value */
    497 oldobj = SCIPvarGetObj(var);
    498
    499 if( SCIPisEQ(scip, oldobj, newobj) )
    500 return SCIP_OKAY;
    501
    502 if( node->data.probingnode->nchgdobjs == 0 )
    503 {
    504 SCIP_CALL( SCIPallocMemoryArray(scip, &node->data.probingnode->origobjvars, 1) ); /*lint !e506*/
    505 SCIP_CALL( SCIPallocMemoryArray(scip, &node->data.probingnode->origobjvals, 1) ); /*lint !e506*/
    506 }
    507 else
    508 {
    511 }
    512
    514 node->data.probingnode->origobjvals[node->data.probingnode->nchgdobjs] = oldobj;
    515 ++node->data.probingnode->nchgdobjs;
    516 ++scip->tree->probingsumchgdobjs;
    517
    519
    520 /* inform tree and LP that the objective was changed and invalidate the LP's cutoff bound, since this has nothing to
    521 * do with the current objective value anymore; the cutoff bound is reset in SCIPendProbing()
    522 */
    523 if( !SCIPtreeProbingObjChanged(scip->tree) )
    524 {
    525 SCIP_CALL( SCIPlpSetCutoffbound(scip->lp, scip->set, scip->transprob, SCIPsetInfinity(scip->set)) );
    526
    529 }
    530 assert(SCIPisInfinity(scip, scip->lp->cutoffbound));
    531
    532 /* perform the objective change */
    533 SCIP_CALL( SCIPvarChgObj(var, scip->mem->probmem, scip->set, scip->transprob, scip->primal, scip->lp, scip->eventqueue, newobj) );
    534
    535 return SCIP_OKAY;
    536}
    537
    538/** returns whether the objective function has changed during probing mode
    539 *
    540 * @return \ref TRUE if objective has changed, \ref FALSE otherwise
    541 *
    542 * @pre This method can be called if @p scip is in one of the following stages:
    543 * - \ref SCIP_STAGE_TRANSFORMED
    544 * - \ref SCIP_STAGE_INITPRESOLVE
    545 * - \ref SCIP_STAGE_PRESOLVING
    546 * - \ref SCIP_STAGE_EXITPRESOLVE
    547 * - \ref SCIP_STAGE_PRESOLVED
    548 * - \ref SCIP_STAGE_INITSOLVE
    549 * - \ref SCIP_STAGE_SOLVING
    550 * - \ref SCIP_STAGE_SOLVED
    551 * - \ref SCIP_STAGE_EXITSOLVE
    552 */
    554 SCIP* scip /**< SCIP data structure */
    555 )
    556{
    557 assert(scip != NULL);
    558
    559 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisObjChangedProbing", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
    560
    561 return scip->tree != NULL && SCIPinProbing(scip) && SCIPtreeProbingObjChanged(scip->tree);
    562}
    563
    564/** applies domain propagation on the probing sub problem, that was changed after SCIPstartProbing() was called;
    565 * the propagated domains of the variables can be accessed with the usual bound accessing calls SCIPvarGetLbLocal()
    566 * and SCIPvarGetUbLocal(); the propagation is only valid locally, i.e. the local bounds as well as the changed
    567 * bounds due to SCIPchgVarLbProbing(), SCIPchgVarUbProbing(), and SCIPfixVarProbing() are used for propagation
    568 *
    569 * @note Conflict analysis can run if the propagation finds infeasibilities. SCIPpropagateProbing can even find
    570 * globally valid bound changes. For this reason, the function restores the original objective (i.e. undoes the changes
    571 * done by SCIPchgVarObjProbing before performing the propagation, as the propagators don't know that the objective
    572 * might have changed. Thus, SCIPpropagateProbing can have an effect on the problem after probing ends.
    573 *
    574 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    575 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    576 *
    577 * @pre This method can be called if @p scip is in one of the following stages:
    578 * - \ref SCIP_STAGE_PRESOLVING
    579 * - \ref SCIP_STAGE_SOLVING
    580 */
    582 SCIP* scip, /**< SCIP data structure */
    583 int maxproprounds, /**< maximal number of propagation rounds (-1: no limit, 0: parameter settings) */
    584 SCIP_Bool* cutoff, /**< pointer to store whether the probing node can be cut off */
    585 SCIP_Longint* ndomredsfound /**< pointer to store the number of domain reductions found, or NULL */
    586 )
    587{
    588 SCIP_VAR** objchgvars;
    589 SCIP_Real* objchgvals;
    590 SCIP_Bool changedobj;
    591 int nobjchg;
    592
    593 if( SCIPisExact(scip) )
    594 return SCIP_OKAY;
    595
    596 SCIP_CALL( SCIPcheckStage(scip, "SCIPpropagateProbing", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
    597
    598 if( !SCIPtreeProbing(scip->tree) )
    599 {
    600 SCIPerrorMessage("not in probing mode\n");
    601 return SCIP_INVALIDCALL;
    602 }
    603
    604 objchgvars = NULL;
    605 objchgvals = NULL;
    606 changedobj = FALSE;
    607 nobjchg = 0;
    608
    609 /* undo objective changes if we want to propagate during probing */
    610 if( scip->tree->probingobjchanged )
    611 {
    612 SCIP_VAR** vars;
    613 int nvars;
    614 int i;
    615
    616 vars = SCIPgetVars(scip);
    617 nvars = SCIPgetNVars(scip);
    618
    619 SCIP_CALL( SCIPallocBufferArray(scip, &objchgvals, MIN(nvars, scip->tree->probingsumchgdobjs)) );
    620 SCIP_CALL( SCIPallocBufferArray(scip, &objchgvars, MIN(nvars, scip->tree->probingsumchgdobjs)) );
    621 nobjchg = 0;
    622
    623 for( i = 0; i < nvars; ++i )
    624 {
    625 if( !SCIPisEQ(scip, vars[i]->unchangedobj, SCIPgetVarObjProbing(scip, vars[i])) )
    626 {
    627 objchgvars[nobjchg] = vars[i];
    628 objchgvals[nobjchg] = SCIPgetVarObjProbing(scip, vars[i]);
    629 ++nobjchg;
    630
    631 SCIP_CALL( SCIPvarChgObj(vars[i], scip->mem->probmem, scip->set, scip->transprob, scip->primal, scip->lp,
    632 scip->eventqueue, vars[i]->unchangedobj) );
    633 }
    634 }
    635 assert(nobjchg <= scip->tree->probingsumchgdobjs);
    636
    638 scip->tree->probingobjchanged = FALSE;
    639 changedobj = TRUE;
    640 }
    641
    642 if( ndomredsfound != NULL )
    643 *ndomredsfound = -(scip->stat->nprobboundchgs + scip->stat->nprobholechgs);
    644
    645 SCIP_CALL( SCIPpropagateDomains(scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
    646 scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->eventfilter,
    647 scip->conflict, scip->cliquetable, SCIPgetDepth(scip), maxproprounds, SCIP_PROPTIMING_ALWAYS, cutoff) );
    648
    649 if( ndomredsfound != NULL )
    650 *ndomredsfound += scip->stat->nprobboundchgs + scip->stat->nprobholechgs;
    651
    652 /* restore old objective function */
    653 if( changedobj )
    654 {
    655 int i;
    656
    657 assert(objchgvars != NULL);
    658 assert(objchgvals != NULL);
    659
    661 scip->tree->probingobjchanged = TRUE;
    662
    663 for( i = 0; i < nobjchg; ++i )
    664 {
    665 SCIP_CALL( SCIPvarChgObj(objchgvars[i], scip->mem->probmem, scip->set, scip->transprob, scip->primal,
    666 scip->lp, scip->eventqueue, objchgvals[i]) );
    667 }
    668
    669 SCIPfreeBufferArray(scip, &objchgvars);
    670 SCIPfreeBufferArray(scip, &objchgvals);
    671 }
    672
    673 return SCIP_OKAY;
    674}
    675
    676/** applies domain propagation on the probing sub problem, that was changed after SCIPstartProbing() was called;
    677 * only propagations of the binary variables fixed at the current probing node that are triggered by the implication
    678 * graph and the clique table are applied;
    679 * the propagated domains of the variables can be accessed with the usual bound accessing calls SCIPvarGetLbLocal()
    680 * and SCIPvarGetUbLocal(); the propagation is only valid locally, i.e. the local bounds as well as the changed
    681 * bounds due to SCIPchgVarLbProbing(), SCIPchgVarUbProbing(), and SCIPfixVarProbing() are used for propagation
    682 *
    683 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    684 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    685 *
    686 * @pre This method can be called if @p scip is in one of the following stages:
    687 * - \ref SCIP_STAGE_PRESOLVING
    688 * - \ref SCIP_STAGE_SOLVING
    689 */
    691 SCIP* scip, /**< SCIP data structure */
    692 SCIP_Bool* cutoff /**< pointer to store whether the probing node can be cut off */
    693 )
    694{
    695 SCIP_CALL( SCIPcheckStage(scip, "SCIPpropagateProbingImplications", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
    696
    697 if( !SCIPtreeProbing(scip->tree) )
    698 {
    699 SCIPerrorMessage("not in probing mode\n");
    700 return SCIP_INVALIDCALL;
    701 }
    702
    703 SCIP_CALL( SCIPnodePropagateImplics(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
    704 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
    705 scip->eventfilter, scip->cliquetable, cutoff) );
    706
    707 return SCIP_OKAY;
    708}
    709
    710/** solves the LP at the current probing node (cannot be applied at preprocessing stage) with or without pricing */
    711static
    713 SCIP* scip, /**< SCIP data structure */
    714 int itlim, /**< maximal number of LP iterations to perform, or -1 for no limit */
    715 SCIP_Bool pricing, /**< should pricing be applied? */
    716 SCIP_Bool pretendroot, /**< should the pricers be called as if we are at the root node? */
    717 SCIP_Bool displayinfo, /**< should info lines be displayed after each pricing round? */
    718 int maxpricerounds, /**< maximal number of pricing rounds (-1: no limit) */
    719 SCIP_Bool* lperror, /**< pointer to store whether an unresolved LP error occurred */
    720 SCIP_Bool* cutoff /**< pointer to store whether the probing LP was infeasible or the objective
    721 * limit was reached (or NULL, if not needed) */
    722 )
    723{
    724 SCIP_Bool initcutoff;
    725
    726 assert(lperror != NULL);
    728
    729 if( !SCIPtreeProbing(scip->tree) )
    730 {
    731 SCIPerrorMessage("not in probing mode\n");
    732 return SCIP_INVALIDCALL;
    733 }
    734 assert(SCIPtreeGetCurrentDepth(scip->tree) > 0);
    735
    736 SCIP_CALL( SCIPinitConssLP(scip->mem->probmem, scip->set, scip->sepastore, scip->cutpool, scip->stat, scip->transprob,
    737 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->eventfilter,
    738 scip->cliquetable, FALSE, FALSE, &initcutoff) );
    739
    740 if( initcutoff )
    741 {
    742 if( cutoff != NULL )
    743 *cutoff = TRUE;
    744
    745 return SCIP_OKAY;
    746 }
    747 else if( cutoff != NULL )
    748 *cutoff = FALSE;
    749
    750 /* load the LP state (if necessary) */
    751 SCIP_CALL( SCIPtreeLoadProbingLPState(scip->tree, scip->mem->probmem, scip->set, scip->transprob, scip->eventqueue, scip->lp) );
    752
    753 /* the LP is a relaxation if and only if the objective has not been changed */
    754 SCIPlpSetIsRelax(scip->lp, !scip->tree->probingobjchanged);
    755
    756 /* solve probing LP */
    757 SCIP_CALL( SCIPlpSolveAndEval(scip->lp, scip->set, scip->messagehdlr, scip->mem->probmem, scip->stat,
    758 scip->eventqueue, scip->eventfilter, scip->transprob, (SCIP_Longint)itlim, FALSE, FALSE, FALSE, FALSE, lperror) );
    759
    760 assert((*lperror) || SCIPlpGetSolstat(scip->lp) != SCIP_LPSOLSTAT_NOTSOLVED);
    761
    762 /* mark the probing node to have a solved LP */
    763 if( !(*lperror) )
    764 {
    765 SCIP_CALL( SCIPtreeMarkProbingNodeHasLP(scip->tree, scip->mem->probmem, scip->lp) );
    766
    767 /* call pricing */
    768 if( pricing )
    769 {
    770 SCIP_Bool mustsepa;
    771 int npricedcolvars;
    772 SCIP_Bool result;
    773
    774 mustsepa = FALSE;
    775 SCIP_CALL( SCIPpriceLoop(scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat, scip->transprob,
    776 scip->origprob, scip->primal, scip->tree, scip->reopt, scip->lp, scip->pricestore, scip->sepastore, scip->cutpool,
    777 scip->branchcand, scip->eventqueue, scip->eventfilter, scip->cliquetable, pretendroot, displayinfo,
    778 maxpricerounds, &npricedcolvars, &mustsepa, lperror, &result) );
    779
    780 /* mark the probing node again to update the LP size in the node and the tree path */
    781 if( !(*lperror) )
    782 {
    783 SCIP_CALL( SCIPtreeMarkProbingNodeHasLP(scip->tree, scip->mem->probmem, scip->lp) );
    784 }
    785 }
    786 }
    787
    788 /* remember that probing might have changed the LPi state; this holds even if solving returned with an LP error */
    789 scip->tree->probingsolvedlp = TRUE;
    790
    791 /* the LP is infeasible or the objective limit was reached */
    792 if( !(*lperror) && (SCIPlpGetSolstat(scip->lp) == SCIP_LPSOLSTAT_INFEASIBLE
    794 (SCIPlpGetSolstat(scip->lp) == SCIP_LPSOLSTAT_OPTIMAL && !scip->tree->probingobjchanged
    796 {
    797 /* analyze the infeasible LP (only if all columns are in the LP and no external pricers exist) */
    798 if( SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->tree->probingobjchanged )
    799 {
    800 SCIP_CALL( SCIPconflictAnalyzeLP(scip->conflict, scip->conflictstore, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
    801 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->eventfilter, scip->cliquetable, NULL) );
    802 }
    803
    804 if( cutoff != NULL )
    805 *cutoff = TRUE;
    806 }
    807
    808 return SCIP_OKAY;
    809}
    810
    811/** solves the LP at the current probing node (cannot be applied at preprocessing stage);
    812 * no separation or pricing is applied
    813 *
    814 * The LP has to be constructed before (you can use SCIPisLPConstructed() or SCIPconstructLP()).
    815 *
    816 * @note if the LP is infeasible or the objective limit is reached, and if all columns are in the LP and no external
    817 * pricers exist then conflict analysis will be run. This can have an effect on the problem after probing ends.
    818 *
    819 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    820 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    821 *
    822 * @pre This method can be called if @p scip is in one of the following stages:
    823 * - \ref SCIP_STAGE_SOLVING
    824 */
    826 SCIP* scip, /**< SCIP data structure */
    827 int itlim, /**< maximal number of LP iterations to perform, or -1 for no limit */
    828 SCIP_Bool* lperror, /**< pointer to store whether an unresolved LP error occurred */
    829 SCIP_Bool* cutoff /**< pointer to store whether the probing LP was infeasible or the objective
    830 * limit was reached (or NULL, if not needed) */
    831 )
    832{
    834
    835 SCIP_CALL( solveProbingLP(scip, itlim, FALSE, FALSE, FALSE, -1, lperror, cutoff) );
    836
    837 return SCIP_OKAY;
    838}
    839
    840/** solves the LP at the current probing node (cannot be applied at preprocessing stage) and applies pricing
    841 * until the LP is solved to optimality; no separation is applied
    842 *
    843 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    844 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    845 *
    846 * @pre This method can be called if @p scip is in one of the following stages:
    847 * - \ref SCIP_STAGE_SOLVING
    848 */
    850 SCIP* scip, /**< SCIP data structure */
    851 SCIP_Bool pretendroot, /**< should the pricers be called as if we were at the root node? */
    852 SCIP_Bool displayinfo, /**< should info lines be displayed after each pricing round? */
    853 int maxpricerounds, /**< maximal number of pricing rounds (-1: no limit);
    854 * a finite limit means that the LP might not be solved to optimality! */
    855 SCIP_Bool* lperror, /**< pointer to store whether an unresolved LP error occurred */
    856 SCIP_Bool* cutoff /**< pointer to store whether the probing LP was infeasible or the objective
    857 * limit was reached (or NULL, if not needed) */
    858 )
    859{
    860 SCIP_CALL( SCIPcheckStage(scip, "SCIPsolveProbingLPWithPricing", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
    861
    862 SCIP_CALL( solveProbingLP(scip, -1, TRUE, pretendroot, displayinfo, maxpricerounds, lperror, cutoff) );
    863
    864 return SCIP_OKAY;
    865}
    866
    867/** sets the LP state for the current probing node
    868 *
    869 * @note state and norms are stored at the node and later released by SCIP; therefore, the pointers are set
    870 * to NULL by the method
    871 *
    872 * @note the pointers to state and norms must not be NULL; however, they may point to a NULL pointer if the
    873 * respective information should not be set
    874 *
    875 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    876 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    877 *
    878 * @pre This method can be called if @p scip is in one of the following stages:
    879 * - \ref SCIP_STAGE_PRESOLVING
    880 * - \ref SCIP_STAGE_SOLVING
    881 */
    883 SCIP* scip, /**< SCIP data structure */
    884 SCIP_LPISTATE** lpistate, /**< pointer to LP state information (like basis information) */
    885 SCIP_LPINORMS** lpinorms, /**< pointer to LP pricing norms information */
    886 SCIP_Bool primalfeas, /**< primal feasibility when LP state information was stored */
    887 SCIP_Bool dualfeas /**< dual feasibility when LP state information was stored */
    888 )
    889{
    890 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetProbingLPState", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
    891
    892 if( !SCIPtreeProbing(scip->tree) )
    893 {
    894 SCIPerrorMessage("not in probing mode\n");
    895 return SCIP_INVALIDCALL;
    896 }
    897
    898 SCIP_CALL( SCIPtreeSetProbingLPState(scip->tree, scip->mem->probmem, scip->lp, lpistate, lpinorms, primalfeas, dualfeas) );
    899
    900 return SCIP_OKAY;
    901}
    902
    903/** adds a row to the LP in the current probing node
    904 *
    905 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    906 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    907 *
    908 * @pre This method can be called if @p scip is in one of the following stages:
    909 * - \ref SCIP_STAGE_SOLVING
    910 *
    911 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
    912 */
    914 SCIP* scip, /**< SCIP data structure */
    915 SCIP_ROW* row /**< row to be added */
    916 )
    917{
    918 SCIP_NODE* node;
    919 int depth;
    920
    921 assert(scip != NULL);
    922 assert(row != NULL);
    923
    925
    926 if( !SCIPtreeProbing(scip->tree) )
    927 {
    928 SCIPerrorMessage("not in probing mode\n");
    929 return SCIP_INVALIDCALL;
    930 }
    931
    932 /* get depth of current node */
    933 node = SCIPtreeGetCurrentNode(scip->tree);
    934 assert(node != NULL);
    935 depth = SCIPnodeGetDepth(node);
    936
    937 SCIP_CALL( SCIPlpAddRow(scip->lp, scip->mem->probmem, scip->set, scip->eventqueue, scip->eventfilter, row, depth) );
    938
    939 return SCIP_OKAY;
    940}
    941
    942
    943/** applies the cuts in the separation storage to the LP and clears the storage afterwards;
    944 * this method can only be applied during probing; the user should resolve the probing LP afterwards
    945 * in order to get a new solution
    946 *
    947 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    948 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    949 *
    950 * @pre This method can be called if @p scip is in one of the following stages:
    951 * - \ref SCIP_STAGE_SOLVING
    952 */
    954 SCIP* scip, /**< SCIP data structure */
    955 SCIP_Bool* cutoff /**< pointer to store whether an empty domain was created */
    956 )
    957{
    958 SCIP_CALL( SCIPcheckStage(scip, "SCIPapplyCutsProbing", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
    959
    960 if( !SCIPtreeProbing(scip->tree) )
    961 {
    962 SCIPerrorMessage("not in probing mode\n");
    963 return SCIP_INVALIDCALL;
    964 }
    965
    966 SCIP_CALL( SCIPsepastoreApplyCuts(scip->sepastore, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
    967 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->eventfilter,
    968 scip->cliquetable, FALSE, SCIP_EFFICIACYCHOICE_LP, cutoff) );
    969
    970 return SCIP_OKAY;
    971}
    972
    973/** solves relaxation(s) at the current probing node (cannot be applied at preprocessing stage);
    974 * no separation or pricing is applied
    975 *
    976 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    977 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    978 *
    979 * @pre This method can be called if @p scip is in one of the following stages:
    980 * - \ref SCIP_STAGE_SOLVING
    981 */
    983 SCIP* scip, /**< SCIP data structure */
    984 SCIP_Bool* cutoff /**< pointer to store whether a relaxation was infeasible or the objective
    985 * limit was reached (or NULL, if not needed) */
    986 )
    987{
    988 SCIP_SET* set;
    989 int r;
    990
    991 SCIP_CALL( SCIPcheckStage(scip, "SCIPsolveProbingRelax", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
    992
    993 if ( ! SCIPtreeProbing(scip->tree) )
    994 {
    995 SCIPerrorMessage("not in probing mode\n");
    996 return SCIP_INVALIDCALL;
    997 }
    998 assert( SCIPtreeGetCurrentDepth(scip->tree) > 0 );
    999
    1000 assert( cutoff != NULL );
    1001 *cutoff = FALSE;
    1002
    1003 set = scip->set;
    1004
    1005 /* sort relaxators by priority */
    1007
    1008 /* solve relaxations */
    1009 for (r = 0; r < set->nrelaxs && !(*cutoff); ++r)
    1010 {
    1011 SCIP_RELAX* relax;
    1012 SCIP_Real lowerbound;
    1013 SCIP_RESULT result;
    1014
    1015 lowerbound = -SCIPinfinity(scip);
    1016
    1017 relax = set->relaxs[r];
    1018 assert( relax != NULL );
    1019
    1020 SCIP_CALL( SCIPrelaxExec(relax, set, scip->tree, scip->stat, SCIPtreeGetCurrentDepth(scip->tree), &lowerbound, &result) );
    1021
    1022 switch( result )
    1023 {
    1024 case SCIP_CUTOFF:
    1025 *cutoff = TRUE;
    1026 SCIPdebugMsg(scip, " -> relaxator <%s> detected cutoff\n", SCIPrelaxGetName(relax));
    1027 break;
    1028
    1029 case SCIP_CONSADDED:
    1030 case SCIP_REDUCEDDOM:
    1031 case SCIP_SEPARATED:
    1032 case SCIP_SUSPENDED:
    1033 SCIPerrorMessage("The relaxator should not return <%d> within probing mode.\n", result);
    1034 break;
    1035
    1036 case SCIP_SUCCESS:
    1037 case SCIP_DIDNOTRUN:
    1038 break;
    1039
    1040 default:
    1041 SCIPerrorMessage("Invalid result code <%d> of relaxator <%s>\n", result, SCIPrelaxGetName(relax));
    1042 return SCIP_INVALIDRESULT;
    1043 } /*lint !e788*/
    1044 }
    1045
    1046 return SCIP_OKAY;
    1047}
    1048
    1049/** print statistics of probing */
    1051 SCIP* scip, /**< SCIP data structure */
    1052 char* strbuf, /**< string buffer */
    1053 int len /**< length of string buffer */
    1054 )
    1055{
    1056 char* ptr = strbuf;
    1057 const int nvartypes = 4;
    1058
    1059 assert(scip != NULL);
    1060 assert(strbuf != NULL);
    1061
    1062 if( SCIPinProbing(scip) )
    1063 {
    1064 SCIP_VAR** vars;
    1065 int nbinvars = SCIPgetNBinVars(scip);
    1066 int nintvars = SCIPgetNIntVars(scip);
    1067 int nimplvars = SCIPgetNImplVars(scip);
    1068 int nvars = SCIPgetNVars(scip);
    1069 int vartypeend[] = {
    1070 nbinvars,
    1071 nbinvars + nintvars,
    1072 nbinvars + nintvars + nimplvars,
    1073 nvars
    1074 };
    1075 const char* vartypenames[] = {
    1076 "binary",
    1077 "integer",
    1078 "implicit integer",
    1079 "continuous"
    1080 };
    1081 int nvartypefixed[4];
    1082 int nvarsfixed = 0;
    1083 int depth;
    1084 int probingdepth;
    1085 int vartypestart = 0;
    1086 int v;
    1087 int p;
    1088
    1089 vars = SCIPgetVars(scip);
    1090 BMSclearMemoryArray(nvartypefixed, nvartypes);
    1091
    1092 /* loop over vartypes and count fixings */
    1093 for( p = 0; p < nvartypes; ++p )
    1094 {
    1095 for( v = vartypestart; v < vartypeend[p]; ++v )
    1096 {
    1097 if( SCIPisEQ(scip, SCIPvarGetLbLocal(vars[v]), SCIPvarGetUbLocal(vars[v])) )
    1098 ++nvartypefixed[p];
    1099 }
    1100 nvarsfixed += nvartypefixed[p];
    1101 vartypestart = vartypeend[p];
    1102 }
    1103
    1104 depth = SCIPgetDepth(scip);
    1105 probingdepth = SCIPgetProbingDepth(scip);
    1106
    1107 ptr += SCIPsnprintf(ptr, len, "Depth: (%d total, %d probing) ", depth, probingdepth);
    1108 ptr += SCIPsnprintf(ptr, len, "Fixed/Variables: %d / %d (", nvarsfixed, vartypeend[nvartypes - 1]);
    1109
    1110 for( p = 0; p < nvartypes; ++p )
    1111 {
    1112 int ntypevars = vartypeend[p] - (p == 0 ? 0 : vartypeend[p - 1]);
    1113 ptr += SCIPsnprintf(ptr, len, "%d / %d %s%s", nvartypefixed[p], ntypevars, vartypenames[p], p < (nvartypes - 1) ? ", " : ")");
    1114 }
    1115 }
    1116 else
    1117 {
    1118 (void) SCIPsnprintf(strbuf, len, "Not in probing");
    1119 }
    1120
    1121 return strbuf;
    1122}
    1123
    1124/** gets the candidate score and preferred rounding direction for a candidate variable */
    1126 SCIP* scip, /**< SCIP data structure */
    1127 SCIP_DIVESET* diveset, /**< general diving settings */
    1128 SCIP_DIVETYPE divetype, /**< represents different methods for a dive set to explore the next children */
    1129 SCIP_VAR* divecand, /**< the candidate for which the branching direction is requested */
    1130 SCIP_Real divecandsol, /**< LP solution value of the candidate */
    1131 SCIP_Real divecandfrac, /**< fractionality of the candidate */
    1132 SCIP_Real* candscore, /**< pointer to store the candidate score */
    1133 SCIP_Bool* roundup /**< pointer to store whether preferred direction for diving is upwards */
    1134 )
    1135{
    1136 assert(scip != NULL);
    1137 assert(candscore != NULL);
    1138 assert(roundup != NULL);
    1139 assert(divecand != NULL);
    1140
    1141 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetDivesetScore", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
    1142
    1143 SCIP_CALL( SCIPdivesetGetScore(diveset, scip->set, divetype, divecand, divecandsol, divecandfrac, candscore,
    1144 roundup) );
    1145
    1146 return SCIP_OKAY;
    1147}
    1148
    1149/** update diveset LP statistics, should be called after every LP solved by this diving heuristic */
    1151 SCIP* scip, /**< SCIP data structure */
    1152 SCIP_DIVESET* diveset, /**< diving settings */
    1153 SCIP_Longint niterstoadd, /**< additional number of LP iterations to be added */
    1154 SCIP_DIVECONTEXT divecontext /**< context for diving statistics */
    1155 )
    1156{
    1157 assert(scip != NULL);
    1158 assert(diveset != NULL);
    1159
    1160 SCIPdivesetUpdateLPStats(diveset, scip->stat, niterstoadd, divecontext);
    1161}
    1162
    1163/** update diveset statistics and global diveset statistics */
    1165 SCIP* scip, /**< SCIP data structure */
    1166 SCIP_DIVESET* diveset, /**< diveset to be reset */
    1167 int nprobingnodes, /**< the number of probing nodes explored this time */
    1168 int nbacktracks, /**< the number of backtracks during probing this time */
    1169 SCIP_Longint nsolsfound, /**< the number of solutions found */
    1170 SCIP_Longint nbestsolsfound, /**< the number of best solutions found */
    1171 SCIP_Longint nconflictsfound, /**< number of new conflicts found this time */
    1172 SCIP_Bool leavewassol, /**< was a solution found at the leaf? */
    1173 SCIP_DIVECONTEXT divecontext /**< context for diving statistics */
    1174 )
    1175{
    1176 assert(scip != NULL);
    1177 assert(diveset != NULL);
    1178 assert(SCIPinProbing(scip));
    1179
    1180 SCIPdivesetUpdateStats(diveset, scip->stat, SCIPgetDepth(scip), nprobingnodes, nbacktracks, nsolsfound,
    1181 nbestsolsfound, nconflictsfound, leavewassol, divecontext);
    1182}
    1183
    1184/** enforces a probing/diving solution by suggesting bound changes that maximize the score w.r.t. the current diving settings
    1185 *
    1186 * the process is guided by the enforcement priorities of the constraint handlers and the scoring mechanism provided by
    1187 * the dive set.
    1188 * Constraint handlers may suggest diving bound changes in decreasing order of their enforcement priority, based on the
    1189 * solution values in the solution @p sol and the current local bounds of the variables. A diving bound change
    1190 * is a triple (variable,branching direction,value) and is used inside SCIPperformGenericDivingAlgorithm().
    1191 *
    1192 * After a successful call, SCIP holds two arrays of suggested dive bound changes, one for the preferred child
    1193 * and one for the alternative.
    1194 *
    1195 * @see SCIPgetDiveBoundChangeData() for retrieving the dive bound change suggestions.
    1196 *
    1197 * The method stops after the first constraint handler was successful
    1198 *
    1199 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    1200 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    1201 *
    1202 * @pre This method can be called if @p scip is in one of the following stages:
    1203 * - \ref SCIP_STAGE_SOLVING
    1204 *
    1205 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
    1206 */
    1208 SCIP* scip, /**< SCIP data structure */
    1209 SCIP_DIVESET* diveset, /**< diving settings to control scoring */
    1210 SCIP_SOL* sol, /**< current solution of diving mode */
    1211 SCIP_Bool* success, /**< pointer to store whether constraint handler successfully found a variable */
    1212 SCIP_Bool* infeasible /**< pointer to store whether the current node was detected to be infeasible */
    1213 )
    1214{
    1215 int i;
    1216
    1217 assert(scip != NULL);
    1218 assert(diveset != NULL);
    1219 assert(SCIPinProbing(scip));
    1220 assert(infeasible != NULL);
    1221 assert(success != NULL);
    1222
    1223 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetDiveBoundChanges", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
    1224
    1225 *success = FALSE;
    1226 *infeasible = FALSE;
    1227
    1228 /* we invalidate the previously stored bound changes */
    1230
    1231 /* loop over constraint handlers until a constraint handler successfully found a variable/value assignment for proceeding
    1232 * or a constraint handler detected the infeasibility of the local node
    1233 */
    1234 for( i = 0; i < scip->set->nconshdlrs && !(*success || *infeasible); ++i )
    1235 {
    1236 SCIP_CALL( SCIPconshdlrGetDiveBoundChanges(scip->set->conshdlrs_enfo[i], scip->set, diveset, sol,
    1237 success, infeasible) );
    1238 }
    1239
    1240#ifndef NDEBUG
    1241 /* check if the constraint handler correctly assigned values to the dive set */
    1242 if( *success )
    1243 {
    1244 SCIP_VAR** bdchgvars;
    1245 SCIP_BRANCHDIR* bdchgdirs;
    1246 SCIP_Real* values;
    1247 int nbdchanges;
    1248 SCIPtreeGetDiveBoundChangeData(scip->tree, &bdchgvars, &bdchgdirs, &values, &nbdchanges, TRUE);
    1249 assert(nbdchanges > 0);
    1250 SCIPtreeGetDiveBoundChangeData(scip->tree, &bdchgvars, &bdchgdirs, &values, &nbdchanges, FALSE);
    1251 assert(nbdchanges > 0);
    1252 }
    1253#endif
    1254
    1255 return SCIP_OKAY;
    1256}
    1257
    1258/** adds a diving bound change to the diving bound change storage of SCIP together with the information if this is a
    1259 * bound change for the preferred direction or not
    1260 *
    1261 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    1262 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    1263 *
    1264 * @pre This method can be called if @p scip is in one of the following stages:
    1265 * - \ref SCIP_STAGE_SOLVING
    1266 *
    1267 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
    1268 */
    1270 SCIP* scip, /**< SCIP data structure */
    1271 SCIP_VAR* var, /**< variable to apply the bound change to */
    1272 SCIP_BRANCHDIR dir, /**< direction of the bound change */
    1273 SCIP_Real value, /**< value to adjust this variable bound to */
    1274 SCIP_Bool preferred /**< is this a bound change for the preferred child? */
    1275 )
    1276{
    1277 assert(scip->tree != NULL);
    1278 assert(scip->mem->probmem != NULL);
    1279 assert(SCIPinProbing(scip));
    1280
    1281 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddDiveBoundChange", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
    1282
    1283 SCIP_CALL( SCIPtreeAddDiveBoundChange(scip->tree, scip->mem->probmem, var, dir, value, preferred) );
    1284
    1285 return SCIP_OKAY;
    1286}
    1287
    1288/** get the dive bound change data for the preferred or the alternative direction
    1289 *
    1290 * @pre This method can be called if @p scip is in one of the following stages:
    1291 * - \ref SCIP_STAGE_SOLVING
    1292 *
    1293 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
    1294 */
    1296 SCIP* scip, /**< SCIP data structure */
    1297 SCIP_VAR*** variables, /**< pointer to store variables for the specified direction */
    1298 SCIP_BRANCHDIR** directions, /**< pointer to store the branching directions */
    1299 SCIP_Real** values, /**< pointer to store bound change values */
    1300 int* ndivebdchgs, /**< pointer to store the number of dive bound changes */
    1301 SCIP_Bool preferred /**< should the dive bound changes for the preferred child be output? */
    1302 )
    1303{
    1304 assert(variables != NULL);
    1305 assert(directions != NULL);
    1306 assert(values != NULL);
    1307 assert(ndivebdchgs != NULL);
    1308 assert(SCIPinProbing(scip));
    1309
    1310 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetDiveBoundChangeData", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
    1311
    1312 SCIPtreeGetDiveBoundChangeData(scip->tree, variables, directions, values, ndivebdchgs, preferred);
    1313}
    1314
    1315/** clear the dive bound change data structures
    1316 *
    1317 * @pre This method can be called if @p scip is in one of the following stages:
    1318 * - \ref SCIP_STAGE_SOLVING
    1319 *
    1320 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
    1321 */
    1323 SCIP* scip /**< SCIP data structure */
    1324 )
    1325{
    1326 assert(scip->tree != NULL);
    1327
    1328 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPclearDiveBoundChanges", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
    1329
    1331}
    SCIP_Real * r
    Definition: circlepacking.c:59
    internal methods for conflict analysis
    SCIP_RETCODE SCIPconflictAnalyzeLP(SCIP_CONFLICT *conflict, SCIP_CONFLICTSTORE *conflictstore, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable, SCIP_Bool *success)
    SCIP_RETCODE SCIPconshdlrGetDiveBoundChanges(SCIP_CONSHDLR *conshdlr, SCIP_SET *set, SCIP_DIVESET *diveset, SCIP_SOL *sol, SCIP_Bool *success, SCIP_Bool *infeasible)
    Definition: cons.c:3589
    internal methods for constraints and constraint handlers
    methods for debugging
    #define SCIPcheckStage(scip, method, init, problem, transforming, transformed, initpresolve, presolving, exitpresolve, presolved, initsolve, solving, solved, exitsolve, freetrans, freescip)
    Definition: debug.h:364
    #define NULL
    Definition: def.h:248
    #define SCIP_Longint
    Definition: def.h:141
    #define SCIP_INVALID
    Definition: def.h:178
    #define SCIP_Bool
    Definition: def.h:91
    #define MIN(x, y)
    Definition: def.h:224
    #define SCIP_Real
    Definition: def.h:156
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define SCIP_CALL_ABORT(x)
    Definition: def.h:334
    #define SCIPABORT()
    Definition: def.h:327
    #define SCIP_CALL(x)
    Definition: def.h:355
    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
    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
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
    Definition: scip_message.c:120
    void SCIPswapPointers(void **pointer1, void **pointer2)
    Definition: misc.c:10511
    SCIP_Bool SCIPisExact(SCIP *scip)
    Definition: scip_exact.c:193
    SCIP_Real SCIPgetLPObjval(SCIP *scip)
    Definition: scip_lp.c:253
    #define SCIPreallocMemoryArray(scip, ptr, newnum)
    Definition: scip_mem.h:70
    #define SCIPallocMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:64
    #define SCIPallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:124
    #define SCIPfreeBufferArray(scip, ptr)
    Definition: scip_mem.h:136
    SCIP_NODETYPE SCIPnodeGetType(SCIP_NODE *node)
    Definition: tree.c:8473
    int SCIPnodeGetDepth(SCIP_NODE *node)
    Definition: tree.c:8493
    SCIP_RETCODE SCIPaddRowProbing(SCIP *scip, SCIP_ROW *row)
    Definition: scip_probing.c:913
    void SCIPclearDiveBoundChanges(SCIP *scip)
    int SCIPgetProbingDepth(SCIP *scip)
    Definition: scip_probing.c:199
    void SCIPupdateDivesetStats(SCIP *scip, SCIP_DIVESET *diveset, int nprobingnodes, int nbacktracks, SCIP_Longint nsolsfound, SCIP_Longint nbestsolsfound, SCIP_Longint nconflictsfound, SCIP_Bool leavewassol, SCIP_DIVECONTEXT divecontext)
    SCIP_RETCODE SCIPapplyCutsProbing(SCIP *scip, SCIP_Bool *cutoff)
    Definition: scip_probing.c:953
    void SCIPgetDiveBoundChangeData(SCIP *scip, SCIP_VAR ***variables, SCIP_BRANCHDIR **directions, SCIP_Real **values, int *ndivebdchgs, SCIP_Bool preferred)
    SCIP_RETCODE SCIPgetDiveBoundChanges(SCIP *scip, SCIP_DIVESET *diveset, SCIP_SOL *sol, SCIP_Bool *success, SCIP_Bool *infeasible)
    SCIP_RETCODE SCIPgetDivesetScore(SCIP *scip, SCIP_DIVESET *diveset, SCIP_DIVETYPE divetype, SCIP_VAR *divecand, SCIP_Real divecandsol, SCIP_Real divecandfrac, SCIP_Real *candscore, SCIP_Bool *roundup)
    SCIP_RETCODE SCIPchgVarUbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
    Definition: scip_probing.c:346
    SCIP_RETCODE SCIPsetProbingLPState(SCIP *scip, SCIP_LPISTATE **lpistate, SCIP_LPINORMS **lpinorms, SCIP_Bool primalfeas, SCIP_Bool dualfeas)
    Definition: scip_probing.c:882
    char * SCIPsnprintfProbingStats(SCIP *scip, char *strbuf, int len)
    SCIP_Bool SCIPisObjChangedProbing(SCIP *scip)
    Definition: scip_probing.c:553
    SCIP_RETCODE SCIPsolveProbingRelax(SCIP *scip, SCIP_Bool *cutoff)
    Definition: scip_probing.c:982
    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_RETCODE SCIPchgVarObjProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
    Definition: scip_probing.c:475
    SCIP_RETCODE SCIPbacktrackProbing(SCIP *scip, int probingdepth)
    Definition: scip_probing.c:226
    void SCIPupdateDivesetLPStats(SCIP *scip, SCIP_DIVESET *diveset, SCIP_Longint niterstoadd, SCIP_DIVECONTEXT divecontext)
    SCIP_Bool SCIPinProbing(SCIP *scip)
    Definition: scip_probing.c:98
    SCIP_RETCODE SCIPstartProbing(SCIP *scip)
    Definition: scip_probing.c:120
    SCIP_Real SCIPgetVarObjProbing(SCIP *scip, SCIP_VAR *var)
    Definition: scip_probing.c:389
    SCIP_RETCODE SCIPaddDiveBoundChange(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir, SCIP_Real value, SCIP_Bool preferred)
    SCIP_RETCODE SCIPnewProbingNode(SCIP *scip)
    Definition: scip_probing.c:166
    SCIP_RETCODE SCIPsolveProbingLP(SCIP *scip, int itlim, SCIP_Bool *lperror, SCIP_Bool *cutoff)
    Definition: scip_probing.c:825
    SCIP_RETCODE SCIPpropagateProbingImplications(SCIP *scip, SCIP_Bool *cutoff)
    Definition: scip_probing.c:690
    SCIP_RETCODE SCIPfixVarProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval)
    Definition: scip_probing.c:419
    SCIP_RETCODE SCIPendProbing(SCIP *scip)
    Definition: scip_probing.c:261
    SCIP_RETCODE SCIPsolveProbingLPWithPricing(SCIP *scip, SCIP_Bool pretendroot, SCIP_Bool displayinfo, int maxpricerounds, SCIP_Bool *lperror, SCIP_Bool *cutoff)
    Definition: scip_probing.c:849
    const char * SCIPrelaxGetName(SCIP_RELAX *relax)
    Definition: relax.c:557
    SCIP_Real SCIPgetCutoffbound(SCIP *scip)
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    int SCIPgetDepth(SCIP *scip)
    Definition: scip_tree.c:672
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24268
    SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
    Definition: var.c:23900
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23267
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24234
    int SCIPsnprintf(char *t, int len, const char *s,...)
    Definition: misc.c:10827
    void SCIPdivesetUpdateLPStats(SCIP_DIVESET *diveset, SCIP_STAT *stat, SCIP_Longint niterstoadd, SCIP_DIVECONTEXT divecontext)
    Definition: heur.c:787
    void SCIPdivesetUpdateStats(SCIP_DIVESET *diveset, SCIP_STAT *stat, int depth, int nprobingnodes, int nbacktracks, SCIP_Longint nsolsfound, SCIP_Longint nbestsolsfound, SCIP_Longint nconflictsfound, SCIP_Bool leavesol, SCIP_DIVECONTEXT divecontext)
    Definition: heur.c:203
    SCIP_RETCODE SCIPdivesetGetScore(SCIP_DIVESET *diveset, SCIP_SET *set, SCIP_DIVETYPE divetype, SCIP_VAR *divecand, SCIP_Real divecandsol, SCIP_Real divecandfrac, SCIP_Real *candscore, SCIP_Bool *roundup)
    Definition: heur.c:834
    internal methods for primal heuristics
    SCIP_Bool SCIPlpDivingObjChanged(SCIP_LP *lp)
    Definition: lp.c:18261
    SCIP_LPSOLSTAT SCIPlpGetSolstat(SCIP_LP *lp)
    Definition: lp.c:13420
    void SCIPlpSetIsRelax(SCIP_LP *lp, SCIP_Bool relax)
    Definition: lp.c:18188
    SCIP_RETCODE SCIPlpSolveAndEval(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_PROB *prob, SCIP_Longint itlim, SCIP_Bool limitresolveiters, SCIP_Bool aging, SCIP_Bool keepsol, SCIP_Bool forcedlpsolve, SCIP_Bool *lperror)
    Definition: lp.c:12680
    void SCIPlpMarkDivingObjChanged(SCIP_LP *lp)
    Definition: lp.c:18271
    SCIP_Bool SCIPlpDiving(SCIP_LP *lp)
    Definition: lp.c:18251
    void SCIPlpUnmarkDivingObjChanged(SCIP_LP *lp)
    Definition: lp.c:18282
    SCIP_RETCODE SCIPlpSetCutoffbound(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_Real cutoffbound)
    Definition: lp.c:10451
    SCIP_RETCODE SCIPlpAddRow(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_ROW *row, int depth)
    Definition: lp.c:9759
    internal methods for LP management
    memory allocation routines
    #define BMSclearMemoryArray(ptr, num)
    Definition: memory.h:130
    SCIP_Bool SCIPprobAllColsInLP(SCIP_PROB *prob, SCIP_SET *set, SCIP_LP *lp)
    Definition: prob.c:2825
    internal methods for storing and manipulating the main problem
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    public data structures and miscellaneous methods
    public methods for relaxation handlers
    public methods for branch and bound tree
    public methods for problem variables
    SCIP_RETCODE SCIPrelaxExec(SCIP_RELAX *relax, SCIP_SET *set, SCIP_TREE *tree, SCIP_STAT *stat, int depth, SCIP_Real *lowerbound, SCIP_RESULT *result)
    Definition: relax.c:354
    internal methods for relaxators
    public methods for exact solving
    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 global and local (sub)problems
    static SCIP_RETCODE solveProbingLP(SCIP *scip, int itlim, SCIP_Bool pricing, SCIP_Bool pretendroot, SCIP_Bool displayinfo, int maxpricerounds, SCIP_Bool *lperror, SCIP_Bool *cutoff)
    Definition: scip_probing.c:712
    public methods for the probing mode
    public methods for querying solving statistics
    public methods for the branch-and-bound tree
    int SCIPsepastoreGetNCuts(SCIP_SEPASTORE *sepastore)
    Definition: sepastore.c:1183
    SCIP_RETCODE SCIPsepastoreApplyCuts(SCIP_SEPASTORE *sepastore, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable, SCIP_Bool root, SCIP_EFFICIACYCHOICE efficiacychoice, SCIP_Bool *cutoff)
    Definition: sepastore.c:935
    internal methods for storing separated cuts
    void SCIPsetSortRelaxs(SCIP_SET *set)
    Definition: set.c:4455
    SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6537
    SCIP_Real SCIPsetInfinity(SCIP_SET *set)
    Definition: set.c:6380
    SCIP_Bool SCIPsetIsLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6557
    SCIP_Bool SCIPsetIsGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6597
    internal methods for global SCIP settings
    SCIP_RETCODE SCIPinitConssLP(BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_SEPASTORE *sepastore, SCIP_CUTPOOL *cutpool, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable, SCIP_Bool root, SCIP_Bool firstsubtreeinit, SCIP_Bool *cutoff)
    Definition: solve.c:1225
    SCIP_RETCODE SCIPpriceLoop(BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_PRICESTORE *pricestore, SCIP_SEPASTORE *sepastore, SCIP_CUTPOOL *cutpool, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable, SCIP_Bool pretendroot, SCIP_Bool displayinfo, int maxpricerounds, int *npricedcolvars, SCIP_Bool *mustsepa, SCIP_Bool *lperror, SCIP_Bool *aborted)
    Definition: solve.c:2211
    SCIP_RETCODE SCIPpropagateDomains(BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CONFLICT *conflict, SCIP_CLIQUETABLE *cliquetable, int depth, int maxrounds, SCIP_PROPTIMING timingmask, SCIP_Bool *cutoff)
    Definition: solve.c:658
    internal methods for main solving loop and node processing
    void SCIPstatEnableVarHistory(SCIP_STAT *stat)
    Definition: stat.c:191
    void SCIPstatDisableVarHistory(SCIP_STAT *stat)
    Definition: stat.c:181
    internal methods for problem statistics
    union SCIP_Node::@21 data
    SCIP_PROBINGNODE * probingnode
    Definition: struct_tree.h:149
    SCIP_VAR ** origobjvars
    Definition: struct_tree.h:63
    SCIP_Real * origobjvals
    Definition: struct_tree.h:64
    SCIP_Real unchangedobj
    Definition: struct_var.h:264
    data structures for LP management
    datastructures for block memory pools and memory buffers
    SCIP main data structure.
    datastructures for global SCIP settings
    datastructures for problem statistics
    data structures for branch and bound tree
    datastructures for problem variables
    Definition: heur_padm.c:135
    SCIP_Bool SCIPtreeIsFocusNodeLPConstructed(SCIP_TREE *tree)
    Definition: tree.c:9442
    SCIP_Bool SCIPtreeProbing(SCIP_TREE *tree)
    Definition: tree.c:9361
    SCIP_Bool SCIPtreeProbingObjChanged(SCIP_TREE *tree)
    Definition: tree.c:9540
    SCIP_RETCODE SCIPnodeAddBoundchg(SCIP_NODE *node, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable, SCIP_VAR *var, SCIP_Real newbound, SCIP_BOUNDTYPE boundtype, SCIP_Bool probingchange)
    Definition: tree.c:2539
    int SCIPtreeGetProbingDepth(SCIP_TREE *tree)
    Definition: tree.c:9507
    SCIP_RETCODE SCIPtreeStartProbing(SCIP_TREE *tree, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp, SCIP_RELAXATION *relaxation, SCIP_PROB *transprob, SCIP_Bool strongbranching)
    Definition: tree.c:7377
    SCIP_RETCODE SCIPtreeSetProbingLPState(SCIP_TREE *tree, BMS_BLKMEM *blkmem, SCIP_LP *lp, SCIP_LPISTATE **lpistate, SCIP_LPINORMS **lpinorms, SCIP_Bool primalfeas, SCIP_Bool dualfeas)
    Definition: tree.c:7470
    SCIP_NODE * SCIPtreeGetCurrentNode(SCIP_TREE *tree)
    Definition: tree.c:9462
    void SCIPtreeMarkProbingObjChanged(SCIP_TREE *tree)
    Definition: tree.c:9551
    SCIP_RETCODE SCIPtreeAddDiveBoundChange(SCIP_TREE *tree, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_BRANCHDIR dir, SCIP_Real value, SCIP_Bool preferred)
    Definition: tree.c:7216
    SCIP_RETCODE SCIPtreeLoadProbingLPState(SCIP_TREE *tree, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PROB *prob, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
    Definition: tree.c:7524
    SCIP_RETCODE SCIPnodePropagateImplics(SCIP_NODE *node, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable, SCIP_Bool *cutoff)
    Definition: tree.c:3100
    SCIP_RETCODE SCIPtreeEndProbing(SCIP_TREE *tree, SCIP_REOPT *reopt, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_LP *lp, SCIP_RELAXATION *relaxation, SCIP_PRIMAL *primal, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable)
    Definition: tree.c:7814
    void SCIPtreeGetDiveBoundChangeData(SCIP_TREE *tree, SCIP_VAR ***variables, SCIP_BRANCHDIR **directions, SCIP_Real **values, int *ndivebdchgs, SCIP_Bool preferred)
    Definition: tree.c:7248
    int SCIPtreeGetCurrentDepth(SCIP_TREE *tree)
    Definition: tree.c:9479
    SCIP_RETCODE SCIPtreeCreateProbingNode(SCIP_TREE *tree, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
    Definition: tree.c:7445
    SCIP_RETCODE SCIPtreeMarkProbingNodeHasLP(SCIP_TREE *tree, BMS_BLKMEM *blkmem, SCIP_LP *lp)
    Definition: tree.c:7606
    SCIP_RETCODE SCIPtreeBacktrackProbing(SCIP_TREE *tree, SCIP_REOPT *reopt, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_LP *lp, SCIP_PRIMAL *primal, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable, int probingdepth)
    Definition: tree.c:7780
    void SCIPtreeClearDiveBoundChanges(SCIP_TREE *tree)
    Definition: tree.c:7271
    internal methods for branch and bound tree
    enum SCIP_DiveContext SCIP_DIVECONTEXT
    Definition: type_heur.h:73
    unsigned int SCIP_DIVETYPE
    Definition: type_heur.h:63
    enum SCIP_BranchDir SCIP_BRANCHDIR
    Definition: type_history.h:48
    @ SCIP_BOUNDTYPE_UPPER
    Definition: type_lp.h:58
    @ SCIP_BOUNDTYPE_LOWER
    Definition: type_lp.h:57
    @ SCIP_LPSOLSTAT_NOTSOLVED
    Definition: type_lp.h:43
    @ SCIP_LPSOLSTAT_OPTIMAL
    Definition: type_lp.h:44
    @ SCIP_LPSOLSTAT_INFEASIBLE
    Definition: type_lp.h:45
    @ SCIP_LPSOLSTAT_OBJLIMIT
    Definition: type_lp.h:47
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_CUTOFF
    Definition: type_result.h:48
    @ SCIP_REDUCEDDOM
    Definition: type_result.h:51
    @ SCIP_CONSADDED
    Definition: type_result.h:52
    @ SCIP_SUSPENDED
    Definition: type_result.h:57
    @ SCIP_SEPARATED
    Definition: type_result.h:49
    @ SCIP_SUCCESS
    Definition: type_result.h:58
    enum SCIP_Result SCIP_RESULT
    Definition: type_result.h:61
    @ SCIP_INVALIDRESULT
    Definition: type_retcode.h:53
    @ SCIP_INVALIDDATA
    Definition: type_retcode.h:52
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_INVALIDCALL
    Definition: type_retcode.h:51
    @ SCIP_MAXDEPTHLEVEL
    Definition: type_retcode.h:59
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_EFFICIACYCHOICE_LP
    @ SCIP_STAGE_SOLVING
    Definition: type_set.h:53
    #define SCIP_PROPTIMING_ALWAYS
    Definition: type_timing.h:73
    @ SCIP_NODETYPE_PROBINGNODE
    Definition: type_tree.h:42
    SCIP_Real SCIPvarGetObjLP(SCIP_VAR *var)
    Definition: var.c:18522
    SCIP_RETCODE SCIPvarChgObj(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PROB *prob, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_Real newobj)
    Definition: var.c:9419
    void SCIPvarAdjustLb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *lb)
    Definition: var.c:9910
    void SCIPvarAdjustUb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *ub)
    Definition: var.c:9961
    internal methods for problem variables