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