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-2014 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/vbc.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] = SCIPvarGetNBinImpls(var, TRUE) + (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] = SCIPvarGetNBinImpls(var, FALSE) + (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( SCIPsetAllocBufferArray(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  else if( *nredvars > 0 )
1990  {
1991 #ifdef SCIP_DEBUG
1992  int nvars;
1993 #endif
1994 
1995  assert(bdchginfos == conflictset->bdchginfos);
1996  assert(relaxedbds == conflictset->relaxedbds);
1997  assert(sortvals == conflictset->sortvals);
1998 
1999  for( v = nbdchginfos - 1; v >= 0; --v )
2000  {
2001  /* if conflict variable was marked to be redundant remove it */
2002  if( redundants[v] )
2003  {
2004  SCIPdebugMessage("remove redundant variable <%s> from conflict set\n", SCIPvarGetName(SCIPbdchginfoGetVar(bdchginfos[v])));
2005 
2006  bdchginfos[v] = bdchginfos[nbdchginfos - 1];
2007  relaxedbds[v] = relaxedbds[nbdchginfos - 1];
2008  sortvals[v] = sortvals[nbdchginfos - 1];
2009 
2010  --nbdchginfos;
2011  }
2012  }
2013  assert((*nredvars) + nbdchginfos == conflictset->nbdchginfos);
2014 
2015  SCIPdebugMessage("removed %d redundant of %d variables from conflictset (%p)\n", (*nredvars), conflictset->nbdchginfos, (void*)conflictset);
2016  conflictset->nbdchginfos = nbdchginfos;
2017 
2018 #ifdef SCIP_DEBUG
2019  nvars = SCIPprobGetNVars(prob);
2020 
2021  SCIPdebugMessage("could shorten conflict (in %s) to:\n", SCIPprobGetName(prob));
2022  SCIPdebugMessage("[");
2023  for( v = 0; v < nbdchginfos; ++v )
2024  {
2025  int confidx;
2026 
2027  var = SCIPbdchginfoGetVar(bdchginfos[v]);;
2028 
2029  confidx = SCIPvarGetProbindex(var);
2030  assert(confidx >= 0);
2031 
2032  if( boundtypes[v] )
2033  confidx += nvars;
2034 
2035  /* if conflict variable was marked to be redundant remove it */
2036  if( redundants[confidx] > 0 )
2037  {
2038  SCIPdebugPrintf("%s %s %g", SCIPvarGetName(SCIPbdchginfoGetVar(bdchginfos[v])), (!boundtypes[v]) ? ">=" : "<=", bounds[v]);
2039  if( v < nbdchginfos - 1 )
2040  SCIPdebugPrintf(", ");
2041  }
2042  }
2043  SCIPdebugPrintf("]\n");
2044 #endif
2045 
2046  }
2047 
2048  SCIPsetFreeBufferArray(set, &redundants);
2049  SCIPsetFreeBufferArray(set, &vars);
2050  }
2051 
2052  /* free temporary memory */
2053  SCIPsetFreeBufferArray(set, &nbinimpls);
2054  SCIPsetFreeBufferArray(set, &bounds);
2055  SCIPsetFreeBufferArray(set, &boundtypes);
2056 
2057  *nredvars += ntrivialredvars;
2058 
2059  return SCIP_OKAY;
2060 }
2061 
2062 /** adds the given conflict set as conflict constraint to the problem */
2063 static
2065  SCIP_CONFLICT* conflict, /**< conflict analysis data */
2066  BMS_BLKMEM* blkmem, /**< block memory */
2067  SCIP_SET* set, /**< global SCIP settings */
2068  SCIP_STAT* stat, /**< dynamic problem statistics */
2069  SCIP_PROB* transprob, /**< transformed problem after presolve */
2070  SCIP_PROB* origprob, /**< original problem */
2071  SCIP_TREE* tree, /**< branch and bound tree */
2072  SCIP_LP* lp, /**< current LP data */
2073  SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
2074  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2075  SCIP_CONFLICTSET* conflictset, /**< conflict set to add to the tree */
2076  int insertdepth, /**< depth level at which the conflict set should be added */
2077  SCIP_Bool* success /**< pointer to store whether the addition was successful */
2078  )
2079 {
2080  SCIP_Bool redundant;
2081  int h;
2082 
2083  assert(conflict != NULL);
2084  assert(tree != NULL);
2085  assert(tree->path != NULL);
2086  assert(conflictset != NULL);
2087  assert(conflictset->validdepth <= insertdepth);
2088  assert(success != NULL);
2089 
2090  *success = FALSE;
2091  redundant = FALSE;
2092 
2093  /* try to derive global bound changes and shorten the conflictset by using implication and clique and variable bound
2094  * information
2095  */
2096  if( conflictset->nbdchginfos > 1 && insertdepth == 0 )
2097  {
2098  int nbdchgs;
2099  int nredvars;
2100  int oldnbdchginfos = conflictset->nbdchginfos;
2101 
2102  assert(conflictset->validdepth == 0);
2103 
2104  SCIPclockStart(conflict->dIBclock, set);
2105 
2106  /* find global bound changes which can be derived from the new conflict set */
2107  SCIP_CALL( detectImpliedBounds(set, transprob, conflictset, &nbdchgs, &nredvars, &redundant) );
2108 
2109  /* debug check for reduced conflict set */
2110  if( nredvars > 0 )
2111  {
2112  /* check conflict set on debugging solution */
2113  SCIP_CALL( SCIPdebugCheckConflict(blkmem, set, tree->root, conflictset->bdchginfos, conflictset->relaxedbds, conflictset->nbdchginfos) ); /*lint !e506 !e774*/
2114  }
2115 
2116  SCIPdebugMessage(" -> conflict set removed %d redundant variables (old nvars %d, new nvars = %d)\n", nredvars, oldnbdchginfos, conflictset->nbdchginfos);
2117  SCIPdebugMessage(" -> conflict set led to %d global bound changes %s(cdpt:%d, fdpt:%d, confdpt:%d, len:%d):\n",
2118  nbdchgs, redundant ? "(conflict became redundant) " : "", SCIPtreeGetCurrentDepth(tree), SCIPtreeGetFocusDepth(tree),
2119  conflictset->conflictdepth, conflictset->nbdchginfos);
2120  SCIPdebug(conflictsetPrint(conflictset));
2121 
2122  SCIPclockStop(conflict->dIBclock, set);
2123 
2124  if( redundant )
2125  {
2126  if( nbdchgs > 0 )
2127  *success = TRUE;
2128 
2129  return SCIP_OKAY;
2130  }
2131  }
2132 
2133  /* in case the conflict set contains only one bound change which is globally valid we apply that bound change
2134  * directly (except if we are in strong branching or diving - in this case a bound change would yield an unflushed LP
2135  * and is not handled when restoring the information)
2136  *
2137  * @note A bound change can only be applied if it is are related to the active node or if is a global bound
2138  * change. Bound changes which are related to any other node cannot be handled at point due to the internal
2139  * data structure
2140  */
2141  if( conflictset->nbdchginfos == 1 && insertdepth == 0 && !lp->strongbranching && !lp->diving )
2142  {
2143  SCIP_VAR* var;
2144  SCIP_Real bound;
2145  SCIP_BOUNDTYPE boundtype;
2146 
2147  var = conflictset->bdchginfos[0]->var;
2148  assert(var != NULL);
2149 
2150  boundtype = SCIPboundtypeOpposite((SCIP_BOUNDTYPE) conflictset->bdchginfos[0]->boundtype);
2151  bound = conflictset->relaxedbds[0];
2152 
2153  /* for continuous variables, we can only use the relaxed version of the bounds negation: !(x <= u) -> x >= u */
2154  if( SCIPvarIsIntegral(var) )
2155  {
2156  assert(SCIPsetIsIntegral(set, bound));
2157  bound += (boundtype == SCIP_BOUNDTYPE_LOWER ? +1.0 : -1.0);
2158  }
2159 
2160  SCIPdebugMessage(" -> apply global bound change: <%s> %s %g\n",
2161  SCIPvarGetName(var), boundtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", bound);
2162 
2163  SCIP_CALL( SCIPnodeAddBoundchg(tree->path[conflictset->validdepth], blkmem, set, stat, transprob, origprob, tree, lp, branchcand,
2164  eventqueue, var, bound, boundtype, FALSE) );
2165 
2166  *success = TRUE;
2167  SCIP_CALL( updateStatistics(conflict, blkmem, set, stat, conflictset, insertdepth) );
2168  }
2169  else
2170  {
2171  /* sort conflict handlers by priority */
2173 
2174  /* call conflict handlers to create a conflict constraint */
2175  for( h = 0; h < set->nconflicthdlrs; ++h )
2176  {
2177  SCIP_RESULT result;
2178 
2179  SCIP_CALL( SCIPconflicthdlrExec(set->conflicthdlrs[h], set, tree->path[insertdepth],
2180  tree->path[conflictset->validdepth], conflictset->bdchginfos, conflictset->relaxedbds, conflictset->nbdchginfos, *success, &result) );
2181  if( result == SCIP_CONSADDED )
2182  {
2183  *success = TRUE;
2184  SCIP_CALL( updateStatistics(conflict, blkmem, set, stat, conflictset, insertdepth) );
2185  }
2186 
2187  SCIPdebugMessage(" -> call conflict handler <%s> (prio=%d) to create conflict set with %d bounds returned result %d\n",
2189  conflictset->nbdchginfos, result);
2190  }
2191  }
2192 
2193  return SCIP_OKAY;
2194 }
2195 
2196 /** adds the collected conflict constraints to the corresponding nodes; the best set->conf_maxconss conflict constraints
2197  * are added to the node of their validdepth; additionally (if not yet added, and if repropagation is activated), the
2198  * conflict constraint that triggers the earliest repropagation is added to the node of its validdepth
2199  */
2201  SCIP_CONFLICT* conflict, /**< conflict analysis data */
2202  BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
2203  SCIP_SET* set, /**< global SCIP settings */
2204  SCIP_STAT* stat, /**< dynamic problem statistics */
2205  SCIP_PROB* transprob, /**< transformed problem */
2206  SCIP_PROB* origprob, /**< original problem */
2207  SCIP_TREE* tree, /**< branch and bound tree */
2208  SCIP_LP* lp, /**< current LP data */
2209  SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
2210  SCIP_EVENTQUEUE* eventqueue /**< event queue */
2211  )
2212 {
2213  assert(conflict != NULL);
2214  assert(set != NULL);
2215  assert(stat != NULL);
2216  assert(transprob != NULL);
2217  assert(tree != NULL);
2218 
2219  /* is there anything to do? */
2220  if( conflict->nconflictsets > 0 )
2221  {
2222  SCIP_CONFLICTSET* repropconflictset;
2223  int nconflictsetsused;
2224  int focusdepth;
2225 #ifndef NDEBUG
2226  int currentdepth;
2227 #endif
2228  int cutoffdepth;
2229  int repropdepth;
2230  int maxconflictsets;
2231  int maxsize;
2232  int i;
2233 
2234  /* calculate the maximal number of conflict sets to accept, and the maximal size of each accepted conflict set */
2235  maxconflictsets = (set->conf_maxconss == -1 ? INT_MAX : set->conf_maxconss);
2236  maxsize = conflictCalcMaxsize(set, transprob);
2237 
2238  focusdepth = SCIPtreeGetFocusDepth(tree);
2239 #ifndef NDEBUG
2240  currentdepth = SCIPtreeGetCurrentDepth(tree);
2241  assert(focusdepth <= currentdepth);
2242  assert(currentdepth == tree->pathlen-1);
2243 #endif
2244 
2245  SCIPdebugMessage("flushing %d conflict sets at focus depth %d (maxconflictsets: %d, maxsize: %d)\n",
2246  conflict->nconflictsets, focusdepth, maxconflictsets, maxsize);
2247 
2248  /* mark the focus node to have produced conflict sets in the VBC tool output */
2249  SCIPvbcFoundConflict(stat->vbc, stat, tree->path[focusdepth]);
2250 
2251  /* insert the conflict sets at the corresponding nodes */
2252  nconflictsetsused = 0;
2253  cutoffdepth = INT_MAX;
2254  repropdepth = INT_MAX;
2255  repropconflictset = NULL;
2256  for( i = 0; i < conflict->nconflictsets && nconflictsetsused < maxconflictsets; ++i )
2257  {
2258  SCIP_CONFLICTSET* conflictset;
2259 
2260  conflictset = conflict->conflictsets[i];
2261  assert(conflictset != NULL);
2262  assert(0 <= conflictset->validdepth);
2263  assert(conflictset->validdepth <= conflictset->insertdepth);
2264  assert(conflictset->insertdepth <= focusdepth);
2265  assert(conflictset->insertdepth <= conflictset->repropdepth);
2266  assert(conflictset->repropdepth <= currentdepth || conflictset->repropdepth == INT_MAX); /* INT_MAX for dive/probing/strong */
2267  assert(conflictset->conflictdepth <= currentdepth || conflictset->conflictdepth == INT_MAX); /* INT_MAX for dive/probing/strong */
2268 
2269  /* ignore conflict sets that are only valid at a node that was already cut off */
2270  if( conflictset->insertdepth >= cutoffdepth )
2271  {
2272  SCIPdebugMessage(" -> ignoring conflict set with insertdepth %d >= cutoffdepth %d\n",
2273  conflictset->validdepth, cutoffdepth);
2274  continue;
2275  }
2276 
2277  /* if no conflict bounds exist, the node and its sub tree in the conflict set's valid depth can be
2278  * cut off completely
2279  */
2280  if( conflictset->nbdchginfos == 0 )
2281  {
2282  SCIPdebugMessage(" -> empty conflict set in depth %d cuts off sub tree at depth %d\n",
2283  focusdepth, conflictset->validdepth);
2284 
2285  SCIPnodeCutoff(tree->path[conflictset->validdepth], set, stat, tree);
2286  cutoffdepth = conflictset->validdepth;
2287  continue;
2288  }
2289 
2290  /* if the conflict set is too long, use the conflict set only if it decreases the repropagation depth */
2291  if( conflictset->nbdchginfos > maxsize )
2292  {
2293  SCIPdebugMessage(" -> conflict set is too long: %d > %d literals\n", conflictset->nbdchginfos, maxsize);
2294  if( set->conf_keepreprop && conflictset->repropagate && conflictset->repropdepth < repropdepth )
2295  {
2296  repropdepth = conflictset->repropdepth;
2297  repropconflictset = conflictset;
2298  }
2299  }
2300  else
2301  {
2302  SCIP_Bool success;
2303 
2304  /* call conflict handlers to create a conflict constraint */
2305  SCIP_CALL( conflictAddConflictCons(conflict, blkmem, set, stat, transprob, origprob,
2306  tree, lp, branchcand, eventqueue, conflictset, conflictset->insertdepth, &success) );
2307 
2308  if( success )
2309  {
2310  SCIPdebugMessage(" -> conflict set %d/%d added (cdpt:%d, fdpt:%d, insert:%d, valid:%d, conf:%d, reprop:%d, len:%d):\n",
2311  nconflictsetsused+1, maxconflictsets, SCIPtreeGetCurrentDepth(tree), SCIPtreeGetFocusDepth(tree),
2312  conflictset->insertdepth, conflictset->validdepth, conflictset->conflictdepth, conflictset->repropdepth,
2313  conflictset->nbdchginfos);
2314  SCIPdebug(conflictsetPrint(conflictset));
2315 
2316  if( conflictset->repropagate && conflictset->repropdepth <= repropdepth )
2317  {
2318  repropdepth = conflictset->repropdepth;
2319  repropconflictset = NULL;
2320  }
2321  nconflictsetsused++;
2322  }
2323  }
2324  }
2325 
2326  /* reactivate propagation on the first node where one of the new conflict sets trigger a deduction */
2327  if( set->conf_repropagate && repropdepth < cutoffdepth && repropdepth < tree->pathlen )
2328  {
2329  assert(0 <= repropdepth && repropdepth < tree->pathlen);
2330  assert((int) tree->path[repropdepth]->depth == repropdepth);
2331 
2332  /* if the conflict constraint of smallest repropagation depth was not yet added, insert it now */
2333  if( repropconflictset != NULL )
2334  {
2335  SCIP_Bool success;
2336 
2337  assert(repropconflictset->repropagate);
2338  assert(repropconflictset->repropdepth == repropdepth);
2339 
2340  SCIP_CALL( conflictAddConflictCons(conflict, blkmem, set, stat, transprob, origprob,
2341  tree, lp, branchcand, eventqueue, repropconflictset, repropdepth, &success) );
2342 #ifdef SCIP_DEBUG
2343  if( success )
2344  {
2345  SCIPdebugMessage(" -> additional reprop conflict set added (cdpt:%d, fdpt:%d, insert:%d, valid:%d, conf:%d, reprop:%d, len:%d):\n",
2347  repropconflictset->insertdepth, repropconflictset->validdepth, repropconflictset->conflictdepth,
2348  repropconflictset->repropdepth, repropconflictset->nbdchginfos);
2349  SCIPdebug(conflictsetPrint(repropconflictset));
2350  }
2351 #endif
2352  }
2353 
2354  /* mark the node in the repropdepth to be propagated again */
2355  SCIPnodePropagateAgain(tree->path[repropdepth], set, stat, tree);
2356 
2357  SCIPdebugMessage("marked node %p in depth %d to be repropagated due to conflicts found in depth %d\n",
2358  (void*)tree->path[repropdepth], repropdepth, focusdepth);
2359  }
2360 
2361  /* free the conflict storage */
2362  for( i = 0; i < conflict->nconflictsets; ++i )
2363  {
2364  conflictsetFree(&conflict->conflictsets[i], blkmem);
2365  }
2366  conflict->nconflictsets = 0;
2367  }
2368 
2369  /* free all temporarily created bound change information data */
2370  conflictFreeTmpBdchginfos(conflict, blkmem);
2371 
2372  return SCIP_OKAY;
2373 }
2374 
2375 /** returns the current number of conflict sets in the conflict set storage */
2377  SCIP_CONFLICT* conflict /**< conflict analysis data */
2378  )
2379 {
2380  assert(conflict != NULL);
2381 
2382  return conflict->nconflictsets;
2383 }
2384 
2385 /** returns the total number of conflict constraints that were added to the problem */
2387  SCIP_CONFLICT* conflict /**< conflict analysis data */
2388  )
2389 {
2390  assert(conflict != NULL);
2391 
2392  return conflict->nappliedglbconss + conflict->nappliedlocconss;
2393 }
2394 
2395 /** returns the total number of literals in conflict constraints that were added to the problem */
2397  SCIP_CONFLICT* conflict /**< conflict analysis data */
2398  )
2399 {
2400  assert(conflict != NULL);
2401 
2402  return conflict->nappliedglbliterals + conflict->nappliedlocliterals;
2403 }
2404 
2405 /** returns the total number of global bound changes applied by the conflict analysis */
2407  SCIP_CONFLICT* conflict /**< conflict analysis data */
2408  )
2409 {
2410  assert(conflict != NULL);
2411 
2412  return conflict->nglbchgbds;
2413 }
2414 
2415 /** returns the total number of conflict constraints that were added globally to the problem */
2417  SCIP_CONFLICT* conflict /**< conflict analysis data */
2418  )
2419 {
2420  assert(conflict != NULL);
2421 
2422  return conflict->nappliedglbconss;
2423 }
2424 
2425 /** returns the total number of literals in conflict constraints that were added globally to the problem */
2427  SCIP_CONFLICT* conflict /**< conflict analysis data */
2428  )
2429 {
2430  assert(conflict != NULL);
2431 
2432  return conflict->nappliedglbliterals;
2433 }
2434 
2435 /** returns the total number of local bound changes applied by the conflict analysis */
2437  SCIP_CONFLICT* conflict /**< conflict analysis data */
2438  )
2439 {
2440  assert(conflict != NULL);
2441 
2442  return conflict->nlocchgbds;
2443 }
2444 
2445 /** returns the total number of conflict constraints that were added locally to the problem */
2447  SCIP_CONFLICT* conflict /**< conflict analysis data */
2448  )
2449 {
2450  assert(conflict != NULL);
2451 
2452  return conflict->nappliedlocconss;
2453 }
2454 
2455 /** returns the total number of literals in conflict constraints that were added locally to the problem */
2457  SCIP_CONFLICT* conflict /**< conflict analysis data */
2458  )
2459 {
2460  assert(conflict != NULL);
2461 
2462  return conflict->nappliedlocliterals;
2463 }
2464 
2465 
2466 
2467 
2468 /*
2469  * Propagation Conflict Analysis
2470  */
2471 
2472 /** returns whether bound change has a valid reason that can be resolved in conflict analysis */
2473 static
2475  SCIP_BDCHGINFO* bdchginfo /**< bound change information */
2476  )
2477 {
2478  assert(bdchginfo != NULL);
2479  assert(!SCIPbdchginfoIsRedundant(bdchginfo));
2480 
2483  && SCIPbdchginfoGetInferProp(bdchginfo) != NULL));
2484 }
2485 
2486 /** compares two conflict set entries, such that bound changes infered later are
2487  * ordered prior to ones that were infered earlier
2488  */
2489 static
2490 SCIP_DECL_SORTPTRCOMP(conflictBdchginfoComp)
2491 { /*lint --e{715}*/
2492  SCIP_BDCHGINFO* bdchginfo1;
2493  SCIP_BDCHGINFO* bdchginfo2;
2494 
2495  bdchginfo1 = (SCIP_BDCHGINFO*)elem1;
2496  bdchginfo2 = (SCIP_BDCHGINFO*)elem2;
2497  assert(bdchginfo1 != NULL);
2498  assert(bdchginfo2 != NULL);
2499  assert(!SCIPbdchginfoIsRedundant(bdchginfo1));
2500  assert(!SCIPbdchginfoIsRedundant(bdchginfo2));
2501 
2503  return -1;
2504  else
2505  return +1;
2506 }
2507 
2508 /** return TRUE if conflict analysis is applicable; In case the function return FALSE there is no need to initialize the
2509  * conflict analysis since it will not be applied
2510  */
2512  SCIP_SET* set /**< global SCIP settings */
2513  )
2514 {
2515  /* check, if propagation conflict analysis is enabled */
2516  if( !set->conf_enable || !set->conf_useprop )
2517  return FALSE;
2518 
2519  /* check, if there are any conflict handlers to use a conflict set */
2520  if( set->nconflicthdlrs == 0 )
2521  return FALSE;
2522 
2523  return TRUE;
2524 }
2525 
2526 /** creates conflict analysis data for propagation conflicts */
2528  SCIP_CONFLICT** conflict, /**< pointer to conflict analysis data */
2529  BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
2530  SCIP_SET* set /**< global SCIP settings */
2531  )
2532 {
2533  assert(conflict != NULL);
2534 
2535  SCIP_ALLOC( BMSallocMemory(conflict) );
2536 
2537  SCIP_CALL( SCIPclockCreate(&(*conflict)->dIBclock, SCIP_CLOCKTYPE_DEFAULT) );
2538  SCIP_CALL( SCIPclockCreate(&(*conflict)->propanalyzetime, SCIP_CLOCKTYPE_DEFAULT) );
2539  SCIP_CALL( SCIPclockCreate(&(*conflict)->inflpanalyzetime, SCIP_CLOCKTYPE_DEFAULT) );
2540  SCIP_CALL( SCIPclockCreate(&(*conflict)->boundlpanalyzetime, SCIP_CLOCKTYPE_DEFAULT) );
2541  SCIP_CALL( SCIPclockCreate(&(*conflict)->sbanalyzetime, SCIP_CLOCKTYPE_DEFAULT) );
2542  SCIP_CALL( SCIPclockCreate(&(*conflict)->pseudoanalyzetime, SCIP_CLOCKTYPE_DEFAULT) );
2543 
2544  /* enable or disable timing depending on the parameter statistic timing */
2546 
2547  SCIP_CALL( SCIPpqueueCreate(&(*conflict)->bdchgqueue, set->mem_arraygrowinit, set->mem_arraygrowfac,
2548  conflictBdchginfoComp) );
2549  SCIP_CALL( SCIPpqueueCreate(&(*conflict)->forcedbdchgqueue, set->mem_arraygrowinit, set->mem_arraygrowfac,
2550  conflictBdchginfoComp) );
2551  SCIP_CALL( conflictsetCreate(&(*conflict)->conflictset, blkmem) );
2552  (*conflict)->conflictsets = NULL;
2553  (*conflict)->conflictsetscores = NULL;
2554  (*conflict)->tmpbdchginfos = NULL;
2555  (*conflict)->conflictsetssize = 0;
2556  (*conflict)->nconflictsets = 0;
2557  (*conflict)->tmpbdchginfossize = 0;
2558  (*conflict)->ntmpbdchginfos = 0;
2559  (*conflict)->count = 0;
2560  (*conflict)->nglbchgbds = 0;
2561  (*conflict)->nappliedglbconss = 0;
2562  (*conflict)->nappliedglbliterals = 0;
2563  (*conflict)->nlocchgbds = 0;
2564  (*conflict)->nappliedlocconss = 0;
2565  (*conflict)->nappliedlocliterals = 0;
2566  (*conflict)->npropcalls = 0;
2567  (*conflict)->npropsuccess = 0;
2568  (*conflict)->npropconfconss = 0;
2569  (*conflict)->npropconfliterals = 0;
2570  (*conflict)->npropreconvconss = 0;
2571  (*conflict)->npropreconvliterals = 0;
2572  (*conflict)->ninflpcalls = 0;
2573  (*conflict)->ninflpsuccess = 0;
2574  (*conflict)->ninflpconfconss = 0;
2575  (*conflict)->ninflpconfliterals = 0;
2576  (*conflict)->ninflpreconvconss = 0;
2577  (*conflict)->ninflpreconvliterals = 0;
2578  (*conflict)->ninflpiterations = 0;
2579  (*conflict)->nboundlpcalls = 0;
2580  (*conflict)->nboundlpsuccess = 0;
2581  (*conflict)->nboundlpconfconss = 0;
2582  (*conflict)->nboundlpconfliterals = 0;
2583  (*conflict)->nboundlpreconvconss = 0;
2584  (*conflict)->nboundlpreconvliterals = 0;
2585  (*conflict)->nboundlpiterations = 0;
2586  (*conflict)->nsbcalls = 0;
2587  (*conflict)->nsbsuccess = 0;
2588  (*conflict)->nsbconfconss = 0;
2589  (*conflict)->nsbconfliterals = 0;
2590  (*conflict)->nsbreconvconss = 0;
2591  (*conflict)->nsbreconvliterals = 0;
2592  (*conflict)->nsbiterations = 0;
2593  (*conflict)->npseudocalls = 0;
2594  (*conflict)->npseudosuccess = 0;
2595  (*conflict)->npseudoconfconss = 0;
2596  (*conflict)->npseudoconfliterals = 0;
2597  (*conflict)->npseudoreconvconss = 0;
2598  (*conflict)->npseudoreconvliterals = 0;
2599 
2600  return SCIP_OKAY;
2601 }
2602 
2603 /** frees conflict analysis data for propagation conflicts */
2605  SCIP_CONFLICT** conflict, /**< pointer to conflict analysis data */
2606  BMS_BLKMEM* blkmem /**< block memory of transformed problem */
2607  )
2608 {
2609  assert(conflict != NULL);
2610  assert(*conflict != NULL);
2611  assert((*conflict)->nconflictsets == 0);
2612  assert((*conflict)->ntmpbdchginfos == 0);
2613 
2614 #ifdef SCIP_CONFGRAPH
2615  confgraphFree();
2616 #endif
2617 
2618  SCIPclockFree(&(*conflict)->dIBclock);
2619  SCIPclockFree(&(*conflict)->propanalyzetime);
2620  SCIPclockFree(&(*conflict)->inflpanalyzetime);
2621  SCIPclockFree(&(*conflict)->boundlpanalyzetime);
2622  SCIPclockFree(&(*conflict)->sbanalyzetime);
2623  SCIPclockFree(&(*conflict)->pseudoanalyzetime);
2624  SCIPpqueueFree(&(*conflict)->bdchgqueue);
2625  SCIPpqueueFree(&(*conflict)->forcedbdchgqueue);
2626  conflictsetFree(&(*conflict)->conflictset, blkmem);
2627  BMSfreeMemoryArrayNull(&(*conflict)->conflictsets);
2628  BMSfreeMemoryArrayNull(&(*conflict)->conflictsetscores);
2629  BMSfreeMemoryArrayNull(&(*conflict)->tmpbdchginfos);
2630  BMSfreeMemory(conflict);
2631 
2632  return SCIP_OKAY;
2633 }
2634 
2635 /** clears the conflict queue and the current conflict set */
2636 static
2638  SCIP_CONFLICT* conflict /**< conflict analysis data */
2639  )
2640 {
2641  assert(conflict != NULL);
2642 
2643  SCIPpqueueClear(conflict->bdchgqueue);
2644  SCIPpqueueClear(conflict->forcedbdchgqueue);
2645  conflictsetClear(conflict->conflictset);
2646 }
2647 
2648 /** initializes the propagation conflict analysis by clearing the conflict candidate queue */
2650  SCIP_CONFLICT* conflict, /**< conflict analysis data */
2651  SCIP_SET* set, /**< global SCIP settings */
2652  SCIP_STAT* stat, /**< problem statistics */
2653  SCIP_PROB* prob /**< problem data */
2654  )
2655 {
2656  assert(conflict != NULL);
2657  assert(set != NULL);
2658  assert(stat != NULL);
2659  assert(prob != NULL);
2660 
2661  SCIPdebugMessage("initializing conflict analysis\n");
2662 
2663  /* clear the conflict candidate queue and the conflict set */
2664  conflictClear(conflict);
2665 
2666  /* increase the conflict counter, such that binary variables of new conflict set and new conflict queue are labeled
2667  * with this new counter
2668  */
2669  conflict->count++;
2670  if( conflict->count == 0 ) /* make sure, 0 is not a valid conflict counter (may happen due to integer overflow) */
2671  conflict->count = 1;
2672 
2673  /* increase the conflict score weight for history updates of future conflict reasons */
2674  if( stat->nnodes > stat->lastconflictnode )
2675  {
2676  assert(0.0 < set->conf_scorefac && set->conf_scorefac <= 1.0);
2677  stat->vsidsweight /= set->conf_scorefac;
2678  assert(stat->vsidsweight > 0.0);
2679 
2680  /* if the conflict score for the next conflict exceeds 1000.0, rescale all history conflict scores */
2681  if( stat->vsidsweight >= 1000.0 )
2682  {
2683  int v;
2684 
2685  for( v = 0; v < prob->nvars; ++v )
2686  {
2687  SCIP_CALL( SCIPvarScaleVSIDS(prob->vars[v], 1.0/stat->vsidsweight) );
2688  }
2689  SCIPhistoryScaleVSIDS(stat->glbhistory, 1.0/stat->vsidsweight);
2691  stat->vsidsweight = 1.0;
2692  }
2693  stat->lastconflictnode = stat->nnodes;
2694  }
2695 
2696 #ifdef SCIP_CONFGRAPH
2697  confgraphFree();
2698  SCIP_CALL( confgraphCreate(set, conflict) );
2699 #endif
2700 
2701  return SCIP_OKAY;
2702 }
2703 
2704 /** marks bound to be present in the current conflict and returns whether a bound which is at least as tight was already
2705  * member of the current conflict (i.e., the given bound change does not need to be added)
2706  */
2707 static
2709  SCIP_CONFLICT* conflict, /**< conflict analysis data */
2710  SCIP_BDCHGINFO* bdchginfo, /**< bound change to add to the conflict set */
2711  SCIP_Real relaxedbd /**< relaxed bound */
2712  )
2713 {
2714  SCIP_VAR* var;
2715  SCIP_Real newbound;
2716 
2717  assert(conflict != NULL);
2718 
2719  var = SCIPbdchginfoGetVar(bdchginfo);
2720  newbound = SCIPbdchginfoGetNewbound(bdchginfo);
2721  assert(var != NULL);
2722 
2723  switch( SCIPbdchginfoGetBoundtype(bdchginfo) )
2724  {
2725  case SCIP_BOUNDTYPE_LOWER:
2726  /* check if the variables lower bound is already member of the conflict */
2727  if( var->conflictlbcount == conflict->count )
2728  {
2729  /* the variable is already member of the conflict; hence check if the new bound is redundant */
2730  if( var->conflictlb > newbound )
2731  {
2732  SCIPdebugMessage("ignoring redundant bound change <%s> >= %g since a stronger lower bound exist <%s> >= %g\n",
2733  SCIPvarGetName(var), newbound, SCIPvarGetName(var), var->conflictlb);
2734  return TRUE;
2735  }
2736  else if( var->conflictlb == newbound ) /*lint !e777*/
2737  {
2738  SCIPdebugMessage("ignoring redundant bound change <%s> >= %g since this lower bound is already present\n", SCIPvarGetName(var), newbound);
2739  SCIPdebugMessage("adjust relaxed lower bound <%g> -> <%g>\n", var->conflictlb, relaxedbd);
2740  var->conflictrelaxedlb = MAX(var->conflictrelaxedlb, relaxedbd);
2741  return TRUE;
2742  }
2743  }
2744 
2745  /* add the variable lower bound to the current conflict */
2746  var->conflictlbcount = conflict->count;
2747 
2748  /* remember the lower bound and relaxed bound to allow only better/tighter lower bounds for that variables
2749  * w.r.t. this conflict
2750  */
2751  var->conflictlb = newbound;
2752  var->conflictrelaxedlb = relaxedbd;
2753 
2754  return FALSE;
2755 
2756  case SCIP_BOUNDTYPE_UPPER:
2757  /* check if the variables upper bound is already member of the conflict */
2758  if( var->conflictubcount == conflict->count )
2759  {
2760  /* the variable is already member of the conflict; hence check if the new bound is redundant */
2761  if( var->conflictub < newbound )
2762  {
2763  SCIPdebugMessage("ignoring redundant bound change <%s> <= %g since a stronger upper bound exist <%s> <= %g\n",
2764  SCIPvarGetName(var), newbound, SCIPvarGetName(var), var->conflictub);
2765  return TRUE;
2766  }
2767  else if( var->conflictub == newbound ) /*lint !e777*/
2768  {
2769  SCIPdebugMessage("ignoring redundant bound change <%s> <= %g since this upper bound is already present\n", SCIPvarGetName(var), newbound);
2770  SCIPdebugMessage("adjust relaxed upper bound <%g> -> <%g>\n", var->conflictub, relaxedbd);
2771  var->conflictrelaxedub = MIN(var->conflictrelaxedub, relaxedbd);
2772  return TRUE;
2773  }
2774  }
2775 
2776  /* add the variable upper bound to the current conflict */
2777  var->conflictubcount = conflict->count;
2778 
2779  /* remember the upper bound and relaxed bound to allow only better/tighter upper bounds for that variables
2780  * w.r.t. this conflict
2781  */
2782  var->conflictub = newbound;
2783  var->conflictrelaxedub = relaxedbd;
2784 
2785  return FALSE;
2786 
2787  default:
2788  SCIPerrorMessage("invalid bound type %d\n", SCIPbdchginfoGetBoundtype(bdchginfo));
2789  SCIPABORT();
2790  return FALSE; /*lint !e527*/
2791  }
2792 }
2793 
2794 /** puts bound change into the current conflict set */
2795 static
2797  SCIP_CONFLICT* conflict, /**< conflict analysis data */
2798  BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
2799  SCIP_SET* set, /**< global SCIP settings */
2800  SCIP_BDCHGINFO* bdchginfo, /**< bound change to add to the conflict set */
2801  SCIP_Real relaxedbd /**< relaxed bound */
2802  )
2803 {
2804  assert(conflict != NULL);
2805  assert(!SCIPbdchginfoIsRedundant(bdchginfo));
2806 
2807  /* check if the relaxed bound is really a relaxed bound */
2808  assert(SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER || SCIPsetIsGE(set, relaxedbd, SCIPbdchginfoGetNewbound(bdchginfo)));
2809  assert(SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_UPPER || SCIPsetIsLE(set, relaxedbd, SCIPbdchginfoGetNewbound(bdchginfo)));
2810 
2811  SCIPdebugMessage("putting bound change <%s> %s %g(%g) at depth %d to current conflict set\n",
2812  SCIPvarGetName(SCIPbdchginfoGetVar(bdchginfo)),
2813  SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", SCIPbdchginfoGetNewbound(bdchginfo),
2814  relaxedbd, SCIPbdchginfoGetDepth(bdchginfo));
2815 
2816  /* mark the bound to be member of the conflict and check if a bound which is at least as tight is already member of
2817  * the conflict
2818  */
2819  if( !conflictMarkBoundCheckPresence(conflict, bdchginfo, relaxedbd) )
2820  {
2821  /* add the bound change to the current conflict set */
2822  SCIP_CALL( conflictsetAddBound(conflict->conflictset, blkmem, set, bdchginfo, relaxedbd) );
2823 
2824 #ifdef SCIP_CONFGRAPH
2825  if( bdchginfo != confgraphcurrentbdchginfo )
2826  confgraphAddBdchg(bdchginfo);
2827 #endif
2828  }
2829 #ifdef SCIP_CONFGRAPH
2830  else
2831  confgraphLinkBdchg(bdchginfo);
2832 #endif
2833 
2834  return SCIP_OKAY;
2835 }
2836 
2837 /** returns whether the negation of the given bound change would lead to a globally valid literal */
2838 static
2840  SCIP_SET* set, /**< global SCIP settings */
2841  SCIP_BDCHGINFO* bdchginfo /**< bound change information */
2842  )
2843 {
2844  SCIP_VAR* var;
2845  SCIP_BOUNDTYPE boundtype;
2846  SCIP_Real bound;
2847 
2848  var = SCIPbdchginfoGetVar(bdchginfo);
2849  boundtype = SCIPbdchginfoGetBoundtype(bdchginfo);
2850  bound = SCIPbdchginfoGetNewbound(bdchginfo);
2851 
2852  return (SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS
2853  && ((boundtype == SCIP_BOUNDTYPE_LOWER && SCIPsetIsFeasGE(set, bound, SCIPvarGetUbGlobal(var)))
2854  || (boundtype == SCIP_BOUNDTYPE_UPPER && SCIPsetIsFeasLE(set, bound, SCIPvarGetLbGlobal(var)))));
2855 }
2856 
2857 /** adds given bound change information to the conflict candidate queue */
2858 static
2860  SCIP_CONFLICT* conflict, /**< conflict analysis data */
2861  SCIP_SET* set, /**< global SCIP settings */
2862  SCIP_BDCHGINFO* bdchginfo, /**< bound change information */
2863  SCIP_Real relaxedbd /**< relaxed bound */
2864  )
2865 {
2866  assert(conflict != NULL);
2867  assert(set != NULL);
2868  assert(bdchginfo != NULL);
2869  assert(!SCIPbdchginfoIsRedundant(bdchginfo));
2870 
2871  /* check if the relaxed bound is really a relaxed bound */
2872  assert(SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER || SCIPsetIsGE(set, relaxedbd, SCIPbdchginfoGetNewbound(bdchginfo)));
2873  assert(SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_UPPER || SCIPsetIsLE(set, relaxedbd, SCIPbdchginfoGetNewbound(bdchginfo)));
2874 
2875  /* mark the bound to be member of the conflict and check if a bound which is at least as tight is already member of
2876  * the conflict
2877  */
2878  if( !conflictMarkBoundCheckPresence(conflict, bdchginfo, relaxedbd) )
2879  {
2880  /* insert the bound change into the conflict queue */
2881  if( (!set->conf_preferbinary || SCIPvarIsBinary(SCIPbdchginfoGetVar(bdchginfo)))
2882  && !isBoundchgUseless(set, bdchginfo) )
2883  {
2884  SCIP_CALL( SCIPpqueueInsert(conflict->bdchgqueue, (void*)bdchginfo) );
2885  }
2886  else
2887  {
2888  SCIP_CALL( SCIPpqueueInsert(conflict->forcedbdchgqueue, (void*)bdchginfo) );
2889  }
2890 
2891 #ifdef SCIP_CONFGRAPH
2892  confgraphAddBdchg(bdchginfo);
2893 #endif
2894  }
2895 #ifdef SCIP_CONFGRAPH
2896  else
2897  confgraphLinkBdchg(bdchginfo);
2898 #endif
2899 
2900  return SCIP_OKAY;
2901 }
2902 
2903 /** convert variable and bound change to active variable */
2904 static
2906  SCIP_VAR** var, /**< pointer to variable */
2907  SCIP_SET* set, /**< global SCIP settings */
2908  SCIP_BOUNDTYPE* boundtype, /**< pointer to type of bound that was changed: lower or upper bound */
2909  SCIP_Real* bound /**< pointer to bound to convert, or NULL */
2910  )
2911 {
2912  SCIP_Real scalar;
2913  SCIP_Real constant;
2914 
2915  scalar = 1.0;
2916  constant = 0.0;
2917 
2918  /* transform given varibale to active varibale */
2919  SCIP_CALL( SCIPvarGetProbvarSum(var, set, &scalar, &constant) );
2920  assert(SCIPvarGetStatus(*var) == SCIP_VARSTATUS_FIXED || scalar != 0.0); /*lint !e777*/
2921 
2922  if( SCIPvarGetStatus(*var) == SCIP_VARSTATUS_FIXED )
2923  return SCIP_OKAY;
2924 
2925  /* if the scalar of the aggregation is negative, we have to switch the bound type */
2926  if( scalar < 0.0 )
2927  (*boundtype) = SCIPboundtypeOpposite(*boundtype);
2928 
2929  if( bound != NULL )
2930  {
2931  (*bound) -= constant;
2932  (*bound) /= scalar;
2933  }
2934 
2935  return SCIP_OKAY;
2936 }
2937 
2938 /** adds variable's bound to conflict candidate queue */
2939 static
2941  SCIP_CONFLICT* conflict, /**< conflict analysis data */
2942  BMS_BLKMEM* blkmem, /**< block memory */
2943  SCIP_SET* set, /**< global SCIP settings */
2944  SCIP_STAT* stat, /**< dynamic problem statistics */
2945  SCIP_VAR* var, /**< problem variable */
2946  SCIP_BOUNDTYPE boundtype, /**< type of bound that was changed: lower or upper bound */
2947  SCIP_BDCHGINFO* bdchginfo, /**< bound change info, or NULL */
2948  SCIP_Real relaxedbd /**< relaxed bound */
2949  )
2950 {
2951  assert(SCIPvarIsActive(var));
2952  assert(bdchginfo != NULL);
2953  assert(!SCIPbdchginfoIsRedundant(bdchginfo));
2954 
2955  SCIPdebugMessage(" -> adding bound <%s> %s %.15g(%.15g) [status:%d, type:%d, depth:%d, pos:%d, reason:<%s>, info:%d] to candidates\n",
2956  SCIPvarGetName(var),
2957  boundtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
2958  SCIPbdchginfoGetNewbound(bdchginfo), relaxedbd,
2959  SCIPvarGetStatus(var), SCIPvarGetType(var),
2960  SCIPbdchginfoGetDepth(bdchginfo), SCIPbdchginfoGetPos(bdchginfo),
2961  SCIPbdchginfoGetChgtype(bdchginfo) == SCIP_BOUNDCHGTYPE_BRANCHING ? "branch"
2965  : "none")),
2967 
2968  /* the local bound change may be resolved and has to be put on the candidate queue;
2969  * we even put bound changes without inference information on the queue in order to automatically
2970  * eliminate multiple insertions of the same bound change
2971  */
2972  assert(SCIPbdchginfoGetVar(bdchginfo) == var);
2973  assert(SCIPbdchginfoGetBoundtype(bdchginfo) == boundtype);
2974  assert(SCIPbdchginfoGetDepth(bdchginfo) >= 0);
2975  assert(SCIPbdchginfoGetPos(bdchginfo) >= 0);
2976 
2977  /* the relaxed bound should be a relaxation */
2978  assert(boundtype == SCIP_BOUNDTYPE_LOWER ? SCIPsetIsLE(set, relaxedbd, SCIPbdchginfoGetNewbound(bdchginfo)) : SCIPsetIsGE(set, relaxedbd, SCIPbdchginfoGetNewbound(bdchginfo)));
2979 
2980  /* the relaxed bound should be worse then the old bound of the bound change info */
2981  assert(boundtype == SCIP_BOUNDTYPE_LOWER ? SCIPsetIsGT(set, relaxedbd, SCIPbdchginfoGetOldbound(bdchginfo)) : SCIPsetIsLT(set, relaxedbd, SCIPbdchginfoGetOldbound(bdchginfo)));
2982 
2983  /* put bound change information into priority queue */
2984  SCIP_CALL( conflictQueueBound(conflict, set, bdchginfo, relaxedbd) );
2985 
2986  /* each variable which is add to the conflict graph gets an increase in the VSIDS
2987  *
2988  * @note That is different to the VSIDS preseted in the literature
2989  */
2990  SCIP_CALL( incVSIDS(var, blkmem, set, stat, boundtype, relaxedbd, set->conf_conflictgraphweight) );
2991 
2992  return SCIP_OKAY;
2993 }
2994 
2995 /** adds variable's bound to conflict candidate queue */
2997  SCIP_CONFLICT* conflict, /**< conflict analysis data */
2998  BMS_BLKMEM* blkmem, /**< block memory */
2999  SCIP_SET* set, /**< global SCIP settings */
3000  SCIP_STAT* stat, /**< dynamic problem statistics */
3001  SCIP_VAR* var, /**< problem variable */
3002  SCIP_BOUNDTYPE boundtype, /**< type of bound that was changed: lower or upper bound */
3003  SCIP_BDCHGIDX* bdchgidx /**< bound change index (time stamp of bound change), or NULL for current time */
3004  )
3005 {
3006  SCIP_BDCHGINFO* bdchginfo;
3007 
3008  assert(conflict != NULL);
3009  assert(stat != NULL);
3010  assert(var != NULL);
3011 
3012  /* convert bound to active problem variable */
3013  SCIP_CALL( convertToActiveVar(&var, set, &boundtype, NULL) );
3014 
3015  /* we can ignore fixed variables */
3017  return SCIP_OKAY;
3018 
3019  /* if the variable is multi-aggregated, add the bounds of all aggregation variables */
3021  {
3022  SCIP_VAR** vars;
3023  SCIP_Real* scalars;
3024  int nvars;
3025  int i;
3026 
3027  vars = SCIPvarGetMultaggrVars(var);
3028  scalars = SCIPvarGetMultaggrScalars(var);
3029  nvars = SCIPvarGetMultaggrNVars(var);
3030  for( i = 0; i < nvars; ++i )
3031  {
3032  SCIP_CALL( SCIPconflictAddBound(conflict, blkmem, set, stat, vars[i],
3033  (scalars[i] < 0.0 ? SCIPboundtypeOpposite(boundtype) : boundtype), bdchgidx) );
3034  }
3035 
3036  return SCIP_OKAY;
3037  }
3038  assert(SCIPvarIsActive(var));
3039 
3040  /* get bound change information */
3041  bdchginfo = SCIPvarGetBdchgInfo(var, boundtype, bdchgidx, FALSE);
3042 
3043  /* if bound of variable was not changed (this means it is still the global bound), we can ignore the conflicting
3044  * bound
3045  */
3046  if( bdchginfo == NULL )
3047  return SCIP_OKAY;
3048 
3049  assert(SCIPbdchgidxIsEarlier(SCIPbdchginfoGetIdx(bdchginfo), bdchgidx));
3050 
3051  SCIP_CALL( conflictAddBound(conflict, blkmem, set, stat, var, boundtype, bdchginfo, SCIPbdchginfoGetNewbound(bdchginfo)) );
3052 
3053  return SCIP_OKAY;
3054 }
3055 
3056 /** adds variable's bound to conflict candidate queue */
3058  SCIP_CONFLICT* conflict, /**< conflict analysis data */
3059  BMS_BLKMEM* blkmem, /**< block memory */
3060  SCIP_SET* set, /**< global SCIP settings */
3061  SCIP_STAT* stat, /**< dynamic problem statistics */
3062  SCIP_VAR* var, /**< problem variable */
3063  SCIP_BOUNDTYPE boundtype, /**< type of bound that was changed: lower or upper bound */
3064  SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
3065  SCIP_Real relaxedbd /**< the relaxed bound */
3066  )
3067 {
3068  SCIP_BDCHGINFO* bdchginfo;
3069  int nbdchgs;
3070 
3071  assert(conflict != NULL);
3072  assert(stat != NULL);
3073  assert(var != NULL);
3074 
3075  if( !SCIPvarIsActive(var) )
3076  {
3077  /* convert bound to active problem variable */
3078  SCIP_CALL( convertToActiveVar(&var, set, &boundtype, &relaxedbd) );
3079 
3080  /* we can ignore fixed variables */
3082  return SCIP_OKAY;
3083 
3084  /* if the variable is multi-aggregated, add the bounds of all aggregation variables */
3086  {
3087  SCIPdebugMessage("ignoring relaxed bound information since variable <%s> is multi-aggregated active\n", SCIPvarGetName(var));
3088 
3089  SCIP_CALL( SCIPconflictAddBound(conflict, blkmem, set, stat, var, boundtype, bdchgidx) );
3090 
3091  return SCIP_OKAY;
3092  }
3093  }
3094  assert(SCIPvarIsActive(var));
3095 
3096  /* get bound change information */
3097  bdchginfo = SCIPvarGetBdchgInfo(var, boundtype, bdchgidx, FALSE);
3098 
3099  /* if bound of variable was not changed (this means it is still the global bound), we can ignore the conflicting
3100  * bound
3101  */
3102  if( bdchginfo == NULL )
3103  return SCIP_OKAY;
3104 
3105  /* check that the bound change info is not a temporary one */
3106  assert(SCIPbdchgidxGetPos(&bdchginfo->bdchgidx) >= 0);
3107 
3108  /* get the position of the bound change information within the bound change array of the variable */
3109  nbdchgs = (int) bdchginfo->pos;
3110  assert(nbdchgs >= 0);
3111 
3112  /* if the relaxed bound should be ignored, set the relaxed bound to the bound given by the bdchgidx; that ensures
3113  * that the loop(s) below will be skipped
3114  */
3115  if( set->conf_ignorerelaxedbd )
3116  relaxedbd = SCIPbdchginfoGetNewbound(bdchginfo);
3117 
3118  /* search for the bound change information which includes the relaxed bound */
3119  if( boundtype == SCIP_BOUNDTYPE_LOWER )
3120  {
3121  SCIP_Real newbound;
3122 
3123  /* adjust relaxed lower bound w.r.t. variable type */
3124  SCIPvarAdjustLb(var, set, &relaxedbd);
3125 
3126  /* due to numericis we compare the relaxed lower bound to the one present at the particular time point and take
3127  * the better one
3128  */
3129  newbound = SCIPbdchginfoGetNewbound(bdchginfo);
3130  relaxedbd = MIN(relaxedbd, newbound);
3131 
3132  /* check if relaxed lower bound is smaller or equal to global lower bound; if so we can ignore the conflicting
3133  * bound
3134  */
3135  if( SCIPsetIsLE(set, relaxedbd, SCIPvarGetLbGlobal(var)) )
3136  return SCIP_OKAY;
3137 
3138  while( nbdchgs > 0 )
3139  {
3140  assert(SCIPsetIsLE(set, relaxedbd, SCIPbdchginfoGetNewbound(bdchginfo)));
3141 
3142  /* check if the old lower bound is greater than or equal to relaxed lower bound; if not we found the bound
3143  * change info which we need to report
3144  */
3145  if( SCIPsetIsGT(set, relaxedbd, SCIPbdchginfoGetOldbound(bdchginfo)) )
3146  break;
3147 
3148  bdchginfo = SCIPvarGetBdchgInfoLb(var, nbdchgs-1);
3149 
3150  SCIPdebugMessage("lower bound change %d oldbd=%.15g, newbd=%.15g, depth=%d, pos=%d, redundant=%u\n",
3151  nbdchgs, SCIPbdchginfoGetOldbound(bdchginfo), SCIPbdchginfoGetNewbound(bdchginfo),
3152  SCIPbdchginfoGetDepth(bdchginfo), SCIPbdchginfoGetPos(bdchginfo),
3153  SCIPbdchginfoIsRedundant(bdchginfo));
3154 
3155  /* if bound change is redundant (this means it now a global bound), we can ignore the conflicting bound */
3156  if( SCIPbdchginfoIsRedundant(bdchginfo) )
3157  return SCIP_OKAY;
3158 
3159  nbdchgs--;
3160  }
3161  assert(SCIPsetIsGT(set, relaxedbd, SCIPbdchginfoGetOldbound(bdchginfo)));
3162  }
3163  else
3164  {
3165  SCIP_Real newbound;
3166 
3167  assert(boundtype == SCIP_BOUNDTYPE_UPPER);
3168 
3169  /* adjust relaxed upper bound w.r.t. variable type */
3170  SCIPvarAdjustUb(var, set, &relaxedbd);
3171 
3172  /* due to numericis we compare the relaxed upper bound to the one present at the particular time point and take
3173  * the better one
3174  */
3175  newbound = SCIPbdchginfoGetNewbound(bdchginfo);
3176  relaxedbd = MAX(relaxedbd, newbound);
3177 
3178  /* check if relaxed upper bound is greater or equal to global upper bound; if so we can ignore the conflicting
3179  * bound
3180  */
3181  if( SCIPsetIsGE(set, relaxedbd, SCIPvarGetUbGlobal(var)) )
3182  return SCIP_OKAY;
3183 
3184  while( nbdchgs > 0 )
3185  {
3186  assert(SCIPsetIsGE(set, relaxedbd, SCIPbdchginfoGetNewbound(bdchginfo)));
3187 
3188  /* check if the old upper bound is smaller than or equal to the relaxed upper bound; if not we found the
3189  * bound change info which we need to report
3190  */
3191  if( SCIPsetIsLT(set, relaxedbd, SCIPbdchginfoGetOldbound(bdchginfo)) )
3192  break;
3193 
3194  bdchginfo = SCIPvarGetBdchgInfoUb(var, nbdchgs-1);
3195 
3196  SCIPdebugMessage("upper bound change %d oldbd=%.15g, newbd=%.15g, depth=%d, pos=%d, redundant=%u\n",
3197  nbdchgs, SCIPbdchginfoGetOldbound(bdchginfo), SCIPbdchginfoGetNewbound(bdchginfo),
3198  SCIPbdchginfoGetDepth(bdchginfo), SCIPbdchginfoGetPos(bdchginfo),
3199  SCIPbdchginfoIsRedundant(bdchginfo));
3200 
3201  /* if bound change is redundant (this means it now a global bound), we can ignore the conflicting bound */
3202  if( SCIPbdchginfoIsRedundant(bdchginfo) )
3203  return SCIP_OKAY;
3204 
3205  nbdchgs--;
3206  }
3207  assert(SCIPsetIsLT(set, relaxedbd, SCIPbdchginfoGetOldbound(bdchginfo)));
3208  }
3209 
3210  assert(SCIPbdchgidxIsEarlier(SCIPbdchginfoGetIdx(bdchginfo), bdchgidx));
3211 
3212  /* put bound change information into priority queue */
3213  SCIP_CALL( conflictAddBound(conflict, blkmem, set, stat, var, boundtype, bdchginfo, relaxedbd) );
3214 
3215  return SCIP_OKAY;
3216 }
3217 
3218 /** checks if the given variable is already part of the current conflict set or queued for resolving with the same or
3219  * even stronger bound
3220  */
3222  SCIP_CONFLICT* conflict, /**< conflict analysis data */
3223  SCIP_VAR* var, /**< problem variable */
3224  SCIP_SET* set, /**< global SCIP settings */
3225  SCIP_BOUNDTYPE boundtype, /**< type of bound for which the score should be increased */
3226  SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
3227  SCIP_Bool* used /**< pointer to store if the variable is already used */
3228  )
3229 {
3230  SCIP_Real newbound;
3231 
3232  /* convert bound to active problem variable */
3233  SCIP_CALL( convertToActiveVar(&var, set, &boundtype, NULL) );
3234 
3236  *used = FALSE;
3237  else
3238  {
3239  assert(SCIPvarIsActive(var));
3240  assert(var != NULL);
3241 
3242  switch( boundtype )
3243  {
3244  case SCIP_BOUNDTYPE_LOWER:
3245 
3246  newbound = SCIPvarGetLbAtIndex(var, bdchgidx, FALSE);
3247 
3248  if( var->conflictlbcount == conflict->count && var->conflictlb >= newbound )
3249  {
3250  SCIPdebugMessage("already queued bound change <%s> >= %g\n", SCIPvarGetName(var), newbound);
3251  *used = TRUE;
3252  }
3253  else
3254  *used = FALSE;
3255  break;
3256  case SCIP_BOUNDTYPE_UPPER:
3257 
3258  newbound = SCIPvarGetUbAtIndex(var, bdchgidx, FALSE);
3259 
3260  if( var->conflictubcount == conflict->count && var->conflictub <= newbound )
3261  {
3262  SCIPdebugMessage("already queued bound change <%s> <= %g\n", SCIPvarGetName(var), newbound);
3263  *used = TRUE;
3264  }
3265  else
3266  *used = FALSE;
3267  break;
3268  default:
3269  SCIPerrorMessage("invalid bound type %d\n", boundtype);
3270  SCIPABORT();
3271  *used = FALSE; /*lint !e527*/
3272  }
3273  }
3274 
3275  return SCIP_OKAY;
3276 }
3277 
3278 /** returns the conflict lower bound if the variable is present in the current conflict set; otherwise the global lower
3279  * bound
3280  */
3282  SCIP_CONFLICT* conflict, /**< conflict analysis data */
3283  SCIP_VAR* var /**< problem variable */
3284  )
3285 {
3286  if( var->conflictlbcount == conflict->count )
3287  {
3288  assert(EPSGE(var->conflictlb, var->conflictrelaxedlb, 1e-09));
3289  return var->conflictrelaxedlb;
3290  }
3291 
3292  return SCIPvarGetLbGlobal(var);
3293 }
3294 
3295 /** returns the conflict upper bound if the variable is present in the current conflict set; otherwise the global upper
3296  * bound
3297  */
3299  SCIP_CONFLICT* conflict, /**< conflict analysis data */
3300  SCIP_VAR* var /**< problem variable */
3301  )
3302 {
3303  if( var->conflictubcount == conflict->count )
3304  {
3305  assert(EPSLE(var->conflictub, var->conflictrelaxedub, 1e-09));
3306  return var->conflictrelaxedub;
3307  }
3308 
3309  return SCIPvarGetUbGlobal(var);
3310 }
3311 
3312 /** removes and returns next conflict analysis candidate from the candidate queue */
3313 static
3315  SCIP_CONFLICT* conflict /**< conflict analysis data */
3316  )
3317 {
3318  SCIP_BDCHGINFO* bdchginfo;
3319  SCIP_VAR* var;
3320 
3321  assert(conflict != NULL);
3322 
3323  if( SCIPpqueueNElems(conflict->forcedbdchgqueue) > 0 )
3324  bdchginfo = (SCIP_BDCHGINFO*)(SCIPpqueueRemove(conflict->forcedbdchgqueue));
3325  else
3326  bdchginfo = (SCIP_BDCHGINFO*)(SCIPpqueueRemove(conflict->bdchgqueue));
3327 
3328  assert(!SCIPbdchginfoIsRedundant(bdchginfo));
3329 
3330  /* if we have a candidate this one should be valid for the current conflict analysis */
3331  assert(!bdchginfoIsInvalid(conflict, bdchginfo));
3332 
3333  /* mark the bound change to be no longer in the conflict (it will be either added again to the conflict set or
3334  * replaced by resolving, which might add a weaker change on the same bound to the queue)
3335  */
3336  var = SCIPbdchginfoGetVar(bdchginfo);
3338  {
3339  var->conflictlbcount = 0;
3341  }
3342  else
3343  {
3344  assert(SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_UPPER);
3345  var->conflictubcount = 0;
3347  }
3348 
3349 #ifdef SCIP_CONFGRAPH
3350  confgraphSetCurrentBdchg(bdchginfo);
3351 #endif
3352 
3353  return bdchginfo;
3354 }
3355 
3356 /** returns next conflict analysis candidate from the candidate queue without removing it */
3357 static
3359  SCIP_CONFLICT* conflict /**< conflict analysis data */
3360  )
3361 {
3362  SCIP_BDCHGINFO* bdchginfo;
3363 
3364  assert(conflict != NULL);
3365 
3366  if( SCIPpqueueNElems(conflict->forcedbdchgqueue) > 0 )
3367  {
3368  /* get next potetioal candidate */
3369  bdchginfo = (SCIP_BDCHGINFO*)(SCIPpqueueFirst(conflict->forcedbdchgqueue));
3370 
3371  /* check if this candidate is valid */
3372  if( bdchginfoIsInvalid(conflict, bdchginfo) )
3373  {
3374  SCIPdebugMessage("bound change info [%d:<%s> %s %g] is invaild -> pop it from the force queue\n", SCIPbdchginfoGetDepth(bdchginfo),
3375  SCIPvarGetName(SCIPbdchginfoGetVar(bdchginfo)),
3376  SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
3377  SCIPbdchginfoGetNewbound(bdchginfo));
3378 
3379  /* pop the invalid bound change info from the queue */
3380  (void)(SCIPpqueueRemove(conflict->forcedbdchgqueue));
3381 
3382  /* call method recursively to get next conflict analysis candidate */
3383  bdchginfo = conflictFirstCand(conflict);
3384  }
3385  }
3386  else
3387  {
3388  bdchginfo = (SCIP_BDCHGINFO*)(SCIPpqueueFirst(conflict->bdchgqueue));
3389 
3390  /* check if this candidate is valid */
3391  if( bdchginfo != NULL && bdchginfoIsInvalid(conflict, bdchginfo) )
3392  {
3393  SCIPdebugMessage("bound change info [%d:<%s> %s %g] is invaild -> pop it from the queue\n", SCIPbdchginfoGetDepth(bdchginfo),
3394  SCIPvarGetName(SCIPbdchginfoGetVar(bdchginfo)),
3395  SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
3396  SCIPbdchginfoGetNewbound(bdchginfo));
3397 
3398  /* pop the invalid bound change info from the queue */
3399  (void)(SCIPpqueueRemove(conflict->bdchgqueue));
3400 
3401  /* call method recursively to get next conflict analysis candidate */
3402  bdchginfo = conflictFirstCand(conflict);
3403  }
3404  }
3405  assert(bdchginfo == NULL || !SCIPbdchginfoIsRedundant(bdchginfo));
3406 
3407  return bdchginfo;
3408 }
3409 
3410 /** adds the current conflict set (extended by all remaining bound changes in the queue) to the pool of conflict sets */
3411 static
3413  SCIP_CONFLICT* conflict, /**< conflict analysis data */
3414  BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
3415  SCIP_SET* set, /**< global SCIP settings */
3416  SCIP_STAT* stat, /**< dynamic problem statistics */
3417  SCIP_TREE* tree, /**< branch and bound tree */
3418  int validdepth, /**< minimal depth level at which the conflict set is valid */
3419  SCIP_Bool diving, /**< are we in strong branching or diving mode? */
3420  SCIP_Bool repropagate, /**< should the constraint trigger a repropagation? */
3421  SCIP_Bool* success, /**< pointer to store whether the conflict set is valid */
3422  int* nliterals /**< pointer to store the number of literals in the generated conflictset */
3423  )
3424 {
3425  SCIP_CONFLICTSET* conflictset;
3426  SCIP_BDCHGINFO** bdchginfos;
3427  int nbdchginfos;
3428  int currentdepth;
3429  int focusdepth;
3430 
3431  assert(conflict != NULL);
3432  assert(conflict->conflictset != NULL);
3433  assert(set != NULL);
3434  assert(stat != NULL);
3435  assert(tree != NULL);
3436  assert(success != NULL);
3437  assert(nliterals != NULL);
3438  assert(SCIPpqueueNElems(conflict->forcedbdchgqueue) == 0);
3439 
3440  *success = FALSE;
3441  *nliterals = 0;
3442 
3443  /* check, whether local conflicts are allowed */
3444  validdepth = MAX(validdepth, conflict->conflictset->validdepth);
3445  if( !set->conf_allowlocal && validdepth > 0 )
3446  return SCIP_OKAY;
3447 
3448  focusdepth = SCIPtreeGetFocusDepth(tree);
3449  currentdepth = SCIPtreeGetCurrentDepth(tree);
3450  assert(currentdepth == tree->pathlen-1);
3451  assert(focusdepth <= currentdepth);
3452  assert(0 <= conflict->conflictset->validdepth && conflict->conflictset->validdepth <= currentdepth);
3453  assert(0 <= validdepth && validdepth <= currentdepth);
3454 
3455  /* get the elements of the bound change queue */
3456  bdchginfos = (SCIP_BDCHGINFO**)SCIPpqueueElems(conflict->bdchgqueue);
3457  nbdchginfos = SCIPpqueueNElems(conflict->bdchgqueue);
3458 
3459  /* create a copy of the current conflict set, allocating memory for the additional elements of the queue */
3460  SCIP_CALL( conflictsetCopy(&conflictset, blkmem, conflict->conflictset, nbdchginfos) );
3461  conflictset->validdepth = validdepth;
3462  conflictset->repropagate = repropagate;
3463 
3464  /* add the valid queue elements to the conflict set */
3465  SCIPdebugMessage("adding %d variables from the queue as temporary conflict variables\n", nbdchginfos);
3466  SCIP_CALL( conflictsetAddBounds(conflict, conflictset, blkmem, set, bdchginfos, nbdchginfos) );
3467 
3468  /* calculate the depth, at which the conflictset should be inserted */
3469  SCIP_CALL( conflictsetCalcInsertDepth(conflictset, set, tree) );
3470  assert(conflictset->validdepth <= conflictset->insertdepth && conflictset->insertdepth <= currentdepth);
3471  SCIPdebugMessage(" -> conflict with %d literals found at depth %d is active in depth %d and valid in depth %d\n",
3472  conflictset->nbdchginfos, currentdepth, conflictset->insertdepth, conflictset->validdepth);
3473 
3474  /* if all branching variables are in the conflict set, the conflict set is of no use;
3475  * don't use conflict sets that are only valid in the probing path but not in the problem tree
3476  */
3477  if( (diving || conflictset->insertdepth < currentdepth) && conflictset->insertdepth <= focusdepth )
3478  {
3479  /* if the conflict should not be located only in the subtree where it is useful, put it to its valid depth level */
3480  if( !set->conf_settlelocal )
3481  conflictset->insertdepth = conflictset->validdepth;
3482 
3483  *nliterals = conflictset->nbdchginfos;
3484  SCIPdebugMessage(" -> final conflict set has %d literals\n", *nliterals);
3485 
3486  /* check conflict set on debugging solution */
3487  SCIP_CALL( SCIPdebugCheckConflict(blkmem, set, tree->path[validdepth],
3488  conflictset->bdchginfos, conflictset->relaxedbds, conflictset->nbdchginfos) ); /*lint !e506 !e774*/
3489 
3490  /* move conflictset to the conflictset storage */
3491  SCIP_CALL( conflictInsertConflictset(conflict, blkmem, set, &conflictset) );
3492  *success = TRUE;
3493  }
3494  else
3495  {
3496  /* free the temporary conflict set */
3497  conflictsetFree(&conflictset, blkmem);
3498  }
3499 
3500  return SCIP_OKAY;
3501 }
3502 
3503 /** tries to resolve given bound change
3504  * - resolutions on local constraints are only applied, if the constraint is valid at the
3505  * current minimal valid depth level, because this depth level is the topmost level to add the conflict
3506  * constraint to anyways
3507  *
3508  * @note it is sufficient to explain the relaxed bound change
3509  */
3510 static
3512  SCIP_CONFLICT* conflict, /**< conflict analysis data */
3513  SCIP_SET* set, /**< global SCIP settings */
3514  SCIP_BDCHGINFO* bdchginfo, /**< bound change to resolve */
3515  SCIP_Real relaxedbd, /**< the relaxed bound */
3516  int validdepth, /**< minimal depth level at which the conflict is valid */
3517  SCIP_Bool* resolved /**< pointer to store whether the bound change was resolved */
3518  )
3519 {
3520  SCIP_VAR* actvar;
3521  SCIP_CONS* infercons;
3522  SCIP_PROP* inferprop;
3523  SCIP_RESULT result;
3524 
3525 #ifndef NDEBUG
3526  int nforcedbdchgqueue;
3527  int nbdchgqueue;
3528  int i;
3529 
3530  /* store the current size of the conflict queues */
3531  nforcedbdchgqueue = SCIPpqueueNElems(conflict->forcedbdchgqueue);
3532  nbdchgqueue = SCIPpqueueNElems(conflict->bdchgqueue);
3533 #endif
3534 
3535  assert(conflict != NULL);
3536  assert(resolved != NULL);
3537  assert(!SCIPbdchginfoIsRedundant(bdchginfo));
3538 
3539  *resolved = FALSE;
3540 
3541  actvar = SCIPbdchginfoGetVar(bdchginfo);
3542  assert(actvar != NULL);
3543  assert(SCIPvarIsActive(actvar));
3544 
3545  SCIPdebugMessage("processing next conflicting bound (depth: %d, valid depth: %d, bdchgtype: %s [%s], vartype: %d): [<%s> %s %g(%g)]\n",
3546  SCIPbdchginfoGetDepth(bdchginfo), validdepth,
3547  SCIPbdchginfoGetChgtype(bdchginfo) == SCIP_BOUNDCHGTYPE_BRANCHING ? "branch"
3548  : SCIPbdchginfoGetChgtype(bdchginfo) == SCIP_BOUNDCHGTYPE_CONSINFER ? "cons" : "prop",
3552  : SCIPbdchginfoGetInferProp(bdchginfo) == NULL ? "-"
3554  SCIPvarGetType(actvar), SCIPvarGetName(actvar),
3555  SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
3556  SCIPbdchginfoGetNewbound(bdchginfo), relaxedbd);
3557  SCIPdebugMessage(" - conflict set :");
3558 
3559 #ifndef NDEBUG
3560  for( i = 0; i < conflict->conflictset->nbdchginfos; ++i )
3561  {
3562  SCIPdebugPrintf(" [%d:<%s> %s %g(%g)]", SCIPbdchginfoGetDepth(conflict->conflictset->bdchginfos[i]),
3564  SCIPbdchginfoGetBoundtype(conflict->conflictset->bdchginfos[i]) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
3565  SCIPbdchginfoGetNewbound(conflict->conflictset->bdchginfos[i]), conflict->conflictset->relaxedbds[i]);
3566  }
3567  SCIPdebugPrintf("\n");
3568  SCIPdebugMessage(" - forced candidates :");
3569 
3570  for( i = 0; i < nforcedbdchgqueue; ++i )
3571  {
3573  SCIPdebugPrintf(" [%d:<%s> %s %g(%g)]", SCIPbdchginfoGetDepth(info), SCIPvarGetName(SCIPbdchginfoGetVar(info)),
3574  bdchginfoIsInvalid(conflict, info) ? "<!>" : SCIPbdchginfoGetBoundtype(info) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
3576  }
3577  SCIPdebugPrintf("\n");
3578  SCIPdebugMessage(" - optional candidates:");
3579 
3580  for( i = 0; i < nbdchgqueue; ++i )
3581  {
3582  SCIP_BDCHGINFO* info = (SCIP_BDCHGINFO*)(SCIPpqueueElems(conflict->bdchgqueue)[i]);
3583  SCIPdebugPrintf(" [%d:<%s> %s %g(%g)]", SCIPbdchginfoGetDepth(info), SCIPvarGetName(SCIPbdchginfoGetVar(info)),
3584  bdchginfoIsInvalid(conflict, info) ? "<!>" : SCIPbdchginfoGetBoundtype(info) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
3586  }
3587  SCIPdebugPrintf("\n");
3588 #endif
3589 
3590  /* check, if the bound change can and should be resolved:
3591  * - resolutions on local constraints should only be applied, if the constraint is valid at the
3592  * current minimal valid depth level (which is initialized with the valid depth level of the initial
3593  * conflict set), because this depth level is the topmost level to add the conflict constraint to anyways
3594  */
3595  switch( SCIPbdchginfoGetChgtype(bdchginfo) )
3596  {
3598  infercons = SCIPbdchginfoGetInferCons(bdchginfo);
3599  assert(infercons != NULL);
3600 
3601  if( SCIPconsIsGlobal(infercons) || SCIPconsGetValidDepth(infercons) <= validdepth )
3602  {
3603  SCIP_VAR* infervar;
3604  int inferinfo;
3605  SCIP_BOUNDTYPE inferboundtype;
3606  SCIP_BDCHGIDX* bdchgidx;
3607 
3608  /* resolve bound change by asking the constraint that infered the bound to put all bounds that were
3609  * the reasons for the conflicting bound change on the priority queue
3610  */
3611  infervar = SCIPbdchginfoGetInferVar(bdchginfo);
3612  inferinfo = SCIPbdchginfoGetInferInfo(bdchginfo);
3613  inferboundtype = SCIPbdchginfoGetInferBoundtype(bdchginfo);
3614  bdchgidx = SCIPbdchginfoGetIdx(bdchginfo);
3615  assert(infervar != NULL);
3616 
3617  SCIPdebugMessage("resolving bound <%s> %s %g(%g) [status:%d, type:%d, depth:%d, pos:%d]: <%s> %s %g [cons:<%s>(%s), info:%d]\n",
3618  SCIPvarGetName(actvar),
3619  SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
3620  SCIPbdchginfoGetNewbound(bdchginfo), relaxedbd,
3621  SCIPvarGetStatus(actvar), SCIPvarGetType(actvar),
3622  SCIPbdchginfoGetDepth(bdchginfo), SCIPbdchginfoGetPos(bdchginfo),
3623  SCIPvarGetName(infervar),
3624  inferboundtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
3625  SCIPvarGetBdAtIndex(infervar, inferboundtype, bdchgidx, TRUE),
3626  SCIPconsGetName(infercons),
3627  SCIPconsIsGlobal(infercons) ? "global" : "local",
3628  inferinfo);
3629 
3630  /* in case the inference variables is not an active variables, we need to transform the relaxed bound */
3631  if( actvar != infervar )
3632  {
3633  SCIP_VAR* var;
3634  SCIP_Real scalar;
3635  SCIP_Real constant;
3636 
3637  assert(SCIPvarGetStatus(infervar) == SCIP_VARSTATUS_AGGREGATED
3638  || SCIPvarGetStatus(infervar) == SCIP_VARSTATUS_NEGATED);
3639 
3640  scalar = 1.0;
3641  constant = 0.0;
3642 
3643  var = infervar;
3644 
3645  /* transform given varibale to active varibale */
3646  SCIP_CALL( SCIPvarGetProbvarSum(&var, set, &scalar, &constant) );
3647  assert(var == actvar);
3648 
3649  relaxedbd *= scalar;
3650  relaxedbd += constant;
3651  }
3652 
3653  SCIP_CALL( SCIPconsResolvePropagation(infercons, set, infervar, inferinfo, inferboundtype, bdchgidx, relaxedbd, &result) );
3654  *resolved = (result == SCIP_SUCCESS);
3655  }
3656  break;
3657 
3659  inferprop = SCIPbdchginfoGetInferProp(bdchginfo);
3660  if( inferprop != NULL )
3661  {
3662  SCIP_VAR* infervar;
3663  int inferinfo;
3664  SCIP_BOUNDTYPE inferboundtype;
3665  SCIP_BDCHGIDX* bdchgidx;
3666 
3667  /* resolve bound change by asking the propagator that infered the bound to put all bounds that were
3668  * the reasons for the conflicting bound change on the priority queue
3669  */
3670  infervar = SCIPbdchginfoGetInferVar(bdchginfo);
3671  inferinfo = SCIPbdchginfoGetInferInfo(bdchginfo);
3672  inferboundtype = SCIPbdchginfoGetInferBoundtype(bdchginfo);
3673  bdchgidx = SCIPbdchginfoGetIdx(bdchginfo);
3674  assert(infervar != NULL);
3675 
3676  SCIPdebugMessage("resolving bound <%s> %s %g(%g) [status:%d, depth:%d, pos:%d]: <%s> %s %g [prop:<%s>, info:%d]\n",
3677  SCIPvarGetName(actvar),
3678  SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
3679  SCIPbdchginfoGetNewbound(bdchginfo), relaxedbd,
3680  SCIPvarGetStatus(actvar), SCIPbdchginfoGetDepth(bdchginfo), SCIPbdchginfoGetPos(bdchginfo),
3681  SCIPvarGetName(infervar),
3682  inferboundtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
3683  SCIPvarGetBdAtIndex(infervar, inferboundtype, bdchgidx, TRUE),
3684  SCIPpropGetName(inferprop), inferinfo);
3685 
3686  SCIP_CALL( SCIPpropResolvePropagation(inferprop, set, infervar, inferinfo, inferboundtype, bdchgidx, relaxedbd, &result) );
3687  *resolved = (result == SCIP_SUCCESS);
3688  }
3689  break;
3690 
3692  assert(!(*resolved));
3693  break;
3694 
3695  default:
3696  SCIPerrorMessage("invalid bound change type <%d>\n", SCIPbdchginfoGetChgtype(bdchginfo));
3697  return SCIP_INVALIDDATA;
3698  }
3699 
3700  SCIPdebugMessage("resolving status: %u\n", *resolved);
3701 
3702 #ifndef NDEBUG
3703  /* subract the size of the conflicq queues */
3704  nforcedbdchgqueue -= SCIPpqueueNElems(conflict->forcedbdchgqueue);
3705  nbdchgqueue -= SCIPpqueueNElems(conflict->bdchgqueue);
3706 
3707  /* in case the bound change was not resolved, the conflict queues should have the same size (contents) */
3708  assert((*resolved) || (nforcedbdchgqueue == 0 && nbdchgqueue == 0));
3709 #endif
3710 
3711  return SCIP_OKAY;
3712 }
3713 
3714 /** if only one conflicting bound change of the last depth level was used, and if this can be resolved,
3715  * creates GRASP-like reconvergence conflict constraints in the conflict graph up to the branching variable of this
3716  * depth level
3717  */
3718 static
3720  SCIP_CONFLICT* conflict, /**< conflict analysis data */
3721  BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
3722  SCIP_SET* set, /**< global SCIP settings */
3723  SCIP_STAT* stat, /**< problem statistics */
3724  SCIP_PROB* prob, /**< problem data */
3725  SCIP_TREE* tree, /**< branch and bound tree */
3726  SCIP_Bool diving, /**< are we in strong branching or diving mode? */
3727  int validdepth, /**< minimal depth level at which the initial conflict set is valid */
3728  SCIP_BDCHGINFO* firstuip, /**< first UIP of conflict graph */
3729  int* nreconvconss, /**< pointer to store the number of generated reconvergence constraints */
3730  int* nreconvliterals /**< pointer to store the number of literals generated reconvergence constraints */
3731  )
3732 {
3733  SCIP_BDCHGINFO* uip;
3734  int firstuipdepth;
3735  int focusdepth;
3736  int currentdepth;
3737  int maxvaliddepth;
3738 
3739  assert(conflict != NULL);
3740  assert(firstuip != NULL);
3741  assert(nreconvconss != NULL);
3742  assert(nreconvliterals != NULL);
3743  assert(!SCIPbdchginfoIsRedundant(firstuip));
3744 
3745  focusdepth = SCIPtreeGetFocusDepth(tree);
3746  currentdepth = SCIPtreeGetCurrentDepth(tree);
3747  assert(currentdepth == tree->pathlen-1);
3748  assert(focusdepth <= currentdepth);
3749 
3750  /* check, whether local constraints are allowed; however, don't generate reconvergence constraints that are only valid
3751  * in the probing path and not in the problem tree (i.e. that exceed the focusdepth)
3752  */
3753  maxvaliddepth = (set->conf_allowlocal ? MIN(currentdepth-1, focusdepth) : 0);
3754  if( validdepth > maxvaliddepth )
3755  return SCIP_OKAY;
3756 
3757  firstuipdepth = SCIPbdchginfoGetDepth(firstuip);
3758 
3759  /* for each succeeding UIP pair of the last depth level, create one reconvergence constraint */
3760  uip = firstuip;
3761  while( uip != NULL && SCIPbdchginfoGetDepth(uip) == SCIPbdchginfoGetDepth(firstuip) && bdchginfoIsResolvable(uip) )
3762  {
3763  SCIP_BDCHGINFO* oppositeuip;
3764  SCIP_BDCHGINFO* bdchginfo;
3765  SCIP_BDCHGINFO* nextuip;
3766  SCIP_VAR* uipvar;
3767  SCIP_Real oppositeuipbound;
3768  SCIP_BOUNDTYPE oppositeuipboundtype;
3769  int nresolutions;
3770 
3771  assert(!SCIPbdchginfoIsRedundant(uip));
3772 
3773  SCIPdebugMessage("creating reconvergence constraint for UIP <%s> %s %g in depth %d pos %d\n",
3776 
3777  /* initialize conflict data */
3778  SCIP_CALL( SCIPconflictInit(conflict, set, stat, prob) );
3779 
3780  /* create a temporary bound change information for the negation of the UIP's bound change;
3781  * this bound change information is freed in the SCIPconflictFlushConss() call;
3782  * for reconvergence constraints for continuous variables we can only use the "negation" !(x <= u) == (x >= u);
3783  * during conflict analysis, we treat a continuous bound "x >= u" in the conflict set as "x > u", and in the
3784  * generated constraint this is negated again to "x <= u" which is correct.
3785  */
3786  uipvar = SCIPbdchginfoGetVar(uip);
3787  oppositeuipboundtype = SCIPboundtypeOpposite(SCIPbdchginfoGetBoundtype(uip));
3788  oppositeuipbound = SCIPbdchginfoGetNewbound(uip);
3789  if( SCIPvarIsIntegral(uipvar) )
3790  {
3791  assert(SCIPsetIsIntegral(set, oppositeuipbound));
3792  oppositeuipbound += (oppositeuipboundtype == SCIP_BOUNDTYPE_LOWER ? +1.0 : -1.0);
3793  }
3794  SCIP_CALL( conflictCreateTmpBdchginfo(conflict, blkmem, set, uipvar,
3795  oppositeuipboundtype, oppositeuipboundtype == SCIP_BOUNDTYPE_LOWER ? SCIP_REAL_MIN : SCIP_REAL_MAX,
3796  oppositeuipbound, &oppositeuip) );
3797 
3798  /* put the negated UIP into the conflict set */
3799  SCIP_CALL( conflictAddConflictBound(conflict, blkmem, set, oppositeuip, oppositeuipbound) );
3800 
3801  /* put positive UIP into priority queue */
3802  SCIP_CALL( conflictQueueBound(conflict, set, uip, SCIPbdchginfoGetNewbound(uip) ) );
3803 
3804  /* resolve the queue until the next UIP is reached */
3805  bdchginfo = conflictFirstCand(conflict);
3806  nextuip = NULL;
3807  nresolutions = 0;
3808  while( bdchginfo != NULL && validdepth <= maxvaliddepth )
3809  {
3810  SCIP_BDCHGINFO* nextbdchginfo;
3811  SCIP_Real relaxedbd;
3812  SCIP_Bool forceresolve;
3813  int bdchgdepth;
3814 
3815  /* check if the next bound change must be resolved in every case */
3816  forceresolve = (SCIPpqueueNElems(conflict->forcedbdchgqueue) > 0);
3817 
3818  /* remove currently processed candidate and get next conflicting bound from the conflict candidate queue before
3819  * we remove the candidate we have to collect the relaxed bound since removing the candidate from the queue
3820  * invalidates the relaxed bound
3821  */
3822  assert(bdchginfo == conflictFirstCand(conflict));
3823  relaxedbd = SCIPbdchginfoGetRelaxedBound(bdchginfo);
3824  bdchginfo = conflictRemoveCand(conflict);
3825  nextbdchginfo = conflictFirstCand(conflict);
3826  bdchgdepth = SCIPbdchginfoGetDepth(bdchginfo);
3827  assert(bdchginfo != NULL);
3828  assert(!SCIPbdchginfoIsRedundant(bdchginfo));
3829  assert(nextbdchginfo == NULL || SCIPbdchginfoGetDepth(bdchginfo) >= SCIPbdchginfoGetDepth(nextbdchginfo)
3830  || forceresolve);
3831  assert(bdchgdepth <= firstuipdepth);
3832 
3833  /* bound changes that are higher in the tree than the valid depth of the conflict can be ignored;
3834  * multiple insertions of the same bound change can be ignored
3835  */
3836  if( bdchgdepth > validdepth && bdchginfo != nextbdchginfo )
3837  {
3838  SCIP_VAR* actvar;
3839  SCIP_Bool resolved;
3840 
3841  actvar = SCIPbdchginfoGetVar(bdchginfo);
3842  assert(actvar != NULL);
3843  assert(SCIPvarIsActive(actvar));
3844 
3845  /* check if we have to resolve the bound change in this depth level
3846  * - the starting uip has to be resolved
3847  * - a bound change should be resolved, if it is in the fuip's depth level and not the
3848  * next uip (i.e., if it is not the last bound change in the fuip's depth level)
3849  * - a forced bound change must be resolved in any case
3850  */
3851  resolved = FALSE;
3852  if( bdchginfo == uip
3853  || (bdchgdepth == firstuipdepth
3854  && nextbdchginfo != NULL
3855  && SCIPbdchginfoGetDepth(nextbdchginfo) == bdchgdepth)
3856  || forceresolve )
3857  {
3858  SCIP_CALL( conflictResolveBound(conflict, set, bdchginfo, relaxedbd, validdepth, &resolved) );
3859  }
3860 
3861  if( resolved )
3862  nresolutions++;
3863  else if( forceresolve )
3864  {
3865  /* variable cannot enter the conflict clause: we have to make the conflict clause local, s.t.
3866  * the unresolved bound change is active in the whole sub tree of the conflict clause
3867  */
3868  assert(bdchgdepth >= validdepth);
3869  validdepth = bdchgdepth;
3870 
3871  SCIPdebugMessage("couldn't resolve forced bound change on <%s> -> new valid depth: %d\n",
3872  SCIPvarGetName(actvar), validdepth);
3873  }
3874  else if( bdchginfo != uip )
3875  {
3876  assert(conflict->conflictset != NULL);
3877  assert(conflict->conflictset->nbdchginfos >= 1); /* starting UIP is already member of the conflict set */
3878 
3879  /* if this is the first variable of the conflict set besides the current starting UIP, it is the next
3880  * UIP (or the first unresolvable bound change)
3881  */
3882  if( bdchgdepth == firstuipdepth && conflict->conflictset->nbdchginfos == 1 )
3883  {
3884  assert(nextuip == NULL);
3885  nextuip = bdchginfo;
3886  }
3887 
3888  /* put bound change into the conflict set */
3889  SCIP_CALL( conflictAddConflictBound(conflict, blkmem, set, bdchginfo, relaxedbd) );
3890  assert(conflict->conflictset->nbdchginfos >= 2);
3891  }
3892  else
3893  assert(conflictFirstCand(conflict) == NULL); /* the starting UIP was not resolved */
3894  }
3895 
3896  /* get next conflicting bound from the conflict candidate queue (this does not need to be nextbdchginfo, because
3897  * due to resolving the bound changes, a variable could be added to the queue which must be
3898  * resolved before nextbdchginfo)
3899  */
3900  bdchginfo = conflictFirstCand(conflict);
3901  }
3902  assert(nextuip != uip);
3903 
3904  /* if only one propagation was resolved, the reconvergence constraint is already member of the constraint set
3905  * (it is exactly the constraint that produced the propagation)
3906  */
3907  if( nextuip != NULL && nresolutions >= 2 && bdchginfo == NULL && validdepth <= maxvaliddepth )
3908  {
3909  int nlits;
3910  SCIP_Bool success;
3911 
3912  assert(SCIPbdchginfoGetDepth(nextuip) == SCIPbdchginfoGetDepth(uip));
3913 
3914  /* check conflict graph frontier on debugging solution */
3915  SCIP_CALL( SCIPdebugCheckConflictFrontier(blkmem, set, tree->path[validdepth],
3916  bdchginfo, conflict->conflictset->bdchginfos, conflict->conflictset->relaxedbds,
3917  conflict->conflictset->nbdchginfos, conflict->bdchgqueue, conflict->forcedbdchgqueue) ); /*lint !e506 !e774*/
3918 
3919  SCIPdebugMessage("creating reconvergence constraint from UIP <%s> to UIP <%s> in depth %d with %d literals after %d resolutions\n",
3921  SCIPbdchginfoGetDepth(uip), conflict->conflictset->nbdchginfos, nresolutions);
3922 
3923  /* call the conflict handlers to create a conflict set */
3924  SCIP_CALL( conflictAddConflictset(conflict, blkmem, set, stat, tree, validdepth, diving, FALSE,
3925  &success, &nlits) );
3926  if( success )
3927  {
3928  (*nreconvconss)++;
3929  (*nreconvliterals) += nlits;
3930  }
3931  }
3932 
3933  /* clear the conflict candidate queue and the conflict set (to make sure, oppositeuip is not referenced anymore) */
3934  conflictClear(conflict);
3935 
3936  uip = nextuip;
3937  }
3938 
3939  return SCIP_OKAY;
3940 }
3941 
3942 /** analyzes conflicting bound changes that were added with calls to SCIPconflictAddBound() and
3943  * SCIPconflictAddRelaxedBound(), and on success, calls the conflict handlers to create a conflict constraint out of
3944  * the resulting conflict set; afterwards the conflict queue and the conflict set is cleared
3945  */
3946 static
3948  SCIP_CONFLICT* conflict, /**< conflict analysis data */
3949  BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
3950  SCIP_SET* set, /**< global SCIP settings */
3951  SCIP_STAT* stat, /**< problem statistics */
3952  SCIP_PROB* prob, /**< problem data */
3953  SCIP_TREE* tree, /**< branch and bound tree */
3954  SCIP_Bool diving, /**< are we in strong branching or diving mode? */
3955  int validdepth, /**< minimal depth level at which the initial conflict set is valid */
3956  SCIP_Bool mustresolve, /**< should the conflict set only be used, if a resolution was applied? */
3957  int* nconss, /**< pointer to store the number of generated conflict constraints */
3958  int* nliterals, /**< pointer to store the number of literals in generated conflict constraints */
3959  int* nreconvconss, /**< pointer to store the number of generated reconvergence constraints */
3960  int* nreconvliterals /**< pointer to store the number of literals generated reconvergence constraints */
3961  )
3962 {
3963  SCIP_BDCHGINFO* bdchginfo;
3964  SCIP_BDCHGINFO** firstuips;
3965  int nfirstuips;
3966  int focusdepth;
3967  int currentdepth;
3968  int maxvaliddepth;
3969  int resolvedepth;
3970  int nresolutions;
3971  int lastconsnresolutions;
3972  int lastconsresoldepth;
3973 
3974  assert(conflict != NULL);
3975  assert(conflict->conflictset != NULL);
3976  assert(conflict->conflictset->nbdchginfos >= 0);
3977  assert(set != NULL);
3978  assert(stat != NULL);
3979  assert(0 <= validdepth && validdepth <= SCIPtreeGetCurrentDepth(tree));
3980  assert(nconss != NULL);
3981  assert(nliterals != NULL);
3982  assert(nreconvconss != NULL);
3983  assert(nreconvliterals != NULL);
3984 
3985  focusdepth = SCIPtreeGetFocusDepth(tree);
3986  currentdepth = SCIPtreeGetCurrentDepth(tree);
3987  assert(currentdepth == tree->pathlen-1);
3988  assert(focusdepth <= currentdepth);
3989 
3990  resolvedepth = ((set->conf_fuiplevels >= 0 && set->conf_fuiplevels <= currentdepth)
3991  ? currentdepth - set->conf_fuiplevels + 1 : 0);
3992  assert(0 <= resolvedepth && resolvedepth <= currentdepth + 1);
3993 
3994  /* if we must resolve at least one bound change, find the first UIP at least in the last depth level */
3995  if( mustresolve )
3996  resolvedepth = MIN(resolvedepth, currentdepth);
3997 
3998  SCIPdebugMessage("analyzing conflict with %d+%d conflict candidates and starting conflict set of size %d in depth %d (resolvedepth=%d)\n",
4000  conflict->conflictset->nbdchginfos, currentdepth, resolvedepth);
4001 
4002  *nconss = 0;
4003  *nliterals = 0;
4004  *nreconvconss = 0;
4005  *nreconvliterals = 0;
4006 
4007  /* check, whether local conflicts are allowed; however, don't generate conflict constraints that are only valid in the
4008  * probing path and not in the problem tree (i.e. that exceed the focusdepth)
4009  */
4010  maxvaliddepth = (set->conf_allowlocal ? MIN(currentdepth-1, focusdepth) : 0);
4011  if( validdepth > maxvaliddepth )
4012  return SCIP_OKAY;
4013 
4014  /* allocate temporary memory for storing first UIPs (in each depth level, at most two bound changes can be flagged
4015  * as UIP, namely a binary and a non-binary bound change)
4016  */
4017  SCIP_CALL( SCIPsetAllocBufferArray(set, &firstuips, 2*(currentdepth+1)) );
4018 
4019  /* process all bound changes in the conflict candidate queue */
4020  nresolutions = 0;
4021  lastconsnresolutions = (mustresolve ? 0 : -1);
4022  lastconsresoldepth = (mustresolve ? currentdepth : INT_MAX);
4023  bdchginfo = conflictFirstCand(conflict);
4024  nfirstuips = 0;
4025 
4026  /* check if the initial reason on debugging solution */
4027  SCIP_CALL( SCIPdebugCheckConflictFrontier(blkmem, set, tree->path[validdepth],
4028  NULL, conflict->conflictset->bdchginfos, conflict->conflictset->relaxedbds, conflict->conflictset->nbdchginfos,
4029  conflict->bdchgqueue, conflict->forcedbdchgqueue) ); /*lint !e506 !e774*/
4030 
4031  while( bdchginfo != NULL && validdepth <= maxvaliddepth )
4032  {
4033  SCIP_BDCHGINFO* nextbdchginfo;
4034  SCIP_Real relaxedbd;
4035  SCIP_Bool forceresolve;
4036  int bdchgdepth;
4037 
4038  assert(!SCIPbdchginfoIsRedundant(bdchginfo));
4039 
4040  /* check if the next bound change must be resolved in every case */
4041  forceresolve = (SCIPpqueueNElems(conflict->forcedbdchgqueue) > 0);
4042 
4043  /* resolve next bound change in queue */
4044  bdchgdepth = SCIPbdchginfoGetDepth(bdchginfo);
4045  assert(0 <= bdchgdepth && bdchgdepth <= currentdepth);
4046  assert(SCIPvarIsActive(SCIPbdchginfoGetVar(bdchginfo)));
4047  assert(bdchgdepth < tree->pathlen);
4048  assert(tree->path[bdchgdepth] != NULL);
4049  assert(tree->path[bdchgdepth]->domchg != NULL);
4050  assert(SCIPbdchginfoGetPos(bdchginfo) < (int)tree->path[bdchgdepth]->domchg->domchgbound.nboundchgs);
4051  assert(tree->path[bdchgdepth]->domchg->domchgbound.boundchgs[SCIPbdchginfoGetPos(bdchginfo)].var
4052  == SCIPbdchginfoGetVar(bdchginfo));
4053  assert(tree->path[bdchgdepth]->domchg->domchgbound.boundchgs[SCIPbdchginfoGetPos(bdchginfo)].newbound
4054  == SCIPbdchginfoGetNewbound(bdchginfo)
4057  == SCIPbdchginfoGetNewbound(bdchginfo)); /*lint !e777*/
4058  assert((SCIP_BOUNDTYPE)tree->path[bdchgdepth]->domchg->domchgbound.boundchgs[SCIPbdchginfoGetPos(bdchginfo)].boundtype
4059  == SCIPbdchginfoGetBoundtype(bdchginfo));
4060 
4061  /* create intermediate conflict constraint */
4062  assert(nresolutions >= lastconsnresolutions);
4063  if( !forceresolve )
4064  {
4065  if( nresolutions == lastconsnresolutions )
4066  lastconsresoldepth = bdchgdepth; /* all intermediate depth levels consisted of only unresolved bound changes */
4067  else if( bdchgdepth < lastconsresoldepth && (set->conf_interconss == -1 || *nconss < set->conf_interconss) )
4068  {
4069  int nlits;
4070  SCIP_Bool success;
4071 
4072  /* call the conflict handlers to create a conflict set */
4073  SCIPdebugMessage("creating intermediate conflictset after %d resolutions up to depth %d (valid at depth %d): %d conflict bounds, %d bounds in queue\n",
4074  nresolutions, bdchgdepth, validdepth, conflict->conflictset->nbdchginfos,
4075  SCIPpqueueNElems(conflict->bdchgqueue));
4076  SCIP_CALL( conflictAddConflictset(conflict, blkmem, set, stat, tree, validdepth, diving, TRUE,
4077  &success, &nlits) );
4078  lastconsnresolutions = nresolutions;
4079  lastconsresoldepth = bdchgdepth;
4080  if( success )
4081  {
4082  (*nconss)++;
4083  (*nliterals) += nlits;
4084  }
4085  }
4086  }
4087 
4088  /* remove currently processed candidate and get next conflicting bound from the conflict candidate queue before
4089  * we remove the candidate we have to collect the relaxed bound since removing the candidate from the queue
4090  * invalidates the relaxed bound
4091  */
4092  assert(bdchginfo == conflictFirstCand(conflict));
4093  relaxedbd = SCIPbdchginfoGetRelaxedBound(bdchginfo);
4094  bdchginfo = conflictRemoveCand(conflict);
4095  nextbdchginfo = conflictFirstCand(conflict);
4096  assert(bdchginfo != NULL);
4097  assert(!SCIPbdchginfoIsRedundant(bdchginfo));
4098  assert(nextbdchginfo == NULL || SCIPbdchginfoGetDepth(bdchginfo) >= SCIPbdchginfoGetDepth(nextbdchginfo)
4099  || forceresolve);
4100 
4101  /* we don't need to resolve bound changes that are already active in the valid depth of the current conflict set,
4102  * because the conflict set can only be added locally at the valid depth, and all bound changes applied in this
4103  * depth or earlier can be removed from the conflict constraint, since they are already applied in the constraint's
4104  * subtree;
4105  * if the next bound change on the remaining queue is equal to the current bound change,
4106  * this is a multiple insertion in the conflict candidate queue and we can ignore the current
4107  * bound change
4108  */
4109  if( bdchgdepth > validdepth && bdchginfo != nextbdchginfo )
4110  {
4111  SCIP_VAR* actvar;
4112  SCIP_Bool resolved;
4113 
4114  actvar = SCIPbdchginfoGetVar(bdchginfo);
4115  assert(actvar != NULL);
4116  assert(SCIPvarIsActive(actvar));
4117 
4118  /* check if we want to resolve the bound change in this depth level
4119  * - bound changes should be resolved, if
4120  * (i) we must apply at least one resolution and didn't resolve a bound change yet, or
4121  * (ii) their depth level is at least equal to the minimal resolving depth, and
4122  * they are not the last remaining conflicting bound change in their depth level
4123  * (iii) the bound change resolving is forced (i.e., the forced queue was non-empty)
4124  */
4125  resolved = FALSE;
4126  if( (mustresolve && nresolutions == 0)
4127  || (bdchgdepth >= resolvedepth
4128  && nextbdchginfo != NULL
4129  && SCIPbdchginfoGetDepth(nextbdchginfo) == bdchgdepth)
4130  || forceresolve )
4131  {
4132  SCIP_CALL( conflictResolveBound(conflict, set, bdchginfo, relaxedbd, validdepth, &resolved) );
4133  }
4134 
4135  if( resolved )
4136  nresolutions++;
4137  else if( forceresolve )
4138  {
4139  /* variable cannot enter the conflict clause: we have to make the conflict clause local, s.t.
4140  * the unresolved bound change is active in the whole sub tree of the conflict clause
4141  */
4142  assert(bdchgdepth >= validdepth);
4143  validdepth = bdchgdepth;
4144 
4145  SCIPdebugMessage("couldn't resolve forced bound change on <%s> -> new valid depth: %d\n",
4146  SCIPvarGetName(actvar), validdepth);
4147  }
4148  else
4149  {
4150  /* if this is a UIP (the last bound change in its depth level), it can be used to generate a
4151  * UIP reconvergence constraint
4152  */
4153  if( nextbdchginfo == NULL || SCIPbdchginfoGetDepth(nextbdchginfo) != bdchgdepth )
4154  {
4155  assert(nfirstuips < 2*(currentdepth+1));
4156  firstuips[nfirstuips] = bdchginfo;
4157  nfirstuips++;
4158  }
4159 
4160  /* put variable into the conflict set, using the literal that is currently fixed to FALSE */
4161  SCIP_CALL( conflictAddConflictBound(conflict, blkmem, set, bdchginfo, relaxedbd) );
4162  }
4163  }
4164 
4165  /* check conflict graph frontier on debugging solution */
4166  SCIP_CALL( SCIPdebugCheckConflictFrontier(blkmem, set, tree->path[validdepth],
4167  bdchginfo, conflict->conflictset->bdchginfos, conflict->conflictset->relaxedbds, conflict->conflictset->nbdchginfos,
4168  conflict->bdchgqueue, conflict->forcedbdchgqueue) ); /*lint !e506 !e774*/
4169 
4170  /* get next conflicting bound from the conflict candidate queue (this needs not to be nextbdchginfo, because
4171  * due to resolving the bound changes, a bound change could be added to the queue which must be
4172  * resolved before nextbdchginfo)
4173  */
4174  bdchginfo = conflictFirstCand(conflict);
4175  }
4176 
4177  /* check, if a valid conflict set was found */
4178  if( bdchginfo == NULL
4179  && nresolutions > lastconsnresolutions
4180  && validdepth <= maxvaliddepth
4181  && (!mustresolve || nresolutions > 0 || conflict->conflictset->nbdchginfos == 0)
4182  && SCIPpqueueNElems(conflict->forcedbdchgqueue) == 0 )
4183  {
4184  int nlits;
4185  SCIP_Bool success;
4186 
4187  /* call the conflict handlers to create a conflict set */
4188  SCIP_CALL( conflictAddConflictset(conflict, blkmem, set, stat, tree, validdepth, diving, TRUE, &success, &nlits) );
4189  if( success )
4190  {
4191  (*nconss)++;
4192  (*nliterals) += nlits;
4193  }
4194  }
4195 
4196  /* produce reconvergence constraints defined by succeeding UIP's of the last depth level */
4197  if( set->conf_reconvlevels != 0 && validdepth <= maxvaliddepth )
4198  {
4199  int reconvlevels;
4200  int i;
4201 
4202  reconvlevels = (set->conf_reconvlevels == -1 ? INT_MAX : set->conf_reconvlevels);
4203  for( i = 0; i < nfirstuips; ++i )
4204  {
4205  if( SCIPbdchginfoHasInferenceReason(firstuips[i])
4206  && currentdepth - SCIPbdchginfoGetDepth(firstuips[i]) < reconvlevels )
4207  {
4208  SCIP_CALL( conflictCreateReconvergenceConss(conflict, blkmem, set, stat, prob, tree, diving,
4209  validdepth, firstuips[i], nreconvconss, nreconvliterals) );
4210  }
4211  }
4212  }
4213 
4214  /* free the temporary memory */
4215  SCIPsetFreeBufferArray(set, &firstuips);
4216 
4217  /* clear the conflict candidate queue and the conflict set */
4218  conflictClear(conflict);
4219 
4220  return SCIP_OKAY;
4221 }
4222 
4223 /** analyzes conflicting bound changes that were added with calls to SCIPconflictAddBound(), and on success, calls the
4224  * conflict handlers to create a conflict constraint out of the resulting conflict set;
4225  * updates statistics for propagation conflict analysis
4226  */
4228  SCIP_CONFLICT* conflict, /**< conflict analysis data */
4229  BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
4230  SCIP_SET* set, /**< global SCIP settings */
4231  SCIP_STAT* stat, /**< problem statistics */
4232  SCIP_PROB* prob, /**< problem data */
4233  SCIP_TREE* tree, /**< branch and bound tree */
4234  int validdepth, /**< minimal depth level at which the initial conflict set is valid */
4235  SCIP_Bool* success /**< pointer to store whether a conflict constraint was created, or NULL */
4236  )
4237 {
4238  int nconss;
4239  int nliterals;
4240  int nreconvconss;
4241  int nreconvliterals;
4242 
4243  assert(conflict != NULL);
4244  assert(conflict->conflictset != NULL);
4245  assert(set != NULL);
4246  assert(prob != NULL);
4247 
4248 
4249  if( success != NULL )
4250  *success = FALSE;
4251 
4252  /* check if the conflict analysis is applicable */
4253  if( !SCIPconflictApplicable(set) )
4254  return SCIP_OKAY;
4255 
4256  /* check, if the conflict set will get too large with high probability */
4257  if( conflict->conflictset->nbdchginfos + SCIPpqueueNElems(conflict->bdchgqueue)
4258  + SCIPpqueueNElems(conflict->forcedbdchgqueue) >= 2*conflictCalcMaxsize(set, prob) )
4259  return SCIP_OKAY;
4260 
4261  SCIPdebugMessage("analyzing conflict after infeasible propagation in depth %d\n", SCIPtreeGetCurrentDepth(tree));
4262 
4263  /* start timing */
4264  SCIPclockStart(conflict->propanalyzetime, set);
4265 
4266  conflict->npropcalls++;
4267 
4268  /* analyze the conflict set, and create a conflict constraint on success */
4269  SCIP_CALL( conflictAnalyze(conflict, blkmem, set, stat, prob, tree, FALSE, validdepth, TRUE,
4270  &nconss, &nliterals, &nreconvconss, &nreconvliterals) );
4271  conflict->npropsuccess += (nconss > 0 ? 1 : 0);
4272  conflict->npropconfconss += nconss;
4273  conflict->npropconfliterals += nliterals;
4274  conflict->npropreconvconss += nreconvconss;
4275  conflict->npropreconvliterals += nreconvliterals;
4276  if( success != NULL )
4277  *success = (nconss > 0);
4278 
4279  /* stop timing */
4280  SCIPclockStop(conflict->propanalyzetime, set);
4281 
4282  return SCIP_OKAY;
4283 }
4284 
4285 /** gets time in seconds used for preprocessing global conflict constraint before appliance */
4287  SCIP_CONFLICT* conflict /**< conflict analysis data */
4288  )
4289 {
4290  assert(conflict != NULL);
4291 
4292  return SCIPclockGetTime(conflict->dIBclock);
4293 }
4294 
4295 /** gets time in seconds used for analyzing propagation conflicts */
4297  SCIP_CONFLICT* conflict /**< conflict analysis data */
4298  )
4299 {
4300  assert(conflict != NULL);
4301 
4302  return SCIPclockGetTime(conflict->propanalyzetime);
4303 }
4304 
4305 /** gets number of calls to propagation conflict analysis */
4307  SCIP_CONFLICT* conflict /**< conflict analysis data */
4308  )
4309 {
4310  assert(conflict != NULL);
4311 
4312  return conflict->npropcalls;
4313 }
4314 
4315 /** gets number of calls to propagation conflict analysis that yield at least one conflict constraint */
4317  SCIP_CONFLICT* conflict /**< conflict analysis data */
4318  )
4319 {
4320  assert(conflict != NULL);
4321 
4322  return conflict->npropsuccess;
4323 }
4324 
4325 /** gets number of conflict constraints detected in propagation conflict analysis */
4327  SCIP_CONFLICT* conflict /**< conflict analysis data */
4328  )
4329 {
4330  assert(conflict != NULL);
4331 
4332  return conflict->npropconfconss;
4333 }
4334 
4335 /** gets total number of literals in conflict constraints created in propagation conflict analysis */
4337  SCIP_CONFLICT* conflict /**< conflict analysis data */
4338  )
4339 {
4340  assert(conflict != NULL);
4341 
4342  return conflict->npropconfliterals;
4343 }
4344 
4345 /** gets number of reconvergence constraints detected in propagation conflict analysis */
4347  SCIP_CONFLICT* conflict /**< conflict analysis data */
4348  )
4349 {
4350  assert(conflict != NULL);
4351 
4352  return conflict->npropreconvconss;
4353 }
4354 
4355 /** gets total number of literals in reconvergence constraints created in propagation conflict analysis */
4357  SCIP_CONFLICT* conflict /**< conflict analysis data */
4358  )
4359 {
4360  assert(conflict != NULL);
4361 
4362  return conflict->npropreconvliterals;
4363 }
4364 
4365 
4366 
4367 
4368 /*
4369  * Infeasible LP Conflict Analysis
4370  */
4371 
4372 /** ensures, that side change arrays can store at least num entries */
4373 static
4375  SCIP_SET* set, /**< global SCIP settings */
4376  int** sidechginds, /**< pointer to side change index array */
4377  SCIP_Real** sidechgoldlhss, /**< pointer to side change old left hand sides array */
4378  SCIP_Real** sidechgoldrhss, /**< pointer to side change old right hand sides array */
4379  SCIP_Real** sidechgnewlhss, /**< pointer to side change new left hand sides array */
4380  SCIP_Real** sidechgnewrhss, /**< pointer to side change new right hand sides array */
4381  int* sidechgssize, /**< pointer to size of side change arrays */
4382  int num /**< minimal number of entries to be able to store in side change arrays */
4383  )
4384 {
4385  assert(sidechginds != NULL);
4386  assert(sidechgoldlhss != NULL);
4387  assert(sidechgoldrhss != NULL);
4388  assert(sidechgnewlhss != NULL);
4389  assert(sidechgnewrhss != NULL);
4390  assert(sidechgssize != NULL);
4391 
4392  if( num > *sidechgssize )
4393  {
4394  int newsize;
4395 
4396  newsize = SCIPsetCalcMemGrowSize(set, num);
4397  SCIP_CALL( SCIPsetReallocBufferArray(set, sidechginds, newsize) );
4398  SCIP_CALL( SCIPsetReallocBufferArray(set, sidechgoldlhss, newsize) );
4399  SCIP_CALL( SCIPsetReallocBufferArray(set, sidechgoldrhss, newsize) );
4400  SCIP_CALL( SCIPsetReallocBufferArray(set, sidechgnewlhss, newsize) );
4401  SCIP_CALL( SCIPsetReallocBufferArray(set, sidechgnewrhss, newsize) );
4402  *sidechgssize = newsize;
4403  }
4404  assert(num <= *sidechgssize);
4405 
4406  return SCIP_OKAY;
4407 }
4408 
4409 /** adds removal of row's side to side change arrays; finite sides are only replaced by near infinite sides, such
4410  * that the row's sense in the LP solver is not changed
4411  */
4412 static
4414  SCIP_SET* set, /**< global SCIP settings */
4415  SCIP_ROW* row, /**< LP row to change the sides for */
4416  SCIP_Real lpiinfinity, /**< value treated as infinity in LP solver */
4417  int** sidechginds, /**< pointer to side change index array */
4418  SCIP_Real** sidechgoldlhss, /**< pointer to side change old left hand sides array */
4419  SCIP_Real** sidechgoldrhss, /**< pointer to side change old right hand sides array */
4420  SCIP_Real** sidechgnewlhss, /**< pointer to side change new left hand sides array */
4421  SCIP_Real** sidechgnewrhss, /**< pointer to side change new right hand sides array */
4422  int* sidechgssize, /**< pointer to size of side change arrays */
4423  int* nsidechgs /**< pointer to number of used slots in side change arrays */
4424  )
4425 {
4426  SCIP_Real lhs;
4427  SCIP_Real rhs;
4428  SCIP_Real constant;
4429 
4430  assert(sidechginds != NULL);
4431  assert(sidechgoldlhss != NULL);
4432  assert(sidechgoldrhss != NULL);
4433  assert(sidechgnewlhss != NULL);
4434  assert(sidechgnewrhss != NULL);
4435  assert(sidechgssize != NULL);
4436  assert(nsidechgs != NULL);
4437 
4438  lhs = SCIProwGetLhs(row);
4439  rhs = SCIProwGetRhs(row);
4440  constant = SCIProwGetConstant(row);
4441  assert(!SCIPsetIsInfinity(set, -lhs) || !SCIPsetIsInfinity(set, rhs));
4442 
4443  /* get memory to store additional side change */
4444  SCIP_CALL( ensureSidechgsSize(set, sidechginds, sidechgoldlhss, sidechgoldrhss, sidechgnewlhss, sidechgnewrhss,
4445  sidechgssize, (*nsidechgs)+1) );
4446  assert(*nsidechgs < *sidechgssize);
4447  assert(*sidechginds != NULL);
4448  assert(*sidechgoldlhss != NULL);
4449  assert(*sidechgoldrhss != NULL);
4450  assert(*sidechgnewlhss != NULL);
4451  assert(*sidechgnewrhss != NULL);
4452 
4453  /* store side change */
4454  (*sidechginds)[*nsidechgs] = SCIProwGetLPPos(row);
4455  if( SCIPsetIsInfinity(set, -lhs) )
4456  {
4457  (*sidechgoldlhss)[*nsidechgs] = -lpiinfinity;
4458  (*sidechgnewlhss)[*nsidechgs] = -lpiinfinity;
4459  }
4460  else
4461  {
4462  (*sidechgoldlhss)[*nsidechgs] = lhs - constant;
4463  (*sidechgnewlhss)[*nsidechgs] = -lpiinfinity/2;
4464  }
4465  if( SCIPsetIsInfinity(set, rhs) )
4466  {
4467  (*sidechgoldrhss)[*nsidechgs] = lpiinfinity;
4468  (*sidechgnewrhss)[*nsidechgs] = lpiinfinity;
4469  }
4470  else
4471  {
4472  (*sidechgoldrhss)[*nsidechgs] = rhs - constant;
4473  (*sidechgnewrhss)[*nsidechgs] = lpiinfinity/2;
4474  }
4475  (*nsidechgs)++;
4476 
4477  return SCIP_OKAY;
4478 }
4479 
4480 /** inserts variable's new bounds into bound change arrays */
4481 static
4483  SCIP_SET* set, /**< global SCIP settings */
4484  SCIP_VAR* var, /**< variable to change the LP bounds for */
4485  SCIP_Real newlb, /**< new lower bound */
4486  SCIP_Real newub, /**< new upper bound */
4487  SCIP_LPBDCHGS* oldlpbdchgs, /**< old LP bound changes used for reset the LP bound change, or NULL */
4488  SCIP_LPBDCHGS* relaxedlpbdchgs /**< relaxed LP bound changes used for reset the LP bound change, or NULL */
4489  )
4490 {
4491  assert(newlb <= newub);
4492  assert(oldlpbdchgs != NULL);
4493  assert(relaxedlpbdchgs != NULL);
4494 
4496  {
4497  SCIP_COL* col;
4498  int idx;
4499  int c;
4500 
4501  col = SCIPvarGetCol(var);
4502  c = SCIPcolGetLPPos(col);
4503 
4504  if( c >= 0 )
4505  {
4506  /* store old bound change for reseting the LP later */
4507  if( !oldlpbdchgs->usedcols[c] )
4508  {
4509  idx = oldlpbdchgs->nbdchgs;
4510  oldlpbdchgs->usedcols[c] = TRUE;
4511  oldlpbdchgs->bdchgcolinds[c] = idx;
4512  oldlpbdchgs->nbdchgs++;
4513 
4514  oldlpbdchgs->bdchginds[idx] = c;
4515  oldlpbdchgs->bdchglbs[idx] = SCIPvarGetLbLP(var, set);
4516  oldlpbdchgs->bdchgubs[idx] = SCIPvarGetUbLP(var, set);
4517  }
4518  assert(oldlpbdchgs->bdchginds[oldlpbdchgs->bdchgcolinds[c]] == c);
4519  assert(oldlpbdchgs->bdchglbs[oldlpbdchgs->bdchgcolinds[c]] == SCIPvarGetLbLP(var, set)); /*lint !e777*/
4520  assert(oldlpbdchgs->bdchgubs[oldlpbdchgs->bdchgcolinds[c]] == SCIPvarGetUbLP(var, set)); /*lint !e777*/
4521 
4522  /* store bound change for conflict analysis */
4523  if( !relaxedlpbdchgs->usedcols[c] )
4524  {
4525  idx = relaxedlpbdchgs->nbdchgs;
4526  relaxedlpbdchgs->usedcols[c] = TRUE;
4527  relaxedlpbdchgs->bdchgcolinds[c] = idx;
4528  relaxedlpbdchgs->nbdchgs++;
4529 
4530  /* remember the positive for later further bound widenings */
4531  relaxedlpbdchgs->bdchginds[idx] = c;
4532  }
4533  else
4534  {
4535  idx = relaxedlpbdchgs->bdchgcolinds[c];
4536  assert(relaxedlpbdchgs->bdchginds[idx] == c);
4537 
4538  /* the new bound should be the same or nore relexed */
4539  assert(relaxedlpbdchgs->bdchglbs[idx] >= newlb);
4540  assert(relaxedlpbdchgs->bdchgubs[idx] <= newub);
4541  }
4542 
4543  /* set the new bounds for the LP */
4544  relaxedlpbdchgs->bdchglbs[idx] = newlb;
4545  relaxedlpbdchgs->bdchgubs[idx] = newub;
4546  }
4547  }
4548 
4549  return SCIP_OKAY;
4550 }
4551 
4552 /** ensures, that candidate array can store at least num entries */
4553 static
4555  SCIP_SET* set, /**< global SCIP settings */
4556  SCIP_VAR*** cands, /**< pointer to candidate array */
4557  SCIP_Real** candscores, /**< pointer to candidate score array */
4558  SCIP_Real** newbounds, /**< pointer to candidate new bounds array */
4559  SCIP_Real** proofactdeltas, /**< pointer to candidate proof delta array */
4560  int* candssize, /**< pointer to size of array */
4561  int num /**< minimal number of candidates to store in array */
4562  )
4563 {
4564  assert(cands != NULL);
4565  assert(candssize != NULL);
4566 
4567  if( num > *candssize )
4568  {
4569  int newsize;
4570 
4571  newsize = SCIPsetCalcMemGrowSize(set, num);
4572  SCIP_CALL( SCIPsetReallocBufferArray(set, cands, newsize) );
4573  SCIP_CALL( SCIPsetReallocBufferArray(set, candscores, newsize) );
4574  SCIP_CALL( SCIPsetReallocBufferArray(set, newbounds, newsize) );
4575  SCIP_CALL( SCIPsetReallocBufferArray(set, proofactdeltas, newsize) );
4576  *candssize = newsize;
4577  }
4578  assert(num <= *candssize);
4579 
4580  return SCIP_OKAY;
4581 }
4582 
4583 /** adds variable to candidate list, if the current best bound corresponding to the proof coefficient is local;
4584  * returns the array position in the candidate list, where the new candidate was inserted, or -1 if the
4585  * variable can relaxed to global bounds immediately without increasing the proof's activity;
4586  * the candidates are sorted with respect to the following two criteria:
4587  * - prefer bound changes that have been applied deeper in the tree, to get a more global conflict
4588  * - prefer variables with small Farkas coefficient to get rid of as many bound changes as possible
4589  */
4590 static
4592  SCIP_SET* set, /**< global SCIP settings */
4593  int currentdepth, /**< current depth in the tree */
4594  SCIP_VAR* var, /**< variable to add to candidate array */
4595  int lbchginfopos, /**< positions of currently active lower bound change information in variable's array */
4596  int ubchginfopos, /**< positions of currently active upper bound change information in variable's array */
4597  SCIP_Real proofcoef, /**< coefficient of variable in infeasibility/bound proof */
4598  SCIP_Real prooflhs, /**< left hand side of infeasibility/bound proof */
4599  SCIP_Real proofact, /**< activity of infeasibility/bound proof row */
4600  SCIP_VAR*** cands, /**< pointer to candidate array for undoing bound changes */
4601  SCIP_Real** candscores, /**< pointer to candidate score array for undoing bound changes */
4602  SCIP_Real** newbounds, /**< pointer to candidate new bounds array for undoing bound changes */
4603  SCIP_Real** proofactdeltas, /**< pointer to proof activity increase array for undoing bound changes */
4604  int* candssize, /**< pointer to size of cands arrays */
4605  int* ncands, /**< pointer to count number of candidates in bound change list */
4606  int firstcand /**< position of first unprocessed bound change candidate */
4607  )
4608 {
4609  SCIP_Real oldbound;
4610  SCIP_Real newbound;
4611  SCIP_Real proofactdelta;
4612  SCIP_Real score;
4613  int depth;
4614  int i;
4615  SCIP_Bool resolvable;
4616 
4617  assert(set != NULL);
4618  assert(var != NULL);
4619  assert(-1 <= lbchginfopos && lbchginfopos <= var->nlbchginfos);
4620  assert(-1 <= ubchginfopos && ubchginfopos <= var->nubchginfos);
4621  assert(!SCIPsetIsZero(set, proofcoef));
4622  assert(SCIPsetIsGT(set, prooflhs, proofact));
4623  assert(cands != NULL);
4624  assert(candscores != NULL);
4625  assert(newbounds != NULL);
4626  assert(proofactdeltas != NULL);
4627  assert(candssize != NULL);
4628  assert(ncands != NULL);
4629  assert(*ncands <= *candssize);
4630  assert(0 <= firstcand && firstcand <= *ncands);
4631 
4632  /* in the infeasibility or dual bound proof, the variable's bound is chosen to maximize the proof's activity */
4633  if( proofcoef > 0.0 )
4634  {
4635  assert(ubchginfopos >= 0); /* otherwise, undoBdchgsProof() should already have relaxed the local bound */
4636 
4637  /* calculate the difference of current bound to the previous bound the variable was set to */
4638  if( ubchginfopos == var->nubchginfos )
4639  {
4640  /* current bound is the strong branching or diving bound */
4641  oldbound = SCIPvarGetUbLP(var, set);
4642  newbound = SCIPvarGetUbLocal(var);
4643  depth = currentdepth+1;
4644  resolvable = FALSE;
4645  }
4646  else
4647  {
4648  /* current bound is the result of a local bound change */
4649  resolvable = bdchginfoIsResolvable(&var->ubchginfos[ubchginfopos]);
4650  depth = var->ubchginfos[ubchginfopos].bdchgidx.depth;
4651  oldbound = var->ubchginfos[ubchginfopos].newbound;
4652  newbound = var->ubchginfos[ubchginfopos].oldbound;
4653  }
4654  }
4655  else
4656  {
4657  assert(lbchginfopos >= 0); /* otherwise, undoBdchgsProof() should already have relaxed the local bound */
4658 
4659  /* calculate the difference of current bound to the previous bound the variable was set to */
4660  if( lbchginfopos == var->nlbchginfos )
4661  {
4662  /* current bound is the strong branching or diving bound */
4663  oldbound = SCIPvarGetLbLP(var, set);
4664  newbound = SCIPvarGetLbLocal(var);
4665  depth = currentdepth+1;
4666  resolvable = FALSE;
4667  }
4668  else
4669  {
4670  /* current bound is the result of a local bound change */
4671  resolvable = bdchginfoIsResolvable(&var->lbchginfos[lbchginfopos]);
4672  depth = var->lbchginfos[lbchginfopos].bdchgidx.depth;
4673  oldbound = var->lbchginfos[lbchginfopos].newbound;
4674  newbound = var->lbchginfos[lbchginfopos].oldbound;
4675  }
4676  }
4677 
4678  /* calculate the increase in the proof's activity */
4679  proofactdelta = (newbound - oldbound)*proofcoef;
4680  assert(proofactdelta > 0.0);
4681 
4682  /* calculate score for undoing the bound change */
4683  score = 1.0 - proofactdelta/(prooflhs - proofact);
4684  score = MAX(score, 0.0);
4685  score += set->conf_depthscorefac * (SCIP_Real)(depth+1)/(SCIP_Real)(currentdepth+1);
4686  if( !resolvable )
4687  {
4688  score += 10.0;
4689  if( !SCIPvarIsBinary(var) )
4690  score += 10.0;
4691  }
4692 
4693  /* get enough memory to store new candidate */
4694  SCIP_CALL( ensureCandsSize(set, cands, candscores, newbounds, proofactdeltas, candssize, (*ncands)+1) );
4695  assert(*cands != NULL);
4696  assert(*candscores != NULL);
4697  assert(*newbounds != NULL);
4698  assert(*proofactdeltas != NULL);
4699 
4700  SCIPdebugMessage(" -> local <%s> %s %g, relax <%s> %s %g, proofcoef=%g, dpt=%d, resolve=%u, delta=%g, score=%g\n",
4701  SCIPvarGetName(var), proofcoef > 0.0 ? "<=" : ">=", oldbound,
4702  SCIPvarGetName(var), proofcoef > 0.0 ? "<=" : ">=", newbound,
4703  proofcoef, depth, resolvable, proofactdelta, score);
4704 
4705  /* insert variable in candidate list without touching the already processed candidates */
4706  for( i = *ncands; i > firstcand && score > (*candscores)[i-1]; --i )
4707  {
4708  (*cands)[i] = (*cands)[i-1];
4709  (*candscores)[i] = (*candscores)[i-1];
4710  (*newbounds)[i] = (*newbounds)[i-1];
4711  (*proofactdeltas)[i] = (*proofactdeltas)[i-1];
4712  }
4713  (*cands)[i] = var;
4714  (*candscores)[i] = score;
4715  (*newbounds)[i] = newbound;
4716  (*proofactdeltas)[i] = proofactdelta;
4717  (*ncands)++;
4718 
4719  return SCIP_OKAY;
4720 }
4721 
4722 /** after changing the global bound of a variable, the bdchginfos that are now redundant are replaced with
4723  * oldbound = newbound = global bound; if the current bdchginfo is of such kind, the bound is equal to the
4724  * global bound and we can ignore it by installing a -1 as the corresponding bound change info position
4725  */
4726 static
4728  SCIP_VAR* var, /**< problem variable */
4729  int* lbchginfopos, /**< pointer to lower bound change information position */
4730  int* ubchginfopos /**< pointer to upper bound change information position */
4731  )
4732 {
4733  assert(var != NULL);
4734  assert(lbchginfopos != NULL);
4735  assert(ubchginfopos != NULL);
4736  assert(-1 <= *lbchginfopos && *lbchginfopos <= var->nlbchginfos);
4737  assert(-1 <= *ubchginfopos && *ubchginfopos <= var->nubchginfos);
4738  assert(*lbchginfopos == -1 || *lbchginfopos == var->nlbchginfos
4739  || var->lbchginfos[*lbchginfopos].redundant
4740  == (var->lbchginfos[*lbchginfopos].oldbound == var->lbchginfos[*lbchginfopos].newbound)); /*lint !e777*/
4741  assert(*ubchginfopos == -1 || *ubchginfopos == var->nubchginfos
4742  || var->ubchginfos[*ubchginfopos].redundant
4743  == (var->ubchginfos[*ubchginfopos].oldbound == var->ubchginfos[*ubchginfopos].newbound)); /*lint !e777*/
4744 
4745  if( *lbchginfopos >= 0 && *lbchginfopos < var->nlbchginfos && var->lbchginfos[*lbchginfopos].redundant )
4746  {
4747  assert(SCIPvarGetLbGlobal(var) == var->lbchginfos[*lbchginfopos].oldbound); /*lint !e777*/
4748  *lbchginfopos = -1;
4749  }
4750  if( *ubchginfopos >= 0 && *ubchginfopos < var->nubchginfos && var->ubchginfos[*ubchginfopos].redundant )
4751  {
4752  assert(SCIPvarGetUbGlobal(var) == var->ubchginfos[*ubchginfopos].oldbound); /*lint !e777*/
4753  *ubchginfopos = -1;
4754  }
4755 }
4756 
4757 /** undoes bound changes on variables, still leaving the given infeasibility proof valid */
4758 static
4760  SCIP_SET* set, /**< global SCIP settings */
4761  SCIP_PROB* prob, /**< problem data */
4762  int currentdepth, /**< current depth in the tree */
4763  SCIP_Real* proofcoefs, /**< coefficients in infeasibility proof */
4764  SCIP_Real prooflhs, /**< left hand side of proof */
4765  SCIP_Real proofact, /**< current activity of proof */
4766  SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
4767  SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
4768  int* lbchginfoposs, /**< positions of currently active lower bound change information in variables' arrays */
4769  int* ubchginfoposs, /**< positions of currently active upper bound change information in variables' arrays */
4770  SCIP_LPBDCHGS* oldlpbdchgs, /**< old LP bound changes used for reset the LP bound change, or NULL */
4771  SCIP_LPBDCHGS* relaxedlpbdchgs, /**< relaxed LP bound changes used for reset the LP bound change, or NULL */
4772  SCIP_Bool* resolve /**< pointer to store whether the changed LP should be resolved again, or NULL */
4773  )
4774 {
4775  SCIP_VAR** vars;
4776  SCIP_VAR** cands;
4777  SCIP_Real* candscores;
4778  SCIP_Real* newbounds;
4779  SCIP_Real* proofactdeltas;
4780  int nvars;
4781  int ncands;
4782  int candssize;
4783  int v;
4784  int i;
4785 
4786  assert(prob != NULL);
4787  assert(proofcoefs != NULL);
4788  assert(SCIPsetIsFeasGT(set, prooflhs, proofact));
4789  assert(curvarlbs != NULL);
4790  assert(curvarubs != NULL);
4791  assert(lbchginfoposs != NULL);
4792  assert(ubchginfoposs != NULL);
4793 
4794  if( resolve != NULL )
4795  *resolve = FALSE;
4796 
4797  vars = prob->vars;
4798  nvars = prob->nvars;
4799  assert(nvars == 0 || vars != NULL);
4800 
4801  /* calculate the order in which the bound changes are tried to be undone, and relax all bounds if this doesn't
4802  * increase the proof's activity
4803  */
4804  SCIP_CALL( SCIPsetAllocBufferArray(set, &cands, nvars) );
4805  SCIP_CALL( SCIPsetAllocBufferArray(set, &candscores, nvars) );
4806  SCIP_CALL( SCIPsetAllocBufferArray(set, &newbounds, nvars) );
4807  SCIP_CALL( SCIPsetAllocBufferArray(set, &proofactdeltas, nvars) );
4808  ncands = 0;
4809  candssize = nvars;
4810  for( v = 0; v < nvars; ++v )
4811  {
4812  SCIP_VAR* var;
4813  SCIP_Bool relaxed;
4814 
4815  var = vars[v];
4816 
4817  /* after changing the global bound of a variable, the bdchginfos that are now redundant are replaced with
4818  * oldbound = newbound = global bound; if the current bdchginfo is of such kind, the bound is equal to the
4819  * global bound and we can ignore it
4820  */
4821  skipRedundantBdchginfos(var, &lbchginfoposs[v], &ubchginfoposs[v]);
4822 
4823  /* ignore variables already relaxed to global bounds */
4824  if( lbchginfoposs[v] == -1 && ubchginfoposs[v] == -1 )
4825  continue;
4826 
4827  /* relax bounds that are not used in the proof to the global bounds */
4828  relaxed = FALSE;
4829  if( !SCIPsetIsNegative(set, proofcoefs[v]) )
4830  {
4831  /* the lower bound is not used */
4832  if( lbchginfoposs[v] >= 0 )
4833  {
4834  SCIPdebugMessage(" -> relaxing variable <%s>[%g,%g] to [%g,%g]: proofcoef=%g, %g <= %g\n",
4835  SCIPvarGetName(var), curvarlbs[v], curvarubs[v], SCIPvarGetLbGlobal(var), curvarubs[v],
4836  proofcoefs[v], prooflhs, proofact);
4837  curvarlbs[v] = SCIPvarGetLbGlobal(var);
4838  lbchginfoposs[v] = -1;
4839  relaxed = TRUE;
4840  }
4841  }
4842  if( !SCIPsetIsPositive(set, proofcoefs[v]) )
4843  {
4844  /* the upper bound is not used */
4845  if( ubchginfoposs[v] >= 0 )
4846  {
4847  SCIPdebugMessage(" -> relaxing variable <%s>[%g,%g] to [%g,%g]: proofcoef=%g, %g <= %g\n",
4848  SCIPvarGetName(var), curvarlbs[v], curvarubs[v], curvarlbs[v], SCIPvarGetUbGlobal(var),
4849  proofcoefs[v], prooflhs, proofact);
4850  curvarubs[v] = SCIPvarGetUbGlobal(var);
4851  ubchginfoposs[v] = -1;
4852  relaxed = TRUE;
4853  }
4854  }
4855  if( relaxed && oldlpbdchgs != NULL )
4856  {
4857  SCIP_CALL( addBdchg(set, var, curvarlbs[v], curvarubs[v], oldlpbdchgs, relaxedlpbdchgs) );
4858  }
4859 
4860  /* add bound to candidate list */
4861  if( lbchginfoposs[v] >= 0 || ubchginfoposs[v] >= 0 )
4862  {
4863  SCIP_CALL( addCand(set, currentdepth, var, lbchginfoposs[v], ubchginfoposs[v], proofcoefs[v],
4864  prooflhs, proofact, &cands, &candscores, &newbounds, &proofactdeltas, &candssize, &ncands, 0) );
4865  }
4866  }
4867 
4868  /* try to undo remaining local bound changes while still keeping the proof row violated:
4869  * bound changes can be undone, if prooflhs > proofact + proofactdelta;
4870  * afterwards, the current proof activity has to be updated
4871  */
4872  for( i = 0; i < ncands; ++i )
4873  {
4874  assert(proofactdeltas[i] > 0.0);
4875  assert((lbchginfoposs[SCIPvarGetProbindex(cands[i])] >= 0) != (ubchginfoposs[SCIPvarGetProbindex(cands[i])] >= 0));
4876 
4877  /* when relaxing a constraint we still need to stay infeasible; therefore we need to do the comparison in
4878  * feasibility tolerance because if 'prooflhs' is (feas-))equal to 'proofact + proofactdeltas[i]' it would mean
4879  * that there is no violation
4880  */
4881  if( SCIPsetIsFeasGT(set, prooflhs, proofact + proofactdeltas[i]) )
4882  {
4883  v = SCIPvarGetProbindex(cands[i]);
4884  assert(0 <= v && v < nvars);
4885  assert((lbchginfoposs[v] >= 0) != (ubchginfoposs[v] >= 0));
4886 
4887  SCIPdebugMessage(" -> relaxing variable <%s>[%g,%g] to [%g,%g]: proofcoef=%g, %g <= %g + %g\n",
4888  SCIPvarGetName(cands[i]), curvarlbs[v], curvarubs[v],
4889  proofcoefs[v] > 0.0 ? curvarlbs[v] : newbounds[i],
4890  proofcoefs[v] > 0.0 ? newbounds[i] : curvarubs[v],
4891  proofcoefs[v], prooflhs, proofact, proofactdeltas[i]);
4892 
4893  assert((SCIPsetIsPositive(set, proofcoefs[v]) && SCIPsetIsGT(set, newbounds[i], curvarubs[v]))
4894  || (SCIPsetIsNegative(set, proofcoefs[v]) && SCIPsetIsLT(set, newbounds[i], curvarlbs[v])));
4895  assert((SCIPsetIsPositive(set, proofcoefs[v])
4896  && SCIPsetIsEQ(set, proofactdeltas[i], (newbounds[i] - curvarubs[v])*proofcoefs[v]))
4897  || (SCIPsetIsNegative(set, proofcoefs[v])
4898  && SCIPsetIsEQ(set, proofactdeltas[i], (newbounds[i] - curvarlbs[v])*proofcoefs[v])));
4899  assert(!SCIPsetIsZero(set, proofcoefs[v]));
4900 
4901  if( proofcoefs[v] > 0.0 )
4902  {
4903  assert(ubchginfoposs[v] >= 0);
4904  assert(lbchginfoposs[v] == -1);
4905  curvarubs[v] = newbounds[i];
4906  ubchginfoposs[v]--;
4907  }
4908  else
4909  {
4910  assert(lbchginfoposs[v] >= 0);
4911  assert(ubchginfoposs[v] == -1);
4912  curvarlbs[v] = newbounds[i];
4913  lbchginfoposs[v]--;
4914  }
4915  if( oldlpbdchgs != NULL )
4916  {
4917  SCIP_CALL( addBdchg(set, cands[i], curvarlbs[v], curvarubs[v], oldlpbdchgs, relaxedlpbdchgs) );
4918  }
4919  proofact += proofactdeltas[i];
4920  if( resolve != NULL && SCIPvarIsInLP(cands[i]) )
4921  *resolve = TRUE;
4922 
4923  /* after changing the global bound of a variable, the bdchginfos that are now redundant are replaced with
4924  * oldbound = newbound = global bound; if the current bdchginfo is of such kind, the bound is equal to the
4925  * global bound and we can ignore it
4926  */
4927  skipRedundantBdchginfos(cands[i], &lbchginfoposs[v], &ubchginfoposs[v]);
4928 
4929  /* insert the new local bound of the variable into the candidate list */
4930  if( lbchginfoposs[v] >= 0 || ubchginfoposs[v] >= 0 )
4931  {
4932  SCIP_CALL( addCand(set, currentdepth, cands[i], lbchginfoposs[v], ubchginfoposs[v], proofcoefs[v],
4933  prooflhs, proofact, &cands, &candscores, &newbounds, &proofactdeltas, &candssize, &ncands, i+1) );
4934  }
4935  }
4936  }
4937 
4938  /* free the buffer for the sorted bound change candidates */
4939  SCIPsetFreeBufferArray(set, &proofactdeltas);
4940  SCIPsetFreeBufferArray(set, &newbounds);
4941  SCIPsetFreeBufferArray(set, &candscores);
4942  SCIPsetFreeBufferArray(set, &cands);
4943 
4944  return SCIP_OKAY;
4945 }
4946 
4947 /* because calculations might cancel out some values, we stop the infeasibility analysis if a value is bigger than
4948  * 2^53 = 9007199254740992
4949  */
4950 #define NUMSTOP 9007199254740992.0
4951 
4952 /** analyzes an infeasible LP and undoes additional bound changes while staying infeasible */
4953 static
4955  SCIP_SET* set, /**< global SCIP settings */
4956  SCIP_PROB* prob, /**< problem data */
4957  SCIP_LP* lp, /**< LP data */
4958  int currentdepth, /**< current depth in the tree */
4959  SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
4960  SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
4961  int* lbchginfoposs, /**< positions of currently active lower bound change information in variables' arrays */
4962  int* ubchginfoposs, /**< positions of currently active upper bound change information in variables' arrays */
4963  SCIP_LPBDCHGS* oldlpbdchgs, /**< old LP bound changes used for reset the LP bound change, or NULL */
4964  SCIP_LPBDCHGS* relaxedlpbdchgs, /**< relaxed LP bound changes used for reset the LP bound change, or NULL */
4965  SCIP_Bool* valid, /**< pointer to store whether the unfixings are valid */
4966  SCIP_Bool* resolve /**< pointer to store whether the changed LP should be resolved again */
4967  )
4968 {
4969  SCIP_RETCODE retcode;
4970  SCIP_LPI* lpi;
4971  SCIP_ROW** rows;
4972  SCIP_VAR** vars;
4973  SCIP_ROW* row;
4974  SCIP_VAR* var;
4975  SCIP_Real* dualfarkas;
4976  SCIP_Real* farkascoefs;
4977  SCIP_Real farkaslhs;
4978  SCIP_Real farkasact;
4979  int nrows;
4980  int nvars;
4981  int r;
4982  int v;
4983  int i;
4984 
4985  assert(prob != NULL);
4986  assert(lp != NULL);
4987  assert(lp->flushed);
4988  assert(lp->solved);
4989  assert(curvarlbs != NULL);
4990  assert(curvarubs != NULL);
4991  assert(lbchginfoposs != NULL);
4992  assert(ubchginfoposs != NULL);
4993  assert(valid != NULL);
4994  assert(resolve != NULL);
4995 
4996  SCIPdebugMessage("undoing bound changes in infeasible LP: cutoff=%g\n", lp->cutoffbound);
4997 
4998  *valid = FALSE;
4999  *resolve = FALSE;
5000 
5001  /* get LP solver interface */
5002  lpi = SCIPlpGetLPI(lp);
5003 
5004  /* get LP rows and problem variables */
5005  rows = SCIPlpGetRows(lp);
5006  nrows = SCIPlpGetNRows(lp);
5007  vars = prob->vars;
5008  nvars = prob->nvars;
5009  assert(nrows == 0 || rows != NULL);
5010  assert(nrows == lp->nlpirows);
5011 
5012  /* allocate temporary memory */
5013  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualfarkas, nrows) );
5014  SCIP_CALL( SCIPsetAllocBufferArray(set, &farkascoefs, nvars) );
5015 
5016  /* if solve for some reason did not produce a dual ray, e.g. because of numerical instabilities, abort conflict analysis */
5017  if( ! SCIPlpiHasDualRay(lpi) )
5018  goto TERMINATE;
5019 
5020  /* get dual Farkas values of rows */
5021  retcode = SCIPlpiGetDualfarkas(lpi, dualfarkas);
5022  if( retcode == SCIP_LPERROR ) /* on an error in the LP solver, just abort the conflict analysis */
5023  goto TERMINATE;
5024  SCIP_CALL( retcode );
5025 
5026  /* calculate the Farkas row */
5027  BMSclearMemoryArray(farkascoefs, nvars);
5028  farkaslhs = 0.0;
5029  for( r = 0; r < nrows; ++r )
5030  {
5031  row = rows[r];
5032  assert(row != NULL);
5033  assert(row->len == 0 || row->cols != NULL);
5034  assert(row->len == 0 || row->vals != NULL);
5035  assert(row == lp->lpirows[r]);
5036 
5037  /* ignore local rows and rows with Farkas value 0.0 */
5038  if( !row->local && !SCIPsetIsZero(set, dualfarkas[r]) )
5039  {
5040 #ifndef NDEBUG
5041  {
5042  SCIP_Real lpilhs;
5043  SCIP_Real lpirhs;
5044 
5045  SCIP_CALL( SCIPlpiGetSides(lpi, r, r, &lpilhs, &lpirhs) );
5046  assert((SCIPsetIsInfinity(set, -lpilhs) && SCIPsetIsInfinity(set, -row->lhs))
5047  || SCIPsetIsRelEQ(set, lpilhs, row->lhs - row->constant));
5048  assert((SCIPsetIsInfinity(set, lpirhs) && SCIPsetIsInfinity(set, row->rhs))
5049  || SCIPsetIsRelEQ(set, lpirhs, row->rhs - row->constant));
5050  }
5051 #endif
5052 
5053  /* add row side to Farkas row lhs: dualfarkas > 0 -> lhs, dualfarkas < 0 -> rhs */
5054  if( dualfarkas[r] > 0.0 )
5055  {
5056  /* check if sign of dual Farkas value is valid */
5057  if( SCIPsetIsInfinity(set, -row->lhs) )
5058  continue;
5059 
5060  /* due to numerical reasons we want to stop */
5061  if( REALABS(dualfarkas[r] * (row->lhs - row->constant)) > NUMSTOP )
5062  goto TERMINATE;
5063 
5064  farkaslhs += dualfarkas[r] * (row->lhs - row->constant);
5065  }
5066  else
5067  {
5068  /* check if sign of dual Farkas value is valid */
5069  if( SCIPsetIsInfinity(set, row->rhs) )
5070  continue;
5071 
5072  /* due to numerical reasons we want to stop */
5073  if( REALABS(dualfarkas[r] * (row->rhs - row->constant)) > NUMSTOP )
5074  goto TERMINATE;
5075 
5076  farkaslhs += dualfarkas[r] * (row->rhs - row->constant);
5077  }
5078  SCIPdebugMessage(" -> farkaslhs: %g<%s>[%g,%g] -> %g\n", dualfarkas[r], SCIProwGetName(row),
5079  row->lhs - row->constant, row->rhs - row->constant, farkaslhs);
5080 
5081  /* due to numerical reasons we want to stop */
5082  if( REALABS(farkaslhs) > NUMSTOP )
5083  goto TERMINATE;
5084 
5085  /* add row coefficients to Farkas row */
5086  for( i = 0; i < row->len; ++i )
5087  {
5088  v = SCIPvarGetProbindex(SCIPcolGetVar(row->cols[i]));
5089  assert(0 <= v && v < nvars);
5090  farkascoefs[v] += dualfarkas[r] * row->vals[i];
5091  }
5092  }
5093 #ifdef SCIP_DEBUG
5094  else if( !SCIPsetIsZero(set, dualfarkas[r]) )
5095  {
5096  SCIPdebugMessage(" -> ignoring %s row <%s> with dual Farkas value %.10f (lhs=%g, rhs=%g)\n",
5097  row->local ? "local" : "global", SCIProwGetName(row), dualfarkas[r],
5098  row->lhs - row->constant, row->rhs - row->constant);
5099  }
5100 #endif
5101  }
5102 
5103  /* calculate the current Farkas activity, always using the best bound w.r.t. the Farkas coefficient */
5104  farkasact = 0.0;
5105  for( v = 0; v < nvars; ++v )
5106  {
5107  var = vars[v];
5108  assert(SCIPvarGetProbindex(var) == v);
5109 
5110  /* ignore coefficients close to 0.0 */
5111  if( SCIPsetIsZero(set, farkascoefs[v]) )
5112  farkascoefs[v] = 0.0;
5113  else if( farkascoefs[v] > 0.0 )
5114  {
5116  || !SCIPsetIsPositive(set, SCIPvarGetUbLP(var, set)));
5117  if( SCIPsetIsInfinity(set, curvarubs[v]) )
5118  goto TERMINATE;
5119  farkasact += farkascoefs[v] * curvarubs[v];
5120  SCIPdebugMessage(" -> farkasact: %g<%s>[%g,%g] -> %g\n", farkascoefs[v], SCIPvarGetName(var),
5121  curvarlbs[v], curvarubs[v], farkasact);
5122  }
5123  else
5124  {
5126  || !SCIPsetIsNegative(set, SCIPvarGetLbLP(var, set)));
5127  if( SCIPsetIsInfinity(set, -curvarlbs[v]) )
5128  goto TERMINATE;
5129  farkasact += farkascoefs[v] * curvarlbs[v];
5130  SCIPdebugMessage(" -> farkasact: %g<%s>[%g,%g] -> %g\n", farkascoefs[v], SCIPvarGetName(var),
5131  curvarlbs[v], curvarubs[v], farkasact);
5132  }
5133  }
5134  SCIPdebugMessage(" -> farkaslhs=%g, farkasact=%g\n", farkaslhs, farkasact);
5135 
5136  /* check, if the Farkas row is still violated (using current bounds and ignoring local rows) */
5137  if( SCIPsetIsFeasGT(set, farkaslhs, farkasact) )
5138  {
5139  /* undo bound changes while keeping the infeasibility proof valid */
5140  SCIP_CALL( undoBdchgsProof(set, prob, currentdepth, farkascoefs, farkaslhs, farkasact,
5141  curvarlbs, curvarubs, lbchginfoposs, ubchginfoposs, oldlpbdchgs, relaxedlpbdchgs, resolve) );
5142 
5143  *valid = TRUE;
5144 
5145  /* resolving does not make sense: the old dual ray is still valid -> resolving will not change the solution */
5146  *resolve = FALSE;
5147  }
5148 
5149  TERMINATE:
5150 
5151  /* free temporary memory */
5152  SCIPsetFreeBufferArray(set, &farkascoefs);
5153  SCIPsetFreeBufferArray(set, &dualfarkas);
5154 
5155  return SCIP_OKAY;
5156 }
5157 
5158 /** analyzes an LP exceeding the objective limit and undoes additional bound changes while staying beyond the
5159  * objective limit
5160  */
5161 static
5163  SCIP_SET* set, /**< global SCIP settings */
5164  SCIP_PROB* prob, /**< problem data */
5165  SCIP_LP* lp, /**< LP data */
5166  int currentdepth, /**< current depth in the tree */
5167  SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
5168  SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
5169  int* lbchginfoposs, /**< positions of currently active lower bound change information in variables' arrays */
5170  int* ubchginfoposs, /**< positions of currently active upper bound change information in variables' arrays */
5171  SCIP_LPBDCHGS* oldlpbdchgs, /**< old LP bound changes used for reset the LP bound change, or NULL */
5172  SCIP_LPBDCHGS* relaxedlpbdchgs, /**< relaxed LP bound changes used for reset the LP bound change, or NULL */
5173  SCIP_Bool* valid, /**< pointer to store whether the unfixings are valid */
5174  SCIP_Bool* resolve /**< pointer to store whether the changed LP should be resolved again */
5175  )
5176 {
5177  SCIP_RETCODE retcode;
5178  SCIP_LPI* lpi;
5179  SCIP_ROW** rows;
5180  SCIP_VAR** vars;
5181  SCIP_ROW* row;
5182  SCIP_VAR* var;
5183  SCIP_Real* primsols;
5184  SCIP_Real* dualsols;
5185  SCIP_Real* redcosts;
5186  SCIP_Real* dualcoefs;
5187  SCIP_Real* varredcosts;
5188  SCIP_Real duallhs;
5189  SCIP_Real dualact;
5190  int nrows;
5191  int ncols;
5192  int nvars;
5193  int r;
5194  int v;
5195  int i;
5196 
5197  assert(set != NULL);
5198  assert(prob != NULL);
5199  assert(lp != NULL);
5200  assert(lp->flushed);
5201  assert(lp->solved);
5202  assert(curvarlbs != NULL);
5203  assert(curvarubs != NULL);
5204  assert(lbchginfoposs != NULL);
5205  assert(ubchginfoposs != NULL);
5206  assert(valid != NULL);
5207  assert(resolve != NULL);
5208 
5209  *valid = FALSE;
5210  *resolve = FALSE;
5211 
5212  SCIPdebugMessage("undoing bound changes in LP exceeding cutoff: cutoff=%g\n", lp->cutoffbound);
5213 
5214  /* get LP solver interface */
5215  lpi = SCIPlpGetLPI(lp);
5216 
5217  /* get LP rows and problem variables */
5218  rows = SCIPlpGetRows(lp);
5219  nrows = SCIPlpGetNRows(lp);
5220  ncols = SCIPlpGetNCols(lp);
5221  vars = prob->vars;
5222  nvars = prob->nvars;
5223  assert(nrows == 0 || rows != NULL);
5224  assert(nrows == lp->nlpirows);
5225 
5226  /* get temporary memory */
5227  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsols, ncols) );
5228  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualsols, nrows) );
5229  SCIP_CALL( SCIPsetAllocBufferArray(set, &redcosts, ncols) );
5230  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualcoefs, nvars) );
5231  SCIP_CALL( SCIPsetAllocBufferArray(set, &varredcosts, nvars) );
5232 
5233  /* get solution from LPI */
5234  retcode = SCIPlpiGetSol(lpi, NULL, primsols, dualsols, NULL, redcosts);
5235  if( retcode == SCIP_LPERROR ) /* on an error in the LP solver, just abort the conflict analysis */
5236  goto TERMINATE;
5237  SCIP_CALL( retcode );
5238 #ifdef SCIP_DEBUG
5239  {
5240  SCIP_Real objval;
5241  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
5242  SCIPdebugMessage(" -> LP objval: %g\n", objval);
5243  }
5244 #endif
5245 
5246  /* Let y be the dual solution and r be the reduced cost vector. Let z be defined as
5247  * z_i := y_i if i is a global row,
5248  * z_i := 0 if i is a local row.
5249  * Define the set X := {x | lhs <= Ax <= rhs, lb <= x <= ub, c^Tx <= c*}, with c* being the current primal bound.
5250  * Then the following inequalities are valid for all x \in X:
5251  * - c* <= -c^Tx
5252  * <=> z^TAx - c* <= (z^TA - c^T) x
5253  * <=> z^TAx - c* <= (y^TA - c^T - (y-z)^TA) x
5254  * <=> z^TAx - c* <= (-r^T - (y-z)^TA) x (dual feasibility of (y,r): y^TA + r^T == c^T)
5255  * Because lhs <= Ax <= rhs and lb <= x <= ub, the inequality can be relaxed to give
5256  * min{z^Tq | lhs <= q <= rhs} - c* <= max{(-r^T - (y-z)^TA) x | lb <= x <= ub}, or X = {}.
5257  *
5258  * The resulting dual row is: z^T{lhs,rhs} - c* <= (-r^T - (y-z)^TA){lb,ub},
5259  * where lhs, rhs, lb, and ub are selected in order to maximize the feasibility of the row.
5260  */
5261 
5262  BMSclearMemoryArray(dualcoefs, nvars);
5263 
5264  /* use a slightly tighter cutoff bound, because solutions with equal objective value should also be declared
5265  * infeasible
5266  */
5267  duallhs = -(lp->cutoffbound - SCIPsetSumepsilon(set));
5268  dualact = 0.0;
5269 
5270  /* dual row: z^T{lhs,rhs} - c* <= (-r^T - (y-z)^TA){lb,ub}
5271  * 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
5272  */
5273  for( r = 0; r < nrows; ++r )
5274  {
5275  row = rows[r];
5276  assert(row != NULL);
5277  assert(row->len == 0 || row->cols != NULL);
5278  assert(row->len == 0 || row->vals != NULL);
5279  assert(row == lp->lpirows[r]);
5280 
5281  /* ignore dual solution values of 0.0 (in this case: y_i == z_i == 0) */
5282  if( SCIPsetIsZero(set, dualsols[r]) )
5283  continue;
5284 
5285  /* check dual feasibility */
5286  if( (SCIPsetIsInfinity(set, -row->lhs) && dualsols[r] > 0.0) || (SCIPsetIsInfinity(set, row->rhs) && dualsols[r] < 0.0) )
5287  {
5288  SCIPdebugMessage(" -> infeasible dual solution %g in row <%s>: lhs=%g, rhs=%g\n",
5289  dualsols[r], SCIProwGetName(row), row->lhs, row->rhs);
5290  goto TERMINATE;
5291  }
5292 
5293  /* local rows add up to the dual row's coefficients (because z_i == 0 => -(y_i - z_i) == -y_i),
5294  * global rows add up to the dual row's left hand side (because z_i == y_i != 0)
5295  */
5296  if( row->local )
5297  {
5298  /* add -y_i A_i to coefficients of dual row */
5299  for( i = 0; i < row->len; ++i )
5300  {
5301  v = SCIPvarGetProbindex(SCIPcolGetVar(row->cols[i]));
5302  assert(0 <= v && v < nvars);
5303  dualcoefs[v] -= dualsols[r] * row->vals[i];
5304  }
5305  SCIPdebugMessage(" -> local row <%s>: dual=%g\n", SCIProwGetName(row), dualsols[r]);
5306  }
5307  else
5308  {
5309  /* add minimal value to dual row's left hand side: z_i == y_i > 0 -> lhs, z_i == y_i < 0 -> rhs */
5310  if( dualsols[r] > 0.0 )
5311  {
5312  assert(!SCIPsetIsInfinity(set, -row->lhs));
5313  duallhs += dualsols[r] * (row->lhs - row->constant);
5314  }
5315  else
5316  {
5317  assert(!SCIPsetIsInfinity(set, row->rhs));
5318  duallhs += dualsols[r] * (row->rhs - row->constant);
5319  }
5320  SCIPdebugMessage(" -> global row <%s>[%g,%g]: dual=%g -> duallhs=%g\n",
5321  SCIProwGetName(row), row->lhs - row->constant, row->rhs - row->constant, dualsols[r], duallhs);
5322  }
5323  }
5324 
5325  /* dual row: z^T{lhs,rhs} - c* <= (-r^T - (y-z)^TA){lb,ub}
5326  * process variables: subtract reduced costs from dual row's coefficients, and calculate current maximal dual
5327  * activity by multiplying the resultant coefficient with lb or ub
5328  */
5329  for( v = 0; v < nvars; ++v )
5330  {
5331  var = vars[v];
5332  assert(SCIPvarGetProbindex(var) == v);
5333 
5335  {
5336  /* reduced costs for loose variables are equal to the objective value */
5337  varredcosts[v] = SCIPvarGetObj(var);
5338  }
5339  else
5340  {
5341  SCIP_COL* col;
5342  int c;
5343 
5344  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN);
5345  col = SCIPvarGetCol(var);
5346  c = SCIPcolGetLPPos(col);
5347  assert(c == -1 || col == lp->cols[c]);
5348  assert(c == -1 || col == lp->lpicols[c]);
5349 
5350  /* get reduced costs from LPI, or calculate it manually if the column is not in current LP */
5351  varredcosts[v] = (c >= 0 ? redcosts[c] : SCIPcolCalcRedcost(col, dualsols));
5352 
5353  /* check dual feasibility */
5354  if( (SCIPsetIsGT(set, primsols[c], curvarlbs[v]) && SCIPsetIsDualfeasPositive(set, varredcosts[v]))
5355  || (SCIPsetIsLT(set, primsols[c], curvarubs[v]) && SCIPsetIsDualfeasNegative(set, varredcosts[v])) )
5356  {
5357  SCIPdebugMessage(" -> infeasible reduced costs %g in var <%s>: lb=%g, ub=%g\n",
5358  varredcosts[v], SCIPvarGetName(var), curvarlbs[v], curvarubs[v]);
5359  goto TERMINATE;
5360  }
5361  }
5362 
5363  /* subtract reduced costs from dual row's coefficients */
5364  dualcoefs[v] -= varredcosts[v];
5365 
5366  /* add maximal value to dual row's activity: dualcoef > 0 -> ub, dualcoef < 0 -> lb */
5367  if( dualcoefs[v] > 0.0 )
5368  {
5369  if( SCIPsetIsInfinity(set, curvarubs[v]) )
5370  goto TERMINATE;
5371  dualact += dualcoefs[v] * curvarubs[v];
5372  }
5373  else
5374  {
5375  if( SCIPsetIsInfinity(set, -curvarlbs[v]) )
5376  goto TERMINATE;
5377  dualact += dualcoefs[v] * curvarlbs[v];
5378  }
5379  }
5380  SCIPdebugMessage(" -> final dual values: lhs=%g, act=%g\n", duallhs, dualact);
5381 
5382  /* check, if the dual row is still violated (using current bounds and ignoring local rows) */
5383  if( SCIPsetIsFeasGT(set, duallhs, dualact) )
5384  {
5385  /* undo bound changes while keeping the infeasibility proof valid */
5386  SCIP_CALL( undoBdchgsProof(set, prob, currentdepth, dualcoefs, duallhs, dualact,
5387  curvarlbs, curvarubs, lbchginfoposs, ubchginfoposs, oldlpbdchgs, relaxedlpbdchgs, resolve) );
5388 
5389  *valid = TRUE;
5390  }
5391 
5392  TERMINATE:
5393 
5394  /* free temporary memory */
5395  SCIPsetFreeBufferArray(set, &varredcosts);
5396  SCIPsetFreeBufferArray(set, &dualcoefs);
5397  SCIPsetFreeBufferArray(set, &redcosts);
5398  SCIPsetFreeBufferArray(set, &dualsols);
5399  SCIPsetFreeBufferArray(set, &primsols);
5400 
5401  return SCIP_OKAY;
5402 }
5403 
5404 /** applies conflict analysis starting with given bound changes, that could not be undone during previous
5405  * infeasibility analysis
5406  */
5407 static
5409  SCIP_CONFLICT* conflict, /**< conflict analysis data */
5410  BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
5411  SCIP_SET* set, /**< global SCIP settings */
5412  SCIP_STAT* stat, /**< problem statistics */
5413  SCIP_PROB* prob, /**< problem data */
5414  SCIP_TREE* tree, /**< branch and bound tree */
5415  SCIP_Bool diving, /**< are we in strong branching or diving mode? */
5416  int* lbchginfoposs, /**< positions of currently active lower bound change information in variables' arrays */
5417  int* ubchginfoposs, /**< positions of currently active upper bound change information in variables' arrays */
5418  int* nconss, /**< pointer to store the number of generated conflict constraints */
5419  int* nliterals, /**< pointer to store the number of literals in generated conflict constraints */
5420  int* nreconvconss, /**< pointer to store the number of generated reconvergence constraints */
5421  int* nreconvliterals /**< pointer to store the number of literals generated reconvergence constraints */
5422  )
5423 {
5424  SCIP_VAR** vars;
5425  SCIP_VAR* var;
5426  int nvars;
5427  int v;
5428  int nbdchgs;
5429  int maxsize;
5430 
5431  assert(prob != NULL);
5432  assert(lbchginfoposs != NULL);
5433  assert(ubchginfoposs != NULL);
5434  assert(nconss != NULL);
5435  assert(nliterals != NULL);
5436  assert(nreconvconss != NULL);
5437  assert(nreconvliterals != NULL);
5438 
5439  *nconss = 0;
5440  *nliterals = 0;
5441  *nreconvconss = 0;
5442  *nreconvliterals = 0;
5443 
5444  vars = prob->vars;
5445  nvars = prob->nvars;
5446  assert(nvars == 0 || vars != NULL);
5447 
5448  maxsize = 2*conflictCalcMaxsize(set, prob);
5449 
5450  /* initialize conflict data */
5451  SCIP_CALL( SCIPconflictInit(conflict, set, stat, prob) );
5452 
5453  /* add remaining bound changes to conflict queue */
5454  SCIPdebugMessage("initial conflict set after undoing bound changes:\n");
5455  nbdchgs = 0;
5456  for( v = 0; v < nvars && nbdchgs < maxsize; ++v )
5457  {
5458  var = vars[v];
5459  assert(var != NULL);
5460  assert(var->nlbchginfos >= 0);
5461  assert(var->nubchginfos >= 0);
5462  assert(-1 <= lbchginfoposs[v] && lbchginfoposs[v] <= var->nlbchginfos);
5463  assert(-1 <= ubchginfoposs[v] && ubchginfoposs[v] <= var->nubchginfos);
5464 
5465  if( lbchginfoposs[v] == var->nlbchginfos || ubchginfoposs[v] == var->nubchginfos )
5466  {
5467  SCIP_BDCHGINFO* bdchginfo;
5468  SCIP_Real relaxedbd;
5469 
5470  /* the strong branching or diving bound stored in the column is responsible for the conflict:
5471  * it cannot be resolved and therefore has to be directly put into the conflict set
5472  */
5473  assert((lbchginfoposs[v] == var->nlbchginfos) != (ubchginfoposs[v] == var->nubchginfos)); /* only one can be tight in the dual! */
5474  assert(lbchginfoposs[v] < var->nlbchginfos || SCIPvarGetLbLP(var, set) > SCIPvarGetLbLocal(var));
5475  assert(ubchginfoposs[v] < var->nubchginfos || SCIPvarGetUbLP(var, set) < SCIPvarGetUbLocal(var));
5476 
5477  /* create an artificial bound change information for the diving/strong branching bound change;
5478  * they are freed in the SCIPconflictFlushConss() call
5479  */
5480  if( lbchginfoposs[v] == var->nlbchginfos )
5481  {
5482  SCIP_CALL( conflictCreateTmpBdchginfo(conflict, blkmem, set, var, SCIP_BOUNDTYPE_LOWER,
5483  SCIPvarGetLbLocal(var), SCIPvarGetLbLP(var, set), &bdchginfo) );
5484  relaxedbd = SCIPvarGetLbLP(var, set);
5485  }
5486  else
5487  {
5488  SCIP_CALL( conflictCreateTmpBdchginfo(conflict, blkmem, set, var, SCIP_BOUNDTYPE_UPPER,
5489  SCIPvarGetUbLocal(var), SCIPvarGetUbLP(var, set), &bdchginfo) );
5490  relaxedbd = SCIPvarGetUbLP(var, set);
5491  }
5492 
5493  /* put variable into the conflict set */
5494  SCIPdebugMessage(" force: <%s> %s %g [status: %d, type: %d, dive/strong]\n",
5495  SCIPvarGetName(var), lbchginfoposs[v] == var->nlbchginfos ? ">=" : "<=",
5496  lbchginfoposs[v] == var->nlbchginfos ? SCIPvarGetLbLP(var, set) : SCIPvarGetUbLP(var, set),
5497  SCIPvarGetStatus(var), SCIPvarGetType(var));
5498  SCIP_CALL( conflictAddConflictBound(conflict, blkmem, set, bdchginfo, relaxedbd) );
5499 
5500  /* each variable which is add to the conflict graph gets an increase in the VSIDS
5501  *
5502  * @note That is different to the VSIDS preseted in the literature
5503  */
5504  SCIP_CALL( incVSIDS(var, blkmem, set, stat, SCIPbdchginfoGetBoundtype(bdchginfo), relaxedbd, set->conf_conflictgraphweight) );
5505  nbdchgs++;
5506  }
5507  else
5508  {
5509  /* put remaining bound changes into conflict candidate queue */
5510  if( lbchginfoposs[v] >= 0 )
5511  {
5512  SCIP_CALL( conflictAddBound(conflict, blkmem, set, stat, var, SCIP_BOUNDTYPE_LOWER, &var->lbchginfos[lbchginfoposs[v]], SCIPbdchginfoGetNewbound(&var->lbchginfos[lbchginfoposs[v]])) );
5513  nbdchgs++;
5514  }
5515  if( ubchginfoposs[v] >= 0 )
5516  {
5517  assert(!SCIPbdchginfoIsRedundant(&var->ubchginfos[ubchginfoposs[v]]));
5518  SCIP_CALL( conflictAddBound(conflict, blkmem, set, stat, var, SCIP_BOUNDTYPE_UPPER, &var->ubchginfos[ubchginfoposs[v]], SCIPbdchginfoGetNewbound(&var->ubchginfos[ubchginfoposs[v]])) );
5519  nbdchgs++;
5520  }
5521  }
5522  }
5523 
5524  if( v == nvars )
5525  {
5526  /* analyze the conflict set, and create conflict constraints on success */
5527  SCIP_CALL( conflictAnalyze(conflict, blkmem, set, stat, prob, tree, diving, 0, FALSE,
5528  nconss, nliterals, nreconvconss, nreconvliterals) );
5529  }
5530 
5531  return SCIP_OKAY;
5532 }
5533 
5534 /** actually performs analysis of infeasible LP */
5535 static
5537  SCIP_CONFLICT* conflict, /**< conflict analysis data */
5538  BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
5539  SCIP_SET* set, /**< global SCIP settings */
5540  SCIP_STAT* stat, /**< problem statistics */
5541  SCIP_PROB* transprob, /**< transformed problem */
5542  SCIP_PROB* origprob, /**< original problem */
5543  SCIP_TREE* tree, /**< branch and bound tree */
5544  SCIP_LP* lp, /**< LP data */
5545  SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
5546  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5547  SCIP_Bool diving, /**< are we in strong branching or diving mode? */
5548  int* iterations, /**< pointer to store the total number of LP iterations used */
5549  int* nconss, /**< pointer to store the number of generated conflict constraints */
5550  int* nliterals, /**< pointer to store the number of literals in generated conflict constraints */
5551  int* nreconvconss, /**< pointer to store the number of generated reconvergence constraints */
5552  int* nreconvliterals, /**< pointer to store the number of literals generated reconvergence constraints */
5553  SCIP_Bool marklpunsolved /**< whether LP should be marked unsolved after analysis (needed for strong branching) */
5554  )
5555 {
5556  SCIP_LPBDCHGS* oldlpbdchgs;
5557  SCIP_LPBDCHGS* relaxedlpbdchgs;
5558  SCIP_LPI* lpi;
5559  SCIP_VAR** vars;
5560  SCIP_Real* curvarlbs;
5561  SCIP_Real* curvarubs;
5562  int* lbchginfoposs;
5563  int* ubchginfoposs;
5564  SCIP_Bool resolve;
5565  SCIP_Bool solvelp;
5566  SCIP_Bool valid;
5567  int ncols;
5568  int nvars;
5569  int v;
5570 
5571  assert(conflict != NULL);
5572  assert(conflict->nconflictsets == 0);
5573  assert(set != NULL);
5574  assert(SCIPprobAllColsInLP(transprob, set, lp)); /* LP conflict analysis is only valid, if all variables are known */
5575  assert(stat != NULL);
5576  assert(transprob != NULL);
5577  assert(lp != NULL);
5578  assert(lp->flushed);
5579  assert(lp->solved);
5580  assert(iterations != NULL);
5581  assert(nconss != NULL);
5582  assert(nliterals != NULL);
5583  assert(nreconvconss != NULL);
5584  assert(nreconvliterals != NULL);
5585 
5586  *iterations = 0;
5587  *nconss = 0;
5588  *nliterals = 0;
5589  *nreconvconss = 0;
5590  *nreconvliterals = 0;
5591 
5592  /* get LP solver interface */
5593  lpi = SCIPlpGetLPI(lp);
5596 
5597  if( !SCIPlpiIsPrimalInfeasible(lpi) )
5598  {
5599  SCIP_Real objval;
5600 
5601  assert(!SCIPlpDivingObjChanged(lp));
5602 
5603  /* make sure, a dual feasible solution exists, that exceeds the objective limit;
5604  * With FASTMIP setting, CPLEX does not apply the final pivot to reach the dual solution exceeding the objective
5605  * limit. Therefore, we have to either turn off FASTMIP and resolve the problem or continue solving it without
5606  * objective limit for at least one iteration. It seems that the strategy to continue with FASTMIP for one
5607  * additional simplex iteration yields better results.
5608  */
5609  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
5610  if( objval < lp->lpiuobjlim )
5611  {
5612  SCIP_RETCODE retcode;
5613 
5614  /* temporarily disable objective limit and install an iteration limit */
5617 
5618  /* start LP timer */
5619  SCIPclockStart(stat->conflictlptime, set);
5620 
5621  /* resolve LP */
5622  retcode = SCIPlpiSolveDual(lpi);
5623 
5624  /* stop LP timer */
5625  SCIPclockStop(stat->conflictlptime, set);
5626 
5627  /* check return code of LP solving call */
5628  valid = (retcode != SCIP_LPERROR);
5629  if( valid )
5630  {
5631  int iter;
5632 
5633  SCIP_CALL( retcode );
5634 
5635  /* count number of LP iterations */
5636  SCIP_CALL( SCIPlpiGetIterations(lpi, &iter) );
5637  (*iterations) += iter;
5638  stat->nconflictlps++;
5639  stat->nconflictlpiterations += iter;
5640  SCIPdebugMessage(" -> resolved objlim exceeding LP in %d iterations (total: %"SCIP_LONGINT_FORMAT") (infeasible:%u, objlim: %u, optimal:%u)\n",
5642  SCIPlpiIsOptimal(lpi));
5644  }
5645 
5646  /* reinstall old objective and iteration limits in LP solver */
5649 
5650  /* abort, if the LP produced an error */
5651  if( !valid )
5652  return SCIP_OKAY;
5653  }
5654  }
5656 
5657  if( !SCIPlpiIsPrimalInfeasible(lpi) )
5658  {
5659  SCIP_Real objval;
5660 
5661  assert(!SCIPlpDivingObjChanged(lp));
5662 
5663  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
5664  if( objval < lp->lpiuobjlim )
5665  {
5666  SCIPdebugMessage(" -> LP does not exceed the cutoff bound: obj=%g, cutoff=%g\n", objval, lp->lpiuobjlim);
5667  return SCIP_OKAY;
5668  }
5669  else
5670  {
5671  SCIPdebugMessage(" -> LP exceeds the cutoff bound: obj=%g, cutoff=%g\n", objval, lp->lpiuobjlim);
5672  }
5673  }
5674 
5675  SCIPdebugMessage("analyzing conflict on infeasible LP (infeasible: %u, objlimexc: %u, optimal:%u) in depth %d (diving: %u)\n",
5677 #ifdef SCIP_DEBUG
5678  {
5679  SCIP_Real uobjlim;
5680 
5681  SCIP_CALL( SCIPlpiGetRealpar(lpi, SCIP_LPPAR_UOBJLIM, &uobjlim) );
5682  SCIPdebugMessage(" -> objective limit in LP solver: %g (in LP: %g)\n", uobjlim, lp->lpiuobjlim);
5683  }
5684 #endif
5685 
5686  /* get active problem variables */
5687  vars = transprob->vars;
5688  nvars = transprob->nvars;
5689 
5690  /* get temporary memory for remembering variables' current bounds and corresponding bound change information
5691  * positions in variable's bound change information arrays
5692  */
5693  SCIP_CALL( SCIPsetAllocBufferArray(set, &curvarlbs, nvars) );
5694  SCIP_CALL( SCIPsetAllocBufferArray(set, &curvarubs, nvars) );
5695  SCIP_CALL( SCIPsetAllocBufferArray(set, &lbchginfoposs, nvars) );
5696  SCIP_CALL( SCIPsetAllocBufferArray(set, &ubchginfoposs, nvars) );
5697 
5698  /* the following algorithm is used to find a subset of changed bounds leading to an infeasible LP:
5699  * 1. call undoBdchgsDualfarkas() or undoBdchgsDualsol()
5700  * -> update lb/ubchginfoposs arrays
5701  * -> store additional changes in bdchg and curvarlbs/ubs arrays
5702  * -> apply additional changes to the LPI
5703  * 2. (optional) if additional bound changes were undone:
5704  * -> resolve LP
5705  * -> goto 1.
5706  * 3. redo all bound changes in the LPI to restore the LPI to its original state
5707  * 4. analyze conflict
5708  * -> put remaining changed bounds (see lb/ubchginfoposs arrays) into starting conflict set
5709  */
5710 
5711  /* get current bounds and current positions in lb/ubchginfos arrays of variables */
5712  valid = TRUE;
5713  for( v = 0; v < nvars && valid; ++v )
5714  {
5715  SCIP_VAR* var;
5716 
5717  var = vars[v];
5718 
5719  curvarlbs[v] = SCIPvarGetLbLP(var, set);
5720  curvarubs[v] = SCIPvarGetUbLP(var, set);
5721  lbchginfoposs[v] = var->nlbchginfos-1;
5722  ubchginfoposs[v] = var->nubchginfos-1;
5723  assert(diving || SCIPsetIsEQ(set, curvarlbs[v], SCIPvarGetLbLocal(var)));
5724  assert(diving || SCIPsetIsEQ(set, curvarubs[v], SCIPvarGetUbLocal(var)));
5725 
5726  /* check, if last bound changes were due to strong branching or diving */
5727  if( diving )
5728  {
5729  SCIP_Real lb;
5730  SCIP_Real ub;
5731 
5732  lb = SCIPvarGetLbLocal(var);
5733  ub = SCIPvarGetUbLocal(var);
5734  if( SCIPsetIsGT(set, curvarlbs[v], lb) )
5735  lbchginfoposs[v] = var->nlbchginfos;
5736  else if( SCIPsetIsLT(set, curvarlbs[v], lb) )
5737  {
5738  /* the bound in the diving LP was relaxed -> the LP is not a subproblem of the current node -> abort! */
5739  /**@todo we could still analyze such a conflict, but we would have to take care with our data structures */
5740  valid = FALSE;
5741  }
5742  if( SCIPsetIsLT(set, curvarubs[v], ub) )
5743  ubchginfoposs[v] = var->nubchginfos;
5744  else if( SCIPsetIsGT(set, curvarubs[v], ub) )
5745  {
5746  /* the bound in the diving LP was relaxed -> the LP is not a subproblem of the current node -> abort! */
5747  /**@todo we could still analyze such a conflict, but we would have to take care with our data structures */
5748  valid = FALSE;
5749  }
5750  }
5751  }
5752 
5753  /* get number of columns in the LP */
5754  ncols = SCIPlpGetNCols(lp);
5755 
5756  /* get temporary memory for remembering bound changes on LPI columns */
5757  SCIP_CALL( lpbdchgsCreate(&oldlpbdchgs, set, ncols) );
5758  SCIP_CALL( lpbdchgsCreate(&relaxedlpbdchgs, set, ncols) );
5759 
5760  /* undo as many bound changes as possible with the current LP solution */
5761  resolve = FALSE;
5762  if( valid )
5763  {
5764  int currentdepth;
5765  currentdepth = SCIPtreeGetCurrentDepth(tree);
5766  if( SCIPlpiIsPrimalInfeasible(lpi) )
5767  {
5768  SCIP_CALL( undoBdchgsDualfarkas(set, transprob, lp, currentdepth, curvarlbs, curvarubs, lbchginfoposs,
5769  ubchginfoposs, oldlpbdchgs, relaxedlpbdchgs, &valid, &resolve) );
5770  }
5771  else
5772  {
5773  assert(SCIPlpiIsDualFeasible(lpi) || SCIPlpiIsObjlimExc(lpi));
5774  SCIP_CALL( undoBdchgsDualsol(set, transprob, lp, currentdepth, curvarlbs, curvarubs, lbchginfoposs, ubchginfoposs,
5775  oldlpbdchgs, relaxedlpbdchgs, &valid, &resolve) );
5776  }
5777  }
5778 
5779  /* check if we want to solve the LP */
5780  assert(SCIPprobAllColsInLP(transprob, set, lp));
5781  solvelp = (set->conf_maxlploops != 0 && set->conf_lpiterations != 0);
5782 
5783  if( valid && resolve && solvelp )
5784  {
5785  SCIP_RETCODE retcode;
5786  SCIP_ROW** rows;
5787  int* sidechginds;
5788  SCIP_Real* sidechgoldlhss;
5789  SCIP_Real* sidechgoldrhss;
5790  SCIP_Real* sidechgnewlhss;
5791  SCIP_Real* sidechgnewrhss;
5792  SCIP_Real lpiinfinity;
5793  int maxlploops;
5794  int lpiterations;
5795  int sidechgssize;
5796  int nsidechgs;
5797  int nrows;
5798  int nloops;
5799  int r;
5800 
5801  /* get infinity value of LP solver */
5802  lpiinfinity = SCIPlpiInfinity(lpi);
5803 
5804  /* temporarily disable objective limit and install an iteration limit */
5805  maxlploops = (set->conf_maxlploops >= 0 ? set->conf_maxlploops : INT_MAX);
5806  lpiterations = (set->conf_lpiterations >= 0 ? set->conf_lpiterations : INT_MAX);
5807  SCIP_CALL( SCIPlpiSetRealpar(lpi, SCIP_LPPAR_UOBJLIM, lpiinfinity) );
5808  SCIP_CALL( SCIPlpiSetIntpar(lpi, SCIP_LPPAR_LPITLIM, lpiterations) );
5809 
5810  /* get LP rows */
5811  rows = SCIPlpGetRows(lp);
5812  nrows = SCIPlpGetNRows(lp);
5813  assert(nrows == 0 || rows != NULL);
5814 
5815  /* get temporary memory for remembering side changes on LPI rows */
5816  SCIP_CALL( SCIPsetAllocBufferArray(set, &sidechginds, nrows) );
5817  SCIP_CALL( SCIPsetAllocBufferArray(set, &sidechgoldlhss, nrows) );
5818  SCIP_CALL( SCIPsetAllocBufferArray(set, &sidechgoldrhss, nrows) );
5819  SCIP_CALL( SCIPsetAllocBufferArray(set, &sidechgnewlhss, nrows) );
5820  SCIP_CALL( SCIPsetAllocBufferArray(set, &sidechgnewrhss, nrows) );
5821  sidechgssize = nrows;
5822  nsidechgs = 0;
5823 
5824  /* remove all local rows by setting their sides to infinity;
5825  * finite sides are only changed to near infinity, such that the row's sense in the LP solver
5826  * is not affected (e.g. CPLEX cannot handle free rows)
5827  */
5828  for( r = 0 ; r < nrows; ++r )
5829  {
5830  assert(SCIProwGetLPPos(rows[r]) == r);
5831 
5832  if( SCIProwIsLocal(rows[r]) )
5833  {
5834  SCIPdebugMessage(" -> removing local row <%s> [%g,%g]\n",
5835  SCIProwGetName(rows[r]), SCIProwGetLhs(rows[r]), SCIProwGetRhs(rows[r]));
5836  SCIP_CALL( addSideRemoval(set, rows[r], lpiinfinity, &sidechginds, &sidechgoldlhss, &sidechgoldrhss,
5837  &sidechgnewlhss, &sidechgnewrhss, &sidechgssize, &nsidechgs) );
5838  }
5839  }
5840 
5841  /* apply changes of local rows to the LP solver */
5842  if( nsidechgs > 0 )
5843  {
5844  SCIP_CALL( SCIPlpiChgSides(lpi, nsidechgs, sidechginds, sidechgnewlhss, sidechgnewrhss) );
5845  }
5846 
5847  /* undo as many additional bound changes as possible by resolving the LP */
5848  assert(valid);
5849  assert(resolve);
5850  nloops = 0;
5851  while( valid && resolve && nloops < maxlploops )
5852  {
5853  int iter;
5854 
5855  nloops++;
5856  resolve = FALSE;
5857 
5858  SCIPdebugMessage("infeasible LP conflict analysis loop %d (changed col bounds: %d)\n", nloops, relaxedlpbdchgs->nbdchgs);
5859 
5860  /* apply bound changes to the LP solver */
5861  assert(relaxedlpbdchgs->nbdchgs >= 0);
5862  if( relaxedlpbdchgs->nbdchgs > 0 )
5863  {
5864  SCIPdebugMessage(" -> applying %d bound changes to the LP solver\n", relaxedlpbdchgs->nbdchgs);
5865  SCIP_CALL( SCIPlpiChgBounds(lpi, relaxedlpbdchgs->nbdchgs,
5866  relaxedlpbdchgs->bdchginds, relaxedlpbdchgs->bdchglbs, relaxedlpbdchgs->bdchgubs) );
5867 
5868  /* reset conflict LP bound change data structure */
5869  lpbdchgsReset(relaxedlpbdchgs);
5870  }
5871 
5872  /* start LP timer */
5873  SCIPclockStart(stat->conflictlptime, set);
5874 
5875  /* resolve LP */
5876  retcode = SCIPlpiSolveDual(lpi);
5877 
5878  /* stop LP timer */
5879  SCIPclockStop(stat->conflictlptime, set);
5880 
5881  /* check return code of LP solving call */
5882  if( retcode == SCIP_LPERROR )
5883  {
5884  valid = FALSE;
5885  break;
5886  }
5887  SCIP_CALL( retcode );
5888 
5889  /* count number of LP iterations */
5890  SCIP_CALL( SCIPlpiGetIterations(lpi, &iter) );
5891  (*iterations) += iter;
5892  stat->nconflictlps++;
5893  stat->nconflictlpiterations += iter;
5894  SCIPdebugMessage(" -> resolved LP in %d iterations (total: %"SCIP_LONGINT_FORMAT") (infeasible:%u)\n",
5896 
5897  /* evaluate result */
5898  if( SCIPlpiIsDualFeasible(lpi) || SCIPlpiIsObjlimExc(lpi) )
5899  {
5900  SCIP_Real objval;
5901 
5902  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
5903  valid = (objval >= lp->lpiuobjlim && !SCIPlpDivingObjChanged(lp));
5904  }
5905  else
5906  valid = SCIPlpiIsPrimalInfeasible(lpi);
5907 
5908  if( valid )
5909  {
5910  int currentdepth;
5911  currentdepth = SCIPtreeGetCurrentDepth(tree);
5912  /* undo additional bound changes */
5913  if( SCIPlpiIsPrimalInfeasible(lpi) )
5914  {
5915  SCIP_CALL( undoBdchgsDualfarkas(set, transprob, lp, currentdepth, curvarlbs, curvarubs,
5916  lbchginfoposs, ubchginfoposs, oldlpbdchgs, relaxedlpbdchgs, &valid, &resolve) );
5917  }
5918  else
5919  {
5920  assert(SCIPlpiIsDualFeasible(lpi) || SCIPlpiIsObjlimExc(lpi));
5921  SCIP_CALL( undoBdchgsDualsol(set, transprob, lp, currentdepth, curvarlbs, curvarubs,
5922  lbchginfoposs, ubchginfoposs, oldlpbdchgs, relaxedlpbdchgs, &valid, &resolve) );
5923  }
5924  }
5925  assert(!resolve || valid);
5926  assert(!resolve || relaxedlpbdchgs->nbdchgs > 0);
5927  SCIPdebugMessage(" -> finished infeasible LP conflict analysis loop %d (iter: %d, nbdchgs: %d)\n",
5928  nloops, iter, relaxedlpbdchgs->nbdchgs);
5929  }
5930 
5931  SCIPdebugMessage("finished undoing bound changes after %d loops (valid=%u, nbdchgs: %d)\n",
5932  nloops, valid, oldlpbdchgs->nbdchgs);
5933 
5934  /* reset variables to local bounds */
5935  if( oldlpbdchgs->nbdchgs > 0 )
5936  {
5937  SCIP_CALL( SCIPlpiChgBounds(lpi, oldlpbdchgs->nbdchgs,
5938  oldlpbdchgs->bdchginds, oldlpbdchgs->bdchglbs, oldlpbdchgs->bdchgubs) );
5939  }
5940 
5941  /* reset changes of local rows */
5942  if( nsidechgs > 0 )
5943  {
5944  SCIP_CALL( SCIPlpiChgSides(lpi, nsidechgs, sidechginds, sidechgoldlhss, sidechgoldrhss) );
5945  }
5946 
5947  /* mark the LP unsolved */
5948  if( oldlpbdchgs->nbdchgs > 0 || nsidechgs > 0 )
5949  {
5950  /* The LPI data are out of sync with LP data. Thus, the LP should be marked
5951  * unsolved. However, for strong branching calls, the LP has to have status 'solved'; in
5952  * this case, marklpunsolved is FALSE and synchronization is performed later. */
5953  if ( marklpunsolved )
5954  {
5955  lp->solved = FALSE;
5956  lp->primalfeasible = FALSE;
5957  lp->dualfeasible = FALSE;
5958  lp->lpobjval = SCIP_INVALID;
5960  }
5961  }
5962 
5963  /* reinstall old objective and iteration limits in LP solver */
5966 
5967  /* free temporary memory */
5968  SCIPsetFreeBufferArray(set, &sidechgnewrhss);
5969  SCIPsetFreeBufferArray(set, &sidechgnewlhss);
5970  SCIPsetFreeBufferArray(set, &sidechgoldrhss);
5971  SCIPsetFreeBufferArray(set, &sidechgoldlhss);
5972  SCIPsetFreeBufferArray(set, &sidechginds);
5973  }
5974 
5975  /* analyze the conflict starting with remaining bound changes */
5976  if( valid )
5977  {
5978  SCIP_CALL( conflictAnalyzeRemainingBdchgs(conflict, blkmem, set, stat, transprob, tree, diving,
5979  lbchginfoposs, ubchginfoposs, nconss, nliterals, nreconvconss, nreconvliterals) );
5980  }
5981 
5982  /* free temporary memory */
5983  lpbdchgsFree(&relaxedlpbdchgs, set);
5984  lpbdchgsFree(&oldlpbdchgs, set);
5985  SCIPsetFreeBufferArray(set, &ubchginfoposs);
5986  SCIPsetFreeBufferArray(set, &lbchginfoposs);
5987  SCIPsetFreeBufferArray(set, &curvarubs);
5988  SCIPsetFreeBufferArray(set, &curvarlbs);
5989 
5990  /* flush conflict set storage */
5991  SCIP_CALL( SCIPconflictFlushConss(conflict, blkmem, set, stat, transprob, origprob, tree, lp, branchcand, eventqueue) );
5992 
5993  return SCIP_OKAY;
5994 }
5995 
5996 /** analyzes an infeasible LP to find out the bound changes on variables that were responsible for the infeasibility;
5997  * on success, calls standard conflict analysis with the responsible variables as starting conflict set, thus creating
5998  * a conflict constraint out of the resulting conflict set;
5999  * updates statistics for infeasible LP conflict analysis
6000  */
6001 static
6003  SCIP_CONFLICT* conflict, /**< conflict analysis data */
6004  BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
6005  SCIP_SET* set, /**< global SCIP settings */
6006  SCIP_STAT* stat, /**< problem statistics */
6007  SCIP_PROB* transprob, /**< transformed problem */
6008  SCIP_PROB* origprob, /**< original problem */
6009  SCIP_TREE* tree, /**< branch and bound tree */
6010  SCIP_LP* lp, /**< LP data */
6011  SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
6012  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
6013  SCIP_Bool* success /**< pointer to store whether a conflict constraint was created, or NULL */
6014  )
6015 {
6016  int iterations;
6017  int nconss;
6018  int nliterals;
6019  int nreconvconss;
6020  int nreconvliterals;
6021 
6022  assert(conflict != NULL);
6023  assert(set != NULL);
6024  assert(lp != NULL);
6025  assert(SCIPprobAllColsInLP(transprob, set, lp)); /* LP conflict analysis is only valid, if all variables are known */
6026 
6027  assert(success == NULL || *success == FALSE);
6028 
6029  /* check, if infeasible LP conflict analysis is enabled */
6030  if( !set->conf_enable || !set->conf_useinflp )
6031  return SCIP_OKAY;
6032 
6033  /* check, if there are any conflict handlers to use a conflict set */
6034  if( set->nconflicthdlrs == 0 )
6035  return SCIP_OKAY;
6036 
6037  SCIPdebugMessage("analyzing conflict on infeasible LP in depth %d (solstat: %d, objchanged: %u)\n",
6039 
6040  /* start timing */
6041  SCIPclockStart(conflict->inflpanalyzetime, set);
6042  conflict->ninflpcalls++;
6043 
6044  /* perform conflict analysis */
6045  SCIP_CALL( conflictAnalyzeLP(conflict, blkmem, set, stat, transprob, origprob, tree, lp, branchcand, eventqueue,
6046  SCIPlpDiving(lp), &iterations, &nconss, &nliterals, &nreconvconss, &nreconvliterals, TRUE) );
6047  conflict->ninflpsuccess += (nconss > 0 ? 1 : 0);
6048  conflict->ninflpiterations += iterations;
6049  conflict->ninflpconfconss += nconss;
6050  conflict->ninflpconfliterals += nliterals;
6051  conflict->ninflpreconvconss += nreconvconss;
6052  conflict->ninflpreconvliterals += nreconvliterals;
6053  if( success != NULL )
6054  *success = (nconss > 0);
6055 
6056  /* stop timing */
6057  SCIPclockStop(conflict->inflpanalyzetime, set);
6058 
6059  return SCIP_OKAY;
6060 }
6061 
6062 /** analyzes a bound exceeding LP to find out the bound changes on variables that were responsible for exceeding the
6063  * primal bound;
6064  * on success, calls standard conflict analysis with the responsible variables as starting conflict set, thus creating
6065  * a conflict constraint out of the resulting conflict set;
6066  * updates statistics for bound exceeding LP conflict analysis
6067  */
6068 static
6070  SCIP_CONFLICT* conflict, /**< conflict analysis data */
6071  BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
6072  SCIP_SET* set, /**< global SCIP settings */
6073  SCIP_STAT* stat, /**< problem statistics */
6074  SCIP_PROB* transprob, /**< transformed problem */
6075  SCIP_PROB* origprob, /**< original problem */
6076  SCIP_TREE* tree, /**< branch and bound tree */
6077  SCIP_LP* lp, /**< LP data */
6078  SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
6079  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
6080  SCIP_Bool* success /**< pointer to store whether a conflict constraint was created, or NULL */
6081  )
6082 {
6083  int iterations;
6084  int nconss;
6085  int nliterals;
6086  int nreconvconss;
6087  int nreconvliterals;
6088 
6089  assert(conflict != NULL);
6090  assert(set != NULL);
6091  assert(lp != NULL);
6092  assert(!SCIPlpDivingObjChanged(lp));
6093  assert(SCIPprobAllColsInLP(transprob, set, lp)); /* LP conflict analysis is only valid, if all variables are known */
6094 
6095  assert(success == NULL || *success == FALSE);
6096 
6097  /* check, if bound exceeding LP conflict analysis is enabled */
6098  if( !set->conf_enable || !set->conf_useboundlp )
6099  return SCIP_OKAY;
6100 
6101  /* check, if there are any conflict handlers to use a conflict set */
6102  if( set->nconflicthdlrs == 0 )
6103  return SCIP_OKAY;
6104 
6105  SCIPdebugMessage("analyzing conflict on bound exceeding LP in depth %d (solstat: %d)\n",
6107 
6108  /* start timing */
6109  SCIPclockStart(conflict->boundlpanalyzetime, set);
6110  conflict->nboundlpcalls++;
6111 
6112  /* perform conflict analysis */
6113  SCIP_CALL( conflictAnalyzeLP(conflict, blkmem, set, stat, transprob, origprob, tree, lp, branchcand, eventqueue,
6114  SCIPlpDiving(lp), &iterations, &nconss, &nliterals, &nreconvconss, &nreconvliterals, TRUE) );
6115  conflict->nboundlpsuccess += (nconss > 0 ? 1 : 0);
6116  conflict->nboundlpiterations += iterations;
6117  conflict->nboundlpconfconss += nconss;
6118  conflict->nboundlpconfliterals += nliterals;
6119  conflict->nboundlpreconvconss += nreconvconss;
6120  conflict->nboundlpreconvliterals += nreconvliterals;
6121  if( success != NULL )
6122  *success = (nconss > 0);
6123 
6124  /* stop timing */
6125  SCIPclockStop(conflict->boundlpanalyzetime, set);
6126 
6127  return SCIP_OKAY;
6128 }
6129 
6130 /** analyzes an infeasible or bound exceeding LP to find out the bound changes on variables that were responsible for the
6131  * infeasibility or for exceeding the primal bound;
6132  * on success, calls standard conflict analysis with the responsible variables as starting conflict set, thus creating
6133  * a conflict constraint out of the resulting conflict set;
6134  * updates statistics for infeasible or bound exceeding LP conflict analysis;
6135  * may only be called if SCIPprobAllColsInLP()
6136  */
6138  SCIP_CONFLICT* conflict, /**< conflict analysis data */
6139  BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
6140  SCIP_SET* set, /**< global SCIP settings */
6141  SCIP_STAT* stat, /**< problem statistics */
6142  SCIP_PROB* transprob, /**< transformed problem */
6143  SCIP_PROB* origprob, /**< original problem */
6144  SCIP_TREE* tree, /**< branch and bound tree */
6145  SCIP_LP* lp, /**< LP data */
6146  SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
6147  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
6148  SCIP_Bool* success /**< pointer to store whether a conflict constraint was created, or NULL */
6149  )
6150 {
6151  SCIP_LPSOLVALS storedsolvals;
6152  SCIP_COLSOLVALS* storedcolsolvals;
6153  SCIP_ROWSOLVALS* storedrowsolvals;
6154  int c;
6155  int r;
6156 
6157  if( success != NULL )
6158  *success = FALSE;
6159 
6160  /* in rare cases, it might happen that the solution stati of the LP and the LPI are out of sync; in particular this
6161  * happens when a new incumbent which cuts off the current node is found during the LP solving loop; in this case the
6162  * LP has status objlimit, but if diving has been used, the LPI only has the basis information, but is not solved
6163  *
6164  * @todo: alternatively, solve the LPI
6165  */
6166  if( !SCIPlpiWasSolved(SCIPlpGetLPI(lp)) )
6167  return SCIP_OKAY;
6168 
6169  /* LP conflict analysis is only valid, if all variables are known */
6170  assert( SCIPprobAllColsInLP(transprob, set, lp) );
6172  || (SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OPTIMAL && set->lp_disablecutoff == 1) );
6173 
6174  /* save status */
6175  storedsolvals.lpsolstat = lp->lpsolstat;
6176  storedsolvals.lpobjval = lp->lpobjval;
6177  storedsolvals.primalfeasible = lp->primalfeasible;
6178  storedsolvals.dualfeasible = lp->dualfeasible;
6179  storedsolvals.solisbasic = lp->solisbasic;
6180  storedsolvals.lpissolved = lp->solved;
6181 
6182  /* store solution values */
6183  SCIP_CALL( SCIPsetAllocBufferArray(set, &storedcolsolvals, lp->ncols) );
6184  SCIP_CALL( SCIPsetAllocBufferArray(set, &storedrowsolvals, lp->nrows) );
6185  for (c = 0; c < lp->ncols; ++c)
6186  {
6187  SCIP_COL* col;
6188 
6189  col = lp->cols[c];
6190  assert( col != NULL );
6191 
6192  storedcolsolvals[c].primsol = col->primsol;
6193  storedcolsolvals[c].redcost = col->redcost;
6194  storedcolsolvals[c].basisstatus = col->basisstatus; /*lint !e641 !e732*/
6195  }
6196  for (r = 0; r < lp->nrows; ++r)
6197  {
6198  SCIP_ROW* row;
6199 
6200  row = lp->rows[r];
6201  assert( row != NULL );
6202 
6203  if ( lp->lpsolstat == SCIP_LPSOLSTAT_INFEASIBLE )
6204  storedrowsolvals[r].dualsol = row->dualfarkas;
6205  else
6206  {
6207  assert( lp->lpsolstat == SCIP_LPSOLSTAT_OBJLIMIT ||
6209  storedrowsolvals[r].dualsol = row->dualsol;
6210  }
6211  storedrowsolvals[r].activity = row->activity;
6212  storedrowsolvals[r].basisstatus = row->basisstatus; /*lint !e641 !e732*/
6213  }
6214 
6215  /* check, if the LP was infeasible or bound exceeding */
6217  {
6218  SCIP_CALL( conflictAnalyzeInfeasibleLP(conflict, blkmem, set, stat, transprob, origprob, tree, lp, branchcand, eventqueue, success) );
6219  }
6220  else
6221  {
6222  SCIP_CALL( conflictAnalyzeBoundexceedingLP(conflict, blkmem, set, stat, transprob, origprob, tree, lp, branchcand, eventqueue, success) );
6223  }
6224 
6225  /* possibly restore solution values */
6227  {
6228  /* restore status */
6229  lp->lpsolstat = storedsolvals.lpsolstat;
6230  lp->lpobjval = storedsolvals.lpobjval;
6231  lp->primalfeasible = storedsolvals.primalfeasible;
6232  lp->dualfeasible = storedsolvals.dualfeasible;
6233  lp->solisbasic = storedsolvals.solisbasic;
6234  lp->solved = storedsolvals.lpissolved;
6235 
6236  for (c = 0; c < lp->ncols; ++c)
6237  {
6238  SCIP_COL* col;
6239 
6240  col = lp->cols[c];
6241  assert( col != NULL );
6242  col->primsol = storedcolsolvals[c].primsol;
6243  col->redcost = storedcolsolvals[c].redcost;
6244  col->basisstatus = storedcolsolvals[c].basisstatus; /*lint !e641 !e732*/
6245  }
6246  for (r = 0; r < lp->nrows; ++r)
6247  {
6248  SCIP_ROW* row;
6249 
6250  row = lp->rows[r];
6251  assert( row != NULL );
6252 
6253  if ( lp->lpsolstat == SCIP_LPSOLSTAT_INFEASIBLE )
6254  row->dualfarkas = storedrowsolvals[r].dualsol;
6255  else
6256  {
6257  assert( lp->lpsolstat == SCIP_LPSOLSTAT_OBJLIMIT );
6258  row->dualsol = storedrowsolvals[r].dualsol;
6259  }
6260  row->activity = storedrowsolvals[r].activity;
6261  row->basisstatus = storedrowsolvals[r].basisstatus; /*lint !e641 !e732*/
6262  }
6263  }
6264  SCIPsetFreeBufferArray(set, &storedrowsolvals);
6265  SCIPsetFreeBufferArray(set, &storedcolsolvals);
6266 
6267  return SCIP_OKAY;
6268 }
6269 
6270 /** gets time in seconds used for analyzing infeasible LP conflicts */
6272  SCIP_CONFLICT* conflict /**< conflict analysis data */
6273  )
6274 {
6275  assert(conflict != NULL);
6276 
6277  return SCIPclockGetTime(conflict->inflpanalyzetime);
6278 }
6279 
6280 /** gets number of calls to infeasible LP conflict analysis */
6282  SCIP_CONFLICT* conflict /**< conflict analysis data */
6283  )
6284 {
6285  assert(conflict != NULL);
6286 
6287  return conflict->ninflpcalls;
6288 }
6289 
6290 /** gets number of calls to infeasible LP conflict analysis that yield at least one conflict constraint */
6292  SCIP_CONFLICT* conflict /**< conflict analysis data */
6293  )
6294 {
6295  assert(conflict != NULL);
6296 
6297  return conflict->ninflpsuccess;
6298 }
6299 
6300 /** gets number of conflict constraints detected in infeasible LP conflict analysis */
6302  SCIP_CONFLICT* conflict /**< conflict analysis data */
6303  )
6304 {
6305  assert(conflict != NULL);
6306 
6307  return conflict->ninflpconfconss;
6308 }
6309 
6310 /** gets total number of literals in conflict constraints created in infeasible LP conflict analysis */
6312  SCIP_CONFLICT* conflict /**< conflict analysis data */
6313  )
6314 {
6315  assert(conflict != NULL);
6316 
6317  return conflict->ninflpconfliterals;
6318 }
6319 
6320 /** gets number of reconvergence constraints detected in infeasible LP conflict analysis */
6322  SCIP_CONFLICT* conflict /**< conflict analysis data */
6323  )
6324 {
6325  assert(conflict != NULL);
6326 
6327  return conflict->ninflpreconvconss;
6328 }
6329 
6330 /** gets total number of literals in reconvergence constraints created in infeasible LP conflict analysis */
6332  SCIP_CONFLICT* conflict /**< conflict analysis data */
6333  )
6334 {
6335  assert(conflict != NULL);
6336 
6337  return conflict->ninflpreconvliterals;
6338 }
6339 
6340 /** gets number of LP iterations in infeasible LP conflict analysis */
6342  SCIP_CONFLICT* conflict /**< conflict analysis data */
6343  )
6344 {
6345  assert(conflict != NULL);
6346 
6347  return conflict->ninflpiterations;
6348 }
6349 
6350 /** gets time in seconds used for analyzing bound exceeding LP conflicts */
6352  SCIP_CONFLICT* conflict /**< conflict analysis data */
6353  )
6354 {
6355  assert(conflict != NULL);
6356 
6357  return SCIPclockGetTime(conflict->boundlpanalyzetime);
6358 }
6359 
6360 /** gets number of calls to bound exceeding LP conflict analysis */
6362  SCIP_CONFLICT* conflict /**< conflict analysis data */
6363  )
6364 {
6365  assert(conflict != NULL);
6366 
6367  return conflict->nboundlpcalls;
6368 }
6369 
6370 /** gets number of calls to bound exceeding LP conflict analysis that yield at least one conflict constraint */
6372  SCIP_CONFLICT* conflict /**< conflict analysis data */
6373  )
6374 {
6375  assert(conflict != NULL);
6376 
6377  return conflict->nboundlpsuccess;
6378 }
6379 
6380 /** gets number of conflict constraints detected in bound exceeding LP conflict analysis */
6382  SCIP_CONFLICT* conflict /**< conflict analysis data */
6383  )
6384 {
6385  assert(conflict != NULL);
6386 
6387  return conflict->nboundlpconfconss;
6388 }
6389 
6390 /** gets total number of literals in conflict constraints created in bound exceeding LP conflict analysis */
6392  SCIP_CONFLICT* conflict /**< conflict analysis data */
6393  )
6394 {
6395  assert(conflict != NULL);
6396 
6397  return conflict->nboundlpconfliterals;
6398 }
6399 
6400 /** gets number of reconvergence constraints detected in bound exceeding LP conflict analysis */
6402  SCIP_CONFLICT* conflict /**< conflict analysis data */
6403  )
6404 {
6405  assert(conflict != NULL);
6406 
6407  return conflict->nboundlpreconvconss;
6408 }
6409 
6410 /** gets total number of literals in reconvergence constraints created in bound exceeding LP conflict analysis */
6412  SCIP_CONFLICT* conflict /**< conflict analysis data */
6413  )
6414 {
6415  assert(conflict != NULL);
6416 
6417  return conflict->nboundlpreconvliterals;
6418 }
6419 
6420 /** gets number of LP iterations in bound exceeding LP conflict analysis */
6422  SCIP_CONFLICT* conflict /**< conflict analysis data */
6423  )
6424 {
6425  assert(conflict != NULL);
6426 
6427  return conflict->nboundlpiterations;
6428 }
6429 
6430 
6431 
6432 
6433 /*
6434  * infeasible strong branching conflict analysis
6435  */
6436 
6437 /** analyses infeasible strong branching sub problems for conflicts */
6439  SCIP_CONFLICT* conflict, /**< conflict analysis data */
6440  BMS_BLKMEM* blkmem, /**< block memory buffers */
6441  SCIP_SET* set, /**< global SCIP settings */
6442  SCIP_STAT* stat, /**< dynamic problem statistics */
6443  SCIP_PROB* transprob, /**< transformed problem */
6444  SCIP_PROB* origprob, /**< original problem */
6445  SCIP_TREE* tree, /**< branch and bound tree */
6446  SCIP_LP* lp, /**< LP data */
6447  SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
6448  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
6449  SCIP_COL* col, /**< LP column with at least one infeasible strong branching subproblem */
6450  SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
6451  * infeasible downwards branch, or NULL */
6452  SCIP_Bool* upconflict /**< pointer to store whether a conflict constraint was created for an
6453  * infeasible upwards branch, or NULL */
6454  )
6455 {
6456  int* cstat;
6457  int* rstat;
6458  SCIP_RETCODE retcode;
6459  SCIP_Bool resolve;
6460  SCIP_Real oldlb;
6461  SCIP_Real oldub;
6462  SCIP_Real newlb;
6463  SCIP_Real newub;
6464  int iter;
6465  int nconss;
6466  int nliterals;
6467  int nreconvconss;
6468  int nreconvliterals;
6469 
6470  assert(stat != NULL);
6471  assert(lp != NULL);
6472  assert(lp->flushed);
6473  assert(lp->solved);
6474  assert(SCIPprobAllColsInLP(transprob, set, lp)); /* LP conflict analysis is only valid, if all variables are known */
6475  assert(col != NULL);
6476  assert((col->sbdownvalid && SCIPsetIsGE(set, col->sbdown, lp->cutoffbound)
6477  && SCIPsetFeasCeil(set, col->primsol-1.0) >= col->lb - 0.5)
6478  || (col->sbupvalid && SCIPsetIsGE(set, col->sbup, lp->cutoffbound)
6479  && SCIPsetFeasFloor(set, col->primsol+1.0) <= col->ub + 0.5));
6480  assert(SCIPtreeGetCurrentDepth(tree) > 0);
6481 
6482  if( downconflict != NULL )
6483  *downconflict = FALSE;
6484  if( upconflict != NULL )
6485  *upconflict = FALSE;
6486 
6487  /* check, if infeasible LP conflict analysis is enabled */
6488  if( !set->conf_enable || !set->conf_usesb )
6489  return SCIP_OKAY;
6490 
6491  /* check, if there are any conflict handlers to use a conflict set */
6492  if( set->nconflicthdlrs == 0 )
6493  return SCIP_OKAY;
6494 
6495  /* inform the LPI that strong branch is (temporarily) finished */
6497 
6498  /* start timing */
6499  SCIPclockStart(conflict->sbanalyzetime, set);
6500 
6501  /* get temporary memory for storing current LP basis */
6502  SCIP_CALL( SCIPsetAllocBufferArray(set, &cstat, lp->nlpicols) );
6503  SCIP_CALL( SCIPsetAllocBufferArray(set, &rstat, lp->nlpirows) );
6504 
6505  /* get current LP basis */
6506  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
6507 
6508  /* remember old bounds */
6509  oldlb = col->lb;
6510  oldub = col->ub;
6511 
6512  resolve = FALSE;
6513 
6514  /* is down branch infeasible? */
6515  if( col->sbdownvalid && SCIPsetIsGE(set, col->sbdown, lp->cutoffbound) )
6516  {
6517  newub = SCIPsetFeasCeil(set, col->primsol-1.0);
6518  if( newub >= col->lb - 0.5 )
6519  {
6520  SCIPdebugMessage("analyzing conflict on infeasible downwards strongbranch for variable <%s>[%g,%g] in depth %d\n",
6522  SCIPtreeGetCurrentDepth(tree));
6523 
6524  conflict->nsbcalls++;
6525 
6526  /* change the upper bound */
6527  col->ub = newub;
6528  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, 1, &col->lpipos, &col->lb, &col->ub) );
6529 
6530  /* start LP timer */
6531  SCIPclockStart(stat->conflictlptime, set);
6532 
6533  /* resolve the LP */
6534  retcode = SCIPlpiSolveDual(lp->lpi);
6535 
6536  /* stop LP timer */
6537  SCIPclockStop(stat->conflictlptime, set);
6538 
6539  /* check return code of LP solving call */
6540  if( retcode != SCIP_LPERROR )
6541  {
6542  SCIP_CALL( retcode );
6543 
6544  /* count number of LP iterations */
6545  SCIP_CALL( SCIPlpiGetIterations(lp->lpi, &iter) );
6546  stat->nconflictlps++;
6547  stat->nconflictlpiterations += iter;
6548  conflict->nsbiterations += iter;
6549  SCIPdebugMessage(" -> resolved downwards strong branching LP in %d iterations\n", iter);
6550 
6551  /* perform conflict analysis on infeasible LP; last parameter guarantees status 'solved' on return */
6552  SCIP_CALL( conflictAnalyzeLP(conflict, blkmem, set, stat, transprob, origprob, tree, lp, branchcand,
6553  eventqueue, TRUE, &iter, &nconss, &nliterals, &nreconvconss, &nreconvliterals, FALSE) );
6554  conflict->nsbsuccess += (nconss > 0 ? 1 : 0);
6555  conflict->nsbiterations += iter;
6556  conflict->nsbconfconss += nconss;
6557  conflict->nsbconfliterals += nliterals;
6558  conflict->nsbreconvconss += nreconvconss;
6559  conflict->nsbreconvliterals += nreconvliterals;
6560  if( downconflict != NULL )
6561  *downconflict = (nconss > 0);
6562  }
6563 
6564  /* reset the upper bound */
6565  col->ub = oldub;
6566  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, 1, &col->lpipos, &col->lb, &col->ub) );
6567 
6568  /* reset LP basis */
6569  SCIP_CALL( SCIPlpiSetBase(lp->lpi, cstat, rstat) );
6570 
6571  /* mark the LP to be resolved at the end */
6572  resolve = TRUE;
6573  }
6574  }
6575 
6576  /* is up branch infeasible? */
6577  if( col->sbupvalid && SCIPsetIsGE(set, col->sbup, lp->cutoffbound) )
6578  {
6579  newlb = SCIPsetFeasFloor(set, col->primsol+1.0);
6580  if( newlb <= col->ub + 0.5 )
6581  {
6582  SCIPdebugMessage("analyzing conflict on infeasible upwards strongbranch for variable <%s>[%g,%g] in depth %d\n",
6584  SCIPtreeGetCurrentDepth(tree));
6585 
6586  conflict->nsbcalls++;
6587 
6588  /* change the lower bound */
6589  col->lb = newlb;
6590  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, 1, &col->lpipos, &col->lb, &col->ub) );
6591 
6592  /* start LP timer */
6593  SCIPclockStart(stat->conflictlptime, set);
6594 
6595  /* resolve the LP */
6596  retcode = SCIPlpiSolveDual(lp->lpi);
6597 
6598  /* stop LP timer */
6599  SCIPclockStop(stat->conflictlptime, set);
6600 
6601  /* check return code of LP solving call */
6602  if( retcode != SCIP_LPERROR )
6603  {
6604  SCIP_CALL( retcode );
6605 
6606  /* count number of LP iterations */
6607  SCIP_CALL( SCIPlpiGetIterations(lp->lpi, &iter) );
6608  stat->nconflictlps++;
6609  stat->nconflictlpiterations += iter;
6610  conflict->nsbiterations += iter;
6611  SCIPdebugMessage(" -> resolved upwards strong branching LP in %d iterations\n", iter);
6612 
6613  /* perform conflict analysis on infeasible LP; last parameter guarantees status 'solved' on return */
6614  SCIP_CALL( conflictAnalyzeLP(conflict, blkmem, set, stat, transprob, origprob, tree, lp, branchcand,
6615  eventqueue, TRUE, &iter, &nconss, &nliterals, &nreconvconss, &nreconvliterals, FALSE) );
6616  conflict->nsbsuccess += (nconss > 0 ? 1 : 0);
6617  conflict->nsbiterations += iter;
6618  conflict->nsbconfconss += nconss;
6619  conflict->nsbconfliterals += nliterals;
6620  conflict->nsbreconvconss += nreconvconss;
6621  conflict->nsbreconvliterals += nreconvliterals;
6622  if( upconflict != NULL )
6623  *upconflict = (nconss > 0);
6624  }
6625 
6626  /* reset the lower bound */
6627  col->lb = oldlb;
6628  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, 1, &col->lpipos, &col->lb, &col->ub) );
6629 
6630  /* reset LP basis */
6631  SCIP_CALL( SCIPlpiSetBase(lp->lpi, cstat, rstat) );
6632 
6633  /* mark the LP to be resolved at the end */
6634  resolve = TRUE;
6635  }
6636  }
6637 
6638  /* free temporary memory for storing current LP basis */
6639  SCIPsetFreeBufferArray(set, &rstat);
6640  SCIPsetFreeBufferArray(set, &cstat);
6641 
6642  assert(lp->flushed);
6643 
6644  /* resolve LP if something has changed in order to synchronize LPI and LP */
6645  if ( resolve )
6646  {
6647  /* start LP timer */
6648  SCIPclockStart(stat->conflictlptime, set);
6649 
6650  /* resolve the LP */
6651  SCIP_CALL( SCIPlpiSolveDual(lp->lpi) );
6652 
6653  /* stop LP timer */
6654  SCIPclockStop(stat->conflictlptime, set);
6655  }
6656 
6657  /* stop timing */
6658  SCIPclockStop(conflict->sbanalyzetime, set);
6659 
6660  /* inform the LPI that strong branch starts (again) */
6662 
6663  return SCIP_OKAY;
6664 }
6665 
6666 /** gets time in seconds used for analyzing infeasible strong branching conflicts */
6668  SCIP_CONFLICT* conflict /**< conflict analysis data */
6669  )
6670 {
6671  assert(conflict != NULL);
6672 
6673  return SCIPclockGetTime(conflict->sbanalyzetime);
6674 }
6675 
6676 /** gets number of calls to infeasible strong branching conflict analysis */
6678  SCIP_CONFLICT* conflict /**< conflict analysis data */
6679  )
6680 {
6681  assert(conflict != NULL);
6682 
6683  return conflict->nsbcalls;
6684 }
6685 
6686 /** gets number of calls to infeasible strong branching conflict analysis that yield at least one conflict constraint */
6688  SCIP_CONFLICT* conflict /**< conflict analysis data */
6689  )
6690 {
6691  assert(conflict != NULL);
6692 
6693  return conflict->nsbsuccess;
6694 }
6695 
6696 /** gets number of conflict constraints detected in infeasible strong branching conflict analysis */
6698  SCIP_CONFLICT* conflict /**< conflict analysis data */
6699  )
6700 {
6701  assert(conflict != NULL);
6702 
6703  return conflict->nsbconfconss;
6704 }
6705 
6706 /** gets total number of literals in conflict constraints created in infeasible strong branching conflict analysis */
6708  SCIP_CONFLICT* conflict /**< conflict analysis data */
6709  )
6710 {
6711  assert(conflict != NULL);
6712 
6713  return conflict->nsbconfliterals;
6714 }
6715 
6716 /** gets number of reconvergence constraints detected in infeasible strong branching conflict analysis */
6718  SCIP_CONFLICT* conflict /**< conflict analysis data */
6719  )
6720 {
6721  assert(conflict != NULL);
6722 
6723  return conflict->nsbreconvconss;
6724 }
6725 
6726 /** gets total number of literals in reconvergence constraints created in infeasible strong branching conflict analysis */
6728  SCIP_CONFLICT* conflict /**< conflict analysis data */
6729  )
6730 {
6731  assert(conflict != NULL);
6732 
6733  return conflict->nsbreconvliterals;
6734 }
6735 
6736 /** gets number of LP iterations in infeasible strong branching conflict analysis */
6738  SCIP_CONFLICT* conflict /**< conflict analysis data */
6739  )
6740 {
6741  assert(conflict != NULL);
6742 
6743  return conflict->nsbiterations;
6744 }
6745 
6746 
6747 
6748 
6749 /*
6750  * pseudo solution conflict analysis
6751  */
6752 
6753 /** analyzes a pseudo solution with objective value exceeding the current cutoff to find out the bound changes on
6754  * variables that were responsible for the objective value degradation;
6755  * on success, calls standard conflict analysis with the responsible variables as starting conflict set, thus creating
6756  * a conflict constraint out of the resulting conflict set;
6757  * updates statistics for pseudo solution conflict analysis
6758  */
6760  SCIP_CONFLICT* conflict, /**< conflict analysis data */
6761  BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
6762  SCIP_SET* set, /**< global SCIP settings */
6763  SCIP_STAT* stat, /**< problem statistics */
6764  SCIP_PROB* transprob, /**< transformed problem */
6765  SCIP_PROB* origprob, /**< original problem */
6766  SCIP_TREE* tree, /**< branch and bound tree */
6767  SCIP_LP* lp, /**< LP data */
6768  SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
6769  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
6770  SCIP_Bool* success /**< pointer to store whether a conflict constraint was created, or NULL */
6771  )
6772 {
6773  SCIP_VAR** vars;
6774  SCIP_VAR* var;
6775  SCIP_Real* curvarlbs;
6776  SCIP_Real* curvarubs;
6777  int* lbchginfoposs;
6778  int* ubchginfoposs;
6779  SCIP_Real* pseudocoefs;
6780  SCIP_Real pseudolhs;
6781  SCIP_Real pseudoact;
6782  int nvars;
6783  int v;
6784 
6785  assert(conflict != NULL);
6786  assert(conflict->nconflictsets == 0);
6787  assert(set != NULL);
6788  assert(stat != NULL);
6789  assert(transprob != NULL);
6790  assert(lp != NULL);
6791  assert(!SCIPsetIsInfinity(set, -SCIPlpGetPseudoObjval(lp, set, transprob)));
6792  assert(!SCIPsetIsInfinity(set, lp->cutoffbound));
6793 
6794  if( success != NULL )
6795  *success = FALSE;
6796 
6797  /* check, if pseudo solution conflict analysis is enabled */
6798  if( !set->conf_enable || !set->conf_usepseudo )
6799  return SCIP_OKAY;
6800 
6801  /* check, if there are any conflict handlers to use a conflict set */
6802  if( set->nconflicthdlrs == 0 )
6803  return SCIP_OKAY;
6804 
6805  SCIPdebugMessage("analyzing pseudo solution (obj: %g) that exceeds objective limit (%g)\n",
6806  SCIPlpGetPseudoObjval(lp, set, transprob), lp->cutoffbound);
6807 
6808  /* start timing */
6809  SCIPclockStart(conflict->pseudoanalyzetime, set);
6810  conflict->npseudocalls++;
6811 
6812  vars = transprob->vars;
6813  nvars = transprob->nvars;
6814  assert(nvars == 0 || vars != NULL);
6815 
6816  /* The current primal bound c* gives an upper bound for the current pseudo objective value:
6817  * min{c^T x | lb <= x <= ub} <= c*.
6818  * We have to transform this row into a >= inequality in order to use methods above:
6819  * -c* <= max{-c^T x | lb <= x <= ub}.
6820  * In the local subproblem, this row is violated. We want to undo bound changes while still keeping the
6821  * row violated.
6822  */
6823 
6824  /* get temporary memory for remembering variables' current bounds and corresponding bound change information
6825  * positions in variable's bound change information arrays
6826  */
6827  SCIP_CALL( SCIPsetAllocBufferArray(set, &curvarlbs, nvars) );
6828  SCIP_CALL( SCIPsetAllocBufferArray(set, &curvarubs, nvars) );
6829  SCIP_CALL( SCIPsetAllocBufferArray(set, &lbchginfoposs, nvars) );
6830  SCIP_CALL( SCIPsetAllocBufferArray(set, &ubchginfoposs, nvars) );
6831 
6832  /* get temporary memory for infeasibility proof coefficients */
6833  SCIP_CALL( SCIPsetAllocBufferArray(set, &pseudocoefs, nvars) );
6834 
6835  /* use a slightly tighter cutoff bound, because solutions with equal objective value should also be declared
6836  * infeasible
6837  */
6838  pseudolhs = -(lp->cutoffbound - SCIPsetSumepsilon(set));
6839 
6840  /* store the objective values as infeasibility proof coefficients, and recalculate the pseudo activity */
6841  pseudoact = 0.0;
6842  for( v = 0; v < nvars; ++v )
6843  {
6844  var = vars[v];
6845  pseudocoefs[v] = -SCIPvarGetObj(var);
6846  curvarlbs[v] = SCIPvarGetLbLocal(var);
6847  curvarubs[v] = SCIPvarGetUbLocal(var);
6848  if( pseudocoefs[v] > 0.0 )
6849  pseudoact += pseudocoefs[v] * curvarubs[v];
6850  else
6851  pseudoact += pseudocoefs[v] * curvarlbs[v];
6852  lbchginfoposs[v] = var->nlbchginfos-1;
6853  ubchginfoposs[v] = var->nubchginfos-1;
6854  }
6855  assert(SCIPsetIsFeasEQ(set, pseudoact, -SCIPlpGetPseudoObjval(lp, set, transprob)));
6856  SCIPdebugMessage(" -> recalculated pseudo infeasibility proof: %g <= %g\n", pseudolhs, pseudoact);
6857 
6858  /* check, if the pseudo row is still violated (after recalculation of pseudo activity) */
6859  if( SCIPsetIsFeasGT(set, pseudolhs, pseudoact) )
6860  {
6861  int nconss;
6862  int nliterals;
6863  int nreconvconss;
6864  int nreconvliterals;
6865 
6866  /* undo bound changes without destroying the infeasibility proof */
6867  SCIP_CALL( undoBdchgsProof(set, transprob, SCIPtreeGetCurrentDepth(tree), pseudocoefs, pseudolhs, pseudoact,
6868  curvarlbs, curvarubs, lbchginfoposs, ubchginfoposs, NULL, NULL, NULL) );
6869 
6870  /* analyze conflict on remaining bound changes */
6871  SCIP_CALL( conflictAnalyzeRemainingBdchgs(conflict, blkmem, set, stat, transprob, tree, FALSE,
6872  lbchginfoposs, ubchginfoposs, &nconss, &nliterals, &nreconvconss, &nreconvliterals) );
6873  conflict->npseudosuccess += (nconss > 0 ? 1 : 0);
6874  conflict->npseudoconfconss += nconss;
6875  conflict->npseudoconfliterals += nliterals;
6876  conflict->npseudoreconvconss += nreconvconss;
6877  conflict->npseudoreconvliterals += nreconvliterals;
6878  if( success != NULL )
6879  *success = (nconss > 0);
6880  }
6881 
6882  /* free temporary memory */
6883  SCIPsetFreeBufferArray(set, &pseudocoefs);
6884  SCIPsetFreeBufferArray(set, &curvarubs);
6885  SCIPsetFreeBufferArray(set, &curvarlbs);
6886  SCIPsetFreeBufferArray(set, &ubchginfoposs);
6887  SCIPsetFreeBufferArray(set, &lbchginfoposs);
6888 
6889  /* flush conflict set storage */
6890  SCIP_CALL( SCIPconflictFlushConss(conflict, blkmem, set, stat, transprob, origprob, tree, lp, branchcand, eventqueue) );
6891 
6892  /* stop timing */
6893  SCIPclockStop(conflict->pseudoanalyzetime, set);
6894 
6895  return SCIP_OKAY;
6896 }
6897 
6898 /** gets time in seconds used for analyzing pseudo solution conflicts */
6900  SCIP_CONFLICT* conflict /**< conflict analysis data */
6901  )
6902 {
6903  assert(conflict != NULL);
6904 
6905  return SCIPclockGetTime(conflict->pseudoanalyzetime);
6906 }
6907 
6908 /** gets number of calls to pseudo solution conflict analysis */
6910  SCIP_CONFLICT* conflict /**< conflict analysis data */
6911  )
6912 {
6913  assert(conflict != NULL);
6914 
6915  return conflict->npseudocalls;
6916 }
6917 
6918 /** gets number of calls to pseudo solution conflict analysis that yield at least one conflict constraint */
6920  SCIP_CONFLICT* conflict /**< conflict analysis data */
6921  )
6922 {
6923  assert(conflict != NULL);
6924 
6925  return conflict->npseudosuccess;
6926 }
6927 
6928 /** gets number of conflict constraints detected in pseudo solution conflict analysis */
6930  SCIP_CONFLICT* conflict /**< conflict analysis data */
6931  )
6932 {
6933  assert(conflict != NULL);
6934 
6935  return conflict->npseudoconfconss;
6936 }
6937 
6938 /** gets total number of literals in conflict constraints created in pseudo solution conflict analysis */
6940  SCIP_CONFLICT* conflict /**< conflict analysis data */
6941  )
6942 {
6943  assert(conflict != NULL);
6944 
6945  return conflict->npseudoconfliterals;
6946 }
6947 
6948 /** gets number of reconvergence constraints detected in pseudo solution conflict analysis */
6950  SCIP_CONFLICT* conflict /**< conflict analysis data */
6951  )
6952 {
6953  assert(conflict != NULL);
6954 
6955  return conflict->npseudoreconvconss;
6956 }
6957 
6958 /** gets total number of literals in reconvergence constraints created in pseudo solution conflict analysis */
6960  SCIP_CONFLICT* conflict /**< conflict analysis data */
6961  )
6962 {
6963  assert(conflict != NULL);
6964 
6965  return conflict->npseudoreconvliterals;
6966 }
6967 
6968 /** enables or disables all clocks of \p conflict, depending on the value of the flag */
6970  SCIP_CONFLICT* conflict, /**< the conflict analysis data for which all clocks should be enabled or disabled */
6971  SCIP_Bool enable /**< should the clocks of the conflict analysis data be enabled? */
6972  )
6973 {
6974  assert(conflict != NULL);
6975 
6976  SCIPclockEnableOrDisable(conflict->boundlpanalyzetime, enable);
6977  SCIPclockEnableOrDisable(conflict->dIBclock, enable);
6978  SCIPclockEnableOrDisable(conflict->inflpanalyzetime, enable);
6979  SCIPclockEnableOrDisable(conflict->propanalyzetime, enable);
6980  SCIPclockEnableOrDisable(conflict->pseudoanalyzetime, enable);
6981  SCIPclockEnableOrDisable(conflict->sbanalyzetime, enable);
6982 }
6983 
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:51
void SCIPconflictEnableOrDisableClocks(SCIP_CONFLICT *conflict, SCIP_Bool enable)
Definition: conflict.c:6969
SCIP_Longint SCIPconflictGetNStrongbranchSuccess(SCIP_CONFLICT *conflict)
Definition: conflict.c:6687
static SCIP_Bool bdchginfoIsResolvable(SCIP_BDCHGINFO *bdchginfo)
Definition: conflict.c:2474
SCIP_Bool solisbasic
Definition: struct_lp.h:337
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:17106
int SCIPpqueueNElems(SCIP_PQUEUE *pqueue)
Definition: misc.c:880
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:4413
void SCIPconflicthdlrSetInit(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_DECL_CONFLICTINIT((*conflictinit)))
Definition: conflict.c:662
SCIP_Real sbup
Definition: struct_lp.h:141
SCIP_Longint ninflpconfliterals
SCIP_Longint SCIPconflictGetNLocalChgBds(SCIP_CONFLICT *conflict)
Definition: conflict.c:2436
SCIP_Real SCIPconflicthdlrGetTime(SCIP_CONFLICTHDLR *conflicthdlr)
Definition: conflict.c:782
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition: set.c:4669
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_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_COL *col, SCIP_Bool *downconflict, SCIP_Bool *upconflict)
Definition: conflict.c:6438
#define BMSfreeBlockMemoryArrayNull(mem, ptr, num)
Definition: memory.h:424
#define NUMSTOP
Definition: conflict.c:4950
unsigned int repropagate
SCIP_Longint ninflpreconvconss
SCIP_Longint SCIPconflictGetNPropConflictConss(SCIP_CONFLICT *conflict)
Definition: conflict.c:4326
SCIP_BDCHGIDX * SCIPbdchginfoGetIdx(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:17037
SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:4715
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:15788
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:431
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:2996
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:13661
int SCIPvarGetNBinImpls(SCIP_VAR *var, SCIP_Bool varfixing)
Definition: var.c:16662
SCIP_PROP * SCIPbdchginfoGetInferProp(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:17071
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:178
SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:1705
SCIP_Bool SCIPlpDiving(SCIP_LP *lp)
Definition: lp.c:19105
int conf_interconss
Definition: struct_set.h:159
int nubchginfos
Definition: struct_var.h:260
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:122
SCIP_BOUNDCHGTYPE SCIPbdchginfoGetChgtype(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:16997
SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
Definition: lpi_clp.cpp:2721
SCIP_CONFLICTHDLR ** conflicthdlrs
Definition: struct_set.h:67
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:3314
SCIP_Bool conf_dynamic
Definition: struct_set.h:180
SCIP_Real conflictlb
Definition: struct_var.h:210
static SCIP_Bool isBoundchgUseless(SCIP_SET *set, SCIP_BDCHGINFO *bdchginfo)
Definition: conflict.c:2839
SCIP_Bool conf_repropagate
Definition: struct_set.h:176
SCIP_Longint SCIPconflictGetNPropSuccess(SCIP_CONFLICT *conflict)
Definition: conflict.c:4316
void SCIPconflicthdlrSetExit(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_DECL_CONFLICTEXIT((*conflictexit)))
Definition: conflict.c:673
SCIP_PQUEUE * bdchgqueue
SCIP_Bool primalfeasible
Definition: struct_lp.h:335
SCIP_Longint nsbcalls
#define SCIPsetAllocBuffer(set, ptr)
Definition: set.h:1762
int nlpicols
Definition: struct_lp.h:290
SCIP_Bool SCIPsetIsFeasEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5007
void SCIPconflicthdlrSetInitsol(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_DECL_CONFLICTINITSOL((*conflictinitsol)))
Definition: conflict.c:684
int SCIPbdchginfoGetDepth(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:17017
SCIP_Longint SCIPconflictGetNBoundexceedingLPConflictConss(SCIP_CONFLICT *conflict)
Definition: conflict.c:6381
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:15968
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:4954
SCIP_PARAMDATA * SCIPparamGetData(SCIP_PARAM *param)
Definition: paramset.c:663
SCIP_Longint SCIPconflictGetNAppliedGlobalConss(SCIP_CONFLICT *conflict)
Definition: conflict.c:2416
SCIP_Longint SCIPconflictGetNBoundexceedingLPIterations(SCIP_CONFLICT *conflict)
Definition: conflict.c:6421
SCIP_CLOCK * conflictlptime
Definition: struct_stat.h:122
#define SCIP_MAXSTRLEN
Definition: def.h:196
SCIP_Bool conf_usesb
Definition: struct_set.h:169
SCIP_Bool conf_useinflp
Definition: struct_set.h:167
SCIP_BDCHGINFO * SCIPvarGetBdchgInfo(SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: var.c:15122
void SCIPgmlWriteArc(FILE *file, unsigned int source, unsigned int target, const char *label, const char *color)
Definition: misc.c:244
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:6959
SCIP_RETCODE SCIPlpiGetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
Definition: lpi_clp.cpp:3567
internal methods for clocks and timing issues
SCIP_Longint SCIPconflictGetNGlobalChgBds(SCIP_CONFLICT *conflict)
Definition: conflict.c:2406
SCIP_Bool conf_usepseudo
Definition: struct_set.h:171
SCIP_BOUNDCHG * boundchgs
Definition: struct_var.h:123
SCIP_Bool SCIPsetIsPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:4762
#define NULL
Definition: lpi_spx.cpp:129
SCIP_Bool conf_useprop
Definition: struct_set.h:166
SCIP_Longint nappliedlocliterals
SCIP_CLOCK * inflpanalyzetime
SCIP_Real SCIPvarGetBdAtIndex(SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: var.c:15325
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:16426
SCIP_Real * bdchgubs
struct SCIP_ParamData SCIP_PARAMDATA
Definition: type_paramset.h:73
SCIP_Longint SCIPconflictGetNPseudoConflictLiterals(SCIP_CONFLICT *conflict)
Definition: conflict.c:6939
SCIP_RETCODE SCIPbdchginfoCreate(SCIP_BDCHGINFO **bdchginfo, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_Real oldbound, SCIP_Real newbound)
Definition: var.c:14966
void SCIPconflicthdlrSetCopy(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_DECL_CONFLICTCOPY((*conflictcopy)))
Definition: conflict.c:640
SCIP_Longint SCIPconflictGetNInfeasibleLPSuccess(SCIP_CONFLICT *conflict)
Definition: conflict.c:6291
SCIP_Longint nappliedglbliterals
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
Definition: lp.c:18637
SCIP_Longint SCIPconflictGetNPropCalls(SCIP_CONFLICT *conflict)
Definition: conflict.c:4306
SCIP_Longint npseudoreconvliterals
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:16380
int SCIPnodeGetDepth(SCIP_NODE *node)
Definition: tree.c:6709
void SCIPgmlWriteNode(FILE *file, unsigned int id, const char *label, const char *nodetype, const char *fillcolor, const char *bordercolor)
Definition: misc.c:102
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:6737
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:16604
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:941
static SCIP_RETCODE conflictAddConflictBound(SCIP_CONFLICT *conflict, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_BDCHGINFO *bdchginfo, SCIP_Real relaxedbd)
Definition: conflict.c:2796
int SCIPprobGetNVars(SCIP_PROB *prob)
Definition: prob.c:2145
SCIP_BDCHGINFO * ubchginfos
Definition: struct_var.h:240
int conf_maxlploops
Definition: struct_set.h:153
SCIP_COL ** cols
Definition: struct_lp.h:279
void SCIPgmlWriteClosing(FILE *file)
Definition: misc.c:304
int nlpirows
Definition: struct_lp.h:293
SCIP_Longint nappliedglbconss
SCIP_Real SCIPvarGetLbLP(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:12120
SCIP_RETCODE SCIPvarScaleVSIDS(SCIP_VAR *var, SCIP_Real scalar)
Definition: var.c:13747
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:402
void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:350
SCIP_Longint SCIPconflictGetNInfeasibleLPReconvergenceConss(SCIP_CONFLICT *conflict)
Definition: conflict.c:6321
SCIP_Longint SCIPconflictGetNInfeasibleLPReconvergenceLiterals(SCIP_CONFLICT *conflict)
Definition: conflict.c:6331
#define FALSE
Definition: def.h:52
SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:1830
static void skipRedundantBdchginfos(SCIP_VAR *var, int *lbchginfopos, int *ubchginfopos)
Definition: conflict.c:4727
static SCIP_BDCHGINFO * conflictFirstCand(SCIP_CONFLICT *conflict)
Definition: conflict.c:3358
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:4227
SCIP_Longint nlocchgbds
SCIP_Bool solved
Definition: struct_lp.h:334
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:280
SCIP_Bool conf_fullshortenconflict
Definition: struct_set.h:192
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:7579
SCIP_Bool SCIPsetIsZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:4751
#define TRUE
Definition: def.h:51
#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:4336
SCIP_Real * relaxedbds
SCIP_Real SCIPbdchginfoGetNewbound(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:16977
unsigned int basisstatus
Definition: struct_lp.h:233
int nlbchginfos
Definition: struct_var.h:258
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:136
#define SCIPsetAllocBufferArray(set, ptr, num)
Definition: set.h:1757
int SCIPtreeGetCurrentDepth(SCIP_TREE *tree)
Definition: tree.c:7213
SCIP_Bool SCIPbdchgidxIsEarlier(SCIP_BDCHGIDX *bdchgidx1, SCIP_BDCHGIDX *bdchgidx2)
Definition: var.c:16947
SCIP_Bool conf_removable
Definition: struct_set.h:181
SCIP_Longint npropcalls
unsigned int sbdownvalid
Definition: struct_lp.h:175
void * SCIPpqueueFirst(SCIP_PQUEUE *pqueue)
Definition: misc.c:866
SCIP_RETCODE SCIPconflicthdlrExitsol(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_SET *set)
Definition: conflict.c:551
int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
Definition: set.c:4264
unsigned int basisstatus
Definition: struct_lp.h:166
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:290
SCIP_Real dualfarkas
Definition: struct_lp.h:202
#define EPSGE(x, y, eps)
Definition: def.h:151
SCIP_Real SCIPvarGetLbAtIndex(SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: var.c:15141
void SCIPpqueueFree(SCIP_PQUEUE **pqueue)
Definition: misc.c:777
static void conflictsetClear(SCIP_CONFLICTSET *conflictset)
Definition: conflict.c:916
SCIP_ROW ** SCIPlpGetRows(SCIP_LP *lp)
Definition: lp.c:18890
SCIP_Bool diving
Definition: struct_lp.h:345
#define SCIPdebugMessage
Definition: pub_message.h:77
SCIP_RETCODE SCIPconflictFree(SCIP_CONFLICT **conflict, BMS_BLKMEM *blkmem)
Definition: conflict.c:2604
SCIP_Longint SCIPconflictGetNAppliedLiterals(SCIP_CONFLICT *conflict)
Definition: conflict.c:2396
SCIP_Real SCIPlpGetPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:14953
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:2940
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_RETCODE SCIPnodeAddBoundchg(SCIP_NODE *node, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_VAR *var, SCIP_Real newbound, SCIP_BOUNDTYPE boundtype, SCIP_Bool probingchange)
Definition: tree.c:1892
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:16227
SCIP_Bool SCIPvarIsInLP(SCIP_VAR *var)
Definition: var.c:16104
int SCIPbdchgidxGetPos(SCIP_BDCHGIDX *bdchgidx)
Definition: var.c:16917
static SCIP_RETCODE conflictQueueBound(SCIP_CONFLICT *conflict, SCIP_SET *set, SCIP_BDCHGINFO *bdchginfo, SCIP_Real relaxedbd)
Definition: conflict.c:2859
internal methods for handling parameter settings
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_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_Bool *success)
Definition: conflict.c:6069
SCIP_Real SCIProwGetConstant(SCIP_ROW *row)
Definition: lp.c:18603
SCIP_Bool conf_enable
Definition: struct_set.h:165
SCIP_Bool SCIPsetIsNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:4773
void SCIPconflicthdlrSetExitsol(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_DECL_CONFLICTEXITSOL((*conflictexitsol)))
Definition: conflict.c:695
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:4286
#define SCIPsetFreeBufferArray(set, ptr)
Definition: set.h:1761
unsigned int basisstatus
Definition: struct_lp.h:99
#define BMSfreeMemory(ptr)
Definition: memory.h:117
void SCIPvarAdjustLb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *lb)
Definition: var.c:6005
int SCIPbdchginfoGetPos(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:17027
SCIP_Longint SCIPconflictGetNStrongbranchReconvergenceLiterals(SCIP_CONFLICT *conflict)
Definition: conflict.c:6727
SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2556
SCIP_Real SCIPconflictGetPseudoTime(SCIP_CONFLICT *conflict)
Definition: conflict.c:6899
SCIP_BDCHGINFO * SCIPvarGetBdchgInfoLb(SCIP_VAR *var, int pos)
Definition: var.c:16786
SCIP_COL ** lpicols
Definition: struct_lp.h:275
#define SCIP_DECL_CONFLICTEXIT(x)
Definition: type_conflict.h:76
SCIP_Longint nappliedlocconss
SCIP_Longint SCIPconflictGetNInfeasibleLPConflictLiterals(SCIP_CONFLICT *conflict)
Definition: conflict.c:6311
SCIP_Longint SCIPconflictGetNPropReconvergenceConss(SCIP_CONFLICT *conflict)
Definition: conflict.c:4346
SCIP_LPSOLSTAT SCIPlpGetSolstat(SCIP_LP *lp)
Definition: lp.c:14823
int conflictlbcount
Definition: struct_var.h:261
internal methods for LP management
SCIP_Longint npseudosuccess
SCIP_Bool conf_preferbinary
Definition: struct_set.h:172
SCIP_Real SCIPconflictGetVarUb(SCIP_CONFLICT *conflict, SCIP_VAR *var)
Definition: conflict.c:3298
internal methods for branching and inference history
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_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue)
Definition: conflict.c:2200
SCIP_Real SCIPconflictGetStrongbranchTime(SCIP_CONFLICT *conflict)
Definition: conflict.c:6667
SCIP_Real lpiuobjlim
Definition: struct_lp.h:267
SCIP_Longint SCIPconflictGetNAppliedLocalLiterals(SCIP_CONFLICT *conflict)
Definition: conflict.c:2456
SCIP_Bool strongbranching
Definition: struct_lp.h:342
SCIP_Longint SCIPconflictGetNPseudoConflictConss(SCIP_CONFLICT *conflict)
Definition: conflict.c:6929
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:188
int SCIPlpGetNCols(SCIP_LP *lp)
Definition: lp.c:18880
SCIP_Real SCIPvarGetUbLP(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:12190
SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:4739
SCIP_HISTORY * glbhistorycrun
Definition: struct_stat.h:131
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:15907
int SCIPtreeGetFocusDepth(SCIP_TREE *tree)
Definition: tree.c:7138
#define SCIPdebugCheckConflict(blkmem, set, node, bdchginfos, relaxedbds, nliterals)
Definition: debug.h:242
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:15979
SCIP_VAR * SCIPbdchginfoGetInferVar(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:17047
void SCIPhistoryScaleVSIDS(SCIP_HISTORY *history, SCIP_Real scalar)
Definition: history.c:445
SCIP_Longint npropconfconss
SCIP_Longint nboundlpcalls
SCIP_Real * vals
Definition: struct_lp.h:214
SCIP_BOUNDTYPE SCIPbdchginfoGetBoundtype(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:17007
enum SCIP_BranchDir SCIP_BRANCHDIR
Definition: type_history.h:39
SCIP_Real conflictrelaxedub
Definition: struct_var.h:213
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:3581
SCIP_VAR * SCIPbdchginfoGetVar(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:16987
SCIP_Bool SCIPsetIsLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:4703
int SCIPcolGetLPPos(SCIP_COL *col)
Definition: lp.c:18448
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:137
int lpiitlim
Definition: struct_lp.h:317
SCIP_Real lb
Definition: struct_lp.h:126
SCIP_Real dualsol
Definition: struct_lp.h:200
SCIP_Real conflictrelaxedlb
Definition: struct_var.h:212
static SCIP_RETCODE detectImpliedBounds(SCIP_SET *set, SCIP_PROB *prob, SCIP_CONFLICTSET *conflictset, int *nbdchgs, int *nredvars, SCIP_Bool *redundant)
Definition: conflict.c: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:4591
#define SCIP_DECL_CONFLICTINITSOL(x)
Definition: type_conflict.h:87
SCIP_CLOCK * boundlpanalyzetime
SCIP_Longint SCIPconflictGetNInfeasibleLPConflictConss(SCIP_CONFLICT *conflict)
Definition: conflict.c:6301
SCIP_Real sbdown
Definition: struct_lp.h:140
SCIP_Longint ninflpreconvliterals
#define SCIP_DECL_CONFLICTEXEC(x)
SCIP_BDCHGINFO ** tmpbdchginfos
SCIP_CLOCK * conflicttime
#define BMSfreeMemoryArray(ptr)
Definition: memory.h:120
SCIP_Real conf_maxvarsfac
Definition: struct_set.h:151
void SCIPhistoryIncNActiveConflicts(SCIP_HISTORY *history, SCIP_BRANCHDIR dir, SCIP_Real length)
Definition: history.c:470
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:18647
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:6401
SCIP_Bool misc_resetstat
Definition: struct_set.h:307
SCIP_COL ** cols
Definition: struct_lp.h:212
void SCIPclockReset(SCIP_CLOCK *clck)
Definition: clock.c:199
SCIP_Longint nconflictlpiterations
Definition: struct_stat.h:62
SCIP_Bool SCIPsetIsRelEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5422
int lp_disablecutoff
Definition: struct_set.h:275
SCIP_Real SCIPvarGetUbAtIndex(SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: var.c:15233
SCIP_CONFLICTHDLRDATA * conflicthdlrdata
SCIP_NODE ** path
Definition: struct_tree.h:164
SCIP_Longint SCIPconflictGetNPseudoReconvergenceConss(SCIP_CONFLICT *conflict)
Definition: conflict.c:6949
SCIP_ROW ** lpirows
Definition: struct_lp.h:276
unsigned int sbupvalid
Definition: struct_lp.h:177
SCIP_Bool SCIPlpiHasDualRay(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2427
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:7557
SCIP_Longint SCIPconflictGetNAppliedLocalConss(SCIP_CONFLICT *conflict)
Definition: conflict.c:2446
SCIP_Real lhs
Definition: struct_lp.h:191
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:2905
SCIP_Longint npropreconvconss
unsigned int pos
Definition: struct_var.h:111
SCIP_Bool SCIProwIsLocal(SCIP_ROW *row)
Definition: lp.c:18746
SCIP_Real SCIPconflictGetBoundexceedingLPTime(SCIP_CONFLICT *conflict)
Definition: conflict.c:6351
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:182
SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:3670
SCIP_Bool SCIPbdchginfoIsRedundant(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:17115
SCIP_Real SCIPsetFeasCeil(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5157
#define SCIPsetReallocBufferArray(set, ptr, num)
Definition: set.h:1759
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:266
SCIP_Longint SCIPconflictGetNStrongbranchReconvergenceConss(SCIP_CONFLICT *conflict)
Definition: conflict.c:6717
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition: var.c:16093
SCIP_HISTORY * glbhistory
Definition: struct_stat.h:130
SCIP_Bool SCIPconsIsGlobal(SCIP_CONS *cons)
Definition: cons.c:7766
#define REALABS(x)
Definition: def.h:146
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:156
SCIP_VAR ** SCIPvarGetMultaggrVars(SCIP_VAR *var)
Definition: var.c:16159
void SCIPgmlWriteEdge(FILE *file, unsigned int source, unsigned int target, const char *label, const char *color)
Definition: misc.c:200
SCIP_RETCODE SCIPconflicthdlrFree(SCIP_CONFLICTHDLR **conflicthdlr, SCIP_SET *set)
Definition: conflict.c:432
SCIP_Longint SCIPconflictGetNStrongbranchConflictLiterals(SCIP_CONFLICT *conflict)
Definition: conflict.c:6707
struct SCIP_ConflicthdlrData SCIP_CONFLICTHDLRDATA
Definition: type_conflict.h:40
internal methods for global SCIP settings
#define SCIP_CALL(x)
Definition: def.h:258
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:5071
int SCIPlpGetNRows(SCIP_LP *lp)
Definition: lp.c:18900
#define SCIP_DECL_CONFLICTCOPY(x)
Definition: type_conflict.h:52
int SCIPconsGetValidDepth(SCIP_CONS *cons)
Definition: cons.c:7630
SCIP_Longint SCIPconflictGetNPseudoSuccess(SCIP_CONFLICT *conflict)
Definition: conflict.c:6919
SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2374
const char * SCIProwGetName(SCIP_ROW *row)
Definition: lp.c:18696
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:2039
SCIP_Bool conf_settlelocal
Definition: struct_set.h:174
SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:4691
SCIP_Real vsidsweight
Definition: struct_stat.h:95
SCIP_RETCODE SCIPsetConflicthdlrPriority(SCIP *scip, SCIP_CONFLICTHDLR *conflicthdlr, int priority)
Definition: scip.c:5849
SCIP_LPI * SCIPlpGetLPI(SCIP_LP *lp)
Definition: lp.c:19052
SCIP_Real conf_conflictgraphweight
Definition: struct_set.h:198
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:274
const char * SCIPconflicthdlrGetName(SCIP_CONFLICTHDLR *conflicthdlr)
Definition: conflict.c:706
SCIP_Longint SCIPconflictGetNInfeasibleLPCalls(SCIP_CONFLICT *conflict)
Definition: conflict.c:6281
SCIP_Real conf_scorefac
Definition: struct_set.h:183
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:3412
void * SCIPpqueueRemove(SCIP_PQUEUE *pqueue)
Definition: misc.c:825
SCIP_CLOCK * sbanalyzetime
SCIP_Bool SCIPsetIsFeasLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5039
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:5162
#define BMSduplicateMemoryArray(ptr, source, num)
Definition: memory.h:111
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_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_Bool *success)
Definition: conflict.c:6759
SCIP_Bool SCIPbdchginfoIsTighter(SCIP_BDCHGINFO *bdchginfo1, SCIP_BDCHGINFO *bdchginfo2)
Definition: var.c:17140
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:5408
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:417
methods for VBC Tool output
SCIP_Longint nboundlpreconvconss
int conf_lpiterations
Definition: struct_set.h:155
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:16436
SCIP_Bool SCIPsetIsIntegral(SCIP_SET *set, SCIP_Real val)
Definition: set.c:4784
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:1129
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_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_CONFLICTSET *conflictset, int insertdepth, SCIP_Bool *success)
Definition: conflict.c:2064
int SCIPvarGetIndex(SCIP_VAR *var)
Definition: var.c:16062
#define SCIP_Bool
Definition: def.h:49
#define SCIPsetFreeBuffer(set, ptr)
Definition: set.h:1767
SCIP_Real redcost
Definition: struct_lp.h:86
SCIP_Real SCIPsetSumepsilon(SCIP_SET *set)
Definition: set.c:4563
#define BMSallocBlockMemoryArray(mem, ptr, num)
Definition: memory.h:386
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:680
SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
Definition: lpi_clp.cpp:3465
int ncontvars
Definition: struct_prob.h:64
unsigned int depth
Definition: struct_tree.h:138
static const char * paramname[]
Definition: lpi_msk.c:4129
SCIP_Bool SCIPconflictApplicable(SCIP_SET *set)
Definition: conflict.c:2511
SCIP_Bool conf_useboundlp
Definition: struct_set.h:168
SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
Definition: lpi_clp.cpp:3613
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_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_Bool *success)
Definition: conflict.c:6137
int mem_arraygrowinit
Definition: struct_set.h:293
SCIP_Bool conf_seperate
Definition: struct_set.h:179
void SCIPclockFree(SCIP_CLOCK **clck)
Definition: clock.c:175
SCIP_Bool SCIPlpDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:19115
#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:152
SCIP_Real conflictub
Definition: struct_var.h:211
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:2102
SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
Definition: lpi_clp.cpp:2798
SCIP_Longint SCIPconflictGetNStrongbranchConflictConss(SCIP_CONFLICT *conflict)
Definition: conflict.c:6697
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:149
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:16147
void ** SCIPpqueueElems(SCIP_PQUEUE *pqueue)
Definition: misc.c:891
SCIP_BOUNDTYPE SCIPboundtypeOpposite(SCIP_BOUNDTYPE boundtype)
Definition: lp.c:18548
int SCIPvarGetNVlbs(SCIP_VAR *var)
Definition: var.c:16562
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:102
static SCIP_Real conflictsetCalcScore(SCIP_CONFLICTSET *conflictset)
Definition: conflict.c:1029
int SCIPconflictGetNConflicts(SCIP_CONFLICT *conflict)
Definition: conflict.c:2376
SCIP_Real * SCIPvarGetMultaggrScalars(SCIP_VAR *var)
Definition: var.c:16171
SCIP_Longint SCIPconflictGetNBoundexceedingLPCalls(SCIP_CONFLICT *conflict)
Definition: conflict.c:6361
SCIP_RETCODE SCIPconflictInit(SCIP_CONFLICT *conflict, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob)
Definition: conflict.c:2649
void SCIPsortIntPtrReal(int *intarray, void **ptrarray, SCIP_Real *realarray, int len)
#define CONFLICTSETSCORE(conflictset)
Definition: conflict.c:143
int nconflicthdlrs
Definition: struct_set.h:89
SCIP_BOUNDTYPE SCIPbdchginfoGetInferBoundtype(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:17094
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:5023
SCIP_Longint nsbconfliterals
SCIP_Longint SCIPconflictGetNBoundexceedingLPReconvergenceLiterals(SCIP_CONFLICT *conflict)
Definition: conflict.c:6411
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:13797
SCIP_ROW ** rows
Definition: struct_lp.h:281
SCIP_Longint nboundlpiterations
SCIP_Bool SCIPprobIsTransformed(SCIP_PROB *prob)
Definition: prob.c:2080
int conflictubcount
Definition: struct_var.h:262
SCIP_Longint npseudoconfliterals
SCIP_Longint ninflpconfconss
#define SCIP_REAL_MAX
Definition: def.h:124
SCIP_Bool SCIPsetIsDualfeasPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5281
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:718
SCIP_Real rhs
Definition: struct_lp.h:192
SCIP_Longint SCIPconflictGetNPseudoCalls(SCIP_CONFLICT *conflict)
Definition: conflict.c:6909
SCIP_Real constant
Definition: struct_lp.h:190
static void lpbdchgsFree(SCIP_LPBDCHGS **lpbdchgs, SCIP_SET *set)
Definition: conflict.c:832
#define SCIP_REAL_MIN
Definition: def.h:125
SCIP_CONFLICTHDLRDATA * SCIPconflicthdlrGetData(SCIP_CONFLICTHDLR *conflicthdlr)
Definition: conflict.c:619
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:15953
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:5146
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:4374
SCIP_DOMCHGBOUND domchgbound
Definition: struct_var.h:151
SCIP_Real SCIPconflictGetInfeasibleLPTime(SCIP_CONFLICT *conflict)
Definition: conflict.c:6271
SCIP_RETCODE SCIPconflictCreate(SCIP_CONFLICT **conflict, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: conflict.c:2527
SCIP_Real SCIPbdchginfoGetOldbound(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:16967
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:16370
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_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_Bool diving, int *iterations, int *nconss, int *nliterals, int *nreconvconss, int *nreconvliterals, SCIP_Bool marklpunsolved)
Definition: conflict.c:5536
void SCIPvbcFoundConflict(SCIP_VBC *vbc, SCIP_STAT *stat, SCIP_NODE *node)
Definition: vbc.c:430
SCIP_Longint SCIPconflictGetNBoundexceedingLPSuccess(SCIP_CONFLICT *conflict)
Definition: conflict.c:6371
SCIP_LPSOLSTAT lpsolstat
Definition: struct_lp.h:108
unsigned int boundtype
Definition: struct_var.h:113
SCIP_Longint lastconflictnode
Definition: struct_stat.h:82
internal methods for conflict analysis
SCIP_RETCODE SCIPpqueueInsert(SCIP_PQUEUE *pqueue, void *elem)
Definition: misc.c:798
static const SCIP_Real scalars[]
Definition: lp.c:5431
SCIP_Longint nsbsuccess
int lpipos
Definition: struct_lp.h:160
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip.c:1239
SCIP_RETCODE SCIPpqueueCreate(SCIP_PQUEUE **pqueue, int initsize, SCIP_Real sizefac, SCIP_DECL_SORTPTRCOMP((*ptrcomp)))
Definition: misc.c:752
void SCIPsetSortConflicthdlrs(SCIP_SET *set)
Definition: set.c:3029
SCIP_Bool SCIPbdchgidxIsEarlierNonNull(SCIP_BDCHGIDX *bdchgidx1, SCIP_BDCHGIDX *bdchgidx2)
Definition: var.c:16927
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:4554
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:333
int nrows
Definition: struct_lp.h:306
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:187
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:16072
SCIP_Real * conflictsetscores
SCIP_Bool conf_allowlocal
Definition: struct_set.h:173
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:3057
SCIP_Bool SCIPsetIsGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:4727
SCIP_Real lpobjval
Definition: struct_lp.h:253
SCIP_Real primsol
Definition: struct_lp.h:85
#define SCIP_Real
Definition: def.h:123
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:16736
SCIP_Longint npseudocalls
#define MIN(x, y)
Definition: memory.c:59
int conf_maxconss
Definition: struct_set.h:161
SCIP_Longint SCIPconflictGetNStrongbranchCalls(SCIP_CONFLICT *conflict)
Definition: conflict.c:6677
SCIP_Longint SCIPconflictGetNInfeasibleLPIterations(SCIP_CONFLICT *conflict)
Definition: conflict.c:6341
SCIP_Real SCIPconflictGetVarLb(SCIP_CONFLICT *conflict, SCIP_VAR *var)
Definition: conflict.c:3281
SCIP_RETCODE SCIPconflictIsVarUsed(SCIP_CONFLICT *conflict, SCIP_VAR *var, SCIP_SET *set, SCIP_BOUNDTYPE boundtype, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool *used)
Definition: conflict.c:3221
#define BMSallocMemory(ptr)
Definition: memory.h:92
#define SCIP_INVALID
Definition: def.h:142
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:80
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:135
SCIP_Longint nsbiterations
SCIP_Longint SCIPconflictGetNAppliedGlobalLiterals(SCIP_CONFLICT *conflict)
Definition: conflict.c:2426
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_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_Bool *success)
Definition: conflict.c:6002
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:3947
#define SCIP_Longint
Definition: def.h:107
int SCIPbdchginfoGetInferInfo(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:17082
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:5055
int SCIProwGetLPPos(SCIP_ROW *row)
Definition: lp.c:18826
SCIP_Longint npseudoconfconss
SCIP_Bool dualfeasible
Definition: struct_lp.h:336
static void conflictFreeTmpBdchginfos(SCIP_CONFLICT *conflict, BMS_BLKMEM *blkmem)
Definition: conflict.c:900
SCIP_Longint SCIPconflictGetNAppliedConss(SCIP_CONFLICT *conflict)
Definition: conflict.c:2386
SCIP_Real newbound
Definition: struct_var.h:107
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:16052
SCIP_Longint SCIPconflictGetNBoundexceedingLPConflictLiterals(SCIP_CONFLICT *conflict)
Definition: conflict.c:6391
void SCIPgmlWriteOpening(FILE *file, SCIP_Bool directed)
Definition: misc.c:288
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:4482
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:14996
SCIP_BDCHGINFO ** bdchginfos
void SCIPvarAdjustUb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *ub)
Definition: var.c:6022
static SCIP_Bool conflictMarkBoundCheckPresence(SCIP_CONFLICT *conflict, SCIP_BDCHGINFO *bdchginfo, SCIP_Real relaxedbd)
Definition: conflict.c:2708
#define BMSallocBlockMemory(mem, ptr)
Definition: memory.h:404
SCIP_Longint SCIPconflictGetNPropReconvergenceLiterals(SCIP_CONFLICT *conflict)
Definition: conflict.c:4356
SCIP_Bool SCIPsetIsDualfeasNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5292
SCIP_CONFLICTSET ** conflictsets
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:98
SCIP_Real SCIPconflictGetPropTime(SCIP_CONFLICT *conflict)
Definition: conflict.c:4296
SCIP_Bool conflicthdlrssorted
Definition: struct_set.h:117
common defines and data types used in all packages of SCIP
SCIP_Longint nnodes
Definition: struct_stat.h:63
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:371
SCIP_RETCODE SCIPvarGetProbvarSum(SCIP_VAR **var, SCIP_SET *set, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:11835
SCIP_Real conf_conflictweight
Definition: struct_set.h:195
#define SCIP_DECL_CONFLICTFREE(x)
Definition: type_conflict.h:60
SCIP_NODE * root
Definition: struct_tree.h:162
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
Definition: lp.c:18407
static SCIP_RETCODE conflictResolveBound(SCIP_CONFLICT *conflict, SCIP_SET *set, SCIP_BDCHGINFO *bdchginfo, SCIP_Real relaxedbd, int validdepth, SCIP_Bool *resolved)
Definition: conflict.c:3511
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:4759
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:3719
void SCIPpqueueClear(SCIP_PQUEUE *pqueue)
Definition: misc.c:788
#define SCIP_ALLOC(x)
Definition: def.h:269
#define SCIPABORT()
Definition: def.h:230
SCIP_CONS * SCIPbdchginfoGetInferCons(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:17059
SCIP_LPSOLSTAT lpsolstat
Definition: struct_lp.h:322
SCIP_VBC * vbc
Definition: struct_stat.h:133
void SCIPnodeCutoff(SCIP_NODE *node, SCIP_SET *set, SCIP_STAT *stat, SCIP_TREE *tree)
Definition: tree.c:1104
int conf_reconvlevels
Definition: struct_set.h:163
const char * SCIPprobGetName(SCIP_PROB *prob)
Definition: prob.c:2136
int ncols
Definition: struct_lp.h:300
static void conflictClear(SCIP_CONFLICT *conflict)
Definition: conflict.c:2637
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:390
unsigned int local
Definition: struct_lp.h:242
const char * SCIPpropGetName(SCIP_PROP *prop)
Definition: prop.c:872
SCIP_Real activity
Definition: struct_lp.h:201
SCIP_Bool * usedcols
int len
Definition: struct_lp.h:220
SCIP callable library.
SCIP_BDCHGINFO * SCIPvarGetBdchgInfoUb(SCIP_VAR *var, int pos)
Definition: var.c:16806
SCIP_Bool SCIPbdchginfoHasInferenceReason(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:17126
SCIP_BDCHGINFO * lbchginfos
Definition: struct_var.h:239
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:6829
int conf_fuiplevels
Definition: struct_set.h:157