Scippy

    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-2025 Zuse Institute Berlin (ZIB) */
    7/* */
    8/* Licensed under the Apache License, Version 2.0 (the "License"); */
    9/* you may not use this file except in compliance with the License. */
    10/* You may obtain a copy of the License at */
    11/* */
    12/* http://www.apache.org/licenses/LICENSE-2.0 */
    13/* */
    14/* Unless required by applicable law or agreed to in writing, software */
    15/* distributed under the License is distributed on an "AS IS" BASIS, */
    16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
    17/* See the License for the specific language governing permissions and */
    18/* limitations under the License. */
    19/* */
    20/* You should have received a copy of the Apache-2.0 license */
    21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
    22/* */
    23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    24
    25/**@file 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 confsortvals[k] = confsortvals[i];
    2918 ++i;
    2919 }
    2920 else
    2921 {
    2922 assert(confsortvals[k] == confsortvals[i]);
    2923
    2924 /* both bound change are equivalent; hence, keep the worse relaxed bound and remove one of them */
    2925 confrelaxedbds[k] = (confsortvals[k] % 2 == 0) ? MAX(confrelaxedbds[k], confrelaxedbds[i]) : MIN(confrelaxedbds[k], confrelaxedbds[i]);
    2926 ++i;
    2927 }
    2928 }
    2929 else
    2930 {
    2931 /* all bound change infos must be valid */
    2932 assert(!bdchginfoIsInvalid(conflict, confbdchginfos[k]));
    2933
    2934 ++k;
    2935 /* move next comparison element to the correct position */
    2936 if( k != i )
    2937 {
    2938 confbdchginfos[k] = confbdchginfos[i];
    2939 confrelaxedbds[k] = confrelaxedbds[i];
    2940 confsortvals[k] = confsortvals[i];
    2941 }
    2942 ++i;
    2943 }
    2944 }
    2945 /* last bound change infos must also be valid */
    2946 assert(!bdchginfoIsInvalid(conflict, confbdchginfos[k]));
    2947 /* the number of bound change infos cannot be decreased, it would mean that the conflict set was not merged
    2948 * before
    2949 */
    2950 assert(conflictset->nbdchginfos <= k + 1 );
    2951 assert(k + 1 <= confnbdchginfos);
    2952
    2953 conflictset->nbdchginfos = k + 1;
    2954 }
    2955
    2956 return SCIP_OKAY;
    2957}
    2958
    2959/** removes and returns next conflict analysis candidate from the candidate queue */
    2960static
    2962 SCIP_CONFLICT* conflict /**< conflict analysis data */
    2963 )
    2964{
    2965 SCIP_BDCHGINFO* bdchginfo;
    2966 SCIP_VAR* var;
    2967
    2968 assert(conflict != NULL);
    2969
    2970 if( SCIPpqueueNElems(conflict->forcedbdchgqueue) > 0 )
    2971 bdchginfo = (SCIP_BDCHGINFO*)(SCIPpqueueRemove(conflict->forcedbdchgqueue));
    2972 else
    2973 bdchginfo = (SCIP_BDCHGINFO*)(SCIPpqueueRemove(conflict->bdchgqueue));
    2974
    2975 assert(!SCIPbdchginfoIsRedundant(bdchginfo));
    2976
    2977 /* if we have a candidate this one should be valid for the current conflict analysis */
    2978 assert(!bdchginfoIsInvalid(conflict, bdchginfo));
    2979
    2980 /* mark the bound change to be no longer in the conflict (it will be either added again to the conflict set or
    2981 * replaced by resolving, which might add a weaker change on the same bound to the queue)
    2982 */
    2983 var = SCIPbdchginfoGetVar(bdchginfo);
    2985 {
    2986 var->conflictlbcount = 0;
    2988 }
    2989 else
    2990 {
    2991 assert(SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_UPPER);
    2992 var->conflictubcount = 0;
    2994 }
    2995
    2996#if defined(SCIP_CONFGRAPH) || defined(SCIP_CONFGRAPH_DOT)
    2997 confgraphSetCurrentBdchg(bdchginfo);
    2998#endif
    2999
    3000 return bdchginfo;
    3001}
    3002
    3003/** returns next conflict analysis candidate from the candidate queue without removing it */
    3004static
    3006 SCIP_CONFLICT* conflict /**< conflict analysis data */
    3007 )
    3008{
    3009 SCIP_BDCHGINFO* bdchginfo;
    3010
    3011 assert(conflict != NULL);
    3012
    3013 if( SCIPpqueueNElems(conflict->forcedbdchgqueue) > 0 )
    3014 {
    3015 /* get next potential candidate */
    3016 bdchginfo = (SCIP_BDCHGINFO*)(SCIPpqueueFirst(conflict->forcedbdchgqueue));
    3017
    3018 /* check if this candidate is valid */
    3019 if( bdchginfoIsInvalid(conflict, bdchginfo) )
    3020 {
    3021 SCIPdebugMessage("bound change info [%d:<%s> %s %g] is invalid -> pop it from the force queue\n", SCIPbdchginfoGetDepth(bdchginfo),
    3023 SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
    3024 SCIPbdchginfoGetNewbound(bdchginfo));
    3025
    3026 /* pop the invalid bound change info from the queue */
    3027 (void)(SCIPpqueueRemove(conflict->forcedbdchgqueue));
    3028
    3029 /* call method recursively to get next conflict analysis candidate */
    3030 bdchginfo = conflictFirstCand(conflict);
    3031 }
    3032 }
    3033 else
    3034 {
    3035 bdchginfo = (SCIP_BDCHGINFO*)(SCIPpqueueFirst(conflict->bdchgqueue));
    3036
    3037 /* check if this candidate is valid */
    3038 if( bdchginfo != NULL && bdchginfoIsInvalid(conflict, bdchginfo) )
    3039 {
    3040 SCIPdebugMessage("bound change info [%d:<%s> %s %g] is invalid -> pop it from the queue\n", SCIPbdchginfoGetDepth(bdchginfo),
    3042 SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
    3043 SCIPbdchginfoGetNewbound(bdchginfo));
    3044
    3045 /* pop the invalid bound change info from the queue */
    3046 (void)(SCIPpqueueRemove(conflict->bdchgqueue));
    3047
    3048 /* call method recursively to get next conflict analysis candidate */
    3049 bdchginfo = conflictFirstCand(conflict);
    3050 }
    3051 }
    3052 assert(bdchginfo == NULL || !SCIPbdchginfoIsRedundant(bdchginfo));
    3053
    3054 return bdchginfo;
    3055}
    3056
    3057/** adds the current conflict set (extended by all remaining bound changes in the queue) to the pool of conflict sets */
    3058static
    3060 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    3061 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
    3062 SCIP_SET* set, /**< global SCIP settings */
    3063 SCIP_STAT* stat, /**< dynamic problem statistics */
    3064 SCIP_TREE* tree, /**< branch and bound tree */
    3065 int validdepth, /**< minimal depth level at which the conflict set is valid */
    3066 SCIP_Bool diving, /**< are we in strong branching or diving mode? */
    3067 SCIP_Bool repropagate, /**< should the constraint trigger a repropagation? */
    3068 SCIP_Bool* success, /**< pointer to store whether the conflict set is valid */
    3069 int* nliterals /**< pointer to store the number of literals in the generated conflictset */
    3070 )
    3071{
    3072 SCIP_CONFLICTSET* conflictset;
    3073 SCIP_BDCHGINFO** bdchginfos;
    3074 int nbdchginfos;
    3075 int currentdepth;
    3076 int focusdepth;
    3077
    3078 assert(conflict != NULL);
    3079 assert(conflict->conflictset != NULL);
    3080 assert(set != NULL);
    3081 assert(stat != NULL);
    3082 assert(tree != NULL);
    3083 assert(success != NULL);
    3084 assert(nliterals != NULL);
    3085 assert(SCIPpqueueNElems(conflict->forcedbdchgqueue) == 0);
    3086
    3087 *success = FALSE;
    3088 *nliterals = 0;
    3089
    3090 /* check, whether local conflicts are allowed */
    3091 validdepth = MAX(validdepth, conflict->conflictset->validdepth);
    3092 if( !set->conf_allowlocal && validdepth > 0 )
    3093 return SCIP_OKAY;
    3094
    3095 focusdepth = SCIPtreeGetFocusDepth(tree);
    3096 currentdepth = SCIPtreeGetCurrentDepth(tree);
    3097 assert(currentdepth == tree->pathlen-1);
    3098 assert(focusdepth <= currentdepth);
    3099 assert(0 <= conflict->conflictset->validdepth && conflict->conflictset->validdepth <= currentdepth);
    3100 assert(0 <= validdepth && validdepth <= currentdepth);
    3101
    3102 /* get the elements of the bound change queue */
    3103 bdchginfos = (SCIP_BDCHGINFO**)SCIPpqueueElems(conflict->bdchgqueue);
    3104 nbdchginfos = SCIPpqueueNElems(conflict->bdchgqueue);
    3105
    3106 /* create a copy of the current conflict set, allocating memory for the additional elements of the queue */
    3107 SCIP_CALL( conflictsetCopy(&conflictset, blkmem, conflict->conflictset, nbdchginfos) );
    3108 conflictset->validdepth = validdepth;
    3109 conflictset->repropagate = repropagate;
    3110
    3111 /* add the valid queue elements to the conflict set */
    3112 SCIPsetDebugMsg(set, "adding %d variables from the queue as temporary conflict variables\n", nbdchginfos);
    3113 SCIP_CALL( conflictsetAddBounds(conflict, conflictset, blkmem, set, bdchginfos, nbdchginfos) );
    3114
    3115 /* calculate the depth, at which the conflictset should be inserted */
    3116 SCIP_CALL( conflictsetCalcInsertDepth(conflictset, set, tree) );
    3117 assert(conflictset->validdepth <= conflictset->insertdepth && conflictset->insertdepth <= currentdepth);
    3118 SCIPsetDebugMsg(set, " -> conflict with %d literals found at depth %d is active in depth %d and valid in depth %d\n",
    3119 conflictset->nbdchginfos, currentdepth, conflictset->insertdepth, conflictset->validdepth);
    3120
    3121 /* if all branching variables are in the conflict set, the conflict set is of no use;
    3122 * don't use conflict sets that are only valid in the probing path but not in the problem tree
    3123 */
    3124 if( (diving || conflictset->insertdepth < currentdepth) && conflictset->insertdepth <= focusdepth )
    3125 {
    3126 /* if the conflict should not be located only in the subtree where it is useful, put it to its valid depth level */
    3127 if( !set->conf_settlelocal )
    3128 conflictset->insertdepth = conflictset->validdepth;
    3129
    3130 *nliterals = conflictset->nbdchginfos;
    3131 SCIPsetDebugMsg(set, " -> final conflict set has %d literals\n", *nliterals);
    3132
    3133 /* check conflict set on debugging solution */
    3134 SCIP_CALL( SCIPdebugCheckConflict(blkmem, set, tree->path[validdepth], \
    3135 conflictset->bdchginfos, conflictset->relaxedbds, conflictset->nbdchginfos) ); /*lint !e506 !e774*/
    3136
    3137 /* move conflictset to the conflictset storage */
    3138 SCIP_CALL( conflictInsertConflictset(conflict, blkmem, set, &conflictset) );
    3139 *success = TRUE;
    3140 }
    3141 else
    3142 {
    3143 /* free the temporary conflict set */
    3144 SCIPconflictsetFree(&conflictset, blkmem);
    3145 }
    3146
    3147 return SCIP_OKAY;
    3148}
    3149
    3150/** tries to resolve given bound change
    3151 * - resolutions on local constraints are only applied, if the constraint is valid at the
    3152 * current minimal valid depth level, because this depth level is the topmost level to add the conflict
    3153 * constraint to anyways
    3154 *
    3155 * @note it is sufficient to explain the relaxed bound change
    3156 */
    3157static
    3159 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    3160 SCIP_SET* set, /**< global SCIP settings */
    3161 SCIP_BDCHGINFO* bdchginfo, /**< bound change to resolve */
    3162 SCIP_Real relaxedbd, /**< the relaxed bound */
    3163 int validdepth, /**< minimal depth level at which the conflict is valid */
    3164 SCIP_Bool* resolved /**< pointer to store whether the bound change was resolved */
    3165 )
    3166{
    3167 SCIP_VAR* actvar;
    3168 SCIP_CONS* infercons;
    3169 SCIP_PROP* inferprop;
    3170 SCIP_RESULT result;
    3171
    3172#ifndef NDEBUG
    3173 int nforcedbdchgqueue;
    3174 int nbdchgqueue;
    3175
    3176 /* store the current size of the conflict queues */
    3177 assert(conflict != NULL);
    3178 nforcedbdchgqueue = SCIPpqueueNElems(conflict->forcedbdchgqueue);
    3179 nbdchgqueue = SCIPpqueueNElems(conflict->bdchgqueue);
    3180#else
    3181 assert(conflict != NULL);
    3182#endif
    3183
    3184 assert(resolved != NULL);
    3185 assert(!SCIPbdchginfoIsRedundant(bdchginfo));
    3186
    3187 *resolved = FALSE;
    3188
    3189 actvar = SCIPbdchginfoGetVar(bdchginfo);
    3190 assert(actvar != NULL);
    3191 assert(SCIPvarIsActive(actvar));
    3192
    3193#ifdef SCIP_DEBUG
    3194 {
    3195 int i;
    3196 SCIPsetDebugMsg(set, "processing next conflicting bound (depth: %d, valid depth: %d, bdchgtype: %s [%s], vartype: %d): [<%s> %s %g(%g)]\n",
    3197 SCIPbdchginfoGetDepth(bdchginfo), validdepth,
    3199 : SCIPbdchginfoGetChgtype(bdchginfo) == SCIP_BOUNDCHGTYPE_CONSINFER ? "cons" : "prop",
    3203 : SCIPbdchginfoGetInferProp(bdchginfo) == NULL ? "-"
    3205 SCIPvarGetType(actvar), SCIPvarGetName(actvar),
    3206 SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
    3207 SCIPbdchginfoGetNewbound(bdchginfo), relaxedbd);
    3208 SCIPsetDebugMsg(set, " - conflict set :");
    3209
    3210 for( i = 0; i < conflict->conflictset->nbdchginfos; ++i )
    3211 {
    3212 SCIPsetDebugMsgPrint(set, " [%d:<%s> %s %g(%g)]", SCIPbdchginfoGetDepth(conflict->conflictset->bdchginfos[i]),
    3216 }
    3218 SCIPsetDebugMsg(set, " - forced candidates :");
    3219
    3220 for( i = 0; i < SCIPpqueueNElems(conflict->forcedbdchgqueue); ++i )
    3221 {
    3224 bdchginfoIsInvalid(conflict, info) ? "<!>" : SCIPbdchginfoGetBoundtype(info) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
    3226 }
    3228 SCIPsetDebugMsg(set, " - optional candidates:");
    3229
    3230 for( i = 0; i < SCIPpqueueNElems(conflict->bdchgqueue); ++i )
    3231 {
    3232 SCIP_BDCHGINFO* info = (SCIP_BDCHGINFO*)(SCIPpqueueElems(conflict->bdchgqueue)[i]);
    3234 bdchginfoIsInvalid(conflict, info) ? "<!>" : SCIPbdchginfoGetBoundtype(info) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
    3236 }
    3238 }
    3239#endif
    3240
    3241 /* check, if the bound change can and should be resolved:
    3242 * - resolutions on local constraints should only be applied, if the constraint is valid at the
    3243 * current minimal valid depth level (which is initialized with the valid depth level of the initial
    3244 * conflict set), because this depth level is the topmost level to add the conflict constraint to anyways
    3245 */
    3246 switch( SCIPbdchginfoGetChgtype(bdchginfo) )
    3247 {
    3249 infercons = SCIPbdchginfoGetInferCons(bdchginfo);
    3250 assert(infercons != NULL);
    3251
    3252 if( SCIPconsIsGlobal(infercons) || SCIPconsGetValidDepth(infercons) <= validdepth )
    3253 {
    3254 SCIP_VAR* infervar;
    3255 int inferinfo;
    3256 SCIP_BOUNDTYPE inferboundtype;
    3257 SCIP_BDCHGIDX* bdchgidx;
    3258
    3259 /* resolve bound change by asking the constraint that inferred the bound to put all bounds that were
    3260 * the reasons for the conflicting bound change on the priority queue
    3261 */
    3262 infervar = SCIPbdchginfoGetInferVar(bdchginfo);
    3263 inferinfo = SCIPbdchginfoGetInferInfo(bdchginfo);
    3264 inferboundtype = SCIPbdchginfoGetInferBoundtype(bdchginfo);
    3265 bdchgidx = SCIPbdchginfoGetIdx(bdchginfo);
    3266 assert(infervar != NULL);
    3267
    3268 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",
    3269 SCIPvarGetName(actvar),
    3270 SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
    3271 SCIPbdchginfoGetNewbound(bdchginfo), relaxedbd,
    3272 SCIPvarGetStatus(actvar), SCIPvarGetType(actvar),
    3273 SCIPbdchginfoGetDepth(bdchginfo), SCIPbdchginfoGetPos(bdchginfo),
    3274 SCIPvarGetName(infervar),
    3275 inferboundtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
    3276 SCIPgetVarBdAtIndex(set->scip, infervar, inferboundtype, bdchgidx, TRUE),
    3277 SCIPconsGetName(infercons),
    3278 SCIPconsIsGlobal(infercons) ? "global" : "local",
    3279 inferinfo);
    3280
    3281 /* in case the inference variables is not an active variables, we need to transform the relaxed bound */
    3282 if( actvar != infervar )
    3283 {
    3284 SCIP_VAR* var;
    3285 SCIP_Real scalar;
    3286 SCIP_Real constant;
    3287
    3290 || (SCIPvarGetStatus(infervar) == SCIP_VARSTATUS_MULTAGGR && SCIPvarGetMultaggrNVars(infervar) == 1));
    3291
    3292 scalar = 1.0;
    3293 constant = 0.0;
    3294
    3295 var = infervar;
    3296
    3297 /* transform given variable to active variable */
    3298 SCIP_CALL( SCIPvarGetProbvarSum(&var, set, &scalar, &constant) );
    3299 assert(var == actvar);
    3300
    3301 relaxedbd *= scalar;
    3302 relaxedbd += constant;
    3303 }
    3304
    3305 SCIP_CALL( SCIPconsResolvePropagation(infercons, set, infervar, inferinfo, inferboundtype, bdchgidx, relaxedbd, &result) );
    3306 *resolved = (result == SCIP_SUCCESS);
    3307 }
    3308 break;
    3309
    3311 inferprop = SCIPbdchginfoGetInferProp(bdchginfo);
    3312 if( inferprop != NULL )
    3313 {
    3314 SCIP_VAR* infervar;
    3315 int inferinfo;
    3316 SCIP_BOUNDTYPE inferboundtype;
    3317 SCIP_BDCHGIDX* bdchgidx;
    3318
    3319 /* resolve bound change by asking the propagator that inferred the bound to put all bounds that were
    3320 * the reasons for the conflicting bound change on the priority queue
    3321 */
    3322 infervar = SCIPbdchginfoGetInferVar(bdchginfo);
    3323 inferinfo = SCIPbdchginfoGetInferInfo(bdchginfo);
    3324 inferboundtype = SCIPbdchginfoGetInferBoundtype(bdchginfo);
    3325 bdchgidx = SCIPbdchginfoGetIdx(bdchginfo);
    3326 assert(infervar != NULL);
    3327
    3328 SCIPsetDebugMsg(set, "resolving bound <%s> %s %g(%g) [status:%d, depth:%d, pos:%d]: <%s> %s %g [prop:<%s>, info:%d]\n",
    3329 SCIPvarGetName(actvar),
    3330 SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
    3331 SCIPbdchginfoGetNewbound(bdchginfo), relaxedbd,
    3332 SCIPvarGetStatus(actvar), SCIPbdchginfoGetDepth(bdchginfo), SCIPbdchginfoGetPos(bdchginfo),
    3333 SCIPvarGetName(infervar),
    3334 inferboundtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
    3335 SCIPgetVarBdAtIndex(set->scip, infervar, inferboundtype, bdchgidx, TRUE),
    3336 SCIPpropGetName(inferprop), inferinfo);
    3337
    3338 SCIP_CALL( SCIPpropResolvePropagation(inferprop, set, infervar, inferinfo, inferboundtype, bdchgidx, relaxedbd, &result) );
    3339 *resolved = (result == SCIP_SUCCESS);
    3340 }
    3341 break;
    3342
    3344 assert(!(*resolved));
    3345 break;
    3346
    3347 default:
    3348 SCIPerrorMessage("invalid bound change type <%d>\n", SCIPbdchginfoGetChgtype(bdchginfo));
    3349 return SCIP_INVALIDDATA;
    3350 }
    3351
    3352 SCIPsetDebugMsg(set, "resolving status: %u\n", *resolved);
    3353
    3354#ifndef NDEBUG
    3355 /* subtract the size of the conflicq queues */
    3356 nforcedbdchgqueue -= SCIPpqueueNElems(conflict->forcedbdchgqueue);
    3357 nbdchgqueue -= SCIPpqueueNElems(conflict->bdchgqueue);
    3358
    3359 /* in case the bound change was not resolved, the conflict queues should have the same size (contents) */
    3360 assert((*resolved) || (nforcedbdchgqueue == 0 && nbdchgqueue == 0));
    3361#endif
    3362
    3363 return SCIP_OKAY;
    3364}
    3365
    3366/** clears the conflict queue and the current conflict set */
    3367static
    3369 SCIP_CONFLICT* conflict /**< conflict analysis data */
    3370 )
    3371{
    3372 assert(conflict != NULL);
    3373
    3374 SCIPpqueueClear(conflict->bdchgqueue);
    3376 conflictsetClear(conflict->conflictset);
    3377}
    3378
    3379
    3380/** clears the resolution conflict analysis queues and the bounds leading to conflict */
    3381static
    3383 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    3384 SCIP_SET* set, /**< global SCIP settings */
    3385 SCIP_PROB* prob /**< problem data */
    3386 )
    3387{
    3388 int nvars;
    3389 int i;
    3390
    3391 assert(conflict != NULL);
    3392 assert(set != NULL);
    3393 assert(prob != NULL);
    3394
    3395 if( !set->conf_usegenres )
    3396 return;
    3397
    3398 /* clear the resolution conflict analysis queues */
    3399 SCIPpqueueClear(conflict->resbdchgqueue);
    3400
    3401 /* reset the current lower and upper bounds leading to conflict */
    3402 nvars = SCIPprobGetNVars(prob);
    3403
    3404 /* allocate memory for the lower and upper bounds of variables used in the resolution conflict analysis */
    3405 if(conflict->conflictprobnvars < nvars)
    3406 {
    3407 conflict->conflictprobnvars = nvars;
    3408 BMSreallocMemoryArray(&conflict->conflictvarslbs, nvars);
    3409 BMSreallocMemoryArray(&conflict->conflictvarsubs, nvars);
    3410 }
    3411
    3412 for( i = 0; i < nvars; ++i )
    3413 {
    3414 conflict->conflictvarslbs[i] = SCIP_REAL_MIN;
    3415 conflict->conflictvarsubs[i] = SCIP_REAL_MAX;
    3416 }
    3417}
    3418
    3419/** initializes propagation and resolution conflict analysis by clearing the conflict candidate queues */
    3421 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    3422 SCIP_SET* set, /**< global SCIP settings */
    3423 SCIP_STAT* stat, /**< problem statistics */
    3424 SCIP_PROB* prob, /**< problem data */
    3425 SCIP_CONFTYPE conftype, /**< type of the conflict */
    3426 SCIP_Bool usescutoffbound /**< depends the conflict on a cutoff bound? */
    3427 )
    3428{
    3429 assert(conflict != NULL);
    3430 assert(set != NULL);
    3431 assert(stat != NULL);
    3432 assert(prob != NULL);
    3433
    3434 SCIPsetDebugMsg(set, "initializing conflict analysis\n");
    3435
    3436 /* clear the conflict candidate queue and the conflict set */
    3437 conflictClear(conflict);
    3438
    3439 /* clear the resolution conflict analysis queues and the bounds leading to conflict */
    3440 conflictClearResolution(conflict, set, prob);
    3441
    3442 /* set conflict type */
    3443 assert(conftype == SCIP_CONFTYPE_BNDEXCEEDING || conftype == SCIP_CONFTYPE_INFEASLP
    3444 || conftype == SCIP_CONFTYPE_PROPAGATION);
    3445 conflict->conflictset->conflicttype = conftype;
    3446 conflict->conflictrow->conflicttype = conftype;
    3447
    3448 /* set whether a cutoff bound is involved */
    3449 conflict->conflictset->usescutoffbound = usescutoffbound;
    3450
    3451 /* increase the conflict counter, such that binary variables of new conflict set and new conflict queue are labeled
    3452 * with this new counter
    3453 */
    3454 conflict->count++;
    3455 if( conflict->count == 0 ) /* make sure, 0 is not a valid conflict counter (may happen due to integer overflow) */
    3456 conflict->count = 1;
    3457
    3458 /* increase the conflict score weight for history updates of future conflict reasons */
    3459 if( stat->nnodes > stat->lastconflictnode )
    3460 {
    3461 assert(0.0 < set->conf_scorefac && set->conf_scorefac <= 1.0);
    3462 stat->vsidsweight /= set->conf_scorefac;
    3463 assert(stat->vsidsweight > 0.0);
    3464
    3465 /* if the conflict score for the next conflict exceeds 1000.0, rescale all history conflict scores */
    3466 if( stat->vsidsweight >= 1000.0 )
    3467 {
    3468 int v;
    3469
    3470 for( v = 0; v < prob->nvars; ++v )
    3471 {
    3472 SCIP_CALL( SCIPvarScaleVSIDS(prob->vars[v], 1.0/stat->vsidsweight) );
    3473 }
    3476 stat->vsidsweight = 1.0;
    3477 }
    3478 stat->lastconflictnode = stat->nnodes;
    3479 }
    3480
    3481#if defined(SCIP_CONFGRAPH) || defined(SCIP_CONFGRAPH_DOT)
    3482 confgraphFree();
    3483 SCIP_CALL( confgraphCreate(set, conflict) );
    3484#endif
    3485
    3486 return SCIP_OKAY;
    3487}
    3488
    3489/** convert variable and bound change to active variable */
    3490static
    3492 SCIP_VAR** var, /**< pointer to variable */
    3493 SCIP_SET* set, /**< global SCIP settings */
    3494 SCIP_BOUNDTYPE* boundtype, /**< pointer to type of bound that was changed: lower or upper bound */
    3495 SCIP_Real* bound /**< pointer to bound to convert, or NULL */
    3496 )
    3497{
    3498 SCIP_Real scalar;
    3499 SCIP_Real constant;
    3500
    3501 scalar = 1.0;
    3502 constant = 0.0;
    3503
    3504 /* transform given variable to active variable */
    3505 SCIP_CALL( SCIPvarGetProbvarSum(var, set, &scalar, &constant) );
    3506 assert(SCIPvarGetStatus(*var) == SCIP_VARSTATUS_FIXED || scalar != 0.0); /*lint !e777*/
    3507
    3509 return SCIP_OKAY;
    3510
    3511 /* if the scalar of the aggregation is negative, we have to switch the bound type */
    3512 if( scalar < 0.0 )
    3513 (*boundtype) = SCIPboundtypeOpposite(*boundtype);
    3514
    3515 if( bound != NULL )
    3516 {
    3517 (*bound) -= constant;
    3518 (*bound) /= scalar;
    3519 }
    3520
    3521 return SCIP_OKAY;
    3522}
    3523
    3524/** returns whether bound change has a valid reason that can be resolved in conflict analysis */
    3525static
    3527 SCIP_BDCHGINFO* bdchginfo /**< bound change information */
    3528 )
    3529{
    3530 assert(bdchginfo != NULL);
    3531 assert(!SCIPbdchginfoIsRedundant(bdchginfo));
    3532
    3535 && SCIPbdchginfoGetInferProp(bdchginfo) != NULL));
    3536}
    3537
    3538
    3539/** if only one conflicting bound change of the last depth level was used, and if this can be resolved,
    3540 * creates GRASP-like reconvergence conflict constraints in the conflict graph up to the branching variable of this
    3541 * depth level
    3542 */
    3543static
    3545 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    3546 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
    3547 SCIP_SET* set, /**< global SCIP settings */
    3548 SCIP_STAT* stat, /**< problem statistics */
    3549 SCIP_PROB* prob, /**< problem data */
    3550 SCIP_TREE* tree, /**< branch and bound tree */
    3551 SCIP_Bool diving, /**< are we in strong branching or diving mode? */
    3552 int validdepth, /**< minimal depth level at which the initial conflict set is valid */
    3553 SCIP_BDCHGINFO* firstuip, /**< first UIP of conflict graph */
    3554 int* nreconvconss, /**< pointer to store the number of generated reconvergence constraints */
    3555 int* nreconvliterals /**< pointer to store the number of literals generated reconvergence constraints */
    3556 )
    3557{
    3558 SCIP_BDCHGINFO* uip;
    3559 SCIP_CONFTYPE conftype;
    3560 SCIP_Bool usescutoffbound;
    3561 int firstuipdepth;
    3562 int focusdepth;
    3563 int currentdepth;
    3564 int maxvaliddepth;
    3565
    3566 assert(conflict != NULL);
    3567 assert(firstuip != NULL);
    3568 assert(nreconvconss != NULL);
    3569 assert(nreconvliterals != NULL);
    3570 assert(!SCIPbdchginfoIsRedundant(firstuip));
    3571
    3572 focusdepth = SCIPtreeGetFocusDepth(tree);
    3573 currentdepth = SCIPtreeGetCurrentDepth(tree);
    3574 assert(currentdepth == tree->pathlen-1);
    3575 assert(focusdepth <= currentdepth);
    3576
    3577 /* check, whether local constraints are allowed; however, don't generate reconvergence constraints that are only valid
    3578 * in the probing path and not in the problem tree (i.e. that exceed the focusdepth)
    3579 */
    3580 maxvaliddepth = (set->conf_allowlocal ? MIN(currentdepth-1, focusdepth) : 0);
    3581 if( validdepth > maxvaliddepth )
    3582 return SCIP_OKAY;
    3583
    3584 firstuipdepth = SCIPbdchginfoGetDepth(firstuip);
    3585
    3586 conftype = conflict->conflictset->conflicttype;
    3587 usescutoffbound = conflict->conflictset->usescutoffbound;
    3588
    3589 /* for each succeeding UIP pair of the last depth level, create one reconvergence constraint */
    3590 uip = firstuip;
    3591 while( uip != NULL && SCIPbdchginfoGetDepth(uip) == SCIPbdchginfoGetDepth(firstuip) && bdchginfoIsResolvable(uip) )
    3592 {
    3593 SCIP_BDCHGINFO* oppositeuip;
    3594 SCIP_BDCHGINFO* bdchginfo;
    3595 SCIP_BDCHGINFO* nextuip;
    3596 SCIP_VAR* uipvar;
    3597 SCIP_Real oppositeuipbound;
    3598 SCIP_BOUNDTYPE oppositeuipboundtype;
    3599 int nresolutions;
    3600
    3601 assert(!SCIPbdchginfoIsRedundant(uip));
    3602
    3603 SCIPsetDebugMsg(set, "creating reconvergence constraint for UIP <%s> %s %g in depth %d pos %d\n",
    3606
    3607 /* initialize conflict data */
    3608 SCIP_CALL( SCIPconflictInit(conflict, set, stat, prob, conftype, usescutoffbound) );
    3609
    3610 conflict->conflictset->conflicttype = conftype;
    3611 conflict->conflictset->usescutoffbound = usescutoffbound;
    3612
    3613 /* create a temporary bound change information for the negation of the UIP's bound change;
    3614 * this bound change information is freed in the SCIPconflictFlushConss() call;
    3615 * for reconvergence constraints for continuous variables we can only use the "negation" !(x <= u) == (x >= u);
    3616 * during conflict analysis, we treat a continuous bound "x >= u" in the conflict set as "x > u", and in the
    3617 * generated constraint this is negated again to "x <= u" which is correct.
    3618 */
    3619 uipvar = SCIPbdchginfoGetVar(uip);
    3620 oppositeuipboundtype = SCIPboundtypeOpposite(SCIPbdchginfoGetBoundtype(uip));
    3621 oppositeuipbound = SCIPbdchginfoGetNewbound(uip);
    3622 if( SCIPvarIsIntegral(uipvar) )
    3623 {
    3624 assert(SCIPsetIsIntegral(set, oppositeuipbound));
    3625 oppositeuipbound += (oppositeuipboundtype == SCIP_BOUNDTYPE_LOWER ? +1.0 : -1.0);
    3626 }
    3627 SCIP_CALL( conflictCreateTmpBdchginfo(conflict, blkmem, set, uipvar, oppositeuipboundtype, \
    3628 oppositeuipboundtype == SCIP_BOUNDTYPE_LOWER ? SCIP_REAL_MIN : SCIP_REAL_MAX, oppositeuipbound, &oppositeuip) );
    3629
    3630 /* put the negated UIP into the conflict set */
    3631 SCIP_CALL( conflictAddConflictBound(conflict, blkmem, set, oppositeuip, oppositeuipbound) );
    3632
    3633 /* put positive UIP into priority queue */
    3635
    3636 /* resolve the queue until the next UIP is reached */
    3637 bdchginfo = conflictFirstCand(conflict);
    3638 nextuip = NULL;
    3639 nresolutions = 0;
    3640 while( bdchginfo != NULL && validdepth <= maxvaliddepth )
    3641 {
    3642 SCIP_BDCHGINFO* nextbdchginfo;
    3643 SCIP_Real relaxedbd;
    3644 SCIP_Bool forceresolve;
    3645 int bdchgdepth;
    3646
    3647 /* check if the next bound change must be resolved in every case */
    3648 forceresolve = (SCIPpqueueNElems(conflict->forcedbdchgqueue) > 0);
    3649
    3650 /* remove currently processed candidate and get next conflicting bound from the conflict candidate queue before
    3651 * we remove the candidate we have to collect the relaxed bound since removing the candidate from the queue
    3652 * invalidates the relaxed bound
    3653 */
    3654 assert(bdchginfo == conflictFirstCand(conflict));
    3655 relaxedbd = SCIPbdchginfoGetRelaxedBound(bdchginfo);
    3656 bdchginfo = conflictRemoveCand(conflict);
    3657 nextbdchginfo = conflictFirstCand(conflict);
    3658 bdchgdepth = SCIPbdchginfoGetDepth(bdchginfo);
    3659 assert(bdchginfo != NULL);
    3660 assert(!SCIPbdchginfoIsRedundant(bdchginfo));
    3661 assert(nextbdchginfo == NULL || SCIPbdchginfoGetDepth(bdchginfo) >= SCIPbdchginfoGetDepth(nextbdchginfo)
    3662 || forceresolve);
    3663 assert(bdchgdepth <= firstuipdepth);
    3664
    3665 /* bound changes that are higher in the tree than the valid depth of the conflict can be ignored;
    3666 * multiple insertions of the same bound change can be ignored
    3667 */
    3668 if( bdchgdepth > validdepth && bdchginfo != nextbdchginfo )
    3669 {
    3670 SCIP_VAR* actvar;
    3671 SCIP_Bool resolved;
    3672
    3673 actvar = SCIPbdchginfoGetVar(bdchginfo);
    3674 assert(actvar != NULL);
    3675 assert(SCIPvarIsActive(actvar));
    3676
    3677 /* check if we have to resolve the bound change in this depth level
    3678 * - the starting uip has to be resolved
    3679 * - a bound change should be resolved, if it is in the fuip's depth level and not the
    3680 * next uip (i.e., if it is not the last bound change in the fuip's depth level)
    3681 * - a forced bound change must be resolved in any case
    3682 */
    3683 resolved = FALSE;
    3684 if( bdchginfo == uip
    3685 || (bdchgdepth == firstuipdepth
    3686 && nextbdchginfo != NULL
    3687 && SCIPbdchginfoGetDepth(nextbdchginfo) == bdchgdepth)
    3688 || forceresolve )
    3689 {
    3690 SCIP_CALL( conflictResolveBound(conflict, set, bdchginfo, relaxedbd, validdepth, &resolved) );
    3691 }
    3692
    3693 if( resolved )
    3694 nresolutions++;
    3695 else if( forceresolve )
    3696 {
    3697 /* variable cannot enter the conflict clause: we have to make the conflict clause local, s.t.
    3698 * the unresolved bound change is active in the whole sub tree of the conflict clause
    3699 */
    3700 assert(bdchgdepth >= validdepth);
    3701 validdepth = bdchgdepth;
    3702
    3703 SCIPsetDebugMsg(set, "couldn't resolve forced bound change on <%s> -> new valid depth: %d\n",
    3704 SCIPvarGetName(actvar), validdepth);
    3705 }
    3706 else if( bdchginfo != uip )
    3707 {
    3708 assert(conflict->conflictset != NULL);
    3709 assert(conflict->conflictset->nbdchginfos >= 1); /* starting UIP is already member of the conflict set */
    3710
    3711 /* if this is the first variable of the conflict set besides the current starting UIP, it is the next
    3712 * UIP (or the first unresolvable bound change)
    3713 */
    3714 if( bdchgdepth == firstuipdepth && conflict->conflictset->nbdchginfos == 1 )
    3715 {
    3716 assert(nextuip == NULL);
    3717 nextuip = bdchginfo;
    3718 }
    3719
    3720 /* put bound change into the conflict set */
    3721 SCIP_CALL( conflictAddConflictBound(conflict, blkmem, set, bdchginfo, relaxedbd) );
    3722 assert(conflict->conflictset->nbdchginfos >= 2);
    3723 }
    3724 else
    3725 assert(conflictFirstCand(conflict) == NULL); /* the starting UIP was not resolved */
    3726 }
    3727
    3728 /* get next conflicting bound from the conflict candidate queue (this does not need to be nextbdchginfo, because
    3729 * due to resolving the bound changes, a variable could be added to the queue which must be
    3730 * resolved before nextbdchginfo)
    3731 */
    3732 bdchginfo = conflictFirstCand(conflict);
    3733 }
    3734 assert(nextuip != uip);
    3735
    3736 /* if only one propagation was resolved, the reconvergence constraint is already member of the constraint set
    3737 * (it is exactly the constraint that produced the propagation)
    3738 */
    3739 if( nextuip != NULL && nresolutions >= 2 && bdchginfo == NULL && validdepth <= maxvaliddepth )
    3740 {
    3741 int nlits;
    3742 SCIP_Bool success;
    3743
    3744 assert(SCIPbdchginfoGetDepth(nextuip) == SCIPbdchginfoGetDepth(uip));
    3745
    3746 /* check conflict graph frontier on debugging solution */
    3747 SCIP_CALL( SCIPdebugCheckConflictFrontier(blkmem, set, tree->path[validdepth], \
    3748 bdchginfo, conflict->conflictset->bdchginfos, conflict->conflictset->relaxedbds, \
    3749 conflict->conflictset->nbdchginfos, conflict->bdchgqueue, conflict->forcedbdchgqueue) ); /*lint !e506 !e774*/
    3750
    3751 SCIPsetDebugMsg(set, "creating reconvergence constraint from UIP <%s> to UIP <%s> in depth %d with %d literals after %d resolutions\n",
    3753 SCIPbdchginfoGetDepth(uip), conflict->conflictset->nbdchginfos, nresolutions);
    3754
    3755 /* call the conflict handlers to create a conflict set */
    3756 SCIP_CALL( conflictAddConflictset(conflict, blkmem, set, stat, tree, validdepth, diving, FALSE, &success, &nlits) );
    3757 if( success )
    3758 {
    3759 (*nreconvconss)++;
    3760 (*nreconvliterals) += nlits;
    3761 }
    3762 }
    3763
    3764 /* clear the conflict candidate queue and the conflict set (to make sure, oppositeuip is not referenced anymore) */
    3765 conflictClear(conflict);
    3766
    3767 uip = nextuip;
    3768 }
    3769
    3770 conflict->conflictset->conflicttype = conftype;
    3771 conflict->conflictset->usescutoffbound = usescutoffbound;
    3772
    3773 return SCIP_OKAY;
    3774}
    3775
    3776/** analyzes conflicting bound changes that were added with calls to SCIPconflictAddBound() and
    3777 * SCIPconflictAddRelaxedBound(), and on success, calls the conflict handlers to create a conflict constraint out of
    3778 * the resulting conflict set; afterwards the conflict queue and the conflict set is cleared
    3779 */
    3781 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    3782 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
    3783 SCIP_SET* set, /**< global SCIP settings */
    3784 SCIP_STAT* stat, /**< problem statistics */
    3785 SCIP_PROB* prob, /**< problem data */
    3786 SCIP_TREE* tree, /**< branch and bound tree */
    3787 SCIP_Bool diving, /**< are we in strong branching or diving mode? */
    3788 int validdepth, /**< minimal depth level at which the initial conflict set is valid */
    3789 SCIP_Bool mustresolve, /**< should the conflict set only be used, if a resolution was applied? */
    3790 int* nconss, /**< pointer to store the number of generated conflict constraints */
    3791 int* nliterals, /**< pointer to store the number of literals in generated conflict constraints */
    3792 int* nreconvconss, /**< pointer to store the number of generated reconvergence constraints */
    3793 int* nreconvliterals /**< pointer to store the number of literals generated reconvergence constraints */
    3794 )
    3795{
    3796 SCIP_BDCHGINFO* bdchginfo;
    3797 SCIP_BDCHGINFO** firstuips;
    3798 SCIP_CONFTYPE conftype;
    3799 int nfirstuips;
    3800 int focusdepth;
    3801 int currentdepth;
    3802 int maxvaliddepth;
    3803 int resolvedepth;
    3804 int nresolutions;
    3805 int lastconsnresolutions;
    3806 int lastconsresoldepth;
    3807
    3808 assert(conflict != NULL);
    3809 assert(conflict->conflictset != NULL);
    3810 assert(conflict->conflictset->nbdchginfos >= 0);
    3811 assert(set != NULL);
    3812 assert(stat != NULL);
    3813 assert(0 <= validdepth && validdepth <= SCIPtreeGetCurrentDepth(tree));
    3814 assert(nconss != NULL);
    3815 assert(nliterals != NULL);
    3816 assert(nreconvconss != NULL);
    3817 assert(nreconvliterals != NULL);
    3818
    3819 focusdepth = SCIPtreeGetFocusDepth(tree);
    3820 currentdepth = SCIPtreeGetCurrentDepth(tree);
    3821 assert(currentdepth == tree->pathlen-1);
    3822 assert(focusdepth <= currentdepth);
    3823
    3824 resolvedepth = ((set->conf_fuiplevels >= 0 && set->conf_fuiplevels <= currentdepth)
    3825 ? currentdepth - set->conf_fuiplevels + 1 : 0);
    3826 assert(0 <= resolvedepth && resolvedepth <= currentdepth + 1);
    3827
    3828 /* if we must resolve at least one bound change, find the first UIP at least in the last depth level */
    3829 if( mustresolve )
    3830 resolvedepth = MIN(resolvedepth, currentdepth);
    3831
    3832 SCIPsetDebugMsg(set, "analyzing conflict with %d+%d conflict candidates and starting conflict set of size %d in depth %d (resolvedepth=%d)\n",
    3834 conflict->conflictset->nbdchginfos, currentdepth, resolvedepth);
    3835
    3836 *nconss = 0;
    3837 *nliterals = 0;
    3838 *nreconvconss = 0;
    3839 *nreconvliterals = 0;
    3840
    3841 /* check, whether local conflicts are allowed; however, don't generate conflict constraints that are only valid in the
    3842 * probing path and not in the problem tree (i.e. that exceed the focusdepth)
    3843 */
    3844 maxvaliddepth = (set->conf_allowlocal ? MIN(currentdepth-1, focusdepth) : 0);
    3845 if( validdepth > maxvaliddepth )
    3846 return SCIP_OKAY;
    3847
    3848 /* allocate temporary memory for storing first UIPs (in each depth level, at most two bound changes can be flagged
    3849 * as UIP, namely a binary and a non-binary bound change)
    3850 */
    3851 SCIP_CALL( SCIPsetAllocBufferArray(set, &firstuips, 2*(currentdepth+1)) ); /*lint !e647*/
    3852
    3853 /* process all bound changes in the conflict candidate queue */
    3854 nresolutions = 0;
    3855 lastconsnresolutions = (mustresolve ? 0 : -1);
    3856 lastconsresoldepth = (mustresolve ? currentdepth : INT_MAX);
    3857 bdchginfo = conflictFirstCand(conflict);
    3858 nfirstuips = 0;
    3859
    3860 /* check if the initial reason on debugging solution */
    3861 SCIP_CALL( SCIPdebugCheckConflictFrontier(blkmem, set, tree->path[validdepth], \
    3862 NULL, conflict->conflictset->bdchginfos, conflict->conflictset->relaxedbds, conflict->conflictset->nbdchginfos, \
    3863 conflict->bdchgqueue, conflict->forcedbdchgqueue) ); /*lint !e506 !e774*/
    3864
    3865 while( bdchginfo != NULL && validdepth <= maxvaliddepth )
    3866 {
    3867 SCIP_BDCHGINFO* nextbdchginfo;
    3868 SCIP_Real relaxedbd;
    3869 SCIP_Bool forceresolve;
    3870 int bdchgdepth;
    3871
    3872 assert(!SCIPbdchginfoIsRedundant(bdchginfo));
    3873
    3874 /* check if the next bound change must be resolved in every case */
    3875 forceresolve = (SCIPpqueueNElems(conflict->forcedbdchgqueue) > 0);
    3876
    3877 /* resolve next bound change in queue */
    3878 bdchgdepth = SCIPbdchginfoGetDepth(bdchginfo);
    3879 assert(0 <= bdchgdepth && bdchgdepth <= currentdepth);
    3880 assert(SCIPvarIsActive(SCIPbdchginfoGetVar(bdchginfo)));
    3881 assert(bdchgdepth < tree->pathlen);
    3882 assert(tree->path[bdchgdepth] != NULL);
    3883 assert(tree->path[bdchgdepth]->domchg != NULL);
    3884 assert(SCIPbdchginfoGetPos(bdchginfo) < (int)tree->path[bdchgdepth]->domchg->domchgbound.nboundchgs);
    3885 assert(tree->path[bdchgdepth]->domchg->domchgbound.boundchgs[SCIPbdchginfoGetPos(bdchginfo)].var
    3886 == SCIPbdchginfoGetVar(bdchginfo));
    3887 assert(tree->path[bdchgdepth]->domchg->domchgbound.boundchgs[SCIPbdchginfoGetPos(bdchginfo)].newbound
    3888 == SCIPbdchginfoGetNewbound(bdchginfo)
    3891 == SCIPbdchginfoGetNewbound(bdchginfo)); /*lint !e777*/
    3892 assert((SCIP_BOUNDTYPE)tree->path[bdchgdepth]->domchg->domchgbound.boundchgs[SCIPbdchginfoGetPos(bdchginfo)].boundtype
    3893 == SCIPbdchginfoGetBoundtype(bdchginfo));
    3894
    3895 /* create intermediate conflict constraint */
    3896 assert(nresolutions >= lastconsnresolutions);
    3897 if( !forceresolve )
    3898 {
    3899 if( nresolutions == lastconsnresolutions )
    3900 lastconsresoldepth = bdchgdepth; /* all intermediate depth levels consisted of only unresolved bound changes */
    3901 else if( bdchgdepth < lastconsresoldepth && (set->conf_interconss == -1 || *nconss < set->conf_interconss) )
    3902 {
    3903 int nlits;
    3904 SCIP_Bool success;
    3905
    3906 /* call the conflict handlers to create a conflict set */
    3907 SCIPsetDebugMsg(set, "creating intermediate conflictset after %d resolutions up to depth %d (valid at depth %d): %d conflict bounds, %d bounds in queue\n",
    3908 nresolutions, bdchgdepth, validdepth, conflict->conflictset->nbdchginfos,
    3909 SCIPpqueueNElems(conflict->bdchgqueue));
    3910
    3911 SCIP_CALL( conflictAddConflictset(conflict, blkmem, set, stat, tree, validdepth, diving, TRUE, &success, &nlits) );
    3912 lastconsnresolutions = nresolutions;
    3913 lastconsresoldepth = bdchgdepth;
    3914 if( success )
    3915 {
    3916 (*nconss)++;
    3917 (*nliterals) += nlits;
    3918 }
    3919 }
    3920 }
    3921
    3922 /* remove currently processed candidate and get next conflicting bound from the conflict candidate queue before
    3923 * we remove the candidate we have to collect the relaxed bound since removing the candidate from the queue
    3924 * invalidates the relaxed bound
    3925 */
    3926 assert(bdchginfo == conflictFirstCand(conflict));
    3927 relaxedbd = SCIPbdchginfoGetRelaxedBound(bdchginfo);
    3928 bdchginfo = conflictRemoveCand(conflict);
    3929 nextbdchginfo = conflictFirstCand(conflict);
    3930 assert(bdchginfo != NULL);
    3931 assert(!SCIPbdchginfoIsRedundant(bdchginfo));
    3932 assert(nextbdchginfo == NULL || SCIPbdchginfoGetDepth(bdchginfo) >= SCIPbdchginfoGetDepth(nextbdchginfo)
    3933 || forceresolve);
    3934
    3935 /* we don't need to resolve bound changes that are already active in the valid depth of the current conflict set,
    3936 * because the conflict set can only be added locally at the valid depth, and all bound changes applied in this
    3937 * depth or earlier can be removed from the conflict constraint, since they are already applied in the constraint's
    3938 * subtree;
    3939 * if the next bound change on the remaining queue is equal to the current bound change,
    3940 * this is a multiple insertion in the conflict candidate queue and we can ignore the current
    3941 * bound change
    3942 */
    3943 if( bdchgdepth > validdepth && bdchginfo != nextbdchginfo )
    3944 {
    3945 SCIP_VAR* actvar;
    3946 SCIP_Bool resolved;
    3947
    3948 actvar = SCIPbdchginfoGetVar(bdchginfo);
    3949 assert(actvar != NULL);
    3950 assert(SCIPvarIsActive(actvar));
    3951
    3952 /* check if we want to resolve the bound change in this depth level
    3953 * - bound changes should be resolved, if
    3954 * (i) we must apply at least one resolution and didn't resolve a bound change yet, or
    3955 * (ii) their depth level is at least equal to the minimal resolving depth, and
    3956 * they are not the last remaining conflicting bound change in their depth level
    3957 * (iii) the bound change resolving is forced (i.e., the forced queue was non-empty)
    3958 */
    3959 resolved = FALSE;
    3960 if( (mustresolve && nresolutions == 0)
    3961 || (bdchgdepth >= resolvedepth
    3962 && nextbdchginfo != NULL
    3963 && SCIPbdchginfoGetDepth(nextbdchginfo) == bdchgdepth)
    3964 || forceresolve )
    3965 {
    3966 SCIP_CALL( conflictResolveBound(conflict, set, bdchginfo, relaxedbd, validdepth, &resolved) );
    3967 }
    3968
    3969 if( resolved )
    3970 nresolutions++;
    3971 else if( forceresolve )
    3972 {
    3973 /* variable cannot enter the conflict clause: we have to make the conflict clause local, s.t.
    3974 * the unresolved bound change is active in the whole sub tree of the conflict clause
    3975 */
    3976 assert(bdchgdepth >= validdepth);
    3977 validdepth = bdchgdepth;
    3978
    3979 SCIPsetDebugMsg(set, "couldn't resolve forced bound change on <%s> -> new valid depth: %d\n",
    3980 SCIPvarGetName(actvar), validdepth);
    3981 }
    3982 else
    3983 {
    3984 /* if this is a UIP (the last bound change in its depth level), it can be used to generate a
    3985 * UIP reconvergence constraint
    3986 */
    3987 if( nextbdchginfo == NULL || SCIPbdchginfoGetDepth(nextbdchginfo) != bdchgdepth )
    3988 {
    3989 assert(nfirstuips < 2*(currentdepth+1));
    3990 firstuips[nfirstuips] = bdchginfo;
    3991 nfirstuips++;
    3992 }
    3993
    3994 /* put variable into the conflict set, using the literal that is currently fixed to FALSE */
    3995 SCIP_CALL( conflictAddConflictBound(conflict, blkmem, set, bdchginfo, relaxedbd) );
    3996 }
    3997 }
    3998
    3999 /* check conflict graph frontier on debugging solution */
    4000 SCIP_CALL( SCIPdebugCheckConflictFrontier(blkmem, set, tree->path[validdepth], \
    4001 bdchginfo, conflict->conflictset->bdchginfos, conflict->conflictset->relaxedbds, conflict->conflictset->nbdchginfos, \
    4002 conflict->bdchgqueue, conflict->forcedbdchgqueue) ); /*lint !e506 !e774*/
    4003
    4004 /* get next conflicting bound from the conflict candidate queue (this needs not to be nextbdchginfo, because
    4005 * due to resolving the bound changes, a bound change could be added to the queue which must be
    4006 * resolved before nextbdchginfo)
    4007 */
    4008 bdchginfo = conflictFirstCand(conflict);
    4009 }
    4010
    4011 /* check, if a valid conflict set was found */
    4012 if( bdchginfo == NULL
    4013 && nresolutions > lastconsnresolutions
    4014 && validdepth <= maxvaliddepth
    4015 && (!mustresolve || nresolutions > 0 || conflict->conflictset->nbdchginfos == 0)
    4016 && SCIPpqueueNElems(conflict->forcedbdchgqueue) == 0 )
    4017 {
    4018 int nlits;
    4019 SCIP_Bool success;
    4020
    4021 /* call the conflict handlers to create a conflict set */
    4022 SCIP_CALL( conflictAddConflictset(conflict, blkmem, set, stat, tree, validdepth, diving, TRUE, &success, &nlits) );
    4023 if( success )
    4024 {
    4025 (*nconss)++;
    4026 (*nliterals) += nlits;
    4027 }
    4028 }
    4029
    4030 /* produce reconvergence constraints defined by succeeding UIP's of the last depth level */
    4031 if( set->conf_reconvlevels != 0 && validdepth <= maxvaliddepth )
    4032 {
    4033 int reconvlevels;
    4034 int i;
    4035
    4036 reconvlevels = (set->conf_reconvlevels == -1 ? INT_MAX : set->conf_reconvlevels);
    4037 for( i = 0; i < nfirstuips; ++i )
    4038 {
    4039 if( SCIPbdchginfoHasInferenceReason(firstuips[i])
    4040 && currentdepth - SCIPbdchginfoGetDepth(firstuips[i]) < reconvlevels )
    4041 {
    4042 SCIP_CALL( conflictCreateReconvergenceConss(conflict, blkmem, set, stat, prob, tree, diving, \
    4043 validdepth, firstuips[i], nreconvconss, nreconvliterals) );
    4044 }
    4045 }
    4046 }
    4047
    4048 /* free the temporary memory */
    4049 SCIPsetFreeBufferArray(set, &firstuips);
    4050
    4051 /* store last conflict type */
    4052 conftype = conflict->conflictset->conflicttype;
    4053
    4054 /* clear the conflict candidate queue and the conflict set */
    4055 conflictClear(conflict);
    4056
    4057 /* restore last conflict type */
    4058 conflict->conflictset->conflicttype = conftype;
    4059
    4060 return SCIP_OKAY;
    4061}
    4062
    4063/** calculates the score of a bound change within a conflict */
    4064static
    4066 SCIP_Real prooflhs, /**< lhs of proof constraint */
    4067 SCIP_Real proofact, /**< activity of the proof constraint */
    4068 SCIP_Real proofactdelta, /**< activity change */
    4069 SCIP_Real proofcoef, /**< coefficient in proof constraint */
    4070 int depth, /**< bound change depth */
    4071 int currentdepth, /**< current depth */
    4072 SCIP_VAR* var, /**< variable corresponding to bound change */
    4073 SCIP_SET* set /**< global SCIP settings */
    4074 )
    4075{
    4076 SCIP_COL* col;
    4077 SCIP_Real score;
    4078
    4079 score = set->conf_proofscorefac * (1.0 - proofactdelta/(prooflhs - proofact));
    4080 score = MAX(score, 0.0);
    4081 score += set->conf_depthscorefac * (SCIP_Real)(depth+1)/(SCIP_Real)(currentdepth+1);
    4082
    4084 col = SCIPvarGetCol(var);
    4085 else
    4086 col = NULL;
    4087
    4088 if( proofcoef > 0.0 )
    4089 {
    4090 if( col != NULL && SCIPcolGetNNonz(col) > 0 )
    4091 score += set->conf_uplockscorefac
    4093 else
    4094 score += set->conf_uplockscorefac * SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL);
    4095 }
    4096 else
    4097 {
    4098 if( col != NULL && SCIPcolGetNNonz(col) > 0 )
    4099 score += set->conf_downlockscorefac
    4101 else
    4102 score += set->conf_downlockscorefac * SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL);
    4103 }
    4104
    4105 return score;
    4106}
    4107
    4108/** ensures, that candidate array can store at least num entries */
    4109static
    4111 SCIP_SET* set, /**< global SCIP settings */
    4112 SCIP_VAR*** cands, /**< pointer to candidate array */
    4113 SCIP_Real** candscores, /**< pointer to candidate score array */
    4114 SCIP_Real** newbounds, /**< pointer to candidate new bounds array */
    4115 SCIP_Real** proofactdeltas, /**< pointer to candidate proof delta array */
    4116 int* candssize, /**< pointer to size of array */
    4117 int num /**< minimal number of candidates to store in array */
    4118 )
    4119{
    4120 assert(cands != NULL);
    4121 assert(candssize != NULL);
    4122
    4123 if( num > *candssize )
    4124 {
    4125 int newsize;
    4126
    4127 newsize = SCIPsetCalcMemGrowSize(set, num);
    4128 SCIP_CALL( SCIPsetReallocBufferArray(set, cands, newsize) );
    4129 SCIP_CALL( SCIPsetReallocBufferArray(set, candscores, newsize) );
    4130 SCIP_CALL( SCIPsetReallocBufferArray(set, newbounds, newsize) );
    4131 SCIP_CALL( SCIPsetReallocBufferArray(set, proofactdeltas, newsize) );
    4132 *candssize = newsize;
    4133 }
    4134 assert(num <= *candssize);
    4135
    4136 return SCIP_OKAY;
    4137}
    4138
    4139/** after changing the global bound of a variable, the bdchginfos that are now redundant are replaced with
    4140 * oldbound = newbound = global bound; if the current bdchginfo is of such kind, the bound is equal to the
    4141 * global bound and we can ignore it by installing a -1 as the corresponding bound change info position
    4142 */
    4143static
    4145 SCIP_VAR* var, /**< problem variable */
    4146 int* lbchginfopos, /**< pointer to lower bound change information position */
    4147 int* ubchginfopos /**< pointer to upper bound change information position */
    4148 )
    4149{
    4150 assert(var != NULL);
    4151 assert(lbchginfopos != NULL);
    4152 assert(ubchginfopos != NULL);
    4153 assert(-1 <= *lbchginfopos && *lbchginfopos <= var->nlbchginfos);
    4154 assert(-1 <= *ubchginfopos && *ubchginfopos <= var->nubchginfos);
    4155 assert(*lbchginfopos == -1 || *lbchginfopos == var->nlbchginfos
    4156 || var->lbchginfos[*lbchginfopos].redundant
    4157 == (var->lbchginfos[*lbchginfopos].oldbound == var->lbchginfos[*lbchginfopos].newbound)); /*lint !e777*/
    4158 assert(*ubchginfopos == -1 || *ubchginfopos == var->nubchginfos
    4159 || var->ubchginfos[*ubchginfopos].redundant
    4160 == (var->ubchginfos[*ubchginfopos].oldbound == var->ubchginfos[*ubchginfopos].newbound)); /*lint !e777*/
    4161
    4162 if( *lbchginfopos >= 0 && *lbchginfopos < var->nlbchginfos && var->lbchginfos[*lbchginfopos].redundant )
    4163 {
    4164 assert(SCIPvarGetLbGlobal(var) == var->lbchginfos[*lbchginfopos].oldbound); /*lint !e777*/
    4165 *lbchginfopos = -1;
    4166 }
    4167 if( *ubchginfopos >= 0 && *ubchginfopos < var->nubchginfos && var->ubchginfos[*ubchginfopos].redundant )
    4168 {
    4169 assert(SCIPvarGetUbGlobal(var) == var->ubchginfos[*ubchginfopos].oldbound); /*lint !e777*/
    4170 *ubchginfopos = -1;
    4171 }
    4172}
    4173
    4174/** adds variable's bound to conflict candidate queue */
    4176 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    4177 BMS_BLKMEM* blkmem, /**< block memory */
    4178 SCIP_SET* set, /**< global SCIP settings */
    4179 SCIP_STAT* stat, /**< dynamic problem statistics */
    4180 SCIP_VAR* var, /**< problem variable */
    4181 SCIP_BOUNDTYPE boundtype, /**< type of bound that was changed: lower or upper bound */
    4182 SCIP_BDCHGIDX* bdchgidx /**< bound change index (time stamp of bound change), or NULL for current time */
    4183 )
    4184{
    4185 SCIP_BDCHGINFO* bdchginfo;
    4186
    4187 assert(conflict != NULL);
    4188 assert(stat != NULL);
    4189 assert(var != NULL);
    4190
    4191 /* convert bound to active problem variable */
    4192 SCIP_CALL( convertToActiveVar(&var, set, &boundtype, NULL) );
    4193
    4194 /* we can ignore fixed variables */
    4196 return SCIP_OKAY;
    4197
    4198 /* if the variable is multi-aggregated, add the bounds of all aggregation variables */
    4200 {
    4201 SCIP_VAR** vars;
    4203 int nvars;
    4204 int i;
    4205
    4206 vars = SCIPvarGetMultaggrVars(var);
    4208 nvars = SCIPvarGetMultaggrNVars(var);
    4209 for( i = 0; i < nvars; ++i )
    4210 {
    4211 SCIP_CALL( SCIPconflictAddBound(conflict, blkmem, set, stat, vars[i],
    4212 (scalars[i] < 0.0 ? SCIPboundtypeOpposite(boundtype) : boundtype), bdchgidx) );
    4213 }
    4214
    4215 return SCIP_OKAY;
    4216 }
    4217 assert(SCIPvarIsActive(var));
    4218
    4219 /* get bound change information */
    4220 bdchginfo = SCIPvarGetBdchgInfo(var, boundtype, bdchgidx, FALSE);
    4221
    4222 /* if bound of variable was not changed (this means it is still the global bound), we can ignore the conflicting
    4223 * bound
    4224 */
    4225 if( bdchginfo == NULL )
    4226 return SCIP_OKAY;
    4227
    4228 assert(SCIPbdchgidxIsEarlier(SCIPbdchginfoGetIdx(bdchginfo), bdchgidx));
    4229
    4230 SCIP_CALL( conflictAddBound(conflict, blkmem, set, stat, var, boundtype, bdchginfo, SCIPbdchginfoGetNewbound(bdchginfo)) );
    4231
    4232 return SCIP_OKAY;
    4233}
    4234
    4235/** adds variable's bound to conflict candidate queue */
    4237 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    4238 BMS_BLKMEM* blkmem, /**< block memory */
    4239 SCIP_SET* set, /**< global SCIP settings */
    4240 SCIP_STAT* stat, /**< dynamic problem statistics */
    4241 SCIP_VAR* var, /**< problem variable */
    4242 SCIP_BOUNDTYPE boundtype, /**< type of bound that was changed: lower or upper bound */
    4243 SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
    4244 SCIP_Real relaxedbd /**< the relaxed bound */
    4245 )
    4246{
    4247 SCIP_BDCHGINFO* bdchginfo;
    4248 int nbdchgs;
    4249
    4250 assert(conflict != NULL);
    4251 assert(stat != NULL);
    4252 assert(var != NULL);
    4253
    4254 if( !SCIPvarIsActive(var) )
    4255 {
    4256 /* convert bound to active problem variable */
    4257 SCIP_CALL( convertToActiveVar(&var, set, &boundtype, &relaxedbd) );
    4258
    4259 /* we can ignore fixed variables */
    4261 return SCIP_OKAY;
    4262
    4263 /* if the variable is multi-aggregated, add the bounds of all aggregation variables */
    4265 {
    4266 SCIPsetDebugMsg(set, "ignoring relaxed bound information since variable <%s> is multi-aggregated active\n", SCIPvarGetName(var));
    4267
    4268 SCIP_CALL( SCIPconflictAddBound(conflict, blkmem, set, stat, var, boundtype, bdchgidx) );
    4269
    4270 return SCIP_OKAY;
    4271 }
    4272 }
    4273 assert(SCIPvarIsActive(var));
    4274
    4275 /* get bound change information */
    4276 bdchginfo = SCIPvarGetBdchgInfo(var, boundtype, bdchgidx, FALSE);
    4277
    4278 /* if bound of variable was not changed (this means it is still the global bound), we can ignore the conflicting
    4279 * bound
    4280 */
    4281 if( bdchginfo == NULL )
    4282 return SCIP_OKAY;
    4283
    4284 /* check that the bound change info is not a temporary one */
    4285 assert(SCIPbdchgidxGetPos(&bdchginfo->bdchgidx) >= 0);
    4286
    4287 /* get the position of the bound change information within the bound change array of the variable */
    4288 nbdchgs = (int) bdchginfo->pos;
    4289 assert(nbdchgs >= 0);
    4290
    4291 /* if the relaxed bound should be ignored, set the relaxed bound to the bound given by the bdchgidx; that ensures
    4292 * that the loop(s) below will be skipped
    4293 */
    4294 if( set->conf_ignorerelaxedbd )
    4295 relaxedbd = SCIPbdchginfoGetNewbound(bdchginfo);
    4296
    4297 /* search for the bound change information which includes the relaxed bound */
    4298 if( boundtype == SCIP_BOUNDTYPE_LOWER )
    4299 {
    4300 SCIP_Real newbound;
    4301
    4302 /* adjust relaxed lower bound w.r.t. variable type */
    4303 SCIPvarAdjustLb(var, set, &relaxedbd);
    4304
    4305 /* due to numericis we compare the relaxed lower bound to the one present at the particular time point and take
    4306 * the better one
    4307 */
    4308 newbound = SCIPbdchginfoGetNewbound(bdchginfo);
    4309 relaxedbd = MIN(relaxedbd, newbound);
    4310
    4311 /* check if relaxed lower bound is smaller or equal to global lower bound; if so we can ignore the conflicting
    4312 * bound
    4313 */
    4314 if( SCIPsetIsLE(set, relaxedbd, SCIPvarGetLbGlobal(var)) )
    4315 return SCIP_OKAY;
    4316
    4317 while( nbdchgs > 0 )
    4318 {
    4319 assert(SCIPsetIsLE(set, relaxedbd, SCIPbdchginfoGetNewbound(bdchginfo)));
    4320
    4321 /* check if the old lower bound is greater than or equal to relaxed lower bound; if not we found the bound
    4322 * change info which we need to report
    4323 */
    4324 if( SCIPsetIsGT(set, relaxedbd, SCIPbdchginfoGetOldbound(bdchginfo)) )
    4325 break;
    4326
    4327 bdchginfo = SCIPvarGetBdchgInfoLb(var, nbdchgs-1);
    4328
    4329 SCIPsetDebugMsg(set, "lower bound change %d oldbd=%.15g, newbd=%.15g, depth=%d, pos=%d, redundant=%u\n",
    4330 nbdchgs, SCIPbdchginfoGetOldbound(bdchginfo), SCIPbdchginfoGetNewbound(bdchginfo),
    4331 SCIPbdchginfoGetDepth(bdchginfo), SCIPbdchginfoGetPos(bdchginfo),
    4332 SCIPbdchginfoIsRedundant(bdchginfo));
    4333
    4334 /* if bound change is redundant (this means it now a global bound), we can ignore the conflicting bound */
    4335 if( SCIPbdchginfoIsRedundant(bdchginfo) )
    4336 return SCIP_OKAY;
    4337
    4338 nbdchgs--;
    4339 }
    4340 assert(SCIPsetIsGT(set, relaxedbd, SCIPbdchginfoGetOldbound(bdchginfo)));
    4341 }
    4342 else
    4343 {
    4344 SCIP_Real newbound;
    4345
    4346 assert(boundtype == SCIP_BOUNDTYPE_UPPER);
    4347
    4348 /* adjust relaxed upper bound w.r.t. variable type */
    4349 SCIPvarAdjustUb(var, set, &relaxedbd);
    4350
    4351 /* due to numericis we compare the relaxed upper bound to the one present at the particular time point and take
    4352 * the better one
    4353 */
    4354 newbound = SCIPbdchginfoGetNewbound(bdchginfo);
    4355 relaxedbd = MAX(relaxedbd, newbound);
    4356
    4357 /* check if relaxed upper bound is greater or equal to global upper bound; if so we can ignore the conflicting
    4358 * bound
    4359 */
    4360 if( SCIPsetIsGE(set, relaxedbd, SCIPvarGetUbGlobal(var)) )
    4361 return SCIP_OKAY;
    4362
    4363 while( nbdchgs > 0 )
    4364 {
    4365 assert(SCIPsetIsGE(set, relaxedbd, SCIPbdchginfoGetNewbound(bdchginfo)));
    4366
    4367 /* check if the old upper bound is smaller than or equal to the relaxed upper bound; if not we found the
    4368 * bound change info which we need to report
    4369 */
    4370 if( SCIPsetIsLT(set, relaxedbd, SCIPbdchginfoGetOldbound(bdchginfo)) )
    4371 break;
    4372
    4373 bdchginfo = SCIPvarGetBdchgInfoUb(var, nbdchgs-1);
    4374
    4375 SCIPsetDebugMsg(set, "upper bound change %d oldbd=%.15g, newbd=%.15g, depth=%d, pos=%d, redundant=%u\n",
    4376 nbdchgs, SCIPbdchginfoGetOldbound(bdchginfo), SCIPbdchginfoGetNewbound(bdchginfo),
    4377 SCIPbdchginfoGetDepth(bdchginfo), SCIPbdchginfoGetPos(bdchginfo),
    4378 SCIPbdchginfoIsRedundant(bdchginfo));
    4379
    4380 /* if bound change is redundant (this means it now a global bound), we can ignore the conflicting bound */
    4381 if( SCIPbdchginfoIsRedundant(bdchginfo) )
    4382 return SCIP_OKAY;
    4383
    4384 nbdchgs--;
    4385 }
    4386 assert(SCIPsetIsLT(set, relaxedbd, SCIPbdchginfoGetOldbound(bdchginfo)));
    4387 }
    4388
    4389 assert(SCIPbdchgidxIsEarlier(SCIPbdchginfoGetIdx(bdchginfo), bdchgidx));
    4390
    4391 /* put bound change information into priority queue */
    4392 SCIP_CALL( conflictAddBound(conflict, blkmem, set, stat, var, boundtype, bdchginfo, relaxedbd) );
    4393
    4394 return SCIP_OKAY;
    4395}
    4396
    4397/** checks if the given variable is already part of the current conflict set or queued for resolving with the same or
    4398 * even stronger bound
    4399 */
    4401 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    4402 SCIP_VAR* var, /**< problem variable */
    4403 SCIP_SET* set, /**< global SCIP settings */
    4404 SCIP_BOUNDTYPE boundtype, /**< type of bound for which the score should be increased */
    4405 SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
    4406 SCIP_Bool* used /**< pointer to store if the variable is already used */
    4407 )
    4408{
    4409 SCIP_Real newbound;
    4410
    4411 /* convert bound to active problem variable */
    4412 SCIP_CALL( convertToActiveVar(&var, set, &boundtype, NULL) );
    4413
    4415 *used = FALSE;
    4416 else
    4417 {
    4418 assert(SCIPvarIsActive(var));
    4419 assert(var != NULL);
    4420
    4421 switch( boundtype )
    4422 {
    4424
    4425 newbound = SCIPgetVarLbAtIndex(set->scip, var, bdchgidx, FALSE);
    4426
    4427 if( var->conflictlbcount == conflict->count && var->conflictlb >= newbound )
    4428 {
    4429 SCIPsetDebugMsg(set, "already queued bound change <%s> >= %g\n", SCIPvarGetName(var), newbound);
    4430 *used = TRUE;
    4431 }
    4432 else
    4433 *used = FALSE;
    4434 break;
    4436
    4437 newbound = SCIPgetVarUbAtIndex(set->scip, var, bdchgidx, FALSE);
    4438
    4439 if( var->conflictubcount == conflict->count && var->conflictub <= newbound )
    4440 {
    4441 SCIPsetDebugMsg(set, "already queued bound change <%s> <= %g\n", SCIPvarGetName(var), newbound);
    4442 *used = TRUE;
    4443 }
    4444 else
    4445 *used = FALSE;
    4446 break;
    4447 default:
    4448 SCIPerrorMessage("invalid bound type %d\n", boundtype);
    4449 SCIPABORT();
    4450 *used = FALSE; /*lint !e527*/
    4451 }
    4452 }
    4453
    4454 return SCIP_OKAY;
    4455}
    4456
    4457/** inserts variable's new bounds into bound change arrays */
    4458static
    4460 SCIP_SET* set, /**< global SCIP settings */
    4461 SCIP_VAR* var, /**< variable to change the LP bounds for */
    4462 SCIP_Real newlb, /**< new lower bound */
    4463 SCIP_Real newub, /**< new upper bound */
    4464 SCIP_LPBDCHGS* oldlpbdchgs, /**< old LP bound changes used for reset the LP bound change */
    4465 SCIP_LPBDCHGS* relaxedlpbdchgs, /**< relaxed LP bound changes used for reset the LP bound change */
    4466 SCIP_LPI* lpi /**< pointer to LPi to access infinity of LP solver; necessary to set correct value */
    4467 )
    4468{
    4469 assert(newlb <= newub);
    4470 assert(oldlpbdchgs != NULL);
    4471 assert(relaxedlpbdchgs != NULL);
    4472
    4474 {
    4475 SCIP_COL* col;
    4476 int idx;
    4477 int c;
    4478
    4479 col = SCIPvarGetCol(var);
    4480 c = SCIPcolGetLPPos(col);
    4481
    4482 if( c >= 0 )
    4483 {
    4484 /* store old bound change for resetting the LP later */
    4485 if( !oldlpbdchgs->usedcols[c] )
    4486 {
    4487 idx = oldlpbdchgs->nbdchgs;
    4488 oldlpbdchgs->usedcols[c] = TRUE;
    4489 oldlpbdchgs->bdchgcolinds[c] = idx;
    4490 oldlpbdchgs->nbdchgs++;
    4491
    4492 oldlpbdchgs->bdchginds[idx] = c;
    4493 oldlpbdchgs->bdchglbs[idx] = SCIPvarGetLbLP(var, set);
    4494 oldlpbdchgs->bdchgubs[idx] = SCIPvarGetUbLP(var, set);
    4495 }
    4496 assert(oldlpbdchgs->bdchginds[oldlpbdchgs->bdchgcolinds[c]] == c);
    4497 assert((SCIPlpiIsInfinity(lpi, -oldlpbdchgs->bdchglbs[oldlpbdchgs->bdchgcolinds[c]]) && SCIPsetIsInfinity(set, -SCIPvarGetLbLP(var, set))) ||
    4498 SCIPsetIsEQ(set, oldlpbdchgs->bdchglbs[oldlpbdchgs->bdchgcolinds[c]], SCIPvarGetLbLP(var, set)));
    4499 assert((SCIPlpiIsInfinity(lpi, oldlpbdchgs->bdchgubs[oldlpbdchgs->bdchgcolinds[c]]) && SCIPsetIsInfinity(set, SCIPvarGetUbLP(var, set))) ||
    4500 SCIPsetIsEQ(set, oldlpbdchgs->bdchgubs[oldlpbdchgs->bdchgcolinds[c]], SCIPvarGetUbLP(var, set)));
    4501
    4502 /* store bound change for conflict analysis */
    4503 if( !relaxedlpbdchgs->usedcols[c] )
    4504 {
    4505 idx = relaxedlpbdchgs->nbdchgs;
    4506 relaxedlpbdchgs->usedcols[c] = TRUE;
    4507 relaxedlpbdchgs->bdchgcolinds[c] = idx;
    4508 relaxedlpbdchgs->nbdchgs++;
    4509
    4510 /* remember the positive for later further bound widenings */
    4511 relaxedlpbdchgs->bdchginds[idx] = c;
    4512 }
    4513 else
    4514 {
    4515 idx = relaxedlpbdchgs->bdchgcolinds[c];
    4516 assert(relaxedlpbdchgs->bdchginds[idx] == c);
    4517
    4518 /* the new bound should be the same or more relaxed */
    4519 assert(relaxedlpbdchgs->bdchglbs[idx] >= newlb ||
    4520 (SCIPlpiIsInfinity(lpi, -relaxedlpbdchgs->bdchglbs[idx]) && SCIPsetIsInfinity(set, -newlb)));
    4521 assert(relaxedlpbdchgs->bdchgubs[idx] <= newub ||
    4522 (SCIPlpiIsInfinity(lpi, relaxedlpbdchgs->bdchgubs[idx]) && SCIPsetIsInfinity(set, newub)));
    4523 }
    4524
    4525 /* set the new bounds for the LP with the correct infinity value */
    4526 relaxedlpbdchgs->bdchglbs[idx] = SCIPsetIsInfinity(set, -newlb) ? -SCIPlpiInfinity(lpi) : newlb;
    4527 relaxedlpbdchgs->bdchgubs[idx] = SCIPsetIsInfinity(set, newub) ? SCIPlpiInfinity(lpi) : newub;
    4528 if( SCIPsetIsInfinity(set, -oldlpbdchgs->bdchglbs[idx]) )
    4529 oldlpbdchgs->bdchglbs[idx] = -SCIPlpiInfinity(lpi);
    4530 if( SCIPsetIsInfinity(set, oldlpbdchgs->bdchgubs[idx]) )
    4531 oldlpbdchgs->bdchgubs[idx] = SCIPlpiInfinity(lpi);
    4532 }
    4533 }
    4534
    4535 return SCIP_OKAY;
    4536}
    4537
    4538/** adds variable to candidate list, if the current best bound corresponding to the proof coefficient is local;
    4539 * returns the array position in the candidate list, where the new candidate was inserted, or -1 if the
    4540 * variable can relaxed to global bounds immediately without increasing the proof's activity;
    4541 * the candidates are sorted with respect to the following two criteria:
    4542 * - prefer bound changes that have been applied deeper in the tree, to get a more global conflict
    4543 * - prefer variables with small Farkas coefficient to get rid of as many bound changes as possible
    4544 */
    4545static
    4547 SCIP_SET* set, /**< global SCIP settings */
    4548 int currentdepth, /**< current depth in the tree */
    4549 SCIP_VAR* var, /**< variable to add to candidate array */
    4550 int lbchginfopos, /**< positions of currently active lower bound change information in variable's array */
    4551 int ubchginfopos, /**< positions of currently active upper bound change information in variable's array */
    4552 SCIP_Real proofcoef, /**< coefficient of variable in infeasibility/bound proof */
    4553 SCIP_Real prooflhs, /**< left hand side of infeasibility/bound proof */
    4554 SCIP_Real proofact, /**< activity of infeasibility/bound proof row */
    4555 SCIP_VAR*** cands, /**< pointer to candidate array for undoing bound changes */
    4556 SCIP_Real** candscores, /**< pointer to candidate score array for undoing bound changes */
    4557 SCIP_Real** newbounds, /**< pointer to candidate new bounds array for undoing bound changes */
    4558 SCIP_Real** proofactdeltas, /**< pointer to proof activity increase array for undoing bound changes */
    4559 int* candssize, /**< pointer to size of cands arrays */
    4560 int* ncands, /**< pointer to count number of candidates in bound change list */
    4561 int firstcand /**< position of first unprocessed bound change candidate */
    4562 )
    4563{
    4564 SCIP_Real oldbound;
    4565 SCIP_Real newbound;
    4566 SCIP_Real QUAD(proofactdelta);
    4567 SCIP_Real score;
    4568 int depth;
    4569 int i;
    4570 SCIP_Bool resolvable;
    4571
    4572 assert(set != NULL);
    4573 assert(var != NULL);
    4574 assert(-1 <= lbchginfopos && lbchginfopos <= var->nlbchginfos);
    4575 assert(-1 <= ubchginfopos && ubchginfopos <= var->nubchginfos);
    4576 assert(!SCIPsetIsZero(set, proofcoef));
    4577 assert(SCIPsetIsGT(set, prooflhs, proofact));
    4578 assert(cands != NULL);
    4579 assert(candscores != NULL);
    4580 assert(newbounds != NULL);
    4581 assert(proofactdeltas != NULL);
    4582 assert(candssize != NULL);
    4583 assert(ncands != NULL);
    4584 assert(*ncands <= *candssize);
    4585 assert(0 <= firstcand && firstcand <= *ncands);
    4586
    4587 /* in the infeasibility or dual bound proof, the variable's bound is chosen to maximize the proof's activity */
    4588 if( proofcoef > 0.0 )
    4589 {
    4590 assert(ubchginfopos >= 0); /* otherwise, undoBdchgsProof() should already have relaxed the local bound */
    4591
    4592 /* calculate the difference of current bound to the previous bound the variable was set to */
    4593 if( ubchginfopos == var->nubchginfos )
    4594 {
    4595 /* current bound is the strong branching or diving bound */
    4596 oldbound = SCIPvarGetUbLP(var, set);
    4597 newbound = SCIPvarGetUbLocal(var);
    4598 depth = currentdepth+1;
    4599 resolvable = FALSE;
    4600 }
    4601 else
    4602 {
    4603 /* current bound is the result of a local bound change */
    4604 resolvable = bdchginfoIsResolvable(&var->ubchginfos[ubchginfopos]);
    4605 depth = var->ubchginfos[ubchginfopos].bdchgidx.depth;
    4606 oldbound = var->ubchginfos[ubchginfopos].newbound;
    4607 newbound = var->ubchginfos[ubchginfopos].oldbound;
    4608 }
    4609 }
    4610 else
    4611 {
    4612 assert(lbchginfopos >= 0); /* otherwise, undoBdchgsProof() should already have relaxed the local bound */
    4613
    4614 /* calculate the difference of current bound to the previous bound the variable was set to */
    4615 if( lbchginfopos == var->nlbchginfos )
    4616 {
    4617 /* current bound is the strong branching or diving bound */
    4618 oldbound = SCIPvarGetLbLP(var, set);
    4619 newbound = SCIPvarGetLbLocal(var);
    4620 depth = currentdepth+1;
    4621 resolvable = FALSE;
    4622 }
    4623 else
    4624 {
    4625 /* current bound is the result of a local bound change */
    4626 resolvable = bdchginfoIsResolvable(&var->lbchginfos[lbchginfopos]);
    4627 depth = var->lbchginfos[lbchginfopos].bdchgidx.depth;
    4628 oldbound = var->lbchginfos[lbchginfopos].newbound;
    4629 newbound = var->lbchginfos[lbchginfopos].oldbound;
    4630 }
    4631 }
    4632
    4633 /* calculate the increase in the proof's activity */
    4634 SCIPquadprecSumDD(proofactdelta, newbound, -oldbound);
    4635 SCIPquadprecProdQD(proofactdelta, proofactdelta, proofcoef);
    4636 assert(QUAD_TO_DBL(proofactdelta) > 0.0);
    4637
    4638 /* calculate score for undoing the bound change */
    4639 score = calcBdchgScore(prooflhs, proofact, QUAD_TO_DBL(proofactdelta), proofcoef, depth, currentdepth, var, set);
    4640
    4641 if( !resolvable )
    4642 {
    4643 score += 10.0;
    4644 if( !SCIPvarIsBinary(var) )
    4645 score += 10.0;
    4646 }
    4647
    4648 /* get enough memory to store new candidate */
    4649 SCIP_CALL( ensureCandsSize(set, cands, candscores, newbounds, proofactdeltas, candssize, (*ncands)+1) );
    4650 assert(*cands != NULL);
    4651 assert(*candscores != NULL);
    4652 assert(*newbounds != NULL);
    4653 assert(*proofactdeltas != NULL);
    4654
    4655 SCIPsetDebugMsg(set, " -> local <%s> %s %g, relax <%s> %s %g, proofcoef=%g, dpt=%d, resolve=%u, delta=%g, score=%g\n",
    4656 SCIPvarGetName(var), proofcoef > 0.0 ? "<=" : ">=", oldbound,
    4657 SCIPvarGetName(var), proofcoef > 0.0 ? "<=" : ">=", newbound,
    4658 proofcoef, depth, resolvable, QUAD_TO_DBL(proofactdelta), score);
    4659
    4660 /* insert variable in candidate list without touching the already processed candidates */
    4661 for( i = *ncands; i > firstcand && score > (*candscores)[i-1]; --i )
    4662 {
    4663 (*cands)[i] = (*cands)[i-1];
    4664 (*candscores)[i] = (*candscores)[i-1];
    4665 (*newbounds)[i] = (*newbounds)[i-1];
    4666 (*proofactdeltas)[i] = (*proofactdeltas)[i-1];
    4667 }
    4668 (*cands)[i] = var;
    4669 (*candscores)[i] = score;
    4670 (*newbounds)[i] = newbound;
    4671 (*proofactdeltas)[i] = QUAD_TO_DBL(proofactdelta);
    4672 (*ncands)++;
    4673
    4674 return SCIP_OKAY;
    4675}
    4676
    4677/** undoes bound changes on variables, still leaving the given infeasibility proof valid */
    4679 SCIP_SET* set, /**< global SCIP settings */
    4680 SCIP_PROB* prob, /**< problem data */
    4681 int currentdepth, /**< current depth in the tree */
    4682 SCIP_Real* proofcoefs, /**< coefficients in infeasibility proof */
    4683 SCIP_Real prooflhs, /**< left hand side of proof */
    4684 SCIP_Real* proofact, /**< current activity of proof */
    4685 SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
    4686 SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
    4687 int* lbchginfoposs, /**< positions of currently active lower bound change information in variables' arrays */
    4688 int* ubchginfoposs, /**< positions of currently active upper bound change information in variables' arrays */
    4689 SCIP_LPBDCHGS* oldlpbdchgs, /**< old LP bound changes used for reset the LP bound change, or NULL */
    4690 SCIP_LPBDCHGS* relaxedlpbdchgs, /**< relaxed LP bound changes used for reset the LP bound change, or NULL */
    4691 SCIP_Bool* resolve, /**< pointer to store whether the changed LP should be resolved again, or NULL */
    4692 SCIP_LPI* lpi /**< pointer to LPi to access infinity of LP solver; necessary to set correct values */
    4693 )
    4694{
    4695 SCIP_VAR** vars;
    4696 SCIP_VAR** cands;
    4697 SCIP_Real* candscores;
    4698 SCIP_Real* newbounds;
    4699 SCIP_Real* proofactdeltas;
    4700 int nvars;
    4701 int ncands;
    4702 int candssize;
    4703 int v;
    4704 int i;
    4705
    4706 assert(prob != NULL);
    4707 assert(proofcoefs != NULL);
    4708 assert(SCIPsetIsFeasGT(set, prooflhs, (*proofact)));
    4709 assert(curvarlbs != NULL);
    4710 assert(curvarubs != NULL);
    4711 assert(lbchginfoposs != NULL);
    4712 assert(ubchginfoposs != NULL);
    4713
    4714 if( resolve != NULL )
    4715 *resolve = FALSE;
    4716
    4717 vars = prob->vars;
    4718 nvars = prob->nvars;
    4719 assert(nvars == 0 || vars != NULL);
    4720
    4721 /* calculate the order in which the bound changes are tried to be undone, and relax all bounds if this doesn't
    4722 * increase the proof's activity
    4723 */
    4724 SCIP_CALL( SCIPsetAllocBufferArray(set, &cands, nvars) );
    4725 SCIP_CALL( SCIPsetAllocBufferArray(set, &candscores, nvars) );
    4726 SCIP_CALL( SCIPsetAllocBufferArray(set, &newbounds, nvars) );
    4727 SCIP_CALL( SCIPsetAllocBufferArray(set, &proofactdeltas, nvars) );
    4728 ncands = 0;
    4729 candssize = nvars;
    4730 for( v = 0; v < nvars; ++v )
    4731 {
    4732 SCIP_VAR* var;
    4733 SCIP_Bool relaxed;
    4734
    4735 var = vars[v];
    4736
    4737 /* after changing the global bound of a variable, the bdchginfos that are now redundant are replaced with
    4738 * oldbound = newbound = global bound; if the current bdchginfo is of such kind, the bound is equal to the
    4739 * global bound and we can ignore it
    4740 */
    4741 skipRedundantBdchginfos(var, &lbchginfoposs[v], &ubchginfoposs[v]);
    4742
    4743 /* ignore variables already relaxed to global bounds */
    4744 if( (lbchginfoposs[v] == -1 && ubchginfoposs[v] == -1) )
    4745 {
    4746 proofcoefs[v] = 0.0;
    4747 continue;
    4748 }
    4749
    4750 /* relax bounds that are not used in the proof to the global bounds */
    4751 relaxed = FALSE;
    4752 if( !SCIPsetIsNegative(set, proofcoefs[v]) )
    4753 {
    4754 /* the lower bound is not used */
    4755 if( lbchginfoposs[v] >= 0 )
    4756 {
    4757 SCIPsetDebugMsg(set, " -> relaxing variable <%s>[%g,%g] to [%g,%g]: proofcoef=%g, %g <= %g\n",
    4758 SCIPvarGetName(var), curvarlbs[v], curvarubs[v], SCIPvarGetLbGlobal(var), curvarubs[v],
    4759 proofcoefs[v], prooflhs, (*proofact));
    4760 curvarlbs[v] = SCIPvarGetLbGlobal(var);
    4761 lbchginfoposs[v] = -1;
    4762 relaxed = TRUE;
    4763 }
    4764 }
    4765 if( !SCIPsetIsPositive(set, proofcoefs[v]) )
    4766 {
    4767 /* the upper bound is not used */
    4768 if( ubchginfoposs[v] >= 0 )
    4769 {
    4770 SCIPsetDebugMsg(set, " -> relaxing variable <%s>[%g,%g] to [%g,%g]: proofcoef=%g, %g <= %g\n",
    4771 SCIPvarGetName(var), curvarlbs[v], curvarubs[v], curvarlbs[v], SCIPvarGetUbGlobal(var),
    4772 proofcoefs[v], prooflhs, (*proofact));
    4773 curvarubs[v] = SCIPvarGetUbGlobal(var);
    4774 ubchginfoposs[v] = -1;
    4775 relaxed = TRUE;
    4776 }
    4777 }
    4778 if( relaxed && oldlpbdchgs != NULL )
    4779 {
    4780 SCIP_CALL( addBdchg(set, var, curvarlbs[v], curvarubs[v], oldlpbdchgs, relaxedlpbdchgs, lpi) );
    4781 }
    4782
    4783 /* add bound to candidate list */
    4784 if( lbchginfoposs[v] >= 0 || ubchginfoposs[v] >= 0 )
    4785 {
    4786 SCIP_CALL( addCand(set, currentdepth, var, lbchginfoposs[v], ubchginfoposs[v], proofcoefs[v],
    4787 prooflhs, (*proofact), &cands, &candscores, &newbounds, &proofactdeltas, &candssize, &ncands, 0) );
    4788 }
    4789 /* we can set the proof coefficient to zero, because the variable is not needed */
    4790 else
    4791 proofcoefs[v] = 0.0;
    4792 }
    4793
    4794 /* try to undo remaining local bound changes while still keeping the proof row violated:
    4795 * bound changes can be undone, if prooflhs > proofact + proofactdelta;
    4796 * afterwards, the current proof activity has to be updated
    4797 */
    4798 for( i = 0; i < ncands; ++i )
    4799 {
    4800 assert(proofactdeltas[i] > 0.0);
    4801 assert((lbchginfoposs[SCIPvarGetProbindex(cands[i])] >= 0) != (ubchginfoposs[SCIPvarGetProbindex(cands[i])] >= 0));
    4802
    4803 /* when relaxing a constraint we still need to stay infeasible; therefore we need to do the comparison in
    4804 * feasibility tolerance because if 'prooflhs' is (feas-))equal to 'proofact + proofactdeltas[i]' it would mean
    4805 * that there is no violation
    4806 */
    4807 if( SCIPsetIsFeasGT(set, prooflhs, (*proofact) + proofactdeltas[i]) )
    4808 {
    4809 v = SCIPvarGetProbindex(cands[i]);
    4810 assert(0 <= v && v < nvars);
    4811 assert((lbchginfoposs[v] >= 0) != (ubchginfoposs[v] >= 0));
    4812
    4813 SCIPsetDebugMsg(set, " -> relaxing variable <%s>[%g,%g] to [%g,%g]: proofcoef=%g, %g <= %g + %g\n",
    4814 SCIPvarGetName(cands[i]), curvarlbs[v], curvarubs[v],
    4815 proofcoefs[v] > 0.0 ? curvarlbs[v] : newbounds[i],
    4816 proofcoefs[v] > 0.0 ? newbounds[i] : curvarubs[v],
    4817 proofcoefs[v], prooflhs, (*proofact), proofactdeltas[i]);
    4818
    4819#ifndef NDEBUG
    4820 {
    4821 SCIP_Real QUAD(verifylb);
    4822 SCIP_Real QUAD(verifyub);
    4823
    4824 SCIPquadprecSumDD(verifylb, newbounds[i], -curvarlbs[v]);
    4825 SCIPquadprecProdQD(verifylb, verifylb, proofcoefs[v]);
    4826
    4827 SCIPquadprecSumDD(verifyub, newbounds[i], -curvarubs[v]);
    4828 SCIPquadprecProdQD(verifyub, verifyub, proofcoefs[v]);
    4829
    4830 assert((SCIPsetIsPositive(set, proofcoefs[v]) && SCIPsetIsGT(set, newbounds[i], curvarubs[v]))
    4831 || (SCIPsetIsNegative(set, proofcoefs[v]) && SCIPsetIsLT(set, newbounds[i], curvarlbs[v])));
    4832 assert((SCIPsetIsPositive(set, proofcoefs[v])
    4833 && SCIPsetIsEQ(set, proofactdeltas[i], QUAD_TO_DBL(verifyub)))
    4834 || (SCIPsetIsNegative(set, proofcoefs[v])
    4835 && SCIPsetIsEQ(set, proofactdeltas[i], QUAD_TO_DBL(verifylb))));
    4836 assert(!SCIPsetIsZero(set, proofcoefs[v]));
    4837 }
    4838#endif
    4839
    4840 if( proofcoefs[v] > 0.0 )
    4841 {
    4842 assert(ubchginfoposs[v] >= 0);
    4843 assert(lbchginfoposs[v] == -1);
    4844 curvarubs[v] = newbounds[i];
    4845 ubchginfoposs[v]--;
    4846 }
    4847 else
    4848 {
    4849 assert(lbchginfoposs[v] >= 0);
    4850 assert(ubchginfoposs[v] == -1);
    4851 curvarlbs[v] = newbounds[i];
    4852 lbchginfoposs[v]--;
    4853 }
    4854 if( oldlpbdchgs != NULL )
    4855 {
    4856 SCIP_CALL( addBdchg(set, cands[i], curvarlbs[v], curvarubs[v], oldlpbdchgs, relaxedlpbdchgs, lpi) );
    4857 }
    4858 (*proofact) += proofactdeltas[i];
    4859 if( resolve != NULL && SCIPvarIsInLP(cands[i]) )
    4860 *resolve = TRUE;
    4861
    4862 /* after changing the global bound of a variable, the bdchginfos that are now redundant are replaced with
    4863 * oldbound = newbound = global bound; if the current bdchginfo is of such kind, the bound is equal to the
    4864 * global bound and we can ignore it
    4865 */
    4866 skipRedundantBdchginfos(cands[i], &lbchginfoposs[v], &ubchginfoposs[v]);
    4867
    4868 /* insert the new local bound of the variable into the candidate list */
    4869 if( lbchginfoposs[v] >= 0 || ubchginfoposs[v] >= 0 )
    4870 {
    4871 SCIP_CALL( addCand(set, currentdepth, cands[i], lbchginfoposs[v], ubchginfoposs[v], proofcoefs[v],
    4872 prooflhs, (*proofact), &cands, &candscores, &newbounds, &proofactdeltas, &candssize, &ncands, i+1) );
    4873 }
    4874 else
    4875 proofcoefs[v] = 0.0;
    4876 }
    4877 }
    4878
    4879 /* free the buffer for the sorted bound change candidates */
    4880 SCIPsetFreeBufferArray(set, &proofactdeltas);
    4881 SCIPsetFreeBufferArray(set, &newbounds);
    4882 SCIPsetFreeBufferArray(set, &candscores);
    4883 SCIPsetFreeBufferArray(set, &cands);
    4884
    4885 return SCIP_OKAY;
    4886}
    4887
    4888/** analyzes an infeasible LP and undoes additional bound changes while staying infeasible */
    4889static
    4891 SCIP_SET* set, /**< global SCIP settings */
    4892 SCIP_PROB* prob, /**< problem data */
    4893 SCIP_LP* lp, /**< LP data */
    4894 int currentdepth, /**< current depth in the tree */
    4895 SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
    4896 SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
    4897 int* lbchginfoposs, /**< positions of currently active lower bound change information in variables' arrays */
    4898 int* ubchginfoposs, /**< positions of currently active upper bound change information in variables' arrays */
    4899 SCIP_LPBDCHGS* oldlpbdchgs, /**< old LP bound changes used for reset the LP bound change, or NULL */
    4900 SCIP_LPBDCHGS* relaxedlpbdchgs, /**< relaxed LP bound changes used for reset the LP bound change, or NULL */
    4901 SCIP_Bool* valid, /**< pointer to store whether the unfixings are valid */
    4902 SCIP_Bool* resolve, /**< pointer to store whether the changed LP should be resolved again */
    4903 SCIP_Real* farkascoefs, /**< coefficients in the proof constraint */
    4904 SCIP_Real farkaslhs, /**< lhs of the proof constraint */
    4905 SCIP_Real* farkasactivity /**< maximal activity of the proof constraint */
    4906 )
    4907{
    4908 SCIP_LPI* lpi;
    4909
    4910 assert(prob != NULL);
    4911 assert(lp != NULL);
    4912 assert(lp->flushed);
    4913 assert(lp->solved);
    4914 assert(curvarlbs != NULL);
    4915 assert(curvarubs != NULL);
    4916 assert(lbchginfoposs != NULL);
    4917 assert(ubchginfoposs != NULL);
    4918 assert(valid != NULL);
    4919 assert(resolve != NULL);
    4920
    4921 SCIPsetDebugMsg(set, "undoing bound changes in infeasible LP: cutoff=%g\n", lp->cutoffbound);
    4922
    4923 *valid = FALSE;
    4924 *resolve = FALSE;
    4925
    4926 lpi = SCIPlpGetLPI(lp);
    4927
    4928 /* check, if the Farkas row is still violated (using current bounds and ignoring local rows) */
    4929 if( SCIPsetIsFeasGT(set, farkaslhs, *farkasactivity) )
    4930 {
    4931 /* undo bound changes while keeping the infeasibility proof valid */
    4932 SCIP_CALL( SCIPundoBdchgsProof(set, prob, currentdepth, farkascoefs, farkaslhs, farkasactivity, \
    4933 curvarlbs, curvarubs, lbchginfoposs, ubchginfoposs, oldlpbdchgs, relaxedlpbdchgs, resolve, lpi) );
    4934
    4935 *valid = TRUE;
    4936
    4937 /* resolving does not make sense: the old dual ray is still valid -> resolving will not change the solution */
    4938 *resolve = FALSE;
    4939 }
    4940
    4941 return SCIP_OKAY;
    4942}
    4943
    4944
    4945/*
    4946 * Conflict LP Bound Changes
    4947 */
    4948
    4949/** create conflict LP bound change data structure */
    4950static
    4952 SCIP_LPBDCHGS** lpbdchgs, /**< pointer to store the conflict LP bound change data structure */
    4953 SCIP_SET* set, /**< global SCIP settings */
    4954 int ncols /**< number of columns */
    4955 )
    4956{
    4957 SCIP_CALL( SCIPsetAllocBuffer(set, lpbdchgs) );
    4958
    4959 SCIP_CALL( SCIPsetAllocBufferArray(set, &(*lpbdchgs)->bdchginds, ncols) );
    4960 SCIP_CALL( SCIPsetAllocBufferArray(set, &(*lpbdchgs)->bdchglbs, ncols) );
    4961 SCIP_CALL( SCIPsetAllocBufferArray(set, &(*lpbdchgs)->bdchgubs, ncols) );
    4962 SCIP_CALL( SCIPsetAllocBufferArray(set, &(*lpbdchgs)->bdchgcolinds, ncols) );
    4963 SCIP_CALL( SCIPsetAllocBufferArray(set, &(*lpbdchgs)->usedcols, ncols) );
    4964 BMSclearMemoryArray((*lpbdchgs)->usedcols, ncols);
    4965
    4966 (*lpbdchgs)->nbdchgs = 0;
    4967
    4968 return SCIP_OKAY;
    4969}
    4970
    4971
    4972/*
    4973 * Propagation Conflict Analysis
    4974 */
    4975
    4976/** ensures, that side change arrays can store at least num entries */
    4977static
    4979 SCIP_SET* set, /**< global SCIP settings */
    4980 int** sidechginds, /**< pointer to side change index array */
    4981 SCIP_Real** sidechgoldlhss, /**< pointer to side change old left hand sides array */
    4982 SCIP_Real** sidechgoldrhss, /**< pointer to side change old right hand sides array */
    4983 SCIP_Real** sidechgnewlhss, /**< pointer to side change new left hand sides array */
    4984 SCIP_Real** sidechgnewrhss, /**< pointer to side change new right hand sides array */
    4985 int* sidechgssize, /**< pointer to size of side change arrays */
    4986 int num /**< minimal number of entries to be able to store in side change arrays */
    4987 )
    4988{
    4989 assert(sidechginds != NULL);
    4990 assert(sidechgoldlhss != NULL);
    4991 assert(sidechgoldrhss != NULL);
    4992 assert(sidechgnewlhss != NULL);
    4993 assert(sidechgnewrhss != NULL);
    4994 assert(sidechgssize != NULL);
    4995
    4996 if( num > *sidechgssize )
    4997 {
    4998 int newsize;
    4999
    5000 newsize = SCIPsetCalcMemGrowSize(set, num);
    5001 SCIP_CALL( SCIPsetReallocBufferArray(set, sidechginds, newsize) );
    5002 SCIP_CALL( SCIPsetReallocBufferArray(set, sidechgoldlhss, newsize) );
    5003 SCIP_CALL( SCIPsetReallocBufferArray(set, sidechgoldrhss, newsize) );
    5004 SCIP_CALL( SCIPsetReallocBufferArray(set, sidechgnewlhss, newsize) );
    5005 SCIP_CALL( SCIPsetReallocBufferArray(set, sidechgnewrhss, newsize) );
    5006 *sidechgssize = newsize;
    5007 }
    5008 assert(num <= *sidechgssize);
    5009
    5010 return SCIP_OKAY;
    5011}
    5012
    5013/** adds removal of row's side to side change arrays; finite sides are only replaced by near infinite sides, such
    5014 * that the row's sense in the LP solver is not changed
    5015 */
    5016static
    5018 SCIP_SET* set, /**< global SCIP settings */
    5019 SCIP_ROW* row, /**< LP row to change the sides for */
    5020 SCIP_Real lpiinfinity, /**< value treated as infinity in LP solver */
    5021 int** sidechginds, /**< pointer to side change index array */
    5022 SCIP_Real** sidechgoldlhss, /**< pointer to side change old left hand sides array */
    5023 SCIP_Real** sidechgoldrhss, /**< pointer to side change old right hand sides array */
    5024 SCIP_Real** sidechgnewlhss, /**< pointer to side change new left hand sides array */
    5025 SCIP_Real** sidechgnewrhss, /**< pointer to side change new right hand sides array */
    5026 int* sidechgssize, /**< pointer to size of side change arrays */
    5027 int* nsidechgs /**< pointer to number of used slots in side change arrays */
    5028 )
    5029{
    5030 SCIP_Real lhs;
    5031 SCIP_Real rhs;
    5032 SCIP_Real constant;
    5033
    5034 assert(sidechginds != NULL);
    5035 assert(sidechgoldlhss != NULL);
    5036 assert(sidechgoldrhss != NULL);
    5037 assert(sidechgnewlhss != NULL);
    5038 assert(sidechgnewrhss != NULL);
    5039 assert(sidechgssize != NULL);
    5040 assert(nsidechgs != NULL);
    5041
    5042 lhs = SCIProwGetLhs(row);
    5043 rhs = SCIProwGetRhs(row);
    5044 constant = SCIProwGetConstant(row);
    5045 assert(!SCIPsetIsInfinity(set, -lhs) || !SCIPsetIsInfinity(set, rhs));
    5046
    5047 /* get memory to store additional side change */
    5048 SCIP_CALL( ensureSidechgsSize(set, sidechginds, sidechgoldlhss, sidechgoldrhss, sidechgnewlhss, sidechgnewrhss, \
    5049 sidechgssize, (*nsidechgs)+1) );
    5050 assert(*nsidechgs < *sidechgssize);
    5051 assert(*sidechginds != NULL);
    5052 assert(*sidechgoldlhss != NULL);
    5053 assert(*sidechgoldrhss != NULL);
    5054 assert(*sidechgnewlhss != NULL);
    5055 assert(*sidechgnewrhss != NULL);
    5056
    5057 /* store side change */
    5058 (*sidechginds)[*nsidechgs] = SCIProwGetLPPos(row);
    5059 if( SCIPsetIsInfinity(set, -lhs) )
    5060 {
    5061 (*sidechgoldlhss)[*nsidechgs] = -lpiinfinity;
    5062 (*sidechgnewlhss)[*nsidechgs] = -lpiinfinity;
    5063 }
    5064 else
    5065 {
    5066 (*sidechgoldlhss)[*nsidechgs] = lhs - constant;
    5067 (*sidechgnewlhss)[*nsidechgs] = -lpiinfinity;
    5068 }
    5069 if( SCIPsetIsInfinity(set, rhs) )
    5070 {
    5071 (*sidechgoldrhss)[*nsidechgs] = lpiinfinity;
    5072 (*sidechgnewrhss)[*nsidechgs] = lpiinfinity;
    5073 }
    5074 else
    5075 {
    5076 (*sidechgoldrhss)[*nsidechgs] = rhs - constant;
    5077 (*sidechgnewrhss)[*nsidechgs] = lpiinfinity;
    5078 }
    5079 (*nsidechgs)++;
    5080
    5081 return SCIP_OKAY;
    5082}
    5083
    5084
    5085/*
    5086 * Infeasible LP Conflict Analysis
    5087 */
    5088
    5089/** reset conflict LP bound change data structure */
    5090static
    5092 SCIP_LPBDCHGS* lpbdchgs, /**< conflict LP bound change data structure */
    5093 int ncols /**< number of columns */
    5094 )
    5095{
    5096 assert(lpbdchgs != NULL);
    5097
    5098 BMSclearMemoryArray(lpbdchgs->usedcols, ncols);
    5099 lpbdchgs->nbdchgs = 0;
    5100}
    5101
    5102/** free conflict LP bound change data structure */
    5103static
    5105 SCIP_LPBDCHGS** lpbdchgs, /**< pointer to store the conflict LP bound change data structure */
    5106 SCIP_SET* set /**< global SCIP settings */
    5107 )
    5108{
    5109 SCIPsetFreeBufferArray(set, &(*lpbdchgs)->usedcols);
    5110 SCIPsetFreeBufferArray(set, &(*lpbdchgs)->bdchgcolinds);
    5111 SCIPsetFreeBufferArray(set, &(*lpbdchgs)->bdchgubs);
    5112 SCIPsetFreeBufferArray(set, &(*lpbdchgs)->bdchglbs);
    5113 SCIPsetFreeBufferArray(set, &(*lpbdchgs)->bdchginds);
    5114
    5115 SCIPsetFreeBuffer(set, lpbdchgs);
    5116}
    5117
    5118/** analyzes an LP exceeding the objective limit and undoes additional bound changes while staying beyond the
    5119 * objective limit
    5120 */
    5121static
    5123 SCIP_SET* set, /**< global SCIP settings */
    5124 SCIP_PROB* prob, /**< problem data */
    5125 SCIP_LP* lp, /**< LP data */
    5126 int currentdepth, /**< current depth in the tree */
    5127 SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
    5128 SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
    5129 int* lbchginfoposs, /**< positions of currently active lower bound change information in variables' arrays */
    5130 int* ubchginfoposs, /**< positions of currently active upper bound change information in variables' arrays */
    5131 SCIP_LPBDCHGS* oldlpbdchgs, /**< old LP bound changes used for reset the LP bound change, or NULL */
    5132 SCIP_LPBDCHGS* relaxedlpbdchgs, /**< relaxed LP bound changes used for reset the LP bound change, or NULL */
    5133 SCIP_Bool* valid, /**< pointer to store whether the unfixings are valid */
    5134 SCIP_Bool* resolve, /**< pointer to store whether the changed LP should be resolved again */
    5135 SCIP_Real* dualcoefs, /**< coefficients in the proof constraint */
    5136 SCIP_Real duallhs, /**< lhs of the proof constraint */
    5137 SCIP_Real* dualactivity /**< maximal activity of the proof constraint */
    5138 )
    5139{
    5140 SCIP_LPI* lpi;
    5141
    5142 assert(set != NULL);
    5143 assert(prob != NULL);
    5144 assert(lp != NULL);
    5145 assert(lp->flushed);
    5146 assert(lp->solved);
    5147 assert(curvarlbs != NULL);
    5148 assert(curvarubs != NULL);
    5149 assert(lbchginfoposs != NULL);
    5150 assert(ubchginfoposs != NULL);
    5151 assert(valid != NULL);
    5152 assert(resolve != NULL);
    5153
    5154 *valid = FALSE;
    5155 *resolve = FALSE;
    5156
    5157 SCIPsetDebugMsg(set, "undoing bound changes in LP exceeding cutoff: cutoff=%g\n", lp->cutoffbound);
    5158
    5159 /* get LP solver interface */
    5160 lpi = SCIPlpGetLPI(lp);
    5161
    5162 /* check, if the dual row is still violated (using current bounds and ignoring local rows) */
    5163 if( SCIPsetIsFeasGT(set, duallhs, *dualactivity) )
    5164 {
    5165 /* undo bound changes while keeping the infeasibility proof valid */
    5166 SCIP_CALL( SCIPundoBdchgsProof(set, prob, currentdepth, dualcoefs, duallhs, dualactivity, curvarlbs, curvarubs, \
    5167 lbchginfoposs, ubchginfoposs, oldlpbdchgs, relaxedlpbdchgs, resolve, lpi) );
    5168
    5169 *valid = TRUE;
    5170 }
    5171
    5172 return SCIP_OKAY;
    5173}
    5174
    5175/** try to find a subset of changed bounds leading to an infeasible LP
    5176 *
    5177 * 1. call undoBdchgsDualfarkas() or undoBdchgsDualsol()
    5178 * -> update lb/ubchginfoposs arrays
    5179 * -> store additional changes in bdchg and curvarlbs/ubs arrays
    5180 * -> apply additional changes to the LPI
    5181 * 2. (optional) if additional bound changes were undone:
    5182 * -> resolve LP
    5183 * -> goto 1.
    5184 * 3. redo all bound changes in the LPI to restore the LPI to its original state
    5185 * 4. analyze conflict
    5186 * -> put remaining changed bounds (see lb/ubchginfoposs arrays) into starting conflict set
    5187 */
    5189 SCIP_CONFLICT* conflict, /**< conflict data */
    5190 SCIP_SET* set, /**< global SCIP settings */
    5191 SCIP_STAT* stat, /**< problem statistics */
    5192 SCIP_PROB* origprob, /**< original problem */
    5193 SCIP_PROB* transprob, /**< transformed problem */
    5194 SCIP_TREE* tree, /**< branch and bound tree */
    5195 SCIP_REOPT* reopt, /**< reoptimization data */
    5196 SCIP_LP* lp, /**< LP data */
    5197 SCIP_LPI* lpi, /**< LPI data */
    5198 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    5199 BMS_BLKMEM* blkmem, /**< block memory */
    5200 SCIP_Real* proofcoefs, /**< coefficients in the proof constraint */
    5201 SCIP_Real* prooflhs, /**< lhs of the proof constraint */
    5202 SCIP_Real* proofactivity, /**< maximal activity of the proof constraint */
    5203 SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
    5204 SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
    5205 int* lbchginfoposs, /**< positions of currently active lower bound change information in variables' arrays */
    5206 int* ubchginfoposs, /**< positions of currently active upper bound change information in variables' arrays */
    5207 int* iterations, /**< pointer to store the total number of LP iterations used */
    5208 SCIP_Bool marklpunsolved, /**< whether LP should be marked unsolved after analysis (needed for strong branching) */
    5209 SCIP_Bool* dualproofsuccess, /**< pointer to store success result of dual proof analysis */
    5210 SCIP_Bool* valid /**< pointer to store whether the result is still a valid proof */
    5211 )
    5212{
    5213 SCIP_LPBDCHGS* oldlpbdchgs;
    5214 SCIP_LPBDCHGS* relaxedlpbdchgs;
    5215 SCIP_Bool solvelp;
    5216 SCIP_Bool resolve;
    5217 int ncols;
    5218
    5219 assert(set != NULL);
    5220
    5221 /* get number of columns in the LP */
    5222 ncols = SCIPlpGetNCols(lp);
    5223
    5224 /* get temporary memory for remembering bound changes on LPI columns */
    5225 SCIP_CALL( lpbdchgsCreate(&oldlpbdchgs, set, ncols) );
    5226 SCIP_CALL( lpbdchgsCreate(&relaxedlpbdchgs, set, ncols) );
    5227
    5228 /* undo as many bound changes as possible with the current LP solution */
    5229 resolve = FALSE;
    5230 if( (*valid) )
    5231 {
    5232 int currentdepth;
    5233 currentdepth = SCIPtreeGetCurrentDepth(tree);
    5234
    5235 if( SCIPlpiIsPrimalInfeasible(lpi) )
    5236 {
    5237 SCIP_CALL( undoBdchgsDualfarkas(set, transprob, lp, currentdepth, curvarlbs, curvarubs, lbchginfoposs, \
    5238 ubchginfoposs, oldlpbdchgs, relaxedlpbdchgs, valid, &resolve, proofcoefs, *prooflhs, proofactivity) );
    5239 }
    5240 else
    5241 {
    5242 assert(SCIPlpiIsDualFeasible(lpi) || SCIPlpiIsObjlimExc(lpi));
    5243 SCIP_CALL( undoBdchgsDualsol(set, transprob, lp, currentdepth, curvarlbs, curvarubs, lbchginfoposs, ubchginfoposs, \
    5244 oldlpbdchgs, relaxedlpbdchgs, valid, &resolve, proofcoefs, *prooflhs, proofactivity) );
    5245 }
    5246 }
    5247
    5248 /* check if we want to solve the LP */
    5249 assert(SCIPprobAllColsInLP(transprob, set, lp));
    5250 solvelp = (set->conf_maxlploops != 0 && set->conf_lpiterations != 0);
    5251
    5252 if( (*valid) && resolve && solvelp )
    5253 {
    5254 SCIP_RETCODE retcode;
    5255 SCIP_ROW** rows;
    5256 int* sidechginds;
    5257 SCIP_Real* sidechgoldlhss;
    5258 SCIP_Real* sidechgoldrhss;
    5259 SCIP_Real* sidechgnewlhss;
    5260 SCIP_Real* sidechgnewrhss;
    5261 SCIP_Real lpiinfinity;
    5262 SCIP_Bool globalinfeasible;
    5263 int maxlploops;
    5264 int lpiterations;
    5265 int sidechgssize;
    5266 int nsidechgs;
    5267 int nrows;
    5268 int nloops;
    5269 int r;
    5270
    5271 /* get infinity value of LP solver */
    5272 lpiinfinity = SCIPlpiInfinity(lpi);
    5273
    5274 /* temporarily disable objective limit and install an iteration limit */
    5275 maxlploops = (set->conf_maxlploops >= 0 ? set->conf_maxlploops : INT_MAX);
    5276 lpiterations = (set->conf_lpiterations >= 0 ? set->conf_lpiterations : INT_MAX);
    5277 SCIP_CALL( SCIPlpiSetRealpar(lpi, SCIP_LPPAR_OBJLIM, lpiinfinity) );
    5278 SCIP_CALL( SCIPlpiSetIntpar(lpi, SCIP_LPPAR_LPITLIM, lpiterations) );
    5279
    5280 /* get LP rows */
    5281 rows = SCIPlpGetRows(lp);
    5282 nrows = SCIPlpGetNRows(lp);
    5283 assert(nrows == 0 || rows != NULL);
    5284
    5285 /* get temporary memory for remembering side changes on LPI rows */
    5286 SCIP_CALL( SCIPsetAllocBufferArray(set, &sidechginds, nrows) );
    5287 SCIP_CALL( SCIPsetAllocBufferArray(set, &sidechgoldlhss, nrows) );
    5288 SCIP_CALL( SCIPsetAllocBufferArray(set, &sidechgoldrhss, nrows) );
    5289 SCIP_CALL( SCIPsetAllocBufferArray(set, &sidechgnewlhss, nrows) );
    5290 SCIP_CALL( SCIPsetAllocBufferArray(set, &sidechgnewrhss, nrows) );
    5291 sidechgssize = nrows;
    5292 nsidechgs = 0;
    5293
    5294 /* remove all local rows by setting their sides to infinity;
    5295 * finite sides are only changed to near infinity, such that the row's sense in the LP solver
    5296 * is not affected (e.g. CPLEX cannot handle free rows)
    5297 */
    5298 for( r = 0; r < nrows; ++r )
    5299 {
    5300 assert(SCIProwGetLPPos(rows[r]) == r);
    5301
    5302 if( SCIProwIsLocal(rows[r]) )
    5303 {
    5304 SCIPsetDebugMsg(set, " -> removing local row <%s> [%g,%g]\n",
    5305 SCIProwGetName(rows[r]), SCIProwGetLhs(rows[r]), SCIProwGetRhs(rows[r]));
    5306 SCIP_CALL( addSideRemoval(set, rows[r], lpiinfinity, &sidechginds, &sidechgoldlhss, &sidechgoldrhss,
    5307 &sidechgnewlhss, &sidechgnewrhss, &sidechgssize, &nsidechgs) );
    5308 }
    5309 }
    5310
    5311 /* apply changes of local rows to the LP solver */
    5312 if( nsidechgs > 0 )
    5313 {
    5314 SCIP_CALL( SCIPlpiChgSides(lpi, nsidechgs, sidechginds, sidechgnewlhss, sidechgnewrhss) );
    5315 }
    5316
    5317 /* undo as many additional bound changes as possible by resolving the LP */
    5318 assert((*valid));
    5319 assert(resolve);
    5320 nloops = 0;
    5321 globalinfeasible = FALSE;
    5322 while( (*valid) && resolve && nloops < maxlploops )
    5323 {
    5324 int iter;
    5325
    5326 assert(!globalinfeasible);
    5327
    5328 nloops++;
    5329 resolve = FALSE;
    5330
    5331 SCIPsetDebugMsg(set, "infeasible LP conflict analysis loop %d (changed col bounds: %d)\n", nloops, relaxedlpbdchgs->nbdchgs);
    5332
    5333 /* apply bound changes to the LP solver */
    5334 assert(relaxedlpbdchgs->nbdchgs >= 0);
    5335 if( relaxedlpbdchgs->nbdchgs > 0 )
    5336 {
    5337 SCIPsetDebugMsg(set, " -> applying %d bound changes to the LP solver\n", relaxedlpbdchgs->nbdchgs);
    5338 SCIP_CALL( SCIPlpiChgBounds(lpi, relaxedlpbdchgs->nbdchgs, relaxedlpbdchgs->bdchginds, \
    5339 relaxedlpbdchgs->bdchglbs, relaxedlpbdchgs->bdchgubs) );
    5340
    5341 /* reset conflict LP bound change data structure */
    5342 lpbdchgsReset(relaxedlpbdchgs, ncols);
    5343 }
    5344
    5345 /* start LP timer */
    5347
    5348 /* resolve LP */
    5349 retcode = SCIPlpiSolveDual(lpi);
    5350
    5351 /* stop LP timer */
    5353
    5354 /* check return code of LP solving call */
    5355 if( retcode == SCIP_LPERROR )
    5356 {
    5357 (*valid) = FALSE;
    5358 break;
    5359 }
    5360 SCIP_CALL( retcode );
    5361
    5362 /* count number of LP iterations */
    5363 SCIP_CALL( SCIPlpiGetIterations(lpi, &iter) );
    5364 (*iterations) += iter;
    5365 stat->nconflictlps++;
    5366 stat->nconflictlpiterations += iter;
    5367 SCIPsetDebugMsg(set, " -> resolved LP in %d iterations (total: %" SCIP_LONGINT_FORMAT ") (infeasible:%u)\n",
    5369
    5370 /* evaluate result */
    5371 if( SCIPlpiIsDualFeasible(lpi) || SCIPlpiIsObjlimExc(lpi) )
    5372 {
    5373 SCIP_Real objval;
    5374
    5375 SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
    5376 (*valid) = (objval >= lp->lpiobjlim && !SCIPlpDivingObjChanged(lp));
    5377 }
    5378 else
    5379 (*valid) = SCIPlpiIsPrimalInfeasible(lpi);
    5380
    5381 if( (*valid) )
    5382 {
    5383 int currentdepth;
    5384 currentdepth = SCIPtreeGetCurrentDepth(tree);
    5385
    5386 /* undo additional bound changes */
    5387 if( SCIPlpiIsPrimalInfeasible(lpi) )
    5388 {
    5389 SCIP_AGGRROW* farkasrow;
    5390 int* inds;
    5391 int validdepth;
    5392 int nnz;
    5393 int v;
    5394
    5395#ifndef NDEBUG
    5396 SCIP_VAR** vars = SCIPprobGetVars(transprob);
    5397#endif
    5398
    5399 SCIP_CALL( SCIPaggrRowCreate(set->scip, &farkasrow) );
    5400
    5401 /* the original LP exceeds the current cutoff bound, thus, we have not constructed the Farkas proof */
    5402 SCIP_CALL( SCIPgetFarkasProof(set, transprob, lp, lpi, tree, farkasrow, proofactivity, &validdepth,
    5403 curvarlbs, curvarubs, valid) );
    5404
    5405 /* the constructed Farkas proof is not valid, we need to break here */
    5406 if( !(*valid) )
    5407 {
    5408 SCIPaggrRowFree(set->scip, &farkasrow);
    5409 break;
    5410 }
    5411
    5412 /* start dual proof analysis */
    5413 if( set->conf_useinflp == 'd' || set->conf_useinflp == 'b' )
    5414 {
    5415 /* change the conflict type */
    5416 SCIP_Bool oldusescutoff = conflict->conflictset->usescutoffbound;
    5417 SCIP_CONFTYPE oldconftype = conflict->conflictset->conflicttype;
    5418 conflict->conflictset->usescutoffbound = FALSE;
    5420
    5421 /* start dual proof analysis */
    5422 SCIP_CALL( SCIPconflictAnalyzeDualProof(conflict, set, stat, eventfilter, blkmem, origprob, transprob, tree, reopt,
    5423 lp, farkasrow, validdepth, curvarlbs, curvarubs, FALSE, &globalinfeasible, dualproofsuccess) );
    5424
    5425 conflict->conflictset->usescutoffbound = oldusescutoff;
    5426 conflict->conflictset->conflicttype = oldconftype;
    5427 }
    5428
    5429 /* todo: in theory, we could apply conflict graph analysis for locally valid proofs, too, but this needs to be implemented */
    5430 if( globalinfeasible || validdepth > SCIPtreeGetEffectiveRootDepth(tree) )
    5431 {
    5432 SCIPaggrRowFree(set->scip, &farkasrow);
    5433 goto TERMINATE;
    5434 }
    5435
    5436 BMSclearMemoryArray(proofcoefs, SCIPprobGetNVars(transprob));
    5437 (*prooflhs) = -SCIPaggrRowGetRhs(farkasrow);
    5438 (*proofactivity) = -(*proofactivity);
    5439
    5440 inds = SCIPaggrRowGetInds(farkasrow);
    5441 nnz = SCIPaggrRowGetNNz(farkasrow);
    5442
    5443 for( v = 0; v < nnz; v++ )
    5444 {
    5445 int i = inds[v];
    5446
    5447 assert(SCIPvarGetProbindex(vars[i]) == inds[v]);
    5448
    5449 proofcoefs[i] = -SCIPaggrRowGetProbvarValue(farkasrow, i);
    5450 }
    5451
    5452 /* free aggregation rows */
    5453 SCIPaggrRowFree(set->scip, &farkasrow);
    5454
    5455 SCIP_CALL( undoBdchgsDualfarkas(set, transprob, lp, currentdepth, curvarlbs, curvarubs, lbchginfoposs, \
    5456 ubchginfoposs, oldlpbdchgs, relaxedlpbdchgs, valid, &resolve, proofcoefs, (*prooflhs), proofactivity) );
    5457 }
    5458 else
    5459 {
    5460 SCIP_AGGRROW* proofrow;
    5461 int* inds;
    5462 int validdepth;
    5463 int nnz;
    5464 int v;
    5465
    5466#ifndef NDEBUG
    5467 SCIP_VAR** vars = SCIPprobGetVars(transprob);
    5468#endif
    5469
    5470 assert(SCIPlpiIsDualFeasible(lpi) || SCIPlpiIsObjlimExc(lpi));
    5471
    5472 SCIP_CALL( SCIPaggrRowCreate(set->scip, &proofrow) );
    5473
    5474 SCIP_CALL( SCIPgetDualProof(set, transprob, lp, lpi, tree, proofrow, proofactivity, &validdepth,
    5475 curvarlbs, curvarubs, valid) );
    5476
    5477 /* the constructed dual proof is not valid, we need to break here */
    5478 if( !(*valid) || validdepth > SCIPtreeGetEffectiveRootDepth(tree) )
    5479 {
    5480 SCIPaggrRowFree(set->scip, &proofrow);
    5481 break;
    5482 }
    5483 /* in contrast to the infeasible case we don't want to analyze the (probably identical) proof again. */
    5484
    5485 BMSclearMemoryArray(proofcoefs, SCIPprobGetNVars(transprob));
    5486 (*prooflhs) = -SCIPaggrRowGetRhs(proofrow);
    5487 (*proofactivity) = -(*proofactivity);
    5488
    5489 inds = SCIPaggrRowGetInds(proofrow);
    5490 nnz = SCIPaggrRowGetNNz(proofrow);
    5491
    5492 for( v = 0; v < nnz; v++ )
    5493 {
    5494 int i = inds[v];
    5495
    5496 assert(SCIPvarGetProbindex(vars[i]) == inds[v]);
    5497
    5498 proofcoefs[i] = -SCIPaggrRowGetProbvarValue(proofrow, i);
    5499 }
    5500
    5501 /* free aggregation rows */
    5502 SCIPaggrRowFree(set->scip, &proofrow);
    5503
    5504 SCIP_CALL( undoBdchgsDualsol(set, transprob, lp, currentdepth, curvarlbs, curvarubs, lbchginfoposs, \
    5505 ubchginfoposs, oldlpbdchgs, relaxedlpbdchgs, valid, &resolve, proofcoefs, *prooflhs, proofactivity) );
    5506 }
    5507 }
    5508 assert(!resolve || (*valid));
    5509 assert(!resolve || relaxedlpbdchgs->nbdchgs > 0);
    5510 SCIPsetDebugMsg(set, " -> finished infeasible LP conflict analysis loop %d (iter: %d, nbdchgs: %d)\n",
    5511 nloops, iter, relaxedlpbdchgs->nbdchgs);
    5512 }
    5513
    5514 SCIPsetDebugMsg(set, "finished undoing bound changes after %d loops (valid=%u, nbdchgs: %d)\n",
    5515 nloops, (*valid), oldlpbdchgs->nbdchgs);
    5516
    5517 TERMINATE:
    5518 /* reset variables to local bounds */
    5519 if( oldlpbdchgs->nbdchgs > 0 )
    5520 {
    5521 SCIP_CALL( SCIPlpiChgBounds(lpi, oldlpbdchgs->nbdchgs, oldlpbdchgs->bdchginds, oldlpbdchgs->bdchglbs, oldlpbdchgs->bdchgubs) );
    5522 }
    5523
    5524 /* reset changes of local rows */
    5525 if( nsidechgs > 0 )
    5526 {
    5527 SCIP_CALL( SCIPlpiChgSides(lpi, nsidechgs, sidechginds, sidechgoldlhss, sidechgoldrhss) );
    5528 }
    5529
    5530 /* mark the LP unsolved */
    5531 if( oldlpbdchgs->nbdchgs > 0 || nsidechgs > 0 )
    5532 {
    5533 /* The LPI data are out of sync with LP data. Thus, the LP should be marked
    5534 * unsolved. However, for strong branching calls, the LP has to have status 'solved'; in
    5535 * this case, marklpunsolved is FALSE and synchronization is performed later. */
    5536 if( marklpunsolved )
    5537 {
    5538 lp->solved = FALSE;
    5539 lp->primalfeasible = FALSE;
    5540 lp->primalchecked = FALSE;
    5541 lp->dualfeasible = FALSE;
    5542 lp->dualchecked = FALSE;
    5543 lp->lpobjval = SCIP_INVALID;
    5545 }
    5546 }
    5547
    5548 /* reinstall old objective and iteration limits in LP solver */
    5551
    5552 /* free temporary memory */
    5553 SCIPsetFreeBufferArray(set, &sidechgnewrhss);
    5554 SCIPsetFreeBufferArray(set, &sidechgnewlhss);
    5555 SCIPsetFreeBufferArray(set, &sidechgoldrhss);
    5556 SCIPsetFreeBufferArray(set, &sidechgoldlhss);
    5557 SCIPsetFreeBufferArray(set, &sidechginds);
    5558 }
    5559
    5560 /* free temporary memory */
    5561 lpbdchgsFree(&relaxedlpbdchgs, set);
    5562 lpbdchgsFree(&oldlpbdchgs, set);
    5563
    5564 return SCIP_OKAY;
    5565}
    5566
    5567/** analyzes conflicting bound changes that were added with calls to SCIPconflictAddBound(), and on success, calls the
    5568 * conflict handlers to create a conflict constraint out of the resulting conflict set;
    5569 * updates statistics for propagation conflict analysis
    5570 */
    5572 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    5573 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
    5574 SCIP_SET* set, /**< global SCIP settings */
    5575 SCIP_STAT* stat, /**< problem statistics */
    5576 SCIP_PROB* prob, /**< problem data */
    5577 SCIP_TREE* tree, /**< branch and bound tree */
    5578 int validdepth, /**< minimal depth level at which the initial conflict set is valid */
    5579 SCIP_Bool* success /**< pointer to store whether a conflict constraint was created, or NULL */
    5580 )
    5581{
    5582 int nconss;
    5583 int nliterals;
    5584 int nreconvconss;
    5585 int nreconvliterals;
    5586
    5587 assert(conflict != NULL);
    5588 assert(conflict->conflictset != NULL);
    5589 assert(set != NULL);
    5590 assert(prob != NULL);
    5591
    5592 if( success != NULL )
    5593 *success = FALSE;
    5594
    5595 /* check if the conflict analysis is applicable */
    5597 return SCIP_OKAY;
    5598
    5599 /* check, if the conflict set will get too large with high probability */
    5600 if( conflict->conflictset->nbdchginfos + SCIPpqueueNElems(conflict->bdchgqueue)
    5601 + SCIPpqueueNElems(conflict->forcedbdchgqueue) >= 2*conflictCalcMaxsize(set, prob) )
    5602 return SCIP_OKAY;
    5603
    5604 SCIPsetDebugMsg(set, "analyzing conflict after infeasible propagation in depth %d\n", SCIPtreeGetCurrentDepth(tree));
    5605
    5606 /* start timing */
    5608
    5609 conflict->npropcalls++;
    5610
    5611 /* setting this to true adds bound changes only to the conflict graph bdchg queue */
    5612 conflict->bdchgonlyconfqueue = TRUE;
    5613
    5614 /* analyze the conflict set, and create a conflict constraint on success */
    5615 SCIP_CALL( conflictAnalyze(conflict, blkmem, set, stat, prob, tree, FALSE, validdepth, TRUE, &nconss, &nliterals, \
    5616 &nreconvconss, &nreconvliterals) );
    5617 conflict->npropsuccess += (nconss > 0 ? 1 : 0);
    5618 conflict->npropconfconss += nconss;
    5619 conflict->npropconfliterals += nliterals;
    5620 conflict->npropreconvconss += nreconvconss;
    5621 conflict->npropreconvliterals += nreconvliterals;
    5622 conflict->bdchgonlyconfqueue = FALSE;
    5623
    5624 if( success != NULL )
    5625 *success = (nconss > 0);
    5626
    5627 /* stop timing */
    5628 SCIPclockStop(conflict->propanalyzetime, set);
    5629
    5630 return SCIP_OKAY;
    5631}
    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:7493
    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:248
    #define SCIP_MAXSTRLEN
    Definition: def.h:269
    #define SCIP_Longint
    Definition: def.h:141
    #define SCIP_REAL_MAX
    Definition: def.h:158
    #define SCIP_INVALID
    Definition: def.h:178
    #define SCIP_Bool
    Definition: def.h:91
    #define MIN(x, y)
    Definition: def.h:224
    #define SCIP_ALLOC(x)
    Definition: def.h:366
    #define SCIP_Real
    Definition: def.h:156
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define MAX(x, y)
    Definition: def.h:220
    #define SCIP_LONGINT_FORMAT
    Definition: def.h:148
    #define SCIPABORT()
    Definition: def.h:327
    #define SCIP_REAL_MIN
    Definition: def.h:159
    #define SCIP_CALL(x)
    Definition: def.h:355
    #define SCIP_CALL_FINALLY(x, y)
    Definition: def.h:397
    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:8472
    SCIP_Bool SCIPconsIsGlobal(SCIP_CONS *cons)
    Definition: cons.c:8618
    const char * SCIPconsGetName(SCIP_CONS *cons)
    Definition: cons.c:8389
    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:8493
    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:24482
    SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
    Definition: var.c:23683
    SCIP_Bool SCIPbdchginfoIsRedundant(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:25057
    SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
    Definition: var.c:23642
    SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
    Definition: var.c:23478
    SCIP_Bool SCIPbdchgidxIsEarlier(SCIP_BDCHGIDX *bdchgidx1, SCIP_BDCHGIDX *bdchgidx2)
    Definition: var.c:24889
    SCIP_BDCHGIDX * SCIPbdchginfoGetIdx(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:24979
    SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
    Definition: var.c:23386
    int SCIPvarGetNLocksUpType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
    Definition: var.c:4386
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24268
    SCIP_PROP * SCIPbdchginfoGetInferProp(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:25013
    SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
    Definition: var.c:23453
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24142
    int SCIPbdchginfoGetDepth(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:24959
    int SCIPbdchginfoGetInferInfo(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:25024
    int SCIPvarGetIndex(SCIP_VAR *var)
    Definition: var.c:23652
    SCIP_CONS * SCIPbdchginfoGetInferCons(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:25001
    int SCIPbdchginfoGetPos(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:24969
    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:23662
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23267
    SCIP_VAR * SCIPbdchginfoGetVar(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:24929
    int SCIPvarGetNVubs(SCIP_VAR *var)
    Definition: var.c:24524
    SCIP_Real SCIPbdchginfoGetOldbound(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:24909
    SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
    Definition: var.c:23490
    SCIP_BOUNDTYPE SCIPbdchginfoGetInferBoundtype(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:25036
    SCIP_BDCHGINFO * SCIPvarGetBdchgInfo(SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
    Definition: var.c:22741
    SCIP_VAR ** SCIPvarGetMultaggrVars(SCIP_VAR *var)
    Definition: var.c:23806
    SCIP_Bool SCIPbdchginfoIsTighter(SCIP_BDCHGINFO *bdchginfo1, SCIP_BDCHGINFO *bdchginfo2)
    Definition: var.c:25082
    int SCIPvarGetMultaggrNVars(SCIP_VAR *var)
    Definition: var.c:23794
    int SCIPvarGetNCliques(SCIP_VAR *var, SCIP_Bool varfixing)
    Definition: var.c:24642
    SCIP_BOUNDCHGTYPE SCIPbdchginfoGetChgtype(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:24939
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24234
    SCIP_VAR * SCIPbdchginfoGetInferVar(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:24989
    SCIP_Bool SCIPbdchginfoHasInferenceReason(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:25068
    SCIP_Bool SCIPvarIsRelaxationOnly(SCIP_VAR *var)
    Definition: var.c:23600
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24120
    SCIP_BDCHGINFO * SCIPvarGetBdchgInfoLb(SCIP_VAR *var, int pos)
    Definition: var.c:24704
    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:24949
    SCIP_Real SCIPbdchginfoGetNewbound(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:24919
    int SCIPvarGetNLocksDownType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
    Definition: var.c:4328
    SCIP_BDCHGINFO * SCIPvarGetBdchgInfoUb(SCIP_VAR *var, int pos)
    Definition: var.c:24724
    SCIP_Real * SCIPvarGetMultaggrScalars(SCIP_VAR *var)
    Definition: var.c:23818
    SCIP_Bool SCIPvarIsInLP(SCIP_VAR *var)
    Definition: var.c:23706
    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:2859
    int SCIPprobGetNVars(SCIP_PROB *prob)
    Definition: prob.c:2868
    SCIP_VAR ** SCIPprobGetVars(SCIP_PROB *prob)
    Definition: prob.c:2913
    SCIP_Bool SCIPprobAllColsInLP(SCIP_PROB *prob, SCIP_SET *set, SCIP_LP *lp)
    Definition: prob.c:2825
    SCIP_Bool SCIPprobIsTransformed(SCIP_PROB *prob)
    Definition: prob.c:2803
    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:9404
    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:9529
    int SCIPtreeGetEffectiveRootDepth(SCIP_TREE *tree)
    Definition: tree.c:9518
    int SCIPtreeGetCurrentDepth(SCIP_TREE *tree)
    Definition: tree.c:9479
    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:22615
    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:21103
    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:21239
    void SCIPvarAdjustLb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *lb)
    Definition: var.c:9910
    SCIP_Real SCIPvarGetLbLP(SCIP_VAR *var, SCIP_SET *set)
    Definition: var.c:18568
    SCIP_RETCODE SCIPvarScaleVSIDS(SCIP_VAR *var, SCIP_Real scalar)
    Definition: var.c:21189
    SCIP_Real SCIPvarGetUbLP(SCIP_VAR *var, SCIP_SET *set)
    Definition: var.c:18638
    int SCIPbdchgidxGetPos(SCIP_BDCHGIDX *bdchgidx)
    Definition: var.c:24849
    SCIP_RETCODE SCIPbdchginfoCreate(SCIP_BDCHGINFO **bdchginfo, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_Real oldbound, SCIP_Real newbound)
    Definition: var.c:22585
    SCIP_RETCODE SCIPvarGetProbvarSum(SCIP_VAR **var, SCIP_SET *set, SCIP_Real *scalar, SCIP_Real *constant)
    Definition: var.c:18075
    void SCIPvarAdjustUb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *ub)
    Definition: var.c:9961
    SCIP_Real SCIPbdchginfoGetRelaxedBound(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:25048
    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)