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