Scippy

SCIP

Solving Constraint Integer Programs

lpexact.c
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the program and library */
4/* SCIP --- Solving Constraint Integer Programs */
5/* */
6/* Copyright (c) 2002-2025 Zuse Institute Berlin (ZIB) */
7/* */
8/* Licensed under the Apache License, Version 2.0 (the "License"); */
9/* you may not use this file except in compliance with the License. */
10/* You may obtain a copy of the License at */
11/* */
12/* http://www.apache.org/licenses/LICENSE-2.0 */
13/* */
14/* Unless required by applicable law or agreed to in writing, software */
15/* distributed under the License is distributed on an "AS IS" BASIS, */
16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17/* See the License for the specific language governing permissions and */
18/* limitations under the License. */
19/* */
20/* You should have received a copy of the Apache-2.0 license */
21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22/* */
23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25/**@file lpexact.c
26 * @brief LP management methods and data structures for exact mirror of LP
27 * @author Leon Eifler
28 *
29 * In LP management, we have to distinguish between the current LP and the SCIP_LP
30 * stored in the LP solver. All LP methods affect the current LP only.
31 * Before solving the current LP with the LP solver or setting an LP state,
32 * the LP solvers data has to be updated to the current LP with a call to
33 * lpExactFlush().
34 */
35
36/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
37
38#include "lpi/lpi.h"
39#include "lpiexact/lpiexact.h"
40#include "scip/clock.h"
41#include "scip/cutpool.h"
42#include "scip/event.h"
43#include "scip/intervalarith.h"
44#include "scip/lp.h"
45#include "scip/lpexact.h"
46#include "scip/misc.h"
47#include "scip/prob.h"
48#include "scip/pub_cons.h"
49#include "scip/pub_lp.h"
50#include "scip/pub_lpexact.h"
51#include "scip/pub_message.h"
52#include "scip/pub_misc.h"
53#include "scip/pub_misc_sort.h"
54#include "scip/pub_var.h"
55#include "scip/pub_tree.h"
56#include "scip/rational.h"
57#include "scip/scip_lp.h"
58#include "scip/scip_lpexact.h"
59#include "scip/scip_message.h"
60#include "scip/set.h"
61#include "scip/sepastoreexact.h"
62#include "scip/sol.h"
63#include "scip/solve.h"
64#include "scip/stat.h"
65#include "scip/struct_event.h"
66#include "scip/struct_lpexact.h"
67#include "scip/struct_prob.h"
68#include "scip/struct_set.h"
69#include "scip/struct_stat.h"
70#include "scip/struct_var.h"
71#include "scip/struct_cutpool.h"
72#include "scip/var.h"
73#include <string.h>
74#include <inttypes.h>
75
76/** comparison method for sorting rows by non-decreasing index */
77SCIP_DECL_SORTPTRCOMP(SCIProwExactComp)
78{
79 assert(elem1 != NULL);
80 assert(elem2 != NULL);
81
82 assert(((SCIP_ROWEXACT*)elem1)->fprow != NULL);
83 assert(((SCIP_ROWEXACT*)elem2)->fprow != NULL);
84
85 if( ((SCIP_ROWEXACT*)elem1)->index < ((SCIP_ROWEXACT*)elem2)->index )
86 return -1;
87 else if( ((SCIP_ROWEXACT*)elem1)->index > ((SCIP_ROWEXACT*)elem2)->index )
88 return +1;
89 else
90 {
91 assert(SCIProwExactGetIndex(((SCIP_ROWEXACT*)elem1))
93 return 0;
94 }
95}
96
97#ifdef SCIP_DISABLED_CODE /* enable this to check links between columns and rows in LP data structure (for debugging, very slow!) */
98
99#ifdef NDEBUG
100#define ASSERT(x) do { if( !(x) ) abort(); } while( FALSE )
101#else
102#define ASSERT(x) assert(x)
103#endif
104
105static SCIP_Bool msgdisp_checklinks = FALSE;
106
107
108static
109void checkLinks(
110 SCIP_LPEXACT* lp /**< current LP data */
111 )
112{
113 SCIP_COLEXACT* col;
114 SCIP_ROWEXACT* row;
115 int i;
116 int j;
117
118 ASSERT(lp != NULL);
119
120 if( !msgdisp_checklinks )
121 {
122 printf("LP LINK CHECKING ACTIVATED! THIS IS VERY SLOW!\n");
123 msgdisp_checklinks = TRUE;
124 }
125
126 for( i = 0; i < lp->ncols; ++i )
127 {
128 col = lp->cols[i];
129 ASSERT(col != NULL);
130 ASSERT(!lp->flushed || col->lppos >= 0);
131 ASSERT(!lp->flushed || col->lppos >= 0);
132 ASSERT(col->nlprows <= col->len);
133 ASSERT(col->lppos == -1 || col->lppos >= lp->lpifirstchgcol || col->nunlinked == 0);
134
135 for( j = 0; j < col->len; ++j )
136 {
137 row = col->rows[j];
138 ASSERT(row != NULL);
139 ASSERT(!lp->flushed || col->lppos == -1 || col->linkpos[j] >= 0);
140 ASSERT(col->linkpos[j] == -1 || row->cols[col->linkpos[j]] == col);
141 ASSERT(col->linkpos[j] == -1 || SCIPrationalIsEQ(row->vals[col->linkpos[j]], col->vals[j]));
142 ASSERT((j < col->nlprows) == (col->linkpos[j] >= 0 && row->lppos >= 0));
143 }
144 }
145
146 for( i = 0; i < lp->nrows; ++i )
147 {
148 row = lp->rows[i];
149 ASSERT(row != NULL);
150 ASSERT(!lp->flushed || row->lppos >= 0);
151 ASSERT(!lp->flushed || row->lppos >= 0);
152 ASSERT(row->nlpcols <= row->len);
153 ASSERT(row->lppos == -1 || row->lppos >= lp->lpifirstchgrow || row->nunlinked == 0);
154
155 for( j = 0; j < row->len; ++j )
156 {
157 col = row->cols[j];
158 ASSERT(col != NULL);
159 ASSERT(!lp->flushed || row->lppos == -1 || row->linkpos[j] >= 0);
160 ASSERT(row->linkpos[j] == -1 || col->rows[row->linkpos[j]] == row);
161 ASSERT(row->linkpos[j] == -1 || SCIPrationalIsEQ(col->vals[row->linkpos[j]], row->vals[j]));
162 ASSERT((j < row->nlpcols) == (row->linkpos[j] >= 0 && col->lppos >= 0));
163 }
164 }
165}
166
167#undef ASSERT
168
169#else
170#define checkLinks(lp) /**/
171#endif
172
173#ifndef NDEBUG
174/** checks if the exact column and its fpcol are consistent */
175static
177 SCIP_COLEXACT* colexact, /**< exact column */
178 SCIP_SET* set /**< global SCIP settings */
179 )
180{
181 SCIP_COL* fpcol;
182
183 assert(colexact != NULL);
184
185 fpcol = colexact->fpcol;
186 assert(fpcol != NULL);
187
188 assert(colexact->var == fpcol->var);
189 assert(colexact->lpipos == fpcol->lpipos);
190 assert(colexact->index == fpcol->index);
191 assert(colexact->len >= fpcol->nlprows);
192
193 assert(SCIPrationalIsApproxEQReal(set, colexact->obj, fpcol->obj, SCIP_R_ROUND_NEAREST));
195 assert(SCIPrationalIsApproxEQReal(set, colexact->lb, fpcol->lb, SCIP_R_ROUND_DOWNWARDS) || (SCIPrationalIsNegInfinity(colexact->lb) && SCIPsetIsInfinity(set, -fpcol->lb)));
196 assert(SCIPrationalIsApproxEQReal(set, colexact->ub, fpcol->ub, SCIP_R_ROUND_UPWARDS) || (SCIPrationalIsInfinity(colexact->ub) && SCIPsetIsInfinity(set, fpcol->ub)));
197
198 return TRUE;
199}
200
201/** checks if the exact row and its fprow are consistent */
202static
204 SCIP_ROWEXACT* rowexact, /**< exact row */
205 SCIP_SET* set, /**< global SCIP settings */
206 SCIP_MESSAGEHDLR* msg /**< message handler for debug output */ /*lint !e204*/
207 ) /*lint --e{715}*/
208{
209 SCIP_ROW* fprow;
210 SCIP_Bool synced;
211
212 assert(rowexact != NULL);
213
214 fprow = rowexact->fprow;
215
216 assert(fprow != NULL);
217 assert(rowexact->len >= fprow->len);
218 assert(rowexact->lppos == rowexact->fprow->lppos);
219
220 synced = SCIPrationalIsGEReal(rowexact->lhs, fprow->lhs) || (SCIPrationalIsNegInfinity(rowexact->lhs) && SCIPsetIsInfinity(set, -fprow->lhs));
221 synced = synced && (SCIPrationalIsLEReal(rowexact->rhs, fprow->rhs) || (SCIPrationalIsInfinity(rowexact->rhs) && SCIPsetIsInfinity(set, fprow->rhs)));
222 synced = synced && (SCIPrationalIsApproxEQReal(set, rowexact->constant, fprow->constant, SCIP_R_ROUND_NEAREST) );
223
224 if( !synced )
225 {
226 SCIPdebug(SCIProwPrint(rowexact->fprow, msg, NULL));
227 SCIPdebug(SCIProwExactPrint(rowexact, msg, NULL));
228 SCIPABORT();
229 }
230
231 return TRUE;
232} /*lint !e715*/
233#endif
234
235/** checks if the exact lp and lp are consistent (same number of rows/cols, and all cols/rows in sync) */
236static
238 SCIP_LPEXACT* lpexact, /**< exact lp */
239 SCIP_SET* set, /**< global SCIP settings */
240 SCIP_MESSAGEHDLR* msg /**< message handler for debug output */
241 )
242{
243#ifndef NDEBUG
244 int i;
245 SCIP_LP* fplp;
246
247 assert(lpexact != NULL);
248
249 fplp = lpexact->fplp;
250 assert(fplp != NULL);
251
252 assert(lpexact->nrows == fplp->nrows);
253 for( i = 0; i < lpexact->nrows; i++)
254 {
255 assert(rowExactInSync(lpexact->rows[i], set, msg));
256 }
257
258 assert(lpexact->ncols == fplp->ncols);
259 for( i = 0; i < lpexact->ncols; i++)
260 {
261 assert(colExactInSync(lpexact->cols[i], set));
262 }
263#endif
264
265 return TRUE;
266}
267
268/** ensures that rows array can store at least num entries */
269static
271 SCIP_LPEXACT* lpexact, /**< current LP data */
272 SCIP_SET* set, /**< global SCIP settings */
273 int num /**< minimum number of entries to store */
274 )
275{
276 assert(lpexact->nrows <= lpexact->rowssize);
277
278 if( num > lpexact->rowssize )
279 {
280 int newsize;
281
282 newsize = SCIPsetCalcMemGrowSize(set, num);
283 SCIP_ALLOC( BMSreallocMemoryArray(&lpexact->rows, newsize) );
284 lpexact->rowssize = newsize;
285 }
286 assert(num <= lpexact->rowssize);
287
288 return SCIP_OKAY;
289}
290
291/** sorts column entries of linked rows currently in the LP such that lower row indices precede higher ones */
292static
294 SCIP_COLEXACT* col /**< column to be sorted */
295 )
296{
297 int i;
298
299 assert(col != NULL);
300
301 /* check, if column is already sorted in the LP part */
302 if( col->lprowssorted )
303 return;
304
305 /* sort coefficients */
306 SCIPsortPtrPtrInt((void**)col->rows, (void**)col->vals, col->linkpos, SCIProwExactComp, col->nlprows );
307
308 /* update links */
309 for( i = 0; i < col->nlprows; ++i )
310 {
311 if( col->linkpos[i] >= 0 )
312 {
313 assert(col->rows[i]->cols[col->linkpos[i]] == col);
314 assert(col->rows[i]->linkpos[col->linkpos[i]] >= 0);
315 col->rows[i]->linkpos[col->linkpos[i]] = i;
316 }
317 }
318
319 col->lprowssorted = TRUE;
320}
321
322/** sorts column entries of unlinked rows or rows currently not in the LP such that lower row indices precede higher
323 * ones
324 */
325static
327 SCIP_COLEXACT* col /**< column to be sorted */
328 )
329{
330 int i;
331
332 assert(col != NULL);
333
334 /* check, if column is already sorted in the non-LP part */
335 if( col->nonlprowssorted )
336 return;
337
338 /* sort coefficients */
339 SCIPsortPtrPtrInt((void**)(&(col->rows[col->nlprows])),
340 (void**)(&(col->vals[col->nlprows])),
341 &(col->linkpos[col->nlprows]), SCIProwExactComp,
342 col->len - col->nlprows);
343
344 /* update links */
345 for( i = col->nlprows; i < col->len; ++i )
346 {
347 if( col->linkpos[i] >= 0 )
348 {
349 assert(col->rows[i]->cols[col->linkpos[i]] == col);
350 assert(col->rows[i]->linkpos[col->linkpos[i]] >= 0);
351 col->rows[i]->linkpos[col->linkpos[i]] = i;
352 }
353 }
354
355 col->nonlprowssorted = TRUE;
356}
357
358/** sorts row entries of linked columns currently in the LP such that lower column indices precede higher ones */
359static
361 SCIP_ROWEXACT* row /**< row to be sorted */
362 )
363{
364 int i;
365
366 assert(row != NULL);
367
368 /* check, if row is already sorted in the LP part, or if the sorting should be delayed */
369 if( row->lpcolssorted || row->delaysort )
370 return;
371
372 /* sort coefficients */
373 SCIPsortIntIntPtrPtrInterval(row->cols_index, row->linkpos, (void**)row->cols,
374 (void**)row->vals, row->valsinterval, row->nlpcols);
375
376 /* update links */
377 for( i = 0; i < row->nlpcols; ++i )
378 {
379 if( row->linkpos[i] >= 0 )
380 {
381 assert(row->cols[i]->rows[row->linkpos[i]] == row);
382 assert(row->cols[i]->linkpos[row->linkpos[i]] >= 0);
383 row->cols[i]->linkpos[row->linkpos[i]] = i;
384 }
385 }
386
387 row->lpcolssorted = TRUE;
388}
389
390/** sorts row entries of unlinked columns or columns currently not in the LP such that lower column indices precede
391 * higher ones
392 */
393static
395 SCIP_ROWEXACT* row /**< row to be sorted */
396 )
397{
398 int i;
399
400 assert(row != NULL);
401
402 /* check, if row is already sorted in the non-LP part, or if the sorting should be delayed */
403 if( row->nonlpcolssorted || row->delaysort )
404 return;
405
406 /* sort coefficients */
408 (void**)(&(row->cols[row->nlpcols])), (void**)&(row->vals[row->nlpcols]), &(row->valsinterval[row->nlpcols]),
409 row->len - row->nlpcols);
410
411 /* update links */
412 for( i = row->nlpcols; i < row->len; ++i )
413 {
414 if( row->linkpos[i] >= 0 )
415 {
416 assert(row->cols[i]->rows[row->linkpos[i]] == row);
417 assert(row->cols[i]->linkpos[row->linkpos[i]] >= 0);
418 row->cols[i]->linkpos[row->linkpos[i]] = i;
419 }
420 }
421
422 row->nonlpcolssorted = TRUE;
423}
424
425/** ensures, that row array of column can store at least num entries */
426static
428 SCIP_COLEXACT* col, /**< LP column */
429 BMS_BLKMEM* blkmem, /**< block memory */
430 SCIP_SET* set, /**< global SCIP settings */
431 int num /**< minimum number of entries to store */
432 )
433{
434 assert(col != NULL);
435 assert(col->len <= col->size);
436
437 if( num > col->size )
438 {
439 int newsize;
440 int i;
441
442 /* realloc fpcol */
443 newsize = SCIPsetCalcMemGrowSize(set, num);
444 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &col->rows, col->size, newsize) );
445 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &col->vals, col->size, newsize) );
446 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &col->linkpos, col->size, newsize) );
447
448 /* realloc colexact */
449 for( i = col->size; i < newsize; ++i )
450 {
451 SCIP_CALL( SCIPrationalCreateBlock(blkmem, &col->vals[i]) );
452 }
453
454 col->size = newsize;
455 }
456 assert(num <= col->size);
457
458 return SCIP_OKAY;
459}
460
461/** ensures, that cols array can store at least num entries */
462static
464 SCIP_LPEXACT* lp, /**< current LP data */
465 SCIP_SET* set, /**< global SCIP settings */
466 int num /**< minimum number of entries to store */
467 )
468{
469 assert(lp->ncols <= lp->colssize);
470
471 if( num > lp->colssize )
472 {
473 int newsize;
474
475 newsize = SCIPsetCalcMemGrowSize(set, num);
476 SCIP_ALLOC( BMSreallocMemoryArray(&lp->cols, newsize) );
477 lp->colssize = newsize;
478 }
479 assert(num <= lp->colssize);
480
481 return SCIP_OKAY;
482}
483
484/** ensures, that chgcols array can store at least num entries */
485static
487 SCIP_LPEXACT* lp, /**< current LP data */
488 SCIP_SET* set, /**< global SCIP settings */
489 int num /**< minimum number of entries to store */
490 )
491{
492 assert(lp->nchgcols <= lp->chgcolssize);
493
494 if( num > lp->chgcolssize )
495 {
496 int newsize;
497
498 newsize = SCIPsetCalcMemGrowSize(set, num);
499 SCIP_ALLOC( BMSreallocMemoryArray(&lp->chgcols, newsize) );
500 lp->chgcolssize = newsize;
501 }
502 assert(num <= lp->chgcolssize);
503
504 return SCIP_OKAY;
505}
506
507/** ensures, that lpicols array can store at least num entries */
508static
510 SCIP_LPEXACT* lp, /**< current LP data */
511 SCIP_SET* set, /**< global SCIP settings */
512 int num /**< minimum number of entries to store */
513 )
514{
515 assert(lp->nlpicols <= lp->lpicolssize);
516
517 if( num > lp->lpicolssize )
518 {
519 int newsize;
520
521 newsize = SCIPsetCalcMemGrowSize(set, num);
522 SCIP_ALLOC( BMSreallocMemoryArray(&lp->lpicols, newsize) );
523 lp->lpicolssize = newsize;
524 }
525 assert(num <= lp->lpicolssize);
526
527 return SCIP_OKAY;
528}
529
530/** ensures, that lpirows array can store at least num entries */
531static
533 SCIP_LPEXACT* lp, /**< current LP data */
534 SCIP_SET* set, /**< global SCIP settings */
535 int num /**< minimum number of entries to store */
536 )
537{
538 assert(lp->nlpirows <= lp->lpirowssize);
539
540 if( num > lp->lpirowssize )
541 {
542 int newsize;
543
544 newsize = SCIPsetCalcMemGrowSize(set, num);
545 SCIP_ALLOC( BMSreallocMemoryArray(&lp->lpirows, newsize) );
546 lp->lpirowssize = newsize;
547 }
548 assert(num <= lp->lpirowssize);
549
550 return SCIP_OKAY;
551}
552
553/** searches coefficient in part of the column, returns position in col vector or -1 if not found */
554static
556 SCIP_COLEXACT* col, /**< column to be searched in */
557 const SCIP_ROWEXACT* row, /**< coefficient to be searched for */
558 int minpos, /**< first position of search range */
559 int maxpos /**< last position of search range */
560 )
561{
562 int pos;
563 int idx;
564 int searchidx;
565
566 assert(col != NULL);
567 assert(row != NULL);
568
569 /* binary search */
570 searchidx = row->index;
571 while(minpos <= maxpos)
572 {
573 pos = (minpos + maxpos)/2;
574 assert(0 <= pos && pos < col->len);
575 assert(col->rows[pos] != NULL);
576 assert((pos < col->nlprows) == (col->rows[pos]->lppos >= 0 && col->linkpos[pos] >= 0));
577 idx = col->rows[pos]->index;
578 if( searchidx == idx )
579 return pos;
580 else if( searchidx < idx )
581 maxpos = pos-1;
582 else
583 minpos = pos+1;
584 }
585
586 return -1;
587}
588
589/** searches coefficient in column, returns position in col vector or -1 if not found */
590static
592 SCIP_COLEXACT* col, /**< column to be searched in */
593 const SCIP_ROWEXACT* row /**< coefficient to be searched for */
594 )
595{
596 int pos;
597
598 assert(col != NULL);
599 assert(row != NULL);
600
601 pos = -1;
602
603 /* search in the linked LP rows */
604 if( row->lppos >= 0 )
605 {
606 /* column has to be sorted, such that binary search works */
607 colExactSortLP(col);
608 assert(col->lprowssorted);
609
610 pos = colExactSearchCoefPart(col, row, 0, col->nlprows-1);
611 if( pos >= 0 )
612 return pos;
613 }
614
615 /* search in the non-LP/unlinked rows */
616 if( row->lppos == -1 || col->nunlinked > 0 )
617 {
618 /* column has to be sorted, such that binary search works */
620 assert(col->nonlprowssorted);
621
622 pos = colExactSearchCoefPart(col, row, col->nlprows, col->len-1);
623 }
624
625 return pos;
626}
627
628/** searches coefficient in part of the row, returns position in col vector or -1 if not found */
629static
631 SCIP_ROWEXACT* row, /**< row to be searched in */
632 const SCIP_COLEXACT* col, /**< coefficient to be searched for */
633 int minpos, /**< first position of search range */
634 int maxpos /**< last position of search range */
635 )
636{
637 int pos;
638 int idx;
639 int searchidx;
640
641 assert(col != NULL);
642 assert(row != NULL);
643
644 /* binary search */
645 searchidx = col->index;
646 while(minpos <= maxpos)
647 {
648 pos = (minpos + maxpos)/2;
649 assert(0 <= pos && pos < row->len);
650 assert(row->cols[pos] != NULL);
651 assert((pos < row->nlpcols) == (row->cols[pos]->lppos >= 0 && row->linkpos[pos] >= 0));
652 assert(row->cols_index[pos] == row->cols[pos]->index);
653 idx = row->cols_index[pos];
654 if( searchidx == idx )
655 return pos;
656 else if( searchidx < idx )
657 maxpos = pos-1;
658 else
659 minpos = pos+1;
660 }
661
662 return -1;
663}
664
665/** searches coefficient in row, returns position in row vector or -1 if not found;
666 * if the sorting of the row is delayed, returns -1
667 */
668static
670 SCIP_ROWEXACT* row, /**< row to be searched in */
671 const SCIP_COLEXACT* col /**< coefficient to be searched for */
672 )
673{
674 int pos;
675
676 assert(col != NULL);
677 assert(row != NULL);
678
679 if( row->delaysort )
680 return -1;
681
682 pos = -1;
683
684 /* search in the linked LP columns */
685 if( col->lppos >= 0 )
686 {
687 /* row has to be sorted, such that binary search works */
688 rowExactSortLP(row);
689 assert(row->lpcolssorted);
690
691 pos = rowExactSearchCoefPart(row, col, 0, row->nlpcols-1);
692 }
693
694 /* search in the non-LP/unlinked columns */
695 if( pos == -1 && (col->lppos == -1 || row->nunlinked > 0) )
696 {
697 /* row has to be sorted, such that binary search works */
699 assert(row->nonlpcolssorted);
700
701 pos = rowExactSearchCoefPart(row, col, row->nlpcols, row->len-1);
702 }
703
704#ifndef NDEBUG
705 /* validate result */
706 assert(-1 <= pos && pos < row->len);
707 if( pos >= 0 )
708 assert(row->cols[pos] == col);
709 else
710 {
711 int i;
712 for( i = 0; i < row->len; ++i )
713 assert(row->cols[i] != col);
714 }
715#endif
716
717 return pos;
718}
719
720/*
721 * Changing announcements
722 */
723
724/** announces, that the given coefficient in the constraint matrix changed */
725static
727 SCIP_ROWEXACT* row, /**< LP row */
728 SCIP_COLEXACT* col, /**< LP col */
729 SCIP_LPEXACT* lp /**< current LP data */
730 )
731{
732 assert(row != NULL);
733 assert(col != NULL);
734 assert(lp != NULL);
735
736 if( row->lpipos >= 0 && col->lpipos >= 0 )
737 {
738 assert(row->lpipos < lp->nlpirows);
739 assert(col->lpipos < lp->nlpicols);
740
741 /* we have to remember the change only in the row or in the column,
742 * because the readdition of one vector would change the other automatically.
743 */
744 if( row->lpipos >= lp->lpifirstchgrow )
745 row->coefchanged = TRUE;
746 else if( col->lpipos >= lp->lpifirstchgcol )
747 col->coefchanged = TRUE;
748 else if( lp->lpifirstchgrow - row->lpipos <= lp->lpifirstchgcol - col->lpipos )
749 {
750 row->coefchanged = TRUE;
751 lp->lpifirstchgrow = row->lpipos;
752 }
753 else
754 {
755 col->coefchanged = TRUE;
756 lp->lpifirstchgcol = col->lpipos;
757 }
758
759 /* mark the current LP unflushed */
760 lp->flushed = FALSE;
761 }
762
764}
765
766/*
767 * local column changing methods
768 */
769
770/** moves a coefficient in a column to a different place, and updates all corresponding data structures */
771static
773 SCIP_COLEXACT* col, /**< LP column */
774 int oldpos, /**< old position of coefficient */
775 int newpos /**< new position of coefficient */
776 )
777{
778 assert(col != NULL);
779 assert(0 <= oldpos && oldpos < col->len);
780 assert(0 <= newpos && newpos < col->len);
781 assert(col->rows[oldpos] != NULL);
782
783 if( oldpos == newpos )
784 return;
785
786 SCIPrationalSetRational(col->vals[newpos], col->vals[oldpos]);
787 col->rows[newpos] = col->rows[oldpos];
788 SCIPrationalSetRational(col->vals[newpos], col->vals[oldpos]);
789 col->linkpos[newpos] = col->linkpos[oldpos];
790
791 /* update link position in row */
792 if( col->linkpos[newpos] >= 0 )
793 {
794 assert(col->rows[newpos]->cols[col->linkpos[newpos]] == col);
795 assert(col->rows[newpos]->linkpos[col->linkpos[newpos]] == oldpos);
796
797 col->rows[newpos]->linkpos[col->linkpos[newpos]] = newpos;
798 }
799
800 /* update sorted flags */
801 if( col->rows[newpos]->lppos >= 0 && col->linkpos[newpos] >= 0 )
802 col->lprowssorted = FALSE;
803 else
804 col->nonlprowssorted = FALSE;
805}
806
807/** swaps two coefficients in a column, and updates all corresponding data structures */
808static
810 SCIP_COLEXACT* col, /**< LP column */
811 BMS_BUFMEM* buffer, /**< buffer for temp real */
812 int pos1, /**< position of first coefficient */
813 int pos2 /**< position of second coefficient */
814 )
815{
816 SCIP_ROWEXACT* tmprow;
817 SCIP_RATIONAL* tmpval;
818 int tmplinkpos;
819
820 assert(col != NULL);
821 assert(0 <= pos1 && pos1 < col->len);
822 assert(0 <= pos2 && pos2 < col->len);
823 assert(col->rows[pos1] != NULL);
824
825 if( pos1 == pos2 )
826 return SCIP_OKAY;
827
828 SCIP_CALL( SCIPrationalCreateBuffer(buffer, &tmpval) );
829
830 /* swap coefficients */
831 tmprow = col->rows[pos2];
832 SCIPrationalSetRational(tmpval, col->vals[pos2]);
833 tmplinkpos = col->linkpos[pos2];
834
835 col->rows[pos2] = col->rows[pos1];
836 SCIPrationalSetRational(col->vals[pos2], col->vals[pos1]);
837 col->linkpos[pos2] = col->linkpos[pos1];
838
839 col->rows[pos1] = tmprow;
840 SCIPrationalSetRational(col->vals[pos1], tmpval);
841 col->linkpos[pos1] = tmplinkpos;
842
843 SCIPrationalFreeBuffer(buffer, &tmpval);
844
845 /* update link position in rows */
846 if( col->linkpos[pos1] >= 0 )
847 {
848 assert(col->rows[pos1]->cols[col->linkpos[pos1]] == col);
849 assert(col->rows[pos1]->linkpos[col->linkpos[pos1]] == pos2);
850
851 col->rows[pos1]->linkpos[col->linkpos[pos1]] = pos1;
852 }
853
854 if( col->linkpos[pos2] >= 0 )
855 {
856 assert(col->rows[pos2]->cols[col->linkpos[pos2]] == col);
857 assert(col->rows[pos2]->linkpos[col->linkpos[pos2]] == pos1);
858
859 col->rows[pos2]->linkpos[col->linkpos[pos2]] = pos2;
860 }
861
862 /* update sorted flags */
863 if( col->rows[pos1]->lppos >= 0 && col->linkpos[pos1] >= 0 )
864 col->lprowssorted = FALSE;
865 else
866 col->nonlprowssorted = FALSE;
867 if( col->rows[pos2]->lppos >= 0 && col->linkpos[pos2] >= 0 )
868 col->lprowssorted = FALSE;
869 else
870 col->nonlprowssorted = FALSE;
871
872 return SCIP_OKAY;
873}
874
875/** moves a coefficient in a row to a different place, and updates all corresponding data structures */
876static
878 SCIP_ROWEXACT* row, /**< LP row */
879 int oldpos, /**< old position of coefficient */
880 int newpos /**< new position of coefficient */
881 )
882{
883 assert(row != NULL);
884 assert(0 <= oldpos && oldpos < row->len);
885 assert(0 <= newpos && newpos < row->len);
886 assert(row->cols[oldpos] != NULL);
887
888 if( oldpos == newpos )
889 return;
890
891 row->cols[newpos] = row->cols[oldpos];
892 row->cols_index[newpos] = row->cols_index[oldpos];
893 SCIPrationalSetRational(row->vals[newpos], row->vals[oldpos]);
894 row->valsinterval[newpos] = row->valsinterval[oldpos];
895 row->linkpos[newpos] = row->linkpos[oldpos];
896
897 /* update link position in column */
898 if( row->linkpos[newpos] >= 0 )
899 {
900 assert(row->cols[newpos]->rows[row->linkpos[newpos]] == row);
901 assert(row->cols[newpos]->linkpos[row->linkpos[newpos]] == oldpos);
902
903 row->cols[newpos]->linkpos[row->linkpos[newpos]] = newpos;
904 }
905
906 /* update sorted flags */
907 if( row->cols[newpos]->lppos >= 0 && row->linkpos[newpos] >= 0 )
908 row->lpcolssorted = FALSE;
909 else
910 row->nonlpcolssorted = FALSE;
911}
912
913/** swaps two coefficients in a row, and updates all corresponding data structures */
914static
916 SCIP_ROWEXACT* row, /**< LP row */
917 BMS_BUFMEM* buffer, /**< buffer for temp real */
918 int pos1, /**< position of first coefficient */
919 int pos2 /**< position of second coefficient */
920 )
921{
922 SCIP_COLEXACT* tmpcol;
923 SCIP_RATIONAL* tmpval;
924 SCIP_INTERVAL tmp;
925 int tmpindex;
926 int tmplinkpos;
927
928 assert(row != NULL);
929 assert(0 <= pos1 && pos1 < row->len);
930 assert(0 <= pos2 && pos2 < row->len);
931 assert(row->cols[pos1] != NULL);
932 assert(row->cols[pos1]->index == row->cols_index[pos1]);
933
934 if( pos1 == pos2 )
935 return SCIP_OKAY;
936
937 SCIP_CALL( SCIPrationalCreateBuffer(buffer, &tmpval) );
938
939 /* swap coefficients */
940 tmpcol = row->cols[pos2];
941 tmpindex = row->cols_index[pos2];
942 SCIPrationalSetRational(tmpval, row->vals[pos2]);
943 tmp = row->valsinterval[pos2];
944 tmplinkpos = row->linkpos[pos2];
945
946 row->cols[pos2] = row->cols[pos1];
947 row->cols_index[pos2] = row->cols_index[pos1];
948 SCIPrationalSetRational(row->vals[pos2], row->vals[pos1]);
949 row->valsinterval[pos2] = row->valsinterval[pos1];
950 row->linkpos[pos2] = row->linkpos[pos1];
951
952 row->cols[pos1] = tmpcol;
953 row->cols_index[pos1] = tmpindex;
954 SCIPrationalSetRational(row->vals[pos1], tmpval);
955 row->valsinterval[pos1] = tmp;
956 row->linkpos[pos1] = tmplinkpos;
957
958 SCIPrationalFreeBuffer(buffer, &tmpval);
959
960 /* update link position in columns */
961 if( row->linkpos[pos1] >= 0 )
962 {
963 assert(row->cols[pos1]->rows[row->linkpos[pos1]] == row);
964 assert(row->cols[pos1]->linkpos[row->linkpos[pos1]] == pos2);
965
966 row->cols[pos1]->linkpos[row->linkpos[pos1]] = pos1;
967 }
968 if( row->linkpos[pos2] >= 0 )
969 {
970 assert(row->cols[pos2]->rows[row->linkpos[pos2]] == row);
971 assert(row->cols[pos2]->linkpos[row->linkpos[pos2]] == pos1);
972
973 row->cols[pos2]->linkpos[row->linkpos[pos2]] = pos2;
974 }
975
976 /* update sorted flags */
977 if( row->cols[pos1]->lppos >= 0 && row->linkpos[pos1] >= 0 )
978 row->lpcolssorted = FALSE;
979 else
980 row->nonlpcolssorted = FALSE;
981 if( row->cols[pos2]->lppos >= 0 && row->linkpos[pos2] >= 0 )
982 row->lpcolssorted = FALSE;
983 else
984 row->nonlpcolssorted = FALSE;
985
986 return SCIP_OKAY;
987}
988
989/** forward declaration for rowExactAddCoef() */
990static
992 SCIP_ROWEXACT* row, /**< LP row */
993 BMS_BLKMEM* blkmem, /**< block memory */
994 SCIP_SET* set, /**< global SCIP settings */
995 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
996 SCIP_LPEXACT* lp, /**< current LP data */
997 SCIP_COLEXACT* col, /**< LP column */
998 SCIP_RATIONAL* val, /**< value of coefficient */
999 int linkpos /**< position of row in the column's row array, or -1 */
1000 );
1001
1002
1003/** insert column in the chgcols list (if not already there) */
1004static
1006 SCIP_COLEXACT* col, /**< LP column to change */
1007 SCIP_SET* set, /**< global SCIP settings */
1008 SCIP_LPEXACT* lp /**< current LP data */
1009 )
1010{
1011 if( !col->objchanged && !col->lbchanged && !col->ubchanged )
1012 {
1013 SCIP_CALL( ensureChgcolsSize(lp, set, lp->nchgcols+1) );
1014 lp->chgcols[lp->nchgcols] = col;
1015 lp->nchgcols++;
1016 }
1017
1018 /* mark the current LP unflushed */
1019 lp->flushed = FALSE;
1020
1021 return SCIP_OKAY;
1022}
1023
1024/** adds a previously non existing coefficient to an LP column */
1025static
1027 SCIP_COLEXACT* col, /**< LP column */
1028 BMS_BLKMEM* blkmem, /**< block memory */
1029 SCIP_SET* set, /**< global SCIP settings */
1030 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1031 SCIP_LPEXACT* lp, /**< current LP data */
1032 SCIP_ROWEXACT* row, /**< LP row */
1033 SCIP_RATIONAL* val, /**< value of coefficient */
1034 int linkpos /**< position of column in the row's col array, or -1 */
1035 )
1036{
1037 int pos;
1038
1039 assert(blkmem != NULL);
1040 assert(col != NULL);
1041 assert(col->nlprows <= col->len);
1042 assert(col->var != NULL);
1043 assert(!SCIPrationalIsZero(val));
1044
1045 SCIP_CALL( colExactEnsureSize(col, blkmem, set, col->len+1) );
1046 assert(col->rows != NULL);
1047 assert(col->vals != NULL);
1048 assert(col->linkpos != NULL);
1049
1050 pos = col->len;
1051 col->len++;
1052
1053 /* 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
1054 * part of the column's arrays
1055 */
1056 if( row->lppos >= 0 && linkpos >= 0 )
1057 {
1058 /* move the first non-LP/not linked row to the end */
1059 if( col->nlprows < pos )
1060 {
1061 colExactMoveCoef(col, col->nlprows, pos);
1062 pos = col->nlprows;
1063 }
1064 col->nlprows++;
1065 }
1066
1067 /* insert the row at the correct position and update the links */
1068 col->rows[pos] = row;
1069
1070 if( col->vals[pos] != NULL )
1071 SCIPrationalSetRational(col->vals[pos], val);
1072 else
1073 SCIP_CALL( SCIPrationalCopyBlock(blkmem, &col->vals[pos], val) );
1074
1075 col->linkpos[pos] = linkpos;
1076 if( linkpos == -1 )
1077 {
1078 col->nunlinked++;
1079
1080 /* if the column is in current LP, we have to link it to the row, because otherwise, the primal information
1081 * of the row is not complete
1082 */
1083 if( col->lppos >= 0 )
1084 {
1085 /* this call might swap the current row with the first non-LP/not linked row, s.t. insertion position
1086 * has to be updated
1087 */
1088 SCIP_CALL( rowExactAddCoef(row, blkmem, set, eventqueue, lp, col, val, pos) );
1089 if( row->lppos >= 0 )
1090 pos = col->nlprows-1;
1091 linkpos = col->linkpos[pos];
1092
1093 assert(0 <= linkpos && linkpos < row->len);
1094 assert(row->cols[linkpos] == col);
1095 assert(col->rows[pos] == row);
1096 assert(col->rows[pos]->cols[col->linkpos[pos]] == col);
1097 assert(col->rows[pos]->fprow->linkpos[col->linkpos[pos]] == pos);
1098 }
1099 }
1100 else
1101 {
1102 assert(row->linkpos[linkpos] == -1);
1103 assert(row->nunlinked > 0);
1104 row->linkpos[linkpos] = pos;
1105 row->nunlinked--;
1106
1107 /* if the column is in current LP, now both conditions, row->cols[linkpos]->lppos >= 0 and row->linkpos[linkpos] >= 0
1108 * hold, so we have to move the column to the linked LP-cols part of the row's cols array
1109 */
1110 if( col->lppos >= 0 )
1111 {
1112 row->nlpcols++;
1113 SCIP_CALL( rowExactSwapCoefs(row, set->buffer, linkpos, row->nlpcols-1) );
1114
1115 /* if no swap was necessary, mark nonlpcols to be unsorted */
1116 if( linkpos == row->nlpcols-1 )
1117 row->lpcolssorted = FALSE;
1118 }
1119 }
1120
1121 /* update the sorted flags */
1122 if( row->lppos >= 0 && linkpos >= 0 )
1123 {
1124 assert(col->nlprows >= 1);
1125 assert(col->rows[col->nlprows-1] == row);
1126 if( col->nlprows > 1 )
1127 {
1128 col->lprowssorted = col->lprowssorted
1129 && (col->rows[col->nlprows-2]->index < row->index);
1130 }
1131 }
1132 else
1133 {
1134 assert(col->len - col->nlprows >= 1);
1135 assert(col->rows[col->len-1] == row);
1136 if( col->len - col->nlprows > 1 )
1137 {
1139 && (col->rows[col->len-2]->index < row->index);
1140 }
1141 }
1142
1143 coefChangedExact(row, col, lp);
1144
1145 SCIPrationalDebugMessage("added coefficient %q * <%s> at position %d (%d/%d) to column <%s> (nunlinked=%d)\n",
1146 val, row->fprow->name, pos, col->nlprows, col->len,
1147 SCIPvarGetName(col->var), col->nunlinked);
1148
1149 return SCIP_OKAY;
1150}
1151
1152/** deletes coefficient at given position from column */
1153static
1155 SCIP_COLEXACT* col, /**< column to be changed */
1156 SCIP_SET* set, /**< global SCIP settings */
1157 SCIP_LPEXACT* lpexact, /**< current LP data */
1158 int pos /**< position in column vector to delete */
1159 )
1160{
1161 SCIP_ROWEXACT* row;
1162
1163 assert(lpexact != NULL);
1164 assert(col != NULL);
1165 assert(col->var != NULL);
1166 assert(set != NULL);
1167 assert(0 <= pos && pos < col->len);
1168 assert(col->rows[pos] != NULL);
1169 assert(col->linkpos[pos] == -1 || col->rows[pos]->cols[col->linkpos[pos]] == col);
1170 assert((pos < col->nlprows) == (col->linkpos[pos] >= 0 && col->rows[pos]->lppos >= 0));
1171
1172 row = col->rows[pos];
1173 assert((row->lppos >= 0) == (pos < col->nlprows));
1174
1175 SCIPrationalDebugMessage("deleting coefficient %q * <%p> at position %d from column <%s>\n",
1176 col->vals[pos], (void*) row, pos, SCIPvarGetName(col->var));
1177
1178 if( col->linkpos[pos] == -1 )
1179 col->nunlinked--;
1180
1181 /* if row is a linked LP row, move last linked LP coefficient to position of empty slot (deleted coefficient) */
1182 if( pos < col->nlprows )
1183 {
1184 colExactMoveCoef(col, col->nlprows-1, pos);
1185 col->nlprows--;
1186 pos = col->nlprows;
1187 }
1188
1189 /* move last coefficient to position of empty slot */
1190 colExactMoveCoef(col, col->len-1, pos);
1191 col->len--;
1192
1193 coefChangedExact(row, col, lpexact);
1194
1195 return SCIP_OKAY;
1196}
1197
1198/** changes a coefficient at given position of an LP column */
1199static
1201 SCIP_COLEXACT* col, /**< LP column */
1202 SCIP_SET* set, /**< global SCIP settings */
1203 SCIP_LPEXACT* lp, /**< current LP data */
1204 int pos, /**< position in column vector to change */
1205 SCIP_RATIONAL* val /**< value of coefficient */
1206 )
1207{
1208 assert(col != NULL);
1209 assert(col->var != NULL);
1210 assert(0 <= pos && pos < col->len);
1211 assert(col->rows[pos] != NULL);
1212 assert(col->linkpos[pos] == -1 || col->rows[pos]->cols[col->linkpos[pos]] == col);
1213
1214 SCIPrationalDebugMessage("changing coefficient %q * <%s> at position %d of column <%s> to %g\n",
1215 col->vals[pos], col->rows[pos]->fprow->name, pos, SCIPvarGetName(col->var), val);
1216
1217 if( SCIPrationalIsZero(val) )
1218 {
1219 /* delete existing coefficient */
1220 SCIP_CALL( colExactDelCoefPos(col, set, lp, pos) );
1221 }
1222 else if( !SCIPrationalIsEQ(col->vals[pos], val) )
1223 {
1224 /* change existing coefficient */
1225 SCIPrationalSetRational(col->vals[pos], val);
1226 coefChangedExact(col->rows[pos], col, lp);
1227 }
1228
1229 return SCIP_OKAY;
1230}
1231
1232
1233/** forward declaration for rowEactAddCoef() */
1234static
1236 SCIP_ROWEXACT* row, /**< LP row */
1237 BMS_BLKMEM* blkmem, /**< block memory */
1238 SCIP_SET* set, /**< global SCIP settings */
1239 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1240 SCIP_LPEXACT* lp, /**< current LP data */
1241 SCIP_COLEXACT* col, /**< LP column */
1242 SCIP_RATIONAL* val, /**< value of coefficient */
1243 int linkpos /**< position of row in the column's row array, or -1 */
1244 )
1245{
1246 int pos;
1247
1248 assert(row != NULL);
1249 assert(row->nlpcols <= row->len);
1250 assert(blkmem != NULL);
1251 assert(col != NULL);
1252 assert(col->var != NULL);
1253 assert(!SCIPrationalIsZero(val));
1254
1255 if( row->nlocks > 0 )
1256 {
1257 SCIPerrorMessage("cannot add a coefficient to the locked unmodifiable row <%s>\n", row->fprow->name);
1258 return SCIP_INVALIDDATA;
1259 }
1260
1261 SCIP_CALL( SCIProwExactEnsureSize(row, blkmem, set, row->len+1) );
1262 assert(row->cols != NULL);
1263 assert(row->vals != NULL);
1264
1265 pos = row->len;
1266 row->len++;
1267
1268 /* 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
1269 * part of the row's arrays
1270 */
1271 if( col->lppos >= 0 && linkpos >= 0 )
1272 {
1273 /* move the first non-LP/not linked column to the end */
1274 if( row->nlpcols < pos )
1275 {
1276 rowExactMoveCoef(row, row->nlpcols, pos);
1277 pos = row->nlpcols;
1278 }
1279 row->nlpcols++;
1280 }
1281
1282 /* insert the column at the correct position and update the links */
1283 row->cols[pos] = col;
1284 row->cols_index[pos] = col->index;
1285 if( row->vals[pos] == NULL )
1286 SCIP_CALL( SCIPrationalCopyBlock(blkmem, &row->vals[pos], val) );
1287 else
1288 SCIPrationalSetRational(row->vals[pos], val);
1289
1290 SCIPintervalSetRational(&row->valsinterval[pos], row->vals[pos]);
1291 row->linkpos[pos] = linkpos;
1292 row->integral = row->integral && SCIPcolIsIntegral(col->fpcol) && SCIPrationalIsIntegral(val);
1293 if( linkpos == -1 )
1294 {
1295 row->nunlinked++;
1296
1297 /* if the row is in current LP, we have to link it to the column, because otherwise, the dual information
1298 * of the column is not complete
1299 */
1300 if( row->lppos >= 0 )
1301 {
1302 /* this call might swap the current column with the first non-LP/not linked column, s.t. insertion position
1303 * has to be updated
1304 */
1305 SCIP_CALL( colExactAddCoef(col, blkmem, set, eventqueue, lp, row, val, pos) );
1306 if( col->lppos >= 0 )
1307 pos = row->nlpcols-1;
1308 linkpos = row->linkpos[pos];
1309
1310 assert(0 <= linkpos && linkpos < col->len);
1311 assert(col->rows[linkpos] == row);
1312 assert(row->cols[pos] == col);
1313 assert(row->cols[pos]->rows[row->linkpos[pos]] == row);
1314 assert(row->cols[pos]->linkpos[row->linkpos[pos]] == pos);
1315 }
1316 }
1317 else
1318 {
1319 assert(col->linkpos[linkpos] == -1);
1320 assert(col->nunlinked > 0);
1321 col->linkpos[linkpos] = pos;
1322 col->nunlinked--;
1323
1324 /* if the row is in current LP, now both conditions, col->rows[linkpos]->lppos >= 0 and col->linkpos[linkpos] >= 0
1325 * hold, so we have to move the row to the linked LP-rows part of the column's rows array
1326 */
1327 if( row->lppos >= 0 )
1328 {
1329 col->nlprows++;
1330 SCIP_CALL( colExactSwapCoefs(col, set->buffer, linkpos, col->nlprows-1) );
1331
1332 /* if no swap was necessary, mark lprows to be unsorted */
1333 if( linkpos == col->nlprows-1 )
1334 col->lprowssorted = FALSE;
1335 }
1336 }
1337
1338 /* update the sorted flags */
1339 if( col->lppos >= 0 && linkpos >= 0 )
1340 {
1341 assert(row->nlpcols >= 1);
1342 assert(row->cols[row->nlpcols-1] == col);
1343 if( row->nlpcols > 1 )
1344 {
1345 assert(row->cols_index[row->nlpcols-2] == row->cols[row->nlpcols-2]->index);
1346 row->lpcolssorted = row->lpcolssorted && (row->cols_index[row->nlpcols-2] < col->index);
1347 }
1348 }
1349 else
1350 {
1351 assert(row->len - row->nlpcols >= 1);
1352 assert(row->cols[row->len-1] == col);
1353 if( row->len - row->nlpcols > 1 )
1354 {
1355 assert(row->cols_index[row->len-2] == row->cols[row->len-2]->index);
1356 row->nonlpcolssorted = row->nonlpcolssorted && (row->cols_index[row->len-2] < col->index);
1357 }
1358 }
1359
1360 coefChangedExact(row, col, lp);
1361
1362 SCIPrationalDebugMessage("added coefficient %q * <%s> at position %d (%d/%d) to row <%s> (nunlinked=%d)\n",
1363 val, SCIPvarGetName(col->var), pos, row->nlpcols, row->len, row->fprow->name, row->nunlinked);
1364
1365 return SCIP_OKAY;
1366}
1367
1368/** deletes coefficient at given position from row */
1369static
1371 SCIP_ROWEXACT* row, /**< row to be changed */
1372 SCIP_SET* set, /**< global SCIP settings */
1373 SCIP_LPEXACT* lp, /**< current LP data */
1374 int pos /**< position in row vector to delete */
1375 )
1376{
1377 SCIP_COLEXACT* col;
1378
1379 assert(row != NULL);
1380 assert(set != NULL);
1381 assert(0 <= pos && pos < row->len);
1382 assert(row->cols[pos] != NULL);
1383 assert((pos < row->nlpcols) == (row->linkpos[pos] >= 0 && row->cols[pos]->lppos >= 0));
1384
1385 col = row->cols[pos];
1386
1387 assert((pos < row->nlpcols) == (col->lppos >= 0 && row->linkpos[pos] >= 0));
1388
1389 SCIPrationalDebugMessage("deleting coefficient %q * <%s> at position %d from row <%s>\n",
1390 row->vals[pos], SCIPvarGetName(col->var), pos, row->fprow->name);
1391
1392 if( row->nlocks > 0 )
1393 {
1394 SCIPerrorMessage("cannot delete a coefficient from the locked unmodifiable row <%s>\n", row->fprow->name);
1395 return SCIP_INVALIDDATA;
1396 }
1397
1398 if( row->linkpos[pos] == -1 )
1399 row->nunlinked--;
1400
1401 /* if column is a linked LP column, move last linked LP coefficient to position of empty slot (deleted coefficient) */
1402 if( pos < row->nlpcols )
1403 {
1404 rowExactMoveCoef(row, row->nlpcols-1, pos);
1405 assert(!row->lpcolssorted);
1406 row->nlpcols--;
1407 pos = row->nlpcols;
1408 }
1409
1410 /* move last coefficient to position of empty slot */
1411 rowExactMoveCoef(row, row->len-1, pos);
1412 row->len--;
1413
1414 coefChangedExact(row, col, lp);
1415
1416 return SCIP_OKAY;
1417}
1418
1419/** changes a coefficient at given position of an LP row */
1420static
1422 SCIP_ROWEXACT* row, /**< LP row */
1423 SCIP_SET* set, /**< global SCIP settings */
1424 SCIP_LPEXACT* lp, /**< current LP data */
1425 int pos, /**< position in row vector to change */
1426 SCIP_RATIONAL* val /**< value of coefficient */
1427 )
1428{
1429 SCIP_COLEXACT* col;
1430
1431 assert(row != NULL);
1432 assert(lp != NULL);
1433
1434 col = row->cols[pos];
1435
1436 assert(col != NULL);
1437 assert(0 <= pos && pos < row->len);
1438
1439 SCIPrationalDebugMessage("changing coefficient %q * <%s> at position %d of row <%s> to %q\n",
1440 row->vals[pos], SCIPvarGetName(row->cols[pos]->var), pos, row->fprow->name, val);
1441
1442 if( row->nlocks > 0 )
1443 {
1444 SCIPerrorMessage("cannot change a coefficient of the locked unmodifiable row <%s>\n", row->fprow->name);
1445 return SCIP_INVALIDDATA;
1446 }
1447
1448 assert(col != NULL);
1449
1450 if( SCIPrationalIsZero(val) )
1451 {
1452 /* delete existing coefficient */
1453 SCIP_CALL( rowExactDelCoefPos(row, set, lp, pos) );
1454 }
1455 else if( !SCIPrationalIsEQ(row->vals[pos], val) )
1456 {
1457 /* change existing coefficient */
1458 SCIPrationalSetRational(row->vals[pos], val);
1459 SCIPintervalSetRational(&row->valsinterval[pos], val);
1460 row->integral = row->integral && SCIPcolIsIntegral(col->fpcol) && SCIPrationalIsIntegral(val);
1461 coefChangedExact(row, col, lp);
1462 }
1463
1464 return SCIP_OKAY;
1465}
1466
1467/*
1468 * double linked coefficient matrix methods
1469 */
1470
1471/** insert column coefficients in corresponding rows */
1472static
1474 SCIP_COLEXACT* col, /**< column data */
1475 BMS_BLKMEM* blkmem, /**< block memory */
1476 SCIP_SET* set, /**< global SCIP settings */
1477 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1478 SCIP_LPEXACT* lp /**< current LP data */
1479 )
1480{
1481 int i;
1482
1483 assert(col != NULL);
1484 assert(col->fpcol->var != NULL);
1485 assert(blkmem != NULL);
1486 assert(set != NULL);
1487 assert(lp != NULL);
1488
1489 if( col->nunlinked > 0 )
1490 {
1491 SCIPsetDebugMsg(set, "linking column <%s>\n", SCIPvarGetName(col->var));
1492
1493 /* unlinked rows can only be in the non-LP/unlinked rows part of the rows array */
1494 for( i = col->nlprows; i < col->len; ++i )
1495 {
1496 assert(!SCIPrationalIsZero(col->vals[i]));
1497 if( col->linkpos[i] == -1 )
1498 {
1499 /* this call might swap the current row with the first non-LP/not linked row, but this is of no harm */
1500 SCIP_CALL( rowExactAddCoef(col->rows[i], blkmem, set, eventqueue, lp, col, col->vals[i], i) );
1501 }
1502 assert(col->rows[i]->cols[col->linkpos[i]] == col);
1503 assert(col->rows[i]->linkpos[col->linkpos[i]] == i);
1504 assert(col->nlprows == 0 || col->rows[col->nlprows-1]->cols[col->linkpos[col->nlprows-1]] == col);
1505 assert(col->nlprows == 0 || col->rows[col->nlprows-1]->linkpos[col->linkpos[col->nlprows-1]] == col->nlprows-1);
1506 }
1507 }
1508 assert(col->nunlinked == 0);
1509
1510 checkLinks(lp);
1511
1512 return SCIP_OKAY;
1513}
1514
1515/** insert row coefficients in corresponding columns */
1516static
1518 SCIP_ROWEXACT* row, /**< row data */
1519 BMS_BLKMEM* blkmem, /**< block memory */
1520 SCIP_SET* set, /**< global SCIP settings */
1521 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1522 SCIP_LPEXACT* lp /**< current LP data */
1523 )
1524{
1525 int i;
1526
1527 assert(row != NULL);
1528 assert(blkmem != NULL);
1529 assert(set != NULL);
1530 assert(lp != NULL);
1531
1532 if( row->nunlinked > 0 )
1533 {
1534 SCIPsetDebugMsg(set, "linking row <%s>\n", row->fprow->name);
1535
1536 /* unlinked columns can only be in the non-LP/unlinked columns part of the cols array */
1537 for( i = row->nlpcols; i < row->len; ++i )
1538 {
1539 assert(!SCIPrationalIsZero(row->vals[i]));
1540 if( row->linkpos[i] == -1 )
1541 {
1542 /* this call might swap the current column with the first non-LP/not linked column, but this is of no harm */
1543 SCIP_CALL( colExactAddCoef(row->cols[i], blkmem, set, eventqueue, lp, row, row->vals[i], i) );
1544 }
1545 assert(row->cols[i]->rows[row->linkpos[i]] == row);
1546 assert(row->cols[i]->linkpos[row->linkpos[i]] == i);
1547 assert(row->nlpcols == 0 || row->cols[row->nlpcols-1]->rows[row->linkpos[row->nlpcols-1]] == row);
1548 assert(row->nlpcols == 0 || row->cols[row->nlpcols-1]->linkpos[row->linkpos[row->nlpcols-1]] == row->nlpcols-1);
1549 }
1550 }
1551 assert(row->nunlinked == 0);
1552
1553 checkLinks(lp);
1554
1555 return SCIP_OKAY;
1556}
1557
1558/** removes row coefficients from corresponding columns */
1559static
1561 SCIP_ROWEXACT* row, /**< row data */
1562 SCIP_SET* set, /**< global SCIP settings */
1563 SCIP_LPEXACT* lp /**< current LP data */
1564 )
1565{
1566 int i;
1567
1568 assert(row != NULL);
1569 assert(set != NULL);
1570 assert(lp != NULL);
1571
1572 if( row->nunlinked < row->len )
1573 {
1574 SCIPsetDebugMsg(set, "unlinking exact row <%p>\n", (void*) row);
1575 for( i = 0; i < row->len; ++i )
1576 {
1577 if( row->linkpos[i] >= 0 )
1578 {
1579 assert(row->cols[i]->rows[row->linkpos[i]] == row);
1580 SCIP_CALL( colExactDelCoefPos(row->cols[i], set, lp, row->linkpos[i]) );
1581 row->nunlinked++;
1582 }
1583 }
1584 }
1585 assert(row->nunlinked == row->len);
1586
1587 return SCIP_OKAY;
1588}
1589
1590/** updates link data after addition of column */
1591static
1593 SCIP_COLEXACT* col, /**< LP column */
1594 SCIP_SET* set /**< global SCIP settings */
1595 )
1596{
1597 SCIP_ROWEXACT* row;
1598 int i;
1599 int pos;
1600
1601 assert(col != NULL);
1602 assert(col->lppos >= 0);
1603
1604 /* update column arrays of all linked rows */
1605 for( i = 0; i < col->len; ++i )
1606 {
1607 pos = col->linkpos[i];
1608 if( pos >= 0 )
1609 {
1610 row = col->rows[i];
1611 assert(row != NULL);
1612 assert(row->linkpos[pos] == i);
1613 assert(row->cols[pos] == col);
1614 assert(row->nlpcols <= pos && pos < row->len);
1615
1616 row->nlpcols++;
1617 SCIP_CALL( rowExactSwapCoefs(row, set->buffer, pos, row->nlpcols-1) );
1618 assert(row->cols[row->nlpcols-1] == col);
1619
1620 /* if no swap was necessary, mark lpcols to be unsorted */
1621 if( pos == row->nlpcols-1 )
1622 row->lpcolssorted = FALSE;
1623 }
1624 }
1625
1626 return SCIP_OKAY;
1627}
1628
1629/** updates link data after addition of row */
1630static
1632 SCIP_ROWEXACT* row, /**< LP row */
1633 SCIP_SET* set /**< global SCIP settings */
1634 )
1635{
1636 SCIP_COLEXACT* col;
1637 int i;
1638 int pos;
1639
1640 assert(row != NULL);
1641 assert(row->lppos >= 0);
1642
1643 /* update row arrays of all linked columns */
1644 for( i = 0; i < row->len; ++i )
1645 {
1646 pos = row->linkpos[i];
1647 if( pos >= 0 )
1648 {
1649 col = row->cols[i];
1650 assert(col != NULL);
1651 assert(col->linkpos[pos] == i);
1652 assert(col->rows[pos] == row);
1653 assert(col->nlprows <= pos && pos < col->len);
1654
1655 col->nlprows++;
1656 SCIP_CALL( colExactSwapCoefs(col, set->buffer, pos, col->nlprows-1) );
1657
1658 /* if no swap was necessary, mark lprows to be unsorted */
1659 if( pos == col->nlprows-1 )
1660 col->lprowssorted = FALSE;
1661 }
1662 }
1663
1664 return SCIP_OKAY;
1665}
1666
1667/** updates link data after removal of column */
1668static
1670 SCIP_COLEXACT* col, /**< LP column */
1671 SCIP_SET* set /**< global SCIP settings */
1672 )
1673{
1674 SCIP_ROWEXACT* row;
1675 int i;
1676 int pos;
1677
1678 assert(col != NULL);
1679 assert(col->lppos == -1);
1680
1681 /* update column arrays of all linked rows */
1682 for( i = 0; i < col->len; ++i )
1683 {
1684 pos = col->linkpos[i];
1685 if( pos >= 0 )
1686 {
1687 row = col->rows[i];
1688 assert(row != NULL);
1689 assert(row->linkpos[pos] == i);
1690 assert(row->cols[pos] == col);
1691 assert(0 <= pos && pos < row->nlpcols);
1692
1693 row->nlpcols--;
1694 SCIP_CALL( rowExactSwapCoefs(row, set->buffer, pos, row->nlpcols) );
1695
1696 /* if no swap was necessary, mark nonlpcols to be unsorted */
1697 if( pos == row->nlpcols )
1698 row->nonlpcolssorted = FALSE;
1699 }
1700 }
1701
1702 return SCIP_OKAY;
1703}
1704
1705/** updates link data after removal of row */
1706static
1708 SCIP_ROWEXACT* row, /**< LP row */
1709 SCIP_SET* set /**< global SCIP settings */
1710 )
1711{
1712 SCIP_COLEXACT* col;
1713 int i;
1714 int pos;
1715
1716 assert(row != NULL);
1717 assert(row->lppos == -1);
1718
1719 /* update row arrays of all linked columns */
1720 for( i = 0; i < row->len; ++i )
1721 {
1722 pos = row->linkpos[i];
1723 if( pos >= 0 )
1724 {
1725 col = row->cols[i];
1726 assert(col != NULL);
1727 assert(0 <= pos && pos < col->nlprows);
1728 assert(col->linkpos[pos] == i);
1729 assert(col->rows[pos] == row);
1730
1731 col->nlprows--;
1732 SCIP_CALL( colExactSwapCoefs(col, set->buffer, pos, col->nlprows) );
1733
1734 /* if no swap was necessary, mark lprows to be unsorted */
1735 if( pos == col->nlprows )
1736 col->nonlprowssorted = FALSE;
1737 }
1738 }
1739
1740 return SCIP_OKAY;
1741}
1742
1743/*
1744 * flushing methods
1745 */
1746
1747/** resets column data to represent a column not in the LP solver */
1748static
1750 SCIP_COLEXACT* col /**< column to be marked deleted */
1751 )
1752{
1753 assert(col != NULL);
1754
1755 col->lpipos = -1;
1756 col->validredcostlp = -1;
1757 col->validfarkaslp = -1;
1758 col->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
1759}
1760
1761/** applies all cached column removals to the LP solver */
1762static
1764 SCIP_LPEXACT* lp /**< current LP data */
1765 )
1766{
1767 assert(lp != NULL);
1768 assert(lp->lpifirstchgcol <= lp->nlpicols);
1769 assert(lp->lpifirstchgcol <= lp->ncols);
1770
1771 /* find the first column to change */
1772 while( lp->lpifirstchgcol < lp->nlpicols
1773 && lp->lpifirstchgcol < lp->ncols
1774 && lp->cols[lp->lpifirstchgcol]->lpipos == lp->lpifirstchgcol
1775 && !lp->cols[lp->lpifirstchgcol]->coefchanged )
1776 {
1777 assert(lp->cols[lp->lpifirstchgcol] == lp->lpicols[lp->lpifirstchgcol]);
1778 lp->lpifirstchgcol++;
1779 }
1780
1781 /* shrink LP to the part which didn't change */
1782 if( lp->lpifirstchgcol < lp->nlpicols )
1783 {
1784 int i;
1785
1786 assert(!lp->fplp->diving);
1787 SCIPdebugMessage("flushing col deletions: shrink exact LP from %d to %d columns\n", lp->nlpicols, lp->lpifirstchgcol);
1789 for( i = lp->lpifirstchgcol; i < lp->nlpicols; ++i )
1790 {
1791 markColexDeleted(lp->lpicols[i]);
1792 }
1793 lp->nlpicols = lp->lpifirstchgcol;
1794 lp->flushdeletedcols = TRUE;
1795 lp->updateintegrality = TRUE;
1796
1797 /* mark the LP unsolved */
1798 lp->solved = FALSE;
1799 lp->primalfeasible = FALSE;
1800 lp->primalchecked = FALSE;
1802 }
1803 assert(lp->nlpicols == lp->lpifirstchgcol);
1804
1805 return SCIP_OKAY;
1806}
1807
1808/** applies all cached column additions to the LP solver */
1809static
1811 SCIP_LPEXACT* lp, /**< current LP data */
1812 BMS_BLKMEM* blkmem, /**< block memory */
1813 SCIP_SET* set, /**< global SCIP settings */
1814 SCIP_EVENTQUEUE* eventqueue /**< event queue */
1815 )
1816{
1817 SCIP_RATIONAL** obj;
1818 SCIP_RATIONAL** lb;
1819 SCIP_RATIONAL** ub;
1820 int* beg;
1821 int* ind;
1822 SCIP_RATIONAL** val;
1823 char** name;
1824 SCIP_COLEXACT* col;
1825 int c;
1826 int pos;
1827 int nnonz;
1828 int naddcols;
1829 int naddcoefs;
1830 int i;
1831 int lpipos;
1832
1833 assert(lp != NULL);
1834 assert(lp->lpifirstchgcol == lp->nlpicols);
1835 assert(blkmem != NULL);
1836 assert(set != NULL);
1837
1838 /* if there are no columns to add, we are ready */
1839 if( lp->ncols == lp->nlpicols )
1840 return SCIP_OKAY;
1841
1842 /* add the additional columns */
1843 assert(lp->ncols > lp->nlpicols);
1845
1846 /* count the (maximal) number of added coefficients, calculate the number of added columns */
1847 naddcols = lp->ncols - lp->nlpicols;
1848 naddcoefs = 0;
1849 for( c = lp->nlpicols; c < lp->ncols; ++c )
1850 naddcoefs += lp->cols[c]->len;
1851 assert(naddcols > 0);
1852
1853 /* get temporary memory for changes */
1854 SCIP_CALL( SCIPrationalCreateBufferArray(set->buffer, &obj, naddcols) );
1855 SCIP_CALL( SCIPrationalCreateBufferArray(set->buffer, &lb, naddcols) );
1856 SCIP_CALL( SCIPrationalCreateBufferArray(set->buffer, &ub, naddcols) );
1857 SCIP_CALL( SCIPrationalCreateBufferArray(set->buffer, &val, naddcoefs) );
1858 SCIP_CALL( SCIPsetAllocBufferArray(set, &beg, naddcols) );
1859 SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, naddcoefs) );
1860 SCIP_CALL( SCIPsetAllocBufferArray(set, &name, naddcols) );
1861
1862 /* fill temporary memory with column data */
1863 nnonz = 0;
1864 for( pos = 0, c = lp->nlpicols; c < lp->ncols; ++pos, ++c )
1865 {
1866 col = lp->cols[c];
1867 assert(col != NULL);
1868 assert(col->var != NULL);
1870 assert(SCIPvarGetColExact(col->var) == col);
1871 assert(col->lppos == c);
1872 assert(nnonz + col->nlprows <= naddcoefs);
1873
1874 SCIPsetDebugMsg(set, "flushing added column <%s>: ", SCIPvarGetName(col->var));
1875
1876 /* Because the column becomes a member of the LP solver, it now can take values
1877 * different from zero. That means, we have to include the column in the corresponding
1878 * row vectors.
1879 */
1880 SCIP_CALL( colExactLink(col, blkmem, set, eventqueue, lp) );
1881
1882 lp->lpicols[c] = col;
1883 col->lpipos = c;
1884 col->validredcostlp = -1;
1885 col->validfarkaslp = -1;
1886 col->objchanged = FALSE;
1887 col->lbchanged = FALSE;
1888 col->ubchanged = FALSE;
1889 col->coefchanged = FALSE;
1890 SCIPrationalSetRational(obj[pos], col->obj);
1891 SCIPrationalSetRational(lb[pos], col->lb);
1892 SCIPrationalSetRational(ub[pos], col->ub);
1893
1894 beg[pos] = nnonz;
1895 name[pos] = (char*)SCIPvarGetName(col->fpcol->var);
1896
1897 SCIPrationalSetRational(col->flushedobj, obj[pos]);
1898 SCIPrationalSetRational(col->flushedlb, lb[pos]);
1899 SCIPrationalSetRational(col->flushedub, ub[pos]);
1900
1901 for( i = 0; i < col->nlprows; ++i )
1902 {
1903 assert(col->rows[i] != NULL);
1904 lpipos = col->rows[i]->lpipos;
1905 if( lpipos >= 0 )
1906 {
1907 assert(lpipos < lp->nrows);
1908 assert(nnonz < naddcoefs);
1909 ind[nnonz] = lpipos;
1910 SCIPrationalSetRational(val[nnonz], col->vals[i]);
1911 nnonz++;
1912 }
1913 }
1914#ifndef NDEBUG
1915 for( i = col->nlprows; i < col->len; ++i )
1916 {
1917 assert(col->rows[i] != NULL);
1918 assert(col->rows[i]->lpipos == -1); /* because the row deletions are already performed */
1919 }
1920#endif
1921 }
1922
1923 /* call LP interface */
1924 SCIPsetDebugMsg(set, "flushing col additions: enlarge exact LP from %d to %d columns\n", lp->nlpicols, lp->ncols);
1925 SCIP_CALL( SCIPlpiExactAddCols(lp->lpiexact, naddcols, obj, lb, ub, name, nnonz, beg, ind, val) );
1926 lp->nlpicols = lp->ncols;
1927 lp->lpifirstchgcol = lp->nlpicols;
1928
1929 /* free temporary memory */
1933 SCIPrationalFreeBufferArray(set->buffer, &val, naddcoefs);
1934 SCIPrationalFreeBufferArray(set->buffer, &ub, naddcols);
1935 SCIPrationalFreeBufferArray(set->buffer, &lb, naddcols);
1936 SCIPrationalFreeBufferArray(set->buffer, &obj, naddcols);
1937
1938 lp->flushaddedcols = TRUE;
1939 lp->updateintegrality = TRUE;
1940
1941 /* mark the LP unsolved */
1942 lp->solved = FALSE;
1943 lp->dualfeasible = FALSE;
1944 lp->dualchecked = FALSE;
1946
1947 return SCIP_OKAY;
1948}
1949
1950/** resets row data to represent a row not in the LP solver */
1951static
1953 SCIP_ROWEXACT* row /**< row to be marked deleted */
1954 )
1955{
1956 assert(row != NULL);
1957
1958 row->lpipos = -1;
1959 row->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
1960 row->validactivitylp = -1;
1961}
1962
1963/** applies all cached row removals to the LP solver */
1964static
1966 SCIP_LPEXACT* lp, /**< current LP data */
1967 BMS_BLKMEM* blkmem, /**< block memory */
1968 SCIP_SET* set /**< global SCIP settings */
1969 )
1970{
1971 assert(lp != NULL);
1972 assert(lp->lpifirstchgrow <= lp->nlpirows);
1973 assert(lp->lpifirstchgrow <= lp->nrows);
1974
1975 /* find the first row to change */
1976 while( lp->lpifirstchgrow < lp->nlpirows
1977 && lp->lpifirstchgrow < lp->nrows
1978 && lp->rows[lp->lpifirstchgrow]->lpipos == lp->lpifirstchgrow
1979 && !lp->rows[lp->lpifirstchgrow]->coefchanged )
1980 {
1981 assert(lp->rows[lp->lpifirstchgrow] == lp->lpirows[lp->lpifirstchgrow]);
1982 lp->lpifirstchgrow++;
1983 }
1984
1985 /* shrink LP to the part which didn't change */
1986 if( lp->lpifirstchgrow < lp->nlpirows )
1987 {
1988 int i;
1989
1990 SCIPsetDebugMsg(set, "flushing row deletions: shrink exact LP from %d to %d rows\n", lp->nlpirows, lp->lpifirstchgrow);
1992 for( i = lp->lpifirstchgrow; i < lp->nlpirows; ++i )
1993 {
1994 markRowexDeleted(lp->lpirows[i]);
1995 SCIP_CALL( SCIProwExactRelease(&lp->lpirows[i], blkmem, set, lp) );
1996 }
1997 lp->nlpirows = lp->lpifirstchgrow;
1998 lp->flushdeletedrows = TRUE;
1999
2000 /* mark the LP unsolved */
2001 lp->solved = FALSE;
2002 lp->dualfeasible = FALSE;
2003 lp->dualchecked = FALSE;
2005 }
2006 assert(lp->nlpirows == lp->lpifirstchgrow);
2007
2008 return SCIP_OKAY;
2009}
2010
2011/** applies all cached row additions and removals to the LP solver */
2012static
2014 SCIP_LPEXACT* lp, /**< current LP data */
2015 BMS_BLKMEM* blkmem, /**< block memory */
2016 SCIP_SET* set, /**< global SCIP settings */
2017 SCIP_EVENTQUEUE* eventqueue /**< event queue */
2018 )
2019{
2020 SCIP_RATIONAL** lhs;
2021 SCIP_RATIONAL** rhs;
2022 SCIP_RATIONAL** val;
2023 int* beg;
2024 int* ind;
2025 char** name;
2026 SCIP_ROWEXACT* row;
2027 int r;
2028 int pos;
2029 int nnonz;
2030 int naddrows;
2031 int naddcoefs;
2032 int i;
2033 int lpipos;
2034
2035 assert(lp != NULL);
2036 assert(lp->lpifirstchgrow == lp->nlpirows);
2037 assert(blkmem != NULL);
2038
2039 /* if there are no rows to add, we are ready */
2040 if( lp->nrows == lp->nlpirows )
2041 return SCIP_OKAY;
2042
2043 /* add the additional rows */
2044 assert(lp->nrows > lp->nlpirows);
2046
2047 /* count the (maximal) number of added coefficients, calculate the number of added rows */
2048 naddrows = lp->nrows - lp->nlpirows;
2049 naddcoefs = 0;
2050 for( r = lp->nlpirows; r < lp->nrows; ++r )
2051 naddcoefs += lp->rows[r]->len;
2052 assert(naddrows > 0);
2053
2054 /* get temporary memory for changes */
2055 SCIP_CALL( SCIPrationalCreateBufferArray(set->buffer, &lhs, naddrows) );
2056 SCIP_CALL( SCIPrationalCreateBufferArray(set->buffer, &rhs, naddrows) );
2057 SCIP_CALL( SCIPrationalCreateBufferArray(set->buffer, &val, naddcoefs) );
2058 SCIP_CALL( SCIPsetAllocBufferArray(set, &beg, naddrows) );
2059 SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, naddcoefs) );
2060 SCIP_CALL( SCIPsetAllocBufferArray(set, &name, naddrows) );
2061
2062 /* fill temporary memory with row data */
2063 nnonz = 0;
2064 for( pos = 0, r = lp->nlpirows; r < lp->nrows; ++pos, ++r )
2065 {
2066 row = lp->rows[r];
2067 assert(row != NULL);
2068 assert(row->lppos == r);
2069 assert(nnonz + row->nlpcols <= naddcoefs);
2070
2071 SCIPsetDebugMsg(set, "flushing added exact row <%s>: ", row->fprow->name);
2072
2073 /* Because the row becomes a member of the LP solver, its dual variable now can take values
2074 * different from zero. That means, we have to include the row in the corresponding
2075 * column vectors.
2076 */
2077 SCIP_CALL( rowExactLink(row, blkmem, set, eventqueue, lp) );
2078
2080 lp->lpirows[r] = row;
2081 row->lpipos = r;
2082 row->lhschanged = FALSE;
2083 row->rhschanged = FALSE;
2084 row->coefchanged = FALSE;
2085
2086 SCIPrationalDiff(lhs[pos], row->lhs, row->constant);
2087 SCIPrationalDiff(rhs[pos], row->rhs, row->constant);
2088 beg[pos] = nnonz;
2089 name[pos] = row->fprow->name;
2090
2091 SCIPrationalSetRational(row->flushedlhs, lhs[pos]);
2092 SCIPrationalSetRational(row->flushedrhs, rhs[pos]);
2093
2094 SCIPrationalDebugMessage("flushing added row (SCIP_LPI): %q <=", lhs[pos]);
2095 for( i = 0; i < row->nlpcols; ++i )
2096 {
2097 assert(row->cols[i] != NULL);
2098 lpipos = row->cols[i]->lpipos;
2099 if( lpipos >= 0 )
2100 {
2101 assert(lpipos < lp->ncols);
2102 assert(nnonz < naddcoefs);
2103 SCIPrationalDebugMessage(" %q %d(<%s>)", row->vals[i], lpipos+1, SCIPvarGetName(row->cols[i]->fpcol->var));
2104 ind[nnonz] = lpipos;
2105 SCIPrationalSetRational(val[nnonz], row->vals[i]);
2106 nnonz++;
2107 }
2108 }
2109 SCIPrationalDebugMessage(" <= %q\n", rhs[pos]);
2110#ifndef NDEBUG
2111 for( i = row->nlpcols; i < row->len; ++i )
2112 {
2113 assert(row->cols[i] != NULL);
2114 assert(row->cols[i]->lpipos == -1); /* because the column deletions are already performed */
2115 }
2116#endif
2117 }
2118
2119 /* call LP interface */
2120 SCIPsetDebugMsg(set, "flushing row additions: enlarge LP from %d to %d rows\n", lp->nlpirows, lp->nrows);
2121 SCIP_CALL( SCIPlpiExactAddRows(lp->lpiexact, naddrows, lhs, rhs, name, nnonz, beg, ind, val) );
2122 lp->nlpirows = lp->nrows;
2123 lp->lpifirstchgrow = lp->nlpirows;
2124
2125 /* free temporary memory */
2129 SCIPrationalFreeBufferArray(set->buffer, &val, naddcoefs);
2130 SCIPrationalFreeBufferArray(set->buffer, &rhs, naddrows);
2131 SCIPrationalFreeBufferArray(set->buffer, &lhs, naddrows);
2132
2133 lp->flushaddedrows = TRUE;
2134
2135 /* mark the LP unsolved */
2136 lp->solved = FALSE;
2137 lp->primalfeasible = FALSE;
2138 lp->primalchecked = FALSE;
2140
2141 return SCIP_OKAY;
2142}
2143
2144/** applies all cached column bound and objective changes to the LP */
2145static
2147 SCIP_LPEXACT* lp, /**< current LP data */
2148 SCIP_SET* set /**< global SCIP settings */
2149 )
2150{
2151#ifndef NDEBUG
2152 SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
2153#endif
2154 SCIP_COLEXACT* col;
2155 int* objind;
2156 int* bdind;
2157 SCIP_RATIONAL** obj;
2158 SCIP_RATIONAL** lb;
2159 SCIP_RATIONAL** ub;
2160 int nobjchg;
2161 int nbdchg;
2162 int i;
2163
2164 assert(lp != NULL);
2165
2166 if( lp->nchgcols == 0 )
2167 return SCIP_OKAY;
2168
2169 /* get temporary memory for changes */
2170 SCIP_CALL( SCIPsetAllocBufferArray(set, &objind, lp->ncols) );
2171 SCIP_CALL( SCIPsetAllocBufferArray(set, &bdind, lp->ncols) );
2172 SCIP_CALL( SCIPrationalCreateBufferArray(set->buffer, &obj, lp->ncols) );
2173 SCIP_CALL( SCIPrationalCreateBufferArray(set->buffer, &lb, lp->ncols) );
2174 SCIP_CALL( SCIPrationalCreateBufferArray(set->buffer, &ub, lp->ncols) );
2175
2176 /* collect all cached bound and objective changes */
2177 nobjchg = 0;
2178 nbdchg = 0;
2179 for( i = 0; i < lp->nchgcols; ++i )
2180 {
2181 col = lp->chgcols[i];
2182 assert(col != NULL);
2183 assert(col->var != NULL);
2185 assert(SCIPvarGetColExact(col->var) == col);
2186
2187 if( col->lpipos >= 0 )
2188 {
2189#ifndef NDEBUG
2190 /* do not check consistency of data with LPI in case of LPI=none */
2191 if( !lpinone )
2192 {
2193 SCIP_RATIONAL* lpiobj;
2194 SCIP_RATIONAL* lpiub;
2195 SCIP_RATIONAL* lpilb;
2196
2197 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &lpiobj) );
2198 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &lpilb) );
2199 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &lpiub) );
2200
2201 SCIP_CALL( SCIPlpiExactGetObj(lp->lpiexact, col->lpipos, col->lpipos, &lpiobj) );
2202 SCIP_CALL( SCIPlpiExactGetBounds(lp->lpiexact, col->lpipos, col->lpipos, &lpilb, &lpiub) );
2203 assert(SCIPrationalIsEQ(lpiobj, col->flushedobj));
2204 SCIPrationalFreeBuffer(set->buffer, &lpiub);
2205 SCIPrationalFreeBuffer(set->buffer, &lpilb);
2206 SCIPrationalFreeBuffer(set->buffer, &lpiobj);
2207 }
2208#endif
2209
2210 if( col->objchanged )
2211 {
2212 if( SCIPrationalIsEQ(col->flushedobj, col->obj) ) /*lint !e777*/
2213 {
2214 assert(nobjchg < lp->ncols);
2215 objind[nobjchg] = col->lpipos;
2216 SCIPrationalSetRational(obj[nobjchg], col->obj);
2217 nobjchg++;
2219 }
2220 col->objchanged = FALSE;
2221 }
2222
2223 if( col->lbchanged || col->ubchanged )
2224 {
2225 if( !SCIPrationalIsEQ(col->flushedlb, col->lb) || !SCIPrationalIsEQ(col->flushedub, col->ub) ) /*lint !e777*/
2226 {
2227 assert(nbdchg < lp->ncols);
2228 bdind[nbdchg] = col->lpipos;
2229 SCIPrationalSetRational(lb[nbdchg], col->lb);
2230 SCIPrationalSetRational(ub[nbdchg], col->ub);
2231 nbdchg++;
2234 }
2235 col->lbchanged = FALSE;
2236 col->ubchanged = FALSE;
2237 }
2238 }
2239 /* maybe lb/ub/objchanged should all be set to false when lpipos is -1 */
2240 }
2241
2242 /* change objective values in LP */
2243 if( nobjchg > 0 )
2244 {
2245 SCIPsetDebugMsg(set, "flushing objective changes: change %d objective values of %d changed columns\n", nobjchg, lp->nchgcols);
2246 SCIP_CALL( SCIPlpiExactChgObj(lp->lpiexact, nobjchg, objind, obj) );
2247
2248 /* mark the LP unsolved */
2249 lp->solved = FALSE;
2250 lp->dualfeasible = FALSE;
2251 lp->dualchecked = FALSE;
2253 }
2254
2255 /* change bounds in LP */
2256 if( nbdchg > 0 )
2257 {
2258 SCIPsetDebugMsg(set, "flushing bound changes: change %d bounds of %d changed columns\n", nbdchg, lp->nchgcols);
2259 SCIP_CALL( SCIPlpiExactChgBounds(lp->lpiexact, nbdchg, bdind, lb, ub) );
2260
2261 /* mark the LP unsolved */
2262 lp->solved = FALSE;
2263 lp->primalfeasible = FALSE;
2264 lp->primalchecked = FALSE;
2266 }
2267
2268 lp->nchgcols = 0;
2269
2270 /* free temporary memory */
2271 SCIPrationalFreeBufferArray(set->buffer, &ub, lp->ncols);
2272 SCIPrationalFreeBufferArray(set->buffer, &lb, lp->ncols);
2273 SCIPrationalFreeBufferArray(set->buffer, &obj, lp->ncols);
2274 SCIPsetFreeBufferArray(set, &bdind);
2275 SCIPsetFreeBufferArray(set, &objind);
2276
2277 return SCIP_OKAY;
2278}
2279
2280/** applies all cached row side changes to the LP */
2281static
2283 SCIP_LPEXACT* lp, /**< current LP data */
2284 SCIP_SET* set /**< global SCIP settings */
2285 )
2286{
2287#ifndef NDEBUG
2288 SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
2289#endif
2290 SCIP_ROWEXACT* row;
2291 int* ind;
2292 SCIP_RATIONAL** lhs;
2293 SCIP_RATIONAL** rhs;
2294 int i;
2295 int nchg;
2296
2297 assert(lp != NULL);
2298
2299 if( lp->nchgrows == 0 )
2300 return SCIP_OKAY;
2301
2302 /* get temporary memory for changes */
2304 SCIP_CALL( SCIPrationalCreateBufferArray(set->buffer, &lhs, lp->nrows) );
2305 SCIP_CALL( SCIPrationalCreateBufferArray(set->buffer, &rhs, lp->nrows) );
2306
2307 /* collect all cached left and right hand side changes */
2308 nchg = 0;
2309 for( i = 0; i < lp->nchgrows; ++i )
2310 {
2311 row = lp->chgrows[i];
2312 assert(row != NULL);
2313
2314 if( row->lpipos >= 0 )
2315 {
2316#ifndef NDEBUG
2317 /* do not check consistency of data with LPI in case of LPI=none */
2318 if( !lpinone )
2319 {
2320 SCIP_RATIONAL* lpirhs;
2321 SCIP_RATIONAL* lpilhs;
2322
2323 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &lpilhs) );
2324 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &lpirhs) );
2325
2326 SCIP_CALL( SCIPlpiExactGetSides(lp->lpiexact, row->lpipos, row->lpipos, &lpilhs, &lpirhs) );
2327 assert(SCIPrationalIsEQ(lpilhs, row->flushedlhs));
2328 assert(SCIPrationalIsEQ(lpirhs, row->flushedrhs));
2329
2330 SCIPrationalFreeBuffer(set->buffer, &lpirhs);
2331 SCIPrationalFreeBuffer(set->buffer, &lpilhs);
2332 }
2333#endif
2334 if( row->lhschanged || row->rhschanged )
2335 {
2336 SCIP_RATIONAL* newlhs;
2337 SCIP_RATIONAL* newrhs;
2338
2339 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &newlhs) );
2340 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &newrhs) );
2341
2342 SCIPrationalDiff(newlhs, row->lhs, row->constant);
2343 SCIPrationalDiff(newrhs, row->rhs, row->constant);
2344 if( SCIPrationalIsEQ(row->flushedlhs, newlhs) || SCIPrationalIsEQ(row->flushedrhs, newrhs) ) /*lint !e777*/
2345 {
2346 assert(nchg < lp->nrows);
2347 ind[nchg] = row->lpipos;
2348 SCIPrationalSetRational(lhs[nchg], newlhs);
2349 SCIPrationalSetRational(rhs[nchg], newrhs);
2350 nchg++;
2351 SCIPrationalSetRational(row->flushedlhs, newlhs);
2352 SCIPrationalSetRational(row->flushedrhs, newrhs);
2353 }
2354 row->lhschanged = FALSE;
2355 row->rhschanged = FALSE;
2356
2357 SCIPrationalFreeBuffer(set->buffer, &newrhs);
2358 SCIPrationalFreeBuffer(set->buffer, &newlhs);
2359 }
2360 }
2361 }
2362
2363 /* change left and right hand sides in LP */
2364 if( nchg > 0 )
2365 {
2366 SCIPsetDebugMsg(set, "flushing side changes: change %d sides of %d exact rows\n", nchg, lp->nchgrows);
2367 SCIP_CALL( SCIPlpiExactChgSides(lp->lpiexact, nchg, ind, lhs, rhs) );
2368
2369 /* mark the LP unsolved */
2370 lp->solved = FALSE;
2371 lp->primalfeasible = FALSE;
2372 lp->primalchecked = FALSE;
2374 }
2375
2376 lp->nchgrows = 0;
2377
2378 /* free temporary memory */
2379 SCIPrationalFreeBufferArray(set->buffer, &rhs, lp->nrows);
2380 SCIPrationalFreeBufferArray(set->buffer, &lhs, lp->nrows);
2382
2383 return SCIP_OKAY;
2384}
2385
2386/** gets finite part of objective value of current LP that results from LOOSE variables only.
2387 * returns reference, so be careful not to change!
2388 */
2389static
2391 SCIP_LPEXACT* lp, /**< current LP data */
2392 SCIP_SET* set, /**< global SCIP settings */
2393 SCIP_PROB* prob /**< problem data */
2394 )
2395{
2396 assert(lp != NULL);
2397 assert(set != NULL);
2398 assert(prob != NULL);
2399 assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && SCIPrationalIsZero(lp->looseobjval)));
2400 assert(lp->looseobjvalinf == 0);
2401
2402 return lp->looseobjval;
2403}
2404
2405/*
2406 * Column methods
2407 */
2408
2409/** creates an LP column */
2411 SCIP_COLEXACT** col, /**< pointer to column data */
2412 SCIP_COL* fpcol, /**< the corresponding fp col */
2413 BMS_BLKMEM* blkmem, /**< block memory */
2414 SCIP_SET* set, /**< global SCIP settings */
2415 SCIP_STAT* stat, /**< problem statistics */
2416 SCIP_VAR* var, /**< variable, this column represents */
2417 int len, /**< number of nonzeros in the column */
2418 SCIP_ROWEXACT** rows, /**< array with rows of column entries */
2419 SCIP_RATIONAL** vals, /**< array with coefficients of column entries */
2420 SCIP_Bool removable /**< should the column be removed from the LP due to aging or cleanup? */
2421 )
2422{
2423 int i;
2424
2425 assert(col != NULL);
2426 assert(fpcol != NULL);
2427 assert(blkmem != NULL);
2428 assert(set != NULL);
2429 assert(stat != NULL);
2430 assert(var != NULL);
2431 assert(len >= 0);
2432 assert(len == 0 || (vals != NULL));
2433
2434 SCIP_ALLOC( BMSallocBlockMemory(blkmem, col) );
2435
2436 (*col)->fpcol = fpcol;
2437
2438 if( len > 0 )
2439 {
2440 SCIP_CALL( SCIPrationalCopyBlockArray(blkmem, &(*col)->vals, vals, len) );
2441 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*col)->linkpos, len) );
2442 SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*col)->rows, rows, len) );
2443
2444 for( i = 0; i < len; ++i )
2445 {
2446 assert(!SCIPrationalIsZero(vals[i]));
2447 assert(rows[i] != NULL);
2448 (*col)->linkpos[i] = -1;
2449 }
2450 }
2451 else
2452 {
2453 (*col)->rows = NULL;
2454 (*col)->vals = NULL;
2455 (*col)->linkpos = NULL;
2456 }
2457
2458 (*col)->var = var;
2459 SCIP_CALL( SCIPrationalCopyBlock(blkmem, &(*col)->obj, SCIPvarGetObjExact(var)) );
2460 SCIP_CALL( SCIPrationalCopyBlock(blkmem, &(*col)->lb, SCIPvarGetLbLocalExact(var)) );
2461 SCIP_CALL( SCIPrationalCopyBlock(blkmem, &(*col)->ub, SCIPvarGetUbLocalExact(var)) );
2462 (*col)->index = (*col)->fpcol->index;
2463 SCIP_CALL( SCIPrationalCreateBlock(blkmem, &(*col)->flushedobj) );
2464 SCIP_CALL( SCIPrationalCreateBlock(blkmem, &(*col)->flushedlb) );
2465 SCIP_CALL( SCIPrationalCreateBlock(blkmem, &(*col)->flushedub) );
2466 SCIP_CALL( SCIPrationalCreateBlock(blkmem, &(*col)->primsol) );
2467 SCIP_CALL( SCIPrationalCreateString(blkmem, &(*col)->redcost, "inf") );
2468 SCIP_CALL( SCIPrationalCreateString(blkmem, &(*col)->farkascoef, "inf") );
2469
2470 (*col)->storedsolvals = NULL;
2471 (*col)->size = len;
2472 (*col)->len = len;
2473 (*col)->nlprows = 0;
2474 (*col)->lprowssorted = 0;
2475 (*col)->nunlinked = len;
2476 (*col)->lppos = -1;
2477 (*col)->lpipos = -1;
2478 (*col)->validredcostlp = -1;
2479 (*col)->validfarkaslp = -1;
2480
2481 assert((*col)->fpcol->removable == removable);
2482
2483 return SCIP_OKAY;
2484}
2485
2486/** sets parameter of type SCIP_Real in exact LP solver, ignoring unknown parameters */
2487static
2489 SCIP_LPEXACT* lp, /**< current LP data */
2490 SCIP_LPPARAM lpparam, /**< LP parameter */
2491 SCIP_Real value, /**< value to set parameter to */
2492 SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2493 )
2494{
2495 SCIP_RETCODE retcode;
2496
2497 assert(lp != NULL);
2498 assert(success != NULL);
2499
2500 retcode = SCIPlpiExactSetRealpar(lp->lpiexact, lpparam, value);
2501
2502 /* check, if parameter is unknown */
2503 if( retcode == SCIP_PARAMETERUNKNOWN )
2504 {
2505 *success = FALSE;
2506 return SCIP_OKAY;
2507 }
2508 *success = TRUE;
2509
2510 return retcode;
2511}
2512
2513/** sets parameter of type SCIP_Real in exact LP solver, ignoring unknown parameters */
2514static
2516 SCIP_LPEXACT* lp, /**< current LP data */
2517 SCIP_LPPARAM lpparam, /**< LP parameter */
2518 int value, /**< value to set parameter to */
2519 SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2520 )
2521{
2522 SCIP_RETCODE retcode;
2523
2524 assert(lp != NULL);
2525 assert(success != NULL);
2526
2527 retcode = SCIPlpiExactSetIntpar(lp->lpiexact, lpparam, value);
2528
2529 /* check, if parameter is unknown */
2530 if( retcode == SCIP_PARAMETERUNKNOWN )
2531 {
2532 *success = FALSE;
2533 return SCIP_OKAY;
2534 }
2535 *success = TRUE;
2536
2537 return retcode;
2538}
2539
2540/** sets the objective limit of the exact LP solver
2541 *
2542 * Note that we are always minimizing.
2543 */
2544static
2546 SCIP_LPEXACT* lp, /**< current LP data */
2547 SCIP_SET* set, /**< global SCIP settings */
2548 SCIP_Real objlim, /**< new objective limit */
2549 SCIP_Bool* success /**< pointer to store whether the parameter was actually changed */
2550 )
2551{
2552 assert(lp != NULL);
2553 assert(set != NULL);
2554 assert(success != NULL);
2555
2556 *success = FALSE;
2557
2558 /* We disabled the objective limit in the LP solver or we want so solve exactly and thus cannot rely on the LP
2559 * solver's objective limit handling, so we return here and do not apply the objective limit. */
2560 if( set->lp_disablecutoff == 1 || (set->nactivepricers > 0 && set->lp_disablecutoff == 2) )
2561 return SCIP_OKAY;
2562
2563 /* convert SCIP infinity value to lp-solver infinity value if necessary */
2564 if( SCIPsetIsInfinity(set, objlim) )
2565 objlim = SCIPlpiExactInfinity(lp->lpiexact);
2566
2567 if( objlim != lp->lpiobjlim ) /*lint !e777*/
2568 {
2569 SCIP_CALL( lpExactSetRealpar(lp, SCIP_LPPAR_OBJLIM, objlim, success) );
2570 if( *success )
2571 {
2572 SCIP_Real actualobjlim;
2573
2574 /* check whether the parameter was actually changed or already was at the boundary of the LP solver's parameter range */
2576 if( actualobjlim != lp->lpiobjlim ) /*lint !e777*/
2577 {
2578 /* mark the current solution invalid */
2579 lp->solved = FALSE;
2580 lp->primalfeasible = FALSE;
2581 lp->primalchecked = FALSE;
2584 }
2585 lp->lpiobjlim = actualobjlim;
2586 }
2587 }
2588
2589 return SCIP_OKAY;
2590}
2591
2592/** sets the iteration limit of the LP solver */
2593static
2595 SCIP_LPEXACT* lp, /**< current LP data */
2596 int itlim /**< maximal number of LP iterations to perform, or -1 for no limit */
2597 )
2598{
2599 SCIP_Bool success;
2600
2601 assert(lp != NULL);
2602 assert(itlim >= -1);
2603
2604 if( itlim == -1 )
2605 itlim = INT_MAX;
2606
2607 if( itlim != lp->lpiitlim )
2608 {
2609 SCIP_CALL( lpExactSetIntpar(lp, SCIP_LPPAR_LPITLIM, itlim, &success) );
2610 if( success )
2611 {
2612 if( itlim > lp->lpiitlim )
2613 {
2614 /* mark the current solution invalid */
2615 lp->solved = FALSE;
2618 }
2619 lp->lpiitlim = itlim;
2620 }
2621 }
2622
2623 return SCIP_OKAY;
2624}
2625
2626/** resets row data to represent a row not in the LP solver */
2627static
2629 SCIP_ROWEXACT* row /**< row to be marked deleted */
2630 )
2631{
2632 assert(row != NULL);
2633
2634 row->lpipos = -1;
2635 SCIPrationalSetReal(row->dualsol, 0.0);
2638 row->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
2639 row->validactivitylp = -1;
2640}
2641
2642/** deletes the marked rows from the LP and the LP interface */
2644 SCIP_LPEXACT* lpexact, /**< current LP data */
2645 BMS_BLKMEM* blkmem, /**< block memory buffers */
2646 SCIP_SET* set, /**< global SCIP settings */
2647 int* rowdstat /**< deletion status of rows: 1 if row should be deleted, 0 if not */
2648 )
2649{
2650 SCIP_ROWEXACT* row;
2651 int nrows;
2652 int nlpirows;
2653 int r;
2654 int c;
2655
2656 assert(lpexact != NULL);
2657 assert(rowdstat != NULL);
2658
2659 nrows = lpexact->nrows;
2660 nlpirows = lpexact->nlpirows;
2661 if( nlpirows == 0 )
2662 return SCIP_OKAY;
2663
2664 /* delete rows in LP solver */
2665 SCIP_CALL( SCIPlpiExactDelRowset(lpexact->lpiexact, rowdstat) );
2666
2667 /* set the correct status for rows that never made it to the lpi (this is special for the exact lp) */
2668 c = lpexact->nlpirows - 1;
2669 while( rowdstat[c] == -1 )
2670 {
2671 c--;
2672 }
2673
2674 c = rowdstat[c] + 1;
2675 for( r = lpexact->nlpirows; r < nrows; r++ )
2676 {
2677 if( rowdstat[r] != 1 )
2678 {
2679 rowdstat[r] = c;
2680 ++c;
2681 }
2682 else
2683 rowdstat[r] = -1;
2684 }
2685
2686 /* update LP data respectively */
2687 for( r = 0; r < nrows; ++r )
2688 {
2689 row = lpexact->rows[r];
2690 assert(rowdstat[r] <= r);
2691 assert(row != NULL);
2692 row->lppos = rowdstat[r];
2693 if( rowdstat[r] == -1 )
2694 {
2695 if( row->removable )
2696 lpexact->nremovablerows--;
2697
2698 /* mark row to be deleted from the LPI and update row arrays of all linked columns */
2701 row->lpdepth = -1;
2702
2703 /* only release lpirows if they actually exist */
2704 if( r < nlpirows )
2705 {
2706 assert(row == lpexact->lpirows[r]);
2707
2708 SCIP_CALL( SCIProwExactRelease(&lpexact->lpirows[r], blkmem, set, lpexact) );
2709 lpexact->nlpirows--;
2710 }
2711 SCIP_CALL( SCIProwExactRelease(&lpexact->rows[r], blkmem, set, lpexact) );
2712 assert(lpexact->rows[r] == NULL);
2713 lpexact->nrows--;
2714 }
2715 else if( rowdstat[r] < r )
2716 {
2717 assert(lpexact->rows[rowdstat[r]] == NULL);
2718 assert(lpexact->lpirows[rowdstat[r]] == NULL);
2719 lpexact->rows[rowdstat[r]] = row;
2720
2721 /* only re-order lpirows if they actually exist */
2722 if( r < nlpirows )
2723 {
2724 lpexact->lpirows[rowdstat[r]] = row;
2725 lpexact->lpirows[r] = NULL;
2726 }
2727 lpexact->rows[rowdstat[r]]->lppos = rowdstat[r];
2728 lpexact->rows[rowdstat[r]]->lpipos = rowdstat[r];
2729 lpexact->rows[r] = NULL;
2730 }
2731 }
2732
2733 /* mark LP to be unsolved */
2734 if( lpexact->nrows < nrows )
2735 {
2736 assert(lpexact->nchgrows == 0);
2737
2738 lpexact->lpifirstchgrow = lpexact->nlpirows;
2739
2740 /* mark the current solution invalid */
2741 lpexact->solved = FALSE;
2742 lpexact->dualfeasible = FALSE;
2743 lpexact->dualchecked = FALSE;
2746 }
2747
2748 checkLinks(lpexact);
2749
2750 return SCIP_OKAY;
2751}
2752
2753/** frees an LP column */
2755 SCIP_COLEXACT** col, /**< pointer to LP column */
2756 BMS_BLKMEM* blkmem /**< block memory */
2757 )
2758{
2759 assert(blkmem != NULL);
2760 assert(col != NULL);
2761 assert(*col != NULL);
2762 assert((*col)->fpcol != NULL);
2763
2764 if( (*col)->size > 0 )
2765 {
2766 SCIPrationalFreeBlockArray(blkmem, &(*col)->vals, (*col)->size);
2767 BMSfreeBlockMemoryArray(blkmem, &(*col)->linkpos, (*col)->size);
2768 BMSfreeBlockMemoryArray(blkmem, &(*col)->rows, (*col)->size);
2769 }
2770 else
2771 assert((*col)->vals == NULL);
2772
2773 if( (*col)->storedsolvals != NULL )
2774 {
2775 SCIPrationalFreeBlock(blkmem, &(*col)->storedsolvals->primsol);
2776 SCIPrationalFreeBlock(blkmem, &(*col)->storedsolvals->redcost);
2777 BMSfreeBlockMemoryNull(blkmem, &(*col)->storedsolvals);
2778 }
2779
2780 SCIPrationalFreeBlock(blkmem, &(*col)->obj);
2781 SCIPrationalFreeBlock(blkmem, &(*col)->lb);
2782 SCIPrationalFreeBlock(blkmem, &(*col)->ub);
2783 SCIPrationalFreeBlock(blkmem, &(*col)->flushedobj);
2784 SCIPrationalFreeBlock(blkmem, &(*col)->flushedlb);
2785 SCIPrationalFreeBlock(blkmem, &(*col)->flushedub);
2786 SCIPrationalFreeBlock(blkmem, &(*col)->primsol);
2787 SCIPrationalFreeBlock(blkmem, &(*col)->redcost);
2788 SCIPrationalFreeBlock(blkmem, &(*col)->farkascoef);
2789
2790 BMSfreeBlockMemory(blkmem, col);
2791
2792 return SCIP_OKAY;
2793}
2794
2795/** output column to file stream */
2797 SCIP_COLEXACT* col, /**< LP column */
2798 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
2799 FILE* file /**< output file (or NULL for standard output) */
2800 )
2801{
2802 int r;
2803
2804 assert(col != NULL);
2805 assert(col->fpcol != NULL);
2806 assert(col->fpcol->var != NULL);
2807
2808 SCIPmessageFPrintInfo(messagehdlr, file, "(obj:");
2809 SCIPrationalMessage(messagehdlr, file, col->obj);
2810 SCIPmessageFPrintInfo(messagehdlr, file, ") [");
2811 SCIPrationalMessage(messagehdlr, file, col->lb);
2812 SCIPmessageFPrintInfo(messagehdlr, file, ", ");
2813 SCIPrationalMessage(messagehdlr, file, col->ub);
2814 SCIPmessageFPrintInfo(messagehdlr, file, "], ");
2815
2816 /* print coefficients */
2817 if( col->len == 0 )
2818 SCIPmessageFPrintInfo(messagehdlr, file, "<empty>");
2819 for( r = 0; r < col->len; ++r )
2820 {
2821 assert(col->rows[r] != NULL);
2822 assert(col->rows[r]->fprow->name != NULL);
2823
2824 if( SCIPrationalIsPositive(col->vals[r]) )
2825 SCIPmessageFPrintInfo(messagehdlr, file, "+");
2826
2827 SCIPrationalMessage(messagehdlr, file, col->vals[r]);
2828 SCIPmessageFPrintInfo(messagehdlr, file, "<%s> ", col->rows[r]->fprow->name);
2829 }
2830 SCIPmessageFPrintInfo(messagehdlr, file, "\n");
2831}
2832
2833/** adds a previously non existing coefficient to an LP column */
2835 SCIP_COLEXACT* col, /**< LP column */
2836 BMS_BLKMEM* blkmem, /**< block memory */
2837 SCIP_SET* set, /**< global SCIP settings */
2838 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2839 SCIP_LPEXACT* lpexact, /**< current LP data */
2840 SCIP_ROWEXACT* row, /**< LP row */
2841 SCIP_RATIONAL* val /**< value of coefficient */
2842 )
2843{
2844 assert(lpexact != NULL);
2845
2846 SCIP_CALL( colExactAddCoef(col, blkmem, set, eventqueue, lpexact, row, val, -1) );
2847
2848 return SCIP_OKAY;
2849}
2850
2851/** deletes coefficient from column */
2853 SCIP_COLEXACT* col, /**< column to be changed */
2854 SCIP_SET* set, /**< global SCIP settings */
2855 SCIP_LPEXACT* lpexact, /**< current LP data */
2856 SCIP_ROWEXACT* row /**< coefficient to be deleted */
2857 )
2858{
2859 int pos;
2860
2861 assert(col != NULL);
2862 assert(col->var != NULL);
2863 assert(lpexact != NULL);
2864 assert(row != NULL);
2865
2866 /* search the position of the row in the column's row vector */
2867 pos = colExactSearchCoef(col, row);
2868 if( pos == -1 )
2869 {
2870 SCIPerrorMessage("coefficient for row <%s> doesn't exist in column <%s>\n", row->fprow->name, SCIPvarGetName(col->var));
2871 return SCIP_INVALIDDATA;
2872 }
2873 assert(0 <= pos && pos < col->fpcol->len);
2874 assert(col->rows[pos] == row);
2875
2876 /* if row knows of the column, remove the column from the row's col vector */
2877 if( col->linkpos[pos] >= 0 )
2878 {
2879 assert(row->cols[col->linkpos[pos]] == col);
2880 assert(row->cols_index[col->linkpos[pos]] == col->index);
2881 assert(SCIPrationalIsEQ(row->vals[col->linkpos[pos]], col->vals[pos]));
2882 SCIP_CALL( rowExactDelCoefPos(row, set, lpexact, col->linkpos[pos]) );
2883 }
2884
2885 /* delete the row from the column's row vector */
2886 SCIP_CALL( colExactDelCoefPos(col, set, lpexact, pos) );
2887
2888 checkLinks(lpexact);
2889
2890 return SCIP_OKAY;
2891}
2892
2893/** changes or adds a coefficient to an LP column */
2895 SCIP_COLEXACT* col, /**< LP column */
2896 BMS_BLKMEM* blkmem, /**< block memory */
2897 SCIP_SET* set, /**< global SCIP settings */
2898 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2899 SCIP_LPEXACT* lpexact, /**< current LP data */
2900 SCIP_ROWEXACT* row, /**< LP row */
2901 SCIP_RATIONAL* val /**< value of coefficient */
2902 )
2903{
2904 int pos;
2905
2906 assert(col != NULL);
2907 assert(lpexact != NULL);
2908 assert(!lpexact->fplp->diving);
2909 assert(row != NULL);
2910
2911 /* search the position of the row in the column's row vector */
2912 pos = colExactSearchCoef(col, row);
2913
2914 /* check, if row already exists in the column's row vector */
2915 if( pos == -1 )
2916 {
2917 /* add previously not existing coefficient */
2918 SCIP_CALL( colExactAddCoef(col, blkmem, set, eventqueue, lpexact, row, val, -1) );
2919 }
2920 else
2921 {
2922 /* modify already existing coefficient */
2923 assert(0 <= pos && pos < col->len);
2924 assert(col->rows[pos] == row);
2925
2926 /* if row knows of the column, change the corresponding coefficient in the row */
2927 if( col->linkpos[pos] >= 0 )
2928 {
2929 assert(row->cols[col->linkpos[pos]] == col);
2930 assert(row->cols_index[col->linkpos[pos]] == col->index);
2931 assert(SCIPrationalIsEQ(row->vals[col->linkpos[pos]], col->vals[pos]));
2932 SCIP_CALL( rowExactChgCoefPos(row, set, lpexact, col->linkpos[pos], val) );
2933 }
2934
2935 /* change the coefficient in the column */
2936 SCIP_CALL( colExactChgCoefPos(col, set, lpexact, pos, val) );
2937 }
2938
2939 checkLinks(lpexact);
2940
2941 return SCIP_OKAY;
2942}
2943
2944/** increases value of an existing or nonexisting coefficient in an LP column */
2946 SCIP_COLEXACT* col, /**< LP column */
2947 BMS_BLKMEM* blkmem, /**< block memory */
2948 SCIP_SET* set, /**< global SCIP settings */
2949 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2950 SCIP_LPEXACT* lpexact, /**< current LP data */
2951 SCIP_ROWEXACT* row, /**< LP row */
2952 SCIP_RATIONAL* incval /**< value to add to the coefficient */
2953 )
2954{
2955 int pos;
2956
2957 assert(col != NULL);
2958 assert(lpexact != NULL);
2959 assert(!lpexact->fplp->diving);
2960 assert(row != NULL);
2961
2962 if( SCIPrationalIsZero(incval) )
2963 return SCIP_OKAY;
2964
2965 /* search the position of the row in the column's row vector */
2966 pos = colExactSearchCoef(col, row);
2967
2968 /* check, if row already exists in the column's row vector */
2969 if( pos == -1 )
2970 {
2971 /* add previously not existing coefficient */
2972 SCIP_CALL( colExactAddCoef(col, blkmem, set, eventqueue, lpexact, row, incval, -1) );
2973 }
2974 else
2975 {
2976 /* modify already existing coefficient */
2977 assert(0 <= pos && pos < col->len);
2978 assert(col->rows[pos] == row);
2979
2980 /* if row knows of the column, change the corresponding coefficient in the row */
2981 if( col->linkpos[pos] >= 0 )
2982 {
2983 assert(row->cols[col->linkpos[pos]] == col);
2984 assert(row->cols_index[col->linkpos[pos]] == col->index);
2985 assert(SCIPrationalIsEQ(row->vals[col->linkpos[pos]], col->vals[pos]));
2986
2987 SCIPrationalAdd(incval, incval, col->vals[pos]);
2988 SCIP_CALL( rowExactChgCoefPos(row, set, lpexact, col->linkpos[pos], incval) );
2989 }
2990
2991 /* change the coefficient in the column */
2992 SCIP_CALL( colExactChgCoefPos(col, set, lpexact, pos, incval) );
2993 }
2994
2995 checkLinks(lpexact);
2996
2997 return SCIP_OKAY;
2998}
2999
3000/** changes objective value of column */
3002 SCIP_COLEXACT* col, /**< LP column to change */
3003 SCIP_SET* set, /**< global SCIP settings */
3004 SCIP_LPEXACT* lpexact, /**< current LP data */
3005 SCIP_RATIONAL* newobj /**< new objective value */
3006 )
3007{
3008 assert(col != NULL);
3009 assert(col->var != NULL);
3011 assert(SCIPvarGetColExact(col->var) == col);
3012 assert(lpexact != NULL);
3013
3014 SCIPrationalDebugMessage("changing objective value of column <%s> from %q to %q\n", SCIPvarGetName(col->var), col->obj, newobj);
3015
3016 /* only add actual changes */
3017 if( !SCIPrationalIsEQ(col->obj, newobj) )
3018 {
3019 /* only variables with a real position in the LPI can be inserted */
3020 if( col->lpipos >= 0 )
3021 {
3022 /* insert column in the chgcols list (if not already there) */
3023 SCIP_CALL( insertColChgcols(col, set, lpexact) );
3024
3025 /* mark objective value change in the column */
3026 col->objchanged = TRUE;
3027
3028 assert(lpexact->nchgcols > 0);
3029 }
3030 /* in any case, when the sign of the objective (and thereby the best bound) changes, the variable has to enter the
3031 * LP and the LP has to be flushed
3032 */
3033 else if( (SCIPrationalIsNegative(col->obj) && SCIPrationalIsPositive(newobj) && SCIPrationalIsZero(col->ub))
3035 {
3036 /* mark the LP unflushed */
3037 lpexact->flushed = FALSE;
3038 }
3039 }
3040
3041 /* store new objective function value */
3042 SCIPrationalSetRational(col->obj, newobj);
3043
3044 return SCIP_OKAY;
3045}
3046
3047/** changes lower bound of column */
3049 SCIP_COLEXACT* col, /**< LP column to change */
3050 SCIP_SET* set, /**< global SCIP settings */
3051 SCIP_LPEXACT* lpexact, /**< current LP data */
3052 SCIP_RATIONAL* newlb /**< new lower bound value */
3053 )
3054{
3055 assert(col != NULL);
3056 assert(col->var != NULL);
3058 assert(SCIPvarGetColExact(col->var) == col);
3059 assert(lpexact != NULL);
3060
3061 SCIPrationalDebugMessage("changing lower bound of column <%s> from %q to %q\n", SCIPvarGetName(col->var), col->lb, newlb);
3062
3063 /* only add actual changes */
3064 if( !SCIPrationalIsEQ(col->lb, newlb) )
3065 {
3066 /* only variables with a real position in the LPI can be inserted */
3067 if( col->lpipos >= 0 )
3068 {
3069 /* insert column in the chgcols list (if not already there) */
3070 SCIP_CALL( insertColChgcols(col, set, lpexact) );
3071
3072 /* mark bound change in the column */
3073 col->lbchanged = TRUE;
3074
3075 assert(lpexact->nchgcols > 0);
3076 }
3077 /* 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
3078 * flushed
3079 */
3080 else if( !SCIPrationalIsNegative(col->obj) && SCIPrationalIsZero(col->lb) )
3081 {
3082 /* mark the LP unflushed */
3083 lpexact->flushed = FALSE;
3084 }
3085 }
3086
3087 SCIPrationalSetRational(col->lb, newlb);
3088
3089 return SCIP_OKAY;
3090}
3091
3092/** changes upper bound of exact column */
3094 SCIP_COLEXACT* col, /**< LP column to change */
3095 SCIP_SET* set, /**< global SCIP settings */
3096 SCIP_LPEXACT* lpexact, /**< current LP data */
3097 SCIP_RATIONAL* newub /**< new upper bound value */
3098 )
3099{
3100 assert(col != NULL);
3101 assert(col->var != NULL);
3103 assert(SCIPvarGetColExact(col->var) == col);
3104 assert(lpexact != NULL);
3105
3106 SCIPrationalDebugMessage("changing upper bound of column <%s> from %q to %q\n", SCIPvarGetName(col->var), col->ub, newub);
3107
3108 /* only add actual changes */
3109 if( !SCIPrationalIsEQ(col->ub, newub) )
3110 {
3111 /* only variables with a real position in the LPI can be inserted */
3112 if( col->lpipos >= 0 )
3113 {
3114 /* insert column in the chgcols list (if not already there) */
3115 SCIP_CALL( insertColChgcols(col, set, lpexact) );
3116
3117 /* mark bound change in the column */
3118 col->ubchanged = TRUE;
3119
3120 assert(lpexact->nchgcols > 0);
3121 }
3122 /* 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
3123 * flushed
3124 */
3125 else if( SCIPrationalIsNegative(col->obj) && SCIPrationalIsZero(col->ub) )
3126 {
3127 /* mark the LP unflushed */
3128 lpexact->flushed = FALSE;
3129 }
3130 }
3131
3132 SCIPrationalSetRational(col->ub, newub);
3133
3134 return SCIP_OKAY;
3135}
3136
3137/** creates and captures an LP row */
3139 SCIP_ROWEXACT** row, /**< pointer to LP row data */
3140 SCIP_ROW* fprow, /**< corresponding fp row */
3141 SCIP_ROW* fprowrhs, /**< rhs-part of fp-relaxation of this row if necessary, NULL otherwise */
3142 BMS_BLKMEM* blkmem, /**< block memory */
3143 SCIP_SET* set, /**< global SCIP settings */
3144 SCIP_STAT* stat, /**< problem statistics */
3145 SCIP_LPEXACT* lpexact, /**< current LP data */
3146 int len, /**< number of nonzeros in the row */
3147 SCIP_COLEXACT** cols, /**< array with columns of row entries */
3148 SCIP_RATIONAL** vals, /**< array with coefficients of row entries */
3149 SCIP_RATIONAL* lhs, /**< left hand side of row */
3150 SCIP_RATIONAL* rhs, /**< right hand side of row */
3151 SCIP_Bool isfprelaxable /**< is it possible to make fp-relaxation of this row */
3152 ) /*lint --e{715}*/
3153{
3154 assert(row != NULL);
3155 assert(fprow != NULL);
3156 assert(blkmem != NULL);
3157 assert(stat != NULL);
3158 assert(len >= 0);
3159 assert(len == 0 || (cols != NULL && vals != NULL));
3160 assert(SCIProwGetNNonz(fprow) == len || len == 0);
3161 /* note, that the assert tries to avoid numerical troubles in the LP solver.
3162 * in case, for example, lhs > rhs but they are equal with tolerances, one could pass lhs=rhs=lhs+rhs/2 to
3163 * SCIProwCreate() (see cons_linear.c: detectRedundantConstraints())
3164 */
3165 assert(SCIPrationalIsLE(lhs, rhs));
3166
3167 SCIP_ALLOC( BMSallocBlockMemory(blkmem, row) );
3168
3169 (*row)->storedsolvals = NULL;
3170 (*row)->integral = TRUE;
3171 (*row)->fprow = fprow;
3172 (*row)->fprowrhs = fprowrhs;
3173 (*row)->nuses = 0;
3174 (*row)->nlocks = 0;
3175 fprow->rowexact = (*row);
3176 SCIProwExactCapture(*row);
3177 if( fprowrhs != NULL )
3178 {
3179 SCIProwExactCapture(*row);
3180 fprowrhs->rowexact = (*row);
3181 }
3182
3183 if( len > 0 )
3184 {
3185 SCIP_VAR* var;
3186 int i;
3187
3188 SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->cols, cols, len) );
3189 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*row)->cols_index, len) );
3190 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*row)->linkpos, len) );
3191 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*row)->valsinterval, len) );
3192 SCIP_CALL( SCIPrationalCopyBlockArray(blkmem, &(*row)->vals, vals, len) );
3193
3194 for( i = 0; i < len; ++i )
3195 {
3196 assert(cols[i] != NULL);
3197 assert(!SCIPrationalIsZero(vals[i]));
3198
3199 var = cols[i]->var;
3200 (*row)->cols_index[i] = cols[i]->index;
3201 (*row)->linkpos[i] = -1;
3202 SCIPintervalSetRational(&(*row)->valsinterval[i], vals[i]);
3203
3204 if( SCIPrationalIsIntegral((*row)->vals[i]) )
3205 (*row)->integral = (*row)->integral && SCIPvarIsIntegral(var);
3206 else
3207 {
3208 (*row)->integral = FALSE;
3209 }
3210 }
3211 }
3212 else
3213 {
3214 (*row)->cols = NULL;
3215 (*row)->vals = NULL;
3216 (*row)->valsinterval = NULL;
3217 (*row)->linkpos = NULL;
3218 (*row)->cols_index = NULL;
3219 }
3220
3221 SCIP_CALL( SCIPrationalCopyBlock(blkmem, &(*row)->lhs, lhs) );
3222 SCIP_CALL( SCIPrationalCopyBlock(blkmem, &(*row)->rhs, rhs) );
3223 SCIP_CALL( SCIPrationalCreateString(blkmem, &(*row)->flushedlhs, "-inf") );
3224 SCIP_CALL( SCIPrationalCreateString(blkmem, &(*row)->flushedrhs, "inf") );
3225 SCIP_CALL( SCIPrationalCreateString(blkmem, &(*row)->objprod, "0") );
3226 SCIP_CALL( SCIPrationalCreateString(blkmem, &(*row)->dualsol, "0") );
3227 SCIP_CALL( SCIPrationalCreateString(blkmem, &(*row)->activity, "inf") );
3228 SCIP_CALL( SCIPrationalCreateString(blkmem, &(*row)->dualfarkas, "0") );
3229 SCIP_CALL( SCIPrationalCreateString(blkmem, &(*row)->pseudoactivity, "inf") );
3230 SCIP_CALL( SCIPrationalCreateString(blkmem, &(*row)->constant, "0") );
3231
3232 (*row)->index = stat->nrowidx;
3233 SCIPstatIncrement(stat, set, nrowidx);
3234 (*row)->size = len;
3235 (*row)->len = len;
3236 (*row)->nlpcols = 0;
3237 (*row)->nunlinked = len;
3238 (*row)->lppos = -1;
3239 (*row)->lpipos = -1;
3240 (*row)->lpdepth = -1;
3241 (*row)->validactivitylp = -1;
3242 (*row)->delaysort = FALSE;
3243 (*row)->lpcolssorted = TRUE;
3244 (*row)->nonlpcolssorted = (len <= 1);
3245 (*row)->delaysort = FALSE;
3246 (*row)->fprelaxable = isfprelaxable;
3247 (*row)->rhsreal = SCIPrationalRoundReal((*row)->rhs, SCIP_R_ROUND_UPWARDS);
3248 (*row)->lhsreal = SCIPrationalRoundReal((*row)->lhs, SCIP_R_ROUND_DOWNWARDS);
3249 SCIPintervalSet(&(*row)->constantreal, 0.0);
3250 return SCIP_OKAY;
3251} /*lint !e715*/
3252
3253/** changes an exact row, so that all denominators are bounded by set->exact_cutmaxdenom */
3254static
3256 SCIP_ROW* row, /**< SCIP row */
3257 SCIP_ROWEXACT* rowexact, /**< exact row */
3258 SCIP_SET* set, /**< SCIP settings */
3259 BMS_BLKMEM* blkmem, /**< block memory structure */
3260 SCIP_EVENTQUEUE* eventqueue, /**< the eventqueue */
3261 SCIP_LPEXACT* lpexact /**< the exact lp */
3262 )
3263{
3264 int i;
3265 SCIP_Longint maxdenom;
3266 SCIP_Longint maxboundval;
3267 SCIP_RATIONAL* val;
3268 SCIP_RATIONAL* newval;
3269 SCIP_RATIONAL* difference;
3270 SCIP_Real rhschange;
3271 int forcegreater;
3272
3273 assert(row != NULL);
3274 assert(set->exact_cutmaxdenom > 0);
3275 assert(set->exact_cutapproxmaxboundval >= 0);
3276
3277 SCIPdebugMessage("approximating row ");
3278 SCIPdebug(SCIPprintRow(set->scip, row, NULL));
3279
3280 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &val) );
3281 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &difference) );
3282 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &newval) );
3283
3284 rhschange = 0;
3285 maxboundval = set->exact_cutapproxmaxboundval;
3286 maxdenom = set->exact_cutmaxdenom;
3287
3288 assert(maxdenom >= 0);
3289 assert(maxboundval >= 0);
3290
3291 for( i = 0; i <= row->len - 1; ++i )
3292 {
3293 SCIP_VAR* var = row->cols[i]->var;
3294 SCIPrationalSetReal(val, row->vals[i]);
3295
3296 forcegreater = 0;
3297
3299 forcegreater = -2;
3301 forcegreater = 1;
3303 forcegreater = -1;
3304
3305 if( forcegreater == -2 || SCIPrationalDenominatorIsLE(val, maxdenom) ||
3306 ((maxboundval > 0) && SCIPrationalIsGTReal(SCIPvarGetUbGlobalExact(var), (double) maxboundval)) ||
3307 SCIPrationalIsLTReal(SCIPvarGetLbGlobalExact(var), (double) -maxboundval) )
3308 {
3309 SCIPrationalSetRational(newval, val);
3310 }
3311 else
3312 SCIPrationalComputeApproximation(newval, val, maxdenom, forcegreater);
3313#ifndef NDEBUG
3314 if( forcegreater == 1 )
3315 assert(SCIPrationalIsGE(newval, val));
3316 else if( forcegreater == -1 )
3317 assert(SCIPrationalIsLE(newval, val));
3318#endif
3319
3320 SCIPrationalDiff(difference, newval, val);
3321 if( SCIPrationalIsPositive(difference) )
3322 SCIPrationalAddProd(rowexact->rhs, difference, SCIPvarGetUbGlobalExact(var));
3323 else
3324 SCIPrationalAddProd(rowexact->rhs, difference, SCIPvarGetLbGlobalExact(var));
3325
3326 if( !SCIPrationalIsZero(newval) )
3327 {
3328 SCIP_CALL( SCIProwExactAddCoef(rowexact, blkmem, set, eventqueue, lpexact, SCIPcolGetColExact(row->cols[i]), newval) );
3329 }
3330
3332 {
3333 rhschange += (SCIPintervalGetInf(rowexact->valsinterval[rowexact->len - 1]) - SCIPintervalGetSup(rowexact->valsinterval[rowexact->len - 1])) * SCIPvarGetLbGlobal(var);
3334 }
3335 }
3336
3337 SCIPrationalComputeApproximation(newval, rowexact->rhs, maxdenom, 1);
3338 assert(SCIPrationalIsGE(newval, rowexact->rhs));
3339
3340 SCIPrationalSetRational(rowexact->rhs, newval);
3341
3342 SCIProwExactSort(rowexact);
3343
3344 for( i = rowexact->fprow-> len-1; i >= 0; i-- )
3345 {
3346 SCIP_CALL( SCIProwDelCoef(rowexact->fprow, blkmem, set, eventqueue, lpexact->fplp, rowexact->fprow->cols[i]) );
3347 }
3348
3349 for( i = 0; i < rowexact->len; i++ )
3350 {
3351 SCIP_CALL( SCIProwAddCoef(rowexact->fprow, blkmem, set, eventqueue, lpexact->fplp, rowexact->cols[i]->fpcol,
3353 }
3354
3355 SCIP_CALL( SCIProwChgRhs(rowexact->fprow, blkmem, set, eventqueue, lpexact->fplp,
3356 SCIPrationalRoundReal(rowexact->rhs, SCIP_R_ROUND_UPWARDS) + rhschange) );
3357
3358 SCIPrationalFreeBuffer(set->buffer, &newval);
3359 SCIPrationalFreeBuffer(set->buffer, &difference);
3360 SCIPrationalFreeBuffer(set->buffer, &val);
3361
3362 SCIPdebugMessage("new row ");
3363 SCIPdebug(SCIPprintRowExact(set->scip, rowexact, NULL));
3364
3365 return SCIP_OKAY;
3366}
3367
3368/** creates and captures an exact LP row from a fp row
3369 *
3370 * @note This may change the floating-point coefficients slightly if the rational representation is rounded to smaller
3371 * denominators according to parameter exact/cutmaxdenom.
3372 */
3374 SCIP_ROW* fprow, /**< corresponding fp row to create from */
3375 BMS_BLKMEM* blkmem, /**< block memory */
3376 SCIP_SET* set, /**< global SCIP settings */
3377 SCIP_STAT* stat, /**< problem statistics */
3378 SCIP_EVENTQUEUE* eventqueue, /**< the eventqueue */
3379 SCIP_PROB* prob, /**< scip prob structure */
3380 SCIP_LPEXACT* lpexact /**< current LP data */
3381 )
3382{
3383 SCIP_ROWEXACT** row;
3384 SCIP_ROWEXACT* workrow;
3385 int i;
3386 int oldnlocks;
3387 SCIP_RATIONAL* tmpval;
3388 SCIP_RATIONAL* tmplhs;
3389 SCIP_Real* rowvals;
3390
3391 row = &(fprow->rowexact);
3392
3393 /* unlock the row temporarily to be able to change it (slightly) */
3394 oldnlocks = (int) fprow->nlocks;
3395 fprow->nlocks = 0;
3396
3397 assert(row != NULL);
3398 assert(fprow != NULL);
3399 assert(blkmem != NULL);
3400 assert(stat != NULL);
3401
3402 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &tmpval) );
3403 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &tmplhs) );
3404
3405 if( !SCIPsetIsInfinity(set, fprow->rhs) )
3406 SCIPrationalSetReal(tmpval, fprow->rhs);
3407 else
3409
3410 if( !SCIPsetIsInfinity(set, -fprow->lhs) )
3411 SCIPrationalSetReal(tmplhs, fprow->lhs);
3412 else
3414
3415 SCIP_CALL( SCIProwExactCreate(row, fprow, NULL, blkmem, set, stat, lpexact, 0, NULL, NULL, tmplhs, tmpval, TRUE) );
3416
3417 workrow = *row;
3418 rowvals = SCIProwGetVals(fprow);
3419 workrow->removable = TRUE;
3420
3421 SCIP_CALL( SCIProwExactEnsureSize(workrow, blkmem, set, fprow->size) );
3422
3424 SCIP_CALL( SCIProwExactAddConstant(workrow, set, stat, lpexact, tmpval) );
3425
3426 if( set->exact_cutmaxdenom > 0 )
3427 {
3428 SCIP_CALL( rowExactCreateFromRowLimitEncodingLength(fprow, workrow, set, blkmem, eventqueue, lpexact) );
3429 SCIProwRecalcNorms(fprow, set);
3430 }
3431 else
3432 {
3433 for( i = 0; i < SCIProwGetNNonz(fprow); i++ )
3434 {
3435 SCIP_COL* col;
3436
3437 SCIPrationalSetReal(tmpval, rowvals[i]);
3438 col = SCIProwGetCols(fprow)[i];
3439
3440 SCIP_CALL( SCIPvarAddToRowExact(SCIPcolGetVar(col), blkmem, set, stat, eventqueue, prob, lpexact, workrow, tmpval) );
3442 }
3443 }
3444
3445 SCIPrationalFreeBuffer(set->buffer, &tmplhs);
3446 SCIPrationalFreeBuffer(set->buffer, &tmpval);
3447
3448 fprow->nlocks = oldnlocks; /*lint !e732*/
3449
3450 return SCIP_OKAY;
3451}
3452
3453/** populate data of two empty fp rows with data from exact row */
3455 BMS_BLKMEM* blkmem, /**< block memory */
3456 SCIP_SET* set, /**< global SCIP settings */
3457 SCIP_STAT* stat, /**< SCIP statistics */
3458 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3459 SCIP_LPEXACT* lpexact, /**< current exact LP data */
3460 SCIP_PROB* prob, /**< SCIP problem data */
3461 SCIP_ROWEXACT* row, /**< SCIP row */
3462 SCIP_ROW* rowlhs, /**< fp row-relaxation wrt lhs */
3463 SCIP_ROW* rowrhs, /**< fp row-relaxation wrt rhs */
3464 SCIP_Bool* onerowrelax, /**< is one row enough to represent the exact row */
3465 SCIP_Bool* hasfprelax /**< is it possible to generate relaxations at all for this row? */
3466 )
3467{
3468 SCIP_Real* valsrhsrelax;
3469 SCIP_Real* valslhsrelax;
3470 SCIP_Real rhsrelax;
3471 SCIP_Real lhsrelax;
3472 SCIP_VAR* var;
3473 SCIP_RATIONAL* ub;
3474 SCIP_RATIONAL* lb;
3475 SCIP_INTERVAL* rowexactvalsinterval;
3476 SCIP_Real lbreal;
3477 SCIP_Real ubreal;
3478 SCIP_ROUNDMODE roundmode;
3479 int i;
3480 int* sideindexpostprocess;
3481 int npostprocess;
3482
3483 assert(row != NULL);
3484 assert(rowlhs != NULL);
3485 assert(rowrhs != NULL);
3486
3487 SCIP_CALL( SCIPsetAllocBufferArray(set, &valsrhsrelax, row->len) );
3488 SCIP_CALL( SCIPsetAllocBufferArray(set, &valslhsrelax, row->len) );
3489 SCIP_CALL( SCIPsetAllocBufferArray(set, &sideindexpostprocess, row->len) );
3490
3491 npostprocess = 0;
3492 *hasfprelax = TRUE;
3493 *onerowrelax = TRUE;
3494
3497 roundmode = SCIPintervalGetRoundingMode();
3498 rowexactvalsinterval = row->valsinterval;
3499
3500 /* we need to adapt the two fprows that are created, so that one is a relaxation wrt the lhs and the other wrt the rhs of the row */
3501 for( i = 0; i < row->len; i++ )
3502 {
3503 var = SCIPcolExactGetVar(row->cols[i]);
3504 ub = SCIPvarGetUbGlobalExact(var);
3505 lb = SCIPvarGetLbGlobalExact(var);
3506
3507 /* coefficient is exactly representable as fp number */
3508 if( rowexactvalsinterval[i].inf == rowexactvalsinterval[i].sup )/*lint !e777*/
3509 {
3510 valslhsrelax[i] = rowexactvalsinterval[i].inf;
3511 valsrhsrelax[i] = rowexactvalsinterval[i].inf;
3512 }
3513 /* unbounded variable with non fp-representable coefficient: var would need to be split in pos/neg to be relaxable */
3515 {
3516 *hasfprelax = FALSE;
3517 valslhsrelax[i] = rowexactvalsinterval[i].inf;
3518 }
3519 /* negative upper or positive lower bounds are good */
3520 else if( !SCIPrationalIsInfinity(ub) && SCIPrationalIsNegative(ub) )
3521 {
3522 *onerowrelax = FALSE;
3523 valslhsrelax[i] = rowexactvalsinterval[i].inf;
3524 valsrhsrelax[i] = rowexactvalsinterval[i].sup;
3525 }
3526 /* negative upper or positive lower bounds are good */
3528 {
3529 *onerowrelax = FALSE;
3530 valslhsrelax[i] = rowexactvalsinterval[i].sup;
3531 valsrhsrelax[i] = rowexactvalsinterval[i].inf;
3532 }
3533 else if( !SCIPrationalIsInfinity(ub) )
3534 {
3535 *onerowrelax = FALSE;
3536 valslhsrelax[i] = rowexactvalsinterval[i].inf;
3537 valsrhsrelax[i] = rowexactvalsinterval[i].sup;
3538 sideindexpostprocess[npostprocess] = i;
3539 npostprocess++;
3540 }
3541 else
3542 {
3543 assert(!SCIPrationalIsInfinity(lb));
3544 *onerowrelax = FALSE;
3545 valslhsrelax[i] = rowexactvalsinterval[i].sup;
3546 valsrhsrelax[i] = rowexactvalsinterval[i].inf;
3547 sideindexpostprocess[npostprocess] = i;
3548 npostprocess++;
3549 }
3550 }
3551
3553
3554 /* change the sides where necessary (do not do it immediately to not change rounding mode too often) */
3555 for( i = 0; i < npostprocess; i++ )
3556 {
3557 int idx;
3558 idx = sideindexpostprocess[i];
3559 var = SCIPcolExactGetVar(row->cols[idx]);
3560 lbreal = SCIPvarGetLbGlobal(var);
3561 ubreal = SCIPvarGetUbGlobal(var);
3562
3563 if( valslhsrelax[idx] == rowexactvalsinterval[idx].inf )/*lint !e777*/
3564 rhsrelax += ubreal >= 0 ? (rowexactvalsinterval[idx].sup - rowexactvalsinterval[idx].inf) * ubreal : 0;
3565 else
3566 rhsrelax -= lbreal <= 0 ? (rowexactvalsinterval[idx].sup - rowexactvalsinterval[idx].inf) * lbreal : 0;
3567 }
3568
3570 for( i = 0; i < npostprocess; i++ )
3571 {
3572 int idx;
3573 idx = sideindexpostprocess[i];
3574 var = SCIPcolExactGetVar(row->cols[idx]);
3575 lbreal = SCIPvarGetLbGlobal(var);
3576 ubreal = SCIPvarGetUbGlobal(var);
3577
3578 // upper bound was used
3579 if( valslhsrelax[idx] == rowexactvalsinterval[idx].sup )/*lint !e777*/
3580 lhsrelax -= ubreal >= 0 ? (rowexactvalsinterval[i].sup - rowexactvalsinterval[i].inf) * ubreal : 0;
3581 else
3582 lhsrelax += lbreal <= 0 ? (rowexactvalsinterval[i].sup - rowexactvalsinterval[i].inf) * lbreal : 0;
3583 }
3584
3585 SCIPintervalSetRoundingMode(roundmode);
3586
3587 /* only create one row if possible, or if relaxation did not work at all */
3588 if( !(*hasfprelax) || *onerowrelax )
3589 {
3590 if( !SCIPsetIsInfinity(set, rhsrelax) )
3591 {
3592 SCIP_CALL( SCIProwChgRhs(rowlhs, blkmem, set, eventqueue, lpexact->fplp, rhsrelax) );
3593 }
3594 if( !SCIPsetIsInfinity(set, -lhsrelax) )
3595 {
3596 SCIP_CALL( SCIProwChgLhs(rowlhs, blkmem, set, eventqueue, lpexact->fplp, lhsrelax) );
3597 }
3598
3599 for( i = 0; i < row->len; i++ )
3600 {
3601 SCIP_CALL( SCIPvarAddToRow(row->cols[i]->var, blkmem, set, stat,
3602 eventqueue, prob, lpexact->fplp, rowlhs, valslhsrelax[i]) );
3603 }
3604
3605 /* we created the fprows directly from the exact row, so we should only have active variables inside it */
3606 assert(SCIProwGetConstant(rowlhs) == 0.0);
3607 SCIP_CALL( SCIProwChgConstant(rowlhs, blkmem, set, stat, eventqueue, lpexact->fplp, SCIPrationalRoundReal(row->constant, SCIP_R_ROUND_DOWNWARDS)) );
3608
3609 SCIP_CALL( SCIProwRelease(&rowrhs, blkmem, set, lpexact->fplp) );
3610 }
3611 /* create two fp-rows for row relaxation */
3612 else
3613 {
3614 if( !SCIPsetIsInfinity(set, rhsrelax) )
3615 {
3616 SCIP_CALL( SCIProwChgRhs(rowlhs, blkmem, set, eventqueue, lpexact->fplp, rhsrelax) );
3617 SCIP_CALL( SCIProwChgRhs(rowrhs, blkmem, set, eventqueue, lpexact->fplp, rhsrelax) );
3618 }
3619 if( !SCIPsetIsInfinity(set, -lhsrelax) )
3620 {
3621 SCIP_CALL( SCIProwChgLhs(rowlhs, blkmem, set, eventqueue, lpexact->fplp, lhsrelax) );
3622 SCIP_CALL( SCIProwChgLhs(rowrhs, blkmem, set, eventqueue, lpexact->fplp, lhsrelax) );
3623 }
3624
3625 for( i = 0; i < row->len; i++ )
3626 {
3627 SCIP_CALL( SCIPvarAddToRow(row->cols[i]->var, blkmem, set, stat,
3628 eventqueue, prob, lpexact->fplp, rowlhs, valslhsrelax[i]) );
3629
3630 SCIP_CALL( SCIPvarAddToRow(row->cols[i]->var, blkmem, set, stat,
3631 eventqueue, prob, lpexact->fplp, rowrhs, valsrhsrelax[i]) );
3632 }
3633
3634 /* we created the fprows directly from the exact row, so we should only have active variables inside it */
3635 assert(SCIProwGetConstant(rowlhs) == 0.0);
3636 assert(SCIProwGetConstant(rowrhs) == 0.0);
3637 SCIP_CALL( SCIProwChgConstant(rowlhs, blkmem, set, stat, eventqueue, lpexact->fplp, SCIPrationalRoundReal(row->constant, SCIP_R_ROUND_UPWARDS)) );
3638 SCIP_CALL( SCIProwChgConstant(rowrhs, blkmem, set, stat, eventqueue, lpexact->fplp, SCIPrationalRoundReal(row->constant, SCIP_R_ROUND_DOWNWARDS)) );
3639 }
3640
3641 row->fprelaxable = *hasfprelax;
3642
3643 SCIPsetFreeBufferArray(set, &sideindexpostprocess);
3644 SCIPsetFreeBufferArray(set, &valslhsrelax);
3645 SCIPsetFreeBufferArray(set, &valsrhsrelax);
3646
3647 return SCIP_OKAY;
3648}
3649
3650/** applies all cached changes to the LP solver */
3652 SCIP_LPEXACT* lpexact, /**< current exact LP data */
3653 BMS_BLKMEM* blkmem, /**< block memory */
3654 SCIP_SET* set, /**< global SCIP settings */
3655 SCIP_EVENTQUEUE* eventqueue /**< event queue */
3656 )
3657{
3658 assert(lpexact != NULL);
3659 assert(blkmem != NULL);
3660
3661 SCIPsetDebugMsg(set, "flushing exact LP changes: old (%d cols, %d rows), nchgcols=%d, nchgrows=%d, firstchgcol=%d, firstchgrow=%d, new (%d cols, %d rows), flushed=%u\n",
3662 lpexact->nlpicols, lpexact->nlpirows, lpexact->nchgcols, lpexact->nchgrows, lpexact->lpifirstchgcol, lpexact->lpifirstchgrow, lpexact->ncols, lpexact->nrows, lpexact->flushed);
3663
3664 if( !lpexact->flushed )
3665 {
3666 lpexact->flushdeletedcols = FALSE;
3667 lpexact->flushaddedcols = FALSE;
3668 lpexact->flushdeletedrows = FALSE;
3669 lpexact->flushaddedrows = FALSE;
3670
3671 SCIP_CALL( lpExactFlushDelCols(lpexact) );
3672 SCIP_CALL( lpExactFlushDelRows(lpexact, blkmem, set) );
3673 SCIP_CALL( lpExactFlushChgCols(lpexact, set) );
3674 SCIP_CALL( lpExactFlushChgRows(lpexact, set) );
3675 SCIP_CALL( lpExactFlushAddCols(lpexact, blkmem, set, eventqueue) );
3676 SCIP_CALL( lpExactFlushAddRows(lpexact, blkmem, set, eventqueue) );
3677
3678 lpexact->flushed = TRUE;
3679
3680 checkLinks(lpexact);
3681 }
3682
3683 /* we can't retrieve the solution from Qsoptex after anything was changed, so we need to resolve the lp */
3684#ifdef SCIP_WITH_QSOPTEX
3685 lpexact->solved = FALSE;
3687#endif
3688
3689 assert(lpexact->nlpicols == lpexact->ncols);
3690 assert(lpexact->lpifirstchgcol == lpexact->nlpicols);
3691 assert(lpexact->nlpirows == lpexact->nrows);
3692 assert(lpexact->lpifirstchgrow == lpexact->nlpirows);
3693 assert(lpexact->nchgcols == 0);
3694 assert(lpexact->nchgrows == 0);
3695#ifndef NDEBUG
3696 {
3697 int ncols;
3698 int nrows;
3699
3700 SCIP_CALL( SCIPlpiExactGetNCols(lpexact->lpiexact, &ncols) );
3701 SCIP_CALL( SCIPlpiExactGetNRows(lpexact->lpiexact, &nrows) );
3702 assert(ncols == lpexact->ncols);
3703 assert(nrows == lpexact->nrows);
3704 }
3705#endif
3706
3707 return SCIP_OKAY;
3708}
3709
3710/** ensures all rows/columns are correctly updated, but changes are not yet communicated to the exact LP solver */
3712 SCIP_LPEXACT* lpexact, /**< current exact LP data */
3713 BMS_BLKMEM* blkmem, /**< block memory */
3714 SCIP_SET* set, /**< global SCIP settings */
3715 SCIP_EVENTQUEUE* eventqueue /**< event queue */
3716 )
3717{
3718 int c, r;
3719 SCIP_COLEXACT* col;
3720 SCIP_ROWEXACT* row;
3721
3722 assert(lpexact != NULL);
3723 assert(blkmem != NULL);
3724
3725 SCIPsetDebugMsg(set, "flushing exact LP changes: old (%d cols, %d rows), nchgcols=%d, nchgrows=%d, firstchgcol=%d, firstchgrow=%d, new (%d cols, %d rows), flushed=%u\n",
3726 lpexact->nlpicols, lpexact->nlpirows, lpexact->nchgcols, lpexact->nchgrows, lpexact->lpifirstchgcol, lpexact->lpifirstchgrow, lpexact->ncols, lpexact->nrows, lpexact->flushed);
3727
3728 if( !lpexact->flushed )
3729 {
3730 lpexact->flushdeletedcols = FALSE;
3731 lpexact->flushaddedcols = FALSE;
3732 lpexact->flushdeletedrows = FALSE;
3733 lpexact->flushaddedrows = FALSE;
3734
3735 /* we still flush added/deleted columns since this should only happen at the very start of the solve */
3736 SCIP_CALL( lpExactFlushDelCols(lpexact) );
3737 SCIP_CALL( lpExactFlushAddCols(lpexact, blkmem, set, eventqueue) );
3738
3739 /* link new columns/rows */
3740 for( c = lpexact->nlpicols; c < lpexact->ncols; ++c )
3741 {
3742 col = lpexact->cols[c];
3743 assert(col != NULL);
3744 assert(col->var != NULL);
3746 assert(SCIPvarGetColExact(col->var) == col);
3747 assert(col->lppos == c);
3748
3749 SCIPsetDebugMsg(set, "linking added column <%s>: ", SCIPvarGetName(col->var));
3750 SCIP_CALL( colExactLink(col, blkmem, set, eventqueue, lpexact) );
3751 }
3752 for( r = lpexact->nlpirows; r < lpexact->nrows; ++r )
3753 {
3754 row = lpexact->rows[r];
3755 assert(row != NULL);
3756 assert(row->lppos == r);
3757
3758 SCIPsetDebugMsg(set, "linking added exact row <%s>: ", row->fprow->name);
3759
3760 SCIP_CALL( rowExactLink(row, blkmem, set, eventqueue, lpexact) );
3761 }
3762
3763 checkLinks(lpexact);
3764 }
3765
3766 return SCIP_OKAY;
3767}
3768
3769/*
3770 * lp methods
3771 */
3772
3773/** creates the data needed for project and shift bounding method */
3774static
3776 SCIP_LPEXACT* lpexact, /**< pointer to LP data object */
3777 SCIP_SET* set, /**< global SCIP settings */
3778 BMS_BLKMEM* blkmem /**< block memory buffers */
3779 )
3780{
3781 SCIP_PROJSHIFTDATA* projshiftdata;
3782
3783 assert(lpexact != NULL);
3784 assert(set != NULL);
3785 assert(blkmem != NULL);
3786
3787 SCIP_ALLOC( BMSallocBlockMemory(blkmem, &lpexact->projshiftdata) );
3788
3789 projshiftdata = lpexact->projshiftdata;
3790
3791 projshiftdata->lpiexact = NULL;
3792 projshiftdata->dvarmap = NULL;
3793 projshiftdata->ndvarmap = 0;
3794 projshiftdata->interiorpoint = NULL;
3795 projshiftdata->interiorray = NULL;
3796 projshiftdata->violation = NULL;
3797 projshiftdata->correction = NULL;
3798 projshiftdata->commonslack = NULL;
3799 projshiftdata->includedrows = NULL;
3800 projshiftdata->projshiftbasis = NULL;
3801#if defined SCIP_WITH_GMP && defined SCIP_WITH_EXACTSOLVE
3802 projshiftdata->rectfactor = (qsnum_factor_work*) NULL;
3803#endif
3804
3805 projshiftdata->nextendedrows = 0;
3806 projshiftdata->projshiftbasisdim = 0;
3807 projshiftdata->violationsize = 0;
3808
3809 projshiftdata->projshiftdatacon = FALSE;
3810 projshiftdata->projshiftdatafail = FALSE;
3811 projshiftdata->projshifthaspoint = FALSE;
3812 projshiftdata->projshifthasray = FALSE;
3813 projshiftdata->projshiftobjweight = FALSE;
3814 projshiftdata->scaleobj = FALSE;
3815 projshiftdata->projshiftuseintpoint = TRUE;
3816
3817 return SCIP_OKAY;
3818}
3819
3820/** frees the exact LPI in project-and-shift */
3821static
3823 SCIP_LPIEXACT** lpiexact /**< pointer to LPI object */
3824 )
3825{
3826 int nlpirows;
3827 int nlpicols;
3828
3829 assert(lpiexact != NULL);
3830 assert(*lpiexact != NULL);
3831
3832 SCIP_CALL( SCIPlpiExactGetNRows(*lpiexact, &nlpirows) );
3833 SCIP_CALL( SCIPlpiExactDelRows(*lpiexact, 0, nlpirows - 1) );
3834
3835 SCIP_CALL( SCIPlpiExactGetNCols(*lpiexact, &nlpicols) );
3836 SCIP_CALL( SCIPlpiExactDelCols(*lpiexact, 0, nlpicols - 1) );
3837
3838 SCIP_CALL( SCIPlpiExactClear(*lpiexact) );
3839 SCIP_CALL( SCIPlpiExactFree(lpiexact) );
3840
3841 return SCIP_OKAY;
3842}
3843
3844/** frees the data needed for project and shift bounding method */
3845static
3847 SCIP_LPEXACT* lpexact, /**< pointer to LP data object */
3848 SCIP_SET* set, /**< global SCIP settings */
3849 BMS_BLKMEM* blkmem /**< block memory buffers */
3850 )
3851{
3852 SCIP_PROJSHIFTDATA* projshiftdata;
3853
3854 assert(lpexact != NULL);
3855 assert(set != NULL);
3856 assert(blkmem != NULL);
3857
3858 projshiftdata = lpexact->projshiftdata;
3859
3860 if( projshiftdata->lpiexact != NULL )
3861 {
3862 SCIP_CALL( SCIPlpExactProjectShiftFreeLPIExact(&projshiftdata->lpiexact) );
3863 }
3864 assert(projshiftdata->lpiexact == NULL);
3865
3866 BMSfreeBlockMemoryArrayNull(blkmem, &projshiftdata->dvarmap, projshiftdata->ndvarmap);
3867
3868 if( projshiftdata->interiorpoint != NULL )
3869 SCIPrationalFreeBlockArray(blkmem, &projshiftdata->interiorpoint, projshiftdata->nextendedrows);
3870 if( projshiftdata->interiorray != NULL )
3871 SCIPrationalFreeBlockArray(blkmem, &projshiftdata->interiorray, projshiftdata->nextendedrows);
3872 if( projshiftdata->violation != NULL )
3873 SCIPrationalFreeBlockArray(blkmem, &projshiftdata->violation, projshiftdata->violationsize);
3874 if( projshiftdata->correction != NULL )
3875 SCIPrationalFreeBlockArray(blkmem, &projshiftdata->correction, projshiftdata->nextendedrows);
3876 if( projshiftdata->commonslack != NULL )
3877 SCIPrationalFreeBlock(blkmem, &projshiftdata->commonslack);
3878
3879 BMSfreeBlockMemoryArrayNull(blkmem, &projshiftdata->includedrows, projshiftdata->nextendedrows);
3880 BMSfreeBlockMemoryArrayNull(blkmem, &projshiftdata->projshiftbasis, projshiftdata->nextendedrows);
3881
3882#if defined(SCIP_WITH_GMP) && defined(SCIP_WITH_EXACTSOLVE)
3883 if( projshiftdata->rectfactor != NULL )
3884 RECTLUfreeFactorization(projshiftdata->rectfactor);
3885#endif
3886
3887 assert(projshiftdata->interiorpoint == NULL);
3888 assert(projshiftdata->interiorray == NULL);
3889 assert(projshiftdata->includedrows == NULL);
3890 assert(projshiftdata->projshiftbasis == NULL);
3891 assert(projshiftdata->commonslack == NULL);
3892
3893 BMSfreeBlockMemoryNull(blkmem, &lpexact->projshiftdata);
3894
3895 return SCIP_OKAY;
3896}
3897
3898/** returns whether the success rate of the Neumaier-Shcherbina safe bounding method is sufficiently high */
3900 SCIP_LPEXACT* lpexact /**< pointer to LP data object */
3901 )
3902{
3903 assert(lpexact != NULL);
3904
3905 return lpexact->boundshiftuseful;
3906}
3907
3908/** returns whether it is possible to use project and shift bounding method */
3910 SCIP_LPEXACT* lpexact /**< pointer to LP data object */
3911 )
3912{
3913 assert(lpexact != NULL);
3914 assert(lpexact->projshiftdata != NULL);
3915
3916 return !(lpexact->projshiftdata->projshiftdatafail);
3917}
3918
3919/** checks that lp and fplp are properly synced */
3921 SCIP_LPEXACT* lpexact, /**< pointer to LP data object */
3922 SCIP_SET* set, /**< global SCIP settings */
3923 SCIP_MESSAGEHDLR* msg /**< message handler for debug output */
3924 )
3925{
3926 assert(lpexact != NULL);
3927 assert(msg != NULL);
3928
3929 return lpExactInSync(lpexact, set, msg);
3930}
3931
3932/** creates empty LP data object */
3934 SCIP_LPEXACT** lpexact, /**< pointer to LP data object */
3935 BMS_BLKMEM* blkmem, /**< block memory data structure */
3936 SCIP_LP* fplp, /**< the floating point LP */
3937 SCIP_SET* set, /**< global SCIP settings */
3938 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
3939 SCIP_STAT* stat, /**< problem statistics */
3940 const char* name /**< problem name */
3941 )
3942{
3943 assert(lpexact != NULL);
3944 assert(fplp != NULL);
3945 assert(set != NULL);
3946 assert(stat != NULL);
3947 assert(name != NULL);
3948
3949 SCIP_ALLOC( BMSallocMemory(lpexact) );
3950
3951 /* open LP Solver interface */
3952 SCIP_CALL( SCIPlpiExactCreate(&(*lpexact)->lpiexact, messagehdlr, name, SCIP_OBJSEN_MINIMIZE) );
3953 SCIP_CALL( SCIPlpPsdataCreate(*lpexact, set, blkmem) );
3954
3955 (*lpexact)->fplp = fplp;
3956 fplp->lpexact = *lpexact;
3957
3958 (*lpexact)->lpicols = NULL;
3959 (*lpexact)->lpirows = NULL;
3960 (*lpexact)->chgcols = NULL;
3961 (*lpexact)->chgrows = NULL;
3962 (*lpexact)->cols = NULL;
3963 (*lpexact)->rows = NULL;
3964 (*lpexact)->divechgsides = NULL;
3965 (*lpexact)->divechgsidetypes = NULL;
3966 (*lpexact)->divechgrows = NULL;
3967 (*lpexact)->divelpistate = NULL;
3968 (*lpexact)->storedsolvals = NULL;
3969 (*lpexact)->lpsolstat = SCIP_LPSOLSTAT_OPTIMAL;
3970 (*lpexact)->flushdeletedcols = FALSE;
3971 (*lpexact)->flushaddedcols = FALSE;
3972 (*lpexact)->flushdeletedrows = FALSE;
3973 (*lpexact)->flushaddedrows = FALSE;
3974 (*lpexact)->updateintegrality = TRUE;
3975 (*lpexact)->flushed = TRUE;
3976 (*lpexact)->solved = FALSE;
3977 (*lpexact)->primalfeasible = TRUE;
3978 (*lpexact)->primalchecked = TRUE;
3979 (*lpexact)->diving = FALSE;
3980 (*lpexact)->divelpwasprimfeas = TRUE;
3981 (*lpexact)->divelpwasprimchecked = TRUE;
3982 (*lpexact)->divelpwasdualfeas = TRUE;
3983 (*lpexact)->divelpwasdualchecked = TRUE;
3984 (*lpexact)->divingobjchg = FALSE;
3985 (*lpexact)->dualfeasible = TRUE;
3986 (*lpexact)->dualchecked = TRUE;
3987 (*lpexact)->solisbasic = FALSE;
3988 (*lpexact)->resolvelperror = FALSE;
3989 (*lpexact)->projshiftpossible = FALSE;
3990 (*lpexact)->boundshiftuseful = TRUE;
3991 (*lpexact)->forceexactsolve = FALSE;
3992 (*lpexact)->allowexactsolve = FALSE;
3993 (*lpexact)->forcesafebound = FALSE;
3994 (*lpexact)->wasforcedsafebound = FALSE;
3995 (*lpexact)->lpiscaling = set->lp_scaling;
3996 (*lpexact)->lpisolutionpolishing = (set->lp_solutionpolishing > 0);
3997 (*lpexact)->lpirefactorinterval = set->lp_refactorinterval;
3998 (*lpexact)->lpiitlim = INT_MAX;
3999 (*lpexact)->lpipricing = SCIP_PRICING_AUTO;
4000 (*lpexact)->lastlpalgo = SCIP_LPALGO_DUALSIMPLEX;
4001 (*lpexact)->lpitiming = (int) set->time_clocktype;
4002 (*lpexact)->lpirandomseed = set->random_randomseed;
4003
4004 (*lpexact)->lpicolssize = 0;
4005 (*lpexact)->nlpicols = 0;
4006 (*lpexact)->lpirowssize = 0;
4007 (*lpexact)->nlpirows = 0;
4008 (*lpexact)->lpifirstchgcol = 0;
4009 (*lpexact)->lpifirstchgrow = 0;
4010 (*lpexact)->colssize = 0;
4011 (*lpexact)->ncols = 0;
4012 (*lpexact)->nloosevars = 0;
4013 (*lpexact)->rowssize = 0;
4014 (*lpexact)->nrows = 0;
4015 (*lpexact)->chgcolssize = 0;
4016 (*lpexact)->nchgcols = 0;
4017 (*lpexact)->chgrowssize = 0;
4018 (*lpexact)->nchgrows = 0;
4019 (*lpexact)->firstnewcol = 0;
4020 (*lpexact)->firstnewrow = 0;
4021 (*lpexact)->looseobjvalinf = 0;
4022 (*lpexact)->pseudoobjvalinf = 0;
4023 (*lpexact)->glbpseudoobjvalinf = 0;
4024 (*lpexact)->ndivingrows = 0;
4025 (*lpexact)->ndivechgsides = 0;
4026 (*lpexact)->nremovablerows = 0;
4027 (*lpexact)->lpiobjlim = SCIPlpiExactInfinity((*lpexact)->lpiexact);
4028 (*lpexact)->cutoffbound = SCIPsetInfinity(set);
4029 (*lpexact)->oldcutoffbound = SCIPsetInfinity(set);
4030 SCIP_CALL( SCIPrationalCreateBlock(blkmem, &(*lpexact)->lpobjval) );
4031 SCIP_CALL( SCIPrationalCreateBlock(blkmem, &(*lpexact)->pseudoobjval) );
4032 SCIP_CALL( SCIPrationalCreateBlock(blkmem, &(*lpexact)->glbpseudoobjval) );
4033 SCIP_CALL( SCIPrationalCreateBlock(blkmem, &(*lpexact)->looseobjval) );
4034
4035 return SCIP_OKAY;
4036}
4037
4038/** frees LP data object */
4040 SCIP_LPEXACT** lpexact, /**< pointer to exact LP data object */
4041 BMS_BLKMEM* blkmem, /**< block memory */
4042 SCIP_SET* set /**< global SCIP settings */
4043 )
4044{
4045 int i;
4046
4047 if( !set->exact_enable )
4048 return SCIP_OKAY;
4049
4050 assert(lpexact != NULL);
4051 assert(*lpexact != NULL);
4052
4053 SCIP_CALL( SCIPlpExactProjectShiftFree(*lpexact, set, blkmem) );
4054 SCIP_CALL( SCIPlpExactClear(*lpexact, blkmem, set) );
4055
4056 /* release LPI rows */
4057 for( i = 0; i < (*lpexact)->nlpirows; ++i )
4058 {
4059 SCIP_CALL( SCIProwExactRelease(&(*lpexact)->lpirows[i], blkmem, set, *lpexact) );
4060 }
4061
4062 if( (*lpexact)->lpiexact != NULL )
4063 {
4064 SCIP_CALL( SCIPlpiExactFree(&(*lpexact)->lpiexact) );
4065 }
4066
4067 SCIPrationalFreeBlock(blkmem, &(*lpexact)->lpobjval);
4068 SCIPrationalFreeBlock(blkmem, &(*lpexact)->pseudoobjval);
4069 SCIPrationalFreeBlock(blkmem, &(*lpexact)->glbpseudoobjval);
4070 SCIPrationalFreeBlock(blkmem, &(*lpexact)->looseobjval);
4071
4072 if( (*lpexact)->storedsolvals != NULL )
4073 {
4074 SCIPrationalFreeBlock(blkmem, &(*lpexact)->storedsolvals->lpobjval);
4075 BMSfreeMemoryNull(&(*lpexact)->storedsolvals);
4076 }
4077 BMSfreeMemoryArrayNull(&(*lpexact)->lpicols);
4078 BMSfreeMemoryArrayNull(&(*lpexact)->lpirows);
4079 BMSfreeMemoryArrayNull(&(*lpexact)->chgcols);
4080 BMSfreeMemoryArrayNull(&(*lpexact)->chgrows);
4081 BMSfreeMemoryArrayNull(&(*lpexact)->cols);
4082 BMSfreeMemoryArrayNull(&(*lpexact)->rows);
4083 BMSfreeMemory(lpexact);
4084
4085 return SCIP_OKAY;
4086}
4087
4088/** adds a column to the LP and captures the variable */
4090 SCIP_LPEXACT* lpexact, /**< LP data */
4091 SCIP_SET* set, /**< global SCIP settings */
4092 SCIP_COLEXACT* col /**< LP column */
4093 )
4094{
4095 if( !set->exact_enable )
4096 return SCIP_OKAY;
4097
4098 assert(lpexact != NULL);
4099 assert(!lpexact->fplp->diving);
4100 assert(col != NULL);
4101 assert(col->len == 0 || col->rows != NULL);
4102 assert(col->lppos == -1);
4103 assert(col->var != NULL);
4105 assert(SCIPvarGetCol(col->var) == col->fpcol);
4106 assert(SCIPvarIsIntegral(col->var) == col->fpcol->integral);
4107
4108 SCIPsetDebugMsg(set, "adding column <%s> to exact LP (%d rows, %d cols)\n", SCIPvarGetName(col->var), lpexact->nrows, lpexact->ncols);
4109#ifdef SCIP_DEBUG
4110 SCIPrationalDebugMessage("(obj: %q) [%q,%q]", col->obj, col->lb, col->ub);
4111 for( int i = 0; i < col->len; ++i )
4112 SCIPrationalDebugMessage(" %q<%s>", col->vals[i], col->rows[i]->fprow->name);
4114#endif
4115
4116 SCIP_CALL( ensureColexsSize(lpexact, set, lpexact->ncols+1) );
4117 lpexact->cols[lpexact->ncols] = col;
4118 col->lppos = lpexact->ncols;
4119 lpexact->ncols++;
4120
4121 /* mark the current LP unflushed */
4122 lpexact->flushed = FALSE;
4123
4124 /* update column arrays of all linked rows */
4126
4127 checkLinks(lpexact);
4128
4129 return SCIP_OKAY;
4130}
4131
4132/** adds a row to the LP and captures it */
4134 SCIP_LPEXACT* lpexact, /**< LP data */
4135 SCIP_SET* set, /**< global SCIP settings */
4136 SCIP_ROWEXACT* rowexact /**< LP row */
4137 )
4138{
4139 assert(lpexact != NULL);
4140 assert(rowexact != NULL);
4141 assert(rowexact->len == 0 || rowexact->cols != NULL);
4142 assert(rowexact->lppos == -1);
4143 assert(rowexact->fprow != NULL);
4144
4145 SCIProwExactCapture(rowexact);
4146
4147 SCIPsetDebugMsg(set, "adding row <%s> to LP (%d rows, %d cols)\n", rowexact->fprow->name, lpexact->nrows, lpexact->ncols);
4148#ifdef SCIP_DEBUG
4149 {
4150 int i;
4151 SCIPrationalDebugMessage(" %q <=", rowexact->lhs);
4152 for( i = 0; i < rowexact->len; ++i )
4153 SCIPrationalDebugMessage(" %q<%s>", rowexact->vals[i], SCIPvarGetName(rowexact->cols[i]->var));
4154 if( !SCIPrationalIsZero(rowexact->constant) )
4155 SCIPrationalDebugMessage(" %q", rowexact->constant);
4156 SCIPrationalDebugMessage(" <= %q\n", rowexact->rhs);
4157 }
4158#endif
4159
4160 SCIP_CALL( ensureRowexsSize(lpexact, set, lpexact->nrows+1) );
4161 lpexact->rows[lpexact->nrows] = rowexact;
4162 rowexact->lppos = lpexact->nrows;
4163 lpexact->nrows++;
4164
4165 /* mark the current LP unflushed */
4166 lpexact->flushed = FALSE;
4167
4168 /* update row arrays of all linked columns */
4169 SCIP_CALL( rowExactUpdateAddLP(rowexact, set) );
4170
4171 return SCIP_OKAY;
4172}
4173
4174/** should the objective limit of the LP solver be disabled */
4175#define lpCutoffDisabled(set) (set->lp_disablecutoff == 1 || (set->nactivepricers > 0 && set->lp_disablecutoff == 2))
4176
4177/** sets the upper objective limit of the exact LP solver */
4179 SCIP_LPEXACT* lpexact, /**< current exact LP data */
4180 SCIP_SET* set, /**< global SCIP settings */
4181 SCIP_Real cutoffbound /**< new upper objective limit */
4182 )
4183{
4184 SCIP_RATIONAL* tmpobj;
4185
4186 if( !set->exact_enable )
4187 return SCIP_OKAY;
4188
4189 assert(lpexact != NULL);
4190
4191 SCIPsetDebugMsg(set, "setting exact LP upper objective limit from %g to %g\n", lpexact->cutoffbound, cutoffbound);
4192
4193 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &tmpobj) );
4194 if( lpexact->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL && lpexact->solved && lpexact->flushed )
4195 SCIPlpExactGetObjval(lpexact, set, tmpobj);
4196
4197 /* if the cutoff bound is increased, and the LP was proved to exceed the old cutoff, it is no longer solved */
4198 if( lpexact->lpsolstat == SCIP_LPSOLSTAT_OBJLIMIT && cutoffbound > lpexact->cutoffbound )
4199 {
4200 /* mark the current solution invalid */
4201 lpexact->solved = FALSE;
4204 }
4205 /* if the cutoff bound is decreased below the current optimal value, the LP now exceeds the objective limit;
4206 * if the objective limit in the LP solver was disabled, the solution status of the LP is not changed
4207 */
4208 else if( !lpCutoffDisabled(set) && lpexact->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL && lpexact->solved && lpexact->flushed
4209 && SCIPrationalIsGEReal(tmpobj, cutoffbound) )
4210 {
4211 assert(lpexact->flushed);
4212 assert(lpexact->solved);
4214 }
4215 SCIPrationalFreeBuffer(set->buffer, &tmpobj);
4216 lpexact->cutoffbound = cutoffbound;
4217
4218 return SCIP_OKAY;
4219}
4220
4221/** maximal number of verblevel-high messages about numerical trouble in LP that will be printed
4222 * when this number is reached and display/verblevel is not full, then further messages are suppressed in this run
4223 */
4224#define MAXNUMTROUBLELPMSGS 10
4225
4226/** prints message about numerical trouble
4227 *
4228 * If message has verblevel at most high and display/verblevel is not full,
4229 * then the message is not printed if already MAXNUMTROUBLELPMSGS messages
4230 * were printed before in the current run.
4231 */
4232static
4234 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
4235 SCIP_SET* set, /**< global SCIP settings */
4236 SCIP_STAT* stat, /**< problem statistics */
4237 SCIP_VERBLEVEL verblevel, /**< verbosity level of message */
4238 const char* formatstr, /**< message format string */
4239 ... /**< arguments to format string */
4240 )
4241{
4242 va_list ap;
4243
4244 assert(verblevel > SCIP_VERBLEVEL_NONE);
4245 assert(verblevel <= SCIP_VERBLEVEL_FULL);
4246 assert(set->disp_verblevel <= SCIP_VERBLEVEL_FULL);
4247
4248 if( set->disp_verblevel < SCIP_VERBLEVEL_FULL )
4249 {
4250 if( verblevel <= SCIP_VERBLEVEL_HIGH )
4251 {
4252 /* if already max number of messages about numerical trouble in LP on verblevel at most high, then skip message */
4254 return;
4255
4256 /* increase count on messages with verblevel high */
4257 ++stat->nnumtroublelpmsgs ;
4258 }
4259
4260 /* if messages wouldn't be printed, then return already */
4261 if( verblevel > set->disp_verblevel )
4262 return;
4263 }
4264
4265 /* print common begin of message */
4266 SCIPmessagePrintInfo(messagehdlr,
4267 "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in exact LP %" SCIP_LONGINT_FORMAT " -- ",
4268 stat->nnodes, stat->nexlp);
4269
4270 /* print individual part of message */
4271 va_start(ap, formatstr); /*lint !e838*/
4272 SCIPmessageVFPrintInfo(messagehdlr, NULL, formatstr, ap);
4273 va_end(ap);
4274
4275 /* warn that further messages will be suppressed */
4276 if( set->disp_verblevel < SCIP_VERBLEVEL_FULL && verblevel <= SCIP_VERBLEVEL_HIGH && stat->nnumtroublelpmsgs > MAXNUMTROUBLELPMSGS )
4277 {
4278 SCIPmessagePrintInfo(messagehdlr, " -- further messages will be suppressed (use display/verblevel=5 to see all)");
4279 }
4280
4281 /* print closing new-line */
4282 SCIPmessagePrintInfo(messagehdlr, "\n");
4283}
4284
4285/** flushes the exact LP and solves it with the primal or dual simplex algorithm, depending on the current basis feasibility */
4286static
4288 SCIP_LPEXACT* lpexact, /**< current exact LP data */
4289 BMS_BLKMEM* blkmem, /**< block memory */
4290 SCIP_SET* set, /**< global SCIP settings */
4291 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
4292 SCIP_STAT* stat, /**< problem statistics */
4293 SCIP_PROB* prob, /**< problem data */
4294 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
4295 int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
4296 SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
4297 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
4298 )
4299{
4300 int* cstat;
4301 int* rstat;
4302 SCIP_Bool solveagain;
4303 SCIP_Bool success;
4304 SCIP_RETCODE retcode;
4305 SCIP_Real lptimelimit;
4306 char algo;
4307 SCIP_LP* lp;
4308 SCIP_LPISTATE* lpistate;
4309
4310 assert(lpexact != NULL);
4311 assert(lpexact->fplp != NULL);
4312 assert(set != NULL);
4313 assert(lperror != NULL);
4314 assert(set->exact_enable);
4315
4316 SCIP_CALL( SCIPlpiExactSetIntpar(lpexact->lpiexact, SCIP_LPPAR_LPINFO, (int) set->exact_lpinfo) );
4317 algo = set->lp_initalgorithm;
4318 lp = lpexact->fplp;
4319
4320 /* set up the exact lpi for the current node */
4321 SCIP_CALL( SCIPlpExactSyncLPs(lpexact, blkmem, set) );
4322 SCIP_CALL( SCIPlpExactFlush(lpexact, blkmem, set, eventqueue) );
4323
4324 assert(SCIPlpExactIsSynced(lpexact, set, messagehdlr));
4325
4326 /* check if a time limit is set, and set time limit for LP solver accordingly */
4327 lptimelimit = SCIPlpiExactInfinity(lpexact->lpiexact);
4328 if( set->istimelimitfinite )
4329 lptimelimit = set->limit_time - SCIPclockGetTime(stat->solvingtime);
4330
4331 success = FALSE;
4332 if( lptimelimit > 0.0 )
4333 SCIP_CALL( lpExactSetRealpar(lpexact, SCIP_LPPAR_LPTILIM, lptimelimit, &success) );
4334
4335 if( lptimelimit <= 0.0 || !success )
4336 {
4337 SCIPsetDebugMsg(set, "time limit of %f seconds could not be set\n", lptimelimit);
4338 *lperror = ((lptimelimit > 0.0) ? TRUE : FALSE);
4339 SCIPsetDebugMsg(set, "time limit exceeded before solving LP\n");
4340 lp->solved = TRUE;
4344 return SCIP_OKAY;
4345 }
4346
4347 /* get lpi state to check whether basis exists */
4348 SCIP_CALL( SCIPlpiGetState(lp->lpi, blkmem, &lpistate) );
4349
4350 /* set the correct basis information for warmstart */
4351 if( !fromscratch && SCIPlpiHasStateBasis(lp->lpi, lpistate) )
4352 {
4353 SCIP_CALL( SCIPsetAllocBufferArray(set, &cstat, lpexact->nlpicols) );
4354 SCIP_CALL( SCIPsetAllocBufferArray(set, &rstat, lpexact->nlpirows) );
4355
4356 SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
4357 SCIP_CALL( SCIPlpiExactSetBase(lpexact->lpiexact, cstat, rstat) );
4358
4359 SCIPsetFreeBufferArray(set, &cstat);
4360 SCIPsetFreeBufferArray(set, &rstat);
4361 }
4362 else
4363 {
4365 }
4366
4367 SCIP_CALL( SCIPlpiFreeState(lp->lpi, blkmem, &lpistate) );
4368
4369 /* solve with given settings (usually fast but imprecise) */
4370 if( SCIPsetIsInfinity(set, lpexact->cutoffbound) )
4371 {
4372 SCIP_CALL( lpExactSetObjlim(lpexact, set, lpexact->cutoffbound, &success) );
4373 }
4374 else
4375 {
4377 }
4378 SCIP_CALL( lpExactSetIterationLimit(lpexact, harditlim) );
4379
4380 do {
4381 solveagain = FALSE;
4382
4383 /* solve the lp exactly */
4384 if( algo != 's' )
4385 {
4386 SCIPerrorMessage("Lp-algorithm-type %d is not supported in exact solving mode \n", algo);
4387 SCIPABORT();
4388 }
4389
4390 SCIPsetDebugMsg(set, "Calling SCIPlpiExactSolveDual()\n");
4391 retcode = SCIPlpiExactSolveDual(lpexact->lpiexact);
4392
4393 if( retcode == SCIP_LPERROR )
4394 {
4395 *lperror = TRUE;
4396 lpexact->solved = FALSE;
4398 SCIPdebugMessage("Error solving lp exactly. \n");
4399 }
4400
4401 if( retcode != SCIP_LPERROR )
4402 {
4403 SCIP_CALL( SCIPlpiExactGetSolFeasibility(lpexact->lpiexact, &(lpexact->primalfeasible), &(lpexact->dualfeasible)) );
4404 lpexact->solisbasic = TRUE;
4405 }
4406
4407 /* only one should return true */
4410
4411 /* evaluate solution status */
4412 if( SCIPlpiExactIsOptimal(lpexact->lpiexact) )
4413 {
4414 assert(lpexact->primalfeasible && lpexact->dualfeasible);
4415
4416 SCIP_CALL( SCIPlpiExactGetObjval(lpexact->lpiexact, lpexact->lpobjval) );
4417 SCIPdebugMessage("Exact lp solve terminated with optimal. Safe dual bound is %e, previous lp obj-val was %e \n",
4420 lp->validsollp = stat->lpcount;
4421
4422 if( !SCIPsetIsInfinity(set, lpexact->lpiobjlim) && SCIPrationalIsGTReal(lpexact->lpobjval, lpexact->lpiobjlim) )
4423 {
4424 /* the solver may return the optimal value, even if this is greater or equal than the upper bound */
4425 SCIPrationalDebugMessage("optimal solution %q exceeds objective limit %.15g\n", lpexact->lpobjval, lp->lpiobjlim);
4428 }
4429 }
4430 else if( SCIPlpiExactIsObjlimExc(lpexact->lpiexact) )
4431 {
4434 }
4435 else if( SCIPlpiExactIsPrimalInfeasible(lpexact->lpiexact) )
4436 {
4439 }
4440 else if( SCIPlpiExactIsPrimalUnbounded(lpexact->lpiexact) )
4441 {
4444 }
4445 else if( SCIPlpiExactIsIterlimExc(lpexact->lpiexact) )
4446 {
4449 }
4450 else if( SCIPlpiExactIsTimelimExc(lpexact->lpiexact) )
4451 {
4454 }
4455 else
4456 {
4457 SCIPdebugMessage("(node %" SCIP_LONGINT_FORMAT ") error or unknown return status of %s in LP %" SCIP_LONGINT_FORMAT " (internal status: %d)\n",
4458 stat->nnodes, &algo, stat->nlps, SCIPlpiExactGetInternalStatus(lpexact->lpiexact));
4460 lpexact->solved = FALSE;
4461 *lperror = TRUE;
4462 return SCIP_OKAY;
4463 }
4464 }
4465 while( solveagain == TRUE );
4466
4467 lpexact->solved = TRUE;
4468
4469 SCIPsetDebugMsg(set, "solving exact LP with %d returned solstat=%d (internal status: %d, primalfeasible=%u, dualfeasible=%u)\n",
4470 algo, lpexact->lpsolstat, SCIPlpiExactGetInternalStatus(lpexact->lpiexact),
4472
4473 return SCIP_OKAY;
4474}
4475
4476/** solves the LP with simplex algorithm, and copy the solution into the column's data */
4478 SCIP_LPEXACT* lpexact, /**< LP data */
4479 SCIP_LP* lp, /**< LP data */
4480 SCIP_SET* set, /**< global SCIP settings */
4481 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
4482 BMS_BLKMEM* blkmem, /**< block memory buffers */
4483 SCIP_STAT* stat, /**< problem statistics */
4484 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
4485 SCIP_PROB* prob, /**< problem data */
4486 SCIP_Longint itlim, /**< maximal number of LP iterations to perform, or -1 for no limit */
4487 SCIP_Bool* lperror, /**< pointer to store whether an unresolved LP error occurred */
4488 SCIP_Bool usefarkas /**< are we aiming to prove infeasibility? */
4489 )
4490{
4491 SCIP_RETCODE retcode;
4492 SCIP_Bool overwritefplp;
4493 SCIP_Bool primalfeasible;
4494 SCIP_Bool dualfeasible;
4495 SCIP_Bool* primalfeaspointer;
4496 SCIP_Bool* dualfeaspointer;
4497 int harditlim;
4498 SCIP_Bool farkasvalid;
4499 SCIP_Bool fromscratch;
4500 int iterations;
4501 SCIP_Real previoustime;
4502
4503 assert(lp != NULL);
4504 assert(lpexact != NULL);
4505 assert(prob != NULL);
4506 assert(prob->nvars >= lp->ncols);
4507 assert(lperror != NULL);
4508
4509 retcode = SCIP_OKAY;
4510 *lperror = FALSE;
4511
4512 /* to avoid complications, we just always overwrite the fp lp */
4513 overwritefplp = TRUE;
4514
4515 /* compute the limit for the number of LP resolving iterations, if needed (i.e. if limitresolveiters == TRUE) */
4516 harditlim = (int) MIN(itlim, INT_MAX);
4517
4518 if( usefarkas )
4519 {
4520 previoustime = SCIPclockGetTime(stat->provedinfeaslptime);
4522 }
4523 else
4524 {
4525 previoustime = SCIPclockGetTime(stat->provedfeaslptime);
4527 }
4528
4529 /* set initial LP solver settings */
4530 fromscratch = FALSE;
4531 primalfeasible = FALSE;
4532 dualfeasible = FALSE;
4533
4534 /* solve the LP */
4535 SCIP_CALL( lpExactFlushAndSolve(lpexact, blkmem, set, messagehdlr, stat,
4536 prob, eventqueue, harditlim, fromscratch, lperror) );
4537 assert(!(*lperror) || !lpexact->solved);
4538
4539 SCIP_CALL( SCIPlpExactGetIterations(lpexact, &iterations) );
4540
4541 if( usefarkas )
4542 SCIPstatAdd(stat, set, niterationsexlpinf, iterations);
4543 else
4544 SCIPstatAdd(stat, set, niterationsexlp, iterations);
4545
4546 /* if not already done, solve again from scratch */
4547 if( *lperror )
4548 {
4549 lpExactNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve exact lp again from scratch");
4550 *lperror = FALSE;
4551 SCIP_CALL( lpExactFlushAndSolve(lpexact, blkmem, set, messagehdlr, stat,
4552 prob, eventqueue, harditlim, TRUE, lperror) );
4553 }
4554
4555 SCIP_CALL( SCIPlpExactGetIterations(lpexact, &iterations) );
4556 if( usefarkas )
4557 SCIPstatAdd(stat, set, niterationsexlpinf, iterations);
4558 else
4559 SCIPstatAdd(stat, set, niterationsexlp, iterations);
4560
4561 /* check for error */
4562 if( *lperror )
4563 {
4564 retcode = SCIP_OKAY;
4565 lp->hasprovedbound = FALSE;
4566 goto TERMINATE;
4567 }
4568
4569 /* evaluate solution status */
4570 switch( lpexact->lpsolstat )
4571 {
4573 /* get LP solution and possibly check the solution's feasibility again */
4574 if( set->lp_checkprimfeas )
4575 {
4576 primalfeaspointer = &primalfeasible;
4577 lp->primalchecked = TRUE;
4578 }
4579 else
4580 {
4581 /* believe in the primal feasibility of the LP solution */
4582 primalfeasible = TRUE;
4583 primalfeaspointer = NULL;
4584 lp->primalchecked = FALSE;
4585 }
4586 if( set->lp_checkdualfeas )
4587 {
4588 dualfeaspointer = &dualfeasible;
4589 lp->dualchecked = TRUE;
4590 }
4591 else
4592 {
4593 /* believe in the dual feasibility of the LP solution */
4594 dualfeasible = TRUE;
4595 dualfeaspointer = NULL;
4596 lp->dualchecked = FALSE;
4597 }
4598
4599 overwritefplp = overwritefplp || (lpexact->lpsolstat != lp->lpsolstat);
4600 SCIP_CALL( SCIPlpExactGetSol(lpexact, set, stat, primalfeaspointer, dualfeaspointer, overwritefplp) );
4601
4602 lpexact->primalfeasible = primalfeasible && lpexact->primalfeasible;
4603 lpexact->dualfeasible = dualfeasible && lpexact->dualfeasible;
4604
4605 if( primalfeasible && dualfeasible )
4606 {
4608 lp->hasprovedbound = TRUE;
4609 }
4610 else
4611 {
4612 /* print common begin of message */
4613 SCIPmessagePrintInfo(messagehdlr, "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in exact LP %" SCIP_LONGINT_FORMAT " -- ",stat->nnodes, stat->nlps);
4614 lp->solved = FALSE;
4616 *lperror = TRUE;
4617 }
4618 break;
4619
4621 SCIPsetDebugMsg(set, " -> LP infeasible\n");
4622 if( SCIPlpiExactHasDualRay(lpexact->lpiexact) )
4623 {
4624 SCIP_CALL( SCIPlpExactGetDualfarkas(lpexact, set, stat, &farkasvalid, overwritefplp) );
4625 lp->solved = TRUE;
4628 lp->hasprovedbound = farkasvalid;
4629 }
4630 else
4631 {
4632 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
4633 "(node %" SCIP_LONGINT_FORMAT ") infeasibility of LP %" SCIP_LONGINT_FORMAT " could not be proven by dual ray\n", stat->nnodes, stat->nlps);
4634 lp->solved = FALSE;
4637 farkasvalid = FALSE;
4638 *lperror = TRUE;
4639 }
4640
4641 /* if the LP solver does not provide a Farkas proof we don't want to resolve the LP */
4642 if( !farkasvalid && !(*lperror) )
4643 {
4644 /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems) and nothing
4645 * helped forget about the LP at this node and mark it to be unsolved
4646 */
4647 SCIPmessagePrintInfo(messagehdlr, "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in exakt LP %" SCIP_LONGINT_FORMAT " -- ",stat->nnodes, stat->nlps);
4648 lp->solved = FALSE;
4650 *lperror = TRUE;
4651 }
4652
4653 break;
4654
4656 SCIPsetDebugMsg(set, " -> LP unbounded\n");
4657 SCIPwarningMessage(set->scip, "Exact LP solver returned unbounded ray: handling not fully supported.\n");
4658 break;
4659
4661 assert(!lpCutoffDisabled(set));
4662 /* Some LP solvers, e.g. CPLEX With FASTMIP setting, do not apply the final pivot to reach the dual solution
4663 * exceeding the objective limit. In some cases like branch-and-price, however, we must make sure that a dual
4664 * feasible solution exists that exceeds the objective limit. Therefore, we have to continue solving it without
4665 * objective limit for at least one iteration. We first try to continue with FASTMIP for one additional simplex
4666 * iteration using the steepest edge pricing rule. If this does not fix the problem, we temporarily disable
4667 * FASTMIP and solve again. */
4668 {
4669 SCIP_RATIONAL* objval;
4670
4671 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &objval) );
4672 /* actually, SCIPsetIsGE(set, lp->lpobjval, lp->lpiuobjlim) should hold, but we are a bit less strict in
4673 * the assert by using !SCIPsetIsFeasNegative()
4674 */
4675
4676 SCIP_CALL( SCIPlpiExactGetObjval(lpexact->lpiexact, objval) );
4677
4678 /* do one additional simplex step if the computed dual solution doesn't exceed the objective limit */
4679 if( SCIPrationalIsLTReal(objval, lpexact->lpiobjlim) )
4680 {
4681 SCIP_Real tmpcutoff;
4682 char tmppricingchar;
4683 SCIP_LPSOLSTAT solstat;
4684
4685 SCIPrationalDebugMessage("objval = %q < %f = lp->lpiobjlim, but status objlimit\n", objval, lp->lpiobjlim);
4686
4687 /* temporarily disable cutoffbound, which also disables the objective limit */
4688 tmpcutoff = lpexact->cutoffbound;
4689 lpexact->cutoffbound = SCIPsetInfinity(set);
4690
4691 /* set lp pricing strategy to steepest edge */
4692 SCIP_CALL( SCIPsetGetCharParam(set, "lp/pricing", &tmppricingchar) );
4693 SCIP_CALL( SCIPsetSetCharParam(set, messagehdlr, "lp/pricing", 's') );
4694
4695 /* resolve LP with an iteration limit of 1 */
4696 SCIP_CALL( lpExactFlushAndSolve(lpexact, blkmem, set, messagehdlr, stat, prob, eventqueue, 1, FALSE, lperror) );
4697
4698 /* reinstall old cutoff bound and lp pricing strategy */
4699 lpexact->cutoffbound = tmpcutoff;
4700 SCIP_CALL( SCIPsetSetCharParam(set, messagehdlr, "lp/pricing", tmppricingchar) );
4701
4702 /* get objective value */
4703 SCIP_CALL( SCIPlpiExactGetObjval(lpexact->lpiexact, objval) );
4704
4705 /* get solution status for the lp */
4706 solstat = lpexact->lpsolstat;
4707 assert(solstat != SCIP_LPSOLSTAT_OBJLIMIT);
4708
4709 if( !(*lperror) && solstat != SCIP_LPSOLSTAT_ERROR && solstat != SCIP_LPSOLSTAT_NOTSOLVED )
4710 {
4711 SCIPrationalDebugMessage(" ---> new objval = %q (solstat: %d, 1 add. step)\n", objval, solstat);
4712 }
4713
4714 /* check for lp errors */
4715 if( *lperror || solstat == SCIP_LPSOLSTAT_ERROR || solstat == SCIP_LPSOLSTAT_NOTSOLVED )
4716 {
4717 SCIPsetDebugMsg(set, "unresolved error while resolving LP in order to exceed the objlimit\n");
4718 lp->solved = FALSE;
4721 lp->hasprovedbound = FALSE;
4722
4723 retcode = *lperror ? SCIP_OKAY : SCIP_LPERROR;
4724 SCIPrationalFreeBuffer(set->buffer, &objval);
4725 goto TERMINATE;
4726 }
4727
4728 lpexact->solved = TRUE;
4729 lp->hasprovedbound = TRUE;
4730
4731 /* optimal solution / objlimit with fastmip turned off / itlimit or timelimit, but objlimit exceeded */
4732 if( solstat == SCIP_LPSOLSTAT_OPTIMAL || solstat == SCIP_LPSOLSTAT_OBJLIMIT
4733 || ( (solstat == SCIP_LPSOLSTAT_ITERLIMIT || solstat == SCIP_LPSOLSTAT_TIMELIMIT)
4735 {
4736 /* get LP solution and possibly check the solution's feasibility again */
4737 if( set->lp_checkprimfeas )
4738 {
4739 primalfeaspointer = &primalfeasible;
4740 lp->primalchecked = TRUE;
4741 }
4742 else
4743 {
4744 /* believe in the primal feasibility of the LP solution */
4745 primalfeasible = TRUE;
4746 primalfeaspointer = NULL;
4747 lp->primalchecked = FALSE;
4748 }
4749 if( set->lp_checkdualfeas )
4750 {
4751 dualfeaspointer = &dualfeasible;
4752 lp->dualchecked = TRUE;
4753 }
4754 else
4755 {
4756 /* believe in the dual feasibility of the LP solution */
4757 dualfeasible = TRUE;
4758 dualfeaspointer = NULL;
4759 lp->dualchecked = FALSE;
4760 }
4761
4762 SCIP_CALL( SCIPlpExactGetSol(lpexact, set, stat, primalfeaspointer, dualfeaspointer, TRUE) );
4763
4764 /* if objective value is larger than the cutoff bound, set solution status to objective
4765 * limit reached and objective value to infinity, in case solstat = SCIP_LPSOLSTAT_OBJLIMIT,
4766 * this was already done in the lpSolve() method
4767 */
4769 {
4772 lp->hasprovedbound = TRUE;
4774 }
4775
4776 /* LP solution is not feasible or objective limit was reached without the LP value really exceeding
4777 * the cutoffbound; mark the LP to be unsolved
4778 */
4779 if( !primalfeasible || !dualfeasible
4780 || (solstat == SCIP_LPSOLSTAT_OBJLIMIT &&
4782 {
4783 SCIPmessagePrintInfo(messagehdlr, "(node %" SCIP_LONGINT_FORMAT ") numerical troubles exact in LP %" SCIP_LONGINT_FORMAT " \n ", stat->nnodes, stat->nlps);
4784 lp->solved = FALSE;
4786 lp->hasprovedbound = FALSE;
4787 *lperror = TRUE;
4788 }
4789 }
4790 /* infeasible solution */
4791 else if( solstat == SCIP_LPSOLSTAT_INFEASIBLE )
4792 {
4793 SCIPsetDebugMsg(set, " -> LPexact infeasible\n");
4794
4795 if( SCIPlpiExactHasDualRay(lpexact->lpiexact) )
4796 {
4797 SCIP_CALL( SCIPlpExactGetDualfarkas(lpexact, set, stat, &farkasvalid, TRUE) );
4798 }
4799 /* it might happen that we have no infeasibility proof for the current LP (e.g. if the LP was always solved
4800 * with the primal simplex due to numerical problems) - treat this case like an LP error
4801 */
4802 else
4803 {
4804 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
4805 "(node %" SCIP_LONGINT_FORMAT ") infeasibility of exact LP %" SCIP_LONGINT_FORMAT " could not be proven by dual ray\n", stat->nnodes, stat->nlps);
4806 lp->solved = FALSE;
4808 lp->hasprovedbound = FALSE;
4809 farkasvalid = FALSE;
4810 *lperror = TRUE;
4811 }
4812 if( !farkasvalid )
4813 {
4814 /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems) and nothing
4815 * helped forget about the LP at this node and mark it to be unsolved
4816 */
4817 SCIPmessagePrintInfo(messagehdlr, "(node %" SCIP_LONGINT_FORMAT ") numerical troubles exact in LP %" SCIP_LONGINT_FORMAT " \n ", stat->nnodes, stat->nlps);
4818 lp->solved = FALSE;
4820 lp->hasprovedbound = FALSE;
4821 *lperror = TRUE;
4822 }
4823 }
4824 /* unbounded solution */
4825 else if( solstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY )
4826 {
4827 SCIP_Bool rayfeasible;
4828
4829 if( set->lp_checkprimfeas )
4830 {
4831 /* get unbounded LP solution and check the solution's feasibility again */
4832 SCIP_CALL( SCIPlpExactGetUnboundedSol(lpexact, set, stat, &primalfeasible, &rayfeasible) );
4833
4834 lp->primalchecked = TRUE;
4835 }
4836 else
4837 {
4838 /* get unbounded LP solution believing in its feasibility */
4839 SCIP_CALL( SCIPlpExactGetUnboundedSol(lpexact, set, stat, NULL, NULL) );
4840
4841 rayfeasible = TRUE;
4842 primalfeasible = TRUE;
4843 lp->primalchecked = FALSE;
4844 }
4845
4846 SCIPsetDebugMsg(set, " -> exact LP has unbounded primal ray\n");
4847
4848 if( !primalfeasible || !rayfeasible )
4849 {
4850 /* unbounded solution is infeasible (this can happen due to numerical problems):
4851 * forget about the LP at this node and mark it to be unsolved
4852 *
4853 * @todo: like in the default LP solving evaluation, solve without fastmip,
4854 * with tighter feasibility tolerance and from scratch
4855 */
4856 SCIPmessagePrintInfo(messagehdlr, "(node %" SCIP_LONGINT_FORMAT ") numerical troubles exact in LP %" SCIP_LONGINT_FORMAT " \n ",
4857 stat->nnodes, stat->nlps);
4858 lp->solved = FALSE;
4860 lp->hasprovedbound = FALSE;
4861 *lperror = TRUE;
4862 }
4863 }
4864
4865 assert(lp->lpsolstat != SCIP_LPSOLSTAT_ITERLIMIT);
4868 }
4869 else
4870 {
4871 overwritefplp = overwritefplp || (lpexact->lpsolstat != lp->lpsolstat);
4872 SCIP_CALL( SCIPlpExactGetSol(lpexact, set, stat, NULL, NULL, overwritefplp) );
4873 lp->hasprovedbound = TRUE;
4874 }
4875
4876 SCIPrationalFreeBuffer(set->buffer, &objval);
4877 }
4878 SCIPsetDebugMsg(set, " -> LP objective limit reached\n");
4879 break;
4880
4882 SCIPsetDebugMsg(set, " -> LP iteration limit exceeded\n");
4883 break;
4884
4886 SCIPsetDebugMsg(set, " -> LP time limit exceeded\n");
4887
4888 /* make sure that we evaluate the time limit exactly in order to avoid erroneous warning */
4889 stat->nclockskipsleft = 0;
4890 if( !SCIPsolveIsStopped(set, stat, FALSE) )
4891 {
4892 SCIPmessagePrintWarning(messagehdlr, "LP solver reached time limit, but SCIP time limit is not exceeded yet; "
4893 "you might consider switching the clock type of SCIP\n");
4895 }
4896
4897 /* set the status of the floating point lp also to timelimit to avoid using the uncorrected bound */
4899 lp->solved = TRUE;
4900 break;
4901
4904 SCIPerrorMessage("error in LP solver\n");
4905 retcode = SCIP_LPERROR;
4906 goto TERMINATE;
4907
4908 default:
4909 SCIPerrorMessage("unknown LP solution status\n");
4910 retcode = SCIP_ERROR;
4911 goto TERMINATE;
4912 }
4913
4914TERMINATE:
4915
4916 /* stop timing and update number of calls and fails, and proved bound status */
4917 if( usefarkas )
4918 {
4920 stat->nexlpinf++;
4921 if( *lperror )
4922 stat->timefailexlpinf += SCIPclockGetTime(stat->provedinfeaslptime) - previoustime;
4923 }
4924 else
4925 {
4927 stat->nexlp++;
4928 if( *lperror )
4929 stat->timefailexlp += SCIPclockGetTime(stat->provedfeaslptime) - previoustime;
4930 }
4931
4932 return retcode;
4933}
4934
4935/*
4936 * row methods
4937 */
4938
4939/** increases usage counter of LP row */
4941 SCIP_ROWEXACT* row /**< LP row */
4942 )
4943{
4944 assert(row != NULL);
4945 assert(row->nuses >= 0);
4946 assert(row->nlocks <= (unsigned int)(row->nuses)); /*lint !e574*/
4947
4948 SCIPdebugMessage("capture row <%s> with nuses=%d and nlocks=%u\n", row->fprow->name, row->nuses, row->nlocks);
4949 row->nuses++;
4950}
4951
4952/** output column to file stream */
4954 SCIP_ROWEXACT* row, /**< LP row */
4955 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
4956 FILE* file /**< output file (or NULL for standard output) */
4957 )
4958{
4959 int r;
4960
4961 assert(row != NULL);
4962 assert(row->fprow != NULL);
4963
4964 SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", row->fprow->name);
4965 SCIPrationalMessage(messagehdlr, file, row->lhs);
4966 SCIPmessageFPrintInfo(messagehdlr, file, " <= ");
4967
4968 /* print coefficients */
4969 if( row->len == 0 )
4970 SCIPmessageFPrintInfo(messagehdlr, file, "<empty>");
4971 for( r = 0; r < row->len; ++r )
4972 {
4973 assert(SCIPvarGetName(row->cols[r]->var) != NULL);
4974 assert(SCIPvarGetStatus(row->cols[r]->var) == SCIP_VARSTATUS_COLUMN);
4975 if( SCIPrationalIsPositive(row->vals[r]) )
4976 SCIPmessageFPrintInfo(messagehdlr, file, "+ ");
4977
4978 SCIPrationalMessage(messagehdlr, file, row->vals[r]);
4979 SCIPmessageFPrintInfo(messagehdlr, file, "(%g)<%s> ", SCIPrationalGetReal(row->vals[r]), SCIPvarGetName(row->cols[r]->var));
4980 }
4981
4982 /* print constant */
4983 if( !SCIPrationalIsZero(row->constant) )
4984 {
4986 SCIPmessageFPrintInfo(messagehdlr, file, "+");
4987 SCIPrationalMessage(messagehdlr, file, row->constant);
4988 }
4989
4990 SCIPmessageFPrintInfo(messagehdlr, file, "<= , ");
4991 SCIPrationalMessage(messagehdlr, file, row->rhs);
4992 SCIPmessageFPrintInfo(messagehdlr, file, "\n");
4993}
4994
4995/** get the index of an exact row */
4997 SCIP_ROWEXACT* row /**< LP row */
4998 )
4999{
5000 assert(row != NULL);
5001
5002 return row->index;
5003}
5004
5005/** gets the length of a row */
5007 SCIP_ROWEXACT* row /**< LP row */
5008 )
5009{
5010 assert(row != NULL);
5011
5012 return row->len;
5013}
5014
5015/** gets array with coefficients of nonzero entries */
5017 SCIP_ROWEXACT* row /**< LP row */
5018 )
5019{
5020 assert(row != NULL);
5021
5022 return row->vals;
5023}
5024
5025/** gets array of exact columns */
5027 SCIP_ROWEXACT* row /**< LP row */
5028 )
5029{
5030 assert(row != NULL);
5031
5032 return row->cols;
5033}
5034
5035/** returns TRUE iff row is member of current LP */
5037 SCIP_ROWEXACT* row /**< LP row */
5038 )
5039{
5040 assert(row != NULL);
5041
5042 return (row->lppos >= 0);
5043}
5044
5045/** return TRUE iff row is modifiable */
5047 SCIP_ROWEXACT* row /**< LP row */
5048 )
5049{
5050 assert(row != NULL);
5051 assert(row->fprow != NULL);
5052
5053 return row->fprow->modifiable;
5054}
5055
5056/** returns true, if an exact row for this fprow was already created */
5058 SCIP_LPEXACT* lpexact, /**< exact lp data structure */
5059 SCIP_ROW* row /**< SCIP row */
5060 )
5061{
5062 assert(row != NULL);
5063 assert(lpexact != NULL);
5064
5065 return (NULL != row->rowexact);
5066}
5067
5068/** returns fp row corresponding to exact row, if it exists. Otherwise returns NULL */
5070 SCIP_ROWEXACT* row /**< SCIP row */
5071 )
5072{
5073 assert(row != NULL);
5074
5075 return row->fprow;
5076}
5077
5078/** returns rhs-relaxation part of exact row, if it exists. Otherwise returns NULL */
5080 SCIP_ROWEXACT* row /**< SCIP row */
5081 )
5082{
5083 assert(row != NULL);
5084
5085 return row->fprowrhs;
5086}
5087
5088/** true if row can be relaxed (possibly as two fp rows) */
5090 SCIP_ROWEXACT* row /**< SCIP row */
5091 )
5092{
5093 assert(row != NULL);
5094
5095 return row->fprelaxable;
5096}
5097
5098/** returns exact col corresponding to fpcol, if it exists. Otherwise returns NULL */
5100 SCIP_COL* col /**< SCIP col */
5101 )
5102{
5103 assert(col != NULL);
5104 assert(col->var != NULL);
5105 assert(col->var->exactdata != NULL);
5106
5107 return col->var->exactdata->colexact;
5108}
5109
5110/** calculates the Farkas coefficient y^T A_i or reduced cost c - y^T A_i of a column i using the given dual Farkas vector y */
5112 SCIP_COLEXACT* col, /**< LP column */
5113 SCIP_SET* set, /**< SCIP settings pointer */
5114 SCIP_RATIONAL* result, /**< rational to store the result */
5115 SCIP_RATIONAL** dual, /**< dense dual vector, NULL to use internal row-values */
5116 SCIP_Bool usefarkas /**< should the farkas coefficient be computed ? */
5117 )
5118{
5119 SCIP_ROWEXACT* row;
5120 SCIP_RATIONAL* val;
5121 SCIP_RATIONAL* tmp;
5122 int i;
5123
5124 assert(col != NULL);
5126 assert(SCIPvarGetColExact(col->var) == col);
5127
5128 if( usefarkas )
5129 SCIPrationalSetFraction(result, 0LL, 1LL);
5130 else
5131 SCIPrationalSetRational(result, col->obj);
5132
5133 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &tmp) );
5134
5135 for( i = 0; i < col->nlprows; ++i )
5136 {
5137 row = col->rows[i];
5138 assert(row != NULL);
5139 assert(row->lppos >= 0);
5140
5141 if( usefarkas )
5142 val = (dual == NULL) ? row->dualfarkas : dual[row->lppos];
5143 else
5144 val = (dual == NULL) ? row->dualsol : dual[row->lppos];
5145
5146 assert(!SCIPrationalIsInfinity(val));
5147
5148 SCIPrationalMult(tmp, col->vals[i], val);
5149 if( usefarkas )
5150 SCIPrationalAdd(result, result, tmp);
5151 else
5152 SCIPrationalDiff(result, result, tmp);
5153 }
5154
5155 if( col->nunlinked > 0 )
5156 {
5157 for( i = col->nlprows; i < col->len; ++i )
5158 {
5159 row = col->rows[i];
5160 assert(row != NULL);
5161 assert(row->lppos == -1 || col->linkpos[i] == -1);
5162 if( row->lppos >= 0 )
5163 {
5164 if( usefarkas )
5165 val = (dual == NULL) ? row->dualfarkas : dual[row->lppos];
5166 else
5167 val = (dual == NULL) ? row->dualsol : dual[row->lppos];
5168
5169 SCIPrationalMult(tmp, col->vals[i], val);
5170 if( usefarkas )
5171 SCIPrationalAdd(result, result, tmp);
5172 else
5173 SCIPrationalDiff(result, result, tmp);
5174 }
5175 }
5176 }
5177#ifndef NDEBUG
5178 else
5179 {
5180 for( i = col->nlprows; i < col->len; ++i )
5181 {
5182 row = col->rows[i];
5183 assert(row != NULL);
5184 assert(row->lppos == -1);
5185 assert(col->linkpos[i] >= 0);
5186 if( dual == NULL )
5187 assert((usefarkas && SCIPrationalIsZero(row->dualfarkas)) || SCIPrationalIsZero(row->dualsol));
5188 }
5189 assert(!SCIPrationalIsPositive(result) || !SCIPrationalIsInfinity(col->ub));
5190 assert(!SCIPrationalIsNegative(result) || !SCIPrationalIsNegInfinity(col->lb));
5191 }
5192#endif
5193
5194 SCIPrationalFreeBuffer(set->buffer, &tmp);
5195
5196 return SCIP_OKAY;
5197}
5198
5199/** adds a previously non existing coefficient to an LP row */
5201 SCIP_ROWEXACT* rowexact, /**< LP row */
5202 BMS_BLKMEM* blkmem, /**< block memory */
5203 SCIP_SET* set, /**< global SCIP settings */
5204 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5205 SCIP_LPEXACT* lpexact, /**< current LP data */
5206 SCIP_COLEXACT* colexact, /**< LP column */
5207 SCIP_RATIONAL* val /**< value of coefficient */
5208 )
5209{
5210 assert(rowexact != NULL);
5211 assert(colexact != NULL);
5212 assert(lpexact != NULL);
5213
5214 assert(lpexact != NULL);
5215 assert(!lpexact->fplp->diving || rowexact->fprow->lppos == -1);
5216
5217 SCIP_CALL( rowExactAddCoef(rowexact, blkmem, set, eventqueue, lpexact, colexact, val, -1) );
5218
5219 checkLinks(lpexact);
5220
5221 return SCIP_OKAY;
5222}
5223
5224/** deletes coefficient from row */
5226 SCIP_ROWEXACT* row, /**< row to be changed */
5227 SCIP_SET* set, /**< global SCIP settings */
5228 SCIP_LPEXACT* lpexact, /**< current LP data */
5229 SCIP_COLEXACT* col /**< coefficient to be deleted */
5230 )
5231{
5232 int pos;
5233
5234 assert(row != NULL);
5235 assert(!row->delaysort);
5236 assert(lpexact != NULL);
5237 assert(!lpexact->fplp->diving || row->lppos == -1);
5238 assert(col != NULL);
5239 assert(col->var != NULL);
5240
5241 /* search the position of the column in the row's col vector */
5242 pos = rowExactSearchCoef(row, col);
5243 if( pos == -1 )
5244 {
5245 SCIPerrorMessage("coefficient for column <%s> doesn't exist in row <%s>\n", SCIPvarGetName(col->var), row->fprow->name);
5246 return SCIP_INVALIDDATA;
5247 }
5248 assert(0 <= pos && pos < row->len);
5249 assert(row->cols[pos] == col);
5250 assert(row->cols_index[pos] == col->index);
5251
5252 /* if column knows of the row, remove the row from the column's row vector */
5253 if( row->linkpos[pos] >= 0 )
5254 {
5255 assert(col->rows[row->linkpos[pos]] == row);
5256 assert(SCIPrationalIsEQ(col->vals[row->linkpos[pos]], row->vals[pos]));
5257 SCIP_CALL( colExactDelCoefPos(col, set, lpexact, row->linkpos[pos]) );
5258 }
5259
5260 /* delete the column from the row's col vector */
5261 SCIP_CALL( rowExactDelCoefPos(row, set, lpexact, pos) );
5262
5263 checkLinks(lpexact);
5264
5265 return SCIP_OKAY;
5266}
5267
5268/** changes or adds a coefficient to an LP row */
5270 SCIP_ROWEXACT* row, /**< LP row */
5271 BMS_BLKMEM* blkmem, /**< block memory */
5272 SCIP_SET* set, /**< global SCIP settings */
5273 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5274 SCIP_LPEXACT* lpexact, /**< current LP data */
5275 SCIP_COLEXACT* col, /**< LP column */
5276 SCIP_RATIONAL* val /**< value of coefficient */
5277 )
5278{
5279 int pos;
5280
5281 assert(row != NULL);
5282 assert(!row->delaysort);
5283 assert(lpexact != NULL);
5284 assert(!lpexact->fplp->diving || row->lppos == -1);
5285 assert(col != NULL);
5286
5287 /* search the position of the column in the row's col vector */
5288 pos = rowExactSearchCoef(row, col);
5289
5290 /* check, if column already exists in the row's col vector */
5291 if( pos == -1 )
5292 {
5293 /* add previously not existing coefficient */
5294 SCIP_CALL( rowExactAddCoef(row, blkmem, set, eventqueue, lpexact, col, val, -1) );
5295 }
5296 else
5297 {
5298 /* modify already existing coefficient */
5299 assert(0 <= pos && pos < row->len);
5300 assert(row->cols[pos] == col);
5301 assert(row->cols_index[pos] == col->index);
5302
5303 /* if column knows of the row, change the corresponding coefficient in the column */
5304 if( row->linkpos[pos] >= 0 )
5305 {
5306 assert(col->rows[row->linkpos[pos]] == row);
5307 assert(SCIPrationalIsEQ(col->vals[row->linkpos[pos]], row->vals[pos]));
5308 SCIP_CALL( colExactChgCoefPos(col, set, lpexact, row->linkpos[pos], val) );
5309 }
5310
5311 /* change the coefficient in the row */
5312 SCIP_CALL( rowExactChgCoefPos(row, set, lpexact, pos, val) );
5313 }
5314
5315 checkLinks(lpexact);
5316
5317 return SCIP_OKAY;
5318}
5319
5320/** increases value of an existing or non-existing coefficient in an LP row */
5322 SCIP_ROWEXACT* row, /**< LP row */
5323 BMS_BLKMEM* blkmem, /**< block memory */
5324 SCIP_SET* set, /**< global SCIP settings */
5325 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5326 SCIP_LPEXACT* lpexact, /**< current LP data */
5327 SCIP_COLEXACT* col, /**< LP column */
5328 SCIP_RATIONAL* incval /**< value to add to the coefficient */
5329 )
5330{
5331 int pos;
5332 SCIP_RATIONAL* tmp;
5333
5334 assert(row != NULL);
5335 assert(lpexact != NULL);
5336 assert(!lpexact->fplp->diving || row->lppos == -1);
5337 assert(col != NULL);
5338
5339 if( SCIPrationalIsZero(incval) )
5340 return SCIP_OKAY;
5341
5342 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &tmp) );
5343
5344 /* search the position of the column in the row's col vector */
5345 pos = rowExactSearchCoef(row, col);
5346
5347 /* check, if column already exists in the row's col vector */
5348 if( pos == -1 )
5349 {
5350 /* coefficient doesn't exist, or sorting is delayed: add coefficient to the end of the row's arrays */
5351 SCIP_CALL( rowExactAddCoef(row, blkmem, set, eventqueue, lpexact, col, incval, -1) );
5352 }
5353 else
5354 {
5355 /* modify already existing coefficient */
5356 assert(0 <= pos && pos < row->len);
5357 assert(row->cols[pos] == col);
5358 assert(row->cols_index[pos] == col->index);
5359
5360 SCIPrationalAdd(tmp, incval, row->vals[pos]);
5361
5362 /* if column knows of the row, change the corresponding coefficient in the column */
5363 if( row->linkpos[pos] >= 0 )
5364 {
5365 assert(col->rows[row->linkpos[pos]] == row);
5366 assert(SCIPrationalIsEQ(col->vals[row->linkpos[pos]], row->vals[pos]));
5367 SCIP_CALL( colExactChgCoefPos(col, set, lpexact, row->linkpos[pos], tmp) );
5368 }
5369
5370 /* change the coefficient in the row */
5371 SCIP_CALL( rowExactChgCoefPos(row, set, lpexact, pos, tmp) );
5372 }
5373
5374 checkLinks(lpexact);
5375
5376 /* invalid the activity */
5377 row->validactivitylp = -1;
5378
5379 SCIPrationalFreeBuffer(set->buffer, &tmp);
5380
5381 return SCIP_OKAY;
5382}
5383
5384/** changes constant value of a row */
5386 SCIP_ROWEXACT* row, /**< LP row */
5387 SCIP_STAT* stat, /**< problem statistics */
5388 SCIP_LPEXACT* lpexact, /**< current LP data */
5389 SCIP_RATIONAL* constant /**< new constant value */
5390 )
5391{
5392 assert(row != NULL);
5393 assert(SCIPrationalIsLE(row->lhs, row->rhs));
5394 assert(!SCIPrationalIsAbsInfinity(constant));
5395 assert(stat != NULL);
5396 assert(lpexact != NULL);
5397 assert(!lpexact->fplp->diving || row->fprow->lppos == -1);
5398
5399 if( !SCIPrationalIsEQ(constant, row->constant) )
5400 {
5401 if( row->fprow->validpsactivitydomchg == stat->domchgcount )
5402 {
5404 SCIPrationalAdd(row->pseudoactivity, row->pseudoactivity, constant);
5406 }
5407
5408 SCIPrationalSetRational(row->constant, constant);
5409 SCIPintervalSetRational(&row->constantreal, constant);
5410 }
5411
5412 return SCIP_OKAY;
5413}
5414
5415/** add constant value to a row */
5417 SCIP_ROWEXACT* row, /**< LP row */
5418 SCIP_SET* set, /**< global SCIP settings */
5419 SCIP_STAT* stat, /**< problem statistics */
5420 SCIP_LPEXACT* lpexact, /**< current LP data */
5421 SCIP_RATIONAL* addval /**< constant value to add to the row */
5422 )
5423{
5424 SCIP_RATIONAL* tmp;
5425
5426 assert(row != NULL);
5427 assert(SCIPrationalIsLE(row->lhs, row->rhs));
5428 assert(!SCIPrationalIsAbsInfinity(addval));
5429 assert(stat != NULL);
5430 assert(lpexact != NULL);
5431 assert(!lpexact->fplp->diving || row->fprow->lppos == -1);
5432
5433 if( !SCIPrationalIsZero(addval) )
5434 {
5435 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &tmp) );
5436 SCIPrationalAdd(tmp, row->constant, addval);
5437 SCIP_CALL( SCIProwExactChgConstant(row, stat, lpexact, tmp) );
5438
5439 SCIPrationalFreeBuffer(set->buffer, &tmp);
5440 }
5441
5442 return SCIP_OKAY;
5443}
5444
5445/** returns the feasibility of a row for the given solution */
5447 SCIP_ROWEXACT* row, /**< LP row */
5448 SCIP_SET* set, /**< global SCIP settings */
5449 SCIP_STAT* stat, /**< problem statistics data */
5450 SCIP_SOL* sol, /**< primal CIP solution */
5451 SCIP_RATIONAL* result /**< result pointer */
5452 )
5453{
5454 SCIP_RATIONAL* temp1;
5455 SCIP_RATIONAL* temp2;
5456
5457 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &temp1) );
5458 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &temp2) );
5459
5460 assert(row != NULL);
5461
5462 SCIP_CALL( SCIProwExactGetSolActivity(row, set, stat, sol, FALSE, result) );
5463
5464 SCIPrationalDiff(temp1, row->rhs, result);
5465 SCIPrationalDiff(temp2, result, row->lhs);
5466 SCIPrationalMin(result, temp1, temp2);
5467
5468 SCIPrationalFreeBuffer(set->buffer, &temp2);
5469 SCIPrationalFreeBuffer(set->buffer, &temp1);
5470
5471 return SCIP_OKAY;
5472}
5473
5474/** does activity computation with running error analysis for a row, return TRUE on success */
5476 SCIP_ROWEXACT* rowexact, /**< LP row */
5477 SCIP_SET* set, /**< global SCIP settings */
5478 SCIP_STAT* stat, /**< problem statistics data */
5479 SCIP_SOL* sol, /**< primal CIP solution */
5480 SCIP_Real* activity, /**< the approximate activity */
5481 SCIP_Real* errorbound /**< the error bound */
5482 )
5483{
5484 SCIP_ROW* row;
5485 SCIP_Real solval;
5486 SCIP_Real mu;
5487 SCIP_Real sum;
5488 int c;
5489
5490 assert(rowexact->fprow != NULL);
5491
5492 row = rowexact->fprow;
5493
5494 if( row->len != rowexact->len )
5495 return FALSE;
5496
5497 sum = 0.0;
5498 mu = 0.0;
5499
5500 for( c = 0; c < row->len; c++ )
5501 {
5502 if( sol != NULL)
5503 solval = SCIPsolGetVal(sol, set, stat, SCIPcolGetVar(row->cols[c]));
5504 else
5505 solval = row->cols[c]->primsol;
5506
5507 if( solval == SCIP_UNKNOWN ) /*lint !e777*/
5508 return FALSE;
5509
5510 sum += row->vals[c] * solval;
5511 mu += REALABS(sum);
5512 /* the factor 3 + eps is needed to account for rounding errors in valsreal[v]/solval */
5513 mu += (3.0 + SCIP_REAL_UNITROUNDOFF) * REALABS(row->vals[c] * solval);
5514 }
5515
5516 sum += row->constant;
5517 mu += (3.0 + SCIP_REAL_UNITROUNDOFF) * REALABS(row->constant);
5518
5519 sum = MAX(sum, -SCIPsetInfinity(set)); /*lint !e666*/
5520 sum = MIN(sum, SCIPsetInfinity(set)); /*lint !e666*/
5521
5522 *activity = sum;
5523 *errorbound = mu;
5524
5525 return TRUE;
5526}
5527
5528/** returns the activity of a row for a given solution */
5530 SCIP_ROWEXACT* rowexact, /**< LP row */
5531 SCIP_SET* set, /**< global SCIP settings */
5532 SCIP_STAT* stat, /**< problem statistics data */
5533 SCIP_SOL* sol, /**< primal CIP solution */
5534 SCIP_Bool useexact, /**< should an exact solution be used */
5535 SCIP_RATIONAL* result /**< resulting activity */
5536 )
5537{
5538 SCIP_COLEXACT* colexact;
5539 SCIP_RATIONAL* solval;
5540 int i;
5541
5542 assert(rowexact != NULL);
5543
5544 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &solval) );
5545 SCIPrationalSetRational(result, rowexact->constant);
5546 for( i = 0; i < rowexact->len; ++i )
5547 {
5548 colexact = rowexact->cols[i];
5549
5550 assert(colexact != NULL);
5551
5552 assert((i < rowexact->nlpcols) == (rowexact->linkpos[i] >= 0
5553 && colexact->lppos >= 0));
5554
5555 if( useexact )
5556 SCIPsolGetValExact(solval, sol, set, stat, colexact->var);
5557 else
5558 SCIPrationalSetReal(solval, SCIPsolGetVal(sol, set, stat, colexact->var));
5559
5560 if( SCIPrationalIsAbsInfinity(solval) ) /*lint !e777*/
5561 {
5562 if( SCIPrationalIsNegInfinity(rowexact->lhs) )
5563 SCIPrationalIsPositive(rowexact->vals[i]) ? SCIPrationalSetRational(solval, colexact->lb) : SCIPrationalSetRational(solval, colexact->ub);
5564 else if( SCIPrationalIsInfinity(rowexact->rhs) )
5565 SCIPrationalIsPositive(rowexact->vals[i]) ? SCIPrationalSetRational(solval, colexact->ub) : SCIPrationalSetRational(solval, colexact->lb);
5566 else
5567 {
5568 SCIPrationalAdd(solval, colexact->lb, colexact->ub);
5569 SCIPrationalMultReal(solval, solval, 0.5);
5570 }
5571 }
5572
5573 SCIPrationalMult(solval, solval, rowexact->vals[i]);
5574 SCIPrationalAdd(result, result, solval);
5575 }
5576
5577 SCIPrationalFreeBuffer(set->buffer, &solval);
5578
5579 return SCIP_OKAY;
5580}
5581
5582/** decreases usage counter of LP row, and frees memory if necessary */
5584 SCIP_ROWEXACT** row, /**< pointer to LP row */
5585 BMS_BLKMEM* blkmem, /**< block memory */
5586 SCIP_SET* set, /**< global SCIP settings */
5587 SCIP_LPEXACT* lpexact /**< current LP data */
5588 )
5589{
5590 assert(blkmem != NULL);
5591 assert(row != NULL);
5592 assert(*row != NULL);
5593 assert((*row)->nuses >= 1);
5594 assert((*row)->nlocks < (unsigned int)((*row)->nuses)); /*lint !e574*/
5595
5596 SCIPsetDebugMsg(set, "release exact row <%p> with nuses=%d and nlocks=%u\n",
5597 (void*) (*row), (*row)->nuses, (*row)->nlocks);
5598 (*row)->nuses--;
5599 if( (*row)->nuses == 0 )
5600 {
5601 SCIP_CALL( SCIProwExactFree(row, blkmem, set, lpexact) );
5602 }
5603
5604 *row = NULL;
5605
5606 return SCIP_OKAY;
5607}
5608
5609/** frees an LP row */
5611 SCIP_ROWEXACT** row, /**< pointer to LP row */
5612 BMS_BLKMEM* blkmem, /**< block memory */
5613 SCIP_SET* set, /**< global SCIP settings */
5614 SCIP_LPEXACT* lpexact /**< current LP data */
5615 )
5616{
5617 assert(blkmem != NULL);
5618 assert(row != NULL);
5619 assert(*row != NULL);
5620 assert((*row)->nuses == 0);
5621 assert((*row)->lppos == -1);
5622
5623 /* remove column indices from corresponding rows */
5624 SCIP_CALL( rowExactUnlink(*row, set, lpexact) );
5625
5626 if( (*row)->storedsolvals != NULL )
5627 {
5628 SCIPrationalFreeBlock(blkmem, &(*row)->storedsolvals->activity);
5629 SCIPrationalFreeBlock(blkmem, &(*row)->storedsolvals->dualsol);
5630 BMSfreeBlockMemoryNull(blkmem, &(*row)->storedsolvals);
5631 }
5632
5633 SCIPrationalFreeBlock(blkmem, &(*row)->constant);
5634 SCIPrationalFreeBlock(blkmem, &(*row)->lhs);
5635 SCIPrationalFreeBlock(blkmem, &(*row)->rhs);
5636 SCIPrationalFreeBlock(blkmem, &(*row)->flushedlhs);
5637 SCIPrationalFreeBlock(blkmem, &(*row)->flushedrhs);
5638 SCIPrationalFreeBlock(blkmem, &(*row)->objprod);
5639 SCIPrationalFreeBlock(blkmem, &(*row)->dualsol);
5640 SCIPrationalFreeBlock(blkmem, &(*row)->activity);
5641 SCIPrationalFreeBlock(blkmem, &(*row)->dualfarkas);
5642 SCIPrationalFreeBlock(blkmem, &(*row)->pseudoactivity);
5643
5644 SCIPrationalFreeBlockArray(blkmem, &(*row)->vals, (*row)->size);
5645 BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->valsinterval, (*row)->size);
5646 BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->cols, (*row)->size);
5647 BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->cols_index, (*row)->size);
5648 BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->linkpos, (*row)->size);
5649 BMSfreeBlockMemory(blkmem, row);
5650
5651 return SCIP_OKAY;
5652}
5653
5654/** returns the feasibility of a row in the current LP solution: negative value means infeasibility */
5656 SCIP_ROWEXACT* row, /**< LP row */
5657 SCIP_SET* set, /**< global SCIP settings */
5658 SCIP_STAT* stat, /**< problem statistics */
5659 SCIP_LPEXACT* lpexact, /**< current LP data */
5660 SCIP_RATIONAL* result /**< rational pointer to store the result */
5661 )
5662{
5663 SCIP_RATIONAL* activity;
5664 SCIP_RATIONAL* actrhs;
5665 SCIP_RATIONAL* actlhs;
5666
5667 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &actrhs) );
5668 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &actlhs) );
5669 assert(row != NULL);
5670
5671 activity = SCIProwExactGetLPActivity(row, stat, lpexact);
5672
5673 SCIPrationalDiff(actlhs, row->rhs, activity);
5674 SCIPrationalDiff(actrhs, activity, row->lhs);
5675 SCIPrationalMin(result, actrhs, actlhs);
5676
5677 SCIPrationalFreeBuffer(set->buffer, &actlhs);
5678 SCIPrationalFreeBuffer(set->buffer, &actrhs);
5679
5680 return SCIP_OKAY;
5681}
5682
5683/** returns the pseudo feasibility of a row in the current pseudo solution: negative value means infeasibility */
5685 SCIP_ROWEXACT* row, /**< LP row */
5686 SCIP_SET* set, /**< global SCIP settings */
5687 SCIP_STAT* stat, /**< problem statistics */
5688 SCIP_RATIONAL* result /**< rational pointer to store the result */
5689 )
5690{
5691 SCIP_RATIONAL* pseudoactivity;
5692 SCIP_RATIONAL* actrhs;
5693 SCIP_RATIONAL* actlhs;
5694
5695 assert(row != NULL);
5696
5697 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &actrhs) );
5698 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &actlhs) );
5699
5700 pseudoactivity = SCIProwExactGetPseudoActivity(row, stat);
5701
5702 SCIPrationalDiff(actlhs, row->rhs, pseudoactivity);
5703 SCIPrationalDiff(actrhs, pseudoactivity, row->lhs);
5704 SCIPrationalMin(result, actrhs, actlhs);
5705
5706 SCIPrationalFreeBuffer(set->buffer, &actlhs);
5707 SCIPrationalFreeBuffer(set->buffer, &actrhs);
5708
5709 return SCIP_OKAY;
5710}
5711
5712/** returns the activity of a row in the current LP solution */
5714 SCIP_ROWEXACT* row, /**< LP row */
5715 SCIP_STAT* stat, /**< problem statistics */
5716 SCIP_LPEXACT* lpexact /**< current LP data */
5717 )
5718{
5719 assert(row != NULL);
5720 assert(stat != NULL);
5721 assert(lpexact != NULL);
5722 assert(row->fprow->validactivitylp <= stat->lpcount);
5723 assert(lpexact->fplp->validsollp == stat->lpcount);
5724
5725 if( row->fprow->validactivitylp != stat->lpcount )
5727 assert(row->fprow->validactivitylp == stat->lpcount);
5728 assert(row->fprow->activity < SCIP_INVALID);
5729
5730 return row->activity;
5731}
5732
5733/** returns the pseudo activity of a row in the current pseudo solution */
5735 SCIP_ROWEXACT* row, /**< LP row */
5736 SCIP_STAT* stat /**< problem statistics */
5737 )
5738{
5739 assert(row != NULL);
5740 assert(stat != NULL);
5741 assert(row->fprow->validpsactivitydomchg <= stat->domchgcount);
5742
5743 /* check, if pseudo activity has to be calculated */
5744 if( row->fprow->validpsactivitydomchg != stat->domchgcount )
5746 assert(row->fprow->validpsactivitydomchg == stat->domchgcount);
5747 assert(row->fprow->pseudoactivity < SCIP_INVALID);
5748
5749 return row->pseudoactivity;
5750}
5751
5752/** sorts row entries such that LP columns precede non-LP columns and inside both parts lower column indices precede
5753 * higher ones
5754 */
5756 SCIP_ROWEXACT* row /**< row to be sorted */
5757 )
5758{
5759 assert(row != NULL);
5760
5761 /* sort LP columns */
5762 rowExactSortLP(row);
5763
5764 /* sort non-LP columns */
5765 rowExactSortNonLP(row);
5766}
5767
5768/** sorts row, and merges equal column entries (resulting from lazy sorting and adding) into a single entry; removes
5769 * zero entries from row the row must not be linked to the columns; otherwise, we would need to update the columns as
5770 * well, which is too expensive
5771 */
5772static
5774 SCIP_ROWEXACT* row, /**< row to be sorted */
5775 SCIP_SET* set /**< global SCIP settings */
5776 )
5777{
5778 assert(row != NULL);
5779 assert(!row->delaysort);
5780 assert(row->nunlinked == row->len);
5781 assert(row->nlpcols == 0);
5782
5783 SCIPsetDebugMsg(set, "merging row <%s>\n", row->fprow->name);
5784
5785 /* do nothing on empty rows; if row is sorted, nothing has to be done */
5786 if( row->len > 0 && (!row->lpcolssorted || !row->nonlpcolssorted) )
5787 {
5788 SCIP_COLEXACT** cols;
5789 int* cols_index;
5790 SCIP_RATIONAL** vals;
5791 int s;
5792 int t;
5793
5794 /* make sure, the row is sorted */
5795 SCIProwExactSort(row);
5796 assert(row->lpcolssorted);
5797 assert(row->nonlpcolssorted);
5798
5799 /* merge equal columns, thereby recalculating whether the row's activity is always integral */
5800 cols = row->cols;
5801 cols_index = row->cols_index;
5802 vals = row->vals;
5803 assert(cols != NULL);
5804 assert(cols_index != NULL);
5805 assert(vals != NULL);
5806
5807 t = 0;
5808 row->integral = TRUE;
5809 assert(!SCIPrationalIsZero(vals[0]));
5810 assert(row->linkpos[0] == -1);
5811
5812 for( s = 1; s < row->len; ++s )
5813 {
5814 assert(!SCIPrationalIsZero(vals[s]));
5815 assert(row->linkpos[s] == -1);
5816
5817 if( cols[s] == cols[t] )
5818 {
5819 /* merge entries with equal column */
5820 SCIPrationalAdd(vals[t], vals[t], vals[s]);
5821 SCIPintervalSetRational(&row->valsinterval[t], vals[t]);
5822 }
5823 else
5824 {
5825 /* go to the next entry, overwriting current entry if coefficient is zero */
5826 if( !SCIPrationalIsZero(vals[t]) )
5827 {
5828 row->integral = row->integral && SCIPcolIsIntegral(cols[t]->fpcol) && SCIPrationalIsIntegral(vals[t]);
5829 t++;
5830 }
5831 cols[t] = cols[s];
5832 cols_index[t] = cols_index[s];
5833 SCIPrationalSetRational(vals[t], vals[s]);
5834 SCIPintervalSetRational(&row->valsinterval[t], vals[t]);
5835 }
5836 }
5837 if( !SCIPrationalIsZero(vals[t]) )
5838 {
5839 row->integral = row->integral && SCIPcolIsIntegral(cols[t]->fpcol) && SCIPrationalIsIntegral(vals[t]);
5840 t++;
5841 }
5842 assert(s == row->len);
5843 assert(t <= row->len);
5844
5845 row->len = t;
5846 row->nunlinked = t;
5847 }
5848
5849#ifndef NDEBUG
5850 /* check for double entries */
5851 {
5852 int i;
5853 int j;
5854
5855 for( i = 0; i < row->len; ++i )
5856 {
5857 assert(row->cols[i] != NULL);
5858 assert(row->cols[i]->index == row->cols_index[i]);
5859 for( j = i+1; j < row->len; ++j )
5860 assert(row->cols[i] != row->cols[j]);
5861 }
5862 }
5863#endif
5864}
5865
5866/** enables delaying of row sorting */
5868 SCIP_ROWEXACT* rowexact /**< LP rowexact */
5869 )
5870{
5871 assert(rowexact != NULL);
5872 assert(!rowexact->delaysort);
5873
5874 rowexact->delaysort = TRUE;
5875}
5876
5877/** disables delaying of row sorting, sorts row and merges coefficients with equal columns */
5879 SCIP_ROWEXACT* rowexact, /**< LP rowexact */
5880 SCIP_SET* set /**< global SCIP settings */
5881 )
5882{
5883 assert(rowexact != NULL);
5884 assert(rowexact->delaysort);
5885
5886 rowexact->delaysort = FALSE;
5887 rowExactMerge(rowexact, set);
5888}
5889
5890/** recalculates the current activity of a row */
5892 SCIP_ROWEXACT* rowexact, /**< LP row */
5893 SCIP_STAT* stat /**< problem statistics */
5894 )
5895{
5896 SCIP_COLEXACT* colexact;
5897 SCIP_COL* col;
5898 SCIP_ROW* row;
5899 int c;
5900
5901 assert(rowexact != NULL);
5902
5903 row = rowexact->fprow;
5904
5905 assert(row != NULL);
5906 assert(stat != NULL);
5907
5908 SCIPrationalSetRational(rowexact->activity, rowexact->constant);
5909 for( c = 0; c < row->nlpcols; ++c )
5910 {
5911 colexact = rowexact->cols[c];
5912 col = row->cols[c];
5913
5914 assert(col != NULL);
5915 assert(colexact != NULL);
5916 assert(!SCIPrationalIsInfinity(colexact->primsol));
5917 assert(col->lppos >= 0);
5918 assert(row->linkpos[c] >= 0);
5919
5920 SCIPrationalAddProd(rowexact->activity, rowexact->vals[c], colexact->primsol);
5921 }
5922
5923 if( row->nunlinked > 0 )
5924 {
5925 for( c = row->nlpcols; c < row->len; ++c )
5926 {
5927 col = row->cols[c];
5928 colexact = rowexact->cols[c];
5929
5930 assert(col != NULL);
5931 assert(colexact != NULL);
5932 assert(col->lppos >= 0 || col->primsol == 0.0);
5933 assert(col->lppos == -1 || row->linkpos[c] == -1);
5934 if( col->lppos >= 0 )
5935 SCIPrationalAddProd(rowexact->activity, rowexact->vals[c], colexact->primsol);
5936 }
5937 }
5938#ifndef NDEBUG
5939 else
5940 {
5941 for( c = row->nlpcols; c < row->len; ++c )
5942 {
5943 col = row->cols[c];
5944 colexact = rowexact->cols[c];
5945
5946 assert(col != NULL);
5947 assert(colexact != NULL);
5948 assert(SCIPrationalIsZero(colexact->primsol));
5949 assert(col->lppos == -1);
5950 assert(row->linkpos[c] >= 0);
5951 }
5952 }
5953#endif
5954
5955 row->activity = SCIPrationalGetReal(rowexact->activity);
5956 row->validactivitylp = stat->lpcount;
5957}
5958
5959/** calculates the current pseudo activity of a row */
5961 SCIP_ROWEXACT* rowexact, /**< row data */
5962 SCIP_STAT* stat /**< problem statistics */
5963 )
5964{
5965 SCIP_COLEXACT* colexact;
5966 SCIP_ROW* row;
5967
5968 int i;
5969
5970 assert(rowexact != NULL);
5971
5972 row = rowexact->fprow;
5973
5974 assert(row != NULL);
5975 assert(stat != NULL);
5976
5977 SCIPrationalSetRational(rowexact->pseudoactivity, rowexact->constant);
5978 for( i = 0; i < row->len; ++i )
5979 {
5980 colexact = rowexact->cols[i];
5981
5982 assert(colexact->fpcol != NULL);
5983 assert(colexact != NULL);
5984 assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && colexact->fpcol->lppos >= 0));
5985 assert(colexact->fpcol->var != NULL);
5986 assert(SCIPvarGetStatus(colexact->fpcol->var) == SCIP_VARSTATUS_COLUMN);
5987
5988 SCIPrationalAddProd(rowexact->pseudoactivity, rowexact->vals[i], SCIPcolExactGetBestBound(colexact));
5989 }
5990
5993}
5994
5995/** gets objective value of column */
5997 SCIP_COLEXACT* col /**< LP column */
5998 )
5999{
6000 assert(col != NULL);
6001
6002 return col->obj;
6003}
6004
6005/** gets lower bound of column */
6007 SCIP_COLEXACT* col /**< LP column */
6008 )
6009{
6010 assert(col != NULL);
6011
6012 return col->lb;
6013}
6014
6015/** gets upper bound of column */
6017 SCIP_COLEXACT* col /**< LP column */
6018 )
6019{
6020 assert(col != NULL);
6021
6022 return col->ub;
6023}
6024
6025/** gets best bound of column with respect to the objective function */
6027 SCIP_COLEXACT* col /**< LP column */
6028 )
6029{
6030 assert(col != NULL);
6031
6033 return col->lb;
6034 else
6035 return col->ub;
6036}
6037
6038/** gets the primal LP solution of a column */
6040 SCIP_COLEXACT* col /**< LP column */
6041 )
6042{
6043 assert(col != NULL);
6044
6045 if( col->fpcol->lppos >= 0 )
6046 return col->primsol;
6047 else
6048 return NULL;
6049}
6050
6051/** gets variable this column represents */
6053 SCIP_COLEXACT* col /**< LP column */
6054 )
6055{
6056 assert(col != NULL);
6057
6058 return col->var;
6059}
6060
6061/** ensures, that column array of row can store at least num entries */
6063 SCIP_ROWEXACT* row, /**< LP row */
6064 BMS_BLKMEM* blkmem, /**< block memory */
6065 SCIP_SET* set, /**< global SCIP settings */
6066 int num /**< minimum number of entries to store */
6067 )
6068{
6069 assert(row != NULL);
6070 assert(row->fprow != NULL);
6071 assert(row->len <= row->size);
6072
6073 if( num > row->size )
6074 {
6075 int newsize;
6076 int i;
6077
6078 newsize = SCIPsetCalcMemGrowSize(set, num);
6079 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->cols, row->size, newsize) );
6080 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->cols_index, row->size, newsize) );
6081 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->vals, row->size, newsize) );
6082 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->valsinterval, row->size, newsize) );
6083 for( i = row->size; i < newsize; ++i )
6084 SCIP_CALL( SCIPrationalCreateBlock(blkmem, &row->vals[i]) );
6085 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->linkpos, row->size, newsize) );
6086 row->size = newsize;
6087 }
6088 assert(num <= row->size);
6089
6090 return SCIP_OKAY;
6091}
6092
6093/*
6094 * lp update methods
6095 */
6096
6097
6098/** compute the objective delta due the new objective coefficient */
6099static
6101 SCIP_SET* set, /**< global SCIP settings */
6102 SCIP_RATIONAL* oldobj, /**< old objective value of variable */
6103 SCIP_RATIONAL* newobj, /**< new objective value of variable */
6104 SCIP_RATIONAL* lb, /**< lower bound of variable */
6105 SCIP_RATIONAL* ub, /**< upper bound of variable */
6106 SCIP_RATIONAL* deltaval, /**< pointer to store the delta value */
6107 int* deltainf /**< pointer to store the number of variables with infinite best bound */
6108 )
6109{
6110 SCIP_RATIONAL* tmp;
6111 assert(!SCIPrationalIsAbsInfinity(oldobj));
6112 assert(!SCIPrationalIsAbsInfinity(newobj));
6113 assert(!SCIPrationalIsInfinity(lb));
6114 assert(!SCIPrationalIsNegInfinity(ub));
6115 assert(!SCIPrationalIsEQ(oldobj, newobj));
6116
6117 SCIPrationalSetReal(deltaval, 0.0);
6118 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &tmp) );
6119 (*deltainf) = 0;
6120
6121 if( SCIPrationalIsPositive(oldobj) )
6122 {
6123 /* sign of objective did not change */
6124 if( SCIPrationalIsPositive(newobj) )
6125 {
6126 /* if the bound is finite, calculate the deltaval */
6127 if( !SCIPrationalIsNegInfinity(lb) )
6128 {
6129 SCIPrationalDiff(deltaval, newobj, oldobj);
6130 SCIPrationalMult(deltaval, deltaval, lb);
6131 }
6132 }
6133 /* sign of objective did change, so the best bound does change */
6134 else if( SCIPrationalIsNegative(newobj) )
6135 {
6137 {
6138 /* old best bound was infinite while new one is not */
6139 if( !SCIPrationalIsInfinity(ub) )
6140 {
6141 (*deltainf) = -1;
6142 SCIPrationalMult(deltaval, ub, newobj);
6143 }
6144 }
6145 else
6146 {
6147 /* new best bound is infinite while old one was not */
6148 if( SCIPrationalIsInfinity(ub) )
6149 {
6150 (*deltainf) = 1;
6151 SCIPrationalMult(deltaval, lb, oldobj);
6152 SCIPrationalNegate(deltaval, deltaval);
6153 }
6154 /* neither old nor new best bound is infinite, so just calculate the deltaval */
6155 else
6156 {
6157 SCIPrationalMult(tmp, lb, oldobj);
6158 SCIPrationalMult(deltaval, ub, newobj);
6159
6160 SCIPrationalDiff(deltaval, deltaval, tmp);
6161 }
6162 }
6163 }
6164 /* new objective is 0.0 */
6165 else
6166 {
6168 (*deltainf) = -1;
6169 else
6170 {
6171 SCIPrationalMult(deltaval, lb, oldobj);
6172 SCIPrationalNegate(deltaval, deltaval);
6173 }
6174 }
6175 }
6176 else if( SCIPrationalIsNegative(oldobj) )
6177 {
6178 /* sign of objective did not change */
6179 if( SCIPrationalIsNegative(newobj) )
6180 {
6181 /* if the bound is finite, calculate the deltaval */
6182 if( !SCIPrationalIsInfinity(ub) )
6183 {
6184 SCIPrationalDiff(tmp, newobj, oldobj);
6185 SCIPrationalMult(deltaval, ub, tmp);
6186 }
6187 }
6188 /* sign of objective did change, so the best bound does change */
6189 else if( SCIPrationalIsPositive(newobj) )
6190 {
6191 if( SCIPrationalIsInfinity(ub) )
6192 {
6193 /* old best bound was infinite while new one is not */
6194 if( !SCIPrationalIsNegInfinity(lb) )
6195 {
6196 (*deltainf) = -1;
6197 SCIPrationalMult(deltaval, lb, newobj);
6198 }
6199 }
6200 else
6201 {
6202 /* new best bound is infinite while old one was not */
6204 {
6205 (*deltainf) = 1;
6206 SCIPrationalMult(deltaval, ub, oldobj);
6207 SCIPrationalNegate(deltaval, deltaval);
6208 }
6209 /* neither old nor new best bound is infinite, so just calculate the deltaval */
6210 else
6211 {
6212 SCIPrationalMult(tmp, ub, oldobj);
6213 SCIPrationalMult(deltaval, lb, newobj);
6214 SCIPrationalDiff(deltaval, deltaval, tmp);
6215 }
6216 }
6217 }
6218 /* new objective is 0.0 */
6219 else
6220 {
6221 if( SCIPrationalIsInfinity(ub) )
6222 (*deltainf) = -1;
6223 else
6224 {
6225 SCIPrationalMult(deltaval, ub, oldobj);
6226 SCIPrationalNegate(deltaval, deltaval);
6227 }
6228 }
6229 }
6230 /* old objective was 0.0 */
6231 else
6232 {
6233 if( SCIPrationalIsNegative(newobj) )
6234 {
6235 if( SCIPrationalIsInfinity(ub) )
6236 (*deltainf) = 1;
6237 else
6238 SCIPrationalMult(deltaval, ub, newobj);
6239 }
6240 else if( SCIPrationalIsPositive(newobj) )
6241 {
6243 (*deltainf) = 1;
6244 else
6245 SCIPrationalMult(deltaval, lb, newobj);
6246 }
6247 }
6248
6249 SCIPrationalFreeBuffer(set->buffer, &tmp);
6250
6251 return SCIP_OKAY;
6252}
6253
6254/** returns the left hand side of the row */
6256 SCIP_ROWEXACT* row /**< LP row */
6257 )
6258{
6259 assert(row != NULL);
6260 assert(row->lhs != NULL);
6261
6262 return row->lhs;
6263}
6264
6265/** returns the right hand side of the row */
6267 SCIP_ROWEXACT* row /**< LP row */
6268 )
6269{
6270 assert(row != NULL);
6271 assert(row->rhs != NULL);
6272
6273 return row->rhs;
6274}
6275
6276/** returns the constant of the row */
6278 SCIP_ROWEXACT* row /**< LP row */
6279 )
6280{
6281 assert(row != NULL);
6282 assert(row->constant != NULL);
6283
6284 return row->constant;
6285}
6286
6287/** compute the objective delta due the new lower bound */
6288static
6290 SCIP_RATIONAL* obj, /**< objective value of variable */
6291 SCIP_RATIONAL* oldlb, /**< old lower bound of variable */
6292 SCIP_RATIONAL* newlb, /**< new lower bound of variable */
6293 SCIP_RATIONAL* deltaval, /**< pointer to store the delta value */
6294 int* deltainf /**< pointer to store the number of variables with infinite best bound */
6295 )
6296{
6297 assert(!SCIPrationalIsAbsInfinity(obj));
6298 assert(!SCIPrationalIsInfinity(oldlb));
6299 assert(!SCIPrationalIsNegInfinity(oldlb) || !SCIPrationalIsNegInfinity(newlb));
6300 assert(SCIPrationalIsPositive(obj)); /* we only need to update if the objective is positive */
6301
6302 if( SCIPrationalIsNegInfinity(oldlb) )
6303 {
6304 if( !SCIPrationalIsInfinity(newlb) )
6305 {
6306 (*deltainf) = -1;
6307 SCIPrationalMult(deltaval, newlb, obj);
6308 }
6309 else
6310 {
6311 (*deltainf) = 0;
6312 SCIPrationalSetReal(deltaval, 0.0);
6313 }
6314 }
6315 else if( SCIPrationalIsAbsInfinity(newlb) )
6316 {
6317 (*deltainf) = 1;
6318 SCIPrationalMult(deltaval, oldlb, obj);
6319 SCIPrationalNegate(deltaval, deltaval);
6320 }
6321 else
6322 {
6323 (*deltainf) = 0;
6324 SCIPrationalDiff(deltaval, newlb, oldlb);
6325 SCIPrationalMult(deltaval, deltaval, obj);
6326 }
6327}
6328
6329/** compute the objective delta due the new upper bound */
6330static
6332 SCIP_RATIONAL* obj, /**< objective value of variable */
6333 SCIP_RATIONAL* oldub, /**< old upper bound of variable */
6334 SCIP_RATIONAL* newub, /**< new upper bound of variable */
6335 SCIP_RATIONAL* deltaval, /**< pointer to store the delta value */
6336 int* deltainf /**< pointer to store the number of variables with infinite best bound */
6337 )
6338{
6339 assert(!SCIPrationalIsAbsInfinity(obj));
6340 assert(!SCIPrationalIsNegInfinity(oldub));
6341 assert(!SCIPrationalIsInfinity(oldub) || !SCIPrationalIsInfinity(newub));
6342 assert(SCIPrationalIsNegative(obj)); /* we only need to update if the objective is negative */
6343
6344 if( SCIPrationalIsInfinity(oldub) )
6345 {
6346 if( !SCIPrationalIsNegInfinity(newub) )
6347 {
6348 (*deltainf) = -1;
6349 SCIPrationalMult(deltaval, newub, obj);
6350 }
6351 else
6352 {
6353 (*deltainf) = 0;
6354 SCIPrationalSetReal(deltaval, 0.0);
6355 }
6356 }
6357 else if( SCIPrationalIsAbsInfinity(newub) )
6358 {
6359 (*deltainf) = 1;
6360 SCIPrationalMult(deltaval, oldub, obj);
6361 SCIPrationalNegate(deltaval, deltaval);
6362 }
6363 else
6364 {
6365 (*deltainf) = 0;
6366 SCIPrationalDiff(deltaval, newub, oldub);
6367 SCIPrationalMult(deltaval, deltaval, obj);
6368 }
6369}
6370
6371/** updates current pseudo and loose objective values for a change in a variable's objective value or bounds */
6372static
6374 SCIP_LPEXACT* lpexact, /**< current LP data */
6375 SCIP_VAR* var, /**< problem variable that changed */
6376 SCIP_RATIONAL* deltavalex, /**< delta value in the objective function */
6377 int deltainf, /**< delta value for the number of variables with infinite best bound */
6378 SCIP_Bool local, /**< should the local pseudo objective value be updated? */
6379 SCIP_Bool loose, /**< should the loose objective value be updated? */
6380 SCIP_Bool global /**< should the global pseudo objective value be updated? */
6381 )
6382{
6383 assert(lpexact != NULL);
6384 assert(lpexact->looseobjvalinf >= 0);
6385 assert(lpexact->pseudoobjvalinf >= 0);
6386 assert(lpexact->glbpseudoobjvalinf >= 0);
6387
6388 /* update the pseudo objective value */
6389 if( local )
6390 {
6391 lpexact->pseudoobjvalinf += deltainf;
6392
6393 SCIPrationalAdd(lpexact->pseudoobjval, lpexact->pseudoobjval, deltavalex);
6394
6395 /* after changing a local bound on a LOOSE variable, we have to update the loose objective value, too */
6397 loose = TRUE;
6398 }
6399 /* update the loose objective value */
6400 if( loose )
6401 {
6402 lpexact->looseobjvalinf += deltainf;
6403
6404 if( !SCIPrationalIsZero(deltavalex) )
6405 SCIPrationalAdd(lpexact->looseobjval, lpexact->looseobjval, deltavalex);
6406 }
6407
6408 /* update the root pseudo objective values */
6409 if( global )
6410 {
6411 lpexact->glbpseudoobjvalinf += deltainf;
6412
6413 SCIPrationalAdd(lpexact->glbpseudoobjval ,lpexact->glbpseudoobjval, deltavalex);
6414 }
6415
6416 assert(lpexact->looseobjvalinf >= 0);
6417 assert(lpexact->pseudoobjvalinf >= 0);
6418 assert(lpexact->glbpseudoobjvalinf >= 0);
6419}
6420
6421/** updates current pseudo and loose objective value for a change in a variable's objective value */
6423 SCIP_SET* set, /**< global SCIP settings */
6424 SCIP_LPEXACT* lpexact, /**< current LP data */
6425 SCIP_VAR* var, /**< problem variable that changed */
6426 SCIP_RATIONAL* oldobj, /**< old objective value of variable */
6427 SCIP_RATIONAL* newobj /**< new objective value of variable */
6428 )
6429{
6430 assert(lpexact != NULL);
6431 assert(var != NULL);
6432
6433 if( !SCIPrationalIsEQ(oldobj, newobj) )
6434 {
6435 SCIP_RATIONAL* deltaval;
6436 int deltainf = 0;
6437
6439 assert(SCIPvarGetProbindex(var) >= 0);
6440 /* the objective coefficient can only be changed during presolving, that implies that the global and local
6441 * domain of the variable are the same
6442 */
6445
6446 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &deltaval) );
6447
6448 /* compute the pseudo objective delta due the new objective coefficient */
6450 SCIPvarGetUbLocalExact(var), deltaval, &deltainf) );
6451
6452 /* update the local pseudo objective value */
6453 lpExactUpdateObjval(lpexact, var, deltaval, deltainf, TRUE, FALSE, FALSE);
6454
6455 /* compute the pseudo objective delta due the new objective coefficient */
6457 SCIPvarGetUbGlobalExact(var), deltaval, &deltainf) );
6458
6459 /* update the global pseudo objective value */
6460 lpExactUpdateObjval(lpexact, var, deltaval, deltainf, FALSE, FALSE, TRUE);
6461
6462 SCIPrationalFreeBuffer(set->buffer, &deltaval);
6463 }
6464
6465 return SCIP_OKAY;
6466}
6467
6468/** updates current root pseudo objective value for a global change in a variable's lower bound */
6470 SCIP_LPEXACT* lpexact, /**< current LP data */
6471 SCIP_SET* set, /**< global SCIP settings */
6472 SCIP_VAR* var, /**< problem variable that changed */
6473 SCIP_RATIONAL* oldlb, /**< old lower bound of variable */
6474 SCIP_RATIONAL* newlb /**< new lower bound of variable */
6475 )
6476{
6477 assert(lpexact != NULL);
6478 assert(set != NULL);
6479 assert(var != NULL);
6480
6481 if( !SCIPrationalIsEQ(oldlb, newlb) && SCIPrationalIsPositive(SCIPvarGetObjExact(var)) )
6482 {
6483 SCIP_RATIONAL* deltaval;
6484 int deltainf;
6485
6486 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &deltaval) );
6487
6488 /* compute the pseudo objective delta due the new lower bound */
6489 getObjvalDeltaLbExact(SCIPvarGetObjExact(var), oldlb, newlb, deltaval, &deltainf);
6490
6491 /* update the root pseudo objective values */
6492 lpExactUpdateObjval(lpexact, var, deltaval, deltainf, FALSE, FALSE, TRUE);
6493
6494 SCIPrationalFreeBuffer(set->buffer, &deltaval);
6495 }
6496
6497 return SCIP_OKAY;
6498}
6499
6500/** updates current pseudo and loose objective value for a change in a variable's lower bound */
6502 SCIP_LPEXACT* lpexact, /**< current LP data */
6503 SCIP_SET* set, /**< global SCIP settings */
6504 SCIP_VAR* var, /**< problem variable that changed */
6505 SCIP_RATIONAL* oldlb, /**< old lower bound of variable */
6506 SCIP_RATIONAL* newlb /**< new lower bound of variable */
6507 )
6508{
6509 assert(lpexact != NULL);
6510 assert(set != NULL);
6511 assert(var != NULL);
6512
6513 if( !SCIPrationalIsEQ(oldlb, newlb) && SCIPrationalIsPositive(SCIPvarGetObjExact(var)) )
6514 {
6515 SCIP_RATIONAL* deltaval;
6516 int deltainf;
6517
6519 assert(SCIPvarGetProbindex(var) >= 0);
6520
6521 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &deltaval) );
6522
6523 /* compute the pseudo objective delta due the new lower bound */
6524 getObjvalDeltaLbExact(SCIPvarGetObjExact(var), oldlb, newlb, deltaval, &deltainf);
6525
6526 /* update the pseudo and loose objective values */
6527 lpExactUpdateObjval(lpexact, var, deltaval, deltainf, TRUE, FALSE, FALSE);
6528
6529 SCIPrationalFreeBuffer(set->buffer, &deltaval);
6530 }
6531
6532 return SCIP_OKAY;
6533}
6534
6535/** updates current root pseudo objective value for a global change in a variable's upper bound */
6537 SCIP_LPEXACT* lpexact, /**< current LP data */
6538 SCIP_SET* set, /**< global SCIP settings */
6539 SCIP_VAR* var, /**< problem variable that changed */
6540 SCIP_RATIONAL* oldub, /**< old upper bound of variable */
6541 SCIP_RATIONAL* newub /**< new upper bound of variable */
6542 )
6543{
6544 assert(lpexact != NULL);
6545 assert(set != NULL);
6546 assert(var != NULL);
6547
6548 if( !SCIPrationalIsEQ(oldub, newub) && SCIPrationalIsNegative(SCIPvarGetObjExact(var)) )
6549 {
6550 SCIP_RATIONAL* deltaval;
6551 int deltainf;
6552
6553 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &deltaval) );
6554
6555 /* compute the pseudo objective delta due the new lower bound */
6556 getObjvalDeltaUbExact(SCIPvarGetObjExact(var), oldub, newub, deltaval, &deltainf);
6557
6558 /* update the root pseudo objective values */
6559 lpExactUpdateObjval(lpexact, var, deltaval, deltainf, FALSE, FALSE, TRUE);
6560
6561 SCIPrationalFreeBuffer(set->buffer, &deltaval);
6562 }
6563
6564 return SCIP_OKAY;
6565}
6566
6567/** updates current pseudo objective value for a change in a variable's upper bound */
6569 SCIP_LPEXACT* lpexact, /**< current LP data */
6570 SCIP_SET* set, /**< global SCIP settings */
6571 SCIP_VAR* var, /**< problem variable that changed */
6572 SCIP_RATIONAL* oldub, /**< old upper bound of variable */
6573 SCIP_RATIONAL* newub /**< new upper bound of variable */
6574 )
6575{
6576 assert(lpexact != NULL);
6577 assert(set != NULL);
6578 assert(var != NULL);
6579
6580 if( !SCIPrationalIsEQ(oldub, newub) && SCIPrationalIsNegative(SCIPvarGetObjExact(var)) )
6581 {
6582 SCIP_RATIONAL* deltaval;
6583 int deltainf;
6584
6586 assert(SCIPvarGetProbindex(var) >= 0);
6587
6588 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &deltaval) );
6589
6590 /* compute the pseudo objective delta due the new lower bound */
6591 getObjvalDeltaUbExact(SCIPvarGetObjExact(var), oldub, newub, deltaval, &deltainf);
6592
6593 /* update the pseudo and loose objective values */
6594 lpExactUpdateObjval(lpexact, var, deltaval, deltainf, TRUE, FALSE, FALSE);
6595
6596 SCIPrationalFreeBuffer(set->buffer, &deltaval);
6597 }
6598
6599 return SCIP_OKAY;
6600}
6601
6602/** informs LP, that given variable was added to the problem */
6604 SCIP_LPEXACT* lpexact, /**< current LP data */
6605 SCIP_SET* set, /**< global SCIP settings */
6606 SCIP_VAR* var /**< variable that is now a LOOSE problem variable */
6607 )
6608{
6609 SCIP_RATIONAL* tmp;
6610
6611 if( !set->exact_enable )
6612 return SCIP_OKAY;
6613
6614 assert(lpexact != NULL);
6615 assert(set != NULL);
6617 assert(SCIPvarGetProbindex(var) >= 0);
6618
6619 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &tmp) );
6620
6621 /* add the variable to the loose objective value sum */
6622 SCIP_CALL( SCIPlpExactUpdateVarObj(set, lpexact, var, tmp, SCIPvarGetObjExact(var)) );
6623
6624 /* update the loose variables counter */
6626 lpexact->nloosevars++;
6627
6628 SCIPrationalFreeBuffer(set->buffer, &tmp);
6629
6630 return SCIP_OKAY;
6631}
6632
6633/** informs LP, that given variable is to be deleted from the problem */
6635 SCIP_LPEXACT* lpexact, /**< current LP data */
6636 SCIP_SET* set, /**< global SCIP settings */
6637 SCIP_VAR* var /**< variable that will be deleted from the problem */
6638 )
6639{
6640 SCIP_RATIONAL* ratzero;
6641
6642 assert(lpexact != NULL);
6644 assert(SCIPvarGetProbindex(var) >= 0);
6645
6646 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &ratzero) );
6647
6648 /* subtract the variable from the loose objective value sum */
6649 SCIP_CALL( SCIPlpExactUpdateVarObj(set, lpexact, var, SCIPvarGetObjExact(var), ratzero) );
6650
6651 /* update the loose variables counter */
6653 {
6654 SCIPlpExactDecNLoosevars(lpexact);
6655 }
6656
6657 SCIPrationalFreeBuffer(set->buffer, &ratzero);
6658
6659 return SCIP_OKAY;
6660}
6661
6662/** informs LP, that given formerly loose problem variable is now a column variable */
6664 SCIP_LPEXACT* lpexact, /**< current LP data */
6665 SCIP_SET* set, /**< global SCIP settings */
6666 SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
6667 )
6668{
6669 SCIP_RATIONAL* tmp;
6670 SCIP_RATIONAL* obj;
6671 SCIP_RATIONAL* lb;
6672 SCIP_RATIONAL* ub;
6673
6674 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &tmp) );
6675
6677 assert(SCIPvarGetProbindex(var) >= 0);
6678 assert(lpexact->looseobjvalinf >= 0);
6679
6680 obj = SCIPvarGetObjExact(var);
6681
6682 /* update loose objective value */
6683 if( SCIPrationalIsPositive(obj) )
6684 {
6685 lb = SCIPvarGetLbLocalExact(var);
6687 lpexact->looseobjvalinf--;
6688 else
6689 {
6690 SCIPrationalNegate(tmp, lb);
6691 SCIPrationalMult(tmp, tmp, obj);
6692 lpExactUpdateObjval(lpexact, var, tmp, 0, FALSE, TRUE, FALSE);
6693 }
6694 }
6695 else if( SCIPrationalIsNegative(obj) )
6696 {
6697 ub = SCIPvarGetUbLocalExact(var);
6698 if( SCIPrationalIsInfinity(ub) )
6699 lpexact->looseobjvalinf--;
6700 else
6701 {
6702 SCIPrationalNegate(tmp, ub);
6703 SCIPrationalMult(tmp, tmp, obj);
6704 lpExactUpdateObjval(lpexact, var, tmp, 0, FALSE, TRUE, FALSE);
6705 }
6706 }
6707
6708 SCIPlpExactDecNLoosevars(lpexact);
6709
6710 assert(lpexact->looseobjvalinf >= 0);
6711
6712 SCIPrationalFreeBuffer(set->buffer, &tmp);
6713
6714 return SCIP_OKAY;
6715}
6716
6717/** informs LP, that given formerly column problem variable is now again a loose variable */
6719 SCIP_LPEXACT* lpexact, /**< current LP data */
6720 SCIP_SET* set, /**< global SCIP settings */
6721 SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
6722 )
6723{
6724 SCIP_RATIONAL* tmp;
6725 SCIP_RATIONAL* obj;
6726 SCIP_RATIONAL* lb;
6727 SCIP_RATIONAL* ub;
6728
6729 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &tmp) );
6730
6731 assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE);
6732 assert(SCIPvarGetProbindex(var) >= 0);
6733 assert(lpexact->looseobjvalinf >= 0);
6734
6735 obj = SCIPvarGetObjExact(var);
6736
6737 /* update loose objective value corresponding to the addition of variable */
6738 if( SCIPrationalIsPositive(obj) )
6739 {
6740 lb = SCIPvarGetLbLocalExact(var);
6742 lpexact->looseobjvalinf++;
6743 else
6744 {
6745 SCIPrationalMult(tmp, lb, obj);
6746 lpExactUpdateObjval(lpexact, var, tmp, 0, FALSE, TRUE, FALSE);
6747 }
6748 }
6749 else if( SCIPrationalIsNegative(obj) )
6750 {
6751 ub = SCIPvarGetUbLocalExact(var);
6752 if( SCIPrationalIsInfinity(ub) )
6753 lpexact->looseobjvalinf++;
6754 else
6755 {
6756 SCIPrationalMult(tmp, ub, obj);
6757 lpExactUpdateObjval(lpexact, var, tmp, 0, FALSE, TRUE, FALSE);
6758 }
6759 }
6760 lpexact->nloosevars++;
6761
6762 assert(lpexact->looseobjvalinf >= 0);
6763
6764 SCIPrationalFreeBuffer(set->buffer, &tmp);
6765
6766 return SCIP_OKAY;
6767}
6768
6769/** decrease the number of loose variables by one */
6771 SCIP_LPEXACT* lpexact /**< current LP data */
6772 )
6773{
6774 assert(lpexact != NULL);
6775 assert(lpexact->nloosevars > 0);
6776
6777 lpexact->nloosevars--;
6778
6779 /* get rid of numerical problems: set loose objective value explicitly to zero, if no loose variables remain */
6780 if( lpexact->nloosevars == 0 )
6781 {
6782 assert(lpexact->looseobjvalinf == 0);
6783 SCIPrationalSetReal(lpexact->looseobjval, 0.0);
6784 }
6785}
6786
6787/** get the number of rows currently in the lp */
6789 SCIP_LPEXACT* lpexact /**< current LP data */
6790 )
6791{
6792 assert(lpexact != NULL);
6793
6794 return lpexact->nrows;
6795}
6796
6797#ifdef SCIP_DEBUG
6798static
6799SCIP_RETCODE lpexactComputeDualValidity(
6800 SCIP_LPEXACT* lpexact, /**< current LP data */
6801 SCIP_SET* set, /**< global SCIP settings */
6802 SCIP_RATIONAL** dualsol, /**< row dual multipliers */
6803 SCIP_RATIONAL** redcost /**< column reduced costs */
6804 )
6805{
6806 int r,c;
6807 SCIP_RATIONAL** obj;
6808 SCIP_RATIONAL* objval;
6809
6810 SCIP_CALL( SCIPrationalCreateBufferArray(set->buffer, &obj, lpexact->ncols) );
6811 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &objval) );
6812
6813 for( c = 0; c < lpexact->nlpicols; c++ )
6814 {
6815 SCIPrationalSetRational(obj[c], lpexact->cols[c]->obj);
6816 SCIPrationalDiff(obj[c], obj[c], redcost[c]);
6817
6818 if( SCIPrationalIsPositive(redcost[c]) )
6819 SCIPrationalDiffProd(objval, redcost[c], lpexact->cols[c]->lb);
6820 else if( SCIPrationalIsNegative(redcost[c]) )
6821 SCIPrationalAddProd(objval, redcost[c], lpexact->cols[c]->ub);
6822 }
6823
6824 for( r = 0; r < lpexact->nlpirows; r++ )
6825 {
6826 SCIP_ROWEXACT* row = lpexact->lpirows[r];
6827
6828 if( SCIPrationalIsPositive(dualsol[r]) )
6829 SCIPrationalDiffProd(objval, dualsol[r], row->lhs);
6830 else if( SCIPrationalIsNegative(dualsol[r]) )
6831 SCIPrationalAddProd(objval, dualsol[r], row->rhs);
6832
6833 for( c = 0; c < row->len; c++ )
6834 {
6835 int idx = row->cols_index[c];
6836 SCIPrationalDiffProd(obj[idx], row->vals[c], dualsol[r]);
6837 }
6838 }
6839
6840 for( c = 0; c < lpexact->ncols; c++ )
6841 {
6842 assert(SCIPrationalIsZero(obj[c]));
6843 }
6844
6845 SCIPrationalFreeBuffer(set->buffer, &objval);
6846 SCIPrationalFreeBufferArray(set->buffer, &obj, lpexact->ncols);
6847
6848 return SCIP_OKAY;
6849}
6850#endif
6851
6852/** stores the LP solution in the columns and rows */
6854 SCIP_LPEXACT* lpexact, /**< current LP data */
6855 SCIP_SET* set, /**< global SCIP settings */
6856 SCIP_STAT* stat, /**< problem statistics */
6857 SCIP_Bool* primalfeasible, /**< pointer to store whether the solution is primal feasible, or NULL */
6858 SCIP_Bool* dualfeasible, /**< pointer to store whether the solution is dual feasible, or NULL */
6859 SCIP_Bool overwritefplp /**< should the floating point values be overwritten, e.g. if fp lp was infeasible */
6860 )
6861{
6862 SCIP_COLEXACT** lpicols;
6863 SCIP_ROWEXACT** lpirows;
6864 SCIP_RATIONAL** primsol;
6865 SCIP_RATIONAL** dualsol;
6866 SCIP_RATIONAL** activity;
6867 SCIP_RATIONAL** redcost;
6868 SCIP_RATIONAL* primalbound;
6869 SCIP_RATIONAL* dualbound;
6870 SCIP_RATIONAL* tmp;
6871 SCIP_Bool stillprimalfeasible;
6872 SCIP_Bool stilldualfeasible;
6873 int* cstat;
6874 int* rstat;
6875 SCIP_Longint lpcount;
6876 int nlpicols;
6877 int nlpirows;
6878 int c;
6879 int r;
6880
6881 assert(lpexact != NULL);
6882 assert(lpexact->solved);
6883 assert(set != NULL);
6884 assert(stat != NULL);
6885
6886 /* initialize return and feasibility flags; if primal oder dual feasibility shall not be checked, we set the
6887 * corresponding flag immediately to FALSE to skip all checks
6888 */
6889 if( primalfeasible == NULL )
6890 stillprimalfeasible = FALSE;
6891 else
6892 {
6893 *primalfeasible = TRUE;
6894 stillprimalfeasible = TRUE;
6895 }
6896 if( dualfeasible == NULL )
6897 stilldualfeasible = FALSE;
6898 else
6899 {
6900 *dualfeasible = TRUE;
6901 stilldualfeasible = TRUE;
6902 }
6903
6904 SCIPsetDebugMsg(set, "getting new LP solution %" SCIP_LONGINT_FORMAT " for solstat %d\n",
6905 stat->lpcount, lpexact->lpsolstat);
6906
6907 lpicols = lpexact->lpicols;
6908 lpirows = lpexact->lpirows;
6909 nlpicols = lpexact->nlpicols;
6910 nlpirows = lpexact->nlpirows;
6911 lpcount = stat->lpcount;
6912
6913 /* get temporary memory */
6914 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &primalbound) );
6915 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &dualbound) );
6916 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &tmp) );
6917 SCIP_CALL( SCIPrationalCreateBufferArray(set->buffer, &primsol, nlpicols) );
6918 SCIP_CALL( SCIPrationalCreateBufferArray(set->buffer, &dualsol, nlpirows) );
6919 SCIP_CALL( SCIPrationalCreateBufferArray(set->buffer, &activity, nlpirows) );
6920 SCIP_CALL( SCIPrationalCreateBufferArray(set->buffer, &redcost, nlpicols) );
6921 SCIP_CALL( SCIPsetAllocBufferArray(set, &cstat, nlpicols) );
6922 SCIP_CALL( SCIPsetAllocBufferArray(set, &rstat, nlpirows) );
6923
6924 SCIP_CALL( SCIPlpiExactGetSol(lpexact->lpiexact, NULL, primsol, dualsol, activity, redcost) );
6925
6926 /* avoid adding infinity to the bounding error */
6927 if( !SCIPrationalIsInfinity(lpexact->lpobjval) )
6929 if( overwritefplp )
6930 {
6932 lpexact->fplp->lpsolstat = lpexact->lpsolstat;
6933 lpexact->fplp->primalfeasible = lpexact->primalfeasible;
6934 lpexact->fplp->dualfeasible = lpexact->dualfeasible;
6935 lpexact->fplp->solved = lpexact->solved;
6936 }
6937 if( lpexact->solisbasic )
6938 {
6939 SCIP_CALL( SCIPlpiExactGetBase(lpexact->lpiexact, cstat, rstat) );
6940 }
6941 else
6942 {
6943 BMSclearMemoryArray(cstat, nlpicols);
6944 BMSclearMemoryArray(rstat, nlpirows);
6945 }
6946
6947 SCIPrationalSetReal(primalbound, 0.0);
6948 SCIPrationalSetReal(dualbound, 0.0);
6949
6950 SCIPdebug( SCIP_CALL( lpexactComputeDualValidity(lpexact, set, dualsol, redcost) ) );
6951
6952 /* copy primal solution and reduced costs into columns */
6953 for( c = 0; c < nlpicols; ++c )
6954 {
6955 assert( 0 <= cstat[c] && cstat[c] < 4 );
6956 SCIPrationalSetRational(lpicols[c]->primsol, primsol[c]);
6957 SCIPrationalSetRational(lpicols[c]->redcost, redcost[c]);
6958 lpicols[c]->basisstatus = (unsigned int) cstat[c];
6959 lpicols[c]->validredcostlp = lpcount;
6960 if( overwritefplp )
6961 {
6962 lpexact->fplp->lpicols[c]->primsol = SCIPrationalGetReal(primsol[c]);
6963 lpexact->fplp->lpicols[c]->redcost = SCIPrationalGetReal(redcost[c]);
6964 lpexact->fplp->lpicols[c]->basisstatus = (unsigned int) cstat[c];
6965 lpexact->fplp->lpicols[c]->validredcostlp = lpcount;
6966 }
6967 if( stillprimalfeasible )
6968 {
6969 stillprimalfeasible =
6970 (SCIPrationalIsNegInfinity(lpicols[c]->lb) || !SCIPrationalIsLT(lpicols[c]->primsol, lpicols[c]->lb))
6971 && (SCIPrationalIsInfinity(lpicols[c]->ub) || !SCIPrationalIsGT(lpicols[c]->primsol, lpicols[c]->ub));
6972 SCIPrationalAddProd(primalbound, lpicols[c]->primsol, lpicols[c]->obj);
6973 }
6974
6975 /* complementary slackness means that if a variable is not at its lower or upper bound, its reduced costs
6976 * must be non-positive or non-negative, respectively; in particular, if a variable is strictly within its
6977 * bounds, its reduced cost must be zero
6978 */
6979 if( stilldualfeasible && (SCIPrationalIsNegInfinity(lpicols[c]->lb) || SCIPrationalIsGT(lpicols[c]->primsol, lpicols[c]->lb)) )
6980 stilldualfeasible = !SCIPrationalIsPositive(lpicols[c]->redcost);
6981 if( stilldualfeasible && (SCIPrationalIsInfinity(lpicols[c]->ub) || SCIPrationalIsLT(lpicols[c]->primsol, lpicols[c]->ub)) )
6982 stilldualfeasible = !SCIPrationalIsNegative(lpicols[c]->redcost);
6983
6984 SCIPrationalDebugMessage("col <%s> [%q,%q]: primsol=%q, redcost=%q, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
6985 SCIPvarGetName(lpicols[c]->var), lpicols[c]->lb, lpicols[c]->ub, lpicols[c]->primsol, lpicols[c]->redcost,
6986 SCIPrationalIsGE(lpicols[c]->primsol, lpicols[c]->lb),
6987 SCIPrationalIsLE(lpicols[c]->primsol, lpicols[c]->ub),
6988 primalfeasible != NULL ? stillprimalfeasible : TRUE,
6989 !SCIPrationalIsGT(lpicols[c]->primsol, lpicols[c]->lb) || !SCIPrationalIsPositive(lpicols[c]->redcost),
6990 !SCIPrationalIsGT(lpicols[c]->primsol, lpicols[c]->ub) || !SCIPrationalIsNegative(lpicols[c]->redcost),
6991 dualfeasible != NULL ? stilldualfeasible : TRUE);
6992
6993 /* we intentionally use an exact positive/negative check because ignoring small reduced cost values may lead to a
6994 * wrong bound value; if the corresponding bound is +/-infinity, we use zero reduced cost (if stilldualfeasible is
6995 * TRUE, we are in the case that the reduced cost is tiny with wrong sign)
6996 */
6997 if( stilldualfeasible )
6998 {
6999 if( SCIPrationalIsPositive(lpicols[c]->redcost) && !SCIPrationalIsNegInfinity(lpicols[c]->lb) )
7000 {
7001 SCIPrationalAddProd(dualbound, lpicols[c]->redcost, lpicols[c]->lb);
7002 }
7003 else if( SCIPrationalIsNegative(lpicols[c]->redcost) && !SCIPrationalIsInfinity(lpicols[c]->ub) )
7004 {
7005 SCIPrationalAddProd(dualbound, lpicols[c]->redcost, lpicols[c]->ub);
7006 }
7007 }
7008 }
7009
7010 /* copy dual solution and activities into rows */
7011 for( r = 0; r < nlpirows; ++r )
7012 {
7013 assert( 0 <= rstat[r] && rstat[r] < 4 );
7014 SCIPrationalSetRational(lpirows[r]->dualsol, dualsol[r]);
7015 SCIPrationalAdd(lpirows[r]->activity, activity[r], lpirows[r]->constant);
7016 lpirows[r]->basisstatus = (unsigned int) rstat[r]; /*lint !e732*/
7017 lpirows[r]->validactivitylp = lpcount;
7018 if( overwritefplp )
7019 {
7020 SCIP_ROW* fprow;
7021 if( SCIProwIsInLP(lpirows[r]->fprow) )
7022 fprow = lpirows[r]->fprow;
7023 else
7024 {
7025 assert(SCIProwIsInLP(lpirows[r]->fprowrhs));
7026 fprow = lpirows[r]->fprowrhs;
7027 }
7028 fprow->dualsol = SCIPrationalGetReal(dualsol[r]);
7029 fprow->activity = SCIPrationalGetReal(lpirows[r]->activity);
7030 fprow->basisstatus = (unsigned int) rstat[r]; /*lint !e732*/
7031 fprow->validactivitylp = lpcount;
7032 }
7033 if( stillprimalfeasible )
7034 {
7035 stillprimalfeasible =
7036 (SCIPrationalIsNegInfinity(lpirows[r]->lhs) ||SCIPrationalIsGE(lpirows[r]->activity, lpirows[r]->lhs))
7037 && (SCIPrationalIsInfinity(lpirows[r]->rhs) || SCIPrationalIsLE(lpirows[r]->activity, lpirows[r]->rhs));
7038 }
7039 /* complementary slackness means that if the activity of a row is not at its left-hand or right-hand side,
7040 * its dual multiplier must be non-positive or non-negative, respectively; in particular, if the activity is
7041 * strictly within left-hand and right-hand side, its dual multiplier must be zero
7042 */
7043 if( stilldualfeasible &&
7044 (SCIPrationalIsNegInfinity(lpirows[r]->lhs) || SCIPrationalIsGT(lpirows[r]->activity, lpirows[r]->lhs)) )
7045 stilldualfeasible = !SCIPrationalIsPositive(lpirows[r]->dualsol);
7046 if( stilldualfeasible &&
7047 (SCIPrationalIsInfinity(lpirows[r]->rhs) || SCIPrationalIsLT(lpirows[r]->activity, lpirows[r]->rhs)) )
7048 stilldualfeasible = !SCIPrationalIsNegative(lpirows[r]->dualsol);
7049
7050 SCIPrationalDebugMessage("<%s> [%q,%q] + %q: activity=%q, dualsol=%q, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
7051 lpirows[r]->fprow->name, lpirows[r]->lhs, lpirows[r]->rhs,
7052 lpirows[r]->constant, lpirows[r]->activity, lpirows[r]->dualsol,
7053 SCIPrationalIsGE(lpirows[r]->activity, lpirows[r]->lhs),
7054 SCIPrationalIsLE(lpirows[r]->activity, lpirows[r]->rhs),
7055 primalfeasible != NULL ? stillprimalfeasible : TRUE,
7056 !SCIPrationalIsGT(lpirows[r]->activity, lpirows[r]->lhs) || !SCIPrationalIsPositive(lpirows[r]->dualsol),
7057 !SCIPrationalIsLT(lpirows[r]->activity, lpirows[r]->rhs) || !SCIPrationalIsNegative(lpirows[r]->dualsol),
7058 dualfeasible != NULL ? stilldualfeasible : TRUE);
7059
7060 /* we intentionally use an exact positive/negative check because ignoring small dual multipliers may lead to a
7061 * wrong bound value; if the corresponding side is +/-infinity, we use a zero dual multiplier (if
7062 * stilldualfeasible is TRUE, we are in the case that the dual multiplier is tiny with wrong sign)
7063 */
7064 if( stilldualfeasible )
7065 {
7066 if( SCIPrationalIsPositive(lpirows[r]->dualsol) && !SCIPrationalIsNegInfinity(lpirows[r]->lhs) )
7067 {
7068 SCIPrationalDiff(tmp, lpirows[r]->lhs, lpirows[r]->constant);
7069 SCIPrationalAddProd(dualbound, tmp, lpirows[r]->dualsol);
7070 }
7071 else if( SCIPrationalIsNegative(lpirows[r]->dualsol) && !SCIPrationalIsInfinity(lpirows[r]->rhs) )
7072 {
7073 SCIPrationalDiff(tmp, lpirows[r]->rhs, lpirows[r]->constant);
7074 SCIPrationalAddProd(dualbound, tmp, lpirows[r]->dualsol);
7075 }
7076 }
7077 }
7078
7079 /* if the objective value returned by the LP solver is smaller than the internally computed primal bound, then we
7080 * declare the solution primal infeasible; we assume primalbound and lpexact->lpobjval to be equal if they are both +/-
7081 * infinity
7082 */
7083 /**@todo alternatively, if otherwise the LP solution is feasible, we could simply update the objective value */
7084 if( stillprimalfeasible && !(SCIPrationalIsInfinity(primalbound) && SCIPrationalIsInfinity(lpexact->lpobjval))
7085 && !(SCIPrationalIsNegInfinity(primalbound) && SCIPrationalIsNegInfinity(lpexact->lpobjval)) )
7086 {
7087 stillprimalfeasible = SCIPrationalIsLE(primalbound, lpexact->lpobjval);
7088 SCIPrationalDebugMessage(" primalbound=%q, lpbound=%q, pfeas=%u(%u)\n", primalbound, lpexact->lpobjval,
7089 SCIPrationalIsLE(primalbound, lpexact->lpobjval), primalfeasible != NULL ? stillprimalfeasible : TRUE);
7090 }
7091
7092 /* if the objective value returned by the LP solver is smaller than the internally computed dual bound, we declare
7093 * the solution dual infeasible; we assume dualbound and lpexact->lpobjval to be equal if they are both +/- infinity
7094 */
7095 /**@todo alternatively, if otherwise the LP solution is feasible, we could simply update the objective value */
7096 if( stilldualfeasible && !(SCIPrationalIsInfinity(dualbound) && SCIPrationalIsInfinity(lpexact->lpobjval))
7097 && !(SCIPrationalIsNegInfinity(dualbound) && SCIPrationalIsNegInfinity(lpexact->lpobjval)) )
7098 {
7099 stilldualfeasible = SCIPrationalIsGE(dualbound, lpexact->lpobjval);
7100 SCIPrationalDebugMessage(" dualbound=%q, lpbound=%q, dfeas=%u(%u)\n", dualbound, lpexact->lpobjval,
7101 SCIPrationalIsGE(dualbound, lpexact->lpobjval), dualfeasible != NULL ? stilldualfeasible : TRUE);
7102 }
7103
7104 if( primalfeasible != NULL )
7105 *primalfeasible = stillprimalfeasible;
7106 if( dualfeasible != NULL )
7107 *dualfeasible = stilldualfeasible;
7108
7109 /* free temporary memory */
7110 SCIPsetFreeBufferArray(set, &rstat);
7111 SCIPsetFreeBufferArray(set, &cstat);
7112 SCIPrationalFreeBufferArray(set->buffer, &redcost, nlpicols);
7113 SCIPrationalFreeBufferArray(set->buffer, &activity, nlpirows);
7114 SCIPrationalFreeBufferArray(set->buffer, &dualsol, nlpirows);
7115 SCIPrationalFreeBufferArray(set->buffer, &primsol, nlpicols);
7116 SCIPrationalFreeBuffer(set->buffer, &tmp);
7117 SCIPrationalFreeBuffer(set->buffer, &dualbound);
7118 SCIPrationalFreeBuffer(set->buffer, &primalbound);
7119
7120 return SCIP_OKAY;
7121}
7122
7123/** stores LP solution with infinite objective value in the columns and rows */
7125 SCIP_LPEXACT* lpexact, /**< current LP data */
7126 SCIP_SET* set, /**< global SCIP settings */
7127 SCIP_STAT* stat, /**< problem statistics */
7128 SCIP_Bool* primalfeasible, /**< pointer to store whether the solution is primal feasible, or NULL */
7129 SCIP_Bool* rayfeasible /**< pointer to store whether the primal ray is a feasible unboundedness proof, or NULL */
7130 ) /*lint --e{715}*/
7131{
7132 SCIPerrorMessage("Unbounded solution not implemented in exact solving mode.\n");
7133 return SCIP_ERROR;
7134}
7135
7136/** returns primal ray proving the unboundedness of the current LP */
7138 SCIP_LPEXACT* lpexact, /**< current LP data */
7139 SCIP_SET* set, /**< global SCIP settings */
7140 SCIP_RATIONAL** ray /**< array for storing primal ray values, they are stored w.r.t. the problem index of the variables,
7141 * so the size of this array should be at least number of active variables
7142 * (all entries have to be initialized to 0 before) */
7143 )
7144{
7145 SCIP_COLEXACT** lpicols;
7146 SCIP_RATIONAL** lpiray;
7147 SCIP_VAR* var;
7148 int nlpicols;
7149 int c;
7150
7151 assert(lpexact != NULL);
7152 assert(set != NULL);
7153 assert(ray != NULL);
7154 assert(lpexact->flushed);
7155 assert(lpexact->solved);
7156 assert(lpexact->lpsolstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY);
7157 assert(SCIPrationalIsNegInfinity(lpexact->lpobjval));
7158
7159 /* check if the LP solver is able to provide a primal unbounded ray */
7160 if( !SCIPlpiExactHasPrimalRay(lpexact->lpiexact) )
7161 {
7162 SCIPerrorMessage("LP solver has no primal ray for unbounded LP\n");
7163 return SCIP_LPERROR;
7164 }
7165
7166 /* get temporary memory */
7167 SCIP_CALL( SCIPrationalCreateBufferArray(set->buffer, &lpiray, lpexact->nlpicols) );
7168
7169 SCIPsetDebugMsg(set, "getting primal ray values\n");
7170
7171 /* get primal unbounded ray */
7172 SCIP_CALL( SCIPlpiExactGetPrimalRay(lpexact->lpiexact, lpiray) );
7173
7174 lpicols = lpexact->lpicols;
7175 nlpicols = lpexact->nlpicols;
7176
7177 /* store the ray values of active problem variables */
7178 for( c = 0; c < nlpicols; c++ )
7179 {
7180 assert(lpicols[c] != NULL);
7181
7182 var = lpicols[c]->var;
7183 assert(var != NULL);
7184 assert(SCIPvarGetProbindex(var) != -1);
7185 SCIPrationalSetRational(ray[SCIPvarGetProbindex(var)], lpiray[c]);
7186 }
7187
7188 SCIPrationalFreeBufferArray(set->buffer, &lpiray, lpexact->nlpicols);
7189
7190 return SCIP_OKAY;
7191}
7192
7193
7194/** stores the dual Farkas multipliers for infeasibility proof in rows. besides
7195 *
7196 * @note The Farkas proof is checked for validity if lp/checkfarkas = TRUE and @p valid is not NULL.
7197 */
7199 SCIP_LPEXACT* lpexact, /**< current LP data */
7200 SCIP_SET* set, /**< global SCIP settings */
7201 SCIP_STAT* stat, /**< problem statistics */
7202 SCIP_Bool* valid, /**< pointer to store whether the Farkas proof is valid or NULL */
7203 SCIP_Bool overwritefplp /**< should the floating point values be overwritten, e.g. if fp lp was infeasible */
7204 )
7205{
7206 SCIP_COLEXACT** lpicols;
7207 SCIP_ROWEXACT** lpirows;
7208 SCIP_RATIONAL** dualfarkas;
7209 SCIP_RATIONAL** farkascoefs;
7210 SCIP_RATIONAL* farkaslhs;
7211 SCIP_RATIONAL* maxactivity;
7212 SCIP_RATIONAL* tmp;
7213 SCIP_Bool checkfarkas;
7214 int nlpicols;
7215 int nlpirows;
7216 int c;
7217 int r;
7218
7219 assert(lpexact != NULL);
7220 assert(lpexact->flushed);
7221 assert(lpexact->solved);
7222 assert(lpexact->lpsolstat == SCIP_LPSOLSTAT_INFEASIBLE);
7223 assert(set != NULL);
7224 assert(stat != NULL);
7225
7226 if( valid != NULL )
7227 *valid = TRUE;
7228
7229 farkascoefs = NULL;
7230 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &maxactivity) );
7231 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &farkaslhs) );
7232 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &tmp) );
7233
7234 checkfarkas = (set->lp_checkfarkas && valid != NULL);
7235
7236 /* get temporary memory */
7237 SCIP_CALL( SCIPrationalCreateBufferArray(set->buffer, &dualfarkas, lpexact->nlpirows) );
7238
7239 if( checkfarkas )
7240 SCIP_CALL( SCIPrationalCreateBufferArray(set->buffer, &farkascoefs, lpexact->nlpicols) );
7241
7242 /* get dual Farkas infeasibility proof */
7243 SCIP_CALL( SCIPlpiExactGetDualfarkas(lpexact->lpiexact, dualfarkas) );
7244
7245 if( overwritefplp )
7246 {
7247 lpexact->fplp->lpobjval = SCIPsetInfinity(set);
7248 lpexact->fplp->lpsolstat = lpexact->lpsolstat;
7249 }
7250
7251 lpicols = lpexact->lpicols;
7252 lpirows = lpexact->lpirows;
7253 nlpicols = lpexact->nlpicols;
7254 nlpirows = lpexact->nlpirows;
7255
7256 /* store infeasibility proof in rows */
7257 SCIPsetDebugMsg(set, "LP is infeasible:\n");
7258 for( r = 0; r < nlpirows; ++r )
7259 {
7260 SCIPrationalDebugMessage(" row <%s>: dualfarkas=%q\n", lpirows[r]->fprow->name, dualfarkas[r]);
7261 SCIPrationalSetRational(lpirows[r]->dualfarkas, dualfarkas[r]);
7262 SCIPrationalSetInfinity(lpirows[r]->dualsol);
7263 SCIPrationalSetReal(lpirows[r]->activity, 0.0);
7264 lpirows[r]->validactivitylp = -1L;
7265 lpirows[r]->basisstatus = (unsigned int) SCIP_BASESTAT_BASIC;
7266 if( overwritefplp )
7267 {
7268 lpexact->fplp->lpirows[r]->dualfarkas = SCIPrationalGetReal(dualfarkas[r]);
7269 lpexact->fplp->lpirows[r]->dualsol = SCIPsetInfinity(set);
7270 lpexact->fplp->lpirows[r]->basisstatus = (unsigned int) SCIP_BASESTAT_BASIC;
7271 lpexact->fplp->lpirows[r]->validactivitylp = -1L;
7272 }
7273
7274 if( checkfarkas )
7275 {
7276 assert(farkascoefs != NULL);
7277
7278 /* the infeasibility proof would be invalid if
7279 * (i) dualfarkas[r] > 0 and lhs = -inf
7280 * (ii) dualfarkas[r] < 0 and rhs = inf
7281 * however, due to numerics we accept slightly negative / positive values
7282 */
7283 if( (SCIPrationalIsPositive(dualfarkas[r]) && SCIPrationalIsNegInfinity(lpirows[r]->lhs))
7284 || (SCIPrationalIsNegative(dualfarkas[r]) && SCIPrationalIsInfinity(lpirows[r]->rhs)) )
7285 {
7286 SCIPrationalDebugMessage("farkas proof is invalid: row <%s>[lhs=%q,rhs=%q,c=%q] has multiplier %q\n",
7287 SCIProwGetName(lpirows[r]->fprow), lpirows[r]->lhs, lpirows[r]->rhs,
7288 lpirows[r]->constant, dualfarkas[r]);
7289
7290 *valid = FALSE; /*lint --e{413,613}*/
7291
7292 goto TERMINATE;
7293 }
7294
7295 /* dual multipliers, for which the corresponding row side in infinite, are treated as zero if they are zero
7296 * within tolerances (see above) but slighty positive / negative
7297 */
7298 if( (SCIPrationalIsPositive(dualfarkas[r]) && SCIPrationalIsNegInfinity(lpirows[r]->lhs))
7299 || (SCIPrationalIsNegative(dualfarkas[r]) && SCIPrationalIsInfinity(lpirows[r]->rhs)) )
7300 continue;
7301
7302 /* iterate over all columns and scale with dual solution */
7303 for( c = 0; c < lpirows[r]->len; c++ )
7304 {
7305 int pos = lpirows[r]->cols[c]->lppos;
7306
7307 if( pos == -1 )
7308 continue;
7309
7310 assert(pos >= 0 && pos < nlpicols);
7311 SCIPrationalAddProd(farkascoefs[pos], dualfarkas[r], lpirows[r]->vals[c]);
7312 }
7313
7314 /* the row contributes with its left-hand side to the proof */
7315 if( SCIPrationalIsPositive(dualfarkas[r]) )
7316 {
7317 assert(!SCIPrationalIsNegInfinity(lpirows[r]->lhs));
7318 SCIPrationalDiff(tmp, lpirows[r]->lhs, lpirows[r]->constant);
7319 SCIPrationalAddProd(farkaslhs, tmp, dualfarkas[r]);
7320 }
7321
7322 /* the row contributes with its right-hand side to the proof */
7323 else if( SCIPrationalIsNegative(dualfarkas[r]) )
7324 {
7325 assert(!SCIPrationalIsInfinity(lpirows[r]->rhs));
7326 SCIPrationalDiff(tmp, lpirows[r]->rhs, lpirows[r]->constant);
7327 SCIPrationalAddProd(farkaslhs, tmp, dualfarkas[r]);
7328 }
7329 }
7330 }
7331
7332 /* set columns as invalid */
7333 for( c = 0; c < nlpicols; ++c )
7334 {
7335 SCIPrationalSetInfinity(lpicols[c]->primsol);
7336 SCIPrationalSetInfinity(lpicols[c]->redcost);
7337 lpicols[c]->validredcostlp = -1L;
7338 lpicols[c]->validfarkaslp = -1L;
7339 if( farkascoefs != NULL )
7340 SCIPrationalSetRational(lpicols[c]->farkascoef, farkascoefs[c]);
7341
7342 if( overwritefplp )
7343 {
7344 lpexact->fplp->lpicols[c]->primsol = SCIPsetInfinity(set);
7345 lpexact->fplp->lpicols[c]->redcost = SCIPsetInfinity(set);
7346 lpexact->fplp->lpicols[c]->validredcostlp = -1L;
7347 lpexact->fplp->lpicols[c]->validfarkaslp = -1L;
7348 }
7349
7350 if( checkfarkas )
7351 {
7352 assert(farkascoefs != NULL);
7353 assert(lpicols[c]->lppos == c);
7354
7355 /* skip coefficients that are too close to zero */
7356 if( SCIPrationalIsZero(farkascoefs[c]) )
7357 continue;
7358
7359 /* calculate the maximal activity */
7360 if( SCIPrationalIsPositive(farkascoefs[c]) )
7361 {
7362 SCIPrationalMult(tmp, farkascoefs[c], SCIPcolExactGetUb(lpicols[c]));
7363 SCIPrationalAdd(maxactivity, maxactivity, tmp);
7364 }
7365 else
7366 {
7367 SCIPrationalMult(tmp, farkascoefs[c], SCIPcolExactGetLb(lpicols[c]));
7368 SCIPrationalAdd(maxactivity, maxactivity, tmp);
7369 }
7370 }
7371 }
7372
7373 /* check whether the farkasproof is valid
7374 * due to numerics, it might happen that the left-hand side of the aggregation is larger/smaller or equal than +/- infinity.
7375 * in that case, we declare the Farkas proof to be invalid.
7376 */
7377 if( checkfarkas && (SCIPrationalIsAbsInfinity(farkaslhs) || SCIPrationalIsGE(maxactivity, farkaslhs)) )
7378 {
7379 SCIPrationalDebugMessage("farkas proof is invalid: maxactivity=%q, lhs=%q\n", maxactivity, farkaslhs);
7380
7381 *valid = FALSE; /*lint --e{413,613}*/
7382 }
7383
7384 TERMINATE:
7385 /* free temporary memory */
7386 if( checkfarkas )
7387 SCIPrationalFreeBufferArray(set->buffer, &farkascoefs, nlpicols);
7388
7389 SCIPrationalFreeBufferArray(set->buffer, &dualfarkas, nlpirows);
7390 SCIPrationalFreeBuffer(set->buffer, &tmp);
7391 SCIPrationalFreeBuffer(set->buffer, &farkaslhs);
7392 SCIPrationalFreeBuffer(set->buffer, &maxactivity);
7393
7394 return SCIP_OKAY;
7395}
7396
7397/** get number of iterations used in last LP solve */
7399 SCIP_LPEXACT* lpexact, /**< current exact LP data */
7400 int* iterations /**< pointer to store the iteration count */
7401 )
7402{
7403 assert(lpexact != NULL);
7404
7405 SCIP_CALL( SCIPlpiExactGetIterations(lpexact->lpiexact, iterations) );
7406
7407 return SCIP_OKAY;
7408}
7409
7410/** gets objective value of current LP
7411 *
7412 * @note This method returns the objective value of the current LP solution, which might be primal or dual infeasible
7413 * if a limit was hit during solving. It must not be used as a dual bound if the LP solution status is
7414 * SCIP_LPSOLSTAT_ITERLIMIT or SCIP_LPSOLSTAT_TIMELIMIT.
7415 */
7417 SCIP_LPEXACT* lpexact, /**< current LP data */
7418 SCIP_SET* set, /**< global SCIP settings */
7419 SCIP_RATIONAL* res /**< result pointer to store rational */
7420 )
7421{
7422 assert(lpexact != NULL);
7423 assert(lpexact->fplp->hasprovedbound);
7424 assert((lpexact->nloosevars > 0) || (lpexact->looseobjvalinf == 0 && SCIPrationalIsZero(lpexact->looseobjval)));
7425 assert(set != NULL);
7426
7427 if( lpexact->looseobjvalinf > 0 )
7429 else if( SCIPrationalIsAbsInfinity(lpexact->lpobjval) )
7430 SCIPrationalSetRational(res, lpexact->lpobjval);
7431 else
7432 SCIPrationalAdd(res, lpexact->lpobjval, lpexact->looseobjval);
7433}
7434
7435/** gets the pseudo objective value for the current search node; that is all variables set to their best (w.r.t. the
7436 * objective function) local bound
7437 */
7439 SCIP_LPEXACT* lpexact, /**< current LP data */
7440 SCIP_SET* set, /**< global SCIP settings */
7441 SCIP_RATIONAL* res /**< result pointer to store rational */
7442 )
7443{
7444 assert(lpexact != NULL);
7445 assert(lpexact->pseudoobjvalinf >= 0);
7446 assert(set != NULL);
7447
7448 if( lpexact->pseudoobjvalinf > 0 || set->nactivepricers > 0 )
7450 else
7452}
7453
7454/** removes all columns after the given number of cols from the LP */
7456 SCIP_LPEXACT* lpexact, /**< LP data */
7457 SCIP_SET* set, /**< global SCIP settings */
7458 int newncols /**< new number of columns in the LP */
7459 )
7460{
7461 SCIP_COLEXACT* col;
7462 int c;
7463
7464 assert(lpexact != NULL);
7465
7466 SCIPsetDebugMsg(set, "shrinking LP from %d to %d columns\n", lpexact->ncols, newncols);
7467 assert(0 <= newncols);
7468 assert(newncols <= lpexact->ncols);
7469
7470 if( newncols < lpexact->ncols )
7471 {
7472 assert(!lpexact->fplp->diving);
7473
7474 for( c = lpexact->ncols-1; c >= newncols; --c )
7475 {
7476 col = lpexact->cols[c];
7477 assert(col != NULL);
7478 assert(col->len == 0 || col->rows != NULL);
7479 assert(col->var != NULL);
7481 assert(SCIPvarGetColExact(col->var) == lpexact->cols[c]);
7482 assert(col->lppos == c);
7483
7484 /* mark column to be removed from the LP */
7485 col->lppos = -1;
7486 lpexact->ncols--;
7487
7488 /* update column arrays of all linked rows */
7490 }
7491
7492 assert(lpexact->ncols == newncols);
7493 lpexact->lpifirstchgcol = MIN(lpexact->lpifirstchgcol, newncols);
7494
7495 lpexact->flushed = FALSE;
7496 checkLinks(lpexact);
7497 }
7498
7499 return SCIP_OKAY;
7500}
7501
7502/** removes and releases all rows after the given number of rows from the LP */
7504 SCIP_LPEXACT* lpexact, /**< LP data */
7505 BMS_BLKMEM* blkmem, /**< block memory */
7506 SCIP_SET* set, /**< global SCIP settings */
7507 int newnrows /**< new number of rows in the LP */
7508 )
7509{
7510 SCIP_ROWEXACT* row;
7511 int r;
7512
7513 assert(lpexact != NULL);
7514 assert(0 <= newnrows && newnrows <= lpexact->nrows);
7515
7516 SCIPsetDebugMsg(set, "shrinking exact LP from %d to %d rows\n", lpexact->nrows, newnrows);
7517 if( newnrows < lpexact->nrows )
7518 {
7519 for( r = lpexact->nrows-1; r >= newnrows; --r )
7520 {
7521 row = lpexact->rows[r];
7522 assert(row != NULL);
7523 assert(row->len == 0 || row->cols != NULL);
7524 assert(row->lppos == r);
7525
7526 /* mark row to be removed from the LP */
7527 row->lppos = -1;
7528 row->lpdepth = -1;
7529 lpexact->nrows--;
7530
7532
7533 SCIP_CALL( SCIProwExactRelease(&lpexact->rows[r], blkmem, set, lpexact) );
7534 }
7535 assert(lpexact->nrows == newnrows);
7536 lpexact->lpifirstchgrow = MIN(lpexact->lpifirstchgrow, newnrows);
7537
7538 /* mark the current LP unflushed */
7539 lpexact->flushed = FALSE;
7540
7541 checkLinks(lpexact);
7542 }
7543
7544 return SCIP_OKAY;
7545}
7546
7547/** resets the LP to the empty LP by removing all columns and rows from LP, releasing all rows, and flushing the
7548 * changes to the LP solver
7549 */
7551 SCIP_LPEXACT* lpexact, /**< LP data */
7552 BMS_BLKMEM* blkmem, /**< block memory */
7553 SCIP_SET* set, /**< global SCIP settings */
7554 SCIP_STAT* stat, /**< problem statistics */
7555 SCIP_EVENTQUEUE* eventqueue /**< event queue */
7556 )
7557{
7558 if( !set->exact_enable )
7559 return SCIP_OKAY;
7560
7561 assert(stat != NULL);
7562
7563 SCIP_CALL( SCIPlpExactClear(lpexact, blkmem, set) );
7564 SCIP_CALL( SCIPlpExactFlush(lpexact, blkmem, set, eventqueue) );
7565
7566 /* mark the empty LP to be solved */
7568 SCIPrationalSetReal(lpexact->lpobjval, 0.0);
7569 lpexact->solved = TRUE;
7570 lpexact->primalfeasible = TRUE;
7571 lpexact->primalchecked = TRUE;
7572 lpexact->dualfeasible = TRUE;
7573 lpexact->dualchecked = TRUE;
7574 lpexact->solisbasic = FALSE;
7576
7577 return SCIP_OKAY;
7578}
7579
7580/** removes all columns and rows from LP, releases all rows */
7582 SCIP_LPEXACT* lpexact, /**< LP data */
7583 BMS_BLKMEM* blkmem, /**< block memory */
7584 SCIP_SET* set /**< global SCIP settings */
7585 )
7586{
7587 assert(lpexact != NULL);
7588 assert(!lpexact->fplp->diving);
7589
7590 SCIPsetDebugMsg(set, "clearing LP\n");
7591 SCIP_CALL( SCIPlpExactShrinkCols(lpexact, set, 0) );
7592 SCIP_CALL( SCIPlpExactShrinkRows(lpexact, blkmem, set, 0) );
7593
7594 return SCIP_OKAY;
7595}
7596
7597/** forces an exact lp to be solved in the next exact bound computation */
7599 SCIP_LPEXACT* lpexact, /**< exact LP data */
7600 SCIP_SET* set /**< global SCIP settings */
7601 )
7602{
7603 assert(set != NULL);
7604
7605 if( !set->exact_enable )
7606 return;
7607
7608 assert(lpexact != NULL);
7609
7610 lpexact->forceexactsolve = TRUE;
7611}
7612
7613/** forces the next exact bound computation to be executed even in probing mode */
7615 SCIP_LPEXACT* lpexact, /**< exact LP data */
7616 SCIP_SET* set /**< global SCIP settings */
7617 )
7618{
7619 assert(set != NULL);
7620
7621 if( !set->exact_enable )
7622 return;
7623
7624 assert(lpexact != NULL);
7625
7626 lpexact->forcesafebound = TRUE;
7627}
7628
7629/** allows an exact lp to be solved in the next exact bound computation */
7631 SCIP_LPEXACT* lpexact, /**< exact LP data */
7632 SCIP_SET* set, /**< global SCIP settings */
7633 SCIP_Bool allowexact /**< TRUE if next safe bounding call should be allowed to be exact, FALSE otherwise */
7634 )
7635{
7636 assert(set != NULL);
7637
7638 if( !set->exact_enable )
7639 return;
7640
7641 assert(lpexact != NULL);
7642
7643 lpexact->allowexactsolve = allowexact;
7644}
7645
7646/** save current LP solution values stored in each column */
7647static
7649 SCIP_COLEXACT* colexact, /**< exact LP column */
7650 BMS_BLKMEM* blkmem /**< block memory */
7651 )
7652{
7653 SCIP_COLEXACTSOLVALS* storedsolvals;
7654
7655 assert(colexact != NULL);
7656 assert(blkmem != NULL);
7657
7658 /* allocate memory for storage */
7659 if( colexact->storedsolvals == NULL )
7660 {
7661 SCIP_ALLOC( BMSallocBlockMemory(blkmem, &colexact->storedsolvals) );
7662
7663 storedsolvals = colexact->storedsolvals;
7664
7665 /* store values */
7666 SCIP_CALL( SCIPrationalCopyBlock(blkmem, &(storedsolvals->primsol), colexact->primsol) );
7667 SCIP_CALL( SCIPrationalCopyBlock(blkmem, &(storedsolvals->redcost), colexact->redcost) );
7668 storedsolvals->basisstatus = colexact->basisstatus; /*lint !e641 !e732*/
7669 }
7670 else
7671 {
7672 storedsolvals = colexact->storedsolvals;
7673
7674 /* store values */
7675 SCIPrationalSetRational(storedsolvals->primsol, colexact->primsol);
7676 SCIPrationalSetRational(storedsolvals->redcost, colexact->redcost);
7677 storedsolvals->basisstatus = colexact->basisstatus; /*lint !e641 !e732*/
7678 }
7679
7680 return SCIP_OKAY;
7681}
7682
7683/** restore LP solution values in column */
7684static
7686 SCIP_COLEXACT* colexact, /**< exact LP column */
7687 BMS_BLKMEM* blkmem, /**< block memory */
7688 SCIP_Longint validlp, /**< number of lp for which restored values are valid */
7689 SCIP_Bool freebuffer /**< should buffer for LP solution values be freed? */
7690 )
7691{
7692 SCIP_COLEXACTSOLVALS* storedsolvals;
7693
7694 assert(colexact != NULL);
7695 assert(blkmem != NULL);
7696
7697 /* if stored values are available, restore them */
7698 storedsolvals = colexact->storedsolvals;
7699 if( storedsolvals != NULL )
7700 {
7701 SCIPrationalSetRational(colexact->primsol, storedsolvals->primsol);
7702 SCIPrationalSetRational(colexact->redcost, storedsolvals->redcost);
7703 colexact->validredcostlp = validlp;
7704 colexact->basisstatus = storedsolvals->basisstatus; /*lint !e641 !e732*/
7705
7706 /* we do not save the farkas coefficient, since it can be recomputed; thus, we invalidate it here */
7707 colexact->validfarkaslp = -1;
7708 }
7709 /* if the column was created after performing the storage (possibly during probing), we treat it as implicitly zero;
7710 * we make sure to invalidate the reduced cost and farkas coefficient, which are not available
7711 */
7712 else
7713 {
7714 SCIPrationalSetReal(colexact->primsol, 0.0);
7715 colexact->validredcostlp = -1;
7716 colexact->validfarkaslp = -1;
7717 colexact->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
7718 }
7719
7720 /* free memory */
7721 if( freebuffer )
7722 {
7723 BMSfreeBlockMemoryNull(blkmem, &colexact->storedsolvals);
7724 assert(colexact->storedsolvals == NULL);
7725 }
7726
7727 return SCIP_OKAY;
7728}
7729
7730/** save current LP solution values stored in each column */
7731static
7733 SCIP_ROWEXACT* rowexact, /**< exact LP row */
7734 BMS_BLKMEM* blkmem, /**< block memory */
7735 SCIP_Bool infeasible /**< is the solution infeasible? */
7736 )
7737{
7738 SCIP_ROWEXACTSOLVALS* storedsolvals;
7739
7740 assert(rowexact != NULL);
7741 assert(blkmem != NULL);
7742
7743 /* allocate memory for storage */
7744 if( rowexact->storedsolvals == NULL )
7745 {
7746 SCIP_ALLOC( BMSallocBlockMemory(blkmem, &rowexact->storedsolvals) );
7747
7748 storedsolvals = rowexact->storedsolvals;
7749
7750 /* store values */
7751 if( infeasible )
7752 {
7753 SCIP_CALL( SCIPrationalCopyBlock(blkmem, &(storedsolvals->dualsol), rowexact->dualfarkas) );
7754 SCIP_CALL( SCIPrationalCreateBlock(blkmem, &(storedsolvals->activity)) );
7755 SCIPrationalSetInfinity(storedsolvals->activity);
7756 storedsolvals->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
7757 }
7758 else
7759 {
7760 SCIP_CALL( SCIPrationalCopyBlock(blkmem, &(storedsolvals->dualsol), rowexact->dualsol) );
7761 SCIP_CALL( SCIPrationalCopyBlock(blkmem, &(storedsolvals->activity), rowexact->activity) );
7762 storedsolvals->basisstatus = rowexact->basisstatus; /*lint !e641 !e732*/
7763 }
7764 }
7765 else
7766 {
7767 storedsolvals = rowexact->storedsolvals;
7768
7769 /* store values */
7770 if( infeasible )
7771 {
7772 SCIPrationalSetRational(storedsolvals->dualsol, rowexact->dualfarkas);
7773 SCIPrationalSetInfinity(storedsolvals->activity);
7774 storedsolvals->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
7775 }
7776 else
7777 {
7778 SCIPrationalSetRational(storedsolvals->dualsol, rowexact->dualsol);
7779 SCIPrationalSetRational(storedsolvals->activity, rowexact->activity);
7780 storedsolvals->basisstatus = rowexact->basisstatus; /*lint !e641 !e732*/
7781 }
7782 }
7783
7784 return SCIP_OKAY;
7785}
7786
7787/** restore LP solution values in row */
7788static
7790 SCIP_ROWEXACT* rowexact, /**< exact LP column */
7791 BMS_BLKMEM* blkmem, /**< block memory */
7792 SCIP_Longint validlp, /**< number of lp for which restored values are valid */
7793 SCIP_Bool freebuffer, /**< should buffer for LP solution values be freed? */
7794 SCIP_Bool infeasible /**< is the solution infeasible? */
7795 )
7796{
7797 SCIP_ROWEXACTSOLVALS* storedsolvals;
7798
7799 assert(rowexact != NULL);
7800 assert(blkmem != NULL);
7801
7802 /* if stored values are available, restore them */
7803 storedsolvals = rowexact->storedsolvals;
7804 if( storedsolvals != NULL )
7805 {
7806 if( infeasible )
7807 SCIPrationalSetRational(rowexact->dualfarkas, storedsolvals->dualsol);
7808 else
7809 SCIPrationalSetRational(rowexact->dualsol, storedsolvals->dualsol);
7810 SCIPrationalSetRational(rowexact->activity, storedsolvals->activity);
7811 rowexact->validactivitylp = validlp;
7812 rowexact->basisstatus = storedsolvals->basisstatus; /*lint !e641 !e732*/
7813 }
7814 /* if the row was created after performing the storage (possibly during probing), we treat it as basic;
7815 * we make sure to invalidate the reduced cost and farkas coefficient, which are not available
7816 */
7817 else
7818 {
7819 SCIPrationalSetReal(rowexact->dualsol, 0.0);
7820 SCIPrationalSetReal(rowexact->dualfarkas, 0.0);
7822 rowexact->validactivitylp = -1;
7823 rowexact->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
7824 }
7825
7826 /* free memory */
7827 if( freebuffer )
7828 {
7829 BMSfreeBlockMemoryNull(blkmem, &rowexact->storedsolvals);
7830 assert(rowexact->storedsolvals == NULL);
7831 }
7832
7833 return SCIP_OKAY;
7834}
7835
7836/** save current LP values dependent on the solution */
7837static
7839 SCIP_LPEXACT* lpexact, /**< exact LP data */
7840 SCIP_STAT* stat, /**< problem statistics */
7841 BMS_BLKMEM* blkmem /**< block memory */
7842 )
7843{
7844 SCIP_LPEXACTSOLVALS* storedsolvals;
7845
7846 assert(lpexact != NULL);
7847 assert(stat != NULL);
7848 assert(blkmem != NULL);
7849
7850 /* allocate memory for storage */
7851 if( lpexact->storedsolvals == NULL )
7852 {
7854
7855 storedsolvals = lpexact->storedsolvals;
7856
7857 /* store values */
7858 SCIP_CALL( SCIPrationalCopyBlock(blkmem, &(storedsolvals->lpobjval), lpexact->lpobjval) );
7859 storedsolvals->lpsolstat = lpexact->lpsolstat;
7860 storedsolvals->primalfeasible = lpexact->primalfeasible;
7861 storedsolvals->primalchecked = lpexact->primalchecked;
7862 storedsolvals->dualfeasible = lpexact->dualfeasible;
7863 storedsolvals->dualchecked = lpexact->dualchecked;
7864 storedsolvals->solisbasic = lpexact->solisbasic;
7865 storedsolvals->lpissolved = lpexact->solved;
7866 }
7867 else
7868 {
7869 storedsolvals = lpexact->storedsolvals;
7870
7871 /* store values */
7872 SCIPrationalSetRational(storedsolvals->lpobjval, lpexact->lpobjval);
7873 storedsolvals->lpsolstat = lpexact->lpsolstat;
7874 storedsolvals->primalfeasible = lpexact->primalfeasible;
7875 storedsolvals->primalchecked = lpexact->primalchecked;
7876 storedsolvals->dualfeasible = lpexact->dualfeasible;
7877 storedsolvals->dualchecked = lpexact->dualchecked;
7878 storedsolvals->solisbasic = lpexact->solisbasic;
7879 storedsolvals->lpissolved = lpexact->solved;
7880 }
7881
7882 return SCIP_OKAY;
7883}
7884
7885/** restore LP solution values in column */
7886static
7888 SCIP_LPEXACT* lpexact, /**< exact LP data */
7889 BMS_BLKMEM* blkmem /**< block memory */
7890 )
7891{
7892 SCIP_LPEXACTSOLVALS* storedsolvals;
7893
7894 assert(lpexact != NULL);
7895 assert(blkmem != NULL);
7896
7897 /* if stored values are available, restore them */
7898 storedsolvals = lpexact->storedsolvals;
7899 if( storedsolvals != NULL )
7900 {
7901#ifdef SCIP_WITH_QSOPTEX
7902 lpexact->solved = FALSE;
7904#else
7905 lpexact->solved = storedsolvals->lpissolved;
7906 lpexact->lpsolstat = storedsolvals->lpsolstat;
7907#endif
7908 SCIPrationalSetRational(lpexact->lpobjval, storedsolvals->lpobjval);
7909 lpexact->primalfeasible = storedsolvals->primalfeasible;
7910 lpexact->primalchecked = storedsolvals->primalchecked;
7911 lpexact->dualfeasible = storedsolvals->dualfeasible;
7912 lpexact->dualchecked = storedsolvals->dualchecked;
7913 lpexact->solisbasic = storedsolvals->solisbasic;
7914
7915 /* solution values are stored only for LPs solved without error */
7916 assert(lpexact->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL ||
7923 }
7924 /* no values available, mark LP as unsolved */
7925 else
7926 {
7927 lpexact->solved = FALSE;
7928 //lpexact->validsollp = -1;
7929
7932 lpexact->primalfeasible = FALSE;
7933 lpexact->primalchecked = FALSE;
7934 lpexact->dualfeasible = FALSE;
7935 lpexact->dualchecked = FALSE;
7936 lpexact->solisbasic = FALSE;
7937 }
7938
7939 return SCIP_OKAY;
7940}
7941
7942/** locks an unmodifiable row, which forbids further changes; has no effect on modifiable rows */
7944 SCIP_ROWEXACT* row /**< exact LP row */
7945 )
7946{
7947 assert(row != NULL);
7948
7949 /* check, if row is modifiable */
7950 if( !row->modifiable )
7951 {
7952 row->nlocks++;
7953 }
7954}
7955
7956/** unlocks a lock of an unmodifiable row; a row with no sealed lock may be modified; has no effect on modifiable rows */
7958 SCIP_ROWEXACT* row /**< exact LP row */
7959 )
7960{
7961 assert(row != NULL);
7962
7963 /* check, if row is modifiable */
7964 if( !row->modifiable )
7965 {
7966 assert(row->nlocks > 0);
7967 row->nlocks--;
7968 }
7969}
7970
7971/** ensures that chgrows array can store at least num entries */
7972static
7974 SCIP_LPEXACT* lpexact, /**< current exact LP data */
7975 SCIP_SET* set, /**< global SCIP settings */
7976 int num /**< minimum number of entries to store */
7977 )
7978{
7979 assert(lpexact->nchgrows <= lpexact->chgrowssize);
7980
7981 if( num > lpexact->chgrowssize )
7982 {
7983 int newsize;
7984
7985 newsize = SCIPsetCalcMemGrowSize(set, num);
7986 SCIP_ALLOC( BMSreallocMemoryArray(&lpexact->chgrows, newsize) );
7987 lpexact->chgrowssize = newsize;
7988 }
7989 assert(num <= lpexact->chgrowssize);
7990
7991 return SCIP_OKAY;
7992}
7993
7994
7995/** notifies exact LP row that its sides were changed */
7996static
7998 SCIP_ROWEXACT* rowexact, /**< exact LP row */
7999 SCIP_SET* set, /**< global SCIP settings */
8000 SCIP_LPEXACT* lpexact, /**< current exact LP data */
8001 SCIP_SIDETYPE sidetype /**< type of side: left or right hand side */
8002 )
8003{
8004 assert(rowexact != NULL);
8005 assert(lpexact != NULL);
8006
8007 if( rowexact->lpipos >= 0 )
8008 {
8009 /* insert row in the chgrows list (if not already there) */
8010 if( !rowexact->lhschanged && !rowexact->rhschanged )
8011 {
8012 SCIP_CALL( ensureChgrowsSizeExact(lpexact, set, lpexact->nchgrows+1) );
8013 lpexact->chgrows[lpexact->nchgrows] = rowexact;
8014 lpexact->nchgrows++;
8015 }
8016
8017 /* mark side change in the row */
8018 switch( sidetype )
8019 {
8020 case SCIP_SIDETYPE_LEFT:
8021 rowexact->lhschanged = TRUE;
8022 break;
8024 rowexact->rhschanged = TRUE;
8025 break;
8026 default:
8027 SCIPerrorMessage("unknown exact row side type\n");
8028 SCIPABORT();
8029 return SCIP_INVALIDDATA; /*lint !e527*/
8030 }
8031
8032 /* mark the current LP unflushed */
8033 lpexact->flushed = FALSE;
8034
8035 assert(lpexact->nchgrows > 0);
8036 }
8037
8038 return SCIP_OKAY;
8039}
8040
8041/** changes left hand side of exact LP row */
8043 SCIP_ROWEXACT* rowexact, /**< exact LP row */
8044 SCIP_SET* set, /**< global SCIP settings */
8045 SCIP_LPEXACT* lpexact, /**< current exact LP data */
8046 SCIP_RATIONAL* lhs /**< new left hand side */
8047 )
8048{
8049 assert(rowexact != NULL);
8050 assert(lpexact != NULL);
8051
8052 if( !SCIPrationalIsEQ(rowexact->lhs, lhs) )
8053 {
8054 SCIPrationalSetRational(rowexact->lhs, lhs);
8056 SCIP_CALL( rowExactSideChanged(rowexact, set, lpexact, SCIP_SIDETYPE_LEFT) );
8057 }
8058
8059 return SCIP_OKAY;
8060}
8061
8062/** changes right hand side of exact LP row */
8064 SCIP_ROWEXACT* rowexact, /**< exact LP row */
8065 SCIP_SET* set, /**< global SCIP settings */
8066 SCIP_LPEXACT* lpexact, /**< current exact LP data */
8067 SCIP_RATIONAL* rhs /**< new right hand side */
8068 )
8069{
8070 assert(rowexact != NULL);
8071 assert(lpexact != NULL);
8072
8073 if( !SCIPrationalIsEQ(rowexact->rhs, rhs) )
8074 {
8075 SCIPrationalSetRational(rowexact->rhs, rhs);
8076 rowexact->rhsreal = SCIPrationalRoundReal(rowexact->rhs, SCIP_R_ROUND_UPWARDS);
8077 SCIP_CALL( rowExactSideChanged(rowexact, set, lpexact, SCIP_SIDETYPE_RIGHT) );
8078 }
8079
8080 return SCIP_OKAY;
8081}
8082
8083/** gets solution status of current exact LP */
8085 SCIP_LPEXACT* lpexact /**< current LP data */
8086 )
8087{
8088 assert(lpexact != NULL);
8089
8090 return (lpexact->flushed ? lpexact->lpsolstat : SCIP_LPSOLSTAT_NOTSOLVED);
8091}
8092
8093/** stores exact LP state (like basis information) into LP state object */
8095 SCIP_LPEXACT* lpexact, /**< exact LP data */
8096 BMS_BLKMEM* blkmem, /**< block memory */
8097 SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
8098 )
8099{
8100 assert(lpexact != NULL);
8101 assert(lpexact->flushed);
8102 assert(lpexact->solved);
8103 assert(blkmem != NULL);
8104 assert(lpistate != NULL);
8105
8106 /* check whether there is no lp */
8107 if( lpexact->nlpicols == 0 && lpexact->nlpirows == 0 )
8108 *lpistate = NULL;
8109 else
8110 {
8111 SCIP_CALL( SCIPlpiExactGetState(lpexact->lpiexact, blkmem, lpistate) );
8112 }
8113
8114 return SCIP_OKAY;
8115}
8116
8117/** loads exact LP state (like basis information) into solver */
8119 SCIP_LPEXACT* lpexact, /**< exact LP data */
8120 BMS_BLKMEM* blkmem, /**< block memory */
8121 SCIP_SET* set, /**< global SCIP settings */
8122 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
8123 SCIP_LPISTATE* lpistate, /**< LP state information (like basis information) */
8124 SCIP_Bool wasprimfeas, /**< primal feasibility when LP state information was stored */
8125 SCIP_Bool wasprimchecked, /**< true if the LP solution has passed the primal feasibility check */
8126 SCIP_Bool wasdualfeas, /**< dual feasibility when LP state information was stored */
8127 SCIP_Bool wasdualchecked /**< true if the LP solution has passed the dual feasibility check */
8128 )
8129{
8130 assert(lpexact != NULL);
8131 assert(blkmem != NULL);
8132
8133 /* flush changes to the LP solver */
8134 SCIP_CALL( SCIPlpExactFlush(lpexact, blkmem, set, eventqueue) );
8135 assert(lpexact->flushed);
8136
8137 if( lpexact->solved && lpexact->solisbasic )
8138 return SCIP_OKAY;
8139
8140 /* set LPI state in the LP solver */
8141 if( lpistate == NULL )
8142 lpexact->solisbasic = FALSE;
8143 else
8144 {
8145 SCIP_CALL( SCIPlpiExactSetState(lpexact->lpiexact, blkmem, lpistate) );
8146 lpexact->solisbasic = SCIPlpiExactHasStateBasis(lpexact->lpiexact, lpistate);
8147 }
8148 /* @todo: setting feasibility to TRUE might be wrong because in probing mode, the state is even saved when the LP was
8149 * flushed and solved, also, e.g., when we hit the iteration limit
8150 */
8151 lpexact->primalfeasible = wasprimfeas;
8152 lpexact->primalchecked = wasprimchecked;
8153 lpexact->dualfeasible = wasdualfeas;
8154 lpexact->dualchecked = wasdualchecked;
8155
8156 return SCIP_OKAY;
8157}
8158
8159/** frees exact LP state information */
8161 SCIP_LPEXACT* lpexact, /**< exact LP data */
8162 BMS_BLKMEM* blkmem, /**< block memory */
8163 SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
8164 )
8165{
8166 assert(lpexact != NULL);
8167
8168 if( *lpistate != NULL )
8169 {
8170 SCIP_CALL( SCIPlpiExactFreeState(lpexact->lpiexact, blkmem, lpistate) );
8171 }
8172
8173 return SCIP_OKAY;
8174}
8175
8176/** initiates exact LP diving */
8178 SCIP_LPEXACT* lpexact, /**< current exact LP data */
8179 BMS_BLKMEM* blkmem, /**< block memory */
8180 SCIP_SET* set, /**< global SCIP settings */
8181 SCIP_STAT* stat /**< problem statistics */
8182 )
8183{
8184 int c;
8185 int r;
8186
8187 assert(lpexact != NULL);
8188 assert(lpexact->flushed || !lpexact->solved);
8189 assert(lpexact->fplp->diving);
8190 assert(!lpexact->diving);
8191 assert(lpexact->divelpistate == NULL);
8192 assert(lpexact->divelpwasprimfeas);
8193 assert(lpexact->divelpwasdualfeas);
8194 assert(blkmem != NULL);
8195 assert(set != NULL);
8196 assert(lpexact->ndivechgsides == 0);
8197
8198 SCIPsetDebugMsg(set, "exact diving started (LP flushed: %u, LP solved: %u, solstat: %d)\n",
8199 lpexact->flushed, lpexact->solved, SCIPlpExactGetSolstat(lpexact));
8200
8201#ifdef SCIP_MORE_DEBUG
8202 for( c = 0; c < lpexact->ncols; ++c )
8203 {
8204 assert(lpexact->cols[c] != NULL);
8205 assert(lpexact->cols[c]->var != NULL);
8206 assert(SCIPvarGetStatusExact(lpexact->cols[c]->var) == SCIP_VARSTATUS_COLUMN);
8207 assert(SCIPvarGetColExact(lpexact->cols[c]->var) == lpexact->cols[c]);
8208 assert(SCIPrationalIsEQ(SCIPvarGetObjExact(lpexact->cols[c]->var), lpexact->cols[c]->obj));
8209 assert(SCIPrationalIsEQ(SCIPvarGetLbLocalExact(lpexact->cols[c]->var), lpexact->cols[c]->lb));
8210 assert(SCIPrationalIsEQ(SCIPvarGetUbLocalExact(lpexact->cols[c]->var), lpexact->cols[c]->ub));
8211 }
8212#endif
8213
8214 /* save current LPI state (basis information) */
8215 SCIP_CALL( SCIPlpiExactGetState(lpexact->lpiexact, blkmem, &lpexact->divelpistate) );
8216 lpexact->divelpwasprimfeas = lpexact->primalfeasible;
8217 lpexact->divelpwasdualfeas = lpexact->dualfeasible;
8218 lpexact->divelpwasprimchecked = lpexact->primalchecked;
8219 lpexact->divelpwasdualchecked = lpexact->dualchecked;
8220
8221 /* save current LP values dependent on the solution */
8222 SCIP_CALL( lpExactStoreSolVals(lpexact, stat, blkmem) );
8223 assert(lpexact->storedsolvals != NULL);
8224 if( !set->lp_resolverestore && lpexact->solved && lpexact->flushed )
8225 {
8226 SCIP_Bool store = TRUE;
8227
8228 switch( lpexact->lpsolstat )
8229 {
8231 SCIP_CALL( SCIPlpExactGetSol(lpexact, set, stat, NULL, NULL, FALSE) );
8232 break;
8234 SCIP_CALL( SCIPlpExactGetUnboundedSol(lpexact, set, stat, NULL, NULL) );
8235 break;
8239 SCIP_CALL( SCIPlpExactGetSol(lpexact, set, stat, NULL, NULL, FALSE) );
8240 break;
8242 SCIP_CALL( SCIPlpExactGetDualfarkas(lpexact, set, stat, NULL, FALSE) );
8243 break;
8246 default:
8247 store = FALSE;
8248 }
8249
8250 if( store )
8251 {
8252 for( c = 0; c < lpexact->ncols; ++c )
8253 {
8254 SCIP_CALL( colExactStoreSolVals(lpexact->cols[c], blkmem) );
8255 }
8256
8257 for( r = 0; r < lpexact->nrows; ++r )
8258 {
8260 }
8261 }
8262 }
8263
8264 /* store LPI iteration limit */
8266
8267 /* remember the number of domain changes */
8268 lpexact->divenolddomchgs = stat->domchgcount;
8269
8270 /* store current number of rows */
8271 lpexact->ndivingrows = lpexact->nrows;
8272
8273 /* switch to diving mode */
8274 lpexact->diving = TRUE;
8275
8276 return SCIP_OKAY;
8277}
8278
8279/** quits exact LP diving and resets bounds and objective values of columns to the current node's values */
8281 SCIP_LPEXACT* lpexact, /**< current exact LP data */
8282 BMS_BLKMEM* blkmem, /**< block memory */
8283 SCIP_SET* set, /**< global SCIP settings */
8284 SCIP_STAT* stat, /**< problem statistics */
8285 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
8286 SCIP_VAR** vars, /**< array with all active variables */
8287 int nvars /**< number of active variables */
8288 )
8289{
8290 SCIP_VAR* var;
8291 int v;
8292
8293 assert(lpexact != NULL);
8294 assert(lpexact->diving);
8295 assert(blkmem != NULL);
8296 assert(nvars == 0 || vars != NULL);
8297
8298 SCIPsetDebugMsg(set, "exact diving ended (LP flushed: %u, solstat: %d)\n", lpexact->flushed, SCIPlpExactGetSolstat(lpexact));
8299
8300 /* reset all columns' objective values and bounds to its original values */
8301 for( v = 0; v < nvars; ++v )
8302 {
8303 var = vars[v];
8304 assert(var != NULL);
8306 {
8310 }
8311 }
8312
8313 /* undo changes to left hand sides and right hand sides */
8314 while( lpexact->ndivechgsides > 0 )
8315 {
8316 SCIP_RATIONAL* oldside;
8317 SCIP_SIDETYPE sidetype;
8318 SCIP_ROWEXACT* row;
8319
8320 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &oldside) );
8321
8322 lpexact->ndivechgsides--;
8323 SCIPrationalSetRational(oldside, lpexact->divechgsides[lpexact->ndivechgsides]);
8324 sidetype = lpexact->divechgsidetypes[lpexact->ndivechgsides];
8325 row = lpexact->divechgrows[lpexact->ndivechgsides];
8326
8327 if( sidetype == SCIP_SIDETYPE_LEFT )
8328 {
8329 SCIP_CALL( SCIProwExactChgLhs(row, set, lpexact, oldside) );
8330 }
8331 else
8332 {
8333 SCIP_CALL( SCIProwExactChgRhs(row, set, lpexact, oldside) );
8334 }
8335
8336 SCIPrationalFreeBuffer(set->buffer, &oldside);
8337 }
8338
8339 /* restore LPI iteration limit */
8341
8342 /* reload LPI state saved at start of diving and free it afterwards; it may be NULL, in which case simply nothing
8343 * happens
8344 */
8345 SCIP_CALL( SCIPlpExactSetState(lpexact, blkmem, set, eventqueue, lpexact->divelpistate,
8346 lpexact->divelpwasprimfeas, lpexact->divelpwasprimchecked, lpexact->divelpwasdualfeas, lpexact->divelpwasdualchecked) );
8347 SCIP_CALL( SCIPlpExactFreeState(lpexact, blkmem, &lpexact->divelpistate) );
8348 lpexact->divelpwasprimfeas = TRUE;
8349 lpexact->divelpwasdualfeas = TRUE;
8350 lpexact->divelpwasprimchecked = TRUE;
8351 lpexact->divelpwasdualchecked = TRUE;
8352 assert(lpexact->divelpistate == NULL);
8353
8354 /* switch to standard (non-diving) mode */
8355 lpexact->diving = FALSE;
8356 lpexact->divingobjchg = FALSE;
8357
8358 assert(lpexact->storedsolvals != NULL);
8359
8360 /* we can just always reload the buffered LP solution values at start of diving; this has the advantage that we
8361 * re-solve as above can lead to a different LP status
8362 */
8363 if( lpexact->storedsolvals->lpissolved )
8364 {
8365 int c;
8366 int r;
8367
8368 /* restore LP solution values in lp data, columns and rows */
8375 {
8376 SCIP_CALL( lpExactRestoreSolVals(lpexact, blkmem) );
8377
8378 for( c = 0; c < lpexact->ncols; ++c )
8379 {
8380 SCIP_CALL( colExactRestoreSolVals(lpexact->cols[c], blkmem, stat->lpcount, set->lp_freesolvalbuffers) );
8381 }
8382
8383 for( r = 0; r < lpexact->nrows; ++r )
8384 {
8385 SCIP_CALL( rowExactRestoreSolVals(lpexact->rows[r], blkmem, stat->lpcount, set->lp_freesolvalbuffers,
8387 }
8388 }
8389 else
8390 {
8391 SCIP_CALL( lpExactRestoreSolVals(lpexact, blkmem) );
8392 }
8393 }
8394 else
8395 {
8396 /* we still need to copy the exact lp objval back because the safe bounding result is saved there */
8398
8399 lpexact->solved = FALSE;
8401 }
8402
8403#ifdef SCIP_MORE_DEBUG
8404 {
8405 int c;
8406 for( c = 0; c < lpexact->ncols; ++c )
8407 {
8408 assert(lpexact->cols[c] != NULL);
8409 assert(lpexact->cols[c]->var != NULL);
8410 assert(SCIPvarGetStatusExact(lpexact->cols[c]->var) == SCIP_VARSTATUS_COLUMN);
8411 assert(SCIPvarGetColExact(lpexact->cols[c]->var) == lpexact->cols[c]);
8412 assert(SCIPrationalIsEQ(SCIPvarGetObjExact(lpexact->cols[c]->var), lpexact->cols[c]->obj));
8413 assert(SCIPrationalIsEQ(SCIPvarGetLbLocalExact(lpexact->cols[c]->var), lpexact->cols[c]->lb));
8414 assert(SCIPrationalIsEQ(SCIPvarGetUbLocalExact(lpexact->cols[c]->var), lpexact->cols[c]->ub));
8415 }
8416 }
8417#endif
8418
8419 return SCIP_OKAY;
8420}
8421
8422/** returns whether the exact LP is in exact diving mode */
8424 SCIP_LPEXACT* lpexact /**< current exact LP data */
8425 )
8426{
8427 if( lpexact == NULL )
8428 return FALSE;
8429
8430 return lpexact->diving;
8431}
8432
8433/** writes exact LP to a file */
8435 SCIP_LPEXACT* lpexact, /**< current LP data */
8436 const char* fname /**< file name */
8437 )
8438{
8439 assert(lpexact != NULL);
8440 assert(lpexact->flushed);
8441 assert(fname != NULL);
8442
8443 SCIP_CALL( SCIPlpiExactWriteLP(lpexact->lpiexact, fname) );
8444
8445 return SCIP_OKAY;
8446}
8447
8448/** overwrites the dual values stored in the fp lp with exact values */
8450 SCIP_LPEXACT* lpexact, /**< current LP data */
8451 SCIP_Bool dualfarkas /**< TRUE if farkas proof, FALSE if dual sol? */
8452 )
8453{
8454 assert(lpexact != NULL);
8455
8456 for( int c = 0; c < lpexact->ncols; ++c )
8457 {
8458 if( dualfarkas )
8459 lpexact->cols[c]->fpcol->farkascoef = SCIPrationalGetReal(lpexact->cols[c]->farkascoef);
8460 else
8461 lpexact->cols[c]->fpcol->redcost = SCIPrationalGetReal(lpexact->cols[c]->redcost);
8462 }
8463
8464 for( int r = 0; r < lpexact->nrows; ++r )
8465 {
8466 if( dualfarkas )
8467 lpexact->rows[r]->fprow->dualfarkas = SCIPrationalGetReal(lpexact->rows[r]->dualfarkas);
8468 else
8469 lpexact->rows[r]->fprow->dualsol = SCIPrationalGetReal(lpexact->rows[r]->dualsol);
8470 }
8471}
8472
8473/** synchronizes the exact LP with cuts from the floating-point LP */
8475 SCIP_LPEXACT* lpexact, /**< LP data */
8476 BMS_BLKMEM* blkmem, /**< block memory */
8477 SCIP_SET* set /**< global SCIP settings */
8478 )
8479{
8480 SCIP_LP* fplp;
8481 SCIP_ROWEXACT* rowexact;
8482 int* rowdset;
8483 int nrowsfp;
8484 int nrowsex;
8485 int i;
8486 SCIP_Bool removecut;
8487
8488 if( !set->exact_enable )
8489 return SCIP_OKAY;
8490
8491 fplp = lpexact->fplp;
8492
8493 assert(fplp != NULL);
8494
8495 nrowsfp = SCIPlpGetNRows(fplp);
8496 nrowsex = SCIPlpExactGetNRows(lpexact);
8497
8498 SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdset, lpexact->nrows) );
8499
8500 removecut = FALSE;
8501
8502 /* this method should sync the fp-lp withe the exact lp */
8503
8504 /* remove all rows from exact lp that are not in the floating point lp */
8505 for( i = 0; i < nrowsex; ++i )
8506 {
8507 SCIP_ROW* fprow = lpexact->rows[i]->fprow;
8508
8509 if( fprow == NULL || !SCIProwIsInLP(fprow) || fprow->lppos != i || removecut )
8510 {
8511 removecut = TRUE;
8512 rowdset[i] = 1;
8513 }
8514 else
8515 rowdset[i] = 0;
8516 }
8517
8518 SCIP_CALL( SCIPlpExactDelRowset(lpexact, blkmem, set, rowdset) );
8519
8520 for( i = 0; i < nrowsfp; ++i )
8521 {
8522 rowexact = SCIProwGetRowExact(fplp->rows[i]);
8523 assert(rowexact != NULL);
8524 /* if the row is already in lp, do nothing */
8525 if( !SCIProwExactIsInLP(rowexact) )
8526 {
8527 /* add the exact row to the exact lp */
8528 SCIP_CALL( SCIPlpExactAddRow(lpexact, set, rowexact) );
8529 }
8530 }
8531
8532 SCIPsetFreeBufferArray(set, &rowdset);
8533
8534 return SCIP_OKAY;
8535}
SCIP_Real * r
Definition: circlepacking.c:59
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
internal methods for storing cuts in a cut pool
#define NULL
Definition: def.h:248
#define SCIP_Longint
Definition: def.h:141
#define SCIP_REAL_UNITROUNDOFF
Definition: def.h:160
#define SCIP_INVALID
Definition: def.h:178
#define SCIP_Bool
Definition: def.h:91
#define MIN(x, y)
Definition: def.h:224
#define SCIP_ALLOC(x)
Definition: def.h:366
#define SCIP_Real
Definition: def.h:156
#define SCIP_UNKNOWN
Definition: def.h:179
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define MAX(x, y)
Definition: def.h:220
#define SCIP_LONGINT_FORMAT
Definition: def.h:148
#define SCIPABORT()
Definition: def.h:327
#define REALABS(x)
Definition: def.h:182
#define SCIP_CALL(x)
Definition: def.h:355
internal methods for managing events
SCIP_Bool SCIPlpiExactHasDualRay(SCIP_LPIEXACT *lpi)
SCIP_RETCODE SCIPlpiExactSetRealpar(SCIP_LPIEXACT *lpi, SCIP_LPPARAM type, SCIP_Real dval)
SCIP_RETCODE SCIPlpiExactSetBase(SCIP_LPIEXACT *lpi, int *cstat, int *rstat)
SCIP_Bool SCIPlpiExactHasStateBasis(SCIP_LPIEXACT *lpi, SCIP_LPISTATE *lpistate)
SCIP_RETCODE SCIPlpiExactGetObj(SCIP_LPIEXACT *lpi, int firstcol, int lastcol, SCIP_RATIONAL **vals)
SCIP_RETCODE SCIPlpiExactGetObjval(SCIP_LPIEXACT *lpi, SCIP_RATIONAL *objval)
SCIP_RETCODE SCIPlpiExactWriteLP(SCIP_LPIEXACT *lpi, const char *fname)
SCIP_Bool SCIPlpiExactHasPrimalRay(SCIP_LPIEXACT *lpi)
SCIP_RETCODE SCIPlpiExactGetDualfarkas(SCIP_LPIEXACT *lpi, SCIP_RATIONAL **dualfarkas)
SCIP_RETCODE SCIPlpiExactSolveDual(SCIP_LPIEXACT *lpi)
SCIP_RETCODE SCIPlpiExactSetIntpar(SCIP_LPIEXACT *lpi, SCIP_LPPARAM type, int ival)
SCIP_Bool SCIPlpiExactIsPrimalUnbounded(SCIP_LPIEXACT *lpi)
SCIP_RETCODE SCIPlpiExactGetSides(SCIP_LPIEXACT *lpi, int firstrow, int lastrow, SCIP_RATIONAL **lhss, SCIP_RATIONAL **rhss)
SCIP_Bool SCIPlpiExactIsPrimalInfeasible(SCIP_LPIEXACT *lpi)
SCIP_Real SCIPlpiExactInfinity(SCIP_LPIEXACT *lpi)
SCIP_RETCODE SCIPlpiExactGetSolFeasibility(SCIP_LPIEXACT *lpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
SCIP_Bool SCIPlpiExactExistsPrimalRay(SCIP_LPIEXACT *lpi)
SCIP_RETCODE SCIPlpiExactAddRows(SCIP_LPIEXACT *lpi, int nrows, SCIP_RATIONAL **lhs, SCIP_RATIONAL **rhs, char **rownames, int nnonz, int *beg, int *ind, SCIP_RATIONAL **val)
SCIP_RETCODE SCIPlpiExactCreate(SCIP_LPIEXACT **lpi, SCIP_MESSAGEHDLR *messagehdlr, const char *name, SCIP_OBJSEN objsen)
SCIP_Bool SCIPlpiExactIsIterlimExc(SCIP_LPIEXACT *lpi)
SCIP_Bool SCIPlpiExactIsPrimalFeasible(SCIP_LPIEXACT *lpi)
SCIP_Bool SCIPlpiExactIsDualFeasible(SCIP_LPIEXACT *lpi)
SCIP_Bool SCIPlpiExactIsOptimal(SCIP_LPIEXACT *lpi)
SCIP_RETCODE SCIPlpiExactAddCols(SCIP_LPIEXACT *lpi, int ncols, SCIP_RATIONAL **obj, SCIP_RATIONAL **lb, SCIP_RATIONAL **ub, char **colnames, int nnonz, int *beg, int *ind, SCIP_RATIONAL **val)
SCIP_RETCODE SCIPlpiExactGetBase(SCIP_LPIEXACT *lpi, int *cstat, int *rstat)
SCIP_RETCODE SCIPlpiExactDelCols(SCIP_LPIEXACT *lpi, int firstcol, int lastcol)
SCIP_RETCODE SCIPlpiExactChgObj(SCIP_LPIEXACT *lpi, int ncols, int *ind, SCIP_RATIONAL **obj)
SCIP_RETCODE SCIPlpiExactGetPrimalRay(SCIP_LPIEXACT *lpi, SCIP_RATIONAL **ray)
SCIP_RETCODE SCIPlpiExactGetBounds(SCIP_LPIEXACT *lpi, int firstcol, int lastcol, SCIP_RATIONAL **lbs, SCIP_RATIONAL **ubs)
int SCIPlpiExactGetInternalStatus(SCIP_LPIEXACT *lpi)
SCIP_RETCODE SCIPlpiExactClear(SCIP_LPIEXACT *lpi)
SCIP_RETCODE SCIPlpiExactFree(SCIP_LPIEXACT **lpi)
SCIP_Bool SCIPlpiExactIsObjlimExc(SCIP_LPIEXACT *lpi)
SCIP_RETCODE SCIPlpiExactGetNCols(SCIP_LPIEXACT *lpi, int *ncols)
SCIP_RETCODE SCIPlpiExactChgSides(SCIP_LPIEXACT *lpi, int nrows, int *ind, SCIP_RATIONAL **lhs, SCIP_RATIONAL **rhs)
SCIP_RETCODE SCIPlpiExactGetState(SCIP_LPIEXACT *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
SCIP_RETCODE SCIPlpiExactDelRows(SCIP_LPIEXACT *lpi, int firstrow, int lastrow)
SCIP_RETCODE SCIPlpiExactGetNRows(SCIP_LPIEXACT *lpi, int *nrows)
SCIP_Bool SCIPlpiExactIsTimelimExc(SCIP_LPIEXACT *lpi)
SCIP_RETCODE SCIPlpiExactGetRealpar(SCIP_LPIEXACT *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
SCIP_RETCODE SCIPlpiExactChgBounds(SCIP_LPIEXACT *lpi, int ncols, int *ind, SCIP_RATIONAL **lb, SCIP_RATIONAL **ub)
SCIP_RETCODE SCIPlpiExactFreeState(SCIP_LPIEXACT *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
SCIP_RETCODE SCIPlpiExactDelRowset(SCIP_LPIEXACT *lpi, int *dstat)
SCIP_RETCODE SCIPlpiExactGetSol(SCIP_LPIEXACT *lpi, SCIP_RATIONAL *objval, SCIP_RATIONAL **primsol, SCIP_RATIONAL **dualsol, SCIP_RATIONAL **activity, SCIP_RATIONAL **redcost)
SCIP_RETCODE SCIPlpiExactGetIntpar(SCIP_LPIEXACT *lpi, SCIP_LPPARAM type, int *ival)
SCIP_RETCODE SCIPlpiExactSetState(SCIP_LPIEXACT *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE *lpistate)
SCIP_RETCODE SCIPlpiExactGetIterations(SCIP_LPIEXACT *lpi, int *iterations)
SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
Definition: lpi_clp.cpp:2995
SCIP_Bool SCIPlpiHasStateBasis(SCIP_LPI *lpi, SCIP_LPISTATE *lpistate)
Definition: lpi_clp.cpp:3550
const char * SCIPlpiGetSolverName(void)
Definition: lpi_clp.cpp:454
SCIP_RETCODE SCIPlpiFreeState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_clp.cpp:3531
SCIP_RETCODE SCIPlpiGetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_clp.cpp:3417
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:120
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
Definition: lp.c:17425
SCIP_Bool SCIPcolIsIntegral(SCIP_COL *col)
Definition: lp.c:17455
void SCIPintervalSetRoundingModeUpwards(void)
void SCIPintervalSetRoundingModeDownwards(void)
SCIP_Real SCIPintervalGetInf(SCIP_INTERVAL interval)
SCIP_ROUNDMODE SCIPintervalGetRoundingMode(void)
void SCIPintervalSetRoundingMode(SCIP_ROUNDMODE roundmode)
int SCIP_ROUNDMODE
Definition: intervalarith.h:65
void SCIPintervalSet(SCIP_INTERVAL *resultant, SCIP_Real value)
SCIP_Real SCIPintervalGetSup(SCIP_INTERVAL interval)
void SCIPintervalSetRational(SCIP_INTERVAL *resultant, SCIP_RATIONAL *value)
SCIP_RETCODE SCIPprintRowExact(SCIP *scip, SCIP_ROWEXACT *row, FILE *file)
Definition: scip_lpexact.c:419
SCIP_Bool SCIPrationalIsLTReal(SCIP_RATIONAL *rat, SCIP_Real real)
Definition: rational.cpp:1576
SCIP_Bool SCIPrationalIsFpRepresentable(SCIP_RATIONAL *rational)
Definition: rational.cpp:1710
void SCIPrationalMin(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
Definition: rational.cpp:1342
SCIP_RETCODE SCIPrationalCreateBlock(BMS_BLKMEM *blkmem, SCIP_RATIONAL **rational)
Definition: rational.cpp:108
void SCIPrationalMult(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
Definition: rational.cpp:1066
void SCIPrationalSetInfinity(SCIP_RATIONAL *res)
Definition: rational.cpp:618
void SCIPrationalAdd(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
Definition: rational.cpp:935
SCIP_Real SCIPrationalGetReal(SCIP_RATIONAL *rational)
Definition: rational.cpp:2085
SCIP_RETCODE SCIPrationalCreateString(BMS_BLKMEM *mem, SCIP_RATIONAL **rational, const char *desc)
Definition: rational.cpp:796
SCIP_Bool SCIPrationalIsApproxEQReal(SCIP_SET *set, SCIP_RATIONAL *rat, SCIP_Real real, SCIP_ROUNDMODE_RAT roundmode)
Definition: rational.cpp:1451
void SCIPrationalFreeBlock(BMS_BLKMEM *mem, SCIP_RATIONAL **rational)
Definition: rational.cpp:461
#define SCIPrationalDebugMessage
Definition: rational.h:641
SCIP_Bool SCIPrationalIsAbsInfinity(SCIP_RATIONAL *rational)
Definition: rational.cpp:1680
SCIP_Bool SCIPrationalIsLT(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
Definition: rational.cpp:1503
void SCIPrationalSetReal(SCIP_RATIONAL *res, SCIP_Real real)
Definition: rational.cpp:603
SCIP_Bool SCIPrationalIsGT(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
Definition: rational.cpp:1474
SCIP_RETCODE SCIPrationalCopyBlock(BMS_BLKMEM *mem, SCIP_RATIONAL **result, SCIP_RATIONAL *src)
Definition: rational.cpp:151
void SCIPrationalFreeBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
Definition: rational.cpp:473
SCIP_RETCODE SCIPrationalCopyBlockArray(BMS_BLKMEM *mem, SCIP_RATIONAL ***target, SCIP_RATIONAL **src, int len)
Definition: rational.cpp:249
void SCIPrationalDiff(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
Definition: rational.cpp:983
SCIP_Bool SCIPrationalIsLEReal(SCIP_RATIONAL *rat, SCIP_Real real)
Definition: rational.cpp:1615
SCIP_Bool SCIPrationalIsPositive(SCIP_RATIONAL *rational)
Definition: rational.cpp:1640
SCIP_RETCODE SCIPrationalCreateBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
Definition: rational.cpp:123
void SCIPrationalAddProd(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
Definition: rational.cpp:1173
SCIP_Bool SCIPrationalIsZero(SCIP_RATIONAL *rational)
Definition: rational.cpp:1624
void SCIPrationalSetRational(SCIP_RATIONAL *res, SCIP_RATIONAL *src)
Definition: rational.cpp:569
SCIP_Bool SCIPrationalIsGEReal(SCIP_RATIONAL *rat, SCIP_Real real)
Definition: rational.cpp:1606
SCIP_Bool SCIPrationalIsIntegral(SCIP_RATIONAL *rational)
Definition: rational.cpp:1691
SCIP_Bool SCIPrationalDenominatorIsLE(SCIP_RATIONAL *rational, SCIP_Longint val)
Definition: rational.cpp:2036
SCIP_Bool SCIPrationalIsGE(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
Definition: rational.cpp:1512
void SCIPrationalMessage(SCIP_MESSAGEHDLR *msg, FILE *file, SCIP_RATIONAL *rational)
Definition: rational.cpp:1790
void SCIPrationalSetNegInfinity(SCIP_RATIONAL *res)
Definition: rational.cpp:630
void SCIPrationalSetFraction(SCIP_RATIONAL *res, SCIP_Longint nom, SCIP_Longint denom)
Definition: rational.cpp:582
void SCIPrationalNegate(SCIP_RATIONAL *res, SCIP_RATIONAL *op)
Definition: rational.cpp:1297
SCIP_Bool SCIPrationalIsNegative(SCIP_RATIONAL *rational)
Definition: rational.cpp:1650
SCIP_Bool SCIPrationalIsInfinity(SCIP_RATIONAL *rational)
Definition: rational.cpp:1660
void SCIPrationalFreeBlockArray(BMS_BLKMEM *mem, SCIP_RATIONAL ***ratblockarray, int size)
Definition: rational.cpp:501
SCIP_Real SCIPrationalRoundReal(SCIP_RATIONAL *rational, SCIP_ROUNDMODE_RAT roundmode)
Definition: rational.cpp:2110
SCIP_RETCODE SCIPrationalCreateBufferArray(BMS_BUFMEM *mem, SCIP_RATIONAL ***rational, int size)
Definition: rational.cpp:214
SCIP_Bool SCIPrationalIsNegInfinity(SCIP_RATIONAL *rational)
Definition: rational.cpp:1670
SCIP_Bool SCIPrationalIsGTReal(SCIP_RATIONAL *rat, SCIP_Real real)
Definition: rational.cpp:1546
SCIP_Bool SCIPrationalIsEQ(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
Definition: rational.cpp:1404
void SCIPrationalDiffProd(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
Definition: rational.cpp:1239
void SCIPrationalMultReal(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_Real op2)
Definition: rational.cpp:1097
void SCIPrationalComputeApproximation(SCIP_RATIONAL *res, SCIP_RATIONAL *src, SCIP_Longint maxdenom, int forcegreater)
Definition: rational.cpp:2464
void SCIPrationalFreeBufferArray(BMS_BUFMEM *mem, SCIP_RATIONAL ***ratbufarray, int size)
Definition: rational.cpp:518
SCIP_Bool SCIPrationalIsLE(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
Definition: rational.cpp:1521
int SCIProwGetNNonz(SCIP_ROW *row)
Definition: lp.c:17607
SCIP_COL ** SCIProwGetCols(SCIP_ROW *row)
Definition: lp.c:17632
SCIP_RETCODE SCIPprintRow(SCIP *scip, SCIP_ROW *row, FILE *file)
Definition: scip_lp.c:2176
const char * SCIProwGetName(SCIP_ROW *row)
Definition: lp.c:17745
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 * SCIProwGetVals(SCIP_ROW *row)
Definition: lp.c:17642
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition: var.c:23683
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:23386
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:24142
SCIP_VARSTATUS SCIPvarGetStatusExact(SCIP_VAR *var)
Definition: var.c:23396
SCIP_COLEXACT * SCIPvarGetColExact(SCIP_VAR *var)
Definition: var.c:23694
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:23662
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:23267
SCIP_RATIONAL * SCIPvarGetUbLocalExact(SCIP_VAR *var)
Definition: var.c:24278
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:23490
SCIP_RATIONAL * SCIPvarGetLbGlobalExact(SCIP_VAR *var)
Definition: var.c:24130
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:24120
SCIP_RATIONAL * SCIPvarGetLbLocalExact(SCIP_VAR *var)
Definition: var.c:24244
SCIP_RATIONAL * SCIPvarGetObjExact(SCIP_VAR *var)
Definition: var.c:23910
SCIP_RATIONAL * SCIPvarGetUbGlobalExact(SCIP_VAR *var)
Definition: var.c:24152
void SCIPsortPtrPtrInt(void **ptrarray1, void **ptrarray2, int *intarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), int len)
void SCIPsortIntIntPtrPtrInterval(int *intarray1, int *intarray2, void **ptrarray, void **ptrarray2, SCIP_INTERVAL *intervalarray, int len)
interval arithmetics for provable bounds
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 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
void SCIProwRecalcNorms(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6393
void SCIProwPrint(SCIP_ROW *row, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: lp.c:5514
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 SCIProwChgRhs(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_Real rhs)
Definition: lp.c:5914
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
int SCIPlpGetNRows(SCIP_LP *lp)
Definition: lp.c:18026
SCIP_RETCODE SCIProwRelease(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:5567
internal methods for LP management
static void rowExactSortLP(SCIP_ROWEXACT *row)
Definition: lpexact.c:360
SCIP_Bool SCIPlpExactProjectShiftPossible(SCIP_LPEXACT *lpexact)
Definition: lpexact.c:3909
void SCIProwExactRecalcLPActivity(SCIP_ROWEXACT *rowexact, SCIP_STAT *stat)
Definition: lpexact.c:5891
SCIP_RETCODE SCIProwExactGetSolFeasibility(SCIP_ROWEXACT *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol, SCIP_RATIONAL *result)
Definition: lpexact.c:5446
SCIP_RETCODE SCIPlpExactShrinkRows(SCIP_LPEXACT *lpexact, BMS_BLKMEM *blkmem, SCIP_SET *set, int newnrows)
Definition: lpexact.c:7503
void SCIPlpExactOverwriteFpDualSol(SCIP_LPEXACT *lpexact, SCIP_Bool dualfarkas)
Definition: lpexact.c:8449
SCIP_Bool SCIProwExactIsModifiable(SCIP_ROWEXACT *row)
Definition: lpexact.c:5046
static SCIP_RETCODE lpExactSetObjlim(SCIP_LPEXACT *lp, SCIP_SET *set, SCIP_Real objlim, SCIP_Bool *success)
Definition: lpexact.c:2545
static SCIP_RETCODE rowExactCreateFromRowLimitEncodingLength(SCIP_ROW *row, SCIP_ROWEXACT *rowexact, SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_EVENTQUEUE *eventqueue, SCIP_LPEXACT *lpexact)
Definition: lpexact.c:3255
SCIP_RETCODE SCIPlpExactFreeState(SCIP_LPEXACT *lpexact, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpexact.c:8160
SCIP_RETCODE SCIPlpExactReset(SCIP_LPEXACT *lpexact, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue)
Definition: lpexact.c:7550
void SCIPlpExactForceExactSolve(SCIP_LPEXACT *lpexact, SCIP_SET *set)
Definition: lpexact.c:7598
SCIP_RETCODE SCIPlpExactGetSol(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible, SCIP_Bool overwritefplp)
Definition: lpexact.c:6853
static SCIP_RETCODE colExactSwapCoefs(SCIP_COLEXACT *col, BMS_BUFMEM *buffer, int pos1, int pos2)
Definition: lpexact.c:809
SCIP_RETCODE SCIPlpExactLink(SCIP_LPEXACT *lpexact, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
Definition: lpexact.c:3711
static SCIP_RETCODE lpExactFlushAndSolve(SCIP_LPEXACT *lpexact, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_EVENTQUEUE *eventqueue, int harditlim, SCIP_Bool fromscratch, SCIP_Bool *lperror)
Definition: lpexact.c:4287
static SCIP_RETCODE ensureRowexsSize(SCIP_LPEXACT *lpexact, SCIP_SET *set, int num)
Definition: lpexact.c:270
SCIP_COLEXACT ** SCIProwExactGetCols(SCIP_ROWEXACT *row)
Definition: lpexact.c:5026
SCIP_RETCODE SCIPlpExactSetState(SCIP_LPEXACT *lpexact, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LPISTATE *lpistate, SCIP_Bool wasprimfeas, SCIP_Bool wasprimchecked, SCIP_Bool wasdualfeas, SCIP_Bool wasdualchecked)
Definition: lpexact.c:8118
SCIP_RETCODE SCIProwExactFree(SCIP_ROWEXACT **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LPEXACT *lpexact)
Definition: lpexact.c:5610
static SCIP_RETCODE insertColChgcols(SCIP_COLEXACT *col, SCIP_SET *set, SCIP_LPEXACT *lp)
Definition: lpexact.c:1005
static SCIP_RETCODE colExactUpdateDelLP(SCIP_COLEXACT *col, SCIP_SET *set)
Definition: lpexact.c:1669
SCIP_RETCODE SCIPlpExactSolveAndEval(SCIP_LPEXACT *lpexact, SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_PROB *prob, SCIP_Longint itlim, SCIP_Bool *lperror, SCIP_Bool usefarkas)
Definition: lpexact.c:4477
SCIP_RATIONAL * SCIProwExactGetRhs(SCIP_ROWEXACT *row)
Definition: lpexact.c:6266
static SCIP_RETCODE colExactRestoreSolVals(SCIP_COLEXACT *colexact, BMS_BLKMEM *blkmem, SCIP_Longint validlp, SCIP_Bool freebuffer)
Definition: lpexact.c:7685
SCIP_RETCODE SCIPlpExactUpdateDelVar(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_VAR *var)
Definition: lpexact.c:6634
static int rowExactSearchCoefPart(SCIP_ROWEXACT *row, const SCIP_COLEXACT *col, int minpos, int maxpos)
Definition: lpexact.c:630
static SCIP_RETCODE ensureLpiExactcolsSize(SCIP_LPEXACT *lp, SCIP_SET *set, int num)
Definition: lpexact.c:509
SCIP_DECL_SORTPTRCOMP(SCIProwExactComp)
Definition: lpexact.c:77
static void rowExactMerge(SCIP_ROWEXACT *row, SCIP_SET *set)
Definition: lpexact.c:5773
SCIP_RETCODE SCIPcolExactDelCoef(SCIP_COLEXACT *col, SCIP_SET *set, SCIP_LPEXACT *lpexact, SCIP_ROWEXACT *row)
Definition: lpexact.c:2852
#define MAXNUMTROUBLELPMSGS
Definition: lpexact.c:4224
SCIP_RETCODE SCIPlpExactDelRowset(SCIP_LPEXACT *lpexact, BMS_BLKMEM *blkmem, SCIP_SET *set, int *rowdstat)
Definition: lpexact.c:2643
SCIP_RATIONAL * SCIProwExactGetLPActivity(SCIP_ROWEXACT *row, SCIP_STAT *stat, SCIP_LPEXACT *lpexact)
Definition: lpexact.c:5713
static void coefChangedExact(SCIP_ROWEXACT *row, SCIP_COLEXACT *col, SCIP_LPEXACT *lp)
Definition: lpexact.c:726
static SCIP_RETCODE rowExactRestoreSolVals(SCIP_ROWEXACT *rowexact, BMS_BLKMEM *blkmem, SCIP_Longint validlp, SCIP_Bool freebuffer, SCIP_Bool infeasible)
Definition: lpexact.c:7789
static SCIP_RETCODE lpExactRestoreSolVals(SCIP_LPEXACT *lpexact, BMS_BLKMEM *blkmem)
Definition: lpexact.c:7887
void SCIProwExactUnlock(SCIP_ROWEXACT *row)
Definition: lpexact.c:7957
static SCIP_RETCODE lpExactSetRealpar(SCIP_LPEXACT *lp, SCIP_LPPARAM lpparam, SCIP_Real value, SCIP_Bool *success)
Definition: lpexact.c:2488
static void getObjvalDeltaUbExact(SCIP_RATIONAL *obj, SCIP_RATIONAL *oldub, SCIP_RATIONAL *newub, SCIP_RATIONAL *deltaval, int *deltainf)
Definition: lpexact.c:6331
static SCIP_RETCODE rowExactSwapCoefs(SCIP_ROWEXACT *row, BMS_BUFMEM *buffer, int pos1, int pos2)
Definition: lpexact.c:915
static SCIP_RETCODE lpExactFlushAddRows(SCIP_LPEXACT *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
Definition: lpexact.c:2013
SCIP_RETCODE SCIProwExactGetLPFeasibility(SCIP_ROWEXACT *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LPEXACT *lpexact, SCIP_RATIONAL *result)
Definition: lpexact.c:5655
SCIP_Bool SCIPlpExactIsSynced(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_MESSAGEHDLR *msg)
Definition: lpexact.c:3920
SCIP_RETCODE SCIPlpExactGetState(SCIP_LPEXACT *lpexact, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpexact.c:8094
static SCIP_RETCODE lpExactFlushChgCols(SCIP_LPEXACT *lp, SCIP_SET *set)
Definition: lpexact.c:2146
SCIP_RETCODE SCIPlpExactGetPrimalRay(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_RATIONAL **ray)
Definition: lpexact.c:7137
void SCIProwExactPrint(SCIP_ROWEXACT *row, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: lpexact.c:4953
static SCIP_RETCODE lpExactFlushAddCols(SCIP_LPEXACT *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
Definition: lpexact.c:1810
SCIP_RETCODE SCIPcolExactAddCoef(SCIP_COLEXACT *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LPEXACT *lpexact, SCIP_ROWEXACT *row, SCIP_RATIONAL *val)
Definition: lpexact.c:2834
SCIP_RETCODE SCIPlpExactUpdateVarColumn(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_VAR *var)
Definition: lpexact.c:6663
static void markRowexDeleted(SCIP_ROWEXACT *row)
Definition: lpexact.c:1952
SCIP_RETCODE SCIPlpExactStartDive(SCIP_LPEXACT *lpexact, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat)
Definition: lpexact.c:8177
SCIP_Bool SCIProwExactIsInLP(SCIP_ROWEXACT *row)
Definition: lpexact.c:5036
static void colExactSortLP(SCIP_COLEXACT *col)
Definition: lpexact.c:293
SCIP_RETCODE SCIProwExactIncCoef(SCIP_ROWEXACT *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LPEXACT *lpexact, SCIP_COLEXACT *col, SCIP_RATIONAL *incval)
Definition: lpexact.c:5321
SCIP_RETCODE SCIPlpExactSyncLPs(SCIP_LPEXACT *lpexact, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: lpexact.c:8474
SCIP_RETCODE SCIProwExactEnsureSize(SCIP_ROWEXACT *row, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
Definition: lpexact.c:6062
SCIP_RETCODE SCIPlpExactUpdateVarLoose(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_VAR *var)
Definition: lpexact.c:6718
SCIP_ROW * SCIProwExactGetRow(SCIP_ROWEXACT *row)
Definition: lpexact.c:5069
SCIP_RETCODE SCIProwExactAddCoef(SCIP_ROWEXACT *rowexact, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LPEXACT *lpexact, SCIP_COLEXACT *colexact, SCIP_RATIONAL *val)
Definition: lpexact.c:5200
static void markColexDeleted(SCIP_COLEXACT *col)
Definition: lpexact.c:1749
void SCIProwExactCapture(SCIP_ROWEXACT *row)
Definition: lpexact.c:4940
SCIP_Bool SCIProwHasExRow(SCIP_LPEXACT *lpexact, SCIP_ROW *row)
Definition: lpexact.c:5057
static SCIP_RETCODE colExactUpdateAddLP(SCIP_COLEXACT *col, SCIP_SET *set)
Definition: lpexact.c:1592
static SCIP_RETCODE lpExactFlushDelRows(SCIP_LPEXACT *lp, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: lpexact.c:1965
static SCIP_RETCODE rowExactAddCoef(SCIP_ROWEXACT *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LPEXACT *lp, SCIP_COLEXACT *col, SCIP_RATIONAL *val, int linkpos)
Definition: lpexact.c:1235
static SCIP_RETCODE rowExactLink(SCIP_ROWEXACT *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LPEXACT *lp)
Definition: lpexact.c:1517
SCIP_Bool SCIProwExactHasFpRelax(SCIP_ROWEXACT *row)
Definition: lpexact.c:5089
SCIP_RETCODE SCIPcolExactIncCoef(SCIP_COLEXACT *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LPEXACT *lpexact, SCIP_ROWEXACT *row, SCIP_RATIONAL *incval)
Definition: lpexact.c:2945
SCIP_RETCODE SCIPlpExactUpdateAddVar(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_VAR *var)
Definition: lpexact.c:6603
static SCIP_RETCODE SCIPlpExactProjectShiftFreeLPIExact(SCIP_LPIEXACT **lpiexact)
Definition: lpexact.c:3822
static SCIP_RETCODE rowExactStoreSolVals(SCIP_ROWEXACT *rowexact, BMS_BLKMEM *blkmem, SCIP_Bool infeasible)
Definition: lpexact.c:7732
static SCIP_RETCODE lpExactSetIntpar(SCIP_LPEXACT *lp, SCIP_LPPARAM lpparam, int value, SCIP_Bool *success)
Definition: lpexact.c:2515
static SCIP_Bool colExactInSync(SCIP_COLEXACT *colexact, SCIP_SET *set)
Definition: lpexact.c:176
static void rowExactSortNonLP(SCIP_ROWEXACT *row)
Definition: lpexact.c:394
SCIP_RETCODE SCIPcolExactChgCoef(SCIP_COLEXACT *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LPEXACT *lpexact, SCIP_ROWEXACT *row, SCIP_RATIONAL *val)
Definition: lpexact.c:2894
static SCIP_RETCODE lpExactFlushDelCols(SCIP_LPEXACT *lp)
Definition: lpexact.c:1763
#define lpCutoffDisabled(set)
Definition: lpexact.c:4175
static SCIP_RETCODE lpExactFlushChgRows(SCIP_LPEXACT *lp, SCIP_SET *set)
Definition: lpexact.c:2282
SCIP_RETCODE SCIProwExactCreate(SCIP_ROWEXACT **row, SCIP_ROW *fprow, SCIP_ROW *fprowrhs, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_LPEXACT *lpexact, int len, SCIP_COLEXACT **cols, SCIP_RATIONAL **vals, SCIP_RATIONAL *lhs, SCIP_RATIONAL *rhs, SCIP_Bool isfprelaxable)
Definition: lpexact.c:3138
void SCIProwExactDelaySort(SCIP_ROWEXACT *rowexact)
Definition: lpexact.c:5867
SCIP_RETCODE SCIProwExactRelease(SCIP_ROWEXACT **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LPEXACT *lpexact)
Definition: lpexact.c:5583
SCIP_RETCODE SCIProwExactGetPseudoFeasibility(SCIP_ROWEXACT *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_RATIONAL *result)
Definition: lpexact.c:5684
SCIP_RATIONAL * SCIProwExactGetConstant(SCIP_ROWEXACT *row)
Definition: lpexact.c:6277
static void lpExactNumericalTroubleMessage(SCIP_MESSAGEHDLR *messagehdlr, SCIP_SET *set, SCIP_STAT *stat, SCIP_VERBLEVEL verblevel, const char *formatstr,...)
Definition: lpexact.c:4233
void SCIPlpExactDecNLoosevars(SCIP_LPEXACT *lpexact)
Definition: lpexact.c:6770
SCIP_RETCODE SCIPlpExactAddRow(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_ROWEXACT *rowexact)
Definition: lpexact.c:4133
static SCIP_RETCODE SCIPlpPsdataCreate(SCIP_LPEXACT *lpexact, SCIP_SET *set, BMS_BLKMEM *blkmem)
Definition: lpexact.c:3775
static SCIP_RETCODE rowExactChgCoefPos(SCIP_ROWEXACT *row, SCIP_SET *set, SCIP_LPEXACT *lp, int pos, SCIP_RATIONAL *val)
Definition: lpexact.c:1421
SCIP_VAR * SCIPcolExactGetVar(SCIP_COLEXACT *col)
Definition: lpexact.c:6052
SCIP_RATIONAL * SCIPcolExactGetPrimsol(SCIP_COLEXACT *col)
Definition: lpexact.c:6039
SCIP_RETCODE SCIPlpExactGetIterations(SCIP_LPEXACT *lpexact, int *iterations)
Definition: lpexact.c:7398
static void markRowExactDeleted(SCIP_ROWEXACT *row)
Definition: lpexact.c:2628
static SCIP_RETCODE ensureChgcolsSize(SCIP_LPEXACT *lp, SCIP_SET *set, int num)
Definition: lpexact.c:486
SCIP_COLEXACT * SCIPcolGetColExact(SCIP_COL *col)
Definition: lpexact.c:5099
SCIP_RATIONAL * SCIProwExactGetLhs(SCIP_ROWEXACT *row)
Definition: lpexact.c:6255
void SCIProwExactForceSort(SCIP_ROWEXACT *rowexact, SCIP_SET *set)
Definition: lpexact.c:5878
int SCIProwExactGetIndex(SCIP_ROWEXACT *row)
Definition: lpexact.c:4996
void SCIPlpExactGetPseudoObjval(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_RATIONAL *res)
Definition: lpexact.c:7438
static SCIP_RETCODE ensureChgrowsSizeExact(SCIP_LPEXACT *lpexact, SCIP_SET *set, int num)
Definition: lpexact.c:7973
static SCIP_RETCODE getObjvalDeltaObjExact(SCIP_SET *set, SCIP_RATIONAL *oldobj, SCIP_RATIONAL *newobj, SCIP_RATIONAL *lb, SCIP_RATIONAL *ub, SCIP_RATIONAL *deltaval, int *deltainf)
Definition: lpexact.c:6100
static SCIP_RETCODE colExactChgCoefPos(SCIP_COLEXACT *col, SCIP_SET *set, SCIP_LPEXACT *lp, int pos, SCIP_RATIONAL *val)
Definition: lpexact.c:1200
static SCIP_RETCODE rowExactSideChanged(SCIP_ROWEXACT *rowexact, SCIP_SET *set, SCIP_LPEXACT *lpexact, SCIP_SIDETYPE sidetype)
Definition: lpexact.c:7997
SCIP_RETCODE SCIPlpExactUpdateVarObj(SCIP_SET *set, SCIP_LPEXACT *lpexact, SCIP_VAR *var, SCIP_RATIONAL *oldobj, SCIP_RATIONAL *newobj)
Definition: lpexact.c:6422
SCIP_RETCODE SCIProwExactDelCoef(SCIP_ROWEXACT *row, SCIP_SET *set, SCIP_LPEXACT *lpexact, SCIP_COLEXACT *col)
Definition: lpexact.c:5225
int SCIPlpExactGetNRows(SCIP_LPEXACT *lpexact)
Definition: lpexact.c:6788
SCIP_RETCODE SCIPlpExactClear(SCIP_LPEXACT *lpexact, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: lpexact.c:7581
static SCIP_RETCODE rowExactUpdateDelLP(SCIP_ROWEXACT *row, SCIP_SET *set)
Definition: lpexact.c:1707
static SCIP_RETCODE lpExactSetIterationLimit(SCIP_LPEXACT *lp, int itlim)
Definition: lpexact.c:2594
static void getObjvalDeltaLbExact(SCIP_RATIONAL *obj, SCIP_RATIONAL *oldlb, SCIP_RATIONAL *newlb, SCIP_RATIONAL *deltaval, int *deltainf)
Definition: lpexact.c:6289
static int rowExactSearchCoef(SCIP_ROWEXACT *row, const SCIP_COLEXACT *col)
Definition: lpexact.c:669
void SCIProwExactLock(SCIP_ROWEXACT *row)
Definition: lpexact.c:7943
SCIP_Bool SCIProwExactGetSolActivityWithErrorbound(SCIP_ROWEXACT *rowexact, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol, SCIP_Real *activity, SCIP_Real *errorbound)
Definition: lpexact.c:5475
SCIP_Bool SCIPlpExactDiving(SCIP_LPEXACT *lpexact)
Definition: lpexact.c:8423
SCIP_RATIONAL * SCIPcolExactGetUb(SCIP_COLEXACT *col)
Definition: lpexact.c:6016
SCIP_RETCODE SCIProwExactCreateFromRow(SCIP_ROW *fprow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_PROB *prob, SCIP_LPEXACT *lpexact)
Definition: lpexact.c:3373
SCIP_RETCODE SCIPlpExactGetDualfarkas(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *valid, SCIP_Bool overwritefplp)
Definition: lpexact.c:7198
SCIP_RETCODE SCIPlpExactEndDive(SCIP_LPEXACT *lpexact, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_VAR **vars, int nvars)
Definition: lpexact.c:8280
static SCIP_RETCODE colExactEnsureSize(SCIP_COLEXACT *col, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
Definition: lpexact.c:427
SCIP_RETCODE SCIPlpExactShrinkCols(SCIP_LPEXACT *lpexact, SCIP_SET *set, int newncols)
Definition: lpexact.c:7455
SCIP_RETCODE SCIPlpExactAddCol(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_COLEXACT *col)
Definition: lpexact.c:4089
static SCIP_RETCODE rowExactUnlink(SCIP_ROWEXACT *row, SCIP_SET *set, SCIP_LPEXACT *lp)
Definition: lpexact.c:1560
SCIP_RETCODE SCIProwExactGetSolActivity(SCIP_ROWEXACT *rowexact, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol, SCIP_Bool useexact, SCIP_RATIONAL *result)
Definition: lpexact.c:5529
SCIP_RETCODE SCIPlpExactGetUnboundedSol(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *primalfeasible, SCIP_Bool *rayfeasible)
Definition: lpexact.c:7124
static void colExactMoveCoef(SCIP_COLEXACT *col, int oldpos, int newpos)
Definition: lpexact.c:772
SCIP_RETCODE SCIPlpExactSetCutoffbound(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_Real cutoffbound)
Definition: lpexact.c:4178
SCIP_LPSOLSTAT SCIPlpExactGetSolstat(SCIP_LPEXACT *lpexact)
Definition: lpexact.c:8084
SCIP_RETCODE SCIPlpExactUpdateVarUb(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_VAR *var, SCIP_RATIONAL *oldub, SCIP_RATIONAL *newub)
Definition: lpexact.c:6568
SCIP_RETCODE SCIPcolExactCalcFarkasRedcostCoef(SCIP_COLEXACT *col, SCIP_SET *set, SCIP_RATIONAL *result, SCIP_RATIONAL **dual, SCIP_Bool usefarkas)
Definition: lpexact.c:5111
static SCIP_RETCODE colExactDelCoefPos(SCIP_COLEXACT *col, SCIP_SET *set, SCIP_LPEXACT *lpexact, int pos)
Definition: lpexact.c:1154
SCIP_ROW * SCIProwExactGetRowRhs(SCIP_ROWEXACT *row)
Definition: lpexact.c:5079
static SCIP_RETCODE lpExactStoreSolVals(SCIP_LPEXACT *lpexact, SCIP_STAT *stat, BMS_BLKMEM *blkmem)
Definition: lpexact.c:7838
SCIP_Bool SCIPlpExactBoundShiftUseful(SCIP_LPEXACT *lpexact)
Definition: lpexact.c:3899
void SCIPlpExactAllowExactSolve(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_Bool allowexact)
Definition: lpexact.c:7630
SCIP_RATIONAL * SCIProwExactGetPseudoActivity(SCIP_ROWEXACT *row, SCIP_STAT *stat)
Definition: lpexact.c:5734
SCIP_RETCODE SCIPcolExactFree(SCIP_COLEXACT **col, BMS_BLKMEM *blkmem)
Definition: lpexact.c:2754
void SCIPcolExactPrint(SCIP_COLEXACT *col, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: lpexact.c:2796
SCIP_RETCODE SCIPlpExactUpdateVarLbGlobal(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_VAR *var, SCIP_RATIONAL *oldlb, SCIP_RATIONAL *newlb)
Definition: lpexact.c:6469
SCIP_RETCODE SCIPcolExactChgObj(SCIP_COLEXACT *col, SCIP_SET *set, SCIP_LPEXACT *lpexact, SCIP_RATIONAL *newobj)
Definition: lpexact.c:3001
SCIP_RETCODE SCIPlpExactUpdateVarLb(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_VAR *var, SCIP_RATIONAL *oldlb, SCIP_RATIONAL *newlb)
Definition: lpexact.c:6501
SCIP_RETCODE SCIProwExactGenerateFpRows(BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_LPEXACT *lpexact, SCIP_PROB *prob, SCIP_ROWEXACT *row, SCIP_ROW *rowlhs, SCIP_ROW *rowrhs, SCIP_Bool *onerowrelax, SCIP_Bool *hasfprelax)
Definition: lpexact.c:3454
SCIP_RETCODE SCIPcolExactChgUb(SCIP_COLEXACT *col, SCIP_SET *set, SCIP_LPEXACT *lpexact, SCIP_RATIONAL *newub)
Definition: lpexact.c:3093
static int colExactSearchCoef(SCIP_COLEXACT *col, const SCIP_ROWEXACT *row)
Definition: lpexact.c:591
static SCIP_RETCODE SCIPlpExactProjectShiftFree(SCIP_LPEXACT *lpexact, SCIP_SET *set, BMS_BLKMEM *blkmem)
Definition: lpexact.c:3846
static SCIP_RETCODE rowExactDelCoefPos(SCIP_ROWEXACT *row, SCIP_SET *set, SCIP_LPEXACT *lp, int pos)
Definition: lpexact.c:1370
SCIP_RETCODE SCIPlpExactCreate(SCIP_LPEXACT **lpexact, BMS_BLKMEM *blkmem, SCIP_LP *fplp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, const char *name)
Definition: lpexact.c:3933
static SCIP_RATIONAL * getFiniteLooseObjvalExact(SCIP_LPEXACT *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lpexact.c:2390
SCIP_RATIONAL ** SCIProwExactGetVals(SCIP_ROWEXACT *row)
Definition: lpexact.c:5016
SCIP_RETCODE SCIProwExactAddConstant(SCIP_ROWEXACT *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LPEXACT *lpexact, SCIP_RATIONAL *addval)
Definition: lpexact.c:5416
static SCIP_Bool lpExactInSync(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_MESSAGEHDLR *msg)
Definition: lpexact.c:237
static void lpExactUpdateObjval(SCIP_LPEXACT *lpexact, SCIP_VAR *var, SCIP_RATIONAL *deltavalex, int deltainf, SCIP_Bool local, SCIP_Bool loose, SCIP_Bool global)
Definition: lpexact.c:6373
static void colExactSortNonLP(SCIP_COLEXACT *col)
Definition: lpexact.c:326
SCIP_RATIONAL * SCIPcolExactGetBestBound(SCIP_COLEXACT *col)
Definition: lpexact.c:6026
static SCIP_RETCODE rowExactUpdateAddLP(SCIP_ROWEXACT *row, SCIP_SET *set)
Definition: lpexact.c:1631
static SCIP_Bool rowExactInSync(SCIP_ROWEXACT *rowexact, SCIP_SET *set, SCIP_MESSAGEHDLR *msg)
Definition: lpexact.c:203
void SCIPlpExactGetObjval(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_RATIONAL *res)
Definition: lpexact.c:7416
SCIP_RETCODE SCIPcolExactCreate(SCIP_COLEXACT **col, SCIP_COL *fpcol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var, int len, SCIP_ROWEXACT **rows, SCIP_RATIONAL **vals, SCIP_Bool removable)
Definition: lpexact.c:2410
static SCIP_RETCODE ensureColexsSize(SCIP_LPEXACT *lp, SCIP_SET *set, int num)
Definition: lpexact.c:463
SCIP_RETCODE SCIProwExactChgRhs(SCIP_ROWEXACT *rowexact, SCIP_SET *set, SCIP_LPEXACT *lpexact, SCIP_RATIONAL *rhs)
Definition: lpexact.c:8063
SCIP_RATIONAL * SCIPcolExactGetLb(SCIP_COLEXACT *col)
Definition: lpexact.c:6006
static int colExactSearchCoefPart(SCIP_COLEXACT *col, const SCIP_ROWEXACT *row, int minpos, int maxpos)
Definition: lpexact.c:555
SCIP_RETCODE SCIProwExactChgCoef(SCIP_ROWEXACT *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LPEXACT *lpexact, SCIP_COLEXACT *col, SCIP_RATIONAL *val)
Definition: lpexact.c:5269
static SCIP_RETCODE colExactStoreSolVals(SCIP_COLEXACT *colexact, BMS_BLKMEM *blkmem)
Definition: lpexact.c:7648
static SCIP_RETCODE colExactLink(SCIP_COLEXACT *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LPEXACT *lp)
Definition: lpexact.c:1473
void SCIProwExactSort(SCIP_ROWEXACT *row)
Definition: lpexact.c:5755
SCIP_RETCODE SCIPlpExactWrite(SCIP_LPEXACT *lpexact, const char *fname)
Definition: lpexact.c:8434
SCIP_RETCODE SCIPlpExactFree(SCIP_LPEXACT **lpexact, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: lpexact.c:4039
SCIP_RATIONAL * SCIPcolExactGetObj(SCIP_COLEXACT *col)
Definition: lpexact.c:5996
SCIP_RETCODE SCIPlpExactFlush(SCIP_LPEXACT *lpexact, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
Definition: lpexact.c:3651
static SCIP_RETCODE ensureLpirowexactsSize(SCIP_LPEXACT *lp, SCIP_SET *set, int num)
Definition: lpexact.c:532
int SCIProwExactGetNNonz(SCIP_ROWEXACT *row)
Definition: lpexact.c:5006
static SCIP_RETCODE colExactAddCoef(SCIP_COLEXACT *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LPEXACT *lp, SCIP_ROWEXACT *row, SCIP_RATIONAL *val, int linkpos)
Definition: lpexact.c:1026
void SCIProwExactRecalcPseudoActivity(SCIP_ROWEXACT *rowexact, SCIP_STAT *stat)
Definition: lpexact.c:5960
SCIP_RETCODE SCIProwExactChgLhs(SCIP_ROWEXACT *rowexact, SCIP_SET *set, SCIP_LPEXACT *lpexact, SCIP_RATIONAL *lhs)
Definition: lpexact.c:8042
SCIP_RETCODE SCIProwExactChgConstant(SCIP_ROWEXACT *row, SCIP_STAT *stat, SCIP_LPEXACT *lpexact, SCIP_RATIONAL *constant)
Definition: lpexact.c:5385
static void rowExactMoveCoef(SCIP_ROWEXACT *row, int oldpos, int newpos)
Definition: lpexact.c:877
void SCIPlpExactForceSafeBound(SCIP_LPEXACT *lpexact, SCIP_SET *set)
Definition: lpexact.c:7614
#define checkLinks(lp)
Definition: lpexact.c:170
SCIP_RETCODE SCIPcolExactChgLb(SCIP_COLEXACT *col, SCIP_SET *set, SCIP_LPEXACT *lpexact, SCIP_RATIONAL *newlb)
Definition: lpexact.c:3048
SCIP_RETCODE SCIPlpExactUpdateVarUbGlobal(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_VAR *var, SCIP_RATIONAL *oldub, SCIP_RATIONAL *newub)
Definition: lpexact.c:6536
internal methods for exact LP management
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 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
internal miscellaneous methods
internal methods for storing and manipulating the main problem
public methods for managing constraints
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
methods for sorting joint arrays of various types
public methods for branch and bound tree
public methods for problem variables
wrapper for rational number arithmetic
public methods for the LP relaxation, rows and columns
public methods for the LP relaxation, rows and columns
public methods for message handling
internal methods for storing separated exact cuts
SCIP_RETCODE SCIPsetGetCharParam(SCIP_SET *set, const char *name, char *value)
Definition: set.c:3424
SCIP_RETCODE SCIPsetSetCharParam(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, const char *name, char value)
Definition: set.c:3669
SCIP_Real SCIPsetInfinity(SCIP_SET *set)
Definition: set.c:6380
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6515
int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
Definition: set.c:6080
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
void SCIPsolGetValExact(SCIP_RATIONAL *res, SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var)
Definition: sol.c:2039
SCIP_Real SCIPsolGetVal(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var)
Definition: sol.c:1908
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
unsigned int basisstatus
SCIP_RATIONAL * redcost
SCIP_RATIONAL * primsol
SCIP_RATIONAL * primsol
SCIP_COL * fpcol
SCIP_RATIONAL * farkascoef
SCIP_RATIONAL * flushedobj
unsigned int lbchanged
SCIP_ROWEXACT ** rows
unsigned int lprowssorted
SCIP_RATIONAL * obj
SCIP_RATIONAL ** vals
SCIP_RATIONAL * ub
unsigned int nonlprowssorted
unsigned int ubchanged
unsigned int coefchanged
unsigned int basisstatus
SCIP_Longint validredcostlp
SCIP_RATIONAL * redcost
SCIP_VAR * var
SCIP_RATIONAL * lb
unsigned int objchanged
SCIP_RATIONAL * flushedub
SCIP_RATIONAL * flushedlb
SCIP_Longint validfarkaslp
SCIP_COLEXACTSOLVALS * storedsolvals
SCIP_Real lb
Definition: struct_lp.h:140
SCIP_Real ub
Definition: struct_lp.h:141
int nlprows
Definition: struct_lp.h:172
unsigned int basisstatus
Definition: struct_lp.h:181
SCIP_Real redcost
Definition: struct_lp.h:151
SCIP_Real flushedobj
Definition: struct_lp.h:147
SCIP_Real farkascoef
Definition: struct_lp.h:152
SCIP_Longint validredcostlp
Definition: struct_lp.h:165
int lppos
Definition: struct_lp.h:174
SCIP_Real primsol
Definition: struct_lp.h:150
SCIP_Longint validfarkaslp
Definition: struct_lp.h:166
int lpipos
Definition: struct_lp.h:175
unsigned int integral
Definition: struct_lp.h:188
SCIP_Real obj
Definition: struct_lp.h:139
int index
Definition: struct_lp.h:169
SCIP_VAR * var
Definition: struct_lp.h:162
SCIP_Real sup
Definition: intervalarith.h:57
SCIP_Real inf
Definition: intervalarith.h:56
SCIP_LPSOLSTAT lpsolstat
SCIP_RATIONAL * lpobjval
SCIP_RATIONAL ** divechgsides
SCIP_SIDETYPE * divechgsidetypes
SCIP_Bool divelpwasprimfeas
SCIP_Bool divelpwasdualchecked
SCIP_ROWEXACT ** lpirows
SCIP_RATIONAL * glbpseudoobjval
SCIP_Bool primalfeasible
SCIP_PROJSHIFTDATA * projshiftdata
SCIP_ROWEXACT ** chgrows
SCIP_Bool solved
SCIP_RATIONAL * looseobjval
SCIP_Real lpiobjlim
SCIP_Longint divenolddomchgs
SCIP_LPEXACTSOLVALS * storedsolvals
SCIP_ROWEXACT ** divechgrows
SCIP_LPALGO lastlpalgo
SCIP_COLEXACT ** cols
SCIP_Bool dualchecked
SCIP_LPIEXACT * lpiexact
SCIP_COLEXACT ** lpicols
SCIP_LPSOLSTAT lpsolstat
SCIP_Bool flushdeletedrows
SCIP_ROWEXACT ** rows
SCIP_Bool boundshiftuseful
SCIP_Bool flushdeletedcols
SCIP_Bool divelpwasdualfeas
SCIP_COLEXACT ** chgcols
SCIP_Bool diving
SCIP_Bool solisbasic
SCIP_Real cutoffbound
SCIP_Bool flushed
SCIP_Bool divingobjchg
SCIP_LP * fplp
SCIP_Bool primalchecked
SCIP_Bool flushaddedcols
SCIP_Bool forcesafebound
SCIP_Bool dualfeasible
SCIP_Bool allowexactsolve
SCIP_RATIONAL * lpobjval
SCIP_Bool forceexactsolve
SCIP_Bool updateintegrality
SCIP_Bool divelpwasprimchecked
SCIP_Bool flushaddedrows
SCIP_RATIONAL * pseudoobjval
SCIP_LPISTATE * divelpistate
SCIP_ROW ** rows
Definition: struct_lp.h:308
SCIP_ROW ** lpirows
Definition: struct_lp.h:303
SCIP_Bool probing
Definition: struct_lp.h:384
SCIP_Bool primalfeasible
Definition: struct_lp.h:374
int ncols
Definition: struct_lp.h:334
SCIP_Real cutoffbound
Definition: struct_lp.h:289
SCIP_LPEXACT * lpexact
Definition: struct_lp.h:309
SCIP_Bool dualfeasible
Definition: struct_lp.h:376
int nrows
Definition: struct_lp.h:340
SCIP_Bool primalchecked
Definition: struct_lp.h:375
SCIP_Longint validsollp
Definition: struct_lp.h:317
SCIP_LPSOLSTAT lpsolstat
Definition: struct_lp.h:359
SCIP_Real lpobjval
Definition: struct_lp.h:276
SCIP_Bool solved
Definition: struct_lp.h:373
SCIP_Bool dualchecked
Definition: struct_lp.h:377
SCIP_Bool diving
Definition: struct_lp.h:386
SCIP_Bool hasprovedbound
Definition: struct_lp.h:409
SCIP_COL ** lpicols
Definition: struct_lp.h:302
SCIP_LPI * lpi
Definition: struct_lp.h:301
SCIP_Real lpiobjlim
Definition: struct_lp.h:291
SCIP_RATIONAL * activity
SCIP_RATIONAL * dualsol
unsigned int basisstatus
SCIP_INTERVAL constantreal
unsigned int coefchanged
SCIP_ROW * fprow
unsigned int rhschanged
unsigned int lpcolssorted
unsigned int modifiable
SCIP_RATIONAL ** vals
SCIP_Longint validactivitylp
unsigned int nlocks
unsigned int delaysort
unsigned int fprelaxable
SCIP_RATIONAL * flushedrhs
SCIP_RATIONAL * dualfarkas
SCIP_ROW * fprowrhs
SCIP_RATIONAL * flushedlhs
unsigned int lhschanged
SCIP_RATIONAL * lhs
unsigned int nonlpcolssorted
unsigned int removable
SCIP_COLEXACT ** cols
SCIP_RATIONAL * rhs
SCIP_ROWEXACTSOLVALS * storedsolvals
SCIP_RATIONAL * dualsol
SCIP_RATIONAL * pseudoactivity
unsigned int basisstatus
SCIP_RATIONAL * activity
SCIP_Real rhsreal
unsigned int integral
SCIP_Real lhsreal
SCIP_INTERVAL * valsinterval
SCIP_RATIONAL * constant
unsigned int basisstatus
Definition: struct_lp.h:255
int nlpcols
Definition: struct_lp.h:240
SCIP_Real rhs
Definition: struct_lp.h:208
int nunlinked
Definition: struct_lp.h:241
SCIP_Real dualfarkas
Definition: struct_lp.h:218
int lppos
Definition: struct_lp.h:243
int size
Definition: struct_lp.h:238
char * name
Definition: struct_lp.h:229
SCIP_Real * vals
Definition: struct_lp.h:232
SCIP_Longint validpsactivitydomchg
Definition: struct_lp.h:222
SCIP_Real lhs
Definition: struct_lp.h:207
int * linkpos
Definition: struct_lp.h:233
SCIP_COL ** cols
Definition: struct_lp.h:230
SCIP_ROWEXACT * rowexact
Definition: struct_lp.h:235
SCIP_Real constant
Definition: struct_lp.h:206
SCIP_Real activity
Definition: struct_lp.h:217
SCIP_Real pseudoactivity
Definition: struct_lp.h:219
SCIP_Real dualsol
Definition: struct_lp.h:216
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 len
Definition: struct_lp.h:239
SCIP_Real timefailexlpinf
Definition: struct_stat.h:166
SCIP_STATUS status
Definition: struct_stat.h:201
SCIP_Longint nnodes
Definition: struct_stat.h:84
SCIP_CLOCK * provedfeaslptime
Definition: struct_stat.h:180
int nclockskipsleft
Definition: struct_stat.h:311
SCIP_Longint nlps
Definition: struct_stat.h:207
SCIP_Longint domchgcount
Definition: struct_stat.h:116
SCIP_Longint lpcount
Definition: struct_stat.h:205
SCIP_Longint nnumtroublelpmsgs
Definition: struct_stat.h:225
SCIP_Longint nexlp
Definition: struct_stat.h:231
SCIP_Longint nexlpinf
Definition: struct_stat.h:229
SCIP_Real boundingerrorexlp
Definition: struct_stat.h:165
SCIP_CLOCK * provedinfeaslptime
Definition: struct_stat.h:181
SCIP_Real timefailexlp
Definition: struct_stat.h:167
SCIP_CLOCK * solvingtime
Definition: struct_stat.h:168
SCIP_COLEXACT * colexact
Definition: struct_var.h:255
SCIP_VARDATAEXACT * exactdata
Definition: struct_var.h:290
datastructures for storing cuts in a cut pool
datastructures for managing events
data structures for exact LP management
datastructures for storing and manipulating the main problem
datastructures for global SCIP settings
datastructures for problem statistics
datastructures for problem variables
Definition: heur_padm.c:135
@ SCIP_LPALGO_DUALSIMPLEX
Definition: type_lp.h:85
enum SCIP_LPSolStat SCIP_LPSOLSTAT
Definition: type_lp.h:52
@ SCIP_SIDETYPE_RIGHT
Definition: type_lp.h:66
@ SCIP_SIDETYPE_LEFT
Definition: type_lp.h:65
@ 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_SideType SCIP_SIDETYPE
Definition: type_lp.h:68
struct SCIP_ProjShiftData SCIP_PROJSHIFTDATA
Definition: type_lpexact.h:58
@ SCIP_PRICING_AUTO
Definition: type_lpi.h:79
enum SCIP_LPParam SCIP_LPPARAM
Definition: type_lpi.h:73
@ SCIP_LPPAR_LPINFO
Definition: type_lpi.h:55
@ SCIP_LPPAR_LPTILIM
Definition: type_lpi.h:61
@ SCIP_LPPAR_FROMSCRATCH
Definition: type_lpi.h:50
@ SCIP_LPPAR_LPITLIM
Definition: type_lpi.h:60
@ SCIP_LPPAR_OBJLIM
Definition: type_lpi.h:59
@ SCIP_BASESTAT_BASIC
Definition: type_lpi.h:92
@ SCIP_BASESTAT_ZERO
Definition: type_lpi.h:94
@ SCIP_OBJSEN_MINIMIZE
Definition: type_lpi.h:43
enum SCIP_VerbLevel SCIP_VERBLEVEL
Definition: type_message.h:64
@ SCIP_VERBLEVEL_NONE
Definition: type_message.h:57
@ SCIP_VERBLEVEL_HIGH
Definition: type_message.h:61
@ SCIP_VERBLEVEL_FULL
Definition: type_message.h:62
@ SCIP_R_ROUND_UPWARDS
Definition: type_rational.h:58
@ SCIP_R_ROUND_DOWNWARDS
Definition: type_rational.h:57
@ SCIP_R_ROUND_NEAREST
Definition: type_rational.h:59
@ SCIP_LPERROR
Definition: type_retcode.h:49
@ SCIP_INVALIDDATA
Definition: type_retcode.h:52
@ SCIP_PARAMETERUNKNOWN
Definition: type_retcode.h:55
@ SCIP_OKAY
Definition: type_retcode.h:42
@ SCIP_ERROR
Definition: type_retcode.h:43
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
@ SCIP_STATUS_TIMELIMIT
Definition: type_stat.h:54
@ SCIP_VARSTATUS_COLUMN
Definition: type_var.h:53
@ SCIP_VARSTATUS_LOOSE
Definition: type_var.h:52
SCIP_RETCODE SCIPvarAddToRow(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_PROB *prob, SCIP_LP *lp, SCIP_ROW *row, SCIP_Real val)
Definition: var.c:20035
SCIP_RETCODE SCIPvarAddToRowExact(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_PROB *prob, SCIP_LPEXACT *lpexact, SCIP_ROWEXACT *rowexact, SCIP_RATIONAL *val)
Definition: var.c:20135
internal methods for problem variables