SCIP Doxygen Documentation
 
Loading...
Searching...
No Matches
conflict.c
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the program and library */
4/* SCIP --- Solving Constraint Integer Programs */
5/* */
6/* Copyright (c) 2002-2023 Zuse Institute Berlin (ZIB) */
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 inferred 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
189static FILE* confgraphfile = NULL; /**< output file for current conflict graph */
190static SCIP_BDCHGINFO* confgraphcurrentbdchginfo = NULL; /**< currently resolved bound change */
191static int confgraphnconflictsets = 0; /**< number of conflict sets marked in the graph */
192
193/** writes a node section to the conflict graph file */
194static
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{
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 */
209static
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{
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 */
226static
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);
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
250
251 confgraphWriteNode(NULL, "conflict", "ellipse", "#ff0000", "#000000");
252
254
255 return SCIP_OKAY;
256}
257
258/** closes conflict graph file */
259static
260void confgraphFree(
261 void
262 )
263{
264 if( confgraphfile != NULL )
265 {
267
269
272 }
273}
274
275/** adds a bound change node to the conflict graph and links it to the currently resolved bound change */
276static
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
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
310 else
315 confgraphWriteNode(bdchginfo, label, "ellipse", colors[col], "#000000");
317}
318
319/** links the already existing bound change node to the currently resolved bound change */
320static
322 SCIP_BDCHGINFO* bdchginfo /**< bound change to add to the conflict graph */
323 )
324{
326}
327
328/** marks the given bound change to be the currently resolved bound change */
329static
331 SCIP_BDCHGINFO* bdchginfo /**< bound change to add to the conflict graph */
332 )
333{
335}
336
337/** marks given conflict set in the conflict graph */
338static
340 SCIP_CONFLICTSET* conflictset /**< conflict set */
341 )
342{
343 char label[SCIP_MAXSTRLEN];
344 int i;
345
346 assert(conflictset != NULL);
347
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 */
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 */
372
373/** method to call, when the priority of a conflict handler was changed */
374static
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{
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 */
408static
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{
429
431 assert(name != NULL);
432 assert(desc != NULL);
433
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{
483 assert(name != NULL);
484 assert(desc != NULL);
485
486 SCIP_CALL_FINALLY( doConflicthdlrCreate(conflicthdlr, set, messagehdlr, blkmem, name, desc, priority,
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{
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);
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{
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{
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{
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{
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{
653 assert(set != NULL);
654 assert(bdchginfos != NULL || nbdchginfos == 0);
655 assert(result != NULL);
656
657 /* call solution start method of conflict handler */
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
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{
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{
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{
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{
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{
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{
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{
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{
767
768 conflicthdlr->conflictexitsol = conflictexitsol;
769}
770
771/** gets name of conflict handler */
773 SCIP_CONFLICTHDLR* conflicthdlr /**< conflict handler */
774 )
775{
777
778 return conflicthdlr->name;
779}
780
781/** gets description of conflict handler */
783 SCIP_CONFLICTHDLR* conflicthdlr /**< conflict handler */
784 )
785{
787
788 return conflicthdlr->desc;
789}
790
791/** gets priority of conflict handler */
793 SCIP_CONFLICTHDLR* conflicthdlr /**< conflict handler */
794 )
795{
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{
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{
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{
832
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{
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{
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 */
863static
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{
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 */
885static
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 */
898static
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
911}
912
913/*
914 * Proof Sets
915 */
916
917/** return the char associated with the type of the variable */
918static
920 SCIP_VAR* var /**< variable */
921 )
922{
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 */
931static
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 */
945static
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 */
966static
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 */
981static
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
998static
999void 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 */
1021static
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 */
1032static
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 */
1043static
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 */
1054static
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 */
1065static
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 */
1076static
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 */
1127static
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
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 */
1168static
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 */
1212static
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
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 */
1236static
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
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 */
1260static
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 */
1276static
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 */
1295static
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 */
1315static
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
1327
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 */
1352static
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 */
1368static
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
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 */
1398static
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 */
1412static
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
1440 * (SCIP_Real)(SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL))/(SCIP_Real)(SCIPcolGetNNonz(col));
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 */
1489static
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
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 invalid since a tight/weaker bound change was already explained */
1510 {
1511 if( var->conflictlbcount != conflict->count || var->conflictlb != SCIPbdchginfoGetNewbound(bdchginfo) ) /*lint !e777*/
1512 {
1514 return TRUE;
1515 }
1516 }
1517 else
1518 {
1520
1521 if( var->conflictubcount != conflict->count || var->conflictub != SCIPbdchginfoGetNewbound(bdchginfo) ) /*lint !e777*/
1522 {
1524 return TRUE;
1525 }
1526 }
1527
1528 return FALSE;
1529}
1530
1531/** adds a bound change to a conflict set */
1532static
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;
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
1599 conflictset->hasrelaxonlyvar = TRUE;
1600
1601 return SCIP_OKAY;
1602}
1603
1604/** adds given bound changes to a conflict set */
1605static
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{
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 {
1646 }
1647 else
1648 {
1649 SCIPsetDebugMsg(set, "-> bound change info [%d:<%s> %s %g] is invalid -> ignore it\n", SCIPbdchginfoGetDepth(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 */
1681
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 */
1693
1695 conflictset->hasrelaxonlyvar = TRUE;
1696 }
1697 else
1698 {
1699 SCIPsetDebugMsg(set, "-> bound change info [%d:<%s> %s %g] is invalid -> ignore it\n", SCIPbdchginfoGetDepth(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 */
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 {
1725 ++i;
1727 {
1728 /* replace worse bound change info by tighter bound change info */
1732 ++i;
1733 }
1734 else
1735 {
1737
1738 /* both bound change are equivalent; hence, keep the worse relaxed bound and remove one of them */
1740 ++i;
1741 }
1742 }
1743 else
1744 {
1745 /* all bound change infos must be valid */
1747
1748 ++k;
1749 /* move next comparison element to the correct position */
1750 if( k != i )
1751 {
1755 }
1756 ++i;
1757 }
1758 }
1759 /* last bound change infos must also be valid */
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 */
1774static
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 */
1818static
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
1838 assert(currentdepth == tree->pathlen-1);
1839
1840 /* mark the levels for which a branching variable is included in the conflict set */
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 */
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 */
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 */
1865static
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
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 */
1907static
1908void 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]),
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 */
1927static
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
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 */
1951static
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
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 */
1976static
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 */
1996static
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: ");
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 */
2090static
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 */
2108static
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{
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
2131 SCIP_CALL( SCIPvarIncVSIDS(var, blkmem, set, stat, branchdir, value, weight) );
2134
2135 return SCIP_OKAY;
2136}
2137
2138/** update conflict statistics */
2139static
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;
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
2174
2175 SCIP_CALL( SCIPvarIncNActiveConflicts(var, blkmem, set, stat, branchdir, bound, (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 */
2193static
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);
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 {
2231 bound += 1.0;
2232 }
2233
2234 /* check if the bound is already fulfilled globally */
2236 return TRUE;
2237 }
2238 else
2239 {
2241
2243 {
2245 bound -= 1.0;
2246 }
2247
2248 /* check if the bound is already fulfilled globally */
2250 return TRUE;
2251 }
2252 }
2253
2254 return FALSE;
2255}
2256
2257/** find global fixings which can be derived from the new conflict set */
2258static
2260 SCIP_SET* set, /**< global SCIP settings */
2261 SCIP_PROB* prob, /**< transformed problem after presolve */
2262 SCIP_STAT* stat, /**< dynamic SCIP statistics */
2263 SCIP_TREE* tree, /**< tree data */
2264 BMS_BLKMEM* blkmem, /**< block memory */
2265 SCIP_PROB* origprob, /**< original problem */
2266 SCIP_REOPT* reopt, /**< reoptimization data */
2267 SCIP_LP* lp, /**< LP data */
2268 SCIP_CONFLICTSET* conflictset, /**< conflict set to add to the tree */
2269 int* nbdchgs, /**< number of global deducted bound changes due to the conflict set */
2270 int* nredvars, /**< number of redundant and removed variables from conflict set */
2271 SCIP_Bool* redundant /**< did we found a global reduction on a conflict set variable, which makes this conflict redundant */
2272 )
2273{
2274 SCIP_BDCHGINFO** bdchginfos;
2275 SCIP_Real* relaxedbds;
2276 SCIP_VAR* var;
2277 SCIP_Bool* boundtypes;
2278 SCIP_Real* bounds;
2279 SCIP_Longint* nbinimpls;
2280 int* sortvals;
2281 SCIP_Real bound;
2282 SCIP_Bool isupper;
2283 int ntrivialredvars;
2284 int nbdchginfos;
2285 int nzeroimpls;
2286 int v;
2287
2288 assert(set != NULL);
2289 assert(prob != NULL);
2291 assert(conflictset != NULL);
2292 assert(nbdchgs != NULL);
2293 assert(nredvars != NULL);
2294 /* only check conflict sets with more than one variable */
2295 assert(conflictset->nbdchginfos > 1);
2296
2297 *nbdchgs = 0;
2298 *nredvars = 0;
2299
2300 /* due to other conflict in the same conflict analysis, this conflict set might have become redundant */
2301 *redundant = checkRedundancy(set, conflictset);
2302
2303 if( *redundant )
2304 return SCIP_OKAY;
2305
2306 bdchginfos = conflictset->bdchginfos;
2307 relaxedbds = conflictset->relaxedbds;
2308 nbdchginfos = conflictset->nbdchginfos;
2309 sortvals = conflictset->sortvals;
2310
2311 assert(bdchginfos != NULL);
2312 assert(relaxedbds != NULL);
2313 assert(sortvals != NULL);
2314
2315 /* check if the boolean representation of boundtypes matches the 'standard' definition */
2316 assert(SCIP_BOUNDTYPE_LOWER == FALSE); /*lint !e641 !e506*/
2317 assert(SCIP_BOUNDTYPE_UPPER == TRUE); /*lint !e641 !e506*/
2318
2319 ntrivialredvars = 0;
2320
2321 /* due to multiple conflict sets for one conflict, it can happen, that we already have redundant information in the
2322 * conflict set
2323 */
2324 for( v = nbdchginfos - 1; v >= 0; --v )
2325 {
2326 var = SCIPbdchginfoGetVar(bdchginfos[v]);
2327 bound = relaxedbds[v];
2329
2330 /* for integral variable we can increase/decrease the conflicting bound */
2331 if( SCIPvarIsIntegral(var) )
2332 bound += (isupper ? -1.0 : +1.0);
2333
2334 /* if conflict variable cannot fulfill the conflict we can remove it */
2337 {
2338 SCIPsetDebugMsg(set, "remove redundant variable <%s> from conflict set\n", SCIPvarGetName(var));
2339
2340 bdchginfos[v] = bdchginfos[nbdchginfos - 1];
2341 relaxedbds[v] = relaxedbds[nbdchginfos - 1];
2342 sortvals[v] = sortvals[nbdchginfos - 1];
2343
2344 --nbdchginfos;
2346 }
2347 }
2348 assert(ntrivialredvars + nbdchginfos == conflictset->nbdchginfos);
2349
2350 SCIPsetDebugMsg(set, "trivially removed %d redundant of %d variables from conflictset (%p)\n", ntrivialredvars, conflictset->nbdchginfos, (void*)conflictset);
2351 conflictset->nbdchginfos = nbdchginfos;
2352
2353 /* all variables where removed, the conflict cannot be fulfilled, i.e., we have an infeasibility proof */
2354 if( conflictset->nbdchginfos == 0 )
2355 return SCIP_OKAY;
2356
2357 /* do not check to big or trivial conflicts */
2358 if( conflictset->nbdchginfos > set->conf_maxvarsdetectimpliedbounds || conflictset->nbdchginfos == 1 )
2359 {
2361 return SCIP_OKAY;
2362 }
2363
2364 /* create array of boundtypes, and bound values in conflict set */
2365 SCIP_CALL( SCIPsetAllocBufferArray(set, &boundtypes, nbdchginfos) );
2366 SCIP_CALL( SCIPsetAllocBufferArray(set, &bounds, nbdchginfos) );
2367 /* memory for the estimates for binary implications used for sorting */
2369
2370 nzeroimpls = 0;
2371
2372 /* collect estimates and initialize variables, boundtypes, and bounds array */
2373 for( v = 0; v < nbdchginfos; ++v )
2374 {
2375 var = SCIPbdchginfoGetVar(bdchginfos[v]);
2376 boundtypes[v] = (SCIP_Bool) SCIPboundtypeOpposite(SCIPbdchginfoGetBoundtype(bdchginfos[v]));
2377 bounds[v] = relaxedbds[v];
2378
2380
2381 /* check if the relaxed bound is really a relaxed bound */
2382 assert(SCIPbdchginfoGetBoundtype(bdchginfos[v]) == SCIP_BOUNDTYPE_LOWER || SCIPsetIsGE(set, relaxedbds[v], SCIPbdchginfoGetNewbound(bdchginfos[v])));
2383 assert(SCIPbdchginfoGetBoundtype(bdchginfos[v]) == SCIP_BOUNDTYPE_UPPER || SCIPsetIsLE(set, relaxedbds[v], SCIPbdchginfoGetNewbound(bdchginfos[v])));
2384
2385 /* for continuous variables, we can only use the relaxed version of the bounds negation: !(x <= u) -> x >= u */
2386 if( SCIPvarIsBinary(var) )
2387 {
2388 if( !boundtypes[v] )
2389 {
2390 assert(SCIPsetIsZero(set, bounds[v]));
2391 bounds[v] = 1.0;
2393 }
2394 else
2395 {
2396 assert(SCIPsetIsEQ(set, bounds[v], 1.0));
2397 bounds[v] = 0.0;
2399 }
2400 }
2401 else if( SCIPvarIsIntegral(var) )
2402 {
2403 assert(SCIPsetIsIntegral(set, bounds[v]));
2404
2405 bounds[v] += ((!boundtypes[v]) ? +1.0 : -1.0);
2406 nbinimpls[v] = (boundtypes[v] ? SCIPvarGetNVlbs(var) : SCIPvarGetNVubs(var));
2407 }
2408 else if( ((!boundtypes[v]) && SCIPsetIsFeasEQ(set, SCIPvarGetLbGlobal(var), bounds[v]))
2409 || ((boundtypes[v]) && SCIPsetIsFeasEQ(set, SCIPvarGetUbGlobal(var), bounds[v])) )
2410 {
2411 /* the literal is satisfied in global bounds (may happen due to weak "negation" of continuous variables)
2412 * -> discard the conflict constraint
2413 */
2414 break;
2415 }
2416 else
2417 {
2418 nbinimpls[v] = (boundtypes[v] ? SCIPvarGetNVlbs(var) : SCIPvarGetNVubs(var));
2419 }
2420
2421 if( nbinimpls[v] == 0 )
2422 ++nzeroimpls;
2423 }
2424
2425 /* starting to derive global bound changes */
2426 if( v == nbdchginfos && ((!set->conf_fullshortenconflict && nzeroimpls < 2) || (set->conf_fullshortenconflict && nzeroimpls < nbdchginfos)) )
2427 {
2428 SCIP_VAR** vars;
2429 SCIP_Bool* redundants;
2430 SCIP_Bool glbinfeas;
2431
2432 /* sort variables in increasing order of binary implications to gain speed later on */
2433 SCIPsortLongPtrRealRealBool(nbinimpls, (void**)bdchginfos, relaxedbds, bounds, boundtypes, v);
2434
2435 SCIPsetDebugMsg(set, "checking for global reductions and redundant conflict variables(in %s) on conflict:\n", SCIPprobGetName(prob));
2436 SCIPsetDebugMsg(set, "[");
2437 for( v = 0; v < nbdchginfos; ++v )
2438 {
2439 SCIPsetDebugMsgPrint(set, "%s %s %g", SCIPvarGetName(SCIPbdchginfoGetVar(bdchginfos[v])), (!boundtypes[v]) ? ">=" : "<=", bounds[v]);
2440 if( v < nbdchginfos - 1 )
2442 }
2443 SCIPsetDebugMsgPrint(set, "]\n");
2444
2447
2448 /* initialize conflict variable data */
2449 for( v = 0; v < nbdchginfos; ++v )
2450 vars[v] = SCIPbdchginfoGetVar(bdchginfos[v]);
2451
2452 SCIP_CALL( SCIPshrinkDisjunctiveVarSet(set->scip, vars, bounds, boundtypes, redundants, nbdchginfos, nredvars, \
2453 nbdchgs, redundant, &glbinfeas, set->conf_fullshortenconflict) );
2454
2455 if( glbinfeas )
2456 {
2457 SCIPsetDebugMsg(set, "conflict set (%p) led to global infeasibility\n", (void*) conflictset);
2458
2459 SCIP_CALL( SCIPnodeCutoff(SCIPtreeGetRootNode(tree), set, stat, tree, prob, origprob, reopt, lp, blkmem) );
2460
2461 /* clear the memory array before freeing it */
2462 BMSclearMemoryArray(redundants, nbdchginfos);
2463 goto TERMINATE;
2464 }
2465
2466#ifdef SCIP_DEBUG
2467 if( *nbdchgs > 0 )
2468 {
2469 SCIPsetDebugMsg(set, "conflict set (%p) led to %d global bound reductions\n", (void*) conflictset, *nbdchgs);
2470 }
2471#endif
2472
2473 /* remove as redundant marked variables */
2474 if( *redundant )
2475 {
2476 SCIPsetDebugMsg(set, "conflict set (%p) is redundant because at least one global reduction, fulfills the conflict constraint\n", (void*)conflictset);
2477
2478 /* clear the memory array before freeing it */
2479 BMSclearMemoryArray(redundants, nbdchginfos);
2480 }
2481 else if( *nredvars > 0 )
2482 {
2483 assert(bdchginfos == conflictset->bdchginfos);
2484 assert(relaxedbds == conflictset->relaxedbds);
2485 assert(sortvals == conflictset->sortvals);
2486
2487 for( v = nbdchginfos - 1; v >= 0; --v )
2488 {
2489 /* if conflict variable was marked to be redundant remove it */
2490 if( redundants[v] )
2491 {
2492 SCIPsetDebugMsg(set, "remove redundant variable <%s> from conflict set\n", SCIPvarGetName(SCIPbdchginfoGetVar(bdchginfos[v])));
2493
2494 bdchginfos[v] = bdchginfos[nbdchginfos - 1];
2495 relaxedbds[v] = relaxedbds[nbdchginfos - 1];
2496 sortvals[v] = sortvals[nbdchginfos - 1];
2497
2498 /* reset redundants[v] to 0 */
2499 redundants[v] = 0;
2500
2501 --nbdchginfos;
2502 }
2503 }
2504 assert((*nredvars) + nbdchginfos == conflictset->nbdchginfos);
2505
2506 SCIPsetDebugMsg(set, "removed %d redundant of %d variables from conflictset (%p)\n", (*nredvars), conflictset->nbdchginfos, (void*)conflictset);
2507 conflictset->nbdchginfos = nbdchginfos;
2508 }
2509 else
2510 {
2511 /* clear the memory array before freeing it */
2512 BMSclearMemoryArray(redundants, nbdchginfos);
2513 }
2514
2515 TERMINATE:
2518 }
2519
2520 /* free temporary memory */
2522 SCIPsetFreeBufferArray(set, &bounds);
2523 SCIPsetFreeBufferArray(set, &boundtypes);
2524
2526
2527 return SCIP_OKAY;
2528}
2529
2530/** tighten the bound of a singleton variable in a constraint
2531 *
2532 * if the bound is contradicting with a global bound we cannot tighten the bound directly.
2533 * in this case we need to create and add a constraint of size one such that propagating this constraint will
2534 * enforce the infeasibility.
2535 */
2536static
2538 SCIP_CONFLICT* conflict, /**< conflict analysis data */
2539 SCIP_SET* set, /**< global SCIP settings */
2540 SCIP_STAT* stat, /**< dynamic SCIP statistics */
2541 SCIP_TREE* tree, /**< tree data */
2542 BMS_BLKMEM* blkmem, /**< block memory */
2543 SCIP_PROB* origprob, /**< original problem */
2544 SCIP_PROB* transprob, /**< transformed problem */
2545 SCIP_REOPT* reopt, /**< reoptimization data */
2546 SCIP_LP* lp, /**< LP data */
2547 SCIP_BRANCHCAND* branchcand, /**< branching candidates */
2548 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2549 SCIP_CLIQUETABLE* cliquetable, /**< clique table */
2550 SCIP_VAR* var, /**< problem variable */
2551 SCIP_Real val, /**< coefficient of the variable */
2552 SCIP_Real rhs, /**< rhs of the constraint */
2553 SCIP_CONFTYPE prooftype, /**< type of the proof */
2554 int validdepth /**< depth where the bound change is valid */
2555 )
2556{
2557 SCIP_Real newbound;
2558 SCIP_Bool applyglobal;
2559 SCIP_BOUNDTYPE boundtype;
2560
2561 assert(tree != NULL);
2562 assert(validdepth >= 0);
2563
2564 applyglobal = (validdepth <= SCIPtreeGetEffectiveRootDepth(tree));
2565
2566 /* if variable and coefficient are integral the rhs can be rounded down */
2568 newbound = SCIPsetFeasFloor(set, rhs)/val;
2569 else
2570 newbound = rhs/val;
2571
2572 boundtype = (val > 0.0 ? SCIP_BOUNDTYPE_UPPER : SCIP_BOUNDTYPE_LOWER);
2573 SCIPvarAdjustBd(var, set, boundtype, &newbound);
2574
2575 /* skip numerical unstable bound changes */
2576 if( applyglobal
2577 && ((boundtype == SCIP_BOUNDTYPE_LOWER && SCIPsetIsLE(set, newbound, SCIPvarGetLbGlobal(var)))
2578 || (boundtype == SCIP_BOUNDTYPE_UPPER && SCIPsetIsGE(set, newbound, SCIPvarGetUbGlobal(var)))) )
2579 {
2580 return SCIP_OKAY;
2581 }
2582
2583 /* the new bound contradicts a global bound, we can cutoff the root node immediately */
2584 if( applyglobal
2585 && ((boundtype == SCIP_BOUNDTYPE_LOWER && SCIPsetIsGT(set, newbound, SCIPvarGetUbGlobal(var)))
2586 || (boundtype == SCIP_BOUNDTYPE_UPPER && SCIPsetIsLT(set, newbound, SCIPvarGetLbGlobal(var)))) )
2587 {
2588 SCIPsetDebugMsg(set, "detected global infeasibility at var <%s>: locdom=[%g,%g] glbdom=[%g,%g] new %s bound=%g\n",
2591 (boundtype == SCIP_BOUNDTYPE_LOWER ? "lower" : "upper"), newbound);
2592 SCIP_CALL( SCIPnodeCutoff(tree->path[0], set, stat, tree, transprob, origprob, reopt, lp, blkmem) );
2593 }
2594 else
2595 {
2596 if( lp->strongbranching || !applyglobal )
2597 {
2598 SCIP_CONS* cons;
2599 SCIP_Real conslhs;
2600 SCIP_Real consrhs;
2601 char name[SCIP_MAXSTRLEN];
2602
2603 SCIPsetDebugMsg(set, "add constraint <%s>[%c] %s %g to node #%lld in depth %d\n",
2604 SCIPvarGetName(var), varGetChar(var), boundtype == SCIP_BOUNDTYPE_UPPER ? "<=" : ">=", newbound,
2605 SCIPnodeGetNumber(tree->path[validdepth]), validdepth);
2606
2607 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "pc_fix_%s", SCIPvarGetName(var));
2608
2609 if( boundtype == SCIP_BOUNDTYPE_UPPER )
2610 {
2612 consrhs = newbound;
2613 }
2614 else
2615 {
2616 conslhs = newbound;
2618 }
2619
2620 SCIP_CALL( SCIPcreateConsLinear(set->scip, &cons, name, 0, NULL, NULL, conslhs, consrhs,
2622
2623 SCIP_CALL( SCIPaddCoefLinear(set->scip, cons, var, 1.0) );
2624
2625 if( applyglobal )
2626 {
2627 SCIP_CALL( SCIPprobAddCons(transprob, set, stat, cons) );
2628 }
2629 else
2630 {
2631 SCIP_CALL( SCIPnodeAddCons(tree->path[validdepth], blkmem, set, stat, tree, cons) );
2632 }
2633
2634 SCIP_CALL( SCIPconsRelease(&cons, blkmem, set) );
2635 }
2636 else
2637 {
2639
2640 SCIPsetDebugMsg(set, "change global %s bound of <%s>[%c]: %g -> %g\n",
2641 (boundtype == SCIP_BOUNDTYPE_LOWER ? "lower" : "upper"),
2644 newbound);
2645
2646 SCIP_CALL( SCIPnodeAddBoundchg(tree->path[0], blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, \
2647 eventqueue, cliquetable, var, newbound, boundtype, FALSE) );
2648
2649 /* mark the node in the validdepth to be propagated again */
2650 SCIPnodePropagateAgain(tree->path[0], set, stat, tree);
2651 }
2652 }
2653
2654 if( applyglobal )
2655 ++conflict->nglbchgbds;
2656 else
2657 ++conflict->nlocchgbds;
2658
2660 {
2661 ++conflict->dualproofsinfnnonzeros; /* we count a global bound reduction as size 1 */
2662 ++conflict->ndualproofsinfsuccess;
2663 ++conflict->ninflpsuccess;
2664
2665 if( applyglobal )
2666 ++conflict->ndualproofsinfglobal;
2667 else
2668 ++conflict->ndualproofsinflocal;
2669 }
2670 else
2671 {
2672 ++conflict->dualproofsbndnnonzeros; /* we count a global bound reduction as size 1 */
2673 ++conflict->ndualproofsbndsuccess;
2674 ++conflict->nboundlpsuccess;
2675
2676 if( applyglobal )
2677 ++conflict->ndualproofsbndglobal;
2678 else
2679 ++conflict->ndualproofsbndlocal;
2680 }
2681
2682 return SCIP_OKAY;
2683}
2684
2685/** calculates the minimal activity of a given aggregation row */
2686static
2688 SCIP_SET* set, /**< global SCIP settings */
2689 SCIP_PROB* transprob, /**< transformed problem data */
2690 SCIP_AGGRROW* aggrrow, /**< aggregation row */
2691 SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables (or NULL for global bounds) */
2692 SCIP_Real* curvarubs, /**< current upper bounds of active problem variables (or NULL for global bounds) */
2693 SCIP_Bool* infdelta /**< pointer to store whether at least one variable contributes with an infinite value */
2694 )
2695{
2696 SCIP_VAR** vars;
2697 SCIP_Real QUAD(minact);
2698 int* inds;
2699 int nnz;
2700 int i;
2701
2702 vars = SCIPprobGetVars(transprob);
2703 assert(vars != NULL);
2704
2705 nnz = SCIPaggrRowGetNNz(aggrrow);
2706 inds = SCIPaggrRowGetInds(aggrrow);
2707
2708 QUAD_ASSIGN(minact, 0.0);
2709
2710 if( infdelta != NULL )
2711 *infdelta = FALSE;
2712
2713 for( i = 0; i < nnz; i++ )
2714 {
2715 SCIP_Real val;
2716 SCIP_Real QUAD(delta);
2717 int v = inds[i];
2718
2720
2721 val = SCIPaggrRowGetProbvarValue(aggrrow, v);
2722
2723 if( val > 0.0 )
2724 {
2725 SCIP_Real bnd = (curvarlbs == NULL ? SCIPvarGetLbGlobal(vars[v]) : curvarlbs[v]);
2726
2727 if( SCIPsetIsInfinity(set, -bnd) )
2728 {
2729 if( infdelta != NULL )
2730 *infdelta = TRUE;
2731
2732 return -SCIPsetInfinity(set);
2733 }
2734
2735 SCIPquadprecProdDD(delta, val, bnd);
2736 }
2737 else
2738 {
2739 SCIP_Real bnd = (curvarubs == NULL ? SCIPvarGetUbGlobal(vars[v]) : curvarubs[v]);
2740
2741 if( SCIPsetIsInfinity(set, bnd) )
2742 {
2743 if( infdelta != NULL )
2744 *infdelta = TRUE;
2745
2746 return -SCIPsetInfinity(set);
2747 }
2748
2749 SCIPquadprecProdDD(delta, val, bnd);
2750 }
2751
2752 /* update minimal activity */
2754 }
2755
2756 /* check whether the minimal activity is infinite */
2758 return SCIPsetInfinity(set);
2760 return -SCIPsetInfinity(set);
2761
2762 return QUAD_TO_DBL(minact);
2763}
2764
2765/** calculates the minimal activity of a given set of bounds and coefficients */
2766static
2768 SCIP_SET* set, /**< global SCIP settings */
2769 SCIP_PROB* transprob, /**< transformed problem data */
2770 SCIP_Real* coefs, /**< coefficients in sparse representation */
2771 int* inds, /**< non-zero indices */
2772 int nnz, /**< number of non-zero indices */
2773 SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables (or NULL for global bounds) */
2774 SCIP_Real* curvarubs /**< current upper bounds of active problem variables (or NULL for global bounds) */
2775 )
2776{
2777 SCIP_VAR** vars;
2778 SCIP_Real QUAD(minact);
2779 int i;
2780
2781 assert(coefs != NULL);
2782 assert(inds != NULL);
2783
2784 vars = SCIPprobGetVars(transprob);
2785 assert(vars != NULL);
2786
2787 QUAD_ASSIGN(minact, 0.0);
2788
2789 for( i = 0; i < nnz; i++ )
2790 {
2791 SCIP_Real val;
2792 SCIP_Real QUAD(delta);
2793 int v = inds[i];
2794
2796
2797 val = coefs[i];
2798
2799 if( val > 0.0 )
2800 {
2801 SCIP_Real bnd;
2802
2804
2806
2807 if( SCIPsetIsInfinity(set, -bnd) )
2808 return -SCIPsetInfinity(set);
2809
2810 SCIPquadprecProdDD(delta, val, bnd);
2811 }
2812 else
2813 {
2814 SCIP_Real bnd;
2815
2817
2819
2820 if( SCIPsetIsInfinity(set, bnd) )
2821 return -SCIPsetInfinity(set);
2822
2823 SCIPquadprecProdDD(delta, val, bnd);
2824 }
2825
2826 /* update minimal activity */
2828 }
2829
2830 /* check whether the minmal activity is infinite */
2832 return SCIPsetInfinity(set);
2834 return -SCIPsetInfinity(set);
2835
2836 return QUAD_TO_DBL(minact);
2837}
2838
2839/** calculates the minimal activity of a given set of bounds and coefficients */
2840static
2842 SCIP_SET* set, /**< global SCIP settings */
2843 SCIP_PROB* transprob, /**< transformed problem data */
2844 SCIP_Real* coefs, /**< coefficients in sparse representation */
2845 int* inds, /**< non-zero indices */
2846 int nnz, /**< number of non-zero indices */
2847 SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables (or NULL for global bounds) */
2848 SCIP_Real* curvarubs /**< current upper bounds of active problem variables (or NULL for global bounds) */
2849 )
2850{
2851 SCIP_VAR** vars;
2852 SCIP_Real QUAD(maxact);
2853 int i;
2854
2855 assert(coefs != NULL);
2856 assert(inds != NULL);
2857
2858 vars = SCIPprobGetVars(transprob);
2859 assert(vars != NULL);
2860
2861 QUAD_ASSIGN(maxact, 0.0);
2862
2863 for( i = 0; i < nnz; i++ )
2864 {
2865 SCIP_Real val;
2866 SCIP_Real QUAD(delta);
2867 int v = inds[i];
2868
2870
2871 val = coefs[i];
2872
2873 if( val < 0.0 )
2874 {
2875 SCIP_Real bnd;
2876
2878
2880
2881 if( SCIPsetIsInfinity(set, -bnd) )
2882 return SCIPsetInfinity(set);
2883
2884 SCIPquadprecProdDD(delta, val, bnd);
2885 }
2886 else
2887 {
2888 SCIP_Real bnd;
2889
2891
2893
2894 if( SCIPsetIsInfinity(set, bnd) )
2895 return SCIPsetInfinity(set);
2896
2897 SCIPquadprecProdDD(delta, val, bnd);
2898 }
2899
2900 /* update maximal activity */
2902 }
2903
2904 /* check whether the maximal activity got infinite */
2906 return SCIPsetInfinity(set);
2908 return -SCIPsetInfinity(set);
2909
2910 return QUAD_TO_DBL(maxact);
2911}
2912
2913static
2915 SCIP_CONFLICT* conflict, /**< conflict analysis data */
2916 SCIP_SET* set, /**< global SCIP settings */
2917 SCIP_STAT* stat, /**< dynamic SCIP statistics */
2918 SCIP_REOPT* reopt, /**< reoptimization data */
2919 SCIP_TREE* tree, /**< tree data */
2920 BMS_BLKMEM* blkmem, /**< block memory */
2921 SCIP_PROB* origprob, /**< original problem */
2922 SCIP_PROB* transprob, /**< transformed problem */
2923 SCIP_LP* lp, /**< LP data */
2924 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
2925 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2926 SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
2927 SCIP_Real* coefs, /**< coefficients in sparse representation */
2928 int* inds, /**< non-zero indices */
2929 int nnz, /**< number of non-zero indices */
2930 SCIP_Real rhs, /**< right-hand side */
2931 SCIP_CONFTYPE conflicttype, /**< type of the conflict */
2932 int validdepth /**< depth where the proof is valid */
2933 )
2934{
2935 SCIP_VAR** vars;
2936 SCIP_Real minact;
2937 int i;
2938
2939 assert(coefs != NULL);
2940 assert(inds != NULL);
2941 assert(nnz >= 0);
2942
2943 vars = SCIPprobGetVars(transprob);
2944 minact = getMinActivity(set, transprob, coefs, inds, nnz, NULL, NULL);
2945
2946 /* we cannot find global tightenings */
2948 return SCIP_OKAY;
2949
2950 for( i = 0; i < nnz; i++ )
2951 {
2952 SCIP_VAR* var;
2953 SCIP_Real val;
2954 SCIP_Real resminact;
2955 SCIP_Real lb;
2956 SCIP_Real ub;
2957 int pos;
2958
2959 pos = inds[i];
2960 val = coefs[i];
2961 var = vars[pos];
2962 lb = SCIPvarGetLbGlobal(var);
2963 ub = SCIPvarGetUbGlobal(var);
2964
2965 assert(!SCIPsetIsZero(set, val));
2966
2967 resminact = minact;
2968
2969 /* we got a potential new upper bound */
2970 if( val > 0.0 )
2971 {
2972 SCIP_Real newub;
2973
2974 resminact -= (val * lb);
2975 newub = (rhs - resminact)/val;
2976
2978 continue;
2979
2980 /* we cannot tighten the upper bound */
2981 if( SCIPsetIsGE(set, newub, ub) )
2982 continue;
2983
2984 SCIP_CALL( tightenSingleVar(conflict, set, stat, tree, blkmem, origprob, transprob, reopt, lp, branchcand, \
2985 eventqueue, cliquetable, var, val, rhs-resminact, conflicttype, validdepth) );
2986 }
2987 /* we got a potential new lower bound */
2988 else
2989 {
2990 SCIP_Real newlb;
2991
2992 resminact -= (val * ub);
2993 newlb = (rhs - resminact)/val;
2994
2995 if( SCIPsetIsInfinity(set, -newlb) )
2996 continue;
2997
2998 /* we cannot tighten the lower bound */
2999 if( SCIPsetIsLE(set, newlb, lb) )
3000 continue;
3001
3002 SCIP_CALL( tightenSingleVar(conflict, set, stat, tree, blkmem, origprob, transprob, reopt, lp, branchcand, \
3003 eventqueue, cliquetable, var, val, rhs-resminact, conflicttype, validdepth) );
3004 }
3005
3006 /* the minimal activity should stay unchanged because we tightened the bound that doesn't contribute to the
3007 * minimal activity
3008 */
3009 assert(SCIPsetIsEQ(set, minact, getMinActivity(set, transprob, coefs, inds, nnz, NULL, NULL)));
3010 }
3011
3012 return SCIP_OKAY;
3013}
3014
3015
3016/** creates a proof constraint and tries to add it to the storage */
3017static
3019 SCIP_CONFLICT* conflict, /**< conflict analysis data */
3020 SCIP_CONFLICTSTORE* conflictstore, /**< conflict pool data */
3021 SCIP_PROOFSET* proofset, /**< proof set */
3022 SCIP_SET* set, /**< global SCIP settings */
3023 SCIP_STAT* stat, /**< dynamic SCIP statistics */
3024 SCIP_PROB* origprob, /**< original problem */
3025 SCIP_PROB* transprob, /**< transformed problem */
3026 SCIP_TREE* tree, /**< tree data */
3027 SCIP_REOPT* reopt, /**< reoptimization data */
3028 SCIP_LP* lp, /**< LP data */
3029 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
3030 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3031 SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
3032 BMS_BLKMEM* blkmem /**< block memory */
3033 )
3034{
3035 SCIP_CONS* cons;
3037 SCIP_VAR** vars;
3038 SCIP_Real* coefs;
3039 int* inds;
3040 SCIP_Real rhs;
3041 SCIP_Real fillin;
3042 SCIP_Real globalminactivity;
3043 SCIP_Bool applyglobal;
3044 SCIP_Bool toolong;
3045 SCIP_Bool contonly;
3046 SCIP_Bool hasrelaxvar;
3047 SCIP_CONFTYPE conflicttype;
3048 char name[SCIP_MAXSTRLEN];
3049 int nnz;
3050 int i;
3051
3052 assert(conflict != NULL);
3053 assert(conflictstore != NULL);
3054 assert(proofset != NULL);
3055 assert(proofset->validdepth == 0 || proofset->validdepth < SCIPtreeGetFocusDepth(tree));
3056
3057 nnz = proofsetGetNVars(proofset);
3058
3059 if( nnz == 0 )
3060 return SCIP_OKAY;
3061
3062 vars = SCIPprobGetVars(transprob);
3063
3064 rhs = proofsetGetRhs(proofset);
3066
3067 coefs = proofsetGetVals(proofset);
3068 assert(coefs != NULL);
3069
3070 inds = proofsetGetInds(proofset);
3071 assert(inds != NULL);
3072
3073 conflicttype = proofsetGetConftype(proofset);
3074
3076
3077 if( applyglobal )
3078 {
3079 SCIP_Real globalmaxactivity = getMaxActivity(set, transprob, coefs, inds, nnz, NULL, NULL);
3080
3081 /* check whether the alternative proof is redundant */
3082 if( SCIPsetIsLE(set, globalmaxactivity, rhs) )
3083 return SCIP_OKAY;
3084
3085 /* check whether the constraint proves global infeasibility */
3086 globalminactivity = getMinActivity(set, transprob, coefs, inds, nnz, NULL, NULL);
3087 if( SCIPsetIsGT(set, globalminactivity, rhs) )
3088 {
3089 SCIPsetDebugMsg(set, "detect global infeasibility: minactivity=%g, rhs=%g\n", globalminactivity, rhs);
3090
3091 SCIP_CALL( SCIPnodeCutoff(tree->path[proofset->validdepth], set, stat, tree, transprob, origprob, reopt, lp, blkmem) );
3092
3093 goto UPDATESTATISTICS;
3094 }
3095 }
3096
3097 if( set->conf_minmaxvars >= nnz )
3098 toolong = FALSE;
3099 else
3100 {
3101 SCIP_Real maxnnz;
3102
3103 if( transprob->startnconss < 100 )
3104 maxnnz = 0.85 * transprob->nvars;
3105 else
3106 maxnnz = (SCIP_Real)transprob->nvars;
3107
3108 fillin = nnz;
3109 if( conflicttype == SCIP_CONFTYPE_INFEASLP || conflicttype == SCIP_CONFTYPE_ALTINFPROOF )
3110 {
3112 fillin /= (SCIPconflictstoreGetNDualInfProofs(conflictstore) + 1.0);
3113 toolong = (fillin > MIN(2.0 * stat->avgnnz, maxnnz));
3114 }
3115 else
3116 {
3117 assert(conflicttype == SCIP_CONFTYPE_BNDEXCEEDING || conflicttype == SCIP_CONFTYPE_ALTBNDPROOF);
3118
3120 fillin /= (SCIPconflictstoreGetNDualBndProofs(conflictstore) + 1.0);
3121 toolong = (fillin > MIN(1.5 * stat->avgnnz, maxnnz));
3122 }
3123
3124 toolong = (toolong && (nnz > set->conf_maxvarsfac * transprob->nvars));
3125 }
3126
3127 /* don't store global dual proofs that are too long / have too many non-zeros */
3128 if( toolong )
3129 {
3130 if( applyglobal )
3131 {
3132 SCIP_CALL( propagateLongProof(conflict, set, stat, reopt, tree, blkmem, origprob, transprob, lp, branchcand,
3133 eventqueue, cliquetable, coefs, inds, nnz, rhs, conflicttype, proofset->validdepth) );
3134 }
3135 return SCIP_OKAY;
3136 }
3137
3138 /* check if conflict contains variables that are invalid after a restart to label it appropriately */
3140 contonly = TRUE;
3141 for( i = 0; i < nnz && (!hasrelaxvar || contonly); ++i )
3142 {
3144
3145 if( SCIPvarIsIntegral(vars[inds[i]]) )
3146 contonly = FALSE;
3147 }
3148
3149 if( !applyglobal && contonly )
3150 return SCIP_OKAY;
3151
3152 if( conflicttype == SCIP_CONFTYPE_INFEASLP || conflicttype == SCIP_CONFTYPE_ALTINFPROOF )
3153 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "dualproof_inf_%" SCIP_LONGINT_FORMAT, conflict->ndualproofsinfsuccess);
3154 else if( conflicttype == SCIP_CONFTYPE_BNDEXCEEDING || conflicttype == SCIP_CONFTYPE_ALTBNDPROOF )
3155 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "dualproof_bnd_%" SCIP_LONGINT_FORMAT, conflict->ndualproofsbndsuccess);
3156 else
3157 return SCIP_INVALIDCALL;
3158
3159 SCIP_CALL( SCIPcreateConsLinear(set->scip, &cons, name, 0, NULL, NULL, -SCIPsetInfinity(set), rhs,
3161 FALSE, TRUE, TRUE, FALSE) );
3162
3163 for( i = 0; i < nnz; i++ )
3164 {
3165 int v = inds[i];
3166 SCIP_CALL( SCIPaddCoefLinear(set->scip, cons, vars[v], coefs[i]) );
3167 }
3168
3169 /* do not upgrade linear constraints of size 1 */
3170 if( nnz > 1 )
3171 {
3172 upgdcons = NULL;
3173 /* try to automatically convert a linear constraint into a more specific and more specialized constraint */
3174 SCIP_CALL( SCIPupgradeConsLinear(set->scip, cons, &upgdcons) );
3175 if( upgdcons != NULL )
3176 {
3177 SCIP_CALL( SCIPreleaseCons(set->scip, &cons) );
3178 cons = upgdcons;
3179
3180 if( conflicttype == SCIP_CONFTYPE_INFEASLP )
3181 conflicttype = SCIP_CONFTYPE_ALTINFPROOF;
3182 else if( conflicttype == SCIP_CONFTYPE_BNDEXCEEDING )
3183 conflicttype = SCIP_CONFTYPE_ALTBNDPROOF;
3184 }
3185 }
3186
3187 /* mark constraint to be a conflict */
3189
3190 /* add constraint to storage */
3191 if( conflicttype == SCIP_CONFTYPE_INFEASLP || conflicttype == SCIP_CONFTYPE_ALTINFPROOF )
3192 {
3193 /* add dual proof to storage */
3194 SCIP_CALL( SCIPconflictstoreAddDualraycons(conflictstore, cons, blkmem, set, stat, transprob, reopt, hasrelaxvar) );
3195 }
3196 else
3197 {
3198 SCIP_Real scale = 1.0;
3199 SCIP_Bool updateside = FALSE;
3200
3201 /* In some cases the constraint could not be updated to a more special type. However, it is possible that
3202 * constraint got scaled. Therefore, we need to be very careful when updating the lhs/rhs after the incumbent
3203 * solution has improved.
3204 */
3205 if( conflicttype == SCIP_CONFTYPE_BNDEXCEEDING )
3206 {
3207 SCIP_Real side;
3208
3209#ifndef NDEBUG
3210 SCIP_CONSHDLR* conshdlr = SCIPconsGetHdlr(cons);
3211
3212 assert(conshdlr != NULL);
3213 assert(strcmp(SCIPconshdlrGetName(conshdlr), "linear") == 0);
3214#endif
3215 side = SCIPgetLhsLinear(set->scip, cons);
3216
3217 if( !SCIPsetIsInfinity(set, -side) )
3218 {
3219 if( SCIPsetIsZero(set, side) )
3220 {
3221 scale = -1.0;
3222 }
3223 else
3224 {
3225 scale = proofsetGetRhs(proofset) / side;
3226 assert(SCIPsetIsNegative(set, scale));
3227 }
3228 }
3229 else
3230 {
3231 side = SCIPgetRhsLinear(set->scip, cons);
3232 assert(!SCIPsetIsInfinity(set, side));
3233
3234 if( SCIPsetIsZero(set, side) )
3235 {
3236 scale = 1.0;
3237 }
3238 else
3239 {
3240 scale = proofsetGetRhs(proofset) / side;
3241 assert(SCIPsetIsPositive(set, scale));
3242 }
3243 }
3244 updateside = TRUE;
3245 }
3246
3247 /* add dual proof to storage */
3248 SCIP_CALL( SCIPconflictstoreAddDualsolcons(conflictstore, cons, blkmem, set, stat, transprob, reopt, scale, updateside, hasrelaxvar) );
3249 }
3250
3251 if( applyglobal ) /*lint !e774*/
3252 {
3253 /* add the constraint to the global problem */
3254 SCIP_CALL( SCIPprobAddCons(transprob, set, stat, cons) );
3255 }
3256 else
3257 {
3258 SCIP_CALL( SCIPnodeAddCons(tree->path[proofset->validdepth], blkmem, set, stat, tree, cons) );
3259 }
3260
3261 SCIPsetDebugMsg(set, "added proof-constraint to node %p (#%lld) in depth %d (nproofconss %d)\n",
3262 (void*)tree->path[proofset->validdepth], SCIPnodeGetNumber(tree->path[proofset->validdepth]),
3263 proofset->validdepth,
3264 (conflicttype == SCIP_CONFTYPE_INFEASLP || conflicttype == SCIP_CONFTYPE_ALTINFPROOF)
3266
3267 /* release the constraint */
3268 SCIP_CALL( SCIPreleaseCons(set->scip, &cons) );
3269
3271 /* update statistics */
3272 if( conflicttype == SCIP_CONFTYPE_INFEASLP || conflicttype == SCIP_CONFTYPE_ALTINFPROOF )
3273 {
3274 conflict->dualproofsinfnnonzeros += nnz;
3275 if( applyglobal ) /*lint !e774*/
3276 ++conflict->ndualproofsinfglobal;
3277 else
3278 ++conflict->ndualproofsinflocal;
3279 ++conflict->ndualproofsinfsuccess;
3280 }
3281 else
3282 {
3283 assert(conflicttype == SCIP_CONFTYPE_BNDEXCEEDING || conflicttype == SCIP_CONFTYPE_ALTBNDPROOF);
3284 conflict->dualproofsbndnnonzeros += nnz;
3285 if( applyglobal ) /*lint !e774*/
3286 ++conflict->ndualproofsbndglobal;
3287 else
3288 ++conflict->ndualproofsbndlocal;
3289
3290 ++conflict->ndualproofsbndsuccess;
3291 }
3292 return SCIP_OKAY;
3293}
3294
3295/* create proof constraints out of proof sets */
3296static
3298 SCIP_CONFLICT* conflict, /**< conflict analysis data */
3299 SCIP_CONFLICTSTORE* conflictstore, /**< conflict store */
3300 BMS_BLKMEM* blkmem, /**< block memory */
3301 SCIP_SET* set, /**< global SCIP settings */
3302 SCIP_STAT* stat, /**< dynamic problem statistics */
3303 SCIP_PROB* transprob, /**< transformed problem after presolve */
3304 SCIP_PROB* origprob, /**< original problem */
3305 SCIP_TREE* tree, /**< branch and bound tree */
3306 SCIP_REOPT* reopt, /**< reoptimization data structure */
3307 SCIP_LP* lp, /**< current LP data */
3308 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
3309 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3310 SCIP_CLIQUETABLE* cliquetable /**< clique table data structure */
3311 )
3312{
3313 assert(conflict != NULL);
3314
3316 {
3317 /* only one variable has a coefficient different to zero, we add this bound change instead of a constraint */
3318 if( proofsetGetNVars(conflict->proofset) == 1 )
3319 {
3320 SCIP_VAR** vars;
3321 SCIP_Real* coefs;
3322 int* inds;
3323 SCIP_Real rhs;
3324
3325 vars = SCIPprobGetVars(transprob);
3326
3327 coefs = proofsetGetVals(conflict->proofset);
3328 inds = proofsetGetInds(conflict->proofset);
3329 rhs = proofsetGetRhs(conflict->proofset);
3330
3331 SCIP_CALL( tightenSingleVar(conflict, set, stat, tree, blkmem, origprob, transprob, reopt, lp, \
3332 branchcand, eventqueue, cliquetable, vars[inds[0]], coefs[0], rhs, conflict->proofset->conflicttype,
3333 conflict->proofset->validdepth) );
3334 }
3335 else
3336 {
3337 SCIP_Bool skipinitialproof = FALSE;
3338
3339 /* prefer an infeasibility proof
3340 *
3341 * todo: check whether this is really what we want
3342 */
3343 if( set->conf_prefinfproof && proofsetGetConftype(conflict->proofset) == SCIP_CONFTYPE_BNDEXCEEDING )
3344 {
3345 int i;
3346
3347 for( i = 0; i < conflict->nproofsets; i++ )
3348 {
3350 {
3352 break;
3353 }
3354 }
3355 }
3356
3357 if( !skipinitialproof )
3358 {
3359 /* create and add the original proof */
3360 SCIP_CALL( createAndAddProofcons(conflict, conflictstore, conflict->proofset, set, stat, origprob, transprob, \
3361 tree, reopt, lp, branchcand, eventqueue, cliquetable, blkmem) );
3362 }
3363 }
3364
3365 /* clear the proof set anyway */
3366 proofsetClear(conflict->proofset);
3367 }
3368
3369 if( conflict->nproofsets > 0 )
3370 {
3371 int i;
3372
3373 for( i = 0; i < conflict->nproofsets; i++ )
3374 {
3375 assert(conflict->proofsets[i] != NULL);
3377
3378 /* only one variable has a coefficient different to zero, we add this bound change instead of a constraint */
3379 if( proofsetGetNVars(conflict->proofsets[i]) == 1 )
3380 {
3381 SCIP_VAR** vars;
3382 SCIP_Real* coefs;
3383 int* inds;
3384 SCIP_Real rhs;
3385
3386 vars = SCIPprobGetVars(transprob);
3387
3388 coefs = proofsetGetVals(conflict->proofsets[i]);
3389 inds = proofsetGetInds(conflict->proofsets[i]);
3390 rhs = proofsetGetRhs(conflict->proofsets[i]);
3391
3392 SCIP_CALL( tightenSingleVar(conflict, set, stat, tree, blkmem, origprob, transprob, reopt, lp,
3393 branchcand, eventqueue, cliquetable, vars[inds[0]], coefs[0], rhs,
3394 conflict->proofsets[i]->conflicttype, conflict->proofsets[i]->validdepth) );
3395 }
3396 else
3397 {
3398 /* create and add proof constraint */
3399 SCIP_CALL( createAndAddProofcons(conflict, conflictstore, conflict->proofsets[i], set, stat, origprob, \
3400 transprob, tree, reopt, lp, branchcand, eventqueue, cliquetable, blkmem) );
3401 }
3402 }
3403
3404 /* free all proofsets */
3405 for( i = 0; i < conflict->nproofsets; i++ )
3406 proofsetFree(&conflict->proofsets[i], blkmem);
3407
3408 conflict->nproofsets = 0;
3409 }
3410
3411 return SCIP_OKAY;
3412}
3413
3414/** adds the given conflict set as conflict constraint to the problem */
3415static
3417 SCIP_CONFLICT* conflict, /**< conflict analysis data */
3418 BMS_BLKMEM* blkmem, /**< block memory */
3419 SCIP_SET* set, /**< global SCIP settings */
3420 SCIP_STAT* stat, /**< dynamic problem statistics */
3421 SCIP_PROB* transprob, /**< transformed problem after presolve */
3422 SCIP_PROB* origprob, /**< original problem */
3423 SCIP_TREE* tree, /**< branch and bound tree */
3424 SCIP_REOPT* reopt, /**< reoptimization data structure */
3425 SCIP_LP* lp, /**< current LP data */
3426 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
3427 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3428 SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
3429 SCIP_CONFLICTSET* conflictset, /**< conflict set to add to the tree */
3430 int insertdepth, /**< depth level at which the conflict set should be added */
3431 SCIP_Bool* success /**< pointer to store whether the addition was successful */
3432 )
3433{
3434 SCIP_Bool redundant;
3435 int h;
3436
3437 assert(conflict != NULL);
3438 assert(tree != NULL);
3439 assert(tree->path != NULL);
3440 assert(conflictset != NULL);
3441 assert(conflictset->validdepth <= insertdepth);
3442 assert(success != NULL);
3443
3444 *success = FALSE;
3445 redundant = FALSE;
3446
3447 /* try to derive global bound changes and shorten the conflictset by using implication and clique and variable bound
3448 * information
3449 */
3450 if( conflictset->nbdchginfos > 1 && insertdepth == 0 && !lp->strongbranching )
3451 {
3452 int nbdchgs;
3453 int nredvars;
3454#ifdef SCIP_DEBUG
3455 int oldnbdchginfos = conflictset->nbdchginfos;
3456#endif
3457 assert(conflictset->validdepth == 0);
3458
3459 /* check conflict set on debugging solution */
3460 SCIP_CALL( SCIPdebugCheckConflict(blkmem, set, tree->root, conflictset->bdchginfos, conflictset->relaxedbds, conflictset->nbdchginfos) );
3461
3462 SCIPclockStart(conflict->dIBclock, set);
3463
3464 /* find global bound changes which can be derived from the new conflict set */
3465 SCIP_CALL( detectImpliedBounds(set, transprob, stat, tree, blkmem, origprob, reopt, lp, conflictset, &nbdchgs, &nredvars, &redundant) );
3466
3467 /* all variables where removed, we have an infeasibility proof */
3468 if( conflictset->nbdchginfos == 0 )
3469 return SCIP_OKAY;
3470
3471 /* debug check for reduced conflict set */
3472 if( nredvars > 0 )
3473 {
3474 /* check conflict set on debugging solution */
3475 SCIP_CALL( SCIPdebugCheckConflict(blkmem, set, tree->root, conflictset->bdchginfos, conflictset->relaxedbds, conflictset->nbdchginfos) ); /*lint !e506 !e774*/
3476 }
3477
3478#ifdef SCIP_DEBUG
3479 SCIPsetDebugMsg(set, " -> conflict set removed %d redundant variables (old nvars %d, new nvars = %d)\n", nredvars, oldnbdchginfos, conflictset->nbdchginfos);
3480 SCIPsetDebugMsg(set, " -> conflict set led to %d global bound changes %s(cdpt:%d, fdpt:%d, confdpt:%d, len:%d):\n",
3481 nbdchgs, redundant ? "(conflict became redundant) " : "", SCIPtreeGetCurrentDepth(tree), SCIPtreeGetFocusDepth(tree),
3482 conflictset->conflictdepth, conflictset->nbdchginfos);
3483 conflictsetPrint(conflictset);
3484#endif
3485
3486 SCIPclockStop(conflict->dIBclock, set);
3487
3488 if( redundant )
3489 {
3490 if( nbdchgs > 0 )
3491 *success = TRUE;
3492
3493 return SCIP_OKAY;
3494 }
3495 }
3496
3497 /* in case the conflict set contains only one bound change which is globally valid we apply that bound change
3498 * directly (except if we are in strong branching or diving - in this case a bound change would yield an unflushed LP
3499 * and is not handled when restoring the information)
3500 *
3501 * @note A bound change can only be applied if it is are related to the active node or if is a global bound
3502 * change. Bound changes which are related to any other node cannot be handled at point due to the internal
3503 * data structure
3504 */
3505 if( conflictset->nbdchginfos == 1 && insertdepth == 0 && !lp->strongbranching && !lp->diving )
3506 {
3507 SCIP_VAR* var;
3508 SCIP_Real bound;
3509 SCIP_BOUNDTYPE boundtype;
3510
3511 var = conflictset->bdchginfos[0]->var;
3512 assert(var != NULL);
3513
3514 boundtype = SCIPboundtypeOpposite((SCIP_BOUNDTYPE) conflictset->bdchginfos[0]->boundtype);
3515 bound = conflictset->relaxedbds[0];
3516
3517 /* for continuous variables, we can only use the relaxed version of the bounds negation: !(x <= u) -> x >= u */
3518 if( SCIPvarIsIntegral(var) )
3519 {
3521 bound += (boundtype == SCIP_BOUNDTYPE_LOWER ? +1.0 : -1.0);
3522 }
3523
3524 SCIPsetDebugMsg(set, " -> apply global bound change: <%s> %s %g\n",
3525 SCIPvarGetName(var), boundtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", bound);
3526
3527 SCIP_CALL( SCIPnodeAddBoundchg(tree->path[conflictset->validdepth], blkmem, set, stat, transprob, origprob, tree,
3528 reopt, lp, branchcand, eventqueue, cliquetable, var, bound, boundtype, FALSE) );
3529
3530 *success = TRUE;
3531 SCIP_CALL( updateStatistics(conflict, blkmem, set, stat, conflictset, insertdepth) );
3532 }
3533 else if( !conflictset->hasrelaxonlyvar )
3534 {
3535 /* sort conflict handlers by priority */
3537
3538 /* call conflict handlers to create a conflict constraint */
3539 for( h = 0; h < set->nconflicthdlrs; ++h )
3540 {
3542
3543 assert(conflictset->conflicttype != SCIP_CONFTYPE_UNKNOWN);
3544
3545 SCIP_CALL( SCIPconflicthdlrExec(set->conflicthdlrs[h], set, tree->path[insertdepth],
3546 tree->path[conflictset->validdepth], conflictset->bdchginfos, conflictset->relaxedbds,
3547 conflictset->nbdchginfos, conflictset->conflicttype, conflictset->usescutoffbound, *success, &result) );
3548 if( result == SCIP_CONSADDED )
3549 {
3550 *success = TRUE;
3551 SCIP_CALL( updateStatistics(conflict, blkmem, set, stat, conflictset, insertdepth) );
3552 }
3553
3554 SCIPsetDebugMsg(set, " -> call conflict handler <%s> (prio=%d) to create conflict set with %d bounds returned result %d\n",
3555 SCIPconflicthdlrGetName(set->conflicthdlrs[h]), SCIPconflicthdlrGetPriority(set->conflicthdlrs[h]),
3556 conflictset->nbdchginfos, result);
3557 }
3558 }
3559 else
3560 {
3561 SCIPsetDebugMsg(set, " -> skip conflict set with relaxation-only variable\n");
3562 /* TODO would be nice to still create a constraint?, if we can make sure that we the constraint does not survive a restart */
3563 }
3564
3565 return SCIP_OKAY;
3566}
3567
3568/** adds the collected conflict constraints to the corresponding nodes; the best set->conf_maxconss conflict constraints
3569 * are added to the node of their validdepth; additionally (if not yet added, and if repropagation is activated), the
3570 * conflict constraint that triggers the earliest repropagation is added to the node of its validdepth
3571 */
3573 SCIP_CONFLICT* conflict, /**< conflict analysis data */
3574 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
3575 SCIP_SET* set, /**< global SCIP settings */
3576 SCIP_STAT* stat, /**< dynamic problem statistics */
3577 SCIP_PROB* transprob, /**< transformed problem */
3578 SCIP_PROB* origprob, /**< original problem */
3579 SCIP_TREE* tree, /**< branch and bound tree */
3580 SCIP_REOPT* reopt, /**< reoptimization data structure */
3581 SCIP_LP* lp, /**< current LP data */
3582 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
3583 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3584 SCIP_CLIQUETABLE* cliquetable /**< clique table data structure */
3585 )
3586{
3587 assert(conflict != NULL);
3588 assert(set != NULL);
3589 assert(stat != NULL);
3590 assert(transprob != NULL);
3591 assert(tree != NULL);
3592
3593 /* is there anything to do? */
3594 if( conflict->nconflictsets > 0 )
3595 {
3598 int focusdepth;
3599#ifndef NDEBUG
3600 int currentdepth;
3601#endif
3602 int cutoffdepth;
3603 int repropdepth;
3604 int maxconflictsets;
3605 int maxsize;
3606 int i;
3607
3608 /* calculate the maximal number of conflict sets to accept, and the maximal size of each accepted conflict set */
3609 maxconflictsets = (set->conf_maxconss == -1 ? INT_MAX : set->conf_maxconss);
3610 maxsize = conflictCalcMaxsize(set, transprob);
3611
3613#ifndef NDEBUG
3616 assert(currentdepth == tree->pathlen-1);
3617#endif
3618
3619 SCIPsetDebugMsg(set, "flushing %d conflict sets at focus depth %d (maxconflictsets: %d, maxsize: %d)\n",
3621
3622 /* mark the focus node to have produced conflict sets in the visualization output */
3623 SCIPvisualFoundConflict(stat->visual, stat, tree->path[focusdepth]);
3624
3625 /* insert the conflict sets at the corresponding nodes */
3627 cutoffdepth = INT_MAX;
3628 repropdepth = INT_MAX;
3630 for( i = 0; i < conflict->nconflictsets && nconflictsetsused < maxconflictsets; ++i )
3631 {
3632 SCIP_CONFLICTSET* conflictset;
3633
3634 conflictset = conflict->conflictsets[i];
3635 assert(conflictset != NULL);
3636 assert(0 <= conflictset->validdepth);
3637 assert(conflictset->validdepth <= conflictset->insertdepth);
3638 assert(conflictset->insertdepth <= focusdepth);
3639 assert(conflictset->insertdepth <= conflictset->repropdepth);
3640 assert(conflictset->repropdepth <= currentdepth || conflictset->repropdepth == INT_MAX); /* INT_MAX for dive/probing/strong */
3641 assert(conflictset->conflictdepth <= currentdepth || conflictset->conflictdepth == INT_MAX); /* INT_MAX for dive/probing/strong */
3642
3643 /* ignore conflict sets that are only valid at a node that was already cut off */
3644 if( conflictset->insertdepth >= cutoffdepth )
3645 {
3646 SCIPsetDebugMsg(set, " -> ignoring conflict set with insertdepth %d >= cutoffdepth %d\n",
3647 conflictset->validdepth, cutoffdepth);
3648 continue;
3649 }
3650
3651 /* if no conflict bounds exist, the node and its sub tree in the conflict set's valid depth can be
3652 * cut off completely
3653 */
3654 if( conflictset->nbdchginfos == 0 )
3655 {
3656 SCIPsetDebugMsg(set, " -> empty conflict set in depth %d cuts off sub tree at depth %d\n",
3657 focusdepth, conflictset->validdepth);
3658
3659 SCIP_CALL( SCIPnodeCutoff(tree->path[conflictset->validdepth], set, stat, tree, transprob, origprob, reopt, lp, blkmem) );
3660 cutoffdepth = conflictset->validdepth;
3661 continue;
3662 }
3663
3664 /* if the conflict set is too long, use the conflict set only if it decreases the repropagation depth */
3665 if( conflictset->nbdchginfos > maxsize )
3666 {
3667 SCIPsetDebugMsg(set, " -> conflict set is too long: %d > %d literals\n", conflictset->nbdchginfos, maxsize);
3668 if( set->conf_keepreprop && conflictset->repropagate && conflictset->repropdepth < repropdepth )
3669 {
3670 repropdepth = conflictset->repropdepth;
3671 repropconflictset = conflictset;
3672 }
3673 }
3674 else
3675 {
3676 SCIP_Bool success;
3677
3678 /* call conflict handlers to create a conflict constraint */
3679 SCIP_CALL( conflictAddConflictCons(conflict, blkmem, set, stat, transprob, origprob, tree, reopt, lp, \
3680 branchcand, eventqueue, cliquetable, conflictset, conflictset->insertdepth, &success) );
3681
3682 /* if no conflict bounds exist, the node and its sub tree in the conflict set's valid depth can be
3683 * cut off completely
3684 */
3685 if( conflictset->nbdchginfos == 0 )
3686 {
3687 assert(!success);
3688
3689 SCIPsetDebugMsg(set, " -> empty conflict set in depth %d cuts off sub tree at depth %d\n",
3690 focusdepth, conflictset->validdepth);
3691
3692 SCIP_CALL( SCIPnodeCutoff(tree->path[conflictset->validdepth], set, stat, tree, transprob, origprob, \
3693 reopt, lp, blkmem) );
3694 cutoffdepth = conflictset->validdepth;
3695 continue;
3696 }
3697
3698 if( success )
3699 {
3700 SCIPsetDebugMsg(set, " -> conflict set %d/%d added (cdpt:%d, fdpt:%d, insert:%d, valid:%d, conf:%d, reprop:%d, len:%d):\n",
3702 conflictset->insertdepth, conflictset->validdepth, conflictset->conflictdepth, conflictset->repropdepth,
3703 conflictset->nbdchginfos);
3704 SCIPdebug(conflictsetPrint(conflictset));
3705
3706 if( conflictset->repropagate && conflictset->repropdepth <= repropdepth )
3707 {
3708 repropdepth = conflictset->repropdepth;
3710 }
3712 }
3713 }
3714 }
3715
3716 /* reactivate propagation on the first node where one of the new conflict sets trigger a deduction */
3717 if( set->conf_repropagate && repropdepth < cutoffdepth && repropdepth < tree->pathlen )
3718 {
3719 assert(0 <= repropdepth && repropdepth < tree->pathlen);
3720 assert((int) tree->path[repropdepth]->depth == repropdepth);
3721
3722 /* if the conflict constraint of smallest repropagation depth was not yet added, insert it now */
3723 if( repropconflictset != NULL )
3724 {
3725 SCIP_Bool success;
3726
3727 assert(repropconflictset->repropagate);
3728 assert(repropconflictset->repropdepth == repropdepth);
3729
3730 SCIP_CALL( conflictAddConflictCons(conflict, blkmem, set, stat, transprob, origprob, tree, reopt, lp, \
3731 branchcand, eventqueue, cliquetable, repropconflictset, repropdepth, &success) );
3732
3733 /* if no conflict bounds exist, the node and its sub tree in the conflict set's valid depth can be
3734 * cut off completely
3735 */
3736 if( repropconflictset->nbdchginfos == 0 )
3737 {
3738 assert(!success);
3739
3740 SCIPsetDebugMsg(set, " -> empty reprop conflict set in depth %d cuts off sub tree at depth %d\n",
3741 focusdepth, repropconflictset->validdepth);
3742
3743 SCIP_CALL( SCIPnodeCutoff(tree->path[repropconflictset->validdepth], set, stat, tree, transprob, \
3744 origprob, reopt, lp, blkmem) );
3745 }
3746
3747#ifdef SCIP_DEBUG
3748 if( success )
3749 {
3750 SCIPsetDebugMsg(set, " -> additional reprop conflict set added (cdpt:%d, fdpt:%d, insert:%d, valid:%d, conf:%d, reprop:%d, len:%d):\n",
3752 repropconflictset->insertdepth, repropconflictset->validdepth, repropconflictset->conflictdepth,
3753 repropconflictset->repropdepth, repropconflictset->nbdchginfos);
3755 }
3756#endif
3757 }
3758
3759 /* mark the node in the repropdepth to be propagated again */
3760 SCIPnodePropagateAgain(tree->path[repropdepth], set, stat, tree);
3761
3762 SCIPsetDebugMsg(set, "marked node %p in depth %d to be repropagated due to conflicts found in depth %d\n",
3763 (void*)tree->path[repropdepth], repropdepth, focusdepth);
3764 }
3765
3766 /* free the conflict store */
3767 for( i = 0; i < conflict->nconflictsets; ++i )
3768 {
3769 conflictsetFree(&conflict->conflictsets[i], blkmem);
3770 }
3771 conflict->nconflictsets = 0;
3772 }
3773
3774 /* free all temporarily created bound change information data */
3775 conflictFreeTmpBdchginfos(conflict, blkmem);
3776
3777 return SCIP_OKAY;
3778}
3779
3780/** returns the current number of conflict sets in the conflict set storage */
3782 SCIP_CONFLICT* conflict /**< conflict analysis data */
3783 )
3784{
3785 assert(conflict != NULL);
3786
3787 return conflict->nconflictsets;
3788}
3789
3790/** returns the total number of conflict constraints that were added to the problem */
3792 SCIP_CONFLICT* conflict /**< conflict analysis data */
3793 )
3794{
3795 assert(conflict != NULL);
3796
3797 return conflict->nappliedglbconss + conflict->nappliedlocconss;
3798}
3799
3800/** returns the total number of literals in conflict constraints that were added to the problem */
3802 SCIP_CONFLICT* conflict /**< conflict analysis data */
3803 )
3804{
3805 assert(conflict != NULL);
3806
3807 return conflict->nappliedglbliterals + conflict->nappliedlocliterals;
3808}
3809
3810/** returns the total number of global bound changes applied by the conflict analysis */
3812 SCIP_CONFLICT* conflict /**< conflict analysis data */
3813 )
3814{
3815 assert(conflict != NULL);
3816
3817 return conflict->nglbchgbds;
3818}
3819
3820/** returns the total number of conflict constraints that were added globally to the problem */
3822 SCIP_CONFLICT* conflict /**< conflict analysis data */
3823 )
3824{
3825 assert(conflict != NULL);
3826
3827 return conflict->nappliedglbconss;
3828}
3829
3830/** returns the total number of literals in conflict constraints that were added globally to the problem */
3832 SCIP_CONFLICT* conflict /**< conflict analysis data */
3833 )
3834{
3835 assert(conflict != NULL);
3836
3837 return conflict->nappliedglbliterals;
3838}
3839
3840/** returns the total number of local bound changes applied by the conflict analysis */
3842 SCIP_CONFLICT* conflict /**< conflict analysis data */
3843 )
3844{
3845 assert(conflict != NULL);
3846
3847 return conflict->nlocchgbds;
3848}
3849
3850/** returns the total number of conflict constraints that were added locally to the problem */
3852 SCIP_CONFLICT* conflict /**< conflict analysis data */
3853 )
3854{
3855 assert(conflict != NULL);
3856
3857 return conflict->nappliedlocconss;
3858}
3859
3860/** returns the total number of literals in conflict constraints that were added locally to the problem */
3862 SCIP_CONFLICT* conflict /**< conflict analysis data */
3863 )
3864{
3865 assert(conflict != NULL);
3866
3867 return conflict->nappliedlocliterals;
3868}
3869
3870
3871
3872
3873/*
3874 * Propagation Conflict Analysis
3875 */
3876
3877/** returns whether bound change has a valid reason that can be resolved in conflict analysis */
3878static
3890
3891/** compares two conflict set entries, such that bound changes inferred later are
3892 * ordered prior to ones that were inferred earlier
3893 */
3894static
3915
3916/** return TRUE if conflict analysis is applicable; In case the function return FALSE there is no need to initialize the
3917 * conflict analysis since it will not be applied
3918 */
3920 SCIP_SET* set /**< global SCIP settings */
3921 )
3922{
3923 /* check, if propagation conflict analysis is enabled */
3924 if( !set->conf_enable || !set->conf_useprop )
3925 return FALSE;
3926
3927 /* check, if there are any conflict handlers to use a conflict set */
3928 if( set->nconflicthdlrs == 0 )
3929 return FALSE;
3930
3931 return TRUE;
3932}
3933
3934/** creates conflict analysis data for propagation conflicts */
3936 SCIP_CONFLICT** conflict, /**< pointer to conflict analysis data */
3937 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
3938 SCIP_SET* set /**< global SCIP settings */
3939 )
3940{
3941 assert(conflict != NULL);
3942
3943 SCIP_ALLOC( BMSallocMemory(conflict) );
3944
3945 SCIP_CALL( SCIPclockCreate(&(*conflict)->dIBclock, SCIP_CLOCKTYPE_DEFAULT) );
3946 SCIP_CALL( SCIPclockCreate(&(*conflict)->propanalyzetime, SCIP_CLOCKTYPE_DEFAULT) );
3947 SCIP_CALL( SCIPclockCreate(&(*conflict)->inflpanalyzetime, SCIP_CLOCKTYPE_DEFAULT) );
3948 SCIP_CALL( SCIPclockCreate(&(*conflict)->boundlpanalyzetime, SCIP_CLOCKTYPE_DEFAULT) );
3949 SCIP_CALL( SCIPclockCreate(&(*conflict)->sbanalyzetime, SCIP_CLOCKTYPE_DEFAULT) );
3950 SCIP_CALL( SCIPclockCreate(&(*conflict)->pseudoanalyzetime, SCIP_CLOCKTYPE_DEFAULT) );
3951
3952 /* enable or disable timing depending on the parameter statistic timing */
3953 SCIPconflictEnableOrDisableClocks((*conflict), set->time_statistictiming);
3954
3955 SCIP_CALL( SCIPpqueueCreate(&(*conflict)->bdchgqueue, set->mem_arraygrowinit, set->mem_arraygrowfac,
3957 SCIP_CALL( SCIPpqueueCreate(&(*conflict)->forcedbdchgqueue, set->mem_arraygrowinit, set->mem_arraygrowfac,
3959 SCIP_CALL( conflictsetCreate(&(*conflict)->conflictset, blkmem) );
3960 (*conflict)->conflictsets = NULL;
3961 (*conflict)->conflictsetscores = NULL;
3962 (*conflict)->tmpbdchginfos = NULL;
3963 (*conflict)->conflictsetssize = 0;
3964 (*conflict)->nconflictsets = 0;
3965 (*conflict)->proofsets = NULL;
3966 (*conflict)->proofsetssize = 0;
3967 (*conflict)->nproofsets = 0;
3968 (*conflict)->tmpbdchginfossize = 0;
3969 (*conflict)->ntmpbdchginfos = 0;
3970 (*conflict)->count = 0;
3971 (*conflict)->nglbchgbds = 0;
3972 (*conflict)->nappliedglbconss = 0;
3973 (*conflict)->nappliedglbliterals = 0;
3974 (*conflict)->nlocchgbds = 0;
3975 (*conflict)->nappliedlocconss = 0;
3976 (*conflict)->nappliedlocliterals = 0;
3977 (*conflict)->npropcalls = 0;
3978 (*conflict)->npropsuccess = 0;
3979 (*conflict)->npropconfconss = 0;
3980 (*conflict)->npropconfliterals = 0;
3981 (*conflict)->npropreconvconss = 0;
3982 (*conflict)->npropreconvliterals = 0;
3983 (*conflict)->ninflpcalls = 0;
3984 (*conflict)->ninflpsuccess = 0;
3985 (*conflict)->ninflpconfconss = 0;
3986 (*conflict)->ninflpconfliterals = 0;
3987 (*conflict)->ninflpreconvconss = 0;
3988 (*conflict)->ninflpreconvliterals = 0;
3989 (*conflict)->ninflpiterations = 0;
3990 (*conflict)->nboundlpcalls = 0;
3991 (*conflict)->nboundlpsuccess = 0;
3992 (*conflict)->nboundlpconfconss = 0;
3993 (*conflict)->nboundlpconfliterals = 0;
3994 (*conflict)->nboundlpreconvconss = 0;
3995 (*conflict)->nboundlpreconvliterals = 0;
3996 (*conflict)->nboundlpiterations = 0;
3997 (*conflict)->nsbcalls = 0;
3998 (*conflict)->nsbsuccess = 0;
3999 (*conflict)->nsbconfconss = 0;
4000 (*conflict)->nsbconfliterals = 0;
4001 (*conflict)->nsbreconvconss = 0;
4002 (*conflict)->nsbreconvliterals = 0;
4003 (*conflict)->nsbiterations = 0;
4004 (*conflict)->npseudocalls = 0;
4005 (*conflict)->npseudosuccess = 0;
4006 (*conflict)->npseudoconfconss = 0;
4007 (*conflict)->npseudoconfliterals = 0;
4008 (*conflict)->npseudoreconvconss = 0;
4009 (*conflict)->npseudoreconvliterals = 0;
4010 (*conflict)->ndualproofsinfglobal = 0;
4011 (*conflict)->ndualproofsinflocal = 0;
4012 (*conflict)->ndualproofsinfsuccess = 0;
4013 (*conflict)->dualproofsinfnnonzeros = 0;
4014 (*conflict)->ndualproofsbndglobal = 0;
4015 (*conflict)->ndualproofsbndlocal = 0;
4016 (*conflict)->ndualproofsbndsuccess = 0;
4017 (*conflict)->dualproofsbndnnonzeros = 0;
4018
4019 SCIP_CALL( conflictInitProofset((*conflict), blkmem) );
4020
4021 return SCIP_OKAY;
4022}
4023
4024/** frees conflict analysis data for propagation conflicts */
4026 SCIP_CONFLICT** conflict, /**< pointer to conflict analysis data */
4027 BMS_BLKMEM* blkmem /**< block memory of transformed problem */
4028 )
4029{
4030 assert(conflict != NULL);
4031 assert(*conflict != NULL);
4032 assert((*conflict)->nconflictsets == 0);
4033 assert((*conflict)->ntmpbdchginfos == 0);
4034
4035#ifdef SCIP_CONFGRAPH
4036 confgraphFree();
4037#endif
4038
4039 SCIPclockFree(&(*conflict)->dIBclock);
4040 SCIPclockFree(&(*conflict)->propanalyzetime);
4041 SCIPclockFree(&(*conflict)->inflpanalyzetime);
4042 SCIPclockFree(&(*conflict)->boundlpanalyzetime);
4043 SCIPclockFree(&(*conflict)->sbanalyzetime);
4044 SCIPclockFree(&(*conflict)->pseudoanalyzetime);
4045 SCIPpqueueFree(&(*conflict)->bdchgqueue);
4046 SCIPpqueueFree(&(*conflict)->forcedbdchgqueue);
4047 conflictsetFree(&(*conflict)->conflictset, blkmem);
4048 proofsetFree(&(*conflict)->proofset, blkmem);
4049
4050 BMSfreeMemoryArrayNull(&(*conflict)->conflictsets);
4051 BMSfreeMemoryArrayNull(&(*conflict)->conflictsetscores);
4052 BMSfreeMemoryArrayNull(&(*conflict)->proofsets);
4053 BMSfreeMemoryArrayNull(&(*conflict)->tmpbdchginfos);
4054 BMSfreeMemory(conflict);
4055
4056 return SCIP_OKAY;
4057}
4058
4059/** clears the conflict queue and the current conflict set */
4060static
4062 SCIP_CONFLICT* conflict /**< conflict analysis data */
4063 )
4064{
4065 assert(conflict != NULL);
4066
4067 SCIPpqueueClear(conflict->bdchgqueue);
4069 conflictsetClear(conflict->conflictset);
4070}
4071
4072/** initializes the propagation conflict analysis by clearing the conflict candidate queue */
4074 SCIP_CONFLICT* conflict, /**< conflict analysis data */
4075 SCIP_SET* set, /**< global SCIP settings */
4076 SCIP_STAT* stat, /**< problem statistics */
4077 SCIP_PROB* prob, /**< problem data */
4078 SCIP_CONFTYPE conftype, /**< type of the conflict */
4079 SCIP_Bool usescutoffbound /**< depends the conflict on a cutoff bound? */
4080 )
4081{
4082 assert(conflict != NULL);
4083 assert(set != NULL);
4084 assert(stat != NULL);
4085 assert(prob != NULL);
4086
4087 SCIPsetDebugMsg(set, "initializing conflict analysis\n");
4088
4089 /* clear the conflict candidate queue and the conflict set */
4090 conflictClear(conflict);
4091
4092 /* set conflict type */
4095 conflict->conflictset->conflicttype = conftype;
4096
4097 /* set whether a cutoff bound is involved */
4098 conflict->conflictset->usescutoffbound = usescutoffbound;
4099
4100 /* increase the conflict counter, such that binary variables of new conflict set and new conflict queue are labeled
4101 * with this new counter
4102 */
4103 conflict->count++;
4104 if( conflict->count == 0 ) /* make sure, 0 is not a valid conflict counter (may happen due to integer overflow) */
4105 conflict->count = 1;
4106
4107 /* increase the conflict score weight for history updates of future conflict reasons */
4108 if( stat->nnodes > stat->lastconflictnode )
4109 {
4110 assert(0.0 < set->conf_scorefac && set->conf_scorefac <= 1.0);
4111 stat->vsidsweight /= set->conf_scorefac;
4112 assert(stat->vsidsweight > 0.0);
4113
4114 /* if the conflict score for the next conflict exceeds 1000.0, rescale all history conflict scores */
4115 if( stat->vsidsweight >= 1000.0 )
4116 {
4117 int v;
4118
4119 for( v = 0; v < prob->nvars; ++v )
4120 {
4121 SCIP_CALL( SCIPvarScaleVSIDS(prob->vars[v], 1.0/stat->vsidsweight) );
4122 }
4125 stat->vsidsweight = 1.0;
4126 }
4127 stat->lastconflictnode = stat->nnodes;
4128 }
4129
4130#ifdef SCIP_CONFGRAPH
4131 confgraphFree();
4132 SCIP_CALL( confgraphCreate(set, conflict) );
4133#endif
4134
4135 return SCIP_OKAY;
4136}
4137
4138/** marks bound to be present in the current conflict and returns whether a bound which is at least as tight was already
4139 * member of the current conflict (i.e., the given bound change does not need to be added)
4140 */
4141static
4143 SCIP_CONFLICT* conflict, /**< conflict analysis data */
4144 SCIP_SET* set, /**< global SCIP settings */
4145 SCIP_BDCHGINFO* bdchginfo, /**< bound change to add to the conflict set */
4146 SCIP_Real relaxedbd /**< relaxed bound */
4147 )
4148{
4149 SCIP_VAR* var;
4150 SCIP_Real newbound;
4151
4152 assert(conflict != NULL);
4153
4156 assert(var != NULL);
4157
4159 {
4161 /* check if the variables lower bound is already member of the conflict */
4162 if( var->conflictlbcount == conflict->count )
4163 {
4164 /* the variable is already member of the conflict; hence check if the new bound is redundant */
4165 if( var->conflictlb > newbound )
4166 {
4167 SCIPsetDebugMsg(set, "ignoring redundant bound change <%s> >= %g since a stronger lower bound exist <%s> >= %g\n",
4169 return TRUE;
4170 }
4171 else if( var->conflictlb == newbound ) /*lint !e777*/
4172 {
4173 SCIPsetDebugMsg(set, "ignoring redundant bound change <%s> >= %g since this lower bound is already present\n", SCIPvarGetName(var), newbound);
4174 SCIPsetDebugMsg(set, "adjust relaxed lower bound <%g> -> <%g>\n", var->conflictlb, relaxedbd);
4176 return TRUE;
4177 }
4178 }
4179
4180 /* add the variable lower bound to the current conflict */
4181 var->conflictlbcount = conflict->count;
4182
4183 /* remember the lower bound and relaxed bound to allow only better/tighter lower bounds for that variables
4184 * w.r.t. this conflict
4185 */
4186 var->conflictlb = newbound;
4188
4189 return FALSE;
4190
4192 /* check if the variables upper bound is already member of the conflict */
4193 if( var->conflictubcount == conflict->count )
4194 {
4195 /* the variable is already member of the conflict; hence check if the new bound is redundant */
4196 if( var->conflictub < newbound )
4197 {
4198 SCIPsetDebugMsg(set, "ignoring redundant bound change <%s> <= %g since a stronger upper bound exist <%s> <= %g\n",
4200 return TRUE;
4201 }
4202 else if( var->conflictub == newbound ) /*lint !e777*/
4203 {
4204 SCIPsetDebugMsg(set, "ignoring redundant bound change <%s> <= %g since this upper bound is already present\n", SCIPvarGetName(var), newbound);
4205 SCIPsetDebugMsg(set, "adjust relaxed upper bound <%g> -> <%g>\n", var->conflictub, relaxedbd);
4207 return TRUE;
4208 }
4209 }
4210
4211 /* add the variable upper bound to the current conflict */
4212 var->conflictubcount = conflict->count;
4213
4214 /* remember the upper bound and relaxed bound to allow only better/tighter upper bounds for that variables
4215 * w.r.t. this conflict
4216 */
4217 var->conflictub = newbound;
4219
4220 return FALSE;
4221
4222 default:
4223 SCIPerrorMessage("invalid bound type %d\n", SCIPbdchginfoGetBoundtype(bdchginfo));
4224 SCIPABORT();
4225 return FALSE; /*lint !e527*/
4226 }
4227}
4228
4229/** puts bound change into the current conflict set */
4230static
4232 SCIP_CONFLICT* conflict, /**< conflict analysis data */
4233 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
4234 SCIP_SET* set, /**< global SCIP settings */
4235 SCIP_BDCHGINFO* bdchginfo, /**< bound change to add to the conflict set */
4236 SCIP_Real relaxedbd /**< relaxed bound */
4237 )
4238{
4239 assert(conflict != NULL);
4241
4242 /* check if the relaxed bound is really a relaxed bound */
4245
4246 SCIPsetDebugMsg(set, "putting bound change <%s> %s %g(%g) at depth %d to current conflict set\n",
4250
4251 /* mark the bound to be member of the conflict and check if a bound which is at least as tight is already member of
4252 * the conflict
4253 */
4255 {
4256 /* add the bound change to the current conflict set */
4258
4259#ifdef SCIP_CONFGRAPH
4262#endif
4263 }
4264#ifdef SCIP_CONFGRAPH
4265 else
4267#endif
4268
4269 return SCIP_OKAY;
4270}
4271
4272/** returns whether the negation of the given bound change would lead to a globally valid literal */
4273static
4275 SCIP_SET* set, /**< global SCIP settings */
4276 SCIP_BDCHGINFO* bdchginfo /**< bound change information */
4277 )
4278{
4279 SCIP_VAR* var;
4280 SCIP_BOUNDTYPE boundtype;
4281 SCIP_Real bound;
4282
4286
4290}
4291
4292/** adds given bound change information to the conflict candidate queue */
4293static
4295 SCIP_CONFLICT* conflict, /**< conflict analysis data */
4296 SCIP_SET* set, /**< global SCIP settings */
4297 SCIP_BDCHGINFO* bdchginfo, /**< bound change information */
4298 SCIP_Real relaxedbd /**< relaxed bound */
4299 )
4300{
4301 assert(conflict != NULL);
4302 assert(set != NULL);
4303 assert(bdchginfo != NULL);
4305
4306 /* check if the relaxed bound is really a relaxed bound */
4309
4310 /* mark the bound to be member of the conflict and check if a bound which is at least as tight is already member of
4311 * the conflict
4312 */
4314 {
4315 /* insert the bound change into the conflict queue */
4316 if( (!set->conf_preferbinary || SCIPvarIsBinary(SCIPbdchginfoGetVar(bdchginfo)))
4318 {
4319 SCIP_CALL( SCIPpqueueInsert(conflict->bdchgqueue, (void*)bdchginfo) );
4320 }
4321 else
4322 {
4324 }
4325
4326#ifdef SCIP_CONFGRAPH
4328#endif
4329 }
4330#ifdef SCIP_CONFGRAPH
4331 else
4333#endif
4334
4335 return SCIP_OKAY;
4336}
4337
4338/** convert variable and bound change to active variable */
4339static
4341 SCIP_VAR** var, /**< pointer to variable */
4342 SCIP_SET* set, /**< global SCIP settings */
4343 SCIP_BOUNDTYPE* boundtype, /**< pointer to type of bound that was changed: lower or upper bound */
4344 SCIP_Real* bound /**< pointer to bound to convert, or NULL */
4345 )
4346{
4347 SCIP_Real scalar;
4348 SCIP_Real constant;
4349
4350 scalar = 1.0;
4351 constant = 0.0;
4352
4353 /* transform given variable to active variable */
4354 SCIP_CALL( SCIPvarGetProbvarSum(var, set, &scalar, &constant) );
4355 assert(SCIPvarGetStatus(*var) == SCIP_VARSTATUS_FIXED || scalar != 0.0); /*lint !e777*/
4356
4358 return SCIP_OKAY;
4359
4360 /* if the scalar of the aggregation is negative, we have to switch the bound type */
4361 if( scalar < 0.0 )
4362 (*boundtype) = SCIPboundtypeOpposite(*boundtype);
4363
4364 if( bound != NULL )
4365 {
4366 (*bound) -= constant;
4367 (*bound) /= scalar;
4368 }
4369
4370 return SCIP_OKAY;
4371}
4372
4373/** adds variable's bound to conflict candidate queue */
4374static
4376 SCIP_CONFLICT* conflict, /**< conflict analysis data */
4377 BMS_BLKMEM* blkmem, /**< block memory */
4378 SCIP_SET* set, /**< global SCIP settings */
4379 SCIP_STAT* stat, /**< dynamic problem statistics */
4380 SCIP_VAR* var, /**< problem variable */
4381 SCIP_BOUNDTYPE boundtype, /**< type of bound that was changed: lower or upper bound */
4382 SCIP_BDCHGINFO* bdchginfo, /**< bound change info, or NULL */
4383 SCIP_Real relaxedbd /**< relaxed bound */
4384 )
4385{
4387 assert(bdchginfo != NULL);
4389
4390 SCIPsetDebugMsg(set, " -> adding bound <%s> %s %.15g(%.15g) [status:%d, type:%d, depth:%d, pos:%d, reason:<%s>, info:%d] to candidates\n",
4392 boundtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
4400 : "none")),
4402
4403 /* the local bound change may be resolved and has to be put on the candidate queue;
4404 * we even put bound changes without inference information on the queue in order to automatically
4405 * eliminate multiple insertions of the same bound change
4406 */
4411
4412 /* the relaxed bound should be a relaxation */
4414
4415 /* the relaxed bound should be worse then the old bound of the bound change info */
4417
4418 /* put bound change information into priority queue */
4420
4421 /* each variable which is add to the conflict graph gets an increase in the VSIDS
4422 *
4423 * @note That is different to the VSIDS preseted in the literature
4424 */
4425 SCIP_CALL( incVSIDS(var, blkmem, set, stat, boundtype, relaxedbd, set->conf_conflictgraphweight) );
4426
4427 return SCIP_OKAY;
4428}
4429
4430/** adds variable's bound to conflict candidate queue */
4432 SCIP_CONFLICT* conflict, /**< conflict analysis data */
4433 BMS_BLKMEM* blkmem, /**< block memory */
4434 SCIP_SET* set, /**< global SCIP settings */
4435 SCIP_STAT* stat, /**< dynamic problem statistics */
4436 SCIP_VAR* var, /**< problem variable */
4437 SCIP_BOUNDTYPE boundtype, /**< type of bound that was changed: lower or upper bound */
4438 SCIP_BDCHGIDX* bdchgidx /**< bound change index (time stamp of bound change), or NULL for current time */
4439 )
4440{
4442
4443 assert(conflict != NULL);
4444 assert(stat != NULL);
4445 assert(var != NULL);
4446
4447 /* convert bound to active problem variable */
4448 SCIP_CALL( convertToActiveVar(&var, set, &boundtype, NULL) );
4449
4450 /* we can ignore fixed variables */
4452 return SCIP_OKAY;
4453
4454 /* if the variable is multi-aggregated, add the bounds of all aggregation variables */
4456 {
4457 SCIP_VAR** vars;
4458 SCIP_Real* scalars;
4459 int nvars;
4460 int i;
4461
4465 for( i = 0; i < nvars; ++i )
4466 {
4467 SCIP_CALL( SCIPconflictAddBound(conflict, blkmem, set, stat, vars[i],
4468 (scalars[i] < 0.0 ? SCIPboundtypeOpposite(boundtype) : boundtype), bdchgidx) );
4469 }
4470
4471 return SCIP_OKAY;
4472 }
4474
4475 /* get bound change information */
4476 bdchginfo = SCIPvarGetBdchgInfo(var, boundtype, bdchgidx, FALSE);
4477
4478 /* if bound of variable was not changed (this means it is still the global bound), we can ignore the conflicting
4479 * bound
4480 */
4481 if( bdchginfo == NULL )
4482 return SCIP_OKAY;
4483
4485
4486 SCIP_CALL( conflictAddBound(conflict, blkmem, set, stat, var, boundtype, bdchginfo, SCIPbdchginfoGetNewbound(bdchginfo)) );
4487
4488 return SCIP_OKAY;
4489}
4490
4491/** adds variable's bound to conflict candidate queue */
4493 SCIP_CONFLICT* conflict, /**< conflict analysis data */
4494 BMS_BLKMEM* blkmem, /**< block memory */
4495 SCIP_SET* set, /**< global SCIP settings */
4496 SCIP_STAT* stat, /**< dynamic problem statistics */
4497 SCIP_VAR* var, /**< problem variable */
4498 SCIP_BOUNDTYPE boundtype, /**< type of bound that was changed: lower or upper bound */
4499 SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
4500 SCIP_Real relaxedbd /**< the relaxed bound */
4501 )
4502{
4504 int nbdchgs;
4505
4506 assert(conflict != NULL);
4507 assert(stat != NULL);
4508 assert(var != NULL);
4509
4510 if( !SCIPvarIsActive(var) )
4511 {
4512 /* convert bound to active problem variable */
4513 SCIP_CALL( convertToActiveVar(&var, set, &boundtype, &relaxedbd) );
4514
4515 /* we can ignore fixed variables */
4517 return SCIP_OKAY;
4518
4519 /* if the variable is multi-aggregated, add the bounds of all aggregation variables */
4521 {
4522 SCIPsetDebugMsg(set, "ignoring relaxed bound information since variable <%s> is multi-aggregated active\n", SCIPvarGetName(var));
4523
4524 SCIP_CALL( SCIPconflictAddBound(conflict, blkmem, set, stat, var, boundtype, bdchgidx) );
4525
4526 return SCIP_OKAY;
4527 }
4528 }
4530
4531 /* get bound change information */
4532 bdchginfo = SCIPvarGetBdchgInfo(var, boundtype, bdchgidx, FALSE);
4533
4534 /* if bound of variable was not changed (this means it is still the global bound), we can ignore the conflicting
4535 * bound
4536 */
4537 if( bdchginfo == NULL )
4538 return SCIP_OKAY;
4539
4540 /* check that the bound change info is not a temporary one */
4541 assert(SCIPbdchgidxGetPos(&bdchginfo->bdchgidx) >= 0);
4542
4543 /* get the position of the bound change information within the bound change array of the variable */
4544 nbdchgs = (int) bdchginfo->pos;
4545 assert(nbdchgs >= 0);
4546
4547 /* if the relaxed bound should be ignored, set the relaxed bound to the bound given by the bdchgidx; that ensures
4548 * that the loop(s) below will be skipped
4549 */
4550 if( set->conf_ignorerelaxedbd )
4552
4553 /* search for the bound change information which includes the relaxed bound */
4554 if( boundtype == SCIP_BOUNDTYPE_LOWER )
4555 {
4556 SCIP_Real newbound;
4557
4558 /* adjust relaxed lower bound w.r.t. variable type */
4560
4561 /* due to numericis we compare the relaxed lower bound to the one present at the particular time point and take
4562 * the better one
4563 */
4565 relaxedbd = MIN(relaxedbd, newbound);
4566
4567 /* check if relaxed lower bound is smaller or equal to global lower bound; if so we can ignore the conflicting
4568 * bound
4569 */
4571 return SCIP_OKAY;
4572
4573 while( nbdchgs > 0 )
4574 {
4576
4577 /* check if the old lower bound is greater than or equal to relaxed lower bound; if not we found the bound
4578 * change info which we need to report
4579 */
4581 break;
4582
4583 bdchginfo = SCIPvarGetBdchgInfoLb(var, nbdchgs-1);
4584
4585 SCIPsetDebugMsg(set, "lower bound change %d oldbd=%.15g, newbd=%.15g, depth=%d, pos=%d, redundant=%u\n",
4589
4590 /* if bound change is redundant (this means it now a global bound), we can ignore the conflicting bound */
4592 return SCIP_OKAY;
4593
4594 nbdchgs--;
4595 }
4597 }
4598 else
4599 {
4600 SCIP_Real newbound;
4601
4602 assert(boundtype == SCIP_BOUNDTYPE_UPPER);
4603
4604 /* adjust relaxed upper bound w.r.t. variable type */
4606
4607 /* due to numericis we compare the relaxed upper bound to the one present at the particular time point and take
4608 * the better one
4609 */
4611 relaxedbd = MAX(relaxedbd, newbound);
4612
4613 /* check if relaxed upper bound is greater or equal to global upper bound; if so we can ignore the conflicting
4614 * bound
4615 */
4617 return SCIP_OKAY;
4618
4619 while( nbdchgs > 0 )
4620 {
4622
4623 /* check if the old upper bound is smaller than or equal to the relaxed upper bound; if not we found the
4624 * bound change info which we need to report
4625 */
4627 break;
4628
4629 bdchginfo = SCIPvarGetBdchgInfoUb(var, nbdchgs-1);
4630
4631 SCIPsetDebugMsg(set, "upper bound change %d oldbd=%.15g, newbd=%.15g, depth=%d, pos=%d, redundant=%u\n",
4635
4636 /* if bound change is redundant (this means it now a global bound), we can ignore the conflicting bound */
4638 return SCIP_OKAY;
4639
4640 nbdchgs--;
4641 }
4643 }
4644
4646
4647 /* put bound change information into priority queue */
4648 SCIP_CALL( conflictAddBound(conflict, blkmem, set, stat, var, boundtype, bdchginfo, relaxedbd) );
4649
4650 return SCIP_OKAY;
4651}
4652
4653/** checks if the given variable is already part of the current conflict set or queued for resolving with the same or
4654 * even stronger bound
4655 */
4657 SCIP_CONFLICT* conflict, /**< conflict analysis data */
4658 SCIP_VAR* var, /**< problem variable */
4659 SCIP_SET* set, /**< global SCIP settings */
4660 SCIP_BOUNDTYPE boundtype, /**< type of bound for which the score should be increased */
4661 SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
4662 SCIP_Bool* used /**< pointer to store if the variable is already used */
4663 )
4664{
4665 SCIP_Real newbound;
4666
4667 /* convert bound to active problem variable */
4668 SCIP_CALL( convertToActiveVar(&var, set, &boundtype, NULL) );
4669
4671 *used = FALSE;
4672 else
4673 {
4675 assert(var != NULL);
4676
4677 switch( boundtype )
4678 {
4680
4681 newbound = SCIPgetVarLbAtIndex(set->scip, var, bdchgidx, FALSE);
4682
4683 if( var->conflictlbcount == conflict->count && var->conflictlb >= newbound )
4684 {
4685 SCIPsetDebugMsg(set, "already queued bound change <%s> >= %g\n", SCIPvarGetName(var), newbound);
4686 *used = TRUE;
4687 }
4688 else
4689 *used = FALSE;
4690 break;
4692
4693 newbound = SCIPgetVarUbAtIndex(set->scip, var, bdchgidx, FALSE);
4694
4695 if( var->conflictubcount == conflict->count && var->conflictub <= newbound )
4696 {
4697 SCIPsetDebugMsg(set, "already queued bound change <%s> <= %g\n", SCIPvarGetName(var), newbound);
4698 *used = TRUE;
4699 }
4700 else
4701 *used = FALSE;
4702 break;
4703 default:
4704 SCIPerrorMessage("invalid bound type %d\n", boundtype);
4705 SCIPABORT();
4706 *used = FALSE; /*lint !e527*/
4707 }
4708 }
4709
4710 return SCIP_OKAY;
4711}
4712
4713/** returns the conflict lower bound if the variable is present in the current conflict set; otherwise the global lower
4714 * bound
4715 */
4717 SCIP_CONFLICT* conflict, /**< conflict analysis data */
4718 SCIP_VAR* var /**< problem variable */
4719 )
4720{
4721 if( var->conflictlbcount == conflict->count )
4722 {
4724 return var->conflictrelaxedlb;
4725 }
4726
4727 return SCIPvarGetLbGlobal(var);
4728}
4729
4730/** returns the conflict upper bound if the variable is present in the current conflict set; otherwise the global upper
4731 * bound
4732 */
4734 SCIP_CONFLICT* conflict, /**< conflict analysis data */
4735 SCIP_VAR* var /**< problem variable */
4736 )
4737{
4738 if( var->conflictubcount == conflict->count )
4739 {
4741 return var->conflictrelaxedub;
4742 }
4743
4744 return SCIPvarGetUbGlobal(var);
4745}
4746
4747/** removes and returns next conflict analysis candidate from the candidate queue */
4748static
4750 SCIP_CONFLICT* conflict /**< conflict analysis data */
4751 )
4752{
4754 SCIP_VAR* var;
4755
4756 assert(conflict != NULL);
4757
4758 if( SCIPpqueueNElems(conflict->forcedbdchgqueue) > 0 )
4760 else
4762
4764
4765 /* if we have a candidate this one should be valid for the current conflict analysis */
4766 assert(!bdchginfoIsInvalid(conflict, bdchginfo));
4767
4768 /* mark the bound change to be no longer in the conflict (it will be either added again to the conflict set or
4769 * replaced by resolving, which might add a weaker change on the same bound to the queue)
4770 */
4773 {
4774 var->conflictlbcount = 0;
4776 }
4777 else
4778 {
4780 var->conflictubcount = 0;
4782 }
4783
4784#ifdef SCIP_CONFGRAPH
4786#endif
4787
4788 return bdchginfo;
4789}
4790
4791/** returns next conflict analysis candidate from the candidate queue without removing it */
4792static
4794 SCIP_CONFLICT* conflict /**< conflict analysis data */
4795 )
4796{
4798
4799 assert(conflict != NULL);
4800
4801 if( SCIPpqueueNElems(conflict->forcedbdchgqueue) > 0 )
4802 {
4803 /* get next potential candidate */
4805
4806 /* check if this candidate is valid */
4807 if( bdchginfoIsInvalid(conflict, bdchginfo) )
4808 {
4809 SCIPdebugMessage("bound change info [%d:<%s> %s %g] is invalid -> pop it from the force queue\n", SCIPbdchginfoGetDepth(bdchginfo),
4813
4814 /* pop the invalid bound change info from the queue */
4816
4817 /* call method recursively to get next conflict analysis candidate */
4818 bdchginfo = conflictFirstCand(conflict);
4819 }
4820 }
4821 else
4822 {
4824
4825 /* check if this candidate is valid */
4826 if( bdchginfo != NULL && bdchginfoIsInvalid(conflict, bdchginfo) )
4827 {
4828 SCIPdebugMessage("bound change info [%d:<%s> %s %g] is invalid -> pop it from the queue\n", SCIPbdchginfoGetDepth(bdchginfo),
4832
4833 /* pop the invalid bound change info from the queue */
4834 (void)(SCIPpqueueRemove(conflict->bdchgqueue));
4835
4836 /* call method recursively to get next conflict analysis candidate */
4837 bdchginfo = conflictFirstCand(conflict);
4838 }
4839 }
4841
4842 return bdchginfo;
4843}
4844
4845/** adds the current conflict set (extended by all remaining bound changes in the queue) to the pool of conflict sets */
4846static
4848 SCIP_CONFLICT* conflict, /**< conflict analysis data */
4849 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
4850 SCIP_SET* set, /**< global SCIP settings */
4851 SCIP_STAT* stat, /**< dynamic problem statistics */
4852 SCIP_TREE* tree, /**< branch and bound tree */
4853 int validdepth, /**< minimal depth level at which the conflict set is valid */
4854 SCIP_Bool diving, /**< are we in strong branching or diving mode? */
4855 SCIP_Bool repropagate, /**< should the constraint trigger a repropagation? */
4856 SCIP_Bool* success, /**< pointer to store whether the conflict set is valid */
4857 int* nliterals /**< pointer to store the number of literals in the generated conflictset */
4858 )
4859{
4860 SCIP_CONFLICTSET* conflictset;
4861 SCIP_BDCHGINFO** bdchginfos;
4862 int nbdchginfos;
4863 int currentdepth;
4864 int focusdepth;
4865
4866 assert(conflict != NULL);
4867 assert(conflict->conflictset != NULL);
4868 assert(set != NULL);
4869 assert(stat != NULL);
4870 assert(tree != NULL);
4871 assert(success != NULL);
4872 assert(nliterals != NULL);
4873 assert(SCIPpqueueNElems(conflict->forcedbdchgqueue) == 0);
4874
4875 *success = FALSE;
4876 *nliterals = 0;
4877
4878 /* check, whether local conflicts are allowed */
4879 validdepth = MAX(validdepth, conflict->conflictset->validdepth);
4880 if( !set->conf_allowlocal && validdepth > 0 )
4881 return SCIP_OKAY;
4882
4885 assert(currentdepth == tree->pathlen-1);
4887 assert(0 <= conflict->conflictset->validdepth && conflict->conflictset->validdepth <= currentdepth);
4888 assert(0 <= validdepth && validdepth <= currentdepth);
4889
4890 /* get the elements of the bound change queue */
4891 bdchginfos = (SCIP_BDCHGINFO**)SCIPpqueueElems(conflict->bdchgqueue);
4892 nbdchginfos = SCIPpqueueNElems(conflict->bdchgqueue);
4893
4894 /* create a copy of the current conflict set, allocating memory for the additional elements of the queue */
4895 SCIP_CALL( conflictsetCopy(&conflictset, blkmem, conflict->conflictset, nbdchginfos) );
4896 conflictset->validdepth = validdepth;
4897 conflictset->repropagate = repropagate;
4898
4899 /* add the valid queue elements to the conflict set */
4900 SCIPsetDebugMsg(set, "adding %d variables from the queue as temporary conflict variables\n", nbdchginfos);
4901 SCIP_CALL( conflictsetAddBounds(conflict, conflictset, blkmem, set, bdchginfos, nbdchginfos) );
4902
4903 /* calculate the depth, at which the conflictset should be inserted */
4904 SCIP_CALL( conflictsetCalcInsertDepth(conflictset, set, tree) );
4905 assert(conflictset->validdepth <= conflictset->insertdepth && conflictset->insertdepth <= currentdepth);
4906 SCIPsetDebugMsg(set, " -> conflict with %d literals found at depth %d is active in depth %d and valid in depth %d\n",
4907 conflictset->nbdchginfos, currentdepth, conflictset->insertdepth, conflictset->validdepth);
4908
4909 /* if all branching variables are in the conflict set, the conflict set is of no use;
4910 * don't use conflict sets that are only valid in the probing path but not in the problem tree
4911 */
4912 if( (diving || conflictset->insertdepth < currentdepth) && conflictset->insertdepth <= focusdepth )
4913 {
4914 /* if the conflict should not be located only in the subtree where it is useful, put it to its valid depth level */
4915 if( !set->conf_settlelocal )
4916 conflictset->insertdepth = conflictset->validdepth;
4917
4918 *nliterals = conflictset->nbdchginfos;
4919 SCIPsetDebugMsg(set, " -> final conflict set has %d literals\n", *nliterals);
4920
4921 /* check conflict set on debugging solution */
4922 SCIP_CALL( SCIPdebugCheckConflict(blkmem, set, tree->path[validdepth], \
4923 conflictset->bdchginfos, conflictset->relaxedbds, conflictset->nbdchginfos) ); /*lint !e506 !e774*/
4924
4925 /* move conflictset to the conflictset storage */
4926 SCIP_CALL( conflictInsertConflictset(conflict, blkmem, set, &conflictset) );
4927 *success = TRUE;
4928 }
4929 else
4930 {
4931 /* free the temporary conflict set */
4932 conflictsetFree(&conflictset, blkmem);
4933 }
4934
4935 return SCIP_OKAY;
4936}
4937
4938/** tries to resolve given bound change
4939 * - resolutions on local constraints are only applied, if the constraint is valid at the
4940 * current minimal valid depth level, because this depth level is the topmost level to add the conflict
4941 * constraint to anyways
4942 *
4943 * @note it is sufficient to explain the relaxed bound change
4944 */
4945static
4947 SCIP_CONFLICT* conflict, /**< conflict analysis data */
4948 SCIP_SET* set, /**< global SCIP settings */
4949 SCIP_BDCHGINFO* bdchginfo, /**< bound change to resolve */
4950 SCIP_Real relaxedbd, /**< the relaxed bound */
4951 int validdepth, /**< minimal depth level at which the conflict is valid */
4952 SCIP_Bool* resolved /**< pointer to store whether the bound change was resolved */
4953 )
4954{
4956 SCIP_CONS* infercons;
4957 SCIP_PROP* inferprop;
4959
4960#ifndef NDEBUG
4962 int nbdchgqueue;
4963
4964 /* store the current size of the conflict queues */
4965 assert(conflict != NULL);
4968#else
4969 assert(conflict != NULL);
4970#endif
4971
4972 assert(resolved != NULL);
4974
4975 *resolved = FALSE;
4976
4978 assert(actvar != NULL);
4980
4981#ifdef SCIP_DEBUG
4982 {
4983 int i;
4984 SCIPsetDebugMsg(set, "processing next conflicting bound (depth: %d, valid depth: %d, bdchgtype: %s [%s], vartype: %d): [<%s> %s %g(%g)]\n",
4985 SCIPbdchginfoGetDepth(bdchginfo), validdepth,
4996 SCIPsetDebugMsg(set, " - conflict set :");
4997
4998 for( i = 0; i < conflict->conflictset->nbdchginfos; ++i )
4999 {
5000 SCIPsetDebugMsgPrint(set, " [%d:<%s> %s %g(%g)]", SCIPbdchginfoGetDepth(conflict->conflictset->bdchginfos[i]),
5004 }
5006 SCIPsetDebugMsg(set, " - forced candidates :");
5007
5008 for( i = 0; i < SCIPpqueueNElems(conflict->forcedbdchgqueue); ++i )
5009 {
5012 bdchginfoIsInvalid(conflict, info) ? "<!>" : SCIPbdchginfoGetBoundtype(info) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
5014 }
5016 SCIPsetDebugMsg(set, " - optional candidates:");
5017
5018 for( i = 0; i < SCIPpqueueNElems(conflict->bdchgqueue); ++i )
5019 {
5022 bdchginfoIsInvalid(conflict, info) ? "<!>" : SCIPbdchginfoGetBoundtype(info) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
5024 }
5026 }
5027#endif
5028
5029 /* check, if the bound change can and should be resolved:
5030 * - resolutions on local constraints should only be applied, if the constraint is valid at the
5031 * current minimal valid depth level (which is initialized with the valid depth level of the initial
5032 * conflict set), because this depth level is the topmost level to add the conflict constraint to anyways
5033 */
5035 {
5038 assert(infercons != NULL);
5039
5040 if( SCIPconsIsGlobal(infercons) || SCIPconsGetValidDepth(infercons) <= validdepth )
5041 {
5043 int inferinfo;
5044 SCIP_BOUNDTYPE inferboundtype;
5045 SCIP_BDCHGIDX* bdchgidx;
5046
5047 /* resolve bound change by asking the constraint that inferred the bound to put all bounds that were
5048 * the reasons for the conflicting bound change on the priority queue
5049 */
5052 inferboundtype = SCIPbdchginfoGetInferBoundtype(bdchginfo);
5053 bdchgidx = SCIPbdchginfoGetIdx(bdchginfo);
5054 assert(infervar != NULL);
5055
5056 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",
5063 inferboundtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
5064 SCIPgetVarBdAtIndex(set->scip, infervar, inferboundtype, bdchgidx, TRUE),
5065 SCIPconsGetName(infercons),
5066 SCIPconsIsGlobal(infercons) ? "global" : "local",
5067 inferinfo);
5068
5069 /* in case the inference variables is not an active variables, we need to transform the relaxed bound */
5070 if( actvar != infervar )
5071 {
5072 SCIP_VAR* var;
5073 SCIP_Real scalar;
5074 SCIP_Real constant;
5075
5079
5080 scalar = 1.0;
5081 constant = 0.0;
5082
5083 var = infervar;
5084
5085 /* transform given variable to active variable */
5086 SCIP_CALL( SCIPvarGetProbvarSum(&var, set, &scalar, &constant) );
5087 assert(var == actvar);
5088
5089 relaxedbd *= scalar;
5090 relaxedbd += constant;
5091 }
5092
5093 SCIP_CALL( SCIPconsResolvePropagation(infercons, set, infervar, inferinfo, inferboundtype, bdchgidx, relaxedbd, &result) );
5095 }
5096 break;
5097
5100 if( inferprop != NULL )
5101 {
5103 int inferinfo;
5104 SCIP_BOUNDTYPE inferboundtype;
5105 SCIP_BDCHGIDX* bdchgidx;
5106
5107 /* resolve bound change by asking the propagator that inferred the bound to put all bounds that were
5108 * the reasons for the conflicting bound change on the priority queue
5109 */
5112 inferboundtype = SCIPbdchginfoGetInferBoundtype(bdchginfo);
5113 bdchgidx = SCIPbdchginfoGetIdx(bdchginfo);
5114 assert(infervar != NULL);
5115
5116 SCIPsetDebugMsg(set, "resolving bound <%s> %s %g(%g) [status:%d, depth:%d, pos:%d]: <%s> %s %g [prop:<%s>, info:%d]\n",
5122 inferboundtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
5123 SCIPgetVarBdAtIndex(set->scip, infervar, inferboundtype, bdchgidx, TRUE),
5124 SCIPpropGetName(inferprop), inferinfo);
5125
5126 SCIP_CALL( SCIPpropResolvePropagation(inferprop, set, infervar, inferinfo, inferboundtype, bdchgidx, relaxedbd, &result) );
5128 }
5129 break;
5130
5132 assert(!(*resolved));
5133 break;
5134
5135 default:
5136 SCIPerrorMessage("invalid bound change type <%d>\n", SCIPbdchginfoGetChgtype(bdchginfo));
5137 return SCIP_INVALIDDATA;
5138 }
5139
5140 SCIPsetDebugMsg(set, "resolving status: %u\n", *resolved);
5141
5142#ifndef NDEBUG
5143 /* subtract the size of the conflicq queues */
5146
5147 /* in case the bound change was not resolved, the conflict queues should have the same size (contents) */
5148 assert((*resolved) || (nforcedbdchgqueue == 0 && nbdchgqueue == 0));
5149#endif
5150
5151 return SCIP_OKAY;
5152}
5153
5154/** if only one conflicting bound change of the last depth level was used, and if this can be resolved,
5155 * creates GRASP-like reconvergence conflict constraints in the conflict graph up to the branching variable of this
5156 * depth level
5157 */
5158static
5160 SCIP_CONFLICT* conflict, /**< conflict analysis data */
5161 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
5162 SCIP_SET* set, /**< global SCIP settings */
5163 SCIP_STAT* stat, /**< problem statistics */
5164 SCIP_PROB* prob, /**< problem data */
5165 SCIP_TREE* tree, /**< branch and bound tree */
5166 SCIP_Bool diving, /**< are we in strong branching or diving mode? */
5167 int validdepth, /**< minimal depth level at which the initial conflict set is valid */
5168 SCIP_BDCHGINFO* firstuip, /**< first UIP of conflict graph */
5169 int* nreconvconss, /**< pointer to store the number of generated reconvergence constraints */
5170 int* nreconvliterals /**< pointer to store the number of literals generated reconvergence constraints */
5171 )
5172{
5175 SCIP_Bool usescutoffbound;
5176 int firstuipdepth;
5177 int focusdepth;
5178 int currentdepth;
5179 int maxvaliddepth;
5180
5181 assert(conflict != NULL);
5182 assert(firstuip != NULL);
5186
5189 assert(currentdepth == tree->pathlen-1);
5191
5192 /* check, whether local constraints are allowed; however, don't generate reconvergence constraints that are only valid
5193 * in the probing path and not in the problem tree (i.e. that exceed the focusdepth)
5194 */
5195 maxvaliddepth = (set->conf_allowlocal ? MIN(currentdepth-1, focusdepth) : 0);
5196 if( validdepth > maxvaliddepth )
5197 return SCIP_OKAY;
5198
5200
5201 conftype = conflict->conflictset->conflicttype;
5202 usescutoffbound = conflict->conflictset->usescutoffbound;
5203
5204 /* for each succeeding UIP pair of the last depth level, create one reconvergence constraint */
5205 uip = firstuip;
5207 {
5212 SCIP_Real oppositeuipbound;
5214 int nresolutions;
5215
5217
5218 SCIPsetDebugMsg(set, "creating reconvergence constraint for UIP <%s> %s %g in depth %d pos %d\n",
5221
5222 /* initialize conflict data */
5223 SCIP_CALL( SCIPconflictInit(conflict, set, stat, prob, conftype, usescutoffbound) );
5224
5225 conflict->conflictset->conflicttype = conftype;
5226 conflict->conflictset->usescutoffbound = usescutoffbound;
5227
5228 /* create a temporary bound change information for the negation of the UIP's bound change;
5229 * this bound change information is freed in the SCIPconflictFlushConss() call;
5230 * for reconvergence constraints for continuous variables we can only use the "negation" !(x <= u) == (x >= u);
5231 * during conflict analysis, we treat a continuous bound "x >= u" in the conflict set as "x > u", and in the
5232 * generated constraint this is negated again to "x <= u" which is correct.
5233 */
5238 {
5241 }
5244
5245 /* put the negated UIP into the conflict set */
5247
5248 /* put positive UIP into priority queue */
5250
5251 /* resolve the queue until the next UIP is reached */
5252 bdchginfo = conflictFirstCand(conflict);
5253 nextuip = NULL;
5254 nresolutions = 0;
5255 while( bdchginfo != NULL && validdepth <= maxvaliddepth )
5256 {
5258 SCIP_Real relaxedbd;
5259 SCIP_Bool forceresolve;
5260 int bdchgdepth;
5261
5262 /* check if the next bound change must be resolved in every case */
5264
5265 /* remove currently processed candidate and get next conflicting bound from the conflict candidate queue before
5266 * we remove the candidate we have to collect the relaxed bound since removing the candidate from the queue
5267 * invalidates the relaxed bound
5268 */
5269 assert(bdchginfo == conflictFirstCand(conflict));
5271 bdchginfo = conflictRemoveCand(conflict);
5272 nextbdchginfo = conflictFirstCand(conflict);
5274 assert(bdchginfo != NULL);
5277 || forceresolve);
5279
5280 /* bound changes that are higher in the tree than the valid depth of the conflict can be ignored;
5281 * multiple insertions of the same bound change can be ignored
5282 */
5283 if( bdchgdepth > validdepth && bdchginfo != nextbdchginfo )
5284 {
5286 SCIP_Bool resolved;
5287
5289 assert(actvar != NULL);
5291
5292 /* check if we have to resolve the bound change in this depth level
5293 * - the starting uip has to be resolved
5294 * - a bound change should be resolved, if it is in the fuip's depth level and not the
5295 * next uip (i.e., if it is not the last bound change in the fuip's depth level)
5296 * - a forced bound change must be resolved in any case
5297 */
5298 resolved = FALSE;
5299 if( bdchginfo == uip
5301 && nextbdchginfo != NULL
5303 || forceresolve )
5304 {
5305 SCIP_CALL( conflictResolveBound(conflict, set, bdchginfo, relaxedbd, validdepth, &resolved) );
5306 }
5307
5308 if( resolved )
5309 nresolutions++;
5310 else if( forceresolve )
5311 {
5312 /* variable cannot enter the conflict clause: we have to make the conflict clause local, s.t.
5313 * the unresolved bound change is active in the whole sub tree of the conflict clause
5314 */
5315 assert(bdchgdepth >= validdepth);
5316 validdepth = bdchgdepth;
5317
5318 SCIPsetDebugMsg(set, "couldn't resolve forced bound change on <%s> -> new valid depth: %d\n",
5319 SCIPvarGetName(actvar), validdepth);
5320 }
5321 else if( bdchginfo != uip )
5322 {
5323 assert(conflict->conflictset != NULL);
5324 assert(conflict->conflictset->nbdchginfos >= 1); /* starting UIP is already member of the conflict set */
5325
5326 /* if this is the first variable of the conflict set besides the current starting UIP, it is the next
5327 * UIP (or the first unresolvable bound change)
5328 */
5329 if( bdchgdepth == firstuipdepth && conflict->conflictset->nbdchginfos == 1 )
5330 {
5331 assert(nextuip == NULL);
5333 }
5334
5335 /* put bound change into the conflict set */
5337 assert(conflict->conflictset->nbdchginfos >= 2);
5338 }
5339 else
5340 assert(conflictFirstCand(conflict) == NULL); /* the starting UIP was not resolved */
5341 }
5342
5343 /* get next conflicting bound from the conflict candidate queue (this does not need to be nextbdchginfo, because
5344 * due to resolving the bound changes, a variable could be added to the queue which must be
5345 * resolved before nextbdchginfo)
5346 */
5347 bdchginfo = conflictFirstCand(conflict);
5348 }
5349 assert(nextuip != uip);
5350
5351 /* if only one propagation was resolved, the reconvergence constraint is already member of the constraint set
5352 * (it is exactly the constraint that produced the propagation)
5353 */
5354 if( nextuip != NULL && nresolutions >= 2 && bdchginfo == NULL && validdepth <= maxvaliddepth )
5355 {
5356 int nlits;
5357 SCIP_Bool success;
5358
5360
5361 /* check conflict graph frontier on debugging solution */
5362 SCIP_CALL( SCIPdebugCheckConflictFrontier(blkmem, set, tree->path[validdepth], \
5363 bdchginfo, conflict->conflictset->bdchginfos, conflict->conflictset->relaxedbds, \
5364 conflict->conflictset->nbdchginfos, conflict->bdchgqueue, conflict->forcedbdchgqueue) ); /*lint !e506 !e774*/
5365
5366 SCIPsetDebugMsg(set, "creating reconvergence constraint from UIP <%s> to UIP <%s> in depth %d with %d literals after %d resolutions\n",
5369
5370 /* call the conflict handlers to create a conflict set */
5371 SCIP_CALL( conflictAddConflictset(conflict, blkmem, set, stat, tree, validdepth, diving, FALSE, &success, &nlits) );
5372 if( success )
5373 {
5374 (*nreconvconss)++;
5375 (*nreconvliterals) += nlits;
5376 }
5377 }
5378
5379 /* clear the conflict candidate queue and the conflict set (to make sure, oppositeuip is not referenced anymore) */
5380 conflictClear(conflict);
5381
5382 uip = nextuip;
5383 }
5384
5385 conflict->conflictset->conflicttype = conftype;
5386 conflict->conflictset->usescutoffbound = usescutoffbound;
5387
5388 return SCIP_OKAY;
5389}
5390
5391/** analyzes conflicting bound changes that were added with calls to SCIPconflictAddBound() and
5392 * SCIPconflictAddRelaxedBound(), and on success, calls the conflict handlers to create a conflict constraint out of
5393 * the resulting conflict set; afterwards the conflict queue and the conflict set is cleared
5394 */
5395static
5397 SCIP_CONFLICT* conflict, /**< conflict analysis data */
5398 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
5399 SCIP_SET* set, /**< global SCIP settings */
5400 SCIP_STAT* stat, /**< problem statistics */
5401 SCIP_PROB* prob, /**< problem data */
5402 SCIP_TREE* tree, /**< branch and bound tree */
5403 SCIP_Bool diving, /**< are we in strong branching or diving mode? */
5404 int validdepth, /**< minimal depth level at which the initial conflict set is valid */
5405 SCIP_Bool mustresolve, /**< should the conflict set only be used, if a resolution was applied? */
5406 int* nconss, /**< pointer to store the number of generated conflict constraints */
5407 int* nliterals, /**< pointer to store the number of literals in generated conflict constraints */
5408 int* nreconvconss, /**< pointer to store the number of generated reconvergence constraints */
5409 int* nreconvliterals /**< pointer to store the number of literals generated reconvergence constraints */
5410 )
5411{
5415 int nfirstuips;
5416 int focusdepth;
5417 int currentdepth;
5418 int maxvaliddepth;
5419 int resolvedepth;
5420 int nresolutions;
5423
5424 assert(conflict != NULL);
5425 assert(conflict->conflictset != NULL);
5426 assert(conflict->conflictset->nbdchginfos >= 0);
5427 assert(set != NULL);
5428 assert(stat != NULL);
5429 assert(0 <= validdepth && validdepth <= SCIPtreeGetCurrentDepth(tree));
5430 assert(nconss != NULL);
5431 assert(nliterals != NULL);
5434
5437 assert(currentdepth == tree->pathlen-1);
5439
5440 resolvedepth = ((set->conf_fuiplevels >= 0 && set->conf_fuiplevels <= currentdepth)
5441 ? currentdepth - set->conf_fuiplevels + 1 : 0);
5443
5444 /* if we must resolve at least one bound change, find the first UIP at least in the last depth level */
5445 if( mustresolve )
5447
5448 SCIPsetDebugMsg(set, "analyzing conflict with %d+%d conflict candidates and starting conflict set of size %d in depth %d (resolvedepth=%d)\n",
5451
5452 *nconss = 0;
5453 *nliterals = 0;
5454 *nreconvconss = 0;
5455 *nreconvliterals = 0;
5456
5457 /* check, whether local conflicts are allowed; however, don't generate conflict constraints that are only valid in the
5458 * probing path and not in the problem tree (i.e. that exceed the focusdepth)
5459 */
5460 maxvaliddepth = (set->conf_allowlocal ? MIN(currentdepth-1, focusdepth) : 0);
5461 if( validdepth > maxvaliddepth )
5462 return SCIP_OKAY;
5463
5464 /* allocate temporary memory for storing first UIPs (in each depth level, at most two bound changes can be flagged
5465 * as UIP, namely a binary and a non-binary bound change)
5466 */
5467 SCIP_CALL( SCIPsetAllocBufferArray(set, &firstuips, 2*(currentdepth+1)) ); /*lint !e647*/
5468
5469 /* process all bound changes in the conflict candidate queue */
5470 nresolutions = 0;
5471 lastconsnresolutions = (mustresolve ? 0 : -1);
5473 bdchginfo = conflictFirstCand(conflict);
5474 nfirstuips = 0;
5475
5476 /* check if the initial reason on debugging solution */
5477 SCIP_CALL( SCIPdebugCheckConflictFrontier(blkmem, set, tree->path[validdepth], \
5478 NULL, conflict->conflictset->bdchginfos, conflict->conflictset->relaxedbds, conflict->conflictset->nbdchginfos, \
5479 conflict->bdchgqueue, conflict->forcedbdchgqueue) ); /*lint !e506 !e774*/
5480
5481 while( bdchginfo != NULL && validdepth <= maxvaliddepth )
5482 {
5484 SCIP_Real relaxedbd;
5485 SCIP_Bool forceresolve;
5486 int bdchgdepth;
5487
5489
5490 /* check if the next bound change must be resolved in every case */
5492
5493 /* resolve next bound change in queue */
5498 assert(tree->path[bdchgdepth] != NULL);
5499 assert(tree->path[bdchgdepth]->domchg != NULL);
5507 == SCIPbdchginfoGetNewbound(bdchginfo)); /*lint !e777*/
5510
5511 /* create intermediate conflict constraint */
5513 if( !forceresolve )
5514 {
5516 lastconsresoldepth = bdchgdepth; /* all intermediate depth levels consisted of only unresolved bound changes */
5517 else if( bdchgdepth < lastconsresoldepth && (set->conf_interconss == -1 || *nconss < set->conf_interconss) )
5518 {
5519 int nlits;
5520 SCIP_Bool success;
5521
5522 /* call the conflict handlers to create a conflict set */
5523 SCIPsetDebugMsg(set, "creating intermediate conflictset after %d resolutions up to depth %d (valid at depth %d): %d conflict bounds, %d bounds in queue\n",
5524 nresolutions, bdchgdepth, validdepth, conflict->conflictset->nbdchginfos,
5525 SCIPpqueueNElems(conflict->bdchgqueue));
5526
5527 SCIP_CALL( conflictAddConflictset(conflict, blkmem, set, stat, tree, validdepth, diving, TRUE, &success, &nlits) );
5530 if( success )
5531 {
5532 (*nconss)++;
5533 (*nliterals) += nlits;
5534 }
5535 }
5536 }
5537
5538 /* remove currently processed candidate and get next conflicting bound from the conflict candidate queue before
5539 * we remove the candidate we have to collect the relaxed bound since removing the candidate from the queue
5540 * invalidates the relaxed bound
5541 */
5542 assert(bdchginfo == conflictFirstCand(conflict));
5544 bdchginfo = conflictRemoveCand(conflict);
5545 nextbdchginfo = conflictFirstCand(conflict);
5546 assert(bdchginfo != NULL);
5549 || forceresolve);
5550
5551 /* we don't need to resolve bound changes that are already active in the valid depth of the current conflict set,
5552 * because the conflict set can only be added locally at the valid depth, and all bound changes applied in this
5553 * depth or earlier can be removed from the conflict constraint, since they are already applied in the constraint's
5554 * subtree;
5555 * if the next bound change on the remaining queue is equal to the current bound change,
5556 * this is a multiple insertion in the conflict candidate queue and we can ignore the current
5557 * bound change
5558 */
5559 if( bdchgdepth > validdepth && bdchginfo != nextbdchginfo )
5560 {
5562 SCIP_Bool resolved;
5563
5565 assert(actvar != NULL);
5567
5568 /* check if we want to resolve the bound change in this depth level
5569 * - bound changes should be resolved, if
5570 * (i) we must apply at least one resolution and didn't resolve a bound change yet, or
5571 * (ii) their depth level is at least equal to the minimal resolving depth, and
5572 * they are not the last remaining conflicting bound change in their depth level
5573 * (iii) the bound change resolving is forced (i.e., the forced queue was non-empty)
5574 */
5575 resolved = FALSE;
5576 if( (mustresolve && nresolutions == 0)
5578 && nextbdchginfo != NULL
5580 || forceresolve )
5581 {
5582 SCIP_CALL( conflictResolveBound(conflict, set, bdchginfo, relaxedbd, validdepth, &resolved) );
5583 }
5584
5585 if( resolved )
5586 nresolutions++;
5587 else if( forceresolve )
5588 {
5589 /* variable cannot enter the conflict clause: we have to make the conflict clause local, s.t.
5590 * the unresolved bound change is active in the whole sub tree of the conflict clause
5591 */
5592 assert(bdchgdepth >= validdepth);
5593 validdepth = bdchgdepth;
5594
5595 SCIPsetDebugMsg(set, "couldn't resolve forced bound change on <%s> -> new valid depth: %d\n",
5596 SCIPvarGetName(actvar), validdepth);
5597 }
5598 else
5599 {
5600 /* if this is a UIP (the last bound change in its depth level), it can be used to generate a
5601 * UIP reconvergence constraint
5602 */
5604 {
5607 nfirstuips++;
5608 }
5609
5610 /* put variable into the conflict set, using the literal that is currently fixed to FALSE */
5612 }
5613 }
5614
5615 /* check conflict graph frontier on debugging solution */
5616 SCIP_CALL( SCIPdebugCheckConflictFrontier(blkmem, set, tree->path[validdepth], \
5617 bdchginfo, conflict->conflictset->bdchginfos, conflict->conflictset->relaxedbds, conflict->conflictset->nbdchginfos, \
5618 conflict->bdchgqueue, conflict->forcedbdchgqueue) ); /*lint !e506 !e774*/
5619
5620 /* get next conflicting bound from the conflict candidate queue (this needs not to be nextbdchginfo, because
5621 * due to resolving the bound changes, a bound change could be added to the queue which must be
5622 * resolved before nextbdchginfo)
5623 */
5624 bdchginfo = conflictFirstCand(conflict);
5625 }
5626
5627 /* check, if a valid conflict set was found */
5628 if( bdchginfo == NULL
5630 && validdepth <= maxvaliddepth
5631 && (!mustresolve || nresolutions > 0 || conflict->conflictset->nbdchginfos == 0)
5632 && SCIPpqueueNElems(conflict->forcedbdchgqueue) == 0 )
5633 {
5634 int nlits;
5635 SCIP_Bool success;
5636
5637 /* call the conflict handlers to create a conflict set */
5638 SCIP_CALL( conflictAddConflictset(conflict, blkmem, set, stat, tree, validdepth, diving, TRUE, &success, &nlits) );
5639 if( success )
5640 {
5641 (*nconss)++;
5642 (*nliterals) += nlits;
5643 }
5644 }
5645
5646 /* produce reconvergence constraints defined by succeeding UIP's of the last depth level */
5647 if( set->conf_reconvlevels != 0 && validdepth <= maxvaliddepth )
5648 {
5649 int reconvlevels;
5650 int i;
5651
5652 reconvlevels = (set->conf_reconvlevels == -1 ? INT_MAX : set->conf_reconvlevels);
5653 for( i = 0; i < nfirstuips; ++i )
5654 {
5657 {
5658 SCIP_CALL( conflictCreateReconvergenceConss(conflict, blkmem, set, stat, prob, tree, diving, \
5659 validdepth, firstuips[i], nreconvconss, nreconvliterals) );
5660 }
5661 }
5662 }
5663
5664 /* free the temporary memory */
5666
5667 /* store last conflict type */
5668 conftype = conflict->conflictset->conflicttype;
5669
5670 /* clear the conflict candidate queue and the conflict set */
5671 conflictClear(conflict);
5672
5673 /* restore last conflict type */
5674 conflict->conflictset->conflicttype = conftype;
5675
5676 return SCIP_OKAY;
5677}
5678
5679/** analyzes conflicting bound changes that were added with calls to SCIPconflictAddBound(), and on success, calls the
5680 * conflict handlers to create a conflict constraint out of the resulting conflict set;
5681 * updates statistics for propagation conflict analysis
5682 */
5684 SCIP_CONFLICT* conflict, /**< conflict analysis data */
5685 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
5686 SCIP_SET* set, /**< global SCIP settings */
5687 SCIP_STAT* stat, /**< problem statistics */
5688 SCIP_PROB* prob, /**< problem data */
5689 SCIP_TREE* tree, /**< branch and bound tree */
5690 int validdepth, /**< minimal depth level at which the initial conflict set is valid */
5691 SCIP_Bool* success /**< pointer to store whether a conflict constraint was created, or NULL */
5692 )
5693{
5694 int nconss;
5695 int nliterals;
5696 int nreconvconss;
5697 int nreconvliterals;
5698
5699 assert(conflict != NULL);
5700 assert(conflict->conflictset != NULL);
5701 assert(set != NULL);
5702 assert(prob != NULL);
5703
5704 if( success != NULL )
5705 *success = FALSE;
5706
5707 /* check if the conflict analysis is applicable */
5709 return SCIP_OKAY;
5710
5711 /* check, if the conflict set will get too large with high probability */
5712 if( conflict->conflictset->nbdchginfos + SCIPpqueueNElems(conflict->bdchgqueue)
5713 + SCIPpqueueNElems(conflict->forcedbdchgqueue) >= 2*conflictCalcMaxsize(set, prob) )
5714 return SCIP_OKAY;
5715
5716 SCIPsetDebugMsg(set, "analyzing conflict after infeasible propagation in depth %d\n", SCIPtreeGetCurrentDepth(tree));
5717
5718 /* start timing */
5720
5721 conflict->npropcalls++;
5722
5723 /* analyze the conflict set, and create a conflict constraint on success */
5724 SCIP_CALL( conflictAnalyze(conflict, blkmem, set, stat, prob, tree, FALSE, validdepth, TRUE, &nconss, &nliterals, \
5726 conflict->npropsuccess += (nconss > 0 ? 1 : 0);
5727 conflict->npropconfconss += nconss;
5728 conflict->npropconfliterals += nliterals;
5729 conflict->npropreconvconss += nreconvconss;
5731 if( success != NULL )
5732 *success = (nconss > 0);
5733
5734 /* stop timing */
5735 SCIPclockStop(conflict->propanalyzetime, set);
5736
5737 return SCIP_OKAY;
5738}
5739
5740/** gets time in seconds used for preprocessing global conflict constraint before appliance */
5742 SCIP_CONFLICT* conflict /**< conflict analysis data */
5743 )
5744{
5745 assert(conflict != NULL);
5746
5747 return SCIPclockGetTime(conflict->dIBclock);
5748}
5749
5750/** gets time in seconds used for analyzing propagation conflicts */
5752 SCIP_CONFLICT* conflict /**< conflict analysis data */
5753 )
5754{
5755 assert(conflict != NULL);
5756
5757 return SCIPclockGetTime(conflict->propanalyzetime);
5758}
5759
5760/** gets number of calls to propagation conflict analysis */
5762 SCIP_CONFLICT* conflict /**< conflict analysis data */
5763 )
5764{
5765 assert(conflict != NULL);
5766
5767 return conflict->npropcalls;
5768}
5769
5770/** gets number of calls to propagation conflict analysis that yield at least one conflict constraint */
5772 SCIP_CONFLICT* conflict /**< conflict analysis data */
5773 )
5774{
5775 assert(conflict != NULL);
5776
5777 return conflict->npropsuccess;
5778}
5779
5780/** gets number of conflict constraints detected in propagation conflict analysis */
5782 SCIP_CONFLICT* conflict /**< conflict analysis data */
5783 )
5784{
5785 assert(conflict != NULL);
5786
5787 return conflict->npropconfconss;
5788}
5789
5790/** gets total number of literals in conflict constraints created in propagation conflict analysis */
5792 SCIP_CONFLICT* conflict /**< conflict analysis data */
5793 )
5794{
5795 assert(conflict != NULL);
5796
5797 return conflict->npropconfliterals;
5798}
5799
5800/** gets number of reconvergence constraints detected in propagation conflict analysis */
5802 SCIP_CONFLICT* conflict /**< conflict analysis data */
5803 )
5804{
5805 assert(conflict != NULL);
5806
5807 return conflict->npropreconvconss;
5808}
5809
5810/** gets total number of literals in reconvergence constraints created in propagation conflict analysis */
5812 SCIP_CONFLICT* conflict /**< conflict analysis data */
5813 )
5814{
5815 assert(conflict != NULL);
5816
5817 return conflict->npropreconvliterals;
5818}
5819
5820
5821
5822
5823/*
5824 * Infeasible LP Conflict Analysis
5825 */
5826
5827/** ensures, that side change arrays can store at least num entries */
5828static
5830 SCIP_SET* set, /**< global SCIP settings */
5831 int** sidechginds, /**< pointer to side change index array */
5832 SCIP_Real** sidechgoldlhss, /**< pointer to side change old left hand sides array */
5833 SCIP_Real** sidechgoldrhss, /**< pointer to side change old right hand sides array */
5834 SCIP_Real** sidechgnewlhss, /**< pointer to side change new left hand sides array */
5835 SCIP_Real** sidechgnewrhss, /**< pointer to side change new right hand sides array */
5836 int* sidechgssize, /**< pointer to size of side change arrays */
5837 int num /**< minimal number of entries to be able to store in side change arrays */
5838 )
5839{
5846
5847 if( num > *sidechgssize )
5848 {
5849 int newsize;
5850
5858 }
5859 assert(num <= *sidechgssize);
5860
5861 return SCIP_OKAY;
5862}
5863
5864/** adds removal of row's side to side change arrays; finite sides are only replaced by near infinite sides, such
5865 * that the row's sense in the LP solver is not changed
5866 */
5867static
5869 SCIP_SET* set, /**< global SCIP settings */
5870 SCIP_ROW* row, /**< LP row to change the sides for */
5871 SCIP_Real lpiinfinity, /**< value treated as infinity in LP solver */
5872 int** sidechginds, /**< pointer to side change index array */
5873 SCIP_Real** sidechgoldlhss, /**< pointer to side change old left hand sides array */
5874 SCIP_Real** sidechgoldrhss, /**< pointer to side change old right hand sides array */
5875 SCIP_Real** sidechgnewlhss, /**< pointer to side change new left hand sides array */
5876 SCIP_Real** sidechgnewrhss, /**< pointer to side change new right hand sides array */
5877 int* sidechgssize, /**< pointer to size of side change arrays */
5878 int* nsidechgs /**< pointer to number of used slots in side change arrays */
5879 )
5880{
5881 SCIP_Real lhs;
5882 SCIP_Real rhs;
5883 SCIP_Real constant;
5884
5891 assert(nsidechgs != NULL);
5892
5893 lhs = SCIProwGetLhs(row);
5894 rhs = SCIProwGetRhs(row);
5895 constant = SCIProwGetConstant(row);
5897
5898 /* get memory to store additional side change */
5900 sidechgssize, (*nsidechgs)+1) );
5902 assert(*sidechginds != NULL);
5907
5908 /* store side change */
5909 (*sidechginds)[*nsidechgs] = SCIProwGetLPPos(row);
5910 if( SCIPsetIsInfinity(set, -lhs) )
5911 {
5912 (*sidechgoldlhss)[*nsidechgs] = -lpiinfinity;
5913 (*sidechgnewlhss)[*nsidechgs] = -lpiinfinity;
5914 }
5915 else
5916 {
5917 (*sidechgoldlhss)[*nsidechgs] = lhs - constant;
5918 (*sidechgnewlhss)[*nsidechgs] = -lpiinfinity;
5919 }
5920 if( SCIPsetIsInfinity(set, rhs) )
5921 {
5922 (*sidechgoldrhss)[*nsidechgs] = lpiinfinity;
5923 (*sidechgnewrhss)[*nsidechgs] = lpiinfinity;
5924 }
5925 else
5926 {
5927 (*sidechgoldrhss)[*nsidechgs] = rhs - constant;
5928 (*sidechgnewrhss)[*nsidechgs] = lpiinfinity;
5929 }
5930 (*nsidechgs)++;
5931
5932 return SCIP_OKAY;
5933}
5934
5935/** inserts variable's new bounds into bound change arrays */
5936static
5938 SCIP_SET* set, /**< global SCIP settings */
5939 SCIP_VAR* var, /**< variable to change the LP bounds for */
5940 SCIP_Real newlb, /**< new lower bound */
5941 SCIP_Real newub, /**< new upper bound */
5942 SCIP_LPBDCHGS* oldlpbdchgs, /**< old LP bound changes used for reset the LP bound change */
5943 SCIP_LPBDCHGS* relaxedlpbdchgs, /**< relaxed LP bound changes used for reset the LP bound change */
5944 SCIP_LPI* lpi /**< pointer to LPi to access infinity of LP solver; necessary to set correct value */
5945 )
5946{
5947 assert(newlb <= newub);
5950
5952 {
5953 SCIP_COL* col;
5954 int idx;
5955 int c;
5956
5957 col = SCIPvarGetCol(var);
5958 c = SCIPcolGetLPPos(col);
5959
5960 if( c >= 0 )
5961 {
5962 /* store old bound change for resetting the LP later */
5963 if( !oldlpbdchgs->usedcols[c] )
5964 {
5965 idx = oldlpbdchgs->nbdchgs;
5966 oldlpbdchgs->usedcols[c] = TRUE;
5967 oldlpbdchgs->bdchgcolinds[c] = idx;
5968 oldlpbdchgs->nbdchgs++;
5969
5970 oldlpbdchgs->bdchginds[idx] = c;
5971 oldlpbdchgs->bdchglbs[idx] = SCIPvarGetLbLP(var, set);
5972 oldlpbdchgs->bdchgubs[idx] = SCIPvarGetUbLP(var, set);
5973 }
5974 assert(oldlpbdchgs->bdchginds[oldlpbdchgs->bdchgcolinds[c]] == c);
5975 assert((SCIPlpiIsInfinity(lpi, -oldlpbdchgs->bdchglbs[oldlpbdchgs->bdchgcolinds[c]]) && SCIPsetIsInfinity(set, -SCIPvarGetLbLP(var, set))) ||
5976 SCIPsetIsEQ(set, oldlpbdchgs->bdchglbs[oldlpbdchgs->bdchgcolinds[c]], SCIPvarGetLbLP(var, set)));
5977 assert((SCIPlpiIsInfinity(lpi, oldlpbdchgs->bdchgubs[oldlpbdchgs->bdchgcolinds[c]]) && SCIPsetIsInfinity(set, SCIPvarGetUbLP(var, set))) ||
5978 SCIPsetIsEQ(set, oldlpbdchgs->bdchgubs[oldlpbdchgs->bdchgcolinds[c]], SCIPvarGetUbLP(var, set)));
5979
5980 /* store bound change for conflict analysis */
5981 if( !relaxedlpbdchgs->usedcols[c] )
5982 {
5983 idx = relaxedlpbdchgs->nbdchgs;
5984 relaxedlpbdchgs->usedcols[c] = TRUE;
5985 relaxedlpbdchgs->bdchgcolinds[c] = idx;
5986 relaxedlpbdchgs->nbdchgs++;
5987
5988 /* remember the positive for later further bound widenings */
5989 relaxedlpbdchgs->bdchginds[idx] = c;
5990 }
5991 else
5992 {
5993 idx = relaxedlpbdchgs->bdchgcolinds[c];
5994 assert(relaxedlpbdchgs->bdchginds[idx] == c);
5995
5996 /* the new bound should be the same or more relaxed */
5997 assert(relaxedlpbdchgs->bdchglbs[idx] >= newlb ||
5998 (SCIPlpiIsInfinity(lpi, -relaxedlpbdchgs->bdchglbs[idx]) && SCIPsetIsInfinity(set, -newlb)));
5999 assert(relaxedlpbdchgs->bdchgubs[idx] <= newub ||
6000 (SCIPlpiIsInfinity(lpi, relaxedlpbdchgs->bdchgubs[idx]) && SCIPsetIsInfinity(set, newub)));
6001 }
6002
6003 /* set the new bounds for the LP with the correct infinity value */
6004 relaxedlpbdchgs->bdchglbs[idx] = SCIPsetIsInfinity(set, -newlb) ? -SCIPlpiInfinity(lpi) : newlb;
6005 relaxedlpbdchgs->bdchgubs[idx] = SCIPsetIsInfinity(set, newub) ? SCIPlpiInfinity(lpi) : newub;
6006 if( SCIPsetIsInfinity(set, -oldlpbdchgs->bdchglbs[idx]) )
6007 oldlpbdchgs->bdchglbs[idx] = -SCIPlpiInfinity(lpi);
6008 if( SCIPsetIsInfinity(set, oldlpbdchgs->bdchgubs[idx]) )
6009 oldlpbdchgs->bdchgubs[idx] = SCIPlpiInfinity(lpi);
6010 }
6011 }
6012
6013 return SCIP_OKAY;
6014}
6015
6016/** ensures, that candidate array can store at least num entries */
6017static
6019 SCIP_SET* set, /**< global SCIP settings */
6020 SCIP_VAR*** cands, /**< pointer to candidate array */
6021 SCIP_Real** candscores, /**< pointer to candidate score array */
6022 SCIP_Real** newbounds, /**< pointer to candidate new bounds array */
6023 SCIP_Real** proofactdeltas, /**< pointer to candidate proof delta array */
6024 int* candssize, /**< pointer to size of array */
6025 int num /**< minimal number of candidates to store in array */
6026 )
6027{
6028 assert(cands != NULL);
6029 assert(candssize != NULL);
6030
6031 if( num > *candssize )
6032 {
6033 int newsize;
6034
6040 *candssize = newsize;
6041 }
6042 assert(num <= *candssize);
6043
6044 return SCIP_OKAY;
6045}
6046
6047/** adds variable to candidate list, if the current best bound corresponding to the proof coefficient is local;
6048 * returns the array position in the candidate list, where the new candidate was inserted, or -1 if the
6049 * variable can relaxed to global bounds immediately without increasing the proof's activity;
6050 * the candidates are sorted with respect to the following two criteria:
6051 * - prefer bound changes that have been applied deeper in the tree, to get a more global conflict
6052 * - prefer variables with small Farkas coefficient to get rid of as many bound changes as possible
6053 */
6054static
6056 SCIP_SET* set, /**< global SCIP settings */
6057 int currentdepth, /**< current depth in the tree */
6058 SCIP_VAR* var, /**< variable to add to candidate array */
6059 int lbchginfopos, /**< positions of currently active lower bound change information in variable's array */
6060 int ubchginfopos, /**< positions of currently active upper bound change information in variable's array */
6061 SCIP_Real proofcoef, /**< coefficient of variable in infeasibility/bound proof */
6062 SCIP_Real prooflhs, /**< left hand side of infeasibility/bound proof */
6063 SCIP_Real proofact, /**< activity of infeasibility/bound proof row */
6064 SCIP_VAR*** cands, /**< pointer to candidate array for undoing bound changes */
6065 SCIP_Real** candscores, /**< pointer to candidate score array for undoing bound changes */
6066 SCIP_Real** newbounds, /**< pointer to candidate new bounds array for undoing bound changes */
6067 SCIP_Real** proofactdeltas, /**< pointer to proof activity increase array for undoing bound changes */
6068 int* candssize, /**< pointer to size of cands arrays */
6069 int* ncands, /**< pointer to count number of candidates in bound change list */
6070 int firstcand /**< position of first unprocessed bound change candidate */
6071 )
6072{
6073 SCIP_Real oldbound;
6074 SCIP_Real newbound;
6075 SCIP_Real QUAD(proofactdelta);
6076 SCIP_Real score;
6077 int depth;
6078 int i;
6079 SCIP_Bool resolvable;
6080
6081 assert(set != NULL);
6082 assert(var != NULL);
6083 assert(-1 <= lbchginfopos && lbchginfopos <= var->nlbchginfos);
6084 assert(-1 <= ubchginfopos && ubchginfopos <= var->nubchginfos);
6087 assert(cands != NULL);
6088 assert(candscores != NULL);
6089 assert(newbounds != NULL);
6091 assert(candssize != NULL);
6092 assert(ncands != NULL);
6093 assert(*ncands <= *candssize);
6094 assert(0 <= firstcand && firstcand <= *ncands);
6095
6096 /* in the infeasibility or dual bound proof, the variable's bound is chosen to maximize the proof's activity */
6097 if( proofcoef > 0.0 )
6098 {
6099 assert(ubchginfopos >= 0); /* otherwise, undoBdchgsProof() should already have relaxed the local bound */
6100
6101 /* calculate the difference of current bound to the previous bound the variable was set to */
6102 if( ubchginfopos == var->nubchginfos )
6103 {
6104 /* current bound is the strong branching or diving bound */
6105 oldbound = SCIPvarGetUbLP(var, set);
6106 newbound = SCIPvarGetUbLocal(var);
6107 depth = currentdepth+1;
6108 resolvable = FALSE;
6109 }
6110 else
6111 {
6112 /* current bound is the result of a local bound change */
6115 oldbound = var->ubchginfos[ubchginfopos].newbound;
6116 newbound = var->ubchginfos[ubchginfopos].oldbound;
6117 }
6118 }
6119 else
6120 {
6121 assert(lbchginfopos >= 0); /* otherwise, undoBdchgsProof() should already have relaxed the local bound */
6122
6123 /* calculate the difference of current bound to the previous bound the variable was set to */
6124 if( lbchginfopos == var->nlbchginfos )
6125 {
6126 /* current bound is the strong branching or diving bound */
6127 oldbound = SCIPvarGetLbLP(var, set);
6128 newbound = SCIPvarGetLbLocal(var);
6129 depth = currentdepth+1;
6130 resolvable = FALSE;
6131 }
6132 else
6133 {
6134 /* current bound is the result of a local bound change */
6137 oldbound = var->lbchginfos[lbchginfopos].newbound;
6138 newbound = var->lbchginfos[lbchginfopos].oldbound;
6139 }
6140 }
6141
6142 /* calculate the increase in the proof's activity */
6143 SCIPquadprecSumDD(proofactdelta, newbound, -oldbound);
6146
6147 /* calculate score for undoing the bound change */
6149
6150 if( !resolvable )
6151 {
6152 score += 10.0;
6153 if( !SCIPvarIsBinary(var) )
6154 score += 10.0;
6155 }
6156
6157 /* get enough memory to store new candidate */
6158 SCIP_CALL( ensureCandsSize(set, cands, candscores, newbounds, proofactdeltas, candssize, (*ncands)+1) );
6159 assert(*cands != NULL);
6160 assert(*candscores != NULL);
6161 assert(*newbounds != NULL);
6163
6164 SCIPsetDebugMsg(set, " -> local <%s> %s %g, relax <%s> %s %g, proofcoef=%g, dpt=%d, resolve=%u, delta=%g, score=%g\n",
6165 SCIPvarGetName(var), proofcoef > 0.0 ? "<=" : ">=", oldbound,
6166 SCIPvarGetName(var), proofcoef > 0.0 ? "<=" : ">=", newbound,
6168
6169 /* insert variable in candidate list without touching the already processed candidates */
6170 for( i = *ncands; i > firstcand && score > (*candscores)[i-1]; --i )
6171 {
6172 (*cands)[i] = (*cands)[i-1];
6173 (*candscores)[i] = (*candscores)[i-1];
6174 (*newbounds)[i] = (*newbounds)[i-1];
6175 (*proofactdeltas)[i] = (*proofactdeltas)[i-1];
6176 }
6177 (*cands)[i] = var;
6178 (*candscores)[i] = score;
6179 (*newbounds)[i] = newbound;
6180 (*proofactdeltas)[i] = QUAD_TO_DBL(proofactdelta);
6181 (*ncands)++;
6182
6183 return SCIP_OKAY;
6184}
6185
6186/** after changing the global bound of a variable, the bdchginfos that are now redundant are replaced with
6187 * oldbound = newbound = global bound; if the current bdchginfo is of such kind, the bound is equal to the
6188 * global bound and we can ignore it by installing a -1 as the corresponding bound change info position
6189 */
6190static
6192 SCIP_VAR* var, /**< problem variable */
6193 int* lbchginfopos, /**< pointer to lower bound change information position */
6194 int* ubchginfopos /**< pointer to upper bound change information position */
6195 )
6196{
6197 assert(var != NULL);
6200 assert(-1 <= *lbchginfopos && *lbchginfopos <= var->nlbchginfos);
6201 assert(-1 <= *ubchginfopos && *ubchginfopos <= var->nubchginfos);
6204 == (var->lbchginfos[*lbchginfopos].oldbound == var->lbchginfos[*lbchginfopos].newbound)); /*lint !e777*/
6207 == (var->ubchginfos[*ubchginfopos].oldbound == var->ubchginfos[*ubchginfopos].newbound)); /*lint !e777*/
6208
6209 if( *lbchginfopos >= 0 && *lbchginfopos < var->nlbchginfos && var->lbchginfos[*lbchginfopos].redundant )
6210 {
6212 *lbchginfopos = -1;
6213 }
6214 if( *ubchginfopos >= 0 && *ubchginfopos < var->nubchginfos && var->ubchginfos[*ubchginfopos].redundant )
6215 {
6217 *ubchginfopos = -1;
6218 }
6219}
6220
6221/** undoes bound changes on variables, still leaving the given infeasibility proof valid */
6222static
6224 SCIP_SET* set, /**< global SCIP settings */
6225 SCIP_PROB* prob, /**< problem data */
6226 int currentdepth, /**< current depth in the tree */
6227 SCIP_Real* proofcoefs, /**< coefficients in infeasibility proof */
6228 SCIP_Real prooflhs, /**< left hand side of proof */
6229 SCIP_Real* proofact, /**< current activity of proof */
6230 SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
6231 SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
6232 int* lbchginfoposs, /**< positions of currently active lower bound change information in variables' arrays */
6233 int* ubchginfoposs, /**< positions of currently active upper bound change information in variables' arrays */
6234 SCIP_LPBDCHGS* oldlpbdchgs, /**< old LP bound changes used for reset the LP bound change, or NULL */
6235 SCIP_LPBDCHGS* relaxedlpbdchgs, /**< relaxed LP bound changes used for reset the LP bound change, or NULL */
6236 SCIP_Bool* resolve, /**< pointer to store whether the changed LP should be resolved again, or NULL */
6237 SCIP_LPI* lpi /**< pointer to LPi to access infinity of LP solver; necessary to set correct values */
6238 )
6239{
6240 SCIP_VAR** vars;
6241 SCIP_VAR** cands;
6242 SCIP_Real* candscores;
6243 SCIP_Real* newbounds;
6244 SCIP_Real* proofactdeltas;
6245 int nvars;
6246 int ncands;
6247 int candssize;
6248 int v;
6249 int i;
6250
6251 assert(prob != NULL);
6254 assert(curvarlbs != NULL);
6255 assert(curvarubs != NULL);
6258
6259 if( resolve != NULL )
6260 *resolve = FALSE;
6261
6262 vars = prob->vars;
6263 nvars = prob->nvars;
6264 assert(nvars == 0 || vars != NULL);
6265
6266 /* calculate the order in which the bound changes are tried to be undone, and relax all bounds if this doesn't
6267 * increase the proof's activity
6268 */
6270 SCIP_CALL( SCIPsetAllocBufferArray(set, &candscores, nvars) );
6273 ncands = 0;
6274 candssize = nvars;
6275 for( v = 0; v < nvars; ++v )
6276 {
6277 SCIP_VAR* var;
6278 SCIP_Bool relaxed;
6279
6280 var = vars[v];
6281
6282 /* after changing the global bound of a variable, the bdchginfos that are now redundant are replaced with
6283 * oldbound = newbound = global bound; if the current bdchginfo is of such kind, the bound is equal to the
6284 * global bound and we can ignore it
6285 */
6287
6288 /* ignore variables already relaxed to global bounds */
6289 if( (lbchginfoposs[v] == -1 && ubchginfoposs[v] == -1) )
6290 {
6291 proofcoefs[v] = 0.0;
6292 continue;
6293 }
6294
6295 /* relax bounds that are not used in the proof to the global bounds */
6296 relaxed = FALSE;
6297 if( !SCIPsetIsNegative(set, proofcoefs[v]) )
6298 {
6299 /* the lower bound is not used */
6300 if( lbchginfoposs[v] >= 0 )
6301 {
6302 SCIPsetDebugMsg(set, " -> relaxing variable <%s>[%g,%g] to [%g,%g]: proofcoef=%g, %g <= %g\n",
6304 proofcoefs[v], prooflhs, (*proofact));
6306 lbchginfoposs[v] = -1;
6307 relaxed = TRUE;
6308 }
6309 }
6310 if( !SCIPsetIsPositive(set, proofcoefs[v]) )
6311 {
6312 /* the upper bound is not used */
6313 if( ubchginfoposs[v] >= 0 )
6314 {
6315 SCIPsetDebugMsg(set, " -> relaxing variable <%s>[%g,%g] to [%g,%g]: proofcoef=%g, %g <= %g\n",
6317 proofcoefs[v], prooflhs, (*proofact));
6319 ubchginfoposs[v] = -1;
6320 relaxed = TRUE;
6321 }
6322 }
6323 if( relaxed && oldlpbdchgs != NULL )
6324 {
6326 }
6327
6328 /* add bound to candidate list */
6329 if( lbchginfoposs[v] >= 0 || ubchginfoposs[v] >= 0 )
6330 {
6332 prooflhs, (*proofact), &cands, &candscores, &newbounds, &proofactdeltas, &candssize, &ncands, 0) );
6333 }
6334 /* we can set the proof coefficient to zero, because the variable is not needed */
6335 else
6336 proofcoefs[v] = 0.0;
6337 }
6338
6339 /* try to undo remaining local bound changes while still keeping the proof row violated:
6340 * bound changes can be undone, if prooflhs > proofact + proofactdelta;
6341 * afterwards, the current proof activity has to be updated
6342 */
6343 for( i = 0; i < ncands; ++i )
6344 {
6345 assert(proofactdeltas[i] > 0.0);
6346 assert((lbchginfoposs[SCIPvarGetProbindex(cands[i])] >= 0) != (ubchginfoposs[SCIPvarGetProbindex(cands[i])] >= 0));
6347
6348 /* when relaxing a constraint we still need to stay infeasible; therefore we need to do the comparison in
6349 * feasibility tolerance because if 'prooflhs' is (feas-))equal to 'proofact + proofactdeltas[i]' it would mean
6350 * that there is no violation
6351 */
6353 {
6354 v = SCIPvarGetProbindex(cands[i]);
6355 assert(0 <= v && v < nvars);
6356 assert((lbchginfoposs[v] >= 0) != (ubchginfoposs[v] >= 0));
6357
6358 SCIPsetDebugMsg(set, " -> relaxing variable <%s>[%g,%g] to [%g,%g]: proofcoef=%g, %g <= %g + %g\n",
6359 SCIPvarGetName(cands[i]), curvarlbs[v], curvarubs[v],
6360 proofcoefs[v] > 0.0 ? curvarlbs[v] : newbounds[i],
6361 proofcoefs[v] > 0.0 ? newbounds[i] : curvarubs[v],
6362 proofcoefs[v], prooflhs, (*proofact), proofactdeltas[i]);
6363
6364#ifndef NDEBUG
6365 {
6366 SCIP_Real QUAD(verifylb);
6367 SCIP_Real QUAD(verifyub);
6368
6371
6374
6382 }
6383#endif
6384
6385 if( proofcoefs[v] > 0.0 )
6386 {
6387 assert(ubchginfoposs[v] >= 0);
6388 assert(lbchginfoposs[v] == -1);
6389 curvarubs[v] = newbounds[i];
6390 ubchginfoposs[v]--;
6391 }
6392 else
6393 {
6394 assert(lbchginfoposs[v] >= 0);
6395 assert(ubchginfoposs[v] == -1);
6396 curvarlbs[v] = newbounds[i];
6397 lbchginfoposs[v]--;
6398 }
6399 if( oldlpbdchgs != NULL )
6400 {
6402 }
6403 (*proofact) += proofactdeltas[i];
6404 if( resolve != NULL && SCIPvarIsInLP(cands[i]) )
6405 *resolve = TRUE;
6406
6407 /* after changing the global bound of a variable, the bdchginfos that are now redundant are replaced with
6408 * oldbound = newbound = global bound; if the current bdchginfo is of such kind, the bound is equal to the
6409 * global bound and we can ignore it
6410 */
6412
6413 /* insert the new local bound of the variable into the candidate list */
6414 if( lbchginfoposs[v] >= 0 || ubchginfoposs[v] >= 0 )
6415 {
6417 prooflhs, (*proofact), &cands, &candscores, &newbounds, &proofactdeltas, &candssize, &ncands, i+1) );
6418 }
6419 else
6420 proofcoefs[v] = 0.0;
6421 }
6422 }
6423
6424 /* free the buffer for the sorted bound change candidates */
6427 SCIPsetFreeBufferArray(set, &candscores);
6428 SCIPsetFreeBufferArray(set, &cands);
6429
6430 return SCIP_OKAY;
6431}
6432
6433/* because calculations might cancel out some values, we stop the infeasibility analysis if a value is bigger than
6434 * 2^53 = 9007199254740992
6435 */
6436#define NUMSTOP 9007199254740992.0
6437
6438/** analyzes an infeasible LP and undoes additional bound changes while staying infeasible */
6439static
6441 SCIP_SET* set, /**< global SCIP settings */
6442 SCIP_PROB* prob, /**< problem data */
6443 SCIP_LP* lp, /**< LP data */
6444 int currentdepth, /**< current depth in the tree */
6445 SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
6446 SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
6447 int* lbchginfoposs, /**< positions of currently active lower bound change information in variables' arrays */
6448 int* ubchginfoposs, /**< positions of currently active upper bound change information in variables' arrays */
6449 SCIP_LPBDCHGS* oldlpbdchgs, /**< old LP bound changes used for reset the LP bound change, or NULL */
6450 SCIP_LPBDCHGS* relaxedlpbdchgs, /**< relaxed LP bound changes used for reset the LP bound change, or NULL */
6451 SCIP_Bool* valid, /**< pointer to store whether the unfixings are valid */
6452 SCIP_Bool* resolve, /**< pointer to store whether the changed LP should be resolved again */
6453 SCIP_Real* farkascoefs, /**< coefficients in the proof constraint */
6454 SCIP_Real farkaslhs, /**< lhs of the proof constraint */
6455 SCIP_Real* farkasactivity /**< maximal activity of the proof constraint */
6456 )
6457{
6458 SCIP_LPI* lpi;
6459
6460 assert(prob != NULL);
6461 assert(lp != NULL);
6462 assert(lp->flushed);
6463 assert(lp->solved);
6464 assert(curvarlbs != NULL);
6465 assert(curvarubs != NULL);
6468 assert(valid != NULL);
6469 assert(resolve != NULL);
6470
6471 SCIPsetDebugMsg(set, "undoing bound changes in infeasible LP: cutoff=%g\n", lp->cutoffbound);
6472
6473 *valid = FALSE;
6474 *resolve = FALSE;
6475
6476 lpi = SCIPlpGetLPI(lp);
6477
6478 /* check, if the Farkas row is still violated (using current bounds and ignoring local rows) */
6480 {
6481 /* undo bound changes while keeping the infeasibility proof valid */
6484
6485 *valid = TRUE;
6486
6487 /* resolving does not make sense: the old dual ray is still valid -> resolving will not change the solution */
6488 *resolve = FALSE;
6489 }
6490
6491 return SCIP_OKAY;
6492}
6493
6494/** analyzes an LP exceeding the objective limit and undoes additional bound changes while staying beyond the
6495 * objective limit
6496 */
6497static
6499 SCIP_SET* set, /**< global SCIP settings */
6500 SCIP_PROB* prob, /**< problem data */
6501 SCIP_LP* lp, /**< LP data */
6502 int currentdepth, /**< current depth in the tree */
6503 SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
6504 SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
6505 int* lbchginfoposs, /**< positions of currently active lower bound change information in variables' arrays */
6506 int* ubchginfoposs, /**< positions of currently active upper bound change information in variables' arrays */
6507 SCIP_LPBDCHGS* oldlpbdchgs, /**< old LP bound changes used for reset the LP bound change, or NULL */
6508 SCIP_LPBDCHGS* relaxedlpbdchgs, /**< relaxed LP bound changes used for reset the LP bound change, or NULL */
6509 SCIP_Bool* valid, /**< pointer to store whether the unfixings are valid */
6510 SCIP_Bool* resolve, /**< pointer to store whether the changed LP should be resolved again */
6511 SCIP_Real* dualcoefs, /**< coefficients in the proof constraint */
6512 SCIP_Real duallhs, /**< lhs of the proof constraint */
6513 SCIP_Real* dualactivity /**< maximal activity of the proof constraint */
6514 )
6515{
6516 SCIP_LPI* lpi;
6517
6518 assert(set != NULL);
6519 assert(prob != NULL);
6520 assert(lp != NULL);
6521 assert(lp->flushed);
6522 assert(lp->solved);
6523 assert(curvarlbs != NULL);
6524 assert(curvarubs != NULL);
6527 assert(valid != NULL);
6528 assert(resolve != NULL);
6529
6530 *valid = FALSE;
6531 *resolve = FALSE;
6532
6533 SCIPsetDebugMsg(set, "undoing bound changes in LP exceeding cutoff: cutoff=%g\n", lp->cutoffbound);
6534
6535 /* get LP solver interface */
6536 lpi = SCIPlpGetLPI(lp);
6537
6538 /* check, if the dual row is still violated (using current bounds and ignoring local rows) */
6540 {
6541 /* undo bound changes while keeping the infeasibility proof valid */
6544
6545 *valid = TRUE;
6546 }
6547
6548 return SCIP_OKAY;
6549}
6550
6551/** applies conflict analysis starting with given bound changes, that could not be undone during previous
6552 * infeasibility analysis
6553 */
6554static
6556 SCIP_CONFLICT* conflict, /**< conflict analysis data */
6557 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
6558 SCIP_SET* set, /**< global SCIP settings */
6559 SCIP_STAT* stat, /**< problem statistics */
6560 SCIP_PROB* prob, /**< problem data */
6561 SCIP_TREE* tree, /**< branch and bound tree */
6562 SCIP_Bool diving, /**< are we in strong branching or diving mode? */
6563 int* lbchginfoposs, /**< positions of currently active lower bound change information in variables' arrays */
6564 int* ubchginfoposs, /**< positions of currently active upper bound change information in variables' arrays */
6565 int* nconss, /**< pointer to store the number of generated conflict constraints */
6566 int* nliterals, /**< pointer to store the number of literals in generated conflict constraints */
6567 int* nreconvconss, /**< pointer to store the number of generated reconvergence constraints */
6568 int* nreconvliterals /**< pointer to store the number of literals generated reconvergence constraints */
6569 )
6570{
6571 SCIP_VAR** vars;
6572 SCIP_VAR* var;
6574 SCIP_Bool usescutoffbound;
6575 int nvars;
6576 int v;
6577 int nbdchgs;
6578 int maxsize;
6579
6580 assert(prob != NULL);
6583 assert(nconss != NULL);
6584 assert(nliterals != NULL);
6587
6588 *nconss = 0;
6589 *nliterals = 0;
6590 *nreconvconss = 0;
6591 *nreconvliterals = 0;
6592
6593 vars = prob->vars;
6594 nvars = prob->nvars;
6595 assert(nvars == 0 || vars != NULL);
6596
6597 maxsize = 2*conflictCalcMaxsize(set, prob);
6598
6599 /* initialize conflict data */
6600 conftype = conflict->conflictset->conflicttype;
6601 usescutoffbound = conflict->conflictset->usescutoffbound;
6602
6603 SCIP_CALL( SCIPconflictInit(conflict, set, stat, prob, conftype, usescutoffbound) );
6604
6605 conflict->conflictset->conflicttype = conftype;
6606 conflict->conflictset->usescutoffbound = usescutoffbound;
6607
6608 /* add remaining bound changes to conflict queue */
6609 SCIPsetDebugMsg(set, "initial conflict set after undoing bound changes:\n");
6610
6611 nbdchgs = 0;
6612 for( v = 0; v < nvars && nbdchgs < maxsize; ++v )
6613 {
6614 var = vars[v];
6615 assert(var != NULL);
6616 assert(var->nlbchginfos >= 0);
6617 assert(var->nubchginfos >= 0);
6618 assert(-1 <= lbchginfoposs[v] && lbchginfoposs[v] <= var->nlbchginfos);
6619 assert(-1 <= ubchginfoposs[v] && ubchginfoposs[v] <= var->nubchginfos);
6620
6622 {
6624 SCIP_Real relaxedbd;
6625
6626 /* the strong branching or diving bound stored in the column is responsible for the conflict:
6627 * it cannot be resolved and therefore has to be directly put into the conflict set
6628 */
6629 assert((lbchginfoposs[v] == var->nlbchginfos) != (ubchginfoposs[v] == var->nubchginfos)); /* only one can be tight in the dual! */
6632
6633 /* create an artificial bound change information for the diving/strong branching bound change;
6634 * they are freed in the SCIPconflictFlushConss() call
6635 */
6636 if( lbchginfoposs[v] == var->nlbchginfos )
6637 {
6641 }
6642 else
6643 {
6647 }
6648
6649 /* put variable into the conflict set */
6650 SCIPsetDebugMsg(set, " force: <%s> %s %g [status: %d, type: %d, dive/strong]\n",
6651 SCIPvarGetName(var), lbchginfoposs[v] == var->nlbchginfos ? ">=" : "<=",
6655
6656 /* each variable which is add to the conflict graph gets an increase in the VSIDS
6657 *
6658 * @note That is different to the VSIDS preseted in the literature
6659 */
6660 SCIP_CALL( incVSIDS(var, blkmem, set, stat, SCIPbdchginfoGetBoundtype(bdchginfo), relaxedbd, set->conf_conflictgraphweight) );
6661 nbdchgs++;
6662 }
6663 else
6664 {
6665 /* put remaining bound changes into conflict candidate queue */
6666 if( lbchginfoposs[v] >= 0 )
6667 {
6668 SCIP_CALL( conflictAddBound(conflict, blkmem, set, stat, var, SCIP_BOUNDTYPE_LOWER, \
6670 nbdchgs++;
6671 }
6672 if( ubchginfoposs[v] >= 0 )
6673 {
6675 SCIP_CALL( conflictAddBound(conflict, blkmem, set, stat, var, SCIP_BOUNDTYPE_UPPER, \
6677 nbdchgs++;
6678 }
6679 }
6680 }
6681
6682 if( v == nvars )
6683 {
6684 /* analyze the conflict set, and create conflict constraints on success */
6685 SCIP_CALL( conflictAnalyze(conflict, blkmem, set, stat, prob, tree, diving, 0, FALSE, nconss, nliterals, \
6687 }
6688
6689 return SCIP_OKAY;
6690}
6691
6692/** adds a weighted LP row to an aggregation row */
6693static
6695 SCIP_SET* set, /**< global SCIP settings */
6696 SCIP_ROW* row, /**< LP row */
6697 SCIP_Real weight, /**< weight for scaling */
6698 SCIP_AGGRROW* aggrrow /**< aggregation row */
6699 )
6700{
6701 assert(set != NULL);
6702 assert(row != NULL);
6703 assert(weight != 0.0);
6704
6705 /* add minimal value to dual row's left hand side: y_i < 0 -> lhs, y_i > 0 -> rhs */
6706 if( weight < 0.0 )
6707 {
6708 assert(!SCIPsetIsInfinity(set, -row->lhs));
6709 SCIP_CALL( SCIPaggrRowAddRow(set->scip, aggrrow, row, weight, -1) );
6710 }
6711 else
6712 {
6714 SCIP_CALL( SCIPaggrRowAddRow(set->scip, aggrrow, row, weight, +1) );
6715 }
6716 SCIPsetDebugMsg(set, " -> add %s row <%s>[%g,%g](lp depth: %d): dual=%g -> dualrhs=%g\n",
6717 row->local ? "local" : "global",
6718 SCIProwGetName(row), row->lhs - row->constant, row->rhs - row->constant,
6719 row->lpdepth, weight, SCIPaggrRowGetRhs(aggrrow));
6720
6721 return SCIP_OKAY;
6722}
6723
6724/** checks validity of an LP row and a corresponding weight */
6725static
6727 SCIP_SET* set, /**< global SCIP settings */
6728 SCIP_ROW* row, /**< LP row */
6729 SCIP_Real weight, /**< weight for scaling */
6730 SCIP_Bool* zerocontribution /**< pointer to store whether every row entry is zero within tolerances */
6731 )
6732{
6733 SCIP_Bool valid = TRUE;
6734
6736
6737 /* dual solution values of 0.0 are always valid */
6738 if( REALABS(weight) > QUAD_EPSILON )
6739 {
6741
6742 /* check dual feasibility */
6743 if( (SCIPsetIsInfinity(set, -row->lhs) && weight > 0.0) || (SCIPsetIsInfinity(set, row->rhs) && weight < 0.0) )
6744 {
6745 int i;
6746
6747 /* ignore slight numerical violations if the contribution of every component of the row is close to zero */
6748 if( weight > 0.0 )
6749 *zerocontribution = SCIPsetIsDualfeasZero(set, row->rhs * weight);
6750 else
6751 *zerocontribution = SCIPsetIsDualfeasZero(set, row->lhs * weight);
6752
6753 for( i = 0; i < row->len && *zerocontribution; i++ )
6754 {
6755 if( !SCIPsetIsDualfeasZero(set, weight * row->vals[i]) )
6757 }
6758
6759 if( !(*zerocontribution) )
6760 {
6761 SCIPsetDebugMsg(set, " -> invalid dual solution value %g for row <%s>: lhs=%g, rhs=%g\n",
6762 weight, SCIProwGetName(row), row->lhs, row->rhs);
6763
6764 valid = FALSE;
6765 }
6766 }
6767 }
6768
6769 return valid;
6770}
6771
6772/** sort local rows by increasing depth and number of nonzeros as tie-breaker */
6773static
6775 SCIP_SET* set, /**< global SCIP settings */
6776 SCIP_AGGRROW* aggrrow, /**< aggregation row */
6777 SCIP_ROW** rows, /**< array of local rows */
6778 int* rowinds, /**< array of row indices */
6779 int* rowdepth, /**< array of LP depths */
6780 int nrows /**< number of local rows */
6781 )
6782{
6783 int* rownnz;
6784 int i;
6785
6786 assert(aggrrow != NULL);
6787 assert(rows != NULL);
6788 assert(nrows > 0);
6789 assert(rowinds != NULL);
6790 assert(rowdepth != NULL);
6791
6792 /* sort row indices by increasing depth */
6793 SCIPsortIntInt(rowdepth, rowinds, nrows);
6794 assert(rowdepth[0] <= rowdepth[nrows-1]);
6795
6797
6798 /* get number of nonzero entries for every row */
6799 for( i = 0; i < nrows; i++ )
6800 {
6801 SCIP_ROW* row = rows[rowinds[i]];
6802 assert(row != NULL);
6803
6804 rownnz[i] = row->len;
6805 }
6806
6807 /* since SCIP has no stable sorting function we sort each bucket separately */
6808 for( i = 0; i < nrows; i++ )
6809 {
6810 int j = i;
6811 int d = rowdepth[i];
6812
6813 /* search for the next row with a greater depth */
6814 while( j+1 < nrows && rowdepth[j+1] == d )
6815 j++;
6816
6817 /* the bucket has size one */
6818 if( j == i )
6819 continue;
6820
6821 assert(j-i+1 <= nrows);
6822
6823 /* sort row indices by increasing number of nonzero elements */
6824 SCIPsortIntIntInt(&rownnz[i], &rowdepth[i], &rowinds[i], j-i+1);
6825 assert(rownnz[i] <= rownnz[j]);
6826
6827 i = j;
6828 } /*lint --e{850} i is modified in the body of the for loop */
6829
6830#ifndef NDEBUG
6831 for( i = 0; i < nrows-1; i++ )
6832 assert(rowdepth[i] < rowdepth[i+1] || (rowdepth[i] == rowdepth[i+1] && rownnz[i] <= rownnz[i+1]));
6833#endif
6834
6836
6837 return SCIP_OKAY;
6838}
6839
6840/** adds locally valid rows to the proof constraint */
6841static
6843 SCIP_SET* set, /**< global SCIP settings */
6844 SCIP_PROB* transprob, /**< transformed problem */
6845 SCIP_LP* lp, /**< LP data */
6846 SCIP_AGGRROW* proofrow, /**< aggregated row representing the proof */
6847 SCIP_ROW** rows, /**< array if locally valid rows */
6848 SCIP_Real* dualsols, /**< dual solution vector */
6849 int* localrowinds, /**< array of row indecies */
6850 int* localrowdepth, /**< array of row depths */
6851 int nlocalrows, /**< number of local rows stored in rows array */
6852 SCIP_Real* proofact, /**< pointer to store the activity of the proof constraint */
6853 int* validdepth, /**< pointer to store the depth where the proof constraint is valid */
6854 SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
6855 SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
6856 SCIP_Bool* valid /**< pointer store whether the proof constraint is valid */
6857 )
6858{
6859 SCIP_Bool infdelta;
6860 int i;
6861
6862 assert(set != NULL);
6863 assert(lp != NULL);
6864
6865 *validdepth = 0;
6866
6867 if( !set->conf_uselocalrows )
6868 return SCIP_OKAY;
6869
6870 SCIPsetDebugMsg(set, "add local rows to dual proof:\n");
6871
6872 /* check whether the proof is already valid, e.g., violated within the local bounds */
6874
6875 /* we stop if the minimal activity is infinite but all variables have a finite activity delta (bad numerics) */
6877 {
6878 *valid = FALSE;
6879 return SCIP_OKAY;
6880 }
6881
6882 /* break if the proof is valid w.r.t local bounds
6883 * note: it can happen that the proof contains a variable with an infinite activity delta.
6884 * here, we don't break immediately because we might be able to fix it by adding local rows
6885 */
6887 {
6888 *valid = TRUE;
6889 return SCIP_OKAY;
6890 }
6891
6892 /* sort local rows by depth */
6894
6895 /* add successively local rows */
6896 for( i = 0; i < nlocalrows; ++i )
6897 {
6898 SCIP_ROW* row;
6899 int r;
6900
6901 r = localrowinds[i];
6902 row = rows[r];
6903
6904 assert(row != NULL);
6905 assert(row->len == 0 || row->cols != NULL);
6906 assert(row->len == 0 || row->vals != NULL);
6907 assert(row == lp->lpirows[r]);
6908 assert(row->local);
6909 assert(row->lpdepth == localrowdepth[i]);
6910
6911 /* ignore dual solution values of 0.0 (in this case: y_i == 0) */
6912 if( REALABS(dualsols[r]) > 0.0 )
6913 {
6914#ifndef NDEBUG
6915 SCIP_Bool zerocontribution;
6916
6917 /* check dual feasibility */
6919 assert(*valid);
6921#endif
6922
6924 continue;
6925
6926 /* add row to dual proof */
6928
6929 /* update depth where the proof is valid */
6930 if( *validdepth < localrowdepth[i] )
6931 *validdepth = localrowdepth[i];
6932
6933 /* get the new minimal activity */
6935
6936 /* we stop if the minimal activity is infinite but all variables have a finite activity delta (bad numerics) */
6938 {
6939 *valid = FALSE;
6940 goto TERMINATE;
6941 }
6942
6943 /* break if the proof is valid w.r.t local bounds */
6945 {
6946 *valid = TRUE;
6947 break;
6948 }
6949 }
6950 }
6951
6952 /* remove all nearly zero coefficients */
6954
6955 TERMINATE:
6956 if( !(*valid) )
6957 {
6958 SCIPsetDebugMsg(set, " -> proof is not valid: %g <= %g\n", *proofact, SCIPaggrRowGetRhs(proofrow));
6959 SCIPsetDebugMsg(set, " -> stop due to numerical troubles\n");
6960 }
6961 else
6962 {
6964
6965 /* we stop if the minimal activity is infinite but all variables have a finite activity delta (bad numerics) */
6967 {
6968 *valid = FALSE;
6969 SCIPsetDebugMsg(set, " -> proof is not valid: %g <= %g [infdelta: %u]\n", *proofact, SCIPaggrRowGetRhs(proofrow), infdelta);
6970 }
6972 {
6973 *valid = FALSE;
6974 SCIPsetDebugMsg(set, " -> proof is not valid: %g <= %g [infdelta: %u]\n", *proofact, SCIPaggrRowGetRhs(proofrow), infdelta);
6975 }
6976 }
6977
6978 return SCIP_OKAY;
6979}
6980
6981/** calculates a Farkas proof from the current dual LP solution */
6982static
6984 SCIP_SET* set, /**< global SCIP settings */
6985 SCIP_PROB* prob, /**< transformed problem */
6986 SCIP_LP* lp, /**< LP data */
6987 SCIP_LPI* lpi, /**< LPI data */
6988 SCIP_TREE* tree, /**< tree data */
6989 SCIP_AGGRROW* farkasrow, /**< aggregated row representing the proof */
6990 SCIP_Real* farkasact, /**< maximal activity of the proof constraint */
6991 int* validdepth, /**< pointer to store the valid depth of the proof constraint */
6992 SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
6993 SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
6994 SCIP_Bool* valid /**< pointer store whether the proof constraint is valid */
6995 )
6996{
6997 SCIP_ROW** rows;
6998 SCIP_Real* dualfarkas;
6999 SCIP_ROW* row;
7000 int* localrowinds;
7001 int* localrowdepth;
7002 SCIP_Bool infdelta;
7003 int nlocalrows;
7004 int nrows;
7005 int r;
7006
7007 assert(set != NULL);
7008 assert(prob != NULL);
7009 assert(lp != NULL);
7010 assert(lp->flushed);
7011 assert(lp->solved);
7012 assert(curvarlbs != NULL);
7013 assert(curvarubs != NULL);
7014 assert(valid != NULL);
7015
7018
7019 /* get LP rows and problem variables */
7020 rows = SCIPlpGetRows(lp);
7021 nrows = SCIPlpGetNRows(lp);
7022 assert(nrows == 0 || rows != NULL);
7023 assert(nrows == lp->nlpirows);
7024
7025 /* it can happen that infeasibility is detetected within LP presolve. in that case, the LP solver may not be able to
7026 * to return the dual ray.
7027 */
7028 if( !SCIPlpiHasDualRay(lpi) )
7029 {
7030 *valid = FALSE;
7031 return SCIP_OKAY;
7032 }
7033
7034 assert(farkasrow != NULL);
7035
7036 /* allocate temporary memory */
7037 SCIP_CALL( SCIPsetAllocBufferArray(set, &dualfarkas, nrows) );
7038 BMSclearMemoryArray(dualfarkas, nrows);
7039
7040 /* get dual Farkas values of rows */
7041 SCIP_CALL( SCIPlpiGetDualfarkas(lpi, dualfarkas) );
7042
7045 nlocalrows = 0;
7046
7047 /* calculate the Farkas row */
7048 (*valid) = TRUE;
7049 (*validdepth) = 0;
7050
7051 for( r = 0; r < nrows; ++r )
7052 {
7053 row = rows[r];
7054 assert(row != NULL);
7055 assert(row->len == 0 || row->cols != NULL);
7056 assert(row->len == 0 || row->vals != NULL);
7057 assert(row == lp->lpirows[r]);
7058
7059 /* ignore dual ray values of 0.0 (in this case: y_i == z_i == 0) */
7060 if( REALABS(dualfarkas[r]) > 0.0 )
7061 {
7062 SCIP_Bool zerocontribution;
7063
7064 /* check dual feasibility */
7065 *valid = checkDualFeasibility(set, row, dualfarkas[r], &zerocontribution);
7066
7067 if( !(*valid) )
7068 goto TERMINATE;
7069
7070 if( zerocontribution )
7071 continue;
7072
7073 if( SCIPsetIsDualfeasZero(set, dualfarkas[r]) )
7074 continue;
7075
7076 if( !row->local )
7077 {
7078 SCIP_CALL( addRowToAggrRow(set, row, -dualfarkas[r], farkasrow) );
7079
7080 /* due to numerical reasons we want to stop */
7082 {
7083 (*valid) = FALSE;
7084 goto TERMINATE;
7085 }
7086 }
7087 else
7088 {
7089 int lpdepth = SCIProwGetLPDepth(row);
7090
7091 if( nlocalrows == 0 && lpdepth < SCIPtreeGetFocusDepth(tree) )
7092 {
7095 }
7096
7097 if( lpdepth < SCIPtreeGetFocusDepth(tree) )
7098 {
7101
7103 localrowdepth[nlocalrows++] = lpdepth;
7104 }
7105 }
7106 }
7107 }
7108
7109 /* remove all coefficients that are too close to zero */
7111
7112 if( !(*valid) )
7113 goto TERMINATE;
7114
7115 infdelta = FALSE;
7116
7117 /* calculate the current Farkas activity, always using the best bound w.r.t. the Farkas coefficient */
7119
7120 SCIPsetDebugMsg(set, " -> farkasact=%g farkasrhs=%g [infdelta: %u], \n",
7122
7123 /* The constructed proof is not valid, this can happen due to numerical reasons,
7124 * e.g., we only consider rows r with !SCIPsetIsZero(set, dualfarkas[r]),
7125 * or because of local rows were ignored so far.
7126 * Due to the latter case, it might happen at least one variable contributes
7127 * with an infinite value to the activity (see: https://git.zib.de/integer/scip/issues/2743)
7128 */
7130 {
7131 /* add contribution of local rows */
7132 if( nlocalrows > 0 && set->conf_uselocalrows > 0 )
7133 {
7134 SCIP_CALL( addLocalRows(set, prob, lp, farkasrow, rows, dualfarkas, localrowinds, localrowdepth,
7135 nlocalrows, farkasact, validdepth, curvarlbs, curvarubs, valid) );
7136 }
7137 else
7138 {
7139 (*valid) = FALSE;
7140 SCIPsetDebugMsg(set, " -> proof is not valid to due infinite activity delta\n");
7141 }
7142 }
7143
7144 TERMINATE:
7145
7148 SCIPsetFreeBufferArray(set, &dualfarkas);
7149
7150 return SCIP_OKAY;
7151}
7152
7153/** calculates a Farkas proof from the current dual LP solution */
7154static
7156 SCIP_SET* set, /**< global SCIP settings */
7157 SCIP_PROB* transprob, /**< transformed problem */
7158 SCIP_LP* lp, /**< LP data */
7159 SCIP_LPI* lpi, /**< LPI data */
7160 SCIP_TREE* tree, /**< tree data */
7161 SCIP_AGGRROW* farkasrow, /**< aggregated row representing the proof */
7162 SCIP_Real* farkasact, /**< maximal activity of the proof constraint */
7163 int* validdepth, /**< pointer to store the valid depth of the proof constraint */
7164 SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
7165 SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
7166 SCIP_Bool* valid /**< pointer store whether the proof constraint is valid */
7167 )
7168{
7169 SCIP_RETCODE retcode;
7170 SCIP_ROW** rows;
7171 SCIP_ROW* row;
7172 SCIP_Real* primsols;
7173 SCIP_Real* dualsols;
7174 SCIP_Real* redcosts;
7175 int* localrowinds;
7176 int* localrowdepth;
7177 SCIP_Real maxabsdualsol;
7178 SCIP_Bool infdelta;
7179 int nlocalrows;
7180 int nrows;
7181 int ncols;
7182 int r;
7183
7184 assert(set != NULL);
7185 assert(transprob != NULL);
7186 assert(lp != NULL);
7187 assert(lp->flushed);
7188 assert(lp->solved);
7189 assert(curvarlbs != NULL);
7190 assert(curvarubs != NULL);
7191 assert(valid != NULL);
7192
7193 *validdepth = 0;
7194 *valid = TRUE;
7195
7198 nlocalrows = 0;
7199
7200 /* get LP rows and problem variables */
7201 rows = SCIPlpGetRows(lp);
7202 nrows = SCIPlpGetNRows(lp);
7203 ncols = SCIPlpGetNCols(lp);
7204 assert(nrows == 0 || rows != NULL);
7205 assert(nrows == lp->nlpirows);
7206
7207 /* get temporary memory */
7211
7212 /* get solution from LPI */
7213 retcode = SCIPlpiGetSol(lpi, NULL, primsols, dualsols, NULL, redcosts);
7214 if( retcode == SCIP_LPERROR ) /* on an error in the LP solver, just abort the conflict analysis */
7215 {
7216 (*valid) = FALSE;
7217 goto TERMINATE;
7218 }
7219 SCIP_CALL( retcode );
7220#ifdef SCIP_DEBUG
7221 {
7222 SCIP_Real objval;
7224 SCIPsetDebugMsg(set, " -> LP objval: %g\n", objval);
7225 }
7226#endif
7227
7228 /* check whether the dual solution is numerically stable */
7229 maxabsdualsol = 0;
7230 for( r = 0; r < nrows; r++ )
7231 {
7232 SCIP_Real absdualsol = REALABS(dualsols[r]);
7233
7236 }
7237
7238 /* don't consider dual solution with maxabsdualsol > 1e+07, this would almost cancel out the objective constraint */
7239 if( maxabsdualsol > 1e+07 )
7240 {
7241 (*valid) = FALSE;
7242 goto TERMINATE;
7243 }
7244
7245 /* clear the proof */
7247
7248 /* Let y be the dual solution and r be the reduced cost vector. Let z be defined as
7249 * z_i := y_i if i is a global row,
7250 * z_i := 0 if i is a local row.
7251 * Define the set X := {x | lhs <= Ax <= rhs, lb <= x <= ub, c^Tx <= c*}, with c* being the current primal bound.
7252 * Then the following inequalities are valid for all x \in X:
7253 * - c* <= -c^Tx
7254 * <=> z^TAx - c* <= (z^TA - c^T) x
7255 * <=> z^TAx - c* <= (y^TA - c^T - (y-z)^TA) x
7256 * <=> z^TAx - c* <= (-r^T - (y-z)^TA) x (dual feasibility of (y,r): y^TA + r^T == c^T)
7257 * Because lhs <= Ax <= rhs and lb <= x <= ub, the inequality can be relaxed to give
7258 * min{z^Tq | lhs <= q <= rhs} - c* <= max{(-r^T - (y-z)^TA) x | lb <= x <= ub}, or X = {}.
7259 *
7260 * The resulting dual row is: z^T{lhs,rhs} - c* <= (-r^T - (y-z)^TA){lb,ub},
7261 * where lhs, rhs, lb, and ub are selected in order to maximize the feasibility of the row.
7262 */
7263
7264 /* add the objective function to the aggregation row with respect to the current cutoff bound
7265 *
7266 * for an integral objective the right-hand side is reduced by the cutoff bound delta to cut off up to the next
7267 * possible objective value below the cutoff bound
7268 */
7270
7271 /* dual row: z^T{lhs,rhs} - c* <= (-r^T - (y-z)^TA){lb,ub}
7272 * 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
7273 */
7274 for( r = 0; r < nrows; ++r )
7275 {
7276 row = rows[r];
7277 assert(row != NULL);
7278 assert(row->len == 0 || row->cols != NULL);
7279 assert(row->len == 0 || row->vals != NULL);
7280 assert(row == lp->lpirows[r]);
7281
7282 /* ignore dual solution values of 0.0 (in this case: y_i == z_i == 0) */
7283 if( REALABS(dualsols[r]) > 0.0 )
7284 {
7285 SCIP_Bool zerocontribution;
7286
7287 /* check dual feasibility */
7289
7290 if( !(*valid) )
7291 goto TERMINATE;
7292
7293 if( zerocontribution )
7294 continue;
7295
7297 continue;
7298
7299 /* skip local row */
7300 if( !row->local )
7301 {
7303
7304 /* due to numerical reasons we want to stop */
7306 {
7307 (*valid) = FALSE;
7308 goto TERMINATE;
7309 }
7310 }
7311 else
7312 {
7313 int lpdepth = SCIProwGetLPDepth(row);
7314
7315 if( nlocalrows == 0 && lpdepth < SCIPtreeGetFocusDepth(tree) )
7316 {
7319 }
7320
7321 if( lpdepth < SCIPtreeGetFocusDepth(tree) )
7322 {
7325
7327 localrowdepth[nlocalrows++] = lpdepth;
7328 }
7329 }
7330 }
7331 }
7332
7333 /* remove all nearly zero coefficients */
7335
7336 if( !(*valid) )
7337 goto TERMINATE;
7338
7339 infdelta = FALSE;
7340
7341 /* check validity of the proof */
7343
7344 SCIPsetDebugMsg(set, " -> farkasact=%g farkasrhs=%g [infdelta: %u], \n",
7346
7347 /* The constructed proof is not valid, this can happen due to numerical reasons,
7348 * e.g., we only consider rows r with !SCIPsetIsZero(set, dualsol[r]),
7349 * or because of local rows were ignored so far.
7350 * Due to the latter case, it might happen at least one variable contributes
7351 * with an infinite value to the activity (see: https://git.zib.de/integer/scip/issues/2743)
7352 */
7354 {
7355 /* add contribution of local rows */
7356 if( nlocalrows > 0 && set->conf_uselocalrows > 0 )
7357 {
7359 nlocalrows, farkasact, validdepth, curvarlbs, curvarubs, valid) );
7360 }
7361 else
7362 {
7363 (*valid) = FALSE;
7364 SCIPsetDebugMsg(set, " -> proof is not valid to due infinite activity delta\n");
7365 }
7366 }
7367
7368 TERMINATE:
7369
7375
7376 return SCIP_OKAY;
7377}
7378
7379#ifdef SCIP_DEBUG
7380static
7382 SCIP_SET* set, /**< global SCIP settings */
7383 SCIP_Real minact, /**< min activity */
7384 SCIP_Real rhs, /**< right hand side */
7385 const char* infostr /**< additional info for this debug message, or NULL */
7386 )
7387{
7388 SCIPsetDebugMsg(set, "-> %sminact=%.15g rhs=%.15g violation=%.15g\n",infostr != NULL ? infostr : "" , minact, rhs, minact - rhs);
7389}
7390#else
7391#define debugPrintViolationInfo(...) /**/
7392#endif
7393
7394/** apply coefficient tightening */
7395static
7397 SCIP_SET* set, /**< global SCIP settings */
7398 SCIP_PROOFSET* proofset, /**< proof set */
7399 int* nchgcoefs, /**< pointer to store number of changed coefficients */
7400 SCIP_Bool* redundant /**< pointer to store whether the proof set is redundant */
7401 )
7402{
7403#ifdef SCIP_DEBUG
7404 SCIP_Real absmax = 0.0;
7405 SCIP_Real absmin = SCIPsetInfinity(set);
7406 int i;
7407
7408 for( i = 0; i < proofset->nnz; i++ )
7409 {
7410 absmax = MAX(absmax, REALABS(proofset->vals[i]));
7411 absmin = MIN(absmin, REALABS(proofset->vals[i]));
7412 }
7413#endif
7414
7415 (*redundant) = SCIPcutsTightenCoefficients(set->scip, FALSE, proofset->vals, &proofset->rhs, proofset->inds, &proofset->nnz, nchgcoefs);
7416
7417#ifdef SCIP_DEBUG
7418 {
7419 SCIP_Real newabsmax = 0.0;
7420 SCIP_Real newabsmin = SCIPsetInfinity(set);
7421
7422 for( i = 0; i < proofset->nnz; i++ )
7423 {
7424 newabsmax = MAX(newabsmax, REALABS(proofset->vals[i]));
7425 newabsmin = MIN(newabsmin, REALABS(proofset->vals[i]));
7426 }
7427
7428 SCIPsetDebugMsg(set, "coefficient tightening: [%.15g,%.15g] -> [%.15g,%.15g] (nnz: %d, nchg: %d rhs: %.15g)\n",
7429 absmin, absmax, newabsmin, newabsmax, proofsetGetNVars(proofset), *nchgcoefs, proofsetGetRhs(proofset));
7430 printf("coefficient tightening: [%.15g,%.15g] -> [%.15g,%.15g] (nnz: %d, nchg: %d rhs: %.15g)\n",
7431 absmin, absmax, newabsmin, newabsmax, proofsetGetNVars(proofset), *nchgcoefs, proofsetGetRhs(proofset));
7432 }
7433#endif
7434}
7435
7436/** try to generate alternative proofs by applying subadditive functions */
7437static
7439 SCIP_CONFLICT* conflict, /**< conflict analysis data */
7440 SCIP_SET* set, /**< global SCIP settings */
7441 SCIP_STAT* stat, /**< dynamic SCIP statistics */
7442 SCIP_PROB* transprob, /**< transformed problem */
7443 SCIP_TREE* tree, /**< tree data */
7444 BMS_BLKMEM* blkmem, /**< block memory */
7445 SCIP_AGGRROW* proofrow, /**< proof rows data */
7446 SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
7447 SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
7448 SCIP_CONFTYPE conflicttype /**< type of the conflict */
7449 )
7450{
7451 SCIP_VAR** vars;
7453 SCIP_Real* cutcoefs;
7454 SCIP_Real cutefficacy;
7455 SCIP_Real cutrhs;
7456 SCIP_Real proofefficacy;
7457 SCIP_Real efficacynorm;
7458 SCIP_Bool islocal;
7459 SCIP_Bool cutsuccess;
7460 SCIP_Bool success;
7461 SCIP_Bool infdelta;
7462 int* cutinds;
7463 int* inds;
7464 int cutnnz;
7465 int nnz;
7466 int nvars;
7467 int i;
7468
7469 vars = SCIPprobGetVars(transprob);
7470 nvars = SCIPprobGetNVars(transprob);
7471
7474
7476
7477 if( infdelta )
7478 return SCIP_OKAY;
7479
7481
7484
7485 /* create reference solution */
7486 SCIP_CALL( SCIPcreateSol(set->scip, &refsol, NULL) );
7487
7488 /* initialize with average solution */
7489 for( i = 0; i < nvars; i++ )
7490 {
7492 }
7493
7494 /* set all variables that are part of the proof to its active local bound */
7495 for( i = 0; i < nnz; i++ )
7496 {
7497 SCIP_Real val = SCIPaggrRowGetProbvarValue(proofrow, inds[i]);
7498
7499 if( val > 0.0 )
7500 {
7501 SCIP_CALL( SCIPsolSetVal(refsol, set, stat, tree, vars[inds[i]], curvarubs[inds[i]]) );
7502 }
7503 else
7504 {
7505 SCIP_CALL( SCIPsolSetVal(refsol, set, stat, tree, vars[inds[i]], curvarlbs[inds[i]]) );
7506 }
7507 }
7508
7511
7512 cutnnz = 0;
7514
7515 /* apply flow cover */
7519
7520 /* apply MIR */
7523 &islocal, &cutsuccess) );
7524 success = (success || cutsuccess);
7525
7526 /* replace the current proof */
7528 {
7530 SCIP_Bool redundant;
7531 int nchgcoefs;
7532
7535
7537
7538 /* apply coefficient tightening */
7539 tightenCoefficients(set, alternativeproofset, &nchgcoefs, &redundant);
7540
7541 if( !redundant )
7542 {
7544 }
7545 else
7546 {
7548 }
7549 } /*lint !e438*/
7550
7553
7554 SCIP_CALL( SCIPfreeSol(set->scip, &refsol) );
7555
7556 return SCIP_OKAY;
7557}
7558
7559/** tighten a given infeasibility proof a^Tx <= b with minact > b w.r.t. local bounds
7560 *
7561 * 1) Apply cut generating functions
7562 * - c-MIR
7563 * - Flow-cover
7564 * - TODO: implement other subadditive functions
7565 * 2) Remove continuous variables contributing with its global bound
7566 * - TODO: implement a variant of non-zero-cancellation
7567 */
7568static
7570 SCIP_CONFLICT* conflict, /**< conflict analysis data */
7571 SCIP_SET* set, /**< global SCIP settings */
7572 SCIP_STAT* stat, /**< dynamic SCIP statistics */
7573 BMS_BLKMEM* blkmem, /**< block memory */
7574 SCIP_PROB* transprob, /**< transformed problem */
7575 SCIP_TREE* tree, /**< tree data */
7576 SCIP_AGGRROW* proofrow, /**< aggregated row representing the proof */
7577 int validdepth, /**< depth where the proof is valid */
7578 SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
7579 SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
7580 SCIP_Bool initialproof /**< do we analyze the initial reason of infeasibility? */
7581 )
7582{
7583 SCIP_VAR** vars;
7584 SCIP_Real* vals;
7585 int* inds;
7586 SCIP_PROOFSET* proofset;
7587 SCIP_Bool valid;
7588 SCIP_Bool redundant;
7589 int nnz;
7590 int nchgcoefs;
7591 int nbinvars;
7592 int ncontvars;
7593 int nintvars;
7594 int i;
7595
7596 assert(conflict->proofset != NULL);
7597 assert(curvarlbs != NULL);
7598 assert(curvarubs != NULL);
7599
7600 vars = SCIPprobGetVars(transprob);
7601 nbinvars = 0;
7602 nintvars = 0;
7603 ncontvars = 0;
7604
7607
7608 /* count number of binary, integer, and continuous variables */
7609 for( i = 0; i < nnz; i++ )
7610 {
7611 assert(SCIPvarGetProbindex(vars[inds[i]]) == inds[i]);
7612
7613 if( SCIPvarIsBinary(vars[inds[i]]) )
7614 ++nbinvars;
7615 else if( SCIPvarIsIntegral(vars[inds[i]]) )
7616 ++nintvars;
7617 else
7618 ++ncontvars;
7619 }
7620
7621 SCIPsetDebugMsg(set, "start dual proof tightening:\n");
7622 SCIPsetDebugMsg(set, "-> tighten dual proof: nvars=%d (bin=%d, int=%d, cont=%d)\n",
7623 nnz, nbinvars, nintvars, ncontvars);
7625
7626 /* try to find an alternative proof of local infeasibility that is stronger */
7627 if( set->conf_sepaaltproofs )
7628 {
7629 SCIP_CALL( separateAlternativeProofs(conflict, set, stat, transprob, tree, blkmem, proofrow, curvarlbs, curvarubs,
7630 conflict->conflictset->conflicttype) );
7631 }
7632
7633 if( initialproof )
7634 proofset = conflict->proofset;
7635 else
7636 {
7637 SCIP_CALL( proofsetCreate(&proofset, blkmem) );
7638 }
7639
7640 /* start with a proofset containing all variables with a non-zero coefficient in the dual proof */
7641 SCIP_CALL( proofsetAddAggrrow(proofset, set, blkmem, proofrow) );
7642 proofset->conflicttype = conflict->conflictset->conflicttype;
7643 proofset->validdepth = validdepth;
7644
7645 /* get proof data */
7646 vals = proofsetGetVals(proofset);
7647 inds = proofsetGetInds(proofset);
7648 nnz = proofsetGetNVars(proofset);
7649
7650#ifndef NDEBUG
7651 for( i = 0; i < nnz; i++ )
7652 {
7653 int idx = inds[i];
7654 if( vals[i] > 0.0 )
7656 if( vals[i] < 0.0 )
7658 }
7659#endif
7660
7661 /* remove continuous variable contributing with their global bound
7662 *
7663 * todo: check whether we also want to do that for bound exceeding proofs, but then we cannot update the
7664 * conflict anymore
7665 */
7666 if( proofset->conflicttype == SCIP_CONFTYPE_INFEASLP )
7667 {
7668 /* remove all continuous variables that have equal global and local bounds (ub or lb depend on the sign)
7669 * from the proof
7670 */
7671
7672 for( i = 0; i < nnz && nnz > 1; )
7673 {
7674 SCIP_Real val;
7675 int idx = inds[i];
7676
7677 assert(vars[idx] != NULL);
7678
7679 val = vals[i];
7680 assert(!SCIPsetIsZero(set, val));
7681
7682 /* skip integral variables */
7684 {
7685 i++;
7686 continue;
7687 }
7688 else
7689 {
7690 SCIP_Real glbbd;
7691 SCIP_Real locbd;
7692
7693 /* get appropriate global and local bounds */
7694 glbbd = (val < 0.0 ? SCIPvarGetUbGlobal(vars[idx]) : SCIPvarGetLbGlobal(vars[idx]));
7695 locbd = (val < 0.0 ? curvarubs[idx] : curvarlbs[idx]);
7696
7697 if( !SCIPsetIsEQ(set, glbbd, locbd) )
7698 {
7699 i++;
7700 continue;
7701 }
7702
7703 SCIPsetDebugMsg(set, "-> remove continuous variable <%s>: glb=[%g,%g], loc=[%g,%g], val=%g\n",
7705 curvarlbs[idx], curvarubs[idx], val);
7706
7707 proofsetCancelVarWithBound(proofset, set, vars[idx], i, &valid);
7708 assert(valid); /* this should be always fulfilled at this place */
7709
7710 --nnz;
7711 }
7712 }
7713 }
7714
7715 /* apply coefficient tightening to initial proof */
7716 tightenCoefficients(set, proofset, &nchgcoefs, &redundant);
7717
7718 /* it can happen that the constraints is almost globally redundant w.r.t to the maximal activity,
7719 * e.g., due to numerics. in this case, we want to discard the proof
7720 */
7721 if( redundant )
7722 {
7723#ifndef NDEBUG
7724 SCIP_Real eps = MIN(0.01, 10.0*set->num_feastol);
7725 assert(proofset->rhs - getMaxActivity(set, transprob, proofset->vals, proofset->inds, proofset->nnz, NULL, NULL) < eps);
7726#endif
7727 if( initialproof )
7728 {
7729 proofsetClear(proofset);
7730 }
7731 else
7732 {
7733 proofsetFree(&proofset, blkmem);
7734 }
7735 }
7736 else
7737 {
7738 if( !initialproof )
7739 {
7740 SCIP_CALL( conflictInsertProofset(conflict, set, proofset) );
7741 }
7742
7743 if( nchgcoefs > 0 )
7744 {
7745 if( proofset->conflicttype == SCIP_CONFTYPE_INFEASLP )
7747 else if( proofset->conflicttype == SCIP_CONFTYPE_BNDEXCEEDING )
7749 }
7750 }
7751
7752 return SCIP_OKAY;
7753}
7754
7755/** perform conflict analysis based on a dual unbounded ray
7756 *
7757 * given an aggregation of rows lhs <= a^Tx such that lhs > maxactivity. if the constraint has size one we add a
7758 * bound change instead of the constraint.
7759 */
7760static
7762 SCIP_CONFLICT* conflict, /**< conflict analysis data */
7763 SCIP_SET* set, /**< global SCIP settings */
7764 SCIP_STAT* stat, /**< dynamic SCIP statistics */
7765 BMS_BLKMEM* blkmem, /**< block memory */
7766 SCIP_PROB* origprob, /**< original problem */
7767 SCIP_PROB* transprob, /**< transformed problem */
7768 SCIP_TREE* tree, /**< tree data */
7769 SCIP_REOPT* reopt, /**< reoptimization data */
7770 SCIP_LP* lp, /**< LP data */
7771 SCIP_AGGRROW* proofrow, /**< aggregated row representing the proof */
7772 int validdepth, /**< valid depth of the dual proof */
7773 SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
7774 SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
7775 SCIP_Bool initialproof, /**< do we analyze the initial reason of infeasibility? */
7776 SCIP_Bool* globalinfeasible, /**< pointer to store whether global infeasibility could be proven */
7777 SCIP_Bool* success /**< pointer to store success result */
7778 )
7779{
7780 SCIP_Real rhs;
7781 SCIP_Real minact;
7782 SCIP_Bool infdelta;
7783 int nnz;
7784
7785 assert(set != NULL);
7786 assert(transprob != NULL);
7787 assert(validdepth >= 0);
7788 assert(validdepth == 0 || validdepth < SCIPtreeGetFocusDepth(tree));
7789
7790 /* get sparse data */
7793
7795 *success = FALSE;
7796
7797 /* get minimal activity w.r.t. local bounds */
7799
7800 if( infdelta )
7801 return SCIP_OKAY;
7802
7803 /* only run is the proof proves local infeasibility */
7804 if( SCIPsetIsFeasLE(set, minact, rhs) )
7805 return SCIP_OKAY;
7806
7807 /* if the farkas-proof is empty, the node and its sub tree can be cut off completely */
7808 if( nnz == 0 )
7809 {
7810 SCIPsetDebugMsg(set, " -> empty farkas-proof in depth %d cuts off sub tree at depth %d\n", SCIPtreeGetFocusDepth(tree), validdepth);
7811
7812 SCIP_CALL( SCIPnodeCutoff(tree->path[validdepth], set, stat, tree, transprob, origprob, reopt, lp, blkmem) );
7813
7815 *success = TRUE;
7816
7817 ++conflict->ndualproofsinfsuccess;
7818
7819 return SCIP_OKAY;
7820 }
7821
7822 /* try to enforce the constraint based on a dual ray */
7823 SCIP_CALL( tightenDualproof(conflict, set, stat, blkmem, transprob, tree, proofrow, validdepth,
7825
7826 if( *globalinfeasible )
7827 {
7828 SCIPsetDebugMsg(set, "detect global: cutoff root node\n");
7829 SCIP_CALL( SCIPnodeCutoff(tree->path[0], set, stat, tree, transprob, origprob, reopt, lp, blkmem) );
7830 *success = TRUE;
7831
7832 ++conflict->ndualproofsinfsuccess;
7833 }
7834
7835 return SCIP_OKAY;
7836}
7837
7838/** try to find a subset of changed bounds leading to an infeasible LP
7839 *
7840 * 1. call undoBdchgsDualfarkas() or undoBdchgsDualsol()
7841 * -> update lb/ubchginfoposs arrays
7842 * -> store additional changes in bdchg and curvarlbs/ubs arrays
7843 * -> apply additional changes to the LPI
7844 * 2. (optional) if additional bound changes were undone:
7845 * -> resolve LP
7846 * -> goto 1.
7847 * 3. redo all bound changes in the LPI to restore the LPI to its original state
7848 * 4. analyze conflict
7849 * -> put remaining changed bounds (see lb/ubchginfoposs arrays) into starting conflict set
7850 */
7851static
7853 SCIP_CONFLICT* conflict, /**< conflict data */
7854 SCIP_SET* set, /**< global SCIP settings */
7855 SCIP_STAT* stat, /**< problem statistics */
7856 SCIP_PROB* origprob, /**< original problem */
7857 SCIP_PROB* transprob, /**< transformed problem */
7858 SCIP_TREE* tree, /**< branch and bound tree */
7859 SCIP_REOPT* reopt, /**< reoptimization data */
7860 SCIP_LP* lp, /**< LP data */
7861 SCIP_LPI* lpi, /**< LPI data */
7862 BMS_BLKMEM* blkmem, /**< block memory */
7863 SCIP_Real* proofcoefs, /**< coefficients in the proof constraint */
7864 SCIP_Real* prooflhs, /**< lhs of the proof constraint */
7865 SCIP_Real* proofactivity, /**< maximal activity of the proof constraint */
7866 SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
7867 SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
7868 int* lbchginfoposs, /**< positions of currently active lower bound change information in variables' arrays */
7869 int* ubchginfoposs, /**< positions of currently active upper bound change information in variables' arrays */
7870 int* iterations, /**< pointer to store the total number of LP iterations used */
7871 SCIP_Bool marklpunsolved, /**< whether LP should be marked unsolved after analysis (needed for strong branching) */
7872 SCIP_Bool* dualproofsuccess, /**< pointer to store success result of dual proof analysis */
7873 SCIP_Bool* valid /**< pointer to store whether the result is still a valid proof */
7874 )
7875{
7878 SCIP_Bool solvelp;
7879 SCIP_Bool resolve;
7880 int ncols;
7881
7882 assert(set != NULL);
7883
7884 /* get number of columns in the LP */
7885 ncols = SCIPlpGetNCols(lp);
7886
7887 /* get temporary memory for remembering bound changes on LPI columns */
7890
7891 /* undo as many bound changes as possible with the current LP solution */
7892 resolve = FALSE;
7893 if( (*valid) )
7894 {
7895 int currentdepth;
7897
7898 if( SCIPlpiIsPrimalInfeasible(lpi) )
7899 {
7902 }
7903 else
7904 {
7908 }
7909 }
7910
7911 /* check if we want to solve the LP */
7912 assert(SCIPprobAllColsInLP(transprob, set, lp));
7913 solvelp = (set->conf_maxlploops != 0 && set->conf_lpiterations != 0);
7914
7915 if( (*valid) && resolve && solvelp )
7916 {
7917 SCIP_RETCODE retcode;
7918 SCIP_ROW** rows;
7919 int* sidechginds;
7920 SCIP_Real* sidechgoldlhss;
7921 SCIP_Real* sidechgoldrhss;
7922 SCIP_Real* sidechgnewlhss;
7923 SCIP_Real* sidechgnewrhss;
7924 SCIP_Real lpiinfinity;
7925 SCIP_Bool globalinfeasible;
7926 int maxlploops;
7927 int lpiterations;
7928 int sidechgssize;
7929 int nsidechgs;
7930 int nrows;
7931 int nloops;
7932 int r;
7933
7934 /* get infinity value of LP solver */
7936
7937 /* temporarily disable objective limit and install an iteration limit */
7938 maxlploops = (set->conf_maxlploops >= 0 ? set->conf_maxlploops : INT_MAX);
7939 lpiterations = (set->conf_lpiterations >= 0 ? set->conf_lpiterations : INT_MAX);
7942
7943 /* get LP rows */
7944 rows = SCIPlpGetRows(lp);
7945 nrows = SCIPlpGetNRows(lp);
7946 assert(nrows == 0 || rows != NULL);
7947
7948 /* get temporary memory for remembering side changes on LPI rows */
7954 sidechgssize = nrows;
7955 nsidechgs = 0;
7956
7957 /* remove all local rows by setting their sides to infinity;
7958 * finite sides are only changed to near infinity, such that the row's sense in the LP solver
7959 * is not affected (e.g. CPLEX cannot handle free rows)
7960 */
7961 for( r = 0; r < nrows; ++r )
7962 {
7963 assert(SCIProwGetLPPos(rows[r]) == r);
7964
7965 if( SCIProwIsLocal(rows[r]) )
7966 {
7967 SCIPsetDebugMsg(set, " -> removing local row <%s> [%g,%g]\n",
7968 SCIProwGetName(rows[r]), SCIProwGetLhs(rows[r]), SCIProwGetRhs(rows[r]));
7971 }
7972 }
7973
7974 /* apply changes of local rows to the LP solver */
7975 if( nsidechgs > 0 )
7976 {
7978 }
7979
7980 /* undo as many additional bound changes as possible by resolving the LP */
7981 assert((*valid));
7982 assert(resolve);
7983 nloops = 0;
7985 while( (*valid) && resolve && nloops < maxlploops )
7986 {
7987 int iter;
7988
7990
7991 nloops++;
7992 resolve = FALSE;
7993
7994 SCIPsetDebugMsg(set, "infeasible LP conflict analysis loop %d (changed col bounds: %d)\n", nloops, relaxedlpbdchgs->nbdchgs);
7995
7996 /* apply bound changes to the LP solver */
7997 assert(relaxedlpbdchgs->nbdchgs >= 0);
7998 if( relaxedlpbdchgs->nbdchgs > 0 )
7999 {
8000 SCIPsetDebugMsg(set, " -> applying %d bound changes to the LP solver\n", relaxedlpbdchgs->nbdchgs);
8001 SCIP_CALL( SCIPlpiChgBounds(lpi, relaxedlpbdchgs->nbdchgs, relaxedlpbdchgs->bdchginds, \
8002 relaxedlpbdchgs->bdchglbs, relaxedlpbdchgs->bdchgubs) );
8003
8004 /* reset conflict LP bound change data structure */
8006 }
8007
8008 /* start LP timer */
8010
8011 /* resolve LP */
8012 retcode = SCIPlpiSolveDual(lpi);
8013
8014 /* stop LP timer */
8016
8017 /* check return code of LP solving call */
8018 if( retcode == SCIP_LPERROR )
8019 {
8020 (*valid) = FALSE;
8021 break;
8022 }
8023 SCIP_CALL( retcode );
8024
8025 /* count number of LP iterations */
8027 (*iterations) += iter;
8028 stat->nconflictlps++;
8029 stat->nconflictlpiterations += iter;
8030 SCIPsetDebugMsg(set, " -> resolved LP in %d iterations (total: %" SCIP_LONGINT_FORMAT ") (infeasible:%u)\n",
8032
8033 /* evaluate result */
8034 if( SCIPlpiIsDualFeasible(lpi) || SCIPlpiIsObjlimExc(lpi) )
8035 {
8036 SCIP_Real objval;
8037
8039 (*valid) = (objval >= lp->lpiobjlim && !SCIPlpDivingObjChanged(lp));
8040 }
8041 else
8043
8044 if( (*valid) )
8045 {
8046 int currentdepth;
8048
8049 /* undo additional bound changes */
8050 if( SCIPlpiIsPrimalInfeasible(lpi) )
8051 {
8053 int* inds;
8054 int validdepth;
8055 int nnz;
8056 int v;
8057
8058#ifndef NDEBUG
8059 SCIP_VAR** vars = SCIPprobGetVars(transprob);
8060#endif
8061
8063
8064 /* the original LP exceeds the current cutoff bound, thus, we have not constructed the Farkas proof */
8065 SCIP_CALL( getFarkasProof(set, transprob, lp, lpi, tree, farkasrow, proofactivity, &validdepth,
8067
8068 /* the constructed Farkas proof is not valid, we need to break here */
8069 if( !(*valid) )
8070 {
8071 SCIPaggrRowFree(set->scip, &farkasrow);
8072 break;
8073 }
8074
8075 /* start dual proof analysis */
8076 if( set->conf_useinflp == 'd' || set->conf_useinflp == 'b' )
8077 {
8078 /* change the conflict type */
8081
8082 /* start dual proof analysis */
8083 SCIP_CALL( conflictAnalyzeDualProof(conflict, set, stat, blkmem, origprob, transprob, tree, reopt, lp, \
8085
8087 }
8088
8089 /* todo: in theory, we could apply conflict graph analysis for locally valid proofs, too, but this needs to be implemented */
8090 if( globalinfeasible || validdepth > SCIPtreeGetEffectiveRootDepth(tree) )
8091 {
8092 SCIPaggrRowFree(set->scip, &farkasrow);
8093 goto TERMINATE;
8094 }
8095
8097 (*prooflhs) = -SCIPaggrRowGetRhs(farkasrow);
8098 (*proofactivity) = -(*proofactivity);
8099
8102
8103 for( v = 0; v < nnz; v++ )
8104 {
8105 int i = inds[v];
8106
8107 assert(SCIPvarGetProbindex(vars[i]) == inds[v]);
8108
8110 }
8111
8112 /* free aggregation rows */
8113 SCIPaggrRowFree(set->scip, &farkasrow);
8114
8117 }
8118 else
8119 {
8121 int* inds;
8122 int validdepth;
8123 int nnz;
8124 int v;
8125
8126#ifndef NDEBUG
8127 SCIP_VAR** vars = SCIPprobGetVars(transprob);
8128#endif
8129
8131
8133
8134 SCIP_CALL( getDualProof(set, transprob, lp, lpi, tree, proofrow, proofactivity, &validdepth,
8136
8137 /* the constructed dual proof is not valid, we need to break here */
8138 if( !(*valid) || validdepth > SCIPtreeGetEffectiveRootDepth(tree) )
8139 {
8140 SCIPaggrRowFree(set->scip, &proofrow);
8141 break;
8142 }
8143 /* in contrast to the infeasible case we don't want to analyze the (probably identical) proof again. */
8144
8146 (*prooflhs) = -SCIPaggrRowGetRhs(proofrow);
8147 (*proofactivity) = -(*proofactivity);
8148
8151
8152 for( v = 0; v < nnz; v++ )
8153 {
8154 int i = inds[v];
8155
8156 assert(SCIPvarGetProbindex(vars[i]) == inds[v]);
8157
8159 }
8160
8161 /* free aggregation rows */
8162 SCIPaggrRowFree(set->scip, &proofrow);
8163
8166 }
8167 }
8168 assert(!resolve || (*valid));
8169 assert(!resolve || relaxedlpbdchgs->nbdchgs > 0);
8170 SCIPsetDebugMsg(set, " -> finished infeasible LP conflict analysis loop %d (iter: %d, nbdchgs: %d)\n",
8171 nloops, iter, relaxedlpbdchgs->nbdchgs);
8172 }
8173
8174 SCIPsetDebugMsg(set, "finished undoing bound changes after %d loops (valid=%u, nbdchgs: %d)\n",
8175 nloops, (*valid), oldlpbdchgs->nbdchgs);
8176
8177 TERMINATE:
8178 /* reset variables to local bounds */
8179 if( oldlpbdchgs->nbdchgs > 0 )
8180 {
8181 SCIP_CALL( SCIPlpiChgBounds(lpi, oldlpbdchgs->nbdchgs, oldlpbdchgs->bdchginds, oldlpbdchgs->bdchglbs, oldlpbdchgs->bdchgubs) );
8182 }
8183
8184 /* reset changes of local rows */
8185 if( nsidechgs > 0 )
8186 {
8188 }
8189
8190 /* mark the LP unsolved */
8191 if( oldlpbdchgs->nbdchgs > 0 || nsidechgs > 0 )
8192 {
8193 /* The LPI data are out of sync with LP data. Thus, the LP should be marked
8194 * unsolved. However, for strong branching calls, the LP has to have status 'solved'; in
8195 * this case, marklpunsolved is FALSE and synchronization is performed later. */
8196 if ( marklpunsolved )
8197 {
8198 lp->solved = FALSE;
8199 lp->primalfeasible = FALSE;
8200 lp->primalchecked = FALSE;
8201 lp->dualfeasible = FALSE;
8202 lp->dualchecked = FALSE;
8203 lp->lpobjval = SCIP_INVALID;
8205 }
8206 }
8207
8208 /* reinstall old objective and iteration limits in LP solver */
8211
8212 /* free temporary memory */
8218 }
8219
8220 /* free temporary memory */
8223
8224 return SCIP_OKAY;
8225}
8226
8227/** actually performs analysis of infeasible LP */
8228static
8230 SCIP_CONFLICT* conflict, /**< conflict analysis data */
8231 SCIP_CONFLICTSTORE* conflictstore, /**< conflict store */
8232 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
8233 SCIP_SET* set, /**< global SCIP settings */
8234 SCIP_STAT* stat, /**< problem statistics */
8235 SCIP_PROB* transprob, /**< transformed problem */
8236 SCIP_PROB* origprob, /**< original problem */
8237 SCIP_TREE* tree, /**< branch and bound tree */
8238 SCIP_REOPT* reopt, /**< reoptimization data structure */
8239 SCIP_LP* lp, /**< LP data */
8240 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
8241 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
8242 SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
8243 SCIP_Bool diving, /**< are we in strong branching or diving mode? */
8244 SCIP_Bool* dualproofsuccess, /**< pointer to store success result of dual proof analysis */
8245 int* iterations, /**< pointer to store the total number of LP iterations used */
8246 int* nconss, /**< pointer to store the number of generated conflict constraints */
8247 int* nliterals, /**< pointer to store the number of literals in generated conflict constraints */
8248 int* nreconvconss, /**< pointer to store the number of generated reconvergence constraints */
8249 int* nreconvliterals, /**< pointer to store the number of literals generated reconvergence constraints */
8250 SCIP_Bool marklpunsolved /**< whether LP should be marked unsolved after analysis (needed for strong branching) */
8251 )
8252{
8253 SCIP_VAR** vars;
8255 SCIP_LPI* lpi;
8256 SCIP_Bool valid;
8257 SCIP_Bool globalinfeasible;
8258 int* lbchginfoposs;
8259 int* ubchginfoposs;
8260 int validdepth;
8261 int nvars;
8262 int v;
8263 SCIP_Real* curvarlbs;
8264 SCIP_Real* curvarubs;
8265 SCIP_Real farkasactivity;
8266
8267 assert(conflict != NULL);
8268 assert(conflict->nconflictsets == 0);
8269 assert(set != NULL);
8270 assert(SCIPprobAllColsInLP(transprob, set, lp)); /* LP conflict analysis is only valid, if all variables are known */
8271 assert(stat != NULL);
8272 assert(transprob != NULL);
8273 assert(lp != NULL);
8274 assert(lp->flushed);
8275 assert(lp->solved);
8276 assert(iterations != NULL);
8277 assert(nconss != NULL);
8278 assert(nliterals != NULL);
8281
8282 *iterations = 0;
8283 *nconss = 0;
8284 *nliterals = 0;
8285 *nreconvconss = 0;
8286 *nreconvliterals = 0;
8287
8288 vars = transprob->vars;
8289 nvars = transprob->nvars;
8290
8291 valid = TRUE;
8292 validdepth = 0;
8293
8294 /* get LP solver interface */
8295 lpi = SCIPlpGetLPI(lp);
8298
8299 if( !SCIPlpiIsPrimalInfeasible(lpi) )
8300 {
8301 SCIP_Real objval;
8302
8304
8305 /* make sure, a dual feasible solution exists, that exceeds the objective limit;
8306 * With FASTMIP setting, CPLEX does not apply the final pivot to reach the dual solution exceeding the objective
8307 * limit. Therefore, we have to either turn off FASTMIP and resolve the problem or continue solving it without
8308 * objective limit for at least one iteration. It seems that the strategy to continue with FASTMIP for one
8309 * additional simplex iteration yields better results.
8310 */
8312 if( objval < lp->lpiobjlim )
8313 {
8314 SCIP_RETCODE retcode;
8315
8316 /* temporarily disable objective limit and install an iteration limit */
8319
8320 /* start LP timer */
8322
8323 /* resolve LP */
8324 retcode = SCIPlpiSolveDual(lpi);
8325
8326 /* stop LP timer */
8328
8329 /* check return code of LP solving call */
8330 valid = (retcode != SCIP_LPERROR);
8331 if( valid )
8332 {
8333 int iter;
8334
8335 SCIP_CALL( retcode );
8336
8337 /* count number of LP iterations */
8339 (*iterations) += iter;
8340 stat->nconflictlps++;
8341 stat->nconflictlpiterations += iter;
8342 SCIPsetDebugMsg(set, " -> resolved objlim exceeding LP in %d iterations (total: %" SCIP_LONGINT_FORMAT ") (infeasible:%u, objlim: %u, optimal:%u)\n",
8345 }
8346
8347 /* reinstall old objective and iteration limits in LP solver */
8350
8351 /* abort, if the LP produced an error */
8352 if( !valid )
8353 return SCIP_OKAY;
8354 }
8355 }
8357
8358 if( !SCIPlpiIsPrimalInfeasible(lpi) )
8359 {
8360 SCIP_Real objval;
8361
8363
8365 if( objval < lp->lpiobjlim )
8366 {
8367 SCIPsetDebugMsg(set, " -> LP does not exceed the cutoff bound: obj=%g, cutoff=%g\n", objval, lp->lpiobjlim);
8368 return SCIP_OKAY;
8369 }
8370 else
8371 {
8372 SCIPsetDebugMsg(set, " -> LP exceeds the cutoff bound: obj=%g, cutoff=%g\n", objval, lp->lpiobjlim);
8373 }
8374 }
8375
8376 assert(valid);
8377
8381
8382 farkasactivity = 0.0;
8383
8384 /* get temporary memory for remembering variables' current bounds and corresponding bound change information
8385 * positions in variable's bound change information arrays
8386 */
8389
8390 /* get current bounds and current positions in lb/ubchginfos arrays of variables */
8391 valid = TRUE;
8392 for( v = 0; v < nvars && valid; ++v )
8393 {
8394 SCIP_VAR* var;
8395
8396 var = vars[v];
8397
8404
8405 /* check, if last bound changes were due to strong branching or diving */
8406 if( diving )
8407 {
8408 SCIP_Real lb;
8409 SCIP_Real ub;
8410
8411 lb = SCIPvarGetLbLocal(var);
8412 ub = SCIPvarGetUbLocal(var);
8413 if( SCIPsetIsGT(set, curvarlbs[v], lb) )
8415 else if( SCIPsetIsLT(set, curvarlbs[v], lb) )
8416 {
8417 /* the bound in the diving LP was relaxed -> the LP is not a subproblem of the current node -> abort! */
8418 /**@todo we could still analyze such a conflict, but we would have to take care with our data structures */
8419 valid = FALSE;
8420 }
8421 if( SCIPsetIsLT(set, curvarubs[v], ub) )
8423 else if( SCIPsetIsGT(set, curvarubs[v], ub) )
8424 {
8425 /* the bound in the diving LP was relaxed -> the LP is not a subproblem of the current node -> abort! */
8426 /**@todo we could still analyze such a conflict, but we would have to take care with our data structures */
8427 valid = FALSE;
8428 }
8429 }
8430 }
8431
8432 if( !valid )
8433 goto TERMINATE;
8434
8435 /* the LP is prooven to be infeasible */
8436 if( SCIPlpiIsPrimalInfeasible(lpi) )
8437 {
8438 SCIP_CALL( getFarkasProof(set, transprob, lp, lpi, tree, farkasrow, &farkasactivity, &validdepth,
8440 }
8441 /* the LP is dual feasible and/or exceeds the current incumbant solution */
8442 else
8443 {
8445 SCIP_CALL( getDualProof(set, transprob, lp, lpi, tree, farkasrow, &farkasactivity, &validdepth,
8447 }
8448
8449 if( !valid || validdepth >= SCIPtreeGetCurrentDepth(tree) )
8450 goto TERMINATE;
8451
8453
8454 /* start dual proof analysis */
8455 if( ((set->conf_useinflp == 'b' || set->conf_useinflp == 'd') && conflict->conflictset->conflicttype == SCIP_CONFTYPE_INFEASLP)
8456 || ((set->conf_useboundlp == 'b' || set->conf_useboundlp == 'd') && conflict->conflictset->conflicttype == SCIP_CONFTYPE_BNDEXCEEDING) )
8457 {
8458 /* start dual proof analysis */
8459 SCIP_CALL( conflictAnalyzeDualProof(conflict, set, stat, blkmem, origprob, transprob, tree, reopt, lp, farkasrow, \
8461 }
8462
8463 assert(valid);
8464
8465 /* todo: in theory, we could apply conflict graph analysis for locally valid proofs, too, but this needs to be implemented */
8466 if( !globalinfeasible && validdepth <= SCIPtreeGetEffectiveRootDepth(tree)
8467 && (((set->conf_useinflp == 'b' || set->conf_useinflp == 'c') && conflict->conflictset->conflicttype == SCIP_CONFTYPE_INFEASLP)
8468 || ((set->conf_useboundlp == 'b' || set->conf_useboundlp == 'c') && conflict->conflictset->conflicttype == SCIP_CONFTYPE_BNDEXCEEDING)) )
8469 {
8470 SCIP_Real* farkascoefs;
8471 SCIP_Real farkaslhs;
8472 int* inds;
8473 int nnz;
8474
8475#ifdef SCIP_DEBUG
8476 {
8477 SCIP_Real objlim;
8478 SCIPsetDebugMsg(set, "analyzing conflict on infeasible LP (infeasible: %u, objlimexc: %u, optimal:%u) in depth %d (diving: %u)\n",
8480
8482 SCIPsetDebugMsg(set, " -> objective limit in LP solver: %g (in LP: %g)\n", objlim, lp->lpiobjlim);
8483 }
8484#endif
8485
8488
8491
8494
8495 for( v = 0; v < nnz; v++ )
8496 {
8497 int i = inds[v];
8498
8499 assert(SCIPvarGetProbindex(vars[i]) == inds[v]);
8500
8502 }
8503
8504 SCIP_CALL( runBoundHeuristic(conflict, set, stat, origprob, transprob, tree, reopt, lp, lpi, blkmem, farkascoefs,
8507
8509
8510 if( !valid )
8511 goto FLUSHPROOFSETS;
8512
8513 /* analyze the conflict starting with remaining bound changes */
8514 SCIP_CALL( conflictAnalyzeRemainingBdchgs(conflict, blkmem, set, stat, transprob, tree, diving, \
8516
8517 /* flush conflict set storage */
8518 SCIP_CALL( SCIPconflictFlushConss(conflict, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, \
8519 eventqueue, cliquetable) );
8520 }
8521
8523 /* flush proof set */
8524 if( proofsetGetNVars(conflict->proofset) > 0 || conflict->nproofsets > 0 )
8525 {
8526 SCIP_CALL( conflictFlushProofset(conflict, conflictstore, blkmem, set, stat, transprob, origprob, tree, reopt, lp, \
8527 branchcand, eventqueue, cliquetable) );
8528 }
8529
8530 TERMINATE:
8535 SCIPaggrRowFree(set->scip, &farkasrow);
8536
8537 return SCIP_OKAY;
8538}
8539
8540/** analyzes an infeasible LP to find out the bound changes on variables that were responsible for the infeasibility;
8541 * on success, calls standard conflict analysis with the responsible variables as starting conflict set, thus creating
8542 * a conflict constraint out of the resulting conflict set;
8543 * updates statistics for infeasible LP conflict analysis
8544 */
8545static
8547 SCIP_CONFLICT* conflict, /**< conflict analysis data */
8548 SCIP_CONFLICTSTORE* conflictstore, /**< conflict store */
8549 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
8550 SCIP_SET* set, /**< global SCIP settings */
8551 SCIP_STAT* stat, /**< problem statistics */
8552 SCIP_PROB* transprob, /**< transformed problem */
8553 SCIP_PROB* origprob, /**< original problem */
8554 SCIP_TREE* tree, /**< branch and bound tree */
8555 SCIP_REOPT* reopt, /**< reoptimization data structure */
8556 SCIP_LP* lp, /**< LP data */
8557 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
8558 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
8559 SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
8560 SCIP_Bool* success /**< pointer to store whether a conflict constraint was created, or NULL */
8561 )
8562{
8563 SCIP_Bool dualraysuccess = FALSE;
8564 SCIP_Longint olddualproofsuccess;
8565 int iterations;
8566 int nconss;
8567 int nliterals;
8568 int nreconvconss;
8569 int nreconvliterals;
8570
8571 assert(conflict != NULL);
8572 assert(set != NULL);
8573 assert(lp != NULL);
8574 assert(SCIPprobAllColsInLP(transprob, set, lp)); /* LP conflict analysis is only valid, if all variables are known */
8575
8576 assert(success == NULL || *success == FALSE);
8577
8578 /* check, if infeasible LP conflict analysis is enabled */
8579 if( !set->conf_enable || set->conf_useinflp == 'o' )
8580 return SCIP_OKAY;
8581
8582 /* check, if there are any conflict handlers to use a conflict set */
8583 if( set->nconflicthdlrs == 0 )
8584 return SCIP_OKAY;
8585
8586 SCIPsetDebugMsg(set, "analyzing conflict on infeasible LP in depth %d (solstat: %d, objchanged: %u)\n",
8588
8589 /* start timing */
8591 conflict->ninflpcalls++;
8592
8594
8596
8597 /* perform conflict analysis */
8598 SCIP_CALL( conflictAnalyzeLP(conflict, conflictstore, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, eventqueue, \
8599 cliquetable, SCIPlpDiving(lp), &dualraysuccess, &iterations, &nconss, &nliterals, &nreconvconss, &nreconvliterals, TRUE) );
8600 conflict->ninflpsuccess += ((nconss > 0 || conflict->ndualproofsinfsuccess > olddualproofsuccess) ? 1 : 0);
8601 conflict->ninflpiterations += iterations;
8602 conflict->ninflpconfconss += nconss;
8603 conflict->ninflpconfliterals += nliterals;
8604 conflict->ninflpreconvconss += nreconvconss;
8606 if( success != NULL )
8607 *success = (nconss > 0 || conflict->ndualproofsinfsuccess > olddualproofsuccess);
8608
8609 /* stop timing */
8611
8612 return SCIP_OKAY;
8613}
8614
8615/** analyzes a bound exceeding LP to find out the bound changes on variables that were responsible for exceeding the
8616 * primal bound;
8617 * on success, calls standard conflict analysis with the responsible variables as starting conflict set, thus creating
8618 * a conflict constraint out of the resulting conflict set;
8619 * updates statistics for bound exceeding LP conflict analysis
8620 */
8621static
8623 SCIP_CONFLICT* conflict, /**< conflict analysis data */
8624 SCIP_CONFLICTSTORE* conflictstore, /**< conflict store */
8625 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
8626 SCIP_SET* set, /**< global SCIP settings */
8627 SCIP_STAT* stat, /**< problem statistics */
8628 SCIP_PROB* transprob, /**< transformed problem */
8629 SCIP_PROB* origprob, /**< original problem */
8630 SCIP_TREE* tree, /**< branch and bound tree */
8631 SCIP_REOPT* reopt, /**< reoptimization data structure */
8632 SCIP_LP* lp, /**< LP data */
8633 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
8634 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
8635 SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
8636 SCIP_Bool* success /**< pointer to store whether a conflict constraint was created, or NULL */
8637 )
8638{
8639 SCIP_Bool dualraysuccess;
8640 SCIP_Longint oldnsuccess;
8641 int iterations;
8642 int nconss;
8643 int nliterals;
8644 int nreconvconss;
8645 int nreconvliterals;
8646
8647 assert(conflict != NULL);
8648 assert(set != NULL);
8649 assert(lp != NULL);
8651 assert(SCIPprobAllColsInLP(transprob, set, lp)); /* LP conflict analysis is only valid, if all variables are known */
8652
8653 assert(success == NULL || *success == FALSE);
8654
8655 /* check, if bound exceeding LP conflict analysis is enabled */
8656 if( !set->conf_enable || set->conf_useboundlp == 'o')
8657 return SCIP_OKAY;
8658
8659 /* check, if there are any conflict handlers to use a conflict set */
8660 if( set->nconflicthdlrs == 0 )
8661 return SCIP_OKAY;
8662
8663 SCIPsetDebugMsg(set, "analyzing conflict on bound exceeding LP in depth %d (solstat: %d)\n",
8665
8666 /* start timing */
8668 conflict->nboundlpcalls++;
8669
8670 /* mark the conflict to depend on the cutoff bound */
8672 conflict->conflictset->usescutoffbound = TRUE;
8673
8675
8676 /* perform conflict analysis */
8677 SCIP_CALL( conflictAnalyzeLP(conflict, conflictstore, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, eventqueue, \
8678 cliquetable, SCIPlpDiving(lp), &dualraysuccess, &iterations, &nconss, &nliterals, &nreconvconss, &nreconvliterals, TRUE) );
8679 conflict->nboundlpsuccess += ((nconss > 0 || conflict->ndualproofsbndsuccess + conflict->ndualproofsinfsuccess > oldnsuccess) ? 1 : 0);
8680 conflict->nboundlpiterations += iterations;
8681 conflict->nboundlpconfconss += nconss;
8682 conflict->nboundlpconfliterals += nliterals;
8683 conflict->nboundlpreconvconss += nreconvconss;
8685 if( success != NULL )
8686 *success = (nconss > 0 || conflict->ndualproofsbndsuccess + conflict->ndualproofsinfsuccess > oldnsuccess);
8687
8688 /* stop timing */
8690
8691 return SCIP_OKAY;
8692}
8693
8694/** analyzes an infeasible or bound exceeding LP to find out the bound changes on variables that were responsible for the
8695 * infeasibility or for exceeding the primal bound;
8696 * on success, calls standard conflict analysis with the responsible variables as starting conflict set, thus creating
8697 * a conflict constraint out of the resulting conflict set;
8698 * updates statistics for infeasible or bound exceeding LP conflict analysis;
8699 * may only be called if SCIPprobAllColsInLP()
8700 */
8702 SCIP_CONFLICT* conflict, /**< conflict analysis data */
8703 SCIP_CONFLICTSTORE* conflictstore, /**< conflict store */
8704 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
8705 SCIP_SET* set, /**< global SCIP settings */
8706 SCIP_STAT* stat, /**< problem statistics */
8707 SCIP_PROB* transprob, /**< transformed problem */
8708 SCIP_PROB* origprob, /**< original problem */
8709 SCIP_TREE* tree, /**< branch and bound tree */
8710 SCIP_REOPT* reopt, /**< reoptimization data structure */
8711 SCIP_LP* lp, /**< LP data */
8712 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
8713 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
8714 SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
8715 SCIP_Bool* success /**< pointer to store whether a conflict constraint was created, or NULL */
8716 )
8717{
8718 SCIP_LPSOLVALS storedsolvals;
8721 int c;
8722 int r;
8723
8724 if( success != NULL )
8725 *success = FALSE;
8726
8727 /* check if the conflict analysis is applicable */
8728 if( !set->conf_enable || (set->conf_useinflp == 'o' && set->conf_useboundlp == 'o') )
8729 return SCIP_OKAY;
8730
8731 /* in rare cases, it might happen that the solution stati of the LP and the LPI are out of sync; in particular this
8732 * happens when a new incumbent which cuts off the current node is found during the LP solving loop; in this case the
8733 * LP has status objlimit, but if diving has been used, the LPI only has the basis information, but is not solved
8734 *
8735 * @todo: alternatively, solve the LPI
8736 */
8737 if( !SCIPlpiWasSolved(SCIPlpGetLPI(lp)) )
8738 return SCIP_OKAY;
8739
8740 /* LP conflict analysis is only valid, if all variables are known */
8741 assert( SCIPprobAllColsInLP(transprob, set, lp) );
8743 || (SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OPTIMAL && set->lp_disablecutoff == 1) );
8744
8745 /* save status */
8746 storedsolvals.lpsolstat = lp->lpsolstat;
8747 storedsolvals.lpobjval = lp->lpobjval;
8748 storedsolvals.primalfeasible = lp->primalfeasible;
8749 storedsolvals.primalchecked = lp->primalchecked;
8750 storedsolvals.dualfeasible = lp->dualfeasible;
8751 storedsolvals.dualchecked = lp->dualchecked;
8752 storedsolvals.solisbasic = lp->solisbasic;
8753 storedsolvals.lpissolved = lp->solved;
8754
8755 /* store solution values */
8758 for (c = 0; c < lp->ncols; ++c)
8759 {
8760 SCIP_COL* col;
8761
8762 col = lp->cols[c];
8763 assert( col != NULL );
8764
8765 storedcolsolvals[c].primsol = col->primsol;
8766 storedcolsolvals[c].redcost = col->redcost;
8767 storedcolsolvals[c].basisstatus = col->basisstatus; /*lint !e641 !e732*/
8768 }
8769 for (r = 0; r < lp->nrows; ++r)
8770 {
8771 SCIP_ROW* row;
8772
8773 row = lp->rows[r];
8774 assert( row != NULL );
8775
8777 storedrowsolvals[r].dualsol = row->dualfarkas;
8778 else
8779 {
8781 (SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OPTIMAL && set->lp_disablecutoff == 1) );
8782 storedrowsolvals[r].dualsol = row->dualsol;
8783 }
8784 storedrowsolvals[r].activity = row->activity;
8785 storedrowsolvals[r].basisstatus = row->basisstatus; /*lint !e641 !e732*/
8786 }
8787
8788 /* check, if the LP was infeasible or bound exceeding */
8790 {
8791 SCIP_CALL( conflictAnalyzeInfeasibleLP(conflict, conflictstore, blkmem, set, stat, transprob, origprob, tree, \
8792 reopt, lp, branchcand, eventqueue, cliquetable, success) );
8793 }
8794 else
8795 {
8796 SCIP_CALL( conflictAnalyzeBoundexceedingLP(conflict, conflictstore, blkmem, set, stat, transprob, origprob, tree, \
8797 reopt, lp, branchcand, eventqueue, cliquetable, success) );
8798 }
8799
8800 /* possibly restore solution values */
8802 {
8803 /* restore status */
8804 lp->lpsolstat = storedsolvals.lpsolstat;
8805 lp->lpobjval = storedsolvals.lpobjval;
8806 lp->primalfeasible = storedsolvals.primalfeasible;
8807 lp->primalchecked = storedsolvals.primalchecked;
8808 lp->dualfeasible = storedsolvals.dualfeasible;
8809 lp->dualchecked = storedsolvals.dualchecked;
8810 lp->solisbasic = storedsolvals.solisbasic;
8811 lp->solved = storedsolvals.lpissolved;
8812
8813 for (c = 0; c < lp->ncols; ++c)
8814 {
8815 SCIP_COL* col;
8816
8817 col = lp->cols[c];
8818 assert( col != NULL );
8819 col->primsol = storedcolsolvals[c].primsol;
8820 col->redcost = storedcolsolvals[c].redcost;
8821 col->basisstatus = storedcolsolvals[c].basisstatus; /*lint !e641 !e732*/
8822 }
8823 for (r = 0; r < lp->nrows; ++r)
8824 {
8825 SCIP_ROW* row;
8826
8827 row = lp->rows[r];
8828 assert( row != NULL );
8829
8831 row->dualfarkas = storedrowsolvals[r].dualsol;
8832 else
8833 {
8835 row->dualsol = storedrowsolvals[r].dualsol;
8836 }
8837 row->activity = storedrowsolvals[r].activity;
8838 row->basisstatus = storedrowsolvals[r].basisstatus; /*lint !e641 !e732*/
8839 }
8840 }
8843
8844 return SCIP_OKAY;
8845}
8846
8847/** gets time in seconds used for analyzing infeasible LP conflicts */
8849 SCIP_CONFLICT* conflict /**< conflict analysis data */
8850 )
8851{
8852 assert(conflict != NULL);
8853
8854 return SCIPclockGetTime(conflict->inflpanalyzetime);
8855}
8856
8857/** gets number of calls to infeasible LP conflict analysis */
8859 SCIP_CONFLICT* conflict /**< conflict analysis data */
8860 )
8861{
8862 assert(conflict != NULL);
8863
8864 return conflict->ninflpcalls;
8865}
8866
8867/** gets number of calls to infeasible LP conflict analysis that yield at least one conflict constraint */
8869 SCIP_CONFLICT* conflict /**< conflict analysis data */
8870 )
8871{
8872 assert(conflict != NULL);
8873
8874 return conflict->ninflpsuccess;
8875}
8876
8877/** gets number of conflict constraints detected in infeasible LP conflict analysis */
8879 SCIP_CONFLICT* conflict /**< conflict analysis data */
8880 )
8881{
8882 assert(conflict != NULL);
8883
8884 return conflict->ninflpconfconss;
8885}
8886
8887/** gets total number of literals in conflict constraints created in infeasible LP conflict analysis */
8889 SCIP_CONFLICT* conflict /**< conflict analysis data */
8890 )
8891{
8892 assert(conflict != NULL);
8893
8894 return conflict->ninflpconfliterals;
8895}
8896
8897/** gets number of reconvergence constraints detected in infeasible LP conflict analysis */
8899 SCIP_CONFLICT* conflict /**< conflict analysis data */
8900 )
8901{
8902 assert(conflict != NULL);
8903
8904 return conflict->ninflpreconvconss;
8905}
8906
8907/** gets total number of literals in reconvergence constraints created in infeasible LP conflict analysis */
8909 SCIP_CONFLICT* conflict /**< conflict analysis data */
8910 )
8911{
8912 assert(conflict != NULL);
8913
8914 return conflict->ninflpreconvliterals;
8915}
8916
8917/** gets number of LP iterations in infeasible LP conflict analysis */
8919 SCIP_CONFLICT* conflict /**< conflict analysis data */
8920 )
8921{
8922 assert(conflict != NULL);
8923
8924 return conflict->ninflpiterations;
8925}
8926
8927/** gets time in seconds used for analyzing bound exceeding LP conflicts */
8929 SCIP_CONFLICT* conflict /**< conflict analysis data */
8930 )
8931{
8932 assert(conflict != NULL);
8933
8934 return SCIPclockGetTime(conflict->boundlpanalyzetime);
8935}
8936
8937/** gets number of calls to bound exceeding LP conflict analysis */
8939 SCIP_CONFLICT* conflict /**< conflict analysis data */
8940 )
8941{
8942 assert(conflict != NULL);
8943
8944 return conflict->nboundlpcalls;
8945}
8946
8947/** gets number of calls to bound exceeding LP conflict analysis that yield at least one conflict constraint */
8949 SCIP_CONFLICT* conflict /**< conflict analysis data */
8950 )
8951{
8952 assert(conflict != NULL);
8953
8954 return conflict->nboundlpsuccess;
8955}
8956
8957/** gets number of conflict constraints detected in bound exceeding LP conflict analysis */
8959 SCIP_CONFLICT* conflict /**< conflict analysis data */
8960 )
8961{
8962 assert(conflict != NULL);
8963
8964 return conflict->nboundlpconfconss;
8965}
8966
8967/** gets total number of literals in conflict constraints created in bound exceeding LP conflict analysis */
8969 SCIP_CONFLICT* conflict /**< conflict analysis data */
8970 )
8971{
8972 assert(conflict != NULL);
8973
8974 return conflict->nboundlpconfliterals;
8975}
8976
8977/** gets number of reconvergence constraints detected in bound exceeding LP conflict analysis */
8979 SCIP_CONFLICT* conflict /**< conflict analysis data */
8980 )
8981{
8982 assert(conflict != NULL);
8983
8984 return conflict->nboundlpreconvconss;
8985}
8986
8987/** gets total number of literals in reconvergence constraints created in bound exceeding LP conflict analysis */
8989 SCIP_CONFLICT* conflict /**< conflict analysis data */
8990 )
8991{
8992 assert(conflict != NULL);
8993
8994 return conflict->nboundlpreconvliterals;
8995}
8996
8997/** gets number of LP iterations in bound exceeding LP conflict analysis */
8999 SCIP_CONFLICT* conflict /**< conflict analysis data */
9000 )
9001{
9002 assert(conflict != NULL);
9003
9004 return conflict->nboundlpiterations;
9005}
9006
9007
9008
9009
9010/*
9011 * infeasible strong branching conflict analysis
9012 */
9013
9014/** analyses infeasible strong branching sub problems for conflicts */
9016 SCIP_CONFLICT* conflict, /**< conflict analysis data */
9017 SCIP_CONFLICTSTORE* conflictstore, /**< conflict store */
9018 BMS_BLKMEM* blkmem, /**< block memory buffers */
9019 SCIP_SET* set, /**< global SCIP settings */
9020 SCIP_STAT* stat, /**< dynamic problem statistics */
9021 SCIP_PROB* transprob, /**< transformed problem */
9022 SCIP_PROB* origprob, /**< original problem */
9023 SCIP_TREE* tree, /**< branch and bound tree */
9024 SCIP_REOPT* reopt, /**< reoptimization data structure */
9025 SCIP_LP* lp, /**< LP data */
9026 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
9027 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9028 SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
9029 SCIP_COL* col, /**< LP column with at least one infeasible strong branching subproblem */
9030 SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
9031 * infeasible downwards branch, or NULL */
9032 SCIP_Bool* upconflict /**< pointer to store whether a conflict constraint was created for an
9033 * infeasible upwards branch, or NULL */
9034 )
9035{
9036 int* cstat;
9037 int* rstat;
9038 SCIP_RETCODE retcode;
9039 SCIP_Bool resolve;
9040 SCIP_Real oldlb;
9041 SCIP_Real oldub;
9042 SCIP_Real newlb;
9043 SCIP_Real newub;
9044 SCIP_Bool dualraysuccess;
9045 int iter;
9046 int nconss;
9047 int nliterals;
9048 int nreconvconss;
9049 int nreconvliterals;
9050
9051 assert(stat != NULL);
9052 assert(lp != NULL);
9053 assert(lp->flushed);
9054 assert(lp->solved);
9055 assert(SCIPprobAllColsInLP(transprob, set, lp)); /* LP conflict analysis is only valid, if all variables are known */
9056 assert(col != NULL);
9057 assert((col->sbdownvalid && SCIPsetIsGE(set, col->sbdown, lp->cutoffbound)
9058 && SCIPsetFeasCeil(set, col->primsol-1.0) >= col->lb - 0.5)
9059 || (col->sbupvalid && SCIPsetIsGE(set, col->sbup, lp->cutoffbound)
9060 && SCIPsetFeasFloor(set, col->primsol+1.0) <= col->ub + 0.5));
9062
9063 if( downconflict != NULL )
9065 if( upconflict != NULL )
9066 *upconflict = FALSE;
9067
9068 /* check, if infeasible LP conflict analysis is enabled */
9069 if( !set->conf_enable || !set->conf_usesb )
9070 return SCIP_OKAY;
9071
9072 /* check, if there are any conflict handlers to use a conflict set */
9073 if( set->nconflicthdlrs == 0 )
9074 return SCIP_OKAY;
9075
9076 /* inform the LPI that strong branch is (temporarily) finished */
9078
9079 /* start timing */
9080 SCIPclockStart(conflict->sbanalyzetime, set);
9081
9082 /* get temporary memory for storing current LP basis */
9085
9086 /* get current LP basis */
9087 SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
9088
9089 /* remember old bounds */
9090 oldlb = col->lb;
9091 oldub = col->ub;
9092
9093 resolve = FALSE;
9094
9095 /* is down branch infeasible? */
9096 if( col->sbdownvalid && SCIPsetIsGE(set, col->sbdown, lp->cutoffbound) )
9097 {
9098 newub = SCIPsetFeasCeil(set, col->primsol-1.0);
9099 if( newub >= col->lb - 0.5 )
9100 {
9101 SCIPsetDebugMsg(set, "analyzing conflict on infeasible downwards strongbranch for variable <%s>[%g,%g] in depth %d\n",
9104
9106 conflict->nsbcalls++;
9107
9108 /* change the upper bound */
9109 col->ub = newub;
9110 SCIP_CALL( SCIPlpiChgBounds(lp->lpi, 1, &col->lpipos, &col->lb, &col->ub) );
9111
9112 /* start LP timer */
9114
9115 /* resolve the LP */
9116 retcode = SCIPlpiSolveDual(lp->lpi);
9117
9118 /* stop LP timer */
9120
9121 /* check return code of LP solving call */
9122 if( retcode != SCIP_LPERROR )
9123 {
9124 SCIP_CALL( retcode );
9125
9126 /* count number of LP iterations */
9128 stat->nconflictlps++;
9129 stat->nconflictlpiterations += iter;
9130 conflict->nsbiterations += iter;
9131 SCIPsetDebugMsg(set, " -> resolved downwards strong branching LP in %d iterations\n", iter);
9132
9133 /* perform conflict analysis on infeasible LP; last parameter guarantees status 'solved' on return */
9134 SCIP_CALL( conflictAnalyzeLP(conflict, conflictstore, blkmem, set, stat, transprob, origprob, tree, reopt, \
9135 lp, branchcand, eventqueue, cliquetable, TRUE, &dualraysuccess, &iter, &nconss, &nliterals, \
9137 conflict->nsbsuccess += ((nconss > 0 || dualraysuccess) ? 1 : 0);
9138 conflict->nsbiterations += iter;
9139 conflict->nsbconfconss += nconss;
9140 conflict->nsbconfliterals += nliterals;
9141 conflict->nsbreconvconss += nreconvconss;
9143 if( downconflict != NULL )
9144 *downconflict = (nconss > 0);
9145 }
9146
9147 /* reset the upper bound */
9148 col->ub = oldub;
9149 SCIP_CALL( SCIPlpiChgBounds(lp->lpi, 1, &col->lpipos, &col->lb, &col->ub) );
9150
9151 /* reset LP basis */
9152 SCIP_CALL( SCIPlpiSetBase(lp->lpi, cstat, rstat) );
9153
9154 /* mark the LP to be resolved at the end */
9155 resolve = TRUE;
9156 }
9157 }
9158
9159 /* is up branch infeasible? */
9160 if( col->sbupvalid && SCIPsetIsGE(set, col->sbup, lp->cutoffbound) )
9161 {
9162 newlb = SCIPsetFeasFloor(set, col->primsol+1.0);
9163 if( newlb <= col->ub + 0.5 )
9164 {
9165 SCIPsetDebugMsg(set, "analyzing conflict on infeasible upwards strongbranch for variable <%s>[%g,%g] in depth %d\n",
9168
9170 conflict->nsbcalls++;
9171
9172 /* change the lower bound */
9173 col->lb = newlb;
9174 SCIP_CALL( SCIPlpiChgBounds(lp->lpi, 1, &col->lpipos, &col->lb, &col->ub) );
9175
9176 /* start LP timer */
9178
9179 /* resolve the LP */
9180 retcode = SCIPlpiSolveDual(lp->lpi);
9181
9182 /* stop LP timer */
9184
9185 /* check return code of LP solving call */
9186 if( retcode != SCIP_LPERROR )
9187 {
9188 SCIP_CALL( retcode );
9189
9190 /* count number of LP iterations */
9192 stat->nconflictlps++;
9193 stat->nconflictlpiterations += iter;
9194 conflict->nsbiterations += iter;
9195 SCIPsetDebugMsg(set, " -> resolved upwards strong branching LP in %d iterations\n", iter);
9196
9197 /* perform conflict analysis on infeasible LP; last parameter guarantees status 'solved' on return */
9198 SCIP_CALL( conflictAnalyzeLP(conflict, conflictstore, blkmem, set, stat, transprob, origprob, tree, reopt, \
9199 lp, branchcand, eventqueue, cliquetable, TRUE, &dualraysuccess, &iter, &nconss, &nliterals, \
9201 conflict->nsbsuccess += ((nconss > 0 || dualraysuccess) ? 1 : 0);
9202 conflict->nsbiterations += iter;
9203 conflict->nsbconfconss += nconss;
9204 conflict->nsbconfliterals += nliterals;
9205 conflict->nsbreconvconss += nreconvconss;
9207 if( upconflict != NULL )
9208 *upconflict = (nconss > 0);
9209 }
9210
9211 /* reset the lower bound */
9212 col->lb = oldlb;
9213 SCIP_CALL( SCIPlpiChgBounds(lp->lpi, 1, &col->lpipos, &col->lb, &col->ub) );
9214
9215 /* reset LP basis */
9216 SCIP_CALL( SCIPlpiSetBase(lp->lpi, cstat, rstat) );
9217
9218 /* mark the LP to be resolved at the end */
9219 resolve = TRUE;
9220 }
9221 }
9222
9223 /* free temporary memory for storing current LP basis */
9224 SCIPsetFreeBufferArray(set, &rstat);
9225 SCIPsetFreeBufferArray(set, &cstat);
9226
9227 assert(lp->flushed);
9228
9229 /* resolve LP if something has changed in order to synchronize LPI and LP */
9230 if ( resolve )
9231 {
9232 /* start LP timer */
9234
9235 /* resolve the LP */
9237
9238 /* stop LP timer */
9240 }
9241
9242 /* stop timing */
9243 SCIPclockStop(conflict->sbanalyzetime, set);
9244
9245 /* inform the LPI that strong branch starts (again) */
9247
9248 return SCIP_OKAY;
9249}
9250
9251/** gets time in seconds used for analyzing infeasible strong branching conflicts */
9253 SCIP_CONFLICT* conflict /**< conflict analysis data */
9254 )
9255{
9256 assert(conflict != NULL);
9257
9258 return SCIPclockGetTime(conflict->sbanalyzetime);
9259}
9260
9261/** gets number of successful calls to dual proof analysis derived from infeasible LPs */
9263 SCIP_CONFLICT* conflict /**< conflict analysis data */
9264 )
9265{
9266 assert(conflict != NULL);
9267
9268 return conflict->ndualproofsinfsuccess;
9269}
9270
9271/** gets number of globally valid dual proof constraints derived from infeasible LPs */
9273 SCIP_CONFLICT* conflict /**< conflict analysis data */
9274 )
9275{
9276 assert(conflict != NULL);
9277
9278 return conflict->ndualproofsinfglobal;
9279}
9280
9281/** gets number of locally valid dual proof constraints derived from infeasible LPs */
9283 SCIP_CONFLICT* conflict /**< conflict analysis data */
9284 )
9285{
9286 assert(conflict != NULL);
9287
9288 return conflict->ndualproofsinflocal;
9289}
9290
9291/** gets average length of dual proof constraints derived from infeasible LPs */
9293 SCIP_CONFLICT* conflict /**< conflict analysis data */
9294 )
9295{
9296 assert(conflict != NULL);
9297
9298 return conflict->dualproofsinfnnonzeros;
9299}
9300
9301/** gets number of successfully analyzed dual proofs derived from bound exceeding LPs */
9303 SCIP_CONFLICT* conflict /**< conflict analysis data */
9304 )
9305{
9306 assert(conflict != NULL);
9307
9308 return conflict->ndualproofsbndsuccess;
9309}
9310
9311/** gets number of globally applied dual proofs derived from bound exceeding LPs */
9313 SCIP_CONFLICT* conflict /**< conflict analysis data */
9314 )
9315{
9316 assert(conflict != NULL);
9317
9318 return conflict->ndualproofsbndglobal;
9319}
9320
9321/** gets number of locally applied dual proofs derived from bound exceeding LPs */
9323 SCIP_CONFLICT* conflict /**< conflict analysis data */
9324 )
9325{
9326 assert(conflict != NULL);
9327
9328 return conflict->ndualproofsbndlocal;
9329}
9330
9331/** gets average length of dual proofs derived from bound exceeding LPs */
9333 SCIP_CONFLICT* conflict /**< conflict analysis data */
9334 )
9335{
9336 assert(conflict != NULL);
9337
9338 return conflict->dualproofsbndnnonzeros;
9339}
9340
9341/** gets number of calls to infeasible strong branching conflict analysis */
9343 SCIP_CONFLICT* conflict /**< conflict analysis data */
9344 )
9345{
9346 assert(conflict != NULL);
9347
9348 return conflict->nsbcalls;
9349}
9350
9351/** gets number of calls to infeasible strong branching conflict analysis that yield at least one conflict constraint */
9353 SCIP_CONFLICT* conflict /**< conflict analysis data */
9354 )
9355{
9356 assert(conflict != NULL);
9357
9358 return conflict->nsbsuccess;
9359}
9360
9361/** gets number of conflict constraints detected in infeasible strong branching conflict analysis */
9363 SCIP_CONFLICT* conflict /**< conflict analysis data */
9364 )
9365{
9366 assert(conflict != NULL);
9367
9368 return conflict->nsbconfconss;
9369}
9370
9371/** gets total number of literals in conflict constraints created in infeasible strong branching conflict analysis */
9373 SCIP_CONFLICT* conflict /**< conflict analysis data */
9374 )
9375{
9376 assert(conflict != NULL);
9377
9378 return conflict->nsbconfliterals;
9379}
9380
9381/** gets number of reconvergence constraints detected in infeasible strong branching conflict analysis */
9383 SCIP_CONFLICT* conflict /**< conflict analysis data */
9384 )
9385{
9386 assert(conflict != NULL);
9387
9388 return conflict->nsbreconvconss;
9389}
9390
9391/** gets total number of literals in reconvergence constraints created in infeasible strong branching conflict analysis */
9393 SCIP_CONFLICT* conflict /**< conflict analysis data */
9394 )
9395{
9396 assert(conflict != NULL);
9397
9398 return conflict->nsbreconvliterals;
9399}
9400
9401/** gets number of LP iterations in infeasible strong branching conflict analysis */
9403 SCIP_CONFLICT* conflict /**< conflict analysis data */
9404 )
9405{
9406 assert(conflict != NULL);
9407
9408 return conflict->nsbiterations;
9409}
9410
9411
9412
9413
9414/*
9415 * pseudo solution conflict analysis
9416 */
9417
9418/** analyzes a pseudo solution with objective value exceeding the current cutoff to find out the bound changes on
9419 * variables that were responsible for the objective value degradation;
9420 * on success, calls standard conflict analysis with the responsible variables as starting conflict set, thus creating
9421 * a conflict constraint out of the resulting conflict set;
9422 * updates statistics for pseudo solution conflict analysis
9423 */
9425 SCIP_CONFLICT* conflict, /**< conflict analysis data */
9426 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
9427 SCIP_SET* set, /**< global SCIP settings */
9428 SCIP_STAT* stat, /**< problem statistics */
9429 SCIP_PROB* transprob, /**< transformed problem */
9430 SCIP_PROB* origprob, /**< original problem */
9431 SCIP_TREE* tree, /**< branch and bound tree */
9432 SCIP_REOPT* reopt, /**< reoptimization data structure */
9433 SCIP_LP* lp, /**< LP data */
9434 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
9435 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9436 SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
9437 SCIP_Bool* success /**< pointer to store whether a conflict constraint was created, or NULL */
9438 )
9439{
9440 SCIP_VAR** vars;
9441 SCIP_VAR* var;
9442 SCIP_Real* curvarlbs;
9443 SCIP_Real* curvarubs;
9444 int* lbchginfoposs;
9445 int* ubchginfoposs;
9446 SCIP_Real* pseudocoefs;
9447 SCIP_Real pseudolhs;
9448 SCIP_Real pseudoact;
9449 int nvars;
9450 int v;
9451
9452 assert(conflict != NULL);
9453 assert(conflict->nconflictsets == 0);
9454 assert(set != NULL);
9455 assert(stat != NULL);
9456 assert(transprob != NULL);
9457 assert(lp != NULL);
9460
9461 if( success != NULL )
9462 *success = FALSE;
9463
9464 /* check, if pseudo solution conflict analysis is enabled */
9465 if( !set->conf_enable || !set->conf_usepseudo )
9466 return SCIP_OKAY;
9467
9468 /* check, if there are any conflict handlers to use a conflict set */
9469 if( set->nconflicthdlrs == 0 )
9470 return SCIP_OKAY;
9471
9472 SCIPsetDebugMsg(set, "analyzing pseudo solution (obj: %g) that exceeds objective limit (%g)\n",
9473 SCIPlpGetPseudoObjval(lp, set, transprob), lp->cutoffbound);
9474
9476 conflict->conflictset->usescutoffbound = TRUE;
9477
9478 /* start timing */
9480 conflict->npseudocalls++;
9481
9482 vars = transprob->vars;
9483 nvars = transprob->nvars;
9484 assert(nvars == 0 || vars != NULL);
9485
9486 /* The current primal bound c* gives an upper bound for the current pseudo objective value:
9487 * min{c^T x | lb <= x <= ub} <= c*.
9488 * We have to transform this row into a >= inequality in order to use methods above:
9489 * -c* <= max{-c^T x | lb <= x <= ub}.
9490 * In the local subproblem, this row is violated. We want to undo bound changes while still keeping the
9491 * row violated.
9492 */
9493
9494 /* get temporary memory for remembering variables' current bounds and corresponding bound change information
9495 * positions in variable's bound change information arrays
9496 */
9501
9502 /* get temporary memory for infeasibility proof coefficients */
9504
9505 /* for an integral objective use the cutoff bound reduced by the cutoff bound delta to cut off up to the next better
9506 * objective value
9507 */
9509
9510 /* store the objective values as infeasibility proof coefficients, and recalculate the pseudo activity */
9511 pseudoact = 0.0;
9512 for( v = 0; v < nvars; ++v )
9513 {
9514 var = vars[v];
9520
9521 if( SCIPsetIsZero(set, pseudocoefs[v]) )
9522 {
9523 pseudocoefs[v] = 0.0;
9524 continue;
9525 }
9526
9527 if( pseudocoefs[v] > 0.0 )
9528 pseudoact += pseudocoefs[v] * curvarubs[v];
9529 else
9530 pseudoact += pseudocoefs[v] * curvarlbs[v];
9531 }
9533 SCIPsetDebugMsg(set, " -> recalculated pseudo infeasibility proof: %g <= %g\n", pseudolhs, pseudoact);
9534
9535 /* check, if the pseudo row is still violated (after recalculation of pseudo activity) */
9537 {
9538 int nconss;
9539 int nliterals;
9540 int nreconvconss;
9541 int nreconvliterals;
9542
9543 /* undo bound changes without destroying the infeasibility proof */
9546
9547 /* analyze conflict on remaining bound changes */
9548 SCIP_CALL( conflictAnalyzeRemainingBdchgs(conflict, blkmem, set, stat, transprob, tree, FALSE, \
9550 conflict->npseudosuccess += (nconss > 0 ? 1 : 0);
9551 conflict->npseudoconfconss += nconss;
9552 conflict->npseudoconfliterals += nliterals;
9553 conflict->npseudoreconvconss += nreconvconss;
9555 if( success != NULL )
9556 *success = (nconss > 0);
9557 }
9558
9559 /* free temporary memory */
9565
9566 /* flush conflict set storage */
9567 SCIP_CALL( SCIPconflictFlushConss(conflict, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, eventqueue, cliquetable) );
9568
9569 /* stop timing */
9571
9572 return SCIP_OKAY;
9573}
9574
9575/** gets time in seconds used for analyzing pseudo solution conflicts */
9577 SCIP_CONFLICT* conflict /**< conflict analysis data */
9578 )
9579{
9580 assert(conflict != NULL);
9581
9582 return SCIPclockGetTime(conflict->pseudoanalyzetime);
9583}
9584
9585/** gets number of calls to pseudo solution conflict analysis */
9587 SCIP_CONFLICT* conflict /**< conflict analysis data */
9588 )
9589{
9590 assert(conflict != NULL);
9591
9592 return conflict->npseudocalls;
9593}
9594
9595/** gets number of calls to pseudo solution conflict analysis that yield at least one conflict constraint */
9597 SCIP_CONFLICT* conflict /**< conflict analysis data */
9598 )
9599{
9600 assert(conflict != NULL);
9601
9602 return conflict->npseudosuccess;
9603}
9604
9605/** gets number of conflict constraints detected in pseudo solution conflict analysis */
9607 SCIP_CONFLICT* conflict /**< conflict analysis data */
9608 )
9609{
9610 assert(conflict != NULL);
9611
9612 return conflict->npseudoconfconss;
9613}
9614
9615/** gets total number of literals in conflict constraints created in pseudo solution conflict analysis */
9617 SCIP_CONFLICT* conflict /**< conflict analysis data */
9618 )
9619{
9620 assert(conflict != NULL);
9621
9622 return conflict->npseudoconfliterals;
9623}
9624
9625/** gets number of reconvergence constraints detected in pseudo solution conflict analysis */
9627 SCIP_CONFLICT* conflict /**< conflict analysis data */
9628 )
9629{
9630 assert(conflict != NULL);
9631
9632 return conflict->npseudoreconvconss;
9633}
9634
9635/** gets total number of literals in reconvergence constraints created in pseudo solution conflict analysis */
9637 SCIP_CONFLICT* conflict /**< conflict analysis data */
9638 )
9639{
9640 assert(conflict != NULL);
9641
9642 return conflict->npseudoreconvliterals;
9643}
9644
9645
9646/** enables or disables all clocks of \p conflict, depending on the value of the flag */
9648 SCIP_CONFLICT* conflict, /**< the conflict analysis data for which all clocks should be enabled or disabled */
9649 SCIP_Bool enable /**< should the clocks of the conflict analysis data be enabled? */
9650 )
9651{
9652 assert(conflict != NULL);
9653
9660}
9661
static long bound
SCIP_VAR * h
void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
Definition clock.c:360
void SCIPclockEnableOrDisable(SCIP_CLOCK *clck, SCIP_Bool enable)
Definition clock.c:260
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition clock.c:290
SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
Definition clock.c:438
void SCIPclockReset(SCIP_CLOCK *clck)
Definition clock.c:209
void SCIPclockFree(SCIP_CLOCK **clck)
Definition clock.c:185
SCIP_RETCODE SCIPclockCreate(SCIP_CLOCK **clck, SCIP_CLOCKTYPE clocktype)
Definition clock.c:170
internal methods for clocks and timing issues
static SCIP_Bool conflictsetIsRedundant(SCIP_CONFLICTSET *conflictset1, SCIP_CONFLICTSET *conflictset2)
Definition conflict.c:1866
static SCIP_RETCODE detectImpliedBounds(SCIP_SET *set, SCIP_PROB *prob, SCIP_STAT *stat, SCIP_TREE *tree, BMS_BLKMEM *blkmem, SCIP_PROB *origprob, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_CONFLICTSET *conflictset, int *nbdchgs, int *nredvars, SCIP_Bool *redundant)
Definition conflict.c:2259
int SCIPconflictGetNConflicts(SCIP_CONFLICT *conflict)
Definition conflict.c:3781
SCIP_Longint SCIPconflictGetNAppliedGlobalConss(SCIP_CONFLICT *conflict)
Definition conflict.c:3821
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:5396
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:3572
SCIP_Longint SCIPconflictGetNDualproofsInfLocal(SCIP_CONFLICT *conflict)
Definition conflict.c:9282
SCIP_Longint SCIPconflictGetNAppliedLocalLiterals(SCIP_CONFLICT *conflict)
Definition conflict.c:3861
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:5829
SCIP_Longint SCIPconflictGetNPropCalls(SCIP_CONFLICT *conflict)
Definition conflict.c:5761
SCIP_Longint SCIPconflictGetNDualproofsInfNonzeros(SCIP_CONFLICT *conflict)
Definition conflict.c:9292
SCIP_Longint SCIPconflictGetNStrongbranchIterations(SCIP_CONFLICT *conflict)
Definition conflict.c:9402
SCIP_Real SCIPconflictGetInfeasibleLPTime(SCIP_CONFLICT *conflict)
Definition conflict.c:8848
SCIP_Longint SCIPconflictGetNInfeasibleLPCalls(SCIP_CONFLICT *conflict)
Definition conflict.c:8858
#define BOUNDSWITCH
Definition conflict.c:172
static SCIP_RETCODE conflictQueueBound(SCIP_CONFLICT *conflict, SCIP_SET *set, SCIP_BDCHGINFO *bdchginfo, SCIP_Real relaxedbd)
Definition conflict.c:4294
SCIP_RETCODE SCIPconflictCreate(SCIP_CONFLICT **conflict, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition conflict.c:3935
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:6498
SCIP_Real SCIPconflictGetGlobalApplTime(SCIP_CONFLICT *conflict)
Definition conflict.c:5741
static void conflictClear(SCIP_CONFLICT *conflict)
Definition conflict.c:4061
SCIP_Longint SCIPconflictGetNInfeasibleLPSuccess(SCIP_CONFLICT *conflict)
Definition conflict.c:8868
void SCIPconflicthdlrEnableOrDisableClocks(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_Bool enable)
Definition conflict.c:826
static void proofsetFree(SCIP_PROOFSET **proofset, BMS_BLKMEM *blkmem)
Definition conflict.c:982
static SCIP_RETCODE conflictEnsureTmpbdchginfosMem(SCIP_CONFLICT *conflict, SCIP_SET *set, int num)
Definition conflict.c:1213
SCIP_Longint SCIPconflictGetNBoundexceedingLPReconvergenceConss(SCIP_CONFLICT *conflict)
Definition conflict.c:8978
SCIP_Longint SCIPconflictGetNGlobalChgBds(SCIP_CONFLICT *conflict)
Definition conflict.c:3811
#define MAXFRAC
Definition conflict.c:177
SCIP_Longint SCIPconflictGetNAppliedLiterals(SCIP_CONFLICT *conflict)
Definition conflict.c:3801
static SCIP_Bool checkDualFeasibility(SCIP_SET *set, SCIP_ROW *row, SCIP_Real weight, SCIP_Bool *zerocontribution)
Definition conflict.c:6726
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:9015
static SCIP_Bool isBoundchgUseless(SCIP_SET *set, SCIP_BDCHGINFO *bdchginfo)
Definition conflict.c:4274
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
void SCIPconflicthdlrSetExitsol(SCIP_CONFLICTHDLR *conflicthdlr,)
Definition conflict.c:761
static void conflictsetCalcConflictDepth(SCIP_CONFLICTSET *conflictset)
Definition conflict.c:1775
SCIP_RETCODE SCIPconflicthdlrExit(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_SET *set)
Definition conflict.c:559
SCIP_Longint SCIPconflictGetNPropConflictLiterals(SCIP_CONFLICT *conflict)
Definition conflict.c:5791
void SCIPconflicthdlrSetFree(SCIP_CONFLICTHDLR *conflicthdlr,)
Definition conflict.c:717
SCIP_Longint SCIPconflictGetNAppliedConss(SCIP_CONFLICT *conflict)
Definition conflict.c:3791
static char varGetChar(SCIP_VAR *var)
Definition conflict.c:919
static SCIP_RETCODE conflictInitProofset(SCIP_CONFLICT *conflict, BMS_BLKMEM *blkmem)
Definition conflict.c:967
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:2537
#define POSTPROCESS
Definition conflict.c:173
SCIP_Longint SCIPconflictGetNInfeasibleLPConflictConss(SCIP_CONFLICT *conflict)
Definition conflict.c:8878
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:7569
SCIP_Longint SCIPconflictGetNBoundexceedingLPConflictConss(SCIP_CONFLICT *conflict)
Definition conflict.c:8958
SCIP_Longint SCIPconflictGetNBoundexceedingLPSuccess(SCIP_CONFLICT *conflict)
Definition conflict.c:8948
SCIP_Longint SCIPconflictGetNStrongbranchCalls(SCIP_CONFLICT *conflict)
Definition conflict.c:9342
SCIP_Longint SCIPconflictGetNInfeasibleLPReconvergenceLiterals(SCIP_CONFLICT *conflict)
Definition conflict.c:8908
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:8229
static SCIP_Bool bdchginfoIsInvalid(SCIP_CONFLICT *conflict, SCIP_BDCHGINFO *bdchginfo)
Definition conflict.c:1490
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
SCIP_Longint SCIPconflictGetNPropReconvergenceConss(SCIP_CONFLICT *conflict)
Definition conflict.c:5801
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:9424
void SCIPconflicthdlrSetPriority(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_SET *set, int priority)
Definition conflict.c:802
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:4431
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:3416
SCIP_RETCODE SCIPconflicthdlrFree(SCIP_CONFLICTHDLR **conflicthdlr, SCIP_SET *set)
Definition conflict.c:494
SCIP_Real SCIPconflictGetBoundexceedingLPTime(SCIP_CONFLICT *conflict)
Definition conflict.c:8928
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:5683
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:3018
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:6440
void SCIPconflicthdlrSetCopy(SCIP_CONFLICTHDLR *conflicthdlr,)
Definition conflict.c:706
SCIP_Longint SCIPconflictGetNStrongbranchReconvergenceLiterals(SCIP_CONFLICT *conflict)
Definition conflict.c:9392
static SCIP_Real * proofsetGetVals(SCIP_PROOFSET *proofset)
Definition conflict.c:1033
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:6055
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:5937
#define ALLOWLOCAL
Definition conflict.c:175
SCIP_Real SCIPconflictGetPseudoTime(SCIP_CONFLICT *conflict)
Definition conflict.c:9576
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:7155
static SCIP_CONFTYPE proofsetGetConftype(SCIP_PROOFSET *proofset)
Definition conflict.c:1066
SCIP_Longint SCIPconflictGetNPseudoReconvergenceLiterals(SCIP_CONFLICT *conflict)
Definition conflict.c:9636
static SCIP_RETCODE conflictEnsureProofsetsMem(SCIP_CONFLICT *conflict, SCIP_SET *set, int num)
Definition conflict.c:1928
static SCIP_RETCODE conflictsetCreate(SCIP_CONFLICTSET **conflictset, BMS_BLKMEM *blkmem)
Definition conflict.c:1296
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:5159
SCIP_RETCODE SCIPconflicthdlrExitsol(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_SET *set)
Definition conflict.c:614
SCIP_Longint SCIPconflictGetNPropReconvergenceLiterals(SCIP_CONFLICT *conflict)
Definition conflict.c:5811
SCIP_Bool SCIPconflictApplicable(SCIP_SET *set)
Definition conflict.c:3919
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:2841
static SCIP_RETCODE conflictResolveBound(SCIP_CONFLICT *conflict, SCIP_SET *set, SCIP_BDCHGINFO *bdchginfo, SCIP_Real relaxedbd, int validdepth, SCIP_Bool *resolved)
Definition conflict.c:4946
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:6842
static void conflictsetFree(SCIP_CONFLICTSET **conflictset, BMS_BLKMEM *blkmem)
Definition conflict.c:1353
static void conflictsetClear(SCIP_CONFLICTSET *conflictset)
Definition conflict.c:1277
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:4492
static int * proofsetGetInds(SCIP_PROOFSET *proofset)
Definition conflict.c:1022
static SCIP_Real conflictsetCalcScore(SCIP_CONFLICTSET *conflictset, SCIP_SET *set)
Definition conflict.c:1399
static int conflictCalcMaxsize(SCIP_SET *set, SCIP_PROB *prob)
Definition conflict.c:2091
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:2767
static SCIP_RETCODE conflictAddConflictBound(SCIP_CONFLICT *conflict, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_BDCHGINFO *bdchginfo, SCIP_Real relaxedbd)
Definition conflict.c:4231
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:2914
static SCIP_RETCODE lpbdchgsCreate(SCIP_LPBDCHGS **lpbdchgs, SCIP_SET *set, int ncols)
Definition conflict.c:864
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_Longint SCIPconflictGetNInfeasibleLPReconvergenceConss(SCIP_CONFLICT *conflict)
Definition conflict.c:8898
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:7438
SCIP_Longint SCIPconflictGetNAppliedLocalConss(SCIP_CONFLICT *conflict)
Definition conflict.c:3851
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:7852
static SCIP_RETCODE sortLocalRows(SCIP_SET *set, SCIP_AGGRROW *aggrrow, SCIP_ROW **rows, int *rowinds, int *rowdepth, int nrows)
Definition conflict.c:6774
SCIP_Longint SCIPconflictGetNStrongbranchReconvergenceConss(SCIP_CONFLICT *conflict)
Definition conflict.c:9382
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:8622
static SCIP_RETCODE conflictsetCopy(SCIP_CONFLICTSET **targetconflictset, BMS_BLKMEM *blkmem, SCIP_CONFLICTSET *sourceconflictset, int nadditionalelems)
Definition conflict.c:1316
static SCIP_RETCODE conflictsetAddBound(SCIP_CONFLICTSET *conflictset, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_BDCHGINFO *bdchginfo, SCIP_Real relaxedbd)
Definition conflict.c:1533
static int proofsetGetNVars(SCIP_PROOFSET *proofset)
Definition conflict.c:1055
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
static SCIP_RETCODE proofsetAddAggrrow(SCIP_PROOFSET *proofset, SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_AGGRROW *aggrrow)
Definition conflict.c:1128
SCIP_Real SCIPconflictGetVarUb(SCIP_CONFLICT *conflict, SCIP_VAR *var)
Definition conflict.c:4733
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:2687
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:8701
SCIP_Longint SCIPconflictGetNBoundexceedingLPConflictLiterals(SCIP_CONFLICT *conflict)
Definition conflict.c:8968
static SCIP_Bool conflictMarkBoundCheckPresence(SCIP_CONFLICT *conflict, SCIP_SET *set, SCIP_BDCHGINFO *bdchginfo, SCIP_Real relaxedbd)
Definition conflict.c:4142
SCIP_RETCODE SCIPconflicthdlrCopyInclude(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_SET *set)
Definition conflict.c:389
#define NUMSTOP
Definition conflict.c:6436
SCIP_Real SCIPconflictGetStrongbranchTime(SCIP_CONFLICT *conflict)
Definition conflict.c:9252
#define USEVBDS
Definition conflict.c:174
void SCIPconflicthdlrSetExit(SCIP_CONFLICTHDLR *conflicthdlr,)
Definition conflict.c:739
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
SCIP_Longint SCIPconflictGetNPseudoSuccess(SCIP_CONFLICT *conflict)
Definition conflict.c:9596
SCIP_Longint SCIPconflictGetNInfeasibleLPConflictLiterals(SCIP_CONFLICT *conflict)
Definition conflict.c:8888
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:5868
static SCIP_RETCODE convertToActiveVar(SCIP_VAR **var, SCIP_SET *set, SCIP_BOUNDTYPE *boundtype, SCIP_Real *bound)
Definition conflict.c:4340
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
SCIP_Longint SCIPconflictGetNPseudoConflictLiterals(SCIP_CONFLICT *conflict)
Definition conflict.c:9616
static SCIP_Bool bdchginfoIsResolvable(SCIP_BDCHGINFO *bdchginfo)
Definition conflict.c:3879
static SCIP_Bool checkRedundancy(SCIP_SET *set, SCIP_CONFLICTSET *conflictset)
Definition conflict.c:2194
static void lpbdchgsReset(SCIP_LPBDCHGS *lpbdchgs, int ncols)
Definition conflict.c:886
SCIP_Longint SCIPconflictGetNLocalChgBds(SCIP_CONFLICT *conflict)
Definition conflict.c:3841
SCIP_Longint SCIPconflictGetNDualproofsBndSuccess(SCIP_CONFLICT *conflict)
Definition conflict.c:9302
SCIP_RETCODE SCIPconflictIsVarUsed(SCIP_CONFLICT *conflict, SCIP_VAR *var, SCIP_SET *set, SCIP_BOUNDTYPE boundtype, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool *used)
Definition conflict.c:4656
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:6223
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:4375
#define MINFRAC
Definition conflict.c:176
SCIP_Longint SCIPconflictGetNPropSuccess(SCIP_CONFLICT *conflict)
Definition conflict.c:5771
SCIP_Longint SCIPconflictGetNDualproofsInfSuccess(SCIP_CONFLICT *conflict)
Definition conflict.c:9262
#define debugPrintViolationInfo(...)
Definition conflict.c:7391
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:6983
SCIP_Longint SCIPconflictGetNBoundexceedingLPCalls(SCIP_CONFLICT *conflict)
Definition conflict.c:8938
static SCIP_RETCODE conflictsetCalcInsertDepth(SCIP_CONFLICTSET *conflictset, SCIP_SET *set, SCIP_TREE *tree)
Definition conflict.c:1819
SCIP_Longint SCIPconflictGetNPropConflictConss(SCIP_CONFLICT *conflict)
Definition conflict.c:5781
static void proofsetCancelVarWithBound(SCIP_PROOFSET *proofset, SCIP_SET *set, SCIP_VAR *var, int pos, SCIP_Bool *valid)
Definition conflict.c:1169
static SCIP_BDCHGINFO * conflictRemoveCand(SCIP_CONFLICT *conflict)
Definition conflict.c:4749
static void tightenCoefficients(SCIP_SET *set, SCIP_PROOFSET *proofset, int *nchgcoefs, SCIP_Bool *redundant)
Definition conflict.c:7396
SCIP_Longint SCIPconflictGetNStrongbranchSuccess(SCIP_CONFLICT *conflict)
Definition conflict.c:9352
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:6555
static void proofsetClear(SCIP_PROOFSET *proofset)
Definition conflict.c:932
SCIP_Longint SCIPconflictGetNDualproofsBndGlobal(SCIP_CONFLICT *conflict)
Definition conflict.c:9312
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:8546
SCIP_Longint SCIPconflictGetNPseudoReconvergenceConss(SCIP_CONFLICT *conflict)
Definition conflict.c:9626
static SCIP_RETCODE conflictsetEnsureBdchginfosMem(SCIP_CONFLICTSET *conflictset, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
Definition conflict.c:1369
SCIP_Longint SCIPconflictGetNAppliedGlobalLiterals(SCIP_CONFLICT *conflict)
Definition conflict.c:3831
static SCIP_BDCHGINFO * conflictFirstCand(SCIP_CONFLICT *conflict)
Definition conflict.c:4793
SCIP_Longint SCIPconflictGetNDualproofsBndLocal(SCIP_CONFLICT *conflict)
Definition conflict.c:9322
SCIP_RETCODE SCIPconflictInit(SCIP_CONFLICT *conflict, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_CONFTYPE conftype, SCIP_Bool usescutoffbound)
Definition conflict.c:4073
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:6018
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
void SCIPconflicthdlrSetInit(SCIP_CONFLICTHDLR *conflicthdlr,)
Definition conflict.c:728
SCIP_Longint SCIPconflictGetNPseudoCalls(SCIP_CONFLICT *conflict)
Definition conflict.c:9586
static SCIP_RETCODE proofsetCreate(SCIP_PROOFSET **proofset, BMS_BLKMEM *blkmem)
Definition conflict.c:946
SCIP_RETCODE SCIPconflicthdlrInitsol(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_SET *set)
Definition conflict.c:590
static void skipRedundantBdchginfos(SCIP_VAR *var, int *lbchginfopos, int *ubchginfopos)
Definition conflict.c:6191
void SCIPconflictEnableOrDisableClocks(SCIP_CONFLICT *conflict, SCIP_Bool enable)
Definition conflict.c:9647
static SCIP_RETCODE conflictInsertConflictset(SCIP_CONFLICT *conflict, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_CONFLICTSET **conflictset)
Definition conflict.c:1997
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:3297
static SCIP_Real proofsetGetRhs(SCIP_PROOFSET *proofset)
Definition conflict.c:1044
SCIP_Real SCIPconflictGetPropTime(SCIP_CONFLICT *conflict)
Definition conflict.c:5751
static SCIP_RETCODE conflictEnsureConflictsetsMem(SCIP_CONFLICT *conflict, SCIP_SET *set, int num)
Definition conflict.c:1952
SCIP_Longint SCIPconflictGetNBoundexceedingLPIterations(SCIP_CONFLICT *conflict)
Definition conflict.c:8998
static void lpbdchgsFree(SCIP_LPBDCHGS **lpbdchgs, SCIP_SET *set)
Definition conflict.c:899
SCIP_Longint SCIPconflictGetNStrongbranchConflictLiterals(SCIP_CONFLICT *conflict)
Definition conflict.c:9372
SCIP_RETCODE SCIPconflicthdlrInit(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_SET *set)
Definition conflict.c:522
static SCIP_RETCODE addRowToAggrRow(SCIP_SET *set, SCIP_ROW *row, SCIP_Real weight, SCIP_AGGRROW *aggrrow)
Definition conflict.c:6694
SCIP_Longint SCIPconflictGetNPseudoConflictConss(SCIP_CONFLICT *conflict)
Definition conflict.c:9606
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:4847
static void conflictFreeTmpBdchginfos(SCIP_CONFLICT *conflict, BMS_BLKMEM *blkmem)
Definition conflict.c:1261
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:7761
SCIP_Longint SCIPconflictGetNDualproofsBndNonzeros(SCIP_CONFLICT *conflict)
Definition conflict.c:9332
SCIP_Longint SCIPconflictGetNDualproofsInfGlobal(SCIP_CONFLICT *conflict)
Definition conflict.c:9272
SCIP_Longint SCIPconflictGetNBoundexceedingLPReconvergenceLiterals(SCIP_CONFLICT *conflict)
Definition conflict.c:8988
SCIP_RETCODE SCIPconflictFree(SCIP_CONFLICT **conflict, BMS_BLKMEM *blkmem)
Definition conflict.c:4025
SCIP_Real SCIPconflictGetVarLb(SCIP_CONFLICT *conflict, SCIP_VAR *var)
Definition conflict.c:4716
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
void SCIPconflicthdlrSetInitsol(SCIP_CONFLICTHDLR *conflicthdlr,)
Definition conflict.c:750
SCIP_Longint SCIPconflictGetNStrongbranchConflictConss(SCIP_CONFLICT *conflict)
Definition conflict.c:9362
SCIP_Longint SCIPconflictGetNInfeasibleLPIterations(SCIP_CONFLICT *conflict)
Definition conflict.c:8918
static SCIP_RETCODE proofsetAddSparseData(SCIP_PROOFSET *proofset, BMS_BLKMEM *blkmem, SCIP_Real *vals, int *inds, int nnz, SCIP_Real rhs)
Definition conflict.c:1077
static SCIP_RETCODE conflictInsertProofset(SCIP_CONFLICT *conflict, SCIP_SET *set, SCIP_PROOFSET *proofset)
Definition conflict.c:1977
internal methods for conflict analysis
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)
int SCIPconflictstoreGetNDualInfProofs(SCIP_CONFLICTSTORE *conflictstore)
SCIP_Real SCIPconflictstoreGetAvgNnzDualInfProofs(SCIP_CONFLICTSTORE *conflictstore)
int SCIPconflictstoreGetNDualBndProofs(SCIP_CONFLICTSTORE *conflictstore)
SCIP_Real SCIPconflictstoreGetAvgNnzDualBndProofs(SCIP_CONFLICTSTORE *conflictstore)
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)
internal methods for storing conflicts
void SCIPconsMarkConflict(SCIP_CONS *cons)
Definition cons.c:6994
SCIP_RETCODE SCIPconsRelease(SCIP_CONS **cons, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition cons.c:6206
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:7192
internal methods for constraints and constraint handlers
Constraint handler for linear constraints in their most general form, .
methods for the aggregation rows
#define QUAD_EPSILON
Definition dbldblarith.h:42
#define SCIPquadprecProdDD(r, a, b)
Definition dbldblarith.h:58
#define SCIPquadprecProdQD(r, a, b)
Definition dbldblarith.h:63
#define QUAD_ASSIGN(a, constant)
Definition dbldblarith.h:51
#define QUAD(x)
Definition dbldblarith.h:47
#define SCIPquadprecSumDD(r, a, b)
Definition dbldblarith.h:60
#define SCIPquadprecSumQQ(r, a, b)
Definition dbldblarith.h:67
#define QUAD_TO_DBL(x)
Definition dbldblarith.h:49
#define SCIPdebugCheckConflict(blkmem, set, node, bdchginfos, relaxedbds, nliterals)
Definition debug.h:295
#define SCIPdebugCheckConflictFrontier(blkmem, set, node, bdchginfo, bdchginfos, relaxedbds, nliterals, bdchgqueue, forcedbdchgqueue)
Definition debug.h:296
#define SCIP_MAXSTRLEN
Definition def.h:302
#define EPSGE(x, y, eps)
Definition def.h:215
#define SCIP_Longint
Definition def.h:171
#define SCIP_REAL_MAX
Definition def.h:187
#define SCIP_INVALID
Definition def.h:206
#define SCIP_Bool
Definition def.h:93
#define EPSLE(x, y, eps)
Definition def.h:213
#define SCIP_ALLOC(x)
Definition def.h:399
#define SCIP_Real
Definition def.h:186
#define TRUE
Definition def.h:95
#define FALSE
Definition def.h:96
#define SCIPABORT()
Definition def.h:360
#define SCIP_REAL_MIN
Definition def.h:188
#define REALABS(x)
Definition def.h:210
#define SCIP_CALL(x)
Definition def.h:388
#define SCIP_CALL_FINALLY(x, y)
Definition def.h:430
SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPupgradeConsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_CONS **upgdcons)
SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
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)
void SCIPgmlWriteNode(FILE *file, unsigned int id, const char *label, const char *nodetype, const char *fillcolor, const char *bordercolor)
Definition misc.c:496
void SCIPgmlWriteClosing(FILE *file)
Definition misc.c:698
void SCIPgmlWriteOpening(FILE *file, SCIP_Bool directed)
Definition misc.c:682
void SCIPgmlWriteEdge(FILE *file, unsigned int source, unsigned int target, const char *label, const char *color)
Definition misc.c:594
void SCIPgmlWriteArc(FILE *file, unsigned int source, unsigned int target, const char *label, const char *color)
Definition misc.c:638
SCIP_RETCODE SCIPlpiChgSides(SCIP_LPI *lpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
Definition lpi_clp.cpp:1167
SCIP_RETCODE SCIPlpiGetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
Definition lpi_clp.cpp:3796
SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
Definition lpi_clp.cpp:3919
SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
Definition lpi_clp.cpp:2690
SCIP_Bool SCIPlpiIsInfinity(SCIP_LPI *lpi, SCIP_Real val)
Definition lpi_clp.cpp:3931
SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
Definition lpi_clp.cpp:2967
SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
Definition lpi_clp.cpp:3833
SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
Definition lpi_clp.cpp:2857
SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
Definition lpi_clp.cpp:2766
SCIP_RETCODE SCIPlpiStartStrongbranch(SCIP_LPI *lpi)
Definition lpi_clp.cpp:2006
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_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
Definition lpi_clp.cpp:2609
SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
Definition lpi_clp.cpp:3692
SCIP_RETCODE SCIPlpiSetBase(SCIP_LPI *lpi, const int *cstat, const int *rstat)
Definition lpi_clp.cpp:3067
SCIP_Bool SCIPlpiWasSolved(SCIP_LPI *lpi)
Definition lpi_clp.cpp:2386
SCIP_Bool SCIPlpiIsOptimal(SCIP_LPI *lpi)
Definition lpi_clp.cpp:2623
SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
Definition lpi_clp.cpp:2018
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
SCIP_Bool SCIPlpiHasDualRay(SCIP_LPI *lpi)
Definition lpi_clp.cpp:2556
SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
Definition lpi_clp.cpp:2502
SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
Definition lpi_clp.cpp:1880
SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
Definition lpi_clp.cpp:2921
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
void ** SCIPpqueueElems(SCIP_PQUEUE *pqueue)
Definition misc.c:1488
void SCIPpqueueClear(SCIP_PQUEUE *pqueue)
Definition misc.c:1283
SCIP_RETCODE SCIPpqueueCreate(SCIP_PQUEUE **pqueue, int initsize, SCIP_Real sizefac, SCIP_DECL_SORTPTRCOMP((*ptrcomp)),)
Definition misc.c:1245
void SCIPpqueueFree(SCIP_PQUEUE **pqueue)
Definition misc.c:1272
SCIP_RETCODE SCIPpqueueInsert(SCIP_PQUEUE *pqueue, void *elem)
Definition misc.c:1344
int SCIPpqueueNElems(SCIP_PQUEUE *pqueue)
Definition misc.c:1477
void * SCIPpqueueRemove(SCIP_PQUEUE *pqueue)
Definition misc.c:1443
void * SCIPpqueueFirst(SCIP_PQUEUE *pqueue)
Definition misc.c:1463
int SCIPcolGetLPPos(SCIP_COL *col)
Definition lp.c:17093
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
Definition lp.c:17042
int SCIPcolGetNNonz(SCIP_COL *col)
Definition lp.c:17126
SCIP_BOUNDTYPE SCIPboundtypeOpposite(SCIP_BOUNDTYPE boundtype)
Definition lp.c:17203
SCIP_CONFLICTHDLRDATA * SCIPconflicthdlrGetData(SCIP_CONFLICTHDLR *conflicthdlr)
Definition conflict.c:685
int SCIPconflicthdlrGetPriority(SCIP_CONFLICTHDLR *conflicthdlr)
Definition conflict.c:792
const char * SCIPconflicthdlrGetName(SCIP_CONFLICTHDLR *conflicthdlr)
Definition conflict.c:772
void SCIPconflicthdlrSetData(SCIP_CONFLICTHDLR *conflicthdlr, SCIP_CONFLICTHDLRDATA *conflicthdlrdata)
Definition conflict.c:695
SCIP_Bool SCIPconflicthdlrIsInitialized(SCIP_CONFLICTHDLR *conflicthdlr)
Definition conflict.c:816
SCIP_Real SCIPconflicthdlrGetTime(SCIP_CONFLICTHDLR *conflicthdlr)
Definition conflict.c:848
SCIP_Real SCIPconflicthdlrGetSetupTime(SCIP_CONFLICTHDLR *conflicthdlr)
Definition conflict.c:838
const char * SCIPconflicthdlrGetDesc(SCIP_CONFLICTHDLR *conflicthdlr)
Definition conflict.c:782
SCIP_RETCODE SCIPsetConflicthdlrPriority(SCIP *scip, SCIP_CONFLICTHDLR *conflicthdlr, int priority)
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition cons.c:4180
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition cons.c:8108
int SCIPconsGetValidDepth(SCIP_CONS *cons)
Definition cons.c:8171
SCIP_Bool SCIPconsIsGlobal(SCIP_CONS *cons)
Definition cons.c:8317
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition cons.c:8088
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition scip_cons.c:1119
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:4218
SCIP_Bool SCIPcutsTightenCoefficients(SCIP *scip, SCIP_Bool cutislocal, SCIP_Real *cutcoefs, SCIP_Real *cutrhs, int *cutinds, int *cutnnz, int *nchgcoefs)
Definition cuts.c:1535
SCIP_RETCODE SCIPaggrRowCreate(SCIP *scip, SCIP_AGGRROW **aggrrow)
Definition cuts.c:1731
void SCIPaggrRowClear(SCIP_AGGRROW *aggrrow)
Definition cuts.c:2141
SCIP_Real SCIPaggrRowGetRhs(SCIP_AGGRROW *aggrrow)
Definition cuts.c:2589
void SCIPaggrRowFree(SCIP *scip, SCIP_AGGRROW **aggrrow)
Definition cuts.c:1763
int * SCIPaggrRowGetInds(SCIP_AGGRROW *aggrrow)
Definition cuts.c:2549
void SCIPaggrRowRemoveZeros(SCIP *scip, SCIP_AGGRROW *aggrrow, SCIP_Bool useglbbounds, SCIP_Bool *valid)
Definition cuts.c:2479
int SCIPaggrRowGetNNz(SCIP_AGGRROW *aggrrow)
Definition cuts.c:2559
SCIP_RETCODE SCIPaggrRowAddRow(SCIP *scip, SCIP_AGGRROW *aggrrow, SCIP_ROW *row, SCIP_Real weight, int sidetype)
Definition cuts.c:1867
static INLINE SCIP_Real SCIPaggrRowGetProbvarValue(SCIP_AGGRROW *aggrrow, int probindex)
Definition cuts.h:251
SCIP_RETCODE SCIPaggrRowAddObjectiveFunction(SCIP *scip, SCIP_AGGRROW *aggrrow, SCIP_Real rhs, SCIP_Real scale)
Definition cuts.c:2012
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:7428
SCIP_Real SCIPaggrRowCalcEfficacyNorm(SCIP *scip, SCIP_AGGRROW *aggrrow)
Definition cuts.c:2166
#define SCIPfreeBufferArrayNull(scip, ptr)
Definition scip_mem.h:137
SCIP_Longint SCIPnodeGetNumber(SCIP_NODE *node)
Definition tree.c:7444
int SCIPnodeGetDepth(SCIP_NODE *node)
Definition tree.c:7454
const char * SCIPpropGetName(SCIP_PROP *prop)
Definition prop.c:941
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
Definition lp.c:17292
int SCIProwGetLPDepth(SCIP_ROW *row)
Definition lp.c:17512
SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
Definition lp.c:17302
int SCIProwGetLPPos(SCIP_ROW *row)
Definition lp.c:17501
SCIP_Bool SCIProwIsLocal(SCIP_ROW *row)
Definition lp.c:17401
const char * SCIProwGetName(SCIP_ROW *row)
Definition lp.c:17351
SCIP_Real SCIProwGetConstant(SCIP_ROW *row)
Definition lp.c:17258
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 SCIPgetVarBdAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition scip_var.c:2264
int SCIPvarGetNVlbs(SCIP_VAR *var)
Definition var.c:18092
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition var.c:17611
SCIP_Bool SCIPbdchginfoIsRedundant(SCIP_BDCHGINFO *bdchginfo)
Definition var.c:18630
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition var.c:17570
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition var.c:17421
SCIP_Bool SCIPbdchgidxIsEarlier(SCIP_BDCHGIDX *bdchgidx1, SCIP_BDCHGIDX *bdchgidx2)
Definition var.c:18462
SCIP_BDCHGIDX * SCIPbdchginfoGetIdx(SCIP_BDCHGINFO *bdchginfo)
Definition var.c:18552
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition var.c:17360
int SCIPvarGetNLocksUpType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
Definition var.c:3353
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition var.c:17966
SCIP_PROP * SCIPbdchginfoGetInferProp(SCIP_BDCHGINFO *bdchginfo)
Definition var.c:18586
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition var.c:17748
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition var.c:17406
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition var.c:17910
int SCIPbdchginfoGetDepth(SCIP_BDCHGINFO *bdchginfo)
Definition var.c:18532
int SCIPbdchginfoGetInferInfo(SCIP_BDCHGINFO *bdchginfo)
Definition var.c:18597
int SCIPvarGetIndex(SCIP_VAR *var)
Definition var.c:17580
SCIP_CONS * SCIPbdchginfoGetInferCons(SCIP_BDCHGINFO *bdchginfo)
Definition var.c:18574
int SCIPbdchginfoGetPos(SCIP_BDCHGINFO *bdchginfo)
Definition var.c:18542
SCIP_Real SCIPgetVarUbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition scip_var.c:2128
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition var.c:17590
const char * SCIPvarGetName(SCIP_VAR *var)
Definition var.c:17241
SCIP_VAR * SCIPbdchginfoGetVar(SCIP_BDCHGINFO *bdchginfo)
Definition var.c:18502
int SCIPvarGetNVubs(SCIP_VAR *var)
Definition var.c:18134
SCIP_Real SCIPvarGetAvgSol(SCIP_VAR *var)
Definition var.c:14051
SCIP_Real SCIPbdchginfoGetOldbound(SCIP_BDCHGINFO *bdchginfo)
Definition var.c:18482
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition var.c:17432
SCIP_BOUNDTYPE SCIPbdchginfoGetInferBoundtype(SCIP_BDCHGINFO *bdchginfo)
Definition var.c:18609
SCIP_BDCHGINFO * SCIPvarGetBdchgInfo(SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition var.c:16511
SCIP_VAR ** SCIPvarGetMultaggrVars(SCIP_VAR *var)
Definition var.c:17680
SCIP_Bool SCIPbdchginfoIsTighter(SCIP_BDCHGINFO *bdchginfo1, SCIP_BDCHGINFO *bdchginfo2)
Definition var.c:18655
int SCIPvarGetMultaggrNVars(SCIP_VAR *var)
Definition var.c:17668
int SCIPvarGetNCliques(SCIP_VAR *var, SCIP_Bool varfixing)
Definition var.c:18252
SCIP_BOUNDCHGTYPE SCIPbdchginfoGetChgtype(SCIP_BDCHGINFO *bdchginfo)
Definition var.c:18512
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition var.c:17956
SCIP_VAR * SCIPbdchginfoGetInferVar(SCIP_BDCHGINFO *bdchginfo)
Definition var.c:18562
SCIP_Bool SCIPbdchginfoHasInferenceReason(SCIP_BDCHGINFO *bdchginfo)
Definition var.c:18641
SCIP_Bool SCIPvarIsRelaxationOnly(SCIP_VAR *var)
Definition var.c:17528
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition var.c:17900
SCIP_BDCHGINFO * SCIPvarGetBdchgInfoLb(SCIP_VAR *var, int pos)
Definition var.c:18300
SCIP_Real SCIPgetVarLbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition scip_var.c:1992
SCIP_BOUNDTYPE SCIPbdchginfoGetBoundtype(SCIP_BDCHGINFO *bdchginfo)
Definition var.c:18522
SCIP_Bool SCIPbdchgidxIsEarlierNonNull(SCIP_BDCHGIDX *bdchgidx1, SCIP_BDCHGIDX *bdchgidx2)
Definition var.c:18442
SCIP_Real SCIPbdchginfoGetNewbound(SCIP_BDCHGINFO *bdchginfo)
Definition var.c:18492
int SCIPvarGetNLocksDownType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
Definition var.c:3295
SCIP_BDCHGINFO * SCIPvarGetBdchgInfoUb(SCIP_VAR *var, int pos)
Definition var.c:18320
SCIP_Real * SCIPvarGetMultaggrScalars(SCIP_VAR *var)
Definition var.c:17692
SCIP_Bool SCIPvarIsInLP(SCIP_VAR *var)
Definition var.c:17622
void SCIPsortIntInt(int *intarray1, int *intarray2, int len)
void SCIPsortedvecInsertIntPtrReal(int *intarray, void **ptrarray, SCIP_Real *realarray, int keyval, void *field1val, SCIP_Real field2val, int *len, int *pos)
void SCIPsortIntIntInt(int *intarray1, int *intarray2, int *intarray3, int len)
void SCIPsortIntPtrReal(int *intarray, void **ptrarray, SCIP_Real *realarray, int len)
void SCIPsortLongPtrRealRealBool(SCIP_Longint *longarray, void **ptrarray, SCIP_Real *realarray, SCIP_Real *realarray2, SCIP_Bool *boolarray, int len)
void SCIPsortedvecDelPosIntPtrReal(int *intarray, void **ptrarray, SCIP_Real *realarray, int pos, int *len)
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition misc.c:10788
return SCIP_OKAY
SCIPfreeSol(scip, &heurdata->sol))
SCIPcreateSol(scip, &heurdata->sol, heur))
int c
int maxdepth
int depth
SCIP_Real objval
int r
assert(minobj< SCIPgetCutoffbound(scip))
int nvars
SCIP_VAR * var
static SCIP_VAR ** vars
int nbinvars
int nintvars
void SCIPhistoryIncNActiveConflicts(SCIP_HISTORY *history, SCIP_BRANCHDIR dir, SCIP_Real length)
Definition history.c:542
void SCIPhistoryScaleVSIDS(SCIP_HISTORY *history, SCIP_Real scalar)
Definition history.c:517
void SCIPhistoryIncVSIDS(SCIP_HISTORY *history, SCIP_BRANCHDIR dir, SCIP_Real weight)
Definition history.c:503
internal methods for branching and inference history
SCIP_Bool SCIPlpDivingObjChanged(SCIP_LP *lp)
Definition lp.c:17857
SCIP_LPSOLSTAT SCIPlpGetSolstat(SCIP_LP *lp)
Definition lp.c:13103
SCIP_LPI * SCIPlpGetLPI(SCIP_LP *lp)
Definition lp.c:17774
SCIP_Bool SCIPlpDiving(SCIP_LP *lp)
Definition lp.c:17847
int SCIPlpGetNCols(SCIP_LP *lp)
Definition lp.c:17575
SCIP_ROW ** SCIPlpGetRows(SCIP_LP *lp)
Definition lp.c:17612
static const SCIP_Real scalars[]
Definition lp.c:5743
int SCIPlpGetNRows(SCIP_LP *lp)
Definition lp.c:17622
SCIP_Real SCIPlpGetPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition lp.c:13302
internal methods for LP management
interface methods for specific LP solvers
static const char * paramname[]
Definition lpi_msk.c:5096
#define NULL
Definition lpi_spx1.cpp:161
#define BMSduplicateBlockMemoryArray(mem, ptr, source, num)
Definition memory.h:464
#define BMSfreeMemory(ptr)
Definition memory.h:147
#define BMSfreeBlockMemory(mem, ptr)
Definition memory.h:467
#define BMSallocBlockMemory(mem, ptr)
Definition memory.h:453
#define BMSreallocMemoryArray(ptr, num)
Definition memory.h:129
#define BMSfreeBlockMemoryArrayNull(mem, ptr, num)
Definition memory.h:470
#define BMSduplicateMemoryArray(ptr, source, num)
Definition memory.h:145
#define BMSclearMemory(ptr)
Definition memory.h:131
#define BMSallocBlockMemoryArray(mem, ptr, num)
Definition memory.h:456
#define BMScopyMemoryArray(ptr, source, num)
Definition memory.h:136
#define BMSreallocBlockMemoryArray(mem, ptr, oldnum, newnum)
Definition memory.h:460
#define BMSclearMemoryArray(ptr, num)
Definition memory.h:132
struct BMS_BlkMem BMS_BLKMEM
Definition memory.h:439
#define BMSfreeMemoryArrayNull(ptr)
Definition memory.h:150
#define BMSallocMemory(ptr)
Definition memory.h:120
real eps
SCIP_PARAMDATA * SCIPparamGetData(SCIP_PARAM *param)
Definition paramset.c:679
int SCIPparamGetInt(SCIP_PARAM *param)
Definition paramset.c:734
methods commonly used for presolving
const char * SCIPprobGetName(SCIP_PROB *prob)
Definition prob.c:2343
SCIP_Bool SCIPprobIsObjIntegral(SCIP_PROB *prob)
Definition prob.c:2297
int SCIPprobGetNVars(SCIP_PROB *prob)
Definition prob.c:2352
SCIP_RETCODE SCIPprobAddCons(SCIP_PROB *prob, SCIP_SET *set, SCIP_STAT *stat, SCIP_CONS *cons)
Definition prob.c:1286
SCIP_VAR ** SCIPprobGetVars(SCIP_PROB *prob)
Definition prob.c:2397
SCIP_Bool SCIPprobAllColsInLP(SCIP_PROB *prob, SCIP_SET *set, SCIP_LP *lp)
Definition prob.c:2309
SCIP_Bool SCIPprobIsTransformed(SCIP_PROB *prob)
Definition prob.c:2287
internal methods for storing and manipulating the main problem
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
internal methods for propagators
public methods for conflict analysis handlers
public methods for managing constraints
public methods for LP management
public methods for message output
#define SCIPerrorMessage
Definition pub_message.h:64
#define SCIPdebug(x)
Definition pub_message.h:93
#define SCIPdebugMessage
Definition pub_message.h:96
#define SCIPdebugPrintf
Definition pub_message.h:99
public data structures and miscellaneous methods
methods for sorting joint arrays of various types
public methods for handling parameter settings
public methods for propagators
public methods for branch and bound tree
public methods for problem variables
public methods for conflict handler plugins and conflict analysis
public methods for constraint handler plugins and constraints
public methods for memory management
public methods for solutions
public methods for SCIP variables
SCIP_Bool SCIPsetIsDualfeasZero(SCIP_SET *set, SCIP_Real val)
Definition set.c:6852
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:2947
SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6227
SCIP_Real SCIPsetFeasCeil(SCIP_SET *set, SCIP_Real val)
Definition set.c:6709
SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6597
SCIP_Bool SCIPsetIsFeasLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6575
SCIP_Bool SCIPsetIsFeasEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6531
SCIP_Bool SCIPsetIsPositive(SCIP_SET *set, SCIP_Real val)
Definition set.c:6256
SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6191
SCIP_Real SCIPsetFeasFloor(SCIP_SET *set, SCIP_Real val)
Definition set.c:6698
SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6155
SCIP_Bool SCIPsetIsFeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6553
SCIP_Real SCIPsetInfinity(SCIP_SET *set)
Definition set.c:5998
SCIP_Bool SCIPsetIsLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6173
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition set.c:6133
SCIP_Bool SCIPsetIsGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6209
SCIP_Bool SCIPsetIsIntegral(SCIP_SET *set, SCIP_Real val)
Definition set.c:6278
SCIP_Bool SCIPsetIsZero(SCIP_SET *set, SCIP_Real val)
Definition set.c:6245
SCIP_Real SCIPsetCutoffbounddelta(SCIP_SET *set)
Definition set.c:6098
SCIP_Bool SCIPsetIsFeasGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6619
void SCIPsetSortConflicthdlrs(SCIP_SET *set)
Definition set.c:3997
int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
Definition set.c:5712
SCIP_Bool SCIPsetIsNegative(SCIP_SET *set, SCIP_Real val)
Definition set.c:6267
internal methods for global SCIP settings
#define SCIPsetFreeBufferArray(set, ptr)
Definition set.h:1741
#define SCIPsetFreeCleanBufferArray(set, ptr)
Definition set.h:1748
#define SCIPsetDebugMsgPrint
Definition set.h:1771
#define SCIPsetAllocBufferArray(set, ptr, num)
Definition set.h:1734
#define SCIPsetFreeBuffer(set, ptr)
Definition set.h:1739
#define SCIPsetAllocCleanBufferArray(set, ptr, num)
Definition set.h:1745
#define SCIPsetDebugMsg
Definition set.h:1770
#define SCIPsetAllocBuffer(set, ptr)
Definition set.h:1732
#define SCIPsetReallocBufferArray(set, ptr, num)
Definition set.h:1738
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
internal methods for storing primal CIP solutions
SCIP_BDCHGIDX bdchgidx
Definition struct_var.h:121
SCIP_Real newbound
Definition struct_var.h:118
unsigned int boundtype
Definition struct_var.h:124
SCIP_VAR * var
Definition struct_var.h:119
unsigned int redundant
Definition struct_var.h:126
SCIP_Real oldbound
Definition struct_var.h:117
SCIP_Real lb
Definition struct_lp.h:138
SCIP_Real ub
Definition struct_lp.h:139
SCIP_Real sbdown
Definition struct_lp.h:153
SCIP_Real sbup
Definition struct_lp.h:154
unsigned int basisstatus
Definition struct_lp.h:179
SCIP_Real redcost
Definition struct_lp.h:149
unsigned int sbupvalid
Definition struct_lp.h:190
SCIP_Real primsol
Definition struct_lp.h:148
int lpipos
Definition struct_lp.h:173
unsigned int sbdownvalid
Definition struct_lp.h:188
unsigned int hasrelaxonlyvar
SCIP_BDCHGINFO ** bdchginfos
unsigned int repropagate
SCIP_Real * relaxedbds
SCIP_CONFTYPE conflicttype
unsigned int usescutoffbound
SCIP_Longint ninflpiterations
SCIP_Real * conflictsetscores
SCIP_Longint ndualproofsbndglobal
SCIP_PROOFSET * proofset
SCIP_Longint ndualproofsinfsuccess
SCIP_Longint nappliedglbconss
SCIP_Longint nsbiterations
SCIP_Longint npropconfconss
SCIP_Longint ninflpconfconss
SCIP_Longint npseudoreconvliterals
SCIP_CLOCK * dIBclock
SCIP_Longint npseudosuccess
SCIP_Longint ninflpconfliterals
SCIP_Longint nsbsuccess
SCIP_CLOCK * propanalyzetime
SCIP_Longint nboundlpconfliterals
SCIP_Longint nsbcalls
SCIP_PROOFSET ** proofsets
SCIP_Longint ndualproofsinflocal
SCIP_Longint npseudoconfconss
SCIP_Longint nboundlpcalls
SCIP_PQUEUE * forcedbdchgqueue
SCIP_Longint nappliedglbliterals
SCIP_Longint nboundlpreconvliterals
SCIP_CONFLICTSET ** conflictsets
SCIP_Longint npseudocalls
SCIP_Longint ninflpreconvconss
SCIP_Longint nglbchgbds
SCIP_Longint dualproofsbndnnonzeros
SCIP_Longint ninflpcalls
SCIP_CLOCK * pseudoanalyzetime
SCIP_Longint nsbconfliterals
SCIP_CLOCK * inflpanalyzetime
SCIP_Longint nboundlpiterations
SCIP_Longint npseudoreconvconss
SCIP_Longint npseudoconfliterals
SCIP_Longint nlocchgbds
SCIP_Longint nsbreconvconss
SCIP_PQUEUE * bdchgqueue
SCIP_Longint nsbreconvliterals
SCIP_Longint npropsuccess
SCIP_Longint ndualproofsinfglobal
SCIP_Longint nappliedlocconss
SCIP_Longint nsbconfconss
SCIP_Longint ninflpsuccess
SCIP_CLOCK * sbanalyzetime
SCIP_Longint npropcalls
SCIP_Longint nboundlpreconvconss
SCIP_Longint ndualproofsbndsuccess
SCIP_Longint dualproofsinfnnonzeros
SCIP_Longint nboundlpconfconss
SCIP_Longint npropreconvliterals
SCIP_CLOCK * boundlpanalyzetime
SCIP_Longint nboundlpsuccess
SCIP_BDCHGINFO ** tmpbdchginfos
SCIP_Longint npropconfliterals
SCIP_Longint ninflpreconvliterals
SCIP_CONFLICTSET * conflictset
SCIP_Longint ndualproofsbndlocal
SCIP_Longint nappliedlocliterals
SCIP_Longint npropreconvconss
SCIP_BOUNDCHG * boundchgs
Definition struct_var.h:134
unsigned int nboundchgs
Definition struct_var.h:132
SCIP_Bool dualchecked
Definition struct_lp.h:123
SCIP_Bool solisbasic
Definition struct_lp.h:124
SCIP_Bool dualfeasible
Definition struct_lp.h:122
SCIP_Bool primalfeasible
Definition struct_lp.h:120
SCIP_Bool primalchecked
Definition struct_lp.h:121
SCIP_Real lpobjval
Definition struct_lp.h:119
SCIP_Bool lpissolved
Definition struct_lp.h:125
SCIP_LPSOLSTAT lpsolstat
Definition struct_lp.h:118
SCIP_ROW ** rows
Definition struct_lp.h:303
SCIP_ROW ** lpirows
Definition struct_lp.h:298
int lpiitlim
Definition struct_lp.h:345
SCIP_Bool strongbranching
Definition struct_lp.h:377
SCIP_Bool primalfeasible
Definition struct_lp.h:368
SCIP_COL ** cols
Definition struct_lp.h:301
int ncols
Definition struct_lp.h:328
SCIP_Real cutoffbound
Definition struct_lp.h:284
SCIP_Bool dualfeasible
Definition struct_lp.h:370
SCIP_Bool solisbasic
Definition struct_lp.h:372
int nrows
Definition struct_lp.h:334
SCIP_Bool primalchecked
Definition struct_lp.h:369
SCIP_LPSOLSTAT lpsolstat
Definition struct_lp.h:353
int nlpicols
Definition struct_lp.h:317
SCIP_Real lpobjval
Definition struct_lp.h:271
int nlpirows
Definition struct_lp.h:320
SCIP_Bool solved
Definition struct_lp.h:367
SCIP_Bool dualchecked
Definition struct_lp.h:371
SCIP_Bool diving
Definition struct_lp.h:380
SCIP_LPI * lpi
Definition struct_lp.h:296
SCIP_Bool flushed
Definition struct_lp.h:366
SCIP_Real lpiobjlim
Definition struct_lp.h:286
SCIP_DOMCHG * domchg
unsigned int depth
int startnconss
Definition struct_prob.h:85
int ncontvars
Definition struct_prob.h:74
SCIP_VAR ** vars
Definition struct_prob.h:64
SCIP_Real * vals
SCIP_CONFTYPE conflicttype
unsigned int basisstatus
Definition struct_lp.h:250
SCIP_Real rhs
Definition struct_lp.h:205
SCIP_Real dualfarkas
Definition struct_lp.h:215
SCIP_Real * vals
Definition struct_lp.h:229
unsigned int local
Definition struct_lp.h:259
SCIP_Real lhs
Definition struct_lp.h:204
SCIP_COL ** cols
Definition struct_lp.h:227
SCIP_Real constant
Definition struct_lp.h:203
SCIP_Real activity
Definition struct_lp.h:214
SCIP_Real dualsol
Definition struct_lp.h:213
int lpdepth
Definition struct_lp.h:241
SCIP_Longint nnodes
Definition struct_stat.h:82
SCIP_Real avgnnz
SCIP_Longint nconflictlps
SCIP_HISTORY * glbhistory
SCIP_VISUAL * visual
SCIP_Real vsidsweight
SCIP_Longint lastconflictnode
SCIP_HISTORY * glbhistorycrun
SCIP_Longint nconflictlpiterations
Definition struct_stat.h:79
SCIP_CLOCK * conflictlptime
SCIP_NODE * root
SCIP_NODE ** path
int nubchginfos
Definition struct_var.h:269
SCIP_BDCHGINFO * lbchginfos
Definition struct_var.h:248
int conflictubcount
Definition struct_var.h:271
SCIP_Real conflictrelaxedub
Definition struct_var.h:222
SCIP_BDCHGINFO * ubchginfos
Definition struct_var.h:249
SCIP_Real conflictub
Definition struct_var.h:220
SCIP_Real conflictrelaxedlb
Definition struct_var.h:221
int nlbchginfos
Definition struct_var.h:267
SCIP_Real conflictlb
Definition struct_var.h:219
int conflictlbcount
Definition struct_var.h:270
datastructures for conflict analysis
data structures for LP management
datastructures for storing and manipulating the main problem
datastructures for global SCIP settings
datastructures for problem statistics
data structures for branch and bound tree
datastructures for problem variables
#define MAX(x, y)
Definition tclique_def.h:92
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
int SCIPtreeGetFocusDepth(SCIP_TREE *tree)
Definition tree.c:8329
void SCIPnodePropagateAgain(SCIP_NODE *node, SCIP_SET *set, SCIP_STAT *stat, SCIP_TREE *tree)
Definition tree.c:1248
SCIP_NODE * SCIPtreeGetRootNode(SCIP_TREE *tree)
Definition tree.c:8454
int SCIPtreeGetEffectiveRootDepth(SCIP_TREE *tree)
Definition tree.c:8443
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
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
int SCIPtreeGetCurrentDepth(SCIP_TREE *tree)
Definition tree.c:8404
internal methods for branch and bound tree
@ SCIP_CLOCKTYPE_DEFAULT
Definition type_clock.h:43
#define SCIP_DECL_CONFLICTEXIT(x)
#define SCIP_DECL_CONFLICTCOPY(x)
#define SCIP_DECL_CONFLICTEXEC(x)
#define SCIP_DECL_CONFLICTINITSOL(x)
#define SCIP_DECL_CONFLICTFREE(x)
@ SCIP_CONFTYPE_ALTINFPROOF
@ SCIP_CONFTYPE_BNDEXCEEDING
@ SCIP_CONFTYPE_PROPAGATION
@ SCIP_CONFTYPE_ALTBNDPROOF
@ SCIP_CONFTYPE_INFEASLP
@ SCIP_CONFTYPE_UNKNOWN
#define SCIP_DECL_CONFLICTINIT(x)
enum SCIP_ConflictType SCIP_CONFTYPE
struct SCIP_ConflicthdlrData SCIP_CONFLICTHDLRDATA
#define SCIP_DECL_CONFLICTEXITSOL(x)
@ SCIP_BRANCHDIR_DOWNWARDS
@ SCIP_BRANCHDIR_UPWARDS
enum SCIP_BranchDir SCIP_BRANCHDIR
@ SCIP_BOUNDTYPE_UPPER
Definition type_lp.h:57
@ SCIP_BOUNDTYPE_LOWER
Definition type_lp.h:56
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition type_lp.h:59
@ SCIP_LPSOLSTAT_NOTSOLVED
Definition type_lp.h:42
@ SCIP_LPSOLSTAT_OPTIMAL
Definition type_lp.h:43
@ SCIP_LPSOLSTAT_INFEASIBLE
Definition type_lp.h:44
@ SCIP_LPSOLSTAT_OBJLIMIT
Definition type_lp.h:46
@ SCIP_LPPAR_LPITLIM
Definition type_lpi.h:60
@ SCIP_LPPAR_OBJLIM
Definition type_lpi.h:59
#define SCIP_DECL_SORTPTRCOMP(x)
Definition type_misc.h:188
struct SCIP_ParamData SCIP_PARAMDATA
#define SCIP_DECL_PARAMCHGD(x)
@ SCIP_DIDNOTRUN
Definition type_result.h:42
@ SCIP_DIDNOTFIND
Definition type_result.h:44
@ SCIP_CONSADDED
Definition type_result.h:52
@ SCIP_SUCCESS
Definition type_result.h:58
enum SCIP_Result SCIP_RESULT
Definition type_result.h:61
@ SCIP_LPERROR
@ SCIP_INVALIDRESULT
@ SCIP_INVALIDDATA
@ SCIP_WRITEERROR
@ SCIP_INVALIDCALL
enum SCIP_Retcode SCIP_RETCODE
@ SCIP_VARTYPE_INTEGER
Definition type_var.h:63
@ SCIP_VARTYPE_CONTINUOUS
Definition type_var.h:71
@ SCIP_VARTYPE_IMPLINT
Definition type_var.h:64
@ SCIP_VARTYPE_BINARY
Definition type_var.h:62
@ SCIP_BOUNDCHGTYPE_PROPINFER
Definition type_var.h:89
@ SCIP_BOUNDCHGTYPE_BRANCHING
Definition type_var.h:87
@ SCIP_BOUNDCHGTYPE_CONSINFER
Definition type_var.h:88
@ SCIP_VARSTATUS_FIXED
Definition type_var.h:52
@ SCIP_VARSTATUS_COLUMN
Definition type_var.h:51
@ SCIP_VARSTATUS_MULTAGGR
Definition type_var.h:54
@ SCIP_VARSTATUS_NEGATED
Definition type_var.h:55
@ SCIP_VARSTATUS_AGGREGATED
Definition type_var.h:53
@ SCIP_LOCKTYPE_MODEL
Definition type_var.h:97
enum SCIP_Vartype SCIP_VARTYPE
Definition type_var.h:73
SCIP_DOMCHGBOUND domchgbound
Definition struct_var.h:162
void SCIPbdchginfoFree(SCIP_BDCHGINFO **bdchginfo, BMS_BLKMEM *blkmem)
Definition var.c:16385
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:15040
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:15176
void SCIPvarAdjustLb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *lb)
Definition var.c:6506
SCIP_Real SCIPvarGetLbLP(SCIP_VAR *var, SCIP_SET *set)
Definition var.c:12921
void SCIPvarAdjustBd(SCIP_VAR *var, SCIP_SET *set, SCIP_BOUNDTYPE boundtype, SCIP_Real *bd)
Definition var.c:6540
SCIP_RETCODE SCIPvarScaleVSIDS(SCIP_VAR *var, SCIP_Real scalar)
Definition var.c:15126
SCIP_Real SCIPvarGetUbLP(SCIP_VAR *var, SCIP_SET *set)
Definition var.c:12991
int SCIPbdchgidxGetPos(SCIP_BDCHGIDX *bdchgidx)
Definition var.c:18432
SCIP_RETCODE SCIPbdchginfoCreate(SCIP_BDCHGINFO **bdchginfo, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_Real oldbound, SCIP_Real newbound)
Definition var.c:16355
SCIP_RETCODE SCIPvarGetProbvarSum(SCIP_VAR **var, SCIP_SET *set, SCIP_Real *scalar, SCIP_Real *constant)
Definition var.c:12636
void SCIPvarAdjustUb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *ub)
Definition var.c:6523
SCIP_Real SCIPbdchginfoGetRelaxedBound(SCIP_BDCHGINFO *bdchginfo)
Definition var.c:18621
internal methods for problem variables
void SCIPvisualFoundConflict(SCIP_VISUAL *visual, SCIP_STAT *stat, SCIP_NODE *node)
Definition visual.c:612
methods for creating output for visualization tools (VBC, BAK)