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