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