Scippy

SCIP

Solving Constraint Integer Programs

conflict.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-2020 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not visit scipopt.org. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 /**@file conflict.c
16  * @ingroup OTHER_CFILES
17  * @brief methods and datastructures for conflict analysis
18  * @author Tobias Achterberg
19  * @author Timo Berthold
20  * @author Stefan Heinz
21  * @author Marc Pfetsch
22  * @author Michael Winkler
23  * @author Jakob Witzig
24  *
25  * This file implements a conflict analysis method like the one used in modern
26  * SAT solvers like zchaff. The algorithm works as follows:
27  *
28  * Given is a set of bound changes that are not allowed being applied simultaneously, because they
29  * render the current node infeasible (e.g. because a single constraint is infeasible in the these
30  * bounds, or because the LP relaxation is infeasible). The goal is to deduce a clause on variables
31  * -- a conflict clause -- representing the "reason" for this conflict, i.e., the branching decisions
32  * or the deductions (applied e.g. in domain propagation) that lead to the conflict. This clause can
33  * then be added to the constraint set to help cutting off similar parts of the branch and bound
34  * tree, that would lead to the same conflict. A conflict clause can also be generated, if the
35  * conflict was detected by a locally valid constraint. In this case, the resulting conflict clause
36  * is also locally valid in the same depth as the conflict detecting constraint. If all involved
37  * variables are binary, a linear (set covering) constraint can be generated, otherwise a bound
38  * disjunction constraint is generated. Details are given in
39  *
40  * Tobias Achterberg, Conflict Analysis in Mixed Integer Programming@n
41  * Discrete Optimization, 4, 4-20 (2007)
42  *
43  * See also @ref CONF. Here is an outline of the algorithm:
44  *
45  * -# Put all the given bound changes to a priority queue, which is ordered,
46  * such that the bound change that was applied last due to branching or deduction
47  * is at the top of the queue. The variables in the queue are always active
48  * problem variables. Because binary variables are preferred over general integer
49  * variables, integer variables are put on the priority queue prior to the binary
50  * variables. Create an empty conflict set.
51  * -# Remove the top bound change b from the priority queue.
52  * -# Perform the following case distinction:
53  * -# If the remaining queue is non-empty, and bound change b' (the one that is now
54  * on the top of the queue) was applied at the same depth level as b, and if
55  * b was a deduction with known inference reason, and if the inference constraint's
56  * valid depth is smaller or equal to the conflict detecting constraint's valid
57  * depth:
58  * - Resolve bound change b by asking the constraint that inferred the
59  * bound change to put all the bound changes on the priority queue, that
60  * lead to the deduction of b.
61  * Note that these bound changes have at most the same inference depth
62  * level as b, and were deduced earlier than b.
63  * -# Otherwise, the bound change b was a branching decision or a deduction with
64  * missing inference reason, or the inference constraint's validity is more local
65  * than the one of the conflict detecting constraint.
66  * - If a the bound changed corresponds to a binary variable, add it or its
67  * negation to the conflict set, depending on which of them is currently fixed to
68  * FALSE (i.e., the conflict set consists of literals that cannot be FALSE
69  * altogether at the same time).
70  * - Otherwise put the bound change into the conflict set.
71  * Note that if the bound change was a branching, all deduced bound changes
72  * remaining in the priority queue have smaller inference depth level than b,
73  * since deductions are always applied after the branching decisions. However,
74  * there is the possibility, that b was a deduction, where the inference
75  * reason was not given or the inference constraint was too local.
76  * With this lack of information, we must treat the deduced bound change like
77  * a branching, and there may exist other deduced bound changes of the same
78  * inference depth level in the priority queue.
79  * -# If priority queue is non-empty, goto step 2.
80  * -# The conflict set represents the conflict clause saying that at least one
81  * of the conflict variables must take a different value. The conflict set is then passed
82  * to the conflict handlers, that may create a corresponding constraint (e.g. a logicor
83  * constraint or bound disjunction constraint) out of these conflict variables and
84  * add it to the problem.
85  *
86  * If all deduced bound changes come with (global) inference information, depending on
87  * the conflict analyzing strategy, the resulting conflict set has the following property:
88  * - 1-FirstUIP: In the depth level where the conflict was found, at most one variable
89  * assigned at that level is member of the conflict set. This conflict variable is the
90  * first unique implication point of its depth level (FUIP).
91  * - All-FirstUIP: For each depth level, at most one variable assigned at that level is
92  * member of the conflict set. This conflict variable is the first unique implication
93  * point of its depth level (FUIP).
94  *
95  * The user has to do the following to get the conflict analysis running in its
96  * current implementation:
97  * - A constraint handler or propagator supporting the conflict analysis must implement
98  * the CONSRESPROP/PROPRESPROP call, that processes a bound change inference b and puts all
99  * the reason bounds leading to the application of b with calls to
100  * SCIPaddConflictBound() on the conflict queue (algorithm step 3.(a)).
101  * - If the current bounds lead to a deduction of a bound change (e.g. in domain
102  * propagation), a constraint handler should call SCIPinferVarLbCons() or
103  * SCIPinferVarUbCons(), thus providing the constraint that infered the bound change.
104  * A propagator should call SCIPinferVarLbProp() or SCIPinferVarUbProp() instead,
105  * thus providing a pointer to itself.
106  * - If (in the current bounds) an infeasibility is detected, the constraint handler or
107  * propagator should
108  * 1. call SCIPinitConflictAnalysis() to initialize the conflict queue,
109  * 2. call SCIPaddConflictBound() for each bound that lead to the conflict,
110  * 3. call SCIPanalyzeConflictCons() or SCIPanalyzeConflict() to analyze the conflict
111  * and add an appropriate conflict constraint.
112  */
113 
114 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
115 
116 #include "lpi/lpi.h"
117 #include "scip/clock.h"
118 #include "scip/conflict.h"
119 #include "scip/conflictstore.h"
120 #include "scip/cons.h"
121 #include "scip/cons_linear.h"
122 #include "scip/cuts.h"
123 #include "scip/history.h"
124 #include "scip/lp.h"
125 #include "scip/presolve.h"
126 #include "scip/prob.h"
127 #include "scip/prop.h"
128 #include "scip/pub_conflict.h"
129 #include "scip/pub_cons.h"
130 #include "scip/pub_lp.h"
131 #include "scip/pub_message.h"
132 #include "scip/pub_misc.h"
133 #include "scip/pub_misc_sort.h"
134 #include "scip/pub_paramset.h"
135 #include "scip/pub_prop.h"
136 #include "scip/pub_tree.h"
137 #include "scip/pub_var.h"
138 #include "scip/scip_conflict.h"
139 #include "scip/scip_cons.h"
140 #include "scip/scip_mem.h"
141 #include "scip/scip_sol.h"
142 #include "scip/scip_var.h"
143 #include "scip/set.h"
144 #include "scip/sol.h"
145 #include "scip/struct_conflict.h"
146 #include "scip/struct_lp.h"
147 #include "scip/struct_prob.h"
148 #include "scip/struct_set.h"
149 #include "scip/struct_stat.h"
150 #include "scip/struct_tree.h"
151 #include "scip/struct_var.h"
152 #include "scip/tree.h"
153 #include "scip/var.h"
154 #include "scip/visual.h"
155 #include <string.h>
156 #if defined(_WIN32) || defined(_WIN64)
157 #else
158 #include <strings.h> /*lint --e{766}*/
159 #endif
160 
161 
162 
163 #define BOUNDSWITCH 0.51 /**< threshold for bound switching - see cuts.c */
164 #define POSTPROCESS FALSE /**< apply postprocessing to the cut - see cuts.c */
165 #define USEVBDS FALSE /**< use variable bounds - see cuts.c */
166 #define ALLOWLOCAL FALSE /**< allow to generate local cuts - see cuts. */
167 #define MINFRAC 0.05 /**< minimal fractionality of floor(rhs) - see cuts.c */
168 #define MAXFRAC 0.999 /**< maximal fractionality of floor(rhs) - see cuts.c */
169 
170 /*#define SCIP_CONFGRAPH*/
171 
172 
173 #ifdef SCIP_CONFGRAPH
174 /*
175  * Output of Conflict Graph
176  */
177 
178 #include <stdio.h>
179 
180 static FILE* confgraphfile = NULL; /**< output file for current conflict graph */
181 static SCIP_BDCHGINFO* confgraphcurrentbdchginfo = NULL; /**< currently resolved bound change */
182 static int confgraphnconflictsets = 0; /**< number of conflict sets marked in the graph */
183 
184 /** writes a node section to the conflict graph file */
185 static
186 void confgraphWriteNode(
187  void* idptr, /**< id of the node */
188  const char* label, /**< label of the node */
189  const char* nodetype, /**< type of the node */
190  const char* fillcolor, /**< color of the node's interior */
191  const char* bordercolor /**< color of the node's border */
192  )
193 {
194  assert(confgraphfile != NULL);
195 
196  SCIPgmlWriteNode(confgraphfile, (unsigned int)(size_t)idptr, label, nodetype, fillcolor, bordercolor);
197 }
198 
199 /** writes an edge section to the conflict graph file */
200 static
201 void confgraphWriteEdge(
202  void* source, /**< source node of the edge */
203  void* target, /**< target node of the edge */
204  const char* color /**< color of the edge */
205  )
206 {
207  assert(confgraphfile != NULL);
208 
209 #ifndef SCIP_CONFGRAPH_EDGE
210  SCIPgmlWriteArc(confgraphfile, (unsigned int)(size_t)source, (unsigned int)(size_t)target, NULL, color);
211 #else
212  SCIPgmlWriteEdge(confgraphfile, (unsigned int)(size_t)source, (unsigned int)(size_t)target, NULL, color);
213 #endif
214 }
215 
216 /** creates a file to output the current conflict graph into; adds the conflict vertex to the graph */
217 static
218 SCIP_RETCODE confgraphCreate(
219  SCIP_SET* set, /**< global SCIP settings */
220  SCIP_CONFLICT* conflict /**< conflict analysis data */
221  )
222 {
223  char fname[SCIP_MAXSTRLEN];
224 
225  assert(conflict != NULL);
226  assert(confgraphfile == NULL);
227 
228  (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "conf%p%d.gml", conflict, conflict->count);
229  SCIPinfoMessage(set->scip, NULL, "storing conflict graph in file <%s>\n", fname);
230 
231  confgraphfile = fopen(fname, "w");
232 
233  if( confgraphfile == NULL )
234  {
235  SCIPerrorMessage("cannot open graph file <%s>\n", fname);
236  SCIPABORT(); /*lint !e527*/
237  return SCIP_WRITEERROR;
238  }
239 
240  SCIPgmlWriteOpening(confgraphfile, TRUE);
241 
242  confgraphWriteNode(NULL, "conflict", "ellipse", "#ff0000", "#000000");
243 
244  confgraphcurrentbdchginfo = NULL;
245 
246  return SCIP_OKAY;
247 }
248 
249 /** closes conflict graph file */
250 static
251 void confgraphFree(
252  void
253  )
254 {
255  if( confgraphfile != NULL )
256  {
257  SCIPgmlWriteClosing(confgraphfile);
258 
259  fclose(confgraphfile);
260 
261  confgraphfile = NULL;
262  confgraphnconflictsets = 0;
263  }
264 }
265 
266 /** adds a bound change node to the conflict graph and links it to the currently resolved bound change */
267 static
268 void confgraphAddBdchg(
269  SCIP_BDCHGINFO* bdchginfo /**< bound change to add to the conflict graph */
270  )
271 {
272  const char* colors[] = {
273  "#8888ff", /* blue for constraint resolving */
274  "#ffff00", /* yellow for propagator resolving */
275  "#55ff55" /* green branching decision */
276  };
277  char label[SCIP_MAXSTRLEN];
278  char depth[SCIP_MAXSTRLEN];
279  int col;
280 
281  switch( SCIPbdchginfoGetChgtype(bdchginfo) )
282  {
284  col = 2;
285  break;
287  col = 0;
288  break;
290  col = (SCIPbdchginfoGetInferProp(bdchginfo) == NULL ? 1 : 0);
291  break;
292  default:
293  SCIPerrorMessage("invalid bound change type\n");
294  col = 0;
295  SCIPABORT();
296  break;
297  }
298 
299  if( SCIPbdchginfoGetDepth(bdchginfo) == INT_MAX )
300  (void) SCIPsnprintf(depth, SCIP_MAXSTRLEN, "dive");
301  else
302  (void) SCIPsnprintf(depth, SCIP_MAXSTRLEN, "%d", SCIPbdchginfoGetDepth(bdchginfo));
303  (void) SCIPsnprintf(label, SCIP_MAXSTRLEN, "%s %s %g\n[%s:%d]", SCIPvarGetName(SCIPbdchginfoGetVar(bdchginfo)),
304  SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
305  SCIPbdchginfoGetNewbound(bdchginfo), depth, SCIPbdchginfoGetPos(bdchginfo));
306  confgraphWriteNode(bdchginfo, label, "ellipse", colors[col], "#000000");
307  confgraphWriteEdge(bdchginfo, confgraphcurrentbdchginfo, "#000000");
308 }
309 
310 /** links the already existing bound change node to the currently resolved bound change */
311 static
312 void confgraphLinkBdchg(
313  SCIP_BDCHGINFO* bdchginfo /**< bound change to add to the conflict graph */
314  )
315 {
316  confgraphWriteEdge(bdchginfo, confgraphcurrentbdchginfo, "#000000");
317 }
318 
319 /** marks the given bound change to be the currently resolved bound change */
320 static
321 void confgraphSetCurrentBdchg(
322  SCIP_BDCHGINFO* bdchginfo /**< bound change to add to the conflict graph */
323  )
324 {
325  confgraphcurrentbdchginfo = bdchginfo;
326 }
327 
328 /** marks given conflict set in the conflict graph */
329 static
330 void confgraphMarkConflictset(
331  SCIP_CONFLICTSET* conflictset /**< conflict set */
332  )
333 {
334  char label[SCIP_MAXSTRLEN];
335  int i;
336 
337  assert(conflictset != NULL);
338 
339  confgraphnconflictsets++;
340  (void) SCIPsnprintf(label, SCIP_MAXSTRLEN, "conf %d (%d)", confgraphnconflictsets, conflictset->validdepth);
341  confgraphWriteNode((void*)(size_t)confgraphnconflictsets, label, "rectangle", "#ff00ff", "#000000");
342  for( i = 0; i < conflictset->nbdchginfos; ++i )
343  confgraphWriteEdge((void*)(size_t)confgraphnconflictsets, conflictset->bdchginfos[i], "#ff00ff");
344 }
345 
346 #endif
347 
348 /*
349  * Conflict Handler
350  */
351 
352 /** compares two conflict handlers w. r. to their priority */
353 SCIP_DECL_SORTPTRCOMP(SCIPconflicthdlrComp)
354 { /*lint --e{715}*/
355  return ((SCIP_CONFLICTHDLR*)elem2)->priority - ((SCIP_CONFLICTHDLR*)elem1)->priority;
356 }
357 
358 /** comparison method for sorting conflict handler w.r.t. to their name */
359 SCIP_DECL_SORTPTRCOMP(SCIPconflicthdlrCompName)
360 {
362 }
363 
364 /** method to call, when the priority of a conflict handler was changed */
365 static
366 SCIP_DECL_PARAMCHGD(paramChgdConflicthdlrPriority)
367 { /*lint --e{715}*/
368  SCIP_PARAMDATA* paramdata;
369 
370  paramdata = SCIPparamGetData(param);
371  assert(paramdata != NULL);
372 
373  /* use SCIPsetConflicthdlrPriority() to mark the conflicthdlrs unsorted */
374  SCIP_CALL( SCIPsetConflicthdlrPriority(scip, (SCIP_CONFLICTHDLR*)paramdata, SCIPparamGetInt(param)) ); /*lint !e740*/
375 
376  return SCIP_OKAY;
377 }
378 
379 /** copies the given conflict handler to a new scip */
381  SCIP_CONFLICTHDLR* conflicthdlr, /**< conflict handler */
382  SCIP_SET* set /**< SCIP_SET of SCIP to copy to */
383  )
384 {
385  assert(conflicthdlr != NULL);
386  assert(set != NULL);
387  assert(set->scip != NULL);
388 
389  if( conflicthdlr->conflictcopy != NULL )
390  {
391  SCIPsetDebugMsg(set, "including conflict handler %s in subscip %p\n", SCIPconflicthdlrGetName(conflicthdlr), (void*)set->scip);
392  SCIP_CALL( conflicthdlr->conflictcopy(set->scip, conflicthdlr) );
393  }
394 
395  return SCIP_OKAY;
396 }
397 
398 /** internal method for creating a conflict handler */
399 static
401  SCIP_CONFLICTHDLR** conflicthdlr, /**< pointer to conflict handler data structure */
402  SCIP_SET* set, /**< global SCIP settings */
403  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
404  BMS_BLKMEM* blkmem, /**< block memory for parameter settings */
405  const char* name, /**< name of conflict handler */
406  const char* desc, /**< description of conflict handler */
407  int priority, /**< priority of the conflict handler */
408  SCIP_DECL_CONFLICTCOPY((*conflictcopy)), /**< copy method of conflict handler or NULL if you don't want to copy your plugin into sub-SCIPs */
409  SCIP_DECL_CONFLICTFREE((*conflictfree)), /**< destructor of conflict handler */
410  SCIP_DECL_CONFLICTINIT((*conflictinit)), /**< initialize conflict handler */
411  SCIP_DECL_CONFLICTEXIT((*conflictexit)), /**< deinitialize conflict handler */
412  SCIP_DECL_CONFLICTINITSOL((*conflictinitsol)),/**< solving process initialization method of conflict handler */
413  SCIP_DECL_CONFLICTEXITSOL((*conflictexitsol)),/**< solving process deinitialization method of conflict handler */
414  SCIP_DECL_CONFLICTEXEC((*conflictexec)), /**< conflict processing method of conflict handler */
415  SCIP_CONFLICTHDLRDATA* conflicthdlrdata /**< conflict handler data */
416  )
417 {
419  char paramdesc[SCIP_MAXSTRLEN];
420 
421  assert(conflicthdlr != NULL);
422  assert(name != NULL);
423  assert(desc != NULL);
424 
425  SCIP_ALLOC( BMSallocMemory(conflicthdlr) );
426  BMSclearMemory(*conflicthdlr);
427 
428  SCIP_ALLOC( BMSduplicateMemoryArray(&(*conflicthdlr)->name, name, strlen(name)+1) );
429  SCIP_ALLOC( BMSduplicateMemoryArray(&(*conflicthdlr)->desc, desc, strlen(desc)+1) );
430  (*conflicthdlr)->priority = priority;
431  (*conflicthdlr)->conflictcopy = conflictcopy;
432  (*conflicthdlr)->conflictfree = conflictfree;
433  (*conflicthdlr)->conflictinit = conflictinit;
434  (*conflicthdlr)->conflictexit = conflictexit;
435  (*conflicthdlr)->conflictinitsol = conflictinitsol;
436  (*conflicthdlr)->conflictexitsol = conflictexitsol;
437  (*conflicthdlr)->conflictexec = conflictexec;
438  (*conflicthdlr)->conflicthdlrdata = conflicthdlrdata;
439  (*conflicthdlr)->initialized = FALSE;
440 
441  SCIP_CALL( SCIPclockCreate(&(*conflicthdlr)->setuptime, SCIP_CLOCKTYPE_DEFAULT) );
442  SCIP_CALL( SCIPclockCreate(&(*conflicthdlr)->conflicttime, SCIP_CLOCKTYPE_DEFAULT) );
443 
444  /* add parameters */
445  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "conflict/%s/priority", name);
446  (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "priority of conflict handler <%s>", name);
447  SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc, &(*conflicthdlr)->priority, TRUE, \
448  priority, INT_MIN, INT_MAX, paramChgdConflicthdlrPriority, (SCIP_PARAMDATA*)(*conflicthdlr)) ); /*lint !e740*/
449 
450  return SCIP_OKAY;
451 }
452 
453 /** creates a conflict handler */
455  SCIP_CONFLICTHDLR** conflicthdlr, /**< pointer to conflict handler data structure */
456  SCIP_SET* set, /**< global SCIP settings */
457  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
458  BMS_BLKMEM* blkmem, /**< block memory for parameter settings */
459  const char* name, /**< name of conflict handler */
460  const char* desc, /**< description of conflict handler */
461  int priority, /**< priority of the conflict handler */
462  SCIP_DECL_CONFLICTCOPY((*conflictcopy)), /**< copy method of conflict handler or NULL if you don't want to
463  * copy your plugin into sub-SCIPs */
464  SCIP_DECL_CONFLICTFREE((*conflictfree)), /**< destructor of conflict handler */
465  SCIP_DECL_CONFLICTINIT((*conflictinit)), /**< initialize conflict handler */
466  SCIP_DECL_CONFLICTEXIT((*conflictexit)), /**< deinitialize conflict handler */
467  SCIP_DECL_CONFLICTINITSOL((*conflictinitsol)),/**< solving process initialization method of conflict handler */
468  SCIP_DECL_CONFLICTEXITSOL((*conflictexitsol)),/**< solving process deinitialization method of conflict handler */
469  SCIP_DECL_CONFLICTEXEC((*conflictexec)), /**< conflict processing method of conflict handler */
470  SCIP_CONFLICTHDLRDATA* conflicthdlrdata /**< conflict handler data */
471  )
472 {
473  assert(conflicthdlr != NULL);
474  assert(name != NULL);
475  assert(desc != NULL);
476 
477  SCIP_CALL_FINALLY( doConflicthdlrCreate(conflicthdlr, set, messagehdlr, blkmem, name, desc, priority,
478  conflictcopy, conflictfree, conflictinit, conflictexit, conflictinitsol, conflictexitsol, conflictexec,
479  conflicthdlrdata), (void) SCIPconflicthdlrFree(conflicthdlr, set) );
480 
481  return SCIP_OKAY;
482 }
483 
484 /** calls destructor and frees memory of conflict handler */
486  SCIP_CONFLICTHDLR** conflicthdlr, /**< pointer to conflict handler data structure */
487  SCIP_SET* set /**< global SCIP settings */
488  )
489 {
490  assert(conflicthdlr != NULL);
491  if( *conflicthdlr == NULL )
492  return SCIP_OKAY;
493  assert(!(*conflicthdlr)->initialized);
494  assert(set != NULL);
495 
496  /* call destructor of conflict handler */
497  if( (*conflicthdlr)->conflictfree != NULL )
498  {
499  SCIP_CALL( (*conflicthdlr)->conflictfree(set->scip, *conflicthdlr) );
500  }
501 
502  SCIPclockFree(&(*conflicthdlr)->conflicttime);
503  SCIPclockFree(&(*conflicthdlr)->setuptime);
504 
505  BMSfreeMemoryArrayNull(&(*conflicthdlr)->name);
506  BMSfreeMemoryArrayNull(&(*conflicthdlr)->desc);
507  BMSfreeMemory(conflicthdlr);
508 
509  return SCIP_OKAY;
510 }
511 
512 /** calls initialization method of conflict handler */
514  SCIP_CONFLICTHDLR* conflicthdlr, /**< conflict handler */
515  SCIP_SET* set /**< global SCIP settings */
516  )
517 {
518  assert(conflicthdlr != NULL);
519  assert(set != NULL);
520 
521  if( conflicthdlr->initialized )
522  {
523  SCIPerrorMessage("conflict handler <%s> already initialized\n", conflicthdlr->name);
524  return SCIP_INVALIDCALL;
525  }
526 
527  if( set->misc_resetstat )
528  {
529  SCIPclockReset(conflicthdlr->setuptime);
530  SCIPclockReset(conflicthdlr->conflicttime);
531  }
532 
533  /* call initialization method of conflict handler */
534  if( conflicthdlr->conflictinit != NULL )
535  {
536  /* start timing */
537  SCIPclockStart(conflicthdlr->setuptime, set);
538 
539  SCIP_CALL( conflicthdlr->conflictinit(set->scip, conflicthdlr) );
540 
541  /* stop timing */
542  SCIPclockStop(conflicthdlr->setuptime, set);
543  }
544  conflicthdlr->initialized = TRUE;
545 
546  return SCIP_OKAY;
547 }
548 
549 /** calls exit method of conflict handler */
551  SCIP_CONFLICTHDLR* conflicthdlr, /**< conflict handler */
552  SCIP_SET* set /**< global SCIP settings */
553  )
554 {
555  assert(conflicthdlr != NULL);
556  assert(set != NULL);
557 
558  if( !conflicthdlr->initialized )
559  {
560  SCIPerrorMessage("conflict handler <%s> not initialized\n", conflicthdlr->name);
561  return SCIP_INVALIDCALL;
562  }
563 
564  /* call deinitialization method of conflict handler */
565  if( conflicthdlr->conflictexit != NULL )
566  {
567  /* start timing */
568  SCIPclockStart(conflicthdlr->setuptime, set);
569 
570  SCIP_CALL( conflicthdlr->conflictexit(set->scip, conflicthdlr) );
571 
572  /* stop timing */
573  SCIPclockStop(conflicthdlr->setuptime, set);
574  }
575  conflicthdlr->initialized = FALSE;
576 
577  return SCIP_OKAY;
578 }
579 
580 /** informs conflict handler that the branch and bound process is being started */
582  SCIP_CONFLICTHDLR* conflicthdlr, /**< conflict handler */
583  SCIP_SET* set /**< global SCIP settings */
584  )
585 {
586  assert(conflicthdlr != NULL);
587  assert(set != NULL);
588 
589  /* call solving process initialization method of conflict handler */
590  if( conflicthdlr->conflictinitsol != NULL )
591  {
592  /* start timing */
593  SCIPclockStart(conflicthdlr->setuptime, set);
594 
595  SCIP_CALL( conflicthdlr->conflictinitsol(set->scip, conflicthdlr) );
596 
597  /* stop timing */
598  SCIPclockStop(conflicthdlr->setuptime, set);
599  }
600 
601  return SCIP_OKAY;
602 }
603 
604 /** informs conflict handler that the branch and bound process data is being freed */
606  SCIP_CONFLICTHDLR* conflicthdlr, /**< conflict handler */
607  SCIP_SET* set /**< global SCIP settings */
608  )
609 {
610  assert(conflicthdlr != NULL);
611  assert(set != NULL);
612 
613  /* call solving process deinitialization method of conflict handler */
614  if( conflicthdlr->conflictexitsol != NULL )
615  {
616  /* start timing */
617  SCIPclockStart(conflicthdlr->setuptime, set);
618 
619  SCIP_CALL( conflicthdlr->conflictexitsol(set->scip, conflicthdlr) );
620 
621  /* stop timing */
622  SCIPclockStop(conflicthdlr->setuptime, set);
623  }
624 
625  return SCIP_OKAY;
626 }
627 
628 /** calls execution method of conflict handler */
630  SCIP_CONFLICTHDLR* conflicthdlr, /**< conflict handler */
631  SCIP_SET* set, /**< global SCIP settings */
632  SCIP_NODE* node, /**< node to add conflict constraint to */
633  SCIP_NODE* validnode, /**< node at which the constraint is valid */
634  SCIP_BDCHGINFO** bdchginfos, /**< bound change resembling the conflict set */
635  SCIP_Real* relaxedbds, /**< array with relaxed bounds which are efficient to create a valid conflict */
636  int nbdchginfos, /**< number of bound changes in the conflict set */
637  SCIP_CONFTYPE conftype, /**< type of the conflict */
638  SCIP_Bool usescutoffbound, /**< depends the conflict on the cutoff bound? */
639  SCIP_Bool resolved, /**< was the conflict set already used to create a constraint? */
640  SCIP_RESULT* result /**< pointer to store the result of the callback method */
641  )
642 {
643  assert(conflicthdlr != NULL);
644  assert(set != NULL);
645  assert(bdchginfos != NULL || nbdchginfos == 0);
646  assert(result != NULL);
647 
648  /* call solution start method of conflict handler */
649  *result = SCIP_DIDNOTRUN;
650  if( conflicthdlr->conflictexec != NULL )
651  {
652  /* start timing */
653  SCIPclockStart(conflicthdlr->conflicttime, set);
654 
655  SCIP_CALL( conflicthdlr->conflictexec(set->scip, conflicthdlr, node, validnode, bdchginfos, relaxedbds, nbdchginfos,
656  conftype, usescutoffbound, set->conf_separate, (SCIPnodeGetDepth(validnode) > 0), set->conf_dynamic,
657  set->conf_removable, resolved, result) );
658 
659  /* stop timing */
660  SCIPclockStop(conflicthdlr->conflicttime, set);
661 
662  if( *result != SCIP_CONSADDED
663  && *result != SCIP_DIDNOTFIND
664  && *result != SCIP_DIDNOTRUN )
665  {
666  SCIPerrorMessage("execution method of conflict handler <%s> returned invalid result <%d>\n",
667  conflicthdlr->name, *result);
668  return SCIP_INVALIDRESULT;
669  }
670  }
671 
672  return SCIP_OKAY;
673 }
674 
675 /** gets user data of conflict handler */
677  SCIP_CONFLICTHDLR* conflicthdlr /**< conflict handler */
678  )
679 {
680  assert(conflicthdlr != NULL);
681 
682  return conflicthdlr->conflicthdlrdata;
683 }
684 
685 /** sets user data of conflict handler; user has to free old data in advance! */
687  SCIP_CONFLICTHDLR* conflicthdlr, /**< conflict handler */
688  SCIP_CONFLICTHDLRDATA* conflicthdlrdata /**< new conflict handler user data */
689  )
690 {
691  assert(conflicthdlr != NULL);
692 
693  conflicthdlr->conflicthdlrdata = conflicthdlrdata;
694 }
695 
696 /** set copy method of conflict handler */
698  SCIP_CONFLICTHDLR* conflicthdlr, /**< conflict handler */
699  SCIP_DECL_CONFLICTCOPY((*conflictcopy)) /**< copy method of the conflict handler */
700  )
701 {
702  assert(conflicthdlr != NULL);
703 
704  conflicthdlr->conflictcopy = conflictcopy;
705 }
706 
707 /** set destructor of conflict handler */
709  SCIP_CONFLICTHDLR* conflicthdlr, /**< conflict handler */
710  SCIP_DECL_CONFLICTFREE((*conflictfree)) /**< destructor of conflict handler */
711  )
712 {
713  assert(conflicthdlr != NULL);
714 
715  conflicthdlr->conflictfree = conflictfree;
716 }
717 
718 /** set initialization method of conflict handler */
720  SCIP_CONFLICTHDLR* conflicthdlr, /**< conflict handler */
721  SCIP_DECL_CONFLICTINIT((*conflictinit)) /**< initialization method conflict handler */
722  )
723 {
724  assert(conflicthdlr != NULL);
725 
726  conflicthdlr->conflictinit = conflictinit;
727 }
728 
729 /** set deinitialization method of conflict handler */
731  SCIP_CONFLICTHDLR* conflicthdlr, /**< conflict handler */
732  SCIP_DECL_CONFLICTEXIT((*conflictexit)) /**< deinitialization method conflict handler */
733  )
734 {
735  assert(conflicthdlr != NULL);
736 
737  conflicthdlr->conflictexit = conflictexit;
738 }
739 
740 /** set solving process initialization method of conflict handler */
742  SCIP_CONFLICTHDLR* conflicthdlr, /**< conflict handler */
743  SCIP_DECL_CONFLICTINITSOL((*conflictinitsol))/**< solving process initialization method of conflict handler */
744  )
745 {
746  assert(conflicthdlr != NULL);
747 
748  conflicthdlr->conflictinitsol = conflictinitsol;
749 }
750 
751 /** set solving process deinitialization method of conflict handler */
753  SCIP_CONFLICTHDLR* conflicthdlr, /**< conflict handler */
754  SCIP_DECL_CONFLICTEXITSOL((*conflictexitsol))/**< solving process deinitialization method of conflict handler */
755  )
756 {
757  assert(conflicthdlr != NULL);
758 
759  conflicthdlr->conflictexitsol = conflictexitsol;
760 }
761 
762 /** gets name of conflict handler */
764  SCIP_CONFLICTHDLR* conflicthdlr /**< conflict handler */
765  )
766 {
767  assert(conflicthdlr != NULL);
768 
769  return conflicthdlr->name;
770 }
771 
772 /** gets description of conflict handler */
774  SCIP_CONFLICTHDLR* conflicthdlr /**< conflict handler */
775  )
776 {
777  assert(conflicthdlr != NULL);
778 
779  return conflicthdlr->desc;
780 }
781 
782 /** gets priority of conflict handler */
784  SCIP_CONFLICTHDLR* conflicthdlr /**< conflict handler */
785  )
786 {
787  assert(conflicthdlr != NULL);
788 
789  return conflicthdlr->priority;
790 }
791 
792 /** sets priority of conflict handler */
794  SCIP_CONFLICTHDLR* conflicthdlr, /**< conflict handler */
795  SCIP_SET* set, /**< global SCIP settings */
796  int priority /**< new priority of the conflict handler */
797  )
798 {
799  assert(conflicthdlr != NULL);
800  assert(set != NULL);
801 
802  conflicthdlr->priority = priority;
803  set->conflicthdlrssorted = FALSE;
804 }
805 
806 /** is conflict handler initialized? */
808  SCIP_CONFLICTHDLR* conflicthdlr /**< conflict handler */
809  )
810 {
811  assert(conflicthdlr != NULL);
812 
813  return conflicthdlr->initialized;
814 }
815 
816 /** enables or disables all clocks of \p conflicthdlr, depending on the value of the flag */
818  SCIP_CONFLICTHDLR* conflicthdlr, /**< the conflict handler for which all clocks should be enabled or disabled */
819  SCIP_Bool enable /**< should the clocks of the conflict handler be enabled? */
820  )
821 {
822  assert(conflicthdlr != NULL);
823 
824  SCIPclockEnableOrDisable(conflicthdlr->setuptime, enable);
825  SCIPclockEnableOrDisable(conflicthdlr->conflicttime, enable);
826 }
827 
828 /** gets time in seconds used in this conflict handler for setting up for next stages */
830  SCIP_CONFLICTHDLR* conflicthdlr /**< conflict handler */
831  )
832 {
833  assert(conflicthdlr != NULL);
834 
835  return SCIPclockGetTime(conflicthdlr->setuptime);
836 }
837 
838 /** gets time in seconds used in this conflict handler */
840  SCIP_CONFLICTHDLR* conflicthdlr /**< conflict handler */
841  )
842 {
843  assert(conflicthdlr != NULL);
844 
845  return SCIPclockGetTime(conflicthdlr->conflicttime);
846 }
847 
848 /*
849  * Conflict LP Bound Changes
850  */
851 
852 
853 /** create conflict LP bound change data structure */
854 static
856  SCIP_LPBDCHGS** lpbdchgs, /**< pointer to store the conflict LP bound change data structure */
857  SCIP_SET* set, /**< global SCIP settings */
858  int ncols /**< number of columns */
859  )
860 {
861  SCIP_CALL( SCIPsetAllocBuffer(set, lpbdchgs) );
862 
863  SCIP_CALL( SCIPsetAllocBufferArray(set, &(*lpbdchgs)->bdchginds, ncols) );
864  SCIP_CALL( SCIPsetAllocBufferArray(set, &(*lpbdchgs)->bdchglbs, ncols) );
865  SCIP_CALL( SCIPsetAllocBufferArray(set, &(*lpbdchgs)->bdchgubs, ncols) );
866  SCIP_CALL( SCIPsetAllocBufferArray(set, &(*lpbdchgs)->bdchgcolinds, ncols) );
867  SCIP_CALL( SCIPsetAllocBufferArray(set, &(*lpbdchgs)->usedcols, ncols) );
868  BMSclearMemoryArray((*lpbdchgs)->usedcols, ncols);
869 
870  (*lpbdchgs)->nbdchgs = 0;
871 
872  return SCIP_OKAY;
873 }
874 
875 /** reset conflict LP bound change data structure */
876 static
878  SCIP_LPBDCHGS* lpbdchgs, /**< conflict LP bound change data structure */
879  int ncols /**< number of columns */
880  )
881 {
882  assert(lpbdchgs != NULL);
883 
884  BMSclearMemoryArray(lpbdchgs->usedcols, ncols);
885  lpbdchgs->nbdchgs = 0;
886 }
887 
888 /** free conflict LP bound change data structure */
889 static
891  SCIP_LPBDCHGS** lpbdchgs, /**< pointer to store the conflict LP bound change data structure */
892  SCIP_SET* set /**< global SCIP settings */
893  )
894 {
895  SCIPsetFreeBufferArray(set, &(*lpbdchgs)->usedcols);
896  SCIPsetFreeBufferArray(set, &(*lpbdchgs)->bdchgcolinds);
897  SCIPsetFreeBufferArray(set, &(*lpbdchgs)->bdchgubs);
898  SCIPsetFreeBufferArray(set, &(*lpbdchgs)->bdchglbs);
899  SCIPsetFreeBufferArray(set, &(*lpbdchgs)->bdchginds);
900 
901  SCIPsetFreeBuffer(set, lpbdchgs);
902 }
903 
904 /*
905  * Proof Sets
906  */
907 
908 /** return the char associated with the type of the variable */
909 static
911  SCIP_VAR* var /**< variable */
912  )
913 {
914  SCIP_VARTYPE vartype = SCIPvarGetType(var);
915 
916  return (!SCIPvarIsIntegral(var) ? 'C' :
917  (vartype == SCIP_VARTYPE_BINARY ? 'B' :
918  (vartype == SCIP_VARTYPE_INTEGER ? 'I' : 'M')));
919 }
920 
921 /** resets the data structure of a proofset */
922 static
924  SCIP_PROOFSET* proofset /**< proof set */
925  )
926 {
927  assert(proofset != NULL);
928 
929  proofset->nnz = 0;
930  proofset->rhs = 0.0;
931  proofset->validdepth = 0;
933 }
934 
935 /** creates a proofset */
936 static
938  SCIP_PROOFSET** proofset, /**< proof set */
939  BMS_BLKMEM* blkmem /**< block memory of transformed problem */
940  )
941 {
942  assert(proofset != NULL);
943 
944  SCIP_ALLOC( BMSallocBlockMemory(blkmem, proofset) );
945  (*proofset)->vals = NULL;
946  (*proofset)->inds = NULL;
947  (*proofset)->rhs = 0.0;
948  (*proofset)->nnz = 0;
949  (*proofset)->size = 0;
950  (*proofset)->validdepth = 0;
951  (*proofset)->conflicttype = SCIP_CONFTYPE_UNKNOWN;
952 
953  return SCIP_OKAY;
954 }
955 
956 /** creates and clears the proofset */
957 static
959  SCIP_CONFLICT* conflict, /**< conflict analysis data */
960  BMS_BLKMEM* blkmem /**< block memory of transformed problem */
961  )
962 {
963  assert(conflict != NULL);
964  assert(blkmem != NULL);
965 
966  SCIP_CALL( proofsetCreate(&conflict->proofset, blkmem) );
967 
968  return SCIP_OKAY;
969 }
970 
971 /** frees a proofset */
972 static
974  SCIP_PROOFSET** proofset, /**< proof set */
975  BMS_BLKMEM* blkmem /**< block memory */
976  )
977 {
978  assert(proofset != NULL);
979  assert(*proofset != NULL);
980  assert(blkmem != NULL);
981 
982  BMSfreeBlockMemoryArrayNull(blkmem, &(*proofset)->vals, (*proofset)->size);
983  BMSfreeBlockMemoryArrayNull(blkmem, &(*proofset)->inds, (*proofset)->size);
984  BMSfreeBlockMemory(blkmem, proofset);
985  (*proofset) = NULL;
986 }
987 
988 #ifdef SCIP_DEBUG
989 static
990 void proofsetPrint(
991  SCIP_PROOFSET* proofset,
992  SCIP_SET* set,
993  SCIP_PROB* transprob
994  )
995 {
996  SCIP_VAR** vars;
997  int i;
998 
999  assert(proofset != NULL);
1000 
1001  vars = SCIPprobGetVars(transprob);
1002  assert(vars != NULL);
1003 
1004  printf("proofset: ");
1005  for( i = 0; i < proofset->nnz; i++ )
1006  printf("%+.15g <%s> ", proofset->vals[i], SCIPvarGetName(vars[proofset->inds[i]]));
1007  printf(" <= %.15g\n", proofset->rhs);
1008 }
1009 #endif
1010 
1011 /** return the indices of variables in the proofset */
1012 static
1014  SCIP_PROOFSET* proofset /**< proof set */
1015  )
1016 {
1017  assert(proofset != NULL);
1018 
1019  return proofset->inds;
1020 }
1021 
1022 /** return coefficient of variable in the proofset with given probindex */
1023 static
1025  SCIP_PROOFSET* proofset /**< proof set */
1026  )
1027 {
1028  assert(proofset != NULL);
1029 
1030  return proofset->vals;
1031 }
1032 
1033 /** return the right-hand side if a proofset */
1034 static
1036  SCIP_PROOFSET* proofset /**< proof set */
1037  )
1038 {
1039  assert(proofset != NULL);
1040 
1041  return proofset->rhs;
1042 }
1043 
1044 /** returns the number of variables in the proofset */
1045 static
1047  SCIP_PROOFSET* proofset /**< proof set */
1048  )
1049 {
1050  assert(proofset != NULL);
1051 
1052  return proofset->nnz;
1053 }
1054 
1055 /** returns the number of variables in the proofset */
1056 static
1058  SCIP_PROOFSET* proofset /**< proof set */
1059  )
1060 {
1061  assert(proofset != NULL);
1062 
1063  return proofset->conflicttype;
1064 }
1065 
1066 /** adds given data as aggregation row to the proofset */
1067 static
1069  SCIP_PROOFSET* proofset, /**< proof set */
1070  BMS_BLKMEM* blkmem, /**< block memory */
1071  SCIP_Real* vals, /**< variable coefficients */
1072  int* inds, /**< variable array */
1073  int nnz, /**< size of variable and coefficient array */
1074  SCIP_Real rhs /**< right-hand side of the aggregation row */
1075  )
1076 {
1077  assert(proofset != NULL);
1078  assert(blkmem != NULL);
1079 
1080  if( proofset->size == 0 )
1081  {
1082  assert(proofset->vals == NULL);
1083  assert(proofset->inds == NULL);
1084 
1085  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &proofset->vals, vals, nnz) );
1086  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &proofset->inds, inds, nnz) );
1087 
1088  proofset->size = nnz;
1089  }
1090  else
1091  {
1092  int i;
1093 
1094  assert(proofset->vals != NULL);
1095  assert(proofset->inds != NULL);
1096 
1097  if( proofset->size < nnz )
1098  {
1099  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &proofset->vals, proofset->size, nnz) );
1100  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &proofset->inds, proofset->size, nnz) );
1101  proofset->size = nnz;
1102  }
1103 
1104  for( i = 0; i < nnz; i++ )
1105  {
1106  proofset->vals[i] = vals[i];
1107  proofset->inds[i] = inds[i];
1108  }
1109  }
1110 
1111  proofset->rhs = rhs;
1112  proofset->nnz = nnz;
1113 
1114  return SCIP_OKAY;
1115 }
1116 
1117 /** adds an aggregation row to the proofset */
1118 static
1120  SCIP_PROOFSET* proofset, /**< proof set */
1121  SCIP_SET* set, /**< global SCIP settings */
1122  BMS_BLKMEM* blkmem, /**< block memory */
1123  SCIP_AGGRROW* aggrrow /**< aggregation row to add */
1124  )
1125 {
1126  SCIP_Real* vals;
1127  int* inds;
1128  int nnz;
1129  int i;
1130 
1131  assert(proofset != NULL);
1132  assert(set != NULL);
1133 
1134  inds = SCIPaggrRowGetInds(aggrrow);
1135  assert(inds != NULL);
1136 
1137  nnz = SCIPaggrRowGetNNz(aggrrow);
1138  assert(nnz > 0);
1139 
1140  SCIP_CALL( SCIPsetAllocBufferArray(set, &vals, nnz) );
1141 
1142  for( i = 0; i < nnz; i++ )
1143  {
1144  vals[i] = SCIPaggrRowGetProbvarValue(aggrrow, inds[i]);
1145  }
1146 
1147  SCIP_CALL( proofsetAddSparseData(proofset, blkmem, vals, inds, nnz, SCIPaggrRowGetRhs(aggrrow)) );
1148 
1149  SCIPsetFreeBufferArray(set, &vals);
1150 
1151  return SCIP_OKAY;
1152 }
1153 
1154 /** Removes a given variable @p var from position @p pos from the proofset and updates the right-hand side according
1155  * to sign of the coefficient, i.e., rhs -= coef * bound, where bound = lb if coef >= 0 and bound = ub, otherwise.
1156  *
1157  * @note: The list of non-zero indices and coefficients will be updated by swapping the last non-zero index to @p pos.
1158  */
1159 static
1161  SCIP_PROOFSET* proofset,
1162  SCIP_SET* set,
1163  SCIP_VAR* var,
1164  int pos,
1165  SCIP_Bool* valid
1166  )
1167 {
1168  assert(proofset != NULL);
1169  assert(var != NULL);
1170  assert(pos >= 0 && pos < proofset->nnz);
1171  assert(valid != NULL);
1172 
1173  *valid = TRUE;
1174 
1175  /* cancel with lower bound */
1176  if( proofset->vals[pos] > 0.0 )
1177  {
1178  proofset->rhs -= proofset->vals[pos] * SCIPvarGetLbGlobal(var);
1179  }
1180  /* cancel with upper bound */
1181  else
1182  {
1183  assert(proofset->vals[pos] < 0.0);
1184  proofset->rhs -= proofset->vals[pos] * SCIPvarGetUbGlobal(var);
1185  }
1186 
1187  --proofset->nnz;
1188 
1189  proofset->vals[pos] = proofset->vals[proofset->nnz];
1190  proofset->inds[pos] = proofset->inds[proofset->nnz];
1191  proofset->vals[proofset->nnz] = 0.0;
1192  proofset->inds[proofset->nnz] = 0;
1193 
1194  if( SCIPsetIsInfinity(set, proofset->rhs) )
1195  *valid = FALSE;
1196 }
1197 
1198 /*
1199  * Conflict Sets
1200  */
1201 
1202 /** resizes the array of the temporary bound change informations to be able to store at least num bound change entries */
1203 static
1205  SCIP_CONFLICT* conflict, /**< conflict analysis data */
1206  SCIP_SET* set, /**< global SCIP settings */
1207  int num /**< minimal number of slots in arrays */
1208  )
1209 {
1210  assert(conflict != NULL);
1211  assert(set != NULL);
1212 
1213  if( num > conflict->tmpbdchginfossize )
1214  {
1215  int newsize;
1216 
1217  newsize = SCIPsetCalcMemGrowSize(set, num);
1218  SCIP_ALLOC( BMSreallocMemoryArray(&conflict->tmpbdchginfos, newsize) );
1219  conflict->tmpbdchginfossize = newsize;
1220  }
1221  assert(num <= conflict->tmpbdchginfossize);
1222 
1223  return SCIP_OKAY;
1224 }
1225 
1226 /** creates a temporary bound change information object that is destroyed after the conflict sets are flushed */
1227 static
1229  SCIP_CONFLICT* conflict, /**< conflict analysis data */
1230  BMS_BLKMEM* blkmem, /**< block memory */
1231  SCIP_SET* set, /**< global SCIP settings */
1232  SCIP_VAR* var, /**< active variable that changed the bounds */
1233  SCIP_BOUNDTYPE boundtype, /**< type of bound for var: lower or upper bound */
1234  SCIP_Real oldbound, /**< old value for bound */
1235  SCIP_Real newbound, /**< new value for bound */
1236  SCIP_BDCHGINFO** bdchginfo /**< pointer to store bound change information */
1237  )
1238 {
1239  assert(conflict != NULL);
1240 
1241  SCIP_CALL( conflictEnsureTmpbdchginfosMem(conflict, set, conflict->ntmpbdchginfos+1) );
1242  SCIP_CALL( SCIPbdchginfoCreate(&conflict->tmpbdchginfos[conflict->ntmpbdchginfos], blkmem,
1243  var, boundtype, oldbound, newbound) );
1244  *bdchginfo = conflict->tmpbdchginfos[conflict->ntmpbdchginfos];
1245  conflict->ntmpbdchginfos++;
1246 
1247  return SCIP_OKAY;
1248 }
1249 
1250 /** frees all temporarily created bound change information data */
1251 static
1253  SCIP_CONFLICT* conflict, /**< conflict analysis data */
1254  BMS_BLKMEM* blkmem /**< block memory */
1255  )
1256 {
1257  int i;
1258 
1259  assert(conflict != NULL);
1260 
1261  for( i = 0; i < conflict->ntmpbdchginfos; ++i )
1262  SCIPbdchginfoFree(&conflict->tmpbdchginfos[i], blkmem);
1263  conflict->ntmpbdchginfos = 0;
1264 }
1265 
1266 /** clears the given conflict set */
1267 static
1269  SCIP_CONFLICTSET* conflictset /**< conflict set */
1270  )
1271 {
1272  assert(conflictset != NULL);
1273 
1274  conflictset->nbdchginfos = 0;
1275  conflictset->validdepth = 0;
1276  conflictset->insertdepth = 0;
1277  conflictset->conflictdepth = 0;
1278  conflictset->repropdepth = 0;
1279  conflictset->repropagate = TRUE;
1280  conflictset->usescutoffbound = FALSE;
1281  conflictset->conflicttype = SCIP_CONFTYPE_UNKNOWN;
1282 }
1283 
1284 /** creates an empty conflict set */
1285 static
1287  SCIP_CONFLICTSET** conflictset, /**< pointer to store the conflict set */
1288  BMS_BLKMEM* blkmem /**< block memory of transformed problem */
1289  )
1290 {
1291  assert(conflictset != NULL);
1292 
1293  SCIP_ALLOC( BMSallocBlockMemory(blkmem, conflictset) );
1294  (*conflictset)->bdchginfos = NULL;
1295  (*conflictset)->relaxedbds = NULL;
1296  (*conflictset)->sortvals = NULL;
1297  (*conflictset)->bdchginfossize = 0;
1298 
1299  conflictsetClear(*conflictset);
1300 
1301  return SCIP_OKAY;
1302 }
1303 
1304 /** creates a copy of the given conflict set, allocating an additional amount of memory */
1305 static
1307  SCIP_CONFLICTSET** targetconflictset, /**< pointer to store the conflict set */
1308  BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
1309  SCIP_CONFLICTSET* sourceconflictset, /**< source conflict set */
1310  int nadditionalelems /**< number of additional elements to allocate memory for */
1311  )
1312 {
1313  int targetsize;
1314 
1315  assert(targetconflictset != NULL);
1316  assert(sourceconflictset != NULL);
1317 
1318  targetsize = sourceconflictset->nbdchginfos + nadditionalelems;
1319  SCIP_ALLOC( BMSallocBlockMemory(blkmem, targetconflictset) );
1320  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*targetconflictset)->bdchginfos, targetsize) );
1321  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*targetconflictset)->relaxedbds, targetsize) );
1322  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*targetconflictset)->sortvals, targetsize) );
1323  (*targetconflictset)->bdchginfossize = targetsize;
1324 
1325  BMScopyMemoryArray((*targetconflictset)->bdchginfos, sourceconflictset->bdchginfos, sourceconflictset->nbdchginfos);
1326  BMScopyMemoryArray((*targetconflictset)->relaxedbds, sourceconflictset->relaxedbds, sourceconflictset->nbdchginfos);
1327  BMScopyMemoryArray((*targetconflictset)->sortvals, sourceconflictset->sortvals, sourceconflictset->nbdchginfos);
1328 
1329  (*targetconflictset)->nbdchginfos = sourceconflictset->nbdchginfos;
1330  (*targetconflictset)->validdepth = sourceconflictset->validdepth;
1331  (*targetconflictset)->insertdepth = sourceconflictset->insertdepth;
1332  (*targetconflictset)->conflictdepth = sourceconflictset->conflictdepth;
1333  (*targetconflictset)->repropdepth = sourceconflictset->repropdepth;
1334  (*targetconflictset)->usescutoffbound = sourceconflictset->usescutoffbound;
1335  (*targetconflictset)->conflicttype = sourceconflictset->conflicttype;
1336 
1337  return SCIP_OKAY;
1338 }
1339 
1340 /** frees a conflict set */
1341 static
1343  SCIP_CONFLICTSET** conflictset, /**< pointer to the conflict set */
1344  BMS_BLKMEM* blkmem /**< block memory of transformed problem */
1345  )
1346 {
1347  assert(conflictset != NULL);
1348  assert(*conflictset != NULL);
1349 
1350  BMSfreeBlockMemoryArrayNull(blkmem, &(*conflictset)->bdchginfos, (*conflictset)->bdchginfossize);
1351  BMSfreeBlockMemoryArrayNull(blkmem, &(*conflictset)->relaxedbds, (*conflictset)->bdchginfossize);
1352  BMSfreeBlockMemoryArrayNull(blkmem, &(*conflictset)->sortvals, (*conflictset)->bdchginfossize);
1353  BMSfreeBlockMemory(blkmem, conflictset);
1354 }
1355 
1356 /** resizes the arrays of the conflict set to be able to store at least num bound change entries */
1357 static
1359  SCIP_CONFLICTSET* conflictset, /**< conflict set */
1360  BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
1361  SCIP_SET* set, /**< global SCIP settings */
1362  int num /**< minimal number of slots in arrays */
1363  )
1364 {
1365  assert(conflictset != NULL);
1366  assert(set != NULL);
1367 
1368  if( num > conflictset->bdchginfossize )
1369  {
1370  int newsize;
1371 
1372  newsize = SCIPsetCalcMemGrowSize(set, num);
1373  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &conflictset->bdchginfos, conflictset->bdchginfossize, newsize) );
1374  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &conflictset->relaxedbds, conflictset->bdchginfossize, newsize) );
1375  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &conflictset->sortvals, conflictset->bdchginfossize, newsize) );
1376  conflictset->bdchginfossize = newsize;
1377  }
1378  assert(num <= conflictset->bdchginfossize);
1379 
1380  return SCIP_OKAY;
1381 }
1382 
1383 /** calculates the score of the conflict set
1384  *
1385  * the score is weighted sum of number of bound changes, repropagation depth, and valid depth
1386  */
1387 static
1389  SCIP_CONFLICTSET* conflictset, /**< conflict set */
1390  SCIP_SET* set /**< global SCIP settings */
1391  )
1392 {
1393  assert(conflictset != NULL);
1394 
1395  return -(set->conf_weightsize * conflictset->nbdchginfos
1396  + set->conf_weightrepropdepth * conflictset->repropdepth
1397  + set->conf_weightvaliddepth * conflictset->validdepth);
1398 }
1399 
1400 /** calculates the score of a bound change within a conflict */
1401 static
1403  SCIP_Real prooflhs, /**< lhs of proof constraint */
1404  SCIP_Real proofact, /**< activity of the proof constraint */
1405  SCIP_Real proofactdelta, /**< activity change */
1406  SCIP_Real proofcoef, /**< coefficient in proof constraint */
1407  int depth, /**< bound change depth */
1408  int currentdepth, /**< current depth */
1409  SCIP_VAR* var, /**< variable corresponding to bound change */
1410  SCIP_SET* set /**< global SCIP settings */
1411  )
1412 {
1413  SCIP_COL* col;
1414  SCIP_Real score;
1415 
1416  score = set->conf_proofscorefac * (1.0 - proofactdelta/(prooflhs - proofact));
1417  score = MAX(score, 0.0);
1418  score += set->conf_depthscorefac * (SCIP_Real)(depth+1)/(SCIP_Real)(currentdepth+1);
1419 
1421  col = SCIPvarGetCol(var);
1422  else
1423  col = NULL;
1424 
1425  if( proofcoef > 0.0 )
1426  {
1427  if( col != NULL && SCIPcolGetNNonz(col) > 0 )
1428  score += set->conf_uplockscorefac
1430  else
1431  score += set->conf_uplockscorefac * SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL);
1432  }
1433  else
1434  {
1435  if( col != NULL && SCIPcolGetNNonz(col) > 0 )
1436  score += set->conf_downlockscorefac
1438  else
1439  score += set->conf_downlockscorefac * SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL);
1440  }
1441 
1442  return score;
1443 }
1444 
1445 /** check if the bound change info (which is the potential next candidate which is queued) is valid for the current
1446  * conflict analysis; a bound change info can get invalid if after this one was added to the queue, a weaker bound
1447  * change was added to the queue (due the bound widening idea) which immediately makes this bound change redundant; due
1448  * to the priority we did not removed that bound change info since that cost O(log(n)); hence we have to skip/ignore it
1449  * now
1450  *
1451  * The following situations can occur before for example the bound change info (x >= 3) is potentially popped from the
1452  * queue.
1453  *
1454  * Postcondition: the reason why (x >= 3) was queued is that at this time point no lower bound of x was involved yet in
1455  * the current conflict or the lower bound which was involved until then was stronger, e.g., (x >= 2).
1456  *
1457  * 1) during the time until (x >= 3) gets potentially popped no weaker lower bound was added to the queue, in that case
1458  * the conflictlbcount is valid and conflictlb is 3; that is (var->conflictlbcount == conflict->count &&
1459  * var->conflictlb == 3)
1460  *
1461  * 2) a weaker bound change info gets queued (e.g., x >= 4); this bound change is popped before (x >= 3) since it has
1462  * higher priority (which is the time stamp of the bound change info and (x >= 4) has to be done after (x >= 3)
1463  * during propagation or branching)
1464  *
1465  * a) if (x >= 4) is popped and added to the conflict set the conflictlbcount is still valid and conflictlb is at
1466  * most 4; that is (var->conflictlbcount == conflict->count && var->conflictlb >= 4); it follows that any bound
1467  * change info which is stronger than (x >= 4) gets ignored (for example x >= 2)
1468  *
1469  * b) if (x >= 4) is popped and resolved without introducing a new lower bound on x until (x >= 3) is a potentially
1470  * candidate the conflictlbcount indicates that bound change is currently not present; that is
1471  * (var->conflictlbcount != conflict->count)
1472  *
1473  * 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
1474  * pooped, the conflictlbcount indicates that bound change is currently present; that is (var->conflictlbcount ==
1475  * conflict->count); however the (x >= 3) only has be explained if conflictlb matches that one; that is
1476  * (var->conflictlb == bdchginfo->newbound); otherwise it redundant/invalid.
1477  */
1478 static
1480  SCIP_CONFLICT* conflict, /**< conflict analysis data */
1481  SCIP_BDCHGINFO* bdchginfo /**< bound change information */
1482  )
1483 {
1484  SCIP_VAR* var;
1485 
1486  assert(bdchginfo != NULL);
1487 
1488  var = SCIPbdchginfoGetVar(bdchginfo);
1489  assert(var != NULL);
1490 
1491  /* the bound change info of a binary (domained) variable can never be invalid since the concepts of relaxed bounds
1492  * and bound widening do not make sense for these type of variables
1493  */
1494  if( SCIPvarIsBinary(var) )
1495  return FALSE;
1496 
1497  /* check if the bdchginfo is invaild since a tight/weaker bound change was already explained */
1499  {
1500  if( var->conflictlbcount != conflict->count || var->conflictlb != SCIPbdchginfoGetNewbound(bdchginfo) ) /*lint !e777*/
1501  {
1502  assert(!SCIPvarIsBinary(var));
1503  return TRUE;
1504  }
1505  }
1506  else
1507  {
1508  assert(SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_UPPER);
1509 
1510  if( var->conflictubcount != conflict->count || var->conflictub != SCIPbdchginfoGetNewbound(bdchginfo) ) /*lint !e777*/
1511  {
1512  assert(!SCIPvarIsBinary(var));
1513  return TRUE;
1514  }
1515  }
1516 
1517  return FALSE;
1518 }
1519 
1520 /** adds a bound change to a conflict set */
1521 static
1523  SCIP_CONFLICTSET* conflictset, /**< conflict set */
1524  BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
1525  SCIP_SET* set, /**< global SCIP settings */
1526  SCIP_BDCHGINFO* bdchginfo, /**< bound change to add to the conflict set */
1527  SCIP_Real relaxedbd /**< relaxed bound */
1528  )
1529 {
1530  SCIP_BDCHGINFO** bdchginfos;
1531  SCIP_Real* relaxedbds;
1532  int* sortvals;
1533  SCIP_VAR* var;
1534  SCIP_BOUNDTYPE boundtype;
1535  int idx;
1536  int sortval;
1537  int pos;
1538 
1539  assert(conflictset != NULL);
1540  assert(bdchginfo != NULL);
1541 
1542  /* allocate memory for additional element */
1543  SCIP_CALL( conflictsetEnsureBdchginfosMem(conflictset, blkmem, set, conflictset->nbdchginfos+1) );
1544 
1545  /* insert the new bound change in the arrays sorted by increasing variable index and by bound type */
1546  bdchginfos = conflictset->bdchginfos;
1547  relaxedbds = conflictset->relaxedbds;
1548  sortvals = conflictset->sortvals;
1549  var = SCIPbdchginfoGetVar(bdchginfo);
1550  boundtype = SCIPbdchginfoGetBoundtype(bdchginfo);
1551  idx = SCIPvarGetIndex(var);
1552  assert(idx < INT_MAX/2);
1553  assert((int)boundtype == 0 || (int)boundtype == 1);
1554  sortval = 2*idx + (int)boundtype; /* first sorting criteria: variable index, second criteria: boundtype */
1555 
1556  /* insert new element into the sorted arrays; if an element exits with the same value insert the new element afterwards
1557  *
1558  * @todo check if it better (faster) to first search for the position O(log n) and compare the sort values and if
1559  * they are equal just replace the element and if not run the insert method O(n)
1560  */
1561 
1562  SCIPsortedvecInsertIntPtrReal(sortvals, (void**)bdchginfos, relaxedbds, sortval, (void*)bdchginfo, relaxedbd, &conflictset->nbdchginfos, &pos);
1563  assert(pos == conflictset->nbdchginfos - 1 || sortval < sortvals[pos+1]);
1564 
1565  /* merge multiple bound changes */
1566  if( pos > 0 && sortval == sortvals[pos-1] )
1567  {
1568  /* this is a multiple bound change */
1569  if( SCIPbdchginfoIsTighter(bdchginfo, bdchginfos[pos-1]) )
1570  {
1571  /* remove the "old" bound change since the "new" one in tighter */
1572  SCIPsortedvecDelPosIntPtrReal(sortvals, (void**)bdchginfos, relaxedbds, pos-1, &conflictset->nbdchginfos);
1573  }
1574  else if( SCIPbdchginfoIsTighter(bdchginfos[pos-1], bdchginfo) )
1575  {
1576  /* remove the "new" bound change since the "old" one is tighter */
1577  SCIPsortedvecDelPosIntPtrReal(sortvals, (void**)bdchginfos, relaxedbds, pos, &conflictset->nbdchginfos);
1578  }
1579  else
1580  {
1581  /* both bound change are equivalent; hence, keep the worse relaxed bound and remove one of them */
1582  relaxedbds[pos-1] = boundtype == SCIP_BOUNDTYPE_LOWER ? MAX(relaxedbds[pos-1], relaxedbd) : MIN(relaxedbds[pos-1], relaxedbd);
1583  SCIPsortedvecDelPosIntPtrReal(sortvals, (void**)bdchginfos, relaxedbds, pos, &conflictset->nbdchginfos);
1584  }
1585  }
1586 
1587  return SCIP_OKAY;
1588 }
1589 
1590 /** adds given bound changes to a conflict set */
1591 static
1593  SCIP_CONFLICT* conflict, /**< conflict analysis data */
1594  SCIP_CONFLICTSET* conflictset, /**< conflict set */
1595  BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
1596  SCIP_SET* set, /**< global SCIP settings */
1597  SCIP_BDCHGINFO** bdchginfos, /**< bound changes to add to the conflict set */
1598  int nbdchginfos /**< number of bound changes to add */
1599  )
1600 {
1601  SCIP_BDCHGINFO** confbdchginfos;
1602  SCIP_BDCHGINFO* bdchginfo;
1603  SCIP_Real* confrelaxedbds;
1604  int* confsortvals;
1605  int confnbdchginfos;
1606  int idx;
1607  int sortval;
1608  int i;
1609  SCIP_BOUNDTYPE boundtype;
1610 
1611  assert(conflict != NULL);
1612  assert(conflictset != NULL);
1613  assert(blkmem != NULL);
1614  assert(set != NULL);
1615  assert(bdchginfos != NULL || nbdchginfos == 0);
1616 
1617  /* nothing to add */
1618  if( nbdchginfos == 0 )
1619  return SCIP_OKAY;
1620 
1621  assert(bdchginfos != NULL);
1622 
1623  /* only one element to add, use the single insertion method */
1624  if( nbdchginfos == 1 )
1625  {
1626  bdchginfo = bdchginfos[0];
1627  assert(bdchginfo != NULL);
1628 
1629  if( !bdchginfoIsInvalid(conflict, bdchginfo) )
1630  {
1631  SCIP_CALL( conflictsetAddBound(conflictset, blkmem, set, bdchginfo, SCIPbdchginfoGetRelaxedBound(bdchginfo)) );
1632  }
1633  else
1634  {
1635  SCIPsetDebugMsg(set, "-> bound change info [%d:<%s> %s %g] is invaild -> ignore it\n", SCIPbdchginfoGetDepth(bdchginfo),
1636  SCIPvarGetName(SCIPbdchginfoGetVar(bdchginfo)),
1637  SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
1638  SCIPbdchginfoGetNewbound(bdchginfo));
1639  }
1640 
1641  return SCIP_OKAY;
1642  }
1643 
1644  confnbdchginfos = conflictset->nbdchginfos;
1645 
1646  /* allocate memory for additional element */
1647  SCIP_CALL( conflictsetEnsureBdchginfosMem(conflictset, blkmem, set, confnbdchginfos + nbdchginfos) );
1648 
1649  confbdchginfos = conflictset->bdchginfos;
1650  confrelaxedbds = conflictset->relaxedbds;
1651  confsortvals = conflictset->sortvals;
1652 
1653  assert(SCIP_BOUNDTYPE_LOWER == FALSE); /*lint !e641 !e506*/
1654  assert(SCIP_BOUNDTYPE_UPPER == TRUE); /*lint !e641 !e506*/
1655 
1656  for( i = 0; i < nbdchginfos; ++i )
1657  {
1658  bdchginfo = bdchginfos[i];
1659  assert(bdchginfo != NULL);
1660 
1661  /* add only valid bound change infos */
1662  if( !bdchginfoIsInvalid(conflict, bdchginfo) )
1663  {
1664  /* calculate sorting value */
1665  boundtype = SCIPbdchginfoGetBoundtype(bdchginfo);
1666  assert(SCIPbdchginfoGetVar(bdchginfo) != NULL);
1667 
1668  idx = SCIPvarGetIndex(SCIPbdchginfoGetVar(bdchginfo));
1669  assert(idx < INT_MAX/2);
1670 
1671  assert((int)boundtype == 0 || (int)boundtype == 1);
1672  sortval = 2*idx + (int)boundtype; /* first sorting criteria: variable index, second criteria: boundtype */
1673 
1674  /* add new element */
1675  confbdchginfos[confnbdchginfos] = bdchginfo;
1676  confrelaxedbds[confnbdchginfos] = SCIPbdchginfoGetRelaxedBound(bdchginfo);
1677  confsortvals[confnbdchginfos] = sortval;
1678  ++confnbdchginfos;
1679  }
1680  else
1681  {
1682  SCIPsetDebugMsg(set, "-> bound change info [%d:<%s> %s %g] is invaild -> ignore it\n", SCIPbdchginfoGetDepth(bdchginfo),
1683  SCIPvarGetName(SCIPbdchginfoGetVar(bdchginfo)),
1684  SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
1685  SCIPbdchginfoGetNewbound(bdchginfo));
1686  }
1687  }
1688  assert(confnbdchginfos <= conflictset->nbdchginfos + nbdchginfos);
1689 
1690  /* sort and merge the new conflict set */
1691  if( confnbdchginfos > conflictset->nbdchginfos )
1692  {
1693  int k = 0;
1694 
1695  /* sort array */
1696  SCIPsortIntPtrReal(confsortvals, (void**)confbdchginfos, confrelaxedbds, confnbdchginfos);
1697 
1698  i = 1;
1699  /* merge multiple bound changes */
1700  while( i < confnbdchginfos )
1701  {
1702  assert(i > k);
1703 
1704  /* is this a multiple bound change */
1705  if( confsortvals[k] == confsortvals[i] )
1706  {
1707  if( SCIPbdchginfoIsTighter(confbdchginfos[k], confbdchginfos[i]) )
1708  ++i;
1709  else if( SCIPbdchginfoIsTighter(confbdchginfos[i], confbdchginfos[k]) )
1710  {
1711  /* replace worse bound change info by tighter bound change info */
1712  confbdchginfos[k] = confbdchginfos[i];
1713  confrelaxedbds[k] = confrelaxedbds[i];
1714  confsortvals[k] = confsortvals[i];
1715  ++i;
1716  }
1717  else
1718  {
1719  assert(confsortvals[k] == confsortvals[i]);
1720 
1721  /* both bound change are equivalent; hence, keep the worse relaxed bound and remove one of them */
1722  confrelaxedbds[k] = (confsortvals[k] % 2 == 0) ? MAX(confrelaxedbds[k], confrelaxedbds[i]) : MIN(confrelaxedbds[k], confrelaxedbds[i]);
1723  ++i;
1724  }
1725  }
1726  else
1727  {
1728  /* all bound change infos must be valid */
1729  assert(!bdchginfoIsInvalid(conflict, confbdchginfos[k]));
1730 
1731  ++k;
1732  /* move next comparison element to the correct position */
1733  if( k != i )
1734  {
1735  confbdchginfos[k] = confbdchginfos[i];
1736  confrelaxedbds[k] = confrelaxedbds[i];
1737  confsortvals[k] = confsortvals[i];
1738  }
1739  ++i;
1740  }
1741  }
1742  /* last bound change infos must also be valid */
1743  assert(!bdchginfoIsInvalid(conflict, confbdchginfos[k]));
1744  /* the number of bound change infos cannot be decreased, it would mean that the conflict set was not merged
1745  * before
1746  */
1747  assert(conflictset->nbdchginfos <= k + 1 );
1748  assert(k + 1 <= confnbdchginfos);
1749 
1750  conflictset->nbdchginfos = k + 1;
1751  }
1752 
1753  return SCIP_OKAY;
1754 }
1755 
1756 /** calculates the conflict and the repropagation depths of the conflict set */
1757 static
1759  SCIP_CONFLICTSET* conflictset /**< conflict set */
1760  )
1761 {
1762  int maxdepth[2];
1763  int i;
1764 
1765  assert(conflictset != NULL);
1766  assert(conflictset->validdepth <= conflictset->insertdepth);
1767 
1768  /* get the depth of the last and last but one bound change */
1769  maxdepth[0] = conflictset->validdepth;
1770  maxdepth[1] = conflictset->validdepth;
1771  for( i = 0; i < conflictset->nbdchginfos; ++i )
1772  {
1773  int depth;
1774 
1775  depth = SCIPbdchginfoGetDepth(conflictset->bdchginfos[i]);
1776  assert(depth >= 0);
1777  if( depth > maxdepth[0] )
1778  {
1779  maxdepth[1] = maxdepth[0];
1780  maxdepth[0] = depth;
1781  }
1782  else if( depth > maxdepth[1] )
1783  maxdepth[1] = depth;
1784  }
1785  assert(maxdepth[0] >= maxdepth[1]);
1786 
1787  conflictset->conflictdepth = maxdepth[0];
1788  conflictset->repropdepth = maxdepth[1];
1789 }
1790 
1791 /** identifies the depth, at which the conflict set should be added:
1792  * - if the branching rule operates on variables only, and if all branching variables up to a certain
1793  * depth level are member of the conflict, the conflict constraint can only be violated in the subtree
1794  * of the node at that depth, because in all other nodes, at least one of these branching variables
1795  * violates its conflicting bound, such that the conflict constraint is feasible
1796  * - if there is at least one branching variable in a node, we assume, that this branching was performed
1797  * on variables, and that the siblings of this node are disjunct w.r.t. the branching variables' fixings
1798  * - we have to add the conflict set at least in the valid depth of the initial conflict set,
1799  * so we start searching at the first branching after this depth level, i.e. validdepth+1
1800  */
1801 static
1803  SCIP_CONFLICTSET* conflictset, /**< conflict set */
1804  SCIP_SET* set, /**< global SCIP settings */
1805  SCIP_TREE* tree /**< branch and bound tree */
1806  )
1807 {
1808  SCIP_Bool* branchingincluded;
1809  int currentdepth;
1810  int i;
1811 
1812  assert(conflictset != NULL);
1813  assert(set != NULL);
1814  assert(tree != NULL);
1815 
1816  /* the conflict set must not be inserted prior to its valid depth */
1817  conflictset->insertdepth = conflictset->validdepth;
1818  assert(conflictset->insertdepth >= 0);
1819 
1820  currentdepth = SCIPtreeGetCurrentDepth(tree);
1821  assert(currentdepth == tree->pathlen-1);
1822 
1823  /* mark the levels for which a branching variable is included in the conflict set */
1824  SCIP_CALL( SCIPsetAllocBufferArray(set, &branchingincluded, currentdepth+2) );
1825  BMSclearMemoryArray(branchingincluded, currentdepth+2);
1826  for( i = 0; i < conflictset->nbdchginfos; ++i )
1827  {
1828  int depth;
1829 
1830  depth = SCIPbdchginfoGetDepth(conflictset->bdchginfos[i]);
1831  depth = MIN(depth, currentdepth+1); /* put diving/probing/strong branching changes in this depth level */
1832  branchingincluded[depth] = TRUE;
1833  }
1834 
1835  /* skip additional depth levels where branching on the conflict variables was applied */
1836  while( conflictset->insertdepth < currentdepth && branchingincluded[conflictset->insertdepth+1] )
1837  conflictset->insertdepth++;
1838 
1839  /* free temporary memory */
1840  SCIPsetFreeBufferArray(set, &branchingincluded);
1841 
1842  assert(conflictset->validdepth <= conflictset->insertdepth && conflictset->insertdepth <= currentdepth);
1843 
1844  return SCIP_OKAY;
1845 }
1846 
1847 /** checks whether the first conflict set is redundant to the second one */
1848 static
1850  SCIP_CONFLICTSET* conflictset1, /**< first conflict conflict set */
1851  SCIP_CONFLICTSET* conflictset2 /**< second conflict conflict set */
1852  )
1853 {
1854  int i1;
1855  int i2;
1856 
1857  assert(conflictset1 != NULL);
1858  assert(conflictset2 != NULL);
1859 
1860  /* if conflictset1 has smaller validdepth, it is definitely not redundant to conflictset2 */
1861  if( conflictset1->validdepth < conflictset2->validdepth )
1862  return FALSE;
1863 
1864  /* check, if all bound changes in conflictset2 are also present at least as tight in conflictset1;
1865  * we can stop immediately, if more bound changes are remaining in conflictset2 than in conflictset1
1866  */
1867  for( i1 = 0, i2 = 0; i2 < conflictset2->nbdchginfos && conflictset1->nbdchginfos - i1 >= conflictset2->nbdchginfos - i2;
1868  ++i1, ++i2 )
1869  {
1870  int sortval;
1871 
1872  assert(i2 == 0 || conflictset2->sortvals[i2-1] < conflictset2->sortvals[i2]);
1873 
1874  sortval = conflictset2->sortvals[i2];
1875  for( ; i1 < conflictset1->nbdchginfos && conflictset1->sortvals[i1] < sortval; ++i1 ) /*lint !e445*/
1876  {
1877  /* while scanning conflictset1, check consistency */
1878  assert(i1 == 0 || conflictset1->sortvals[i1-1] < conflictset1->sortvals[i1]);
1879  }
1880  if( i1 >= conflictset1->nbdchginfos || conflictset1->sortvals[i1] > sortval
1881  || SCIPbdchginfoIsTighter(conflictset2->bdchginfos[i2], conflictset1->bdchginfos[i1]) )
1882  return FALSE;
1883  }
1884 
1885  return (i2 == conflictset2->nbdchginfos);
1886 }
1887 
1888 #ifdef SCIP_DEBUG
1889 /** prints a conflict set to the screen */
1890 static
1891 void conflictsetPrint(
1892  SCIP_CONFLICTSET* conflictset /**< conflict set */
1893  )
1894 {
1895  int i;
1896 
1897  assert(conflictset != NULL);
1898  for( i = 0; i < conflictset->nbdchginfos; ++i )
1899  {
1900  SCIPdebugPrintf(" [%d:<%s> %s %g(%g)]", SCIPbdchginfoGetDepth(conflictset->bdchginfos[i]),
1901  SCIPvarGetName(SCIPbdchginfoGetVar(conflictset->bdchginfos[i])),
1902  SCIPbdchginfoGetBoundtype(conflictset->bdchginfos[i]) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
1903  SCIPbdchginfoGetNewbound(conflictset->bdchginfos[i]), conflictset->relaxedbds[i]);
1904  }
1905  SCIPdebugPrintf("\n");
1906 }
1907 #endif
1908 
1909 /** resizes proofsets array to be able to store at least num entries */
1910 static
1912  SCIP_CONFLICT* conflict, /**< conflict analysis data */
1913  SCIP_SET* set, /**< global SCIP settings */
1914  int num /**< minimal number of slots in array */
1915  )
1916 {
1917  assert(conflict != NULL);
1918  assert(set != NULL);
1919 
1920  if( num > conflict->proofsetssize )
1921  {
1922  int newsize;
1923 
1924  newsize = SCIPsetCalcMemGrowSize(set, num);
1925  SCIP_ALLOC( BMSreallocMemoryArray(&conflict->proofsets, newsize) );
1926  conflict->proofsetssize = newsize;
1927  }
1928  assert(num <= conflict->proofsetssize);
1929 
1930  return SCIP_OKAY;
1931 }
1932 
1933 /** resizes conflictsets array to be able to store at least num entries */
1934 static
1936  SCIP_CONFLICT* conflict, /**< conflict analysis data */
1937  SCIP_SET* set, /**< global SCIP settings */
1938  int num /**< minimal number of slots in array */
1939  )
1940 {
1941  assert(conflict != NULL);
1942  assert(set != NULL);
1943 
1944  if( num > conflict->conflictsetssize )
1945  {
1946  int newsize;
1947 
1948  newsize = SCIPsetCalcMemGrowSize(set, num);
1949  SCIP_ALLOC( BMSreallocMemoryArray(&conflict->conflictsets, newsize) );
1950  SCIP_ALLOC( BMSreallocMemoryArray(&conflict->conflictsetscores, newsize) );
1951  conflict->conflictsetssize = newsize;
1952  }
1953  assert(num <= conflict->conflictsetssize);
1954 
1955  return SCIP_OKAY;
1956 }
1957 
1958 /** add a proofset to the list of all proofsets */
1959 static
1961  SCIP_CONFLICT* conflict, /**< conflict analysis data */
1962  SCIP_SET* set, /**< global SCIP settings */
1963  SCIP_PROOFSET* proofset /**< proof set to add */
1964  )
1965 {
1966  assert(conflict != NULL);
1967  assert(proofset != NULL);
1968 
1969  /* insert proofset into the sorted proofsets array */
1970  SCIP_CALL( conflictEnsureProofsetsMem(conflict, set, conflict->nproofsets + 1) );
1971 
1972  conflict->proofsets[conflict->nproofsets] = proofset;
1973  ++conflict->nproofsets;
1974 
1975  return SCIP_OKAY;
1976 }
1977 
1978 /** inserts conflict set into sorted conflictsets array and deletes the conflict set pointer */
1979 static
1981  SCIP_CONFLICT* conflict, /**< conflict analysis data */
1982  BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
1983  SCIP_SET* set, /**< global SCIP settings */
1984  SCIP_CONFLICTSET** conflictset /**< pointer to conflict set to insert */
1985  )
1986 {
1987  SCIP_Real score;
1988  int pos;
1989  int i;
1990  int j;
1991 
1992  assert(conflict != NULL);
1993  assert(set != NULL);
1994  assert(conflictset != NULL);
1995  assert(*conflictset != NULL);
1996  assert((*conflictset)->validdepth <= (*conflictset)->insertdepth);
1997  assert(set->conf_allowlocal || (*conflictset)->validdepth == 0);
1998 
1999  /* calculate conflict and repropagation depth */
2000  conflictsetCalcConflictDepth(*conflictset);
2001 
2002  /* if we apply repropagations, the conflict set should be inserted at most at its repropdepth */
2003  if( set->conf_repropagate )
2004  (*conflictset)->insertdepth = MIN((*conflictset)->insertdepth, (*conflictset)->repropdepth);
2005  else
2006  (*conflictset)->repropdepth = INT_MAX;
2007  assert((*conflictset)->insertdepth <= (*conflictset)->repropdepth);
2008 
2009  SCIPsetDebugMsg(set, "inserting conflict set (valid: %d, insert: %d, conf: %d, reprop: %d):\n",
2010  (*conflictset)->validdepth, (*conflictset)->insertdepth, (*conflictset)->conflictdepth, (*conflictset)->repropdepth);
2011  SCIPdebug(conflictsetPrint(*conflictset));
2012 
2013  /* get the score of the conflict set */
2014  score = conflictsetCalcScore(*conflictset, set);
2015 
2016  /* check, if conflict set is redundant to a better conflict set */
2017  for( pos = 0; pos < conflict->nconflictsets && score < conflict->conflictsetscores[pos]; ++pos )
2018  {
2019  /* check if conflict set is redundant with respect to conflictsets[pos] */
2020  if( conflictsetIsRedundant(*conflictset, conflict->conflictsets[pos]) )
2021  {
2022  SCIPsetDebugMsg(set, " -> conflict set is redundant to: ");
2023  SCIPdebug(conflictsetPrint(conflict->conflictsets[pos]));
2024  conflictsetFree(conflictset, blkmem);
2025  return SCIP_OKAY;
2026  }
2027 
2028  /**@todo like in sepastore.c: calculate overlap between conflictsets -> large overlap reduces score */
2029  }
2030 
2031  /* insert conflictset into the sorted conflictsets array */
2032  SCIP_CALL( conflictEnsureConflictsetsMem(conflict, set, conflict->nconflictsets + 1) );
2033  for( i = conflict->nconflictsets; i > pos; --i )
2034  {
2035  assert(score >= conflict->conflictsetscores[i-1]);
2036  conflict->conflictsets[i] = conflict->conflictsets[i-1];
2037  conflict->conflictsetscores[i] = conflict->conflictsetscores[i-1];
2038  }
2039  conflict->conflictsets[pos] = *conflictset;
2040  conflict->conflictsetscores[pos] = score;
2041  conflict->nconflictsets++;
2042 
2043  /* remove worse conflictsets that are redundant to the new conflictset */
2044  for( i = pos+1, j = pos+1; i < conflict->nconflictsets; ++i )
2045  {
2046  if( conflictsetIsRedundant(conflict->conflictsets[i], *conflictset) )
2047  {
2048  SCIPsetDebugMsg(set, " -> conflict set dominates: ");
2049  SCIPdebug(conflictsetPrint(conflict->conflictsets[i]));
2050  conflictsetFree(&conflict->conflictsets[i], blkmem);
2051  }
2052  else
2053  {
2054  assert(j <= i);
2055  conflict->conflictsets[j] = conflict->conflictsets[i];
2056  conflict->conflictsetscores[j] = conflict->conflictsetscores[i];
2057  j++;
2058  }
2059  }
2060  assert(j <= conflict->nconflictsets);
2061  conflict->nconflictsets = j;
2062 
2063 #ifdef SCIP_CONFGRAPH
2064  confgraphMarkConflictset(*conflictset);
2065 #endif
2066 
2067  *conflictset = NULL; /* ownership of pointer is now in the conflictsets array */
2068 
2069  return SCIP_OKAY;
2070 }
2071 
2072 /** calculates the maximal size of conflict sets to be used */
2073 static
2075  SCIP_SET* set, /**< global SCIP settings */
2076  SCIP_PROB* prob /**< problem data */
2077  )
2078 {
2079  int maxsize;
2080 
2081  assert(set != NULL);
2082  assert(prob != NULL);
2083 
2084  maxsize = (int)(set->conf_maxvarsfac * (prob->nvars - prob->ncontvars));
2085  maxsize = MAX(maxsize, set->conf_minmaxvars);
2086 
2087  return maxsize;
2088 }
2089 
2090 /** increases the conflict score of the variable in the given direction */
2091 static
2093  SCIP_VAR* var, /**< problem variable */
2094  BMS_BLKMEM* blkmem, /**< block memory */
2095  SCIP_SET* set, /**< global SCIP settings */
2096  SCIP_STAT* stat, /**< dynamic problem statistics */
2097  SCIP_BOUNDTYPE boundtype, /**< type of bound for which the score should be increased */
2098  SCIP_Real value, /**< value of the bound */
2099  SCIP_Real weight /**< weight of this VSIDS updates */
2100  )
2101 {
2102  SCIP_BRANCHDIR branchdir;
2103 
2104  assert(var != NULL);
2105  assert(stat != NULL);
2106 
2107  /* weight the VSIDS by the given weight */
2108  weight *= stat->vsidsweight;
2109 
2110  if( SCIPsetIsZero(set, weight) )
2111  return SCIP_OKAY;
2112 
2113  branchdir = (boundtype == SCIP_BOUNDTYPE_LOWER ? SCIP_BRANCHDIR_UPWARDS : SCIP_BRANCHDIR_DOWNWARDS); /*lint !e641*/
2114  SCIP_CALL( SCIPvarIncVSIDS(var, blkmem, set, stat, branchdir, value, weight) );
2115  SCIPhistoryIncVSIDS(stat->glbhistory, branchdir, weight);
2116  SCIPhistoryIncVSIDS(stat->glbhistorycrun, branchdir, weight);
2117 
2118  return SCIP_OKAY;
2119 }
2120 
2121 /** update conflict statistics */
2122 static
2124  SCIP_CONFLICT* conflict, /**< conflict analysis data */
2125  BMS_BLKMEM* blkmem, /**< block memory */
2126  SCIP_SET* set, /**< global SCIP settings */
2127  SCIP_STAT* stat, /**< dynamic problem statistics */
2128  SCIP_CONFLICTSET* conflictset, /**< conflict set to add to the tree */
2129  int insertdepth /**< depth level at which the conflict set should be added */
2130  )
2131 {
2132  if( insertdepth > 0 )
2133  {
2134  conflict->nappliedlocconss++;
2135  conflict->nappliedlocliterals += conflictset->nbdchginfos;
2136  }
2137  else
2138  {
2139  int i;
2140  int conflictlength;
2141  conflictlength = conflictset->nbdchginfos;
2142 
2143  for( i = 0; i < conflictlength; i++ )
2144  {
2145  SCIP_VAR* var;
2146  SCIP_BRANCHDIR branchdir;
2147  SCIP_BOUNDTYPE boundtype;
2148  SCIP_Real bound;
2149 
2150  assert(stat != NULL);
2151 
2152  var = conflictset->bdchginfos[i]->var;
2153  boundtype = SCIPbdchginfoGetBoundtype(conflictset->bdchginfos[i]);
2154  bound = conflictset->relaxedbds[i];
2155 
2156  branchdir = (boundtype == SCIP_BOUNDTYPE_LOWER ? SCIP_BRANCHDIR_UPWARDS : SCIP_BRANCHDIR_DOWNWARDS); /*lint !e641*/
2157 
2158  SCIP_CALL( SCIPvarIncNActiveConflicts(var, blkmem, set, stat, branchdir, bound, (SCIP_Real)conflictlength) );
2159  SCIPhistoryIncNActiveConflicts(stat->glbhistory, branchdir, (SCIP_Real)conflictlength);
2160  SCIPhistoryIncNActiveConflicts(stat->glbhistorycrun, branchdir, (SCIP_Real)conflictlength);
2161 
2162  /* each variable which is part of the conflict gets an increase in the VSIDS */
2163  SCIP_CALL( incVSIDS(var, blkmem, set, stat, boundtype, bound, set->conf_conflictweight) );
2164  }
2165  conflict->nappliedglbconss++;
2166  conflict->nappliedglbliterals += conflictset->nbdchginfos;
2167  }
2168 
2169  return SCIP_OKAY;
2170 }
2171 
2172 
2173 /** check conflict set for redundancy, other conflicts in the same conflict analysis could have led to global reductions
2174  * an made this conflict set redundant
2175  */
2176 static
2178  SCIP_SET* set, /**< global SCIP settings */
2179  SCIP_CONFLICTSET* conflictset /**< conflict set */
2180  )
2181 {
2182  SCIP_BDCHGINFO** bdchginfos;
2183  SCIP_VAR* var;
2184  SCIP_Real* relaxedbds;
2185  SCIP_Real bound;
2186  int v;
2187 
2188  assert(set != NULL);
2189  assert(conflictset != NULL);
2190 
2191  bdchginfos = conflictset->bdchginfos;
2192  relaxedbds = conflictset->relaxedbds;
2193  assert(bdchginfos != NULL);
2194  assert(relaxedbds != NULL);
2195 
2196  /* check all boundtypes and bounds for redundancy */
2197  for( v = conflictset->nbdchginfos - 1; v >= 0; --v )
2198  {
2199  var = SCIPbdchginfoGetVar(bdchginfos[v]);
2200  assert(var != NULL);
2201  assert(SCIPvarGetProbindex(var) >= 0);
2202 
2203  /* check if the relaxed bound is really a relaxed bound */
2204  assert(SCIPbdchginfoGetBoundtype(bdchginfos[v]) == SCIP_BOUNDTYPE_LOWER || SCIPsetIsGE(set, relaxedbds[v], SCIPbdchginfoGetNewbound(bdchginfos[v])));
2205  assert(SCIPbdchginfoGetBoundtype(bdchginfos[v]) == SCIP_BOUNDTYPE_UPPER || SCIPsetIsLE(set, relaxedbds[v], SCIPbdchginfoGetNewbound(bdchginfos[v])));
2206 
2207  bound = relaxedbds[v];
2208 
2209  if( SCIPbdchginfoGetBoundtype(bdchginfos[v]) == SCIP_BOUNDTYPE_UPPER )
2210  {
2212  {
2213  assert(SCIPsetIsIntegral(set, bound));
2214  bound += 1.0;
2215  }
2216 
2217  /* check if the bound is already fulfilled globally */
2218  if( SCIPsetIsFeasGE(set, SCIPvarGetLbGlobal(var), bound) )
2219  return TRUE;
2220  }
2221  else
2222  {
2223  assert(SCIPbdchginfoGetBoundtype(bdchginfos[v]) == SCIP_BOUNDTYPE_LOWER);
2224 
2226  {
2227  assert(SCIPsetIsIntegral(set, bound));
2228  bound -= 1.0;
2229  }
2230 
2231  /* check if the bound is already fulfilled globally */
2232  if( SCIPsetIsFeasLE(set, SCIPvarGetUbGlobal(var), bound) )
2233  return TRUE;
2234  }
2235  }
2236 
2237  return FALSE;
2238 }
2239 
2240 /** find global fixings which can be derived from the new conflict set */
2241 static
2243  SCIP_SET* set, /**< global SCIP settings */
2244  SCIP_PROB* prob, /**< transformed problem after presolve */
2245  SCIP_CONFLICTSET* conflictset, /**< conflict set to add to the tree */
2246  int* nbdchgs, /**< number of global deducted bound changes due to the conflict set */
2247  int* nredvars, /**< number of redundant and removed variables from conflict set */
2248  SCIP_Bool* redundant /**< did we found a global reduction on a conflict set variable, which makes this conflict redundant */
2249  )
2250 {
2251  SCIP_BDCHGINFO** bdchginfos;
2252  SCIP_Real* relaxedbds;
2253  SCIP_VAR* var;
2254  SCIP_Bool* boundtypes;
2255  SCIP_Real* bounds;
2256  SCIP_Longint* nbinimpls;
2257  int* sortvals;
2258  SCIP_Real bound;
2259  SCIP_Bool isupper;
2260  int ntrivialredvars;
2261  int nbdchginfos;
2262  int nzeroimpls;
2263  int v;
2264 
2265  assert(set != NULL);
2266  assert(prob != NULL);
2267  assert(SCIPprobIsTransformed(prob));
2268  assert(conflictset != NULL);
2269  assert(nbdchgs != NULL);
2270  assert(nredvars != NULL);
2271  /* only check conflict sets with more than one variable */
2272  assert(conflictset->nbdchginfos > 1);
2273 
2274  *nbdchgs = 0;
2275  *nredvars = 0;
2276 
2277  /* due to other conflict in the same conflict analysis, this conflict set might have become redundant */
2278  *redundant = checkRedundancy(set, conflictset);
2279 
2280  if( *redundant )
2281  return SCIP_OKAY;
2282 
2283  bdchginfos = conflictset->bdchginfos;
2284  relaxedbds = conflictset->relaxedbds;
2285  nbdchginfos = conflictset->nbdchginfos;
2286  sortvals = conflictset->sortvals;
2287 
2288  assert(bdchginfos != NULL);
2289  assert(relaxedbds != NULL);
2290  assert(sortvals != NULL);
2291 
2292  /* check if the boolean representation of boundtypes matches the 'standard' definition */
2293  assert(SCIP_BOUNDTYPE_LOWER == FALSE); /*lint !e641 !e506*/
2294  assert(SCIP_BOUNDTYPE_UPPER == TRUE); /*lint !e641 !e506*/
2295 
2296  ntrivialredvars = 0;
2297 
2298  /* due to multiple conflict sets for one conflict, it can happen, that we already have redundant information in the
2299  * conflict set
2300  */
2301  for( v = nbdchginfos - 1; v >= 0; --v )
2302  {
2303  var = SCIPbdchginfoGetVar(bdchginfos[v]);
2304  bound = relaxedbds[v];
2305  isupper = (SCIP_Bool) SCIPboundtypeOpposite(SCIPbdchginfoGetBoundtype(bdchginfos[v]));
2306 
2307  /* for integral variable we can increase/decrease the conflicting bound */
2308  if( SCIPvarIsIntegral(var) )
2309  bound += (isupper ? -1.0 : +1.0);
2310 
2311  /* if conflict variable cannot fulfill the conflict we can remove it */
2312  if( (isupper && SCIPsetIsFeasLT(set, bound, SCIPvarGetLbGlobal(var))) ||
2313  (!isupper && SCIPsetIsFeasGT(set, bound, SCIPvarGetUbGlobal(var))) )
2314  {
2315  SCIPsetDebugMsg(set, "remove redundant variable <%s> from conflict set\n", SCIPvarGetName(var));
2316 
2317  bdchginfos[v] = bdchginfos[nbdchginfos - 1];
2318  relaxedbds[v] = relaxedbds[nbdchginfos - 1];
2319  sortvals[v] = sortvals[nbdchginfos - 1];
2320 
2321  --nbdchginfos;
2322  ++ntrivialredvars;
2323  }
2324  }
2325  assert(ntrivialredvars + nbdchginfos == conflictset->nbdchginfos);
2326 
2327  SCIPsetDebugMsg(set, "trivially removed %d redundant of %d variables from conflictset (%p)\n", ntrivialredvars, conflictset->nbdchginfos, (void*)conflictset);
2328  conflictset->nbdchginfos = nbdchginfos;
2329 
2330  /* all variables where removed, the conflict cannot be fulfilled, i.e., we have an infeasibility proof */
2331  if( conflictset->nbdchginfos == 0 )
2332  return SCIP_OKAY;
2333 
2334  /* do not check to big or trivial conflicts */
2335  if( conflictset->nbdchginfos > set->conf_maxvarsdetectimpliedbounds || conflictset->nbdchginfos == 1 )
2336  {
2337  *nredvars = ntrivialredvars;
2338  return SCIP_OKAY;
2339  }
2340 
2341  /* create array of boundtypes, and bound values in conflict set */
2342  SCIP_CALL( SCIPsetAllocBufferArray(set, &boundtypes, nbdchginfos) );
2343  SCIP_CALL( SCIPsetAllocBufferArray(set, &bounds, nbdchginfos) );
2344  /* memory for the estimates for binary implications used for sorting */
2345  SCIP_CALL( SCIPsetAllocBufferArray(set, &nbinimpls, nbdchginfos) );
2346 
2347  nzeroimpls = 0;
2348 
2349  /* collect estimates and initialize variables, boundtypes, and bounds array */
2350  for( v = 0; v < nbdchginfos; ++v )
2351  {
2352  var = SCIPbdchginfoGetVar(bdchginfos[v]);
2353  boundtypes[v] = (SCIP_Bool) SCIPboundtypeOpposite(SCIPbdchginfoGetBoundtype(bdchginfos[v]));
2354  bounds[v] = relaxedbds[v];
2355 
2356  assert(SCIPvarGetProbindex(var) >= 0);
2357 
2358  /* check if the relaxed bound is really a relaxed bound */
2359  assert(SCIPbdchginfoGetBoundtype(bdchginfos[v]) == SCIP_BOUNDTYPE_LOWER || SCIPsetIsGE(set, relaxedbds[v], SCIPbdchginfoGetNewbound(bdchginfos[v])));
2360  assert(SCIPbdchginfoGetBoundtype(bdchginfos[v]) == SCIP_BOUNDTYPE_UPPER || SCIPsetIsLE(set, relaxedbds[v], SCIPbdchginfoGetNewbound(bdchginfos[v])));
2361 
2362  /* for continuous variables, we can only use the relaxed version of the bounds negation: !(x <= u) -> x >= u */
2363  if( SCIPvarIsBinary(var) )
2364  {
2365  if( !boundtypes[v] )
2366  {
2367  assert(SCIPsetIsZero(set, bounds[v]));
2368  bounds[v] = 1.0;
2369  nbinimpls[v] = (SCIP_Longint)SCIPvarGetNCliques(var, TRUE) * 2;
2370  }
2371  else
2372  {
2373  assert(SCIPsetIsEQ(set, bounds[v], 1.0));
2374  bounds[v] = 0.0;
2375  nbinimpls[v] = (SCIP_Longint)SCIPvarGetNCliques(var, FALSE) * 2;
2376  }
2377  }
2378  else if( SCIPvarIsIntegral(var) )
2379  {
2380  assert(SCIPsetIsIntegral(set, bounds[v]));
2381 
2382  bounds[v] += ((!boundtypes[v]) ? +1.0 : -1.0);
2383  nbinimpls[v] = (boundtypes[v] ? SCIPvarGetNVlbs(var) : SCIPvarGetNVubs(var));
2384  }
2385  else if( ((!boundtypes[v]) && SCIPsetIsFeasEQ(set, SCIPvarGetLbGlobal(var), bounds[v]))
2386  || ((boundtypes[v]) && SCIPsetIsFeasEQ(set, SCIPvarGetUbGlobal(var), bounds[v])) )
2387  {
2388  /* the literal is satisfied in global bounds (may happen due to weak "negation" of continuous variables)
2389  * -> discard the conflict constraint
2390  */
2391  break;
2392  }
2393  else
2394  {
2395  nbinimpls[v] = (boundtypes[v] ? SCIPvarGetNVlbs(var) : SCIPvarGetNVubs(var));
2396  }
2397 
2398  if( nbinimpls[v] == 0 )
2399  ++nzeroimpls;
2400  }
2401 
2402  /* starting to derive global bound changes */
2403  if( v == nbdchginfos && ((!set->conf_fullshortenconflict && nzeroimpls < 2) || (set->conf_fullshortenconflict && nzeroimpls < nbdchginfos)) )
2404  {
2405  SCIP_VAR** vars;
2406  SCIP_Bool* redundants;
2407  SCIP_Bool glbinfeas;
2408 
2409  /* sort variables in increasing order of binary implications to gain speed later on */
2410  SCIPsortLongPtrRealRealBool(nbinimpls, (void**)bdchginfos, relaxedbds, bounds, boundtypes, v);
2411 
2412  SCIPsetDebugMsg(set, "checking for global reductions and redundant conflict variables(in %s) on conflict:\n", SCIPprobGetName(prob));
2413  SCIPsetDebugMsg(set, "[");
2414  for( v = 0; v < nbdchginfos; ++v )
2415  {
2416  SCIPsetDebugMsgPrint(set, "%s %s %g", SCIPvarGetName(SCIPbdchginfoGetVar(bdchginfos[v])), (!boundtypes[v]) ? ">=" : "<=", bounds[v]);
2417  if( v < nbdchginfos - 1 )
2418  SCIPsetDebugMsgPrint(set, ", ");
2419  }
2420  SCIPsetDebugMsgPrint(set, "]\n");
2421 
2422  SCIP_CALL( SCIPsetAllocBufferArray(set, &vars, v) );
2423  SCIP_CALL( SCIPsetAllocCleanBufferArray(set, &redundants, v) );
2424 
2425  /* initialize conflict variable data */
2426  for( v = 0; v < nbdchginfos; ++v )
2427  vars[v] = SCIPbdchginfoGetVar(bdchginfos[v]);
2428 
2429  SCIP_CALL( SCIPshrinkDisjunctiveVarSet(set->scip, vars, bounds, boundtypes, redundants, nbdchginfos, nredvars, \
2430  nbdchgs, redundant, &glbinfeas, set->conf_fullshortenconflict) );
2431 
2432  if( glbinfeas )
2433  {
2434  SCIPsetDebugMsg(set, "conflict set (%p) led to global infeasibility\n", (void*) conflictset);
2435 
2436  /* clear the memory array before freeing it */
2437  BMSclearMemoryArray(redundants, nbdchginfos);
2438  goto TERMINATE;
2439  }
2440 
2441 #ifdef SCIP_DEBUG
2442  if( *nbdchgs > 0 )
2443  {
2444  SCIPsetDebugMsg(set, "conflict set (%p) led to %d global bound reductions\n", (void*) conflictset, *nbdchgs);
2445  }
2446 #endif
2447 
2448  /* remove as redundant marked variables */
2449  if( *redundant )
2450  {
2451  SCIPsetDebugMsg(set, "conflict set (%p) is redundant because at least one global reduction, fulfills the conflict constraint\n", (void*)conflictset);
2452 
2453  /* clear the memory array before freeing it */
2454  BMSclearMemoryArray(redundants, nbdchginfos);
2455  }
2456  else if( *nredvars > 0 )
2457  {
2458  assert(bdchginfos == conflictset->bdchginfos);
2459  assert(relaxedbds == conflictset->relaxedbds);
2460  assert(sortvals == conflictset->sortvals);
2461 
2462  for( v = nbdchginfos - 1; v >= 0; --v )
2463  {
2464  /* if conflict variable was marked to be redundant remove it */
2465  if( redundants[v] )
2466  {
2467  SCIPsetDebugMsg(set, "remove redundant variable <%s> from conflict set\n", SCIPvarGetName(SCIPbdchginfoGetVar(bdchginfos[v])));
2468 
2469  bdchginfos[v] = bdchginfos[nbdchginfos - 1];
2470  relaxedbds[v] = relaxedbds[nbdchginfos - 1];
2471  sortvals[v] = sortvals[nbdchginfos - 1];
2472 
2473  /* reset redundants[v] to 0 */
2474  redundants[v] = 0;
2475 
2476  --nbdchginfos;
2477  }
2478  }
2479  assert((*nredvars) + nbdchginfos == conflictset->nbdchginfos);
2480 
2481  SCIPsetDebugMsg(set, "removed %d redundant of %d variables from conflictset (%p)\n", (*nredvars), conflictset->nbdchginfos, (void*)conflictset);
2482  conflictset->nbdchginfos = nbdchginfos;
2483  }
2484  else
2485  {
2486  /* clear the memory array before freeing it */
2487  BMSclearMemoryArray(redundants, nbdchginfos);
2488  }
2489 
2490  TERMINATE:
2491  SCIPsetFreeCleanBufferArray(set, &redundants);
2492  SCIPsetFreeBufferArray(set, &vars);
2493  }
2494 
2495  /* free temporary memory */
2496  SCIPsetFreeBufferArray(set, &nbinimpls);
2497  SCIPsetFreeBufferArray(set, &bounds);
2498  SCIPsetFreeBufferArray(set, &boundtypes);
2499 
2500  *nredvars += ntrivialredvars;
2501 
2502  return SCIP_OKAY;
2503 }
2504 
2505 /** tighten the bound of a singleton variable in a constraint
2506  *
2507  * if the bound is contradicting with a global bound we cannot tighten the bound directly.
2508  * in this case we need to create and add a constraint of size one such that propagating this constraint will
2509  * enforce the infeasibility.
2510  */
2511 static
2513  SCIP_CONFLICT* conflict, /**< conflict analysis data */
2514  SCIP_SET* set, /**< global SCIP settings */
2515  SCIP_STAT* stat, /**< dynamic SCIP statistics */
2516  SCIP_TREE* tree, /**< tree data */
2517  BMS_BLKMEM* blkmem, /**< block memory */
2518  SCIP_PROB* origprob, /**< original problem */
2519  SCIP_PROB* transprob, /**< transformed problem */
2520  SCIP_REOPT* reopt, /**< reoptimization data */
2521  SCIP_LP* lp, /**< LP data */
2522  SCIP_BRANCHCAND* branchcand, /**< branching candidates */
2523  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2524  SCIP_CLIQUETABLE* cliquetable, /**< clique table */
2525  SCIP_VAR* var, /**< problem variable */
2526  SCIP_Real val, /**< coefficient of the variable */
2527  SCIP_Real rhs, /**< rhs of the constraint */
2528  SCIP_CONFTYPE prooftype, /**< type of the proof */
2529  int validdepth /**< depth where the bound change is valid */
2530  )
2531 {
2532  SCIP_Real newbound;
2533  SCIP_Bool applyglobal;
2534  SCIP_BOUNDTYPE boundtype;
2535 
2536  assert(tree != NULL);
2537  assert(validdepth >= 0);
2538 
2539  applyglobal = (validdepth <= SCIPtreeGetEffectiveRootDepth(tree));
2540 
2541  /* if variable and coefficient are integral the rhs can be rounded down */
2542  if( SCIPvarIsIntegral(var) && SCIPsetIsIntegral(set, val) )
2543  newbound = SCIPsetFeasFloor(set, rhs)/val;
2544  else
2545  newbound = rhs/val;
2546 
2547  boundtype = (val > 0.0 ? SCIP_BOUNDTYPE_UPPER : SCIP_BOUNDTYPE_LOWER);
2548  SCIPvarAdjustBd(var, set, boundtype, &newbound);
2549 
2550  /* skip numerical unstable bound changes */
2551  if( applyglobal
2552  && ((boundtype == SCIP_BOUNDTYPE_LOWER && SCIPsetIsLE(set, newbound, SCIPvarGetLbGlobal(var)))
2553  || (boundtype == SCIP_BOUNDTYPE_UPPER && SCIPsetIsGE(set, newbound, SCIPvarGetUbGlobal(var)))) )
2554  {
2555  return SCIP_OKAY;
2556  }
2557 
2558  /* the new bound contradicts a global bound, we can cutoff the root node immediately */
2559  if( applyglobal
2560  && ((boundtype == SCIP_BOUNDTYPE_LOWER && SCIPsetIsGT(set, newbound, SCIPvarGetUbGlobal(var)))
2561  || (boundtype == SCIP_BOUNDTYPE_UPPER && SCIPsetIsLT(set, newbound, SCIPvarGetLbGlobal(var)))) )
2562  {
2563  SCIPsetDebugMsg(set, "detected global infeasibility at var <%s>: locdom=[%g,%g] glbdom=[%g,%g] new %s bound=%g\n",
2564  SCIPvarGetName(var), SCIPvarGetLbLocal(var),
2566  (boundtype == SCIP_BOUNDTYPE_LOWER ? "lower" : "upper"), newbound);
2567  SCIP_CALL( SCIPnodeCutoff(tree->path[0], set, stat, tree, transprob, origprob, reopt, lp, blkmem) );
2568  }
2569  else
2570  {
2571  if( lp->strongbranching || !applyglobal )
2572  {
2573  SCIP_CONS* cons;
2574  SCIP_Real conslhs;
2575  SCIP_Real consrhs;
2576  char name[SCIP_MAXSTRLEN];
2577 
2578  SCIPsetDebugMsg(set, "add constraint <%s>[%c] %s %g to node #%lld in depth %d\n",
2579  SCIPvarGetName(var), varGetChar(var), boundtype == SCIP_BOUNDTYPE_UPPER ? "<=" : ">=", newbound,
2580  SCIPnodeGetNumber(tree->path[validdepth]), validdepth);
2581 
2582  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "pc_fix_%s", SCIPvarGetName(var));
2583 
2584  if( boundtype == SCIP_BOUNDTYPE_UPPER )
2585  {
2586  conslhs = -SCIPsetInfinity(set);
2587  consrhs = newbound;
2588  }
2589  else
2590  {
2591  conslhs = newbound;
2592  consrhs = SCIPsetInfinity(set);
2593  }
2594 
2595  SCIP_CALL( SCIPcreateConsLinear(set->scip, &cons, name, 0, NULL, NULL, conslhs, consrhs,
2597 
2598  SCIP_CALL( SCIPaddCoefLinear(set->scip, cons, var, 1.0) );
2599 
2600  if( applyglobal )
2601  {
2602  SCIP_CALL( SCIPprobAddCons(transprob, set, stat, cons) );
2603  }
2604  else
2605  {
2606  SCIP_CALL( SCIPnodeAddCons(tree->path[validdepth], blkmem, set, stat, tree, cons) );
2607  }
2608 
2609  SCIP_CALL( SCIPconsRelease(&cons, blkmem, set) );
2610  }
2611  else
2612  {
2613  assert(applyglobal);
2614 
2615  SCIPsetDebugMsg(set, "change global %s bound of <%s>[%c]: %g -> %g\n",
2616  (boundtype == SCIP_BOUNDTYPE_LOWER ? "lower" : "upper"),
2617  SCIPvarGetName(var), varGetChar(var),
2618  (boundtype == SCIP_BOUNDTYPE_LOWER ? SCIPvarGetLbGlobal(var) : SCIPvarGetUbGlobal(var)),
2619  newbound);
2620 
2621  SCIP_CALL( SCIPnodeAddBoundchg(tree->path[0], blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, \
2622  eventqueue, cliquetable, var, newbound, boundtype, FALSE) );
2623 
2624  /* mark the node in the validdepth to be propagated again */
2625  SCIPnodePropagateAgain(tree->path[0], set, stat, tree);
2626  }
2627  }
2628 
2629  if( applyglobal )
2630  ++conflict->nglbchgbds;
2631  else
2632  ++conflict->nlocchgbds;
2633 
2634  if( prooftype == SCIP_CONFTYPE_INFEASLP || prooftype == SCIP_CONFTYPE_ALTINFPROOF )
2635  {
2636  ++conflict->dualproofsinfnnonzeros; /* we count a global bound reduction as size 1 */
2637  ++conflict->ndualproofsinfsuccess;
2638  ++conflict->ninflpsuccess;
2639 
2640  if( applyglobal )
2641  ++conflict->ndualproofsinfglobal;
2642  else
2643  ++conflict->ndualproofsinflocal;
2644  }
2645  else
2646  {
2647  ++conflict->dualproofsbndnnonzeros; /* we count a global bound reduction as size 1 */
2648  ++conflict->ndualproofsbndsuccess;
2649  ++conflict->nboundlpsuccess;
2650 
2651  if( applyglobal )
2652  ++conflict->ndualproofsbndglobal;
2653  else
2654  ++conflict->ndualproofsbndlocal;
2655  }
2656 
2657  return SCIP_OKAY;
2658 }
2659 
2660 /** calculates the minimal activity of a given aggregation row */
2661 static
2663  SCIP_SET* set, /**< global SCIP settings */
2664  SCIP_PROB* transprob, /**< transformed problem data */
2665  SCIP_AGGRROW* aggrrow, /**< aggregation row */
2666  SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables (or NULL for global bounds) */
2667  SCIP_Real* curvarubs, /**< current upper bounds of active problem variables (or NULL for global bounds) */
2668  SCIP_Bool* infdelta /**< pointer to store whether at least one variable contributes with an infinite value */
2669  )
2670 {
2671  SCIP_VAR** vars;
2672  SCIP_Real QUAD(minact);
2673  int* inds;
2674  int nnz;
2675  int i;
2676 
2677  vars = SCIPprobGetVars(transprob);
2678  assert(vars != NULL);
2679 
2680  nnz = SCIPaggrRowGetNNz(aggrrow);
2681  inds = SCIPaggrRowGetInds(aggrrow);
2682 
2683  QUAD_ASSIGN(minact, 0.0);
2684 
2685  if( infdelta != NULL )
2686  *infdelta = FALSE;
2687 
2688  for( i = 0; i < nnz; i++ )
2689  {
2690  SCIP_Real val;
2691  SCIP_Real QUAD(delta);
2692  int v = inds[i];
2693 
2694  assert(SCIPvarGetProbindex(vars[v]) == v);
2695 
2696  val = SCIPaggrRowGetProbvarValue(aggrrow, v);
2697 
2698  if( val > 0.0 )
2699  {
2700  SCIP_Real bnd = (curvarlbs == NULL ? SCIPvarGetLbGlobal(vars[v]) : curvarlbs[v]);
2701  SCIPquadprecProdDD(delta, val, bnd);
2702  }
2703  else
2704  {
2705  SCIP_Real bnd = (curvarubs == NULL ? SCIPvarGetUbGlobal(vars[v]) : curvarubs[v]);
2706  SCIPquadprecProdDD(delta, val, bnd);
2707  }
2708 
2709  /* update minimal activity */
2710  SCIPquadprecSumQQ(minact, minact, delta);
2711 
2712  if( infdelta != NULL && SCIPsetIsInfinity(set, REALABS(QUAD_TO_DBL(delta))) )
2713  {
2714  *infdelta = TRUE;
2715  goto TERMINATE;
2716  }
2717  }
2718 
2719  TERMINATE:
2720  /* check whether the minimal activity is infinite */
2721  if( SCIPsetIsInfinity(set, QUAD_TO_DBL(minact)) )
2722  return SCIPsetInfinity(set);
2723  if( SCIPsetIsInfinity(set, -QUAD_TO_DBL(minact)) )
2724  return -SCIPsetInfinity(set);
2725 
2726  return QUAD_TO_DBL(minact);
2727 }
2728 
2729 /** calculates the minimal activity of a given set of bounds and coefficients */
2730 static
2732  SCIP_SET* set, /**< global SCIP settings */
2733  SCIP_PROB* transprob, /**< transformed problem data */
2734  SCIP_Real* coefs, /**< coefficients in sparse representation */
2735  int* inds, /**< non-zero indices */
2736  int nnz, /**< number of non-zero indices */
2737  SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables (or NULL for global bounds) */
2738  SCIP_Real* curvarubs /**< current upper bounds of active problem variables (or NULL for global bounds) */
2739  )
2740 {
2741  SCIP_VAR** vars;
2742  SCIP_Real QUAD(minact);
2743  int i;
2744 
2745  assert(coefs != NULL);
2746  assert(inds != NULL);
2747 
2748  vars = SCIPprobGetVars(transprob);
2749  assert(vars != NULL);
2750 
2751  QUAD_ASSIGN(minact, 0.0);
2752 
2753  for( i = 0; i < nnz; i++ )
2754  {
2755  SCIP_Real val;
2756  SCIP_Real QUAD(delta);
2757  int v = inds[i];
2758 
2759  assert(SCIPvarGetProbindex(vars[v]) == v);
2760 
2761  val = coefs[i];
2762 
2763  if( val > 0.0 )
2764  {
2765  SCIP_Real bnd;
2766 
2767  assert(curvarlbs == NULL || !SCIPsetIsInfinity(set, -curvarlbs[v]));
2768 
2769  bnd = (curvarlbs == NULL ? SCIPvarGetLbGlobal(vars[v]) : curvarlbs[v]);
2770  SCIPquadprecProdDD(delta, val, bnd);
2771  }
2772  else
2773  {
2774  SCIP_Real bnd;
2775 
2776  assert(curvarubs == NULL || !SCIPsetIsInfinity(set, curvarubs[v]));
2777 
2778  bnd = (curvarubs == NULL ? SCIPvarGetUbGlobal(vars[v]) : curvarubs[v]);
2779  SCIPquadprecProdDD(delta, val, bnd);
2780  }
2781 
2782  /* update minimal activity */
2783  SCIPquadprecSumQQ(minact, minact, delta);
2784  }
2785 
2786  /* check whether the minmal activity is infinite */
2787  if( SCIPsetIsInfinity(set, QUAD_TO_DBL(minact)) )
2788  return SCIPsetInfinity(set);
2789  if( SCIPsetIsInfinity(set, -QUAD_TO_DBL(minact)) )
2790  return -SCIPsetInfinity(set);
2791 
2792  return QUAD_TO_DBL(minact);
2793 }
2794 
2795 /** calculates the minimal activity of a given set of bounds and coefficients */
2796 static
2798  SCIP_SET* set, /**< global SCIP settings */
2799  SCIP_PROB* transprob, /**< transformed problem data */
2800  SCIP_Real* coefs, /**< coefficients in sparse representation */
2801  int* inds, /**< non-zero indices */
2802  int nnz, /**< number of non-zero indices */
2803  SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables (or NULL for global bounds) */
2804  SCIP_Real* curvarubs /**< current upper bounds of active problem variables (or NULL for global bounds) */
2805  )
2806 {
2807  SCIP_VAR** vars;
2808  SCIP_Real QUAD(maxact);
2809  int i;
2810 
2811  assert(coefs != NULL);
2812  assert(inds != NULL);
2813 
2814  vars = SCIPprobGetVars(transprob);
2815  assert(vars != NULL);
2816 
2817  QUAD_ASSIGN(maxact, 0.0);
2818 
2819  for( i = 0; i < nnz; i++ )
2820  {
2821  SCIP_Real val;
2822  SCIP_Real QUAD(delta);
2823  int v = inds[i];
2824 
2825  assert(SCIPvarGetProbindex(vars[v]) == v);
2826 
2827  val = coefs[i];
2828 
2829  if( val < 0.0 )
2830  {
2831  SCIP_Real bnd;
2832 
2833  assert(curvarlbs == NULL || !SCIPsetIsInfinity(set, -curvarlbs[v]));
2834 
2835  bnd = (curvarlbs == NULL ? SCIPvarGetLbGlobal(vars[v]) : curvarlbs[v]);
2836  SCIPquadprecProdDD(delta, val, bnd);
2837  }
2838  else
2839  {
2840  SCIP_Real bnd;
2841 
2842  assert(curvarubs == NULL || !SCIPsetIsInfinity(set, curvarubs[v]));
2843 
2844  bnd = (curvarubs == NULL ? SCIPvarGetUbGlobal(vars[v]) : curvarubs[v]);
2845  SCIPquadprecProdDD(delta, val, bnd);
2846  }
2847 
2848  /* update maximal activity */
2849  SCIPquadprecSumQQ(maxact, maxact, delta);
2850  }
2851 
2852  /* check whether the maximal activity got infinite */
2853  if( SCIPsetIsInfinity(set, QUAD_TO_DBL(maxact)) )
2854  return SCIPsetInfinity(set);
2855  if( SCIPsetIsInfinity(set, -QUAD_TO_DBL(maxact)) )
2856  return -SCIPsetInfinity(set);
2857 
2858  return QUAD_TO_DBL(maxact);
2859 }
2860 
2861 static
2863  SCIP_CONFLICT* conflict, /**< conflict analysis data */
2864  SCIP_SET* set, /**< global SCIP settings */
2865  SCIP_STAT* stat, /**< dynamic SCIP statistics */
2866  SCIP_REOPT* reopt, /**< reoptimization data */
2867  SCIP_TREE* tree, /**< tree data */
2868  BMS_BLKMEM* blkmem, /**< block memory */
2869  SCIP_PROB* origprob, /**< original problem */
2870  SCIP_PROB* transprob, /**< transformed problem */
2871  SCIP_LP* lp, /**< LP data */
2872  SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
2873  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2874  SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
2875  SCIP_Real* coefs, /**< coefficients in sparse representation */
2876  int* inds, /**< non-zero indices */
2877  int nnz, /**< number of non-zero indices */
2878  SCIP_Real rhs, /**< right-hand side */
2879  SCIP_CONFTYPE conflicttype, /**< type of the conflict */
2880  int validdepth /**< depth where the proof is valid */
2881  )
2882 {
2883  SCIP_VAR** vars;
2884  SCIP_Real minact;
2885  int i;
2886 
2887  assert(coefs != NULL);
2888  assert(inds != NULL);
2889  assert(nnz >= 0);
2890 
2891  vars = SCIPprobGetVars(transprob);
2892  minact = getMinActivity(set, transprob, coefs, inds, nnz, NULL, NULL);
2893 
2894  /* we cannot find global tightenings */
2895  if( SCIPsetIsInfinity(set, -minact) )
2896  return SCIP_OKAY;
2897 
2898  for( i = 0; i < nnz; i++ )
2899  {
2900  SCIP_VAR* var;
2901  SCIP_Real val;
2902  SCIP_Real resminact;
2903  SCIP_Real lb;
2904  SCIP_Real ub;
2905  int pos;
2906 
2907  pos = inds[i];
2908  val = coefs[i];
2909  var = vars[pos];
2910  lb = SCIPvarGetLbGlobal(var);
2911  ub = SCIPvarGetUbGlobal(var);
2912 
2913  assert(!SCIPsetIsZero(set, val));
2914 
2915  resminact = minact;
2916 
2917  /* we got a potential new upper bound */
2918  if( val > 0.0 )
2919  {
2920  SCIP_Real newub;
2921 
2922  resminact -= (val * lb);
2923  newub = (rhs - resminact)/val;
2924 
2925  if( SCIPsetIsInfinity(set, newub) )
2926  continue;
2927 
2928  /* we cannot tighten the upper bound */
2929  if( SCIPsetIsGE(set, newub, ub) )
2930  continue;
2931 
2932  SCIP_CALL( tightenSingleVar(conflict, set, stat, tree, blkmem, origprob, transprob, reopt, lp, branchcand, \
2933  eventqueue, cliquetable, var, val, rhs-resminact, conflicttype, validdepth) );
2934  }
2935  /* we got a potential new lower bound */
2936  else
2937  {
2938  SCIP_Real newlb;
2939 
2940  resminact -= (val * ub);
2941  newlb = (rhs - resminact)/val;
2942 
2943  if( SCIPsetIsInfinity(set, -newlb) )
2944  continue;
2945 
2946  /* we cannot tighten the lower bound */
2947  if( SCIPsetIsLE(set, newlb, lb) )
2948  continue;
2949 
2950  SCIP_CALL( tightenSingleVar(conflict, set, stat, tree, blkmem, origprob, transprob, reopt, lp, branchcand, \
2951  eventqueue, cliquetable, var, val, rhs-resminact, conflicttype, validdepth) );
2952  }
2953 
2954  /* the minimal activity should stay unchanged because we tightened the bound that doesn't contribute to the
2955  * minimal activity
2956  */
2957  assert(SCIPsetIsEQ(set, minact, getMinActivity(set, transprob, coefs, inds, nnz, NULL, NULL)));
2958  }
2959 
2960  return SCIP_OKAY;
2961 }
2962 
2963 
2964 /** creates a proof constraint and tries to add it to the storage */
2965 static
2967  SCIP_CONFLICT* conflict, /**< conflict analysis data */
2968  SCIP_CONFLICTSTORE* conflictstore, /**< conflict pool data */
2969  SCIP_PROOFSET* proofset, /**< proof set */
2970  SCIP_SET* set, /**< global SCIP settings */
2971  SCIP_STAT* stat, /**< dynamic SCIP statistics */
2972  SCIP_PROB* origprob, /**< original problem */
2973  SCIP_PROB* transprob, /**< transformed problem */
2974  SCIP_TREE* tree, /**< tree data */
2975  SCIP_REOPT* reopt, /**< reoptimization data */
2976  SCIP_LP* lp, /**< LP data */
2977  SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
2978  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2979  SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
2980  BMS_BLKMEM* blkmem /**< block memory */
2981  )
2982 {
2983  SCIP_CONS* cons;
2984  SCIP_CONS* upgdcons;
2985  SCIP_VAR** vars;
2986  SCIP_Real* coefs;
2987  int* inds;
2988  SCIP_Real rhs;
2989  SCIP_Real fillin;
2990  SCIP_Real globalminactivity;
2991  SCIP_Bool applyglobal;
2992  SCIP_Bool toolong;
2993  SCIP_Bool contonly;
2994  SCIP_Bool hasrelaxvar;
2995  SCIP_CONFTYPE conflicttype;
2996  char name[SCIP_MAXSTRLEN];
2997  int nnz;
2998  int i;
2999 
3000  assert(conflict != NULL);
3001  assert(conflictstore != NULL);
3002  assert(proofset != NULL);
3003  assert(proofset->validdepth == 0 || proofset->validdepth < SCIPtreeGetFocusDepth(tree));
3004 
3005  nnz = proofsetGetNVars(proofset);
3006 
3007  if( nnz == 0 )
3008  return SCIP_OKAY;
3009 
3010  vars = SCIPprobGetVars(transprob);
3011 
3012  rhs = proofsetGetRhs(proofset);
3013  assert(!SCIPsetIsInfinity(set, rhs));
3014 
3015  coefs = proofsetGetVals(proofset);
3016  assert(coefs != NULL);
3017 
3018  inds = proofsetGetInds(proofset);
3019  assert(inds != NULL);
3020 
3021  conflicttype = proofsetGetConftype(proofset);
3022 
3023  applyglobal = (proofset->validdepth <= SCIPtreeGetEffectiveRootDepth(tree));
3024 
3025  if( applyglobal )
3026  {
3027  SCIP_Real globalmaxactivity = getMaxActivity(set, transprob, coefs, inds, nnz, NULL, NULL);
3028 
3029  /* check whether the alternative proof is redundant */
3030  if( SCIPsetIsLE(set, globalmaxactivity, rhs) )
3031  return SCIP_OKAY;
3032 
3033  /* check whether the constraint proves global infeasibility */
3034  globalminactivity = getMinActivity(set, transprob, coefs, inds, nnz, NULL, NULL);
3035  if( SCIPsetIsGT(set, globalminactivity, rhs) )
3036  {
3037  SCIPsetDebugMsg(set, "detect global infeasibility: minactivity=%g, rhs=%g\n", globalminactivity, rhs);
3038 
3039  SCIP_CALL( SCIPnodeCutoff(tree->path[proofset->validdepth], set, stat, tree, transprob, origprob, reopt, lp, blkmem) );
3040 
3041  goto UPDATESTATISTICS;
3042  }
3043  }
3044 
3045  if( set->conf_minmaxvars >= nnz )
3046  toolong = FALSE;
3047  else
3048  {
3049  SCIP_Real maxnnz;
3050 
3051  if( transprob->startnconss < 100 )
3052  maxnnz = 0.85 * transprob->nvars;
3053  else
3054  maxnnz = (SCIP_Real)transprob->nvars;
3055 
3056  fillin = nnz;
3057  if( conflicttype == SCIP_CONFTYPE_INFEASLP || conflicttype == SCIP_CONFTYPE_ALTINFPROOF )
3058  {
3059  fillin += SCIPconflictstoreGetNDualInfProofs(conflictstore) * SCIPconflictstoreGetAvgNnzDualInfProofs(conflictstore);
3060  fillin /= (SCIPconflictstoreGetNDualInfProofs(conflictstore) + 1.0);
3061  toolong = (fillin > MIN(2.0 * stat->avgnnz, maxnnz));
3062  }
3063  else
3064  {
3065  assert(conflicttype == SCIP_CONFTYPE_BNDEXCEEDING || conflicttype == SCIP_CONFTYPE_ALTBNDPROOF);
3066 
3067  fillin += SCIPconflictstoreGetNDualBndProofs(conflictstore) * SCIPconflictstoreGetAvgNnzDualBndProofs(conflictstore);
3068  fillin /= (SCIPconflictstoreGetNDualBndProofs(conflictstore) + 1.0);
3069  toolong = (fillin > MIN(1.5 * stat->avgnnz, maxnnz));
3070  }
3071 
3072  toolong = (toolong && (nnz > set->conf_maxvarsfac * transprob->nvars));
3073  }
3074 
3075  /* don't store global dual proofs that are too long / have too many non-zeros */
3076  if( toolong )
3077  {
3078  if( applyglobal )
3079  {
3080  SCIP_CALL( propagateLongProof(conflict, set, stat, reopt, tree, blkmem, origprob, transprob, lp, branchcand,
3081  eventqueue, cliquetable, coefs, inds, nnz, rhs, conflicttype, proofset->validdepth) );
3082  }
3083  return SCIP_OKAY;
3084  }
3085 
3086  /* check if conflict contains variables that are invalid after a restart to label it appropriately */
3087  hasrelaxvar = FALSE;
3088  contonly = TRUE;
3089  for( i = 0; i < nnz && (!hasrelaxvar || contonly); ++i )
3090  {
3091  hasrelaxvar |= SCIPvarIsRelaxationOnly(vars[inds[i]]);
3092 
3093  if( SCIPvarIsIntegral(vars[inds[i]]) )
3094  contonly = FALSE;
3095  }
3096 
3097  if( !applyglobal && contonly )
3098  return SCIP_OKAY;
3099 
3100  if( conflicttype == SCIP_CONFTYPE_INFEASLP || conflicttype == SCIP_CONFTYPE_ALTINFPROOF )
3101  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "dualproof_inf_%" SCIP_LONGINT_FORMAT, conflict->ndualproofsinfsuccess);
3102  else if( conflicttype == SCIP_CONFTYPE_BNDEXCEEDING || conflicttype == SCIP_CONFTYPE_ALTBNDPROOF )
3103  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "dualproof_bnd_%" SCIP_LONGINT_FORMAT, conflict->ndualproofsbndsuccess);
3104  else
3105  return SCIP_INVALIDCALL;
3106 
3107  SCIP_CALL( SCIPcreateConsLinear(set->scip, &cons, name, 0, NULL, NULL, -SCIPsetInfinity(set), rhs,
3108  FALSE, FALSE, FALSE, FALSE, TRUE, !applyglobal,
3109  FALSE, TRUE, TRUE, FALSE) );
3110 
3111  for( i = 0; i < nnz; i++ )
3112  {
3113  int v = inds[i];
3114  SCIP_CALL( SCIPaddCoefLinear(set->scip, cons, vars[v], coefs[i]) );
3115  }
3116 
3117  /* do not upgrade linear constraints of size 1 */
3118  if( nnz > 1 )
3119  {
3120  upgdcons = NULL;
3121  /* try to automatically convert a linear constraint into a more specific and more specialized constraint */
3122  SCIP_CALL( SCIPupgradeConsLinear(set->scip, cons, &upgdcons) );
3123  if( upgdcons != NULL )
3124  {
3125  SCIP_CALL( SCIPreleaseCons(set->scip, &cons) );
3126  cons = upgdcons;
3127 
3128  if( conflicttype == SCIP_CONFTYPE_INFEASLP )
3129  conflicttype = SCIP_CONFTYPE_ALTINFPROOF;
3130  else if( conflicttype == SCIP_CONFTYPE_BNDEXCEEDING )
3131  conflicttype = SCIP_CONFTYPE_ALTBNDPROOF;
3132  }
3133  }
3134 
3135  /* mark constraint to be a conflict */
3136  SCIPconsMarkConflict(cons);
3137 
3138  /* add constraint to storage */
3139  if( conflicttype == SCIP_CONFTYPE_INFEASLP || conflicttype == SCIP_CONFTYPE_ALTINFPROOF )
3140  {
3141  /* add dual proof to storage */
3142  SCIP_CALL( SCIPconflictstoreAddDualraycons(conflictstore, cons, blkmem, set, stat, transprob, reopt, hasrelaxvar) );
3143  }
3144  else
3145  {
3146  SCIP_Real scale = 1.0;
3147  SCIP_Bool updateside = FALSE;
3148 
3149  /* In some cases the constraint could not be updated to a more special type. However, it is possible that
3150  * constraint got scaled. Therefore, we need to be very careful when updating the lhs/rhs after the incumbent
3151  * solution has improved.
3152  */
3153  if( conflicttype == SCIP_CONFTYPE_BNDEXCEEDING )
3154  {
3155  SCIP_Real side;
3156 
3157 #ifndef NDEBUG
3158  SCIP_CONSHDLR* conshdlr = SCIPconsGetHdlr(cons);
3159 
3160  assert(conshdlr != NULL);
3161  assert(strcmp(SCIPconshdlrGetName(conshdlr), "linear") == 0);
3162 #endif
3163  side = SCIPgetLhsLinear(set->scip, cons);
3164 
3165  if( !SCIPsetIsInfinity(set, -side) )
3166  {
3167  if( SCIPsetIsZero(set, side) )
3168  {
3169  scale = 1.0;
3170  }
3171  else
3172  {
3173  scale = proofsetGetRhs(proofset) / side;
3174  assert(SCIPsetIsNegative(set, scale));
3175  }
3176  }
3177  else
3178  {
3179  side = SCIPgetRhsLinear(set->scip, cons);
3180  assert(!SCIPsetIsInfinity(set, side));
3181 
3182  if( SCIPsetIsZero(set, side) )
3183  {
3184  scale = 1.0;
3185  }
3186  else
3187  {
3188  scale = proofsetGetRhs(proofset) / side;
3189  assert(SCIPsetIsPositive(set, scale));
3190  }
3191  }
3192  updateside = TRUE;
3193  }
3194 
3195  /* add dual proof to storage */
3196  SCIP_CALL( SCIPconflictstoreAddDualsolcons(conflictstore, cons, blkmem, set, stat, transprob, reopt, scale, updateside, hasrelaxvar) );
3197  }
3198 
3199  if( applyglobal ) /*lint !e774*/
3200  {
3201  /* add the constraint to the global problem */
3202  SCIP_CALL( SCIPprobAddCons(transprob, set, stat, cons) );
3203  }
3204  else
3205  {
3206  SCIP_CALL( SCIPnodeAddCons(tree->path[proofset->validdepth], blkmem, set, stat, tree, cons) );
3207  }
3208 
3209  SCIPsetDebugMsg(set, "added proof-constraint to node %p (#%lld) in depth %d (nproofconss %d)\n",
3210  (void*)tree->path[proofset->validdepth], SCIPnodeGetNumber(tree->path[proofset->validdepth]),
3211  proofset->validdepth,
3212  (conflicttype == SCIP_CONFTYPE_INFEASLP || conflicttype == SCIP_CONFTYPE_ALTINFPROOF)
3214 
3215  /* release the constraint */
3216  SCIP_CALL( SCIPreleaseCons(set->scip, &cons) );
3217 
3218  UPDATESTATISTICS:
3219  /* update statistics */
3220  if( conflicttype == SCIP_CONFTYPE_INFEASLP || conflicttype == SCIP_CONFTYPE_ALTINFPROOF )
3221  {
3222  conflict->dualproofsinfnnonzeros += nnz;
3223  if( applyglobal ) /*lint !e774*/
3224  ++conflict->ndualproofsinfglobal;
3225  else
3226  ++conflict->ndualproofsinflocal;
3227  ++conflict->ndualproofsinfsuccess;
3228  }
3229  else
3230  {
3231  assert(conflicttype == SCIP_CONFTYPE_BNDEXCEEDING || conflicttype == SCIP_CONFTYPE_ALTBNDPROOF);
3232  conflict->dualproofsbndnnonzeros += nnz;
3233  if( applyglobal ) /*lint !e774*/
3234  ++conflict->ndualproofsbndglobal;
3235  else
3236  ++conflict->ndualproofsbndlocal;
3237 
3238  ++conflict->ndualproofsbndsuccess;
3239  }
3240  return SCIP_OKAY;
3241 }
3242 
3243 /* create proof constraints out of proof sets */
3244 static
3246  SCIP_CONFLICT* conflict, /**< conflict analysis data */
3247  SCIP_CONFLICTSTORE* conflictstore, /**< conflict store */
3248  BMS_BLKMEM* blkmem, /**< block memory */
3249  SCIP_SET* set, /**< global SCIP settings */
3250  SCIP_STAT* stat, /**< dynamic problem statistics */
3251  SCIP_PROB* transprob, /**< transformed problem after presolve */
3252  SCIP_PROB* origprob, /**< original problem */
3253  SCIP_TREE* tree, /**< branch and bound tree */
3254  SCIP_REOPT* reopt, /**< reoptimization data structure */
3255  SCIP_LP* lp, /**< current LP data */
3256  SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
3257  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3258  SCIP_CLIQUETABLE* cliquetable /**< clique table data structure */
3259  )
3260 {
3261  assert(conflict != NULL);
3262 
3264  {
3265  /* only one variable has a coefficient different to zero, we add this bound change instead of a constraint */
3266  if( proofsetGetNVars(conflict->proofset) == 1 )
3267  {
3268  SCIP_VAR** vars;
3269  SCIP_Real* coefs;
3270  int* inds;
3271  SCIP_Real rhs;
3272 
3273  vars = SCIPprobGetVars(transprob);
3274 
3275  coefs = proofsetGetVals(conflict->proofset);
3276  inds = proofsetGetInds(conflict->proofset);
3277  rhs = proofsetGetRhs(conflict->proofset);
3278 
3279  SCIP_CALL( tightenSingleVar(conflict, set, stat, tree, blkmem, origprob, transprob, reopt, lp, \
3280  branchcand, eventqueue, cliquetable, vars[inds[0]], coefs[0], rhs, conflict->proofset->conflicttype,
3281  conflict->proofset->validdepth) );
3282  }
3283  else
3284  {
3285  SCIP_Bool skipinitialproof = FALSE;
3286 
3287  /* prefer an infeasibility proof
3288  *
3289  * todo: check whether this is really what we want
3290  */
3291  if( set->conf_prefinfproof && proofsetGetConftype(conflict->proofset) == SCIP_CONFTYPE_BNDEXCEEDING )
3292  {
3293  int i;
3294 
3295  for( i = 0; i < conflict->nproofsets; i++ )
3296  {
3298  {
3299  skipinitialproof = TRUE;
3300  break;
3301  }
3302  }
3303  }
3304 
3305  if( !skipinitialproof )
3306  {
3307  /* create and add the original proof */
3308  SCIP_CALL( createAndAddProofcons(conflict, conflictstore, conflict->proofset, set, stat, origprob, transprob, \
3309  tree, reopt, lp, branchcand, eventqueue, cliquetable, blkmem) );
3310  }
3311  }
3312 
3313  /* clear the proof set anyway */
3314  proofsetClear(conflict->proofset);
3315  }
3316 
3317  if( conflict->nproofsets > 0 )
3318  {
3319  int i;
3320 
3321  for( i = 0; i < conflict->nproofsets; i++ )
3322  {
3323  assert(conflict->proofsets[i] != NULL);
3324  assert(proofsetGetConftype(conflict->proofsets[i]) != SCIP_CONFTYPE_UNKNOWN);
3325 
3326  /* only one variable has a coefficient different to zero, we add this bound change instead of a constraint */
3327  if( proofsetGetNVars(conflict->proofsets[i]) == 1 )
3328  {
3329  SCIP_VAR** vars;
3330  SCIP_Real* coefs;
3331  int* inds;
3332  SCIP_Real rhs;
3333 
3334  vars = SCIPprobGetVars(transprob);
3335 
3336  coefs = proofsetGetVals(conflict->proofsets[i]);
3337  inds = proofsetGetInds(conflict->proofsets[i]);
3338  rhs = proofsetGetRhs(conflict->proofsets[i]);
3339 
3340  SCIP_CALL( tightenSingleVar(conflict, set, stat, tree, blkmem, origprob, transprob, reopt, lp,
3341  branchcand, eventqueue, cliquetable, vars[inds[0]], coefs[0], rhs,
3342  conflict->proofsets[i]->conflicttype, conflict->proofsets[i]->validdepth) );
3343  }
3344  else
3345  {
3346  /* create and add proof constraint */
3347  SCIP_CALL( createAndAddProofcons(conflict, conflictstore, conflict->proofsets[i], set, stat, origprob, \
3348  transprob, tree, reopt, lp, branchcand, eventqueue, cliquetable, blkmem) );
3349  }
3350  }
3351 
3352  /* free all proofsets */
3353  for( i = 0; i < conflict->nproofsets; i++ )
3354  proofsetFree(&conflict->proofsets[i], blkmem);
3355 
3356  conflict->nproofsets = 0;
3357  }
3358 
3359  return SCIP_OKAY;
3360 }
3361 
3362 /** adds the given conflict set as conflict constraint to the problem */
3363 static
3365  SCIP_CONFLICT* conflict, /**< conflict analysis data */
3366  BMS_BLKMEM* blkmem, /**< block memory */
3367  SCIP_SET* set, /**< global SCIP settings */
3368  SCIP_STAT* stat, /**< dynamic problem statistics */
3369  SCIP_PROB* transprob, /**< transformed problem after presolve */
3370  SCIP_PROB* origprob, /**< original problem */
3371  SCIP_TREE* tree, /**< branch and bound tree */
3372  SCIP_REOPT* reopt, /**< reoptimization data structure */
3373  SCIP_LP* lp, /**< current LP data */
3374  SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
3375  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3376  SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
3377  SCIP_CONFLICTSET* conflictset, /**< conflict set to add to the tree */
3378  int insertdepth, /**< depth level at which the conflict set should be added */
3379  SCIP_Bool* success /**< pointer to store whether the addition was successful */
3380  )
3381 {
3382  SCIP_Bool redundant;
3383  int h;
3384 
3385  assert(conflict != NULL);
3386  assert(tree != NULL);
3387  assert(tree->path != NULL);
3388  assert(conflictset != NULL);
3389  assert(conflictset->validdepth <= insertdepth);
3390  assert(success != NULL);
3391 
3392  *success = FALSE;
3393  redundant = FALSE;
3394 
3395  /* try to derive global bound changes and shorten the conflictset by using implication and clique and variable bound
3396  * information
3397  */
3398  if( conflictset->nbdchginfos > 1 && insertdepth == 0 && !lp->strongbranching )
3399  {
3400  int nbdchgs;
3401  int nredvars;
3402 #ifdef SCIP_DEBUG
3403  int oldnbdchginfos = conflictset->nbdchginfos;
3404 #endif
3405  assert(conflictset->validdepth == 0);
3406 
3407  /* check conflict set on debugging solution */
3408  SCIP_CALL( SCIPdebugCheckConflict(blkmem, set, tree->root, conflictset->bdchginfos, conflictset->relaxedbds, conflictset->nbdchginfos) );
3409 
3410  SCIPclockStart(conflict->dIBclock, set);
3411 
3412  /* find global bound changes which can be derived from the new conflict set */
3413  SCIP_CALL( detectImpliedBounds(set, transprob, conflictset, &nbdchgs, &nredvars, &redundant) );
3414 
3415  /* all variables where removed, we have an infeasibility proof */
3416  if( conflictset->nbdchginfos == 0 )
3417  return SCIP_OKAY;
3418 
3419  /* debug check for reduced conflict set */
3420  if( nredvars > 0 )
3421  {
3422  /* check conflict set on debugging solution */
3423  SCIP_CALL( SCIPdebugCheckConflict(blkmem, set, tree->root, conflictset->bdchginfos, conflictset->relaxedbds, conflictset->nbdchginfos) ); /*lint !e506 !e774*/
3424  }
3425 
3426 #ifdef SCIP_DEBUG
3427  SCIPsetDebugMsg(set, " -> conflict set removed %d redundant variables (old nvars %d, new nvars = %d)\n", nredvars, oldnbdchginfos, conflictset->nbdchginfos);
3428  SCIPsetDebugMsg(set, " -> conflict set led to %d global bound changes %s(cdpt:%d, fdpt:%d, confdpt:%d, len:%d):\n",
3429  nbdchgs, redundant ? "(conflict became redundant) " : "", SCIPtreeGetCurrentDepth(tree), SCIPtreeGetFocusDepth(tree),
3430  conflictset->conflictdepth, conflictset->nbdchginfos);
3431  conflictsetPrint(conflictset);
3432 #endif
3433 
3434  SCIPclockStop(conflict->dIBclock, set);
3435 
3436  if( redundant )
3437  {
3438  if( nbdchgs > 0 )
3439  *success = TRUE;
3440 
3441  return SCIP_OKAY;
3442  }
3443  }
3444 
3445  /* in case the conflict set contains only one bound change which is globally valid we apply that bound change
3446  * directly (except if we are in strong branching or diving - in this case a bound change would yield an unflushed LP
3447  * and is not handled when restoring the information)
3448  *
3449  * @note A bound change can only be applied if it is are related to the active node or if is a global bound
3450  * change. Bound changes which are related to any other node cannot be handled at point due to the internal
3451  * data structure
3452  */
3453  if( conflictset->nbdchginfos == 1 && insertdepth == 0 && !lp->strongbranching && !lp->diving )
3454  {
3455  SCIP_VAR* var;
3456  SCIP_Real bound;
3457  SCIP_BOUNDTYPE boundtype;
3458 
3459  var = conflictset->bdchginfos[0]->var;
3460  assert(var != NULL);
3461 
3462  boundtype = SCIPboundtypeOpposite((SCIP_BOUNDTYPE) conflictset->bdchginfos[0]->boundtype);
3463  bound = conflictset->relaxedbds[0];
3464 
3465  /* for continuous variables, we can only use the relaxed version of the bounds negation: !(x <= u) -> x >= u */
3466  if( SCIPvarIsIntegral(var) )
3467  {
3468  assert(SCIPsetIsIntegral(set, bound));
3469  bound += (boundtype == SCIP_BOUNDTYPE_LOWER ? +1.0 : -1.0);
3470  }
3471 
3472  SCIPsetDebugMsg(set, " -> apply global bound change: <%s> %s %g\n",
3473  SCIPvarGetName(var), boundtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", bound);
3474 
3475  SCIP_CALL( SCIPnodeAddBoundchg(tree->path[conflictset->validdepth], blkmem, set, stat, transprob, origprob, tree,
3476  reopt, lp, branchcand, eventqueue, cliquetable, var, bound, boundtype, FALSE) );
3477 
3478  *success = TRUE;
3479  SCIP_CALL( updateStatistics(conflict, blkmem, set, stat, conflictset, insertdepth) );
3480  }
3481  else
3482  {
3483  /* sort conflict handlers by priority */
3485 
3486  /* call conflict handlers to create a conflict constraint */
3487  for( h = 0; h < set->nconflicthdlrs; ++h )
3488  {
3489  SCIP_RESULT result;
3490 
3491  assert(conflictset->conflicttype != SCIP_CONFTYPE_UNKNOWN);
3492 
3493  SCIP_CALL( SCIPconflicthdlrExec(set->conflicthdlrs[h], set, tree->path[insertdepth],
3494  tree->path[conflictset->validdepth], conflictset->bdchginfos, conflictset->relaxedbds,
3495  conflictset->nbdchginfos, conflictset->conflicttype, conflictset->usescutoffbound, *success, &result) );
3496  if( result == SCIP_CONSADDED )
3497  {
3498  *success = TRUE;
3499  SCIP_CALL( updateStatistics(conflict, blkmem, set, stat, conflictset, insertdepth) );
3500  }
3501 
3502  SCIPsetDebugMsg(set, " -> call conflict handler <%s> (prio=%d) to create conflict set with %d bounds returned result %d\n",
3503  SCIPconflicthdlrGetName(set->conflicthdlrs[h]), SCIPconflicthdlrGetPriority(set->conflicthdlrs[h]),
3504  conflictset->nbdchginfos, result);
3505  }
3506  }
3507 
3508  return SCIP_OKAY;
3509 }
3510 
3511 /** adds the collected conflict constraints to the corresponding nodes; the best set->conf_maxconss conflict constraints
3512  * are added to the node of their validdepth; additionally (if not yet added, and if repropagation is activated), the
3513  * conflict constraint that triggers the earliest repropagation is added to the node of its validdepth
3514  */
3516  SCIP_CONFLICT* conflict, /**< conflict analysis data */
3517  BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
3518  SCIP_SET* set, /**< global SCIP settings */
3519  SCIP_STAT* stat, /**< dynamic problem statistics */
3520  SCIP_PROB* transprob, /**< transformed problem */
3521  SCIP_PROB* origprob, /**< original problem */
3522  SCIP_TREE* tree, /**< branch and bound tree */
3523  SCIP_REOPT* reopt, /**< reoptimization data structure */
3524  SCIP_LP* lp, /**< current LP data */
3525  SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
3526  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3527  SCIP_CLIQUETABLE* cliquetable /**< clique table data structure */
3528  )
3529 {
3530  assert(conflict != NULL);
3531  assert(set != NULL);
3532  assert(stat != NULL);
3533  assert(transprob != NULL);
3534  assert(tree != NULL);
3535 
3536  /* is there anything to do? */
3537  if( conflict->nconflictsets > 0 )
3538  {
3539  SCIP_CONFLICTSET* repropconflictset;
3540  int nconflictsetsused;
3541  int focusdepth;
3542 #ifndef NDEBUG
3543  int currentdepth;
3544 #endif
3545  int cutoffdepth;
3546  int repropdepth;
3547  int maxconflictsets;
3548  int maxsize;
3549  int i;
3550 
3551  /* calculate the maximal number of conflict sets to accept, and the maximal size of each accepted conflict set */
3552  maxconflictsets = (set->conf_maxconss == -1 ? INT_MAX : set->conf_maxconss);
3553  maxsize = conflictCalcMaxsize(set, transprob);
3554 
3555  focusdepth = SCIPtreeGetFocusDepth(tree);
3556 #ifndef NDEBUG
3557  currentdepth = SCIPtreeGetCurrentDepth(tree);
3558  assert(focusdepth <= currentdepth);
3559  assert(currentdepth == tree->pathlen-1);
3560 #endif
3561 
3562  SCIPsetDebugMsg(set, "flushing %d conflict sets at focus depth %d (maxconflictsets: %d, maxsize: %d)\n",
3563  conflict->nconflictsets, focusdepth, maxconflictsets, maxsize);
3564 
3565  /* mark the focus node to have produced conflict sets in the visualization output */
3566  SCIPvisualFoundConflict(stat->visual, stat, tree->path[focusdepth]);
3567 
3568  /* insert the conflict sets at the corresponding nodes */
3569  nconflictsetsused = 0;
3570  cutoffdepth = INT_MAX;
3571  repropdepth = INT_MAX;
3572  repropconflictset = NULL;
3573  for( i = 0; i < conflict->nconflictsets && nconflictsetsused < maxconflictsets; ++i )
3574  {
3575  SCIP_CONFLICTSET* conflictset;
3576 
3577  conflictset = conflict->conflictsets[i];
3578  assert(conflictset != NULL);
3579  assert(0 <= conflictset->validdepth);
3580  assert(conflictset->validdepth <= conflictset->insertdepth);
3581  assert(conflictset->insertdepth <= focusdepth);
3582  assert(conflictset->insertdepth <= conflictset->repropdepth);
3583  assert(conflictset->repropdepth <= currentdepth || conflictset->repropdepth == INT_MAX); /* INT_MAX for dive/probing/strong */
3584  assert(conflictset->conflictdepth <= currentdepth || conflictset->conflictdepth == INT_MAX); /* INT_MAX for dive/probing/strong */
3585 
3586  /* ignore conflict sets that are only valid at a node that was already cut off */
3587  if( conflictset->insertdepth >= cutoffdepth )
3588  {
3589  SCIPsetDebugMsg(set, " -> ignoring conflict set with insertdepth %d >= cutoffdepth %d\n",
3590  conflictset->validdepth, cutoffdepth);
3591  continue;
3592  }
3593 
3594  /* if no conflict bounds exist, the node and its sub tree in the conflict set's valid depth can be
3595  * cut off completely
3596  */
3597  if( conflictset->nbdchginfos == 0 )
3598  {
3599  SCIPsetDebugMsg(set, " -> empty conflict set in depth %d cuts off sub tree at depth %d\n",
3600  focusdepth, conflictset->validdepth);
3601 
3602  SCIP_CALL( SCIPnodeCutoff(tree->path[conflictset->validdepth], set, stat, tree, transprob, origprob, reopt, lp, blkmem) );
3603  cutoffdepth = conflictset->validdepth;
3604  continue;
3605  }
3606 
3607  /* if the conflict set is too long, use the conflict set only if it decreases the repropagation depth */
3608  if( conflictset->nbdchginfos > maxsize )
3609  {
3610  SCIPsetDebugMsg(set, " -> conflict set is too long: %d > %d literals\n", conflictset->nbdchginfos, maxsize);
3611  if( set->conf_keepreprop && conflictset->repropagate && conflictset->repropdepth < repropdepth )
3612  {
3613  repropdepth = conflictset->repropdepth;
3614  repropconflictset = conflictset;
3615  }
3616  }
3617  else
3618  {
3619  SCIP_Bool success;
3620 
3621  /* call conflict handlers to create a conflict constraint */
3622  SCIP_CALL( conflictAddConflictCons(conflict, blkmem, set, stat, transprob, origprob, tree, reopt, lp, \
3623  branchcand, eventqueue, cliquetable, conflictset, conflictset->insertdepth, &success) );
3624 
3625  /* if no conflict bounds exist, the node and its sub tree in the conflict set's valid depth can be
3626  * cut off completely
3627  */
3628  if( conflictset->nbdchginfos == 0 )
3629  {
3630  assert(!success);
3631 
3632  SCIPsetDebugMsg(set, " -> empty conflict set in depth %d cuts off sub tree at depth %d\n",
3633  focusdepth, conflictset->validdepth);
3634 
3635  SCIP_CALL( SCIPnodeCutoff(tree->path[conflictset->validdepth], set, stat, tree, transprob, origprob, \
3636  reopt, lp, blkmem) );
3637  cutoffdepth = conflictset->validdepth;
3638  continue;
3639  }
3640 
3641  if( success )
3642  {
3643  SCIPsetDebugMsg(set, " -> conflict set %d/%d added (cdpt:%d, fdpt:%d, insert:%d, valid:%d, conf:%d, reprop:%d, len:%d):\n",
3644  nconflictsetsused+1, maxconflictsets, SCIPtreeGetCurrentDepth(tree), SCIPtreeGetFocusDepth(tree),
3645  conflictset->insertdepth, conflictset->validdepth, conflictset->conflictdepth, conflictset->repropdepth,
3646  conflictset->nbdchginfos);
3647  SCIPdebug(conflictsetPrint(conflictset));
3648 
3649  if( conflictset->repropagate && conflictset->repropdepth <= repropdepth )
3650  {
3651  repropdepth = conflictset->repropdepth;
3652  repropconflictset = NULL;
3653  }
3654  nconflictsetsused++;
3655  }
3656  }
3657  }
3658 
3659  /* reactivate propagation on the first node where one of the new conflict sets trigger a deduction */
3660  if( set->conf_repropagate && repropdepth < cutoffdepth && repropdepth < tree->pathlen )
3661  {
3662  assert(0 <= repropdepth && repropdepth < tree->pathlen);
3663  assert((int) tree->path[repropdepth]->depth == repropdepth);
3664 
3665  /* if the conflict constraint of smallest repropagation depth was not yet added, insert it now */
3666  if( repropconflictset != NULL )
3667  {
3668  SCIP_Bool success;
3669 
3670  assert(repropconflictset->repropagate);
3671  assert(repropconflictset->repropdepth == repropdepth);
3672 
3673  SCIP_CALL( conflictAddConflictCons(conflict, blkmem, set, stat, transprob, origprob, tree, reopt, lp, \
3674  branchcand, eventqueue, cliquetable, repropconflictset, repropdepth, &success) );
3675 
3676  /* if no conflict bounds exist, the node and its sub tree in the conflict set's valid depth can be
3677  * cut off completely
3678  */
3679  if( repropconflictset->nbdchginfos == 0 )
3680  {
3681  assert(!success);
3682 
3683  SCIPsetDebugMsg(set, " -> empty reprop conflict set in depth %d cuts off sub tree at depth %d\n",
3684  focusdepth, repropconflictset->validdepth);
3685 
3686  SCIP_CALL( SCIPnodeCutoff(tree->path[repropconflictset->validdepth], set, stat, tree, transprob, \
3687  origprob, reopt, lp, blkmem) );
3688  }
3689 
3690 #ifdef SCIP_DEBUG
3691  if( success )
3692  {
3693  SCIPsetDebugMsg(set, " -> additional reprop conflict set added (cdpt:%d, fdpt:%d, insert:%d, valid:%d, conf:%d, reprop:%d, len:%d):\n",
3695  repropconflictset->insertdepth, repropconflictset->validdepth, repropconflictset->conflictdepth,
3696  repropconflictset->repropdepth, repropconflictset->nbdchginfos);
3697  SCIPdebug(conflictsetPrint(repropconflictset));
3698  }
3699 #endif
3700  }
3701 
3702  /* mark the node in the repropdepth to be propagated again */
3703  SCIPnodePropagateAgain(tree->path[repropdepth], set, stat, tree);
3704 
3705  SCIPsetDebugMsg(set, "marked node %p in depth %d to be repropagated due to conflicts found in depth %d\n",
3706  (void*)tree->path[repropdepth], repropdepth, focusdepth);
3707  }
3708 
3709  /* free the conflict store */
3710  for( i = 0; i < conflict->nconflictsets; ++i )
3711  {
3712  conflictsetFree(&conflict->conflictsets[i], blkmem);
3713  }
3714  conflict->nconflictsets = 0;
3715  }
3716 
3717  /* free all temporarily created bound change information data */
3718  conflictFreeTmpBdchginfos(conflict, blkmem);
3719 
3720  return SCIP_OKAY;
3721 }
3722 
3723 /** returns the current number of conflict sets in the conflict set storage */
3725  SCIP_CONFLICT* conflict /**< conflict analysis data */
3726  )
3727 {
3728  assert(conflict != NULL);
3729 
3730  return conflict->nconflictsets;
3731 }
3732 
3733 /** returns the total number of conflict constraints that were added to the problem */
3735  SCIP_CONFLICT* conflict /**< conflict analysis data */
3736  )
3737 {
3738  assert(conflict != NULL);
3739 
3740  return conflict->nappliedglbconss + conflict->nappliedlocconss;
3741 }
3742 
3743 /** returns the total number of literals in conflict constraints that were added to the problem */
3745  SCIP_CONFLICT* conflict /**< conflict analysis data */
3746  )
3747 {
3748  assert(conflict != NULL);
3749 
3750  return conflict->nappliedglbliterals + conflict->nappliedlocliterals;
3751 }
3752 
3753 /** returns the total number of global bound changes applied by the conflict analysis */
3755  SCIP_CONFLICT* conflict /**< conflict analysis data */
3756  )
3757 {
3758  assert(conflict != NULL);
3759 
3760  return conflict->nglbchgbds;
3761 }
3762 
3763 /** returns the total number of conflict constraints that were added globally to the problem */
3765  SCIP_CONFLICT* conflict /**< conflict analysis data */
3766  )
3767 {
3768  assert(conflict != NULL);
3769 
3770  return conflict->nappliedglbconss;
3771 }
3772 
3773 /** returns the total number of literals in conflict constraints that were added globally to the problem */
3775  SCIP_CONFLICT* conflict /**< conflict analysis data */
3776  )
3777 {
3778  assert(conflict != NULL);
3779 
3780  return conflict->nappliedglbliterals;
3781 }
3782 
3783 /** returns the total number of local bound changes applied by the conflict analysis */
3785  SCIP_CONFLICT* conflict /**< conflict analysis data */
3786  )
3787 {
3788  assert(conflict != NULL);
3789 
3790  return conflict->nlocchgbds;
3791 }
3792 
3793 /** returns the total number of conflict constraints that were added locally to the problem */
3795  SCIP_CONFLICT* conflict /**< conflict analysis data */
3796  )
3797 {
3798  assert(conflict != NULL);
3799 
3800  return conflict->nappliedlocconss;
3801 }
3802 
3803 /** returns the total number of literals in conflict constraints that were added locally to the problem */
3805  SCIP_CONFLICT* conflict /**< conflict analysis data */
3806  )
3807 {
3808  assert(conflict != NULL);
3809 
3810  return conflict->nappliedlocliterals;
3811 }
3812 
3813 
3814 
3815 
3816 /*
3817  * Propagation Conflict Analysis
3818  */
3819 
3820 /** returns whether bound change has a valid reason that can be resolved in conflict analysis */
3821 static
3823  SCIP_BDCHGINFO* bdchginfo /**< bound change information */
3824  )
3825 {
3826  assert(bdchginfo != NULL);
3827  assert(!SCIPbdchginfoIsRedundant(bdchginfo));
3828 
3831  && SCIPbdchginfoGetInferProp(bdchginfo) != NULL));
3832 }
3833 
3834 /** compares two conflict set entries, such that bound changes infered later are
3835  * ordered prior to ones that were infered earlier
3836  */
3837 static
3838 SCIP_DECL_SORTPTRCOMP(conflictBdchginfoComp)
3839 { /*lint --e{715}*/
3840  SCIP_BDCHGINFO* bdchginfo1;
3841  SCIP_BDCHGINFO* bdchginfo2;
3842 
3843  bdchginfo1 = (SCIP_BDCHGINFO*)elem1;
3844  bdchginfo2 = (SCIP_BDCHGINFO*)elem2;
3845  assert(bdchginfo1 != NULL);
3846  assert(bdchginfo2 != NULL);
3847  assert(!SCIPbdchginfoIsRedundant(bdchginfo1));
3848  assert(!SCIPbdchginfoIsRedundant(bdchginfo2));
3849 
3850  if( bdchginfo1 == bdchginfo2 )
3851  return 0;
3852 
3854  return -1;
3855  else
3856  return +1;
3857 }
3858 
3859 /** return TRUE if conflict analysis is applicable; In case the function return FALSE there is no need to initialize the
3860  * conflict analysis since it will not be applied
3861  */
3863  SCIP_SET* set /**< global SCIP settings */
3864  )
3865 {
3866  /* check, if propagation conflict analysis is enabled */
3867  if( !set->conf_enable || !set->conf_useprop )
3868  return FALSE;
3869 
3870  /* check, if there are any conflict handlers to use a conflict set */
3871  if( set->nconflicthdlrs == 0 )
3872  return FALSE;
3873 
3874  return TRUE;
3875 }
3876 
3877 /** creates conflict analysis data for propagation conflicts */
3879  SCIP_CONFLICT** conflict, /**< pointer to conflict analysis data */
3880  BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
3881  SCIP_SET* set /**< global SCIP settings */
3882  )
3883 {
3884  assert(conflict != NULL);
3885 
3886  SCIP_ALLOC( BMSallocMemory(conflict) );
3887 
3888  SCIP_CALL( SCIPclockCreate(&(*conflict)->dIBclock, SCIP_CLOCKTYPE_DEFAULT) );
3889  SCIP_CALL( SCIPclockCreate(&(*conflict)->propanalyzetime, SCIP_CLOCKTYPE_DEFAULT) );
3890  SCIP_CALL( SCIPclockCreate(&(*conflict)->inflpanalyzetime, SCIP_CLOCKTYPE_DEFAULT) );
3891  SCIP_CALL( SCIPclockCreate(&(*conflict)->boundlpanalyzetime, SCIP_CLOCKTYPE_DEFAULT) );
3892  SCIP_CALL( SCIPclockCreate(&(*conflict)->sbanalyzetime, SCIP_CLOCKTYPE_DEFAULT) );
3893  SCIP_CALL( SCIPclockCreate(&(*conflict)->pseudoanalyzetime, SCIP_CLOCKTYPE_DEFAULT) );
3894 
3895  /* enable or disable timing depending on the parameter statistic timing */
3896  SCIPconflictEnableOrDisableClocks((*conflict), set->time_statistictiming);
3897 
3898  SCIP_CALL( SCIPpqueueCreate(&(*conflict)->bdchgqueue, set->mem_arraygrowinit, set->mem_arraygrowfac,
3899  conflictBdchginfoComp, NULL) );
3900  SCIP_CALL( SCIPpqueueCreate(&(*conflict)->forcedbdchgqueue, set->mem_arraygrowinit, set->mem_arraygrowfac,
3901  conflictBdchginfoComp, NULL) );
3902  SCIP_CALL( conflictsetCreate(&(*conflict)->conflictset, blkmem) );
3903  (*conflict)->conflictsets = NULL;
3904  (*conflict)->conflictsetscores = NULL;
3905  (*conflict)->tmpbdchginfos = NULL;
3906  (*conflict)->conflictsetssize = 0;
3907  (*conflict)->nconflictsets = 0;
3908  (*conflict)->proofsets = NULL;
3909  (*conflict)->proofsetssize = 0;
3910  (*conflict)->nproofsets = 0;
3911  (*conflict)->tmpbdchginfossize = 0;
3912  (*conflict)->ntmpbdchginfos = 0;
3913  (*conflict)->count = 0;
3914  (*conflict)->nglbchgbds = 0;
3915  (*conflict)->nappliedglbconss = 0;
3916  (*conflict)->nappliedglbliterals = 0;
3917  (*conflict)->nlocchgbds = 0;
3918  (*conflict)->nappliedlocconss = 0;
3919  (*conflict)->nappliedlocliterals = 0;
3920  (*conflict)->npropcalls = 0;
3921  (*conflict)->npropsuccess = 0;
3922  (*conflict)->npropconfconss = 0;
3923  (*conflict)->npropconfliterals = 0;
3924  (*conflict)->npropreconvconss = 0;
3925  (*conflict)->npropreconvliterals = 0;
3926  (*conflict)->ninflpcalls = 0;
3927  (*conflict)->ninflpsuccess = 0;
3928  (*conflict)->ninflpconfconss = 0;
3929  (*conflict)->ninflpconfliterals = 0;
3930  (*conflict)->ninflpreconvconss = 0;
3931  (*conflict)->ninflpreconvliterals = 0;
3932  (*conflict)->ninflpiterations = 0;
3933  (*conflict)->nboundlpcalls = 0;
3934  (*conflict)->nboundlpsuccess = 0;
3935  (*conflict)->nboundlpconfconss = 0;
3936  (*conflict)->nboundlpconfliterals = 0;
3937  (*conflict)->nboundlpreconvconss = 0;
3938  (*conflict)->nboundlpreconvliterals = 0;
3939  (*conflict)->nboundlpiterations = 0;
3940  (*conflict)->nsbcalls = 0;
3941  (*conflict)->nsbsuccess = 0;
3942  (*conflict)->nsbconfconss = 0;
3943  (*conflict)->nsbconfliterals = 0;
3944  (*conflict)->nsbreconvconss = 0;
3945  (*conflict)->nsbreconvliterals = 0;
3946  (*conflict)->nsbiterations = 0;
3947  (*conflict)->npseudocalls = 0;
3948  (*conflict)->npseudosuccess = 0;
3949  (*conflict)->npseudoconfconss = 0;
3950  (*conflict)->npseudoconfliterals = 0;
3951  (*conflict)->npseudoreconvconss = 0;
3952  (*conflict)->npseudoreconvliterals = 0;
3953  (*conflict)->ndualproofsinfglobal = 0;
3954  (*conflict)->ndualproofsinflocal = 0;
3955  (*conflict)->ndualproofsinfsuccess = 0;
3956  (*conflict)->dualproofsinfnnonzeros = 0;
3957  (*conflict)->ndualproofsbndglobal = 0;
3958  (*conflict)->ndualproofsbndlocal = 0;
3959  (*conflict)->ndualproofsbndsuccess = 0;
3960  (*conflict)->dualproofsbndnnonzeros = 0;
3961 
3962  SCIP_CALL( conflictInitProofset((*conflict), blkmem) );
3963 
3964  return SCIP_OKAY;
3965 }
3966 
3967 /** frees conflict analysis data for propagation conflicts */
3969  SCIP_CONFLICT** conflict, /**< pointer to conflict analysis data */
3970  BMS_BLKMEM* blkmem /**< block memory of transformed problem */
3971  )
3972 {
3973  assert(conflict != NULL);
3974  assert(*conflict != NULL);
3975  assert((*conflict)->nconflictsets == 0);
3976  assert((*conflict)->ntmpbdchginfos == 0);
3977 
3978 #ifdef SCIP_CONFGRAPH
3979  confgraphFree();
3980 #endif
3981 
3982  SCIPclockFree(&(*conflict)->dIBclock);
3983  SCIPclockFree(&(*conflict)->propanalyzetime);
3984  SCIPclockFree(&(*conflict)->inflpanalyzetime);
3985  SCIPclockFree(&(*conflict)->boundlpanalyzetime);
3986  SCIPclockFree(&(*conflict)->sbanalyzetime);
3987  SCIPclockFree(&(*conflict)->pseudoanalyzetime);
3988  SCIPpqueueFree(&(*conflict)->bdchgqueue);
3989  SCIPpqueueFree(&(*conflict)->forcedbdchgqueue);
3990  conflictsetFree(&(*conflict)->conflictset, blkmem);
3991  proofsetFree(&(*conflict)->proofset, blkmem);
3992 
3993  BMSfreeMemoryArrayNull(&(*conflict)->conflictsets);
3994  BMSfreeMemoryArrayNull(&(*conflict)->conflictsetscores);
3995  BMSfreeMemoryArrayNull(&(*conflict)->proofsets);
3996  BMSfreeMemoryArrayNull(&(*conflict)->tmpbdchginfos);
3997  BMSfreeMemory(conflict);
3998 
3999  return SCIP_OKAY;
4000 }
4001 
4002 /** clears the conflict queue and the current conflict set */
4003 static
4005  SCIP_CONFLICT* conflict /**< conflict analysis data */
4006  )
4007 {
4008  assert(conflict != NULL);
4009 
4010  SCIPpqueueClear(conflict->bdchgqueue);
4011  SCIPpqueueClear(conflict->forcedbdchgqueue);
4012  conflictsetClear(conflict->conflictset);
4013 }
4014 
4015 /** initializes the propagation conflict analysis by clearing the conflict candidate queue */
4017  SCIP_CONFLICT* conflict, /**< conflict analysis data */
4018  SCIP_SET* set, /**< global SCIP settings */
4019  SCIP_STAT* stat, /**< problem statistics */
4020  SCIP_PROB* prob, /**< problem data */
4021  SCIP_CONFTYPE conftype, /**< type of the conflict */
4022  SCIP_Bool usescutoffbound /**< depends the conflict on a cutoff bound? */
4023  )
4024 {
4025  assert(conflict != NULL);
4026  assert(set != NULL);
4027  assert(stat != NULL);
4028  assert(prob != NULL);
4029 
4030  SCIPsetDebugMsg(set, "initializing conflict analysis\n");
4031 
4032  /* clear the conflict candidate queue and the conflict set */
4033  conflictClear(conflict);
4034 
4035  /* set conflict type */
4036  assert(conftype == SCIP_CONFTYPE_BNDEXCEEDING || conftype == SCIP_CONFTYPE_INFEASLP
4037  || conftype == SCIP_CONFTYPE_PROPAGATION);
4038  conflict->conflictset->conflicttype = conftype;
4039 
4040  /* set whether a cutoff bound is involved */
4041  conflict->conflictset->usescutoffbound = usescutoffbound;
4042 
4043  /* increase the conflict counter, such that binary variables of new conflict set and new conflict queue are labeled
4044  * with this new counter
4045  */
4046  conflict->count++;
4047  if( conflict->count == 0 ) /* make sure, 0 is not a valid conflict counter (may happen due to integer overflow) */
4048  conflict->count = 1;
4049 
4050  /* increase the conflict score weight for history updates of future conflict reasons */
4051  if( stat->nnodes > stat->lastconflictnode )
4052  {
4053  assert(0.0 < set->conf_scorefac && set->conf_scorefac <= 1.0);
4054  stat->vsidsweight /= set->conf_scorefac;
4055  assert(stat->vsidsweight > 0.0);
4056 
4057  /* if the conflict score for the next conflict exceeds 1000.0, rescale all history conflict scores */
4058  if( stat->vsidsweight >= 1000.0 )
4059  {
4060  int v;
4061 
4062  for( v = 0; v < prob->nvars; ++v )
4063  {
4064  SCIP_CALL( SCIPvarScaleVSIDS(prob->vars[v], 1.0/stat->vsidsweight) );
4065  }
4066  SCIPhistoryScaleVSIDS(stat->glbhistory, 1.0/stat->vsidsweight);
4068  stat->vsidsweight = 1.0;
4069  }
4070  stat->lastconflictnode = stat->nnodes;
4071  }
4072 
4073 #ifdef SCIP_CONFGRAPH
4074  confgraphFree();
4075  SCIP_CALL( confgraphCreate(set, conflict) );
4076 #endif
4077 
4078  return SCIP_OKAY;
4079 }
4080 
4081 /** marks bound to be present in the current conflict and returns whether a bound which is at least as tight was already
4082  * member of the current conflict (i.e., the given bound change does not need to be added)
4083  */
4084 static
4086  SCIP_CONFLICT* conflict, /**< conflict analysis data */
4087  SCIP_SET* set, /**< global SCIP settings */
4088  SCIP_BDCHGINFO* bdchginfo, /**< bound change to add to the conflict set */
4089  SCIP_Real relaxedbd /**< relaxed bound */
4090  )
4091 {
4092  SCIP_VAR* var;
4093  SCIP_Real newbound;
4094 
4095  assert(conflict != NULL);
4096 
4097  var = SCIPbdchginfoGetVar(bdchginfo);
4098  newbound = SCIPbdchginfoGetNewbound(bdchginfo);
4099  assert(var != NULL);
4100 
4101  switch( SCIPbdchginfoGetBoundtype(bdchginfo) )
4102  {
4103  case SCIP_BOUNDTYPE_LOWER:
4104  /* check if the variables lower bound is already member of the conflict */
4105  if( var->conflictlbcount == conflict->count )
4106  {
4107  /* the variable is already member of the conflict; hence check if the new bound is redundant */
4108  if( var->conflictlb > newbound )
4109  {
4110  SCIPsetDebugMsg(set, "ignoring redundant bound change <%s> >= %g since a stronger lower bound exist <%s> >= %g\n",
4111  SCIPvarGetName(var), newbound, SCIPvarGetName(var), var->conflictlb);
4112  return TRUE;
4113  }
4114  else if( var->conflictlb == newbound ) /*lint !e777*/
4115  {
4116  SCIPsetDebugMsg(set, "ignoring redundant bound change <%s> >= %g since this lower bound is already present\n", SCIPvarGetName(var), newbound);
4117  SCIPsetDebugMsg(set, "adjust relaxed lower bound <%g> -> <%g>\n", var->conflictlb, relaxedbd);
4118  var->conflictrelaxedlb = MAX(var->conflictrelaxedlb, relaxedbd);
4119  return TRUE;
4120  }
4121  }
4122 
4123  /* add the variable lower bound to the current conflict */
4124  var->conflictlbcount = conflict->count;
4125 
4126  /* remember the lower bound and relaxed bound to allow only better/tighter lower bounds for that variables
4127  * w.r.t. this conflict
4128  */
4129  var->conflictlb = newbound;
4130  var->conflictrelaxedlb = relaxedbd;
4131 
4132  return FALSE;
4133 
4134  case SCIP_BOUNDTYPE_UPPER:
4135  /* check if the variables upper bound is already member of the conflict */
4136  if( var->conflictubcount == conflict->count )
4137  {
4138  /* the variable is already member of the conflict; hence check if the new bound is redundant */
4139  if( var->conflictub < newbound )
4140  {
4141  SCIPsetDebugMsg(set, "ignoring redundant bound change <%s> <= %g since a stronger upper bound exist <%s> <= %g\n",
4142  SCIPvarGetName(var), newbound, SCIPvarGetName(var), var->conflictub);
4143  return TRUE;
4144  }
4145  else if( var->conflictub == newbound ) /*lint !e777*/
4146  {
4147  SCIPsetDebugMsg(set, "ignoring redundant bound change <%s> <= %g since this upper bound is already present\n", SCIPvarGetName(var), newbound);
4148  SCIPsetDebugMsg(set, "adjust relaxed upper bound <%g> -> <%g>\n", var->conflictub, relaxedbd);
4149  var->conflictrelaxedub = MIN(var->conflictrelaxedub, relaxedbd);
4150  return TRUE;
4151  }
4152  }
4153 
4154  /* add the variable upper bound to the current conflict */
4155  var->conflictubcount = conflict->count;
4156 
4157  /* remember the upper bound and relaxed bound to allow only better/tighter upper bounds for that variables
4158  * w.r.t. this conflict
4159  */
4160  var->conflictub = newbound;
4161  var->conflictrelaxedub = relaxedbd;
4162 
4163  return FALSE;
4164 
4165  default:
4166  SCIPerrorMessage("invalid bound type %d\n", SCIPbdchginfoGetBoundtype(bdchginfo));
4167  SCIPABORT();
4168  return FALSE; /*lint !e527*/
4169  }
4170 }
4171 
4172 /** puts bound change into the current conflict set */
4173 static
4175  SCIP_CONFLICT* conflict, /**< conflict analysis data */
4176  BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
4177  SCIP_SET* set, /**< global SCIP settings */
4178  SCIP_BDCHGINFO* bdchginfo, /**< bound change to add to the conflict set */
4179  SCIP_Real relaxedbd /**< relaxed bound */
4180  )
4181 {
4182  assert(conflict != NULL);
4183  assert(!SCIPbdchginfoIsRedundant(bdchginfo));
4184 
4185  /* check if the relaxed bound is really a relaxed bound */
4186  assert(SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER || SCIPsetIsGE(set, relaxedbd, SCIPbdchginfoGetNewbound(bdchginfo)));
4187  assert(SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_UPPER || SCIPsetIsLE(set, relaxedbd, SCIPbdchginfoGetNewbound(bdchginfo)));
4188 
4189  SCIPsetDebugMsg(set, "putting bound change <%s> %s %g(%g) at depth %d to current conflict set\n",
4190  SCIPvarGetName(SCIPbdchginfoGetVar(bdchginfo)),
4191  SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", SCIPbdchginfoGetNewbound(bdchginfo),
4192  relaxedbd, SCIPbdchginfoGetDepth(bdchginfo));
4193 
4194  /* mark the bound to be member of the conflict and check if a bound which is at least as tight is already member of
4195  * the conflict
4196  */
4197  if( !conflictMarkBoundCheckPresence(conflict, set, bdchginfo, relaxedbd) )
4198  {
4199  /* add the bound change to the current conflict set */
4200  SCIP_CALL( conflictsetAddBound(conflict->conflictset, blkmem, set, bdchginfo, relaxedbd) );
4201 
4202 #ifdef SCIP_CONFGRAPH
4203  if( bdchginfo != confgraphcurrentbdchginfo )
4204  confgraphAddBdchg(bdchginfo);
4205 #endif
4206  }
4207 #ifdef SCIP_CONFGRAPH
4208  else
4209  confgraphLinkBdchg(bdchginfo);
4210 #endif
4211 
4212  return SCIP_OKAY;
4213 }
4214 
4215 /** returns whether the negation of the given bound change would lead to a globally valid literal */
4216 static
4218  SCIP_SET* set, /**< global SCIP settings */
4219  SCIP_BDCHGINFO* bdchginfo /**< bound change information */
4220  )
4221 {
4222  SCIP_VAR* var;
4223  SCIP_BOUNDTYPE boundtype;
4224  SCIP_Real bound;
4225 
4226  var = SCIPbdchginfoGetVar(bdchginfo);
4227  boundtype = SCIPbdchginfoGetBoundtype(bdchginfo);
4228  bound = SCIPbdchginfoGetNewbound(bdchginfo);
4229 
4230  return (SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS
4231  && ((boundtype == SCIP_BOUNDTYPE_LOWER && SCIPsetIsFeasGE(set, bound, SCIPvarGetUbGlobal(var)))
4232  || (boundtype == SCIP_BOUNDTYPE_UPPER && SCIPsetIsFeasLE(set, bound, SCIPvarGetLbGlobal(var)))));
4233 }
4234 
4235 /** adds given bound change information to the conflict candidate queue */
4236 static
4238  SCIP_CONFLICT* conflict, /**< conflict analysis data */
4239  SCIP_SET* set, /**< global SCIP settings */
4240  SCIP_BDCHGINFO* bdchginfo, /**< bound change information */
4241  SCIP_Real relaxedbd /**< relaxed bound */
4242  )
4243 {
4244  assert(conflict != NULL);
4245  assert(set != NULL);
4246  assert(bdchginfo != NULL);
4247  assert(!SCIPbdchginfoIsRedundant(bdchginfo));
4248 
4249  /* check if the relaxed bound is really a relaxed bound */
4250  assert(SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER || SCIPsetIsGE(set, relaxedbd, SCIPbdchginfoGetNewbound(bdchginfo)));
4251  assert(SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_UPPER || SCIPsetIsLE(set, relaxedbd, SCIPbdchginfoGetNewbound(bdchginfo)));
4252 
4253  /* mark the bound to be member of the conflict and check if a bound which is at least as tight is already member of
4254  * the conflict
4255  */
4256  if( !conflictMarkBoundCheckPresence(conflict, set, bdchginfo, relaxedbd) )
4257  {
4258  /* insert the bound change into the conflict queue */
4259  if( (!set->conf_preferbinary || SCIPvarIsBinary(SCIPbdchginfoGetVar(bdchginfo)))
4260  && !isBoundchgUseless(set, bdchginfo) )
4261  {
4262  SCIP_CALL( SCIPpqueueInsert(conflict->bdchgqueue, (void*)bdchginfo) );
4263  }
4264  else
4265  {
4266  SCIP_CALL( SCIPpqueueInsert(conflict->forcedbdchgqueue, (void*)bdchginfo) );
4267  }
4268 
4269 #ifdef SCIP_CONFGRAPH
4270  confgraphAddBdchg(bdchginfo);
4271 #endif
4272  }
4273 #ifdef SCIP_CONFGRAPH
4274  else
4275  confgraphLinkBdchg(bdchginfo);
4276 #endif
4277 
4278  return SCIP_OKAY;
4279 }
4280 
4281 /** convert variable and bound change to active variable */
4282 static
4284  SCIP_VAR** var, /**< pointer to variable */
4285  SCIP_SET* set, /**< global SCIP settings */
4286  SCIP_BOUNDTYPE* boundtype, /**< pointer to type of bound that was changed: lower or upper bound */
4287  SCIP_Real* bound /**< pointer to bound to convert, or NULL */
4288  )
4289 {
4290  SCIP_Real scalar;
4291  SCIP_Real constant;
4292 
4293  scalar = 1.0;
4294  constant = 0.0;
4295 
4296  /* transform given varibale to active varibale */
4297  SCIP_CALL( SCIPvarGetProbvarSum(var, set, &scalar, &constant) );
4298  assert(SCIPvarGetStatus(*var) == SCIP_VARSTATUS_FIXED || scalar != 0.0); /*lint !e777*/
4299 
4300  if( SCIPvarGetStatus(*var) == SCIP_VARSTATUS_FIXED )
4301  return SCIP_OKAY;
4302 
4303  /* if the scalar of the aggregation is negative, we have to switch the bound type */
4304  if( scalar < 0.0 )
4305  (*boundtype) = SCIPboundtypeOpposite(*boundtype);
4306 
4307  if( bound != NULL )
4308  {
4309  (*bound) -= constant;
4310  (*bound) /= scalar;
4311  }
4312 
4313  return SCIP_OKAY;
4314 }
4315 
4316 /** adds variable's bound to conflict candidate queue */
4317 static
4319  SCIP_CONFLICT* conflict, /**< conflict analysis data */
4320  BMS_BLKMEM* blkmem, /**< block memory */
4321  SCIP_SET* set, /**< global SCIP settings */
4322  SCIP_STAT* stat, /**< dynamic problem statistics */
4323  SCIP_VAR* var, /**< problem variable */
4324  SCIP_BOUNDTYPE boundtype, /**< type of bound that was changed: lower or upper bound */
4325  SCIP_BDCHGINFO* bdchginfo, /**< bound change info, or NULL */
4326  SCIP_Real relaxedbd /**< relaxed bound */
4327  )
4328 {
4329  assert(SCIPvarIsActive(var));
4330  assert(bdchginfo != NULL);
4331  assert(!SCIPbdchginfoIsRedundant(bdchginfo));
4332 
4333  SCIPsetDebugMsg(set, " -> adding bound <%s> %s %.15g(%.15g) [status:%d, type:%d, depth:%d, pos:%d, reason:<%s>, info:%d] to candidates\n",
4334  SCIPvarGetName(var),
4335  boundtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
4336  SCIPbdchginfoGetNewbound(bdchginfo), relaxedbd,
4337  SCIPvarGetStatus(var), SCIPvarGetType(var),
4338  SCIPbdchginfoGetDepth(bdchginfo), SCIPbdchginfoGetPos(bdchginfo),
4339  SCIPbdchginfoGetChgtype(bdchginfo) == SCIP_BOUNDCHGTYPE_BRANCHING ? "branch"
4343  : "none")),
4345 
4346  /* the local bound change may be resolved and has to be put on the candidate queue;
4347  * we even put bound changes without inference information on the queue in order to automatically
4348  * eliminate multiple insertions of the same bound change
4349  */
4350  assert(SCIPbdchginfoGetVar(bdchginfo) == var);
4351  assert(SCIPbdchginfoGetBoundtype(bdchginfo) == boundtype);
4352  assert(SCIPbdchginfoGetDepth(bdchginfo) >= 0);
4353  assert(SCIPbdchginfoGetPos(bdchginfo) >= 0);
4354 
4355  /* the relaxed bound should be a relaxation */
4356  assert(boundtype == SCIP_BOUNDTYPE_LOWER ? SCIPsetIsLE(set, relaxedbd, SCIPbdchginfoGetNewbound(bdchginfo)) : SCIPsetIsGE(set, relaxedbd, SCIPbdchginfoGetNewbound(bdchginfo)));
4357 
4358  /* the relaxed bound should be worse then the old bound of the bound change info */
4359  assert(boundtype == SCIP_BOUNDTYPE_LOWER ? SCIPsetIsGT(set, relaxedbd, SCIPbdchginfoGetOldbound(bdchginfo)) : SCIPsetIsLT(set, relaxedbd, SCIPbdchginfoGetOldbound(bdchginfo)));
4360 
4361  /* put bound change information into priority queue */
4362  SCIP_CALL( conflictQueueBound(conflict, set, bdchginfo, relaxedbd) );
4363 
4364  /* each variable which is add to the conflict graph gets an increase in the VSIDS
4365  *
4366  * @note That is different to the VSIDS preseted in the literature
4367  */
4368  SCIP_CALL( incVSIDS(var, blkmem, set, stat, boundtype, relaxedbd, set->conf_conflictgraphweight) );
4369 
4370  return SCIP_OKAY;
4371 }
4372 
4373 /** adds variable's bound to conflict candidate queue */
4375  SCIP_CONFLICT* conflict, /**< conflict analysis data */
4376  BMS_BLKMEM* blkmem, /**< block memory */
4377  SCIP_SET* set, /**< global SCIP settings */
4378  SCIP_STAT* stat, /**< dynamic problem statistics */
4379  SCIP_VAR* var, /**< problem variable */
4380  SCIP_BOUNDTYPE boundtype, /**< type of bound that was changed: lower or upper bound */
4381  SCIP_BDCHGIDX* bdchgidx /**< bound change index (time stamp of bound change), or NULL for current time */
4382  )
4383 {
4384  SCIP_BDCHGINFO* bdchginfo;
4385 
4386  assert(conflict != NULL);
4387  assert(stat != NULL);
4388  assert(var != NULL);
4389 
4390  /* convert bound to active problem variable */
4391  SCIP_CALL( convertToActiveVar(&var, set, &boundtype, NULL) );
4392 
4393  /* we can ignore fixed variables */
4395  return SCIP_OKAY;
4396 
4397  /* if the variable is multi-aggregated, add the bounds of all aggregation variables */
4399  {
4400  SCIP_VAR** vars;
4401  SCIP_Real* scalars;
4402  int nvars;
4403  int i;
4404 
4405  vars = SCIPvarGetMultaggrVars(var);
4406  scalars = SCIPvarGetMultaggrScalars(var);
4407  nvars = SCIPvarGetMultaggrNVars(var);
4408  for( i = 0; i < nvars; ++i )
4409  {
4410  SCIP_CALL( SCIPconflictAddBound(conflict, blkmem, set, stat, vars[i],
4411  (scalars[i] < 0.0 ? SCIPboundtypeOpposite(boundtype) : boundtype), bdchgidx) );
4412  }
4413 
4414  return SCIP_OKAY;
4415  }
4416  assert(SCIPvarIsActive(var));
4417 
4418  /* get bound change information */
4419  bdchginfo = SCIPvarGetBdchgInfo(var, boundtype, bdchgidx, FALSE);
4420 
4421  /* if bound of variable was not changed (this means it is still the global bound), we can ignore the conflicting
4422  * bound
4423  */
4424  if( bdchginfo == NULL )
4425  return SCIP_OKAY;
4426 
4427  assert(SCIPbdchgidxIsEarlier(SCIPbdchginfoGetIdx(bdchginfo), bdchgidx));
4428 
4429  SCIP_CALL( conflictAddBound(conflict, blkmem, set, stat, var, boundtype, bdchginfo, SCIPbdchginfoGetNewbound(bdchginfo)) );
4430 
4431  return SCIP_OKAY;
4432 }
4433 
4434 /** adds variable's bound to conflict candidate queue */
4436  SCIP_CONFLICT* conflict, /**< conflict analysis data */
4437  BMS_BLKMEM* blkmem, /**< block memory */
4438  SCIP_SET* set, /**< global SCIP settings */
4439  SCIP_STAT* stat, /**< dynamic problem statistics */
4440  SCIP_VAR* var, /**< problem variable */
4441  SCIP_BOUNDTYPE boundtype, /**< type of bound that was changed: lower or upper bound */
4442  SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
4443  SCIP_Real relaxedbd /**< the relaxed bound */
4444  )
4445 {
4446  SCIP_BDCHGINFO* bdchginfo;
4447  int nbdchgs;
4448 
4449  assert(conflict != NULL);
4450  assert(stat != NULL);
4451  assert(var != NULL);
4452 
4453  if( !SCIPvarIsActive(var) )
4454  {
4455  /* convert bound to active problem variable */
4456  SCIP_CALL( convertToActiveVar(&var, set, &boundtype, &relaxedbd) );
4457 
4458  /* we can ignore fixed variables */
4460  return SCIP_OKAY;
4461 
4462  /* if the variable is multi-aggregated, add the bounds of all aggregation variables */
4464  {
4465  SCIPsetDebugMsg(set, "ignoring relaxed bound information since variable <%s> is multi-aggregated active\n", SCIPvarGetName(var));
4466 
4467  SCIP_CALL( SCIPconflictAddBound(conflict, blkmem, set, stat, var, boundtype, bdchgidx) );
4468 
4469  return SCIP_OKAY;
4470  }
4471  }
4472  assert(SCIPvarIsActive(var));
4473 
4474  /* get bound change information */
4475  bdchginfo = SCIPvarGetBdchgInfo(var, boundtype, bdchgidx, FALSE);
4476 
4477  /* if bound of variable was not changed (this means it is still the global bound), we can ignore the conflicting
4478  * bound
4479  */
4480  if( bdchginfo == NULL )
4481  return SCIP_OKAY;
4482 
4483  /* check that the bound change info is not a temporary one */
4484  assert(SCIPbdchgidxGetPos(&bdchginfo->bdchgidx) >= 0);
4485 
4486  /* get the position of the bound change information within the bound change array of the variable */
4487  nbdchgs = (int) bdchginfo->pos;
4488  assert(nbdchgs >= 0);
4489 
4490  /* if the relaxed bound should be ignored, set the relaxed bound to the bound given by the bdchgidx; that ensures
4491  * that the loop(s) below will be skipped
4492  */
4493  if( set->conf_ignorerelaxedbd )
4494  relaxedbd = SCIPbdchginfoGetNewbound(bdchginfo);
4495 
4496  /* search for the bound change information which includes the relaxed bound */
4497  if( boundtype == SCIP_BOUNDTYPE_LOWER )
4498  {
4499  SCIP_Real newbound;
4500 
4501  /* adjust relaxed lower bound w.r.t. variable type */
4502  SCIPvarAdjustLb(var, set, &relaxedbd);
4503 
4504  /* due to numericis we compare the relaxed lower bound to the one present at the particular time point and take
4505  * the better one
4506  */
4507  newbound = SCIPbdchginfoGetNewbound(bdchginfo);
4508  relaxedbd = MIN(relaxedbd, newbound);
4509 
4510  /* check if relaxed lower bound is smaller or equal to global lower bound; if so we can ignore the conflicting
4511  * bound
4512  */
4513  if( SCIPsetIsLE(set, relaxedbd, SCIPvarGetLbGlobal(var)) )
4514  return SCIP_OKAY;
4515 
4516  while( nbdchgs > 0 )
4517  {
4518  assert(SCIPsetIsLE(set, relaxedbd, SCIPbdchginfoGetNewbound(bdchginfo)));
4519 
4520  /* check if the old lower bound is greater than or equal to relaxed lower bound; if not we found the bound
4521  * change info which we need to report
4522  */
4523  if( SCIPsetIsGT(set, relaxedbd, SCIPbdchginfoGetOldbound(bdchginfo)) )
4524  break;
4525 
4526  bdchginfo = SCIPvarGetBdchgInfoLb(var, nbdchgs-1);
4527 
4528  SCIPsetDebugMsg(set, "lower bound change %d oldbd=%.15g, newbd=%.15g, depth=%d, pos=%d, redundant=%u\n",
4529  nbdchgs, SCIPbdchginfoGetOldbound(bdchginfo), SCIPbdchginfoGetNewbound(bdchginfo),
4530  SCIPbdchginfoGetDepth(bdchginfo), SCIPbdchginfoGetPos(bdchginfo),
4531  SCIPbdchginfoIsRedundant(bdchginfo));
4532 
4533  /* if bound change is redundant (this means it now a global bound), we can ignore the conflicting bound */
4534  if( SCIPbdchginfoIsRedundant(bdchginfo) )
4535  return SCIP_OKAY;
4536 
4537  nbdchgs--;
4538  }
4539  assert(SCIPsetIsGT(set, relaxedbd, SCIPbdchginfoGetOldbound(bdchginfo)));
4540  }
4541  else
4542  {
4543  SCIP_Real newbound;
4544 
4545  assert(boundtype == SCIP_BOUNDTYPE_UPPER);
4546 
4547  /* adjust relaxed upper bound w.r.t. variable type */
4548  SCIPvarAdjustUb(var, set, &relaxedbd);
4549 
4550  /* due to numericis we compare the relaxed upper bound to the one present at the particular time point and take
4551  * the better one
4552  */
4553  newbound = SCIPbdchginfoGetNewbound(bdchginfo);
4554  relaxedbd = MAX(relaxedbd, newbound);
4555 
4556  /* check if relaxed upper bound is greater or equal to global upper bound; if so we can ignore the conflicting
4557  * bound
4558  */
4559  if( SCIPsetIsGE(set, relaxedbd, SCIPvarGetUbGlobal(var)) )
4560  return SCIP_OKAY;
4561 
4562  while( nbdchgs > 0 )
4563  {
4564  assert(SCIPsetIsGE(set, relaxedbd, SCIPbdchginfoGetNewbound(bdchginfo)));
4565 
4566  /* check if the old upper bound is smaller than or equal to the relaxed upper bound; if not we found the
4567  * bound change info which we need to report
4568  */
4569  if( SCIPsetIsLT(set, relaxedbd, SCIPbdchginfoGetOldbound(bdchginfo)) )
4570  break;
4571 
4572  bdchginfo = SCIPvarGetBdchgInfoUb(var, nbdchgs-1);
4573 
4574  SCIPsetDebugMsg(set, "upper bound change %d oldbd=%.15g, newbd=%.15g, depth=%d, pos=%d, redundant=%u\n",
4575  nbdchgs, SCIPbdchginfoGetOldbound(bdchginfo), SCIPbdchginfoGetNewbound(bdchginfo),
4576  SCIPbdchginfoGetDepth(bdchginfo), SCIPbdchginfoGetPos(bdchginfo),
4577  SCIPbdchginfoIsRedundant(bdchginfo));
4578 
4579  /* if bound change is redundant (this means it now a global bound), we can ignore the conflicting bound */
4580  if( SCIPbdchginfoIsRedundant(bdchginfo) )
4581  return SCIP_OKAY;
4582 
4583  nbdchgs--;
4584  }
4585  assert(SCIPsetIsLT(set, relaxedbd, SCIPbdchginfoGetOldbound(bdchginfo)));
4586  }
4587 
4588  assert(SCIPbdchgidxIsEarlier(SCIPbdchginfoGetIdx(bdchginfo), bdchgidx));
4589 
4590  /* put bound change information into priority queue */
4591  SCIP_CALL( conflictAddBound(conflict, blkmem, set, stat, var, boundtype, bdchginfo, relaxedbd) );
4592 
4593  return SCIP_OKAY;
4594 }
4595 
4596 /** checks if the given variable is already part of the current conflict set or queued for resolving with the same or
4597  * even stronger bound
4598  */
4600  SCIP_CONFLICT* conflict, /**< conflict analysis data */
4601  SCIP_VAR* var, /**< problem variable */
4602  SCIP_SET* set, /**< global SCIP settings */
4603  SCIP_BOUNDTYPE boundtype, /**< type of bound for which the score should be increased */
4604  SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
4605  SCIP_Bool* used /**< pointer to store if the variable is already used */
4606  )
4607 {
4608  SCIP_Real newbound;
4609 
4610  /* convert bound to active problem variable */
4611  SCIP_CALL( convertToActiveVar(&var, set, &boundtype, NULL) );
4612 
4614  *used = FALSE;
4615  else
4616  {
4617  assert(SCIPvarIsActive(var));
4618  assert(var != NULL);
4619 
4620  switch( boundtype )
4621  {
4622  case SCIP_BOUNDTYPE_LOWER:
4623 
4624  newbound = SCIPgetVarLbAtIndex(set->scip, var, bdchgidx, FALSE);
4625 
4626  if( var->conflictlbcount == conflict->count && var->conflictlb >= newbound )
4627  {
4628  SCIPsetDebugMsg(set, "already queued bound change <%s> >= %g\n", SCIPvarGetName(var), newbound);
4629  *used = TRUE;
4630  }
4631  else
4632  *used = FALSE;
4633  break;
4634  case SCIP_BOUNDTYPE_UPPER:
4635 
4636  newbound = SCIPgetVarUbAtIndex(set->scip, var, bdchgidx, FALSE);
4637 
4638  if( var->conflictubcount == conflict->count && var->conflictub <= newbound )
4639  {
4640  SCIPsetDebugMsg(set, "already queued bound change <%s> <= %g\n", SCIPvarGetName(var), newbound);
4641  *used = TRUE;
4642  }
4643  else
4644  *used = FALSE;
4645  break;
4646  default:
4647  SCIPerrorMessage("invalid bound type %d\n", boundtype);
4648  SCIPABORT();
4649  *used = FALSE; /*lint !e527*/
4650  }
4651  }
4652 
4653  return SCIP_OKAY;
4654 }
4655 
4656 /** returns the conflict lower bound if the variable is present in the current conflict set; otherwise the global lower
4657  * bound
4658  */
4660  SCIP_CONFLICT* conflict, /**< conflict analysis data */
4661  SCIP_VAR* var /**< problem variable */
4662  )
4663 {
4664  if( var->conflictlbcount == conflict->count )
4665  {
4666  assert(EPSGE(var->conflictlb, var->conflictrelaxedlb, 1e-09));
4667  return var->conflictrelaxedlb;
4668  }
4669 
4670  return SCIPvarGetLbGlobal(var);
4671 }
4672 
4673 /** returns the conflict upper bound if the variable is present in the current conflict set; otherwise the global upper
4674  * bound
4675  */
4677  SCIP_CONFLICT* conflict, /**< conflict analysis data */
4678  SCIP_VAR* var /**< problem variable */
4679  )
4680 {
4681  if( var->conflictubcount == conflict->count )
4682  {
4683  assert(EPSLE(var->conflictub, var->conflictrelaxedub, 1e-09));
4684  return var->conflictrelaxedub;
4685  }
4686 
4687  return SCIPvarGetUbGlobal(var);
4688 }
4689 
4690 /** removes and returns next conflict analysis candidate from the candidate queue */
4691 static
4693  SCIP_CONFLICT* conflict /**< conflict analysis data */
4694  )
4695 {
4696  SCIP_BDCHGINFO* bdchginfo;
4697  SCIP_VAR* var;
4698 
4699  assert(conflict != NULL);
4700 
4701  if( SCIPpqueueNElems(conflict->forcedbdchgqueue) > 0 )
4702  bdchginfo = (SCIP_BDCHGINFO*)(SCIPpqueueRemove(conflict->forcedbdchgqueue));
4703  else
4704  bdchginfo = (SCIP_BDCHGINFO*)(SCIPpqueueRemove(conflict->bdchgqueue));
4705 
4706  assert(!SCIPbdchginfoIsRedundant(bdchginfo));
4707 
4708  /* if we have a candidate this one should be valid for the current conflict analysis */
4709  assert(!bdchginfoIsInvalid(conflict, bdchginfo));
4710 
4711  /* mark the bound change to be no longer in the conflict (it will be either added again to the conflict set or
4712  * replaced by resolving, which might add a weaker change on the same bound to the queue)
4713  */
4714  var = SCIPbdchginfoGetVar(bdchginfo);
4716  {
4717  var->conflictlbcount = 0;
4719  }
4720  else
4721  {
4722  assert(SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_UPPER);
4723  var->conflictubcount = 0;
4725  }
4726 
4727 #ifdef SCIP_CONFGRAPH
4728  confgraphSetCurrentBdchg(bdchginfo);
4729 #endif
4730 
4731  return bdchginfo;
4732 }
4733 
4734 /** returns next conflict analysis candidate from the candidate queue without removing it */
4735 static
4737  SCIP_CONFLICT* conflict /**< conflict analysis data */
4738  )
4739 {
4740  SCIP_BDCHGINFO* bdchginfo;
4741 
4742  assert(conflict != NULL);
4743 
4744  if( SCIPpqueueNElems(conflict->forcedbdchgqueue) > 0 )
4745  {
4746  /* get next potetioal candidate */
4747  bdchginfo = (SCIP_BDCHGINFO*)(SCIPpqueueFirst(conflict->forcedbdchgqueue));
4748 
4749  /* check if this candidate is valid */
4750  if( bdchginfoIsInvalid(conflict, bdchginfo) )
4751  {
4752  SCIPdebugMessage("bound change info [%d:<%s> %s %g] is invaild -> pop it from the force queue\n", SCIPbdchginfoGetDepth(bdchginfo),
4753  SCIPvarGetName(SCIPbdchginfoGetVar(bdchginfo)),
4754  SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
4755  SCIPbdchginfoGetNewbound(bdchginfo));
4756 
4757  /* pop the invalid bound change info from the queue */
4758  (void)(SCIPpqueueRemove(conflict->forcedbdchgqueue));
4759 
4760  /* call method recursively to get next conflict analysis candidate */
4761  bdchginfo = conflictFirstCand(conflict);
4762  }
4763  }
4764  else
4765  {
4766  bdchginfo = (SCIP_BDCHGINFO*)(SCIPpqueueFirst(conflict->bdchgqueue));
4767 
4768  /* check if this candidate is valid */
4769  if( bdchginfo != NULL && bdchginfoIsInvalid(conflict, bdchginfo) )
4770  {
4771  SCIPdebugMessage("bound change info [%d:<%s> %s %g] is invaild -> pop it from the queue\n", SCIPbdchginfoGetDepth(bdchginfo),
4772  SCIPvarGetName(SCIPbdchginfoGetVar(bdchginfo)),
4773  SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
4774  SCIPbdchginfoGetNewbound(bdchginfo));
4775 
4776  /* pop the invalid bound change info from the queue */
4777  (void)(SCIPpqueueRemove(conflict->bdchgqueue));
4778 
4779  /* call method recursively to get next conflict analysis candidate */
4780  bdchginfo = conflictFirstCand(conflict);
4781  }
4782  }
4783  assert(bdchginfo == NULL || !SCIPbdchginfoIsRedundant(bdchginfo));
4784 
4785  return bdchginfo;
4786 }
4787 
4788 /** adds the current conflict set (extended by all remaining bound changes in the queue) to the pool of conflict sets */
4789 static
4791  SCIP_CONFLICT* conflict, /**< conflict analysis data */
4792  BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
4793  SCIP_SET* set, /**< global SCIP settings */
4794  SCIP_STAT* stat, /**< dynamic problem statistics */
4795  SCIP_TREE* tree, /**< branch and bound tree */
4796  int validdepth, /**< minimal depth level at which the conflict set is valid */
4797  SCIP_Bool diving, /**< are we in strong branching or diving mode? */
4798  SCIP_Bool repropagate, /**< should the constraint trigger a repropagation? */
4799  SCIP_Bool* success, /**< pointer to store whether the conflict set is valid */
4800  int* nliterals /**< pointer to store the number of literals in the generated conflictset */
4801  )
4802 {
4803  SCIP_CONFLICTSET* conflictset;
4804  SCIP_BDCHGINFO** bdchginfos;
4805  int nbdchginfos;
4806  int currentdepth;
4807  int focusdepth;
4808 
4809  assert(conflict != NULL);
4810  assert(conflict->conflictset != NULL);
4811  assert(set != NULL);
4812  assert(stat != NULL);
4813  assert(tree != NULL);
4814  assert(success != NULL);
4815  assert(nliterals != NULL);
4816  assert(SCIPpqueueNElems(conflict->forcedbdchgqueue) == 0);
4817 
4818  *success = FALSE;
4819  *nliterals = 0;
4820 
4821  /* check, whether local conflicts are allowed */
4822  validdepth = MAX(validdepth, conflict->conflictset->validdepth);
4823  if( !set->conf_allowlocal && validdepth > 0 )
4824  return SCIP_OKAY;
4825 
4826  focusdepth = SCIPtreeGetFocusDepth(tree);
4827  currentdepth = SCIPtreeGetCurrentDepth(tree);
4828  assert(currentdepth == tree->pathlen-1);
4829  assert(focusdepth <= currentdepth);
4830  assert(0 <= conflict->conflictset->validdepth && conflict->conflictset->validdepth <= currentdepth);
4831  assert(0 <= validdepth && validdepth <= currentdepth);
4832 
4833  /* get the elements of the bound change queue */
4834  bdchginfos = (SCIP_BDCHGINFO**)SCIPpqueueElems(conflict->bdchgqueue);
4835  nbdchginfos = SCIPpqueueNElems(conflict->bdchgqueue);
4836 
4837  /* create a copy of the current conflict set, allocating memory for the additional elements of the queue */
4838  SCIP_CALL( conflictsetCopy(&conflictset, blkmem, conflict->conflictset, nbdchginfos) );
4839  conflictset->validdepth = validdepth;
4840  conflictset->repropagate = repropagate;
4841 
4842  /* add the valid queue elements to the conflict set */
4843  SCIPsetDebugMsg(set, "adding %d variables from the queue as temporary conflict variables\n", nbdchginfos);
4844  SCIP_CALL( conflictsetAddBounds(conflict, conflictset, blkmem, set, bdchginfos, nbdchginfos) );
4845 
4846  /* calculate the depth, at which the conflictset should be inserted */
4847  SCIP_CALL( conflictsetCalcInsertDepth(conflictset, set, tree) );
4848  assert(conflictset->validdepth <= conflictset->insertdepth && conflictset->insertdepth <= currentdepth);
4849  SCIPsetDebugMsg(set, " -> conflict with %d literals found at depth %d is active in depth %d and valid in depth %d\n",
4850  conflictset->nbdchginfos, currentdepth, conflictset->insertdepth, conflictset->validdepth);
4851 
4852  /* if all branching variables are in the conflict set, the conflict set is of no use;
4853  * don't use conflict sets that are only valid in the probing path but not in the problem tree
4854  */
4855  if( (diving || conflictset->insertdepth < currentdepth) && conflictset->insertdepth <= focusdepth )
4856  {
4857  /* if the conflict should not be located only in the subtree where it is useful, put it to its valid depth level */
4858  if( !set->conf_settlelocal )
4859  conflictset->insertdepth = conflictset->validdepth;
4860 
4861  *nliterals = conflictset->nbdchginfos;
4862  SCIPsetDebugMsg(set, " -> final conflict set has %d literals\n", *nliterals);
4863 
4864  /* check conflict set on debugging solution */
4865  SCIP_CALL( SCIPdebugCheckConflict(blkmem, set, tree->path[validdepth], \
4866  conflictset->bdchginfos, conflictset->relaxedbds, conflictset->nbdchginfos) ); /*lint !e506 !e774*/
4867 
4868  /* move conflictset to the conflictset storage */
4869  SCIP_CALL( conflictInsertConflictset(conflict, blkmem, set, &conflictset) );
4870  *success = TRUE;
4871  }
4872  else
4873  {
4874  /* free the temporary conflict set */
4875  conflictsetFree(&conflictset, blkmem);
4876  }
4877 
4878  return SCIP_OKAY;
4879 }
4880 
4881 /** tries to resolve given bound change
4882  * - resolutions on local constraints are only applied, if the constraint is valid at the
4883  * current minimal valid depth level, because this depth level is the topmost level to add the conflict
4884  * constraint to anyways
4885  *
4886  * @note it is sufficient to explain the relaxed bound change
4887  */
4888 static
4890  SCIP_CONFLICT* conflict, /**< conflict analysis data */
4891  SCIP_SET* set, /**< global SCIP settings */
4892  SCIP_BDCHGINFO* bdchginfo, /**< bound change to resolve */
4893  SCIP_Real relaxedbd, /**< the relaxed bound */
4894  int validdepth, /**< minimal depth level at which the conflict is valid */
4895  SCIP_Bool* resolved /**< pointer to store whether the bound change was resolved */
4896  )
4897 {
4898  SCIP_VAR* actvar;
4899  SCIP_CONS* infercons;
4900  SCIP_PROP* inferprop;
4901  SCIP_RESULT result;
4902 
4903 #ifndef NDEBUG
4904  int nforcedbdchgqueue;
4905  int nbdchgqueue;
4906 
4907  /* store the current size of the conflict queues */
4908  assert(conflict != NULL);
4909  nforcedbdchgqueue = SCIPpqueueNElems(conflict->forcedbdchgqueue);
4910  nbdchgqueue = SCIPpqueueNElems(conflict->bdchgqueue);
4911 #else
4912  assert(conflict != NULL);
4913 #endif
4914 
4915  assert(resolved != NULL);
4916  assert(!SCIPbdchginfoIsRedundant(bdchginfo));
4917 
4918  *resolved = FALSE;
4919 
4920  actvar = SCIPbdchginfoGetVar(bdchginfo);
4921  assert(actvar != NULL);
4922  assert(SCIPvarIsActive(actvar));
4923 
4924 #ifdef SCIP_DEBUG
4925  {
4926  int i;
4927  SCIPsetDebugMsg(set, "processing next conflicting bound (depth: %d, valid depth: %d, bdchgtype: %s [%s], vartype: %d): [<%s> %s %g(%g)]\n",
4928  SCIPbdchginfoGetDepth(bdchginfo), validdepth,
4929  SCIPbdchginfoGetChgtype(bdchginfo) == SCIP_BOUNDCHGTYPE_BRANCHING ? "branch"
4930  : SCIPbdchginfoGetChgtype(bdchginfo) == SCIP_BOUNDCHGTYPE_CONSINFER ? "cons" : "prop",
4934  : SCIPbdchginfoGetInferProp(bdchginfo) == NULL ? "-"
4936  SCIPvarGetType(actvar), SCIPvarGetName(actvar),
4937  SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
4938  SCIPbdchginfoGetNewbound(bdchginfo), relaxedbd);
4939  SCIPsetDebugMsg(set, " - conflict set :");
4940 
4941  for( i = 0; i < conflict->conflictset->nbdchginfos; ++i )
4942  {
4943  SCIPsetDebugMsgPrint(set, " [%d:<%s> %s %g(%g)]", SCIPbdchginfoGetDepth(conflict->conflictset->bdchginfos[i]),
4945  SCIPbdchginfoGetBoundtype(conflict->conflictset->bdchginfos[i]) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
4946  SCIPbdchginfoGetNewbound(conflict->conflictset->bdchginfos[i]), conflict->conflictset->relaxedbds[i]);
4947  }
4948  SCIPsetDebugMsgPrint(set, "\n");
4949  SCIPsetDebugMsg(set, " - forced candidates :");
4950 
4951  for( i = 0; i < SCIPpqueueNElems(conflict->forcedbdchgqueue); ++i )
4952  {
4954  SCIPsetDebugMsgPrint(set, " [%d:<%s> %s %g(%g)]", SCIPbdchginfoGetDepth(info), SCIPvarGetName(SCIPbdchginfoGetVar(info)),
4955  bdchginfoIsInvalid(conflict, info) ? "<!>" : SCIPbdchginfoGetBoundtype(info) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
4957  }
4958  SCIPsetDebugMsgPrint(set, "\n");
4959  SCIPsetDebugMsg(set, " - optional candidates:");
4960 
4961  for( i = 0; i < SCIPpqueueNElems(conflict->bdchgqueue); ++i )
4962  {
4963  SCIP_BDCHGINFO* info = (SCIP_BDCHGINFO*)(SCIPpqueueElems(conflict->bdchgqueue)[i]);
4964  SCIPsetDebugMsgPrint(set, " [%d:<%s> %s %g(%g)]", SCIPbdchginfoGetDepth(info), SCIPvarGetName(SCIPbdchginfoGetVar(info)),
4965  bdchginfoIsInvalid(conflict, info) ? "<!>" : SCIPbdchginfoGetBoundtype(info) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
4967  }
4968  SCIPsetDebugMsgPrint(set, "\n");
4969  }
4970 #endif
4971 
4972  /* check, if the bound change can and should be resolved:
4973  * - resolutions on local constraints should only be applied, if the constraint is valid at the
4974  * current minimal valid depth level (which is initialized with the valid depth level of the initial
4975  * conflict set), because this depth level is the topmost level to add the conflict constraint to anyways
4976  */
4977  switch( SCIPbdchginfoGetChgtype(bdchginfo) )
4978  {
4980  infercons = SCIPbdchginfoGetInferCons(bdchginfo);
4981  assert(infercons != NULL);
4982 
4983  if( SCIPconsIsGlobal(infercons) || SCIPconsGetValidDepth(infercons) <= validdepth )
4984  {
4985  SCIP_VAR* infervar;
4986  int inferinfo;
4987  SCIP_BOUNDTYPE inferboundtype;
4988  SCIP_BDCHGIDX* bdchgidx;
4989 
4990  /* resolve bound change by asking the constraint that infered the bound to put all bounds that were
4991  * the reasons for the conflicting bound change on the priority queue
4992  */
4993  infervar = SCIPbdchginfoGetInferVar(bdchginfo);
4994  inferinfo = SCIPbdchginfoGetInferInfo(bdchginfo);
4995  inferboundtype = SCIPbdchginfoGetInferBoundtype(bdchginfo);
4996  bdchgidx = SCIPbdchginfoGetIdx(bdchginfo);
4997  assert(infervar != NULL);
4998 
4999  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",
5000  SCIPvarGetName(actvar),
5001  SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
5002  SCIPbdchginfoGetNewbound(bdchginfo), relaxedbd,
5003  SCIPvarGetStatus(actvar), SCIPvarGetType(actvar),
5004  SCIPbdchginfoGetDepth(bdchginfo), SCIPbdchginfoGetPos(bdchginfo),
5005  SCIPvarGetName(infervar),
5006  inferboundtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
5007  SCIPgetVarBdAtIndex(set->scip, infervar, inferboundtype, bdchgidx, TRUE),
5008  SCIPconsGetName(infercons),
5009  SCIPconsIsGlobal(infercons) ? "global" : "local",
5010  inferinfo);
5011 
5012  /* in case the inference variables is not an active variables, we need to transform the relaxed bound */
5013  if( actvar != infervar )
5014  {
5015  SCIP_VAR* var;
5016  SCIP_Real scalar;
5017  SCIP_Real constant;
5018 
5019  assert(SCIPvarGetStatus(infervar) == SCIP_VARSTATUS_AGGREGATED
5021  || (SCIPvarGetStatus(infervar) == SCIP_VARSTATUS_MULTAGGR && SCIPvarGetMultaggrNVars(infervar) == 1));
5022 
5023  scalar = 1.0;
5024  constant = 0.0;
5025 
5026  var = infervar;
5027 
5028  /* transform given varibale to active varibale */
5029  SCIP_CALL( SCIPvarGetProbvarSum(&var, set, &scalar, &constant) );
5030  assert(var == actvar);
5031 
5032  relaxedbd *= scalar;
5033  relaxedbd += constant;
5034  }
5035 
5036  SCIP_CALL( SCIPconsResolvePropagation(infercons, set, infervar, inferinfo, inferboundtype, bdchgidx, relaxedbd, &result) );
5037  *resolved = (result == SCIP_SUCCESS);
5038  }
5039  break;
5040 
5042  inferprop = SCIPbdchginfoGetInferProp(bdchginfo);
5043  if( inferprop != NULL )
5044  {
5045  SCIP_VAR* infervar;
5046  int inferinfo;
5047  SCIP_BOUNDTYPE inferboundtype;
5048  SCIP_BDCHGIDX* bdchgidx;
5049 
5050  /* resolve bound change by asking the propagator that infered the bound to put all bounds that were
5051  * the reasons for the conflicting bound change on the priority queue
5052  */
5053  infervar = SCIPbdchginfoGetInferVar(bdchginfo);
5054  inferinfo = SCIPbdchginfoGetInferInfo(bdchginfo);
5055  inferboundtype = SCIPbdchginfoGetInferBoundtype(bdchginfo);
5056  bdchgidx = SCIPbdchginfoGetIdx(bdchginfo);
5057  assert(infervar != NULL);
5058 
5059  SCIPsetDebugMsg(set, "resolving bound <%s> %s %g(%g) [status:%d, depth:%d, pos:%d]: <%s> %s %g [prop:<%s>, info:%d]\n",
5060  SCIPvarGetName(actvar),
5061  SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
5062  SCIPbdchginfoGetNewbound(bdchginfo), relaxedbd,
5063  SCIPvarGetStatus(actvar), SCIPbdchginfoGetDepth(bdchginfo), SCIPbdchginfoGetPos(bdchginfo),
5064  SCIPvarGetName(infervar),
5065  inferboundtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
5066  SCIPgetVarBdAtIndex(set->scip, infervar, inferboundtype, bdchgidx, TRUE),
5067  SCIPpropGetName(inferprop), inferinfo);
5068 
5069  SCIP_CALL( SCIPpropResolvePropagation(inferprop, set, infervar, inferinfo, inferboundtype, bdchgidx, relaxedbd, &result) );
5070  *resolved = (result == SCIP_SUCCESS);
5071  }
5072  break;
5073 
5075  assert(!(*resolved));
5076  break;
5077 
5078  default:
5079  SCIPerrorMessage("invalid bound change type <%d>\n", SCIPbdchginfoGetChgtype(bdchginfo));
5080  return SCIP_INVALIDDATA;
5081  }
5082 
5083  SCIPsetDebugMsg(set, "resolving status: %u\n", *resolved);
5084 
5085 #ifndef NDEBUG
5086  /* subtract the size of the conflicq queues */
5087  nforcedbdchgqueue -= SCIPpqueueNElems(conflict->forcedbdchgqueue);
5088  nbdchgqueue -= SCIPpqueueNElems(conflict->bdchgqueue);
5089 
5090  /* in case the bound change was not resolved, the conflict queues should have the same size (contents) */
5091  assert((*resolved) || (nforcedbdchgqueue == 0 && nbdchgqueue == 0));
5092 #endif
5093 
5094  return SCIP_OKAY;
5095 }
5096 
5097 /** if only one conflicting bound change of the last depth level was used, and if this can be resolved,
5098  * creates GRASP-like reconvergence conflict constraints in the conflict graph up to the branching variable of this
5099  * depth level
5100  */
5101 static
5103  SCIP_CONFLICT* conflict, /**< conflict analysis data */
5104  BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
5105  SCIP_SET* set, /**< global SCIP settings */
5106  SCIP_STAT* stat, /**< problem statistics */
5107  SCIP_PROB* prob, /**< problem data */
5108  SCIP_TREE* tree, /**< branch and bound tree */
5109  SCIP_Bool diving, /**< are we in strong branching or diving mode? */
5110  int validdepth, /**< minimal depth level at which the initial conflict set is valid */
5111  SCIP_BDCHGINFO* firstuip, /**< first UIP of conflict graph */
5112  int* nreconvconss, /**< pointer to store the number of generated reconvergence constraints */
5113  int* nreconvliterals /**< pointer to store the number of literals generated reconvergence constraints */
5114  )
5115 {
5116  SCIP_BDCHGINFO* uip;
5117  SCIP_CONFTYPE conftype;
5118  SCIP_Bool usescutoffbound;
5119  int firstuipdepth;
5120  int focusdepth;
5121  int currentdepth;
5122  int maxvaliddepth;
5123 
5124  assert(conflict != NULL);
5125  assert(firstuip != NULL);
5126  assert(nreconvconss != NULL);
5127  assert(nreconvliterals != NULL);
5128  assert(!SCIPbdchginfoIsRedundant(firstuip));
5129 
5130  focusdepth = SCIPtreeGetFocusDepth(tree);
5131  currentdepth = SCIPtreeGetCurrentDepth(tree);
5132  assert(currentdepth == tree->pathlen-1);
5133  assert(focusdepth <= currentdepth);
5134 
5135  /* check, whether local constraints are allowed; however, don't generate reconvergence constraints that are only valid
5136  * in the probing path and not in the problem tree (i.e. that exceed the focusdepth)
5137  */
5138  maxvaliddepth = (set->conf_allowlocal ? MIN(currentdepth-1, focusdepth) : 0);
5139  if( validdepth > maxvaliddepth )
5140  return SCIP_OKAY;
5141 
5142  firstuipdepth = SCIPbdchginfoGetDepth(firstuip);
5143 
5144  conftype = conflict->conflictset->conflicttype;
5145  usescutoffbound = conflict->conflictset->usescutoffbound;
5146 
5147  /* for each succeeding UIP pair of the last depth level, create one reconvergence constraint */
5148  uip = firstuip;
5149  while( uip != NULL && SCIPbdchginfoGetDepth(uip) == SCIPbdchginfoGetDepth(firstuip) && bdchginfoIsResolvable(uip) )
5150  {
5151  SCIP_BDCHGINFO* oppositeuip;
5152  SCIP_BDCHGINFO* bdchginfo;
5153  SCIP_BDCHGINFO* nextuip;
5154  SCIP_VAR* uipvar;
5155  SCIP_Real oppositeuipbound;
5156  SCIP_BOUNDTYPE oppositeuipboundtype;
5157  int nresolutions;
5158 
5159  assert(!SCIPbdchginfoIsRedundant(uip));
5160 
5161  SCIPsetDebugMsg(set, "creating reconvergence constraint for UIP <%s> %s %g in depth %d pos %d\n",
5164 
5165  /* initialize conflict data */
5166  SCIP_CALL( SCIPconflictInit(conflict, set, stat, prob, conftype, usescutoffbound) );
5167 
5168  conflict->conflictset->conflicttype = conftype;
5169  conflict->conflictset->usescutoffbound = usescutoffbound;
5170 
5171  /* create a temporary bound change information for the negation of the UIP's bound change;
5172  * this bound change information is freed in the SCIPconflictFlushConss() call;
5173  * for reconvergence constraints for continuous variables we can only use the "negation" !(x <= u) == (x >= u);
5174  * during conflict analysis, we treat a continuous bound "x >= u" in the conflict set as "x > u", and in the
5175  * generated constraint this is negated again to "x <= u" which is correct.
5176  */
5177  uipvar = SCIPbdchginfoGetVar(uip);
5178  oppositeuipboundtype = SCIPboundtypeOpposite(SCIPbdchginfoGetBoundtype(uip));
5179  oppositeuipbound = SCIPbdchginfoGetNewbound(uip);
5180  if( SCIPvarIsIntegral(uipvar) )
5181  {
5182  assert(SCIPsetIsIntegral(set, oppositeuipbound));
5183  oppositeuipbound += (oppositeuipboundtype == SCIP_BOUNDTYPE_LOWER ? +1.0 : -1.0);
5184  }
5185  SCIP_CALL( conflictCreateTmpBdchginfo(conflict, blkmem, set, uipvar, oppositeuipboundtype, \
5186  oppositeuipboundtype == SCIP_BOUNDTYPE_LOWER ? SCIP_REAL_MIN : SCIP_REAL_MAX, oppositeuipbound, &oppositeuip) );
5187 
5188  /* put the negated UIP into the conflict set */
5189  SCIP_CALL( conflictAddConflictBound(conflict, blkmem, set, oppositeuip, oppositeuipbound) );
5190 
5191  /* put positive UIP into priority queue */
5192  SCIP_CALL( conflictQueueBound(conflict, set, uip, SCIPbdchginfoGetNewbound(uip) ) );
5193 
5194  /* resolve the queue until the next UIP is reached */
5195  bdchginfo = conflictFirstCand(conflict);
5196  nextuip = NULL;
5197  nresolutions = 0;
5198  while( bdchginfo != NULL && validdepth <= maxvaliddepth )
5199  {
5200  SCIP_BDCHGINFO* nextbdchginfo;
5201  SCIP_Real relaxedbd;
5202  SCIP_Bool forceresolve;
5203  int bdchgdepth;
5204 
5205  /* check if the next bound change must be resolved in every case */
5206  forceresolve = (SCIPpqueueNElems(conflict->forcedbdchgqueue) > 0);
5207 
5208  /* remove currently processed candidate and get next conflicting bound from the conflict candidate queue before
5209  * we remove the candidate we have to collect the relaxed bound since removing the candidate from the queue
5210  * invalidates the relaxed bound
5211  */
5212  assert(bdchginfo == conflictFirstCand(conflict));
5213  relaxedbd = SCIPbdchginfoGetRelaxedBound(bdchginfo);
5214  bdchginfo = conflictRemoveCand(conflict);
5215  nextbdchginfo = conflictFirstCand(conflict);
5216  bdchgdepth = SCIPbdchginfoGetDepth(bdchginfo);
5217  assert(bdchginfo != NULL);
5218  assert(!SCIPbdchginfoIsRedundant(bdchginfo));
5219  assert(nextbdchginfo == NULL || SCIPbdchginfoGetDepth(bdchginfo) >= SCIPbdchginfoGetDepth(nextbdchginfo)
5220  || forceresolve);
5221  assert(bdchgdepth <= firstuipdepth);
5222 
5223  /* bound changes that are higher in the tree than the valid depth of the conflict can be ignored;
5224  * multiple insertions of the same bound change can be ignored
5225  */
5226  if( bdchgdepth > validdepth && bdchginfo != nextbdchginfo )
5227  {
5228  SCIP_VAR* actvar;
5229  SCIP_Bool resolved;
5230 
5231  actvar = SCIPbdchginfoGetVar(bdchginfo);
5232  assert(actvar != NULL);
5233  assert(SCIPvarIsActive(actvar));
5234 
5235  /* check if we have to resolve the bound change in this depth level
5236  * - the starting uip has to be resolved
5237  * - a bound change should be resolved, if it is in the fuip's depth level and not the
5238  * next uip (i.e., if it is not the last bound change in the fuip's depth level)
5239  * - a forced bound change must be resolved in any case
5240  */
5241  resolved = FALSE;
5242  if( bdchginfo == uip
5243  || (bdchgdepth == firstuipdepth
5244  && nextbdchginfo != NULL
5245  && SCIPbdchginfoGetDepth(nextbdchginfo) == bdchgdepth)
5246  || forceresolve )
5247  {
5248  SCIP_CALL( conflictResolveBound(conflict, set, bdchginfo, relaxedbd, validdepth, &resolved) );
5249  }
5250 
5251  if( resolved )
5252  nresolutions++;
5253  else if( forceresolve )
5254  {
5255  /* variable cannot enter the conflict clause: we have to make the conflict clause local, s.t.
5256  * the unresolved bound change is active in the whole sub tree of the conflict clause
5257  */
5258  assert(bdchgdepth >= validdepth);
5259  validdepth = bdchgdepth;
5260 
5261  SCIPsetDebugMsg(set, "couldn't resolve forced bound change on <%s> -> new valid depth: %d\n",
5262  SCIPvarGetName(actvar), validdepth);
5263  }
5264  else if( bdchginfo != uip )
5265  {
5266  assert(conflict->conflictset != NULL);
5267  assert(conflict->conflictset->nbdchginfos >= 1); /* starting UIP is already member of the conflict set */
5268 
5269  /* if this is the first variable of the conflict set besides the current starting UIP, it is the next
5270  * UIP (or the first unresolvable bound change)
5271  */
5272  if( bdchgdepth == firstuipdepth && conflict->conflictset->nbdchginfos == 1 )
5273  {
5274  assert(nextuip == NULL);
5275  nextuip = bdchginfo;
5276  }
5277 
5278  /* put bound change into the conflict set */
5279  SCIP_CALL( conflictAddConflictBound(conflict, blkmem, set, bdchginfo, relaxedbd) );
5280  assert(conflict->conflictset->nbdchginfos >= 2);
5281  }
5282  else
5283  assert(conflictFirstCand(conflict) == NULL); /* the starting UIP was not resolved */
5284  }
5285 
5286  /* get next conflicting bound from the conflict candidate queue (this does not need to be nextbdchginfo, because
5287  * due to resolving the bound changes, a variable could be added to the queue which must be
5288  * resolved before nextbdchginfo)
5289  */
5290  bdchginfo = conflictFirstCand(conflict);
5291  }
5292  assert(nextuip != uip);
5293 
5294  /* if only one propagation was resolved, the reconvergence constraint is already member of the constraint set
5295  * (it is exactly the constraint that produced the propagation)
5296  */
5297  if( nextuip != NULL && nresolutions >= 2 && bdchginfo == NULL && validdepth <= maxvaliddepth )
5298  {
5299  int nlits;
5300  SCIP_Bool success;
5301 
5302  assert(SCIPbdchginfoGetDepth(nextuip) == SCIPbdchginfoGetDepth(uip));
5303 
5304  /* check conflict graph frontier on debugging solution */
5305  SCIP_CALL( SCIPdebugCheckConflictFrontier(blkmem, set, tree->path[validdepth], \
5306  bdchginfo, conflict->conflictset->bdchginfos, conflict->conflictset->relaxedbds, \
5307  conflict->conflictset->nbdchginfos, conflict->bdchgqueue, conflict->forcedbdchgqueue) ); /*lint !e506 !e774*/
5308 
5309  SCIPsetDebugMsg(set, "creating reconvergence constraint from UIP <%s> to UIP <%s> in depth %d with %d literals after %d resolutions\n",
5311  SCIPbdchginfoGetDepth(uip), conflict->conflictset->nbdchginfos, nresolutions);
5312 
5313  /* call the conflict handlers to create a conflict set */
5314  SCIP_CALL( conflictAddConflictset(conflict, blkmem, set, stat, tree, validdepth, diving, FALSE, &success, &nlits) );
5315  if( success )
5316  {
5317  (*nreconvconss)++;
5318  (*nreconvliterals) += nlits;
5319  }
5320  }
5321 
5322  /* clear the conflict candidate queue and the conflict set (to make sure, oppositeuip is not referenced anymore) */
5323  conflictClear(conflict);
5324 
5325  uip = nextuip;
5326  }
5327 
5328  conflict->conflictset->conflicttype = conftype;
5329  conflict->conflictset->usescutoffbound = usescutoffbound;
5330 
5331  return SCIP_OKAY;
5332 }
5333 
5334 /** analyzes conflicting bound changes that were added with calls to SCIPconflictAddBound() and
5335  * SCIPconflictAddRelaxedBound(), and on success, calls the conflict handlers to create a conflict constraint out of
5336  * the resulting conflict set; afterwards the conflict queue and the conflict set is cleared
5337  */
5338 static
5340  SCIP_CONFLICT* conflict, /**< conflict analysis data */
5341  BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
5342  SCIP_SET* set, /**< global SCIP settings */
5343  SCIP_STAT* stat, /**< problem statistics */
5344  SCIP_PROB* prob, /**< problem data */
5345  SCIP_TREE* tree, /**< branch and bound tree */
5346  SCIP_Bool diving, /**< are we in strong branching or diving mode? */
5347  int validdepth, /**< minimal depth level at which the initial conflict set is valid */
5348  SCIP_Bool mustresolve, /**< should the conflict set only be used, if a resolution was applied? */
5349  int* nconss, /**< pointer to store the number of generated conflict constraints */
5350  int* nliterals, /**< pointer to store the number of literals in generated conflict constraints */
5351  int* nreconvconss, /**< pointer to store the number of generated reconvergence constraints */
5352  int* nreconvliterals /**< pointer to store the number of literals generated reconvergence constraints */
5353  )
5354 {
5355  SCIP_BDCHGINFO* bdchginfo;
5356  SCIP_BDCHGINFO** firstuips;
5357  SCIP_CONFTYPE conftype;
5358  int nfirstuips;
5359  int focusdepth;
5360  int currentdepth;
5361  int maxvaliddepth;
5362  int resolvedepth;
5363  int nresolutions;
5364  int lastconsnresolutions;
5365  int lastconsresoldepth;
5366 
5367  assert(conflict != NULL);
5368  assert(conflict->conflictset != NULL);
5369  assert(conflict->conflictset->nbdchginfos >= 0);
5370  assert(set != NULL);
5371  assert(stat != NULL);
5372  assert(0 <= validdepth && validdepth <= SCIPtreeGetCurrentDepth(tree));
5373  assert(nconss != NULL);
5374  assert(nliterals != NULL);
5375  assert(nreconvconss != NULL);
5376  assert(nreconvliterals != NULL);
5377 
5378  focusdepth = SCIPtreeGetFocusDepth(tree);
5379  currentdepth = SCIPtreeGetCurrentDepth(tree);
5380  assert(currentdepth == tree->pathlen-1);
5381  assert(focusdepth <= currentdepth);
5382 
5383  resolvedepth = ((set->conf_fuiplevels >= 0 && set->conf_fuiplevels <= currentdepth)
5384  ? currentdepth - set->conf_fuiplevels + 1 : 0);
5385  assert(0 <= resolvedepth && resolvedepth <= currentdepth + 1);
5386 
5387  /* if we must resolve at least one bound change, find the first UIP at least in the last depth level */
5388  if( mustresolve )
5389  resolvedepth = MIN(resolvedepth, currentdepth);
5390 
5391  SCIPsetDebugMsg(set, "analyzing conflict with %d+%d conflict candidates and starting conflict set of size %d in depth %d (resolvedepth=%d)\n",
5393  conflict->conflictset->nbdchginfos, currentdepth, resolvedepth);
5394 
5395  *nconss = 0;
5396  *nliterals = 0;
5397  *nreconvconss = 0;
5398  *nreconvliterals = 0;
5399 
5400  /* check, whether local conflicts are allowed; however, don't generate conflict constraints that are only valid in the
5401  * probing path and not in the problem tree (i.e. that exceed the focusdepth)
5402  */
5403  maxvaliddepth = (set->conf_allowlocal ? MIN(currentdepth-1, focusdepth) : 0);
5404  if( validdepth > maxvaliddepth )
5405  return SCIP_OKAY;
5406 
5407  /* allocate temporary memory for storing first UIPs (in each depth level, at most two bound changes can be flagged
5408  * as UIP, namely a binary and a non-binary bound change)
5409  */
5410  SCIP_CALL( SCIPsetAllocBufferArray(set, &firstuips, 2*(currentdepth+1)) ); /*lint !e647*/
5411 
5412  /* process all bound changes in the conflict candidate queue */
5413  nresolutions = 0;
5414  lastconsnresolutions = (mustresolve ? 0 : -1);
5415  lastconsresoldepth = (mustresolve ? currentdepth : INT_MAX);
5416  bdchginfo = conflictFirstCand(conflict);
5417  nfirstuips = 0;
5418 
5419  /* check if the initial reason on debugging solution */
5420  SCIP_CALL( SCIPdebugCheckConflictFrontier(blkmem, set, tree->path[validdepth], \
5421  NULL, conflict->conflictset->bdchginfos, conflict->conflictset->relaxedbds, conflict->conflictset->nbdchginfos, \
5422  conflict->bdchgqueue, conflict->forcedbdchgqueue) ); /*lint !e506 !e774*/
5423 
5424  while( bdchginfo != NULL && validdepth <= maxvaliddepth )
5425  {
5426  SCIP_BDCHGINFO* nextbdchginfo;
5427  SCIP_Real relaxedbd;
5428  SCIP_Bool forceresolve;
5429  int bdchgdepth;
5430 
5431  assert(!SCIPbdchginfoIsRedundant(bdchginfo));
5432 
5433  /* check if the next bound change must be resolved in every case */
5434  forceresolve = (SCIPpqueueNElems(conflict->forcedbdchgqueue) > 0);
5435 
5436  /* resolve next bound change in queue */
5437  bdchgdepth = SCIPbdchginfoGetDepth(bdchginfo);
5438  assert(0 <= bdchgdepth && bdchgdepth <= currentdepth);
5439  assert(SCIPvarIsActive(SCIPbdchginfoGetVar(bdchginfo)));
5440  assert(bdchgdepth < tree->pathlen);
5441  assert(tree->path[bdchgdepth] != NULL);
5442  assert(tree->path[bdchgdepth]->domchg != NULL);
5443  assert(SCIPbdchginfoGetPos(bdchginfo) < (int)tree->path[bdchgdepth]->domchg->domchgbound.nboundchgs);
5444  assert(tree->path[bdchgdepth]->domchg->domchgbound.boundchgs[SCIPbdchginfoGetPos(bdchginfo)].var
5445  == SCIPbdchginfoGetVar(bdchginfo));
5446  assert(tree->path[bdchgdepth]->domchg->domchgbound.boundchgs[SCIPbdchginfoGetPos(bdchginfo)].newbound
5447  == SCIPbdchginfoGetNewbound(bdchginfo)
5450  == SCIPbdchginfoGetNewbound(bdchginfo)); /*lint !e777*/
5451  assert((SCIP_BOUNDTYPE)tree->path[bdchgdepth]->domchg->domchgbound.boundchgs[SCIPbdchginfoGetPos(bdchginfo)].boundtype
5452  == SCIPbdchginfoGetBoundtype(bdchginfo));
5453 
5454  /* create intermediate conflict constraint */
5455  assert(nresolutions >= lastconsnresolutions);
5456  if( !forceresolve )
5457  {
5458  if( nresolutions == lastconsnresolutions )
5459  lastconsresoldepth = bdchgdepth; /* all intermediate depth levels consisted of only unresolved bound changes */
5460  else if( bdchgdepth < lastconsresoldepth && (set->conf_interconss == -1 || *nconss < set->conf_interconss) )
5461  {
5462  int nlits;
5463  SCIP_Bool success;
5464 
5465  /* call the conflict handlers to create a conflict set */
5466  SCIPsetDebugMsg(set, "creating intermediate conflictset after %d resolutions up to depth %d (valid at depth %d): %d conflict bounds, %d bounds in queue\n",
5467  nresolutions, bdchgdepth, validdepth, conflict->conflictset->nbdchginfos,
5468  SCIPpqueueNElems(conflict->bdchgqueue));
5469 
5470  SCIP_CALL( conflictAddConflictset(conflict, blkmem, set, stat, tree, validdepth, diving, TRUE, &success, &nlits) );
5471  lastconsnresolutions = nresolutions;
5472  lastconsresoldepth = bdchgdepth;
5473  if( success )
5474  {
5475  (*nconss)++;
5476  (*nliterals) += nlits;
5477  }
5478  }
5479  }
5480 
5481  /* remove currently processed candidate and get next conflicting bound from the conflict candidate queue before
5482  * we remove the candidate we have to collect the relaxed bound since removing the candidate from the queue
5483  * invalidates the relaxed bound
5484  */
5485  assert(bdchginfo == conflictFirstCand(conflict));
5486  relaxedbd = SCIPbdchginfoGetRelaxedBound(bdchginfo);
5487  bdchginfo = conflictRemoveCand(conflict);
5488  nextbdchginfo = conflictFirstCand(conflict);
5489  assert(bdchginfo != NULL);
5490  assert(!SCIPbdchginfoIsRedundant(bdchginfo));
5491  assert(nextbdchginfo == NULL || SCIPbdchginfoGetDepth(bdchginfo) >= SCIPbdchginfoGetDepth(nextbdchginfo)
5492  || forceresolve);
5493 
5494  /* we don't need to resolve bound changes that are already active in the valid depth of the current conflict set,
5495  * because the conflict set can only be added locally at the valid depth, and all bound changes applied in this
5496  * depth or earlier can be removed from the conflict constraint, since they are already applied in the constraint's
5497  * subtree;
5498  * if the next bound change on the remaining queue is equal to the current bound change,
5499  * this is a multiple insertion in the conflict candidate queue and we can ignore the current
5500  * bound change
5501  */
5502  if( bdchgdepth > validdepth && bdchginfo != nextbdchginfo )
5503  {
5504  SCIP_VAR* actvar;
5505  SCIP_Bool resolved;
5506 
5507  actvar = SCIPbdchginfoGetVar(bdchginfo);
5508  assert(actvar != NULL);
5509  assert(SCIPvarIsActive(actvar));
5510 
5511  /* check if we want to resolve the bound change in this depth level
5512  * - bound changes should be resolved, if
5513  * (i) we must apply at least one resolution and didn't resolve a bound change yet, or
5514  * (ii) their depth level is at least equal to the minimal resolving depth, and
5515  * they are not the last remaining conflicting bound change in their depth level
5516  * (iii) the bound change resolving is forced (i.e., the forced queue was non-empty)
5517  */
5518  resolved = FALSE;
5519  if( (mustresolve && nresolutions == 0)
5520  || (bdchgdepth >= resolvedepth
5521  && nextbdchginfo != NULL
5522  && SCIPbdchginfoGetDepth(nextbdchginfo) == bdchgdepth)
5523  || forceresolve )
5524  {
5525  SCIP_CALL( conflictResolveBound(conflict, set, bdchginfo, relaxedbd, validdepth, &resolved) );
5526  }
5527 
5528  if( resolved )
5529  nresolutions++;
5530  else if( forceresolve )
5531  {
5532  /* variable cannot enter the conflict clause: we have to make the conflict clause local, s.t.
5533  * the unresolved bound change is active in the whole sub tree of the conflict clause
5534  */
5535  assert(bdchgdepth >= validdepth);
5536  validdepth = bdchgdepth;
5537 
5538  SCIPsetDebugMsg(set, "couldn't resolve forced bound change on <%s> -> new valid depth: %d\n",
5539  SCIPvarGetName(actvar), validdepth);
5540  }
5541  else
5542  {
5543  /* if this is a UIP (the last bound change in its depth level), it can be used to generate a
5544  * UIP reconvergence constraint
5545  */
5546  if( nextbdchginfo == NULL || SCIPbdchginfoGetDepth(nextbdchginfo) != bdchgdepth )
5547  {
5548  assert(nfirstuips < 2*(currentdepth+1));
5549  firstuips[nfirstuips] = bdchginfo;
5550  nfirstuips++;
5551  }
5552 
5553  /* put variable into the conflict set, using the literal that is currently fixed to FALSE */
5554  SCIP_CALL( conflictAddConflictBound(conflict, blkmem, set, bdchginfo, relaxedbd) );
5555  }
5556  }
5557 
5558  /* check conflict graph frontier on debugging solution */
5559  SCIP_CALL( SCIPdebugCheckConflictFrontier(blkmem, set, tree->path[validdepth], \
5560  bdchginfo, conflict->conflictset->bdchginfos, conflict->conflictset->relaxedbds, conflict->conflictset->nbdchginfos, \
5561  conflict->bdchgqueue, conflict->forcedbdchgqueue) ); /*lint !e506 !e774*/
5562 
5563  /* get next conflicting bound from the conflict candidate queue (this needs not to be nextbdchginfo, because
5564  * due to resolving the bound changes, a bound change could be added to the queue which must be
5565  * resolved before nextbdchginfo)
5566  */
5567  bdchginfo = conflictFirstCand(conflict);
5568  }
5569 
5570  /* check, if a valid conflict set was found */
5571  if( bdchginfo == NULL
5572  && nresolutions > lastconsnresolutions
5573  && validdepth <= maxvaliddepth
5574  && (!mustresolve || nresolutions > 0 || conflict->conflictset->nbdchginfos == 0)
5575  && SCIPpqueueNElems(conflict->forcedbdchgqueue) == 0 )
5576  {
5577  int nlits;
5578  SCIP_Bool success;
5579 
5580  /* call the conflict handlers to create a conflict set */
5581  SCIP_CALL( conflictAddConflictset(conflict, blkmem, set, stat, tree, validdepth, diving, TRUE, &success, &nlits) );
5582  if( success )
5583  {
5584  (*nconss)++;
5585  (*nliterals) += nlits;
5586  }
5587  }
5588 
5589  /* produce reconvergence constraints defined by succeeding UIP's of the last depth level */
5590  if( set->conf_reconvlevels != 0 && validdepth <= maxvaliddepth )
5591  {
5592  int reconvlevels;
5593  int i;
5594 
5595  reconvlevels = (set->conf_reconvlevels == -1 ? INT_MAX : set->conf_reconvlevels);
5596  for( i = 0; i < nfirstuips; ++i )
5597  {
5598  if( SCIPbdchginfoHasInferenceReason(firstuips[i])
5599  && currentdepth - SCIPbdchginfoGetDepth(firstuips[i]) < reconvlevels )
5600  {
5601  SCIP_CALL( conflictCreateReconvergenceConss(conflict, blkmem, set, stat, prob, tree, diving, \
5602  validdepth, firstuips[i], nreconvconss, nreconvliterals) );
5603  }
5604  }
5605  }
5606 
5607  /* free the temporary memory */
5608  SCIPsetFreeBufferArray(set, &firstuips);
5609 
5610  /* store last conflict type */
5611  conftype = conflict->conflictset->conflicttype;
5612 
5613  /* clear the conflict candidate queue and the conflict set */
5614  conflictClear(conflict);
5615 
5616  /* restore last conflict type */
5617  conflict->conflictset->conflicttype = conftype;
5618 
5619  return SCIP_OKAY;
5620 }
5621 
5622 /** analyzes conflicting bound changes that were added with calls to SCIPconflictAddBound(), and on success, calls the
5623  * conflict handlers to create a conflict constraint out of the resulting conflict set;
5624  * updates statistics for propagation conflict analysis
5625  */
5627  SCIP_CONFLICT* conflict, /**< conflict analysis data */
5628  BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
5629  SCIP_SET* set, /**< global SCIP settings */
5630  SCIP_STAT* stat, /**< problem statistics */
5631  SCIP_PROB* prob, /**< problem data */
5632  SCIP_TREE* tree, /**< branch and bound tree */
5633  int validdepth, /**< minimal depth level at which the initial conflict set is valid */
5634  SCIP_Bool* success /**< pointer to store whether a conflict constraint was created, or NULL */
5635  )
5636 {
5637  int nconss;
5638  int nliterals;
5639  int nreconvconss;
5640  int nreconvliterals;
5641 
5642  assert(conflict != NULL);
5643  assert(conflict->conflictset != NULL);
5644  assert(set != NULL);
5645  assert(prob != NULL);
5646 
5647  if( success != NULL )
5648  *success = FALSE;
5649 
5650  /* check if the conflict analysis is applicable */
5651  if( !SCIPconflictApplicable(set) )
5652  return SCIP_OKAY;
5653 
5654  /* check, if the conflict set will get too large with high probability */
5655  if( conflict->conflictset->nbdchginfos + SCIPpqueueNElems(conflict->bdchgqueue)
5656  + SCIPpqueueNElems(conflict->forcedbdchgqueue) >= 2*conflictCalcMaxsize(set, prob) )
5657  return SCIP_OKAY;
5658 
5659  SCIPsetDebugMsg(set, "analyzing conflict after infeasible propagation in depth %d\n", SCIPtreeGetCurrentDepth(tree));
5660 
5661  /* start timing */
5662  SCIPclockStart(conflict->propanalyzetime, set);
5663 
5664  conflict->npropcalls++;
5665 
5666  /* analyze the conflict set, and create a conflict constraint on success */
5667  SCIP_CALL( conflictAnalyze(conflict, blkmem, set, stat, prob, tree, FALSE, validdepth, TRUE, &nconss, &nliterals, \
5668  &nreconvconss, &nreconvliterals) );
5669  conflict->npropsuccess += (nconss > 0 ? 1 : 0);
5670  conflict->npropconfconss += nconss;
5671  conflict->npropconfliterals += nliterals;
5672  conflict->npropreconvconss += nreconvconss;
5673  conflict->npropreconvliterals += nreconvliterals;
5674  if( success != NULL )
5675  *success = (nconss > 0);
5676 
5677  /* stop timing */
5678  SCIPclockStop(conflict->propanalyzetime, set);
5679 
5680  return SCIP_OKAY;
5681 }
5682 
5683 /** gets time in seconds used for preprocessing global conflict constraint before appliance */
5685  SCIP_CONFLICT* conflict /**< conflict analysis data */
5686  )
5687 {
5688  assert(conflict != NULL);
5689 
5690  return SCIPclockGetTime(conflict->dIBclock);
5691 }
5692 
5693 /** gets time in seconds used for analyzing propagation conflicts */
5695  SCIP_CONFLICT* conflict /**< conflict analysis data */
5696  )
5697 {
5698  assert(conflict != NULL);
5699 
5700  return SCIPclockGetTime(conflict->propanalyzetime);
5701 }
5702 
5703 /** gets number of calls to propagation conflict analysis */
5705  SCIP_CONFLICT* conflict /**< conflict analysis data */
5706  )
5707 {
5708  assert(conflict != NULL);
5709 
5710  return conflict->npropcalls;
5711 }
5712 
5713 /** gets number of calls to propagation conflict analysis that yield at least one conflict constraint */
5715  SCIP_CONFLICT* conflict /**< conflict analysis data */
5716  )
5717 {
5718  assert(conflict != NULL);
5719 
5720  return conflict->npropsuccess;
5721 }
5722 
5723 /** gets number of conflict constraints detected in propagation conflict analysis */
5725  SCIP_CONFLICT* conflict /**< conflict analysis data */
5726  )
5727 {
5728  assert(conflict != NULL);
5729 
5730  return conflict->npropconfconss;
5731 }
5732 
5733 /** gets total number of literals in conflict constraints created in propagation conflict analysis */
5735  SCIP_CONFLICT* conflict /**< conflict analysis data */
5736  )
5737 {
5738  assert(conflict != NULL);
5739 
5740  return conflict->npropconfliterals;
5741 }
5742 
5743 /** gets number of reconvergence constraints detected in propagation conflict analysis */
5745  SCIP_CONFLICT* conflict /**< conflict analysis data */
5746  )
5747 {
5748  assert(conflict != NULL);
5749 
5750  return conflict->npropreconvconss;
5751 }
5752 
5753 /** gets total number of literals in reconvergence constraints created in propagation conflict analysis */
5755  SCIP_CONFLICT* conflict /**< conflict analysis data */
5756  )
5757 {
5758  assert(conflict != NULL);
5759 
5760  return conflict->npropreconvliterals;
5761 }
5762 
5763 
5764 
5765 
5766 /*
5767  * Infeasible LP Conflict Analysis
5768  */
5769 
5770 /** ensures, that side change arrays can store at least num entries */
5771 static
5773  SCIP_SET* set, /**< global SCIP settings */
5774  int** sidechginds, /**< pointer to side change index array */
5775  SCIP_Real** sidechgoldlhss, /**< pointer to side change old left hand sides array */
5776  SCIP_Real** sidechgoldrhss, /**< pointer to side change old right hand sides array */
5777  SCIP_Real** sidechgnewlhss, /**< pointer to side change new left hand sides array */
5778  SCIP_Real** sidechgnewrhss, /**< pointer to side change new right hand sides array */
5779  int* sidechgssize, /**< pointer to size of side change arrays */
5780  int num /**< minimal number of entries to be able to store in side change arrays */
5781  )
5782 {
5783  assert(sidechginds != NULL);
5784  assert(sidechgoldlhss != NULL);
5785  assert(sidechgoldrhss != NULL);
5786  assert(sidechgnewlhss != NULL);
5787  assert(sidechgnewrhss != NULL);
5788  assert(sidechgssize != NULL);
5789 
5790  if( num > *sidechgssize )
5791  {
5792  int newsize;
5793 
5794  newsize = SCIPsetCalcMemGrowSize(set, num);
5795  SCIP_CALL( SCIPsetReallocBufferArray(set, sidechginds, newsize) );
5796  SCIP_CALL( SCIPsetReallocBufferArray(set, sidechgoldlhss, newsize) );
5797  SCIP_CALL( SCIPsetReallocBufferArray(set, sidechgoldrhss, newsize) );
5798  SCIP_CALL( SCIPsetReallocBufferArray(set, sidechgnewlhss, newsize) );
5799  SCIP_CALL( SCIPsetReallocBufferArray(set, sidechgnewrhss, newsize) );
5800  *sidechgssize = newsize;
5801  }
5802  assert(num <= *sidechgssize);
5803 
5804  return SCIP_OKAY;
5805 }
5806 
5807 /** adds removal of row's side to side change arrays; finite sides are only replaced by near infinite sides, such
5808  * that the row's sense in the LP solver is not changed
5809  */
5810 static
5812  SCIP_SET* set, /**< global SCIP settings */
5813  SCIP_ROW* row, /**< LP row to change the sides for */
5814  SCIP_Real lpiinfinity, /**< value treated as infinity in LP solver */
5815  int** sidechginds, /**< pointer to side change index array */
5816  SCIP_Real** sidechgoldlhss, /**< pointer to side change old left hand sides array */
5817  SCIP_Real** sidechgoldrhss, /**< pointer to side change old right hand sides array */
5818  SCIP_Real** sidechgnewlhss, /**< pointer to side change new left hand sides array */
5819  SCIP_Real** sidechgnewrhss, /**< pointer to side change new right hand sides array */
5820  int* sidechgssize, /**< pointer to size of side change arrays */
5821  int* nsidechgs /**< pointer to number of used slots in side change arrays */
5822  )
5823 {
5824  SCIP_Real lhs;
5825  SCIP_Real rhs;
5826  SCIP_Real constant;
5827 
5828  assert(sidechginds != NULL);
5829  assert(sidechgoldlhss != NULL);
5830  assert(sidechgoldrhss != NULL);
5831  assert(sidechgnewlhss != NULL);
5832  assert(sidechgnewrhss != NULL);
5833  assert(sidechgssize != NULL);
5834  assert(nsidechgs != NULL);
5835 
5836  lhs = SCIProwGetLhs(row);
5837  rhs = SCIProwGetRhs(row);
5838  constant = SCIProwGetConstant(row);
5839  assert(!SCIPsetIsInfinity(set, -lhs) || !SCIPsetIsInfinity(set, rhs));
5840 
5841  /* get memory to store additional side change */
5842  SCIP_CALL( ensureSidechgsSize(set, sidechginds, sidechgoldlhss, sidechgoldrhss, sidechgnewlhss, sidechgnewrhss, \
5843  sidechgssize, (*nsidechgs)+1) );
5844  assert(*nsidechgs < *sidechgssize);
5845  assert(*sidechginds != NULL);
5846  assert(*sidechgoldlhss != NULL);
5847  assert(*sidechgoldrhss != NULL);
5848  assert(*sidechgnewlhss != NULL);
5849  assert(*sidechgnewrhss != NULL);
5850 
5851  /* store side change */
5852  (*sidechginds)[*nsidechgs] = SCIProwGetLPPos(row);
5853  if( SCIPsetIsInfinity(set, -lhs) )
5854  {
5855  (*sidechgoldlhss)[*nsidechgs] = -lpiinfinity;
5856  (*sidechgnewlhss)[*nsidechgs] = -lpiinfinity;
5857  }
5858  else
5859  {
5860  (*sidechgoldlhss)[*nsidechgs] = lhs - constant;
5861  (*sidechgnewlhss)[*nsidechgs] = -lpiinfinity;
5862  }
5863  if( SCIPsetIsInfinity(set, rhs) )
5864  {
5865  (*sidechgoldrhss)[*nsidechgs] = lpiinfinity;
5866  (*sidechgnewrhss)[*nsidechgs] = lpiinfinity;
5867  }
5868  else
5869  {
5870  (*sidechgoldrhss)[*nsidechgs] = rhs - constant;
5871  (*sidechgnewrhss)[*nsidechgs] = lpiinfinity;
5872  }
5873  (*nsidechgs)++;
5874 
5875  return SCIP_OKAY;
5876 }
5877 
5878 /** inserts variable's new bounds into bound change arrays */
5879 static
5881  SCIP_SET* set, /**< global SCIP settings */
5882  SCIP_VAR* var, /**< variable to change the LP bounds for */
5883  SCIP_Real newlb, /**< new lower bound */
5884  SCIP_Real newub, /**< new upper bound */
5885  SCIP_LPBDCHGS* oldlpbdchgs, /**< old LP bound changes used for reset the LP bound change */
5886  SCIP_LPBDCHGS* relaxedlpbdchgs, /**< relaxed LP bound changes used for reset the LP bound change */
5887  SCIP_LPI* lpi /**< pointer to LPi to access infinity of LP solver; necessary to set correct value */
5888  )
5889 {
5890  assert(newlb <= newub);
5891  assert(oldlpbdchgs != NULL);
5892  assert(relaxedlpbdchgs != NULL);
5893 
5895  {
5896  SCIP_COL* col;
5897  int idx;
5898  int c;
5899 
5900  col = SCIPvarGetCol(var);
5901  c = SCIPcolGetLPPos(col);
5902 
5903  if( c >= 0 )
5904  {
5905  /* store old bound change for resetting the LP later */
5906  if( !oldlpbdchgs->usedcols[c] )
5907  {
5908  idx = oldlpbdchgs->nbdchgs;
5909  oldlpbdchgs->usedcols[c] = TRUE;
5910  oldlpbdchgs->bdchgcolinds[c] = idx;
5911  oldlpbdchgs->nbdchgs++;
5912 
5913  oldlpbdchgs->bdchginds[idx] = c;
5914  oldlpbdchgs->bdchglbs[idx] = SCIPvarGetLbLP(var, set);
5915  oldlpbdchgs->bdchgubs[idx] = SCIPvarGetUbLP(var, set);
5916  }
5917  assert(oldlpbdchgs->bdchginds[oldlpbdchgs->bdchgcolinds[c]] == c);
5918  assert((SCIPlpiIsInfinity(lpi, -oldlpbdchgs->bdchglbs[oldlpbdchgs->bdchgcolinds[c]]) && SCIPsetIsInfinity(set, -SCIPvarGetLbLP(var, set))) ||
5919  SCIPsetIsEQ(set, oldlpbdchgs->bdchglbs[oldlpbdchgs->bdchgcolinds[c]], SCIPvarGetLbLP(var, set)));
5920  assert((SCIPlpiIsInfinity(lpi, oldlpbdchgs->bdchgubs[oldlpbdchgs->bdchgcolinds[c]]) && SCIPsetIsInfinity(set, SCIPvarGetUbLP(var, set))) ||
5921  SCIPsetIsEQ(set, oldlpbdchgs->bdchgubs[oldlpbdchgs->bdchgcolinds[c]], SCIPvarGetUbLP(var, set)));
5922 
5923  /* store bound change for conflict analysis */
5924  if( !relaxedlpbdchgs->usedcols[c] )
5925  {
5926  idx = relaxedlpbdchgs->nbdchgs;
5927  relaxedlpbdchgs->usedcols[c] = TRUE;
5928  relaxedlpbdchgs->bdchgcolinds[c] = idx;
5929  relaxedlpbdchgs->nbdchgs++;
5930 
5931  /* remember the positive for later further bound widenings */
5932  relaxedlpbdchgs->bdchginds[idx] = c;
5933  }
5934  else
5935  {
5936  idx = relaxedlpbdchgs->bdchgcolinds[c];
5937  assert(relaxedlpbdchgs->bdchginds[idx] == c);
5938 
5939  /* the new bound should be the same or more relaxed */
5940  assert(relaxedlpbdchgs->bdchglbs[idx] >= newlb ||
5941  (SCIPlpiIsInfinity(lpi, -relaxedlpbdchgs->bdchglbs[idx]) && SCIPsetIsInfinity(set, -newlb)));
5942  assert(relaxedlpbdchgs->bdchgubs[idx] <= newub ||
5943  (SCIPlpiIsInfinity(lpi, relaxedlpbdchgs->bdchgubs[idx]) && SCIPsetIsInfinity(set, newub)));
5944  }
5945 
5946  /* set the new bounds for the LP with the correct infinity value */
5947  relaxedlpbdchgs->bdchglbs[idx] = SCIPsetIsInfinity(set, -newlb) ? -SCIPlpiInfinity(lpi) : newlb;
5948  relaxedlpbdchgs->bdchgubs[idx] = SCIPsetIsInfinity(set, newub) ? SCIPlpiInfinity(lpi) : newub;
5949  if( SCIPsetIsInfinity(set, -oldlpbdchgs->bdchglbs[idx]) )
5950  oldlpbdchgs->bdchglbs[idx] = -SCIPlpiInfinity(lpi);
5951  if( SCIPsetIsInfinity(set, oldlpbdchgs->bdchgubs[idx]) )
5952  oldlpbdchgs->bdchgubs[idx] = SCIPlpiInfinity(lpi);
5953  }
5954  }
5955 
5956  return SCIP_OKAY;
5957 }
5958 
5959 /** ensures, that candidate array can store at least num entries */
5960 static
5962  SCIP_SET* set, /**< global SCIP settings */
5963  SCIP_VAR*** cands, /**< pointer to candidate array */
5964  SCIP_Real** candscores, /**< pointer to candidate score array */
5965  SCIP_Real** newbounds, /**< pointer to candidate new bounds array */
5966  SCIP_Real** proofactdeltas, /**< pointer to candidate proof delta array */
5967  int* candssize, /**< pointer to size of array */
5968  int num /**< minimal number of candidates to store in array */
5969  )
5970 {
5971  assert(cands != NULL);
5972  assert(candssize != NULL);
5973 
5974  if( num > *candssize )
5975  {
5976  int newsize;
5977 
5978  newsize = SCIPsetCalcMemGrowSize(set, num);
5979  SCIP_CALL( SCIPsetReallocBufferArray(set, cands, newsize) );
5980  SCIP_CALL( SCIPsetReallocBufferArray(set, candscores, newsize) );
5981  SCIP_CALL( SCIPsetReallocBufferArray(set, newbounds, newsize) );
5982  SCIP_CALL( SCIPsetReallocBufferArray(set, proofactdeltas, newsize) );
5983  *candssize = newsize;
5984  }
5985  assert(num <= *candssize);
5986 
5987  return SCIP_OKAY;
5988 }
5989 
5990 /** adds variable to candidate list, if the current best bound corresponding to the proof coefficient is local;
5991  * returns the array position in the candidate list, where the new candidate was inserted, or -1 if the
5992  * variable can relaxed to global bounds immediately without increasing the proof's activity;
5993  * the candidates are sorted with respect to the following two criteria:
5994  * - prefer bound changes that have been applied deeper in the tree, to get a more global conflict
5995  * - prefer variables with small Farkas coefficient to get rid of as many bound changes as possible
5996  */
5997 static
5999  SCIP_SET* set, /**< global SCIP settings */
6000  int currentdepth, /**< current depth in the tree */
6001  SCIP_VAR* var, /**< variable to add to candidate array */
6002  int lbchginfopos, /**< positions of currently active lower bound change information in variable's array */
6003  int ubchginfopos, /**< positions of currently active upper bound change information in variable's array */
6004  SCIP_Real proofcoef, /**< coefficient of variable in infeasibility/bound proof */
6005  SCIP_Real prooflhs, /**< left hand side of infeasibility/bound proof */
6006  SCIP_Real proofact, /**< activity of infeasibility/bound proof row */
6007  SCIP_VAR*** cands, /**< pointer to candidate array for undoing bound changes */
6008  SCIP_Real** candscores, /**< pointer to candidate score array for undoing bound changes */
6009  SCIP_Real** newbounds, /**< pointer to candidate new bounds array for undoing bound changes */
6010  SCIP_Real** proofactdeltas, /**< pointer to proof activity increase array for undoing bound changes */
6011  int* candssize, /**< pointer to size of cands arrays */
6012  int* ncands, /**< pointer to count number of candidates in bound change list */
6013  int firstcand /**< position of first unprocessed bound change candidate */
6014  )
6015 {
6016  SCIP_Real oldbound;
6017  SCIP_Real newbound;
6018  SCIP_Real QUAD(proofactdelta);
6019  SCIP_Real score;
6020  int depth;
6021  int i;
6022  SCIP_Bool resolvable;
6023 
6024  assert(set != NULL);
6025  assert(var != NULL);
6026  assert(-1 <= lbchginfopos && lbchginfopos <= var->nlbchginfos);
6027  assert(-1 <= ubchginfopos && ubchginfopos <= var->nubchginfos);
6028  assert(!SCIPsetIsZero(set, proofcoef));
6029  assert(SCIPsetIsGT(set, prooflhs, proofact));
6030  assert(cands != NULL);
6031  assert(candscores != NULL);
6032  assert(newbounds != NULL);
6033  assert(proofactdeltas != NULL);
6034  assert(candssize != NULL);
6035  assert(ncands != NULL);
6036  assert(*ncands <= *candssize);
6037  assert(0 <= firstcand && firstcand <= *ncands);
6038 
6039  /* in the infeasibility or dual bound proof, the variable's bound is chosen to maximize the proof's activity */
6040  if( proofcoef > 0.0 )
6041  {
6042  assert(ubchginfopos >= 0); /* otherwise, undoBdchgsProof() should already have relaxed the local bound */
6043 
6044  /* calculate the difference of current bound to the previous bound the variable was set to */
6045  if( ubchginfopos == var->nubchginfos )
6046  {
6047  /* current bound is the strong branching or diving bound */
6048  oldbound = SCIPvarGetUbLP(var, set);
6049  newbound = SCIPvarGetUbLocal(var);
6050  depth = currentdepth+1;
6051  resolvable = FALSE;
6052  }
6053  else
6054  {
6055  /* current bound is the result of a local bound change */
6056  resolvable = bdchginfoIsResolvable(&var->ubchginfos[ubchginfopos]);
6057  depth = var->ubchginfos[ubchginfopos].bdchgidx.depth;
6058  oldbound = var->ubchginfos[ubchginfopos].newbound;
6059  newbound = var->ubchginfos[ubchginfopos].oldbound;
6060  }
6061  }
6062  else
6063  {
6064  assert(lbchginfopos >= 0); /* otherwise, undoBdchgsProof() should already have relaxed the local bound */
6065 
6066  /* calculate the difference of current bound to the previous bound the variable was set to */
6067  if( lbchginfopos == var->nlbchginfos )
6068  {
6069  /* current bound is the strong branching or diving bound */
6070  oldbound = SCIPvarGetLbLP(var, set);
6071  newbound = SCIPvarGetLbLocal(var);
6072  depth = currentdepth+1;
6073  resolvable = FALSE;
6074  }
6075  else
6076  {
6077  /* current bound is the result of a local bound change */
6078  resolvable = bdchginfoIsResolvable(&var->lbchginfos[lbchginfopos]);
6079  depth = var->lbchginfos[lbchginfopos].bdchgidx.depth;
6080  oldbound = var->lbchginfos[lbchginfopos].newbound;
6081  newbound = var->lbchginfos[lbchginfopos].oldbound;
6082  }
6083  }
6084 
6085  /* calculate the increase in the proof's activity */
6086  SCIPquadprecSumDD(proofactdelta, newbound, -oldbound);
6087  SCIPquadprecProdQD(proofactdelta, proofactdelta, proofcoef);
6088  assert(QUAD_TO_DBL(proofactdelta) > 0.0);
6089 
6090  /* calculate score for undoing the bound change */
6091  score = calcBdchgScore(prooflhs, proofact, QUAD_TO_DBL(proofactdelta), proofcoef, depth, currentdepth, var, set);
6092 
6093  if( !resolvable )
6094  {
6095  score += 10.0;
6096  if( !SCIPvarIsBinary(var) )
6097  score += 10.0;
6098  }
6099 
6100  /* get enough memory to store new candidate */
6101  SCIP_CALL( ensureCandsSize(set, cands, candscores, newbounds, proofactdeltas, candssize, (*ncands)+1) );
6102  assert(*cands != NULL);
6103  assert(*candscores != NULL);
6104  assert(*newbounds != NULL);
6105  assert(*proofactdeltas != NULL);
6106 
6107  SCIPsetDebugMsg(set, " -> local <%s> %s %g, relax <%s> %s %g, proofcoef=%g, dpt=%d, resolve=%u, delta=%g, score=%g\n",
6108  SCIPvarGetName(var), proofcoef > 0.0 ? "<=" : ">=", oldbound,
6109  SCIPvarGetName(var), proofcoef > 0.0 ? "<=" : ">=", newbound,
6110  proofcoef, depth, resolvable, QUAD_TO_DBL(proofactdelta), score);
6111 
6112  /* insert variable in candidate list without touching the already processed candidates */
6113  for( i = *ncands; i > firstcand && score > (*candscores)[i-1]; --i )
6114  {
6115  (*cands)[i] = (*cands)[i-1];
6116  (*candscores)[i] = (*candscores)[i-1];
6117  (*newbounds)[i] = (*newbounds)[i-1];
6118  (*proofactdeltas)[i] = (*proofactdeltas)[i-1];
6119  }
6120  (*cands)[i] = var;
6121  (*candscores)[i] = score;
6122  (*newbounds)[i] = newbound;
6123  (*proofactdeltas)[i] = QUAD_TO_DBL(proofactdelta);
6124  (*ncands)++;
6125 
6126  return SCIP_OKAY;
6127 }
6128 
6129 /** after changing the global bound of a variable, the bdchginfos that are now redundant are replaced with
6130  * oldbound = newbound = global bound; if the current bdchginfo is of such kind, the bound is equal to the
6131  * global bound and we can ignore it by installing a -1 as the corresponding bound change info position
6132  */
6133 static
6135  SCIP_VAR* var, /**< problem variable */
6136  int* lbchginfopos, /**< pointer to lower bound change information position */
6137  int* ubchginfopos /**< pointer to upper bound change information position */
6138  )
6139 {
6140  assert(var != NULL);
6141  assert(lbchginfopos != NULL);
6142  assert(ubchginfopos != NULL);
6143  assert(-1 <= *lbchginfopos && *lbchginfopos <= var->nlbchginfos);
6144  assert(-1 <= *ubchginfopos && *ubchginfopos <= var->nubchginfos);
6145  assert(*lbchginfopos == -1 || *lbchginfopos == var->nlbchginfos
6146  || var->lbchginfos[*lbchginfopos].redundant
6147  == (var->lbchginfos[*lbchginfopos].oldbound == var->lbchginfos[*lbchginfopos].newbound)); /*lint !e777*/
6148  assert(*ubchginfopos == -1 || *ubchginfopos == var->nubchginfos
6149  || var->ubchginfos[*ubchginfopos].redundant
6150  == (var->ubchginfos[*ubchginfopos].oldbound == var->ubchginfos[*ubchginfopos].newbound)); /*lint !e777*/
6151 
6152  if( *lbchginfopos >= 0 && *lbchginfopos < var->nlbchginfos && var->lbchginfos[*lbchginfopos].redundant )
6153  {
6154  assert(SCIPvarGetLbGlobal(var) == var->lbchginfos[*lbchginfopos].oldbound); /*lint !e777*/
6155  *lbchginfopos = -1;
6156  }
6157  if( *ubchginfopos >= 0 && *ubchginfopos < var->nubchginfos && var->ubchginfos[*ubchginfopos].redundant )
6158  {
6159  assert(SCIPvarGetUbGlobal(var) == var->ubchginfos[*ubchginfopos].oldbound); /*lint !e777*/
6160  *ubchginfopos = -1;
6161  }
6162 }
6163 
6164 /** undoes bound changes on variables, still leaving the given infeasibility proof valid */
6165 static
6167  SCIP_SET* set, /**< global SCIP settings */
6168  SCIP_PROB* prob, /**< problem data */
6169  int currentdepth, /**< current depth in the tree */
6170  SCIP_Real* proofcoefs, /**< coefficients in infeasibility proof */
6171  SCIP_Real prooflhs, /**< left hand side of proof */
6172  SCIP_Real* proofact, /**< current activity of proof */
6173  SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
6174  SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
6175  int* lbchginfoposs, /**< positions of currently active lower bound change information in variables' arrays */
6176  int* ubchginfoposs, /**< positions of currently active upper bound change information in variables' arrays */
6177  SCIP_LPBDCHGS* oldlpbdchgs, /**< old LP bound changes used for reset the LP bound change, or NULL */
6178  SCIP_LPBDCHGS* relaxedlpbdchgs, /**< relaxed LP bound changes used for reset the LP bound change, or NULL */
6179  SCIP_Bool* resolve, /**< pointer to store whether the changed LP should be resolved again, or NULL */
6180  SCIP_LPI* lpi /**< pointer to LPi to access infinity of LP solver; necessary to set correct values */
6181  )
6182 {
6183  SCIP_VAR** vars;
6184  SCIP_VAR** cands;
6185  SCIP_Real* candscores;
6186  SCIP_Real* newbounds;
6187  SCIP_Real* proofactdeltas;
6188  int nvars;
6189  int ncands;
6190  int candssize;
6191  int v;
6192  int i;
6193 
6194  assert(prob != NULL);
6195  assert(proofcoefs != NULL);
6196  assert(SCIPsetIsFeasGT(set, prooflhs, (*proofact)));
6197  assert(curvarlbs != NULL);
6198  assert(curvarubs != NULL);
6199  assert(lbchginfoposs != NULL);
6200  assert(ubchginfoposs != NULL);
6201 
6202  if( resolve != NULL )
6203  *resolve = FALSE;
6204 
6205  vars = prob->vars;
6206  nvars = prob->nvars;
6207  assert(nvars == 0 || vars != NULL);
6208 
6209  /* calculate the order in which the bound changes are tried to be undone, and relax all bounds if this doesn't
6210  * increase the proof's activity
6211  */
6212  SCIP_CALL( SCIPsetAllocBufferArray(set, &cands, nvars) );
6213  SCIP_CALL( SCIPsetAllocBufferArray(set, &candscores, nvars) );
6214  SCIP_CALL( SCIPsetAllocBufferArray(set, &newbounds, nvars) );
6215  SCIP_CALL( SCIPsetAllocBufferArray(set, &proofactdeltas, nvars) );
6216  ncands = 0;
6217  candssize = nvars;
6218  for( v = 0; v < nvars; ++v )
6219  {
6220  SCIP_VAR* var;
6221  SCIP_Bool relaxed;
6222 
6223  var = vars[v];
6224 
6225  /* after changing the global bound of a variable, the bdchginfos that are now redundant are replaced with
6226  * oldbound = newbound = global bound; if the current bdchginfo is of such kind, the bound is equal to the
6227  * global bound and we can ignore it
6228  */
6229  skipRedundantBdchginfos(var, &lbchginfoposs[v], &ubchginfoposs[v]);
6230 
6231  /* ignore variables already relaxed to global bounds */
6232  if( (lbchginfoposs[v] == -1 && ubchginfoposs[v] == -1) )
6233  {
6234  proofcoefs[v] = 0.0;
6235  continue;
6236  }
6237 
6238  /* relax bounds that are not used in the proof to the global bounds */
6239  relaxed = FALSE;
6240  if( !SCIPsetIsNegative(set, proofcoefs[v]) )
6241  {
6242  /* the lower bound is not used */
6243  if( lbchginfoposs[v] >= 0 )
6244  {
6245  SCIPsetDebugMsg(set, " -> relaxing variable <%s>[%g,%g] to [%g,%g]: proofcoef=%g, %g <= %g\n",
6246  SCIPvarGetName(var), curvarlbs[v], curvarubs[v], SCIPvarGetLbGlobal(var), curvarubs[v],
6247  proofcoefs[v], prooflhs, (*proofact));
6248  curvarlbs[v] = SCIPvarGetLbGlobal(var);
6249  lbchginfoposs[v] = -1;
6250  relaxed = TRUE;
6251  }
6252  }
6253  if( !SCIPsetIsPositive(set, proofcoefs[v]) )
6254  {
6255  /* the upper bound is not used */
6256  if( ubchginfoposs[v] >= 0 )
6257  {
6258  SCIPsetDebugMsg(set, " -> relaxing variable <%s>[%g,%g] to [%g,%g]: proofcoef=%g, %g <= %g\n",
6259  SCIPvarGetName(var), curvarlbs[v], curvarubs[v], curvarlbs[v], SCIPvarGetUbGlobal(var),
6260  proofcoefs[v], prooflhs, (*proofact));
6261  curvarubs[v] = SCIPvarGetUbGlobal(var);
6262  ubchginfoposs[v] = -1;
6263  relaxed = TRUE;
6264  }
6265  }
6266  if( relaxed && oldlpbdchgs != NULL )
6267  {
6268  SCIP_CALL( addBdchg(set, var, curvarlbs[v], curvarubs[v], oldlpbdchgs, relaxedlpbdchgs, lpi) );
6269  }
6270 
6271  /* add bound to candidate list */
6272  if( lbchginfoposs[v] >= 0 || ubchginfoposs[v] >= 0 )
6273  {
6274  SCIP_CALL( addCand(set, currentdepth, var, lbchginfoposs[v], ubchginfoposs[v], proofcoefs[v],
6275  prooflhs, (*proofact), &cands, &candscores, &newbounds, &proofactdeltas, &candssize, &ncands, 0) );
6276  }
6277  /* we can set the proof coefficient to zero, because the variable is not needed */
6278  else
6279  proofcoefs[v] = 0.0;
6280  }
6281 
6282  /* try to undo remaining local bound changes while still keeping the proof row violated:
6283  * bound changes can be undone, if prooflhs > proofact + proofactdelta;
6284  * afterwards, the current proof activity has to be updated
6285  */
6286  for( i = 0; i < ncands; ++i )
6287  {
6288  assert(proofactdeltas[i] > 0.0);
6289  assert((lbchginfoposs[SCIPvarGetProbindex(cands[i])] >= 0) != (ubchginfoposs[SCIPvarGetProbindex(cands[i])] >= 0));
6290 
6291  /* when relaxing a constraint we still need to stay infeasible; therefore we need to do the comparison in
6292  * feasibility tolerance because if 'prooflhs' is (feas-))equal to 'proofact + proofactdeltas[i]' it would mean
6293  * that there is no violation
6294  */
6295  if( SCIPsetIsFeasGT(set, prooflhs, (*proofact) + proofactdeltas[i]) )
6296  {
6297  v = SCIPvarGetProbindex(cands[i]);
6298  assert(0 <= v && v < nvars);
6299  assert((lbchginfoposs[v] >= 0) != (ubchginfoposs[v] >= 0));
6300 
6301  SCIPsetDebugMsg(set, " -> relaxing variable <%s>[%g,%g] to [%g,%g]: proofcoef=%g, %g <= %g + %g\n",
6302  SCIPvarGetName(cands[i]), curvarlbs[v], curvarubs[v],
6303  proofcoefs[v] > 0.0 ? curvarlbs[v] : newbounds[i],
6304  proofcoefs[v] > 0.0 ? newbounds[i] : curvarubs[v],
6305  proofcoefs[v], prooflhs, (*proofact), proofactdeltas[i]);
6306 
6307 #ifndef NDEBUG
6308  {
6309  SCIP_Real QUAD(verifylb);
6310  SCIP_Real QUAD(verifyub);
6311 
6312  SCIPquadprecSumDD(verifylb, newbounds[i], -curvarlbs[v]);
6313  SCIPquadprecProdQD(verifylb, verifylb, proofcoefs[v]);
6314 
6315  SCIPquadprecSumDD(verifyub, newbounds[i], -curvarubs[v]);
6316  SCIPquadprecProdQD(verifyub, verifyub, proofcoefs[v]);
6317 
6318  assert((SCIPsetIsPositive(set, proofcoefs[v]) && SCIPsetIsGT(set, newbounds[i], curvarubs[v]))
6319  || (SCIPsetIsNegative(set, proofcoefs[v]) && SCIPsetIsLT(set, newbounds[i], curvarlbs[v])));
6320  assert((SCIPsetIsPositive(set, proofcoefs[v])
6321  && SCIPsetIsEQ(set, proofactdeltas[i], QUAD_TO_DBL(verifyub)))
6322  || (SCIPsetIsNegative(set, proofcoefs[v])
6323  && SCIPsetIsEQ(set, proofactdeltas[i], QUAD_TO_DBL(verifylb))));
6324  assert(!SCIPsetIsZero(set, proofcoefs[v]));
6325  }
6326 #endif
6327 
6328  if( proofcoefs[v] > 0.0 )
6329  {
6330  assert(ubchginfoposs[v] >= 0);
6331  assert(lbchginfoposs[v] == -1);
6332  curvarubs[v] = newbounds[i];
6333  ubchginfoposs[v]--;
6334  }
6335  else
6336  {
6337  assert(lbchginfoposs[v] >= 0);
6338  assert(ubchginfoposs[v] == -1);
6339  curvarlbs[v] = newbounds[i];
6340  lbchginfoposs[v]--;
6341  }
6342  if( oldlpbdchgs != NULL )
6343  {
6344  SCIP_CALL( addBdchg(set, cands[i], curvarlbs[v], curvarubs[v], oldlpbdchgs, relaxedlpbdchgs, lpi) );
6345  }
6346  (*proofact) += proofactdeltas[i];
6347  if( resolve != NULL && SCIPvarIsInLP(cands[i]) )
6348  *resolve = TRUE;
6349 
6350  /* after changing the global bound of a variable, the bdchginfos that are now redundant are replaced with
6351  * oldbound = newbound = global bound; if the current bdchginfo is of such kind, the bound is equal to the
6352  * global bound and we can ignore it
6353  */
6354  skipRedundantBdchginfos(cands[i], &lbchginfoposs[v], &ubchginfoposs[v]);
6355 
6356  /* insert the new local bound of the variable into the candidate list */
6357  if( lbchginfoposs[v] >= 0 || ubchginfoposs[v] >= 0 )
6358  {
6359  SCIP_CALL( addCand(set, currentdepth, cands[i], lbchginfoposs[v], ubchginfoposs[v], proofcoefs[v],
6360  prooflhs, (*proofact), &cands, &candscores, &newbounds, &proofactdeltas, &candssize, &ncands, i+1) );
6361  }
6362  else
6363  proofcoefs[v] = 0.0;
6364  }
6365  }
6366 
6367  /* free the buffer for the sorted bound change candidates */
6368  SCIPsetFreeBufferArray(set, &proofactdeltas);
6369  SCIPsetFreeBufferArray(set, &newbounds);
6370  SCIPsetFreeBufferArray(set, &candscores);
6371  SCIPsetFreeBufferArray(set, &cands);
6372 
6373  return SCIP_OKAY;
6374 }
6375 
6376 /* because calculations might cancel out some values, we stop the infeasibility analysis if a value is bigger than
6377  * 2^53 = 9007199254740992
6378  */
6379 #define NUMSTOP 9007199254740992.0
6380 
6381 /** analyzes an infeasible LP and undoes additional bound changes while staying infeasible */
6382 static
6384  SCIP_SET* set, /**< global SCIP settings */
6385  SCIP_PROB* prob, /**< problem data */
6386  SCIP_LP* lp, /**< LP data */
6387  int currentdepth, /**< current depth in the tree */
6388  SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
6389  SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
6390  int* lbchginfoposs, /**< positions of currently active lower bound change information in variables' arrays */
6391  int* ubchginfoposs, /**< positions of currently active upper bound change information in variables' arrays */
6392  SCIP_LPBDCHGS* oldlpbdchgs, /**< old LP bound changes used for reset the LP bound change, or NULL */
6393  SCIP_LPBDCHGS* relaxedlpbdchgs, /**< relaxed LP bound changes used for reset the LP bound change, or NULL */
6394  SCIP_Bool* valid, /**< pointer to store whether the unfixings are valid */
6395  SCIP_Bool* resolve, /**< pointer to store whether the changed LP should be resolved again */
6396  SCIP_Real* farkascoefs, /**< coefficients in the proof constraint */
6397  SCIP_Real farkaslhs, /**< lhs of the proof constraint */
6398  SCIP_Real* farkasactivity /**< maximal activity of the proof constraint */
6399  )
6400 {
6401  SCIP_LPI* lpi;
6402 
6403  assert(prob != NULL);
6404  assert(lp != NULL);
6405  assert(lp->flushed);
6406  assert(lp->solved);
6407  assert(curvarlbs != NULL);
6408  assert(curvarubs != NULL);
6409  assert(lbchginfoposs != NULL);
6410  assert(ubchginfoposs != NULL);
6411  assert(valid != NULL);
6412  assert(resolve != NULL);
6413 
6414  SCIPsetDebugMsg(set, "undoing bound changes in infeasible LP: cutoff=%g\n", lp->cutoffbound);
6415 
6416  *valid = FALSE;
6417  *resolve = FALSE;
6418 
6419  lpi = SCIPlpGetLPI(lp);
6420 
6421  /* check, if the Farkas row is still violated (using current bounds and ignoring local rows) */
6422  if( SCIPsetIsFeasGT(set, farkaslhs, *farkasactivity) )
6423  {
6424  /* undo bound changes while keeping the infeasibility proof valid */
6425  SCIP_CALL( undoBdchgsProof(set, prob, currentdepth, farkascoefs, farkaslhs, farkasactivity, \
6426  curvarlbs, curvarubs, lbchginfoposs, ubchginfoposs, oldlpbdchgs, relaxedlpbdchgs, resolve, lpi) );
6427 
6428  *valid = TRUE;
6429 
6430  /* resolving does not make sense: the old dual ray is still valid -> resolving will not change the solution */
6431  *resolve = FALSE;
6432  }
6433 
6434  return SCIP_OKAY;
6435 }
6436 
6437 /** analyzes an LP exceeding the objective limit and undoes additional bound changes while staying beyond the
6438  * objective limit
6439  */
6440 static
6442  SCIP_SET* set, /**< global SCIP settings */
6443  SCIP_PROB* prob, /**< problem data */
6444  SCIP_LP* lp, /**< LP data */
6445  int currentdepth, /**< current depth in the tree */
6446  SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
6447  SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
6448  int* lbchginfoposs, /**< positions of currently active lower bound change information in variables' arrays */
6449  int* ubchginfoposs, /**< positions of currently active upper bound change information in variables' arrays */
6450  SCIP_LPBDCHGS* oldlpbdchgs, /**< old LP bound changes used for reset the LP bound change, or NULL */
6451  SCIP_LPBDCHGS* relaxedlpbdchgs, /**< relaxed LP bound changes used for reset the LP bound change, or NULL */
6452  SCIP_Bool* valid, /**< pointer to store whether the unfixings are valid */
6453  SCIP_Bool* resolve, /**< pointer to store whether the changed LP should be resolved again */
6454  SCIP_Real* dualcoefs, /**< coefficients in the proof constraint */
6455  SCIP_Real duallhs, /**< lhs of the proof constraint */
6456  SCIP_Real* dualactivity /**< maximal activity of the proof constraint */
6457  )
6458 {
6459  SCIP_LPI* lpi;
6460 
6461  assert(set != NULL);
6462  assert(prob != NULL);
6463  assert(lp != NULL);
6464  assert(lp->flushed);
6465  assert(lp->solved);
6466  assert(curvarlbs != NULL);
6467  assert(curvarubs != NULL);
6468  assert(lbchginfoposs != NULL);
6469  assert(ubchginfoposs != NULL);
6470  assert(valid != NULL);
6471  assert(resolve != NULL);
6472 
6473  *valid = FALSE;
6474  *resolve = FALSE;
6475 
6476  SCIPsetDebugMsg(set, "undoing bound changes in LP exceeding cutoff: cutoff=%g\n", lp->cutoffbound);
6477 
6478  /* get LP solver interface */
6479  lpi = SCIPlpGetLPI(lp);
6480 
6481  /* check, if the dual row is still violated (using current bounds and ignoring local rows) */
6482  if( SCIPsetIsFeasGT(set, duallhs, *dualactivity) )
6483  {
6484  /* undo bound changes while keeping the infeasibility proof valid */
6485  SCIP_CALL( undoBdchgsProof(set, prob, currentdepth, dualcoefs, duallhs, dualactivity, curvarlbs, curvarubs, \
6486  lbchginfoposs, ubchginfoposs, oldlpbdchgs, relaxedlpbdchgs, resolve, lpi) );
6487 
6488  *valid = TRUE;
6489  }
6490 
6491  return SCIP_OKAY;
6492 }
6493 
6494 /** applies conflict analysis starting with given bound changes, that could not be undone during previous
6495  * infeasibility analysis
6496  */
6497 static
6499  SCIP_CONFLICT* conflict, /**< conflict analysis data */
6500  BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
6501  SCIP_SET* set, /**< global SCIP settings */
6502  SCIP_STAT* stat, /**< problem statistics */
6503  SCIP_PROB* prob, /**< problem data */
6504  SCIP_TREE* tree, /**< branch and bound tree */
6505  SCIP_Bool diving, /**< are we in strong branching or diving mode? */
6506  int* lbchginfoposs, /**< positions of currently active lower bound change information in variables' arrays */
6507  int* ubchginfoposs, /**< positions of currently active upper bound change information in variables' arrays */
6508  int* nconss, /**< pointer to store the number of generated conflict constraints */
6509  int* nliterals, /**< pointer to store the number of literals in generated conflict constraints */
6510  int* nreconvconss, /**< pointer to store the number of generated reconvergence constraints */
6511  int* nreconvliterals /**< pointer to store the number of literals generated reconvergence constraints */
6512  )
6513 {
6514  SCIP_VAR** vars;
6515  SCIP_VAR* var;
6516  SCIP_CONFTYPE conftype;
6517  SCIP_Bool usescutoffbound;
6518  int nvars;
6519  int v;
6520  int nbdchgs;
6521  int maxsize;
6522 
6523  assert(prob != NULL);
6524  assert(lbchginfoposs != NULL);
6525  assert(ubchginfoposs != NULL);
6526  assert(nconss != NULL);
6527  assert(nliterals != NULL);
6528  assert(nreconvconss != NULL);
6529  assert(nreconvliterals != NULL);
6530 
6531  *nconss = 0;
6532  *nliterals = 0;
6533  *nreconvconss = 0;
6534  *nreconvliterals = 0;
6535 
6536  vars = prob->vars;
6537  nvars = prob->nvars;
6538  assert(nvars == 0 || vars != NULL);
6539 
6540  maxsize = 2*conflictCalcMaxsize(set, prob);
6541 
6542  /* initialize conflict data */
6543  conftype = conflict->conflictset->conflicttype;
6544  usescutoffbound = conflict->conflictset->usescutoffbound;
6545 
6546  SCIP_CALL( SCIPconflictInit(conflict, set, stat, prob, conftype, usescutoffbound) );
6547 
6548  conflict->conflictset->conflicttype = conftype;
6549  conflict->conflictset->usescutoffbound = usescutoffbound;
6550 
6551  /* add remaining bound changes to conflict queue */
6552  SCIPsetDebugMsg(set, "initial conflict set after undoing bound changes:\n");
6553 
6554  nbdchgs = 0;
6555  for( v = 0; v < nvars && nbdchgs < maxsize; ++v )
6556  {
6557  var = vars[v];
6558  assert(var != NULL);
6559  assert(var->nlbchginfos >= 0);
6560  assert(var->nubchginfos >= 0);
6561  assert(-1 <= lbchginfoposs[v] && lbchginfoposs[v] <= var->nlbchginfos);
6562  assert(-1 <= ubchginfoposs[v] && ubchginfoposs[v] <= var->nubchginfos);
6563 
6564  if( lbchginfoposs[v] == var->nlbchginfos || ubchginfoposs[v] == var->nubchginfos )
6565  {
6566  SCIP_BDCHGINFO* bdchginfo;
6567  SCIP_Real relaxedbd;
6568 
6569  /* the strong branching or diving bound stored in the column is responsible for the conflict:
6570  * it cannot be resolved and therefore has to be directly put into the conflict set
6571  */
6572  assert((lbchginfoposs[v] == var->nlbchginfos) != (ubchginfoposs[v] == var->nubchginfos)); /* only one can be tight in the dual! */
6573  assert(lbchginfoposs[v] < var->nlbchginfos || SCIPvarGetLbLP(var, set) > SCIPvarGetLbLocal(var));
6574  assert(ubchginfoposs[v] < var->nubchginfos || SCIPvarGetUbLP(var, set) < SCIPvarGetUbLocal(var));
6575 
6576  /* create an artificial bound change information for the diving/strong branching bound change;
6577  * they are freed in the SCIPconflictFlushConss() call
6578  */
6579  if( lbchginfoposs[v] == var->nlbchginfos )
6580  {
6581  SCIP_CALL( conflictCreateTmpBdchginfo(conflict, blkmem, set, var, SCIP_BOUNDTYPE_LOWER,
6582  SCIPvarGetLbLocal(var), SCIPvarGetLbLP(var, set), &bdchginfo) );
6583  relaxedbd = SCIPvarGetLbLP(var, set);
6584  }
6585  else
6586  {
6587  SCIP_CALL( conflictCreateTmpBdchginfo(conflict, blkmem, set, var, SCIP_BOUNDTYPE_UPPER,
6588  SCIPvarGetUbLocal(var), SCIPvarGetUbLP(var, set), &bdchginfo) );
6589  relaxedbd = SCIPvarGetUbLP(var, set);
6590  }
6591 
6592  /* put variable into the conflict set */
6593  SCIPsetDebugMsg(set, " force: <%s> %s %g [status: %d, type: %d, dive/strong]\n",
6594  SCIPvarGetName(var), lbchginfoposs[v] == var->nlbchginfos ? ">=" : "<=",
6595  lbchginfoposs[v] == var->nlbchginfos ? SCIPvarGetLbLP(var, set) : SCIPvarGetUbLP(var, set),
6596  SCIPvarGetStatus(var), SCIPvarGetType(var));
6597  SCIP_CALL( conflictAddConflictBound(conflict, blkmem, set, bdchginfo, relaxedbd) );
6598 
6599  /* each variable which is add to the conflict graph gets an increase in the VSIDS
6600  *
6601  * @note That is different to the VSIDS preseted in the literature
6602  */
6603  SCIP_CALL( incVSIDS(var, blkmem, set, stat, SCIPbdchginfoGetBoundtype(bdchginfo), relaxedbd, set->conf_conflictgraphweight) );
6604  nbdchgs++;
6605  }
6606  else
6607  {
6608  /* put remaining bound changes into conflict candidate queue */
6609  if( lbchginfoposs[v] >= 0 )
6610  {
6611  SCIP_CALL( conflictAddBound(conflict, blkmem, set, stat, var, SCIP_BOUNDTYPE_LOWER, \
6612  &var->lbchginfos[lbchginfoposs[v]], SCIPbdchginfoGetNewbound(&var->lbchginfos[lbchginfoposs[v]])) );
6613  nbdchgs++;
6614  }
6615  if( ubchginfoposs[v] >= 0 )
6616  {
6617  assert(!SCIPbdchginfoIsRedundant(&var->ubchginfos[ubchginfoposs[v]]));
6618  SCIP_CALL( conflictAddBound(conflict, blkmem, set, stat, var, SCIP_BOUNDTYPE_UPPER, \
6619  &var->ubchginfos[ubchginfoposs[v]], SCIPbdchginfoGetNewbound(&var->ubchginfos[ubchginfoposs[v]])) );
6620  nbdchgs++;
6621  }
6622  }
6623  }
6624 
6625  if( v == nvars )
6626  {
6627  /* analyze the conflict set, and create conflict constraints on success */
6628  SCIP_CALL( conflictAnalyze(conflict, blkmem, set, stat, prob, tree, diving, 0, FALSE, nconss, nliterals, \
6629  nreconvconss, nreconvliterals) );
6630  }
6631 
6632  return SCIP_OKAY;
6633 }
6634 
6635 /** adds a weighted LP row to an aggregation row */
6636 static
6638  SCIP_SET* set, /**< global SCIP settings */
6639  SCIP_ROW* row, /**< LP row */
6640  SCIP_Real weight, /**< weight for scaling */
6641  SCIP_AGGRROW* aggrrow /**< aggregation row */
6642  )
6643 {
6644  assert(set != NULL);
6645  assert(row != NULL);
6646  assert(weight != 0.0);
6647 
6648  /* add minimal value to dual row's left hand side: y_i < 0 -> lhs, y_i > 0 -> rhs */
6649  if( weight < 0.0 )
6650  {
6651  assert(!SCIPsetIsInfinity(set, -row->lhs));
6652  SCIP_CALL( SCIPaggrRowAddRow(set->scip, aggrrow, row, weight, -1) );
6653  }
6654  else
6655  {
6656  assert(!SCIPsetIsInfinity(set, row->rhs));
6657  SCIP_CALL( SCIPaggrRowAddRow(set->scip, aggrrow, row, weight, +1) );
6658  }
6659  SCIPsetDebugMsg(set, " -> add %s row <%s>[%g,%g](lp depth: %d): dual=%g -> dualrhs=%g\n",
6660  row->local ? "local" : "global",
6661  SCIProwGetName(row), row->lhs - row->constant, row->rhs - row->constant,
6662  row->lpdepth, weight, SCIPaggrRowGetRhs(aggrrow));
6663 
6664  return SCIP_OKAY;
6665 }
6666 
6667 /** checks validity of an LP row and a corresponding weight */
6668 static
6670  SCIP_SET* set, /**< global SCIP settings */
6671  SCIP_ROW* row, /**< LP row */
6672  SCIP_Real weight, /**< weight for scaling */
6673  SCIP_Bool* zerocontribution /**< pointer to store whether every row entry is zero within tolerances */
6674  )
6675 {
6676  SCIP_Bool valid = TRUE;
6677 
6678  *zerocontribution = TRUE;
6679 
6680  /* dual solution values of 0.0 are always valid */
6681  if( REALABS(weight) > QUAD_EPSILON )
6682  {
6683  *zerocontribution = FALSE;
6684 
6685  /* check dual feasibility */
6686  if( (SCIPsetIsInfinity(set, -row->lhs) && weight > 0.0) || (SCIPsetIsInfinity(set, row->rhs) && weight < 0.0) )
6687  {
6688  int i;
6689 
6690  /* ignore slight numerical violations if the contribution of every component of the row is close to zero */
6691  if( weight > 0.0 )
6692  *zerocontribution = SCIPsetIsDualfeasZero(set, row->rhs * weight);
6693  else
6694  *zerocontribution = SCIPsetIsDualfeasZero(set, row->lhs * weight);
6695 
6696  for( i = 0; i < row->len && *zerocontribution; i++ )
6697  {
6698  if( !SCIPsetIsDualfeasZero(set, weight * row->vals[i]) )
6699  *zerocontribution = FALSE;
6700  }
6701 
6702  if( !(*zerocontribution) )
6703  {
6704  SCIPsetDebugMsg(set, " -> invalid dual solution value %g for row <%s>: lhs=%g, rhs=%g\n",
6705  weight, SCIProwGetName(row), row->lhs, row->rhs);
6706 
6707  valid = FALSE;
6708  }
6709  }
6710  }
6711 
6712  return valid;
6713 }
6714 
6715 /** sort local rows by increasing depth and number of nonzeros as tie-breaker */
6716 static
6718  SCIP_SET* set, /**< global SCIP settings */
6719  SCIP_AGGRROW* aggrrow, /**< aggregation row */
6720  SCIP_ROW** rows, /**< array of local rows */
6721  int* rowinds, /**< array of row indices */
6722  int* rowdepth, /**< array of LP depths */
6723  int nrows /**< number of local rows */
6724  )
6725 {
6726  int* rownnz;
6727  int i;
6728 
6729  assert(aggrrow != NULL);
6730  assert(rows != NULL);
6731  assert(nrows > 0);
6732  assert(rowinds != NULL);
6733  assert(rowdepth != NULL);
6734 
6735  /* sort row indices by increasing depth */
6736  SCIPsortIntInt(rowdepth, rowinds, nrows);
6737  assert(rowdepth[0] <= rowdepth[nrows-1]);
6738 
6739  SCIP_CALL( SCIPsetAllocBufferArray(set, &rownnz, nrows) );
6740 
6741  /* get number of nonzero entries for every row */
6742  for( i = 0; i < nrows; i++ )
6743  {
6744  SCIP_ROW* row = rows[rowinds[i]];
6745  assert(row != NULL);
6746 
6747  rownnz[i] = row->len;
6748  }
6749 
6750  /* since SCIP has no stable sorting function we sort each bucket separately */
6751  for( i = 0; i < nrows; i++ )
6752  {
6753  int j = i;
6754  int d = rowdepth[i];
6755 
6756  /* search for the next row with a greater depth */
6757  while( j+1 < nrows && rowdepth[j+1] == d )
6758  j++;
6759 
6760  /* the bucket has size one */
6761  if( j == i )
6762  continue;
6763 
6764  assert(j-i+1 <= nrows);
6765 
6766  /* sort row indices by increasing number of nonzero elements */
6767  SCIPsortIntIntInt(&rownnz[i], &rowdepth[i], &rowinds[i], j-i+1);
6768  assert(rownnz[i] <= rownnz[j]);
6769 
6770  i = j;
6771  } /*lint --e{850} i is modified in the body of the for loop */
6772 
6773 #ifndef NDEBUG
6774  for( i = 0; i < nrows-1; i++ )
6775  assert(rowdepth[i] < rowdepth[i+1] || (rowdepth[i] == rowdepth[i+1] && rownnz[i] <= rownnz[i+1]));
6776 #endif
6777 
6778  SCIPsetFreeBufferArray(set, &rownnz);
6779 
6780  return SCIP_OKAY;
6781 }
6782 
6783 /** adds locally valid rows to the proof constraint */
6784 static
6786  SCIP_SET* set, /**< global SCIP settings */
6787  SCIP_PROB* transprob, /**< transformed problem */
6788  SCIP_LP* lp, /**< LP data */
6789  SCIP_AGGRROW* proofrow, /**< aggregated row representing the proof */
6790  SCIP_ROW** rows, /**< array if locally valid rows */
6791  SCIP_Real* dualsols, /**< dual solution vector */
6792  int* localrowinds, /**< array of row indecies */
6793  int* localrowdepth, /**< array of row depths */
6794  int nlocalrows, /**< number of local rows stored in rows array */
6795  SCIP_Real* proofact, /**< pointer to store the activity of the proof constraint */
6796  int* validdepth, /**< pointer to store the depth where the proof constraint is valid */
6797  SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
6798  SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
6799  SCIP_Bool* valid /**< pointer store whether the proof constraint is valid */
6800  )
6801 {
6802  SCIP_Bool infdelta;
6803  int i;
6804 
6805  assert(set != NULL);
6806  assert(lp != NULL);
6807 
6808  *validdepth = 0;
6809 
6810  if( !set->conf_uselocalrows )
6811  return SCIP_OKAY;
6812 
6813  SCIPsetDebugMsg(set, "add local rows to dual proof:\n");
6814 
6815  /* check whether the proof is already valid, e.g., violated within the local bounds */
6816  *proofact = aggrRowGetMinActivity(set, transprob, proofrow, curvarlbs, curvarubs, &infdelta);
6817 
6818  /* we stop if the minimal activity is infinite but all variables have a finite activity delta (bad numerics) */
6819  if( !infdelta && SCIPsetIsInfinity(set, REALABS(*proofact)) )
6820  {
6821  *valid = FALSE;
6822  return SCIP_OKAY;
6823  }
6824 
6825  /* break if the proof is valid w.r.t local bounds
6826  * note: it can happen that the proof contains a variable with an infinite activity delta.
6827  * here, we don't break immediately because we might be able to fix it by adding local rows
6828  */
6829  if( !infdelta && SCIPsetIsGT(set, *proofact, SCIPaggrRowGetRhs(proofrow)) )
6830  {
6831  *valid = TRUE;
6832  return SCIP_OKAY;
6833  }
6834 
6835  /* sort local rows by depth */
6836  SCIP_CALL( sortLocalRows(set, proofrow, rows, localrowinds, localrowdepth, nlocalrows) );
6837 
6838  /* add successively local rows */
6839  for( i = 0; i < nlocalrows; ++i )
6840  {
6841  SCIP_ROW* row;
6842  int r;
6843 
6844  r = localrowinds[i];
6845  row = rows[r];
6846 
6847  assert(row != NULL);
6848  assert(row->len == 0 || row->cols != NULL);
6849  assert(row->len == 0 || row->vals != NULL);
6850  assert(row == lp->lpirows[r]);
6851  assert(row->local);
6852  assert(row->lpdepth == localrowdepth[i]);
6853 
6854  /* ignore dual solution values of 0.0 (in this case: y_i == 0) */
6855  if( REALABS(dualsols[r]) > 0.0 )
6856  {
6857 #ifndef NDEBUG
6858  SCIP_Bool zerocontribution;
6859 
6860  /* check dual feasibility */
6861  *valid = checkDualFeasibility(set, row, dualsols[r], &zerocontribution);
6862  assert(*valid);
6863  assert(!zerocontribution);
6864 #endif
6865 
6866  if( SCIPsetIsDualfeasZero(set, dualsols[r]) )
6867  continue;
6868 
6869  /* add row to dual proof */
6870  SCIP_CALL( addRowToAggrRow(set, row, -dualsols[r], proofrow) );
6871 
6872  /* update depth where the proof is valid */
6873  if( *validdepth < localrowdepth[i] )
6874  *validdepth = localrowdepth[i];
6875 
6876  /* get the new minimal activity */
6877  *proofact = aggrRowGetMinActivity(set, transprob, proofrow, curvarlbs, curvarubs, &infdelta);
6878 
6879  /* we stop if the minimal activity is infinite but all variables have a finite activity delta (bad numerics) */
6880  if( !infdelta && SCIPsetIsInfinity(set, REALABS(*proofact)) )
6881  {
6882  *valid = FALSE;
6883  goto TERMINATE;
6884  }
6885 
6886  /* break if the proof is valid w.r.t local bounds */
6887  if( !infdelta && SCIPsetIsGT(set, *proofact, SCIPaggrRowGetRhs(proofrow)) )
6888  {
6889  *valid = TRUE;
6890  break;
6891  }
6892  }
6893  }
6894 
6895  /* remove all nearly zero coefficients */
6896  SCIPaggrRowRemoveZeros(set->scip, proofrow, TRUE, valid);
6897 
6898  TERMINATE:
6899  if( !(*valid) )
6900  {
6901  SCIPsetDebugMsg(set, " -> proof is not valid: %g <= %g\n", *proofact, SCIPaggrRowGetRhs(proofrow));
6902  SCIPsetDebugMsg(set, " -> stop due to numerical troubles\n");
6903  }
6904  else
6905  {
6906  *proofact = aggrRowGetMinActivity(set, transprob, proofrow, curvarlbs, curvarubs, &infdelta);
6907 
6908  /* we stop if the minimal activity is infinite but all variables have a finite activity delta (bad numerics) */
6909  if( !infdelta && SCIPsetIsInfinity(set, REALABS(*proofact)) )
6910  {
6911  *valid = FALSE;
6912  SCIPsetDebugMsg(set, " -> proof is not valid: %g <= %g [infdelta: %d]\n", *proofact, SCIPaggrRowGetRhs(proofrow), infdelta);
6913  }
6914  else if( infdelta || SCIPsetIsLE(set, *proofact, SCIPaggrRowGetRhs(proofrow)) )
6915  {
6916  *valid = FALSE;
6917  SCIPsetDebugMsg(set, " -> proof is not valid: %g <= %g [infdelta: %d]\n", *proofact, SCIPaggrRowGetRhs(proofrow), infdelta);
6918  }
6919  }
6920 
6921  return SCIP_OKAY;
6922 }
6923 
6924 /** calculates a Farkas proof from the current dual LP solution */
6925 static
6927  SCIP_SET* set, /**< global SCIP settings */
6928  SCIP_PROB* prob, /**< transformed problem */
6929  SCIP_LP* lp, /**< LP data */
6930  SCIP_LPI* lpi, /**< LPI data */
6931  SCIP_TREE* tree, /**< tree data */
6932  SCIP_AGGRROW* farkasrow, /**< aggregated row representing the proof */
6933  SCIP_Real* farkasact, /**< maximal activity of the proof constraint */
6934  int* validdepth, /**< pointer to store the valid depth of the proof constraint */
6935  SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
6936  SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
6937  SCIP_Bool* valid /**< pointer store whether the proof constraint is valid */
6938  )
6939 {
6940  SCIP_ROW** rows;
6941  SCIP_Real* dualfarkas;
6942  SCIP_ROW* row;
6943  int* localrowinds;
6944  int* localrowdepth;
6945  SCIP_Bool infdelta;
6946  int nlocalrows;
6947  int nrows;
6948  int r;
6949 
6950  assert(set != NULL);
6951  assert(prob != NULL);
6952  assert(lp != NULL);
6953  assert(lp->flushed);
6954  assert(lp->solved);
6955  assert(curvarlbs != NULL);
6956  assert(curvarubs != NULL);
6957  assert(valid != NULL);
6958 
6961 
6962  /* get LP rows and problem variables */
6963  rows = SCIPlpGetRows(lp);
6964  nrows = SCIPlpGetNRows(lp);
6965  assert(nrows == 0 || rows != NULL);
6966  assert(nrows == lp->nlpirows);
6967 
6968  /* it can happen that infeasibility is detetected within LP presolve. in that case, the LP solver may not be able to
6969  * to return the dual ray.
6970  */
6971  if( !SCIPlpiHasDualRay(lpi) )
6972  {
6973  *valid = FALSE;
6974  return SCIP_OKAY;
6975  }
6976 
6977  assert(farkasrow != NULL);
6978 
6979  /* allocate temporary memory */
6980  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualfarkas, nrows) );
6981  BMSclearMemoryArray(dualfarkas, nrows);
6982 
6983  /* get dual Farkas values of rows */
6984  SCIP_CALL( SCIPlpiGetDualfarkas(lpi, dualfarkas) );
6985 
6986  localrowinds = NULL;
6987  localrowdepth = NULL;
6988  nlocalrows = 0;
6989 
6990  /* calculate the Farkas row */
6991  (*valid) = TRUE;
6992  (*validdepth) = 0;
6993 
6994  for( r = 0; r < nrows; ++r )
6995  {
6996  row = rows[r];
6997  assert(row != NULL);
6998  assert(row->len == 0 || row->cols != NULL);
6999  assert(row->len == 0 || row->vals != NULL);
7000  assert(row == lp->lpirows[r]);
7001 
7002  /* ignore dual ray values of 0.0 (in this case: y_i == z_i == 0) */
7003  if( REALABS(dualfarkas[r]) > 0.0 )
7004  {
7005  SCIP_Bool zerocontribution;
7006 
7007  /* check dual feasibility */
7008  *valid = checkDualFeasibility(set, row, dualfarkas[r], &zerocontribution);
7009 
7010  if( !(*valid) )
7011  goto TERMINATE;
7012 
7013  if( zerocontribution )
7014  continue;
7015 
7016  if( SCIPsetIsDualfeasZero(set, dualfarkas[r]) )
7017  continue;
7018 
7019  if( !row->local )
7020  {
7021  SCIP_CALL( addRowToAggrRow(set, row, -dualfarkas[r], farkasrow) );
7022 
7023  /* due to numerical reasons we want to stop */
7024  if( REALABS(SCIPaggrRowGetRhs(farkasrow)) > NUMSTOP )
7025  {
7026  (*valid) = FALSE;
7027  goto TERMINATE;
7028  }
7029  }
7030  else
7031  {
7032  int lpdepth = SCIProwGetLPDepth(row);
7033 
7034  if( nlocalrows == 0 && lpdepth < SCIPtreeGetFocusDepth(tree) )
7035  {
7036  SCIP_CALL( SCIPsetAllocBufferArray(set, &localrowinds, nrows-r) );
7037  SCIP_CALL( SCIPsetAllocBufferArray(set, &localrowdepth, nrows-r) );
7038  }
7039 
7040  if( lpdepth < SCIPtreeGetFocusDepth(tree) )
7041  {
7042  assert(localrowinds != NULL);
7043  assert(localrowdepth != NULL);
7044 
7045  localrowinds[nlocalrows] = r;
7046  localrowdepth[nlocalrows++] = lpdepth;
7047  }
7048  }
7049  }
7050  }
7051 
7052  /* remove all coefficients that are too close to zero */
7053  SCIPaggrRowRemoveZeros(set->scip, farkasrow, TRUE, valid);
7054 
7055  if( !(*valid) )
7056  goto TERMINATE;
7057 
7058  infdelta = FALSE;
7059 
7060  /* calculate the current Farkas activity, always using the best bound w.r.t. the Farkas coefficient */
7061  *farkasact = aggrRowGetMinActivity(set, prob, farkasrow, curvarlbs, curvarubs, &infdelta);
7062 
7063  SCIPsetDebugMsg(set, " -> farkasact=%g farkasrhs=%g [infdelta: %d], \n",
7064  (*farkasact), SCIPaggrRowGetRhs(farkasrow), infdelta);
7065 
7066  /* The constructed proof is not valid, this can happen due to numerical reasons,
7067  * e.g., we only consider rows r with !SCIPsetIsZero(set, dualfarkas[r]),
7068  * or because of local rows were ignored so far.
7069  * Due to the latter case, it might happen at least one variable contributes
7070  * with an infinite value to the activity (see: https://git.zib.de/integer/scip/issues/2743)
7071  */
7072  if( infdelta || SCIPsetIsFeasLE(set, *farkasact, SCIPaggrRowGetRhs(farkasrow)))
7073  {
7074  /* add contribution of local rows */
7075  if( nlocalrows > 0 && set->conf_uselocalrows > 0 )
7076  {
7077  SCIP_CALL( addLocalRows(set, prob, lp, farkasrow, rows, dualfarkas, localrowinds, localrowdepth,
7078  nlocalrows, farkasact, validdepth, curvarlbs, curvarubs, valid) );
7079  }
7080  else
7081  {
7082  (*valid) = FALSE;
7083  SCIPsetDebugMsg(set, " -> proof is not valid to due infinite activity delta\n",
7084  *farkasact, SCIPaggrRowGetRhs(farkasrow));
7085  }
7086  }
7087 
7088  TERMINATE:
7089 
7090  SCIPfreeBufferArrayNull(set->scip, &localrowdepth);
7091  SCIPfreeBufferArrayNull(set->scip, &localrowinds);
7092  SCIPsetFreeBufferArray(set, &dualfarkas);
7093 
7094  return SCIP_OKAY;
7095 }
7096 
7097 /** calculates a Farkas proof from the current dual LP solution */
7098 static
7100  SCIP_SET* set, /**< global SCIP settings */
7101  SCIP_PROB* transprob, /**< transformed problem */
7102  SCIP_LP* lp, /**< LP data */
7103  SCIP_LPI* lpi, /**< LPI data */
7104  SCIP_TREE* tree, /**< tree data */
7105  SCIP_AGGRROW* farkasrow, /**< aggregated row representing the proof */
7106  SCIP_Real* farkasact, /**< maximal activity of the proof constraint */
7107  int* validdepth, /**< pointer to store the valid depth of the proof constraint */
7108  SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
7109  SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
7110  SCIP_Bool* valid /**< pointer store whether the proof constraint is valid */
7111  )
7112 {
7113  SCIP_RETCODE retcode;
7114  SCIP_ROW** rows;
7115  SCIP_ROW* row;
7116  SCIP_Real* primsols;
7117  SCIP_Real* dualsols;
7118  SCIP_Real* redcosts;
7119  int* localrowinds;
7120  int* localrowdepth;
7121  SCIP_Real maxabsdualsol;
7122  SCIP_Bool infdelta;
7123  int nlocalrows;
7124  int nrows;
7125  int ncols;
7126  int r;
7127 
7128  assert(set != NULL);
7129  assert(transprob != NULL);
7130  assert(lp != NULL);
7131  assert(lp->flushed);
7132  assert(lp->solved);
7133  assert(curvarlbs != NULL);
7134  assert(curvarubs != NULL);
7135  assert(valid != NULL);
7136 
7137  *validdepth = 0;
7138  *valid = TRUE;
7139 
7140  localrowinds = NULL;
7141  localrowdepth = NULL;
7142  nlocalrows = 0;
7143 
7144  /* get LP rows and problem variables */
7145  rows = SCIPlpGetRows(lp);
7146  nrows = SCIPlpGetNRows(lp);
7147  ncols = SCIPlpGetNCols(lp);
7148  assert(nrows == 0 || rows != NULL);
7149  assert(nrows == lp->nlpirows);
7150 
7151  /* get temporary memory */
7152  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsols, ncols) );
7153  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualsols, nrows) );
7154  SCIP_CALL( SCIPsetAllocBufferArray(set, &redcosts, ncols) );
7155 
7156  /* get solution from LPI */
7157  retcode = SCIPlpiGetSol(lpi, NULL, primsols, dualsols, NULL, redcosts);
7158  if( retcode == SCIP_LPERROR ) /* on an error in the LP solver, just abort the conflict analysis */
7159  {
7160  (*valid) = FALSE;
7161  goto TERMINATE;
7162  }
7163  SCIP_CALL( retcode );
7164 #ifdef SCIP_DEBUG
7165  {
7166  SCIP_Real objval;
7167  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
7168  SCIPsetDebugMsg(set, " -> LP objval: %g\n", objval);
7169  }
7170 #endif
7171 
7172  /* check whether the dual solution is numerically stable */
7173  maxabsdualsol = 0;
7174  for( r = 0; r < nrows; r++ )
7175  {
7176  SCIP_Real absdualsol = REALABS(dualsols[r]);
7177 
7178  if( absdualsol > maxabsdualsol )
7179  maxabsdualsol = absdualsol;
7180  }
7181 
7182  /* don't consider dual solution with maxabsdualsol > 1e+07, this would almost cancel out the objective constraint */
7183  if( maxabsdualsol > 1e+07 )
7184  {
7185  (*valid) = FALSE;
7186  goto TERMINATE;
7187  }
7188 
7189  /* clear the proof */
7190  SCIPaggrRowClear(farkasrow);
7191 
7192  /* Let y be the dual solution and r be the reduced cost vector. Let z be defined as
7193  * z_i := y_i if i is a global row,
7194  * z_i := 0 if i is a local row.
7195  * Define the set X := {x | lhs <= Ax <= rhs, lb <= x <= ub, c^Tx <= c*}, with c* being the current primal bound.
7196  * Then the following inequalities are valid for all x \in X:
7197  * - c* <= -c^Tx
7198  * <=> z^TAx - c* <= (z^TA - c^T) x
7199  * <=> z^TAx - c* <= (y^TA - c^T - (y-z)^TA) x
7200  * <=> z^TAx - c* <= (-r^T - (y-z)^TA) x (dual feasibility of (y,r): y^TA + r^T == c^T)
7201  * Because lhs <= Ax <= rhs and lb <= x <= ub, the inequality can be relaxed to give
7202  * min{z^Tq | lhs <= q <= rhs} - c* <= max{(-r^T - (y-z)^TA) x | lb <= x <= ub}, or X = {}.
7203  *
7204  * The resulting dual row is: z^T{lhs,rhs} - c* <= (-r^T - (y-z)^TA){lb,ub},
7205  * where lhs, rhs, lb, and ub are selected in order to maximize the feasibility of the row.
7206  */
7207 
7208  /* add the objective function to the aggregation row with current cutoff bound as right-hand side
7209  *
7210  * use a slightly tighter cutoff bound, because solutions with equal objective value should also be declared
7211  * infeasible
7212  */
7213  SCIP_CALL( SCIPaggrRowAddObjectiveFunction(set->scip, farkasrow, lp->cutoffbound - SCIPsetSumepsilon(set), 1.0) );
7214 
7215  /* dual row: z^T{lhs,rhs} - c* <= (-r^T - (y-z)^TA){lb,ub}
7216  * process rows: add z^T{lhs,rhs} to the dual row's left hand side, and -(y-z)^TA to the dual row's coefficients
7217  */
7218  for( r = 0; r < nrows; ++r )
7219  {
7220  row = rows[r];
7221  assert(row != NULL);
7222  assert(row->len == 0 || row->cols != NULL);
7223  assert(row->len == 0 || row->vals != NULL);
7224  assert(row == lp->lpirows[r]);
7225 
7226  /* ignore dual solution values of 0.0 (in this case: y_i == z_i == 0) */
7227  if( REALABS(dualsols[r]) > 0.0 )
7228  {
7229  SCIP_Bool zerocontribution;
7230 
7231  /* check dual feasibility */
7232  *valid = checkDualFeasibility(set, row, dualsols[r], &zerocontribution);
7233 
7234  if( !(*valid) )
7235  goto TERMINATE;
7236 
7237  if( zerocontribution )
7238  continue;
7239 
7240  if( SCIPsetIsDualfeasZero(set, dualsols[r]) )
7241  continue;
7242 
7243  /* skip local row */
7244  if( !row->local )
7245  {
7246  SCIP_CALL( addRowToAggrRow(set, row, -dualsols[r], farkasrow) );
7247 
7248  /* due to numerical reasons we want to stop */
7249  if( REALABS(SCIPaggrRowGetRhs(farkasrow)) > NUMSTOP )
7250  {
7251  (*valid) = FALSE;
7252  goto TERMINATE;
7253  }
7254  }
7255  else
7256  {
7257  int lpdepth = SCIProwGetLPDepth(row);
7258 
7259  if( nlocalrows == 0 && lpdepth < SCIPtreeGetFocusDepth(tree) )
7260  {
7261  SCIP_CALL( SCIPsetAllocBufferArray(set, &localrowinds, nrows-r) );
7262  SCIP_CALL( SCIPsetAllocBufferArray(set, &localrowdepth, nrows-r) );
7263  }
7264 
7265  if( lpdepth < SCIPtreeGetFocusDepth(tree) )
7266  {
7267  assert(localrowinds != NULL);
7268  assert(localrowdepth != NULL);
7269 
7270  localrowinds[nlocalrows] = r;
7271  localrowdepth[nlocalrows++] = lpdepth;
7272  }
7273  }
7274  }
7275  }
7276 
7277  /* remove all nearly zero coefficients */
7278  SCIPaggrRowRemoveZeros(set->scip, farkasrow, TRUE, valid);
7279 
7280  if( !(*valid) )
7281  goto TERMINATE;
7282 
7283  infdelta = FALSE;
7284 
7285  /* check validity of the proof */
7286  *farkasact = aggrRowGetMinActivity(set, transprob, farkasrow, curvarlbs, curvarubs, &infdelta);
7287 
7288  SCIPsetDebugMsg(set, " -> farkasact=%g farkasrhs=%g [infdelta: %d], \n",
7289  (*farkasact), SCIPaggrRowGetRhs(farkasrow), infdelta);
7290 
7291  /* The constructed proof is not valid, this can happen due to numerical reasons,
7292  * e.g., we only consider rows r with !SCIPsetIsZero(set, dualsol[r]),
7293  * or because of local rows were ignored so far.
7294  * Due to the latter case, it might happen at least one variable contributes
7295  * with an infinite value to the activity (see: https://git.zib.de/integer/scip/issues/2743)
7296  */
7297  if( infdelta || SCIPsetIsFeasLE(set, *farkasact, SCIPaggrRowGetRhs(farkasrow)))
7298  {
7299  /* add contribution of local rows */
7300  if( nlocalrows > 0 && set->conf_uselocalrows > 0 )
7301  {
7302  SCIP_CALL( addLocalRows(set, transprob, lp, farkasrow, rows, dualsols, localrowinds, localrowdepth,
7303  nlocalrows, farkasact, validdepth, curvarlbs, curvarubs, valid) );
7304  }
7305  else
7306  {
7307  (*valid) = FALSE;
7308  SCIPsetDebugMsg(set, " -> proof is not valid to due infinite activity delta\n",
7309  *farkasact, SCIPaggrRowGetRhs(farkasrow));
7310  }
7311  }
7312 
7313  TERMINATE:
7314 
7315  SCIPfreeBufferArrayNull(set->scip, &localrowdepth);
7316  SCIPfreeBufferArrayNull(set->scip, &localrowinds);
7317  SCIPsetFreeBufferArray(set, &redcosts);
7318  SCIPsetFreeBufferArray(set, &dualsols);
7319  SCIPsetFreeBufferArray(set, &primsols);
7320 
7321  return SCIP_OKAY;
7322 }
7323 
7324 #ifdef SCIP_DEBUG
7325 static
7327  SCIP_SET* set, /**< global SCIP settings */
7328  SCIP_Real minact, /**< min activity */
7329  SCIP_Real rhs, /**< right hand side */
7330  const char* infostr /**< additional info for this debug message, or NULL */
7331  )
7332 {
7333  SCIPsetDebugMsg(set, "-> %sminact=%.15g rhs=%.15g violation=%.15g\n",infostr != NULL ? infostr : "" , minact, rhs, minact - rhs);
7334 }
7335 #else
7336 #define debugPrintViolationInfo(...) /**/
7337 #endif
7338 
7339 /** apply coefficient tightening */
7340 static
7342  SCIP_SET* set, /**< global SCIP settings */
7343  SCIP_PROOFSET* proofset, /**< proof set */
7344  int* nchgcoefs, /**< pointer to store number of changed coefficients */
7345  SCIP_Bool* redundant /**< pointer to store whether the proof set is redundant */
7346  )
7347 {
7348 #ifdef SCIP_DEBUG
7349  SCIP_Real absmax = 0.0;
7350  SCIP_Real absmin = SCIPsetInfinity(set);
7351  int i;
7352 
7353  for( i = 0; i < proofset->nnz; i++ )
7354  {
7355  absmax = MAX(absmax, REALABS(proofset->vals[i]));
7356  absmin = MIN(absmin, REALABS(proofset->vals[i]));
7357  }
7358 #endif
7359 
7360  (*redundant) = SCIPcutsTightenCoefficients(set->scip, FALSE, proofset->vals, &proofset->rhs, proofset->inds, &proofset->nnz, nchgcoefs);
7361 
7362 #ifdef SCIP_DEBUG
7363  {
7364  SCIP_Real newabsmax = 0.0;
7365  SCIP_Real newabsmin = SCIPsetInfinity(set);
7366 
7367  for( i = 0; i < proofset->nnz; i++ )
7368  {
7369  newabsmax = MAX(newabsmax, REALABS(proofset->vals[i]));
7370  newabsmin = MIN(newabsmin, REALABS(proofset->vals[i]));
7371  }
7372 
7373  SCIPsetDebugMsg(set, "coefficient tightening: [%.15g,%.15g] -> [%.15g,%.15g] (nnz: %d, nchg: %d rhs: %.15g)\n",
7374  absmin, absmax, newabsmin, newabsmax, proofsetGetNVars(proofset), *nchgcoefs, proofsetGetRhs(proofset));
7375  printf("coefficient tightening: [%.15g,%.15g] -> [%.15g,%.15g] (nnz: %d, nchg: %d rhs: %.15g)\n",
7376  absmin, absmax, newabsmin, newabsmax, proofsetGetNVars(proofset), *nchgcoefs, proofsetGetRhs(proofset));
7377  }
7378 #endif
7379 }
7380 
7381 /** try to generate alternative proofs by applying subadditive functions */
7382 static
7384  SCIP_CONFLICT* conflict, /**< conflict analysis data */
7385  SCIP_SET* set, /**< global SCIP settings */
7386  SCIP_STAT* stat, /**< dynamic SCIP statistics */
7387  SCIP_PROB* transprob, /**< transformed problem */
7388  SCIP_TREE* tree, /**< tree data */
7389  BMS_BLKMEM* blkmem, /**< block memory */
7390  SCIP_AGGRROW* proofrow, /**< proof rows data */
7391  SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
7392  SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
7393  SCIP_CONFTYPE conflicttype /**< type of the conflict */
7394  )
7395 {
7396  SCIP_VAR** vars;
7397  SCIP_SOL* refsol;
7398  SCIP_Real* cutcoefs;
7399  SCIP_Real cutefficacy;
7400  SCIP_Real cutrhs;
7401  SCIP_Real proofefficiacy;
7402  SCIP_Real efficiacynorm;
7403  SCIP_Bool islocal;
7404  SCIP_Bool cutsuccess;
7405  SCIP_Bool success;
7406  SCIP_Bool infdelta;
7407  int* cutinds;
7408  int* inds;
7409  int cutnnz;
7410  int nnz;
7411  int nvars;
7412  int i;
7413 
7414  vars = SCIPprobGetVars(transprob);
7415  nvars = SCIPprobGetNVars(transprob);
7416 
7417  inds = SCIPaggrRowGetInds(proofrow);
7418  nnz = SCIPaggrRowGetNNz(proofrow);
7419 
7420  proofefficiacy = aggrRowGetMinActivity(set, transprob, proofrow, curvarlbs, curvarubs, &infdelta);
7421 
7422  if( infdelta )
7423  return SCIP_OKAY;
7424 
7425  proofefficiacy -= SCIPaggrRowGetRhs(proofrow);
7426 
7427  efficiacynorm = SCIPaggrRowCalcEfficacyNorm(set->scip, proofrow);
7428  proofefficiacy /= MAX(1e-6, efficiacynorm);
7429 
7430  /* create reference solution */
7431  SCIP_CALL( SCIPcreateSol(set->scip, &refsol, NULL) );
7432 
7433  /* initialize with average solution */
7434  for( i = 0; i < nvars; i++ )
7435  {
7436  SCIP_CALL( SCIPsolSetVal(refsol, set, stat, tree, vars[i], SCIPvarGetAvgSol(vars[i])) );
7437  }
7438 
7439  /* set all variables that are part of the proof to its active local bound */
7440  for( i = 0; i < nnz; i++ )
7441  {
7442  SCIP_Real val = SCIPaggrRowGetProbvarValue(proofrow, inds[i]);
7443 
7444  if( val > 0.0 )
7445  {
7446  SCIP_CALL( SCIPsolSetVal(refsol, set, stat, tree, vars[inds[i]], curvarubs[inds[i]]) );
7447  }
7448  else
7449  {
7450  SCIP_CALL( SCIPsolSetVal(refsol, set, stat, tree, vars[inds[i]], curvarlbs[inds[i]]) );
7451  }
7452  }
7453 
7454  SCIP_CALL( SCIPsetAllocBufferArray(set, &cutcoefs, nvars) );
7455  SCIP_CALL( SCIPsetAllocBufferArray(set, &cutinds, nvars) );
7456 
7457  cutnnz = 0;
7458  cutefficacy = -SCIPsetInfinity(set);
7459 
7460  /* apply flow cover */
7461  SCIP_CALL( SCIPcalcFlowCover(set->scip, refsol, POSTPROCESS, BOUNDSWITCH, ALLOWLOCAL, proofrow, \
7462  cutcoefs, &cutrhs, cutinds, &cutnnz, &cutefficacy, NULL, &islocal, &cutsuccess) );
7463  success = cutsuccess;
7464 
7465  /* apply MIR */
7467  NULL, NULL, MINFRAC, MAXFRAC, proofrow, cutcoefs, &cutrhs, cutinds, &cutnnz, &cutefficacy, NULL, \
7468  &islocal, &cutsuccess) );
7469  success = (success || cutsuccess);
7470 
7471  /* replace the current proof */
7472  if( success && !islocal && SCIPsetIsPositive(set, cutefficacy) && cutefficacy * nnz > proofefficiacy * cutnnz )
7473  {
7474  SCIP_PROOFSET* alternativeproofset;
7475  SCIP_Bool redundant;
7476  int nchgcoefs;
7477 
7478  SCIP_CALL( proofsetCreate(&alternativeproofset, blkmem) );
7479  alternativeproofset->conflicttype = (conflicttype == SCIP_CONFTYPE_INFEASLP ? SCIP_CONFTYPE_ALTINFPROOF : SCIP_CONFTYPE_ALTBNDPROOF);
7480 
7481  SCIP_CALL( proofsetAddSparseData(alternativeproofset, blkmem, cutcoefs, cutinds, cutnnz, cutrhs) );
7482 
7483  /* apply coefficient tightening */
7484  tightenCoefficients(set, alternativeproofset, &nchgcoefs, &redundant);
7485 
7486  if( !redundant )
7487  {
7488  SCIP_CALL( conflictInsertProofset(conflict, set, alternativeproofset) );
7489  }
7490  else
7491  {
7492  proofsetFree(&alternativeproofset, blkmem);
7493  }
7494  } /*lint !e438*/
7495 
7496  SCIPsetFreeBufferArray(set, &cutinds);
7497  SCIPsetFreeBufferArray(set, &cutcoefs);
7498 
7499  SCIP_CALL( SCIPfreeSol(set->scip, &refsol) );
7500 
7501  return SCIP_OKAY;
7502 }
7503 
7504 /** tighten a given infeasibility proof a^Tx <= b with minact > b w.r.t. local bounds
7505  *
7506  * 1) Apply cut generating functions
7507  * - c-MIR
7508  * - Flow-cover
7509  * - TODO: implement other subadditive functions
7510  * 2) Remove continuous variables contributing with its global bound
7511  * - TODO: implement a variant of non-zero-cancellation
7512  */
7513 static
7515  SCIP_CONFLICT* conflict, /**< conflict analysis data */
7516  SCIP_SET* set, /**< global SCIP settings */
7517  SCIP_STAT* stat, /**< dynamic SCIP statistics */
7518  BMS_BLKMEM* blkmem, /**< block memory */
7519  SCIP_PROB* transprob, /**< transformed problem */
7520  SCIP_TREE* tree, /**< tree data */
7521  SCIP_AGGRROW* proofrow, /**< aggregated row representing the proof */
7522  int validdepth, /**< depth where the proof is valid */
7523  SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
7524  SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
7525  SCIP_Bool initialproof /**< do we analyze the initial reason of infeasibility? */
7526  )
7527 {
7528  SCIP_VAR** vars;
7529  SCIP_Real* vals;
7530  int* inds;
7531  SCIP_PROOFSET* proofset;
7532  SCIP_Bool valid;
7533  SCIP_Bool redundant;
7534  int nnz;
7535  int nchgcoefs;
7536  int nbinvars;
7537  int ncontvars;
7538  int nintvars;
7539  int i;
7540 
7541  assert(conflict->proofset != NULL);
7542  assert(curvarlbs != NULL);
7543  assert(curvarubs != NULL);
7544 
7545  vars = SCIPprobGetVars(transprob);
7546  nbinvars = 0;
7547  nintvars = 0;
7548  ncontvars = 0;
7549 
7550  inds = SCIPaggrRowGetInds(proofrow);
7551  nnz = SCIPaggrRowGetNNz(proofrow);
7552 
7553  /* count number of binary, integer, and continuous variables */
7554  for( i = 0; i < nnz; i++ )
7555  {
7556  assert(SCIPvarGetProbindex(vars[inds[i]]) == inds[i]);
7557 
7558  if( SCIPvarIsBinary(vars[inds[i]]) )
7559  ++nbinvars;
7560  else if( SCIPvarIsIntegral(vars[inds[i]]) )
7561  ++nintvars;
7562  else
7563  ++ncontvars;
7564  }
7565 
7566  SCIPsetDebugMsg(set, "start dual proof tightening:\n");
7567  SCIPsetDebugMsg(set, "-> tighten dual proof: nvars=%d (bin=%d, int=%d, cont=%d)\n",
7568  nnz, nbinvars, nintvars, ncontvars);
7569  debugPrintViolationInfo(set, aggrRowGetMinActivity(set, transprob, proofrow, curvarlbs, curvarubs, NULL), SCIPaggrRowGetRhs(proofrow), NULL);
7570 
7571  /* try to find an alternative proof of local infeasibility that is stronger */
7572  if( set->conf_sepaaltproofs )
7573  {
7574  SCIP_CALL( separateAlternativeProofs(conflict, set, stat, transprob, tree, blkmem, proofrow, curvarlbs, curvarubs,
7575  conflict->conflictset->conflicttype) );
7576  }
7577 
7578  if( initialproof )
7579  proofset = conflict->proofset;
7580  else
7581  {
7582  SCIP_CALL( proofsetCreate(&proofset, blkmem) );
7583  }
7584 
7585  /* start with a proofset containing all variables with a non-zero coefficient in the dual proof */
7586  SCIP_CALL( proofsetAddAggrrow(proofset, set, blkmem, proofrow) );
7587  proofset->conflicttype = conflict->conflictset->conflicttype;
7588  proofset->validdepth = validdepth;
7589 
7590  /* get proof data */
7591  vals = proofsetGetVals(proofset);
7592  inds = proofsetGetInds(proofset);
7593  nnz = proofsetGetNVars(proofset);
7594 
7595 #ifndef NDEBUG
7596  for( i = 0; i < nnz; i++ )
7597  {
7598  int idx = inds[i];
7599  if( vals[i] > 0.0 )
7600  assert(!SCIPsetIsInfinity(set, -curvarlbs[idx]));
7601  if( vals[i] < 0.0 )
7602  assert(!SCIPsetIsInfinity(set, curvarubs[idx]));
7603  }
7604 #endif
7605 
7606  /* remove continuous variable contributing with their global bound
7607  *
7608  * todo: check whether we also want to do that for bound exceeding proofs, but then we cannot update the
7609  * conflict anymore
7610  */
7611  if( proofset->conflicttype == SCIP_CONFTYPE_INFEASLP )
7612  {
7613  /* remove all continuous variables that have equal global and local bounds (ub or lb depend on the sign)
7614  * from the proof
7615  */
7616 
7617  for( i = 0; i < nnz && nnz > 1; )
7618  {
7619  SCIP_Real val;
7620  int idx = inds[i];
7621 
7622  assert(vars[idx] != NULL);
7623 
7624  val = vals[i];
7625  assert(!SCIPsetIsZero(set, val));
7626 
7627  /* skip integral variables */
7628  if( SCIPvarGetType(vars[idx]) != SCIP_VARTYPE_CONTINUOUS && SCIPvarGetType(vars[idx]) != SCIP_VARTYPE_IMPLINT )
7629  {
7630  i++;
7631  continue;
7632  }
7633  else
7634  {
7635  SCIP_Real glbbd;
7636  SCIP_Real locbd;
7637 
7638  /* get appropriate global and local bounds */
7639  glbbd = (val < 0.0 ? SCIPvarGetUbGlobal(vars[idx]) : SCIPvarGetLbGlobal(vars[idx]));
7640  locbd = (val < 0.0 ? curvarubs[idx] : curvarlbs[idx]);
7641 
7642  if( !SCIPsetIsEQ(set, glbbd, locbd) )
7643  {
7644  i++;
7645  continue;
7646  }
7647 
7648  SCIPsetDebugMsg(set, "-> remove continuous variable <%s>: glb=[%g,%g], loc=[%g,%g], val=%g\n",
7649  SCIPvarGetName(vars[idx]), SCIPvarGetLbGlobal(vars[idx]), SCIPvarGetUbGlobal(vars[idx]),
7650  curvarlbs[idx], curvarubs[idx], val);
7651 
7652  proofsetCancelVarWithBound(proofset, set, vars[idx], i, &valid);
7653  assert(valid); /* this should be always fulfilled at this place */
7654 
7655  --nnz;
7656  }
7657  }
7658  }
7659 
7660  /* apply coefficient tightening to initial proof */
7661  tightenCoefficients(set, proofset, &nchgcoefs, &redundant);
7662 
7663  /* it can happen that the constraints is almost globally redundant w.r.t to the maximal activity,
7664  * e.g., due to numerics. in this case, we want to discard the proof
7665  */
7666  if( redundant )
7667  {
7668 #ifndef NDEBUG
7669  SCIP_Real eps = MIN(0.01, 10.0*set->num_feastol);
7670  assert(proofset->rhs - getMaxActivity(set, transprob, proofset->vals, proofset->inds, proofset->nnz, NULL, NULL) < eps);
7671 #endif
7672  if( initialproof )
7673  {
7674  proofsetClear(proofset);
7675  }
7676  else
7677  {
7678  proofsetFree(&proofset, blkmem);
7679  }
7680  }
7681  else
7682  {
7683  if( !initialproof )
7684  {
7685  SCIP_CALL( conflictInsertProofset(conflict, set, proofset) );
7686  }
7687 
7688  if( nchgcoefs > 0 )
7689  {
7690  if( proofset->conflicttype == SCIP_CONFTYPE_INFEASLP )
7692  else if( proofset->conflicttype == SCIP_CONFTYPE_BNDEXCEEDING )
7694  }
7695  }
7696 
7697  return SCIP_OKAY;
7698 }
7699 
7700 /** perform conflict analysis based on a dual unbounded ray
7701  *
7702  * given an aggregation of rows lhs <= a^Tx such that lhs > maxactivity. if the constraint has size one we add a
7703  * bound change instead of the constraint.
7704  */
7705 static
7707  SCIP_CONFLICT* conflict, /**< conflict analysis data */
7708  SCIP_SET* set, /**< global SCIP settings */
7709  SCIP_STAT* stat, /**< dynamic SCIP statistics */
7710  BMS_BLKMEM* blkmem, /**< block memory */
7711  SCIP_PROB* origprob, /**< original problem */
7712  SCIP_PROB* transprob, /**< transformed problem */
7713  SCIP_TREE* tree, /**< tree data */
7714  SCIP_REOPT* reopt, /**< reoptimization data */
7715  SCIP_LP* lp, /**< LP data */
7716  SCIP_AGGRROW* proofrow, /**< aggregated row representing the proof */
7717  int validdepth, /**< valid depth of the dual proof */
7718  SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
7719  SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
7720  SCIP_Bool initialproof, /**< do we analyze the initial reason of infeasibility? */
7721  SCIP_Bool* globalinfeasible, /**< pointer to store whether global infeasibility could be proven */
7722  SCIP_Bool* success /**< pointer to store success result */
7723  )
7724 {
7725  SCIP_Real rhs;
7726  SCIP_Real minact;
7727  SCIP_Bool infdelta;
7728  int nnz;
7729 
7730  assert(set != NULL);
7731  assert(transprob != NULL);
7732  assert(validdepth >= 0);
7733  assert(validdepth == 0 || validdepth < SCIPtreeGetFocusDepth(tree));
7734 
7735  /* get sparse data */
7736  nnz = SCIPaggrRowGetNNz(proofrow);
7737  rhs = SCIPaggrRowGetRhs(proofrow);
7738 
7739  *globalinfeasible = FALSE;
7740  *success = FALSE;
7741 
7742  /* get minimal activity w.r.t. local bounds */
7743  minact = aggrRowGetMinActivity(set, transprob, proofrow, curvarlbs, curvarubs, &infdelta);
7744 
7745  if( infdelta )
7746  return SCIP_OKAY;
7747 
7748  /* only run is the proof proves local infeasibility */
7749  if( SCIPsetIsFeasLE(set, minact, rhs) )
7750  return SCIP_OKAY;
7751 
7752  /* if the farkas-proof is empty, the node and its sub tree can be cut off completely */
7753  if( nnz == 0 )
7754  {
7755  SCIPsetDebugMsg(set, " -> empty farkas-proof in depth %d cuts off sub tree at depth %d\n", SCIPtreeGetFocusDepth(tree), validdepth);
7756 
7757  SCIP_CALL( SCIPnodeCutoff(tree->path[validdepth], set, stat, tree, transprob, origprob, reopt, lp, blkmem) );
7758 
7759  *globalinfeasible = TRUE;
7760  *success = TRUE;
7761 
7762  ++conflict->ndualproofsinfsuccess;
7763 
7764  return SCIP_OKAY;
7765  }
7766 
7767  /* try to enforce the constraint based on a dual ray */
7768  SCIP_CALL( tightenDualproof(conflict, set, stat, blkmem, transprob, tree, proofrow, validdepth,
7769  curvarlbs, curvarubs, initialproof) );
7770 
7771  if( *globalinfeasible )
7772  {
7773  SCIPsetDebugMsg(set, "detect global: cutoff root node\n");
7774  SCIP_CALL( SCIPnodeCutoff(tree->path[0], set, stat, tree, transprob, origprob, reopt, lp, blkmem) );
7775  *success = TRUE;
7776 
7777  ++conflict->ndualproofsinfsuccess;
7778  }
7779 
7780  return SCIP_OKAY;
7781 }
7782 
7783 /** try to find a subset of changed bounds leading to an infeasible LP
7784  *
7785  * 1. call undoBdchgsDualfarkas() or undoBdchgsDualsol()
7786  * -> update lb/ubchginfoposs arrays
7787  * -> store additional changes in bdchg and curvarlbs/ubs arrays
7788  * -> apply additional changes to the LPI
7789  * 2. (optional) if additional bound changes were undone:
7790  * -> resolve LP
7791  * -> goto 1.
7792  * 3. redo all bound changes in the LPI to restore the LPI to its original state
7793  * 4. analyze conflict
7794  * -> put remaining changed bounds (see lb/ubchginfoposs arrays) into starting conflict set
7795  */
7796 static
7798  SCIP_CONFLICT* conflict, /**< conflict data */
7799  SCIP_SET* set, /**< global SCIP settings */
7800  SCIP_STAT* stat, /**< problem statistics */
7801  SCIP_PROB* origprob, /**< original problem */
7802  SCIP_PROB* transprob, /**< transformed problem */
7803  SCIP_TREE* tree, /**< branch and bound tree */
7804  SCIP_REOPT* reopt, /**< reoptimization data */
7805  SCIP_LP* lp, /**< LP data */
7806  SCIP_LPI* lpi, /**< LPI data */
7807  BMS_BLKMEM* blkmem, /**< block memory */
7808  SCIP_Real* proofcoefs, /**< coefficients in the proof constraint */
7809  SCIP_Real* prooflhs, /**< lhs of the proof constraint */
7810  SCIP_Real* proofactivity, /**< maximal activity of the proof constraint */
7811  SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
7812  SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
7813  int* lbchginfoposs, /**< positions of currently active lower bound change information in variables' arrays */
7814  int* ubchginfoposs, /**< positions of currently active upper bound change information in variables' arrays */
7815  int* iterations, /**< pointer to store the total number of LP iterations used */
7816  SCIP_Bool marklpunsolved, /**< whether LP should be marked unsolved after analysis (needed for strong branching) */
7817  SCIP_Bool* dualproofsuccess, /**< pointer to store success result of dual proof analysis */
7818  SCIP_Bool* valid /**< pointer to store whether the result is still a valid proof */
7819  )
7820 {
7821  SCIP_LPBDCHGS* oldlpbdchgs;
7822  SCIP_LPBDCHGS* relaxedlpbdchgs;
7823  SCIP_Bool solvelp;
7824  SCIP_Bool resolve;
7825  int ncols;
7826 
7827  assert(set != NULL);
7828 
7829  /* get number of columns in the LP */
7830  ncols = SCIPlpGetNCols(lp);
7831 
7832  /* get temporary memory for remembering bound changes on LPI columns */
7833  SCIP_CALL( lpbdchgsCreate(&oldlpbdchgs, set, ncols) );
7834  SCIP_CALL( lpbdchgsCreate(&relaxedlpbdchgs, set, ncols) );
7835 
7836  /* undo as many bound changes as possible with the current LP solution */
7837  resolve = FALSE;
7838  if( (*valid) )
7839  {
7840  int currentdepth;
7841  currentdepth = SCIPtreeGetCurrentDepth(tree);
7842 
7843  if( SCIPlpiIsPrimalInfeasible(lpi) )
7844  {
7845  SCIP_CALL( undoBdchgsDualfarkas(set, transprob, lp, currentdepth, curvarlbs, curvarubs, lbchginfoposs, \
7846  ubchginfoposs, oldlpbdchgs, relaxedlpbdchgs, valid, &resolve, proofcoefs, *prooflhs, proofactivity) );
7847  }
7848  else
7849  {
7850  assert(SCIPlpiIsDualFeasible(lpi) || SCIPlpiIsObjlimExc(lpi));
7851  SCIP_CALL( undoBdchgsDualsol(set, transprob, lp, currentdepth, curvarlbs, curvarubs, lbchginfoposs, ubchginfoposs, \
7852  oldlpbdchgs, relaxedlpbdchgs, valid, &resolve, proofcoefs, *prooflhs, proofactivity) );
7853  }
7854  }
7855 
7856  /* check if we want to solve the LP */
7857  assert(SCIPprobAllColsInLP(transprob, set, lp));
7858  solvelp = (set->conf_maxlploops != 0 && set->conf_lpiterations != 0);
7859 
7860  if( (*valid) && resolve && solvelp )
7861  {
7862  SCIP_RETCODE retcode;
7863  SCIP_ROW** rows;
7864  int* sidechginds;
7865  SCIP_Real* sidechgoldlhss;
7866  SCIP_Real* sidechgoldrhss;
7867  SCIP_Real* sidechgnewlhss;
7868  SCIP_Real* sidechgnewrhss;
7869  SCIP_Real lpiinfinity;
7870  SCIP_Bool globalinfeasible;
7871  int maxlploops;
7872  int lpiterations;
7873  int sidechgssize;
7874  int nsidechgs;
7875  int nrows;
7876  int nloops;
7877  int r;
7878 
7879  /* get infinity value of LP solver */
7880  lpiinfinity = SCIPlpiInfinity(lpi);
7881 
7882  /* temporarily disable objective limit and install an iteration limit */
7883  maxlploops = (set->conf_maxlploops >= 0 ? set->conf_maxlploops : INT_MAX);
7884  lpiterations = (set->conf_lpiterations >= 0 ? set->conf_lpiterations : INT_MAX);
7885  SCIP_CALL( SCIPlpiSetRealpar(lpi, SCIP_LPPAR_OBJLIM, lpiinfinity) );
7886  SCIP_CALL( SCIPlpiSetIntpar(lpi, SCIP_LPPAR_LPITLIM, lpiterations) );
7887 
7888  /* get LP rows */
7889  rows = SCIPlpGetRows(lp);
7890  nrows = SCIPlpGetNRows(lp);
7891  assert(nrows == 0 || rows != NULL);
7892 
7893  /* get temporary memory for remembering side changes on LPI rows */
7894  SCIP_CALL( SCIPsetAllocBufferArray(set, &sidechginds, nrows) );
7895  SCIP_CALL( SCIPsetAllocBufferArray(set, &sidechgoldlhss, nrows) );
7896  SCIP_CALL( SCIPsetAllocBufferArray(set, &sidechgoldrhss, nrows) );
7897  SCIP_CALL( SCIPsetAllocBufferArray(set, &sidechgnewlhss, nrows) );
7898  SCIP_CALL( SCIPsetAllocBufferArray(set, &sidechgnewrhss, nrows) );
7899  sidechgssize = nrows;
7900  nsidechgs = 0;
7901 
7902  /* remove all local rows by setting their sides to infinity;
7903  * finite sides are only changed to near infinity, such that the row's sense in the LP solver
7904  * is not affected (e.g. CPLEX cannot handle free rows)
7905  */
7906  for( r = 0; r < nrows; ++r )
7907  {
7908  assert(SCIProwGetLPPos(rows[r]) == r);
7909 
7910  if( SCIProwIsLocal(rows[r]) )
7911  {
7912  SCIPsetDebugMsg(set, " -> removing local row <%s> [%g,%g]\n",
7913  SCIProwGetName(rows[r]), SCIProwGetLhs(rows[r]), SCIProwGetRhs(rows[r]));
7914  SCIP_CALL( addSideRemoval(set, rows[r], lpiinfinity, &sidechginds, &sidechgoldlhss, &sidechgoldrhss,
7915  &sidechgnewlhss, &sidechgnewrhss, &sidechgssize, &nsidechgs) );
7916  }
7917  }
7918 
7919  /* apply changes of local rows to the LP solver */
7920  if( nsidechgs > 0 )
7921  {
7922  SCIP_CALL( SCIPlpiChgSides(lpi, nsidechgs, sidechginds, sidechgnewlhss, sidechgnewrhss) );
7923  }
7924 
7925  /* undo as many additional bound changes as possible by resolving the LP */
7926  assert((*valid));
7927  assert(resolve);
7928  nloops = 0;
7929  globalinfeasible = FALSE;
7930  while( (*valid) && resolve && nloops < maxlploops )
7931  {
7932  int iter;
7933 
7934  assert(!globalinfeasible);
7935 
7936  nloops++;
7937  resolve = FALSE;
7938 
7939  SCIPsetDebugMsg(set, "infeasible LP conflict analysis loop %d (changed col bounds: %d)\n", nloops, relaxedlpbdchgs->nbdchgs);
7940 
7941  /* apply bound changes to the LP solver */
7942  assert(relaxedlpbdchgs->nbdchgs >= 0);
7943  if( relaxedlpbdchgs->nbdchgs > 0 )
7944  {
7945  SCIPsetDebugMsg(set, " -> applying %d bound changes to the LP solver\n", relaxedlpbdchgs->nbdchgs);
7946  SCIP_CALL( SCIPlpiChgBounds(lpi, relaxedlpbdchgs->nbdchgs, relaxedlpbdchgs->bdchginds, \
7947  relaxedlpbdchgs->bdchglbs, relaxedlpbdchgs->bdchgubs) );
7948 
7949  /* reset conflict LP bound change data structure */
7950  lpbdchgsReset(relaxedlpbdchgs, ncols);
7951  }
7952 
7953  /* start LP timer */
7954  SCIPclockStart(stat->conflictlptime, set);
7955 
7956  /* resolve LP */
7957  retcode = SCIPlpiSolveDual(lpi);
7958 
7959  /* stop LP timer */
7960  SCIPclockStop(stat->conflictlptime, set);
7961 
7962  /* check return code of LP solving call */
7963  if( retcode == SCIP_LPERROR )
7964  {
7965  (*valid) = FALSE;
7966  break;
7967  }
7968  SCIP_CALL( retcode );
7969 
7970  /* count number of LP iterations */
7971  SCIP_CALL( SCIPlpiGetIterations(lpi, &iter) );
7972  (*iterations) += iter;
7973  stat->nconflictlps++;
7974  stat->nconflictlpiterations += iter;
7975  SCIPsetDebugMsg(set, " -> resolved LP in %d iterations (total: %" SCIP_LONGINT_FORMAT ") (infeasible:%u)\n",
7977 
7978  /* evaluate result */
7979  if( SCIPlpiIsDualFeasible(lpi) || SCIPlpiIsObjlimExc(lpi) )
7980  {
7981  SCIP_Real objval;
7982 
7983  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
7984  (*valid) = (objval >= lp->lpiobjlim && !SCIPlpDivingObjChanged(lp));
7985  }
7986  else
7987  (*valid) = SCIPlpiIsPrimalInfeasible(lpi);
7988 
7989  if( (*valid) )
7990  {
7991  int currentdepth;
7992  currentdepth = SCIPtreeGetCurrentDepth(tree);
7993 
7994  /* undo additional bound changes */
7995  if( SCIPlpiIsPrimalInfeasible(lpi) )
7996  {
7997  SCIP_AGGRROW* farkasrow;
7998  int* inds;
7999  int validdepth;
8000  int nnz;
8001  int v;
8002 
8003 #ifndef NDEBUG
8004  SCIP_VAR** vars = SCIPprobGetVars(transprob);
8005 #endif
8006 
8007  SCIP_CALL( SCIPaggrRowCreate(set->scip, &farkasrow) );
8008 
8009  /* the original LP exceeds the current cutoff bound, thus, we have not constructed the Farkas proof */
8010  SCIP_CALL( getFarkasProof(set, transprob, lp, lpi, tree, farkasrow, proofactivity, &validdepth,
8011  curvarlbs, curvarubs, valid) );
8012 
8013  /* the constructed Farkas proof is not valid, we need to break here */
8014  if( !(*valid) )
8015  {
8016  SCIPaggrRowFree(set->scip, &farkasrow);
8017  break;
8018  }
8019 
8020  /* start dual proof analysis */
8021  if( set->conf_useinflp == 'd' || set->conf_useinflp == 'b' )
8022  {
8023  /* change the conflict type */
8024  SCIP_CONFTYPE oldconftype = conflict->conflictset->conflicttype;
8026 
8027  /* start dual proof analysis */
8028  SCIP_CALL( conflictAnalyzeDualProof(conflict, set, stat, blkmem, origprob, transprob, tree, reopt, lp, \
8029  farkasrow, validdepth, curvarlbs, curvarubs, FALSE, &globalinfeasible, dualproofsuccess) );
8030 
8031  conflict->conflictset->conflicttype = oldconftype;
8032  }
8033 
8034  /* todo: in theory, we could apply conflict graph analysis for locally valid proofs, too, but this needs to be implemented */
8035  if( globalinfeasible || validdepth > SCIPtreeGetEffectiveRootDepth(tree) )
8036  {
8037  SCIPaggrRowFree(set->scip, &farkasrow);
8038  goto TERMINATE;
8039  }
8040 
8041  BMSclearMemoryArray(proofcoefs, SCIPprobGetNVars(transprob));
8042  (*prooflhs) = -SCIPaggrRowGetRhs(farkasrow);
8043  (*proofactivity) = -(*proofactivity);
8044 
8045  inds = SCIPaggrRowGetInds(farkasrow);
8046  nnz = SCIPaggrRowGetNNz(farkasrow);
8047 
8048  for( v = 0; v < nnz; v++ )
8049  {
8050  int i = inds[v];
8051 
8052  assert(SCIPvarGetProbindex(vars[i]) == inds[v]);
8053 
8054  proofcoefs[i] = -SCIPaggrRowGetProbvarValue(farkasrow, i);
8055  }
8056 
8057  /* free aggregation rows */
8058  SCIPaggrRowFree(set->scip, &farkasrow);
8059 
8060  SCIP_CALL( undoBdchgsDualfarkas(set, transprob, lp, currentdepth, curvarlbs, curvarubs, lbchginfoposs, \
8061  ubchginfoposs, oldlpbdchgs, relaxedlpbdchgs, valid, &resolve, proofcoefs, (*prooflhs), proofactivity) );
8062  }
8063  else
8064  {
8065  SCIP_AGGRROW* proofrow;
8066  int* inds;
8067  int validdepth;
8068  int nnz;
8069  int v;
8070 
8071 #ifndef NDEBUG
8072  SCIP_VAR** vars = SCIPprobGetVars(transprob);
8073 #endif
8074 
8075  assert(SCIPlpiIsDualFeasible(lpi) || SCIPlpiIsObjlimExc(lpi));
8076 
8077  SCIP_CALL( SCIPaggrRowCreate(set->scip, &proofrow) );
8078 
8079  SCIP_CALL( getDualProof(set, transprob, lp, lpi, tree, proofrow, proofactivity, &validdepth,
8080  curvarlbs, curvarubs, valid) );
8081 
8082  /* the constructed dual proof is not valid, we need to break here */
8083  if( !(*valid) || validdepth > SCIPtreeGetEffectiveRootDepth(tree) )
8084  {
8085  SCIPaggrRowFree(set->scip, &proofrow);
8086  break;
8087  }
8088  /* in contrast to the infeasible case we don't want to analyze the (probably identical) proof again. */
8089 
8090  BMSclearMemoryArray(proofcoefs, SCIPprobGetNVars(transprob));
8091  (*prooflhs) = -SCIPaggrRowGetRhs(proofrow);
8092  (*proofactivity) = -(*proofactivity);
8093 
8094  inds = SCIPaggrRowGetInds(proofrow);
8095  nnz = SCIPaggrRowGetNNz(proofrow);
8096 
8097  for( v = 0; v < nnz; v++ )
8098  {
8099  int i = inds[v];
8100 
8101  assert(SCIPvarGetProbindex(vars[i]) == inds[v]);
8102 
8103  proofcoefs[i] = -SCIPaggrRowGetProbvarValue(proofrow, i);
8104  }
8105 
8106  /* free aggregation rows */
8107  SCIPaggrRowFree(set->scip, &proofrow);
8108 
8109  SCIP_CALL( undoBdchgsDualsol(set, transprob, lp, currentdepth, curvarlbs, curvarubs, lbchginfoposs, \
8110  ubchginfoposs, oldlpbdchgs, relaxedlpbdchgs, valid, &resolve, proofcoefs, *prooflhs, proofactivity) );
8111  }
8112  }
8113  assert(!resolve || (*valid));
8114  assert(!resolve || relaxedlpbdchgs->nbdchgs > 0);
8115  SCIPsetDebugMsg(set, " -> finished infeasible LP conflict analysis loop %d (iter: %d, nbdchgs: %d)\n",
8116  nloops, iter, relaxedlpbdchgs->nbdchgs);
8117  }
8118 
8119  SCIPsetDebugMsg(set, "finished undoing bound changes after %d loops (valid=%u, nbdchgs: %d)\n",
8120  nloops, (*valid), oldlpbdchgs->nbdchgs);
8121 
8122  TERMINATE:
8123  /* reset variables to local bounds */
8124  if( oldlpbdchgs->nbdchgs > 0 )
8125  {
8126  SCIP_CALL( SCIPlpiChgBounds(lpi, oldlpbdchgs->nbdchgs, oldlpbdchgs->bdchginds, oldlpbdchgs->bdchglbs, oldlpbdchgs->bdchgubs) );
8127  }
8128 
8129  /* reset changes of local rows */
8130  if( nsidechgs > 0 )
8131  {
8132  SCIP_CALL( SCIPlpiChgSides(lpi, nsidechgs, sidechginds, sidechgoldlhss, sidechgoldrhss) );
8133  }
8134 
8135  /* mark the LP unsolved */
8136  if( oldlpbdchgs->nbdchgs > 0 || nsidechgs > 0 )
8137  {
8138  /* The LPI data are out of sync with LP data. Thus, the LP should be marked
8139  * unsolved. However, for strong branching calls, the LP has to have status 'solved'; in
8140  * this case, marklpunsolved is FALSE and synchronization is performed later. */
8141  if ( marklpunsolved )
8142  {
8143  lp->solved = FALSE;
8144  lp->primalfeasible = FALSE;
8145  lp->primalchecked = FALSE;
8146  lp->dualfeasible = FALSE;
8147  lp->dualchecked = FALSE;
8148  lp->lpobjval = SCIP_INVALID;
8150  }
8151  }
8152 
8153  /* reinstall old objective and iteration limits in LP solver */
8156 
8157  /* free temporary memory */
8158  SCIPsetFreeBufferArray(set, &sidechgnewrhss);
8159  SCIPsetFreeBufferArray(set, &sidechgnewlhss);
8160  SCIPsetFreeBufferArray(set, &sidechgoldrhss);
8161  SCIPsetFreeBufferArray(set, &sidechgoldlhss);
8162  SCIPsetFreeBufferArray(set, &sidechginds);
8163  }
8164 
8165  /* free temporary memory */
8166  lpbdchgsFree(&relaxedlpbdchgs, set);
8167  lpbdchgsFree(&oldlpbdchgs, set);
8168 
8169  return SCIP_OKAY;
8170 }
8171 
8172 /** actually performs analysis of infeasible LP */
8173 static
8175  SCIP_CONFLICT* conflict, /**< conflict analysis data */
8176  SCIP_CONFLICTSTORE* conflictstore, /**< conflict store */
8177  BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
8178  SCIP_SET* set, /**< global SCIP settings */
8179  SCIP_STAT* stat, /**< problem statistics */
8180  SCIP_PROB* transprob, /**< transformed problem */
8181  SCIP_PROB* origprob, /**< original problem */
8182  SCIP_TREE* tree, /**< branch and bound tree */
8183  SCIP_REOPT* reopt, /**< reoptimization data structure */
8184  SCIP_LP* lp, /**< LP data */
8185  SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
8186  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
8187  SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
8188  SCIP_Bool diving, /**< are we in strong branching or diving mode? */
8189  SCIP_Bool* dualproofsuccess, /**< pointer to store success result of dual proof analysis */
8190  int* iterations, /**< pointer to store the total number of LP iterations used */
8191  int* nconss, /**< pointer to store the number of generated conflict constraints */
8192  int* nliterals, /**< pointer to store the number of literals in generated conflict constraints */
8193  int* nreconvconss, /**< pointer to store the number of generated reconvergence constraints */
8194  int* nreconvliterals, /**< pointer to store the number of literals generated reconvergence constraints */
8195  SCIP_Bool marklpunsolved /**< whether LP should be marked unsolved after analysis (needed for strong branching) */
8196  )
8197 {
8198  SCIP_VAR** vars;
8199  SCIP_AGGRROW* farkasrow;
8200  SCIP_LPI* lpi;
8201  SCIP_Bool valid;
8202  SCIP_Bool globalinfeasible;
8203  int* lbchginfoposs;
8204  int* ubchginfoposs;
8205  int validdepth;
8206  int nvars;
8207  int v;
8208  SCIP_Real* curvarlbs;
8209  SCIP_Real* curvarubs;
8210  SCIP_Real farkasactivity;
8211 
8212  assert(conflict != NULL);
8213  assert(conflict->nconflictsets == 0);
8214  assert(set != NULL);
8215  assert(SCIPprobAllColsInLP(transprob, set, lp)); /* LP conflict analysis is only valid, if all variables are known */
8216  assert(stat != NULL);
8217  assert(transprob != NULL);
8218  assert(lp != NULL);
8219  assert(lp->flushed);
8220  assert(lp->solved);
8221  assert(iterations != NULL);
8222  assert(nconss != NULL);
8223  assert(nliterals != NULL);
8224  assert(nreconvconss != NULL);
8225  assert(nreconvliterals != NULL);
8226 
8227  *iterations = 0;
8228  *nconss = 0;
8229  *nliterals = 0;
8230  *nreconvconss = 0;
8231  *nreconvliterals = 0;
8232 
8233  vars = transprob->vars;
8234  nvars = transprob->nvars;
8235 
8236  valid = TRUE;
8237  validdepth = 0;
8238 
8239  /* get LP solver interface */
8240  lpi = SCIPlpGetLPI(lp);
8243 
8244  if( !SCIPlpiIsPrimalInfeasible(lpi) )
8245  {
8246  SCIP_Real objval;
8247 
8248  assert(!SCIPlpDivingObjChanged(lp));
8249 
8250  /* make sure, a dual feasible solution exists, that exceeds the objective limit;
8251  * With FASTMIP setting, CPLEX does not apply the final pivot to reach the dual solution exceeding the objective
8252  * limit. Therefore, we have to either turn off FASTMIP and resolve the problem or continue solving it without
8253  * objective limit for at least one iteration. It seems that the strategy to continue with FASTMIP for one
8254  * additional simplex iteration yields better results.
8255  */
8256  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
8257  if( objval < lp->lpiobjlim )
8258  {
8259  SCIP_RETCODE retcode;
8260 
8261  /* temporarily disable objective limit and install an iteration limit */
8264 
8265  /* start LP timer */
8266  SCIPclockStart(stat->conflictlptime, set);
8267 
8268  /* resolve LP */
8269  retcode = SCIPlpiSolveDual(lpi);
8270 
8271  /* stop LP timer */
8272  SCIPclockStop(stat->conflictlptime, set);
8273 
8274  /* check return code of LP solving call */
8275  valid = (retcode != SCIP_LPERROR);
8276  if( valid )
8277  {
8278  int iter;
8279 
8280  SCIP_CALL( retcode );
8281 
8282  /* count number of LP iterations */
8283  SCIP_CALL( SCIPlpiGetIterations(lpi, &iter) );
8284  (*iterations) += iter;
8285  stat->nconflictlps++;
8286  stat->nconflictlpiterations += iter;
8287  SCIPsetDebugMsg(set, " -> resolved objlim exceeding LP in %d iterations (total: %" SCIP_LONGINT_FORMAT ") (infeasible:%u, objlim: %u, optimal:%u)\n",
8290  }
8291 
8292  /* reinstall old objective and iteration limits in LP solver */
8295 
8296  /* abort, if the LP produced an error */
8297  if( !valid )
8298  return SCIP_OKAY;
8299  }
8300  }
8302 
8303  if( !SCIPlpiIsPrimalInfeasible(lpi) )
8304  {
8305  SCIP_Real objval;
8306 
8307  assert(!SCIPlpDivingObjChanged(lp));
8308 
8309  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
8310  if( objval < lp->lpiobjlim )
8311  {
8312  SCIPsetDebugMsg(set, " -> LP does not exceed the cutoff bound: obj=%g, cutoff=%g\n", objval, lp->lpiobjlim);
8313  return SCIP_OKAY;
8314  }
8315  else
8316  {
8317  SCIPsetDebugMsg(set, " -> LP exceeds the cutoff bound: obj=%g, cutoff=%g\n", objval, lp->lpiobjlim);
8318  }
8319  }
8320 
8321  assert(valid);
8322 
8323  SCIP_CALL( SCIPaggrRowCreate(set->scip, &farkasrow) );
8324  SCIP_CALL( SCIPsetAllocBufferArray(set, &lbchginfoposs, transprob->nvars) );
8325  SCIP_CALL( SCIPsetAllocBufferArray(set, &ubchginfoposs, transprob->nvars) );
8326 
8327  farkasactivity = 0.0;
8328 
8329  /* get temporary memory for remembering variables' current bounds and corresponding bound change information
8330  * positions in variable's bound change information arrays
8331  */
8332  SCIP_CALL( SCIPsetAllocBufferArray(set, &curvarlbs, nvars) );
8333  SCIP_CALL( SCIPsetAllocBufferArray(set, &curvarubs, nvars) );
8334 
8335  /* get current bounds and current positions in lb/ubchginfos arrays of variables */
8336  valid = TRUE;
8337  for( v = 0; v < nvars && valid; ++v )
8338  {
8339  SCIP_VAR* var;
8340 
8341  var = vars[v];
8342 
8343  curvarlbs[v] = SCIPvarGetLbLP(var, set);
8344  curvarubs[v] = SCIPvarGetUbLP(var, set);
8345  lbchginfoposs[v] = var->nlbchginfos-1;
8346  ubchginfoposs[v] = var->nubchginfos-1;
8347  assert(diving || SCIPsetIsEQ(set, curvarlbs[v], SCIPvarGetLbLocal(var)));
8348  assert(diving || SCIPsetIsEQ(set, curvarubs[v], SCIPvarGetUbLocal(var)));
8349 
8350  /* check, if last bound changes were due to strong branching or diving */
8351  if( diving )
8352  {
8353  SCIP_Real lb;
8354  SCIP_Real ub;
8355 
8356  lb = SCIPvarGetLbLocal(var);
8357  ub = SCIPvarGetUbLocal(var);
8358  if( SCIPsetIsGT(set, curvarlbs[v], lb) )
8359  lbchginfoposs[v] = var->nlbchginfos;
8360  else if( SCIPsetIsLT(set, curvarlbs[v], lb) )
8361  {
8362  /* the bound in the diving LP was relaxed -> the LP is not a subproblem of the current node -> abort! */
8363  /**@todo we could still analyze such a conflict, but we would have to take care with our data structures */
8364  valid = FALSE;
8365  }
8366  if( SCIPsetIsLT(set, curvarubs[v], ub) )
8367  ubchginfoposs[v] = var->nubchginfos;
8368  else if( SCIPsetIsGT(set, curvarubs[v], ub) )
8369  {
8370  /* the bound in the diving LP was relaxed -> the LP is not a subproblem of the current node -> abort! */
8371  /**@todo we could still analyze such a conflict, but we would have to take care with our data structures */
8372  valid = FALSE;
8373  }
8374  }
8375  }
8376 
8377  if( !valid )
8378  goto TERMINATE;
8379 
8380  /* the LP is prooven to be infeasible */
8381  if( SCIPlpiIsPrimalInfeasible(lpi) )
8382  {
8383  SCIP_CALL( getFarkasProof(set, transprob, lp, lpi, tree, farkasrow, &farkasactivity, &validdepth,
8384  curvarlbs, curvarubs, &valid) );
8385  }
8386  /* the LP is dual feasible and/or exceeds the current incumbant solution */
8387  else
8388  {
8389  assert(SCIPlpiIsDualFeasible(lpi) || SCIPlpiIsObjlimExc(lpi));
8390  SCIP_CALL( getDualProof(set, transprob, lp, lpi, tree, farkasrow, &farkasactivity, &validdepth,
8391  curvarlbs, curvarubs, &valid) );
8392  }
8393 
8394  if( !valid || validdepth >= SCIPtreeGetCurrentDepth(tree) )
8395  goto TERMINATE;
8396 
8397  globalinfeasible = FALSE;
8398 
8399  /* start dual proof analysis */
8400  if( ((set->conf_useinflp == 'b' || set->conf_useinflp == 'd') && conflict->conflictset->conflicttype == SCIP_CONFTYPE_INFEASLP)
8401  || ((set->conf_useboundlp == 'b' || set->conf_useboundlp == 'd') && conflict->conflictset->conflicttype == SCIP_CONFTYPE_BNDEXCEEDING) )
8402  {
8403  /* start dual proof analysis */
8404  SCIP_CALL( conflictAnalyzeDualProof(conflict, set, stat, blkmem, origprob, transprob, tree, reopt, lp, farkasrow, \
8405  validdepth, curvarlbs, curvarubs, TRUE, &globalinfeasible, dualproofsuccess) );
8406  }
8407 
8408  assert(valid);
8409 
8410  /* todo: in theory, we could apply conflict graph analysis for locally valid proofs, too, but this needs to be implemented */
8411  if( !globalinfeasible && validdepth <= SCIPtreeGetEffectiveRootDepth(tree)
8412  && (((set->conf_useinflp == 'b' || set->conf_useinflp == 'c') && conflict->conflictset->conflicttype == SCIP_CONFTYPE_INFEASLP)
8413  || ((set->conf_useboundlp == 'b' || set->conf_useboundlp == 'c') && conflict->conflictset->conflicttype == SCIP_CONFTYPE_BNDEXCEEDING)) )
8414  {
8415  SCIP_Real* farkascoefs;
8416  SCIP_Real farkaslhs;
8417  int* inds;
8418  int nnz;
8419 
8420 #ifdef SCIP_DEBUG
8421  {
8422  SCIP_Real objlim;
8423  SCIPsetDebugMsg(set, "analyzing conflict on infeasible LP (infeasible: %u, objlimexc: %u, optimal:%u) in depth %d (diving: %u)\n",
8425 
8426  SCIP_CALL( SCIPlpiGetRealpar(lpi, SCIP_LPPAR_OBJLIM, &objlim) );
8427  SCIPsetDebugMsg(set, " -> objective limit in LP solver: %g (in LP: %g)\n", objlim, lp->lpiobjlim);
8428  }
8429 #endif
8430 
8431  SCIP_CALL( SCIPsetAllocBufferArray(set, &farkascoefs, SCIPprobGetNVars(transprob)) );
8432  BMSclearMemoryArray(farkascoefs, SCIPprobGetNVars(transprob));
8433 
8434  farkaslhs = -SCIPaggrRowGetRhs(farkasrow);
8435  farkasactivity = -farkasactivity;
8436 
8437  inds = SCIPaggrRowGetInds(farkasrow);
8438  nnz = SCIPaggrRowGetNNz(farkasrow);
8439 
8440  for( v = 0; v < nnz; v++ )
8441  {
8442  int i = inds[v];
8443 
8444  assert(SCIPvarGetProbindex(vars[i]) == inds[v]);
8445 
8446  farkascoefs[i] = -SCIPaggrRowGetProbvarValue(farkasrow, i);
8447  }
8448 
8449  SCIP_CALL( runBoundHeuristic(conflict, set, stat, origprob, transprob, tree, reopt, lp, lpi, blkmem, farkascoefs,
8450  &farkaslhs, &farkasactivity, curvarlbs, curvarubs, lbchginfoposs, ubchginfoposs, iterations, marklpunsolved,
8451  dualproofsuccess, &valid) );
8452 
8453  SCIPsetFreeBufferArray(set, &farkascoefs);
8454 
8455  if( !valid )
8456  goto FLUSHPROOFSETS;
8457 
8458  /* analyze the conflict starting with remaining bound changes */
8459  SCIP_CALL( conflictAnalyzeRemainingBdchgs(conflict, blkmem, set, stat, transprob, tree, diving, \
8460  lbchginfoposs, ubchginfoposs, nconss, nliterals, nreconvconss, nreconvliterals) );
8461 
8462  /* flush conflict set storage */
8463  SCIP_CALL( SCIPconflictFlushConss(conflict, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, \
8464  eventqueue, cliquetable) );
8465  }
8466 
8467  FLUSHPROOFSETS:
8468  /* flush proof set */
8469  if( proofsetGetNVars(conflict->proofset) > 0 || conflict->nproofsets > 0 )
8470  {
8471  SCIP_CALL( conflictFlushProofset(conflict, conflictstore, blkmem, set, stat, transprob, origprob, tree, reopt, lp, \
8472  branchcand, eventqueue, cliquetable) );
8473  }
8474 
8475  TERMINATE:
8476  SCIPsetFreeBufferArray(set, &curvarubs);
8477  SCIPsetFreeBufferArray(set, &curvarlbs);
8478  SCIPsetFreeBufferArray(set, &ubchginfoposs);
8479  SCIPsetFreeBufferArray(set, &lbchginfoposs);
8480  SCIPaggrRowFree(set->scip, &farkasrow);
8481 
8482  return SCIP_OKAY;
8483 }
8484 
8485 /** analyzes an infeasible LP to find out the bound changes on variables that were responsible for the infeasibility;
8486  * on success, calls standard conflict analysis with the responsible variables as starting conflict set, thus creating
8487  * a conflict constraint out of the resulting conflict set;
8488  * updates statistics for infeasible LP conflict analysis
8489  */
8490 static
8492  SCIP_CONFLICT* conflict, /**< conflict analysis data */
8493  SCIP_CONFLICTSTORE* conflictstore, /**< conflict store */
8494  BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
8495  SCIP_SET* set, /**< global SCIP settings */
8496  SCIP_STAT* stat, /**< problem statistics */
8497  SCIP_PROB* transprob, /**< transformed problem */
8498  SCIP_PROB* origprob, /**< original problem */
8499  SCIP_TREE* tree, /**< branch and bound tree */
8500  SCIP_REOPT* reopt, /**< reoptimization data structure */
8501  SCIP_LP* lp, /**< LP data */
8502  SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
8503  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
8504  SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
8505  SCIP_Bool* success /**< pointer to store whether a conflict constraint was created, or NULL */
8506  )
8507 {
8508  SCIP_Bool dualraysuccess = FALSE;
8509  SCIP_Longint olddualproofsuccess;
8510  int iterations;
8511  int nconss;
8512  int nliterals;
8513  int nreconvconss;
8514  int nreconvliterals;
8515 
8516  assert(conflict != NULL);
8517  assert(set != NULL);
8518  assert(lp != NULL);
8519  assert(SCIPprobAllColsInLP(transprob, set, lp)); /* LP conflict analysis is only valid, if all variables are known */
8520 
8521  assert(success == NULL || *success == FALSE);
8522 
8523  /* check, if infeasible LP conflict analysis is enabled */
8524  if( !set->conf_enable || set->conf_useinflp == 'o' )
8525  return SCIP_OKAY;
8526 
8527  /* check, if there are any conflict handlers to use a conflict set */
8528  if( set->nconflicthdlrs == 0 )
8529  return SCIP_OKAY;
8530 
8531  SCIPsetDebugMsg(set, "analyzing conflict on infeasible LP in depth %d (solstat: %d, objchanged: %u)\n",
8533 
8534  /* start timing */
8535  SCIPclockStart(conflict->inflpanalyzetime, set);
8536  conflict->ninflpcalls++;
8537 
8539 
8540  olddualproofsuccess = conflict->ndualproofsinfsuccess;
8541 
8542  /* perform conflict analysis */
8543  SCIP_CALL( conflictAnalyzeLP(conflict, conflictstore, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, eventqueue, \
8544  cliquetable, SCIPlpDiving(lp), &dualraysuccess, &iterations, &nconss, &nliterals, &nreconvconss, &nreconvliterals, TRUE) );
8545  conflict->ninflpsuccess += ((nconss > 0 || conflict->ndualproofsinfsuccess > olddualproofsuccess) ? 1 : 0);
8546  conflict->ninflpiterations += iterations;
8547  conflict->ninflpconfconss += nconss;
8548  conflict->ninflpconfliterals += nliterals;
8549  conflict->ninflpreconvconss += nreconvconss;
8550  conflict->ninflpreconvliterals += nreconvliterals;
8551  if( success != NULL )
8552  *success = (nconss > 0 || conflict->ndualproofsinfsuccess > olddualproofsuccess);
8553 
8554  /* stop timing */
8555  SCIPclockStop(conflict->inflpanalyzetime, set);
8556 
8557  return SCIP_OKAY;
8558 }
8559 
8560 /** analyzes a bound exceeding LP to find out the bound changes on variables that were responsible for exceeding the
8561  * primal bound;
8562  * on success, calls standard conflict analysis with the responsible variables as starting conflict set, thus creating
8563  * a conflict constraint out of the resulting conflict set;
8564  * updates statistics for bound exceeding LP conflict analysis
8565  */
8566 static
8568  SCIP_CONFLICT* conflict, /**< conflict analysis data */
8569  SCIP_CONFLICTSTORE* conflictstore, /**< conflict store */
8570  BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
8571  SCIP_SET* set, /**< global SCIP settings */
8572  SCIP_STAT* stat, /**< problem statistics */
8573  SCIP_PROB* transprob, /**< transformed problem */
8574  SCIP_PROB* origprob, /**< original problem */
8575  SCIP_TREE* tree, /**< branch and bound tree */
8576  SCIP_REOPT* reopt, /**< reoptimization data structure */
8577  SCIP_LP* lp, /**< LP data */
8578  SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
8579  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
8580  SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
8581  SCIP_Bool* success /**< pointer to store whether a conflict constraint was created, or NULL */
8582  )
8583 {
8584  SCIP_Bool dualraysuccess;
8585  SCIP_Longint oldnsuccess;
8586  int iterations;
8587  int nconss;
8588  int nliterals;
8589  int nreconvconss;
8590  int nreconvliterals;
8591 
8592  assert(conflict != NULL);
8593  assert(set != NULL);
8594  assert(lp != NULL);
8595  assert(!SCIPlpDivingObjChanged(lp));
8596  assert(SCIPprobAllColsInLP(transprob, set, lp)); /* LP conflict analysis is only valid, if all variables are known */
8597 
8598  assert(success == NULL || *success == FALSE);
8599 
8600  /* check, if bound exceeding LP conflict analysis is enabled */
8601  if( !set->conf_enable || set->conf_useboundlp == 'o')
8602  return SCIP_OKAY;
8603 
8604  /* check, if there are any conflict handlers to use a conflict set */
8605  if( set->nconflicthdlrs == 0 )
8606  return SCIP_OKAY;
8607 
8608  SCIPsetDebugMsg(set, "analyzing conflict on bound exceeding LP in depth %d (solstat: %d)\n",
8610 
8611  /* start timing */
8612  SCIPclockStart(conflict->boundlpanalyzetime, set);
8613  conflict->nboundlpcalls++;
8614 
8615  /* mark the conflict to depend on the cutoff bound */
8617  conflict->conflictset->usescutoffbound = TRUE;
8618 
8619  oldnsuccess = conflict->ndualproofsbndsuccess + conflict->ndualproofsinfsuccess;
8620 
8621  /* perform conflict analysis */
8622  SCIP_CALL( conflictAnalyzeLP(conflict, conflictstore, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, eventqueue, \
8623  cliquetable, SCIPlpDiving(lp), &dualraysuccess, &iterations, &nconss, &nliterals, &nreconvconss, &nreconvliterals, TRUE) );
8624  conflict->nboundlpsuccess += ((nconss > 0 || conflict->ndualproofsbndsuccess + conflict->ndualproofsinfsuccess > oldnsuccess) ? 1 : 0);
8625  conflict->nboundlpiterations += iterations;
8626  conflict->nboundlpconfconss += nconss;
8627  conflict->nboundlpconfliterals += nliterals;
8628  conflict->nboundlpreconvconss += nreconvconss;
8629  conflict->nboundlpreconvliterals += nreconvliterals;
8630  if( success != NULL )
8631  *success = (nconss > 0 || conflict->ndualproofsbndsuccess + conflict->ndualproofsinfsuccess > oldnsuccess);
8632 
8633  /* stop timing */
8634  SCIPclockStop(conflict->boundlpanalyzetime, set);
8635 
8636  return SCIP_OKAY;
8637 }
8638 
8639 /** analyzes an infeasible or bound exceeding LP to find out the bound changes on variables that were responsible for the
8640  * infeasibility or for exceeding the primal bound;
8641  * on success, calls standard conflict analysis with the responsible variables as starting conflict set, thus creating
8642  * a conflict constraint out of the resulting conflict set;
8643  * updates statistics for infeasible or bound exceeding LP conflict analysis;
8644  * may only be called if SCIPprobAllColsInLP()
8645  */
8647  SCIP_CONFLICT* conflict, /**< conflict analysis data */
8648  SCIP_CONFLICTSTORE* conflictstore, /**< conflict store */
8649  BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
8650  SCIP_SET* set, /**< global SCIP settings */
8651  SCIP_STAT* stat, /**< problem statistics */
8652  SCIP_PROB* transprob, /**< transformed problem */
8653  SCIP_PROB* origprob, /**< original problem */
8654  SCIP_TREE* tree, /**< branch and bound tree */
8655  SCIP_REOPT* reopt, /**< reoptimization data structure */
8656  SCIP_LP* lp, /**< LP data */
8657  SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
8658  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
8659  SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
8660  SCIP_Bool* success /**< pointer to store whether a conflict constraint was created, or NULL */
8661  )
8662 {
8663  SCIP_LPSOLVALS storedsolvals;
8664  SCIP_COLSOLVALS* storedcolsolvals;
8665  SCIP_ROWSOLVALS* storedrowsolvals;
8666  int c;
8667  int r;
8668 
8669  if( success != NULL )
8670  *success = FALSE;
8671 
8672  /* check if the conflict analysis is applicable */
8673  if( !set->conf_enable || (set->conf_useinflp == 'o' && set->conf_useboundlp == 'o') )
8674  return SCIP_OKAY;
8675 
8676  /* in rare cases, it might happen that the solution stati of the LP and the LPI are out of sync; in particular this
8677  * happens when a new incumbent which cuts off the current node is found during the LP solving loop; in this case the
8678  * LP has status objlimit, but if diving has been used, the LPI only has the basis information, but is not solved
8679  *
8680  * @todo: alternatively, solve the LPI
8681  */
8682  if( !SCIPlpiWasSolved(SCIPlpGetLPI(lp)) )
8683  return SCIP_OKAY;
8684 
8685  /* LP conflict analysis is only valid, if all variables are known */
8686  assert( SCIPprobAllColsInLP(transprob, set, lp) );
8688  || (SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OPTIMAL && set->lp_disablecutoff == 1) );
8689 
8690  /* save status */
8691  storedsolvals.lpsolstat = lp->lpsolstat;
8692  storedsolvals.lpobjval = lp->lpobjval;
8693  storedsolvals.primalfeasible = lp->primalfeasible;
8694  storedsolvals.primalchecked = lp->primalchecked;
8695  storedsolvals.dualfeasible = lp->dualfeasible;
8696  storedsolvals.dualchecked = lp->dualchecked;
8697  storedsolvals.solisbasic = lp->solisbasic;
8698  storedsolvals.lpissolved = lp->solved;
8699 
8700  /* store solution values */
8701  SCIP_CALL( SCIPsetAllocBufferArray(set, &storedcolsolvals, lp->ncols) );
8702  SCIP_CALL( SCIPsetAllocBufferArray(set, &storedrowsolvals, lp->nrows) );
8703  for (c = 0; c < lp->ncols; ++c)
8704  {
8705  SCIP_COL* col;
8706 
8707  col = lp->cols[c];
8708  assert( col != NULL );
8709 
8710  storedcolsolvals[c].primsol = col->primsol;
8711  storedcolsolvals[c].redcost = col->redcost;
8712  storedcolsolvals[c].basisstatus = col->basisstatus; /*lint !e641 !e732*/
8713  }
8714  for (r = 0; r < lp->nrows; ++r)
8715  {
8716  SCIP_ROW* row;
8717 
8718  row = lp->rows[r];
8719  assert( row != NULL );
8720 
8721  if ( lp->lpsolstat == SCIP_LPSOLSTAT_INFEASIBLE )
8722  storedrowsolvals[r].dualsol = row->dualfarkas;
8723  else
8724  {
8725  assert( lp->lpsolstat == SCIP_LPSOLSTAT_OBJLIMIT ||
8726  (SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OPTIMAL && set->lp_disablecutoff == 1) );
8727  storedrowsolvals[r].dualsol = row->dualsol;
8728  }
8729  storedrowsolvals[r].activity = row->activity;
8730  storedrowsolvals[r].basisstatus = row->basisstatus; /*lint !e641 !e732*/
8731  }
8732 
8733  /* check, if the LP was infeasible or bound exceeding */
8735  {
8736  SCIP_CALL( conflictAnalyzeInfeasibleLP(conflict, conflictstore, blkmem, set, stat, transprob, origprob, tree, \
8737  reopt, lp, branchcand, eventqueue, cliquetable, success) );
8738  }
8739  else
8740  {
8741  SCIP_CALL( conflictAnalyzeBoundexceedingLP(conflict, conflictstore, blkmem, set, stat, transprob, origprob, tree, \
8742  reopt, lp, branchcand, eventqueue, cliquetable, success) );
8743  }
8744 
8745  /* possibly restore solution values */
8747  {
8748  /* restore status */
8749  lp->lpsolstat = storedsolvals.lpsolstat;
8750  lp->lpobjval = storedsolvals.lpobjval;
8751  lp->primalfeasible = storedsolvals.primalfeasible;
8752  lp->primalchecked = storedsolvals.primalchecked;
8753  lp->dualfeasible = storedsolvals.dualfeasible;
8754  lp->dualchecked = storedsolvals.dualchecked;
8755  lp->solisbasic = storedsolvals.solisbasic;
8756  lp->solved = storedsolvals.lpissolved;
8757 
8758  for (c = 0; c < lp->ncols; ++c)
8759  {
8760  SCIP_COL* col;
8761 
8762  col = lp->cols[c];
8763  assert( col != NULL );
8764  col->primsol = storedcolsolvals[c].primsol;
8765  col->redcost = storedcolsolvals[c].redcost;
8766  col->basisstatus = storedcolsolvals[c].basisstatus; /*lint !e641 !e732*/
8767  }
8768  for (r = 0; r < lp->nrows; ++r)
8769  {
8770  SCIP_ROW* row;
8771 
8772  row = lp->rows[r];
8773  assert( row != NULL );
8774 
8775  if ( lp->lpsolstat == SCIP_LPSOLSTAT_INFEASIBLE )
8776  row->dualfarkas = storedrowsolvals[r].dualsol;
8777  else
8778  {
8779  assert( lp->lpsolstat == SCIP_LPSOLSTAT_OBJLIMIT );
8780  row->dualsol = storedrowsolvals[r].dualsol;
8781  }
8782  row->activity = storedrowsolvals[r].activity;
8783  row->basisstatus = storedrowsolvals[r].basisstatus; /*lint !e641 !e732*/
8784  }
8785  }
8786  SCIPsetFreeBufferArray(set, &storedrowsolvals);
8787  SCIPsetFreeBufferArray(set, &storedcolsolvals);
8788 
8789  return SCIP_OKAY;
8790 }
8791 
8792 /** gets time in seconds used for analyzing infeasible LP conflicts */
8794  SCIP_CONFLICT* conflict /**< conflict analysis data */
8795  )
8796 {
8797  assert(conflict != NULL);
8798 
8799  return SCIPclockGetTime(conflict->inflpanalyzetime);
8800 }
8801 
8802 /** gets number of calls to infeasible LP conflict analysis */
8804  SCIP_CONFLICT* conflict /**< conflict analysis data */
8805  )
8806 {
8807  assert(conflict != NULL);
8808 
8809  return conflict->ninflpcalls;
8810 }
8811 
8812 /** gets number of calls to infeasible LP conflict analysis that yield at least one conflict constraint */
8814  SCIP_CONFLICT* conflict /**< conflict analysis data */
8815  )
8816 {
8817  assert(conflict != NULL);
8818 
8819  return conflict->ninflpsuccess;
8820 }
8821 
8822 /** gets number of conflict constraints detected in infeasible LP conflict analysis */
8824  SCIP_CONFLICT* conflict /**< conflict analysis data */
8825  )
8826 {
8827  assert(conflict != NULL);
8828 
8829  return conflict->ninflpconfconss;
8830 }
8831 
8832 /** gets total number of literals in conflict constraints created in infeasible LP conflict analysis */
8834  SCIP_CONFLICT* conflict /**< conflict analysis data */
8835  )
8836 {
8837  assert(conflict != NULL);
8838 
8839  return conflict->ninflpconfliterals;
8840 }
8841 
8842 /** gets number of reconvergence constraints detected in infeasible LP conflict analysis */
8844  SCIP_CONFLICT* conflict /**< conflict analysis data */
8845  )
8846 {
8847  assert(conflict != NULL);
8848 
8849  return conflict->ninflpreconvconss;
8850 }
8851 
8852 /** gets total number of literals in reconvergence constraints created in infeasible LP conflict analysis */
8854  SCIP_CONFLICT* conflict /**< conflict analysis data */
8855  )
8856 {
8857  assert(conflict != NULL);
8858 
8859  return conflict->ninflpreconvliterals;
8860 }
8861 
8862 /** gets number of LP iterations in infeasible LP conflict analysis */
8864  SCIP_CONFLICT* conflict /**< conflict analysis data */
8865  )
8866 {
8867  assert(conflict != NULL);
8868 
8869  return conflict->ninflpiterations;
8870 }
8871 
8872 /** gets time in seconds used for analyzing bound exceeding LP conflicts */
8874  SCIP_CONFLICT* conflict /**< conflict analysis data */
8875  )
8876 {
8877  assert(conflict != NULL);
8878 
8879  return SCIPclockGetTime(conflict->boundlpanalyzetime);
8880 }
8881 
8882 /** gets number of calls to bound exceeding LP conflict analysis */
8884  SCIP_CONFLICT* conflict /**< conflict analysis data */
8885  )
8886 {
8887  assert(conflict != NULL);
8888 
8889  return conflict->nboundlpcalls;
8890 }
8891 
8892 /** gets number of calls to bound exceeding LP conflict analysis that yield at least one conflict constraint */
8894  SCIP_CONFLICT* conflict /**< conflict analysis data */
8895  )
8896 {
8897  assert(conflict != NULL);
8898 
8899  return conflict->nboundlpsuccess;
8900 }
8901 
8902 /** gets number of conflict constraints detected in bound exceeding LP conflict analysis */
8904  SCIP_CONFLICT* conflict /**< conflict analysis data */
8905  )
8906 {
8907  assert(conflict != NULL);
8908 
8909  return conflict->nboundlpconfconss;
8910 }
8911 
8912 /** gets total number of literals in conflict constraints created in bound exceeding LP conflict analysis */
8914  SCIP_CONFLICT* conflict /**< conflict analysis data */
8915  )
8916 {
8917  assert(conflict != NULL);
8918 
8919  return conflict->nboundlpconfliterals;
8920 }
8921 
8922 /** gets number of reconvergence constraints detected in bound exceeding LP conflict analysis */
8924  SCIP_CONFLICT* conflict /**< conflict analysis data */
8925  )
8926 {
8927  assert(conflict != NULL);
8928 
8929  return conflict->nboundlpreconvconss;
8930 }
8931 
8932 /** gets total number of literals in reconvergence constraints created in bound exceeding LP conflict analysis */
8934  SCIP_CONFLICT* conflict /**< conflict analysis data */
8935  )
8936 {
8937  assert(conflict != NULL);
8938 
8939  return conflict->nboundlpreconvliterals;
8940 }
8941 
8942 /** gets number of LP iterations in bound exceeding LP conflict analysis */
8944  SCIP_CONFLICT* conflict /**< conflict analysis data */
8945  )
8946 {
8947  assert(conflict != NULL);
8948 
8949  return conflict->nboundlpiterations;
8950 }
8951 
8952 
8953 
8954 
8955 /*
8956  * infeasible strong branching conflict analysis
8957  */
8958 
8959 /** analyses infeasible strong branching sub problems for conflicts */
8961  SCIP_CONFLICT* conflict, /**< conflict analysis data */
8962  SCIP_CONFLICTSTORE* conflictstore, /**< conflict store */
8963  BMS_BLKMEM* blkmem, /**< block memory buffers */
8964  SCIP_SET* set, /**< global SCIP settings */
8965  SCIP_STAT* stat, /**< dynamic problem statistics */
8966  SCIP_PROB* transprob, /**< transformed problem */
8967  SCIP_PROB* origprob, /**< original problem */
8968  SCIP_TREE* tree, /**< branch and bound tree */
8969  SCIP_REOPT* reopt, /**< reoptimization data structure */
8970  SCIP_LP* lp, /**< LP data */
8971  SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
8972  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
8973  SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
8974  SCIP_COL* col, /**< LP column with at least one infeasible strong branching subproblem */
8975  SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
8976  * infeasible downwards branch, or NULL */
8977  SCIP_Bool* upconflict /**< pointer to store whether a conflict constraint was created for an
8978  * infeasible upwards branch, or NULL */
8979  )
8980 {
8981  int* cstat;
8982  int* rstat;
8983  SCIP_RETCODE retcode;
8984  SCIP_Bool resolve;
8985  SCIP_Real oldlb;
8986  SCIP_Real oldub;
8987  SCIP_Real newlb;
8988  SCIP_Real newub;
8989  SCIP_Bool dualraysuccess;
8990  int iter;
8991  int nconss;
8992  int nliterals;
8993  int nreconvconss;
8994  int nreconvliterals;
8995 
8996  assert(stat != NULL);
8997  assert(lp != NULL);
8998  assert(lp->flushed);
8999  assert(lp->solved);
9000  assert(SCIPprobAllColsInLP(transprob, set, lp)); /* LP conflict analysis is only valid, if all variables are known */
9001  assert(col != NULL);
9002  assert((col->sbdownvalid && SCIPsetIsGE(set, col->sbdown, lp->cutoffbound)
9003  && SCIPsetFeasCeil(set, col->primsol-1.0) >= col->lb - 0.5)
9004  || (col->sbupvalid && SCIPsetIsGE(set, col->sbup, lp->cutoffbound)
9005  && SCIPsetFeasFloor(set, col->primsol+1.0) <= col->ub + 0.5));
9006  assert(SCIPtreeGetCurrentDepth(tree) > 0);
9007 
9008  if( downconflict != NULL )
9009  *downconflict = FALSE;
9010  if( upconflict != NULL )
9011  *upconflict = FALSE;
9012 
9013  /* check, if infeasible LP conflict analysis is enabled */
9014  if( !set->conf_enable || !set->conf_usesb )
9015  return SCIP_OKAY;
9016 
9017  /* check, if there are any conflict handlers to use a conflict set */
9018  if( set->nconflicthdlrs == 0 )
9019  return SCIP_OKAY;
9020 
9021  /* inform the LPI that strong branch is (temporarily) finished */
9023 
9024  /* start timing */
9025  SCIPclockStart(conflict->sbanalyzetime, set);
9026 
9027  /* get temporary memory for storing current LP basis */
9028  SCIP_CALL( SCIPsetAllocBufferArray(set, &cstat, lp->nlpicols) );
9029  SCIP_CALL( SCIPsetAllocBufferArray(set, &rstat, lp->nlpirows) );
9030 
9031  /* get current LP basis */
9032  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
9033 
9034  /* remember old bounds */
9035  oldlb = col->lb;
9036  oldub = col->ub;
9037 
9038  resolve = FALSE;
9039 
9040  /* is down branch infeasible? */
9041  if( col->sbdownvalid && SCIPsetIsGE(set, col->sbdown, lp->cutoffbound) )
9042  {
9043  newub = SCIPsetFeasCeil(set, col->primsol-1.0);
9044  if( newub >= col->lb - 0.5 )
9045  {
9046  SCIPsetDebugMsg(set, "analyzing conflict on infeasible downwards strongbranch for variable <%s>[%g,%g] in depth %d\n",
9048  SCIPtreeGetCurrentDepth(tree));
9049 
9051  conflict->nsbcalls++;
9052 
9053  /* change the upper bound */
9054  col->ub = newub;
9055  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, 1, &col->lpipos, &col->lb, &col->ub) );
9056 
9057  /* start LP timer */
9058  SCIPclockStart(stat->conflictlptime, set);
9059 
9060  /* resolve the LP */
9061  retcode = SCIPlpiSolveDual(lp->lpi);
9062 
9063  /* stop LP timer */
9064  SCIPclockStop(stat->conflictlptime, set);
9065 
9066  /* check return code of LP solving call */
9067  if( retcode != SCIP_LPERROR )
9068  {
9069  SCIP_CALL( retcode );
9070 
9071  /* count number of LP iterations */
9072  SCIP_CALL( SCIPlpiGetIterations(lp->lpi, &iter) );
9073  stat->nconflictlps++;
9074  stat->nconflictlpiterations += iter;
9075  conflict->nsbiterations += iter;
9076  SCIPsetDebugMsg(set, " -> resolved downwards strong branching LP in %d iterations\n", iter);
9077 
9078  /* perform conflict analysis on infeasible LP; last parameter guarantees status 'solved' on return */
9079  SCIP_CALL( conflictAnalyzeLP(conflict, conflictstore, blkmem, set, stat, transprob, origprob, tree, reopt, \
9080  lp, branchcand, eventqueue, cliquetable, TRUE, &dualraysuccess, &iter, &nconss, &nliterals, \
9081  &nreconvconss, &nreconvliterals, FALSE) );
9082  conflict->nsbsuccess += ((nconss > 0 || dualraysuccess) ? 1 : 0);
9083  conflict->nsbiterations += iter;
9084  conflict->nsbconfconss += nconss;
9085  conflict->nsbconfliterals += nliterals;
9086  conflict->nsbreconvconss += nreconvconss;
9087  conflict->nsbreconvliterals += nreconvliterals;
9088  if( downconflict != NULL )
9089  *downconflict = (nconss > 0);
9090  }
9091 
9092  /* reset the upper bound */
9093  col->ub = oldub;
9094  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, 1, &col->lpipos, &col->lb, &col->ub) );
9095 
9096  /* reset LP basis */
9097  SCIP_CALL( SCIPlpiSetBase(lp->lpi, cstat, rstat) );
9098 
9099  /* mark the LP to be resolved at the end */
9100  resolve = TRUE;
9101  }
9102  }
9103 
9104  /* is up branch infeasible? */
9105  if( col->sbupvalid && SCIPsetIsGE(set, col->sbup, lp->cutoffbound) )
9106  {
9107  newlb = SCIPsetFeasFloor(set, col->primsol+1.0);
9108  if( newlb <= col->ub + 0.5 )
9109  {
9110  SCIPsetDebugMsg(set, "analyzing conflict on infeasible upwards strongbranch for variable <%s>[%g,%g] in depth %d\n",
9112  SCIPtreeGetCurrentDepth(tree));
9113 
9115  conflict->nsbcalls++;
9116 
9117  /* change the lower bound */
9118  col->lb = newlb;
9119  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, 1, &col->lpipos, &col->lb, &col->ub) );
9120 
9121  /* start LP timer */
9122  SCIPclockStart(stat->conflictlptime, set);
9123 
9124  /* resolve the LP */
9125  retcode = SCIPlpiSolveDual(lp->lpi);
9126 
9127  /* stop LP timer */
9128  SCIPclockStop(stat->conflictlptime, set);
9129 
9130  /* check return code of LP solving call */
9131  if( retcode != SCIP_LPERROR )
9132  {
9133  SCIP_CALL( retcode );
9134 
9135  /* count number of LP iterations */
9136  SCIP_CALL( SCIPlpiGetIterations(lp->lpi, &iter) );
9137  stat->nconflictlps++;
9138  stat->nconflictlpiterations += iter;
9139  conflict->nsbiterations += iter;
9140  SCIPsetDebugMsg(set, " -> resolved upwards strong branching LP in %d iterations\n", iter);
9141 
9142  /* perform conflict analysis on infeasible LP; last parameter guarantees status 'solved' on return */
9143  SCIP_CALL( conflictAnalyzeLP(conflict, conflictstore, blkmem, set, stat, transprob, origprob, tree, reopt, \
9144  lp, branchcand, eventqueue, cliquetable, TRUE, &dualraysuccess, &iter, &nconss, &nliterals, \
9145  &nreconvconss, &nreconvliterals, FALSE) );
9146  conflict->nsbsuccess += ((nconss > 0 || dualraysuccess) ? 1 : 0);
9147  conflict->nsbiterations += iter;
9148  conflict->nsbconfconss += nconss;
9149  conflict->nsbconfliterals += nliterals;
9150  conflict->nsbreconvconss += nreconvconss;
9151  conflict->nsbreconvliterals += nreconvliterals;
9152  if( upconflict != NULL )
9153  *upconflict = (nconss > 0);
9154  }
9155 
9156  /* reset the lower bound */
9157  col->lb = oldlb;
9158  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, 1, &col->lpipos, &col->lb, &col->ub) );
9159 
9160  /* reset LP basis */
9161  SCIP_CALL( SCIPlpiSetBase(lp->lpi, cstat, rstat) );
9162 
9163  /* mark the LP to be resolved at the end */
9164  resolve = TRUE;
9165  }
9166  }
9167 
9168  /* free temporary memory for storing current LP basis */
9169  SCIPsetFreeBufferArray(set, &rstat);
9170  SCIPsetFreeBufferArray(set, &cstat);
9171 
9172  assert(lp->flushed);
9173 
9174  /* resolve LP if something has changed in order to synchronize LPI and LP */
9175  if ( resolve )
9176  {
9177  /* start LP timer */
9178  SCIPclockStart(stat->conflictlptime, set);
9179 
9180  /* resolve the LP */
9181  SCIP_CALL( SCIPlpiSolveDual(lp->lpi) );
9182 
9183  /* stop LP timer */
9184  SCIPclockStop(stat->conflictlptime, set);
9185  }
9186 
9187  /* stop timing */
9188  SCIPclockStop(conflict->sbanalyzetime, set);
9189 
9190  /* inform the LPI that strong branch starts (again) */
9192 
9193  return SCIP_OKAY;
9194 }
9195 
9196 /** gets time in seconds used for analyzing infeasible strong branching conflicts */
9198  SCIP_CONFLICT* conflict /**< conflict analysis data */
9199  )
9200 {
9201  assert(conflict != NULL);
9202 
9203  return SCIPclockGetTime(conflict->sbanalyzetime);
9204 }
9205 
9206 /** gets number of successful calls to dual proof analysis derived from infeasible LPs */
9208  SCIP_CONFLICT* conflict /**< conflict analysis data */
9209  )
9210 {
9211  assert(conflict != NULL);
9212 
9213  return conflict->ndualproofsinfsuccess;
9214 }
9215 
9216 /** gets number of globally valid dual proof constraints derived from infeasible LPs */
9218  SCIP_CONFLICT* conflict /**< conflict analysis data */
9219  )
9220 {
9221  assert(conflict != NULL);
9222 
9223  return conflict->ndualproofsinfglobal;
9224 }
9225 
9226 /** gets number of locally valid dual proof constraints derived from infeasible LPs */
9228  SCIP_CONFLICT* conflict /**< conflict analysis data */
9229  )
9230 {
9231  assert(conflict != NULL);
9232 
9233  return conflict->ndualproofsinflocal;
9234 }
9235 
9236 /** gets average length of dual proof constraints derived from infeasible LPs */
9238  SCIP_CONFLICT* conflict /**< conflict analysis data */
9239  )
9240 {
9241  assert(conflict != NULL);
9242 
9243  return conflict->dualproofsinfnnonzeros;
9244 }
9245 
9246 /** gets number of successfully analyzed dual proofs derived from bound exceeding LPs */
9248  SCIP_CONFLICT* conflict /**< conflict analysis data */
9249  )
9250 {
9251  assert(conflict != NULL);
9252 
9253  return conflict->ndualproofsbndsuccess;
9254 }
9255 
9256 /** gets number of globally applied dual proofs derived from bound exceeding LPs */
9258  SCIP_CONFLICT* conflict /**< conflict analysis data */
9259  )
9260 {
9261  assert(conflict != NULL);
9262 
9263  return conflict->ndualproofsbndglobal;
9264 }
9265 
9266 /** gets number of locally applied dual proofs derived from bound exceeding LPs */
9268  SCIP_CONFLICT* conflict /**< conflict analysis data */
9269  )
9270 {
9271  assert(conflict != NULL);
9272 
9273  return conflict->ndualproofsbndlocal;
9274 }
9275 
9276 /** gets average length of dual proofs derived from bound exceeding LPs */
9278  SCIP_CONFLICT* conflict /**< conflict analysis data */
9279  )
9280 {
9281  assert(conflict != NULL);
9282 
9283  return conflict->dualproofsbndnnonzeros;
9284 }
9285 
9286 /** gets number of calls to infeasible strong branching conflict analysis */
9288  SCIP_CONFLICT* conflict /**< conflict analysis data */
9289  )
9290 {
9291  assert(conflict != NULL);
9292 
9293  return conflict->nsbcalls;
9294 }
9295 
9296 /** gets number of calls to infeasible strong branching conflict analysis that yield at least one conflict constraint */
9298  SCIP_CONFLICT* conflict /**< conflict analysis data */
9299  )
9300 {
9301  assert(conflict != NULL);
9302 
9303  return conflict->nsbsuccess;
9304 }
9305 
9306 /** gets number of conflict constraints detected in infeasible strong branching conflict analysis */
9308  SCIP_CONFLICT* conflict /**< conflict analysis data */
9309  )
9310 {
9311  assert(conflict != NULL);
9312 
9313  return conflict->nsbconfconss;
9314 }
9315 
9316 /** gets total number of literals in conflict constraints created in infeasible strong branching conflict analysis */
9318  SCIP_CONFLICT* conflict /**< conflict analysis data */
9319  )
9320 {
9321  assert(conflict != NULL);
9322 
9323  return conflict->nsbconfliterals;
9324 }
9325 
9326 /** gets number of reconvergence constraints detected in infeasible strong branching conflict analysis */
9328  SCIP_CONFLICT* conflict /**< conflict analysis data */
9329  )
9330 {
9331  assert(conflict != NULL);
9332 
9333  return conflict->nsbreconvconss;
9334 }
9335 
9336 /** gets total number of literals in reconvergence constraints created in infeasible strong branching conflict analysis */
9338  SCIP_CONFLICT* conflict /**< conflict analysis data */
9339  )
9340 {
9341  assert(conflict != NULL);
9342 
9343  return conflict->nsbreconvliterals;
9344 }
9345 
9346 /** gets number of LP iterations in infeasible strong branching conflict analysis */
9348  SCIP_CONFLICT* conflict /**< conflict analysis data */
9349  )
9350 {
9351  assert(conflict != NULL);
9352 
9353  return conflict->nsbiterations;
9354 }
9355 
9356 
9357 
9358 
9359 /*
9360  * pseudo solution conflict analysis
9361  */
9362 
9363 /** analyzes a pseudo solution with objective value exceeding the current cutoff to find out the bound changes on
9364  * variables that were responsible for the objective value degradation;
9365  * on success, calls standard conflict analysis with the responsible variables as starting conflict set, thus creating
9366  * a conflict constraint out of the resulting conflict set;
9367  * updates statistics for pseudo solution conflict analysis
9368  */
9370  SCIP_CONFLICT* conflict, /**< conflict analysis data */
9371  BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
9372  SCIP_SET* set, /**< global SCIP settings */
9373  SCIP_STAT* stat, /**< problem statistics */
9374  SCIP_PROB* transprob, /**< transformed problem */
9375  SCIP_PROB* origprob, /**< original problem */
9376  SCIP_TREE* tree, /**< branch and bound tree */
9377  SCIP_REOPT* reopt, /**< reoptimization data structure */
9378  SCIP_LP* lp, /**< LP data */
9379  SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
9380  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9381  SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
9382  SCIP_Bool* success /**< pointer to store whether a conflict constraint was created, or NULL */
9383  )
9384 {
9385  SCIP_VAR** vars;
9386  SCIP_VAR* var;
9387  SCIP_Real* curvarlbs;
9388  SCIP_Real* curvarubs;
9389  int* lbchginfoposs;
9390  int* ubchginfoposs;
9391  SCIP_Real* pseudocoefs;
9392  SCIP_Real pseudolhs;
9393  SCIP_Real pseudoact;
9394  int nvars;
9395  int v;
9396 
9397  assert(conflict != NULL);
9398  assert(conflict->nconflictsets == 0);
9399  assert(set != NULL);
9400  assert(stat != NULL);
9401  assert(transprob != NULL);
9402  assert(lp != NULL);
9403  assert(!SCIPsetIsInfinity(set, -SCIPlpGetPseudoObjval(lp, set, transprob)));
9404  assert(!SCIPsetIsInfinity(set, lp->cutoffbound));
9405 
9406  if( success != NULL )
9407  *success = FALSE;
9408 
9409  /* check, if pseudo solution conflict analysis is enabled */
9410  if( !set->conf_enable || !set->conf_usepseudo )
9411  return SCIP_OKAY;
9412 
9413  /* check, if there are any conflict handlers to use a conflict set */
9414  if( set->nconflicthdlrs == 0 )
9415  return SCIP_OKAY;
9416 
9417  SCIPsetDebugMsg(set, "analyzing pseudo solution (obj: %g) that exceeds objective limit (%g)\n",
9418  SCIPlpGetPseudoObjval(lp, set, transprob), lp->cutoffbound);
9419 
9421  conflict->conflictset->usescutoffbound = TRUE;
9422 
9423  /* start timing */
9424  SCIPclockStart(conflict->pseudoanalyzetime, set);
9425  conflict->npseudocalls++;
9426 
9427  vars = transprob->vars;
9428  nvars = transprob->nvars;
9429  assert(nvars == 0 || vars != NULL);
9430 
9431  /* The current primal bound c* gives an upper bound for the current pseudo objective value:
9432  * min{c^T x | lb <= x <= ub} <= c*.
9433  * We have to transform this row into a >= inequality in order to use methods above:
9434  * -c* <= max{-c^T x | lb <= x <= ub}.
9435  * In the local subproblem, this row is violated. We want to undo bound changes while still keeping the
9436  * row violated.
9437  */
9438 
9439  /* get temporary memory for remembering variables' current bounds and corresponding bound change information
9440  * positions in variable's bound change information arrays
9441  */
9442  SCIP_CALL( SCIPsetAllocBufferArray(set, &curvarlbs, nvars) );
9443  SCIP_CALL( SCIPsetAllocBufferArray(set, &curvarubs, nvars) );
9444  SCIP_CALL( SCIPsetAllocBufferArray(set, &lbchginfoposs, nvars) );
9445  SCIP_CALL( SCIPsetAllocBufferArray(set, &ubchginfoposs, nvars) );
9446 
9447  /* get temporary memory for infeasibility proof coefficients */
9448  SCIP_CALL( SCIPsetAllocBufferArray(set, &pseudocoefs, nvars) );
9449 
9450  /* use a slightly tighter cutoff bound, because solutions with equal objective value should also be declared
9451  * infeasible
9452  */
9453  pseudolhs = -(lp->cutoffbound - SCIPsetSumepsilon(set));
9454 
9455  /* store the objective values as infeasibility proof coefficients, and recalculate the pseudo activity */
9456  pseudoact = 0.0;
9457  for( v = 0; v < nvars; ++v )
9458  {
9459  var = vars[v];
9460  pseudocoefs[v] = -SCIPvarGetObj(var);
9461  curvarlbs[v] = SCIPvarGetLbLocal(var);
9462  curvarubs[v] = SCIPvarGetUbLocal(var);
9463  lbchginfoposs[v] = var->nlbchginfos-1;
9464  ubchginfoposs[v] = var->nubchginfos-1;
9465 
9466  if( SCIPsetIsZero(set, pseudocoefs[v]) )
9467  {
9468  pseudocoefs[v] = 0.0;
9469  continue;
9470  }
9471 
9472  if( pseudocoefs[v] > 0.0 )
9473  pseudoact += pseudocoefs[v] * curvarubs[v];
9474  else
9475  pseudoact += pseudocoefs[v] * curvarlbs[v];
9476  }
9477  assert(SCIPsetIsFeasEQ(set, pseudoact, -SCIPlpGetPseudoObjval(lp, set, transprob)));
9478  SCIPsetDebugMsg(set, " -> recalculated pseudo infeasibility proof: %g <= %g\n", pseudolhs, pseudoact);
9479 
9480  /* check, if the pseudo row is still violated (after recalculation of pseudo activity) */
9481  if( SCIPsetIsFeasGT(set, pseudolhs, pseudoact) )
9482  {
9483  int nconss;
9484  int nliterals;
9485  int nreconvconss;
9486  int nreconvliterals;
9487 
9488  /* undo bound changes without destroying the infeasibility proof */
9489  SCIP_CALL( undoBdchgsProof(set, transprob, SCIPtreeGetCurrentDepth(tree), pseudocoefs, pseudolhs, &pseudoact,
9490  curvarlbs, curvarubs, lbchginfoposs, ubchginfoposs, NULL, NULL, NULL, lp->lpi) );
9491 
9492  /* analyze conflict on remaining bound changes */
9493  SCIP_CALL( conflictAnalyzeRemainingBdchgs(conflict, blkmem, set, stat, transprob, tree, FALSE, \
9494  lbchginfoposs, ubchginfoposs, &nconss, &nliterals, &nreconvconss, &nreconvliterals) );
9495  conflict->npseudosuccess += (nconss > 0 ? 1 : 0);
9496  conflict->npseudoconfconss += nconss;
9497  conflict->npseudoconfliterals += nliterals;
9498  conflict->npseudoreconvconss += nreconvconss;
9499  conflict->npseudoreconvliterals += nreconvliterals;
9500  if( success != NULL )
9501  *success = (nconss > 0);
9502  }
9503 
9504  /* free temporary memory */
9505  SCIPsetFreeBufferArray(set, &pseudocoefs);
9506  SCIPsetFreeBufferArray(set, &ubchginfoposs);
9507  SCIPsetFreeBufferArray(set, &lbchginfoposs);
9508  SCIPsetFreeBufferArray(set, &curvarubs);
9509  SCIPsetFreeBufferArray(set, &curvarlbs);
9510 
9511  /* flush conflict set storage */
9512  SCIP_CALL( SCIPconflictFlushConss(conflict, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, eventqueue, cliquetable) );
9513 
9514  /* stop timing */
9515  SCIPclockStop(conflict->pseudoanalyzetime, set);
9516 
9517  return SCIP_OKAY;
9518 }
9519 
9520 /** gets time in seconds used for analyzing pseudo solution conflicts */
9522  SCIP_CONFLICT* conflict /**< conflict analysis data */
9523  )
9524 {
9525  assert(conflict != NULL);
9526 
9527  return SCIPclockGetTime(conflict->pseudoanalyzetime);
9528 }
9529 
9530 /** gets number of calls to pseudo solution conflict analysis */
9532  SCIP_CONFLICT* conflict /**< conflict analysis data */
9533  )
9534 {
9535  assert(conflict != NULL);
9536 
9537  return conflict->npseudocalls;
9538 }
9539 
9540 /** gets number of calls to pseudo solution conflict analysis that yield at least one conflict constraint */
9542  SCIP_CONFLICT* conflict /**< conflict analysis data */
9543  )
9544 {
9545  assert(conflict != NULL);
9546 
9547  return conflict->npseudosuccess;
9548 }
9549 
9550 /** gets number of conflict constraints detected in pseudo solution conflict analysis */
9552  SCIP_CONFLICT* conflict /**< conflict analysis data */
9553  )
9554 {
9555  assert(conflict != NULL);
9556 
9557  return conflict->npseudoconfconss;
9558 }
9559 
9560 /** gets total number of literals in conflict constraints created in pseudo solution conflict analysis */
9562  SCIP_CONFLICT* conflict /**< conflict analysis data */
9563  )
9564 {
9565  assert(conflict != NULL);
9566 
9567  return conflict->npseudoconfliterals;
9568 }
9569 
9570 /** gets number of reconvergence constraints detected in pseudo solution conflict analysis */
9572  SCIP_CONFLICT* conflict /**< conflict analysis data */
9573  )
9574 {
9575  assert(conflict != NULL);
9576 
9577  return conflict->npseudoreconvconss;
9578 }
9579 
9580 /** gets total number of literals in reconvergence constraints created in pseudo solution conflict analysis */
9582  SCIP_CONFLICT* conflict /**< conflict analysis data */
9583  )
9584 {
9585  assert(conflict != NULL);
9586 
9587  return conflict->npseudoreconvliterals;
9588 }
9589 
9590 
9591 /** enables or disables all clocks of \p conflict, depending on the value of the flag */
9593  SCIP_CONFLICT* conflict, /**< the conflict analysis data for which all clocks should be enabled or disabled */
9594  SCIP_Bool enable /**< should the clocks of the conflict analysis data be enabled? */
9595  )
9596 {
9597  assert(conflict != NULL);
9598 
9599  SCIPclockEnableOrDisable(conflict->boundlpanalyzetime, enable);
9600  SCIPclockEnableOrDisable(conflict->dIBclock, enable);
9601  SCIPclockEnableOrDisable(conflict->inflpanalyzetime, enable);
9602  SCIPclockEnableOrDisable(conflict->propanalyzetime, enable);
9603  SCIPclockEnableOrDisable(conflict->pseudoanalyzetime, enable);
9604  SCIPclockEnableOrDisable(conflict->sbanalyzetime, enable);
9605 }
9606 
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:52
void SCIPconflictEnableOrDisableClocks(SCIP_CONFLICT *conflict, SCIP_Bool enable)
Definition: conflict.c:9592
SCIP_Longint SCIPconflictGetNStrongbranchSuccess(SCIP_CONFLICT *conflict)
Definition: conflict.c:9297
SCIP_EXPORT SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
Definition: lpi_clp.cpp:3678
static SCIP_Bool bdchginfoIsResolvable(SCIP_BDCHGINFO *bdchginfo)
Definition: conflict.c:3822
SCIP_Bool solisbasic
Definition: struct_lp.h:362
#define ALLOWLOCAL
Definition: conflict.c:166
static SCIP_RETCODE conflictInitProofset(SCIP_CONFLICT *conflict, BMS_BLKMEM *blkmem)
Definition: conflict.c:958
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:50
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)
Definition: conflict.c:6441
SCIP_CLOCK * propanalyzetime
void * SCIPpqueueRemove(SCIP_PQUEUE *pqueue)
Definition: misc.c:1434
SCIP_Bool lpissolved
Definition: struct_lp.h:116
SCIP_Real SCIPbdchginfoGetRelaxedBound(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:18388
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)
Definition: conflict.c:5811
void SCIPconflicthdlrSetInit(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_DECL_CONFLICTINIT((*conflictinit)))
Definition: conflict.c:719
SCIP_Real sbup
Definition: struct_lp.h:145
SCIP_Longint ninflpconfliterals
SCIP_Longint SCIPconflictGetNLocalChgBds(SCIP_CONFLICT *conflict)
Definition: conflict.c:3784
SCIP_RETCODE SCIPcreateConsLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
Definition: scip_sol.c:977
void SCIPgmlWriteEdge(FILE *file, unsigned int source, unsigned int target, const char *label, const char *color)
Definition: misc.c:585
SCIP_Bool primalchecked
Definition: struct_lp.h:112
SCIP_Bool SCIProwIsLocal(SCIP_ROW *row)
Definition: lp.c:17263
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5987
SCIP_EXPORT void SCIPsortedvecInsertIntPtrReal(int *intarray, void **ptrarray, SCIP_Real *realarray, int keyval, void *field1val, SCIP_Real field2val, int *len, int *pos)
SCIP_RETCODE SCIPconflictAnalyzeLP(SCIP_CONFLICT *conflict, SCIP_CONFLICTSTORE *conflictstore, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, SCIP_Bool *success)
Definition: conflict.c:8646
static SCIP_RETCODE addLocalRows(SCIP_SET *set, SCIP_PROB *transprob, SCIP_LP *lp, SCIP_AGGRROW *proofrow, SCIP_ROW **rows, SCIP_Real *dualsols, int *localrowinds, int *localrowdepth, int nlocalrows, SCIP_Real *proofact, int *validdepth, SCIP_Real *curvarlbs, SCIP_Real *curvarubs, SCIP_Bool *valid)
Definition: conflict.c:6785
SCIP_EXPORT SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:3893
#define BMSfreeBlockMemoryArrayNull(mem, ptr, num)
Definition: memory.h:459
#define NUMSTOP
Definition: conflict.c:6379
unsigned int repropagate
SCIP_Longint ninflpreconvconss
SCIP_Longint SCIPconflictGetNPropConflictConss(SCIP_CONFLICT *conflict)
Definition: conflict.c:5724
SCIP_Real SCIPaggrRowCalcEfficacyNorm(SCIP *scip, SCIP_AGGRROW *aggrrow)
Definition: cuts.c:2009
void SCIPpqueueFree(SCIP_PQUEUE **pqueue)
Definition: misc.c:1263
#define MINFRAC
Definition: conflict.c:167
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)
Definition: conflict.c:400
SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6045
static int conflictCalcMaxsize(SCIP_SET *set, SCIP_PROB *prob)
Definition: conflict.c:2074
internal methods for storing primal CIP solutions
void SCIPhistoryIncVSIDS(SCIP_HISTORY *history, SCIP_BRANCHDIR dir, SCIP_Real weight)
Definition: history.c:494
SCIP_RETCODE SCIPconflictAddBound(SCIP_CONFLICT *conflict, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_BDCHGIDX *bdchgidx)
Definition: conflict.c:4374
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:14816
SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Bool SCIPlpDiving(SCIP_LP *lp)
Definition: lp.c:17682
int nubchginfos
Definition: struct_var.h:260
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:140
SCIP_Longint ndualproofsinfsuccess
SCIP_Real SCIPgetVarLbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:1996
public methods for branch and bound tree
internal methods for branch and bound tree
SCIP_BDCHGIDX bdchgidx
Definition: struct_var.h:112
static SCIP_BDCHGINFO * conflictRemoveCand(SCIP_CONFLICT *conflict)
Definition: conflict.c:4692
void * SCIPpqueueFirst(SCIP_PQUEUE *pqueue)
Definition: misc.c:1454
SCIP_Real conflictlb
Definition: struct_var.h:210
static SCIP_Bool isBoundchgUseless(SCIP_SET *set, SCIP_BDCHGINFO *bdchginfo)
Definition: conflict.c:4217
SCIP_Longint SCIPconflictGetNPropSuccess(SCIP_CONFLICT *conflict)
Definition: conflict.c:5714
SCIP_EXPORT SCIP_Bool SCIPvarIsInLP(SCIP_VAR *var)
Definition: var.c:17392
void SCIPconflicthdlrSetExit(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_DECL_CONFLICTEXIT((*conflictexit)))
Definition: conflict.c:730
SCIP_PQUEUE * bdchgqueue
SCIP_EXPORT SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
Definition: lpi_clp.cpp:2843
SCIP_Bool primalfeasible
Definition: struct_lp.h:358
SCIP_Longint dualproofsinfnnonzeros
SCIP_EXPORT int SCIPvarGetNLocksUpType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
Definition: var.c:3250
public methods for memory management
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:986
SCIP_Longint nsbcalls
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)
Definition: conflict.c:1402
#define SCIPsetAllocBuffer(set, ptr)
Definition: set.h:1683
int nlpicols
Definition: struct_lp.h:307
SCIP_Bool SCIPsetIsFeasEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6385
void SCIPconflicthdlrSetInitsol(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_DECL_CONFLICTINITSOL((*conflictinitsol)))
Definition: conflict.c:741
SCIP_Longint SCIPconflictGetNBoundexceedingLPConflictConss(SCIP_CONFLICT *conflict)
Definition: conflict.c:8903
SCIP_PARAMDATA * SCIPparamGetData(SCIP_PARAM *param)
Definition: paramset.c:670
SCIP_Longint SCIPconflictGetNAppliedGlobalConss(SCIP_CONFLICT *conflict)
Definition: conflict.c:3764
SCIP_EXPORT void SCIPsortIntPtrReal(int *intarray, void **ptrarray, SCIP_Real *realarray, int len)
SCIP_Longint SCIPconflictGetNBoundexceedingLPIterations(SCIP_CONFLICT *conflict)
Definition: conflict.c:8943
SCIP_CLOCK * conflictlptime
Definition: struct_stat.h:159
#define SCIP_MAXSTRLEN
Definition: def.h:273
SCIP_EXPORT SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
Definition: lpi_clp.cpp:2953
public methods for conflict handler plugins and conflict analysis
static void lpbdchgsReset(SCIP_LPBDCHGS *lpbdchgs, int ncols)
Definition: conflict.c:877
static 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)
Definition: conflict.c:1228
SCIP_Longint SCIPconflictGetNPseudoReconvergenceLiterals(SCIP_CONFLICT *conflict)
Definition: conflict.c:9581
internal methods for clocks and timing issues
SCIP_Longint SCIPconflictGetNGlobalChgBds(SCIP_CONFLICT *conflict)
Definition: conflict.c:3754
int lpdepth
Definition: struct_lp.h:232
SCIP_BOUNDCHG * boundchgs
Definition: struct_var.h:125
SCIP_Bool SCIPsetIsPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6110
SCIP_Longint nappliedlocliterals
static long bound
SCIP_CLOCK * inflpanalyzetime
SCIP_Real * bdchgubs
struct SCIP_ParamData SCIP_PARAMDATA
Definition: type_paramset.h:77
SCIP_Longint SCIPconflictGetNPseudoConflictLiterals(SCIP_CONFLICT *conflict)
Definition: conflict.c:9561
#define SCIPsetAllocCleanBufferArray(set, ptr, num)
Definition: set.h:1696
SCIP_EXPORT SCIP_Bool SCIPbdchginfoIsRedundant(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:18397
SCIP_RETCODE SCIPbdchginfoCreate(SCIP_BDCHGINFO **bdchginfo, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_Real oldbound, SCIP_Real newbound)
Definition: var.c:16131
void SCIPconflicthdlrSetCopy(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_DECL_CONFLICTCOPY((*conflictcopy)))
Definition: conflict.c:697
#define SCIP_CALL_FINALLY(x, y)
Definition: def.h:406
SCIP_Longint SCIPconflictGetNInfeasibleLPSuccess(SCIP_CONFLICT *conflict)
Definition: conflict.c:8813
static SCIP_RETCODE undoBdchgsProof(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)
Definition: conflict.c:6166
SCIP_Longint nappliedglbliterals
int SCIPconsGetValidDepth(SCIP_CONS *cons)
Definition: cons.c:8160
SCIP_Longint SCIPconflictGetNPropCalls(SCIP_CONFLICT *conflict)
Definition: conflict.c:5704
SCIP_Longint npseudoreconvliterals
SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
static SCIP_Real getMinActivity(SCIP_SET *set, SCIP_PROB *transprob, SCIP_Real *coefs, int *inds, int nnz, SCIP_Real *curvarlbs, SCIP_Real *curvarubs)
Definition: conflict.c:2731
SCIP_EXPORT SCIP_BDCHGINFO * SCIPvarGetBdchgInfoUb(SCIP_VAR *var, int pos)
Definition: var.c:18087
static void proofsetCancelVarWithBound(SCIP_PROOFSET *proofset, SCIP_SET *set, SCIP_VAR *var, int pos, SCIP_Bool *valid)
Definition: conflict.c:1160
SCIP_EXPORT SCIP_Longint SCIPnodeGetNumber(SCIP_NODE *node)
Definition: tree.c:7429
int SCIPcolGetNNonz(SCIP_COL *col)
Definition: lp.c:16988
static SCIP_RETCODE lpbdchgsCreate(SCIP_LPBDCHGS **lpbdchgs, SCIP_SET *set, int ncols)
Definition: conflict.c:855
SCIP_Longint SCIPconflictGetNStrongbranchIterations(SCIP_CONFLICT *conflict)
Definition: conflict.c:9347
static SCIP_RETCODE conflictsetCalcInsertDepth(SCIP_CONFLICTSET *conflictset, SCIP_SET *set, SCIP_TREE *tree)
Definition: conflict.c:1802
interface methods for specific LP solvers
SCIP_Longint npropconfliterals
SCIP_Real SCIPsetInfinity(SCIP_SET *set)
Definition: set.c:5852
static SCIP_RETCODE conflictAddConflictBound(SCIP_CONFLICT *conflict, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_BDCHGINFO *bdchginfo, SCIP_Real relaxedbd)
Definition: conflict.c:4174
int SCIPprobGetNVars(SCIP_PROB *prob)
Definition: prob.c:2318
SCIP_BDCHGINFO * ubchginfos
Definition: struct_var.h:240
void SCIPconsMarkConflict(SCIP_CONS *cons)
Definition: cons.c:6983
SCIP_COL ** cols
Definition: struct_lp.h:291
int startnconss
Definition: struct_prob.h:76
int nlpirows
Definition: struct_lp.h:310
SCIP_Longint nappliedglbconss
SCIP_Real SCIPvarGetLbLP(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:12703
SCIP_RETCODE SCIPvarScaleVSIDS(SCIP_VAR *var, SCIP_Real scalar)
Definition: var.c:14902
unsigned int nboundchgs
Definition: struct_var.h:123
SCIP_Longint SCIPconflictGetNDualproofsInfGlobal(SCIP_CONFLICT *conflict)
Definition: conflict.c:9217
SCIP_Real SCIProwGetConstant(SCIP_ROW *row)
Definition: lp.c:17120
datastructures for conflict analysis
SCIP_Longint npseudoreconvconss
SCIP_EXPORT SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:17197
SCIP_EXPORT void SCIPsortedvecDelPosIntPtrReal(int *intarray, void **ptrarray, SCIP_Real *realarray, int pos, int *len)
void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:351
SCIP_EXPORT SCIP_Bool SCIPlpiIsInfinity(SCIP_LPI *lpi, SCIP_Real val)
Definition: lpi_clp.cpp:3905
SCIP_Longint SCIPconflictGetNInfeasibleLPReconvergenceConss(SCIP_CONFLICT *conflict)
Definition: conflict.c:8843
SCIP_Longint SCIPconflictGetNInfeasibleLPReconvergenceLiterals(SCIP_CONFLICT *conflict)
Definition: conflict.c:8853
#define FALSE
Definition: def.h:73
static void skipRedundantBdchginfos(SCIP_VAR *var, int *lbchginfopos, int *ubchginfopos)
Definition: conflict.c:6134
methods for the aggregation rows
static SCIP_BDCHGINFO * conflictFirstCand(SCIP_CONFLICT *conflict)
Definition: conflict.c:4736
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)
Definition: conflict.c:5626
SCIP_EXPORT SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17515
SCIP_Longint nlocchgbds
SCIP_EXPORT SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2488
SCIP_Bool solved
Definition: struct_lp.h:357
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:281
SCIP_EXPORT int SCIPnodeGetDepth(SCIP_NODE *node)
Definition: tree.c:7439
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)
Definition: conflict.c:629
SCIP_Bool dualchecked
Definition: struct_lp.h:361
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)
Definition: conflict.c:6383
SCIP_Bool SCIPsetIsZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6099
SCIP_EXPORT SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:17182
#define TRUE
Definition: def.h:72
#define SCIPdebug(x)
Definition: pub_message.h:84
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
SCIP_Longint SCIPconflictGetNPropConflictLiterals(SCIP_CONFLICT *conflict)
Definition: conflict.c:5734
SCIP_Real * relaxedbds
SCIP_EXPORT SCIP_RETCODE SCIPlpiStartStrongbranch(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:1992
unsigned int basisstatus
Definition: struct_lp.h:240
static SCIP_RETCODE propagateLongProof(SCIP_CONFLICT *conflict, SCIP_SET *set, SCIP_STAT *stat, SCIP_REOPT *reopt, SCIP_TREE *tree, BMS_BLKMEM *blkmem, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, SCIP_Real *coefs, int *inds, int nnz, SCIP_Real rhs, SCIP_CONFTYPE conflicttype, int validdepth)
Definition: conflict.c:2862
int SCIPpqueueNElems(SCIP_PQUEUE *pqueue)
Definition: misc.c:1468
int nlbchginfos
Definition: struct_var.h:258
void SCIPconflicthdlrSetPriority(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_SET *set, int priority)
Definition: conflict.c:793
SCIP_Real dualsol
Definition: struct_lp.h:98
SCIP_Real redcost
Definition: struct_lp.h:140
#define SCIPsetAllocBufferArray(set, ptr, num)
Definition: set.h:1685
int SCIPtreeGetCurrentDepth(SCIP_TREE *tree)
Definition: tree.c:8389
void SCIPaggrRowFree(SCIP *scip, SCIP_AGGRROW **aggrrow)
Definition: cuts.c:1616
SCIP_Longint npropcalls
unsigned int sbdownvalid
Definition: struct_lp.h:179
SCIP_RETCODE SCIPconflicthdlrExitsol(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_SET *set)
Definition: conflict.c:605
int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
Definition: set.c:5580
unsigned int basisstatus
Definition: struct_lp.h:170
SCIP_Longint nglbchgbds
SCIP_Real * bdchglbs
SCIP_EXPORT SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:17340
public methods for problem variables
SCIP_EXPORT SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2676
SCIP_Longint npropsuccess
SCIP_Real dualfarkas
Definition: struct_lp.h:206
#define EPSGE(x, y, eps)
Definition: def.h:192
static void conflictsetClear(SCIP_CONFLICTSET *conflictset)
Definition: conflict.c:1268
SCIP_ROW ** SCIPlpGetRows(SCIP_LP *lp)
Definition: lp.c:17447
SCIP_Bool diving
Definition: struct_lp.h:370
#define SCIPdebugMessage
Definition: pub_message.h:87
SCIP_RETCODE SCIPconflictFree(SCIP_CONFLICT **conflict, BMS_BLKMEM *blkmem)
Definition: conflict.c:3968
SCIP_Longint SCIPconflictGetNAppliedLiterals(SCIP_CONFLICT *conflict)
Definition: conflict.c:3744
SCIP_Real SCIPlpGetPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13246
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)
Definition: conflict.c:4318
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)
Definition: conflict.c:454
SCIP_EXPORT SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17136
void SCIPaggrRowRemoveZeros(SCIP *scip, SCIP_AGGRROW *aggrrow, SCIP_Bool useglbbounds, SCIP_Bool *valid)
Definition: cuts.c:2320
int SCIProwGetLPPos(SCIP_ROW *row)
Definition: lp.c:17363
int SCIPbdchgidxGetPos(SCIP_BDCHGIDX *bdchgidx)
Definition: var.c:18199
static SCIP_RETCODE conflictQueueBound(SCIP_CONFLICT *conflict, SCIP_SET *set, SCIP_BDCHGINFO *bdchginfo, SCIP_Real relaxedbd)
Definition: conflict.c:4237
SCIP_Bool SCIPsetIsNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6121
void SCIPconflicthdlrSetExitsol(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_DECL_CONFLICTEXITSOL((*conflictexitsol)))
Definition: conflict.c:752
static SCIP_RETCODE conflictInsertProofset(SCIP_CONFLICT *conflict, SCIP_SET *set, SCIP_PROOFSET *proofset)
Definition: conflict.c:1960
methods for creating output for visualization tools (VBC, BAK)
void SCIPclockEnableOrDisable(SCIP_CLOCK *clck, SCIP_Bool enable)
Definition: clock.c:251
#define QUAD_ASSIGN(a, constant)
Definition: dbldblarith.h:42
SCIP_Real SCIPconflictGetGlobalApplTime(SCIP_CONFLICT *conflict)
Definition: conflict.c:5684
#define SCIPsetFreeBufferArray(set, ptr)
Definition: set.h:1692
unsigned int basisstatus
Definition: struct_lp.h:100
#define BMSfreeMemory(ptr)
Definition: memory.h:137
SCIP_Longint SCIPconflictGetNDualproofsInfNonzeros(SCIP_CONFLICT *conflict)
Definition: conflict.c:9237
void SCIPvarAdjustLb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *lb)
Definition: var.c:6326
public methods for SCIP variables
static SCIP_RETCODE conflictFlushProofset(SCIP_CONFLICT *conflict, SCIP_CONFLICTSTORE *conflictstore, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable)
Definition: conflict.c:3245
SCIP_Longint SCIPconflictGetNStrongbranchReconvergenceLiterals(SCIP_CONFLICT *conflict)
Definition: conflict.c:9337
SCIP_Longint SCIPconflictGetNDualproofsBndSuccess(SCIP_CONFLICT *conflict)
Definition: conflict.c:9247
SCIP_Real SCIPconflictGetPseudoTime(SCIP_CONFLICT *conflict)
Definition: conflict.c:9521
#define SCIP_DECL_CONFLICTEXIT(x)
SCIP_Longint nappliedlocconss
SCIP_Longint SCIPconflictGetNInfeasibleLPConflictLiterals(SCIP_CONFLICT *conflict)
Definition: conflict.c:8833
SCIP_Longint SCIPconflictGetNPropReconvergenceConss(SCIP_CONFLICT *conflict)
Definition: conflict.c:5744
SCIP_LPSOLSTAT SCIPlpGetSolstat(SCIP_LP *lp)
Definition: lp.c:13047
SCIP_VISUAL * visual
Definition: struct_stat.h:172
int conflictlbcount
Definition: struct_var.h:261
SCIP_EXPORT void SCIPsortIntIntInt(int *intarray1, int *intarray2, int *intarray3, int len)
internal methods for LP management
SCIP_RETCODE SCIPaggrRowCreate(SCIP *scip, SCIP_AGGRROW **aggrrow)
Definition: cuts.c:1584
void SCIPpqueueClear(SCIP_PQUEUE *pqueue)
Definition: misc.c:1274
static void proofsetClear(SCIP_PROOFSET *proofset)
Definition: conflict.c:923
SCIP_Longint npseudosuccess
Definition: heur_padm.c:125
SCIP_Real SCIPconflictGetVarUb(SCIP_CONFLICT *conflict, SCIP_VAR *var)
Definition: conflict.c:4676
SCIP_Longint SCIPconflictGetNDualproofsInfSuccess(SCIP_CONFLICT *conflict)
Definition: conflict.c:9207
#define QUAD_TO_DBL(x)
Definition: dbldblarith.h:40
SCIP_Bool primalchecked
Definition: struct_lp.h:359
real eps
internal methods for branching and inference history
int * SCIPaggrRowGetInds(SCIP_AGGRROW *aggrrow)
Definition: cuts.c:2390
static char varGetChar(SCIP_VAR *var)
Definition: conflict.c:910
SCIP_Real SCIPconflictGetStrongbranchTime(SCIP_CONFLICT *conflict)
Definition: conflict.c:9197
SCIP_Longint SCIPconflictGetNAppliedLocalLiterals(SCIP_CONFLICT *conflict)
Definition: conflict.c:3804
SCIP_Bool strongbranching
Definition: struct_lp.h:367
void SCIPgmlWriteOpening(FILE *file, SCIP_Bool directed)
Definition: misc.c:673
SCIP_Longint SCIPconflictGetNPseudoConflictConss(SCIP_CONFLICT *conflict)
Definition: conflict.c:9551
SCIP_Longint ninflpiterations
#define POSTPROCESS
Definition: conflict.c:164
SCIP_Bool dualfeasible
Definition: struct_lp.h:113
SCIP_EXPORT SCIP_Real * SCIPvarGetMultaggrScalars(SCIP_VAR *var)
Definition: var.c:17459
void SCIPgmlWriteArc(FILE *file, unsigned int source, unsigned int target, const char *label, const char *color)
Definition: misc.c:629
SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition: scip_sol.c:320
int SCIPconflictstoreGetNDualInfProofs(SCIP_CONFLICTSTORE *conflictstore)
int SCIPlpGetNCols(SCIP_LP *lp)
Definition: lp.c:17437
SCIP_Real SCIPvarGetUbLP(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:12773
static SCIP_RETCODE conflictEnsureProofsetsMem(SCIP_CONFLICT *conflict, SCIP_SET *set, int num)
Definition: conflict.c:1911
SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6081
SCIP_HISTORY * glbhistorycrun
Definition: struct_stat.h:170
internal methods for propagators
SCIP_Longint npropreconvliterals
static SCIP_RETCODE getDualProof(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)
Definition: conflict.c:7099
static SCIP_Bool conflictsetIsRedundant(SCIP_CONFLICTSET *conflictset1, SCIP_CONFLICTSET *conflictset2)
Definition: conflict.c:1849
int SCIPtreeGetFocusDepth(SCIP_TREE *tree)
Definition: tree.c:8314
#define SCIPdebugCheckConflict(blkmem, set, node, bdchginfos, relaxedbds, nliterals)
Definition: debug.h:253
void SCIPhistoryScaleVSIDS(SCIP_HISTORY *history, SCIP_Real scalar)
Definition: history.c:508
SCIP_Longint ndualproofsinflocal
SCIP_Longint npropconfconss
SCIP_Longint nboundlpcalls
SCIP_Real * vals
Definition: struct_lp.h:220
enum SCIP_BranchDir SCIP_BRANCHDIR
Definition: type_history.h:39
SCIP_EXPORT SCIP_VAR * SCIPbdchginfoGetInferVar(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:18329
SCIP_Real conflictrelaxedub
Definition: struct_var.h:213
SCIP_Real avgnnz
Definition: struct_stat.h:117
SCIP_EXPORT SCIP_Bool SCIPvarIsRelaxationOnly(SCIP_VAR *var)
Definition: var.c:17304
SCIP_RETCODE SCIPnodeCutoff(SCIP_NODE *node, SCIP_SET *set, SCIP_STAT *stat, SCIP_TREE *tree, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_REOPT *reopt, SCIP_LP *lp, BMS_BLKMEM *blkmem)
Definition: tree.c:1176
SCIP_RETCODE SCIPconflictAnalyzePseudo(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_CLIQUETABLE *cliquetable, SCIP_Bool *success)
Definition: conflict.c:9369
void SCIPconflicthdlrSetFree(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_DECL_CONFLICTFREE((*conflictfree)))
Definition: conflict.c:708
SCIP_EXPORT SCIP_BOUNDCHGTYPE SCIPbdchginfoGetChgtype(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:18279
SCIP_Bool SCIPsetIsLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6027
const char * SCIPconflicthdlrGetDesc(SCIP_CONFLICTHDLR *conflicthdlr)
Definition: conflict.c:773
#define BOUNDSWITCH
Definition: conflict.c:163
static SCIP_Real aggrRowGetMinActivity(SCIP_SET *set, SCIP_PROB *transprob, SCIP_AGGRROW *aggrrow, SCIP_Real *curvarlbs, SCIP_Real *curvarubs, SCIP_Bool *infdelta)
Definition: conflict.c:2662
SCIP_BOUNDTYPE SCIPboundtypeOpposite(SCIP_BOUNDTYPE boundtype)
Definition: lp.c:17065
SCIP_CLOCK * setuptime
SCIP_RETCODE SCIPconflicthdlrExit(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_SET *set)
Definition: conflict.c:550
SCIP_CLOCK * pseudoanalyzetime
public methods for handling parameter settings
SCIP_RETCODE SCIPconflicthdlrInitsol(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_SET *set)
Definition: conflict.c:581
public methods for managing constraints
SCIP_DOMCHG * domchg
Definition: struct_tree.h:150
static void proofsetFree(SCIP_PROOFSET **proofset, BMS_BLKMEM *blkmem)
Definition: conflict.c:973
int lpiitlim
Definition: struct_lp.h:335
SCIP_Real lb
Definition: struct_lp.h:129
SCIP_Real dualsol
Definition: struct_lp.h:204
SCIP_Real conflictrelaxedlb
Definition: struct_var.h:212
static SCIP_RETCODE detectImpliedBounds(SCIP_SET *set, SCIP_PROB *prob, SCIP_CONFLICTSET *conflictset, int *nbdchgs, int *nredvars, SCIP_Bool *redundant)
Definition: conflict.c:2242
SCIP_Real SCIPconflicthdlrGetSetupTime(SCIP_CONFLICTHDLR *conflicthdlr)
Definition: conflict.c:829
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)
Definition: conflict.c:5998
#define SCIP_DECL_CONFLICTINITSOL(x)
SCIP_CLOCK * boundlpanalyzetime
#define BMSduplicateBlockMemoryArray(mem, ptr, source, num)
Definition: memory.h:453
SCIP_Longint SCIPconflictGetNInfeasibleLPConflictConss(SCIP_CONFLICT *conflict)
Definition: conflict.c:8823
SCIP_Real sbdown
Definition: struct_lp.h:144
SCIP_Longint ninflpreconvliterals
SCIP_EXPORT const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17017
#define SCIP_DECL_CONFLICTEXEC(x)
SCIP_BDCHGINFO ** tmpbdchginfos
SCIP_CLOCK * conflicttime
SCIP_EXPORT SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:17208
static SCIP_RETCODE separateAlternativeProofs(SCIP_CONFLICT *conflict, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_TREE *tree, BMS_BLKMEM *blkmem, SCIP_AGGRROW *proofrow, SCIP_Real *curvarlbs, SCIP_Real *curvarubs, SCIP_CONFTYPE conflicttype)
Definition: conflict.c:7383
SCIP_EXPORT SCIP_Bool SCIPbdchginfoIsTighter(SCIP_BDCHGINFO *bdchginfo1, SCIP_BDCHGINFO *bdchginfo2)
Definition: var.c:18422
void SCIPhistoryIncNActiveConflicts(SCIP_HISTORY *history, SCIP_BRANCHDIR dir, SCIP_Real length)
Definition: history.c:533
internal methods for storing and manipulating the main problem
#define SCIPerrorMessage
Definition: pub_message.h:55
#define SCIPdebugPrintf
Definition: pub_message.h:90
#define QUAD_EPSILON
Definition: dbldblarith.h:33
SCIP_EXPORT SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2004
int SCIPconflicthdlrGetPriority(SCIP_CONFLICTHDLR *conflicthdlr)
Definition: conflict.c:783
static SCIP_RETCODE conflictsetAddBounds(SCIP_CONFLICT *conflict, SCIP_CONFLICTSET *conflictset, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_BDCHGINFO **bdchginfos, int nbdchginfos)
Definition: conflict.c:1592
static SCIP_RETCODE conflictsetEnsureBdchginfosMem(SCIP_CONFLICTSET *conflictset, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
Definition: conflict.c:1358
SCIP_RETCODE SCIPconflictstoreAddDualraycons(SCIP_CONFLICTSTORE *conflictstore, SCIP_CONS *dualproof, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_REOPT *reopt, SCIP_Bool hasrelaxvar)
SCIP_Longint SCIPconflictGetNBoundexceedingLPReconvergenceConss(SCIP_CONFLICT *conflict)
Definition: conflict.c:8923
void SCIPconflicthdlrSetData(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_CONFLICTHDLRDATA *conflicthdlrdata)
Definition: conflict.c:686
SCIP_Bool SCIPconflicthdlrIsInitialized(SCIP_CONFLICTHDLR *conflicthdlr)
Definition: conflict.c:807
SCIP_Bool dualchecked
Definition: struct_lp.h:114
SCIP_COL ** cols
Definition: struct_lp.h:218
void SCIPclockReset(SCIP_CLOCK *clck)
Definition: clock.c:200
SCIP_Real SCIPaggrRowGetRhs(SCIP_AGGRROW *aggrrow)
Definition: cuts.c:2430
SCIP_Longint ndualproofsbndglobal
SCIP_Longint nconflictlpiterations
Definition: struct_stat.h:70
static SCIP_Bool conflictMarkBoundCheckPresence(SCIP_CONFLICT *conflict, SCIP_SET *set, SCIP_BDCHGINFO *bdchginfo, SCIP_Real relaxedbd)
Definition: conflict.c:4085
SCIP_EXPORT int SCIPbdchginfoGetDepth(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:18299
SCIP_EXPORT SCIP_RETCODE SCIPlpiSetBase(SCIP_LPI *lpi, const int *cstat, const int *rstat)
Definition: lpi_clp.cpp:3053
static SCIP_RETCODE runBoundHeuristic(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, 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)
Definition: conflict.c:7797
SCIP_CONFLICTHDLRDATA * conflicthdlrdata
static SCIP_RETCODE createAndAddProofcons(SCIP_CONFLICT *conflict, SCIP_CONFLICTSTORE *conflictstore, SCIP_PROOFSET *proofset, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, BMS_BLKMEM *blkmem)
Definition: conflict.c:2966
SCIP_NODE ** path
Definition: struct_tree.h:179
SCIP_Longint SCIPconflictGetNPseudoReconvergenceConss(SCIP_CONFLICT *conflict)
Definition: conflict.c:9571
SCIP_ROW ** lpirows
Definition: struct_lp.h:288
#define SCIPfreeBufferArrayNull(scip, ptr)
Definition: scip_mem.h:124
unsigned int sbupvalid
Definition: struct_lp.h:181
SCIP_Longint ndualproofsbndlocal
SCIP_RETCODE SCIPsolSetVal(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_TREE *tree, SCIP_VAR *var, SCIP_Real val)
Definition: sol.c:1068
SCIP_Longint SCIPconflictGetNAppliedLocalConss(SCIP_CONFLICT *conflict)
Definition: conflict.c:3794
const char * SCIPpropGetName(SCIP_PROP *prop)
Definition: prop.c:932
#define QUAD(x)
Definition: dbldblarith.h:38
SCIP_Real lhs
Definition: struct_lp.h:195
SCIP_EXPORT SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
Definition: lpi_clp.cpp:2752
SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
static SCIP_RETCODE conflictEnsureConflictsetsMem(SCIP_CONFLICT *conflict, SCIP_SET *set, int num)
Definition: conflict.c:1935
static SCIP_RETCODE convertToActiveVar(SCIP_VAR **var, SCIP_SET *set, SCIP_BOUNDTYPE *boundtype, SCIP_Real *bound)
Definition: conflict.c:4283
SCIP_Longint npropreconvconss
unsigned int pos
Definition: struct_var.h:113
static SCIP_Real conflictsetCalcScore(SCIP_CONFLICTSET *conflictset, SCIP_SET *set)
Definition: conflict.c:1388
SCIP_PROOFSET * proofset
SCIP_Real SCIPconflictGetBoundexceedingLPTime(SCIP_CONFLICT *conflict)
Definition: conflict.c:8873
static SCIP_RETCODE conflictsetCreate(SCIP_CONFLICTSET **conflictset, BMS_BLKMEM *blkmem)
Definition: conflict.c:1286
SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
Definition: clock.c:429
SCIP_Real SCIPsetFeasCeil(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6563
#define SCIPsetReallocBufferArray(set, ptr, num)
Definition: set.h:1689
SCIP_Real cutoffbound
Definition: struct_lp.h:274
#define NULL
Definition: lpi_spx1.cpp:155
SCIP_PROOFSET ** proofsets
static SCIP_RETCODE proofsetCreate(SCIP_PROOFSET **proofset, BMS_BLKMEM *blkmem)
Definition: conflict.c:937
SCIP_Longint SCIPconflictGetNStrongbranchReconvergenceConss(SCIP_CONFLICT *conflict)
Definition: conflict.c:9327
data structures for branch and bound tree
SCIP_HISTORY * glbhistory
Definition: struct_stat.h:169
#define REALABS(x)
Definition: def.h:187
SCIP_Longint SCIPconflictGetNDualproofsBndNonzeros(SCIP_CONFLICT *conflict)
Definition: conflict.c:9277
void SCIPaggrRowClear(SCIP_AGGRROW *aggrrow)
Definition: cuts.c:1984
SCIP_Longint ninflpcalls
SCIP_Longint nconflictlps
Definition: struct_stat.h:201
SCIP_RETCODE SCIPconflicthdlrFree(SCIP_CONFLICTHDLR **conflicthdlr, SCIP_SET *set)
Definition: conflict.c:485
SCIP_Longint SCIPconflictGetNStrongbranchConflictLiterals(SCIP_CONFLICT *conflict)
Definition: conflict.c:9317
struct SCIP_ConflicthdlrData SCIP_CONFLICTHDLRDATA
Definition: type_conflict.h:40
internal methods for global SCIP settings
internal methods for storing conflicts
#define SCIP_CALL(x)
Definition: def.h:364
SCIP_Longint SCIPconflictGetNDualproofsBndLocal(SCIP_CONFLICT *conflict)
Definition: conflict.c:9267
SCIP_EXPORT int SCIPvarGetNVubs(SCIP_VAR *var)
Definition: var.c:17901
SCIP_EXPORT void SCIPsortLongPtrRealRealBool(SCIP_Longint *longarray, void **ptrarray, SCIP_Real *realarray, SCIP_Real *realarray2, SCIP_Bool *boolarray, int len)
SCIP_Real activity
Definition: struct_lp.h:99
static SCIP_Real * proofsetGetVals(SCIP_PROOFSET *proofset)
Definition: conflict.c:1024
SCIP_EXPORT SCIP_RETCODE SCIPlpiChgSides(SCIP_LPI *lpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
Definition: lpi_clp.cpp:1158
SCIP_Bool SCIPsetIsFeasGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6473
int SCIPlpGetNRows(SCIP_LP *lp)
Definition: lp.c:17457
SCIP_VAR * h
Definition: circlepacking.c:59
#define SCIP_DECL_CONFLICTCOPY(x)
Definition: type_conflict.h:77
SCIP_Bool SCIPcutsTightenCoefficients(SCIP *scip, SCIP_Bool cutislocal, SCIP_Real *cutcoefs, SCIP_Real *cutrhs, int *cutinds, int *cutnnz, int *nchgcoefs)
Definition: cuts.c:1383
SCIP_Longint SCIPconflictGetNPseudoSuccess(SCIP_CONFLICT *conflict)
Definition: conflict.c:9541
SCIP_EXPORT SCIP_PROP * SCIPbdchginfoGetInferProp(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:18353
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:2956
SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6009
SCIP_Real vsidsweight
Definition: struct_stat.h:120
SCIP_EXPORT SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2595
SCIP_LPI * SCIPlpGetLPI(SCIP_LP *lp)
Definition: lp.c:17609
static SCIP_RETCODE conflictsetAddBound(SCIP_CONFLICTSET *conflictset, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_BDCHGINFO *bdchginfo, SCIP_Real relaxedbd)
Definition: conflict.c:1522
SCIP_LPI * lpi
Definition: struct_lp.h:286
#define SCIPquadprecProdDD(r, a, b)
Definition: dbldblarith.h:49
SCIP_Longint SCIPconflictGetNInfeasibleLPCalls(SCIP_CONFLICT *conflict)
Definition: conflict.c:8803
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)
Definition: conflict.c:4790
static SCIP_CONFTYPE proofsetGetConftype(SCIP_PROOFSET *proofset)
Definition: conflict.c:1057
SCIP_EXPORT SCIP_RETCODE SCIPlpiChgBounds(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
Definition: lpi_clp.cpp:1075
SCIP_CLOCK * sbanalyzetime
SCIP_Longint dualproofsbndnnonzeros
SCIP_Bool SCIPsetIsFeasLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6429
#define BMSduplicateMemoryArray(ptr, source, num)
Definition: memory.h:135
public methods for constraint handler plugins and constraints
static SCIP_RETCODE conflictAnalyzeRemainingBdchgs(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)
Definition: conflict.c:6498
SCIP_RETCODE SCIPclockCreate(SCIP_CLOCK **clck, SCIP_CLOCKTYPE clocktype)
Definition: clock.c:161
methods commonly used for presolving
SCIP_Longint nboundlpsuccess
SCIP_RETCODE SCIPconflicthdlrInit(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_SET *set)
Definition: conflict.c:513
void SCIPvarAdjustBd(SCIP_VAR *var, SCIP_SET *set, SCIP_BOUNDTYPE boundtype, SCIP_Real *bd)
Definition: var.c:6360
static SCIP_RETCODE conflictAnalyzeBoundexceedingLP(SCIP_CONFLICT *conflict, SCIP_CONFLICTSTORE *conflictstore, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, SCIP_Bool *success)
Definition: conflict.c:8567
SCIP_CONFLICTSET * conflictset
SCIP_DECL_SORTPTRCOMP(SCIPconflicthdlrComp)
Definition: conflict.c:353
SCIP_EXPORT SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition: var.c:17381
#define BMSfreeBlockMemory(mem, ptr)
Definition: memory.h:456
SCIP_Longint nboundlpreconvconss
internal methods for problem variables
SCIP_Bool SCIPsetIsIntegral(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6132
public data structures and miscellaneous methods
static SCIP_RETCODE conflictAnalyzeDualProof(SCIP_CONFLICT *conflict, SCIP_SET *set, SCIP_STAT *stat, 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)
Definition: conflict.c:7706
void SCIPnodePropagateAgain(SCIP_NODE *node, SCIP_SET *set, SCIP_STAT *stat, SCIP_TREE *tree)
Definition: tree.c:1236
static SCIP_RETCODE sortLocalRows(SCIP_SET *set, SCIP_AGGRROW *aggrrow, SCIP_ROW **rows, int *rowinds, int *rowdepth, int nrows)
Definition: conflict.c:6717
int SCIPtreeGetEffectiveRootDepth(SCIP_TREE *tree)
Definition: tree.c:8428
#define SCIP_Bool
Definition: def.h:70
#define SCIPsetFreeBuffer(set, ptr)
Definition: set.h:1690
SCIP_Real redcost
Definition: struct_lp.h:87
SCIP_Real SCIPsetSumepsilon(SCIP_SET *set)
Definition: set.c:5884
SCIP_Real * vals
#define BMSallocBlockMemoryArray(mem, ptr, num)
Definition: memory.h:445
SCIP_EXPORT SCIP_Bool SCIPbdchginfoHasInferenceReason(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:18408
SCIP_EXPORT SCIP_Bool SCIPbdchgidxIsEarlierNonNull(SCIP_BDCHGIDX *bdchgidx1, SCIP_BDCHGIDX *bdchgidx2)
Definition: var.c:18209
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:728
SCIP_EXPORT void SCIPsortIntInt(int *intarray1, int *intarray2, int len)
int ncontvars
Definition: struct_prob.h:65
static SCIP_RETCODE getFarkasProof(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)
Definition: conflict.c:6926
unsigned int depth
Definition: struct_tree.h:151
static const char * paramname[]
Definition: lpi_msk.c:4958
SCIP_Bool SCIPconflictApplicable(SCIP_SET *set)
Definition: conflict.c:3862
SCIP_RETCODE SCIPconsRelease(SCIP_CONS **cons, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: cons.c:6195
SCIP_EXPORT SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17677
static SCIP_RETCODE proofsetAddAggrrow(SCIP_PROOFSET *proofset, SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_AGGRROW *aggrrow)
Definition: conflict.c:1119
void SCIPclockFree(SCIP_CLOCK **clck)
Definition: clock.c:176
int SCIProwGetLPDepth(SCIP_ROW *row)
Definition: lp.c:17374
SCIP_Bool SCIPlpDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:17692
SCIP_Longint ndualproofsinfglobal
SCIP_RETCODE SCIPconflictAnalyzeStrongbranch(SCIP_CONFLICT *conflict, SCIP_CONFLICTSTORE *conflictstore, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, SCIP_COL *col, SCIP_Bool *downconflict, SCIP_Bool *upconflict)
Definition: conflict.c:8960
SCIP_EXPORT SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
Definition: lpi_clp.cpp:3819
#define MAX(x, y)
Definition: tclique_def.h:83
unsigned int basisstatus
Definition: struct_lp.h:88
SCIP_EXPORT int SCIPbdchginfoGetInferInfo(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:18364
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
Definition: lp.c:17154
#define SCIPdebugCheckConflictFrontier(blkmem, set, node, bdchginfo, bdchginfos, relaxedbds, nliterals, bdchgqueue, forcedbdchgqueue)
Definition: debug.h:254
SCIP_RETCODE SCIPcutGenerationHeuristicCMIR(SCIP *scip, SCIP_SOL *sol, SCIP_Bool postprocess, SCIP_Real boundswitch, SCIP_Bool usevbds, SCIP_Bool allowlocal, int maxtestdelta, int *boundsfortrans, SCIP_BOUNDTYPE *boundtypesfortrans, SCIP_Real minfrac, SCIP_Real maxfrac, SCIP_AGGRROW *aggrrow, SCIP_Real *cutcoefs, SCIP_Real *cutrhs, int *cutinds, int *cutnnz, SCIP_Real *cutefficacy, int *cutrank, SCIP_Bool *cutislocal, SCIP_Bool *success)
Definition: cuts.c:4281
SCIP_Real SCIPconflictstoreGetAvgNnzDualBndProofs(SCIP_CONFLICTSTORE *conflictstore)
public methods for LP management
SCIP_CONFTYPE conflicttype
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)
Definition: conflict.c:2092
#define SCIPsetDebugMsg
Definition: set.h:1721
void SCIPgmlWriteClosing(FILE *file)
Definition: misc.c:689
SCIP_Real conflictub
Definition: struct_var.h:211
SCIP_PQUEUE * forcedbdchgqueue
SCIP_Real oldbound
Definition: struct_var.h:108
SCIP_Bool SCIPprobAllColsInLP(SCIP_PROB *prob, SCIP_SET *set, SCIP_LP *lp)
Definition: prob.c:2275
SCIP_Longint SCIPconflictGetNStrongbranchConflictConss(SCIP_CONFLICT *conflict)
Definition: conflict.c:9307
static void conflictsetCalcConflictDepth(SCIP_CONFLICTSET *conflictset)
Definition: conflict.c:1758
SCIP_EXPORT SCIP_Bool SCIPbdchgidxIsEarlier(SCIP_BDCHGIDX *bdchgidx1, SCIP_BDCHGIDX *bdchgidx2)
Definition: var.c:18229
static SCIP_DECL_PARAMCHGD(paramChgdConflicthdlrPriority)
Definition: conflict.c:366
#define EPSLE(x, y, eps)
Definition: def.h:190
SCIP_EXPORT SCIP_BOUNDTYPE SCIPbdchginfoGetBoundtype(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:18289
SCIP_EXPORT SCIP_BOUNDTYPE SCIPbdchginfoGetInferBoundtype(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:18376
static SCIP_RETCODE tightenSingleVar(SCIP_CONFLICT *conflict, SCIP_SET *set, SCIP_STAT *stat, SCIP_TREE *tree, BMS_BLKMEM *blkmem, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, SCIP_VAR *var, SCIP_Real val, SCIP_Real rhs, SCIP_CONFTYPE prooftype, int validdepth)
Definition: conflict.c:2512
#define SCIPquadprecProdQD(r, a, b)
Definition: dbldblarith.h:54
static SCIP_RETCODE updateStatistics(SCIP_CONFLICT *conflict, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_CONFLICTSET *conflictset, int insertdepth)
Definition: conflict.c:2123
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:126
const char * SCIPconflicthdlrGetName(SCIP_CONFLICTHDLR *conflicthdlr)
Definition: conflict.c:763
int SCIPconflictGetNConflicts(SCIP_CONFLICT *conflict)
Definition: conflict.c:3724
SCIP_Longint SCIPconflictGetNBoundexceedingLPCalls(SCIP_CONFLICT *conflict)
Definition: conflict.c:8883
Constraint handler for linear constraints in their most general form, .
#define MAXFRAC
Definition: conflict.c:168
datastructures for problem statistics
SCIP_Longint nboundlpreconvliterals
SCIP_Real ub
Definition: struct_lp.h:130
SCIP_Longint nsbconfconss
#define BMSclearMemory(ptr)
Definition: memory.h:121
SCIP_Bool SCIPsetIsFeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6407
SCIP_Longint nsbconfliterals
SCIP_Longint SCIPconflictGetNBoundexceedingLPReconvergenceLiterals(SCIP_CONFLICT *conflict)
Definition: conflict.c:8933
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:14952
SCIP_ROW ** rows
Definition: struct_lp.h:293
SCIP_EXPORT SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17723
SCIP_Longint nboundlpiterations
#define SCIPquadprecSumQQ(r, a, b)
Definition: dbldblarith.h:58
#define debugPrintViolationInfo(...)
Definition: conflict.c:7336
SCIP_Real SCIPconflicthdlrGetTime(SCIP_CONFLICTHDLR *conflicthdlr)
Definition: conflict.c:839
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
Definition: lp.c:16904
SCIP_Bool SCIPprobIsTransformed(SCIP_PROB *prob)
Definition: prob.c:2253
SCIP_Real SCIPgetVarUbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:2132
int conflictubcount
Definition: struct_var.h:262
SCIP_EXPORT int SCIPbdchginfoGetPos(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:18309
SCIP_Longint npseudoconfliterals
SCIP_Longint ninflpconfconss
SCIP_EXPORT int SCIPvarGetNLocksDownType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
Definition: var.c:3193
#define SCIP_REAL_MAX
Definition: def.h:164
static SCIP_RETCODE conflictsetCopy(SCIP_CONFLICTSET **targetconflictset, BMS_BLKMEM *blkmem, SCIP_CONFLICTSET *sourceconflictset, int nadditionalelems)
Definition: conflict.c:1306
int SCIPparamGetInt(SCIP_PARAM *param)
Definition: paramset.c:725
SCIP_Real rhs
Definition: struct_lp.h:196
SCIP_Longint SCIPconflictGetNPseudoCalls(SCIP_CONFLICT *conflict)
Definition: conflict.c:9531
SCIP_Real constant
Definition: struct_lp.h:194
static void lpbdchgsFree(SCIP_LPBDCHGS **lpbdchgs, SCIP_SET *set)
Definition: conflict.c:890
SCIP_Bool SCIPconsIsGlobal(SCIP_CONS *cons)
Definition: cons.c:8306
datastructures for storing and manipulating the main problem
SCIP_RETCODE SCIPconflictstoreAddDualsolcons(SCIP_CONFLICTSTORE *conflictstore, SCIP_CONS *dualproof, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_REOPT *reopt, SCIP_Real scale, SCIP_Bool updateside, SCIP_Bool hasrelaxvar)
SCIP_Real * r
Definition: circlepacking.c:50
#define SCIP_REAL_MIN
Definition: def.h:165
SCIP_EXPORT SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17733
methods for sorting joint arrays of various types
SCIP_Real SCIPsetFeasFloor(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6552
SCIP_EXPORT SCIP_Bool SCIPlpiHasDualRay(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2542
SCIP_CONFTYPE conflicttype
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)
Definition: conflict.c:5772
SCIP_DOMCHGBOUND domchgbound
Definition: struct_var.h:153
SCIP_Real SCIPconflictGetInfeasibleLPTime(SCIP_CONFLICT *conflict)
Definition: conflict.c:8793
SCIP_RETCODE SCIPconflictCreate(SCIP_CONFLICT **conflict, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: conflict.c:3878
SCIP_EXPORT SCIP_VAR * SCIPbdchginfoGetVar(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:18269
SCIP_RETCODE SCIPsetConflicthdlrPriority(SCIP *scip, SCIP_CONFLICTHDLR *conflicthdlr, int priority)
SCIP_EXPORT SCIP_RETCODE SCIPlpiGetSol(SCIP_LPI *lpi, SCIP_Real *objval, SCIP_Real *primsol, SCIP_Real *dualsol, SCIP_Real *activity, SCIP_Real *redcost)
Definition: lpi_clp.cpp:2774
void SCIPvisualFoundConflict(SCIP_VISUAL *visual, SCIP_STAT *stat, SCIP_NODE *node)
Definition: visual.c:603
SCIP_RETCODE SCIPpqueueCreate(SCIP_PQUEUE **pqueue, int initsize, SCIP_Real sizefac, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), SCIP_DECL_PQUEUEELEMCHGPOS((*elemchgpos)))
Definition: misc.c:1236
SCIP_EXPORT SCIP_CONS * SCIPbdchginfoGetInferCons(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:18341
SCIP_Longint SCIPconflictGetNBoundexceedingLPSuccess(SCIP_CONFLICT *conflict)
Definition: conflict.c:8893
SCIP_RETCODE SCIPaggrRowAddObjectiveFunction(SCIP *scip, SCIP_AGGRROW *aggrrow, SCIP_Real rhs, SCIP_Real scale)
Definition: cuts.c:1863
SCIP_RETCODE SCIPaggrRowAddRow(SCIP *scip, SCIP_AGGRROW *aggrrow, SCIP_ROW *row, SCIP_Real weight, int sidetype)
Definition: cuts.c:1719
SCIP_LPSOLSTAT lpsolstat
Definition: struct_lp.h:109
unsigned int boundtype
Definition: struct_var.h:115
public methods for solutions
SCIP_Longint lastconflictnode
Definition: struct_stat.h:103
internal methods for conflict analysis
#define SCIPsetFreeCleanBufferArray(set, ptr)
Definition: set.h:1699
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_CLIQUETABLE *cliquetable, SCIP_CONFLICTSET *conflictset, int insertdepth, SCIP_Bool *success)
Definition: conflict.c:3364
void ** SCIPpqueueElems(SCIP_PQUEUE *pqueue)
Definition: misc.c:1479
static const SCIP_Real scalars[]
Definition: lp.c:5731
SCIP_Longint nsbsuccess
int lpipos
Definition: struct_lp.h:164
SCIP_EXPORT SCIP_Bool SCIPlpiIsOptimal(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2609
static int * proofsetGetInds(SCIP_PROOFSET *proofset)
Definition: conflict.c:1013
void SCIPsetSortConflicthdlrs(SCIP_SET *set)
Definition: set.c:4021
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_CLIQUETABLE *cliquetable, SCIP_VAR *var, SCIP_Real newbound, SCIP_BOUNDTYPE boundtype, SCIP_Bool probingchange)
Definition: tree.c:2075
static SCIP_RETCODE conflictAnalyzeInfeasibleLP(SCIP_CONFLICT *conflict, SCIP_CONFLICTSTORE *conflictstore, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, SCIP_Bool *success)
Definition: conflict.c:8491
unsigned int redundant
Definition: struct_var.h:117
public methods for conflict analysis handlers
SCIP_RETCODE SCIPcalcFlowCover(SCIP *scip, SCIP_SOL *sol, SCIP_Bool postprocess, SCIP_Real boundswitch, SCIP_Bool allowlocal, SCIP_AGGRROW *aggrrow, SCIP_Real *cutcoefs, SCIP_Real *cutrhs, int *cutinds, int *cutnnz, SCIP_Real *cutefficacy, int *cutrank, SCIP_Bool *cutislocal, SCIP_Bool *success)
Definition: cuts.c:7480
static SCIP_RETCODE ensureCandsSize(SCIP_SET *set, SCIP_VAR ***cands, SCIP_Real **candscores, SCIP_Real **newbounds, SCIP_Real **proofactdeltas, int *candssize, int num)
Definition: conflict.c:5961
SCIP_Longint nsbreconvliterals
SCIP_EXPORT SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17667
static void conflictsetFree(SCIP_CONFLICTSET **conflictset, BMS_BLKMEM *blkmem)
Definition: conflict.c:1342
SCIP_Longint nboundlpconfliterals
SCIP_Bool flushed
Definition: struct_lp.h:356
SCIP_EXPORT int SCIPvarGetMultaggrNVars(SCIP_VAR *var)
Definition: var.c:17435
int nrows
Definition: struct_lp.h:324
static SCIP_RETCODE conflictInsertConflictset(SCIP_CONFLICT *conflict, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_CONFLICTSET **conflictset)
Definition: conflict.c:1980
SCIP_VAR * var
Definition: struct_var.h:110
public methods for message output
SCIP_RETCODE SCIPconflictInit(SCIP_CONFLICT *conflict, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_CONFTYPE conftype, SCIP_Bool usescutoffbound)
Definition: conflict.c:4016
data structures for LP management
#define USEVBDS
Definition: conflict.c:165
SCIP_Real * conflictsetscores
SCIP_EXPORT SCIP_BDCHGINFO * SCIPvarGetBdchgInfoLb(SCIP_VAR *var, int pos)
Definition: var.c:18067
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10604
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)
Definition: conflict.c:4435
SCIP_Bool SCIPsetIsGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6063
datastructures for problem variables
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:8077
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)
Definition: conflict.c:5880
SCIP_Real lpobjval
Definition: struct_lp.h:261
SCIP_Real primsol
Definition: struct_lp.h:86
#define SCIP_Real
Definition: def.h:163
static SCIP_RETCODE addRowToAggrRow(SCIP_SET *set, SCIP_ROW *row, SCIP_Real weight, SCIP_AGGRROW *aggrrow)
Definition: conflict.c:6637
SCIP_Bool solisbasic
Definition: struct_lp.h:115
SCIP_VAR ** vars
Definition: struct_prob.h:55
enum SCIP_ConflictType SCIP_CONFTYPE
Definition: type_conflict.h:56
SCIP_Longint npseudocalls
SCIP_Real lpiobjlim
Definition: struct_lp.h:276
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:8097
SCIP_Longint SCIPconflictGetNStrongbranchCalls(SCIP_CONFLICT *conflict)
Definition: conflict.c:9287
SCIP_Longint SCIPconflictGetNInfeasibleLPIterations(SCIP_CONFLICT *conflict)
Definition: conflict.c:8863
SCIP_Real SCIPconflictGetVarLb(SCIP_CONFLICT *conflict, SCIP_VAR *var)
Definition: conflict.c:4659
SCIP_EXPORT SCIP_Bool SCIPlpiWasSolved(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2372
#define SCIPsetDebugMsgPrint
Definition: set.h:1722
const char * SCIProwGetName(SCIP_ROW *row)
Definition: lp.c:17213
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_CLIQUETABLE *cliquetable)
Definition: conflict.c:3515
SCIP_VAR ** SCIPprobGetVars(SCIP_PROB *prob)
Definition: prob.c:2363
SCIP_RETCODE SCIPconflictIsVarUsed(SCIP_CONFLICT *conflict, SCIP_VAR *var, SCIP_SET *set, SCIP_BOUNDTYPE boundtype, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool *used)
Definition: conflict.c:4599
#define BMSallocMemory(ptr)
Definition: memory.h:111
#define SCIP_INVALID
Definition: def.h:183
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:119
SCIP_CLOCK * dIBclock
#define SCIP_DECL_CONFLICTINIT(x)
Definition: type_conflict.h:93
internal methods for constraints and constraint handlers
static SCIP_Bool checkRedundancy(SCIP_SET *set, SCIP_CONFLICTSET *conflictset)
Definition: conflict.c:2177
SCIP_EXPORT SCIP_BDCHGINFO * SCIPvarGetBdchgInfo(SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: var.c:16287
#define SCIPquadprecSumDD(r, a, b)
Definition: dbldblarith.h:51
SCIP_Real primsol
Definition: struct_lp.h:139
SCIP_Longint nsbiterations
SCIP_Longint SCIPconflictGetNAppliedGlobalLiterals(SCIP_CONFLICT *conflict)
Definition: conflict.c:3774
SCIP_Longint nboundlpconfconss
static 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)
Definition: conflict.c:5339
int SCIPconflictstoreGetNDualBndProofs(SCIP_CONFLICTSTORE *conflictstore)
SCIP_RETCODE SCIPnodeAddCons(SCIP_NODE *node, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_TREE *tree, SCIP_CONS *cons)
Definition: tree.c:1596
#define SCIP_Longint
Definition: def.h:148
SCIP_Bool SCIPsetIsDualfeasZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6706
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4167
void SCIPconflicthdlrEnableOrDisableClocks(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_Bool enable)
Definition: conflict.c:817
SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6451
SCIP_Longint npseudoconfconss
SCIP_Real SCIPconflictstoreGetAvgNnzDualInfProofs(SCIP_CONFLICTSTORE *conflictstore)
SCIP_Bool dualfeasible
Definition: struct_lp.h:360
SCIP_Real SCIPgetVarBdAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:2268
SCIP_EXPORT SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:1871
static void conflictFreeTmpBdchginfos(SCIP_CONFLICT *conflict, BMS_BLKMEM *blkmem)
Definition: conflict.c:1252
SCIP_EXPORT int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:17360
SCIP_EXPORT SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
Definition: lpi_clp.cpp:2907
enum SCIP_Vartype SCIP_VARTYPE
Definition: type_var.h:60
SCIP_Longint SCIPconflictGetNAppliedConss(SCIP_CONFLICT *conflict)
Definition: conflict.c:3734
SCIP_RETCODE SCIPupgradeConsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_CONS **upgdcons)
static INLINE SCIP_Real SCIPaggrRowGetProbvarValue(SCIP_AGGRROW *aggrrow, int probindex)
Definition: cuts.h:240
SCIP_Real newbound
Definition: struct_var.h:109
SCIP_Longint SCIPconflictGetNBoundexceedingLPConflictLiterals(SCIP_CONFLICT *conflict)
Definition: conflict.c:8913
SCIP_RETCODE SCIPprobAddCons(SCIP_PROB *prob, SCIP_SET *set, SCIP_STAT *stat, SCIP_CONS *cons)
Definition: prob.c:1277
void SCIPbdchginfoFree(SCIP_BDCHGINFO **bdchginfo, BMS_BLKMEM *blkmem)
Definition: var.c:16161
SCIP_BDCHGINFO ** bdchginfos
void SCIPvarAdjustUb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *ub)
Definition: var.c:6343
#define BMSallocBlockMemory(mem, ptr)
Definition: memory.h:443
static int proofsetGetNVars(SCIP_PROOFSET *proofset)
Definition: conflict.c:1046
SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
Definition: lp.c:17164
SCIP_Longint SCIPconflictGetNPropReconvergenceLiterals(SCIP_CONFLICT *conflict)
Definition: conflict.c:5754
static SCIP_RETCODE conflictAnalyzeLP(SCIP_CONFLICT *conflict, SCIP_CONFLICTSTORE *conflictstore, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, SCIP_Bool diving, SCIP_Bool *dualproofsuccess, int *iterations, int *nconss, int *nliterals, int *nreconvconss, int *nreconvliterals, SCIP_Bool marklpunsolved)
Definition: conflict.c:8174
SCIP_EXPORT SCIP_RETCODE SCIPlpiGetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
Definition: lpi_clp.cpp:3782
unsigned int usescutoffbound
static SCIP_Real getMaxActivity(SCIP_SET *set, SCIP_PROB *transprob, SCIP_Real *coefs, int *inds, int nnz, SCIP_Real *curvarlbs, SCIP_Real *curvarubs)
Definition: conflict.c:2797
static void tightenCoefficients(SCIP_SET *set, SCIP_PROOFSET *proofset, int *nchgcoefs, SCIP_Bool *redundant)
Definition: conflict.c:7341
SCIP_CONFLICTSET ** conflictsets
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:122
SCIP_Real SCIPconflictGetPropTime(SCIP_CONFLICT *conflict)
Definition: conflict.c:5694
SCIP_Longint nnodes
Definition: struct_stat.h:73
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:199
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:429
SCIP_EXPORT int SCIPvarGetNCliques(SCIP_VAR *var, SCIP_Bool varfixing)
Definition: var.c:18019
SCIP_RETCODE SCIPvarGetProbvarSum(SCIP_VAR **var, SCIP_SET *set, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:12418
SCIP_Longint SCIPconflictGetNDualproofsInfLocal(SCIP_CONFLICT *conflict)
Definition: conflict.c:9227
#define SCIP_DECL_CONFLICTFREE(x)
Definition: type_conflict.h:85
SCIP_NODE * root
Definition: struct_tree.h:177
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1110
static SCIP_RETCODE conflictResolveBound(SCIP_CONFLICT *conflict, SCIP_SET *set, SCIP_BDCHGINFO *bdchginfo, SCIP_Real relaxedbd, int validdepth, SCIP_Bool *resolved)
Definition: conflict.c:4889
void SCIPgmlWriteNode(FILE *file, unsigned int id, const char *label, const char *nodetype, const char *fillcolor, const char *bordercolor)
Definition: misc.c:487
SCIP_RETCODE SCIPconflicthdlrCopyInclude(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_SET *set)
Definition: conflict.c:380
static SCIP_RETCODE conflictEnsureTmpbdchginfosMem(SCIP_CONFLICT *conflict, SCIP_SET *set, int num)
Definition: conflict.c:1204
SCIP_Bool primalfeasible
Definition: struct_lp.h:111
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)
Definition: conflict.c:5102
SCIP_Longint ndualproofsbndsuccess
#define SCIP_ALLOC(x)
Definition: def.h:375
#define SCIPABORT()
Definition: def.h:336
SCIP_LPSOLSTAT lpsolstat
Definition: struct_lp.h:343
SCIP_Longint SCIPconflictGetNDualproofsBndGlobal(SCIP_CONFLICT *conflict)
Definition: conflict.c:9257
const char * SCIPprobGetName(SCIP_PROB *prob)
Definition: prob.c:2309
int ncols
Definition: struct_lp.h:318
datastructures for global SCIP settings
static void conflictClear(SCIP_CONFLICT *conflict)
Definition: conflict.c:4004
static SCIP_Bool bdchginfoIsInvalid(SCIP_CONFLICT *conflict, SCIP_BDCHGINFO *bdchginfo)
Definition: conflict.c:1479
SCIP_Real lpobjval
Definition: struct_lp.h:110
SCIP_Longint nsbreconvconss
#define BMSreallocBlockMemoryArray(mem, ptr, oldnum, newnum)
Definition: memory.h:449
SCIP_EXPORT SCIP_Real SCIPvarGetAvgSol(SCIP_VAR *var)
Definition: var.c:13829
SCIP_EXPORT SCIP_Real SCIPbdchginfoGetOldbound(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:18249
SCIP_CONFLICTHDLRDATA * SCIPconflicthdlrGetData(SCIP_CONFLICTHDLR *conflicthdlr)
Definition: conflict.c:676
unsigned int local
Definition: struct_lp.h:249
static SCIP_Bool checkDualFeasibility(SCIP_SET *set, SCIP_ROW *row, SCIP_Real weight, SCIP_Bool *zerocontribution)
Definition: conflict.c:6669
SCIP_EXPORT SCIP_VAR ** SCIPvarGetMultaggrVars(SCIP_VAR *var)
Definition: var.c:17447
SCIP_EXPORT SCIP_BDCHGIDX * SCIPbdchginfoGetIdx(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:18319
SCIP_EXPORT SCIP_Real SCIPbdchginfoGetNewbound(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:18259
SCIP_Real activity
Definition: struct_lp.h:205
SCIP_Bool * usedcols
int len
Definition: struct_lp.h:226
int SCIPaggrRowGetNNz(SCIP_AGGRROW *aggrrow)
Definition: cuts.c:2400
SCIP_EXPORT int SCIPvarGetNVlbs(SCIP_VAR *var)
Definition: var.c:17859
static SCIP_RETCODE proofsetAddSparseData(SCIP_PROOFSET *proofset, BMS_BLKMEM *blkmem, SCIP_Real *vals, int *inds, int nnz, SCIP_Real rhs)
Definition: conflict.c:1068
SCIP_EXPORT int SCIPvarGetIndex(SCIP_VAR *var)
Definition: var.c:17350
int SCIPcolGetLPPos(SCIP_COL *col)
Definition: lp.c:16955
SCIP_BDCHGINFO * lbchginfos
Definition: struct_var.h:239
public methods for propagators
SCIP_Longint ninflpsuccess
#define SCIP_DECL_CONFLICTEXITSOL(x)
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:7181
SCIP_RETCODE SCIPpqueueInsert(SCIP_PQUEUE *pqueue, void *elem)
Definition: misc.c:1335
static SCIP_RETCODE tightenDualproof(SCIP_CONFLICT *conflict, SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_PROB *transprob, SCIP_TREE *tree, SCIP_AGGRROW *proofrow, int validdepth, SCIP_Real *curvarlbs, SCIP_Real *curvarubs, SCIP_Bool initialproof)
Definition: conflict.c:7514
static SCIP_Real proofsetGetRhs(SCIP_PROOFSET *proofset)
Definition: conflict.c:1035