Scippy

SCIP

Solving Constraint Integer Programs

conflict_general.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-2025 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
25/**@file conflict_general.c
26 * @ingroup OTHER_CFILES
27 * @brief methods and datastructures for conflict analysis
28 * @author Tobias Achterberg
29 * @author Timo Berthold
30 * @author Stefan Heinz
31 * @author Marc Pfetsch
32 * @author Michael Winkler
33 * @author Jakob Witzig
34 *
35 * SCIP contains two kinds of conflict analysis:
36 * - In graph based conflict analysis, the graph consisting of derived
37 * is analysed. Code and documentation is available in conflict_graphanalysis.h
38 * - In dual proof analysis, an infeasible LP relaxation is analysed.
39 * Using the dual solution, a valid constraint is derived that is violated
40 * by all values in the domain. This constraint is added to the problem
41 * and can then be used for domain propagation.
42 * Code is available in conflict_dualproofanalysis.h
43 * This file contains the methods that are shared by both kinds of conflict analysis.
44 */
45
46/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
47
48#include "lpi/lpi.h"
49#include "scip/clock.h"
50#include "scip/conflict.h"
51#include "scip/conflictstore.h"
52#include "scip/cons.h"
53#include "scip/cons_linear.h"
54#include "scip/cuts.h"
55#include "scip/history.h"
56#include "scip/lp.h"
57#include "scip/presolve.h"
58#include "scip/prob.h"
59#include "scip/prop.h"
60#include "scip/pub_conflict.h"
61#include "scip/pub_cons.h"
62#include "scip/pub_lp.h"
63#include "scip/pub_message.h"
64#include "scip/pub_misc.h"
65#include "scip/pub_misc_sort.h"
66#include "scip/pub_paramset.h"
67#include "scip/pub_prop.h"
68#include "scip/pub_tree.h"
69#include "scip/pub_var.h"
70#include "scip/scip_conflict.h"
71#include "scip/scip_cons.h"
72#include "scip/scip_mem.h"
73#include "scip/scip_sol.h"
74#include "scip/scip_var.h"
75#include "scip/set.h"
76#include "scip/sol.h"
78#include "scip/struct_lp.h"
79#include "scip/struct_prob.h"
80#include "scip/struct_set.h"
81#include "scip/struct_stat.h"
82#include "scip/struct_tree.h"
83#include "scip/struct_var.h"
84#include "scip/tree.h"
85#include "scip/var.h"
86#include "scip/visual.h"
87#include <string.h>
88#if defined(_WIN32) || defined(_WIN64)
89#else
90#include <strings.h> /*lint --e{766}*/
91#endif
92
93/* because calculations might cancel out some values, we stop the infeasibility analysis if a value is bigger than
94 * 2^53 = 9007199254740992
95 */
96#define NUMSTOP 9007199254740992.0
97/* because row violations might be magnified, we stop the infeasibility analysis if a dual weight is bigger than
98 * 10^7 = 10000000
99 */
100#define SOLSTOP 10000000.0
101
102/** returns the current number of conflict sets in the conflict set storage */
104 SCIP_CONFLICT* conflict /**< conflict analysis data */
105 )
106{
107 assert(conflict != NULL);
108
109 return conflict->nconflictsets;
110}
111
112/** returns the total number of conflict constraints that were added to the problem */
114 SCIP_CONFLICT* conflict /**< conflict analysis data */
115 )
116{
117 assert(conflict != NULL);
118
119 return conflict->nappliedglbconss + conflict->nappliedlocconss;
120}
121
122/** returns the total number of literals in conflict constraints that were added to the problem */
124 SCIP_CONFLICT* conflict /**< conflict analysis data */
125 )
126{
127 assert(conflict != NULL);
128
129 return conflict->nappliedglbliterals + conflict->nappliedlocliterals;
130}
131
132/** returns the total number of global bound changes applied by the conflict analysis */
134 SCIP_CONFLICT* conflict /**< conflict analysis data */
135 )
136{
137 assert(conflict != NULL);
138
139 return conflict->nglbchgbds;
140}
141
142/** returns the total number of conflict constraints that were added globally to the problem */
144 SCIP_CONFLICT* conflict /**< conflict analysis data */
145 )
146{
147 assert(conflict != NULL);
148
149 return conflict->nappliedglbconss;
150}
151
152/** returns the total number of literals in conflict constraints that were added globally to the problem */
154 SCIP_CONFLICT* conflict /**< conflict analysis data */
155 )
156{
157 assert(conflict != NULL);
158
159 return conflict->nappliedglbliterals;
160}
161
162/** returns the total number of local bound changes applied by the conflict analysis */
164 SCIP_CONFLICT* conflict /**< conflict analysis data */
165 )
166{
167 assert(conflict != NULL);
168
169 return conflict->nlocchgbds;
170}
171
172/** returns the total number of conflict constraints that were added locally to the problem */
174 SCIP_CONFLICT* conflict /**< conflict analysis data */
175 )
176{
177 assert(conflict != NULL);
178
179 return conflict->nappliedlocconss;
180}
181
182/** returns the total number of literals in conflict constraints that were added locally to the problem */
184 SCIP_CONFLICT* conflict /**< conflict analysis data */
185 )
186{
187 assert(conflict != NULL);
188
189 return conflict->nappliedlocliterals;
190}
191
192/** compares two conflict set entries, such that bound changes inferred later are
193 * ordered prior to ones that were inferred earlier
194 */
195static
196SCIP_DECL_SORTPTRCOMP(conflictBdchginfoComp)
197{ /*lint --e{715}*/
198 SCIP_BDCHGINFO* bdchginfo1;
199 SCIP_BDCHGINFO* bdchginfo2;
200
201 bdchginfo1 = (SCIP_BDCHGINFO*)elem1;
202 bdchginfo2 = (SCIP_BDCHGINFO*)elem2;
203 assert(bdchginfo1 != NULL);
204 assert(bdchginfo2 != NULL);
205 assert(!SCIPbdchginfoIsRedundant(bdchginfo1));
206 assert(!SCIPbdchginfoIsRedundant(bdchginfo2));
207
208 if( bdchginfo1 == bdchginfo2 )
209 return 0;
210
212 return -1;
213 else
214 return +1;
215}
216
217/** enables or disables all clocks of \p conflict, depending on the value of the flag */
219 SCIP_CONFLICT* conflict, /**< the conflict analysis data for which all clocks should be enabled or disabled */
220 SCIP_Bool enable /**< should the clocks of the conflict analysis data be enabled? */
221 )
222{
223 assert(conflict != NULL);
224
226 SCIPclockEnableOrDisable(conflict->dIBclock, enable);
228 SCIPclockEnableOrDisable(conflict->propanalyzetime, enable);
230 SCIPclockEnableOrDisable(conflict->sbanalyzetime, enable);
231}
232
233/** creates conflict analysis data for propagation conflicts */
235 SCIP_CONFLICT** conflict, /**< pointer to conflict analysis data */
236 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
237 SCIP_SET* set /**< global SCIP settings */
238 )
239{
240 assert(conflict != NULL);
241
242 SCIP_ALLOC( BMSallocMemory(conflict) );
243
244 SCIP_CALL( SCIPclockCreate(&(*conflict)->dIBclock, SCIP_CLOCKTYPE_DEFAULT) );
245 SCIP_CALL( SCIPclockCreate(&(*conflict)->propanalyzetime, SCIP_CLOCKTYPE_DEFAULT) );
246 SCIP_CALL( SCIPclockCreate(&(*conflict)->inflpanalyzetime, SCIP_CLOCKTYPE_DEFAULT) );
247 SCIP_CALL( SCIPclockCreate(&(*conflict)->boundlpanalyzetime, SCIP_CLOCKTYPE_DEFAULT) );
248 SCIP_CALL( SCIPclockCreate(&(*conflict)->sbanalyzetime, SCIP_CLOCKTYPE_DEFAULT) );
249 SCIP_CALL( SCIPclockCreate(&(*conflict)->pseudoanalyzetime, SCIP_CLOCKTYPE_DEFAULT) );
250
251 /* enable or disable timing depending on the parameter statistic timing */
252 SCIPconflictEnableOrDisableClocks((*conflict), set->time_statistictiming);
253
254 SCIP_CALL( SCIPpqueueCreate(&(*conflict)->bdchgqueue, set->mem_arraygrowinit, set->mem_arraygrowfac,
255 conflictBdchginfoComp, NULL) );
256 SCIP_CALL( SCIPpqueueCreate(&(*conflict)->forcedbdchgqueue, set->mem_arraygrowinit, set->mem_arraygrowfac,
257 conflictBdchginfoComp, NULL) );
258 SCIP_CALL( SCIPconflictsetCreate(&(*conflict)->conflictset, blkmem) );
259 (*conflict)->conflictsets = NULL;
260 (*conflict)->conflictsetscores = NULL;
261 (*conflict)->tmpbdchginfos = NULL;
262 (*conflict)->conflictsetssize = 0;
263 (*conflict)->nconflictsets = 0;
264 (*conflict)->proofsets = NULL;
265 (*conflict)->proofsetssize = 0;
266 (*conflict)->nproofsets = 0;
267 (*conflict)->tmpbdchginfossize = 0;
268 (*conflict)->ntmpbdchginfos = 0;
269 (*conflict)->count = 0;
270 (*conflict)->nglbchgbds = 0;
271 (*conflict)->nappliedglbconss = 0;
272 (*conflict)->nappliedglbliterals = 0;
273 (*conflict)->nlocchgbds = 0;
274 (*conflict)->nappliedlocconss = 0;
275 (*conflict)->nappliedlocliterals = 0;
276 (*conflict)->npropcalls = 0;
277 (*conflict)->npropsuccess = 0;
278 (*conflict)->npropconfconss = 0;
279 (*conflict)->npropconfliterals = 0;
280 (*conflict)->npropreconvconss = 0;
281 (*conflict)->npropreconvliterals = 0;
282 (*conflict)->ninflpcalls = 0;
283 (*conflict)->ninflpsuccess = 0;
284 (*conflict)->ninflpconfconss = 0;
285 (*conflict)->ninflpconfliterals = 0;
286 (*conflict)->ninflpreconvconss = 0;
287 (*conflict)->ninflpreconvliterals = 0;
288 (*conflict)->ninflpiterations = 0;
289 (*conflict)->nboundlpcalls = 0;
290 (*conflict)->nboundlpsuccess = 0;
291 (*conflict)->nboundlpconfconss = 0;
292 (*conflict)->nboundlpconfliterals = 0;
293 (*conflict)->nboundlpreconvconss = 0;
294 (*conflict)->nboundlpreconvliterals = 0;
295 (*conflict)->nboundlpiterations = 0;
296 (*conflict)->nsbcalls = 0;
297 (*conflict)->nsbsuccess = 0;
298 (*conflict)->nsbconfconss = 0;
299 (*conflict)->nsbconfliterals = 0;
300 (*conflict)->nsbreconvconss = 0;
301 (*conflict)->nsbreconvliterals = 0;
302 (*conflict)->nsbiterations = 0;
303 (*conflict)->npseudocalls = 0;
304 (*conflict)->npseudosuccess = 0;
305 (*conflict)->npseudoconfconss = 0;
306 (*conflict)->npseudoconfliterals = 0;
307 (*conflict)->npseudoreconvconss = 0;
308 (*conflict)->npseudoreconvliterals = 0;
309 (*conflict)->ndualproofsinfglobal = 0;
310 (*conflict)->ndualproofsinflocal = 0;
311 (*conflict)->ndualproofsinfsuccess = 0;
312 (*conflict)->dualproofsinfnnonzeros = 0;
313 (*conflict)->ndualproofsbndglobal = 0;
314 (*conflict)->ndualproofsbndlocal = 0;
315 (*conflict)->ndualproofsbndsuccess = 0;
316 (*conflict)->dualproofsbndnnonzeros = 0;
317
318 SCIP_CALL( SCIPconflictInitProofset((*conflict), blkmem) );
319
320 return SCIP_OKAY;
321}
322
323/** frees conflict analysis data for propagation conflicts */
325 SCIP_CONFLICT** conflict, /**< pointer to conflict analysis data */
326 BMS_BLKMEM* blkmem /**< block memory of transformed problem */
327 )
328{
329 assert(conflict != NULL);
330 assert(*conflict != NULL);
331 assert((*conflict)->nconflictsets == 0);
332 assert((*conflict)->ntmpbdchginfos == 0);
333
334#if defined(SCIP_CONFGRAPH) || defined(SCIP_CONFGRAPH_DOT)
335 confgraphFree();
336#endif
337
338 SCIPclockFree(&(*conflict)->dIBclock);
339 SCIPclockFree(&(*conflict)->propanalyzetime);
340 SCIPclockFree(&(*conflict)->inflpanalyzetime);
341 SCIPclockFree(&(*conflict)->boundlpanalyzetime);
342 SCIPclockFree(&(*conflict)->sbanalyzetime);
343 SCIPclockFree(&(*conflict)->pseudoanalyzetime);
344 SCIPpqueueFree(&(*conflict)->bdchgqueue);
345 SCIPpqueueFree(&(*conflict)->forcedbdchgqueue);
346 SCIPconflictsetFree(&(*conflict)->conflictset, blkmem);
347 SCIPproofsetFree(&(*conflict)->proofset, blkmem);
348
349 BMSfreeMemoryArrayNull(&(*conflict)->conflictsets);
350 BMSfreeMemoryArrayNull(&(*conflict)->conflictsetscores);
351 BMSfreeMemoryArrayNull(&(*conflict)->proofsets);
352 BMSfreeMemoryArrayNull(&(*conflict)->tmpbdchginfos);
353 BMSfreeMemory(conflict);
354
355 return SCIP_OKAY;
356}
357
358/** returns the conflict lower bound if the variable is present in the current conflict set; otherwise the global lower
359 * bound
360 */
362 SCIP_CONFLICT* conflict, /**< conflict analysis data */
363 SCIP_VAR* var /**< problem variable */
364 )
365{
366 if( var->conflictlbcount == conflict->count )
367 {
368 assert(EPSGE(var->conflictlb, var->conflictrelaxedlb, 1e-09));
369 return var->conflictrelaxedlb;
370 }
371
372 return SCIPvarGetLbGlobal(var);
373}
374
375/** returns the conflict upper bound if the variable is present in the current conflict set; otherwise the global upper
376 * bound
377 */
379 SCIP_CONFLICT* conflict, /**< conflict analysis data */
380 SCIP_VAR* var /**< problem variable */
381 )
382{
383 if( var->conflictubcount == conflict->count )
384 {
385 assert(EPSLE(var->conflictub, var->conflictrelaxedub, 1e-09));
386 return var->conflictrelaxedub;
387 }
388
389 return SCIPvarGetUbGlobal(var);
390}
391
392/** gets time in seconds used for preprocessing global conflict constraint before appliance */
394 SCIP_CONFLICT* conflict /**< conflict analysis data */
395 )
396{
397 assert(conflict != NULL);
398
399 return SCIPclockGetTime(conflict->dIBclock);
400}
401
402/** gets time in seconds used for analyzing propagation conflicts */
404 SCIP_CONFLICT* conflict /**< conflict analysis data */
405 )
406{
407 assert(conflict != NULL);
408
409 return SCIPclockGetTime(conflict->propanalyzetime);
410}
411
412/** gets number of calls to propagation conflict analysis */
414 SCIP_CONFLICT* conflict /**< conflict analysis data */
415 )
416{
417 assert(conflict != NULL);
418
419 return conflict->npropcalls;
420}
421
422/** gets number of calls to propagation conflict analysis that yield at least one conflict constraint */
424 SCIP_CONFLICT* conflict /**< conflict analysis data */
425 )
426{
427 assert(conflict != NULL);
428
429 return conflict->npropsuccess;
430}
431
432/** gets number of conflict constraints detected in propagation conflict analysis */
434 SCIP_CONFLICT* conflict /**< conflict analysis data */
435 )
436{
437 assert(conflict != NULL);
438
439 return conflict->npropconfconss;
440}
441
442/** gets total number of literals in conflict constraints created in propagation conflict analysis */
444 SCIP_CONFLICT* conflict /**< conflict analysis data */
445 )
446{
447 assert(conflict != NULL);
448
449 return conflict->npropconfliterals;
450}
451
452/** gets number of reconvergence constraints detected in propagation conflict analysis */
454 SCIP_CONFLICT* conflict /**< conflict analysis data */
455 )
456{
457 assert(conflict != NULL);
458
459 return conflict->npropreconvconss;
460}
461
462/** gets total number of literals in reconvergence constraints created in propagation conflict analysis */
464 SCIP_CONFLICT* conflict /**< conflict analysis data */
465 )
466{
467 assert(conflict != NULL);
468
469 return conflict->npropreconvliterals;
470}
471
472/** gets time in seconds used for analyzing infeasible LP conflicts */
474 SCIP_CONFLICT* conflict /**< conflict analysis data */
475 )
476{
477 assert(conflict != NULL);
478
479 return SCIPclockGetTime(conflict->inflpanalyzetime);
480}
481
482/** gets number of calls to infeasible LP conflict analysis */
484 SCIP_CONFLICT* conflict /**< conflict analysis data */
485 )
486{
487 assert(conflict != NULL);
488
489 return conflict->ninflpcalls;
490}
491
492/** gets number of calls to infeasible LP conflict analysis that yield at least one conflict constraint */
494 SCIP_CONFLICT* conflict /**< conflict analysis data */
495 )
496{
497 assert(conflict != NULL);
498
499 return conflict->ninflpsuccess;
500}
501
502/** gets number of conflict constraints detected in infeasible LP conflict analysis */
504 SCIP_CONFLICT* conflict /**< conflict analysis data */
505 )
506{
507 assert(conflict != NULL);
508
509 return conflict->ninflpconfconss;
510}
511
512/** gets total number of literals in conflict constraints created in infeasible LP conflict analysis */
514 SCIP_CONFLICT* conflict /**< conflict analysis data */
515 )
516{
517 assert(conflict != NULL);
518
519 return conflict->ninflpconfliterals;
520}
521
522/** gets number of reconvergence constraints detected in infeasible LP conflict analysis */
524 SCIP_CONFLICT* conflict /**< conflict analysis data */
525 )
526{
527 assert(conflict != NULL);
528
529 return conflict->ninflpreconvconss;
530}
531
532/** gets total number of literals in reconvergence constraints created in infeasible LP conflict analysis */
534 SCIP_CONFLICT* conflict /**< conflict analysis data */
535 )
536{
537 assert(conflict != NULL);
538
539 return conflict->ninflpreconvliterals;
540}
541
542/** gets number of LP iterations in infeasible LP conflict analysis */
544 SCIP_CONFLICT* conflict /**< conflict analysis data */
545 )
546{
547 assert(conflict != NULL);
548
549 return conflict->ninflpiterations;
550}
551
552/** gets time in seconds used for analyzing bound exceeding LP conflicts */
554 SCIP_CONFLICT* conflict /**< conflict analysis data */
555 )
556{
557 assert(conflict != NULL);
558
559 return SCIPclockGetTime(conflict->boundlpanalyzetime);
560}
561
562/** gets number of calls to bound exceeding LP conflict analysis */
564 SCIP_CONFLICT* conflict /**< conflict analysis data */
565 )
566{
567 assert(conflict != NULL);
568
569 return conflict->nboundlpcalls;
570}
571
572/** gets number of calls to bound exceeding LP conflict analysis that yield at least one conflict constraint */
574 SCIP_CONFLICT* conflict /**< conflict analysis data */
575 )
576{
577 assert(conflict != NULL);
578
579 return conflict->nboundlpsuccess;
580}
581
582/** gets number of conflict constraints detected in bound exceeding LP conflict analysis */
584 SCIP_CONFLICT* conflict /**< conflict analysis data */
585 )
586{
587 assert(conflict != NULL);
588
589 return conflict->nboundlpconfconss;
590}
591
592/** gets total number of literals in conflict constraints created in bound exceeding LP conflict analysis */
594 SCIP_CONFLICT* conflict /**< conflict analysis data */
595 )
596{
597 assert(conflict != NULL);
598
599 return conflict->nboundlpconfliterals;
600}
601
602/** gets number of reconvergence constraints detected in bound exceeding LP conflict analysis */
604 SCIP_CONFLICT* conflict /**< conflict analysis data */
605 )
606{
607 assert(conflict != NULL);
608
609 return conflict->nboundlpreconvconss;
610}
611
612/** gets total number of literals in reconvergence constraints created in bound exceeding LP conflict analysis */
614 SCIP_CONFLICT* conflict /**< conflict analysis data */
615 )
616{
617 assert(conflict != NULL);
618
619 return conflict->nboundlpreconvliterals;
620}
621
622/** gets number of LP iterations in bound exceeding LP conflict analysis */
624 SCIP_CONFLICT* conflict /**< conflict analysis data */
625 )
626{
627 assert(conflict != NULL);
628
629 return conflict->nboundlpiterations;
630}
631
632/** gets time in seconds used for analyzing infeasible strong branching conflicts */
634 SCIP_CONFLICT* conflict /**< conflict analysis data */
635 )
636{
637 assert(conflict != NULL);
638
639 return SCIPclockGetTime(conflict->sbanalyzetime);
640}
641
642/** gets number of successful calls to dual proof analysis derived from infeasible LPs */
644 SCIP_CONFLICT* conflict /**< conflict analysis data */
645 )
646{
647 assert(conflict != NULL);
648
649 return conflict->ndualproofsinfsuccess;
650}
651
652/** gets number of globally valid dual proof constraints derived from infeasible LPs */
654 SCIP_CONFLICT* conflict /**< conflict analysis data */
655 )
656{
657 assert(conflict != NULL);
658
659 return conflict->ndualproofsinfglobal;
660}
661
662/** gets number of locally valid dual proof constraints derived from infeasible LPs */
664 SCIP_CONFLICT* conflict /**< conflict analysis data */
665 )
666{
667 assert(conflict != NULL);
668
669 return conflict->ndualproofsinflocal;
670}
671
672/** gets average length of dual proof constraints derived from infeasible LPs */
674 SCIP_CONFLICT* conflict /**< conflict analysis data */
675 )
676{
677 assert(conflict != NULL);
678
679 return conflict->dualproofsinfnnonzeros;
680}
681
682/** gets number of successfully analyzed dual proofs derived from bound exceeding LPs */
684 SCIP_CONFLICT* conflict /**< conflict analysis data */
685 )
686{
687 assert(conflict != NULL);
688
689 return conflict->ndualproofsbndsuccess;
690}
691
692/** gets number of globally applied dual proofs derived from bound exceeding LPs */
694 SCIP_CONFLICT* conflict /**< conflict analysis data */
695 )
696{
697 assert(conflict != NULL);
698
699 return conflict->ndualproofsbndglobal;
700}
701
702/** gets number of locally applied dual proofs derived from bound exceeding LPs */
704 SCIP_CONFLICT* conflict /**< conflict analysis data */
705 )
706{
707 assert(conflict != NULL);
708
709 return conflict->ndualproofsbndlocal;
710}
711
712/** gets average length of dual proofs derived from bound exceeding LPs */
714 SCIP_CONFLICT* conflict /**< conflict analysis data */
715 )
716{
717 assert(conflict != NULL);
718
719 return conflict->dualproofsbndnnonzeros;
720}
721
722/** gets number of calls to infeasible strong branching conflict analysis */
724 SCIP_CONFLICT* conflict /**< conflict analysis data */
725 )
726{
727 assert(conflict != NULL);
728
729 return conflict->nsbcalls;
730}
731
732/** gets number of calls to infeasible strong branching conflict analysis that yield at least one conflict constraint */
734 SCIP_CONFLICT* conflict /**< conflict analysis data */
735 )
736{
737 assert(conflict != NULL);
738
739 return conflict->nsbsuccess;
740}
741
742/** gets number of conflict constraints detected in infeasible strong branching conflict analysis */
744 SCIP_CONFLICT* conflict /**< conflict analysis data */
745 )
746{
747 assert(conflict != NULL);
748
749 return conflict->nsbconfconss;
750}
751
752/** gets total number of literals in conflict constraints created in infeasible strong branching conflict analysis */
754 SCIP_CONFLICT* conflict /**< conflict analysis data */
755 )
756{
757 assert(conflict != NULL);
758
759 return conflict->nsbconfliterals;
760}
761
762/** gets number of reconvergence constraints detected in infeasible strong branching conflict analysis */
764 SCIP_CONFLICT* conflict /**< conflict analysis data */
765 )
766{
767 assert(conflict != NULL);
768
769 return conflict->nsbreconvconss;
770}
771
772/** gets total number of literals in reconvergence constraints created in infeasible strong branching conflict analysis */
774 SCIP_CONFLICT* conflict /**< conflict analysis data */
775 )
776{
777 assert(conflict != NULL);
778
779 return conflict->nsbreconvliterals;
780}
781
782/** gets number of LP iterations in infeasible strong branching conflict analysis */
784 SCIP_CONFLICT* conflict /**< conflict analysis data */
785 )
786{
787 assert(conflict != NULL);
788
789 return conflict->nsbiterations;
790}
791
792/** adds a weighted LP row to an aggregation row */
793static
795 SCIP_SET* set, /**< global SCIP settings */
796 SCIP_ROW* row, /**< LP row */
797 SCIP_Real weight, /**< weight for scaling */
798 SCIP_AGGRROW* aggrrow /**< aggregation row */
799 )
800{
801 assert(set != NULL);
802 assert(row != NULL);
803 assert(weight != 0.0);
804
805 /* add minimal value to dual row's left hand side: y_i < 0 -> lhs, y_i > 0 -> rhs */
806 if( weight < 0.0 )
807 {
808 assert(!SCIPsetIsInfinity(set, -row->lhs));
809 SCIP_CALL( SCIPaggrRowAddRow(set->scip, aggrrow, row, weight, -1) );
810 }
811 else
812 {
813 assert(!SCIPsetIsInfinity(set, row->rhs));
814 SCIP_CALL( SCIPaggrRowAddRow(set->scip, aggrrow, row, weight, +1) );
815 }
816 SCIPsetDebugMsg(set, " -> add %s row <%s>[%g,%g](lp depth: %d): dual=%g -> dualrhs=%g\n",
817 row->local ? "local" : "global",
818 SCIProwGetName(row), row->lhs - row->constant, row->rhs - row->constant,
819 row->lpdepth, weight, SCIPaggrRowGetRhs(aggrrow));
820
821 return SCIP_OKAY;
822}
823
824/** checks validity of an LP row and a corresponding weight */
825static
827 SCIP_SET* set, /**< global SCIP settings */
828 SCIP_ROW* row, /**< LP row */
829 SCIP_Real weight, /**< weight for scaling */
830 SCIP_Bool* zerocontribution /**< pointer to store whether every row entry is zero within tolerances */
831 )
832{
833 SCIP_Bool valid = TRUE;
834
835 *zerocontribution = TRUE;
836
837 /* dual solution values of 0.0 are always valid */
838 if( REALABS(weight) > QUAD_EPSILON )
839 {
840 *zerocontribution = FALSE;
841
842 /* check dual feasibility */
843 if( (SCIPsetIsInfinity(set, -row->lhs) && weight > 0.0) || (SCIPsetIsInfinity(set, row->rhs) && weight < 0.0) )
844 {
845 int i;
846
847 /* ignore slight numerical violations if the contribution of every component of the row is close to zero */
848 if( weight > 0.0 )
849 *zerocontribution = SCIPsetIsDualfeasZero(set, row->rhs * weight);
850 else
851 *zerocontribution = SCIPsetIsDualfeasZero(set, row->lhs * weight);
852
853 for( i = 0; i < row->len && *zerocontribution; i++ )
854 {
855 if( !SCIPsetIsDualfeasZero(set, weight * row->vals[i]) )
856 *zerocontribution = FALSE;
857 }
858
859 if( !(*zerocontribution) )
860 {
861 SCIPsetDebugMsg(set, " -> invalid dual solution value %g for row <%s>: lhs=%g, rhs=%g\n",
862 weight, SCIProwGetName(row), row->lhs, row->rhs);
863
864 valid = FALSE;
865 }
866 }
867 }
868
869 return valid;
870}
871
872/** calculates the minimal activity of a given aggregation row */
874 SCIP_SET* set, /**< global SCIP settings */
875 SCIP_PROB* transprob, /**< transformed problem data */
876 SCIP_AGGRROW* aggrrow, /**< aggregation row */
877 SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables (or NULL for global bounds) */
878 SCIP_Real* curvarubs, /**< current upper bounds of active problem variables (or NULL for global bounds) */
879 SCIP_Bool* infdelta /**< pointer to store whether at least one variable contributes with an infinite value */
880 )
881{
882 SCIP_VAR** vars;
883 SCIP_Real QUAD(minact);
884 int* inds;
885 int nnz;
886 int i;
887
888 vars = SCIPprobGetVars(transprob);
889 assert(vars != NULL);
890
891 nnz = SCIPaggrRowGetNNz(aggrrow);
892 inds = SCIPaggrRowGetInds(aggrrow);
893
894 QUAD_ASSIGN(minact, 0.0);
895
896 if( infdelta != NULL )
897 *infdelta = FALSE;
898
899 for( i = 0; i < nnz; i++ )
900 {
901 SCIP_Real val;
902 SCIP_Real QUAD(delta);
903 int v = inds[i];
904
905 assert(SCIPvarGetProbindex(vars[v]) == v);
906
907 val = SCIPaggrRowGetProbvarValue(aggrrow, v);
908
909 if( val > 0.0 )
910 {
911 SCIP_Real bnd = (curvarlbs == NULL ? SCIPvarGetLbGlobal(vars[v]) : curvarlbs[v]);
912
913 if( SCIPsetIsInfinity(set, -bnd) )
914 {
915 if( infdelta != NULL )
916 *infdelta = TRUE;
917
918 return -SCIPsetInfinity(set);
919 }
920
921 SCIPquadprecProdDD(delta, val, bnd);
922 }
923 else
924 {
925 SCIP_Real bnd = (curvarubs == NULL ? SCIPvarGetUbGlobal(vars[v]) : curvarubs[v]);
926
927 if( SCIPsetIsInfinity(set, bnd) )
928 {
929 if( infdelta != NULL )
930 *infdelta = TRUE;
931
932 return -SCIPsetInfinity(set);
933 }
934
935 SCIPquadprecProdDD(delta, val, bnd);
936 }
937
938 /* update minimal activity */
939 SCIPquadprecSumQQ(minact, minact, delta);
940 }
941
942 /* check whether the minimal activity is infinite */
943 if( SCIPsetIsInfinity(set, QUAD_TO_DBL(minact)) )
944 return SCIPsetInfinity(set);
945 if( SCIPsetIsInfinity(set, -QUAD_TO_DBL(minact)) )
946 return -SCIPsetInfinity(set);
947
948 return QUAD_TO_DBL(minact);
949}
950
951/** sort local rows by increasing depth and number of nonzeros as tie-breaker */
952static
954 SCIP_SET* set, /**< global SCIP settings */
955 SCIP_AGGRROW* aggrrow, /**< aggregation row */
956 SCIP_ROW** rows, /**< array of local rows */
957 int* rowinds, /**< array of row indices */
958 int* rowdepth, /**< array of LP depths */
959 int nrows /**< number of local rows */
960 )
961{
962 int* rownnz;
963 int i;
964
965 assert(aggrrow != NULL);
966 assert(rows != NULL);
967 assert(nrows > 0);
968 assert(rowinds != NULL);
969 assert(rowdepth != NULL);
970
971 /* sort row indices by increasing depth */
972 SCIPsortIntInt(rowdepth, rowinds, nrows);
973 assert(rowdepth[0] <= rowdepth[nrows-1]);
974
975 SCIP_CALL( SCIPsetAllocBufferArray(set, &rownnz, nrows) );
976
977 /* get number of nonzero entries for every row */
978 for( i = 0; i < nrows; i++ )
979 {
980 SCIP_ROW* row = rows[rowinds[i]];
981 assert(row != NULL);
982
983 rownnz[i] = row->len;
984 }
985
986 /* since SCIP has no stable sorting function we sort each bucket separately */
987 for( i = 0; i < nrows; i++ )
988 {
989 int j = i;
990 int d = rowdepth[i];
991
992 /* search for the next row with a greater depth */
993 while( j+1 < nrows && rowdepth[j+1] == d )
994 j++;
995
996 /* the bucket has size one */
997 if( j == i )
998 continue;
999
1000 assert(j-i+1 <= nrows);
1001
1002 /* sort row indices by increasing number of nonzero elements */
1003 SCIPsortIntIntInt(&rownnz[i], &rowdepth[i], &rowinds[i], j-i+1);
1004 assert(rownnz[i] <= rownnz[j]);
1005
1006 i = j;
1007 } /*lint --e{850} i is modified in the body of the for loop */
1008
1009#ifndef NDEBUG
1010 for( i = 0; i < nrows-1; i++ )
1011 assert(rowdepth[i] < rowdepth[i+1] || (rowdepth[i] == rowdepth[i+1] && rownnz[i] <= rownnz[i+1]));
1012#endif
1013
1014 SCIPsetFreeBufferArray(set, &rownnz);
1015
1016 return SCIP_OKAY;
1017}
1018
1019/** adds locally valid rows to the proof constraint */
1020static
1022 SCIP_SET* set, /**< global SCIP settings */
1023 SCIP_PROB* transprob, /**< transformed problem */
1024 SCIP_LP* lp, /**< LP data */
1025 SCIP_AGGRROW* proofrow, /**< aggregated row representing the proof */
1026 SCIP_ROW** rows, /**< array if locally valid rows */
1027 SCIP_Real* dualsols, /**< dual solution vector */
1028 int* localrowinds, /**< array of row indecies */
1029 int* localrowdepth, /**< array of row depths */
1030 int nlocalrows, /**< number of local rows stored in rows array */
1031 SCIP_Real* proofact, /**< pointer to store the activity of the proof constraint */
1032 int* validdepth, /**< pointer to store the depth where the proof constraint is valid */
1033 SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
1034 SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
1035 SCIP_Bool* valid /**< pointer store whether the proof constraint is valid */
1036 )
1037{
1038 SCIP_Bool infdelta;
1039 int i;
1040
1041 assert(set != NULL);
1042 assert(lp != NULL);
1043
1044 *validdepth = 0;
1045
1046 if( !set->conf_uselocalrows )
1047 return SCIP_OKAY;
1048
1049 SCIPsetDebugMsg(set, "add local rows to dual proof:\n");
1050
1051 /* check whether the proof is already valid, e.g., violated within the local bounds */
1052 *proofact = SCIPaggrRowGetMinActivity(set, transprob, proofrow, curvarlbs, curvarubs, &infdelta);
1053
1054 /* we stop if the minimal activity is infinite but all variables have a finite activity delta (bad numerics) */
1055 if( !infdelta && SCIPsetIsInfinity(set, REALABS(*proofact)) )
1056 {
1057 *valid = FALSE;
1058 return SCIP_OKAY;
1059 }
1060
1061 /* break if the proof is valid w.r.t local bounds
1062 * note: it can happen that the proof contains a variable with an infinite activity delta.
1063 * here, we don't break immediately because we might be able to fix it by adding local rows
1064 */
1065 if( !infdelta && SCIPsetIsGT(set, *proofact, SCIPaggrRowGetRhs(proofrow)) )
1066 {
1067 *valid = TRUE;
1068 return SCIP_OKAY;
1069 }
1070
1071 /* sort local rows by depth */
1072 SCIP_CALL( sortLocalRows(set, proofrow, rows, localrowinds, localrowdepth, nlocalrows) );
1073
1074 /* add successively local rows */
1075 for( i = 0; i < nlocalrows; ++i )
1076 {
1077 SCIP_ROW* row;
1078 int r;
1079
1080 r = localrowinds[i];
1081 row = rows[r];
1082
1083 assert(row != NULL);
1084 assert(row->len == 0 || row->cols != NULL);
1085 assert(row->len == 0 || row->vals != NULL);
1086 assert(row == lp->lpirows[r]);
1087 assert(row->local);
1088 assert(row->lpdepth == localrowdepth[i]);
1089
1090 /* ignore dual solution values of 0.0 (in this case: y_i == 0) */
1091 if( REALABS(dualsols[r]) > 0.0 )
1092 {
1093#ifndef NDEBUG
1094 SCIP_Bool zerocontribution;
1095
1096 /* check dual feasibility */
1097 *valid = checkDualFeasibility(set, row, dualsols[r], &zerocontribution);
1098 assert(*valid);
1099 assert(!zerocontribution);
1100#endif
1101
1102 if( SCIPsetIsDualfeasZero(set, dualsols[r]) )
1103 continue;
1104
1105 /* add row to dual proof */
1106 SCIP_CALL( addRowToAggrRow(set, row, -dualsols[r], proofrow) );
1107
1108 /* update depth where the proof is valid */
1109 if( *validdepth < localrowdepth[i] )
1110 *validdepth = localrowdepth[i];
1111
1112 /* get the new minimal activity */
1113 *proofact = SCIPaggrRowGetMinActivity(set, transprob, proofrow, curvarlbs, curvarubs, &infdelta);
1114
1115 /* we stop if the minimal activity is infinite but all variables have a finite activity delta (bad numerics) */
1116 if( !infdelta && SCIPsetIsInfinity(set, REALABS(*proofact)) )
1117 {
1118 *valid = FALSE;
1119 goto TERMINATE;
1120 }
1121
1122 /* break if the proof is valid w.r.t local bounds */
1123 if( !infdelta && SCIPsetIsGT(set, *proofact, SCIPaggrRowGetRhs(proofrow)) )
1124 {
1125 *valid = TRUE;
1126 break;
1127 }
1128 }
1129 }
1130
1131 /* remove all nearly zero coefficients */
1132 SCIPaggrRowRemoveZeros(set->scip, proofrow, TRUE, valid);
1133
1134 TERMINATE:
1135 if( !(*valid) )
1136 {
1137 SCIPsetDebugMsg(set, " -> proof is not valid: %g <= %g\n", *proofact, SCIPaggrRowGetRhs(proofrow));
1138 SCIPsetDebugMsg(set, " -> stop due to numerical troubles\n");
1139 }
1140 else
1141 {
1142 *proofact = SCIPaggrRowGetMinActivity(set, transprob, proofrow, curvarlbs, curvarubs, &infdelta);
1143
1144 /* we stop if the minimal activity is infinite but all variables have a finite activity delta (bad numerics) */
1145 if( !infdelta && SCIPsetIsInfinity(set, REALABS(*proofact)) )
1146 {
1147 *valid = FALSE;
1148 SCIPsetDebugMsg(set, " -> proof is not valid: %g <= %g [infdelta: %u]\n", *proofact, SCIPaggrRowGetRhs(proofrow), infdelta);
1149 }
1150 else if( infdelta || SCIPsetIsLE(set, *proofact, SCIPaggrRowGetRhs(proofrow)) )
1151 {
1152 *valid = FALSE;
1153 SCIPsetDebugMsg(set, " -> proof is not valid: %g <= %g [infdelta: %u]\n", *proofact, SCIPaggrRowGetRhs(proofrow), infdelta);
1154 }
1155 }
1156
1157 return SCIP_OKAY;
1158}
1159
1160/** calculates a Farkas proof from the current dual LP solution */
1162 SCIP_SET* set, /**< global SCIP settings */
1163 SCIP_PROB* prob, /**< transformed problem */
1164 SCIP_LP* lp, /**< LP data */
1165 SCIP_LPI* lpi, /**< LPI data */
1166 SCIP_TREE* tree, /**< tree data */
1167 SCIP_AGGRROW* farkasrow, /**< aggregated row representing the proof */
1168 SCIP_Real* farkasact, /**< maximal activity of the proof constraint */
1169 int* validdepth, /**< pointer to store the valid depth of the proof constraint */
1170 SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
1171 SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
1172 SCIP_Bool* valid /**< pointer store whether the proof constraint is valid */
1173 )
1174{
1175 SCIP_ROW** rows;
1176 SCIP_Real* dualfarkas;
1177 SCIP_ROW* row;
1178 int* localrowinds;
1179 int* localrowdepth;
1180 SCIP_Bool infdelta;
1181 int nlocalrows;
1182 int nrows;
1183 int r;
1184
1185 assert(set != NULL);
1186 assert(prob != NULL);
1187 assert(lp != NULL);
1188 assert(lp->flushed);
1189 assert(lp->solved);
1190 assert(curvarlbs != NULL);
1191 assert(curvarubs != NULL);
1192 assert(valid != NULL);
1193
1196
1197 /* get LP rows and problem variables */
1198 rows = SCIPlpGetRows(lp);
1199 nrows = SCIPlpGetNRows(lp);
1200 assert(nrows == 0 || rows != NULL);
1201 assert(nrows == lp->nlpirows);
1202
1203 /* it can happen that infeasibility is detetected within LP presolve. in that case, the LP solver may not be able to
1204 * to return the dual ray.
1205 */
1206 if( !SCIPlpiHasDualRay(lpi) )
1207 {
1208 *valid = FALSE;
1209 return SCIP_OKAY;
1210 }
1211
1212 assert(farkasrow != NULL);
1213
1214 /* allocate temporary memory */
1215 SCIP_CALL( SCIPsetAllocBufferArray(set, &dualfarkas, nrows) );
1216 BMSclearMemoryArray(dualfarkas, nrows);
1217 localrowinds = NULL;
1218 localrowdepth = NULL;
1219 nlocalrows = 0;
1220
1221 /* get dual Farkas values of rows */
1222 SCIP_CALL( SCIPlpiGetDualfarkas(lpi, dualfarkas) );
1223
1224 /* check whether the Farkas solution is numerically stable */
1225 for( r = 0; r < nrows; ++r )
1226 {
1227 if( REALABS(dualfarkas[r]) > SOLSTOP )
1228 {
1229 *valid = FALSE;
1230 goto TERMINATE;
1231 }
1232 }
1233
1234 /* calculate the Farkas row */
1235 *valid = TRUE;
1236 *validdepth = 0;
1237
1238 for( r = 0; r < nrows; ++r )
1239 {
1240 row = rows[r];
1241 assert(row != NULL);
1242 assert(row->len == 0 || row->cols != NULL);
1243 assert(row->len == 0 || row->vals != NULL);
1244 assert(row == lp->lpirows[r]);
1245
1246 /* ignore dual ray values of 0.0 (in this case: y_i == z_i == 0) */
1247 if( REALABS(dualfarkas[r]) > 0.0 )
1248 {
1249 SCIP_Bool zerocontribution;
1250
1251 /* check dual feasibility */
1252 *valid = checkDualFeasibility(set, row, dualfarkas[r], &zerocontribution);
1253
1254 if( !(*valid) )
1255 goto TERMINATE;
1256
1257 if( zerocontribution )
1258 continue;
1259
1260 if( SCIPsetIsDualfeasZero(set, dualfarkas[r]) )
1261 continue;
1262
1263 if( !row->local )
1264 {
1265 SCIP_CALL( addRowToAggrRow(set, row, -dualfarkas[r], farkasrow) );
1266
1267 /* due to numerical reasons we want to stop */
1268 if( REALABS(SCIPaggrRowGetRhs(farkasrow)) > NUMSTOP )
1269 {
1270 *valid = FALSE;
1271 goto TERMINATE;
1272 }
1273 }
1274 else
1275 {
1276 int lpdepth = SCIProwGetLPDepth(row);
1277
1278 if( nlocalrows == 0 && lpdepth < SCIPtreeGetFocusDepth(tree) )
1279 {
1280 SCIP_CALL( SCIPsetAllocBufferArray(set, &localrowinds, nrows-r) );
1281 SCIP_CALL( SCIPsetAllocBufferArray(set, &localrowdepth, nrows-r) );
1282 }
1283
1284 if( lpdepth < SCIPtreeGetFocusDepth(tree) )
1285 {
1286 assert(localrowinds != NULL);
1287 assert(localrowdepth != NULL);
1288
1289 localrowinds[nlocalrows] = r;
1290 localrowdepth[nlocalrows++] = lpdepth;
1291 }
1292 }
1293 }
1294 }
1295
1296 /* remove all coefficients that are too close to zero */
1297 SCIPaggrRowRemoveZeros(set->scip, farkasrow, TRUE, valid);
1298
1299 if( !(*valid) )
1300 goto TERMINATE;
1301
1302 infdelta = FALSE;
1303
1304 /* calculate the current Farkas activity, always using the best bound w.r.t. the Farkas coefficient */
1305 *farkasact = SCIPaggrRowGetMinActivity(set, prob, farkasrow, curvarlbs, curvarubs, &infdelta);
1306
1307 SCIPsetDebugMsg(set, " -> farkasact=%g farkasrhs=%g [infdelta: %u], \n",
1308 (*farkasact), SCIPaggrRowGetRhs(farkasrow), infdelta);
1309
1310 /* The constructed proof is not valid, this can happen due to numerical reasons,
1311 * e.g., we only consider rows r with !SCIPsetIsZero(set, dualfarkas[r]),
1312 * or because of local rows were ignored so far.
1313 * Due to the latter case, it might happen at least one variable contributes
1314 * with an infinite value to the activity (see: https://git.zib.de/integer/scip/issues/2743)
1315 */
1316 if( infdelta || SCIPsetIsFeasLE(set, *farkasact, SCIPaggrRowGetRhs(farkasrow)))
1317 {
1318 /* add contribution of local rows */
1319 if( nlocalrows > 0 && set->conf_uselocalrows > 0 )
1320 {
1321 SCIP_CALL( addLocalRows(set, prob, lp, farkasrow, rows, dualfarkas, localrowinds, localrowdepth,
1322 nlocalrows, farkasact, validdepth, curvarlbs, curvarubs, valid) );
1323 }
1324 else
1325 {
1326 *valid = FALSE;
1327 SCIPsetDebugMsg(set, " -> proof is not valid to due infinite activity delta\n");
1328 }
1329 }
1330
1331 TERMINATE:
1332
1333 SCIPfreeBufferArrayNull(set->scip, &localrowdepth);
1334 SCIPfreeBufferArrayNull(set->scip, &localrowinds);
1335 SCIPsetFreeBufferArray(set, &dualfarkas);
1336
1337 return SCIP_OKAY;
1338}
1339
1340/** calculates a dual proof from the current dual LP solution */
1342 SCIP_SET* set, /**< global SCIP settings */
1343 SCIP_PROB* transprob, /**< transformed problem */
1344 SCIP_LP* lp, /**< LP data */
1345 SCIP_LPI* lpi, /**< LPI data */
1346 SCIP_TREE* tree, /**< tree data */
1347 SCIP_AGGRROW* farkasrow, /**< aggregated row representing the proof */
1348 SCIP_Real* farkasact, /**< maximal activity of the proof constraint */
1349 int* validdepth, /**< pointer to store the valid depth of the proof constraint */
1350 SCIP_Real* curvarlbs, /**< current lower bounds of active problem variables */
1351 SCIP_Real* curvarubs, /**< current upper bounds of active problem variables */
1352 SCIP_Bool* valid /**< pointer store whether the proof constraint is valid */
1353 )
1354{
1355 SCIP_RETCODE retcode;
1356 SCIP_ROW** rows;
1357 SCIP_ROW* row;
1358 SCIP_Real* primsols;
1359 SCIP_Real* dualsols;
1360 SCIP_Real* redcosts;
1361 int* localrowinds;
1362 int* localrowdepth;
1363 SCIP_Bool infdelta;
1364 int nlocalrows;
1365 int nrows;
1366 int ncols;
1367 int r;
1368
1369 assert(set != NULL);
1370 assert(transprob != NULL);
1371 assert(lp != NULL);
1372 assert(lp->flushed);
1373 assert(lp->solved);
1374 assert(curvarlbs != NULL);
1375 assert(curvarubs != NULL);
1376 assert(valid != NULL);
1377
1378 *validdepth = 0;
1379 *valid = TRUE;
1380
1381 localrowinds = NULL;
1382 localrowdepth = NULL;
1383 nlocalrows = 0;
1384
1385 /* get LP rows and problem variables */
1386 rows = SCIPlpGetRows(lp);
1387 nrows = SCIPlpGetNRows(lp);
1388 ncols = SCIPlpGetNCols(lp);
1389 assert(nrows == 0 || rows != NULL);
1390 assert(nrows == lp->nlpirows);
1391
1392 /* get temporary memory */
1393 SCIP_CALL( SCIPsetAllocBufferArray(set, &primsols, ncols) );
1394 SCIP_CALL( SCIPsetAllocBufferArray(set, &dualsols, nrows) );
1395 SCIP_CALL( SCIPsetAllocBufferArray(set, &redcosts, ncols) );
1396
1397 /* get solution from LPI */
1398 retcode = SCIPlpiGetSol(lpi, NULL, primsols, dualsols, NULL, redcosts);
1399 if( retcode == SCIP_LPERROR ) /* on an error in the LP solver, just abort the conflict analysis */
1400 {
1401 *valid = FALSE;
1402 goto TERMINATE;
1403 }
1404 SCIP_CALL( retcode );
1405#ifdef SCIP_DEBUG
1406 {
1407 SCIP_Real objval;
1408 SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
1409 SCIPsetDebugMsg(set, " -> LP objval: %g\n", objval);
1410 }
1411#endif
1412
1413 /* check whether the dual solution is numerically stable */
1414 for( r = 0; r < nrows; ++r )
1415 {
1416 if( REALABS(dualsols[r]) > SOLSTOP )
1417 {
1418 *valid = FALSE;
1419 goto TERMINATE;
1420 }
1421 }
1422
1423 /* clear the proof */
1424 SCIPaggrRowClear(farkasrow);
1425
1426 /* Let y be the dual solution and r be the reduced cost vector. Let z be defined as
1427 * z_i := y_i if i is a global row,
1428 * z_i := 0 if i is a local row.
1429 * Define the set X := {x | lhs <= Ax <= rhs, lb <= x <= ub, c^Tx <= c*}, with c* being the current primal bound.
1430 * Then the following inequalities are valid for all x \in X:
1431 * - c* <= -c^Tx
1432 * <=> z^TAx - c* <= (z^TA - c^T) x
1433 * <=> z^TAx - c* <= (y^TA - c^T - (y-z)^TA) x
1434 * <=> z^TAx - c* <= (-r^T - (y-z)^TA) x (dual feasibility of (y,r): y^TA + r^T == c^T)
1435 * Because lhs <= Ax <= rhs and lb <= x <= ub, the inequality can be relaxed to give
1436 * min{z^Tq | lhs <= q <= rhs} - c* <= max{(-r^T - (y-z)^TA) x | lb <= x <= ub}, or X = {}.
1437 *
1438 * The resulting dual row is: z^T{lhs,rhs} - c* <= (-r^T - (y-z)^TA){lb,ub},
1439 * where lhs, rhs, lb, and ub are selected in order to maximize the feasibility of the row.
1440 */
1441
1442 /* add the objective function to the aggregation row with respect to the current cutoff bound
1443 *
1444 * for an integral objective the right-hand side is reduced by the cutoff bound delta to cut off up to the next
1445 * possible objective value below the cutoff bound
1446 */
1447 SCIP_CALL( SCIPaggrRowAddObjectiveFunction(set->scip, farkasrow, lp->cutoffbound - (SCIPprobIsObjIntegral(transprob) ? SCIPsetCutoffbounddelta(set) : 0.0), 1.0) );
1448
1449 /* dual row: z^T{lhs,rhs} - c* <= (-r^T - (y-z)^TA){lb,ub}
1450 * 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
1451 */
1452 for( r = 0; r < nrows; ++r )
1453 {
1454 row = rows[r];
1455 assert(row != NULL);
1456 assert(row->len == 0 || row->cols != NULL);
1457 assert(row->len == 0 || row->vals != NULL);
1458 assert(row == lp->lpirows[r]);
1459
1460 /* ignore dual solution values of 0.0 (in this case: y_i == z_i == 0) */
1461 if( REALABS(dualsols[r]) > 0.0 )
1462 {
1463 SCIP_Bool zerocontribution;
1464
1465 /* check dual feasibility */
1466 *valid = checkDualFeasibility(set, row, dualsols[r], &zerocontribution);
1467
1468 if( !(*valid) )
1469 goto TERMINATE;
1470
1471 if( zerocontribution )
1472 continue;
1473
1474 if( SCIPsetIsDualfeasZero(set, dualsols[r]) )
1475 continue;
1476
1477 /* skip local row */
1478 if( !row->local )
1479 {
1480 SCIP_CALL( addRowToAggrRow(set, row, -dualsols[r], farkasrow) );
1481
1482 /* due to numerical reasons we want to stop */
1483 if( REALABS(SCIPaggrRowGetRhs(farkasrow)) > NUMSTOP )
1484 {
1485 *valid = FALSE;
1486 goto TERMINATE;
1487 }
1488 }
1489 else
1490 {
1491 int lpdepth = SCIProwGetLPDepth(row);
1492
1493 if( nlocalrows == 0 && lpdepth < SCIPtreeGetFocusDepth(tree) )
1494 {
1495 SCIP_CALL( SCIPsetAllocBufferArray(set, &localrowinds, nrows-r) );
1496 SCIP_CALL( SCIPsetAllocBufferArray(set, &localrowdepth, nrows-r) );
1497 }
1498
1499 if( lpdepth < SCIPtreeGetFocusDepth(tree) )
1500 {
1501 assert(localrowinds != NULL);
1502 assert(localrowdepth != NULL);
1503
1504 localrowinds[nlocalrows] = r;
1505 localrowdepth[nlocalrows++] = lpdepth;
1506 }
1507 }
1508 }
1509 }
1510
1511 /* remove all nearly zero coefficients */
1512 SCIPaggrRowRemoveZeros(set->scip, farkasrow, TRUE, valid);
1513
1514 if( !(*valid) )
1515 goto TERMINATE;
1516
1517 infdelta = FALSE;
1518
1519 /* check validity of the proof */
1520 *farkasact = SCIPaggrRowGetMinActivity(set, transprob, farkasrow, curvarlbs, curvarubs, &infdelta);
1521
1522 SCIPsetDebugMsg(set, " -> farkasact=%g farkasrhs=%g [infdelta: %u], \n",
1523 (*farkasact), SCIPaggrRowGetRhs(farkasrow), infdelta);
1524
1525 /* The constructed proof is not valid, this can happen due to numerical reasons,
1526 * e.g., we only consider rows r with !SCIPsetIsZero(set, dualsol[r]),
1527 * or because of local rows were ignored so far.
1528 * Due to the latter case, it might happen at least one variable contributes
1529 * with an infinite value to the activity (see: https://git.zib.de/integer/scip/issues/2743)
1530 */
1531 if( infdelta || SCIPsetIsFeasLE(set, *farkasact, SCIPaggrRowGetRhs(farkasrow)))
1532 {
1533 /* add contribution of local rows */
1534 if( nlocalrows > 0 && set->conf_uselocalrows > 0 )
1535 {
1536 SCIP_CALL( addLocalRows(set, transprob, lp, farkasrow, rows, dualsols, localrowinds, localrowdepth,
1537 nlocalrows, farkasact, validdepth, curvarlbs, curvarubs, valid) );
1538 }
1539 else
1540 {
1541 *valid = FALSE;
1542 SCIPsetDebugMsg(set, " -> proof is not valid to due infinite activity delta\n");
1543 }
1544 }
1545
1546 TERMINATE:
1547
1548 SCIPfreeBufferArrayNull(set->scip, &localrowdepth);
1549 SCIPfreeBufferArrayNull(set->scip, &localrowinds);
1550 SCIPsetFreeBufferArray(set, &redcosts);
1551 SCIPsetFreeBufferArray(set, &dualsols);
1552 SCIPsetFreeBufferArray(set, &primsols);
1553
1554 return SCIP_OKAY;
1555}
1556
1557
1558/*
1559 * pseudo solution conflict analysis
1560 */
1561
1562/** analyzes a pseudo solution with objective value exceeding the current cutoff to find out the bound changes on
1563 * variables that were responsible for the objective value degradation;
1564 * on success, calls standard conflict analysis with the responsible variables as starting conflict set, thus creating
1565 * a conflict constraint out of the resulting conflict set;
1566 * updates statistics for pseudo solution conflict analysis
1567 */
1569 SCIP_CONFLICT* conflict, /**< conflict analysis data */
1570 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
1571 SCIP_SET* set, /**< global SCIP settings */
1572 SCIP_STAT* stat, /**< problem statistics */
1573 SCIP_PROB* transprob, /**< transformed problem */
1574 SCIP_PROB* origprob, /**< original problem */
1575 SCIP_TREE* tree, /**< branch and bound tree */
1576 SCIP_REOPT* reopt, /**< reoptimization data structure */
1577 SCIP_LP* lp, /**< LP data */
1578 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
1579 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1580 SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
1581 SCIP_Bool* success /**< pointer to store whether a conflict constraint was created, or NULL */
1582 )
1583{
1584 SCIP_VAR** vars;
1585 SCIP_VAR* var;
1586 SCIP_Real* curvarlbs;
1587 SCIP_Real* curvarubs;
1588 int* lbchginfoposs;
1589 int* ubchginfoposs;
1590 SCIP_Real* pseudocoefs;
1591 SCIP_Real pseudolhs;
1592 SCIP_Real pseudoact;
1593 int nvars;
1594 int v;
1595
1596 assert(conflict != NULL);
1597 assert(conflict->nconflictsets == 0);
1598 assert(set != NULL);
1599 assert(stat != NULL);
1600 assert(transprob != NULL);
1601 assert(lp != NULL);
1602 assert(!SCIPsetIsInfinity(set, -SCIPlpGetPseudoObjval(lp, set, transprob)));
1603 assert(!SCIPsetIsInfinity(set, lp->cutoffbound));
1604
1605 if( success != NULL )
1606 *success = FALSE;
1607
1608 /* check, if pseudo solution conflict analysis is enabled */
1609 if( !set->conf_enable || !set->conf_usepseudo )
1610 return SCIP_OKAY;
1611
1612 /* check, if there are any conflict handlers to use a conflict set */
1613 if( set->nconflicthdlrs == 0 )
1614 return SCIP_OKAY;
1615
1616 SCIPsetDebugMsg(set, "analyzing pseudo solution (obj: %g) that exceeds objective limit (%g)\n",
1617 SCIPlpGetPseudoObjval(lp, set, transprob), lp->cutoffbound);
1618
1620 conflict->conflictset->usescutoffbound = TRUE;
1621
1622 /* start timing */
1624 conflict->npseudocalls++;
1625
1626 vars = transprob->vars;
1627 nvars = transprob->nvars;
1628 assert(nvars == 0 || vars != NULL);
1629
1630 /* The current primal bound c* gives an upper bound for the current pseudo objective value:
1631 * min{c^T x | lb <= x <= ub} <= c*.
1632 * We have to transform this row into a >= inequality in order to use methods above:
1633 * -c* <= max{-c^T x | lb <= x <= ub}.
1634 * In the local subproblem, this row is violated. We want to undo bound changes while still keeping the
1635 * row violated.
1636 */
1637
1638 /* get temporary memory for remembering variables' current bounds and corresponding bound change information
1639 * positions in variable's bound change information arrays
1640 */
1641 SCIP_CALL( SCIPsetAllocBufferArray(set, &curvarlbs, nvars) );
1642 SCIP_CALL( SCIPsetAllocBufferArray(set, &curvarubs, nvars) );
1643 SCIP_CALL( SCIPsetAllocBufferArray(set, &lbchginfoposs, nvars) );
1644 SCIP_CALL( SCIPsetAllocBufferArray(set, &ubchginfoposs, nvars) );
1645
1646 /* get temporary memory for infeasibility proof coefficients */
1647 SCIP_CALL( SCIPsetAllocBufferArray(set, &pseudocoefs, nvars) );
1648
1649 /* for an integral objective use the cutoff bound reduced by the cutoff bound delta to cut off up to the next better
1650 * objective value
1651 */
1652 pseudolhs = -(lp->cutoffbound - (SCIPprobIsObjIntegral(transprob) ? SCIPsetCutoffbounddelta(set) : 0.0));
1653
1654 /* store the objective values as infeasibility proof coefficients, and recalculate the pseudo activity */
1655 pseudoact = 0.0;
1656 for( v = 0; v < nvars; ++v )
1657 {
1658 var = vars[v];
1659 pseudocoefs[v] = -SCIPvarGetObj(var);
1660 curvarlbs[v] = SCIPvarGetLbLocal(var);
1661 curvarubs[v] = SCIPvarGetUbLocal(var);
1662 lbchginfoposs[v] = var->nlbchginfos-1;
1663 ubchginfoposs[v] = var->nubchginfos-1;
1664
1665 if( SCIPsetIsZero(set, pseudocoefs[v]) )
1666 {
1667 pseudocoefs[v] = 0.0;
1668 continue;
1669 }
1670
1671 if( pseudocoefs[v] > 0.0 )
1672 pseudoact += pseudocoefs[v] * curvarubs[v];
1673 else
1674 pseudoact += pseudocoefs[v] * curvarlbs[v];
1675 }
1676 assert(SCIPsetIsFeasEQ(set, pseudoact, -SCIPlpGetPseudoObjval(lp, set, transprob)));
1677 SCIPsetDebugMsg(set, " -> recalculated pseudo infeasibility proof: %g <= %g\n", pseudolhs, pseudoact);
1678
1679 /* check, if the pseudo row is still violated (after recalculation of pseudo activity) */
1680 if( SCIPsetIsFeasGT(set, pseudolhs, pseudoact) )
1681 {
1682 int nconss;
1683 int nliterals;
1684 int nreconvconss;
1685 int nreconvliterals;
1686
1687 /* undo bound changes without destroying the infeasibility proof */
1688 SCIP_CALL( SCIPundoBdchgsProof(set, transprob, SCIPtreeGetCurrentDepth(tree), pseudocoefs, pseudolhs, &pseudoact,
1689 curvarlbs, curvarubs, lbchginfoposs, ubchginfoposs, NULL, NULL, NULL, lp->lpi) );
1690
1691 /* analyze conflict on remaining bound changes */
1692 SCIP_CALL( SCIPconflictAnalyzeRemainingBdchgs(conflict, blkmem, set, stat, transprob, tree, FALSE, \
1693 lbchginfoposs, ubchginfoposs, &nconss, &nliterals, &nreconvconss, &nreconvliterals) );
1694 conflict->npseudosuccess += (nconss > 0 ? 1 : 0);
1695 conflict->npseudoconfconss += nconss;
1696 conflict->npseudoconfliterals += nliterals;
1697 conflict->npseudoreconvconss += nreconvconss;
1698 conflict->npseudoreconvliterals += nreconvliterals;
1699 if( success != NULL )
1700 *success = (nconss > 0);
1701 }
1702
1703 /* free temporary memory */
1704 SCIPsetFreeBufferArray(set, &pseudocoefs);
1705 SCIPsetFreeBufferArray(set, &ubchginfoposs);
1706 SCIPsetFreeBufferArray(set, &lbchginfoposs);
1707 SCIPsetFreeBufferArray(set, &curvarubs);
1708 SCIPsetFreeBufferArray(set, &curvarlbs);
1709
1710 /* flush conflict set storage */
1711 SCIP_CALL( SCIPconflictFlushConss(conflict, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, eventqueue, cliquetable) );
1712
1713 /* stop timing */
1715
1716 return SCIP_OKAY;
1717}
1718
1719/** gets time in seconds used for analyzing pseudo solution conflicts */
1721 SCIP_CONFLICT* conflict /**< conflict analysis data */
1722 )
1723{
1724 assert(conflict != NULL);
1725
1726 return SCIPclockGetTime(conflict->pseudoanalyzetime);
1727}
1728
1729/** gets number of calls to pseudo solution conflict analysis */
1731 SCIP_CONFLICT* conflict /**< conflict analysis data */
1732 )
1733{
1734 assert(conflict != NULL);
1735
1736 return conflict->npseudocalls;
1737}
1738
1739/** gets number of calls to pseudo solution conflict analysis that yield at least one conflict constraint */
1741 SCIP_CONFLICT* conflict /**< conflict analysis data */
1742 )
1743{
1744 assert(conflict != NULL);
1745
1746 return conflict->npseudosuccess;
1747}
1748
1749/** gets number of conflict constraints detected in pseudo solution conflict analysis */
1751 SCIP_CONFLICT* conflict /**< conflict analysis data */
1752 )
1753{
1754 assert(conflict != NULL);
1755
1756 return conflict->npseudoconfconss;
1757}
1758
1759/** gets total number of literals in conflict constraints created in pseudo solution conflict analysis */
1761 SCIP_CONFLICT* conflict /**< conflict analysis data */
1762 )
1763{
1764 assert(conflict != NULL);
1765
1766 return conflict->npseudoconfliterals;
1767}
1768
1769/** gets number of reconvergence constraints detected in pseudo solution conflict analysis */
1771 SCIP_CONFLICT* conflict /**< conflict analysis data */
1772 )
1773{
1774 assert(conflict != NULL);
1775
1776 return conflict->npseudoreconvconss;
1777}
1778
1779/** gets total number of literals in reconvergence constraints created in pseudo solution conflict analysis */
1781 SCIP_CONFLICT* conflict /**< conflict analysis data */
1782 )
1783{
1784 assert(conflict != NULL);
1785
1786 return conflict->npseudoreconvliterals;
1787}
1788
1789/** actually performs analysis of infeasible LP */
1790static
1792 SCIP_CONFLICT* conflict, /**< conflict analysis data */
1793 SCIP_CONFLICTSTORE* conflictstore, /**< conflict store */
1794 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
1795 SCIP_SET* set, /**< global SCIP settings */
1796 SCIP_STAT* stat, /**< problem statistics */
1797 SCIP_PROB* transprob, /**< transformed problem */
1798 SCIP_PROB* origprob, /**< original problem */
1799 SCIP_TREE* tree, /**< branch and bound tree */
1800 SCIP_REOPT* reopt, /**< reoptimization data structure */
1801 SCIP_LP* lp, /**< LP data */
1802 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
1803 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1804 SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
1805 SCIP_Bool diving, /**< are we in strong branching or diving mode? */
1806 SCIP_Bool* dualproofsuccess, /**< pointer to store success result of dual proof analysis */
1807 int* iterations, /**< pointer to store the total number of LP iterations used */
1808 int* nconss, /**< pointer to store the number of generated conflict constraints */
1809 int* nliterals, /**< pointer to store the number of literals in generated conflict constraints */
1810 int* nreconvconss, /**< pointer to store the number of generated reconvergence constraints */
1811 int* nreconvliterals, /**< pointer to store the number of literals generated reconvergence constraints */
1812 SCIP_Bool marklpunsolved /**< whether LP should be marked unsolved after analysis (needed for strong branching) */
1813 )
1814{
1815 SCIP_VAR** vars;
1816 SCIP_AGGRROW* farkasrow;
1817 SCIP_LPI* lpi;
1818 SCIP_Bool valid;
1819 SCIP_Bool globalinfeasible;
1820 int* lbchginfoposs;
1821 int* ubchginfoposs;
1822 int validdepth;
1823 int nvars;
1824 int v;
1825 SCIP_Real* curvarlbs;
1826 SCIP_Real* curvarubs;
1827 SCIP_Real farkasactivity;
1828
1829 assert(conflict != NULL);
1830 assert(conflict->nconflictsets == 0);
1831 assert(set != NULL);
1832 assert(SCIPprobAllColsInLP(transprob, set, lp)); /* LP conflict analysis is only valid, if all variables are known */
1833 assert(stat != NULL);
1834 assert(transprob != NULL);
1835 assert(lp != NULL);
1836 assert(lp->flushed);
1837 assert(lp->solved);
1838 assert(iterations != NULL);
1839 assert(nconss != NULL);
1840 assert(nliterals != NULL);
1841 assert(nreconvconss != NULL);
1842 assert(nreconvliterals != NULL);
1843
1844 *dualproofsuccess = FALSE;
1845 *iterations = 0;
1846 *nconss = 0;
1847 *nliterals = 0;
1848 *nreconvconss = 0;
1849 *nreconvliterals = 0;
1850
1851 vars = transprob->vars;
1852 nvars = transprob->nvars;
1853
1854 valid = TRUE;
1855 validdepth = 0;
1856
1857 /* get LP solver interface */
1858 lpi = SCIPlpGetLPI(lp);
1861
1862 if( !SCIPlpiIsPrimalInfeasible(lpi) )
1863 {
1864 SCIP_Real objval;
1865
1866 assert(!SCIPlpDivingObjChanged(lp));
1867
1868 /* make sure, a dual feasible solution exists, that exceeds the objective limit;
1869 * With FASTMIP setting, CPLEX does not apply the final pivot to reach the dual solution exceeding the objective
1870 * limit. Therefore, we have to either turn off FASTMIP and resolve the problem or continue solving it without
1871 * objective limit for at least one iteration. It seems that the strategy to continue with FASTMIP for one
1872 * additional simplex iteration yields better results.
1873 */
1874 SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
1875 if( objval < lp->lpiobjlim )
1876 {
1877 SCIP_RETCODE retcode;
1878
1879 /* temporarily disable objective limit and install an iteration limit */
1882
1883 /* start LP timer */
1885
1886 /* resolve LP */
1887 retcode = SCIPlpiSolveDual(lpi);
1888
1889 /* stop LP timer */
1891
1892 /* check return code of LP solving call */
1893 valid = (retcode != SCIP_LPERROR);
1894 if( valid )
1895 {
1896 int iter;
1897
1898 SCIP_CALL( retcode );
1899
1900 /* count number of LP iterations */
1901 SCIP_CALL( SCIPlpiGetIterations(lpi, &iter) );
1902 (*iterations) += iter;
1903 stat->nconflictlps++;
1904 stat->nconflictlpiterations += iter;
1905 SCIPsetDebugMsg(set, " -> resolved objlim exceeding LP in %d iterations (total: %" SCIP_LONGINT_FORMAT ") (infeasible:%u, objlim: %u, optimal:%u)\n",
1908 }
1909
1910 /* reinstall old objective and iteration limits in LP solver */
1913
1914 /* abort, if the LP produced an error */
1915 if( !valid )
1916 return SCIP_OKAY;
1917 }
1918 }
1920
1921 if( !SCIPlpiIsPrimalInfeasible(lpi) )
1922 {
1923 SCIP_Real objval;
1924
1925 assert(!SCIPlpDivingObjChanged(lp));
1926
1927 SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
1928 if( objval < lp->lpiobjlim )
1929 {
1930 SCIPsetDebugMsg(set, " -> LP does not exceed the cutoff bound: obj=%g, cutoff=%g\n", objval, lp->lpiobjlim);
1931 return SCIP_OKAY;
1932 }
1933 else
1934 {
1935 SCIPsetDebugMsg(set, " -> LP exceeds the cutoff bound: obj=%g, cutoff=%g\n", objval, lp->lpiobjlim);
1936 }
1937 }
1938
1939 assert(valid);
1940
1941 SCIP_CALL( SCIPaggrRowCreate(set->scip, &farkasrow) );
1942 SCIP_CALL( SCIPsetAllocBufferArray(set, &lbchginfoposs, transprob->nvars) );
1943 SCIP_CALL( SCIPsetAllocBufferArray(set, &ubchginfoposs, transprob->nvars) );
1944
1945 farkasactivity = 0.0;
1946
1947 /* get temporary memory for remembering variables' current bounds and corresponding bound change information
1948 * positions in variable's bound change information arrays
1949 */
1950 SCIP_CALL( SCIPsetAllocBufferArray(set, &curvarlbs, nvars) );
1951 SCIP_CALL( SCIPsetAllocBufferArray(set, &curvarubs, nvars) );
1952
1953 /* get current bounds and current positions in lb/ubchginfos arrays of variables */
1954 valid = TRUE;
1955 for( v = 0; v < nvars && valid; ++v )
1956 {
1957 SCIP_VAR* var;
1958
1959 var = vars[v];
1960
1961 curvarlbs[v] = SCIPvarGetLbLP(var, set);
1962 curvarubs[v] = SCIPvarGetUbLP(var, set);
1963 lbchginfoposs[v] = var->nlbchginfos-1;
1964 ubchginfoposs[v] = var->nubchginfos-1;
1965 assert(diving || SCIPsetIsEQ(set, curvarlbs[v], SCIPvarGetLbLocal(var)));
1966 assert(diving || SCIPsetIsEQ(set, curvarubs[v], SCIPvarGetUbLocal(var)));
1967
1968 /* check, if last bound changes were due to strong branching or diving */
1969 if( diving )
1970 {
1971 SCIP_Real lb;
1972 SCIP_Real ub;
1973
1974 lb = SCIPvarGetLbLocal(var);
1975 ub = SCIPvarGetUbLocal(var);
1976 if( SCIPsetIsGT(set, curvarlbs[v], lb) )
1977 lbchginfoposs[v] = var->nlbchginfos;
1978 else if( SCIPsetIsLT(set, curvarlbs[v], lb) )
1979 {
1980 /* the bound in the diving LP was relaxed -> the LP is not a subproblem of the current node -> abort! */
1981 /**@todo we could still analyze such a conflict, but we would have to take care with our data structures */
1982 valid = FALSE;
1983 }
1984 if( SCIPsetIsLT(set, curvarubs[v], ub) )
1985 ubchginfoposs[v] = var->nubchginfos;
1986 else if( SCIPsetIsGT(set, curvarubs[v], ub) )
1987 {
1988 /* the bound in the diving LP was relaxed -> the LP is not a subproblem of the current node -> abort! */
1989 /**@todo we could still analyze such a conflict, but we would have to take care with our data structures */
1990 valid = FALSE;
1991 }
1992 }
1993 }
1994
1995 if( !valid )
1996 goto TERMINATE;
1997
1998 /* the LP is prooven to be infeasible */
1999 if( SCIPlpiIsPrimalInfeasible(lpi) )
2000 {
2001 SCIP_CALL( SCIPgetFarkasProof(set, transprob, lp, lpi, tree, farkasrow, &farkasactivity, &validdepth,
2002 curvarlbs, curvarubs, &valid) );
2003 }
2004 /* the LP is dual feasible and/or exceeds the current incumbant solution */
2005 else
2006 {
2007 assert(SCIPlpiIsDualFeasible(lpi) || SCIPlpiIsObjlimExc(lpi));
2008 SCIP_CALL( SCIPgetDualProof(set, transprob, lp, lpi, tree, farkasrow, &farkasactivity, &validdepth,
2009 curvarlbs, curvarubs, &valid) );
2010 }
2011
2012 if( !valid || validdepth >= SCIPtreeGetCurrentDepth(tree) )
2013 goto TERMINATE;
2014
2015 globalinfeasible = FALSE;
2016
2017 /* start dual proof analysis */
2018 if( ((set->conf_useinflp == 'b' || set->conf_useinflp == 'd') && conflict->conflictset->conflicttype == SCIP_CONFTYPE_INFEASLP)
2019 || ((set->conf_useboundlp == 'b' || set->conf_useboundlp == 'd') && conflict->conflictset->conflicttype == SCIP_CONFTYPE_BNDEXCEEDING) )
2020 {
2021 /* start dual proof analysis */
2022 SCIP_CALL( SCIPconflictAnalyzeDualProof(conflict, set, stat, blkmem, origprob, transprob, tree, reopt, lp, farkasrow, \
2023 validdepth, curvarlbs, curvarubs, TRUE, &globalinfeasible, dualproofsuccess) );
2024 }
2025
2026 assert(valid);
2027
2028 /* todo: in theory, we could apply conflict graph analysis for locally valid proofs, too, but this needs to be implemented */
2029 if( !globalinfeasible && validdepth <= SCIPtreeGetEffectiveRootDepth(tree)
2030 && (((set->conf_useinflp == 'b' || set->conf_useinflp == 'c') && conflict->conflictset->conflicttype == SCIP_CONFTYPE_INFEASLP)
2031 || ((set->conf_useboundlp == 'b' || set->conf_useboundlp == 'c') && conflict->conflictset->conflicttype == SCIP_CONFTYPE_BNDEXCEEDING)) )
2032 {
2033 SCIP_Real* farkascoefs;
2034 SCIP_Real farkaslhs;
2035 int* inds;
2036 int nnz;
2037
2038#ifdef SCIP_DEBUG
2039 {
2040 SCIP_Real objlim;
2041 SCIPsetDebugMsg(set, "analyzing conflict on infeasible LP (infeasible: %u, objlimexc: %u, optimal:%u) in depth %d (diving: %u)\n",
2043
2045 SCIPsetDebugMsg(set, " -> objective limit in LP solver: %g (in LP: %g)\n", objlim, lp->lpiobjlim);
2046 }
2047#endif
2048
2049 SCIP_CALL( SCIPsetAllocBufferArray(set, &farkascoefs, SCIPprobGetNVars(transprob)) );
2050 BMSclearMemoryArray(farkascoefs, SCIPprobGetNVars(transprob));
2051
2052 farkaslhs = -SCIPaggrRowGetRhs(farkasrow);
2053 farkasactivity = -farkasactivity;
2054
2055 inds = SCIPaggrRowGetInds(farkasrow);
2056 nnz = SCIPaggrRowGetNNz(farkasrow);
2057
2058 for( v = 0; v < nnz; v++ )
2059 {
2060 int i = inds[v];
2061
2062 assert(SCIPvarGetProbindex(vars[i]) == inds[v]);
2063
2064 farkascoefs[i] = -SCIPaggrRowGetProbvarValue(farkasrow, i);
2065 }
2066
2067 SCIP_CALL( SCIPrunBoundHeuristic(conflict, set, stat, origprob, transprob, tree, reopt, lp, lpi, blkmem, farkascoefs,
2068 &farkaslhs, &farkasactivity, curvarlbs, curvarubs, lbchginfoposs, ubchginfoposs, iterations, marklpunsolved,
2069 dualproofsuccess, &valid) );
2070
2071 SCIPsetFreeBufferArray(set, &farkascoefs);
2072
2073 if( !valid )
2074 goto FLUSHPROOFSETS;
2075
2076 /* analyze the conflict starting with remaining bound changes */
2077 SCIP_CALL( SCIPconflictAnalyzeRemainingBdchgs(conflict, blkmem, set, stat, transprob, tree, diving, \
2078 lbchginfoposs, ubchginfoposs, nconss, nliterals, nreconvconss, nreconvliterals) );
2079
2080 /* flush conflict set storage */
2081 SCIP_CALL( SCIPconflictFlushConss(conflict, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, \
2082 eventqueue, cliquetable) );
2083 }
2084
2085 FLUSHPROOFSETS:
2086 /* flush proof set */
2087 if( SCIPproofsetGetNVars(conflict->proofset) > 0 || conflict->nproofsets > 0 )
2088 {
2089 SCIP_CALL( SCIPconflictFlushProofset(conflict, conflictstore, blkmem, set, stat, transprob, origprob, tree, reopt, lp, \
2090 branchcand, eventqueue, cliquetable) );
2091 }
2092
2093 TERMINATE:
2094 SCIPsetFreeBufferArray(set, &curvarubs);
2095 SCIPsetFreeBufferArray(set, &curvarlbs);
2096 SCIPsetFreeBufferArray(set, &ubchginfoposs);
2097 SCIPsetFreeBufferArray(set, &lbchginfoposs);
2098 SCIPaggrRowFree(set->scip, &farkasrow);
2099
2100 return SCIP_OKAY;
2101}
2102
2103
2104/*
2105 * infeasible strong branching conflict analysis
2106 */
2107
2108/** analyses infeasible strong branching sub problems for conflicts */
2110 SCIP_CONFLICT* conflict, /**< conflict analysis data */
2111 SCIP_CONFLICTSTORE* conflictstore, /**< conflict store */
2112 BMS_BLKMEM* blkmem, /**< block memory buffers */
2113 SCIP_SET* set, /**< global SCIP settings */
2114 SCIP_STAT* stat, /**< dynamic problem statistics */
2115 SCIP_PROB* transprob, /**< transformed problem */
2116 SCIP_PROB* origprob, /**< original problem */
2117 SCIP_TREE* tree, /**< branch and bound tree */
2118 SCIP_REOPT* reopt, /**< reoptimization data structure */
2119 SCIP_LP* lp, /**< LP data */
2120 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
2121 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2122 SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
2123 SCIP_COL* col, /**< LP column with at least one infeasible strong branching subproblem */
2124 SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
2125 * infeasible downwards branch, or NULL */
2126 SCIP_Bool* upconflict /**< pointer to store whether a conflict constraint was created for an
2127 * infeasible upwards branch, or NULL */
2128 )
2129{
2130 int* cstat;
2131 int* rstat;
2132 SCIP_RETCODE retcode;
2133 SCIP_Bool resolve;
2134 SCIP_Real oldlb;
2135 SCIP_Real oldub;
2136 SCIP_Real newlb;
2137 SCIP_Real newub;
2138 SCIP_Bool dualraysuccess;
2139 int iter;
2140 int nconss;
2141 int nliterals;
2142 int nreconvconss;
2143 int nreconvliterals;
2144
2145 assert(stat != NULL);
2146 assert(lp != NULL);
2147 assert(lp->flushed);
2148 assert(lp->solved);
2149 assert(SCIPprobAllColsInLP(transprob, set, lp)); /* LP conflict analysis is only valid, if all variables are known */
2150 assert(col != NULL);
2151 assert((col->sbdownvalid && SCIPsetIsGE(set, col->sbdown, lp->cutoffbound)
2152 && SCIPsetFeasCeil(set, col->primsol-1.0) >= col->lb - 0.5)
2153 || (col->sbupvalid && SCIPsetIsGE(set, col->sbup, lp->cutoffbound)
2154 && SCIPsetFeasFloor(set, col->primsol+1.0) <= col->ub + 0.5));
2155 assert(SCIPtreeGetCurrentDepth(tree) > 0);
2156
2157 if( downconflict != NULL )
2158 *downconflict = FALSE;
2159 if( upconflict != NULL )
2160 *upconflict = FALSE;
2161
2162 /* check, if infeasible LP conflict analysis is enabled */
2163 if( !set->conf_enable || !set->conf_usesb )
2164 return SCIP_OKAY;
2165
2166 /* check, if there are any conflict handlers to use a conflict set */
2167 if( set->nconflicthdlrs == 0 )
2168 return SCIP_OKAY;
2169
2170 /* inform the LPI that strong branch is (temporarily) finished */
2172
2173 /* start timing */
2174 SCIPclockStart(conflict->sbanalyzetime, set);
2175
2176 /* get temporary memory for storing current LP basis */
2179
2180 /* get current LP basis */
2181 SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
2182
2183 /* remember old bounds */
2184 oldlb = col->lb;
2185 oldub = col->ub;
2186
2187 resolve = FALSE;
2188
2189 /* is down branch infeasible? */
2190 if( col->sbdownvalid && SCIPsetIsGE(set, col->sbdown, lp->cutoffbound) )
2191 {
2192 newub = SCIPsetFeasCeil(set, col->primsol-1.0);
2193 if( newub >= col->lb - 0.5 )
2194 {
2195 SCIPsetDebugMsg(set, "analyzing conflict on infeasible downwards strongbranch for variable <%s>[%g,%g] in depth %d\n",
2198
2200 conflict->nsbcalls++;
2201
2202 /* change the upper bound */
2203 col->ub = newub;
2204 SCIP_CALL( SCIPlpiChgBounds(lp->lpi, 1, &col->lpipos, &col->lb, &col->ub) );
2205
2206 /* start LP timer */
2208
2209 /* resolve the LP */
2210 retcode = SCIPlpiSolveDual(lp->lpi);
2211
2212 /* stop LP timer */
2214
2215 /* check return code of LP solving call */
2216 if( retcode != SCIP_LPERROR )
2217 {
2218 SCIP_CALL( retcode );
2219 }
2220
2221 if( retcode != SCIP_LPERROR && SCIPlpiIsStable(lp->lpi) )
2222 {
2223 /* count number of LP iterations */
2224 SCIP_CALL( SCIPlpiGetIterations(lp->lpi, &iter) );
2225 stat->nconflictlps++;
2226 stat->nconflictlpiterations += iter;
2227 conflict->nsbiterations += iter;
2228 SCIPsetDebugMsg(set, " -> resolved downwards strong branching LP in %d iterations\n", iter);
2229
2230 /* perform conflict analysis on infeasible LP; last parameter guarantees status 'solved' on return */
2231 SCIP_CALL( conflictAnalyzeLP(conflict, conflictstore, blkmem, set, stat, transprob, origprob, tree, reopt, \
2232 lp, branchcand, eventqueue, cliquetable, TRUE, &dualraysuccess, &iter, &nconss, &nliterals, \
2233 &nreconvconss, &nreconvliterals, FALSE) );
2234 conflict->nsbsuccess += ((nconss > 0 || dualraysuccess) ? 1 : 0);
2235 conflict->nsbiterations += iter;
2236 conflict->nsbconfconss += nconss;
2237 conflict->nsbconfliterals += nliterals;
2238 conflict->nsbreconvconss += nreconvconss;
2239 conflict->nsbreconvliterals += nreconvliterals;
2240 if( downconflict != NULL )
2241 *downconflict = (nconss > 0);
2242 }
2243
2244 /* reset the upper bound */
2245 col->ub = oldub;
2246 SCIP_CALL( SCIPlpiChgBounds(lp->lpi, 1, &col->lpipos, &col->lb, &col->ub) );
2247
2248 /* reset LP basis */
2249 SCIP_CALL( SCIPlpiSetBase(lp->lpi, cstat, rstat) );
2250
2251 /* mark the LP to be resolved at the end */
2252 resolve = TRUE;
2253 }
2254 }
2255
2256 /* is up branch infeasible? */
2257 if( col->sbupvalid && SCIPsetIsGE(set, col->sbup, lp->cutoffbound) )
2258 {
2259 newlb = SCIPsetFeasFloor(set, col->primsol+1.0);
2260 if( newlb <= col->ub + 0.5 )
2261 {
2262 SCIPsetDebugMsg(set, "analyzing conflict on infeasible upwards strongbranch for variable <%s>[%g,%g] in depth %d\n",
2265
2267 conflict->nsbcalls++;
2268
2269 /* change the lower bound */
2270 col->lb = newlb;
2271 SCIP_CALL( SCIPlpiChgBounds(lp->lpi, 1, &col->lpipos, &col->lb, &col->ub) );
2272
2273 /* start LP timer */
2275
2276 /* resolve the LP */
2277 retcode = SCIPlpiSolveDual(lp->lpi);
2278
2279 /* stop LP timer */
2281
2282 /* check return code of LP solving call */
2283 if( retcode != SCIP_LPERROR )
2284 {
2285 SCIP_CALL( retcode );
2286 }
2287
2288 if( retcode != SCIP_LPERROR && SCIPlpiIsStable(lp->lpi) )
2289 {
2290 /* count number of LP iterations */
2291 SCIP_CALL( SCIPlpiGetIterations(lp->lpi, &iter) );
2292 stat->nconflictlps++;
2293 stat->nconflictlpiterations += iter;
2294 conflict->nsbiterations += iter;
2295 SCIPsetDebugMsg(set, " -> resolved upwards strong branching LP in %d iterations\n", iter);
2296
2297 /* perform conflict analysis on infeasible LP; last parameter guarantees status 'solved' on return */
2298 SCIP_CALL( conflictAnalyzeLP(conflict, conflictstore, blkmem, set, stat, transprob, origprob, tree, reopt, \
2299 lp, branchcand, eventqueue, cliquetable, TRUE, &dualraysuccess, &iter, &nconss, &nliterals, \
2300 &nreconvconss, &nreconvliterals, FALSE) );
2301 conflict->nsbsuccess += ((nconss > 0 || dualraysuccess) ? 1 : 0);
2302 conflict->nsbiterations += iter;
2303 conflict->nsbconfconss += nconss;
2304 conflict->nsbconfliterals += nliterals;
2305 conflict->nsbreconvconss += nreconvconss;
2306 conflict->nsbreconvliterals += nreconvliterals;
2307 if( upconflict != NULL )
2308 *upconflict = (nconss > 0);
2309 }
2310
2311 /* reset the lower bound */
2312 col->lb = oldlb;
2313 SCIP_CALL( SCIPlpiChgBounds(lp->lpi, 1, &col->lpipos, &col->lb, &col->ub) );
2314
2315 /* reset LP basis */
2316 SCIP_CALL( SCIPlpiSetBase(lp->lpi, cstat, rstat) );
2317
2318 /* mark the LP to be resolved at the end */
2319 resolve = TRUE;
2320 }
2321 }
2322
2323 /* free temporary memory for storing current LP basis */
2324 SCIPsetFreeBufferArray(set, &rstat);
2325 SCIPsetFreeBufferArray(set, &cstat);
2326
2327 assert(lp->flushed);
2328
2329 /* resolve LP if something has changed in order to synchronize LPI and LP */
2330 if ( resolve )
2331 {
2332 /* start LP timer */
2334
2335 /* resolve the LP */
2337
2338 /* stop LP timer */
2340 }
2341
2342 /* stop timing */
2343 SCIPclockStop(conflict->sbanalyzetime, set);
2344
2345 /* inform the LPI that strong branch starts (again) */
2347
2348 return SCIP_OKAY;
2349}
2350
2351/** analyzes an infeasible LP to find out the bound changes on variables that were responsible for the infeasibility;
2352 * on success, calls standard conflict analysis with the responsible variables as starting conflict set, thus creating
2353 * a conflict constraint out of the resulting conflict set;
2354 * updates statistics for infeasible LP conflict analysis
2355 */
2356static
2358 SCIP_CONFLICT* conflict, /**< conflict analysis data */
2359 SCIP_CONFLICTSTORE* conflictstore, /**< conflict store */
2360 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
2361 SCIP_SET* set, /**< global SCIP settings */
2362 SCIP_STAT* stat, /**< problem statistics */
2363 SCIP_PROB* transprob, /**< transformed problem */
2364 SCIP_PROB* origprob, /**< original problem */
2365 SCIP_TREE* tree, /**< branch and bound tree */
2366 SCIP_REOPT* reopt, /**< reoptimization data structure */
2367 SCIP_LP* lp, /**< LP data */
2368 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
2369 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2370 SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
2371 SCIP_Bool* success /**< pointer to store whether a conflict constraint was created, or NULL */
2372 )
2373{
2374 SCIP_Bool dualraysuccess = FALSE;
2375 SCIP_Longint olddualproofsuccess;
2376 int iterations;
2377 int nconss;
2378 int nliterals;
2379 int nreconvconss;
2380 int nreconvliterals;
2381
2382 assert(conflict != NULL);
2383 assert(set != NULL);
2384 assert(lp != NULL);
2385 assert(SCIPprobAllColsInLP(transprob, set, lp)); /* LP conflict analysis is only valid, if all variables are known */
2386
2387 assert(success == NULL || *success == FALSE);
2388
2389 /* check, if infeasible LP conflict analysis is enabled */
2390 if( !set->conf_enable || set->conf_useinflp == 'o' )
2391 return SCIP_OKAY;
2392
2393 /* check, if there are any conflict handlers to use a conflict set */
2394 if( set->nconflicthdlrs == 0 )
2395 return SCIP_OKAY;
2396
2397 SCIPsetDebugMsg(set, "analyzing conflict on infeasible LP in depth %d (solstat: %d, objchanged: %u)\n",
2399
2400 /* start timing */
2402 conflict->ninflpcalls++;
2403
2405
2406 olddualproofsuccess = conflict->ndualproofsinfsuccess;
2407
2408 /* perform conflict analysis */
2409 SCIP_CALL( conflictAnalyzeLP(conflict, conflictstore, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, eventqueue, \
2410 cliquetable, SCIPlpDiving(lp), &dualraysuccess, &iterations, &nconss, &nliterals, &nreconvconss, &nreconvliterals, TRUE) );
2411 conflict->ninflpsuccess += ((nconss > 0 || conflict->ndualproofsinfsuccess > olddualproofsuccess) ? 1 : 0);
2412 conflict->ninflpiterations += iterations;
2413 conflict->ninflpconfconss += nconss;
2414 conflict->ninflpconfliterals += nliterals;
2415 conflict->ninflpreconvconss += nreconvconss;
2416 conflict->ninflpreconvliterals += nreconvliterals;
2417 if( success != NULL )
2418 *success = (nconss > 0 || conflict->ndualproofsinfsuccess > olddualproofsuccess);
2419
2420 /* stop timing */
2422
2423 return SCIP_OKAY;
2424}
2425
2426/** analyzes a bound exceeding LP to find out the bound changes on variables that were responsible for exceeding the
2427 * primal bound;
2428 * on success, calls standard conflict analysis with the responsible variables as starting conflict set, thus creating
2429 * a conflict constraint out of the resulting conflict set;
2430 * updates statistics for bound exceeding LP conflict analysis
2431 */
2432static
2434 SCIP_CONFLICT* conflict, /**< conflict analysis data */
2435 SCIP_CONFLICTSTORE* conflictstore, /**< conflict store */
2436 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
2437 SCIP_SET* set, /**< global SCIP settings */
2438 SCIP_STAT* stat, /**< problem statistics */
2439 SCIP_PROB* transprob, /**< transformed problem */
2440 SCIP_PROB* origprob, /**< original problem */
2441 SCIP_TREE* tree, /**< branch and bound tree */
2442 SCIP_REOPT* reopt, /**< reoptimization data structure */
2443 SCIP_LP* lp, /**< LP data */
2444 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
2445 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2446 SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
2447 SCIP_Bool* success /**< pointer to store whether a conflict constraint was created, or NULL */
2448 )
2449{
2450 SCIP_Bool dualraysuccess;
2451 SCIP_Longint oldnsuccess;
2452 int iterations;
2453 int nconss;
2454 int nliterals;
2455 int nreconvconss;
2456 int nreconvliterals;
2457
2458 assert(conflict != NULL);
2459 assert(set != NULL);
2460 assert(lp != NULL);
2461 assert(!SCIPlpDivingObjChanged(lp));
2462 assert(SCIPprobAllColsInLP(transprob, set, lp)); /* LP conflict analysis is only valid, if all variables are known */
2463
2464 assert(success == NULL || *success == FALSE);
2465
2466 /* check, if bound exceeding LP conflict analysis is enabled */
2467 if( !set->conf_enable || set->conf_useboundlp == 'o')
2468 return SCIP_OKAY;
2469
2470 /* check, if there are any conflict handlers to use a conflict set */
2471 if( set->nconflicthdlrs == 0 )
2472 return SCIP_OKAY;
2473
2474 SCIPsetDebugMsg(set, "analyzing conflict on bound exceeding LP in depth %d (solstat: %d)\n",
2476
2477 /* start timing */
2479 conflict->nboundlpcalls++;
2480
2481 /* mark the conflict to depend on the cutoff bound */
2483 conflict->conflictset->usescutoffbound = TRUE;
2484
2485 oldnsuccess = conflict->ndualproofsbndsuccess + conflict->ndualproofsinfsuccess;
2486
2487 /* perform conflict analysis */
2488 SCIP_CALL( conflictAnalyzeLP(conflict, conflictstore, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, eventqueue, \
2489 cliquetable, SCIPlpDiving(lp), &dualraysuccess, &iterations, &nconss, &nliterals, &nreconvconss, &nreconvliterals, TRUE) );
2490 conflict->nboundlpsuccess += ((nconss > 0 || conflict->ndualproofsbndsuccess + conflict->ndualproofsinfsuccess > oldnsuccess) ? 1 : 0);
2491 conflict->nboundlpiterations += iterations;
2492 conflict->nboundlpconfconss += nconss;
2493 conflict->nboundlpconfliterals += nliterals;
2494 conflict->nboundlpreconvconss += nreconvconss;
2495 conflict->nboundlpreconvliterals += nreconvliterals;
2496 if( success != NULL )
2497 *success = (nconss > 0 || conflict->ndualproofsbndsuccess + conflict->ndualproofsinfsuccess > oldnsuccess);
2498
2499 /* stop timing */
2501
2502 return SCIP_OKAY;
2503}
2504
2505/** analyzes an infeasible or bound exceeding LP to find out the bound changes on variables that were responsible for the
2506 * infeasibility or for exceeding the primal bound;
2507 * on success, calls standard conflict analysis with the responsible variables as starting conflict set, thus creating
2508 * a conflict constraint out of the resulting conflict set;
2509 * updates statistics for infeasible or bound exceeding LP conflict analysis;
2510 * may only be called if SCIPprobAllColsInLP()
2511 */
2513 SCIP_CONFLICT* conflict, /**< conflict analysis data */
2514 SCIP_CONFLICTSTORE* conflictstore, /**< conflict store */
2515 BMS_BLKMEM* blkmem, /**< block memory of transformed problem */
2516 SCIP_SET* set, /**< global SCIP settings */
2517 SCIP_STAT* stat, /**< problem statistics */
2518 SCIP_PROB* transprob, /**< transformed problem */
2519 SCIP_PROB* origprob, /**< original problem */
2520 SCIP_TREE* tree, /**< branch and bound tree */
2521 SCIP_REOPT* reopt, /**< reoptimization data structure */
2522 SCIP_LP* lp, /**< LP data */
2523 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
2524 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2525 SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
2526 SCIP_Bool* success /**< pointer to store whether a conflict constraint was created, or NULL */
2527 )
2528{
2529 SCIP_LPSOLVALS storedsolvals;
2530 SCIP_COLSOLVALS* storedcolsolvals;
2531 SCIP_ROWSOLVALS* storedrowsolvals;
2532 int c;
2533 int r;
2534
2535 if( success != NULL )
2536 *success = FALSE;
2537
2538 /* check if the conflict analysis is applicable */
2539 if( !set->conf_enable || (set->conf_useinflp == 'o' && set->conf_useboundlp == 'o') )
2540 return SCIP_OKAY;
2541
2542 /* in rare cases, it might happen that the solution stati of the LP and the LPI are out of sync; in particular this
2543 * happens when a new incumbent which cuts off the current node is found during the LP solving loop; in this case the
2544 * LP has status objlimit, but if diving has been used, the LPI only has the basis information, but is not solved
2545 *
2546 * @todo: alternatively, solve the LPI
2547 */
2548 if( !SCIPlpiWasSolved(SCIPlpGetLPI(lp)) )
2549 return SCIP_OKAY;
2550
2551 /* LP conflict analysis is only valid, if all variables are known */
2552 assert( SCIPprobAllColsInLP(transprob, set, lp) );
2554 || (SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OPTIMAL && set->lp_disablecutoff == 1) );
2555
2556 /* save status */
2557 storedsolvals.lpsolstat = lp->lpsolstat;
2558 storedsolvals.lpobjval = lp->lpobjval;
2559 storedsolvals.primalfeasible = lp->primalfeasible;
2560 storedsolvals.primalchecked = lp->primalchecked;
2561 storedsolvals.dualfeasible = lp->dualfeasible;
2562 storedsolvals.dualchecked = lp->dualchecked;
2563 storedsolvals.solisbasic = lp->solisbasic;
2564 storedsolvals.lpissolved = lp->solved;
2565
2566 /* store solution values */
2567 SCIP_CALL( SCIPsetAllocBufferArray(set, &storedcolsolvals, lp->ncols) );
2568 SCIP_CALL( SCIPsetAllocBufferArray(set, &storedrowsolvals, lp->nrows) );
2569 for (c = 0; c < lp->ncols; ++c)
2570 {
2571 SCIP_COL* col;
2572
2573 col = lp->cols[c];
2574 assert( col != NULL );
2575
2576 storedcolsolvals[c].primsol = col->primsol;
2577 storedcolsolvals[c].redcost = col->redcost;
2578 storedcolsolvals[c].basisstatus = col->basisstatus; /*lint !e641 !e732*/
2579 }
2580 for (r = 0; r < lp->nrows; ++r)
2581 {
2582 SCIP_ROW* row;
2583
2584 row = lp->rows[r];
2585 assert( row != NULL );
2586
2588 storedrowsolvals[r].dualsol = row->dualfarkas;
2589 else
2590 {
2591 assert( lp->lpsolstat == SCIP_LPSOLSTAT_OBJLIMIT ||
2592 (SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OPTIMAL && set->lp_disablecutoff == 1) );
2593 storedrowsolvals[r].dualsol = row->dualsol;
2594 }
2595 storedrowsolvals[r].activity = row->activity;
2596 storedrowsolvals[r].basisstatus = row->basisstatus; /*lint !e641 !e732*/
2597 }
2598
2599 /* check, if the LP was infeasible or bound exceeding */
2601 {
2602 SCIP_CALL( conflictAnalyzeInfeasibleLP(conflict, conflictstore, blkmem, set, stat, transprob, origprob, tree, \
2603 reopt, lp, branchcand, eventqueue, cliquetable, success) );
2604 }
2605 else
2606 {
2607 SCIP_CALL( conflictAnalyzeBoundexceedingLP(conflict, conflictstore, blkmem, set, stat, transprob, origprob, tree, \
2608 reopt, lp, branchcand, eventqueue, cliquetable, success) );
2609 }
2610
2611 /* possibly restore solution values */
2613 {
2614 /* restore status */
2615 lp->lpsolstat = storedsolvals.lpsolstat;
2616 lp->lpobjval = storedsolvals.lpobjval;
2617 lp->primalfeasible = storedsolvals.primalfeasible;
2618 lp->primalchecked = storedsolvals.primalchecked;
2619 lp->dualfeasible = storedsolvals.dualfeasible;
2620 lp->dualchecked = storedsolvals.dualchecked;
2621 lp->solisbasic = storedsolvals.solisbasic;
2622 lp->solved = storedsolvals.lpissolved;
2623
2624 for (c = 0; c < lp->ncols; ++c)
2625 {
2626 SCIP_COL* col;
2627
2628 col = lp->cols[c];
2629 assert( col != NULL );
2630 col->primsol = storedcolsolvals[c].primsol;
2631 col->redcost = storedcolsolvals[c].redcost;
2632 col->basisstatus = storedcolsolvals[c].basisstatus; /*lint !e641 !e732*/
2633 }
2634 for (r = 0; r < lp->nrows; ++r)
2635 {
2636 SCIP_ROW* row;
2637
2638 row = lp->rows[r];
2639 assert( row != NULL );
2640
2642 row->dualfarkas = storedrowsolvals[r].dualsol;
2643 else
2644 {
2645 assert( lp->lpsolstat == SCIP_LPSOLSTAT_OBJLIMIT );
2646 row->dualsol = storedrowsolvals[r].dualsol;
2647 }
2648 row->activity = storedrowsolvals[r].activity;
2649 row->basisstatus = storedrowsolvals[r].basisstatus; /*lint !e641 !e732*/
2650 }
2651 }
2652 SCIPsetFreeBufferArray(set, &storedrowsolvals);
2653 SCIPsetFreeBufferArray(set, &storedcolsolvals);
2654
2655 return SCIP_OKAY;
2656}
SCIP_Real * r
Definition: circlepacking.c:59
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 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
internal methods for conflict analysis
void SCIPproofsetFree(SCIP_PROOFSET **proofset, BMS_BLKMEM *blkmem)
SCIP_RETCODE SCIPconflictInitProofset(SCIP_CONFLICT *conflict, BMS_BLKMEM *blkmem)
SCIP_RETCODE SCIPconflictAnalyzeDualProof(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)
SCIP_RETCODE SCIPconflictFlushProofset(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)
int SCIPproofsetGetNVars(SCIP_PROOFSET *proofset)
int SCIPconflictGetNConflicts(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNAppliedGlobalConss(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNDualproofsInfLocal(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNAppliedLocalLiterals(SCIP_CONFLICT *conflict)
#define SOLSTOP
SCIP_Longint SCIPconflictGetNPropCalls(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNDualproofsInfNonzeros(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNStrongbranchIterations(SCIP_CONFLICT *conflict)
SCIP_Real SCIPconflictGetInfeasibleLPTime(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNInfeasibleLPCalls(SCIP_CONFLICT *conflict)
SCIP_RETCODE SCIPgetFarkasProof(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)
SCIP_RETCODE SCIPconflictCreate(SCIP_CONFLICT **conflict, BMS_BLKMEM *blkmem, SCIP_SET *set)
SCIP_Real SCIPconflictGetGlobalApplTime(SCIP_CONFLICT *conflict)
SCIP_RETCODE SCIPgetDualProof(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)
SCIP_Longint SCIPconflictGetNInfeasibleLPSuccess(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNBoundexceedingLPReconvergenceConss(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNGlobalChgBds(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNAppliedLiterals(SCIP_CONFLICT *conflict)
static SCIP_Bool checkDualFeasibility(SCIP_SET *set, SCIP_ROW *row, SCIP_Real weight, SCIP_Bool *zerocontribution)
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)
SCIP_Longint SCIPconflictGetNPropConflictLiterals(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNAppliedConss(SCIP_CONFLICT *conflict)
static SCIP_DECL_SORTPTRCOMP(conflictBdchginfoComp)
SCIP_Longint SCIPconflictGetNInfeasibleLPConflictConss(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNBoundexceedingLPConflictConss(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNBoundexceedingLPSuccess(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNStrongbranchCalls(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNInfeasibleLPReconvergenceLiterals(SCIP_CONFLICT *conflict)
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)
SCIP_Longint SCIPconflictGetNPropReconvergenceConss(SCIP_CONFLICT *conflict)
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)
SCIP_Real SCIPconflictGetBoundexceedingLPTime(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNStrongbranchReconvergenceLiterals(SCIP_CONFLICT *conflict)
SCIP_Real SCIPconflictGetPseudoTime(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNPseudoReconvergenceLiterals(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNPropReconvergenceLiterals(SCIP_CONFLICT *conflict)
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)
SCIP_Longint SCIPconflictGetNInfeasibleLPReconvergenceConss(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNAppliedLocalConss(SCIP_CONFLICT *conflict)
static SCIP_RETCODE sortLocalRows(SCIP_SET *set, SCIP_AGGRROW *aggrrow, SCIP_ROW **rows, int *rowinds, int *rowdepth, int nrows)
SCIP_Longint SCIPconflictGetNStrongbranchReconvergenceConss(SCIP_CONFLICT *conflict)
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)
SCIP_Real SCIPconflictGetVarUb(SCIP_CONFLICT *conflict, SCIP_VAR *var)
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)
SCIP_Longint SCIPconflictGetNBoundexceedingLPConflictLiterals(SCIP_CONFLICT *conflict)
#define NUMSTOP
SCIP_Real SCIPconflictGetStrongbranchTime(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNPseudoSuccess(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNInfeasibleLPConflictLiterals(SCIP_CONFLICT *conflict)
SCIP_Real SCIPaggrRowGetMinActivity(SCIP_SET *set, SCIP_PROB *transprob, SCIP_AGGRROW *aggrrow, SCIP_Real *curvarlbs, SCIP_Real *curvarubs, SCIP_Bool *infdelta)
SCIP_Longint SCIPconflictGetNPseudoConflictLiterals(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNLocalChgBds(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNDualproofsBndSuccess(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNPropSuccess(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNDualproofsInfSuccess(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNBoundexceedingLPCalls(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNPropConflictConss(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNStrongbranchSuccess(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNDualproofsBndGlobal(SCIP_CONFLICT *conflict)
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)
SCIP_Longint SCIPconflictGetNPseudoReconvergenceConss(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNAppliedGlobalLiterals(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNDualproofsBndLocal(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNPseudoCalls(SCIP_CONFLICT *conflict)
void SCIPconflictEnableOrDisableClocks(SCIP_CONFLICT *conflict, SCIP_Bool enable)
SCIP_Real SCIPconflictGetPropTime(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNBoundexceedingLPIterations(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNStrongbranchConflictLiterals(SCIP_CONFLICT *conflict)
static SCIP_RETCODE addRowToAggrRow(SCIP_SET *set, SCIP_ROW *row, SCIP_Real weight, SCIP_AGGRROW *aggrrow)
SCIP_Longint SCIPconflictGetNPseudoConflictConss(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNDualproofsBndNonzeros(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNDualproofsInfGlobal(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNBoundexceedingLPReconvergenceLiterals(SCIP_CONFLICT *conflict)
SCIP_RETCODE SCIPconflictFree(SCIP_CONFLICT **conflict, BMS_BLKMEM *blkmem)
SCIP_Real SCIPconflictGetVarLb(SCIP_CONFLICT *conflict, SCIP_VAR *var)
SCIP_Longint SCIPconflictGetNStrongbranchConflictConss(SCIP_CONFLICT *conflict)
SCIP_Longint SCIPconflictGetNInfeasibleLPIterations(SCIP_CONFLICT *conflict)
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)
void SCIPconflictsetFree(SCIP_CONFLICTSET **conflictset, BMS_BLKMEM *blkmem)
SCIP_RETCODE SCIPconflictAnalyzeRemainingBdchgs(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)
SCIP_RETCODE SCIPrunBoundHeuristic(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)
SCIP_RETCODE SCIPundoBdchgsProof(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)
SCIP_RETCODE SCIPconflictsetCreate(SCIP_CONFLICTSET **conflictset, BMS_BLKMEM *blkmem)
internal methods for storing conflicts
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 QUAD_ASSIGN(a, constant)
Definition: dbldblarith.h:51
#define QUAD(x)
Definition: dbldblarith.h:47
#define SCIPquadprecSumQQ(r, a, b)
Definition: dbldblarith.h:67
#define QUAD_TO_DBL(x)
Definition: dbldblarith.h:49
#define NULL
Definition: def.h:262
#define EPSGE(x, y, eps)
Definition: def.h:201
#define SCIP_Longint
Definition: def.h:157
#define SCIP_Bool
Definition: def.h:91
#define EPSLE(x, y, eps)
Definition: def.h:199
#define SCIP_ALLOC(x)
Definition: def.h:380
#define SCIP_Real
Definition: def.h:172
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define SCIP_LONGINT_FORMAT
Definition: def.h:164
#define REALABS(x)
Definition: def.h:196
#define SCIP_CALL(x)
Definition: def.h:369
SCIP_RETCODE SCIPlpiGetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
Definition: lpi_clp.cpp:3824
SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:3947
SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2718
SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
Definition: lpi_clp.cpp:2995
SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
Definition: lpi_clp.cpp:3861
SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
Definition: lpi_clp.cpp:2885
SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
Definition: lpi_clp.cpp:2794
SCIP_RETCODE SCIPlpiStartStrongbranch(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2034
SCIP_RETCODE SCIPlpiChgBounds(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
Definition: lpi_clp.cpp:1096
SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2637
SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
Definition: lpi_clp.cpp:3720
SCIP_RETCODE SCIPlpiSetBase(SCIP_LPI *lpi, const int *cstat, const int *rstat)
Definition: lpi_clp.cpp:3095
SCIP_Bool SCIPlpiWasSolved(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2414
SCIP_Bool SCIPlpiIsOptimal(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2651
SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2046
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:2816
SCIP_Bool SCIPlpiHasDualRay(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2584
SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2530
SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:1908
SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
Definition: lpi_clp.cpp:2949
SCIP_Bool SCIPlpiIsStable(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2675
void SCIPpqueueFree(SCIP_PQUEUE **pqueue)
Definition: misc.c:1325
SCIP_RETCODE SCIPpqueueCreate(SCIP_PQUEUE **pqueue, int initsize, SCIP_Real sizefac, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), SCIP_DECL_PQUEUEELEMCHGPOS((*elemchgpos)))
Definition: misc.c:1298
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
Definition: lp.c:17071
SCIP_RETCODE SCIPaggrRowCreate(SCIP *scip, SCIP_AGGRROW **aggrrow)
Definition: cuts.c:1723
void SCIPaggrRowClear(SCIP_AGGRROW *aggrrow)
Definition: cuts.c:2133
SCIP_Real SCIPaggrRowGetRhs(SCIP_AGGRROW *aggrrow)
Definition: cuts.c:2581
void SCIPaggrRowFree(SCIP *scip, SCIP_AGGRROW **aggrrow)
Definition: cuts.c:1755
int * SCIPaggrRowGetInds(SCIP_AGGRROW *aggrrow)
Definition: cuts.c:2541
void SCIPaggrRowRemoveZeros(SCIP *scip, SCIP_AGGRROW *aggrrow, SCIP_Bool useglbbounds, SCIP_Bool *valid)
Definition: cuts.c:2471
int SCIPaggrRowGetNNz(SCIP_AGGRROW *aggrrow)
Definition: cuts.c:2551
SCIP_RETCODE SCIPaggrRowAddRow(SCIP *scip, SCIP_AGGRROW *aggrrow, SCIP_ROW *row, SCIP_Real weight, int sidetype)
Definition: cuts.c:1859
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:2004
#define SCIPfreeBufferArrayNull(scip, ptr)
Definition: scip_mem.h:137
int SCIProwGetLPDepth(SCIP_ROW *row)
Definition: lp.c:17541
const char * SCIProwGetName(SCIP_ROW *row)
Definition: lp.c:17380
SCIP_Bool SCIPbdchginfoIsRedundant(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:18826
SCIP_BDCHGIDX * SCIPbdchginfoGetIdx(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:18748
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:18162
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17944
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:18106
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:17786
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17437
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:18152
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:18096
SCIP_Bool SCIPbdchgidxIsEarlierNonNull(SCIP_BDCHGIDX *bdchgidx1, SCIP_BDCHGIDX *bdchgidx2)
Definition: var.c:18638
void SCIPsortIntInt(int *intarray1, int *intarray2, int len)
void SCIPsortIntIntInt(int *intarray1, int *intarray2, int *intarray3, int len)
internal methods for branching and inference history
SCIP_Bool SCIPlpDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:17886
SCIP_LPSOLSTAT SCIPlpGetSolstat(SCIP_LP *lp)
Definition: lp.c:13114
SCIP_LPI * SCIPlpGetLPI(SCIP_LP *lp)
Definition: lp.c:17803
SCIP_Bool SCIPlpDiving(SCIP_LP *lp)
Definition: lp.c:17876
int SCIPlpGetNCols(SCIP_LP *lp)
Definition: lp.c:17604
SCIP_ROW ** SCIPlpGetRows(SCIP_LP *lp)
Definition: lp.c:17641
int SCIPlpGetNRows(SCIP_LP *lp)
Definition: lp.c:17651
SCIP_Real SCIPlpGetPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13313
internal methods for LP management
interface methods for specific LP solvers
#define BMSfreeMemory(ptr)
Definition: memory.h:145
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:130
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:437
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:148
#define BMSallocMemory(ptr)
Definition: memory.h:118
methods commonly used for presolving
SCIP_Bool SCIPprobIsObjIntegral(SCIP_PROB *prob)
Definition: prob.c:2346
int SCIPprobGetNVars(SCIP_PROB *prob)
Definition: prob.c:2401
SCIP_VAR ** SCIPprobGetVars(SCIP_PROB *prob)
Definition: prob.c:2446
SCIP_Bool SCIPprobAllColsInLP(SCIP_PROB *prob, SCIP_SET *set, SCIP_LP *lp)
Definition: prob.c:2358
internal methods for storing and manipulating the main problem
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
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:6918
SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6293
SCIP_Real SCIPsetFeasCeil(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6775
SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6663
SCIP_Bool SCIPsetIsFeasLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6641
SCIP_Bool SCIPsetIsFeasEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6597
SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6257
SCIP_Real SCIPsetFeasFloor(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6764
SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6221
SCIP_Real SCIPsetInfinity(SCIP_SET *set)
Definition: set.c:6064
SCIP_Bool SCIPsetIsLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6239
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6199
SCIP_Bool SCIPsetIsGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6275
SCIP_Bool SCIPsetIsZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6311
SCIP_Real SCIPsetCutoffbounddelta(SCIP_SET *set)
Definition: set.c:6164
internal methods for global SCIP settings
#define SCIPsetFreeBufferArray(set, ptr)
Definition: set.h:1755
#define SCIPsetAllocBufferArray(set, ptr, num)
Definition: set.h:1748
#define SCIPsetDebugMsg
Definition: set.h:1784
internal methods for storing primal CIP solutions
SCIP_Real primsol
Definition: struct_lp.h:95
unsigned int basisstatus
Definition: struct_lp.h:97
SCIP_Real redcost
Definition: struct_lp.h:96
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
SCIP_CONFTYPE conflicttype
unsigned int usescutoffbound
SCIP_Longint ninflpiterations
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_Longint ndualproofsinflocal
SCIP_Longint npseudoconfconss
SCIP_Longint nboundlpcalls
SCIP_Longint nappliedglbliterals
SCIP_Longint nboundlpreconvliterals
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_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_Longint npropconfliterals
SCIP_Longint ninflpreconvliterals
SCIP_CONFLICTSET * conflictset
SCIP_Longint ndualproofsbndlocal
SCIP_Longint nappliedlocliterals
SCIP_Longint npropreconvconss
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 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_LPI * lpi
Definition: struct_lp.h:296
SCIP_Bool flushed
Definition: struct_lp.h:366
SCIP_Real lpiobjlim
Definition: struct_lp.h:286
SCIP_VAR ** vars
Definition: struct_prob.h:64
SCIP_Real activity
Definition: struct_lp.h:108
unsigned int basisstatus
Definition: struct_lp.h:109
SCIP_Real dualsol
Definition: struct_lp.h:107
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
int len
Definition: struct_lp.h:235
SCIP_Longint nconflictlps
Definition: struct_stat.h:213
SCIP_Longint nconflictlpiterations
Definition: struct_stat.h:79
SCIP_CLOCK * conflictlptime
Definition: struct_stat.h:171
int nubchginfos
Definition: struct_var.h:269
int conflictubcount
Definition: struct_var.h:271
SCIP_Real conflictrelaxedub
Definition: struct_var.h:222
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
Definition: heur_padm.c:135
int SCIPtreeGetFocusDepth(SCIP_TREE *tree)
Definition: tree.c:8448
int SCIPtreeGetEffectiveRootDepth(SCIP_TREE *tree)
Definition: tree.c:8562
int SCIPtreeGetCurrentDepth(SCIP_TREE *tree)
Definition: tree.c:8523
internal methods for branch and bound tree
@ SCIP_CLOCKTYPE_DEFAULT
Definition: type_clock.h:43
@ SCIP_CONFTYPE_BNDEXCEEDING
Definition: type_conflict.h:62
@ SCIP_CONFTYPE_INFEASLP
Definition: type_conflict.h:61
@ 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
@ SCIP_LPERROR
Definition: type_retcode.h:49
@ SCIP_OKAY
Definition: type_retcode.h:42
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
SCIP_Real SCIPvarGetLbLP(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:12950
SCIP_Real SCIPvarGetUbLP(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:13020
internal methods for problem variables
methods for creating output for visualization tools (VBC, BAK)