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 )
    4560{
    4561 SCIP_Real oldbound;
    4562 SCIP_Real newbound;
    4563 SCIP_Real QUAD(proofactdelta);
    4564 SCIP_Real score;
    4565 int depth;
    4566 int i;
    4567 SCIP_Bool resolvable;
    4568
    4569 assert(set != NULL);
    4570 assert(var != NULL);
    4571 assert(-1 <= lbchginfopos && lbchginfopos <= var->nlbchginfos);
    4572 assert(-1 <= ubchginfopos && ubchginfopos <= var->nubchginfos);
    4573 assert(!SCIPsetIsZero(set, proofcoef));
    4574 assert(SCIPsetIsGT(set, prooflhs, proofact));
    4575 assert(cands != NULL);
    4576 assert(candscores != NULL);
    4577 assert(newbounds != NULL);
    4578 assert(proofactdeltas != NULL);
    4579 assert(candssize != NULL);
    4580 assert(ncands != NULL);
    4581 assert(*ncands <= *candssize);
    4582 assert(0 <= firstcand && firstcand <= *ncands);
    4583
    4584 /* in the infeasibility or dual bound proof, the variable's bound is chosen to maximize the proof's activity */
    4585 if( proofcoef > 0.0 )
    4586 {
    4587 assert(ubchginfopos >= 0); /* otherwise, undoBdchgsProof() should already have relaxed the local bound */
    4588
    4589 /* calculate the difference of current bound to the previous bound the variable was set to */
    4590 if( ubchginfopos == var->nubchginfos )
    4591 {
    4592 /* current bound is the strong branching or diving bound */
    4593 oldbound = SCIPvarGetUbLP(var, set);
    4594 newbound = SCIPvarGetUbLocal(var);
    4595 depth = currentdepth+1;
    4596 resolvable = FALSE;
    4597 }
    4598 else
    4599 {
    4600 /* current bound is the result of a local bound change */
    4601 resolvable = bdchginfoIsResolvable(&var->ubchginfos[ubchginfopos]);
    4602 depth = var->ubchginfos[ubchginfopos].bdchgidx.depth;
    4603 oldbound = var->ubchginfos[ubchginfopos].newbound;
    4604 newbound = var->ubchginfos[ubchginfopos].oldbound;
    4605 }
    4606 }
    4607 else
    4608 {
    4609 assert(lbchginfopos >= 0); /* otherwise, undoBdchgsProof() should already have relaxed the local bound */
    4610
    4611 /* calculate the difference of current bound to the previous bound the variable was set to */
    4612 if( lbchginfopos == var->nlbchginfos )
    4613 {
    4614 /* current bound is the strong branching or diving bound */
    4615 oldbound = SCIPvarGetLbLP(var, set);
    4616 newbound = SCIPvarGetLbLocal(var);
    4617 depth = currentdepth+1;
    4618 resolvable = FALSE;
    4619 }
    4620 else
    4621 {
    4622 /* current bound is the result of a local bound change */
    4623 resolvable = bdchginfoIsResolvable(&var->lbchginfos[lbchginfopos]);
    4624 depth = var->lbchginfos[lbchginfopos].bdchgidx.depth;
    4625 oldbound = var->lbchginfos[lbchginfopos].newbound;
    4626 newbound = var->lbchginfos[lbchginfopos].oldbound;
    4627 }
    4628 }
    4629
    4630 /* calculate the increase in the proof's activity */
    4631 SCIPquadprecSumDD(proofactdelta, newbound, -oldbound);
    4632 SCIPquadprecProdQD(proofactdelta, proofactdelta, proofcoef);
    4633 assert(QUAD_TO_DBL(proofactdelta) > 0.0);
    4634
    4635 /* calculate score for undoing the bound change */
    4636 score = calcBdchgScore(prooflhs, proofact, QUAD_TO_DBL(proofactdelta), proofcoef, depth, currentdepth, var, set);
    4637
    4638 if( !resolvable )
    4639 {
    4640 score += 10.0;
    4641 if( !SCIPvarIsBinary(var) )
    4642 score += 10.0;
    4643 }
    4644
    4645 /* get enough memory to store new candidate */
    4646 SCIP_CALL( ensureCandsSize(set, cands, candscores, newbounds, proofactdeltas, candssize, (*ncands)+1) );
    4647 assert(*cands != NULL);
    4648 assert(*candscores != NULL);
    4649 assert(*newbounds != NULL);
    4650 assert(*proofactdeltas != NULL);
    4651
    4652 SCIPsetDebugMsg(set, " -> local <%s> %s %g, relax <%s> %s %g, proofcoef=%g, dpt=%d, resolve=%u, delta=%g, score=%g\n",
    4653 SCIPvarGetName(var), proofcoef > 0.0 ? "<=" : ">=", oldbound,
    4654 SCIPvarGetName(var), proofcoef > 0.0 ? "<=" : ">=", newbound,
    4655 proofcoef, depth, resolvable, QUAD_TO_DBL(proofactdelta), score);
    4656
    4657 /* insert variable in candidate list without touching the already processed candidates */
    4658 for( i = *ncands; i > firstcand && score > (*candscores)[i-1]; --i )
    4659 {
    4660 (*cands)[i] = (*cands)[i-1];
    4661 (*candscores)[i] = (*candscores)[i-1];
    4662 (*newbounds)[i] = (*newbounds)[i-1];
    4663 (*proofactdeltas)[i] = (*proofactdeltas)[i-1];
    4664 }
    4665 (*cands)[i] = var;
    4666 (*candscores)[i] = score;
    4667 (*newbounds)[i] = newbound;
    4668 (*proofactdeltas)[i] = QUAD_TO_DBL(proofactdelta);
    4669 (*ncands)++;
    4670
    4671 return SCIP_OKAY;
    4672}
    4673
    4674/** undoes bound changes on variables, still leaving the given infeasibility proof valid */
    4676 SCIP_SET* set, /**< global SCIP settings */
    4677 SCIP_PROB* prob, /**< problem data */
    4678 int currentdepth, /**< current depth in the tree */
    4679 SCIP_Real* proofcoefs, /**< coefficients in infeasibility proof */
    4680 SCIP_Real prooflhs, /**< left hand side of proof */
    4681 SCIP_Real* proofact, /**< current activity of proof */
    4682 SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
    4683 SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
    4684 int* lbchginfoposs, /**< positions of currently active lower bound change information in variables' arrays */
    4685 int* ubchginfoposs, /**< positions of currently active upper bound change information in variables' arrays */
    4686 SCIP_LPBDCHGS* oldlpbdchgs, /**< old LP bound changes used for reset the LP bound change, or NULL */
    4687 SCIP_LPBDCHGS* relaxedlpbdchgs, /**< relaxed LP bound changes used for reset the LP bound change, or NULL */
    4688 SCIP_Bool* resolve, /**< pointer to store whether the changed LP should be resolved again, or NULL */
    4689 SCIP_LPI* lpi /**< pointer to LPi to access infinity of LP solver; necessary to set correct values */
    4690 )
    4691{
    4692 SCIP_VAR** vars;
    4693 SCIP_VAR** cands;
    4694 SCIP_Real* candscores;
    4695 SCIP_Real* newbounds;
    4696 SCIP_Real* proofactdeltas;
    4697 int nvars;
    4698 int ncands;
    4699 int candssize;
    4700 int v;
    4701 int i;
    4702
    4703 assert(prob != NULL);
    4704 assert(proofcoefs != NULL);
    4705 assert(SCIPsetIsFeasGT(set, prooflhs, (*proofact)));
    4706 assert(curvarlbs != NULL);
    4707 assert(curvarubs != NULL);
    4708 assert(lbchginfoposs != NULL);
    4709 assert(ubchginfoposs != NULL);
    4710
    4711 if( resolve != NULL )
    4712 *resolve = FALSE;
    4713
    4714 vars = prob->vars;
    4715 nvars = prob->nvars;
    4716 assert(nvars == 0 || vars != NULL);
    4717
    4718 /* calculate the order in which the bound changes are tried to be undone, and relax all bounds if this doesn't
    4719 * increase the proof's activity
    4720 */
    4721 SCIP_CALL( SCIPsetAllocBufferArray(set, &cands, nvars) );
    4722 SCIP_CALL( SCIPsetAllocBufferArray(set, &candscores, nvars) );
    4723 SCIP_CALL( SCIPsetAllocBufferArray(set, &newbounds, nvars) );
    4724 SCIP_CALL( SCIPsetAllocBufferArray(set, &proofactdeltas, nvars) );
    4725 ncands = 0;
    4726 candssize = nvars;
    4727 for( v = 0; v < nvars; ++v )
    4728 {
    4729 SCIP_VAR* var;
    4730 SCIP_Bool relaxed;
    4731
    4732 var = vars[v];
    4733
    4734 /* after changing the global bound of a variable, the bdchginfos that are now redundant are replaced with
    4735 * oldbound = newbound = global bound; if the current bdchginfo is of such kind, the bound is equal to the
    4736 * global bound and we can ignore it
    4737 */
    4738 skipRedundantBdchginfos(var, &lbchginfoposs[v], &ubchginfoposs[v]);
    4739
    4740 /* ignore variables already relaxed to global bounds */
    4741 if( (lbchginfoposs[v] == -1 && ubchginfoposs[v] == -1) )
    4742 {
    4743 proofcoefs[v] = 0.0;
    4744 continue;
    4745 }
    4746
    4747 /* relax bounds that are not used in the proof to the global bounds */
    4748 relaxed = FALSE;
    4749 if( !SCIPsetIsNegative(set, proofcoefs[v]) )
    4750 {
    4751 /* the lower bound is not used */
    4752 if( lbchginfoposs[v] >= 0 )
    4753 {
    4754 SCIPsetDebugMsg(set, " -> relaxing variable <%s>[%g,%g] to [%g,%g]: proofcoef=%g, %g <= %g\n",
    4755 SCIPvarGetName(var), curvarlbs[v], curvarubs[v], SCIPvarGetLbGlobal(var), curvarubs[v],
    4756 proofcoefs[v], prooflhs, (*proofact));
    4757 curvarlbs[v] = SCIPvarGetLbGlobal(var);
    4758 lbchginfoposs[v] = -1;
    4759 relaxed = TRUE;
    4760 }
    4761 }
    4762 if( !SCIPsetIsPositive(set, proofcoefs[v]) )
    4763 {
    4764 /* the upper bound is not used */
    4765 if( ubchginfoposs[v] >= 0 )
    4766 {
    4767 SCIPsetDebugMsg(set, " -> relaxing variable <%s>[%g,%g] to [%g,%g]: proofcoef=%g, %g <= %g\n",
    4768 SCIPvarGetName(var), curvarlbs[v], curvarubs[v], curvarlbs[v], SCIPvarGetUbGlobal(var),
    4769 proofcoefs[v], prooflhs, (*proofact));
    4770 curvarubs[v] = SCIPvarGetUbGlobal(var);
    4771 ubchginfoposs[v] = -1;
    4772 relaxed = TRUE;
    4773 }
    4774 }
    4775 if( relaxed && oldlpbdchgs != NULL )
    4776 {
    4777 SCIP_CALL( addBdchg(set, var, curvarlbs[v], curvarubs[v], oldlpbdchgs, relaxedlpbdchgs, lpi) );
    4778 }
    4779
    4780 /* add bound to candidate list */
    4781 if( lbchginfoposs[v] >= 0 || ubchginfoposs[v] >= 0 )
    4782 {
    4783 SCIP_CALL( addCand(set, currentdepth, var, lbchginfoposs[v], ubchginfoposs[v], proofcoefs[v],
    4784 prooflhs, (*proofact), &cands, &candscores, &newbounds, &proofactdeltas, &candssize, &ncands, 0) );
    4785 }
    4786 /* we can set the proof coefficient to zero, because the variable is not needed */
    4787 else
    4788 proofcoefs[v] = 0.0;
    4789 }
    4790
    4791 /* try to undo remaining local bound changes while still keeping the proof row violated:
    4792 * bound changes can be undone, if prooflhs > proofact + proofactdelta;
    4793 * afterwards, the current proof activity has to be updated
    4794 */
    4795 for( i = 0; i < ncands; ++i )
    4796 {
    4797 assert(proofactdeltas[i] > 0.0);
    4798 assert((lbchginfoposs[SCIPvarGetProbindex(cands[i])] >= 0) != (ubchginfoposs[SCIPvarGetProbindex(cands[i])] >= 0));
    4799
    4800 /* when relaxing a constraint we still need to stay infeasible; therefore we need to do the comparison in
    4801 * feasibility tolerance because if 'prooflhs' is (feas-))equal to 'proofact + proofactdeltas[i]' it would mean
    4802 * that there is no violation
    4803 */
    4804 if( SCIPsetIsFeasGT(set, prooflhs, (*proofact) + proofactdeltas[i]) )
    4805 {
    4806 v = SCIPvarGetProbindex(cands[i]);
    4807 assert(0 <= v && v < nvars);
    4808 assert((lbchginfoposs[v] >= 0) != (ubchginfoposs[v] >= 0));
    4809
    4810 SCIPsetDebugMsg(set, " -> relaxing variable <%s>[%g,%g] to [%g,%g]: proofcoef=%g, %g <= %g + %g\n",
    4811 SCIPvarGetName(cands[i]), curvarlbs[v], curvarubs[v],
    4812 proofcoefs[v] > 0.0 ? curvarlbs[v] : newbounds[i],
    4813 proofcoefs[v] > 0.0 ? newbounds[i] : curvarubs[v],
    4814 proofcoefs[v], prooflhs, (*proofact), proofactdeltas[i]);
    4815
    4816#ifndef NDEBUG
    4817 {
    4818 SCIP_Real QUAD(verifylb);
    4819 SCIP_Real QUAD(verifyub);
    4820
    4821 SCIPquadprecSumDD(verifylb, newbounds[i], -curvarlbs[v]);
    4822 SCIPquadprecProdQD(verifylb, verifylb, proofcoefs[v]);
    4823
    4824 SCIPquadprecSumDD(verifyub, newbounds[i], -curvarubs[v]);
    4825 SCIPquadprecProdQD(verifyub, verifyub, proofcoefs[v]);
    4826
    4827 assert((SCIPsetIsPositive(set, proofcoefs[v]) && SCIPsetIsGT(set, newbounds[i], curvarubs[v]))
    4828 || (SCIPsetIsNegative(set, proofcoefs[v]) && SCIPsetIsLT(set, newbounds[i], curvarlbs[v])));
    4829 assert((SCIPsetIsPositive(set, proofcoefs[v])
    4830 && SCIPsetIsEQ(set, proofactdeltas[i], QUAD_TO_DBL(verifyub)))
    4831 || (SCIPsetIsNegative(set, proofcoefs[v])
    4832 && SCIPsetIsEQ(set, proofactdeltas[i], QUAD_TO_DBL(verifylb))));
    4833 assert(!SCIPsetIsZero(set, proofcoefs[v]));
    4834 }
    4835#endif
    4836
    4837 if( proofcoefs[v] > 0.0 )
    4838 {
    4839 assert(ubchginfoposs[v] >= 0);
    4840 assert(lbchginfoposs[v] == -1);
    4841 curvarubs[v] = newbounds[i];
    4842 ubchginfoposs[v]--;
    4843 }
    4844 else
    4845 {
    4846 assert(lbchginfoposs[v] >= 0);
    4847 assert(ubchginfoposs[v] == -1);
    4848 curvarlbs[v] = newbounds[i];
    4849 lbchginfoposs[v]--;
    4850 }
    4851 if( oldlpbdchgs != NULL )
    4852 {
    4853 SCIP_CALL( addBdchg(set, cands[i], curvarlbs[v], curvarubs[v], oldlpbdchgs, relaxedlpbdchgs, lpi) );
    4854 }
    4855 (*proofact) += proofactdeltas[i];
    4856 if( resolve != NULL && SCIPvarIsInLP(cands[i]) )
    4857 *resolve = TRUE;
    4858
    4859 /* after changing the global bound of a variable, the bdchginfos that are now redundant are replaced with
    4860 * oldbound = newbound = global bound; if the current bdchginfo is of such kind, the bound is equal to the
    4861 * global bound and we can ignore it
    4862 */
    4863 skipRedundantBdchginfos(cands[i], &lbchginfoposs[v], &ubchginfoposs[v]);
    4864
    4865 /* insert the new local bound of the variable into the candidate list */
    4866 if( lbchginfoposs[v] >= 0 || ubchginfoposs[v] >= 0 )
    4867 {
    4868 SCIP_CALL( addCand(set, currentdepth, cands[i], lbchginfoposs[v], ubchginfoposs[v], proofcoefs[v],
    4869 prooflhs, (*proofact), &cands, &candscores, &newbounds, &proofactdeltas, &candssize, &ncands, i+1) );
    4870 }
    4871 else
    4872 proofcoefs[v] = 0.0;
    4873 }
    4874 }
    4875
    4876 /* free the buffer for the sorted bound change candidates */
    4877 SCIPsetFreeBufferArray(set, &proofactdeltas);
    4878 SCIPsetFreeBufferArray(set, &newbounds);
    4879 SCIPsetFreeBufferArray(set, &candscores);
    4880 SCIPsetFreeBufferArray(set, &cands);
    4881
    4882 return SCIP_OKAY;
    4883}
    4884
    4885/** analyzes an infeasible LP and undoes additional bound changes while staying infeasible */
    4886static
    4888 SCIP_SET* set, /**< global SCIP settings */
    4889 SCIP_PROB* prob, /**< problem data */
    4890 SCIP_LP* lp, /**< LP data */
    4891 int currentdepth, /**< current depth in the tree */
    4892 SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
    4893 SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
    4894 int* lbchginfoposs, /**< positions of currently active lower bound change information in variables' arrays */
    4895 int* ubchginfoposs, /**< positions of currently active upper bound change information in variables' arrays */
    4896 SCIP_LPBDCHGS* oldlpbdchgs, /**< old LP bound changes used for reset the LP bound change, or NULL */
    4897 SCIP_LPBDCHGS* relaxedlpbdchgs, /**< relaxed LP bound changes used for reset the LP bound change, or NULL */
    4898 SCIP_Bool* valid, /**< pointer to store whether the unfixings are valid */
    4899 SCIP_Bool* resolve, /**< pointer to store whether the changed LP should be resolved again */
    4900 SCIP_Real* farkascoefs, /**< coefficients in the proof constraint */
    4901 SCIP_Real farkaslhs, /**< lhs of the proof constraint */
    4902 SCIP_Real* farkasactivity /**< maximal activity of the proof constraint */
    4903 )
    4904{
    4905 SCIP_LPI* lpi;
    4906
    4907 assert(prob != NULL);
    4908 assert(lp != NULL);
    4909 assert(lp->flushed);
    4910 assert(lp->solved);
    4911 assert(curvarlbs != NULL);
    4912 assert(curvarubs != NULL);
    4913 assert(lbchginfoposs != NULL);
    4914 assert(ubchginfoposs != NULL);
    4915 assert(valid != NULL);
    4916 assert(resolve != NULL);
    4917
    4918 SCIPsetDebugMsg(set, "undoing bound changes in infeasible LP: cutoff=%g\n", lp->cutoffbound);
    4919
    4920 *valid = FALSE;
    4921 *resolve = FALSE;
    4922
    4923 lpi = SCIPlpGetLPI(lp);
    4924
    4925 /* check, if the Farkas row is still violated (using current bounds and ignoring local rows) */
    4926 if( SCIPsetIsFeasGT(set, farkaslhs, *farkasactivity) )
    4927 {
    4928 /* undo bound changes while keeping the infeasibility proof valid */
    4929 SCIP_CALL( SCIPundoBdchgsProof(set, prob, currentdepth, farkascoefs, farkaslhs, farkasactivity, \
    4930 curvarlbs, curvarubs, lbchginfoposs, ubchginfoposs, oldlpbdchgs, relaxedlpbdchgs, resolve, lpi) );
    4931
    4932 *valid = TRUE;
    4933
    4934 /* resolving does not make sense: the old dual ray is still valid -> resolving will not change the solution */
    4935 *resolve = FALSE;
    4936 }
    4937
    4938 return SCIP_OKAY;
    4939}
    4940
    4941
    4942/*
    4943 * Conflict LP Bound Changes
    4944 */
    4945
    4946/** create conflict LP bound change data structure */
    4947static
    4949 SCIP_LPBDCHGS** lpbdchgs, /**< pointer to store the conflict LP bound change data structure */
    4950 SCIP_SET* set, /**< global SCIP settings */
    4951 int ncols /**< number of columns */
    4952 )
    4953{
    4954 SCIP_CALL( SCIPsetAllocBuffer(set, lpbdchgs) );
    4955
    4956 SCIP_CALL( SCIPsetAllocBufferArray(set, &(*lpbdchgs)->bdchginds, ncols) );
    4957 SCIP_CALL( SCIPsetAllocBufferArray(set, &(*lpbdchgs)->bdchglbs, ncols) );
    4958 SCIP_CALL( SCIPsetAllocBufferArray(set, &(*lpbdchgs)->bdchgubs, ncols) );
    4959 SCIP_CALL( SCIPsetAllocBufferArray(set, &(*lpbdchgs)->bdchgcolinds, ncols) );
    4960 SCIP_CALL( SCIPsetAllocBufferArray(set, &(*lpbdchgs)->usedcols, ncols) );
    4961 BMSclearMemoryArray((*lpbdchgs)->usedcols, ncols);
    4962
    4963 (*lpbdchgs)->nbdchgs = 0;
    4964
    4965 return SCIP_OKAY;
    4966}
    4967
    4968
    4969/*
    4970 * Propagation Conflict Analysis
    4971 */
    4972
    4973/** ensures, that side change arrays can store at least num entries */
    4974static
    4976 SCIP_SET* set, /**< global SCIP settings */
    4977 int** sidechginds, /**< pointer to side change index array */
    4978 SCIP_Real** sidechgoldlhss, /**< pointer to side change old left hand sides array */
    4979 SCIP_Real** sidechgoldrhss, /**< pointer to side change old right hand sides array */
    4980 SCIP_Real** sidechgnewlhss, /**< pointer to side change new left hand sides array */
    4981 SCIP_Real** sidechgnewrhss, /**< pointer to side change new right hand sides array */
    4982 int* sidechgssize, /**< pointer to size of side change arrays */
    4983 int num /**< minimal number of entries to be able to store in side change arrays */
    4984 )
    4985{
    4986 assert(sidechginds != NULL);
    4987 assert(sidechgoldlhss != NULL);
    4988 assert(sidechgoldrhss != NULL);
    4989 assert(sidechgnewlhss != NULL);
    4990 assert(sidechgnewrhss != NULL);
    4991 assert(sidechgssize != NULL);
    4992
    4993 if( num > *sidechgssize )
    4994 {
    4995 int newsize;
    4996
    4997 newsize = SCIPsetCalcMemGrowSize(set, num);
    4998 SCIP_CALL( SCIPsetReallocBufferArray(set, sidechginds, newsize) );
    4999 SCIP_CALL( SCIPsetReallocBufferArray(set, sidechgoldlhss, newsize) );
    5000 SCIP_CALL( SCIPsetReallocBufferArray(set, sidechgoldrhss, newsize) );
    5001 SCIP_CALL( SCIPsetReallocBufferArray(set, sidechgnewlhss, newsize) );
    5002 SCIP_CALL( SCIPsetReallocBufferArray(set, sidechgnewrhss, newsize) );
    5003 *sidechgssize = newsize;
    5004 }
    5005 assert(num <= *sidechgssize);
    5006
    5007 return SCIP_OKAY;
    5008}
    5009
    5010/** adds removal of row's side to side change arrays; finite sides are only replaced by near infinite sides, such
    5011 * that the row's sense in the LP solver is not changed
    5012 */
    5013static
    5015 SCIP_SET* set, /**< global SCIP settings */
    5016 SCIP_ROW* row, /**< LP row to change the sides for */
    5017 SCIP_Real lpiinfinity, /**< value treated as infinity in LP solver */
    5018 int** sidechginds, /**< pointer to side change index array */
    5019 SCIP_Real** sidechgoldlhss, /**< pointer to side change old left hand sides array */
    5020 SCIP_Real** sidechgoldrhss, /**< pointer to side change old right hand sides array */
    5021 SCIP_Real** sidechgnewlhss, /**< pointer to side change new left hand sides array */
    5022 SCIP_Real** sidechgnewrhss, /**< pointer to side change new right hand sides array */
    5023 int* sidechgssize, /**< pointer to size of side change arrays */
    5024 int* nsidechgs /**< pointer to number of used slots in side change arrays */
    5025 )
    5026{
    5027 SCIP_Real lhs;
    5028 SCIP_Real rhs;
    5029 SCIP_Real constant;
    5030
    5031 assert(sidechginds != NULL);
    5032 assert(sidechgoldlhss != NULL);
    5033 assert(sidechgoldrhss != NULL);
    5034 assert(sidechgnewlhss != NULL);
    5035 assert(sidechgnewrhss != NULL);
    5036 assert(sidechgssize != NULL);
    5037 assert(nsidechgs != NULL);
    5038
    5039 lhs = SCIProwGetLhs(row);
    5040 rhs = SCIProwGetRhs(row);
    5041 constant = SCIProwGetConstant(row);
    5042 assert(!SCIPsetIsInfinity(set, -lhs) || !SCIPsetIsInfinity(set, rhs));
    5043
    5044 /* get memory to store additional side change */
    5045 SCIP_CALL( ensureSidechgsSize(set, sidechginds, sidechgoldlhss, sidechgoldrhss, sidechgnewlhss, sidechgnewrhss, \
    5046 sidechgssize, (*nsidechgs)+1) );
    5047 assert(*nsidechgs < *sidechgssize);
    5048 assert(*sidechginds != NULL);
    5049 assert(*sidechgoldlhss != NULL);
    5050 assert(*sidechgoldrhss != NULL);
    5051 assert(*sidechgnewlhss != NULL);
    5052 assert(*sidechgnewrhss != NULL);
    5053
    5054 /* store side change */
    5055 (*sidechginds)[*nsidechgs] = SCIProwGetLPPos(row);
    5056 if( SCIPsetIsInfinity(set, -lhs) )
    5057 {
    5058 (*sidechgoldlhss)[*nsidechgs] = -lpiinfinity;
    5059 (*sidechgnewlhss)[*nsidechgs] = -lpiinfinity;
    5060 }
    5061 else
    5062 {
    5063 (*sidechgoldlhss)[*nsidechgs] = lhs - constant;
    5064 (*sidechgnewlhss)[*nsidechgs] = -lpiinfinity;
    5065 }
    5066 if( SCIPsetIsInfinity(set, rhs) )
    5067 {
    5068 (*sidechgoldrhss)[*nsidechgs] = lpiinfinity;
    5069 (*sidechgnewrhss)[*nsidechgs] = lpiinfinity;
    5070 }
    5071 else
    5072 {
    5073 (*sidechgoldrhss)[*nsidechgs] = rhs - constant;
    5074 (*sidechgnewrhss)[*nsidechgs] = lpiinfinity;
    5075 }
    5076 (*nsidechgs)++;
    5077
    5078 return SCIP_OKAY;
    5079}
    5080
    5081
    5082/*
    5083 * Infeasible LP Conflict Analysis
    5084 */
    5085
    5086/** reset conflict LP bound change data structure */
    5087static
    5089 SCIP_LPBDCHGS* lpbdchgs, /**< conflict LP bound change data structure */
    5090 int ncols /**< number of columns */
    5091 )
    5092{
    5093 assert(lpbdchgs != NULL);
    5094
    5095 BMSclearMemoryArray(lpbdchgs->usedcols, ncols);
    5096 lpbdchgs->nbdchgs = 0;
    5097}
    5098
    5099/** free conflict LP bound change data structure */
    5100static
    5102 SCIP_LPBDCHGS** lpbdchgs, /**< pointer to store the conflict LP bound change data structure */
    5103 SCIP_SET* set /**< global SCIP settings */
    5104 )
    5105{
    5106 SCIPsetFreeBufferArray(set, &(*lpbdchgs)->usedcols);
    5107 SCIPsetFreeBufferArray(set, &(*lpbdchgs)->bdchgcolinds);
    5108 SCIPsetFreeBufferArray(set, &(*lpbdchgs)->bdchgubs);
    5109 SCIPsetFreeBufferArray(set, &(*lpbdchgs)->bdchglbs);
    5110 SCIPsetFreeBufferArray(set, &(*lpbdchgs)->bdchginds);
    5111
    5112 SCIPsetFreeBuffer(set, lpbdchgs);
    5113}
    5114
    5115/** analyzes an LP exceeding the objective limit and undoes additional bound changes while staying beyond the
    5116 * objective limit
    5117 */
    5118static
    5120 SCIP_SET* set, /**< global SCIP settings */
    5121 SCIP_PROB* prob, /**< problem data */
    5122 SCIP_LP* lp, /**< LP data */
    5123 int currentdepth, /**< current depth in the tree */
    5124 SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
    5125 SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
    5126 int* lbchginfoposs, /**< positions of currently active lower bound change information in variables' arrays */
    5127 int* ubchginfoposs, /**< positions of currently active upper bound change information in variables' arrays */
    5128 SCIP_LPBDCHGS* oldlpbdchgs, /**< old LP bound changes used for reset the LP bound change, or NULL */
    5129 SCIP_LPBDCHGS* relaxedlpbdchgs, /**< relaxed LP bound changes used for reset the LP bound change, or NULL */
    5130 SCIP_Bool* valid, /**< pointer to store whether the unfixings are valid */
    5131 SCIP_Bool* resolve, /**< pointer to store whether the changed LP should be resolved again */
    5132 SCIP_Real* dualcoefs, /**< coefficients in the proof constraint */
    5133 SCIP_Real duallhs, /**< lhs of the proof constraint */
    5134 SCIP_Real* dualactivity /**< maximal activity of the proof constraint */
    5135 )
    5136{
    5137 SCIP_LPI* lpi;
    5138
    5139 assert(set != NULL);
    5140 assert(prob != NULL);
    5141 assert(lp != NULL);
    5142 assert(lp->flushed);
    5143 assert(lp->solved);
    5144 assert(curvarlbs != NULL);
    5145 assert(curvarubs != NULL);
    5146 assert(lbchginfoposs != NULL);
    5147 assert(ubchginfoposs != NULL);
    5148 assert(valid != NULL);
    5149 assert(resolve != NULL);
    5150
    5151 *valid = FALSE;
    5152 *resolve = FALSE;
    5153
    5154 SCIPsetDebugMsg(set, "undoing bound changes in LP exceeding cutoff: cutoff=%g\n", lp->cutoffbound);
    5155
    5156 /* get LP solver interface */
    5157 lpi = SCIPlpGetLPI(lp);
    5158
    5159 /* check, if the dual row is still violated (using current bounds and ignoring local rows) */
    5160 if( SCIPsetIsFeasGT(set, duallhs, *dualactivity) )
    5161 {
    5162 /* undo bound changes while keeping the infeasibility proof valid */
    5163 SCIP_CALL( SCIPundoBdchgsProof(set, prob, currentdepth, dualcoefs, duallhs, dualactivity, curvarlbs, curvarubs, \
    5164 lbchginfoposs, ubchginfoposs, oldlpbdchgs, relaxedlpbdchgs, resolve, lpi) );
    5165
    5166 *valid = TRUE;
    5167 }
    5168
    5169 return SCIP_OKAY;
    5170}
    5171
    5172/** try to find a subset of changed bounds leading to an infeasible LP
    5173 *
    5174 * 1. call undoBdchgsDualfarkas() or undoBdchgsDualsol()
    5175 * -> update lb/ubchginfoposs arrays
    5176 * -> store additional changes in bdchg and curvarlbs/ubs arrays
    5177 * -> apply additional changes to the LPI
    5178 * 2. (optional) if additional bound changes were undone:
    5179 * -> resolve LP
    5180 * -> goto 1.
    5181 * 3. redo all bound changes in the LPI to restore the LPI to its original state
    5182 * 4. analyze conflict
    5183 * -> put remaining changed bounds (see lb/ubchginfoposs arrays) into starting conflict set
    5184 */
    5186 SCIP_CONFLICT* conflict, /**< conflict data */
    5187 SCIP_SET* set, /**< global SCIP settings */
    5188 SCIP_STAT* stat, /**< problem statistics */
    5189 SCIP_PROB* origprob, /**< original problem */
    5190 SCIP_PROB* transprob, /**< transformed problem */
    5191 SCIP_TREE* tree, /**< branch and bound tree */
    5192 SCIP_REOPT* reopt, /**< reoptimization data */
    5193 SCIP_LP* lp, /**< LP data */
    5194 SCIP_LPI* lpi, /**< LPI data */
    5195 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    5196 BMS_BLKMEM* blkmem, /**< block memory */
    5197 SCIP_Real* proofcoefs, /**< coefficients in the proof constraint */
    5198 SCIP_Real* prooflhs, /**< lhs of the proof constraint */
    5199 SCIP_Real* proofactivity, /**< maximal activity of the proof constraint */
    5200 SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
    5201 SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
    5202 int* lbchginfoposs, /**< positions of currently active lower bound change information in variables' arrays */
    5203 int* ubchginfoposs, /**< positions of currently active upper bound change information in variables' arrays */
    5204 int* iterations, /**< pointer to store the total number of LP iterations used */
    5205 SCIP_Bool marklpunsolved, /**< whether LP should be marked unsolved after analysis (needed for strong branching) */
    5206 SCIP_Bool* dualproofsuccess, /**< pointer to store success result of dual proof analysis */
    5207 SCIP_Bool* valid /**< pointer to store whether the result is still a valid proof */
    5208 )
    5209{
    5210 SCIP_LPBDCHGS* oldlpbdchgs;
    5211 SCIP_LPBDCHGS* relaxedlpbdchgs;
    5212 SCIP_Bool solvelp;
    5213 SCIP_Bool resolve;
    5214 int ncols;
    5215
    5216 assert(set != NULL);
    5217
    5218 /* get number of columns in the LP */
    5219 ncols = SCIPlpGetNCols(lp);
    5220
    5221 /* get temporary memory for remembering bound changes on LPI columns */
    5222 SCIP_CALL( lpbdchgsCreate(&oldlpbdchgs, set, ncols) );
    5223 SCIP_CALL( lpbdchgsCreate(&relaxedlpbdchgs, set, ncols) );
    5224
    5225 /* undo as many bound changes as possible with the current LP solution */
    5226 resolve = FALSE;
    5227 if( (*valid) )
    5228 {
    5229 int currentdepth;
    5230 currentdepth = SCIPtreeGetCurrentDepth(tree);
    5231
    5232 if( SCIPlpiIsPrimalInfeasible(lpi) )
    5233 {
    5234 SCIP_CALL( undoBdchgsDualfarkas(set, transprob, lp, currentdepth, curvarlbs, curvarubs, lbchginfoposs, \
    5235 ubchginfoposs, oldlpbdchgs, relaxedlpbdchgs, valid, &resolve, proofcoefs, *prooflhs, proofactivity) );
    5236 }
    5237 else
    5238 {
    5239 assert(SCIPlpiIsDualFeasible(lpi) || SCIPlpiIsObjlimExc(lpi));
    5240 SCIP_CALL( undoBdchgsDualsol(set, transprob, lp, currentdepth, curvarlbs, curvarubs, lbchginfoposs, ubchginfoposs, \
    5241 oldlpbdchgs, relaxedlpbdchgs, valid, &resolve, proofcoefs, *prooflhs, proofactivity) );
    5242 }
    5243 }
    5244
    5245 /* check if we want to solve the LP */
    5246 assert(SCIPprobAllColsInLP(transprob, set, lp));
    5247 solvelp = (set->conf_maxlploops != 0 && set->conf_lpiterations != 0);
    5248
    5249 if( (*valid) && resolve && solvelp )
    5250 {
    5251 SCIP_RETCODE retcode;
    5252 SCIP_ROW** rows;
    5253 int* sidechginds;
    5254 SCIP_Real* sidechgoldlhss;
    5255 SCIP_Real* sidechgoldrhss;
    5256 SCIP_Real* sidechgnewlhss;
    5257 SCIP_Real* sidechgnewrhss;
    5258 SCIP_Real lpiinfinity;
    5259 SCIP_Bool globalinfeasible;
    5260 int maxlploops;
    5261 int lpiterations;
    5262 int sidechgssize;
    5263 int nsidechgs;
    5264 int nrows;
    5265 int nloops;
    5266 int r;
    5267
    5268 /* get infinity value of LP solver */
    5269 lpiinfinity = SCIPlpiInfinity(lpi);
    5270
    5271 /* temporarily disable objective limit and install an iteration limit */
    5272 maxlploops = (set->conf_maxlploops >= 0 ? set->conf_maxlploops : INT_MAX);
    5273 lpiterations = (set->conf_lpiterations >= 0 ? set->conf_lpiterations : INT_MAX);
    5274 SCIP_CALL( SCIPlpiSetRealpar(lpi, SCIP_LPPAR_OBJLIM, lpiinfinity) );
    5275 SCIP_CALL( SCIPlpiSetIntpar(lpi, SCIP_LPPAR_LPITLIM, lpiterations) );
    5276
    5277 /* get LP rows */
    5278 rows = SCIPlpGetRows(lp);
    5279 nrows = SCIPlpGetNRows(lp);
    5280 assert(nrows == 0 || rows != NULL);
    5281
    5282 /* get temporary memory for remembering side changes on LPI rows */
    5283 SCIP_CALL( SCIPsetAllocBufferArray(set, &sidechginds, nrows) );
    5284 SCIP_CALL( SCIPsetAllocBufferArray(set, &sidechgoldlhss, nrows) );
    5285 SCIP_CALL( SCIPsetAllocBufferArray(set, &sidechgoldrhss, nrows) );
    5286 SCIP_CALL( SCIPsetAllocBufferArray(set, &sidechgnewlhss, nrows) );
    5287 SCIP_CALL( SCIPsetAllocBufferArray(set, &sidechgnewrhss, nrows) );
    5288 sidechgssize = nrows;
    5289 nsidechgs = 0;
    5290
    5291 /* remove all local rows by setting their sides to infinity;
    5292 * finite sides are only changed to near infinity, such that the row's sense in the LP solver
    5293 * is not affected (e.g. CPLEX cannot handle free rows)
    5294 */
    5295 for( r = 0; r < nrows; ++r )
    5296 {
    5297 assert(SCIProwGetLPPos(rows[r]) == r);
    5298
    5299 if( SCIProwIsLocal(rows[r]) )
    5300 {
    5301 SCIPsetDebugMsg(set, " -> removing local row <%s> [%g,%g]\n",
    5302 SCIProwGetName(rows[r]), SCIProwGetLhs(rows[r]), SCIProwGetRhs(rows[r]));
    5303 SCIP_CALL( addSideRemoval(set, rows[r], lpiinfinity, &sidechginds, &sidechgoldlhss, &sidechgoldrhss,
    5304 &sidechgnewlhss, &sidechgnewrhss, &sidechgssize, &nsidechgs) );
    5305 }
    5306 }
    5307
    5308 /* apply changes of local rows to the LP solver */
    5309 if( nsidechgs > 0 )
    5310 {
    5311 SCIP_CALL( SCIPlpiChgSides(lpi, nsidechgs, sidechginds, sidechgnewlhss, sidechgnewrhss) );
    5312 }
    5313
    5314 /* undo as many additional bound changes as possible by resolving the LP */
    5315 assert((*valid));
    5316 assert(resolve);
    5317 nloops = 0;
    5318 globalinfeasible = FALSE;
    5319 while( (*valid) && resolve && nloops < maxlploops )
    5320 {
    5321 int iter;
    5322
    5323 assert(!globalinfeasible);
    5324
    5325 nloops++;
    5326 resolve = FALSE;
    5327
    5328 SCIPsetDebugMsg(set, "infeasible LP conflict analysis loop %d (changed col bounds: %d)\n", nloops, relaxedlpbdchgs->nbdchgs);
    5329
    5330 /* apply bound changes to the LP solver */
    5331 assert(relaxedlpbdchgs->nbdchgs >= 0);
    5332 if( relaxedlpbdchgs->nbdchgs > 0 )
    5333 {
    5334 SCIPsetDebugMsg(set, " -> applying %d bound changes to the LP solver\n", relaxedlpbdchgs->nbdchgs);
    5335 SCIP_CALL( SCIPlpiChgBounds(lpi, relaxedlpbdchgs->nbdchgs, relaxedlpbdchgs->bdchginds, \
    5336 relaxedlpbdchgs->bdchglbs, relaxedlpbdchgs->bdchgubs) );
    5337
    5338 /* reset conflict LP bound change data structure */
    5339 lpbdchgsReset(relaxedlpbdchgs, ncols);
    5340 }
    5341
    5342 /* start LP timer */
    5344
    5345 /* resolve LP */
    5346 retcode = SCIPlpiSolveDual(lpi);
    5347
    5348 /* stop LP timer */
    5350
    5351 /* check return code of LP solving call */
    5352 if( retcode == SCIP_LPERROR )
    5353 {
    5354 (*valid) = FALSE;
    5355 break;
    5356 }
    5357 SCIP_CALL( retcode );
    5358
    5359 /* count number of LP iterations */
    5360 SCIP_CALL( SCIPlpiGetIterations(lpi, &iter) );
    5361 (*iterations) += iter;
    5362 stat->nconflictlps++;
    5363 stat->nconflictlpiterations += iter;
    5364 SCIPsetDebugMsg(set, " -> resolved LP in %d iterations (total: %" SCIP_LONGINT_FORMAT ") (infeasible:%u)\n",
    5366
    5367 /* evaluate result */
    5368 if( SCIPlpiIsDualFeasible(lpi) || SCIPlpiIsObjlimExc(lpi) )
    5369 {
    5370 SCIP_Real objval;
    5371
    5372 SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
    5373 (*valid) = (objval >= lp->lpiobjlim && !SCIPlpDivingObjChanged(lp));
    5374 }
    5375 else
    5376 (*valid) = SCIPlpiIsPrimalInfeasible(lpi);
    5377
    5378 if( (*valid) )
    5379 {
    5380 int currentdepth;
    5381 currentdepth = SCIPtreeGetCurrentDepth(tree);
    5382
    5383 /* undo additional bound changes */
    5384 if( SCIPlpiIsPrimalInfeasible(lpi) )
    5385 {
    5386 SCIP_AGGRROW* farkasrow;
    5387 int* inds;
    5388 int validdepth;
    5389 int nnz;
    5390 int v;
    5391
    5392#ifndef NDEBUG
    5393 SCIP_VAR** vars = SCIPprobGetVars(transprob);
    5394#endif
    5395
    5396 SCIP_CALL( SCIPaggrRowCreate(set->scip, &farkasrow) );
    5397
    5398 /* the original LP exceeds the current cutoff bound, thus, we have not constructed the Farkas proof */
    5399 SCIP_CALL( SCIPgetFarkasProof(set, transprob, lp, lpi, tree, farkasrow, proofactivity, &validdepth,
    5400 curvarlbs, curvarubs, valid) );
    5401
    5402 /* the constructed Farkas proof is not valid, we need to break here */
    5403 if( !(*valid) )
    5404 {
    5405 SCIPaggrRowFree(set->scip, &farkasrow);
    5406 break;
    5407 }
    5408
    5409 /* start dual proof analysis */
    5410 if( set->conf_useinflp == 'd' || set->conf_useinflp == 'b' )
    5411 {
    5412 /* change the conflict type */
    5413 SCIP_Bool oldusescutoff = conflict->conflictset->usescutoffbound;
    5414 SCIP_CONFTYPE oldconftype = conflict->conflictset->conflicttype;
    5415 conflict->conflictset->usescutoffbound = FALSE;
    5417
    5418 /* start dual proof analysis */
    5419 SCIP_CALL( SCIPconflictAnalyzeDualProof(conflict, set, stat, eventfilter, blkmem, origprob, transprob, tree, reopt,
    5420 lp, farkasrow, validdepth, curvarlbs, curvarubs, FALSE, &globalinfeasible, dualproofsuccess) );
    5421
    5422 conflict->conflictset->usescutoffbound = oldusescutoff;
    5423 conflict->conflictset->conflicttype = oldconftype;
    5424 }
    5425
    5426 /* todo: in theory, we could apply conflict graph analysis for locally valid proofs, too, but this needs to be implemented */
    5427 if( globalinfeasible || validdepth > SCIPtreeGetEffectiveRootDepth(tree) )
    5428 {
    5429 SCIPaggrRowFree(set->scip, &farkasrow);
    5430 goto TERMINATE;
    5431 }
    5432
    5433 BMSclearMemoryArray(proofcoefs, SCIPprobGetNVars(transprob));
    5434 (*prooflhs) = -SCIPaggrRowGetRhs(farkasrow);
    5435 (*proofactivity) = -(*proofactivity);
    5436
    5437 inds = SCIPaggrRowGetInds(farkasrow);
    5438 nnz = SCIPaggrRowGetNNz(farkasrow);
    5439
    5440 for( v = 0; v < nnz; v++ )
    5441 {
    5442 int i = inds[v];
    5443
    5444 assert(SCIPvarGetProbindex(vars[i]) == inds[v]);
    5445
    5446 proofcoefs[i] = -SCIPaggrRowGetProbvarValue(farkasrow, i);
    5447 }
    5448
    5449 /* free aggregation rows */
    5450 SCIPaggrRowFree(set->scip, &farkasrow);
    5451
    5452 SCIP_CALL( undoBdchgsDualfarkas(set, transprob, lp, currentdepth, curvarlbs, curvarubs, lbchginfoposs, \
    5453 ubchginfoposs, oldlpbdchgs, relaxedlpbdchgs, valid, &resolve, proofcoefs, (*prooflhs), proofactivity) );
    5454 }
    5455 else
    5456 {
    5457 SCIP_AGGRROW* proofrow;
    5458 int* inds;
    5459 int validdepth;
    5460 int nnz;
    5461 int v;
    5462
    5463#ifndef NDEBUG
    5464 SCIP_VAR** vars = SCIPprobGetVars(transprob);
    5465#endif
    5466
    5467 assert(SCIPlpiIsDualFeasible(lpi) || SCIPlpiIsObjlimExc(lpi));
    5468
    5469 SCIP_CALL( SCIPaggrRowCreate(set->scip, &proofrow) );
    5470
    5471 SCIP_CALL( SCIPgetDualProof(set, transprob, lp, lpi, tree, proofrow, proofactivity, &validdepth,
    5472 curvarlbs, curvarubs, valid) );
    5473
    5474 /* the constructed dual proof is not valid, we need to break here */
    5475 if( !(*valid) || validdepth > SCIPtreeGetEffectiveRootDepth(tree) )
    5476 {
    5477 SCIPaggrRowFree(set->scip, &proofrow);
    5478 break;
    5479 }
    5480 /* in contrast to the infeasible case we don't want to analyze the (probably identical) proof again. */
    5481
    5482 BMSclearMemoryArray(proofcoefs, SCIPprobGetNVars(transprob));
    5483 (*prooflhs) = -SCIPaggrRowGetRhs(proofrow);
    5484 (*proofactivity) = -(*proofactivity);
    5485
    5486 inds = SCIPaggrRowGetInds(proofrow);
    5487 nnz = SCIPaggrRowGetNNz(proofrow);
    5488
    5489 for( v = 0; v < nnz; v++ )
    5490 {
    5491 int i = inds[v];
    5492
    5493 assert(SCIPvarGetProbindex(vars[i]) == inds[v]);
    5494
    5495 proofcoefs[i] = -SCIPaggrRowGetProbvarValue(proofrow, i);
    5496 }
    5497
    5498 /* free aggregation rows */
    5499 SCIPaggrRowFree(set->scip, &proofrow);
    5500
    5501 SCIP_CALL( undoBdchgsDualsol(set, transprob, lp, currentdepth, curvarlbs, curvarubs, lbchginfoposs, \
    5502 ubchginfoposs, oldlpbdchgs, relaxedlpbdchgs, valid, &resolve, proofcoefs, *prooflhs, proofactivity) );
    5503 }
    5504 }
    5505 assert(!resolve || (*valid));
    5506 assert(!resolve || relaxedlpbdchgs->nbdchgs > 0);
    5507 SCIPsetDebugMsg(set, " -> finished infeasible LP conflict analysis loop %d (iter: %d, nbdchgs: %d)\n",
    5508 nloops, iter, relaxedlpbdchgs->nbdchgs);
    5509 }
    5510
    5511 SCIPsetDebugMsg(set, "finished undoing bound changes after %d loops (valid=%u, nbdchgs: %d)\n",
    5512 nloops, (*valid), oldlpbdchgs->nbdchgs);
    5513
    5514 TERMINATE:
    5515 /* reset variables to local bounds */
    5516 if( oldlpbdchgs->nbdchgs > 0 )
    5517 {
    5518 SCIP_CALL( SCIPlpiChgBounds(lpi, oldlpbdchgs->nbdchgs, oldlpbdchgs->bdchginds, oldlpbdchgs->bdchglbs, oldlpbdchgs->bdchgubs) );
    5519 }
    5520
    5521 /* reset changes of local rows */
    5522 if( nsidechgs > 0 )
    5523 {
    5524 SCIP_CALL( SCIPlpiChgSides(lpi, nsidechgs, sidechginds, sidechgoldlhss, sidechgoldrhss) );
    5525 }
    5526
    5527 /* mark the LP unsolved */
    5528 if( oldlpbdchgs->nbdchgs > 0 || nsidechgs > 0 )
    5529 {
    5530 /* The LPI data are out of sync with LP data. Thus, the LP should be marked
    5531 * unsolved. However, for strong branching calls, the LP has to have status 'solved'; in
    5532 * this case, marklpunsolved is FALSE and synchronization is performed later. */
    5533 if( marklpunsolved )
    5534 {
    5535 lp->solved = FALSE;
    5536 lp->primalfeasible = FALSE;
    5537 lp->primalchecked = FALSE;
    5538 lp->dualfeasible = FALSE;
    5539 lp->dualchecked = FALSE;
    5540 lp->lpobjval = SCIP_INVALID;
    5542 }
    5543 }
    5544
    5545 /* reinstall old objective and iteration limits in LP solver */
    5548
    5549 /* free temporary memory */
    5550 SCIPsetFreeBufferArray(set, &sidechgnewrhss);
    5551 SCIPsetFreeBufferArray(set, &sidechgnewlhss);
    5552 SCIPsetFreeBufferArray(set, &sidechgoldrhss);
    5553 SCIPsetFreeBufferArray(set, &sidechgoldlhss);
    5554 SCIPsetFreeBufferArray(set, &sidechginds);
    5555 }
    5556
    5557 /* free temporary memory */
    5558 lpbdchgsFree(&relaxedlpbdchgs, set);
    5559 lpbdchgsFree(&oldlpbdchgs, set);
    5560
    5561 return SCIP_OKAY;
    5562}
    5563
    5564/** analyzes conflicting bound changes that were added with calls to SCIPconflictAddBound(), and on success, calls the
    5565 * conflict handlers to create a conflict constraint out of the resulting conflict set;
    5566 * updates statistics for propagation conflict analysis
    5567 */
    5569 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    5570 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
    5571 SCIP_SET* set, /**< global SCIP settings */
    5572 SCIP_STAT* stat, /**< problem statistics */
    5573 SCIP_PROB* prob, /**< problem data */
    5574 SCIP_TREE* tree, /**< branch and bound tree */
    5575 int validdepth, /**< minimal depth level at which the initial conflict set is valid */
    5576 SCIP_Bool* success /**< pointer to store whether a conflict constraint was created, or NULL */
    5577 )
    5578{
    5579 int nconss;
    5580 int nliterals;
    5581 int nreconvconss;
    5582 int nreconvliterals;
    5583
    5584 assert(conflict != NULL);
    5585 assert(conflict->conflictset != NULL);
    5586 assert(set != NULL);
    5587 assert(prob != NULL);
    5588
    5589 if( success != NULL )
    5590 *success = FALSE;
    5591
    5592 /* check if the conflict analysis is applicable */
    5594 return SCIP_OKAY;
    5595
    5596 /* check, if the conflict set will get too large with high probability */
    5597 if( conflict->conflictset->nbdchginfos + SCIPpqueueNElems(conflict->bdchgqueue)
    5598 + SCIPpqueueNElems(conflict->forcedbdchgqueue) >= 2*conflictCalcMaxsize(set, prob) )
    5599 return SCIP_OKAY;
    5600
    5601 SCIPsetDebugMsg(set, "analyzing conflict after infeasible propagation in depth %d\n", SCIPtreeGetCurrentDepth(tree));
    5602
    5603 /* start timing */
    5605
    5606 conflict->npropcalls++;
    5607
    5608 /* setting this to true adds bound changes only to the conflict graph bdchg queue */
    5609 conflict->bdchgonlyconfqueue = TRUE;
    5610
    5611 /* analyze the conflict set, and create a conflict constraint on success */
    5612 SCIP_CALL( conflictAnalyze(conflict, blkmem, set, stat, prob, tree, FALSE, validdepth, TRUE, &nconss, &nliterals, \
    5613 &nreconvconss, &nreconvliterals) );
    5614 conflict->npropsuccess += (nconss > 0 ? 1 : 0);
    5615 conflict->npropconfconss += nconss;
    5616 conflict->npropconfliterals += nliterals;
    5617 conflict->npropreconvconss += nreconvconss;
    5618 conflict->npropreconvliterals += nreconvliterals;
    5619 conflict->bdchgonlyconfqueue = FALSE;
    5620
    5621 if( success != NULL )
    5622 *success = (nconss > 0);
    5623
    5624 /* stop timing */
    5625 SCIPclockStop(conflict->propanalyzetime, set);
    5626
    5627 return SCIP_OKAY;
    5628}
    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 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)
    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 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:308
    #define SCIPdebugCheckConflictFrontier(blkmem, set, node, bdchginfo, bdchginfos, relaxedbds, nliterals, bdchgqueue, forcedbdchgqueue)
    Definition: debug.h:309
    #define NULL
    Definition: def.h:255
    #define SCIP_MAXSTRLEN
    Definition: def.h:276
    #define SCIP_Longint
    Definition: def.h:148
    #define SCIP_REAL_MAX
    Definition: def.h:165
    #define SCIP_INVALID
    Definition: def.h:185
    #define SCIP_Bool
    Definition: def.h:98
    #define MIN(x, y)
    Definition: def.h:231
    #define SCIP_ALLOC(x)
    Definition: def.h:373
    #define SCIP_Real
    Definition: def.h:163
    #define TRUE
    Definition: def.h:100
    #define FALSE
    Definition: def.h:101
    #define MAX(x, y)
    Definition: def.h:227
    #define SCIP_LONGINT_FORMAT
    Definition: def.h:155
    #define SCIPABORT()
    Definition: def.h:334
    #define SCIP_REAL_MIN
    Definition: def.h:166
    #define SCIP_CALL(x)
    Definition: def.h:362
    #define SCIP_CALL_FINALLY(x, y)
    Definition: def.h:404
    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:2668
    SCIP_Real SCIPaggrRowGetRhs(SCIP_AGGRROW *aggrrow)
    Definition: cuts.c:4068
    void SCIPaggrRowFree(SCIP *scip, SCIP_AGGRROW **aggrrow)
    Definition: cuts.c:2700
    int * SCIPaggrRowGetInds(SCIP_AGGRROW *aggrrow)
    Definition: cuts.c:4028
    int SCIPaggrRowGetNNz(SCIP_AGGRROW *aggrrow)
    Definition: cuts.c:4038
    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:24483
    SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
    Definition: var.c:23684
    SCIP_Bool SCIPbdchginfoIsRedundant(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:25058
    SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
    Definition: var.c:23643
    SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
    Definition: var.c:23479
    SCIP_Bool SCIPbdchgidxIsEarlier(SCIP_BDCHGIDX *bdchgidx1, SCIP_BDCHGIDX *bdchgidx2)
    Definition: var.c:24890
    SCIP_BDCHGIDX * SCIPbdchginfoGetIdx(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:24980
    SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
    Definition: var.c:23387
    int SCIPvarGetNLocksUpType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
    Definition: var.c:4386
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24269
    SCIP_PROP * SCIPbdchginfoGetInferProp(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:25014
    SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
    Definition: var.c:23454
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24143
    int SCIPbdchginfoGetDepth(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:24960
    int SCIPbdchginfoGetInferInfo(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:25025
    int SCIPvarGetIndex(SCIP_VAR *var)
    Definition: var.c:23653
    SCIP_CONS * SCIPbdchginfoGetInferCons(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:25002
    int SCIPbdchginfoGetPos(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:24970
    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:23663
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23268
    SCIP_VAR * SCIPbdchginfoGetVar(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:24930
    int SCIPvarGetNVubs(SCIP_VAR *var)
    Definition: var.c:24525
    SCIP_Real SCIPbdchginfoGetOldbound(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:24910
    SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
    Definition: var.c:23491
    SCIP_BOUNDTYPE SCIPbdchginfoGetInferBoundtype(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:25037
    SCIP_BDCHGINFO * SCIPvarGetBdchgInfo(SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
    Definition: var.c:22742
    SCIP_VAR ** SCIPvarGetMultaggrVars(SCIP_VAR *var)
    Definition: var.c:23807
    SCIP_Bool SCIPbdchginfoIsTighter(SCIP_BDCHGINFO *bdchginfo1, SCIP_BDCHGINFO *bdchginfo2)
    Definition: var.c:25083
    int SCIPvarGetMultaggrNVars(SCIP_VAR *var)
    Definition: var.c:23795
    int SCIPvarGetNCliques(SCIP_VAR *var, SCIP_Bool varfixing)
    Definition: var.c:24643
    SCIP_BOUNDCHGTYPE SCIPbdchginfoGetChgtype(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:24940
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24235
    SCIP_VAR * SCIPbdchginfoGetInferVar(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:24990
    SCIP_Bool SCIPbdchginfoHasInferenceReason(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:25069
    SCIP_Bool SCIPvarIsRelaxationOnly(SCIP_VAR *var)
    Definition: var.c:23601
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24121
    SCIP_BDCHGINFO * SCIPvarGetBdchgInfoLb(SCIP_VAR *var, int pos)
    Definition: var.c:24705
    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:24950
    SCIP_Real SCIPbdchginfoGetNewbound(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:24920
    int SCIPvarGetNLocksDownType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
    Definition: var.c:4328
    SCIP_BDCHGINFO * SCIPvarGetBdchgInfoUb(SCIP_VAR *var, int pos)
    Definition: var.c:24725
    SCIP_Real * SCIPvarGetMultaggrScalars(SCIP_VAR *var)
    Definition: var.c:23819
    SCIP_Bool SCIPvarIsInLP(SCIP_VAR *var)
    Definition: var.c:23707
    void SCIPsortedvecInsertIntPtrReal(int *intarray, void **ptrarray, SCIP_Real *realarray, int keyval, void *field1val, SCIP_Real field2val, int *len, int *pos)
    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:674
    void SCIPhistoryScaleVSIDS(SCIP_HISTORY *history, SCIP_Real scalar)
    Definition: history.c:649
    void SCIPhistoryIncVSIDS(SCIP_HISTORY *history, SCIP_BRANCHDIR dir, SCIP_Real weight)
    Definition: history.c:635
    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:678
    int SCIPparamGetInt(SCIP_PARAM *param)
    Definition: paramset.c:733
    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:3229
    SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6617
    SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:7017
    SCIP_Bool SCIPsetIsFeasLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6993
    SCIP_Bool SCIPsetIsFeasEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6945
    SCIP_Bool SCIPsetIsPositive(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6648
    SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6577
    SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6537
    SCIP_Bool SCIPsetIsFeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6969
    SCIP_Bool SCIPsetIsLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6557
    SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6515
    SCIP_Bool SCIPsetIsGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6597
    SCIP_Bool SCIPsetIsIntegral(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6670
    SCIP_Bool SCIPsetIsZero(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6637
    SCIP_Bool SCIPsetIsFeasGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:7041
    void SCIPsetSortConflicthdlrs(SCIP_SET *set)
    Definition: set.c:4308
    int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
    Definition: set.c:6080
    SCIP_Bool SCIPsetIsNegative(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6659
    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:135
    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:22616
    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:21104
    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:21240
    void SCIPvarAdjustLb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *lb)
    Definition: var.c:9911
    SCIP_Real SCIPvarGetLbLP(SCIP_VAR *var, SCIP_SET *set)
    Definition: var.c:18569
    SCIP_RETCODE SCIPvarScaleVSIDS(SCIP_VAR *var, SCIP_Real scalar)
    Definition: var.c:21190
    SCIP_Real SCIPvarGetUbLP(SCIP_VAR *var, SCIP_SET *set)
    Definition: var.c:18639
    int SCIPbdchgidxGetPos(SCIP_BDCHGIDX *bdchgidx)
    Definition: var.c:24850
    SCIP_RETCODE SCIPbdchginfoCreate(SCIP_BDCHGINFO **bdchginfo, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_Real oldbound, SCIP_Real newbound)
    Definition: var.c:22586
    SCIP_RETCODE SCIPvarGetProbvarSum(SCIP_VAR **var, SCIP_SET *set, SCIP_Real *scalar, SCIP_Real *constant)
    Definition: var.c:18076
    void SCIPvarAdjustUb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *ub)
    Definition: var.c:9962
    SCIP_Real SCIPbdchginfoGetRelaxedBound(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:25049
    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)