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