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