SCIP

    Solving Constraint Integer Programs

    conflict_graphanalysis.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 conflict_graphanalysis.c
    26 * @ingroup OTHER_CFILES
    27 * @brief methods and datastructures for conflict analysis
    28 * @author Tobias Achterberg
    29 * @author Timo Berthold
    30 * @author Stefan Heinz
    31 * @author Marc Pfetsch
    32 * @author Michael Winkler
    33 * @author Jakob Witzig
    34 *
    35 * This file implements a conflict analysis method like the one used in modern
    36 * SAT solvers like zchaff. The algorithm works as follows:
    37 *
    38 * Given is a set of bound changes that are not allowed being applied simultaneously, because they
    39 * render the current node infeasible (e.g. because a single constraint is infeasible in the these
    40 * bounds, or because the LP relaxation is infeasible). The goal is to deduce a clause on variables
    41 * -- a conflict clause -- representing the "reason" for this conflict, i.e., the branching decisions
    42 * or the deductions (applied e.g. in domain propagation) that lead to the conflict. This clause can
    43 * then be added to the constraint set to help cutting off similar parts of the branch and bound
    44 * tree, that would lead to the same conflict. A conflict clause can also be generated, if the
    45 * conflict was detected by a locally valid constraint. In this case, the resulting conflict clause
    46 * is also locally valid in the same depth as the conflict detecting constraint. If all involved
    47 * variables are binary, a linear (set covering) constraint can be generated, otherwise a bound
    48 * disjunction constraint is generated. Details are given in
    49 *
    50 * Tobias Achterberg, Conflict Analysis in Mixed Integer Programming@n
    51 * Discrete Optimization, 4, 4-20 (2007)
    52 *
    53 * See also @ref CONF. Here is an outline of the algorithm:
    54 *
    55 * -# Put all the given bound changes to a priority queue, which is ordered,
    56 * such that the bound change that was applied last due to branching or deduction
    57 * is at the top of the queue. The variables in the queue are always active
    58 * problem variables. Because binary variables are preferred over general integer
    59 * variables, integer variables are put on the priority queue prior to the binary
    60 * variables. Create an empty conflict set.
    61 * -# Remove the top bound change b from the priority queue.
    62 * -# Perform the following case distinction:
    63 * -# If the remaining queue is non-empty, and bound change b' (the one that is now
    64 * on the top of the queue) was applied at the same depth level as b, and if
    65 * b was a deduction with known inference reason, and if the inference constraint's
    66 * valid depth is smaller or equal to the conflict detecting constraint's valid
    67 * depth:
    68 * - Resolve bound change b by asking the constraint that inferred the
    69 * bound change to put all the bound changes on the priority queue, that
    70 * lead to the deduction of b.
    71 * Note that these bound changes have at most the same inference depth
    72 * level as b, and were deduced earlier than b.
    73 * -# Otherwise, the bound change b was a branching decision or a deduction with
    74 * missing inference reason, or the inference constraint's validity is more local
    75 * than the one of the conflict detecting constraint.
    76 * - If a the bound changed corresponds to a binary variable, add it or its
    77 * negation to the conflict set, depending on which of them is currently fixed to
    78 * FALSE (i.e., the conflict set consists of literals that cannot be FALSE
    79 * altogether at the same time).
    80 * - Otherwise put the bound change into the conflict set.
    81 * Note that if the bound change was a branching, all deduced bound changes
    82 * remaining in the priority queue have smaller inference depth level than b,
    83 * since deductions are always applied after the branching decisions. However,
    84 * there is the possibility, that b was a deduction, where the inference
    85 * reason was not given or the inference constraint was too local.
    86 * With this lack of information, we must treat the deduced bound change like
    87 * a branching, and there may exist other deduced bound changes of the same
    88 * inference depth level in the priority queue.
    89 * -# If priority queue is non-empty, goto step 2.
    90 * -# The conflict set represents the conflict clause saying that at least one
    91 * of the conflict variables must take a different value. The conflict set is then passed
    92 * to the conflict handlers, that may create a corresponding constraint (e.g. a logicor
    93 * constraint or bound disjunction constraint) out of these conflict variables and
    94 * add it to the problem.
    95 *
    96 * If all deduced bound changes come with (global) inference information, depending on
    97 * the conflict analyzing strategy, the resulting conflict set has the following property:
    98 * - 1-FirstUIP: In the depth level where the conflict was found, at most one variable
    99 * assigned at that level is member of the conflict set. This conflict variable is the
    100 * first unique implication point of its depth level (FUIP).
    101 * - All-FirstUIP: For each depth level, at most one variable assigned at that level is
    102 * member of the conflict set. This conflict variable is the first unique implication
    103 * point of its depth level (FUIP).
    104 *
    105 * The user has to do the following to get the conflict analysis running in its
    106 * current implementation:
    107 * - A constraint handler or propagator supporting the conflict analysis must implement
    108 * the CONSRESPROP/PROPRESPROP call, that processes a bound change inference b and puts all
    109 * the reason bounds leading to the application of b with calls to
    110 * SCIPaddConflictBound() on the conflict queue (algorithm step 3.(a)).
    111 * - If the current bounds lead to a deduction of a bound change (e.g. in domain
    112 * propagation), a constraint handler should call SCIPinferVarLbCons() or
    113 * SCIPinferVarUbCons(), thus providing the constraint that inferred the bound change.
    114 * A propagator should call SCIPinferVarLbProp() or SCIPinferVarUbProp() instead,
    115 * thus providing a pointer to itself.
    116 * - If (in the current bounds) an infeasibility is detected, the constraint handler or
    117 * propagator should
    118 * 1. call SCIPinitConflictAnalysis() to initialize the conflict queue,
    119 * 2. call SCIPaddConflictBound() for each bound that lead to the conflict,
    120 * 3. call SCIPanalyzeConflictCons() or SCIPanalyzeConflict() to analyze the conflict
    121 * and add an appropriate conflict constraint.
    122 */
    123
    124/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    125
    126#include "lpi/lpi.h"
    129#include "scip/clock.h"
    130#include "scip/conflict.h"
    131#include "scip/cons.h"
    132#include "scip/cons_linear.h"
    133#include "scip/cuts.h"
    134#include "scip/history.h"
    135#include "scip/lp.h"
    136#include "scip/presolve.h"
    137#include "scip/prob.h"
    138#include "scip/prop.h"
    139#include "scip/pub_conflict.h"
    140#include "scip/pub_cons.h"
    141#include "scip/pub_lp.h"
    142#include "scip/pub_message.h"
    143#include "scip/pub_misc.h"
    144#include "scip/pub_misc_sort.h"
    145#include "scip/pub_paramset.h"
    146#include "scip/pub_prop.h"
    147#include "scip/pub_tree.h"
    148#include "scip/pub_var.h"
    149#include "scip/scip_conflict.h"
    150#include "scip/scip_cons.h"
    151#include "scip/scip_mem.h"
    152#include "scip/scip_sol.h"
    153#include "scip/scip_var.h"
    154#include "scip/scip_message.h"
    155#include "scip/set.h"
    156#include "scip/sol.h"
    157#include "scip/struct_conflict.h"
    158#include "scip/struct_lp.h"
    159#include "scip/struct_prob.h"
    160#include "scip/struct_set.h"
    161#include "scip/struct_stat.h"
    162#include "scip/struct_tree.h"
    163#include "scip/struct_var.h"
    164#include "scip/tree.h"
    165#include "scip/var.h"
    166#include "scip/visual.h"
    167#include <string.h>
    168#ifndef _WIN32
    169#include <strings.h> /*lint --e{766}*/
    170#endif
    171
    172/* #define SCIP_CONFGRAPH */
    173/* #define SCIP_CONFGRAPH_DOT */
    174
    175
    176#if defined(SCIP_CONFGRAPH) || defined(SCIP_CONFGRAPH_DOT)
    177/*
    178 * Output of Conflict Graph
    179 */
    180
    181#include <stdio.h>
    182#include "scip/scip_message.h"
    183
    184static FILE* confgraphfile = NULL; /**< output file for current conflict graph */
    185static SCIP_BDCHGINFO* confgraphcurrentbdchginfo = NULL; /**< currently resolved bound change */
    186static int confgraphnconflictsets = 0; /**< number of conflict sets marked in the graph */
    187
    188/** writes a node section to the conflict graph file */
    189static
    190void confgraphWriteNode(
    191 void* idptr, /**< id of the node */
    192 const char* label, /**< label of the node */
    193 const char* nodetype, /**< type of the node */
    194 const char* fillcolor, /**< color of the node's interior */
    195 const char* bordercolor /**< color of the node's border */
    196 )
    197{
    198 assert(confgraphfile != NULL);
    199
    200#ifdef SCIP_CONFGRAPH_DOT
    201 SCIPdotWriteNode(confgraphfile, (int)(size_t) idptr, label, nodetype, fillcolor, bordercolor); /*lint !e571*/
    202
    203#else
    204 SCIPgmlWriteNode(confgraphfile, (unsigned int)(size_t)idptr, label, nodetype, fillcolor, bordercolor); /*lint !e571*/
    205
    206#endif
    207}
    208
    209/** writes an edge section to the conflict graph file */
    210static
    211void confgraphWriteEdge(
    212 void* source, /**< source node of the edge */
    213 void* target, /**< target node of the edge */
    214 const char* color /**< color of the edge */
    215 )
    216{
    217 assert(confgraphfile != NULL);
    218
    219#ifdef SCIP_CONFGRAPH_DOT
    220 SCIPdotWriteArc(confgraphfile, (int)(size_t)source, (int)(size_t)target, color); /*lint !e571*/
    221
    222#else
    223#ifndef SCIP_CONFGRAPH_EDGE
    224 SCIPgmlWriteArc(confgraphfile, (unsigned int)(size_t)source, (unsigned int)(size_t)target, NULL, color); /*lint !e571*/
    225
    226#else
    227 SCIPgmlWriteEdge(confgraphfile, (unsigned int)(size_t)source, (unsigned int)(size_t)target, NULL, color); /*lint !e571*/
    228#endif
    229#endif
    230}
    231
    232/** creates a file to output the current conflict graph into; adds the conflict vertex to the graph */
    233static
    234SCIP_RETCODE confgraphCreate(
    235 SCIP_SET* set, /**< global SCIP settings */
    236 SCIP_CONFLICT* conflict /**< conflict analysis data */
    237 )
    238{
    239 char fname[SCIP_MAXSTRLEN];
    240
    241 assert(conflict != NULL);
    242 assert(confgraphfile == NULL);
    243
    244#ifdef SCIP_CONFGRAPH_DOT
    245 (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "conf%p%d.dot", conflict, conflict->count);
    246#else
    247 (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "conf%p%d.gml", conflict, conflict->count);
    248#endif
    249 SCIPinfoMessage(set->scip, NULL, "storing conflict graph in file <%s>\n", fname);
    250
    251 confgraphfile = fopen(fname, "w");
    252
    253 if( confgraphfile == NULL )
    254 {
    255 SCIPerrorMessage("cannot open graph file <%s>\n", fname);
    256 SCIPABORT(); /*lint !e527*/
    257 return SCIP_WRITEERROR;
    258 }
    259
    260#ifdef SCIP_CONFGRAPH_DOT
    261 SCIPdotWriteOpening(confgraphfile);
    262#else
    263 SCIPgmlWriteOpening(confgraphfile, TRUE);
    264#endif
    265 confgraphWriteNode(NULL, "conflict", "ellipse", "#ff0000", "#000000");
    266
    267 confgraphcurrentbdchginfo = NULL;
    268
    269 return SCIP_OKAY;
    270}
    271
    272/** closes conflict graph file */
    273static
    274void confgraphFree(
    275 void
    276 )
    277{
    278 if( confgraphfile != NULL )
    279 {
    280#ifdef SCIP_CONFGRAPH_DOT
    281 SCIPdotWriteClosing(confgraphfile);
    282#else
    283 SCIPgmlWriteClosing(confgraphfile);
    284#endif
    285 fclose(confgraphfile);
    286
    287 confgraphfile = NULL;
    288 confgraphnconflictsets = 0;
    289 }
    290}
    291
    292/** adds a bound change node to the conflict graph and links it to the currently resolved bound change */
    293static
    294void confgraphAddBdchg(
    295 SCIP_BDCHGINFO* bdchginfo /**< bound change to add to the conflict graph */
    296 )
    297{
    298 const char* colors[] = {
    299 "#8888ff", /* blue for constraint resolving */
    300 "#ffff00", /* yellow for propagator resolving */
    301 "#55ff55" /* green branching decision */
    302 };
    303 char label[SCIP_MAXSTRLEN];
    304 char depth[SCIP_MAXSTRLEN];
    305 int col;
    306
    307 switch( SCIPbdchginfoGetChgtype(bdchginfo) )
    308 {
    310 col = 2;
    311 break;
    313 col = 0;
    314 break;
    316 col = (SCIPbdchginfoGetInferProp(bdchginfo) == NULL ? 1 : 0);
    317 break;
    318 default:
    319 SCIPerrorMessage("invalid bound change type\n");
    320 col = 0;
    321 SCIPABORT();
    322 break;
    323 }
    324
    325 if( SCIPbdchginfoGetDepth(bdchginfo) == INT_MAX )
    326 (void) SCIPsnprintf(depth, SCIP_MAXSTRLEN, "dive");
    327 else
    328 (void) SCIPsnprintf(depth, SCIP_MAXSTRLEN, "%d", SCIPbdchginfoGetDepth(bdchginfo));
    329 (void) SCIPsnprintf(label, SCIP_MAXSTRLEN, "%s %s %g\n[%s:%d]", SCIPvarGetName(SCIPbdchginfoGetVar(bdchginfo)),
    330 SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
    331 SCIPbdchginfoGetNewbound(bdchginfo), depth, SCIPbdchginfoGetPos(bdchginfo));
    332 confgraphWriteNode(bdchginfo, label, "ellipse", colors[col], "#000000");
    333 confgraphWriteEdge(bdchginfo, confgraphcurrentbdchginfo, "#000000");
    334}
    335
    336/** links the already existing bound change node to the currently resolved bound change */
    337static
    338void confgraphLinkBdchg(
    339 SCIP_BDCHGINFO* bdchginfo /**< bound change to add to the conflict graph */
    340 )
    341{
    342 confgraphWriteEdge(bdchginfo, confgraphcurrentbdchginfo, "#000000");
    343}
    344
    345/** marks the given bound change to be the currently resolved bound change */
    346static
    347void confgraphSetCurrentBdchg(
    348 SCIP_BDCHGINFO* bdchginfo /**< bound change to add to the conflict graph */
    349 )
    350{
    351 confgraphcurrentbdchginfo = bdchginfo;
    352}
    353
    354/** marks given conflict set in the conflict graph */
    355static
    356void confgraphMarkConflictset(
    357 SCIP_CONFLICTSET* conflictset /**< conflict set */
    358 )
    359{
    360 char label[SCIP_MAXSTRLEN];
    361 int i;
    362
    363 assert(conflictset != NULL);
    364
    365 confgraphnconflictsets++;
    366 (void) SCIPsnprintf(label, SCIP_MAXSTRLEN, "conf %d (%d)", confgraphnconflictsets, conflictset->validdepth);
    367 confgraphWriteNode((void*)(size_t)confgraphnconflictsets, label, "rectangle", "#ff00ff", "#000000"); /*lint !e571*/
    368 for( i = 0; i < conflictset->nbdchginfos; ++i )
    369 confgraphWriteEdge((void*)(size_t)confgraphnconflictsets, conflictset->bdchginfos[i], "#ff00ff"); /*lint !e571*/
    370}
    371
    372#endif
    373
    374/** Conflict sets */
    375
    376/** resizes the arrays of the conflict set to be able to store at least num bound change entries */
    377static
    379 SCIP_CONFLICTSET* conflictset, /**< conflict set */
    380 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
    381 SCIP_SET* set, /**< global SCIP settings */
    382 int num /**< minimal number of slots in arrays */
    383 )
    384{
    385 assert(conflictset != NULL);
    386 assert(set != NULL);
    387
    388 if( num > conflictset->bdchginfossize )
    389 {
    390 int newsize;
    391
    392 newsize = SCIPsetCalcMemGrowSize(set, num);
    393 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &conflictset->bdchginfos, conflictset->bdchginfossize, newsize) );
    394 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &conflictset->relaxedbds, conflictset->bdchginfossize, newsize) );
    395 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &conflictset->sortvals, conflictset->bdchginfossize, newsize) );
    396 conflictset->bdchginfossize = newsize;
    397 }
    398 assert(num <= conflictset->bdchginfossize);
    399
    400 return SCIP_OKAY;
    401}
    402
    403/** adds a bound change to a conflict set */
    404static
    406 SCIP_CONFLICTSET* conflictset, /**< conflict set */
    407 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
    408 SCIP_SET* set, /**< global SCIP settings */
    409 SCIP_BDCHGINFO* bdchginfo, /**< bound change to add to the conflict set */
    410 SCIP_Real relaxedbd /**< relaxed bound */
    411 )
    412{
    413 SCIP_BDCHGINFO** bdchginfos;
    414 SCIP_Real* relaxedbds;
    415 int* sortvals;
    416 SCIP_VAR* var;
    417 SCIP_BOUNDTYPE boundtype;
    418 int idx;
    419 int sortval;
    420 int pos;
    421
    422 assert(conflictset != NULL);
    423 assert(bdchginfo != NULL);
    424
    425 /* allocate memory for additional element */
    426 SCIP_CALL( conflictsetEnsureBdchginfosMem(conflictset, blkmem, set, conflictset->nbdchginfos+1) );
    427
    428 /* insert the new bound change in the arrays sorted by increasing variable index and by bound type */
    429 bdchginfos = conflictset->bdchginfos;
    430 relaxedbds = conflictset->relaxedbds;
    431 sortvals = conflictset->sortvals;
    432 var = SCIPbdchginfoGetVar(bdchginfo);
    433 boundtype = SCIPbdchginfoGetBoundtype(bdchginfo);
    434 idx = SCIPvarGetIndex(var);
    435 assert(idx < INT_MAX/2);
    436 assert((int)boundtype == 0 || (int)boundtype == 1);
    437 sortval = 2*idx + (int)boundtype; /* first sorting criteria: variable index, second criteria: boundtype */
    438
    439 /* insert new element into the sorted arrays; if an element exits with the same value insert the new element afterwards
    440 *
    441 * @todo check if it better (faster) to first search for the position O(log n) and compare the sort values and if
    442 * they are equal just replace the element and if not run the insert method O(n)
    443 */
    444
    445 SCIPsortedvecInsertIntPtrReal(sortvals, (void**)bdchginfos, relaxedbds, sortval, (void*)bdchginfo, relaxedbd, &conflictset->nbdchginfos, &pos);
    446 assert(pos == conflictset->nbdchginfos - 1 || sortval < sortvals[pos+1]);
    447
    448 /* merge multiple bound changes */
    449 if( pos > 0 && sortval == sortvals[pos-1] )
    450 {
    451 /* this is a multiple bound change */
    452 if( SCIPbdchginfoIsTighter(bdchginfo, bdchginfos[pos-1]) )
    453 {
    454 /* remove the "old" bound change since the "new" one in tighter */
    455 SCIPsortedvecDelPosIntPtrReal(sortvals, (void**)bdchginfos, relaxedbds, pos-1, &conflictset->nbdchginfos);
    456 }
    457 else if( SCIPbdchginfoIsTighter(bdchginfos[pos-1], bdchginfo) )
    458 {
    459 /* remove the "new" bound change since the "old" one is tighter */
    460 SCIPsortedvecDelPosIntPtrReal(sortvals, (void**)bdchginfos, relaxedbds, pos, &conflictset->nbdchginfos);
    461 }
    462 else
    463 {
    464 /* both bound change are equivalent; hence, keep the worse relaxed bound and remove one of them */
    465 relaxedbds[pos-1] = boundtype == SCIP_BOUNDTYPE_LOWER ? MAX(relaxedbds[pos-1], relaxedbd) : MIN(relaxedbds[pos-1], relaxedbd);
    466 SCIPsortedvecDelPosIntPtrReal(sortvals, (void**)bdchginfos, relaxedbds, pos, &conflictset->nbdchginfos);
    467 }
    468 }
    469
    470 if( SCIPvarIsRelaxationOnly(var) )
    471 conflictset->hasrelaxonlyvar = TRUE;
    472
    473 return SCIP_OKAY;
    474}
    475
    476/** calculates the conflict and the repropagation depths of the conflict set */
    477static
    479 SCIP_CONFLICTSET* conflictset /**< conflict set */
    480 )
    481{
    482 int maxdepth[2];
    483 int i;
    484
    485 assert(conflictset != NULL);
    486 assert(conflictset->validdepth <= conflictset->insertdepth);
    487
    488 /* get the depth of the last and last but one bound change */
    489 maxdepth[0] = conflictset->validdepth;
    490 maxdepth[1] = conflictset->validdepth;
    491 for( i = 0; i < conflictset->nbdchginfos; ++i )
    492 {
    493 int depth;
    494
    495 depth = SCIPbdchginfoGetDepth(conflictset->bdchginfos[i]);
    496 assert(depth >= 0);
    497 if( depth > maxdepth[0] )
    498 {
    499 maxdepth[1] = maxdepth[0];
    500 maxdepth[0] = depth;
    501 }
    502 else if( depth > maxdepth[1] )
    503 maxdepth[1] = depth;
    504 }
    505 assert(maxdepth[0] >= maxdepth[1]);
    506
    507 conflictset->conflictdepth = maxdepth[0];
    508 conflictset->repropdepth = maxdepth[1];
    509}
    510
    511/** identifies the depth, at which the conflict set should be added:
    512 * - if the branching rule operates on variables only, and if all branching variables up to a certain
    513 * depth level are member of the conflict, the conflict constraint can only be violated in the subtree
    514 * of the node at that depth, because in all other nodes, at least one of these branching variables
    515 * violates its conflicting bound, such that the conflict constraint is feasible
    516 * - if there is at least one branching variable in a node, we assume, that this branching was performed
    517 * on variables, and that the siblings of this node are disjunct w.r.t. the branching variables' fixings
    518 * - we have to add the conflict set at least in the valid depth of the initial conflict set,
    519 * so we start searching at the first branching after this depth level, i.e. validdepth+1
    520 */
    521static
    523 SCIP_CONFLICTSET* conflictset, /**< conflict set */
    524 SCIP_SET* set, /**< global SCIP settings */
    525 SCIP_TREE* tree /**< branch and bound tree */
    526 )
    527{
    528 SCIP_Bool* branchingincluded;
    529 int currentdepth;
    530 int i;
    531
    532 assert(conflictset != NULL);
    533 assert(set != NULL);
    534 assert(tree != NULL);
    535
    536 /* the conflict set must not be inserted prior to its valid depth */
    537 conflictset->insertdepth = conflictset->validdepth;
    538 assert(conflictset->insertdepth >= 0);
    539
    540 currentdepth = SCIPtreeGetCurrentDepth(tree);
    541 assert(currentdepth == tree->pathlen-1);
    542
    543 /* mark the levels for which a branching variable is included in the conflict set */
    544 SCIP_CALL( SCIPsetAllocBufferArray(set, &branchingincluded, currentdepth+2) );
    545 BMSclearMemoryArray(branchingincluded, currentdepth+2);
    546 for( i = 0; i < conflictset->nbdchginfos; ++i )
    547 {
    548 int depth;
    549
    550 depth = SCIPbdchginfoGetDepth(conflictset->bdchginfos[i]);
    551 depth = MIN(depth, currentdepth+1); /* put diving/probing/strong branching changes in this depth level */
    552 branchingincluded[depth] = TRUE;
    553 }
    554
    555 /* skip additional depth levels where branching on the conflict variables was applied */
    556 while( conflictset->insertdepth < currentdepth && branchingincluded[conflictset->insertdepth+1] )
    557 conflictset->insertdepth++;
    558
    559 /* free temporary memory */
    560 SCIPsetFreeBufferArray(set, &branchingincluded);
    561
    562 assert(conflictset->validdepth <= conflictset->insertdepth && conflictset->insertdepth <= currentdepth);
    563
    564 return SCIP_OKAY;
    565}
    566
    567/** checks whether the first conflict set is redundant to the second one */
    568static
    570 SCIP_CONFLICTSET* conflictset1, /**< first conflict conflict set */
    571 SCIP_CONFLICTSET* conflictset2 /**< second conflict conflict set */
    572 )
    573{
    574 int i1;
    575 int i2;
    576
    577 assert(conflictset1 != NULL);
    578 assert(conflictset2 != NULL);
    579
    580 /* if conflictset1 has smaller validdepth, it is definitely not redundant to conflictset2 */
    581 if( conflictset1->validdepth < conflictset2->validdepth )
    582 return FALSE;
    583
    584 /* check, if all bound changes in conflictset2 are also present at least as tight in conflictset1;
    585 * we can stop immediately, if more bound changes are remaining in conflictset2 than in conflictset1
    586 */
    587 for( i1 = 0, i2 = 0; i2 < conflictset2->nbdchginfos && conflictset1->nbdchginfos - i1 >= conflictset2->nbdchginfos - i2;
    588 ++i1, ++i2 )
    589 {
    590 int sortval;
    591
    592 assert(i2 == 0 || conflictset2->sortvals[i2-1] < conflictset2->sortvals[i2]);
    593
    594 sortval = conflictset2->sortvals[i2];
    595 for( ; i1 < conflictset1->nbdchginfos && conflictset1->sortvals[i1] < sortval; ++i1 ) /*lint !e445*/
    596 {
    597 /* while scanning conflictset1, check consistency */
    598 assert(i1 == 0 || conflictset1->sortvals[i1-1] < conflictset1->sortvals[i1]);
    599 }
    600 if( i1 >= conflictset1->nbdchginfos || conflictset1->sortvals[i1] > sortval
    601 || SCIPbdchginfoIsTighter(conflictset2->bdchginfos[i2], conflictset1->bdchginfos[i1]) )
    602 return FALSE;
    603 }
    604
    605 return (i2 == conflictset2->nbdchginfos);
    606}
    607
    608#ifdef SCIP_DEBUG
    609/** prints a conflict set to the screen */
    611 SCIP_CONFLICTSET* conflictset /**< conflict set */
    612 )
    613{
    614 int i;
    615
    616 assert(conflictset != NULL);
    617 for( i = 0; i < conflictset->nbdchginfos; ++i )
    618 {
    619 SCIPdebugPrintf(" [%d:<%s> %s %g(%g)]", SCIPbdchginfoGetDepth(conflictset->bdchginfos[i]),
    621 SCIPbdchginfoGetBoundtype(conflictset->bdchginfos[i]) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
    622 SCIPbdchginfoGetNewbound(conflictset->bdchginfos[i]), conflictset->relaxedbds[i]);
    623 }
    624 SCIPdebugPrintf("\n");
    625}
    626#endif
    627
    628
    629/** check conflict set for redundancy, other conflicts in the same conflict analysis could have led to global reductions
    630 * an made this conflict set redundant
    631 */
    632static
    634 SCIP_SET* set, /**< global SCIP settings */
    635 SCIP_CONFLICTSET* conflictset /**< conflict set */
    636 )
    637{
    638 SCIP_BDCHGINFO** bdchginfos;
    639 SCIP_VAR* var;
    640 SCIP_Real* relaxedbds;
    642 int v;
    643
    644 assert(set != NULL);
    645 assert(conflictset != NULL);
    646
    647 bdchginfos = conflictset->bdchginfos;
    648 relaxedbds = conflictset->relaxedbds;
    649 assert(bdchginfos != NULL);
    650 assert(relaxedbds != NULL);
    651
    652 /* check all boundtypes and bounds for redundancy */
    653 for( v = conflictset->nbdchginfos - 1; v >= 0; --v )
    654 {
    655 var = SCIPbdchginfoGetVar(bdchginfos[v]);
    656 assert(var != NULL);
    657 assert(SCIPvarGetProbindex(var) >= 0);
    658
    659 /* check if the relaxed bound is really a relaxed bound */
    660 assert(SCIPbdchginfoGetBoundtype(bdchginfos[v]) == SCIP_BOUNDTYPE_LOWER || SCIPsetIsGE(set, relaxedbds[v], SCIPbdchginfoGetNewbound(bdchginfos[v])));
    661 assert(SCIPbdchginfoGetBoundtype(bdchginfos[v]) == SCIP_BOUNDTYPE_UPPER || SCIPsetIsLE(set, relaxedbds[v], SCIPbdchginfoGetNewbound(bdchginfos[v])));
    662
    663 bound = relaxedbds[v];
    664
    665 if( SCIPbdchginfoGetBoundtype(bdchginfos[v]) == SCIP_BOUNDTYPE_UPPER )
    666 {
    667 if( SCIPvarIsIntegral(var) )
    668 {
    669 assert(SCIPsetIsIntegral(set, bound));
    670 bound += 1.0;
    671 }
    672
    673 /* check if the bound is already fulfilled globally */
    675 return TRUE;
    676 }
    677 else
    678 {
    679 assert(SCIPbdchginfoGetBoundtype(bdchginfos[v]) == SCIP_BOUNDTYPE_LOWER);
    680
    681 if( SCIPvarIsIntegral(var) )
    682 {
    683 assert(SCIPsetIsIntegral(set, bound));
    684 bound -= 1.0;
    685 }
    686
    687 /* check if the bound is already fulfilled globally */
    689 return TRUE;
    690 }
    691 }
    692
    693 return FALSE;
    694}
    695
    696/** find global fixings which can be derived from the new conflict set */
    697static
    699 SCIP_SET* set, /**< global SCIP settings */
    700 SCIP_PROB* prob, /**< transformed problem after presolve */
    701 SCIP_STAT* stat, /**< dynamic SCIP statistics */
    702 SCIP_TREE* tree, /**< tree data */
    703 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    704 BMS_BLKMEM* blkmem, /**< block memory */
    705 SCIP_PROB* origprob, /**< original problem */
    706 SCIP_REOPT* reopt, /**< reoptimization data */
    707 SCIP_LP* lp, /**< LP data */
    708 SCIP_CONFLICTSET* conflictset, /**< conflict set to add to the tree */
    709 int* nbdchgs, /**< number of global deducted bound changes due to the conflict set */
    710 int* nredvars, /**< number of redundant and removed variables from conflict set */
    711 SCIP_Bool* redundant /**< did we found a global reduction on a conflict set variable, which makes this conflict redundant */
    712 )
    713{
    714 SCIP_BDCHGINFO** bdchginfos;
    715 SCIP_Real* relaxedbds;
    716 SCIP_VAR* var;
    717 SCIP_Bool* boundtypes;
    718 SCIP_Real* bounds;
    719 SCIP_Longint* nbinimpls;
    720 int* sortvals;
    722 SCIP_Bool isupper;
    723 int ntrivialredvars;
    724 int nbdchginfos;
    725 int nzeroimpls;
    726 int v;
    727
    728 assert(set != NULL);
    729 assert(prob != NULL);
    730 assert(SCIPprobIsTransformed(prob));
    731 assert(conflictset != NULL);
    732 assert(nbdchgs != NULL);
    733 assert(nredvars != NULL);
    734 /* only check conflict sets with more than one variable */
    735 assert(conflictset->nbdchginfos > 1);
    736
    737 *nbdchgs = 0;
    738 *nredvars = 0;
    739
    740 /* due to other conflict in the same conflict analysis, this conflict set might have become redundant */
    741 *redundant = checkRedundancy(set, conflictset);
    742
    743 if( *redundant )
    744 return SCIP_OKAY;
    745
    746 bdchginfos = conflictset->bdchginfos;
    747 relaxedbds = conflictset->relaxedbds;
    748 nbdchginfos = conflictset->nbdchginfos;
    749 sortvals = conflictset->sortvals;
    750
    751 assert(bdchginfos != NULL);
    752 assert(relaxedbds != NULL);
    753 assert(sortvals != NULL);
    754
    755 /* check if the boolean representation of boundtypes matches the 'standard' definition */
    756 assert(SCIP_BOUNDTYPE_LOWER == FALSE); /*lint !e641 !e506*/
    757 assert(SCIP_BOUNDTYPE_UPPER == TRUE); /*lint !e641 !e506*/
    758
    759 ntrivialredvars = 0;
    760
    761 /* due to multiple conflict sets for one conflict, it can happen, that we already have redundant information in the
    762 * conflict set
    763 */
    764 for( v = nbdchginfos - 1; v >= 0; --v )
    765 {
    766 var = SCIPbdchginfoGetVar(bdchginfos[v]);
    767 bound = relaxedbds[v];
    769
    770 /* for integral variable we can increase/decrease the conflicting bound */
    771 if( SCIPvarIsIntegral(var) )
    772 bound += (isupper ? -1.0 : +1.0);
    773
    774 /* if conflict variable cannot fulfill the conflict we can remove it */
    775 if( (isupper && SCIPsetIsFeasLT(set, bound, SCIPvarGetLbGlobal(var))) ||
    776 (!isupper && SCIPsetIsFeasGT(set, bound, SCIPvarGetUbGlobal(var))) )
    777 {
    778 SCIPsetDebugMsg(set, "remove redundant variable <%s> from conflict set\n", SCIPvarGetName(var));
    779
    780 bdchginfos[v] = bdchginfos[nbdchginfos - 1];
    781 relaxedbds[v] = relaxedbds[nbdchginfos - 1];
    782 sortvals[v] = sortvals[nbdchginfos - 1];
    783
    784 --nbdchginfos;
    785 ++ntrivialredvars;
    786 }
    787 }
    788 assert(ntrivialredvars + nbdchginfos == conflictset->nbdchginfos);
    789
    790 SCIPsetDebugMsg(set, "trivially removed %d redundant of %d variables from conflictset (%p)\n", ntrivialredvars, conflictset->nbdchginfos, (void*)conflictset);
    791 conflictset->nbdchginfos = nbdchginfos;
    792
    793 /* all variables where removed, the conflict cannot be fulfilled, i.e., we have an infeasibility proof */
    794 if( conflictset->nbdchginfos == 0 )
    795 return SCIP_OKAY;
    796
    797 /* do not check to big or trivial conflicts */
    798 if( conflictset->nbdchginfos > set->conf_maxvarsdetectimpliedbounds || conflictset->nbdchginfos == 1 )
    799 {
    800 *nredvars = ntrivialredvars;
    801 return SCIP_OKAY;
    802 }
    803
    804 /* create array of boundtypes, and bound values in conflict set */
    805 SCIP_CALL( SCIPsetAllocBufferArray(set, &boundtypes, nbdchginfos) );
    806 SCIP_CALL( SCIPsetAllocBufferArray(set, &bounds, nbdchginfos) );
    807 /* memory for the estimates for binary implications used for sorting */
    808 SCIP_CALL( SCIPsetAllocBufferArray(set, &nbinimpls, nbdchginfos) );
    809
    810 nzeroimpls = 0;
    811
    812 /* collect estimates and initialize variables, boundtypes, and bounds array */
    813 for( v = 0; v < nbdchginfos; ++v )
    814 {
    815 var = SCIPbdchginfoGetVar(bdchginfos[v]);
    816 boundtypes[v] = (SCIP_Bool) SCIPboundtypeOpposite(SCIPbdchginfoGetBoundtype(bdchginfos[v]));
    817 bounds[v] = relaxedbds[v];
    818
    819 assert(SCIPvarGetProbindex(var) >= 0);
    820
    821 /* check if the relaxed bound is really a relaxed bound */
    822 assert(SCIPbdchginfoGetBoundtype(bdchginfos[v]) == SCIP_BOUNDTYPE_LOWER || SCIPsetIsGE(set, relaxedbds[v], SCIPbdchginfoGetNewbound(bdchginfos[v])));
    823 assert(SCIPbdchginfoGetBoundtype(bdchginfos[v]) == SCIP_BOUNDTYPE_UPPER || SCIPsetIsLE(set, relaxedbds[v], SCIPbdchginfoGetNewbound(bdchginfos[v])));
    824
    825 /* for continuous variables, we can only use the relaxed version of the bounds negation: !(x <= u) -> x >= u */
    826 if( SCIPvarIsBinary(var) )
    827 {
    828 if( !boundtypes[v] )
    829 {
    830 assert(SCIPsetIsZero(set, bounds[v]));
    831 bounds[v] = 1.0;
    832 nbinimpls[v] = (SCIP_Longint)SCIPvarGetNCliques(var, TRUE) * 2;
    833 }
    834 else
    835 {
    836 assert(SCIPsetIsEQ(set, bounds[v], 1.0));
    837 bounds[v] = 0.0;
    838 nbinimpls[v] = (SCIP_Longint)SCIPvarGetNCliques(var, FALSE) * 2;
    839 }
    840 }
    841 else if( SCIPvarIsIntegral(var) )
    842 {
    843 assert(SCIPsetIsIntegral(set, bounds[v]));
    844
    845 bounds[v] += ((!boundtypes[v]) ? +1.0 : -1.0);
    846 nbinimpls[v] = (boundtypes[v] ? SCIPvarGetNVlbs(var) : SCIPvarGetNVubs(var));
    847 }
    848 else if( ((!boundtypes[v]) && SCIPsetIsFeasEQ(set, SCIPvarGetLbGlobal(var), bounds[v]))
    849 || ((boundtypes[v]) && SCIPsetIsFeasEQ(set, SCIPvarGetUbGlobal(var), bounds[v])) )
    850 {
    851 /* the literal is satisfied in global bounds (may happen due to weak "negation" of continuous variables)
    852 * -> discard the conflict constraint
    853 */
    854 break;
    855 }
    856 else
    857 {
    858 nbinimpls[v] = (boundtypes[v] ? SCIPvarGetNVlbs(var) : SCIPvarGetNVubs(var));
    859 }
    860
    861 if( nbinimpls[v] == 0 )
    862 ++nzeroimpls;
    863 }
    864
    865 /* starting to derive global bound changes */
    866 if( v == nbdchginfos && ((!set->conf_fullshortenconflict && nzeroimpls < 2) || (set->conf_fullshortenconflict && nzeroimpls < nbdchginfos)) )
    867 {
    868 SCIP_VAR** vars;
    869 SCIP_Bool* redundants;
    870 SCIP_Bool glbinfeas;
    871
    872 /* sort variables in increasing order of binary implications to gain speed later on */
    873 SCIPsortLongPtrRealRealBool(nbinimpls, (void**)bdchginfos, relaxedbds, bounds, boundtypes, v);
    874
    875 SCIPsetDebugMsg(set, "checking for global reductions and redundant conflict variables(in %s) on conflict:\n", SCIPprobGetName(prob));
    876 SCIPsetDebugMsg(set, "[");
    877 for( v = 0; v < nbdchginfos; ++v )
    878 {
    879 SCIPsetDebugMsgPrint(set, "%s %s %g", SCIPvarGetName(SCIPbdchginfoGetVar(bdchginfos[v])), (!boundtypes[v]) ? ">=" : "<=", bounds[v]);
    880 if( v < nbdchginfos - 1 )
    882 }
    884
    886 SCIP_CALL( SCIPsetAllocCleanBufferArray(set, &redundants, v) );
    887
    888 /* initialize conflict variable data */
    889 for( v = 0; v < nbdchginfos; ++v )
    890 vars[v] = SCIPbdchginfoGetVar(bdchginfos[v]);
    891
    892 SCIP_CALL( SCIPshrinkDisjunctiveVarSet(set->scip, vars, bounds, boundtypes, redundants, nbdchginfos, nredvars, \
    893 nbdchgs, redundant, &glbinfeas, set->conf_fullshortenconflict) );
    894
    895 if( glbinfeas )
    896 {
    897 SCIPsetDebugMsg(set, "conflict set (%p) led to global infeasibility\n", (void*) conflictset);
    898
    899 SCIP_CALL( SCIPnodeCutoff(SCIPtreeGetRootNode(tree), set, stat, eventfilter, tree, prob, origprob, reopt, lp, blkmem) );
    900
    901 /* clear the memory array before freeing it */
    902 BMSclearMemoryArray(redundants, nbdchginfos);
    903 goto TERMINATE;
    904 }
    905
    906#ifdef SCIP_DEBUG
    907 if( *nbdchgs > 0 )
    908 {
    909 SCIPsetDebugMsg(set, "conflict set (%p) led to %d global bound reductions\n", (void*) conflictset, *nbdchgs);
    910 }
    911#endif
    912
    913 /* remove as redundant marked variables */
    914 if( *redundant )
    915 {
    916 SCIPsetDebugMsg(set, "conflict set (%p) is redundant because at least one global reduction, fulfills the conflict constraint\n", (void*)conflictset);
    917
    918 /* clear the memory array before freeing it */
    919 BMSclearMemoryArray(redundants, nbdchginfos);
    920 }
    921 else if( *nredvars > 0 )
    922 {
    923 assert(bdchginfos == conflictset->bdchginfos);
    924 assert(relaxedbds == conflictset->relaxedbds);
    925 assert(sortvals == conflictset->sortvals);
    926
    927 for( v = nbdchginfos - 1; v >= 0; --v )
    928 {
    929 /* if conflict variable was marked to be redundant remove it */
    930 if( redundants[v] )
    931 {
    932 SCIPsetDebugMsg(set, "remove redundant variable <%s> from conflict set\n", SCIPvarGetName(SCIPbdchginfoGetVar(bdchginfos[v])));
    933
    934 bdchginfos[v] = bdchginfos[nbdchginfos - 1];
    935 relaxedbds[v] = relaxedbds[nbdchginfos - 1];
    936 sortvals[v] = sortvals[nbdchginfos - 1];
    937
    938 /* reset redundants[v] to 0 */
    939 redundants[v] = 0;
    940
    941 --nbdchginfos;
    942 }
    943 }
    944 assert((*nredvars) + nbdchginfos == conflictset->nbdchginfos);
    945
    946 SCIPsetDebugMsg(set, "removed %d redundant of %d variables from conflictset (%p)\n", (*nredvars), conflictset->nbdchginfos, (void*)conflictset);
    947 conflictset->nbdchginfos = nbdchginfos;
    948 }
    949 else
    950 {
    951 /* clear the memory array before freeing it */
    952 BMSclearMemoryArray(redundants, nbdchginfos);
    953 }
    954
    955 TERMINATE:
    956 SCIPsetFreeCleanBufferArray(set, &redundants);
    958 }
    959
    960 /* free temporary memory */
    961 SCIPsetFreeBufferArray(set, &nbinimpls);
    962 SCIPsetFreeBufferArray(set, &bounds);
    963 SCIPsetFreeBufferArray(set, &boundtypes);
    964
    965 *nredvars += ntrivialredvars;
    966
    967 return SCIP_OKAY;
    968}
    969
    970/** clears the given conflict set */
    971static
    973 SCIP_CONFLICTSET* conflictset /**< conflict set */
    974 )
    975{
    976 assert(conflictset != NULL);
    977
    978 conflictset->nbdchginfos = 0;
    979 conflictset->validdepth = 0;
    980 conflictset->insertdepth = 0;
    981 conflictset->conflictdepth = 0;
    982 conflictset->repropdepth = 0;
    983 conflictset->repropagate = TRUE;
    984 conflictset->usescutoffbound = FALSE;
    985 conflictset->hasrelaxonlyvar = FALSE;
    986 conflictset->conflicttype = SCIP_CONFTYPE_UNKNOWN;
    987}
    988
    989/** creates an empty conflict set */
    991 SCIP_CONFLICTSET** conflictset, /**< pointer to store the conflict set */
    992 BMS_BLKMEM* blkmem /**< block memory of transformed problem */
    993 )
    994{
    995 assert(conflictset != NULL);
    996
    997 SCIP_ALLOC( BMSallocBlockMemory(blkmem, conflictset) );
    998 (*conflictset)->bdchginfos = NULL;
    999 (*conflictset)->relaxedbds = NULL;
    1000 (*conflictset)->sortvals = NULL;
    1001 (*conflictset)->bdchginfossize = 0;
    1002
    1003 conflictsetClear(*conflictset);
    1004
    1005 return SCIP_OKAY;
    1006}
    1007
    1008/** creates a copy of the given conflict set, allocating an additional amount of memory */
    1009static
    1011 SCIP_CONFLICTSET** targetconflictset, /**< pointer to store the conflict set */
    1012 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
    1013 SCIP_CONFLICTSET* sourceconflictset, /**< source conflict set */
    1014 int nadditionalelems /**< number of additional elements to allocate memory for */
    1015 )
    1016{
    1017 int targetsize;
    1018
    1019 assert(targetconflictset != NULL);
    1020 assert(sourceconflictset != NULL);
    1021
    1022 targetsize = sourceconflictset->nbdchginfos + nadditionalelems;
    1023 SCIP_ALLOC( BMSallocBlockMemory(blkmem, targetconflictset) );
    1024 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*targetconflictset)->bdchginfos, targetsize) );
    1025 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*targetconflictset)->relaxedbds, targetsize) );
    1026 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*targetconflictset)->sortvals, targetsize) );
    1027 (*targetconflictset)->bdchginfossize = targetsize;
    1028
    1029 BMScopyMemoryArray((*targetconflictset)->bdchginfos, sourceconflictset->bdchginfos, sourceconflictset->nbdchginfos);
    1030 BMScopyMemoryArray((*targetconflictset)->relaxedbds, sourceconflictset->relaxedbds, sourceconflictset->nbdchginfos);
    1031 BMScopyMemoryArray((*targetconflictset)->sortvals, sourceconflictset->sortvals, sourceconflictset->nbdchginfos);
    1032
    1033 (*targetconflictset)->nbdchginfos = sourceconflictset->nbdchginfos;
    1034 (*targetconflictset)->validdepth = sourceconflictset->validdepth;
    1035 (*targetconflictset)->insertdepth = sourceconflictset->insertdepth;
    1036 (*targetconflictset)->conflictdepth = sourceconflictset->conflictdepth;
    1037 (*targetconflictset)->repropdepth = sourceconflictset->repropdepth;
    1038 (*targetconflictset)->usescutoffbound = sourceconflictset->usescutoffbound;
    1039 (*targetconflictset)->hasrelaxonlyvar = sourceconflictset->hasrelaxonlyvar;
    1040 (*targetconflictset)->conflicttype = sourceconflictset->conflicttype;
    1041
    1042 return SCIP_OKAY;
    1043}
    1044
    1045/** frees a conflict set */
    1047 SCIP_CONFLICTSET** conflictset, /**< pointer to the conflict set */
    1048 BMS_BLKMEM* blkmem /**< block memory of transformed problem */
    1049 )
    1050{
    1051 assert(conflictset != NULL);
    1052 assert(*conflictset != NULL);
    1053
    1054 BMSfreeBlockMemoryArrayNull(blkmem, &(*conflictset)->bdchginfos, (*conflictset)->bdchginfossize);
    1055 BMSfreeBlockMemoryArrayNull(blkmem, &(*conflictset)->relaxedbds, (*conflictset)->bdchginfossize);
    1056 BMSfreeBlockMemoryArrayNull(blkmem, &(*conflictset)->sortvals, (*conflictset)->bdchginfossize);
    1057 BMSfreeBlockMemory(blkmem, conflictset);
    1058}
    1059
    1060/** calculates the score of the conflict set
    1061 *
    1062 * the score is weighted sum of number of bound changes, repropagation depth, and valid depth
    1063 */
    1064static
    1066 SCIP_CONFLICTSET* conflictset, /**< conflict set */
    1067 SCIP_SET* set /**< global SCIP settings */
    1068 )
    1069{
    1070 assert(conflictset != NULL);
    1071
    1072 return -(set->conf_weightsize * conflictset->nbdchginfos
    1073 + set->conf_weightrepropdepth * conflictset->repropdepth
    1074 + set->conf_weightvaliddepth * conflictset->validdepth);
    1075}
    1076
    1077
    1078/*
    1079 * Conflict Handler
    1080 */
    1081
    1082/** compares two conflict handlers w. r. to their priority */
    1083SCIP_DECL_SORTPTRCOMP(SCIPconflicthdlrComp)
    1084{ /*lint --e{715}*/
    1085 return ((SCIP_CONFLICTHDLR*)elem2)->priority - ((SCIP_CONFLICTHDLR*)elem1)->priority;
    1086}
    1087
    1088/** comparison method for sorting conflict handler w.r.t. to their name */
    1089SCIP_DECL_SORTPTRCOMP(SCIPconflicthdlrCompName)
    1090{
    1092}
    1093
    1094/** method to call, when the priority of a conflict handler was changed */
    1095static
    1096SCIP_DECL_PARAMCHGD(paramChgdConflicthdlrPriority)
    1097{ /*lint --e{715}*/
    1098 SCIP_PARAMDATA* paramdata;
    1099
    1100 paramdata = SCIPparamGetData(param);
    1101 assert(paramdata != NULL);
    1102
    1103 /* use SCIPsetConflicthdlrPriority() to mark the conflicthdlrs unsorted */
    1104 SCIP_CALL( SCIPsetConflicthdlrPriority(scip, (SCIP_CONFLICTHDLR*)paramdata, SCIPparamGetInt(param)) ); /*lint !e740*/
    1105
    1106 return SCIP_OKAY;
    1107}
    1108
    1109/** copies the given conflict handler to a new scip */
    1111 SCIP_CONFLICTHDLR* conflicthdlr, /**< conflict handler */
    1112 SCIP_SET* set /**< SCIP_SET of SCIP to copy to */
    1113 )
    1114{
    1115 assert(conflicthdlr != NULL);
    1116 assert(set != NULL);
    1117 assert(set->scip != NULL);
    1118
    1119 if( conflicthdlr->conflictcopy != NULL )
    1120 {
    1121 SCIPsetDebugMsg(set, "including conflict handler %s in subscip %p\n", SCIPconflicthdlrGetName(conflicthdlr), (void*)set->scip);
    1122 SCIP_CALL( conflicthdlr->conflictcopy(set->scip, conflicthdlr) );
    1123 }
    1124
    1125 return SCIP_OKAY;
    1126}
    1127
    1128/** internal method for creating a conflict handler */
    1129static
    1131 SCIP_CONFLICTHDLR** conflicthdlr, /**< pointer to conflict handler data structure */
    1132 SCIP_SET* set, /**< global SCIP settings */
    1133 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    1134 BMS_BLKMEM* blkmem, /**< block memory for parameter settings */
    1135 const char* name, /**< name of conflict handler */
    1136 const char* desc, /**< description of conflict handler */
    1137 int priority, /**< priority of the conflict handler */
    1138 SCIP_DECL_CONFLICTCOPY((*conflictcopy)), /**< copy method of conflict handler or NULL if you don't want to copy your plugin into sub-SCIPs */
    1139 SCIP_DECL_CONFLICTFREE((*conflictfree)), /**< destructor of conflict handler */
    1140 SCIP_DECL_CONFLICTINIT((*conflictinit)), /**< initialize conflict handler */
    1141 SCIP_DECL_CONFLICTEXIT((*conflictexit)), /**< deinitialize conflict handler */
    1142 SCIP_DECL_CONFLICTINITSOL((*conflictinitsol)),/**< solving process initialization method of conflict handler */
    1143 SCIP_DECL_CONFLICTEXITSOL((*conflictexitsol)),/**< solving process deinitialization method of conflict handler */
    1144 SCIP_DECL_CONFLICTEXEC((*conflictexec)), /**< conflict processing method of conflict handler */
    1145 SCIP_CONFLICTHDLRDATA* conflicthdlrdata /**< conflict handler data */
    1146 )
    1147{
    1149 char paramdesc[SCIP_MAXSTRLEN];
    1150
    1151 assert(conflicthdlr != NULL);
    1152 assert(name != NULL);
    1153 assert(desc != NULL);
    1154
    1155 SCIP_ALLOC( BMSallocMemory(conflicthdlr) );
    1156 BMSclearMemory(*conflicthdlr);
    1157
    1158 SCIP_ALLOC( BMSduplicateMemoryArray(&(*conflicthdlr)->name, name, strlen(name)+1) );
    1159 SCIP_ALLOC( BMSduplicateMemoryArray(&(*conflicthdlr)->desc, desc, strlen(desc)+1) );
    1160 (*conflicthdlr)->priority = priority;
    1161 (*conflicthdlr)->conflictcopy = conflictcopy;
    1162 (*conflicthdlr)->conflictfree = conflictfree;
    1163 (*conflicthdlr)->conflictinit = conflictinit;
    1164 (*conflicthdlr)->conflictexit = conflictexit;
    1165 (*conflicthdlr)->conflictinitsol = conflictinitsol;
    1166 (*conflicthdlr)->conflictexitsol = conflictexitsol;
    1167 (*conflicthdlr)->conflictexec = conflictexec;
    1168 (*conflicthdlr)->conflicthdlrdata = conflicthdlrdata;
    1169 (*conflicthdlr)->initialized = FALSE;
    1170
    1171 SCIP_CALL( SCIPclockCreate(&(*conflicthdlr)->setuptime, SCIP_CLOCKTYPE_DEFAULT) );
    1172 SCIP_CALL( SCIPclockCreate(&(*conflicthdlr)->conflicttime, SCIP_CLOCKTYPE_DEFAULT) );
    1173
    1174 /* add parameters */
    1175 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "conflict/%s/priority", name);
    1176 (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "priority of conflict handler <%s>", name);
    1177 SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc, &(*conflicthdlr)->priority, TRUE, \
    1178 priority, INT_MIN, INT_MAX, paramChgdConflicthdlrPriority, (SCIP_PARAMDATA*)(*conflicthdlr)) ); /*lint !e740*/
    1179
    1180 return SCIP_OKAY;
    1181}
    1182
    1183/** creates a conflict handler */
    1185 SCIP_CONFLICTHDLR** conflicthdlr, /**< pointer to conflict handler data structure */
    1186 SCIP_SET* set, /**< global SCIP settings */
    1187 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    1188 BMS_BLKMEM* blkmem, /**< block memory for parameter settings */
    1189 const char* name, /**< name of conflict handler */
    1190 const char* desc, /**< description of conflict handler */
    1191 int priority, /**< priority of the conflict handler */
    1192 SCIP_DECL_CONFLICTCOPY((*conflictcopy)), /**< copy method of conflict handler or NULL if you don't want to
    1193 * copy your plugin into sub-SCIPs */
    1194 SCIP_DECL_CONFLICTFREE((*conflictfree)), /**< destructor of conflict handler */
    1195 SCIP_DECL_CONFLICTINIT((*conflictinit)), /**< initialize conflict handler */
    1196 SCIP_DECL_CONFLICTEXIT((*conflictexit)), /**< deinitialize conflict handler */
    1197 SCIP_DECL_CONFLICTINITSOL((*conflictinitsol)),/**< solving process initialization method of conflict handler */
    1198 SCIP_DECL_CONFLICTEXITSOL((*conflictexitsol)),/**< solving process deinitialization method of conflict handler */
    1199 SCIP_DECL_CONFLICTEXEC((*conflictexec)), /**< conflict processing method of conflict handler */
    1200 SCIP_CONFLICTHDLRDATA* conflicthdlrdata /**< conflict handler data */
    1201 )
    1202{
    1203 assert(conflicthdlr != NULL);
    1204 assert(name != NULL);
    1205 assert(desc != NULL);
    1206
    1207 SCIP_CALL_FINALLY( doConflicthdlrCreate(conflicthdlr, set, messagehdlr, blkmem, name, desc, priority,
    1208 conflictcopy, conflictfree, conflictinit, conflictexit, conflictinitsol, conflictexitsol, conflictexec,
    1209 conflicthdlrdata), (void) SCIPconflicthdlrFree(conflicthdlr, set) );
    1210
    1211 return SCIP_OKAY;
    1212}
    1213
    1214/** calls destructor and frees memory of conflict handler */
    1216 SCIP_CONFLICTHDLR** conflicthdlr, /**< pointer to conflict handler data structure */
    1217 SCIP_SET* set /**< global SCIP settings */
    1218 )
    1219{
    1220 assert(conflicthdlr != NULL);
    1221 if( *conflicthdlr == NULL )
    1222 return SCIP_OKAY;
    1223 assert(!(*conflicthdlr)->initialized);
    1224 assert(set != NULL);
    1225
    1226 /* call destructor of conflict handler */
    1227 if( (*conflicthdlr)->conflictfree != NULL )
    1228 {
    1229 SCIP_CALL( (*conflicthdlr)->conflictfree(set->scip, *conflicthdlr) );
    1230 }
    1231
    1232 SCIPclockFree(&(*conflicthdlr)->conflicttime);
    1233 SCIPclockFree(&(*conflicthdlr)->setuptime);
    1234
    1235 BMSfreeMemoryArrayNull(&(*conflicthdlr)->name);
    1236 BMSfreeMemoryArrayNull(&(*conflicthdlr)->desc);
    1237 BMSfreeMemory(conflicthdlr);
    1238
    1239 return SCIP_OKAY;
    1240}
    1241
    1242/** calls initialization method of conflict handler */
    1244 SCIP_CONFLICTHDLR* conflicthdlr, /**< conflict handler */
    1245 SCIP_SET* set /**< global SCIP settings */
    1246 )
    1247{
    1248 assert(conflicthdlr != NULL);
    1249 assert(set != NULL);
    1250
    1251 if( conflicthdlr->initialized )
    1252 {
    1253 SCIPerrorMessage("conflict handler <%s> already initialized\n", conflicthdlr->name);
    1254 return SCIP_INVALIDCALL;
    1255 }
    1256
    1257 if( set->misc_resetstat )
    1258 {
    1259 SCIPclockReset(conflicthdlr->setuptime);
    1260 SCIPclockReset(conflicthdlr->conflicttime);
    1261 }
    1262
    1263 /* call initialization method of conflict handler */
    1264 if( conflicthdlr->conflictinit != NULL )
    1265 {
    1266 /* start timing */
    1267 SCIPclockStart(conflicthdlr->setuptime, set);
    1268
    1269 SCIP_CALL( conflicthdlr->conflictinit(set->scip, conflicthdlr) );
    1270
    1271 /* stop timing */
    1272 SCIPclockStop(conflicthdlr->setuptime, set);
    1273 }
    1274 conflicthdlr->initialized = TRUE;
    1275
    1276 return SCIP_OKAY;
    1277}
    1278
    1279/** calls exit method of conflict handler */
    1281 SCIP_CONFLICTHDLR* conflicthdlr, /**< conflict handler */
    1282 SCIP_SET* set /**< global SCIP settings */
    1283 )
    1284{
    1285 assert(conflicthdlr != NULL);
    1286 assert(set != NULL);
    1287
    1288 if( !conflicthdlr->initialized )
    1289 {
    1290 SCIPerrorMessage("conflict handler <%s> not initialized\n", conflicthdlr->name);
    1291 return SCIP_INVALIDCALL;
    1292 }
    1293
    1294 /* call deinitialization method of conflict handler */
    1295 if( conflicthdlr->conflictexit != NULL )
    1296 {
    1297 /* start timing */
    1298 SCIPclockStart(conflicthdlr->setuptime, set);
    1299
    1300 SCIP_CALL( conflicthdlr->conflictexit(set->scip, conflicthdlr) );
    1301
    1302 /* stop timing */
    1303 SCIPclockStop(conflicthdlr->setuptime, set);
    1304 }
    1305 conflicthdlr->initialized = FALSE;
    1306
    1307 return SCIP_OKAY;
    1308}
    1309
    1310/** informs conflict handler that the branch and bound process is being started */
    1312 SCIP_CONFLICTHDLR* conflicthdlr, /**< conflict handler */
    1313 SCIP_SET* set /**< global SCIP settings */
    1314 )
    1315{
    1316 assert(conflicthdlr != NULL);
    1317 assert(set != NULL);
    1318
    1319 /* call solving process initialization method of conflict handler */
    1320 if( conflicthdlr->conflictinitsol != NULL )
    1321 {
    1322 /* start timing */
    1323 SCIPclockStart(conflicthdlr->setuptime, set);
    1324
    1325 SCIP_CALL( conflicthdlr->conflictinitsol(set->scip, conflicthdlr) );
    1326
    1327 /* stop timing */
    1328 SCIPclockStop(conflicthdlr->setuptime, set);
    1329 }
    1330
    1331 return SCIP_OKAY;
    1332}
    1333
    1334/** informs conflict handler that the branch and bound process data is being freed */
    1336 SCIP_CONFLICTHDLR* conflicthdlr, /**< conflict handler */
    1337 SCIP_SET* set /**< global SCIP settings */
    1338 )
    1339{
    1340 assert(conflicthdlr != NULL);
    1341 assert(set != NULL);
    1342
    1343 /* call solving process deinitialization method of conflict handler */
    1344 if( conflicthdlr->conflictexitsol != NULL )
    1345 {
    1346 /* start timing */
    1347 SCIPclockStart(conflicthdlr->setuptime, set);
    1348
    1349 SCIP_CALL( conflicthdlr->conflictexitsol(set->scip, conflicthdlr) );
    1350
    1351 /* stop timing */
    1352 SCIPclockStop(conflicthdlr->setuptime, set);
    1353 }
    1354
    1355 return SCIP_OKAY;
    1356}
    1357
    1358/** calls execution method of conflict handler */
    1360 SCIP_CONFLICTHDLR* conflicthdlr, /**< conflict handler */
    1361 SCIP_SET* set, /**< global SCIP settings */
    1362 SCIP_NODE* node, /**< node to add conflict constraint to */
    1363 SCIP_NODE* validnode, /**< node at which the constraint is valid */
    1364 SCIP_BDCHGINFO** bdchginfos, /**< bound change resembling the conflict set */
    1365 SCIP_Real* relaxedbds, /**< array with relaxed bounds which are efficient to create a valid conflict */
    1366 int nbdchginfos, /**< number of bound changes in the conflict set */
    1367 SCIP_CONFTYPE conftype, /**< type of the conflict */
    1368 SCIP_Bool usescutoffbound, /**< depends the conflict on the cutoff bound? */
    1369 SCIP_Bool resolved, /**< was the conflict set already used to create a constraint? */
    1370 SCIP_RESULT* result /**< pointer to store the result of the callback method */
    1371 )
    1372{
    1373 assert(conflicthdlr != NULL);
    1374 assert(set != NULL);
    1375 assert(bdchginfos != NULL || nbdchginfos == 0);
    1376 assert(result != NULL);
    1377
    1378 /* call solution start method of conflict handler */
    1379 *result = SCIP_DIDNOTRUN;
    1380 if( conflicthdlr->conflictexec != NULL )
    1381 {
    1382 /* start timing */
    1383 SCIPclockStart(conflicthdlr->conflicttime, set);
    1384
    1385 SCIP_CALL( conflicthdlr->conflictexec(set->scip, conflicthdlr, node, validnode, bdchginfos, relaxedbds, nbdchginfos,
    1386 conftype, usescutoffbound, set->conf_separate, (SCIPnodeGetDepth(validnode) > 0), set->conf_dynamic,
    1387 set->conf_removable, resolved, result) );
    1388
    1389 /* stop timing */
    1390 SCIPclockStop(conflicthdlr->conflicttime, set);
    1391
    1392 if( *result != SCIP_CONSADDED
    1393 && *result != SCIP_DIDNOTFIND
    1394 && *result != SCIP_DIDNOTRUN )
    1395 {
    1396 SCIPerrorMessage("execution method of conflict handler <%s> returned invalid result <%d>\n",
    1397 conflicthdlr->name, *result);
    1398 return SCIP_INVALIDRESULT;
    1399 }
    1400 }
    1401
    1402 return SCIP_OKAY;
    1403}
    1404
    1405/** gets user data of conflict handler */
    1407 SCIP_CONFLICTHDLR* conflicthdlr /**< conflict handler */
    1408 )
    1409{
    1410 assert(conflicthdlr != NULL);
    1411
    1412 return conflicthdlr->conflicthdlrdata;
    1413}
    1414
    1415/** sets user data of conflict handler; user has to free old data in advance! */
    1417 SCIP_CONFLICTHDLR* conflicthdlr, /**< conflict handler */
    1418 SCIP_CONFLICTHDLRDATA* conflicthdlrdata /**< new conflict handler user data */
    1419 )
    1420{
    1421 assert(conflicthdlr != NULL);
    1422
    1423 conflicthdlr->conflicthdlrdata = conflicthdlrdata;
    1424}
    1425
    1426/** set copy method of conflict handler */
    1428 SCIP_CONFLICTHDLR* conflicthdlr, /**< conflict handler */
    1429 SCIP_DECL_CONFLICTCOPY((*conflictcopy)) /**< copy method of the conflict handler */
    1430 )
    1431{
    1432 assert(conflicthdlr != NULL);
    1433
    1434 conflicthdlr->conflictcopy = conflictcopy;
    1435}
    1436
    1437/** set destructor of conflict handler */
    1439 SCIP_CONFLICTHDLR* conflicthdlr, /**< conflict handler */
    1440 SCIP_DECL_CONFLICTFREE((*conflictfree)) /**< destructor of conflict handler */
    1441 )
    1442{
    1443 assert(conflicthdlr != NULL);
    1444
    1445 conflicthdlr->conflictfree = conflictfree;
    1446}
    1447
    1448/** set initialization method of conflict handler */
    1449
    1451 SCIP_CONFLICTHDLR* conflicthdlr, /**< conflict handler */
    1452 SCIP_DECL_CONFLICTINIT((*conflictinit)) /**< initialization method conflict handler */
    1453 )
    1454{
    1455 assert(conflicthdlr != NULL);
    1456
    1457 conflicthdlr->conflictinit = conflictinit;
    1458}
    1459
    1460/** set deinitialization method of conflict handler */
    1462 SCIP_CONFLICTHDLR* conflicthdlr, /**< conflict handler */
    1463 SCIP_DECL_CONFLICTEXIT((*conflictexit)) /**< deinitialization method conflict handler */
    1464 )
    1465{
    1466 assert(conflicthdlr != NULL);
    1467
    1468 conflicthdlr->conflictexit = conflictexit;
    1469}
    1470
    1471/** set solving process initialization method of conflict handler */
    1473 SCIP_CONFLICTHDLR* conflicthdlr, /**< conflict handler */
    1474 SCIP_DECL_CONFLICTINITSOL((*conflictinitsol))/**< solving process initialization method of conflict handler */
    1475 )
    1476{
    1477 assert(conflicthdlr != NULL);
    1478
    1479 conflicthdlr->conflictinitsol = conflictinitsol;
    1480}
    1481
    1482/** set solving process deinitialization method of conflict handler */
    1484 SCIP_CONFLICTHDLR* conflicthdlr, /**< conflict handler */
    1485 SCIP_DECL_CONFLICTEXITSOL((*conflictexitsol))/**< solving process deinitialization method of conflict handler */
    1486 )
    1487{
    1488 assert(conflicthdlr != NULL);
    1489
    1490 conflicthdlr->conflictexitsol = conflictexitsol;
    1491}
    1492
    1493/** gets name of conflict handler */
    1495 SCIP_CONFLICTHDLR* conflicthdlr /**< conflict handler */
    1496 )
    1497{
    1498 assert(conflicthdlr != NULL);
    1499
    1500 return conflicthdlr->name;
    1501}
    1502
    1503/** gets description of conflict handler */
    1505 SCIP_CONFLICTHDLR* conflicthdlr /**< conflict handler */
    1506 )
    1507{
    1508 assert(conflicthdlr != NULL);
    1509
    1510 return conflicthdlr->desc;
    1511}
    1512
    1513/** gets priority of conflict handler */
    1515 SCIP_CONFLICTHDLR* conflicthdlr /**< conflict handler */
    1516 )
    1517{
    1518 assert(conflicthdlr != NULL);
    1519
    1520 return conflicthdlr->priority;
    1521}
    1522
    1523/** sets priority of conflict handler */
    1525 SCIP_CONFLICTHDLR* conflicthdlr, /**< conflict handler */
    1526 SCIP_SET* set, /**< global SCIP settings */
    1527 int priority /**< new priority of the conflict handler */
    1528 )
    1529{
    1530 assert(conflicthdlr != NULL);
    1531 assert(set != NULL);
    1532
    1533 conflicthdlr->priority = priority;
    1534 set->conflicthdlrssorted = FALSE;
    1535}
    1536
    1537/** is conflict handler initialized? */
    1539 SCIP_CONFLICTHDLR* conflicthdlr /**< conflict handler */
    1540 )
    1541{
    1542 assert(conflicthdlr != NULL);
    1543
    1544 return conflicthdlr->initialized;
    1545}
    1546
    1547/** enables or disables all clocks of \p conflicthdlr, depending on the value of the flag */
    1549 SCIP_CONFLICTHDLR* conflicthdlr, /**< the conflict handler for which all clocks should be enabled or disabled */
    1550 SCIP_Bool enable /**< should the clocks of the conflict handler be enabled? */
    1551 )
    1552{
    1553 assert(conflicthdlr != NULL);
    1554
    1555 SCIPclockEnableOrDisable(conflicthdlr->setuptime, enable);
    1556 SCIPclockEnableOrDisable(conflicthdlr->conflicttime, enable);
    1557}
    1558
    1559/** gets time in seconds used in this conflict handler for setting up for next stages */
    1561 SCIP_CONFLICTHDLR* conflicthdlr /**< conflict handler */
    1562 )
    1563{
    1564 assert(conflicthdlr != NULL);
    1565
    1566 return SCIPclockGetTime(conflicthdlr->setuptime);
    1567}
    1568
    1569/** gets time in seconds used in this conflict handler */
    1571 SCIP_CONFLICTHDLR* conflicthdlr /**< conflict handler */
    1572 )
    1573{
    1574 assert(conflicthdlr != NULL);
    1575
    1576 return SCIPclockGetTime(conflicthdlr->conflicttime);
    1577}
    1578
    1579/** return TRUE if conflict graph analysis is applicable */
    1581 SCIP_SET* set /**< global SCIP settings */
    1582 )
    1583{
    1584 /* check, if propagation conflict analysis is enabled */
    1585 if( !set->conf_enable || !set->conf_useprop )
    1586 return FALSE;
    1587
    1588 /* check, if there are any conflict handlers to use a conflict set */
    1589 if( set->nconflicthdlrs == 0 )
    1590 return FALSE;
    1591
    1592 return TRUE;
    1593}
    1594
    1595/** resizes the array of the temporary bound change informations to be able to store at least num bound change entries */
    1596static
    1598 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    1599 SCIP_SET* set, /**< global SCIP settings */
    1600 int num /**< minimal number of slots in arrays */
    1601 )
    1602{
    1603 assert(conflict != NULL);
    1604 assert(set != NULL);
    1605
    1606 if( num > conflict->tmpbdchginfossize )
    1607 {
    1608 int newsize;
    1609
    1610 newsize = SCIPsetCalcMemGrowSize(set, num);
    1611 SCIP_ALLOC( BMSreallocMemoryArray(&conflict->tmpbdchginfos, newsize) );
    1612 conflict->tmpbdchginfossize = newsize;
    1613 }
    1614 assert(num <= conflict->tmpbdchginfossize);
    1615
    1616 return SCIP_OKAY;
    1617}
    1618
    1619/** creates a temporary bound change information object that is destroyed after the conflict sets are flushed */
    1621 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    1622 BMS_BLKMEM* blkmem, /**< block memory */
    1623 SCIP_SET* set, /**< global SCIP settings */
    1624 SCIP_VAR* var, /**< active variable that changed the bounds */
    1625 SCIP_BOUNDTYPE boundtype, /**< type of bound for var: lower or upper bound */
    1626 SCIP_Real oldbound, /**< old value for bound */
    1627 SCIP_Real newbound, /**< new value for bound */
    1628 SCIP_BDCHGINFO** bdchginfo /**< pointer to store bound change information */
    1629 )
    1630{
    1631 assert(conflict != NULL);
    1632
    1634 SCIP_CALL( SCIPbdchginfoCreate(&conflict->tmpbdchginfos[conflict->ntmpbdchginfos], blkmem,
    1635 var, boundtype, oldbound, newbound) );
    1636 *bdchginfo = conflict->tmpbdchginfos[conflict->ntmpbdchginfos];
    1637 conflict->ntmpbdchginfos++;
    1638
    1639 return SCIP_OKAY;
    1640}
    1641
    1642/** frees all temporarily created bound change information data */
    1643static
    1645 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    1646 BMS_BLKMEM* blkmem /**< block memory */
    1647 )
    1648{
    1649 int i;
    1650
    1651 assert(conflict != NULL);
    1652
    1653 for( i = 0; i < conflict->ntmpbdchginfos; ++i )
    1654 SCIPbdchginfoFree(&conflict->tmpbdchginfos[i], blkmem);
    1655 conflict->ntmpbdchginfos = 0;
    1656}
    1657
    1658/** increases the conflict score of the variable in the given direction */
    1659static
    1661 SCIP_VAR* var, /**< problem variable */
    1662 BMS_BLKMEM* blkmem, /**< block memory */
    1663 SCIP_SET* set, /**< global SCIP settings */
    1664 SCIP_STAT* stat, /**< dynamic problem statistics */
    1665 SCIP_BOUNDTYPE boundtype, /**< type of bound for which the score should be increased */
    1666 SCIP_Real value, /**< value of the bound */
    1667 SCIP_Real weight /**< weight of this VSIDS updates */
    1668 )
    1669{
    1670 SCIP_BRANCHDIR branchdir;
    1671
    1672 assert(var != NULL);
    1673 assert(stat != NULL);
    1674
    1675 /* weight the VSIDS by the given weight */
    1676 weight *= stat->vsidsweight;
    1677
    1678 if( SCIPsetIsZero(set, weight) )
    1679 return SCIP_OKAY;
    1680
    1681 branchdir = (boundtype == SCIP_BOUNDTYPE_LOWER ? SCIP_BRANCHDIR_UPWARDS : SCIP_BRANCHDIR_DOWNWARDS); /*lint !e641*/
    1682 SCIP_CALL( SCIPvarIncVSIDS(var, blkmem, set, stat, branchdir, value, weight) );
    1683 SCIPhistoryIncVSIDS(stat->glbhistory, branchdir, weight);
    1684 SCIPhistoryIncVSIDS(stat->glbhistorycrun, branchdir, weight);
    1685
    1686 return SCIP_OKAY;
    1687}
    1688
    1689/** update conflict statistics */
    1690static
    1692 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    1693 BMS_BLKMEM* blkmem, /**< block memory */
    1694 SCIP_SET* set, /**< global SCIP settings */
    1695 SCIP_STAT* stat, /**< dynamic problem statistics */
    1696 SCIP_CONFLICTSET* conflictset, /**< conflict set to add to the tree */
    1697 int insertdepth /**< depth level at which the conflict set should be added */
    1698 )
    1699{
    1700 if( insertdepth > 0 )
    1701 {
    1702 conflict->nappliedlocconss++;
    1703 conflict->nappliedlocliterals += conflictset->nbdchginfos;
    1704 }
    1705 else
    1706 {
    1707 int i;
    1708 int conflictlength;
    1709 conflictlength = conflictset->nbdchginfos;
    1710
    1711 for( i = 0; i < conflictlength; i++ )
    1712 {
    1713 SCIP_VAR* var;
    1714 SCIP_BRANCHDIR branchdir;
    1715 SCIP_BOUNDTYPE boundtype;
    1717
    1718 assert(stat != NULL);
    1719
    1720 var = conflictset->bdchginfos[i]->var;
    1721 boundtype = SCIPbdchginfoGetBoundtype(conflictset->bdchginfos[i]);
    1722 bound = conflictset->relaxedbds[i];
    1723
    1724 branchdir = (boundtype == SCIP_BOUNDTYPE_LOWER ? SCIP_BRANCHDIR_UPWARDS : SCIP_BRANCHDIR_DOWNWARDS); /*lint !e641*/
    1725
    1726 SCIP_CALL( SCIPvarIncNActiveConflicts(var, blkmem, set, stat, branchdir, bound, (SCIP_Real)conflictlength) );
    1727 SCIPhistoryIncNActiveConflicts(stat->glbhistory, branchdir, (SCIP_Real)conflictlength);
    1728 SCIPhistoryIncNActiveConflicts(stat->glbhistorycrun, branchdir, (SCIP_Real)conflictlength);
    1729
    1730 /* each variable which is part of the conflict gets an increase in the VSIDS */
    1731 SCIP_CALL( incVSIDS(var, blkmem, set, stat, boundtype, bound, set->conf_conflictweight) );
    1732 }
    1733 conflict->nappliedglbconss++;
    1734 conflict->nappliedglbliterals += conflictset->nbdchginfos;
    1735 }
    1736
    1737 return SCIP_OKAY;
    1738}
    1739
    1740/** adds the given conflict set as conflict constraint to the problem */
    1741static
    1743 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    1744 BMS_BLKMEM* blkmem, /**< block memory */
    1745 SCIP_SET* set, /**< global SCIP settings */
    1746 SCIP_STAT* stat, /**< dynamic problem statistics */
    1747 SCIP_PROB* transprob, /**< transformed problem after presolve */
    1748 SCIP_PROB* origprob, /**< original problem */
    1749 SCIP_TREE* tree, /**< branch and bound tree */
    1750 SCIP_REOPT* reopt, /**< reoptimization data structure */
    1751 SCIP_LP* lp, /**< current LP data */
    1752 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    1753 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    1754 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    1755 SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
    1756 SCIP_CONFLICTSET* conflictset, /**< conflict set to add to the tree */
    1757 int insertdepth, /**< depth level at which the conflict set should be added */
    1758 SCIP_Bool* success /**< pointer to store whether the addition was successful */
    1759 )
    1760{
    1761 SCIP_Bool redundant;
    1762 int h;
    1763
    1764 assert(conflict != NULL);
    1765 assert(tree != NULL);
    1766 assert(tree->path != NULL);
    1767 assert(conflictset != NULL);
    1768 assert(conflictset->validdepth <= insertdepth);
    1769 assert(success != NULL);
    1770
    1771 *success = FALSE;
    1772 redundant = FALSE;
    1773
    1774 /* try to derive global bound changes and shorten the conflictset by using implication and clique and variable bound
    1775 * information
    1776 */
    1777 if( conflictset->nbdchginfos > 1 && insertdepth == 0 && !lp->strongbranching )
    1778 {
    1779 int nbdchgs;
    1780 int nredvars;
    1781#ifdef SCIP_DEBUG
    1782 int oldnbdchginfos = conflictset->nbdchginfos;
    1783#endif
    1784 assert(conflictset->validdepth == 0);
    1785
    1786 /* check conflict set on debugging solution */
    1787 SCIP_CALL( SCIPdebugCheckConflict(blkmem, set, tree->root, conflictset->bdchginfos, conflictset->relaxedbds, conflictset->nbdchginfos) );
    1788
    1789 SCIPclockStart(conflict->dIBclock, set);
    1790
    1791 /* find global bound changes which can be derived from the new conflict set */
    1792 SCIP_CALL( detectImpliedBounds(set, transprob, stat, tree, eventfilter, blkmem, origprob, reopt, lp, conflictset, &nbdchgs, &nredvars, &redundant) );
    1793
    1794 /* all variables where removed, we have an infeasibility proof */
    1795 if( conflictset->nbdchginfos == 0 )
    1796 return SCIP_OKAY;
    1797
    1798 /* debug check for reduced conflict set */
    1799 if( nredvars > 0 )
    1800 {
    1801 /* check conflict set on debugging solution */
    1802 SCIP_CALL( SCIPdebugCheckConflict(blkmem, set, tree->root, conflictset->bdchginfos, conflictset->relaxedbds, conflictset->nbdchginfos) ); /*lint !e506 !e774*/
    1803 }
    1804
    1805#ifdef SCIP_DEBUG
    1806 SCIPsetDebugMsg(set, " -> conflict set removed %d redundant variables (old nvars %d, new nvars = %d)\n", nredvars, oldnbdchginfos, conflictset->nbdchginfos);
    1807 SCIPsetDebugMsg(set, " -> conflict set led to %d global bound changes %s(cdpt:%d, fdpt:%d, confdpt:%d, len:%d):\n",
    1808 nbdchgs, redundant ? "(conflict became redundant) " : "", SCIPtreeGetCurrentDepth(tree), SCIPtreeGetFocusDepth(tree),
    1809 conflictset->conflictdepth, conflictset->nbdchginfos);
    1810 conflictsetPrint(conflictset);
    1811#endif
    1812
    1813 SCIPclockStop(conflict->dIBclock, set);
    1814
    1815 if( redundant )
    1816 {
    1817 if( nbdchgs > 0 )
    1818 *success = TRUE;
    1819
    1820 return SCIP_OKAY;
    1821 }
    1822 }
    1823
    1824 /* in case the conflict set contains only one bound change which is globally valid we apply that bound change
    1825 * directly (except if we are in strong branching or diving - in this case a bound change would yield an unflushed LP
    1826 * and is not handled when restoring the information)
    1827 *
    1828 * @note A bound change can only be applied if it is are related to the active node or if is a global bound
    1829 * change. Bound changes which are related to any other node cannot be handled at point due to the internal
    1830 * data structure
    1831 */
    1832 if( conflictset->nbdchginfos == 1 && insertdepth == 0 && !lp->strongbranching && !lp->diving )
    1833 {
    1834 SCIP_VAR* var;
    1836 SCIP_BOUNDTYPE boundtype;
    1837
    1838 var = conflictset->bdchginfos[0]->var;
    1839 assert(var != NULL);
    1840
    1841 boundtype = SCIPboundtypeOpposite((SCIP_BOUNDTYPE) conflictset->bdchginfos[0]->boundtype);
    1842 bound = conflictset->relaxedbds[0];
    1843
    1844 /* for continuous variables, we can only use the relaxed version of the bounds negation: !(x <= u) -> x >= u */
    1845 if( SCIPvarIsIntegral(var) )
    1846 {
    1847 assert(SCIPsetIsIntegral(set, bound));
    1848 bound += (boundtype == SCIP_BOUNDTYPE_LOWER ? +1.0 : -1.0);
    1849 }
    1850
    1851 SCIPsetDebugMsg(set, " -> apply global bound change: <%s> %s %g\n",
    1852 SCIPvarGetName(var), boundtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", bound);
    1853
    1854 SCIP_CALL( SCIPnodeAddBoundchg(tree->path[conflictset->validdepth], blkmem, set, stat, transprob, origprob, tree,
    1855 reopt, lp, branchcand, eventqueue, eventfilter, cliquetable, var, bound, boundtype, FALSE) );
    1856
    1857 *success = TRUE;
    1858 SCIP_CALL( updateStatistics(conflict, blkmem, set, stat, conflictset, insertdepth) );
    1859 }
    1860 else if( !conflictset->hasrelaxonlyvar )
    1861 {
    1862 /* sort conflict handlers by priority */
    1864
    1865 /* call conflict handlers to create a conflict constraint */
    1866 for( h = 0; h < set->nconflicthdlrs; ++h )
    1867 {
    1868 SCIP_RESULT result;
    1869
    1870 assert(conflictset->conflicttype != SCIP_CONFTYPE_UNKNOWN);
    1871
    1872 SCIP_CALL( SCIPconflicthdlrExec(set->conflicthdlrs[h], set, tree->path[insertdepth],
    1873 tree->path[conflictset->validdepth], conflictset->bdchginfos, conflictset->relaxedbds,
    1874 conflictset->nbdchginfos, conflictset->conflicttype, conflictset->usescutoffbound, *success, &result) );
    1875 if( result == SCIP_CONSADDED )
    1876 {
    1877 *success = TRUE;
    1878 SCIP_CALL( updateStatistics(conflict, blkmem, set, stat, conflictset, insertdepth) );
    1879 }
    1880
    1881 SCIPsetDebugMsg(set, " -> call conflict handler <%s> (prio=%d) to create conflict set with %d bounds returned result %d\n",
    1882 SCIPconflicthdlrGetName(set->conflicthdlrs[h]), SCIPconflicthdlrGetPriority(set->conflicthdlrs[h]),
    1883 conflictset->nbdchginfos, result);
    1884 }
    1885 }
    1886 else
    1887 {
    1888 SCIPsetDebugMsg(set, " -> skip conflict set with relaxation-only variable\n");
    1889 /* TODO would be nice to still create a constraint?, if we can make sure that we the constraint does not survive a restart */
    1890 }
    1891
    1892 return SCIP_OKAY;
    1893}
    1894
    1895/** calculates the maximal size of conflict sets to be used */
    1897 SCIP_SET* set, /**< global SCIP settings */
    1898 SCIP_PROB* prob /**< problem data */
    1899 )
    1900{
    1901 int maxsize;
    1902
    1903 assert(set != NULL);
    1904 assert(prob != NULL);
    1905
    1906 maxsize = (int)(set->conf_maxvarsfac * (prob->nvars - prob->ncontvars));
    1907 maxsize = MAX(maxsize, set->conf_minmaxvars);
    1908
    1909 return maxsize;
    1910}
    1911
    1912/** adds the collected conflict constraints to the corresponding nodes; the best set->conf_maxconss conflict constraints
    1913 * are added to the node of their validdepth; additionally (if not yet added, and if repropagation is activated), the
    1914 * conflict constraint that triggers the earliest repropagation is added to the node of its validdepth
    1915 */
    1917 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    1918 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
    1919 SCIP_SET* set, /**< global SCIP settings */
    1920 SCIP_STAT* stat, /**< dynamic problem statistics */
    1921 SCIP_PROB* transprob, /**< transformed problem */
    1922 SCIP_PROB* origprob, /**< original problem */
    1923 SCIP_TREE* tree, /**< branch and bound tree */
    1924 SCIP_REOPT* reopt, /**< reoptimization data structure */
    1925 SCIP_LP* lp, /**< current LP data */
    1926 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    1927 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    1928 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    1929 SCIP_CLIQUETABLE* cliquetable /**< clique table data structure */
    1930 )
    1931{
    1932 assert(conflict != NULL);
    1933 assert(set != NULL);
    1934 assert(stat != NULL);
    1935 assert(transprob != NULL);
    1936 assert(tree != NULL);
    1937
    1938 /* is there anything to do? */
    1939 if( conflict->nconflictsets > 0 )
    1940 {
    1941 SCIP_CONFLICTSET* repropconflictset;
    1942 int nconflictsetsused;
    1943 int focusdepth;
    1944#ifndef NDEBUG
    1945 int currentdepth;
    1946#endif
    1947 int cutoffdepth;
    1948 int repropdepth;
    1949 int maxconflictsets;
    1950 int maxsize;
    1951 int i;
    1952
    1953 /* calculate the maximal number of conflict sets to accept, and the maximal size of each accepted conflict set */
    1954 maxconflictsets = (set->conf_maxconss == -1 ? INT_MAX : set->conf_maxconss);
    1955 maxsize = conflictCalcMaxsize(set, transprob);
    1956
    1957 focusdepth = SCIPtreeGetFocusDepth(tree);
    1958#ifndef NDEBUG
    1959 currentdepth = SCIPtreeGetCurrentDepth(tree);
    1960 assert(focusdepth <= currentdepth);
    1961 assert(currentdepth == tree->pathlen-1);
    1962#endif
    1963
    1964 SCIPsetDebugMsg(set, "flushing %d conflict sets at focus depth %d (maxconflictsets: %d, maxsize: %d)\n",
    1965 conflict->nconflictsets, focusdepth, maxconflictsets, maxsize);
    1966
    1967 /* mark the focus node to have produced conflict sets in the visualization output */
    1968 SCIPvisualFoundConflict(stat->visual, stat, tree->path[focusdepth]);
    1969
    1970 /* insert the conflict sets at the corresponding nodes */
    1971 nconflictsetsused = 0;
    1972 cutoffdepth = INT_MAX;
    1973 repropdepth = INT_MAX;
    1974 repropconflictset = NULL;
    1975 for( i = 0; i < conflict->nconflictsets && nconflictsetsused < maxconflictsets; ++i )
    1976 {
    1977 SCIP_CONFLICTSET* conflictset;
    1978
    1979 conflictset = conflict->conflictsets[i];
    1980 assert(conflictset != NULL);
    1981 assert(0 <= conflictset->validdepth);
    1982 assert(conflictset->validdepth <= conflictset->insertdepth);
    1983 assert(conflictset->insertdepth <= focusdepth);
    1984 assert(conflictset->insertdepth <= conflictset->repropdepth);
    1985 assert(conflictset->repropdepth <= currentdepth || conflictset->repropdepth == INT_MAX); /* INT_MAX for dive/probing/strong */
    1986 assert(conflictset->conflictdepth <= currentdepth || conflictset->conflictdepth == INT_MAX); /* INT_MAX for dive/probing/strong */
    1987
    1988 /* ignore conflict sets that are only valid at a node that was already cut off */
    1989 if( conflictset->insertdepth >= cutoffdepth )
    1990 {
    1991 SCIPsetDebugMsg(set, " -> ignoring conflict set with insertdepth %d >= cutoffdepth %d\n",
    1992 conflictset->validdepth, cutoffdepth);
    1993 continue;
    1994 }
    1995
    1996 /* if no conflict bounds exist, the node and its sub tree in the conflict set's valid depth can be
    1997 * cut off completely
    1998 */
    1999 if( conflictset->nbdchginfos == 0 )
    2000 {
    2001 SCIPsetDebugMsg(set, " -> empty conflict set in depth %d cuts off sub tree at depth %d\n",
    2002 focusdepth, conflictset->validdepth);
    2003
    2004 SCIP_CALL( SCIPnodeCutoff(tree->path[conflictset->validdepth], set, stat, eventfilter, tree, transprob, origprob, reopt, lp, blkmem) );
    2005 cutoffdepth = conflictset->validdepth;
    2006 continue;
    2007 }
    2008
    2009 /* if the conflict set is too long, use the conflict set only if it decreases the repropagation depth */
    2010 if( conflictset->nbdchginfos > maxsize )
    2011 {
    2012 SCIPsetDebugMsg(set, " -> conflict set is too long: %d > %d literals\n", conflictset->nbdchginfos, maxsize);
    2013 if( set->conf_keepreprop && conflictset->repropagate && conflictset->repropdepth < repropdepth )
    2014 {
    2015 repropdepth = conflictset->repropdepth;
    2016 repropconflictset = conflictset;
    2017 }
    2018 }
    2019 else
    2020 {
    2021 SCIP_Bool success;
    2022
    2023 /* call conflict handlers to create a conflict constraint */
    2024 SCIP_CALL( conflictAddConflictCons(conflict, blkmem, set, stat, transprob, origprob, tree, reopt, lp,
    2025 branchcand, eventqueue, eventfilter, cliquetable, conflictset, conflictset->insertdepth, &success) );
    2026
    2027 /* if no conflict bounds exist, the node and its sub tree in the conflict set's valid depth can be
    2028 * cut off completely
    2029 */
    2030 if( conflictset->nbdchginfos == 0 )
    2031 {
    2032 assert(!success);
    2033
    2034 SCIPsetDebugMsg(set, " -> empty conflict set in depth %d cuts off sub tree at depth %d\n",
    2035 focusdepth, conflictset->validdepth);
    2036
    2037 SCIP_CALL( SCIPnodeCutoff(tree->path[conflictset->validdepth], set, stat, eventfilter, tree, transprob,
    2038 origprob, reopt, lp, blkmem) );
    2039 cutoffdepth = conflictset->validdepth;
    2040 continue;
    2041 }
    2042
    2043 if( success )
    2044 {
    2045 SCIPsetDebugMsg(set, " -> conflict set %d/%d added (cdpt:%d, fdpt:%d, insert:%d, valid:%d, conf:%d, reprop:%d, len:%d):\n",
    2046 nconflictsetsused+1, maxconflictsets, SCIPtreeGetCurrentDepth(tree), SCIPtreeGetFocusDepth(tree),
    2047 conflictset->insertdepth, conflictset->validdepth, conflictset->conflictdepth, conflictset->repropdepth,
    2048 conflictset->nbdchginfos);
    2049 SCIPdebug(conflictsetPrint(conflictset));
    2050 SCIPdebugPrintf("\n");
    2051 if( conflictset->repropagate && conflictset->repropdepth <= repropdepth )
    2052 {
    2053 repropdepth = conflictset->repropdepth;
    2054 repropconflictset = NULL;
    2055 }
    2056 nconflictsetsused++;
    2057 }
    2058 }
    2059 }
    2060
    2061 /* reactivate propagation on the first node where one of the new conflict sets trigger a deduction */
    2062 if( set->conf_repropagate && repropdepth < cutoffdepth && repropdepth < tree->pathlen )
    2063 {
    2064 assert(0 <= repropdepth && repropdepth < tree->pathlen);
    2065 assert((int) tree->path[repropdepth]->depth == repropdepth);
    2066
    2067 /* if the conflict constraint of smallest repropagation depth was not yet added, insert it now */
    2068 if( repropconflictset != NULL )
    2069 {
    2070 SCIP_Bool success;
    2071
    2072 assert(repropconflictset->repropagate);
    2073 assert(repropconflictset->repropdepth == repropdepth);
    2074
    2075 SCIP_CALL( conflictAddConflictCons(conflict, blkmem, set, stat, transprob, origprob, tree, reopt, lp,
    2076 branchcand, eventqueue, eventfilter, cliquetable, repropconflictset, repropdepth, &success) );
    2077
    2078 /* if no conflict bounds exist, the node and its sub tree in the conflict set's valid depth can be
    2079 * cut off completely
    2080 */
    2081 if( repropconflictset->nbdchginfos == 0 )
    2082 {
    2083 assert(!success);
    2084
    2085 SCIPsetDebugMsg(set, " -> empty reprop conflict set in depth %d cuts off sub tree at depth %d\n",
    2086 focusdepth, repropconflictset->validdepth);
    2087
    2088 SCIP_CALL( SCIPnodeCutoff(tree->path[repropconflictset->validdepth], set, stat, eventfilter, tree,
    2089 transprob, origprob, reopt, lp, blkmem) );
    2090 }
    2091
    2092#ifdef SCIP_DEBUG
    2093 if( success )
    2094 {
    2095 SCIPsetDebugMsg(set, " -> additional reprop conflict set added (cdpt:%d, fdpt:%d, insert:%d, valid:%d, conf:%d, reprop:%d, len:%d):\n",
    2097 repropconflictset->insertdepth, repropconflictset->validdepth, repropconflictset->conflictdepth,
    2098 repropconflictset->repropdepth, repropconflictset->nbdchginfos);
    2099 SCIPdebug(conflictsetPrint(repropconflictset));
    2100 }
    2101#endif
    2102 }
    2103
    2104 /* mark the node in the repropdepth to be propagated again */
    2105 SCIPnodePropagateAgain(tree->path[repropdepth], set, stat, tree);
    2106
    2107 SCIPsetDebugMsg(set, "marked node %p in depth %d to be repropagated due to conflicts found in depth %d\n",
    2108 (void*)tree->path[repropdepth], repropdepth, focusdepth);
    2109 }
    2110
    2111 /* free the conflict store */
    2112 for( i = 0; i < conflict->nconflictsets; ++i )
    2113 {
    2114 SCIPconflictsetFree(&conflict->conflictsets[i], blkmem);
    2115 }
    2116 conflict->nconflictsets = 0;
    2117 }
    2118
    2119 /* free all temporarily created bound change information data */
    2120 conflictFreeTmpBdchginfos(conflict, blkmem);
    2121
    2122 return SCIP_OKAY;
    2123}
    2124
    2125/** resizes conflictsets array to be able to store at least num entries */
    2126static
    2128 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    2129 SCIP_SET* set, /**< global SCIP settings */
    2130 int num /**< minimal number of slots in array */
    2131 )
    2132{
    2133 assert(conflict != NULL);
    2134 assert(set != NULL);
    2135
    2136 if( num > conflict->conflictsetssize )
    2137 {
    2138 int newsize;
    2139
    2140 newsize = SCIPsetCalcMemGrowSize(set, num);
    2141 SCIP_ALLOC( BMSreallocMemoryArray(&conflict->conflictsets, newsize) );
    2142 SCIP_ALLOC( BMSreallocMemoryArray(&conflict->conflictsetscores, newsize) );
    2143 conflict->conflictsetssize = newsize;
    2144 }
    2145 assert(num <= conflict->conflictsetssize);
    2146
    2147 return SCIP_OKAY;
    2148}
    2149
    2150/** inserts conflict set into sorted conflictsets array and deletes the conflict set pointer */
    2151static
    2153 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    2154 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
    2155 SCIP_SET* set, /**< global SCIP settings */
    2156 SCIP_CONFLICTSET** conflictset /**< pointer to conflict set to insert */
    2157 )
    2158{
    2159 SCIP_Real score;
    2160 int pos;
    2161 int i;
    2162 int j;
    2163
    2164 assert(conflict != NULL);
    2165 assert(set != NULL);
    2166 assert(conflictset != NULL);
    2167 assert(*conflictset != NULL);
    2168 assert((*conflictset)->validdepth <= (*conflictset)->insertdepth);
    2169 assert(set->conf_allowlocal || (*conflictset)->validdepth == 0);
    2170
    2171 /* calculate conflict and repropagation depth */
    2172 conflictsetCalcConflictDepth(*conflictset);
    2173
    2174 /* if we apply repropagations, the conflict set should be inserted at most at its repropdepth */
    2175 if( set->conf_repropagate )
    2176 (*conflictset)->insertdepth = MIN((*conflictset)->insertdepth, (*conflictset)->repropdepth);
    2177 else
    2178 (*conflictset)->repropdepth = INT_MAX;
    2179 assert((*conflictset)->insertdepth <= (*conflictset)->repropdepth);
    2180
    2181 SCIPsetDebugMsg(set, "inserting conflict set (valid: %d, insert: %d, conf: %d, reprop: %d):\n",
    2182 (*conflictset)->validdepth, (*conflictset)->insertdepth, (*conflictset)->conflictdepth, (*conflictset)->repropdepth);
    2183 SCIPdebug(conflictsetPrint(*conflictset));
    2184
    2185 /* get the score of the conflict set */
    2186 score = conflictsetCalcScore(*conflictset, set);
    2187
    2188 /* check, if conflict set is redundant to a better conflict set */
    2189 for( pos = 0; pos < conflict->nconflictsets && score < conflict->conflictsetscores[pos]; ++pos )
    2190 {
    2191 /* check if conflict set is redundant with respect to conflictsets[pos] */
    2192 if( conflictsetIsRedundant(*conflictset, conflict->conflictsets[pos]) )
    2193 {
    2194 SCIPsetDebugMsg(set, " -> conflict set is redundant to: ");
    2195 SCIPdebug(conflictsetPrint(conflict->conflictsets[pos]));
    2196 SCIPconflictsetFree(conflictset, blkmem);
    2197 return SCIP_OKAY;
    2198 }
    2199
    2200 /**@todo like in sepastore.c: calculate overlap between conflictsets -> large overlap reduces score */
    2201 }
    2202
    2203 /* insert conflictset into the sorted conflictsets array */
    2204 SCIP_CALL( conflictEnsureConflictsetsMem(conflict, set, conflict->nconflictsets + 1) );
    2205 for( i = conflict->nconflictsets; i > pos; --i )
    2206 {
    2207 assert(score >= conflict->conflictsetscores[i-1]);
    2208 conflict->conflictsets[i] = conflict->conflictsets[i-1];
    2209 conflict->conflictsetscores[i] = conflict->conflictsetscores[i-1];
    2210 }
    2211 conflict->conflictsets[pos] = *conflictset;
    2212 conflict->conflictsetscores[pos] = score;
    2213 conflict->nconflictsets++;
    2214
    2215 /* remove worse conflictsets that are redundant to the new conflictset */
    2216 for( i = pos+1, j = pos+1; i < conflict->nconflictsets; ++i )
    2217 {
    2218 if( conflictsetIsRedundant(conflict->conflictsets[i], *conflictset) )
    2219 {
    2220 SCIPsetDebugMsg(set, " -> conflict set dominates: ");
    2222 SCIPconflictsetFree(&conflict->conflictsets[i], blkmem);
    2223 }
    2224 else
    2225 {
    2226 assert(j <= i);
    2227 conflict->conflictsets[j] = conflict->conflictsets[i];
    2228 conflict->conflictsetscores[j] = conflict->conflictsetscores[i];
    2229 j++;
    2230 }
    2231 }
    2232 assert(j <= conflict->nconflictsets);
    2233 conflict->nconflictsets = j;
    2234
    2235#if defined(SCIP_CONFGRAPH) || defined(SCIP_CONFGRAPH_DOT)
    2236 confgraphMarkConflictset(*conflictset);
    2237#endif
    2238
    2239 *conflictset = NULL; /* ownership of pointer is now in the conflictsets array */
    2240
    2241 return SCIP_OKAY;
    2242}
    2243
    2244/** marks bound to be present in the current conflict and returns whether a bound which is at least as tight was already
    2245 * member of the current conflict (i.e., the given bound change does not need to be added)
    2246 */
    2247static
    2249 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    2250 SCIP_SET* set, /**< global SCIP settings */
    2251 SCIP_BDCHGINFO* bdchginfo, /**< bound change to add to the conflict set */
    2252 SCIP_Real relaxedbd /**< relaxed bound */
    2253 )
    2254{
    2255 SCIP_VAR* var;
    2256 SCIP_Real newbound;
    2257
    2258 assert(conflict != NULL);
    2259
    2260 var = SCIPbdchginfoGetVar(bdchginfo);
    2261 newbound = SCIPbdchginfoGetNewbound(bdchginfo);
    2262 assert(var != NULL);
    2263
    2264 switch( SCIPbdchginfoGetBoundtype(bdchginfo) )
    2265 {
    2267 /* check if the variables lower bound is already member of the conflict */
    2268 if( var->conflictlbcount == conflict->count )
    2269 {
    2270 /* the variable is already member of the conflict; hence check if the new bound is redundant */
    2271 if( var->conflictlb > newbound )
    2272 {
    2273 SCIPsetDebugMsg(set, "ignoring redundant bound change <%s> >= %g since a stronger lower bound exist <%s> >= %g\n",
    2274 SCIPvarGetName(var), newbound, SCIPvarGetName(var), var->conflictlb);
    2275 return TRUE;
    2276 }
    2277 else if( var->conflictlb == newbound ) /*lint !e777*/
    2278 {
    2279 SCIPsetDebugMsg(set, "ignoring redundant bound change <%s> >= %g since this lower bound is already present\n", SCIPvarGetName(var), newbound);
    2280 SCIPsetDebugMsg(set, "adjust relaxed lower bound <%g> -> <%g>\n", var->conflictlb, relaxedbd);
    2281 var->conflictrelaxedlb = MAX(var->conflictrelaxedlb, relaxedbd);
    2282 return TRUE;
    2283 }
    2284 }
    2285
    2286 /* add the variable lower bound to the current conflict */
    2287 var->conflictlbcount = conflict->count;
    2288
    2289 /* remember the lower bound and relaxed bound to allow only better/tighter lower bounds for that variables
    2290 * w.r.t. this conflict
    2291 */
    2292 var->conflictlb = newbound;
    2293 var->conflictrelaxedlb = relaxedbd;
    2294
    2295 return FALSE;
    2296
    2298 /* check if the variables upper bound is already member of the conflict */
    2299 if( var->conflictubcount == conflict->count )
    2300 {
    2301 /* the variable is already member of the conflict; hence check if the new bound is redundant */
    2302 if( var->conflictub < newbound )
    2303 {
    2304 SCIPsetDebugMsg(set, "ignoring redundant bound change <%s> <= %g since a stronger upper bound exist <%s> <= %g\n",
    2305 SCIPvarGetName(var), newbound, SCIPvarGetName(var), var->conflictub);
    2306 return TRUE;
    2307 }
    2308 else if( var->conflictub == newbound ) /*lint !e777*/
    2309 {
    2310 SCIPsetDebugMsg(set, "ignoring redundant bound change <%s> <= %g since this upper bound is already present\n", SCIPvarGetName(var), newbound);
    2311 SCIPsetDebugMsg(set, "adjust relaxed upper bound <%g> -> <%g>\n", var->conflictub, relaxedbd);
    2312 var->conflictrelaxedub = MIN(var->conflictrelaxedub, relaxedbd);
    2313 return TRUE;
    2314 }
    2315 }
    2316
    2317 /* add the variable upper bound to the current conflict */
    2318 var->conflictubcount = conflict->count;
    2319
    2320 /* remember the upper bound and relaxed bound to allow only better/tighter upper bounds for that variables
    2321 * w.r.t. this conflict
    2322 */
    2323 var->conflictub = newbound;
    2324 var->conflictrelaxedub = relaxedbd;
    2325
    2326 return FALSE;
    2327
    2328 default:
    2329 SCIPerrorMessage("invalid bound type %d\n", SCIPbdchginfoGetBoundtype(bdchginfo));
    2330 SCIPABORT();
    2331 return FALSE; /*lint !e527*/
    2332 }
    2333}
    2334/** marks bound to be present in the current conflict and returns whether a bound which is at least as tight was already
    2335 * member of the current conflict (i.e., the given bound change does not need to be added)
    2336 */
    2337static
    2339 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    2340 SCIP_SET* set, /**< global SCIP settings */
    2341 SCIP_BDCHGINFO* bdchginfo /**< bound change to add to the conflict set */
    2342 )
    2343{
    2344 SCIP_VAR* var;
    2345 SCIP_Real newbound;
    2346
    2347 assert(conflict != NULL);
    2348
    2349 var = SCIPbdchginfoGetVar(bdchginfo);
    2350 newbound = SCIPbdchginfoGetNewbound(bdchginfo);
    2351 assert(var != NULL);
    2352
    2353 switch( SCIPbdchginfoGetBoundtype(bdchginfo) )
    2354 {
    2356 /* the variable is already member of the conflict; hence check if the new bound is redundant */
    2357 if( conflict->conflictvarslbs[SCIPvarGetProbindex(var)] < newbound )
    2358 {
    2359 conflict->conflictvarslbs[SCIPvarGetProbindex(var)] = newbound;
    2360 return FALSE;
    2361 }
    2362 SCIPsetDebugMsg(set, "ResQueue: ignoring redundant bound change <%s> >= %g since a stronger lower bound exist <%s> >= %g\n",
    2363 SCIPvarGetName(var), newbound, SCIPvarGetName(var), conflict->conflictvarslbs[SCIPvarGetProbindex(var)]);
    2364 return TRUE;
    2365
    2367 /* the variable is already member of the conflict; hence check if the new bound is redundant */
    2368 if( conflict->conflictvarsubs[SCIPvarGetProbindex(var)] > newbound )
    2369 {
    2370 conflict->conflictvarsubs[SCIPvarGetProbindex(var)] = newbound;
    2371 return FALSE;
    2372 }
    2373 SCIPsetDebugMsg(set, "ResQueue: ignoring redundant bound change <%s> <= %g since a stronger upper bound exist <%s> <= %g\n",
    2374 SCIPvarGetName(var), newbound, SCIPvarGetName(var), conflict->conflictvarsubs[SCIPvarGetProbindex(var)]);
    2375
    2376 return TRUE;
    2377
    2378 default:
    2379 SCIPerrorMessage("invalid bound type %d\n", SCIPbdchginfoGetBoundtype(bdchginfo));
    2380 SCIPABORT();
    2381 return FALSE; /*lint !e527*/
    2382 }
    2383}
    2384
    2385/** puts bound change into the current conflict set */
    2386static
    2388 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    2389 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
    2390 SCIP_SET* set, /**< global SCIP settings */
    2391 SCIP_BDCHGINFO* bdchginfo, /**< bound change to add to the conflict set */
    2392 SCIP_Real relaxedbd /**< relaxed bound */
    2393 )
    2394{
    2395 assert(conflict != NULL);
    2396 assert(!SCIPbdchginfoIsRedundant(bdchginfo));
    2397
    2398 /* check if the relaxed bound is really a relaxed bound */
    2399 assert(SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER || SCIPsetIsGE(set, relaxedbd, SCIPbdchginfoGetNewbound(bdchginfo)));
    2400 assert(SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_UPPER || SCIPsetIsLE(set, relaxedbd, SCIPbdchginfoGetNewbound(bdchginfo)));
    2401
    2402 SCIPsetDebugMsg(set, "putting bound change <%s> %s %g(%g) at depth %d to current conflict set\n",
    2404 SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", SCIPbdchginfoGetNewbound(bdchginfo),
    2405 relaxedbd, SCIPbdchginfoGetDepth(bdchginfo));
    2406
    2407 /* mark the bound to be member of the conflict and check if a bound which is at least as tight is already member of
    2408 * the conflict
    2409 */
    2410 if( !conflictMarkBoundCheckPresence(conflict, set, bdchginfo, relaxedbd) )
    2411 {
    2412 /* add the bound change to the current conflict set */
    2413 SCIP_CALL( conflictsetAddBound(conflict->conflictset, blkmem, set, bdchginfo, relaxedbd) );
    2414
    2415#if defined(SCIP_CONFGRAPH) || defined(SCIP_CONFGRAPH_DOT)
    2416 if( bdchginfo != confgraphcurrentbdchginfo )
    2417 confgraphAddBdchg(bdchginfo);
    2418#endif
    2419 }
    2420#if defined(SCIP_CONFGRAPH) || defined(SCIP_CONFGRAPH_DOT)
    2421 else
    2422 confgraphLinkBdchg(bdchginfo);
    2423#endif
    2424
    2425 return SCIP_OKAY;
    2426}
    2427
    2428/** returns whether the negation of the given bound change would lead to a globally valid literal */
    2429static
    2431 SCIP_SET* set, /**< global SCIP settings */
    2432 SCIP_BDCHGINFO* bdchginfo /**< bound change information */
    2433 )
    2434{
    2435 SCIP_VAR* var;
    2436 SCIP_BOUNDTYPE boundtype;
    2438
    2439 var = SCIPbdchginfoGetVar(bdchginfo);
    2440 boundtype = SCIPbdchginfoGetBoundtype(bdchginfo);
    2441 bound = SCIPbdchginfoGetNewbound(bdchginfo);
    2442
    2443 return ( !SCIPvarIsIntegral(var)
    2445 || (boundtype == SCIP_BOUNDTYPE_UPPER && SCIPsetIsFeasLE(set, bound, SCIPvarGetLbGlobal(var)))));
    2446}
    2447
    2448/** adds given bound change information to the conflict candidate queue */
    2449static
    2451 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    2452 SCIP_SET* set, /**< global SCIP settings */
    2453 SCIP_BDCHGINFO* bdchginfo, /**< bound change information */
    2454 SCIP_Real relaxedbd, /**< relaxed bound */
    2455 SCIP_Bool* success /**< was the bound change successfully added to the queue? */
    2456 )
    2457{
    2458 assert(conflict != NULL);
    2459 assert(set != NULL);
    2460 assert(bdchginfo != NULL);
    2461
    2462 assert(!SCIPbdchginfoIsRedundant(bdchginfo));
    2463
    2464 /* check if the relaxed bound is really a relaxed bound */
    2465 assert(SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER || SCIPsetIsGE(set, relaxedbd, SCIPbdchginfoGetNewbound(bdchginfo)));
    2466 assert(SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_UPPER || SCIPsetIsLE(set, relaxedbd, SCIPbdchginfoGetNewbound(bdchginfo)));
    2467
    2468 if( success != NULL )
    2469 *success = FALSE;
    2470
    2471 if( set->conf_usegenres && !conflict->bdchgonlyconfqueue )
    2472 {
    2473 if( !betterBoundInResolutionQueue(conflict, set, bdchginfo) )
    2474 {
    2475 SCIP_CALL( SCIPpqueueInsert(conflict->resbdchgqueue, (void*)bdchginfo) );
    2476 if( success != NULL )
    2477 *success = TRUE;
    2478 }
    2479 }
    2480 /* mark the bound to be member of the conflict and check if a bound which is at least as tight is already member of
    2481 * the conflict
    2482 */
    2483 if( !conflict->bdchgonlyresqueue && set->conf_useprop && !conflictMarkBoundCheckPresence(conflict, set, bdchginfo, relaxedbd) )
    2484 {
    2485 /* insert the bound change into the conflict queue */
    2486 if( (!set->conf_preferbinary || SCIPvarIsBinary(SCIPbdchginfoGetVar(bdchginfo)))
    2487 && !isBoundchgUseless(set, bdchginfo) )
    2488 {
    2489 SCIP_CALL( SCIPpqueueInsert(conflict->bdchgqueue, (void*)bdchginfo) );
    2490 if( success != NULL )
    2491 *success = TRUE;
    2492 }
    2493 else
    2494 {
    2495 SCIP_CALL( SCIPpqueueInsert(conflict->forcedbdchgqueue, (void*)bdchginfo) );
    2496 if( success != NULL )
    2497 *success = TRUE;
    2498 }
    2499
    2500#if defined(SCIP_CONFGRAPH) || defined(SCIP_CONFGRAPH_DOT)
    2501 confgraphAddBdchg(bdchginfo);
    2502#endif
    2503 }
    2504#if defined(SCIP_CONFGRAPH) || defined(SCIP_CONFGRAPH_DOT)
    2505 else
    2506 confgraphLinkBdchg(bdchginfo);
    2507#endif
    2508
    2509 return SCIP_OKAY;
    2510}
    2511
    2512/** adds variable's bound to conflict candidate queue */
    2513static
    2515 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    2516 BMS_BLKMEM* blkmem, /**< block memory */
    2517 SCIP_SET* set, /**< global SCIP settings */
    2518 SCIP_STAT* stat, /**< dynamic problem statistics */
    2519 SCIP_VAR* var, /**< problem variable */
    2520 SCIP_BOUNDTYPE boundtype, /**< type of bound that was changed: lower or upper bound */
    2521 SCIP_BDCHGINFO* bdchginfo, /**< bound change info, or NULL */
    2522 SCIP_Real relaxedbd /**< relaxed bound */
    2523 )
    2524{
    2525 SCIP_Bool success;
    2526
    2527 assert(SCIPvarIsActive(var));
    2528 assert(bdchginfo != NULL);
    2529 assert(!SCIPbdchginfoIsRedundant(bdchginfo));
    2530
    2531 SCIPsetDebugMsg(set, " -> adding bound <%s> %s %.15g(%.15g) [status:%d, type:%d, depth:%d, pos:%d, reason:<%s>, info:%d] to candidates\n",
    2532 SCIPvarGetName(var),
    2533 boundtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
    2534 SCIPbdchginfoGetNewbound(bdchginfo), relaxedbd,
    2536 SCIPbdchginfoGetDepth(bdchginfo), SCIPbdchginfoGetPos(bdchginfo),
    2541 : "none")),
    2543
    2544 /* the local bound change may be resolved and has to be put on the candidate queue;
    2545 * we even put bound changes without inference information on the queue in order to automatically
    2546 * eliminate multiple insertions of the same bound change
    2547 */
    2548 assert(SCIPbdchginfoGetVar(bdchginfo) == var);
    2549 assert(SCIPbdchginfoGetBoundtype(bdchginfo) == boundtype);
    2550 assert(SCIPbdchginfoGetDepth(bdchginfo) >= 0);
    2551 assert(SCIPbdchginfoGetPos(bdchginfo) >= 0);
    2552
    2553 /* the relaxed bound should be a relaxation */
    2554 assert(boundtype == SCIP_BOUNDTYPE_LOWER ? SCIPsetIsLE(set, relaxedbd, SCIPbdchginfoGetNewbound(bdchginfo)) : SCIPsetIsGE(set, relaxedbd, SCIPbdchginfoGetNewbound(bdchginfo)));
    2555
    2556 /* the relaxed bound should be worse then the old bound of the bound change info */
    2557 assert(boundtype == SCIP_BOUNDTYPE_LOWER ? SCIPsetIsGT(set, relaxedbd, SCIPbdchginfoGetOldbound(bdchginfo)) : SCIPsetIsLT(set, relaxedbd, SCIPbdchginfoGetOldbound(bdchginfo)));
    2558
    2559 /* put bound change information into priority queue */
    2560 SCIP_CALL( conflictQueueBound(conflict, set, bdchginfo, relaxedbd, &success) );
    2561
    2562 /* each variable which is add to the conflict graph gets an increase in the VSIDS
    2563 *
    2564 * @note That is different to the VSIDS presented in the literature
    2565 */
    2566 /* refactortodo update VSIDS score only in case of successfully adding the bound change to the queue? */
    2567 SCIP_CALL( incVSIDS(var, blkmem, set, stat, boundtype, relaxedbd, set->conf_conflictgraphweight) );
    2568
    2569 return SCIP_OKAY;
    2570}
    2571
    2572/** applies conflict analysis starting with given bound changes, that could not be undone during previous
    2573 * infeasibility analysis
    2574 */
    2576 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    2577 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
    2578 SCIP_SET* set, /**< global SCIP settings */
    2579 SCIP_STAT* stat, /**< problem statistics */
    2580 SCIP_PROB* prob, /**< problem data */
    2581 SCIP_TREE* tree, /**< branch and bound tree */
    2582 SCIP_Bool diving, /**< are we in strong branching or diving mode? */
    2583 int* lbchginfoposs, /**< positions of currently active lower bound change information in variables' arrays */
    2584 int* ubchginfoposs, /**< positions of currently active upper bound change information in variables' arrays */
    2585 int* nconss, /**< pointer to store the number of generated conflict constraints */
    2586 int* nliterals, /**< pointer to store the number of literals in generated conflict constraints */
    2587 int* nreconvconss, /**< pointer to store the number of generated reconvergence constraints */
    2588 int* nreconvliterals /**< pointer to store the number of literals generated reconvergence constraints */
    2589 )
    2590{
    2591 SCIP_VAR** vars;
    2592 SCIP_VAR* var;
    2593 SCIP_CONFTYPE conftype;
    2594 SCIP_Bool usescutoffbound;
    2595 int nvars;
    2596 int v;
    2597 int nbdchgs;
    2598 int maxsize;
    2599
    2600 assert(prob != NULL);
    2601 assert(lbchginfoposs != NULL);
    2602 assert(ubchginfoposs != NULL);
    2603 assert(nconss != NULL);
    2604 assert(nliterals != NULL);
    2605 assert(nreconvconss != NULL);
    2606 assert(nreconvliterals != NULL);
    2607
    2608 *nconss = 0;
    2609 *nliterals = 0;
    2610 *nreconvconss = 0;
    2611 *nreconvliterals = 0;
    2612
    2613 vars = prob->vars;
    2614 nvars = prob->nvars;
    2615 assert(nvars == 0 || vars != NULL);
    2616
    2617 maxsize = 2*conflictCalcMaxsize(set, prob);
    2618
    2619 /* initialize conflict data */
    2620 conftype = conflict->conflictset->conflicttype;
    2621 usescutoffbound = conflict->conflictset->usescutoffbound;
    2622
    2623 SCIP_CALL( SCIPconflictInit(conflict, set, stat, prob, conftype, usescutoffbound) );
    2624
    2625 conflict->conflictset->conflicttype = conftype;
    2626 conflict->conflictset->usescutoffbound = usescutoffbound;
    2627
    2628 /* add remaining bound changes to conflict queue */
    2629 SCIPsetDebugMsg(set, "initial conflict set after undoing bound changes:\n");
    2630
    2631 nbdchgs = 0;
    2632 for( v = 0; v < nvars && nbdchgs < maxsize; ++v )
    2633 {
    2634 var = vars[v];
    2635 assert(var != NULL);
    2636 assert(var->nlbchginfos >= 0);
    2637 assert(var->nubchginfos >= 0);
    2638 assert(-1 <= lbchginfoposs[v] && lbchginfoposs[v] <= var->nlbchginfos);
    2639 assert(-1 <= ubchginfoposs[v] && ubchginfoposs[v] <= var->nubchginfos);
    2640
    2641 if( lbchginfoposs[v] == var->nlbchginfos || ubchginfoposs[v] == var->nubchginfos )
    2642 {
    2643 SCIP_BDCHGINFO* bdchginfo;
    2644 SCIP_Real relaxedbd;
    2645
    2646 /* the strong branching or diving bound stored in the column is responsible for the conflict:
    2647 * it cannot be resolved and therefore has to be directly put into the conflict set
    2648 */
    2649 assert((lbchginfoposs[v] == var->nlbchginfos) != (ubchginfoposs[v] == var->nubchginfos)); /* only one can be tight in the dual! */
    2650 assert(lbchginfoposs[v] < var->nlbchginfos || SCIPvarGetLbLP(var, set) > SCIPvarGetLbLocal(var));
    2651 assert(ubchginfoposs[v] < var->nubchginfos || SCIPvarGetUbLP(var, set) < SCIPvarGetUbLocal(var));
    2652
    2653 /* create an artificial bound change information for the diving/strong branching bound change;
    2654 * they are freed in the SCIPconflictFlushConss() call
    2655 */
    2656 if( lbchginfoposs[v] == var->nlbchginfos )
    2657 {
    2659 SCIPvarGetLbLocal(var), SCIPvarGetLbLP(var, set), &bdchginfo) );
    2660 relaxedbd = SCIPvarGetLbLP(var, set);
    2661 }
    2662 else
    2663 {
    2665 SCIPvarGetUbLocal(var), SCIPvarGetUbLP(var, set), &bdchginfo) );
    2666 relaxedbd = SCIPvarGetUbLP(var, set);
    2667 }
    2668
    2669 /* put variable into the conflict set */
    2670 SCIPsetDebugMsg(set, " force: <%s> %s %g [status: %d, type: %d, dive/strong]\n",
    2671 SCIPvarGetName(var), lbchginfoposs[v] == var->nlbchginfos ? ">=" : "<=",
    2672 lbchginfoposs[v] == var->nlbchginfos ? SCIPvarGetLbLP(var, set) : SCIPvarGetUbLP(var, set),
    2673 SCIPvarGetStatus(var), SCIPvarGetType(var));
    2674 SCIP_CALL( conflictAddConflictBound(conflict, blkmem, set, bdchginfo, relaxedbd) );
    2675
    2676 /* each variable which is add to the conflict graph gets an increase in the VSIDS
    2677 *
    2678 * @note That is different to the VSIDS preseted in the literature
    2679 */
    2680 SCIP_CALL( incVSIDS(var, blkmem, set, stat, SCIPbdchginfoGetBoundtype(bdchginfo), relaxedbd, set->conf_conflictgraphweight) );
    2681 nbdchgs++;
    2682 }
    2683 else
    2684 {
    2685 /* put remaining bound changes into conflict candidate queue */
    2686 if( lbchginfoposs[v] >= 0 )
    2687 {
    2688 SCIP_CALL( conflictAddBound(conflict, blkmem, set, stat, var, SCIP_BOUNDTYPE_LOWER, \
    2689 &var->lbchginfos[lbchginfoposs[v]], SCIPbdchginfoGetNewbound(&var->lbchginfos[lbchginfoposs[v]])) );
    2690 nbdchgs++;
    2691 }
    2692 if( ubchginfoposs[v] >= 0 )
    2693 {
    2694 assert(!SCIPbdchginfoIsRedundant(&var->ubchginfos[ubchginfoposs[v]]));
    2695 SCIP_CALL( conflictAddBound(conflict, blkmem, set, stat, var, SCIP_BOUNDTYPE_UPPER, \
    2696 &var->ubchginfos[ubchginfoposs[v]], SCIPbdchginfoGetNewbound(&var->ubchginfos[ubchginfoposs[v]])) );
    2697 nbdchgs++;
    2698 }
    2699 }
    2700 }
    2701
    2702 if( v == nvars )
    2703 {
    2704 /* check if the conflict analysis is applicable */
    2706 {
    2707 /* analyze the conflict set, and create conflict constraints on success */
    2708 SCIP_CALL( conflictAnalyze(conflict, blkmem, set, stat, prob, tree, diving, 0, FALSE, nconss, nliterals, \
    2709 nreconvconss, nreconvliterals) );
    2710 }
    2711 }
    2712
    2713 return SCIP_OKAY;
    2714}
    2715
    2716/** check if the bound change info (which is the potential next candidate which is queued) is valid for the current
    2717 * conflict analysis; a bound change info can get invalid if after this one was added to the queue, a weaker bound
    2718 * change was added to the queue (due the bound widening idea) which immediately makes this bound change redundant; due
    2719 * to the priority we did not removed that bound change info since that cost O(log(n)); hence we have to skip/ignore it
    2720 * now
    2721 *
    2722 * The following situations can occur before for example the bound change info (x >= 3) is potentially popped from the
    2723 * queue.
    2724 *
    2725 * Postcondition: the reason why (x >= 3) was queued is that at this time point no lower bound of x was involved yet in
    2726 * the current conflict or the lower bound which was involved until then was stronger, e.g., (x >= 2).
    2727 *
    2728 * 1) during the time until (x >= 3) gets potentially popped no weaker lower bound was added to the queue, in that case
    2729 * the conflictlbcount is valid and conflictlb is 3; that is (var->conflictlbcount == conflict->count &&
    2730 * var->conflictlb == 3)
    2731 *
    2732 * 2) a weaker bound change info gets queued (e.g., x >= 4); this bound change is popped before (x >= 3) since it has
    2733 * higher priority (which is the time stamp of the bound change info and (x >= 4) has to be done after (x >= 3)
    2734 * during propagation or branching)
    2735 *
    2736 * a) if (x >= 4) is popped and added to the conflict set the conflictlbcount is still valid and conflictlb is at
    2737 * most 4; that is (var->conflictlbcount == conflict->count && var->conflictlb >= 4); it follows that any bound
    2738 * change info which is stronger than (x >= 4) gets ignored (for example x >= 2)
    2739 *
    2740 * b) if (x >= 4) is popped and resolved without introducing a new lower bound on x until (x >= 3) is a potentially
    2741 * candidate the conflictlbcount indicates that bound change is currently not present; that is
    2742 * (var->conflictlbcount != conflict->count)
    2743 *
    2744 * c) if (x >= 4) is popped and resolved and a new lower bound on x (e.g., x >= 2) is introduced until (x >= 3) is
    2745 * pooped, the conflictlbcount indicates that bound change is currently present; that is (var->conflictlbcount ==
    2746 * conflict->count); however the (x >= 3) only has be explained if conflictlb matches that one; that is
    2747 * (var->conflictlb == bdchginfo->newbound); otherwise it redundant/invalid.
    2748 */
    2750 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    2751 SCIP_BDCHGINFO* bdchginfo /**< bound change information */
    2752 )
    2753{
    2754 SCIP_VAR* var;
    2755
    2756 assert(bdchginfo != NULL);
    2757
    2758 var = SCIPbdchginfoGetVar(bdchginfo);
    2759 assert(var != NULL);
    2760
    2761 /* the bound change info of a binary (domained) variable can never be invalid since the concepts of relaxed bounds
    2762 * and bound widening do not make sense for these type of variables
    2763 */
    2764 if( SCIPvarIsBinary(var) )
    2765 return FALSE;
    2766
    2767 /* check if the bdchginfo is invalid since a tight/weaker bound change was already explained */
    2769 {
    2770 if( var->conflictlbcount != conflict->count || var->conflictlb != SCIPbdchginfoGetNewbound(bdchginfo) ) /*lint !e777*/
    2771 {
    2772 assert(!SCIPvarIsBinary(var));
    2773 return TRUE;
    2774 }
    2775 }
    2776 else
    2777 {
    2778 assert(SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_UPPER);
    2779
    2780 if( var->conflictubcount != conflict->count || var->conflictub != SCIPbdchginfoGetNewbound(bdchginfo) ) /*lint !e777*/
    2781 {
    2782 assert(!SCIPvarIsBinary(var));
    2783 return TRUE;
    2784 }
    2785 }
    2786
    2787 return FALSE;
    2788}
    2789
    2790/** adds given bound changes to a conflict set */
    2791static
    2793 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    2794 SCIP_CONFLICTSET* conflictset, /**< conflict set */
    2795 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
    2796 SCIP_SET* set, /**< global SCIP settings */
    2797 SCIP_BDCHGINFO** bdchginfos, /**< bound changes to add to the conflict set */
    2798 int nbdchginfos /**< number of bound changes to add */
    2799 )
    2800{
    2801 SCIP_BDCHGINFO** confbdchginfos;
    2802 SCIP_BDCHGINFO* bdchginfo;
    2803 SCIP_Real* confrelaxedbds;
    2804 int* confsortvals;
    2805 int confnbdchginfos;
    2806 int idx;
    2807 int sortval;
    2808 int i;
    2809 SCIP_BOUNDTYPE boundtype;
    2810
    2811 assert(conflict != NULL);
    2812 assert(conflictset != NULL);
    2813 assert(blkmem != NULL);
    2814 assert(set != NULL);
    2815 assert(bdchginfos != NULL || nbdchginfos == 0);
    2816
    2817 /* nothing to add */
    2818 if( nbdchginfos == 0 )
    2819 return SCIP_OKAY;
    2820
    2821 assert(bdchginfos != NULL);
    2822
    2823 /* only one element to add, use the single insertion method */
    2824 if( nbdchginfos == 1 )
    2825 {
    2826 bdchginfo = bdchginfos[0];
    2827 assert(bdchginfo != NULL);
    2828
    2829 if( !bdchginfoIsInvalid(conflict, bdchginfo) )
    2830 {
    2831 SCIP_CALL( conflictsetAddBound(conflictset, blkmem, set, bdchginfo, SCIPbdchginfoGetRelaxedBound(bdchginfo)) );
    2832 }
    2833 else
    2834 {
    2835 SCIPsetDebugMsg(set, "-> bound change info [%d:<%s> %s %g] is invalid -> ignore it\n", SCIPbdchginfoGetDepth(bdchginfo),
    2837 SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
    2838 SCIPbdchginfoGetNewbound(bdchginfo));
    2839 }
    2840
    2841 return SCIP_OKAY;
    2842 }
    2843
    2844 confnbdchginfos = conflictset->nbdchginfos;
    2845
    2846 /* allocate memory for additional element */
    2847 SCIP_CALL( conflictsetEnsureBdchginfosMem(conflictset, blkmem, set, confnbdchginfos + nbdchginfos) );
    2848
    2849 confbdchginfos = conflictset->bdchginfos;
    2850 confrelaxedbds = conflictset->relaxedbds;
    2851 confsortvals = conflictset->sortvals;
    2852
    2853 assert(SCIP_BOUNDTYPE_LOWER == FALSE); /*lint !e641 !e506*/
    2854 assert(SCIP_BOUNDTYPE_UPPER == TRUE); /*lint !e641 !e506*/
    2855
    2856 for( i = 0; i < nbdchginfos; ++i )
    2857 {
    2858 bdchginfo = bdchginfos[i];
    2859 assert(bdchginfo != NULL);
    2860
    2861 /* add only valid bound change infos */
    2862 if( !bdchginfoIsInvalid(conflict, bdchginfo) )
    2863 {
    2864 /* calculate sorting value */
    2865 boundtype = SCIPbdchginfoGetBoundtype(bdchginfo);
    2866 assert(SCIPbdchginfoGetVar(bdchginfo) != NULL);
    2867
    2868 idx = SCIPvarGetIndex(SCIPbdchginfoGetVar(bdchginfo));
    2869 assert(idx < INT_MAX/2);
    2870
    2871 assert((int)boundtype == 0 || (int)boundtype == 1);
    2872 sortval = 2*idx + (int)boundtype; /* first sorting criteria: variable index, second criteria: boundtype */
    2873
    2874 /* add new element */
    2875 confbdchginfos[confnbdchginfos] = bdchginfo;
    2876 confrelaxedbds[confnbdchginfos] = SCIPbdchginfoGetRelaxedBound(bdchginfo);
    2877 confsortvals[confnbdchginfos] = sortval;
    2878 ++confnbdchginfos;
    2879
    2881 conflictset->hasrelaxonlyvar = TRUE;
    2882 }
    2883 else
    2884 {
    2885 SCIPsetDebugMsg(set, "-> bound change info [%d:<%s> %s %g] is invalid -> ignore it\n", SCIPbdchginfoGetDepth(bdchginfo),
    2887 SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
    2888 SCIPbdchginfoGetNewbound(bdchginfo));
    2889 }
    2890 }
    2891 assert(confnbdchginfos <= conflictset->nbdchginfos + nbdchginfos);
    2892
    2893 /* sort and merge the new conflict set */
    2894 if( confnbdchginfos > conflictset->nbdchginfos )
    2895 {
    2896 int k = 0;
    2897
    2898 /* sort array */
    2899 SCIPsortIntPtrReal(confsortvals, (void**)confbdchginfos, confrelaxedbds, confnbdchginfos);
    2900
    2901 i = 1;
    2902 /* merge multiple bound changes */
    2903 while( i < confnbdchginfos )
    2904 {
    2905 assert(i > k);
    2906
    2907 /* is this a multiple bound change */
    2908 if( confsortvals[k] == confsortvals[i] )
    2909 {
    2910 if( SCIPbdchginfoIsTighter(confbdchginfos[k], confbdchginfos[i]) )
    2911 ++i;
    2912 else if( SCIPbdchginfoIsTighter(confbdchginfos[i], confbdchginfos[k]) )
    2913 {
    2914 /* replace worse bound change info by tighter bound change info */
    2915 confbdchginfos[k] = confbdchginfos[i];
    2916 confrelaxedbds[k] = confrelaxedbds[i];
    2917 ++i;
    2918 }
    2919 else
    2920 {
    2921 /* both bound change are equivalent; hence, keep the worse relaxed bound and remove one of them */
    2922 confrelaxedbds[k] = (confsortvals[k] % 2 == 0) ? MAX(confrelaxedbds[k], confrelaxedbds[i]) : MIN(confrelaxedbds[k], confrelaxedbds[i]);
    2923 ++i;
    2924 }
    2925 }
    2926 else
    2927 {
    2928 /* all bound change infos must be valid */
    2929 assert(!bdchginfoIsInvalid(conflict, confbdchginfos[k]));
    2930
    2931 ++k;
    2932 /* move next comparison element to the correct position */
    2933 if( k != i )
    2934 {
    2935 confbdchginfos[k] = confbdchginfos[i];
    2936 confrelaxedbds[k] = confrelaxedbds[i];
    2937 confsortvals[k] = confsortvals[i];
    2938 }
    2939 ++i;
    2940 }
    2941 }
    2942 /* last bound change infos must also be valid */
    2943 assert(!bdchginfoIsInvalid(conflict, confbdchginfos[k]));
    2944 /* the number of bound change infos cannot be decreased, it would mean that the conflict set was not merged
    2945 * before
    2946 */
    2947 assert(conflictset->nbdchginfos <= k + 1 );
    2948 assert(k + 1 <= confnbdchginfos);
    2949
    2950 conflictset->nbdchginfos = k + 1;
    2951 }
    2952
    2953 return SCIP_OKAY;
    2954}
    2955
    2956/** removes and returns next conflict analysis candidate from the candidate queue */
    2957static
    2959 SCIP_CONFLICT* conflict /**< conflict analysis data */
    2960 )
    2961{
    2962 SCIP_BDCHGINFO* bdchginfo;
    2963 SCIP_VAR* var;
    2964
    2965 assert(conflict != NULL);
    2966
    2967 if( SCIPpqueueNElems(conflict->forcedbdchgqueue) > 0 )
    2968 bdchginfo = (SCIP_BDCHGINFO*)(SCIPpqueueRemove(conflict->forcedbdchgqueue));
    2969 else
    2970 bdchginfo = (SCIP_BDCHGINFO*)(SCIPpqueueRemove(conflict->bdchgqueue));
    2971
    2972 assert(!SCIPbdchginfoIsRedundant(bdchginfo));
    2973
    2974 /* if we have a candidate this one should be valid for the current conflict analysis */
    2975 assert(!bdchginfoIsInvalid(conflict, bdchginfo));
    2976
    2977 /* mark the bound change to be no longer in the conflict (it will be either added again to the conflict set or
    2978 * replaced by resolving, which might add a weaker change on the same bound to the queue)
    2979 */
    2980 var = SCIPbdchginfoGetVar(bdchginfo);
    2982 {
    2983 var->conflictlbcount = 0;
    2985 }
    2986 else
    2987 {
    2988 assert(SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_UPPER);
    2989 var->conflictubcount = 0;
    2991 }
    2992
    2993#if defined(SCIP_CONFGRAPH) || defined(SCIP_CONFGRAPH_DOT)
    2994 confgraphSetCurrentBdchg(bdchginfo);
    2995#endif
    2996
    2997 return bdchginfo;
    2998}
    2999
    3000/** returns next conflict analysis candidate from the candidate queue without removing it */
    3001static
    3003 SCIP_CONFLICT* conflict /**< conflict analysis data */
    3004 )
    3005{
    3006 SCIP_BDCHGINFO* bdchginfo;
    3007
    3008 assert(conflict != NULL);
    3009
    3010 if( SCIPpqueueNElems(conflict->forcedbdchgqueue) > 0 )
    3011 {
    3012 /* get next potential candidate */
    3013 bdchginfo = (SCIP_BDCHGINFO*)(SCIPpqueueFirst(conflict->forcedbdchgqueue));
    3014
    3015 /* check if this candidate is valid */
    3016 if( bdchginfoIsInvalid(conflict, bdchginfo) )
    3017 {
    3018 SCIPdebugMessage("bound change info [%d:<%s> %s %g] is invalid -> pop it from the force queue\n", SCIPbdchginfoGetDepth(bdchginfo),
    3020 SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
    3021 SCIPbdchginfoGetNewbound(bdchginfo));
    3022
    3023 /* pop the invalid bound change info from the queue */
    3024 (void)(SCIPpqueueRemove(conflict->forcedbdchgqueue));
    3025
    3026 /* call method recursively to get next conflict analysis candidate */
    3027 bdchginfo = conflictFirstCand(conflict);
    3028 }
    3029 }
    3030 else
    3031 {
    3032 bdchginfo = (SCIP_BDCHGINFO*)(SCIPpqueueFirst(conflict->bdchgqueue));
    3033
    3034 /* check if this candidate is valid */
    3035 if( bdchginfo != NULL && bdchginfoIsInvalid(conflict, bdchginfo) )
    3036 {
    3037 SCIPdebugMessage("bound change info [%d:<%s> %s %g] is invalid -> pop it from the queue\n", SCIPbdchginfoGetDepth(bdchginfo),
    3039 SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
    3040 SCIPbdchginfoGetNewbound(bdchginfo));
    3041
    3042 /* pop the invalid bound change info from the queue */
    3043 (void)(SCIPpqueueRemove(conflict->bdchgqueue));
    3044
    3045 /* call method recursively to get next conflict analysis candidate */
    3046 bdchginfo = conflictFirstCand(conflict);
    3047 }
    3048 }
    3049 assert(bdchginfo == NULL || !SCIPbdchginfoIsRedundant(bdchginfo));
    3050
    3051 return bdchginfo;
    3052}
    3053
    3054/** adds the current conflict set (extended by all remaining bound changes in the queue) to the pool of conflict sets */
    3055static
    3057 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    3058 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
    3059 SCIP_SET* set, /**< global SCIP settings */
    3060 SCIP_STAT* stat, /**< dynamic problem statistics */
    3061 SCIP_TREE* tree, /**< branch and bound tree */
    3062 int validdepth, /**< minimal depth level at which the conflict set is valid */
    3063 SCIP_Bool diving, /**< are we in strong branching or diving mode? */
    3064 SCIP_Bool repropagate, /**< should the constraint trigger a repropagation? */
    3065 SCIP_Bool* success, /**< pointer to store whether the conflict set is valid */
    3066 int* nliterals /**< pointer to store the number of literals in the generated conflictset */
    3067 )
    3068{
    3069 SCIP_CONFLICTSET* conflictset;
    3070 SCIP_BDCHGINFO** bdchginfos;
    3071 int nbdchginfos;
    3072 int currentdepth;
    3073 int focusdepth;
    3074
    3075 assert(conflict != NULL);
    3076 assert(conflict->conflictset != NULL);
    3077 assert(set != NULL);
    3078 assert(stat != NULL);
    3079 assert(tree != NULL);
    3080 assert(success != NULL);
    3081 assert(nliterals != NULL);
    3082 assert(SCIPpqueueNElems(conflict->forcedbdchgqueue) == 0);
    3083
    3084 *success = FALSE;
    3085 *nliterals = 0;
    3086
    3087 /* check, whether local conflicts are allowed */
    3088 validdepth = MAX(validdepth, conflict->conflictset->validdepth);
    3089 if( !set->conf_allowlocal && validdepth > 0 )
    3090 return SCIP_OKAY;
    3091
    3092 focusdepth = SCIPtreeGetFocusDepth(tree);
    3093 currentdepth = SCIPtreeGetCurrentDepth(tree);
    3094 assert(currentdepth == tree->pathlen-1);
    3095 assert(focusdepth <= currentdepth);
    3096 assert(0 <= conflict->conflictset->validdepth && conflict->conflictset->validdepth <= currentdepth);
    3097 assert(0 <= validdepth && validdepth <= currentdepth);
    3098
    3099 /* get the elements of the bound change queue */
    3100 bdchginfos = (SCIP_BDCHGINFO**)SCIPpqueueElems(conflict->bdchgqueue);
    3101 nbdchginfos = SCIPpqueueNElems(conflict->bdchgqueue);
    3102
    3103 /* create a copy of the current conflict set, allocating memory for the additional elements of the queue */
    3104 SCIP_CALL( conflictsetCopy(&conflictset, blkmem, conflict->conflictset, nbdchginfos) );
    3105 conflictset->validdepth = validdepth;
    3106 conflictset->repropagate = repropagate;
    3107
    3108 /* add the valid queue elements to the conflict set */
    3109 SCIPsetDebugMsg(set, "adding %d variables from the queue as temporary conflict variables\n", nbdchginfos);
    3110 SCIP_CALL( conflictsetAddBounds(conflict, conflictset, blkmem, set, bdchginfos, nbdchginfos) );
    3111
    3112 /* calculate the depth, at which the conflictset should be inserted */
    3113 SCIP_CALL( conflictsetCalcInsertDepth(conflictset, set, tree) );
    3114 assert(conflictset->validdepth <= conflictset->insertdepth && conflictset->insertdepth <= currentdepth);
    3115 SCIPsetDebugMsg(set, " -> conflict with %d literals found at depth %d is active in depth %d and valid in depth %d\n",
    3116 conflictset->nbdchginfos, currentdepth, conflictset->insertdepth, conflictset->validdepth);
    3117
    3118 /* if all branching variables are in the conflict set, the conflict set is of no use;
    3119 * don't use conflict sets that are only valid in the probing path but not in the problem tree
    3120 */
    3121 if( (diving || conflictset->insertdepth < currentdepth) && conflictset->insertdepth <= focusdepth )
    3122 {
    3123 /* if the conflict should not be located only in the subtree where it is useful, put it to its valid depth level */
    3124 if( !set->conf_settlelocal )
    3125 conflictset->insertdepth = conflictset->validdepth;
    3126
    3127 *nliterals = conflictset->nbdchginfos;
    3128 SCIPsetDebugMsg(set, " -> final conflict set has %d literals\n", *nliterals);
    3129
    3130 /* check conflict set on debugging solution */
    3131 SCIP_CALL( SCIPdebugCheckConflict(blkmem, set, tree->path[validdepth], \
    3132 conflictset->bdchginfos, conflictset->relaxedbds, conflictset->nbdchginfos) ); /*lint !e506 !e774*/
    3133
    3134 /* move conflictset to the conflictset storage */
    3135 SCIP_CALL( conflictInsertConflictset(conflict, blkmem, set, &conflictset) );
    3136 *success = TRUE;
    3137 }
    3138 else
    3139 {
    3140 /* free the temporary conflict set */
    3141 SCIPconflictsetFree(&conflictset, blkmem);
    3142 }
    3143
    3144 return SCIP_OKAY;
    3145}
    3146
    3147/** tries to resolve given bound change
    3148 * - resolutions on local constraints are only applied, if the constraint is valid at the
    3149 * current minimal valid depth level, because this depth level is the topmost level to add the conflict
    3150 * constraint to anyways
    3151 *
    3152 * @note it is sufficient to explain the relaxed bound change
    3153 */
    3154static
    3156 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    3157 SCIP_SET* set, /**< global SCIP settings */
    3158 SCIP_BDCHGINFO* bdchginfo, /**< bound change to resolve */
    3159 SCIP_Real relaxedbd, /**< the relaxed bound */
    3160 int validdepth, /**< minimal depth level at which the conflict is valid */
    3161 SCIP_Bool* resolved /**< pointer to store whether the bound change was resolved */
    3162 )
    3163{
    3164 SCIP_VAR* actvar;
    3165 SCIP_CONS* infercons;
    3166 SCIP_PROP* inferprop;
    3167 SCIP_RESULT result;
    3168
    3169#ifndef NDEBUG
    3170 int nforcedbdchgqueue;
    3171 int nbdchgqueue;
    3172
    3173 /* store the current size of the conflict queues */
    3174 assert(conflict != NULL);
    3175 nforcedbdchgqueue = SCIPpqueueNElems(conflict->forcedbdchgqueue);
    3176 nbdchgqueue = SCIPpqueueNElems(conflict->bdchgqueue);
    3177#else
    3178 assert(conflict != NULL);
    3179#endif
    3180
    3181 assert(resolved != NULL);
    3182 assert(!SCIPbdchginfoIsRedundant(bdchginfo));
    3183
    3184 *resolved = FALSE;
    3185
    3186 actvar = SCIPbdchginfoGetVar(bdchginfo);
    3187 assert(actvar != NULL);
    3188 assert(SCIPvarIsActive(actvar));
    3189
    3190#ifdef SCIP_DEBUG
    3191 {
    3192 int i;
    3193 SCIPsetDebugMsg(set, "processing next conflicting bound (depth: %d, valid depth: %d, bdchgtype: %s [%s], vartype: %d): [<%s> %s %g(%g)]\n",
    3194 SCIPbdchginfoGetDepth(bdchginfo), validdepth,
    3196 : SCIPbdchginfoGetChgtype(bdchginfo) == SCIP_BOUNDCHGTYPE_CONSINFER ? "cons" : "prop",
    3200 : SCIPbdchginfoGetInferProp(bdchginfo) == NULL ? "-"
    3202 SCIPvarGetType(actvar), SCIPvarGetName(actvar),
    3203 SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
    3204 SCIPbdchginfoGetNewbound(bdchginfo), relaxedbd);
    3205 SCIPsetDebugMsg(set, " - conflict set :");
    3206
    3207 for( i = 0; i < conflict->conflictset->nbdchginfos; ++i )
    3208 {
    3209 SCIPsetDebugMsgPrint(set, " [%d:<%s> %s %g(%g)]", SCIPbdchginfoGetDepth(conflict->conflictset->bdchginfos[i]),
    3213 }
    3215 SCIPsetDebugMsg(set, " - forced candidates :");
    3216
    3217 for( i = 0; i < SCIPpqueueNElems(conflict->forcedbdchgqueue); ++i )
    3218 {
    3221 bdchginfoIsInvalid(conflict, info) ? "<!>" : SCIPbdchginfoGetBoundtype(info) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
    3223 }
    3225 SCIPsetDebugMsg(set, " - optional candidates:");
    3226
    3227 for( i = 0; i < SCIPpqueueNElems(conflict->bdchgqueue); ++i )
    3228 {
    3229 SCIP_BDCHGINFO* info = (SCIP_BDCHGINFO*)(SCIPpqueueElems(conflict->bdchgqueue)[i]);
    3231 bdchginfoIsInvalid(conflict, info) ? "<!>" : SCIPbdchginfoGetBoundtype(info) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
    3233 }
    3235 }
    3236#endif
    3237
    3238 /* check, if the bound change can and should be resolved:
    3239 * - resolutions on local constraints should only be applied, if the constraint is valid at the
    3240 * current minimal valid depth level (which is initialized with the valid depth level of the initial
    3241 * conflict set), because this depth level is the topmost level to add the conflict constraint to anyways
    3242 */
    3243 switch( SCIPbdchginfoGetChgtype(bdchginfo) )
    3244 {
    3246 infercons = SCIPbdchginfoGetInferCons(bdchginfo);
    3247 assert(infercons != NULL);
    3248
    3249 if( SCIPconsIsGlobal(infercons) || SCIPconsGetValidDepth(infercons) <= validdepth )
    3250 {
    3251 SCIP_VAR* infervar;
    3252 int inferinfo;
    3253 SCIP_BOUNDTYPE inferboundtype;
    3254 SCIP_BDCHGIDX* bdchgidx;
    3255
    3256 /* resolve bound change by asking the constraint that inferred the bound to put all bounds that were
    3257 * the reasons for the conflicting bound change on the priority queue
    3258 */
    3259 infervar = SCIPbdchginfoGetInferVar(bdchginfo);
    3260 inferinfo = SCIPbdchginfoGetInferInfo(bdchginfo);
    3261 inferboundtype = SCIPbdchginfoGetInferBoundtype(bdchginfo);
    3262 bdchgidx = SCIPbdchginfoGetIdx(bdchginfo);
    3263 assert(infervar != NULL);
    3264
    3265 SCIPsetDebugMsg(set, "resolving bound <%s> %s %g(%g) [status:%d, type:%d, depth:%d, pos:%d]: <%s> %s %g [cons:<%s>(%s), info:%d]\n",
    3266 SCIPvarGetName(actvar),
    3267 SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
    3268 SCIPbdchginfoGetNewbound(bdchginfo), relaxedbd,
    3269 SCIPvarGetStatus(actvar), SCIPvarGetType(actvar),
    3270 SCIPbdchginfoGetDepth(bdchginfo), SCIPbdchginfoGetPos(bdchginfo),
    3271 SCIPvarGetName(infervar),
    3272 inferboundtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
    3273 SCIPgetVarBdAtIndex(set->scip, infervar, inferboundtype, bdchgidx, TRUE),
    3274 SCIPconsGetName(infercons),
    3275 SCIPconsIsGlobal(infercons) ? "global" : "local",
    3276 inferinfo);
    3277
    3278 /* in case the inference variables is not an active variables, we need to transform the relaxed bound */
    3279 if( actvar != infervar )
    3280 {
    3281 SCIP_VAR* var;
    3282 SCIP_Real scalar;
    3283 SCIP_Real constant;
    3284
    3287 || (SCIPvarGetStatus(infervar) == SCIP_VARSTATUS_MULTAGGR && SCIPvarGetMultaggrNVars(infervar) == 1));
    3288
    3289 scalar = 1.0;
    3290 constant = 0.0;
    3291
    3292 var = infervar;
    3293
    3294 /* transform given variable to active variable */
    3295 SCIP_CALL( SCIPvarGetProbvarSum(&var, set, &scalar, &constant) );
    3296 assert(var == actvar);
    3297
    3298 relaxedbd *= scalar;
    3299 relaxedbd += constant;
    3300 }
    3301
    3302 SCIP_CALL( SCIPconsResolvePropagation(infercons, set, infervar, inferinfo, inferboundtype, bdchgidx, relaxedbd, &result) );
    3303 *resolved = (result == SCIP_SUCCESS);
    3304 }
    3305 break;
    3306
    3308 inferprop = SCIPbdchginfoGetInferProp(bdchginfo);
    3309 if( inferprop != NULL )
    3310 {
    3311 SCIP_VAR* infervar;
    3312 int inferinfo;
    3313 SCIP_BOUNDTYPE inferboundtype;
    3314 SCIP_BDCHGIDX* bdchgidx;
    3315
    3316 /* resolve bound change by asking the propagator that inferred the bound to put all bounds that were
    3317 * the reasons for the conflicting bound change on the priority queue
    3318 */
    3319 infervar = SCIPbdchginfoGetInferVar(bdchginfo);
    3320 inferinfo = SCIPbdchginfoGetInferInfo(bdchginfo);
    3321 inferboundtype = SCIPbdchginfoGetInferBoundtype(bdchginfo);
    3322 bdchgidx = SCIPbdchginfoGetIdx(bdchginfo);
    3323 assert(infervar != NULL);
    3324
    3325 SCIPsetDebugMsg(set, "resolving bound <%s> %s %g(%g) [status:%d, depth:%d, pos:%d]: <%s> %s %g [prop:<%s>, info:%d]\n",
    3326 SCIPvarGetName(actvar),
    3327 SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
    3328 SCIPbdchginfoGetNewbound(bdchginfo), relaxedbd,
    3329 SCIPvarGetStatus(actvar), SCIPbdchginfoGetDepth(bdchginfo), SCIPbdchginfoGetPos(bdchginfo),
    3330 SCIPvarGetName(infervar),
    3331 inferboundtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
    3332 SCIPgetVarBdAtIndex(set->scip, infervar, inferboundtype, bdchgidx, TRUE),
    3333 SCIPpropGetName(inferprop), inferinfo);
    3334
    3335 SCIP_CALL( SCIPpropResolvePropagation(inferprop, set, infervar, inferinfo, inferboundtype, bdchgidx, relaxedbd, &result) );
    3336 *resolved = (result == SCIP_SUCCESS);
    3337 }
    3338 break;
    3339
    3341 assert(!(*resolved));
    3342 break;
    3343
    3344 default:
    3345 SCIPerrorMessage("invalid bound change type <%d>\n", SCIPbdchginfoGetChgtype(bdchginfo));
    3346 return SCIP_INVALIDDATA;
    3347 }
    3348
    3349 SCIPsetDebugMsg(set, "resolving status: %u\n", *resolved);
    3350
    3351#ifndef NDEBUG
    3352 /* subtract the size of the conflicq queues */
    3353 nforcedbdchgqueue -= SCIPpqueueNElems(conflict->forcedbdchgqueue);
    3354 nbdchgqueue -= SCIPpqueueNElems(conflict->bdchgqueue);
    3355
    3356 /* in case the bound change was not resolved, the conflict queues should have the same size (contents) */
    3357 assert((*resolved) || (nforcedbdchgqueue == 0 && nbdchgqueue == 0));
    3358#endif
    3359
    3360 return SCIP_OKAY;
    3361}
    3362
    3363/** clears the conflict queue and the current conflict set */
    3364static
    3366 SCIP_CONFLICT* conflict /**< conflict analysis data */
    3367 )
    3368{
    3369 assert(conflict != NULL);
    3370
    3371 SCIPpqueueClear(conflict->bdchgqueue);
    3373 conflictsetClear(conflict->conflictset);
    3374}
    3375
    3376
    3377/** clears the resolution conflict analysis queues and the bounds leading to conflict */
    3378static
    3380 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    3381 SCIP_SET* set, /**< global SCIP settings */
    3382 SCIP_PROB* prob /**< problem data */
    3383 )
    3384{
    3385 int nvars;
    3386 int i;
    3387
    3388 assert(conflict != NULL);
    3389 assert(set != NULL);
    3390 assert(prob != NULL);
    3391
    3392 if( !set->conf_usegenres )
    3393 return;
    3394
    3395 /* clear the resolution conflict analysis queues */
    3396 SCIPpqueueClear(conflict->resbdchgqueue);
    3397
    3398 /* reset the current lower and upper bounds leading to conflict */
    3399 nvars = SCIPprobGetNVars(prob);
    3400
    3401 /* allocate memory for the lower and upper bounds of variables used in the resolution conflict analysis */
    3402 if(conflict->conflictprobnvars < nvars)
    3403 {
    3404 conflict->conflictprobnvars = nvars;
    3405 BMSreallocMemoryArray(&conflict->conflictvarslbs, nvars);
    3406 BMSreallocMemoryArray(&conflict->conflictvarsubs, nvars);
    3407 }
    3408
    3409 for( i = 0; i < nvars; ++i )
    3410 {
    3411 conflict->conflictvarslbs[i] = SCIP_REAL_MIN;
    3412 conflict->conflictvarsubs[i] = SCIP_REAL_MAX;
    3413 }
    3414}
    3415
    3416/** initializes propagation and resolution conflict analysis by clearing the conflict candidate queues */
    3418 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    3419 SCIP_SET* set, /**< global SCIP settings */
    3420 SCIP_STAT* stat, /**< problem statistics */
    3421 SCIP_PROB* prob, /**< problem data */
    3422 SCIP_CONFTYPE conftype, /**< type of the conflict */
    3423 SCIP_Bool usescutoffbound /**< depends the conflict on a cutoff bound? */
    3424 )
    3425{
    3426 assert(conflict != NULL);
    3427 assert(set != NULL);
    3428 assert(stat != NULL);
    3429 assert(prob != NULL);
    3430
    3431 SCIPsetDebugMsg(set, "initializing conflict analysis\n");
    3432
    3433 /* clear the conflict candidate queue and the conflict set */
    3434 conflictClear(conflict);
    3435
    3436 /* clear the resolution conflict analysis queues and the bounds leading to conflict */
    3437 conflictClearResolution(conflict, set, prob);
    3438
    3439 /* set conflict type */
    3440 assert(conftype == SCIP_CONFTYPE_BNDEXCEEDING || conftype == SCIP_CONFTYPE_INFEASLP
    3441 || conftype == SCIP_CONFTYPE_PROPAGATION);
    3442 conflict->conflictset->conflicttype = conftype;
    3443 conflict->conflictrow->conflicttype = conftype;
    3444
    3445 /* set whether a cutoff bound is involved */
    3446 conflict->conflictset->usescutoffbound = usescutoffbound;
    3447
    3448 /* increase the conflict counter, such that binary variables of new conflict set and new conflict queue are labeled
    3449 * with this new counter
    3450 */
    3451 conflict->count++;
    3452 if( conflict->count == 0 ) /* make sure, 0 is not a valid conflict counter (may happen due to integer overflow) */
    3453 conflict->count = 1;
    3454
    3455 /* increase the conflict score weight for history updates of future conflict reasons */
    3456 if( stat->nnodes > stat->lastconflictnode )
    3457 {
    3458 assert(0.0 < set->conf_scorefac && set->conf_scorefac <= 1.0);
    3459 stat->vsidsweight /= set->conf_scorefac;
    3460 assert(stat->vsidsweight > 0.0);
    3461
    3462 /* if the conflict score for the next conflict exceeds 1000.0, rescale all history conflict scores */
    3463 if( stat->vsidsweight >= 1000.0 )
    3464 {
    3465 int v;
    3466
    3467 for( v = 0; v < prob->nvars; ++v )
    3468 {
    3469 SCIP_CALL( SCIPvarScaleVSIDS(prob->vars[v], 1.0/stat->vsidsweight) );
    3470 }
    3473 stat->vsidsweight = 1.0;
    3474 }
    3475 stat->lastconflictnode = stat->nnodes;
    3476 }
    3477
    3478#if defined(SCIP_CONFGRAPH) || defined(SCIP_CONFGRAPH_DOT)
    3479 confgraphFree();
    3480 SCIP_CALL( confgraphCreate(set, conflict) );
    3481#endif
    3482
    3483 return SCIP_OKAY;
    3484}
    3485
    3486/** convert variable and bound change to active variable */
    3487static
    3489 SCIP_VAR** var, /**< pointer to variable */
    3490 SCIP_SET* set, /**< global SCIP settings */
    3491 SCIP_BOUNDTYPE* boundtype, /**< pointer to type of bound that was changed: lower or upper bound */
    3492 SCIP_Real* bound /**< pointer to bound to convert, or NULL */
    3493 )
    3494{
    3495 SCIP_Real scalar;
    3496 SCIP_Real constant;
    3497
    3498 scalar = 1.0;
    3499 constant = 0.0;
    3500
    3501 /* transform given variable to active variable */
    3502 SCIP_CALL( SCIPvarGetProbvarSum(var, set, &scalar, &constant) );
    3503 assert(SCIPvarGetStatus(*var) == SCIP_VARSTATUS_FIXED || scalar != 0.0); /*lint !e777*/
    3504
    3506 return SCIP_OKAY;
    3507
    3508 /* if the scalar of the aggregation is negative, we have to switch the bound type */
    3509 if( scalar < 0.0 )
    3510 (*boundtype) = SCIPboundtypeOpposite(*boundtype);
    3511
    3512 if( bound != NULL )
    3513 {
    3514 (*bound) -= constant;
    3515 (*bound) /= scalar;
    3516 }
    3517
    3518 return SCIP_OKAY;
    3519}
    3520
    3521/** returns whether bound change has a valid reason that can be resolved in conflict analysis */
    3522static
    3524 SCIP_BDCHGINFO* bdchginfo /**< bound change information */
    3525 )
    3526{
    3527 assert(bdchginfo != NULL);
    3528 assert(!SCIPbdchginfoIsRedundant(bdchginfo));
    3529
    3532 && SCIPbdchginfoGetInferProp(bdchginfo) != NULL));
    3533}
    3534
    3535
    3536/** if only one conflicting bound change of the last depth level was used, and if this can be resolved,
    3537 * creates GRASP-like reconvergence conflict constraints in the conflict graph up to the branching variable of this
    3538 * depth level
    3539 */
    3540static
    3542 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    3543 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
    3544 SCIP_SET* set, /**< global SCIP settings */
    3545 SCIP_STAT* stat, /**< problem statistics */
    3546 SCIP_PROB* prob, /**< problem data */
    3547 SCIP_TREE* tree, /**< branch and bound tree */
    3548 SCIP_Bool diving, /**< are we in strong branching or diving mode? */
    3549 int validdepth, /**< minimal depth level at which the initial conflict set is valid */
    3550 SCIP_BDCHGINFO* firstuip, /**< first UIP of conflict graph */
    3551 int* nreconvconss, /**< pointer to store the number of generated reconvergence constraints */
    3552 int* nreconvliterals /**< pointer to store the number of literals generated reconvergence constraints */
    3553 )
    3554{
    3555 SCIP_BDCHGINFO* uip;
    3556 SCIP_CONFTYPE conftype;
    3557 SCIP_Bool usescutoffbound;
    3558 int firstuipdepth;
    3559 int focusdepth;
    3560 int currentdepth;
    3561 int maxvaliddepth;
    3562
    3563 assert(conflict != NULL);
    3564 assert(firstuip != NULL);
    3565 assert(nreconvconss != NULL);
    3566 assert(nreconvliterals != NULL);
    3567 assert(!SCIPbdchginfoIsRedundant(firstuip));
    3568
    3569 focusdepth = SCIPtreeGetFocusDepth(tree);
    3570 currentdepth = SCIPtreeGetCurrentDepth(tree);
    3571 assert(currentdepth == tree->pathlen-1);
    3572 assert(focusdepth <= currentdepth);
    3573
    3574 /* check, whether local constraints are allowed; however, don't generate reconvergence constraints that are only valid
    3575 * in the probing path and not in the problem tree (i.e. that exceed the focusdepth)
    3576 */
    3577 maxvaliddepth = (set->conf_allowlocal ? MIN(currentdepth-1, focusdepth) : 0);
    3578 if( validdepth > maxvaliddepth )
    3579 return SCIP_OKAY;
    3580
    3581 firstuipdepth = SCIPbdchginfoGetDepth(firstuip);
    3582
    3583 conftype = conflict->conflictset->conflicttype;
    3584 usescutoffbound = conflict->conflictset->usescutoffbound;
    3585
    3586 /* for each succeeding UIP pair of the last depth level, create one reconvergence constraint */
    3587 uip = firstuip;
    3588 while( uip != NULL && SCIPbdchginfoGetDepth(uip) == SCIPbdchginfoGetDepth(firstuip) && bdchginfoIsResolvable(uip) )
    3589 {
    3590 SCIP_BDCHGINFO* oppositeuip;
    3591 SCIP_BDCHGINFO* bdchginfo;
    3592 SCIP_BDCHGINFO* nextuip;
    3593 SCIP_VAR* uipvar;
    3594 SCIP_Real oppositeuipbound;
    3595 SCIP_BOUNDTYPE oppositeuipboundtype;
    3596 int nresolutions;
    3597
    3598 assert(!SCIPbdchginfoIsRedundant(uip));
    3599
    3600 SCIPsetDebugMsg(set, "creating reconvergence constraint for UIP <%s> %s %g in depth %d pos %d\n",
    3603
    3604 /* initialize conflict data */
    3605 SCIP_CALL( SCIPconflictInit(conflict, set, stat, prob, conftype, usescutoffbound) );
    3606
    3607 conflict->conflictset->conflicttype = conftype;
    3608 conflict->conflictset->usescutoffbound = usescutoffbound;
    3609
    3610 /* create a temporary bound change information for the negation of the UIP's bound change;
    3611 * this bound change information is freed in the SCIPconflictFlushConss() call;
    3612 * for reconvergence constraints for continuous variables we can only use the "negation" !(x <= u) == (x >= u);
    3613 * during conflict analysis, we treat a continuous bound "x >= u" in the conflict set as "x > u", and in the
    3614 * generated constraint this is negated again to "x <= u" which is correct.
    3615 */
    3616 uipvar = SCIPbdchginfoGetVar(uip);
    3617 oppositeuipboundtype = SCIPboundtypeOpposite(SCIPbdchginfoGetBoundtype(uip));
    3618 oppositeuipbound = SCIPbdchginfoGetNewbound(uip);
    3619 if( SCIPvarIsIntegral(uipvar) )
    3620 {
    3621 assert(SCIPsetIsIntegral(set, oppositeuipbound));
    3622 oppositeuipbound += (oppositeuipboundtype == SCIP_BOUNDTYPE_LOWER ? +1.0 : -1.0);
    3623 }
    3624 SCIP_CALL( conflictCreateTmpBdchginfo(conflict, blkmem, set, uipvar, oppositeuipboundtype, \
    3625 oppositeuipboundtype == SCIP_BOUNDTYPE_LOWER ? SCIP_REAL_MIN : SCIP_REAL_MAX, oppositeuipbound, &oppositeuip) );
    3626
    3627 /* put the negated UIP into the conflict set */
    3628 SCIP_CALL( conflictAddConflictBound(conflict, blkmem, set, oppositeuip, oppositeuipbound) );
    3629
    3630 /* put positive UIP into priority queue */
    3632
    3633 /* resolve the queue until the next UIP is reached */
    3634 bdchginfo = conflictFirstCand(conflict);
    3635 nextuip = NULL;
    3636 nresolutions = 0;
    3637 while( bdchginfo != NULL && validdepth <= maxvaliddepth )
    3638 {
    3639 SCIP_BDCHGINFO* nextbdchginfo;
    3640 SCIP_Real relaxedbd;
    3641 SCIP_Bool forceresolve;
    3642 int bdchgdepth;
    3643
    3644 /* check if the next bound change must be resolved in every case */
    3645 forceresolve = (SCIPpqueueNElems(conflict->forcedbdchgqueue) > 0);
    3646
    3647 /* remove currently processed candidate and get next conflicting bound from the conflict candidate queue before
    3648 * we remove the candidate we have to collect the relaxed bound since removing the candidate from the queue
    3649 * invalidates the relaxed bound
    3650 */
    3651 assert(bdchginfo == conflictFirstCand(conflict));
    3652 relaxedbd = SCIPbdchginfoGetRelaxedBound(bdchginfo);
    3653 bdchginfo = conflictRemoveCand(conflict);
    3654 nextbdchginfo = conflictFirstCand(conflict);
    3655 bdchgdepth = SCIPbdchginfoGetDepth(bdchginfo);
    3656 assert(bdchginfo != NULL);
    3657 assert(!SCIPbdchginfoIsRedundant(bdchginfo));
    3658 assert(nextbdchginfo == NULL || SCIPbdchginfoGetDepth(bdchginfo) >= SCIPbdchginfoGetDepth(nextbdchginfo)
    3659 || forceresolve);
    3660 assert(bdchgdepth <= firstuipdepth);
    3661
    3662 /* bound changes that are higher in the tree than the valid depth of the conflict can be ignored;
    3663 * multiple insertions of the same bound change can be ignored
    3664 */
    3665 if( bdchgdepth > validdepth && bdchginfo != nextbdchginfo )
    3666 {
    3667 SCIP_VAR* actvar;
    3668 SCIP_Bool resolved;
    3669
    3670 actvar = SCIPbdchginfoGetVar(bdchginfo);
    3671 assert(actvar != NULL);
    3672 assert(SCIPvarIsActive(actvar));
    3673
    3674 /* check if we have to resolve the bound change in this depth level
    3675 * - the starting uip has to be resolved
    3676 * - a bound change should be resolved, if it is in the fuip's depth level and not the
    3677 * next uip (i.e., if it is not the last bound change in the fuip's depth level)
    3678 * - a forced bound change must be resolved in any case
    3679 */
    3680 resolved = FALSE;
    3681 if( bdchginfo == uip
    3682 || (bdchgdepth == firstuipdepth
    3683 && nextbdchginfo != NULL
    3684 && SCIPbdchginfoGetDepth(nextbdchginfo) == bdchgdepth)
    3685 || forceresolve )
    3686 {
    3687 SCIP_CALL( conflictResolveBound(conflict, set, bdchginfo, relaxedbd, validdepth, &resolved) );
    3688 }
    3689
    3690 if( resolved )
    3691 nresolutions++;
    3692 else if( forceresolve )
    3693 {
    3694 /* variable cannot enter the conflict clause: we have to make the conflict clause local, s.t.
    3695 * the unresolved bound change is active in the whole sub tree of the conflict clause
    3696 */
    3697 assert(bdchgdepth >= validdepth);
    3698 validdepth = bdchgdepth;
    3699
    3700 SCIPsetDebugMsg(set, "couldn't resolve forced bound change on <%s> -> new valid depth: %d\n",
    3701 SCIPvarGetName(actvar), validdepth);
    3702 }
    3703 else if( bdchginfo != uip )
    3704 {
    3705 assert(conflict->conflictset != NULL);
    3706 assert(conflict->conflictset->nbdchginfos >= 1); /* starting UIP is already member of the conflict set */
    3707
    3708 /* if this is the first variable of the conflict set besides the current starting UIP, it is the next
    3709 * UIP (or the first unresolvable bound change)
    3710 */
    3711 if( bdchgdepth == firstuipdepth && conflict->conflictset->nbdchginfos == 1 )
    3712 {
    3713 assert(nextuip == NULL);
    3714 nextuip = bdchginfo;
    3715 }
    3716
    3717 /* put bound change into the conflict set */
    3718 SCIP_CALL( conflictAddConflictBound(conflict, blkmem, set, bdchginfo, relaxedbd) );
    3719 assert(conflict->conflictset->nbdchginfos >= 2);
    3720 }
    3721 else
    3722 assert(conflictFirstCand(conflict) == NULL); /* the starting UIP was not resolved */
    3723 }
    3724
    3725 /* get next conflicting bound from the conflict candidate queue (this does not need to be nextbdchginfo, because
    3726 * due to resolving the bound changes, a variable could be added to the queue which must be
    3727 * resolved before nextbdchginfo)
    3728 */
    3729 bdchginfo = conflictFirstCand(conflict);
    3730 }
    3731 assert(nextuip != uip);
    3732
    3733 /* if only one propagation was resolved, the reconvergence constraint is already member of the constraint set
    3734 * (it is exactly the constraint that produced the propagation)
    3735 */
    3736 if( nextuip != NULL && nresolutions >= 2 && bdchginfo == NULL && validdepth <= maxvaliddepth )
    3737 {
    3738 int nlits;
    3739 SCIP_Bool success;
    3740
    3741 assert(SCIPbdchginfoGetDepth(nextuip) == SCIPbdchginfoGetDepth(uip));
    3742
    3743 /* check conflict graph frontier on debugging solution */
    3744 SCIP_CALL( SCIPdebugCheckConflictFrontier(blkmem, set, tree->path[validdepth], \
    3745 bdchginfo, conflict->conflictset->bdchginfos, conflict->conflictset->relaxedbds, \
    3746 conflict->conflictset->nbdchginfos, conflict->bdchgqueue, conflict->forcedbdchgqueue) ); /*lint !e506 !e774*/
    3747
    3748 SCIPsetDebugMsg(set, "creating reconvergence constraint from UIP <%s> to UIP <%s> in depth %d with %d literals after %d resolutions\n",
    3750 SCIPbdchginfoGetDepth(uip), conflict->conflictset->nbdchginfos, nresolutions);
    3751
    3752 /* call the conflict handlers to create a conflict set */
    3753 SCIP_CALL( conflictAddConflictset(conflict, blkmem, set, stat, tree, validdepth, diving, FALSE, &success, &nlits) );
    3754 if( success )
    3755 {
    3756 (*nreconvconss)++;
    3757 (*nreconvliterals) += nlits;
    3758 }
    3759 }
    3760
    3761 /* clear the conflict candidate queue and the conflict set (to make sure, oppositeuip is not referenced anymore) */
    3762 conflictClear(conflict);
    3763
    3764 uip = nextuip;
    3765 }
    3766
    3767 conflict->conflictset->conflicttype = conftype;
    3768 conflict->conflictset->usescutoffbound = usescutoffbound;
    3769
    3770 return SCIP_OKAY;
    3771}
    3772
    3773/** analyzes conflicting bound changes that were added with calls to SCIPconflictAddBound() and
    3774 * SCIPconflictAddRelaxedBound(), and on success, calls the conflict handlers to create a conflict constraint out of
    3775 * the resulting conflict set; afterwards the conflict queue and the conflict set is cleared
    3776 */
    3778 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    3779 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
    3780 SCIP_SET* set, /**< global SCIP settings */
    3781 SCIP_STAT* stat, /**< problem statistics */
    3782 SCIP_PROB* prob, /**< problem data */
    3783 SCIP_TREE* tree, /**< branch and bound tree */
    3784 SCIP_Bool diving, /**< are we in strong branching or diving mode? */
    3785 int validdepth, /**< minimal depth level at which the initial conflict set is valid */
    3786 SCIP_Bool mustresolve, /**< should the conflict set only be used, if a resolution was applied? */
    3787 int* nconss, /**< pointer to store the number of generated conflict constraints */
    3788 int* nliterals, /**< pointer to store the number of literals in generated conflict constraints */
    3789 int* nreconvconss, /**< pointer to store the number of generated reconvergence constraints */
    3790 int* nreconvliterals /**< pointer to store the number of literals generated reconvergence constraints */
    3791 )
    3792{
    3793 SCIP_BDCHGINFO* bdchginfo;
    3794 SCIP_BDCHGINFO** firstuips;
    3795 SCIP_CONFTYPE conftype;
    3796 int nfirstuips;
    3797 int focusdepth;
    3798 int currentdepth;
    3799 int maxvaliddepth;
    3800 int resolvedepth;
    3801 int nresolutions;
    3802 int lastconsnresolutions;
    3803 int lastconsresoldepth;
    3804
    3805 assert(conflict != NULL);
    3806 assert(conflict->conflictset != NULL);
    3807 assert(conflict->conflictset->nbdchginfos >= 0);
    3808 assert(set != NULL);
    3809 assert(stat != NULL);
    3810 assert(0 <= validdepth && validdepth <= SCIPtreeGetCurrentDepth(tree));
    3811 assert(nconss != NULL);
    3812 assert(nliterals != NULL);
    3813 assert(nreconvconss != NULL);
    3814 assert(nreconvliterals != NULL);
    3815
    3816 focusdepth = SCIPtreeGetFocusDepth(tree);
    3817 currentdepth = SCIPtreeGetCurrentDepth(tree);
    3818 assert(currentdepth == tree->pathlen-1);
    3819 assert(focusdepth <= currentdepth);
    3820
    3821 resolvedepth = ((set->conf_fuiplevels >= 0 && set->conf_fuiplevels <= currentdepth)
    3822 ? currentdepth - set->conf_fuiplevels + 1 : 0);
    3823 assert(0 <= resolvedepth && resolvedepth <= currentdepth + 1);
    3824
    3825 /* if we must resolve at least one bound change, find the first UIP at least in the last depth level */
    3826 if( mustresolve )
    3827 resolvedepth = MIN(resolvedepth, currentdepth);
    3828
    3829 SCIPsetDebugMsg(set, "analyzing conflict with %d+%d conflict candidates and starting conflict set of size %d in depth %d (resolvedepth=%d)\n",
    3831 conflict->conflictset->nbdchginfos, currentdepth, resolvedepth);
    3832
    3833 *nconss = 0;
    3834 *nliterals = 0;
    3835 *nreconvconss = 0;
    3836 *nreconvliterals = 0;
    3837
    3838 /* check, whether local conflicts are allowed; however, don't generate conflict constraints that are only valid in the
    3839 * probing path and not in the problem tree (i.e. that exceed the focusdepth)
    3840 */
    3841 maxvaliddepth = (set->conf_allowlocal ? MIN(currentdepth-1, focusdepth) : 0);
    3842 if( validdepth > maxvaliddepth )
    3843 return SCIP_OKAY;
    3844
    3845 /* allocate temporary memory for storing first UIPs (in each depth level, at most two bound changes can be flagged
    3846 * as UIP, namely a binary and a non-binary bound change)
    3847 */
    3848 SCIP_CALL( SCIPsetAllocBufferArray(set, &firstuips, 2*(currentdepth+1)) ); /*lint !e647*/
    3849
    3850 /* process all bound changes in the conflict candidate queue */
    3851 nresolutions = 0;
    3852 lastconsnresolutions = (mustresolve ? 0 : -1);
    3853 lastconsresoldepth = (mustresolve ? currentdepth : INT_MAX);
    3854 bdchginfo = conflictFirstCand(conflict);
    3855 nfirstuips = 0;
    3856
    3857 /* check if the initial reason on debugging solution */
    3858 SCIP_CALL( SCIPdebugCheckConflictFrontier(blkmem, set, tree->path[validdepth], \
    3859 NULL, conflict->conflictset->bdchginfos, conflict->conflictset->relaxedbds, conflict->conflictset->nbdchginfos, \
    3860 conflict->bdchgqueue, conflict->forcedbdchgqueue) ); /*lint !e506 !e774*/
    3861
    3862 while( bdchginfo != NULL && validdepth <= maxvaliddepth )
    3863 {
    3864 SCIP_BDCHGINFO* nextbdchginfo;
    3865 SCIP_Real relaxedbd;
    3866 SCIP_Bool forceresolve;
    3867 int bdchgdepth;
    3868
    3869 assert(!SCIPbdchginfoIsRedundant(bdchginfo));
    3870
    3871 /* check if the next bound change must be resolved in every case */
    3872 forceresolve = (SCIPpqueueNElems(conflict->forcedbdchgqueue) > 0);
    3873
    3874 /* resolve next bound change in queue */
    3875 bdchgdepth = SCIPbdchginfoGetDepth(bdchginfo);
    3876 assert(0 <= bdchgdepth && bdchgdepth <= currentdepth);
    3877 assert(SCIPvarIsActive(SCIPbdchginfoGetVar(bdchginfo)));
    3878 assert(bdchgdepth < tree->pathlen);
    3879 assert(tree->path[bdchgdepth] != NULL);
    3880 assert(tree->path[bdchgdepth]->domchg != NULL);
    3881 assert(SCIPbdchginfoGetPos(bdchginfo) < (int)tree->path[bdchgdepth]->domchg->domchgbound.nboundchgs);
    3882 assert(tree->path[bdchgdepth]->domchg->domchgbound.boundchgs[SCIPbdchginfoGetPos(bdchginfo)].var
    3883 == SCIPbdchginfoGetVar(bdchginfo));
    3884 assert(tree->path[bdchgdepth]->domchg->domchgbound.boundchgs[SCIPbdchginfoGetPos(bdchginfo)].newbound
    3885 == SCIPbdchginfoGetNewbound(bdchginfo)
    3888 == SCIPbdchginfoGetNewbound(bdchginfo)); /*lint !e777*/
    3889 assert((SCIP_BOUNDTYPE)tree->path[bdchgdepth]->domchg->domchgbound.boundchgs[SCIPbdchginfoGetPos(bdchginfo)].boundtype
    3890 == SCIPbdchginfoGetBoundtype(bdchginfo));
    3891
    3892 /* create intermediate conflict constraint */
    3893 assert(nresolutions >= lastconsnresolutions);
    3894 if( !forceresolve )
    3895 {
    3896 if( nresolutions == lastconsnresolutions )
    3897 lastconsresoldepth = bdchgdepth; /* all intermediate depth levels consisted of only unresolved bound changes */
    3898 else if( bdchgdepth < lastconsresoldepth && (set->conf_interconss == -1 || *nconss < set->conf_interconss) )
    3899 {
    3900 int nlits;
    3901 SCIP_Bool success;
    3902
    3903 /* call the conflict handlers to create a conflict set */
    3904 SCIPsetDebugMsg(set, "creating intermediate conflictset after %d resolutions up to depth %d (valid at depth %d): %d conflict bounds, %d bounds in queue\n",
    3905 nresolutions, bdchgdepth, validdepth, conflict->conflictset->nbdchginfos,
    3906 SCIPpqueueNElems(conflict->bdchgqueue));
    3907
    3908 SCIP_CALL( conflictAddConflictset(conflict, blkmem, set, stat, tree, validdepth, diving, TRUE, &success, &nlits) );
    3909 lastconsnresolutions = nresolutions;
    3910 lastconsresoldepth = bdchgdepth;
    3911 if( success )
    3912 {
    3913 (*nconss)++;
    3914 (*nliterals) += nlits;
    3915 }
    3916 }
    3917 }
    3918
    3919 /* remove currently processed candidate and get next conflicting bound from the conflict candidate queue before
    3920 * we remove the candidate we have to collect the relaxed bound since removing the candidate from the queue
    3921 * invalidates the relaxed bound
    3922 */
    3923 assert(bdchginfo == conflictFirstCand(conflict));
    3924 relaxedbd = SCIPbdchginfoGetRelaxedBound(bdchginfo);
    3925 bdchginfo = conflictRemoveCand(conflict);
    3926 nextbdchginfo = conflictFirstCand(conflict);
    3927 assert(bdchginfo != NULL);
    3928 assert(!SCIPbdchginfoIsRedundant(bdchginfo));
    3929 assert(nextbdchginfo == NULL || SCIPbdchginfoGetDepth(bdchginfo) >= SCIPbdchginfoGetDepth(nextbdchginfo)
    3930 || forceresolve);
    3931
    3932 /* we don't need to resolve bound changes that are already active in the valid depth of the current conflict set,
    3933 * because the conflict set can only be added locally at the valid depth, and all bound changes applied in this
    3934 * depth or earlier can be removed from the conflict constraint, since they are already applied in the constraint's
    3935 * subtree;
    3936 * if the next bound change on the remaining queue is equal to the current bound change,
    3937 * this is a multiple insertion in the conflict candidate queue and we can ignore the current
    3938 * bound change
    3939 */
    3940 if( bdchgdepth > validdepth && bdchginfo != nextbdchginfo )
    3941 {
    3942 SCIP_VAR* actvar;
    3943 SCIP_Bool resolved;
    3944
    3945 actvar = SCIPbdchginfoGetVar(bdchginfo);
    3946 assert(actvar != NULL);
    3947 assert(SCIPvarIsActive(actvar));
    3948
    3949 /* check if we want to resolve the bound change in this depth level
    3950 * - bound changes should be resolved, if
    3951 * (i) we must apply at least one resolution and didn't resolve a bound change yet, or
    3952 * (ii) their depth level is at least equal to the minimal resolving depth, and
    3953 * they are not the last remaining conflicting bound change in their depth level
    3954 * (iii) the bound change resolving is forced (i.e., the forced queue was non-empty)
    3955 */
    3956 resolved = FALSE;
    3957 if( (mustresolve && nresolutions == 0)
    3958 || (bdchgdepth >= resolvedepth
    3959 && nextbdchginfo != NULL
    3960 && SCIPbdchginfoGetDepth(nextbdchginfo) == bdchgdepth)
    3961 || forceresolve )
    3962 {
    3963 SCIP_CALL( conflictResolveBound(conflict, set, bdchginfo, relaxedbd, validdepth, &resolved) );
    3964 }
    3965
    3966 if( resolved )
    3967 nresolutions++;
    3968 else if( forceresolve )
    3969 {
    3970 /* variable cannot enter the conflict clause: we have to make the conflict clause local, s.t.
    3971 * the unresolved bound change is active in the whole sub tree of the conflict clause
    3972 */
    3973 assert(bdchgdepth >= validdepth);
    3974 validdepth = bdchgdepth;
    3975
    3976 SCIPsetDebugMsg(set, "couldn't resolve forced bound change on <%s> -> new valid depth: %d\n",
    3977 SCIPvarGetName(actvar), validdepth);
    3978 }
    3979 else
    3980 {
    3981 /* if this is a UIP (the last bound change in its depth level), it can be used to generate a
    3982 * UIP reconvergence constraint
    3983 */
    3984 if( nextbdchginfo == NULL || SCIPbdchginfoGetDepth(nextbdchginfo) != bdchgdepth )
    3985 {
    3986 assert(nfirstuips < 2*(currentdepth+1));
    3987 firstuips[nfirstuips] = bdchginfo;
    3988 nfirstuips++;
    3989 }
    3990
    3991 /* put variable into the conflict set, using the literal that is currently fixed to FALSE */
    3992 SCIP_CALL( conflictAddConflictBound(conflict, blkmem, set, bdchginfo, relaxedbd) );
    3993 }
    3994 }
    3995
    3996 /* check conflict graph frontier on debugging solution */
    3997 SCIP_CALL( SCIPdebugCheckConflictFrontier(blkmem, set, tree->path[validdepth], \
    3998 bdchginfo, conflict->conflictset->bdchginfos, conflict->conflictset->relaxedbds, conflict->conflictset->nbdchginfos, \
    3999 conflict->bdchgqueue, conflict->forcedbdchgqueue) ); /*lint !e506 !e774*/
    4000
    4001 /* get next conflicting bound from the conflict candidate queue (this needs not to be nextbdchginfo, because
    4002 * due to resolving the bound changes, a bound change could be added to the queue which must be
    4003 * resolved before nextbdchginfo)
    4004 */
    4005 bdchginfo = conflictFirstCand(conflict);
    4006 }
    4007
    4008 /* check, if a valid conflict set was found */
    4009 if( bdchginfo == NULL
    4010 && nresolutions > lastconsnresolutions
    4011 && validdepth <= maxvaliddepth
    4012 && (!mustresolve || nresolutions > 0 || conflict->conflictset->nbdchginfos == 0)
    4013 && SCIPpqueueNElems(conflict->forcedbdchgqueue) == 0 )
    4014 {
    4015 int nlits;
    4016 SCIP_Bool success;
    4017
    4018 /* call the conflict handlers to create a conflict set */
    4019 SCIP_CALL( conflictAddConflictset(conflict, blkmem, set, stat, tree, validdepth, diving, TRUE, &success, &nlits) );
    4020 if( success )
    4021 {
    4022 (*nconss)++;
    4023 (*nliterals) += nlits;
    4024 }
    4025 }
    4026
    4027 /* produce reconvergence constraints defined by succeeding UIP's of the last depth level */
    4028 if( set->conf_reconvlevels != 0 && validdepth <= maxvaliddepth )
    4029 {
    4030 int reconvlevels;
    4031 int i;
    4032
    4033 reconvlevels = (set->conf_reconvlevels == -1 ? INT_MAX : set->conf_reconvlevels);
    4034 for( i = 0; i < nfirstuips; ++i )
    4035 {
    4036 if( SCIPbdchginfoHasInferenceReason(firstuips[i])
    4037 && currentdepth - SCIPbdchginfoGetDepth(firstuips[i]) < reconvlevels )
    4038 {
    4039 SCIP_CALL( conflictCreateReconvergenceConss(conflict, blkmem, set, stat, prob, tree, diving, \
    4040 validdepth, firstuips[i], nreconvconss, nreconvliterals) );
    4041 }
    4042 }
    4043 }
    4044
    4045 /* free the temporary memory */
    4046 SCIPsetFreeBufferArray(set, &firstuips);
    4047
    4048 /* store last conflict type */
    4049 conftype = conflict->conflictset->conflicttype;
    4050
    4051 /* clear the conflict candidate queue and the conflict set */
    4052 conflictClear(conflict);
    4053
    4054 /* restore last conflict type */
    4055 conflict->conflictset->conflicttype = conftype;
    4056
    4057 return SCIP_OKAY;
    4058}
    4059
    4060/** calculates the score of a bound change within a conflict */
    4061static
    4063 SCIP_Real prooflhs, /**< lhs of proof constraint */
    4064 SCIP_Real proofact, /**< activity of the proof constraint */
    4065 SCIP_Real proofactdelta, /**< activity change */
    4066 SCIP_Real proofcoef, /**< coefficient in proof constraint */
    4067 int depth, /**< bound change depth */
    4068 int currentdepth, /**< current depth */
    4069 SCIP_VAR* var, /**< variable corresponding to bound change */
    4070 SCIP_SET* set /**< global SCIP settings */
    4071 )
    4072{
    4073 SCIP_COL* col;
    4074 SCIP_Real score;
    4075
    4076 score = set->conf_proofscorefac * (1.0 - proofactdelta/(prooflhs - proofact));
    4077 score = MAX(score, 0.0);
    4078 score += set->conf_depthscorefac * (SCIP_Real)(depth+1)/(SCIP_Real)(currentdepth+1);
    4079
    4081 col = SCIPvarGetCol(var);
    4082 else
    4083 col = NULL;
    4084
    4085 if( proofcoef > 0.0 )
    4086 {
    4087 if( col != NULL && SCIPcolGetNNonz(col) > 0 )
    4088 score += set->conf_uplockscorefac
    4090 else
    4091 score += set->conf_uplockscorefac * SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL);
    4092 }
    4093 else
    4094 {
    4095 if( col != NULL && SCIPcolGetNNonz(col) > 0 )
    4096 score += set->conf_downlockscorefac
    4098 else
    4099 score += set->conf_downlockscorefac * SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL);
    4100 }
    4101
    4102 return score;
    4103}
    4104
    4105/** ensures, that candidate array can store at least num entries */
    4106static
    4108 SCIP_SET* set, /**< global SCIP settings */
    4109 SCIP_VAR*** cands, /**< pointer to candidate array */
    4110 SCIP_Real** candscores, /**< pointer to candidate score array */
    4111 SCIP_Real** newbounds, /**< pointer to candidate new bounds array */
    4112 SCIP_Real** proofactdeltas, /**< pointer to candidate proof delta array */
    4113 int* candssize, /**< pointer to size of array */
    4114 int num /**< minimal number of candidates to store in array */
    4115 )
    4116{
    4117 assert(cands != NULL);
    4118 assert(candssize != NULL);
    4119
    4120 if( num > *candssize )
    4121 {
    4122 int newsize;
    4123
    4124 newsize = SCIPsetCalcMemGrowSize(set, num);
    4125 SCIP_CALL( SCIPsetReallocBufferArray(set, cands, newsize) );
    4126 SCIP_CALL( SCIPsetReallocBufferArray(set, candscores, newsize) );
    4127 SCIP_CALL( SCIPsetReallocBufferArray(set, newbounds, newsize) );
    4128 SCIP_CALL( SCIPsetReallocBufferArray(set, proofactdeltas, newsize) );
    4129 *candssize = newsize;
    4130 }
    4131 assert(num <= *candssize);
    4132
    4133 return SCIP_OKAY;
    4134}
    4135
    4136/** after changing the global bound of a variable, the bdchginfos that are now redundant are replaced with
    4137 * oldbound = newbound = global bound; if the current bdchginfo is of such kind, the bound is equal to the
    4138 * global bound and we can ignore it by installing a -1 as the corresponding bound change info position
    4139 */
    4140static
    4142 SCIP_VAR* var, /**< problem variable */
    4143 int* lbchginfopos, /**< pointer to lower bound change information position */
    4144 int* ubchginfopos /**< pointer to upper bound change information position */
    4145 )
    4146{
    4147 assert(var != NULL);
    4148 assert(lbchginfopos != NULL);
    4149 assert(ubchginfopos != NULL);
    4150 assert(-1 <= *lbchginfopos && *lbchginfopos <= var->nlbchginfos);
    4151 assert(-1 <= *ubchginfopos && *ubchginfopos <= var->nubchginfos);
    4152 assert(*lbchginfopos == -1 || *lbchginfopos == var->nlbchginfos
    4153 || var->lbchginfos[*lbchginfopos].redundant
    4154 == (var->lbchginfos[*lbchginfopos].oldbound == var->lbchginfos[*lbchginfopos].newbound)); /*lint !e777*/
    4155 assert(*ubchginfopos == -1 || *ubchginfopos == var->nubchginfos
    4156 || var->ubchginfos[*ubchginfopos].redundant
    4157 == (var->ubchginfos[*ubchginfopos].oldbound == var->ubchginfos[*ubchginfopos].newbound)); /*lint !e777*/
    4158
    4159 if( *lbchginfopos >= 0 && *lbchginfopos < var->nlbchginfos && var->lbchginfos[*lbchginfopos].redundant )
    4160 {
    4161 assert(SCIPvarGetLbGlobal(var) == var->lbchginfos[*lbchginfopos].oldbound); /*lint !e777*/
    4162 *lbchginfopos = -1;
    4163 }
    4164 if( *ubchginfopos >= 0 && *ubchginfopos < var->nubchginfos && var->ubchginfos[*ubchginfopos].redundant )
    4165 {
    4166 assert(SCIPvarGetUbGlobal(var) == var->ubchginfos[*ubchginfopos].oldbound); /*lint !e777*/
    4167 *ubchginfopos = -1;
    4168 }
    4169}
    4170
    4171/** adds variable's bound to conflict candidate queue */
    4173 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    4174 BMS_BLKMEM* blkmem, /**< block memory */
    4175 SCIP_SET* set, /**< global SCIP settings */
    4176 SCIP_STAT* stat, /**< dynamic problem statistics */
    4177 SCIP_VAR* var, /**< problem variable */
    4178 SCIP_BOUNDTYPE boundtype, /**< type of bound that was changed: lower or upper bound */
    4179 SCIP_BDCHGIDX* bdchgidx /**< bound change index (time stamp of bound change), or NULL for current time */
    4180 )
    4181{
    4182 SCIP_BDCHGINFO* bdchginfo;
    4183
    4184 assert(conflict != NULL);
    4185 assert(stat != NULL);
    4186 assert(var != NULL);
    4187
    4188 /* convert bound to active problem variable */
    4189 SCIP_CALL( convertToActiveVar(&var, set, &boundtype, NULL) );
    4190
    4191 /* we can ignore fixed variables */
    4193 return SCIP_OKAY;
    4194
    4195 /* if the variable is multi-aggregated, add the bounds of all aggregation variables */
    4197 {
    4198 SCIP_VAR** vars;
    4200 int nvars;
    4201 int i;
    4202
    4203 vars = SCIPvarGetMultaggrVars(var);
    4205 nvars = SCIPvarGetMultaggrNVars(var);
    4206 for( i = 0; i < nvars; ++i )
    4207 {
    4208 SCIP_CALL( SCIPconflictAddBound(conflict, blkmem, set, stat, vars[i],
    4209 (scalars[i] < 0.0 ? SCIPboundtypeOpposite(boundtype) : boundtype), bdchgidx) );
    4210 }
    4211
    4212 return SCIP_OKAY;
    4213 }
    4214 assert(SCIPvarIsActive(var));
    4215
    4216 /* get bound change information */
    4217 bdchginfo = SCIPvarGetBdchgInfo(var, boundtype, bdchgidx, FALSE);
    4218
    4219 /* if bound of variable was not changed (this means it is still the global bound), we can ignore the conflicting
    4220 * bound
    4221 */
    4222 if( bdchginfo == NULL )
    4223 return SCIP_OKAY;
    4224
    4225 assert(SCIPbdchgidxIsEarlier(SCIPbdchginfoGetIdx(bdchginfo), bdchgidx));
    4226
    4227 SCIP_CALL( conflictAddBound(conflict, blkmem, set, stat, var, boundtype, bdchginfo, SCIPbdchginfoGetNewbound(bdchginfo)) );
    4228
    4229 return SCIP_OKAY;
    4230}
    4231
    4232/** adds variable's bound to conflict candidate queue */
    4234 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    4235 BMS_BLKMEM* blkmem, /**< block memory */
    4236 SCIP_SET* set, /**< global SCIP settings */
    4237 SCIP_STAT* stat, /**< dynamic problem statistics */
    4238 SCIP_VAR* var, /**< problem variable */
    4239 SCIP_BOUNDTYPE boundtype, /**< type of bound that was changed: lower or upper bound */
    4240 SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
    4241 SCIP_Real relaxedbd /**< the relaxed bound */
    4242 )
    4243{
    4244 SCIP_BDCHGINFO* bdchginfo;
    4245 int nbdchgs;
    4246
    4247 assert(conflict != NULL);
    4248 assert(stat != NULL);
    4249 assert(var != NULL);
    4250
    4251 if( !SCIPvarIsActive(var) )
    4252 {
    4253 /* convert bound to active problem variable */
    4254 SCIP_CALL( convertToActiveVar(&var, set, &boundtype, &relaxedbd) );
    4255
    4256 /* we can ignore fixed variables */
    4258 return SCIP_OKAY;
    4259
    4260 /* if the variable is multi-aggregated, add the bounds of all aggregation variables */
    4262 {
    4263 SCIPsetDebugMsg(set, "ignoring relaxed bound information since variable <%s> is multi-aggregated active\n", SCIPvarGetName(var));
    4264
    4265 SCIP_CALL( SCIPconflictAddBound(conflict, blkmem, set, stat, var, boundtype, bdchgidx) );
    4266
    4267 return SCIP_OKAY;
    4268 }
    4269 }
    4270 assert(SCIPvarIsActive(var));
    4271
    4272 /* get bound change information */
    4273 bdchginfo = SCIPvarGetBdchgInfo(var, boundtype, bdchgidx, FALSE);
    4274
    4275 /* if bound of variable was not changed (this means it is still the global bound), we can ignore the conflicting
    4276 * bound
    4277 */
    4278 if( bdchginfo == NULL )
    4279 return SCIP_OKAY;
    4280
    4281 /* check that the bound change info is not a temporary one */
    4282 assert(SCIPbdchgidxGetPos(&bdchginfo->bdchgidx) >= 0);
    4283
    4284 /* get the position of the bound change information within the bound change array of the variable */
    4285 nbdchgs = (int) bdchginfo->pos;
    4286 assert(nbdchgs >= 0);
    4287
    4288 /* if the relaxed bound should be ignored, set the relaxed bound to the bound given by the bdchgidx; that ensures
    4289 * that the loop(s) below will be skipped
    4290 */
    4291 if( set->conf_ignorerelaxedbd )
    4292 relaxedbd = SCIPbdchginfoGetNewbound(bdchginfo);
    4293
    4294 /* search for the bound change information which includes the relaxed bound */
    4295 if( boundtype == SCIP_BOUNDTYPE_LOWER )
    4296 {
    4297 SCIP_Real newbound;
    4298
    4299 /* adjust relaxed lower bound w.r.t. variable type */
    4300 SCIPvarAdjustLb(var, set, &relaxedbd);
    4301
    4302 /* due to numericis we compare the relaxed lower bound to the one present at the particular time point and take
    4303 * the better one
    4304 */
    4305 newbound = SCIPbdchginfoGetNewbound(bdchginfo);
    4306 relaxedbd = MIN(relaxedbd, newbound);
    4307
    4308 /* check if relaxed lower bound is smaller or equal to global lower bound; if so we can ignore the conflicting
    4309 * bound
    4310 */
    4311 if( SCIPsetIsLE(set, relaxedbd, SCIPvarGetLbGlobal(var)) )
    4312 return SCIP_OKAY;
    4313
    4314 while( nbdchgs > 0 )
    4315 {
    4316 assert(SCIPsetIsLE(set, relaxedbd, SCIPbdchginfoGetNewbound(bdchginfo)));
    4317
    4318 /* check if the old lower bound is greater than or equal to relaxed lower bound; if not we found the bound
    4319 * change info which we need to report
    4320 */
    4321 if( SCIPsetIsGT(set, relaxedbd, SCIPbdchginfoGetOldbound(bdchginfo)) )
    4322 break;
    4323
    4324 bdchginfo = SCIPvarGetBdchgInfoLb(var, nbdchgs-1);
    4325
    4326 SCIPsetDebugMsg(set, "lower bound change %d oldbd=%.15g, newbd=%.15g, depth=%d, pos=%d, redundant=%u\n",
    4327 nbdchgs, SCIPbdchginfoGetOldbound(bdchginfo), SCIPbdchginfoGetNewbound(bdchginfo),
    4328 SCIPbdchginfoGetDepth(bdchginfo), SCIPbdchginfoGetPos(bdchginfo),
    4329 SCIPbdchginfoIsRedundant(bdchginfo));
    4330
    4331 /* if bound change is redundant (this means it now a global bound), we can ignore the conflicting bound */
    4332 if( SCIPbdchginfoIsRedundant(bdchginfo) )
    4333 return SCIP_OKAY;
    4334
    4335 nbdchgs--;
    4336 }
    4337 assert(SCIPsetIsGT(set, relaxedbd, SCIPbdchginfoGetOldbound(bdchginfo)));
    4338 }
    4339 else
    4340 {
    4341 SCIP_Real newbound;
    4342
    4343 assert(boundtype == SCIP_BOUNDTYPE_UPPER);
    4344
    4345 /* adjust relaxed upper bound w.r.t. variable type */
    4346 SCIPvarAdjustUb(var, set, &relaxedbd);
    4347
    4348 /* due to numericis we compare the relaxed upper bound to the one present at the particular time point and take
    4349 * the better one
    4350 */
    4351 newbound = SCIPbdchginfoGetNewbound(bdchginfo);
    4352 relaxedbd = MAX(relaxedbd, newbound);
    4353
    4354 /* check if relaxed upper bound is greater or equal to global upper bound; if so we can ignore the conflicting
    4355 * bound
    4356 */
    4357 if( SCIPsetIsGE(set, relaxedbd, SCIPvarGetUbGlobal(var)) )
    4358 return SCIP_OKAY;
    4359
    4360 while( nbdchgs > 0 )
    4361 {
    4362 assert(SCIPsetIsGE(set, relaxedbd, SCIPbdchginfoGetNewbound(bdchginfo)));
    4363
    4364 /* check if the old upper bound is smaller than or equal to the relaxed upper bound; if not we found the
    4365 * bound change info which we need to report
    4366 */
    4367 if( SCIPsetIsLT(set, relaxedbd, SCIPbdchginfoGetOldbound(bdchginfo)) )
    4368 break;
    4369
    4370 bdchginfo = SCIPvarGetBdchgInfoUb(var, nbdchgs-1);
    4371
    4372 SCIPsetDebugMsg(set, "upper bound change %d oldbd=%.15g, newbd=%.15g, depth=%d, pos=%d, redundant=%u\n",
    4373 nbdchgs, SCIPbdchginfoGetOldbound(bdchginfo), SCIPbdchginfoGetNewbound(bdchginfo),
    4374 SCIPbdchginfoGetDepth(bdchginfo), SCIPbdchginfoGetPos(bdchginfo),
    4375 SCIPbdchginfoIsRedundant(bdchginfo));
    4376
    4377 /* if bound change is redundant (this means it now a global bound), we can ignore the conflicting bound */
    4378 if( SCIPbdchginfoIsRedundant(bdchginfo) )
    4379 return SCIP_OKAY;
    4380
    4381 nbdchgs--;
    4382 }
    4383 assert(SCIPsetIsLT(set, relaxedbd, SCIPbdchginfoGetOldbound(bdchginfo)));
    4384 }
    4385
    4386 assert(SCIPbdchgidxIsEarlier(SCIPbdchginfoGetIdx(bdchginfo), bdchgidx));
    4387
    4388 /* put bound change information into priority queue */
    4389 SCIP_CALL( conflictAddBound(conflict, blkmem, set, stat, var, boundtype, bdchginfo, relaxedbd) );
    4390
    4391 return SCIP_OKAY;
    4392}
    4393
    4394/** checks if the given variable is already part of the current conflict set or queued for resolving with the same or
    4395 * even stronger bound
    4396 */
    4398 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    4399 SCIP_VAR* var, /**< problem variable */
    4400 SCIP_SET* set, /**< global SCIP settings */
    4401 SCIP_BOUNDTYPE boundtype, /**< type of bound for which the score should be increased */
    4402 SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
    4403 SCIP_Bool* used /**< pointer to store if the variable is already used */
    4404 )
    4405{
    4406 SCIP_Real newbound;
    4407
    4408 /* convert bound to active problem variable */
    4409 SCIP_CALL( convertToActiveVar(&var, set, &boundtype, NULL) );
    4410
    4412 *used = FALSE;
    4413 else
    4414 {
    4415 assert(SCIPvarIsActive(var));
    4416 assert(var != NULL);
    4417
    4418 switch( boundtype )
    4419 {
    4421
    4422 newbound = SCIPgetVarLbAtIndex(set->scip, var, bdchgidx, FALSE);
    4423
    4424 if( var->conflictlbcount == conflict->count && var->conflictlb >= newbound )
    4425 {
    4426 SCIPsetDebugMsg(set, "already queued bound change <%s> >= %g\n", SCIPvarGetName(var), newbound);
    4427 *used = TRUE;
    4428 }
    4429 else
    4430 *used = FALSE;
    4431 break;
    4433
    4434 newbound = SCIPgetVarUbAtIndex(set->scip, var, bdchgidx, FALSE);
    4435
    4436 if( var->conflictubcount == conflict->count && var->conflictub <= newbound )
    4437 {
    4438 SCIPsetDebugMsg(set, "already queued bound change <%s> <= %g\n", SCIPvarGetName(var), newbound);
    4439 *used = TRUE;
    4440 }
    4441 else
    4442 *used = FALSE;
    4443 break;
    4444 default:
    4445 SCIPerrorMessage("invalid bound type %d\n", boundtype);
    4446 SCIPABORT();
    4447 *used = FALSE; /*lint !e527*/
    4448 }
    4449 }
    4450
    4451 return SCIP_OKAY;
    4452}
    4453
    4454/** inserts variable's new bounds into bound change arrays */
    4455static
    4457 SCIP_SET* set, /**< global SCIP settings */
    4458 SCIP_VAR* var, /**< variable to change the LP bounds for */
    4459 SCIP_Real newlb, /**< new lower bound */
    4460 SCIP_Real newub, /**< new upper bound */
    4461 SCIP_LPBDCHGS* oldlpbdchgs, /**< old LP bound changes used for reset the LP bound change */
    4462 SCIP_LPBDCHGS* relaxedlpbdchgs, /**< relaxed LP bound changes used for reset the LP bound change */
    4463 SCIP_LPI* lpi /**< pointer to LPi to access infinity of LP solver; necessary to set correct value */
    4464 )
    4465{
    4466 assert(newlb <= newub);
    4467 assert(oldlpbdchgs != NULL);
    4468 assert(relaxedlpbdchgs != NULL);
    4469
    4471 {
    4472 SCIP_COL* col;
    4473 int idx;
    4474 int c;
    4475
    4476 col = SCIPvarGetCol(var);
    4477 c = SCIPcolGetLPPos(col);
    4478
    4479 if( c >= 0 )
    4480 {
    4481 /* store old bound change for resetting the LP later */
    4482 if( !oldlpbdchgs->usedcols[c] )
    4483 {
    4484 idx = oldlpbdchgs->nbdchgs;
    4485 oldlpbdchgs->usedcols[c] = TRUE;
    4486 oldlpbdchgs->bdchgcolinds[c] = idx;
    4487 oldlpbdchgs->nbdchgs++;
    4488
    4489 oldlpbdchgs->bdchginds[idx] = c;
    4490 oldlpbdchgs->bdchglbs[idx] = SCIPvarGetLbLP(var, set);
    4491 oldlpbdchgs->bdchgubs[idx] = SCIPvarGetUbLP(var, set);
    4492 }
    4493 assert(oldlpbdchgs->bdchginds[oldlpbdchgs->bdchgcolinds[c]] == c);
    4494 assert((SCIPlpiIsInfinity(lpi, -oldlpbdchgs->bdchglbs[oldlpbdchgs->bdchgcolinds[c]]) && SCIPsetIsInfinity(set, -SCIPvarGetLbLP(var, set))) ||
    4495 SCIPsetIsEQ(set, oldlpbdchgs->bdchglbs[oldlpbdchgs->bdchgcolinds[c]], SCIPvarGetLbLP(var, set)));
    4496 assert((SCIPlpiIsInfinity(lpi, oldlpbdchgs->bdchgubs[oldlpbdchgs->bdchgcolinds[c]]) && SCIPsetIsInfinity(set, SCIPvarGetUbLP(var, set))) ||
    4497 SCIPsetIsEQ(set, oldlpbdchgs->bdchgubs[oldlpbdchgs->bdchgcolinds[c]], SCIPvarGetUbLP(var, set)));
    4498
    4499 /* store bound change for conflict analysis */
    4500 if( !relaxedlpbdchgs->usedcols[c] )
    4501 {
    4502 idx = relaxedlpbdchgs->nbdchgs;
    4503 relaxedlpbdchgs->usedcols[c] = TRUE;
    4504 relaxedlpbdchgs->bdchgcolinds[c] = idx;
    4505 relaxedlpbdchgs->nbdchgs++;
    4506
    4507 /* remember the positive for later further bound widenings */
    4508 relaxedlpbdchgs->bdchginds[idx] = c;
    4509 }
    4510 else
    4511 {
    4512 idx = relaxedlpbdchgs->bdchgcolinds[c];
    4513 assert(relaxedlpbdchgs->bdchginds[idx] == c);
    4514
    4515 /* the new bound should be the same or more relaxed */
    4516 assert(relaxedlpbdchgs->bdchglbs[idx] >= newlb ||
    4517 (SCIPlpiIsInfinity(lpi, -relaxedlpbdchgs->bdchglbs[idx]) && SCIPsetIsInfinity(set, -newlb)));
    4518 assert(relaxedlpbdchgs->bdchgubs[idx] <= newub ||
    4519 (SCIPlpiIsInfinity(lpi, relaxedlpbdchgs->bdchgubs[idx]) && SCIPsetIsInfinity(set, newub)));
    4520 }
    4521
    4522 /* set the new bounds for the LP with the correct infinity value */
    4523 relaxedlpbdchgs->bdchglbs[idx] = SCIPsetIsInfinity(set, -newlb) ? -SCIPlpiInfinity(lpi) : newlb;
    4524 relaxedlpbdchgs->bdchgubs[idx] = SCIPsetIsInfinity(set, newub) ? SCIPlpiInfinity(lpi) : newub;
    4525 if( SCIPsetIsInfinity(set, -oldlpbdchgs->bdchglbs[idx]) )
    4526 oldlpbdchgs->bdchglbs[idx] = -SCIPlpiInfinity(lpi);
    4527 if( SCIPsetIsInfinity(set, oldlpbdchgs->bdchgubs[idx]) )
    4528 oldlpbdchgs->bdchgubs[idx] = SCIPlpiInfinity(lpi);
    4529 }
    4530 }
    4531
    4532 return SCIP_OKAY;
    4533}
    4534
    4535/** adds variable to candidate list, if the current best bound corresponding to the proof coefficient is local;
    4536 * returns the array position in the candidate list, where the new candidate was inserted, or -1 if the
    4537 * variable can relaxed to global bounds immediately without increasing the proof's activity;
    4538 * the candidates are sorted with respect to the following two criteria:
    4539 * - prefer bound changes that have been applied deeper in the tree, to get a more global conflict
    4540 * - prefer variables with small Farkas coefficient to get rid of as many bound changes as possible
    4541 */
    4542static
    4544 SCIP_SET* set, /**< global SCIP settings */
    4545 int currentdepth, /**< current depth in the tree */
    4546 SCIP_VAR* var, /**< variable to add to candidate array */
    4547 int lbchginfopos, /**< positions of currently active lower bound change information in variable's array */
    4548 int ubchginfopos, /**< positions of currently active upper bound change information in variable's array */
    4549 SCIP_Real proofcoef, /**< coefficient of variable in infeasibility/bound proof */
    4550 SCIP_Real prooflhs, /**< left hand side of infeasibility/bound proof */
    4551 SCIP_Real proofact, /**< activity of infeasibility/bound proof row */
    4552 SCIP_VAR*** cands, /**< pointer to candidate array for undoing bound changes */
    4553 SCIP_Real** candscores, /**< pointer to candidate score array for undoing bound changes */
    4554 SCIP_Real** newbounds, /**< pointer to candidate new bounds array for undoing bound changes */
    4555 SCIP_Real** proofactdeltas, /**< pointer to proof activity increase array for undoing bound changes */
    4556 int* candssize, /**< pointer to size of cands arrays */
    4557 int* ncands, /**< pointer to count number of candidates in bound change list */
    4558 int firstcand, /**< position of first unprocessed bound change candidate */
    4559 SCIP_Bool keepsorted /**< insert the candidate in sorted order; if FALSE the caller must sort afterwards */
    4560 )
    4561{
    4562 SCIP_Real oldbound;
    4563 SCIP_Real newbound;
    4564 SCIP_Real QUAD(proofactdelta);
    4565 SCIP_Real score;
    4566 int depth;
    4567 int i;
    4568 SCIP_Bool resolvable;
    4569
    4570 assert(set != NULL);
    4571 assert(var != NULL);
    4572 assert(-1 <= lbchginfopos && lbchginfopos <= var->nlbchginfos);
    4573 assert(-1 <= ubchginfopos && ubchginfopos <= var->nubchginfos);
    4574 assert(!SCIPsetIsZero(set, proofcoef));
    4575 assert(SCIPsetIsGT(set, prooflhs, proofact));
    4576 assert(cands != NULL);
    4577 assert(candscores != NULL);
    4578 assert(newbounds != NULL);
    4579 assert(proofactdeltas != NULL);
    4580 assert(candssize != NULL);
    4581 assert(ncands != NULL);
    4582 assert(*ncands <= *candssize);
    4583 assert(0 <= firstcand && firstcand <= *ncands);
    4584
    4585 /* in the infeasibility or dual bound proof, the variable's bound is chosen to maximize the proof's activity */
    4586 if( proofcoef > 0.0 )
    4587 {
    4588 assert(ubchginfopos >= 0); /* otherwise, undoBdchgsProof() should already have relaxed the local bound */
    4589
    4590 /* calculate the difference of current bound to the previous bound the variable was set to */
    4591 if( ubchginfopos == var->nubchginfos )
    4592 {
    4593 /* current bound is the strong branching or diving bound */
    4594 oldbound = SCIPvarGetUbLP(var, set);
    4595 newbound = SCIPvarGetUbLocal(var);
    4596 depth = currentdepth+1;
    4597 resolvable = FALSE;
    4598 }
    4599 else
    4600 {
    4601 /* current bound is the result of a local bound change */
    4602 resolvable = bdchginfoIsResolvable(&var->ubchginfos[ubchginfopos]);
    4603 depth = var->ubchginfos[ubchginfopos].bdchgidx.depth;
    4604 oldbound = var->ubchginfos[ubchginfopos].newbound;
    4605 newbound = var->ubchginfos[ubchginfopos].oldbound;
    4606 }
    4607 }
    4608 else
    4609 {
    4610 assert(lbchginfopos >= 0); /* otherwise, undoBdchgsProof() should already have relaxed the local bound */
    4611
    4612 /* calculate the difference of current bound to the previous bound the variable was set to */
    4613 if( lbchginfopos == var->nlbchginfos )
    4614 {
    4615 /* current bound is the strong branching or diving bound */
    4616 oldbound = SCIPvarGetLbLP(var, set);
    4617 newbound = SCIPvarGetLbLocal(var);
    4618 depth = currentdepth+1;
    4619 resolvable = FALSE;
    4620 }
    4621 else
    4622 {
    4623 /* current bound is the result of a local bound change */
    4624 resolvable = bdchginfoIsResolvable(&var->lbchginfos[lbchginfopos]);
    4625 depth = var->lbchginfos[lbchginfopos].bdchgidx.depth;
    4626 oldbound = var->lbchginfos[lbchginfopos].newbound;
    4627 newbound = var->lbchginfos[lbchginfopos].oldbound;
    4628 }
    4629 }
    4630
    4631 /* calculate the increase in the proof's activity */
    4632 SCIPquadprecSumDD(proofactdelta, newbound, -oldbound);
    4633 SCIPquadprecProdQD(proofactdelta, proofactdelta, proofcoef);
    4634 assert(QUAD_TO_DBL(proofactdelta) > 0.0);
    4635
    4636 /* calculate score for undoing the bound change */
    4637 score = calcBdchgScore(prooflhs, proofact, QUAD_TO_DBL(proofactdelta), proofcoef, depth, currentdepth, var, set);
    4638
    4639 if( !resolvable )
    4640 {
    4641 score += 10.0;
    4642 if( !SCIPvarIsBinary(var) )
    4643 score += 10.0;
    4644 }
    4645
    4646 /* get enough memory to store new candidate */
    4647 SCIP_CALL( ensureCandsSize(set, cands, candscores, newbounds, proofactdeltas, candssize, (*ncands)+1) );
    4648 assert(*cands != NULL);
    4649 assert(*candscores != NULL);
    4650 assert(*newbounds != NULL);
    4651 assert(*proofactdeltas != NULL);
    4652
    4653 SCIPsetDebugMsg(set, " -> local <%s> %s %g, relax <%s> %s %g, proofcoef=%g, dpt=%d, resolve=%u, delta=%g, score=%g\n",
    4654 SCIPvarGetName(var), proofcoef > 0.0 ? "<=" : ">=", oldbound,
    4655 SCIPvarGetName(var), proofcoef > 0.0 ? "<=" : ">=", newbound,
    4656 proofcoef, depth, resolvable, QUAD_TO_DBL(proofactdelta), score);
    4657
    4658 if( keepsorted )
    4659 {
    4660 /* insert variable in candidate list without touching the already processed candidates */
    4661 for( i = *ncands; i > firstcand && score > (*candscores)[i-1]; --i )
    4662 {
    4663 (*cands)[i] = (*cands)[i-1];
    4664 (*candscores)[i] = (*candscores)[i-1];
    4665 (*newbounds)[i] = (*newbounds)[i-1];
    4666 (*proofactdeltas)[i] = (*proofactdeltas)[i-1];
    4667 }
    4668 }
    4669 else
    4670 {
    4671 /* append to back */
    4672 i = *ncands;
    4673 }
    4674 (*cands)[i] = var;
    4675 (*candscores)[i] = score;
    4676 (*newbounds)[i] = newbound;
    4677 (*proofactdeltas)[i] = QUAD_TO_DBL(proofactdelta);
    4678 (*ncands)++;
    4679
    4680 return SCIP_OKAY;
    4681}
    4682
    4683/** undoes bound changes on variables, still leaving the given infeasibility proof valid */
    4685 SCIP_SET* set, /**< global SCIP settings */
    4686 SCIP_PROB* prob, /**< problem data */
    4687 int currentdepth, /**< current depth in the tree */
    4688 SCIP_Real* proofcoefs, /**< coefficients in infeasibility proof */
    4689 SCIP_Real prooflhs, /**< left hand side of proof */
    4690 SCIP_Real* proofact, /**< current activity of proof */
    4691 SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
    4692 SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
    4693 int* lbchginfoposs, /**< positions of currently active lower bound change information in variables' arrays */
    4694 int* ubchginfoposs, /**< positions of currently active upper bound change information in variables' arrays */
    4695 SCIP_LPBDCHGS* oldlpbdchgs, /**< old LP bound changes used for reset the LP bound change, or NULL */
    4696 SCIP_LPBDCHGS* relaxedlpbdchgs, /**< relaxed LP bound changes used for reset the LP bound change, or NULL */
    4697 SCIP_Bool* resolve, /**< pointer to store whether the changed LP should be resolved again, or NULL */
    4698 SCIP_LPI* lpi /**< pointer to LPi to access infinity of LP solver; necessary to set correct values */
    4699 )
    4700{
    4701 SCIP_VAR** vars;
    4702 SCIP_VAR** cands;
    4703 SCIP_Real* candscores;
    4704 SCIP_Real* newbounds;
    4705 SCIP_Real* proofactdeltas;
    4706 int nvars;
    4707 int ncands;
    4708 int nmaincands;
    4709 int candssize;
    4710 int v;
    4711 int i;
    4712 int j;
    4713 int k;
    4714
    4715 assert(prob != NULL);
    4716 assert(proofcoefs != NULL);
    4717 assert(SCIPsetIsFeasGT(set, prooflhs, (*proofact)));
    4718 assert(curvarlbs != NULL);
    4719 assert(curvarubs != NULL);
    4720 assert(lbchginfoposs != NULL);
    4721 assert(ubchginfoposs != NULL);
    4722
    4723 if( resolve != NULL )
    4724 *resolve = FALSE;
    4725
    4726 vars = prob->vars;
    4727 nvars = prob->nvars;
    4728 assert(nvars == 0 || vars != NULL);
    4729
    4730 /* calculate the order in which the bound changes are tried to be undone, and relax all bounds if this doesn't
    4731 * increase the proof's activity
    4732 */
    4733 SCIP_CALL( SCIPsetAllocBufferArray(set, &cands, nvars) );
    4734 SCIP_CALL( SCIPsetAllocBufferArray(set, &candscores, nvars) );
    4735 SCIP_CALL( SCIPsetAllocBufferArray(set, &newbounds, nvars) );
    4736 SCIP_CALL( SCIPsetAllocBufferArray(set, &proofactdeltas, nvars) );
    4737 ncands = 0;
    4738 candssize = nvars;
    4739 for( v = 0; v < nvars; ++v )
    4740 {
    4741 SCIP_VAR* var;
    4742 SCIP_Bool relaxed;
    4743
    4744 var = vars[v];
    4745
    4746 /* after changing the global bound of a variable, the bdchginfos that are now redundant are replaced with
    4747 * oldbound = newbound = global bound; if the current bdchginfo is of such kind, the bound is equal to the
    4748 * global bound and we can ignore it
    4749 */
    4750 skipRedundantBdchginfos(var, &lbchginfoposs[v], &ubchginfoposs[v]);
    4751
    4752 /* ignore variables already relaxed to global bounds */
    4753 if( (lbchginfoposs[v] == -1 && ubchginfoposs[v] == -1) )
    4754 {
    4755 proofcoefs[v] = 0.0;
    4756 continue;
    4757 }
    4758
    4759 /* relax bounds that are not used in the proof to the global bounds */
    4760 relaxed = FALSE;
    4761 if( !SCIPsetIsNegative(set, proofcoefs[v]) )
    4762 {
    4763 /* the lower bound is not used */
    4764 if( lbchginfoposs[v] >= 0 )
    4765 {
    4766 SCIPsetDebugMsg(set, " -> relaxing variable <%s>[%g,%g] to [%g,%g]: proofcoef=%g, %g <= %g\n",
    4767 SCIPvarGetName(var), curvarlbs[v], curvarubs[v], SCIPvarGetLbGlobal(var), curvarubs[v],
    4768 proofcoefs[v], prooflhs, (*proofact));
    4769 curvarlbs[v] = SCIPvarGetLbGlobal(var);
    4770 lbchginfoposs[v] = -1;
    4771 relaxed = TRUE;
    4772 }
    4773 }
    4774 if( !SCIPsetIsPositive(set, proofcoefs[v]) )
    4775 {
    4776 /* the upper bound is not used */
    4777 if( ubchginfoposs[v] >= 0 )
    4778 {
    4779 SCIPsetDebugMsg(set, " -> relaxing variable <%s>[%g,%g] to [%g,%g]: proofcoef=%g, %g <= %g\n",
    4780 SCIPvarGetName(var), curvarlbs[v], curvarubs[v], curvarlbs[v], SCIPvarGetUbGlobal(var),
    4781 proofcoefs[v], prooflhs, (*proofact));
    4782 curvarubs[v] = SCIPvarGetUbGlobal(var);
    4783 ubchginfoposs[v] = -1;
    4784 relaxed = TRUE;
    4785 }
    4786 }
    4787 if( relaxed && oldlpbdchgs != NULL )
    4788 {
    4789 SCIP_CALL( addBdchg(set, var, curvarlbs[v], curvarubs[v], oldlpbdchgs, relaxedlpbdchgs, lpi) );
    4790 }
    4791
    4792 /* add bound to candidate list */
    4793 if( lbchginfoposs[v] >= 0 || ubchginfoposs[v] >= 0 )
    4794 {
    4795 SCIP_CALL( addCand(set, currentdepth, var, lbchginfoposs[v], ubchginfoposs[v], proofcoefs[v],
    4796 prooflhs, (*proofact), &cands, &candscores, &newbounds, &proofactdeltas, &candssize, &ncands, 0, FALSE) );
    4797 }
    4798 /* we can set the proof coefficient to zero, because the variable is not needed */
    4799 else
    4800 proofcoefs[v] = 0.0;
    4801 }
    4802
    4803 /* sort candidates collected by first loop once for descending score */
    4804 SCIPsortDownRealRealRealPtr(candscores, newbounds, proofactdeltas, (void**)cands, ncands);
    4805
    4806 /* try to undo remaining local bound changes while still keeping the proof row violated:
    4807 * bound changes can be undone, if prooflhs > proofact + proofactdelta;
    4808 * afterwards, the current proof activity has to be updated;
    4809 * candidates produced during this pass are appended to the tail of the same arrays starting at
    4810 * nmaincands and kept sorted among themselves; higher score head is picked in each iteration
    4811 */
    4812 nmaincands = ncands;
    4813 j = 0;
    4814 k = nmaincands;
    4815 while( j < nmaincands || k < ncands )
    4816 {
    4817 if( j < nmaincands && (k >= ncands || candscores[j] >= candscores[k]) )
    4818 i = j++;
    4819 else
    4820 i = k++;
    4821
    4822 assert(proofactdeltas[i] > 0.0);
    4823 assert((lbchginfoposs[SCIPvarGetProbindex(cands[i])] >= 0) != (ubchginfoposs[SCIPvarGetProbindex(cands[i])] >= 0));
    4824
    4825 /* when relaxing a constraint we still need to stay infeasible; therefore we need to do the comparison in
    4826 * feasibility tolerance because if 'prooflhs' is (feas-))equal to 'proofact + proofactdeltas[i]' it would mean
    4827 * that there is no violation
    4828 */
    4829 if( SCIPsetIsFeasGT(set, prooflhs, (*proofact) + proofactdeltas[i]) )
    4830 {
    4831 v = SCIPvarGetProbindex(cands[i]);
    4832 assert(0 <= v && v < nvars);
    4833 assert((lbchginfoposs[v] >= 0) != (ubchginfoposs[v] >= 0));
    4834
    4835 SCIPsetDebugMsg(set, " -> relaxing variable <%s>[%g,%g] to [%g,%g]: proofcoef=%g, %g <= %g + %g\n",
    4836 SCIPvarGetName(cands[i]), curvarlbs[v], curvarubs[v],
    4837 proofcoefs[v] > 0.0 ? curvarlbs[v] : newbounds[i],
    4838 proofcoefs[v] > 0.0 ? newbounds[i] : curvarubs[v],
    4839 proofcoefs[v], prooflhs, (*proofact), proofactdeltas[i]);
    4840
    4841#ifndef NDEBUG
    4842 {
    4843 SCIP_Real QUAD(verifylb);
    4844 SCIP_Real QUAD(verifyub);
    4845
    4846 SCIPquadprecSumDD(verifylb, newbounds[i], -curvarlbs[v]);
    4847 SCIPquadprecProdQD(verifylb, verifylb, proofcoefs[v]);
    4848
    4849 SCIPquadprecSumDD(verifyub, newbounds[i], -curvarubs[v]);
    4850 SCIPquadprecProdQD(verifyub, verifyub, proofcoefs[v]);
    4851
    4852 assert((SCIPsetIsPositive(set, proofcoefs[v]) && SCIPsetIsGT(set, newbounds[i], curvarubs[v]))
    4853 || (SCIPsetIsNegative(set, proofcoefs[v]) && SCIPsetIsLT(set, newbounds[i], curvarlbs[v])));
    4854 assert((SCIPsetIsPositive(set, proofcoefs[v])
    4855 && SCIPsetIsEQ(set, proofactdeltas[i], QUAD_TO_DBL(verifyub)))
    4856 || (SCIPsetIsNegative(set, proofcoefs[v])
    4857 && SCIPsetIsEQ(set, proofactdeltas[i], QUAD_TO_DBL(verifylb))));
    4858 assert(!SCIPsetIsZero(set, proofcoefs[v]));
    4859 }
    4860#endif
    4861
    4862 if( proofcoefs[v] > 0.0 )
    4863 {
    4864 assert(ubchginfoposs[v] >= 0);
    4865 assert(lbchginfoposs[v] == -1);
    4866 curvarubs[v] = newbounds[i];
    4867 ubchginfoposs[v]--;
    4868 }
    4869 else
    4870 {
    4871 assert(lbchginfoposs[v] >= 0);
    4872 assert(ubchginfoposs[v] == -1);
    4873 curvarlbs[v] = newbounds[i];
    4874 lbchginfoposs[v]--;
    4875 }
    4876 if( oldlpbdchgs != NULL )
    4877 {
    4878 SCIP_CALL( addBdchg(set, cands[i], curvarlbs[v], curvarubs[v], oldlpbdchgs, relaxedlpbdchgs, lpi) );
    4879 }
    4880 (*proofact) += proofactdeltas[i];
    4881 if( resolve != NULL && SCIPvarIsInLP(cands[i]) )
    4882 *resolve = TRUE;
    4883
    4884 /* after changing the global bound of a variable, the bdchginfos that are now redundant are replaced with
    4885 * oldbound = newbound = global bound; if the current bdchginfo is of such kind, the bound is equal to the
    4886 * global bound and we can ignore it
    4887 */
    4888 skipRedundantBdchginfos(cands[i], &lbchginfoposs[v], &ubchginfoposs[v]);
    4889
    4890 /* insert the new local bound of the variable into the candidate list */
    4891 if( lbchginfoposs[v] >= 0 || ubchginfoposs[v] >= 0 )
    4892 {
    4893 SCIP_CALL( addCand(set, currentdepth, cands[i], lbchginfoposs[v], ubchginfoposs[v], proofcoefs[v],
    4894 prooflhs, (*proofact), &cands, &candscores, &newbounds, &proofactdeltas, &candssize, &ncands, k, TRUE) );
    4895 }
    4896 else
    4897 proofcoefs[v] = 0.0;
    4898 }
    4899 }
    4900
    4901 /* free the buffer for the sorted bound change candidates */
    4902 SCIPsetFreeBufferArray(set, &proofactdeltas);
    4903 SCIPsetFreeBufferArray(set, &newbounds);
    4904 SCIPsetFreeBufferArray(set, &candscores);
    4905 SCIPsetFreeBufferArray(set, &cands);
    4906
    4907 return SCIP_OKAY;
    4908}
    4909
    4910/** analyzes an infeasible LP and undoes additional bound changes while staying infeasible */
    4911static
    4913 SCIP_SET* set, /**< global SCIP settings */
    4914 SCIP_PROB* prob, /**< problem data */
    4915 SCIP_LP* lp, /**< LP data */
    4916 int currentdepth, /**< current depth in the tree */
    4917 SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
    4918 SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
    4919 int* lbchginfoposs, /**< positions of currently active lower bound change information in variables' arrays */
    4920 int* ubchginfoposs, /**< positions of currently active upper bound change information in variables' arrays */
    4921 SCIP_LPBDCHGS* oldlpbdchgs, /**< old LP bound changes used for reset the LP bound change, or NULL */
    4922 SCIP_LPBDCHGS* relaxedlpbdchgs, /**< relaxed LP bound changes used for reset the LP bound change, or NULL */
    4923 SCIP_Bool* valid, /**< pointer to store whether the unfixings are valid */
    4924 SCIP_Bool* resolve, /**< pointer to store whether the changed LP should be resolved again */
    4925 SCIP_Real* farkascoefs, /**< coefficients in the proof constraint */
    4926 SCIP_Real farkaslhs, /**< lhs of the proof constraint */
    4927 SCIP_Real* farkasactivity /**< maximal activity of the proof constraint */
    4928 )
    4929{
    4930 SCIP_LPI* lpi;
    4931
    4932 assert(prob != NULL);
    4933 assert(lp != NULL);
    4934 assert(lp->flushed);
    4935 assert(lp->solved);
    4936 assert(curvarlbs != NULL);
    4937 assert(curvarubs != NULL);
    4938 assert(lbchginfoposs != NULL);
    4939 assert(ubchginfoposs != NULL);
    4940 assert(valid != NULL);
    4941 assert(resolve != NULL);
    4942
    4943 SCIPsetDebugMsg(set, "undoing bound changes in infeasible LP: cutoff=%g\n", lp->cutoffbound);
    4944
    4945 *valid = FALSE;
    4946 *resolve = FALSE;
    4947
    4948 lpi = SCIPlpGetLPI(lp);
    4949
    4950 /* check, if the Farkas row is still violated (using current bounds and ignoring local rows) */
    4951 if( SCIPsetIsFeasGT(set, farkaslhs, *farkasactivity) )
    4952 {
    4953 /* undo bound changes while keeping the infeasibility proof valid */
    4954 SCIP_CALL( SCIPundoBdchgsProof(set, prob, currentdepth, farkascoefs, farkaslhs, farkasactivity, \
    4955 curvarlbs, curvarubs, lbchginfoposs, ubchginfoposs, oldlpbdchgs, relaxedlpbdchgs, resolve, lpi) );
    4956
    4957 *valid = TRUE;
    4958
    4959 /* resolving does not make sense: the old dual ray is still valid -> resolving will not change the solution */
    4960 *resolve = FALSE;
    4961 }
    4962
    4963 return SCIP_OKAY;
    4964}
    4965
    4966
    4967/*
    4968 * Conflict LP Bound Changes
    4969 */
    4970
    4971/** create conflict LP bound change data structure */
    4972static
    4974 SCIP_LPBDCHGS** lpbdchgs, /**< pointer to store the conflict LP bound change data structure */
    4975 SCIP_SET* set, /**< global SCIP settings */
    4976 int ncols /**< number of columns */
    4977 )
    4978{
    4979 SCIP_CALL( SCIPsetAllocBuffer(set, lpbdchgs) );
    4980
    4981 SCIP_CALL( SCIPsetAllocBufferArray(set, &(*lpbdchgs)->bdchginds, ncols) );
    4982 SCIP_CALL( SCIPsetAllocBufferArray(set, &(*lpbdchgs)->bdchglbs, ncols) );
    4983 SCIP_CALL( SCIPsetAllocBufferArray(set, &(*lpbdchgs)->bdchgubs, ncols) );
    4984 SCIP_CALL( SCIPsetAllocBufferArray(set, &(*lpbdchgs)->bdchgcolinds, ncols) );
    4985 SCIP_CALL( SCIPsetAllocBufferArray(set, &(*lpbdchgs)->usedcols, ncols) );
    4986 BMSclearMemoryArray((*lpbdchgs)->usedcols, ncols);
    4987
    4988 (*lpbdchgs)->nbdchgs = 0;
    4989
    4990 return SCIP_OKAY;
    4991}
    4992
    4993
    4994/*
    4995 * Propagation Conflict Analysis
    4996 */
    4997
    4998/** ensures, that side change arrays can store at least num entries */
    4999static
    5001 SCIP_SET* set, /**< global SCIP settings */
    5002 int** sidechginds, /**< pointer to side change index array */
    5003 SCIP_Real** sidechgoldlhss, /**< pointer to side change old left hand sides array */
    5004 SCIP_Real** sidechgoldrhss, /**< pointer to side change old right hand sides array */
    5005 SCIP_Real** sidechgnewlhss, /**< pointer to side change new left hand sides array */
    5006 SCIP_Real** sidechgnewrhss, /**< pointer to side change new right hand sides array */
    5007 int* sidechgssize, /**< pointer to size of side change arrays */
    5008 int num /**< minimal number of entries to be able to store in side change arrays */
    5009 )
    5010{
    5011 assert(sidechginds != NULL);
    5012 assert(sidechgoldlhss != NULL);
    5013 assert(sidechgoldrhss != NULL);
    5014 assert(sidechgnewlhss != NULL);
    5015 assert(sidechgnewrhss != NULL);
    5016 assert(sidechgssize != NULL);
    5017
    5018 if( num > *sidechgssize )
    5019 {
    5020 int newsize;
    5021
    5022 newsize = SCIPsetCalcMemGrowSize(set, num);
    5023 SCIP_CALL( SCIPsetReallocBufferArray(set, sidechginds, newsize) );
    5024 SCIP_CALL( SCIPsetReallocBufferArray(set, sidechgoldlhss, newsize) );
    5025 SCIP_CALL( SCIPsetReallocBufferArray(set, sidechgoldrhss, newsize) );
    5026 SCIP_CALL( SCIPsetReallocBufferArray(set, sidechgnewlhss, newsize) );
    5027 SCIP_CALL( SCIPsetReallocBufferArray(set, sidechgnewrhss, newsize) );
    5028 *sidechgssize = newsize;
    5029 }
    5030 assert(num <= *sidechgssize);
    5031
    5032 return SCIP_OKAY;
    5033}
    5034
    5035/** adds removal of row's side to side change arrays; finite sides are only replaced by near infinite sides, such
    5036 * that the row's sense in the LP solver is not changed
    5037 */
    5038static
    5040 SCIP_SET* set, /**< global SCIP settings */
    5041 SCIP_ROW* row, /**< LP row to change the sides for */
    5042 SCIP_Real lpiinfinity, /**< value treated as infinity in LP solver */
    5043 int** sidechginds, /**< pointer to side change index array */
    5044 SCIP_Real** sidechgoldlhss, /**< pointer to side change old left hand sides array */
    5045 SCIP_Real** sidechgoldrhss, /**< pointer to side change old right hand sides array */
    5046 SCIP_Real** sidechgnewlhss, /**< pointer to side change new left hand sides array */
    5047 SCIP_Real** sidechgnewrhss, /**< pointer to side change new right hand sides array */
    5048 int* sidechgssize, /**< pointer to size of side change arrays */
    5049 int* nsidechgs /**< pointer to number of used slots in side change arrays */
    5050 )
    5051{
    5052 SCIP_Real lhs;
    5053 SCIP_Real rhs;
    5054 SCIP_Real constant;
    5055
    5056 assert(sidechginds != NULL);
    5057 assert(sidechgoldlhss != NULL);
    5058 assert(sidechgoldrhss != NULL);
    5059 assert(sidechgnewlhss != NULL);
    5060 assert(sidechgnewrhss != NULL);
    5061 assert(sidechgssize != NULL);
    5062 assert(nsidechgs != NULL);
    5063
    5064 lhs = SCIProwGetLhs(row);
    5065 rhs = SCIProwGetRhs(row);
    5066 constant = SCIProwGetConstant(row);
    5067 assert(!SCIPsetIsInfinity(set, -lhs) || !SCIPsetIsInfinity(set, rhs));
    5068
    5069 /* get memory to store additional side change */
    5070 SCIP_CALL( ensureSidechgsSize(set, sidechginds, sidechgoldlhss, sidechgoldrhss, sidechgnewlhss, sidechgnewrhss, \
    5071 sidechgssize, (*nsidechgs)+1) );
    5072 assert(*nsidechgs < *sidechgssize);
    5073 assert(*sidechginds != NULL);
    5074 assert(*sidechgoldlhss != NULL);
    5075 assert(*sidechgoldrhss != NULL);
    5076 assert(*sidechgnewlhss != NULL);
    5077 assert(*sidechgnewrhss != NULL);
    5078
    5079 /* store side change */
    5080 (*sidechginds)[*nsidechgs] = SCIProwGetLPPos(row);
    5081 if( SCIPsetIsInfinity(set, -lhs) )
    5082 {
    5083 (*sidechgoldlhss)[*nsidechgs] = -lpiinfinity;
    5084 (*sidechgnewlhss)[*nsidechgs] = -lpiinfinity;
    5085 }
    5086 else
    5087 {
    5088 (*sidechgoldlhss)[*nsidechgs] = lhs - constant;
    5089 (*sidechgnewlhss)[*nsidechgs] = -lpiinfinity;
    5090 }
    5091 if( SCIPsetIsInfinity(set, rhs) )
    5092 {
    5093 (*sidechgoldrhss)[*nsidechgs] = lpiinfinity;
    5094 (*sidechgnewrhss)[*nsidechgs] = lpiinfinity;
    5095 }
    5096 else
    5097 {
    5098 (*sidechgoldrhss)[*nsidechgs] = rhs - constant;
    5099 (*sidechgnewrhss)[*nsidechgs] = lpiinfinity;
    5100 }
    5101 (*nsidechgs)++;
    5102
    5103 return SCIP_OKAY;
    5104}
    5105
    5106
    5107/*
    5108 * Infeasible LP Conflict Analysis
    5109 */
    5110
    5111/** reset conflict LP bound change data structure */
    5112static
    5114 SCIP_LPBDCHGS* lpbdchgs, /**< conflict LP bound change data structure */
    5115 int ncols /**< number of columns */
    5116 )
    5117{
    5118 assert(lpbdchgs != NULL);
    5119
    5120 BMSclearMemoryArray(lpbdchgs->usedcols, ncols);
    5121 lpbdchgs->nbdchgs = 0;
    5122}
    5123
    5124/** free conflict LP bound change data structure */
    5125static
    5127 SCIP_LPBDCHGS** lpbdchgs, /**< pointer to store the conflict LP bound change data structure */
    5128 SCIP_SET* set /**< global SCIP settings */
    5129 )
    5130{
    5131 SCIPsetFreeBufferArray(set, &(*lpbdchgs)->usedcols);
    5132 SCIPsetFreeBufferArray(set, &(*lpbdchgs)->bdchgcolinds);
    5133 SCIPsetFreeBufferArray(set, &(*lpbdchgs)->bdchgubs);
    5134 SCIPsetFreeBufferArray(set, &(*lpbdchgs)->bdchglbs);
    5135 SCIPsetFreeBufferArray(set, &(*lpbdchgs)->bdchginds);
    5136
    5137 SCIPsetFreeBuffer(set, lpbdchgs);
    5138}
    5139
    5140/** analyzes an LP exceeding the objective limit and undoes additional bound changes while staying beyond the
    5141 * objective limit
    5142 */
    5143static
    5145 SCIP_SET* set, /**< global SCIP settings */
    5146 SCIP_PROB* prob, /**< problem data */
    5147 SCIP_LP* lp, /**< LP data */
    5148 int currentdepth, /**< current depth in the tree */
    5149 SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
    5150 SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
    5151 int* lbchginfoposs, /**< positions of currently active lower bound change information in variables' arrays */
    5152 int* ubchginfoposs, /**< positions of currently active upper bound change information in variables' arrays */
    5153 SCIP_LPBDCHGS* oldlpbdchgs, /**< old LP bound changes used for reset the LP bound change, or NULL */
    5154 SCIP_LPBDCHGS* relaxedlpbdchgs, /**< relaxed LP bound changes used for reset the LP bound change, or NULL */
    5155 SCIP_Bool* valid, /**< pointer to store whether the unfixings are valid */
    5156 SCIP_Bool* resolve, /**< pointer to store whether the changed LP should be resolved again */
    5157 SCIP_Real* dualcoefs, /**< coefficients in the proof constraint */
    5158 SCIP_Real duallhs, /**< lhs of the proof constraint */
    5159 SCIP_Real* dualactivity /**< maximal activity of the proof constraint */
    5160 )
    5161{
    5162 SCIP_LPI* lpi;
    5163
    5164 assert(set != NULL);
    5165 assert(prob != NULL);
    5166 assert(lp != NULL);
    5167 assert(lp->flushed);
    5168 assert(lp->solved);
    5169 assert(curvarlbs != NULL);
    5170 assert(curvarubs != NULL);
    5171 assert(lbchginfoposs != NULL);
    5172 assert(ubchginfoposs != NULL);
    5173 assert(valid != NULL);
    5174 assert(resolve != NULL);
    5175
    5176 *valid = FALSE;
    5177 *resolve = FALSE;
    5178
    5179 SCIPsetDebugMsg(set, "undoing bound changes in LP exceeding cutoff: cutoff=%g\n", lp->cutoffbound);
    5180
    5181 /* get LP solver interface */
    5182 lpi = SCIPlpGetLPI(lp);
    5183
    5184 /* check, if the dual row is still violated (using current bounds and ignoring local rows) */
    5185 if( SCIPsetIsFeasGT(set, duallhs, *dualactivity) )
    5186 {
    5187 /* undo bound changes while keeping the infeasibility proof valid */
    5188 SCIP_CALL( SCIPundoBdchgsProof(set, prob, currentdepth, dualcoefs, duallhs, dualactivity, curvarlbs, curvarubs, \
    5189 lbchginfoposs, ubchginfoposs, oldlpbdchgs, relaxedlpbdchgs, resolve, lpi) );
    5190
    5191 *valid = TRUE;
    5192 }
    5193
    5194 return SCIP_OKAY;
    5195}
    5196
    5197/** try to find a subset of changed bounds leading to an infeasible LP
    5198 *
    5199 * 1. call undoBdchgsDualfarkas() or undoBdchgsDualsol()
    5200 * -> update lb/ubchginfoposs arrays
    5201 * -> store additional changes in bdchg and curvarlbs/ubs arrays
    5202 * -> apply additional changes to the LPI
    5203 * 2. (optional) if additional bound changes were undone:
    5204 * -> resolve LP
    5205 * -> goto 1.
    5206 * 3. redo all bound changes in the LPI to restore the LPI to its original state
    5207 * 4. analyze conflict
    5208 * -> put remaining changed bounds (see lb/ubchginfoposs arrays) into starting conflict set
    5209 */
    5211 SCIP_CONFLICT* conflict, /**< conflict data */
    5212 SCIP_SET* set, /**< global SCIP settings */
    5213 SCIP_STAT* stat, /**< problem statistics */
    5214 SCIP_PROB* origprob, /**< original problem */
    5215 SCIP_PROB* transprob, /**< transformed problem */
    5216 SCIP_TREE* tree, /**< branch and bound tree */
    5217 SCIP_REOPT* reopt, /**< reoptimization data */
    5218 SCIP_LP* lp, /**< LP data */
    5219 SCIP_LPI* lpi, /**< LPI data */
    5220 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    5221 BMS_BLKMEM* blkmem, /**< block memory */
    5222 SCIP_Real* proofcoefs, /**< coefficients in the proof constraint */
    5223 SCIP_Real* prooflhs, /**< lhs of the proof constraint */
    5224 SCIP_Real* proofactivity, /**< maximal activity of the proof constraint */
    5225 SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
    5226 SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
    5227 int* lbchginfoposs, /**< positions of currently active lower bound change information in variables' arrays */
    5228 int* ubchginfoposs, /**< positions of currently active upper bound change information in variables' arrays */
    5229 int* iterations, /**< pointer to store the total number of LP iterations used */
    5230 SCIP_Bool marklpunsolved, /**< whether LP should be marked unsolved after analysis (needed for strong branching) */
    5231 SCIP_Bool* dualproofsuccess, /**< pointer to store success result of dual proof analysis */
    5232 SCIP_Bool* valid /**< pointer to store whether the result is still a valid proof */
    5233 )
    5234{
    5235 SCIP_LPBDCHGS* oldlpbdchgs;
    5236 SCIP_LPBDCHGS* relaxedlpbdchgs;
    5237 SCIP_Bool solvelp;
    5238 SCIP_Bool resolve;
    5239 int ncols;
    5240
    5241 assert(set != NULL);
    5242
    5243 /* get number of columns in the LP */
    5244 ncols = SCIPlpGetNCols(lp);
    5245
    5246 /* get temporary memory for remembering bound changes on LPI columns */
    5247 SCIP_CALL( lpbdchgsCreate(&oldlpbdchgs, set, ncols) );
    5248 SCIP_CALL( lpbdchgsCreate(&relaxedlpbdchgs, set, ncols) );
    5249
    5250 /* undo as many bound changes as possible with the current LP solution */
    5251 resolve = FALSE;
    5252 if( (*valid) )
    5253 {
    5254 int currentdepth;
    5255 currentdepth = SCIPtreeGetCurrentDepth(tree);
    5256
    5257 if( SCIPlpiIsPrimalInfeasible(lpi) )
    5258 {
    5259 SCIP_CALL( undoBdchgsDualfarkas(set, transprob, lp, currentdepth, curvarlbs, curvarubs, lbchginfoposs, \
    5260 ubchginfoposs, oldlpbdchgs, relaxedlpbdchgs, valid, &resolve, proofcoefs, *prooflhs, proofactivity) );
    5261 }
    5262 else
    5263 {
    5264 assert(SCIPlpiIsDualFeasible(lpi) || SCIPlpiIsObjlimExc(lpi));
    5265 SCIP_CALL( undoBdchgsDualsol(set, transprob, lp, currentdepth, curvarlbs, curvarubs, lbchginfoposs, ubchginfoposs, \
    5266 oldlpbdchgs, relaxedlpbdchgs, valid, &resolve, proofcoefs, *prooflhs, proofactivity) );
    5267 }
    5268 }
    5269
    5270 /* check if we want to solve the LP */
    5271 assert(SCIPprobAllColsInLP(transprob, set, lp));
    5272 solvelp = (set->conf_maxlploops != 0 && set->conf_lpiterations != 0);
    5273
    5274 if( (*valid) && resolve && solvelp )
    5275 {
    5276 SCIP_RETCODE retcode;
    5277 SCIP_ROW** rows;
    5278 int* sidechginds;
    5279 SCIP_Real* sidechgoldlhss;
    5280 SCIP_Real* sidechgoldrhss;
    5281 SCIP_Real* sidechgnewlhss;
    5282 SCIP_Real* sidechgnewrhss;
    5283 SCIP_Real lpiinfinity;
    5284 SCIP_Bool globalinfeasible;
    5285 int maxlploops;
    5286 int lpiterations;
    5287 int sidechgssize;
    5288 int nsidechgs;
    5289 int nrows;
    5290 int nloops;
    5291 int r;
    5292
    5293 /* get infinity value of LP solver */
    5294 lpiinfinity = SCIPlpiInfinity(lpi);
    5295
    5296 /* temporarily disable objective limit and install an iteration limit */
    5297 maxlploops = (set->conf_maxlploops >= 0 ? set->conf_maxlploops : INT_MAX);
    5298 lpiterations = (set->conf_lpiterations >= 0 ? set->conf_lpiterations : INT_MAX);
    5299 SCIP_CALL( SCIPlpiSetRealpar(lpi, SCIP_LPPAR_OBJLIM, lpiinfinity) );
    5300 SCIP_CALL( SCIPlpiSetIntpar(lpi, SCIP_LPPAR_LPITLIM, lpiterations) );
    5301
    5302 /* get LP rows */
    5303 rows = SCIPlpGetRows(lp);
    5304 nrows = SCIPlpGetNRows(lp);
    5305 assert(nrows == 0 || rows != NULL);
    5306
    5307 /* get temporary memory for remembering side changes on LPI rows */
    5308 SCIP_CALL( SCIPsetAllocBufferArray(set, &sidechginds, nrows) );
    5309 SCIP_CALL( SCIPsetAllocBufferArray(set, &sidechgoldlhss, nrows) );
    5310 SCIP_CALL( SCIPsetAllocBufferArray(set, &sidechgoldrhss, nrows) );
    5311 SCIP_CALL( SCIPsetAllocBufferArray(set, &sidechgnewlhss, nrows) );
    5312 SCIP_CALL( SCIPsetAllocBufferArray(set, &sidechgnewrhss, nrows) );
    5313 sidechgssize = nrows;
    5314 nsidechgs = 0;
    5315
    5316 /* remove all local rows by setting their sides to infinity;
    5317 * finite sides are only changed to near infinity, such that the row's sense in the LP solver
    5318 * is not affected (e.g. CPLEX cannot handle free rows)
    5319 */
    5320 for( r = 0; r < nrows; ++r )
    5321 {
    5322 assert(SCIProwGetLPPos(rows[r]) == r);
    5323
    5324 if( SCIProwIsLocal(rows[r]) )
    5325 {
    5326 SCIPsetDebugMsg(set, " -> removing local row <%s> [%g,%g]\n",
    5327 SCIProwGetName(rows[r]), SCIProwGetLhs(rows[r]), SCIProwGetRhs(rows[r]));
    5328 SCIP_CALL( addSideRemoval(set, rows[r], lpiinfinity, &sidechginds, &sidechgoldlhss, &sidechgoldrhss,
    5329 &sidechgnewlhss, &sidechgnewrhss, &sidechgssize, &nsidechgs) );
    5330 }
    5331 }
    5332
    5333 /* apply changes of local rows to the LP solver */
    5334 if( nsidechgs > 0 )
    5335 {
    5336 SCIP_CALL( SCIPlpiChgSides(lpi, nsidechgs, sidechginds, sidechgnewlhss, sidechgnewrhss) );
    5337 }
    5338
    5339 /* undo as many additional bound changes as possible by resolving the LP */
    5340 assert((*valid));
    5341 assert(resolve);
    5342 nloops = 0;
    5343 globalinfeasible = FALSE;
    5344 while( (*valid) && resolve && nloops < maxlploops )
    5345 {
    5346 int iter;
    5347
    5348 assert(!globalinfeasible);
    5349
    5350 nloops++;
    5351 resolve = FALSE;
    5352
    5353 SCIPsetDebugMsg(set, "infeasible LP conflict analysis loop %d (changed col bounds: %d)\n", nloops, relaxedlpbdchgs->nbdchgs);
    5354
    5355 /* apply bound changes to the LP solver */
    5356 assert(relaxedlpbdchgs->nbdchgs >= 0);
    5357 if( relaxedlpbdchgs->nbdchgs > 0 )
    5358 {
    5359 SCIPsetDebugMsg(set, " -> applying %d bound changes to the LP solver\n", relaxedlpbdchgs->nbdchgs);
    5360 SCIP_CALL( SCIPlpiChgBounds(lpi, relaxedlpbdchgs->nbdchgs, relaxedlpbdchgs->bdchginds, \
    5361 relaxedlpbdchgs->bdchglbs, relaxedlpbdchgs->bdchgubs) );
    5362
    5363 /* reset conflict LP bound change data structure */
    5364 lpbdchgsReset(relaxedlpbdchgs, ncols);
    5365 }
    5366
    5367 /* start LP timer */
    5369
    5370 /* resolve LP */
    5371 retcode = SCIPlpiSolveDual(lpi);
    5372
    5373 /* stop LP timer */
    5375
    5376 /* check return code of LP solving call */
    5377 if( retcode == SCIP_LPERROR )
    5378 {
    5379 (*valid) = FALSE;
    5380 break;
    5381 }
    5382 SCIP_CALL( retcode );
    5383
    5384 /* count number of LP iterations */
    5385 SCIP_CALL( SCIPlpiGetIterations(lpi, &iter) );
    5386 (*iterations) += iter;
    5387 stat->nconflictlps++;
    5388 stat->nconflictlpiterations += iter;
    5389 SCIPsetDebugMsg(set, " -> resolved LP in %d iterations (total: %" SCIP_LONGINT_FORMAT ") (infeasible:%u)\n",
    5391
    5392 /* evaluate result */
    5393 if( SCIPlpiIsDualFeasible(lpi) || SCIPlpiIsObjlimExc(lpi) )
    5394 {
    5395 SCIP_Real objval;
    5396
    5397 SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
    5398 (*valid) = (objval >= lp->lpiobjlim && !SCIPlpDivingObjChanged(lp));
    5399 }
    5400 else
    5401 (*valid) = SCIPlpiIsPrimalInfeasible(lpi);
    5402
    5403 if( (*valid) )
    5404 {
    5405 int currentdepth;
    5406 currentdepth = SCIPtreeGetCurrentDepth(tree);
    5407
    5408 /* undo additional bound changes */
    5409 if( SCIPlpiIsPrimalInfeasible(lpi) )
    5410 {
    5411 SCIP_AGGRROW* farkasrow;
    5412 int* inds;
    5413 int validdepth;
    5414 int nnz;
    5415 int v;
    5416
    5417#ifndef NDEBUG
    5418 SCIP_VAR** vars = SCIPprobGetVars(transprob);
    5419#endif
    5420
    5421 SCIP_CALL( SCIPaggrRowCreate(set->scip, &farkasrow) );
    5422
    5423 /* the original LP exceeds the current cutoff bound, thus, we have not constructed the Farkas proof */
    5424 SCIP_CALL( SCIPgetFarkasProof(set, transprob, lp, lpi, tree, farkasrow, proofactivity, &validdepth,
    5425 curvarlbs, curvarubs, valid) );
    5426
    5427 /* the constructed Farkas proof is not valid, we need to break here */
    5428 if( !(*valid) )
    5429 {
    5430 SCIPaggrRowFree(set->scip, &farkasrow);
    5431 break;
    5432 }
    5433
    5434 /* start dual proof analysis */
    5435 if( set->conf_useinflp == 'd' || set->conf_useinflp == 'b' )
    5436 {
    5437 /* change the conflict type */
    5438 SCIP_Bool oldusescutoff = conflict->conflictset->usescutoffbound;
    5439 SCIP_CONFTYPE oldconftype = conflict->conflictset->conflicttype;
    5440 conflict->conflictset->usescutoffbound = FALSE;
    5442
    5443 /* start dual proof analysis */
    5444 SCIP_CALL( SCIPconflictAnalyzeDualProof(conflict, set, stat, eventfilter, blkmem, origprob, transprob, tree, reopt,
    5445 lp, farkasrow, validdepth, curvarlbs, curvarubs, FALSE, &globalinfeasible, dualproofsuccess) );
    5446
    5447 conflict->conflictset->usescutoffbound = oldusescutoff;
    5448 conflict->conflictset->conflicttype = oldconftype;
    5449 }
    5450
    5451 /* todo: in theory, we could apply conflict graph analysis for locally valid proofs, too, but this needs to be implemented */
    5452 if( globalinfeasible || validdepth > SCIPtreeGetEffectiveRootDepth(tree) )
    5453 {
    5454 SCIPaggrRowFree(set->scip, &farkasrow);
    5455 goto TERMINATE;
    5456 }
    5457
    5458 BMSclearMemoryArray(proofcoefs, SCIPprobGetNVars(transprob));
    5459 (*prooflhs) = -SCIPaggrRowGetRhs(farkasrow);
    5460 (*proofactivity) = -(*proofactivity);
    5461
    5462 inds = SCIPaggrRowGetInds(farkasrow);
    5463 nnz = SCIPaggrRowGetNNz(farkasrow);
    5464
    5465 for( v = 0; v < nnz; v++ )
    5466 {
    5467 int i = inds[v];
    5468
    5469 assert(SCIPvarGetProbindex(vars[i]) == inds[v]);
    5470
    5471 proofcoefs[i] = -SCIPaggrRowGetProbvarValue(farkasrow, i);
    5472 }
    5473
    5474 /* free aggregation rows */
    5475 SCIPaggrRowFree(set->scip, &farkasrow);
    5476
    5477 SCIP_CALL( undoBdchgsDualfarkas(set, transprob, lp, currentdepth, curvarlbs, curvarubs, lbchginfoposs, \
    5478 ubchginfoposs, oldlpbdchgs, relaxedlpbdchgs, valid, &resolve, proofcoefs, (*prooflhs), proofactivity) );
    5479 }
    5480 else
    5481 {
    5482 SCIP_AGGRROW* proofrow;
    5483 int* inds;
    5484 int validdepth;
    5485 int nnz;
    5486 int v;
    5487
    5488#ifndef NDEBUG
    5489 SCIP_VAR** vars = SCIPprobGetVars(transprob);
    5490#endif
    5491
    5492 assert(SCIPlpiIsDualFeasible(lpi) || SCIPlpiIsObjlimExc(lpi));
    5493
    5494 SCIP_CALL( SCIPaggrRowCreate(set->scip, &proofrow) );
    5495
    5496 SCIP_CALL( SCIPgetDualProof(set, transprob, lp, lpi, tree, proofrow, proofactivity, &validdepth,
    5497 curvarlbs, curvarubs, valid) );
    5498
    5499 /* the constructed dual proof is not valid, we need to break here */
    5500 if( !(*valid) || validdepth > SCIPtreeGetEffectiveRootDepth(tree) )
    5501 {
    5502 SCIPaggrRowFree(set->scip, &proofrow);
    5503 break;
    5504 }
    5505 /* in contrast to the infeasible case we don't want to analyze the (probably identical) proof again. */
    5506
    5507 BMSclearMemoryArray(proofcoefs, SCIPprobGetNVars(transprob));
    5508 (*prooflhs) = -SCIPaggrRowGetRhs(proofrow);
    5509 (*proofactivity) = -(*proofactivity);
    5510
    5511 inds = SCIPaggrRowGetInds(proofrow);
    5512 nnz = SCIPaggrRowGetNNz(proofrow);
    5513
    5514 for( v = 0; v < nnz; v++ )
    5515 {
    5516 int i = inds[v];
    5517
    5518 assert(SCIPvarGetProbindex(vars[i]) == inds[v]);
    5519
    5520 proofcoefs[i] = -SCIPaggrRowGetProbvarValue(proofrow, i);
    5521 }
    5522
    5523 /* free aggregation rows */
    5524 SCIPaggrRowFree(set->scip, &proofrow);
    5525
    5526 SCIP_CALL( undoBdchgsDualsol(set, transprob, lp, currentdepth, curvarlbs, curvarubs, lbchginfoposs, \
    5527 ubchginfoposs, oldlpbdchgs, relaxedlpbdchgs, valid, &resolve, proofcoefs, *prooflhs, proofactivity) );
    5528 }
    5529 }
    5530 assert(!resolve || (*valid));
    5531 assert(!resolve || relaxedlpbdchgs->nbdchgs > 0);
    5532 SCIPsetDebugMsg(set, " -> finished infeasible LP conflict analysis loop %d (iter: %d, nbdchgs: %d)\n",
    5533 nloops, iter, relaxedlpbdchgs->nbdchgs);
    5534 }
    5535
    5536 SCIPsetDebugMsg(set, "finished undoing bound changes after %d loops (valid=%u, nbdchgs: %d)\n",
    5537 nloops, (*valid), oldlpbdchgs->nbdchgs);
    5538
    5539 TERMINATE:
    5540 /* reset variables to local bounds */
    5541 if( oldlpbdchgs->nbdchgs > 0 )
    5542 {
    5543 SCIP_CALL( SCIPlpiChgBounds(lpi, oldlpbdchgs->nbdchgs, oldlpbdchgs->bdchginds, oldlpbdchgs->bdchglbs, oldlpbdchgs->bdchgubs) );
    5544 }
    5545
    5546 /* reset changes of local rows */
    5547 if( nsidechgs > 0 )
    5548 {
    5549 SCIP_CALL( SCIPlpiChgSides(lpi, nsidechgs, sidechginds, sidechgoldlhss, sidechgoldrhss) );
    5550 }
    5551
    5552 /* mark the LP unsolved */
    5553 if( oldlpbdchgs->nbdchgs > 0 || nsidechgs > 0 )
    5554 {
    5555 /* The LPI data are out of sync with LP data. Thus, the LP should be marked
    5556 * unsolved. However, for strong branching calls, the LP has to have status 'solved'; in
    5557 * this case, marklpunsolved is FALSE and synchronization is performed later. */
    5558 if( marklpunsolved )
    5559 {
    5560 lp->solved = FALSE;
    5561 lp->primalfeasible = FALSE;
    5562 lp->primalchecked = FALSE;
    5563 lp->dualfeasible = FALSE;
    5564 lp->dualchecked = FALSE;
    5565 lp->lpobjval = SCIP_INVALID;
    5567 }
    5568 }
    5569
    5570 /* reinstall old objective and iteration limits in LP solver */
    5573
    5574 /* free temporary memory */
    5575 SCIPsetFreeBufferArray(set, &sidechgnewrhss);
    5576 SCIPsetFreeBufferArray(set, &sidechgnewlhss);
    5577 SCIPsetFreeBufferArray(set, &sidechgoldrhss);
    5578 SCIPsetFreeBufferArray(set, &sidechgoldlhss);
    5579 SCIPsetFreeBufferArray(set, &sidechginds);
    5580 }
    5581
    5582 /* free temporary memory */
    5583 lpbdchgsFree(&relaxedlpbdchgs, set);
    5584 lpbdchgsFree(&oldlpbdchgs, set);
    5585
    5586 return SCIP_OKAY;
    5587}
    5588
    5589/** analyzes conflicting bound changes that were added with calls to SCIPconflictAddBound(), and on success, calls the
    5590 * conflict handlers to create a conflict constraint out of the resulting conflict set;
    5591 * updates statistics for propagation conflict analysis
    5592 */
    5594 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    5595 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
    5596 SCIP_SET* set, /**< global SCIP settings */
    5597 SCIP_STAT* stat, /**< problem statistics */
    5598 SCIP_PROB* prob, /**< problem data */
    5599 SCIP_TREE* tree, /**< branch and bound tree */
    5600 int validdepth, /**< minimal depth level at which the initial conflict set is valid */
    5601 SCIP_Bool* success /**< pointer to store whether a conflict constraint was created, or NULL */
    5602 )
    5603{
    5604 int nconss;
    5605 int nliterals;
    5606 int nreconvconss;
    5607 int nreconvliterals;
    5608
    5609 assert(conflict != NULL);
    5610 assert(conflict->conflictset != NULL);
    5611 assert(set != NULL);
    5612 assert(prob != NULL);
    5613
    5614 if( success != NULL )
    5615 *success = FALSE;
    5616
    5617 /* check if the conflict analysis is applicable */
    5619 return SCIP_OKAY;
    5620
    5621 /* check, if the conflict set will get too large with high probability */
    5622 if( conflict->conflictset->nbdchginfos + SCIPpqueueNElems(conflict->bdchgqueue)
    5623 + SCIPpqueueNElems(conflict->forcedbdchgqueue) >= 2*conflictCalcMaxsize(set, prob) )
    5624 return SCIP_OKAY;
    5625
    5626 SCIPsetDebugMsg(set, "analyzing conflict after infeasible propagation in depth %d\n", SCIPtreeGetCurrentDepth(tree));
    5627
    5628 /* start timing */
    5630
    5631 conflict->npropcalls++;
    5632
    5633 /* setting this to true adds bound changes only to the conflict graph bdchg queue */
    5634 conflict->bdchgonlyconfqueue = TRUE;
    5635
    5636 /* analyze the conflict set, and create a conflict constraint on success */
    5637 SCIP_CALL( conflictAnalyze(conflict, blkmem, set, stat, prob, tree, FALSE, validdepth, TRUE, &nconss, &nliterals, \
    5638 &nreconvconss, &nreconvliterals) );
    5639 conflict->npropsuccess += (nconss > 0 ? 1 : 0);
    5640 conflict->npropconfconss += nconss;
    5641 conflict->npropconfliterals += nliterals;
    5642 conflict->npropreconvconss += nreconvconss;
    5643 conflict->npropreconvliterals += nreconvliterals;
    5644 conflict->bdchgonlyconfqueue = FALSE;
    5645
    5646 if( success != NULL )
    5647 *success = (nconss > 0);
    5648
    5649 /* stop timing */
    5650 SCIPclockStop(conflict->propanalyzetime, set);
    5651
    5652 return SCIP_OKAY;
    5653}
    static long bound
    SCIP_VAR * h
    Definition: circlepacking.c:68
    SCIP_Real * r
    Definition: circlepacking.c:59
    void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
    Definition: clock.c:360
    void SCIPclockEnableOrDisable(SCIP_CLOCK *clck, SCIP_Bool enable)
    Definition: clock.c:260
    void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
    Definition: clock.c:290
    SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
    Definition: clock.c:438
    void SCIPclockReset(SCIP_CLOCK *clck)
    Definition: clock.c:209
    void SCIPclockFree(SCIP_CLOCK **clck)
    Definition: clock.c:185
    SCIP_RETCODE SCIPclockCreate(SCIP_CLOCK **clck, SCIP_CLOCKTYPE clocktype)
    Definition: clock.c:170
    internal methods for clocks and timing issues
    internal methods for conflict analysis
    SCIP_RETCODE SCIPconflictAnalyzeDualProof(SCIP_CONFLICT *conflict, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTFILTER *eventfilter, BMS_BLKMEM *blkmem, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_AGGRROW *proofrow, int validdepth, SCIP_Real *curvarlbs, SCIP_Real *curvarubs, SCIP_Bool initialproof, SCIP_Bool *globalinfeasible, SCIP_Bool *success)
    internal methods for dual proof conflict analysis
    SCIP_RETCODE SCIPgetFarkasProof(SCIP_SET *set, SCIP_PROB *prob, SCIP_LP *lp, SCIP_LPI *lpi, SCIP_TREE *tree, SCIP_AGGRROW *farkasrow, SCIP_Real *farkasact, int *validdepth, SCIP_Real *curvarlbs, SCIP_Real *curvarubs, SCIP_Bool *valid)
    SCIP_RETCODE SCIPgetDualProof(SCIP_SET *set, SCIP_PROB *transprob, SCIP_LP *lp, SCIP_LPI *lpi, SCIP_TREE *tree, SCIP_AGGRROW *farkasrow, SCIP_Real *farkasact, int *validdepth, SCIP_Real *curvarlbs, SCIP_Real *curvarubs, SCIP_Bool *valid)
    void SCIPconflictsetFree(SCIP_CONFLICTSET **conflictset, BMS_BLKMEM *blkmem)
    static SCIP_Bool conflictsetIsRedundant(SCIP_CONFLICTSET *conflictset1, SCIP_CONFLICTSET *conflictset2)
    SCIP_Bool SCIPconflictGraphApplicable(SCIP_SET *set)
    static SCIP_RETCODE ensureSidechgsSize(SCIP_SET *set, int **sidechginds, SCIP_Real **sidechgoldlhss, SCIP_Real **sidechgoldrhss, SCIP_Real **sidechgnewlhss, SCIP_Real **sidechgnewrhss, int *sidechgssize, int num)
    static void conflictClearResolution(SCIP_CONFLICT *conflict, SCIP_SET *set, SCIP_PROB *prob)
    static SCIP_RETCODE undoBdchgsDualsol(SCIP_SET *set, SCIP_PROB *prob, SCIP_LP *lp, int currentdepth, SCIP_Real *curvarlbs, SCIP_Real *curvarubs, int *lbchginfoposs, int *ubchginfoposs, SCIP_LPBDCHGS *oldlpbdchgs, SCIP_LPBDCHGS *relaxedlpbdchgs, SCIP_Bool *valid, SCIP_Bool *resolve, SCIP_Real *dualcoefs, SCIP_Real duallhs, SCIP_Real *dualactivity)
    static void conflictClear(SCIP_CONFLICT *conflict)
    static SCIP_RETCODE detectImpliedBounds(SCIP_SET *set, SCIP_PROB *prob, SCIP_STAT *stat, SCIP_TREE *tree, SCIP_EVENTFILTER *eventfilter, BMS_BLKMEM *blkmem, SCIP_PROB *origprob, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_CONFLICTSET *conflictset, int *nbdchgs, int *nredvars, SCIP_Bool *redundant)
    void SCIPconflicthdlrEnableOrDisableClocks(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_Bool enable)
    SCIP_RETCODE conflictCreateTmpBdchginfo(SCIP_CONFLICT *conflict, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_Real oldbound, SCIP_Real newbound, SCIP_BDCHGINFO **bdchginfo)
    SCIP_RETCODE SCIPconflictAnalyzeRemainingBdchgs(SCIP_CONFLICT *conflict, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_TREE *tree, SCIP_Bool diving, int *lbchginfoposs, int *ubchginfoposs, int *nconss, int *nliterals, int *nreconvconss, int *nreconvliterals)
    static SCIP_RETCODE conflictEnsureTmpbdchginfosMem(SCIP_CONFLICT *conflict, SCIP_SET *set, int num)
    static SCIP_RETCODE conflictQueueBound(SCIP_CONFLICT *conflict, SCIP_SET *set, SCIP_BDCHGINFO *bdchginfo, SCIP_Real relaxedbd, SCIP_Bool *success)
    static SCIP_Bool isBoundchgUseless(SCIP_SET *set, SCIP_BDCHGINFO *bdchginfo)
    SCIP_RETCODE SCIPrunBoundHeuristic(SCIP_CONFLICT *conflict, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_LPI *lpi, SCIP_EVENTFILTER *eventfilter, BMS_BLKMEM *blkmem, SCIP_Real *proofcoefs, SCIP_Real *prooflhs, SCIP_Real *proofactivity, SCIP_Real *curvarlbs, SCIP_Real *curvarubs, int *lbchginfoposs, int *ubchginfoposs, int *iterations, SCIP_Bool marklpunsolved, SCIP_Bool *dualproofsuccess, SCIP_Bool *valid)
    SCIP_RETCODE SCIPconflicthdlrCreate(SCIP_CONFLICTHDLR **conflicthdlr, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, const char *name, const char *desc, int priority, SCIP_DECL_CONFLICTCOPY((*conflictcopy)), SCIP_DECL_CONFLICTFREE((*conflictfree)), SCIP_DECL_CONFLICTINIT((*conflictinit)), SCIP_DECL_CONFLICTEXIT((*conflictexit)), SCIP_DECL_CONFLICTINITSOL((*conflictinitsol)), SCIP_DECL_CONFLICTEXITSOL((*conflictexitsol)), SCIP_DECL_CONFLICTEXEC((*conflictexec)), SCIP_CONFLICTHDLRDATA *conflicthdlrdata)
    static void conflictsetCalcConflictDepth(SCIP_CONFLICTSET *conflictset)
    SCIP_RETCODE SCIPconflicthdlrExit(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_SET *set)
    static SCIP_Real calcBdchgScore(SCIP_Real prooflhs, SCIP_Real proofact, SCIP_Real proofactdelta, SCIP_Real proofcoef, int depth, int currentdepth, SCIP_VAR *var, SCIP_SET *set)
    void SCIPconflicthdlrSetInit(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_DECL_CONFLICTINIT((*conflictinit)))
    int conflictCalcMaxsize(SCIP_SET *set, SCIP_PROB *prob)
    void SCIPconflicthdlrSetPriority(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_SET *set, int priority)
    SCIP_RETCODE SCIPconflictAddBound(SCIP_CONFLICT *conflict, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_BDCHGIDX *bdchgidx)
    SCIP_RETCODE SCIPconflicthdlrFree(SCIP_CONFLICTHDLR **conflicthdlr, SCIP_SET *set)
    SCIP_RETCODE SCIPconflictAnalyze(SCIP_CONFLICT *conflict, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_TREE *tree, int validdepth, SCIP_Bool *success)
    static SCIP_RETCODE undoBdchgsDualfarkas(SCIP_SET *set, SCIP_PROB *prob, SCIP_LP *lp, int currentdepth, SCIP_Real *curvarlbs, SCIP_Real *curvarubs, int *lbchginfoposs, int *ubchginfoposs, SCIP_LPBDCHGS *oldlpbdchgs, SCIP_LPBDCHGS *relaxedlpbdchgs, SCIP_Bool *valid, SCIP_Bool *resolve, SCIP_Real *farkascoefs, SCIP_Real farkaslhs, SCIP_Real *farkasactivity)
    static SCIP_RETCODE addBdchg(SCIP_SET *set, SCIP_VAR *var, SCIP_Real newlb, SCIP_Real newub, SCIP_LPBDCHGS *oldlpbdchgs, SCIP_LPBDCHGS *relaxedlpbdchgs, SCIP_LPI *lpi)
    static SCIP_RETCODE addCand(SCIP_SET *set, int currentdepth, SCIP_VAR *var, int lbchginfopos, int ubchginfopos, SCIP_Real proofcoef, SCIP_Real prooflhs, SCIP_Real proofact, SCIP_VAR ***cands, SCIP_Real **candscores, SCIP_Real **newbounds, SCIP_Real **proofactdeltas, int *candssize, int *ncands, int firstcand, SCIP_Bool keepsorted)
    static SCIP_RETCODE conflictCreateReconvergenceConss(SCIP_CONFLICT *conflict, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_TREE *tree, SCIP_Bool diving, int validdepth, SCIP_BDCHGINFO *firstuip, int *nreconvconss, int *nreconvliterals)
    SCIP_RETCODE SCIPconflicthdlrExitsol(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_SET *set)
    static SCIP_RETCODE conflictResolveBound(SCIP_CONFLICT *conflict, SCIP_SET *set, SCIP_BDCHGINFO *bdchginfo, SCIP_Real relaxedbd, int validdepth, SCIP_Bool *resolved)
    static void conflictsetClear(SCIP_CONFLICTSET *conflictset)
    SCIP_RETCODE SCIPconflictAddRelaxedBound(SCIP_CONFLICT *conflict, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_BDCHGIDX *bdchgidx, SCIP_Real relaxedbd)
    void SCIPconflicthdlrSetFree(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_DECL_CONFLICTFREE((*conflictfree)))
    static SCIP_Real conflictsetCalcScore(SCIP_CONFLICTSET *conflictset, SCIP_SET *set)
    void SCIPconflicthdlrSetExitsol(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_DECL_CONFLICTEXITSOL((*conflictexitsol)))
    static SCIP_RETCODE conflictAddConflictBound(SCIP_CONFLICT *conflict, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_BDCHGINFO *bdchginfo, SCIP_Real relaxedbd)
    static SCIP_RETCODE lpbdchgsCreate(SCIP_LPBDCHGS **lpbdchgs, SCIP_SET *set, int ncols)
    static SCIP_RETCODE doConflicthdlrCreate(SCIP_CONFLICTHDLR **conflicthdlr, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, const char *name, const char *desc, int priority, SCIP_DECL_CONFLICTCOPY((*conflictcopy)), SCIP_DECL_CONFLICTFREE((*conflictfree)), SCIP_DECL_CONFLICTINIT((*conflictinit)), SCIP_DECL_CONFLICTEXIT((*conflictexit)), SCIP_DECL_CONFLICTINITSOL((*conflictinitsol)), SCIP_DECL_CONFLICTEXITSOL((*conflictexitsol)), SCIP_DECL_CONFLICTEXEC((*conflictexec)), SCIP_CONFLICTHDLRDATA *conflicthdlrdata)
    static SCIP_RETCODE conflictsetCopy(SCIP_CONFLICTSET **targetconflictset, BMS_BLKMEM *blkmem, SCIP_CONFLICTSET *sourceconflictset, int nadditionalelems)
    static SCIP_RETCODE conflictsetAddBound(SCIP_CONFLICTSET *conflictset, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_BDCHGINFO *bdchginfo, SCIP_Real relaxedbd)
    static SCIP_RETCODE conflictAddConflictCons(SCIP_CONFLICT *conflict, 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_CONFLICTSET *conflictset, int insertdepth, SCIP_Bool *success)
    static SCIP_Bool conflictMarkBoundCheckPresence(SCIP_CONFLICT *conflict, SCIP_SET *set, SCIP_BDCHGINFO *bdchginfo, SCIP_Real relaxedbd)
    SCIP_RETCODE SCIPconflicthdlrCopyInclude(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_SET *set)
    static SCIP_Bool betterBoundInResolutionQueue(SCIP_CONFLICT *conflict, SCIP_SET *set, SCIP_BDCHGINFO *bdchginfo)
    void SCIPconflicthdlrSetExit(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_DECL_CONFLICTEXIT((*conflictexit)))
    SCIP_RETCODE SCIPundoBdchgsProof(SCIP_SET *set, SCIP_PROB *prob, int currentdepth, SCIP_Real *proofcoefs, SCIP_Real prooflhs, SCIP_Real *proofact, SCIP_Real *curvarlbs, SCIP_Real *curvarubs, int *lbchginfoposs, int *ubchginfoposs, SCIP_LPBDCHGS *oldlpbdchgs, SCIP_LPBDCHGS *relaxedlpbdchgs, SCIP_Bool *resolve, SCIP_LPI *lpi)
    static SCIP_RETCODE conflictsetAddBounds(SCIP_CONFLICT *conflict, SCIP_CONFLICTSET *conflictset, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_BDCHGINFO **bdchginfos, int nbdchginfos)
    static SCIP_RETCODE addSideRemoval(SCIP_SET *set, SCIP_ROW *row, SCIP_Real lpiinfinity, int **sidechginds, SCIP_Real **sidechgoldlhss, SCIP_Real **sidechgoldrhss, SCIP_Real **sidechgnewlhss, SCIP_Real **sidechgnewrhss, int *sidechgssize, int *nsidechgs)
    static SCIP_RETCODE convertToActiveVar(SCIP_VAR **var, SCIP_SET *set, SCIP_BOUNDTYPE *boundtype, SCIP_Real *bound)
    static SCIP_RETCODE incVSIDS(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_BOUNDTYPE boundtype, SCIP_Real value, SCIP_Real weight)
    static SCIP_Bool bdchginfoIsResolvable(SCIP_BDCHGINFO *bdchginfo)
    SCIP_RETCODE conflictAnalyze(SCIP_CONFLICT *conflict, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_TREE *tree, SCIP_Bool diving, int validdepth, SCIP_Bool mustresolve, int *nconss, int *nliterals, int *nreconvconss, int *nreconvliterals)
    void SCIPconflicthdlrSetCopy(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_DECL_CONFLICTCOPY((*conflictcopy)))
    static SCIP_Bool checkRedundancy(SCIP_SET *set, SCIP_CONFLICTSET *conflictset)
    static void lpbdchgsReset(SCIP_LPBDCHGS *lpbdchgs, int ncols)
    SCIP_RETCODE SCIPconflictIsVarUsed(SCIP_CONFLICT *conflict, SCIP_VAR *var, SCIP_SET *set, SCIP_BOUNDTYPE boundtype, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool *used)
    static SCIP_RETCODE conflictAddBound(SCIP_CONFLICT *conflict, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_BDCHGINFO *bdchginfo, SCIP_Real relaxedbd)
    SCIP_RETCODE SCIPconflictsetCreate(SCIP_CONFLICTSET **conflictset, BMS_BLKMEM *blkmem)
    static SCIP_RETCODE conflictsetCalcInsertDepth(SCIP_CONFLICTSET *conflictset, SCIP_SET *set, SCIP_TREE *tree)
    static SCIP_BDCHGINFO * conflictRemoveCand(SCIP_CONFLICT *conflict)
    static SCIP_DECL_PARAMCHGD(paramChgdConflicthdlrPriority)
    static SCIP_RETCODE conflictsetEnsureBdchginfosMem(SCIP_CONFLICTSET *conflictset, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
    static SCIP_BDCHGINFO * conflictFirstCand(SCIP_CONFLICT *conflict)
    SCIP_RETCODE SCIPconflictInit(SCIP_CONFLICT *conflict, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_CONFTYPE conftype, SCIP_Bool usescutoffbound)
    static SCIP_RETCODE ensureCandsSize(SCIP_SET *set, SCIP_VAR ***cands, SCIP_Real **candscores, SCIP_Real **newbounds, SCIP_Real **proofactdeltas, int *candssize, int num)
    SCIP_RETCODE SCIPconflicthdlrExec(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_SET *set, SCIP_NODE *node, SCIP_NODE *validnode, SCIP_BDCHGINFO **bdchginfos, SCIP_Real *relaxedbds, int nbdchginfos, SCIP_CONFTYPE conftype, SCIP_Bool usescutoffbound, SCIP_Bool resolved, SCIP_RESULT *result)
    SCIP_RETCODE SCIPconflicthdlrInitsol(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_SET *set)
    static void skipRedundantBdchginfos(SCIP_VAR *var, int *lbchginfopos, int *ubchginfopos)
    static SCIP_RETCODE conflictInsertConflictset(SCIP_CONFLICT *conflict, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_CONFLICTSET **conflictset)
    static SCIP_RETCODE conflictEnsureConflictsetsMem(SCIP_CONFLICT *conflict, SCIP_SET *set, int num)
    static void lpbdchgsFree(SCIP_LPBDCHGS **lpbdchgs, SCIP_SET *set)
    SCIP_RETCODE SCIPconflicthdlrInit(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_SET *set)
    static SCIP_RETCODE conflictAddConflictset(SCIP_CONFLICT *conflict, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_TREE *tree, int validdepth, SCIP_Bool diving, SCIP_Bool repropagate, SCIP_Bool *success, int *nliterals)
    static void conflictFreeTmpBdchginfos(SCIP_CONFLICT *conflict, BMS_BLKMEM *blkmem)
    void SCIPconflicthdlrSetInitsol(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_DECL_CONFLICTINITSOL((*conflictinitsol)))
    SCIP_RETCODE SCIPconflictFlushConss(SCIP_CONFLICT *conflict, 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)
    static SCIP_RETCODE updateStatistics(SCIP_CONFLICT *conflict, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_CONFLICTSET *conflictset, int insertdepth)
    SCIP_Bool bdchginfoIsInvalid(SCIP_CONFLICT *conflict, SCIP_BDCHGINFO *bdchginfo)
    methods and datastructures for conflict analysis
    void conflictsetPrint(SCIP_CONFLICTSET *conflictset)
    SCIP_RETCODE SCIPconsResolvePropagation(SCIP_CONS *cons, SCIP_SET *set, SCIP_VAR *infervar, int inferinfo, SCIP_BOUNDTYPE inferboundtype, SCIP_BDCHGIDX *bdchgidx, SCIP_Real relaxedbd, SCIP_RESULT *result)
    Definition: cons.c:7497
    internal methods for constraints and constraint handlers
    Constraint handler for linear constraints in their most general form, .
    methods for the aggregation rows
    #define SCIPquadprecProdQD(r, a, b)
    Definition: dbldblarith.h:63
    #define QUAD(x)
    Definition: dbldblarith.h:47
    #define SCIPquadprecSumDD(r, a, b)
    Definition: dbldblarith.h:60
    #define QUAD_TO_DBL(x)
    Definition: dbldblarith.h:49
    #define SCIPdebugCheckConflict(blkmem, set, node, bdchginfos, relaxedbds, nliterals)
    Definition: debug.h:309
    #define SCIPdebugCheckConflictFrontier(blkmem, set, node, bdchginfo, bdchginfos, relaxedbds, nliterals, bdchgqueue, forcedbdchgqueue)
    Definition: debug.h:310
    #define NULL
    Definition: def.h:257
    #define SCIP_MAXSTRLEN
    Definition: def.h:278
    #define SCIP_Longint
    Definition: def.h:150
    #define SCIP_REAL_MAX
    Definition: def.h:167
    #define SCIP_INVALID
    Definition: def.h:187
    #define SCIP_Bool
    Definition: def.h:100
    #define MIN(x, y)
    Definition: def.h:233
    #define SCIP_ALLOC(x)
    Definition: def.h:375
    #define SCIP_Real
    Definition: def.h:165
    #define TRUE
    Definition: def.h:102
    #define FALSE
    Definition: def.h:103
    #define MAX(x, y)
    Definition: def.h:229
    #define SCIP_LONGINT_FORMAT
    Definition: def.h:157
    #define SCIPABORT()
    Definition: def.h:336
    #define SCIP_REAL_MIN
    Definition: def.h:168
    #define SCIP_CALL(x)
    Definition: def.h:364
    #define SCIP_CALL_FINALLY(x, y)
    Definition: def.h:406
    void SCIPdotWriteOpening(FILE *file)
    Definition: misc.c:715
    void SCIPdotWriteClosing(FILE *file)
    Definition: misc.c:753
    void SCIPdotWriteArc(FILE *file, int source, int target, const char *color)
    Definition: misc.c:740
    void SCIPgmlWriteNode(FILE *file, unsigned int id, const char *label, const char *nodetype, const char *fillcolor, const char *bordercolor)
    Definition: misc.c:501
    void SCIPgmlWriteClosing(FILE *file)
    Definition: misc.c:703
    void SCIPdotWriteNode(FILE *file, int node, const char *label, const char *nodetype, const char *fillcolor, const char *bordercolor)
    Definition: misc.c:725
    void SCIPgmlWriteOpening(FILE *file, SCIP_Bool directed)
    Definition: misc.c:687
    void SCIPgmlWriteEdge(FILE *file, unsigned int source, unsigned int target, const char *label, const char *color)
    Definition: misc.c:599
    void SCIPgmlWriteArc(FILE *file, unsigned int source, unsigned int target, const char *label, const char *color)
    Definition: misc.c:643
    SCIP_RETCODE SCIPlpiChgSides(SCIP_LPI *lpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
    Definition: lpi_clp.cpp:1179
    SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
    Definition: lpi_clp.cpp:3947
    SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
    Definition: lpi_clp.cpp:2718
    SCIP_Bool SCIPlpiIsInfinity(SCIP_LPI *lpi, SCIP_Real val)
    Definition: lpi_clp.cpp:3959
    SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
    Definition: lpi_clp.cpp:3861
    SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
    Definition: lpi_clp.cpp:2794
    SCIP_RETCODE SCIPlpiChgBounds(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
    Definition: lpi_clp.cpp:1096
    SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
    Definition: lpi_clp.cpp:2637
    SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
    Definition: lpi_clp.cpp:3720
    SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
    Definition: lpi_clp.cpp:2530
    SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
    Definition: lpi_clp.cpp:1908
    SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
    Definition: lpi_clp.cpp:2949
    void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:208
    void ** SCIPpqueueElems(SCIP_PQUEUE *pqueue)
    Definition: misc.c:1540
    void SCIPpqueueClear(SCIP_PQUEUE *pqueue)
    Definition: misc.c:1335
    SCIP_RETCODE SCIPpqueueInsert(SCIP_PQUEUE *pqueue, void *elem)
    Definition: misc.c:1396
    int SCIPpqueueNElems(SCIP_PQUEUE *pqueue)
    Definition: misc.c:1529
    void * SCIPpqueueRemove(SCIP_PQUEUE *pqueue)
    Definition: misc.c:1495
    void * SCIPpqueueFirst(SCIP_PQUEUE *pqueue)
    Definition: misc.c:1515
    int SCIPcolGetLPPos(SCIP_COL *col)
    Definition: lp.c:17487
    int SCIPcolGetNNonz(SCIP_COL *col)
    Definition: lp.c:17520
    SCIP_BOUNDTYPE SCIPboundtypeOpposite(SCIP_BOUNDTYPE boundtype)
    Definition: lp.c:17597
    SCIP_CONFLICTHDLRDATA * SCIPconflicthdlrGetData(SCIP_CONFLICTHDLR *conflicthdlr)
    SCIP_DECL_SORTPTRCOMP(SCIPconflicthdlrComp)
    int SCIPconflicthdlrGetPriority(SCIP_CONFLICTHDLR *conflicthdlr)
    const char * SCIPconflicthdlrGetName(SCIP_CONFLICTHDLR *conflicthdlr)
    void SCIPconflicthdlrSetData(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_CONFLICTHDLRDATA *conflicthdlrdata)
    SCIP_Bool SCIPconflicthdlrIsInitialized(SCIP_CONFLICTHDLR *conflicthdlr)
    SCIP_Real SCIPconflicthdlrGetTime(SCIP_CONFLICTHDLR *conflicthdlr)
    SCIP_Real SCIPconflicthdlrGetSetupTime(SCIP_CONFLICTHDLR *conflicthdlr)
    const char * SCIPconflicthdlrGetDesc(SCIP_CONFLICTHDLR *conflicthdlr)
    SCIP_RETCODE SCIPsetConflicthdlrPriority(SCIP *scip, SCIP_CONFLICTHDLR *conflicthdlr, int priority)
    int SCIPconsGetValidDepth(SCIP_CONS *cons)
    Definition: cons.c:8476
    SCIP_Bool SCIPconsIsGlobal(SCIP_CONS *cons)
    Definition: cons.c:8622
    const char * SCIPconsGetName(SCIP_CONS *cons)
    Definition: cons.c:8393
    SCIP_RETCODE SCIPaggrRowCreate(SCIP *scip, SCIP_AGGRROW **aggrrow)
    Definition: cuts.c:2679
    SCIP_Real SCIPaggrRowGetRhs(SCIP_AGGRROW *aggrrow)
    Definition: cuts.c:4079
    void SCIPaggrRowFree(SCIP *scip, SCIP_AGGRROW **aggrrow)
    Definition: cuts.c:2711
    int * SCIPaggrRowGetInds(SCIP_AGGRROW *aggrrow)
    Definition: cuts.c:4039
    int SCIPaggrRowGetNNz(SCIP_AGGRROW *aggrrow)
    Definition: cuts.c:4049
    static INLINE SCIP_Real SCIPaggrRowGetProbvarValue(SCIP_AGGRROW *aggrrow, int probindex)
    Definition: cuts.h:297
    int SCIPnodeGetDepth(SCIP_NODE *node)
    Definition: tree.c:8523
    const char * SCIPpropGetName(SCIP_PROP *prop)
    Definition: prop.c:951
    SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
    Definition: lp.c:17686
    SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
    Definition: lp.c:17696
    int SCIProwGetLPPos(SCIP_ROW *row)
    Definition: lp.c:17895
    SCIP_Bool SCIProwIsLocal(SCIP_ROW *row)
    Definition: lp.c:17795
    const char * SCIProwGetName(SCIP_ROW *row)
    Definition: lp.c:17745
    SCIP_Real SCIProwGetConstant(SCIP_ROW *row)
    Definition: lp.c:17652
    SCIP_RETCODE SCIPshrinkDisjunctiveVarSet(SCIP *scip, SCIP_VAR **vars, SCIP_Real *bounds, SCIP_Bool *boundtypes, SCIP_Bool *redundants, int nvars, int *nredvars, int *nglobalred, SCIP_Bool *setredundant, SCIP_Bool *glbinfeas, SCIP_Bool fullshortening)
    Definition: presolve.c:995
    SCIP_Real SCIPgetVarBdAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
    Definition: scip_var.c:3008
    int SCIPvarGetNVlbs(SCIP_VAR *var)
    Definition: var.c:24514
    SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
    Definition: var.c:23715
    SCIP_Bool SCIPbdchginfoIsRedundant(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:25089
    SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
    Definition: var.c:23674
    SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
    Definition: var.c:23510
    SCIP_Bool SCIPbdchgidxIsEarlier(SCIP_BDCHGIDX *bdchgidx1, SCIP_BDCHGIDX *bdchgidx2)
    Definition: var.c:24921
    SCIP_BDCHGIDX * SCIPbdchginfoGetIdx(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:25011
    SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
    Definition: var.c:23418
    int SCIPvarGetNLocksUpType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
    Definition: var.c:4380
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24300
    SCIP_PROP * SCIPbdchginfoGetInferProp(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:25045
    SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
    Definition: var.c:23485
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24174
    int SCIPbdchginfoGetDepth(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:24991
    int SCIPbdchginfoGetInferInfo(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:25056
    int SCIPvarGetIndex(SCIP_VAR *var)
    Definition: var.c:23684
    SCIP_CONS * SCIPbdchginfoGetInferCons(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:25033
    int SCIPbdchginfoGetPos(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:25001
    SCIP_Real SCIPgetVarUbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
    Definition: scip_var.c:2872
    int SCIPvarGetProbindex(SCIP_VAR *var)
    Definition: var.c:23694
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23299
    SCIP_VAR * SCIPbdchginfoGetVar(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:24961
    int SCIPvarGetNVubs(SCIP_VAR *var)
    Definition: var.c:24556
    SCIP_Real SCIPbdchginfoGetOldbound(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:24941
    SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
    Definition: var.c:23522
    SCIP_BOUNDTYPE SCIPbdchginfoGetInferBoundtype(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:25068
    SCIP_BDCHGINFO * SCIPvarGetBdchgInfo(SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
    Definition: var.c:22770
    SCIP_VAR ** SCIPvarGetMultaggrVars(SCIP_VAR *var)
    Definition: var.c:23838
    SCIP_Bool SCIPbdchginfoIsTighter(SCIP_BDCHGINFO *bdchginfo1, SCIP_BDCHGINFO *bdchginfo2)
    Definition: var.c:25114
    int SCIPvarGetMultaggrNVars(SCIP_VAR *var)
    Definition: var.c:23826
    int SCIPvarGetNCliques(SCIP_VAR *var, SCIP_Bool varfixing)
    Definition: var.c:24674
    SCIP_BOUNDCHGTYPE SCIPbdchginfoGetChgtype(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:24971
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24266
    SCIP_VAR * SCIPbdchginfoGetInferVar(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:25021
    SCIP_Bool SCIPbdchginfoHasInferenceReason(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:25100
    SCIP_Bool SCIPvarIsRelaxationOnly(SCIP_VAR *var)
    Definition: var.c:23632
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24152
    SCIP_BDCHGINFO * SCIPvarGetBdchgInfoLb(SCIP_VAR *var, int pos)
    Definition: var.c:24736
    SCIP_Real SCIPgetVarLbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
    Definition: scip_var.c:2736
    SCIP_BOUNDTYPE SCIPbdchginfoGetBoundtype(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:24981
    SCIP_Real SCIPbdchginfoGetNewbound(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:24951
    int SCIPvarGetNLocksDownType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
    Definition: var.c:4322
    SCIP_BDCHGINFO * SCIPvarGetBdchgInfoUb(SCIP_VAR *var, int pos)
    Definition: var.c:24756
    SCIP_Real * SCIPvarGetMultaggrScalars(SCIP_VAR *var)
    Definition: var.c:23850
    SCIP_Bool SCIPvarIsInLP(SCIP_VAR *var)
    Definition: var.c:23738
    void SCIPsortedvecInsertIntPtrReal(int *intarray, void **ptrarray, SCIP_Real *realarray, int keyval, void *field1val, SCIP_Real field2val, int *len, int *pos)
    void SCIPsortDownRealRealRealPtr(SCIP_Real *realarray1, SCIP_Real *realarray2, SCIP_Real *realarray3, void **ptrarray, int len)
    void SCIPsortIntPtrReal(int *intarray, void **ptrarray, SCIP_Real *realarray, int len)
    void SCIPsortLongPtrRealRealBool(SCIP_Longint *longarray, void **ptrarray, SCIP_Real *realarray, SCIP_Real *realarray2, SCIP_Bool *boolarray, int len)
    void SCIPsortedvecDelPosIntPtrReal(int *intarray, void **ptrarray, SCIP_Real *realarray, int pos, int *len)
    int SCIPsnprintf(char *t, int len, const char *s,...)
    Definition: misc.c:10827
    void SCIPhistoryIncNActiveConflicts(SCIP_HISTORY *history, SCIP_BRANCHDIR dir, SCIP_Real length)
    Definition: history.c:677
    void SCIPhistoryScaleVSIDS(SCIP_HISTORY *history, SCIP_Real scalar)
    Definition: history.c:652
    void SCIPhistoryIncVSIDS(SCIP_HISTORY *history, SCIP_BRANCHDIR dir, SCIP_Real weight)
    Definition: history.c:638
    internal methods for branching and inference history
    SCIP_Bool SCIPlpDivingObjChanged(SCIP_LP *lp)
    Definition: lp.c:18261
    SCIP_LPI * SCIPlpGetLPI(SCIP_LP *lp)
    Definition: lp.c:18178
    int SCIPlpGetNCols(SCIP_LP *lp)
    Definition: lp.c:17979
    SCIP_ROW ** SCIPlpGetRows(SCIP_LP *lp)
    Definition: lp.c:18016
    static const SCIP_Real scalars[]
    Definition: lp.c:5959
    int SCIPlpGetNRows(SCIP_LP *lp)
    Definition: lp.c:18026
    internal methods for LP management
    interface methods for specific LP solvers
    static const char * paramname[]
    Definition: lpi_msk.c:5172
    #define BMSfreeMemory(ptr)
    Definition: memory.h:145
    #define BMSfreeBlockMemory(mem, ptr)
    Definition: memory.h:465
    #define BMSallocBlockMemory(mem, ptr)
    Definition: memory.h:451
    #define BMSreallocMemoryArray(ptr, num)
    Definition: memory.h:127
    #define BMSfreeBlockMemoryArrayNull(mem, ptr, num)
    Definition: memory.h:468
    #define BMSduplicateMemoryArray(ptr, source, num)
    Definition: memory.h:143
    #define BMSclearMemory(ptr)
    Definition: memory.h:129
    #define BMSallocBlockMemoryArray(mem, ptr, num)
    Definition: memory.h:454
    #define BMScopyMemoryArray(ptr, source, num)
    Definition: memory.h:134
    #define BMSreallocBlockMemoryArray(mem, ptr, oldnum, newnum)
    Definition: memory.h:458
    #define BMSclearMemoryArray(ptr, num)
    Definition: memory.h:130
    struct BMS_BlkMem BMS_BLKMEM
    Definition: memory.h:437
    #define BMSfreeMemoryArrayNull(ptr)
    Definition: memory.h:148
    #define BMSallocMemory(ptr)
    Definition: memory.h:118
    SCIP_PARAMDATA * SCIPparamGetData(SCIP_PARAM *param)
    Definition: paramset.c:676
    int SCIPparamGetInt(SCIP_PARAM *param)
    Definition: paramset.c:731
    methods commonly used for presolving
    const char * SCIPprobGetName(SCIP_PROB *prob)
    Definition: prob.c:2856
    int SCIPprobGetNVars(SCIP_PROB *prob)
    Definition: prob.c:2865
    SCIP_VAR ** SCIPprobGetVars(SCIP_PROB *prob)
    Definition: prob.c:2910
    SCIP_Bool SCIPprobAllColsInLP(SCIP_PROB *prob, SCIP_SET *set, SCIP_LP *lp)
    Definition: prob.c:2822
    SCIP_Bool SCIPprobIsTransformed(SCIP_PROB *prob)
    Definition: prob.c:2800
    internal methods for storing and manipulating the main problem
    SCIP_RETCODE SCIPpropResolvePropagation(SCIP_PROP *prop, SCIP_SET *set, SCIP_VAR *infervar, int inferinfo, SCIP_BOUNDTYPE inferboundtype, SCIP_BDCHGIDX *bdchgidx, SCIP_Real relaxedbd, SCIP_RESULT *result)
    Definition: prop.c:739
    internal methods for propagators
    public methods for conflict analysis handlers
    public methods for managing constraints
    public methods for LP management
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    #define SCIPdebug(x)
    Definition: pub_message.h:93
    #define SCIPdebugMessage
    Definition: pub_message.h:96
    #define SCIPdebugPrintf
    Definition: pub_message.h:99
    public data structures and miscellaneous methods
    methods for sorting joint arrays of various types
    public methods for handling parameter settings
    public methods for propagators
    public methods for branch and bound tree
    public methods for problem variables
    public methods for conflict handler plugins and conflict analysis
    public methods for constraint handler plugins and constraints
    public methods for memory management
    public methods for message handling
    public methods for solutions
    public methods for SCIP variables
    SCIP_RETCODE SCIPsetAddIntParam(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, 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: set.c:3235
    SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6623
    SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:7023
    SCIP_Bool SCIPsetIsFeasLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6999
    SCIP_Bool SCIPsetIsFeasEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6951
    SCIP_Bool SCIPsetIsPositive(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6654
    SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6583
    SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6543
    SCIP_Bool SCIPsetIsFeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6975
    SCIP_Bool SCIPsetIsLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6563
    SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6521
    SCIP_Bool SCIPsetIsGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6603
    SCIP_Bool SCIPsetIsIntegral(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6676
    SCIP_Bool SCIPsetIsZero(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6643
    SCIP_Bool SCIPsetIsFeasGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:7047
    void SCIPsetSortConflicthdlrs(SCIP_SET *set)
    Definition: set.c:4314
    int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
    Definition: set.c:6086
    SCIP_Bool SCIPsetIsNegative(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6665
    internal methods for global SCIP settings
    #define SCIPsetFreeBufferArray(set, ptr)
    Definition: set.h:1782
    #define SCIPsetFreeCleanBufferArray(set, ptr)
    Definition: set.h:1789
    #define SCIPsetDebugMsgPrint
    Definition: set.h:1812
    #define SCIPsetAllocBufferArray(set, ptr, num)
    Definition: set.h:1775
    #define SCIPsetFreeBuffer(set, ptr)
    Definition: set.h:1780
    #define SCIPsetAllocCleanBufferArray(set, ptr, num)
    Definition: set.h:1786
    #define SCIPsetDebugMsg
    Definition: set.h:1811
    #define SCIPsetAllocBuffer(set, ptr)
    Definition: set.h:1773
    #define SCIPsetReallocBufferArray(set, ptr, num)
    Definition: set.h:1779
    internal methods for storing primal CIP solutions
    SCIP_BDCHGIDX bdchgidx
    Definition: struct_var.h:127
    SCIP_Real newbound
    Definition: struct_var.h:123
    unsigned int boundtype
    Definition: struct_var.h:130
    SCIP_VAR * var
    Definition: struct_var.h:125
    unsigned int redundant
    Definition: struct_var.h:132
    SCIP_Real oldbound
    Definition: struct_var.h:122
    unsigned int pos
    Definition: struct_var.h:128
    SCIP_CONFTYPE conflicttype
    unsigned int hasrelaxonlyvar
    SCIP_BDCHGINFO ** bdchginfos
    unsigned int repropagate
    SCIP_Real * relaxedbds
    SCIP_CONFTYPE conflicttype
    unsigned int usescutoffbound
    SCIP_Real * conflictvarsubs
    SCIP_Real * conflictsetscores
    SCIP_Longint nappliedglbconss
    SCIP_Longint npropconfconss
    SCIP_CLOCK * dIBclock
    SCIP_PQUEUE * resbdchgqueue
    SCIP_CLOCK * propanalyzetime
    SCIP_PQUEUE * forcedbdchgqueue
    SCIP_Longint nappliedglbliterals
    SCIP_CONFLICTSET ** conflictsets
    SCIP_Bool bdchgonlyconfqueue
    SCIP_PQUEUE * bdchgqueue
    SCIP_Longint npropsuccess
    SCIP_Longint nappliedlocconss
    SCIP_Longint npropcalls
    SCIP_CONFLICTROW * conflictrow
    SCIP_Longint npropreconvliterals
    SCIP_Bool bdchgonlyresqueue
    SCIP_BDCHGINFO ** tmpbdchginfos
    SCIP_Longint npropconfliterals
    SCIP_CONFLICTSET * conflictset
    SCIP_Real * conflictvarslbs
    SCIP_Longint nappliedlocliterals
    SCIP_Longint npropreconvconss
    SCIP_CONFLICTHDLRDATA * conflicthdlrdata
    SCIP_CLOCK * setuptime
    SCIP_CLOCK * conflicttime
    SCIP_BOUNDCHG * boundchgs
    Definition: struct_var.h:140
    unsigned int nboundchgs
    Definition: struct_var.h:138
    SCIP_Real * bdchgubs
    SCIP_Bool * usedcols
    SCIP_Real * bdchglbs
    int lpiitlim
    Definition: struct_lp.h:351
    SCIP_Bool strongbranching
    Definition: struct_lp.h:383
    SCIP_Bool primalfeasible
    Definition: struct_lp.h:374
    SCIP_Real cutoffbound
    Definition: struct_lp.h:289
    SCIP_Bool dualfeasible
    Definition: struct_lp.h:376
    SCIP_Bool primalchecked
    Definition: struct_lp.h:375
    SCIP_LPSOLSTAT lpsolstat
    Definition: struct_lp.h:359
    SCIP_Real lpobjval
    Definition: struct_lp.h:276
    SCIP_Bool solved
    Definition: struct_lp.h:373
    SCIP_Bool dualchecked
    Definition: struct_lp.h:377
    SCIP_Bool diving
    Definition: struct_lp.h:386
    SCIP_Bool flushed
    Definition: struct_lp.h:372
    SCIP_Real lpiobjlim
    Definition: struct_lp.h:291
    SCIP_DOMCHG * domchg
    Definition: struct_tree.h:160
    unsigned int depth
    Definition: struct_tree.h:161
    int ncontvars
    Definition: struct_prob.h:80
    SCIP_VAR ** vars
    Definition: struct_prob.h:67
    SCIP_Longint nnodes
    Definition: struct_stat.h:84
    SCIP_Longint nconflictlps
    Definition: struct_stat.h:228
    SCIP_HISTORY * glbhistory
    Definition: struct_stat.h:195
    SCIP_VISUAL * visual
    Definition: struct_stat.h:198
    SCIP_Real vsidsweight
    Definition: struct_stat.h:134
    SCIP_Longint lastconflictnode
    Definition: struct_stat.h:114
    SCIP_HISTORY * glbhistorycrun
    Definition: struct_stat.h:196
    SCIP_Longint nconflictlpiterations
    Definition: struct_stat.h:81
    SCIP_CLOCK * conflictlptime
    Definition: struct_stat.h:179
    SCIP_NODE * root
    Definition: struct_tree.h:188
    SCIP_NODE ** path
    Definition: struct_tree.h:190
    int nubchginfos
    Definition: struct_var.h:325
    SCIP_BDCHGINFO * lbchginfos
    Definition: struct_var.h:304
    int conflictubcount
    Definition: struct_var.h:327
    SCIP_Real conflictrelaxedub
    Definition: struct_var.h:276
    SCIP_BDCHGINFO * ubchginfos
    Definition: struct_var.h:305
    SCIP_Real conflictub
    Definition: struct_var.h:274
    SCIP_Real conflictrelaxedlb
    Definition: struct_var.h:275
    int nlbchginfos
    Definition: struct_var.h:323
    SCIP_Real conflictlb
    Definition: struct_var.h:273
    int conflictlbcount
    Definition: struct_var.h:326
    datastructures for conflict analysis
    data structures for LP management
    datastructures for storing and manipulating the main problem
    datastructures for global SCIP settings
    datastructures for problem statistics
    data structures for branch and bound tree
    datastructures for problem variables
    Definition: heur_padm.c:132
    int SCIPtreeGetFocusDepth(SCIP_TREE *tree)
    Definition: tree.c:9434
    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
    void SCIPnodePropagateAgain(SCIP_NODE *node, SCIP_SET *set, SCIP_STAT *stat, SCIP_TREE *tree)
    Definition: tree.c:1368
    SCIP_RETCODE SCIPnodeCutoff(SCIP_NODE *node, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTFILTER *eventfilter, SCIP_TREE *tree, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_REOPT *reopt, SCIP_LP *lp, BMS_BLKMEM *blkmem)
    Definition: tree.c:1259
    SCIP_NODE * SCIPtreeGetRootNode(SCIP_TREE *tree)
    Definition: tree.c:9559
    int SCIPtreeGetEffectiveRootDepth(SCIP_TREE *tree)
    Definition: tree.c:9548
    int SCIPtreeGetCurrentDepth(SCIP_TREE *tree)
    Definition: tree.c:9509
    internal methods for branch and bound tree
    @ SCIP_CLOCKTYPE_DEFAULT
    Definition: type_clock.h:43
    #define SCIP_DECL_CONFLICTEXIT(x)
    #define SCIP_DECL_CONFLICTCOPY(x)
    Definition: type_conflict.h:89
    #define SCIP_DECL_CONFLICTEXEC(x)
    #define SCIP_DECL_CONFLICTINITSOL(x)
    #define SCIP_DECL_CONFLICTFREE(x)
    Definition: type_conflict.h:97
    @ SCIP_CONFTYPE_BNDEXCEEDING
    Definition: type_conflict.h:64
    @ SCIP_CONFTYPE_PROPAGATION
    Definition: type_conflict.h:62
    @ SCIP_CONFTYPE_INFEASLP
    Definition: type_conflict.h:63
    @ SCIP_CONFTYPE_UNKNOWN
    Definition: type_conflict.h:61
    #define SCIP_DECL_CONFLICTINIT(x)
    enum SCIP_ConflictType SCIP_CONFTYPE
    Definition: type_conflict.h:68
    struct SCIP_ConflicthdlrData SCIP_CONFLICTHDLRDATA
    Definition: type_conflict.h:50
    #define SCIP_DECL_CONFLICTEXITSOL(x)
    @ SCIP_BRANCHDIR_DOWNWARDS
    Definition: type_history.h:43
    @ SCIP_BRANCHDIR_UPWARDS
    Definition: type_history.h:44
    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
    enum SCIP_BoundType SCIP_BOUNDTYPE
    Definition: type_lp.h:60
    @ SCIP_LPSOLSTAT_NOTSOLVED
    Definition: type_lp.h:43
    @ SCIP_LPPAR_LPITLIM
    Definition: type_lpi.h:60
    @ SCIP_LPPAR_OBJLIM
    Definition: type_lpi.h:59
    struct SCIP_ParamData SCIP_PARAMDATA
    Definition: type_paramset.h:87
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_DIDNOTFIND
    Definition: type_result.h:44
    @ SCIP_CONSADDED
    Definition: type_result.h:52
    @ SCIP_SUCCESS
    Definition: type_result.h:58
    enum SCIP_Result SCIP_RESULT
    Definition: type_result.h:61
    @ SCIP_LPERROR
    Definition: type_retcode.h:49
    @ SCIP_INVALIDRESULT
    Definition: type_retcode.h:53
    @ SCIP_INVALIDDATA
    Definition: type_retcode.h:52
    @ SCIP_WRITEERROR
    Definition: type_retcode.h:46
    @ 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_BOUNDCHGTYPE_PROPINFER
    Definition: type_var.h:133
    @ SCIP_BOUNDCHGTYPE_BRANCHING
    Definition: type_var.h:131
    @ SCIP_BOUNDCHGTYPE_CONSINFER
    Definition: type_var.h:132
    @ SCIP_VARSTATUS_FIXED
    Definition: type_var.h:54
    @ SCIP_VARSTATUS_COLUMN
    Definition: type_var.h:53
    @ SCIP_VARSTATUS_MULTAGGR
    Definition: type_var.h:56
    @ SCIP_VARSTATUS_NEGATED
    Definition: type_var.h:57
    @ SCIP_VARSTATUS_AGGREGATED
    Definition: type_var.h:55
    @ SCIP_LOCKTYPE_MODEL
    Definition: type_var.h:141
    SCIP_DOMCHGBOUND domchgbound
    Definition: struct_var.h:168
    void SCIPbdchginfoFree(SCIP_BDCHGINFO **bdchginfo, BMS_BLKMEM *blkmem)
    Definition: var.c:22644
    SCIP_RETCODE SCIPvarIncVSIDS(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_BRANCHDIR dir, SCIP_Real value, SCIP_Real weight)
    Definition: var.c:21132
    SCIP_RETCODE SCIPvarIncNActiveConflicts(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_BRANCHDIR dir, SCIP_Real value, SCIP_Real length)
    Definition: var.c:21268
    void SCIPvarAdjustLb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *lb)
    Definition: var.c:9906
    SCIP_Real SCIPvarGetLbLP(SCIP_VAR *var, SCIP_SET *set)
    Definition: var.c:18603
    SCIP_RETCODE SCIPvarScaleVSIDS(SCIP_VAR *var, SCIP_Real scalar)
    Definition: var.c:21218
    SCIP_Real SCIPvarGetUbLP(SCIP_VAR *var, SCIP_SET *set)
    Definition: var.c:18673
    int SCIPbdchgidxGetPos(SCIP_BDCHGIDX *bdchgidx)
    Definition: var.c:24881
    SCIP_RETCODE SCIPbdchginfoCreate(SCIP_BDCHGINFO **bdchginfo, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_Real oldbound, SCIP_Real newbound)
    Definition: var.c:22614
    SCIP_RETCODE SCIPvarGetProbvarSum(SCIP_VAR **var, SCIP_SET *set, SCIP_Real *scalar, SCIP_Real *constant)
    Definition: var.c:18120
    void SCIPvarAdjustUb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *ub)
    Definition: var.c:9957
    SCIP_Real SCIPbdchginfoGetRelaxedBound(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:25080
    internal methods for problem variables
    void SCIPvisualFoundConflict(SCIP_VISUAL *visual, SCIP_STAT *stat, SCIP_NODE *node)
    Definition: visual.c:612
    methods for creating output for visualization tools (VBC, BAK)