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