SCIP Doxygen Documentation
Loading...
Searching...
No Matches
lp.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-2026 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 lp.c
26 * @ingroup OTHER_CFILES
27 * @brief LP management methods and data structures
28 * @author Tobias Achterberg
29 * @author Timo Berthold
30 * @author Marc Pfetsch
31 * @author Kati Wolter
32 * @author Gerald Gamrath
33 *
34 * In LP management, we have to differ between the current LP and the SCIP_LP
35 * stored in the LP solver. All LP methods affect the current LP only.
36 * Before solving the current LP with the LP solver or setting an LP state,
37 * the LP solvers data has to be updated to the current LP with a call to
38 * lpFlush().
39 */
40
41/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
42
43#include "lpi/lpi.h"
44#include "lpiexact/lpiexact.h"
45#include "scip/clock.h"
46#include "scip/certificate.h"
47#include "scip/cons.h"
48#include "scip/event.h"
49#include "scip/intervalarith.h"
50#include "scip/lp.h"
52#include "scip/misc.h"
53#include "scip/prob.h"
54#include "scip/pub_lp.h"
55#include "scip/pub_lpexact.h"
56#include "scip/pub_message.h"
57#include "scip/pub_misc.h"
58#include "scip/pub_misc_sort.h"
59#include "scip/pub_var.h"
60#include "scip/set.h"
61#include "scip/sol.h"
62#include "scip/solve.h"
63#include "scip/stat.h"
64#include "scip/struct_scip.h"
65#include "scip/struct_event.h"
66#include "scip/struct_lp.h"
67#include "scip/struct_lpexact.h"
68#include "scip/struct_prob.h"
69#include "scip/struct_set.h"
70#include "scip/struct_stat.h"
71#include "scip/struct_var.h"
72#include "scip/var.h"
73#include <string.h>
74
75
76/* activate this to use the row activities as given by the LPI instead of recalculating
77 * using the LP solver activity is potentially faster, but may not be consistent with the SCIP_ROW calculations
78 * see also #2594 for more details on possible trouble
79 */
80/* #define SCIP_USE_LPSOLVER_ACTIVITY */
81
82/*
83 * debug messages
84 */
85
86#ifdef SCIP_DEBUG
87/** method is to print in row in case SCIP_DEBUG is defined */
88static
89void debugRowPrint(
90 SCIP_SET* set, /**< global SCIP settings */
91 SCIP_ROW* row /**< LP row */
92 )
93{
94 int i;
95
96 assert(row != NULL);
97
98 /* print row name */
99 if( row->name != NULL && row->name[0] != '\0' )
100 {
101 SCIPsetDebugMsgPrint(set, "%s: ", row->name);
102 }
103
104 /* print left hand side */
105 SCIPsetDebugMsgPrint(set, "%.15g <= ", row->lhs);
106
107 /* print coefficients */
108 if( row->len == 0 )
109 {
111 }
112 for( i = 0; i < row->len; ++i )
113 {
114 assert(row->cols[i] != NULL);
115 assert(row->cols[i]->var != NULL);
116 assert(SCIPvarGetName(row->cols[i]->var) != NULL);
118 SCIPsetDebugMsgPrint(set, "%+.15g<%s> ", row->vals[i], SCIPvarGetName(row->cols[i]->var));
119 }
120
121 /* print constant */
123 {
124 SCIPsetDebugMsgPrint(set, "%+.15g ", row->constant);
125 }
126
127 /* print right hand side */
128 SCIPsetDebugMsgPrint(set, "<= %.15g\n", row->rhs);
129}
130#else
131#define debugRowPrint(x,y) /**/
132#endif
133
134#ifdef SCIP_DEBUG
135/** method to output column if SCIP_DEBUG is define */
136static
137void debugColPrint(
138 SCIP_SET* set, /**< global SCIP settings */
139 SCIP_COL* col /**< LP column */
140 )
141{
142 int r;
143
144 assert(col != NULL);
145 assert(col->var != NULL);
146
147 /* print bounds */
148 SCIPsetDebugMsgPrint(set, "(obj: %.15g) [%.15g,%.15g], ", col->obj, col->lb, col->ub);
149
150 /* print coefficients */
151 if( col->len == 0 )
152 {
153 SCIPsetDebugMsgPrint(set, "<empty>");
154 }
155 for( r = 0; r < col->len; ++r )
156 {
157 assert(col->rows[r] != NULL);
158 assert(col->rows[r]->name != NULL);
159 SCIPsetDebugMsgPrint(set, "%+.15g<%s> ", col->vals[r], col->rows[r]->name);
160 }
162}
163#else
164#define debugColPrint(x,y) /**/
165#endif
166
167/*
168 * memory growing methods for dynamically allocated arrays
169 */
170
171/** ensures, that chgcols array can store at least num entries */
172static
174 SCIP_LP* lp, /**< current LP data */
175 SCIP_SET* set, /**< global SCIP settings */
176 int num /**< minimum number of entries to store */
177 )
178{
179 assert(lp->nchgcols <= lp->chgcolssize);
180
181 if( num > lp->chgcolssize )
182 {
183 int newsize;
184
185 newsize = SCIPsetCalcMemGrowSize(set, num);
186 SCIP_ALLOC( BMSreallocMemoryArray(&lp->chgcols, newsize) );
187 lp->chgcolssize = newsize;
188 }
189 assert(num <= lp->chgcolssize);
190
191 return SCIP_OKAY;
192}
193
194/** ensures, that chgrows array can store at least num entries */
195static
197 SCIP_LP* lp, /**< current LP data */
198 SCIP_SET* set, /**< global SCIP settings */
199 int num /**< minimum number of entries to store */
200 )
201{
202 assert(lp->nchgrows <= lp->chgrowssize);
203
204 if( num > lp->chgrowssize )
205 {
206 int newsize;
207
208 newsize = SCIPsetCalcMemGrowSize(set, num);
209 SCIP_ALLOC( BMSreallocMemoryArray(&lp->chgrows, newsize) );
210 lp->chgrowssize = newsize;
211 }
212 assert(num <= lp->chgrowssize);
213
214 return SCIP_OKAY;
215}
216
217/** ensures, that lpicols array can store at least num entries */
218static
220 SCIP_LP* lp, /**< current LP data */
221 SCIP_SET* set, /**< global SCIP settings */
222 int num /**< minimum number of entries to store */
223 )
224{
225 assert(lp->nlpicols <= lp->lpicolssize);
226
227 if( num > lp->lpicolssize )
228 {
229 int newsize;
230
231 newsize = SCIPsetCalcMemGrowSize(set, num);
232 SCIP_ALLOC( BMSreallocMemoryArray(&lp->lpicols, newsize) );
233 lp->lpicolssize = newsize;
234 }
235 assert(num <= lp->lpicolssize);
236
237 return SCIP_OKAY;
238}
239
240/** ensures, that lpirows array can store at least num entries */
241static
243 SCIP_LP* lp, /**< current LP data */
244 SCIP_SET* set, /**< global SCIP settings */
245 int num /**< minimum number of entries to store */
246 )
247{
248 assert(lp->nlpirows <= lp->lpirowssize);
249
250 if( num > lp->lpirowssize )
251 {
252 int newsize;
253
254 newsize = SCIPsetCalcMemGrowSize(set, num);
255 SCIP_ALLOC( BMSreallocMemoryArray(&lp->lpirows, newsize) );
256 lp->lpirowssize = newsize;
257 }
258 assert(num <= lp->lpirowssize);
259
260 return SCIP_OKAY;
261}
262
263/** ensures, that cols array can store at least num entries */
264static
266 SCIP_LP* lp, /**< current LP data */
267 SCIP_SET* set, /**< global SCIP settings */
268 int num /**< minimum number of entries to store */
269 )
270{
271 assert(lp->ncols <= lp->colssize);
272
273 if( num > lp->colssize )
274 {
275 int newsize;
276
277 newsize = SCIPsetCalcMemGrowSize(set, num);
278 SCIP_ALLOC( BMSreallocMemoryArray(&lp->cols, newsize) );
279 lp->colssize = newsize;
280 }
281 assert(num <= lp->colssize);
282
283 return SCIP_OKAY;
284}
285
286/** ensures, that soldirection array can store at least num entries */
287static
289 SCIP_LP* lp, /**< current LP data */
290 int num /**< minimum number of entries to store */
291 )
292{
293 if( num > lp->soldirectionsize )
294 {
297
298 lp->soldirectionsize = num;
299 }
300
301 assert(num <= lp->soldirectionsize);
302
303 return SCIP_OKAY;
304}
305
306/** ensures, that lazy cols array can store at least num entries */
307static
309 SCIP_LP* lp, /**< current LP data */
310 SCIP_SET* set, /**< global SCIP settings */
311 int num /**< minimum number of entries to store */
312 )
313{
314 assert(lp->nlazycols <= lp->lazycolssize);
315
316 if( num > lp->lazycolssize )
317 {
318 int newsize;
319
320 newsize = SCIPsetCalcMemGrowSize(set, num);
321 SCIP_ALLOC( BMSreallocMemoryArray(&lp->lazycols, newsize) );
322 lp->lazycolssize = newsize;
323 }
324 assert(num <= lp->lazycolssize);
325
326 return SCIP_OKAY;
327}
328
329/** ensures, that rows array can store at least num entries */
330static
332 SCIP_LP* lp, /**< current LP data */
333 SCIP_SET* set, /**< global SCIP settings */
334 int num /**< minimum number of entries to store */
335 )
336{
337 assert(lp->nrows <= lp->rowssize);
338
339 if( num > lp->rowssize )
340 {
341 int newsize;
342
343 newsize = SCIPsetCalcMemGrowSize(set, num);
344 SCIP_ALLOC( BMSreallocMemoryArray(&lp->rows, newsize) );
345 lp->rowssize = newsize;
346 }
347 assert(num <= lp->rowssize);
348
349 return SCIP_OKAY;
350}
351
352/** ensures, that row array of column can store at least num entries */
353static
355 SCIP_COL* col, /**< LP column */
356 BMS_BLKMEM* blkmem, /**< block memory */
357 SCIP_SET* set, /**< global SCIP settings */
358 int num /**< minimum number of entries to store */
359 )
360{
361 assert(col != NULL);
362 assert(col->len <= col->size);
363
364 if( num > col->size )
365 {
366 int newsize;
367
368 newsize = SCIPsetCalcMemGrowSize(set, num);
369 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &col->rows, col->size, newsize) );
370 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &col->vals, col->size, newsize) );
371 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &col->linkpos, col->size, newsize) );
372 col->size = newsize;
373 }
374 assert(num <= col->size);
375
376 return SCIP_OKAY;
377}
378
379/** save current LP values dependent on the solution */
380static
382 SCIP_LP* lp, /**< LP data */
383 SCIP_STAT* stat, /**< problem statistics */
384 BMS_BLKMEM* blkmem /**< block memory */
385 )
386{
387 SCIP_LPSOLVALS* storedsolvals;
388
389 assert(lp != NULL);
390 assert(stat != NULL);
391 assert(blkmem != NULL);
392
393 /* allocate memory for storage */
394 if( lp->storedsolvals == NULL )
395 {
397 }
398 storedsolvals = lp->storedsolvals;
399
400 /* store values */
401 storedsolvals->lpsolstat = lp->lpsolstat;
402 storedsolvals->lpobjval = lp->lpobjval;
403 storedsolvals->primalfeasible = lp->primalfeasible;
404 storedsolvals->primalchecked = lp->primalchecked;
405 storedsolvals->dualfeasible = lp->dualfeasible;
406 storedsolvals->dualchecked = lp->dualchecked;
407 storedsolvals->solisbasic = lp->solisbasic;
408 storedsolvals->lpissolved = lp->solved;
409 storedsolvals->hasprovedboundexact = lp->hasprovedbound;
410
411 return SCIP_OKAY;
412}
413
414/** restore LP solution values in column */
415static
417 SCIP_LP* lp, /**< LP data */
418 BMS_BLKMEM* blkmem, /**< block memory */
419 SCIP_Longint validlp /**< number of lp for which restored values are valid */
420 )
421{
422 SCIP_LPSOLVALS* storedsolvals;
423
424 assert(lp != NULL);
425 assert(blkmem != NULL);
426
427 /* if stored values are available, restore them */
428 storedsolvals = lp->storedsolvals;
429 if( storedsolvals != NULL )
430 {
431 lp->solved = storedsolvals->lpissolved;
432 lp->validsollp = validlp;
433
434 lp->lpsolstat = storedsolvals->lpsolstat;
435 lp->lpobjval = storedsolvals->lpobjval;
436 lp->primalfeasible = storedsolvals->primalfeasible;
437 lp->primalchecked = storedsolvals->primalchecked;
438 lp->dualfeasible = storedsolvals->dualfeasible;
439 lp->dualchecked = storedsolvals->dualchecked;
440 lp->solisbasic = storedsolvals->solisbasic;
441 lp->hasprovedbound = storedsolvals->hasprovedboundexact;
442
443 /* solution values are stored only for LPs solved without error */
450 lp->validsollp == -1);
451 }
452 /* no values available, mark LP as unsolved */
453 else
454 {
455 lp->solved = FALSE;
456 lp->validsollp = -1;
457
460 lp->primalfeasible = FALSE;
461 lp->primalchecked = FALSE;
462 lp->dualfeasible = FALSE;
463 lp->dualchecked = FALSE;
464 lp->solisbasic = FALSE;
465 lp->validfarkaslp = -1;
466 }
467
468 lp->validdegeneracylp = -1;
469
470 /* intentionally keep storage space allocated */
471
472 return SCIP_OKAY;
473}
474
475/** save current LP solution values stored in each column */
476static
478 SCIP_COL* col, /**< LP column */
479 BMS_BLKMEM* blkmem /**< block memory */
480 )
481{
482 SCIP_COLSOLVALS* storedsolvals;
483
484 assert(col != NULL);
485 assert(blkmem != NULL);
486
487 /* allocate memory for storage */
488 if( col->storedsolvals == NULL )
489 {
491 }
492 storedsolvals = col->storedsolvals;
493
494 /* store values */
495 storedsolvals->primsol = col->primsol;
496 storedsolvals->redcost = col->redcost;
497 storedsolvals->basisstatus = col->basisstatus; /*lint !e641 !e732*/
498
499 return SCIP_OKAY;
500}
501
502/** restore LP solution values in column */
503static
505 SCIP_COL* col, /**< LP column */
506 BMS_BLKMEM* blkmem, /**< block memory */
507 SCIP_Longint validlp, /**< number of lp for which restored values are valid */
508 SCIP_Bool freebuffer /**< should buffer for LP solution values be freed? */
509 )
510{
511 SCIP_COLSOLVALS* storedsolvals;
512
513 assert(col != NULL);
514 assert(blkmem != NULL);
515
516 /* if stored values are available, restore them */
517 storedsolvals = col->storedsolvals;
518 if( storedsolvals != NULL )
519 {
520 col->primsol = storedsolvals->primsol;
521 col->redcost = storedsolvals->redcost;
522 col->validredcostlp = validlp;
523 col->basisstatus = storedsolvals->basisstatus; /*lint !e641 !e732*/
524
525 /* we do not save the farkas coefficient, since it can be recomputed; thus, we invalidate it here */
526 col->validfarkaslp = -1;
527 }
528 /* if the column was created after performing the storage (possibly during probing), we treat it as implicitly zero;
529 * we make sure to invalidate the reduced cost and farkas coefficient, which are not available
530 */
531 else
532 {
533 col->primsol = 0.0;
534 col->validredcostlp = -1;
535 col->validfarkaslp = -1;
536 col->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
537 }
538
539 /* free memory */
540 if( freebuffer )
541 {
543 assert(col->storedsolvals == NULL);
544 }
545
546 return SCIP_OKAY;
547}
548
549/** save current LP solution values stored in each column */
550static
552 SCIP_ROW* row, /**< LP row */
553 BMS_BLKMEM* blkmem, /**< block memory */
554 SCIP_Bool infeasible /**< is the solution infeasible? */
555 )
556{
557 SCIP_ROWSOLVALS* storedsolvals;
558
559 assert(row != NULL);
560 assert(blkmem != NULL);
561
562 /* allocate memory for storage */
563 if( row->storedsolvals == NULL )
564 {
566 }
567 storedsolvals = row->storedsolvals;
568
569 /* store values */
570 if ( infeasible )
571 {
572 storedsolvals->dualsol = row->dualfarkas;
573 storedsolvals->activity = SCIP_INVALID;
574 storedsolvals->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
575 }
576 else
577 {
578 storedsolvals->dualsol = row->dualsol;
579 storedsolvals->activity = row->activity;
580 storedsolvals->basisstatus = row->basisstatus; /*lint !e641 !e732*/
581 }
582
583 return SCIP_OKAY;
584}
585
586/** restore LP solution values in row */
587static
589 SCIP_ROW* row, /**< LP column */
590 BMS_BLKMEM* blkmem, /**< block memory */
591 SCIP_Longint validlp, /**< number of lp for which restored values are valid */
592 SCIP_Bool freebuffer, /**< should buffer for LP solution values be freed? */
593 SCIP_Bool infeasible /**< is the solution infeasible? */
594 )
595{
596 SCIP_ROWSOLVALS* storedsolvals;
597
598 assert(row != NULL);
599 assert(blkmem != NULL);
600
601 /* if stored values are available, restore them */
602 storedsolvals = row->storedsolvals;
603 if( storedsolvals != NULL )
604 {
605 if ( infeasible )
606 row->dualfarkas = storedsolvals->dualsol;
607 else
608 row->dualsol = storedsolvals->dualsol;
609 row->activity = storedsolvals->activity;
610 row->validactivitylp = validlp;
611 row->basisstatus = storedsolvals->basisstatus; /*lint !e641 !e732*/
612 }
613 /* if the row was created after performing the storage (possibly during probing), we treat it as basic;
614 * we make sure to invalidate the reduced cost and farkas coefficient, which are not available
615 */
616 else
617 {
618 row->dualsol = 0.0;
619 row->dualfarkas = 0.0;
620 row->activity = SCIP_INVALID;
621 row->validactivitylp = -1;
622 row->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
623 }
624
625 /* free memory */
626 if( freebuffer )
627 {
629 assert(row->storedsolvals == NULL);
630 }
631
632 return SCIP_OKAY;
633}
634
635/** ensures, that column array of row can store at least num entries */
637 SCIP_ROW* row, /**< LP row */
638 BMS_BLKMEM* blkmem, /**< block memory */
639 SCIP_SET* set, /**< global SCIP settings */
640 int num /**< minimum number of entries to store */
641 )
642{
643 assert(row != NULL);
644 assert(row->len <= row->size);
645
646 if( num > row->size )
647 {
648 int newsize;
649
650 newsize = SCIPsetCalcMemGrowSize(set, num);
651 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->cols, row->size, newsize) );
652 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->cols_index, row->size, newsize) );
653 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->vals, row->size, newsize) );
654 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->linkpos, row->size, newsize) );
655 row->size = newsize;
656 }
657 assert(num <= row->size);
658
659 return SCIP_OKAY;
660}
661
662
663#ifdef SCIP_MORE_DEBUG /* enable this to check the sortings within rows (for debugging, very slow!) */
664static SCIP_Bool msgdisp_checkrow = FALSE;
665
666static
667void checkRow(
668 SCIP_ROW* row
669 )
670{
671 int i;
672
673 if( !msgdisp_checkrow )
674 {
675 printf("LP ROW CHECKING ACTIVATED! THIS IS VERY SLOW!\n");
676 msgdisp_checkrow = TRUE;
677 }
678
679 /* validate sorting of LP part of row */
680 if( row->lpcolssorted && row->nlpcols > 0)
681 {
682 assert(row->cols_index[0] == row->cols[0]->index);
683 for( i = 1; i < row->nlpcols; ++i )
684 {
685 assert(row->cols_index[i] == row->cols[i]->index);
686 assert(row->cols_index[i] >= row->cols_index[i-1]);
687 }
688 }
689
690 /* validate sorting of non-LP part of row */
691 if( row->nonlpcolssorted && row->len > row->nlpcols )
692 {
693 assert(row->cols_index[row->nlpcols] == row->cols[row->nlpcols]->index);
694 for( i = row->nlpcols + 1; i < row->len; ++i )
695 {
696 assert(row->cols_index[i] == row->cols[i]->index);
697 assert(row->cols_index[i] >= row->cols_index[i-1]);
698 }
699 }
700}
701#else
702#define checkRow(row) /**/
703#endif
704
705#ifdef SCIP_MORE_DEBUG /* enable this to check norms of rows (for debugging, very slow!) */
706static
707void checkRowSqrnorm(
708 SCIP_ROW* row
709 )
710{
711 SCIP_COL** cols;
712 SCIP_Real sqrnorm;
713 int c;
714
715 cols = row->cols;
716 assert(cols != NULL || row->len == 0);
717
718 sqrnorm = 0.0;
719
720 for( c = row->len - 1; c >= 0; --c )
721 {
722 if( cols[c]->lppos >= 0 )
723 sqrnorm += SQR(row->vals[c]);
724 }
725
726 assert(ABS(sqrnorm - row->sqrnorm) < 1e-06 * MAX(1.0,sqrnorm));
727}
728
729static
730void checkRowSumnorm(
731 SCIP_ROW* row
732 )
733{
734 SCIP_COL** cols;
735 SCIP_Real sumnorm;
736 int c;
737
738 cols = row->cols;
739 assert(cols != NULL || row->len == 0);
740
741 sumnorm = 0.0;
742
743 for( c = row->len - 1; c >= 0; --c )
744 {
745 if( cols[c]->lppos >= 0 )
746 sumnorm += REALABS(row->vals[c]);
747 }
748
749 assert(ABS(sumnorm - row->sumnorm) < 1e-06 * MAX(1.0,sumnorm));
750}
751
752static
753void checkRowObjprod(
754 SCIP_ROW* row
755 )
756{
757 SCIP_COL** cols;
758 SCIP_Real objprod;
759 int c;
760
761 cols = row->cols;
762 assert(cols != NULL || row->len == 0);
763
764 objprod = 0.0;
765
766 for( c = row->len - 1; c >= 0; --c )
767 {
768 if( cols[c]->lppos >= 0 )
769 objprod += row->vals[c] * cols[c]->unchangedobj;
770 }
771
772 assert(ABS(objprod - row->objprod) < 1e-06 * MAX(1.0,objprod));
773}
774#else
775#define checkRowSqrnorm(row) /**/
776#define checkRowSumnorm(row) /**/
777#define checkRowObjprod(row) /**/
778#endif
779
780/*
781 * Local methods for pseudo and loose objective values
782 */
783
784/** recompute the pseudo solution value from scratch, if it was marked to be unreliable before
785 *
786 * Safe version for use in exact SCIP.
787 */
788static
790 SCIP_LP* lp, /**< current LP data */
791 SCIP_SET* set, /**< global SCIP settings */
792 SCIP_PROB* prob /**< problem data */
793 )
794{
795 SCIP_VAR** vars;
797 SCIP_INTERVAL bnd;
798 SCIP_INTERVAL res;
799 SCIP_INTERVAL prod;
800 int nvars;
801 int v;
802
803 assert(lp != NULL);
804 assert(set != NULL);
805 assert(prob != NULL);
806 assert(set->exact_enable);
807
808 vars = prob->vars;
809 nvars = prob->nvars;
810
811 SCIPintervalSet(&res, 0.0);
812
813 /* iterate over all variables in the problem */
814 for( v = 0; v < nvars; ++v )
815 {
817 {
819
820 /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
821 if( obj.sup > 0 && !SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(vars[v])) )
822 {
824 SCIPintervalMul(SCIPsetInfinity(set), &prod, obj, bnd);
825 SCIPintervalAdd(SCIPsetInfinity(set), &res, res, prod);
826 }
827 else if( obj.inf < 0 && !SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
828 {
830 SCIPintervalMul(SCIPsetInfinity(set), &prod, obj, bnd);
831 SCIPintervalAdd(SCIPsetInfinity(set), &res, res, prod);
832 }
833 }
834 }
835
836 /* the recomputed value is reliable */
838 lp->rellooseobjval = lp->looseobjval;
839 lp->looseobjvalid = TRUE;
840}
841
842/** recompute the loose objective value from scratch, if it was marked to be unreliable before */
843static
845 SCIP_LP* lp, /**< current LP data */
846 SCIP_SET* set, /**< global SCIP settings */
847 SCIP_PROB* prob /**< problem data */
848 )
849{
850 SCIP_VAR** vars;
852 int nvars;
853 int v;
854
855 assert(lp != NULL);
856 assert(set != NULL);
857 assert(prob != NULL);
858 assert(!lp->looseobjvalid);
859
860 vars = prob->vars;
861 nvars = prob->nvars;
862 lp->looseobjval = 0.0;
863
864 if( set->exact_enable )
865 {
867 return;
868 }
869
870 /* iterate over all variables in the problem */
871 for( v = 0; v < nvars; ++v )
872 {
874 {
875 obj = SCIPvarGetObj(vars[v]);
876
877 /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
882 }
883 }
884
885 /* the recomputed value is reliable */
886 lp->rellooseobjval = lp->looseobjval;
887 lp->looseobjvalid = TRUE;
888}
889
890/** recompute the pseudo solution value from scratch, if it was marked to be unreliable before
891 *
892 * Safe version for use in exact SCIP.
893 */
894static
896 SCIP_LP* lp, /**< current LP data */
897 SCIP_SET* set, /**< global SCIP settings */
898 SCIP_PROB* prob /**< problem data */
899 )
900{
901 SCIP_VAR** vars;
903 SCIP_INTERVAL bnd;
904 SCIP_INTERVAL res;
905 SCIP_INTERVAL prod;
906 int nvars;
907 int v;
908
909 assert(lp != NULL);
910 assert(set != NULL);
911 assert(prob != NULL);
913 assert(set->exact_enable);
914
915 vars = prob->vars;
916 nvars = prob->nvars;
917
918 SCIPintervalSet(&res, 0.0);
919
920 /* iterate over all variables in the problem */
921 for( v = 0; v < nvars; ++v )
922 {
924
925 /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
926 if( obj.sup > 0 && !SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(vars[v])) )
927 {
929 SCIPintervalMul(SCIPsetInfinity(set), &prod, obj, bnd);
930 SCIPintervalAdd(SCIPsetInfinity(set), &res, res, prod);
931 }
932 else if( obj.inf < 0 && !SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
933 {
935 SCIPintervalMul(SCIPsetInfinity(set), &prod, obj, bnd);
936 SCIPintervalAdd(SCIPsetInfinity(set), &res, res, prod);
937 }
938 }
939
940 /* the recomputed value is reliable */
943 lp->pseudoobjvalid = TRUE;
944}
945
946/** recompute the pseudo solution value from scratch, if it was marked to be unreliable before */
947static
949 SCIP_LP* lp, /**< current LP data */
950 SCIP_SET* set, /**< global SCIP settings */
951 SCIP_PROB* prob /**< problem data */
952 )
953{
954 SCIP_VAR** vars;
955 int nvars;
956 int v;
957
958 assert(lp != NULL);
959 assert(set != NULL);
960 assert(prob != NULL);
962
963 vars = prob->vars;
964 nvars = prob->nvars;
965 lp->pseudoobjval = 0.0;
966
967 if( set->exact_enable )
968 {
970 return;
971 }
972
973 /* iterate over all variables in the problem */
974 for( v = 0; v < nvars; ++v )
975 {
976 /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
978 {
980 }
982 {
984 }
985 }
986
987 /* the recomputed value is reliable */
989 lp->pseudoobjvalid = TRUE;
990}
991
992/** recompute the global pseudo solution value from scratch, if it was marked to be unreliable before */
993static
995 SCIP_LP* lp, /**< current LP data */
996 SCIP_SET* set, /**< global SCIP settings */
997 SCIP_PROB* prob /**< problem data */
998 )
999{
1000 SCIP_VAR** vars;
1001 int nvars;
1002 int v;
1003
1004 assert(lp != NULL);
1005 assert(set != NULL);
1006 assert(prob != NULL);
1008
1009 vars = prob->vars;
1010 nvars = prob->nvars;
1011 lp->glbpseudoobjval = 0.0;
1012
1013 /* iterate over all variables in the problem */
1014 for( v = 0; v < nvars; ++v )
1015 {
1016 /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
1018 {
1020 }
1022 {
1024 }
1025 }
1026
1027 /* the recomputed value is reliable */
1029 lp->glbpseudoobjvalid = TRUE;
1030}
1031
1032/** gets finite part of objective value of current LP that results from LOOSE variables only */
1033static
1035 SCIP_LP* lp, /**< current LP data */
1036 SCIP_SET* set, /**< global SCIP settings */
1037 SCIP_PROB* prob /**< problem data */
1038 )
1039{
1040 assert(lp != NULL);
1041 assert(set != NULL);
1042 assert(prob != NULL);
1043 assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
1044 assert(lp->flushed);
1045 assert(lp->looseobjvalinf == 0);
1046
1047 /* recalculate the loose objective value, if needed */
1048 if( !lp->looseobjvalid )
1050
1051 return lp->looseobjval;
1052}
1053
1054/** gets finite part of pseudo objective value of current LP */
1055static
1057 SCIP_LP* lp, /**< current LP data */
1058 SCIP_SET* set, /**< global SCIP settings */
1059 SCIP_PROB* prob /**< problem data */
1060 )
1061{
1062 assert(lp != NULL);
1063 assert(set != NULL);
1064 assert(prob != NULL);
1065
1066 /* recalculate the pseudo objective value, if needed */
1067 if( !lp->pseudoobjvalid )
1069
1070 return lp->pseudoobjval;
1071}
1072
1073/*
1074 * Sorting and searching rows and columns
1075 */
1076
1077
1078/** comparison method for sorting rows by non-decreasing index */
1080{
1081 assert(elem1 != NULL);
1082 assert(elem2 != NULL);
1083
1084 if( ((SCIP_ROW*)elem1)->index < ((SCIP_ROW*)elem2)->index )
1085 return -1;
1086 else if( ((SCIP_ROW*)elem1)->index > ((SCIP_ROW*)elem2)->index )
1087 return +1;
1088 else
1089 {
1090 assert(SCIProwGetIndex((SCIP_ROW*)(elem1)) == SCIProwGetIndex(((SCIP_ROW*)elem2)));
1091 return 0;
1092 }
1093}
1094
1095
1096/** sorts column entries of linked rows currently in the LP such that lower row indices precede higher ones */
1097static
1099 SCIP_COL* col /**< column to be sorted */
1100 )
1101{
1102 int i;
1103
1104 assert(col != NULL);
1105
1106 /* check, if column is already sorted in the LP part */
1107 if( col->lprowssorted )
1108 return;
1109
1110 /* sort coefficients */
1111 SCIPsortPtrRealInt((void**)col->rows, col->vals, col->linkpos, SCIProwComp, col->nlprows );
1112
1113 /* update links */
1114 for( i = 0; i < col->nlprows; ++i )
1115 {
1116 if( col->linkpos[i] >= 0 )
1117 {
1118 assert(col->rows[i]->cols[col->linkpos[i]] == col);
1119 assert(col->rows[i]->linkpos[col->linkpos[i]] >= 0);
1120 col->rows[i]->linkpos[col->linkpos[i]] = i;
1121 }
1122 }
1123
1124 col->lprowssorted = TRUE;
1125}
1126
1127/** sorts column entries of unlinked rows or rows currently not in the LP such that lower row indices precede higher
1128 * ones
1129 */
1130static
1132 SCIP_COL* col /**< column to be sorted */
1133 )
1134{
1135 int i;
1136
1137 assert(col != NULL);
1138
1139 /* check, if column is already sorted in the non-LP part */
1140 if( col->nonlprowssorted )
1141 return;
1142
1143 /* sort coefficients */
1144 SCIPsortPtrRealInt((void**)(&(col->rows[col->nlprows])), &(col->vals[col->nlprows]), &(col->linkpos[col->nlprows]), SCIProwComp, col->len - col->nlprows);
1145
1146 /* update links */
1147 for( i = col->nlprows; i < col->len; ++i )
1148 {
1149 if( col->linkpos[i] >= 0 )
1150 {
1151 assert(col->rows[i]->cols[col->linkpos[i]] == col);
1152 assert(col->rows[i]->linkpos[col->linkpos[i]] >= 0);
1153 col->rows[i]->linkpos[col->linkpos[i]] = i;
1154 }
1155 }
1156
1157 col->nonlprowssorted = TRUE;
1158}
1159
1160/** sorts row entries of linked columns currently in the LP such that lower column indices precede higher ones */
1161static
1163 SCIP_ROW* row /**< row to be sorted */
1164 )
1165{
1166 int i;
1167
1168 assert(row != NULL);
1169
1170 /* check, if row is already sorted in the LP part, or if the sorting should be delayed */
1171 if( row->lpcolssorted || row->delaysort )
1172 return;
1173
1174 /* sort coefficients */
1175 SCIPsortIntPtrIntReal(row->cols_index, (void**)row->cols, row->linkpos, row->vals, row->nlpcols);
1176
1177 /* update links */
1178 for( i = 0; i < row->nlpcols; ++i )
1179 {
1180 if( row->linkpos[i] >= 0 )
1181 {
1182 assert(row->cols[i]->rows[row->linkpos[i]] == row);
1183 assert(row->cols[i]->linkpos[row->linkpos[i]] >= 0);
1184 row->cols[i]->linkpos[row->linkpos[i]] = i;
1185 }
1186 }
1187
1188 row->lpcolssorted = TRUE;
1189}
1190
1191/** sorts row entries of unlinked columns or columns currently not in the LP such that lower column indices precede
1192 * higher ones
1193 */
1194static
1196 SCIP_ROW* row /**< row to be sorted */
1197 )
1198{
1199 int i;
1200
1201 assert(row != NULL);
1202
1203 checkRow(row);
1204
1205 /* check, if row is already sorted in the non-LP part, or if the sorting should be delayed */
1206 if( row->nonlpcolssorted || row->delaysort )
1207 return;
1208
1209 /* sort coefficients */
1210 SCIPsortIntPtrIntReal(&(row->cols_index[row->nlpcols]), (void**)(&(row->cols[row->nlpcols])), &(row->linkpos[row->nlpcols]), &(row->vals[row->nlpcols]), row->len - row->nlpcols);
1211
1212 /* update links */
1213 for( i = row->nlpcols; i < row->len; ++i )
1214 {
1215 if( row->linkpos[i] >= 0 )
1216 {
1217 assert(row->cols[i]->rows[row->linkpos[i]] == row);
1218 assert(row->cols[i]->linkpos[row->linkpos[i]] >= 0);
1219 row->cols[i]->linkpos[row->linkpos[i]] = i;
1220 }
1221 }
1222
1223 checkRow(row);
1224
1225 row->nonlpcolssorted = TRUE;
1226}
1227
1228/** searches coefficient in part of the column, returns position in col vector or -1 if not found */
1229static
1231 SCIP_COL* col, /**< column to be searched in */
1232 const SCIP_ROW* row, /**< coefficient to be searched for */
1233 int minpos, /**< first position of search range */
1234 int maxpos /**< last position of search range */
1235 )
1236{
1237 int pos;
1238 int idx;
1239 int searchidx;
1240
1241 assert(col != NULL);
1242 assert(row != NULL);
1243
1244 /* binary search */
1245 searchidx = row->index;
1246 while(minpos <= maxpos)
1247 {
1248 pos = (minpos + maxpos)/2;
1249 assert(0 <= pos && pos < col->len);
1250 assert(col->rows[pos] != NULL);
1251 assert((pos < col->nlprows) == (col->rows[pos]->lppos >= 0 && col->linkpos[pos] >= 0));
1252 idx = col->rows[pos]->index;
1253 if( searchidx == idx )
1254 return pos;
1255 else if( searchidx < idx )
1256 maxpos = pos-1;
1257 else
1258 minpos = pos+1;
1259 }
1260
1261 return -1;
1262}
1263
1264/** searches coefficient in column, returns position in col vector or -1 if not found */
1265static
1267 SCIP_COL* col, /**< column to be searched in */
1268 const SCIP_ROW* row /**< coefficient to be searched for */
1269 )
1270{
1271 int pos;
1272
1273 assert(col != NULL);
1274 assert(row != NULL);
1275
1276 pos = -1;
1277
1278 /* search in the linked LP rows */
1279 if( row->lppos >= 0 )
1280 {
1281 /* column has to be sorted, such that binary search works */
1282 colSortLP(col);
1283 assert(col->lprowssorted);
1284
1285 pos = colSearchCoefPart(col, row, 0, col->nlprows-1);
1286 if( pos >= 0 )
1287 return pos;
1288 }
1289
1290 /* search in the non-LP/unlinked rows */
1291 if( row->lppos == -1 || col->nunlinked > 0 )
1292 {
1293 /* column has to be sorted, such that binary search works */
1294 colSortNonLP(col);
1295 assert(col->nonlprowssorted);
1296
1297 pos = colSearchCoefPart(col, row, col->nlprows, col->len-1);
1298 }
1299
1300 return pos;
1301}
1302
1303/** searches coefficient in part of the row, returns position in col vector or -1 if not found */
1304static
1306 SCIP_ROW* row, /**< row to be searched in */
1307 const SCIP_COL* col, /**< coefficient to be searched for */
1308 int minpos, /**< first position of search range */
1309 int maxpos /**< last position of search range */
1310 )
1311{
1312 int pos;
1313 int idx;
1314 int searchidx;
1315
1316 assert(row != NULL);
1317 assert(col != NULL);
1318
1319 /* binary search */
1320 searchidx = col->index;
1321 while(minpos <= maxpos)
1322 {
1323 pos = (minpos + maxpos)/2;
1324 assert(0 <= pos && pos < row->len);
1325 assert(row->cols[pos] != NULL);
1326 assert((pos < row->nlpcols) == (row->cols[pos]->lppos >= 0 && row->linkpos[pos] >= 0));
1327 assert(row->cols_index[pos] == row->cols[pos]->index);
1328 idx = row->cols_index[pos];
1329 if( searchidx == idx )
1330 return pos;
1331 else if( searchidx < idx )
1332 maxpos = pos-1;
1333 else
1334 minpos = pos+1;
1335 }
1336
1337 return -1;
1338}
1339
1340/** searches coefficient in row, returns position in row vector or -1 if not found;
1341 * if the sorting of the row is delayed, returns -1
1342 */
1343static
1345 SCIP_ROW* row, /**< row to be searched in */
1346 const SCIP_COL* col /**< coefficient to be searched for */
1347 )
1348{
1349 int pos;
1350
1351 assert(row != NULL);
1352 assert(col != NULL);
1353
1354 if( row->delaysort )
1355 return -1;
1356
1357 pos = -1;
1358
1359 /* search in the linked LP columns */
1360 if( col->lppos >= 0 )
1361 {
1362 /* row has to be sorted, such that binary search works */
1363 rowSortLP(row);
1364 assert(row->lpcolssorted);
1365
1366 pos = rowSearchCoefPart(row, col, 0, row->nlpcols-1);
1367 }
1368
1369 /* search in the non-LP/unlinked columns */
1370 if( pos == -1 && (col->lppos == -1 || row->nunlinked > 0) )
1371 {
1372 /* row has to be sorted, such that binary search works */
1373 rowSortNonLP(row);
1374 assert(row->nonlpcolssorted);
1375
1376 pos = rowSearchCoefPart(row, col, row->nlpcols, row->len-1);
1377 }
1378
1379#ifndef NDEBUG
1380 /* validate result */
1381 assert(-1 <= pos && pos < row->len);
1382 if( pos >= 0 )
1383 assert(row->cols[pos] == col);
1384 else
1385 {
1386 int i;
1387 for( i = 0; i < row->len; ++i )
1388 assert(row->cols[i] != col);
1389 }
1390#endif
1391
1392 return pos;
1393}
1394
1395/** moves a coefficient in a column to a different place, and updates all corresponding data structures */
1396static
1398 SCIP_COL* col, /**< LP column */
1399 int oldpos, /**< old position of coefficient */
1400 int newpos /**< new position of coefficient */
1401 )
1402{
1403 assert(col != NULL);
1404 assert(0 <= oldpos && oldpos < col->len);
1405 assert(0 <= newpos && newpos < col->len);
1406 assert(col->rows[oldpos] != NULL);
1407
1408 if( oldpos == newpos )
1409 return;
1410
1411 col->rows[newpos] = col->rows[oldpos];
1412 col->vals[newpos] = col->vals[oldpos];
1413 col->linkpos[newpos] = col->linkpos[oldpos];
1414
1415 /* update link position in row */
1416 if( col->linkpos[newpos] >= 0 )
1417 {
1418 assert(col->rows[newpos]->cols[col->linkpos[newpos]] == col);
1419 assert(col->rows[newpos]->linkpos[col->linkpos[newpos]] == oldpos);
1420
1421 col->rows[newpos]->linkpos[col->linkpos[newpos]] = newpos;
1422 }
1423
1424 /* update sorted flags */
1425 if( col->rows[newpos]->lppos >= 0 && col->linkpos[newpos] >= 0 )
1426 col->lprowssorted = FALSE;
1427 else
1428 col->nonlprowssorted = FALSE;
1429}
1430
1431/** swaps two coefficients in a column, and updates all corresponding data structures */
1432static
1434 SCIP_COL* col, /**< LP column */
1435 int pos1, /**< position of first coefficient */
1436 int pos2 /**< position of second coefficient */
1437 )
1438{
1439 SCIP_ROW* tmprow;
1440 SCIP_Real tmpval;
1441 int tmplinkpos;
1442
1443 assert(col != NULL);
1444 assert(0 <= pos1 && pos1 < col->len);
1445 assert(0 <= pos2 && pos2 < col->len);
1446 assert(col->rows[pos1] != NULL);
1447
1448 if( pos1 == pos2 )
1449 return;
1450
1451 /* swap coefficients */
1452 tmprow = col->rows[pos2];
1453 tmpval = col->vals[pos2];
1454 tmplinkpos = col->linkpos[pos2];
1455
1456 col->rows[pos2] = col->rows[pos1];
1457 col->vals[pos2] = col->vals[pos1];
1458 col->linkpos[pos2] = col->linkpos[pos1];
1459
1460 col->rows[pos1] = tmprow;
1461 col->vals[pos1] = tmpval;
1462 col->linkpos[pos1] = tmplinkpos;
1463
1464 /* update link position in rows */
1465 if( col->linkpos[pos1] >= 0 )
1466 {
1467 assert(col->rows[pos1]->cols[col->linkpos[pos1]] == col);
1468 assert(col->rows[pos1]->linkpos[col->linkpos[pos1]] == pos2);
1469
1470 col->rows[pos1]->linkpos[col->linkpos[pos1]] = pos1;
1471 }
1472 if( col->linkpos[pos2] >= 0 )
1473 {
1474 assert(col->rows[pos2]->cols[col->linkpos[pos2]] == col);
1475 assert(col->rows[pos2]->linkpos[col->linkpos[pos2]] == pos1);
1476
1477 col->rows[pos2]->linkpos[col->linkpos[pos2]] = pos2;
1478 }
1479
1480 /* update sorted flags */
1481 if( col->rows[pos1]->lppos >= 0 && col->linkpos[pos1] >= 0 )
1482 col->lprowssorted = FALSE;
1483 else
1484 col->nonlprowssorted = FALSE;
1485 if( col->rows[pos2]->lppos >= 0 && col->linkpos[pos2] >= 0 )
1486 col->lprowssorted = FALSE;
1487 else
1488 col->nonlprowssorted = FALSE;
1489}
1490
1491/** moves a coefficient in a row to a different place, and updates all corresponding data structures */
1492static
1494 SCIP_ROW* row, /**< LP row */
1495 int oldpos, /**< old position of coefficient */
1496 int newpos /**< new position of coefficient */
1497 )
1498{
1499 assert(row != NULL);
1500 assert(0 <= oldpos && oldpos < row->len);
1501 assert(0 <= newpos && newpos < row->len);
1502 assert(row->cols[oldpos] != NULL);
1503
1504 if( oldpos == newpos )
1505 return;
1506
1507 row->cols[newpos] = row->cols[oldpos];
1508 row->cols_index[newpos] = row->cols_index[oldpos];
1509 row->vals[newpos] = row->vals[oldpos];
1510 row->linkpos[newpos] = row->linkpos[oldpos];
1511
1512 /* update link position in column */
1513 if( row->linkpos[newpos] >= 0 )
1514 {
1515 assert(row->cols[newpos]->rows[row->linkpos[newpos]] == row);
1516 assert(row->cols[newpos]->linkpos[row->linkpos[newpos]] == oldpos);
1517
1518 row->cols[newpos]->linkpos[row->linkpos[newpos]] = newpos;
1519 }
1520
1521 /* update sorted flags */
1522 if( row->cols[newpos]->lppos >= 0 && row->linkpos[newpos] >= 0 )
1523 row->lpcolssorted = FALSE;
1524 else
1525 row->nonlpcolssorted = FALSE;
1526}
1527
1528/** swaps two coefficients in a row, and updates all corresponding data structures */
1529static
1531 SCIP_ROW* row, /**< LP row */
1532 int pos1, /**< position of first coefficient */
1533 int pos2 /**< position of second coefficient */
1534 )
1535{
1536 SCIP_COL* tmpcol;
1537 SCIP_Real tmpval;
1538 int tmpindex;
1539 int tmplinkpos;
1540
1541 assert(row != NULL);
1542 assert(0 <= pos1 && pos1 < row->len);
1543 assert(0 <= pos2 && pos2 < row->len);
1544 assert(row->cols[pos1] != NULL);
1545 assert(row->cols[pos1]->index == row->cols_index[pos1]);
1546
1547 if( pos1 == pos2 )
1548 return;
1549
1550 /* swap coefficients */
1551 tmpcol = row->cols[pos2];
1552 tmpindex = row->cols_index[pos2];
1553 tmpval = row->vals[pos2];
1554 tmplinkpos = row->linkpos[pos2];
1555
1556 row->cols[pos2] = row->cols[pos1];
1557 row->cols_index[pos2] = row->cols_index[pos1];
1558 row->vals[pos2] = row->vals[pos1];
1559 row->linkpos[pos2] = row->linkpos[pos1];
1560
1561 row->cols[pos1] = tmpcol;
1562 row->cols_index[pos1] = tmpindex;
1563 row->vals[pos1] = tmpval;
1564 row->linkpos[pos1] = tmplinkpos;
1565
1566 /* update link position in columns */
1567 if( row->linkpos[pos1] >= 0 )
1568 {
1569 assert(row->cols[pos1]->rows[row->linkpos[pos1]] == row);
1570 assert(row->cols[pos1]->linkpos[row->linkpos[pos1]] == pos2);
1571
1572 row->cols[pos1]->linkpos[row->linkpos[pos1]] = pos1;
1573 }
1574 if( row->linkpos[pos2] >= 0 )
1575 {
1576 assert(row->cols[pos2]->rows[row->linkpos[pos2]] == row);
1577 assert(row->cols[pos2]->linkpos[row->linkpos[pos2]] == pos1);
1578
1579 row->cols[pos2]->linkpos[row->linkpos[pos2]] = pos2;
1580 }
1581
1582 /* update sorted flags */
1583 if( row->cols[pos1]->lppos >= 0 && row->linkpos[pos1] >= 0 )
1584 row->lpcolssorted = FALSE;
1585 else
1586 row->nonlpcolssorted = FALSE;
1587 if( row->cols[pos2]->lppos >= 0 && row->linkpos[pos2] >= 0 )
1588 row->lpcolssorted = FALSE;
1589 else
1590 row->nonlpcolssorted = FALSE;
1591}
1592
1593/** issues a ROWCOEFCHANGED event on the given row */
1594static
1596 SCIP_ROW* row, /**< row which coefficient has changed */
1597 BMS_BLKMEM* blkmem, /**< block memory */
1598 SCIP_SET* set, /**< global SCIP settings */
1599 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1600 SCIP_COL* col, /**< the column which coefficient has changed */
1601 SCIP_Real oldval, /**< old value of the coefficient */
1602 SCIP_Real newval /**< new value of the coefficient */
1603 )
1604{
1605 assert(row != NULL);
1606 assert(row->eventfilter != NULL);
1607 assert(col != NULL);
1608
1609 /* check, if the row is being tracked for coefficient changes
1610 * if so, issue ROWCOEFCHANGED event
1611 */
1612 if( (row->eventfilter->len > 0 && (row->eventfilter->eventmask & SCIP_EVENTTYPE_ROWCOEFCHANGED) != 0) ) /*lint !e587*/
1613 {
1614 SCIP_EVENT* event;
1615
1616 SCIP_CALL( SCIPeventCreateRowCoefChanged(&event, blkmem, row, col, oldval, newval) );
1617 SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, row->eventfilter, &event) );
1618 }
1619
1620 return SCIP_OKAY;
1621}
1622
1623/** issues a ROWCONSTCHANGED event on the given row */
1624static
1626 SCIP_ROW* row, /**< row which coefficient has changed */
1627 BMS_BLKMEM* blkmem, /**< block memory */
1628 SCIP_SET* set, /**< global SCIP settings */
1629 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1630 SCIP_Real oldval, /**< old value of the constant */
1631 SCIP_Real newval /**< new value of the constant */
1632 )
1633{
1634 assert(row != NULL);
1635 assert(row->eventfilter != NULL);
1636
1637 /* check, if the row is being tracked for coefficient changes
1638 * if so, issue ROWCONSTCHANGED event
1639 */
1641 {
1642 SCIP_EVENT* event;
1643
1644 SCIP_CALL( SCIPeventCreateRowConstChanged(&event, blkmem, row, oldval, newval) );
1645 SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, row->eventfilter, &event) );
1646 }
1647
1648 return SCIP_OKAY;
1649}
1650
1651/** issues a ROWSIDECHANGED event on the given row */
1652static
1654 SCIP_ROW* row, /**< row which coefficient has changed */
1655 BMS_BLKMEM* blkmem, /**< block memory */
1656 SCIP_SET* set, /**< global SCIP settings */
1657 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1658 SCIP_SIDETYPE side, /**< the side that has changed */
1659 SCIP_Real oldval, /**< old value of side */
1660 SCIP_Real newval /**< new value of side */
1661 )
1662{
1663 assert(row != NULL);
1664 assert(row->eventfilter != NULL);
1665
1666 /* check, if the row is being tracked for coefficient changes
1667 * if so, issue ROWSIDECHANGED event
1668 */
1669 if( (row->eventfilter->len > 0 && !(row->eventfilter->eventmask & SCIP_EVENTTYPE_ROWSIDECHANGED)) )
1670 {
1671 SCIP_EVENT* event;
1672
1673 SCIP_CALL( SCIPeventCreateRowSideChanged(&event, blkmem, row, side, oldval, newval) );
1674 SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, row->eventfilter, &event) );
1675 }
1676
1677 return SCIP_OKAY;
1678}
1679
1680#ifdef SCIP_MORE_DEBUG /* enable this to check links between columns and rows in LP data structure (for debugging, very slow!) */
1681
1682#ifdef NDEBUG
1683#define ASSERT(x) do { if( !(x) ) abort(); } while( FALSE )
1684#else
1685#define ASSERT(x) assert(x)
1686#endif
1687
1688static SCIP_Bool msgdisp_checklinks = FALSE;
1689
1690
1691static
1692void checkLinks(
1693 SCIP_LP* lp /**< current LP data */
1694 )
1695{
1696 SCIP_COL* col;
1697 SCIP_ROW* row;
1698 int i;
1699 int j;
1700
1701 ASSERT(lp != NULL);
1702
1703 if( !msgdisp_checklinks )
1704 {
1705 printf("LP LINK CHECKING ACTIVATED! THIS IS VERY SLOW!\n");
1706 msgdisp_checklinks = TRUE;
1707 }
1708
1709 for( i = 0; i < lp->ncols; ++i )
1710 {
1711 col = lp->cols[i];
1712 ASSERT(col != NULL);
1713 ASSERT(!lp->flushed || col->lppos >= 0 || col->primsol == 0.0);
1714 ASSERT(!lp->flushed || col->lppos >= 0 || col->farkascoef == 0.0);
1715 ASSERT(col->nlprows <= col->len);
1716 ASSERT(col->lppos == -1 || col->lppos >= lp->lpifirstchgcol || col->nunlinked == 0);
1717
1718 for( j = 0; j < col->len; ++j )
1719 {
1720 row = col->rows[j];
1721 ASSERT(row != NULL);
1722 ASSERT(!lp->flushed || col->lppos == -1 || col->linkpos[j] >= 0);
1723 ASSERT(col->linkpos[j] == -1 || row->cols[col->linkpos[j]] == col);
1724 ASSERT(col->linkpos[j] == -1 || EPSEQ(row->vals[col->linkpos[j]], col->vals[j], 1e-6));
1725 ASSERT((j < col->nlprows) == (col->linkpos[j] >= 0 && row->lppos >= 0));
1726 }
1727 }
1728
1729 for( i = 0; i < lp->nrows; ++i )
1730 {
1731 row = lp->rows[i];
1732 ASSERT(row != NULL);
1733 ASSERT(!lp->flushed || row->lppos >= 0 || row->dualsol == 0.0);
1734 ASSERT(!lp->flushed || row->lppos >= 0 || row->dualfarkas == 0.0);
1735 ASSERT(row->nlpcols <= row->len);
1736 ASSERT(row->lppos == -1 || row->lppos >= lp->lpifirstchgrow || row->nunlinked == 0);
1737
1738 for( j = 0; j < row->len; ++j )
1739 {
1740 col = row->cols[j];
1741 ASSERT(col != NULL);
1742 ASSERT(!lp->flushed || row->lppos == -1 || row->linkpos[j] >= 0);
1743 ASSERT(row->linkpos[j] == -1 || col->rows[row->linkpos[j]] == row);
1744 ASSERT(row->linkpos[j] == -1 || EPSEQ(col->vals[row->linkpos[j]], row->vals[j], 1e-6));
1745 ASSERT((j < row->nlpcols) == (row->linkpos[j] >= 0 && col->lppos >= 0));
1746 }
1747 }
1748}
1749
1750#undef ASSERT
1751
1752#else
1753#define checkLinks(lp) /**/
1754#endif
1755
1756/*
1757 * Changing announcements
1758 */
1759
1760/** announces, that the given coefficient in the constraint matrix changed */
1761static
1763 SCIP_ROW* row, /**< LP row */
1764 SCIP_COL* col, /**< LP col */
1765 SCIP_LP* lp /**< current LP data */
1766 )
1767{
1768 assert(row != NULL);
1769 assert(col != NULL);
1770 assert(lp != NULL);
1771
1772 if( row->lpipos >= 0 && col->lpipos >= 0 )
1773 {
1774 assert(row->lpipos < lp->nlpirows);
1775 assert(col->lpipos < lp->nlpicols);
1776
1777 /* we have to remember the change only in the row or in the column,
1778 * because the readdition of one vector would change the other automatically.
1779 */
1780 if( row->lpipos >= lp->lpifirstchgrow )
1781 row->coefchanged = TRUE;
1782 else if( col->lpipos >= lp->lpifirstchgcol )
1783 col->coefchanged = TRUE;
1784 else if( lp->lpifirstchgrow - row->lpipos <= lp->lpifirstchgcol - col->lpipos )
1785 {
1786 row->coefchanged = TRUE;
1787 lp->lpifirstchgrow = row->lpipos;
1788 }
1789 else
1790 {
1791 col->coefchanged = TRUE;
1792 lp->lpifirstchgcol = col->lpipos;
1793 }
1794
1795 /* mark the current LP unflushed */
1796 lp->flushed = FALSE;
1797 }
1798
1802 row->validpsactivitydomchg = -1;
1803 row->validactivitybdsdomchg = -1;
1804}
1805
1806
1807
1808/*
1809 * local column changing methods
1810 */
1811
1812/* forward declaration for colAddCoef() */
1813static
1815 SCIP_ROW* row, /**< LP row */
1816 BMS_BLKMEM* blkmem, /**< block memory */
1817 SCIP_SET* set, /**< global SCIP settings */
1818 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1819 SCIP_LP* lp, /**< current LP data */
1820 SCIP_COL* col, /**< LP column */
1821 SCIP_Real val, /**< value of coefficient */
1822 int linkpos /**< position of row in the column's row array, or -1 */
1823 );
1824
1825/** adds a previously non existing coefficient to an LP column */
1826static
1828 SCIP_COL* col, /**< LP column */
1829 BMS_BLKMEM* blkmem, /**< block memory */
1830 SCIP_SET* set, /**< global SCIP settings */
1831 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1832 SCIP_LP* lp, /**< current LP data */
1833 SCIP_ROW* row, /**< LP row */
1834 SCIP_Real val, /**< value of coefficient */
1835 int linkpos /**< position of column in the row's col array, or -1 */
1836 )
1837{
1838 int pos;
1839
1840 assert(blkmem != NULL);
1841 assert(col != NULL);
1842 assert(col->nlprows <= col->len);
1843 assert(col->var != NULL);
1844 assert(row != NULL);
1845 assert(!SCIPsetIsZero(set, val));
1846 /*assert(colSearchCoef(col, row) == -1);*/ /* this assert would lead to slight differences in the solution process */
1847
1848 SCIP_CALL( colEnsureSize(col, blkmem, set, col->len+1) );
1849 assert(col->rows != NULL);
1850 assert(col->vals != NULL);
1851 assert(col->linkpos != NULL);
1852
1853 pos = col->len;
1854 col->len++;
1855
1856 /* if the row is in current LP and is linked to the column, we have to insert it at the end of the linked LP rows
1857 * part of the column's arrays
1858 */
1859 if( row->lppos >= 0 && linkpos >= 0 )
1860 {
1861 /* move the first non-LP/not linked row to the end */
1862 if( col->nlprows < pos )
1863 {
1864 colMoveCoef(col, col->nlprows, pos);
1865 pos = col->nlprows;
1866 }
1867 col->nlprows++;
1868 }
1869
1870 /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
1871 if( !set->exact_enable )
1872 val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
1873
1874 /* insert the row at the correct position and update the links */
1875 col->rows[pos] = row;
1876 col->vals[pos] = val;
1877 col->linkpos[pos] = linkpos;
1878 if( linkpos == -1 )
1879 {
1880 col->nunlinked++;
1881
1882 /* if the column is in current LP, we have to link it to the row, because otherwise, the primal information
1883 * of the row is not complete
1884 */
1885 if( col->lppos >= 0 )
1886 {
1887 /* this call might swap the current row with the first non-LP/not linked row, s.t. insertion position
1888 * has to be updated
1889 */
1890 SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, val, pos) );
1891 if( row->lppos >= 0 )
1892 pos = col->nlprows-1;
1893 linkpos = col->linkpos[pos];
1894
1895 assert(0 <= linkpos && linkpos < row->len);
1896 assert(row->cols[linkpos] == col);
1897 assert(col->rows[pos] == row);
1898 assert(col->rows[pos]->cols[col->linkpos[pos]] == col);
1899 assert(col->rows[pos]->linkpos[col->linkpos[pos]] == pos);
1900 }
1901 }
1902 else
1903 {
1904 assert(row->linkpos[linkpos] == -1);
1905 assert(row->nunlinked > 0);
1906 row->linkpos[linkpos] = pos;
1907 row->nunlinked--;
1908
1909 /* if the column is in current LP, now both conditions, row->cols[linkpos]->lppos >= 0 and row->linkpos[linkpos] >= 0
1910 * hold, so we have to move the column to the linked LP-cols part of the row's cols array
1911 */
1912 if( col->lppos >= 0 )
1913 {
1914 row->nlpcols++;
1915 rowSwapCoefs(row, linkpos, row->nlpcols-1);
1916
1917 /* if no swap was necessary, mark nonlpcols to be unsorted */
1918 if( linkpos == row->nlpcols-1 )
1919 row->lpcolssorted = FALSE;
1920 }
1921 }
1922
1923 /* update the sorted flags */
1924 if( row->lppos >= 0 && linkpos >= 0 )
1925 {
1926 assert(col->nlprows >= 1);
1927 assert(col->rows[col->nlprows-1] == row);
1928 if( col->nlprows > 1 )
1929 col->lprowssorted = col->lprowssorted && (col->rows[col->nlprows-2]->index < row->index);
1930 }
1931 else
1932 {
1933 assert(col->len - col->nlprows >= 1);
1934 assert(col->rows[col->len-1] == row);
1935 if( col->len - col->nlprows > 1 )
1936 col->nonlprowssorted = col->nonlprowssorted && (col->rows[col->len-2]->index < row->index);
1937 }
1938
1939 coefChanged(row, col, lp);
1940
1941 SCIPsetDebugMsg(set, "added coefficient %g * <%s> at position %d (%d/%d) to column <%s> (nunlinked=%d)\n",
1942 val, row->name, pos, col->nlprows, col->len, SCIPvarGetName(col->var), col->nunlinked);
1943
1944 return SCIP_OKAY;
1945}
1946
1947/** deletes coefficient at given position from column */
1948static
1950 SCIP_COL* col, /**< column to be changed */
1951 SCIP_SET* set, /**< global SCIP settings */
1952 SCIP_LP* lp, /**< current LP data */
1953 int pos /**< position in column vector to delete */
1954 )
1955{
1956 SCIP_ROW* row;
1957
1958 assert(col != NULL);
1959 assert(col->var != NULL);
1960 assert(set != NULL);
1961 assert(0 <= pos && pos < col->len);
1962 assert(col->rows[pos] != NULL);
1963 assert(col->linkpos[pos] == -1 || col->rows[pos]->cols[col->linkpos[pos]] == col);
1964 assert((pos < col->nlprows) == (col->linkpos[pos] >= 0 && col->rows[pos]->lppos >= 0));
1965
1966 row = col->rows[pos];
1967 assert((row->lppos >= 0) == (pos < col->nlprows));
1968
1969 /*SCIPsetDebugMsg(set, "deleting coefficient %g * <%s> at position %d from column <%s>\n",
1970 col->vals[pos], row->name, pos, SCIPvarGetName(col->var));*/
1971
1972 if( col->linkpos[pos] == -1 )
1973 col->nunlinked--;
1974
1975 /* if row is a linked LP row, move last linked LP coefficient to position of empty slot (deleted coefficient) */
1976 if( pos < col->nlprows )
1977 {
1978 colMoveCoef(col, col->nlprows-1, pos);
1979 col->nlprows--;
1980 pos = col->nlprows;
1981 }
1982
1983 /* move last coefficient to position of empty slot */
1984 colMoveCoef(col, col->len-1, pos);
1985 col->len--;
1986
1987 coefChanged(row, col, lp);
1988
1989 return SCIP_OKAY;
1990}
1991
1992/** changes a coefficient at given position of an LP column */
1993static
1995 SCIP_COL* col, /**< LP column */
1996 SCIP_SET* set, /**< global SCIP settings */
1997 SCIP_LP* lp, /**< current LP data */
1998 int pos, /**< position in column vector to change */
1999 SCIP_Real val /**< value of coefficient */
2000 )
2001{
2002 assert(col != NULL);
2003 assert(col->var != NULL);
2004 assert(0 <= pos && pos < col->len);
2005 assert(col->rows[pos] != NULL);
2006 assert(col->linkpos[pos] == -1 || col->rows[pos]->cols[col->linkpos[pos]] == col);
2007
2008 /*debugMsg(scip, "changing coefficient %g * <%s> at position %d of column <%s> to %g\n",
2009 col->vals[pos], col->rows[pos]->name, pos, SCIPvarGetName(col->var), val);*/
2010
2011 /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
2012 if( !set->exact_enable )
2013 val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
2014
2015 if( SCIPsetIsZero(set, val) )
2016 {
2017 /* delete existing coefficient */
2018 SCIP_CALL( colDelCoefPos(col, set, lp, pos) );
2019 }
2020 else if( !SCIPsetIsEQ(set, col->vals[pos], val) )
2021 {
2022 /* change existing coefficient */
2023 col->vals[pos] = val;
2024 coefChanged(col->rows[pos], col, lp);
2025 }
2026
2027 return SCIP_OKAY;
2028}
2029
2030
2031
2032
2033/*
2034 * local row changing methods
2035 */
2036
2037/** update row norms after addition of coefficient */
2038static
2040 SCIP_ROW* row, /**< LP row */
2041 SCIP_SET* set, /**< global SCIP settings */
2042 SCIP_COL* col, /**< column of added coefficient */
2043 SCIP_Real val, /**< value of added coefficient */
2044 SCIP_Bool updateidxvals /**< update min/max idx and min/max val? */
2045 )
2046{
2047 SCIP_Real absval;
2048
2049 assert(row != NULL);
2050 assert(row->nummaxval >= 0);
2051 assert(row->numminval >= 0);
2052 assert(set != NULL);
2053 assert(col != NULL);
2054
2055 absval = REALABS(val);
2056 assert(!SCIPsetIsZero(set, absval));
2057
2058 /* Euclidean norm, sum norm, and objective function scalar product only take LP columns into account */
2059 if( col->lppos >= 0 )
2060 {
2061 /* update squared Euclidean norm and sum norm */
2062 row->sqrnorm += SQR(absval);
2063 row->sumnorm += absval;
2064
2065 /* update objective function scalar product */
2066 row->objprod += val * col->unchangedobj;
2067 }
2068
2069 if( updateidxvals )
2070 {
2071 /* update min/maxidx */
2072 row->minidx = MIN(row->minidx, col->index);
2073 row->maxidx = MAX(row->maxidx, col->index);
2074
2075 /* update maximal and minimal non-zero value */
2076 if( row->nummaxval > 0 )
2077 {
2078 if( SCIPsetIsGT(set, absval, row->maxval) )
2079 {
2080 row->maxval = absval;
2081 row->nummaxval = 1;
2082 }
2083 else if( SCIPsetIsGE(set, absval, row->maxval) )
2084 {
2085 /* make sure the maxval is always exactly the same */
2086 row->maxval = MAX(absval, row->maxval);
2087 row->nummaxval++;
2088 }
2089 }
2090 if( row->numminval > 0 )
2091 {
2092 if( SCIPsetIsLT(set, absval, row->minval) )
2093 {
2094 row->minval = absval;
2095 row->numminval = 1;
2096 }
2097 else if( SCIPsetIsLE(set, absval, row->minval) )
2098 {
2099 /* make sure the minval is always exactly the same */
2100 row->minval = MIN(absval, row->minval);
2101 row->numminval++;
2102 }
2103 }
2104 }
2105 else
2106 {
2107 assert(row->minidx <= col->index);
2108 assert(row->maxidx >= col->index);
2109 assert(row->numminval <= 0 || absval >= row->minval);
2110 assert(row->nummaxval <= 0 || absval <= row->maxval);
2111 }
2112}
2113
2114/** update row norms after deletion of coefficient */
2115static
2117 SCIP_ROW* row, /**< LP row */
2118 SCIP_SET* set, /**< global SCIP settings */
2119 SCIP_COL* col, /**< column of deleted coefficient */
2120 SCIP_Real val, /**< value of deleted coefficient */
2121 SCIP_Bool forcenormupdate, /**< should the norms be updated even if lppos of column is -1? */
2122 SCIP_Bool updateindex, /**< should the minimal/maximal column index of row be updated? */
2123 SCIP_Bool updateval /**< should the minimal/maximal value of row be updated? */
2124 )
2125{
2126 SCIP_Real absval;
2127
2128 assert(row != NULL);
2129 assert(row->nummaxval >= 0);
2130 assert(row->numminval >= 0);
2131 assert(set != NULL);
2132 assert(col != NULL);
2133
2134 absval = REALABS(val);
2135 assert(!SCIPsetIsZero(set, absval));
2136 assert(row->nummaxval == 0 || row->maxval >= absval);
2137 assert(row->numminval == 0 || row->minval <= absval);
2138
2139 /* update min/maxidx validity */
2140 if( updateindex && (col->index == row->minidx || col->index == row->maxidx) )
2141 row->validminmaxidx = FALSE;
2142
2143 /* Euclidean norm, sum norm, and objective function scalar product only take LP columns into account */
2144 if( forcenormupdate || col->lppos >= 0 )
2145 {
2146 /* update squared Euclidean norm and sum norm */
2147 row->sqrnorm -= SQR(absval);
2148 row->sqrnorm = MAX(row->sqrnorm, 0.0);
2149 row->sumnorm -= absval;
2150 row->sumnorm = MAX(row->sumnorm, 0.0);
2151
2152 /* update objective function scalar product */
2153 row->objprod -= val * col->unchangedobj;
2154 }
2155
2156 if( updateval )
2157 {
2158 /* update maximal and minimal non-zero value */
2159 if( row->nummaxval > 0 )
2160 {
2161 if( SCIPsetIsGE(set, absval, row->maxval) )
2162 row->nummaxval--;
2163 }
2164 if( row->numminval > 0 )
2165 {
2166 if( SCIPsetIsLE(set, absval, row->minval) )
2167 row->numminval--;
2168 }
2169 }
2170}
2171
2172/** adds a previously non existing coefficient to an LP row */
2173static
2175 SCIP_ROW* row, /**< LP row */
2176 BMS_BLKMEM* blkmem, /**< block memory */
2177 SCIP_SET* set, /**< global SCIP settings */
2178 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2179 SCIP_LP* lp, /**< current LP data */
2180 SCIP_COL* col, /**< LP column */
2181 SCIP_Real val, /**< value of coefficient */
2182 int linkpos /**< position of row in the column's row array, or -1 */
2183 )
2184{
2185 int pos;
2186
2187 assert(row != NULL);
2188 assert(row->nlpcols <= row->len);
2189 assert(blkmem != NULL);
2190 assert(col != NULL);
2191 assert(col->var != NULL);
2193 assert(!SCIPsetIsZero(set, val));
2194 /*assert(rowSearchCoef(row, col) == -1);*/ /* this assert would lead to slight differences in the solution process */
2195
2196 if( row->nlocks > 0 )
2197 {
2198 SCIPerrorMessage("cannot add a coefficient to the locked unmodifiable row <%s>\n", row->name);
2199 return SCIP_INVALIDDATA;
2200 }
2201
2202 SCIP_CALL( SCIProwEnsureSize(row, blkmem, set, row->len+1) );
2203 assert(row->cols != NULL);
2204 assert(row->vals != NULL);
2205
2206 pos = row->len;
2207 row->len++;
2208
2209 /* if the column is in current LP and is linked to the row, we have to insert it at the end of the linked LP columns
2210 * part of the row's arrays
2211 */
2212 if( col->lppos >= 0 && linkpos >= 0 )
2213 {
2214 /* move the first non-LP/not linked column to the end */
2215 if( row->nlpcols < pos )
2216 {
2217 rowMoveCoef(row, row->nlpcols, pos);
2218 pos = row->nlpcols;
2219 }
2220 row->nlpcols++;
2221 }
2222
2223 /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
2224 if( !set->exact_enable )
2225 val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
2226
2227 /* insert the column at the correct position and update the links */
2228 row->cols[pos] = col;
2229 row->cols_index[pos] = col->index;
2230 row->vals[pos] = val;
2231 row->linkpos[pos] = linkpos;
2232 row->integral = row->integral && SCIPcolIsIntegral(col) && SCIPsetIsIntegral(set, val);
2233 if( set->exact_enable )
2235 if( linkpos == -1 )
2236 {
2237 row->nunlinked++;
2238
2239 /* if the row is in current LP, we have to link it to the column, because otherwise, the dual information
2240 * of the column is not complete
2241 */
2242 if( row->lppos >= 0 )
2243 {
2244 /* this call might swap the current column with the first non-LP/not linked column, s.t. insertion position
2245 * has to be updated
2246 */
2247 SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, val, pos) );
2248 if( col->lppos >= 0 )
2249 pos = row->nlpcols-1;
2250 linkpos = row->linkpos[pos];
2251
2252 assert(0 <= linkpos && linkpos < col->len);
2253 assert(col->rows[linkpos] == row);
2254 assert(row->cols[pos] == col);
2255 assert(row->cols[pos]->rows[row->linkpos[pos]] == row);
2256 assert(row->cols[pos]->linkpos[row->linkpos[pos]] == pos);
2257 }
2258 }
2259 else
2260 {
2261 assert(col->linkpos[linkpos] == -1);
2262 assert(col->nunlinked > 0);
2263 col->linkpos[linkpos] = pos;
2264 col->nunlinked--;
2265
2266 /* if the row is in current LP, now both conditions, col->rows[linkpos]->lppos >= 0 and col->linkpos[linkpos] >= 0
2267 * hold, so we have to move the row to the linked LP-rows part of the column's rows array
2268 */
2269 if( row->lppos >= 0 )
2270 {
2271 col->nlprows++;
2272 colSwapCoefs(col, linkpos, col->nlprows-1);
2273
2274 /* if no swap was necessary, mark lprows to be unsorted */
2275 if( linkpos == col->nlprows-1 )
2276 col->lprowssorted = FALSE;
2277 }
2278 }
2279
2280 /* update the sorted flags */
2281 if( col->lppos >= 0 && linkpos >= 0 )
2282 {
2283 assert(row->nlpcols >= 1);
2284 assert(row->cols[row->nlpcols-1] == col);
2285 if( row->nlpcols > 1 )
2286 {
2287 assert(row->cols_index[row->nlpcols-2] == row->cols[row->nlpcols-2]->index);
2288 row->lpcolssorted = row->lpcolssorted && (row->cols_index[row->nlpcols-2] < col->index);
2289 }
2290 }
2291 else
2292 {
2293 assert(row->len - row->nlpcols >= 1);
2294 assert(row->cols[row->len-1] == col);
2295 if( row->len - row->nlpcols > 1 )
2296 {
2297 assert(row->cols_index[row->len-2] == row->cols[row->len-2]->index);
2298 row->nonlpcolssorted = row->nonlpcolssorted && (row->cols_index[row->len-2] < col->index);
2299 }
2300 }
2301
2302 /* update row norm */
2303 rowAddNorms(row, set, col, val, TRUE);
2304
2305 coefChanged(row, col, lp);
2306
2307 SCIPsetDebugMsg(set, "added coefficient %g * <%s> at position %d (%d/%d) to row <%s> (nunlinked=%d)\n",
2308 val, SCIPvarGetName(col->var), pos, row->nlpcols, row->len, row->name, row->nunlinked);
2309
2310 /* issue row coefficient changed event */
2311 SCIP_CALL( rowEventCoefChanged(row, blkmem, set, eventqueue, col, 0.0, val) );
2312
2313 return SCIP_OKAY;
2314}
2315
2316/** deletes coefficient at given position from row */
2317static
2319 SCIP_ROW* row, /**< row to be changed */
2320 BMS_BLKMEM* blkmem, /**< block memory */
2321 SCIP_SET* set, /**< global SCIP settings */
2322 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2323 SCIP_LP* lp, /**< current LP data */
2324 int pos /**< position in row vector to delete */
2325 )
2326{
2327 SCIP_COL* col;
2328 SCIP_Real val;
2329
2330 assert(row != NULL);
2331 assert(set != NULL);
2332 assert(0 <= pos && pos < row->len);
2333 assert(row->cols[pos] != NULL);
2334 assert((pos < row->nlpcols) == (row->linkpos[pos] >= 0 && row->cols[pos]->lppos >= 0));
2335
2336 col = row->cols[pos];
2337 val = row->vals[pos];
2338 assert((pos < row->nlpcols) == (col->lppos >= 0 && row->linkpos[pos] >= 0));
2339
2340 /*SCIPsetDebugMsg(set, "deleting coefficient %g * <%s> at position %d from row <%s>\n",
2341 val, SCIPvarGetName(col->var), pos, row->name);*/
2342
2343 if( row->nlocks > 0 )
2344 {
2345 SCIPerrorMessage("cannot delete a coefficient from the locked unmodifiable row <%s>\n", row->name);
2346 return SCIP_INVALIDDATA;
2347 }
2348
2349 if( row->linkpos[pos] == -1 )
2350 row->nunlinked--;
2351
2352 /* if column is a linked LP column, move last linked LP coefficient to position of empty slot (deleted coefficient) */
2353 if( pos < row->nlpcols )
2354 {
2355 rowMoveCoef(row, row->nlpcols-1, pos);
2356 row->nlpcols--;
2357 pos = row->nlpcols;
2358 }
2359
2360 /* move last coefficient to position of empty slot */
2361 rowMoveCoef(row, row->len-1, pos);
2362 row->len--;
2363
2364 /* update norms */
2365 rowDelNorms(row, set, col, val, FALSE, TRUE, TRUE);
2366
2367 coefChanged(row, col, lp);
2368
2369 /* issue row coefficient changed event */
2370 SCIP_CALL( rowEventCoefChanged(row, blkmem, set, eventqueue, col, val, 0.0) );
2371
2372 return SCIP_OKAY;
2373}
2374
2375/** changes a coefficient at given position of an LP row */
2376static
2378 SCIP_ROW* row, /**< LP row */
2379 BMS_BLKMEM* blkmem, /**< block memory */
2380 SCIP_SET* set, /**< global SCIP settings */
2381 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2382 SCIP_LP* lp, /**< current LP data */
2383 int pos, /**< position in row vector to change */
2384 SCIP_Real val /**< value of coefficient */
2385 )
2386{
2387 SCIP_COL* col;
2388
2389 assert(row != NULL);
2390 assert(0 <= pos && pos < row->len);
2391
2392 /*SCIPsetDebugMsg(set, "changing coefficient %g * <%s> at position %d of row <%s> to %g\n",
2393 row->vals[pos], SCIPvarGetName(row->cols[pos]->var), pos, row->name, val);*/
2394
2395 if( row->nlocks > 0 )
2396 {
2397 SCIPerrorMessage("cannot change a coefficient of the locked unmodifiable row <%s>\n", row->name);
2398 return SCIP_INVALIDDATA;
2399 }
2400
2401 /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
2402 if( !set->exact_enable )
2403 val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
2404 col = row->cols[pos];
2405 assert(row->cols[pos] != NULL);
2406
2407 if( SCIPsetIsZero(set, val) )
2408 {
2409 /* delete existing coefficient */
2410 SCIP_CALL( rowDelCoefPos(row, blkmem, set, eventqueue, lp, pos) );
2411 }
2412 else if( !SCIPsetIsEQ(set, row->vals[pos], val) || (set->exact_enable && row->vals[pos] != val) ) /*lint !e777*/
2413 {
2414 SCIP_Real oldval;
2415
2416 oldval = row->vals[pos];
2417
2418 /* change existing coefficient */
2419 rowDelNorms(row, set, col, row->vals[pos], FALSE, FALSE, TRUE);
2420 row->vals[pos] = val;
2421 row->integral = row->integral && SCIPcolIsIntegral(col) && SCIPsetIsIntegral(set, val);
2422 if( set->exact_enable )
2424 rowAddNorms(row, set, col, row->vals[pos], TRUE);
2425 coefChanged(row, col, lp);
2426
2427 /* issue row coefficient changed event */
2428 SCIP_CALL( rowEventCoefChanged(row, blkmem, set, eventqueue, col, oldval, val) );
2429 }
2430
2431 return SCIP_OKAY;
2432}
2433
2434/** notifies LP row, that its sides were changed */
2435static
2437 SCIP_ROW* row, /**< LP row */
2438 SCIP_SET* set, /**< global SCIP settings */
2439 SCIP_LP* lp, /**< current LP data */
2440 SCIP_SIDETYPE sidetype /**< type of side: left or right hand side */
2441 )
2442{
2443 assert(row != NULL);
2444 assert(lp != NULL);
2445
2446 if( row->lpipos >= 0 )
2447 {
2448 /* insert row in the chgrows list (if not already there) */
2449 if( !row->lhschanged && !row->rhschanged )
2450 {
2451 SCIP_CALL( ensureChgrowsSize(lp, set, lp->nchgrows+1) );
2452 lp->chgrows[lp->nchgrows] = row;
2453 lp->nchgrows++;
2454 }
2455
2456 /* mark side change in the row */
2457 switch( sidetype )
2458 {
2459 case SCIP_SIDETYPE_LEFT:
2460 row->lhschanged = TRUE;
2461 break;
2463 row->rhschanged = TRUE;
2464 break;
2465 default:
2466 SCIPerrorMessage("unknown row side type\n");
2467 SCIPABORT();
2468 return SCIP_INVALIDDATA; /*lint !e527*/
2469 }
2470
2471 /* mark the current LP unflushed */
2472 lp->flushed = FALSE;
2473
2474 assert(lp->nchgrows > 0);
2475 }
2476
2477 return SCIP_OKAY;
2478}
2479
2480
2481
2482
2483/*
2484 * double linked coefficient matrix methods
2485 */
2486
2487/** insert column coefficients in corresponding rows */
2489 SCIP_COL* col, /**< column data */
2490 BMS_BLKMEM* blkmem, /**< block memory */
2491 SCIP_SET* set, /**< global SCIP settings */
2492 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2493 SCIP_LP* lp /**< current LP data */
2494 )
2495{
2496 int i;
2497
2498 assert(col != NULL);
2499 assert(col->var != NULL);
2500 assert(blkmem != NULL);
2501 assert(set != NULL);
2502 assert(lp != NULL);
2503
2504 if( col->nunlinked > 0 )
2505 {
2506 SCIPsetDebugMsg(set, "linking column <%s>\n", SCIPvarGetName(col->var));
2507
2508 /* unlinked rows can only be in the non-LP/unlinked rows part of the rows array */
2509 for( i = col->nlprows; i < col->len; ++i )
2510 {
2511 assert(!SCIPsetIsZero(set, col->vals[i]));
2512 if( col->linkpos[i] == -1 )
2513 {
2514 /* this call might swap the current row with the first non-LP/not linked row, but this is of no harm */
2515 SCIP_CALL( rowAddCoef(col->rows[i], blkmem, set, eventqueue, lp, col, col->vals[i], i) );
2516 }
2517 assert(col->rows[i]->cols[col->linkpos[i]] == col);
2518 assert(col->rows[i]->linkpos[col->linkpos[i]] == i);
2519 assert(col->nlprows == 0 || col->rows[col->nlprows-1]->cols[col->linkpos[col->nlprows-1]] == col);
2520 assert(col->nlprows == 0 || col->rows[col->nlprows-1]->linkpos[col->linkpos[col->nlprows-1]] == col->nlprows-1);
2521 }
2522 }
2523 assert(col->nunlinked == 0);
2524
2525 checkLinks(lp);
2526
2527 return SCIP_OKAY;
2528}
2529
2530/** removes column coefficients from corresponding rows */
2532 SCIP_COL* col, /**< column data */
2533 BMS_BLKMEM* blkmem, /**< block memory */
2534 SCIP_SET* set, /**< global SCIP settings */
2535 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2536 SCIP_LP* lp /**< current LP data */
2537 )
2538{
2539 int i;
2540
2541 assert(col != NULL);
2542 assert(col->var != NULL);
2543 assert(blkmem != NULL);
2544 assert(set != NULL);
2545 assert(lp != NULL);
2546
2547 if( col->nunlinked < col->len )
2548 {
2549 SCIPsetDebugMsg(set, "unlinking column <%s>\n", SCIPvarGetName(col->var));
2550 for( i = 0; i < col->len; ++i )
2551 {
2552 if( col->linkpos[i] >= 0 )
2553 {
2554 assert(col->rows[i]->cols[col->linkpos[i]] == col);
2555 SCIP_CALL( rowDelCoefPos(col->rows[i], blkmem, set, eventqueue, lp, col->linkpos[i]) );
2556 col->linkpos[i] = -1;
2557 col->nunlinked++;
2558 }
2559 }
2560 }
2561 assert(col->nunlinked == col->len);
2562
2563 checkLinks(lp);
2564
2565 return SCIP_OKAY;
2566}
2567
2568/** insert row coefficients in corresponding columns */
2570 SCIP_ROW* row, /**< row data */
2571 BMS_BLKMEM* blkmem, /**< block memory */
2572 SCIP_SET* set, /**< global SCIP settings */
2573 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2574 SCIP_LP* lp /**< current LP data */
2575 )
2576{
2577 int i;
2578
2579 assert(row != NULL);
2580 assert(blkmem != NULL);
2581 assert(set != NULL);
2582 assert(lp != NULL);
2583
2584 if( row->nunlinked > 0 )
2585 {
2586 SCIPsetDebugMsg(set, "linking row <%s>\n", row->name);
2587
2588 /* unlinked columns can only be in the non-LP/unlinked columns part of the cols array */
2589 for( i = row->nlpcols; i < row->len; ++i )
2590 {
2591 assert(!SCIPsetIsZero(set, row->vals[i]));
2592 if( row->linkpos[i] == -1 )
2593 {
2594 /* this call might swap the current column with the first non-LP/not linked column, but this is of no harm */
2595 SCIP_CALL( colAddCoef(row->cols[i], blkmem, set, eventqueue, lp, row, row->vals[i], i) );
2596 }
2597 assert(row->cols[i]->rows[row->linkpos[i]] == row);
2598 assert(row->cols[i]->linkpos[row->linkpos[i]] == i);
2599 assert(row->nlpcols == 0 || row->cols[row->nlpcols-1]->rows[row->linkpos[row->nlpcols-1]] == row);
2600 assert(row->nlpcols == 0 || row->cols[row->nlpcols-1]->linkpos[row->linkpos[row->nlpcols-1]] == row->nlpcols-1);
2601 }
2602 }
2603 assert(row->nunlinked == 0);
2604
2605 checkLinks(lp);
2606
2607 return SCIP_OKAY;
2608}
2609
2610/** removes row coefficients from corresponding columns */
2612 SCIP_ROW* row, /**< row data */
2613 SCIP_SET* set, /**< global SCIP settings */
2614 SCIP_LP* lp /**< current LP data */
2615 )
2616{
2617 int i;
2618
2619 assert(row != NULL);
2620 assert(set != NULL);
2621 assert(lp != NULL);
2622
2623 if( row->nunlinked < row->len )
2624 {
2625 SCIPsetDebugMsg(set, "unlinking row <%s>\n", row->name);
2626 for( i = 0; i < row->len; ++i )
2627 {
2628 if( row->linkpos[i] >= 0 )
2629 {
2630 assert(row->cols[i]->rows[row->linkpos[i]] == row);
2631 SCIP_CALL( colDelCoefPos(row->cols[i], set, lp, row->linkpos[i]) );
2632 row->nunlinked++;
2633 }
2634 }
2635 }
2636 assert(row->nunlinked == row->len);
2637
2638 return SCIP_OKAY;
2639}
2640
2641
2642
2643
2644/*
2645 * local LP parameter methods
2646 */
2647
2648/** sets parameter of type int in LP solver, ignoring unknown parameters */
2649static
2651 SCIP_LP* lp, /**< current LP data */
2652 SCIP_LPPARAM lpparam, /**< LP parameter */
2653 int value, /**< value to set parameter to */
2654 SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2655 )
2656{
2657 SCIP_RETCODE retcode;
2658
2659 assert(lp != NULL);
2660 assert(success != NULL);
2661
2662 retcode = SCIPlpiSetIntpar(lp->lpi, lpparam, value);
2663
2664 /* check, if parameter is unknown */
2665 if( retcode == SCIP_PARAMETERUNKNOWN )
2666 {
2667 *success = FALSE;
2668 return SCIP_OKAY;
2669 }
2670 *success = TRUE;
2671
2672 return retcode;
2673}
2674
2675/** sets parameter of type SCIP_Bool in LP solver, ignoring unknown parameters */
2676static
2678 SCIP_LP* lp, /**< current LP data */
2679 SCIP_LPPARAM lpparam, /**< LP parameter */
2680 SCIP_Bool value, /**< value to set parameter to */
2681 SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2682 )
2683{
2684 return lpSetIntpar(lp, lpparam, (int)value, success);
2685}
2686
2687/** sets parameter of type SCIP_Real in LP solver, ignoring unknown parameters */
2688static
2690 SCIP_LP* lp, /**< current LP data */
2691 SCIP_LPPARAM lpparam, /**< LP parameter */
2692 SCIP_Real value, /**< value to set parameter to */
2693 SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2694 )
2695{
2696 SCIP_RETCODE retcode;
2697
2698 assert(lp != NULL);
2699 assert(success != NULL);
2700
2701 retcode = SCIPlpiSetRealpar(lp->lpi, lpparam, value);
2702
2703 /* check, if parameter is unknown */
2704 if( retcode == SCIP_PARAMETERUNKNOWN )
2705 {
2706 *success = FALSE;
2707 return SCIP_OKAY;
2708 }
2709 *success = TRUE;
2710
2711 return retcode;
2712}
2713
2714#ifndef NDEBUG
2715/** checks that parameter of type int in LP solver has the given value, ignoring unknown parameters */
2716static
2718 SCIP_LP* lp, /**< current LP data */
2719 SCIP_LPPARAM lpparam, /**< LP parameter */
2720 int value /**< value parameter should have */
2721 )
2722{
2723 SCIP_RETCODE retcode;
2724 int lpivalue;
2725
2726 assert(lp != NULL);
2727
2728 retcode = SCIPlpiGetIntpar(lp->lpi, lpparam, &lpivalue);
2729
2730 /* ignore unknown parameter error */
2731 if( retcode == SCIP_PARAMETERUNKNOWN )
2732 return SCIP_OKAY;
2733
2734 /* check value */
2735 assert(lpivalue == value);
2736
2737 return retcode;
2738}
2739
2740/** checks that parameter of type SCIP_Bool in LP solver has the given value, ignoring unknown parameters */
2741static
2743 SCIP_LP* lp, /**< current LP data */
2744 SCIP_LPPARAM lpparam, /**< LP parameter */
2745 SCIP_Bool value /**< value parameter should have */
2746 )
2747{
2748 return lpCheckIntpar(lp, lpparam, (int)value);
2749}
2750
2751/** checks that parameter of type SCIP_Real in LP solver has the given value, ignoring unknown parameters */
2752static
2754 SCIP_LP* lp, /**< current LP data */
2755 SCIP_LPPARAM lpparam, /**< LP parameter */
2756 SCIP_Real value /**< value parameter should have */
2757 )
2758{
2759 SCIP_RETCODE retcode;
2760 SCIP_Real lpivalue;
2761
2762 assert(lp != NULL);
2763
2764 retcode = SCIPlpiGetRealpar(lp->lpi, lpparam, &lpivalue);
2765
2766 /* ignore unknown parameter error */
2767 if( retcode == SCIP_PARAMETERUNKNOWN )
2768 return SCIP_OKAY;
2769
2770 /* check value */
2771 assert(lpivalue == value); /*lint !e777*/
2772
2773 return retcode;
2774}
2775#else
2776#define lpCheckIntpar(lp, lpparam, value) SCIP_OKAY
2777#define lpCheckBoolpar(lp, lpparam, value) SCIP_OKAY
2778#define lpCheckRealpar(lp, lpparam, value) SCIP_OKAY
2779#endif
2780
2781/** should the objective limit of the LP solver be disabled */
2782#define lpCutoffDisabled(set, prob, lp) (set->lp_disablecutoff == 1 || (set->lp_disablecutoff == 2 && !SCIPprobAllColsInLP(prob, set, lp)))
2783
2784/** sets the objective limit of the LP solver
2785 *
2786 * Note that we are always minimizing.
2787 */
2788static
2790 SCIP_LP* lp, /**< current LP data */
2791 SCIP_SET* set, /**< global SCIP settings */
2792 SCIP_PROB* prob, /**< problem data */
2793 SCIP_Real objlim, /**< new objective limit */
2794 SCIP_Bool* success /**< pointer to store whether the parameter was actually changed */
2795 )
2796{
2797 assert(lp != NULL);
2798 assert(set != NULL);
2799 assert(success != NULL);
2800
2801 *success = FALSE;
2802
2803 /* if the objective limit is disabled or SCIP infinity, make sure that the LP objective limit is deactivated by
2804 * setting it to the LP solver's infinity
2805 */
2806 if( lpCutoffDisabled(set, prob, lp) || SCIPsetIsInfinity(set, objlim) )
2807 objlim = SCIPlpiInfinity(lp->lpi);
2808
2810
2811 if( objlim != lp->lpiobjlim ) /*lint !e777*/
2812 {
2813 SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_OBJLIM, objlim, success) );
2814 if( *success )
2815 {
2816 SCIP_Real actualobjlim;
2817
2818 /* check whether the parameter was actually changed or already was at the boundary of the LP solver's parameter range */
2819 SCIP_CALL( SCIPlpiGetRealpar(lp->lpi, SCIP_LPPAR_OBJLIM, &actualobjlim) );
2820 if( actualobjlim != lp->lpiobjlim ) /*lint !e777*/
2821 {
2822 /* mark the current solution invalid */
2823 lp->solved = FALSE;
2824 lp->primalfeasible = FALSE;
2825 lp->primalchecked = FALSE;
2826 lp->lpobjval = SCIP_INVALID;
2828 }
2829 lp->lpiobjlim = actualobjlim;
2830 }
2831 }
2832
2833 return SCIP_OKAY;
2834}
2835
2836/** adjust the objective limit of the lp solver to make safe dual bounding possible
2837 *
2838 * Note that we are always minimizing.
2839 */
2840static
2842 SCIP_LP* lp, /**< current LP data */
2843 SCIP_SET* set, /**< global SCIP settings */
2844 SCIP_PROB* prob, /**< problem data */
2845 SCIP_STAT* stat, /**< problem statistics */
2846 SCIP_Bool* success /**< pointer to store whether the parameter was actually changed */
2847 )
2848{
2849 SCIP_Real adjustedobjlim;
2850 SCIP_Real avgboundingerror;
2851
2852 assert(lp != NULL);
2853 assert(set != NULL);
2854 assert(success != NULL);
2855
2856 *success = FALSE;
2857
2858 /* we disabled the objective limit in the LP solver or we are not in exact solving mode */
2859 if( !set->exact_enable || lpCutoffDisabled(set, prob, lp) )
2860 return SCIP_OKAY;
2861
2862 /* no need to adjust in infinity case */
2863 if( SCIPsetIsInfinity(set, lp->lpiobjlim) )
2864 return SCIP_OKAY;
2865
2867
2868 if( stat->nboundshift + stat->nprojshift + stat->nexlp == 0 )
2869 avgboundingerror = 1.0;
2870 else
2871 avgboundingerror = (stat->boundingerrorbs + stat->boundingerrorps + stat->boundingerrorexlp) / (stat->nboundshift + stat->nprojshift + stat->nexlp);
2872 adjustedobjlim = lp->lpiobjlim + MAX(avgboundingerror, 1e-6);
2873
2874 SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_OBJLIM, adjustedobjlim, success) );
2875 if( *success )
2876 {
2877 SCIP_Real actualobjlim;
2878
2879 /* check whether the parameter was actually changed or already was at the boundary of the LP solver's parameter range */
2880 SCIP_CALL( SCIPlpiGetRealpar(lp->lpi, SCIP_LPPAR_OBJLIM, &actualobjlim) );
2881 if( actualobjlim != lp->lpiobjlim ) /*lint !e777*/
2882 {
2883 /* mark the current solution invalid */
2884 lp->solved = FALSE;
2885 lp->primalfeasible = FALSE;
2886 lp->primalchecked = FALSE;
2887 lp->lpobjval = SCIP_INVALID;
2889 }
2890 lp->lpiobjlim = actualobjlim;
2891 }
2892
2893 return SCIP_OKAY;
2894}
2895
2896
2897/** sets the feasibility tolerance of the LP solver */
2898static
2900 SCIP_LP* lp, /**< current LP data */
2901 SCIP_Real feastol, /**< new feasibility tolerance */
2902 SCIP_Bool* success /**< pointer to store whether the parameter was actually changed */
2903 )
2904{
2905 assert(lp != NULL);
2906 assert(feastol >= 0.0);
2907 assert(success != NULL);
2908
2910
2911 if( feastol != lp->lpifeastol ) /*lint !e777*/
2912 {
2913 SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_FEASTOL, feastol, success) );
2914 if( *success )
2915 {
2916 SCIP_Real actualfeastol;
2917
2918 /* check whether the parameter was actually changed or already was at the boundary of the LP solver's parameter range */
2919 SCIP_CALL( SCIPlpiGetRealpar(lp->lpi, SCIP_LPPAR_FEASTOL, &actualfeastol) );
2920 if( lp->nrows > 0 && actualfeastol < lp->lpifeastol )
2921 {
2922 /* mark the current solution invalid */
2923 lp->solved = FALSE;
2924 lp->primalfeasible = FALSE;
2925 lp->primalchecked = FALSE;
2926 lp->lpobjval = SCIP_INVALID;
2928 }
2929 else
2930 *success = FALSE;
2931 lp->lpifeastol = actualfeastol;
2932 }
2933 }
2934 else
2935 *success = FALSE;
2936
2937 return SCIP_OKAY;
2938}
2939
2940/** sets the reduced costs feasibility tolerance of the LP solver */
2941static
2943 SCIP_LP* lp, /**< current LP data */
2944 SCIP_Real dualfeastol, /**< new reduced costs feasibility tolerance */
2945 SCIP_Bool* success /**< pointer to store whether the parameter was actually changed */
2946 )
2947{
2948 assert(lp != NULL);
2949 assert(dualfeastol >= 0.0);
2950 assert(success != NULL);
2951
2953
2954 if( dualfeastol != lp->lpidualfeastol ) /*lint !e777*/
2955 {
2956 SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_DUALFEASTOL, dualfeastol, success) );
2957 if( *success )
2958 {
2959 SCIP_Real actualdualfeastol;
2960
2961 /* check whether the parameter was actually changed or already was at the boundary of the LP solver's parameter range */
2962 SCIP_CALL( SCIPlpiGetRealpar(lp->lpi, SCIP_LPPAR_DUALFEASTOL, &actualdualfeastol) );
2963 if( lp->nrows > 0 && actualdualfeastol < lp->lpidualfeastol )
2964 {
2965 /* mark the current solution invalid */
2966 lp->solved = FALSE;
2967 lp->dualfeasible = FALSE;
2968 lp->dualchecked = FALSE;
2969 lp->lpobjval = SCIP_INVALID;
2971 }
2972 else
2973 *success = FALSE;
2974 lp->lpidualfeastol = actualdualfeastol;
2975 }
2976 }
2977 else
2978 *success = FALSE;
2979
2980 return SCIP_OKAY;
2981}
2982
2983/** sets the convergence tolerance used in barrier algorithm of the LP solver */
2984static
2986 SCIP_LP* lp, /**< current LP data */
2987 SCIP_Real barrierconvtol, /**< new convergence tolerance used in barrier algorithm */
2988 SCIP_Bool* success /**< pointer to store whether the parameter was actually changed */
2989 )
2990{
2991 assert(lp != NULL);
2992 assert(barrierconvtol >= 0.0);
2993 assert(success != NULL);
2994
2996
2997 if( barrierconvtol != lp->lpibarrierconvtol ) /*lint !e777*/
2998 {
2999 SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_BARRIERCONVTOL, barrierconvtol, success) );
3000 if( *success )
3001 {
3002 SCIP_Real actualbarrierconvtol;
3003
3004 /* check whether the parameter was actually changed or already was at the boundary of the LP solver's parameter range */
3005 SCIP_CALL( SCIPlpiGetRealpar(lp->lpi, SCIP_LPPAR_BARRIERCONVTOL, &actualbarrierconvtol) );
3006 if( lp->nrows > 0 && actualbarrierconvtol < lp->lpibarrierconvtol
3008 {
3009 /* mark the current solution invalid */
3010 lp->solved = FALSE;
3011 lp->dualfeasible = FALSE;
3012 lp->dualchecked = FALSE;
3013 lp->lpobjval = SCIP_INVALID;
3015 }
3016 else
3017 *success = FALSE;
3018 lp->lpibarrierconvtol = actualbarrierconvtol;
3019 }
3020 }
3021 else
3022 *success = FALSE;
3023
3024 return SCIP_OKAY;
3025}
3026
3027/** sets the FROMSCRATCH setting of the LP solver */
3028static
3030 SCIP_LP* lp, /**< current LP data */
3031 SCIP_Bool fromscratch, /**< new FROMSCRATCH setting */
3032 SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3033 )
3034{
3035 assert(lp != NULL);
3036 assert(success != NULL);
3037
3039
3040 if( fromscratch != lp->lpifromscratch )
3041 {
3042 SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_FROMSCRATCH, fromscratch, success) );
3043 if( *success )
3044 lp->lpifromscratch = fromscratch;
3045 }
3046 else
3047 *success = FALSE;
3048
3049 return SCIP_OKAY;
3050}
3051
3052/** sets the FASTMIP setting of the LP solver */
3053static
3055 SCIP_LP* lp, /**< current LP data */
3056 int fastmip, /**< new FASTMIP setting */
3057 SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3058 )
3059{
3060 assert(lp != NULL);
3061 assert(success != NULL);
3062 assert(0 <= fastmip && fastmip <= 1);
3063
3065
3066 if( fastmip != lp->lpifastmip )
3067 {
3068 SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_FASTMIP, fastmip, success) );
3069 if( *success )
3070 {
3071 lp->lpifastmip = fastmip;
3072 lp->solved = FALSE;
3073 /* We might only set lp->solved to false if fastmip is turned off, since the latter should be the more
3074 * demanding setting; however, in the current code, this should have not effect. */
3075 }
3076 }
3077 else
3078 *success = FALSE;
3079
3080 return SCIP_OKAY;
3081}
3082
3083/** sets the SCALING setting of the LP solver */
3084static
3086 SCIP_LP* lp, /**< current LP data */
3087 int scaling, /**< new SCALING setting */
3088 SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3089 )
3090{
3091 assert(lp != NULL);
3092 assert(success != NULL);
3093
3095
3096 if( scaling != lp->lpiscaling )
3097 {
3098 SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_SCALING, scaling, success) );
3099 if( *success )
3100 lp->lpiscaling = scaling;
3101 }
3102 else
3103 *success = FALSE;
3104
3105 return SCIP_OKAY;
3106}
3107
3108/** sets the number of THREADS of the LP solver */
3109static
3111 SCIP_LP* lp, /**< current LP data */
3112 int threads, /**< new number of threads used to solve the LP */
3113 SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3114 )
3115{
3116 assert(lp != NULL);
3117 assert(success != NULL);
3118
3120
3121 if( threads != lp->lpithreads )
3122 {
3123 SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_THREADS, threads, success) );
3124 if( *success )
3125 lp->lpithreads = threads;
3126 }
3127 else
3128 *success = FALSE;
3129
3130 return SCIP_OKAY;
3131}
3132
3133/** sets the PRESOLVING setting of the LP solver */
3134static
3136 SCIP_LP* lp, /**< current LP data */
3137 SCIP_Bool presolving, /**< new PRESOLVING setting */
3138 SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3139 )
3140{
3141 assert(lp != NULL);
3142 assert(success != NULL);
3143
3145
3146 if( presolving != lp->lpipresolving )
3147 {
3148 SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_PRESOLVING, presolving, success) );
3149 if( *success )
3150 lp->lpipresolving = presolving;
3151 }
3152 else
3153 *success = FALSE;
3154
3155 return SCIP_OKAY;
3156}
3157
3158/** sets the ROWREPSWITCH setting of the LP solver */
3159static
3161 SCIP_LP* lp, /**< current LP data */
3162 SCIP_Real rowrepswitch, /**< new ROWREPSWITCH value */
3163 SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3164 )
3165{
3166 assert(lp != NULL);
3167 assert(success != NULL);
3168
3170
3171 if( rowrepswitch != lp->lpirowrepswitch ) /*lint !e777*/
3172 {
3173 SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_ROWREPSWITCH, rowrepswitch, success) );
3174 if( *success )
3175 lp->lpirowrepswitch = rowrepswitch;
3176 }
3177 else
3178 *success = FALSE;
3179
3180 return SCIP_OKAY;
3181}
3182
3183/** sets the iteration limit of the LP solver */
3184static
3186 SCIP_LP* lp, /**< current LP data */
3187 int itlim /**< maximal number of LP iterations to perform, or -1 for no limit */
3188 )
3189{
3190 SCIP_Bool success;
3191
3192 assert(lp != NULL);
3193 assert(itlim >= -1);
3194
3195 if( itlim == -1 )
3196 itlim = INT_MAX;
3197
3199
3200 if( itlim != lp->lpiitlim )
3201 {
3202 SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_LPITLIM, itlim, &success) );
3203 if( success )
3204 {
3205 if( itlim > lp->lpiitlim )
3206 {
3207 /* mark the current solution invalid */
3208 lp->solved = FALSE;
3209 lp->lpobjval = SCIP_INVALID;
3211 }
3212 lp->lpiitlim = itlim;
3213 }
3214 }
3215
3216 return SCIP_OKAY;
3217}
3218
3219/** sets the pricing strategy of the LP solver */
3220static
3222 SCIP_LP* lp, /**< current LP data */
3223 SCIP_PRICING pricing /**< pricing strategy */
3224 )
3225{
3226 SCIP_Bool success;
3227
3228 assert(lp != NULL);
3229
3231
3232 if( pricing != lp->lpipricing )
3233 {
3234 SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_PRICING, (int)pricing, &success) );
3235 if( success )
3236 lp->lpipricing = pricing;
3237 }
3238
3239 return SCIP_OKAY;
3240}
3241
3242/** sets the pricing strategy of the LP solver (given the character representation of the strategy) */
3243static
3245 SCIP_LP* lp, /**< current LP data */
3246 char pricingchar /**< character representing the pricing strategy */
3247 )
3248{
3249 SCIP_PRICING pricing;
3250
3251 switch( pricingchar )
3252 {
3253 case 'l':
3254 pricing = SCIP_PRICING_LPIDEFAULT;
3255 break;
3256 case 'a':
3257 pricing = SCIP_PRICING_AUTO;
3258 break;
3259 case 'f':
3260 pricing = SCIP_PRICING_FULL;
3261 break;
3262 case 'p':
3263 pricing = SCIP_PRICING_PARTIAL;
3264 break;
3265 case 's':
3266 pricing = SCIP_PRICING_STEEP;
3267 break;
3268 case 'q':
3269 pricing = SCIP_PRICING_STEEPQSTART;
3270 break;
3271 case 'd':
3272 pricing = SCIP_PRICING_DEVEX;
3273 break;
3274 default:
3275 SCIPerrorMessage("invalid LP pricing parameter <%c>\n", pricingchar);
3276 return SCIP_INVALIDDATA;
3277 }
3278
3279 SCIP_CALL( lpSetPricing(lp, pricing) );
3280
3281 return SCIP_OKAY;
3282}
3283
3284/** sets the verbosity of the LP solver */
3285static
3287 SCIP_LP* lp, /**< current LP data */
3288 SCIP_Bool lpinfo /**< should the LP solver display status messages? */
3289 )
3290{
3291 SCIP_Bool success;
3292
3293 assert(lp != NULL);
3294
3296
3297 if( lpinfo != lp->lpilpinfo )
3298 {
3299 SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_LPINFO, lpinfo, &success) );
3300 if( success )
3301 lp->lpilpinfo = lpinfo;
3302 }
3303
3304 return SCIP_OKAY;
3305}
3306
3307/** sets the CONDITIONLIMIT setting of the LP solver */
3308static
3310 SCIP_LP* lp, /**< current LP data */
3311 SCIP_Real condlimit, /**< new CONDITIONLIMIT value */
3312 SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3313 )
3314{
3315 assert(lp != NULL);
3316 assert(success != NULL);
3317
3319
3320 if( condlimit != lp->lpiconditionlimit ) /*lint !e777*/
3321 {
3322 SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_CONDITIONLIMIT, condlimit, success) );
3323 if( *success )
3324 lp->lpiconditionlimit = condlimit;
3325 }
3326 else
3327 *success = FALSE;
3328
3329 return SCIP_OKAY;
3330}
3331
3332/** sets the MARKOWITZ setting of the LP solver */
3333static
3335 SCIP_LP* lp, /**< current LP data */
3336 SCIP_Real threshhold, /**< new MARKOWITZ value */
3337 SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3338 )
3339{
3340 assert(lp != NULL);
3341 assert(success != NULL);
3342
3344
3345 if( threshhold != lp->lpimarkowitz ) /*lint !e777*/
3346 {
3347 SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_MARKOWITZ, threshhold, success) );
3348 if( *success )
3349 lp->lpimarkowitz = threshhold;
3350 }
3351 else
3352 *success = FALSE;
3353
3354 return SCIP_OKAY;
3355}
3356
3357/** sets the type of timer of the LP solver */
3358static
3360 SCIP_LP* lp, /**< current LP data */
3361 SCIP_CLOCKTYPE timing, /**< new timing value */
3362 SCIP_Bool enabled, /**< is timing enabled? */
3363 SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3364 )
3365{
3366 int lptiming;
3367
3368 assert(lp != NULL);
3369 assert(success != NULL);
3370 assert((int) SCIP_CLOCKTYPE_CPU == 1 && (int) SCIP_CLOCKTYPE_WALL == 2); /*lint !e506*//*lint !e1564*/
3371
3373
3374 if( !enabled )
3375 lptiming = 0;
3376 else
3377 lptiming = (int) timing;
3378
3379 if( lptiming != lp->lpitiming ) /*lint !e777*/
3380 {
3381 SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_TIMING, lptiming, success) );
3382 if( *success )
3383 lp->lpitiming = lptiming;
3384 }
3385 else
3386 *success = FALSE;
3387
3388 return SCIP_OKAY;
3389}
3390
3391/** sets the initial random seed of the LP solver */
3392static
3394 SCIP_LP* lp, /**< current LP data */
3395 int randomseed, /**< new initial random seed */
3396 SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3397 )
3398{
3399 assert(lp != NULL);
3400 assert(success != NULL);
3401
3402 /* we don't check this parameter because SoPlex will always return its current random seed, not the initial one */
3403
3404 if( randomseed == 0 )
3405 {
3406 lp->lpirandomseed = randomseed;
3407 *success = TRUE;
3408 }
3409 else if( randomseed != lp->lpirandomseed ) /*lint !e777*/
3410 {
3411 SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_RANDOMSEED, randomseed, success) );
3412 if( *success )
3413 lp->lpirandomseed = randomseed;
3414 }
3415 else
3416 *success = FALSE;
3417
3418 return SCIP_OKAY;
3419}
3420
3421/** sets the LP solution polishing method */
3422static
3424 SCIP_LP* lp, /**< current LP data */
3425 SCIP_Bool polishing, /**< LP solution polishing activated (0: disabled, 1: enabled) */
3426 SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3427 )
3428{
3429 assert(lp != NULL);
3430 assert(success != NULL);
3431
3432 if( polishing != lp->lpisolutionpolishing )
3433 {
3434 SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_POLISHING, (polishing ? 1 : 0), success) );
3435 if( *success )
3436 lp->lpisolutionpolishing = polishing;
3437 }
3438 else
3439 *success = FALSE;
3440
3441 return SCIP_OKAY;
3442}
3443
3444/** sets the LP refactorization interval */
3445static
3447 SCIP_LP* lp, /**< current LP data */
3448 int refactor, /**< LP refactorization interval (0: automatic) */
3449 SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3450 )
3451{
3452 assert(lp != NULL);
3453 assert(success != NULL);
3454
3455 if( refactor != lp->lpirefactorinterval )
3456 {
3457 SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_REFACTOR, refactor, success) );
3458 if( *success )
3459 lp->lpirefactorinterval = refactor;
3460 }
3461 else
3462 *success = FALSE;
3463
3464 return SCIP_OKAY;
3465}
3466
3467
3468/*
3469 * Column methods
3470 */
3471
3472/** creates an LP column */
3474 SCIP_COL** col, /**< pointer to column data */
3475 BMS_BLKMEM* blkmem, /**< block memory */
3476 SCIP_SET* set, /**< global SCIP settings */
3477 SCIP_STAT* stat, /**< problem statistics */
3478 SCIP_VAR* var, /**< variable, this column represents */
3479 int len, /**< number of nonzeros in the column */
3480 SCIP_ROW** rows, /**< array with rows of column entries */
3481 SCIP_Real* vals, /**< array with coefficients of column entries */
3482 SCIP_Bool removable /**< should the column be removed from the LP due to aging or cleanup? */
3483 )
3484{
3485 int i;
3486
3487 assert(col != NULL);
3488 assert(blkmem != NULL);
3489 assert(set != NULL);
3490 assert(stat != NULL);
3491 assert(var != NULL);
3492 assert(len >= 0);
3493 assert(len == 0 || (rows != NULL && vals != NULL));
3494
3495 SCIP_ALLOC( BMSallocBlockMemory(blkmem, col) );
3496
3497 if( len > 0 )
3498 {
3499 SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*col)->rows, rows, len) );
3500 SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*col)->vals, vals, len) );
3501 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*col)->linkpos, len) );
3502
3503 for( i = 0; i < len; ++i )
3504 {
3505 assert(rows[i] != NULL);
3506 assert(!SCIPsetIsZero(set, vals[i]));
3507 (*col)->linkpos[i] = -1;
3508 }
3509 }
3510 else
3511 {
3512 (*col)->rows = NULL;
3513 (*col)->vals = NULL;
3514 (*col)->linkpos = NULL;
3515 }
3516
3517 (*col)->var = var;
3518 (*col)->obj = SCIPvarGetObj(var);
3519 (*col)->unchangedobj = SCIPvarGetUnchangedObj(var);
3520 (*col)->lb = SCIPvarGetLbLocal(var);
3521 (*col)->ub = SCIPvarGetUbLocal(var);
3522 (*col)->flushedobj = 0.0;
3523 (*col)->flushedlb = 0.0;
3524 (*col)->flushedub = 0.0;
3525 (*col)->index = stat->ncolidx;
3526 SCIPstatIncrement(stat, set, ncolidx);
3527 (*col)->size = len;
3528 (*col)->len = len;
3529 (*col)->nlprows = 0;
3530 (*col)->nunlinked = len;
3531 (*col)->lppos = -1;
3532 (*col)->lpipos = -1;
3533 (*col)->lpdepth = -1;
3534 (*col)->primsol = 0.0;
3535 (*col)->redcost = SCIP_INVALID;
3536 (*col)->farkascoef = SCIP_INVALID;
3537 (*col)->minprimsol = (*col)->ub;
3538 (*col)->maxprimsol = (*col)->lb;
3539 (*col)->sbdown = SCIP_INVALID;
3540 (*col)->sbup = SCIP_INVALID;
3541 (*col)->sbsolval = SCIP_INVALID;
3542 (*col)->sblpobjval = SCIP_INVALID;
3543 (*col)->sbnode = -1;
3544 (*col)->validredcostlp = -1;
3545 (*col)->validfarkaslp = -1;
3546 (*col)->validsblp = -1;
3547 (*col)->sbitlim = -1;
3548 (*col)->nsbcalls = 0;
3549 (*col)->age = 0;
3550 (*col)->obsoletenode = -1;
3551 (*col)->var_probindex = SCIPvarGetProbindex(var);
3552 (*col)->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
3553 (*col)->lprowssorted = TRUE;
3554 (*col)->nonlprowssorted = (len <= 1);
3555 (*col)->objchanged = FALSE;
3556 (*col)->lbchanged = FALSE;
3557 (*col)->ubchanged = FALSE;
3558 (*col)->coefchanged = FALSE;
3559 (*col)->integral = SCIPvarIsIntegral(var);
3560 (*col)->impliedintegral = SCIPvarIsImpliedIntegral(var);
3561 (*col)->removable = removable;
3562 (*col)->sbdownvalid = FALSE;
3563 (*col)->sbupvalid = FALSE;
3564 (*col)->lazylb = SCIPvarGetLbLazy(var);
3565 (*col)->lazyub = SCIPvarGetUbLazy(var);
3566 (*col)->storedsolvals = NULL;
3567
3568 return SCIP_OKAY;
3569}
3570
3571/** frees an LP column */
3573 SCIP_COL** col, /**< pointer to LP column */
3574 BMS_BLKMEM* blkmem, /**< block memory */
3575 SCIP_SET* set, /**< global SCIP settings */
3576 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3577 SCIP_LP* lp /**< current LP data */
3578 )
3579{
3580 assert(blkmem != NULL);
3581 assert(col != NULL);
3582 assert(*col != NULL);
3583 assert((*col)->var != NULL);
3585 assert(&(*col)->var->data.col == col); /* SCIPcolFree() has to be called from SCIPvarFree() */
3586 assert((*col)->lppos == -1);
3587 assert((*col)->lpipos == -1);
3588
3589 /* remove column indices from corresponding rows */
3590 SCIP_CALL( colUnlink(*col, blkmem, set, eventqueue, lp) );
3591
3592 BMSfreeBlockMemoryNull(blkmem, &(*col)->storedsolvals);
3593 BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->rows, (*col)->size);
3594 BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->vals, (*col)->size);
3595 BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->linkpos, (*col)->size);
3596 BMSfreeBlockMemory(blkmem, col);
3597
3598 return SCIP_OKAY;
3599}
3600
3601/** output column to file stream */
3603 SCIP_COL* col, /**< LP column */
3604 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
3605 FILE* file /**< output file (or NULL for standard output) */
3606 )
3607{
3608 int r;
3609
3610 assert(col != NULL);
3611 assert(col->var != NULL);
3612
3613 /* print bounds */
3614 SCIPmessageFPrintInfo(messagehdlr, file, "(obj: %.15g) [%.15g,%.15g], ", col->obj, col->lb, col->ub);
3615
3616 /* print coefficients */
3617 if( col->len == 0 )
3618 SCIPmessageFPrintInfo(messagehdlr, file, "<empty>");
3619 for( r = 0; r < col->len; ++r )
3620 {
3621 assert(col->rows[r] != NULL);
3622 assert(col->rows[r]->name != NULL);
3623 SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g<%s> ", col->vals[r], col->rows[r]->name);
3624 }
3625 SCIPmessageFPrintInfo(messagehdlr, file, "\n");
3626}
3627
3628/** sorts column entries such that LP rows precede non-LP rows and inside both parts lower row indices precede higher ones
3629 */
3631 SCIP_COL* col /**< column to be sorted */
3632 )
3633{
3634 /* sort LP rows */
3635 colSortLP(col);
3636
3637 /* sort non-LP rows */
3638 colSortNonLP(col);
3639}
3640
3641/** adds a previously non existing coefficient to an LP column */
3643 SCIP_COL* col, /**< LP column */
3644 BMS_BLKMEM* blkmem, /**< block memory */
3645 SCIP_SET* set, /**< global SCIP settings */
3646 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3647 SCIP_LP* lp, /**< current LP data */
3648 SCIP_ROW* row, /**< LP row */
3649 SCIP_Real val /**< value of coefficient */
3650 )
3651{
3652 assert(lp != NULL);
3653 assert(!lp->diving);
3654
3655 SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, val, -1) );
3656
3657 checkLinks(lp);
3658
3659 return SCIP_OKAY;
3660}
3661
3662/** deletes existing coefficient from column */
3664 SCIP_COL* col, /**< column to be changed */
3665 BMS_BLKMEM* blkmem, /**< block memory */
3666 SCIP_SET* set, /**< global SCIP settings */
3667 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3668 SCIP_LP* lp, /**< current LP data */
3669 SCIP_ROW* row /**< coefficient to be deleted */
3670 )
3671{
3672 int pos;
3673
3674 assert(col != NULL);
3675 assert(col->var != NULL);
3676 assert(lp != NULL);
3677 assert(!lp->diving);
3678 assert(row != NULL);
3679
3680 /* search the position of the row in the column's row vector */
3681 pos = colSearchCoef(col, row);
3682 if( pos == -1 )
3683 {
3684 SCIPerrorMessage("coefficient for row <%s> doesn't exist in column <%s>\n", row->name, SCIPvarGetName(col->var));
3685 return SCIP_INVALIDDATA;
3686 }
3687 assert(0 <= pos && pos < col->len);
3688 assert(col->rows[pos] == row);
3689
3690 /* if row knows of the column, remove the column from the row's col vector */
3691 if( col->linkpos[pos] >= 0 )
3692 {
3693 assert(row->cols[col->linkpos[pos]] == col);
3694 assert(row->cols_index[col->linkpos[pos]] == col->index);
3695 assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
3696 SCIP_CALL( rowDelCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos]) );
3697 }
3698
3699 /* delete the row from the column's row vector */
3700 SCIP_CALL( colDelCoefPos(col, set, lp, pos) );
3701
3702 checkLinks(lp);
3703
3704 return SCIP_OKAY;
3705}
3706
3707/** changes or adds a coefficient to an LP column */
3709 SCIP_COL* col, /**< LP column */
3710 BMS_BLKMEM* blkmem, /**< block memory */
3711 SCIP_SET* set, /**< global SCIP settings */
3712 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3713 SCIP_LP* lp, /**< current LP data */
3714 SCIP_ROW* row, /**< LP row */
3715 SCIP_Real val /**< value of coefficient */
3716 )
3717{
3718 int pos;
3719
3720 assert(col != NULL);
3721 assert(lp != NULL);
3722 assert(!lp->diving);
3723 assert(row != NULL);
3724
3725 /* search the position of the row in the column's row vector */
3726 pos = colSearchCoef(col, row);
3727
3728 /* check, if row already exists in the column's row vector */
3729 if( pos == -1 )
3730 {
3731 /* add previously not existing coefficient */
3732 SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, val, -1) );
3733 }
3734 else
3735 {
3736 /* modify already existing coefficient */
3737 assert(0 <= pos && pos < col->len);
3738 assert(col->rows[pos] == row);
3739
3740 /* if row knows of the column, change the corresponding coefficient in the row */
3741 if( col->linkpos[pos] >= 0 )
3742 {
3743 assert(row->cols[col->linkpos[pos]] == col);
3744 assert(row->cols_index[col->linkpos[pos]] == col->index);
3745 assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
3746 SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos], val) );
3747 }
3748
3749 /* change the coefficient in the column */
3750 SCIP_CALL( colChgCoefPos(col, set, lp, pos, val) );
3751 }
3752
3753 checkLinks(lp);
3754
3755 return SCIP_OKAY;
3756}
3757
3758/** increases value of an existing or non-existing coefficient in an LP column */
3760 SCIP_COL* col, /**< LP column */
3761 BMS_BLKMEM* blkmem, /**< block memory */
3762 SCIP_SET* set, /**< global SCIP settings */
3763 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3764 SCIP_LP* lp, /**< current LP data */
3765 SCIP_ROW* row, /**< LP row */
3766 SCIP_Real incval /**< value to add to the coefficient */
3767 )
3768{
3769 int pos;
3770
3771 assert(col != NULL);
3772 assert(lp != NULL);
3773 assert(!lp->diving);
3774 assert(row != NULL);
3775
3776 if( SCIPsetIsZero(set, incval) )
3777 return SCIP_OKAY;
3778
3779 /* search the position of the row in the column's row vector */
3780 pos = colSearchCoef(col, row);
3781
3782 /* check, if row already exists in the column's row vector */
3783 if( pos == -1 )
3784 {
3785 /* add previously not existing coefficient */
3786 SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, incval, -1) );
3787 }
3788 else
3789 {
3790 /* modify already existing coefficient */
3791 assert(0 <= pos && pos < col->len);
3792 assert(col->rows[pos] == row);
3793
3794 /* if row knows of the column, change the corresponding coefficient in the row */
3795 if( col->linkpos[pos] >= 0 )
3796 {
3797 assert(row->cols[col->linkpos[pos]] == col);
3798 assert(row->cols_index[col->linkpos[pos]] == col->index);
3799 assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
3800 SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos], col->vals[pos] + incval) );
3801 }
3802
3803 /* change the coefficient in the column */
3804 SCIP_CALL( colChgCoefPos(col, set, lp, pos, col->vals[pos] + incval) );
3805 }
3806
3807 checkLinks(lp);
3808
3809 return SCIP_OKAY;
3810}
3811
3812/** insert column in the chgcols list (if not already there) */
3813static
3815 SCIP_COL* col, /**< LP column to change */
3816 SCIP_SET* set, /**< global SCIP settings */
3817 SCIP_LP* lp /**< current LP data */
3818 )
3819{
3820 if( !col->objchanged && !col->lbchanged && !col->ubchanged )
3821 {
3822 SCIP_CALL( ensureChgcolsSize(lp, set, lp->nchgcols+1) );
3823 lp->chgcols[lp->nchgcols] = col;
3824 lp->nchgcols++;
3825 }
3826
3827 /* mark the current LP unflushed */
3828 lp->flushed = FALSE;
3829
3830 return SCIP_OKAY;
3831}
3832
3833/** Is the new value reliable or may we have cancellation?
3834 *
3835 * @note: Here we only consider cancellations which can occur during decreasing the oldvalue to newvalue; not the
3836 * cancellations which can occur during increasing the oldvalue to the newvalue
3837 */
3838static
3840 SCIP_SET* set, /**< global SCIP settings */
3841 SCIP_Real newvalue, /**< new value */
3842 SCIP_Real oldvalue /**< old reliable value */
3843 )
3844{
3845 SCIP_Real quotient;
3846
3847 assert(set != NULL);
3848 assert(oldvalue != SCIP_INVALID); /*lint !e777*/
3849
3850 quotient = (REALABS(newvalue)+1.0) / (REALABS(oldvalue) + 1.0);
3851
3852 return SCIPsetIsZero(set, quotient);
3853}
3854
3855/** update norms of objective function vector */
3856static
3858 SCIP_LP* lp, /**< current LP data */
3859 SCIP_SET* set, /**< global SCIP settings */
3860 SCIP_Real oldobj, /**< old objective value of variable */
3861 SCIP_Real newobj /**< new objective value of variable */
3862 )
3863{
3864 if( REALABS(newobj) != REALABS(oldobj) ) /*lint !e777*/
3865 {
3866 if( !lp->objsqrnormunreliable )
3867 {
3868 SCIP_Real oldvalue;
3869
3870 oldvalue = lp->objsqrnorm;
3871 lp->objsqrnorm += SQR(newobj) - SQR(oldobj);
3872
3873 /* due to numerical cancellations, we recalculate lp->objsqrnorm using all variables */
3874 if( SCIPsetIsLT(set, lp->objsqrnorm, 0.0) || isNewValueUnreliable(set, lp->objsqrnorm, oldvalue) )
3876 else
3877 {
3878 assert(SCIPsetIsGE(set, lp->objsqrnorm, 0.0));
3879
3880 /* due to numerical troubles it still can appear that lp->objsqrnorm is a little bit smaller than 0 */
3881 lp->objsqrnorm = MAX(lp->objsqrnorm, 0.0);
3882
3883 assert(lp->objsqrnorm >= 0.0);
3884 }
3885 }
3886
3888 lp->objsumnorm = MAX(lp->objsumnorm, 0.0);
3889 }
3890}
3891
3892/** changes objective value of column */
3894 SCIP_COL* col, /**< LP column to change */
3895 SCIP_SET* set, /**< global SCIP settings */
3896 SCIP_LP* lp, /**< current LP data */
3897 SCIP_Real newobj /**< new objective value */
3898 )
3899{
3900 assert(col != NULL);
3901 assert(col->var != NULL);
3903 assert(SCIPvarGetCol(col->var) == col);
3904 assert(lp != NULL);
3905
3906 SCIPsetDebugMsg(set, "changing objective value of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->obj, newobj);
3907
3908 /* only add actual changes */
3909 if( !SCIPsetIsEQ(set, col->obj, newobj) )
3910 {
3911 /* only variables with a real position in the LPI can be inserted */
3912 if( col->lpipos >= 0 )
3913 {
3914 /* insert column in the chgcols list (if not already there) */
3915 SCIP_CALL( insertColChgcols(col, set, lp) );
3916
3917 /* mark objective value change in the column */
3918 col->objchanged = TRUE;
3919
3920 assert(lp->nchgcols > 0);
3921 }
3922 /* in any case, when the sign of the objective (and thereby the best bound) changes, the variable has to enter the
3923 * LP and the LP has to be flushed
3924 */
3925 else if( (col->obj < 0.0 && newobj >= 0.0 && SCIPsetIsZero(set, col->ub))
3926 || (col->obj >= 0.0 && newobj < 0.0 && SCIPsetIsZero(set, col->lb)) )
3927 {
3928 /* mark the LP unflushed */
3929 lp->flushed = FALSE;
3930 }
3931 }
3932
3933 /* store new objective function value */
3934 col->obj = newobj;
3935
3936 /* update original objective value, as long as we are not in diving or probing and changed objective values */
3937 if( !lp->divingobjchg )
3938 {
3940
3942 col->unchangedobj = newobj;
3943
3944 /* update the objective function vector norms */
3946 }
3947
3948 return SCIP_OKAY;
3949}
3950
3951/** changes lower bound of column */
3953 SCIP_COL* col, /**< LP column to change */
3954 SCIP_SET* set, /**< global SCIP settings */
3955 SCIP_LP* lp, /**< current LP data */
3956 SCIP_Real newlb /**< new lower bound value */
3957 )
3958{
3959 assert(col != NULL);
3960 assert(col->var != NULL);
3962 assert(SCIPvarGetCol(col->var) == col);
3963 assert(lp != NULL);
3964
3965 SCIPsetDebugMsg(set, "changing lower bound of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->lb, newlb);
3966
3967 /* only add actual changes */
3968 if( !SCIPsetIsEQ(set, col->lb, newlb) )
3969 {
3970 /* only variables with a real position in the LPI can be inserted */
3971 if( col->lpipos >= 0 )
3972 {
3973 /* insert column in the chgcols list (if not already there) */
3974 SCIP_CALL( insertColChgcols(col, set, lp) );
3975
3976 /* mark bound change in the column */
3977 col->lbchanged = TRUE;
3978
3979 assert(lp->nchgcols > 0);
3980 }
3981 /* in any case, when the best bound is zero and gets changed, the variable has to enter the LP and the LP has to be
3982 * flushed
3983 */
3984 else if( col->obj >= 0.0 && SCIPsetIsZero(set, col->lb) )
3985 {
3986 /* mark the LP unflushed */
3987 lp->flushed = FALSE;
3988 }
3989 }
3990
3991 col->lb = newlb;
3992
3993 return SCIP_OKAY;
3994}
3995
3996/** changes upper bound of column */
3998 SCIP_COL* col, /**< LP column to change */
3999 SCIP_SET* set, /**< global SCIP settings */
4000 SCIP_LP* lp, /**< current LP data */
4001 SCIP_Real newub /**< new upper bound value */
4002 )
4003{
4004 assert(col != NULL);
4005 assert(col->var != NULL);
4007 assert(SCIPvarGetCol(col->var) == col);
4008 assert(lp != NULL);
4009
4010 SCIPsetDebugMsg(set, "changing upper bound of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->ub, newub);
4011
4012 /* only add actual changes */
4013 if( !SCIPsetIsEQ(set, col->ub, newub) )
4014 {
4015 /* only variables with a real position in the LPI can be inserted */
4016 if( col->lpipos >= 0 )
4017 {
4018 /* insert column in the chgcols list (if not already there) */
4019 SCIP_CALL( insertColChgcols(col, set, lp) );
4020
4021 /* mark bound change in the column */
4022 col->ubchanged = TRUE;
4023
4024 assert(lp->nchgcols > 0);
4025 }
4026 /* in any case, when the best bound is zero and gets changed, the variable has to enter the LP and the LP has to be
4027 * flushed
4028 */
4029 else if( col->obj < 0.0 && SCIPsetIsZero(set, col->ub) )
4030 {
4031 /* mark the LP unflushed */
4032 lp->flushed = FALSE;
4033 }
4034 }
4035
4036 col->ub = newub;
4037
4038 return SCIP_OKAY;
4039}
4040
4041/** calculates the reduced costs of a column using the given dual solution vector */
4043 SCIP_COL* col, /**< LP column */
4044 SCIP_Real* dualsol /**< dual solution vector for current LP rows */
4045 )
4046{
4047 SCIP_ROW* row;
4048 SCIP_Real redcost;
4049 int i;
4050
4051 assert(col != NULL);
4053 assert(SCIPvarGetCol(col->var) == col);
4054 assert(dualsol != NULL);
4055
4056 redcost = col->obj;
4057 for( i = 0; i < col->nlprows; ++i )
4058 {
4059 row = col->rows[i];
4060 assert(row != NULL);
4061 assert(row->lppos >= 0);
4062 redcost -= col->vals[i] * dualsol[row->lppos];
4063 }
4064
4065 if( col->nunlinked > 0 )
4066 {
4067 for( i = col->nlprows; i < col->len; ++i )
4068 {
4069 row = col->rows[i];
4070 assert(row != NULL);
4071 assert(row->lppos == -1 || col->linkpos[i] == -1);
4072 if( row->lppos >= 0 )
4073 redcost -= col->vals[i] * dualsol[row->lppos];
4074 }
4075 }
4076#ifndef NDEBUG
4077 else
4078 {
4079 for( i = col->nlprows; i < col->len; ++i )
4080 {
4081 row = col->rows[i];
4082 assert(row != NULL);
4083 assert(row->lppos == -1);
4084 assert(col->linkpos[i] >= 0);
4085 }
4086 }
4087#endif
4088
4089 return redcost;
4090}
4091
4092/** calculates the reduced costs of a column using the dual solution stored in the rows */
4093static
4095 SCIP_COL* col /**< LP column */
4096 )
4097{
4098 SCIP_ROW* row;
4099 SCIP_Real redcost;
4100 int i;
4101
4102 assert(col != NULL);
4104 assert(SCIPvarGetCol(col->var) == col);
4105
4106 redcost = col->obj;
4107 for( i = 0; i < col->nlprows; ++i )
4108 {
4109 row = col->rows[i];
4110 assert(row != NULL);
4111 assert(row->dualsol != SCIP_INVALID); /*lint !e777*/
4112 assert(row->lppos >= 0);
4113 assert(col->linkpos[i] >= 0);
4114 redcost -= col->vals[i] * row->dualsol;
4115 }
4116
4117 if( col->nunlinked > 0 )
4118 {
4119 for( i = col->nlprows; i < col->len; ++i )
4120 {
4121 row = col->rows[i];
4122 assert(row != NULL);
4123 assert(row->lppos >= 0 || row->dualsol == 0.0);
4124 assert(row->lppos == -1 || col->linkpos[i] == -1);
4125 if( row->lppos >= 0 )
4126 redcost -= col->vals[i] * row->dualsol;
4127 }
4128 }
4129#ifndef NDEBUG
4130 else
4131 {
4132 for( i = col->nlprows; i < col->len; ++i )
4133 {
4134 row = col->rows[i];
4135 assert(row != NULL);
4136 assert(row->dualsol == 0.0);
4137 assert(row->lppos == -1);
4138 assert(col->linkpos[i] >= 0);
4139 }
4140 }
4141#endif
4142
4143 return redcost;
4144}
4145
4146/** gets the reduced costs of a column in last LP or after recalculation */
4148 SCIP_COL* col, /**< LP column */
4149 SCIP_STAT* stat, /**< problem statistics */
4150 SCIP_LP* lp /**< current LP data */
4151 )
4152{
4153 assert(col != NULL);
4154 assert(stat != NULL);
4155 assert(lp != NULL);
4156 assert(col->validredcostlp <= stat->lpcount);
4157 assert(lp->validsollp == stat->lpcount);
4158
4159 if( col->validredcostlp < stat->lpcount )
4160 {
4161 col->redcost = colCalcInternalRedcost(col);
4162 col->validredcostlp = stat->lpcount;
4163 }
4164 assert(col->validredcostlp == stat->lpcount);
4165 assert(col->redcost != SCIP_INVALID); /*lint !e777*/
4166
4167 return col->redcost;
4168}
4169
4170/** gets the feasibility of (the dual row of) a column in last LP or after recalculation */
4172 SCIP_COL* col, /**< LP column */
4173 SCIP_SET* set, /**< global SCIP settings */
4174 SCIP_STAT* stat, /**< problem statistics */
4175 SCIP_LP* lp /**< current LP data */
4176 )
4177{
4178 assert(col != NULL);
4179 assert(set != NULL);
4180 assert(stat != NULL);
4181 assert(lp != NULL);
4182 assert(lp->validsollp == stat->lpcount);
4183
4184 /* A column's reduced cost is defined as
4185 * redcost = obj - activity, activity = y^T * col. (activity = obj - redcost)
4186 * The activity is equal to the activity of the corresponding row in the dual LP.
4187 * The column's feasibility is the feasibility of the corresponding row in the dual LP.
4188 * The sides of the dual row depend on the bounds of the column:
4189 * - lb == ub : dual row is a free row with infinite sides
4190 * - 0 <= lb < ub: activity <= obj => 0 <= redcost
4191 * - lb < 0 < ub: obj <= activity <= obj => 0 <= redcost <= 0
4192 * - lb < ub <= 0: obj <= activity => redcost <= 0
4193 */
4194 if( SCIPsetIsEQ(set, col->lb, col->ub) )
4195 {
4196 /* dual row is free */
4197 return SCIPsetInfinity(set);
4198 }
4199 else
4200 {
4201 SCIP_Real redcost;
4202
4203 /* calculate reduced costs */
4204 redcost = SCIPcolGetRedcost(col, stat, lp);
4205
4206 if( !SCIPsetIsNegative(set, col->lb) )
4207 {
4208 /* dual row is activity <= obj <=> redcost >= 0 */
4209 return redcost;
4210 }
4211 else if( SCIPsetIsPositive(set, col->ub) )
4212 {
4213 /* dual row is activity == obj <=> redcost == 0 */
4214 return -REALABS(redcost);
4215 }
4216 else
4217 {
4218 /* dual row is activity >= obj <=> redcost <= 0 */
4219 return -redcost;
4220 }
4221 }
4222}
4223
4224/** calculates the Farkas coefficient y^T A_i of a column i using the given dual Farkas vector y */
4226 SCIP_COL* col, /**< LP column */
4227 SCIP_Real* dualfarkas /**< dense dual Farkas vector for current LP rows */
4228 )
4229{
4230 SCIP_ROW* row;
4231 SCIP_Real farkas;
4232 int i;
4233
4234 assert(col != NULL);
4236 assert(SCIPvarGetCol(col->var) == col);
4237 assert(dualfarkas != NULL);
4238
4239 farkas = 0.0;
4240 for( i = 0; i < col->nlprows; ++i )
4241 {
4242 row = col->rows[i];
4243 assert(row != NULL);
4244 assert(row->lppos >= 0);
4245 farkas += col->vals[i] * dualfarkas[row->lppos];
4246 }
4247
4248 if( col->nunlinked > 0 )
4249 {
4250 for( i = col->nlprows; i < col->len; ++i )
4251 {
4252 row = col->rows[i];
4253 assert(row != NULL);
4254 assert(row->lppos == -1 || col->linkpos[i] == -1);
4255 if( row->lppos >= 0 )
4256 farkas += col->vals[i] * dualfarkas[row->lppos];
4257 }
4258 }
4259#ifndef NDEBUG
4260 else
4261 {
4262 for( i = col->nlprows; i < col->len; ++i )
4263 {
4264 row = col->rows[i];
4265 assert(row != NULL);
4266 assert(row->lppos == -1);
4267 assert(col->linkpos[i] >= 0);
4268 }
4269 }
4270#endif
4271
4272 return farkas;
4273}
4274
4275/** gets the Farkas coefficient y^T A_i of a column i in last LP (which must be infeasible) */
4276static
4278 SCIP_COL* col /**< LP column */
4279 )
4280{
4281 SCIP_ROW* row;
4282 SCIP_Real farkas;
4283 int i;
4284
4285 assert(col != NULL);
4287 assert(SCIPvarGetCol(col->var) == col);
4288
4289 farkas = 0.0;
4290 for( i = 0; i < col->nlprows; ++i )
4291 {
4292 row = col->rows[i];
4293 assert(row != NULL);
4294 assert(row->dualfarkas != SCIP_INVALID); /*lint !e777*/
4295 assert(row->lppos >= 0);
4296 assert(col->linkpos[i] >= 0);
4297 farkas += col->vals[i] * row->dualfarkas;
4298 }
4299
4300 if( col->nunlinked > 0 )
4301 {
4302 for( i = col->nlprows; i < col->len; ++i )
4303 {
4304 row = col->rows[i];
4305 assert(row != NULL);
4306 assert(row->lppos >= 0 || row->dualfarkas == 0.0);
4307 assert(row->lppos == -1 || col->linkpos[i] == -1);
4308 if( row->lppos >= 0 )
4309 farkas += col->vals[i] * row->dualfarkas;
4310 }
4311 }
4312#ifndef NDEBUG
4313 else
4314 {
4315 for( i = col->nlprows; i < col->len; ++i )
4316 {
4317 row = col->rows[i];
4318 assert(row != NULL);
4319 assert(row->dualfarkas == 0.0);
4320 assert(row->lppos == -1);
4321 assert(col->linkpos[i] >= 0);
4322 }
4323 }
4324#endif
4325
4326 return farkas;
4327}
4328
4329/** gets the Farkas coefficient of a column in last LP (which must be infeasible) */
4331 SCIP_COL* col, /**< LP column */
4332 SCIP_STAT* stat, /**< problem statistics */
4333 SCIP_LP* lp /**< current LP data */
4334 )
4335{
4336 assert(col != NULL);
4337 assert(stat != NULL);
4338 assert(lp != NULL);
4339 assert(col->validfarkaslp <= stat->lpcount);
4340 assert(lp->validfarkaslp == stat->lpcount);
4341
4342 if( col->validfarkaslp < stat->lpcount )
4343 {
4345 col->validfarkaslp = stat->lpcount;
4346 }
4347 assert(col->validfarkaslp == stat->lpcount);
4348 assert(col->farkascoef != SCIP_INVALID); /*lint !e777*/
4349
4350 return col->farkascoef;
4351}
4352
4353/** gets the Farkas value of a column in last LP (which must be infeasible), i.e. the Farkas coefficient y^T A_i times
4354 * the best bound for this coefficient, i.e. max{y^T A_i x_i | lb <= x_i <= ub}
4355 */
4357 SCIP_COL* col, /**< LP column */
4358 SCIP_STAT* stat, /**< problem statistics */
4359 SCIP_LP* lp /**< current LP data */
4360 )
4361{
4362 SCIP_Real farkascoef;
4363
4364 assert(col != NULL);
4365
4366 farkascoef = SCIPcolGetFarkasCoef(col, stat, lp);
4367
4368 if( farkascoef > 0.0 )
4369 return col->ub * farkascoef;
4370 else
4371 return col->lb * farkascoef;
4372}
4373
4374/** start strong branching - call before any strong branching */
4376 SCIP_LP* lp /**< LP data */
4377 )
4378{
4379 assert(lp != NULL);
4380 assert(!lp->strongbranching);
4381
4382 lp->strongbranching = TRUE;
4383 SCIPdebugMessage("starting strong branching ...\n");
4385
4386 return SCIP_OKAY;
4387}
4388
4389/** end strong branching - call after any strong branching */
4391 SCIP_LP* lp /**< LP data */
4392 )
4393{
4394 assert(lp != NULL);
4396
4397 lp->strongbranching = FALSE;
4398 SCIPdebugMessage("ending strong branching ...\n");
4400
4401 return SCIP_OKAY;
4402}
4403
4404/** sets strong branching information for a column variable */
4406 SCIP_COL* col, /**< LP column */
4407 SCIP_SET* set, /**< global SCIP settings */
4408 SCIP_STAT* stat, /**< dynamic problem statistics */
4409 SCIP_LP* lp, /**< LP data */
4410 SCIP_Real lpobjval, /**< objective value of the current LP */
4411 SCIP_Real primsol, /**< primal solution value of the column in the current LP */
4412 SCIP_Real sbdown, /**< dual bound after branching column down */
4413 SCIP_Real sbup, /**< dual bound after branching column up */
4414 SCIP_Bool sbdownvalid, /**< is the returned down value a valid dual bound? */
4415 SCIP_Bool sbupvalid, /**< is the returned up value a valid dual bound? */
4416 SCIP_Longint iter, /**< total number of strong branching iterations */
4417 int itlim /**< iteration limit applied to the strong branching call */
4418 )
4419{
4420 assert(col != NULL);
4421 assert(col->var != NULL);
4425 assert(SCIPvarGetCol(col->var) == col);
4426 assert(col->lpipos >= 0);
4427 assert(col->lppos >= 0);
4428 assert(set != NULL);
4429 assert(stat != NULL);
4430 assert(lp != NULL);
4432 assert(col->lppos < lp->ncols);
4433 assert(lp->cols[col->lppos] == col);
4434 assert(itlim >= 1);
4435
4436 col->sblpobjval = lpobjval;
4437 col->sbsolval = primsol;
4438 col->validsblp = stat->nlps;
4439 col->sbnode = stat->nnodes;
4440
4441 col->sbitlim = itlim;
4442 col->nsbcalls++;
4443
4444 col->sbdown = MIN(sbdown, lp->cutoffbound);
4445 col->sbup = MIN(sbup, lp->cutoffbound);
4446 col->sbdownvalid = sbdownvalid;
4447 col->sbupvalid = sbupvalid;
4448
4449 SCIPstatIncrement(stat, set, nstrongbranchs);
4450 SCIPstatAdd(stat, set, nsblpiterations, iter);
4451 if( stat->nnodes == 1 )
4452 {
4453 SCIPstatIncrement(stat, set, nrootstrongbranchs);
4454 SCIPstatAdd(stat, set, nrootsblpiterations, iter);
4455 }
4456}
4457
4458/** invalidates strong branching information for a column variable */
4460 SCIP_COL* col, /**< LP column */
4461 SCIP_SET* set, /**< global SCIP settings */
4462 SCIP_STAT* stat, /**< dynamic problem statistics */
4463 SCIP_LP* lp /**< LP data */
4464 )
4465{
4466 assert(col != NULL);
4467 assert(col->var != NULL);
4471 assert(SCIPvarGetCol(col->var) == col);
4472 assert(col->lpipos >= 0);
4473 assert(col->lppos >= 0);
4474 assert(set != NULL);
4475 assert(stat != NULL);
4476 assert(lp != NULL);
4478 assert(col->lppos < lp->ncols);
4479 assert(lp->cols[col->lppos] == col);
4480
4481 col->sbdown = SCIP_INVALID;
4482 col->sbup = SCIP_INVALID;
4483 col->sbdownvalid = FALSE;
4484 col->sbupvalid = FALSE;
4485 col->validsblp = -1;
4486 col->sbsolval = SCIP_INVALID;
4487 col->sblpobjval = SCIP_INVALID;
4488 col->sbnode = -1;
4489 col->sbitlim = -1;
4490}
4491
4492
4493/** gets strong branching information on a column variable */
4495 SCIP_COL* col, /**< LP column */
4496 SCIP_Bool integral, /**< should integral strong branching be performed? */
4497 SCIP_SET* set, /**< global SCIP settings */
4498 SCIP_STAT* stat, /**< dynamic problem statistics */
4499 SCIP_PROB* prob, /**< problem data */
4500 SCIP_LP* lp, /**< LP data */
4501 int itlim, /**< iteration limit for strong branchings */
4502 SCIP_Bool updatecol, /**< should col be updated, or should it stay in its current state ? */
4503 SCIP_Bool updatestat, /**< should stat be updated, or should it stay in its current state ? */
4504 SCIP_Real* down, /**< stores dual bound after branching column down */
4505 SCIP_Real* up, /**< stores dual bound after branching column up */
4506 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
4507 * otherwise, it can only be used as an estimate value */
4508 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
4509 * otherwise, it can only be used as an estimate value */
4510 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
4511 )
4512{
4513 SCIP_Real sbdown;
4514 SCIP_Real sbup;
4515 SCIP_Bool sbdownvalid;
4516 SCIP_Bool sbupvalid;
4517 SCIP_Longint validsblp;
4518 SCIP_Real sbsolval;
4519 SCIP_Real sblpobjval;
4520 SCIP_Longint sbnode;
4521 int sbitlim;
4522 int nsbcalls;
4523
4524 assert(col != NULL);
4525 assert(col->var != NULL);
4529 assert(SCIPvarGetCol(col->var) == col);
4530 assert(col->primsol != SCIP_INVALID); /*lint !e777*/
4531 assert(col->lpipos >= 0);
4532 assert(col->lppos >= 0);
4533 assert(set != NULL);
4534 assert(stat != NULL);
4535 assert(lp != NULL);
4536 assert(lp->flushed);
4537 assert(lp->solved);
4540 assert(lp->validsollp == stat->lpcount);
4541 assert(col->lppos < lp->ncols);
4542 assert(lp->cols[col->lppos] == col);
4543 assert(itlim >= 1);
4544 /* assert(down != NULL);
4545 * assert(up != NULL); temporary hack for cloud branching
4546 */
4547 assert(lperror != NULL);
4548
4549 *lperror = FALSE;
4550
4551 sbitlim = col->sbitlim;
4552 nsbcalls = col->nsbcalls;
4553
4554 validsblp = stat->nlps;
4555 sbsolval = col->primsol;
4556 sblpobjval = SCIPlpGetObjval(lp, set, prob);
4557 sbnode = stat->nnodes;
4558 assert(integral || !SCIPsetIsFeasIntegral(set, col->primsol));
4559
4560 /* if a loose variables has an infinite best bound, the LP bound is -infinity and no gain can be achieved */
4561 if( lp->looseobjvalinf > 0 )
4562 {
4563 sbdown = -SCIPsetInfinity(set);
4564 sbup = -SCIPsetInfinity(set);
4565 sbdownvalid = FALSE;
4566 sbupvalid = FALSE;
4567 }
4568 else
4569 {
4570 SCIP_RETCODE retcode;
4571 int iter;
4572
4573 SCIPsetDebugMsg(set, "performing strong branching on variable <%s>(%g) with %d iterations\n",
4574 SCIPvarGetName(col->var), col->primsol, itlim);
4575
4576 /* start timing */
4578
4579 /* call LPI strong branching */
4580 sbitlim = itlim;
4581 nsbcalls++;
4582
4583 sbdown = lp->lpobjval;
4584 sbup = lp->lpobjval;
4585 sbdownvalid = col->sbdownvalid;
4586 sbupvalid = col->sbupvalid;
4587
4588 if( integral )
4589 retcode = SCIPlpiStrongbranchInt(lp->lpi, col->lpipos, col->primsol, itlim, down == NULL ? NULL : &sbdown, up == NULL ? NULL : &sbup, &sbdownvalid, &sbupvalid, &iter);
4590 else
4591 {
4592 assert( ! SCIPsetIsIntegral(set, col->primsol) );
4593 retcode = SCIPlpiStrongbranchFrac(lp->lpi, col->lpipos, col->primsol, itlim, down == NULL ? NULL : &sbdown, up == NULL ? NULL : &sbup, &sbdownvalid, &sbupvalid, &iter);
4594 }
4595
4596 /* check return code for errors */
4597 if( retcode == SCIP_LPERROR )
4598 {
4599 *lperror = TRUE;
4600 sbdown = SCIP_INVALID;
4601 sbup = SCIP_INVALID;
4602 sbdownvalid = FALSE;
4603 sbupvalid = FALSE;
4604 validsblp = -1;
4605 sbsolval = SCIP_INVALID;
4606 sblpobjval = SCIP_INVALID;
4607 sbnode = -1;
4608 }
4609 else
4610 {
4611 SCIP_Real looseobjval;
4612
4613 *lperror = FALSE;
4614 SCIP_CALL( retcode );
4615
4616 looseobjval = getFiniteLooseObjval(lp, set, prob);
4617 sbdown = MIN(sbdown + looseobjval, lp->cutoffbound);
4618 sbup = MIN(sbup + looseobjval, lp->cutoffbound);
4619
4620 /* update strong branching statistics */
4621 if( updatestat )
4622 {
4623 if( iter == -1 )
4624 {
4625 /* calculate average iteration number */
4626 iter = stat->ndualresolvelps > 0 ? (int)(2*stat->ndualresolvelpiterations / stat->ndualresolvelps)
4627 : stat->nduallps > 0 ? (int)((stat->nduallpiterations / stat->nduallps) / 5)
4628 : stat->nprimalresolvelps > 0 ? (int)(2*stat->nprimalresolvelpiterations / stat->nprimalresolvelps)
4629 : stat->nprimallps > 0 ? (int)((stat->nprimallpiterations / stat->nprimallps) / 5)
4630 : 0;
4631 if( iter/2 >= itlim )
4632 iter = 2*itlim;
4633 }
4634 SCIPstatIncrement(stat, set, nstrongbranchs);
4635 SCIPstatAdd(stat, set, nsblpiterations, iter);
4636 if( stat->nnodes == 1 )
4637 {
4638 SCIPstatIncrement(stat, set, nrootstrongbranchs);
4639 SCIPstatAdd(stat, set, nrootsblpiterations, iter);
4640 }
4641 }
4642 }
4643
4644 /* stop timing */
4646 }
4647 assert(*lperror || sbdown != SCIP_INVALID); /*lint !e777*/
4648 assert(*lperror || sbup != SCIP_INVALID); /*lint !e777*/
4649
4650 if( down != NULL)
4651 *down = sbdown;
4652 if( up != NULL )
4653 *up = sbup;
4654 if( downvalid != NULL )
4655 *downvalid = sbdownvalid;
4656 if( upvalid != NULL )
4657 *upvalid = sbupvalid;
4658
4659 if( updatecol )
4660 {
4661 col->sbdown = sbdown;
4662 col->sbup = sbup;
4663 col->sbdownvalid = sbdownvalid;
4664 col->sbupvalid = sbupvalid;
4665 col->validsblp = validsblp;
4666 col->sbsolval = sbsolval;
4667 col->sblpobjval = sblpobjval;
4668 col->sbnode = sbnode;
4669 col->sbitlim = sbitlim;
4670 col->nsbcalls = nsbcalls;
4671 }
4672
4673 return SCIP_OKAY;
4674}
4675
4676/** gets strong branching information on column variables */
4678 SCIP_COL** cols, /**< LP columns */
4679 int ncols, /**< number of columns */
4680 SCIP_Bool integral, /**< should integral strong branching be performed? */
4681 SCIP_SET* set, /**< global SCIP settings */
4682 SCIP_STAT* stat, /**< dynamic problem statistics */
4683 SCIP_PROB* prob, /**< problem data */
4684 SCIP_LP* lp, /**< LP data */
4685 int itlim, /**< iteration limit for strong branchings */
4686 SCIP_Real* down, /**< stores dual bounds after branching columns down */
4687 SCIP_Real* up, /**< stores dual bounds after branching columns up */
4688 SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds, or NULL;
4689 * otherwise, they can only be used as an estimate value */
4690 SCIP_Bool* upvalid, /**< stores whether the returned up values are valid dual bounds, or NULL;
4691 * otherwise, they can only be used as an estimate value */
4692 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
4693 )
4694{
4695 SCIP_RETCODE retcode;
4696 SCIP_Real* sbdown;
4697 SCIP_Real* sbup;
4698 SCIP_Bool* sbdownvalid;
4699 SCIP_Bool* sbupvalid;
4700 SCIP_Real* primsols;
4701 SCIP_COL** subcols;
4702 int* lpipos;
4703 int* subidx;
4704 int nsubcols;
4705 int iter;
4706 int j;
4707
4708 assert(cols != NULL);
4709 assert(set != NULL);
4710 assert(stat != NULL);
4711 assert(lp != NULL);
4712 assert(lp->flushed);
4713 assert(lp->solved);
4715 assert(lp->validsollp == stat->lpcount);
4716 assert(itlim >= 1);
4717 assert(down != NULL);
4718 assert(up != NULL);
4719 assert(lperror != NULL);
4720
4721 *lperror = FALSE;
4722
4723 if ( ncols <= 0 )
4724 return SCIP_OKAY;
4725
4726 /* start timing */
4728
4729 /* initialize storage */
4730 SCIP_CALL( SCIPsetAllocBufferArray(set, &subcols, ncols) );
4731 SCIP_CALL( SCIPsetAllocBufferArray(set, &subidx, ncols) );
4732 SCIP_CALL( SCIPsetAllocBufferArray(set, &lpipos, ncols) );
4733 SCIP_CALL( SCIPsetAllocBufferArray(set, &primsols, ncols) );
4734 SCIP_CALL( SCIPsetAllocBufferArray(set, &sbdown, ncols) );
4735 SCIP_CALL( SCIPsetAllocBufferArray(set, &sbup, ncols) );
4736 SCIP_CALL( SCIPsetAllocBufferArray(set, &sbdownvalid, ncols) );
4737 SCIP_CALL( SCIPsetAllocBufferArray(set, &sbupvalid, ncols) );
4738
4739 nsubcols = 0;
4740 for( j = 0; j < ncols; ++j )
4741 {
4742 SCIP_COL* col;
4743 col = cols[j];
4744
4745 assert(col->lppos < lp->ncols);
4746 assert(lp->cols[col->lppos] == col);
4750 assert(SCIPvarGetCol(col->var) == col);
4751 assert(col->primsol != SCIP_INVALID); /*lint !e777*/
4752 assert(col->lpipos >= 0);
4753 assert(col->lppos >= 0);
4754
4755 col->validsblp = stat->nlps;
4756 col->sbsolval = col->primsol;
4757 col->sblpobjval = SCIPlpGetObjval(lp, set, prob);
4758 col->sbnode = stat->nnodes;
4760
4761 /* if a loose variables has an infinite best bound, the LP bound is -infinity and no gain can be achieved */
4762 if( lp->looseobjvalinf > 0 )
4763 {
4764 /* directly set up column and result vectors*/
4765 col->sbdown = -SCIPsetInfinity(set);
4766 col->sbup = -SCIPsetInfinity(set);
4767 col->sbdownvalid = FALSE;
4768 col->sbupvalid = FALSE;
4769 down[j] = col->sbdown;
4770 up[j] = col->sbup;
4771 if( downvalid != NULL )
4772 downvalid[j] = col->sbdownvalid;
4773 if( upvalid != NULL )
4774 upvalid[j] = col->sbupvalid;
4775 }
4776 else
4777 {
4778 col->sbitlim = itlim;
4779 col->nsbcalls++;
4780
4781 lpipos[nsubcols] = col->lpipos;
4782 primsols[nsubcols] = col->primsol;
4783 assert( integral || ! SCIPsetIsFeasIntegral(set, col->primsol) );
4784 subidx[nsubcols] = j;
4785 subcols[nsubcols++] = col;
4786 }
4787 }
4788
4789 SCIPsetDebugMsg(set, "performing strong branching on %d variables with %d iterations\n", ncols, itlim);
4790
4791 /* call LPI strong branching */
4792 if ( integral )
4793 retcode = SCIPlpiStrongbranchesInt(lp->lpi, lpipos, nsubcols, primsols, itlim, sbdown, sbup, sbdownvalid, sbupvalid, &iter);
4794 else
4795 retcode = SCIPlpiStrongbranchesFrac(lp->lpi, lpipos, nsubcols, primsols, itlim, sbdown, sbup, sbdownvalid, sbupvalid, &iter);
4796
4797 /* check return code for errors */
4798 if( retcode == SCIP_LPERROR )
4799 {
4800 *lperror = TRUE;
4801
4802 for( j = 0; j < nsubcols; ++j )
4803 {
4804 SCIP_COL* col;
4805 int idx;
4806
4807 col = subcols[j];
4808 idx = subidx[j];
4809
4810 col->sbdown = SCIP_INVALID;
4811 col->sbup = SCIP_INVALID;
4812 col->sbdownvalid = FALSE;
4813 col->sbupvalid = FALSE;
4814 col->validsblp = -1;
4815 col->sbsolval = SCIP_INVALID;
4816 col->sblpobjval = SCIP_INVALID;
4817 col->sbnode = -1;
4818
4819 down[idx] = col->sbdown;
4820 up[idx] = col->sbup;
4821 if( downvalid != NULL )
4822 downvalid[idx] = col->sbdownvalid;
4823 if( upvalid != NULL )
4824 upvalid[idx] = col->sbupvalid;
4825 }
4826 }
4827 else
4828 {
4829 SCIP_Real looseobjval;
4830
4831 *lperror = FALSE;
4832 SCIP_CALL( retcode );
4833
4834 looseobjval = getFiniteLooseObjval(lp, set, prob);
4835
4836 for( j = 0; j < nsubcols; ++j )
4837 {
4838 SCIP_COL* col;
4839 int idx;
4840
4841 col = subcols[j];
4842 idx = subidx[j];
4843
4844 assert( col->sbdown != SCIP_INVALID); /*lint !e777*/
4845 assert( col->sbup != SCIP_INVALID); /*lint !e777*/
4846
4847 col->sbdown = MIN(sbdown[j] + looseobjval, lp->cutoffbound);
4848 col->sbup = MIN(sbup[j] + looseobjval, lp->cutoffbound);
4849 col->sbdownvalid = sbdownvalid[j];
4850 col->sbupvalid = sbupvalid[j];
4851
4852 down[idx] = col->sbdown;
4853 up[idx] = col->sbup;
4854 if( downvalid != NULL )
4855 downvalid[idx] = col->sbdownvalid;
4856 if( upvalid != NULL )
4857 upvalid[idx] = col->sbupvalid;
4858 }
4859
4860 /* update strong branching statistics */
4861 if( iter == -1 )
4862 {
4863 /* calculate average iteration number */
4864 iter = stat->ndualresolvelps > 0 ? (int)(2*stat->ndualresolvelpiterations / stat->ndualresolvelps)
4865 : stat->nduallps > 0 ? (int)((stat->nduallpiterations / stat->nduallps) / 5)
4866 : stat->nprimalresolvelps > 0 ? (int)(2*stat->nprimalresolvelpiterations / stat->nprimalresolvelps)
4867 : stat->nprimallps > 0 ? (int)((stat->nprimallpiterations / stat->nprimallps) / 5)
4868 : 0;
4869 if( iter/2 >= itlim )
4870 iter = 2*itlim;
4871 }
4872 SCIPstatAdd(stat, set, nstrongbranchs, ncols);
4873 SCIPstatAdd(stat, set, nsblpiterations, iter);
4874 if( stat->nnodes == 1 )
4875 {
4876 SCIPstatAdd(stat, set, nrootstrongbranchs, ncols);
4877 SCIPstatAdd(stat, set, nrootsblpiterations, iter);
4878 }
4879 }
4880
4881 SCIPsetFreeBufferArray(set, &sbupvalid);
4882 SCIPsetFreeBufferArray(set, &sbdownvalid);
4884 SCIPsetFreeBufferArray(set, &sbdown);
4885 SCIPsetFreeBufferArray(set, &primsols);
4886 SCIPsetFreeBufferArray(set, &lpipos);
4887 SCIPsetFreeBufferArray(set, &subidx);
4888 SCIPsetFreeBufferArray(set, &subcols);
4889
4890 /* stop timing */
4892
4893 return SCIP_OKAY;
4894}
4895
4896/** gets last strong branching information available for a column variable;
4897 * returns values of SCIP_INVALID, if strong branching was not yet called on the given column;
4898 * keep in mind, that the returned old values may have nothing to do with the current LP solution
4899 */
4901 SCIP_COL* col, /**< LP column */
4902 SCIP_Real* down, /**< stores dual bound after branching column down, or NULL */
4903 SCIP_Real* up, /**< stores dual bound after branching column up, or NULL */
4904 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
4905 * otherwise, it can only be used as an estimate value */
4906 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
4907 * otherwise, it can only be used as an estimate value */
4908 SCIP_Real* solval, /**< stores LP solution value of column at last strong branching call, or NULL */
4909 SCIP_Real* lpobjval /**< stores LP objective value at last strong branching call, or NULL */
4910 )
4911{
4912 assert(col != NULL);
4913
4914 if( down != NULL )
4915 *down = col->sbdown;
4916 if( up != NULL )
4917 *up = col->sbup;
4918 if( downvalid != NULL )
4919 *downvalid = col->sbdownvalid;
4920 if( upvalid != NULL )
4921 *upvalid = col->sbupvalid;
4922 if( solval != NULL )
4923 *solval = col->sbsolval;
4924 if( lpobjval != NULL )
4925 *lpobjval = col->sblpobjval;
4926}
4927
4928/** if strong branching was already applied on the column at the current node, returns the number of LPs solved after
4929 * the LP where the strong branching on this column was applied;
4930 * if strong branching was not yet applied on the column at the current node, returns INT_MAX
4931 */
4933 SCIP_COL* col, /**< LP column */
4934 SCIP_STAT* stat /**< dynamic problem statistics */
4935 )
4936{
4937 assert(col != NULL);
4938 assert(stat != NULL);
4939
4940 return (col->sbnode != stat->nnodes ? SCIP_LONGINT_MAX : stat->nlps - col->validsblp);
4941}
4942
4943/** marks a column to be not removable from the LP in the current node because it became obsolete */
4945 SCIP_COL* col, /**< LP column */
4946 SCIP_STAT* stat /**< problem statistics */
4947 )
4948{
4949 assert(col != NULL);
4950 assert(stat != NULL);
4951 assert(stat->nnodes > 0);
4952
4953 /* lpRemoveObsoleteCols() does not remove a column if the node number stored in obsoletenode equals the current node number */
4954 col->obsoletenode = stat->nnodes;
4955}
4956
4957
4958/*
4959 * Row methods
4960 */
4961
4962/** calculates row norms and min/maxidx from scratch, and checks for sorting */
4963static
4965 SCIP_ROW* row, /**< LP row */
4966 SCIP_SET* set /**< global SCIP settings */
4967 )
4968{
4969 int i;
4970
4971 assert(row != NULL);
4972 assert(set != NULL);
4973
4974 row->sqrnorm = 0.0;
4975 row->sumnorm = 0.0;
4976 row->objprod = 0.0;
4977 row->maxval = 0.0;
4978 row->nummaxval = 1;
4979 row->minval = SCIPsetInfinity(set);
4980 row->numminval = 1;
4981 row->minidx = INT_MAX;
4982 row->maxidx = INT_MIN;
4983 row->validminmaxidx = TRUE;
4984 row->lpcolssorted = TRUE;
4985 row->nonlpcolssorted = TRUE;
4986
4987 /* check, if row is sorted
4988 * calculate sqrnorm, sumnorm, maxval, minval, minidx, and maxidx
4989 */
4990 for( i = 0; i < row->nlpcols; ++i )
4991 {
4992 assert(row->cols[i] != NULL);
4993 assert(!SCIPsetIsZero(set, row->vals[i]));
4994 assert(row->cols[i]->lppos >= 0);
4995 assert(row->linkpos[i] >= 0);
4996 assert(row->cols[i]->index == row->cols_index[i]);
4997
4998 rowAddNorms(row, set, row->cols[i], row->vals[i], TRUE);
4999 if( i > 0 )
5000 {
5001 assert(row->cols[i-1]->index == row->cols_index[i-1]);
5002 row->lpcolssorted = row->lpcolssorted && (row->cols_index[i-1] < row->cols_index[i]);
5003 }
5004 }
5005 for( i = row->nlpcols; i < row->len; ++i )
5006 {
5007 assert(row->cols[i] != NULL);
5008 assert(!SCIPsetIsZero(set, row->vals[i]));
5009 assert(row->cols[i]->lppos == -1 || row->linkpos[i] == -1);
5010 assert(row->cols[i]->index == row->cols_index[i]);
5011
5012 rowAddNorms(row, set, row->cols[i], row->vals[i], TRUE);
5013 if( i > row->nlpcols )
5014 {
5015 assert(row->cols[i-1]->index == row->cols_index[i-1]);
5016 row->nonlpcolssorted = row->nonlpcolssorted && (row->cols_index[i-1] < row->cols_index[i]);
5017 }
5018 }
5019}
5020
5021/** calculates min/maxval and min/maxidx from scratch */
5022static
5024 SCIP_ROW* row, /**< LP row */
5025 SCIP_SET* set /**< global SCIP settings */
5026 )
5027{
5028 SCIP_COL* col;
5029 SCIP_Real absval;
5030 int i;
5031
5032 assert(row != NULL);
5033 assert(set != NULL);
5034
5035 row->maxval = 0.0;
5036 row->nummaxval = 1;
5037 row->numintcols = 0;
5038 row->numimplintcols = 0;
5039 row->minval = SCIPsetInfinity(set);
5040 row->numminval = 1;
5041 row->minidx = INT_MAX;
5042 row->maxidx = INT_MIN;
5043 row->validminmaxidx = TRUE;
5044
5045 /* calculate maxval, minval, minidx, and maxidx */
5046 for( i = 0; i < row->len; ++i )
5047 {
5048 col = row->cols[i];
5049 assert(col != NULL);
5050 assert(!SCIPsetIsZero(set, row->vals[i]));
5051
5052 absval = REALABS(row->vals[i]);
5053 assert(!SCIPsetIsZero(set, absval));
5054
5055 /* update min/maxidx */
5056 row->minidx = MIN(row->minidx, col->index);
5057 row->maxidx = MAX(row->maxidx, col->index);
5058 if( SCIPcolIsIntegral(col) )
5059 {
5060 ++row->numintcols;
5061 if( SCIPcolIsImpliedIntegral(col) )
5062 ++row->numimplintcols;
5063 }
5064
5065 /* update maximal and minimal non-zero value */
5066 if( row->nummaxval > 0 )
5067 {
5068 if( SCIPsetIsGT(set, absval, row->maxval) )
5069 {
5070 row->maxval = absval;
5071 row->nummaxval = 1;
5072 }
5073 else if( SCIPsetIsGE(set, absval, row->maxval) )
5074 {
5075 /* make sure the maxval is always exactly the same */
5076 row->maxval = MAX(absval, row->maxval);
5077 row->nummaxval++;
5078 }
5079 }
5080 if( row->numminval > 0 )
5081 {
5082 if( SCIPsetIsLT(set, absval, row->minval) )
5083 {
5084 row->minval = absval;
5085 row->numminval = 1;
5086 }
5087 else if( SCIPsetIsLE(set, absval, row->minval) )
5088 {
5089 /* make sure the minval is always exactly the same */
5090 row->minval = MIN(absval, row->minval);
5091 row->numminval++;
5092 }
5093 }
5094 }
5095}
5096
5097/** checks whether the given scalar scales the given value to an integral number with error in the given bounds */
5098static
5100 SCIP_Real val, /**< value that should be scaled to an integral value */
5101 SCIP_Real scalar, /**< scalar that should be tried */
5102 SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
5103 SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
5104 SCIP_Real* intval /**< pointer to store the scaled integral value, or NULL */
5105 )
5106{
5107 SCIP_Real sval;
5108 SCIP_Real downval;
5109 SCIP_Real upval;
5110
5111 assert(mindelta <= 0.0);
5112 assert(maxdelta >= 0.0);
5113
5114 sval = val * scalar;
5115 downval = floor(sval);
5116 upval = ceil(sval);
5117
5118 if( SCIPrelDiff(sval, downval) <= maxdelta )
5119 {
5120 if( intval != NULL )
5121 *intval = downval;
5122 return TRUE;
5123 }
5124 else if( SCIPrelDiff(sval, upval) >= mindelta )
5125 {
5126 if( intval != NULL )
5127 *intval = upval;
5128 return TRUE;
5129 }
5130
5131 return FALSE;
5132}
5133
5134/** scales row with given factor, and rounds coefficients to integers if close enough;
5135 * the constant is automatically moved to the sides;
5136 * if the row's activity is proven to be integral, the sides are automatically rounded to the next integer
5137 */
5138static
5140 SCIP_ROW* row, /**< LP row */
5141 BMS_BLKMEM* blkmem, /**< block memory */
5142 SCIP_SET* set, /**< global SCIP settings */
5143 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5144 SCIP_STAT* stat, /**< problem statistics */
5145 SCIP_LP* lp, /**< current LP data */
5146 SCIP_Real scaleval, /**< value to scale row with */
5147 SCIP_Bool integralcontvars, /**< should the coefficients of the continuous variables also be made integral,
5148 * if they are close to integral values? */
5149 SCIP_Real minrounddelta, /**< minimal relative difference of scaled coefficient s*c and integral i,
5150 * upto which the integral is used instead of the scaled real coefficient */
5151 SCIP_Real maxrounddelta /**< maximal relative difference of scaled coefficient s*c and integral i
5152 * upto which the integral is used instead of the scaled real coefficient */
5153 )
5154{
5155 SCIP_COL* col;
5156 SCIP_Real val;
5157 SCIP_Real newval;
5158 SCIP_Real intval;
5159 SCIP_Real mindelta;
5160 SCIP_Real maxdelta;
5161 SCIP_Real lb;
5162 SCIP_Real ub;
5163 SCIP_Bool mindeltainf;
5164 SCIP_Bool maxdeltainf;
5165 int oldlen;
5166 int c;
5167
5168 assert(row != NULL);
5169 assert(row->len == 0 || row->cols != NULL);
5170 assert(row->len == 0 || row->vals != NULL);
5171 assert(SCIPsetIsPositive(set, scaleval));
5172 assert(-1.0 < minrounddelta && minrounddelta <= 0.0);
5173 assert(0.0 <= maxrounddelta && maxrounddelta < 1.0);
5174
5175 SCIPsetDebugMsg(set, "scale row <%s> with %g (tolerance=[%g,%g])\n", row->name, scaleval, minrounddelta, maxrounddelta);
5176
5177 mindelta = 0.0;
5178 maxdelta = 0.0;
5179 mindeltainf = FALSE;
5180 maxdeltainf = FALSE;
5181 oldlen = row->len;
5182
5183 /* scale the row coefficients, thereby recalculating whether the row's activity is always integral;
5184 * if the row coefficients are rounded to the nearest integer value, calculate the maximal activity difference,
5185 * this rounding can lead to
5186 */
5187 row->integral = TRUE;
5188
5189 c = 0;
5190 while( c < row->len )
5191 {
5192 col = row->cols[c];
5193 val = row->vals[c];
5194 assert(!SCIPsetIsZero(set, val));
5195
5196 /* get local or global bounds for column, depending on the local or global feasibility of the row */
5197 if( row->local )
5198 {
5199 lb = col->lb;
5200 ub = col->ub;
5201 }
5202 else
5203 {
5204 lb = SCIPvarGetLbGlobal(col->var);
5205 ub = SCIPvarGetUbGlobal(col->var);
5206 }
5207
5208 /* calculate scaled coefficient */
5209 newval = val * scaleval;
5210 if( (integralcontvars || SCIPcolIsIntegral(col) || SCIPsetIsIntegral(set, newval))
5211 && isIntegralScalar(val, scaleval, minrounddelta, maxrounddelta, &intval) )
5212 {
5213 if( !SCIPsetIsEQ(set, intval, newval) )
5214 {
5215 if( intval < newval )
5216 {
5217 mindelta += (intval - newval)*ub;
5218 maxdelta += (intval - newval)*lb;
5219 mindeltainf = mindeltainf || SCIPsetIsInfinity(set, ub);
5220 maxdeltainf = maxdeltainf || SCIPsetIsInfinity(set, -lb);
5221 }
5222 else
5223 {
5224 mindelta += (intval - newval)*lb;
5225 maxdelta += (intval - newval)*ub;
5226 mindeltainf = mindeltainf || SCIPsetIsInfinity(set, -lb);
5227 maxdeltainf = maxdeltainf || SCIPsetIsInfinity(set, ub);
5228 }
5229 }
5230 newval = intval;
5231 }
5232
5233 if( !SCIPsetIsEQ(set, val, newval) )
5234 {
5235 /* if column knows of the row, change the corresponding coefficient in the column */
5236 if( row->linkpos[c] >= 0 )
5237 {
5238 assert(col->rows[row->linkpos[c]] == row);
5239 assert(SCIPsetIsEQ(set, col->vals[row->linkpos[c]], row->vals[c]));
5240 SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[c], newval) );
5241 }
5242
5243 /* change the coefficient in the row, and update the norms and integrality status */
5244 SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, c, newval) );
5245
5246 /* current coefficient has been deleted from the row because it was almost zero */
5247 if( oldlen != row->len )
5248 {
5249 assert(row->len == oldlen - 1);
5250 c--;
5251 oldlen = row->len;
5252 }
5253 }
5254 else
5255 {
5256 row->integral = row->integral && SCIPcolIsIntegral(col) && SCIPsetIsIntegral(set, val);
5257 if( set->exact_enable )
5259 }
5260
5261 ++c;
5262 }
5263
5264 /* scale the row sides, and move the constant to the sides; relax the sides with accumulated delta in order
5265 * to not destroy feasibility due to rounding
5266 */
5267 /**@todo ensure that returned cut does not have infinite lhs and rhs */
5268 if( !SCIPsetIsInfinity(set, -row->lhs) )
5269 {
5270 if( mindeltainf )
5271 newval = -SCIPsetInfinity(set);
5272 else
5273 {
5274 newval = (row->lhs - row->constant) * scaleval + mindelta;
5275 if( SCIPsetIsIntegral(set, newval) || (row->integral && !row->modifiable) )
5276 newval = SCIPsetSumCeil(set, newval);
5277 }
5278 SCIP_CALL( SCIProwChgLhs(row, blkmem, set, eventqueue, lp, newval) );
5279 }
5280 if( !SCIPsetIsInfinity(set, row->rhs) )
5281 {
5282 if( maxdeltainf )
5283 newval = SCIPsetInfinity(set);
5284 else
5285 {
5286 newval = (row->rhs - row->constant) * scaleval + maxdelta;
5287 if( SCIPsetIsIntegral(set, newval) || (row->integral && !row->modifiable) )
5288 newval = SCIPsetSumFloor(set, newval);
5289 }
5290 SCIP_CALL( SCIProwChgRhs(row, blkmem, set, eventqueue, lp, newval) );
5291 }
5292
5293 /* clear the row constant */
5294 SCIP_CALL( SCIProwChgConstant(row, blkmem, set, stat, eventqueue, lp, 0.0) );
5295
5296 SCIPsetDebugMsg(set, "scaled row <%s> (integral: %u)\n", row->name, row->integral);
5297 debugRowPrint(set, row);
5298
5299#ifdef SCIP_DEBUG
5300 /* check integrality status of row */
5301 for( c = 0; c < row->len && SCIPcolIsIntegral(row->cols[c]) && SCIPsetIsIntegral(set, row->vals[c]); ++c )
5302 {}
5303 assert(row->integral == (c == row->len));
5304#endif
5305
5306 /* invalid the activity */
5307 row->validactivitylp = -1;
5308
5309 return SCIP_OKAY;
5310}
5311
5312/** creates and captures an LP row */
5314 SCIP_ROW** row, /**< pointer to LP row data */
5315 BMS_BLKMEM* blkmem, /**< block memory */
5316 SCIP_SET* set, /**< global SCIP settings */
5317 SCIP_STAT* stat, /**< problem statistics */
5318 const char* name, /**< name of row */
5319 int len, /**< number of nonzeros in the row */
5320 SCIP_COL** cols, /**< array with columns of row entries */
5321 SCIP_Real* vals, /**< array with coefficients of row entries */
5322 SCIP_Real lhs, /**< left hand side of row */
5323 SCIP_Real rhs, /**< right hand side of row */
5324 SCIP_ROWORIGINTYPE origintype, /**< type of origin of row */
5325 void* origin, /**< pointer to constraint handler or separator who created the row (NULL if unkown) */
5326 SCIP_Bool local, /**< is row only valid locally? */
5327 SCIP_Bool modifiable, /**< is row modifiable during node processing (subject to column generation)? */
5328 SCIP_Bool removable /**< should the row be removed from the LP due to aging or cleanup? */
5329 )
5330{
5331 assert(row != NULL);
5332 assert(blkmem != NULL);
5333 assert(stat != NULL);
5334 assert(len >= 0);
5335 assert(len == 0 || (cols != NULL && vals != NULL));
5336 /* note, that the assert tries to avoid numerical troubles in the LP solver.
5337 * in case, for example, lhs > rhs but they are equal with tolerances, one could pass lhs=rhs=lhs+rhs/2 to
5338 * SCIProwCreate() (see cons_linear.c: detectRedundantConstraints())
5339 */
5340 assert(lhs <= rhs);
5341
5342 SCIP_ALLOC( BMSallocBlockMemory(blkmem, row) );
5343
5344 (*row)->integral = TRUE;
5345 if( len > 0 )
5346 {
5347 SCIP_VAR* var;
5348 int i;
5349
5350 SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->cols, cols, len) );
5351 SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->vals, vals, len) );
5352 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*row)->cols_index, len) );
5353 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*row)->linkpos, len) );
5354
5355 for( i = 0; i < len; ++i )
5356 {
5357 assert(cols[i] != NULL);
5358 assert(!SCIPsetIsZero(set, vals[i]));
5359
5360 var = cols[i]->var;
5361 (*row)->cols_index[i] = cols[i]->index;
5362 (*row)->linkpos[i] = -1;
5363 if( SCIPsetIsIntegral(set, (*row)->vals[i]) && !set->exact_enable )
5364 {
5365 (*row)->vals[i] = SCIPsetRound(set, (*row)->vals[i]);
5366 (*row)->integral = (*row)->integral && SCIPvarIsIntegral(var);
5367 }
5368 else
5369 {
5370 (*row)->integral = FALSE;
5371 }
5372 }
5373 }
5374 else
5375 {
5376 (*row)->cols = NULL;
5377 (*row)->cols_index = NULL;
5378 (*row)->vals = NULL;
5379 (*row)->linkpos = NULL;
5380 }
5381
5382 SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->name, name, strlen(name)+1) );
5383 (*row)->constant = 0.0;
5384 (*row)->lhs = lhs;
5385 (*row)->rhs = rhs;
5386 (*row)->flushedlhs = -SCIPsetInfinity(set);
5387 (*row)->flushedrhs = SCIPsetInfinity(set);
5388 (*row)->sqrnorm = 0.0;
5389 (*row)->sumnorm = 0.0;
5390 (*row)->objprod = 0.0;
5391 (*row)->maxval = 0.0;
5392 (*row)->minval = SCIPsetInfinity(set);
5393 (*row)->dualsol = 0.0;
5394 (*row)->activity = SCIP_INVALID;
5395 (*row)->dualfarkas = 0.0;
5396 (*row)->pseudoactivity = SCIP_INVALID;
5397 (*row)->minactivity = SCIP_INVALID;
5398 (*row)->maxactivity = SCIP_INVALID;
5399 (*row)->origin = origin;
5400 (*row)->eventfilter = NULL;
5401 (*row)->index = stat->nrowidx;
5402 SCIPstatIncrement(stat, set, nrowidx);
5403 (*row)->size = len;
5404 (*row)->len = len;
5405 (*row)->nlpcols = 0;
5406 (*row)->nunlinked = len;
5407 (*row)->nuses = 0;
5408 (*row)->lppos = -1;
5409 (*row)->lpipos = -1;
5410 (*row)->lpdepth = -1;
5411 (*row)->minidx = INT_MAX;
5412 (*row)->maxidx = INT_MIN;
5413 (*row)->nummaxval = 0;
5414 (*row)->numminval = 0;
5415 (*row)->numintcols = -1;
5416 (*row)->numimplintcols = -1;
5417 (*row)->validactivitylp = -1;
5418 (*row)->validpsactivitydomchg = -1;
5419 (*row)->validactivitybdsdomchg = -1;
5420 (*row)->nlpsaftercreation = 0L;
5421 (*row)->activeinlpcounter = 0L;
5422 (*row)->age = 0;
5423 (*row)->rank = 0;
5424 (*row)->obsoletenode = -1;
5425 (*row)->fromcutpool = FALSE;
5426 (*row)->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
5427 (*row)->lpcolssorted = TRUE;
5428 (*row)->nonlpcolssorted = (len <= 1);
5429 (*row)->delaysort = FALSE;
5430 (*row)->validminmaxidx = FALSE;
5431 (*row)->lhschanged = FALSE;
5432 (*row)->rhschanged = FALSE;
5433 (*row)->coefchanged = FALSE;
5434 (*row)->local = local;
5435 (*row)->modifiable = modifiable;
5436 (*row)->nlocks = 0;
5437 (*row)->origintype = origintype; /*lint !e641*/
5438 (*row)->removable = removable;
5439 (*row)->inglobalcutpool = FALSE;
5440 (*row)->storedsolvals = NULL;
5441 (*row)->rowexact = NULL;
5442
5443 /* calculate row norms and min/maxidx, and check if row is sorted */
5444 rowCalcNorms(*row, set);
5445
5446 /* capture the row */
5447 SCIProwCapture(*row);
5448
5449 /* create event filter */
5450 SCIP_CALL( SCIPeventfilterCreate(&(*row)->eventfilter, blkmem) );
5451
5452 /* capture origin constraint if available */
5453 if( origintype == SCIP_ROWORIGINTYPE_CONS )
5454 {
5455 SCIP_CONS* cons = (SCIP_CONS*) origin;
5456 assert(cons != NULL);
5457 SCIPconsCapture(cons);
5458 }
5459
5460 return SCIP_OKAY;
5461} /*lint !e715*/
5462
5463/** frees an LP row */
5465 SCIP_ROW** row, /**< pointer to LP row */
5466 BMS_BLKMEM* blkmem, /**< block memory */
5467 SCIP_SET* set, /**< global SCIP settings */
5468 SCIP_LP* lp /**< current LP data */
5469 )
5470{
5471 assert(blkmem != NULL);
5472 assert(row != NULL);
5473 assert(*row != NULL);
5474 assert((*row)->nuses == 0);
5475 assert((*row)->lppos == -1);
5476 assert((*row)->eventfilter != NULL);
5477
5478 /* release constraint that has been used for creating the row */
5479 if( (SCIP_ROWORIGINTYPE) (*row)->origintype == SCIP_ROWORIGINTYPE_CONS )
5480 {
5481 SCIP_CONS* cons = (SCIP_CONS*) (*row)->origin;
5482 assert(cons != NULL);
5483 SCIP_CALL( SCIPconsRelease(&cons, blkmem, set) );
5484 }
5485
5486 /* remove column indices from corresponding rows */
5487 SCIP_CALL( rowUnlink(*row, set, lp) );
5488
5489 /* free event filter */
5490 SCIP_CALL( SCIPeventfilterFree(&(*row)->eventfilter, blkmem, set) );
5491
5492 BMSfreeBlockMemoryNull(blkmem, &(*row)->storedsolvals);
5493 BMSfreeBlockMemoryArray(blkmem, &(*row)->name, strlen((*row)->name)+1);
5494 BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->cols, (*row)->size);
5495 BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->cols_index, (*row)->size);
5496 BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->vals, (*row)->size);
5497 BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->linkpos, (*row)->size);
5498
5499 if( (*row)->rowexact != NULL )
5500 {
5501 if( *row == (*row)->rowexact->fprow )
5502 (*row)->rowexact->fprow = NULL;
5503 else
5504 (*row)->rowexact->fprowrhs = NULL;
5505 SCIP_CALL( SCIProwExactRelease(&(*row)->rowexact, blkmem, set, lp->lpexact) );
5506 }
5507
5508 BMSfreeBlockMemory(blkmem, row);
5509
5510 return SCIP_OKAY;
5511}
5512
5513/** output row to file stream */
5515 SCIP_ROW* row, /**< LP row */
5516 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
5517 FILE* file /**< output file (or NULL for standard output) */
5518 )
5519{
5520 int i;
5521
5522 assert(row != NULL);
5523
5524 /* print row name */
5525 if( row->name != NULL && row->name[0] != '\0' )
5526 {
5527 SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", row->name);
5528 }
5529
5530 /* print left hand side */
5531 SCIPmessageFPrintInfo(messagehdlr, file, "%.15g <= ", row->lhs);
5532
5533 /* print coefficients */
5534 if( row->len == 0 )
5535 SCIPmessageFPrintInfo(messagehdlr, file, "0 ");
5536 for( i = 0; i < row->len; ++i )
5537 {
5538 assert(row->cols[i] != NULL);
5539 assert(row->cols[i]->var != NULL);
5540 assert(SCIPvarGetName(row->cols[i]->var) != NULL);
5542 SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g<%s> ", row->vals[i], SCIPvarGetName(row->cols[i]->var));
5543 }
5544
5545 /* print constant */
5547 SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g ", row->constant);
5548
5549 /* print right hand side */
5550 SCIPmessageFPrintInfo(messagehdlr, file, "<= %.15g\n", row->rhs);
5551}
5552
5553/** increases usage counter of LP row */
5555 SCIP_ROW* row /**< LP row */
5556 )
5557{
5558 assert(row != NULL);
5559 assert(row->nuses >= 0);
5560 assert(row->nlocks <= (unsigned int)(row->nuses)); /*lint !e574*/
5561
5562 SCIPdebugMessage("capture row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
5563 row->nuses++;
5564}
5565
5566/** decreases usage counter of LP row, and frees memory if necessary */
5568 SCIP_ROW** row, /**< pointer to LP row */
5569 BMS_BLKMEM* blkmem, /**< block memory */
5570 SCIP_SET* set, /**< global SCIP settings */
5571 SCIP_LP* lp /**< current LP data */
5572 )
5573{
5574 assert(blkmem != NULL);
5575 assert(row != NULL);
5576 assert(*row != NULL);
5577 assert((*row)->nuses >= 1);
5578 assert((*row)->nlocks < (unsigned int)((*row)->nuses)); /*lint !e574*/
5579
5580 SCIPsetDebugMsg(set, "release row <%s> with nuses=%d and nlocks=%u\n", (*row)->name, (*row)->nuses, (*row)->nlocks);
5581 (*row)->nuses--;
5582 if( (*row)->nuses == 0 )
5583 {
5584 SCIP_CALL( SCIPcertificateFreeRowInfo(set->scip, (*row)) );
5585 SCIP_CALL( SCIProwFree(row, blkmem, set, lp) );
5586 }
5587
5588 *row = NULL;
5589
5590 return SCIP_OKAY;
5591}
5592
5593/** locks an unmodifiable row, which forbids further changes; has no effect on modifiable rows */
5595 SCIP_ROW* row /**< LP row */
5596 )
5597{
5598 assert(row != NULL);
5599
5600 /* check, if row is modifiable */
5601 if( !row->modifiable )
5602 {
5603 SCIPdebugMessage("lock row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
5604 row->nlocks++;
5605 }
5606}
5607
5608/** unlocks a lock of an unmodifiable row; a row with no sealed lock may be modified; has no effect on modifiable rows */
5610 SCIP_ROW* row /**< LP row */
5611 )
5612{
5613 assert(row != NULL);
5614
5615 /* check, if row is modifiable */
5616 if( !row->modifiable )
5617 {
5618 SCIPdebugMessage("unlock row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
5619 assert(row->nlocks > 0);
5620 row->nlocks--;
5621 }
5622}
5623
5624/** adds a previously non existing coefficient to an LP row */
5626 SCIP_ROW* row, /**< LP row */
5627 BMS_BLKMEM* blkmem, /**< block memory */
5628 SCIP_SET* set, /**< global SCIP settings */
5629 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5630 SCIP_LP* lp, /**< current LP data */
5631 SCIP_COL* col, /**< LP column */
5632 SCIP_Real val /**< value of coefficient */
5633 )
5634{
5635 assert(lp != NULL);
5636 assert(!lp->diving || row->lppos == -1);
5637
5638 SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, val, -1) );
5639
5640 checkLinks(lp);
5641
5642 return SCIP_OKAY;
5643}
5644
5645/** deletes coefficient from row */
5647 SCIP_ROW* row, /**< row to be changed */
5648 BMS_BLKMEM* blkmem, /**< block memory */
5649 SCIP_SET* set, /**< global SCIP settings */
5650 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5651 SCIP_LP* lp, /**< current LP data */
5652 SCIP_COL* col /**< coefficient to be deleted */
5653 )
5654{
5655 int pos;
5656
5657 assert(row != NULL);
5658 assert(!row->delaysort);
5659 assert(lp != NULL);
5660 assert(!lp->diving || row->lppos == -1);
5661 assert(col != NULL);
5662 assert(col->var != NULL);
5663
5664 /* search the position of the column in the row's col vector */
5665 pos = rowSearchCoef(row, col);
5666 if( pos == -1 )
5667 {
5668 SCIPerrorMessage("coefficient for column <%s> doesn't exist in row <%s>\n", SCIPvarGetName(col->var), row->name);
5669 return SCIP_INVALIDDATA;
5670 }
5671 assert(0 <= pos && pos < row->len);
5672 assert(row->cols[pos] == col);
5673 assert(row->cols_index[pos] == col->index);
5674
5675 /* if column knows of the row, remove the row from the column's row vector */
5676 if( row->linkpos[pos] >= 0 )
5677 {
5678 assert(col->rows[row->linkpos[pos]] == row);
5679 assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
5680 SCIP_CALL( colDelCoefPos(col, set, lp, row->linkpos[pos]) );
5681 }
5682
5683 /* delete the column from the row's col vector */
5684 SCIP_CALL( rowDelCoefPos(row, blkmem, set, eventqueue, lp, pos) );
5685
5686 checkLinks(lp);
5687
5688 return SCIP_OKAY;
5689}
5690
5691/** changes or adds a coefficient to an LP row */
5693 SCIP_ROW* row, /**< LP row */
5694 BMS_BLKMEM* blkmem, /**< block memory */
5695 SCIP_SET* set, /**< global SCIP settings */
5696 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5697 SCIP_LP* lp, /**< current LP data */
5698 SCIP_COL* col, /**< LP column */
5699 SCIP_Real val /**< value of coefficient */
5700 )
5701{
5702 int pos;
5703
5704 assert(row != NULL);
5705 assert(!row->delaysort);
5706 assert(lp != NULL);
5707 assert(!lp->diving || row->lppos == -1);
5708 assert(col != NULL);
5709
5710 /* search the position of the column in the row's col vector */
5711 pos = rowSearchCoef(row, col);
5712
5713 /* check, if column already exists in the row's col vector */
5714 if( pos == -1 )
5715 {
5716 /* add previously not existing coefficient */
5717 SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, val, -1) );
5718 }
5719 else
5720 {
5721 /* modify already existing coefficient */
5722 assert(0 <= pos && pos < row->len);
5723 assert(row->cols[pos] == col);
5724 assert(row->cols_index[pos] == col->index);
5725
5726 /* if column knows of the row, change the corresponding coefficient in the column */
5727 if( row->linkpos[pos] >= 0 )
5728 {
5729 assert(col->rows[row->linkpos[pos]] == row);
5730 assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
5731 SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[pos], val) );
5732 }
5733
5734 /* change the coefficient in the row */
5735 SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, pos, val) );
5736 }
5737
5738 checkLinks(lp);
5739
5740 return SCIP_OKAY;
5741}
5742
5743/** increases value of an existing or non-existing coefficient in an LP row */
5745 SCIP_ROW* row, /**< LP row */
5746 BMS_BLKMEM* blkmem, /**< block memory */
5747 SCIP_SET* set, /**< global SCIP settings */
5748 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5749 SCIP_LP* lp, /**< current LP data */
5750 SCIP_COL* col, /**< LP column */
5751 SCIP_Real incval /**< value to add to the coefficient */
5752 )
5753{
5754 int pos;
5755
5756 assert(row != NULL);
5757 assert(lp != NULL);
5758 assert(!lp->diving || row->lppos == -1);
5759 assert(col != NULL);
5760
5761 if( SCIPsetIsZero(set, incval) )
5762 return SCIP_OKAY;
5763
5764 /* search the position of the column in the row's col vector */
5765 pos = rowSearchCoef(row, col);
5766
5767 /* check, if column already exists in the row's col vector */
5768 if( pos == -1 )
5769 {
5770 /* coefficient doesn't exist, or sorting is delayed: add coefficient to the end of the row's arrays */
5771 SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, incval, -1) );
5772 }
5773 else
5774 {
5775 /* modify already existing coefficient */
5776 assert(0 <= pos && pos < row->len);
5777 assert(row->cols[pos] == col);
5778 assert(row->cols_index[pos] == col->index);
5779
5780 /* if column knows of the row, change the corresponding coefficient in the column */
5781 if( row->linkpos[pos] >= 0 )
5782 {
5783 assert(col->rows[row->linkpos[pos]] == row);
5784 assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
5785 SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[pos], row->vals[pos] + incval) );
5786 }
5787
5788 /* change the coefficient in the row */
5789 SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, pos, row->vals[pos] + incval) );
5790 }
5791
5792 checkLinks(lp);
5793
5794 /* invalid the activity */
5795 row->validactivitylp = -1;
5796
5797 return SCIP_OKAY;
5798}
5799
5800/** changes constant value of a row */
5802 SCIP_ROW* row, /**< LP row */
5803 BMS_BLKMEM* blkmem, /**< block memory */
5804 SCIP_SET* set, /**< global SCIP settings */
5805 SCIP_STAT* stat, /**< problem statistics */
5806 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5807 SCIP_LP* lp, /**< current LP data */
5808 SCIP_Real constant /**< new constant value */
5809 )
5810{
5811 assert(row != NULL);
5812 assert(row->lhs <= row->rhs);
5813 assert(!SCIPsetIsInfinity(set, REALABS(constant)));
5814 assert(stat != NULL);
5815 assert(lp != NULL);
5816 assert(!lp->diving || row->lppos == -1);
5817
5818 if( !SCIPsetIsEQ(set, constant, row->constant) )
5819 {
5820 SCIP_Real oldconstant;
5821
5822 if( row->validpsactivitydomchg == stat->domchgcount )
5823 {
5824 assert(row->pseudoactivity != SCIP_INVALID); /*lint !e777*/
5825 row->pseudoactivity += constant - row->constant;
5826 }
5827 if( row->validactivitybdsdomchg == stat->domchgcount )
5828 {
5829 assert(row->minactivity != SCIP_INVALID); /*lint !e777*/
5830 assert(row->maxactivity != SCIP_INVALID); /*lint !e777*/
5831 row->minactivity += constant - row->constant;
5832 row->maxactivity += constant - row->constant;
5833 }
5834
5835 if( !SCIPsetIsInfinity(set, -row->lhs) )
5836 {
5838 }
5839 if( !SCIPsetIsInfinity(set, row->rhs) )
5840 {
5842 }
5843
5844 oldconstant = row->constant;
5845
5846 row->constant = constant;
5847
5848 /* issue row constant changed event */
5849 SCIP_CALL( rowEventConstantChanged(row, blkmem, set, eventqueue, oldconstant, constant) );
5850 }
5851
5852 return SCIP_OKAY;
5853}
5854
5855/** add constant value to a row */
5857 SCIP_ROW* row, /**< LP row */
5858 BMS_BLKMEM* blkmem, /**< block memory */
5859 SCIP_SET* set, /**< global SCIP settings */
5860 SCIP_STAT* stat, /**< problem statistics */
5861 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5862 SCIP_LP* lp, /**< current LP data */
5863 SCIP_Real addval /**< constant value to add to the row */
5864 )
5865{
5866 assert(row != NULL);
5867 assert(row->lhs <= row->rhs);
5868 assert(!SCIPsetIsInfinity(set, REALABS(addval)));
5869 assert(stat != NULL);
5870 assert(lp != NULL);
5871 assert(!lp->diving || row->lppos == -1);
5872
5873 if( !SCIPsetIsZero(set, addval) )
5874 {
5875 SCIP_CALL( SCIProwChgConstant(row, blkmem, set, stat, eventqueue, lp, row->constant + addval) );
5876 }
5877
5878 return SCIP_OKAY;
5879}
5880
5881/** changes left hand side of LP row */
5883 SCIP_ROW* row, /**< LP row */
5884 BMS_BLKMEM* blkmem, /**< block memory */
5885 SCIP_SET* set, /**< global SCIP settings */
5886 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5887 SCIP_LP* lp, /**< current LP data */
5888 SCIP_Real lhs /**< new left hand side */
5889 )
5890{
5891 assert(row != NULL);
5892 assert(lp != NULL);
5893
5894 if( !SCIPsetIsEQ(set, row->lhs, lhs) || (set->exact_enable && row->lhs != lhs) ) /*lint !e777*/
5895 {
5896 SCIP_Real oldlhs;
5897
5898 oldlhs = row->lhs;
5899
5900 row->lhs = lhs;
5902
5903 if( !lp->diving )
5904 {
5905 /* issue row side changed event */
5906 SCIP_CALL( rowEventSideChanged(row, blkmem, set, eventqueue, SCIP_SIDETYPE_LEFT, oldlhs, lhs) );
5907 }
5908 }
5909
5910 return SCIP_OKAY;
5911}
5912
5913/** changes right hand side of LP row */
5915 SCIP_ROW* row, /**< LP row */
5916 BMS_BLKMEM* blkmem, /**< block memory */
5917 SCIP_SET* set, /**< global SCIP settings */
5918 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5919 SCIP_LP* lp, /**< current LP data */
5920 SCIP_Real rhs /**< new right hand side */
5921 )
5922{
5923 assert(row != NULL);
5924 assert(lp != NULL);
5925
5926 if( !SCIPsetIsEQ(set, row->rhs, rhs) || (set->exact_enable && row->rhs != rhs) ) /*lint !e777*/
5927 {
5928 SCIP_Real oldrhs;
5929
5930 oldrhs = row->rhs;
5931
5932 row->rhs = rhs;
5934
5935 if( !lp->diving )
5936 {
5937 /* issue row side changed event */
5938 SCIP_CALL( rowEventSideChanged(row, blkmem, set, eventqueue, SCIP_SIDETYPE_RIGHT, oldrhs, rhs) );
5939 }
5940 }
5941
5942 return SCIP_OKAY;
5943}
5944
5945/** changes the local flag of LP row */
5947 SCIP_ROW* row, /**< LP row */
5948 SCIP_Bool local /**< new value for local flag */
5949 )
5950{
5951 assert(row != NULL);
5952
5953 row->local = local;
5954
5955 return SCIP_OKAY;
5956}
5957
5958/** additional scalars that are tried in integrality scaling */
5959static const SCIP_Real scalars[] = {3.0, 5.0, 7.0, 9.0, 11.0, 13.0, 15.0, 17.0, 19.0};
5960static const int nscalars = 9;
5961
5962/** tries to find a value, such that all row coefficients, if scaled with this value become integral */
5964 SCIP_ROW* row, /**< LP row */
5965 SCIP_SET* set, /**< global SCIP settings */
5966 SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
5967 SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
5968 SCIP_Longint maxdnom, /**< maximal denominator allowed in rational numbers */
5969 SCIP_Real maxscale, /**< maximal allowed scalar */
5970 SCIP_Bool usecontvars, /**< should the coefficients of the continuous variables also be made integral? */
5971 SCIP_Real* intscalar, /**< pointer to store scalar that would make the coefficients integral, or NULL */
5972 SCIP_Bool* success /**< stores whether returned value is valid */
5973 )
5974{
5975#ifndef NDEBUG
5976 SCIP_COL* col;
5977#endif
5978 SCIP_Longint gcd;
5979 SCIP_Longint scm;
5980 SCIP_Longint numerator;
5981 SCIP_Longint denominator;
5982 SCIP_Real val;
5983 SCIP_Real absval;
5984 SCIP_Real minval;
5985 SCIP_Real scaleval;
5986 SCIP_Real twomultval;
5987 SCIP_Bool scalable;
5988 SCIP_Bool twomult;
5989 SCIP_Bool rational;
5990 int c;
5991 int s;
5992
5993 /**@todo call misc.c:SCIPcalcIntegralScalar() instead - if usecontvars == FALSE, filter the integer variables first */
5994 assert(row != NULL);
5995 assert(row->len == 0 || row->cols != NULL);
5996 assert(row->len == 0 || row->cols_index != NULL);
5997 assert(row->len == 0 || row->vals != NULL);
5998 assert(maxdnom >= 1);
5999 assert(mindelta < 0.0);
6000 assert(maxdelta > 0.0);
6001 assert(success != NULL);
6002
6003 SCIPsetDebugMsg(set, "trying to find rational representation for row <%s> (contvars: %u)\n", SCIProwGetName(row), usecontvars);
6004 SCIPdebug( val = 0; ); /* avoid warning "val might be used uninitialized; see SCIPdebugMessage lastval=%g below */
6005
6006 if( intscalar != NULL )
6007 *intscalar = SCIP_INVALID;
6008 *success = FALSE;
6009
6010 /* get minimal absolute non-zero value */
6011 minval = SCIP_REAL_MAX;
6012 for( c = 0; c < row->len; ++c )
6013 {
6014#ifndef NDEBUG
6015 col = row->cols[c];
6016 assert(col != NULL);
6017 assert(col->var != NULL);
6019 assert(SCIPvarGetCol(col->var) == col);
6020#endif
6021 val = row->vals[c];
6022 assert(!SCIPsetIsZero(set, val));
6023
6024 if( val < mindelta || val > maxdelta )
6025 {
6026 absval = REALABS(val);
6027 minval = MIN(minval, absval);
6028 }
6029 }
6030 if( minval == SCIP_REAL_MAX ) /*lint !e777*/
6031 {
6032 /* all coefficients are zero (inside tolerances) */
6033 if( intscalar != NULL )
6034 *intscalar = 1.0;
6035 *success = TRUE;
6036 SCIPsetDebugMsg(set, " -> all values are zero (inside tolerances)\n");
6037
6038 return SCIP_OKAY;
6039 }
6040 assert(minval > MIN(-mindelta, maxdelta));
6041 assert(SCIPsetIsPositive(set, minval));
6042 assert(!SCIPsetIsInfinity(set, minval));
6043
6044 /* try, if row coefficients can be made integral by multiplying them with the reciprocal of the smallest coefficient
6045 * and a power of 2
6046 */
6047 scaleval = 1.0/minval;
6048 scalable = (scaleval <= maxscale);
6049 for( c = 0; c < row->len && scalable; ++c )
6050 {
6051 /* don't look at continuous variables, if we don't have to */
6052 if( !usecontvars && !SCIPcolIsIntegral(row->cols[c]) )
6053 continue;
6054
6055 /* check, if the coefficient can be scaled with a simple scalar */
6056 val = row->vals[c];
6057 absval = REALABS(val);
6058 while( scaleval <= maxscale
6059 && (absval * scaleval < 0.5 || !isIntegralScalar(val, scaleval, mindelta, maxdelta, NULL)) )
6060 {
6061 for( s = 0; s < nscalars; ++s )
6062 {
6063 if( isIntegralScalar(val, scaleval * scalars[s], mindelta, maxdelta, NULL) )
6064 {
6065 scaleval *= scalars[s];
6066 break;
6067 }
6068 }
6069 if( s >= nscalars )
6070 scaleval *= 2.0;
6071 }
6072 scalable = (scaleval <= maxscale);
6073 SCIPsetDebugMsg(set, " -> val=%g, scaleval=%g, val*scaleval=%g, scalable=%u\n", val, scaleval, val*scaleval, scalable);
6074 }
6075 if( scalable )
6076 {
6077 /* make row coefficients integral by dividing them by the smallest coefficient
6078 * (and multiplying them with a power of 2)
6079 */
6080 assert(scaleval <= maxscale);
6081 if( intscalar != NULL )
6082 *intscalar = scaleval;
6083 *success = TRUE;
6084 SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (minval=%g)\n", scaleval, minval);
6085
6086 return SCIP_OKAY;
6087 }
6088
6089 /* try, if row coefficients can be made integral by multiplying them by a power of 2 */
6090 twomultval = 1.0;
6091 twomult = (twomultval <= maxscale);
6092 for( c = 0; c < row->len && twomult; ++c )
6093 {
6094 /* don't look at continuous variables, if we don't have to */
6095 if( !usecontvars && !SCIPcolIsIntegral(row->cols[c]) )
6096 continue;
6097
6098 /* check, if the coefficient can be scaled with a simple scalar */
6099 val = row->vals[c];
6100 absval = REALABS(val);
6101 while( twomultval <= maxscale
6102 && (absval * twomultval < 0.5 || !isIntegralScalar(val, twomultval, mindelta, maxdelta, NULL)) )
6103 {
6104 for( s = 0; s < nscalars; ++s )
6105 {
6106 if( isIntegralScalar(val, twomultval * scalars[s], mindelta, maxdelta, NULL) )
6107 {
6108 twomultval *= scalars[s];
6109 break;
6110 }
6111 }
6112 if( s >= nscalars )
6113 twomultval *= 2.0;
6114 }
6115 twomult = (twomultval <= maxscale);
6116 SCIPsetDebugMsg(set, " -> val=%g, twomult=%g, val*twomult=%g, twomultable=%u\n",
6117 val, twomultval, val*twomultval, twomult);
6118 }
6119 if( twomult )
6120 {
6121 /* make row coefficients integral by multiplying them with a power of 2 */
6122 assert(twomultval <= maxscale);
6123 if( intscalar != NULL )
6124 *intscalar = twomultval;
6125 *success = TRUE;
6126 SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (power of 2)\n", twomultval);
6127
6128 return SCIP_OKAY;
6129 }
6130
6131 /* convert each coefficient into a rational number, calculate the greatest common divisor of the numerators
6132 * and the smallest common multiple of the denominators
6133 */
6134 gcd = 1;
6135 scm = 1;
6136 rational = (maxdnom > 1);
6137
6138 /* first coefficient (to initialize gcd) */
6139 for( c = 0; c < row->len && rational; ++c )
6140 {
6141 if( usecontvars || SCIPcolIsIntegral(row->cols[c]) )
6142 {
6143 val = row->vals[c];
6144 rational = SCIPrealToRational(val, mindelta, maxdelta, maxdnom, &numerator, &denominator);
6145 if( rational && numerator != 0 )
6146 {
6147 assert(denominator > 0);
6148 gcd = ABS(numerator);
6149 scm = denominator;
6150 rational = ((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
6151 SCIPsetDebugMsg(set, " -> first rational: val: %g == %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ", gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", rational=%u\n",
6152 val, numerator, denominator, gcd, scm, rational);
6153 break;
6154 }
6155 }
6156 }
6157
6158 /* remaining coefficients */
6159 for( ++c; c < row->len && rational; ++c )
6160 {
6161 if( usecontvars || SCIPcolIsIntegral(row->cols[c]) )
6162 {
6163 val = row->vals[c];
6164 rational = SCIPrealToRational(val, mindelta, maxdelta, maxdnom, &numerator, &denominator);
6165 if( rational && numerator != 0 )
6166 {
6167 assert(denominator > 0);
6168 gcd = SCIPcalcGreComDiv(gcd, ABS(numerator));
6169 scm *= denominator / SCIPcalcGreComDiv(scm, denominator);
6170 rational = ((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
6171 SCIPsetDebugMsg(set, " -> next rational : val: %g == %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ", gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", rational=%u\n",
6172 val, numerator, denominator, gcd, scm, rational);
6173 }
6174 }
6175 }
6176
6177 if( rational )
6178 {
6179 /* make row coefficients integral by multiplying them with the smallest common multiple of the denominators */
6180 assert((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
6181 if( intscalar != NULL )
6182 *intscalar = (SCIP_Real)scm/(SCIP_Real)gcd;
6183 *success = TRUE;
6184 SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (rational:%" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ")\n",
6185 (SCIP_Real)scm/(SCIP_Real)gcd, scm, gcd);
6186 }
6187 else
6188 {
6189 assert(!(*success));
6190 SCIPsetDebugMsg(set, " -> rationalizing failed: gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", lastval=%g\n", gcd, scm, val); /*lint !e771*/
6191 }
6192
6193 return SCIP_OKAY;
6194}
6195
6196/** tries to scale row, s.t. all coefficients become integral */
6198 SCIP_ROW* row, /**< LP row */
6199 BMS_BLKMEM* blkmem, /**< block memory */
6200 SCIP_SET* set, /**< global SCIP settings */
6201 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
6202 SCIP_STAT* stat, /**< problem statistics */
6203 SCIP_LP* lp, /**< current LP data */
6204 SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
6205 SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
6206 SCIP_Longint maxdnom, /**< maximal denominator allowed in rational numbers */
6207 SCIP_Real maxscale, /**< maximal value to scale row with */
6208 SCIP_Bool usecontvars, /**< should the coefficients of the continuous variables also be made integral? */
6209 SCIP_Bool* success /**< stores whether row could be made rational */
6210 )
6211{
6212 SCIP_Real intscalar;
6213
6214 assert(success != NULL);
6215
6216 /* calculate scalar to make coefficients integral */
6217 SCIP_CALL( SCIProwCalcIntegralScalar(row, set, mindelta, maxdelta, maxdnom, maxscale, usecontvars,
6218 &intscalar, success) );
6219
6220 if( *success )
6221 {
6222 /* scale the row */
6223 SCIP_CALL( rowScale(row, blkmem, set, eventqueue, stat, lp, intscalar, usecontvars, mindelta, maxdelta) );
6224 }
6225
6226 return SCIP_OKAY;
6227}
6228
6229/** sorts row entries such that LP columns precede non-LP columns and inside both parts lower column indices precede
6230 * higher ones
6231 */
6233 SCIP_ROW* row /**< row to be sorted */
6234 )
6235{
6236 assert(row != NULL);
6237
6238 /* sort LP columns */
6239 rowSortLP(row);
6240
6241 /* sort non-LP columns */
6242 rowSortNonLP(row);
6243
6244#ifdef SCIP_MORE_DEBUG
6245 /* check the sorting */
6246 {
6247 int c;
6248 if( !row->delaysort )
6249 {
6250 for( c = 1; c < row->nlpcols; ++c )
6251 assert(row->cols[c]->index >= row->cols[c-1]->index);
6252 for( c = row->nlpcols + 1; c < row->len; ++c )
6253 assert(row->cols[c]->index >= row->cols[c-1]->index);
6254 }
6255 }
6256#endif
6257}
6258
6259/** sorts row, and merges equal column entries (resulting from lazy sorting and adding) into a single entry; removes
6260 * zero entries from row
6261 * the row must not be linked to the columns; otherwise, we would need to update the columns as
6262 * well, which is too expensive
6263 */
6264static
6266 SCIP_ROW* row, /**< row to be sorted */
6267 SCIP_SET* set /**< global SCIP settings */
6268 )
6269{
6270 assert(row != NULL);
6271 assert(!row->delaysort);
6272 assert(row->nunlinked == row->len);
6273 assert(row->nlpcols == 0);
6274
6275 SCIPsetDebugMsg(set, "merging row <%s>\n", row->name);
6276
6277 /* do nothing on empty rows; if row is sorted, nothing has to be done */
6278 if( row->len > 0 && (!row->lpcolssorted || !row->nonlpcolssorted) )
6279 {
6280 SCIP_COL** cols;
6281 int* cols_index;
6282 SCIP_Real* vals;
6283 int s;
6284 int t;
6285
6286 /* make sure, the row is sorted */
6287 SCIProwSort(row);
6288 assert(row->lpcolssorted);
6289 assert(row->nonlpcolssorted);
6290
6291 /* merge equal columns, thereby recalculating whether the row's activity is always integral */
6292 cols = row->cols;
6293 cols_index = row->cols_index;
6294 vals = row->vals;
6295 assert(cols != NULL);
6296 assert(cols_index != NULL);
6297 assert(vals != NULL);
6298
6299 t = 0;
6300 row->integral = TRUE;
6301 assert(!SCIPsetIsZero(set, vals[0]));
6302 assert(row->linkpos[0] == -1);
6303
6304 for( s = 1; s < row->len; ++s )
6305 {
6306 assert(!SCIPsetIsZero(set, vals[s]));
6307 assert(row->linkpos[s] == -1);
6308
6309 if( cols[s] == cols[t] )
6310 {
6311 /* merge entries with equal column */
6312 vals[t] += vals[s];
6313 }
6314 else
6315 {
6316 /* go to the next entry, overwriting current entry if coefficient is zero */
6317 if( !SCIPsetIsZero(set, vals[t]) )
6318 {
6319 /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
6320 if( !set->exact_enable )
6321 vals[t] = SCIPsetIsIntegral(set, vals[t]) ? SCIPsetRound(set, vals[t]) : vals[t];
6322
6323 row->integral = row->integral && SCIPcolIsIntegral(cols[t]) && SCIPsetIsIntegral(set, vals[t]);
6324 if( set->exact_enable )
6325 row->integral = row->integral && SCIPcolIsIntegral(cols[t]) && SCIPrealIsExactlyIntegral(vals[t]);
6326 t++;
6327 }
6328 cols[t] = cols[s];
6329 cols_index[t] = cols_index[s];
6330 vals[t] = vals[s];
6331 }
6332 }
6333 if( !SCIPsetIsZero(set, vals[t]) )
6334 {
6335 row->integral = row->integral && SCIPcolIsIntegral(cols[t]) && SCIPsetIsIntegral(set, vals[t]);
6336 if( set->exact_enable )
6337 row->integral = row->integral && SCIPcolIsIntegral(cols[t]) && SCIPrealIsExactlyIntegral(vals[t]);
6338 t++;
6339 }
6340 assert(s == row->len);
6341 assert(t <= row->len);
6342
6343 row->len = t;
6344 row->nunlinked = t;
6345
6346 /* if equal entries were merged, we have to recalculate the norms, since the squared Euclidean norm is wrong */
6347 if( t < s )
6348 rowCalcNorms(row, set);
6349 }
6350
6351#ifndef NDEBUG
6352 /* check for double entries */
6353 {
6354 int i;
6355 int j;
6356
6357 for( i = 0; i < row->len; ++i )
6358 {
6359 assert(row->cols[i] != NULL);
6360 assert(row->cols[i]->index == row->cols_index[i]);
6361 for( j = i+1; j < row->len; ++j )
6362 assert(row->cols[i] != row->cols[j]);
6363 }
6364 }
6365#endif
6366}
6367
6368/** enables delaying of row sorting */
6370 SCIP_ROW* row /**< LP row */
6371 )
6372{
6373 assert(row != NULL);
6374 assert(!row->delaysort);
6375
6376 row->delaysort = TRUE;
6377}
6378
6379/** disables delaying of row sorting, sorts row and merges coefficients with equal columns */
6381 SCIP_ROW* row, /**< LP row */
6382 SCIP_SET* set /**< global SCIP settings */
6383 )
6384{
6385 assert(row != NULL);
6386 assert(row->delaysort);
6387
6388 row->delaysort = FALSE;
6389 rowMerge(row, set);
6390}
6391
6392/** recalculates norms of a row */
6394 SCIP_ROW* row, /**< LP row */
6395 SCIP_SET* set /**< global SCIP settings */
6396 )
6397{
6398 rowCalcNorms(row, set);
6399}
6400
6401/** recalculates the current activity of a row */
6403 SCIP_ROW* row, /**< LP row */
6404 SCIP_STAT* stat /**< problem statistics */
6405 )
6406{
6407 SCIP_COL* col;
6408 int c;
6409
6410 assert(row != NULL);
6411 assert(stat != NULL);
6412
6413 row->activity = row->constant;
6414 for( c = 0; c < row->nlpcols; ++c )
6415 {
6416 col = row->cols[c];
6417 assert(col != NULL);
6418 assert(col->primsol != SCIP_INVALID); /*lint !e777*/
6419 assert(col->lppos >= 0);
6420 assert(row->linkpos[c] >= 0);
6421 row->activity += row->vals[c] * col->primsol;
6422 }
6423
6424 if( row->nunlinked > 0 )
6425 {
6426 for( c = row->nlpcols; c < row->len; ++c )
6427 {
6428 col = row->cols[c];
6429 assert(col != NULL);
6430 assert(col->lppos >= 0 || col->primsol == 0.0);
6431 assert(col->lppos == -1 || row->linkpos[c] == -1);
6432 if( col->lppos >= 0 )
6433 row->activity += row->vals[c] * col->primsol;
6434 }
6435 }
6436#ifndef NDEBUG
6437 else
6438 {
6439 for( c = row->nlpcols; c < row->len; ++c )
6440 {
6441 col = row->cols[c];
6442 assert(col != NULL);
6443 assert(col->primsol == 0.0);
6444 assert(col->lppos == -1);
6445 assert(row->linkpos[c] >= 0);
6446 }
6447 }
6448#endif
6449
6450 row->validactivitylp = stat->lpcount;
6451}
6452
6453/** returns the activity of a row in the current LP solution */
6455 SCIP_ROW* row, /**< LP row */
6456 SCIP_SET* set, /**< global SCIP settings */
6457 SCIP_STAT* stat, /**< problem statistics */
6458 SCIP_LP* lp /**< current LP data */
6459 )
6460{
6461 SCIP_Real inf;
6462 SCIP_Real activity;
6463
6464 assert(row != NULL);
6465 assert(stat != NULL);
6466 assert(lp != NULL);
6467 assert(row->validactivitylp <= stat->lpcount);
6468 assert(lp->validsollp == stat->lpcount);
6469
6470 if( row->validactivitylp != stat->lpcount )
6471 SCIProwRecalcLPActivity(row, stat);
6472 assert(row->validactivitylp == stat->lpcount);
6473 assert(row->activity != SCIP_INVALID); /*lint !e777*/
6474
6475 activity = row->activity;
6476 inf = SCIPsetInfinity(set);
6477 activity = MAX(activity, -inf);
6478 activity = MIN(activity, +inf);
6479
6480 return activity;
6481}
6482
6483/** returns the feasibility of a row in the current LP solution: negative value means infeasibility */
6485 SCIP_ROW* row, /**< LP row */
6486 SCIP_SET* set, /**< global SCIP settings */
6487 SCIP_STAT* stat, /**< problem statistics */
6488 SCIP_LP* lp /**< current LP data */
6489 )
6490{
6491 SCIP_Real activity;
6492
6493 assert(row != NULL);
6494
6495 activity = SCIProwGetLPActivity(row, set, stat, lp);
6496
6497 return MIN(row->rhs - activity, activity - row->lhs);
6498}
6499
6500/** returns the feasibility of a row in the relaxed solution solution: negative value means infeasibility
6501 *
6502 * @todo Implement calculation of activities similar to LPs.
6503 */
6505 SCIP_ROW* row, /**< LP row */
6506 SCIP_SET* set, /**< global SCIP settings */
6507 SCIP_STAT* stat /**< problem statistics */
6508 )
6509{
6510 SCIP_Real inf;
6511 SCIP_Real activity;
6512 SCIP_COL* col;
6513 int c;
6514
6515 assert( row != NULL );
6516 assert( stat != NULL );
6517
6518 activity = row->constant;
6519 for (c = 0; c < row->nlpcols; ++c)
6520 {
6521 col = row->cols[c];
6522 assert( col != NULL );
6523 assert( col->lppos >= 0 );
6524 assert( col->var != NULL );
6525 assert( row->linkpos[c] >= 0 );
6526 activity += row->vals[c] * SCIPvarGetRelaxSol(col->var, set);
6527 }
6528
6529 if ( row->nunlinked > 0 )
6530 {
6531 for (c = row->nlpcols; c < row->len; ++c)
6532 {
6533 col = row->cols[c];
6534 assert( col != NULL );
6535 assert( col->lppos == -1 || row->linkpos[c] == -1 );
6536 if ( col->lppos >= 0 )
6537 {
6538 assert( col->var != NULL );
6539 activity += row->vals[c] * SCIPvarGetRelaxSol(col->var, set);
6540 }
6541 }
6542 }
6543#ifndef NDEBUG
6544 else
6545 {
6546 for (c = row->nlpcols; c < row->len; ++c)
6547 {
6548 col = row->cols[c];
6549 assert( col != NULL );
6550 assert( col->lppos == -1 );
6551 assert( row->linkpos[c] >= 0 );
6552 }
6553 }
6554#endif
6555 inf = SCIPsetInfinity(set);
6556 activity = MAX(activity, -inf);
6557 activity = MIN(activity, +inf);
6558
6559 return MIN(row->rhs - activity, activity - row->lhs);
6560}
6561
6562/** returns the feasibility of a row in the current NLP solution: negative value means infeasibility
6563 *
6564 * @todo Implement calculation of activities similar to LPs.
6565 */
6567 SCIP_ROW* row, /**< LP row */
6568 SCIP_SET* set, /**< global SCIP settings */
6569 SCIP_STAT* stat /**< problem statistics */
6570 )
6571{
6572 SCIP_Real inf;
6573 SCIP_Real activity;
6574 SCIP_COL* col;
6575 int c;
6576
6577 assert( row != NULL );
6578 assert( stat != NULL );
6579
6580 activity = row->constant;
6581 for (c = 0; c < row->nlpcols; ++c)
6582 {
6583 col = row->cols[c];
6584 assert( col != NULL );
6585 assert( col->lppos >= 0 );
6586 assert( col->var != NULL );
6587 assert( row->linkpos[c] >= 0 );
6588 activity += row->vals[c] * SCIPvarGetNLPSol(col->var);
6589 }
6590
6591 if ( row->nunlinked > 0 )
6592 {
6593 for (c = row->nlpcols; c < row->len; ++c)
6594 {
6595 col = row->cols[c];
6596 assert( col != NULL );
6597 assert( col->lppos == -1 || row->linkpos[c] == -1 );
6598 if ( col->lppos >= 0 )
6599 {
6600 assert( col->var != NULL );
6601 activity += row->vals[c] * SCIPvarGetNLPSol(col->var);
6602 }
6603 }
6604 }
6605#ifndef NDEBUG
6606 else
6607 {
6608 for (c = row->nlpcols; c < row->len; ++c)
6609 {
6610 col = row->cols[c];
6611 assert( col != NULL );
6612 assert( col->lppos == -1 );
6613 assert( row->linkpos[c] >= 0 );
6614 }
6615 }
6616#endif
6617 inf = SCIPsetInfinity(set);
6618 activity = MAX(activity, -inf);
6619 activity = MIN(activity, +inf);
6620
6621 return MIN(row->rhs - activity, activity - row->lhs);
6622}
6623
6624/** calculates the current pseudo activity of a row */
6626 SCIP_ROW* row, /**< row data */
6627 SCIP_STAT* stat /**< problem statistics */
6628 )
6629{
6630 SCIP_COL* col;
6631 int i;
6632
6633 assert(row != NULL);
6634 assert(stat != NULL);
6635
6636 row->pseudoactivity = row->constant;
6637 for( i = 0; i < row->len; ++i )
6638 {
6639 col = row->cols[i];
6640 assert(col != NULL);
6641 assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
6642 assert(col->var != NULL);
6644
6645 row->pseudoactivity += SCIPcolGetBestBound(col) * row->vals[i];
6646 }
6649}
6650
6651/** returns the pseudo activity of a row in the current pseudo solution */
6653 SCIP_ROW* row, /**< LP row */
6654 SCIP_SET* set, /**< global SCIP settings */
6655 SCIP_STAT* stat /**< problem statistics */
6656 )
6657{
6658 SCIP_Real inf;
6659 SCIP_Real activity;
6660
6661 assert(row != NULL);
6662 assert(stat != NULL);
6664
6665 /* check, if pseudo activity has to be calculated */
6666 if( row->validpsactivitydomchg != stat->domchgcount )
6667 SCIProwRecalcPseudoActivity(row, stat);
6669 assert(row->pseudoactivity != SCIP_INVALID); /*lint !e777*/
6670
6671 activity = row->pseudoactivity;
6672 inf = SCIPsetInfinity(set);
6673 activity = MAX(activity, -inf);
6674 activity = MIN(activity, +inf);
6675
6676 return activity;
6677}
6678
6679/** returns the pseudo feasibility of a row in the current pseudo solution: negative value means infeasibility */
6681 SCIP_ROW* row, /**< LP row */
6682 SCIP_SET* set, /**< global SCIP settings */
6683 SCIP_STAT* stat /**< problem statistics */
6684 )
6685{
6686 SCIP_Real pseudoactivity;
6687
6688 assert(row != NULL);
6689
6690 pseudoactivity = SCIProwGetPseudoActivity(row, set, stat);
6691
6692 return MIN(row->rhs - pseudoactivity, pseudoactivity - row->lhs);
6693}
6694
6695/** returns the activity of a row for a given solution */
6697 SCIP_ROW* row, /**< LP row */
6698 SCIP_SET* set, /**< global SCIP settings */
6699 SCIP_STAT* stat, /**< problem statistics data */
6700 SCIP_SOL* sol /**< primal CIP solution */
6701 )
6702{
6703 SCIP_COL* col;
6704 SCIP_Real inf;
6705 SCIP_Real activity;
6706 SCIP_Real solval;
6707 int i;
6708
6709 assert(row != NULL);
6710
6711 activity = row->constant;
6712 for( i = 0; i < row->len; ++i )
6713 {
6714 col = row->cols[i];
6715 assert(col != NULL);
6716 assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
6717 solval = SCIPsolGetVal(sol, set, stat, col->var);
6718 if( solval == SCIP_UNKNOWN ) /*lint !e777*/
6719 {
6720 if( SCIPsetIsInfinity(set, -row->lhs) )
6721 solval = (row->vals[i] >= 0.0 ? col->lb : col->ub);
6722 else if( SCIPsetIsInfinity(set, row->rhs) )
6723 solval = (row->vals[i] >= 0.0 ? col->ub : col->lb);
6724 else
6725 solval = (col->lb + col->ub)/2.0;
6726 }
6727 activity += row->vals[i] * solval;
6728 }
6729
6730 inf = SCIPsetInfinity(set);
6731 activity = MAX(activity, -inf);
6732 activity = MIN(activity, +inf);
6733
6734 return activity;
6735}
6736
6737/** returns the feasibility of a row for the given solution */
6739 SCIP_ROW* row, /**< LP row */
6740 SCIP_SET* set, /**< global SCIP settings */
6741 SCIP_STAT* stat, /**< problem statistics data */
6742 SCIP_SOL* sol /**< primal CIP solution */
6743 )
6744{
6745 SCIP_Real activity;
6746
6747 assert(row != NULL);
6748
6749 activity = SCIProwGetSolActivity(row, set, stat, sol);
6750
6751 return MIN(row->rhs - activity, activity - row->lhs);
6752}
6753
6754/** calculates minimal and maximal activity of row w.r.t. the column's bounds */
6755static
6757 SCIP_ROW* row, /**< row data */
6758 SCIP_SET* set, /**< global SCIP settings */
6759 SCIP_STAT* stat /**< problem statistics data */
6760 )
6761{
6762 SCIP_COL* col;
6763 SCIP_Real val;
6764 SCIP_Bool mininfinite;
6765 SCIP_Bool maxinfinite;
6766 int i;
6767
6768 assert(row != NULL);
6770 assert(stat != NULL);
6771
6772 /* calculate activity bounds */
6773 mininfinite = FALSE;
6774 maxinfinite = FALSE;
6775 row->minactivity = row->constant;
6776 row->maxactivity = row->constant;
6777 for( i = 0; i < row->len && (!mininfinite || !maxinfinite); ++i )
6778 {
6779 col = row->cols[i];
6780 assert(col != NULL);
6781 assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
6782 val = row->vals[i];
6783 if( val >= 0.0 )
6784 {
6785 mininfinite = mininfinite || SCIPsetIsInfinity(set, -col->lb);
6786 maxinfinite = maxinfinite || SCIPsetIsInfinity(set, col->ub);
6787 if( !mininfinite )
6788 row->minactivity += val * col->lb;
6789 if( !maxinfinite )
6790 row->maxactivity += val * col->ub;
6791 }
6792 else
6793 {
6794 mininfinite = mininfinite || SCIPsetIsInfinity(set, col->ub);
6795 maxinfinite = maxinfinite || SCIPsetIsInfinity(set, -col->lb);
6796 if( !mininfinite )
6797 row->minactivity += val * col->ub;
6798 if( !maxinfinite )
6799 row->maxactivity += val * col->lb;
6800 }
6801 }
6802
6803 if( mininfinite )
6805 if( maxinfinite )
6808
6809#ifndef NDEBUG
6810 {
6811 SCIP_Real inttol = 1000.0*SCIPsetFeastol(set);
6812
6813 /* even if the row is integral, the bounds on the variables used for computing minimum and maximum activity might
6814 * be integral only within feasibility tolerance; this can happen, e.g., if a continuous variable is promoted to
6815 * an (implicit) integer variable and the bounds cannot be adjusted because they are minimally tighter than the
6816 * rounded bound value; hence, the activity may violate integrality; we allow 1000 times the default feasibility
6817 * tolerance as a proxy to account for the accumulation effect
6818 */
6819 assert(!row->integral || mininfinite || REALABS(row->minactivity - row->constant) > 1.0/SCIPsetSumepsilon(set)
6820 || EPSISINT(row->minactivity - row->constant, inttol));
6821 assert(!row->integral || maxinfinite || REALABS(row->maxactivity - row->constant) > 1.0/SCIPsetSumepsilon(set)
6822 || EPSISINT(row->maxactivity - row->constant, inttol));
6823 }
6824#endif
6825}
6826
6827/** returns the minimal activity of a row w.r.t. the columns' bounds */
6829 SCIP_ROW* row, /**< LP row */
6830 SCIP_SET* set, /**< global SCIP settings */
6831 SCIP_STAT* stat /**< problem statistics data */
6832 )
6833{
6834 assert(row != NULL);
6835 assert(stat != NULL);
6837
6838 /* check, if activity bounds has to be calculated */
6839 if( row->validactivitybdsdomchg != stat->domchgcount )
6840 rowCalcActivityBounds(row, set, stat);
6842 assert(row->minactivity != SCIP_INVALID); /*lint !e777*/
6843 assert(row->maxactivity != SCIP_INVALID); /*lint !e777*/
6844
6845 return row->minactivity;
6846}
6847
6848/** returns the maximal activity of a row w.r.t. the columns' bounds */
6850 SCIP_ROW* row, /**< LP row */
6851 SCIP_SET* set, /**< global SCIP settings */
6852 SCIP_STAT* stat /**< problem statistics data */
6853 )
6854{
6855 assert(row != NULL);
6856 assert(stat != NULL);
6858
6859 /* check, if activity bounds has to be calculated */
6860 if( row->validactivitybdsdomchg != stat->domchgcount )
6861 rowCalcActivityBounds(row, set, stat);
6863 assert(row->minactivity != SCIP_INVALID); /*lint !e777*/
6864 assert(row->maxactivity != SCIP_INVALID); /*lint !e777*/
6865
6866 return row->maxactivity;
6867}
6868
6869/** returns whether the row is unmodifiable and redundant w.r.t. the columns' bounds */
6871 SCIP_ROW* row, /**< LP row */
6872 SCIP_SET* set, /**< global SCIP settings */
6873 SCIP_STAT* stat /**< problem statistics data */
6874 )
6875{
6876 assert(row != NULL);
6877
6878 if( row->modifiable )
6879 return FALSE;
6880 if( !SCIPsetIsInfinity(set, -row->lhs) )
6881 {
6882 SCIP_Real minactivity;
6883
6884 minactivity = SCIProwGetMinActivity(row, set, stat);
6885 if( SCIPsetIsFeasLT(set, minactivity, row->lhs) )
6886 return FALSE;
6887 }
6888 if( !SCIPsetIsInfinity(set, row->rhs) )
6889 {
6890 SCIP_Real maxactivity;
6891
6892 maxactivity = SCIProwGetMaxActivity(row, set, stat);
6893 if( SCIPsetIsFeasGT(set, maxactivity, row->rhs) )
6894 return FALSE;
6895 }
6896
6897 return TRUE;
6898}
6899
6900/** gets maximal absolute value of row vector coefficients */
6902 SCIP_ROW* row, /**< LP row */
6903 SCIP_SET* set /**< global SCIP settings */
6904 )
6905{
6906 assert(row != NULL);
6907
6908 if( row->nummaxval == 0 )
6909 rowCalcIdxsAndVals(row, set);
6910 assert(row->nummaxval > 0);
6911 assert(row->maxval >= 0.0 || row->len == 0);
6912
6913 return row->maxval;
6914}
6915
6916/** gets minimal absolute value of row vector's non-zero coefficients */
6918 SCIP_ROW* row, /**< LP row */
6919 SCIP_SET* set /**< global SCIP settings */
6920 )
6921{
6922 assert(row != NULL);
6923
6924 if( row->numminval == 0 )
6925 rowCalcIdxsAndVals(row, set);
6926 assert(row->numminval > 0);
6927 assert(row->minval >= 0.0 || row->len == 0);
6928
6929 return row->minval;
6930}
6931
6932/** gets maximal column index of row entries */
6934 SCIP_ROW* row, /**< LP row */
6935 SCIP_SET* set /**< global SCIP settings */
6936 )
6937{
6938 assert(row != NULL);
6939
6940 if( row->validminmaxidx == 0 )
6941 rowCalcIdxsAndVals(row, set);
6942 assert(row->maxidx >= 0 || row->len == 0);
6943 assert(row->validminmaxidx);
6944
6945 return row->maxidx;
6946}
6947
6948/** gets minimal column index of row entries */
6950 SCIP_ROW* row, /**< LP row */
6951 SCIP_SET* set /**< global SCIP settings */
6952 )
6953{
6954 assert(row != NULL);
6955
6956 if( row->validminmaxidx == 0 )
6957 rowCalcIdxsAndVals(row, set);
6958 assert(row->minidx >= 0 || row->len == 0);
6959 assert(row->validminmaxidx);
6960
6961 return row->minidx;
6962}
6963
6964/** gets number of integral columns in row */
6966 SCIP_ROW* row, /**< LP row */
6967 SCIP_SET* set /**< global SCIP settings */
6968 )
6969{
6970 assert(row != NULL);
6971
6972 if( row->numintcols == -1 )
6973 rowCalcIdxsAndVals(row, set);
6974
6975 assert(row->numintcols <= row->len && row->numintcols >= 0);
6976
6977 return row->numintcols;
6978}
6979
6980/** gets number of implied integral columns in row */
6982 SCIP_ROW* row, /**< LP row */
6983 SCIP_SET* set /**< global SCIP settings */
6984 )
6985{
6986 assert(row != NULL);
6987
6988 if( row->numimplintcols == -1 )
6989 rowCalcIdxsAndVals(row, set);
6990
6991 assert(row->numimplintcols <= row->len && row->numimplintcols >= 0);
6992
6993 return row->numimplintcols;
6994}
6995
6996/** returns row's cutoff distance in the direction of the given primal solution */
6998 SCIP_ROW* row, /**< LP row */
6999 SCIP_SET* set, /**< global SCIP settings */
7000 SCIP_STAT* stat, /**< problem statistics data */
7001 SCIP_SOL* sol, /**< solution to compute direction for cutoff distance; must not be NULL */
7002 SCIP_LP* lp /**< current LP data */
7003 )
7004{
7005 SCIP_Real solcutoffdist;
7006 int k;
7007
7008 assert(sol != NULL);
7009
7010 if( lp->validsoldirlp != stat->lpcount || lp->validsoldirsol != sol )
7011 {
7012 SCIP_Real scale = 0.0;
7013
7014 lp->validsoldirlp = stat->lpcount;
7015 lp->validsoldirsol = sol;
7016
7018
7019 for( k = 0; k < lp->ncols; ++k )
7020 {
7021 assert(lp->cols[k]->lppos == k);
7022 lp->soldirection[k] = SCIPsolGetVal(sol, set, stat, lp->cols[k]->var) - lp->cols[k]->primsol;
7023 scale += SQR(lp->soldirection[k]);
7024 }
7025
7026 if( scale > 0.0 )
7027 {
7028 scale = 1.0 / sqrt(scale);
7029
7030 for( k = 0; k < lp->ncols; ++k )
7031 lp->soldirection[k] *= scale;
7032 }
7033 }
7034
7035 solcutoffdist = 0.0;
7036 for( k = 0; k < row->nlpcols; ++k )
7037 solcutoffdist += row->vals[k] * lp->soldirection[row->cols[k]->lppos];
7038
7039 for( k = row->nlpcols; k < row->len; ++k )
7040 {
7041 if( row->cols[k]->lppos >= 0 )
7042 solcutoffdist += row->vals[k] * lp->soldirection[row->cols[k]->lppos];
7043 }
7044
7045 if( SCIPsetIsSumZero(set, solcutoffdist) )
7046 solcutoffdist = set->num_sumepsilon;
7047
7048 solcutoffdist = -SCIProwGetLPFeasibility(row, set, stat, lp) / ABS(solcutoffdist); /*lint !e795*/
7049
7050 return solcutoffdist;
7051}
7052
7053/** returns row's efficacy with respect to the current LP solution: e = -feasibility/norm */
7055 SCIP_ROW* row, /**< LP row */
7056 SCIP_SET* set, /**< global SCIP settings */
7057 SCIP_STAT* stat, /**< problem statistics data */
7058 SCIP_LP* lp /**< current LP data */
7059 )
7060{
7061 SCIP_Real norm;
7062 SCIP_Real feasibility;
7063 SCIP_Real eps;
7064
7065 assert(set != NULL);
7066
7067 switch( set->sepa_efficacynorm )
7068 {
7069 case 'e':
7070 norm = SCIProwGetNorm(row);
7071 break;
7072 case 'm':
7073 norm = SCIProwGetMaxval(row, set);
7074 break;
7075 case 's':
7076 norm = SCIProwGetSumNorm(row);
7077 break;
7078 case 'd':
7079 norm = (row->len == 0 ? 0.0 : 1.0);
7080 break;
7081 default:
7082 SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
7083 SCIPABORT();
7084 norm = 0.0; /*lint !e527*/
7085 }
7086
7088 norm = MAX(norm, eps);
7089 feasibility = SCIProwGetLPFeasibility(row, set, stat, lp);
7090
7091 return -feasibility / norm;
7092}
7093
7094/** returns whether the row's efficacy with respect to the current LP solution is greater than the minimal cut efficacy */
7096 SCIP_ROW* row, /**< LP row */
7097 SCIP_SET* set, /**< global SCIP settings */
7098 SCIP_STAT* stat, /**< problem statistics data */
7099 SCIP_LP* lp, /**< current LP data */
7100 SCIP_Bool root /**< should the root's minimal cut efficacy be used? */
7101 )
7102{
7103 SCIP_Real efficacy;
7104
7105 efficacy = SCIProwGetLPEfficacy(row, set, stat, lp);
7106
7107 return SCIPsetIsEfficacious(set, root, efficacy);
7108}
7109
7110/** returns row's efficacy with respect to the given primal solution: e = -feasibility/norm */
7112 SCIP_ROW* row, /**< LP row */
7113 SCIP_SET* set, /**< global SCIP settings */
7114 SCIP_STAT* stat, /**< problem statistics data */
7115 SCIP_SOL* sol /**< primal CIP solution */
7116 )
7117{
7118 SCIP_Real norm;
7119 SCIP_Real feasibility;
7120 SCIP_Real eps;
7121
7122 assert(set != NULL);
7123
7124 switch( set->sepa_efficacynorm )
7125 {
7126 case 'e':
7127 norm = SCIProwGetNorm(row);
7128 break;
7129 case 'm':
7130 norm = SCIProwGetMaxval(row, set);
7131 break;
7132 case 's':
7133 norm = SCIProwGetSumNorm(row);
7134 break;
7135 case 'd':
7136 norm = (row->len == 0 ? 0.0 : 1.0);
7137 break;
7138 default:
7139 SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
7140 SCIPABORT();
7141 norm = 0.0; /*lint !e527*/
7142 }
7143
7145 norm = MAX(norm, eps);
7146 feasibility = SCIProwGetSolFeasibility(row, set, stat, sol);
7147
7148 return -feasibility / norm;
7149}
7150
7151/** returns whether the row's efficacy with respect to the given primal solution is greater than the minimal cut
7152 * efficacy
7153 */
7155 SCIP_ROW* row, /**< LP row */
7156 SCIP_SET* set, /**< global SCIP settings */
7157 SCIP_STAT* stat, /**< problem statistics data */
7158 SCIP_SOL* sol, /**< primal CIP solution */
7159 SCIP_Bool root /**< should the root's minimal cut efficacy be used? */
7160 )
7161{
7162 SCIP_Real efficacy;
7163
7164 efficacy = SCIProwGetSolEfficacy(row, set, stat, sol);
7165
7166 return SCIPsetIsEfficacious(set, root, efficacy);
7167}
7168
7169/** returns row's efficacy with respect to the relaxed solution: e = -feasibility/norm */
7171 SCIP_ROW* row, /**< LP row */
7172 SCIP_SET* set, /**< global SCIP settings */
7173 SCIP_STAT* stat /**< problem statistics data */
7174 )
7175{
7176 SCIP_Real norm;
7177 SCIP_Real feasibility;
7178 SCIP_Real eps;
7179
7180 assert(set != NULL);
7181
7182 switch( set->sepa_efficacynorm )
7183 {
7184 case 'e':
7185 norm = SCIProwGetNorm(row);
7186 break;
7187 case 'm':
7188 norm = SCIProwGetMaxval(row, set);
7189 break;
7190 case 's':
7191 norm = SCIProwGetSumNorm(row);
7192 break;
7193 case 'd':
7194 norm = (row->len == 0 ? 0.0 : 1.0);
7195 break;
7196 default:
7197 SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
7198 SCIPABORT();
7199 norm = 0.0; /*lint !e527*/
7200 }
7201
7203 norm = MAX(norm, eps);
7204 feasibility = SCIProwGetRelaxFeasibility(row, set, stat);
7205
7206 return -feasibility / norm;
7207}
7208
7209/** returns row's efficacy with respect to the NLP solution: e = -feasibility/norm */
7211 SCIP_ROW* row, /**< LP row */
7212 SCIP_SET* set, /**< global SCIP settings */
7213 SCIP_STAT* stat /**< problem statistics data */
7214 )
7215{
7216 SCIP_Real norm;
7217 SCIP_Real feasibility;
7218 SCIP_Real eps;
7219
7220 assert(set != NULL);
7221
7222 switch( set->sepa_efficacynorm )
7223 {
7224 case 'e':
7225 norm = SCIProwGetNorm(row);
7226 break;
7227 case 'm':
7228 norm = SCIProwGetMaxval(row, set);
7229 break;
7230 case 's':
7231 norm = SCIProwGetSumNorm(row);
7232 break;
7233 case 'd':
7234 norm = (row->len == 0 ? 0.0 : 1.0);
7235 break;
7236 default:
7237 SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
7238 SCIPABORT();
7239 norm = 0.0; /*lint !e527*/
7240 }
7241
7243 norm = MAX(norm, eps);
7244 feasibility = SCIProwGetNLPFeasibility(row, set, stat);
7245
7246 return -feasibility / norm;
7247}
7248
7249/** returns the scalar product of the coefficient vectors of the two given rows
7250 *
7251 * @note the scalar product is computed w.r.t. the current LP columns only
7252 * @todo also consider non-LP columns for the computation?
7253 */
7255 SCIP_ROW* row1, /**< first LP row */
7256 SCIP_ROW* row2 /**< second LP row */
7257 )
7258{
7259 SCIP_Real scalarprod;
7260 int* row1colsidx;
7261 int* row2colsidx;
7262 int i1;
7263 int i2;
7264
7265 assert(row1 != NULL);
7266 assert(row2 != NULL);
7267
7268 /* Sort the column indices of both rows.
7269 *
7270 * The columns in a row are divided into two parts: LP columns, which are currently in the LP and non-LP columns;
7271 * we sort the rows, but that only ensures that within these two parts, columns are sorted w.r.t. their index.
7272 * Normally, this should be suficient, because a column contained in both rows should either be one of the LP columns
7273 * for both or one of the non-LP columns for both.
7274 * However, directly after a row was created, before a row is added to the LP, the row is not linked to all its
7275 * columns and all columns are treated as non-LP columns. Moreover, for example when doing column generation,
7276 * columns can be added later and remain unlinked while all previously added columns might already be linked.
7277 * Therefore, we have to be very careful about whether we can rely on the partitioning of the variables.
7278 *
7279 * We distinguish the following cases:
7280 *
7281 * 1) both rows have no unlinked columns
7282 * -> we just check the LP partitions
7283 *
7284 * 2) exactly one row is completely unlinked, the other one is completely linked
7285 * -> we compare the non-LP (unlinked) partition with the LP partition of the other row
7286 * (thus all common LP columns are regarded)
7287 *
7288 * 3) we have unlinked and LP columns in both rows
7289 * -> we need to compare four partitions at once
7290 *
7291 * 4a) we have one row with unlinked and LP columns and the other without any unlinked columns
7292 * -> we need to compare three partitions: the LP part of the completely linked row and both partitions of the
7293 * other row
7294 *
7295 * 4b) we have one row with unlinked and LP columns and the other is completely unlinked
7296 * -> we need to compare three partitions: the complete unlinked row and both partitions of the other row
7297 *
7298 * 5) both rows are completely unlinked
7299 * -> we need to compare two partitions: both complete rows
7300 */
7301 SCIProwSort(row1);
7302 assert(row1->lpcolssorted);
7303 assert(row1->nonlpcolssorted);
7304 SCIProwSort(row2);
7305 assert(row2->lpcolssorted);
7306 assert(row2->nonlpcolssorted);
7307
7308 assert(row1->nunlinked <= row1->len - row1->nlpcols);
7309 assert(row2->nunlinked <= row2->len - row2->nlpcols);
7310
7311 row1colsidx = row1->cols_index;
7312 row2colsidx = row2->cols_index;
7313
7314#ifndef NDEBUG
7315 /* check that we can rely on the partition into LP columns and non-LP columns if the rows are completely linked */
7316 if( row1->nunlinked == 0 && row2->nunlinked == 0 )
7317 {
7318 i1 = 0;
7319 i2 = row2->nlpcols;
7320 while( i1 < row1->nlpcols && i2 < row2->len )
7321 {
7322 assert(row1->cols[i1] != row2->cols[i2]);
7323 if( row1->cols[i1]->index < row2->cols[i2]->index )
7324 ++i1;
7325 else
7326 {
7327 assert(row1->cols[i1]->index > row2->cols[i2]->index);
7328 ++i2;
7329 }
7330 }
7331 assert(i1 == row1->nlpcols || i2 == row2->len);
7332
7333 i1 = row1->nlpcols;
7334 i2 = 0;
7335 while( i1 < row1->len && i2 < row2->nlpcols )
7336 {
7337 assert(row1->cols[i1] != row2->cols[i2]);
7338 if( row1->cols[i1]->index < row2->cols[i2]->index )
7339 ++i1;
7340 else
7341 {
7342 assert(row1->cols[i1]->index > row2->cols[i2]->index);
7343 ++i2;
7344 }
7345 }
7346 assert(i1 == row1->len || i2 == row2->nlpcols);
7347 }
7348#endif
7349
7350 /* The "easy" cases 1) and 2) */
7351 if( (row1->nunlinked == 0 && row2->nunlinked == 0) ||
7352 ((row1->nlpcols == row1->len || row1->nunlinked == row1->len)
7353 && (row2->nlpcols == row2->len || row2->nunlinked == row2->len)
7354 && (row1->nunlinked == 0 || row2->nunlinked == 0)) )
7355 {
7356 assert(row1->nunlinked == 0 || row1->nunlinked == row1->len);
7357 assert(row2->nunlinked == 0 || row2->nunlinked == row2->len);
7358
7359 /* set the iterators to the last column we want to regard in the row: nunlinked is either 0 or row->len,
7360 * therefore, we get nlpcols if nunlinked is 0 and row->len if the row is completely unlinked
7361 */
7362 i1 = MAX(row1->nlpcols, row1->nunlinked) - 1;
7363 i2 = MAX(row2->nlpcols, row2->nunlinked) - 1;
7364 scalarprod = 0.0;
7365
7366 /* calculate the scalar product */
7367 while( i1 >= 0 && i2 >= 0 )
7368 {
7369 assert(row1->cols[i1]->index == row1colsidx[i1]);
7370 assert(row2->cols[i2]->index == row2colsidx[i2]);
7371 assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7372 if( row1colsidx[i1] < row2colsidx[i2] )
7373 --i2;
7374 else if( row1colsidx[i1] > row2colsidx[i2] )
7375 --i1;
7376 else
7377 {
7378 scalarprod += row1->vals[i1] * row2->vals[i2];
7379 --i1;
7380 --i2;
7381 }
7382 }
7383 }
7384 /* the "harder" cases 3) - 5): start with four partitions and reduce their number iteratively */
7385 else
7386 {
7387 SCIP_Bool lpcols;
7388 int ilp1;
7389 int inlp1;
7390 int ilp2;
7391 int inlp2;
7392 int end1;
7393 int end2;
7394
7395 scalarprod = 0;
7396 ilp1 = 0;
7397 ilp2 = 0;
7398
7399 /* if a row is completely linked (case 4a), we do not have to consider its non-LP columns */
7400 inlp1 = (row1->nunlinked > 0 ? row1->nlpcols : row1->len);
7401 inlp2 = (row2->nunlinked > 0 ? row2->nlpcols : row2->len);
7402
7403 /* handle the case of four partitions (case 3) until one partition is finished;
7404 * cases 4a), 4b), and 5) will fail the while-condition
7405 */
7406 while( ilp1 < row1->nlpcols && inlp1 < row1->len && ilp2 < row2->nlpcols && inlp2 < row2->len )
7407 {
7408 assert(row1->cols[ilp1]->index == row1colsidx[ilp1]);
7409 assert(row1->cols[inlp1]->index == row1colsidx[inlp1]);
7410 assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7411 assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7412 assert((row1->cols[ilp1] == row2->cols[ilp2]) == (row1colsidx[ilp1] == row2colsidx[ilp2]));
7413 assert((row1->cols[ilp1] == row2->cols[inlp2]) == (row1colsidx[ilp1] == row2colsidx[inlp2]));
7414 assert((row1->cols[inlp1] == row2->cols[ilp2]) == (row1colsidx[inlp1] == row2colsidx[ilp2]));
7415 assert((row1->cols[inlp1] == row2->cols[inlp2]) == (row1colsidx[inlp1] == row2colsidx[inlp2]));
7416
7417 /* rows have the same linked LP columns */
7418 if( row1colsidx[ilp1] == row2colsidx[ilp2] )
7419 {
7420 scalarprod += row1->vals[ilp1] * row2->vals[ilp2];
7421 ++ilp1;
7422 ++ilp2;
7423 }
7424 /* LP column of row1 is the same as unlinked column of row2 */
7425 else if( row1colsidx[ilp1] == row2colsidx[inlp2] )
7426 {
7427 scalarprod += row1->vals[ilp1] * row2->vals[inlp2];
7428 ++ilp1;
7429 ++inlp2;
7430 }
7431 /* unlinked column of row1 is the same as LP column of row2 */
7432 else if( row1colsidx[inlp1] == row2colsidx[ilp2] )
7433 {
7434 scalarprod += row1->vals[inlp1] * row2->vals[ilp2];
7435 ++inlp1;
7436 ++ilp2;
7437 }
7438 /* two unlinked LP columns are the same */
7439 else if( row1colsidx[inlp1] == row2colsidx[inlp2] && row1->cols[inlp1]->lppos >= 0 )
7440 {
7441 scalarprod += row1->vals[inlp1] * row2->vals[inlp2];
7442 ++inlp1;
7443 ++inlp2;
7444 }
7445 /* increase smallest counter */
7446 else if( row1colsidx[ilp1] < row1colsidx[inlp1] )
7447 {
7448 if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7449 {
7450 if( row1colsidx[ilp1] < row2colsidx[ilp2] )
7451 ++ilp1;
7452 else
7453 ++ilp2;
7454 }
7455 else
7456 {
7457 if( row1colsidx[ilp1] < row2colsidx[inlp2] )
7458 ++ilp1;
7459 else
7460 ++inlp2;
7461 }
7462 }
7463 else
7464 {
7465 if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7466 {
7467 if( row1colsidx[inlp1] < row2colsidx[ilp2] )
7468 ++inlp1;
7469 else
7470 ++ilp2;
7471 }
7472 else
7473 {
7474 if( row1colsidx[inlp1] < row2colsidx[inlp2] )
7475 ++inlp1;
7476 else
7477 ++inlp2;
7478 }
7479 }
7480 }
7481
7482 /* One partition was completely handled, we just have to handle the three remaining partitions:
7483 * the remaining partition of this row and the two partitions of the other row.
7484 * If necessary, we swap the partitions to ensure that row1 is the row with only one remaining partition.
7485 */
7486 if( ilp1 != row1->nlpcols && inlp1 != row1->len )
7487 {
7488 int tmpilp;
7489 int tmpinlp;
7490
7491 assert(ilp2 == row2->nlpcols || inlp2 == row2->len);
7492
7493 SCIPswapPointers((void**) &row1, (void**) &row2);
7494 SCIPswapPointers((void**) &row1colsidx, (void**) &row2colsidx);
7495 tmpilp = ilp1;
7496 tmpinlp = inlp1;
7497 ilp1 = ilp2;
7498 inlp1 = inlp2;
7499 ilp2 = tmpilp;
7500 inlp2 = tmpinlp;
7501 }
7502
7503 /* determine section of row 1 that we want to look at (current iterator = begin, end, LP-columns?)
7504 * -> this merges cases 4a) and 4b)
7505 */
7506 if( ilp1 == row1->nlpcols )
7507 {
7508 i1 = inlp1;
7509 end1 = row1->len;
7510 lpcols = FALSE;
7511 }
7512 else
7513 {
7514 assert(inlp1 == row1->len);
7515
7516 i1 = ilp1;
7517 end1 = row1->nlpcols;
7518 lpcols = TRUE;
7519 }
7520
7521 /* handle the case of three partitions (case 4) until one partition is finished, this reduces our problem to case 1), 2), or 5);
7522 * case 5) will fail the while-condition
7523 */
7524 while( i1 < end1 && ilp2 < row2->nlpcols && inlp2 < row2->len )
7525 {
7526 assert(row1->cols[i1]->index == row1colsidx[i1]);
7527 assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7528 assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7529 assert((row1->cols[i1] == row2->cols[ilp2]) == (row1colsidx[i1] == row2colsidx[ilp2]));
7530 assert((row1->cols[i1] == row2->cols[inlp2]) == (row1colsidx[i1] == row2colsidx[inlp2]));
7531
7532 /* current column in row 1 is the same as the current LP column in row 2 */
7533 if( row1colsidx[i1] == row2colsidx[ilp2] )
7534 {
7535 scalarprod += row1->vals[i1] * row2->vals[ilp2];
7536 ++i1;
7537 ++ilp2;
7538 }
7539 /* linked or unlinked LP column of row1 is the same as unlinked column of row2 */
7540 else if( row1colsidx[i1] == row2colsidx[inlp2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7541 {
7542 scalarprod += row1->vals[i1] * row2->vals[inlp2];
7543 ++i1;
7544 ++inlp2;
7545 }
7546 /* increase smallest counter */
7547 else if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7548 {
7549 if( row1colsidx[i1] < row2colsidx[ilp2] )
7550 ++i1;
7551 else
7552 ++ilp2;
7553 }
7554 else
7555 {
7556 if( row1colsidx[i1] < row2colsidx[inlp2] )
7557 ++i1;
7558 else
7559 ++inlp2;
7560 }
7561 }
7562
7563 /* if the second section of row 1 was finished, we can stop; otherwise, we have to consider the remaining parts of
7564 * the two rows
7565 */
7566 if( i1 < end1 )
7567 {
7568 /* determine section of row 2 that we want to look at (current iterator = begin, end, LP-columns?) */
7569 if( ilp2 == row2->nlpcols )
7570 {
7571 i2 = inlp2;
7572 end2 = row2->len;
7573 lpcols = FALSE;
7574 }
7575 else
7576 {
7577 assert(inlp2 == row2->len);
7578
7579 i2 = ilp2;
7580 end2 = row2->nlpcols;
7581 }
7582
7583 /* handle the case of two partitions (standard case 5, or case 1 or 2 due to partition reduction) */
7584 while( i1 < end1 && i2 < end2 )
7585 {
7586 assert(row1->cols[i1]->index == row1colsidx[i1]);
7587 assert(row2->cols[i2]->index == row2colsidx[i2]);
7588 assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7589
7590 /* linked or unlinked LP column of row1 is the same as linked or unlinked LP column of row2 */
7591 if( row1colsidx[i1] == row2colsidx[i2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7592 {
7593 scalarprod += row1->vals[i1] * row2->vals[i2];
7594 ++i1;
7595 ++i2;
7596 }
7597 /* increase smallest counter */
7598 else if( row1colsidx[i1] < row2colsidx[i2] )
7599 ++i1;
7600 else
7601 ++i2;
7602 }
7603 }
7604 }
7605
7606 return scalarprod;
7607}
7608
7609/** returns the discrete scalar product of the coefficient vectors of the two given rows */
7610static
7612 SCIP_ROW* row1, /**< first LP row */
7613 SCIP_ROW* row2 /**< second LP row */
7614 )
7615{
7616 int prod;
7617 int* row1colsidx;
7618 int* row2colsidx;
7619 int i1;
7620 int i2;
7621
7622 assert(row1 != NULL);
7623 assert(row2 != NULL);
7624
7625 /* Sort the column indices of both rows.
7626 *
7627 * The columns in a row are divided into two parts: LP columns, which are currently in the LP and non-LP columns;
7628 * we sort the rows, but that only ensures that within these two parts, columns are sorted w.r.t. their index.
7629 * Normally, this should be suficient, because a column contained in both rows should either be one of the LP columns
7630 * for both or one of the non-LP columns for both.
7631 * However, directly after a row was created, before a row is added to the LP, the row is not linked to all its
7632 * columns and all columns are treated as non-LP columns. Moreover, for example when doing column generation,
7633 * columns can be added later and remain unlinked while all previously added columns might already be linked.
7634 * Therefore, we have to be very careful about whether we can rely on the partitioning of the variables.
7635 *
7636 * We distinguish the following cases:
7637 *
7638 * 1) both rows have no unlinked columns
7639 * -> we just check the LP partitions
7640 *
7641 * 2) exactly one row is completely unlinked, the other one is completely linked
7642 * -> we compare the non-LP (unlinked) partition with the LP partition of the other row
7643 * (thus all common LP columns are regarded)
7644 *
7645 * 3) we have unlinked and LP columns in both rows
7646 * -> we need to compare four partitions at once
7647 *
7648 * 4a) we have one row with unlinked and LP columns and the other without any unlinked columns
7649 * -> we need to compare three partitions: the LP part of the completely linked row and both partitions of the
7650 * other row
7651 *
7652 * 4b) we have one row with unlinked and LP columns and the other is completely unlinked
7653 * -> we need to compare three partitions: the complete unlinked row and both partitions of the other row
7654 *
7655 * 5) both rows are completely unlinked
7656 * -> we need to compare two partitions: both complete rows
7657 */
7658 SCIProwSort(row1);
7659 assert(row1->lpcolssorted);
7660 assert(row1->nonlpcolssorted);
7661 SCIProwSort(row2);
7662 assert(row2->lpcolssorted);
7663 assert(row2->nonlpcolssorted);
7664
7665 assert(row1->nunlinked <= row1->len - row1->nlpcols);
7666 assert(row2->nunlinked <= row2->len - row2->nlpcols);
7667
7668 row1colsidx = row1->cols_index;
7669 row2colsidx = row2->cols_index;
7670
7671#ifndef NDEBUG
7672 /* check that we can rely on the partition into LP columns and non-LP columns if the rows are completely linked */
7673 if( row1->nunlinked == 0 && row2->nunlinked == 0 )
7674 {
7675 i1 = 0;
7676 i2 = row2->nlpcols;
7677 while( i1 < row1->nlpcols && i2 < row2->len )
7678 {
7679 assert(row1->cols[i1] != row2->cols[i2]);
7680 if( row1->cols[i1]->index < row2->cols[i2]->index )
7681 ++i1;
7682 else
7683 {
7684 assert(row1->cols[i1]->index > row2->cols[i2]->index);
7685 ++i2;
7686 }
7687 }
7688 assert(i1 == row1->nlpcols || i2 == row2->len);
7689
7690 i1 = row1->nlpcols;
7691 i2 = 0;
7692 while( i1 < row1->len && i2 < row2->nlpcols )
7693 {
7694 assert(row1->cols[i1] != row2->cols[i2]);
7695 if( row1->cols[i1]->index < row2->cols[i2]->index )
7696 ++i1;
7697 else
7698 {
7699 assert(row1->cols[i1]->index > row2->cols[i2]->index);
7700 ++i2;
7701 }
7702 }
7703 assert(i1 == row1->len || i2 == row2->nlpcols);
7704 }
7705#endif
7706
7707 /* The "easy" cases 1) and 2) */
7708 if( (row1->nunlinked == 0 && row2->nunlinked == 0) ||
7709 ((row1->nlpcols == row1->len || row1->nunlinked == row1->len)
7710 && (row2->nlpcols == row2->len || row2->nunlinked == row2->len)
7711 && (row1->nunlinked == 0 || row2->nunlinked == 0)) )
7712 {
7713 assert(row1->nunlinked == 0 || row1->nunlinked == row1->len);
7714 assert(row2->nunlinked == 0 || row2->nunlinked == row2->len);
7715
7716 /* set the iterators to the last column we want to regard in the row: nunlinked is either 0 or row->len,
7717 * therefore, we get nlpcols if nunlinked is 0 and row->len if the row is completely unlinked
7718 */
7719 i1 = MAX(row1->nlpcols, row1->nunlinked) - 1;
7720 i2 = MAX(row2->nlpcols, row2->nunlinked) - 1;
7721 prod = 0;
7722
7723 /* calculate the scalar product */
7724 while( i1 >= 0 && i2 >= 0 )
7725 {
7726 assert(row1->cols[i1]->index == row1colsidx[i1]);
7727 assert(row2->cols[i2]->index == row2colsidx[i2]);
7728 assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7729 if( row1colsidx[i1] < row2colsidx[i2] )
7730 --i2;
7731 else if( row1colsidx[i1] > row2colsidx[i2] )
7732 --i1;
7733 else
7734 {
7735 ++prod;
7736 --i1;
7737 --i2;
7738 }
7739 }
7740 }
7741 /* the "harder" cases 3) - 5): start with four partitions and reduce their number iteratively */
7742 else
7743 {
7744 SCIP_Bool lpcols;
7745 int ilp1;
7746 int inlp1;
7747 int ilp2;
7748 int inlp2;
7749 int end1;
7750 int end2;
7751
7752 prod = 0;
7753 ilp1 = 0;
7754 ilp2 = 0;
7755
7756 /* if a row is completely linked (case 4a), we do not have to consider its non-LP columns */
7757 inlp1 = (row1->nunlinked > 0 ? row1->nlpcols : row1->len);
7758 inlp2 = (row2->nunlinked > 0 ? row2->nlpcols : row2->len);
7759
7760 /* handle the case of four partitions (case 3) until one partition is finished;
7761 * cases 4a), 4b), and 5) will fail the while-condition
7762 */
7763 while( ilp1 < row1->nlpcols && inlp1 < row1->len && ilp2 < row2->nlpcols && inlp2 < row2->len )
7764 {
7765 assert(row1->cols[ilp1]->index == row1colsidx[ilp1]);
7766 assert(row1->cols[inlp1]->index == row1colsidx[inlp1]);
7767 assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7768 assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7769 assert((row1->cols[ilp1] == row2->cols[ilp2]) == (row1colsidx[ilp1] == row2colsidx[ilp2]));
7770 assert((row1->cols[ilp1] == row2->cols[inlp2]) == (row1colsidx[ilp1] == row2colsidx[inlp2]));
7771 assert((row1->cols[inlp1] == row2->cols[ilp2]) == (row1colsidx[inlp1] == row2colsidx[ilp2]));
7772 assert((row1->cols[inlp1] == row2->cols[inlp2]) == (row1colsidx[inlp1] == row2colsidx[inlp2]));
7773
7774 /* rows have the same linked LP columns */
7775 if( row1colsidx[ilp1] == row2colsidx[ilp2] )
7776 {
7777 ++prod;
7778 ++ilp1;
7779 ++ilp2;
7780 }
7781 /* LP column of row1 is the same as unlinked column of row2 */
7782 else if( row1colsidx[ilp1] == row2colsidx[inlp2] )
7783 {
7784 ++prod;
7785 ++ilp1;
7786 ++inlp2;
7787 }
7788 /* unlinked column of row1 is the same as LP column of row2 */
7789 else if( row1colsidx[inlp1] == row2colsidx[ilp2] )
7790 {
7791 ++prod;
7792 ++inlp1;
7793 ++ilp2;
7794 }
7795 /* two unlinked LP columns are the same */
7796 else if( row1colsidx[inlp1] == row2colsidx[inlp2] && row1->cols[inlp1]->lppos >= 0 )
7797 {
7798 ++prod;
7799 ++inlp1;
7800 ++inlp2;
7801 }
7802 /* increase smallest counter */
7803 else if( row1colsidx[ilp1] < row1colsidx[inlp1] )
7804 {
7805 if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7806 {
7807 if( row1colsidx[ilp1] < row2colsidx[ilp2] )
7808 ++ilp1;
7809 else
7810 ++ilp2;
7811 }
7812 else
7813 {
7814 if( row1colsidx[ilp1] < row2colsidx[inlp2] )
7815 ++ilp1;
7816 else
7817 ++inlp2;
7818 }
7819 }
7820 else
7821 {
7822 if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7823 {
7824 if( row1colsidx[inlp1] < row2colsidx[ilp2] )
7825 ++inlp1;
7826 else
7827 ++ilp2;
7828 }
7829 else
7830 {
7831 if( row1colsidx[inlp1] < row2colsidx[inlp2] )
7832 ++inlp1;
7833 else
7834 ++inlp2;
7835 }
7836 }
7837 }
7838
7839 /* One partition was completely handled, we just have to handle the three remaining partitions:
7840 * the remaining partition of this row and the two partitions of the other row.
7841 * If necessary, we swap the partitions to ensure that row1 is the row with only one remaining partition.
7842 */
7843 if( ilp1 != row1->nlpcols && inlp1 != row1->len )
7844 {
7845 int tmpilp;
7846 int tmpinlp;
7847
7848 assert(ilp2 == row2->nlpcols || inlp2 == row2->len);
7849
7850 SCIPswapPointers((void**) &row1, (void**) &row2);
7851 SCIPswapPointers((void**) &row1colsidx, (void**) &row2colsidx);
7852 tmpilp = ilp1;
7853 tmpinlp = inlp1;
7854 ilp1 = ilp2;
7855 inlp1 = inlp2;
7856 ilp2 = tmpilp;
7857 inlp2 = tmpinlp;
7858 }
7859
7860 /* determine section of row 1 that we want to look at (current iterator = begin, end, LP-columns?)
7861 * -> this merges cases 4a) and 4b)
7862 */
7863 if( ilp1 == row1->nlpcols )
7864 {
7865 i1 = inlp1;
7866 end1 = row1->len;
7867 lpcols = FALSE;
7868 }
7869 else
7870 {
7871 assert(inlp1 == row1->len);
7872
7873 i1 = ilp1;
7874 end1 = row1->nlpcols;
7875 lpcols = TRUE;
7876 }
7877
7878 /* handle the case of three partitions (case 4) until one partition is finished, this reduces our problem to case 1), 2), or 5);
7879 * case 5) will fail the while-condition
7880 */
7881 while( i1 < end1 && ilp2 < row2->nlpcols && inlp2 < row2->len )
7882 {
7883 assert(row1->cols[i1]->index == row1colsidx[i1]);
7884 assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7885 assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7886 assert((row1->cols[i1] == row2->cols[ilp2]) == (row1colsidx[i1] == row2colsidx[ilp2]));
7887 assert((row1->cols[i1] == row2->cols[inlp2]) == (row1colsidx[i1] == row2colsidx[inlp2]));
7888
7889 /* current column in row 1 is the same as the current LP column in row 2 */
7890 if( row1colsidx[i1] == row2colsidx[ilp2] )
7891 {
7892 ++prod;
7893 ++i1;
7894 ++ilp2;
7895 }
7896 /* linked or unlinked LP column of row1 is the same as unlinked column of row2 */
7897 else if( row1colsidx[i1] == row2colsidx[inlp2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7898 {
7899 ++prod;
7900 ++i1;
7901 ++inlp2;
7902 }
7903 /* increase smallest counter */
7904 else if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7905 {
7906 if( row1colsidx[i1] < row2colsidx[ilp2] )
7907 ++i1;
7908 else
7909 ++ilp2;
7910 }
7911 else
7912 {
7913 if( row1colsidx[i1] < row2colsidx[inlp2] )
7914 ++i1;
7915 else
7916 ++inlp2;
7917 }
7918 }
7919
7920 /* if the second section of row 1 was finished, we can stop; otherwise, we have to consider the remaining parts of
7921 * the two rows
7922 */
7923 if( i1 < end1 )
7924 {
7925 /* determine section of row 2 that we want to look at (current iterator = begin, end, LP-columns?) */
7926 if( ilp2 == row2->nlpcols )
7927 {
7928 i2 = inlp2;
7929 end2 = row2->len;
7930 lpcols = FALSE;
7931 }
7932 else
7933 {
7934 assert(inlp2 == row2->len);
7935
7936 i2 = ilp2;
7937 end2 = row2->nlpcols;
7938 }
7939
7940 /* handle the case of two partitions (standard case 5, or case 1 or 2 due to partition reduction) */
7941 while( i1 < end1 && i2 < end2 )
7942 {
7943 assert(row1->cols[i1]->index == row1colsidx[i1]);
7944 assert(row2->cols[i2]->index == row2colsidx[i2]);
7945 assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7946
7947 /* linked or unlinked LP column of row1 is the same as linked or unlinked LP column of row2 */
7948 if( row1colsidx[i1] == row2colsidx[i2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7949 {
7950 ++prod;
7951 ++i1;
7952 ++i2;
7953 }
7954 /* increase smallest counter */
7955 else if( row1colsidx[i1] < row2colsidx[i2] )
7956 ++i1;
7957 else
7958 ++i2;
7959 }
7960 }
7961 }
7962
7963 return prod;
7964}
7965
7966/** returns the degree of parallelism between the hyperplanes defined by the two row vectors v, w:
7967 * p = |v*w|/(|v|*|w|);
7968 * the hyperplanes are parallel, iff p = 1, they are orthogonal, iff p = 0
7969 */
7971 SCIP_ROW* row1, /**< first LP row */
7972 SCIP_ROW* row2, /**< second LP row */
7973 char orthofunc /**< function used for calc. scalar prod. ('e'uclidean, 'd'iscrete) */
7974 )
7975{
7976 SCIP_Real parallelism;
7977 SCIP_Real scalarprod;
7978
7979 switch( orthofunc )
7980 {
7981 case 'e':
7982 scalarprod = SCIProwGetScalarProduct(row1, row2);
7983 if( scalarprod == 0.0 )
7984 {
7985 parallelism = 0.0;
7986 break;
7987 }
7988
7989 if( SCIProwGetNorm(row1) == 0.0 )
7990 {
7991 /* In theory, this should not happen if the scalarproduct is not zero
7992 * But due to bug 520 (also issue 44), it is possible that norms are not correct.
7993 * Thus, if the norm is so bad that it is even 0, then reevaluate it here.
7994 * But as we don't have set available here, we cannot call rowCalcNorms, so do it by hand.
7995 */
7996 int i;
7997 for( i = 0; i < row1->len; ++i )
7998 if( row1->cols[i]->lppos >= 0 )
7999 row1->sqrnorm += SQR(row1->vals[i]);
8000 assert(SCIProwGetNorm(row1) != 0.0);
8001 }
8002
8003 if( SCIProwGetNorm(row2) == 0.0 )
8004 {
8005 /* same as for row1 above: reeval norms if it is 0, which is wrong */
8006 int i;
8007 for( i = 0; i < row2->len; ++i )
8008 if( row2->cols[i]->lppos >= 0 )
8009 row2->sqrnorm += SQR(row2->vals[i]);
8010 assert(SCIProwGetNorm(row2) != 0.0);
8011 }
8012
8013 parallelism = REALABS(scalarprod) / (SCIProwGetNorm(row1) * SCIProwGetNorm(row2));
8014 break;
8015
8016 case 'd':
8017 scalarprod = (SCIP_Real) SCIProwGetDiscreteScalarProduct(row1, row2);
8018 parallelism = scalarprod / (sqrt((SCIP_Real) SCIProwGetNNonz(row1)) * sqrt((SCIP_Real) SCIProwGetNNonz(row2)));
8019 break;
8020
8021 default:
8022 SCIPerrorMessage("invalid orthogonality function parameter '%c'\n", orthofunc);
8023 SCIPABORT();
8024 parallelism = 0.0; /*lint !e527*/
8025 }
8026
8027 return parallelism;
8028}
8029
8030/** returns the degree of orthogonality between the hyperplanes defined by the two row vectors v, w:
8031 * o = 1 - |v*w|/(|v|*|w|);
8032 * the hyperplanes are orthogonal, iff p = 1, they are parallel, iff p = 0
8033 */
8035 SCIP_ROW* row1, /**< first LP row */
8036 SCIP_ROW* row2, /**< second LP row */
8037 char orthofunc /**< function used for calc. scalar prod. ('e'uclidean, 'd'iscrete) */
8038 )
8039{
8040 return 1.0 - SCIProwGetParallelism(row1, row2, orthofunc);
8041}
8042
8043/** gets parallelism of row with objective function: if the returned value is 1, the row is parallel to the objective
8044 * function, if the value is 0, it is orthogonal to the objective function
8045 */
8047 SCIP_ROW* row, /**< LP row */
8048 SCIP_SET* set, /**< global SCIP settings */
8049 SCIP_LP* lp /**< current LP data */
8050 )
8051{
8052 SCIP_Real prod;
8053 SCIP_Real parallelism;
8054
8055 assert(row != NULL);
8056 assert(lp != NULL);
8057
8058 if( lp->objsqrnormunreliable )
8060
8062 assert(lp->objsqrnorm >= 0.0);
8063
8064 checkRowSqrnorm(row);
8065 checkRowObjprod(row);
8066
8067 prod = row->sqrnorm * lp->objsqrnorm;
8068
8069 parallelism = SCIPsetIsPositive(set, prod) ? REALABS(row->objprod) / sqrt(prod) : 0.0;
8070 assert(SCIPsetIsSumGE(set, parallelism, 0.0));
8071 assert(SCIPsetIsSumLE(set, parallelism, 1.0));
8072 parallelism = MIN(parallelism, 1.0);
8073 parallelism = MAX(parallelism, 0.0);
8074
8075 return parallelism;
8076}
8077
8078/** includes event handler with given data in row's event filter */
8080 SCIP_ROW* row, /**< row */
8081 BMS_BLKMEM* blkmem, /**< block memory */
8082 SCIP_SET* set, /**< global SCIP settings */
8083 SCIP_EVENTTYPE eventtype, /**< event type to catch */
8084 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
8085 SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler for the event processing */
8086 int* filterpos /**< pointer to store position of event filter entry, or NULL */
8087 )
8088{
8089 assert(row != NULL);
8090 assert(row->eventfilter != NULL);
8091 assert((eventtype & ~SCIP_EVENTTYPE_ROWCHANGED) == 0);
8092 assert((eventtype & SCIP_EVENTTYPE_ROWCHANGED) != 0);
8093
8094 SCIPsetDebugMsg(set, "catch event of type 0x%" SCIP_EVENTTYPE_FORMAT " of row <%s> with handler %p and data %p\n",
8095 eventtype, row->name, (void*)eventhdlr, (void*)eventdata);
8096
8097 SCIP_CALL( SCIPeventfilterAdd(row->eventfilter, blkmem, set, eventtype, eventhdlr, eventdata, filterpos) );
8098
8099 return SCIP_OKAY;
8100}
8101
8102/** deletes event handler with given data from row's event filter */
8104 SCIP_ROW* row, /**< row */
8105 BMS_BLKMEM* blkmem, /**< block memory */
8106 SCIP_SET* set, /**< global SCIP settings */
8107 SCIP_EVENTTYPE eventtype, /**< event type mask of dropped event */
8108 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
8109 SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler for the event processing */
8110 int filterpos /**< position of event filter entry returned by SCIPvarCatchEvent(), or -1 */
8111 )
8112{
8113 assert(row != NULL);
8114 assert(row->eventfilter != NULL);
8115
8116 SCIPsetDebugMsg(set, "drop event of row <%s> with handler %p and data %p\n", row->name, (void*)eventhdlr, (void*)eventdata);
8117
8118 SCIP_CALL( SCIPeventfilterDel(row->eventfilter, blkmem, set, eventtype, eventhdlr, eventdata, filterpos) );
8119
8120 return SCIP_OKAY;
8121}
8122
8123/** marks a row to be not removable from the LP in the current node because it became obsolete */
8125 SCIP_ROW* row, /**< LP row */
8126 SCIP_STAT* stat /**< problem statistics */
8127 )
8128{
8129 assert(row != NULL);
8130 assert(stat != NULL);
8131 assert(stat->nnodes > 0);
8132
8133 /* lpRemoveObsoleteRows() does not remove a row if the node number stored in obsoletenode equals the current node number */
8134 row->obsoletenode = stat->nnodes;
8135}
8136
8137/*
8138 * LP solver data update
8139 */
8140
8141/** resets column data to represent a column not in the LP solver */
8142static
8144 SCIP_COL* col /**< column to be marked deleted */
8145 )
8146{
8147 assert(col != NULL);
8148
8149 col->lpipos = -1;
8150 col->primsol = 0.0;
8151 col->redcost = SCIP_INVALID;
8152 col->farkascoef = SCIP_INVALID;
8153 col->sbdown = SCIP_INVALID;
8154 col->sbup = SCIP_INVALID;
8155 col->sbdownvalid = FALSE;
8156 col->sbupvalid = FALSE;
8157 col->validredcostlp = -1;
8158 col->validfarkaslp = -1;
8159 col->sbitlim = -1;
8160 col->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
8161}
8162
8163/** applies all cached column removals to the LP solver */
8164static
8166 SCIP_LP* lp /**< current LP data */
8167 )
8168{
8169 assert(lp != NULL);
8170 assert(lp->lpifirstchgcol <= lp->nlpicols);
8171 assert(lp->lpifirstchgcol <= lp->ncols);
8172
8173 /* find the first column to change */
8174 while( lp->lpifirstchgcol < lp->nlpicols
8175 && lp->lpifirstchgcol < lp->ncols
8176 && lp->cols[lp->lpifirstchgcol]->lpipos == lp->lpifirstchgcol
8177 && !lp->cols[lp->lpifirstchgcol]->coefchanged )
8178 {
8179 assert(lp->cols[lp->lpifirstchgcol] == lp->lpicols[lp->lpifirstchgcol]);
8180 lp->lpifirstchgcol++;
8181 }
8182
8183 /* shrink LP to the part which didn't change */
8184 if( lp->lpifirstchgcol < lp->nlpicols )
8185 {
8186 int i;
8187
8188 assert(!lp->diving);
8189 SCIPdebugMessage("flushing col deletions: shrink LP from %d to %d columns\n", lp->nlpicols, lp->lpifirstchgcol);
8191 for( i = lp->lpifirstchgcol; i < lp->nlpicols; ++i )
8192 {
8193 markColDeleted(lp->lpicols[i]);
8194 }
8195 lp->nlpicols = lp->lpifirstchgcol;
8196 lp->flushdeletedcols = TRUE;
8197 lp->updateintegrality = TRUE;
8198
8199 /* mark the LP unsolved */
8200 lp->solved = FALSE;
8201 lp->primalfeasible = FALSE;
8202 lp->primalchecked = FALSE;
8203 lp->lpobjval = SCIP_INVALID;
8205 }
8206 assert(lp->nlpicols == lp->lpifirstchgcol);
8207
8208 return SCIP_OKAY;
8209}
8210
8211/** computes for the given column the lower and upper bound that should be flushed into the LP
8212 * depending on lazy bounds and diving mode; in diving mode, lazy bounds are ignored, i.e.,
8213 * the bounds are explicitly added to the LP in any case
8214 */
8215static
8217 SCIP_LP* lp, /**< current LP data */
8218 SCIP_SET* set, /**< global SCIP settings */
8219 SCIP_COL* col, /**< column to compute bounds for */
8220 SCIP_Real lpiinf, /**< infinity value if the LP solver */
8221 SCIP_Real* lb, /**< pointer to store the new lower bound */
8222 SCIP_Real* ub /**< pointer to store the new upper bound */
8223 )
8224{
8225 assert(lp != NULL);
8226 assert(set != NULL);
8227 assert(col != NULL);
8228 assert(lb != NULL);
8229 assert(ub != NULL);
8230
8231 /* get the correct new lower bound:
8232 * if lazy lower bound exists and is larger than lower bound, set lower bound to infinity;
8233 * if we are in diving mode, ignore lazy bounds and always take the lower bound
8234 */
8235 if( SCIPsetIsInfinity(set, -col->lb) || (SCIPsetIsLE(set, col->lb, col->lazylb) && !SCIPlpDiving(lp)) )
8236 (*lb) = -lpiinf;
8237 else
8238 (*lb) = col->lb;
8239 /* get the correct new upper bound:
8240 * if lazy upper bound exists and is larger than upper bound, set upper bound to infinity;
8241 * if we are in diving mode, ignore lazy bounds and always take the upper bound
8242 */
8243 if( SCIPsetIsInfinity(set, col->ub) || (SCIPsetIsGE(set, col->ub, col->lazyub) && !SCIPlpDiving(lp)) )
8244 (*ub) = lpiinf;
8245 else
8246 (*ub) = col->ub;
8247}
8248
8249/** applies all cached column additions to the LP solver */
8250static
8252 SCIP_LP* lp, /**< current LP data */
8253 BMS_BLKMEM* blkmem, /**< block memory */
8254 SCIP_SET* set, /**< global SCIP settings */
8255 SCIP_EVENTQUEUE* eventqueue /**< event queue */
8256 )
8257{
8258 SCIP_Real* obj;
8259 SCIP_Real* lb;
8260 SCIP_Real* ub;
8261 int* beg;
8262 int* ind;
8263 SCIP_Real* val;
8264 char** name;
8265 SCIP_COL* col;
8266 SCIP_Real lpiinf;
8267 int c;
8268 int pos;
8269 int nnonz;
8270 int naddcols;
8271 int naddcoefs;
8272 int i;
8273 int lpipos;
8274
8275 assert(lp != NULL);
8276 assert(lp->lpifirstchgcol == lp->nlpicols);
8277 assert(blkmem != NULL);
8278 assert(set != NULL);
8279
8280 /* if there are no columns to add, we are ready */
8281 if( lp->ncols == lp->nlpicols )
8282 return SCIP_OKAY;
8283
8284 /* add the additional columns */
8285 assert(!lp->diving);
8286 assert(lp->ncols > lp->nlpicols);
8287 SCIP_CALL( ensureLpicolsSize(lp, set, lp->ncols) );
8288
8289 /* get the solver's infinity value */
8290 lpiinf = SCIPlpiInfinity(lp->lpi);
8291
8292 /* count the (maximal) number of added coefficients, calculate the number of added columns */
8293 naddcols = lp->ncols - lp->nlpicols;
8294 naddcoefs = 0;
8295 for( c = lp->nlpicols; c < lp->ncols; ++c )
8296 naddcoefs += lp->cols[c]->len;
8297 assert(naddcols > 0);
8298
8299 /* get temporary memory for changes */
8300 SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, naddcols) );
8301 SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, naddcols) );
8302 SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, naddcols) );
8303 SCIP_CALL( SCIPsetAllocBufferArray(set, &beg, naddcols) );
8304 SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, naddcoefs) );
8305 SCIP_CALL( SCIPsetAllocBufferArray(set, &val, naddcoefs) );
8306 SCIP_CALL( SCIPsetAllocBufferArray(set, &name, naddcols) );
8307
8308 /* fill temporary memory with column data */
8309 nnonz = 0;
8310 for( pos = 0, c = lp->nlpicols; c < lp->ncols; ++pos, ++c )
8311 {
8312 col = lp->cols[c];
8313 assert(col != NULL);
8314 assert(col->var != NULL);
8316 assert(SCIPvarGetCol(col->var) == col);
8317 assert(col->lppos == c);
8318 assert(nnonz + col->nlprows <= naddcoefs);
8319
8320 SCIPsetDebugMsg(set, "flushing added column <%s>: ", SCIPvarGetName(col->var));
8321 debugColPrint(set, col);
8322
8323 /* Because the column becomes a member of the LP solver, it now can take values
8324 * different from zero. That means, we have to include the column in the corresponding
8325 * row vectors.
8326 */
8327 SCIP_CALL( colLink(col, blkmem, set, eventqueue, lp) );
8328
8329 lp->lpicols[c] = col;
8330 col->lpipos = c;
8331 col->primsol = SCIP_INVALID;
8332 col->redcost = SCIP_INVALID;
8333 col->farkascoef = SCIP_INVALID;
8334 col->sbdown = SCIP_INVALID;
8335 col->sbup = SCIP_INVALID;
8336 col->sbdownvalid = FALSE;
8337 col->sbupvalid = FALSE;
8338 col->validredcostlp = -1;
8339 col->validfarkaslp = -1;
8340 col->sbitlim = -1;
8341 col->objchanged = FALSE;
8342 col->lbchanged = FALSE;
8343 col->ubchanged = FALSE;
8344 col->coefchanged = FALSE;
8345 obj[pos] = col->obj;
8346
8347 /* compute bounds that should be flushed into the LP (taking into account lazy bounds) */
8348 computeLPBounds(lp, set, col, lpiinf, &(lb[pos]), &(ub[pos]));
8349
8350 beg[pos] = nnonz;
8351 name[pos] = (char*)SCIPvarGetName(col->var);
8352
8353 col->flushedobj = obj[pos];
8354 col->flushedlb = lb[pos];
8355 col->flushedub = ub[pos];
8356
8357 for( i = 0; i < col->nlprows; ++i )
8358 {
8359 assert(col->rows[i] != NULL);
8360 lpipos = col->rows[i]->lpipos;
8361 if( lpipos >= 0 )
8362 {
8363 assert(lpipos < lp->nrows);
8364 assert(nnonz < naddcoefs);
8365 ind[nnonz] = lpipos;
8366 val[nnonz] = col->vals[i];
8367 nnonz++;
8368 }
8369 }
8370#ifndef NDEBUG
8371 for( i = col->nlprows; i < col->len; ++i )
8372 {
8373 assert(col->rows[i] != NULL);
8374 assert(col->rows[i]->lpipos == -1); /* because the row deletions are already performed */
8375 }
8376#endif
8377 }
8378
8379 /* call LP interface */
8380 SCIPsetDebugMsg(set, "flushing col additions: enlarge LP from %d to %d columns\n", lp->nlpicols, lp->ncols);
8381 SCIP_CALL( SCIPlpiAddCols(lp->lpi, naddcols, obj, lb, ub, name, nnonz, beg, ind, val) );
8382 lp->nlpicols = lp->ncols;
8383 lp->lpifirstchgcol = lp->nlpicols;
8384
8385 /* free temporary memory */
8393
8394 lp->flushaddedcols = TRUE;
8395 lp->updateintegrality = TRUE;
8396
8397 /* mark the LP unsolved */
8398 lp->solved = FALSE;
8399 lp->dualfeasible = FALSE;
8400 lp->dualchecked = FALSE;
8401 lp->lpobjval = SCIP_INVALID;
8403
8404 return SCIP_OKAY;
8405}
8406
8407/** resets row data to represent a row not in the LP solver */
8408static
8410 SCIP_ROW* row /**< row to be marked deleted */
8411 )
8412{
8413 assert(row != NULL);
8414
8415 row->lpipos = -1;
8416 row->dualsol = 0.0;
8417 row->activity = SCIP_INVALID;
8418 row->dualfarkas = 0.0;
8419 row->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
8420 row->validactivitylp = -1;
8421}
8422
8423/** applies all cached row removals to the LP solver */
8424static
8426 SCIP_LP* lp, /**< current LP data */
8427 BMS_BLKMEM* blkmem, /**< block memory */
8428 SCIP_SET* set /**< global SCIP settings */
8429 )
8430{
8431 assert(lp != NULL);
8432 assert(lp->lpifirstchgrow <= lp->nlpirows);
8433 assert(lp->lpifirstchgrow <= lp->nrows);
8434
8435 /* find the first row to change */
8436 while( lp->lpifirstchgrow < lp->nlpirows
8437 && lp->lpifirstchgrow < lp->nrows
8438 && lp->rows[lp->lpifirstchgrow]->lpipos == lp->lpifirstchgrow
8439 && !lp->rows[lp->lpifirstchgrow]->coefchanged )
8440 {
8441 assert(lp->rows[lp->lpifirstchgrow] == lp->lpirows[lp->lpifirstchgrow]);
8442 lp->lpifirstchgrow++;
8443 }
8444
8445 /* shrink LP to the part which didn't change */
8446 if( lp->lpifirstchgrow < lp->nlpirows )
8447 {
8448 int i;
8449
8450 SCIPsetDebugMsg(set, "flushing row deletions: shrink LP from %d to %d rows\n", lp->nlpirows, lp->lpifirstchgrow);
8452 for( i = lp->lpifirstchgrow; i < lp->nlpirows; ++i )
8453 {
8454 markRowDeleted(lp->lpirows[i]);
8455 SCIP_CALL( SCIProwRelease(&lp->lpirows[i], blkmem, set, lp) );
8456 }
8457 lp->nlpirows = lp->lpifirstchgrow;
8458 lp->flushdeletedrows = TRUE;
8459
8460 /* mark the LP unsolved */
8461 lp->solved = FALSE;
8462 lp->dualfeasible = FALSE;
8463 lp->dualchecked = FALSE;
8464 lp->lpobjval = SCIP_INVALID;
8466 }
8467 assert(lp->nlpirows == lp->lpifirstchgrow);
8468
8469 return SCIP_OKAY;
8470}
8471
8472/** applies all cached row additions and removals to the LP solver */
8473static
8475 SCIP_LP* lp, /**< current LP data */
8476 BMS_BLKMEM* blkmem, /**< block memory */
8477 SCIP_SET* set, /**< global SCIP settings */
8478 SCIP_EVENTQUEUE* eventqueue /**< event queue */
8479 )
8480{
8481 SCIP_Real* lhs;
8482 SCIP_Real* rhs;
8483 int* beg;
8484 int* ind;
8485 SCIP_Real* val;
8486 char** name;
8487 SCIP_ROW* row;
8488 SCIP_Real lpiinf;
8489 int r;
8490 int pos;
8491 int nnonz;
8492 int naddrows;
8493 int naddcoefs;
8494 int i;
8495 int lpipos;
8496
8497 assert(lp != NULL);
8498 assert(lp->lpifirstchgrow == lp->nlpirows);
8499 assert(blkmem != NULL);
8500
8501 /* if there are no rows to add, we are ready */
8502 if( lp->nrows == lp->nlpirows )
8503 return SCIP_OKAY;
8504
8505 /* add the additional rows */
8506 assert(lp->nrows > lp->nlpirows);
8507 SCIP_CALL( ensureLpirowsSize(lp, set, lp->nrows) );
8508
8509 /* get the solver's infinity value */
8510 lpiinf = SCIPlpiInfinity(lp->lpi);
8511
8512 /* count the (maximal) number of added coefficients, calculate the number of added rows */
8513 naddrows = lp->nrows - lp->nlpirows;
8514 naddcoefs = 0;
8515 for( r = lp->nlpirows; r < lp->nrows; ++r )
8516 naddcoefs += lp->rows[r]->len;
8517 assert(naddrows > 0);
8518
8519 /* get temporary memory for changes */
8520 SCIP_CALL( SCIPsetAllocBufferArray(set, &lhs, naddrows) );
8521 SCIP_CALL( SCIPsetAllocBufferArray(set, &rhs, naddrows) );
8522 SCIP_CALL( SCIPsetAllocBufferArray(set, &beg, naddrows) );
8523 SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, naddcoefs) );
8524 SCIP_CALL( SCIPsetAllocBufferArray(set, &val, naddcoefs) );
8525 SCIP_CALL( SCIPsetAllocBufferArray(set, &name, naddrows) );
8526
8527 /* fill temporary memory with row data */
8528 nnonz = 0;
8529 for( pos = 0, r = lp->nlpirows; r < lp->nrows; ++pos, ++r )
8530 {
8531 row = lp->rows[r];
8532 assert(row != NULL);
8533 assert(row->lppos == r);
8534 assert(nnonz + row->nlpcols <= naddcoefs);
8535
8536 SCIPsetDebugMsg(set, "flushing added row <%s>: ", row->name);
8537 debugRowPrint(set, row);
8538
8539 /* Because the row becomes a member of the LP solver, its dual variable now can take values
8540 * different from zero. That means, we have to include the row in the corresponding
8541 * column vectors.
8542 */
8543 SCIP_CALL( rowLink(row, blkmem, set, eventqueue, lp) );
8544
8545 SCIProwCapture(row);
8546 lp->lpirows[r] = row;
8547 row->lpipos = r;
8548 row->dualsol = SCIP_INVALID;
8549 row->activity = SCIP_INVALID;
8550 row->dualfarkas = SCIP_INVALID;
8551 row->validactivitylp = -1;
8552 row->lhschanged = FALSE;
8553 row->rhschanged = FALSE;
8554 row->coefchanged = FALSE;
8555 if( SCIPsetIsInfinity(set, -row->lhs) )
8556 lhs[pos] = -lpiinf;
8557 else
8558 lhs[pos] = row->lhs - row->constant;
8559 if( SCIPsetIsInfinity(set, row->rhs) )
8560 rhs[pos] = lpiinf;
8561 else
8562 rhs[pos] = row->rhs - row->constant;
8563 beg[pos] = nnonz;
8564 name[pos] = row->name;
8565
8566 row->flushedlhs = lhs[pos];
8567 row->flushedrhs = rhs[pos];
8568
8569 SCIPsetDebugMsg(set, "flushing added row (SCIP_LPI): %+g <=", lhs[pos]);
8570 for( i = 0; i < row->nlpcols; ++i )
8571 {
8572 assert(row->cols[i] != NULL);
8573 lpipos = row->cols[i]->lpipos;
8574 if( lpipos >= 0 )
8575 {
8576 assert(lpipos < lp->ncols);
8577 assert(nnonz < naddcoefs);
8578 SCIPsetDebugMsgPrint(set, " %+gx%d(<%s>)", row->vals[i], lpipos+1, SCIPvarGetName(row->cols[i]->var));
8579 ind[nnonz] = lpipos;
8580 val[nnonz] = row->vals[i];
8581 nnonz++;
8582 }
8583 }
8584 SCIPsetDebugMsgPrint(set, " <= %+g\n", rhs[pos]);
8585#ifndef NDEBUG
8586 for( i = row->nlpcols; i < row->len; ++i )
8587 {
8588 assert(row->cols[i] != NULL);
8589 assert(row->cols[i]->lpipos == -1); /* because the column deletions are already performed */
8590 }
8591#endif
8592 }
8593
8594 /* call LP interface */
8595 SCIPsetDebugMsg(set, "flushing row additions: enlarge LP from %d to %d rows\n", lp->nlpirows, lp->nrows);
8596 SCIP_CALL( SCIPlpiAddRows(lp->lpi, naddrows, lhs, rhs, name, nnonz, beg, ind, val) );
8597 lp->nlpirows = lp->nrows;
8598 lp->lpifirstchgrow = lp->nlpirows;
8599
8600 /* free temporary memory */
8607
8608 lp->flushaddedrows = TRUE;
8609
8610 /* mark the LP unsolved */
8611 lp->solved = FALSE;
8612 lp->primalfeasible = FALSE;
8613 lp->primalchecked = FALSE;
8614 lp->lpobjval = SCIP_INVALID;
8616
8617 return SCIP_OKAY;
8618}
8619
8620/** applies all cached column bound and objective changes to the LP */
8621static
8623 SCIP_LP* lp, /**< current LP data */
8624 SCIP_SET* set /**< global SCIP settings */
8625 )
8626{
8627#ifndef NDEBUG
8628 SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
8629#endif
8630 SCIP_COL* col;
8631 int* objind;
8632 int* bdind;
8633 SCIP_Real* obj;
8634 SCIP_Real* lb;
8635 SCIP_Real* ub;
8636 SCIP_Real lpiinf;
8637 int nobjchg;
8638 int nbdchg;
8639 int i;
8640
8641 assert(lp != NULL);
8642
8643 if( lp->nchgcols == 0 )
8644 return SCIP_OKAY;
8645
8646 /* get the solver's infinity value */
8647 lpiinf = SCIPlpiInfinity(lp->lpi);
8648
8649 /* get temporary memory for changes */
8650 SCIP_CALL( SCIPsetAllocBufferArray(set, &objind, lp->ncols) );
8652 SCIP_CALL( SCIPsetAllocBufferArray(set, &bdind, lp->ncols) );
8655
8656 /* collect all cached bound and objective changes */
8657 nobjchg = 0;
8658 nbdchg = 0;
8659 for( i = 0; i < lp->nchgcols; ++i )
8660 {
8661 col = lp->chgcols[i];
8662 assert(col != NULL);
8663 assert(col->var != NULL);
8665 assert(SCIPvarGetCol(col->var) == col);
8666
8667 if( col->lpipos >= 0 )
8668 {
8669#ifndef NDEBUG
8670 /* do not check consistency of data with LPI in case of LPI=none */
8671 if( !lpinone )
8672 {
8673 SCIP_Real lpiobj;
8674 SCIP_Real lpilb;
8675 SCIP_Real lpiub;
8676
8677 SCIP_CALL( SCIPlpiGetObj(lp->lpi, col->lpipos, col->lpipos, &lpiobj) );
8678 SCIP_CALL( SCIPlpiGetBounds(lp->lpi, col->lpipos, col->lpipos, &lpilb, &lpiub) );
8679 assert(SCIPsetIsFeasEQ(set, lpiobj, col->flushedobj));
8681 || (!SCIPsetIsInfinity(set, -lpilb) && !SCIPsetIsInfinity(set, -col->flushedlb) && SCIPsetIsFeasEQ(set, lpilb, col->flushedlb)));
8683 || (!SCIPsetIsInfinity(set, lpiub) && !SCIPsetIsInfinity(set, col->flushedub) && SCIPsetIsFeasEQ(set, lpiub, col->flushedub)));
8684 }
8685#endif
8686
8687 if( col->objchanged )
8688 {
8690
8691 newobj = col->obj;
8692 if( col->flushedobj != newobj ) /*lint !e777*/
8693 {
8694 assert(nobjchg < lp->ncols);
8695 objind[nobjchg] = col->lpipos;
8696 obj[nobjchg] = newobj;
8697 nobjchg++;
8698 col->flushedobj = newobj;
8699 }
8700 col->objchanged = FALSE;
8701 }
8702
8703 if( col->lbchanged || col->ubchanged )
8704 {
8705 SCIP_Real newlb;
8706 SCIP_Real newub;
8707
8708 /* compute bounds that should be flushed into the LP (taking into account lazy bounds) */
8709 computeLPBounds(lp, set, col, lpiinf, &newlb, &newub);
8710
8711 if( col->flushedlb != newlb || col->flushedub != newub ) /*lint !e777*/
8712 {
8713 assert(nbdchg < lp->ncols);
8714 bdind[nbdchg] = col->lpipos;
8715 lb[nbdchg] = newlb;
8716 ub[nbdchg] = newub;
8717 nbdchg++;
8718 col->flushedlb = newlb;
8719 col->flushedub = newub;
8720 }
8721 col->lbchanged = FALSE;
8722 col->ubchanged = FALSE;
8723 }
8724 }
8725 /* maybe lb/ub/objchanged should all be set to false when lpipos is -1 */
8726 }
8727
8728 /* change objective values in LP */
8729 if( nobjchg > 0 )
8730 {
8731 SCIPsetDebugMsg(set, "flushing objective changes: change %d objective values of %d changed columns\n", nobjchg, lp->nchgcols);
8732 SCIP_CALL( SCIPlpiChgObj(lp->lpi, nobjchg, objind, obj) );
8733
8734 /* mark the LP unsolved */
8735 lp->solved = FALSE;
8736 lp->dualfeasible = FALSE;
8737 lp->dualchecked = FALSE;
8738 lp->lpobjval = SCIP_INVALID;
8740 }
8741
8742 /* change bounds in LP */
8743 if( nbdchg > 0 )
8744 {
8745 SCIPsetDebugMsg(set, "flushing bound changes: change %d bounds of %d changed columns\n", nbdchg, lp->nchgcols);
8746 SCIP_CALL( SCIPlpiChgBounds(lp->lpi, nbdchg, bdind, lb, ub) );
8747
8748 /* mark the LP unsolved */
8749 lp->solved = FALSE;
8750 lp->primalfeasible = FALSE;
8751 lp->primalchecked = FALSE;
8752 lp->lpobjval = SCIP_INVALID;
8754 }
8755
8756 lp->nchgcols = 0;
8757
8758 /* free temporary memory */
8761 SCIPsetFreeBufferArray(set, &bdind);
8763 SCIPsetFreeBufferArray(set, &objind);
8764
8765 return SCIP_OKAY;
8766}
8767
8768/** applies all cached row side changes to the LP */
8769static
8771 SCIP_LP* lp, /**< current LP data */
8772 SCIP_SET* set /**< global SCIP settings */
8773 )
8774{
8775#ifndef NDEBUG
8776 SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
8777#endif
8778 SCIP_ROW* row;
8779 int* ind;
8780 SCIP_Real* lhs;
8781 SCIP_Real* rhs;
8782 SCIP_Real lpiinf;
8783 int i;
8784 int nchg;
8785
8786 assert(lp != NULL);
8787
8788 if( lp->nchgrows == 0 )
8789 return SCIP_OKAY;
8790
8791 /* get the solver's infinity value */
8792 lpiinf = SCIPlpiInfinity(lp->lpi);
8793
8794 /* get temporary memory for changes */
8798
8799 /* collect all cached left and right hand side changes */
8800 nchg = 0;
8801 for( i = 0; i < lp->nchgrows; ++i )
8802 {
8803 row = lp->chgrows[i];
8804 assert(row != NULL);
8805
8806 if( row->lpipos >= 0 )
8807 {
8808#ifndef NDEBUG
8809 /* do not check consistency of data with LPI in case of LPI=none */
8810 if( !lpinone )
8811 {
8812 SCIP_Real lpilhs;
8813 SCIP_Real lpirhs;
8814
8815 SCIP_CALL( SCIPlpiGetSides(lp->lpi, row->lpipos, row->lpipos, &lpilhs, &lpirhs) );
8816 assert(SCIPsetIsSumEQ(set, lpilhs, row->flushedlhs));
8817 assert(SCIPsetIsSumEQ(set, lpirhs, row->flushedrhs));
8818 }
8819#endif
8820 if( row->lhschanged || row->rhschanged )
8821 {
8822 SCIP_Real newlhs;
8823 SCIP_Real newrhs;
8824
8825 newlhs = (SCIPsetIsInfinity(set, -row->lhs) ? -lpiinf : row->lhs - row->constant);
8826 newrhs = (SCIPsetIsInfinity(set, row->rhs) ? lpiinf : row->rhs - row->constant);
8827 if( row->flushedlhs != newlhs || row->flushedrhs != newrhs ) /*lint !e777*/
8828 {
8829 assert(nchg < lp->nrows);
8830 ind[nchg] = row->lpipos;
8831 lhs[nchg] = newlhs;
8832 rhs[nchg] = newrhs;
8833 nchg++;
8834 row->flushedlhs = newlhs;
8835 row->flushedrhs = newrhs;
8836 }
8837 row->lhschanged = FALSE;
8838 row->rhschanged = FALSE;
8839 }
8840 }
8841 }
8842
8843 /* change left and right hand sides in LP */
8844 if( nchg > 0 )
8845 {
8846 SCIPsetDebugMsg(set, "flushing side changes: change %d sides of %d rows\n", nchg, lp->nchgrows);
8847 SCIP_CALL( SCIPlpiChgSides(lp->lpi, nchg, ind, lhs, rhs) );
8848
8849 /* mark the LP unsolved */
8850 lp->solved = FALSE;
8851 lp->primalfeasible = FALSE;
8852 lp->primalchecked = FALSE;
8853 lp->lpobjval = SCIP_INVALID;
8855 }
8856
8857 lp->nchgrows = 0;
8858
8859 /* free temporary memory */
8863
8864 return SCIP_OKAY;
8865}
8866
8867/** copy integrality information to the LP */
8868static
8870 SCIP_LP* lp, /**< current LP data */
8871 SCIP_SET* set /**< global SCIP settings */
8872 )
8873{
8874 int i;
8875 int nintegers;
8876 int* integerInfo;
8877 SCIP_VAR* var;
8878
8879 assert(lp != NULL);
8880
8881 SCIP_CALL( SCIPsetAllocBufferArray(set, &integerInfo, lp->ncols) );
8882
8883 /* count total number of integralities */
8884 nintegers = 0;
8885
8886 for( i = 0; i < lp->ncols; ++i )
8887 {
8888 var = SCIPcolGetVar(lp->cols[i]);
8890 {
8891 integerInfo[i] = 1;
8892 ++nintegers;
8893 }
8894 else
8895 integerInfo[i] = 0;
8896 }
8897
8898 /* only pass integrality information if integer variables are present */
8899 if( nintegers > 0 )
8900 {
8901 SCIP_CALL( SCIPlpiSetIntegralityInformation(lp->lpi, lp->ncols, integerInfo) );
8902 }
8903 else
8904 {
8906 }
8907
8908 SCIPsetFreeBufferArray(set, &integerInfo);
8909
8910 /* mark integralities to be updated */
8912
8913 return SCIP_OKAY;
8914}
8915
8916/** applies all cached changes to the LP solver */
8918 SCIP_LP* lp, /**< current LP data */
8919 BMS_BLKMEM* blkmem, /**< block memory */
8920 SCIP_SET* set, /**< global SCIP settings */
8921 SCIP_PROB* prob, /**< problem data */
8922 SCIP_EVENTQUEUE* eventqueue /**< event queue */
8923 )
8924{
8925 assert(lp != NULL);
8926 assert(blkmem != NULL);
8927
8928 SCIPsetDebugMsg(set, "flushing LP changes: old (%d cols, %d rows), nchgcols=%d, nchgrows=%d, firstchgcol=%d, firstchgrow=%d, new (%d cols, %d rows), flushed=%u\n",
8929 lp->nlpicols, lp->nlpirows, lp->nchgcols, lp->nchgrows, lp->lpifirstchgcol, lp->lpifirstchgrow, lp->ncols, lp->nrows, lp->flushed);
8930
8931 if( !lp->flushed )
8932 {
8933 lp->flushdeletedcols = FALSE;
8934 lp->flushaddedcols = FALSE;
8935 lp->flushdeletedrows = FALSE;
8936 lp->flushaddedrows = FALSE;
8937
8939 SCIP_CALL( lpFlushDelRows(lp, blkmem, set) );
8942 SCIP_CALL( lpFlushAddCols(lp, blkmem, set, eventqueue) );
8943 SCIP_CALL( lpFlushAddRows(lp, blkmem, set, eventqueue) );
8944
8945 lp->flushed = TRUE;
8946
8947 checkLinks(lp);
8948 }
8949
8950 /* if the cutoff bound was changed in between and it is not disabled (e.g. for column generation),
8951 * we want to re-optimize the LP even if nothing else has changed
8952 */
8953 if( !lpCutoffDisabled(set, prob, lp) && lp->cutoffbound != lp->lpiobjlim && lp->ncols > 0 ) /*lint !e777*/
8954 {
8955 lp->solved = FALSE;
8957 }
8958
8959 assert(lp->nlpicols == lp->ncols);
8960 assert(lp->lpifirstchgcol == lp->nlpicols);
8961 assert(lp->nlpirows == lp->nrows);
8962 assert(lp->lpifirstchgrow == lp->nlpirows);
8963 assert(lp->nchgcols == 0);
8964 assert(lp->nchgrows == 0);
8965#ifndef NDEBUG
8966 {
8967 int ncols;
8968 int nrows;
8969
8970 SCIP_CALL( SCIPlpiGetNCols(lp->lpi, &ncols) );
8971 SCIP_CALL( SCIPlpiGetNRows(lp->lpi, &nrows) );
8972 assert(ncols == lp->ncols);
8973 assert(nrows == lp->nrows);
8974 }
8975#endif
8976
8977 return SCIP_OKAY;
8978}
8979
8980/** marks the LP to be flushed, even if the LP thinks it is not flushed */
8982 SCIP_LP* lp, /**< current LP data */
8983 SCIP_SET* set /**< global SCIP settings */
8984 )
8985{
8986#ifndef NDEBUG
8987 SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
8988#endif
8989 int i;
8990
8991 assert(lp != NULL);
8992
8993#ifndef NDEBUG
8994 /* check, if there are really no column or row deletions or coefficient changes left */
8995 while( lp->lpifirstchgcol < lp->nlpicols
8996 && lp->lpifirstchgcol < lp->ncols
8997 && lp->cols[lp->lpifirstchgcol]->lpipos == lp->lpifirstchgcol
8998 && !lp->cols[lp->lpifirstchgcol]->coefchanged )
8999 {
9000 assert(lp->cols[lp->lpifirstchgcol] == lp->lpicols[lp->lpifirstchgcol]);
9001 lp->lpifirstchgcol++;
9002 }
9003 assert(lp->nlpicols == lp->lpifirstchgcol);
9004
9005 while( lp->lpifirstchgrow < lp->nlpirows
9006 && lp->lpifirstchgrow < lp->nrows
9007 && lp->rows[lp->lpifirstchgrow]->lpipos == lp->lpifirstchgrow
9008 && !lp->rows[lp->lpifirstchgrow]->coefchanged )
9009 {
9010 assert(lp->rows[lp->lpifirstchgrow] == lp->lpirows[lp->lpifirstchgrow]);
9011 lp->lpifirstchgrow++;
9012 }
9013 assert(lp->nlpirows == lp->lpifirstchgrow);
9014#endif
9015
9016 lp->lpifirstchgcol = lp->nlpicols;
9017 lp->lpifirstchgrow = lp->nlpirows;
9018
9019 /* check, if there are really no column or row additions left */
9020 assert(lp->ncols == lp->nlpicols);
9021 assert(lp->nrows == lp->nlpirows);
9022
9023 /* mark the changed columns to be unchanged, and check, if this is really correct */
9024 for( i = 0; i < lp->nchgcols; ++i )
9025 {
9026 SCIP_COL* col;
9027
9028 col = lp->chgcols[i];
9029 assert(col != NULL);
9030 assert(col->var != NULL);
9032 assert(SCIPvarGetCol(col->var) == col);
9033
9034 if( col->lpipos >= 0 )
9035 {
9036#ifndef NDEBUG
9037 /* do not check consistency of data with LPI in case of LPI=none */
9038 if( !lpinone )
9039 {
9040 SCIP_Real lpiobj;
9041 SCIP_Real lpilb;
9042 SCIP_Real lpiub;
9043
9044 SCIP_CALL( SCIPlpiGetObj(lp->lpi, col->lpipos, col->lpipos, &lpiobj) );
9045 SCIP_CALL( SCIPlpiGetBounds(lp->lpi, col->lpipos, col->lpipos, &lpilb, &lpiub) );
9046 assert(SCIPsetIsSumEQ(set, lpiobj, col->flushedobj));
9047 assert(SCIPsetIsSumEQ(set, lpilb, col->flushedlb));
9048 assert(SCIPsetIsSumEQ(set, lpiub, col->flushedub));
9049 assert(col->flushedobj == col->obj); /*lint !e777*/
9050 assert(col->flushedlb == (SCIPsetIsInfinity(set, -col->lb) ? -SCIPlpiInfinity(lp->lpi) : col->lb)); /*lint !e777*/
9051 assert(col->flushedub == (SCIPsetIsInfinity(set, col->ub) ? SCIPlpiInfinity(lp->lpi) : col->ub)); /*lint !e777*/
9052 }
9053#endif
9054 col->objchanged = FALSE;
9055 col->lbchanged = FALSE;
9056 col->ubchanged = FALSE;
9057 }
9058 /* maybe lb/ub/objchanged should be set to false also when lpipos is -1 */
9059 }
9060 lp->nchgcols = 0;
9061
9062 /* mark the changed rows to be unchanged, and check, if this is really correct */
9063 for( i = 0; i < lp->nchgrows; ++i )
9064 {
9065 SCIP_ROW* row;
9066
9067 row = lp->chgrows[i];
9068 assert(row != NULL);
9069
9070 if( row->lpipos >= 0 )
9071 {
9072#ifndef NDEBUG
9073 /* do not check consistency of data with LPI in case of LPI=none */
9074 if( !lpinone )
9075 {
9076 SCIP_Real lpilhs;
9077 SCIP_Real lpirhs;
9078
9079 SCIP_CALL( SCIPlpiGetSides(lp->lpi, row->lpipos, row->lpipos, &lpilhs, &lpirhs) );
9080 assert(SCIPsetIsSumEQ(set, lpilhs, row->flushedlhs));
9081 assert(SCIPsetIsSumEQ(set, lpirhs, row->flushedrhs));
9082 assert(row->flushedlhs == (SCIPsetIsInfinity(set, -row->lhs) ? -SCIPlpiInfinity(lp->lpi) : row->lhs - row->constant)); /*lint !e777*/
9083 assert(row->flushedrhs == (SCIPsetIsInfinity(set, row->rhs) ? SCIPlpiInfinity(lp->lpi) : row->rhs - row->constant)); /*lint !e777*/
9084 }
9085#endif
9086 row->lhschanged = FALSE;
9087 row->rhschanged = FALSE;
9088 }
9089 }
9090 lp->nchgrows = 0;
9091
9092 /* mark the LP to be flushed */
9093 lp->flushed = TRUE;
9094
9095 checkLinks(lp);
9096
9097 return SCIP_OKAY;
9098}
9099
9100
9101
9102
9103/*
9104 * LP methods
9105 */
9106
9107/** updates link data after addition of column */
9108static
9110 SCIP_COL* col, /**< LP column */
9111 SCIP_SET* set /**< global SCIP settings */
9112 )
9113{
9114 SCIP_ROW* row;
9115 int i;
9116 int pos;
9117
9118 assert(col != NULL);
9119 assert(col->lppos >= 0);
9120
9121 /* update column arrays of all linked rows */
9122 for( i = 0; i < col->len; ++i )
9123 {
9124 pos = col->linkpos[i];
9125 if( pos >= 0 )
9126 {
9127 row = col->rows[i];
9128 assert(row != NULL);
9129 assert(row->linkpos[pos] == i);
9130 assert(row->cols[pos] == col);
9131 assert(row->nlpcols <= pos && pos < row->len);
9132
9133 row->nlpcols++;
9134 rowSwapCoefs(row, pos, row->nlpcols-1);
9135 assert(row->cols[row->nlpcols-1] == col);
9136
9137 /* if no swap was necessary, mark lpcols to be unsorted */
9138 if( pos == row->nlpcols-1 )
9139 row->lpcolssorted = FALSE;
9140
9141 /* update norms */
9142 rowAddNorms(row, set, col, row->vals[row->nlpcols-1], FALSE);
9143 }
9144 }
9145}
9146
9147/** updates link data after addition of row */
9148static
9150 SCIP_ROW* row /**< LP row */
9151 )
9152{
9153 SCIP_COL* col;
9154 int i;
9155 int pos;
9156
9157 assert(row != NULL);
9158 assert(row->lppos >= 0);
9159
9160 /* update row arrays of all linked columns */
9161 for( i = 0; i < row->len; ++i )
9162 {
9163 pos = row->linkpos[i];
9164 if( pos >= 0 )
9165 {
9166 col = row->cols[i];
9167 assert(col != NULL);
9168 assert(col->linkpos[pos] == i);
9169 assert(col->rows[pos] == row);
9170 assert(col->nlprows <= pos && pos < col->len);
9171
9172 col->nlprows++;
9173 colSwapCoefs(col, pos, col->nlprows-1);
9174
9175 /* if no swap was necessary, mark lprows to be unsorted */
9176 if( pos == col->nlprows-1 )
9177 col->lprowssorted = FALSE;
9178 }
9179 }
9180}
9181
9182/** updates link data after removal of column */
9183static
9185 SCIP_COL* col, /**< LP column */
9186 SCIP_SET* set /**< global SCIP settings */
9187 )
9188{
9189 SCIP_ROW* row;
9190 int i;
9191 int pos;
9192
9193 assert(col != NULL);
9194 assert(col->lppos == -1);
9195
9196 /* update column arrays of all linked rows */
9197 for( i = 0; i < col->len; ++i )
9198 {
9199 pos = col->linkpos[i];
9200 if( pos >= 0 )
9201 {
9202 row = col->rows[i];
9203 assert(row != NULL);
9204 assert(row->linkpos[pos] == i);
9205 assert(row->cols[pos] == col);
9206 assert(0 <= pos && pos < row->nlpcols);
9207
9208 /* update norms */
9209 rowDelNorms(row, set, col, row->vals[pos], TRUE, FALSE, FALSE);
9210
9211 row->nlpcols--;
9212 rowSwapCoefs(row, pos, row->nlpcols);
9213
9214 /* if no swap was necessary, mark nonlpcols to be unsorted */
9215 if( pos == row->nlpcols )
9216 row->nonlpcolssorted = FALSE;
9217 }
9218 }
9219}
9220
9221/** updates link data after removal of row */
9222static
9224 SCIP_ROW* row /**< LP row */
9225 )
9226{
9227 SCIP_COL* col;
9228 int i;
9229 int pos;
9230
9231 assert(row != NULL);
9232 assert(row->lppos == -1);
9233
9234 /* update row arrays of all linked columns */
9235 for( i = 0; i < row->len; ++i )
9236 {
9237 pos = row->linkpos[i];
9238 if( pos >= 0 )
9239 {
9240 col = row->cols[i];
9241 assert(col != NULL);
9242 assert(0 <= pos && pos < col->nlprows);
9243 assert(col->linkpos[pos] == i);
9244 assert(col->rows[pos] == row);
9245
9246 col->nlprows--;
9247 colSwapCoefs(col, pos, col->nlprows);
9248
9249 /* if no swap was necessary, mark lprows to be unsorted */
9250 if( pos == col->nlprows )
9251 col->nonlprowssorted = FALSE;
9252 }
9253 }
9254}
9255
9256static
9258 SCIP_LP* lp, /**< LP data object */
9259 int initsize /**< initial size of the arrays */
9260 )
9261{
9262 assert(lp != NULL);
9263 assert(lp->divechgsides == NULL);
9265 assert(lp->divechgrows == NULL);
9266 assert(lp->ndivechgsides == 0);
9267 assert(lp->divechgsidessize == 0);
9268 assert(initsize > 0);
9269
9270 lp->divechgsidessize = initsize;
9274
9275 return SCIP_OKAY;
9276}
9277
9278static
9280 SCIP_LP* lp, /**< LP data object */
9281 int minsize, /**< minimal number of elements */
9282 SCIP_Real growfact /**< growing factor */
9283 )
9284{
9285 assert(lp != NULL);
9286 assert(lp->divechgsides != NULL);
9288 assert(lp->divechgrows != NULL);
9289 assert(lp->ndivechgsides > 0);
9290 assert(lp->divechgsidessize > 0);
9291 assert(minsize > 0);
9292
9293 if( minsize <= lp->divechgsidessize )
9294 return SCIP_OKAY;
9295
9296 lp->divechgsidessize = MAX(minsize, (int)(lp->divechgsidessize * growfact));
9300
9301 return SCIP_OKAY;
9302}
9303
9304static
9306 SCIP_LP* lp /**< LP data object */
9307 )
9308{
9309 assert(lp != NULL);
9310 assert(lp->divechgsides != NULL);
9312 assert(lp->divechgrows != NULL);
9313 assert(lp->ndivechgsides == 0);
9314 assert(lp->divechgsidessize > 0);
9315
9319 lp->divechgsidessize = 0;
9320}
9321
9322#define DIVESTACKINITSIZE 100
9323
9324/** creates empty LP data object */
9326 SCIP_LP** lp, /**< pointer to LP data object */
9327 SCIP_SET* set, /**< global SCIP settings */
9328 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
9329 SCIP_STAT* stat, /**< problem statistics */
9330 const char* name /**< problem name */
9331 )
9332{
9333 SCIP_Bool success;
9334
9335 assert(lp != NULL);
9336 assert(set != NULL);
9337 assert(stat != NULL);
9338 assert(name != NULL);
9339
9341
9342 /* open LP Solver interface */
9343 SCIP_CALL( SCIPlpiCreate(&(*lp)->lpi, messagehdlr, name, SCIP_OBJSEN_MINIMIZE) );
9344
9345 (*lp)->lpicols = NULL;
9346 (*lp)->lpirows = NULL;
9347 (*lp)->chgcols = NULL;
9348 (*lp)->chgrows = NULL;
9349 (*lp)->cols = NULL;
9350 (*lp)->soldirection = NULL;
9351 (*lp)->lazycols = NULL;
9352 (*lp)->rows = NULL;
9353 (*lp)->lpobjval = 0.0;
9354 (*lp)->glbpseudoobjval = 0.0;
9355 (*lp)->relglbpseudoobjval = 0.0;
9356 (*lp)->glbpseudoobjvalid = TRUE;
9357 (*lp)->glbpseudoobjvalinf = 0;
9358 (*lp)->pseudoobjval = 0.0;
9359 (*lp)->relpseudoobjval = 0.0;
9360 (*lp)->pseudoobjvalid = TRUE;
9361 (*lp)->pseudoobjvalinf = 0;
9362 (*lp)->looseobjval = 0.0;
9363 (*lp)->rellooseobjval = 0.0;
9364 (*lp)->looseobjvalid = TRUE;
9365 (*lp)->looseobjvalinf = 0;
9366 (*lp)->nloosevars = 0;
9367 (*lp)->rootlpobjval = SCIP_INVALID;
9368 (*lp)->rootlooseobjval = SCIP_INVALID;
9369 (*lp)->cutoffbound = SCIPsetInfinity(set);
9370 (*lp)->feastol = SCIP_INVALID; /* to have it initialized */
9371 SCIPlpResetFeastol(*lp, set);
9372 (*lp)->validdegeneracylp = -1;
9373 (*lp)->objsqrnorm = 0.0;
9374 (*lp)->objsumnorm = 0.0;
9375 (*lp)->lpicolssize = 0;
9376 (*lp)->nlpicols = 0;
9377 (*lp)->lpirowssize = 0;
9378 (*lp)->nlpirows = 0;
9379 (*lp)->lpifirstchgcol = 0;
9380 (*lp)->lpifirstchgrow = 0;
9381 (*lp)->colssize = 0;
9382 (*lp)->soldirectionsize = 0;
9383 (*lp)->ncols = 0;
9384 (*lp)->lazycolssize = 0;
9385 (*lp)->nlazycols = 0;
9386 (*lp)->rowssize = 0;
9387 (*lp)->nrows = 0;
9388 (*lp)->chgcolssize = 0;
9389 (*lp)->nchgcols = 0;
9390 (*lp)->chgrowssize = 0;
9391 (*lp)->nchgrows = 0;
9392 (*lp)->firstnewcol = 0;
9393 (*lp)->firstnewrow = 0;
9394 (*lp)->nremovablecols = 0;
9395 (*lp)->nremovablerows = 0;
9396 (*lp)->validsollp = stat->lpcount; /* the initial (empty) SCIP_LP is solved with primal and dual solution of zero */
9397 (*lp)->validfarkaslp = -1;
9398 (*lp)->validsoldirlp = -1;
9399 (*lp)->validsoldirsol = NULL;
9400 (*lp)->objsqrnormunreliable = FALSE;
9401 (*lp)->flushdeletedcols = FALSE;
9402 (*lp)->flushaddedcols = FALSE;
9403 (*lp)->flushdeletedrows = FALSE;
9404 (*lp)->flushaddedrows = FALSE;
9405 (*lp)->updateintegrality = TRUE;
9406 (*lp)->flushed = TRUE;
9407 (*lp)->lpsolstat = SCIP_LPSOLSTAT_OPTIMAL;
9408 (*lp)->solved = TRUE;
9409 (*lp)->primalfeasible = TRUE;
9410 (*lp)->primalchecked = TRUE;
9411 (*lp)->dualfeasible = TRUE;
9412 (*lp)->dualchecked = TRUE;
9413 (*lp)->solisbasic = FALSE;
9414 (*lp)->rootlpisrelax = TRUE;
9415 (*lp)->isrelax = TRUE;
9416 (*lp)->installing = FALSE;
9417 (*lp)->strongbranching = FALSE;
9418 (*lp)->strongbranchprobing = FALSE;
9419 (*lp)->probing = FALSE;
9420 (*lp)->diving = FALSE;
9421 (*lp)->divingobjchg = FALSE;
9422 (*lp)->divinglazyapplied = FALSE;
9423 (*lp)->divelpistate = NULL;
9424 (*lp)->divelpwasprimfeas = TRUE;
9425 (*lp)->divelpwasprimchecked = TRUE;
9426 (*lp)->divelpwasdualfeas = TRUE;
9427 (*lp)->divelpwasdualchecked = TRUE;
9428 (*lp)->hasprovedbound = FALSE;
9429 (*lp)->divechgsides = NULL;
9430 (*lp)->divechgsidetypes = NULL;
9431 (*lp)->divechgrows = NULL;
9432 (*lp)->ndivechgsides = 0;
9433 (*lp)->divechgsidessize = 0;
9434 (*lp)->ndivingrows = 0;
9435 (*lp)->divinglpiitlim = INT_MAX;
9436 (*lp)->resolvelperror = FALSE;
9437 (*lp)->divenolddomchgs = 0;
9438 (*lp)->adjustlpval = FALSE;
9439 (*lp)->lpiobjlim = SCIPlpiInfinity((*lp)->lpi);
9440 (*lp)->lpifeastol = (*lp)->feastol;
9441 (*lp)->lpidualfeastol = SCIPsetDualfeastol(set);
9442 (*lp)->lpibarrierconvtol = SCIPsetBarrierconvtol(set);
9443 (*lp)->lpifromscratch = FALSE;
9444 (*lp)->lpifastmip = set->lp_fastmip;
9445 (*lp)->lpiscaling = set->lp_scaling;
9446 (*lp)->lpipresolving = set->lp_presolving;
9447 (*lp)->lpilpinfo = set->disp_lpinfo;
9448 (*lp)->lpirowrepswitch = set->lp_rowrepswitch;
9449 (*lp)->lpisolutionpolishing = (set->lp_solutionpolishing > 0);
9450 (*lp)->lpirefactorinterval = set->lp_refactorinterval;
9451 (*lp)->lpiconditionlimit = set->lp_conditionlimit;
9452 (*lp)->lpimarkowitz = set->lp_markowitz;
9453 (*lp)->lpiitlim = INT_MAX;
9454 (*lp)->lpipricing = SCIP_PRICING_AUTO;
9455 (*lp)->lastlpalgo = SCIP_LPALGO_DUALSIMPLEX;
9456 (*lp)->lpithreads = set->lp_threads;
9457 (*lp)->lpitiming = (int) set->time_clocktype;
9458 (*lp)->lpirandomseed = set->random_randomseed;
9459 (*lp)->storedsolvals = NULL;
9460 (*lp)->lpexact = NULL;
9461
9462 /* allocate arrays for diving */
9464
9465 /* set default parameters in LP solver */
9466 SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_OBJLIM, (*lp)->lpiobjlim, &success) );
9467 if( !success )
9468 {
9469 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9470 "LP Solver <%s>: objective limit cannot be set -- can lead to unnecessary simplex iterations\n",
9472 }
9473 SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_FEASTOL, (*lp)->lpifeastol, &success) );
9474 (*lp)->lpihasfeastol = success;
9475 if( !success )
9476 {
9477 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9478 "LP Solver <%s>: primal feasibility tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
9480 }
9481 SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_DUALFEASTOL, (*lp)->lpidualfeastol, &success) );
9482 (*lp)->lpihasdualfeastol = success;
9483 if( !success )
9484 {
9485 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9486 "LP Solver <%s>: dual feasibility tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
9488 }
9489 SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_BARRIERCONVTOL, (*lp)->lpibarrierconvtol, &success) );
9490 (*lp)->lpihasbarrierconvtol = success;
9491 if( !success )
9492 {
9493 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9494 "LP Solver <%s>: barrier convergence tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
9496 }
9497 SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_FROMSCRATCH, (*lp)->lpifromscratch, &success) );
9498 SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_FASTMIP, (*lp)->lpifastmip, &success) );
9499 (*lp)->lpihasfastmip = success;
9500 if( !success )
9501 {
9502 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9503 "LP Solver <%s>: fastmip setting not available -- SCIP parameter has no effect\n",
9505 }
9506 SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_SCALING, (*lp)->lpiscaling, &success) );
9507 (*lp)->lpihasscaling = success;
9508 if( !success )
9509 {
9510 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9511 "LP Solver <%s>: scaling not available -- SCIP parameter has no effect\n",
9513 }
9514 SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_PRESOLVING, (*lp)->lpipresolving, &success) );
9515 (*lp)->lpihaspresolving = success;
9516 if( !success )
9517 {
9518 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9519 "LP Solver <%s>: presolving not available -- SCIP parameter has no effect\n",
9521 }
9522 SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_TIMING, (*lp)->lpitiming, &success) );
9523 if( !success )
9524 {
9525 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9526 "LP Solver <%s>: clock type cannot be set\n",
9528 }
9529 SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_LPITLIM, (*lp)->lpiitlim, &success) );
9530 if( !success )
9531 {
9532 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9533 "LP Solver <%s>: iteration limit cannot be set -- can lead to unnecessary simplex iterations\n",
9535 }
9536 SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_PRICING, (int)(*lp)->lpipricing, &success) );
9537 if( !success )
9538 {
9539 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9540 "LP Solver <%s>: pricing strategy cannot be set -- SCIP parameter has no effect\n",
9542 }
9543 SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_LPINFO, (*lp)->lpilpinfo, &success) );
9544 if( !success )
9545 {
9546 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9547 "LP Solver <%s>: lpinfo setting not available -- SCIP parameter has no effect\n",
9549 }
9550 SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_ROWREPSWITCH, (*lp)->lpirowrepswitch, &success) );
9551 (*lp)->lpihasrowrep = success;
9552 if( !success )
9553 {
9554 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9555 "LP Solver <%s>: row representation of the basis not available -- SCIP parameter lp/rowrepswitch has no effect\n",
9557 }
9558 SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_POLISHING, ((*lp)->lpisolutionpolishing ? 1 : 0), &success) );
9559 (*lp)->lpihaspolishing = success;
9560 if( !success )
9561 {
9562 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9563 "LP Solver <%s>: solution polishing not available -- SCIP parameter lp/solutionpolishing has no effect\n",
9565 }
9566 SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_REFACTOR, (*lp)->lpirefactorinterval, &success) );
9567 (*lp)->lpihasrefactor = success;
9568 if( !success )
9569 {
9570 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9571 "LP Solver <%s>: refactorization interval not available -- SCIP parameter lp/refactorinterval has no effect\n",
9573 }
9574 SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_CONDITIONLIMIT, (*lp)->lpiconditionlimit, &success) );
9575 if( !success )
9576 {
9577 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9578 "LP Solver <%s>: condition number limit for the basis not available -- SCIP parameter lp/conditionlimit has no effect\n",
9580 }
9581 SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_MARKOWITZ, (*lp)->lpimarkowitz, &success) );
9582 if( !success )
9583 {
9584 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9585 "LP Solver <%s>: markowitz threshhold not available -- SCIP parameter lp/minmarkowitz has no effect\n",
9587 }
9588 SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_THREADS, (*lp)->lpithreads, &success) );
9589 if( !success )
9590 {
9591 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9592 "LP Solver <%s>: number of threads settings not available -- SCIP parameter has no effect\n",
9594 }
9595 /* keep the default LP random seed if this parameter is set to 0 (current default) */
9596 if( (*lp)->lpirandomseed != 0 )
9597 {
9598 SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_RANDOMSEED, (*lp)->lpirandomseed, &success) );
9599 if( !success )
9600 {
9601 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9602 "LP Solver <%s>: random seed parameter not available -- SCIP parameter has no effect\n",
9604 }
9605 }
9606
9607 /* Check that infinity value of LP-solver is at least as large as the one used in SCIP. This is necessary, because we
9608 * transfer SCIP infinity values to the ones by the LPI, but not the converse. */
9609 if ( set->num_infinity > SCIPlpiInfinity((*lp)->lpi) )
9610 {
9611 SCIPerrorMessage("The infinity value of the LP solver has to be at least as large as the one of SCIP.\n");
9613 }
9614
9615 return SCIP_OKAY;
9616}
9617
9618/** frees LP data object */
9620 SCIP_LP** lp, /**< pointer to LP data object */
9621 BMS_BLKMEM* blkmem, /**< block memory */
9622 SCIP_SET* set, /**< global SCIP settings */
9623 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9624 SCIP_EVENTFILTER* eventfilter /**< global event filter */
9625 )
9626{
9627 int i;
9628
9629 assert(lp != NULL);
9630 assert(*lp != NULL);
9631
9632 SCIP_CALL( SCIPlpClear(*lp, blkmem, set, eventqueue, eventfilter) );
9633
9635
9636 /* release LPI rows */
9637 for( i = 0; i < (*lp)->nlpirows; ++i )
9638 {
9639 SCIP_CALL( SCIProwRelease(&(*lp)->lpirows[i], blkmem, set, *lp) );
9640 }
9641
9642 if( (*lp)->lpi != NULL )
9643 {
9644 SCIP_CALL( SCIPlpiFree(&(*lp)->lpi) );
9645 }
9646
9647 BMSfreeMemoryNull(&(*lp)->storedsolvals);
9648 BMSfreeMemoryArrayNull(&(*lp)->lpicols);
9649 BMSfreeMemoryArrayNull(&(*lp)->lpirows);
9650 BMSfreeMemoryArrayNull(&(*lp)->chgcols);
9651 BMSfreeMemoryArrayNull(&(*lp)->chgrows);
9652 BMSfreeMemoryArrayNull(&(*lp)->lazycols);
9653 BMSfreeMemoryArrayNull(&(*lp)->cols);
9654 BMSfreeMemoryArrayNull(&(*lp)->rows);
9655 BMSfreeMemoryArrayNull(&(*lp)->soldirection);
9656 BMSfreeMemory(lp);
9657
9658 return SCIP_OKAY;
9659}
9660
9661/** resets the LP to the empty LP by removing all columns and rows from LP, releasing all rows, and flushing the
9662 * changes to the LP solver
9663 */
9665 SCIP_LP* lp, /**< LP data */
9666 BMS_BLKMEM* blkmem, /**< block memory */
9667 SCIP_SET* set, /**< global SCIP settings */
9668 SCIP_PROB* prob, /**< problem data */
9669 SCIP_STAT* stat, /**< problem statistics */
9670 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9671 SCIP_EVENTFILTER* eventfilter /**< global event filter */
9672 )
9673{
9674 assert(stat != NULL);
9675
9676 SCIP_CALL( SCIPlpClear(lp, blkmem, set, eventqueue, eventfilter) );
9677 SCIP_CALL( SCIPlpFlush(lp, blkmem, set, prob, eventqueue) );
9678
9679 /* mark the empty LP to be solved */
9681 lp->lpobjval = 0.0;
9682 lp->validsollp = stat->lpcount; /* the initial (empty) SCIP_LP is solved with primal and dual solution of zero */
9683 lp->validfarkaslp = -1;
9684 lp->validdegeneracylp = -1;
9685 lp->validsoldirlp = -1;
9686 lp->validsoldirsol = NULL;
9687 lp->solved = TRUE;
9688 lp->primalfeasible = TRUE;
9689 lp->primalchecked = TRUE;
9690 lp->dualfeasible = TRUE;
9691 lp->dualchecked = TRUE;
9692 lp->solisbasic = FALSE;
9694
9695 return SCIP_OKAY;
9696}
9697
9698/** adds a column to the LP */
9700 SCIP_LP* lp, /**< LP data */
9701 SCIP_SET* set, /**< global SCIP settings */
9702 SCIP_COL* col, /**< LP column */
9703 int depth /**< depth in the tree where the column addition is performed */
9704 )
9705{
9706 assert(lp != NULL);
9707 assert(!lp->diving);
9708 assert(col != NULL);
9709 assert(col->len == 0 || col->rows != NULL);
9710 assert(col->lppos == -1);
9711 assert(col->var != NULL);
9713 assert(SCIPvarGetCol(col->var) == col);
9714 assert(SCIPvarIsIntegral(col->var) == col->integral);
9716
9717 SCIPsetDebugMsg(set, "adding column <%s> to LP (%d rows, %d cols)\n", SCIPvarGetName(col->var), lp->nrows, lp->ncols);
9718#ifdef SCIP_DEBUG
9719 {
9720 int i;
9721 SCIPsetDebugMsgPrint(set, " (obj: %g) [%g,%g]", col->obj, col->lb, col->ub);
9722 for( i = 0; i < col->len; ++i )
9723 SCIPsetDebugMsgPrint(set, " %+g<%s>", col->vals[i], col->rows[i]->name);
9725 }
9726#endif
9727
9728 SCIP_CALL( ensureColsSize(lp, set, lp->ncols+1) );
9729 lp->cols[lp->ncols] = col;
9730 col->lppos = lp->ncols;
9731 col->lpdepth = depth;
9732 col->age = 0;
9733 lp->ncols++;
9734 if( col->removable )
9735 lp->nremovablecols++;
9736
9737 if( !SCIPsetIsInfinity(set, -col->lazylb) || !SCIPsetIsInfinity(set, col->lazyub) )
9738 {
9740 lp->lazycols[lp->nlazycols] = col;
9741 lp->nlazycols++;
9742 }
9743
9744 /* mark the current LP unflushed */
9745 lp->flushed = FALSE;
9746
9747 /* update column arrays of all linked rows */
9748 colUpdateAddLP(col, set);
9749
9750 /* update the objective function vector norms */
9751 lpUpdateObjNorms(lp, set, 0.0, col->unchangedobj);
9752
9753 checkLinks(lp);
9754
9755 return SCIP_OKAY;
9756}
9757
9758/** adds a row to the LP and captures it */
9760 SCIP_LP* lp, /**< LP data */
9761 BMS_BLKMEM* blkmem, /**< block memory buffers */
9762 SCIP_SET* set, /**< global SCIP settings */
9763 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9764 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
9765 SCIP_ROW* row, /**< LP row */
9766 int depth /**< depth in the tree where the row addition is performed */
9767 )
9768{
9769 assert(lp != NULL);
9770 assert(row != NULL);
9771 assert(row->len == 0 || row->cols != NULL);
9772 assert(row->lppos == -1);
9773
9774 SCIProwCapture(row);
9775 SCIProwLock(row);
9776
9777 SCIPsetDebugMsg(set, "adding row <%s> to LP (%d rows, %d cols)\n", row->name, lp->nrows, lp->ncols);
9778#ifdef SCIP_DEBUG
9779 {
9780 int i;
9781 SCIPsetDebugMsgPrint(set, " %g <=", row->lhs);
9782 for( i = 0; i < row->len; ++i )
9783 SCIPsetDebugMsgPrint(set, " %+g<%s>", row->vals[i], SCIPvarGetName(row->cols[i]->var));
9784 if( !SCIPsetIsZero(set, row->constant) )
9785 SCIPsetDebugMsgPrint(set, " %+g", row->constant);
9786 SCIPsetDebugMsgPrint(set, " <= %g\n", row->rhs);
9787 }
9788#endif
9789
9790 SCIP_CALL( ensureRowsSize(lp, set, lp->nrows+1) );
9791 lp->rows[lp->nrows] = row;
9792 row->lppos = lp->nrows;
9793 row->lpdepth = depth;
9794 row->age = 0;
9795 lp->nrows++;
9796 if( row->removable )
9797 lp->nremovablerows++;
9798
9799 /* mark the current LP unflushed */
9800 lp->flushed = FALSE;
9801
9802 /* update row arrays of all linked columns */
9803 rowUpdateAddLP(row);
9804
9805 checkLinks(lp);
9806
9807 rowCalcNorms(row, set);
9808
9809 /* check, if row addition to LP events are tracked
9810 * if so, issue ROWADDEDLP event
9811 */
9812 if( (eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWADDEDLP) != 0) )
9813 {
9814 SCIP_EVENT* event;
9815
9816 SCIP_CALL( SCIPeventCreateRowAddedLP(&event, blkmem, row) );
9817 SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
9818 }
9819
9820 return SCIP_OKAY;
9821}
9822
9823
9824#ifndef NDEBUG
9825/** method checks if all columns in the lazycols array have at least one lazy bound and also have a counter part in the
9826 * cols array; furthermore, it is checked if columns in the cols array which have a lazy bound have a counter part in
9827 * the lazycols array
9828 */
9829static
9831 SCIP_LP* lp, /**< LP data */
9832 SCIP_SET* set /**< global SCIP settings */
9833 )
9834{
9835 SCIP_Bool contained;
9836 int c;
9837 int i;
9838
9839 assert(lp != NULL);
9840
9841 /* check if each column in the lazy column array has a counter part in the column array */
9842 for( i = 0; i < lp->nlazycols; ++i )
9843 {
9844 /* check if each lazy column has at least on lazy bound */
9845 assert(lp->lazycols[i] != NULL);
9847
9848 contained = FALSE;
9849 for( c = 0; c < lp->ncols; ++c )
9850 {
9851 if( lp->lazycols[i] == lp->cols[c] )
9852 {
9854 contained = TRUE;
9855 }
9856 }
9857 assert(contained);
9858 }
9859
9860 /* check if each column in the column array which has at least one lazy bound has a counter part in the lazy column *
9861 * array */
9862 for( c = 0; c < lp->ncols; ++c )
9863 {
9864 contained = FALSE;
9865 assert(lp->cols[c] != NULL);
9866
9867 for( i = 0; i < lp->nlazycols; ++i )
9868 {
9869 if( lp->lazycols[i] == lp->cols[c] )
9870 {
9871 contained = TRUE;
9872 }
9873 }
9874
9875 assert(contained == (!SCIPsetIsInfinity(set, lp->cols[c]->lazyub) || !SCIPsetIsInfinity(set, -lp->cols[c]->lazylb)));
9876 }
9877}
9878#else
9879#define checkLazyColArray(lp, set) /**/
9880#endif
9881
9882/** removes all columns after the given number of cols from the LP */
9884 SCIP_LP* lp, /**< LP data */
9885 SCIP_SET* set, /**< global SCIP settings */
9886 int newncols /**< new number of columns in the LP */
9887 )
9888{
9889 SCIP_COL* col;
9890 int c;
9891
9892 assert(lp != NULL);
9893
9894 SCIPsetDebugMsg(set, "shrinking LP from %d to %d columns\n", lp->ncols, newncols);
9895 assert(0 <= newncols);
9896 assert(newncols <= lp->ncols);
9897
9898 if( newncols < lp->ncols )
9899 {
9900 assert(!lp->diving);
9901
9902 for( c = lp->ncols-1; c >= newncols; --c )
9903 {
9904 col = lp->cols[c];
9905 assert(col != NULL);
9906 assert(col->len == 0 || col->rows != NULL);
9907 assert(col->var != NULL);
9909 assert(SCIPvarGetCol(col->var) == lp->cols[c]);
9910 assert(col->lppos == c);
9911
9912 /* mark column to be removed from the LP */
9913 col->lppos = -1;
9914 col->lpdepth = -1;
9915 lp->ncols--;
9916
9917 /* count removable columns */
9918 if( col->removable )
9919 lp->nremovablecols--;
9920
9921 /* update column arrays of all linked rows */
9922 colUpdateDelLP(col, set);
9923
9924 /* update the objective function vector norms */
9925 lpUpdateObjNorms(lp, set, col->unchangedobj, 0.0);
9926 }
9927 assert(lp->ncols == newncols);
9928 lp->lpifirstchgcol = MIN(lp->lpifirstchgcol, newncols);
9929
9930 /* remove columns which are deleted from the lazy column array */
9931 c = 0;
9932 while( c < lp->nlazycols )
9933 {
9934 if( lp->lazycols[c]->lppos < 0 )
9935 {
9936 lp->lazycols[c] = lp->lazycols[lp->nlazycols-1];
9937 lp->nlazycols--;
9938 }
9939 else
9940 c++;
9941 }
9942
9943 /* mark the current LP unflushed */
9944 lp->flushed = FALSE;
9945
9947 checkLinks(lp);
9948 }
9949 assert(lp->nremovablecols <= lp->ncols);
9950
9951 return SCIP_OKAY;
9952}
9953
9954/** removes and releases all rows after the given number of rows from the LP */
9956 SCIP_LP* lp, /**< LP data */
9957 BMS_BLKMEM* blkmem, /**< block memory */
9958 SCIP_SET* set, /**< global SCIP settings */
9959 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9960 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
9961 int newnrows /**< new number of rows in the LP */
9962 )
9963{
9964 SCIP_ROW* row;
9965 int r;
9966
9967 assert(lp != NULL);
9968 assert(0 <= newnrows && newnrows <= lp->nrows);
9969
9970 SCIPsetDebugMsg(set, "shrinking LP from %d to %d rows\n", lp->nrows, newnrows);
9971 if( newnrows < lp->nrows )
9972 {
9973 for( r = lp->nrows-1; r >= newnrows; --r )
9974 {
9975 row = lp->rows[r];
9976 assert(row != NULL);
9977 assert(row->len == 0 || row->cols != NULL);
9978 assert(row->lppos == r);
9979
9980 /* mark row to be removed from the LP */
9981 row->lppos = -1;
9982 row->lpdepth = -1;
9983 lp->nrows--;
9984
9985 /* count removable rows */
9986 if( row->removable )
9987 lp->nremovablerows--;
9988
9989 /* update row arrays of all linked columns */
9990 rowUpdateDelLP(row);
9991
9992 SCIProwUnlock(lp->rows[r]);
9993
9994 /* check, if row deletion events are tracked
9995 * if so, issue ROWDELETEDLP event
9996 */
9997 if( eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWDELETEDLP) != 0 ) /*lint !e587*/
9998 {
9999 SCIP_EVENT* event;
10000
10001 SCIP_CALL( SCIPeventCreateRowDeletedLP(&event, blkmem, lp->rows[r]) );
10002 SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
10003 }
10004
10005 SCIP_CALL( SCIProwRelease(&lp->rows[r], blkmem, set, lp) );
10006 }
10007 assert(lp->nrows == newnrows);
10008 lp->lpifirstchgrow = MIN(lp->lpifirstchgrow, newnrows);
10009
10010 /* mark the current LP unflushed */
10011 lp->flushed = FALSE;
10012
10013 checkLinks(lp);
10014 }
10015 assert(lp->nremovablerows <= lp->nrows);
10016
10017 return SCIP_OKAY;
10018}
10019
10020/** removes all columns and rows from LP, releases all rows */
10022 SCIP_LP* lp, /**< LP data */
10023 BMS_BLKMEM* blkmem, /**< block memory */
10024 SCIP_SET* set, /**< global SCIP settings */
10025 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
10026 SCIP_EVENTFILTER* eventfilter /**< global event filter */
10027 )
10028{
10029 assert(lp != NULL);
10030 assert(!lp->diving);
10031
10032 SCIPsetDebugMsg(set, "clearing LP\n");
10033 SCIP_CALL( SCIPlpShrinkCols(lp, set, 0) );
10034 SCIP_CALL( SCIPlpShrinkRows(lp, blkmem, set, eventqueue, eventfilter, 0) );
10035
10036 return SCIP_OKAY;
10037}
10038
10039/** remembers number of columns and rows to track the newly added ones */
10041 SCIP_LP* lp /**< current LP data */
10042 )
10043{
10044 assert(lp != NULL);
10045 assert(!lp->diving);
10046
10047 lp->firstnewrow = lp->nrows;
10048 lp->firstnewcol = lp->ncols;
10049}
10050
10051/** sets the remembered number of columns and rows to the given values */
10053 SCIP_LP* lp, /**< current LP data */
10054 int nrows, /**< number of rows to set the size marker to */
10055 int ncols /**< number of columns to set the size marker to */
10056 )
10057{
10058 assert(lp != NULL);
10059 assert(!lp->diving);
10060
10061 lp->firstnewrow = nrows;
10062 lp->firstnewcol = ncols;
10063}
10064
10065/** gets all indices of basic columns and rows: index i >= 0 corresponds to column i, index i < 0 to row -i-1 */
10067 SCIP_LP* lp, /**< LP data */
10068 int* basisind /**< pointer to store basis indices ready to keep number of rows entries */
10069 )
10070{
10071 assert(lp != NULL);
10072 assert(lp->flushed);
10073 assert(lp->solved);
10074 assert(lp->solisbasic);
10075 assert(basisind != NULL);
10076
10077 SCIP_CALL( SCIPlpiGetBasisInd(lp->lpi, basisind) );
10078
10079 return SCIP_OKAY;
10080}
10081
10082/** gets current basis status for columns and rows; arrays must be large enough to store the basis status */
10084 SCIP_LP* lp, /**< LP data */
10085 int* cstat, /**< array to store column basis status, or NULL */
10086 int* rstat /**< array to store row basis status, or NULL */
10087 )
10088{
10089 assert(lp != NULL);
10090 assert(lp->flushed);
10091 assert(lp->solved);
10092 assert(lp->solisbasic);
10093
10094 SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
10095
10096 return SCIP_OKAY;
10097}
10098
10099/** gets a row from the inverse basis matrix B^-1 */
10101 SCIP_LP* lp, /**< LP data */
10102 int r, /**< row number */
10103 SCIP_Real* coef, /**< pointer to store the coefficients of the row */
10104 int* inds, /**< array to store the non-zero indices, or NULL */
10105 int* ninds /**< pointer to store the number of non-zero indices, or NULL
10106 * (-1: if we do not store sparsity informations) */
10107 )
10108{
10109 assert(lp != NULL);
10110 assert(lp->flushed);
10111 assert(lp->solved);
10112 assert(lp->solisbasic);
10113 assert(0 <= r && r < lp->nrows); /* the basis matrix is nrows x nrows */
10114 assert(coef != NULL);
10115
10116 SCIP_CALL( SCIPlpiGetBInvRow(lp->lpi, r, coef, inds, ninds) );
10117
10118 return SCIP_OKAY;
10119}
10120
10121/** gets a column from the inverse basis matrix B^-1 */
10123 SCIP_LP* lp, /**< LP data */
10124 int c, /**< column number of B^-1; this is NOT the number of the column in the LP
10125 * returned by SCIPcolGetLPPos(); you have to call SCIPgetBasisInd()
10126 * to get the array which links the B^-1 column numbers to the row and
10127 * column numbers of the LP! c must be between 0 and nrows-1, since the
10128 * basis has the size nrows * nrows */
10129 SCIP_Real* coef, /**< pointer to store the coefficients of the column */
10130 int* inds, /**< array to store the non-zero indices, or NULL */
10131 int* ninds /**< pointer to store the number of non-zero indices, or NULL
10132 * (-1: if we do not store sparsity informations) */
10133 )
10134{
10135 assert(lp != NULL);
10136 assert(lp->flushed);
10137 assert(lp->solved);
10138 assert(lp->solisbasic);
10139 assert(0 <= c && c < lp->nrows); /* the basis matrix is nrows x nrows */
10140 assert(coef != NULL);
10141
10142 SCIP_CALL( SCIPlpiGetBInvCol(lp->lpi, c, coef, inds, ninds) );
10143
10144 return SCIP_OKAY;
10145}
10146
10147/** gets a row from the product of inverse basis matrix B^-1 and coefficient matrix A (i.e. from B^-1 * A) */
10149 SCIP_LP* lp, /**< LP data */
10150 int r, /**< row number */
10151 SCIP_Real* binvrow, /**< row in B^-1 from prior call to SCIPlpGetBInvRow(), or NULL */
10152 SCIP_Real* coef, /**< pointer to store the coefficients of the row */
10153 int* inds, /**< array to store the non-zero indices, or NULL */
10154 int* ninds /**< pointer to store the number of non-zero indices, or NULL
10155 * (-1: if we do not store sparsity informations) */
10156 )
10157{
10158 assert(lp != NULL);
10159 assert(lp->flushed);
10160 assert(lp->solved);
10161 assert(lp->solisbasic);
10162 assert(0 <= r && r < lp->nrows); /* the basis matrix is nrows x nrows */
10163 assert(coef != NULL);
10164
10165 SCIP_CALL( SCIPlpiGetBInvARow(lp->lpi, r, binvrow, coef, inds, ninds) );
10166
10167 return SCIP_OKAY;
10168}
10169
10170/** gets a column from the product of inverse basis matrix B^-1 and coefficient matrix A (i.e. from B^-1 * A),
10171 * i.e., it computes B^-1 * A_c with A_c being the c'th column of A
10172 */
10174 SCIP_LP* lp, /**< LP data */
10175 int c, /**< column number which can be accessed by SCIPcolGetLPPos() */
10176 SCIP_Real* coef, /**< pointer to store the coefficients of the column */
10177 int* inds, /**< array to store the non-zero indices, or NULL */
10178 int* ninds /**< pointer to store the number of non-zero indices, or NULL
10179 * (-1: if we do not store sparsity informations) */
10180 )
10181{
10182 assert(lp != NULL);
10183 assert(lp->flushed);
10184 assert(lp->solved);
10185 assert(lp->solisbasic);
10186 assert(0 <= c && c < lp->ncols);
10187 assert(coef != NULL);
10188
10189 SCIP_CALL( SCIPlpiGetBInvACol(lp->lpi, c, coef, inds, ninds) );
10190
10191 return SCIP_OKAY;
10192}
10193
10194/** calculates a weighted sum of all LP rows; for negative weights, the left and right hand side of the corresponding
10195 * LP row are swapped in the summation
10196 */
10198 SCIP_LP* lp, /**< LP data */
10199 SCIP_SET* set, /**< global SCIP settings */
10200 SCIP_PROB* prob, /**< problem data */
10201 SCIP_Real* weights, /**< row weights in row summation */
10202 SCIP_REALARRAY* sumcoef, /**< array to store sum coefficients indexed by variables' probindex */
10203 SCIP_Real* sumlhs, /**< pointer to store the left hand side of the row summation */
10204 SCIP_Real* sumrhs /**< pointer to store the right hand side of the row summation */
10205 )
10206{
10207 SCIP_ROW* row;
10208 int r;
10209 int i;
10210 int idx;
10211 SCIP_Bool lhsinfinite;
10212 SCIP_Bool rhsinfinite;
10213
10214 assert(lp != NULL);
10215 assert(prob != NULL);
10216 assert(weights != NULL);
10217 assert(sumcoef != NULL);
10218 assert(sumlhs != NULL);
10219 assert(sumrhs != NULL);
10220
10221 /**@todo test, if a column based summation is faster */
10222
10223 SCIP_CALL( SCIPrealarrayClear(sumcoef) );
10224 SCIP_CALL( SCIPrealarrayExtend(sumcoef, set->mem_arraygrowinit, set->mem_arraygrowfac, 0, prob->nvars-1) );
10225 *sumlhs = 0.0;
10226 *sumrhs = 0.0;
10227 lhsinfinite = FALSE;
10228 rhsinfinite = FALSE;
10229 for( r = 0; r < lp->nrows; ++r )
10230 {
10231 if( !SCIPsetIsZero(set, weights[r]) )
10232 {
10233 row = lp->rows[r];
10234 assert(row != NULL);
10235 assert(row->len == 0 || row->cols != NULL);
10236 assert(row->len == 0 || row->cols_index != NULL);
10237 assert(row->len == 0 || row->vals != NULL);
10238
10239 /* add the row coefficients to the sum */
10240 for( i = 0; i < row->len; ++i )
10241 {
10242 assert(row->cols[i] != NULL);
10243 assert(row->cols[i]->var != NULL);
10245 assert(SCIPvarGetCol(row->cols[i]->var) == row->cols[i]);
10247 idx = row->cols[i]->var_probindex;
10248 assert(0 <= idx && idx < prob->nvars);
10249 SCIP_CALL( SCIPrealarrayIncVal(sumcoef, set->mem_arraygrowinit, set->mem_arraygrowfac, idx, weights[r] * row->vals[i]) );
10250 }
10251
10252 /* add the row sides to the sum, depending on the sign of the weight */
10253 if( weights[r] > 0.0 )
10254 {
10255 lhsinfinite = lhsinfinite || SCIPsetIsInfinity(set, -row->lhs);
10256 if( !lhsinfinite )
10257 (*sumlhs) += weights[r] * (row->lhs - row->constant);
10258 rhsinfinite = rhsinfinite || SCIPsetIsInfinity(set, row->rhs);
10259 if( !rhsinfinite )
10260 (*sumrhs) += weights[r] * (row->rhs - row->constant);
10261 }
10262 else
10263 {
10264 lhsinfinite = lhsinfinite || SCIPsetIsInfinity(set, row->rhs);
10265 if( !lhsinfinite )
10266 (*sumlhs) += weights[r] * (row->rhs - row->constant);
10267 rhsinfinite = rhsinfinite || SCIPsetIsInfinity(set, -row->lhs);
10268 if( !rhsinfinite )
10269 (*sumrhs) += weights[r] * (row->lhs - row->constant);
10270 }
10271 }
10272 }
10273
10274 if( lhsinfinite )
10275 *sumlhs = -SCIPsetInfinity(set);
10276 if( rhsinfinite )
10277 *sumrhs = SCIPsetInfinity(set);
10278
10279 return SCIP_OKAY;
10280}
10281
10282/** stores LP state (like basis information) into LP state object */
10284 SCIP_LP* lp, /**< LP data */
10285 BMS_BLKMEM* blkmem, /**< block memory */
10286 SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
10287 )
10288{
10289 assert(lp != NULL);
10290 assert(lp->flushed);
10291 assert(lp->solved);
10292 assert(blkmem != NULL);
10293 assert(lpistate != NULL);
10294
10295 /* check whether there is no lp */
10296 if( lp->nlpicols == 0 && lp->nlpirows == 0 )
10297 *lpistate = NULL;
10298 else
10299 {
10300 SCIP_CALL( SCIPlpiGetState(lp->lpi, blkmem, lpistate) );
10301 }
10302
10303 return SCIP_OKAY;
10304}
10305
10306/** loads LP state (like basis information) into solver */
10308 SCIP_LP* lp, /**< LP data */
10309 BMS_BLKMEM* blkmem, /**< block memory */
10310 SCIP_SET* set, /**< global SCIP settings */
10311 SCIP_PROB* prob, /**< problem data */
10312 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
10313 SCIP_LPISTATE* lpistate, /**< LP state information (like basis information) */
10314 SCIP_Bool wasprimfeas, /**< primal feasibility when LP state information was stored */
10315 SCIP_Bool wasprimchecked, /**< true if the LP solution has passed the primal feasibility check */
10316 SCIP_Bool wasdualfeas, /**< dual feasibility when LP state information was stored */
10317 SCIP_Bool wasdualchecked /**< true if the LP solution has passed the dual feasibility check */
10318 )
10319{
10320 assert(lp != NULL);
10321 assert(blkmem != NULL);
10322
10323 /* flush changes to the LP solver */
10324 SCIP_CALL( SCIPlpFlush(lp, blkmem, set, prob, eventqueue) );
10325 assert(lp->flushed);
10326
10327 if( lp->solved && lp->solisbasic )
10328 return SCIP_OKAY;
10329
10330 /* set LPI state in the LP solver */
10331 if( lpistate == NULL )
10332 lp->solisbasic = FALSE;
10333 else
10334 {
10335 SCIP_CALL( SCIPlpiSetState(lp->lpi, blkmem, lpistate) );
10336 lp->solisbasic = SCIPlpiHasStateBasis(lp->lpi, lpistate);
10337 }
10338 /* @todo: setting feasibility to TRUE might be wrong because in probing mode, the state is even saved when the LP was
10339 * flushed and solved, also, e.g., when we hit the iteration limit
10340 */
10341 lp->primalfeasible = wasprimfeas;
10342 lp->primalchecked = wasprimchecked;
10343 lp->dualfeasible = wasdualfeas;
10344 lp->dualchecked = wasdualchecked;
10345
10346 return SCIP_OKAY;
10347}
10348
10349/** frees LP state information */
10351 SCIP_LP* lp, /**< LP data */
10352 BMS_BLKMEM* blkmem, /**< block memory */
10353 SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
10354 )
10355{
10356 assert(lp != NULL);
10357
10358 if( *lpistate != NULL )
10359 {
10360 SCIP_CALL( SCIPlpiFreeState(lp->lpi, blkmem, lpistate) );
10361 }
10362
10363 return SCIP_OKAY;
10364}
10365
10366/** interrupts the currently ongoing lp solve, or disables the interrupt */
10368 SCIP_LP* lp, /**< LP data */
10369 SCIP_Bool interrupt /**< TRUE if interrupt should be set, FALSE if it should be disabled */
10370 )
10371{
10372 assert(lp != NULL);
10373
10374 if( lp->lpi == NULL )
10375 return SCIP_OKAY;
10376
10377 SCIP_CALL( SCIPlpiInterrupt(lp->lpi, interrupt) );
10378
10379 return SCIP_OKAY;
10380}
10381
10382/** stores pricing norms into LP norms object */
10384 SCIP_LP* lp, /**< LP data */
10385 BMS_BLKMEM* blkmem, /**< block memory */
10386 SCIP_LPINORMS** lpinorms /**< pointer to LP pricing norms information */
10387 )
10388{
10389 assert(lp != NULL);
10390 assert(lp->flushed);
10391 assert(lp->solved);
10392 assert(blkmem != NULL);
10393 assert(lpinorms != NULL);
10394
10395 /* check whether there is no lp */
10396 if( lp->nlpicols == 0 && lp->nlpirows == 0 )
10397 *lpinorms = NULL;
10398 else
10399 {
10400 SCIP_CALL( SCIPlpiGetNorms(lp->lpi, blkmem, lpinorms) );
10401 }
10402
10403 return SCIP_OKAY;
10404}
10405
10406/** loads pricing norms from LP norms object into solver */
10408 SCIP_LP* lp, /**< LP data */
10409 BMS_BLKMEM* blkmem, /**< block memory */
10410 SCIP_LPINORMS* lpinorms /**< LP pricing norms information */
10411 )
10412{
10413 assert(lp != NULL);
10414 assert(blkmem != NULL);
10415 assert(lp->flushed);
10416
10417 /* set LPI norms in the LP solver */
10418 if( lpinorms != NULL )
10419 {
10420 SCIP_CALL( SCIPlpiSetNorms(lp->lpi, blkmem, lpinorms) );
10421 }
10422
10423 return SCIP_OKAY;
10424}
10425
10426/** frees pricing norms information */
10428 SCIP_LP* lp, /**< LP data */
10429 BMS_BLKMEM* blkmem, /**< block memory */
10430 SCIP_LPINORMS** lpinorms /**< pointer to LP pricing norms information */
10431 )
10432{
10433 assert(lp != NULL);
10434
10435 SCIP_CALL( SCIPlpiFreeNorms(lp->lpi, blkmem, lpinorms) );
10436
10437 return SCIP_OKAY;
10438}
10439
10440/** return the current cutoff bound of the lp */
10442 SCIP_LP* lp /**< current LP data */
10443 )
10444{
10445 assert(lp != NULL);
10446
10447 return lp->cutoffbound;
10448}
10449
10450/** sets the upper objective limit of the LP solver */
10452 SCIP_LP* lp, /**< current LP data */
10453 SCIP_SET* set, /**< global SCIP settings */
10454 SCIP_PROB* prob, /**< problem data */
10455 SCIP_Real cutoffbound /**< new upper objective limit */
10456 )
10457{
10458 assert(lp != NULL);
10459
10460 SCIPsetDebugMsg(set, "setting LP upper objective limit from %g to %g\n", lp->cutoffbound, cutoffbound);
10461
10462 /* if the objective function was changed in diving, the cutoff bound has no meaning (it will be set correctly
10463 * in SCIPendDive())
10464 */
10465 if( SCIPlpDivingObjChanged(lp) )
10466 {
10468 return SCIP_OKAY;
10469 }
10470
10471 /* if the cutoff bound is increased, and the LP was proved to exceed the old cutoff, it is no longer solved */
10472 if( SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OBJLIMIT && cutoffbound > lp->cutoffbound )
10473 {
10474 /* mark the current solution invalid */
10475 lp->solved = FALSE;
10476 lp->lpobjval = SCIP_INVALID;
10478 }
10479 /* if the cutoff bound is decreased below the current optimal value, the LP now exceeds the objective limit;
10480 * if the objective limit in the LP solver was disabled, the solution status of the LP is not changed
10481 */
10482 else if( !lpCutoffDisabled(set, prob, lp) && SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OPTIMAL
10483 && SCIPlpGetObjval(lp, set, prob) >= cutoffbound )
10484 {
10485 assert(lp->flushed);
10486 assert(lp->solved);
10488 }
10489
10490 if( !lp->diving && !lp->probing )
10491 SCIP_CALL( SCIPlpExactSetCutoffbound(lp->lpexact, set, cutoffbound) );
10492
10493 lp->cutoffbound = cutoffbound;
10494
10495 return SCIP_OKAY;
10496}
10497
10498/** gets current primal feasibility tolerance of LP solver */
10500 SCIP_LP* lp /**< current LP data */
10501 )
10502{
10503 assert(lp != NULL);
10504
10505 return lp->feastol;
10506}
10507
10508/** sets primal feasibility tolerance of LP solver */
10510 SCIP_LP* lp, /**< current LP data */
10511 SCIP_SET* set, /**< global SCIP settings */
10512 SCIP_Real newfeastol /**< new primal feasibility tolerance for LP */
10513 )
10514{
10515 assert(lp != NULL);
10516 assert(newfeastol > 0.0);
10517
10518 SCIPsetDebugMsg(set, "setting LP primal feasibility tolerance from %g to %g\n", lp->feastol, newfeastol);
10519
10520 /* mark the LP unsolved, if the primal feasibility tolerance is tightened */
10521 if( newfeastol < lp->feastol )
10522 {
10523 lp->solved = FALSE;
10525 }
10526
10527 lp->feastol = newfeastol;
10528}
10529
10530/** resets primal feasibility tolerance of LP solver
10531 *
10532 * Sets primal feasibility tolerance to min of numerics/lpfeastolfactor * numerics/feastol and relaxfeastol.
10533 */
10535 SCIP_LP* lp, /**< current LP data */
10536 SCIP_SET* set /**< global SCIP settings */
10537 )
10538{
10539 assert(lp != NULL);
10540
10541 SCIPsetDebugMsg(set, "reset LP primal feasibility tolerance\n");
10542
10543 if( SCIPsetRelaxfeastol(set) != SCIP_INVALID ) /*lint !e777*/
10545 else
10547}
10548
10549/** returns the name of the given LP algorithm */
10550static
10551const char* lpalgoName(
10552 SCIP_LPALGO lpalgo /**< LP algorithm */
10553 )
10554{
10555 switch( lpalgo )
10556 {
10558 return "primal simplex";
10560 return "dual simplex";
10562 return "barrier";
10564 return "barrier/crossover";
10565 default:
10566 SCIPerrorMessage("invalid LP algorithm\n");
10567 SCIPABORT();
10568 return "invalid"; /*lint !e527*/
10569 }
10570}
10571
10572/** calls LPI to perform primal simplex, measures time and counts iterations, gets basis feasibility status */
10573static
10575 SCIP_LP* lp, /**< current LP data */
10576 SCIP_SET* set, /**< global SCIP settings */
10577 SCIP_STAT* stat, /**< problem statistics */
10578 SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
10579 SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10580 SCIP_Bool instable, /**< is this a resolving call to avoid instable LPs? */
10581 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10582 )
10583{
10584 SCIP_Real timedelta;
10585 SCIP_RETCODE retcode;
10586 int iterations;
10587
10588 assert(lp != NULL);
10589 assert(lp->flushed);
10590 assert(set != NULL);
10591 assert(stat != NULL);
10592 assert(lperror != NULL);
10593
10594 SCIPsetDebugMsg(set, "solving LP %" SCIP_LONGINT_FORMAT " (%d cols, %d rows) with primal simplex (diving=%d, nprimallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
10595 stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nprimallps, stat->ndivinglps);
10596
10597 *lperror = FALSE;
10598
10599#ifdef SCIP_MORE_DEBUG /* for debugging: write all root node LP's */
10600 if( stat->nnodes == 1 && !lp->diving && !lp->probing )
10601 {
10602 char fname[SCIP_MAXSTRLEN];
10603 (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
10604 SCIP_CALL( SCIPlpWrite(lp, fname) );
10605 SCIPsetDebugMsg(set, "wrote LP to file <%s> (primal simplex, objlim=%.15g, feastol=%.15g/%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
10606 fname, lp->lpiobjlim, lp->lpifeastol, lp->lpidualfeastol,
10608 }
10609#endif
10610
10611 /* start timing */
10612 if( lp->diving || lp->probing )
10613 {
10614 if( lp->strongbranchprobing )
10616 else
10618
10619 timedelta = 0.0; /* unused for diving or probing */
10620 }
10621 else
10622 {
10624 timedelta = -SCIPclockGetTime(stat->primallptime);
10625 }
10626
10627 /* if this is a call to resolve an instable LP, collect time */
10628 if( instable )
10629 {
10631 }
10632
10633 /* call primal simplex */
10634 retcode = SCIPlpiSolvePrimal(lp->lpi);
10635 if( retcode == SCIP_LPERROR )
10636 {
10637 *lperror = TRUE;
10638 SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") primal simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10639 }
10640 else
10641 {
10642 SCIP_CALL( retcode );
10643 }
10645 lp->solisbasic = TRUE;
10646
10647 /* stop timing */
10648 if( lp->diving || lp->probing )
10649 {
10650 if( lp->strongbranchprobing )
10652 else
10654 }
10655 else
10656 {
10657 timedelta += SCIPclockGetTime(stat->primallptime);
10659 }
10660
10661 if ( instable )
10662 {
10664 }
10665
10666 /* count number of iterations */
10667 SCIPstatIncrement(stat, set, lpcount);
10668 SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10669 if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10670 {
10671 if( !lp->strongbranchprobing )
10672 {
10673 SCIPstatIncrement(stat, set, nlps);
10674 SCIPstatAdd( stat, set, nlpiterations, iterations );
10675 }
10676 if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10677 {
10678 SCIPstatIncrement(stat, set, nprimalresolvelps );
10679 SCIPstatAdd(stat, set, nprimalresolvelpiterations, iterations);
10680 }
10681 if ( instable )
10682 {
10683 SCIPstatIncrement(stat, set, nresolveinstablelps);
10684 SCIPstatAdd(stat, set, nresolveinstablelpiters, iterations);
10685 }
10686 if( lp->diving || lp->probing )
10687 {
10688 if( lp->strongbranchprobing )
10689 {
10690 SCIPstatIncrement(stat, set, nsbdivinglps);
10691 SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10692 }
10693 else
10694 {
10695 SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10696 SCIPstatIncrement(stat, set, ndivinglps);
10697 SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10698 }
10699 }
10700 else
10701 {
10702 SCIPstatIncrement(stat, set, nprimallps);
10703 SCIPstatAdd(stat, set, nprimallpiterations, iterations);
10704 }
10705 }
10706 else
10707 {
10708 if ( ! lp->diving && ! lp->probing )
10709 {
10710 SCIPstatIncrement(stat, set, nprimalzeroitlps);
10711 SCIPstatAdd(stat, set, primalzeroittime, timedelta);
10712 }
10713
10714 if ( keepsol && !(*lperror) )
10715 {
10716 /* the solution didn't change: if the solution was valid before resolve, it is still valid */
10717 if( lp->validsollp == stat->lpcount-1 )
10718 lp->validsollp = stat->lpcount;
10719 if( lp->validfarkaslp == stat->lpcount-1 )
10720 lp->validfarkaslp = stat->lpcount;
10721 }
10722 }
10723
10724 SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with primal simplex (diving=%d, nprimallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
10725 stat->lpcount, lp->diving || lp->probing, stat->nprimallps, stat->ndivinglps);
10726
10727 return SCIP_OKAY;
10728}
10729
10730/** calls LPI to perform dual simplex, measures time and counts iterations */
10731static
10733 SCIP_LP* lp, /**< current LP data */
10734 SCIP_SET* set, /**< global SCIP settings */
10735 SCIP_STAT* stat, /**< problem statistics */
10736 SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
10737 SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10738 SCIP_Bool instable, /**< is this a resolving call to avoid instable LPs? */
10739 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10740 )
10741{
10742 SCIP_Real timedelta;
10743 SCIP_RETCODE retcode;
10744 int iterations;
10745
10746 assert(lp != NULL);
10747 assert(lp->flushed);
10748 assert(set != NULL);
10749 assert(stat != NULL);
10750 assert(lperror != NULL);
10751
10752 SCIPsetDebugMsg(set, "solving LP %" SCIP_LONGINT_FORMAT " (%d cols, %d rows) with dual simplex (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
10753 stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10754
10755 *lperror = FALSE;
10756
10757#ifdef SCIP_MORE_DEBUG /* for debugging: write all root node LP's */
10758 if( stat->nnodes == 1 && !lp->diving && !lp->probing )
10759 {
10760 char fname[SCIP_MAXSTRLEN];
10761 (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
10762 SCIP_CALL( SCIPlpWrite(lp, fname) );
10763 SCIPsetDebugMsg(set, "wrote LP to file <%s> (dual simplex, objlim=%.15g, feastol=%.15g/%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
10764 fname, lp->lpiobjlim, lp->lpifeastol, lp->lpidualfeastol,
10766 }
10767#endif
10768
10769 /* start timing */
10770 if( lp->diving || lp->probing )
10771 {
10772 if( lp->strongbranchprobing )
10774 else
10776
10777 timedelta = 0.0; /* unused for diving or probing */
10778 }
10779 else
10780 {
10782 timedelta = -SCIPclockGetTime(stat->duallptime);
10783 }
10784
10785 /* if this is a call to resolve an instable LP, collect time */
10786 if ( instable )
10787 {
10789 }
10790
10791 /* call dual simplex */
10792 retcode = SCIPlpiSolveDual(lp->lpi);
10793 if( retcode == SCIP_LPERROR )
10794 {
10795 *lperror = TRUE;
10796 SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10797 }
10798 else
10799 {
10800 SCIP_CALL( retcode );
10801 }
10803 lp->solisbasic = TRUE;
10804
10805 /* stop timing */
10806 if( lp->diving || lp->probing )
10807 {
10808 if( lp->strongbranchprobing )
10810 else
10812 }
10813 else
10814 {
10815 timedelta += SCIPclockGetTime(stat->duallptime);
10817 }
10818
10819 if ( instable )
10820 {
10822 }
10823
10824 /* count number of iterations */
10825 SCIPstatIncrement(stat, set, lpcount);
10826 SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10827 if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10828 {
10829 if( !lp->strongbranchprobing )
10830 {
10831 SCIPstatIncrement(stat, set, nlps);
10832 SCIPstatAdd(stat, set, nlpiterations, iterations);
10833 }
10834 if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10835 {
10836 SCIPstatIncrement(stat, set, ndualresolvelps);
10837 SCIPstatAdd(stat, set, ndualresolvelpiterations, iterations);
10838 }
10839 if ( instable )
10840 {
10841 SCIPstatIncrement(stat, set, nresolveinstablelps);
10842 SCIPstatAdd(stat, set, nresolveinstablelpiters, iterations);
10843 }
10844 if( lp->diving || lp->probing )
10845 {
10846 if( lp->strongbranchprobing )
10847 {
10848 SCIPstatIncrement(stat, set, nsbdivinglps);
10849 SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10850 }
10851 else
10852 {
10853 SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10854 SCIPstatIncrement(stat, set, ndivinglps);
10855 SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10856 }
10857 }
10858 else
10859 {
10860 SCIPstatIncrement(stat, set, nduallps);
10861 SCIPstatAdd(stat, set, nduallpiterations, iterations);
10862 }
10863 }
10864 else
10865 {
10866 if ( ! lp->diving && ! lp->probing )
10867 {
10868 SCIPstatIncrement(stat, set, ndualzeroitlps);
10869 SCIPstatAdd(stat, set, dualzeroittime, timedelta);
10870 }
10871
10872 if( keepsol && !(*lperror) )
10873 {
10874 /* the solution didn't change: if the solution was valid before resolve, it is still valid */
10875 if( lp->validsollp == stat->lpcount-1 )
10876 lp->validsollp = stat->lpcount;
10877 if( lp->validfarkaslp == stat->lpcount-1 )
10878 lp->validfarkaslp = stat->lpcount;
10879 }
10880 }
10881
10882 SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with dual simplex (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
10883 stat->lpcount, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10884
10885 return SCIP_OKAY;
10886}
10887
10888/** calls LPI to perform lexicographic dual simplex to find a lexicographically minimal optimal solution, measures time and counts iterations
10889 *
10890 * We follow the approach of the following paper to find a lexicographically minimal optimal
10891 * solution:
10892 *
10893 * Zanette, Fischetti, Balas@n
10894 * Can pure cutting plane algorithms work?@n
10895 * IPCO 2008, Bertinoro, Italy.
10896 *
10897 * We do, however, not aim for the exact lexicographically minimal optimal solutions, but perform a
10898 * heuristic, i.e., we limit the number of components which are minimized.
10899 *
10900 * More precisely, we first solve the problem with the dual simplex algorithm. Then we fix those
10901 * nonbasic variables to their current value (i.e., one of the bounds except maybe for free
10902 * variables) that have nonzero reduced cost. This fixes the objective function value, because only
10903 * pivots that will not change the objective are allowed afterwards.
10904 *
10905 * Then the not yet fixed variables are considered in turn. If they are at their lower bounds and
10906 * nonbasic, they are fixed to this bound, since their value cannot be decreased further. Once a
10907 * candidate is found, we set the objective to minimize this variable. We run the primal simplex
10908 * algorithm (since the objective is changed the solution is not dual feasible anymore; if
10909 * variables out of the basis have been fixed to their lower bound, the basis is also not primal
10910 * feasible anymore). After the optimization, we again fix nonbasic variables that have nonzero
10911 * reduced cost. We then choose the next variable and iterate.
10912 *
10913 * We stop the process once we do not find candidates or have performed a maximum number of
10914 * iterations.
10915 *
10916 * @todo Does this really produce a lexicographically minimal solution?
10917 * @todo Can we skip the consideration of basic variables that are at their lower bound? How can we
10918 * guarantee that these variables will not be changed in later stages? We can fix these variables
10919 * to their lower bound, but this destroys the basis.
10920 * @todo Should we use lexicographical minimization in diving/probing or not?
10921 */
10922static
10924 SCIP_LP* lp, /**< current LP data */
10925 SCIP_SET* set, /**< global SCIP settings */
10926 SCIP_STAT* stat, /**< problem statistics */
10927 SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
10928 SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10929 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10930 )
10931{
10932 SCIP_Real timedelta;
10933 SCIP_RETCODE retcode;
10934 int totalIterations;
10935 int lexIterations;
10936 int iterations;
10937 int rounds;
10938
10939 assert(lp != NULL);
10940 assert(lp->flushed);
10941 assert(set != NULL);
10942 assert(stat != NULL);
10943 assert(lperror != NULL);
10944
10945 SCIPsetDebugMsg(set, "solving LP %" SCIP_LONGINT_FORMAT " (%d cols, %d rows) with lex dual simplex (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
10946 stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10947
10948 *lperror = FALSE;
10949
10950 /* start timing */
10951 if( lp->diving || lp->probing )
10952 {
10953 if( lp->strongbranchprobing )
10955 else
10957
10958 timedelta = 0.0; /* unused for diving or probing */
10959 }
10960 else
10961 {
10963 timedelta = -SCIPclockGetTime(stat->duallptime);
10964 }
10965
10966 /* call dual simplex for first lp */
10967 retcode = SCIPlpiSolveDual(lp->lpi);
10968 if( retcode == SCIP_LPERROR )
10969 {
10970 *lperror = TRUE;
10971 SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10972 }
10973 else
10974 {
10975 SCIP_CALL( retcode );
10976 }
10977 SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10978 totalIterations = iterations;
10979
10980 /* stop timing */
10981 if( lp->diving || lp->probing )
10982 {
10983 if( lp->strongbranchprobing )
10985 else
10987 }
10988 else
10989 {
10990 timedelta += SCIPclockGetTime(stat->duallptime);
10992 }
10993
10994 /* count number of iterations */
10995 SCIPstatIncrement(stat, set, lpcount);
10996 if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10997 {
10998 if( lp->strongbranchprobing )
10999 {
11000 SCIPstatAdd(stat, set, nlpiterations, iterations);
11001 }
11002 if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
11003 {
11004 SCIPstatIncrement(stat, set, ndualresolvelps);
11005 SCIPstatAdd(stat, set, ndualresolvelpiterations, iterations);
11006 }
11007 if( lp->diving || lp->probing )
11008 {
11009 if( lp->strongbranchprobing )
11010 {
11011 SCIPstatIncrement(stat, set, nsbdivinglps);
11012 SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
11013 }
11014 else
11015 {
11016 SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
11017 SCIPstatIncrement(stat, set, ndivinglps);
11018 SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
11019 }
11020 }
11021 else
11022 {
11023 SCIPstatIncrement(stat, set, nduallps);
11024 SCIPstatAdd(stat, set, nduallpiterations, iterations);
11025 }
11026 }
11027 else
11028 {
11029 if ( ! lp->diving && ! lp->probing )
11030 {
11031 SCIPstatIncrement(stat, set, ndualzeroitlps);
11032 SCIPstatAdd(stat, set, dualzeroittime, timedelta);
11033 }
11034 }
11035 lexIterations = 0;
11036
11037 /* search for lexicographically minimal optimal solution */
11038 if( !lp->diving && !lp->probing && SCIPlpiIsOptimal(lp->lpi) )
11039 {
11041 SCIP_Real* dualsol;
11042 SCIP_Real* redcost;
11043 int* cstat;
11044 int* rstat;
11046 SCIP_Real* newlb;
11047 SCIP_Real* newub;
11048 SCIP_Real* newlhs;
11049 SCIP_Real* newrhs;
11050 SCIP_Real* oldlb;
11051 SCIP_Real* oldub;
11052 SCIP_Real* oldlhs;
11053 SCIP_Real* oldrhs;
11055 SCIP_Bool* fixedc;
11056 SCIP_Bool* fixedr;
11057 int* indcol;
11058 int* indrow;
11059 int* indallcol;
11060 int* indallrow;
11061 SCIP_Bool chooseBasic;
11062 SCIP_Bool success;
11063 int nDualDeg;
11064 int r, c;
11065 int cntcol;
11066 int cntrow;
11067 int nruns;
11068 int pos;
11069
11070 chooseBasic = set->lp_lexdualbasic;
11071
11072 /* start timing */
11074
11075 /* get all solution information */
11076 SCIP_CALL( SCIPsetAllocBufferArray(set, &dualsol, lp->nlpirows) );
11077 SCIP_CALL( SCIPsetAllocBufferArray(set, &redcost, lp->nlpicols) );
11078 if( chooseBasic )
11079 {
11081 }
11082 else
11083 primsol = NULL;
11084
11085 /* get basic and nonbasic information */
11088
11089 /* save bounds, lhs/rhs, and objective */
11095 SCIP_CALL( SCIPlpiGetBounds(lp->lpi, 0, lp->nlpicols-1, oldlb, oldub) );
11096 SCIP_CALL( SCIPlpiGetSides(lp->lpi, 0, lp->nlpirows-1, oldlhs, oldrhs) );
11097 SCIP_CALL( SCIPlpiGetObj(lp->lpi, 0, lp->nlpicols-1, oldobj) );
11098
11099 /* get storage for several arrays */
11103
11107
11108 SCIP_CALL( SCIPsetAllocBufferArray(set, &indallcol, lp->nlpicols) );
11109 SCIP_CALL( SCIPsetAllocBufferArray(set, &indallrow, lp->nlpirows) );
11110
11113
11114 /* initialize: set objective to 0, get fixed variables */
11116 for( c = 0; c < lp->nlpicols; ++c )
11117 {
11118 newobj[c] = 0.0;
11119 indallcol[c] = c;
11120 if( SCIPsetIsFeasEQ(set, oldlb[c], oldub[c]) )
11121 fixedc[c] = TRUE;
11122 else
11123 fixedc[c] = FALSE;
11124 }
11125
11126 /* initialize: get fixed slack variables */
11127 for( r = 0; r < lp->nlpirows; ++r )
11128 {
11129 indallrow[r] = r;
11130 if( SCIPsetIsFeasEQ(set, oldlhs[r], oldrhs[r]) )
11131 fixedr[r] = TRUE;
11132 else
11133 fixedr[r] = FALSE;
11134 }
11135
11136#ifdef DEBUG_LEXDUAL
11137 {
11138 int j;
11139
11140 if( !chooseBasic )
11141 {
11142 assert(primsol == NULL);
11144 }
11145 assert(primsol != NULL);
11147 SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
11148
11149 for( j = 0; j < lp->nlpicols; ++j )
11150 {
11151 if( fixedc[j] )
11152 {
11153 SCIPsetDebugMsg(set, "%f (%d) [f] ", primsol[j], j);
11154 }
11155 else
11156 {
11157 char type;
11158 switch( (SCIP_BASESTAT) cstat[j] )
11159 {
11161 type = 'l';
11162 break;
11164 type = 'u';
11165 break;
11166 case SCIP_BASESTAT_ZERO:
11167 type = 'z';
11168 break;
11170 type = 'b';
11171 break;
11172 default:
11173 type = '?';
11174 SCIPerrorMessage("unknown base stat %d\n", cstat[j]);
11175 SCIPABORT();
11176 }
11177 SCIPsetDebugMsg(set, "%f (%d) [%c] ", primsol[j], j, type);
11178 }
11179 }
11180 SCIPsetDebugMsg(set, "\n\n");
11181
11182 if( !chooseBasic )
11183 {
11185 assert(primsol == NULL);
11186 }
11187 }
11188#endif
11189
11190 /* disable objective limit */
11192 assert(success);
11193
11194 /* perform lexicographic rounds */
11195 pos = -1;
11196 nruns = 0;
11197 rounds = 0;
11198 /* SCIP_CALL( lpSetLPInfo(lp, TRUE) ); */
11199 do
11200 {
11201 int oldpos;
11202
11203 /* get current solution */
11204 if( chooseBasic )
11205 SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, dualsol, NULL, redcost) );
11206 else
11207 {
11208 SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, NULL, dualsol, NULL, redcost) );
11209 assert(primsol == NULL);
11210 }
11211
11212 /* get current basis */
11213 SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
11214
11215 /* check columns: find first candidate (either basic or nonbasic and zero reduced cost) and fix variables */
11216 nDualDeg = 0;
11217 cntcol = 0;
11218 oldpos = pos;
11219 pos = -1;
11220 for( c = 0; c < lp->nlpicols; ++c )
11221 {
11222 if( !fixedc[c] )
11223 {
11224 /* check whether variable is in basis */
11225 if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_BASIC )
11226 {
11227 /* store first candidate */
11228 if( pos == -1 && c > oldpos )
11229 {
11230 if( !chooseBasic || !SCIPsetIsIntegral(set, primsol[c]) ) /*lint !e613*/
11231 pos = c;
11232 }
11233 }
11234 else
11235 {
11236 /* reduced cost == 0 -> possible candidate */
11237 if( SCIPsetIsDualfeasZero(set, redcost[c]) )
11238 {
11239 ++nDualDeg;
11240 /* only if we have not yet found a candidate */
11241 if( pos == -1 && c > oldpos )
11242 {
11243 /* if the variable is at its lower bound - fix it, because its value cannot be reduced */
11244 if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_LOWER )
11245 {
11246 newlb[cntcol] = oldlb[c];
11247 newub[cntcol] = oldlb[c];
11248 indcol[cntcol++] = c;
11249 fixedc[c] = TRUE;
11250 }
11251 else /* found a non-fixed candidate */
11252 {
11253 if( !chooseBasic )
11254 pos = c;
11255 }
11256 }
11257 }
11258 else
11259 {
11260 /* nonzero reduced cost -> variable can be fixed */
11261 if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_LOWER )
11262 {
11263 newlb[cntcol] = oldlb[c];
11264 newub[cntcol] = oldlb[c];
11265 }
11266 else
11267 {
11268 if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_UPPER )
11269 {
11270 newlb[cntcol] = oldub[c];
11271 newub[cntcol] = oldub[c];
11272 }
11273 else
11274 {
11276 newlb[cntcol] = 0.0;
11277 newub[cntcol] = 0.0;
11278 }
11279 }
11280 indcol[cntcol++] = c;
11281 fixedc[c] = TRUE;
11282 }
11283 }
11284 }
11285 }
11286
11287 /* check rows */
11288 cntrow = 0;
11289 for( r = 0; r < lp->nlpirows; ++r )
11290 {
11291 if( !fixedr[r] )
11292 {
11293 /* consider only nonbasic rows */
11294 if( (SCIP_BASESTAT) rstat[r] != SCIP_BASESTAT_BASIC )
11295 {
11297 if( SCIPsetIsFeasZero(set, dualsol[r]) )
11298 ++nDualDeg;
11299 else
11300 {
11301 if( SCIPsetIsFeasPositive(set, dualsol[r]) )
11302 {
11303 assert(!SCIPsetIsInfinity(set, -oldlhs[r]));
11304 newlhs[cntrow] = oldlhs[r];
11305 newrhs[cntrow] = oldlhs[r];
11306 }
11307 else
11308 {
11309 assert(!SCIPsetIsInfinity(set, oldrhs[r]));
11310 newlhs[cntrow] = oldrhs[r];
11311 newrhs[cntrow] = oldrhs[r];
11312 }
11313 indrow[cntrow++] = r;
11314 fixedr[r] = TRUE;
11315 }
11316 }
11317 }
11318 }
11319
11320 if( nDualDeg > 0 && pos >= 0 )
11321 {
11322 assert(0 <= pos && pos < lp->nlpicols && pos > oldpos);
11323
11324 /* change objective */
11325 if( nruns == 0 )
11326 {
11327 /* set objective to appropriate unit vector for first run */
11328 newobj[pos] = 1.0;
11329 SCIP_CALL( SCIPlpiChgObj(lp->lpi, lp->nlpicols, indallcol, newobj) );
11330 }
11331 else
11332 {
11333 /* set obj. coef. to 1 for other runs (ones remain in previous positions) */
11334 SCIP_Real obj = 1.0;
11335 SCIP_CALL( SCIPlpiChgObj(lp->lpi, 1, &pos, &obj) );
11336 }
11337
11338 /* fix variables */
11339 SCIP_CALL( SCIPlpiChgBounds(lp->lpi, cntcol, indcol, newlb, newub) );
11340 SCIP_CALL( SCIPlpiChgSides(lp->lpi, cntrow, indrow, newlhs, newrhs) );
11341
11342 /* solve with primal simplex, because we are primal feasible, but not necessarily dual feasible */
11343 retcode = SCIPlpiSolvePrimal(lp->lpi);
11344 if( retcode == SCIP_LPERROR )
11345 {
11346 *lperror = TRUE;
11347 SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") in lex-dual: primal simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
11348 }
11349 else
11350 {
11351 SCIP_CALL( retcode );
11352 }
11353 SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
11354 lexIterations += iterations;
11355
11356 if( iterations > 0 )
11357 {
11358#ifdef DEBUG_LEXDUAL
11359 int j;
11360
11361 if( !chooseBasic )
11362 {
11363 assert(primsol == NULL);
11365 }
11366 assert(primsol != NULL);
11368
11369 for( j = 0; j < lp->nlpicols; ++j )
11370 {
11371 if( fixedc[j] )
11372 {
11373 SCIPsetDebugMsg(set, "%f (%d) [f] ", primsol[j], j);
11374 }
11375 else
11376 {
11377 char cstart = '[';
11378 char cend = ']';
11379 char type;
11380
11381 if(j == pos)
11382 {
11383 cstart = '*';
11384 cend = '*';
11385 }
11386
11387 switch( (SCIP_BASESTAT) cstat[j] )
11388 {
11390 type = 'l';
11391 break;
11393 type = 'u';
11394 break;
11395 case SCIP_BASESTAT_ZERO:
11396 type = 'z';
11397 break;
11399 type = 'b';
11400 break;
11401 default:
11402 type = '?';
11403 SCIPerrorMessage("unknown base state %d\n", cstat[j]);
11404 SCIPABORT();
11405 }
11406 SCIPsetDebugMsg(set, "%f (%d) %c%c%c ", primsol[j], j, cstart, type, cend);
11407 }
11408 }
11409 SCIPsetDebugMsg(set, "\n\n");
11410
11411 if( !chooseBasic )
11412 {
11414 assert(primsol == NULL);
11415 }
11416#endif
11417
11418 /* count only as round if iterations have been performed */
11419 ++rounds;
11420 }
11421
11422 ++nruns;
11423 }
11424 }
11425 while( pos >= 0 && nDualDeg > 0 && (set->lp_lexdualmaxrounds == -1 || rounds < set->lp_lexdualmaxrounds) );
11426
11427 /* reset bounds, lhs/rhs, and obj */
11428 SCIP_CALL( SCIPlpiChgBounds(lp->lpi, lp->nlpicols, indallcol, oldlb, oldub) );
11429 SCIP_CALL( SCIPlpiChgSides(lp->lpi, lp->nlpirows, indallrow, oldlhs, oldrhs) );
11430 SCIP_CALL( SCIPlpiChgObj(lp->lpi, lp->nlpicols, indallcol, oldobj) );
11431
11432 /* resolve to update solvers internal data structures - should only produce few pivots */
11433 retcode = SCIPlpiSolveDual(lp->lpi);
11434 if( retcode == SCIP_LPERROR )
11435 {
11436 *lperror = TRUE;
11437 SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
11438 }
11439 else
11440 {
11441 SCIP_CALL( retcode );
11442 }
11444
11445 /* reset objective limit */
11446 SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_OBJLIM, lp->lpiobjlim, &success) );
11447 assert(success);
11448
11449 /* add LP iterations */
11450 SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
11451 lexIterations += iterations;
11452
11453 /* SCIP_CALL( lpSetLPInfo(lp, set->disp_lpinfo) ); */
11454
11455 /* count number of iterations */
11456 if( totalIterations == 0 && lexIterations > 0 && !lp->strongbranchprobing )
11457 SCIPstatIncrement(stat, set, nlps);
11458
11459 if( lexIterations > 0 ) /* don't count the resolves after removing unused columns/rows */
11460 {
11461 SCIPstatAdd(stat, set, nlpiterations, lexIterations);
11462 if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
11463 {
11464 SCIPstatIncrement(stat, set, nlexdualresolvelps);
11465 SCIPstatAdd(stat, set, nlexdualresolvelpiterations, lexIterations);
11466 }
11467 SCIPstatIncrement(stat, set, nlexduallps);
11468 SCIPstatAdd(stat, set, nlexduallpiterations, lexIterations);
11469
11470 totalIterations += lexIterations;
11471 }
11472
11473 /* free space */
11475
11476 SCIPsetFreeBufferArray(set, &fixedr);
11477 SCIPsetFreeBufferArray(set, &fixedc);
11478
11479 SCIPsetFreeBufferArray(set, &indallrow);
11480 SCIPsetFreeBufferArray(set, &indallcol);
11481
11482 SCIPsetFreeBufferArray(set, &indrow);
11483 SCIPsetFreeBufferArray(set, &newrhs);
11484 SCIPsetFreeBufferArray(set, &newlhs);
11485
11486 SCIPsetFreeBufferArray(set, &indcol);
11487 SCIPsetFreeBufferArray(set, &newub);
11488 SCIPsetFreeBufferArray(set, &newlb);
11489
11491 SCIPsetFreeBufferArray(set, &oldrhs);
11492 SCIPsetFreeBufferArray(set, &oldlhs);
11493 SCIPsetFreeBufferArray(set, &oldub);
11494 SCIPsetFreeBufferArray(set, &oldlb);
11495
11496 SCIPsetFreeBufferArray(set, &rstat);
11497 SCIPsetFreeBufferArray(set, &cstat);
11498
11499 SCIPsetFreeBufferArray(set, &redcost);
11500 SCIPsetFreeBufferArray(set, &dualsol);
11501 if( chooseBasic )
11503
11504 /* stop timing */
11506
11507 SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with lex dual simplex (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
11508 stat->lpcount, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
11509 }
11511 lp->solisbasic = TRUE;
11512
11513 if( totalIterations > 0 && !lp->strongbranchprobing )
11514 SCIPstatIncrement(stat, set, nlps);
11515 else
11516 {
11517 if( keepsol && !(*lperror) )
11518 {
11519 /* the solution didn't change: if the solution was valid before resolve, it is still valid */
11520 if( lp->validsollp == stat->lpcount-1 )
11521 lp->validsollp = stat->lpcount;
11522 if( lp->validfarkaslp == stat->lpcount-1 )
11523 lp->validfarkaslp = stat->lpcount;
11524 }
11525 }
11526
11527 return SCIP_OKAY;
11528}
11529
11530/** calls LPI to perform barrier, measures time and counts iterations, gets basis feasibility status */
11531static
11533 SCIP_LP* lp, /**< current LP data */
11534 SCIP_SET* set, /**< global SCIP settings */
11535 SCIP_STAT* stat, /**< problem statistics */
11536 SCIP_Bool crossover, /**< should crossover be performed? */
11537 SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11538 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11539 )
11540{
11541 SCIP_Real timedelta;
11542 SCIP_RETCODE retcode;
11543 int iterations;
11544
11545 assert(lp != NULL);
11546 assert(lp->flushed);
11547 assert(set != NULL);
11548 assert(stat != NULL);
11549 assert(lperror != NULL);
11550
11551 SCIPsetDebugMsg(set, "solving LP %" SCIP_LONGINT_FORMAT " (%d cols, %d rows) with barrier%s (diving=%d, nbarrierlps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
11552 stat->lpcount+1, lp->ncols, lp->nrows, crossover ? "/crossover" : "", lp->diving || lp->probing,
11553 stat->nbarrierlps, stat->ndivinglps);
11554
11555 *lperror = FALSE;
11556
11557#ifdef SCIP_MORE_DEBUG /* for debugging: write all root node LP's */
11558 if( stat->nnodes == 1 && !lp->diving && !lp->probing )
11559 {
11560 char fname[SCIP_MAXSTRLEN];
11561 (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
11562 SCIP_CALL( SCIPlpWrite(lp, fname) );
11563 SCIPsetDebugMsg(set, "wrote LP to file <%s> (barrier, objlim=%.15g, feastol=%.15g/%.15g, convtol=%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
11564 fname, lp->lpiobjlim, lp->lpifeastol, lp->lpidualfeastol, lp->lpibarrierconvtol,
11566 }
11567#endif
11568
11569 /* start timing */
11570 if( lp->diving || lp->probing )
11571 {
11572 if( lp->strongbranchprobing )
11574 else
11576
11577 timedelta = 0.0; /* unused for diving or probing */
11578 }
11579 else
11580 {
11582 timedelta = -SCIPclockGetTime(stat->barrierlptime);
11583 }
11584
11585 /* call barrier algorithm */
11586 retcode = SCIPlpiSolveBarrier(lp->lpi, crossover);
11587 if( retcode == SCIP_LPERROR )
11588 {
11589 *lperror = TRUE;
11590 SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") barrier solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
11591 }
11592 else
11593 {
11594 SCIP_CALL( retcode );
11595 }
11597 lp->solisbasic = crossover;
11598
11599 /* stop timing */
11600 if( lp->diving || lp->probing )
11601 {
11602 if( lp->strongbranchprobing )
11604 else
11606 }
11607 else
11608 {
11610 timedelta += SCIPclockGetTime(stat->barrierlptime);
11611 }
11612
11613 /* count number of iterations */
11614 SCIPstatIncrement(stat, set, lpcount);
11615 SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
11616 if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
11617 {
11618 if( !lp->strongbranchprobing )
11619 {
11620 SCIPstatIncrement(stat, set, nlps);
11621 SCIPstatAdd(stat, set, nlpiterations, iterations);
11622 }
11623 if( lp->diving || lp->probing )
11624 {
11625 if( lp->strongbranchprobing )
11626 {
11627 SCIPstatIncrement(stat, set, nsbdivinglps);
11628 SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
11629 }
11630 else
11631 {
11632 SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
11633 SCIPstatIncrement(stat, set, ndivinglps);
11634 SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
11635 }
11636 }
11637 else
11638 {
11639 SCIPstatIncrement(stat, set, nbarrierlps);
11640 SCIPstatAdd(stat, set, nbarrierlpiterations, iterations);
11641 }
11642 }
11643 else
11644 {
11645 if ( ! lp->diving && ! lp->probing )
11646 {
11647 SCIPstatIncrement(stat, set, nbarrierzeroitlps);
11648 SCIPstatAdd(stat, set, barrierzeroittime, timedelta);
11649 }
11650
11651 if( keepsol && !(*lperror) )
11652 {
11653 /* the solution didn't change: if the solution was valid before resolve, it is still valid */
11654 if( lp->validsollp == stat->lpcount-1 )
11655 lp->validsollp = stat->lpcount;
11656 if( lp->validfarkaslp == stat->lpcount-1 )
11657 lp->validfarkaslp = stat->lpcount;
11658 }
11659 }
11660
11661 SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with barrier%s (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", nbarrierlps=%" SCIP_LONGINT_FORMAT ")\n",
11662 stat->lpcount, crossover ? "/crossover" : "", lp->diving || lp->probing, stat->nbarrierlps, stat->ndivinglps);
11663
11664 return SCIP_OKAY;
11665}
11666
11667/** solves the LP with the given algorithm */
11668static
11670 SCIP_LP* lp, /**< current LP data */
11671 SCIP_SET* set, /**< global SCIP settings */
11672 SCIP_STAT* stat, /**< problem statistics */
11673 SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11674 SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
11675 SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11676 SCIP_Bool instable, /**< is this a resolving call to avoid instable LPs? */
11677 SCIP_Bool* timelimit, /**< pointer to store whether the time limit was hit */
11678 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11679 )
11680{
11681 SCIP_Real lptimelimit;
11682 SCIP_Bool success;
11683
11684 assert(lp != NULL);
11685 assert(lp->flushed);
11686 assert(lperror != NULL);
11687
11688 /* check if a time limit is set, and set time limit for LP solver accordingly */
11689 lptimelimit = SCIPlpiInfinity(lp->lpi);
11690 if( set->istimelimitfinite )
11691 lptimelimit = set->limit_time - SCIPclockGetTime(stat->solvingtime);
11692
11693 success = FALSE;
11694 if( lptimelimit > 0.0 )
11695 SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_LPTILIM, lptimelimit, &success) );
11696
11697 if( lptimelimit <= 0.0 || !success )
11698 {
11699 SCIPsetDebugMsg(set, "time limit of %f seconds could not be set\n", lptimelimit);
11700 *lperror = ((lptimelimit > 0.0) ? TRUE : FALSE);
11701 *timelimit = TRUE;
11702 return SCIP_OKAY;
11703 }
11704 SCIPsetDebugMsg(set, "calling LP algorithm <%s> with a time limit of %g seconds\n", lpalgoName(lpalgo), lptimelimit);
11705
11706 /* call appropriate LP algorithm */
11707 switch( lpalgo )
11708 {
11710 SCIP_CALL( lpPrimalSimplex(lp, set, stat, resolve, keepsol, instable, lperror) );
11711 break;
11712
11714 /* run dual lexicographic simplex if required */
11715 if( set->lp_lexdualalgo && (!set->lp_lexdualrootonly || stat->maxdepth == 0) && (!set->lp_lexdualstalling || lp->installing) )
11716 {
11717 SCIP_CALL( lpLexDualSimplex(lp, set, stat, resolve, keepsol, lperror) );
11718 }
11719 else
11720 {
11721 SCIP_CALL( lpDualSimplex(lp, set, stat, resolve, keepsol, instable, lperror) );
11722 }
11723 break;
11724
11726 SCIP_CALL( lpBarrier(lp, set, stat, FALSE, keepsol, lperror) );
11727 break;
11728
11730 SCIP_CALL( lpBarrier(lp, set, stat, TRUE, keepsol, lperror) );
11731 break;
11732
11733 default:
11734 SCIPerrorMessage("invalid LP algorithm\n");
11735 return SCIP_INVALIDDATA;
11736 }
11737
11738 if( !(*lperror) )
11739 {
11740 /* check for primal and dual feasibility */
11742
11743 SCIPsetDebugMsg(set, "LP feasibility: primalfeasible=%u, dualfeasible=%u\n", lp->primalfeasible, lp->dualfeasible);
11744 }
11745
11746 return SCIP_OKAY;
11747}
11748
11749/** maximal number of verblevel-high messages about numerical trouble in LP that will be printed
11750 * when this number is reached and display/verblevel is not full, then further messages are suppressed in this run
11751 */
11752#define MAXNUMTROUBLELPMSGS 10
11753
11754/** prints message about numerical trouble
11755 *
11756 * If message has verblevel at most high and display/verblevel is not full,
11757 * then the message is not printed if already MAXNUMTROUBLELPMSGS messages
11758 * were printed before in the current run.
11759 */
11760static
11762 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11763 SCIP_SET* set, /**< global SCIP settings */
11764 SCIP_STAT* stat, /**< problem statistics */
11765 SCIP_VERBLEVEL verblevel, /**< verbosity level of message */
11766 const char* formatstr, /**< message format string */
11767 ... /**< arguments to format string */
11768 )
11769{
11770 va_list ap;
11771
11772 assert(verblevel > SCIP_VERBLEVEL_NONE);
11773 assert(verblevel <= SCIP_VERBLEVEL_FULL);
11774 assert(set->disp_verblevel <= SCIP_VERBLEVEL_FULL);
11775
11776 if( set->disp_verblevel < SCIP_VERBLEVEL_FULL )
11777 {
11778 if( verblevel <= SCIP_VERBLEVEL_HIGH )
11779 {
11780 /* if already max number of messages about numerical trouble in LP on verblevel at most high, then skip message */
11782 return;
11783
11784 /* increase count on messages with verblevel high */
11785 ++stat->nnumtroublelpmsgs ;
11786 }
11787
11788 /* if messages wouldn't be printed, then return already */
11789 if( verblevel > set->disp_verblevel )
11790 return;
11791 }
11792
11793 /* print common begin of message */
11794 SCIPmessagePrintInfo(messagehdlr,
11795 "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- ",
11796 stat->nnodes, stat->nlps);
11797
11798 /* print individual part of message */
11799 va_start(ap, formatstr); /*lint !e838*/
11800 SCIPmessageVFPrintInfo(messagehdlr, NULL, formatstr, ap);
11801 va_end(ap);
11802
11803 /* warn that further messages will be suppressed */
11804 if( set->disp_verblevel < SCIP_VERBLEVEL_FULL && verblevel <= SCIP_VERBLEVEL_HIGH && stat->nnumtroublelpmsgs > MAXNUMTROUBLELPMSGS )
11805 {
11806 SCIPmessagePrintInfo(messagehdlr, " -- further messages will be suppressed (use display/verblevel=5 to see all)");
11807 }
11808
11809 /* print closing new-line */
11810 SCIPmessagePrintInfo(messagehdlr, "\n");
11811}
11812
11813static
11815 SCIP_LP* lp, /**< current LP data */
11816 SCIP_SET* set, /**< global SCIP settings */
11817 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11818 SCIP_STAT* stat, /**< problem statistics */
11819 SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11820 SCIP_Bool* success /**< was instability successfully ignored */
11821 )
11822{
11823 assert(lp != NULL);
11824 assert(set != NULL);
11825
11826 SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, success) );
11827
11828 if( *success )
11829 {
11830 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11831 if( !set->lp_checkdualfeas )
11832 lp->dualfeasible = TRUE;
11833 if( !set->lp_checkprimfeas )
11834 lp->primalchecked = TRUE;
11835 }
11836
11837 return SCIP_OKAY;
11838}
11839
11840#define FEASTOLTIGHTFAC 0.001
11841/** solves the LP with the given LP algorithm, and tries to resolve numerical problems */
11842static
11844 SCIP_LP* lp, /**< current LP data */
11845 SCIP_SET* set, /**< global SCIP settings */
11846 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11847 SCIP_STAT* stat, /**< problem statistics */
11848 SCIP_PROB* prob, /**< problem data */
11849 SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11850 int itlim, /**< maximal number of LP iterations to perform in first LP calls (before solving from scratch), or -1 for no limit */
11851 int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
11852 SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
11853 int fastmip, /**< which FASTMIP setting of LP solver should be used? */
11854 SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
11855 SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
11856 SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
11857 int scaling, /**< LP scaling (0: none, 1: normal, 2: aggressive) */
11858 SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11859 SCIP_Bool* timelimit, /**< pointer to store whether the time limit was hit */
11860 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11861 )
11862{
11863 SCIP_Bool success;
11864 SCIP_Bool success2;
11865 SCIP_Bool success3;
11866 SCIP_Bool simplex;
11867 SCIP_Bool itlimishard;
11868 SCIP_Bool usepolishing;
11869
11870 assert(lp != NULL);
11871 assert(lp->flushed);
11872 assert(set != NULL);
11873 assert(stat != NULL);
11874 assert(lperror != NULL);
11875 assert(timelimit != NULL);
11876
11877 *lperror = FALSE;
11878
11879 /**@todo implement solving the LP when loose variables with infinite best bound are present; for this, we need to
11880 * solve with deactivated objective limit in order to determine whether we are (a) infeasible or (b) feasible
11881 * and hence unbounded; to handle case (b) we need to store an array of loose variables with best bound in
11882 * SCIP_LP such that we can return a primal ray
11883 */
11884 if( lp->looseobjvalinf > 0 )
11885 {
11886 SCIPerrorMessage("cannot solve LP when loose variable with infinite best bound is present\n");
11887 return SCIP_ERROR;
11888 }
11889
11890 /* check, whether we solve with a simplex algorithm */
11891 simplex = (lpalgo == SCIP_LPALGO_PRIMALSIMPLEX || lpalgo == SCIP_LPALGO_DUALSIMPLEX);
11892
11893 /* check whether the iteration limit is a hard one */
11894 itlimishard = (itlim == harditlim);
11895
11896 /* check whether solution polishing should be used */
11897 if( lp->lpihaspolishing && (set->lp_solutionpolishing == 2 || (set->lp_solutionpolishing == 1 && stat->nnodes == 1 && !lp->probing)
11898 || (set->lp_solutionpolishing == 3 && ((lp->probing && !lp->strongbranchprobing) || lp->diving))) )
11899 {
11900 usepolishing = TRUE;
11901 if( lp->updateintegrality )
11902 {
11904 }
11905 }
11906 else
11907 usepolishing = FALSE;
11908
11909 /* solve with given settings (usually fast but imprecise) */
11911 {
11912 SCIP_CALL( lpSetObjlim(lp, set, prob, lp->cutoffbound, &success) );
11913 }
11914 else
11915 {
11916 SCIP_CALL( lpSetObjlim(lp, set, prob, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob), &success) );
11917 SCIP_CALL( lpAdjustObjlimForExactSolve(lp, set, prob, stat, &success) );
11918 }
11919 SCIP_CALL( lpSetIterationLimit(lp, itlim) );
11920 SCIP_CALL( lpSetFeastol(lp, tightprimfeastol ? FEASTOLTIGHTFAC * lp->feastol : lp->feastol, &success) );
11922 &success) );
11923 SCIP_CALL( lpSetBarrierconvtol(lp, (tightprimfeastol || tightdualfeastol) ? FEASTOLTIGHTFAC * SCIPsetBarrierconvtol(set)
11924 : SCIPsetBarrierconvtol(set), &success) );
11925 SCIP_CALL( lpSetFromscratch(lp, fromscratch, &success) );
11926 SCIP_CALL( lpSetFastmip(lp, fastmip, &success) );
11927 SCIP_CALL( lpSetScaling(lp, scaling, &success) );
11928 SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11929 SCIP_CALL( lpSetRowrepswitch(lp, set->lp_rowrepswitch, &success) );
11930 SCIP_CALL( lpSetPricingChar(lp, set->lp_pricing) );
11931 SCIP_CALL( lpSetThreads(lp, set->lp_threads, &success) );
11932 SCIP_CALL( lpSetLPInfo(lp, set->disp_lpinfo) );
11933 SCIP_CALL( lpSetConditionLimit(lp, set->lp_conditionlimit, &success) );
11934 SCIP_CALL( lpSetMarkowitz(lp, set->lp_markowitz, &success) );
11935 SCIP_CALL( lpSetTiming(lp, set->time_clocktype, set->time_enabled, &success) );
11936 SCIP_CALL( lpSetRandomseed(lp, (int) (SCIPsetInitializeRandomSeed(set, (unsigned) set->random_randomseed) % INT_MAX), &success) );
11937 SCIP_CALL( lpSetSolutionPolishing(lp, usepolishing, &success) );
11938 SCIP_CALL( lpSetRefactorInterval(lp, set->lp_refactorinterval, &success) );
11939
11940 SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, FALSE, timelimit, lperror) );
11941
11942 /* after the first solve, do not use starting basis, since otherwise the solver will probably think the basis is
11943 * optimal without preforming scaling/change tolerances/presolving */
11944 resolve = FALSE;
11945
11946 /* check for stability; iteration limit exceeded is also treated like instability if the iteration limit is soft */
11947 if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11948 return SCIP_OKAY;
11949
11950 if( !set->lp_checkstability )
11951 {
11952 SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11953
11954 if( success )
11955 return SCIP_OKAY;
11956 }
11957
11958 /* In the following, whenever the LP iteration limit is exceeded in an LP solving call, we leave out the
11959 * remaining resolving calls with changed settings and go directly to solving the LP from scratch.
11960 */
11961
11962 /* if FASTMIP is turned on, solve again without FASTMIP (starts from the solution of the last LP solving call);
11963 * do this only if the iteration limit was not exceeded in the last LP solving call
11964 */
11965 if( fastmip > 0 && simplex && ((*lperror) || !SCIPlpiIsIterlimExc(lp->lpi)) )
11966 {
11967 SCIP_CALL( lpSetFastmip(lp, 0, &success) );
11968 if( success )
11969 {
11970 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s without FASTMIP", lpalgoName(lpalgo));
11971 SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11972
11973 /* check for stability */
11974 if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11975 return SCIP_OKAY;
11976
11977 if( !set->lp_checkstability )
11978 {
11979 SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11980
11981 if( success )
11982 return SCIP_OKAY;
11983 }
11984 }
11985 }
11986
11987 /* if the iteration limit was exceeded in the last LP solving call, we leave out the remaining resolving calls with changed settings
11988 * and go directly to solving the LP from scratch
11989 */
11990 if( (*lperror) || !SCIPlpiIsIterlimExc(lp->lpi) )
11991 {
11992 /* solve again with opposite scaling setting (starts from the solution of the last LP solving call) */
11993 SCIP_CALL( lpSetScaling(lp, (scaling > 0) ? 0 : 1, &success) );
11994 if( success )
11995 {
11996 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s %s scaling",
11997 lpalgoName(lpalgo), (scaling == 0) ? "with" : "without");
11998 SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11999
12000 /* check for stability */
12001 if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
12002 return SCIP_OKAY;
12003
12004 if( !set->lp_checkstability )
12005 {
12006 SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
12007
12008 if( success )
12009 return SCIP_OKAY;
12010 }
12011
12012 /* reset scaling */
12013 SCIP_CALL( lpSetScaling(lp, scaling, &success) );
12014 assert(success);
12015 }
12016 }
12017
12018 /* if the iteration limit was exceeded in the last LP solving call, we leave out the remaining resolving calls with changed settings
12019 * and go directly to solving the LP from scratch */
12020 if( (*lperror) || !SCIPlpiIsIterlimExc(lp->lpi) )
12021 {
12022 /* solve again with opposite presolving setting (starts from the solution of the last LP solving call) */
12023 SCIP_CALL( lpSetPresolving(lp, !set->lp_presolving, &success) );
12024 if( success )
12025 {
12026 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s %s presolving",
12027 lpalgoName(lpalgo), !set->lp_presolving ? "with" : "without");
12028 SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
12029
12030 /* check for stability */
12031 if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
12032 return SCIP_OKAY;
12033
12034 if( !set->lp_checkstability )
12035 {
12036 SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
12037
12038 if( success )
12039 return SCIP_OKAY;
12040 }
12041
12042 /* reset presolving */
12043 SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
12044 assert(success);
12045 }
12046 }
12047
12048 /* solve again with a tighter feasibility tolerance (starts from the solution of the last LP solving call);
12049 * do this only if the iteration limit was not exceeded in the last LP solving call
12050 */
12051 if( ((simplex && (!tightprimfeastol || !tightdualfeastol)) || (!tightprimfeastol && !tightdualfeastol)) &&
12052 ((*lperror) || !SCIPlpiIsIterlimExc(lp->lpi)) )
12053 {
12054 success = FALSE;
12055 if( !tightprimfeastol )
12056 {
12057 SCIP_CALL( lpSetFeastol(lp, FEASTOLTIGHTFAC * lp->feastol, &success) );
12058 }
12059
12060 success2 = FALSE;
12061 if( !tightdualfeastol )
12062 {
12064 }
12065
12066 success3 = FALSE;
12067 if( !simplex && !tightprimfeastol && !tightdualfeastol )
12068 {
12070 }
12071
12072 /* only resolve if at least one of the parameters was actually changed in the LP solver */
12073 if( success || success2 || success3 )
12074 {
12075 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s with tighter primal and dual feasibility tolerance",
12076 lpalgoName(lpalgo));
12077 SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
12078
12079 /* check for stability */
12080 if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
12081 return SCIP_OKAY;
12082
12083 if( !set->lp_checkstability )
12084 {
12085 SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
12086
12087 if( success )
12088 return SCIP_OKAY;
12089 }
12090
12091 /* reset feasibility tolerance */
12092 if( !tightprimfeastol )
12093 {
12094 SCIP_CALL( lpSetFeastol(lp, lp->feastol, &success) );
12095 }
12096 if( !tightdualfeastol )
12097 {
12099 }
12100 if( !simplex && !tightprimfeastol && !tightdualfeastol )
12101 {
12103 }
12104 }
12105 }
12106
12107 /* all LPs solved after this point are solved from scratch, so set the LP iteration limit to the hard limit;
12108 * the given iteration limit might be a soft one to restrict resolving calls only */
12109 SCIP_CALL( lpSetIterationLimit(lp, harditlim) );
12110
12111 /* if not already done, solve again from scratch */
12112 if( !fromscratch && simplex )
12113 {
12114 SCIP_CALL( lpSetFromscratch(lp, TRUE, &success) );
12115 if( success )
12116 {
12117 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s", lpalgoName(lpalgo));
12118 SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
12119
12120 /* check for stability */
12121 if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
12122 return SCIP_OKAY;
12123
12124 if( !set->lp_checkstability )
12125 {
12126 SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
12127
12128 if( success )
12129 return SCIP_OKAY;
12130 }
12131 }
12132 }
12133
12134 /* solve again, use other simplex this time */
12135 if( simplex )
12136 {
12138 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s", lpalgoName(lpalgo));
12139 SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
12140
12141 /* check for stability */
12142 if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
12143 return SCIP_OKAY;
12144
12145 if( !set->lp_checkstability )
12146 {
12147 SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
12148
12149 if( success )
12150 return SCIP_OKAY;
12151 }
12152
12153 /* solve again with opposite scaling and other simplex */
12154 SCIP_CALL( lpSetScaling(lp, (scaling > 0) ? 0 : 1, &success) );
12155 if( success )
12156 {
12157 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s %s scaling",
12158 lpalgoName(lpalgo), (scaling == 0) ? "with" : "without");
12159 SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
12160
12161 /* check for stability */
12162 if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
12163 return SCIP_OKAY;
12164
12165 if( !set->lp_checkstability )
12166 {
12167 SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
12168
12169 if( success )
12170 return SCIP_OKAY;
12171 }
12172
12173 /* reset scaling */
12174 SCIP_CALL( lpSetScaling(lp, scaling, &success) );
12175 assert(success);
12176 }
12177
12178 /* solve again with opposite presolving and other simplex */
12179 SCIP_CALL( lpSetPresolving(lp, !set->lp_presolving, &success) );
12180 if( success )
12181 {
12182 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s %s presolving",
12183 lpalgoName(lpalgo), !set->lp_presolving ? "with" : "without");
12184 SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
12185
12186 /* check for stability */
12187 if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
12188 return SCIP_OKAY;
12189
12190 if( !set->lp_checkstability )
12191 {
12192 SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
12193
12194 if( success )
12195 return SCIP_OKAY;
12196 }
12197
12198 /* reset presolving */
12199 SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
12200 assert(success);
12201 }
12202
12203 /* solve again with tighter feasibility tolerance, use other simplex this time */
12204 if( !tightprimfeastol || !tightdualfeastol )
12205 {
12206 success = FALSE;
12207 if( !tightprimfeastol )
12208 {
12209 SCIP_CALL( lpSetFeastol(lp, FEASTOLTIGHTFAC * lp->feastol, &success) );
12210 }
12211
12212 success2 = FALSE;
12213 if( !tightdualfeastol )
12214 {
12216 }
12217
12218 /* only resolve if at least one of the parameters was actually changed in the LP solver */
12219 if( success || success2 )
12220 {
12221 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s with tighter feasibility tolerance",
12222 lpalgoName(lpalgo));
12223 SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
12224
12225 /* check for stability */
12226 if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
12227 return SCIP_OKAY;
12228
12229 if( !set->lp_checkstability )
12230 {
12231 SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
12232
12233 if( success )
12234 return SCIP_OKAY;
12235 }
12236
12237 /* reset feasibility tolerance */
12238 if( !tightprimfeastol )
12239 {
12240 SCIP_CALL( lpSetFeastol(lp, lp->feastol, &success) );
12241 }
12242 if( !tightdualfeastol )
12243 {
12245 }
12246 SCIP_UNUSED(success);
12247 }
12248 }
12249 }
12250
12251 /* nothing worked -- exit with an LPERROR */
12252 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_HIGH, "unresolved");
12253 *lperror = TRUE;
12254
12255 return SCIP_OKAY;
12256}
12257
12258/** adjust the LP objective value if it is greater/less than +/- SCIPsetInfinity() */
12259static
12261 SCIP_LP* lp, /**< current LP data */
12262 SCIP_SET* set, /**< global SCIP settings */
12263 SCIP_MESSAGEHDLR* messagehdlr /**< message handler */
12264 )
12265{
12266 assert(lp != NULL);
12267 assert(set != NULL);
12268
12269 if( SCIPsetIsInfinity(set, lp->lpobjval) && lp->lpobjval != SCIPsetInfinity(set) ) /*lint !e777*/
12270 {
12271 if( !lp->adjustlpval && messagehdlr != NULL )
12272 {
12273 SCIPmessagePrintWarning(messagehdlr, "LP solution value is above SCIP's infinity value\n");
12274 lp->adjustlpval = TRUE;
12275 }
12277 }
12278 else if( SCIPsetIsInfinity(set, -lp->lpobjval) && lp->lpobjval != -SCIPsetInfinity(set) ) /*lint !e777*/
12279 {
12280 if( !lp->adjustlpval && messagehdlr != NULL )
12281 {
12282 SCIPmessagePrintWarning(messagehdlr, "LP solution value is below SCIP's -infinity value\n");
12283 lp->adjustlpval = TRUE;
12284 }
12286 }
12287}
12288
12289/** solves the LP with the given algorithm and evaluates return status */
12290static
12292 SCIP_LP* lp, /**< current LP data */
12293 SCIP_SET* set, /**< global SCIP settings */
12294 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
12295 SCIP_STAT* stat, /**< problem statistics */
12296 SCIP_PROB* prob, /**< problem data */
12297 SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
12298 int resolveitlim, /**< maximal number of LP iterations to perform in resolving calls, or -1 for no limit */
12299 int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
12300 SCIP_Bool needprimalray, /**< if the LP is unbounded, do we need a primal ray? */
12301 SCIP_Bool needdualray, /**< if the LP is infeasible, do we need a dual ray? */
12302 SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
12303 int fastmip, /**< which FASTMIP setting of LP solver should be used? */
12304 SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
12305 SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
12306 SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
12307 int scaling, /**< LP scaling (0: none, 1: normal, 2: aggressive) */
12308 SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
12309 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
12310 )
12311{
12312 SCIP_Bool solvedprimal;
12313 SCIP_Bool solveddual;
12314 SCIP_Bool timelimit;
12315 int itlim;
12316
12317 assert(lp != NULL);
12318 assert(lp->flushed);
12319 assert(set != NULL);
12320 assert(stat != NULL);
12321 assert(lperror != NULL);
12322
12323 checkLinks(lp);
12324
12325 solvedprimal = FALSE;
12326 solveddual = FALSE;
12327 timelimit = FALSE;
12328
12329 /* select the basic iteration limit depending on whether this is a resolving call or not */
12330 itlim = ( resolve ? resolveitlim : harditlim );
12331
12332 SOLVEAGAIN:
12333 /* call simplex */
12334 SCIP_CALL( lpSolveStable(lp, set, messagehdlr, stat, prob, lpalgo, itlim, harditlim, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch,
12335 scaling, keepsol, &timelimit, lperror) );
12336 resolve = FALSE; /* only the first solve should be counted as resolving call */
12337 solvedprimal = solvedprimal || (lp->lastlpalgo == SCIP_LPALGO_PRIMALSIMPLEX);
12338 solveddual = solveddual || (lp->lastlpalgo == SCIP_LPALGO_DUALSIMPLEX);
12339
12340 /* check, if an error occurred */
12341 if( *lperror )
12342 {
12343 SCIPsetDebugMsg(set, "unresolved error while solving LP with %s\n", lpalgoName(lp->lastlpalgo));
12344 lp->solved = FALSE;
12346 return SCIP_OKAY;
12347 }
12348
12349 /* check, if a time limit was exceeded */
12350 if( timelimit )
12351 {
12352 SCIPsetDebugMsg(set, "time limit exceeded before solving LP\n");
12353 lp->solved = TRUE;
12356 return SCIP_OKAY;
12357 }
12358
12359 /* only one should return true */
12362
12363 /* evaluate solution status */
12364 if( SCIPlpiIsOptimal(lp->lpi) )
12365 {
12367 assert(lp->dualfeasible);
12369 SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
12370 adjustLPobjval(lp, set, messagehdlr);
12371
12373 {
12374 /* the solver may return the optimal value, even if this is greater or equal than the upper bound */
12375 SCIPsetDebugMsg(set, "optimal solution %.15g exceeds objective limit %.15g\n", lp->lpobjval, lp->lpiobjlim);
12378 }
12379 /* if we did not disable the cutoff bound in the LP solver, the LP solution status should be objective limit
12380 * reached if the LP objective value is greater than the cutoff bound
12381 */
12382 assert(lpCutoffDisabled(set, prob, lp) || set->exact_enable || lp->lpsolstat == SCIP_LPSOLSTAT_OBJLIMIT
12384 || SCIPsetIsLE(set, lp->lpobjval + getFiniteLooseObjval(lp, set, prob), lp->cutoffbound));
12385 }
12386 else if( SCIPlpiIsObjlimExc(lp->lpi) )
12387 {
12388 assert(!lpCutoffDisabled(set, prob, lp));
12389
12390#ifndef NDEBUG
12391 /* the LP solution objective should exceed the limit in this case; if this assert is triggered, it typically means
12392 * that the LP interface method SCIPlpiIsStable() lacks a check for this event and incorrectly returned TRUE */
12393 SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
12394 assert(!set->lp_checkstability || SCIPsetIsRelGE(set, lp->lpobjval, lp->lpiobjlim));
12395#endif
12396
12399 }
12400 else if( SCIPlpiIsPrimalInfeasible(lp->lpi) )
12401 {
12402 /* because of numerical instability lpalgo != lp->lastlpalgo might happen - hence, we have to check both */
12403 if( needdualray && !SCIPlpiHasDualRay(lp->lpi) && !solveddual && lpalgo != SCIP_LPALGO_DUALSIMPLEX )
12404 {
12406 lpalgo = SCIP_LPALGO_DUALSIMPLEX;
12407 goto SOLVEAGAIN;
12408 }
12411 }
12412 else if( SCIPlpiExistsPrimalRay(lp->lpi) )
12413 {
12414 /* because of numerical instability lpalgo != lp->lastlpalgo might happen - hence, we have to check both */
12415 if( needprimalray && !SCIPlpiIsPrimalUnbounded(lp->lpi) && !solvedprimal && lpalgo != SCIP_LPALGO_PRIMALSIMPLEX )
12416 {
12417 /* unboundedness includes that the primal is feasible: ensure a primal solution here */
12420 goto SOLVEAGAIN;
12421 }
12424 }
12425 else if( SCIPlpiIsIterlimExc(lp->lpi) )
12426 {
12427 SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
12428
12429 /* The lpobjval might be infinite, e.g. if the LP solver was not able to produce a valid bound while reaching the
12430 iteration limit. In this case, we avoid the warning in adjustLPobjval() by setting the messagehdlr to NULL. */
12431 if ( REALABS(lp->lpobjval) == SCIPlpiInfinity(lp->lpi) ) /*lint !e777*/
12432 adjustLPobjval(lp, set, NULL);
12433 else
12434 adjustLPobjval(lp, set, messagehdlr);
12435
12437 }
12438 else if( SCIPlpiIsTimelimExc(lp->lpi) )
12439 {
12442 }
12443 else if( !solveddual && lpalgo != SCIP_LPALGO_DUALSIMPLEX)
12444 {
12446 lpalgo = SCIP_LPALGO_DUALSIMPLEX;
12447 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12448 "(node %" SCIP_LONGINT_FORMAT ") solution status of LP %" SCIP_LONGINT_FORMAT " could not be proven (internal status:%d) -- solve again with %s\n",
12449 stat->nnodes, stat->nlps, SCIPlpiGetInternalStatus(lp->lpi), lpalgoName(lpalgo));
12450 goto SOLVEAGAIN;
12451 }
12452 else if( !solvedprimal && lpalgo != SCIP_LPALGO_PRIMALSIMPLEX)
12453 {
12456 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12457 "(node %" SCIP_LONGINT_FORMAT ") solution status of LP %" SCIP_LONGINT_FORMAT " could not be proven (internal status:%d) -- solve again with %s\n",
12458 stat->nnodes, stat->nlps, SCIPlpiGetInternalStatus(lp->lpi), lpalgoName(lpalgo));
12459 goto SOLVEAGAIN;
12460 }
12461 else
12462 {
12463 SCIPerrorMessage("(node %" SCIP_LONGINT_FORMAT ") error or unknown return status of %s in LP %" SCIP_LONGINT_FORMAT " (internal status: %d)\n",
12464 stat->nnodes, lpalgoName(lp->lastlpalgo), stat->nlps, SCIPlpiGetInternalStatus(lp->lpi));
12466 return SCIP_LPERROR;
12467 }
12468
12469 lp->solved = TRUE;
12470
12471 SCIPsetDebugMsg(set, "solving LP with %s returned solstat=%d (internal status: %d, primalfeasible=%u, dualfeasible=%u)\n",
12474
12475 return SCIP_OKAY;
12476}
12477
12478/** flushes the LP and solves it with the primal or dual simplex algorithm, depending on the current basis feasibility */
12479static
12481 SCIP_LP* lp, /**< current LP data */
12482 BMS_BLKMEM* blkmem, /**< block memory */
12483 SCIP_SET* set, /**< global SCIP settings */
12484 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
12485 SCIP_STAT* stat, /**< problem statistics */
12486 SCIP_PROB* prob, /**< problem data */
12487 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
12488 int resolveitlim, /**< maximal number of LP iterations to perform in resolving calls, or -1 for no limit */
12489 int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
12490 SCIP_Bool needprimalray, /**< if the LP is unbounded, do we need a primal ray? */
12491 SCIP_Bool needdualray, /**< if the LP is infeasible, do we need a dual ray? */
12492 int fastmip, /**< which FASTMIP setting of LP solver should be used? */
12493 SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
12494 SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
12495 SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
12496 int scaling, /**< LP scaling (0: none, 1: normal, 2: aggressive) */
12497 SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
12498 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
12499 )
12500{
12501 SCIP_Bool resolve;
12502 char algo;
12503
12504 assert(lp != NULL);
12505 assert(set != NULL);
12506 assert(lperror != NULL);
12507
12508 /* flush changes to the LP solver */
12509 SCIP_CALL( SCIPlpFlush(lp, blkmem, set, prob, eventqueue) );
12510 fastmip = ((!lp->flushaddedcols && !lp->flushdeletedcols) ? fastmip : 0); /* turn off FASTMIP if columns were changed */
12511
12512 /* select LP algorithm to apply */
12513 resolve = lp->solisbasic && (lp->dualfeasible || lp->primalfeasible) && !fromscratch;
12514 algo = resolve ? set->lp_resolvealgorithm : set->lp_initalgorithm;
12515 lp->hasprovedbound = FALSE;
12516
12517 switch( algo )
12518 {
12519 case 's':
12520 /* select simplex method */
12521 if( lp->dualfeasible || !lp->primalfeasible )
12522 {
12523 SCIPsetDebugMsg(set, "solving dual LP\n");
12524 SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, resolveitlim, harditlim, needprimalray,
12525 needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
12526 }
12527 else
12528 {
12529 SCIPsetDebugMsg(set, "solving primal LP\n");
12530 SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_PRIMALSIMPLEX, resolveitlim, harditlim, needprimalray,
12531 needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
12532 }
12533 break;
12534
12535 case 'p':
12536 SCIPsetDebugMsg(set, "solving primal LP\n");
12537 SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_PRIMALSIMPLEX, resolveitlim, harditlim, needprimalray,
12538 needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
12539 break;
12540
12541 case 'd':
12542 SCIPsetDebugMsg(set, "solving dual LP\n");
12543 SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, resolveitlim, harditlim, needprimalray,
12544 needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
12545 break;
12546
12547 case 'b':
12548 SCIPsetDebugMsg(set, "solving barrier LP\n");
12549 SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_BARRIER, resolveitlim, harditlim, needprimalray,
12550 needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
12551 break;
12552
12553 case 'c':
12554 SCIPsetDebugMsg(set, "solving barrier LP with crossover\n");
12555 SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_BARRIERCROSSOVER, resolveitlim, harditlim, needprimalray,
12556 needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
12557 break;
12558
12559 default:
12560 SCIPerrorMessage("invalid parameter setting <%c> for LP algorithm\n", algo);
12562 }
12563 assert(!(*lperror) || !lp->solved);
12564
12565 return SCIP_OKAY;
12566}
12567
12568#ifndef NDEBUG
12569/** checks if the lazy bounds are valid */
12570static
12572 SCIP_LP* lp, /**< LP data */
12573 SCIP_SET* set /**< global SCIP settings */
12574 )
12575{
12576 SCIP_COL* col;
12577 int c;
12578
12579 assert(lp->flushed);
12580
12581 for( c = 0; c < lp->nlazycols; ++c )
12582 {
12583 col = lp->lazycols[c];
12584
12585 /* in case lazy bounds are given, check that the primal solution satisfies them */
12588 }
12589}
12590#else
12591#define checkLazyBounds(lp, set) /**/
12592#endif
12593
12594/** marks all lazy columns to be changed; this is needed for reloading/removing bounds of these columns before and after
12595 * diving
12596 */
12597static
12599 SCIP_LP* lp, /**< LP data */
12600 SCIP_SET* set /**< global SCIP settings */
12601 )
12602{
12603 SCIP_COL* col;
12604 int c;
12605
12606 assert(lp->nlazycols > 0);
12607
12608 /* return, if we are in diving, and bounds were already applied
12609 * or if we are not in diving and bounds were not applied
12610 */
12611 if( lp->diving == lp->divinglazyapplied )
12612 return SCIP_OKAY;
12613
12614 SCIPsetDebugMsg(set, "mark all lazy columns as changed in order to reload bounds (diving=%u, applied=%u)\n",
12615 lp->diving, lp->divinglazyapplied);
12616
12617 for( c = 0; c < lp->nlazycols; ++c )
12618 {
12619 col = lp->lazycols[c];
12620
12621 /* if the column has a lazy lower bound, mark its lower bounds as changed */
12622 if( !SCIPsetIsInfinity(set, -col->lazylb) )
12623 {
12624 assert((!(lp->divinglazyapplied)) || (col->flushedlb == col->lb) || col->lbchanged); /*lint !e777*/
12625 assert(lp->divinglazyapplied || SCIPsetIsGT(set, col->lb, col->lazylb)
12626 || (col->flushedlb == -SCIPlpiInfinity(lp->lpi)) || col->lbchanged); /*lint !e777*/
12627
12628 /* insert column in the chgcols list (if not already there) */
12629 SCIP_CALL( insertColChgcols(col, set, lp) );
12630
12631 /* mark bound change in the column */
12632 col->lbchanged = TRUE;
12633 }
12634
12635 /* if the column has a lazy upper bound, mark its upper bounds as changed */
12636 if( !SCIPsetIsInfinity(set, col->lazyub) )
12637 {
12638 assert((!(lp->divinglazyapplied)) || (col->flushedub == col->ub) || col->ubchanged); /*lint !e777*/
12639 assert(lp->divinglazyapplied || SCIPsetIsLT(set, col->ub, col->lazyub)
12640 || (col->flushedub == SCIPlpiInfinity(lp->lpi)) || col->ubchanged); /*lint !e777*/
12641
12642 /* insert column in the chgcols list (if not already there) */
12643 SCIP_CALL( insertColChgcols(col, set, lp) );
12644
12645 /* mark bound change in the column */
12646 col->ubchanged = TRUE;
12647 }
12648 }
12649
12650 /* update lp->divinglazyapplied flag: if we are in diving mode, we just applied the lazy bounds,
12651 * if not, we just removed them
12652 */
12653 lp->divinglazyapplied = lp->diving;
12654
12655 return SCIP_OKAY;
12656}
12657
12658/** returns the iteration limit for an LP resolving call */
12659static
12661 SCIP_SET* set, /**< global SCIP settings */
12662 SCIP_STAT* stat, /**< dynamic problem statistics */
12663 int itlim /**< hard iteration limit */
12664 )
12665{
12666 /* no limit set or average not yet reliable */
12667 if( (set->lp_resolveiterfac == -1) || stat->nlps - stat->nrootlps < 5 )
12668 return itlim;
12669 /* set itlim to INT_MAX if it is -1 to reduce the number of cases to be regarded in the following */
12670 if( itlim == -1 )
12671 itlim = INT_MAX;
12672 /* return resolveiterfac * average iteration number per call after root, but at least resolveitermin and at most the hard iteration limit */
12673 return (int) MIN(itlim, MAX(set->lp_resolveitermin, \
12674 (set->lp_resolveiterfac * (stat->nlpiterations - stat->nrootlpiterations) / (SCIP_Real)(stat->nlps - stat->nrootlps))));
12675}
12676
12677
12678
12679/** solves the LP with simplex algorithm, and copy the solution into the column's data */
12681 SCIP_LP* lp, /**< LP data */
12682 SCIP_SET* set, /**< global SCIP settings */
12683 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
12684 BMS_BLKMEM* blkmem, /**< block memory buffers */
12685 SCIP_STAT* stat, /**< problem statistics */
12686 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
12687 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
12688 SCIP_PROB* prob, /**< problem data */
12689 SCIP_Longint itlim, /**< maximal number of LP iterations to perform, or -1 for no limit */
12690 SCIP_Bool limitresolveiters, /**< should LP iterations for resolving calls be limited?
12691 * (limit is computed within the method w.r.t. the average LP iterations) */
12692 SCIP_Bool aging, /**< should aging and removal of obsolete cols/rows be applied? */
12693 SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
12694 SCIP_Bool forcedlpsolve, /**< would SCIP abort if the LP is not solved? */
12695 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
12696 )
12697{
12698 SCIP_RETCODE retcode;
12699 SCIP_Bool needprimalray;
12700 SCIP_Bool needdualray;
12701 int harditlim;
12702 int resolveitlim;
12703
12704 assert(lp != NULL);
12705 assert(prob != NULL);
12706 assert(prob->nvars >= lp->ncols);
12707 assert(lperror != NULL);
12708
12709 retcode = SCIP_OKAY;
12710 *lperror = FALSE;
12711
12712 if( lp->flushed && lp->solved )
12713 {
12714 SCIPsetDebugMsg(set, "skipping LP solve: already flushed and solved)\n");
12715 return SCIP_OKAY;
12716 }
12717
12718 SCIPsetDebugMsg(set, "solving LP: %d rows, %d cols, primalfeasible=%u, dualfeasible=%u, solved=%u, diving=%u, probing=%u, cutoffbnd=%g\n",
12719 lp->nrows, lp->ncols, lp->primalfeasible, lp->dualfeasible, lp->solved, lp->diving, lp->probing, lp->cutoffbound);
12720
12721 /* check whether we need a proof of unboundedness or infeasibility by a primal or dual ray */
12722 needprimalray = TRUE;
12723 needdualray = (!SCIPprobAllColsInLP(prob, set, lp) || set->exact_enable || (set->conf_enable && set->conf_useinflp != 'o'));
12724
12725 /* compute the limit for the number of LP resolving iterations, if needed (i.e. if limitresolveiters == TRUE) */
12726 harditlim = (int) MIN(itlim, INT_MAX);
12727 resolveitlim = ( limitresolveiters ? lpGetResolveItlim(set, stat, harditlim) : harditlim );
12728 assert(harditlim == -1 || (resolveitlim <= harditlim));
12729
12730 /* if there are lazy bounds, check whether the bounds should explicitly be put into the LP (diving was started)
12731 * or removed from the LP (diving was ended)
12732 */
12733 if( lp->nlazycols > 0 )
12734 {
12735 /* @todo avoid loosing primal feasibility here after changing the objective already did destroy dual feasibility;
12736 * first resolve LP?
12737 */
12739 assert(lp->diving == lp->divinglazyapplied);
12740 }
12741
12742 /* flush changes to the LP solver */
12743 SCIP_CALL( SCIPlpFlush(lp, blkmem, set, prob, eventqueue) );
12744 assert(lp->flushed);
12745
12746 /* if the time limit was reached in the last call and the LP did not change, lp->solved is set to TRUE, but we want
12747 * to run again anyway, since there seems to be some time left / the time limit was increased
12748 */
12749 if( !lp->solved || (lp->lpsolstat == SCIP_LPSOLSTAT_TIMELIMIT && stat->status != SCIP_STATUS_TIMELIMIT) )
12750 {
12751 SCIP_Bool* primalfeaspointer;
12752 SCIP_Bool* dualfeaspointer;
12753 SCIP_Bool primalfeasible;
12754 SCIP_Bool dualfeasible;
12755 SCIP_Bool farkasvalid;
12756 SCIP_Bool rayfeasible;
12757 SCIP_Bool tightprimfeastol;
12758 SCIP_Bool tightdualfeastol;
12759 SCIP_Bool fromscratch;
12760 SCIP_Bool wasfromscratch;
12761 int scaling;
12762 SCIP_Longint oldnlps;
12763 int fastmip;
12764
12765 /* set initial LP solver settings */
12766 fastmip = ((lp->lpihasfastmip && !lp->flushaddedcols && !lp->flushdeletedcols && stat->nnodes > 1) ? set->lp_fastmip : 0);
12767 tightprimfeastol = FALSE;
12768 tightdualfeastol = FALSE;
12769 fromscratch = FALSE;
12770 primalfeasible = FALSE;
12771 dualfeasible = FALSE;
12772 wasfromscratch = (stat->nlps == 0);
12773 scaling = set->lp_scaling;
12774
12775 SOLVEAGAIN:
12776 /* solve the LP */
12777 oldnlps = stat->nlps;
12778 SCIP_CALL( lpFlushAndSolve(lp, blkmem, set, messagehdlr, stat, prob, eventqueue, resolveitlim, harditlim, needprimalray,
12779 needdualray, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
12780 SCIPsetDebugMsg(set, "lpFlushAndSolve() returned solstat %d (error=%u)\n", SCIPlpGetSolstat(lp), *lperror);
12781 assert(!(*lperror) || !lp->solved);
12782
12783 /* check for error */
12784 if( *lperror )
12785 {
12786 retcode = SCIP_OKAY;
12787 goto TERMINATE;
12788 }
12789
12790 /* compute safe bound might change the solstat so we have to compute it before we evaluate the solution status */
12792 {
12794 SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat, FALSE, &farkasvalid) );
12795 else
12796 SCIP_CALL( SCIPlpGetSol(lp, set, stat, &primalfeasible, &dualfeasible) );
12797
12798 /* in objlimit case, the lp objval is set to infinity, get the real objval to correct */
12800 {
12801 SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
12802 }
12803
12804 SCIP_CALL( SCIPlpExactComputeSafeBound(lp, lp->lpexact, set, messagehdlr, blkmem, stat, eventqueue,
12805 prob, lperror, SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_INFEASIBLE, &(lp->lpobjval), &primalfeasible, &dualfeasible ) );
12806
12807 /* handle error case in objlimit */
12808 if( SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OBJLIMIT && !lp->hasprovedbound && !(lp->probing || lp->diving) )
12809 {
12810 /* if safe bounding did fail, we have not managed to get a dual bound exceeding the cutoffbound, therefore just disable cutoffbound
12811 * and resolve the lp with another bounding step */
12813 lp->cutoffbound = SCIPlpiInfinity(lp->lpi);
12814 goto SOLVEAGAIN;
12815 }
12816 /* restore the old cutoffbound if it was disabled prior and reset the saved value to inf */
12818 {
12821 }
12822
12823 /* check for error */
12824 if( *lperror )
12825 {
12826 retcode = SCIP_OKAY;
12827 goto TERMINATE;
12828 }
12829 }
12830
12831 /* evaluate solution status */
12832 switch( SCIPlpGetSolstat(lp) )
12833 {
12835 /* get LP solution and possibly check the solution's feasibility again */
12836 if( set->lp_checkprimfeas )
12837 {
12838 primalfeaspointer = &primalfeasible;
12839 lp->primalchecked = TRUE;
12840 }
12841 else
12842 {
12843 /* believe in the primal feasibility of the LP solution */
12844 primalfeasible = TRUE;
12845 primalfeaspointer = NULL;
12846 lp->primalchecked = FALSE;
12847 }
12848 if( set->lp_checkdualfeas )
12849 {
12850 dualfeaspointer = &dualfeasible;
12851 lp->dualchecked = TRUE;
12852 }
12853 else
12854 {
12855 /* believe in the dual feasibility of the LP solution */
12856 dualfeasible = TRUE;
12857 dualfeaspointer = NULL;
12858 lp->dualchecked = FALSE;
12859 }
12860
12861 if( !set->exact_enable )
12862 {
12863 SCIP_CALL( SCIPlpGetSol(lp, set, stat, primalfeaspointer, dualfeaspointer) );
12864 }
12865
12866 /* in debug mode, check that lazy bounds (if present) are not violated */
12867 checkLazyBounds(lp, set);
12868
12869 if( primalfeasible && dualfeasible && aging && !lp->diving && stat->nlps > oldnlps )
12870 {
12871 /* update ages and remove obsolete columns and rows from LP */
12872 SCIP_CALL( SCIPlpUpdateAges(lp, stat) );
12873 if( stat->nlps % ((set->lp_rowagelimit+1)/2 + 1) == 0 ) /*lint !e776*/
12874 {
12875 SCIP_CALL( SCIPlpRemoveNewObsoletes(lp, blkmem, set, stat, eventqueue, eventfilter) );
12876 }
12877
12878 if( !lp->solved )
12879 {
12880 /* resolve LP after removing obsolete columns and rows */
12881 SCIPsetDebugMsg(set, "removed obsoletes - resolve LP again: %d rows, %d cols\n", lp->nrows, lp->ncols);
12882 aging = FALSE; /* to prevent infinite loops */
12883 goto SOLVEAGAIN;
12884 }
12885 }
12886 if( !primalfeasible || !dualfeasible )
12887 {
12889
12890 if( set->exact_enable && lp->lpexact->wasforcedsafebound )
12892
12893 if( (fastmip > 0) && simplex )
12894 {
12895 /* solution is infeasible (this can happen due to numerical problems): solve again without FASTMIP */
12896 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12897 "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, dfeas=%u) -- solving again without FASTMIP\n",
12898 stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12899 fastmip = 0;
12900 goto SOLVEAGAIN;
12901 }
12902 else if( (!primalfeasible && !tightprimfeastol) || (!dualfeasible && !tightdualfeastol) )
12903 {
12904 /* solution is infeasible (this can happen due to numerical problems): solve again with tighter feasibility
12905 * tolerance
12906 */
12907 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12908 "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, dfeas=%u) -- solving again with tighter feasibility tolerance\n",
12909 stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12910 tightprimfeastol = tightprimfeastol || !primalfeasible;
12911 tightdualfeastol = tightdualfeastol || !dualfeasible;
12912 goto SOLVEAGAIN;
12913 }
12914 else if( !fromscratch && !wasfromscratch && simplex )
12915 {
12916 /* solution is infeasible (this can happen due to numerical problems): solve again from scratch */
12917 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12918 "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, dfeas=%u) -- solving again from scratch\n",
12919 stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12920 fromscratch = TRUE;
12921 goto SOLVEAGAIN;
12922 }
12923 else
12924 {
12925 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved");
12926 lp->solved = FALSE;
12928 *lperror = TRUE;
12929 }
12930 }
12931 SCIPsetDebugMsg(set, " -> LP objective value: %g + %g = %g (solstat=%d, cutoff=%g)\n",
12932 lp->lpobjval, getFiniteLooseObjval(lp, set, prob), lp->lpobjval + getFiniteLooseObjval(lp, set, prob),
12933 lp->lpsolstat, lp->cutoffbound);
12934 break;
12935
12937 SCIPsetDebugMsg(set, " -> LP infeasible\n");
12938 if( set->lp_checkfarkas || set->lp_alwaysgetduals || set->exact_enable || !SCIPprobAllColsInLP(prob, set, lp) )
12939 {
12940 if( set->exact_enable && SCIPlpiExactHasDualRay(lp->lpexact->lpiexact) )
12941 farkasvalid = TRUE;
12942 else if( SCIPlpiHasDualRay(lp->lpi) )
12943 {
12944 SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat, forcedlpsolve, &farkasvalid) );
12945 }
12946 /* it might happen that we have no infeasibility proof for the current LP (e.g. if the LP was always solved
12947 * with the primal simplex due to numerical problems) - treat this case like an LP error
12948 */
12949 else
12950 {
12951 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12952 "(node %" SCIP_LONGINT_FORMAT ") infeasibility of LP %" SCIP_LONGINT_FORMAT " could not be proven by dual ray\n", stat->nnodes, stat->nlps);
12953 lp->solved = FALSE;
12955 farkasvalid = FALSE;
12956 *lperror = TRUE;
12957 }
12958 }
12959 else
12960 farkasvalid = TRUE;
12961
12962 /* if the LP solver does not provide a Farkas proof we don't want to resolve the LP */
12963 if( !farkasvalid && !(*lperror) )
12964 {
12966
12967 if( (fastmip > 0) && simplex )
12968 {
12969 /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems): solve again
12970 * without FASTMIP
12971 */
12972 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12973 "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again without FASTMIP\n",
12974 stat->nnodes, stat->nlps);
12975 fastmip = 0;
12976 goto SOLVEAGAIN;
12977 }
12978 else if( !tightdualfeastol )
12979 {
12980 /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems):
12981 * solve again with tighter feasibility tolerance
12982 */
12983 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12984 "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again with tighter dual feasibility tolerance\n",
12985 stat->nnodes, stat->nlps);
12986 tightdualfeastol = TRUE;
12987 goto SOLVEAGAIN;
12988 }
12989 else if( !fromscratch && simplex )
12990 {
12991 /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems): solve again
12992 * from scratch
12993 */
12994 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12995 "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again from scratch\n",
12996 stat->nnodes, stat->nlps);
12997 fromscratch = TRUE;
12998 goto SOLVEAGAIN;
12999 }
13000 else
13001 {
13002 /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems) and nothing
13003 * helped forget about the LP at this node and mark it to be unsolved
13004 */
13005 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, LP infeasible");
13006 lp->solved = FALSE;
13008 *lperror = TRUE;
13009 }
13010 }
13011
13012 break;
13013
13015 if( set->lp_checkprimfeas )
13016 {
13017 /* get unbounded LP solution and check the solution's feasibility again */
13018 SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, &primalfeasible, &rayfeasible) );
13019
13020 lp->primalchecked = TRUE;
13021 }
13022 else
13023 {
13024 /* get unbounded LP solution believing in the feasibility of the LP solution */
13026
13027 primalfeasible = TRUE;
13028 rayfeasible = TRUE;
13029 lp->primalchecked = FALSE;
13030 }
13031
13032 /* in debug mode, check that lazy bounds (if present) are not violated */
13033 checkLazyBounds(lp, set);
13034
13035 SCIPsetDebugMsg(set, " -> LP has unbounded primal ray (primalfeas=%u, rayfeas=%u)\n",
13036 primalfeasible, rayfeasible);
13037
13038 if( !primalfeasible || !rayfeasible )
13039 {
13041
13042 if( (fastmip > 0) && simplex )
13043 {
13044 /* unbounded solution is infeasible (this can happen due to numerical problems): solve again without FASTMIP */
13045 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
13046 "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, rfeas=%u) -- solving again without FASTMIP\n",
13047 stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
13048 fastmip = 0;
13049 goto SOLVEAGAIN;
13050 }
13051 else if( !tightprimfeastol )
13052 {
13053 /* unbounded solution is infeasible (this can happen due to numerical problems): solve again with tighter feasibility
13054 * tolerance
13055 */
13056 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
13057 "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, rfeas=%u) -- solving again with tighter primal feasibility tolerance\n",
13058 stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
13059 tightprimfeastol = TRUE;
13060 goto SOLVEAGAIN;
13061 }
13062 else if( !fromscratch && simplex )
13063 {
13064 /* unbounded solution is infeasible (this can happen due to numerical problems): solve again from scratch */
13065 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
13066 "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, rfeas=%u) -- solving again from scratch\n",
13067 stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
13068 fromscratch = TRUE;
13069 goto SOLVEAGAIN;
13070 }
13071 else if( scaling > 0 )
13072 {
13073 /* unbounded solution is infeasible (this can happen due to numerical problems): solve again without scaling */
13074 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
13075 "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, rfeas=%u) -- solving without scaling\n",
13076 stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
13077 scaling = 0;
13078 goto SOLVEAGAIN;
13079 }
13080 else
13081 {
13082 /* unbounded solution is infeasible (this can happen due to numerical problems) and nothing helped:
13083 * forget about the LP at this node and mark it to be unsolved
13084 */
13085 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, LP unbounded");
13086 lp->solved = FALSE;
13088 *lperror = TRUE;
13089 }
13090 }
13091
13092 break;
13093
13095 assert(!lpCutoffDisabled(set, prob, lp));
13096 /* Some LP solvers, e.g. CPLEX With FASTMIP setting, do not apply the final pivot to reach the dual solution
13097 * exceeding the objective limit. In some cases like branch-and-price, however, we must make sure that a dual
13098 * feasible solution exists that exceeds the objective limit. Therefore, we have to continue solving it without
13099 * objective limit for at least one iteration. We first try to continue with FASTMIP for one additional simplex
13100 * iteration using the steepest edge pricing rule. If this does not fix the problem, we temporarily disable
13101 * FASTMIP and solve again.
13102 */
13103 if( !set->exact_enable && !SCIPprobAllColsInLP(prob, set, lp) )
13104 {
13105 SCIP_LPI* lpi;
13107
13108 lpi = SCIPlpGetLPI(lp);
13109
13110 assert(lpi != NULL);
13111 /* actually, SCIPsetIsGE(set, lp->lpobjval, lp->lpiuobjlim) should hold, but we are a bit less strict in
13112 * the assert by using !SCIPsetIsFeasNegative()
13113 */
13115
13117
13118 /* do one additional simplex step if the computed dual solution doesn't exceed the objective limit */
13119 if( SCIPsetIsLT(set, objval, lp->lpiobjlim) )
13120 {
13121 SCIP_Real tmpcutoff;
13122 char tmppricingchar;
13123 SCIP_LPSOLSTAT solstat;
13124
13125 SCIPsetDebugMsg(set, "objval = %f < %f = lp->lpiobjlim, but status objlimit\n", objval, lp->lpiobjlim);
13126
13127 /* we want to resolve from the current basis (also if the LP had to be solved from scratch) */
13128 fromscratch = FALSE;
13129
13130 /* temporarily disable cutoffbound, which also disables the objective limit */
13131 tmpcutoff = lp->cutoffbound;
13132 lp->cutoffbound = SCIPlpiInfinity(lpi);
13133
13134 /* set lp pricing strategy to steepest edge */
13135 SCIP_CALL( SCIPsetGetCharParam(set, "lp/pricing", &tmppricingchar) );
13136 SCIP_CALL( SCIPsetSetCharParam(set, messagehdlr, "lp/pricing", 's') );
13137
13138 /* resolve LP with an iteration limit of 1 */
13139 SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, 1, 1,
13140 FALSE, FALSE, TRUE, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
13141
13142 /* reinstall old cutoff bound and lp pricing strategy */
13143 lp->cutoffbound = tmpcutoff;
13144 SCIP_CALL( SCIPsetSetCharParam(set, messagehdlr, "lp/pricing", tmppricingchar) );
13145
13146 /* get objective value */
13148
13149 /* get solution status for the lp */
13150 solstat = SCIPlpGetSolstat(lp);
13151 assert(solstat != SCIP_LPSOLSTAT_OBJLIMIT);
13152
13153 SCIPsetDebugMsg(set, " ---> new objval = %f (solstat: %d, 1 add. step)\n", objval, solstat);
13154
13155 /* the solution is still not exceeding the objective limit and the solving process
13156 * was stopped due to time or iteration limit, solve again with fastmip turned off
13157 */
13158 if( solstat == SCIP_LPSOLSTAT_ITERLIMIT &&
13160 {
13162 if( !(*lperror) && (fastmip > 0) && simplex )
13163 {
13164 fastmip = 0;
13165 SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, -1, -1,
13166 FALSE, FALSE, TRUE, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
13167
13168 /* get objective value */
13170
13171 /* get solution status for the lp */
13172 solstat = SCIPlpGetSolstat(lp);
13173
13174 SCIPsetDebugMsg(set, " ---> new objval = %f (solstat: %d, without fastmip)\n", objval, solstat);
13175 }
13176 }/*lint !e438*/
13177
13178 /* check for lp errors */
13179 if( *lperror || solstat == SCIP_LPSOLSTAT_ERROR || solstat == SCIP_LPSOLSTAT_NOTSOLVED )
13180 {
13181 SCIPsetDebugMsg(set, "unresolved error while resolving LP in order to exceed the objlimit\n");
13182 lp->solved = FALSE;
13184
13185 retcode = *lperror ? SCIP_OKAY : SCIP_LPERROR;
13186 goto TERMINATE;
13187 }
13188
13189 lp->solved = TRUE;
13190
13191 /* optimal solution / objlimit / itlimit or timelimit, but objlimit exceeded */
13192 if( solstat == SCIP_LPSOLSTAT_OPTIMAL || solstat == SCIP_LPSOLSTAT_OBJLIMIT
13193 || ( (solstat == SCIP_LPSOLSTAT_ITERLIMIT || solstat == SCIP_LPSOLSTAT_TIMELIMIT)
13194 && SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) ) )
13195 {
13196 /* get LP solution and possibly check the solution's feasibility again */
13197 if( set->lp_checkprimfeas )
13198 {
13199 primalfeaspointer = &primalfeasible;
13200 lp->primalchecked = TRUE;
13201 }
13202 else
13203 {
13204 /* believe in the primal feasibility of the LP solution */
13205 primalfeasible = TRUE;
13206 primalfeaspointer = NULL;
13207 lp->primalchecked = FALSE;
13208 }
13209 if( set->lp_checkdualfeas )
13210 {
13211 dualfeaspointer = &dualfeasible;
13212 lp->dualchecked = TRUE;
13213 }
13214 else
13215 {
13216 /* believe in the dual feasibility of the LP solution */
13217 dualfeasible = TRUE;
13218 dualfeaspointer = NULL;
13219 lp->dualchecked = FALSE;
13220 }
13221
13222 SCIP_CALL( SCIPlpGetSol(lp, set, stat, primalfeaspointer, dualfeaspointer) );
13223
13224 /* in debug mode, check that lazy bounds (if present) are not violated by an optimal LP solution */
13225 if( solstat == SCIP_LPSOLSTAT_OPTIMAL )
13226 {
13227 checkLazyBounds(lp, set);
13228 }
13229
13230 /* if objective value is larger than the cutoff bound, set solution status to objective
13231 * limit reached and objective value to infinity, in case solstat = SCIP_LPSOLSTAT_OBJLIMIT,
13232 * this was already done in the lpSolve() method
13233 */
13234 if( SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) )
13235 {
13238 }
13239
13240 /* LP solution is not feasible or objective limit was reached without the LP value really exceeding
13241 * the cutoffbound; mark the LP to be unsolved
13242 */
13243 if( !primalfeasible || !dualfeasible
13244 || (solstat == SCIP_LPSOLSTAT_OBJLIMIT &&
13246 {
13247 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_HIGH, "unresolved");
13248 lp->solved = FALSE;
13250 *lperror = TRUE;
13251 }
13252
13253 SCIPsetDebugMsg(set, " -> LP objective value: %g + %g = %g (solstat=%d, cutoff=%g)\n",
13254 lp->lpobjval, getFiniteLooseObjval(lp, set, prob), lp->lpobjval + getFiniteLooseObjval(lp, set, prob),
13255 lp->lpsolstat, lp->cutoffbound);
13256 }
13257 /* infeasible solution */
13258 else if( solstat == SCIP_LPSOLSTAT_INFEASIBLE )
13259 {
13260 SCIPsetDebugMsg(set, " -> LP infeasible\n");
13261
13262 if( set->lp_checkfarkas || set->exact_enable || !SCIPprobAllColsInLP(prob, set, lp) )
13263 {
13264 if( SCIPlpiHasDualRay(lp->lpi) )
13265 {
13266 SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat, forcedlpsolve, &farkasvalid) );
13267 }
13268 /* it might happen that we have no infeasibility proof for the current LP (e.g. if the LP was always solved
13269 * with the primal simplex due to numerical problems) - treat this case like an LP error
13270 */
13271 else
13272 {
13273 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
13274 "(node %" SCIP_LONGINT_FORMAT ") infeasibility of LP %" SCIP_LONGINT_FORMAT " could not be proven by dual ray\n", stat->nnodes, stat->nlps);
13275 lp->solved = FALSE;
13277 farkasvalid = FALSE;
13278 *lperror = TRUE;
13279 }
13280 }
13281 else
13282 farkasvalid = TRUE;
13283
13284 if( !farkasvalid )
13285 {
13287
13288 if( !tightprimfeastol )
13289 {
13290 /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems):
13291 * solve again with tighter feasibility tolerance
13292 */
13293 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
13294 "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again with tighter primal feasibility tolerance\n",
13295 stat->nnodes, stat->nlps);
13296 tightprimfeastol = TRUE;
13297 goto SOLVEAGAIN;
13298 }
13299 else if( simplex )
13300 {
13301 /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems): solve again
13302 * from scratch
13303 */
13304 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
13305 "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again from scratch\n",
13306 stat->nnodes, stat->nlps);
13307 fromscratch = TRUE;
13308 goto SOLVEAGAIN;
13309 }
13310 else
13311 {
13312 /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems) and nothing
13313 * helped forget about the LP at this node and mark it to be unsolved
13314 */
13315 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, LP infeasible");
13316 lp->solved = FALSE;
13318 *lperror = TRUE;
13319 }
13320 }
13321 }
13322 /* unbounded solution */
13323 else if( solstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY )
13324 {
13325 if( set->lp_checkprimfeas )
13326 {
13327 /* get unbounded LP solution and check the solution's feasibility again */
13328 SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, &primalfeasible, &rayfeasible) );
13329
13330 lp->primalchecked = TRUE;
13331 }
13332 else
13333 {
13334 /* get unbounded LP solution believing in its feasibility */
13336
13337 primalfeasible = TRUE;
13338 rayfeasible = TRUE;
13339 lp->primalchecked = FALSE;
13340 }
13341
13342 SCIPsetDebugMsg(set, " -> LP has unbounded primal ray\n");
13343
13344 /* in debug mode, check that lazy bounds (if present) are not violated */
13345 checkLazyBounds(lp, set);
13346
13347 if( !primalfeasible || !rayfeasible )
13348 {
13349 /* unbounded solution is infeasible (this can happen due to numerical problems):
13350 * forget about the LP at this node and mark it to be unsolved
13351 *
13352 * @todo: like in the default LP solving evaluation, solve without fastmip,
13353 * with tighter feasibility tolerance and from scratch
13354 */
13355 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, unbounded LP");
13356 lp->solved = FALSE;
13358 *lperror = TRUE;
13359 }
13360 }
13361
13365 }
13366 else
13367 {
13368 SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
13369 }
13370 }
13371 SCIPsetDebugMsg(set, " -> LP objective limit reached\n");
13372 break;
13373
13375 SCIPsetDebugMsg(set, " -> LP iteration limit exceeded\n");
13376 break;
13377
13379 SCIPsetDebugMsg(set, " -> LP time limit exceeded\n");
13380
13381 /* make sure that we evaluate the time limit exactly in order to avoid erroneous warning */
13382 stat->nclockskipsleft = 0;
13383 if( !stat->userinterrupt && !SCIPsolveIsStopped(set, stat, FALSE) )
13384 {
13385 SCIPmessagePrintWarning(messagehdlr, "LP solver reached time limit, but SCIP time limit is not exceeded yet; "
13386 "you might consider switching the clock type of SCIP\n");
13388 }
13389 break;
13390
13393 SCIPerrorMessage("error in LP solver\n");
13394 retcode = SCIP_LPERROR;
13395 goto TERMINATE;
13396
13397 default:
13398 SCIPerrorMessage("unknown LP solution status\n");
13399 retcode = SCIP_ERROR;
13400 goto TERMINATE;
13401 }
13402 }
13403 assert(!(*lperror) || !lp->solved);
13404
13405 TERMINATE:
13406 /* if the LP had to be solved from scratch, we have to reset this flag since it is stored in the LPI; otherwise it
13407 * may happen that we continue to solve from scratch during strong branching */
13408 if( lp->lpifromscratch )
13409 {
13410 SCIP_Bool success;
13411 (void) lpSetFromscratch(lp, FALSE, &success);
13412 SCIPsetDebugMsg(set, "resetting parameter SCIP_LPPARAM_FROMSCRATCH to FALSE %s\n", success ? "" : "failed");
13413 SCIP_UNUSED(success);
13414 }
13415
13416 return retcode;
13417}
13418
13419/** gets solution status of current LP */
13421 SCIP_LP* lp /**< current LP data */
13422 )
13423{
13424 assert(lp != NULL);
13426
13427 return (lp->flushed ? lp->lpsolstat : SCIP_LPSOLSTAT_NOTSOLVED);
13428}
13429
13430/** gets objective value of current LP
13431 *
13432 * @note This method returns the objective value of the current LP solution, which might be primal or dual infeasible
13433 * if a limit was hit during solving. It must not be used as a dual bound if the LP solution status is
13434 * SCIP_LPSOLSTAT_ITERLIMIT or SCIP_LPSOLSTAT_TIMELIMIT.
13435 */
13437 SCIP_LP* lp, /**< current LP data */
13438 SCIP_SET* set, /**< global SCIP settings */
13439 SCIP_PROB* prob /**< problem data */
13440 )
13441{
13442 assert(lp != NULL);
13443 assert(lp->solved);
13444 assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
13445 assert(set != NULL);
13446
13447 if( !lp->flushed )
13448 return SCIP_INVALID;
13450 return lp->lpobjval;
13451 else if( lp->looseobjvalinf > 0 )
13452 return -SCIPsetInfinity(set);
13453 else
13454 {
13455 /* recalculate the loose objective value, if needed */
13456 if( !lp->looseobjvalid )
13458
13459 return lp->lpobjval + lp->looseobjval;
13460 }
13461}
13462
13463/** gets part of objective value of current LP that results from COLUMN variables only */
13465 SCIP_LP* lp /**< current LP data */
13466 )
13467{
13468 assert(lp != NULL);
13469 assert(lp->solved);
13470
13471 return (lp->flushed ? lp->lpobjval : SCIP_INVALID);
13472}
13473
13474/** gets part of objective value of current LP that results from LOOSE variables only */
13476 SCIP_LP* lp, /**< current LP data */
13477 SCIP_SET* set, /**< global SCIP settings */
13478 SCIP_PROB* prob /**< problem data */
13479 )
13480{
13481 assert(lp != NULL);
13482 assert(lp->solved);
13483 assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
13484 assert(set != NULL);
13485
13486 if( !lp->flushed )
13487 return SCIP_INVALID;
13488 else if( lp->looseobjvalinf > 0 )
13489 return -SCIPsetInfinity(set);
13490 else
13491 return getFiniteLooseObjval(lp, set, prob);
13492}
13493
13494/** remembers the current LP objective value as root solution value */
13496 SCIP_LP* lp, /**< current LP data */
13497 SCIP_SET* set, /**< global SCIP settings */
13498 SCIP_PROB* prob /**< problem data */
13499 )
13500{
13501 assert(lp != NULL);
13502
13504 lp->rootlooseobjval = SCIPlpGetLooseObjval(lp, set, prob);
13505}
13506
13507/** invalidates the root LP solution value */
13509 SCIP_LP* lp /**< current LP data */
13510 )
13511{
13512 assert(lp != NULL);
13513
13516}
13517
13518/** recomputes local and global pseudo objective values */
13520 SCIP_LP* lp, /**< current LP data */
13521 SCIP_SET* set, /**< global SCIP settings */
13522 SCIP_PROB* prob /**< problem data */
13523 )
13524{
13525 SCIP_VAR** vars;
13526 int nvars;
13527 int v;
13528
13529 assert(lp != NULL);
13530 assert(set != NULL);
13531 assert(prob != NULL);
13532
13533 vars = prob->vars;
13534 nvars = prob->nvars;
13535
13536 lp->glbpseudoobjvalinf = 0;
13537 lp->glbpseudoobjval = 0.0;
13538
13539 lp->pseudoobjvalinf = 0;
13540 lp->pseudoobjval = 0.0;
13541
13542 for( v = 0; v < nvars; ++v )
13543 {
13545
13546 if( SCIPsetIsPositive(set, obj) )
13547 {
13548 /* update the global pseudo objective value */
13550 ++(lp->glbpseudoobjvalinf);
13551 else
13553
13554 /* update the local pseudo objective value */
13556 ++(lp->pseudoobjvalinf);
13557 else
13559 }
13560
13561 if( SCIPsetIsNegative(set, obj) )
13562 {
13563 /* update the global pseudo objective value */
13565 ++(lp->glbpseudoobjvalinf);
13566 else
13568
13569 /* update the local pseudo objective value */
13571 ++(lp->pseudoobjvalinf);
13572 else
13574 }
13575 }
13576
13577 /* the recomputed values are reliable */
13579 lp->glbpseudoobjvalid = TRUE;
13580 lp->relpseudoobjval = lp->pseudoobjval;
13581 lp->pseudoobjvalid = TRUE;
13582}
13583
13584/** gets the global pseudo objective value; that is all variables set to their best (w.r.t. the objective function)
13585 * global bound
13586 */
13588 SCIP_LP* lp, /**< current LP data */
13589 SCIP_SET* set, /**< global SCIP settings */
13590 SCIP_PROB* prob /**< problem data */
13591 )
13592{
13593 assert(lp != NULL);
13594 assert(lp->glbpseudoobjvalinf >= 0);
13595 assert(set != NULL);
13596
13597 if( lp->glbpseudoobjvalinf > 0 || set->nactivepricers > 0 )
13598 return -SCIPsetInfinity(set);
13599 else
13600 {
13601 /* recalculate the global pseudo solution value, if needed */
13602 if( !lp->glbpseudoobjvalid )
13604
13605 /* if the global pseudo objective value is smaller than -infinity, we just return -infinity */
13607 return -SCIPsetInfinity(set);
13608
13610 return SCIPsetInfinity(set);
13611
13612 return lp->glbpseudoobjval;
13613 }
13614}
13615
13616/** gets the pseudo objective value for the current search node; that is all variables set to their best (w.r.t. the
13617 * objective function) local bound
13618 */
13620 SCIP_LP* lp, /**< current LP data */
13621 SCIP_SET* set, /**< global SCIP settings */
13622 SCIP_PROB* prob /**< problem data */
13623 )
13624{
13625 assert(lp != NULL);
13626 assert(lp->pseudoobjvalinf >= 0);
13627 assert(set != NULL);
13628
13629 if( lp->pseudoobjvalinf > 0 || set->nactivepricers > 0 )
13630 return -SCIPsetInfinity(set);
13631 else
13632 {
13633 /* recalculate the pseudo solution value, if needed */
13634 if( !lp->pseudoobjvalid )
13636
13637 /* if the pseudo objective value is smaller than -infinity, we just return -infinity */
13639 return -SCIPsetInfinity(set);
13640
13642 return SCIPsetInfinity(set);
13643
13644 return lp->pseudoobjval;
13645 }
13646}
13647
13648/** gets safe pseudo objective value, if a bound of the given variable would be modified in the given way;
13649 * perform calculations with interval arithmetic to get an exact lower bound
13650 */
13651static
13653 SCIP_LP* lp, /**< current LP data */
13654 SCIP_SET* set, /**< global SCIP settings */
13655 SCIP_PROB* prob, /**< problem data */
13656 SCIP_VAR* var, /**< problem variable */
13657 SCIP_Real oldbound, /**< old value for bound */
13658 SCIP_Real newbound, /**< new value for bound */
13659 SCIP_BOUNDTYPE boundtype /**< type of bound: lower or upper bound */
13660 )
13661{
13662 SCIP_Real pseudoobjval;
13663 int pseudoobjvalinf;
13664 SCIP_Real obj;
13665
13666 pseudoobjval = getFinitePseudoObjval(lp, set, prob);
13667 pseudoobjvalinf = lp->pseudoobjvalinf;
13669 if( !SCIPsetIsZero(set, obj) && boundtype == SCIPvarGetBestBoundType(var) )
13670 {
13671 SCIP_INTERVAL objint;
13672 SCIP_INTERVAL bd;
13673 SCIP_INTERVAL prod;
13674 SCIP_INTERVAL psval;
13675
13676 SCIPintervalSet(&psval, pseudoobjval);
13679 else
13681
13682 if( SCIPsetIsInfinity(set, REALABS(oldbound)) )
13683 pseudoobjvalinf--;
13684 else
13685 {
13686 SCIPintervalSet(&bd, oldbound);
13687 SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, objint);
13688 SCIPintervalSub(SCIPsetInfinity(set), &psval, psval, prod);
13689 }
13690 assert(pseudoobjvalinf >= 0);
13691 if( SCIPsetIsInfinity(set, REALABS(newbound)) )
13692 pseudoobjvalinf++;
13693 else
13694 {
13695 SCIPintervalSet(&bd, newbound);
13696 SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, objint);
13697 SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, prod);
13698 }
13699
13700 pseudoobjval = SCIPintervalGetInf(psval);
13701 }
13702 assert(pseudoobjvalinf >= 0);
13703
13704 if( pseudoobjvalinf > 0 || set->nactivepricers > 0 )
13705 return -SCIPsetInfinity(set);
13706 else
13707 return pseudoobjval;
13708}
13709
13710/** gets pseudo objective value, if a bound of the given variable would be modified in the given way */
13712 SCIP_LP* lp, /**< current LP data */
13713 SCIP_SET* set, /**< global SCIP settings */
13714 SCIP_PROB* prob, /**< problem data */
13715 SCIP_VAR* var, /**< problem variable */
13716 SCIP_Real oldbound, /**< old value for bound */
13717 SCIP_Real newbound, /**< new value for bound */
13718 SCIP_BOUNDTYPE boundtype /**< type of bound: lower or upper bound */
13719 )
13720{
13721 SCIP_Real pseudoobjval;
13722 int pseudoobjvalinf;
13723 SCIP_Real obj;
13724
13725 if( set->exact_enable )
13726 return lpGetModifiedPseudoObjvalExact(lp, set, prob, var, oldbound, newbound, boundtype);
13727
13728 pseudoobjval = getFinitePseudoObjval(lp, set, prob);
13729 pseudoobjvalinf = lp->pseudoobjvalinf;
13731 if( !SCIPsetIsZero(set, obj) && boundtype == SCIPvarGetBestBoundType(var) )
13732 {
13733 if( SCIPsetIsInfinity(set, REALABS(oldbound)) )
13734 pseudoobjvalinf--;
13735 else
13736 pseudoobjval -= oldbound * obj;
13737 assert(pseudoobjvalinf >= 0);
13738 if( SCIPsetIsInfinity(set, REALABS(newbound)) )
13739 pseudoobjvalinf++;
13740 else
13741 pseudoobjval += newbound * obj;
13742 }
13743 assert(pseudoobjvalinf >= 0);
13744
13745 if( pseudoobjvalinf > 0 || set->nactivepricers > 0 )
13746 return -SCIPsetInfinity(set);
13747 else
13748 return pseudoobjval;
13749}
13750
13751/** compute the objective delta due the new objective coefficient */
13752static
13754 SCIP_SET* set, /**< global SCIP settings */
13755 SCIP_Real oldobj, /**< old objective value of variable */
13756 SCIP_Real newobj, /**< new objective value of variable */
13757 SCIP_Real lb, /**< lower bound of variable */
13758 SCIP_Real ub, /**< upper bound of variable */
13759 SCIP_Real* deltaval, /**< pointer to store the delta value */
13760 int* deltainf /**< pointer to store the number of variables with infinite best bound */
13761 )
13762{
13768
13769 (*deltaval) = 0.0;
13770 (*deltainf) = 0;
13771
13773 {
13774 /* sign of objective did not change */
13776 {
13777 /* if the bound is finite, calculate the deltaval */
13778 if( !SCIPsetIsInfinity(set, -lb) )
13779 (*deltaval) = lb * (newobj - oldobj);
13780 }
13781 /* sign of objective did change, so the best bound does change */
13782 else if( SCIPsetIsNegative(set, newobj) )
13783 {
13784 if( SCIPsetIsInfinity(set, -lb) )
13785 {
13786 /* old best bound was infinite while new one is not */
13787 if( !SCIPsetIsInfinity(set, ub) )
13788 {
13789 (*deltainf) = -1;
13790 (*deltaval) = ub * newobj;
13791 }
13792 }
13793 else
13794 {
13795 /* new best bound is infinite while old one was not */
13796 if( SCIPsetIsInfinity(set, ub) )
13797 {
13798 (*deltainf) = 1;
13799 (*deltaval) = -lb * oldobj;
13800 }
13801 /* neither old nor new best bound is infinite, so just calculate the deltaval */
13802 else
13803 {
13804 (*deltaval) = (ub * newobj) - (lb * oldobj);
13805 }
13806 }
13807 }
13808 /* new objective is 0.0 */
13809 else
13810 {
13811 if( SCIPsetIsInfinity(set, -lb) )
13812 (*deltainf) = -1;
13813 else
13814 (*deltaval) = -lb * oldobj;
13815 }
13816 }
13817 else if( SCIPsetIsNegative(set, oldobj) )
13818 {
13819 /* sign of objective did not change */
13821 {
13822 /* if the bound is finite, calculate the deltaval */
13823 if( !SCIPsetIsInfinity(set, ub) )
13824 (*deltaval) = ub * (newobj - oldobj);
13825 }
13826 /* sign of objective did change, so the best bound does change */
13827 else if( SCIPsetIsPositive(set, newobj) )
13828 {
13829 if( SCIPsetIsInfinity(set, ub) )
13830 {
13831 /* old best bound was infinite while new one is not */
13832 if( !SCIPsetIsInfinity(set, -lb) )
13833 {
13834 (*deltainf) = -1;
13835 (*deltaval) = lb * newobj;
13836 }
13837 }
13838 else
13839 {
13840 /* new best bound is infinite while old one was not */
13841 if( SCIPsetIsInfinity(set, -lb) )
13842 {
13843 (*deltainf) = 1;
13844 (*deltaval) = -ub * oldobj;
13845 }
13846 /* neither old nor new best bound is infinite, so just calculate the deltaval */
13847 else
13848 {
13849 (*deltaval) = (lb * newobj) - (ub * oldobj);
13850 }
13851 }
13852 }
13853 /* new objective is 0.0 */
13854 else
13855 {
13856 if( SCIPsetIsInfinity(set, ub) )
13857 (*deltainf) = -1;
13858 else
13859 (*deltaval) = -ub * oldobj;
13860 }
13861 }
13862 /* old objective was 0.0 */
13863 else
13864 {
13866 {
13867 if( SCIPsetIsInfinity(set, ub) )
13868 (*deltainf) = 1;
13869 else
13870 (*deltaval) = ub * newobj;
13871 }
13872 else if( SCIPsetIsPositive(set, newobj) )
13873 {
13874 if( SCIPsetIsInfinity(set, -lb) )
13875 (*deltainf) = 1;
13876 else
13877 (*deltaval) = lb * newobj;
13878 }
13879 }
13880}
13881
13882/** compute the objective delta due the new lower bound */
13883static
13885 SCIP_SET* set, /**< global SCIP settings */
13886 SCIP_Real obj, /**< objective value of variable */
13887 SCIP_Real oldlb, /**< old lower bound of variable */
13888 SCIP_Real newlb, /**< new lower bound of variable */
13889 SCIP_Real* deltaval, /**< pointer to store the delta value */
13890 int* deltainf /**< pointer to store the number of variables with infinite best bound */
13891 )
13892{
13893 assert(obj > 0.0);
13895 assert(!SCIPsetIsInfinity(set, oldlb));
13896 assert(!SCIPsetIsInfinity(set, newlb));
13897 assert(newlb != oldlb); /*lint !e777*/
13898
13899 if( SCIPsetIsInfinity(set, -newlb) )
13900 {
13901 assert(!SCIPsetIsInfinity(set, -oldlb));
13902
13903 *deltainf = 1;
13904 *deltaval = -obj * oldlb;
13905 }
13906 else if( SCIPsetIsInfinity(set, -oldlb) )
13907 {
13908 assert(!SCIPsetIsInfinity(set, -newlb));
13909
13910 *deltainf = -1;
13911 *deltaval = obj * newlb;
13912 }
13913 else
13914 {
13915 *deltainf = 0;
13916 *deltaval = obj * (newlb - oldlb);
13917 }
13918}
13919
13920/** compute the objective delta due the new upper bound */
13921static
13923 SCIP_SET* set, /**< global SCIP settings */
13924 SCIP_Real obj, /**< objective value of variable */
13925 SCIP_Real oldub, /**< old upper bound of variable */
13926 SCIP_Real newub, /**< new upper bound of variable */
13927 SCIP_Real* deltaval, /**< pointer to store the delta value */
13928 int* deltainf /**< pointer to store the number of variables with infinite best bound */
13929 )
13930{
13931 assert(obj < 0.0);
13933 assert(!SCIPsetIsInfinity(set, -oldub));
13934 assert(!SCIPsetIsInfinity(set, -newub));
13935 assert(newub != oldub); /*lint !e777*/
13936
13937 if( SCIPsetIsInfinity(set, newub) )
13938 {
13939 assert(!SCIPsetIsInfinity(set, oldub));
13940
13941 *deltainf = 1;
13942 *deltaval = -obj * oldub;
13943 }
13944 else if( SCIPsetIsInfinity(set, oldub) )
13945 {
13946 assert(!SCIPsetIsInfinity(set, newub));
13947
13948 *deltainf = -1;
13949 *deltaval = obj * newub;
13950 }
13951 else
13952 {
13953 *deltainf = 0;
13954 *deltaval = obj * (newub - oldub);
13955 }
13956}
13957
13958/** updates current pseudo and loose objective values for a change in a variable's objective value or bounds */
13959static
13961 SCIP_LP* lp, /**< current LP data */
13962 SCIP_SET* set, /**< global SCIP settings */
13963 SCIP_VAR* var, /**< problem variable that changed */
13964 SCIP_Real deltaval, /**< delta value in the objective function */
13965 int deltainf, /**< delta value for the number of variables with infinite best bound */
13966 SCIP_Bool local, /**< should the local pseudo objective value be updated? */
13967 SCIP_Bool loose, /**< should the loose objective value be updated? */
13968 SCIP_Bool global /**< should the global pseudo objective value be updated? */
13969 )
13970{
13971 assert(lp != NULL);
13972 assert(lp->looseobjvalinf >= 0);
13973 assert(lp->pseudoobjvalinf >= 0);
13974 assert(lp->glbpseudoobjvalinf >= 0);
13975
13976 /* update the pseudo objective value */
13977 if( local )
13978 {
13979 lp->pseudoobjvalinf += deltainf;
13980 if( lp->pseudoobjvalid )
13981 {
13982 lp->pseudoobjval += deltaval;
13983
13984 /* if the absolute value was increased, this is regarded as reliable,
13985 * otherwise, we check whether we can still trust the updated value
13986 */
13988 lp->relpseudoobjval = lp->pseudoobjval;
13990 lp->pseudoobjvalid = FALSE;
13991 }
13992
13993 /* after changing a local bound on a LOOSE variable, we have to update the loose objective value, too */
13995 loose = TRUE;
13996 }
13997 /* update the loose objective value */
13998 if( loose )
13999 {
14000 lp->looseobjvalinf += deltainf;
14001
14002 if( deltaval != 0.0 && lp->looseobjvalid )
14003 {
14004 lp->looseobjval += deltaval;
14005
14006 /* if the absolute value was increased, this is regarded as reliable,
14007 * otherwise, we check whether we can still trust the updated value
14008 */
14009 if( REALABS(lp->rellooseobjval) < REALABS(lp->looseobjval) )
14010 lp->rellooseobjval = lp->looseobjval;
14012 lp->looseobjvalid = FALSE;
14013 }
14014 }
14015 /* update the root pseudo objective values */
14016 if( global )
14017 {
14018 lp->glbpseudoobjvalinf += deltainf;
14019 if( lp->glbpseudoobjvalid )
14020 {
14021 lp->glbpseudoobjval += deltaval;
14022
14023 /* if the absolute value was increased, this is regarded as reliable,
14024 * otherwise, we check whether we can still trust the updated value
14025 */
14030 }
14031 }
14032
14033 assert(lp->looseobjvalinf >= 0);
14034 assert(lp->pseudoobjvalinf >= 0);
14035 assert(lp->glbpseudoobjvalinf >= 0);
14036}
14037
14038/** updates current pseudo and loose objective values for a change in a variable's objective value or bounds;
14039 * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
14040 */
14041static
14043 SCIP_LP* lp, /**< current LP data */
14044 SCIP_SET* set, /**< global SCIP settings */
14045 SCIP_VAR* var, /**< problem variable that changed */
14046 SCIP_Real oldobj, /**< old objective value of variable */
14047 SCIP_Real oldlb, /**< old objective value of variable */
14048 SCIP_Real oldub, /**< old objective value of variable */
14049 SCIP_Real newobj, /**< new objective value of variable */
14050 SCIP_Real newlb, /**< new objective value of variable */
14051 SCIP_Real newub, /**< new objective value of variable */
14052 SCIP_Bool global /**< is the change global? */
14053 )
14054{
14055 SCIP_INTERVAL deltaval;
14056 SCIP_INTERVAL bd;
14058 SCIP_INTERVAL prod;
14059 SCIP_INTERVAL psval;
14060 int deltainf;
14061
14062 assert(lp != NULL);
14063 assert(lp->pseudoobjvalinf >= 0);
14064 assert(lp->looseobjvalinf >= 0);
14066 assert(!SCIPsetIsInfinity(set, oldlb));
14067 assert(!SCIPsetIsInfinity(set, -oldub));
14069 assert(!SCIPsetIsInfinity(set, newlb));
14070 assert(!SCIPsetIsInfinity(set, -newub));
14071 assert(var != NULL);
14072
14074 {
14075 SCIPerrorMessage("LP was informed of an objective change of a non-active variable\n");
14076 return SCIP_INVALIDDATA;
14077 }
14078
14080
14081 SCIPintervalSet(&deltaval, 0.0);
14082 deltainf = 0;
14083
14084 /* subtract old pseudo objective value */
14085 if( oldobj > 0.0 )
14086 {
14087 if( SCIPsetIsInfinity(set, -oldlb) )
14088 deltainf--;
14089 else
14090 {
14091 SCIPintervalSet(&bd, oldlb);
14093 SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
14094 SCIPintervalSub(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval -= oldlb * oldobj; */
14095 }
14096 }
14097 else if( oldobj < 0.0 )
14098 {
14099 if( SCIPsetIsInfinity(set, oldub) )
14100 deltainf--;
14101 else
14102 {
14103 SCIPintervalSet(&bd, oldub);
14105 SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
14106 SCIPintervalSub(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval -= oldub * oldobj; */
14107 }
14108 }
14109
14110 /* add new pseudo objective value */
14111 if( newobj > 0.0 )
14112 {
14113 if( SCIPsetIsInfinity(set, -newlb) )
14114 deltainf++;
14115 else
14116 {
14117 SCIPintervalSet(&bd, newlb);
14119 SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
14120 SCIPintervalAdd(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval += newlb * newobj; */
14121 }
14122 }
14123 else if( newobj < 0.0 )
14124 {
14125 if( SCIPsetIsInfinity(set, newub) )
14126 deltainf++;
14127 else
14128 {
14129 SCIPintervalSet(&bd, newub);
14131 SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
14132 SCIPintervalAdd(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval += newub * newobj; */
14133 }
14134 }
14135
14136 /* update the pseudo and loose objective values */
14137 if( global )
14138 {
14139 SCIPintervalSet(&psval, lp->glbpseudoobjval);
14140 SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, deltaval);
14142 lp->glbpseudoobjvalinf += deltainf;
14143 }
14144 else
14145 {
14146 SCIPintervalSet(&psval, lp->pseudoobjval);
14147 SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, deltaval);
14148 lp->pseudoobjval = SCIPintervalGetInf(psval);
14149 lp->pseudoobjvalinf += deltainf;
14151 {
14152 SCIPintervalSet(&psval, lp->looseobjval);
14153 SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, deltaval);
14154 lp->looseobjval = SCIPintervalGetInf(psval);
14155 lp->looseobjvalinf += deltainf;
14156 }
14157
14158 assert(lp->pseudoobjvalinf >= 0);
14159 assert(lp->looseobjvalinf >= 0);
14160 }
14161
14162 return SCIP_OKAY;
14163}
14164
14165/** updates current pseudo and loose objective value for a change in a variable's objective coefficient */
14167 SCIP_LP* lp, /**< current LP data */
14168 SCIP_SET* set, /**< global SCIP settings */
14169 SCIP_VAR* var, /**< problem variable that changed */
14170 SCIP_Real oldobj, /**< old objective coefficient of variable */
14171 SCIP_Real newobj /**< new objective coefficient of variable */
14172 )
14173{
14174 assert(set != NULL);
14175 assert(var != NULL);
14176
14177 if( set->exact_enable )
14178 {
14179 if( oldobj != newobj ) /*lint !e777*/
14180 {
14183 /* the global ps objval can be set directly because the global and local bounds have to be the same here (see below) */
14186
14187 lp->glbpseudoobjval = lp->pseudoobjval;
14189 }
14190 }
14191 else
14192 {
14193 if( !SCIPsetIsEQ(set, oldobj, newobj) )
14194 {
14195 SCIP_Real deltaval;
14196 int deltainf;
14197
14200
14201 /* the objective coefficient can only be changed during presolving, that implies that the global and local
14202 * domain of the variable are the same
14203 */
14206
14207 /* compute the pseudo objective delta due the new objective coefficient */
14209
14210 /* update the local pseudo objective value */
14211 lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
14212
14213 /* compute the pseudo objective delta due the new objective coefficient */
14215
14216 /* update the global pseudo objective value */
14217 lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
14218 }
14219 }
14220
14221 return SCIP_OKAY;
14222}
14223
14224
14225/** updates current root pseudo objective value for a global change in a variable's lower bound */
14227 SCIP_LP* lp, /**< current LP data */
14228 SCIP_SET* set, /**< global SCIP settings */
14229 SCIP_VAR* var, /**< problem variable that changed */
14230 SCIP_Real oldlb, /**< old lower bound of variable */
14231 SCIP_Real newlb /**< new lower bound of variable */
14232 )
14233{
14234 assert(set != NULL);
14235 assert(var != NULL);
14236
14237 if( set->exact_enable )
14238 {
14239 if( oldlb != newlb && SCIPvarGetObj(var) > 0.0 ) /*lint !e777*/
14240 {
14243 }
14244 }
14245 else
14246 {
14247 if( !SCIPsetIsEQ(set, oldlb, newlb) && SCIPsetIsPositive(set, SCIPvarGetObj(var)) )
14248 {
14249 SCIP_Real deltaval;
14250 int deltainf;
14251
14252 /* compute the pseudo objective delta due the new lower bound */
14253 getObjvalDeltaLb(set, SCIPvarGetObj(var), oldlb, newlb, &deltaval, &deltainf);
14254
14255 /* update the root pseudo objective values */
14256 lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
14257 }
14258 }
14259
14260 return SCIP_OKAY;
14261}
14262
14263/** updates current pseudo and loose objective value for a change in a variable's lower bound */
14265 SCIP_LP* lp, /**< current LP data */
14266 SCIP_SET* set, /**< global SCIP settings */
14267 SCIP_VAR* var, /**< problem variable that changed */
14268 SCIP_Real oldlb, /**< old lower bound of variable */
14269 SCIP_Real newlb /**< new lower bound of variable */
14270 )
14271{
14272 assert(set != NULL);
14273 assert(var != NULL);
14274
14275 if( set->exact_enable )
14276 {
14277 if( oldlb != newlb && SCIPvarGetObj(var) > 0.0 ) /*lint !e777*/
14278 {
14281 }
14282 }
14283 else
14284 {
14285 if( !SCIPsetIsEQ(set, oldlb, newlb) && SCIPsetIsPositive(set, SCIPvarGetObj(var)) )
14286 {
14287 SCIP_Real deltaval;
14288 int deltainf;
14289
14292
14293 /* compute the pseudo objective delta due the new lower bound */
14294 getObjvalDeltaLb(set, SCIPvarGetObj(var), oldlb, newlb, &deltaval, &deltainf);
14295
14296 /* update the pseudo and loose objective values */
14297 lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
14298 }
14299 }
14300
14301 return SCIP_OKAY;
14302}
14303
14304/** updates current root pseudo objective value for a global change in a variable's upper bound */
14306 SCIP_LP* lp, /**< current LP data */
14307 SCIP_SET* set, /**< global SCIP settings */
14308 SCIP_VAR* var, /**< problem variable that changed */
14309 SCIP_Real oldub, /**< old upper bound of variable */
14310 SCIP_Real newub /**< new upper bound of variable */
14311 )
14312{
14313 assert(set != NULL);
14314 assert(var != NULL);
14315
14316 if( set->exact_enable )
14317 {
14318 if( oldub != newub && SCIPvarGetObj(var) < 0.0 ) /*lint !e777*/
14319 {
14322 }
14323 }
14324 else
14325 {
14326 if( !SCIPsetIsEQ(set, oldub, newub) && SCIPsetIsNegative(set, SCIPvarGetObj(var)) )
14327 {
14328 SCIP_Real deltaval;
14329 int deltainf;
14330
14331 /* compute the pseudo objective delta due the new upper bound */
14332 getObjvalDeltaUb(set, SCIPvarGetObj(var), oldub, newub, &deltaval, &deltainf);
14333
14334 /* update the root pseudo objective values */
14335 lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
14336 }
14337 }
14338
14339 return SCIP_OKAY;
14340}
14341
14342/** updates current pseudo objective value for a change in a variable's upper bound */
14344 SCIP_LP* lp, /**< current LP data */
14345 SCIP_SET* set, /**< global SCIP settings */
14346 SCIP_VAR* var, /**< problem variable that changed */
14347 SCIP_Real oldub, /**< old upper bound of variable */
14348 SCIP_Real newub /**< new upper bound of variable */
14349 )
14350{
14351 assert(set != NULL);
14352 assert(var != NULL);
14353
14354 if( set->exact_enable )
14355 {
14356 if( oldub != newub && SCIPvarGetObj(var) < 0.0 ) /*lint !e777*/
14357 {
14360 }
14361 }
14362 else
14363 {
14364 if( !SCIPsetIsEQ(set, oldub, newub) && SCIPsetIsNegative(set, SCIPvarGetObj(var)) )
14365 {
14366 SCIP_Real deltaval;
14367 int deltainf;
14368
14371
14372 /* compute the pseudo objective delta due the new upper bound */
14373 getObjvalDeltaUb(set, SCIPvarGetObj(var), oldub, newub, &deltaval, &deltainf);
14374
14375 /* update the pseudo and loose objective values */
14376 lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
14377 }
14378 }
14379
14380 return SCIP_OKAY;
14381}
14382
14383/** informs LP, that given variable was added to the problem */
14385 SCIP_LP* lp, /**< current LP data */
14386 SCIP_SET* set, /**< global SCIP settings */
14387 SCIP_VAR* var /**< variable that is now a LOOSE problem variable */
14388 )
14389{
14390 assert(lp != NULL);
14393
14394 /* add the variable to the loose objective value sum */
14396
14397 /* update the loose variables counter */
14399 lp->nloosevars++;
14400
14401 return SCIP_OKAY;
14402}
14403
14404/** informs LP, that given variable is to be deleted from the problem */
14406 SCIP_LP* lp, /**< current LP data */
14407 SCIP_SET* set, /**< global SCIP settings */
14408 SCIP_VAR* var /**< variable that will be deleted from the problem */
14409 )
14410{
14411 assert(lp != NULL);
14414
14415 /* subtract the variable from the loose objective value sum */
14417
14418 /* update the loose variables counter */
14420 {
14422 }
14423
14424 return SCIP_OKAY;
14425}
14426
14427/** informs LP, that given formerly loose problem variable is now a column variable */
14428static
14430 SCIP_LP* lp, /**< current LP data */
14431 SCIP_SET* set, /**< global SCIP settings */
14432 SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
14433 )
14434{
14435 SCIP_Real obj;
14436 SCIP_Real lb;
14437 SCIP_Real ub;
14438
14439 assert(lp != NULL);
14440 assert(lp->nloosevars > 0);
14443 assert(lp->looseobjvalinf >= 0);
14444
14446
14447 /* update loose objective value */
14448 if( SCIPsetIsPositive(set, obj) )
14449 {
14450 lb = SCIPvarGetLbLocal(var);
14451 if( SCIPsetIsInfinity(set, -lb) )
14452 lp->looseobjvalinf--;
14453 else
14454 lpUpdateObjval(lp, set, var, -lb * obj, 0, FALSE, TRUE, FALSE);
14455 }
14456 else if( SCIPsetIsNegative(set, obj) )
14457 {
14458 ub = SCIPvarGetUbLocal(var);
14459 if( SCIPsetIsInfinity(set, ub) )
14460 lp->looseobjvalinf--;
14461 else
14462 lpUpdateObjval(lp, set, var, -ub * obj, 0, FALSE, TRUE, FALSE);
14463 }
14464
14466
14467 assert(lp->looseobjvalinf >= 0);
14468
14469 return SCIP_OKAY;
14470}
14471
14472/** informs LP, that given formerly loose problem variable is now a column variable
14473 * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
14474 */
14475static
14477 SCIP_LP* lp, /**< current LP data */
14478 SCIP_SET* set, /**< global SCIP settings */
14479 SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
14480 )
14481{
14482 SCIP_INTERVAL bd;
14483 SCIP_INTERVAL ob;
14484 SCIP_INTERVAL prod;
14485 SCIP_INTERVAL loose;
14486 SCIP_Real obj;
14487 SCIP_Real lb;
14488 SCIP_Real ub;
14489
14490 assert(lp != NULL);
14491 assert(lp->nloosevars > 0);
14494
14496
14497 SCIPintervalSet(&loose, lp->looseobjval);
14498
14499 /* update loose objective value corresponding to the deletion of variable */
14500 if( obj > 0.0 )
14501 {
14502 lb = SCIPvarGetLbLocal(var);
14503 if( SCIPsetIsInfinity(set, -lb) )
14504 lp->looseobjvalinf--;
14505 else
14506 {
14507 SCIPintervalSet(&bd, lb);
14508 SCIPintervalSet(&ob, obj);
14509 SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
14510 SCIPintervalSub(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval -= lb * obj; */
14511 }
14512 }
14513 else if( obj < 0.0 )
14514 {
14515 ub = SCIPvarGetUbLocal(var);
14516 if( SCIPsetIsInfinity(set, ub) )
14517 lp->looseobjvalinf--;
14518 else
14519 {
14520 SCIPintervalSet(&bd, ub);
14521 SCIPintervalSet(&ob, obj);
14522 SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
14523 SCIPintervalSub(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval -= ub * obj; */
14524 }
14525 }
14526 lp->nloosevars--;
14527
14528 /* get rid of numerical problems: set loose objective value explicitly to zero, if no loose variables remain */
14529 if( lp->nloosevars == 0 )
14530 {
14531 assert(lp->looseobjvalinf == 0);
14532 lp->looseobjval = 0.0;
14533 }
14534 else
14535 lp->looseobjval = SCIPintervalGetInf(loose);
14536
14537 return SCIP_OKAY;
14538}
14539
14540/** informs LP, that given formerly loose problem variable is now a column variable */
14542 SCIP_LP* lp, /**< current LP data */
14543 SCIP_SET* set, /**< global SCIP settings */
14544 SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
14545 )
14546{
14547 assert(set != NULL);
14548
14549 if( set->exact_enable )
14550 {
14552 }
14553 else
14554 {
14556 }
14557
14558 return SCIP_OKAY;
14559}
14560
14561/** informs LP, that given formerly column problem variable is now again a loose variable */
14562static
14564 SCIP_LP* lp, /**< current LP data */
14565 SCIP_SET* set, /**< global SCIP settings */
14566 SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
14567 )
14568{
14569 SCIP_Real obj;
14570 SCIP_Real lb;
14571 SCIP_Real ub;
14572
14573 assert(lp != NULL);
14576 assert(lp->looseobjvalinf >= 0);
14577
14579
14580 /* update loose objective value corresponding to the addition of variable */
14581 if( SCIPsetIsPositive(set, obj) )
14582 {
14583 lb = SCIPvarGetLbLocal(var);
14584 if( SCIPsetIsInfinity(set, -lb) )
14585 lp->looseobjvalinf++;
14586 else
14587 lpUpdateObjval(lp, set, var, lb * obj, 0, FALSE, TRUE, FALSE);
14588 }
14589 else if( SCIPsetIsNegative(set, obj) )
14590 {
14591 ub = SCIPvarGetUbLocal(var);
14592 if( SCIPsetIsInfinity(set, ub) )
14593 lp->looseobjvalinf++;
14594 else
14595 lpUpdateObjval(lp, set, var, ub * obj, 0, FALSE, TRUE, FALSE);
14596 }
14597 lp->nloosevars++;
14598
14599 assert(lp->looseobjvalinf >= 0);
14600
14601 return SCIP_OKAY;
14602}
14603
14604/** informs LP, that given formerly column problem variable is now again a loose variable
14605 * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
14606 */
14607static
14609 SCIP_LP* lp, /**< current LP data */
14610 SCIP_SET* set, /**< global SCIP settings */
14611 SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
14612 )
14613{
14614 SCIP_INTERVAL bd;
14615 SCIP_INTERVAL ob;
14616 SCIP_INTERVAL prod;
14617 SCIP_INTERVAL loose;
14618 SCIP_Real obj;
14619 SCIP_Real lb;
14620 SCIP_Real ub;
14621
14622 assert(lp != NULL);
14625
14627
14628 SCIPintervalSet(&loose, lp->looseobjval);
14629
14630 /* update loose objective value corresponding to the deletion of variable */
14631 if( obj > 0.0 )
14632 {
14633 lb = SCIPvarGetLbLocal(var);
14634 if( SCIPsetIsInfinity(set, -lb) )
14635 lp->looseobjvalinf++;
14636 else
14637 {
14638 SCIPintervalSet(&bd, lb);
14639 SCIPintervalSet(&ob, obj);
14640 SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
14641 SCIPintervalAdd(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval += lb * obj; */
14642 }
14643 }
14644 else if( SCIPsetIsNegative(set, obj) )
14645 {
14646 ub = SCIPvarGetUbLocal(var);
14647 if( SCIPsetIsInfinity(set, ub) )
14648 lp->looseobjvalinf++;
14649 else
14650 {
14651 SCIPintervalSet(&bd, ub);
14652 SCIPintervalSet(&ob, obj);
14653 SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
14654 SCIPintervalAdd(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval += ub * obj; */
14655 }
14656 }
14657 lp->nloosevars++;
14658
14659 lp->looseobjval = SCIPintervalGetInf(loose);
14660
14661 return SCIP_OKAY;
14662}
14663
14664/** informs LP, that given formerly column problem variable is now again a loose variable */
14666 SCIP_LP* lp, /**< current LP data */
14667 SCIP_SET* set, /**< global SCIP settings */
14668 SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
14669 )
14670{
14671 assert(set != NULL);
14672
14673 if( set->exact_enable )
14674 {
14676 }
14677 else
14678 {
14680 }
14681
14682 return SCIP_OKAY;
14683}
14684
14685/** decrease the number of loose variables by one */
14687 SCIP_LP* lp /**< current LP data */
14688 )
14689{
14690 assert(lp != NULL);
14691 assert(lp->nloosevars > 0);
14692
14693 lp->nloosevars--;
14694
14695 /* get rid of numerical problems: set loose objective value explicitly to zero, if no loose variables remain */
14696 if( lp->nloosevars == 0 )
14697 {
14698 assert(lp->looseobjvalinf == 0);
14699 lp->looseobjval = 0.0;
14700 }
14701}
14702
14703/** stores the LP solution in the columns and rows */
14705 SCIP_LP* lp, /**< current LP data */
14706 SCIP_SET* set, /**< global SCIP settings */
14707 SCIP_STAT* stat, /**< problem statistics */
14708 SCIP_Bool* primalfeasible, /**< pointer to store whether the solution is primal feasible, or NULL */
14709 SCIP_Bool* dualfeasible /**< pointer to store whether the solution is dual feasible, or NULL */
14710 )
14711{
14712 SCIP_COL** lpicols;
14713 SCIP_ROW** lpirows;
14715 SCIP_Real* dualsol;
14716 SCIP_Real* activity = NULL;
14717 SCIP_Real* redcost;
14718 SCIP_Real primalbound;
14719 SCIP_Real dualbound;
14720 SCIP_Bool stillprimalfeasible;
14721 SCIP_Bool stilldualfeasible;
14722 int* cstat;
14723 int* rstat;
14724 SCIP_Longint lpcount;
14725 int nlpicols;
14726 int nlpirows;
14727 int c;
14728 int r;
14729
14730 assert(lp != NULL);
14731 assert(lp->flushed);
14732 assert(lp->solved);
14733 assert(set != NULL);
14734 assert(stat != NULL);
14735 assert(lp->validsollp <= stat->lpcount);
14736
14737 /* initialize return and feasibility flags; if primal oder dual feasibility shall not be checked, we set the
14738 * corresponding flag immediately to FALSE to skip all checks
14739 */
14740 if( primalfeasible == NULL )
14741 stillprimalfeasible = FALSE;
14742 else
14743 {
14744 *primalfeasible = TRUE;
14745 stillprimalfeasible = TRUE;
14746 }
14747 if( dualfeasible == NULL )
14748 stilldualfeasible = FALSE;
14749 else
14750 {
14751 *dualfeasible = TRUE;
14752 stilldualfeasible = TRUE;
14753 }
14754
14755 /* check if the values are already calculated */
14756 if( lp->validsollp == stat->lpcount )
14757 return SCIP_OKAY;
14758 lp->validsollp = stat->lpcount;
14759
14760 SCIPsetDebugMsg(set, "getting new LP solution %" SCIP_LONGINT_FORMAT " for solstat %d\n",
14761 stat->lpcount, SCIPlpGetSolstat(lp));
14762
14763 lpicols = lp->lpicols;
14764 lpirows = lp->lpirows;
14765 nlpicols = lp->nlpicols;
14766 nlpirows = lp->nlpirows;
14767 lpcount = stat->lpcount;
14768
14769 /* get temporary memory */
14771 SCIP_CALL( SCIPsetAllocBufferArray(set, &dualsol, nlpirows) );
14772#ifdef SCIP_USE_LPSOLVER_ACTIVITY
14773 SCIP_CALL( SCIPsetAllocBufferArray(set, &activity, nlpirows) );
14774#endif
14775 SCIP_CALL( SCIPsetAllocBufferArray(set, &redcost, nlpicols) );
14776 SCIP_CALL( SCIPsetAllocBufferArray(set, &cstat, nlpicols) );
14777 SCIP_CALL( SCIPsetAllocBufferArray(set, &rstat, nlpirows) );
14778
14779 SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, dualsol, activity, redcost) );
14780 if( lp->solisbasic )
14781 {
14782 SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
14783 }
14784 else
14785 {
14786 BMSclearMemoryArray(cstat, nlpicols);
14787 BMSclearMemoryArray(rstat, nlpirows);
14788 }
14789
14790 primalbound = 0.0;
14791 dualbound = 0.0;
14792
14793 /* copy primal solution and reduced costs into columns */
14794 for( c = 0; c < nlpicols; ++c )
14795 {
14796 assert( 0 <= cstat[c] && cstat[c] < 4 );
14797 lpicols[c]->primsol = primsol[c];
14798 if( !SCIPisFinite(lpicols[c]->primsol) )
14799 {
14800 /* calculating with nan or +/-inf can have many unexpected effects
14801 * thus change the solution here to a reasonable value (0.0) and declare it as neither primal nor dual feasible
14802 * this should trigger a resolve of the LP, or a stop with an LP error
14803 */
14804 stillprimalfeasible = FALSE;
14805 stilldualfeasible = FALSE;
14806 lpicols[c]->primsol = 0.0;
14807 SCIPsetDebugMsg(set, " col <%s>: primsol=%.9f is not finite\n", SCIPvarGetName(lpicols[c]->var), primsol[c]);
14808 }
14809 lpicols[c]->minprimsol = MIN(lpicols[c]->minprimsol, primsol[c]);
14810 lpicols[c]->maxprimsol = MAX(lpicols[c]->maxprimsol, primsol[c]);
14811 lpicols[c]->redcost = redcost[c];
14812 lpicols[c]->basisstatus = (unsigned int) cstat[c];
14813 lpicols[c]->validredcostlp = lpcount;
14814 if( stillprimalfeasible )
14815 {
14816 stillprimalfeasible =
14817 (SCIPsetIsInfinity(set, -lpicols[c]->lb) || SCIPlpIsFeasGE(set, lp, lpicols[c]->primsol, lpicols[c]->lb))
14818 && (SCIPsetIsInfinity(set, lpicols[c]->ub) || SCIPlpIsFeasLE(set, lp, lpicols[c]->primsol, lpicols[c]->ub));
14819 primalbound += (lpicols[c]->primsol * lpicols[c]->obj);
14820 }
14821 if( lp->lastlpalgo == SCIP_LPALGO_BARRIER )
14822 {
14823 double compslack;
14824
14825 /* complementary slackness in barrier solutions is measured as product of primal slack and dual multiplier;
14826 * we use a slack of at most 1, because otherwise we multiply by something like SCIPinfinty() for unbounded
14827 * variables, which would magnify even the tiniest violation in the dual multiplier
14828 */
14829 if( stilldualfeasible )
14830 {
14831 compslack = MIN((lpicols[c]->primsol - lpicols[c]->lb), 1.0) * lpicols[c]->redcost;
14832 stilldualfeasible = !SCIPsetIsDualfeasPositive(set, compslack);
14833 }
14834 if( stilldualfeasible )
14835 {
14836 compslack = MIN((lpicols[c]->ub - lpicols[c]->primsol), 1.0) * lpicols[c]->redcost;
14837 stilldualfeasible = !SCIPsetIsDualfeasNegative(set, compslack);
14838 }
14839
14840 SCIPsetDebugMsg(set, " col <%s> [%.9g,%.9g]: primsol=%.9f, redcost=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14841 SCIPvarGetName(lpicols[c]->var), lpicols[c]->lb, lpicols[c]->ub, lpicols[c]->primsol, lpicols[c]->redcost,
14842 SCIPlpIsFeasGE(set, lp, lpicols[c]->primsol, lpicols[c]->lb),
14843 SCIPlpIsFeasLE(set, lp, lpicols[c]->primsol, lpicols[c]->ub),
14844 primalfeasible != NULL ? stillprimalfeasible : TRUE,
14845 !SCIPsetIsDualfeasPositive(set, MIN((lpicols[c]->primsol - lpicols[c]->lb), 1.0) * lpicols[c]->redcost),
14846 !SCIPsetIsDualfeasNegative(set, MIN((lpicols[c]->ub - lpicols[c]->primsol), 1.0) * lpicols[c]->redcost),
14847 dualfeasible != NULL ? stilldualfeasible : TRUE);
14848 }
14849 else
14850 {
14851 /* if dual feasibility check is disabled, set reduced costs of basic variables to 0 */
14852 if( dualfeasible == NULL && lpicols[c]->basisstatus == (unsigned int) SCIP_BASESTAT_BASIC )
14853 {
14854 lpicols[c]->redcost = 0.0;
14855 }
14856
14857 /* complementary slackness means that if a variable is not at its lower or upper bound, its reduced costs
14858 * must be non-positive or non-negative, respectively; in particular, if a variable is strictly within its
14859 * bounds, its reduced cost must be zero
14860 */
14861 if( stilldualfeasible
14862 && (SCIPsetIsInfinity(set, -lpicols[c]->lb) || SCIPlpIsFeasGT(set, lp, lpicols[c]->primsol, lpicols[c]->lb)) )
14863 stilldualfeasible = !SCIPsetIsDualfeasPositive(set, lpicols[c]->redcost);
14864 if( stilldualfeasible
14865 && (SCIPsetIsInfinity(set, lpicols[c]->ub) || SCIPlpIsFeasLT(set, lp, lpicols[c]->primsol, lpicols[c]->ub)) )
14866 stilldualfeasible = !SCIPsetIsDualfeasNegative(set, lpicols[c]->redcost);
14867
14868 SCIPsetDebugMsg(set, " col <%s> [%.9g,%.9g]: primsol=%.9f, redcost=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14869 SCIPvarGetName(lpicols[c]->var), lpicols[c]->lb, lpicols[c]->ub, lpicols[c]->primsol, lpicols[c]->redcost,
14870 SCIPlpIsFeasGE(set, lp, lpicols[c]->primsol, lpicols[c]->lb),
14871 SCIPlpIsFeasLE(set, lp, lpicols[c]->primsol, lpicols[c]->ub),
14872 primalfeasible != NULL ? stillprimalfeasible : TRUE,
14873 !SCIPlpIsFeasGT(set, lp, lpicols[c]->primsol, lpicols[c]->lb) || !SCIPsetIsDualfeasPositive(set, lpicols[c]->redcost),
14874 !SCIPlpIsFeasLT(set, lp, lpicols[c]->primsol, lpicols[c]->ub) || !SCIPsetIsDualfeasNegative(set, lpicols[c]->redcost),
14875 dualfeasible != NULL ? stilldualfeasible : TRUE);
14876 }
14877
14878 /* we intentionally use an exact positive/negative check because ignoring small reduced cost values may lead to a
14879 * wrong bound value; if the corresponding bound is +/-infinity, we use zero reduced cost (if stilldualfeasible is
14880 * TRUE, we are in the case that the reduced cost is tiny with wrong sign)
14881 */
14882 if( stilldualfeasible )
14883 {
14884 if( lpicols[c]->redcost > 0.0 && !SCIPsetIsInfinity(set, -lpicols[c]->lb) )
14885 dualbound += (lpicols[c]->redcost * lpicols[c]->lb);
14886 else if( lpicols[c]->redcost < 0.0 && !SCIPsetIsInfinity(set, lpicols[c]->ub) )
14887 dualbound += (lpicols[c]->redcost * lpicols[c]->ub);
14888 }
14889 }
14890
14891 /* copy dual solution and activities into rows */
14892 for( r = 0; r < nlpirows; ++r )
14893 {
14894 assert( 0 <= rstat[r] && rstat[r] < 4 );
14895 lpirows[r]->dualsol = dualsol[r];
14896#ifdef SCIP_USE_LPSOLVER_ACTIVITY
14897 lpirows[r]->activity = activity[r] + lpirows[r]->constant;
14898#else
14899 /* calculate row activity if invalid */
14900 if( lpirows[r]->validactivitylp != stat->lpcount )
14901 SCIProwRecalcLPActivity(lpirows[r], stat);
14902#endif
14903 lpirows[r]->basisstatus = (unsigned int) rstat[r]; /*lint !e732*/
14904 lpirows[r]->validactivitylp = lpcount;
14905 if( stillprimalfeasible )
14906 {
14907 stillprimalfeasible =
14908 (SCIPsetIsInfinity(set, -lpirows[r]->lhs) || SCIPlpIsFeasGE(set, lp, lpirows[r]->activity, lpirows[r]->lhs))
14909 && (SCIPsetIsInfinity(set, lpirows[r]->rhs) || SCIPlpIsFeasLE(set, lp, lpirows[r]->activity, lpirows[r]->rhs));
14910 }
14911 if( lp->lastlpalgo == SCIP_LPALGO_BARRIER )
14912 {
14913 double compslack;
14914
14915 /* complementary slackness in barrier solutions is measured as product of primal slack and dual multiplier;
14916 * we use a slack of at most 1, because otherwise we multiply by something like SCIPinfinity() for unbounded
14917 * variables, which would magnify even the tiniest violation in the dual multiplier
14918 */
14919 if( stilldualfeasible )
14920 {
14921 compslack = MIN((lpirows[r]->activity - lpirows[r]->lhs), 1.0) * lpirows[r]->dualsol;
14922 stilldualfeasible = !SCIPsetIsDualfeasPositive(set, compslack);
14923 }
14924 if( stilldualfeasible )
14925 {
14926 compslack = MIN((lpirows[r]->rhs - lpirows[r]->activity), 1.0) * lpirows[r]->dualsol;
14927 stilldualfeasible = !SCIPsetIsDualfeasNegative(set, compslack);
14928 }
14929
14930 SCIPsetDebugMsg(set, " row <%s> [%.9g,%.9g]: activity=%.9f, dualsol=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14931 lpirows[r]->name, lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->activity, lpirows[r]->dualsol,
14932 SCIPlpIsFeasGE(set, lp, lpirows[r]->activity, lpirows[r]->lhs),
14933 SCIPlpIsFeasLE(set, lp, lpirows[r]->activity, lpirows[r]->rhs),
14934 primalfeasible != NULL ? stillprimalfeasible : TRUE,
14935 !SCIPsetIsDualfeasPositive(set, MIN((lpirows[r]->activity - lpirows[r]->lhs), 1.0) * lpirows[r]->dualsol),
14936 !SCIPsetIsDualfeasNegative(set, MIN((lpirows[r]->rhs - lpirows[r]->activity), 1.0) * lpirows[r]->dualsol),
14937 dualfeasible != NULL ? stilldualfeasible : TRUE);
14938 }
14939 else
14940 {
14941 /* complementary slackness means that if the activity of a row is not at its left-hand or right-hand side,
14942 * its dual multiplier must be non-positive or non-negative, respectively; in particular, if the activity is
14943 * strictly within left-hand and right-hand side, its dual multiplier must be zero
14944 */
14945 if( stilldualfeasible &&
14946 (SCIPsetIsInfinity(set, -lpirows[r]->lhs) || SCIPlpIsFeasGT(set, lp, lpirows[r]->activity, lpirows[r]->lhs)) )
14947 stilldualfeasible = !SCIPsetIsDualfeasPositive(set, lpirows[r]->dualsol);
14948 if( stilldualfeasible &&
14949 (SCIPsetIsInfinity(set,lpirows[r]->rhs) || SCIPlpIsFeasLT(set, lp, lpirows[r]->activity, lpirows[r]->rhs)) )
14950 stilldualfeasible = !SCIPsetIsDualfeasNegative(set, lpirows[r]->dualsol);
14951
14952 SCIPsetDebugMsg(set, " row <%s> [%.9g,%.9g] + %.9g: activity=%.9f, dualsol=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14953 lpirows[r]->name, lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->constant, lpirows[r]->activity, lpirows[r]->dualsol,
14954 SCIPlpIsFeasGE(set, lp, lpirows[r]->activity, lpirows[r]->lhs),
14955 SCIPlpIsFeasLE(set, lp, lpirows[r]->activity, lpirows[r]->rhs),
14956 primalfeasible != NULL ? stillprimalfeasible : TRUE,
14957 !SCIPlpIsFeasGT(set, lp, lpirows[r]->activity, lpirows[r]->lhs) || !SCIPsetIsDualfeasPositive(set, lpirows[r]->dualsol),
14958 !SCIPlpIsFeasLT(set, lp, lpirows[r]->activity, lpirows[r]->rhs) || !SCIPsetIsDualfeasNegative(set, lpirows[r]->dualsol),
14959 dualfeasible != NULL ? stilldualfeasible : TRUE);
14960 }
14961
14962 /* we intentionally use an exact positive/negative check because ignoring small dual multipliers may lead to a
14963 * wrong bound value; if the corresponding side is +/-infinity, we use a zero dual multiplier (if
14964 * stilldualfeasible is TRUE, we are in the case that the dual multiplier is tiny with wrong sign)
14965 */
14966 if( stilldualfeasible )
14967 {
14968 if( lpirows[r]->dualsol > 0.0 && !SCIPsetIsInfinity(set, -lpirows[r]->lhs) )
14969 dualbound += (lpirows[r]->dualsol * (lpirows[r]->lhs - lpirows[r]->constant));
14970 else if( lpirows[r]->dualsol < 0.0 && !SCIPsetIsInfinity(set, lpirows[r]->rhs) )
14971 dualbound += (lpirows[r]->dualsol * (lpirows[r]->rhs - lpirows[r]->constant));
14972 }
14973 }
14974
14975 /* if the objective value returned by the LP solver is smaller than the internally computed primal bound, then we
14976 * declare the solution primal infeasible; we assume primalbound and lp->lpobjval to be equal if they are both +/-
14977 * infinity
14978 */
14979 /**@todo alternatively, if otherwise the LP solution is feasible, we could simply update the objective value */
14980 if( stillprimalfeasible && !(SCIPsetIsInfinity(set, primalbound) && SCIPsetIsInfinity(set, lp->lpobjval))
14981 && !(SCIPsetIsInfinity(set, -primalbound) && SCIPsetIsInfinity(set, -lp->lpobjval)) )
14982 {
14983 stillprimalfeasible = SCIPsetIsFeasLE(set, primalbound, lp->lpobjval);
14984 SCIPsetDebugMsg(set, " primalbound=%.9f, lpbound=%.9g, pfeas=%u(%u)\n", primalbound, lp->lpobjval,
14985 SCIPsetIsFeasLE(set, primalbound, lp->lpobjval), primalfeasible != NULL ? stillprimalfeasible : TRUE);
14986 }
14987
14988 /* if the objective value returned by the LP solver is smaller than the internally computed dual bound, we declare
14989 * the solution dual infeasible; we assume dualbound and lp->lpobjval to be equal if they are both +/- infinity
14990 */
14991 /**@todo alternatively, if otherwise the LP solution is feasible, we could simply update the objective value */
14992 if( stilldualfeasible && !(SCIPsetIsInfinity(set, dualbound) && SCIPsetIsInfinity(set, lp->lpobjval))
14993 && !(SCIPsetIsInfinity(set, -dualbound) && SCIPsetIsInfinity(set, -lp->lpobjval)) )
14994 {
14995 stilldualfeasible = SCIPsetIsFeasGE(set, dualbound, lp->lpobjval);
14996 SCIPsetDebugMsg(set, " dualbound=%.9f, lpbound=%.9g, dfeas=%u(%u)\n", dualbound, lp->lpobjval,
14997 SCIPsetIsFeasGE(set, dualbound, lp->lpobjval), dualfeasible != NULL ? stilldualfeasible : TRUE);
14998 }
14999
15000 if( primalfeasible != NULL )
15001 *primalfeasible = stillprimalfeasible;
15002 if( dualfeasible != NULL )
15003 *dualfeasible = stilldualfeasible;
15004
15005 /* free temporary memory */
15006 SCIPsetFreeBufferArray(set, &rstat);
15007 SCIPsetFreeBufferArray(set, &cstat);
15008 SCIPsetFreeBufferArray(set, &redcost);
15009#ifdef SCIP_USE_LPSOLVER_ACTIVITY
15010 SCIPsetFreeBufferArray(set, &activity);
15011#endif
15012 SCIPsetFreeBufferArray(set, &dualsol);
15014
15015 return SCIP_OKAY;
15016}
15017
15018/** stores LP solution with infinite objective value in the columns and rows */
15020 SCIP_LP* lp, /**< current LP data */
15021 SCIP_SET* set, /**< global SCIP settings */
15022 SCIP_STAT* stat, /**< problem statistics */
15023 SCIP_Bool* primalfeasible, /**< pointer to store whether the solution is primal feasible, or NULL */
15024 SCIP_Bool* rayfeasible /**< pointer to store whether the primal ray is a feasible unboundedness proof, or NULL */
15025 )
15026{
15027 SCIP_COL** lpicols;
15028 SCIP_ROW** lpirows;
15030 SCIP_Real* activity;
15031 SCIP_Real* ray;
15032 SCIP_Real rayobjval;
15033 SCIP_Real rayscale;
15034 SCIP_Longint lpcount;
15035 SCIP_COL* col;
15036 int nlpicols;
15037 int nlpirows;
15038 int c;
15039 int r;
15040
15041 assert(lp != NULL);
15042 assert(lp->flushed);
15043 assert(lp->solved);
15046 assert(set != NULL);
15047 assert(stat != NULL);
15048 assert(lp->validsollp <= stat->lpcount);
15049
15050 if( primalfeasible != NULL )
15051 *primalfeasible = TRUE;
15052 if( rayfeasible != NULL )
15053 *rayfeasible = TRUE;
15054
15055 /* check if the values are already calculated */
15056 if( lp->validsollp == stat->lpcount )
15057 return SCIP_OKAY;
15058 lp->validsollp = stat->lpcount;
15059
15060 /* check if the LP solver is able to provide a primal unbounded ray */
15061 if( !SCIPlpiHasPrimalRay(lp->lpi) )
15062 {
15063 SCIPerrorMessage("LP solver has no primal ray to prove unboundedness.\n");
15064 return SCIP_LPERROR;
15065 }
15066
15067 SCIPsetDebugMsg(set, "getting new unbounded LP solution %" SCIP_LONGINT_FORMAT "\n", stat->lpcount);
15068
15069 /* get temporary memory */
15071 SCIP_CALL( SCIPsetAllocBufferArray(set, &activity, lp->nlpirows) );
15073
15074 /* get primal unbounded ray */
15075 SCIP_CALL( SCIPlpiGetPrimalRay(lp->lpi, ray) );
15076
15077 lpicols = lp->lpicols;
15078 lpirows = lp->lpirows;
15079 nlpicols = lp->nlpicols;
15080 nlpirows = lp->nlpirows;
15081 lpcount = stat->lpcount;
15082
15083 /* calculate the objective value decrease of the ray and heuristically try to construct primal solution */
15084 rayobjval = 0.0;
15085 for( c = 0; c < nlpicols; ++c )
15086 {
15087 assert(lpicols[c] != NULL);
15088 assert(lpicols[c]->var != NULL);
15089
15090 col = lpicols[c];
15091
15092 /* there should only be a nonzero value in the ray if there is no finite bound in this direction */
15093 if( rayfeasible != NULL )
15094 {
15095 *rayfeasible = *rayfeasible
15096 && (!SCIPsetIsNegative(set, ray[c]) || SCIPsetIsInfinity(set, -col->lb))
15097 && (!SCIPsetIsPositive(set, ray[c]) || SCIPsetIsInfinity(set, col->ub));
15098 }
15099
15100 if( ! SCIPsetIsZero(set, ray[c]) )
15101 rayobjval += ray[c] * col->obj;
15102
15103 /* Many LP solvers cannot directly provide a feasible solution if they detected unboundedness. We therefore first
15104 * heuristically try to construct a primal solution.
15105 */
15106 primsol[c] = 0.0;
15107 if( SCIPsetIsFeasZero(set, ray[c]) )
15108 {
15109 /* if the ray component is 0, we try to satisfy as many rows as possible */
15110 if( SCIPvarGetNLocksDown(col->var) == 0 && ! SCIPsetIsInfinity(set, -col->lb) )
15111 primsol[c] = col->lb;
15112 else if( SCIPvarGetNLocksUp(col->var) == 0 && ! SCIPsetIsInfinity(set, col->ub) )
15113 primsol[c] = col->ub;
15114 }
15115
15116 /* make sure we respect the bounds */
15117 primsol[c] = MAX(primsol[c], col->lb);
15118 primsol[c] = MIN(primsol[c], col->ub);
15119
15120 assert( SCIPlpIsFeasGE(set, lp, primsol[c], col->lb) && SCIPlpIsFeasLE(set, lp, primsol[c], col->ub) );
15121 }
15122
15123 /* check feasibility of heuristic primal solution */
15124 for( r = 0; r < nlpirows; ++r )
15125 {
15126 SCIP_Real act;
15127 SCIP_ROW* row;
15128
15129 row = lpirows[r];
15130 assert( row != NULL );
15131 act = row->constant;
15132
15133 for( c = 0; c < row->nlpcols; ++c )
15134 {
15135 col = row->cols[c];
15136
15137 assert( col != NULL );
15138 assert( col->lppos >= 0 );
15139 assert( row->linkpos[c] >= 0 );
15140 assert( primsol[col->lppos] != SCIP_INVALID ); /*lint !e777*/
15141
15142 act += row->vals[c] * primsol[col->lppos];
15143 }
15144
15145 if( row->nunlinked > 0 )
15146 {
15147 for( c = row->nlpcols; c < row->len; ++c )
15148 {
15149 col = row->cols[c];
15150 assert( col != NULL );
15151
15152 if( col->lppos >= 0 )
15153 act += row->vals[c] * primsol[col->lppos];
15154 }
15155 }
15156
15157 /* check feasibility */
15158 if( (! SCIPsetIsInfinity(set, -row->lhs) && SCIPlpIsFeasLT(set, lp, act, row->lhs) ) ||
15159 (! SCIPsetIsInfinity(set, row->rhs) && SCIPlpIsFeasGT(set, lp, act, row->rhs) ) )
15160 break;
15161 }
15162
15163 /* if heuristic primal solution is not feasible, try to obtain solution from LPI */
15164 if( r < nlpirows )
15165 {
15166 /* get primal feasible point */
15168
15169 /* check bounds of primal solution */
15170 if( primalfeasible != NULL )
15171 {
15172 assert( *primalfeasible );
15173 for( c = 0; c < nlpicols; ++c )
15174 {
15175 assert( lpicols[c] != NULL );
15176 assert( lpicols[c]->var != NULL );
15177
15178 /* check whether primal solution satisfies the bounds; note that we also ensure that the primal
15179 * solution is within SCIP's infinity bounds; otherwise the rayscale below is not well-defined */
15180 if( SCIPsetIsInfinity(set, REALABS(primsol[c])) || SCIPlpIsFeasLT(set, lp, primsol[c], lpicols[c]->lb) ||
15181 SCIPlpIsFeasGT(set, lp, primsol[c], lpicols[c]->ub) )
15182 {
15183 *primalfeasible = FALSE;
15184 break;
15185 }
15186 }
15187 }
15188 }
15189
15190 /* compute activity and check feasibility of primal solution and ray */
15191 for( r = 0; r < nlpirows; ++r )
15192 {
15193 SCIP_Real primact;
15194 SCIP_Real rayact = 0.0;
15195 SCIP_ROW* row;
15196
15197 row = lpirows[r];
15198 assert( row != NULL );
15199
15200 primact = row->constant;
15201
15202 for( c = 0; c < row->nlpcols; ++c )
15203 {
15204 col = row->cols[c];
15205
15206 assert( col != NULL );
15207 assert( col->lppos >= 0 );
15208 assert( row->linkpos[c] >= 0 );
15209 assert( primsol[col->lppos] != SCIP_INVALID ); /*lint !e777*/
15210
15211 primact += row->vals[c] * primsol[col->lppos];
15212 rayact += row->vals[c] * ray[col->lppos];
15213 }
15214
15215 if( row->nunlinked > 0 )
15216 {
15217 for( c = row->nlpcols; c < row->len; ++c )
15218 {
15219 col = row->cols[c];
15220 assert( col != NULL );
15221
15222 if( col->lppos >= 0 )
15223 {
15224 primact += row->vals[c] * primsol[col->lppos];
15225 rayact += row->vals[c] * ray[col->lppos];
15226 }
15227 }
15228 }
15229
15230 /* check feasibility of primal solution */
15231 if( primalfeasible != NULL && *primalfeasible )
15232 {
15233 if(( ! SCIPsetIsInfinity(set, -row->lhs) && SCIPlpIsFeasLT(set, lp, primact, row->lhs) ) ||
15234 ( ! SCIPsetIsInfinity(set, row->rhs) && SCIPlpIsFeasGT(set, lp, primact, row->rhs) ) )
15235 *primalfeasible = FALSE;
15236 }
15237
15238 /* check feasibility of ray */
15239 if( rayfeasible != NULL && *rayfeasible )
15240 {
15241 if(( ! SCIPsetIsInfinity(set, -row->lhs) && SCIPlpIsFeasLT(set, lp, rayact, 0.0) ) ||
15242 ( ! SCIPsetIsInfinity(set, row->rhs) && SCIPlpIsFeasGT(set, lp, rayact, 0.0) ) )
15243 *rayfeasible = FALSE;
15244 }
15245
15246 /* store activity of primal solution */
15247 activity[r] = primact;
15248 }
15249
15250 if( primalfeasible != NULL && !(*primalfeasible) )
15251 {
15252 /* if the finite point is already infeasible, we do not have to add the ray */
15253 rayscale = 0.0;
15254 }
15255 else if( rayfeasible != NULL && !(*rayfeasible) )
15256 {
15257 /* if the ray is already infeasible (due to numerics), we do not want to add the ray */
15258 rayscale = 0.0;
15259 }
15260 else if( !SCIPsetIsNegative(set, rayobjval) )
15261 {
15262 /* due to numerical problems, the objective of the ray might be nonnegative
15263 *
15264 * @todo How to check for negative objective value here?
15265 */
15266 if( rayfeasible != NULL )
15267 *rayfeasible = FALSE;
15268
15269 rayscale = 0.0;
15270 }
15271 else
15272 {
15273 assert(rayobjval != 0.0);
15274
15275 /* scale the ray, such that the resulting point has infinite objective value */
15276 rayscale = -2.0 * SCIPsetInfinity(set) / rayobjval;
15277 assert(SCIPsetIsFeasPositive(set, rayscale));
15278
15279 /* ensure that unbounded point does not violate the bounds of the variables */
15280 for( c = 0; c < nlpicols; ++c )
15281 {
15282 if( SCIPsetIsPositive(set, ray[c]) )
15283 {
15284 if( !SCIPsetIsInfinity(set, primsol[c]) )
15285 rayscale = MIN(rayscale, (lpicols[c]->ub - primsol[c]) / ray[c]);
15286 /* if primsol is infinity, as well as the bound, don't scale the ray to 0 */
15287 else
15288 {
15289 assert(SCIPsetIsInfinity(set, lpicols[c]->ub));
15290 rayscale = MIN(rayscale, 1.0 / ray[c]);
15291 }
15292 }
15293 else if( SCIPsetIsNegative(set, ray[c]) )
15294 {
15295 if( !SCIPsetIsInfinity(set, -primsol[c]) )
15296 rayscale = MIN(rayscale, (lpicols[c]->lb - primsol[c]) / ray[c]);
15297 /* if primsol is infinity, as well as the bound, don't scale the ray to 0 */
15298 else
15299 {
15300 assert(SCIPsetIsInfinity(set, -lpicols[c]->lb));
15301 rayscale = MIN(rayscale, -1.0 / ray[c]);
15302 }
15303 }
15304
15305 assert(SCIPsetIsFeasPositive(set, rayscale));
15306 }
15307 }
15308
15309 SCIPsetDebugMsg(set, "unbounded LP solution: rayobjval=%f, rayscale=%f\n", rayobjval, rayscale);
15310
15311 /* calculate the unbounded point: x' = x + rayscale * ray */
15312 /* Note: We do not check the feasibility of the unbounded solution, because it will likely be infeasible due to the
15313 * typically large values in scaling. */
15314 for( c = 0; c < nlpicols; ++c )
15315 {
15316 if( SCIPsetIsZero(set, ray[c]) )
15317 lpicols[c]->primsol = primsol[c];
15318 else
15319 {
15320 SCIP_Real primsolval;
15321 primsolval = primsol[c] + rayscale * ray[c];
15322 lpicols[c]->primsol = MAX(-SCIPsetInfinity(set), MIN(SCIPsetInfinity(set), primsolval)); /*lint !e666*/
15323 }
15324 lpicols[c]->redcost = SCIP_INVALID;
15325 lpicols[c]->validredcostlp = -1;
15326 }
15327
15328 /* transfer solution */
15329 for( r = 0; r < nlpirows; ++r )
15330 {
15331 lpirows[r]->dualsol = SCIP_INVALID;
15332 lpirows[r]->activity = activity[r] + lpirows[r]->constant;
15333 lpirows[r]->validactivitylp = lpcount;
15334 }
15335
15336 /* free temporary memory */
15338 SCIPsetFreeBufferArray(set, &activity);
15340
15341 return SCIP_OKAY;
15342}
15343
15344/** returns primal ray proving the unboundedness of the current LP */
15346 SCIP_LP* lp, /**< current LP data */
15347 SCIP_SET* set, /**< global SCIP settings */
15348 SCIP_Real* ray /**< array for storing primal ray values, they are stored w.r.t. the problem index of the variables,
15349 * so the size of this array should be at least number of active variables
15350 * (all entries have to be initialized to 0 before) */
15351 )
15352{
15353 SCIP_COL** lpicols;
15354 SCIP_Real* lpiray;
15355 SCIP_VAR* var;
15356 int nlpicols;
15357 int c;
15358
15359 assert(lp != NULL);
15360 assert(set != NULL);
15361 assert(ray != NULL);
15362 assert(lp->flushed);
15363 assert(lp->solved);
15366
15367 /* check if the LP solver is able to provide a primal unbounded ray */
15368 if( !SCIPlpiHasPrimalRay(lp->lpi) )
15369 {
15370 SCIPerrorMessage("LP solver has no primal ray for unbounded LP\n");
15371 return SCIP_LPERROR;
15372 }
15373
15374 /* get temporary memory */
15376
15377 SCIPsetDebugMsg(set, "getting primal ray values\n");
15378
15379 /* get primal unbounded ray */
15380 SCIP_CALL( SCIPlpiGetPrimalRay(lp->lpi, lpiray) );
15381
15382 lpicols = lp->lpicols;
15383 nlpicols = lp->nlpicols;
15384
15385 /* store the ray values of active problem variables */
15386 for( c = 0; c < nlpicols; c++ )
15387 {
15388 assert(lpicols[c] != NULL);
15389
15390 var = lpicols[c]->var;
15391 assert(var != NULL);
15393 ray[SCIPvarGetProbindex(var)] = lpiray[c];
15394 }
15395
15396 SCIPsetFreeBufferArray(set, &lpiray);
15397
15398 return SCIP_OKAY;
15399}
15400
15401/** stores the dual Farkas multipliers for infeasibility proof in rows. besides, the proof is checked for validity if
15402 * lp/checkfarkas = TRUE.
15403 *
15404 * @note the check will not be performed if @p valid is NULL.
15405 */
15407 SCIP_LP* lp, /**< current LP data */
15408 SCIP_SET* set, /**< global SCIP settings */
15409 SCIP_STAT* stat, /**< problem statistics */
15410 SCIP_Bool forcedlpsolve, /**< would SCIP abort if the LP is not solved? */
15411 SCIP_Bool* valid /**< pointer to store whether the Farkas proof is valid or NULL */
15412 )
15413{
15414 SCIP_COL** lpicols;
15415 SCIP_ROW** lpirows;
15416 SCIP_Real* dualfarkas;
15417 SCIP_Real* farkascoefs;
15418 SCIP_Real farkaslhs;
15419 SCIP_Real maxactivity;
15420 SCIP_Bool checkfarkas;
15421 int nlpicols;
15422 int nlpirows;
15423 int c;
15424 int r;
15425
15426 assert(lp != NULL);
15427 assert(lp->flushed);
15428 assert(lp->solved);
15430 assert(set != NULL);
15431 assert(stat != NULL);
15432 assert(lp->validfarkaslp <= stat->lpcount);
15433
15434 if( valid != NULL )
15435 *valid = TRUE;
15436
15437 /* check if the values are already calculated */
15438 if( lp->validfarkaslp == stat->lpcount )
15439 return SCIP_OKAY;
15440 lp->validfarkaslp = stat->lpcount;
15441
15442 farkascoefs = NULL;
15443 maxactivity = 0.0;
15444 farkaslhs = 0.0;
15445 checkfarkas = set->lp_checkfarkas && valid != NULL;
15446
15447 /* get temporary memory */
15448 SCIP_CALL( SCIPsetAllocBufferArray(set, &dualfarkas, lp->nlpirows) );
15449
15450 if( checkfarkas )
15451 {
15452 SCIP_CALL( SCIPsetAllocBufferArray(set, &farkascoefs, lp->nlpicols) );
15453 BMSclearMemoryArray(farkascoefs, lp->nlpicols);
15454 }
15455
15456 /* get dual Farkas infeasibility proof */
15457 SCIP_CALL( SCIPlpiGetDualfarkas(lp->lpi, dualfarkas) );
15458
15459 lpicols = lp->lpicols;
15460 lpirows = lp->lpirows;
15461 nlpicols = lp->nlpicols;
15462 nlpirows = lp->nlpirows;
15463
15464 /* store infeasibility proof in rows */
15465 SCIPsetDebugMsg(set, "LP is infeasible:\n");
15466 for( r = 0; r < nlpirows; ++r )
15467 {
15468 SCIPsetDebugMsg(set, " row <%s>: dualfarkas=%f\n", lpirows[r]->name, dualfarkas[r]);
15469 lpirows[r]->dualfarkas = dualfarkas[r];
15470 lpirows[r]->dualsol = SCIP_INVALID;
15471 lpirows[r]->activity = 0.0;
15472 lpirows[r]->validactivitylp = -1L;
15473 lpirows[r]->basisstatus = (unsigned int) SCIP_BASESTAT_BASIC;
15474
15475 if( checkfarkas && dualfarkas[r] != 0.0 ) /*lint !e777*/
15476 {
15477 assert(valid != NULL);
15478 assert(farkascoefs != NULL);
15479
15480 /* the infeasibility proof would be invalid if
15481 * (i) dualfarkas[r] > 0 and lhs = -inf
15482 * (ii) dualfarkas[r] < 0 and rhs = inf
15483 * however, due to numerics we accept slightly negative / positive values
15484 */
15485 if( (SCIPsetIsDualfeasGT(set, dualfarkas[r], 0.0) && SCIPsetIsInfinity(set, -lpirows[r]->lhs))
15486 || (SCIPsetIsDualfeasLT(set, dualfarkas[r], 0.0) && SCIPsetIsInfinity(set, lpirows[r]->rhs)) )
15487 {
15488 SCIPsetDebugMsg(set, "farkas proof is invalid: row <%s>[lhs=%g,rhs=%g,c=%g] has multiplier %g\n",
15489 SCIProwGetName(lpirows[r]), lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->constant, dualfarkas[r]);
15490
15491 *valid = FALSE;
15492 goto TERMINATE;
15493 }
15494
15495 /* dual multipliers, for which the corresponding row side in infinite, are treated as zero if they are zero
15496 * within tolerances (see above) but slighty positive / negative
15497 */
15498 if( (dualfarkas[r] > 0.0 && SCIPsetIsInfinity(set, -lpirows[r]->lhs))
15499 || (dualfarkas[r] < 0.0 && SCIPsetIsInfinity(set, lpirows[r]->rhs)) )
15500 continue;
15501
15502 /* iterate over all columns and scale with dual solution */
15503 for( c = 0; c < lpirows[r]->len; c++ )
15504 {
15505 int pos = SCIPcolGetLPPos(lpirows[r]->cols[c]);
15506
15507 if( pos == -1 )
15508 continue;
15509
15510 assert(pos >= 0 && pos < nlpicols);
15511
15512 farkascoefs[pos] += dualfarkas[r] * lpirows[r]->vals[c];
15513 }
15514
15515 /* the row contributes with its left-hand side to the proof */
15516 if( dualfarkas[r] > 0.0 )
15517 {
15518 assert(!SCIPsetIsInfinity(set, -lpirows[r]->lhs));
15519
15520 farkaslhs += dualfarkas[r] * lpirows[r]->lhs;
15521 }
15522 /* the row contributes with its right-hand side to the proof */
15523 else if( dualfarkas[r] < 0.0 )
15524 {
15525 assert(!SCIPsetIsInfinity(set, lpirows[r]->rhs));
15526
15527 farkaslhs += dualfarkas[r] * lpirows[r]->rhs;
15528 }
15529
15530 maxactivity += dualfarkas[r] * lpirows[r]->constant;
15531 }
15532 }
15533
15534 /* set columns as invalid */
15535 for( c = 0; c < nlpicols; ++c )
15536 {
15537 lpicols[c]->primsol = SCIP_INVALID;
15538 lpicols[c]->redcost = SCIP_INVALID;
15539 lpicols[c]->validredcostlp = -1L;
15540 lpicols[c]->validfarkaslp = -1L;
15541
15542 if( checkfarkas )
15543 {
15544 assert(valid != NULL);
15545 assert(farkascoefs != NULL);
15546 assert(SCIPcolGetLPPos(lpicols[c]) == c);
15547
15548 /* skip coefficients that are too close to zero */
15549 if( SCIPsetIsDualfeasZero(set, farkascoefs[c]) )
15550 continue;
15551
15552 /* calculate the maximal activity */
15553 if( farkascoefs[c] > 0.0 )
15554 {
15555 maxactivity += farkascoefs[c] * lpicols[c]->ub;
15556
15557 if( SCIPsetIsInfinity(set, lpicols[c]->ub) )
15558 {
15559 SCIPsetDebugMsg(set, "farkas proof is invalid: col <%s>[lb=%g,ub=%g] has coefficient %g\n",
15560 SCIPvarGetName(SCIPcolGetVar(lpicols[c])), lpicols[c]->lb, lpicols[c]->ub, farkascoefs[c]);
15561
15562 *valid = FALSE;
15563 goto TERMINATE;
15564 }
15565 }
15566 else
15567 {
15568 maxactivity += farkascoefs[c] * lpicols[c]->lb;
15569
15570 if( SCIPsetIsInfinity(set, -lpicols[c]->lb) )
15571 {
15572 SCIPsetDebugMsg(set, "farkas proof is invalid: col <%s>[lb=%g,ub=%g] has coefficient %g\n",
15573 SCIPvarGetName(SCIPcolGetVar(lpicols[c])), lpicols[c]->lb, lpicols[c]->ub, farkascoefs[c]);
15574
15575 *valid = FALSE;
15576 goto TERMINATE;
15577 }
15578 }
15579 }
15580 }
15581
15582 /* check whether the farkasproof is valid for relative epsilon tolerance to allow feasibility tightening */
15583 if( checkfarkas
15584 && ( SCIPsetIsInfinity(set, maxactivity) || SCIPsetIsInfinity(set, -farkaslhs) || SCIPsetIsRelGE(set, maxactivity, farkaslhs) ) )
15585 {
15586 assert(valid != NULL);
15587
15588 SCIPsetDebugMsg(set, "farkas proof is invalid: maxactivity=%.12f, lhs=%.12f\n", maxactivity, farkaslhs);
15589
15590 if( forcedlpsolve && SCIPsetIsLT(set, maxactivity, farkaslhs) )
15591 SCIPmessagePrintWarning(set->scip->messagehdlr, "Unreliable farkas proof forced valid, result might not be optimal.\n");
15592 else
15593 *valid = FALSE;
15594 }
15595
15596 TERMINATE:
15597 /* free temporary memory */
15598 if( checkfarkas )
15599 SCIPsetFreeBufferArray(set, &farkascoefs);
15600
15601 SCIPsetFreeBufferArray(set, &dualfarkas);
15602
15603 return SCIP_OKAY;
15604}
15605
15606/** get number of iterations used in last LP solve */
15608 SCIP_LP* lp, /**< current LP data */
15609 int* iterations /**< pointer to store the iteration count */
15610 )
15611{
15612 assert(lp != NULL);
15613
15614 SCIP_CALL( SCIPlpiGetIterations(lp->lpi, iterations) );
15615
15616 return SCIP_OKAY;
15617}
15618
15619/** increases age of columns with solution value 0.0 and basic rows with activity not at its bounds,
15620 * resets age of non-zero columns and sharp rows
15621 */
15623 SCIP_LP* lp, /**< current LP data */
15624 SCIP_STAT* stat /**< problem statistics */
15625 )
15626{
15627 SCIP_COL** lpicols;
15628 SCIP_ROW** lpirows;
15629 int nlpicols;
15630 int nlpirows;
15631 int c;
15632 int r;
15633
15634 assert(lp != NULL);
15635 assert(lp->flushed);
15636 assert(lp->solved);
15637 assert(lp->nlpicols == lp->ncols);
15638 assert(lp->nlpirows == lp->nrows);
15639 assert(stat != NULL);
15640 assert(lp->validsollp == stat->lpcount);
15641
15642 SCIPdebugMessage("updating LP ages\n");
15643
15644 lpicols = lp->lpicols;
15645 lpirows = lp->lpirows;
15646 nlpicols = lp->nlpicols;
15647 nlpirows = lp->nlpirows;
15648
15649 for( c = 0; c < nlpicols; ++c )
15650 {
15651 assert(lpicols[c] == lp->cols[c]);
15652 if( lpicols[c]->primsol == 0.0 ) /* non-basic columns to remove are exactly at 0.0 */
15653 lpicols[c]->age++;
15654 else
15655 lpicols[c]->age = 0;
15656 /*SCIPstatDebugMsg(stat, " -> col <%s>: primsol=%f, age=%d\n",
15657 SCIPvarGetName(lpicols[c]->var), lpicols[c]->primsol, lpicols[c]->age);*/
15658 }
15659
15660 for( r = 0; r < nlpirows; ++r )
15661 {
15662 lpirows[r]->nlpsaftercreation++;
15663 assert(lpirows[r] == lp->rows[r]);
15664
15665 if( lpirows[r]->dualsol == 0.0 ) /* basic rows to remove are exactly at 0.0 */
15666 {
15667 lpirows[r]->age++;
15668 }
15669 else
15670 {
15671 lpirows[r]->activeinlpcounter++;
15672 lpirows[r]->age = 0;
15673 }
15674 /*debugMsg(scip, " -> row <%s>: activity=%f, age=%d\n", lpirows[r]->name, lpirows[r]->activity, lpirows[r]->age);*/
15675 }
15676
15677 return SCIP_OKAY;
15678}
15679
15680/* deletes the marked columns from the LP and the LP interface */
15681static
15683 SCIP_LP* lp, /**< current LP data */
15684 SCIP_SET* set, /**< global SCIP settings */
15685 int* coldstat /**< deletion status of columns: 1 if column should be deleted, 0 if not */
15686 )
15687{
15688 SCIP_COL* col;
15689 int ncols;
15690 int c;
15691
15692 assert(lp != NULL);
15693 assert(lp->flushed);
15694 assert(lp->ncols == lp->nlpicols);
15695 assert(!lp->diving);
15696 assert(coldstat != NULL);
15697 assert(lp->nlazycols <= lp->ncols);
15698
15699 ncols = lp->ncols;
15700
15701 /* delete columns in LP solver */
15702 SCIP_CALL( SCIPlpiDelColset(lp->lpi, coldstat) );
15703
15704 /* update LP data respectively */
15705 for( c = 0; c < ncols; ++c )
15706 {
15707 col = lp->cols[c];
15708 assert(col != NULL);
15709 assert(col == lp->lpicols[c]);
15710 assert(coldstat[c] <= c);
15711 col->lppos = coldstat[c];
15712 if( coldstat[c] == -1 )
15713 {
15714 assert(col->removable);
15715
15716 /* mark column to be deleted from the LPI, update column arrays of all linked rows, and update the objective
15717 * function vector norms
15718 */
15719 markColDeleted(col);
15720 colUpdateDelLP(col, set);
15721 lpUpdateObjNorms(lp, set, col->unchangedobj, 0.0);
15722 col->lpdepth = -1;
15723
15724 lp->cols[c] = NULL;
15725 lp->lpicols[c] = NULL;
15726 lp->ncols--;
15727 lp->nremovablecols--;
15728 lp->nlpicols--;
15729 }
15730 else if( coldstat[c] < c )
15731 {
15732 assert(lp->cols[coldstat[c]] == NULL);
15733 assert(lp->lpicols[coldstat[c]] == NULL);
15734 lp->cols[coldstat[c]] = col;
15735 lp->lpicols[coldstat[c]] = col;
15736 lp->cols[coldstat[c]]->lppos = coldstat[c];
15737 lp->cols[coldstat[c]]->lpipos = coldstat[c];
15738 lp->cols[c] = NULL;
15739 lp->lpicols[c] = NULL;
15740 }
15741 }
15742
15743 /* remove columns which are deleted from the lazy column array */
15744 c = 0;
15745 while( c < lp->nlazycols )
15746 {
15747 if( lp->lazycols[c]->lpipos < 0 )
15748 {
15749 lp->lazycols[c] = lp->lazycols[lp->nlazycols-1];
15750 lp->nlazycols--;
15751 }
15752 else
15753 c++;
15754 }
15755
15756 /* mark LP to be unsolved */
15757 if( lp->ncols < ncols )
15758 {
15759 assert(lp->ncols == lp->nlpicols);
15760 assert(lp->nchgcols == 0);
15761 assert(lp->flushed);
15762
15763 lp->lpifirstchgcol = lp->nlpicols;
15764
15765 /* mark the current solution invalid */
15766 lp->solved = FALSE;
15767 lp->primalfeasible = FALSE;
15768 lp->primalchecked = FALSE;
15769 lp->lpobjval = SCIP_INVALID;
15771 }
15772
15774 checkLinks(lp);
15775
15776 return SCIP_OKAY;
15777}
15778
15779/* deletes the marked rows from the LP and the LP interface */
15780static
15782 SCIP_LP* lp, /**< current LP data */
15783 BMS_BLKMEM* blkmem, /**< block memory buffers */
15784 SCIP_SET* set, /**< global SCIP settings */
15785 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15786 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15787 int* rowdstat /**< deletion status of rows: 1 if row should be deleted, 0 if not */
15788 )
15789{
15790 SCIP_ROW* row;
15791 int nrows;
15792 int r;
15793
15794 assert(lp != NULL);
15795 assert(lp->flushed);
15796 assert(lp->nrows == lp->nlpirows);
15797 assert(!lp->diving);
15798 assert(rowdstat != NULL);
15799
15800 nrows = lp->nrows;
15801
15802 /* delete rows in LP solver */
15803 SCIP_CALL( SCIPlpiDelRowset(lp->lpi, rowdstat) );
15804
15805 /* update LP data respectively */
15806 for( r = 0; r < nrows; ++r )
15807 {
15808 row = lp->rows[r];
15809 assert(row == lp->lpirows[r]);
15810 assert(rowdstat[r] <= r);
15811 assert(row != NULL);
15812 row->lppos = rowdstat[r];
15813 if( rowdstat[r] == -1 )
15814 {
15815 if( row->removable )
15816 lp->nremovablerows--;
15817
15818 /* mark row to be deleted from the LPI and update row arrays of all linked columns */
15819 markRowDeleted(row);
15820 rowUpdateDelLP(row);
15821 row->lpdepth = -1;
15822
15823 /* check, if row deletion events are tracked
15824 * if so, issue ROWDELETEDLP event
15825 */
15826 if( eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWDELETEDLP) != 0 ) /*lint !e587*/
15827 {
15828 SCIP_EVENT* event;
15829
15830 SCIP_CALL( SCIPeventCreateRowDeletedLP(&event, blkmem, row) );
15831 SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
15832 }
15833
15834 SCIP_CALL( SCIProwRelease(&lp->lpirows[r], blkmem, set, lp) );
15835 SCIProwUnlock(lp->rows[r]);
15836 SCIP_CALL( SCIProwRelease(&lp->rows[r], blkmem, set, lp) );
15837 assert(lp->lpirows[r] == NULL);
15838 assert(lp->rows[r] == NULL);
15839 lp->nrows--;
15840 lp->nlpirows--;
15841 }
15842 else if( rowdstat[r] < r )
15843 {
15844 assert(lp->rows[rowdstat[r]] == NULL);
15845 assert(lp->lpirows[rowdstat[r]] == NULL);
15846 lp->rows[rowdstat[r]] = row;
15847 lp->lpirows[rowdstat[r]] = row;
15848 lp->rows[rowdstat[r]]->lppos = rowdstat[r];
15849 lp->rows[rowdstat[r]]->lpipos = rowdstat[r];
15850 lp->rows[r] = NULL;
15851 lp->lpirows[r] = NULL;
15852 }
15853 }
15854
15855 /* mark LP to be unsolved */
15856 if( lp->nrows < nrows )
15857 {
15858 assert(lp->nrows == lp->nlpirows);
15859 assert(lp->nchgrows == 0);
15860 assert(lp->flushed);
15861
15862 lp->lpifirstchgrow = lp->nlpirows;
15863
15864 /* mark the current solution invalid */
15865 lp->solved = FALSE;
15866 lp->dualfeasible = FALSE;
15867 lp->dualchecked = FALSE;
15868 lp->lpobjval = SCIP_INVALID;
15870 }
15871
15872 checkLinks(lp);
15873
15874 return SCIP_OKAY;
15875}
15876
15877/** removes all non-basic columns, that are too old, beginning with the given firstcol */
15878static
15880 SCIP_LP* lp, /**< current LP data */
15881 SCIP_SET* set, /**< global SCIP settings */
15882 SCIP_STAT* stat, /**< problem statistics */
15883 int firstcol /**< first column to check for clean up */
15884 )
15885{
15886 SCIP_COL** cols;
15887#ifndef NDEBUG
15888 SCIP_COL** lpicols;
15889#endif
15890 int* coldstat;
15891 int ncols;
15892 int ndelcols;
15893 int c;
15894
15895 assert(lp != NULL);
15896 assert(lp->flushed);
15897 assert(lp->ncols == lp->nlpicols);
15898 assert(lp->nremovablecols <= lp->ncols);
15899 assert(!lp->diving);
15900 assert(set != NULL);
15901 assert(stat != NULL);
15902
15903 if( lp->nremovablecols == 0 || set->lp_colagelimit == -1 || !lp->solisbasic )
15904 return SCIP_OKAY;
15905
15906 ncols = lp->ncols;
15907 cols = lp->cols;
15908#ifndef NDEBUG
15909 lpicols = lp->lpicols;
15910#endif
15911
15912 /* get temporary memory */
15913 SCIP_CALL( SCIPsetAllocBufferArray(set, &coldstat, ncols) );
15914
15915 /* mark obsolete columns to be deleted */
15916 ndelcols = 0;
15917 BMSclearMemoryArray(coldstat, ncols);
15918 for( c = firstcol; c < ncols; ++c )
15919 {
15920 assert(cols[c] == lpicols[c]);
15921 assert(cols[c]->lppos == c);
15922 assert(cols[c]->lpipos == c);
15923 if( cols[c]->removable
15924 && cols[c]->obsoletenode != stat->nnodes /* don't remove column a second time from same node (avoid cycling), or a first time if marked nonremovable locally */
15925 && cols[c]->age > set->lp_colagelimit
15927 && SCIPsetIsZero(set, SCIPcolGetBestBound(cols[c])) ) /* bestbd != 0 -> column would be priced in next time */
15928 {
15929 assert(cols[c]->primsol == 0.0);
15930 coldstat[c] = 1;
15931 ndelcols++;
15932 cols[c]->obsoletenode = stat->nnodes;
15933 SCIPsetDebugMsg(set, "removing obsolete col <%s>: primsol=%f, bounds=[%g,%g]\n",
15934 SCIPvarGetName(cols[c]->var), cols[c]->primsol, cols[c]->lb, cols[c]->ub);
15935 }
15936 }
15937
15938 SCIPsetDebugMsg(set, "removing %d/%d obsolete columns from LP\n", ndelcols, ncols);
15939
15940 /* delete the marked columns in the LP solver interface, update the LP respectively */
15941 if( ndelcols > 0 )
15942 {
15943 SCIP_CALL( lpDelColset(lp, set, coldstat) );
15944 }
15945 assert(lp->ncols == ncols - ndelcols);
15946
15947 /* release temporary memory */
15948 SCIPsetFreeBufferArray(set, &coldstat);
15949
15950 return SCIP_OKAY;
15951}
15952
15953/** removes all basic rows, that are too old, beginning with the given firstrow */
15954static
15956 SCIP_LP* lp, /**< current LP data */
15957 BMS_BLKMEM* blkmem, /**< block memory buffers */
15958 SCIP_SET* set, /**< global SCIP settings */
15959 SCIP_STAT* stat, /**< problem statistics */
15960 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15961 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15962 int firstrow /**< first row to check for clean up */
15963 )
15964{
15965 SCIP_ROW** rows;
15966#ifndef NDEBUG
15967 SCIP_ROW** lpirows;
15968#endif
15969 int* rowdstat;
15970 int nrows;
15971 int ndelrows;
15972 int r;
15973
15974 assert(lp != NULL);
15975 assert(lp->flushed);
15976 assert(lp->nrows == lp->nlpirows);
15977 assert(lp->nremovablerows <= lp->nrows);
15978 assert(!lp->diving);
15979 assert(set != NULL);
15980 assert(stat != NULL);
15981
15982 if( lp->nremovablerows == 0 || set->lp_rowagelimit == -1 || !lp->solisbasic )
15983 return SCIP_OKAY;
15984
15985 nrows = lp->nrows;
15986 rows = lp->rows;
15987#ifndef NDEBUG
15988 lpirows = lp->lpirows;
15989#endif
15990
15991 /* get temporary memory */
15992 SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
15993
15994 /* mark obsolete rows to be deleted */
15995 ndelrows = 0;
15996 BMSclearMemoryArray(rowdstat, nrows);
15997 for( r = firstrow; r < nrows; ++r )
15998 {
15999 assert(rows[r] == lpirows[r]);
16000 assert(rows[r]->lppos == r);
16001 assert(rows[r]->lpipos == r);
16002 if( rows[r]->removable
16003 && rows[r]->obsoletenode != stat->nnodes /* don't remove row a second time from same node (avoid cycling), or a first time if marked nonremovable locally */
16004 && rows[r]->age > set->lp_rowagelimit
16006 {
16007 rowdstat[r] = 1;
16008 ndelrows++;
16009 rows[r]->obsoletenode = stat->nnodes;
16010 SCIPsetDebugMsg(set, "removing obsolete row <%s>: activity=%f, sides=[%g,%g]\n",
16011 rows[r]->name, rows[r]->activity, rows[r]->lhs, rows[r]->rhs);
16012 }
16013 }
16014
16015 SCIPsetDebugMsg(set, "removing %d/%d obsolete rows from LP\n", ndelrows, nrows);
16016
16017 /* delete the marked rows in the LP solver interface, update the LP respectively */
16018 if( ndelrows > 0 )
16019 {
16020 SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
16021 }
16022 assert(lp->nrows == nrows - ndelrows);
16023
16024 /* release temporary memory */
16025 SCIPsetFreeBufferArray(set, &rowdstat);
16026
16027 return SCIP_OKAY;
16028}
16029
16030/** removes all non-basic columns and basic rows in the part of the LP created at the current node, that are too old */
16032 SCIP_LP* lp, /**< current LP data */
16033 BMS_BLKMEM* blkmem, /**< block memory buffers */
16034 SCIP_SET* set, /**< global SCIP settings */
16035 SCIP_STAT* stat, /**< problem statistics */
16036 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
16037 SCIP_EVENTFILTER* eventfilter /**< global event filter */
16038 )
16039{
16040 assert(lp != NULL);
16041 assert(lp->solved);
16042 assert(!lp->diving);
16044 assert(set != NULL);
16045
16046 SCIPsetDebugMsg(set, "removing obsolete columns starting with %d/%d, obsolete rows starting with %d/%d\n",
16047 lp->firstnewcol, lp->ncols, lp->firstnewrow, lp->nrows);
16048
16049 if( lp->firstnewcol < lp->ncols )
16050 {
16051 SCIP_CALL( lpRemoveObsoleteCols(lp, set, stat, lp->firstnewcol) );
16052 }
16053 if( lp->firstnewrow < lp->nrows )
16054 {
16055 SCIP_CALL( lpRemoveObsoleteRows(lp, blkmem, set, stat, eventqueue, eventfilter, lp->firstnewrow) );
16056 }
16057
16058 return SCIP_OKAY;
16059}
16060
16061/** removes all non-basic columns and basic rows in whole LP, that are too old */
16063 SCIP_LP* lp, /**< current LP data */
16064 BMS_BLKMEM* blkmem, /**< block memory buffers */
16065 SCIP_SET* set, /**< global SCIP settings */
16066 SCIP_STAT* stat, /**< problem statistics */
16067 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
16068 SCIP_EVENTFILTER* eventfilter /**< global event filter */
16069 )
16070{
16071 assert(lp != NULL);
16072 assert(lp->solved);
16073 assert(!lp->diving);
16075 assert(set != NULL);
16076
16077 SCIPsetDebugMsg(set, "removing all obsolete columns and rows\n");
16078
16079 if( 0 < lp->ncols )
16080 {
16081 SCIP_CALL( lpRemoveObsoleteCols(lp, set, stat, 0) );
16082 }
16083 if( 0 < lp->nrows )
16084 {
16085 SCIP_CALL( lpRemoveObsoleteRows(lp, blkmem, set, stat, eventqueue, eventfilter, 0) );
16086 }
16087
16088 return SCIP_OKAY;
16089}
16090
16091/** removes all non-basic columns at 0.0 beginning with the given firstcol */
16092static
16094 SCIP_LP* lp, /**< current LP data */
16095 SCIP_SET* set, /**< global SCIP settings */
16096 SCIP_STAT* stat, /**< problem statistics */
16097 int firstcol /**< first column to check for clean up */
16098 )
16099{
16100 SCIP_COL** cols;
16101 SCIP_COL** lpicols;
16102 int* coldstat;
16103 int ncols;
16104 int ndelcols;
16105 int c;
16106
16107 assert(lp != NULL);
16108 assert(lp->flushed);
16109 assert(lp->ncols == lp->nlpicols);
16110 assert(!lp->diving);
16111 assert(stat != NULL);
16112 assert(lp->validsollp == stat->lpcount);
16113 assert(0 <= firstcol && firstcol < lp->ncols);
16114
16115 if( lp->nremovablecols == 0 || !lp->solisbasic )
16116 return SCIP_OKAY;
16117
16118 ncols = lp->ncols;
16119 cols = lp->cols;
16120 lpicols = lp->lpicols;
16121
16122 /* get temporary memory */
16123 SCIP_CALL( SCIPsetAllocBufferArray(set, &coldstat, ncols) );
16124
16125 /* mark unused columns to be deleted */
16126 ndelcols = 0;
16127 BMSclearMemoryArray(coldstat, ncols);
16128 for( c = firstcol; c < ncols; ++c )
16129 {
16130 assert(cols[c] == lpicols[c]);
16131 assert(cols[c]->lppos == c);
16132 assert(cols[c]->lpipos == c);
16133 if( lpicols[c]->removable
16134 && (SCIP_BASESTAT)lpicols[c]->basisstatus != SCIP_BASESTAT_BASIC
16135 && lpicols[c]->primsol == 0.0 /* non-basic columns to remove are exactly at 0.0 */
16136 && SCIPsetIsZero(set, SCIPcolGetBestBound(cols[c])) ) /* bestbd != 0 -> column would be priced in next time */
16137 {
16138 coldstat[c] = 1;
16139 ndelcols++;
16140 }
16141 }
16142
16143 SCIPsetDebugMsg(set, "removing %d/%d unused columns from LP\n", ndelcols, ncols);
16144
16145 /* delete the marked columns in the LP solver interface, update the LP respectively */
16146 if( ndelcols > 0 )
16147 {
16148 SCIP_CALL( lpDelColset(lp, set, coldstat) );
16149 }
16150 assert(lp->ncols == ncols - ndelcols);
16151
16152 /* release temporary memory */
16153 SCIPsetFreeBufferArray(set, &coldstat);
16154
16155 return SCIP_OKAY;
16156}
16157
16158/** removes all basic rows beginning with the given firstrow */
16159static
16161 SCIP_LP* lp, /**< current LP data */
16162 BMS_BLKMEM* blkmem, /**< block memory buffers */
16163 SCIP_SET* set, /**< global SCIP settings */
16164 SCIP_STAT* stat, /**< problem statistics */
16165 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
16166 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
16167 int firstrow /**< first row to check for clean up */
16168 )
16169{
16170#ifndef NDEBUG
16171 SCIP_ROW** rows;
16172#endif
16173 SCIP_ROW** lpirows;
16174 int* rowdstat;
16175 int nrows;
16176 int ndelrows;
16177 int r;
16178
16179 assert(lp != NULL);
16180 assert(lp->flushed);
16181 assert(lp->ncols == lp->nlpicols);
16182 assert(lp->nrows == lp->nlpirows);
16183 assert(!lp->diving);
16184 assert(stat != NULL);
16185 assert(lp->validsollp == stat->lpcount);
16186 assert(0 <= firstrow && firstrow < lp->nrows);
16187
16188 if( lp->nremovablerows == 0 || !lp->solisbasic )
16189 return SCIP_OKAY;
16190
16191#ifndef NDEBUG
16192 rows = lp->rows;
16193#endif
16194 nrows = lp->nrows;
16195 lpirows = lp->lpirows;
16196
16197 /* get temporary memory */
16198 SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
16199
16200 /* mark unused rows to be deleted */
16201 ndelrows = 0;
16202 BMSclearMemoryArray(rowdstat, nrows);
16203 for( r = firstrow; r < nrows; ++r )
16204 {
16205 assert(rows[r] == lpirows[r]);
16206 assert(rows[r]->lppos == r);
16207 assert(rows[r]->lpipos == r);
16208 if( lpirows[r]->removable && (SCIP_BASESTAT)lpirows[r]->basisstatus == SCIP_BASESTAT_BASIC )
16209 {
16210 rowdstat[r] = 1;
16211 ndelrows++;
16212 }
16213 }
16214
16215 SCIPsetDebugMsg(set, "removing %d/%d unused rows from LP\n", ndelrows, nrows);
16216
16217 /* delete the marked rows in the LP solver interface, update the LP respectively */
16218 if( ndelrows > 0 )
16219 {
16220 SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
16221 }
16222 assert(lp->nrows == nrows - ndelrows);
16223
16224 /* release temporary memory */
16225 SCIPsetFreeBufferArray(set, &rowdstat);
16226
16227 return SCIP_OKAY;
16228}
16229
16230/** removes all non-basic columns at 0.0 and basic rows in the part of the LP created at the current node */
16232 SCIP_LP* lp, /**< current LP data */
16233 BMS_BLKMEM* blkmem, /**< block memory buffers */
16234 SCIP_SET* set, /**< global SCIP settings */
16235 SCIP_STAT* stat, /**< problem statistics */
16236 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
16237 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
16238 SCIP_Bool root /**< are we at the root node? */
16239 )
16240{
16241 SCIP_Bool cleanupcols;
16242 SCIP_Bool cleanuprows;
16243
16244 assert(lp != NULL);
16245 assert(lp->solved);
16246 assert(!lp->diving);
16248 assert(set != NULL);
16249
16250 /* check, if we want to clean up the columns and rows */
16251 cleanupcols = (root ? set->lp_cleanupcolsroot : set->lp_cleanupcols);
16252 cleanuprows = (root ? set->lp_cleanuprowsroot : set->lp_cleanuprows);
16253
16254 SCIPsetDebugMsg(set, "removing unused columns starting with %d/%d (%u), unused rows starting with %d/%d (%u), LP algo: %d, basic sol: %u\n",
16255 lp->firstnewcol, lp->ncols, cleanupcols, lp->firstnewrow, lp->nrows, cleanuprows, lp->lastlpalgo, lp->solisbasic);
16256
16257 if( cleanupcols && lp->firstnewcol < lp->ncols )
16258 {
16259 SCIP_CALL( lpCleanupCols(lp, set, stat, lp->firstnewcol) );
16260 }
16261 if( cleanuprows && lp->firstnewrow < lp->nrows )
16262 {
16263 SCIP_CALL( lpCleanupRows(lp, blkmem, set, stat, eventqueue, eventfilter, lp->firstnewrow) );
16264 }
16265
16266 return SCIP_OKAY;
16267}
16268
16269/** removes all non-basic columns at 0.0 and basic rows in the whole LP */
16271 SCIP_LP* lp, /**< current LP data */
16272 BMS_BLKMEM* blkmem, /**< block memory buffers */
16273 SCIP_SET* set, /**< global SCIP settings */
16274 SCIP_STAT* stat, /**< problem statistics */
16275 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
16276 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
16277 SCIP_Bool root /**< are we at the root node? */
16278 )
16279{
16280 SCIP_Bool cleanupcols;
16281 SCIP_Bool cleanuprows;
16282
16283 assert(lp != NULL);
16284 assert(lp->solved);
16285 assert(!lp->diving);
16287 assert(set != NULL);
16288
16289 /* check, if we want to clean up the columns and rows */
16290 cleanupcols = (root ? set->lp_cleanupcolsroot : set->lp_cleanupcols);
16291 cleanuprows = (root ? set->lp_cleanuprowsroot : set->lp_cleanuprows);
16292
16293 SCIPsetDebugMsg(set, "removing all unused columns (%u) and rows (%u), LP algo: %d, basic sol: %u\n",
16294 cleanupcols, cleanuprows, lp->lastlpalgo, lp->solisbasic);
16295
16296 if( cleanupcols && 0 < lp->ncols )
16297 {
16298 SCIP_CALL( lpCleanupCols(lp, set, stat, 0) );
16299 }
16300 if( cleanuprows && 0 < lp->nrows )
16301 {
16302 SCIP_CALL( lpCleanupRows(lp, blkmem, set, stat, eventqueue, eventfilter, 0) );
16303 }
16304
16305 return SCIP_OKAY;
16306}
16307
16308/** removes all redundant rows that were added at the current node */
16310 SCIP_LP* lp, /**< current LP data */
16311 BMS_BLKMEM* blkmem, /**< block memory buffers */
16312 SCIP_SET* set, /**< global SCIP settings */
16313 SCIP_STAT* stat, /**< problem statistics */
16314 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
16315 SCIP_EVENTFILTER* eventfilter /**< global event filter */
16316 )
16317{
16318#ifndef NDEBUG
16319 SCIP_ROW** rows;
16320#endif
16321 SCIP_ROW** lpirows;
16322 int* rowdstat;
16323 int nrows;
16324 int ndelrows;
16325 int r;
16326
16327 assert(lp != NULL);
16328 assert(lp->flushed);
16329 assert(lp->ncols == lp->nlpicols);
16330 assert(lp->nrows == lp->nlpirows);
16331 assert(!lp->diving);
16332 assert(stat != NULL);
16333 assert(lp->validsollp == stat->lpcount);
16334 assert(lp->firstnewrow <= lp->nrows);
16335
16336 if( lp->firstnewrow == lp->nrows )
16337 return SCIP_OKAY;
16338
16339#ifndef NDEBUG
16340 rows = lp->rows;
16341#endif
16342 nrows = lp->nrows;
16343 lpirows = lp->lpirows;
16344
16345 /* get temporary memory */
16346 SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
16347
16348 /* mark redundant rows to be deleted (only delete basic rows!) */
16349 ndelrows = 0;
16350 BMSclearMemoryArray(rowdstat, nrows);
16351 for( r = lp->firstnewrow; r < nrows; ++r )
16352 {
16353 assert(rows[r] == lpirows[r]);
16354 assert(rows[r]->lppos == r);
16355 assert(rows[r]->lpipos == r);
16356 if( (!lp->solisbasic || (SCIP_BASESTAT)lpirows[r]->basisstatus == SCIP_BASESTAT_BASIC)
16357 && SCIProwIsRedundant(lpirows[r], set, stat) )
16358 {
16359 SCIPsetDebugMsg(set, "basic row <%s> is redundant: sides=[%g,%g], act=[%g,%g]\n",
16360 SCIProwGetName(lpirows[r]), SCIProwGetLhs(lpirows[r]), SCIProwGetRhs(lpirows[r]),
16361 SCIProwGetMinActivity(lpirows[r], set, stat), SCIProwGetMaxActivity(lpirows[r], set, stat));
16362 rowdstat[r] = 1;
16363 ndelrows++;
16364 }
16365 }
16366
16367 SCIPsetDebugMsg(set, "removing %d/%d redundant basic rows from LP\n", ndelrows, nrows);
16368
16369 /* delete the marked rows in the LP solver interface, update the LP respectively */
16370 if( ndelrows > 0 )
16371 {
16372 SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
16373 }
16374 assert(lp->nrows == nrows - ndelrows);
16375
16376 /* release temporary memory */
16377 SCIPsetFreeBufferArray(set, &rowdstat);
16378
16379 return SCIP_OKAY;
16380}
16381
16382/** initiates LP diving */
16384 SCIP_LP* lp, /**< current LP data */
16385 BMS_BLKMEM* blkmem, /**< block memory */
16386 SCIP_SET* set, /**< global SCIP settings */
16387 SCIP_STAT* stat /**< problem statistics */
16388 )
16389{
16390 int c;
16391 int r;
16392
16393 assert(lp != NULL);
16394 assert(lp->flushed || !lp->solved);
16395 assert(!lp->diving);
16396 assert(!lp->probing);
16397 assert(lp->divelpistate == NULL);
16400 assert(lp->validsollp <= stat->lpcount);
16401 assert(blkmem != NULL);
16402 assert(set != NULL);
16403 assert(lp->ndivechgsides == 0);
16404
16405 SCIPsetDebugMsg(set, "diving started (LP flushed: %u, LP solved: %u, solstat: %d)\n",
16406 lp->flushed, lp->solved, SCIPlpGetSolstat(lp));
16407
16408#ifndef NDEBUG
16409 for( c = 0; c < lp->ncols; ++c )
16410 {
16411 assert(lp->cols[c] != NULL);
16412 assert(lp->cols[c]->var != NULL);
16414 assert(SCIPvarGetCol(lp->cols[c]->var) == lp->cols[c]);
16418 }
16419#endif
16420
16421 /* save current LPI state (basis information) */
16422 SCIP_CALL( SCIPlpiGetState(lp->lpi, blkmem, &lp->divelpistate) );
16427
16428 /* save current LP values dependent on the solution */
16429 SCIP_CALL( lpStoreSolVals(lp, stat, blkmem) );
16430 assert(lp->storedsolvals != NULL);
16431 if( !set->lp_resolverestore && lp->solved )
16432 {
16433 SCIP_Bool store = TRUE;
16434
16435 switch ( lp->lpsolstat )
16436 {
16438 SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
16439 assert(lp->validsollp == stat->lpcount);
16440 break;
16443 assert(lp->validsollp == stat->lpcount);
16444 break;
16448 SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
16449 assert(lp->validsollp == stat->lpcount);
16450 break;
16452 SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat, FALSE, NULL) );
16453 break;
16456 default:
16457 store = FALSE;
16458 }
16459
16460 if ( store )
16461 {
16462 for( c = 0; c < lp->ncols; ++c )
16463 {
16464 SCIP_CALL( colStoreSolVals(lp->cols[c], blkmem) );
16465 }
16466 for( r = 0; r < lp->nrows; ++r )
16467 {
16469 }
16470 }
16471 }
16472
16473 /* store LPI iteration limit */
16475
16476 /* remember the number of domain changes */
16477 lp->divenolddomchgs = stat->domchgcount;
16478
16479 /* store current number of rows */
16480 lp->ndivingrows = lp->nrows;
16481
16482 /* switch to diving mode */
16483 lp->diving = TRUE;
16484
16485 return SCIP_OKAY;
16486}
16487
16488/** quits LP diving and resets bounds and objective values of columns to the current node's values */
16490 SCIP_LP* lp, /**< current LP data */
16491 BMS_BLKMEM* blkmem, /**< block memory */
16492 SCIP_SET* set, /**< global SCIP settings */
16493 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
16494 SCIP_STAT* stat, /**< problem statistics */
16495 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
16496 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
16497 SCIP_PROB* prob, /**< problem data */
16498 SCIP_VAR** vars, /**< array with all active variables */
16499 int nvars /**< number of active variables */
16500 )
16501{
16502 SCIP_VAR* var;
16503 int v;
16504
16505 assert(lp != NULL);
16506 assert(lp->diving);
16507 assert(blkmem != NULL);
16508 assert(nvars == 0 || vars != NULL);
16509
16510 SCIPsetDebugMsg(set, "diving ended (LP flushed: %u, solstat: %d)\n", lp->flushed, SCIPlpGetSolstat(lp));
16511
16512 /* reset all columns' objective values and bounds to its original values */
16513 for( v = 0; v < nvars; ++v )
16514 {
16515 var = vars[v];
16516 assert(var != NULL);
16518 {
16522 }
16523 }
16524
16525 /* remove rows which were added in diving mode */
16526 SCIP_CALL( SCIPlpShrinkRows(lp, blkmem, set, eventqueue, eventfilter, lp->ndivingrows) );
16527
16528 /* undo changes to left hand sides and right hand sides */
16529 while( lp->ndivechgsides > 0 )
16530 {
16531 SCIP_Real oldside;
16532 SCIP_SIDETYPE sidetype;
16533 SCIP_ROW* row;
16534
16535 lp->ndivechgsides--;
16536 oldside = lp->divechgsides[lp->ndivechgsides];
16537 sidetype = lp->divechgsidetypes[lp->ndivechgsides];
16538 row = lp->divechgrows[lp->ndivechgsides];
16539
16540 if( sidetype == SCIP_SIDETYPE_LEFT )
16541 {
16542 SCIP_CALL( SCIProwChgLhs(row, blkmem, set, eventqueue, lp, oldside) );
16543 }
16544 else
16545 {
16546 SCIP_CALL( SCIProwChgRhs(row, blkmem, set, eventqueue, lp, oldside) );
16547 }
16548 }
16549
16550 /* restore LPI iteration limit */
16552
16553 /* reload LPI state saved at start of diving and free it afterwards; it may be NULL, in which case simply nothing
16554 * happens
16555 */
16556 SCIP_CALL( SCIPlpSetState(lp, blkmem, set, prob, eventqueue, lp->divelpistate,
16558 SCIP_CALL( SCIPlpFreeState(lp, blkmem, &lp->divelpistate) );
16559 lp->divelpwasprimfeas = TRUE;
16560 lp->divelpwasdualfeas = TRUE;
16563 assert(lp->divelpistate == NULL);
16564
16565 /* switch to standard (non-diving) mode */
16566 lp->diving = FALSE;
16567 lp->divingobjchg = FALSE;
16568
16569 /* if the LP was solved before starting the dive, but not to optimality (or unboundedness), then we need to solve the
16570 * LP again to reset the solution (e.g. we do not save the Farkas proof for infeasible LPs, because we assume that we
16571 * are not called in this case, anyway); restoring by solving the LP again in either case can be forced by setting
16572 * the parameter resolverestore to TRUE
16573 * restoring an unbounded ray after solve does not seem to work currently (bug 631), so we resolve also in this case
16574 */
16575 assert(lp->storedsolvals != NULL);
16576 if( lp->storedsolvals->lpissolved && !set->exact_enable
16577 && (set->lp_resolverestore || lp->storedsolvals->lpsolstat != SCIP_LPSOLSTAT_OPTIMAL || lp->divenolddomchgs < stat->domchgcount) )
16578 {
16580
16581 SCIP_CALL( SCIPlpSolveAndEval(lp, set, messagehdlr, blkmem, stat, eventqueue, eventfilter, prob, -1LL, FALSE, FALSE, FALSE, FALSE, &lperror) );
16582 if( lperror )
16583 {
16584 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved when resolving LP after diving");
16585 lp->resolvelperror = TRUE;
16586 }
16591 {
16592 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
16593 "LP was not resolved to a sufficient status after diving\n");
16594 lp->resolvelperror = TRUE;
16595 }
16596 }
16597 /* otherwise, we can just reload the buffered LP solution values at start of diving; this has the advantage that we
16598 * are guaranteed to continue with the same LP status as before diving, while in numerically difficult cases, a
16599 * re-solve as above can lead to a different LP status
16600 */
16601 else
16602 {
16603 int c;
16604 int r;
16605
16606 /* if there are lazy bounds, remove them from the LP */
16607 if( lp->nlazycols > 0 )
16608 {
16609 /* @todo avoid loosing primal feasibility here after changing the objective already did destroy dual feasibility;
16610 * first resolve LP?
16611 */
16613 assert(lp->diving == lp->divinglazyapplied);
16614
16615 /* flush changes to the LP solver */
16616 SCIP_CALL( SCIPlpFlush(lp, blkmem, set, prob, eventqueue) );
16617 }
16618
16619 /* increment lp counter to ensure that we do not use solution values from the last solved diving lp; only when we
16620 * are in exact diving mode, we do not want to increase it since we want to use the exact diving solution added
16621 * by the exactsol constraint handler
16622 */
16623 if( !SCIPlpExactDiving(lp->lpexact) )
16624 SCIPstatIncrement(stat, set, lpcount);
16625
16626 /* restore LP solution values in lp data, columns and rows */
16627 if( lp->storedsolvals->lpissolved &&
16634 )
16635 {
16636 SCIP_CALL( lpRestoreSolVals(lp, blkmem, stat->lpcount) );
16637
16638 for( c = 0; c < lp->ncols; ++c )
16639 {
16640 SCIP_CALL( colRestoreSolVals(lp->cols[c], blkmem, stat->lpcount, set->lp_freesolvalbuffers) );
16641 }
16642 for( r = 0; r < lp->nrows; ++r )
16643 {
16644 SCIP_CALL( rowRestoreSolVals(lp->rows[r], blkmem, stat->lpcount, set->lp_freesolvalbuffers, lp->storedsolvals->lpsolstat == SCIP_LPSOLSTAT_INFEASIBLE) );
16645 }
16646 }
16647 else
16648 {
16649 SCIP_CALL( lpRestoreSolVals(lp, blkmem, -1LL) );
16650 }
16651 }
16652
16653#ifndef NDEBUG
16654 {
16655 int c;
16656 for( c = 0; c < lp->ncols; ++c )
16657 {
16658 assert(lp->cols[c] != NULL);
16659 assert(lp->cols[c]->var != NULL);
16661 assert(SCIPvarGetCol(lp->cols[c]->var) == lp->cols[c]);
16662 assert(SCIPsetIsEQ(set, SCIPvarGetObj(lp->cols[c]->var), lp->cols[c]->obj));
16665 }
16666 }
16667#endif
16668
16669 return SCIP_OKAY;
16670}
16671
16672#define DIVESTACKGROWFACT 1.5
16673
16674/** records a current row side such that any change will be undone after diving */
16676 SCIP_LP* lp, /**< LP data object */
16677 SCIP_ROW* row, /**< row affected by the change */
16678 SCIP_SIDETYPE sidetype /**< side type */
16679 )
16680{
16681 assert(lp != NULL);
16682 assert(row != NULL);
16683
16684 if( lp->ndivechgsides == lp->divechgsidessize )
16685 {
16687 }
16689
16690 lp->divechgsides[lp->ndivechgsides] = (sidetype == SCIP_SIDETYPE_LEFT) ? row->lhs : row->rhs;
16691 lp->divechgsidetypes[lp->ndivechgsides] = sidetype;
16692 lp->divechgrows[lp->ndivechgsides] = row;
16693 lp->ndivechgsides++;
16694
16695 return SCIP_OKAY;
16696}
16697
16698/** informs the LP that probing mode was initiated */
16700 SCIP_LP* lp /**< current LP data */
16701 )
16702{
16703 assert(lp != NULL);
16704 assert(!lp->probing);
16705 assert(!lp->strongbranching);
16707
16708 lp->probing = TRUE;
16709
16710 return SCIP_OKAY;
16711}
16712
16713/** informs the LP that probing mode was finished */
16715 SCIP_LP* lp /**< current LP data */
16716 )
16717{
16718 assert(lp != NULL);
16719 assert(lp->probing);
16720 assert(!lp->strongbranching);
16722
16723 lp->probing = FALSE;
16724
16725 return SCIP_OKAY;
16726}
16727
16728/** informs the LP that the probing mode is now used for strongbranching */
16730 SCIP_LP* lp /**< current LP data */
16731 )
16732{
16733 assert(lp != NULL);
16734 assert(lp->probing);
16735 assert(!lp->strongbranching);
16737
16739}
16740
16741/** informs the LP that the probing mode is not used for strongbranching anymore */
16743 SCIP_LP* lp /**< current LP data */
16744 )
16745{
16746 assert(lp != NULL);
16747 assert(lp->probing);
16748 assert(!lp->strongbranching);
16750
16752}
16753
16754/** calculates y*b + min{(c - y*A)*x | lb <= x <= ub} for given vectors y and c;
16755 * the vector b is defined with b[i] = lhs[i] if y[i] >= 0, b[i] = rhs[i] if y[i] < 0
16756 * Calculating this value in interval arithmetics gives a proved lower LP bound for the following reason (assuming,
16757 * we have only left hand sides):
16758 * min{cx | b <= Ax, lb <= x <= ub}
16759 * >= min{cx | yb <= yAx, lb <= x <= ub} (restriction in minimum is relaxed)
16760 * == yb + min{cx - yb | yb <= yAx, lb <= x <= ub} (added yb - yb == 0)
16761 * >= yb + min{cx - yAx | yb <= yAx, lb <= x <= ub} (because yAx >= yb inside minimum)
16762 * >= yb + min{cx - yAx | lb <= x <= ub} (restriction in minimum is relaxed)
16763 */
16764static
16766 SCIP_LP* lp, /**< current LP data */
16767 SCIP_SET* set, /**< global SCIP settings */
16768 SCIP_Bool usefarkas, /**< use y = dual Farkas and c = 0 instead of y = dual solution and c = obj? */
16769 SCIP_Real* bound /**< result of interval arithmetic minimization */
16770 )
16771{
16772 SCIP_INTERVAL* yinter;
16774 SCIP_INTERVAL ytb;
16775 SCIP_INTERVAL prod;
16776 SCIP_INTERVAL diff;
16778 SCIP_INTERVAL minprod;
16780 SCIP_ROW* row;
16781 SCIP_COL* col;
16782 SCIP_Real y;
16783 SCIP_Real c;
16784 int i;
16785 int j;
16786
16787 assert(lp != NULL);
16788 assert(lp->solved);
16789 assert(set != NULL);
16790 assert(bound != NULL);
16791
16792 /* allocate buffer for storing y in interval arithmetic */
16793 SCIP_CALL( SCIPsetAllocBufferArray(set, &yinter, lp->nrows) );
16794
16795 /* create y vector in interval arithmetic, setting near zeros to zero; calculate y^Tb */
16796 SCIPintervalSet(&ytb, 0.0);
16797 for( j = 0; j < lp->nrows; ++j )
16798 {
16799 row = lp->rows[j];
16800 assert(row != NULL);
16801
16802 y = (usefarkas ? row->dualfarkas : row->dualsol);
16803
16805 {
16806 SCIPintervalSet(&yinter[j], y);
16807 SCIPintervalSet(&b, row->lhs - row->constant);
16808 }
16809 else if( SCIPsetIsFeasNegative(set, y) )
16810 {
16811 SCIPintervalSet(&yinter[j], y);
16812 SCIPintervalSet(&b, row->rhs - row->constant);
16813 }
16814 else
16815 {
16816 SCIPintervalSet(&yinter[j], 0.0);
16817 SCIPintervalSet(&b, 0.0);
16818 }
16819
16820 SCIPintervalMul(SCIPsetInfinity(set), &prod, yinter[j], b);
16821 SCIPintervalAdd(SCIPsetInfinity(set), &ytb, ytb, prod);
16822 }
16823
16824 /* calculate min{(c^T - y^TA)x} */
16825 SCIPintervalSet(&minprod, 0.0);
16826 for( j = 0; j < lp->ncols; ++j )
16827 {
16828 col = lp->cols[j];
16829 assert(col != NULL);
16830 assert(col->nunlinked == 0);
16831
16833
16834 c = usefarkas ? 0.0 : col->obj;
16835 SCIPintervalSet(&diff, c);
16836
16837 for( i = 0; i < col->nlprows; ++i )
16838 {
16839 assert(col->rows[i] != NULL);
16840 assert(col->rows[i]->lppos >= 0);
16841 assert(col->linkpos[i] >= 0);
16842 SCIPintervalSet(&a, col->vals[i]);
16843 SCIPintervalMul(SCIPsetInfinity(set), &prod, yinter[col->rows[i]->lppos], a);
16844 SCIPintervalSub(SCIPsetInfinity(set), &diff, diff, prod);
16845 }
16846
16847#ifndef NDEBUG
16848 for( i = col->nlprows; i < col->len; ++i )
16849 {
16850 assert(col->rows[i] != NULL);
16851 assert(col->rows[i]->lppos == -1);
16852 assert(col->rows[i]->dualsol == 0.0);
16853 assert(col->rows[i]->dualfarkas == 0.0);
16854 assert(col->linkpos[i] >= 0);
16855 }
16856#endif
16857
16858 SCIPintervalSetBounds(&x, col->lb, col->ub);
16859 SCIPintervalMul(SCIPsetInfinity(set), &diff, diff, x);
16860 SCIPintervalAdd(SCIPsetInfinity(set), &minprod, minprod, diff);
16861 }
16862
16863 /* add y^Tb */
16864 SCIPintervalAdd(SCIPsetInfinity(set), &minprod, minprod, ytb);
16865
16866 /* free buffer for storing y in interval arithmetic */
16867 SCIPsetFreeBufferArray(set, &yinter);
16868
16869 *bound = SCIPintervalGetInf(minprod);
16870
16871 return SCIP_OKAY;
16872}
16873
16874/** gets proven lower (dual) bound of last LP solution */
16876 SCIP_LP* lp, /**< current LP data */
16877 SCIP_SET* set, /**< global SCIP settings */
16878 SCIP_Real* bound /**< pointer to store proven dual bound */
16879 )
16880{
16882
16883 SCIPsetDebugMsg(set, "proved lower bound of LP: %.15g\n", *bound);
16884
16885 return SCIP_OKAY;
16886}
16887
16888/** gets proven dual bound of last LP solution */
16890 SCIP_LP* lp, /**< current LP data */
16891 SCIP_SET* set, /**< global SCIP settings */
16892 SCIP_Bool* proved /**< pointer to store whether infeasibility is proven */
16893 )
16894{
16896
16897 assert(proved != NULL);
16898
16899 SCIP_CALL( provedBound(lp, set, TRUE, &bound) );
16900
16901 *proved = (bound > 0.0);
16902
16903 SCIPsetDebugMsg(set, "proved Farkas value of LP: %g -> infeasibility %sproved\n", bound, *proved ? "" : "not ");
16904
16905 return SCIP_OKAY;
16906}
16907
16908
16909
16910/** writes LP to a file */
16912 SCIP_LP* lp, /**< current LP data */
16913 const char* fname /**< file name */
16914 )
16915{
16916 assert(lp != NULL);
16917 assert(fname != NULL);
16918
16919 SCIP_CALL( SCIPlpiWriteLP(lp->lpi, fname) );
16920
16921 return SCIP_OKAY;
16922}
16923
16924/** writes MIP relaxation of the current B&B node to a file */
16926 SCIP_LP* lp, /**< current LP data */
16927 SCIP_SET* set, /**< global SCIP settings */
16928 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
16929 const char* fname, /**< file name */
16930 SCIP_Bool genericnames, /**< should generic names like x_i and row_j be used in order to avoid
16931 * troubles with reserved symbols? */
16932 SCIP_Bool origobj, /**< should the original objective function be used? */
16933 SCIP_OBJSENSE objsense, /**< objective sense */
16934 SCIP_Real objscale, /**< objective scaling factor */
16935 SCIP_Real objoffset, /**< objective offset, e.g., caused by variable fixings in presolving */
16936 SCIP_Bool lazyconss /**< output removable rows as lazy constraints? */
16937 )
16938{
16939 FILE* file;
16940 int i;
16941 int j;
16942 char rowname[SCIP_MAXSTRLEN];
16943 SCIP_Real coeff;
16944
16945 assert(lp != NULL);
16946 assert(fname != NULL);
16947
16948 SCIPsetDebugMsg(set, "Start to write MIP to file <%s>\n", fname);
16949 file = fopen(fname, "w");
16950 if( file == NULL )
16951 {
16952 SCIPerrorMessage("cannot open file <%s> for writing\n", fname);
16953 SCIPprintSysError(fname);
16954 return SCIP_FILECREATEERROR;
16955 }
16956
16957 /* print comments */
16958 if( genericnames )
16959 SCIPmessageFPrintInfo(messagehdlr, file, "\\ Original Variable and Constraint Names have been replaced by generic names.\n");
16960 else
16961 {
16962 SCIPmessageFPrintInfo(messagehdlr, file, "\\ Warning: Variable and Constraint Names should not contain special characters like '+', '=' etc.\n");
16963 SCIPmessageFPrintInfo(messagehdlr, file, "\\ If this is the case, the model may be corrupted!\n");
16964 }
16965
16966 if( origobj && objoffset != 0.0 )
16967 {
16968 SCIPmessageFPrintInfo(messagehdlr, file, "\\ An artificial variable 'objoffset' has been added and fixed to 1.\n");
16969 SCIPmessageFPrintInfo(messagehdlr, file, "\\ Switching this variable to 0 will disable the offset in the objective.\n\n");
16970 }
16971
16972 /* print objective function */
16973 /**@note the transformed problem in SCIP is always a minimization problem */
16974 if( !origobj || objsense == SCIP_OBJSENSE_MINIMIZE )
16975 SCIPmessageFPrintInfo(messagehdlr, file, "Minimize");
16976 else
16977 SCIPmessageFPrintInfo(messagehdlr, file, "Maximize");
16978
16979 /* print objective */
16980 SCIPmessageFPrintInfo(messagehdlr, file, "\nObj:");
16981 j = 0;
16982 for( i = 0; i < lp->ncols; ++i )
16983 {
16984 if( lp->cols[i]->obj != 0.0 )
16985 {
16986 coeff = lp->cols[i]->obj;
16987 if( origobj )
16988 {
16989 coeff *= (SCIP_Real) objsense;
16990 coeff *= objscale;
16991 }
16992
16993 if( genericnames )
16994 SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", coeff, lp->cols[i]->lppos);
16995 else
16996 SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", coeff, lp->cols[i]->var->name);
16997
16998 ++j;
16999 if( j % 10 == 0 )
17000 SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
17001 }
17002 }
17003 /* add artificial variable 'objoffset' to transfer objective offset */
17004 if( origobj && objoffset != 0.0 )
17005 SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g objoffset", objoffset * (SCIP_Real) objsense * objscale);
17006
17007 /* print constraint section */
17008 SCIPmessageFPrintInfo(messagehdlr, file, "\nSubject to\n");
17009 for( i = 0; i < lp->nrows; i++ )
17010 {
17011 char type = 'i';
17012
17013 /* skip removable rows if we want to write them as lazy constraints */
17014 if ( lazyconss && SCIProwIsRemovable(lp->rows[i]) )
17015 continue;
17016
17017 /* constraint types: 'l' means: only lhs exists, 'r' means: only rhs exists, 'e' means: both sides exist and are
17018 * equal, 'b' and 'B' mean: both sides exist, if the type is 'b', the lhs will be written, if the type is 'B',
17019 * the rhs will be written. Ergo: set type to b first, change it to 'B' afterwards and go back to WRITEROW.
17020 * type 'i' means: lhs and rhs are both infinite */
17022 type = 'r';
17023 else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
17024 type = 'l';
17025 else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsEQ(set, lp->rows[i]->lhs, lp->rows[i]->rhs) )
17026 type = 'e';
17027 else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
17028 type = 'b';
17029
17030 /* print name of row */
17031 if( genericnames )
17032 (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "row_%d", lp->rows[i]->lppos);
17033 else
17034 (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s", lp->rows[i]->name);
17035
17036 WRITEROW:
17037 switch( type )
17038 {
17039 case 'r':
17040 case 'l':
17041 case 'e':
17042 if( strlen(rowname) > 0 )
17043 SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", rowname);
17044 break;
17045 case 'i':
17046 SCIPmessageFPrintInfo(messagehdlr, file, "\\\\ WARNING: The lhs and the rhs of the row with original name <%s>", lp->rows[i]->name);
17047 SCIPmessageFPrintInfo(messagehdlr, file, "are not in a valid range. The following two constraints may be corrupted!\n");
17048 SCIPmessagePrintWarning(messagehdlr, "The lhs and rhs of row <%s> are not in a valid range.\n", lp->rows[i]->name);
17049 type = 'b';
17050 /*lint -fallthrough*/
17051 case 'b':
17052 SCIPmessageFPrintInfo(messagehdlr, file, "%s_lhs: ", rowname);
17053 break;
17054 default:
17055 assert(type == 'B');
17056 SCIPmessageFPrintInfo(messagehdlr, file, "%s_rhs: ", rowname);
17057 break;
17058 }
17059
17060 /* print coefficients and variables */
17061 for( j = 0; j < lp->rows[i]->nlpcols; ++j )
17062 {
17063 if( genericnames )
17064 SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->lppos);
17065 else
17066 SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->var->name);
17067
17068 if( (j+1) % 10 == 0 )
17069 SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
17070 }
17071
17072 /* print right hand side */
17073 switch( type )
17074 {
17075 case 'b':
17076 SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
17077 type = 'B';
17078 goto WRITEROW;
17079 case 'l':
17080 SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
17081 break;
17082 case 'B':
17083 case 'r':
17084 SCIPmessageFPrintInfo(messagehdlr, file, " <= %.15g\n", lp->rows[i]->rhs - lp->rows[i]->constant);
17085 break;
17086 case 'e':
17087 SCIPmessageFPrintInfo(messagehdlr, file, " = %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
17088 break;
17089 default:
17090 SCIPerrorMessage("Undefined row type!\n");
17091 fclose(file);
17092 return SCIP_ERROR;
17093 }
17094 }
17095
17096 if ( lazyconss )
17097 {
17098 /* print lazy constraint section */
17099 SCIPmessageFPrintInfo(messagehdlr, file, "lazy constraints\n");
17100 for( i = 0; i < lp->nrows; i++ )
17101 {
17102 char type = 'i';
17103
17104 /* skip non-removable rows if we want to write lazy constraints */
17105 if ( ! SCIProwIsRemovable(lp->rows[i]) )
17106 continue;
17107
17108 /* constraint types: 'l' means: only lhs exists, 'r' means: only rhs exists, 'e' means: both sides exist and are
17109 * equal, 'b' and 'B' mean: both sides exist, if the type is 'b', the lhs will be written, if the type is 'B',
17110 * the rhs will be written. Ergo: set type to b first, change it to 'B' afterwards and go back to WRITEROW.
17111 * type 'i' means: lhs and rhs are both infinite */
17113 type = 'r';
17114 else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
17115 type = 'l';
17116 else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsEQ(set, lp->rows[i]->lhs, lp->rows[i]->rhs) )
17117 type = 'e';
17118 else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
17119 type = 'b';
17120
17121 /* print name of row */
17122 if( genericnames )
17123 (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "row_%d", lp->rows[i]->lppos);
17124 else
17125 (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s", lp->rows[i]->name);
17126
17127 WRITELAZYROW:
17128 switch( type )
17129 {
17130 case 'r':
17131 case 'l':
17132 case 'e':
17133 if( strlen(rowname) > 0 )
17134 SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", rowname);
17135 break;
17136 case 'i':
17137 SCIPmessageFPrintInfo(messagehdlr, file, "\\\\ WARNING: The lhs and the rhs of the row with original name <%s>", lp->rows[i]->name);
17138 SCIPmessageFPrintInfo(messagehdlr, file, "are not in a valid range. The following two constraints may be corrupted!\n");
17139 SCIPmessagePrintWarning(messagehdlr, "The lhs and rhs of row <%s> are not in a valid range.\n",lp->rows[i]->name);
17140 type = 'b';
17141 /*lint -fallthrough*/
17142 case 'b':
17143 SCIPmessageFPrintInfo(messagehdlr, file, "%s_lhs: ", rowname);
17144 break;
17145 default:
17146 assert(type == 'B');
17147 SCIPmessageFPrintInfo(messagehdlr, file, "%s_rhs: ", rowname);
17148 break;
17149 }
17150
17151 /* print coefficients and variables */
17152 for( j = 0; j < lp->rows[i]->nlpcols; ++j )
17153 {
17154 if( genericnames )
17155 SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->lppos);
17156 else
17157 SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->var->name);
17158
17159 if( (j+1) % 10 == 0 )
17160 SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
17161 }
17162
17163 /* print right hand side */
17164 switch( type )
17165 {
17166 case 'b':
17167 SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
17168 type = 'B';
17169 goto WRITELAZYROW;
17170 case 'l':
17171 SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
17172 break;
17173 case 'B':
17174 case 'r':
17175 SCIPmessageFPrintInfo(messagehdlr, file, " <= %.15g\n", lp->rows[i]->rhs - lp->rows[i]->constant);
17176 break;
17177 case 'e':
17178 SCIPmessageFPrintInfo(messagehdlr, file, " = %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
17179 break;
17180 default:
17181 SCIPerrorMessage("Undefined row type!\n");
17182 fclose(file);
17183 return SCIP_ERROR;
17184 }
17185 }
17186 }
17187
17188 /* print variable bounds */
17189 SCIPmessageFPrintInfo(messagehdlr, file, "Bounds\n");
17190 for( i = 0; i < lp->ncols; ++i )
17191 {
17192 if( !SCIPsetIsInfinity(set,-lp->cols[i]->lb) || !SCIPsetIsInfinity(set,lp->cols[i]->ub) )
17193 {
17194 /* print lower bound as far this one is not infinity */
17195 if( !SCIPsetIsInfinity(set,-lp->cols[i]->lb) )
17196 SCIPmessageFPrintInfo(messagehdlr, file, " %.15g <=", lp->cols[i]->lb);
17197
17198 /* print variable name */
17199 if( genericnames )
17200 SCIPmessageFPrintInfo(messagehdlr, file, " x_%d ", lp->cols[i]->lppos);
17201 else
17202 SCIPmessageFPrintInfo(messagehdlr, file, " %s ", lp->cols[i]->var->name);
17203
17204 /* print upper bound as far this one is not infinity */
17205 if( !SCIPsetIsInfinity(set,lp->cols[i]->ub) )
17206 SCIPmessageFPrintInfo(messagehdlr, file, "<= %.15g", lp->cols[i]->ub);
17207 SCIPmessageFPrintInfo(messagehdlr, file, "\n");
17208 }
17209 }
17210 if( origobj && objoffset != 0.0 )
17211 SCIPmessageFPrintInfo(messagehdlr, file, " objoffset = 1\n");
17212
17213 /* print integer variables */
17214 SCIPmessageFPrintInfo(messagehdlr, file, "Generals\n");
17215 j = 0;
17216 for( i = 0; i < lp->ncols; ++i )
17217 {
17218 if( SCIPvarIsIntegral(lp->cols[i]->var) )
17219 {
17220 /* print variable name */
17221 if( genericnames )
17222 SCIPmessageFPrintInfo(messagehdlr, file, " x_%d ", lp->cols[i]->lppos);
17223 else
17224 SCIPmessageFPrintInfo(messagehdlr, file, " %s ", lp->cols[i]->var->name);
17225
17226 j++;
17227 if( j % 10 == 0 )
17228 SCIPmessageFPrintInfo(messagehdlr, file, "\n");
17229 }
17230 }
17231
17232 SCIPmessageFPrintInfo(messagehdlr, file, "\nEnd");
17233 fclose(file);
17234
17235 return SCIP_OKAY;
17236}
17237
17238/*
17239 * simple functions implemented as defines
17240 */
17241
17242/* In debug mode, the following methods are implemented as function calls to ensure
17243 * type validity.
17244 * In optimized mode, the methods are implemented as defines to improve performance.
17245 * However, we want to have them in the library anyways, so we have to undef the defines.
17246 */
17247
17248#undef SCIPcolGetObj
17249#undef SCIPcolGetLb
17250#undef SCIPcolGetUb
17251#undef SCIPcolGetBestBound
17252#undef SCIPcolGetPrimsol
17253#undef SCIPcolGetMinPrimsol
17254#undef SCIPcolGetMaxPrimsol
17255#undef SCIPcolGetBasisStatus
17256#undef SCIPcolGetVar
17257#undef SCIPcolGetIndex
17258#undef SCIPcolGetVarProbindex
17259#undef SCIPcolIsIntegral
17260#undef SCIPcolIsRemovable
17261#undef SCIPcolGetLPPos
17262#undef SCIPcolGetLPDepth
17263#undef SCIPcolIsInLP
17264#undef SCIPcolGetNNonz
17265#undef SCIPcolGetNLPNonz
17266#undef SCIPcolGetRows
17267#undef SCIPcolGetVals
17268#undef SCIPcolGetStrongbranchNode
17269#undef SCIPcolGetNStrongbranchs
17270#undef SCIPcolGetAge
17271#undef SCIPboundtypeOpposite
17272#undef SCIProwGetNNonz
17273#undef SCIProwGetNLPNonz
17274#undef SCIProwGetCols
17275#undef SCIProwGetVals
17276#undef SCIProwGetConstant
17277#undef SCIProwGetNorm
17278#undef SCIProwGetSumNorm
17279#undef SCIProwGetLhs
17280#undef SCIProwGetRhs
17281#undef SCIProwGetDualsol
17282#undef SCIProwGetDualfarkas
17283#undef SCIProwGetBasisStatus
17284#undef SCIProwGetName
17285#undef SCIProwGetIndex
17286#undef SCIProwGetAge
17287#undef SCIProwGetRank
17288#undef SCIProwIsIntegral
17289#undef SCIProwIsLocal
17290#undef SCIProwIsModifiable
17291#undef SCIProwIsRemovable
17292#undef SCIProwGetOrigintype
17293#undef SCIProwGetOriginCons
17294#undef SCIProwGetOriginConshdlr
17295#undef SCIProwGetOriginSepa
17296#undef SCIProwIsInGlobalCutpool
17297#undef SCIProwGetLPPos
17298#undef SCIProwGetLPDepth
17299#undef SCIProwIsInLP
17300#undef SCIProwGetActiveLPCount
17301#undef SCIProwGetNLPsAfterCreation
17302#undef SCIProwChgRank
17303#undef SCIProwGetRowExact
17304#undef SCIPlpGetCols
17305#undef SCIPlpGetNCols
17306#undef SCIPlpGetRows
17307#undef SCIPlpGetNRows
17308#undef SCIPlpGetNewcols
17309#undef SCIPlpGetNNewcols
17310#undef SCIPlpGetNewrows
17311#undef SCIPlpGetNNewrows
17312#undef SCIPlpGetObjNorm
17313#undef SCIPlpGetRootObjval
17314#undef SCIPlpGetRootColumnObjval
17315#undef SCIPlpGetRootLooseObjval
17316#undef SCIPlpGetLPI
17317#undef SCIPlpSetIsRelax
17318#undef SCIPlpIsRelax
17319#undef SCIPlpIsSolved
17320#undef SCIPlpIsSolBasic
17321#undef SCIPlpDiving
17322#undef SCIPlpDivingObjChanged
17323#undef SCIPlpMarkDivingObjChanged
17324#undef SCIPlpUnmarkDivingObjChanged
17325#undef SCIPlpDivingRowsChanged
17326#undef SCIPlpIsFeasEQ
17327#undef SCIPlpIsFeasLT
17328#undef SCIPlpIsFeasLE
17329#undef SCIPlpIsFeasGT
17330#undef SCIPlpIsFeasGE
17331#undef SCIPlpIsFeasZero
17332#undef SCIPlpIsFeasPositive
17333#undef SCIPlpIsFeasNegative
17334
17335/** gets objective value of column */
17337 SCIP_COL* col /**< LP column */
17338 )
17339{
17340 assert(col != NULL);
17341
17342 return col->obj;
17343}
17344
17345/** gets lower bound of column */
17347 SCIP_COL* col /**< LP column */
17348 )
17349{
17350 assert(col != NULL);
17351
17352 return col->lb;
17353}
17354
17355/** gets upper bound of column */
17357 SCIP_COL* col /**< LP column */
17358 )
17359{
17360 assert(col != NULL);
17361
17362 return col->ub;
17363}
17364
17365/** gets best bound of column with respect to the objective function */
17367 SCIP_COL* col /**< LP column */
17368 )
17369{
17370 assert(col != NULL);
17371
17372 if( col->obj >= 0.0 )
17373 return col->lb;
17374 else
17375 return col->ub;
17376}
17377
17378/** gets the primal LP solution of a column */
17380 SCIP_COL* col /**< LP column */
17381 )
17382{
17383 assert(col != NULL);
17384
17385 if( col->lppos >= 0 )
17386 return col->primsol;
17387 else
17388 return 0.0;
17389}
17390
17391/** gets the minimal LP solution value, this column ever assumed */
17393 SCIP_COL* col /**< LP column */
17394 )
17395{
17396 assert(col != NULL);
17397
17398 return col->minprimsol;
17399}
17400
17401/** gets the maximal LP solution value, this column ever assumed */
17403 SCIP_COL* col /**< LP column */
17404 )
17405{
17406 assert(col != NULL);
17407
17408 return col->maxprimsol;
17409}
17410
17411/** gets the basis status of a column in the LP solution; only valid for LPs with status SCIP_LPSOLSTAT_OPTIMAL
17412 * and with SCIPisLPSolBasic(scip) == TRUE; returns SCIP_BASESTAT_ZERO for columns not in the current SCIP_LP
17413 */
17415 SCIP_COL* col /**< LP column */
17416 )
17417{
17418 assert(col != NULL);
17420
17421 return (SCIP_BASESTAT)col->basisstatus;
17422}
17423
17424/** gets variable this column represents */
17426 SCIP_COL* col /**< LP column */
17427 )
17428{
17429 assert(col != NULL);
17430
17431 return col->var;
17432}
17433
17434/** gets unique index of col */
17436 SCIP_COL* col /**< LP col */
17437 )
17438{
17439 assert(col != NULL);
17440
17441 return col->index;
17442}
17443
17444/** gets probindex of corresponding variable */
17446 SCIP_COL* col /**< LP col */
17447 )
17448{
17449 assert(col != NULL);
17450
17451 return col->var_probindex;
17452}
17453
17454/** returns whether the associated variable is of integral type (binary, integer, or implied integral) */
17456 SCIP_COL* col /**< LP column */
17457 )
17458{
17459 assert(col != NULL);
17460 assert(SCIPvarIsIntegral(col->var) == col->integral);
17461
17462 return col->integral;
17463}
17464
17465/** returns whether the associated variable is implied integral */
17467 SCIP_COL* col /**< LP column */
17468 )
17469{
17470 assert(col != NULL);
17472
17473 return col->impliedintegral;
17474}
17475
17476/** returns TRUE iff column is removable from the LP (due to aging or cleanup) */
17478 SCIP_COL* col /**< LP column */
17479 )
17480{
17481 assert(col != NULL);
17482
17483 return col->removable;
17484}
17485
17486/** gets position of column in current LP, or -1 if it is not in LP */
17488 SCIP_COL* col /**< LP column */
17489 )
17490{
17491 assert(col != NULL);
17492 assert((col->lppos == -1) == (col->lpdepth == -1));
17493
17494 return col->lppos;
17495}
17496
17497/** gets depth in the tree where the column entered the LP, or -1 if it is not in LP */
17499 SCIP_COL* col /**< LP column */
17500 )
17501{
17502 assert(col != NULL);
17503 assert((col->lppos == -1) == (col->lpdepth == -1));
17504
17505 return col->lpdepth;
17506}
17507
17508/** returns TRUE iff column is member of current LP */
17510 SCIP_COL* col /**< LP column */
17511 )
17512{
17513 assert(col != NULL);
17514 assert((col->lppos == -1) == (col->lpdepth == -1));
17515
17516 return (col->lppos >= 0);
17517}
17518
17519/** get number of nonzero entries in column vector */
17521 SCIP_COL* col /**< LP column */
17522 )
17523{
17524 assert(col != NULL);
17525
17526 return col->len;
17527}
17528
17529/** get number of nonzero entries in column vector, that correspond to rows currently in the SCIP_LP;
17530 *
17531 * @warning This method is only applicable on columns, that are completely linked to their rows (e.g. a column
17532 * that is in the current LP and the LP was solved, or a column that was in a solved LP and didn't change afterwards
17533 */
17535 SCIP_COL* col /**< LP column */
17536 )
17537{
17538 assert(col != NULL);
17539 assert(col->nunlinked == 0);
17540
17541 return col->nlprows;
17542}
17543
17544/** gets array with rows of nonzero entries */
17546 SCIP_COL* col /**< LP column */
17547 )
17548{
17549 assert(col != NULL);
17550
17551 return col->rows;
17552}
17553
17554/** gets array with coefficients of nonzero entries */
17556 SCIP_COL* col /**< LP column */
17557 )
17558{
17559 assert(col != NULL);
17560
17561 return col->vals;
17562}
17563
17564/** gets node number of the last node in current branch and bound run, where strong branching was used on the
17565 * given column, or -1 if strong branching was never applied to the column in current run
17566 */
17568 SCIP_COL* col /**< LP column */
17569 )
17570{
17571 assert(col != NULL);
17572
17573 return col->sbnode;
17574}
17575
17576/** gets number of times, strong branching was applied in current run on the given column */
17578 SCIP_COL* col /**< LP column */
17579 )
17580{
17581 assert(col != NULL);
17582
17583 return col->nsbcalls;
17584}
17585
17586/** gets the age of a column, i.e., the total number of successive times a column was in the LP and was 0.0 in the solution */
17588 SCIP_COL* col /**< LP column */
17589 )
17590{
17591 assert(col != NULL);
17592
17593 return col->age;
17594}
17595
17596/** gets opposite bound type of given bound type */
17598 SCIP_BOUNDTYPE boundtype /**< type of bound (lower or upper) */
17599 )
17600{
17601 assert(boundtype == SCIP_BOUNDTYPE_LOWER || boundtype == SCIP_BOUNDTYPE_UPPER);
17602
17604}
17605
17606/** get number of nonzero entries in row vector */
17608 SCIP_ROW* row /**< LP row */
17609 )
17610{
17611 assert(row != NULL);
17612
17613 return row->len;
17614}
17615
17616/** get number of nonzero entries in row vector, that correspond to columns currently in the SCIP_LP;
17617 *
17618 * @warning This method is only applicable on rows, that are completely linked to their columns (e.g. a row
17619 * that is in the current LP and the LP was solved, or a row that was in a solved LP and didn't change afterwards
17620 */
17622 SCIP_ROW* row /**< LP row */
17623 )
17624{
17625 assert(row != NULL);
17626 assert(row->nunlinked == 0);
17627
17628 return row->nlpcols;
17629}
17630
17631/** gets array with columns of nonzero entries */
17633 SCIP_ROW* row /**< LP row */
17634 )
17635{
17636 assert(row != NULL);
17637
17638 return row->cols;
17639}
17640
17641/** gets array with coefficients of nonzero entries */
17643 SCIP_ROW* row /**< LP row */
17644 )
17645{
17646 assert(row != NULL);
17647
17648 return row->vals;
17649}
17650
17651/** gets constant shift of row */
17653 SCIP_ROW* row /**< LP row */
17654 )
17655{
17656 assert(row != NULL);
17657
17658 return row->constant;
17659}
17660
17661/** gets Euclidean norm of row vector */
17663 SCIP_ROW* row /**< LP row */
17664 )
17665{
17666 assert(row != NULL);
17667
17668 checkRowSqrnorm(row);
17669
17670 return sqrt(row->sqrnorm);
17671}
17672
17673/** gets sum norm of row vector (sum of absolute values of coefficients) */
17675 SCIP_ROW* row /**< LP row */
17676 )
17677{
17678 assert(row != NULL);
17679
17680 checkRowSumnorm(row);
17681
17682 return row->sumnorm;
17683}
17684
17685/** returns the left hand side of the row */
17687 SCIP_ROW* row /**< LP row */
17688 )
17689{
17690 assert(row != NULL);
17691
17692 return row->lhs;
17693}
17694
17695/** returns the right hand side of the row */
17697 SCIP_ROW* row /**< LP row */
17698 )
17699{
17700 assert(row != NULL);
17701
17702 return row->rhs;
17703}
17704
17705/** gets the dual LP solution of a row */
17707 SCIP_ROW* row /**< LP row */
17708 )
17709{
17710 assert(row != NULL);
17711
17712 if( row->lppos >= 0 )
17713 return row->dualsol;
17714 else
17715 return 0.0;
17716}
17717
17718/** gets the dual Farkas coefficient of a row in an infeasible LP */
17720 SCIP_ROW* row /**< LP row */
17721 )
17722{
17723 assert(row != NULL);
17724
17725 if( row->lppos >= 0 )
17726 return row->dualfarkas;
17727 else
17728 return 0.0;
17729}
17730
17731/** gets the basis status of a row in the LP solution; only valid for LPs with status SCIP_LPSOLSTAT_OPTIMAL
17732 * and with SCIPisLPSolBasic(scip) == TRUE; returns SCIP_BASESTAT_BASIC for rows not in the current SCIP_LP
17733 */
17735 SCIP_ROW* row /**< LP row */
17736 )
17737{
17738 assert(row != NULL);
17740
17741 return (SCIP_BASESTAT)row->basisstatus;
17742}
17743
17744/** returns the name of the row */
17745const char* SCIProwGetName(
17746 SCIP_ROW* row /**< LP row */
17747 )
17748{
17749 assert(row != NULL);
17750
17751 return row->name;
17752}
17753
17754/** gets unique index of row */
17756 SCIP_ROW* row /**< LP row */
17757 )
17758{
17759 assert(row != NULL);
17760
17761 return row->index;
17762}
17763
17764/** gets age of row */
17766 SCIP_ROW* row /**< LP row */
17767 )
17768{
17769 assert(row != NULL);
17770
17771 return row->age;
17772}
17773
17774/** gets rank of row */
17776 SCIP_ROW* row /**< LP row */
17777 )
17778{
17779 assert(row != NULL);
17780
17781 return row->rank;
17782}
17783
17784/** returns TRUE if the activity of the row (without the row's constant) is integral for an optimal solution */
17786 SCIP_ROW* row /**< LP row */
17787 )
17788{
17789 assert(row != NULL);
17790
17791 return row->integral;
17792}
17793
17794/** returns TRUE iff row is only valid locally */
17796 SCIP_ROW* row /**< LP row */
17797 )
17798{
17799 assert(row != NULL);
17800
17801 return row->local;
17802}
17803
17804/** returns TRUE iff row is modifiable during node processing (subject to column generation) */
17806 SCIP_ROW* row /**< LP row */
17807 )
17808{
17809 assert(row != NULL);
17810
17811 return row->modifiable;
17812}
17813
17814/** returns TRUE iff row is removable from the LP (due to aging or cleanup) */
17816 SCIP_ROW* row /**< LP row */
17817 )
17818{
17819 assert(row != NULL);
17820
17821 return row->removable;
17822}
17823
17824/** returns type of origin that created the row */
17826 SCIP_ROW* row /**< LP row */
17827 )
17828{
17829 assert( row != NULL );
17830
17831 return (SCIP_ROWORIGINTYPE) row->origintype;
17832}
17833
17834/** returns origin constraint that created the row (NULL if not available) */
17836 SCIP_ROW* row /**< LP row */
17837 )
17838{
17839 assert( row != NULL );
17840
17842 {
17843 assert( row->origin != NULL );
17844 return (SCIP_CONS*) row->origin;
17845 }
17846 return NULL;
17847}
17848
17849/** returns origin constraint handler that created the row (NULL if not available) */
17851 SCIP_ROW* row /**< LP row */
17852 )
17853{
17854 assert( row != NULL );
17855
17857 {
17858 assert( row->origin != NULL );
17859 return (SCIP_CONSHDLR*) row->origin;
17860 }
17862 {
17863 assert(row->origin != NULL);
17864 return SCIPconsGetHdlr((SCIP_CONS*)row->origin);
17865 }
17866 return NULL;
17867}
17868
17869/** returns origin separator that created the row (NULL if not available) */
17871 SCIP_ROW* row /**< LP row */
17872 )
17873{
17874 assert( row != NULL );
17875
17877 {
17878 assert( row->origin != NULL );
17879 return (SCIP_SEPA*) row->origin;
17880 }
17881 return NULL;
17882}
17883
17884/** returns TRUE iff row is member of the global cut pool */
17886 SCIP_ROW* row /**< LP row */
17887 )
17888{
17889 assert(row != NULL);
17890
17891 return row->inglobalcutpool;
17892}
17893
17894/** gets position of row in current LP, or -1 if it is not in LP */
17896 SCIP_ROW* row /**< LP row */
17897 )
17898{
17899 assert(row != NULL);
17900 assert((row->lppos == -1) == (row->lpdepth == -1));
17901
17902 return row->lppos;
17903}
17904
17905/** gets depth in the tree where the row entered the LP, or -1 if it is not in LP */
17907 SCIP_ROW* row /**< LP row */
17908 )
17909{
17910 assert(row != NULL);
17911 assert((row->lppos == -1) == (row->lpdepth == -1));
17912
17913 return row->lpdepth;
17914}
17915
17916/** returns TRUE iff row is member of current LP */
17918 SCIP_ROW* row /**< LP row */
17919 )
17920{
17921 assert(row != NULL);
17922 assert((row->lppos == -1) == (row->lpdepth == -1));
17923
17924 return (row->lppos >= 0);
17925}
17926
17927/** changes the rank of LP row */
17929 SCIP_ROW* row, /**< LP row */
17930 int rank /**< new value for rank */
17931 )
17932{
17933 assert(row != NULL);
17934
17935 row->rank = rank;
17936}
17937
17938/** returns the number of times that this row has been sharp in an optimal LP solution */
17940 SCIP_ROW* row /**< row */
17941 )
17942{
17943 assert(row != NULL);
17944
17945 return row->activeinlpcounter;
17946}
17947
17948/** returns the number of LPs since this row has been created */
17950 SCIP_ROW* row /**< row */
17951 )
17952{
17953 assert(row != NULL);
17954
17955 return row->nlpsaftercreation;
17956}
17957
17958/** returns exact row corresponding to fprow, if it exists. Otherwise returns NULL */
17960 SCIP_ROW* row /**< SCIP row */
17961 )
17962{
17963 assert(row != NULL);
17964
17965 return row->rowexact;
17966}
17967
17968/** gets array with columns of the LP */
17970 SCIP_LP* lp /**< current LP data */
17971 )
17972{
17973 assert(lp != NULL);
17974
17975 return lp->cols;
17976}
17977
17978/** gets current number of columns in LP */
17980 SCIP_LP* lp /**< current LP data */
17981 )
17982{
17983 assert(lp != NULL);
17984
17985 return lp->ncols;
17986}
17987
17988/** gets current number of unfixed columns in LP */
17990 SCIP_LP* lp, /**< current LP data */
17991 SCIP_Real eps /**< numerical tolerance */
17992 )
17993{
17994 SCIP_COL** lpcols;
17995 int nlpcols;
17996 int nunfixedcols;
17997 int c;
17998
17999 assert(lp != NULL);
18000 assert(eps > 0.0);
18001
18002 lpcols = lp->cols;
18003 nlpcols = lp->ncols;
18004
18005 nunfixedcols = 0;
18006 for( c = 0; c < nlpcols; ++c )
18007 {
18008 if( lpcols[c]->ub - lpcols[c]->lb > eps )
18009 ++nunfixedcols;
18010 }
18011
18012 return nunfixedcols;
18013}
18014
18015/** gets array with rows of the LP */
18017 SCIP_LP* lp /**< current LP data */
18018 )
18019{
18020 assert(lp != NULL);
18021
18022 return lp->rows;
18023}
18024
18025/** gets current number of rows in LP */
18027 SCIP_LP* lp /**< current LP data */
18028 )
18029{
18030 assert(lp != NULL);
18031
18032 return lp->nrows;
18033}
18034
18035/** gets array with newly added columns after the last mark */
18037 SCIP_LP* lp /**< current LP data */
18038 )
18039{
18040 assert(lp != NULL);
18041 assert(0 <= lp->firstnewcol && lp->firstnewcol <= lp->ncols);
18042
18043 return &(lp->cols[lp->firstnewcol]);
18044}
18045
18046/** gets number of newly added columns after the last mark */
18048 SCIP_LP* lp /**< current LP data */
18049 )
18050{
18051 assert(lp != NULL);
18052 assert(0 <= lp->firstnewcol && lp->firstnewcol <= lp->ncols);
18053
18054 return lp->ncols - lp->firstnewcol;
18055}
18056
18057/** gets array with newly added rows after the last mark */
18059 SCIP_LP* lp /**< current LP data */
18060 )
18061{
18062 assert(lp != NULL);
18063 assert(0 <= lp->firstnewrow && lp->firstnewrow <= lp->nrows);
18064
18065 return &(lp->rows[lp->firstnewrow]);
18066}
18067
18068/** gets number of newly added rows after the last mark */
18070 SCIP_LP* lp /**< current LP data */
18071 )
18072{
18073 assert(lp != NULL);
18074 assert(0 <= lp->firstnewrow && lp->firstnewrow <= lp->nrows);
18075
18076 return lp->nrows - lp->firstnewrow;
18077}
18078
18079/** recalculates Euclidean norm of objective function vector of column variables if it have gotten unreliable during calculation */
18081 SCIP_SET* set, /**< global SCIP settings */
18082 SCIP_LP* lp /**< LP data */
18083 )
18084{
18085 if( lp->objsqrnormunreliable )
18086 {
18087 SCIP_COL** cols;
18088 int c;
18089
18090 cols = lp->cols;
18091 assert(cols != NULL || lp->ncols == 0);
18092
18093 lp->objsqrnorm = 0.0;
18094
18095 for( c = lp->ncols - 1; c >= 0; --c )
18096 {
18097 lp->objsqrnorm += SQR(cols[c]->unchangedobj); /*lint !e613*/
18098 }
18099 assert(SCIPsetIsGE(set, lp->objsqrnorm, 0.0));
18100
18101 /* due to numerical troubles it still can appear that lp->objsqrnorm is a little bit smaller than 0 */
18102 lp->objsqrnorm = MAX(lp->objsqrnorm, 0.0);
18103
18105 }
18106 return;
18107}
18108
18109/** gets Euclidean norm of objective function vector of column variables, only use this method if
18110 * lp->objsqrnormunreliable == FALSE, so probably you have to call SCIPlpRecalculateObjSqrNorm before */
18112 SCIP_LP* lp /**< LP data */
18113 )
18114{
18115 assert(lp != NULL);
18117 assert(lp->objsqrnorm >= 0.0);
18118
18119 return sqrt(lp->objsqrnorm);
18120}
18121
18122/** sets whether the root lp is a relaxation of the problem and its optimal objective value is a global lower bound */
18124 SCIP_LP* lp, /**< LP data */
18125 SCIP_Bool isrelax /**< is the root lp a relaxation of the problem? */
18126 )
18127{
18128 assert(lp != NULL);
18129
18130 lp->rootlpisrelax = isrelax;
18131}
18132
18133/** returns whether the root lp is a relaxation of the problem and its optimal objective value is a global lower bound */
18135 SCIP_LP* lp /**< LP data */
18136 )
18137{
18138 assert(lp != NULL);
18139
18140 return lp->rootlpisrelax;
18141}
18142
18143/** gets the objective value of the root node LP; returns SCIP_INVALID if the root node LP was not (yet) solved */
18145 SCIP_LP* lp /**< LP data */
18146 )
18147{
18148 assert(lp != NULL);
18149
18150 return MIN(lp->rootlpobjval + lp->rootlooseobjval, SCIP_INVALID);
18151}
18152
18153/** gets part of the objective value of the root node LP that results from COLUMN variables only;
18154 * returns SCIP_INVALID if the root node LP was not (yet) solved
18155 */
18157 SCIP_LP* lp /**< LP data */
18158 )
18159{
18160 assert(lp != NULL);
18161
18162 return lp->rootlpobjval;
18163}
18164
18165/** gets part of the objective value of the root node LP that results from LOOSE variables only;
18166 * returns SCIP_INVALID if the root node LP was not (yet) solved
18167 */
18169 SCIP_LP* lp /**< LP data */
18170 )
18171{
18172 assert(lp != NULL);
18173
18174 return lp->rootlooseobjval;
18175}
18176
18177/** gets the LP solver interface */
18179 SCIP_LP* lp /**< current LP data */
18180 )
18181{
18182 assert(lp != NULL);
18183
18184 return lp->lpi;
18185}
18186
18187/** sets whether the current LP is a relaxation of the current problem and its optimal objective value is a local lower bound */
18189 SCIP_LP* lp, /**< LP data */
18190 SCIP_Bool relax /**< is the current lp a relaxation? */
18191 )
18192{
18193 assert(lp != NULL);
18194
18195 lp->isrelax = relax;
18196}
18197
18198/** returns whether the current LP is a relaxation of the problem for which it has been solved and its
18199 * solution value a valid local lower bound?
18200 */
18202 SCIP_LP* lp /**< LP data */
18203 )
18204{
18205 assert(lp != NULL);
18206
18207 return lp->isrelax;
18208}
18209
18210/** returns whether the current LP is flushed and solved */
18212 SCIP_LP* lp /**< current LP data */
18213 )
18214{
18215 assert(lp != NULL);
18216
18217 return lp->flushed && lp->solved;
18218}
18219
18220/** return whether the current LP solution passed the primal feasibility check */
18222 SCIP_LP* lp /**< current LP data */
18223 )
18224{
18225 assert(lp != NULL);
18226
18227 return (lp->primalchecked && lp->primalfeasible);
18228}
18229
18230/** return whether the current LP solution passed the dual feasibility check */
18232 SCIP_LP* lp /**< current LP data */
18233 )
18234{
18235 assert(lp != NULL);
18236
18237 return (lp->dualchecked && lp->dualfeasible);
18238}
18239
18240/** returns whether the current LP solution is a basic solution */
18242 SCIP_LP* lp /**< current LP data */
18243 )
18244{
18245 assert(lp != NULL);
18246
18247 return lp->solisbasic;
18248}
18249
18250/** returns whether the LP is in diving mode */
18252 SCIP_LP* lp /**< current LP data */
18253 )
18254{
18255 assert(lp != NULL);
18256
18257 return lp->diving;
18258}
18259
18260/** returns whether the LP is in diving mode and the objective value of at least one column was changed */
18262 SCIP_LP* lp /**< current LP data */
18263 )
18264{
18265 assert(lp != NULL);
18266
18267 return lp->divingobjchg;
18268}
18269
18270/** marks the diving LP to have a changed objective function */
18272 SCIP_LP* lp /**< current LP data */
18273 )
18274{
18275 assert(lp != NULL);
18276 assert(lp->diving || lp->probing);
18277
18278 lp->divingobjchg = TRUE;
18279}
18280
18281/** marks the diving LP to not have a changed objective function anymore */
18283 SCIP_LP* lp /**< current LP data */
18284 )
18285{
18286 assert(lp != NULL);
18287 assert(lp->diving || lp->probing);
18288
18289 lp->divingobjchg = FALSE;
18290}
18291
18292/* returns TRUE if at least one left/right hand side of an LP row was changed during diving mode */
18294 SCIP_LP* lp /**< current LP data */
18295 )
18296{
18297 assert(lp != NULL);
18298 assert(lp->diving || lp->ndivechgsides == 0);
18299
18300 return (lp->ndivechgsides > 0);
18301}
18302
18303/** compute relative interior point with auxiliary lpi, see SCIPlpComputeRelIntPoint() */
18304static
18306 SCIP_LPI* lpi, /**< auxiliary LP interface */
18307 SCIP_SET* set, /**< global SCIP settings */
18308 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
18309 SCIP_LP* lp, /**< LP data */
18310 SCIP_PROB* prob, /**< problem data */
18311 SCIP_Bool relaxrows, /**< should the rows be relaxed */
18312 SCIP_Bool inclobjcutoff, /**< should a row for the objective cutoff be included */
18313 SCIP_Real timelimit, /**< time limit for LP solver */
18314 int iterlimit, /**< iteration limit for LP solver */
18315 SCIP_Real* point, /**< array to store relative interior point on exit */
18316 SCIP_Bool* success /**< buffer to indicate whether interior point was successfully computed */
18317 )
18318{
18319 SCIP_RETCODE retcode;
18320 SCIP_Real* primal;
18321 SCIP_Real* obj;
18322 SCIP_Real* lb;
18323 SCIP_Real* ub;
18324 SCIP_Real* matvals;
18325 SCIP_Real* matlhs;
18326 SCIP_Real* matrhs;
18329 int* matinds;
18330 int* matbeg;
18331#ifndef NDEBUG
18332 int nslacks;
18333#endif
18334 int nnewcols;
18335 int ntotnonz = 0;
18336 int ntotrows = 0;
18337 int matrowidx;
18338 int matidx;
18339 int cnt;
18340 int j;
18341 int i;
18342
18343 assert(lpi != NULL);
18344
18345 retcode = SCIPlpiSetRealpar(lpi, SCIP_LPPAR_FEASTOL, lp->feastol);
18346 if( retcode != SCIP_OKAY )
18347 {
18348 /* stop execution on error, since result is likely to be unsuable */
18349 SCIPmessagePrintWarning(messagehdlr, "Could not set feasibility tolerance of LP solver for relative interior point computation.\n");
18350 return SCIP_LPERROR;
18351 }
18352
18354 if( retcode != SCIP_OKAY )
18355 {
18356 /* stop execution on error, since result is likely to be unsuable */
18357 SCIPmessagePrintWarning(messagehdlr, "Could not set dual feasibility tolerance of LP solver for relative interior point computation.\n");
18358 return SCIP_LPERROR;
18359 }
18360
18361 /* get storage */
18362 nnewcols = 3*lp->ncols + 2*lp->nrows + (inclobjcutoff ? 1 : 0) + 1;
18363 SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, nnewcols) );
18364 SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, nnewcols) );
18365 SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, nnewcols) );
18366
18367 /* create original columns (bounds are relaxed below, unless the variable is fixed) */
18368 for( j = 0; j < lp->ncols; ++j )
18369 {
18370 /* note: if the variable is fixed we cannot simply fix the variables (because alpha scales the problem) */
18371 obj[j] = 0.0;
18372 lb[j] = -SCIPlpiInfinity(lpi);
18373 ub[j] = SCIPlpiInfinity(lpi);
18374 /* note: we could also use the original bounds - free variables seem to be faster. */
18375 }
18376
18377 /* add artificial alpha variable */
18378 nnewcols = lp->ncols;
18379 obj[nnewcols] = 0.0;
18380 lb[nnewcols] = 1.0;
18381 ub[nnewcols] = SCIPlpiInfinity(lpi);
18382 ++nnewcols;
18383
18384 /* create slacks for rows */
18385 for( i = 0; i < lp->nrows; ++i )
18386 {
18387 SCIP_ROW* row;
18388
18389 row = lp->rows[i];
18390 assert( row != NULL );
18391
18392 if( SCIProwIsModifiable(row) )
18393 continue;
18394
18395 /* make sure row is sorted */
18396 rowSortLP(row);
18397 assert( row->lpcolssorted );
18398
18399 /* check whether we have an equation */
18400 if( SCIPsetIsEQ(set, row->lhs, row->rhs) )
18401 {
18404 ntotnonz += row->nlpcols + 1;
18405 ++ntotrows;
18406 }
18407 else
18408 {
18409 /* otherwise add slacks for each side if necessary */
18410 if ( ! SCIPsetIsInfinity(set, REALABS(row->lhs)) )
18411 {
18412 if ( relaxrows )
18413 {
18414 lb[nnewcols] = 0.0;
18415 ub[nnewcols] = 1.0;
18416 obj[nnewcols++] = 1.0;
18417 ntotnonz += row->nlpcols + 2;
18418 }
18419 else
18420 ntotnonz += row->nlpcols + 1;
18421 ++ntotrows;
18422 }
18423 if ( ! SCIPsetIsInfinity(set, REALABS(row->rhs)) )
18424 {
18425 if ( relaxrows )
18426 {
18427 lb[nnewcols] = 0.0;
18428 ub[nnewcols] = 1.0;
18429 obj[nnewcols++] = 1.0;
18430 ntotnonz += row->nlpcols + 2;
18431 }
18432 else
18433 ntotnonz += row->nlpcols + 1;
18434 ++ntotrows;
18435 }
18436 }
18437 }
18438
18439 /* create slacks for objective cutoff row */
18440 if( inclobjcutoff && relaxrows )
18441 {
18442 /* add slacks for right hand side */
18443 lb[nnewcols] = 0.0;
18444 ub[nnewcols] = 1.0;
18445 obj[nnewcols++] = 1.0;
18446 ntotnonz += lp->ncols + 2;
18447 ++ntotrows;
18448 }
18449
18450 /* create slacks for bounds */
18451 for( j = 0; j < lp->ncols; ++j )
18452 {
18453 SCIP_COL* col;
18454
18455 col = lp->cols[j];
18456 assert( col != NULL );
18457
18458 /* no slacks for fixed variables */
18459 if( SCIPsetIsEQ(set, col->lb, col->ub) )
18460 {
18461 ++ntotrows;
18462 ntotnonz += 2;
18463 }
18464 else
18465 {
18466 /* add slacks for each bound if necessary */
18467 if ( ! SCIPsetIsInfinity(set, REALABS(col->lb)) )
18468 {
18469 lb[nnewcols] = 0.0;
18470 ub[nnewcols] = 1.0;
18471 obj[nnewcols++] = 1.0;
18472 ntotnonz += 3;
18473 ++ntotrows;
18474 }
18475 if( ! SCIPsetIsInfinity(set, REALABS(col->ub)) )
18476 {
18477 lb[nnewcols] = 0.0;
18478 ub[nnewcols] = 1.0;
18479 obj[nnewcols++] = 1.0;
18480 ntotnonz += 3;
18481 ++ntotrows;
18482 }
18483 }
18484 }
18485#ifndef NDEBUG
18486 nslacks = nnewcols - lp->ncols - 1;
18487 assert( nslacks >= 0 );
18488 assert( nnewcols <= 3*lp->ncols + 2*lp->nrows + (inclobjcutoff ? 1 : 0) + 1 );
18489#endif
18490
18491 /* add columns */
18492 SCIP_CALL( SCIPlpiAddCols(lpi, nnewcols, obj, lb, ub, NULL, 0, NULL, NULL, NULL) );
18493
18494 /* free storage */
18498
18499 /* prepare storage for rows */
18500 SCIP_CALL( SCIPsetAllocBufferArray(set, &matinds, ntotnonz) );
18501 SCIP_CALL( SCIPsetAllocBufferArray(set, &matvals, ntotnonz) );
18502 SCIP_CALL( SCIPsetAllocBufferArray(set, &matbeg, ntotrows) );
18503 SCIP_CALL( SCIPsetAllocBufferArray(set, &matlhs, ntotrows) );
18504 SCIP_CALL( SCIPsetAllocBufferArray(set, &matrhs, ntotrows) );
18505
18506 /* create rows arising from original rows */
18507 cnt = 0;
18508 matrowidx = 0;
18509 matidx = 0;
18510 for( i = 0; i < lp->nrows; ++i )
18511 {
18512 SCIP_ROW* row;
18513 SCIP_COL** rowcols;
18514 SCIP_Real* rowvals;
18515 SCIP_Real lhs;
18516 SCIP_Real rhs;
18517 int nnonz;
18518
18519 row = lp->rows[i];
18520 assert( row != NULL );
18521
18522 if( SCIProwIsModifiable(row) )
18523 continue;
18524 assert( row->lpcolssorted );
18525
18526 /* get row data */
18527 lhs = row->lhs - (SCIPsetIsInfinity(set, -row->lhs) ? 0.0 : row->constant);
18528 rhs = row->rhs - (SCIPsetIsInfinity(set, row->rhs) ? 0.0 : row->constant);
18529 nnonz = row->nlpcols;
18530 assert( nnonz <= lp->ncols );
18531 rowcols = row->cols;
18532 rowvals = row->vals;
18533
18534 /* if we have an equation */
18535 if( SCIPsetIsEQ(set, lhs, rhs) )
18536 {
18537 /* set up indices */
18538 matbeg[matrowidx] = matidx;
18539 for( j = 0; j < nnonz; ++j )
18540 {
18541 assert( rowcols[j] != NULL );
18542 assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
18543 assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
18544 assert( ! SCIPsetIsZero(set, rowvals[j]) );
18545 matinds[matidx] = rowcols[j]->lppos;
18546 matvals[matidx++] = rowvals[j];
18547 assert( matidx <= ntotnonz );
18548 }
18549
18550 /* add artificial variable */
18551 if ( ! SCIPsetIsZero(set, rhs) )
18552 {
18553 matinds[matidx] = lp->ncols;
18554 matvals[matidx++] = -rhs;
18555 assert( matidx <= ntotnonz );
18556 }
18557
18558 matlhs[matrowidx] = 0.0;
18559 matrhs[matrowidx++] = 0.0;
18560 assert( matrowidx <= ntotrows );
18561 }
18562 else
18563 {
18564 SCIP_Real abslhs = REALABS(lhs);
18565 SCIP_Real absrhs = REALABS(rhs);
18566
18567 assert(!SCIPsetIsEQ(set, lhs, rhs));
18568
18569 /* treat lhs */
18570 if( !SCIPsetIsInfinity(set, abslhs) )
18571 {
18572 /* set up indices */
18573 matbeg[matrowidx] = matidx;
18574 for( j = 0; j < nnonz; ++j )
18575 {
18576 assert( rowcols[j] != NULL );
18577 assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
18578 assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
18579 assert( ! SCIPsetIsZero(set, rowvals[j]) );
18580 matinds[matidx] = rowcols[j]->lppos;
18581 matvals[matidx++] = rowvals[j];
18582 assert( matidx <= ntotnonz );
18583 }
18584
18585 /* add artificial variable */
18586 if ( ! SCIPsetIsZero(set, lhs) )
18587 {
18588 matinds[matidx] = lp->ncols;
18589 matvals[matidx++] = -lhs;
18590 assert( matidx <= ntotnonz );
18591 }
18592
18593 if( relaxrows )
18594 {
18595 /* add slack variable */
18596 matvals[matidx] = -MAX(1.0, lhs); /*lint !e679*/
18597 matinds[matidx++] = lp->ncols + 1 + cnt; /*lint !e679*/
18598 assert( matidx <= ntotnonz );
18599 ++cnt;
18600 }
18601
18602 matlhs[matrowidx] = 0.0;
18603 matrhs[matrowidx++] = SCIPlpiInfinity(lpi);
18604 assert( matrowidx <= ntotrows );
18605 }
18606
18607 /* treat rhs */
18608 if( !SCIPsetIsInfinity(set, absrhs) )
18609 {
18610 /* set up indices */
18611 matbeg[matrowidx] = matidx;
18612 for( j = 0; j < nnonz; ++j )
18613 {
18614 assert( rowcols[j] != NULL );
18615 assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
18616 assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
18617 assert( ! SCIPsetIsZero(set, rowvals[j]) );
18618 matinds[matidx] = rowcols[j]->lppos;
18619 matvals[matidx++] = rowvals[j];
18620 assert( matidx <= ntotnonz );
18621 }
18622
18623 /* add artificial variable */
18624 if ( ! SCIPsetIsZero(set, rhs) )
18625 {
18626 matinds[matidx] = lp->ncols;
18627 matvals[matidx++] = -rhs;
18628 assert( matidx <= ntotnonz );
18629 }
18630
18631 if( relaxrows )
18632 {
18633 /* add slack variable */
18634 matvals[matidx] = MAX(1.0, absrhs); /*lint !e679*/
18635 matinds[matidx++] = lp->ncols + 1 + cnt; /*lint !e679*/
18636 ++cnt;
18637 }
18638
18639 matlhs[matrowidx] = -SCIPlpiInfinity(lpi);
18640 matrhs[matrowidx++] = 0.0;
18641 assert( matrowidx <= ntotrows );
18642 }
18643 }
18644 }
18645
18646 /* create row arising from objective cutoff */
18647 if( inclobjcutoff )
18648 {
18649 SCIP_Real rhs;
18650
18651 /* get row data */
18652 assert(lp->looseobjvalinf == 0);
18653 rhs = lp->cutoffbound - getFiniteLooseObjval(lp, set, prob);
18654
18655 /* set up indices and coefficients */
18656 matbeg[matrowidx] = matidx;
18657 for( j = 0; j < lp->ncols; ++j )
18658 {
18659 assert( lp->cols[j] != NULL );
18660 assert( 0 <= lp->cols[j]->lppos && lp->cols[j]->lppos < lp->ncols );
18661 assert( lp->cols[lp->cols[j]->lppos] == lp->cols[j] );
18662
18663 if( ! SCIPsetIsZero(set, lp->cols[j]->obj) )
18664 {
18665 matinds[matidx] = lp->cols[j]->lppos;
18666 matvals[matidx++] = lp->cols[j]->obj;
18667 assert( matidx <= ntotnonz );
18668 }
18669 }
18670
18671 /* treat rhs */
18672
18673 /* add artificial variable */
18674 if ( ! SCIPsetIsZero(set, rhs) )
18675 {
18676 matinds[matidx] = lp->ncols;
18677 matvals[matidx++] = -rhs;
18678 assert( matidx <= ntotnonz );
18679 }
18680
18681 if( relaxrows )
18682 {
18683 SCIP_Real absrhs = REALABS(rhs);
18684
18685 /* add slack variable */
18686 matvals[matidx] = MAX(1.0, absrhs);
18687 matinds[matidx++] = lp->ncols + 1 + cnt;
18688 assert( matidx <= ntotnonz );
18689 ++cnt;
18690 }
18691 matlhs[matrowidx] = -SCIPsetInfinity(set);
18692 matrhs[matrowidx++] = 0.0;
18693 assert( matrowidx <= ntotrows );
18694 }
18695
18696 /* create rows arising from bounds */
18697 for( j = 0; j < lp->ncols; ++j )
18698 {
18699 SCIP_COL* col;
18700 SCIP_Real abscollb;
18701 SCIP_Real abscolub;
18702
18703 col = lp->cols[j];
18704 assert( col != NULL );
18705 assert( col->lppos == j );
18706
18707 /* fixed variable */
18708 if( SCIPsetIsEQ(set, col->lb, col->ub) )
18709 {
18710 /* set up index of column */
18711 matbeg[matrowidx] = matidx;
18712
18713 matinds[matidx] = j;
18714 matvals[matidx++] = 1.0;
18715 assert( matidx <= ntotnonz );
18716
18717 /* add artificial variable */
18718 if ( ! SCIPsetIsZero(set, col->ub) )
18719 {
18720 matinds[matidx] = lp->ncols;
18721 matvals[matidx++] = -col->ub;
18722 assert( matidx <= ntotnonz );
18723 }
18724
18725 matlhs[matrowidx] = 0.0;
18726 matrhs[matrowidx++] = 0.0;
18727 assert( matrowidx <= ntotrows );
18728
18729 continue;
18730 }
18731
18732 abscollb = REALABS(col->lb);
18733 abscolub = REALABS(col->ub);
18734
18735 /* lower bound */
18736 if ( ! SCIPsetIsInfinity(set, abscollb) )
18737 {
18738 /* set up index of column */
18739 matbeg[matrowidx] = matidx;
18740
18741 matinds[matidx] = j;
18742 matvals[matidx++] = 1.0;
18743 assert( matidx <= ntotnonz );
18744
18745 /* add artificial variable */
18746 if ( ! SCIPsetIsZero(set, col->lb) )
18747 {
18748 matinds[matidx] = lp->ncols;
18749 matvals[matidx++] = -col->lb;
18750 assert( matidx <= ntotnonz );
18751 }
18752
18753 /* add slack variable */
18754 matvals[matidx] = -MAX(1.0, abscollb);
18755 matinds[matidx++] = lp->ncols + 1 + cnt;
18756 assert( matidx <= ntotnonz );
18757 ++cnt;
18758
18759 matlhs[matrowidx] = 0.0;
18760 matrhs[matrowidx++] = SCIPsetInfinity(set);
18761 assert( matrowidx <= ntotrows );
18762 }
18763
18764 /* upper bound */
18765 if ( ! SCIPsetIsInfinity(set, abscolub) )
18766 {
18767 /* set up index of column */
18768 matbeg[matrowidx] = matidx;
18769
18770 matinds[matidx] = j;
18771 matvals[matidx++] = 1.0;
18772 assert( matidx <= ntotnonz );
18773
18774 /* add artificial variable */
18775 if ( ! SCIPsetIsZero(set, col->ub) )
18776 {
18777 matinds[matidx] = lp->ncols;
18778 matvals[matidx++] = -col->ub;
18779 assert( matidx <= ntotnonz );
18780 }
18781
18782 /* add slack variable */
18783 matvals[matidx] = MAX(1.0, abscolub);
18784 matinds[matidx++] = lp->ncols + 1 + cnt;
18785 assert( matidx <= ntotnonz );
18786 ++cnt;
18787
18788 matlhs[matrowidx] = -SCIPsetInfinity(set);
18789 matrhs[matrowidx++] = 0.0;
18790 assert( matrowidx <= ntotrows );
18791 }
18792 }
18793 assert( cnt == nslacks );
18794 assert( matrowidx == ntotrows );
18795
18796 /* add rows */
18797 SCIP_CALL( SCIPlpiAddRows(lpi, ntotrows, matlhs, matrhs, NULL, matidx, matbeg, matinds, matvals) );
18798
18799 SCIPsetFreeBufferArray(set, &matrhs);
18800 SCIPsetFreeBufferArray(set, &matlhs);
18801 SCIPsetFreeBufferArray(set, &matbeg);
18802 SCIPsetFreeBufferArray(set, &matvals);
18803 SCIPsetFreeBufferArray(set, &matinds);
18804
18805#ifdef SCIP_OUTPUT
18806 SCIP_CALL( SCIPlpiWriteLP(lpi, "relativeInterior.lp") );
18807#endif
18808
18809#ifndef NDEBUG
18810 {
18811 int ncols;
18812 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
18813 assert( ncols == nnewcols );
18814 }
18815#endif
18816
18817 /* set time limit */
18818 if( SCIPsetIsInfinity(set, timelimit) )
18819 timelimit = SCIPlpiInfinity(lpi);
18820 retcode = SCIPlpiSetRealpar(lpi, SCIP_LPPAR_LPTILIM, timelimit);
18821
18822 /* check, if parameter is unknown */
18823 if( retcode == SCIP_PARAMETERUNKNOWN )
18824 SCIPmessagePrintWarning(messagehdlr, "Could not set time limit of LP solver for relative interior point computation.\n");
18825 else if ( retcode != SCIP_OKAY )
18826 return retcode;
18827
18828 /* set iteration limit */
18829 retcode = SCIPlpiSetIntpar(lpi, SCIP_LPPAR_LPITLIM, iterlimit);
18830
18831 /* check, if parameter is unknown */
18832 if( retcode == SCIP_PARAMETERUNKNOWN )
18833 SCIPmessagePrintWarning(messagehdlr, "Could not set iteration limit of LP solver for relative interior point computation.\n");
18834 else if ( retcode != SCIP_OKAY )
18835 return retcode;
18836
18837 /* solve and store point */
18838 /* SCIP_CALL( SCIPlpiSolvePrimal(lpi) ); */
18839 SCIP_CALL( SCIPlpiSolveDual(lpi) ); /* dual is usually faster */
18840
18841#ifndef NDEBUG
18842 if ( SCIPlpiIsIterlimExc(lpi) )
18843 SCIPmessagePrintWarning(messagehdlr, "Iteration limit exceeded in relative interior point computation.\n");
18844 if ( SCIPlpiIsTimelimExc(lpi) )
18845 SCIPmessagePrintWarning(messagehdlr, "Time limit exceeded in relative interior point computation.\n");
18846#endif
18847
18848 if( SCIPlpiIsOptimal(lpi) )
18849 {
18850 /* get primal solution */
18851 SCIP_CALL( SCIPsetAllocBufferArray(set, &primal, nnewcols) );
18852 SCIP_CALL( SCIPlpiGetSol(lpi, &objval, primal, NULL, NULL, NULL) );
18853 alpha = primal[lp->ncols];
18854 assert( SCIPsetIsFeasGE(set, alpha, 1.0) );
18855
18856 SCIPsetDebugMsg(set, "Solved relative interior lp with objective %g.\n", objval);
18857
18858 /* construct relative interior point */
18859 for( j = 0; j < lp->ncols; ++j )
18860 point[j] = primal[j]/alpha;
18861
18862#ifdef SCIP_DEBUG
18863 /* check whether the point is a relative interior point */
18864 cnt = 0;
18865 if( relaxrows )
18866 {
18867 for( i = 0; i < lp->nrows; ++i )
18868 {
18869 SCIP_ROW* row;
18870 SCIP_COL** rowcols;
18871 SCIP_Real* rowvals;
18872 SCIP_Real lhs;
18873 SCIP_Real rhs;
18874 SCIP_Real sum;
18875 int nnonz;
18876
18877 row = lp->rows[i];
18878 assert( row != NULL );
18879
18880 /* get row data */
18881 lhs = row->lhs - (SCIPsetIsInfinity(set, -row->lhs) ? 0.0 : row->constant);
18882 rhs = row->rhs - (SCIPsetIsInfinity(set, row->rhs) ? 0.0 : row->constant);
18883 nnonz = row->nlpcols;
18884 assert( nnonz <= lp->ncols );
18885 rowcols = row->cols;
18886 rowvals = row->vals;
18887
18888 sum = 0.0;
18889 for( j = 0; j < nnonz; ++j )
18890 sum += rowvals[j] * primal[rowcols[j]->lppos];
18891 sum /= alpha;
18892
18893 /* if we have an equation */
18894 if( SCIPsetIsEQ(set, lhs, rhs) )
18895 {
18896 assert( SCIPsetIsFeasEQ(set, sum, lhs) );
18897 }
18898 else
18899 {
18900 /* treat lhs */
18901 if( !SCIPsetIsInfinity(set, REALABS(lhs)) )
18902 {
18903 assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasGT(set, sum, lhs) );
18904 ++cnt;
18905 }
18906 /* treat rhs */
18907 if( !SCIPsetIsInfinity(set, REALABS(rhs)) )
18908 {
18909 assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, sum, rhs) );
18910 ++cnt;
18911 }
18912 }
18913 }
18914 if( inclobjcutoff )
18915 {
18916 SCIP_Real sum;
18917#ifndef NDEBUG
18918 SCIP_Real rhs;
18919
18920 rhs = lp->cutoffbound - getFiniteLooseObjval(lp, set, prob);
18921#endif
18922 sum = 0.0;
18923 for( j = 0; j < lp->ncols; ++j )
18924 sum += lp->cols[j]->obj * primal[lp->cols[j]->lppos];
18925 sum /= alpha;
18926
18927 assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, sum, rhs) );
18928 ++cnt;
18929 }
18930 }
18931 /* check bounds */
18932 for( j = 0; j < lp->ncols; ++j )
18933 {
18934 SCIP_COL* col;
18935#ifndef NDEBUG
18936 SCIP_Real val;
18937#endif
18938
18939 col = lp->cols[j];
18940 assert( col != NULL );
18941#ifndef NDEBUG
18942 val = primal[col->lppos] / alpha;
18943#endif
18944 /* if the variable is not fixed */
18945 if( !SCIPsetIsEQ(set, col->lb, col->ub) )
18946 {
18947 /* treat lb */
18948 if( !SCIPsetIsInfinity(set, REALABS(col->lb)) )
18949 {
18950 assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasGT(set, val, col->lb) );
18951 ++cnt;
18952 }
18953 /* treat rhs */
18954 if( !SCIPsetIsInfinity(set, REALABS(col->ub)) )
18955 {
18956 assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, val, col->ub) );
18957 ++cnt;
18958 }
18959 }
18960 }
18961#endif
18962
18963 /* free */
18964 SCIPsetFreeBufferArray(set, &primal);
18965
18966 *success = TRUE;
18967 }
18968
18969 return SCIP_OKAY;
18970}
18971
18972/** compute relative interior point
18973 *
18974 * We use the approach of@par
18975 * R. Freund, R. Roundy, M. J. Todd@par
18976 * "Identifying the Set of Always-Active Constraints in a System of Linear Inequalities by a Single Linear Program"@par
18977 * Tech. Rep, No. 1674-85, Sloan School, M.I.T., 1985
18978 *
18979 * to compute a relative interior point for the current LP.
18980 *
18981 * Assume the original LP looks as follows:
18982 * \f[
18983 * \begin{array}{rrl}
18984 * \min & c^T x &\\
18985 * & A x & \geq a\\
18986 * & B x & \leq b\\
18987 * & D x & = d.
18988 * \end{array}
18989 * \f]
18990 * Note that bounds should be included in the system.
18991 *
18992 * To find an interior point the following LP does the job:
18993 * \f[
18994 * \begin{array}{rrl}
18995 * \max & 1^T y &\\
18996 * & A x - y - \alpha a & \geq 0\\
18997 * & B x + y - \alpha b & \leq 0\\
18998 * & D x - \alpha d & = 0\\
18999 * & 0 \leq y & \leq 1\\
19000 * & \alpha & \geq 1.
19001 * \end{array}
19002 * \f]
19003 * If the original LP is feasible, this LP is feasible as well. Any optimal solution yields the relative interior point
19004 * \f$x^*_j/\alpha^*\f$. Note that this will just produce some relative interior point. It does not produce a
19005 * particular relative interior point, e.g., one that maximizes the distance to the boundary in some norm.
19006 */
19008 SCIP_SET* set, /**< global SCIP settings */
19009 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
19010 SCIP_LP* lp, /**< LP data */
19011 SCIP_PROB* prob, /**< problem data */
19012 SCIP_Bool relaxrows, /**< should the rows be relaxed */
19013 SCIP_Bool inclobjcutoff, /**< should a row for the objective cutoff be included */
19014 SCIP_Real timelimit, /**< time limit for LP solver */
19015 int iterlimit, /**< iteration limit for LP solver */
19016 SCIP_Real* point, /**< array to store relative interior point on exit */
19017 SCIP_Bool* success /**< buffer to indicate whether interior point was successfully computed */
19018 )
19019{
19020 SCIP_LPI* lpi;
19021 SCIP_RETCODE retcode;
19022
19023 assert(set != NULL);
19024 assert(lp != NULL);
19025 assert(point != NULL);
19026 assert(success != NULL);
19027
19028 *success = FALSE;
19029
19030 /* check time and iteration limits */
19031 if ( timelimit <= 0.0 || iterlimit <= 0 )
19032 return SCIP_OKAY;
19033
19034 /* exit if there are no columns */
19035 assert(lp->nrows >= 0);
19036 assert(lp->ncols >= 0);
19037 if( lp->ncols == 0 )
19038 return SCIP_OKAY;
19039
19040 /* disable objective cutoff if we have none */
19041 if( inclobjcutoff && (SCIPsetIsInfinity(set, lp->cutoffbound) || lp->looseobjvalinf > 0 || lp->looseobjval == SCIP_INVALID) ) /*lint !e777 */
19042 inclobjcutoff = FALSE;
19043
19044 SCIPsetDebugMsg(set, "Computing relative interior point to current LP.\n");
19045
19046 /* if there are no rows, we return the zero point */
19047 if( lp->nrows == 0 && !inclobjcutoff )
19048 {
19049 /* create zero point */
19050 BMSclearMemoryArray(point, lp->ncols);
19051 *success = TRUE;
19052
19053 return SCIP_OKAY;
19054 }
19055
19056 /* create auxiliary LP */
19057 SCIP_CALL( SCIPlpiCreate(&lpi, messagehdlr, "relativeInterior", SCIP_OBJSEN_MAXIMIZE) );
19058
19059 /* catch return code and ensure that lpi is freed, anyway */
19060 retcode = computeRelIntPoint(lpi, set, messagehdlr, lp, prob, relaxrows, inclobjcutoff, timelimit, iterlimit, point, success);
19061
19062 SCIP_CALL( SCIPlpiFree(&lpi) );
19063
19064 /* return error, unless we obtained an LP error */
19065 if ( retcode != SCIP_OKAY && retcode != SCIP_LPERROR )
19066 {
19067 SCIP_CALL( retcode );
19068 }
19069
19070 return SCIP_OKAY;
19071}
19072
19073/** computes two measures for dual degeneracy (dual degeneracy rate and variable-constraint ratio)
19074 * based on the changes applied when reducing the problem to the optimal face
19075 *
19076 * returns the dual degeneracy rate, i.e., the share of nonbasic variables with reduced cost 0
19077 * and the variable-constraint ratio, i.e., the number of unfixed variables in relation to the basis size
19078 */
19080 SCIP_LP* lp, /**< LP data */
19081 SCIP_SET* set, /**< global SCIP settings */
19082 SCIP_STAT* stat, /**< problem statistics */
19083 SCIP_Real* degeneracy, /**< pointer to store the dual degeneracy rate */
19084 SCIP_Real* varconsratio /**< pointer to store the variable-constraint ratio */
19085 )
19086{
19087 assert(lp != NULL);
19088 assert(lp->solved);
19089 assert(lp->flushed);
19090
19091 if( lp->validdegeneracylp != stat->nlps )
19092 {
19093 lp->validdegeneracylp = stat->nlps;
19094
19095 /* if the LP was solved to optimality, we determine the dual degeneracy */
19097 {
19098 SCIP_COL** cols;
19099 SCIP_ROW** rows;
19100 SCIP_COL* col;
19101 int ncols;
19102 int nrows;
19103 int nfixedcols = 0;
19104 int nalreadyfixedcols = 0;
19105 int nfixedrows = 0;
19106#ifndef NDEBUG
19107 int nimplicitfixedrows = 0;
19108#endif
19109 int nineq = 0;
19110 int c;
19111 int r;
19112 int nbasicequalities = 0;
19113
19114 cols = lp->cols;
19115 rows = lp->rows;
19116 ncols = lp->ncols;
19117 nrows = lp->nrows;
19118
19119 /* count number of columns that will be fixed when reducing the LP to the optimal face */
19120 for( c = ncols - 1 ; c >= 0; --c )
19121 {
19122 col = cols[c];
19123 assert(SCIPcolIsInLP(col));
19124
19125 /* column is not basic and not fixed already */
19127 {
19128 /* variable with nonzero reduced costs are fixed */
19129 /* @todo which tolerance should be used here? epsilon or dualfeastol? */
19130 if( !SCIPsetIsZero(set, SCIPcolGetRedcost(col, stat, lp)) )
19131 ++nfixedcols;
19132 else if( SCIPsetIsEQ(set, SCIPcolGetLb(col), SCIPcolGetUb(col)) )
19133 ++nalreadyfixedcols;
19134 }
19135 }
19136
19137 /* count number of rows that will be turned into equations when reducing the LP to the optimal face */
19138 for( r = nrows - 1; r >= 0; --r )
19139 {
19140 SCIP_ROW* row = rows[r];
19141
19142 assert(SCIProwIsInLP(row));
19143
19144 if( !SCIPsetIsEQ(set, SCIProwGetLhs(row), SCIProwGetRhs(row)) )
19145 {
19146 SCIP_Real dualsol = SCIProwGetDualsol(row);
19147
19148 ++nineq;
19149
19151 {
19152 /* rows with nonzero dual solution are turned into equations */
19153 /* @todo which tolerance should be used here? epsilon or dualfeastol? */
19154 if( !SCIPsetIsZero(set, dualsol) )
19155 {
19156 if( SCIPsetIsEQ(set, SCIProwGetLhs(row), SCIProwGetLPActivity(row, set, stat, lp)) )
19157 {
19158 assert(!SCIPlpIsDualReliable(lp) || !SCIPsetIsDualfeasNegative(set, dualsol) || set->exact_enable);
19159 ++nfixedrows;
19160 }
19161 else if( SCIPsetIsEQ(set, SCIProwGetRhs(row), SCIProwGetLPActivity(row, set, stat, lp)) )
19162 {
19163 assert(!SCIPlpIsDualReliable(lp) || !SCIPsetIsDualfeasPositive(set, dualsol)|| set->exact_enable);
19164 ++nfixedrows;
19165 }
19166 }
19167#ifndef NDEBUG
19168 else if( SCIPsetIsEQ(set, SCIProwGetLhs(row), SCIProwGetMaxActivity(row, set, stat))
19169 || SCIPsetIsEQ(set, SCIProwGetRhs(row), SCIProwGetMinActivity(row, set, stat)) )
19170 {
19171 ++nimplicitfixedrows;
19172 }
19173#endif
19174 }
19175 }
19177 ++nbasicequalities;
19178 }
19179 assert(nfixedcols + nfixedrows <= ncols + nineq + nbasicequalities - nrows - nalreadyfixedcols - nimplicitfixedrows);
19180
19181 if( ncols + nineq - nrows + nbasicequalities - nalreadyfixedcols > 0 )
19182 lp->degeneracy = 1.0 - 1.0 * (nfixedcols + nfixedrows) / (ncols + nineq - nrows + nbasicequalities - nalreadyfixedcols);
19183 else
19184 lp->degeneracy = 0.0;
19185
19186 if( nrows > 0 )
19187 lp->varconsratio = 1.0 * (ncols + nineq + nbasicequalities - nfixedcols - nfixedrows - nalreadyfixedcols) / nrows;
19188 else
19189 lp->varconsratio = 1.0; /* @todo should this rather be set to a large value? */
19190 assert(lp->degeneracy >= 0);
19191 assert(SCIPsetIsLE(set, lp->degeneracy, 1.0));
19192 assert(SCIPsetIsGE(set, lp->varconsratio, 1.0));
19193 }
19194 else
19195 {
19196 lp->degeneracy = 0.0;
19197 lp->varconsratio = 0.0;
19198 }
19199 }
19200
19201 *degeneracy = lp->degeneracy;
19202 *varconsratio = lp->varconsratio;
19203
19204 return SCIP_OKAY;
19205}
19206
19207/** checks if absolute difference of values is in range of LP primal feastol */
19209 SCIP_SET* set, /**< global SCIP settings */
19210 SCIP_LP* lp, /**< current LP data */
19211 SCIP_Real val1, /**< first value to be compared */
19212 SCIP_Real val2 /**< second value to be compared */
19213 )
19214{
19215 assert(set != NULL);
19216 assert(lp != NULL);
19217
19218 /* avoid to compare two different infinities; the reason for that is
19219 * that such a comparison can lead to unexpected results */
19220 assert( ((!SCIPsetIsInfinity(set, val1) || !SCIPsetIsInfinity(set, val2))
19221 && (!SCIPsetIsInfinity(set, -val1) || !SCIPsetIsInfinity(set, -val2)))
19222 || val1 == val2 ); /*lint !e777*/
19223
19224 return EPSEQ(val1, val2, lp->feastol);
19225}
19226
19227/** checks if absolute difference of val1 and val2 is lower than LP primal feastol */
19229 SCIP_SET* set, /**< global SCIP settings */
19230 SCIP_LP* lp, /**< current LP data */
19231 SCIP_Real val1, /**< first value to be compared */
19232 SCIP_Real val2 /**< second value to be compared */
19233 )
19234{
19235 assert(set != NULL);
19236 assert(lp != NULL);
19237
19238 /* avoid to compare two different infinities; the reason for that is
19239 * that such a comparison can lead to unexpected results */
19240 assert( ((!SCIPsetIsInfinity(set, val1) || !SCIPsetIsInfinity(set, val2))
19241 && (!SCIPsetIsInfinity(set, -val1) || !SCIPsetIsInfinity(set, -val2)))
19242 || val1 == val2 ); /*lint !e777*/
19243
19244 return EPSLT(val1, val2, lp->feastol);
19245}
19246
19247/** checks if absolute difference of val1 and val2 is not greater than LP primal feastol */
19249 SCIP_SET* set, /**< global SCIP settings */
19250 SCIP_LP* lp, /**< current LP data */
19251 SCIP_Real val1, /**< first value to be compared */
19252 SCIP_Real val2 /**< second value to be compared */
19253 )
19254{
19255 assert(set != NULL);
19256 assert(lp != NULL);
19257
19258 /* avoid to compare two different infinities; the reason for that is
19259 * that such a comparison can lead to unexpected results */
19260 assert( ((!SCIPsetIsInfinity(set, val1) || !SCIPsetIsInfinity(set, val2))
19261 && (!SCIPsetIsInfinity(set, -val1) || !SCIPsetIsInfinity(set, -val2)))
19262 || val1 == val2 ); /*lint !e777*/
19263
19264 return EPSLE(val1, val2, lp->feastol);
19265}
19266
19267/** checks if absolute difference of val1 and val2 is greater than LP primal feastol */
19269 SCIP_SET* set, /**< global SCIP settings */
19270 SCIP_LP* lp, /**< current LP data */
19271 SCIP_Real val1, /**< first value to be compared */
19272 SCIP_Real val2 /**< second value to be compared */
19273 )
19274{
19275 assert(set != NULL);
19276 assert(lp != NULL);
19277
19278 /* avoid to compare two different infinities; the reason for that is
19279 * that such a comparison can lead to unexpected results */
19280 assert( ((!SCIPsetIsInfinity(set, val1) || !SCIPsetIsInfinity(set, val2))
19281 && (!SCIPsetIsInfinity(set, -val1) || !SCIPsetIsInfinity(set, -val2)))
19282 || val1 == val2 ); /*lint !e777*/
19283
19284 return EPSGT(val1, val2, lp->feastol);
19285}
19286
19287/** checks if absolute difference of val1 and val2 is not lower than -LP primal feastol */
19289 SCIP_SET* set, /**< global SCIP settings */
19290 SCIP_LP* lp, /**< current LP data */
19291 SCIP_Real val1, /**< first value to be compared */
19292 SCIP_Real val2 /**< second value to be compared */
19293 )
19294{
19295 assert(set != NULL);
19296 assert(lp != NULL);
19297
19298 /* avoid to compare two different infinities; the reason for that is
19299 * that such a comparison can lead to unexpected results */
19300 assert( ((!SCIPsetIsInfinity(set, val1) || !SCIPsetIsInfinity(set, val2))
19301 && (!SCIPsetIsInfinity(set, -val1) || !SCIPsetIsInfinity(set, -val2)))
19302 || val1 == val2 ); /*lint !e777*/
19303
19304 return EPSGE(val1, val2, lp->feastol);
19305}
19306
19307/** checks if value is in range LP primal feasibility tolerance of 0.0 */
19309 SCIP_LP* lp, /**< current LP data */
19310 SCIP_Real val /**< value to process */
19311 )
19312{
19313 assert(lp != NULL);
19314
19315 return EPSZ(val, lp->feastol);
19316}
19317
19318/** checks if value is greater than LP primal feasibility tolerance */
19320 SCIP_LP* lp, /**< current LP data */
19321 SCIP_Real val /**< value to process */
19322 )
19323{
19324 assert(lp != NULL);
19325
19326 return EPSP(val, lp->feastol);
19327}
19328
19329/** checks if value is lower than -LP primal feasibility tolerance */
19331 SCIP_LP* lp, /**< current LP data */
19332 SCIP_Real val /**< value to process */
19333 )
19334{
19335 assert(lp != NULL);
19336
19337 return EPSN(val, lp->feastol);
19338}
static long bound
SCIP_RETCODE SCIPcertificateFreeRowInfo(SCIP *scip, SCIP_ROW *row)
methods for certificate output
SCIP_VAR * a
SCIP_VAR ** b
SCIP_VAR ** y
SCIP_VAR ** x
void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
Definition clock.c:360
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition clock.c:290
SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
Definition clock.c:438
internal methods for clocks and timing issues
void SCIPconsCapture(SCIP_CONS *cons)
Definition cons.c:6427
SCIP_RETCODE SCIPconsRelease(SCIP_CONS **cons, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition cons.c:6439
internal methods for constraints and constraint handlers
#define NULL
Definition def.h:255
#define SCIP_MAXSTRLEN
Definition def.h:276
#define EPSGE(x, y, eps)
Definition def.h:194
#define SCIP_Longint
Definition def.h:148
#define SCIP_UNUSED(x)
Definition def.h:416
#define EPSISINT(x, eps)
Definition def.h:202
#define SCIP_DEFAULT_SUMEPSILON
Definition def.h:172
#define EPSP(x, eps)
Definition def.h:196
#define SCIP_REAL_MAX
Definition def.h:165
#define SCIP_INVALID
Definition def.h:185
#define SCIP_Bool
Definition def.h:98
#define SCIP_DEFAULT_EPSILON
Definition def.h:171
#define EPSLE(x, y, eps)
Definition def.h:192
#define MIN(x, y)
Definition def.h:231
#define SCIP_ALLOC(x)
Definition def.h:373
#define SCIP_Real
Definition def.h:163
#define SCIP_UNKNOWN
Definition def.h:186
#define EPSLT(x, y, eps)
Definition def.h:191
#define ABS(x)
Definition def.h:223
#define SQR(x)
Definition def.h:206
#define EPSEQ(x, y, eps)
Definition def.h:190
#define TRUE
Definition def.h:100
#define FALSE
Definition def.h:101
#define MAX(x, y)
Definition def.h:227
#define SCIP_CALL_ABORT(x)
Definition def.h:341
#define EPSN(x, eps)
Definition def.h:197
#define SCIP_LONGINT_FORMAT
Definition def.h:155
#define SCIPABORT()
Definition def.h:334
#define REALABS(x)
Definition def.h:189
#define EPSGT(x, y, eps)
Definition def.h:193
#define SCIP_LONGINT_MAX
Definition def.h:149
#define EPSZ(x, eps)
Definition def.h:195
#define SCIP_CALL(x)
Definition def.h:362
SCIP_RETCODE SCIPeventCreateRowDeletedLP(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
Definition event.c:1055
SCIP_RETCODE SCIPeventqueueAdd(SCIP_EVENTQUEUE *eventqueue, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTFILTER *eventfilter, SCIP_EVENT **event)
Definition event.c:2561
SCIP_RETCODE SCIPeventfilterFree(SCIP_EVENTFILTER **eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition event.c:2167
SCIP_RETCODE SCIPeventCreateRowSideChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_SIDETYPE side, SCIP_Real oldval, SCIP_Real newval)
Definition event.c:1122
SCIP_RETCODE SCIPeventfilterDel(SCIP_EVENTFILTER *eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
Definition event.c:2300
SCIP_RETCODE SCIPeventfilterCreate(SCIP_EVENTFILTER **eventfilter, BMS_BLKMEM *blkmem)
Definition event.c:2142
SCIP_RETCODE SCIPeventCreateRowConstChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_Real oldval, SCIP_Real newval)
Definition event.c:1099
SCIP_RETCODE SCIPeventfilterAdd(SCIP_EVENTFILTER *eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition event.c:2207
SCIP_RETCODE SCIPeventCreateRowCoefChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_COL *col, SCIP_Real oldval, SCIP_Real newval)
Definition event.c:1074
SCIP_RETCODE SCIPeventCreateRowAddedLP(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
Definition event.c:1036
internal methods for managing events
SCIP_Bool SCIPlpiExactHasDualRay(SCIP_LPIEXACT *lpi)
SCIP_RETCODE SCIPlpiChgSides(SCIP_LPI *lpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
Definition lpi_clp.cpp:1179
SCIP_RETCODE SCIPlpiSetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPISTATE *lpistate)
Definition lpi_clp.cpp:3457
SCIP_RETCODE SCIPlpiGetBInvACol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition lpi_clp.cpp:3377
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_Bool SCIPlpiExistsPrimalRay(SCIP_LPI *lpi)
Definition lpi_clp.cpp:2478
SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
Definition lpi_clp.cpp:2995
SCIP_RETCODE SCIPlpiAddRows(SCIP_LPI *lpi, int nrows, const SCIP_Real *lhs, const SCIP_Real *rhs, char **rownames, int nnonz, const int *beg, const int *ind, const SCIP_Real *val)
Definition lpi_clp.cpp:920
SCIP_RETCODE SCIPlpiGetPrimalRay(SCIP_LPI *lpi, SCIP_Real *ray)
Definition lpi_clp.cpp:2860
SCIP_RETCODE SCIPlpiGetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int *ival)
Definition lpi_clp.cpp:3676
SCIP_RETCODE SCIPlpiWriteLP(SCIP_LPI *lpi, const char *fname)
Definition lpi_clp.cpp:4029
SCIP_RETCODE SCIPlpiSetIntegralityInformation(SCIP_LPI *lpi, int ncols, int *intInfo)
Definition lpi_clp.cpp:480
SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
Definition lpi_clp.cpp:3861
SCIP_RETCODE SCIPlpiStrongbranchFrac(SCIP_LPI *lpi, int col, SCIP_Real psol, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition lpi_clp.cpp:2311
SCIP_RETCODE SCIPlpiSetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPINORMS *lpinorms)
Definition lpi_clp.cpp:3638
SCIP_RETCODE SCIPlpiStrongbranchInt(SCIP_LPI *lpi, int col, SCIP_Real psol, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition lpi_clp.cpp:2357
SCIP_RETCODE SCIPlpiGetBounds(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lbs, SCIP_Real *ubs)
Definition lpi_clp.cpp:1733
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
int SCIPlpiGetInternalStatus(SCIP_LPI *lpi)
Definition lpi_clp.cpp:2780
SCIP_RETCODE SCIPlpiStartStrongbranch(SCIP_LPI *lpi)
Definition lpi_clp.cpp:2034
SCIP_RETCODE SCIPlpiGetSolFeasibility(SCIP_LPI *lpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
Definition lpi_clp.cpp:2433
SCIP_RETCODE SCIPlpiFreeNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition lpi_clp.cpp:3651
SCIP_Bool SCIPlpiIsIterlimExc(SCIP_LPI *lpi)
Definition lpi_clp.cpp:2748
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 SCIPlpiIsPrimalUnbounded(SCIP_LPI *lpi)
Definition lpi_clp.cpp:2516
SCIP_RETCODE SCIPlpiIgnoreInstability(SCIP_LPI *lpi, SCIP_Bool *success)
Definition lpi_clp.cpp:1669
SCIP_RETCODE SCIPlpiFree(SCIP_LPI **lpi)
Definition lpi_clp.cpp:643
SCIP_RETCODE SCIPlpiStrongbranchesFrac(SCIP_LPI *lpi, int *cols, int ncols, SCIP_Real *psols, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition lpi_clp.cpp:2332
SCIP_Bool SCIPlpiIsPrimalFeasible(SCIP_LPI *lpi)
Definition lpi_clp.cpp:2549
SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
Definition lpi_clp.cpp:2637
SCIP_RETCODE SCIPlpiGetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition lpi_clp.cpp:3620
SCIP_Bool SCIPlpiIsTimelimExc(SCIP_LPI *lpi)
Definition lpi_clp.cpp:2764
SCIP_Bool SCIPlpiHasStateBasis(SCIP_LPI *lpi, SCIP_LPISTATE *lpistate)
Definition lpi_clp.cpp:3550
SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
Definition lpi_clp.cpp:3720
const char * SCIPlpiGetSolverName(void)
Definition lpi_clp.cpp:454
SCIP_Bool SCIPlpiHasPrimalRay(SCIP_LPI *lpi)
Definition lpi_clp.cpp:2496
SCIP_RETCODE SCIPlpiGetBInvRow(SCIP_LPI *lpi, int r, SCIP_Real *coef, int *inds, int *ninds)
Definition lpi_clp.cpp:3269
SCIP_RETCODE SCIPlpiDelRows(SCIP_LPI *lpi, int firstrow, int lastrow)
Definition lpi_clp.cpp:992
SCIP_RETCODE SCIPlpiGetBInvCol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition lpi_clp.cpp:3304
SCIP_RETCODE SCIPlpiGetBInvARow(SCIP_LPI *lpi, int r, const SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
Definition lpi_clp.cpp:3342
SCIP_RETCODE SCIPlpiSolveBarrier(SCIP_LPI *lpi, SCIP_Bool crossover)
Definition lpi_clp.cpp:1985
SCIP_Bool SCIPlpiIsOptimal(SCIP_LPI *lpi)
Definition lpi_clp.cpp:2651
SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
Definition lpi_clp.cpp:2046
SCIP_RETCODE SCIPlpiGetSides(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhss, SCIP_Real *rhss)
Definition lpi_clp.cpp:1766
SCIP_RETCODE SCIPlpiStrongbranchesInt(SCIP_LPI *lpi, int *cols, int ncols, SCIP_Real *psols, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition lpi_clp.cpp:2378
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_RETCODE SCIPlpiDelColset(SCIP_LPI *lpi, int *dstat)
Definition lpi_clp.cpp:874
SCIP_RETCODE SCIPlpiGetObj(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *vals)
Definition lpi_clp.cpp:1708
SCIP_RETCODE SCIPlpiFreeState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition lpi_clp.cpp:3531
SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
Definition lpi_clp.cpp:2530
SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
Definition lpi_clp.cpp:1908
SCIP_RETCODE SCIPlpiAddCols(SCIP_LPI *lpi, int ncols, const SCIP_Real *obj, const SCIP_Real *lb, const SCIP_Real *ub, char **colnames, int nnonz, const int *beg, const int *ind, const SCIP_Real *val)
Definition lpi_clp.cpp:758
SCIP_RETCODE SCIPlpiSolvePrimal(SCIP_LPI *lpi)
Definition lpi_clp.cpp:1833
SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
Definition lpi_clp.cpp:2949
SCIP_RETCODE SCIPlpiGetBasisInd(SCIP_LPI *lpi, int *bind)
Definition lpi_clp.cpp:3217
SCIP_RETCODE SCIPlpiCreate(SCIP_LPI **lpi, SCIP_MESSAGEHDLR *messagehdlr, const char *name, SCIP_OBJSEN objsen)
Definition lpi_clp.cpp:531
SCIP_RETCODE SCIPlpiChgObj(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *obj)
Definition lpi_clp.cpp:1252
SCIP_Bool SCIPlpiIsStable(SCIP_LPI *lpi)
Definition lpi_clp.cpp:2675
SCIP_RETCODE SCIPlpiGetNCols(SCIP_LPI *lpi, int *ncols)
Definition lpi_clp.cpp:1447
SCIP_RETCODE SCIPlpiInterrupt(SCIP_LPI *lpi, SCIP_Bool interrupt)
Definition lpi_clp.cpp:3923
SCIP_RETCODE SCIPlpiDelCols(SCIP_LPI *lpi, int firstcol, int lastcol)
Definition lpi_clp.cpp:837
SCIP_RETCODE SCIPlpiDelRowset(SCIP_LPI *lpi, int *dstat)
Definition lpi_clp.cpp:1030
SCIP_RETCODE SCIPlpiGetNRows(SCIP_LPI *lpi, int *nrows)
Definition lpi_clp.cpp:1429
SCIP_RETCODE SCIPlpiGetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition lpi_clp.cpp:3417
SCIP_Longint SCIPcalcGreComDiv(SCIP_Longint val1, SCIP_Longint val2)
Definition misc.c:9197
SCIP_Bool SCIPrealIsExactlyIntegral(SCIP_Real val)
Definition misc.c:9604
SCIP_Bool SCIPrealToRational(SCIP_Real val, SCIP_Real mindelta, SCIP_Real maxdelta, SCIP_Longint maxdnom, SCIP_Longint *numerator, SCIP_Longint *denominator)
Definition misc.c:9470
SCIP_Real SCIPrelDiff(SCIP_Real val1, SCIP_Real val2)
Definition misc.c:11162
void SCIPswapPointers(void **pointer1, void **pointer2)
Definition misc.c:10511
SCIP_Real SCIPcolGetMinPrimsol(SCIP_COL *col)
Definition lp.c:17392
int SCIPcolGetLPPos(SCIP_COL *col)
Definition lp.c:17487
int SCIPcolGetVarProbindex(SCIP_COL *col)
Definition lp.c:17445
SCIP_Bool SCIPcolIsRemovable(SCIP_COL *col)
Definition lp.c:17477
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
Definition lp.c:17425
SCIP_Bool SCIPcolIsIntegral(SCIP_COL *col)
Definition lp.c:17455
SCIP_Bool SCIPcolIsImpliedIntegral(SCIP_COL *col)
Definition lp.c:17466
SCIP_Real SCIPcolGetObj(SCIP_COL *col)
Definition lp.c:17336
int SCIPcolGetNNonz(SCIP_COL *col)
Definition lp.c:17520
SCIP_Real * SCIPcolGetVals(SCIP_COL *col)
Definition lp.c:17555
SCIP_ROW ** SCIPcolGetRows(SCIP_COL *col)
Definition lp.c:17545
void SCIPcolSort(SCIP_COL *col)
Definition lp.c:3630
int SCIPcolGetIndex(SCIP_COL *col)
Definition lp.c:17435
SCIP_Real SCIPcolGetBestBound(SCIP_COL *col)
Definition lp.c:17366
SCIP_Real SCIPcolGetLb(SCIP_COL *col)
Definition lp.c:17346
SCIP_Real SCIPcolGetPrimsol(SCIP_COL *col)
Definition lp.c:17379
SCIP_Real SCIPcolGetUb(SCIP_COL *col)
Definition lp.c:17356
SCIP_Longint SCIPcolGetStrongbranchNode(SCIP_COL *col)
Definition lp.c:17567
int SCIPcolGetNLPNonz(SCIP_COL *col)
Definition lp.c:17534
int SCIPcolGetNStrongbranchs(SCIP_COL *col)
Definition lp.c:17577
int SCIPcolGetAge(SCIP_COL *col)
Definition lp.c:17587
SCIP_Bool SCIPcolIsInLP(SCIP_COL *col)
Definition lp.c:17509
int SCIPcolGetLPDepth(SCIP_COL *col)
Definition lp.c:17498
SCIP_BASESTAT SCIPcolGetBasisStatus(SCIP_COL *col)
Definition lp.c:17414
SCIP_BOUNDTYPE SCIPboundtypeOpposite(SCIP_BOUNDTYPE boundtype)
Definition lp.c:17597
SCIP_Real SCIPcolGetMaxPrimsol(SCIP_COL *col)
Definition lp.c:17402
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition cons.c:8409
SCIP_Real SCIPintervalGetInf(SCIP_INTERVAL interval)
void SCIPintervalSub(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
void SCIPintervalSet(SCIP_INTERVAL *resultant, SCIP_Real value)
void SCIPintervalSetBounds(SCIP_INTERVAL *resultant, SCIP_Real inf, SCIP_Real sup)
struct SCIP_Interval SCIP_INTERVAL
void SCIPintervalMul(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
void SCIPintervalAdd(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
void SCIPintervalSetRational(SCIP_INTERVAL *resultant, SCIP_RATIONAL *value)
SCIP_Bool SCIPrationalIsFpRepresentable(SCIP_RATIONAL *rational)
SCIP_Bool SCIProwIsIntegral(SCIP_ROW *row)
Definition lp.c:17785
void SCIProwSort(SCIP_ROW *row)
Definition lp.c:6232
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
Definition lp.c:17686
SCIP_Bool SCIProwIsModifiable(SCIP_ROW *row)
Definition lp.c:17805
SCIP_Longint SCIProwGetActiveLPCount(SCIP_ROW *row)
Definition lp.c:17939
SCIP_Real SCIProwGetOrthogonality(SCIP_ROW *row1, SCIP_ROW *row2, char orthofunc)
Definition lp.c:8034
SCIP_Real SCIProwGetScalarProduct(SCIP_ROW *row1, SCIP_ROW *row2)
Definition lp.c:7254
int SCIProwGetLPDepth(SCIP_ROW *row)
Definition lp.c:17906
SCIP_Real SCIProwGetParallelism(SCIP_ROW *row1, SCIP_ROW *row2, char orthofunc)
Definition lp.c:7970
SCIP_CONS * SCIProwGetOriginCons(SCIP_ROW *row)
Definition lp.c:17835
int SCIProwGetNNonz(SCIP_ROW *row)
Definition lp.c:17607
SCIP_COL ** SCIProwGetCols(SCIP_ROW *row)
Definition lp.c:17632
SCIP_Bool SCIProwIsInGlobalCutpool(SCIP_ROW *row)
Definition lp.c:17885
SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
Definition lp.c:17696
int SCIProwGetAge(SCIP_ROW *row)
Definition lp.c:17765
int SCIProwGetNLPNonz(SCIP_ROW *row)
Definition lp.c:17621
SCIP_Real SCIProwGetNorm(SCIP_ROW *row)
Definition lp.c:17662
int SCIProwGetLPPos(SCIP_ROW *row)
Definition lp.c:17895
SCIP_Bool SCIProwIsLocal(SCIP_ROW *row)
Definition lp.c:17795
SCIP_CONSHDLR * SCIProwGetOriginConshdlr(SCIP_ROW *row)
Definition lp.c:17850
SCIP_Longint SCIProwGetNLPsAfterCreation(SCIP_ROW *row)
Definition lp.c:17949
void SCIProwLock(SCIP_ROW *row)
Definition lp.c:5594
SCIP_Bool SCIProwIsRemovable(SCIP_ROW *row)
Definition lp.c:17815
const char * SCIProwGetName(SCIP_ROW *row)
Definition lp.c:17745
SCIP_SEPA * SCIProwGetOriginSepa(SCIP_ROW *row)
Definition lp.c:17870
void SCIProwUnlock(SCIP_ROW *row)
Definition lp.c:5609
SCIP_Real SCIProwGetSumNorm(SCIP_ROW *row)
Definition lp.c:17674
int SCIProwGetRank(SCIP_ROW *row)
Definition lp.c:17775
SCIP_Real SCIProwGetDualfarkas(SCIP_ROW *row)
Definition lp.c:17719
int SCIProwGetIndex(SCIP_ROW *row)
Definition lp.c:17755
void SCIProwChgRank(SCIP_ROW *row, int rank)
Definition lp.c:17928
SCIP_Real SCIProwGetConstant(SCIP_ROW *row)
Definition lp.c:17652
SCIP_ROWEXACT * SCIProwGetRowExact(SCIP_ROW *row)
Definition lp.c:17959
SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
Definition lp.c:17917
SCIP_Real SCIProwGetDualsol(SCIP_ROW *row)
Definition lp.c:17706
SCIP_Real * SCIProwGetVals(SCIP_ROW *row)
Definition lp.c:17642
SCIP_ROWORIGINTYPE SCIProwGetOrigintype(SCIP_ROW *row)
Definition lp.c:17825
SCIP_BASESTAT SCIProwGetBasisStatus(SCIP_ROW *row)
Definition lp.c:17734
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition var.c:23683
SCIP_BOUNDTYPE SCIPvarGetBestBoundType(SCIP_VAR *var)
Definition var.c:24372
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition var.c:23478
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition var.c:23386
SCIP_Bool SCIPvarIsImpliedIntegral(SCIP_VAR *var)
Definition var.c:23498
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition var.c:24268
int SCIPvarGetNLocksDown(SCIP_VAR *var)
Definition var.c:4449
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition var.c:23900
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition var.c:24142
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition var.c:23662
const char * SCIPvarGetName(SCIP_VAR *var)
Definition var.c:23267
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition var.c:23490
SCIP_Real SCIPvarGetUbLazy(SCIP_VAR *var)
Definition var.c:24438
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition var.c:24234
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition var.c:24120
int SCIPvarGetNLocksUp(SCIP_VAR *var)
Definition var.c:4462
SCIP_Real SCIPvarGetNLPSol(SCIP_VAR *var)
Definition var.c:24691
SCIP_RATIONAL * SCIPvarGetObjExact(SCIP_VAR *var)
Definition var.c:23910
SCIP_Real SCIPvarGetUnchangedObj(SCIP_VAR *var)
Definition var.c:23932
SCIP_Real SCIPvarGetLbLazy(SCIP_VAR *var)
Definition var.c:24428
void SCIPsortPtrRealInt(void **ptrarray, SCIP_Real *realarray, int *intarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), int len)
void SCIPsortIntPtrIntReal(int *intarray1, void **ptrarray, int *intarray2, SCIP_Real *realarray, int len)
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition misc.c:10827
void SCIPprintSysError(const char *message)
Definition misc.c:10719
return SCIP_OKAY
SCIP_Bool lperror
int c
heurdata nlpiterations
int depth
SCIP_Real objval
int nlprows
static SCIP_SOL * sol
SCIP_Longint nlps
int r
SCIP_Real obj
assert(minobj< SCIPgetCutoffbound(scip))
int nvars
SCIP_VAR * var
SCIP_Real primsol
SCIP_Real objscale
SCIP_Real newobj
SCIP_Real oldobj
static SCIP_VAR ** vars
SCIP_Real alpha
interval arithmetics for provable bounds
static SCIP_RETCODE lpFlushDelRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition lp.c:8425
static void rowCalcIdxsAndVals(SCIP_ROW *row, SCIP_SET *set)
Definition lp.c:5023
SCIP_RETCODE SCIPlpCleanupNew(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_Bool root)
Definition lp.c:16231
SCIP_Bool SCIPlpIsSolBasic(SCIP_LP *lp)
Definition lp.c:18241
#define debugColPrint(x, y)
Definition lp.c:164
static void getObjvalDeltaObj(SCIP_SET *set, SCIP_Real oldobj, SCIP_Real newobj, SCIP_Real lb, SCIP_Real ub, SCIP_Real *deltaval, int *deltainf)
Definition lp.c:13753
static SCIP_RETCODE lpSetObjlim(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_Real objlim, SCIP_Bool *success)
Definition lp.c:2789
static SCIP_RETCODE insertColChgcols(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp)
Definition lp.c:3814
SCIP_Real SCIProwGetMaxval(SCIP_ROW *row, SCIP_SET *set)
Definition lp.c:6901
SCIP_Real SCIProwGetRelaxEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition lp.c:7170
SCIP_RETCODE SCIPcolChgUb(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newub)
Definition lp.c:3997
SCIP_Real SCIProwGetLPFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition lp.c:6484
SCIP_Real SCIPcolCalcRedcost(SCIP_COL *col, SCIP_Real *dualsol)
Definition lp.c:4042
SCIP_RETCODE SCIPlpGetBInvRow(SCIP_LP *lp, int r, SCIP_Real *coef, int *inds, int *ninds)
Definition lp.c:10100
static SCIP_RETCODE lpSetRefactorInterval(SCIP_LP *lp, int refactor, SCIP_Bool *success)
Definition lp.c:3446
SCIP_Real SCIProwGetNLPFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition lp.c:6566
SCIP_RETCODE SCIPcolFree(SCIP_COL **col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition lp.c:3572
static SCIP_RETCODE lpSolveStable(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_LPALGO lpalgo, int itlim, int harditlim, SCIP_Bool resolve, int fastmip, SCIP_Bool tightprimfeastol, SCIP_Bool tightdualfeastol, SCIP_Bool fromscratch, int scaling, SCIP_Bool keepsol, SCIP_Bool *timelimit, SCIP_Bool *lperror)
Definition lp.c:11843
void SCIProwCapture(SCIP_ROW *row)
Definition lp.c:5554
SCIP_RETCODE SCIPlpFreeState(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition lp.c:10350
SCIP_Real SCIProwGetPseudoFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition lp.c:6680
SCIP_RETCODE SCIPlpUpdateAges(SCIP_LP *lp, SCIP_STAT *stat)
Definition lp.c:15622
SCIP_RETCODE SCIPlpGetBInvCol(SCIP_LP *lp, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition lp.c:10122
SCIP_RETCODE SCIPcolChgLb(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newlb)
Definition lp.c:3952
#define DIVESTACKGROWFACT
Definition lp.c:16672
static SCIP_RETCODE lpSetTiming(SCIP_LP *lp, SCIP_CLOCKTYPE timing, SCIP_Bool enabled, SCIP_Bool *success)
Definition lp.c:3359
SCIP_RETCODE SCIPlpInterrupt(SCIP_LP *lp, SCIP_Bool interrupt)
Definition lp.c:10367
static SCIP_RETCODE lpLexDualSimplex(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool resolve, SCIP_Bool keepsol, SCIP_Bool *lperror)
Definition lp.c:10923
static void rowDelNorms(SCIP_ROW *row, SCIP_SET *set, SCIP_COL *col, SCIP_Real val, SCIP_Bool forcenormupdate, SCIP_Bool updateindex, SCIP_Bool updateval)
Definition lp.c:2116
SCIP_RETCODE SCIProwChgCoef(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_COL *col, SCIP_Real val)
Definition lp.c:5692
static SCIP_RETCODE lpSetFromscratch(SCIP_LP *lp, SCIP_Bool fromscratch, SCIP_Bool *success)
Definition lp.c:3029
static void colSortNonLP(SCIP_COL *col)
Definition lp.c:1131
static SCIP_RETCODE ensureLpicolsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition lp.c:219
SCIP_Real SCIPcolCalcFarkasCoef(SCIP_COL *col, SCIP_Real *dualfarkas)
Definition lp.c:4225
static void rowMoveCoef(SCIP_ROW *row, int oldpos, int newpos)
Definition lp.c:1493
static SCIP_RETCODE lpSetFastmip(SCIP_LP *lp, int fastmip, SCIP_Bool *success)
Definition lp.c:3054
SCIP_RETCODE SCIPlpGetNorms(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition lp.c:10383
static SCIP_RETCODE lpSetRealpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Real value, SCIP_Bool *success)
Definition lp.c:2689
static SCIP_RETCODE lpCopyIntegrality(SCIP_LP *lp, SCIP_SET *set)
Definition lp.c:8869
static SCIP_RETCODE lpStoreSolVals(SCIP_LP *lp, SCIP_STAT *stat, BMS_BLKMEM *blkmem)
Definition lp.c:381
void SCIPlpMarkSize(SCIP_LP *lp)
Definition lp.c:10040
static SCIP_RETCODE lpUpdateVarProved(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real oldlb, SCIP_Real oldub, SCIP_Real newobj, SCIP_Real newlb, SCIP_Real newub, SCIP_Bool global)
Definition lp.c:14042
int SCIProwGetNumIntCols(SCIP_ROW *row, SCIP_SET *set)
Definition lp.c:6965
static SCIP_RETCODE lpSetLPInfo(SCIP_LP *lp, SCIP_Bool lpinfo)
Definition lp.c:3286
SCIP_RETCODE SCIPlpGetState(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition lp.c:10283
void SCIPlpRecalculateObjSqrNorm(SCIP_SET *set, SCIP_LP *lp)
Definition lp.c:18080
static void lpUpdateObjNorms(SCIP_LP *lp, SCIP_SET *set, SCIP_Real oldobj, SCIP_Real newobj)
Definition lp.c:3857
static SCIP_RETCODE lpRemoveObsoleteRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int firstrow)
Definition lp.c:15955
int SCIPlpGetNNewcols(SCIP_LP *lp)
Definition lp.c:18047
SCIP_Real SCIProwGetSolFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition lp.c:6738
void SCIProwRecalcPseudoActivity(SCIP_ROW *row, SCIP_STAT *stat)
Definition lp.c:6625
SCIP_RETCODE SCIProwEnsureSize(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
Definition lp.c:636
SCIP_Bool SCIPlpIsFeasPositive(SCIP_LP *lp, SCIP_Real val)
Definition lp.c:19319
SCIP_Bool SCIPlpIsFeasGT(SCIP_SET *set, SCIP_LP *lp, SCIP_Real val1, SCIP_Real val2)
Definition lp.c:19268
SCIP_RETCODE SCIPlpIsInfeasibilityProved(SCIP_LP *lp, SCIP_SET *set, SCIP_Bool *proved)
Definition lp.c:16889
SCIP_Real SCIProwGetRelaxFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition lp.c:6504
SCIP_RETCODE SCIPlpAddCol(SCIP_LP *lp, SCIP_SET *set, SCIP_COL *col, int depth)
Definition lp.c:9699
#define MAXNUMTROUBLELPMSGS
Definition lp.c:11752
SCIP_Real SCIPlpGetLooseObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition lp.c:13475
SCIP_RETCODE SCIPlpSetState(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PROB *prob, SCIP_EVENTQUEUE *eventqueue, SCIP_LPISTATE *lpistate, SCIP_Bool wasprimfeas, SCIP_Bool wasprimchecked, SCIP_Bool wasdualfeas, SCIP_Bool wasdualchecked)
Definition lp.c:10307
static SCIP_RETCODE colDelCoefPos(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, int pos)
Definition lp.c:1949
static void colSwapCoefs(SCIP_COL *col, int pos1, int pos2)
Definition lp.c:1433
static void rowCalcActivityBounds(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition lp.c:6756
SCIP_Real SCIPlpGetObjNorm(SCIP_LP *lp)
Definition lp.c:18111
SCIP_Real SCIProwGetMaxActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition lp.c:6849
SCIP_RETCODE SCIProwMakeIntegral(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_STAT *stat, SCIP_LP *lp, SCIP_Real mindelta, SCIP_Real maxdelta, SCIP_Longint maxdnom, SCIP_Real maxscale, SCIP_Bool usecontvars, SCIP_Bool *success)
Definition lp.c:6197
static SCIP_RETCODE lpSetPresolving(SCIP_LP *lp, SCIP_Bool presolving, SCIP_Bool *success)
Definition lp.c:3135
SCIP_RETCODE SCIPlpRemoveNewObsoletes(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition lp.c:16031
SCIP_Bool SCIProwIsLPEfficacious(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_Bool root)
Definition lp.c:7095
SCIP_Real SCIProwGetSolEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition lp.c:7111
static int colSearchCoefPart(SCIP_COL *col, const SCIP_ROW *row, int minpos, int maxpos)
Definition lp.c:1230
SCIP_RETCODE SCIPlpStartStrongbranch(SCIP_LP *lp)
Definition lp.c:4375
static int rowSearchCoefPart(SCIP_ROW *row, const SCIP_COL *col, int minpos, int maxpos)
Definition lp.c:1305
SCIP_Bool SCIPlpDivingObjChanged(SCIP_LP *lp)
Definition lp.c:18261
#define checkRowSumnorm(row)
Definition lp.c:776
static int colSearchCoef(SCIP_COL *col, const SCIP_ROW *row)
Definition lp.c:1266
SCIP_RETCODE SCIPlpFlush(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PROB *prob, SCIP_EVENTQUEUE *eventqueue)
Definition lp.c:8917
static SCIP_RETCODE rowDelCoefPos(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, int pos)
Definition lp.c:2318
SCIP_RETCODE SCIPlpUpdateVarLb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb)
Definition lp.c:14264
void SCIPlpDecNLoosevars(SCIP_LP *lp)
Definition lp.c:14686
static void rowSwapCoefs(SCIP_ROW *row, int pos1, int pos2)
Definition lp.c:1530
SCIP_RETCODE SCIProwAddConstant(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_Real addval)
Definition lp.c:5856
static SCIP_RETCODE rowChgCoefPos(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, int pos, SCIP_Real val)
Definition lp.c:2377
static SCIP_RETCODE rowEventCoefChanged(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_COL *col, SCIP_Real oldval, SCIP_Real newval)
Definition lp.c:1595
static SCIP_RETCODE lpAdjustObjlimForExactSolve(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_STAT *stat, SCIP_Bool *success)
Definition lp.c:2841
static void recomputePseudoObjectiveValue(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition lp.c:948
void SCIPlpSetFeastol(SCIP_LP *lp, SCIP_SET *set, SCIP_Real newfeastol)
Definition lp.c:10509
SCIP_RETCODE SCIPcolChgCoef(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_ROW *row, SCIP_Real val)
Definition lp.c:3708
SCIP_RETCODE rowUnlink(SCIP_ROW *row, SCIP_SET *set, SCIP_LP *lp)
Definition lp.c:2611
#define lpCutoffDisabled(set, prob, lp)
Definition lp.c:2782
SCIP_RETCODE SCIPlpWrite(SCIP_LP *lp, const char *fname)
Definition lp.c:16911
int SCIProwGetMaxidx(SCIP_ROW *row, SCIP_SET *set)
Definition lp.c:6933
static void colSortLP(SCIP_COL *col)
Definition lp.c:1098
static void adjustLPobjval(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr)
Definition lp.c:12260
static SCIP_RETCODE lpFlushAddRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
Definition lp.c:8474
SCIP_Real SCIPlpGetModifiedPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound, SCIP_BOUNDTYPE boundtype)
Definition lp.c:13711
static int rowSearchCoef(SCIP_ROW *row, const SCIP_COL *col)
Definition lp.c:1344
SCIP_Real SCIProwGetLPActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition lp.c:6454
void SCIProwMarkNotRemovableLocal(SCIP_ROW *row, SCIP_STAT *stat)
Definition lp.c:8124
static SCIP_RETCODE lpSetPricing(SCIP_LP *lp, SCIP_PRICING pricing)
Definition lp.c:3221
SCIP_RETCODE SCIPlpUpdateVarLbGlobal(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb)
Definition lp.c:14226
static SCIP_RETCODE colRestoreSolVals(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_Longint validlp, SCIP_Bool freebuffer)
Definition lp.c:504
SCIP_LPSOLSTAT SCIPlpGetSolstat(SCIP_LP *lp)
Definition lp.c:13420
SCIP_RETCODE SCIPlpShrinkCols(SCIP_LP *lp, SCIP_SET *set, int newncols)
Definition lp.c:9883
void SCIPlpStoreRootObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition lp.c:13495
static SCIP_RETCODE lpSetPricingChar(SCIP_LP *lp, char pricingchar)
Definition lp.c:3244
SCIP_RETCODE SCIProwCreate(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, const char *name, int len, SCIP_COL **cols, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_ROWORIGINTYPE origintype, void *origin, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool removable)
Definition lp.c:5313
static SCIP_RETCODE colStoreSolVals(SCIP_COL *col, BMS_BLKMEM *blkmem)
Definition lp.c:477
static SCIP_RETCODE rowAddCoef(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_COL *col, SCIP_Real val, int linkpos)
Definition lp.c:2174
SCIP_ROW ** SCIPlpGetNewrows(SCIP_LP *lp)
Definition lp.c:18058
static SCIP_RETCODE ensureSoldirectionSize(SCIP_LP *lp, int num)
Definition lp.c:288
void SCIPlpRecomputeLocalAndGlobalPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition lp.c:13519
static SCIP_RETCODE lpSetMarkowitz(SCIP_LP *lp, SCIP_Real threshhold, SCIP_Bool *success)
Definition lp.c:3334
static void rowUpdateAddLP(SCIP_ROW *row)
Definition lp.c:9149
static SCIP_RETCODE lpCheckIntpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, int value)
Definition lp.c:2717
SCIP_Real SCIPlpGetColumnObjval(SCIP_LP *lp)
Definition lp.c:13464
SCIP_RETCODE SCIPlpUpdateAddVar(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition lp.c:14384
SCIP_RETCODE SCIPlpClear(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition lp.c:10021
SCIP_Bool SCIPlpIsPrimalReliable(SCIP_LP *lp)
Definition lp.c:18221
static SCIP_RETCODE colEnsureSize(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
Definition lp.c:354
static void rowSortNonLP(SCIP_ROW *row)
Definition lp.c:1195
void SCIPlpSetIsRelax(SCIP_LP *lp, SCIP_Bool relax)
Definition lp.c:18188
static SCIP_RETCODE ensureChgcolsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition lp.c:173
SCIP_RETCODE SCIProwDelCoef(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_COL *col)
Definition lp.c:5646
SCIP_RETCODE SCIPlpGetBase(SCIP_LP *lp, int *cstat, int *rstat)
Definition lp.c:10083
SCIP_Bool SCIPlpIsRelax(SCIP_LP *lp)
Definition lp.c:18201
#define FEASTOLTIGHTFAC
Definition lp.c:11840
static SCIP_RETCODE rowEventConstantChanged(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_Real oldval, SCIP_Real newval)
Definition lp.c:1625
void SCIPcolInvalidateStrongbranchData(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition lp.c:4459
static SCIP_RETCODE lpSolve(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_LPALGO lpalgo, int resolveitlim, int harditlim, SCIP_Bool needprimalray, SCIP_Bool needdualray, SCIP_Bool resolve, int fastmip, SCIP_Bool tightprimfeastol, SCIP_Bool tightdualfeastol, SCIP_Bool fromscratch, int scaling, SCIP_Bool keepsol, SCIP_Bool *lperror)
Definition lp.c:12291
static int lpGetResolveItlim(SCIP_SET *set, SCIP_STAT *stat, int itlim)
Definition lp.c:12660
SCIP_RETCODE SCIPlpSolveAndEval(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_PROB *prob, SCIP_Longint itlim, SCIP_Bool limitresolveiters, SCIP_Bool aging, SCIP_Bool keepsol, SCIP_Bool forcedlpsolve, SCIP_Bool *lperror)
Definition lp.c:12680
SCIP_RETCODE SCIPcolGetStrongbranch(SCIP_COL *col, SCIP_Bool integral, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_LP *lp, int itlim, SCIP_Bool updatecol, SCIP_Bool updatestat, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Bool *lperror)
Definition lp.c:4494
static SCIP_RETCODE lpCheckRealpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Real value)
Definition lp.c:2753
SCIP_RETCODE SCIPcolDelCoef(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_ROW *row)
Definition lp.c:3663
static void rowMerge(SCIP_ROW *row, SCIP_SET *set)
Definition lp.c:6265
static void colMoveCoef(SCIP_COL *col, int oldpos, int newpos)
Definition lp.c:1397
static SCIP_Bool isIntegralScalar(SCIP_Real val, SCIP_Real scalar, SCIP_Real mindelta, SCIP_Real maxdelta, SCIP_Real *intval)
Definition lp.c:5099
SCIP_Real SCIPlpGetObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition lp.c:13436
static void computeLPBounds(SCIP_LP *lp, SCIP_SET *set, SCIP_COL *col, SCIP_Real lpiinf, SCIP_Real *lb, SCIP_Real *ub)
Definition lp.c:8216
SCIP_RETCODE SCIPlpCleanupAll(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_Bool root)
Definition lp.c:16270
void SCIProwRecalcLPActivity(SCIP_ROW *row, SCIP_STAT *stat)
Definition lp.c:6402
static SCIP_Bool isNewValueUnreliable(SCIP_SET *set, SCIP_Real newvalue, SCIP_Real oldvalue)
Definition lp.c:3839
static SCIP_RETCODE provedBound(SCIP_LP *lp, SCIP_SET *set, SCIP_Bool usefarkas, SCIP_Real *bound)
Definition lp.c:16765
SCIP_Real SCIProwGetMinval(SCIP_ROW *row, SCIP_SET *set)
Definition lp.c:6917
SCIP_RETCODE SCIPlpEndStrongbranch(SCIP_LP *lp)
Definition lp.c:4390
SCIP_Longint SCIPcolGetStrongbranchLPAge(SCIP_COL *col, SCIP_STAT *stat)
Definition lp.c:4932
static SCIP_RETCODE lpDelColset(SCIP_LP *lp, SCIP_SET *set, int *coldstat)
Definition lp.c:15682
static SCIP_RETCODE lpRemoveObsoleteCols(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, int firstcol)
Definition lp.c:15879
SCIP_Real SCIPlpGetRootObjval(SCIP_LP *lp)
Definition lp.c:18144
static SCIP_RETCODE rowScale(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_STAT *stat, SCIP_LP *lp, SCIP_Real scaleval, SCIP_Bool integralcontvars, SCIP_Real minrounddelta, SCIP_Real maxrounddelta)
Definition lp.c:5139
static SCIP_RETCODE ensureLazycolsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition lp.c:308
SCIP_Bool SCIPlpIsFeasGE(SCIP_SET *set, SCIP_LP *lp, SCIP_Real val1, SCIP_Real val2)
Definition lp.c:19288
static SCIP_RETCODE ignoreInstability(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_LPALGO lpalgo, SCIP_Bool *success)
Definition lp.c:11814
SCIP_RETCODE SCIPlpGetProvedLowerbound(SCIP_LP *lp, SCIP_SET *set, SCIP_Real *bound)
Definition lp.c:16875
static void checkLazyColArray(SCIP_LP *lp, SCIP_SET *set)
Definition lp.c:9830
SCIP_RETCODE SCIPcolChgObj(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newobj)
Definition lp.c:3893
static void colUpdateAddLP(SCIP_COL *col, SCIP_SET *set)
Definition lp.c:9109
SCIP_Real SCIProwGetLPSolCutoffDistance(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol, SCIP_LP *lp)
Definition lp.c:6997
static SCIP_RETCODE lpSetRandomseed(SCIP_LP *lp, int randomseed, SCIP_Bool *success)
Definition lp.c:3393
static SCIP_RETCODE rowRestoreSolVals(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_Longint validlp, SCIP_Bool freebuffer, SCIP_Bool infeasible)
Definition lp.c:588
static SCIP_RETCODE ensureChgrowsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition lp.c:196
SCIP_Real SCIProwGetSolActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition lp.c:6696
static SCIP_RETCODE lpSetScaling(SCIP_LP *lp, int scaling, SCIP_Bool *success)
Definition lp.c:3085
static SCIP_RETCODE colChgCoefPos(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, int pos, SCIP_Real val)
Definition lp.c:1994
SCIP_RETCODE SCIPlpFree(SCIP_LP **lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition lp.c:9619
static SCIP_RETCODE lpSetIntpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, int value, SCIP_Bool *success)
Definition lp.c:2650
void SCIPlpMarkDivingObjChanged(SCIP_LP *lp)
Definition lp.c:18271
SCIP_COL ** SCIPlpGetNewcols(SCIP_LP *lp)
Definition lp.c:18036
SCIP_RETCODE SCIPlpFreeNorms(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition lp.c:10427
static SCIP_RETCODE lpBarrier(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool crossover, SCIP_Bool keepsol, SCIP_Bool *lperror)
Definition lp.c:11532
SCIP_RETCODE SCIProwAddCoef(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_COL *col, SCIP_Real val)
Definition lp.c:5625
static void freeDiveChgSideArrays(SCIP_LP *lp)
Definition lp.c:9305
SCIP_RETCODE SCIPlpGetBInvARow(SCIP_LP *lp, int r, SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
Definition lp.c:10148
SCIP_LPI * SCIPlpGetLPI(SCIP_LP *lp)
Definition lp.c:18178
SCIP_Bool SCIPlpIsFeasLT(SCIP_SET *set, SCIP_LP *lp, SCIP_Real val1, SCIP_Real val2)
Definition lp.c:19228
static SCIP_RETCODE rowStoreSolVals(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_Bool infeasible)
Definition lp.c:551
SCIP_RETCODE SCIProwIncCoef(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_COL *col, SCIP_Real incval)
Definition lp.c:5744
static SCIP_RETCODE lpUpdateVarColumnProved(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition lp.c:14476
#define debugRowPrint(x, y)
Definition lp.c:131
SCIP_RETCODE SCIPlpRemoveRedundantRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition lp.c:16309
SCIP_Bool SCIPlpDiving(SCIP_LP *lp)
Definition lp.c:18251
static void rowUpdateDelLP(SCIP_ROW *row)
Definition lp.c:9223
void SCIPlpUnmarkDivingObjChanged(SCIP_LP *lp)
Definition lp.c:18282
SCIP_RETCODE SCIPlpGetBasisInd(SCIP_LP *lp, int *basisind)
Definition lp.c:10066
SCIP_Real SCIProwGetNLPEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition lp.c:7210
SCIP_RETCODE SCIPlpSetNorms(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPINORMS *lpinorms)
Definition lp.c:10407
SCIP_RETCODE SCIProwChgLocal(SCIP_ROW *row, SCIP_Bool local)
Definition lp.c:5946
SCIP_RETCODE SCIPlpComputeRelIntPoint(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_LP *lp, SCIP_PROB *prob, SCIP_Bool relaxrows, SCIP_Bool inclobjcutoff, SCIP_Real timelimit, int iterlimit, SCIP_Real *point, SCIP_Bool *success)
Definition lp.c:19007
#define DIVESTACKINITSIZE
Definition lp.c:9322
SCIP_RETCODE SCIPlpGetDualDegeneracy(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real *degeneracy, SCIP_Real *varconsratio)
Definition lp.c:19079
static SCIP_RETCODE lpSetBoolpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Bool value, SCIP_Bool *success)
Definition lp.c:2677
static SCIP_RETCODE ensureColsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition lp.c:265
static void rowCalcNorms(SCIP_ROW *row, SCIP_SET *set)
Definition lp.c:4964
SCIP_Real SCIProwGetLPEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition lp.c:7054
SCIP_RETCODE SCIPlpGetSol(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
Definition lp.c:14704
static void markRowDeleted(SCIP_ROW *row)
Definition lp.c:8409
void SCIProwRecalcNorms(SCIP_ROW *row, SCIP_SET *set)
Definition lp.c:6393
static void rowAddNorms(SCIP_ROW *row, SCIP_SET *set, SCIP_COL *col, SCIP_Real val, SCIP_Bool updateidxvals)
Definition lp.c:2039
static void lpUpdateObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real deltaval, int deltainf, SCIP_Bool local, SCIP_Bool loose, SCIP_Bool global)
Definition lp.c:13960
static const int nscalars
Definition lp.c:5960
void SCIPcolGetStrongbranchLast(SCIP_COL *col, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Real *solval, SCIP_Real *lpobjval)
Definition lp.c:4900
SCIP_RETCODE SCIPcolAddCoef(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_ROW *row, SCIP_Real val)
Definition lp.c:3642
static SCIP_RETCODE computeRelIntPoint(SCIP_LPI *lpi, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_LP *lp, SCIP_PROB *prob, SCIP_Bool relaxrows, SCIP_Bool inclobjcutoff, SCIP_Real timelimit, int iterlimit, SCIP_Real *point, SCIP_Bool *success)
Definition lp.c:18305
SCIP_RETCODE SCIPcolIncCoef(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_ROW *row, SCIP_Real incval)
Definition lp.c:3759
SCIP_Real SCIPlpGetRootLooseObjval(SCIP_LP *lp)
Definition lp.c:18168
SCIP_RETCODE SCIPlpGetDualfarkas(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool forcedlpsolve, SCIP_Bool *valid)
Definition lp.c:15406
void SCIProwPrint(SCIP_ROW *row, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition lp.c:5514
SCIP_RETCODE SCIPlpSetCutoffbound(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_Real cutoffbound)
Definition lp.c:10451
SCIP_RETCODE SCIPlpRecordOldRowSideDive(SCIP_LP *lp, SCIP_ROW *row, SCIP_SIDETYPE sidetype)
Definition lp.c:16675
static SCIP_RETCODE lpCleanupCols(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, int firstcol)
Definition lp.c:16093
SCIP_RETCODE SCIPlpMarkFlushed(SCIP_LP *lp, SCIP_SET *set)
Definition lp.c:8981
static SCIP_RETCODE lpAlgorithm(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_LPALGO lpalgo, SCIP_Bool resolve, SCIP_Bool keepsol, SCIP_Bool instable, SCIP_Bool *timelimit, SCIP_Bool *lperror)
Definition lp.c:11669
SCIP_Real SCIPcolGetFeasibility(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition lp.c:4171
#define checkRowSqrnorm(row)
Definition lp.c:775
SCIP_RETCODE SCIPlpShrinkRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int newnrows)
Definition lp.c:9955
SCIP_Bool SCIProwIsRedundant(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition lp.c:6870
void SCIPlpStartStrongbranchProbing(SCIP_LP *lp)
Definition lp.c:16729
static SCIP_RETCODE lpFlushDelCols(SCIP_LP *lp)
Definition lp.c:8165
static SCIP_RETCODE lpSetRowrepswitch(SCIP_LP *lp, SCIP_Real rowrepswitch, SCIP_Bool *success)
Definition lp.c:3160
SCIP_RETCODE SCIPlpGetIterations(SCIP_LP *lp, int *iterations)
Definition lp.c:15607
static void recomputeLooseObjectiveValue(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition lp.c:844
static void colUpdateDelLP(SCIP_COL *col, SCIP_SET *set)
Definition lp.c:9184
SCIP_RETCODE SCIProwChgConstant(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_Real constant)
Definition lp.c:5801
SCIP_RETCODE SCIPlpStartProbing(SCIP_LP *lp)
Definition lp.c:16699
SCIP_Real SCIPlpGetFeastol(SCIP_LP *lp)
Definition lp.c:10499
static SCIP_RETCODE lpSetFeastol(SCIP_LP *lp, SCIP_Real feastol, SCIP_Bool *success)
Definition lp.c:2899
SCIP_Bool SCIProwIsSolEfficacious(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol, SCIP_Bool root)
Definition lp.c:7154
static SCIP_RETCODE lpUpdateVarColumn(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition lp.c:14429
SCIP_RETCODE SCIPlpUpdateDelVar(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition lp.c:14405
void SCIPlpEndStrongbranchProbing(SCIP_LP *lp)
Definition lp.c:16742
SCIP_RETCODE SCIPlpGetBInvACol(SCIP_LP *lp, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition lp.c:10173
SCIP_Bool SCIPlpIsFeasZero(SCIP_LP *lp, SCIP_Real val)
Definition lp.c:19308
static SCIP_RETCODE lpSetThreads(SCIP_LP *lp, int threads, SCIP_Bool *success)
Definition lp.c:3110
SCIP_RETCODE SCIPlpRemoveAllObsoletes(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition lp.c:16062
static SCIP_RETCODE lpFlushChgCols(SCIP_LP *lp, SCIP_SET *set)
Definition lp.c:8622
static SCIP_RETCODE lpUpdateVarLooseProved(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition lp.c:14608
SCIP_RETCODE SCIProwCatchEvent(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition lp.c:8079
SCIP_RETCODE colLink(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition lp.c:2488
SCIP_RETCODE SCIProwFree(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
Definition lp.c:5464
static SCIP_Real getFiniteLooseObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition lp.c:1034
SCIP_Real SCIPcolGetFarkasValue(SCIP_COL *col, SCIP_STAT *stat, SCIP_LP *lp)
Definition lp.c:4356
static SCIP_RETCODE lpDualSimplex(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool resolve, SCIP_Bool keepsol, SCIP_Bool instable, SCIP_Bool *lperror)
Definition lp.c:10732
static const char * lpalgoName(SCIP_LPALGO lpalgo)
Definition lp.c:10551
static void coefChanged(SCIP_ROW *row, SCIP_COL *col, SCIP_LP *lp)
Definition lp.c:1762
static SCIP_RETCODE lpUpdateVarLoose(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition lp.c:14563
static void getObjvalDeltaUb(SCIP_SET *set, SCIP_Real obj, SCIP_Real oldub, SCIP_Real newub, SCIP_Real *deltaval, int *deltainf)
Definition lp.c:13922
static SCIP_RETCODE lpRestoreSolVals(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_Longint validlp)
Definition lp.c:416
static SCIP_RETCODE rowSideChanged(SCIP_ROW *row, SCIP_SET *set, SCIP_LP *lp, SCIP_SIDETYPE sidetype)
Definition lp.c:2436
static void rowSortLP(SCIP_ROW *row)
Definition lp.c:1162
static SCIP_Real colCalcInternalFarkasCoef(SCIP_COL *col)
Definition lp.c:4277
SCIP_RETCODE colUnlink(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition lp.c:2531
SCIP_RETCODE SCIPlpCreate(SCIP_LP **lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, const char *name)
Definition lp.c:9325
SCIP_Bool SCIPlpDivingRowsChanged(SCIP_LP *lp)
Definition lp.c:18293
SCIP_RETCODE SCIPlpUpdateVarUbGlobal(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub)
Definition lp.c:14305
static SCIP_RETCODE lpFlushAndSolve(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_EVENTQUEUE *eventqueue, int resolveitlim, int harditlim, SCIP_Bool needprimalray, SCIP_Bool needdualray, int fastmip, SCIP_Bool tightprimfeastol, SCIP_Bool tightdualfeastol, SCIP_Bool fromscratch, int scaling, SCIP_Bool keepsol, SCIP_Bool *lperror)
Definition lp.c:12480
SCIP_RETCODE SCIPlpReset(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PROB *prob, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition lp.c:9664
static void recomputeSafeLooseObjectiveValue(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition lp.c:789
static SCIP_RETCODE lpCheckBoolpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Bool value)
Definition lp.c:2742
SCIP_Real SCIPcolGetRedcost(SCIP_COL *col, SCIP_STAT *stat, SCIP_LP *lp)
Definition lp.c:4147
SCIP_RETCODE SCIPlpEndProbing(SCIP_LP *lp)
Definition lp.c:16714
SCIP_RETCODE SCIProwDropEvent(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
Definition lp.c:8103
static SCIP_RETCODE colAddCoef(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_ROW *row, SCIP_Real val, int linkpos)
Definition lp.c:1827
static SCIP_Real lpGetModifiedPseudoObjvalExact(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound, SCIP_BOUNDTYPE boundtype)
Definition lp.c:13652
SCIP_RETCODE SCIPcolCreate(SCIP_COL **col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var, int len, SCIP_ROW **rows, SCIP_Real *vals, SCIP_Bool removable)
Definition lp.c:3473
SCIP_Bool SCIPlpIsRootLPRelax(SCIP_LP *lp)
Definition lp.c:18134
SCIP_Bool SCIPlpIsSolved(SCIP_LP *lp)
Definition lp.c:18211
SCIP_RETCODE SCIPlpUpdateVarUb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub)
Definition lp.c:14343
static SCIP_RETCODE lpSetConditionLimit(SCIP_LP *lp, SCIP_Real condlimit, SCIP_Bool *success)
Definition lp.c:3309
SCIP_RETCODE SCIPlpUpdateVarObj(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
Definition lp.c:14166
static void lpNumericalTroubleMessage(SCIP_MESSAGEHDLR *messagehdlr, SCIP_SET *set, SCIP_STAT *stat, SCIP_VERBLEVEL verblevel, const char *formatstr,...)
Definition lp.c:11761
SCIP_Real SCIPcolGetFarkasCoef(SCIP_COL *col, SCIP_STAT *stat, SCIP_LP *lp)
Definition lp.c:4330
SCIP_RETCODE SCIPlpUpdateVarLoose(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition lp.c:14665
SCIP_Real SCIPlpGetGlobalPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition lp.c:13587
static SCIP_RETCODE reallocDiveChgSideArrays(SCIP_LP *lp, int minsize, SCIP_Real growfact)
Definition lp.c:9279
SCIP_Bool SCIPlpIsDualReliable(SCIP_LP *lp)
Definition lp.c:18231
SCIP_RETCODE SCIPlpAddRow(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_ROW *row, int depth)
Definition lp.c:9759
SCIP_RETCODE SCIPlpWriteMip(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, const char *fname, SCIP_Bool genericnames, SCIP_Bool origobj, SCIP_OBJSENSE objsense, SCIP_Real objscale, SCIP_Real objoffset, SCIP_Bool lazyconss)
Definition lp.c:16925
static void getObjvalDeltaLb(SCIP_SET *set, SCIP_Real obj, SCIP_Real oldlb, SCIP_Real newlb, SCIP_Real *deltaval, int *deltainf)
Definition lp.c:13884
int SCIProwGetMinidx(SCIP_ROW *row, SCIP_SET *set)
Definition lp.c:6949
static SCIP_Real colCalcInternalRedcost(SCIP_COL *col)
Definition lp.c:4094
static void recomputeSafePseudoObjectiveValue(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition lp.c:895
SCIP_RETCODE SCIPlpStartDive(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat)
Definition lp.c:16383
SCIP_Bool SCIPlpIsFeasNegative(SCIP_LP *lp, SCIP_Real val)
Definition lp.c:19330
SCIP_RETCODE SCIPlpEndDive(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_PROB *prob, SCIP_VAR **vars, int nvars)
Definition lp.c:16489
SCIP_COL ** SCIPlpGetCols(SCIP_LP *lp)
Definition lp.c:17969
int SCIPlpGetNCols(SCIP_LP *lp)
Definition lp.c:17979
static SCIP_RETCODE lpSetBarrierconvtol(SCIP_LP *lp, SCIP_Real barrierconvtol, SCIP_Bool *success)
Definition lp.c:2985
SCIP_RETCODE SCIProwChgRhs(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_Real rhs)
Definition lp.c:5914
SCIP_Real SCIPlpGetRootColumnObjval(SCIP_LP *lp)
Definition lp.c:18156
static SCIP_RETCODE rowEventSideChanged(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_SIDETYPE side, SCIP_Real oldval, SCIP_Real newval)
Definition lp.c:1653
SCIP_RETCODE SCIPlpGetUnboundedSol(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *primalfeasible, SCIP_Bool *rayfeasible)
Definition lp.c:15019
static SCIP_RETCODE lpSetDualfeastol(SCIP_LP *lp, SCIP_Real dualfeastol, SCIP_Bool *success)
Definition lp.c:2942
SCIP_RETCODE SCIProwCalcIntegralScalar(SCIP_ROW *row, SCIP_SET *set, SCIP_Real mindelta, SCIP_Real maxdelta, SCIP_Longint maxdnom, SCIP_Real maxscale, SCIP_Bool usecontvars, SCIP_Real *intscalar, SCIP_Bool *success)
Definition lp.c:5963
SCIP_Real SCIPlpGetCutoffbound(SCIP_LP *lp)
Definition lp.c:10441
SCIP_Bool SCIPlpIsFeasEQ(SCIP_SET *set, SCIP_LP *lp, SCIP_Real val1, SCIP_Real val2)
Definition lp.c:19208
static void markColDeleted(SCIP_COL *col)
Definition lp.c:8143
SCIP_Real SCIProwGetPseudoActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition lp.c:6652
static void checkLazyBounds(SCIP_LP *lp, SCIP_SET *set)
Definition lp.c:12571
static SCIP_RETCODE lpSetIterationLimit(SCIP_LP *lp, int itlim)
Definition lp.c:3185
static SCIP_RETCODE ensureRowsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition lp.c:331
static SCIP_Real getFinitePseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition lp.c:1056
static SCIP_RETCODE allocDiveChgSideArrays(SCIP_LP *lp, int initsize)
Definition lp.c:9257
SCIP_ROW ** SCIPlpGetRows(SCIP_LP *lp)
Definition lp.c:18016
void SCIPlpSetRootLPIsRelax(SCIP_LP *lp, SCIP_Bool isrelax)
Definition lp.c:18123
static SCIP_RETCODE ensureLpirowsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition lp.c:242
SCIP_RETCODE SCIProwChgLhs(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_Real lhs)
Definition lp.c:5882
void SCIProwForceSort(SCIP_ROW *row, SCIP_SET *set)
Definition lp.c:6380
void SCIPcolMarkNotRemovableLocal(SCIP_COL *col, SCIP_STAT *stat)
Definition lp.c:4944
static SCIP_RETCODE updateLazyBounds(SCIP_LP *lp, SCIP_SET *set)
Definition lp.c:12598
SCIP_RETCODE rowLink(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition lp.c:2569
int SCIPlpGetNUnfixedCols(SCIP_LP *lp, SCIP_Real eps)
Definition lp.c:17989
SCIP_Real SCIProwGetMinActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition lp.c:6828
#define checkRowObjprod(row)
Definition lp.c:777
static const SCIP_Real scalars[]
Definition lp.c:5959
void SCIPcolSetStrongbranchData(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_Real lpobjval, SCIP_Real primsol, SCIP_Real sbdown, SCIP_Real sbup, SCIP_Bool sbdownvalid, SCIP_Bool sbupvalid, SCIP_Longint iter, int itlim)
Definition lp.c:4405
SCIP_Bool SCIPlpIsFeasLE(SCIP_SET *set, SCIP_LP *lp, SCIP_Real val1, SCIP_Real val2)
Definition lp.c:19248
int SCIPlpGetNNewrows(SCIP_LP *lp)
Definition lp.c:18069
void SCIPlpResetFeastol(SCIP_LP *lp, SCIP_SET *set)
Definition lp.c:10534
SCIP_RETCODE SCIPlpGetPrimalRay(SCIP_LP *lp, SCIP_SET *set, SCIP_Real *ray)
Definition lp.c:15345
#define checkRow(row)
Definition lp.c:702
int SCIProwGetNumImpliedIntCols(SCIP_ROW *row, SCIP_SET *set)
Definition lp.c:6981
void SCIProwDelaySort(SCIP_ROW *row)
Definition lp.c:6369
static SCIP_RETCODE lpSetSolutionPolishing(SCIP_LP *lp, SCIP_Bool polishing, SCIP_Bool *success)
Definition lp.c:3423
void SCIPlpInvalidateRootObjval(SCIP_LP *lp)
Definition lp.c:13508
int SCIPlpGetNRows(SCIP_LP *lp)
Definition lp.c:18026
static SCIP_RETCODE lpFlushChgRows(SCIP_LP *lp, SCIP_SET *set)
Definition lp.c:8770
static SCIP_RETCODE lpPrimalSimplex(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool resolve, SCIP_Bool keepsol, SCIP_Bool instable, SCIP_Bool *lperror)
Definition lp.c:10574
SCIP_Real SCIProwGetObjParallelism(SCIP_ROW *row, SCIP_SET *set, SCIP_LP *lp)
Definition lp.c:8046
static void recomputeGlbPseudoObjectiveValue(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition lp.c:994
SCIP_RETCODE SCIPlpSumRows(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_Real *weights, SCIP_REALARRAY *sumcoef, SCIP_Real *sumlhs, SCIP_Real *sumrhs)
Definition lp.c:10197
SCIP_RETCODE SCIPcolGetStrongbranches(SCIP_COL **cols, int ncols, SCIP_Bool integral, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_LP *lp, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Bool *lperror)
Definition lp.c:4677
static SCIP_RETCODE lpCleanupRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int firstrow)
Definition lp.c:16160
SCIP_Real SCIPlpGetPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition lp.c:13619
static SCIP_RETCODE lpDelRowset(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int *rowdstat)
Definition lp.c:15781
void SCIPlpSetSizeMark(SCIP_LP *lp, int nrows, int ncols)
Definition lp.c:10052
static int SCIProwGetDiscreteScalarProduct(SCIP_ROW *row1, SCIP_ROW *row2)
Definition lp.c:7611
SCIP_RETCODE SCIPlpUpdateVarColumn(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition lp.c:14541
SCIP_RETCODE SCIProwRelease(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
Definition lp.c:5567
#define checkLinks(lp)
Definition lp.c:1753
static SCIP_RETCODE lpFlushAddCols(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
Definition lp.c:8251
void SCIPcolPrint(SCIP_COL *col, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition lp.c:3602
internal methods for LP management
SCIP_RETCODE SCIProwExactRelease(SCIP_ROWEXACT **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LPEXACT *lpexact)
Definition lpexact.c:5583
SCIP_Bool SCIPlpExactDiving(SCIP_LPEXACT *lpexact)
Definition lpexact.c:8423
SCIP_RETCODE SCIPlpExactSetCutoffbound(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_Real cutoffbound)
Definition lpexact.c:4178
void SCIPlpExactForceSafeBound(SCIP_LPEXACT *lpexact, SCIP_SET *set)
Definition lpexact.c:7614
SCIP_RETCODE SCIPlpExactComputeSafeBound(SCIP_LP *lp, SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_PROB *prob, SCIP_Bool *lperror, SCIP_Bool usefarkas, SCIP_Real *safebound, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
safe exact rational bounding methods
interface methods for specific LP solvers
interface methods for specific exact LP solvers
#define BMSduplicateBlockMemoryArray(mem, ptr, source, num)
Definition memory.h:462
#define BMSfreeMemory(ptr)
Definition memory.h:145
#define BMSfreeBlockMemory(mem, ptr)
Definition memory.h:465
#define BMSallocBlockMemory(mem, ptr)
Definition memory.h:451
#define BMSreallocMemoryArray(ptr, num)
Definition memory.h:127
#define BMSfreeBlockMemoryArrayNull(mem, ptr, num)
Definition memory.h:468
#define BMSfreeMemoryNull(ptr)
Definition memory.h:146
#define BMSallocMemoryArray(ptr, num)
Definition memory.h:123
#define BMSallocBlockMemoryArray(mem, ptr, num)
Definition memory.h:454
#define BMSfreeBlockMemoryNull(mem, ptr)
Definition memory.h:466
#define BMSfreeBlockMemoryArray(mem, ptr, num)
Definition memory.h:467
#define BMSreallocBlockMemoryArray(mem, ptr, oldnum, newnum)
Definition memory.h:458
#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
void SCIPmessageFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr,...)
Definition message.c:618
void SCIPmessageVFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr, va_list ap)
Definition message.c:633
void SCIPmessagePrintInfo(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition message.c:594
void SCIPmessagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition message.c:427
void SCIPmessagePrintVerbInfo(SCIP_MESSAGEHDLR *messagehdlr, SCIP_VERBLEVEL verblevel, SCIP_VERBLEVEL msgverblevel, const char *formatstr,...)
Definition message.c:678
SCIP_RETCODE SCIPrealarrayExtend(SCIP_REALARRAY *realarray, int arraygrowinit, SCIP_Real arraygrowfac, int minidx, int maxidx)
Definition misc.c:4131
SCIP_RETCODE SCIPrealarrayIncVal(SCIP_REALARRAY *realarray, int arraygrowinit, SCIP_Real arraygrowfac, int idx, SCIP_Real incval)
Definition misc.c:4407
SCIP_RETCODE SCIPrealarrayClear(SCIP_REALARRAY *realarray)
Definition misc.c:4286
internal miscellaneous methods
real eps
SCIP_Bool SCIPprobAllColsInLP(SCIP_PROB *prob, SCIP_SET *set, SCIP_LP *lp)
Definition prob.c:2825
internal methods for storing and manipulating the main problem
public methods for LP management
public methods for LP management
public methods for message output
#define SCIPerrorMessage
Definition pub_message.h:64
#define SCIPdebug(x)
Definition pub_message.h:93
#define SCIPdebugMessage
Definition pub_message.h:96
public data structures and miscellaneous methods
#define SCIPisFinite(x)
Definition pub_misc.h:82
methods for sorting joint arrays of various types
public methods for problem variables
SCIP_Bool SCIPsetIsDualfeasZero(SCIP_SET *set, SCIP_Real val)
Definition set.c:7292
SCIP_Bool SCIPsetIsEfficacious(SCIP_SET *set, SCIP_Bool root, SCIP_Real efficacy)
Definition set.c:7447
SCIP_Bool SCIPsetIsFeasPositive(SCIP_SET *set, SCIP_Real val)
Definition set.c:7076
SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6617
SCIP_RETCODE SCIPsetGetCharParam(SCIP_SET *set, const char *name, char *value)
Definition set.c:3424
SCIP_Real SCIPsetSumFloor(SCIP_SET *set, SCIP_Real val)
Definition set.c:6897
SCIP_Bool SCIPsetIsFeasNegative(SCIP_SET *set, SCIP_Real val)
Definition set.c:7087
SCIP_Real SCIPsetFeastol(SCIP_SET *set)
Definition set.c:6422
SCIP_Bool SCIPsetIsDualfeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:7196
SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:7017
SCIP_Bool SCIPsetIsFeasLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6993
SCIP_Bool SCIPsetIsFeasEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6945
SCIP_Bool SCIPsetIsPositive(SCIP_SET *set, SCIP_Real val)
Definition set.c:6648
SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6577
SCIP_Real SCIPsetRelaxfeastol(SCIP_SET *set)
Definition set.c:6494
SCIP_Bool SCIPsetIsSumLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6804
SCIP_Bool SCIPsetIsDualfeasNegative(SCIP_SET *set, SCIP_Real val)
Definition set.c:7314
SCIP_Real SCIPsetDualfeastol(SCIP_SET *set)
Definition set.c:6432
SCIP_Bool SCIPsetIsSumGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6844
SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6537
SCIP_Bool SCIPsetIsFeasZero(SCIP_SET *set, SCIP_Real val)
Definition set.c:7065
SCIP_Bool SCIPsetIsFeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6969
SCIP_RETCODE SCIPsetSetCharParam(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, const char *name, char value)
Definition set.c:3669
SCIP_Real SCIPsetLPFeastolFactor(SCIP_SET *set)
Definition set.c:6442
SCIP_Real SCIPsetInfinity(SCIP_SET *set)
Definition set.c:6380
SCIP_Real SCIPsetSumepsilon(SCIP_SET *set)
Definition set.c:6412
SCIP_Bool SCIPsetIsLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6557
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition set.c:6515
SCIP_Bool SCIPsetIsSumZero(SCIP_SET *set, SCIP_Real val)
Definition set.c:6864
SCIP_Bool SCIPsetIsRelGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:7559
SCIP_Bool SCIPsetIsDualfeasPositive(SCIP_SET *set, SCIP_Real val)
Definition set.c:7303
SCIP_Bool SCIPsetIsDualfeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:7244
SCIP_Bool SCIPsetIsGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6597
SCIP_Bool SCIPsetIsSumEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6764
SCIP_Bool SCIPsetIsIntegral(SCIP_SET *set, SCIP_Real val)
Definition set.c:6670
SCIP_Bool SCIPsetIsZero(SCIP_SET *set, SCIP_Real val)
Definition set.c:6637
SCIP_Bool SCIPsetIsUpdateUnreliable(SCIP_SET *set, SCIP_Real newvalue, SCIP_Real oldvalue)
Definition set.c:7723
SCIP_Real SCIPsetSumCeil(SCIP_SET *set, SCIP_Real val)
Definition set.c:6909
SCIP_Bool SCIPsetIsFeasGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:7041
SCIP_Real SCIPsetBarrierconvtol(SCIP_SET *set)
Definition set.c:6450
SCIP_Real SCIPsetRound(SCIP_SET *set, SCIP_Real val)
Definition set.c:6740
int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
Definition set.c:6080
SCIP_Bool SCIPsetIsFeasIntegral(SCIP_SET *set, SCIP_Real val)
Definition set.c:7098
SCIP_Bool SCIPsetIsNegative(SCIP_SET *set, SCIP_Real val)
Definition set.c:6659
unsigned int SCIPsetInitializeRandomSeed(SCIP_SET *set, unsigned int initialseedvalue)
Definition set.c:7800
internal methods for global SCIP settings
#define SCIPsetFreeBufferArray(set, ptr)
Definition set.h:1782
#define SCIPsetDebugMsgPrint
Definition set.h:1812
#define SCIPsetAllocBufferArray(set, ptr, num)
Definition set.h:1775
#define SCIPsetDebugMsg
Definition set.h:1811
SCIP_Real SCIPsolGetVal(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var)
Definition sol.c:1912
internal methods for storing primal CIP solutions
SCIP_Bool SCIPsolveIsStopped(SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool checknodelimits)
Definition solve.c:110
internal methods for main solving loop and node processing
internal methods for problem statistics
#define SCIPstatAdd(stat, set, field, val)
Definition stat.h:280
#define SCIPstatIncrement(stat, set, field)
Definition stat.h:260
#define SCIPstatUpdate(stat, set, field, val)
Definition stat.h:239
SCIP_Real primsol
Definition struct_lp.h:96
unsigned int basisstatus
Definition struct_lp.h:98
SCIP_Real redcost
Definition struct_lp.h:97
SCIP_Real lb
Definition struct_lp.h:140
SCIP_Real maxprimsol
Definition struct_lp.h:154
SCIP_Real ub
Definition struct_lp.h:141
unsigned int lbchanged
Definition struct_lp.h:185
SCIP_ROW ** rows
Definition struct_lp.h:163
unsigned int objchanged
Definition struct_lp.h:184
int lpdepth
Definition struct_lp.h:176
int nlprows
Definition struct_lp.h:172
SCIP_Real sbsolval
Definition struct_lp.h:157
SCIP_Real sbdown
Definition struct_lp.h:155
SCIP_Real sbup
Definition struct_lp.h:156
SCIP_Real lazylb
Definition struct_lp.h:143
SCIP_COLSOLVALS * storedsolvals
Definition struct_lp.h:161
unsigned int basisstatus
Definition struct_lp.h:181
SCIP_Real redcost
Definition struct_lp.h:151
SCIP_Real lazyub
Definition struct_lp.h:145
SCIP_Real minprimsol
Definition struct_lp.h:153
SCIP_Real sblpobjval
Definition struct_lp.h:158
SCIP_Real flushedobj
Definition struct_lp.h:147
unsigned int coefchanged
Definition struct_lp.h:187
SCIP_Real flushedlb
Definition struct_lp.h:148
unsigned int removable
Definition struct_lp.h:190
unsigned int impliedintegral
Definition struct_lp.h:189
SCIP_Real farkascoef
Definition struct_lp.h:152
unsigned int sbupvalid
Definition struct_lp.h:193
SCIP_Longint obsoletenode
Definition struct_lp.h:160
unsigned int lprowssorted
Definition struct_lp.h:182
SCIP_Longint validredcostlp
Definition struct_lp.h:165
int lppos
Definition struct_lp.h:174
SCIP_Real flushedub
Definition struct_lp.h:149
unsigned int nonlprowssorted
Definition struct_lp.h:183
int nsbcalls
Definition struct_lp.h:178
int * linkpos
Definition struct_lp.h:168
SCIP_Real * vals
Definition struct_lp.h:164
unsigned int ubchanged
Definition struct_lp.h:186
SCIP_Real primsol
Definition struct_lp.h:150
SCIP_Longint validfarkaslp
Definition struct_lp.h:166
int nunlinked
Definition struct_lp.h:173
int lpipos
Definition struct_lp.h:175
unsigned int integral
Definition struct_lp.h:188
SCIP_Longint validsblp
Definition struct_lp.h:167
int sbitlim
Definition struct_lp.h:177
SCIP_Longint sbnode
Definition struct_lp.h:159
SCIP_Real obj
Definition struct_lp.h:139
int index
Definition struct_lp.h:169
unsigned int sbdownvalid
Definition struct_lp.h:191
SCIP_Real unchangedobj
Definition struct_lp.h:142
SCIP_VAR * var
Definition struct_lp.h:162
int var_probindex
Definition struct_lp.h:180
SCIP_EVENTTYPE eventmask
SCIP_Bool wasforcedsafebound
SCIP_LPIEXACT * lpiexact
SCIP_Real oldcutoffbound
SCIP_Bool dualchecked
Definition struct_lp.h:124
SCIP_Bool solisbasic
Definition struct_lp.h:125
SCIP_Bool dualfeasible
Definition struct_lp.h:123
SCIP_Bool primalfeasible
Definition struct_lp.h:121
SCIP_Bool primalchecked
Definition struct_lp.h:122
SCIP_Real lpobjval
Definition struct_lp.h:120
SCIP_Bool lpissolved
Definition struct_lp.h:126
SCIP_Bool hasprovedboundexact
Definition struct_lp.h:127
SCIP_LPSOLSTAT lpsolstat
Definition struct_lp.h:119
SCIP_Bool glbpseudoobjvalid
Definition struct_lp.h:365
SCIP_Real * divechgsides
Definition struct_lp.h:312
SCIP_ROW ** rows
Definition struct_lp.h:308
SCIP_Real feastol
Definition struct_lp.h:290
SCIP_Real lpirowrepswitch
Definition struct_lp.h:403
SCIP_Real objsumnorm
Definition struct_lp.h:298
SCIP_Longint validsoldirlp
Definition struct_lp.h:319
SCIP_Real pseudoobjval
Definition struct_lp.h:284
SCIP_Real relglbpseudoobjval
Definition struct_lp.h:283
int glbpseudoobjvalinf
Definition struct_lp.h:345
SCIP_Real objsqrnorm
Definition struct_lp.h:297
SCIP_Bool flushaddedcols
Definition struct_lp.h:368
SCIP_ROW ** lpirows
Definition struct_lp.h:303
SCIP_SIDETYPE * divechgsidetypes
Definition struct_lp.h:313
int lpicolssize
Definition struct_lp.h:322
int lpiitlim
Definition struct_lp.h:351
SCIP_Bool strongbranching
Definition struct_lp.h:383
SCIP_Bool probing
Definition struct_lp.h:384
SCIP_Real rellooseobjval
Definition struct_lp.h:279
SCIP_Bool updateintegrality
Definition struct_lp.h:371
SCIP_Bool isrelax
Definition struct_lp.h:380
SCIP_Bool lpipresolving
Definition struct_lp.h:392
int lpirefactorinterval
Definition struct_lp.h:357
SCIP_Real varconsratio
Definition struct_lp.h:300
int lpifirstchgrow
Definition struct_lp.h:327
SCIP_Bool lpifromscratch
Definition struct_lp.h:391
SCIP_Bool objsqrnormunreliable
Definition struct_lp.h:361
SCIP_Bool primalfeasible
Definition struct_lp.h:374
SCIP_Real lpiconditionlimit
Definition struct_lp.h:295
SCIP_COL ** cols
Definition struct_lp.h:306
SCIP_LPALGO lastlpalgo
Definition struct_lp.h:360
int lpifirstchgcol
Definition struct_lp.h:324
int divinglpiitlim
Definition struct_lp.h:350
int nlazycols
Definition struct_lp.h:336
SCIP_Real rootlpobjval
Definition struct_lp.h:287
SCIP_Real * soldirection
Definition struct_lp.h:310
int rowssize
Definition struct_lp.h:339
int ncols
Definition struct_lp.h:334
SCIP_Real cutoffbound
Definition struct_lp.h:289
SCIP_Bool strongbranchprobing
Definition struct_lp.h:385
int nremovablerows
Definition struct_lp.h:341
SCIP_Real lpidualfeastol
Definition struct_lp.h:293
SCIP_Bool installing
Definition struct_lp.h:382
SCIP_Real rootlooseobjval
Definition struct_lp.h:288
SCIP_LPEXACT * lpexact
Definition struct_lp.h:309
SCIP_Bool dualfeasible
Definition struct_lp.h:376
int nchgrows
Definition struct_lp.h:331
int firstnewcol
Definition struct_lp.h:338
int lpithreads
Definition struct_lp.h:353
SCIP_Bool solisbasic
Definition struct_lp.h:378
SCIP_Bool divelpwasdualfeas
Definition struct_lp.h:407
SCIP_Bool rootlpisrelax
Definition struct_lp.h:379
SCIP_Bool lpisolutionpolishing
Definition struct_lp.h:363
SCIP_PRICING lpipricing
Definition struct_lp.h:358
SCIP_Real looseobjval
Definition struct_lp.h:277
SCIP_Bool divelpwasprimchecked
Definition struct_lp.h:406
SCIP_Bool flushaddedrows
Definition struct_lp.h:370
SCIP_COL ** chgcols
Definition struct_lp.h:304
int nrows
Definition struct_lp.h:340
SCIP_Bool primalchecked
Definition struct_lp.h:375
SCIP_LPSOLVALS * storedsolvals
Definition struct_lp.h:315
int lpiscaling
Definition struct_lp.h:356
int lpirandomseed
Definition struct_lp.h:355
int lpifastmip
Definition struct_lp.h:352
SCIP_LPISTATE * divelpistate
Definition struct_lp.h:311
SCIP_Real lpifeastol
Definition struct_lp.h:292
SCIP_Longint validsollp
Definition struct_lp.h:317
SCIP_Bool lpihasfastmip
Definition struct_lp.h:397
SCIP_SOL * validsoldirsol
Definition struct_lp.h:316
SCIP_Bool divingobjchg
Definition struct_lp.h:387
int ndivechgsides
Definition struct_lp.h:348
int lazycolssize
Definition struct_lp.h:335
SCIP_ROW ** chgrows
Definition struct_lp.h:305
SCIP_Real lpimarkowitz
Definition struct_lp.h:296
int firstnewrow
Definition struct_lp.h:342
int ndivingrows
Definition struct_lp.h:347
SCIP_Bool lpilpinfo
Definition struct_lp.h:393
SCIP_Real relpseudoobjval
Definition struct_lp.h:286
SCIP_LPSOLSTAT lpsolstat
Definition struct_lp.h:359
int colssize
Definition struct_lp.h:332
SCIP_Real lpibarrierconvtol
Definition struct_lp.h:294
SCIP_ROW ** divechgrows
Definition struct_lp.h:314
int nloosevars
Definition struct_lp.h:344
int chgrowssize
Definition struct_lp.h:330
SCIP_Longint validdegeneracylp
Definition struct_lp.h:320
int nlpicols
Definition struct_lp.h:323
SCIP_Real lpobjval
Definition struct_lp.h:276
int nlpirows
Definition struct_lp.h:326
int chgcolssize
Definition struct_lp.h:328
SCIP_Longint divenolddomchgs
Definition struct_lp.h:321
int pseudoobjvalinf
Definition struct_lp.h:346
SCIP_Bool solved
Definition struct_lp.h:373
SCIP_Bool divinglazyapplied
Definition struct_lp.h:388
int lpitiming
Definition struct_lp.h:354
SCIP_Bool resolvelperror
Definition struct_lp.h:389
SCIP_Bool dualchecked
Definition struct_lp.h:377
SCIP_Bool divelpwasdualchecked
Definition struct_lp.h:408
SCIP_Bool pseudoobjvalid
Definition struct_lp.h:366
int nchgcols
Definition struct_lp.h:329
SCIP_Longint validfarkaslp
Definition struct_lp.h:318
SCIP_Bool looseobjvalid
Definition struct_lp.h:364
SCIP_Bool adjustlpval
Definition struct_lp.h:390
SCIP_Bool diving
Definition struct_lp.h:386
SCIP_Bool hasprovedbound
Definition struct_lp.h:409
SCIP_Real glbpseudoobjval
Definition struct_lp.h:281
int divechgsidessize
Definition struct_lp.h:349
SCIP_Bool lpihaspolishing
Definition struct_lp.h:401
SCIP_COL ** lpicols
Definition struct_lp.h:302
int lpirowssize
Definition struct_lp.h:325
int nremovablecols
Definition struct_lp.h:337
SCIP_LPI * lpi
Definition struct_lp.h:301
SCIP_Bool flushdeletedrows
Definition struct_lp.h:369
int looseobjvalinf
Definition struct_lp.h:343
int soldirectionsize
Definition struct_lp.h:333
SCIP_COL ** lazycols
Definition struct_lp.h:307
SCIP_Real degeneracy
Definition struct_lp.h:299
SCIP_Bool flushed
Definition struct_lp.h:372
SCIP_Bool divelpwasprimfeas
Definition struct_lp.h:405
SCIP_Real lpiobjlim
Definition struct_lp.h:291
SCIP_Bool flushdeletedcols
Definition struct_lp.h:367
SCIP_VAR ** vars
Definition struct_prob.h:67
SCIP_ROW * fprow
SCIP_Real activity
Definition struct_lp.h:109
unsigned int basisstatus
Definition struct_lp.h:110
SCIP_Real dualsol
Definition struct_lp.h:108
SCIP_Longint nlpsaftercreation
Definition struct_lp.h:226
unsigned int basisstatus
Definition struct_lp.h:255
int nlpcols
Definition struct_lp.h:240
SCIP_Real minactivity
Definition struct_lp.h:220
SCIP_Longint activeinlpcounter
Definition struct_lp.h:225
unsigned int lpcolssorted
Definition struct_lp.h:256
unsigned int inglobalcutpool
Definition struct_lp.h:267
SCIP_Real rhs
Definition struct_lp.h:208
SCIP_Real maxactivity
Definition struct_lp.h:221
int nunlinked
Definition struct_lp.h:241
SCIP_Real dualfarkas
Definition struct_lp.h:218
int lppos
Definition struct_lp.h:243
SCIP_Longint obsoletenode
Definition struct_lp.h:224
unsigned int delaysort
Definition struct_lp.h:258
SCIP_Real flushedrhs
Definition struct_lp.h:210
int index
Definition struct_lp.h:237
unsigned int lhschanged
Definition struct_lp.h:260
unsigned int nonlpcolssorted
Definition struct_lp.h:257
char * name
Definition struct_lp.h:229
unsigned int origintype
Definition struct_lp.h:270
SCIP_Real * vals
Definition struct_lp.h:232
unsigned int validminmaxidx
Definition struct_lp.h:259
unsigned int removable
Definition struct_lp.h:266
int numintcols
Definition struct_lp.h:248
unsigned int local
Definition struct_lp.h:264
SCIP_Real maxval
Definition struct_lp.h:214
SCIP_Longint validpsactivitydomchg
Definition struct_lp.h:222
SCIP_Real flushedlhs
Definition struct_lp.h:209
int numminval
Definition struct_lp.h:251
SCIP_Longint validactivitybdsdomchg
Definition struct_lp.h:223
SCIP_Real lhs
Definition struct_lp.h:207
int lpipos
Definition struct_lp.h:244
int maxidx
Definition struct_lp.h:247
int * linkpos
Definition struct_lp.h:233
SCIP_Real sqrnorm
Definition struct_lp.h:211
SCIP_COL ** cols
Definition struct_lp.h:230
SCIP_ROWEXACT * rowexact
Definition struct_lp.h:235
SCIP_Real objprod
Definition struct_lp.h:213
unsigned int integral
Definition struct_lp.h:263
int nummaxval
Definition struct_lp.h:250
void * origin
Definition struct_lp.h:228
SCIP_Real constant
Definition struct_lp.h:206
SCIP_ROWSOLVALS * storedsolvals
Definition struct_lp.h:227
unsigned int coefchanged
Definition struct_lp.h:262
SCIP_Real activity
Definition struct_lp.h:217
SCIP_EVENTFILTER * eventfilter
Definition struct_lp.h:234
SCIP_Real minval
Definition struct_lp.h:215
SCIP_Real pseudoactivity
Definition struct_lp.h:219
SCIP_Real sumnorm
Definition struct_lp.h:212
int * cols_index
Definition struct_lp.h:231
int minidx
Definition struct_lp.h:246
unsigned int rhschanged
Definition struct_lp.h:261
SCIP_Real dualsol
Definition struct_lp.h:216
int lpdepth
Definition struct_lp.h:245
unsigned int modifiable
Definition struct_lp.h:265
unsigned int nlocks
Definition struct_lp.h:269
SCIP_Longint validactivitylp
Definition struct_lp.h:236
int nuses
Definition struct_lp.h:242
int numimplintcols
Definition struct_lp.h:249
SCIP_STATUS status
SCIP_Longint ndualresolvelpiterations
Definition struct_stat.h:72
SCIP_Longint nprimalresolvelpiterations
Definition struct_stat.h:71
SCIP_Longint nprimallps
SCIP_Real boundingerrorps
SCIP_Longint nnodes
Definition struct_stat.h:84
SCIP_Longint nboundshift
SCIP_CLOCK * strongbranchtime
SCIP_CLOCK * barrierlptime
SCIP_Longint nduallps
SCIP_Longint nduallpiterations
Definition struct_stat.h:68
int nclockskipsleft
SCIP_Longint nlps
SCIP_Longint ndualresolvelps
SCIP_Longint domchgcount
SCIP_CLOCK * divinglptime
SCIP_Longint lpcount
SCIP_Longint nlpiterations
Definition struct_stat.h:64
SCIP_Longint nprimalresolvelps
SCIP_Longint nrootlpiterations
Definition struct_stat.h:65
SCIP_Longint nnumtroublelpmsgs
SCIP_CLOCK * resolveinstablelptime
SCIP_Longint nexlp
SCIP_Real boundingerrorbs
SCIP_CLOCK * duallptime
SCIP_Longint nprojshift
SCIP_Longint ndivinglps
SCIP_Longint nrootlps
SCIP_Real boundingerrorexlp
SCIP_CLOCK * primallptime
SCIP_Longint nprimallpiterations
Definition struct_stat.h:67
SCIP_CLOCK * solvingtime
SCIP_Longint nbarrierlps
SCIP_Bool userinterrupt
SCIP_CLOCK * lexduallptime
char * name
Definition struct_var.h:291
datastructures for managing events
data structures for LP management
data structures for exact LP management
datastructures for storing and manipulating the main problem
SCIP main data structure.
datastructures for global SCIP settings
datastructures for problem statistics
datastructures for problem variables
enum SCIP_ClockType SCIP_CLOCKTYPE
Definition type_clock.h:47
@ SCIP_CLOCKTYPE_WALL
Definition type_clock.h:45
@ SCIP_CLOCKTYPE_CPU
Definition type_clock.h:44
struct SCIP_Cons SCIP_CONS
Definition type_cons.h:63
struct SCIP_Conshdlr SCIP_CONSHDLR
Definition type_cons.h:62
struct SCIP_Eventhdlr SCIP_EVENTHDLR
Definition type_event.h:159
#define SCIP_EVENTTYPE_ROWSIDECHANGED
Definition type_event.h:115
#define SCIP_EVENTTYPE_ROWADDEDLP
Definition type_event.h:111
struct SCIP_EventData SCIP_EVENTDATA
Definition type_event.h:179
struct SCIP_EventFilter SCIP_EVENTFILTER
Definition type_event.h:180
#define SCIP_EVENTTYPE_ROWCHANGED
Definition type_event.h:153
struct SCIP_EventQueue SCIP_EVENTQUEUE
Definition type_event.h:181
#define SCIP_EVENTTYPE_FORMAT
Definition type_event.h:157
#define SCIP_EVENTTYPE_ROWDELETEDLP
Definition type_event.h:112
uint64_t SCIP_EVENTTYPE
Definition type_event.h:156
#define SCIP_EVENTTYPE_ROWCOEFCHANGED
Definition type_event.h:113
struct SCIP_Event SCIP_EVENT
Definition type_event.h:161
#define SCIP_EVENTTYPE_ROWCONSTCHANGED
Definition type_event.h:114
struct SCIP_Row SCIP_ROW
Definition type_lp.h:105
enum SCIP_RowOriginType SCIP_ROWORIGINTYPE
Definition type_lp.h:79
@ SCIP_LPALGO_BARRIER
Definition type_lp.h:86
@ SCIP_LPALGO_PRIMALSIMPLEX
Definition type_lp.h:84
@ SCIP_LPALGO_BARRIERCROSSOVER
Definition type_lp.h:87
@ SCIP_LPALGO_DUALSIMPLEX
Definition type_lp.h:85
struct SCIP_Lp SCIP_LP
Definition type_lp.h:111
enum SCIP_LPSolStat SCIP_LPSOLSTAT
Definition type_lp.h:52
@ SCIP_ROWORIGINTYPE_CONSHDLR
Definition type_lp.h:74
@ SCIP_ROWORIGINTYPE_SEPA
Definition type_lp.h:76
@ SCIP_ROWORIGINTYPE_CONS
Definition type_lp.h:75
@ SCIP_BOUNDTYPE_UPPER
Definition type_lp.h:58
@ SCIP_BOUNDTYPE_LOWER
Definition type_lp.h:57
struct SCIP_Col SCIP_COL
Definition type_lp.h:99
struct SCIP_LpSolVals SCIP_LPSOLVALS
Definition type_lp.h:93
struct SCIP_ColSolVals SCIP_COLSOLVALS
Definition type_lp.h:91
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition type_lp.h:60
@ SCIP_SIDETYPE_RIGHT
Definition type_lp.h:66
@ SCIP_SIDETYPE_LEFT
Definition type_lp.h:65
struct SCIP_RowSolVals SCIP_ROWSOLVALS
Definition type_lp.h:92
@ SCIP_LPSOLSTAT_ERROR
Definition type_lp.h:50
@ SCIP_LPSOLSTAT_NOTSOLVED
Definition type_lp.h:43
@ SCIP_LPSOLSTAT_OPTIMAL
Definition type_lp.h:44
@ SCIP_LPSOLSTAT_TIMELIMIT
Definition type_lp.h:49
@ SCIP_LPSOLSTAT_UNBOUNDEDRAY
Definition type_lp.h:46
@ SCIP_LPSOLSTAT_INFEASIBLE
Definition type_lp.h:45
@ SCIP_LPSOLSTAT_OBJLIMIT
Definition type_lp.h:47
@ SCIP_LPSOLSTAT_ITERLIMIT
Definition type_lp.h:48
enum SCIP_LPAlgo SCIP_LPALGO
Definition type_lp.h:89
enum SCIP_SideType SCIP_SIDETYPE
Definition type_lp.h:68
struct SCIP_RowExact SCIP_ROWEXACT
@ SCIP_PRICING_STEEPQSTART
Definition type_lpi.h:83
@ SCIP_PRICING_AUTO
Definition type_lpi.h:79
@ SCIP_PRICING_DEVEX
Definition type_lpi.h:84
@ SCIP_PRICING_STEEP
Definition type_lpi.h:82
@ SCIP_PRICING_FULL
Definition type_lpi.h:80
@ SCIP_PRICING_LPIDEFAULT
Definition type_lpi.h:78
@ SCIP_PRICING_PARTIAL
Definition type_lpi.h:81
enum SCIP_Pricing SCIP_PRICING
Definition type_lpi.h:86
enum SCIP_LPParam SCIP_LPPARAM
Definition type_lpi.h:73
struct SCIP_LPiState SCIP_LPISTATE
Definition type_lpi.h:107
struct SCIP_LPi SCIP_LPI
Definition type_lpi.h:106
struct SCIP_LPiNorms SCIP_LPINORMS
Definition type_lpi.h:108
@ SCIP_LPPAR_PRICING
Definition type_lpi.h:54
@ SCIP_LPPAR_REFACTOR
Definition type_lpi.h:71
@ SCIP_LPPAR_THREADS
Definition type_lpi.h:66
@ SCIP_LPPAR_LPINFO
Definition type_lpi.h:55
@ SCIP_LPPAR_POLISHING
Definition type_lpi.h:70
@ SCIP_LPPAR_SCALING
Definition type_lpi.h:52
@ SCIP_LPPAR_TIMING
Definition type_lpi.h:68
@ SCIP_LPPAR_LPTILIM
Definition type_lpi.h:61
@ SCIP_LPPAR_BARRIERCONVTOL
Definition type_lpi.h:58
@ SCIP_LPPAR_PRESOLVING
Definition type_lpi.h:53
@ SCIP_LPPAR_CONDITIONLIMIT
Definition type_lpi.h:67
@ SCIP_LPPAR_RANDOMSEED
Definition type_lpi.h:69
@ SCIP_LPPAR_FASTMIP
Definition type_lpi.h:51
@ SCIP_LPPAR_DUALFEASTOL
Definition type_lpi.h:57
@ SCIP_LPPAR_FROMSCRATCH
Definition type_lpi.h:50
@ SCIP_LPPAR_MARKOWITZ
Definition type_lpi.h:62
@ SCIP_LPPAR_FEASTOL
Definition type_lpi.h:56
@ SCIP_LPPAR_LPITLIM
Definition type_lpi.h:60
@ SCIP_LPPAR_ROWREPSWITCH
Definition type_lpi.h:63
@ SCIP_LPPAR_OBJLIM
Definition type_lpi.h:59
@ SCIP_BASESTAT_BASIC
Definition type_lpi.h:92
@ SCIP_BASESTAT_UPPER
Definition type_lpi.h:93
@ SCIP_BASESTAT_LOWER
Definition type_lpi.h:91
@ SCIP_BASESTAT_ZERO
Definition type_lpi.h:94
@ SCIP_OBJSEN_MAXIMIZE
Definition type_lpi.h:42
@ SCIP_OBJSEN_MINIMIZE
Definition type_lpi.h:43
enum SCIP_BaseStat SCIP_BASESTAT
Definition type_lpi.h:96
enum SCIP_VerbLevel SCIP_VERBLEVEL
struct SCIP_Messagehdlr SCIP_MESSAGEHDLR
@ SCIP_VERBLEVEL_NONE
@ SCIP_VERBLEVEL_HIGH
@ SCIP_VERBLEVEL_FULL
struct SCIP_RealArray SCIP_REALARRAY
Definition type_misc.h:115
#define SCIP_DECL_SORTPTRCOMP(x)
Definition type_misc.h:189
struct SCIP_Prob SCIP_PROB
Definition type_prob.h:52
@ SCIP_OBJSENSE_MINIMIZE
Definition type_prob.h:48
enum SCIP_Objsense SCIP_OBJSENSE
Definition type_prob.h:50
@ SCIP_FILECREATEERROR
@ SCIP_LPERROR
@ SCIP_INVALIDDATA
@ SCIP_PARAMETERUNKNOWN
@ SCIP_PARAMETERWRONGVAL
@ SCIP_ERROR
enum SCIP_Retcode SCIP_RETCODE
struct SCIP_Sepa SCIP_SEPA
Definition type_sepa.h:51
struct SCIP_Set SCIP_SET
Definition type_set.h:71
struct SCIP_Sol SCIP_SOL
Definition type_sol.h:57
@ SCIP_STATUS_TIMELIMIT
Definition type_stat.h:54
struct SCIP_Stat SCIP_STAT
Definition type_stat.h:66
struct SCIP_Var SCIP_VAR
Definition type_var.h:166
@ SCIP_VARSTATUS_COLUMN
Definition type_var.h:53
@ SCIP_VARSTATUS_LOOSE
Definition type_var.h:52
SCIP_Real SCIPvarGetRelaxSol(SCIP_VAR *var, SCIP_SET *set)
Definition var.c:19688
internal methods for problem variables