Scippy

    SCIP

    Solving Constraint Integer Programs

    lp.c
    Go to the documentation of this file.
    1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    2/* */
    3/* This file is part of the program and library */
    4/* SCIP --- Solving Constraint Integer Programs */
    5/* */
    6/* Copyright (c) 2002-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 lp.c
    26 * @ingroup OTHER_CFILES
    27 * @brief LP management methods and data structures
    28 * @author Tobias Achterberg
    29 * @author Timo Berthold
    30 * @author Marc Pfetsch
    31 * @author Kati Wolter
    32 * @author Gerald Gamrath
    33 *
    34 * In LP management, we have to differ between the current LP and the SCIP_LP
    35 * stored in the LP solver. All LP methods affect the current LP only.
    36 * Before solving the current LP with the LP solver or setting an LP state,
    37 * the LP solvers data has to be updated to the current LP with a call to
    38 * lpFlush().
    39 */
    40
    41/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    42
    43#include "lpi/lpi.h"
    44#include "lpiexact/lpiexact.h"
    45#include "scip/clock.h"
    46#include "scip/certificate.h"
    47#include "scip/cons.h"
    48#include "scip/event.h"
    49#include "scip/intervalarith.h"
    50#include "scip/lp.h"
    52#include "scip/misc.h"
    53#include "scip/prob.h"
    54#include "scip/pub_lp.h"
    55#include "scip/pub_lpexact.h"
    56#include "scip/pub_message.h"
    57#include "scip/pub_misc.h"
    58#include "scip/pub_misc_sort.h"
    59#include "scip/pub_var.h"
    60#include "scip/set.h"
    61#include "scip/sol.h"
    62#include "scip/solve.h"
    63#include "scip/stat.h"
    64#include "scip/struct_scip.h"
    65#include "scip/struct_event.h"
    66#include "scip/struct_lp.h"
    67#include "scip/struct_lpexact.h"
    68#include "scip/struct_prob.h"
    69#include "scip/struct_set.h"
    70#include "scip/struct_stat.h"
    71#include "scip/struct_var.h"
    72#include "scip/var.h"
    73#include <string.h>
    74
    75
    76/* activate this to use the row activities as given by the LPI instead of recalculating
    77 * using the LP solver activity is potentially faster, but may not be consistent with the SCIP_ROW calculations
    78 * see also #2594 for more details on possible trouble
    79 */
    80/* #define SCIP_USE_LPSOLVER_ACTIVITY */
    81
    82/*
    83 * debug messages
    84 */
    85
    86#ifdef SCIP_DEBUG
    87/** method is to print in row in case SCIP_DEBUG is defined */
    88static
    89void debugRowPrint(
    90 SCIP_SET* set, /**< global SCIP settings */
    91 SCIP_ROW* row /**< LP row */
    92 )
    93{
    94 int i;
    95
    96 assert(row != NULL);
    97
    98 /* print row name */
    99 if( row->name != NULL && row->name[0] != '\0' )
    100 {
    101 SCIPsetDebugMsgPrint(set, "%s: ", row->name);
    102 }
    103
    104 /* print left hand side */
    105 SCIPsetDebugMsgPrint(set, "%.15g <= ", row->lhs);
    106
    107 /* print coefficients */
    108 if( row->len == 0 )
    109 {
    111 }
    112 for( i = 0; i < row->len; ++i )
    113 {
    114 assert(row->cols[i] != NULL);
    115 assert(row->cols[i]->var != NULL);
    116 assert(SCIPvarGetName(row->cols[i]->var) != NULL);
    117 assert(SCIPvarGetStatus(row->cols[i]->var) == SCIP_VARSTATUS_COLUMN);
    118 SCIPsetDebugMsgPrint(set, "%+.15g<%s> ", row->vals[i], SCIPvarGetName(row->cols[i]->var));
    119 }
    120
    121 /* print constant */
    123 {
    124 SCIPsetDebugMsgPrint(set, "%+.15g ", row->constant);
    125 }
    126
    127 /* print right hand side */
    128 SCIPsetDebugMsgPrint(set, "<= %.15g\n", row->rhs);
    129}
    130#else
    131#define debugRowPrint(x,y) /**/
    132#endif
    133
    134#ifdef SCIP_DEBUG
    135/** method to output column if SCIP_DEBUG is define */
    136static
    137void debugColPrint(
    138 SCIP_SET* set, /**< global SCIP settings */
    139 SCIP_COL* col /**< LP column */
    140 )
    141{
    142 int r;
    143
    144 assert(col != NULL);
    145 assert(col->var != NULL);
    146
    147 /* print bounds */
    148 SCIPsetDebugMsgPrint(set, "(obj: %.15g) [%.15g,%.15g], ", col->obj, col->lb, col->ub);
    149
    150 /* print coefficients */
    151 if( col->len == 0 )
    152 {
    153 SCIPsetDebugMsgPrint(set, "<empty>");
    154 }
    155 for( r = 0; r < col->len; ++r )
    156 {
    157 assert(col->rows[r] != NULL);
    158 assert(col->rows[r]->name != NULL);
    159 SCIPsetDebugMsgPrint(set, "%+.15g<%s> ", col->vals[r], col->rows[r]->name);
    160 }
    162}
    163#else
    164#define debugColPrint(x,y) /**/
    165#endif
    166
    167/*
    168 * memory growing methods for dynamically allocated arrays
    169 */
    170
    171/** ensures, that chgcols array can store at least num entries */
    172static
    174 SCIP_LP* lp, /**< current LP data */
    175 SCIP_SET* set, /**< global SCIP settings */
    176 int num /**< minimum number of entries to store */
    177 )
    178{
    179 assert(lp->nchgcols <= lp->chgcolssize);
    180
    181 if( num > lp->chgcolssize )
    182 {
    183 int newsize;
    184
    185 newsize = SCIPsetCalcMemGrowSize(set, num);
    186 SCIP_ALLOC( BMSreallocMemoryArray(&lp->chgcols, newsize) );
    187 lp->chgcolssize = newsize;
    188 }
    189 assert(num <= lp->chgcolssize);
    190
    191 return SCIP_OKAY;
    192}
    193
    194/** ensures, that chgrows array can store at least num entries */
    195static
    197 SCIP_LP* lp, /**< current LP data */
    198 SCIP_SET* set, /**< global SCIP settings */
    199 int num /**< minimum number of entries to store */
    200 )
    201{
    202 assert(lp->nchgrows <= lp->chgrowssize);
    203
    204 if( num > lp->chgrowssize )
    205 {
    206 int newsize;
    207
    208 newsize = SCIPsetCalcMemGrowSize(set, num);
    209 SCIP_ALLOC( BMSreallocMemoryArray(&lp->chgrows, newsize) );
    210 lp->chgrowssize = newsize;
    211 }
    212 assert(num <= lp->chgrowssize);
    213
    214 return SCIP_OKAY;
    215}
    216
    217/** ensures, that lpicols array can store at least num entries */
    218static
    220 SCIP_LP* lp, /**< current LP data */
    221 SCIP_SET* set, /**< global SCIP settings */
    222 int num /**< minimum number of entries to store */
    223 )
    224{
    225 assert(lp->nlpicols <= lp->lpicolssize);
    226
    227 if( num > lp->lpicolssize )
    228 {
    229 int newsize;
    230
    231 newsize = SCIPsetCalcMemGrowSize(set, num);
    232 SCIP_ALLOC( BMSreallocMemoryArray(&lp->lpicols, newsize) );
    233 lp->lpicolssize = newsize;
    234 }
    235 assert(num <= lp->lpicolssize);
    236
    237 return SCIP_OKAY;
    238}
    239
    240/** ensures, that lpirows array can store at least num entries */
    241static
    243 SCIP_LP* lp, /**< current LP data */
    244 SCIP_SET* set, /**< global SCIP settings */
    245 int num /**< minimum number of entries to store */
    246 )
    247{
    248 assert(lp->nlpirows <= lp->lpirowssize);
    249
    250 if( num > lp->lpirowssize )
    251 {
    252 int newsize;
    253
    254 newsize = SCIPsetCalcMemGrowSize(set, num);
    255 SCIP_ALLOC( BMSreallocMemoryArray(&lp->lpirows, newsize) );
    256 lp->lpirowssize = newsize;
    257 }
    258 assert(num <= lp->lpirowssize);
    259
    260 return SCIP_OKAY;
    261}
    262
    263/** ensures, that cols array can store at least num entries */
    264static
    266 SCIP_LP* lp, /**< current LP data */
    267 SCIP_SET* set, /**< global SCIP settings */
    268 int num /**< minimum number of entries to store */
    269 )
    270{
    271 assert(lp->ncols <= lp->colssize);
    272
    273 if( num > lp->colssize )
    274 {
    275 int newsize;
    276
    277 newsize = SCIPsetCalcMemGrowSize(set, num);
    278 SCIP_ALLOC( BMSreallocMemoryArray(&lp->cols, newsize) );
    279 lp->colssize = newsize;
    280 }
    281 assert(num <= lp->colssize);
    282
    283 return SCIP_OKAY;
    284}
    285
    286/** ensures, that soldirection array can store at least num entries */
    287static
    289 SCIP_LP* lp, /**< current LP data */
    290 int num /**< minimum number of entries to store */
    291 )
    292{
    293 if( num > lp->soldirectionsize )
    294 {
    297
    298 lp->soldirectionsize = num;
    299 }
    300
    301 assert(num <= lp->soldirectionsize);
    302
    303 return SCIP_OKAY;
    304}
    305
    306/** ensures, that lazy cols array can store at least num entries */
    307static
    309 SCIP_LP* lp, /**< current LP data */
    310 SCIP_SET* set, /**< global SCIP settings */
    311 int num /**< minimum number of entries to store */
    312 )
    313{
    314 assert(lp->nlazycols <= lp->lazycolssize);
    315
    316 if( num > lp->lazycolssize )
    317 {
    318 int newsize;
    319
    320 newsize = SCIPsetCalcMemGrowSize(set, num);
    321 SCIP_ALLOC( BMSreallocMemoryArray(&lp->lazycols, newsize) );
    322 lp->lazycolssize = newsize;
    323 }
    324 assert(num <= lp->lazycolssize);
    325
    326 return SCIP_OKAY;
    327}
    328
    329/** ensures, that rows array can store at least num entries */
    330static
    332 SCIP_LP* lp, /**< current LP data */
    333 SCIP_SET* set, /**< global SCIP settings */
    334 int num /**< minimum number of entries to store */
    335 )
    336{
    337 assert(lp->nrows <= lp->rowssize);
    338
    339 if( num > lp->rowssize )
    340 {
    341 int newsize;
    342
    343 newsize = SCIPsetCalcMemGrowSize(set, num);
    344 SCIP_ALLOC( BMSreallocMemoryArray(&lp->rows, newsize) );
    345 lp->rowssize = newsize;
    346 }
    347 assert(num <= lp->rowssize);
    348
    349 return SCIP_OKAY;
    350}
    351
    352/** ensures, that row array of column can store at least num entries */
    353static
    355 SCIP_COL* col, /**< LP column */
    356 BMS_BLKMEM* blkmem, /**< block memory */
    357 SCIP_SET* set, /**< global SCIP settings */
    358 int num /**< minimum number of entries to store */
    359 )
    360{
    361 assert(col != NULL);
    362 assert(col->len <= col->size);
    363
    364 if( num > col->size )
    365 {
    366 int newsize;
    367
    368 newsize = SCIPsetCalcMemGrowSize(set, num);
    369 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &col->rows, col->size, newsize) );
    370 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &col->vals, col->size, newsize) );
    371 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &col->linkpos, col->size, newsize) );
    372 col->size = newsize;
    373 }
    374 assert(num <= col->size);
    375
    376 return SCIP_OKAY;
    377}
    378
    379/** save current LP values dependent on the solution */
    380static
    382 SCIP_LP* lp, /**< LP data */
    383 SCIP_STAT* stat, /**< problem statistics */
    384 BMS_BLKMEM* blkmem /**< block memory */
    385 )
    386{
    387 SCIP_LPSOLVALS* storedsolvals;
    388
    389 assert(lp != NULL);
    390 assert(stat != NULL);
    391 assert(blkmem != NULL);
    392
    393 /* allocate memory for storage */
    394 if( lp->storedsolvals == NULL )
    395 {
    397 }
    398 storedsolvals = lp->storedsolvals;
    399
    400 /* store values */
    401 storedsolvals->lpsolstat = lp->lpsolstat;
    402 storedsolvals->lpobjval = lp->lpobjval;
    403 storedsolvals->primalfeasible = lp->primalfeasible;
    404 storedsolvals->primalchecked = lp->primalchecked;
    405 storedsolvals->dualfeasible = lp->dualfeasible;
    406 storedsolvals->dualchecked = lp->dualchecked;
    407 storedsolvals->solisbasic = lp->solisbasic;
    408 storedsolvals->lpissolved = lp->solved;
    409 storedsolvals->hasprovedboundexact = lp->hasprovedbound;
    410
    411 return SCIP_OKAY;
    412}
    413
    414/** restore LP solution values in column */
    415static
    417 SCIP_LP* lp, /**< LP data */
    418 BMS_BLKMEM* blkmem, /**< block memory */
    419 SCIP_Longint validlp /**< number of lp for which restored values are valid */
    420 )
    421{
    422 SCIP_LPSOLVALS* storedsolvals;
    423
    424 assert(lp != NULL);
    425 assert(blkmem != NULL);
    426
    427 /* if stored values are available, restore them */
    428 storedsolvals = lp->storedsolvals;
    429 if( storedsolvals != NULL )
    430 {
    431 lp->solved = storedsolvals->lpissolved;
    432 lp->validsollp = validlp;
    433
    434 lp->lpsolstat = storedsolvals->lpsolstat;
    435 lp->lpobjval = storedsolvals->lpobjval;
    436 lp->primalfeasible = storedsolvals->primalfeasible;
    437 lp->primalchecked = storedsolvals->primalchecked;
    438 lp->dualfeasible = storedsolvals->dualfeasible;
    439 lp->dualchecked = storedsolvals->dualchecked;
    440 lp->solisbasic = storedsolvals->solisbasic;
    441 lp->hasprovedbound = storedsolvals->hasprovedboundexact;
    442
    443 /* solution values are stored only for LPs solved without error */
    444 assert(lp->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL ||
    450 lp->validsollp == -1);
    451 }
    452 /* no values available, mark LP as unsolved */
    453 else
    454 {
    455 lp->solved = FALSE;
    456 lp->validsollp = -1;
    457
    460 lp->primalfeasible = FALSE;
    461 lp->primalchecked = FALSE;
    462 lp->dualfeasible = FALSE;
    463 lp->dualchecked = FALSE;
    464 lp->solisbasic = FALSE;
    465 lp->validfarkaslp = -1;
    466 }
    467
    468 lp->validdegeneracylp = -1;
    469
    470 /* intentionally keep storage space allocated */
    471
    472 return SCIP_OKAY;
    473}
    474
    475/** save current LP solution values stored in each column */
    476static
    478 SCIP_COL* col, /**< LP column */
    479 BMS_BLKMEM* blkmem /**< block memory */
    480 )
    481{
    482 SCIP_COLSOLVALS* storedsolvals;
    483
    484 assert(col != NULL);
    485 assert(blkmem != NULL);
    486
    487 /* allocate memory for storage */
    488 if( col->storedsolvals == NULL )
    489 {
    491 }
    492 storedsolvals = col->storedsolvals;
    493
    494 /* store values */
    495 storedsolvals->primsol = col->primsol;
    496 storedsolvals->redcost = col->redcost;
    497 storedsolvals->basisstatus = col->basisstatus; /*lint !e641 !e732*/
    498
    499 return SCIP_OKAY;
    500}
    501
    502/** restore LP solution values in column */
    503static
    505 SCIP_COL* col, /**< LP column */
    506 BMS_BLKMEM* blkmem, /**< block memory */
    507 SCIP_Longint validlp, /**< number of lp for which restored values are valid */
    508 SCIP_Bool freebuffer /**< should buffer for LP solution values be freed? */
    509 )
    510{
    511 SCIP_COLSOLVALS* storedsolvals;
    512
    513 assert(col != NULL);
    514 assert(blkmem != NULL);
    515
    516 /* if stored values are available, restore them */
    517 storedsolvals = col->storedsolvals;
    518 if( storedsolvals != NULL )
    519 {
    520 col->primsol = storedsolvals->primsol;
    521 col->redcost = storedsolvals->redcost;
    522 col->validredcostlp = validlp;
    523 col->basisstatus = storedsolvals->basisstatus; /*lint !e641 !e732*/
    524
    525 /* we do not save the farkas coefficient, since it can be recomputed; thus, we invalidate it here */
    526 col->validfarkaslp = -1;
    527 }
    528 /* if the column was created after performing the storage (possibly during probing), we treat it as implicitly zero;
    529 * we make sure to invalidate the reduced cost and farkas coefficient, which are not available
    530 */
    531 else
    532 {
    533 col->primsol = 0.0;
    534 col->validredcostlp = -1;
    535 col->validfarkaslp = -1;
    536 col->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
    537 }
    538
    539 /* free memory */
    540 if( freebuffer )
    541 {
    543 assert(col->storedsolvals == NULL);
    544 }
    545
    546 return SCIP_OKAY;
    547}
    548
    549/** save current LP solution values stored in each column */
    550static
    552 SCIP_ROW* row, /**< LP row */
    553 BMS_BLKMEM* blkmem, /**< block memory */
    554 SCIP_Bool infeasible /**< is the solution infeasible? */
    555 )
    556{
    557 SCIP_ROWSOLVALS* storedsolvals;
    558
    559 assert(row != NULL);
    560 assert(blkmem != NULL);
    561
    562 /* allocate memory for storage */
    563 if( row->storedsolvals == NULL )
    564 {
    566 }
    567 storedsolvals = row->storedsolvals;
    568
    569 /* store values */
    570 if ( infeasible )
    571 {
    572 storedsolvals->dualsol = row->dualfarkas;
    573 storedsolvals->activity = SCIP_INVALID;
    574 storedsolvals->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
    575 }
    576 else
    577 {
    578 storedsolvals->dualsol = row->dualsol;
    579 storedsolvals->activity = row->activity;
    580 storedsolvals->basisstatus = row->basisstatus; /*lint !e641 !e732*/
    581 }
    582
    583 return SCIP_OKAY;
    584}
    585
    586/** restore LP solution values in row */
    587static
    589 SCIP_ROW* row, /**< LP column */
    590 BMS_BLKMEM* blkmem, /**< block memory */
    591 SCIP_Longint validlp, /**< number of lp for which restored values are valid */
    592 SCIP_Bool freebuffer, /**< should buffer for LP solution values be freed? */
    593 SCIP_Bool infeasible /**< is the solution infeasible? */
    594 )
    595{
    596 SCIP_ROWSOLVALS* storedsolvals;
    597
    598 assert(row != NULL);
    599 assert(blkmem != NULL);
    600
    601 /* if stored values are available, restore them */
    602 storedsolvals = row->storedsolvals;
    603 if( storedsolvals != NULL )
    604 {
    605 if ( infeasible )
    606 row->dualfarkas = storedsolvals->dualsol;
    607 else
    608 row->dualsol = storedsolvals->dualsol;
    609 row->activity = storedsolvals->activity;
    610 row->validactivitylp = validlp;
    611 row->basisstatus = storedsolvals->basisstatus; /*lint !e641 !e732*/
    612 }
    613 /* if the row was created after performing the storage (possibly during probing), we treat it as basic;
    614 * we make sure to invalidate the reduced cost and farkas coefficient, which are not available
    615 */
    616 else
    617 {
    618 row->dualsol = 0.0;
    619 row->dualfarkas = 0.0;
    620 row->activity = SCIP_INVALID;
    621 row->validactivitylp = -1;
    622 row->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
    623 }
    624
    625 /* free memory */
    626 if( freebuffer )
    627 {
    629 assert(row->storedsolvals == NULL);
    630 }
    631
    632 return SCIP_OKAY;
    633}
    634
    635/** ensures, that column array of row can store at least num entries */
    637 SCIP_ROW* row, /**< LP row */
    638 BMS_BLKMEM* blkmem, /**< block memory */
    639 SCIP_SET* set, /**< global SCIP settings */
    640 int num /**< minimum number of entries to store */
    641 )
    642{
    643 assert(row != NULL);
    644 assert(row->len <= row->size);
    645
    646 if( num > row->size )
    647 {
    648 int newsize;
    649
    650 newsize = SCIPsetCalcMemGrowSize(set, num);
    651 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->cols, row->size, newsize) );
    652 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->cols_index, row->size, newsize) );
    653 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->vals, row->size, newsize) );
    654 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->linkpos, row->size, newsize) );
    655 row->size = newsize;
    656 }
    657 assert(num <= row->size);
    658
    659 return SCIP_OKAY;
    660}
    661
    662
    663#ifdef SCIP_MORE_DEBUG /* enable this to check the sortings within rows (for debugging, very slow!) */
    664static SCIP_Bool msgdisp_checkrow = FALSE;
    665
    666static
    667void checkRow(
    668 SCIP_ROW* row
    669 )
    670{
    671 int i;
    672
    673 if( !msgdisp_checkrow )
    674 {
    675 printf("LP ROW CHECKING ACTIVATED! THIS IS VERY SLOW!\n");
    676 msgdisp_checkrow = TRUE;
    677 }
    678
    679 /* validate sorting of LP part of row */
    680 if( row->lpcolssorted && row->nlpcols > 0)
    681 {
    682 assert(row->cols_index[0] == row->cols[0]->index);
    683 for( i = 1; i < row->nlpcols; ++i )
    684 {
    685 assert(row->cols_index[i] == row->cols[i]->index);
    686 assert(row->cols_index[i] >= row->cols_index[i-1]);
    687 }
    688 }
    689
    690 /* validate sorting of non-LP part of row */
    691 if( row->nonlpcolssorted && row->len > row->nlpcols )
    692 {
    693 assert(row->cols_index[row->nlpcols] == row->cols[row->nlpcols]->index);
    694 for( i = row->nlpcols + 1; i < row->len; ++i )
    695 {
    696 assert(row->cols_index[i] == row->cols[i]->index);
    697 assert(row->cols_index[i] >= row->cols_index[i-1]);
    698 }
    699 }
    700}
    701#else
    702#define checkRow(row) /**/
    703#endif
    704
    705#ifdef SCIP_MORE_DEBUG /* enable this to check norms of rows (for debugging, very slow!) */
    706static
    707void checkRowSqrnorm(
    708 SCIP_ROW* row
    709 )
    710{
    711 SCIP_COL** cols;
    712 SCIP_Real sqrnorm;
    713 int c;
    714
    715 cols = row->cols;
    716 assert(cols != NULL || row->len == 0);
    717
    718 sqrnorm = 0.0;
    719
    720 for( c = row->len - 1; c >= 0; --c )
    721 {
    722 if( cols[c]->lppos >= 0 )
    723 sqrnorm += SQR(row->vals[c]);
    724 }
    725
    726 assert(ABS(sqrnorm - row->sqrnorm) < 1e-06 * MAX(1.0,sqrnorm));
    727}
    728
    729static
    730void checkRowSumnorm(
    731 SCIP_ROW* row
    732 )
    733{
    734 SCIP_COL** cols;
    735 SCIP_Real sumnorm;
    736 int c;
    737
    738 cols = row->cols;
    739 assert(cols != NULL || row->len == 0);
    740
    741 sumnorm = 0.0;
    742
    743 for( c = row->len - 1; c >= 0; --c )
    744 {
    745 if( cols[c]->lppos >= 0 )
    746 sumnorm += REALABS(row->vals[c]);
    747 }
    748
    749 assert(ABS(sumnorm - row->sumnorm) < 1e-06 * MAX(1.0,sumnorm));
    750}
    751
    752static
    753void checkRowObjprod(
    754 SCIP_ROW* row
    755 )
    756{
    757 SCIP_COL** cols;
    758 SCIP_Real objprod;
    759 int c;
    760
    761 cols = row->cols;
    762 assert(cols != NULL || row->len == 0);
    763
    764 objprod = 0.0;
    765
    766 for( c = row->len - 1; c >= 0; --c )
    767 {
    768 if( cols[c]->lppos >= 0 )
    769 objprod += row->vals[c] * cols[c]->unchangedobj;
    770 }
    771
    772 assert(ABS(objprod - row->objprod) < 1e-06 * MAX(1.0,objprod));
    773}
    774#else
    775#define checkRowSqrnorm(row) /**/
    776#define checkRowSumnorm(row) /**/
    777#define checkRowObjprod(row) /**/
    778#endif
    779
    780/*
    781 * Local methods for pseudo and loose objective values
    782 */
    783
    784/** recompute the pseudo solution value from scratch, if it was marked to be unreliable before
    785 *
    786 * Safe version for use in exact SCIP.
    787 */
    788static
    790 SCIP_LP* lp, /**< current LP data */
    791 SCIP_SET* set, /**< global SCIP settings */
    792 SCIP_PROB* prob /**< problem data */
    793 )
    794{
    795 SCIP_VAR** vars;
    796 SCIP_INTERVAL obj;
    797 SCIP_INTERVAL bnd;
    798 SCIP_INTERVAL res;
    799 SCIP_INTERVAL prod;
    800 int nvars;
    801 int v;
    802
    803 assert(lp != NULL);
    804 assert(set != NULL);
    805 assert(prob != NULL);
    806 assert(set->exact_enable);
    807
    808 vars = prob->vars;
    809 nvars = prob->nvars;
    810
    811 SCIPintervalSet(&res, 0.0);
    812
    813 /* iterate over all variables in the problem */
    814 for( v = 0; v < nvars; ++v )
    815 {
    816 if( SCIPvarGetStatus(vars[v]) == SCIP_VARSTATUS_LOOSE )
    817 {
    819
    820 /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
    821 if( obj.sup > 0 && !SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(vars[v])) )
    822 {
    823 SCIPintervalSet(&bnd, SCIPvarGetLbLocal(vars[v]));
    824 SCIPintervalMul(SCIPsetInfinity(set), &prod, obj, bnd);
    825 SCIPintervalAdd(SCIPsetInfinity(set), &res, res, prod);
    826 }
    827 else if( obj.inf < 0 && !SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
    828 {
    829 SCIPintervalSet(&bnd, SCIPvarGetUbLocal(vars[v]));
    830 SCIPintervalMul(SCIPsetInfinity(set), &prod, obj, bnd);
    831 SCIPintervalAdd(SCIPsetInfinity(set), &res, res, prod);
    832 }
    833 }
    834 }
    835
    836 /* the recomputed value is reliable */
    838 lp->rellooseobjval = lp->looseobjval;
    839 lp->looseobjvalid = TRUE;
    840}
    841
    842/** recompute the loose objective value from scratch, if it was marked to be unreliable before */
    843static
    845 SCIP_LP* lp, /**< current LP data */
    846 SCIP_SET* set, /**< global SCIP settings */
    847 SCIP_PROB* prob /**< problem data */
    848 )
    849{
    850 SCIP_VAR** vars;
    851 SCIP_Real obj;
    852 int nvars;
    853 int v;
    854
    855 assert(lp != NULL);
    856 assert(set != NULL);
    857 assert(prob != NULL);
    858 assert(!lp->looseobjvalid);
    859
    860 vars = prob->vars;
    861 nvars = prob->nvars;
    862 lp->looseobjval = 0.0;
    863
    864 if( set->exact_enable )
    865 {
    867 return;
    868 }
    869
    870 /* iterate over all variables in the problem */
    871 for( v = 0; v < nvars; ++v )
    872 {
    873 if( SCIPvarGetStatus(vars[v]) == SCIP_VARSTATUS_LOOSE )
    874 {
    875 obj = SCIPvarGetObj(vars[v]);
    876
    877 /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
    879 lp->looseobjval += obj * SCIPvarGetLbLocal(vars[v]);
    880 else if( SCIPsetIsNegative(set, obj) && !SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
    881 lp->looseobjval += obj * SCIPvarGetUbLocal(vars[v]);
    882 }
    883 }
    884
    885 /* the recomputed value is reliable */
    886 lp->rellooseobjval = lp->looseobjval;
    887 lp->looseobjvalid = TRUE;
    888}
    889
    890/** recompute the pseudo solution value from scratch, if it was marked to be unreliable before
    891 *
    892 * Safe version for use in exact SCIP.
    893 */
    894static
    896 SCIP_LP* lp, /**< current LP data */
    897 SCIP_SET* set, /**< global SCIP settings */
    898 SCIP_PROB* prob /**< problem data */
    899 )
    900{
    901 SCIP_VAR** vars;
    902 SCIP_INTERVAL obj;
    903 SCIP_INTERVAL bnd;
    904 SCIP_INTERVAL res;
    905 SCIP_INTERVAL prod;
    906 int nvars;
    907 int v;
    908
    909 assert(lp != NULL);
    910 assert(set != NULL);
    911 assert(prob != NULL);
    912 assert(!lp->pseudoobjvalid);
    913 assert(set->exact_enable);
    914
    915 vars = prob->vars;
    916 nvars = prob->nvars;
    917
    918 SCIPintervalSet(&res, 0.0);
    919
    920 /* iterate over all variables in the problem */
    921 for( v = 0; v < nvars; ++v )
    922 {
    924
    925 /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
    926 if( obj.sup > 0 && !SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(vars[v])) )
    927 {
    928 SCIPintervalSet(&bnd, SCIPvarGetLbLocal(vars[v]));
    929 SCIPintervalMul(SCIPsetInfinity(set), &prod, obj, bnd);
    930 SCIPintervalAdd(SCIPsetInfinity(set), &res, res, prod);
    931 }
    932 else if( obj.inf < 0 && !SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
    933 {
    934 SCIPintervalSet(&bnd, SCIPvarGetUbLocal(vars[v]));
    935 SCIPintervalMul(SCIPsetInfinity(set), &prod, obj, bnd);
    936 SCIPintervalAdd(SCIPsetInfinity(set), &res, res, prod);
    937 }
    938 }
    939
    940 /* the recomputed value is reliable */
    943 lp->pseudoobjvalid = TRUE;
    944}
    945
    946/** recompute the pseudo solution value from scratch, if it was marked to be unreliable before */
    947static
    949 SCIP_LP* lp, /**< current LP data */
    950 SCIP_SET* set, /**< global SCIP settings */
    951 SCIP_PROB* prob /**< problem data */
    952 )
    953{
    954 SCIP_VAR** vars;
    955 int nvars;
    956 int v;
    957
    958 assert(lp != NULL);
    959 assert(set != NULL);
    960 assert(prob != NULL);
    961 assert(!lp->pseudoobjvalid);
    962
    963 vars = prob->vars;
    964 nvars = prob->nvars;
    965 lp->pseudoobjval = 0.0;
    966
    967 if( set->exact_enable )
    968 {
    970 return;
    971 }
    972
    973 /* iterate over all variables in the problem */
    974 for( v = 0; v < nvars; ++v )
    975 {
    976 /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
    978 {
    979 lp->pseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetLbLocal(vars[v]);
    980 }
    981 else if( SCIPsetIsNegative(set, SCIPvarGetObj(vars[v])) && !SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
    982 {
    983 lp->pseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetUbLocal(vars[v]);
    984 }
    985 }
    986
    987 /* the recomputed value is reliable */
    989 lp->pseudoobjvalid = TRUE;
    990}
    991
    992/** recompute the global pseudo solution value from scratch, if it was marked to be unreliable before */
    993static
    995 SCIP_LP* lp, /**< current LP data */
    996 SCIP_SET* set, /**< global SCIP settings */
    997 SCIP_PROB* prob /**< problem data */
    998 )
    999{
    1000 SCIP_VAR** vars;
    1001 int nvars;
    1002 int v;
    1003
    1004 assert(lp != NULL);
    1005 assert(set != NULL);
    1006 assert(prob != NULL);
    1007 assert(!lp->glbpseudoobjvalid);
    1008
    1009 vars = prob->vars;
    1010 nvars = prob->nvars;
    1011 lp->glbpseudoobjval = 0.0;
    1012
    1013 /* iterate over all variables in the problem */
    1014 for( v = 0; v < nvars; ++v )
    1015 {
    1016 /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
    1018 {
    1019 lp->glbpseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetLbGlobal(vars[v]);
    1020 }
    1021 else if( SCIPsetIsNegative(set, SCIPvarGetObj(vars[v])) && !SCIPsetIsInfinity(set, SCIPvarGetUbGlobal(vars[v])) )
    1022 {
    1023 lp->glbpseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetUbGlobal(vars[v]);
    1024 }
    1025 }
    1026
    1027 /* the recomputed value is reliable */
    1029 lp->glbpseudoobjvalid = TRUE;
    1030}
    1031
    1032/** gets finite part of objective value of current LP that results from LOOSE variables only */
    1033static
    1035 SCIP_LP* lp, /**< current LP data */
    1036 SCIP_SET* set, /**< global SCIP settings */
    1037 SCIP_PROB* prob /**< problem data */
    1038 )
    1039{
    1040 assert(lp != NULL);
    1041 assert(set != NULL);
    1042 assert(prob != NULL);
    1043 assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
    1044 assert(lp->flushed);
    1045 assert(lp->looseobjvalinf == 0);
    1046
    1047 /* recalculate the loose objective value, if needed */
    1048 if( !lp->looseobjvalid )
    1050
    1051 return lp->looseobjval;
    1052}
    1053
    1054/** gets finite part of pseudo objective value of current LP */
    1055static
    1057 SCIP_LP* lp, /**< current LP data */
    1058 SCIP_SET* set, /**< global SCIP settings */
    1059 SCIP_PROB* prob /**< problem data */
    1060 )
    1061{
    1062 assert(lp != NULL);
    1063 assert(set != NULL);
    1064 assert(prob != NULL);
    1065
    1066 /* recalculate the pseudo objective value, if needed */
    1067 if( !lp->pseudoobjvalid )
    1069
    1070 return lp->pseudoobjval;
    1071}
    1072
    1073/*
    1074 * Sorting and searching rows and columns
    1075 */
    1076
    1077
    1078/** comparison method for sorting rows by non-decreasing index */
    1080{
    1081 assert(elem1 != NULL);
    1082 assert(elem2 != NULL);
    1083
    1084 if( ((SCIP_ROW*)elem1)->index < ((SCIP_ROW*)elem2)->index )
    1085 return -1;
    1086 else if( ((SCIP_ROW*)elem1)->index > ((SCIP_ROW*)elem2)->index )
    1087 return +1;
    1088 else
    1089 {
    1090 assert(SCIProwGetIndex((SCIP_ROW*)(elem1)) == SCIProwGetIndex(((SCIP_ROW*)elem2)));
    1091 return 0;
    1092 }
    1093}
    1094
    1095
    1096/** sorts column entries of linked rows currently in the LP such that lower row indices precede higher ones */
    1097static
    1099 SCIP_COL* col /**< column to be sorted */
    1100 )
    1101{
    1102 int i;
    1103
    1104 assert(col != NULL);
    1105
    1106 /* check, if column is already sorted in the LP part */
    1107 if( col->lprowssorted )
    1108 return;
    1109
    1110 /* sort coefficients */
    1111 SCIPsortPtrRealInt((void**)col->rows, col->vals, col->linkpos, SCIProwComp, col->nlprows );
    1112
    1113 /* update links */
    1114 for( i = 0; i < col->nlprows; ++i )
    1115 {
    1116 if( col->linkpos[i] >= 0 )
    1117 {
    1118 assert(col->rows[i]->cols[col->linkpos[i]] == col);
    1119 assert(col->rows[i]->linkpos[col->linkpos[i]] >= 0);
    1120 col->rows[i]->linkpos[col->linkpos[i]] = i;
    1121 }
    1122 }
    1123
    1124 col->lprowssorted = TRUE;
    1125}
    1126
    1127/** sorts column entries of unlinked rows or rows currently not in the LP such that lower row indices precede higher
    1128 * ones
    1129 */
    1130static
    1132 SCIP_COL* col /**< column to be sorted */
    1133 )
    1134{
    1135 int i;
    1136
    1137 assert(col != NULL);
    1138
    1139 /* check, if column is already sorted in the non-LP part */
    1140 if( col->nonlprowssorted )
    1141 return;
    1142
    1143 /* sort coefficients */
    1144 SCIPsortPtrRealInt((void**)(&(col->rows[col->nlprows])), &(col->vals[col->nlprows]), &(col->linkpos[col->nlprows]), SCIProwComp, col->len - col->nlprows);
    1145
    1146 /* update links */
    1147 for( i = col->nlprows; i < col->len; ++i )
    1148 {
    1149 if( col->linkpos[i] >= 0 )
    1150 {
    1151 assert(col->rows[i]->cols[col->linkpos[i]] == col);
    1152 assert(col->rows[i]->linkpos[col->linkpos[i]] >= 0);
    1153 col->rows[i]->linkpos[col->linkpos[i]] = i;
    1154 }
    1155 }
    1156
    1157 col->nonlprowssorted = TRUE;
    1158}
    1159
    1160/** sorts row entries of linked columns currently in the LP such that lower column indices precede higher ones */
    1161static
    1163 SCIP_ROW* row /**< row to be sorted */
    1164 )
    1165{
    1166 int i;
    1167
    1168 assert(row != NULL);
    1169
    1170 /* check, if row is already sorted in the LP part, or if the sorting should be delayed */
    1171 if( row->lpcolssorted || row->delaysort )
    1172 return;
    1173
    1174 /* sort coefficients */
    1175 SCIPsortIntPtrIntReal(row->cols_index, (void**)row->cols, row->linkpos, row->vals, row->nlpcols);
    1176
    1177 /* update links */
    1178 for( i = 0; i < row->nlpcols; ++i )
    1179 {
    1180 if( row->linkpos[i] >= 0 )
    1181 {
    1182 assert(row->cols[i]->rows[row->linkpos[i]] == row);
    1183 assert(row->cols[i]->linkpos[row->linkpos[i]] >= 0);
    1184 row->cols[i]->linkpos[row->linkpos[i]] = i;
    1185 }
    1186 }
    1187
    1188 row->lpcolssorted = TRUE;
    1189}
    1190
    1191/** sorts row entries of unlinked columns or columns currently not in the LP such that lower column indices precede
    1192 * higher ones
    1193 */
    1194static
    1196 SCIP_ROW* row /**< row to be sorted */
    1197 )
    1198{
    1199 int i;
    1200
    1201 assert(row != NULL);
    1202
    1203 checkRow(row);
    1204
    1205 /* check, if row is already sorted in the non-LP part, or if the sorting should be delayed */
    1206 if( row->nonlpcolssorted || row->delaysort )
    1207 return;
    1208
    1209 /* sort coefficients */
    1210 SCIPsortIntPtrIntReal(&(row->cols_index[row->nlpcols]), (void**)(&(row->cols[row->nlpcols])), &(row->linkpos[row->nlpcols]), &(row->vals[row->nlpcols]), row->len - row->nlpcols);
    1211
    1212 /* update links */
    1213 for( i = row->nlpcols; i < row->len; ++i )
    1214 {
    1215 if( row->linkpos[i] >= 0 )
    1216 {
    1217 assert(row->cols[i]->rows[row->linkpos[i]] == row);
    1218 assert(row->cols[i]->linkpos[row->linkpos[i]] >= 0);
    1219 row->cols[i]->linkpos[row->linkpos[i]] = i;
    1220 }
    1221 }
    1222
    1223 checkRow(row);
    1224
    1225 row->nonlpcolssorted = TRUE;
    1226}
    1227
    1228/** searches coefficient in part of the column, returns position in col vector or -1 if not found */
    1229static
    1231 SCIP_COL* col, /**< column to be searched in */
    1232 const SCIP_ROW* row, /**< coefficient to be searched for */
    1233 int minpos, /**< first position of search range */
    1234 int maxpos /**< last position of search range */
    1235 )
    1236{
    1237 int pos;
    1238 int idx;
    1239 int searchidx;
    1240
    1241 assert(col != NULL);
    1242 assert(row != NULL);
    1243
    1244 /* binary search */
    1245 searchidx = row->index;
    1246 while(minpos <= maxpos)
    1247 {
    1248 pos = (minpos + maxpos)/2;
    1249 assert(0 <= pos && pos < col->len);
    1250 assert(col->rows[pos] != NULL);
    1251 assert((pos < col->nlprows) == (col->rows[pos]->lppos >= 0 && col->linkpos[pos] >= 0));
    1252 idx = col->rows[pos]->index;
    1253 if( searchidx == idx )
    1254 return pos;
    1255 else if( searchidx < idx )
    1256 maxpos = pos-1;
    1257 else
    1258 minpos = pos+1;
    1259 }
    1260
    1261 return -1;
    1262}
    1263
    1264/** searches coefficient in column, returns position in col vector or -1 if not found */
    1265static
    1267 SCIP_COL* col, /**< column to be searched in */
    1268 const SCIP_ROW* row /**< coefficient to be searched for */
    1269 )
    1270{
    1271 int pos;
    1272
    1273 assert(col != NULL);
    1274 assert(row != NULL);
    1275
    1276 pos = -1;
    1277
    1278 /* search in the linked LP rows */
    1279 if( row->lppos >= 0 )
    1280 {
    1281 /* column has to be sorted, such that binary search works */
    1282 colSortLP(col);
    1283 assert(col->lprowssorted);
    1284
    1285 pos = colSearchCoefPart(col, row, 0, col->nlprows-1);
    1286 if( pos >= 0 )
    1287 return pos;
    1288 }
    1289
    1290 /* search in the non-LP/unlinked rows */
    1291 if( row->lppos == -1 || col->nunlinked > 0 )
    1292 {
    1293 /* column has to be sorted, such that binary search works */
    1294 colSortNonLP(col);
    1295 assert(col->nonlprowssorted);
    1296
    1297 pos = colSearchCoefPart(col, row, col->nlprows, col->len-1);
    1298 }
    1299
    1300 return pos;
    1301}
    1302
    1303/** searches coefficient in part of the row, returns position in col vector or -1 if not found */
    1304static
    1306 SCIP_ROW* row, /**< row to be searched in */
    1307 const SCIP_COL* col, /**< coefficient to be searched for */
    1308 int minpos, /**< first position of search range */
    1309 int maxpos /**< last position of search range */
    1310 )
    1311{
    1312 int pos;
    1313 int idx;
    1314 int searchidx;
    1315
    1316 assert(row != NULL);
    1317 assert(col != NULL);
    1318
    1319 /* binary search */
    1320 searchidx = col->index;
    1321 while(minpos <= maxpos)
    1322 {
    1323 pos = (minpos + maxpos)/2;
    1324 assert(0 <= pos && pos < row->len);
    1325 assert(row->cols[pos] != NULL);
    1326 assert((pos < row->nlpcols) == (row->cols[pos]->lppos >= 0 && row->linkpos[pos] >= 0));
    1327 assert(row->cols_index[pos] == row->cols[pos]->index);
    1328 idx = row->cols_index[pos];
    1329 if( searchidx == idx )
    1330 return pos;
    1331 else if( searchidx < idx )
    1332 maxpos = pos-1;
    1333 else
    1334 minpos = pos+1;
    1335 }
    1336
    1337 return -1;
    1338}
    1339
    1340/** searches coefficient in row, returns position in row vector or -1 if not found;
    1341 * if the sorting of the row is delayed, returns -1
    1342 */
    1343static
    1345 SCIP_ROW* row, /**< row to be searched in */
    1346 const SCIP_COL* col /**< coefficient to be searched for */
    1347 )
    1348{
    1349 int pos;
    1350
    1351 assert(row != NULL);
    1352 assert(col != NULL);
    1353
    1354 if( row->delaysort )
    1355 return -1;
    1356
    1357 pos = -1;
    1358
    1359 /* search in the linked LP columns */
    1360 if( col->lppos >= 0 )
    1361 {
    1362 /* row has to be sorted, such that binary search works */
    1363 rowSortLP(row);
    1364 assert(row->lpcolssorted);
    1365
    1366 pos = rowSearchCoefPart(row, col, 0, row->nlpcols-1);
    1367 }
    1368
    1369 /* search in the non-LP/unlinked columns */
    1370 if( pos == -1 && (col->lppos == -1 || row->nunlinked > 0) )
    1371 {
    1372 /* row has to be sorted, such that binary search works */
    1373 rowSortNonLP(row);
    1374 assert(row->nonlpcolssorted);
    1375
    1376 pos = rowSearchCoefPart(row, col, row->nlpcols, row->len-1);
    1377 }
    1378
    1379#ifndef NDEBUG
    1380 /* validate result */
    1381 assert(-1 <= pos && pos < row->len);
    1382 if( pos >= 0 )
    1383 assert(row->cols[pos] == col);
    1384 else
    1385 {
    1386 int i;
    1387 for( i = 0; i < row->len; ++i )
    1388 assert(row->cols[i] != col);
    1389 }
    1390#endif
    1391
    1392 return pos;
    1393}
    1394
    1395/** moves a coefficient in a column to a different place, and updates all corresponding data structures */
    1396static
    1398 SCIP_COL* col, /**< LP column */
    1399 int oldpos, /**< old position of coefficient */
    1400 int newpos /**< new position of coefficient */
    1401 )
    1402{
    1403 assert(col != NULL);
    1404 assert(0 <= oldpos && oldpos < col->len);
    1405 assert(0 <= newpos && newpos < col->len);
    1406 assert(col->rows[oldpos] != NULL);
    1407
    1408 if( oldpos == newpos )
    1409 return;
    1410
    1411 col->rows[newpos] = col->rows[oldpos];
    1412 col->vals[newpos] = col->vals[oldpos];
    1413 col->linkpos[newpos] = col->linkpos[oldpos];
    1414
    1415 /* update link position in row */
    1416 if( col->linkpos[newpos] >= 0 )
    1417 {
    1418 assert(col->rows[newpos]->cols[col->linkpos[newpos]] == col);
    1419 assert(col->rows[newpos]->linkpos[col->linkpos[newpos]] == oldpos);
    1420
    1421 col->rows[newpos]->linkpos[col->linkpos[newpos]] = newpos;
    1422 }
    1423
    1424 /* update sorted flags */
    1425 if( col->rows[newpos]->lppos >= 0 && col->linkpos[newpos] >= 0 )
    1426 col->lprowssorted = FALSE;
    1427 else
    1428 col->nonlprowssorted = FALSE;
    1429}
    1430
    1431/** swaps two coefficients in a column, and updates all corresponding data structures */
    1432static
    1434 SCIP_COL* col, /**< LP column */
    1435 int pos1, /**< position of first coefficient */
    1436 int pos2 /**< position of second coefficient */
    1437 )
    1438{
    1439 SCIP_ROW* tmprow;
    1440 SCIP_Real tmpval;
    1441 int tmplinkpos;
    1442
    1443 assert(col != NULL);
    1444 assert(0 <= pos1 && pos1 < col->len);
    1445 assert(0 <= pos2 && pos2 < col->len);
    1446 assert(col->rows[pos1] != NULL);
    1447
    1448 if( pos1 == pos2 )
    1449 return;
    1450
    1451 /* swap coefficients */
    1452 tmprow = col->rows[pos2];
    1453 tmpval = col->vals[pos2];
    1454 tmplinkpos = col->linkpos[pos2];
    1455
    1456 col->rows[pos2] = col->rows[pos1];
    1457 col->vals[pos2] = col->vals[pos1];
    1458 col->linkpos[pos2] = col->linkpos[pos1];
    1459
    1460 col->rows[pos1] = tmprow;
    1461 col->vals[pos1] = tmpval;
    1462 col->linkpos[pos1] = tmplinkpos;
    1463
    1464 /* update link position in rows */
    1465 if( col->linkpos[pos1] >= 0 )
    1466 {
    1467 assert(col->rows[pos1]->cols[col->linkpos[pos1]] == col);
    1468 assert(col->rows[pos1]->linkpos[col->linkpos[pos1]] == pos2);
    1469
    1470 col->rows[pos1]->linkpos[col->linkpos[pos1]] = pos1;
    1471 }
    1472 if( col->linkpos[pos2] >= 0 )
    1473 {
    1474 assert(col->rows[pos2]->cols[col->linkpos[pos2]] == col);
    1475 assert(col->rows[pos2]->linkpos[col->linkpos[pos2]] == pos1);
    1476
    1477 col->rows[pos2]->linkpos[col->linkpos[pos2]] = pos2;
    1478 }
    1479
    1480 /* update sorted flags */
    1481 if( col->rows[pos1]->lppos >= 0 && col->linkpos[pos1] >= 0 )
    1482 col->lprowssorted = FALSE;
    1483 else
    1484 col->nonlprowssorted = FALSE;
    1485 if( col->rows[pos2]->lppos >= 0 && col->linkpos[pos2] >= 0 )
    1486 col->lprowssorted = FALSE;
    1487 else
    1488 col->nonlprowssorted = FALSE;
    1489}
    1490
    1491/** moves a coefficient in a row to a different place, and updates all corresponding data structures */
    1492static
    1494 SCIP_ROW* row, /**< LP row */
    1495 int oldpos, /**< old position of coefficient */
    1496 int newpos /**< new position of coefficient */
    1497 )
    1498{
    1499 assert(row != NULL);
    1500 assert(0 <= oldpos && oldpos < row->len);
    1501 assert(0 <= newpos && newpos < row->len);
    1502 assert(row->cols[oldpos] != NULL);
    1503
    1504 if( oldpos == newpos )
    1505 return;
    1506
    1507 row->cols[newpos] = row->cols[oldpos];
    1508 row->cols_index[newpos] = row->cols_index[oldpos];
    1509 row->vals[newpos] = row->vals[oldpos];
    1510 row->linkpos[newpos] = row->linkpos[oldpos];
    1511
    1512 /* update link position in column */
    1513 if( row->linkpos[newpos] >= 0 )
    1514 {
    1515 assert(row->cols[newpos]->rows[row->linkpos[newpos]] == row);
    1516 assert(row->cols[newpos]->linkpos[row->linkpos[newpos]] == oldpos);
    1517
    1518 row->cols[newpos]->linkpos[row->linkpos[newpos]] = newpos;
    1519 }
    1520
    1521 /* update sorted flags */
    1522 if( row->cols[newpos]->lppos >= 0 && row->linkpos[newpos] >= 0 )
    1523 row->lpcolssorted = FALSE;
    1524 else
    1525 row->nonlpcolssorted = FALSE;
    1526}
    1527
    1528/** swaps two coefficients in a row, and updates all corresponding data structures */
    1529static
    1531 SCIP_ROW* row, /**< LP row */
    1532 int pos1, /**< position of first coefficient */
    1533 int pos2 /**< position of second coefficient */
    1534 )
    1535{
    1536 SCIP_COL* tmpcol;
    1537 SCIP_Real tmpval;
    1538 int tmpindex;
    1539 int tmplinkpos;
    1540
    1541 assert(row != NULL);
    1542 assert(0 <= pos1 && pos1 < row->len);
    1543 assert(0 <= pos2 && pos2 < row->len);
    1544 assert(row->cols[pos1] != NULL);
    1545 assert(row->cols[pos1]->index == row->cols_index[pos1]);
    1546
    1547 if( pos1 == pos2 )
    1548 return;
    1549
    1550 /* swap coefficients */
    1551 tmpcol = row->cols[pos2];
    1552 tmpindex = row->cols_index[pos2];
    1553 tmpval = row->vals[pos2];
    1554 tmplinkpos = row->linkpos[pos2];
    1555
    1556 row->cols[pos2] = row->cols[pos1];
    1557 row->cols_index[pos2] = row->cols_index[pos1];
    1558 row->vals[pos2] = row->vals[pos1];
    1559 row->linkpos[pos2] = row->linkpos[pos1];
    1560
    1561 row->cols[pos1] = tmpcol;
    1562 row->cols_index[pos1] = tmpindex;
    1563 row->vals[pos1] = tmpval;
    1564 row->linkpos[pos1] = tmplinkpos;
    1565
    1566 /* update link position in columns */
    1567 if( row->linkpos[pos1] >= 0 )
    1568 {
    1569 assert(row->cols[pos1]->rows[row->linkpos[pos1]] == row);
    1570 assert(row->cols[pos1]->linkpos[row->linkpos[pos1]] == pos2);
    1571
    1572 row->cols[pos1]->linkpos[row->linkpos[pos1]] = pos1;
    1573 }
    1574 if( row->linkpos[pos2] >= 0 )
    1575 {
    1576 assert(row->cols[pos2]->rows[row->linkpos[pos2]] == row);
    1577 assert(row->cols[pos2]->linkpos[row->linkpos[pos2]] == pos1);
    1578
    1579 row->cols[pos2]->linkpos[row->linkpos[pos2]] = pos2;
    1580 }
    1581
    1582 /* update sorted flags */
    1583 if( row->cols[pos1]->lppos >= 0 && row->linkpos[pos1] >= 0 )
    1584 row->lpcolssorted = FALSE;
    1585 else
    1586 row->nonlpcolssorted = FALSE;
    1587 if( row->cols[pos2]->lppos >= 0 && row->linkpos[pos2] >= 0 )
    1588 row->lpcolssorted = FALSE;
    1589 else
    1590 row->nonlpcolssorted = FALSE;
    1591}
    1592
    1593/** issues a ROWCOEFCHANGED event on the given row */
    1594static
    1596 SCIP_ROW* row, /**< row which coefficient has changed */
    1597 BMS_BLKMEM* blkmem, /**< block memory */
    1598 SCIP_SET* set, /**< global SCIP settings */
    1599 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    1600 SCIP_COL* col, /**< the column which coefficient has changed */
    1601 SCIP_Real oldval, /**< old value of the coefficient */
    1602 SCIP_Real newval /**< new value of the coefficient */
    1603 )
    1604{
    1605 assert(row != NULL);
    1606 assert(row->eventfilter != NULL);
    1607 assert(col != NULL);
    1608
    1609 /* check, if the row is being tracked for coefficient changes
    1610 * if so, issue ROWCOEFCHANGED event
    1611 */
    1612 if( (row->eventfilter->len > 0 && (row->eventfilter->eventmask & SCIP_EVENTTYPE_ROWCOEFCHANGED) != 0) ) /*lint !e587*/
    1613 {
    1614 SCIP_EVENT* event;
    1615
    1616 SCIP_CALL( SCIPeventCreateRowCoefChanged(&event, blkmem, row, col, oldval, newval) );
    1617 SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, row->eventfilter, &event) );
    1618 }
    1619
    1620 return SCIP_OKAY;
    1621}
    1622
    1623/** issues a ROWCONSTCHANGED event on the given row */
    1624static
    1626 SCIP_ROW* row, /**< row which coefficient has changed */
    1627 BMS_BLKMEM* blkmem, /**< block memory */
    1628 SCIP_SET* set, /**< global SCIP settings */
    1629 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    1630 SCIP_Real oldval, /**< old value of the constant */
    1631 SCIP_Real newval /**< new value of the constant */
    1632 )
    1633{
    1634 assert(row != NULL);
    1635 assert(row->eventfilter != NULL);
    1636
    1637 /* check, if the row is being tracked for coefficient changes
    1638 * if so, issue ROWCONSTCHANGED event
    1639 */
    1641 {
    1642 SCIP_EVENT* event;
    1643
    1644 SCIP_CALL( SCIPeventCreateRowConstChanged(&event, blkmem, row, oldval, newval) );
    1645 SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, row->eventfilter, &event) );
    1646 }
    1647
    1648 return SCIP_OKAY;
    1649}
    1650
    1651/** issues a ROWSIDECHANGED event on the given row */
    1652static
    1654 SCIP_ROW* row, /**< row which coefficient has changed */
    1655 BMS_BLKMEM* blkmem, /**< block memory */
    1656 SCIP_SET* set, /**< global SCIP settings */
    1657 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    1658 SCIP_SIDETYPE side, /**< the side that has changed */
    1659 SCIP_Real oldval, /**< old value of side */
    1660 SCIP_Real newval /**< new value of side */
    1661 )
    1662{
    1663 assert(row != NULL);
    1664 assert(row->eventfilter != NULL);
    1665
    1666 /* check, if the row is being tracked for coefficient changes
    1667 * if so, issue ROWSIDECHANGED event
    1668 */
    1669 if( (row->eventfilter->len > 0 && !(row->eventfilter->eventmask & SCIP_EVENTTYPE_ROWSIDECHANGED)) )
    1670 {
    1671 SCIP_EVENT* event;
    1672
    1673 SCIP_CALL( SCIPeventCreateRowSideChanged(&event, blkmem, row, side, oldval, newval) );
    1674 SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, row->eventfilter, &event) );
    1675 }
    1676
    1677 return SCIP_OKAY;
    1678}
    1679
    1680#ifdef SCIP_MORE_DEBUG /* enable this to check links between columns and rows in LP data structure (for debugging, very slow!) */
    1681
    1682#ifdef NDEBUG
    1683#define ASSERT(x) do { if( !(x) ) abort(); } while( FALSE )
    1684#else
    1685#define ASSERT(x) assert(x)
    1686#endif
    1687
    1688static SCIP_Bool msgdisp_checklinks = FALSE;
    1689
    1690
    1691static
    1692void checkLinks(
    1693 SCIP_LP* lp /**< current LP data */
    1694 )
    1695{
    1696 SCIP_COL* col;
    1697 SCIP_ROW* row;
    1698 int i;
    1699 int j;
    1700
    1701 ASSERT(lp != NULL);
    1702
    1703 if( !msgdisp_checklinks )
    1704 {
    1705 printf("LP LINK CHECKING ACTIVATED! THIS IS VERY SLOW!\n");
    1706 msgdisp_checklinks = TRUE;
    1707 }
    1708
    1709 for( i = 0; i < lp->ncols; ++i )
    1710 {
    1711 col = lp->cols[i];
    1712 ASSERT(col != NULL);
    1713 ASSERT(!lp->flushed || col->lppos >= 0 || col->primsol == 0.0);
    1714 ASSERT(!lp->flushed || col->lppos >= 0 || col->farkascoef == 0.0);
    1715 ASSERT(col->nlprows <= col->len);
    1716 ASSERT(col->lppos == -1 || col->lppos >= lp->lpifirstchgcol || col->nunlinked == 0);
    1717
    1718 for( j = 0; j < col->len; ++j )
    1719 {
    1720 row = col->rows[j];
    1721 ASSERT(row != NULL);
    1722 ASSERT(!lp->flushed || col->lppos == -1 || col->linkpos[j] >= 0);
    1723 ASSERT(col->linkpos[j] == -1 || row->cols[col->linkpos[j]] == col);
    1724 ASSERT(col->linkpos[j] == -1 || EPSEQ(row->vals[col->linkpos[j]], col->vals[j], 1e-6));
    1725 ASSERT((j < col->nlprows) == (col->linkpos[j] >= 0 && row->lppos >= 0));
    1726 }
    1727 }
    1728
    1729 for( i = 0; i < lp->nrows; ++i )
    1730 {
    1731 row = lp->rows[i];
    1732 ASSERT(row != NULL);
    1733 ASSERT(!lp->flushed || row->lppos >= 0 || row->dualsol == 0.0);
    1734 ASSERT(!lp->flushed || row->lppos >= 0 || row->dualfarkas == 0.0);
    1735 ASSERT(row->nlpcols <= row->len);
    1736 ASSERT(row->lppos == -1 || row->lppos >= lp->lpifirstchgrow || row->nunlinked == 0);
    1737
    1738 for( j = 0; j < row->len; ++j )
    1739 {
    1740 col = row->cols[j];
    1741 ASSERT(col != NULL);
    1742 ASSERT(!lp->flushed || row->lppos == -1 || row->linkpos[j] >= 0);
    1743 ASSERT(row->linkpos[j] == -1 || col->rows[row->linkpos[j]] == row);
    1744 ASSERT(row->linkpos[j] == -1 || EPSEQ(col->vals[row->linkpos[j]], row->vals[j], 1e-6));
    1745 ASSERT((j < row->nlpcols) == (row->linkpos[j] >= 0 && col->lppos >= 0));
    1746 }
    1747 }
    1748}
    1749
    1750#undef ASSERT
    1751
    1752#else
    1753#define checkLinks(lp) /**/
    1754#endif
    1755
    1756/*
    1757 * Changing announcements
    1758 */
    1759
    1760/** announces, that the given coefficient in the constraint matrix changed */
    1761static
    1763 SCIP_ROW* row, /**< LP row */
    1764 SCIP_COL* col, /**< LP col */
    1765 SCIP_LP* lp /**< current LP data */
    1766 )
    1767{
    1768 assert(row != NULL);
    1769 assert(col != NULL);
    1770 assert(lp != NULL);
    1771
    1772 if( row->lpipos >= 0 && col->lpipos >= 0 )
    1773 {
    1774 assert(row->lpipos < lp->nlpirows);
    1775 assert(col->lpipos < lp->nlpicols);
    1776
    1777 /* we have to remember the change only in the row or in the column,
    1778 * because the readdition of one vector would change the other automatically.
    1779 */
    1780 if( row->lpipos >= lp->lpifirstchgrow )
    1781 row->coefchanged = TRUE;
    1782 else if( col->lpipos >= lp->lpifirstchgcol )
    1783 col->coefchanged = TRUE;
    1784 else if( lp->lpifirstchgrow - row->lpipos <= lp->lpifirstchgcol - col->lpipos )
    1785 {
    1786 row->coefchanged = TRUE;
    1787 lp->lpifirstchgrow = row->lpipos;
    1788 }
    1789 else
    1790 {
    1791 col->coefchanged = TRUE;
    1792 lp->lpifirstchgcol = col->lpipos;
    1793 }
    1794
    1795 /* mark the current LP unflushed */
    1796 lp->flushed = FALSE;
    1797 }
    1798
    1802 row->validpsactivitydomchg = -1;
    1803 row->validactivitybdsdomchg = -1;
    1804}
    1805
    1806
    1807
    1808/*
    1809 * local column changing methods
    1810 */
    1811
    1812/* forward declaration for colAddCoef() */
    1813static
    1815 SCIP_ROW* row, /**< LP row */
    1816 BMS_BLKMEM* blkmem, /**< block memory */
    1817 SCIP_SET* set, /**< global SCIP settings */
    1818 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    1819 SCIP_LP* lp, /**< current LP data */
    1820 SCIP_COL* col, /**< LP column */
    1821 SCIP_Real val, /**< value of coefficient */
    1822 int linkpos /**< position of row in the column's row array, or -1 */
    1823 );
    1824
    1825/** adds a previously non existing coefficient to an LP column */
    1826static
    1828 SCIP_COL* col, /**< LP column */
    1829 BMS_BLKMEM* blkmem, /**< block memory */
    1830 SCIP_SET* set, /**< global SCIP settings */
    1831 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    1832 SCIP_LP* lp, /**< current LP data */
    1833 SCIP_ROW* row, /**< LP row */
    1834 SCIP_Real val, /**< value of coefficient */
    1835 int linkpos /**< position of column in the row's col array, or -1 */
    1836 )
    1837{
    1838 int pos;
    1839
    1840 assert(blkmem != NULL);
    1841 assert(col != NULL);
    1842 assert(col->nlprows <= col->len);
    1843 assert(col->var != NULL);
    1844 assert(row != NULL);
    1845 assert(!SCIPsetIsZero(set, val));
    1846 /*assert(colSearchCoef(col, row) == -1);*/ /* this assert would lead to slight differences in the solution process */
    1847
    1848 SCIP_CALL( colEnsureSize(col, blkmem, set, col->len+1) );
    1849 assert(col->rows != NULL);
    1850 assert(col->vals != NULL);
    1851 assert(col->linkpos != NULL);
    1852
    1853 pos = col->len;
    1854 col->len++;
    1855
    1856 /* if the row is in current LP and is linked to the column, we have to insert it at the end of the linked LP rows
    1857 * part of the column's arrays
    1858 */
    1859 if( row->lppos >= 0 && linkpos >= 0 )
    1860 {
    1861 /* move the first non-LP/not linked row to the end */
    1862 if( col->nlprows < pos )
    1863 {
    1864 colMoveCoef(col, col->nlprows, pos);
    1865 pos = col->nlprows;
    1866 }
    1867 col->nlprows++;
    1868 }
    1869
    1870 /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
    1871 if( !set->exact_enable )
    1872 val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
    1873
    1874 /* insert the row at the correct position and update the links */
    1875 col->rows[pos] = row;
    1876 col->vals[pos] = val;
    1877 col->linkpos[pos] = linkpos;
    1878 if( linkpos == -1 )
    1879 {
    1880 col->nunlinked++;
    1881
    1882 /* if the column is in current LP, we have to link it to the row, because otherwise, the primal information
    1883 * of the row is not complete
    1884 */
    1885 if( col->lppos >= 0 )
    1886 {
    1887 /* this call might swap the current row with the first non-LP/not linked row, s.t. insertion position
    1888 * has to be updated
    1889 */
    1890 SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, val, pos) );
    1891 if( row->lppos >= 0 )
    1892 pos = col->nlprows-1;
    1893 linkpos = col->linkpos[pos];
    1894
    1895 assert(0 <= linkpos && linkpos < row->len);
    1896 assert(row->cols[linkpos] == col);
    1897 assert(col->rows[pos] == row);
    1898 assert(col->rows[pos]->cols[col->linkpos[pos]] == col);
    1899 assert(col->rows[pos]->linkpos[col->linkpos[pos]] == pos);
    1900 }
    1901 }
    1902 else
    1903 {
    1904 assert(row->linkpos[linkpos] == -1);
    1905 assert(row->nunlinked > 0);
    1906 row->linkpos[linkpos] = pos;
    1907 row->nunlinked--;
    1908
    1909 /* if the column is in current LP, now both conditions, row->cols[linkpos]->lppos >= 0 and row->linkpos[linkpos] >= 0
    1910 * hold, so we have to move the column to the linked LP-cols part of the row's cols array
    1911 */
    1912 if( col->lppos >= 0 )
    1913 {
    1914 row->nlpcols++;
    1915 rowSwapCoefs(row, linkpos, row->nlpcols-1);
    1916
    1917 /* if no swap was necessary, mark nonlpcols to be unsorted */
    1918 if( linkpos == row->nlpcols-1 )
    1919 row->lpcolssorted = FALSE;
    1920 }
    1921 }
    1922
    1923 /* update the sorted flags */
    1924 if( row->lppos >= 0 && linkpos >= 0 )
    1925 {
    1926 assert(col->nlprows >= 1);
    1927 assert(col->rows[col->nlprows-1] == row);
    1928 if( col->nlprows > 1 )
    1929 col->lprowssorted = col->lprowssorted && (col->rows[col->nlprows-2]->index < row->index);
    1930 }
    1931 else
    1932 {
    1933 assert(col->len - col->nlprows >= 1);
    1934 assert(col->rows[col->len-1] == row);
    1935 if( col->len - col->nlprows > 1 )
    1936 col->nonlprowssorted = col->nonlprowssorted && (col->rows[col->len-2]->index < row->index);
    1937 }
    1938
    1939 coefChanged(row, col, lp);
    1940
    1941 SCIPsetDebugMsg(set, "added coefficient %g * <%s> at position %d (%d/%d) to column <%s> (nunlinked=%d)\n",
    1942 val, row->name, pos, col->nlprows, col->len, SCIPvarGetName(col->var), col->nunlinked);
    1943
    1944 return SCIP_OKAY;
    1945}
    1946
    1947/** deletes coefficient at given position from column */
    1948static
    1950 SCIP_COL* col, /**< column to be changed */
    1951 SCIP_SET* set, /**< global SCIP settings */
    1952 SCIP_LP* lp, /**< current LP data */
    1953 int pos /**< position in column vector to delete */
    1954 )
    1955{
    1956 SCIP_ROW* row;
    1957
    1958 assert(col != NULL);
    1959 assert(col->var != NULL);
    1960 assert(set != NULL);
    1961 assert(0 <= pos && pos < col->len);
    1962 assert(col->rows[pos] != NULL);
    1963 assert(col->linkpos[pos] == -1 || col->rows[pos]->cols[col->linkpos[pos]] == col);
    1964 assert((pos < col->nlprows) == (col->linkpos[pos] >= 0 && col->rows[pos]->lppos >= 0));
    1965
    1966 row = col->rows[pos];
    1967 assert((row->lppos >= 0) == (pos < col->nlprows));
    1968
    1969 /*SCIPsetDebugMsg(set, "deleting coefficient %g * <%s> at position %d from column <%s>\n",
    1970 col->vals[pos], row->name, pos, SCIPvarGetName(col->var));*/
    1971
    1972 if( col->linkpos[pos] == -1 )
    1973 col->nunlinked--;
    1974
    1975 /* if row is a linked LP row, move last linked LP coefficient to position of empty slot (deleted coefficient) */
    1976 if( pos < col->nlprows )
    1977 {
    1978 colMoveCoef(col, col->nlprows-1, pos);
    1979 col->nlprows--;
    1980 pos = col->nlprows;
    1981 }
    1982
    1983 /* move last coefficient to position of empty slot */
    1984 colMoveCoef(col, col->len-1, pos);
    1985 col->len--;
    1986
    1987 coefChanged(row, col, lp);
    1988
    1989 return SCIP_OKAY;
    1990}
    1991
    1992/** changes a coefficient at given position of an LP column */
    1993static
    1995 SCIP_COL* col, /**< LP column */
    1996 SCIP_SET* set, /**< global SCIP settings */
    1997 SCIP_LP* lp, /**< current LP data */
    1998 int pos, /**< position in column vector to change */
    1999 SCIP_Real val /**< value of coefficient */
    2000 )
    2001{
    2002 assert(col != NULL);
    2003 assert(col->var != NULL);
    2004 assert(0 <= pos && pos < col->len);
    2005 assert(col->rows[pos] != NULL);
    2006 assert(col->linkpos[pos] == -1 || col->rows[pos]->cols[col->linkpos[pos]] == col);
    2007
    2008 /*debugMsg(scip, "changing coefficient %g * <%s> at position %d of column <%s> to %g\n",
    2009 col->vals[pos], col->rows[pos]->name, pos, SCIPvarGetName(col->var), val);*/
    2010
    2011 /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
    2012 if( !set->exact_enable )
    2013 val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
    2014
    2015 if( SCIPsetIsZero(set, val) )
    2016 {
    2017 /* delete existing coefficient */
    2018 SCIP_CALL( colDelCoefPos(col, set, lp, pos) );
    2019 }
    2020 else if( !SCIPsetIsEQ(set, col->vals[pos], val) )
    2021 {
    2022 /* change existing coefficient */
    2023 col->vals[pos] = val;
    2024 coefChanged(col->rows[pos], col, lp);
    2025 }
    2026
    2027 return SCIP_OKAY;
    2028}
    2029
    2030
    2031
    2032
    2033/*
    2034 * local row changing methods
    2035 */
    2036
    2037/** update row norms after addition of coefficient */
    2038static
    2040 SCIP_ROW* row, /**< LP row */
    2041 SCIP_SET* set, /**< global SCIP settings */
    2042 SCIP_COL* col, /**< column of added coefficient */
    2043 SCIP_Real val, /**< value of added coefficient */
    2044 SCIP_Bool updateidxvals /**< update min/max idx and min/max val? */
    2045 )
    2046{
    2047 SCIP_Real absval;
    2048
    2049 assert(row != NULL);
    2050 assert(row->nummaxval >= 0);
    2051 assert(row->numminval >= 0);
    2052 assert(set != NULL);
    2053 assert(col != NULL);
    2054
    2055 absval = REALABS(val);
    2056 assert(!SCIPsetIsZero(set, absval));
    2057
    2058 /* Euclidean norm, sum norm, and objective function scalar product only take LP columns into account */
    2059 if( col->lppos >= 0 )
    2060 {
    2061 /* update squared Euclidean norm and sum norm */
    2062 row->sqrnorm += SQR(absval);
    2063 row->sumnorm += absval;
    2064
    2065 /* update objective function scalar product */
    2066 row->objprod += val * col->unchangedobj;
    2067 }
    2068
    2069 if( updateidxvals )
    2070 {
    2071 /* update min/maxidx */
    2072 row->minidx = MIN(row->minidx, col->index);
    2073 row->maxidx = MAX(row->maxidx, col->index);
    2074
    2075 /* update maximal and minimal non-zero value */
    2076 if( row->nummaxval > 0 )
    2077 {
    2078 if( SCIPsetIsGT(set, absval, row->maxval) )
    2079 {
    2080 row->maxval = absval;
    2081 row->nummaxval = 1;
    2082 }
    2083 else if( SCIPsetIsGE(set, absval, row->maxval) )
    2084 {
    2085 /* make sure the maxval is always exactly the same */
    2086 row->maxval = MAX(absval, row->maxval);
    2087 row->nummaxval++;
    2088 }
    2089 }
    2090 if( row->numminval > 0 )
    2091 {
    2092 if( SCIPsetIsLT(set, absval, row->minval) )
    2093 {
    2094 row->minval = absval;
    2095 row->numminval = 1;
    2096 }
    2097 else if( SCIPsetIsLE(set, absval, row->minval) )
    2098 {
    2099 /* make sure the minval is always exactly the same */
    2100 row->minval = MIN(absval, row->minval);
    2101 row->numminval++;
    2102 }
    2103 }
    2104 }
    2105 else
    2106 {
    2107 assert(row->minidx <= col->index);
    2108 assert(row->maxidx >= col->index);
    2109 assert(row->numminval <= 0 || absval >= row->minval);
    2110 assert(row->nummaxval <= 0 || absval <= row->maxval);
    2111 }
    2112}
    2113
    2114/** update row norms after deletion of coefficient */
    2115static
    2117 SCIP_ROW* row, /**< LP row */
    2118 SCIP_SET* set, /**< global SCIP settings */
    2119 SCIP_COL* col, /**< column of deleted coefficient */
    2120 SCIP_Real val, /**< value of deleted coefficient */
    2121 SCIP_Bool forcenormupdate, /**< should the norms be updated even if lppos of column is -1? */
    2122 SCIP_Bool updateindex, /**< should the minimal/maximal column index of row be updated? */
    2123 SCIP_Bool updateval /**< should the minimal/maximal value of row be updated? */
    2124 )
    2125{
    2126 SCIP_Real absval;
    2127
    2128 assert(row != NULL);
    2129 assert(row->nummaxval >= 0);
    2130 assert(row->numminval >= 0);
    2131 assert(set != NULL);
    2132 assert(col != NULL);
    2133
    2134 absval = REALABS(val);
    2135 assert(!SCIPsetIsZero(set, absval));
    2136 assert(row->nummaxval == 0 || row->maxval >= absval);
    2137 assert(row->numminval == 0 || row->minval <= absval);
    2138
    2139 /* update min/maxidx validity */
    2140 if( updateindex && (col->index == row->minidx || col->index == row->maxidx) )
    2141 row->validminmaxidx = FALSE;
    2142
    2143 /* Euclidean norm, sum norm, and objective function scalar product only take LP columns into account */
    2144 if( forcenormupdate || col->lppos >= 0 )
    2145 {
    2146 /* update squared Euclidean norm and sum norm */
    2147 row->sqrnorm -= SQR(absval);
    2148 row->sqrnorm = MAX(row->sqrnorm, 0.0);
    2149 row->sumnorm -= absval;
    2150 row->sumnorm = MAX(row->sumnorm, 0.0);
    2151
    2152 /* update objective function scalar product */
    2153 row->objprod -= val * col->unchangedobj;
    2154 }
    2155
    2156 if( updateval )
    2157 {
    2158 /* update maximal and minimal non-zero value */
    2159 if( row->nummaxval > 0 )
    2160 {
    2161 if( SCIPsetIsGE(set, absval, row->maxval) )
    2162 row->nummaxval--;
    2163 }
    2164 if( row->numminval > 0 )
    2165 {
    2166 if( SCIPsetIsLE(set, absval, row->minval) )
    2167 row->numminval--;
    2168 }
    2169 }
    2170}
    2171
    2172/** adds a previously non existing coefficient to an LP row */
    2173static
    2175 SCIP_ROW* row, /**< LP row */
    2176 BMS_BLKMEM* blkmem, /**< block memory */
    2177 SCIP_SET* set, /**< global SCIP settings */
    2178 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    2179 SCIP_LP* lp, /**< current LP data */
    2180 SCIP_COL* col, /**< LP column */
    2181 SCIP_Real val, /**< value of coefficient */
    2182 int linkpos /**< position of row in the column's row array, or -1 */
    2183 )
    2184{
    2185 int pos;
    2186
    2187 assert(row != NULL);
    2188 assert(row->nlpcols <= row->len);
    2189 assert(blkmem != NULL);
    2190 assert(col != NULL);
    2191 assert(col->var != NULL);
    2192 assert(col->var_probindex == SCIPvarGetProbindex(col->var));
    2193 assert(!SCIPsetIsZero(set, val));
    2194 /*assert(rowSearchCoef(row, col) == -1);*/ /* this assert would lead to slight differences in the solution process */
    2195
    2196 if( row->nlocks > 0 )
    2197 {
    2198 SCIPerrorMessage("cannot add a coefficient to the locked unmodifiable row <%s>\n", row->name);
    2199 return SCIP_INVALIDDATA;
    2200 }
    2201
    2202 SCIP_CALL( SCIProwEnsureSize(row, blkmem, set, row->len+1) );
    2203 assert(row->cols != NULL);
    2204 assert(row->vals != NULL);
    2205
    2206 pos = row->len;
    2207 row->len++;
    2208
    2209 /* if the column is in current LP and is linked to the row, we have to insert it at the end of the linked LP columns
    2210 * part of the row's arrays
    2211 */
    2212 if( col->lppos >= 0 && linkpos >= 0 )
    2213 {
    2214 /* move the first non-LP/not linked column to the end */
    2215 if( row->nlpcols < pos )
    2216 {
    2217 rowMoveCoef(row, row->nlpcols, pos);
    2218 pos = row->nlpcols;
    2219 }
    2220 row->nlpcols++;
    2221 }
    2222
    2223 /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
    2224 if( !set->exact_enable )
    2225 val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
    2226
    2227 /* insert the column at the correct position and update the links */
    2228 row->cols[pos] = col;
    2229 row->cols_index[pos] = col->index;
    2230 row->vals[pos] = val;
    2231 row->linkpos[pos] = linkpos;
    2232 row->integral = row->integral && SCIPcolIsIntegral(col) && SCIPsetIsIntegral(set, val);
    2233 if( set->exact_enable )
    2235 if( linkpos == -1 )
    2236 {
    2237 row->nunlinked++;
    2238
    2239 /* if the row is in current LP, we have to link it to the column, because otherwise, the dual information
    2240 * of the column is not complete
    2241 */
    2242 if( row->lppos >= 0 )
    2243 {
    2244 /* this call might swap the current column with the first non-LP/not linked column, s.t. insertion position
    2245 * has to be updated
    2246 */
    2247 SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, val, pos) );
    2248 if( col->lppos >= 0 )
    2249 pos = row->nlpcols-1;
    2250 linkpos = row->linkpos[pos];
    2251
    2252 assert(0 <= linkpos && linkpos < col->len);
    2253 assert(col->rows[linkpos] == row);
    2254 assert(row->cols[pos] == col);
    2255 assert(row->cols[pos]->rows[row->linkpos[pos]] == row);
    2256 assert(row->cols[pos]->linkpos[row->linkpos[pos]] == pos);
    2257 }
    2258 }
    2259 else
    2260 {
    2261 assert(col->linkpos[linkpos] == -1);
    2262 assert(col->nunlinked > 0);
    2263 col->linkpos[linkpos] = pos;
    2264 col->nunlinked--;
    2265
    2266 /* if the row is in current LP, now both conditions, col->rows[linkpos]->lppos >= 0 and col->linkpos[linkpos] >= 0
    2267 * hold, so we have to move the row to the linked LP-rows part of the column's rows array
    2268 */
    2269 if( row->lppos >= 0 )
    2270 {
    2271 col->nlprows++;
    2272 colSwapCoefs(col, linkpos, col->nlprows-1);
    2273
    2274 /* if no swap was necessary, mark lprows to be unsorted */
    2275 if( linkpos == col->nlprows-1 )
    2276 col->lprowssorted = FALSE;
    2277 }
    2278 }
    2279
    2280 /* update the sorted flags */
    2281 if( col->lppos >= 0 && linkpos >= 0 )
    2282 {
    2283 assert(row->nlpcols >= 1);
    2284 assert(row->cols[row->nlpcols-1] == col);
    2285 if( row->nlpcols > 1 )
    2286 {
    2287 assert(row->cols_index[row->nlpcols-2] == row->cols[row->nlpcols-2]->index);
    2288 row->lpcolssorted = row->lpcolssorted && (row->cols_index[row->nlpcols-2] < col->index);
    2289 }
    2290 }
    2291 else
    2292 {
    2293 assert(row->len - row->nlpcols >= 1);
    2294 assert(row->cols[row->len-1] == col);
    2295 if( row->len - row->nlpcols > 1 )
    2296 {
    2297 assert(row->cols_index[row->len-2] == row->cols[row->len-2]->index);
    2298 row->nonlpcolssorted = row->nonlpcolssorted && (row->cols_index[row->len-2] < col->index);
    2299 }
    2300 }
    2301
    2302 /* update row norm */
    2303 rowAddNorms(row, set, col, val, TRUE);
    2304
    2305 coefChanged(row, col, lp);
    2306
    2307 SCIPsetDebugMsg(set, "added coefficient %g * <%s> at position %d (%d/%d) to row <%s> (nunlinked=%d)\n",
    2308 val, SCIPvarGetName(col->var), pos, row->nlpcols, row->len, row->name, row->nunlinked);
    2309
    2310 /* issue row coefficient changed event */
    2311 SCIP_CALL( rowEventCoefChanged(row, blkmem, set, eventqueue, col, 0.0, val) );
    2312
    2313 return SCIP_OKAY;
    2314}
    2315
    2316/** deletes coefficient at given position from row */
    2317static
    2319 SCIP_ROW* row, /**< row to be changed */
    2320 BMS_BLKMEM* blkmem, /**< block memory */
    2321 SCIP_SET* set, /**< global SCIP settings */
    2322 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    2323 SCIP_LP* lp, /**< current LP data */
    2324 int pos /**< position in row vector to delete */
    2325 )
    2326{
    2327 SCIP_COL* col;
    2328 SCIP_Real val;
    2329
    2330 assert(row != NULL);
    2331 assert(set != NULL);
    2332 assert(0 <= pos && pos < row->len);
    2333 assert(row->cols[pos] != NULL);
    2334 assert((pos < row->nlpcols) == (row->linkpos[pos] >= 0 && row->cols[pos]->lppos >= 0));
    2335
    2336 col = row->cols[pos];
    2337 val = row->vals[pos];
    2338 assert((pos < row->nlpcols) == (col->lppos >= 0 && row->linkpos[pos] >= 0));
    2339
    2340 /*SCIPsetDebugMsg(set, "deleting coefficient %g * <%s> at position %d from row <%s>\n",
    2341 val, SCIPvarGetName(col->var), pos, row->name);*/
    2342
    2343 if( row->nlocks > 0 )
    2344 {
    2345 SCIPerrorMessage("cannot delete a coefficient from the locked unmodifiable row <%s>\n", row->name);
    2346 return SCIP_INVALIDDATA;
    2347 }
    2348
    2349 if( row->linkpos[pos] == -1 )
    2350 row->nunlinked--;
    2351
    2352 /* if column is a linked LP column, move last linked LP coefficient to position of empty slot (deleted coefficient) */
    2353 if( pos < row->nlpcols )
    2354 {
    2355 rowMoveCoef(row, row->nlpcols-1, pos);
    2356 row->nlpcols--;
    2357 pos = row->nlpcols;
    2358 }
    2359
    2360 /* move last coefficient to position of empty slot */
    2361 rowMoveCoef(row, row->len-1, pos);
    2362 row->len--;
    2363
    2364 /* update norms */
    2365 rowDelNorms(row, set, col, val, FALSE, TRUE, TRUE);
    2366
    2367 coefChanged(row, col, lp);
    2368
    2369 /* issue row coefficient changed event */
    2370 SCIP_CALL( rowEventCoefChanged(row, blkmem, set, eventqueue, col, val, 0.0) );
    2371
    2372 return SCIP_OKAY;
    2373}
    2374
    2375/** changes a coefficient at given position of an LP row */
    2376static
    2378 SCIP_ROW* row, /**< LP row */
    2379 BMS_BLKMEM* blkmem, /**< block memory */
    2380 SCIP_SET* set, /**< global SCIP settings */
    2381 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    2382 SCIP_LP* lp, /**< current LP data */
    2383 int pos, /**< position in row vector to change */
    2384 SCIP_Real val /**< value of coefficient */
    2385 )
    2386{
    2387 SCIP_COL* col;
    2388
    2389 assert(row != NULL);
    2390 assert(0 <= pos && pos < row->len);
    2391
    2392 /*SCIPsetDebugMsg(set, "changing coefficient %g * <%s> at position %d of row <%s> to %g\n",
    2393 row->vals[pos], SCIPvarGetName(row->cols[pos]->var), pos, row->name, val);*/
    2394
    2395 if( row->nlocks > 0 )
    2396 {
    2397 SCIPerrorMessage("cannot change a coefficient of the locked unmodifiable row <%s>\n", row->name);
    2398 return SCIP_INVALIDDATA;
    2399 }
    2400
    2401 /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
    2402 if( !set->exact_enable )
    2403 val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
    2404 col = row->cols[pos];
    2405 assert(row->cols[pos] != NULL);
    2406
    2407 if( SCIPsetIsZero(set, val) )
    2408 {
    2409 /* delete existing coefficient */
    2410 SCIP_CALL( rowDelCoefPos(row, blkmem, set, eventqueue, lp, pos) );
    2411 }
    2412 else if( !SCIPsetIsEQ(set, row->vals[pos], val) || (set->exact_enable && row->vals[pos] != val) ) /*lint !e777*/
    2413 {
    2414 SCIP_Real oldval;
    2415
    2416 oldval = row->vals[pos];
    2417
    2418 /* change existing coefficient */
    2419 rowDelNorms(row, set, col, row->vals[pos], FALSE, FALSE, TRUE);
    2420 row->vals[pos] = val;
    2421 row->integral = row->integral && SCIPcolIsIntegral(col) && SCIPsetIsIntegral(set, val);
    2422 if( set->exact_enable )
    2424 rowAddNorms(row, set, col, row->vals[pos], TRUE);
    2425 coefChanged(row, col, lp);
    2426
    2427 /* issue row coefficient changed event */
    2428 SCIP_CALL( rowEventCoefChanged(row, blkmem, set, eventqueue, col, oldval, val) );
    2429 }
    2430
    2431 return SCIP_OKAY;
    2432}
    2433
    2434/** notifies LP row, that its sides were changed */
    2435static
    2437 SCIP_ROW* row, /**< LP row */
    2438 SCIP_SET* set, /**< global SCIP settings */
    2439 SCIP_LP* lp, /**< current LP data */
    2440 SCIP_SIDETYPE sidetype /**< type of side: left or right hand side */
    2441 )
    2442{
    2443 assert(row != NULL);
    2444 assert(lp != NULL);
    2445
    2446 if( row->lpipos >= 0 )
    2447 {
    2448 /* insert row in the chgrows list (if not already there) */
    2449 if( !row->lhschanged && !row->rhschanged )
    2450 {
    2451 SCIP_CALL( ensureChgrowsSize(lp, set, lp->nchgrows+1) );
    2452 lp->chgrows[lp->nchgrows] = row;
    2453 lp->nchgrows++;
    2454 }
    2455
    2456 /* mark side change in the row */
    2457 switch( sidetype )
    2458 {
    2459 case SCIP_SIDETYPE_LEFT:
    2460 row->lhschanged = TRUE;
    2461 break;
    2463 row->rhschanged = TRUE;
    2464 break;
    2465 default:
    2466 SCIPerrorMessage("unknown row side type\n");
    2467 SCIPABORT();
    2468 return SCIP_INVALIDDATA; /*lint !e527*/
    2469 }
    2470
    2471 /* mark the current LP unflushed */
    2472 lp->flushed = FALSE;
    2473
    2474 assert(lp->nchgrows > 0);
    2475 }
    2476
    2477 return SCIP_OKAY;
    2478}
    2479
    2480
    2481
    2482
    2483/*
    2484 * double linked coefficient matrix methods
    2485 */
    2486
    2487/** insert column coefficients in corresponding rows */
    2489 SCIP_COL* col, /**< column data */
    2490 BMS_BLKMEM* blkmem, /**< block memory */
    2491 SCIP_SET* set, /**< global SCIP settings */
    2492 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    2493 SCIP_LP* lp /**< current LP data */
    2494 )
    2495{
    2496 int i;
    2497
    2498 assert(col != NULL);
    2499 assert(col->var != NULL);
    2500 assert(blkmem != NULL);
    2501 assert(set != NULL);
    2502 assert(lp != NULL);
    2503
    2504 if( col->nunlinked > 0 )
    2505 {
    2506 SCIPsetDebugMsg(set, "linking column <%s>\n", SCIPvarGetName(col->var));
    2507
    2508 /* unlinked rows can only be in the non-LP/unlinked rows part of the rows array */
    2509 for( i = col->nlprows; i < col->len; ++i )
    2510 {
    2511 assert(!SCIPsetIsZero(set, col->vals[i]));
    2512 if( col->linkpos[i] == -1 )
    2513 {
    2514 /* this call might swap the current row with the first non-LP/not linked row, but this is of no harm */
    2515 SCIP_CALL( rowAddCoef(col->rows[i], blkmem, set, eventqueue, lp, col, col->vals[i], i) );
    2516 }
    2517 assert(col->rows[i]->cols[col->linkpos[i]] == col);
    2518 assert(col->rows[i]->linkpos[col->linkpos[i]] == i);
    2519 assert(col->nlprows == 0 || col->rows[col->nlprows-1]->cols[col->linkpos[col->nlprows-1]] == col);
    2520 assert(col->nlprows == 0 || col->rows[col->nlprows-1]->linkpos[col->linkpos[col->nlprows-1]] == col->nlprows-1);
    2521 }
    2522 }
    2523 assert(col->nunlinked == 0);
    2524
    2525 checkLinks(lp);
    2526
    2527 return SCIP_OKAY;
    2528}
    2529
    2530/** removes column coefficients from corresponding rows */
    2532 SCIP_COL* col, /**< column data */
    2533 BMS_BLKMEM* blkmem, /**< block memory */
    2534 SCIP_SET* set, /**< global SCIP settings */
    2535 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    2536 SCIP_LP* lp /**< current LP data */
    2537 )
    2538{
    2539 int i;
    2540
    2541 assert(col != NULL);
    2542 assert(col->var != NULL);
    2543 assert(blkmem != NULL);
    2544 assert(set != NULL);
    2545 assert(lp != NULL);
    2546
    2547 if( col->nunlinked < col->len )
    2548 {
    2549 SCIPsetDebugMsg(set, "unlinking column <%s>\n", SCIPvarGetName(col->var));
    2550 for( i = 0; i < col->len; ++i )
    2551 {
    2552 if( col->linkpos[i] >= 0 )
    2553 {
    2554 assert(col->rows[i]->cols[col->linkpos[i]] == col);
    2555 SCIP_CALL( rowDelCoefPos(col->rows[i], blkmem, set, eventqueue, lp, col->linkpos[i]) );
    2556 col->linkpos[i] = -1;
    2557 col->nunlinked++;
    2558 }
    2559 }
    2560 }
    2561 assert(col->nunlinked == col->len);
    2562
    2563 checkLinks(lp);
    2564
    2565 return SCIP_OKAY;
    2566}
    2567
    2568/** insert row coefficients in corresponding columns */
    2570 SCIP_ROW* row, /**< row data */
    2571 BMS_BLKMEM* blkmem, /**< block memory */
    2572 SCIP_SET* set, /**< global SCIP settings */
    2573 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    2574 SCIP_LP* lp /**< current LP data */
    2575 )
    2576{
    2577 int i;
    2578
    2579 assert(row != NULL);
    2580 assert(blkmem != NULL);
    2581 assert(set != NULL);
    2582 assert(lp != NULL);
    2583
    2584 if( row->nunlinked > 0 )
    2585 {
    2586 SCIPsetDebugMsg(set, "linking row <%s>\n", row->name);
    2587
    2588 /* unlinked columns can only be in the non-LP/unlinked columns part of the cols array */
    2589 for( i = row->nlpcols; i < row->len; ++i )
    2590 {
    2591 assert(!SCIPsetIsZero(set, row->vals[i]));
    2592 if( row->linkpos[i] == -1 )
    2593 {
    2594 /* this call might swap the current column with the first non-LP/not linked column, but this is of no harm */
    2595 SCIP_CALL( colAddCoef(row->cols[i], blkmem, set, eventqueue, lp, row, row->vals[i], i) );
    2596 }
    2597 assert(row->cols[i]->rows[row->linkpos[i]] == row);
    2598 assert(row->cols[i]->linkpos[row->linkpos[i]] == i);
    2599 assert(row->nlpcols == 0 || row->cols[row->nlpcols-1]->rows[row->linkpos[row->nlpcols-1]] == row);
    2600 assert(row->nlpcols == 0 || row->cols[row->nlpcols-1]->linkpos[row->linkpos[row->nlpcols-1]] == row->nlpcols-1);
    2601 }
    2602 }
    2603 assert(row->nunlinked == 0);
    2604
    2605 checkLinks(lp);
    2606
    2607 return SCIP_OKAY;
    2608}
    2609
    2610/** removes row coefficients from corresponding columns */
    2612 SCIP_ROW* row, /**< row data */
    2613 SCIP_SET* set, /**< global SCIP settings */
    2614 SCIP_LP* lp /**< current LP data */
    2615 )
    2616{
    2617 int i;
    2618
    2619 assert(row != NULL);
    2620 assert(set != NULL);
    2621 assert(lp != NULL);
    2622
    2623 if( row->nunlinked < row->len )
    2624 {
    2625 SCIPsetDebugMsg(set, "unlinking row <%s>\n", row->name);
    2626 for( i = 0; i < row->len; ++i )
    2627 {
    2628 if( row->linkpos[i] >= 0 )
    2629 {
    2630 assert(row->cols[i]->rows[row->linkpos[i]] == row);
    2631 SCIP_CALL( colDelCoefPos(row->cols[i], set, lp, row->linkpos[i]) );
    2632 row->nunlinked++;
    2633 }
    2634 }
    2635 }
    2636 assert(row->nunlinked == row->len);
    2637
    2638 return SCIP_OKAY;
    2639}
    2640
    2641
    2642
    2643
    2644/*
    2645 * local LP parameter methods
    2646 */
    2647
    2648/** sets parameter of type int in LP solver, ignoring unknown parameters */
    2649static
    2651 SCIP_LP* lp, /**< current LP data */
    2652 SCIP_LPPARAM lpparam, /**< LP parameter */
    2653 int value, /**< value to set parameter to */
    2654 SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
    2655 )
    2656{
    2657 SCIP_RETCODE retcode;
    2658
    2659 assert(lp != NULL);
    2660 assert(success != NULL);
    2661
    2662 retcode = SCIPlpiSetIntpar(lp->lpi, lpparam, value);
    2663
    2664 /* check, if parameter is unknown */
    2665 if( retcode == SCIP_PARAMETERUNKNOWN )
    2666 {
    2667 *success = FALSE;
    2668 return SCIP_OKAY;
    2669 }
    2670 *success = TRUE;
    2671
    2672 return retcode;
    2673}
    2674
    2675/** sets parameter of type SCIP_Bool in LP solver, ignoring unknown parameters */
    2676static
    2678 SCIP_LP* lp, /**< current LP data */
    2679 SCIP_LPPARAM lpparam, /**< LP parameter */
    2680 SCIP_Bool value, /**< value to set parameter to */
    2681 SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
    2682 )
    2683{
    2684 return lpSetIntpar(lp, lpparam, (int)value, success);
    2685}
    2686
    2687/** sets parameter of type SCIP_Real in LP solver, ignoring unknown parameters */
    2688static
    2690 SCIP_LP* lp, /**< current LP data */
    2691 SCIP_LPPARAM lpparam, /**< LP parameter */
    2692 SCIP_Real value, /**< value to set parameter to */
    2693 SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
    2694 )
    2695{
    2696 SCIP_RETCODE retcode;
    2697
    2698 assert(lp != NULL);
    2699 assert(success != NULL);
    2700
    2701 retcode = SCIPlpiSetRealpar(lp->lpi, lpparam, value);
    2702
    2703 /* check, if parameter is unknown */
    2704 if( retcode == SCIP_PARAMETERUNKNOWN )
    2705 {
    2706 *success = FALSE;
    2707 return SCIP_OKAY;
    2708 }
    2709 *success = TRUE;
    2710
    2711 return retcode;
    2712}
    2713
    2714#ifndef NDEBUG
    2715/** checks that parameter of type int in LP solver has the given value, ignoring unknown parameters */
    2716static
    2718 SCIP_LP* lp, /**< current LP data */
    2719 SCIP_LPPARAM lpparam, /**< LP parameter */
    2720 int value /**< value parameter should have */
    2721 )
    2722{
    2723 SCIP_RETCODE retcode;
    2724 int lpivalue;
    2725
    2726 assert(lp != NULL);
    2727
    2728 retcode = SCIPlpiGetIntpar(lp->lpi, lpparam, &lpivalue);
    2729
    2730 /* ignore unknown parameter error */
    2731 if( retcode == SCIP_PARAMETERUNKNOWN )
    2732 return SCIP_OKAY;
    2733
    2734 /* check value */
    2735 assert(lpivalue == value);
    2736
    2737 return retcode;
    2738}
    2739
    2740/** checks that parameter of type SCIP_Bool in LP solver has the given value, ignoring unknown parameters */
    2741static
    2743 SCIP_LP* lp, /**< current LP data */
    2744 SCIP_LPPARAM lpparam, /**< LP parameter */
    2745 SCIP_Bool value /**< value parameter should have */
    2746 )
    2747{
    2748 return lpCheckIntpar(lp, lpparam, (int)value);
    2749}
    2750
    2751/** checks that parameter of type SCIP_Real in LP solver has the given value, ignoring unknown parameters */
    2752static
    2754 SCIP_LP* lp, /**< current LP data */
    2755 SCIP_LPPARAM lpparam, /**< LP parameter */
    2756 SCIP_Real value /**< value parameter should have */
    2757 )
    2758{
    2759 SCIP_RETCODE retcode;
    2760 SCIP_Real lpivalue;
    2761
    2762 assert(lp != NULL);
    2763
    2764 retcode = SCIPlpiGetRealpar(lp->lpi, lpparam, &lpivalue);
    2765
    2766 /* ignore unknown parameter error */
    2767 if( retcode == SCIP_PARAMETERUNKNOWN )
    2768 return SCIP_OKAY;
    2769
    2770 /* check value */
    2771 assert(lpivalue == value); /*lint !e777*/
    2772
    2773 return retcode;
    2774}
    2775#else
    2776#define lpCheckIntpar(lp, lpparam, value) SCIP_OKAY
    2777#define lpCheckBoolpar(lp, lpparam, value) SCIP_OKAY
    2778#define lpCheckRealpar(lp, lpparam, value) SCIP_OKAY
    2779#endif
    2780
    2781/** should the objective limit of the LP solver be disabled */
    2782#define lpCutoffDisabled(set, prob, lp) (set->lp_disablecutoff == 1 || (set->lp_disablecutoff == 2 && !SCIPprobAllColsInLP(prob, set, lp)))
    2783
    2784/** sets the objective limit of the LP solver
    2785 *
    2786 * Note that we are always minimizing.
    2787 */
    2788static
    2790 SCIP_LP* lp, /**< current LP data */
    2791 SCIP_SET* set, /**< global SCIP settings */
    2792 SCIP_PROB* prob, /**< problem data */
    2793 SCIP_Real objlim, /**< new objective limit */
    2794 SCIP_Bool* success /**< pointer to store whether the parameter was actually changed */
    2795 )
    2796{
    2797 assert(lp != NULL);
    2798 assert(set != NULL);
    2799 assert(success != NULL);
    2800
    2801 *success = FALSE;
    2802
    2803 /* if the objective limit is disabled or SCIP infinity, make sure that the LP objective limit is deactivated by
    2804 * setting it to the LP solver's infinity
    2805 */
    2806 if( lpCutoffDisabled(set, prob, lp) || SCIPsetIsInfinity(set, objlim) )
    2807 objlim = SCIPlpiInfinity(lp->lpi);
    2808
    2810
    2811 if( objlim != lp->lpiobjlim ) /*lint !e777*/
    2812 {
    2813 SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_OBJLIM, objlim, success) );
    2814 if( *success )
    2815 {
    2816 SCIP_Real actualobjlim;
    2817
    2818 /* check whether the parameter was actually changed or already was at the boundary of the LP solver's parameter range */
    2819 SCIP_CALL( SCIPlpiGetRealpar(lp->lpi, SCIP_LPPAR_OBJLIM, &actualobjlim) );
    2820 if( actualobjlim != lp->lpiobjlim ) /*lint !e777*/
    2821 {
    2822 /* mark the current solution invalid */
    2823 lp->solved = FALSE;
    2824 lp->primalfeasible = FALSE;
    2825 lp->primalchecked = FALSE;
    2826 lp->lpobjval = SCIP_INVALID;
    2828 }
    2829 lp->lpiobjlim = actualobjlim;
    2830 }
    2831 }
    2832
    2833 return SCIP_OKAY;
    2834}
    2835
    2836/** adjust the objective limit of the lp solver to make safe dual bounding possible
    2837 *
    2838 * Note that we are always minimizing.
    2839 */
    2840static
    2842 SCIP_LP* lp, /**< current LP data */
    2843 SCIP_SET* set, /**< global SCIP settings */
    2844 SCIP_PROB* prob, /**< problem data */
    2845 SCIP_STAT* stat, /**< problem statistics */
    2846 SCIP_Bool* success /**< pointer to store whether the parameter was actually changed */
    2847 )
    2848{
    2849 SCIP_Real adjustedobjlim;
    2850 SCIP_Real avgboundingerror;
    2851
    2852 assert(lp != NULL);
    2853 assert(set != NULL);
    2854 assert(success != NULL);
    2855
    2856 *success = FALSE;
    2857
    2858 /* we disabled the objective limit in the LP solver or we are not in exact solving mode */
    2859 if( !set->exact_enable || lpCutoffDisabled(set, prob, lp) )
    2860 return SCIP_OKAY;
    2861
    2862 /* no need to adjust in infinity case */
    2863 if( SCIPsetIsInfinity(set, lp->lpiobjlim) )
    2864 return SCIP_OKAY;
    2865
    2867
    2868 if( stat->nboundshift + stat->nprojshift + stat->nexlp == 0 )
    2869 avgboundingerror = 1.0;
    2870 else
    2871 avgboundingerror = (stat->boundingerrorbs + stat->boundingerrorps + stat->boundingerrorexlp) / (stat->nboundshift + stat->nprojshift + stat->nexlp);
    2872 adjustedobjlim = lp->lpiobjlim + MAX(avgboundingerror, 1e-6);
    2873
    2874 SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_OBJLIM, adjustedobjlim, success) );
    2875 if( *success )
    2876 {
    2877 SCIP_Real actualobjlim;
    2878
    2879 /* check whether the parameter was actually changed or already was at the boundary of the LP solver's parameter range */
    2880 SCIP_CALL( SCIPlpiGetRealpar(lp->lpi, SCIP_LPPAR_OBJLIM, &actualobjlim) );
    2881 if( actualobjlim != lp->lpiobjlim ) /*lint !e777*/
    2882 {
    2883 /* mark the current solution invalid */
    2884 lp->solved = FALSE;
    2885 lp->primalfeasible = FALSE;
    2886 lp->primalchecked = FALSE;
    2887 lp->lpobjval = SCIP_INVALID;
    2889 }
    2890 lp->lpiobjlim = actualobjlim;
    2891 }
    2892
    2893 return SCIP_OKAY;
    2894}
    2895
    2896
    2897/** sets the feasibility tolerance of the LP solver */
    2898static
    2900 SCIP_LP* lp, /**< current LP data */
    2901 SCIP_Real feastol, /**< new feasibility tolerance */
    2902 SCIP_Bool* success /**< pointer to store whether the parameter was actually changed */
    2903 )
    2904{
    2905 assert(lp != NULL);
    2906 assert(feastol >= 0.0);
    2907 assert(success != NULL);
    2908
    2910
    2911 if( feastol != lp->lpifeastol ) /*lint !e777*/
    2912 {
    2913 SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_FEASTOL, feastol, success) );
    2914 if( *success )
    2915 {
    2916 SCIP_Real actualfeastol;
    2917
    2918 /* check whether the parameter was actually changed or already was at the boundary of the LP solver's parameter range */
    2919 SCIP_CALL( SCIPlpiGetRealpar(lp->lpi, SCIP_LPPAR_FEASTOL, &actualfeastol) );
    2920 if( lp->nrows > 0 && actualfeastol < lp->lpifeastol )
    2921 {
    2922 /* mark the current solution invalid */
    2923 lp->solved = FALSE;
    2924 lp->primalfeasible = FALSE;
    2925 lp->primalchecked = FALSE;
    2926 lp->lpobjval = SCIP_INVALID;
    2928 }
    2929 else
    2930 *success = FALSE;
    2931 lp->lpifeastol = actualfeastol;
    2932 }
    2933 }
    2934 else
    2935 *success = FALSE;
    2936
    2937 return SCIP_OKAY;
    2938}
    2939
    2940/** sets the reduced costs feasibility tolerance of the LP solver */
    2941static
    2943 SCIP_LP* lp, /**< current LP data */
    2944 SCIP_Real dualfeastol, /**< new reduced costs feasibility tolerance */
    2945 SCIP_Bool* success /**< pointer to store whether the parameter was actually changed */
    2946 )
    2947{
    2948 assert(lp != NULL);
    2949 assert(dualfeastol >= 0.0);
    2950 assert(success != NULL);
    2951
    2953
    2954 if( dualfeastol != lp->lpidualfeastol ) /*lint !e777*/
    2955 {
    2956 SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_DUALFEASTOL, dualfeastol, success) );
    2957 if( *success )
    2958 {
    2959 SCIP_Real actualdualfeastol;
    2960
    2961 /* check whether the parameter was actually changed or already was at the boundary of the LP solver's parameter range */
    2962 SCIP_CALL( SCIPlpiGetRealpar(lp->lpi, SCIP_LPPAR_DUALFEASTOL, &actualdualfeastol) );
    2963 if( lp->nrows > 0 && actualdualfeastol < lp->lpidualfeastol )
    2964 {
    2965 /* mark the current solution invalid */
    2966 lp->solved = FALSE;
    2967 lp->dualfeasible = FALSE;
    2968 lp->dualchecked = FALSE;
    2969 lp->lpobjval = SCIP_INVALID;
    2971 }
    2972 else
    2973 *success = FALSE;
    2974 lp->lpidualfeastol = actualdualfeastol;
    2975 }
    2976 }
    2977 else
    2978 *success = FALSE;
    2979
    2980 return SCIP_OKAY;
    2981}
    2982
    2983/** sets the convergence tolerance used in barrier algorithm of the LP solver */
    2984static
    2986 SCIP_LP* lp, /**< current LP data */
    2987 SCIP_Real barrierconvtol, /**< new convergence tolerance used in barrier algorithm */
    2988 SCIP_Bool* success /**< pointer to store whether the parameter was actually changed */
    2989 )
    2990{
    2991 assert(lp != NULL);
    2992 assert(barrierconvtol >= 0.0);
    2993 assert(success != NULL);
    2994
    2996
    2997 if( barrierconvtol != lp->lpibarrierconvtol ) /*lint !e777*/
    2998 {
    2999 SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_BARRIERCONVTOL, barrierconvtol, success) );
    3000 if( *success )
    3001 {
    3002 SCIP_Real actualbarrierconvtol;
    3003
    3004 /* check whether the parameter was actually changed or already was at the boundary of the LP solver's parameter range */
    3005 SCIP_CALL( SCIPlpiGetRealpar(lp->lpi, SCIP_LPPAR_BARRIERCONVTOL, &actualbarrierconvtol) );
    3006 if( lp->nrows > 0 && actualbarrierconvtol < lp->lpibarrierconvtol
    3008 {
    3009 /* mark the current solution invalid */
    3010 lp->solved = FALSE;
    3011 lp->dualfeasible = FALSE;
    3012 lp->dualchecked = FALSE;
    3013 lp->lpobjval = SCIP_INVALID;
    3015 }
    3016 else
    3017 *success = FALSE;
    3018 lp->lpibarrierconvtol = actualbarrierconvtol;
    3019 }
    3020 }
    3021 else
    3022 *success = FALSE;
    3023
    3024 return SCIP_OKAY;
    3025}
    3026
    3027/** sets the FROMSCRATCH setting of the LP solver */
    3028static
    3030 SCIP_LP* lp, /**< current LP data */
    3031 SCIP_Bool fromscratch, /**< new FROMSCRATCH setting */
    3032 SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
    3033 )
    3034{
    3035 assert(lp != NULL);
    3036 assert(success != NULL);
    3037
    3039
    3040 if( fromscratch != lp->lpifromscratch )
    3041 {
    3042 SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_FROMSCRATCH, fromscratch, success) );
    3043 if( *success )
    3044 lp->lpifromscratch = fromscratch;
    3045 }
    3046 else
    3047 *success = FALSE;
    3048
    3049 return SCIP_OKAY;
    3050}
    3051
    3052/** sets the FASTMIP setting of the LP solver */
    3053static
    3055 SCIP_LP* lp, /**< current LP data */
    3056 int fastmip, /**< new FASTMIP setting */
    3057 SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
    3058 )
    3059{
    3060 assert(lp != NULL);
    3061 assert(success != NULL);
    3062 assert(0 <= fastmip && fastmip <= 1);
    3063
    3065
    3066 if( fastmip != lp->lpifastmip )
    3067 {
    3068 SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_FASTMIP, fastmip, success) );
    3069 if( *success )
    3070 {
    3071 lp->lpifastmip = fastmip;
    3072 lp->solved = FALSE;
    3073 /* We might only set lp->solved to false if fastmip is turned off, since the latter should be the more
    3074 * demanding setting; however, in the current code, this should have not effect. */
    3075 }
    3076 }
    3077 else
    3078 *success = FALSE;
    3079
    3080 return SCIP_OKAY;
    3081}
    3082
    3083/** sets the SCALING setting of the LP solver */
    3084static
    3086 SCIP_LP* lp, /**< current LP data */
    3087 int scaling, /**< new SCALING setting */
    3088 SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
    3089 )
    3090{
    3091 assert(lp != NULL);
    3092 assert(success != NULL);
    3093
    3095
    3096 if( scaling != lp->lpiscaling )
    3097 {
    3098 SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_SCALING, scaling, success) );
    3099 if( *success )
    3100 lp->lpiscaling = scaling;
    3101 }
    3102 else
    3103 *success = FALSE;
    3104
    3105 return SCIP_OKAY;
    3106}
    3107
    3108/** sets the number of THREADS of the LP solver */
    3109static
    3111 SCIP_LP* lp, /**< current LP data */
    3112 int threads, /**< new number of threads used to solve the LP */
    3113 SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
    3114 )
    3115{
    3116 assert(lp != NULL);
    3117 assert(success != NULL);
    3118
    3120
    3121 if( threads != lp->lpithreads )
    3122 {
    3123 SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_THREADS, threads, success) );
    3124 if( *success )
    3125 lp->lpithreads = threads;
    3126 }
    3127 else
    3128 *success = FALSE;
    3129
    3130 return SCIP_OKAY;
    3131}
    3132
    3133/** sets the PRESOLVING setting of the LP solver */
    3134static
    3136 SCIP_LP* lp, /**< current LP data */
    3137 SCIP_Bool presolving, /**< new PRESOLVING setting */
    3138 SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
    3139 )
    3140{
    3141 assert(lp != NULL);
    3142 assert(success != NULL);
    3143
    3145
    3146 if( presolving != lp->lpipresolving )
    3147 {
    3148 SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_PRESOLVING, presolving, success) );
    3149 if( *success )
    3150 lp->lpipresolving = presolving;
    3151 }
    3152 else
    3153 *success = FALSE;
    3154
    3155 return SCIP_OKAY;
    3156}
    3157
    3158/** sets the ROWREPSWITCH setting of the LP solver */
    3159static
    3161 SCIP_LP* lp, /**< current LP data */
    3162 SCIP_Real rowrepswitch, /**< new ROWREPSWITCH value */
    3163 SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
    3164 )
    3165{
    3166 assert(lp != NULL);
    3167 assert(success != NULL);
    3168
    3170
    3171 if( rowrepswitch != lp->lpirowrepswitch ) /*lint !e777*/
    3172 {
    3173 SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_ROWREPSWITCH, rowrepswitch, success) );
    3174 if( *success )
    3175 lp->lpirowrepswitch = rowrepswitch;
    3176 }
    3177 else
    3178 *success = FALSE;
    3179
    3180 return SCIP_OKAY;
    3181}
    3182
    3183/** sets the iteration limit of the LP solver */
    3184static
    3186 SCIP_LP* lp, /**< current LP data */
    3187 int itlim /**< maximal number of LP iterations to perform, or -1 for no limit */
    3188 )
    3189{
    3190 SCIP_Bool success;
    3191
    3192 assert(lp != NULL);
    3193 assert(itlim >= -1);
    3194
    3195 if( itlim == -1 )
    3196 itlim = INT_MAX;
    3197
    3199
    3200 if( itlim != lp->lpiitlim )
    3201 {
    3202 SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_LPITLIM, itlim, &success) );
    3203 if( success )
    3204 {
    3205 if( itlim > lp->lpiitlim )
    3206 {
    3207 /* mark the current solution invalid */
    3208 lp->solved = FALSE;
    3209 lp->lpobjval = SCIP_INVALID;
    3211 }
    3212 lp->lpiitlim = itlim;
    3213 }
    3214 }
    3215
    3216 return SCIP_OKAY;
    3217}
    3218
    3219/** sets the pricing strategy of the LP solver */
    3220static
    3222 SCIP_LP* lp, /**< current LP data */
    3223 SCIP_PRICING pricing /**< pricing strategy */
    3224 )
    3225{
    3226 SCIP_Bool success;
    3227
    3228 assert(lp != NULL);
    3229
    3231
    3232 if( pricing != lp->lpipricing )
    3233 {
    3234 SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_PRICING, (int)pricing, &success) );
    3235 if( success )
    3236 lp->lpipricing = pricing;
    3237 }
    3238
    3239 return SCIP_OKAY;
    3240}
    3241
    3242/** sets the pricing strategy of the LP solver (given the character representation of the strategy) */
    3243static
    3245 SCIP_LP* lp, /**< current LP data */
    3246 char pricingchar /**< character representing the pricing strategy */
    3247 )
    3248{
    3249 SCIP_PRICING pricing;
    3250
    3251 switch( pricingchar )
    3252 {
    3253 case 'l':
    3254 pricing = SCIP_PRICING_LPIDEFAULT;
    3255 break;
    3256 case 'a':
    3257 pricing = SCIP_PRICING_AUTO;
    3258 break;
    3259 case 'f':
    3260 pricing = SCIP_PRICING_FULL;
    3261 break;
    3262 case 'p':
    3263 pricing = SCIP_PRICING_PARTIAL;
    3264 break;
    3265 case 's':
    3266 pricing = SCIP_PRICING_STEEP;
    3267 break;
    3268 case 'q':
    3269 pricing = SCIP_PRICING_STEEPQSTART;
    3270 break;
    3271 case 'd':
    3272 pricing = SCIP_PRICING_DEVEX;
    3273 break;
    3274 default:
    3275 SCIPerrorMessage("invalid LP pricing parameter <%c>\n", pricingchar);
    3276 return SCIP_INVALIDDATA;
    3277 }
    3278
    3279 SCIP_CALL( lpSetPricing(lp, pricing) );
    3280
    3281 return SCIP_OKAY;
    3282}
    3283
    3284/** sets the verbosity of the LP solver */
    3285static
    3287 SCIP_LP* lp, /**< current LP data */
    3288 SCIP_Bool lpinfo /**< should the LP solver display status messages? */
    3289 )
    3290{
    3291 SCIP_Bool success;
    3292
    3293 assert(lp != NULL);
    3294
    3296
    3297 if( lpinfo != lp->lpilpinfo )
    3298 {
    3299 SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_LPINFO, lpinfo, &success) );
    3300 if( success )
    3301 lp->lpilpinfo = lpinfo;
    3302 }
    3303
    3304 return SCIP_OKAY;
    3305}
    3306
    3307/** sets the CONDITIONLIMIT setting of the LP solver */
    3308static
    3310 SCIP_LP* lp, /**< current LP data */
    3311 SCIP_Real condlimit, /**< new CONDITIONLIMIT value */
    3312 SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
    3313 )
    3314{
    3315 assert(lp != NULL);
    3316 assert(success != NULL);
    3317
    3319
    3320 if( condlimit != lp->lpiconditionlimit ) /*lint !e777*/
    3321 {
    3322 SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_CONDITIONLIMIT, condlimit, success) );
    3323 if( *success )
    3324 lp->lpiconditionlimit = condlimit;
    3325 }
    3326 else
    3327 *success = FALSE;
    3328
    3329 return SCIP_OKAY;
    3330}
    3331
    3332/** sets the MARKOWITZ setting of the LP solver */
    3333static
    3335 SCIP_LP* lp, /**< current LP data */
    3336 SCIP_Real threshhold, /**< new MARKOWITZ value */
    3337 SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
    3338 )
    3339{
    3340 assert(lp != NULL);
    3341 assert(success != NULL);
    3342
    3344
    3345 if( threshhold != lp->lpimarkowitz ) /*lint !e777*/
    3346 {
    3347 SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_MARKOWITZ, threshhold, success) );
    3348 if( *success )
    3349 lp->lpimarkowitz = threshhold;
    3350 }
    3351 else
    3352 *success = FALSE;
    3353
    3354 return SCIP_OKAY;
    3355}
    3356
    3357/** sets the type of timer of the LP solver */
    3358static
    3360 SCIP_LP* lp, /**< current LP data */
    3361 SCIP_CLOCKTYPE timing, /**< new timing value */
    3362 SCIP_Bool enabled, /**< is timing enabled? */
    3363 SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
    3364 )
    3365{
    3366 int lptiming;
    3367
    3368 assert(lp != NULL);
    3369 assert(success != NULL);
    3370 assert((int) SCIP_CLOCKTYPE_CPU == 1 && (int) SCIP_CLOCKTYPE_WALL == 2); /*lint !e506*//*lint !e1564*/
    3371
    3373
    3374 if( !enabled )
    3375 lptiming = 0;
    3376 else
    3377 lptiming = (int) timing;
    3378
    3379 if( lptiming != lp->lpitiming ) /*lint !e777*/
    3380 {
    3381 SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_TIMING, lptiming, success) );
    3382 if( *success )
    3383 lp->lpitiming = lptiming;
    3384 }
    3385 else
    3386 *success = FALSE;
    3387
    3388 return SCIP_OKAY;
    3389}
    3390
    3391/** sets the initial random seed of the LP solver */
    3392static
    3394 SCIP_LP* lp, /**< current LP data */
    3395 int randomseed, /**< new initial random seed */
    3396 SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
    3397 )
    3398{
    3399 assert(lp != NULL);
    3400 assert(success != NULL);
    3401
    3402 /* we don't check this parameter because SoPlex will always return its current random seed, not the initial one */
    3403
    3404 if( randomseed == 0 )
    3405 {
    3406 lp->lpirandomseed = randomseed;
    3407 *success = TRUE;
    3408 }
    3409 else if( randomseed != lp->lpirandomseed ) /*lint !e777*/
    3410 {
    3411 SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_RANDOMSEED, randomseed, success) );
    3412 if( *success )
    3413 lp->lpirandomseed = randomseed;
    3414 }
    3415 else
    3416 *success = FALSE;
    3417
    3418 return SCIP_OKAY;
    3419}
    3420
    3421/** sets the LP solution polishing method */
    3422static
    3424 SCIP_LP* lp, /**< current LP data */
    3425 SCIP_Bool polishing, /**< LP solution polishing activated (0: disabled, 1: enabled) */
    3426 SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
    3427 )
    3428{
    3429 assert(lp != NULL);
    3430 assert(success != NULL);
    3431
    3432 if( polishing != lp->lpisolutionpolishing )
    3433 {
    3434 SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_POLISHING, (polishing ? 1 : 0), success) );
    3435 if( *success )
    3436 lp->lpisolutionpolishing = polishing;
    3437 }
    3438 else
    3439 *success = FALSE;
    3440
    3441 return SCIP_OKAY;
    3442}
    3443
    3444/** sets the LP refactorization interval */
    3445static
    3447 SCIP_LP* lp, /**< current LP data */
    3448 int refactor, /**< LP refactorization interval (0: automatic) */
    3449 SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
    3450 )
    3451{
    3452 assert(lp != NULL);
    3453 assert(success != NULL);
    3454
    3455 if( refactor != lp->lpirefactorinterval )
    3456 {
    3457 SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_REFACTOR, refactor, success) );
    3458 if( *success )
    3459 lp->lpirefactorinterval = refactor;
    3460 }
    3461 else
    3462 *success = FALSE;
    3463
    3464 return SCIP_OKAY;
    3465}
    3466
    3467
    3468/*
    3469 * Column methods
    3470 */
    3471
    3472/** creates an LP column */
    3474 SCIP_COL** col, /**< pointer to column data */
    3475 BMS_BLKMEM* blkmem, /**< block memory */
    3476 SCIP_SET* set, /**< global SCIP settings */
    3477 SCIP_STAT* stat, /**< problem statistics */
    3478 SCIP_VAR* var, /**< variable, this column represents */
    3479 int len, /**< number of nonzeros in the column */
    3480 SCIP_ROW** rows, /**< array with rows of column entries */
    3481 SCIP_Real* vals, /**< array with coefficients of column entries */
    3482 SCIP_Bool removable /**< should the column be removed from the LP due to aging or cleanup? */
    3483 )
    3484{
    3485 int i;
    3486
    3487 assert(col != NULL);
    3488 assert(blkmem != NULL);
    3489 assert(set != NULL);
    3490 assert(stat != NULL);
    3491 assert(var != NULL);
    3492 assert(len >= 0);
    3493 assert(len == 0 || (rows != NULL && vals != NULL));
    3494
    3495 SCIP_ALLOC( BMSallocBlockMemory(blkmem, col) );
    3496
    3497 if( len > 0 )
    3498 {
    3499 SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*col)->rows, rows, len) );
    3500 SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*col)->vals, vals, len) );
    3501 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*col)->linkpos, len) );
    3502
    3503 for( i = 0; i < len; ++i )
    3504 {
    3505 assert(rows[i] != NULL);
    3506 assert(!SCIPsetIsZero(set, vals[i]));
    3507 (*col)->linkpos[i] = -1;
    3508 }
    3509 }
    3510 else
    3511 {
    3512 (*col)->rows = NULL;
    3513 (*col)->vals = NULL;
    3514 (*col)->linkpos = NULL;
    3515 }
    3516
    3517 (*col)->var = var;
    3518 (*col)->obj = SCIPvarGetObj(var);
    3519 (*col)->unchangedobj = SCIPvarGetUnchangedObj(var);
    3520 (*col)->lb = SCIPvarGetLbLocal(var);
    3521 (*col)->ub = SCIPvarGetUbLocal(var);
    3522 (*col)->flushedobj = 0.0;
    3523 (*col)->flushedlb = 0.0;
    3524 (*col)->flushedub = 0.0;
    3525 (*col)->index = stat->ncolidx;
    3526 SCIPstatIncrement(stat, set, ncolidx);
    3527 (*col)->size = len;
    3528 (*col)->len = len;
    3529 (*col)->nlprows = 0;
    3530 (*col)->nunlinked = len;
    3531 (*col)->lppos = -1;
    3532 (*col)->lpipos = -1;
    3533 (*col)->lpdepth = -1;
    3534 (*col)->primsol = 0.0;
    3535 (*col)->redcost = SCIP_INVALID;
    3536 (*col)->farkascoef = SCIP_INVALID;
    3537 (*col)->minprimsol = (*col)->ub;
    3538 (*col)->maxprimsol = (*col)->lb;
    3539 (*col)->sbdown = SCIP_INVALID;
    3540 (*col)->sbup = SCIP_INVALID;
    3541 (*col)->sbsolval = SCIP_INVALID;
    3542 (*col)->sblpobjval = SCIP_INVALID;
    3543 (*col)->sbnode = -1;
    3544 (*col)->validredcostlp = -1;
    3545 (*col)->validfarkaslp = -1;
    3546 (*col)->validsblp = -1;
    3547 (*col)->sbitlim = -1;
    3548 (*col)->nsbcalls = 0;
    3549 (*col)->age = 0;
    3550 (*col)->obsoletenode = -1;
    3551 (*col)->var_probindex = SCIPvarGetProbindex(var);
    3552 (*col)->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
    3553 (*col)->lprowssorted = TRUE;
    3554 (*col)->nonlprowssorted = (len <= 1);
    3555 (*col)->objchanged = FALSE;
    3556 (*col)->lbchanged = FALSE;
    3557 (*col)->ubchanged = FALSE;
    3558 (*col)->coefchanged = FALSE;
    3559 (*col)->integral = SCIPvarIsIntegral(var);
    3560 (*col)->impliedintegral = SCIPvarIsImpliedIntegral(var);
    3561 (*col)->removable = removable;
    3562 (*col)->sbdownvalid = FALSE;
    3563 (*col)->sbupvalid = FALSE;
    3564 (*col)->lazylb = SCIPvarGetLbLazy(var);
    3565 (*col)->lazyub = SCIPvarGetUbLazy(var);
    3566 (*col)->storedsolvals = NULL;
    3567
    3568 return SCIP_OKAY;
    3569}
    3570
    3571/** frees an LP column */
    3573 SCIP_COL** col, /**< pointer to LP column */
    3574 BMS_BLKMEM* blkmem, /**< block memory */
    3575 SCIP_SET* set, /**< global SCIP settings */
    3576 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    3577 SCIP_LP* lp /**< current LP data */
    3578 )
    3579{
    3580 assert(blkmem != NULL);
    3581 assert(col != NULL);
    3582 assert(*col != NULL);
    3583 assert((*col)->var != NULL);
    3584 assert(SCIPvarGetStatus((*col)->var) == SCIP_VARSTATUS_COLUMN);
    3585 assert(&(*col)->var->data.col == col); /* SCIPcolFree() has to be called from SCIPvarFree() */
    3586 assert((*col)->lppos == -1);
    3587 assert((*col)->lpipos == -1);
    3588
    3589 /* remove column indices from corresponding rows */
    3590 SCIP_CALL( colUnlink(*col, blkmem, set, eventqueue, lp) );
    3591
    3592 BMSfreeBlockMemoryNull(blkmem, &(*col)->storedsolvals);
    3593 BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->rows, (*col)->size);
    3594 BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->vals, (*col)->size);
    3595 BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->linkpos, (*col)->size);
    3596 BMSfreeBlockMemory(blkmem, col);
    3597
    3598 return SCIP_OKAY;
    3599}
    3600
    3601/** output column to file stream */
    3603 SCIP_COL* col, /**< LP column */
    3604 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    3605 FILE* file /**< output file (or NULL for standard output) */
    3606 )
    3607{
    3608 int r;
    3609
    3610 assert(col != NULL);
    3611 assert(col->var != NULL);
    3612
    3613 /* print bounds */
    3614 SCIPmessageFPrintInfo(messagehdlr, file, "(obj: %.15g) [%.15g,%.15g], ", col->obj, col->lb, col->ub);
    3615
    3616 /* print coefficients */
    3617 if( col->len == 0 )
    3618 SCIPmessageFPrintInfo(messagehdlr, file, "<empty>");
    3619 for( r = 0; r < col->len; ++r )
    3620 {
    3621 assert(col->rows[r] != NULL);
    3622 assert(col->rows[r]->name != NULL);
    3623 SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g<%s> ", col->vals[r], col->rows[r]->name);
    3624 }
    3625 SCIPmessageFPrintInfo(messagehdlr, file, "\n");
    3626}
    3627
    3628/** sorts column entries such that LP rows precede non-LP rows and inside both parts lower row indices precede higher ones
    3629 */
    3631 SCIP_COL* col /**< column to be sorted */
    3632 )
    3633{
    3634 /* sort LP rows */
    3635 colSortLP(col);
    3636
    3637 /* sort non-LP rows */
    3638 colSortNonLP(col);
    3639}
    3640
    3641/** adds a previously non existing coefficient to an LP column */
    3643 SCIP_COL* col, /**< LP column */
    3644 BMS_BLKMEM* blkmem, /**< block memory */
    3645 SCIP_SET* set, /**< global SCIP settings */
    3646 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    3647 SCIP_LP* lp, /**< current LP data */
    3648 SCIP_ROW* row, /**< LP row */
    3649 SCIP_Real val /**< value of coefficient */
    3650 )
    3651{
    3652 assert(lp != NULL);
    3653 assert(!lp->diving);
    3654
    3655 SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, val, -1) );
    3656
    3657 checkLinks(lp);
    3658
    3659 return SCIP_OKAY;
    3660}
    3661
    3662/** deletes existing coefficient from column */
    3664 SCIP_COL* col, /**< column to be changed */
    3665 BMS_BLKMEM* blkmem, /**< block memory */
    3666 SCIP_SET* set, /**< global SCIP settings */
    3667 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    3668 SCIP_LP* lp, /**< current LP data */
    3669 SCIP_ROW* row /**< coefficient to be deleted */
    3670 )
    3671{
    3672 int pos;
    3673
    3674 assert(col != NULL);
    3675 assert(col->var != NULL);
    3676 assert(lp != NULL);
    3677 assert(!lp->diving);
    3678 assert(row != NULL);
    3679
    3680 /* search the position of the row in the column's row vector */
    3681 pos = colSearchCoef(col, row);
    3682 if( pos == -1 )
    3683 {
    3684 SCIPerrorMessage("coefficient for row <%s> doesn't exist in column <%s>\n", row->name, SCIPvarGetName(col->var));
    3685 return SCIP_INVALIDDATA;
    3686 }
    3687 assert(0 <= pos && pos < col->len);
    3688 assert(col->rows[pos] == row);
    3689
    3690 /* if row knows of the column, remove the column from the row's col vector */
    3691 if( col->linkpos[pos] >= 0 )
    3692 {
    3693 assert(row->cols[col->linkpos[pos]] == col);
    3694 assert(row->cols_index[col->linkpos[pos]] == col->index);
    3695 assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
    3696 SCIP_CALL( rowDelCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos]) );
    3697 }
    3698
    3699 /* delete the row from the column's row vector */
    3700 SCIP_CALL( colDelCoefPos(col, set, lp, pos) );
    3701
    3702 checkLinks(lp);
    3703
    3704 return SCIP_OKAY;
    3705}
    3706
    3707/** changes or adds a coefficient to an LP column */
    3709 SCIP_COL* col, /**< LP column */
    3710 BMS_BLKMEM* blkmem, /**< block memory */
    3711 SCIP_SET* set, /**< global SCIP settings */
    3712 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    3713 SCIP_LP* lp, /**< current LP data */
    3714 SCIP_ROW* row, /**< LP row */
    3715 SCIP_Real val /**< value of coefficient */
    3716 )
    3717{
    3718 int pos;
    3719
    3720 assert(col != NULL);
    3721 assert(lp != NULL);
    3722 assert(!lp->diving);
    3723 assert(row != NULL);
    3724
    3725 /* search the position of the row in the column's row vector */
    3726 pos = colSearchCoef(col, row);
    3727
    3728 /* check, if row already exists in the column's row vector */
    3729 if( pos == -1 )
    3730 {
    3731 /* add previously not existing coefficient */
    3732 SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, val, -1) );
    3733 }
    3734 else
    3735 {
    3736 /* modify already existing coefficient */
    3737 assert(0 <= pos && pos < col->len);
    3738 assert(col->rows[pos] == row);
    3739
    3740 /* if row knows of the column, change the corresponding coefficient in the row */
    3741 if( col->linkpos[pos] >= 0 )
    3742 {
    3743 assert(row->cols[col->linkpos[pos]] == col);
    3744 assert(row->cols_index[col->linkpos[pos]] == col->index);
    3745 assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
    3746 SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos], val) );
    3747 }
    3748
    3749 /* change the coefficient in the column */
    3750 SCIP_CALL( colChgCoefPos(col, set, lp, pos, val) );
    3751 }
    3752
    3753 checkLinks(lp);
    3754
    3755 return SCIP_OKAY;
    3756}
    3757
    3758/** increases value of an existing or non-existing coefficient in an LP column */
    3760 SCIP_COL* col, /**< LP column */
    3761 BMS_BLKMEM* blkmem, /**< block memory */
    3762 SCIP_SET* set, /**< global SCIP settings */
    3763 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    3764 SCIP_LP* lp, /**< current LP data */
    3765 SCIP_ROW* row, /**< LP row */
    3766 SCIP_Real incval /**< value to add to the coefficient */
    3767 )
    3768{
    3769 int pos;
    3770
    3771 assert(col != NULL);
    3772 assert(lp != NULL);
    3773 assert(!lp->diving);
    3774 assert(row != NULL);
    3775
    3776 if( SCIPsetIsZero(set, incval) )
    3777 return SCIP_OKAY;
    3778
    3779 /* search the position of the row in the column's row vector */
    3780 pos = colSearchCoef(col, row);
    3781
    3782 /* check, if row already exists in the column's row vector */
    3783 if( pos == -1 )
    3784 {
    3785 /* add previously not existing coefficient */
    3786 SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, incval, -1) );
    3787 }
    3788 else
    3789 {
    3790 /* modify already existing coefficient */
    3791 assert(0 <= pos && pos < col->len);
    3792 assert(col->rows[pos] == row);
    3793
    3794 /* if row knows of the column, change the corresponding coefficient in the row */
    3795 if( col->linkpos[pos] >= 0 )
    3796 {
    3797 assert(row->cols[col->linkpos[pos]] == col);
    3798 assert(row->cols_index[col->linkpos[pos]] == col->index);
    3799 assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
    3800 SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos], col->vals[pos] + incval) );
    3801 }
    3802
    3803 /* change the coefficient in the column */
    3804 SCIP_CALL( colChgCoefPos(col, set, lp, pos, col->vals[pos] + incval) );
    3805 }
    3806
    3807 checkLinks(lp);
    3808
    3809 return SCIP_OKAY;
    3810}
    3811
    3812/** insert column in the chgcols list (if not already there) */
    3813static
    3815 SCIP_COL* col, /**< LP column to change */
    3816 SCIP_SET* set, /**< global SCIP settings */
    3817 SCIP_LP* lp /**< current LP data */
    3818 )
    3819{
    3820 if( !col->objchanged && !col->lbchanged && !col->ubchanged )
    3821 {
    3822 SCIP_CALL( ensureChgcolsSize(lp, set, lp->nchgcols+1) );
    3823 lp->chgcols[lp->nchgcols] = col;
    3824 lp->nchgcols++;
    3825 }
    3826
    3827 /* mark the current LP unflushed */
    3828 lp->flushed = FALSE;
    3829
    3830 return SCIP_OKAY;
    3831}
    3832
    3833/** Is the new value reliable or may we have cancellation?
    3834 *
    3835 * @note: Here we only consider cancellations which can occur during decreasing the oldvalue to newvalue; not the
    3836 * cancellations which can occur during increasing the oldvalue to the newvalue
    3837 */
    3838static
    3840 SCIP_SET* set, /**< global SCIP settings */
    3841 SCIP_Real newvalue, /**< new value */
    3842 SCIP_Real oldvalue /**< old reliable value */
    3843 )
    3844{
    3845 SCIP_Real quotient;
    3846
    3847 assert(set != NULL);
    3848 assert(oldvalue != SCIP_INVALID); /*lint !e777*/
    3849
    3850 quotient = (REALABS(newvalue)+1.0) / (REALABS(oldvalue) + 1.0);
    3851
    3852 return SCIPsetIsZero(set, quotient);
    3853}
    3854
    3855/** update norms of objective function vector */
    3856static
    3858 SCIP_LP* lp, /**< current LP data */
    3859 SCIP_SET* set, /**< global SCIP settings */
    3860 SCIP_Real oldobj, /**< old objective value of variable */
    3861 SCIP_Real newobj /**< new objective value of variable */
    3862 )
    3863{
    3864 if( REALABS(newobj) != REALABS(oldobj) ) /*lint !e777*/
    3865 {
    3866 if( !lp->objsqrnormunreliable )
    3867 {
    3868 SCIP_Real oldvalue;
    3869
    3870 oldvalue = lp->objsqrnorm;
    3871 lp->objsqrnorm += SQR(newobj) - SQR(oldobj);
    3872
    3873 /* due to numerical cancellations, we recalculate lp->objsqrnorm using all variables */
    3874 if( SCIPsetIsLT(set, lp->objsqrnorm, 0.0) || isNewValueUnreliable(set, lp->objsqrnorm, oldvalue) )
    3876 else
    3877 {
    3878 assert(SCIPsetIsGE(set, lp->objsqrnorm, 0.0));
    3879
    3880 /* due to numerical troubles it still can appear that lp->objsqrnorm is a little bit smaller than 0 */
    3881 lp->objsqrnorm = MAX(lp->objsqrnorm, 0.0);
    3882
    3883 assert(lp->objsqrnorm >= 0.0);
    3884 }
    3885 }
    3886
    3887 lp->objsumnorm += REALABS(newobj) - REALABS(oldobj);
    3888 lp->objsumnorm = MAX(lp->objsumnorm, 0.0);
    3889 }
    3890}
    3891
    3892/** changes objective value of column */
    3894 SCIP_COL* col, /**< LP column to change */
    3895 SCIP_SET* set, /**< global SCIP settings */
    3896 SCIP_LP* lp, /**< current LP data */
    3897 SCIP_Real newobj /**< new objective value */
    3898 )
    3899{
    3900 assert(col != NULL);
    3901 assert(col->var != NULL);
    3903 assert(SCIPvarGetCol(col->var) == col);
    3904 assert(lp != NULL);
    3905
    3906 SCIPsetDebugMsg(set, "changing objective value of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->obj, newobj);
    3907
    3908 /* only add actual changes */
    3909 if( !SCIPsetIsEQ(set, col->obj, newobj) )
    3910 {
    3911 /* only variables with a real position in the LPI can be inserted */
    3912 if( col->lpipos >= 0 )
    3913 {
    3914 /* insert column in the chgcols list (if not already there) */
    3915 SCIP_CALL( insertColChgcols(col, set, lp) );
    3916
    3917 /* mark objective value change in the column */
    3918 col->objchanged = TRUE;
    3919
    3920 assert(lp->nchgcols > 0);
    3921 }
    3922 /* in any case, when the sign of the objective (and thereby the best bound) changes, the variable has to enter the
    3923 * LP and the LP has to be flushed
    3924 */
    3925 else if( (col->obj < 0.0 && newobj >= 0.0 && SCIPsetIsZero(set, col->ub))
    3926 || (col->obj >= 0.0 && newobj < 0.0 && SCIPsetIsZero(set, col->lb)) )
    3927 {
    3928 /* mark the LP unflushed */
    3929 lp->flushed = FALSE;
    3930 }
    3931 }
    3932
    3933 /* store new objective function value */
    3934 col->obj = newobj;
    3935
    3936 /* update original objective value, as long as we are not in diving or probing and changed objective values */
    3937 if( !lp->divingobjchg )
    3938 {
    3939 SCIP_Real oldobj = col->unchangedobj;
    3940
    3941 assert(SCIPsetIsEQ(set, newobj, SCIPvarGetUnchangedObj(col->var)));
    3942 col->unchangedobj = newobj;
    3943
    3944 /* update the objective function vector norms */
    3945 lpUpdateObjNorms(lp, set, oldobj, newobj);
    3946 }
    3947
    3948 return SCIP_OKAY;
    3949}
    3950
    3951/** changes lower bound of column */
    3953 SCIP_COL* col, /**< LP column to change */
    3954 SCIP_SET* set, /**< global SCIP settings */
    3955 SCIP_LP* lp, /**< current LP data */
    3956 SCIP_Real newlb /**< new lower bound value */
    3957 )
    3958{
    3959 assert(col != NULL);
    3960 assert(col->var != NULL);
    3962 assert(SCIPvarGetCol(col->var) == col);
    3963 assert(lp != NULL);
    3964
    3965 SCIPsetDebugMsg(set, "changing lower bound of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->lb, newlb);
    3966
    3967 /* only add actual changes */
    3968 if( !SCIPsetIsEQ(set, col->lb, newlb) )
    3969 {
    3970 /* only variables with a real position in the LPI can be inserted */
    3971 if( col->lpipos >= 0 )
    3972 {
    3973 /* insert column in the chgcols list (if not already there) */
    3974 SCIP_CALL( insertColChgcols(col, set, lp) );
    3975
    3976 /* mark bound change in the column */
    3977 col->lbchanged = TRUE;
    3978
    3979 assert(lp->nchgcols > 0);
    3980 }
    3981 /* in any case, when the best bound is zero and gets changed, the variable has to enter the LP and the LP has to be
    3982 * flushed
    3983 */
    3984 else if( col->obj >= 0.0 && SCIPsetIsZero(set, col->lb) )
    3985 {
    3986 /* mark the LP unflushed */
    3987 lp->flushed = FALSE;
    3988 }
    3989 }
    3990
    3991 col->lb = newlb;
    3992
    3993 return SCIP_OKAY;
    3994}
    3995
    3996/** changes upper bound of column */
    3998 SCIP_COL* col, /**< LP column to change */
    3999 SCIP_SET* set, /**< global SCIP settings */
    4000 SCIP_LP* lp, /**< current LP data */
    4001 SCIP_Real newub /**< new upper bound value */
    4002 )
    4003{
    4004 assert(col != NULL);
    4005 assert(col->var != NULL);
    4007 assert(SCIPvarGetCol(col->var) == col);
    4008 assert(lp != NULL);
    4009
    4010 SCIPsetDebugMsg(set, "changing upper bound of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->ub, newub);
    4011
    4012 /* only add actual changes */
    4013 if( !SCIPsetIsEQ(set, col->ub, newub) )
    4014 {
    4015 /* only variables with a real position in the LPI can be inserted */
    4016 if( col->lpipos >= 0 )
    4017 {
    4018 /* insert column in the chgcols list (if not already there) */
    4019 SCIP_CALL( insertColChgcols(col, set, lp) );
    4020
    4021 /* mark bound change in the column */
    4022 col->ubchanged = TRUE;
    4023
    4024 assert(lp->nchgcols > 0);
    4025 }
    4026 /* in any case, when the best bound is zero and gets changed, the variable has to enter the LP and the LP has to be
    4027 * flushed
    4028 */
    4029 else if( col->obj < 0.0 && SCIPsetIsZero(set, col->ub) )
    4030 {
    4031 /* mark the LP unflushed */
    4032 lp->flushed = FALSE;
    4033 }
    4034 }
    4035
    4036 col->ub = newub;
    4037
    4038 return SCIP_OKAY;
    4039}
    4040
    4041/** calculates the reduced costs of a column using the given dual solution vector */
    4043 SCIP_COL* col, /**< LP column */
    4044 SCIP_Real* dualsol /**< dual solution vector for current LP rows */
    4045 )
    4046{
    4047 SCIP_ROW* row;
    4048 SCIP_Real redcost;
    4049 int i;
    4050
    4051 assert(col != NULL);
    4053 assert(SCIPvarGetCol(col->var) == col);
    4054 assert(dualsol != NULL);
    4055
    4056 redcost = col->obj;
    4057 for( i = 0; i < col->nlprows; ++i )
    4058 {
    4059 row = col->rows[i];
    4060 assert(row != NULL);
    4061 assert(row->lppos >= 0);
    4062 redcost -= col->vals[i] * dualsol[row->lppos];
    4063 }
    4064
    4065 if( col->nunlinked > 0 )
    4066 {
    4067 for( i = col->nlprows; i < col->len; ++i )
    4068 {
    4069 row = col->rows[i];
    4070 assert(row != NULL);
    4071 assert(row->lppos == -1 || col->linkpos[i] == -1);
    4072 if( row->lppos >= 0 )
    4073 redcost -= col->vals[i] * dualsol[row->lppos];
    4074 }
    4075 }
    4076#ifndef NDEBUG
    4077 else
    4078 {
    4079 for( i = col->nlprows; i < col->len; ++i )
    4080 {
    4081 row = col->rows[i];
    4082 assert(row != NULL);
    4083 assert(row->lppos == -1);
    4084 assert(col->linkpos[i] >= 0);
    4085 }
    4086 }
    4087#endif
    4088
    4089 return redcost;
    4090}
    4091
    4092/** calculates the reduced costs of a column using the dual solution stored in the rows */
    4093static
    4095 SCIP_COL* col /**< LP column */
    4096 )
    4097{
    4098 SCIP_ROW* row;
    4099 SCIP_Real redcost;
    4100 int i;
    4101
    4102 assert(col != NULL);
    4104 assert(SCIPvarGetCol(col->var) == col);
    4105
    4106 redcost = col->obj;
    4107 for( i = 0; i < col->nlprows; ++i )
    4108 {
    4109 row = col->rows[i];
    4110 assert(row != NULL);
    4111 assert(row->dualsol != SCIP_INVALID); /*lint !e777*/
    4112 assert(row->lppos >= 0);
    4113 assert(col->linkpos[i] >= 0);
    4114 redcost -= col->vals[i] * row->dualsol;
    4115 }
    4116
    4117 if( col->nunlinked > 0 )
    4118 {
    4119 for( i = col->nlprows; i < col->len; ++i )
    4120 {
    4121 row = col->rows[i];
    4122 assert(row != NULL);
    4123 assert(row->lppos >= 0 || row->dualsol == 0.0);
    4124 assert(row->lppos == -1 || col->linkpos[i] == -1);
    4125 if( row->lppos >= 0 )
    4126 redcost -= col->vals[i] * row->dualsol;
    4127 }
    4128 }
    4129#ifndef NDEBUG
    4130 else
    4131 {
    4132 for( i = col->nlprows; i < col->len; ++i )
    4133 {
    4134 row = col->rows[i];
    4135 assert(row != NULL);
    4136 assert(row->dualsol == 0.0);
    4137 assert(row->lppos == -1);
    4138 assert(col->linkpos[i] >= 0);
    4139 }
    4140 }
    4141#endif
    4142
    4143 return redcost;
    4144}
    4145
    4146/** gets the reduced costs of a column in last LP or after recalculation */
    4148 SCIP_COL* col, /**< LP column */
    4149 SCIP_STAT* stat, /**< problem statistics */
    4150 SCIP_LP* lp /**< current LP data */
    4151 )
    4152{
    4153 assert(col != NULL);
    4154 assert(stat != NULL);
    4155 assert(lp != NULL);
    4156 assert(col->validredcostlp <= stat->lpcount);
    4157 assert(lp->validsollp == stat->lpcount);
    4158
    4159 if( col->validredcostlp < stat->lpcount )
    4160 {
    4161 col->redcost = colCalcInternalRedcost(col);
    4162 col->validredcostlp = stat->lpcount;
    4163 }
    4164 assert(col->validredcostlp == stat->lpcount);
    4165 assert(col->redcost != SCIP_INVALID); /*lint !e777*/
    4166
    4167 return col->redcost;
    4168}
    4169
    4170/** gets the feasibility of (the dual row of) a column in last LP or after recalculation */
    4172 SCIP_COL* col, /**< LP column */
    4173 SCIP_SET* set, /**< global SCIP settings */
    4174 SCIP_STAT* stat, /**< problem statistics */
    4175 SCIP_LP* lp /**< current LP data */
    4176 )
    4177{
    4178 assert(col != NULL);
    4179 assert(set != NULL);
    4180 assert(stat != NULL);
    4181 assert(lp != NULL);
    4182 assert(lp->validsollp == stat->lpcount);
    4183
    4184 /* A column's reduced cost is defined as
    4185 * redcost = obj - activity, activity = y^T * col. (activity = obj - redcost)
    4186 * The activity is equal to the activity of the corresponding row in the dual LP.
    4187 * The column's feasibility is the feasibility of the corresponding row in the dual LP.
    4188 * The sides of the dual row depend on the bounds of the column:
    4189 * - lb == ub : dual row is a free row with infinite sides
    4190 * - 0 <= lb < ub: activity <= obj => 0 <= redcost
    4191 * - lb < 0 < ub: obj <= activity <= obj => 0 <= redcost <= 0
    4192 * - lb < ub <= 0: obj <= activity => redcost <= 0
    4193 */
    4194 if( SCIPsetIsEQ(set, col->lb, col->ub) )
    4195 {
    4196 /* dual row is free */
    4197 return SCIPsetInfinity(set);
    4198 }
    4199 else
    4200 {
    4201 SCIP_Real redcost;
    4202
    4203 /* calculate reduced costs */
    4204 redcost = SCIPcolGetRedcost(col, stat, lp);
    4205
    4206 if( !SCIPsetIsNegative(set, col->lb) )
    4207 {
    4208 /* dual row is activity <= obj <=> redcost >= 0 */
    4209 return redcost;
    4210 }
    4211 else if( SCIPsetIsPositive(set, col->ub) )
    4212 {
    4213 /* dual row is activity == obj <=> redcost == 0 */
    4214 return -REALABS(redcost);
    4215 }
    4216 else
    4217 {
    4218 /* dual row is activity >= obj <=> redcost <= 0 */
    4219 return -redcost;
    4220 }
    4221 }
    4222}
    4223
    4224/** calculates the Farkas coefficient y^T A_i of a column i using the given dual Farkas vector y */
    4226 SCIP_COL* col, /**< LP column */
    4227 SCIP_Real* dualfarkas /**< dense dual Farkas vector for current LP rows */
    4228 )
    4229{
    4230 SCIP_ROW* row;
    4231 SCIP_Real farkas;
    4232 int i;
    4233
    4234 assert(col != NULL);
    4236 assert(SCIPvarGetCol(col->var) == col);
    4237 assert(dualfarkas != NULL);
    4238
    4239 farkas = 0.0;
    4240 for( i = 0; i < col->nlprows; ++i )
    4241 {
    4242 row = col->rows[i];
    4243 assert(row != NULL);
    4244 assert(row->lppos >= 0);
    4245 farkas += col->vals[i] * dualfarkas[row->lppos];
    4246 }
    4247
    4248 if( col->nunlinked > 0 )
    4249 {
    4250 for( i = col->nlprows; i < col->len; ++i )
    4251 {
    4252 row = col->rows[i];
    4253 assert(row != NULL);
    4254 assert(row->lppos == -1 || col->linkpos[i] == -1);
    4255 if( row->lppos >= 0 )
    4256 farkas += col->vals[i] * dualfarkas[row->lppos];
    4257 }
    4258 }
    4259#ifndef NDEBUG
    4260 else
    4261 {
    4262 for( i = col->nlprows; i < col->len; ++i )
    4263 {
    4264 row = col->rows[i];
    4265 assert(row != NULL);
    4266 assert(row->lppos == -1);
    4267 assert(col->linkpos[i] >= 0);
    4268 }
    4269 }
    4270#endif
    4271
    4272 return farkas;
    4273}
    4274
    4275/** gets the Farkas coefficient y^T A_i of a column i in last LP (which must be infeasible) */
    4276static
    4278 SCIP_COL* col /**< LP column */
    4279 )
    4280{
    4281 SCIP_ROW* row;
    4282 SCIP_Real farkas;
    4283 int i;
    4284
    4285 assert(col != NULL);
    4287 assert(SCIPvarGetCol(col->var) == col);
    4288
    4289 farkas = 0.0;
    4290 for( i = 0; i < col->nlprows; ++i )
    4291 {
    4292 row = col->rows[i];
    4293 assert(row != NULL);
    4294 assert(row->dualfarkas != SCIP_INVALID); /*lint !e777*/
    4295 assert(row->lppos >= 0);
    4296 assert(col->linkpos[i] >= 0);
    4297 farkas += col->vals[i] * row->dualfarkas;
    4298 }
    4299
    4300 if( col->nunlinked > 0 )
    4301 {
    4302 for( i = col->nlprows; i < col->len; ++i )
    4303 {
    4304 row = col->rows[i];
    4305 assert(row != NULL);
    4306 assert(row->lppos >= 0 || row->dualfarkas == 0.0);
    4307 assert(row->lppos == -1 || col->linkpos[i] == -1);
    4308 if( row->lppos >= 0 )
    4309 farkas += col->vals[i] * row->dualfarkas;
    4310 }
    4311 }
    4312#ifndef NDEBUG
    4313 else
    4314 {
    4315 for( i = col->nlprows; i < col->len; ++i )
    4316 {
    4317 row = col->rows[i];
    4318 assert(row != NULL);
    4319 assert(row->dualfarkas == 0.0);
    4320 assert(row->lppos == -1);
    4321 assert(col->linkpos[i] >= 0);
    4322 }
    4323 }
    4324#endif
    4325
    4326 return farkas;
    4327}
    4328
    4329/** gets the Farkas coefficient of a column in last LP (which must be infeasible) */
    4331 SCIP_COL* col, /**< LP column */
    4332 SCIP_STAT* stat, /**< problem statistics */
    4333 SCIP_LP* lp /**< current LP data */
    4334 )
    4335{
    4336 assert(col != NULL);
    4337 assert(stat != NULL);
    4338 assert(lp != NULL);
    4339 assert(col->validfarkaslp <= stat->lpcount);
    4340 assert(lp->validfarkaslp == stat->lpcount);
    4341
    4342 if( col->validfarkaslp < stat->lpcount )
    4343 {
    4345 col->validfarkaslp = stat->lpcount;
    4346 }
    4347 assert(col->validfarkaslp == stat->lpcount);
    4348 assert(col->farkascoef != SCIP_INVALID); /*lint !e777*/
    4349
    4350 return col->farkascoef;
    4351}
    4352
    4353/** gets the Farkas value of a column in last LP (which must be infeasible), i.e. the Farkas coefficient y^T A_i times
    4354 * the best bound for this coefficient, i.e. max{y^T A_i x_i | lb <= x_i <= ub}
    4355 */
    4357 SCIP_COL* col, /**< LP column */
    4358 SCIP_STAT* stat, /**< problem statistics */
    4359 SCIP_LP* lp /**< current LP data */
    4360 )
    4361{
    4362 SCIP_Real farkascoef;
    4363
    4364 assert(col != NULL);
    4365
    4366 farkascoef = SCIPcolGetFarkasCoef(col, stat, lp);
    4367
    4368 if( farkascoef > 0.0 )
    4369 return col->ub * farkascoef;
    4370 else
    4371 return col->lb * farkascoef;
    4372}
    4373
    4374/** start strong branching - call before any strong branching */
    4376 SCIP_LP* lp /**< LP data */
    4377 )
    4378{
    4379 assert(lp != NULL);
    4380 assert(!lp->strongbranching);
    4381
    4382 lp->strongbranching = TRUE;
    4383 SCIPdebugMessage("starting strong branching ...\n");
    4385
    4386 return SCIP_OKAY;
    4387}
    4388
    4389/** end strong branching - call after any strong branching */
    4391 SCIP_LP* lp /**< LP data */
    4392 )
    4393{
    4394 assert(lp != NULL);
    4395 assert(lp->strongbranching);
    4396
    4397 lp->strongbranching = FALSE;
    4398 SCIPdebugMessage("ending strong branching ...\n");
    4400
    4401 return SCIP_OKAY;
    4402}
    4403
    4404/** sets strong branching information for a column variable */
    4406 SCIP_COL* col, /**< LP column */
    4407 SCIP_SET* set, /**< global SCIP settings */
    4408 SCIP_STAT* stat, /**< dynamic problem statistics */
    4409 SCIP_LP* lp, /**< LP data */
    4410 SCIP_Real lpobjval, /**< objective value of the current LP */
    4411 SCIP_Real primsol, /**< primal solution value of the column in the current LP */
    4412 SCIP_Real sbdown, /**< dual bound after branching column down */
    4413 SCIP_Real sbup, /**< dual bound after branching column up */
    4414 SCIP_Bool sbdownvalid, /**< is the returned down value a valid dual bound? */
    4415 SCIP_Bool sbupvalid, /**< is the returned up value a valid dual bound? */
    4416 SCIP_Longint iter, /**< total number of strong branching iterations */
    4417 int itlim /**< iteration limit applied to the strong branching call */
    4418 )
    4419{
    4420 assert(col != NULL);
    4421 assert(col->var != NULL);
    4422 assert(SCIPcolIsIntegral(col));
    4423 assert(SCIPvarIsIntegral(col->var));
    4425 assert(SCIPvarGetCol(col->var) == col);
    4426 assert(col->lpipos >= 0);
    4427 assert(col->lppos >= 0);
    4428 assert(set != NULL);
    4429 assert(stat != NULL);
    4430 assert(lp != NULL);
    4431 assert(lp->strongbranchprobing);
    4432 assert(col->lppos < lp->ncols);
    4433 assert(lp->cols[col->lppos] == col);
    4434 assert(itlim >= 1);
    4435
    4436 col->sblpobjval = lpobjval;
    4437 col->sbsolval = primsol;
    4438 col->validsblp = stat->nlps;
    4439 col->sbnode = stat->nnodes;
    4440
    4441 col->sbitlim = itlim;
    4442 col->nsbcalls++;
    4443
    4444 col->sbdown = MIN(sbdown, lp->cutoffbound);
    4445 col->sbup = MIN(sbup, lp->cutoffbound);
    4446 col->sbdownvalid = sbdownvalid;
    4447 col->sbupvalid = sbupvalid;
    4448
    4449 SCIPstatIncrement(stat, set, nstrongbranchs);
    4450 SCIPstatAdd(stat, set, nsblpiterations, iter);
    4451 if( stat->nnodes == 1 )
    4452 {
    4453 SCIPstatIncrement(stat, set, nrootstrongbranchs);
    4454 SCIPstatAdd(stat, set, nrootsblpiterations, iter);
    4455 }
    4456}
    4457
    4458/** invalidates strong branching information for a column variable */
    4460 SCIP_COL* col, /**< LP column */
    4461 SCIP_SET* set, /**< global SCIP settings */
    4462 SCIP_STAT* stat, /**< dynamic problem statistics */
    4463 SCIP_LP* lp /**< LP data */
    4464 )
    4465{
    4466 assert(col != NULL);
    4467 assert(col->var != NULL);
    4468 assert(SCIPcolIsIntegral(col));
    4469 assert(SCIPvarIsIntegral(col->var));
    4471 assert(SCIPvarGetCol(col->var) == col);
    4472 assert(col->lpipos >= 0);
    4473 assert(col->lppos >= 0);
    4474 assert(set != NULL);
    4475 assert(stat != NULL);
    4476 assert(lp != NULL);
    4477 assert(lp->strongbranchprobing);
    4478 assert(col->lppos < lp->ncols);
    4479 assert(lp->cols[col->lppos] == col);
    4480
    4481 col->sbdown = SCIP_INVALID;
    4482 col->sbup = SCIP_INVALID;
    4483 col->sbdownvalid = FALSE;
    4484 col->sbupvalid = FALSE;
    4485 col->validsblp = -1;
    4486 col->sbsolval = SCIP_INVALID;
    4487 col->sblpobjval = SCIP_INVALID;
    4488 col->sbnode = -1;
    4489 col->sbitlim = -1;
    4490}
    4491
    4492
    4493/** gets strong branching information on a column variable */
    4495 SCIP_COL* col, /**< LP column */
    4496 SCIP_Bool integral, /**< should integral strong branching be performed? */
    4497 SCIP_SET* set, /**< global SCIP settings */
    4498 SCIP_STAT* stat, /**< dynamic problem statistics */
    4499 SCIP_PROB* prob, /**< problem data */
    4500 SCIP_LP* lp, /**< LP data */
    4501 int itlim, /**< iteration limit for strong branchings */
    4502 SCIP_Bool updatecol, /**< should col be updated, or should it stay in its current state ? */
    4503 SCIP_Bool updatestat, /**< should stat be updated, or should it stay in its current state ? */
    4504 SCIP_Real* down, /**< stores dual bound after branching column down */
    4505 SCIP_Real* up, /**< stores dual bound after branching column up */
    4506 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
    4507 * otherwise, it can only be used as an estimate value */
    4508 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
    4509 * otherwise, it can only be used as an estimate value */
    4510 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
    4511 )
    4512{
    4513 SCIP_Real sbdown;
    4514 SCIP_Real sbup;
    4515 SCIP_Bool sbdownvalid;
    4516 SCIP_Bool sbupvalid;
    4517 SCIP_Longint validsblp;
    4518 SCIP_Real sbsolval;
    4519 SCIP_Real sblpobjval;
    4520 SCIP_Longint sbnode;
    4521 int sbitlim;
    4522 int nsbcalls;
    4523
    4524 assert(col != NULL);
    4525 assert(col->var != NULL);
    4526 assert(SCIPcolIsIntegral(col));
    4527 assert(SCIPvarIsIntegral(col->var));
    4529 assert(SCIPvarGetCol(col->var) == col);
    4530 assert(col->primsol != SCIP_INVALID); /*lint !e777*/
    4531 assert(col->lpipos >= 0);
    4532 assert(col->lppos >= 0);
    4533 assert(set != NULL);
    4534 assert(stat != NULL);
    4535 assert(lp != NULL);
    4536 assert(lp->flushed);
    4537 assert(lp->solved);
    4538 assert(lp->strongbranching);
    4539 assert(lp->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL);
    4540 assert(lp->validsollp == stat->lpcount);
    4541 assert(col->lppos < lp->ncols);
    4542 assert(lp->cols[col->lppos] == col);
    4543 assert(itlim >= 1);
    4544 /* assert(down != NULL);
    4545 * assert(up != NULL); temporary hack for cloud branching
    4546 */
    4547 assert(lperror != NULL);
    4548
    4549 *lperror = FALSE;
    4550
    4551 sbitlim = col->sbitlim;
    4552 nsbcalls = col->nsbcalls;
    4553
    4554 validsblp = stat->nlps;
    4555 sbsolval = col->primsol;
    4556 sblpobjval = SCIPlpGetObjval(lp, set, prob);
    4557 sbnode = stat->nnodes;
    4558 assert(integral || !SCIPsetIsFeasIntegral(set, col->primsol));
    4559
    4560 /* if a loose variables has an infinite best bound, the LP bound is -infinity and no gain can be achieved */
    4561 if( lp->looseobjvalinf > 0 )
    4562 {
    4563 sbdown = -SCIPsetInfinity(set);
    4564 sbup = -SCIPsetInfinity(set);
    4565 sbdownvalid = FALSE;
    4566 sbupvalid = FALSE;
    4567 }
    4568 else
    4569 {
    4570 SCIP_RETCODE retcode;
    4571 int iter;
    4572
    4573 SCIPsetDebugMsg(set, "performing strong branching on variable <%s>(%g) with %d iterations\n",
    4574 SCIPvarGetName(col->var), col->primsol, itlim);
    4575
    4576 /* start timing */
    4578
    4579 /* call LPI strong branching */
    4580 sbitlim = itlim;
    4581 nsbcalls++;
    4582
    4583 sbdown = lp->lpobjval;
    4584 sbup = lp->lpobjval;
    4585 sbdownvalid = col->sbdownvalid;
    4586 sbupvalid = col->sbupvalid;
    4587
    4588 if( integral )
    4589 retcode = SCIPlpiStrongbranchInt(lp->lpi, col->lpipos, col->primsol, itlim, down == NULL ? NULL : &sbdown, up == NULL ? NULL : &sbup, &sbdownvalid, &sbupvalid, &iter);
    4590 else
    4591 {
    4592 assert( ! SCIPsetIsIntegral(set, col->primsol) );
    4593 retcode = SCIPlpiStrongbranchFrac(lp->lpi, col->lpipos, col->primsol, itlim, down == NULL ? NULL : &sbdown, up == NULL ? NULL : &sbup, &sbdownvalid, &sbupvalid, &iter);
    4594 }
    4595
    4596 /* check return code for errors */
    4597 if( retcode == SCIP_LPERROR )
    4598 {
    4599 *lperror = TRUE;
    4600 sbdown = SCIP_INVALID;
    4601 sbup = SCIP_INVALID;
    4602 sbdownvalid = FALSE;
    4603 sbupvalid = FALSE;
    4604 validsblp = -1;
    4605 sbsolval = SCIP_INVALID;
    4606 sblpobjval = SCIP_INVALID;
    4607 sbnode = -1;
    4608 }
    4609 else
    4610 {
    4611 SCIP_Real looseobjval;
    4612
    4613 *lperror = FALSE;
    4614 SCIP_CALL( retcode );
    4615
    4616 looseobjval = getFiniteLooseObjval(lp, set, prob);
    4617 sbdown = MIN(sbdown + looseobjval, lp->cutoffbound);
    4618 sbup = MIN(sbup + looseobjval, lp->cutoffbound);
    4619
    4620 /* update strong branching statistics */
    4621 if( updatestat )
    4622 {
    4623 if( iter == -1 )
    4624 {
    4625 /* calculate average iteration number */
    4626 iter = stat->ndualresolvelps > 0 ? (int)(2*stat->ndualresolvelpiterations / stat->ndualresolvelps)
    4627 : stat->nduallps > 0 ? (int)((stat->nduallpiterations / stat->nduallps) / 5)
    4628 : stat->nprimalresolvelps > 0 ? (int)(2*stat->nprimalresolvelpiterations / stat->nprimalresolvelps)
    4629 : stat->nprimallps > 0 ? (int)((stat->nprimallpiterations / stat->nprimallps) / 5)
    4630 : 0;
    4631 if( iter/2 >= itlim )
    4632 iter = 2*itlim;
    4633 }
    4634 SCIPstatIncrement(stat, set, nstrongbranchs);
    4635 SCIPstatAdd(stat, set, nsblpiterations, iter);
    4636 if( stat->nnodes == 1 )
    4637 {
    4638 SCIPstatIncrement(stat, set, nrootstrongbranchs);
    4639 SCIPstatAdd(stat, set, nrootsblpiterations, iter);
    4640 }
    4641 }
    4642 }
    4643
    4644 /* stop timing */
    4646 }
    4647 assert(*lperror || sbdown != SCIP_INVALID); /*lint !e777*/
    4648 assert(*lperror || sbup != SCIP_INVALID); /*lint !e777*/
    4649
    4650 if( down != NULL)
    4651 *down = sbdown;
    4652 if( up != NULL )
    4653 *up = sbup;
    4654 if( downvalid != NULL )
    4655 *downvalid = sbdownvalid;
    4656 if( upvalid != NULL )
    4657 *upvalid = sbupvalid;
    4658
    4659 if( updatecol )
    4660 {
    4661 col->sbdown = sbdown;
    4662 col->sbup = sbup;
    4663 col->sbdownvalid = sbdownvalid;
    4664 col->sbupvalid = sbupvalid;
    4665 col->validsblp = validsblp;
    4666 col->sbsolval = sbsolval;
    4667 col->sblpobjval = sblpobjval;
    4668 col->sbnode = sbnode;
    4669 col->sbitlim = sbitlim;
    4670 col->nsbcalls = nsbcalls;
    4671 }
    4672
    4673 return SCIP_OKAY;
    4674}
    4675
    4676/** gets strong branching information on column variables */
    4678 SCIP_COL** cols, /**< LP columns */
    4679 int ncols, /**< number of columns */
    4680 SCIP_Bool integral, /**< should integral strong branching be performed? */
    4681 SCIP_SET* set, /**< global SCIP settings */
    4682 SCIP_STAT* stat, /**< dynamic problem statistics */
    4683 SCIP_PROB* prob, /**< problem data */
    4684 SCIP_LP* lp, /**< LP data */
    4685 int itlim, /**< iteration limit for strong branchings */
    4686 SCIP_Real* down, /**< stores dual bounds after branching columns down */
    4687 SCIP_Real* up, /**< stores dual bounds after branching columns up */
    4688 SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds, or NULL;
    4689 * otherwise, they can only be used as an estimate value */
    4690 SCIP_Bool* upvalid, /**< stores whether the returned up values are valid dual bounds, or NULL;
    4691 * otherwise, they can only be used as an estimate value */
    4692 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
    4693 )
    4694{
    4695 SCIP_RETCODE retcode;
    4696 SCIP_Real* sbdown;
    4697 SCIP_Real* sbup;
    4698 SCIP_Bool* sbdownvalid;
    4699 SCIP_Bool* sbupvalid;
    4700 SCIP_Real* primsols;
    4701 SCIP_COL** subcols;
    4702 int* lpipos;
    4703 int* subidx;
    4704 int nsubcols;
    4705 int iter;
    4706 int j;
    4707
    4708 assert(cols != NULL);
    4709 assert(set != NULL);
    4710 assert(stat != NULL);
    4711 assert(lp != NULL);
    4712 assert(lp->flushed);
    4713 assert(lp->solved);
    4714 assert(lp->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL);
    4715 assert(lp->validsollp == stat->lpcount);
    4716 assert(itlim >= 1);
    4717 assert(down != NULL);
    4718 assert(up != NULL);
    4719 assert(lperror != NULL);
    4720
    4721 *lperror = FALSE;
    4722
    4723 if ( ncols <= 0 )
    4724 return SCIP_OKAY;
    4725
    4726 /* start timing */
    4728
    4729 /* initialize storage */
    4730 SCIP_CALL( SCIPsetAllocBufferArray(set, &subcols, ncols) );
    4731 SCIP_CALL( SCIPsetAllocBufferArray(set, &subidx, ncols) );
    4732 SCIP_CALL( SCIPsetAllocBufferArray(set, &lpipos, ncols) );
    4733 SCIP_CALL( SCIPsetAllocBufferArray(set, &primsols, ncols) );
    4734 SCIP_CALL( SCIPsetAllocBufferArray(set, &sbdown, ncols) );
    4735 SCIP_CALL( SCIPsetAllocBufferArray(set, &sbup, ncols) );
    4736 SCIP_CALL( SCIPsetAllocBufferArray(set, &sbdownvalid, ncols) );
    4737 SCIP_CALL( SCIPsetAllocBufferArray(set, &sbupvalid, ncols) );
    4738
    4739 nsubcols = 0;
    4740 for( j = 0; j < ncols; ++j )
    4741 {
    4742 SCIP_COL* col;
    4743 col = cols[j];
    4744
    4745 assert(col->lppos < lp->ncols);
    4746 assert(lp->cols[col->lppos] == col);
    4747 assert(SCIPcolIsIntegral(col));
    4748 assert(SCIPvarIsIntegral(col->var));
    4750 assert(SCIPvarGetCol(col->var) == col);
    4751 assert(col->primsol != SCIP_INVALID); /*lint !e777*/
    4752 assert(col->lpipos >= 0);
    4753 assert(col->lppos >= 0);
    4754
    4755 col->validsblp = stat->nlps;
    4756 col->sbsolval = col->primsol;
    4757 col->sblpobjval = SCIPlpGetObjval(lp, set, prob);
    4758 col->sbnode = stat->nnodes;
    4759 assert(!SCIPsetIsFeasIntegral(set, col->primsol));
    4760
    4761 /* if a loose variables has an infinite best bound, the LP bound is -infinity and no gain can be achieved */
    4762 if( lp->looseobjvalinf > 0 )
    4763 {
    4764 /* directly set up column and result vectors*/
    4765 col->sbdown = -SCIPsetInfinity(set);
    4766 col->sbup = -SCIPsetInfinity(set);
    4767 col->sbdownvalid = FALSE;
    4768 col->sbupvalid = FALSE;
    4769 down[j] = col->sbdown;
    4770 up[j] = col->sbup;
    4771 if( downvalid != NULL )
    4772 downvalid[j] = col->sbdownvalid;
    4773 if( upvalid != NULL )
    4774 upvalid[j] = col->sbupvalid;
    4775 }
    4776 else
    4777 {
    4778 col->sbitlim = itlim;
    4779 col->nsbcalls++;
    4780
    4781 lpipos[nsubcols] = col->lpipos;
    4782 primsols[nsubcols] = col->primsol;
    4783 assert( integral || ! SCIPsetIsFeasIntegral(set, col->primsol) );
    4784 subidx[nsubcols] = j;
    4785 subcols[nsubcols++] = col;
    4786 }
    4787 }
    4788
    4789 SCIPsetDebugMsg(set, "performing strong branching on %d variables with %d iterations\n", ncols, itlim);
    4790
    4791 /* call LPI strong branching */
    4792 if ( integral )
    4793 retcode = SCIPlpiStrongbranchesInt(lp->lpi, lpipos, nsubcols, primsols, itlim, sbdown, sbup, sbdownvalid, sbupvalid, &iter);
    4794 else
    4795 retcode = SCIPlpiStrongbranchesFrac(lp->lpi, lpipos, nsubcols, primsols, itlim, sbdown, sbup, sbdownvalid, sbupvalid, &iter);
    4796
    4797 /* check return code for errors */
    4798 if( retcode == SCIP_LPERROR )
    4799 {
    4800 *lperror = TRUE;
    4801
    4802 for( j = 0; j < nsubcols; ++j )
    4803 {
    4804 SCIP_COL* col;
    4805 int idx;
    4806
    4807 col = subcols[j];
    4808 idx = subidx[j];
    4809
    4810 col->sbdown = SCIP_INVALID;
    4811 col->sbup = SCIP_INVALID;
    4812 col->sbdownvalid = FALSE;
    4813 col->sbupvalid = FALSE;
    4814 col->validsblp = -1;
    4815 col->sbsolval = SCIP_INVALID;
    4816 col->sblpobjval = SCIP_INVALID;
    4817 col->sbnode = -1;
    4818
    4819 down[idx] = col->sbdown;
    4820 up[idx] = col->sbup;
    4821 if( downvalid != NULL )
    4822 downvalid[idx] = col->sbdownvalid;
    4823 if( upvalid != NULL )
    4824 upvalid[idx] = col->sbupvalid;
    4825 }
    4826 }
    4827 else
    4828 {
    4829 SCIP_Real looseobjval;
    4830
    4831 *lperror = FALSE;
    4832 SCIP_CALL( retcode );
    4833
    4834 looseobjval = getFiniteLooseObjval(lp, set, prob);
    4835
    4836 for( j = 0; j < nsubcols; ++j )
    4837 {
    4838 SCIP_COL* col;
    4839 int idx;
    4840
    4841 col = subcols[j];
    4842 idx = subidx[j];
    4843
    4844 assert( col->sbdown != SCIP_INVALID); /*lint !e777*/
    4845 assert( col->sbup != SCIP_INVALID); /*lint !e777*/
    4846
    4847 col->sbdown = MIN(sbdown[j] + looseobjval, lp->cutoffbound);
    4848 col->sbup = MIN(sbup[j] + looseobjval, lp->cutoffbound);
    4849 col->sbdownvalid = sbdownvalid[j];
    4850 col->sbupvalid = sbupvalid[j];
    4851
    4852 down[idx] = col->sbdown;
    4853 up[idx] = col->sbup;
    4854 if( downvalid != NULL )
    4855 downvalid[idx] = col->sbdownvalid;
    4856 if( upvalid != NULL )
    4857 upvalid[idx] = col->sbupvalid;
    4858 }
    4859
    4860 /* update strong branching statistics */
    4861 if( iter == -1 )
    4862 {
    4863 /* calculate average iteration number */
    4864 iter = stat->ndualresolvelps > 0 ? (int)(2*stat->ndualresolvelpiterations / stat->ndualresolvelps)
    4865 : stat->nduallps > 0 ? (int)((stat->nduallpiterations / stat->nduallps) / 5)
    4866 : stat->nprimalresolvelps > 0 ? (int)(2*stat->nprimalresolvelpiterations / stat->nprimalresolvelps)
    4867 : stat->nprimallps > 0 ? (int)((stat->nprimallpiterations / stat->nprimallps) / 5)
    4868 : 0;
    4869 if( iter/2 >= itlim )
    4870 iter = 2*itlim;
    4871 }
    4872 SCIPstatAdd(stat, set, nstrongbranchs, ncols);
    4873 SCIPstatAdd(stat, set, nsblpiterations, iter);
    4874 if( stat->nnodes == 1 )
    4875 {
    4876 SCIPstatAdd(stat, set, nrootstrongbranchs, ncols);
    4877 SCIPstatAdd(stat, set, nrootsblpiterations, iter);
    4878 }
    4879 }
    4880
    4881 SCIPsetFreeBufferArray(set, &sbupvalid);
    4882 SCIPsetFreeBufferArray(set, &sbdownvalid);
    4884 SCIPsetFreeBufferArray(set, &sbdown);
    4885 SCIPsetFreeBufferArray(set, &primsols);
    4886 SCIPsetFreeBufferArray(set, &lpipos);
    4887 SCIPsetFreeBufferArray(set, &subidx);
    4888 SCIPsetFreeBufferArray(set, &subcols);
    4889
    4890 /* stop timing */
    4892
    4893 return SCIP_OKAY;
    4894}
    4895
    4896/** gets last strong branching information available for a column variable;
    4897 * returns values of SCIP_INVALID, if strong branching was not yet called on the given column;
    4898 * keep in mind, that the returned old values may have nothing to do with the current LP solution
    4899 */
    4901 SCIP_COL* col, /**< LP column */
    4902 SCIP_Real* down, /**< stores dual bound after branching column down, or NULL */
    4903 SCIP_Real* up, /**< stores dual bound after branching column up, or NULL */
    4904 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
    4905 * otherwise, it can only be used as an estimate value */
    4906 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
    4907 * otherwise, it can only be used as an estimate value */
    4908 SCIP_Real* solval, /**< stores LP solution value of column at last strong branching call, or NULL */
    4909 SCIP_Real* lpobjval /**< stores LP objective value at last strong branching call, or NULL */
    4910 )
    4911{
    4912 assert(col != NULL);
    4913
    4914 if( down != NULL )
    4915 *down = col->sbdown;
    4916 if( up != NULL )
    4917 *up = col->sbup;
    4918 if( downvalid != NULL )
    4919 *downvalid = col->sbdownvalid;
    4920 if( upvalid != NULL )
    4921 *upvalid = col->sbupvalid;
    4922 if( solval != NULL )
    4923 *solval = col->sbsolval;
    4924 if( lpobjval != NULL )
    4925 *lpobjval = col->sblpobjval;
    4926}
    4927
    4928/** if strong branching was already applied on the column at the current node, returns the number of LPs solved after
    4929 * the LP where the strong branching on this column was applied;
    4930 * if strong branching was not yet applied on the column at the current node, returns INT_MAX
    4931 */
    4933 SCIP_COL* col, /**< LP column */
    4934 SCIP_STAT* stat /**< dynamic problem statistics */
    4935 )
    4936{
    4937 assert(col != NULL);
    4938 assert(stat != NULL);
    4939
    4940 return (col->sbnode != stat->nnodes ? SCIP_LONGINT_MAX : stat->nlps - col->validsblp);
    4941}
    4942
    4943/** marks a column to be not removable from the LP in the current node because it became obsolete */
    4945 SCIP_COL* col, /**< LP column */
    4946 SCIP_STAT* stat /**< problem statistics */
    4947 )
    4948{
    4949 assert(col != NULL);
    4950 assert(stat != NULL);
    4951 assert(stat->nnodes > 0);
    4952
    4953 /* lpRemoveObsoleteCols() does not remove a column if the node number stored in obsoletenode equals the current node number */
    4954 col->obsoletenode = stat->nnodes;
    4955}
    4956
    4957
    4958/*
    4959 * Row methods
    4960 */
    4961
    4962/** calculates row norms and min/maxidx from scratch, and checks for sorting */
    4963static
    4965 SCIP_ROW* row, /**< LP row */
    4966 SCIP_SET* set /**< global SCIP settings */
    4967 )
    4968{
    4969 int i;
    4970
    4971 assert(row != NULL);
    4972 assert(set != NULL);
    4973
    4974 row->sqrnorm = 0.0;
    4975 row->sumnorm = 0.0;
    4976 row->objprod = 0.0;
    4977 row->maxval = 0.0;
    4978 row->nummaxval = 1;
    4979 row->minval = SCIPsetInfinity(set);
    4980 row->numminval = 1;
    4981 row->minidx = INT_MAX;
    4982 row->maxidx = INT_MIN;
    4983 row->validminmaxidx = TRUE;
    4984 row->lpcolssorted = TRUE;
    4985 row->nonlpcolssorted = TRUE;
    4986
    4987 /* check, if row is sorted
    4988 * calculate sqrnorm, sumnorm, maxval, minval, minidx, and maxidx
    4989 */
    4990 for( i = 0; i < row->nlpcols; ++i )
    4991 {
    4992 assert(row->cols[i] != NULL);
    4993 assert(!SCIPsetIsZero(set, row->vals[i]));
    4994 assert(row->cols[i]->lppos >= 0);
    4995 assert(row->linkpos[i] >= 0);
    4996 assert(row->cols[i]->index == row->cols_index[i]);
    4997
    4998 rowAddNorms(row, set, row->cols[i], row->vals[i], TRUE);
    4999 if( i > 0 )
    5000 {
    5001 assert(row->cols[i-1]->index == row->cols_index[i-1]);
    5002 row->lpcolssorted = row->lpcolssorted && (row->cols_index[i-1] < row->cols_index[i]);
    5003 }
    5004 }
    5005 for( i = row->nlpcols; i < row->len; ++i )
    5006 {
    5007 assert(row->cols[i] != NULL);
    5008 assert(!SCIPsetIsZero(set, row->vals[i]));
    5009 assert(row->cols[i]->lppos == -1 || row->linkpos[i] == -1);
    5010 assert(row->cols[i]->index == row->cols_index[i]);
    5011
    5012 rowAddNorms(row, set, row->cols[i], row->vals[i], TRUE);
    5013 if( i > row->nlpcols )
    5014 {
    5015 assert(row->cols[i-1]->index == row->cols_index[i-1]);
    5016 row->nonlpcolssorted = row->nonlpcolssorted && (row->cols_index[i-1] < row->cols_index[i]);
    5017 }
    5018 }
    5019}
    5020
    5021/** calculates min/maxval and min/maxidx from scratch */
    5022static
    5024 SCIP_ROW* row, /**< LP row */
    5025 SCIP_SET* set /**< global SCIP settings */
    5026 )
    5027{
    5028 SCIP_COL* col;
    5029 SCIP_Real absval;
    5030 int i;
    5031
    5032 assert(row != NULL);
    5033 assert(set != NULL);
    5034
    5035 row->maxval = 0.0;
    5036 row->nummaxval = 1;
    5037 row->numintcols = 0;
    5038 row->numimplintcols = 0;
    5039 row->minval = SCIPsetInfinity(set);
    5040 row->numminval = 1;
    5041 row->minidx = INT_MAX;
    5042 row->maxidx = INT_MIN;
    5043 row->validminmaxidx = TRUE;
    5044
    5045 /* calculate maxval, minval, minidx, and maxidx */
    5046 for( i = 0; i < row->len; ++i )
    5047 {
    5048 col = row->cols[i];
    5049 assert(col != NULL);
    5050 assert(!SCIPsetIsZero(set, row->vals[i]));
    5051
    5052 absval = REALABS(row->vals[i]);
    5053 assert(!SCIPsetIsZero(set, absval));
    5054
    5055 /* update min/maxidx */
    5056 row->minidx = MIN(row->minidx, col->index);
    5057 row->maxidx = MAX(row->maxidx, col->index);
    5058 if( SCIPcolIsIntegral(col) )
    5059 {
    5060 ++row->numintcols;
    5061 if( SCIPcolIsImpliedIntegral(col) )
    5062 ++row->numimplintcols;
    5063 }
    5064
    5065 /* update maximal and minimal non-zero value */
    5066 if( row->nummaxval > 0 )
    5067 {
    5068 if( SCIPsetIsGT(set, absval, row->maxval) )
    5069 {
    5070 row->maxval = absval;
    5071 row->nummaxval = 1;
    5072 }
    5073 else if( SCIPsetIsGE(set, absval, row->maxval) )
    5074 {
    5075 /* make sure the maxval is always exactly the same */
    5076 row->maxval = MAX(absval, row->maxval);
    5077 row->nummaxval++;
    5078 }
    5079 }
    5080 if( row->numminval > 0 )
    5081 {
    5082 if( SCIPsetIsLT(set, absval, row->minval) )
    5083 {
    5084 row->minval = absval;
    5085 row->numminval = 1;
    5086 }
    5087 else if( SCIPsetIsLE(set, absval, row->minval) )
    5088 {
    5089 /* make sure the minval is always exactly the same */
    5090 row->minval = MIN(absval, row->minval);
    5091 row->numminval++;
    5092 }
    5093 }
    5094 }
    5095}
    5096
    5097/** checks whether the given scalar scales the given value to an integral number with error in the given bounds */
    5098static
    5100 SCIP_Real val, /**< value that should be scaled to an integral value */
    5101 SCIP_Real scalar, /**< scalar that should be tried */
    5102 SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
    5103 SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
    5104 SCIP_Real* intval /**< pointer to store the scaled integral value, or NULL */
    5105 )
    5106{
    5107 SCIP_Real sval;
    5108 SCIP_Real downval;
    5109 SCIP_Real upval;
    5110
    5111 assert(mindelta <= 0.0);
    5112 assert(maxdelta >= 0.0);
    5113
    5114 sval = val * scalar;
    5115 downval = floor(sval);
    5116 upval = ceil(sval);
    5117
    5118 if( SCIPrelDiff(sval, downval) <= maxdelta )
    5119 {
    5120 if( intval != NULL )
    5121 *intval = downval;
    5122 return TRUE;
    5123 }
    5124 else if( SCIPrelDiff(sval, upval) >= mindelta )
    5125 {
    5126 if( intval != NULL )
    5127 *intval = upval;
    5128 return TRUE;
    5129 }
    5130
    5131 return FALSE;
    5132}
    5133
    5134/** scales row with given factor, and rounds coefficients to integers if close enough;
    5135 * the constant is automatically moved to the sides;
    5136 * if the row's activity is proven to be integral, the sides are automatically rounded to the next integer
    5137 */
    5138static
    5140 SCIP_ROW* row, /**< LP row */
    5141 BMS_BLKMEM* blkmem, /**< block memory */
    5142 SCIP_SET* set, /**< global SCIP settings */
    5143 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    5144 SCIP_STAT* stat, /**< problem statistics */
    5145 SCIP_LP* lp, /**< current LP data */
    5146 SCIP_Real scaleval, /**< value to scale row with */
    5147 SCIP_Bool integralcontvars, /**< should the coefficients of the continuous variables also be made integral,
    5148 * if they are close to integral values? */
    5149 SCIP_Real minrounddelta, /**< minimal relative difference of scaled coefficient s*c and integral i,
    5150 * upto which the integral is used instead of the scaled real coefficient */
    5151 SCIP_Real maxrounddelta /**< maximal relative difference of scaled coefficient s*c and integral i
    5152 * upto which the integral is used instead of the scaled real coefficient */
    5153 )
    5154{
    5155 SCIP_COL* col;
    5156 SCIP_Real val;
    5157 SCIP_Real newval;
    5158 SCIP_Real intval;
    5159 SCIP_Real mindelta;
    5160 SCIP_Real maxdelta;
    5161 SCIP_Real lb;
    5162 SCIP_Real ub;
    5163 SCIP_Bool mindeltainf;
    5164 SCIP_Bool maxdeltainf;
    5165 int oldlen;
    5166 int c;
    5167
    5168 assert(row != NULL);
    5169 assert(row->len == 0 || row->cols != NULL);
    5170 assert(row->len == 0 || row->vals != NULL);
    5171 assert(SCIPsetIsPositive(set, scaleval));
    5172 assert(-1.0 < minrounddelta && minrounddelta <= 0.0);
    5173 assert(0.0 <= maxrounddelta && maxrounddelta < 1.0);
    5174
    5175 SCIPsetDebugMsg(set, "scale row <%s> with %g (tolerance=[%g,%g])\n", row->name, scaleval, minrounddelta, maxrounddelta);
    5176
    5177 mindelta = 0.0;
    5178 maxdelta = 0.0;
    5179 mindeltainf = FALSE;
    5180 maxdeltainf = FALSE;
    5181 oldlen = row->len;
    5182
    5183 /* scale the row coefficients, thereby recalculating whether the row's activity is always integral;
    5184 * if the row coefficients are rounded to the nearest integer value, calculate the maximal activity difference,
    5185 * this rounding can lead to
    5186 */
    5187 row->integral = TRUE;
    5188
    5189 c = 0;
    5190 while( c < row->len )
    5191 {
    5192 col = row->cols[c];
    5193 val = row->vals[c];
    5194 assert(!SCIPsetIsZero(set, val));
    5195
    5196 /* get local or global bounds for column, depending on the local or global feasibility of the row */
    5197 if( row->local )
    5198 {
    5199 lb = col->lb;
    5200 ub = col->ub;
    5201 }
    5202 else
    5203 {
    5204 lb = SCIPvarGetLbGlobal(col->var);
    5205 ub = SCIPvarGetUbGlobal(col->var);
    5206 }
    5207
    5208 /* calculate scaled coefficient */
    5209 newval = val * scaleval;
    5210 if( (integralcontvars || SCIPcolIsIntegral(col) || SCIPsetIsIntegral(set, newval))
    5211 && isIntegralScalar(val, scaleval, minrounddelta, maxrounddelta, &intval) )
    5212 {
    5213 if( !SCIPsetIsEQ(set, intval, newval) )
    5214 {
    5215 if( intval < newval )
    5216 {
    5217 mindelta += (intval - newval)*ub;
    5218 maxdelta += (intval - newval)*lb;
    5219 mindeltainf = mindeltainf || SCIPsetIsInfinity(set, ub);
    5220 maxdeltainf = maxdeltainf || SCIPsetIsInfinity(set, -lb);
    5221 }
    5222 else
    5223 {
    5224 mindelta += (intval - newval)*lb;
    5225 maxdelta += (intval - newval)*ub;
    5226 mindeltainf = mindeltainf || SCIPsetIsInfinity(set, -lb);
    5227 maxdeltainf = maxdeltainf || SCIPsetIsInfinity(set, ub);
    5228 }
    5229 }
    5230 newval = intval;
    5231 }
    5232
    5233 if( !SCIPsetIsEQ(set, val, newval) )
    5234 {
    5235 /* if column knows of the row, change the corresponding coefficient in the column */
    5236 if( row->linkpos[c] >= 0 )
    5237 {
    5238 assert(col->rows[row->linkpos[c]] == row);
    5239 assert(SCIPsetIsEQ(set, col->vals[row->linkpos[c]], row->vals[c]));
    5240 SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[c], newval) );
    5241 }
    5242
    5243 /* change the coefficient in the row, and update the norms and integrality status */
    5244 SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, c, newval) );
    5245
    5246 /* current coefficient has been deleted from the row because it was almost zero */
    5247 if( oldlen != row->len )
    5248 {
    5249 assert(row->len == oldlen - 1);
    5250 c--;
    5251 oldlen = row->len;
    5252 }
    5253 }
    5254 else
    5255 {
    5256 row->integral = row->integral && SCIPcolIsIntegral(col) && SCIPsetIsIntegral(set, val);
    5257 if( set->exact_enable )
    5259 }
    5260
    5261 ++c;
    5262 }
    5263
    5264 /* scale the row sides, and move the constant to the sides; relax the sides with accumulated delta in order
    5265 * to not destroy feasibility due to rounding
    5266 */
    5267 /**@todo ensure that returned cut does not have infinite lhs and rhs */
    5268 if( !SCIPsetIsInfinity(set, -row->lhs) )
    5269 {
    5270 if( mindeltainf )
    5271 newval = -SCIPsetInfinity(set);
    5272 else
    5273 {
    5274 newval = (row->lhs - row->constant) * scaleval + mindelta;
    5275 if( SCIPsetIsIntegral(set, newval) || (row->integral && !row->modifiable) )
    5276 newval = SCIPsetSumCeil(set, newval);
    5277 }
    5278 SCIP_CALL( SCIProwChgLhs(row, blkmem, set, eventqueue, lp, newval) );
    5279 }
    5280 if( !SCIPsetIsInfinity(set, row->rhs) )
    5281 {
    5282 if( maxdeltainf )
    5283 newval = SCIPsetInfinity(set);
    5284 else
    5285 {
    5286 newval = (row->rhs - row->constant) * scaleval + maxdelta;
    5287 if( SCIPsetIsIntegral(set, newval) || (row->integral && !row->modifiable) )
    5288 newval = SCIPsetSumFloor(set, newval);
    5289 }
    5290 SCIP_CALL( SCIProwChgRhs(row, blkmem, set, eventqueue, lp, newval) );
    5291 }
    5292
    5293 /* clear the row constant */
    5294 SCIP_CALL( SCIProwChgConstant(row, blkmem, set, stat, eventqueue, lp, 0.0) );
    5295
    5296 SCIPsetDebugMsg(set, "scaled row <%s> (integral: %u)\n", row->name, row->integral);
    5297 debugRowPrint(set, row);
    5298
    5299#ifdef SCIP_DEBUG
    5300 /* check integrality status of row */
    5301 for( c = 0; c < row->len && SCIPcolIsIntegral(row->cols[c]) && SCIPsetIsIntegral(set, row->vals[c]); ++c )
    5302 {}
    5303 assert(row->integral == (c == row->len));
    5304#endif
    5305
    5306 /* invalid the activity */
    5307 row->validactivitylp = -1;
    5308
    5309 return SCIP_OKAY;
    5310}
    5311
    5312/** creates and captures an LP row */
    5314 SCIP_ROW** row, /**< pointer to LP row data */
    5315 BMS_BLKMEM* blkmem, /**< block memory */
    5316 SCIP_SET* set, /**< global SCIP settings */
    5317 SCIP_STAT* stat, /**< problem statistics */
    5318 const char* name, /**< name of row */
    5319 int len, /**< number of nonzeros in the row */
    5320 SCIP_COL** cols, /**< array with columns of row entries */
    5321 SCIP_Real* vals, /**< array with coefficients of row entries */
    5322 SCIP_Real lhs, /**< left hand side of row */
    5323 SCIP_Real rhs, /**< right hand side of row */
    5324 SCIP_ROWORIGINTYPE origintype, /**< type of origin of row */
    5325 void* origin, /**< pointer to constraint handler or separator who created the row (NULL if unkown) */
    5326 SCIP_Bool local, /**< is row only valid locally? */
    5327 SCIP_Bool modifiable, /**< is row modifiable during node processing (subject to column generation)? */
    5328 SCIP_Bool removable /**< should the row be removed from the LP due to aging or cleanup? */
    5329 )
    5330{
    5331 assert(row != NULL);
    5332 assert(blkmem != NULL);
    5333 assert(stat != NULL);
    5334 assert(len >= 0);
    5335 assert(len == 0 || (cols != NULL && vals != NULL));
    5336 /* note, that the assert tries to avoid numerical troubles in the LP solver.
    5337 * in case, for example, lhs > rhs but they are equal with tolerances, one could pass lhs=rhs=lhs+rhs/2 to
    5338 * SCIProwCreate() (see cons_linear.c: detectRedundantConstraints())
    5339 */
    5340 assert(lhs <= rhs);
    5341
    5342 SCIP_ALLOC( BMSallocBlockMemory(blkmem, row) );
    5343
    5344 (*row)->integral = TRUE;
    5345 if( len > 0 )
    5346 {
    5347 SCIP_VAR* var;
    5348 int i;
    5349
    5350 SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->cols, cols, len) );
    5351 SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->vals, vals, len) );
    5352 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*row)->cols_index, len) );
    5353 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*row)->linkpos, len) );
    5354
    5355 for( i = 0; i < len; ++i )
    5356 {
    5357 assert(cols[i] != NULL);
    5358 assert(!SCIPsetIsZero(set, vals[i]));
    5359
    5360 var = cols[i]->var;
    5361 (*row)->cols_index[i] = cols[i]->index;
    5362 (*row)->linkpos[i] = -1;
    5363 if( SCIPsetIsIntegral(set, (*row)->vals[i]) && !set->exact_enable )
    5364 {
    5365 (*row)->vals[i] = SCIPsetRound(set, (*row)->vals[i]);
    5366 (*row)->integral = (*row)->integral && SCIPvarIsIntegral(var);
    5367 }
    5368 else
    5369 {
    5370 (*row)->integral = FALSE;
    5371 }
    5372 }
    5373 }
    5374 else
    5375 {
    5376 (*row)->cols = NULL;
    5377 (*row)->cols_index = NULL;
    5378 (*row)->vals = NULL;
    5379 (*row)->linkpos = NULL;
    5380 }
    5381
    5382 SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->name, name, strlen(name)+1) );
    5383 (*row)->constant = 0.0;
    5384 (*row)->lhs = lhs;
    5385 (*row)->rhs = rhs;
    5386 (*row)->flushedlhs = -SCIPsetInfinity(set);
    5387 (*row)->flushedrhs = SCIPsetInfinity(set);
    5388 (*row)->sqrnorm = 0.0;
    5389 (*row)->sumnorm = 0.0;
    5390 (*row)->objprod = 0.0;
    5391 (*row)->maxval = 0.0;
    5392 (*row)->minval = SCIPsetInfinity(set);
    5393 (*row)->dualsol = 0.0;
    5394 (*row)->activity = SCIP_INVALID;
    5395 (*row)->dualfarkas = 0.0;
    5396 (*row)->pseudoactivity = SCIP_INVALID;
    5397 (*row)->minactivity = SCIP_INVALID;
    5398 (*row)->maxactivity = SCIP_INVALID;
    5399 (*row)->origin = origin;
    5400 (*row)->eventfilter = NULL;
    5401 (*row)->index = stat->nrowidx;
    5402 SCIPstatIncrement(stat, set, nrowidx);
    5403 (*row)->size = len;
    5404 (*row)->len = len;
    5405 (*row)->nlpcols = 0;
    5406 (*row)->nunlinked = len;
    5407 (*row)->nuses = 0;
    5408 (*row)->lppos = -1;
    5409 (*row)->lpipos = -1;
    5410 (*row)->lpdepth = -1;
    5411 (*row)->minidx = INT_MAX;
    5412 (*row)->maxidx = INT_MIN;
    5413 (*row)->nummaxval = 0;
    5414 (*row)->numminval = 0;
    5415 (*row)->numintcols = -1;
    5416 (*row)->numimplintcols = -1;
    5417 (*row)->validactivitylp = -1;
    5418 (*row)->validpsactivitydomchg = -1;
    5419 (*row)->validactivitybdsdomchg = -1;
    5420 (*row)->nlpsaftercreation = 0L;
    5421 (*row)->activeinlpcounter = 0L;
    5422 (*row)->age = 0;
    5423 (*row)->rank = 0;
    5424 (*row)->obsoletenode = -1;
    5425 (*row)->fromcutpool = FALSE;
    5426 (*row)->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
    5427 (*row)->lpcolssorted = TRUE;
    5428 (*row)->nonlpcolssorted = (len <= 1);
    5429 (*row)->delaysort = FALSE;
    5430 (*row)->validminmaxidx = FALSE;
    5431 (*row)->lhschanged = FALSE;
    5432 (*row)->rhschanged = FALSE;
    5433 (*row)->coefchanged = FALSE;
    5434 (*row)->local = local;
    5435 (*row)->modifiable = modifiable;
    5436 (*row)->nlocks = 0;
    5437 (*row)->origintype = origintype; /*lint !e641*/
    5438 (*row)->removable = removable;
    5439 (*row)->inglobalcutpool = FALSE;
    5440 (*row)->storedsolvals = NULL;
    5441 (*row)->rowexact = NULL;
    5442
    5443 /* calculate row norms and min/maxidx, and check if row is sorted */
    5444 rowCalcNorms(*row, set);
    5445
    5446 /* capture the row */
    5447 SCIProwCapture(*row);
    5448
    5449 /* create event filter */
    5450 SCIP_CALL( SCIPeventfilterCreate(&(*row)->eventfilter, blkmem) );
    5451
    5452 /* capture origin constraint if available */
    5453 if( origintype == SCIP_ROWORIGINTYPE_CONS )
    5454 {
    5455 SCIP_CONS* cons = (SCIP_CONS*) origin;
    5456 assert(cons != NULL);
    5457 SCIPconsCapture(cons);
    5458 }
    5459
    5460 return SCIP_OKAY;
    5461} /*lint !e715*/
    5462
    5463/** frees an LP row */
    5465 SCIP_ROW** row, /**< pointer to LP row */
    5466 BMS_BLKMEM* blkmem, /**< block memory */
    5467 SCIP_SET* set, /**< global SCIP settings */
    5468 SCIP_LP* lp /**< current LP data */
    5469 )
    5470{
    5471 assert(blkmem != NULL);
    5472 assert(row != NULL);
    5473 assert(*row != NULL);
    5474 assert((*row)->nuses == 0);
    5475 assert((*row)->lppos == -1);
    5476 assert((*row)->eventfilter != NULL);
    5477
    5478 /* release constraint that has been used for creating the row */
    5479 if( (SCIP_ROWORIGINTYPE) (*row)->origintype == SCIP_ROWORIGINTYPE_CONS )
    5480 {
    5481 SCIP_CONS* cons = (SCIP_CONS*) (*row)->origin;
    5482 assert(cons != NULL);
    5483 SCIP_CALL( SCIPconsRelease(&cons, blkmem, set) );
    5484 }
    5485
    5486 /* remove column indices from corresponding rows */
    5487 SCIP_CALL( rowUnlink(*row, set, lp) );
    5488
    5489 /* free event filter */
    5490 SCIP_CALL( SCIPeventfilterFree(&(*row)->eventfilter, blkmem, set) );
    5491
    5492 BMSfreeBlockMemoryNull(blkmem, &(*row)->storedsolvals);
    5493 BMSfreeBlockMemoryArray(blkmem, &(*row)->name, strlen((*row)->name)+1);
    5494 BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->cols, (*row)->size);
    5495 BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->cols_index, (*row)->size);
    5496 BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->vals, (*row)->size);
    5497 BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->linkpos, (*row)->size);
    5498
    5499 if( (*row)->rowexact != NULL )
    5500 {
    5501 if( *row == (*row)->rowexact->fprow )
    5502 (*row)->rowexact->fprow = NULL;
    5503 else
    5504 (*row)->rowexact->fprowrhs = NULL;
    5505 SCIP_CALL( SCIProwExactRelease(&(*row)->rowexact, blkmem, set, lp->lpexact) );
    5506 }
    5507
    5508 BMSfreeBlockMemory(blkmem, row);
    5509
    5510 return SCIP_OKAY;
    5511}
    5512
    5513/** output row to file stream */
    5515 SCIP_ROW* row, /**< LP row */
    5516 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    5517 FILE* file /**< output file (or NULL for standard output) */
    5518 )
    5519{
    5520 int i;
    5521
    5522 assert(row != NULL);
    5523
    5524 /* print row name */
    5525 if( row->name != NULL && row->name[0] != '\0' )
    5526 {
    5527 SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", row->name);
    5528 }
    5529
    5530 /* print left hand side */
    5531 SCIPmessageFPrintInfo(messagehdlr, file, "%.15g <= ", row->lhs);
    5532
    5533 /* print coefficients */
    5534 if( row->len == 0 )
    5535 SCIPmessageFPrintInfo(messagehdlr, file, "0 ");
    5536 for( i = 0; i < row->len; ++i )
    5537 {
    5538 assert(row->cols[i] != NULL);
    5539 assert(row->cols[i]->var != NULL);
    5540 assert(SCIPvarGetName(row->cols[i]->var) != NULL);
    5541 assert(SCIPvarGetStatus(row->cols[i]->var) == SCIP_VARSTATUS_COLUMN);
    5542 SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g<%s> ", row->vals[i], SCIPvarGetName(row->cols[i]->var));
    5543 }
    5544
    5545 /* print constant */
    5547 SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g ", row->constant);
    5548
    5549 /* print right hand side */
    5550 SCIPmessageFPrintInfo(messagehdlr, file, "<= %.15g\n", row->rhs);
    5551}
    5552
    5553/** increases usage counter of LP row */
    5555 SCIP_ROW* row /**< LP row */
    5556 )
    5557{
    5558 assert(row != NULL);
    5559 assert(row->nuses >= 0);
    5560 assert(row->nlocks <= (unsigned int)(row->nuses)); /*lint !e574*/
    5561
    5562 SCIPdebugMessage("capture row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
    5563 row->nuses++;
    5564}
    5565
    5566/** decreases usage counter of LP row, and frees memory if necessary */
    5568 SCIP_ROW** row, /**< pointer to LP row */
    5569 BMS_BLKMEM* blkmem, /**< block memory */
    5570 SCIP_SET* set, /**< global SCIP settings */
    5571 SCIP_LP* lp /**< current LP data */
    5572 )
    5573{
    5574 assert(blkmem != NULL);
    5575 assert(row != NULL);
    5576 assert(*row != NULL);
    5577 assert((*row)->nuses >= 1);
    5578 assert((*row)->nlocks < (unsigned int)((*row)->nuses)); /*lint !e574*/
    5579
    5580 SCIPsetDebugMsg(set, "release row <%s> with nuses=%d and nlocks=%u\n", (*row)->name, (*row)->nuses, (*row)->nlocks);
    5581 (*row)->nuses--;
    5582 if( (*row)->nuses == 0 )
    5583 {
    5584 SCIP_CALL( SCIPcertificateFreeRowInfo(set->scip, (*row)) );
    5585 SCIP_CALL( SCIProwFree(row, blkmem, set, lp) );
    5586 }
    5587
    5588 *row = NULL;
    5589
    5590 return SCIP_OKAY;
    5591}
    5592
    5593/** locks an unmodifiable row, which forbids further changes; has no effect on modifiable rows */
    5595 SCIP_ROW* row /**< LP row */
    5596 )
    5597{
    5598 assert(row != NULL);
    5599
    5600 /* check, if row is modifiable */
    5601 if( !row->modifiable )
    5602 {
    5603 SCIPdebugMessage("lock row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
    5604 row->nlocks++;
    5605 }
    5606}
    5607
    5608/** unlocks a lock of an unmodifiable row; a row with no sealed lock may be modified; has no effect on modifiable rows */
    5610 SCIP_ROW* row /**< LP row */
    5611 )
    5612{
    5613 assert(row != NULL);
    5614
    5615 /* check, if row is modifiable */
    5616 if( !row->modifiable )
    5617 {
    5618 SCIPdebugMessage("unlock row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
    5619 assert(row->nlocks > 0);
    5620 row->nlocks--;
    5621 }
    5622}
    5623
    5624/** adds a previously non existing coefficient to an LP row */
    5626 SCIP_ROW* row, /**< LP row */
    5627 BMS_BLKMEM* blkmem, /**< block memory */
    5628 SCIP_SET* set, /**< global SCIP settings */
    5629 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    5630 SCIP_LP* lp, /**< current LP data */
    5631 SCIP_COL* col, /**< LP column */
    5632 SCIP_Real val /**< value of coefficient */
    5633 )
    5634{
    5635 assert(lp != NULL);
    5636 assert(!lp->diving || row->lppos == -1);
    5637
    5638 SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, val, -1) );
    5639
    5640 checkLinks(lp);
    5641
    5642 return SCIP_OKAY;
    5643}
    5644
    5645/** deletes coefficient from row */
    5647 SCIP_ROW* row, /**< row to be changed */
    5648 BMS_BLKMEM* blkmem, /**< block memory */
    5649 SCIP_SET* set, /**< global SCIP settings */
    5650 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    5651 SCIP_LP* lp, /**< current LP data */
    5652 SCIP_COL* col /**< coefficient to be deleted */
    5653 )
    5654{
    5655 int pos;
    5656
    5657 assert(row != NULL);
    5658 assert(!row->delaysort);
    5659 assert(lp != NULL);
    5660 assert(!lp->diving || row->lppos == -1);
    5661 assert(col != NULL);
    5662 assert(col->var != NULL);
    5663
    5664 /* search the position of the column in the row's col vector */
    5665 pos = rowSearchCoef(row, col);
    5666 if( pos == -1 )
    5667 {
    5668 SCIPerrorMessage("coefficient for column <%s> doesn't exist in row <%s>\n", SCIPvarGetName(col->var), row->name);
    5669 return SCIP_INVALIDDATA;
    5670 }
    5671 assert(0 <= pos && pos < row->len);
    5672 assert(row->cols[pos] == col);
    5673 assert(row->cols_index[pos] == col->index);
    5674
    5675 /* if column knows of the row, remove the row from the column's row vector */
    5676 if( row->linkpos[pos] >= 0 )
    5677 {
    5678 assert(col->rows[row->linkpos[pos]] == row);
    5679 assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
    5680 SCIP_CALL( colDelCoefPos(col, set, lp, row->linkpos[pos]) );
    5681 }
    5682
    5683 /* delete the column from the row's col vector */
    5684 SCIP_CALL( rowDelCoefPos(row, blkmem, set, eventqueue, lp, pos) );
    5685
    5686 checkLinks(lp);
    5687
    5688 return SCIP_OKAY;
    5689}
    5690
    5691/** changes or adds a coefficient to an LP row */
    5693 SCIP_ROW* row, /**< LP row */
    5694 BMS_BLKMEM* blkmem, /**< block memory */
    5695 SCIP_SET* set, /**< global SCIP settings */
    5696 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    5697 SCIP_LP* lp, /**< current LP data */
    5698 SCIP_COL* col, /**< LP column */
    5699 SCIP_Real val /**< value of coefficient */
    5700 )
    5701{
    5702 int pos;
    5703
    5704 assert(row != NULL);
    5705 assert(!row->delaysort);
    5706 assert(lp != NULL);
    5707 assert(!lp->diving || row->lppos == -1);
    5708 assert(col != NULL);
    5709
    5710 /* search the position of the column in the row's col vector */
    5711 pos = rowSearchCoef(row, col);
    5712
    5713 /* check, if column already exists in the row's col vector */
    5714 if( pos == -1 )
    5715 {
    5716 /* add previously not existing coefficient */
    5717 SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, val, -1) );
    5718 }
    5719 else
    5720 {
    5721 /* modify already existing coefficient */
    5722 assert(0 <= pos && pos < row->len);
    5723 assert(row->cols[pos] == col);
    5724 assert(row->cols_index[pos] == col->index);
    5725
    5726 /* if column knows of the row, change the corresponding coefficient in the column */
    5727 if( row->linkpos[pos] >= 0 )
    5728 {
    5729 assert(col->rows[row->linkpos[pos]] == row);
    5730 assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
    5731 SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[pos], val) );
    5732 }
    5733
    5734 /* change the coefficient in the row */
    5735 SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, pos, val) );
    5736 }
    5737
    5738 checkLinks(lp);
    5739
    5740 return SCIP_OKAY;
    5741}
    5742
    5743/** increases value of an existing or non-existing coefficient in an LP row */
    5745 SCIP_ROW* row, /**< LP row */
    5746 BMS_BLKMEM* blkmem, /**< block memory */
    5747 SCIP_SET* set, /**< global SCIP settings */
    5748 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    5749 SCIP_LP* lp, /**< current LP data */
    5750 SCIP_COL* col, /**< LP column */
    5751 SCIP_Real incval /**< value to add to the coefficient */
    5752 )
    5753{
    5754 int pos;
    5755
    5756 assert(row != NULL);
    5757 assert(lp != NULL);
    5758 assert(!lp->diving || row->lppos == -1);
    5759 assert(col != NULL);
    5760
    5761 if( SCIPsetIsZero(set, incval) )
    5762 return SCIP_OKAY;
    5763
    5764 /* search the position of the column in the row's col vector */
    5765 pos = rowSearchCoef(row, col);
    5766
    5767 /* check, if column already exists in the row's col vector */
    5768 if( pos == -1 )
    5769 {
    5770 /* coefficient doesn't exist, or sorting is delayed: add coefficient to the end of the row's arrays */
    5771 SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, incval, -1) );
    5772 }
    5773 else
    5774 {
    5775 /* modify already existing coefficient */
    5776 assert(0 <= pos && pos < row->len);
    5777 assert(row->cols[pos] == col);
    5778 assert(row->cols_index[pos] == col->index);
    5779
    5780 /* if column knows of the row, change the corresponding coefficient in the column */
    5781 if( row->linkpos[pos] >= 0 )
    5782 {
    5783 assert(col->rows[row->linkpos[pos]] == row);
    5784 assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
    5785 SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[pos], row->vals[pos] + incval) );
    5786 }
    5787
    5788 /* change the coefficient in the row */
    5789 SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, pos, row->vals[pos] + incval) );
    5790 }
    5791
    5792 checkLinks(lp);
    5793
    5794 /* invalid the activity */
    5795 row->validactivitylp = -1;
    5796
    5797 return SCIP_OKAY;
    5798}
    5799
    5800/** changes constant value of a row */
    5802 SCIP_ROW* row, /**< LP row */
    5803 BMS_BLKMEM* blkmem, /**< block memory */
    5804 SCIP_SET* set, /**< global SCIP settings */
    5805 SCIP_STAT* stat, /**< problem statistics */
    5806 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    5807 SCIP_LP* lp, /**< current LP data */
    5808 SCIP_Real constant /**< new constant value */
    5809 )
    5810{
    5811 assert(row != NULL);
    5812 assert(row->lhs <= row->rhs);
    5813 assert(!SCIPsetIsInfinity(set, REALABS(constant)));
    5814 assert(stat != NULL);
    5815 assert(lp != NULL);
    5816 assert(!lp->diving || row->lppos == -1);
    5817
    5818 if( !SCIPsetIsEQ(set, constant, row->constant) )
    5819 {
    5820 SCIP_Real oldconstant;
    5821
    5822 if( row->validpsactivitydomchg == stat->domchgcount )
    5823 {
    5824 assert(row->pseudoactivity != SCIP_INVALID); /*lint !e777*/
    5825 row->pseudoactivity += constant - row->constant;
    5826 }
    5827 if( row->validactivitybdsdomchg == stat->domchgcount )
    5828 {
    5829 assert(row->minactivity != SCIP_INVALID); /*lint !e777*/
    5830 assert(row->maxactivity != SCIP_INVALID); /*lint !e777*/
    5831 row->minactivity += constant - row->constant;
    5832 row->maxactivity += constant - row->constant;
    5833 }
    5834
    5835 if( !SCIPsetIsInfinity(set, -row->lhs) )
    5836 {
    5838 }
    5839 if( !SCIPsetIsInfinity(set, row->rhs) )
    5840 {
    5842 }
    5843
    5844 oldconstant = row->constant;
    5845
    5846 row->constant = constant;
    5847
    5848 /* issue row constant changed event */
    5849 SCIP_CALL( rowEventConstantChanged(row, blkmem, set, eventqueue, oldconstant, constant) );
    5850 }
    5851
    5852 return SCIP_OKAY;
    5853}
    5854
    5855/** add constant value to a row */
    5857 SCIP_ROW* row, /**< LP row */
    5858 BMS_BLKMEM* blkmem, /**< block memory */
    5859 SCIP_SET* set, /**< global SCIP settings */
    5860 SCIP_STAT* stat, /**< problem statistics */
    5861 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    5862 SCIP_LP* lp, /**< current LP data */
    5863 SCIP_Real addval /**< constant value to add to the row */
    5864 )
    5865{
    5866 assert(row != NULL);
    5867 assert(row->lhs <= row->rhs);
    5868 assert(!SCIPsetIsInfinity(set, REALABS(addval)));
    5869 assert(stat != NULL);
    5870 assert(lp != NULL);
    5871 assert(!lp->diving || row->lppos == -1);
    5872
    5873 if( !SCIPsetIsZero(set, addval) )
    5874 {
    5875 SCIP_CALL( SCIProwChgConstant(row, blkmem, set, stat, eventqueue, lp, row->constant + addval) );
    5876 }
    5877
    5878 return SCIP_OKAY;
    5879}
    5880
    5881/** changes left hand side of LP row */
    5883 SCIP_ROW* row, /**< LP row */
    5884 BMS_BLKMEM* blkmem, /**< block memory */
    5885 SCIP_SET* set, /**< global SCIP settings */
    5886 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    5887 SCIP_LP* lp, /**< current LP data */
    5888 SCIP_Real lhs /**< new left hand side */
    5889 )
    5890{
    5891 assert(row != NULL);
    5892 assert(lp != NULL);
    5893
    5894 if( !SCIPsetIsEQ(set, row->lhs, lhs) || (set->exact_enable && row->lhs != lhs) ) /*lint !e777*/
    5895 {
    5896 SCIP_Real oldlhs;
    5897
    5898 oldlhs = row->lhs;
    5899
    5900 row->lhs = lhs;
    5902
    5903 if( !lp->diving )
    5904 {
    5905 /* issue row side changed event */
    5906 SCIP_CALL( rowEventSideChanged(row, blkmem, set, eventqueue, SCIP_SIDETYPE_LEFT, oldlhs, lhs) );
    5907 }
    5908 }
    5909
    5910 return SCIP_OKAY;
    5911}
    5912
    5913/** changes right hand side of LP row */
    5915 SCIP_ROW* row, /**< LP row */
    5916 BMS_BLKMEM* blkmem, /**< block memory */
    5917 SCIP_SET* set, /**< global SCIP settings */
    5918 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    5919 SCIP_LP* lp, /**< current LP data */
    5920 SCIP_Real rhs /**< new right hand side */
    5921 )
    5922{
    5923 assert(row != NULL);
    5924 assert(lp != NULL);
    5925
    5926 if( !SCIPsetIsEQ(set, row->rhs, rhs) || (set->exact_enable && row->rhs != rhs) ) /*lint !e777*/
    5927 {
    5928 SCIP_Real oldrhs;
    5929
    5930 oldrhs = row->rhs;
    5931
    5932 row->rhs = rhs;
    5934
    5935 if( !lp->diving )
    5936 {
    5937 /* issue row side changed event */
    5938 SCIP_CALL( rowEventSideChanged(row, blkmem, set, eventqueue, SCIP_SIDETYPE_RIGHT, oldrhs, rhs) );
    5939 }
    5940 }
    5941
    5942 return SCIP_OKAY;
    5943}
    5944
    5945/** changes the local flag of LP row */
    5947 SCIP_ROW* row, /**< LP row */
    5948 SCIP_Bool local /**< new value for local flag */
    5949 )
    5950{
    5951 assert(row != NULL);
    5952
    5953 row->local = local;
    5954
    5955 return SCIP_OKAY;
    5956}
    5957
    5958/** additional scalars that are tried in integrality scaling */
    5959static const SCIP_Real scalars[] = {3.0, 5.0, 7.0, 9.0, 11.0, 13.0, 15.0, 17.0, 19.0};
    5960static const int nscalars = 9;
    5961
    5962/** tries to find a value, such that all row coefficients, if scaled with this value become integral */
    5964 SCIP_ROW* row, /**< LP row */
    5965 SCIP_SET* set, /**< global SCIP settings */
    5966 SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
    5967 SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
    5968 SCIP_Longint maxdnom, /**< maximal denominator allowed in rational numbers */
    5969 SCIP_Real maxscale, /**< maximal allowed scalar */
    5970 SCIP_Bool usecontvars, /**< should the coefficients of the continuous variables also be made integral? */
    5971 SCIP_Real* intscalar, /**< pointer to store scalar that would make the coefficients integral, or NULL */
    5972 SCIP_Bool* success /**< stores whether returned value is valid */
    5973 )
    5974{
    5975#ifndef NDEBUG
    5976 SCIP_COL* col;
    5977#endif
    5978 SCIP_Longint gcd;
    5979 SCIP_Longint scm;
    5982 SCIP_Real val;
    5983 SCIP_Real absval;
    5984 SCIP_Real minval;
    5985 SCIP_Real scaleval;
    5986 SCIP_Real twomultval;
    5987 SCIP_Bool scalable;
    5988 SCIP_Bool twomult;
    5989 SCIP_Bool rational;
    5990 int c;
    5991 int s;
    5992
    5993 /**@todo call misc.c:SCIPcalcIntegralScalar() instead - if usecontvars == FALSE, filter the integer variables first */
    5994 assert(row != NULL);
    5995 assert(row->len == 0 || row->cols != NULL);
    5996 assert(row->len == 0 || row->cols_index != NULL);
    5997 assert(row->len == 0 || row->vals != NULL);
    5998 assert(maxdnom >= 1);
    5999 assert(mindelta < 0.0);
    6000 assert(maxdelta > 0.0);
    6001 assert(success != NULL);
    6002
    6003 SCIPsetDebugMsg(set, "trying to find rational representation for row <%s> (contvars: %u)\n", SCIProwGetName(row), usecontvars);
    6004 SCIPdebug( val = 0; ); /* avoid warning "val might be used uninitialized; see SCIPdebugMessage lastval=%g below */
    6005
    6006 if( intscalar != NULL )
    6007 *intscalar = SCIP_INVALID;
    6008 *success = FALSE;
    6009
    6010 /* get minimal absolute non-zero value */
    6011 minval = SCIP_REAL_MAX;
    6012 for( c = 0; c < row->len; ++c )
    6013 {
    6014#ifndef NDEBUG
    6015 col = row->cols[c];
    6016 assert(col != NULL);
    6017 assert(col->var != NULL);
    6019 assert(SCIPvarGetCol(col->var) == col);
    6020#endif
    6021 val = row->vals[c];
    6022 assert(!SCIPsetIsZero(set, val));
    6023
    6024 if( val < mindelta || val > maxdelta )
    6025 {
    6026 absval = REALABS(val);
    6027 minval = MIN(minval, absval);
    6028 }
    6029 }
    6030 if( minval == SCIP_REAL_MAX ) /*lint !e777*/
    6031 {
    6032 /* all coefficients are zero (inside tolerances) */
    6033 if( intscalar != NULL )
    6034 *intscalar = 1.0;
    6035 *success = TRUE;
    6036 SCIPsetDebugMsg(set, " -> all values are zero (inside tolerances)\n");
    6037
    6038 return SCIP_OKAY;
    6039 }
    6040 assert(minval > MIN(-mindelta, maxdelta));
    6041 assert(SCIPsetIsPositive(set, minval));
    6042 assert(!SCIPsetIsInfinity(set, minval));
    6043
    6044 /* try, if row coefficients can be made integral by multiplying them with the reciprocal of the smallest coefficient
    6045 * and a power of 2
    6046 */
    6047 scaleval = 1.0/minval;
    6048 scalable = (scaleval <= maxscale);
    6049 for( c = 0; c < row->len && scalable; ++c )
    6050 {
    6051 /* don't look at continuous variables, if we don't have to */
    6052 if( !usecontvars && !SCIPcolIsIntegral(row->cols[c]) )
    6053 continue;
    6054
    6055 /* check, if the coefficient can be scaled with a simple scalar */
    6056 val = row->vals[c];
    6057 absval = REALABS(val);
    6058 while( scaleval <= maxscale
    6059 && (absval * scaleval < 0.5 || !isIntegralScalar(val, scaleval, mindelta, maxdelta, NULL)) )
    6060 {
    6061 for( s = 0; s < nscalars; ++s )
    6062 {
    6063 if( isIntegralScalar(val, scaleval * scalars[s], mindelta, maxdelta, NULL) )
    6064 {
    6065 scaleval *= scalars[s];
    6066 break;
    6067 }
    6068 }
    6069 if( s >= nscalars )
    6070 scaleval *= 2.0;
    6071 }
    6072 scalable = (scaleval <= maxscale);
    6073 SCIPsetDebugMsg(set, " -> val=%g, scaleval=%g, val*scaleval=%g, scalable=%u\n", val, scaleval, val*scaleval, scalable);
    6074 }
    6075 if( scalable )
    6076 {
    6077 /* make row coefficients integral by dividing them by the smallest coefficient
    6078 * (and multiplying them with a power of 2)
    6079 */
    6080 assert(scaleval <= maxscale);
    6081 if( intscalar != NULL )
    6082 *intscalar = scaleval;
    6083 *success = TRUE;
    6084 SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (minval=%g)\n", scaleval, minval);
    6085
    6086 return SCIP_OKAY;
    6087 }
    6088
    6089 /* try, if row coefficients can be made integral by multiplying them by a power of 2 */
    6090 twomultval = 1.0;
    6091 twomult = (twomultval <= maxscale);
    6092 for( c = 0; c < row->len && twomult; ++c )
    6093 {
    6094 /* don't look at continuous variables, if we don't have to */
    6095 if( !usecontvars && !SCIPcolIsIntegral(row->cols[c]) )
    6096 continue;
    6097
    6098 /* check, if the coefficient can be scaled with a simple scalar */
    6099 val = row->vals[c];
    6100 absval = REALABS(val);
    6101 while( twomultval <= maxscale
    6102 && (absval * twomultval < 0.5 || !isIntegralScalar(val, twomultval, mindelta, maxdelta, NULL)) )
    6103 {
    6104 for( s = 0; s < nscalars; ++s )
    6105 {
    6106 if( isIntegralScalar(val, twomultval * scalars[s], mindelta, maxdelta, NULL) )
    6107 {
    6108 twomultval *= scalars[s];
    6109 break;
    6110 }
    6111 }
    6112 if( s >= nscalars )
    6113 twomultval *= 2.0;
    6114 }
    6115 twomult = (twomultval <= maxscale);
    6116 SCIPsetDebugMsg(set, " -> val=%g, twomult=%g, val*twomult=%g, twomultable=%u\n",
    6117 val, twomultval, val*twomultval, twomult);
    6118 }
    6119 if( twomult )
    6120 {
    6121 /* make row coefficients integral by multiplying them with a power of 2 */
    6122 assert(twomultval <= maxscale);
    6123 if( intscalar != NULL )
    6124 *intscalar = twomultval;
    6125 *success = TRUE;
    6126 SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (power of 2)\n", twomultval);
    6127
    6128 return SCIP_OKAY;
    6129 }
    6130
    6131 /* convert each coefficient into a rational number, calculate the greatest common divisor of the numerators
    6132 * and the smallest common multiple of the denominators
    6133 */
    6134 gcd = 1;
    6135 scm = 1;
    6136 rational = (maxdnom > 1);
    6137
    6138 /* first coefficient (to initialize gcd) */
    6139 for( c = 0; c < row->len && rational; ++c )
    6140 {
    6141 if( usecontvars || SCIPcolIsIntegral(row->cols[c]) )
    6142 {
    6143 val = row->vals[c];
    6144 rational = SCIPrealToRational(val, mindelta, maxdelta, maxdnom, &numerator, &denominator);
    6145 if( rational && numerator != 0 )
    6146 {
    6147 assert(denominator > 0);
    6148 gcd = ABS(numerator);
    6149 scm = denominator;
    6150 rational = ((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
    6151 SCIPsetDebugMsg(set, " -> first rational: val: %g == %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ", gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", rational=%u\n",
    6152 val, numerator, denominator, gcd, scm, rational);
    6153 break;
    6154 }
    6155 }
    6156 }
    6157
    6158 /* remaining coefficients */
    6159 for( ++c; c < row->len && rational; ++c )
    6160 {
    6161 if( usecontvars || SCIPcolIsIntegral(row->cols[c]) )
    6162 {
    6163 val = row->vals[c];
    6164 rational = SCIPrealToRational(val, mindelta, maxdelta, maxdnom, &numerator, &denominator);
    6165 if( rational && numerator != 0 )
    6166 {
    6167 assert(denominator > 0);
    6168 gcd = SCIPcalcGreComDiv(gcd, ABS(numerator));
    6170 rational = ((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
    6171 SCIPsetDebugMsg(set, " -> next rational : val: %g == %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ", gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", rational=%u\n",
    6172 val, numerator, denominator, gcd, scm, rational);
    6173 }
    6174 }
    6175 }
    6176
    6177 if( rational )
    6178 {
    6179 /* make row coefficients integral by multiplying them with the smallest common multiple of the denominators */
    6180 assert((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
    6181 if( intscalar != NULL )
    6182 *intscalar = (SCIP_Real)scm/(SCIP_Real)gcd;
    6183 *success = TRUE;
    6184 SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (rational:%" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ")\n",
    6185 (SCIP_Real)scm/(SCIP_Real)gcd, scm, gcd);
    6186 }
    6187 else
    6188 {
    6189 assert(!(*success));
    6190 SCIPsetDebugMsg(set, " -> rationalizing failed: gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", lastval=%g\n", gcd, scm, val); /*lint !e771*/
    6191 }
    6192
    6193 return SCIP_OKAY;
    6194}
    6195
    6196/** tries to scale row, s.t. all coefficients become integral */
    6198 SCIP_ROW* row, /**< LP row */
    6199 BMS_BLKMEM* blkmem, /**< block memory */
    6200 SCIP_SET* set, /**< global SCIP settings */
    6201 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    6202 SCIP_STAT* stat, /**< problem statistics */
    6203 SCIP_LP* lp, /**< current LP data */
    6204 SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
    6205 SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
    6206 SCIP_Longint maxdnom, /**< maximal denominator allowed in rational numbers */
    6207 SCIP_Real maxscale, /**< maximal value to scale row with */
    6208 SCIP_Bool usecontvars, /**< should the coefficients of the continuous variables also be made integral? */
    6209 SCIP_Bool* success /**< stores whether row could be made rational */
    6210 )
    6211{
    6212 SCIP_Real intscalar;
    6213
    6214 assert(success != NULL);
    6215
    6216 /* calculate scalar to make coefficients integral */
    6217 SCIP_CALL( SCIProwCalcIntegralScalar(row, set, mindelta, maxdelta, maxdnom, maxscale, usecontvars,
    6218 &intscalar, success) );
    6219
    6220 if( *success )
    6221 {
    6222 /* scale the row */
    6223 SCIP_CALL( rowScale(row, blkmem, set, eventqueue, stat, lp, intscalar, usecontvars, mindelta, maxdelta) );
    6224 }
    6225
    6226 return SCIP_OKAY;
    6227}
    6228
    6229/** sorts row entries such that LP columns precede non-LP columns and inside both parts lower column indices precede
    6230 * higher ones
    6231 */
    6233 SCIP_ROW* row /**< row to be sorted */
    6234 )
    6235{
    6236 assert(row != NULL);
    6237
    6238 /* sort LP columns */
    6239 rowSortLP(row);
    6240
    6241 /* sort non-LP columns */
    6242 rowSortNonLP(row);
    6243
    6244#ifdef SCIP_MORE_DEBUG
    6245 /* check the sorting */
    6246 {
    6247 int c;
    6248 if( !row->delaysort )
    6249 {
    6250 for( c = 1; c < row->nlpcols; ++c )
    6251 assert(row->cols[c]->index >= row->cols[c-1]->index);
    6252 for( c = row->nlpcols + 1; c < row->len; ++c )
    6253 assert(row->cols[c]->index >= row->cols[c-1]->index);
    6254 }
    6255 }
    6256#endif
    6257}
    6258
    6259/** sorts row, and merges equal column entries (resulting from lazy sorting and adding) into a single entry; removes
    6260 * zero entries from row
    6261 * the row must not be linked to the columns; otherwise, we would need to update the columns as
    6262 * well, which is too expensive
    6263 */
    6264static
    6266 SCIP_ROW* row, /**< row to be sorted */
    6267 SCIP_SET* set /**< global SCIP settings */
    6268 )
    6269{
    6270 assert(row != NULL);
    6271 assert(!row->delaysort);
    6272 assert(row->nunlinked == row->len);
    6273 assert(row->nlpcols == 0);
    6274
    6275 SCIPsetDebugMsg(set, "merging row <%s>\n", row->name);
    6276
    6277 /* do nothing on empty rows; if row is sorted, nothing has to be done */
    6278 if( row->len > 0 && (!row->lpcolssorted || !row->nonlpcolssorted) )
    6279 {
    6280 SCIP_COL** cols;
    6281 int* cols_index;
    6282 SCIP_Real* vals;
    6283 int s;
    6284 int t;
    6285
    6286 /* make sure, the row is sorted */
    6287 SCIProwSort(row);
    6288 assert(row->lpcolssorted);
    6289 assert(row->nonlpcolssorted);
    6290
    6291 /* merge equal columns, thereby recalculating whether the row's activity is always integral */
    6292 cols = row->cols;
    6293 cols_index = row->cols_index;
    6294 vals = row->vals;
    6295 assert(cols != NULL);
    6296 assert(cols_index != NULL);
    6297 assert(vals != NULL);
    6298
    6299 t = 0;
    6300 row->integral = TRUE;
    6301 assert(!SCIPsetIsZero(set, vals[0]));
    6302 assert(row->linkpos[0] == -1);
    6303
    6304 for( s = 1; s < row->len; ++s )
    6305 {
    6306 assert(!SCIPsetIsZero(set, vals[s]));
    6307 assert(row->linkpos[s] == -1);
    6308
    6309 if( cols[s] == cols[t] )
    6310 {
    6311 /* merge entries with equal column */
    6312 vals[t] += vals[s];
    6313 }
    6314 else
    6315 {
    6316 /* go to the next entry, overwriting current entry if coefficient is zero */
    6317 if( !SCIPsetIsZero(set, vals[t]) )
    6318 {
    6319 /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
    6320 if( !set->exact_enable )
    6321 vals[t] = SCIPsetIsIntegral(set, vals[t]) ? SCIPsetRound(set, vals[t]) : vals[t];
    6322
    6323 row->integral = row->integral && SCIPcolIsIntegral(cols[t]) && SCIPsetIsIntegral(set, vals[t]);
    6324 if( set->exact_enable )
    6325 row->integral = row->integral && SCIPcolIsIntegral(cols[t]) && SCIPrealIsExactlyIntegral(vals[t]);
    6326 t++;
    6327 }
    6328 cols[t] = cols[s];
    6329 cols_index[t] = cols_index[s];
    6330 vals[t] = vals[s];
    6331 }
    6332 }
    6333 if( !SCIPsetIsZero(set, vals[t]) )
    6334 {
    6335 row->integral = row->integral && SCIPcolIsIntegral(cols[t]) && SCIPsetIsIntegral(set, vals[t]);
    6336 if( set->exact_enable )
    6337 row->integral = row->integral && SCIPcolIsIntegral(cols[t]) && SCIPrealIsExactlyIntegral(vals[t]);
    6338 t++;
    6339 }
    6340 assert(s == row->len);
    6341 assert(t <= row->len);
    6342
    6343 row->len = t;
    6344 row->nunlinked = t;
    6345
    6346 /* if equal entries were merged, we have to recalculate the norms, since the squared Euclidean norm is wrong */
    6347 if( t < s )
    6348 rowCalcNorms(row, set);
    6349 }
    6350
    6351#ifndef NDEBUG
    6352 /* check for double entries */
    6353 {
    6354 int i;
    6355 int j;
    6356
    6357 for( i = 0; i < row->len; ++i )
    6358 {
    6359 assert(row->cols[i] != NULL);
    6360 assert(row->cols[i]->index == row->cols_index[i]);
    6361 for( j = i+1; j < row->len; ++j )
    6362 assert(row->cols[i] != row->cols[j]);
    6363 }
    6364 }
    6365#endif
    6366}
    6367
    6368/** enables delaying of row sorting */
    6370 SCIP_ROW* row /**< LP row */
    6371 )
    6372{
    6373 assert(row != NULL);
    6374 assert(!row->delaysort);
    6375
    6376 row->delaysort = TRUE;
    6377}
    6378
    6379/** disables delaying of row sorting, sorts row and merges coefficients with equal columns */
    6381 SCIP_ROW* row, /**< LP row */
    6382 SCIP_SET* set /**< global SCIP settings */
    6383 )
    6384{
    6385 assert(row != NULL);
    6386 assert(row->delaysort);
    6387
    6388 row->delaysort = FALSE;
    6389 rowMerge(row, set);
    6390}
    6391
    6392/** recalculates norms of a row */
    6394 SCIP_ROW* row, /**< LP row */
    6395 SCIP_SET* set /**< global SCIP settings */
    6396 )
    6397{
    6398 rowCalcNorms(row, set);
    6399}
    6400
    6401/** recalculates the current activity of a row */
    6403 SCIP_ROW* row, /**< LP row */
    6404 SCIP_STAT* stat /**< problem statistics */
    6405 )
    6406{
    6407 SCIP_COL* col;
    6408 int c;
    6409
    6410 assert(row != NULL);
    6411 assert(stat != NULL);
    6412
    6413 row->activity = row->constant;
    6414 for( c = 0; c < row->nlpcols; ++c )
    6415 {
    6416 col = row->cols[c];
    6417 assert(col != NULL);
    6418 assert(col->primsol != SCIP_INVALID); /*lint !e777*/
    6419 assert(col->lppos >= 0);
    6420 assert(row->linkpos[c] >= 0);
    6421 row->activity += row->vals[c] * col->primsol;
    6422 }
    6423
    6424 if( row->nunlinked > 0 )
    6425 {
    6426 for( c = row->nlpcols; c < row->len; ++c )
    6427 {
    6428 col = row->cols[c];
    6429 assert(col != NULL);
    6430 assert(col->lppos >= 0 || col->primsol == 0.0);
    6431 assert(col->lppos == -1 || row->linkpos[c] == -1);
    6432 if( col->lppos >= 0 )
    6433 row->activity += row->vals[c] * col->primsol;
    6434 }
    6435 }
    6436#ifndef NDEBUG
    6437 else
    6438 {
    6439 for( c = row->nlpcols; c < row->len; ++c )
    6440 {
    6441 col = row->cols[c];
    6442 assert(col != NULL);
    6443 assert(col->primsol == 0.0);
    6444 assert(col->lppos == -1);
    6445 assert(row->linkpos[c] >= 0);
    6446 }
    6447 }
    6448#endif
    6449
    6450 row->validactivitylp = stat->lpcount;
    6451}
    6452
    6453/** returns the activity of a row in the current LP solution */
    6455 SCIP_ROW* row, /**< LP row */
    6456 SCIP_SET* set, /**< global SCIP settings */
    6457 SCIP_STAT* stat, /**< problem statistics */
    6458 SCIP_LP* lp /**< current LP data */
    6459 )
    6460{
    6461 SCIP_Real inf;
    6462 SCIP_Real activity;
    6463
    6464 assert(row != NULL);
    6465 assert(stat != NULL);
    6466 assert(lp != NULL);
    6467 assert(row->validactivitylp <= stat->lpcount);
    6468 assert(lp->validsollp == stat->lpcount);
    6469
    6470 if( row->validactivitylp != stat->lpcount )
    6471 SCIProwRecalcLPActivity(row, stat);
    6472 assert(row->validactivitylp == stat->lpcount);
    6473 assert(row->activity != SCIP_INVALID); /*lint !e777*/
    6474
    6475 activity = row->activity;
    6476 inf = SCIPsetInfinity(set);
    6477 activity = MAX(activity, -inf);
    6478 activity = MIN(activity, +inf);
    6479
    6480 return activity;
    6481}
    6482
    6483/** returns the feasibility of a row in the current LP solution: negative value means infeasibility */
    6485 SCIP_ROW* row, /**< LP row */
    6486 SCIP_SET* set, /**< global SCIP settings */
    6487 SCIP_STAT* stat, /**< problem statistics */
    6488 SCIP_LP* lp /**< current LP data */
    6489 )
    6490{
    6491 SCIP_Real activity;
    6492
    6493 assert(row != NULL);
    6494
    6495 activity = SCIProwGetLPActivity(row, set, stat, lp);
    6496
    6497 return MIN(row->rhs - activity, activity - row->lhs);
    6498}
    6499
    6500/** returns the feasibility of a row in the relaxed solution solution: negative value means infeasibility
    6501 *
    6502 * @todo Implement calculation of activities similar to LPs.
    6503 */
    6505 SCIP_ROW* row, /**< LP row */
    6506 SCIP_SET* set, /**< global SCIP settings */
    6507 SCIP_STAT* stat /**< problem statistics */
    6508 )
    6509{
    6510 SCIP_Real inf;
    6511 SCIP_Real activity;
    6512 SCIP_COL* col;
    6513 int c;
    6514
    6515 assert( row != NULL );
    6516 assert( stat != NULL );
    6517
    6518 activity = row->constant;
    6519 for (c = 0; c < row->nlpcols; ++c)
    6520 {
    6521 col = row->cols[c];
    6522 assert( col != NULL );
    6523 assert( col->lppos >= 0 );
    6524 assert( col->var != NULL );
    6525 assert( row->linkpos[c] >= 0 );
    6526 activity += row->vals[c] * SCIPvarGetRelaxSol(col->var, set);
    6527 }
    6528
    6529 if ( row->nunlinked > 0 )
    6530 {
    6531 for (c = row->nlpcols; c < row->len; ++c)
    6532 {
    6533 col = row->cols[c];
    6534 assert( col != NULL );
    6535 assert( col->lppos == -1 || row->linkpos[c] == -1 );
    6536 if ( col->lppos >= 0 )
    6537 {
    6538 assert( col->var != NULL );
    6539 activity += row->vals[c] * SCIPvarGetRelaxSol(col->var, set);
    6540 }
    6541 }
    6542 }
    6543#ifndef NDEBUG
    6544 else
    6545 {
    6546 for (c = row->nlpcols; c < row->len; ++c)
    6547 {
    6548 col = row->cols[c];
    6549 assert( col != NULL );
    6550 assert( col->lppos == -1 );
    6551 assert( row->linkpos[c] >= 0 );
    6552 }
    6553 }
    6554#endif
    6555 inf = SCIPsetInfinity(set);
    6556 activity = MAX(activity, -inf);
    6557 activity = MIN(activity, +inf);
    6558
    6559 return MIN(row->rhs - activity, activity - row->lhs);
    6560}
    6561
    6562/** returns the feasibility of a row in the current NLP solution: negative value means infeasibility
    6563 *
    6564 * @todo Implement calculation of activities similar to LPs.
    6565 */
    6567 SCIP_ROW* row, /**< LP row */
    6568 SCIP_SET* set, /**< global SCIP settings */
    6569 SCIP_STAT* stat /**< problem statistics */
    6570 )
    6571{
    6572 SCIP_Real inf;
    6573 SCIP_Real activity;
    6574 SCIP_COL* col;
    6575 int c;
    6576
    6577 assert( row != NULL );
    6578 assert( stat != NULL );
    6579
    6580 activity = row->constant;
    6581 for (c = 0; c < row->nlpcols; ++c)
    6582 {
    6583 col = row->cols[c];
    6584 assert( col != NULL );
    6585 assert( col->lppos >= 0 );
    6586 assert( col->var != NULL );
    6587 assert( row->linkpos[c] >= 0 );
    6588 activity += row->vals[c] * SCIPvarGetNLPSol(col->var);
    6589 }
    6590
    6591 if ( row->nunlinked > 0 )
    6592 {
    6593 for (c = row->nlpcols; c < row->len; ++c)
    6594 {
    6595 col = row->cols[c];
    6596 assert( col != NULL );
    6597 assert( col->lppos == -1 || row->linkpos[c] == -1 );
    6598 if ( col->lppos >= 0 )
    6599 {
    6600 assert( col->var != NULL );
    6601 activity += row->vals[c] * SCIPvarGetNLPSol(col->var);
    6602 }
    6603 }
    6604 }
    6605#ifndef NDEBUG
    6606 else
    6607 {
    6608 for (c = row->nlpcols; c < row->len; ++c)
    6609 {
    6610 col = row->cols[c];
    6611 assert( col != NULL );
    6612 assert( col->lppos == -1 );
    6613 assert( row->linkpos[c] >= 0 );
    6614 }
    6615 }
    6616#endif
    6617 inf = SCIPsetInfinity(set);
    6618 activity = MAX(activity, -inf);
    6619 activity = MIN(activity, +inf);
    6620
    6621 return MIN(row->rhs - activity, activity - row->lhs);
    6622}
    6623
    6624/** calculates the current pseudo activity of a row */
    6626 SCIP_ROW* row, /**< row data */
    6627 SCIP_STAT* stat /**< problem statistics */
    6628 )
    6629{
    6630 SCIP_COL* col;
    6631 int i;
    6632
    6633 assert(row != NULL);
    6634 assert(stat != NULL);
    6635
    6636 row->pseudoactivity = row->constant;
    6637 for( i = 0; i < row->len; ++i )
    6638 {
    6639 col = row->cols[i];
    6640 assert(col != NULL);
    6641 assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
    6642 assert(col->var != NULL);
    6644
    6645 row->pseudoactivity += SCIPcolGetBestBound(col) * row->vals[i];
    6646 }
    6648 assert(!row->integral || EPSISINT(row->pseudoactivity - row->constant, SCIP_DEFAULT_SUMEPSILON));
    6649}
    6650
    6651/** returns the pseudo activity of a row in the current pseudo solution */
    6653 SCIP_ROW* row, /**< LP row */
    6654 SCIP_SET* set, /**< global SCIP settings */
    6655 SCIP_STAT* stat /**< problem statistics */
    6656 )
    6657{
    6658 SCIP_Real inf;
    6659 SCIP_Real activity;
    6660
    6661 assert(row != NULL);
    6662 assert(stat != NULL);
    6663 assert(row->validpsactivitydomchg <= stat->domchgcount);
    6664
    6665 /* check, if pseudo activity has to be calculated */
    6666 if( row->validpsactivitydomchg != stat->domchgcount )
    6667 SCIProwRecalcPseudoActivity(row, stat);
    6668 assert(row->validpsactivitydomchg == stat->domchgcount);
    6669 assert(row->pseudoactivity != SCIP_INVALID); /*lint !e777*/
    6670
    6671 activity = row->pseudoactivity;
    6672 inf = SCIPsetInfinity(set);
    6673 activity = MAX(activity, -inf);
    6674 activity = MIN(activity, +inf);
    6675
    6676 return activity;
    6677}
    6678
    6679/** returns the pseudo feasibility of a row in the current pseudo solution: negative value means infeasibility */
    6681 SCIP_ROW* row, /**< LP row */
    6682 SCIP_SET* set, /**< global SCIP settings */
    6683 SCIP_STAT* stat /**< problem statistics */
    6684 )
    6685{
    6686 SCIP_Real pseudoactivity;
    6687
    6688 assert(row != NULL);
    6689
    6690 pseudoactivity = SCIProwGetPseudoActivity(row, set, stat);
    6691
    6692 return MIN(row->rhs - pseudoactivity, pseudoactivity - row->lhs);
    6693}
    6694
    6695/** returns the activity of a row for a given solution */
    6697 SCIP_ROW* row, /**< LP row */
    6698 SCIP_SET* set, /**< global SCIP settings */
    6699 SCIP_STAT* stat, /**< problem statistics data */
    6700 SCIP_SOL* sol /**< primal CIP solution */
    6701 )
    6702{
    6703 SCIP_COL* col;
    6704 SCIP_Real inf;
    6705 SCIP_Real activity;
    6706 SCIP_Real solval;
    6707 int i;
    6708
    6709 assert(row != NULL);
    6710
    6711 activity = row->constant;
    6712 for( i = 0; i < row->len; ++i )
    6713 {
    6714 col = row->cols[i];
    6715 assert(col != NULL);
    6716 assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
    6717 solval = SCIPsolGetVal(sol, set, stat, col->var);
    6718 if( solval == SCIP_UNKNOWN ) /*lint !e777*/
    6719 {
    6720 if( SCIPsetIsInfinity(set, -row->lhs) )
    6721 solval = (row->vals[i] >= 0.0 ? col->lb : col->ub);
    6722 else if( SCIPsetIsInfinity(set, row->rhs) )
    6723 solval = (row->vals[i] >= 0.0 ? col->ub : col->lb);
    6724 else
    6725 solval = (col->lb + col->ub)/2.0;
    6726 }
    6727 activity += row->vals[i] * solval;
    6728 }
    6729
    6730 inf = SCIPsetInfinity(set);
    6731 activity = MAX(activity, -inf);
    6732 activity = MIN(activity, +inf);
    6733
    6734 return activity;
    6735}
    6736
    6737/** returns the feasibility of a row for the given solution */
    6739 SCIP_ROW* row, /**< LP row */
    6740 SCIP_SET* set, /**< global SCIP settings */
    6741 SCIP_STAT* stat, /**< problem statistics data */
    6742 SCIP_SOL* sol /**< primal CIP solution */
    6743 )
    6744{
    6745 SCIP_Real activity;
    6746
    6747 assert(row != NULL);
    6748
    6749 activity = SCIProwGetSolActivity(row, set, stat, sol);
    6750
    6751 return MIN(row->rhs - activity, activity - row->lhs);
    6752}
    6753
    6754/** calculates minimal and maximal activity of row w.r.t. the column's bounds */
    6755static
    6757 SCIP_ROW* row, /**< row data */
    6758 SCIP_SET* set, /**< global SCIP settings */
    6759 SCIP_STAT* stat /**< problem statistics data */
    6760 )
    6761{
    6762 SCIP_COL* col;
    6763 SCIP_Real val;
    6764 SCIP_Bool mininfinite;
    6765 SCIP_Bool maxinfinite;
    6766 int i;
    6767
    6768 assert(row != NULL);
    6769 assert(!SCIPsetIsInfinity(set, REALABS(row->constant)));
    6770 assert(stat != NULL);
    6771
    6772 /* calculate activity bounds */
    6773 mininfinite = FALSE;
    6774 maxinfinite = FALSE;
    6775 row->minactivity = row->constant;
    6776 row->maxactivity = row->constant;
    6777 for( i = 0; i < row->len && (!mininfinite || !maxinfinite); ++i )
    6778 {
    6779 col = row->cols[i];
    6780 assert(col != NULL);
    6781 assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
    6782 val = row->vals[i];
    6783 if( val >= 0.0 )
    6784 {
    6785 mininfinite = mininfinite || SCIPsetIsInfinity(set, -col->lb);
    6786 maxinfinite = maxinfinite || SCIPsetIsInfinity(set, col->ub);
    6787 if( !mininfinite )
    6788 row->minactivity += val * col->lb;
    6789 if( !maxinfinite )
    6790 row->maxactivity += val * col->ub;
    6791 }
    6792 else
    6793 {
    6794 mininfinite = mininfinite || SCIPsetIsInfinity(set, col->ub);
    6795 maxinfinite = maxinfinite || SCIPsetIsInfinity(set, -col->lb);
    6796 if( !mininfinite )
    6797 row->minactivity += val * col->ub;
    6798 if( !maxinfinite )
    6799 row->maxactivity += val * col->lb;
    6800 }
    6801 }
    6802
    6803 if( mininfinite )
    6805 if( maxinfinite )
    6808
    6809#ifndef NDEBUG
    6810 {
    6811 SCIP_Real inttol = 1000.0*SCIPsetFeastol(set);
    6812
    6813 /* even if the row is integral, the bounds on the variables used for computing minimum and maximum activity might
    6814 * be integral only within feasibility tolerance; this can happen, e.g., if a continuous variable is promoted to
    6815 * an (implicit) integer variable and the bounds cannot be adjusted because they are minimally tighter than the
    6816 * rounded bound value; hence, the activity may violate integrality; we allow 1000 times the default feasibility
    6817 * tolerance as a proxy to account for the accumulation effect
    6818 */
    6819 assert(!row->integral || mininfinite || REALABS(row->minactivity - row->constant) > 1.0/SCIPsetSumepsilon(set)
    6820 || EPSISINT(row->minactivity - row->constant, inttol));
    6821 assert(!row->integral || maxinfinite || REALABS(row->maxactivity - row->constant) > 1.0/SCIPsetSumepsilon(set)
    6822 || EPSISINT(row->maxactivity - row->constant, inttol));
    6823 }
    6824#endif
    6825}
    6826
    6827/** returns the minimal activity of a row w.r.t. the columns' bounds */
    6829 SCIP_ROW* row, /**< LP row */
    6830 SCIP_SET* set, /**< global SCIP settings */
    6831 SCIP_STAT* stat /**< problem statistics data */
    6832 )
    6833{
    6834 assert(row != NULL);
    6835 assert(stat != NULL);
    6836 assert(row->validactivitybdsdomchg <= stat->domchgcount);
    6837
    6838 /* check, if activity bounds has to be calculated */
    6839 if( row->validactivitybdsdomchg != stat->domchgcount )
    6840 rowCalcActivityBounds(row, set, stat);
    6841 assert(row->validactivitybdsdomchg == stat->domchgcount);
    6842 assert(row->minactivity != SCIP_INVALID); /*lint !e777*/
    6843 assert(row->maxactivity != SCIP_INVALID); /*lint !e777*/
    6844
    6845 return row->minactivity;
    6846}
    6847
    6848/** returns the maximal activity of a row w.r.t. the columns' bounds */
    6850 SCIP_ROW* row, /**< LP row */
    6851 SCIP_SET* set, /**< global SCIP settings */
    6852 SCIP_STAT* stat /**< problem statistics data */
    6853 )
    6854{
    6855 assert(row != NULL);
    6856 assert(stat != NULL);
    6857 assert(row->validactivitybdsdomchg <= stat->domchgcount);
    6858
    6859 /* check, if activity bounds has to be calculated */
    6860 if( row->validactivitybdsdomchg != stat->domchgcount )
    6861 rowCalcActivityBounds(row, set, stat);
    6862 assert(row->validactivitybdsdomchg == stat->domchgcount);
    6863 assert(row->minactivity != SCIP_INVALID); /*lint !e777*/
    6864 assert(row->maxactivity != SCIP_INVALID); /*lint !e777*/
    6865
    6866 return row->maxactivity;
    6867}
    6868
    6869/** returns whether the row is unmodifiable and redundant w.r.t. the columns' bounds */
    6871 SCIP_ROW* row, /**< LP row */
    6872 SCIP_SET* set, /**< global SCIP settings */
    6873 SCIP_STAT* stat /**< problem statistics data */
    6874 )
    6875{
    6876 assert(row != NULL);
    6877
    6878 if( row->modifiable )
    6879 return FALSE;
    6880 if( !SCIPsetIsInfinity(set, -row->lhs) )
    6881 {
    6882 SCIP_Real minactivity;
    6883
    6884 minactivity = SCIProwGetMinActivity(row, set, stat);
    6885 if( SCIPsetIsFeasLT(set, minactivity, row->lhs) )
    6886 return FALSE;
    6887 }
    6888 if( !SCIPsetIsInfinity(set, row->rhs) )
    6889 {
    6890 SCIP_Real maxactivity;
    6891
    6892 maxactivity = SCIProwGetMaxActivity(row, set, stat);
    6893 if( SCIPsetIsFeasGT(set, maxactivity, row->rhs) )
    6894 return FALSE;
    6895 }
    6896
    6897 return TRUE;
    6898}
    6899
    6900/** gets maximal absolute value of row vector coefficients */
    6902 SCIP_ROW* row, /**< LP row */
    6903 SCIP_SET* set /**< global SCIP settings */
    6904 )
    6905{
    6906 assert(row != NULL);
    6907
    6908 if( row->nummaxval == 0 )
    6909 rowCalcIdxsAndVals(row, set);
    6910 assert(row->nummaxval > 0);
    6911 assert(row->maxval >= 0.0 || row->len == 0);
    6912
    6913 return row->maxval;
    6914}
    6915
    6916/** gets minimal absolute value of row vector's non-zero coefficients */
    6918 SCIP_ROW* row, /**< LP row */
    6919 SCIP_SET* set /**< global SCIP settings */
    6920 )
    6921{
    6922 assert(row != NULL);
    6923
    6924 if( row->numminval == 0 )
    6925 rowCalcIdxsAndVals(row, set);
    6926 assert(row->numminval > 0);
    6927 assert(row->minval >= 0.0 || row->len == 0);
    6928
    6929 return row->minval;
    6930}
    6931
    6932/** gets maximal column index of row entries */
    6934 SCIP_ROW* row, /**< LP row */
    6935 SCIP_SET* set /**< global SCIP settings */
    6936 )
    6937{
    6938 assert(row != NULL);
    6939
    6940 if( row->validminmaxidx == 0 )
    6941 rowCalcIdxsAndVals(row, set);
    6942 assert(row->maxidx >= 0 || row->len == 0);
    6943 assert(row->validminmaxidx);
    6944
    6945 return row->maxidx;
    6946}
    6947
    6948/** gets minimal column index of row entries */
    6950 SCIP_ROW* row, /**< LP row */
    6951 SCIP_SET* set /**< global SCIP settings */
    6952 )
    6953{
    6954 assert(row != NULL);
    6955
    6956 if( row->validminmaxidx == 0 )
    6957 rowCalcIdxsAndVals(row, set);
    6958 assert(row->minidx >= 0 || row->len == 0);
    6959 assert(row->validminmaxidx);
    6960
    6961 return row->minidx;
    6962}
    6963
    6964/** gets number of integral columns in row */
    6966 SCIP_ROW* row, /**< LP row */
    6967 SCIP_SET* set /**< global SCIP settings */
    6968 )
    6969{
    6970 assert(row != NULL);
    6971
    6972 if( row->numintcols == -1 )
    6973 rowCalcIdxsAndVals(row, set);
    6974
    6975 assert(row->numintcols <= row->len && row->numintcols >= 0);
    6976
    6977 return row->numintcols;
    6978}
    6979
    6980/** gets number of implied integral columns in row */
    6982 SCIP_ROW* row, /**< LP row */
    6983 SCIP_SET* set /**< global SCIP settings */
    6984 )
    6985{
    6986 assert(row != NULL);
    6987
    6988 if( row->numimplintcols == -1 )
    6989 rowCalcIdxsAndVals(row, set);
    6990
    6991 assert(row->numimplintcols <= row->len && row->numimplintcols >= 0);
    6992
    6993 return row->numimplintcols;
    6994}
    6995
    6996/** returns row's cutoff distance in the direction of the given primal solution */
    6998 SCIP_ROW* row, /**< LP row */
    6999 SCIP_SET* set, /**< global SCIP settings */
    7000 SCIP_STAT* stat, /**< problem statistics data */
    7001 SCIP_SOL* sol, /**< solution to compute direction for cutoff distance; must not be NULL */
    7002 SCIP_LP* lp /**< current LP data */
    7003 )
    7004{
    7005 SCIP_Real solcutoffdist;
    7006 int k;
    7007
    7008 assert(sol != NULL);
    7009
    7010 if( lp->validsoldirlp != stat->lpcount || lp->validsoldirsol != sol )
    7011 {
    7012 SCIP_Real scale = 0.0;
    7013
    7014 lp->validsoldirlp = stat->lpcount;
    7015 lp->validsoldirsol = sol;
    7016
    7018
    7019 for( k = 0; k < lp->ncols; ++k )
    7020 {
    7021 assert(lp->cols[k]->lppos == k);
    7022 lp->soldirection[k] = SCIPsolGetVal(sol, set, stat, lp->cols[k]->var) - lp->cols[k]->primsol;
    7023 scale += SQR(lp->soldirection[k]);
    7024 }
    7025
    7026 if( scale > 0.0 )
    7027 {
    7028 scale = 1.0 / sqrt(scale);
    7029
    7030 for( k = 0; k < lp->ncols; ++k )
    7031 lp->soldirection[k] *= scale;
    7032 }
    7033 }
    7034
    7035 solcutoffdist = 0.0;
    7036 for( k = 0; k < row->nlpcols; ++k )
    7037 solcutoffdist += row->vals[k] * lp->soldirection[row->cols[k]->lppos];
    7038
    7039 for( k = row->nlpcols; k < row->len; ++k )
    7040 {
    7041 if( row->cols[k]->lppos >= 0 )
    7042 solcutoffdist += row->vals[k] * lp->soldirection[row->cols[k]->lppos];
    7043 }
    7044
    7045 if( SCIPsetIsSumZero(set, solcutoffdist) )
    7046 solcutoffdist = set->num_sumepsilon;
    7047
    7048 solcutoffdist = -SCIProwGetLPFeasibility(row, set, stat, lp) / ABS(solcutoffdist); /*lint !e795*/
    7049
    7050 return solcutoffdist;
    7051}
    7052
    7053/** returns row's efficacy with respect to the current LP solution: e = -feasibility/norm */
    7055 SCIP_ROW* row, /**< LP row */
    7056 SCIP_SET* set, /**< global SCIP settings */
    7057 SCIP_STAT* stat, /**< problem statistics data */
    7058 SCIP_LP* lp /**< current LP data */
    7059 )
    7060{
    7061 SCIP_Real norm;
    7062 SCIP_Real feasibility;
    7063 SCIP_Real eps;
    7064
    7065 assert(set != NULL);
    7066
    7067 switch( set->sepa_efficacynorm )
    7068 {
    7069 case 'e':
    7070 norm = SCIProwGetNorm(row);
    7071 break;
    7072 case 'm':
    7073 norm = SCIProwGetMaxval(row, set);
    7074 break;
    7075 case 's':
    7076 norm = SCIProwGetSumNorm(row);
    7077 break;
    7078 case 'd':
    7079 norm = (row->len == 0 ? 0.0 : 1.0);
    7080 break;
    7081 default:
    7082 SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
    7083 SCIPABORT();
    7084 norm = 0.0; /*lint !e527*/
    7085 }
    7086
    7088 norm = MAX(norm, eps);
    7089 feasibility = SCIProwGetLPFeasibility(row, set, stat, lp);
    7090
    7091 return -feasibility / norm;
    7092}
    7093
    7094/** returns whether the row's efficacy with respect to the current LP solution is greater than the minimal cut efficacy */
    7096 SCIP_ROW* row, /**< LP row */
    7097 SCIP_SET* set, /**< global SCIP settings */
    7098 SCIP_STAT* stat, /**< problem statistics data */
    7099 SCIP_LP* lp, /**< current LP data */
    7100 SCIP_Bool root /**< should the root's minimal cut efficacy be used? */
    7101 )
    7102{
    7103 SCIP_Real efficacy;
    7104
    7105 efficacy = SCIProwGetLPEfficacy(row, set, stat, lp);
    7106
    7107 return SCIPsetIsEfficacious(set, root, efficacy);
    7108}
    7109
    7110/** returns row's efficacy with respect to the given primal solution: e = -feasibility/norm */
    7112 SCIP_ROW* row, /**< LP row */
    7113 SCIP_SET* set, /**< global SCIP settings */
    7114 SCIP_STAT* stat, /**< problem statistics data */
    7115 SCIP_SOL* sol /**< primal CIP solution */
    7116 )
    7117{
    7118 SCIP_Real norm;
    7119 SCIP_Real feasibility;
    7120 SCIP_Real eps;
    7121
    7122 assert(set != NULL);
    7123
    7124 switch( set->sepa_efficacynorm )
    7125 {
    7126 case 'e':
    7127 norm = SCIProwGetNorm(row);
    7128 break;
    7129 case 'm':
    7130 norm = SCIProwGetMaxval(row, set);
    7131 break;
    7132 case 's':
    7133 norm = SCIProwGetSumNorm(row);
    7134 break;
    7135 case 'd':
    7136 norm = (row->len == 0 ? 0.0 : 1.0);
    7137 break;
    7138 default:
    7139 SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
    7140 SCIPABORT();
    7141 norm = 0.0; /*lint !e527*/
    7142 }
    7143
    7145 norm = MAX(norm, eps);
    7146 feasibility = SCIProwGetSolFeasibility(row, set, stat, sol);
    7147
    7148 return -feasibility / norm;
    7149}
    7150
    7151/** returns whether the row's efficacy with respect to the given primal solution is greater than the minimal cut
    7152 * efficacy
    7153 */
    7155 SCIP_ROW* row, /**< LP row */
    7156 SCIP_SET* set, /**< global SCIP settings */
    7157 SCIP_STAT* stat, /**< problem statistics data */
    7158 SCIP_SOL* sol, /**< primal CIP solution */
    7159 SCIP_Bool root /**< should the root's minimal cut efficacy be used? */
    7160 )
    7161{
    7162 SCIP_Real efficacy;
    7163
    7164 efficacy = SCIProwGetSolEfficacy(row, set, stat, sol);
    7165
    7166 return SCIPsetIsEfficacious(set, root, efficacy);
    7167}
    7168
    7169/** returns row's efficacy with respect to the relaxed solution: e = -feasibility/norm */
    7171 SCIP_ROW* row, /**< LP row */
    7172 SCIP_SET* set, /**< global SCIP settings */
    7173 SCIP_STAT* stat /**< problem statistics data */
    7174 )
    7175{
    7176 SCIP_Real norm;
    7177 SCIP_Real feasibility;
    7178 SCIP_Real eps;
    7179
    7180 assert(set != NULL);
    7181
    7182 switch( set->sepa_efficacynorm )
    7183 {
    7184 case 'e':
    7185 norm = SCIProwGetNorm(row);
    7186 break;
    7187 case 'm':
    7188 norm = SCIProwGetMaxval(row, set);
    7189 break;
    7190 case 's':
    7191 norm = SCIProwGetSumNorm(row);
    7192 break;
    7193 case 'd':
    7194 norm = (row->len == 0 ? 0.0 : 1.0);
    7195 break;
    7196 default:
    7197 SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
    7198 SCIPABORT();
    7199 norm = 0.0; /*lint !e527*/
    7200 }
    7201
    7203 norm = MAX(norm, eps);
    7204 feasibility = SCIProwGetRelaxFeasibility(row, set, stat);
    7205
    7206 return -feasibility / norm;
    7207}
    7208
    7209/** returns row's efficacy with respect to the NLP solution: e = -feasibility/norm */
    7211 SCIP_ROW* row, /**< LP row */
    7212 SCIP_SET* set, /**< global SCIP settings */
    7213 SCIP_STAT* stat /**< problem statistics data */
    7214 )
    7215{
    7216 SCIP_Real norm;
    7217 SCIP_Real feasibility;
    7218 SCIP_Real eps;
    7219
    7220 assert(set != NULL);
    7221
    7222 switch( set->sepa_efficacynorm )
    7223 {
    7224 case 'e':
    7225 norm = SCIProwGetNorm(row);
    7226 break;
    7227 case 'm':
    7228 norm = SCIProwGetMaxval(row, set);
    7229 break;
    7230 case 's':
    7231 norm = SCIProwGetSumNorm(row);
    7232 break;
    7233 case 'd':
    7234 norm = (row->len == 0 ? 0.0 : 1.0);
    7235 break;
    7236 default:
    7237 SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
    7238 SCIPABORT();
    7239 norm = 0.0; /*lint !e527*/
    7240 }
    7241
    7243 norm = MAX(norm, eps);
    7244 feasibility = SCIProwGetNLPFeasibility(row, set, stat);
    7245
    7246 return -feasibility / norm;
    7247}
    7248
    7249/** returns the scalar product of the coefficient vectors of the two given rows
    7250 *
    7251 * @note the scalar product is computed w.r.t. the current LP columns only
    7252 * @todo also consider non-LP columns for the computation?
    7253 */
    7255 SCIP_ROW* row1, /**< first LP row */
    7256 SCIP_ROW* row2 /**< second LP row */
    7257 )
    7258{
    7259 SCIP_Real scalarprod;
    7260 int* row1colsidx;
    7261 int* row2colsidx;
    7262 int i1;
    7263 int i2;
    7264
    7265 assert(row1 != NULL);
    7266 assert(row2 != NULL);
    7267
    7268 /* Sort the column indices of both rows.
    7269 *
    7270 * The columns in a row are divided into two parts: LP columns, which are currently in the LP and non-LP columns;
    7271 * we sort the rows, but that only ensures that within these two parts, columns are sorted w.r.t. their index.
    7272 * Normally, this should be suficient, because a column contained in both rows should either be one of the LP columns
    7273 * for both or one of the non-LP columns for both.
    7274 * However, directly after a row was created, before a row is added to the LP, the row is not linked to all its
    7275 * columns and all columns are treated as non-LP columns. Moreover, for example when doing column generation,
    7276 * columns can be added later and remain unlinked while all previously added columns might already be linked.
    7277 * Therefore, we have to be very careful about whether we can rely on the partitioning of the variables.
    7278 *
    7279 * We distinguish the following cases:
    7280 *
    7281 * 1) both rows have no unlinked columns
    7282 * -> we just check the LP partitions
    7283 *
    7284 * 2) exactly one row is completely unlinked, the other one is completely linked
    7285 * -> we compare the non-LP (unlinked) partition with the LP partition of the other row
    7286 * (thus all common LP columns are regarded)
    7287 *
    7288 * 3) we have unlinked and LP columns in both rows
    7289 * -> we need to compare four partitions at once
    7290 *
    7291 * 4a) we have one row with unlinked and LP columns and the other without any unlinked columns
    7292 * -> we need to compare three partitions: the LP part of the completely linked row and both partitions of the
    7293 * other row
    7294 *
    7295 * 4b) we have one row with unlinked and LP columns and the other is completely unlinked
    7296 * -> we need to compare three partitions: the complete unlinked row and both partitions of the other row
    7297 *
    7298 * 5) both rows are completely unlinked
    7299 * -> we need to compare two partitions: both complete rows
    7300 */
    7301 SCIProwSort(row1);
    7302 assert(row1->lpcolssorted);
    7303 assert(row1->nonlpcolssorted);
    7304 SCIProwSort(row2);
    7305 assert(row2->lpcolssorted);
    7306 assert(row2->nonlpcolssorted);
    7307
    7308 assert(row1->nunlinked <= row1->len - row1->nlpcols);
    7309 assert(row2->nunlinked <= row2->len - row2->nlpcols);
    7310
    7311 row1colsidx = row1->cols_index;
    7312 row2colsidx = row2->cols_index;
    7313
    7314#ifndef NDEBUG
    7315 /* check that we can rely on the partition into LP columns and non-LP columns if the rows are completely linked */
    7316 if( row1->nunlinked == 0 && row2->nunlinked == 0 )
    7317 {
    7318 i1 = 0;
    7319 i2 = row2->nlpcols;
    7320 while( i1 < row1->nlpcols && i2 < row2->len )
    7321 {
    7322 assert(row1->cols[i1] != row2->cols[i2]);
    7323 if( row1->cols[i1]->index < row2->cols[i2]->index )
    7324 ++i1;
    7325 else
    7326 {
    7327 assert(row1->cols[i1]->index > row2->cols[i2]->index);
    7328 ++i2;
    7329 }
    7330 }
    7331 assert(i1 == row1->nlpcols || i2 == row2->len);
    7332
    7333 i1 = row1->nlpcols;
    7334 i2 = 0;
    7335 while( i1 < row1->len && i2 < row2->nlpcols )
    7336 {
    7337 assert(row1->cols[i1] != row2->cols[i2]);
    7338 if( row1->cols[i1]->index < row2->cols[i2]->index )
    7339 ++i1;
    7340 else
    7341 {
    7342 assert(row1->cols[i1]->index > row2->cols[i2]->index);
    7343 ++i2;
    7344 }
    7345 }
    7346 assert(i1 == row1->len || i2 == row2->nlpcols);
    7347 }
    7348#endif
    7349
    7350 /* The "easy" cases 1) and 2) */
    7351 if( (row1->nunlinked == 0 && row2->nunlinked == 0) ||
    7352 ((row1->nlpcols == row1->len || row1->nunlinked == row1->len)
    7353 && (row2->nlpcols == row2->len || row2->nunlinked == row2->len)
    7354 && (row1->nunlinked == 0 || row2->nunlinked == 0)) )
    7355 {
    7356 assert(row1->nunlinked == 0 || row1->nunlinked == row1->len);
    7357 assert(row2->nunlinked == 0 || row2->nunlinked == row2->len);
    7358
    7359 /* set the iterators to the last column we want to regard in the row: nunlinked is either 0 or row->len,
    7360 * therefore, we get nlpcols if nunlinked is 0 and row->len if the row is completely unlinked
    7361 */
    7362 i1 = MAX(row1->nlpcols, row1->nunlinked) - 1;
    7363 i2 = MAX(row2->nlpcols, row2->nunlinked) - 1;
    7364 scalarprod = 0.0;
    7365
    7366 /* calculate the scalar product */
    7367 while( i1 >= 0 && i2 >= 0 )
    7368 {
    7369 assert(row1->cols[i1]->index == row1colsidx[i1]);
    7370 assert(row2->cols[i2]->index == row2colsidx[i2]);
    7371 assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
    7372 if( row1colsidx[i1] < row2colsidx[i2] )
    7373 --i2;
    7374 else if( row1colsidx[i1] > row2colsidx[i2] )
    7375 --i1;
    7376 else
    7377 {
    7378 scalarprod += row1->vals[i1] * row2->vals[i2];
    7379 --i1;
    7380 --i2;
    7381 }
    7382 }
    7383 }
    7384 /* the "harder" cases 3) - 5): start with four partitions and reduce their number iteratively */
    7385 else
    7386 {
    7387 SCIP_Bool lpcols;
    7388 int ilp1;
    7389 int inlp1;
    7390 int ilp2;
    7391 int inlp2;
    7392 int end1;
    7393 int end2;
    7394
    7395 scalarprod = 0;
    7396 ilp1 = 0;
    7397 ilp2 = 0;
    7398
    7399 /* if a row is completely linked (case 4a), we do not have to consider its non-LP columns */
    7400 inlp1 = (row1->nunlinked > 0 ? row1->nlpcols : row1->len);
    7401 inlp2 = (row2->nunlinked > 0 ? row2->nlpcols : row2->len);
    7402
    7403 /* handle the case of four partitions (case 3) until one partition is finished;
    7404 * cases 4a), 4b), and 5) will fail the while-condition
    7405 */
    7406 while( ilp1 < row1->nlpcols && inlp1 < row1->len && ilp2 < row2->nlpcols && inlp2 < row2->len )
    7407 {
    7408 assert(row1->cols[ilp1]->index == row1colsidx[ilp1]);
    7409 assert(row1->cols[inlp1]->index == row1colsidx[inlp1]);
    7410 assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
    7411 assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
    7412 assert((row1->cols[ilp1] == row2->cols[ilp2]) == (row1colsidx[ilp1] == row2colsidx[ilp2]));
    7413 assert((row1->cols[ilp1] == row2->cols[inlp2]) == (row1colsidx[ilp1] == row2colsidx[inlp2]));
    7414 assert((row1->cols[inlp1] == row2->cols[ilp2]) == (row1colsidx[inlp1] == row2colsidx[ilp2]));
    7415 assert((row1->cols[inlp1] == row2->cols[inlp2]) == (row1colsidx[inlp1] == row2colsidx[inlp2]));
    7416
    7417 /* rows have the same linked LP columns */
    7418 if( row1colsidx[ilp1] == row2colsidx[ilp2] )
    7419 {
    7420 scalarprod += row1->vals[ilp1] * row2->vals[ilp2];
    7421 ++ilp1;
    7422 ++ilp2;
    7423 }
    7424 /* LP column of row1 is the same as unlinked column of row2 */
    7425 else if( row1colsidx[ilp1] == row2colsidx[inlp2] )
    7426 {
    7427 scalarprod += row1->vals[ilp1] * row2->vals[inlp2];
    7428 ++ilp1;
    7429 ++inlp2;
    7430 }
    7431 /* unlinked column of row1 is the same as LP column of row2 */
    7432 else if( row1colsidx[inlp1] == row2colsidx[ilp2] )
    7433 {
    7434 scalarprod += row1->vals[inlp1] * row2->vals[ilp2];
    7435 ++inlp1;
    7436 ++ilp2;
    7437 }
    7438 /* two unlinked LP columns are the same */
    7439 else if( row1colsidx[inlp1] == row2colsidx[inlp2] && row1->cols[inlp1]->lppos >= 0 )
    7440 {
    7441 scalarprod += row1->vals[inlp1] * row2->vals[inlp2];
    7442 ++inlp1;
    7443 ++inlp2;
    7444 }
    7445 /* increase smallest counter */
    7446 else if( row1colsidx[ilp1] < row1colsidx[inlp1] )
    7447 {
    7448 if( row2colsidx[ilp2] < row2colsidx[inlp2] )
    7449 {
    7450 if( row1colsidx[ilp1] < row2colsidx[ilp2] )
    7451 ++ilp1;
    7452 else
    7453 ++ilp2;
    7454 }
    7455 else
    7456 {
    7457 if( row1colsidx[ilp1] < row2colsidx[inlp2] )
    7458 ++ilp1;
    7459 else
    7460 ++inlp2;
    7461 }
    7462 }
    7463 else
    7464 {
    7465 if( row2colsidx[ilp2] < row2colsidx[inlp2] )
    7466 {
    7467 if( row1colsidx[inlp1] < row2colsidx[ilp2] )
    7468 ++inlp1;
    7469 else
    7470 ++ilp2;
    7471 }
    7472 else
    7473 {
    7474 if( row1colsidx[inlp1] < row2colsidx[inlp2] )
    7475 ++inlp1;
    7476 else
    7477 ++inlp2;
    7478 }
    7479 }
    7480 }
    7481
    7482 /* One partition was completely handled, we just have to handle the three remaining partitions:
    7483 * the remaining partition of this row and the two partitions of the other row.
    7484 * If necessary, we swap the partitions to ensure that row1 is the row with only one remaining partition.
    7485 */
    7486 if( ilp1 != row1->nlpcols && inlp1 != row1->len )
    7487 {
    7488 int tmpilp;
    7489 int tmpinlp;
    7490
    7491 assert(ilp2 == row2->nlpcols || inlp2 == row2->len);
    7492
    7493 SCIPswapPointers((void**) &row1, (void**) &row2);
    7494 SCIPswapPointers((void**) &row1colsidx, (void**) &row2colsidx);
    7495 tmpilp = ilp1;
    7496 tmpinlp = inlp1;
    7497 ilp1 = ilp2;
    7498 inlp1 = inlp2;
    7499 ilp2 = tmpilp;
    7500 inlp2 = tmpinlp;
    7501 }
    7502
    7503 /* determine section of row 1 that we want to look at (current iterator = begin, end, LP-columns?)
    7504 * -> this merges cases 4a) and 4b)
    7505 */
    7506 if( ilp1 == row1->nlpcols )
    7507 {
    7508 i1 = inlp1;
    7509 end1 = row1->len;
    7510 lpcols = FALSE;
    7511 }
    7512 else
    7513 {
    7514 assert(inlp1 == row1->len);
    7515
    7516 i1 = ilp1;
    7517 end1 = row1->nlpcols;
    7518 lpcols = TRUE;
    7519 }
    7520
    7521 /* handle the case of three partitions (case 4) until one partition is finished, this reduces our problem to case 1), 2), or 5);
    7522 * case 5) will fail the while-condition
    7523 */
    7524 while( i1 < end1 && ilp2 < row2->nlpcols && inlp2 < row2->len )
    7525 {
    7526 assert(row1->cols[i1]->index == row1colsidx[i1]);
    7527 assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
    7528 assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
    7529 assert((row1->cols[i1] == row2->cols[ilp2]) == (row1colsidx[i1] == row2colsidx[ilp2]));
    7530 assert((row1->cols[i1] == row2->cols[inlp2]) == (row1colsidx[i1] == row2colsidx[inlp2]));
    7531
    7532 /* current column in row 1 is the same as the current LP column in row 2 */
    7533 if( row1colsidx[i1] == row2colsidx[ilp2] )
    7534 {
    7535 scalarprod += row1->vals[i1] * row2->vals[ilp2];
    7536 ++i1;
    7537 ++ilp2;
    7538 }
    7539 /* linked or unlinked LP column of row1 is the same as unlinked column of row2 */
    7540 else if( row1colsidx[i1] == row2colsidx[inlp2] && (lpcols || row1->cols[i1]->lppos >= 0) )
    7541 {
    7542 scalarprod += row1->vals[i1] * row2->vals[inlp2];
    7543 ++i1;
    7544 ++inlp2;
    7545 }
    7546 /* increase smallest counter */
    7547 else if( row2colsidx[ilp2] < row2colsidx[inlp2] )
    7548 {
    7549 if( row1colsidx[i1] < row2colsidx[ilp2] )
    7550 ++i1;
    7551 else
    7552 ++ilp2;
    7553 }
    7554 else
    7555 {
    7556 if( row1colsidx[i1] < row2colsidx[inlp2] )
    7557 ++i1;
    7558 else
    7559 ++inlp2;
    7560 }
    7561 }
    7562
    7563 /* if the second section of row 1 was finished, we can stop; otherwise, we have to consider the remaining parts of
    7564 * the two rows
    7565 */
    7566 if( i1 < end1 )
    7567 {
    7568 /* determine section of row 2 that we want to look at (current iterator = begin, end, LP-columns?) */
    7569 if( ilp2 == row2->nlpcols )
    7570 {
    7571 i2 = inlp2;
    7572 end2 = row2->len;
    7573 lpcols = FALSE;
    7574 }
    7575 else
    7576 {
    7577 assert(inlp2 == row2->len);
    7578
    7579 i2 = ilp2;
    7580 end2 = row2->nlpcols;
    7581 }
    7582
    7583 /* handle the case of two partitions (standard case 5, or case 1 or 2 due to partition reduction) */
    7584 while( i1 < end1 && i2 < end2 )
    7585 {
    7586 assert(row1->cols[i1]->index == row1colsidx[i1]);
    7587 assert(row2->cols[i2]->index == row2colsidx[i2]);
    7588 assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
    7589
    7590 /* linked or unlinked LP column of row1 is the same as linked or unlinked LP column of row2 */
    7591 if( row1colsidx[i1] == row2colsidx[i2] && (lpcols || row1->cols[i1]->lppos >= 0) )
    7592 {
    7593 scalarprod += row1->vals[i1] * row2->vals[i2];
    7594 ++i1;
    7595 ++i2;
    7596 }
    7597 /* increase smallest counter */
    7598 else if( row1colsidx[i1] < row2colsidx[i2] )
    7599 ++i1;
    7600 else
    7601 ++i2;
    7602 }
    7603 }
    7604 }
    7605
    7606 return scalarprod;
    7607}
    7608
    7609/** returns the discrete scalar product of the coefficient vectors of the two given rows */
    7610static
    7612 SCIP_ROW* row1, /**< first LP row */
    7613 SCIP_ROW* row2 /**< second LP row */
    7614 )
    7615{
    7616 int prod;
    7617 int* row1colsidx;
    7618 int* row2colsidx;
    7619 int i1;
    7620 int i2;
    7621
    7622 assert(row1 != NULL);
    7623 assert(row2 != NULL);
    7624
    7625 /* Sort the column indices of both rows.
    7626 *
    7627 * The columns in a row are divided into two parts: LP columns, which are currently in the LP and non-LP columns;
    7628 * we sort the rows, but that only ensures that within these two parts, columns are sorted w.r.t. their index.
    7629 * Normally, this should be suficient, because a column contained in both rows should either be one of the LP columns
    7630 * for both or one of the non-LP columns for both.
    7631 * However, directly after a row was created, before a row is added to the LP, the row is not linked to all its
    7632 * columns and all columns are treated as non-LP columns. Moreover, for example when doing column generation,
    7633 * columns can be added later and remain unlinked while all previously added columns might already be linked.
    7634 * Therefore, we have to be very careful about whether we can rely on the partitioning of the variables.
    7635 *
    7636 * We distinguish the following cases:
    7637 *
    7638 * 1) both rows have no unlinked columns
    7639 * -> we just check the LP partitions
    7640 *
    7641 * 2) exactly one row is completely unlinked, the other one is completely linked
    7642 * -> we compare the non-LP (unlinked) partition with the LP partition of the other row
    7643 * (thus all common LP columns are regarded)
    7644 *
    7645 * 3) we have unlinked and LP columns in both rows
    7646 * -> we need to compare four partitions at once
    7647 *
    7648 * 4a) we have one row with unlinked and LP columns and the other without any unlinked columns
    7649 * -> we need to compare three partitions: the LP part of the completely linked row and both partitions of the
    7650 * other row
    7651 *
    7652 * 4b) we have one row with unlinked and LP columns and the other is completely unlinked
    7653 * -> we need to compare three partitions: the complete unlinked row and both partitions of the other row
    7654 *
    7655 * 5) both rows are completely unlinked
    7656 * -> we need to compare two partitions: both complete rows
    7657 */
    7658 SCIProwSort(row1);
    7659 assert(row1->lpcolssorted);
    7660 assert(row1->nonlpcolssorted);
    7661 SCIProwSort(row2);
    7662 assert(row2->lpcolssorted);
    7663 assert(row2->nonlpcolssorted);
    7664
    7665 assert(row1->nunlinked <= row1->len - row1->nlpcols);
    7666 assert(row2->nunlinked <= row2->len - row2->nlpcols);
    7667
    7668 row1colsidx = row1->cols_index;
    7669 row2colsidx = row2->cols_index;
    7670
    7671#ifndef NDEBUG
    7672 /* check that we can rely on the partition into LP columns and non-LP columns if the rows are completely linked */
    7673 if( row1->nunlinked == 0 && row2->nunlinked == 0 )
    7674 {
    7675 i1 = 0;
    7676 i2 = row2->nlpcols;
    7677 while( i1 < row1->nlpcols && i2 < row2->len )
    7678 {
    7679 assert(row1->cols[i1] != row2->cols[i2]);
    7680 if( row1->cols[i1]->index < row2->cols[i2]->index )
    7681 ++i1;
    7682 else
    7683 {
    7684 assert(row1->cols[i1]->index > row2->cols[i2]->index);
    7685 ++i2;
    7686 }
    7687 }
    7688 assert(i1 == row1->nlpcols || i2 == row2->len);
    7689
    7690 i1 = row1->nlpcols;
    7691 i2 = 0;
    7692 while( i1 < row1->len && i2 < row2->nlpcols )
    7693 {
    7694 assert(row1->cols[i1] != row2->cols[i2]);
    7695 if( row1->cols[i1]->index < row2->cols[i2]->index )
    7696 ++i1;
    7697 else
    7698 {
    7699 assert(row1->cols[i1]->index > row2->cols[i2]->index);
    7700 ++i2;
    7701 }
    7702 }
    7703 assert(i1 == row1->len || i2 == row2->nlpcols);
    7704 }
    7705#endif
    7706
    7707 /* The "easy" cases 1) and 2) */
    7708 if( (row1->nunlinked == 0 && row2->nunlinked == 0) ||
    7709 ((row1->nlpcols == row1->len || row1->nunlinked == row1->len)
    7710 && (row2->nlpcols == row2->len || row2->nunlinked == row2->len)
    7711 && (row1->nunlinked == 0 || row2->nunlinked == 0)) )
    7712 {
    7713 assert(row1->nunlinked == 0 || row1->nunlinked == row1->len);
    7714 assert(row2->nunlinked == 0 || row2->nunlinked == row2->len);
    7715
    7716 /* set the iterators to the last column we want to regard in the row: nunlinked is either 0 or row->len,
    7717 * therefore, we get nlpcols if nunlinked is 0 and row->len if the row is completely unlinked
    7718 */
    7719 i1 = MAX(row1->nlpcols, row1->nunlinked) - 1;
    7720 i2 = MAX(row2->nlpcols, row2->nunlinked) - 1;
    7721 prod = 0;
    7722
    7723 /* calculate the scalar product */
    7724 while( i1 >= 0 && i2 >= 0 )
    7725 {
    7726 assert(row1->cols[i1]->index == row1colsidx[i1]);
    7727 assert(row2->cols[i2]->index == row2colsidx[i2]);
    7728 assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
    7729 if( row1colsidx[i1] < row2colsidx[i2] )
    7730 --i2;
    7731 else if( row1colsidx[i1] > row2colsidx[i2] )
    7732 --i1;
    7733 else
    7734 {
    7735 ++prod;
    7736 --i1;
    7737 --i2;
    7738 }
    7739 }
    7740 }
    7741 /* the "harder" cases 3) - 5): start with four partitions and reduce their number iteratively */
    7742 else
    7743 {
    7744 SCIP_Bool lpcols;
    7745 int ilp1;
    7746 int inlp1;
    7747 int ilp2;
    7748 int inlp2;
    7749 int end1;
    7750 int end2;
    7751
    7752 prod = 0;
    7753 ilp1 = 0;
    7754 ilp2 = 0;
    7755
    7756 /* if a row is completely linked (case 4a), we do not have to consider its non-LP columns */
    7757 inlp1 = (row1->nunlinked > 0 ? row1->nlpcols : row1->len);
    7758 inlp2 = (row2->nunlinked > 0 ? row2->nlpcols : row2->len);
    7759
    7760 /* handle the case of four partitions (case 3) until one partition is finished;
    7761 * cases 4a), 4b), and 5) will fail the while-condition
    7762 */
    7763 while( ilp1 < row1->nlpcols && inlp1 < row1->len && ilp2 < row2->nlpcols && inlp2 < row2->len )
    7764 {
    7765 assert(row1->cols[ilp1]->index == row1colsidx[ilp1]);
    7766 assert(row1->cols[inlp1]->index == row1colsidx[inlp1]);
    7767 assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
    7768 assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
    7769 assert((row1->cols[ilp1] == row2->cols[ilp2]) == (row1colsidx[ilp1] == row2colsidx[ilp2]));
    7770 assert((row1->cols[ilp1] == row2->cols[inlp2]) == (row1colsidx[ilp1] == row2colsidx[inlp2]));
    7771 assert((row1->cols[inlp1] == row2->cols[ilp2]) == (row1colsidx[inlp1] == row2colsidx[ilp2]));
    7772 assert((row1->cols[inlp1] == row2->cols[inlp2]) == (row1colsidx[inlp1] == row2colsidx[inlp2]));
    7773
    7774 /* rows have the same linked LP columns */
    7775 if( row1colsidx[ilp1] == row2colsidx[ilp2] )
    7776 {
    7777 ++prod;
    7778 ++ilp1;
    7779 ++ilp2;
    7780 }
    7781 /* LP column of row1 is the same as unlinked column of row2 */
    7782 else if( row1colsidx[ilp1] == row2colsidx[inlp2] )
    7783 {
    7784 ++prod;
    7785 ++ilp1;
    7786 ++inlp2;
    7787 }
    7788 /* unlinked column of row1 is the same as LP column of row2 */
    7789 else if( row1colsidx[inlp1] == row2colsidx[ilp2] )
    7790 {
    7791 ++prod;
    7792 ++inlp1;
    7793 ++ilp2;
    7794 }
    7795 /* two unlinked LP columns are the same */
    7796 else if( row1colsidx[inlp1] == row2colsidx[inlp2] && row1->cols[inlp1]->lppos >= 0 )
    7797 {
    7798 ++prod;
    7799 ++inlp1;
    7800 ++inlp2;
    7801 }
    7802 /* increase smallest counter */
    7803 else if( row1colsidx[ilp1] < row1colsidx[inlp1] )
    7804 {
    7805 if( row2colsidx[ilp2] < row2colsidx[inlp2] )
    7806 {
    7807 if( row1colsidx[ilp1] < row2colsidx[ilp2] )
    7808 ++ilp1;
    7809 else
    7810 ++ilp2;
    7811 }
    7812 else
    7813 {
    7814 if( row1colsidx[ilp1] < row2colsidx[inlp2] )
    7815 ++ilp1;
    7816 else
    7817 ++inlp2;
    7818 }
    7819 }
    7820 else
    7821 {
    7822 if( row2colsidx[ilp2] < row2colsidx[inlp2] )
    7823 {
    7824 if( row1colsidx[inlp1] < row2colsidx[ilp2] )
    7825 ++inlp1;
    7826 else
    7827 ++ilp2;
    7828 }
    7829 else
    7830 {
    7831 if( row1colsidx[inlp1] < row2colsidx[inlp2] )
    7832 ++inlp1;
    7833 else
    7834 ++inlp2;
    7835 }
    7836 }
    7837 }
    7838
    7839 /* One partition was completely handled, we just have to handle the three remaining partitions:
    7840 * the remaining partition of this row and the two partitions of the other row.
    7841 * If necessary, we swap the partitions to ensure that row1 is the row with only one remaining partition.
    7842 */
    7843 if( ilp1 != row1->nlpcols && inlp1 != row1->len )
    7844 {
    7845 int tmpilp;
    7846 int tmpinlp;
    7847
    7848 assert(ilp2 == row2->nlpcols || inlp2 == row2->len);
    7849
    7850 SCIPswapPointers((void**) &row1, (void**) &row2);
    7851 SCIPswapPointers((void**) &row1colsidx, (void**) &row2colsidx);
    7852 tmpilp = ilp1;
    7853 tmpinlp = inlp1;
    7854 ilp1 = ilp2;
    7855 inlp1 = inlp2;
    7856 ilp2 = tmpilp;
    7857 inlp2 = tmpinlp;
    7858 }
    7859
    7860 /* determine section of row 1 that we want to look at (current iterator = begin, end, LP-columns?)
    7861 * -> this merges cases 4a) and 4b)
    7862 */
    7863 if( ilp1 == row1->nlpcols )
    7864 {
    7865 i1 = inlp1;
    7866 end1 = row1->len;
    7867 lpcols = FALSE;
    7868 }
    7869 else
    7870 {
    7871 assert(inlp1 == row1->len);
    7872
    7873 i1 = ilp1;
    7874 end1 = row1->nlpcols;
    7875 lpcols = TRUE;
    7876 }
    7877
    7878 /* handle the case of three partitions (case 4) until one partition is finished, this reduces our problem to case 1), 2), or 5);
    7879 * case 5) will fail the while-condition
    7880 */
    7881 while( i1 < end1 && ilp2 < row2->nlpcols && inlp2 < row2->len )
    7882 {
    7883 assert(row1->cols[i1]->index == row1colsidx[i1]);
    7884 assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
    7885 assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
    7886 assert((row1->cols[i1] == row2->cols[ilp2]) == (row1colsidx[i1] == row2colsidx[ilp2]));
    7887 assert((row1->cols[i1] == row2->cols[inlp2]) == (row1colsidx[i1] == row2colsidx[inlp2]));
    7888
    7889 /* current column in row 1 is the same as the current LP column in row 2 */
    7890 if( row1colsidx[i1] == row2colsidx[ilp2] )
    7891 {
    7892 ++prod;
    7893 ++i1;
    7894 ++ilp2;
    7895 }
    7896 /* linked or unlinked LP column of row1 is the same as unlinked column of row2 */
    7897 else if( row1colsidx[i1] == row2colsidx[inlp2] && (lpcols || row1->cols[i1]->lppos >= 0) )
    7898 {
    7899 ++prod;
    7900 ++i1;
    7901 ++inlp2;
    7902 }
    7903 /* increase smallest counter */
    7904 else if( row2colsidx[ilp2] < row2colsidx[inlp2] )
    7905 {
    7906 if( row1colsidx[i1] < row2colsidx[ilp2] )
    7907 ++i1;
    7908 else
    7909 ++ilp2;
    7910 }
    7911 else
    7912 {
    7913 if( row1colsidx[i1] < row2colsidx[inlp2] )
    7914 ++i1;
    7915 else
    7916 ++inlp2;
    7917 }
    7918 }
    7919
    7920 /* if the second section of row 1 was finished, we can stop; otherwise, we have to consider the remaining parts of
    7921 * the two rows
    7922 */
    7923 if( i1 < end1 )
    7924 {
    7925 /* determine section of row 2 that we want to look at (current iterator = begin, end, LP-columns?) */
    7926 if( ilp2 == row2->nlpcols )
    7927 {
    7928 i2 = inlp2;
    7929 end2 = row2->len;
    7930 lpcols = FALSE;
    7931 }
    7932 else
    7933 {
    7934 assert(inlp2 == row2->len);
    7935
    7936 i2 = ilp2;
    7937 end2 = row2->nlpcols;
    7938 }
    7939
    7940 /* handle the case of two partitions (standard case 5, or case 1 or 2 due to partition reduction) */
    7941 while( i1 < end1 && i2 < end2 )
    7942 {
    7943 assert(row1->cols[i1]->index == row1colsidx[i1]);
    7944 assert(row2->cols[i2]->index == row2colsidx[i2]);
    7945 assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
    7946
    7947 /* linked or unlinked LP column of row1 is the same as linked or unlinked LP column of row2 */
    7948 if( row1colsidx[i1] == row2colsidx[i2] && (lpcols || row1->cols[i1]->lppos >= 0) )
    7949 {
    7950 ++prod;
    7951 ++i1;
    7952 ++i2;
    7953 }
    7954 /* increase smallest counter */
    7955 else if( row1colsidx[i1] < row2colsidx[i2] )
    7956 ++i1;
    7957 else
    7958 ++i2;
    7959 }
    7960 }
    7961 }
    7962
    7963 return prod;
    7964}
    7965
    7966/** returns the degree of parallelism between the hyperplanes defined by the two row vectors v, w:
    7967 * p = |v*w|/(|v|*|w|);
    7968 * the hyperplanes are parallel, iff p = 1, they are orthogonal, iff p = 0
    7969 */
    7971 SCIP_ROW* row1, /**< first LP row */
    7972 SCIP_ROW* row2, /**< second LP row */
    7973 char orthofunc /**< function used for calc. scalar prod. ('e'uclidean, 'd'iscrete) */
    7974 )
    7975{
    7976 SCIP_Real parallelism;
    7977 SCIP_Real scalarprod;
    7978
    7979 switch( orthofunc )
    7980 {
    7981 case 'e':
    7982 scalarprod = SCIProwGetScalarProduct(row1, row2);
    7983 if( scalarprod == 0.0 )
    7984 {
    7985 parallelism = 0.0;
    7986 break;
    7987 }
    7988
    7989 if( SCIProwGetNorm(row1) == 0.0 )
    7990 {
    7991 /* In theory, this should not happen if the scalarproduct is not zero
    7992 * But due to bug 520 (also issue 44), it is possible that norms are not correct.
    7993 * Thus, if the norm is so bad that it is even 0, then reevaluate it here.
    7994 * But as we don't have set available here, we cannot call rowCalcNorms, so do it by hand.
    7995 */
    7996 int i;
    7997 for( i = 0; i < row1->len; ++i )
    7998 if( row1->cols[i]->lppos >= 0 )
    7999 row1->sqrnorm += SQR(row1->vals[i]);
    8000 assert(SCIProwGetNorm(row1) != 0.0);
    8001 }
    8002
    8003 if( SCIProwGetNorm(row2) == 0.0 )
    8004 {
    8005 /* same as for row1 above: reeval norms if it is 0, which is wrong */
    8006 int i;
    8007 for( i = 0; i < row2->len; ++i )
    8008 if( row2->cols[i]->lppos >= 0 )
    8009 row2->sqrnorm += SQR(row2->vals[i]);
    8010 assert(SCIProwGetNorm(row2) != 0.0);
    8011 }
    8012
    8013 parallelism = REALABS(scalarprod) / (SCIProwGetNorm(row1) * SCIProwGetNorm(row2));
    8014 break;
    8015
    8016 case 'd':
    8017 scalarprod = (SCIP_Real) SCIProwGetDiscreteScalarProduct(row1, row2);
    8018 parallelism = scalarprod / (sqrt((SCIP_Real) SCIProwGetNNonz(row1)) * sqrt((SCIP_Real) SCIProwGetNNonz(row2)));
    8019 break;
    8020
    8021 default:
    8022 SCIPerrorMessage("invalid orthogonality function parameter '%c'\n", orthofunc);
    8023 SCIPABORT();
    8024 parallelism = 0.0; /*lint !e527*/
    8025 }
    8026
    8027 return parallelism;
    8028}
    8029
    8030/** returns the degree of orthogonality between the hyperplanes defined by the two row vectors v, w:
    8031 * o = 1 - |v*w|/(|v|*|w|);
    8032 * the hyperplanes are orthogonal, iff p = 1, they are parallel, iff p = 0
    8033 */
    8035 SCIP_ROW* row1, /**< first LP row */
    8036 SCIP_ROW* row2, /**< second LP row */
    8037 char orthofunc /**< function used for calc. scalar prod. ('e'uclidean, 'd'iscrete) */
    8038 )
    8039{
    8040 return 1.0 - SCIProwGetParallelism(row1, row2, orthofunc);
    8041}
    8042
    8043/** gets parallelism of row with objective function: if the returned value is 1, the row is parallel to the objective
    8044 * function, if the value is 0, it is orthogonal to the objective function
    8045 */
    8047 SCIP_ROW* row, /**< LP row */
    8048 SCIP_SET* set, /**< global SCIP settings */
    8049 SCIP_LP* lp /**< current LP data */
    8050 )
    8051{
    8052 SCIP_Real prod;
    8053 SCIP_Real parallelism;
    8054
    8055 assert(row != NULL);
    8056 assert(lp != NULL);
    8057
    8058 if( lp->objsqrnormunreliable )
    8060
    8061 assert(!lp->objsqrnormunreliable);
    8062 assert(lp->objsqrnorm >= 0.0);
    8063
    8064 checkRowSqrnorm(row);
    8065 checkRowObjprod(row);
    8066
    8067 prod = row->sqrnorm * lp->objsqrnorm;
    8068
    8069 parallelism = SCIPsetIsPositive(set, prod) ? REALABS(row->objprod) / sqrt(prod) : 0.0;
    8070 assert(SCIPsetIsSumGE(set, parallelism, 0.0));
    8071 assert(SCIPsetIsSumLE(set, parallelism, 1.0));
    8072 parallelism = MIN(parallelism, 1.0);
    8073 parallelism = MAX(parallelism, 0.0);
    8074
    8075 return parallelism;
    8076}
    8077
    8078/** includes event handler with given data in row's event filter */
    8080 SCIP_ROW* row, /**< row */
    8081 BMS_BLKMEM* blkmem, /**< block memory */
    8082 SCIP_SET* set, /**< global SCIP settings */
    8083 SCIP_EVENTTYPE eventtype, /**< event type to catch */
    8084 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
    8085 SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler for the event processing */
    8086 int* filterpos /**< pointer to store position of event filter entry, or NULL */
    8087 )
    8088{
    8089 assert(row != NULL);
    8090 assert(row->eventfilter != NULL);
    8091 assert((eventtype & ~SCIP_EVENTTYPE_ROWCHANGED) == 0);
    8092 assert((eventtype & SCIP_EVENTTYPE_ROWCHANGED) != 0);
    8093
    8094 SCIPsetDebugMsg(set, "catch event of type 0x%" SCIP_EVENTTYPE_FORMAT " of row <%s> with handler %p and data %p\n",
    8095 eventtype, row->name, (void*)eventhdlr, (void*)eventdata);
    8096
    8097 SCIP_CALL( SCIPeventfilterAdd(row->eventfilter, blkmem, set, eventtype, eventhdlr, eventdata, filterpos) );
    8098
    8099 return SCIP_OKAY;
    8100}
    8101
    8102/** deletes event handler with given data from row's event filter */
    8104 SCIP_ROW* row, /**< row */
    8105 BMS_BLKMEM* blkmem, /**< block memory */
    8106 SCIP_SET* set, /**< global SCIP settings */
    8107 SCIP_EVENTTYPE eventtype, /**< event type mask of dropped event */
    8108 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
    8109 SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler for the event processing */
    8110 int filterpos /**< position of event filter entry returned by SCIPvarCatchEvent(), or -1 */
    8111 )
    8112{
    8113 assert(row != NULL);
    8114 assert(row->eventfilter != NULL);
    8115
    8116 SCIPsetDebugMsg(set, "drop event of row <%s> with handler %p and data %p\n", row->name, (void*)eventhdlr, (void*)eventdata);
    8117
    8118 SCIP_CALL( SCIPeventfilterDel(row->eventfilter, blkmem, set, eventtype, eventhdlr, eventdata, filterpos) );
    8119
    8120 return SCIP_OKAY;
    8121}
    8122
    8123/** marks a row to be not removable from the LP in the current node because it became obsolete */
    8125 SCIP_ROW* row, /**< LP row */
    8126 SCIP_STAT* stat /**< problem statistics */
    8127 )
    8128{
    8129 assert(row != NULL);
    8130 assert(stat != NULL);
    8131 assert(stat->nnodes > 0);
    8132
    8133 /* lpRemoveObsoleteRows() does not remove a row if the node number stored in obsoletenode equals the current node number */
    8134 row->obsoletenode = stat->nnodes;
    8135}
    8136
    8137/*
    8138 * LP solver data update
    8139 */
    8140
    8141/** resets column data to represent a column not in the LP solver */
    8142static
    8144 SCIP_COL* col /**< column to be marked deleted */
    8145 )
    8146{
    8147 assert(col != NULL);
    8148
    8149 col->lpipos = -1;
    8150 col->primsol = 0.0;
    8151 col->redcost = SCIP_INVALID;
    8152 col->farkascoef = SCIP_INVALID;
    8153 col->sbdown = SCIP_INVALID;
    8154 col->sbup = SCIP_INVALID;
    8155 col->sbdownvalid = FALSE;
    8156 col->sbupvalid = FALSE;
    8157 col->validredcostlp = -1;
    8158 col->validfarkaslp = -1;
    8159 col->sbitlim = -1;
    8160 col->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
    8161}
    8162
    8163/** applies all cached column removals to the LP solver */
    8164static
    8166 SCIP_LP* lp /**< current LP data */
    8167 )
    8168{
    8169 assert(lp != NULL);
    8170 assert(lp->lpifirstchgcol <= lp->nlpicols);
    8171 assert(lp->lpifirstchgcol <= lp->ncols);
    8172
    8173 /* find the first column to change */
    8174 while( lp->lpifirstchgcol < lp->nlpicols
    8175 && lp->lpifirstchgcol < lp->ncols
    8176 && lp->cols[lp->lpifirstchgcol]->lpipos == lp->lpifirstchgcol
    8177 && !lp->cols[lp->lpifirstchgcol]->coefchanged )
    8178 {
    8179 assert(lp->cols[lp->lpifirstchgcol] == lp->lpicols[lp->lpifirstchgcol]);
    8180 lp->lpifirstchgcol++;
    8181 }
    8182
    8183 /* shrink LP to the part which didn't change */
    8184 if( lp->lpifirstchgcol < lp->nlpicols )
    8185 {
    8186 int i;
    8187
    8188 assert(!lp->diving);
    8189 SCIPdebugMessage("flushing col deletions: shrink LP from %d to %d columns\n", lp->nlpicols, lp->lpifirstchgcol);
    8191 for( i = lp->lpifirstchgcol; i < lp->nlpicols; ++i )
    8192 {
    8193 markColDeleted(lp->lpicols[i]);
    8194 }
    8195 lp->nlpicols = lp->lpifirstchgcol;
    8196 lp->flushdeletedcols = TRUE;
    8197 lp->updateintegrality = TRUE;
    8198
    8199 /* mark the LP unsolved */
    8200 lp->solved = FALSE;
    8201 lp->primalfeasible = FALSE;
    8202 lp->primalchecked = FALSE;
    8203 lp->lpobjval = SCIP_INVALID;
    8205 }
    8206 assert(lp->nlpicols == lp->lpifirstchgcol);
    8207
    8208 return SCIP_OKAY;
    8209}
    8210
    8211/** computes for the given column the lower and upper bound that should be flushed into the LP
    8212 * depending on lazy bounds and diving mode; in diving mode, lazy bounds are ignored, i.e.,
    8213 * the bounds are explicitly added to the LP in any case
    8214 */
    8215static
    8217 SCIP_LP* lp, /**< current LP data */
    8218 SCIP_SET* set, /**< global SCIP settings */
    8219 SCIP_COL* col, /**< column to compute bounds for */
    8220 SCIP_Real lpiinf, /**< infinity value if the LP solver */
    8221 SCIP_Real* lb, /**< pointer to store the new lower bound */
    8222 SCIP_Real* ub /**< pointer to store the new upper bound */
    8223 )
    8224{
    8225 assert(lp != NULL);
    8226 assert(set != NULL);
    8227 assert(col != NULL);
    8228 assert(lb != NULL);
    8229 assert(ub != NULL);
    8230
    8231 /* get the correct new lower bound:
    8232 * if lazy lower bound exists and is larger than lower bound, set lower bound to infinity;
    8233 * if we are in diving mode, ignore lazy bounds and always take the lower bound
    8234 */
    8235 if( SCIPsetIsInfinity(set, -col->lb) || (SCIPsetIsLE(set, col->lb, col->lazylb) && !SCIPlpDiving(lp)) )
    8236 (*lb) = -lpiinf;
    8237 else
    8238 (*lb) = col->lb;
    8239 /* get the correct new upper bound:
    8240 * if lazy upper bound exists and is larger than upper bound, set upper bound to infinity;
    8241 * if we are in diving mode, ignore lazy bounds and always take the upper bound
    8242 */
    8243 if( SCIPsetIsInfinity(set, col->ub) || (SCIPsetIsGE(set, col->ub, col->lazyub) && !SCIPlpDiving(lp)) )
    8244 (*ub) = lpiinf;
    8245 else
    8246 (*ub) = col->ub;
    8247}
    8248
    8249/** applies all cached column additions to the LP solver */
    8250static
    8252 SCIP_LP* lp, /**< current LP data */
    8253 BMS_BLKMEM* blkmem, /**< block memory */
    8254 SCIP_SET* set, /**< global SCIP settings */
    8255 SCIP_EVENTQUEUE* eventqueue /**< event queue */
    8256 )
    8257{
    8258 SCIP_Real* obj;
    8259 SCIP_Real* lb;
    8260 SCIP_Real* ub;
    8261 int* beg;
    8262 int* ind;
    8263 SCIP_Real* val;
    8264 char** name;
    8265 SCIP_COL* col;
    8266 SCIP_Real lpiinf;
    8267 int c;
    8268 int pos;
    8269 int nnonz;
    8270 int naddcols;
    8271 int naddcoefs;
    8272 int i;
    8273 int lpipos;
    8274
    8275 assert(lp != NULL);
    8276 assert(lp->lpifirstchgcol == lp->nlpicols);
    8277 assert(blkmem != NULL);
    8278 assert(set != NULL);
    8279
    8280 /* if there are no columns to add, we are ready */
    8281 if( lp->ncols == lp->nlpicols )
    8282 return SCIP_OKAY;
    8283
    8284 /* add the additional columns */
    8285 assert(!lp->diving);
    8286 assert(lp->ncols > lp->nlpicols);
    8287 SCIP_CALL( ensureLpicolsSize(lp, set, lp->ncols) );
    8288
    8289 /* get the solver's infinity value */
    8290 lpiinf = SCIPlpiInfinity(lp->lpi);
    8291
    8292 /* count the (maximal) number of added coefficients, calculate the number of added columns */
    8293 naddcols = lp->ncols - lp->nlpicols;
    8294 naddcoefs = 0;
    8295 for( c = lp->nlpicols; c < lp->ncols; ++c )
    8296 naddcoefs += lp->cols[c]->len;
    8297 assert(naddcols > 0);
    8298
    8299 /* get temporary memory for changes */
    8300 SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, naddcols) );
    8301 SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, naddcols) );
    8302 SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, naddcols) );
    8303 SCIP_CALL( SCIPsetAllocBufferArray(set, &beg, naddcols) );
    8304 SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, naddcoefs) );
    8305 SCIP_CALL( SCIPsetAllocBufferArray(set, &val, naddcoefs) );
    8306 SCIP_CALL( SCIPsetAllocBufferArray(set, &name, naddcols) );
    8307
    8308 /* fill temporary memory with column data */
    8309 nnonz = 0;
    8310 for( pos = 0, c = lp->nlpicols; c < lp->ncols; ++pos, ++c )
    8311 {
    8312 col = lp->cols[c];
    8313 assert(col != NULL);
    8314 assert(col->var != NULL);
    8316 assert(SCIPvarGetCol(col->var) == col);
    8317 assert(col->lppos == c);
    8318 assert(nnonz + col->nlprows <= naddcoefs);
    8319
    8320 SCIPsetDebugMsg(set, "flushing added column <%s>: ", SCIPvarGetName(col->var));
    8321 debugColPrint(set, col);
    8322
    8323 /* Because the column becomes a member of the LP solver, it now can take values
    8324 * different from zero. That means, we have to include the column in the corresponding
    8325 * row vectors.
    8326 */
    8327 SCIP_CALL( colLink(col, blkmem, set, eventqueue, lp) );
    8328
    8329 lp->lpicols[c] = col;
    8330 col->lpipos = c;
    8331 col->primsol = SCIP_INVALID;
    8332 col->redcost = SCIP_INVALID;
    8333 col->farkascoef = SCIP_INVALID;
    8334 col->sbdown = SCIP_INVALID;
    8335 col->sbup = SCIP_INVALID;
    8336 col->sbdownvalid = FALSE;
    8337 col->sbupvalid = FALSE;
    8338 col->validredcostlp = -1;
    8339 col->validfarkaslp = -1;
    8340 col->sbitlim = -1;
    8341 col->objchanged = FALSE;
    8342 col->lbchanged = FALSE;
    8343 col->ubchanged = FALSE;
    8344 col->coefchanged = FALSE;
    8345 obj[pos] = col->obj;
    8346
    8347 /* compute bounds that should be flushed into the LP (taking into account lazy bounds) */
    8348 computeLPBounds(lp, set, col, lpiinf, &(lb[pos]), &(ub[pos]));
    8349
    8350 beg[pos] = nnonz;
    8351 name[pos] = (char*)SCIPvarGetName(col->var);
    8352
    8353 col->flushedobj = obj[pos];
    8354 col->flushedlb = lb[pos];
    8355 col->flushedub = ub[pos];
    8356
    8357 for( i = 0; i < col->nlprows; ++i )
    8358 {
    8359 assert(col->rows[i] != NULL);
    8360 lpipos = col->rows[i]->lpipos;
    8361 if( lpipos >= 0 )
    8362 {
    8363 assert(lpipos < lp->nrows);
    8364 assert(nnonz < naddcoefs);
    8365 ind[nnonz] = lpipos;
    8366 val[nnonz] = col->vals[i];
    8367 nnonz++;
    8368 }
    8369 }
    8370#ifndef NDEBUG
    8371 for( i = col->nlprows; i < col->len; ++i )
    8372 {
    8373 assert(col->rows[i] != NULL);
    8374 assert(col->rows[i]->lpipos == -1); /* because the row deletions are already performed */
    8375 }
    8376#endif
    8377 }
    8378
    8379 /* call LP interface */
    8380 SCIPsetDebugMsg(set, "flushing col additions: enlarge LP from %d to %d columns\n", lp->nlpicols, lp->ncols);
    8381 SCIP_CALL( SCIPlpiAddCols(lp->lpi, naddcols, obj, lb, ub, name, nnonz, beg, ind, val) );
    8382 lp->nlpicols = lp->ncols;
    8383 lp->lpifirstchgcol = lp->nlpicols;
    8384
    8385 /* free temporary memory */
    8393
    8394 lp->flushaddedcols = TRUE;
    8395 lp->updateintegrality = TRUE;
    8396
    8397 /* mark the LP unsolved */
    8398 lp->solved = FALSE;
    8399 lp->dualfeasible = FALSE;
    8400 lp->dualchecked = FALSE;
    8401 lp->lpobjval = SCIP_INVALID;
    8403
    8404 return SCIP_OKAY;
    8405}
    8406
    8407/** resets row data to represent a row not in the LP solver */
    8408static
    8410 SCIP_ROW* row /**< row to be marked deleted */
    8411 )
    8412{
    8413 assert(row != NULL);
    8414
    8415 row->lpipos = -1;
    8416 row->dualsol = 0.0;
    8417 row->activity = SCIP_INVALID;
    8418 row->dualfarkas = 0.0;
    8419 row->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
    8420 row->validactivitylp = -1;
    8421}
    8422
    8423/** applies all cached row removals to the LP solver */
    8424static
    8426 SCIP_LP* lp, /**< current LP data */
    8427 BMS_BLKMEM* blkmem, /**< block memory */
    8428 SCIP_SET* set /**< global SCIP settings */
    8429 )
    8430{
    8431 assert(lp != NULL);
    8432 assert(lp->lpifirstchgrow <= lp->nlpirows);
    8433 assert(lp->lpifirstchgrow <= lp->nrows);
    8434
    8435 /* find the first row to change */
    8436 while( lp->lpifirstchgrow < lp->nlpirows
    8437 && lp->lpifirstchgrow < lp->nrows
    8438 && lp->rows[lp->lpifirstchgrow]->lpipos == lp->lpifirstchgrow
    8439 && !lp->rows[lp->lpifirstchgrow]->coefchanged )
    8440 {
    8441 assert(lp->rows[lp->lpifirstchgrow] == lp->lpirows[lp->lpifirstchgrow]);
    8442 lp->lpifirstchgrow++;
    8443 }
    8444
    8445 /* shrink LP to the part which didn't change */
    8446 if( lp->lpifirstchgrow < lp->nlpirows )
    8447 {
    8448 int i;
    8449
    8450 SCIPsetDebugMsg(set, "flushing row deletions: shrink LP from %d to %d rows\n", lp->nlpirows, lp->lpifirstchgrow);
    8452 for( i = lp->lpifirstchgrow; i < lp->nlpirows; ++i )
    8453 {
    8454 markRowDeleted(lp->lpirows[i]);
    8455 SCIP_CALL( SCIProwRelease(&lp->lpirows[i], blkmem, set, lp) );
    8456 }
    8457 lp->nlpirows = lp->lpifirstchgrow;
    8458 lp->flushdeletedrows = TRUE;
    8459
    8460 /* mark the LP unsolved */
    8461 lp->solved = FALSE;
    8462 lp->dualfeasible = FALSE;
    8463 lp->dualchecked = FALSE;
    8464 lp->lpobjval = SCIP_INVALID;
    8466 }
    8467 assert(lp->nlpirows == lp->lpifirstchgrow);
    8468
    8469 return SCIP_OKAY;
    8470}
    8471
    8472/** applies all cached row additions and removals to the LP solver */
    8473static
    8475 SCIP_LP* lp, /**< current LP data */
    8476 BMS_BLKMEM* blkmem, /**< block memory */
    8477 SCIP_SET* set, /**< global SCIP settings */
    8478 SCIP_EVENTQUEUE* eventqueue /**< event queue */
    8479 )
    8480{
    8481 SCIP_Real* lhs;
    8482 SCIP_Real* rhs;
    8483 int* beg;
    8484 int* ind;
    8485 SCIP_Real* val;
    8486 char** name;
    8487 SCIP_ROW* row;
    8488 SCIP_Real lpiinf;
    8489 int r;
    8490 int pos;
    8491 int nnonz;
    8492 int naddrows;
    8493 int naddcoefs;
    8494 int i;
    8495 int lpipos;
    8496
    8497 assert(lp != NULL);
    8498 assert(lp->lpifirstchgrow == lp->nlpirows);
    8499 assert(blkmem != NULL);
    8500
    8501 /* if there are no rows to add, we are ready */
    8502 if( lp->nrows == lp->nlpirows )
    8503 return SCIP_OKAY;
    8504
    8505 /* add the additional rows */
    8506 assert(lp->nrows > lp->nlpirows);
    8507 SCIP_CALL( ensureLpirowsSize(lp, set, lp->nrows) );
    8508
    8509 /* get the solver's infinity value */
    8510 lpiinf = SCIPlpiInfinity(lp->lpi);
    8511
    8512 /* count the (maximal) number of added coefficients, calculate the number of added rows */
    8513 naddrows = lp->nrows - lp->nlpirows;
    8514 naddcoefs = 0;
    8515 for( r = lp->nlpirows; r < lp->nrows; ++r )
    8516 naddcoefs += lp->rows[r]->len;
    8517 assert(naddrows > 0);
    8518
    8519 /* get temporary memory for changes */
    8520 SCIP_CALL( SCIPsetAllocBufferArray(set, &lhs, naddrows) );
    8521 SCIP_CALL( SCIPsetAllocBufferArray(set, &rhs, naddrows) );
    8522 SCIP_CALL( SCIPsetAllocBufferArray(set, &beg, naddrows) );
    8523 SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, naddcoefs) );
    8524 SCIP_CALL( SCIPsetAllocBufferArray(set, &val, naddcoefs) );
    8525 SCIP_CALL( SCIPsetAllocBufferArray(set, &name, naddrows) );
    8526
    8527 /* fill temporary memory with row data */
    8528 nnonz = 0;
    8529 for( pos = 0, r = lp->nlpirows; r < lp->nrows; ++pos, ++r )
    8530 {
    8531 row = lp->rows[r];
    8532 assert(row != NULL);
    8533 assert(row->lppos == r);
    8534 assert(nnonz + row->nlpcols <= naddcoefs);
    8535
    8536 SCIPsetDebugMsg(set, "flushing added row <%s>: ", row->name);
    8537 debugRowPrint(set, row);
    8538
    8539 /* Because the row becomes a member of the LP solver, its dual variable now can take values
    8540 * different from zero. That means, we have to include the row in the corresponding
    8541 * column vectors.
    8542 */
    8543 SCIP_CALL( rowLink(row, blkmem, set, eventqueue, lp) );
    8544
    8545 SCIProwCapture(row);
    8546 lp->lpirows[r] = row;
    8547 row->lpipos = r;
    8548 row->dualsol = SCIP_INVALID;
    8549 row->activity = SCIP_INVALID;
    8550 row->dualfarkas = SCIP_INVALID;
    8551 row->validactivitylp = -1;
    8552 row->lhschanged = FALSE;
    8553 row->rhschanged = FALSE;
    8554 row->coefchanged = FALSE;
    8555 if( SCIPsetIsInfinity(set, -row->lhs) )
    8556 lhs[pos] = -lpiinf;
    8557 else
    8558 lhs[pos] = row->lhs - row->constant;
    8559 if( SCIPsetIsInfinity(set, row->rhs) )
    8560 rhs[pos] = lpiinf;
    8561 else
    8562 rhs[pos] = row->rhs - row->constant;
    8563 beg[pos] = nnonz;
    8564 name[pos] = row->name;
    8565
    8566 row->flushedlhs = lhs[pos];
    8567 row->flushedrhs = rhs[pos];
    8568
    8569 SCIPsetDebugMsg(set, "flushing added row (SCIP_LPI): %+g <=", lhs[pos]);
    8570 for( i = 0; i < row->nlpcols; ++i )
    8571 {
    8572 assert(row->cols[i] != NULL);
    8573 lpipos = row->cols[i]->lpipos;
    8574 if( lpipos >= 0 )
    8575 {
    8576 assert(lpipos < lp->ncols);
    8577 assert(nnonz < naddcoefs);
    8578 SCIPsetDebugMsgPrint(set, " %+gx%d(<%s>)", row->vals[i], lpipos+1, SCIPvarGetName(row->cols[i]->var));
    8579 ind[nnonz] = lpipos;
    8580 val[nnonz] = row->vals[i];
    8581 nnonz++;
    8582 }
    8583 }
    8584 SCIPsetDebugMsgPrint(set, " <= %+g\n", rhs[pos]);
    8585#ifndef NDEBUG
    8586 for( i = row->nlpcols; i < row->len; ++i )
    8587 {
    8588 assert(row->cols[i] != NULL);
    8589 assert(row->cols[i]->lpipos == -1); /* because the column deletions are already performed */
    8590 }
    8591#endif
    8592 }
    8593
    8594 /* call LP interface */
    8595 SCIPsetDebugMsg(set, "flushing row additions: enlarge LP from %d to %d rows\n", lp->nlpirows, lp->nrows);
    8596 SCIP_CALL( SCIPlpiAddRows(lp->lpi, naddrows, lhs, rhs, name, nnonz, beg, ind, val) );
    8597 lp->nlpirows = lp->nrows;
    8598 lp->lpifirstchgrow = lp->nlpirows;
    8599
    8600 /* free temporary memory */
    8607
    8608 lp->flushaddedrows = TRUE;
    8609
    8610 /* mark the LP unsolved */
    8611 lp->solved = FALSE;
    8612 lp->primalfeasible = FALSE;
    8613 lp->primalchecked = FALSE;
    8614 lp->lpobjval = SCIP_INVALID;
    8616
    8617 return SCIP_OKAY;
    8618}
    8619
    8620/** applies all cached column bound and objective changes to the LP */
    8621static
    8623 SCIP_LP* lp, /**< current LP data */
    8624 SCIP_SET* set /**< global SCIP settings */
    8625 )
    8626{
    8627#ifndef NDEBUG
    8628 SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
    8629#endif
    8630 SCIP_COL* col;
    8631 int* objind;
    8632 int* bdind;
    8633 SCIP_Real* obj;
    8634 SCIP_Real* lb;
    8635 SCIP_Real* ub;
    8636 SCIP_Real lpiinf;
    8637 int nobjchg;
    8638 int nbdchg;
    8639 int i;
    8640
    8641 assert(lp != NULL);
    8642
    8643 if( lp->nchgcols == 0 )
    8644 return SCIP_OKAY;
    8645
    8646 /* get the solver's infinity value */
    8647 lpiinf = SCIPlpiInfinity(lp->lpi);
    8648
    8649 /* get temporary memory for changes */
    8650 SCIP_CALL( SCIPsetAllocBufferArray(set, &objind, lp->ncols) );
    8652 SCIP_CALL( SCIPsetAllocBufferArray(set, &bdind, lp->ncols) );
    8655
    8656 /* collect all cached bound and objective changes */
    8657 nobjchg = 0;
    8658 nbdchg = 0;
    8659 for( i = 0; i < lp->nchgcols; ++i )
    8660 {
    8661 col = lp->chgcols[i];
    8662 assert(col != NULL);
    8663 assert(col->var != NULL);
    8665 assert(SCIPvarGetCol(col->var) == col);
    8666
    8667 if( col->lpipos >= 0 )
    8668 {
    8669#ifndef NDEBUG
    8670 /* do not check consistency of data with LPI in case of LPI=none */
    8671 if( !lpinone )
    8672 {
    8673 SCIP_Real lpiobj;
    8674 SCIP_Real lpilb;
    8675 SCIP_Real lpiub;
    8676
    8677 SCIP_CALL( SCIPlpiGetObj(lp->lpi, col->lpipos, col->lpipos, &lpiobj) );
    8678 SCIP_CALL( SCIPlpiGetBounds(lp->lpi, col->lpipos, col->lpipos, &lpilb, &lpiub) );
    8679 assert(SCIPsetIsFeasEQ(set, lpiobj, col->flushedobj));
    8680 assert((SCIPsetIsInfinity(set, -lpilb) && SCIPsetIsInfinity(set, -col->flushedlb))
    8681 || (!SCIPsetIsInfinity(set, -lpilb) && !SCIPsetIsInfinity(set, -col->flushedlb) && SCIPsetIsFeasEQ(set, lpilb, col->flushedlb)));
    8682 assert((SCIPsetIsInfinity(set, lpiub) && SCIPsetIsInfinity(set, col->flushedub))
    8683 || (!SCIPsetIsInfinity(set, lpiub) && !SCIPsetIsInfinity(set, col->flushedub) && SCIPsetIsFeasEQ(set, lpiub, col->flushedub)));
    8684 }
    8685#endif
    8686
    8687 if( col->objchanged )
    8688 {
    8689 SCIP_Real newobj;
    8690
    8691 newobj = col->obj;
    8692 if( col->flushedobj != newobj ) /*lint !e777*/
    8693 {
    8694 assert(nobjchg < lp->ncols);
    8695 objind[nobjchg] = col->lpipos;
    8696 obj[nobjchg] = newobj;
    8697 nobjchg++;
    8698 col->flushedobj = newobj;
    8699 }
    8700 col->objchanged = FALSE;
    8701 }
    8702
    8703 if( col->lbchanged || col->ubchanged )
    8704 {
    8705 SCIP_Real newlb;
    8706 SCIP_Real newub;
    8707
    8708 /* compute bounds that should be flushed into the LP (taking into account lazy bounds) */
    8709 computeLPBounds(lp, set, col, lpiinf, &newlb, &newub);
    8710
    8711 if( col->flushedlb != newlb || col->flushedub != newub ) /*lint !e777*/
    8712 {
    8713 assert(nbdchg < lp->ncols);
    8714 bdind[nbdchg] = col->lpipos;
    8715 lb[nbdchg] = newlb;
    8716 ub[nbdchg] = newub;
    8717 nbdchg++;
    8718 col->flushedlb = newlb;
    8719 col->flushedub = newub;
    8720 }
    8721 col->lbchanged = FALSE;
    8722 col->ubchanged = FALSE;
    8723 }
    8724 }
    8725 /* maybe lb/ub/objchanged should all be set to false when lpipos is -1 */
    8726 }
    8727
    8728 /* change objective values in LP */
    8729 if( nobjchg > 0 )
    8730 {
    8731 SCIPsetDebugMsg(set, "flushing objective changes: change %d objective values of %d changed columns\n", nobjchg, lp->nchgcols);
    8732 SCIP_CALL( SCIPlpiChgObj(lp->lpi, nobjchg, objind, obj) );
    8733
    8734 /* mark the LP unsolved */
    8735 lp->solved = FALSE;
    8736 lp->dualfeasible = FALSE;
    8737 lp->dualchecked = FALSE;
    8738 lp->lpobjval = SCIP_INVALID;
    8740 }
    8741
    8742 /* change bounds in LP */
    8743 if( nbdchg > 0 )
    8744 {
    8745 SCIPsetDebugMsg(set, "flushing bound changes: change %d bounds of %d changed columns\n", nbdchg, lp->nchgcols);
    8746 SCIP_CALL( SCIPlpiChgBounds(lp->lpi, nbdchg, bdind, lb, ub) );
    8747
    8748 /* mark the LP unsolved */
    8749 lp->solved = FALSE;
    8750 lp->primalfeasible = FALSE;
    8751 lp->primalchecked = FALSE;
    8752 lp->lpobjval = SCIP_INVALID;
    8754 }
    8755
    8756 lp->nchgcols = 0;
    8757
    8758 /* free temporary memory */
    8761 SCIPsetFreeBufferArray(set, &bdind);
    8763 SCIPsetFreeBufferArray(set, &objind);
    8764
    8765 return SCIP_OKAY;
    8766}
    8767
    8768/** applies all cached row side changes to the LP */
    8769static
    8771 SCIP_LP* lp, /**< current LP data */
    8772 SCIP_SET* set /**< global SCIP settings */
    8773 )
    8774{
    8775#ifndef NDEBUG
    8776 SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
    8777#endif
    8778 SCIP_ROW* row;
    8779 int* ind;
    8780 SCIP_Real* lhs;
    8781 SCIP_Real* rhs;
    8782 SCIP_Real lpiinf;
    8783 int i;
    8784 int nchg;
    8785
    8786 assert(lp != NULL);
    8787
    8788 if( lp->nchgrows == 0 )
    8789 return SCIP_OKAY;
    8790
    8791 /* get the solver's infinity value */
    8792 lpiinf = SCIPlpiInfinity(lp->lpi);
    8793
    8794 /* get temporary memory for changes */
    8798
    8799 /* collect all cached left and right hand side changes */
    8800 nchg = 0;
    8801 for( i = 0; i < lp->nchgrows; ++i )
    8802 {
    8803 row = lp->chgrows[i];
    8804 assert(row != NULL);
    8805
    8806 if( row->lpipos >= 0 )
    8807 {
    8808#ifndef NDEBUG
    8809 /* do not check consistency of data with LPI in case of LPI=none */
    8810 if( !lpinone )
    8811 {
    8812 SCIP_Real lpilhs;
    8813 SCIP_Real lpirhs;
    8814
    8815 SCIP_CALL( SCIPlpiGetSides(lp->lpi, row->lpipos, row->lpipos, &lpilhs, &lpirhs) );
    8816 assert(SCIPsetIsSumEQ(set, lpilhs, row->flushedlhs));
    8817 assert(SCIPsetIsSumEQ(set, lpirhs, row->flushedrhs));
    8818 }
    8819#endif
    8820 if( row->lhschanged || row->rhschanged )
    8821 {
    8822 SCIP_Real newlhs;
    8823 SCIP_Real newrhs;
    8824
    8825 newlhs = (SCIPsetIsInfinity(set, -row->lhs) ? -lpiinf : row->lhs - row->constant);
    8826 newrhs = (SCIPsetIsInfinity(set, row->rhs) ? lpiinf : row->rhs - row->constant);
    8827 if( row->flushedlhs != newlhs || row->flushedrhs != newrhs ) /*lint !e777*/
    8828 {
    8829 assert(nchg < lp->nrows);
    8830 ind[nchg] = row->lpipos;
    8831 lhs[nchg] = newlhs;
    8832 rhs[nchg] = newrhs;
    8833 nchg++;
    8834 row->flushedlhs = newlhs;
    8835 row->flushedrhs = newrhs;
    8836 }
    8837 row->lhschanged = FALSE;
    8838 row->rhschanged = FALSE;
    8839 }
    8840 }
    8841 }
    8842
    8843 /* change left and right hand sides in LP */
    8844 if( nchg > 0 )
    8845 {
    8846 SCIPsetDebugMsg(set, "flushing side changes: change %d sides of %d rows\n", nchg, lp->nchgrows);
    8847 SCIP_CALL( SCIPlpiChgSides(lp->lpi, nchg, ind, lhs, rhs) );
    8848
    8849 /* mark the LP unsolved */
    8850 lp->solved = FALSE;
    8851 lp->primalfeasible = FALSE;
    8852 lp->primalchecked = FALSE;
    8853 lp->lpobjval = SCIP_INVALID;
    8855 }
    8856
    8857 lp->nchgrows = 0;
    8858
    8859 /* free temporary memory */
    8863
    8864 return SCIP_OKAY;
    8865}
    8866
    8867/** copy integrality information to the LP */
    8868static
    8870 SCIP_LP* lp, /**< current LP data */
    8871 SCIP_SET* set /**< global SCIP settings */
    8872 )
    8873{
    8874 int i;
    8875 int nintegers;
    8876 int* integerInfo;
    8877 SCIP_VAR* var;
    8878
    8879 assert(lp != NULL);
    8880
    8881 SCIP_CALL( SCIPsetAllocBufferArray(set, &integerInfo, lp->ncols) );
    8882
    8883 /* count total number of integralities */
    8884 nintegers = 0;
    8885
    8886 for( i = 0; i < lp->ncols; ++i )
    8887 {
    8888 var = SCIPcolGetVar(lp->cols[i]);
    8889 if( SCIPvarIsIntegral(var) || SCIPvarIsBinary(var) )
    8890 {
    8891 integerInfo[i] = 1;
    8892 ++nintegers;
    8893 }
    8894 else
    8895 integerInfo[i] = 0;
    8896 }
    8897
    8898 /* only pass integrality information if integer variables are present */
    8899 if( nintegers > 0 )
    8900 {
    8901 SCIP_CALL( SCIPlpiSetIntegralityInformation(lp->lpi, lp->ncols, integerInfo) );
    8902 }
    8903 else
    8904 {
    8906 }
    8907
    8908 SCIPsetFreeBufferArray(set, &integerInfo);
    8909
    8910 /* mark integralities to be updated */
    8912
    8913 return SCIP_OKAY;
    8914}
    8915
    8916/** applies all cached changes to the LP solver */
    8918 SCIP_LP* lp, /**< current LP data */
    8919 BMS_BLKMEM* blkmem, /**< block memory */
    8920 SCIP_SET* set, /**< global SCIP settings */
    8921 SCIP_PROB* prob, /**< problem data */
    8922 SCIP_EVENTQUEUE* eventqueue /**< event queue */
    8923 )
    8924{
    8925 assert(lp != NULL);
    8926 assert(blkmem != NULL);
    8927
    8928 SCIPsetDebugMsg(set, "flushing LP changes: old (%d cols, %d rows), nchgcols=%d, nchgrows=%d, firstchgcol=%d, firstchgrow=%d, new (%d cols, %d rows), flushed=%u\n",
    8929 lp->nlpicols, lp->nlpirows, lp->nchgcols, lp->nchgrows, lp->lpifirstchgcol, lp->lpifirstchgrow, lp->ncols, lp->nrows, lp->flushed);
    8930
    8931 if( !lp->flushed )
    8932 {
    8933 lp->flushdeletedcols = FALSE;
    8934 lp->flushaddedcols = FALSE;
    8935 lp->flushdeletedrows = FALSE;
    8936 lp->flushaddedrows = FALSE;
    8937
    8939 SCIP_CALL( lpFlushDelRows(lp, blkmem, set) );
    8942 SCIP_CALL( lpFlushAddCols(lp, blkmem, set, eventqueue) );
    8943 SCIP_CALL( lpFlushAddRows(lp, blkmem, set, eventqueue) );
    8944
    8945 lp->flushed = TRUE;
    8946
    8947 checkLinks(lp);
    8948 }
    8949
    8950 /* if the cutoff bound was changed in between and it is not disabled (e.g. for column generation),
    8951 * we want to re-optimize the LP even if nothing else has changed
    8952 */
    8953 if( !lpCutoffDisabled(set, prob, lp) && lp->cutoffbound != lp->lpiobjlim && lp->ncols > 0 ) /*lint !e777*/
    8954 {
    8955 lp->solved = FALSE;
    8957 }
    8958
    8959 assert(lp->nlpicols == lp->ncols);
    8960 assert(lp->lpifirstchgcol == lp->nlpicols);
    8961 assert(lp->nlpirows == lp->nrows);
    8962 assert(lp->lpifirstchgrow == lp->nlpirows);
    8963 assert(lp->nchgcols == 0);
    8964 assert(lp->nchgrows == 0);
    8965#ifndef NDEBUG
    8966 {
    8967 int ncols;
    8968 int nrows;
    8969
    8970 SCIP_CALL( SCIPlpiGetNCols(lp->lpi, &ncols) );
    8971 SCIP_CALL( SCIPlpiGetNRows(lp->lpi, &nrows) );
    8972 assert(ncols == lp->ncols);
    8973 assert(nrows == lp->nrows);
    8974 }
    8975#endif
    8976
    8977 return SCIP_OKAY;
    8978}
    8979
    8980/** marks the LP to be flushed, even if the LP thinks it is not flushed */
    8982 SCIP_LP* lp, /**< current LP data */
    8983 SCIP_SET* set /**< global SCIP settings */
    8984 )
    8985{
    8986#ifndef NDEBUG
    8987 SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
    8988#endif
    8989 int i;
    8990
    8991 assert(lp != NULL);
    8992
    8993#ifndef NDEBUG
    8994 /* check, if there are really no column or row deletions or coefficient changes left */
    8995 while( lp->lpifirstchgcol < lp->nlpicols
    8996 && lp->lpifirstchgcol < lp->ncols
    8997 && lp->cols[lp->lpifirstchgcol]->lpipos == lp->lpifirstchgcol
    8998 && !lp->cols[lp->lpifirstchgcol]->coefchanged )
    8999 {
    9000 assert(lp->cols[lp->lpifirstchgcol] == lp->lpicols[lp->lpifirstchgcol]);
    9001 lp->lpifirstchgcol++;
    9002 }
    9003 assert(lp->nlpicols == lp->lpifirstchgcol);
    9004
    9005 while( lp->lpifirstchgrow < lp->nlpirows
    9006 && lp->lpifirstchgrow < lp->nrows
    9007 && lp->rows[lp->lpifirstchgrow]->lpipos == lp->lpifirstchgrow
    9008 && !lp->rows[lp->lpifirstchgrow]->coefchanged )
    9009 {
    9010 assert(lp->rows[lp->lpifirstchgrow] == lp->lpirows[lp->lpifirstchgrow]);
    9011 lp->lpifirstchgrow++;
    9012 }
    9013 assert(lp->nlpirows == lp->lpifirstchgrow);
    9014#endif
    9015
    9016 lp->lpifirstchgcol = lp->nlpicols;
    9017 lp->lpifirstchgrow = lp->nlpirows;
    9018
    9019 /* check, if there are really no column or row additions left */
    9020 assert(lp->ncols == lp->nlpicols);
    9021 assert(lp->nrows == lp->nlpirows);
    9022
    9023 /* mark the changed columns to be unchanged, and check, if this is really correct */
    9024 for( i = 0; i < lp->nchgcols; ++i )
    9025 {
    9026 SCIP_COL* col;
    9027
    9028 col = lp->chgcols[i];
    9029 assert(col != NULL);
    9030 assert(col->var != NULL);
    9032 assert(SCIPvarGetCol(col->var) == col);
    9033
    9034 if( col->lpipos >= 0 )
    9035 {
    9036#ifndef NDEBUG
    9037 /* do not check consistency of data with LPI in case of LPI=none */
    9038 if( !lpinone )
    9039 {
    9040 SCIP_Real lpiobj;
    9041 SCIP_Real lpilb;
    9042 SCIP_Real lpiub;
    9043
    9044 SCIP_CALL( SCIPlpiGetObj(lp->lpi, col->lpipos, col->lpipos, &lpiobj) );
    9045 SCIP_CALL( SCIPlpiGetBounds(lp->lpi, col->lpipos, col->lpipos, &lpilb, &lpiub) );
    9046 assert(SCIPsetIsSumEQ(set, lpiobj, col->flushedobj));
    9047 assert(SCIPsetIsSumEQ(set, lpilb, col->flushedlb));
    9048 assert(SCIPsetIsSumEQ(set, lpiub, col->flushedub));
    9049 assert(col->flushedobj == col->obj); /*lint !e777*/
    9050 assert(col->flushedlb == (SCIPsetIsInfinity(set, -col->lb) ? -SCIPlpiInfinity(lp->lpi) : col->lb)); /*lint !e777*/
    9051 assert(col->flushedub == (SCIPsetIsInfinity(set, col->ub) ? SCIPlpiInfinity(lp->lpi) : col->ub)); /*lint !e777*/
    9052 }
    9053#endif
    9054 col->objchanged = FALSE;
    9055 col->lbchanged = FALSE;
    9056 col->ubchanged = FALSE;
    9057 }
    9058 /* maybe lb/ub/objchanged should be set to false also when lpipos is -1 */
    9059 }
    9060 lp->nchgcols = 0;
    9061
    9062 /* mark the changed rows to be unchanged, and check, if this is really correct */
    9063 for( i = 0; i < lp->nchgrows; ++i )
    9064 {
    9065 SCIP_ROW* row;
    9066
    9067 row = lp->chgrows[i];
    9068 assert(row != NULL);
    9069
    9070 if( row->lpipos >= 0 )
    9071 {
    9072#ifndef NDEBUG
    9073 /* do not check consistency of data with LPI in case of LPI=none */
    9074 if( !lpinone )
    9075 {
    9076 SCIP_Real lpilhs;
    9077 SCIP_Real lpirhs;
    9078
    9079 SCIP_CALL( SCIPlpiGetSides(lp->lpi, row->lpipos, row->lpipos, &lpilhs, &lpirhs) );
    9080 assert(SCIPsetIsSumEQ(set, lpilhs, row->flushedlhs));
    9081 assert(SCIPsetIsSumEQ(set, lpirhs, row->flushedrhs));
    9082 assert(row->flushedlhs == (SCIPsetIsInfinity(set, -row->lhs) ? -SCIPlpiInfinity(lp->lpi) : row->lhs - row->constant)); /*lint !e777*/
    9083 assert(row->flushedrhs == (SCIPsetIsInfinity(set, row->rhs) ? SCIPlpiInfinity(lp->lpi) : row->rhs - row->constant)); /*lint !e777*/
    9084 }
    9085#endif
    9086 row->lhschanged = FALSE;
    9087 row->rhschanged = FALSE;
    9088 }
    9089 }
    9090 lp->nchgrows = 0;
    9091
    9092 /* mark the LP to be flushed */
    9093 lp->flushed = TRUE;
    9094
    9095 checkLinks(lp);
    9096
    9097 return SCIP_OKAY;
    9098}
    9099
    9100
    9101
    9102
    9103/*
    9104 * LP methods
    9105 */
    9106
    9107/** updates link data after addition of column */
    9108static
    9110 SCIP_COL* col, /**< LP column */
    9111 SCIP_SET* set /**< global SCIP settings */
    9112 )
    9113{
    9114 SCIP_ROW* row;
    9115 int i;
    9116 int pos;
    9117
    9118 assert(col != NULL);
    9119 assert(col->lppos >= 0);
    9120
    9121 /* update column arrays of all linked rows */
    9122 for( i = 0; i < col->len; ++i )
    9123 {
    9124 pos = col->linkpos[i];
    9125 if( pos >= 0 )
    9126 {
    9127 row = col->rows[i];
    9128 assert(row != NULL);
    9129 assert(row->linkpos[pos] == i);
    9130 assert(row->cols[pos] == col);
    9131 assert(row->nlpcols <= pos && pos < row->len);
    9132
    9133 row->nlpcols++;
    9134 rowSwapCoefs(row, pos, row->nlpcols-1);
    9135 assert(row->cols[row->nlpcols-1] == col);
    9136
    9137 /* if no swap was necessary, mark lpcols to be unsorted */
    9138 if( pos == row->nlpcols-1 )
    9139 row->lpcolssorted = FALSE;
    9140
    9141 /* update norms */
    9142 rowAddNorms(row, set, col, row->vals[row->nlpcols-1], FALSE);
    9143 }
    9144 }
    9145}
    9146
    9147/** updates link data after addition of row */
    9148static
    9150 SCIP_ROW* row /**< LP row */
    9151 )
    9152{
    9153 SCIP_COL* col;
    9154 int i;
    9155 int pos;
    9156
    9157 assert(row != NULL);
    9158 assert(row->lppos >= 0);
    9159
    9160 /* update row arrays of all linked columns */
    9161 for( i = 0; i < row->len; ++i )
    9162 {
    9163 pos = row->linkpos[i];
    9164 if( pos >= 0 )
    9165 {
    9166 col = row->cols[i];
    9167 assert(col != NULL);
    9168 assert(col->linkpos[pos] == i);
    9169 assert(col->rows[pos] == row);
    9170 assert(col->nlprows <= pos && pos < col->len);
    9171
    9172 col->nlprows++;
    9173 colSwapCoefs(col, pos, col->nlprows-1);
    9174
    9175 /* if no swap was necessary, mark lprows to be unsorted */
    9176 if( pos == col->nlprows-1 )
    9177 col->lprowssorted = FALSE;
    9178 }
    9179 }
    9180}
    9181
    9182/** updates link data after removal of column */
    9183static
    9185 SCIP_COL* col, /**< LP column */
    9186 SCIP_SET* set /**< global SCIP settings */
    9187 )
    9188{
    9189 SCIP_ROW* row;
    9190 int i;
    9191 int pos;
    9192
    9193 assert(col != NULL);
    9194 assert(col->lppos == -1);
    9195
    9196 /* update column arrays of all linked rows */
    9197 for( i = 0; i < col->len; ++i )
    9198 {
    9199 pos = col->linkpos[i];
    9200 if( pos >= 0 )
    9201 {
    9202 row = col->rows[i];
    9203 assert(row != NULL);
    9204 assert(row->linkpos[pos] == i);
    9205 assert(row->cols[pos] == col);
    9206 assert(0 <= pos && pos < row->nlpcols);
    9207
    9208 /* update norms */
    9209 rowDelNorms(row, set, col, row->vals[pos], TRUE, FALSE, FALSE);
    9210
    9211 row->nlpcols--;
    9212 rowSwapCoefs(row, pos, row->nlpcols);
    9213
    9214 /* if no swap was necessary, mark nonlpcols to be unsorted */
    9215 if( pos == row->nlpcols )
    9216 row->nonlpcolssorted = FALSE;
    9217 }
    9218 }
    9219}
    9220
    9221/** updates link data after removal of row */
    9222static
    9224 SCIP_ROW* row /**< LP row */
    9225 )
    9226{
    9227 SCIP_COL* col;
    9228 int i;
    9229 int pos;
    9230
    9231 assert(row != NULL);
    9232 assert(row->lppos == -1);
    9233
    9234 /* update row arrays of all linked columns */
    9235 for( i = 0; i < row->len; ++i )
    9236 {
    9237 pos = row->linkpos[i];
    9238 if( pos >= 0 )
    9239 {
    9240 col = row->cols[i];
    9241 assert(col != NULL);
    9242 assert(0 <= pos && pos < col->nlprows);
    9243 assert(col->linkpos[pos] == i);
    9244 assert(col->rows[pos] == row);
    9245
    9246 col->nlprows--;
    9247 colSwapCoefs(col, pos, col->nlprows);
    9248
    9249 /* if no swap was necessary, mark lprows to be unsorted */
    9250 if( pos == col->nlprows )
    9251 col->nonlprowssorted = FALSE;
    9252 }
    9253 }
    9254}
    9255
    9256static
    9258 SCIP_LP* lp, /**< LP data object */
    9259 int initsize /**< initial size of the arrays */
    9260 )
    9261{
    9262 assert(lp != NULL);
    9263 assert(lp->divechgsides == NULL);
    9264 assert(lp->divechgsidetypes == NULL);
    9265 assert(lp->divechgrows == NULL);
    9266 assert(lp->ndivechgsides == 0);
    9267 assert(lp->divechgsidessize == 0);
    9268 assert(initsize > 0);
    9269
    9270 lp->divechgsidessize = initsize;
    9274
    9275 return SCIP_OKAY;
    9276}
    9277
    9278static
    9280 SCIP_LP* lp, /**< LP data object */
    9281 int minsize, /**< minimal number of elements */
    9282 SCIP_Real growfact /**< growing factor */
    9283 )
    9284{
    9285 assert(lp != NULL);
    9286 assert(lp->divechgsides != NULL);
    9287 assert(lp->divechgsidetypes != NULL);
    9288 assert(lp->divechgrows != NULL);
    9289 assert(lp->ndivechgsides > 0);
    9290 assert(lp->divechgsidessize > 0);
    9291 assert(minsize > 0);
    9292
    9293 if( minsize <= lp->divechgsidessize )
    9294 return SCIP_OKAY;
    9295
    9296 lp->divechgsidessize = MAX(minsize, (int)(lp->divechgsidessize * growfact));
    9300
    9301 return SCIP_OKAY;
    9302}
    9303
    9304static
    9306 SCIP_LP* lp /**< LP data object */
    9307 )
    9308{
    9309 assert(lp != NULL);
    9310 assert(lp->divechgsides != NULL);
    9311 assert(lp->divechgsidetypes != NULL);
    9312 assert(lp->divechgrows != NULL);
    9313 assert(lp->ndivechgsides == 0);
    9314 assert(lp->divechgsidessize > 0);
    9315
    9319 lp->divechgsidessize = 0;
    9320}
    9321
    9322#define DIVESTACKINITSIZE 100
    9323
    9324/** creates empty LP data object */
    9326 SCIP_LP** lp, /**< pointer to LP data object */
    9327 SCIP_SET* set, /**< global SCIP settings */
    9328 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    9329 SCIP_STAT* stat, /**< problem statistics */
    9330 const char* name /**< problem name */
    9331 )
    9332{
    9333 SCIP_Bool success;
    9334
    9335 assert(lp != NULL);
    9336 assert(set != NULL);
    9337 assert(stat != NULL);
    9338 assert(name != NULL);
    9339
    9341
    9342 /* open LP Solver interface */
    9343 SCIP_CALL( SCIPlpiCreate(&(*lp)->lpi, messagehdlr, name, SCIP_OBJSEN_MINIMIZE) );
    9344
    9345 (*lp)->lpicols = NULL;
    9346 (*lp)->lpirows = NULL;
    9347 (*lp)->chgcols = NULL;
    9348 (*lp)->chgrows = NULL;
    9349 (*lp)->cols = NULL;
    9350 (*lp)->soldirection = NULL;
    9351 (*lp)->lazycols = NULL;
    9352 (*lp)->rows = NULL;
    9353 (*lp)->lpobjval = 0.0;
    9354 (*lp)->glbpseudoobjval = 0.0;
    9355 (*lp)->relglbpseudoobjval = 0.0;
    9356 (*lp)->glbpseudoobjvalid = TRUE;
    9357 (*lp)->glbpseudoobjvalinf = 0;
    9358 (*lp)->pseudoobjval = 0.0;
    9359 (*lp)->relpseudoobjval = 0.0;
    9360 (*lp)->pseudoobjvalid = TRUE;
    9361 (*lp)->pseudoobjvalinf = 0;
    9362 (*lp)->looseobjval = 0.0;
    9363 (*lp)->rellooseobjval = 0.0;
    9364 (*lp)->looseobjvalid = TRUE;
    9365 (*lp)->looseobjvalinf = 0;
    9366 (*lp)->nloosevars = 0;
    9367 (*lp)->rootlpobjval = SCIP_INVALID;
    9368 (*lp)->rootlooseobjval = SCIP_INVALID;
    9369 (*lp)->cutoffbound = SCIPsetInfinity(set);
    9370 (*lp)->feastol = SCIP_INVALID; /* to have it initialized */
    9371 SCIPlpResetFeastol(*lp, set);
    9372 (*lp)->validdegeneracylp = -1;
    9373 (*lp)->objsqrnorm = 0.0;
    9374 (*lp)->objsumnorm = 0.0;
    9375 (*lp)->lpicolssize = 0;
    9376 (*lp)->nlpicols = 0;
    9377 (*lp)->lpirowssize = 0;
    9378 (*lp)->nlpirows = 0;
    9379 (*lp)->lpifirstchgcol = 0;
    9380 (*lp)->lpifirstchgrow = 0;
    9381 (*lp)->colssize = 0;
    9382 (*lp)->soldirectionsize = 0;
    9383 (*lp)->ncols = 0;
    9384 (*lp)->lazycolssize = 0;
    9385 (*lp)->nlazycols = 0;
    9386 (*lp)->rowssize = 0;
    9387 (*lp)->nrows = 0;
    9388 (*lp)->chgcolssize = 0;
    9389 (*lp)->nchgcols = 0;
    9390 (*lp)->chgrowssize = 0;
    9391 (*lp)->nchgrows = 0;
    9392 (*lp)->firstnewcol = 0;
    9393 (*lp)->firstnewrow = 0;
    9394 (*lp)->nremovablecols = 0;
    9395 (*lp)->nremovablerows = 0;
    9396 (*lp)->validsollp = stat->lpcount; /* the initial (empty) SCIP_LP is solved with primal and dual solution of zero */
    9397 (*lp)->validfarkaslp = -1;
    9398 (*lp)->validsoldirlp = -1;
    9399 (*lp)->validsoldirsol = NULL;
    9400 (*lp)->objsqrnormunreliable = FALSE;
    9401 (*lp)->flushdeletedcols = FALSE;
    9402 (*lp)->flushaddedcols = FALSE;
    9403 (*lp)->flushdeletedrows = FALSE;
    9404 (*lp)->flushaddedrows = FALSE;
    9405 (*lp)->updateintegrality = TRUE;
    9406 (*lp)->flushed = TRUE;
    9407 (*lp)->lpsolstat = SCIP_LPSOLSTAT_OPTIMAL;
    9408 (*lp)->solved = TRUE;
    9409 (*lp)->primalfeasible = TRUE;
    9410 (*lp)->primalchecked = TRUE;
    9411 (*lp)->dualfeasible = TRUE;
    9412 (*lp)->dualchecked = TRUE;
    9413 (*lp)->solisbasic = FALSE;
    9414 (*lp)->rootlpisrelax = TRUE;
    9415 (*lp)->isrelax = TRUE;
    9416 (*lp)->installing = FALSE;
    9417 (*lp)->strongbranching = FALSE;
    9418 (*lp)->strongbranchprobing = FALSE;
    9419 (*lp)->probing = FALSE;
    9420 (*lp)->diving = FALSE;
    9421 (*lp)->divingobjchg = FALSE;
    9422 (*lp)->divinglazyapplied = FALSE;
    9423 (*lp)->divelpistate = NULL;
    9424 (*lp)->divelpwasprimfeas = TRUE;
    9425 (*lp)->divelpwasprimchecked = TRUE;
    9426 (*lp)->divelpwasdualfeas = TRUE;
    9427 (*lp)->divelpwasdualchecked = TRUE;
    9428 (*lp)->hasprovedbound = FALSE;
    9429 (*lp)->divechgsides = NULL;
    9430 (*lp)->divechgsidetypes = NULL;
    9431 (*lp)->divechgrows = NULL;
    9432 (*lp)->ndivechgsides = 0;
    9433 (*lp)->divechgsidessize = 0;
    9434 (*lp)->ndivingrows = 0;
    9435 (*lp)->divinglpiitlim = INT_MAX;
    9436 (*lp)->resolvelperror = FALSE;
    9437 (*lp)->divenolddomchgs = 0;
    9438 (*lp)->adjustlpval = FALSE;
    9439 (*lp)->lpiobjlim = SCIPlpiInfinity((*lp)->lpi);
    9440 (*lp)->lpifeastol = (*lp)->feastol;
    9441 (*lp)->lpidualfeastol = SCIPsetDualfeastol(set);
    9442 (*lp)->lpibarrierconvtol = SCIPsetBarrierconvtol(set);
    9443 (*lp)->lpifromscratch = FALSE;
    9444 (*lp)->lpifastmip = set->lp_fastmip;
    9445 (*lp)->lpiscaling = set->lp_scaling;
    9446 (*lp)->lpipresolving = set->lp_presolving;
    9447 (*lp)->lpilpinfo = set->disp_lpinfo;
    9448 (*lp)->lpirowrepswitch = set->lp_rowrepswitch;
    9449 (*lp)->lpisolutionpolishing = (set->lp_solutionpolishing > 0);
    9450 (*lp)->lpirefactorinterval = set->lp_refactorinterval;
    9451 (*lp)->lpiconditionlimit = set->lp_conditionlimit;
    9452 (*lp)->lpimarkowitz = set->lp_markowitz;
    9453 (*lp)->lpiitlim = INT_MAX;
    9454 (*lp)->lpipricing = SCIP_PRICING_AUTO;
    9455 (*lp)->lastlpalgo = SCIP_LPALGO_DUALSIMPLEX;
    9456 (*lp)->lpithreads = set->lp_threads;
    9457 (*lp)->lpitiming = (int) set->time_clocktype;
    9458 (*lp)->lpirandomseed = set->random_randomseed;
    9459 (*lp)->storedsolvals = NULL;
    9460 (*lp)->lpexact = NULL;
    9461
    9462 /* allocate arrays for diving */
    9464
    9465 /* set default parameters in LP solver */
    9466 SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_OBJLIM, (*lp)->lpiobjlim, &success) );
    9467 if( !success )
    9468 {
    9469 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    9470 "LP Solver <%s>: objective limit cannot be set -- can lead to unnecessary simplex iterations\n",
    9472 }
    9473 SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_FEASTOL, (*lp)->lpifeastol, &success) );
    9474 (*lp)->lpihasfeastol = success;
    9475 if( !success )
    9476 {
    9477 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    9478 "LP Solver <%s>: primal feasibility tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
    9480 }
    9481 SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_DUALFEASTOL, (*lp)->lpidualfeastol, &success) );
    9482 (*lp)->lpihasdualfeastol = success;
    9483 if( !success )
    9484 {
    9485 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    9486 "LP Solver <%s>: dual feasibility tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
    9488 }
    9489 SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_BARRIERCONVTOL, (*lp)->lpibarrierconvtol, &success) );
    9490 (*lp)->lpihasbarrierconvtol = success;
    9491 if( !success )
    9492 {
    9493 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    9494 "LP Solver <%s>: barrier convergence tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
    9496 }
    9497 SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_FROMSCRATCH, (*lp)->lpifromscratch, &success) );
    9498 SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_FASTMIP, (*lp)->lpifastmip, &success) );
    9499 (*lp)->lpihasfastmip = success;
    9500 if( !success )
    9501 {
    9502 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    9503 "LP Solver <%s>: fastmip setting not available -- SCIP parameter has no effect\n",
    9505 }
    9506 SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_SCALING, (*lp)->lpiscaling, &success) );
    9507 (*lp)->lpihasscaling = success;
    9508 if( !success )
    9509 {
    9510 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    9511 "LP Solver <%s>: scaling not available -- SCIP parameter has no effect\n",
    9513 }
    9514 SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_PRESOLVING, (*lp)->lpipresolving, &success) );
    9515 (*lp)->lpihaspresolving = success;
    9516 if( !success )
    9517 {
    9518 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    9519 "LP Solver <%s>: presolving not available -- SCIP parameter has no effect\n",
    9521 }
    9522 SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_TIMING, (*lp)->lpitiming, &success) );
    9523 if( !success )
    9524 {
    9525 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    9526 "LP Solver <%s>: clock type cannot be set\n",
    9528 }
    9529 SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_LPITLIM, (*lp)->lpiitlim, &success) );
    9530 if( !success )
    9531 {
    9532 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    9533 "LP Solver <%s>: iteration limit cannot be set -- can lead to unnecessary simplex iterations\n",
    9535 }
    9536 SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_PRICING, (int)(*lp)->lpipricing, &success) );
    9537 if( !success )
    9538 {
    9539 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    9540 "LP Solver <%s>: pricing strategy cannot be set -- SCIP parameter has no effect\n",
    9542 }
    9543 SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_LPINFO, (*lp)->lpilpinfo, &success) );
    9544 if( !success )
    9545 {
    9546 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    9547 "LP Solver <%s>: lpinfo setting not available -- SCIP parameter has no effect\n",
    9549 }
    9550 SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_ROWREPSWITCH, (*lp)->lpirowrepswitch, &success) );
    9551 (*lp)->lpihasrowrep = success;
    9552 if( !success )
    9553 {
    9554 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    9555 "LP Solver <%s>: row representation of the basis not available -- SCIP parameter lp/rowrepswitch has no effect\n",
    9557 }
    9558 SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_POLISHING, ((*lp)->lpisolutionpolishing ? 1 : 0), &success) );
    9559 (*lp)->lpihaspolishing = success;
    9560 if( !success )
    9561 {
    9562 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    9563 "LP Solver <%s>: solution polishing not available -- SCIP parameter lp/solutionpolishing has no effect\n",
    9565 }
    9566 SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_REFACTOR, (*lp)->lpirefactorinterval, &success) );
    9567 (*lp)->lpihasrefactor = success;
    9568 if( !success )
    9569 {
    9570 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    9571 "LP Solver <%s>: refactorization interval not available -- SCIP parameter lp/refactorinterval has no effect\n",
    9573 }
    9574 SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_CONDITIONLIMIT, (*lp)->lpiconditionlimit, &success) );
    9575 if( !success )
    9576 {
    9577 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    9578 "LP Solver <%s>: condition number limit for the basis not available -- SCIP parameter lp/conditionlimit has no effect\n",
    9580 }
    9581 SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_MARKOWITZ, (*lp)->lpimarkowitz, &success) );
    9582 if( !success )
    9583 {
    9584 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    9585 "LP Solver <%s>: markowitz threshhold not available -- SCIP parameter lp/minmarkowitz has no effect\n",
    9587 }
    9588 SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_THREADS, (*lp)->lpithreads, &success) );
    9589 if( !success )
    9590 {
    9591 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    9592 "LP Solver <%s>: number of threads settings not available -- SCIP parameter has no effect\n",
    9594 }
    9595 /* keep the default LP random seed if this parameter is set to 0 (current default) */
    9596 if( (*lp)->lpirandomseed != 0 )
    9597 {
    9598 SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_RANDOMSEED, (*lp)->lpirandomseed, &success) );
    9599 if( !success )
    9600 {
    9601 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    9602 "LP Solver <%s>: random seed parameter not available -- SCIP parameter has no effect\n",
    9604 }
    9605 }
    9606
    9607 /* Check that infinity value of LP-solver is at least as large as the one used in SCIP. This is necessary, because we
    9608 * transfer SCIP infinity values to the ones by the LPI, but not the converse. */
    9609 if ( set->num_infinity > SCIPlpiInfinity((*lp)->lpi) )
    9610 {
    9611 SCIPerrorMessage("The infinity value of the LP solver has to be at least as large as the one of SCIP.\n");
    9613 }
    9614
    9615 return SCIP_OKAY;
    9616}
    9617
    9618/** frees LP data object */
    9620 SCIP_LP** lp, /**< pointer to LP data object */
    9621 BMS_BLKMEM* blkmem, /**< block memory */
    9622 SCIP_SET* set, /**< global SCIP settings */
    9623 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    9624 SCIP_EVENTFILTER* eventfilter /**< global event filter */
    9625 )
    9626{
    9627 int i;
    9628
    9629 assert(lp != NULL);
    9630 assert(*lp != NULL);
    9631
    9632 SCIP_CALL( SCIPlpClear(*lp, blkmem, set, eventqueue, eventfilter) );
    9633
    9635
    9636 /* release LPI rows */
    9637 for( i = 0; i < (*lp)->nlpirows; ++i )
    9638 {
    9639 SCIP_CALL( SCIProwRelease(&(*lp)->lpirows[i], blkmem, set, *lp) );
    9640 }
    9641
    9642 if( (*lp)->lpi != NULL )
    9643 {
    9644 SCIP_CALL( SCIPlpiFree(&(*lp)->lpi) );
    9645 }
    9646
    9647 BMSfreeMemoryNull(&(*lp)->storedsolvals);
    9648 BMSfreeMemoryArrayNull(&(*lp)->lpicols);
    9649 BMSfreeMemoryArrayNull(&(*lp)->lpirows);
    9650 BMSfreeMemoryArrayNull(&(*lp)->chgcols);
    9651 BMSfreeMemoryArrayNull(&(*lp)->chgrows);
    9652 BMSfreeMemoryArrayNull(&(*lp)->lazycols);
    9653 BMSfreeMemoryArrayNull(&(*lp)->cols);
    9654 BMSfreeMemoryArrayNull(&(*lp)->rows);
    9655 BMSfreeMemoryArrayNull(&(*lp)->soldirection);
    9656 BMSfreeMemory(lp);
    9657
    9658 return SCIP_OKAY;
    9659}
    9660
    9661/** resets the LP to the empty LP by removing all columns and rows from LP, releasing all rows, and flushing the
    9662 * changes to the LP solver
    9663 */
    9665 SCIP_LP* lp, /**< LP data */
    9666 BMS_BLKMEM* blkmem, /**< block memory */
    9667 SCIP_SET* set, /**< global SCIP settings */
    9668 SCIP_PROB* prob, /**< problem data */
    9669 SCIP_STAT* stat, /**< problem statistics */
    9670 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    9671 SCIP_EVENTFILTER* eventfilter /**< global event filter */
    9672 )
    9673{
    9674 assert(stat != NULL);
    9675
    9676 SCIP_CALL( SCIPlpClear(lp, blkmem, set, eventqueue, eventfilter) );
    9677 SCIP_CALL( SCIPlpFlush(lp, blkmem, set, prob, eventqueue) );
    9678
    9679 /* mark the empty LP to be solved */
    9681 lp->lpobjval = 0.0;
    9682 lp->validsollp = stat->lpcount; /* the initial (empty) SCIP_LP is solved with primal and dual solution of zero */
    9683 lp->validfarkaslp = -1;
    9684 lp->validdegeneracylp = -1;
    9685 lp->validsoldirlp = -1;
    9686 lp->validsoldirsol = NULL;
    9687 lp->solved = TRUE;
    9688 lp->primalfeasible = TRUE;
    9689 lp->primalchecked = TRUE;
    9690 lp->dualfeasible = TRUE;
    9691 lp->dualchecked = TRUE;
    9692 lp->solisbasic = FALSE;
    9694
    9695 return SCIP_OKAY;
    9696}
    9697
    9698/** adds a column to the LP */
    9700 SCIP_LP* lp, /**< LP data */
    9701 SCIP_SET* set, /**< global SCIP settings */
    9702 SCIP_COL* col, /**< LP column */
    9703 int depth /**< depth in the tree where the column addition is performed */
    9704 )
    9705{
    9706 assert(lp != NULL);
    9707 assert(!lp->diving);
    9708 assert(col != NULL);
    9709 assert(col->len == 0 || col->rows != NULL);
    9710 assert(col->lppos == -1);
    9711 assert(col->var != NULL);
    9713 assert(SCIPvarGetCol(col->var) == col);
    9714 assert(SCIPvarIsIntegral(col->var) == col->integral);
    9715 assert(SCIPvarIsImpliedIntegral(col->var) == col->impliedintegral);
    9716
    9717 SCIPsetDebugMsg(set, "adding column <%s> to LP (%d rows, %d cols)\n", SCIPvarGetName(col->var), lp->nrows, lp->ncols);
    9718#ifdef SCIP_DEBUG
    9719 {
    9720 int i;
    9721 SCIPsetDebugMsgPrint(set, " (obj: %g) [%g,%g]", col->obj, col->lb, col->ub);
    9722 for( i = 0; i < col->len; ++i )
    9723 SCIPsetDebugMsgPrint(set, " %+g<%s>", col->vals[i], col->rows[i]->name);
    9725 }
    9726#endif
    9727
    9728 SCIP_CALL( ensureColsSize(lp, set, lp->ncols+1) );
    9729 lp->cols[lp->ncols] = col;
    9730 col->lppos = lp->ncols;
    9731 col->lpdepth = depth;
    9732 col->age = 0;
    9733 lp->ncols++;
    9734 if( col->removable )
    9735 lp->nremovablecols++;
    9736
    9737 if( !SCIPsetIsInfinity(set, -col->lazylb) || !SCIPsetIsInfinity(set, col->lazyub) )
    9738 {
    9740 lp->lazycols[lp->nlazycols] = col;
    9741 lp->nlazycols++;
    9742 }
    9743
    9744 /* mark the current LP unflushed */
    9745 lp->flushed = FALSE;
    9746
    9747 /* update column arrays of all linked rows */
    9748 colUpdateAddLP(col, set);
    9749
    9750 /* update the objective function vector norms */
    9751 lpUpdateObjNorms(lp, set, 0.0, col->unchangedobj);
    9752
    9753 checkLinks(lp);
    9754
    9755 return SCIP_OKAY;
    9756}
    9757
    9758/** adds a row to the LP and captures it */
    9760 SCIP_LP* lp, /**< LP data */
    9761 BMS_BLKMEM* blkmem, /**< block memory buffers */
    9762 SCIP_SET* set, /**< global SCIP settings */
    9763 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    9764 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    9765 SCIP_ROW* row, /**< LP row */
    9766 int depth /**< depth in the tree where the row addition is performed */
    9767 )
    9768{
    9769 assert(lp != NULL);
    9770 assert(row != NULL);
    9771 assert(row->len == 0 || row->cols != NULL);
    9772 assert(row->lppos == -1);
    9773
    9774 SCIProwCapture(row);
    9775 SCIProwLock(row);
    9776
    9777 SCIPsetDebugMsg(set, "adding row <%s> to LP (%d rows, %d cols)\n", row->name, lp->nrows, lp->ncols);
    9778#ifdef SCIP_DEBUG
    9779 {
    9780 int i;
    9781 SCIPsetDebugMsgPrint(set, " %g <=", row->lhs);
    9782 for( i = 0; i < row->len; ++i )
    9783 SCIPsetDebugMsgPrint(set, " %+g<%s>", row->vals[i], SCIPvarGetName(row->cols[i]->var));
    9784 if( !SCIPsetIsZero(set, row->constant) )
    9785 SCIPsetDebugMsgPrint(set, " %+g", row->constant);
    9786 SCIPsetDebugMsgPrint(set, " <= %g\n", row->rhs);
    9787 }
    9788#endif
    9789
    9790 SCIP_CALL( ensureRowsSize(lp, set, lp->nrows+1) );
    9791 lp->rows[lp->nrows] = row;
    9792 row->lppos = lp->nrows;
    9793 row->lpdepth = depth;
    9794 row->age = 0;
    9795 lp->nrows++;
    9796 if( row->removable )
    9797 lp->nremovablerows++;
    9798
    9799 /* mark the current LP unflushed */
    9800 lp->flushed = FALSE;
    9801
    9802 /* update row arrays of all linked columns */
    9803 rowUpdateAddLP(row);
    9804
    9805 checkLinks(lp);
    9806
    9807 rowCalcNorms(row, set);
    9808
    9809 /* check, if row addition to LP events are tracked
    9810 * if so, issue ROWADDEDLP event
    9811 */
    9812 if( (eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWADDEDLP) != 0) )
    9813 {
    9814 SCIP_EVENT* event;
    9815
    9816 SCIP_CALL( SCIPeventCreateRowAddedLP(&event, blkmem, row) );
    9817 SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
    9818 }
    9819
    9820 return SCIP_OKAY;
    9821}
    9822
    9823
    9824#ifndef NDEBUG
    9825/** method checks if all columns in the lazycols array have at least one lazy bound and also have a counter part in the
    9826 * cols array; furthermore, it is checked if columns in the cols array which have a lazy bound have a counter part in
    9827 * the lazycols array
    9828 */
    9829static
    9831 SCIP_LP* lp, /**< LP data */
    9832 SCIP_SET* set /**< global SCIP settings */
    9833 )
    9834{
    9835 SCIP_Bool contained;
    9836 int c;
    9837 int i;
    9838
    9839 assert(lp != NULL);
    9840
    9841 /* check if each column in the lazy column array has a counter part in the column array */
    9842 for( i = 0; i < lp->nlazycols; ++i )
    9843 {
    9844 /* check if each lazy column has at least on lazy bound */
    9845 assert(lp->lazycols[i] != NULL);
    9846 assert(!SCIPsetIsInfinity(set, lp->lazycols[i]->lazyub) || !SCIPsetIsInfinity(set, -lp->lazycols[i]->lazylb));
    9847
    9848 contained = FALSE;
    9849 for( c = 0; c < lp->ncols; ++c )
    9850 {
    9851 if( lp->lazycols[i] == lp->cols[c] )
    9852 {
    9853 assert(!SCIPsetIsInfinity(set, lp->cols[c]->lazyub) || !SCIPsetIsInfinity(set, -lp->cols[c]->lazylb));
    9854 contained = TRUE;
    9855 }
    9856 }
    9857 assert(contained);
    9858 }
    9859
    9860 /* check if each column in the column array which has at least one lazy bound has a counter part in the lazy column *
    9861 * array */
    9862 for( c = 0; c < lp->ncols; ++c )
    9863 {
    9864 contained = FALSE;
    9865 assert(lp->cols[c] != NULL);
    9866
    9867 for( i = 0; i < lp->nlazycols; ++i )
    9868 {
    9869 if( lp->lazycols[i] == lp->cols[c] )
    9870 {
    9871 contained = TRUE;
    9872 }
    9873 }
    9874
    9875 assert(contained == (!SCIPsetIsInfinity(set, lp->cols[c]->lazyub) || !SCIPsetIsInfinity(set, -lp->cols[c]->lazylb)));
    9876 }
    9877}
    9878#else
    9879#define checkLazyColArray(lp, set) /**/
    9880#endif
    9881
    9882/** removes all columns after the given number of cols from the LP */
    9884 SCIP_LP* lp, /**< LP data */
    9885 SCIP_SET* set, /**< global SCIP settings */
    9886 int newncols /**< new number of columns in the LP */
    9887 )
    9888{
    9889 SCIP_COL* col;
    9890 int c;
    9891
    9892 assert(lp != NULL);
    9893
    9894 SCIPsetDebugMsg(set, "shrinking LP from %d to %d columns\n", lp->ncols, newncols);
    9895 assert(0 <= newncols);
    9896 assert(newncols <= lp->ncols);
    9897
    9898 if( newncols < lp->ncols )
    9899 {
    9900 assert(!lp->diving);
    9901
    9902 for( c = lp->ncols-1; c >= newncols; --c )
    9903 {
    9904 col = lp->cols[c];
    9905 assert(col != NULL);
    9906 assert(col->len == 0 || col->rows != NULL);
    9907 assert(col->var != NULL);
    9909 assert(SCIPvarGetCol(col->var) == lp->cols[c]);
    9910 assert(col->lppos == c);
    9911
    9912 /* mark column to be removed from the LP */
    9913 col->lppos = -1;
    9914 col->lpdepth = -1;
    9915 lp->ncols--;
    9916
    9917 /* count removable columns */
    9918 if( col->removable )
    9919 lp->nremovablecols--;
    9920
    9921 /* update column arrays of all linked rows */
    9922 colUpdateDelLP(col, set);
    9923
    9924 /* update the objective function vector norms */
    9925 lpUpdateObjNorms(lp, set, col->unchangedobj, 0.0);
    9926 }
    9927 assert(lp->ncols == newncols);
    9928 lp->lpifirstchgcol = MIN(lp->lpifirstchgcol, newncols);
    9929
    9930 /* remove columns which are deleted from the lazy column array */
    9931 c = 0;
    9932 while( c < lp->nlazycols )
    9933 {
    9934 if( lp->lazycols[c]->lppos < 0 )
    9935 {
    9936 lp->lazycols[c] = lp->lazycols[lp->nlazycols-1];
    9937 lp->nlazycols--;
    9938 }
    9939 else
    9940 c++;
    9941 }
    9942
    9943 /* mark the current LP unflushed */
    9944 lp->flushed = FALSE;
    9945
    9947 checkLinks(lp);
    9948 }
    9949 assert(lp->nremovablecols <= lp->ncols);
    9950
    9951 return SCIP_OKAY;
    9952}
    9953
    9954/** removes and releases all rows after the given number of rows from the LP */
    9956 SCIP_LP* lp, /**< LP data */
    9957 BMS_BLKMEM* blkmem, /**< block memory */
    9958 SCIP_SET* set, /**< global SCIP settings */
    9959 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    9960 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    9961 int newnrows /**< new number of rows in the LP */
    9962 )
    9963{
    9964 SCIP_ROW* row;
    9965 int r;
    9966
    9967 assert(lp != NULL);
    9968 assert(0 <= newnrows && newnrows <= lp->nrows);
    9969
    9970 SCIPsetDebugMsg(set, "shrinking LP from %d to %d rows\n", lp->nrows, newnrows);
    9971 if( newnrows < lp->nrows )
    9972 {
    9973 for( r = lp->nrows-1; r >= newnrows; --r )
    9974 {
    9975 row = lp->rows[r];
    9976 assert(row != NULL);
    9977 assert(row->len == 0 || row->cols != NULL);
    9978 assert(row->lppos == r);
    9979
    9980 /* mark row to be removed from the LP */
    9981 row->lppos = -1;
    9982 row->lpdepth = -1;
    9983 lp->nrows--;
    9984
    9985 /* count removable rows */
    9986 if( row->removable )
    9987 lp->nremovablerows--;
    9988
    9989 /* update row arrays of all linked columns */
    9990 rowUpdateDelLP(row);
    9991
    9992 SCIProwUnlock(lp->rows[r]);
    9993
    9994 /* check, if row deletion events are tracked
    9995 * if so, issue ROWDELETEDLP event
    9996 */
    9997 if( eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWDELETEDLP) != 0 ) /*lint !e587*/
    9998 {
    9999 SCIP_EVENT* event;
    10000
    10001 SCIP_CALL( SCIPeventCreateRowDeletedLP(&event, blkmem, lp->rows[r]) );
    10002 SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
    10003 }
    10004
    10005 SCIP_CALL( SCIProwRelease(&lp->rows[r], blkmem, set, lp) );
    10006 }
    10007 assert(lp->nrows == newnrows);
    10008 lp->lpifirstchgrow = MIN(lp->lpifirstchgrow, newnrows);
    10009
    10010 /* mark the current LP unflushed */
    10011 lp->flushed = FALSE;
    10012
    10013 checkLinks(lp);
    10014 }
    10015 assert(lp->nremovablerows <= lp->nrows);
    10016
    10017 return SCIP_OKAY;
    10018}
    10019
    10020/** removes all columns and rows from LP, releases all rows */
    10022 SCIP_LP* lp, /**< LP data */
    10023 BMS_BLKMEM* blkmem, /**< block memory */
    10024 SCIP_SET* set, /**< global SCIP settings */
    10025 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    10026 SCIP_EVENTFILTER* eventfilter /**< global event filter */
    10027 )
    10028{
    10029 assert(lp != NULL);
    10030 assert(!lp->diving);
    10031
    10032 SCIPsetDebugMsg(set, "clearing LP\n");
    10033 SCIP_CALL( SCIPlpShrinkCols(lp, set, 0) );
    10034 SCIP_CALL( SCIPlpShrinkRows(lp, blkmem, set, eventqueue, eventfilter, 0) );
    10035
    10036 return SCIP_OKAY;
    10037}
    10038
    10039/** remembers number of columns and rows to track the newly added ones */
    10041 SCIP_LP* lp /**< current LP data */
    10042 )
    10043{
    10044 assert(lp != NULL);
    10045 assert(!lp->diving);
    10046
    10047 lp->firstnewrow = lp->nrows;
    10048 lp->firstnewcol = lp->ncols;
    10049}
    10050
    10051/** sets the remembered number of columns and rows to the given values */
    10053 SCIP_LP* lp, /**< current LP data */
    10054 int nrows, /**< number of rows to set the size marker to */
    10055 int ncols /**< number of columns to set the size marker to */
    10056 )
    10057{
    10058 assert(lp != NULL);
    10059 assert(!lp->diving);
    10060
    10061 lp->firstnewrow = nrows;
    10062 lp->firstnewcol = ncols;
    10063}
    10064
    10065/** gets all indices of basic columns and rows: index i >= 0 corresponds to column i, index i < 0 to row -i-1 */
    10067 SCIP_LP* lp, /**< LP data */
    10068 int* basisind /**< pointer to store basis indices ready to keep number of rows entries */
    10069 )
    10070{
    10071 assert(lp != NULL);
    10072 assert(lp->flushed);
    10073 assert(lp->solved);
    10074 assert(lp->solisbasic);
    10075 assert(basisind != NULL);
    10076
    10077 SCIP_CALL( SCIPlpiGetBasisInd(lp->lpi, basisind) );
    10078
    10079 return SCIP_OKAY;
    10080}
    10081
    10082/** gets current basis status for columns and rows; arrays must be large enough to store the basis status */
    10084 SCIP_LP* lp, /**< LP data */
    10085 int* cstat, /**< array to store column basis status, or NULL */
    10086 int* rstat /**< array to store row basis status, or NULL */
    10087 )
    10088{
    10089 assert(lp != NULL);
    10090 assert(lp->flushed);
    10091 assert(lp->solved);
    10092 assert(lp->solisbasic);
    10093
    10094 SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
    10095
    10096 return SCIP_OKAY;
    10097}
    10098
    10099/** gets a row from the inverse basis matrix B^-1 */
    10101 SCIP_LP* lp, /**< LP data */
    10102 int r, /**< row number */
    10103 SCIP_Real* coef, /**< pointer to store the coefficients of the row */
    10104 int* inds, /**< array to store the non-zero indices, or NULL */
    10105 int* ninds /**< pointer to store the number of non-zero indices, or NULL
    10106 * (-1: if we do not store sparsity informations) */
    10107 )
    10108{
    10109 assert(lp != NULL);
    10110 assert(lp->flushed);
    10111 assert(lp->solved);
    10112 assert(lp->solisbasic);
    10113 assert(0 <= r && r < lp->nrows); /* the basis matrix is nrows x nrows */
    10114 assert(coef != NULL);
    10115
    10116 SCIP_CALL( SCIPlpiGetBInvRow(lp->lpi, r, coef, inds, ninds) );
    10117
    10118 return SCIP_OKAY;
    10119}
    10120
    10121/** gets a column from the inverse basis matrix B^-1 */
    10123 SCIP_LP* lp, /**< LP data */
    10124 int c, /**< column number of B^-1; this is NOT the number of the column in the LP
    10125 * returned by SCIPcolGetLPPos(); you have to call SCIPgetBasisInd()
    10126 * to get the array which links the B^-1 column numbers to the row and
    10127 * column numbers of the LP! c must be between 0 and nrows-1, since the
    10128 * basis has the size nrows * nrows */
    10129 SCIP_Real* coef, /**< pointer to store the coefficients of the column */
    10130 int* inds, /**< array to store the non-zero indices, or NULL */
    10131 int* ninds /**< pointer to store the number of non-zero indices, or NULL
    10132 * (-1: if we do not store sparsity informations) */
    10133 )
    10134{
    10135 assert(lp != NULL);
    10136 assert(lp->flushed);
    10137 assert(lp->solved);
    10138 assert(lp->solisbasic);
    10139 assert(0 <= c && c < lp->nrows); /* the basis matrix is nrows x nrows */
    10140 assert(coef != NULL);
    10141
    10142 SCIP_CALL( SCIPlpiGetBInvCol(lp->lpi, c, coef, inds, ninds) );
    10143
    10144 return SCIP_OKAY;
    10145}
    10146
    10147/** gets a row from the product of inverse basis matrix B^-1 and coefficient matrix A (i.e. from B^-1 * A) */
    10149 SCIP_LP* lp, /**< LP data */
    10150 int r, /**< row number */
    10151 SCIP_Real* binvrow, /**< row in B^-1 from prior call to SCIPlpGetBInvRow(), or NULL */
    10152 SCIP_Real* coef, /**< pointer to store the coefficients of the row */
    10153 int* inds, /**< array to store the non-zero indices, or NULL */
    10154 int* ninds /**< pointer to store the number of non-zero indices, or NULL
    10155 * (-1: if we do not store sparsity informations) */
    10156 )
    10157{
    10158 assert(lp != NULL);
    10159 assert(lp->flushed);
    10160 assert(lp->solved);
    10161 assert(lp->solisbasic);
    10162 assert(0 <= r && r < lp->nrows); /* the basis matrix is nrows x nrows */
    10163 assert(coef != NULL);
    10164
    10165 SCIP_CALL( SCIPlpiGetBInvARow(lp->lpi, r, binvrow, coef, inds, ninds) );
    10166
    10167 return SCIP_OKAY;
    10168}
    10169
    10170/** gets a column from the product of inverse basis matrix B^-1 and coefficient matrix A (i.e. from B^-1 * A),
    10171 * i.e., it computes B^-1 * A_c with A_c being the c'th column of A
    10172 */
    10174 SCIP_LP* lp, /**< LP data */
    10175 int c, /**< column number which can be accessed by SCIPcolGetLPPos() */
    10176 SCIP_Real* coef, /**< pointer to store the coefficients of the column */
    10177 int* inds, /**< array to store the non-zero indices, or NULL */
    10178 int* ninds /**< pointer to store the number of non-zero indices, or NULL
    10179 * (-1: if we do not store sparsity informations) */
    10180 )
    10181{
    10182 assert(lp != NULL);
    10183 assert(lp->flushed);
    10184 assert(lp->solved);
    10185 assert(lp->solisbasic);
    10186 assert(0 <= c && c < lp->ncols);
    10187 assert(coef != NULL);
    10188
    10189 SCIP_CALL( SCIPlpiGetBInvACol(lp->lpi, c, coef, inds, ninds) );
    10190
    10191 return SCIP_OKAY;
    10192}
    10193
    10194/** calculates a weighted sum of all LP rows; for negative weights, the left and right hand side of the corresponding
    10195 * LP row are swapped in the summation
    10196 */
    10198 SCIP_LP* lp, /**< LP data */
    10199 SCIP_SET* set, /**< global SCIP settings */
    10200 SCIP_PROB* prob, /**< problem data */
    10201 SCIP_Real* weights, /**< row weights in row summation */
    10202 SCIP_REALARRAY* sumcoef, /**< array to store sum coefficients indexed by variables' probindex */
    10203 SCIP_Real* sumlhs, /**< pointer to store the left hand side of the row summation */
    10204 SCIP_Real* sumrhs /**< pointer to store the right hand side of the row summation */
    10205 )
    10206{
    10207 SCIP_ROW* row;
    10208 int r;
    10209 int i;
    10210 int idx;
    10211 SCIP_Bool lhsinfinite;
    10212 SCIP_Bool rhsinfinite;
    10213
    10214 assert(lp != NULL);
    10215 assert(prob != NULL);
    10216 assert(weights != NULL);
    10217 assert(sumcoef != NULL);
    10218 assert(sumlhs != NULL);
    10219 assert(sumrhs != NULL);
    10220
    10221 /**@todo test, if a column based summation is faster */
    10222
    10223 SCIP_CALL( SCIPrealarrayClear(sumcoef) );
    10224 SCIP_CALL( SCIPrealarrayExtend(sumcoef, set->mem_arraygrowinit, set->mem_arraygrowfac, 0, prob->nvars-1) );
    10225 *sumlhs = 0.0;
    10226 *sumrhs = 0.0;
    10227 lhsinfinite = FALSE;
    10228 rhsinfinite = FALSE;
    10229 for( r = 0; r < lp->nrows; ++r )
    10230 {
    10231 if( !SCIPsetIsZero(set, weights[r]) )
    10232 {
    10233 row = lp->rows[r];
    10234 assert(row != NULL);
    10235 assert(row->len == 0 || row->cols != NULL);
    10236 assert(row->len == 0 || row->cols_index != NULL);
    10237 assert(row->len == 0 || row->vals != NULL);
    10238
    10239 /* add the row coefficients to the sum */
    10240 for( i = 0; i < row->len; ++i )
    10241 {
    10242 assert(row->cols[i] != NULL);
    10243 assert(row->cols[i]->var != NULL);
    10244 assert(SCIPvarGetStatus(row->cols[i]->var) == SCIP_VARSTATUS_COLUMN);
    10245 assert(SCIPvarGetCol(row->cols[i]->var) == row->cols[i]);
    10246 assert(SCIPvarGetProbindex(row->cols[i]->var) == row->cols[i]->var_probindex);
    10247 idx = row->cols[i]->var_probindex;
    10248 assert(0 <= idx && idx < prob->nvars);
    10249 SCIP_CALL( SCIPrealarrayIncVal(sumcoef, set->mem_arraygrowinit, set->mem_arraygrowfac, idx, weights[r] * row->vals[i]) );
    10250 }
    10251
    10252 /* add the row sides to the sum, depending on the sign of the weight */
    10253 if( weights[r] > 0.0 )
    10254 {
    10255 lhsinfinite = lhsinfinite || SCIPsetIsInfinity(set, -row->lhs);
    10256 if( !lhsinfinite )
    10257 (*sumlhs) += weights[r] * (row->lhs - row->constant);
    10258 rhsinfinite = rhsinfinite || SCIPsetIsInfinity(set, row->rhs);
    10259 if( !rhsinfinite )
    10260 (*sumrhs) += weights[r] * (row->rhs - row->constant);
    10261 }
    10262 else
    10263 {
    10264 lhsinfinite = lhsinfinite || SCIPsetIsInfinity(set, row->rhs);
    10265 if( !lhsinfinite )
    10266 (*sumlhs) += weights[r] * (row->rhs - row->constant);
    10267 rhsinfinite = rhsinfinite || SCIPsetIsInfinity(set, -row->lhs);
    10268 if( !rhsinfinite )
    10269 (*sumrhs) += weights[r] * (row->lhs - row->constant);
    10270 }
    10271 }
    10272 }
    10273
    10274 if( lhsinfinite )
    10275 *sumlhs = -SCIPsetInfinity(set);
    10276 if( rhsinfinite )
    10277 *sumrhs = SCIPsetInfinity(set);
    10278
    10279 return SCIP_OKAY;
    10280}
    10281
    10282/** stores LP state (like basis information) into LP state object */
    10284 SCIP_LP* lp, /**< LP data */
    10285 BMS_BLKMEM* blkmem, /**< block memory */
    10286 SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
    10287 )
    10288{
    10289 assert(lp != NULL);
    10290 assert(lp->flushed);
    10291 assert(lp->solved);
    10292 assert(blkmem != NULL);
    10293 assert(lpistate != NULL);
    10294
    10295 /* check whether there is no lp */
    10296 if( lp->nlpicols == 0 && lp->nlpirows == 0 )
    10297 *lpistate = NULL;
    10298 else
    10299 {
    10300 SCIP_CALL( SCIPlpiGetState(lp->lpi, blkmem, lpistate) );
    10301 }
    10302
    10303 return SCIP_OKAY;
    10304}
    10305
    10306/** loads LP state (like basis information) into solver */
    10308 SCIP_LP* lp, /**< LP data */
    10309 BMS_BLKMEM* blkmem, /**< block memory */
    10310 SCIP_SET* set, /**< global SCIP settings */
    10311 SCIP_PROB* prob, /**< problem data */
    10312 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    10313 SCIP_LPISTATE* lpistate, /**< LP state information (like basis information) */
    10314 SCIP_Bool wasprimfeas, /**< primal feasibility when LP state information was stored */
    10315 SCIP_Bool wasprimchecked, /**< true if the LP solution has passed the primal feasibility check */
    10316 SCIP_Bool wasdualfeas, /**< dual feasibility when LP state information was stored */
    10317 SCIP_Bool wasdualchecked /**< true if the LP solution has passed the dual feasibility check */
    10318 )
    10319{
    10320 assert(lp != NULL);
    10321 assert(blkmem != NULL);
    10322
    10323 /* flush changes to the LP solver */
    10324 SCIP_CALL( SCIPlpFlush(lp, blkmem, set, prob, eventqueue) );
    10325 assert(lp->flushed);
    10326
    10327 if( lp->solved && lp->solisbasic )
    10328 return SCIP_OKAY;
    10329
    10330 /* set LPI state in the LP solver */
    10331 if( lpistate == NULL )
    10332 lp->solisbasic = FALSE;
    10333 else
    10334 {
    10335 SCIP_CALL( SCIPlpiSetState(lp->lpi, blkmem, lpistate) );
    10336 lp->solisbasic = SCIPlpiHasStateBasis(lp->lpi, lpistate);
    10337 }
    10338 /* @todo: setting feasibility to TRUE might be wrong because in probing mode, the state is even saved when the LP was
    10339 * flushed and solved, also, e.g., when we hit the iteration limit
    10340 */
    10341 lp->primalfeasible = wasprimfeas;
    10342 lp->primalchecked = wasprimchecked;
    10343 lp->dualfeasible = wasdualfeas;
    10344 lp->dualchecked = wasdualchecked;
    10345
    10346 return SCIP_OKAY;
    10347}
    10348
    10349/** frees LP state information */
    10351 SCIP_LP* lp, /**< LP data */
    10352 BMS_BLKMEM* blkmem, /**< block memory */
    10353 SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
    10354 )
    10355{
    10356 assert(lp != NULL);
    10357
    10358 if( *lpistate != NULL )
    10359 {
    10360 SCIP_CALL( SCIPlpiFreeState(lp->lpi, blkmem, lpistate) );
    10361 }
    10362
    10363 return SCIP_OKAY;
    10364}
    10365
    10366/** interrupts the currently ongoing lp solve, or disables the interrupt */
    10368 SCIP_LP* lp, /**< LP data */
    10369 SCIP_Bool interrupt /**< TRUE if interrupt should be set, FALSE if it should be disabled */
    10370 )
    10371{
    10372 assert(lp != NULL);
    10373
    10374 if( lp->lpi == NULL )
    10375 return SCIP_OKAY;
    10376
    10377 SCIP_CALL( SCIPlpiInterrupt(lp->lpi, interrupt) );
    10378
    10379 return SCIP_OKAY;
    10380}
    10381
    10382/** stores pricing norms into LP norms object */
    10384 SCIP_LP* lp, /**< LP data */
    10385 BMS_BLKMEM* blkmem, /**< block memory */
    10386 SCIP_LPINORMS** lpinorms /**< pointer to LP pricing norms information */
    10387 )
    10388{
    10389 assert(lp != NULL);
    10390 assert(lp->flushed);
    10391 assert(lp->solved);
    10392 assert(blkmem != NULL);
    10393 assert(lpinorms != NULL);
    10394
    10395 /* check whether there is no lp */
    10396 if( lp->nlpicols == 0 && lp->nlpirows == 0 )
    10397 *lpinorms = NULL;
    10398 else
    10399 {
    10400 SCIP_CALL( SCIPlpiGetNorms(lp->lpi, blkmem, lpinorms) );
    10401 }
    10402
    10403 return SCIP_OKAY;
    10404}
    10405
    10406/** loads pricing norms from LP norms object into solver */
    10408 SCIP_LP* lp, /**< LP data */
    10409 BMS_BLKMEM* blkmem, /**< block memory */
    10410 SCIP_LPINORMS* lpinorms /**< LP pricing norms information */
    10411 )
    10412{
    10413 assert(lp != NULL);
    10414 assert(blkmem != NULL);
    10415 assert(lp->flushed);
    10416
    10417 /* set LPI norms in the LP solver */
    10418 if( lpinorms != NULL )
    10419 {
    10420 SCIP_CALL( SCIPlpiSetNorms(lp->lpi, blkmem, lpinorms) );
    10421 }
    10422
    10423 return SCIP_OKAY;
    10424}
    10425
    10426/** frees pricing norms information */
    10428 SCIP_LP* lp, /**< LP data */
    10429 BMS_BLKMEM* blkmem, /**< block memory */
    10430 SCIP_LPINORMS** lpinorms /**< pointer to LP pricing norms information */
    10431 )
    10432{
    10433 assert(lp != NULL);
    10434
    10435 SCIP_CALL( SCIPlpiFreeNorms(lp->lpi, blkmem, lpinorms) );
    10436
    10437 return SCIP_OKAY;
    10438}
    10439
    10440/** return the current cutoff bound of the lp */
    10442 SCIP_LP* lp /**< current LP data */
    10443 )
    10444{
    10445 assert(lp != NULL);
    10446
    10447 return lp->cutoffbound;
    10448}
    10449
    10450/** sets the upper objective limit of the LP solver */
    10452 SCIP_LP* lp, /**< current LP data */
    10453 SCIP_SET* set, /**< global SCIP settings */
    10454 SCIP_PROB* prob, /**< problem data */
    10455 SCIP_Real cutoffbound /**< new upper objective limit */
    10456 )
    10457{
    10458 assert(lp != NULL);
    10459
    10460 SCIPsetDebugMsg(set, "setting LP upper objective limit from %g to %g\n", lp->cutoffbound, cutoffbound);
    10461
    10462 /* if the objective function was changed in diving, the cutoff bound has no meaning (it will be set correctly
    10463 * in SCIPendDive())
    10464 */
    10465 if( SCIPlpDivingObjChanged(lp) )
    10466 {
    10467 assert(SCIPsetIsInfinity(set, lp->cutoffbound));
    10468 return SCIP_OKAY;
    10469 }
    10470
    10471 /* if the cutoff bound is increased, and the LP was proved to exceed the old cutoff, it is no longer solved */
    10472 if( SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OBJLIMIT && cutoffbound > lp->cutoffbound )
    10473 {
    10474 /* mark the current solution invalid */
    10475 lp->solved = FALSE;
    10476 lp->lpobjval = SCIP_INVALID;
    10478 }
    10479 /* if the cutoff bound is decreased below the current optimal value, the LP now exceeds the objective limit;
    10480 * if the objective limit in the LP solver was disabled, the solution status of the LP is not changed
    10481 */
    10482 else if( !lpCutoffDisabled(set, prob, lp) && SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OPTIMAL
    10483 && SCIPlpGetObjval(lp, set, prob) >= cutoffbound )
    10484 {
    10485 assert(lp->flushed);
    10486 assert(lp->solved);
    10488 }
    10489
    10490 if( !lp->diving && !lp->probing )
    10491 SCIP_CALL( SCIPlpExactSetCutoffbound(lp->lpexact, set, cutoffbound) );
    10492
    10493 lp->cutoffbound = cutoffbound;
    10494
    10495 return SCIP_OKAY;
    10496}
    10497
    10498/** gets current primal feasibility tolerance of LP solver */
    10500 SCIP_LP* lp /**< current LP data */
    10501 )
    10502{
    10503 assert(lp != NULL);
    10504
    10505 return lp->feastol;
    10506}
    10507
    10508/** sets primal feasibility tolerance of LP solver */
    10510 SCIP_LP* lp, /**< current LP data */
    10511 SCIP_SET* set, /**< global SCIP settings */
    10512 SCIP_Real newfeastol /**< new primal feasibility tolerance for LP */
    10513 )
    10514{
    10515 assert(lp != NULL);
    10516 assert(newfeastol > 0.0);
    10517
    10518 SCIPsetDebugMsg(set, "setting LP primal feasibility tolerance from %g to %g\n", lp->feastol, newfeastol);
    10519
    10520 /* mark the LP unsolved, if the primal feasibility tolerance is tightened */
    10521 if( newfeastol < lp->feastol )
    10522 {
    10523 lp->solved = FALSE;
    10525 }
    10526
    10527 lp->feastol = newfeastol;
    10528}
    10529
    10530/** resets primal feasibility tolerance of LP solver
    10531 *
    10532 * Sets primal feasibility tolerance to min of numerics/lpfeastolfactor * numerics/feastol and relaxfeastol.
    10533 */
    10535 SCIP_LP* lp, /**< current LP data */
    10536 SCIP_SET* set /**< global SCIP settings */
    10537 )
    10538{
    10539 assert(lp != NULL);
    10540
    10541 SCIPsetDebugMsg(set, "reset LP primal feasibility tolerance\n");
    10542
    10543 if( SCIPsetRelaxfeastol(set) != SCIP_INVALID ) /*lint !e777*/
    10545 else
    10547}
    10548
    10549/** returns the name of the given LP algorithm */
    10550static
    10551const char* lpalgoName(
    10552 SCIP_LPALGO lpalgo /**< LP algorithm */
    10553 )
    10554{
    10555 switch( lpalgo )
    10556 {
    10558 return "primal simplex";
    10560 return "dual simplex";
    10562 return "barrier";
    10564 return "barrier/crossover";
    10565 default:
    10566 SCIPerrorMessage("invalid LP algorithm\n");
    10567 SCIPABORT();
    10568 return "invalid"; /*lint !e527*/
    10569 }
    10570}
    10571
    10572/** calls LPI to perform primal simplex, measures time and counts iterations, gets basis feasibility status */
    10573static
    10575 SCIP_LP* lp, /**< current LP data */
    10576 SCIP_SET* set, /**< global SCIP settings */
    10577 SCIP_STAT* stat, /**< problem statistics */
    10578 SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
    10579 SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
    10580 SCIP_Bool instable, /**< is this a resolving call to avoid instable LPs? */
    10581 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
    10582 )
    10583{
    10584 SCIP_Real timedelta;
    10585 SCIP_RETCODE retcode;
    10586 int iterations;
    10587
    10588 assert(lp != NULL);
    10589 assert(lp->flushed);
    10590 assert(set != NULL);
    10591 assert(stat != NULL);
    10592 assert(lperror != NULL);
    10593
    10594 SCIPsetDebugMsg(set, "solving LP %" SCIP_LONGINT_FORMAT " (%d cols, %d rows) with primal simplex (diving=%d, nprimallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
    10595 stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nprimallps, stat->ndivinglps);
    10596
    10597 *lperror = FALSE;
    10598
    10599#ifdef SCIP_MORE_DEBUG /* for debugging: write all root node LP's */
    10600 if( stat->nnodes == 1 && !lp->diving && !lp->probing )
    10601 {
    10602 char fname[SCIP_MAXSTRLEN];
    10603 (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
    10604 SCIP_CALL( SCIPlpWrite(lp, fname) );
    10605 SCIPsetDebugMsg(set, "wrote LP to file <%s> (primal simplex, objlim=%.15g, feastol=%.15g/%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
    10606 fname, lp->lpiobjlim, lp->lpifeastol, lp->lpidualfeastol,
    10608 }
    10609#endif
    10610
    10611 /* start timing */
    10612 if( lp->diving || lp->probing )
    10613 {
    10614 if( lp->strongbranchprobing )
    10616 else
    10618
    10619 timedelta = 0.0; /* unused for diving or probing */
    10620 }
    10621 else
    10622 {
    10624 timedelta = -SCIPclockGetTime(stat->primallptime);
    10625 }
    10626
    10627 /* if this is a call to resolve an instable LP, collect time */
    10628 if( instable )
    10629 {
    10631 }
    10632
    10633 /* call primal simplex */
    10634 retcode = SCIPlpiSolvePrimal(lp->lpi);
    10635 if( retcode == SCIP_LPERROR )
    10636 {
    10637 *lperror = TRUE;
    10638 SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") primal simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
    10639 }
    10640 else
    10641 {
    10642 SCIP_CALL( retcode );
    10643 }
    10645 lp->solisbasic = TRUE;
    10646
    10647 /* stop timing */
    10648 if( lp->diving || lp->probing )
    10649 {
    10650 if( lp->strongbranchprobing )
    10652 else
    10654 }
    10655 else
    10656 {
    10657 timedelta += SCIPclockGetTime(stat->primallptime);
    10659 }
    10660
    10661 if ( instable )
    10662 {
    10664 }
    10665
    10666 /* count number of iterations */
    10667 SCIPstatIncrement(stat, set, lpcount);
    10668 SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
    10669 if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
    10670 {
    10671 if( !lp->strongbranchprobing )
    10672 {
    10673 SCIPstatIncrement(stat, set, nlps);
    10674 SCIPstatAdd( stat, set, nlpiterations, iterations );
    10675 }
    10676 if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
    10677 {
    10678 SCIPstatIncrement(stat, set, nprimalresolvelps );
    10679 SCIPstatAdd(stat, set, nprimalresolvelpiterations, iterations);
    10680 }
    10681 if ( instable )
    10682 {
    10683 SCIPstatIncrement(stat, set, nresolveinstablelps);
    10684 SCIPstatAdd(stat, set, nresolveinstablelpiters, iterations);
    10685 }
    10686 if( lp->diving || lp->probing )
    10687 {
    10688 if( lp->strongbranchprobing )
    10689 {
    10690 SCIPstatIncrement(stat, set, nsbdivinglps);
    10691 SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
    10692 }
    10693 else
    10694 {
    10695 SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
    10696 SCIPstatIncrement(stat, set, ndivinglps);
    10697 SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
    10698 }
    10699 }
    10700 else
    10701 {
    10702 SCIPstatIncrement(stat, set, nprimallps);
    10703 SCIPstatAdd(stat, set, nprimallpiterations, iterations);
    10704 }
    10705 }
    10706 else
    10707 {
    10708 if ( ! lp->diving && ! lp->probing )
    10709 {
    10710 SCIPstatIncrement(stat, set, nprimalzeroitlps);
    10711 SCIPstatAdd(stat, set, primalzeroittime, timedelta);
    10712 }
    10713
    10714 if ( keepsol && !(*lperror) )
    10715 {
    10716 /* the solution didn't change: if the solution was valid before resolve, it is still valid */
    10717 if( lp->validsollp == stat->lpcount-1 )
    10718 lp->validsollp = stat->lpcount;
    10719 if( lp->validfarkaslp == stat->lpcount-1 )
    10720 lp->validfarkaslp = stat->lpcount;
    10721 }
    10722 }
    10723
    10724 SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with primal simplex (diving=%d, nprimallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
    10725 stat->lpcount, lp->diving || lp->probing, stat->nprimallps, stat->ndivinglps);
    10726
    10727 return SCIP_OKAY;
    10728}
    10729
    10730/** calls LPI to perform dual simplex, measures time and counts iterations */
    10731static
    10733 SCIP_LP* lp, /**< current LP data */
    10734 SCIP_SET* set, /**< global SCIP settings */
    10735 SCIP_STAT* stat, /**< problem statistics */
    10736 SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
    10737 SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
    10738 SCIP_Bool instable, /**< is this a resolving call to avoid instable LPs? */
    10739 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
    10740 )
    10741{
    10742 SCIP_Real timedelta;
    10743 SCIP_RETCODE retcode;
    10744 int iterations;
    10745
    10746 assert(lp != NULL);
    10747 assert(lp->flushed);
    10748 assert(set != NULL);
    10749 assert(stat != NULL);
    10750 assert(lperror != NULL);
    10751
    10752 SCIPsetDebugMsg(set, "solving LP %" SCIP_LONGINT_FORMAT " (%d cols, %d rows) with dual simplex (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
    10753 stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
    10754
    10755 *lperror = FALSE;
    10756
    10757#ifdef SCIP_MORE_DEBUG /* for debugging: write all root node LP's */
    10758 if( stat->nnodes == 1 && !lp->diving && !lp->probing )
    10759 {
    10760 char fname[SCIP_MAXSTRLEN];
    10761 (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
    10762 SCIP_CALL( SCIPlpWrite(lp, fname) );
    10763 SCIPsetDebugMsg(set, "wrote LP to file <%s> (dual simplex, objlim=%.15g, feastol=%.15g/%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
    10764 fname, lp->lpiobjlim, lp->lpifeastol, lp->lpidualfeastol,
    10766 }
    10767#endif
    10768
    10769 /* start timing */
    10770 if( lp->diving || lp->probing )
    10771 {
    10772 if( lp->strongbranchprobing )
    10774 else
    10776
    10777 timedelta = 0.0; /* unused for diving or probing */
    10778 }
    10779 else
    10780 {
    10782 timedelta = -SCIPclockGetTime(stat->duallptime);
    10783 }
    10784
    10785 /* if this is a call to resolve an instable LP, collect time */
    10786 if ( instable )
    10787 {
    10789 }
    10790
    10791 /* call dual simplex */
    10792 retcode = SCIPlpiSolveDual(lp->lpi);
    10793 if( retcode == SCIP_LPERROR )
    10794 {
    10795 *lperror = TRUE;
    10796 SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
    10797 }
    10798 else
    10799 {
    10800 SCIP_CALL( retcode );
    10801 }
    10803 lp->solisbasic = TRUE;
    10804
    10805 /* stop timing */
    10806 if( lp->diving || lp->probing )
    10807 {
    10808 if( lp->strongbranchprobing )
    10810 else
    10812 }
    10813 else
    10814 {
    10815 timedelta += SCIPclockGetTime(stat->duallptime);
    10817 }
    10818
    10819 if ( instable )
    10820 {
    10822 }
    10823
    10824 /* count number of iterations */
    10825 SCIPstatIncrement(stat, set, lpcount);
    10826 SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
    10827 if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
    10828 {
    10829 if( !lp->strongbranchprobing )
    10830 {
    10831 SCIPstatIncrement(stat, set, nlps);
    10832 SCIPstatAdd(stat, set, nlpiterations, iterations);
    10833 }
    10834 if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
    10835 {
    10836 SCIPstatIncrement(stat, set, ndualresolvelps);
    10837 SCIPstatAdd(stat, set, ndualresolvelpiterations, iterations);
    10838 }
    10839 if ( instable )
    10840 {
    10841 SCIPstatIncrement(stat, set, nresolveinstablelps);
    10842 SCIPstatAdd(stat, set, nresolveinstablelpiters, iterations);
    10843 }
    10844 if( lp->diving || lp->probing )
    10845 {
    10846 if( lp->strongbranchprobing )
    10847 {
    10848 SCIPstatIncrement(stat, set, nsbdivinglps);
    10849 SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
    10850 }
    10851 else
    10852 {
    10853 SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
    10854 SCIPstatIncrement(stat, set, ndivinglps);
    10855 SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
    10856 }
    10857 }
    10858 else
    10859 {
    10860 SCIPstatIncrement(stat, set, nduallps);
    10861 SCIPstatAdd(stat, set, nduallpiterations, iterations);
    10862 }
    10863 }
    10864 else
    10865 {
    10866 if ( ! lp->diving && ! lp->probing )
    10867 {
    10868 SCIPstatIncrement(stat, set, ndualzeroitlps);
    10869 SCIPstatAdd(stat, set, dualzeroittime, timedelta);
    10870 }
    10871
    10872 if( keepsol && !(*lperror) )
    10873 {
    10874 /* the solution didn't change: if the solution was valid before resolve, it is still valid */
    10875 if( lp->validsollp == stat->lpcount-1 )
    10876 lp->validsollp = stat->lpcount;
    10877 if( lp->validfarkaslp == stat->lpcount-1 )
    10878 lp->validfarkaslp = stat->lpcount;
    10879 }
    10880 }
    10881
    10882 SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with dual simplex (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
    10883 stat->lpcount, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
    10884
    10885 return SCIP_OKAY;
    10886}
    10887
    10888/** calls LPI to perform lexicographic dual simplex to find a lexicographically minimal optimal solution, measures time and counts iterations
    10889 *
    10890 * We follow the approach of the following paper to find a lexicographically minimal optimal
    10891 * solution:
    10892 *
    10893 * Zanette, Fischetti, Balas@n
    10894 * Can pure cutting plane algorithms work?@n
    10895 * IPCO 2008, Bertinoro, Italy.
    10896 *
    10897 * We do, however, not aim for the exact lexicographically minimal optimal solutions, but perform a
    10898 * heuristic, i.e., we limit the number of components which are minimized.
    10899 *
    10900 * More precisely, we first solve the problem with the dual simplex algorithm. Then we fix those
    10901 * nonbasic variables to their current value (i.e., one of the bounds except maybe for free
    10902 * variables) that have nonzero reduced cost. This fixes the objective function value, because only
    10903 * pivots that will not change the objective are allowed afterwards.
    10904 *
    10905 * Then the not yet fixed variables are considered in turn. If they are at their lower bounds and
    10906 * nonbasic, they are fixed to this bound, since their value cannot be decreased further. Once a
    10907 * candidate is found, we set the objective to minimize this variable. We run the primal simplex
    10908 * algorithm (since the objective is changed the solution is not dual feasible anymore; if
    10909 * variables out of the basis have been fixed to their lower bound, the basis is also not primal
    10910 * feasible anymore). After the optimization, we again fix nonbasic variables that have nonzero
    10911 * reduced cost. We then choose the next variable and iterate.
    10912 *
    10913 * We stop the process once we do not find candidates or have performed a maximum number of
    10914 * iterations.
    10915 *
    10916 * @todo Does this really produce a lexicographically minimal solution?
    10917 * @todo Can we skip the consideration of basic variables that are at their lower bound? How can we
    10918 * guarantee that these variables will not be changed in later stages? We can fix these variables
    10919 * to their lower bound, but this destroys the basis.
    10920 * @todo Should we use lexicographical minimization in diving/probing or not?
    10921 */
    10922static
    10924 SCIP_LP* lp, /**< current LP data */
    10925 SCIP_SET* set, /**< global SCIP settings */
    10926 SCIP_STAT* stat, /**< problem statistics */
    10927 SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
    10928 SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
    10929 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
    10930 )
    10931{
    10932 SCIP_Real timedelta;
    10933 SCIP_RETCODE retcode;
    10934 int totalIterations;
    10935 int lexIterations;
    10936 int iterations;
    10937 int rounds;
    10938
    10939 assert(lp != NULL);
    10940 assert(lp->flushed);
    10941 assert(set != NULL);
    10942 assert(stat != NULL);
    10943 assert(lperror != NULL);
    10944
    10945 SCIPsetDebugMsg(set, "solving LP %" SCIP_LONGINT_FORMAT " (%d cols, %d rows) with lex dual simplex (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
    10946 stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
    10947
    10948 *lperror = FALSE;
    10949
    10950 /* start timing */
    10951 if( lp->diving || lp->probing )
    10952 {
    10953 if( lp->strongbranchprobing )
    10955 else
    10957
    10958 timedelta = 0.0; /* unused for diving or probing */
    10959 }
    10960 else
    10961 {
    10963 timedelta = -SCIPclockGetTime(stat->duallptime);
    10964 }
    10965
    10966 /* call dual simplex for first lp */
    10967 retcode = SCIPlpiSolveDual(lp->lpi);
    10968 if( retcode == SCIP_LPERROR )
    10969 {
    10970 *lperror = TRUE;
    10971 SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
    10972 }
    10973 else
    10974 {
    10975 SCIP_CALL( retcode );
    10976 }
    10977 SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
    10978 totalIterations = iterations;
    10979
    10980 /* stop timing */
    10981 if( lp->diving || lp->probing )
    10982 {
    10983 if( lp->strongbranchprobing )
    10985 else
    10987 }
    10988 else
    10989 {
    10990 timedelta += SCIPclockGetTime(stat->duallptime);
    10992 }
    10993
    10994 /* count number of iterations */
    10995 SCIPstatIncrement(stat, set, lpcount);
    10996 if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
    10997 {
    10998 if( lp->strongbranchprobing )
    10999 {
    11000 SCIPstatAdd(stat, set, nlpiterations, iterations);
    11001 }
    11002 if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
    11003 {
    11004 SCIPstatIncrement(stat, set, ndualresolvelps);
    11005 SCIPstatAdd(stat, set, ndualresolvelpiterations, iterations);
    11006 }
    11007 if( lp->diving || lp->probing )
    11008 {
    11009 if( lp->strongbranchprobing )
    11010 {
    11011 SCIPstatIncrement(stat, set, nsbdivinglps);
    11012 SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
    11013 }
    11014 else
    11015 {
    11016 SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
    11017 SCIPstatIncrement(stat, set, ndivinglps);
    11018 SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
    11019 }
    11020 }
    11021 else
    11022 {
    11023 SCIPstatIncrement(stat, set, nduallps);
    11024 SCIPstatAdd(stat, set, nduallpiterations, iterations);
    11025 }
    11026 }
    11027 else
    11028 {
    11029 if ( ! lp->diving && ! lp->probing )
    11030 {
    11031 SCIPstatIncrement(stat, set, ndualzeroitlps);
    11032 SCIPstatAdd(stat, set, dualzeroittime, timedelta);
    11033 }
    11034 }
    11035 lexIterations = 0;
    11036
    11037 /* search for lexicographically minimal optimal solution */
    11038 if( !lp->diving && !lp->probing && SCIPlpiIsOptimal(lp->lpi) )
    11039 {
    11040 SCIP_Real* primsol;
    11041 SCIP_Real* dualsol;
    11042 SCIP_Real* redcost;
    11043 int* cstat;
    11044 int* rstat;
    11045 SCIP_Real* newobj;
    11046 SCIP_Real* newlb;
    11047 SCIP_Real* newub;
    11048 SCIP_Real* newlhs;
    11049 SCIP_Real* newrhs;
    11050 SCIP_Real* oldlb;
    11051 SCIP_Real* oldub;
    11052 SCIP_Real* oldlhs;
    11053 SCIP_Real* oldrhs;
    11054 SCIP_Real* oldobj;
    11055 SCIP_Bool* fixedc;
    11056 SCIP_Bool* fixedr;
    11057 int* indcol;
    11058 int* indrow;
    11059 int* indallcol;
    11060 int* indallrow;
    11061 SCIP_Bool chooseBasic;
    11062 SCIP_Bool success;
    11063 int nDualDeg;
    11064 int r, c;
    11065 int cntcol;
    11066 int cntrow;
    11067 int nruns;
    11068 int pos;
    11069
    11070 chooseBasic = set->lp_lexdualbasic;
    11071
    11072 /* start timing */
    11074
    11075 /* get all solution information */
    11076 SCIP_CALL( SCIPsetAllocBufferArray(set, &dualsol, lp->nlpirows) );
    11077 SCIP_CALL( SCIPsetAllocBufferArray(set, &redcost, lp->nlpicols) );
    11078 if( chooseBasic )
    11079 {
    11080 SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
    11081 }
    11082 else
    11083 primsol = NULL;
    11084
    11085 /* get basic and nonbasic information */
    11088
    11089 /* save bounds, lhs/rhs, and objective */
    11095 SCIP_CALL( SCIPlpiGetBounds(lp->lpi, 0, lp->nlpicols-1, oldlb, oldub) );
    11096 SCIP_CALL( SCIPlpiGetSides(lp->lpi, 0, lp->nlpirows-1, oldlhs, oldrhs) );
    11097 SCIP_CALL( SCIPlpiGetObj(lp->lpi, 0, lp->nlpicols-1, oldobj) );
    11098
    11099 /* get storage for several arrays */
    11103
    11107
    11108 SCIP_CALL( SCIPsetAllocBufferArray(set, &indallcol, lp->nlpicols) );
    11109 SCIP_CALL( SCIPsetAllocBufferArray(set, &indallrow, lp->nlpirows) );
    11110
    11113
    11114 /* initialize: set objective to 0, get fixed variables */
    11116 for( c = 0; c < lp->nlpicols; ++c )
    11117 {
    11118 newobj[c] = 0.0;
    11119 indallcol[c] = c;
    11120 if( SCIPsetIsFeasEQ(set, oldlb[c], oldub[c]) )
    11121 fixedc[c] = TRUE;
    11122 else
    11123 fixedc[c] = FALSE;
    11124 }
    11125
    11126 /* initialize: get fixed slack variables */
    11127 for( r = 0; r < lp->nlpirows; ++r )
    11128 {
    11129 indallrow[r] = r;
    11130 if( SCIPsetIsFeasEQ(set, oldlhs[r], oldrhs[r]) )
    11131 fixedr[r] = TRUE;
    11132 else
    11133 fixedr[r] = FALSE;
    11134 }
    11135
    11136#ifdef DEBUG_LEXDUAL
    11137 {
    11138 int j;
    11139
    11140 if( !chooseBasic )
    11141 {
    11142 assert(primsol == NULL);
    11143 SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
    11144 }
    11145 assert(primsol != NULL);
    11146 SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, NULL, NULL) );
    11147 SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
    11148
    11149 for( j = 0; j < lp->nlpicols; ++j )
    11150 {
    11151 if( fixedc[j] )
    11152 {
    11153 SCIPsetDebugMsg(set, "%f (%d) [f] ", primsol[j], j);
    11154 }
    11155 else
    11156 {
    11157 char type;
    11158 switch( (SCIP_BASESTAT) cstat[j] )
    11159 {
    11161 type = 'l';
    11162 break;
    11164 type = 'u';
    11165 break;
    11166 case SCIP_BASESTAT_ZERO:
    11167 type = 'z';
    11168 break;
    11170 type = 'b';
    11171 break;
    11172 default:
    11173 type = '?';
    11174 SCIPerrorMessage("unknown base stat %d\n", cstat[j]);
    11175 SCIPABORT();
    11176 }
    11177 SCIPsetDebugMsg(set, "%f (%d) [%c] ", primsol[j], j, type);
    11178 }
    11179 }
    11180 SCIPsetDebugMsg(set, "\n\n");
    11181
    11182 if( !chooseBasic )
    11183 {
    11184 SCIPsetFreeBufferArray(set, &primsol);
    11185 assert(primsol == NULL);
    11186 }
    11187 }
    11188#endif
    11189
    11190 /* disable objective limit */
    11192 assert(success);
    11193
    11194 /* perform lexicographic rounds */
    11195 pos = -1;
    11196 nruns = 0;
    11197 rounds = 0;
    11198 /* SCIP_CALL( lpSetLPInfo(lp, TRUE) ); */
    11199 do
    11200 {
    11201 int oldpos;
    11202
    11203 /* get current solution */
    11204 if( chooseBasic )
    11205 SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, dualsol, NULL, redcost) );
    11206 else
    11207 {
    11208 SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, NULL, dualsol, NULL, redcost) );
    11209 assert(primsol == NULL);
    11210 }
    11211
    11212 /* get current basis */
    11213 SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
    11214
    11215 /* check columns: find first candidate (either basic or nonbasic and zero reduced cost) and fix variables */
    11216 nDualDeg = 0;
    11217 cntcol = 0;
    11218 oldpos = pos;
    11219 pos = -1;
    11220 for( c = 0; c < lp->nlpicols; ++c )
    11221 {
    11222 if( !fixedc[c] )
    11223 {
    11224 /* check whether variable is in basis */
    11225 if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_BASIC )
    11226 {
    11227 /* store first candidate */
    11228 if( pos == -1 && c > oldpos )
    11229 {
    11230 if( !chooseBasic || !SCIPsetIsIntegral(set, primsol[c]) ) /*lint !e613*/
    11231 pos = c;
    11232 }
    11233 }
    11234 else
    11235 {
    11236 /* reduced cost == 0 -> possible candidate */
    11237 if( SCIPsetIsDualfeasZero(set, redcost[c]) )
    11238 {
    11239 ++nDualDeg;
    11240 /* only if we have not yet found a candidate */
    11241 if( pos == -1 && c > oldpos )
    11242 {
    11243 /* if the variable is at its lower bound - fix it, because its value cannot be reduced */
    11244 if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_LOWER )
    11245 {
    11246 newlb[cntcol] = oldlb[c];
    11247 newub[cntcol] = oldlb[c];
    11248 indcol[cntcol++] = c;
    11249 fixedc[c] = TRUE;
    11250 }
    11251 else /* found a non-fixed candidate */
    11252 {
    11253 if( !chooseBasic )
    11254 pos = c;
    11255 }
    11256 }
    11257 }
    11258 else
    11259 {
    11260 /* nonzero reduced cost -> variable can be fixed */
    11261 if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_LOWER )
    11262 {
    11263 newlb[cntcol] = oldlb[c];
    11264 newub[cntcol] = oldlb[c];
    11265 }
    11266 else
    11267 {
    11268 if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_UPPER )
    11269 {
    11270 newlb[cntcol] = oldub[c];
    11271 newub[cntcol] = oldub[c];
    11272 }
    11273 else
    11274 {
    11275 assert((SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_ZERO);
    11276 newlb[cntcol] = 0.0;
    11277 newub[cntcol] = 0.0;
    11278 }
    11279 }
    11280 indcol[cntcol++] = c;
    11281 fixedc[c] = TRUE;
    11282 }
    11283 }
    11284 }
    11285 }
    11286
    11287 /* check rows */
    11288 cntrow = 0;
    11289 for( r = 0; r < lp->nlpirows; ++r )
    11290 {
    11291 if( !fixedr[r] )
    11292 {
    11293 /* consider only nonbasic rows */
    11294 if( (SCIP_BASESTAT) rstat[r] != SCIP_BASESTAT_BASIC )
    11295 {
    11296 assert((SCIP_BASESTAT) rstat[r] != SCIP_BASESTAT_ZERO);
    11297 if( SCIPsetIsFeasZero(set, dualsol[r]) )
    11298 ++nDualDeg;
    11299 else
    11300 {
    11301 if( SCIPsetIsFeasPositive(set, dualsol[r]) )
    11302 {
    11303 assert(!SCIPsetIsInfinity(set, -oldlhs[r]));
    11304 newlhs[cntrow] = oldlhs[r];
    11305 newrhs[cntrow] = oldlhs[r];
    11306 }
    11307 else
    11308 {
    11309 assert(!SCIPsetIsInfinity(set, oldrhs[r]));
    11310 newlhs[cntrow] = oldrhs[r];
    11311 newrhs[cntrow] = oldrhs[r];
    11312 }
    11313 indrow[cntrow++] = r;
    11314 fixedr[r] = TRUE;
    11315 }
    11316 }
    11317 }
    11318 }
    11319
    11320 if( nDualDeg > 0 && pos >= 0 )
    11321 {
    11322 assert(0 <= pos && pos < lp->nlpicols && pos > oldpos);
    11323
    11324 /* change objective */
    11325 if( nruns == 0 )
    11326 {
    11327 /* set objective to appropriate unit vector for first run */
    11328 newobj[pos] = 1.0;
    11329 SCIP_CALL( SCIPlpiChgObj(lp->lpi, lp->nlpicols, indallcol, newobj) );
    11330 }
    11331 else
    11332 {
    11333 /* set obj. coef. to 1 for other runs (ones remain in previous positions) */
    11334 SCIP_Real obj = 1.0;
    11335 SCIP_CALL( SCIPlpiChgObj(lp->lpi, 1, &pos, &obj) );
    11336 }
    11337
    11338 /* fix variables */
    11339 SCIP_CALL( SCIPlpiChgBounds(lp->lpi, cntcol, indcol, newlb, newub) );
    11340 SCIP_CALL( SCIPlpiChgSides(lp->lpi, cntrow, indrow, newlhs, newrhs) );
    11341
    11342 /* solve with primal simplex, because we are primal feasible, but not necessarily dual feasible */
    11343 retcode = SCIPlpiSolvePrimal(lp->lpi);
    11344 if( retcode == SCIP_LPERROR )
    11345 {
    11346 *lperror = TRUE;
    11347 SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") in lex-dual: primal simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
    11348 }
    11349 else
    11350 {
    11351 SCIP_CALL( retcode );
    11352 }
    11353 SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
    11354 lexIterations += iterations;
    11355
    11356 if( iterations > 0 )
    11357 {
    11358#ifdef DEBUG_LEXDUAL
    11359 int j;
    11360
    11361 if( !chooseBasic )
    11362 {
    11363 assert(primsol == NULL);
    11364 SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
    11365 }
    11366 assert(primsol != NULL);
    11367 SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, NULL, NULL) );
    11368
    11369 for( j = 0; j < lp->nlpicols; ++j )
    11370 {
    11371 if( fixedc[j] )
    11372 {
    11373 SCIPsetDebugMsg(set, "%f (%d) [f] ", primsol[j], j);
    11374 }
    11375 else
    11376 {
    11377 char cstart = '[';
    11378 char cend = ']';
    11379 char type;
    11380
    11381 if(j == pos)
    11382 {
    11383 cstart = '*';
    11384 cend = '*';
    11385 }
    11386
    11387 switch( (SCIP_BASESTAT) cstat[j] )
    11388 {
    11390 type = 'l';
    11391 break;
    11393 type = 'u';
    11394 break;
    11395 case SCIP_BASESTAT_ZERO:
    11396 type = 'z';
    11397 break;
    11399 type = 'b';
    11400 break;
    11401 default:
    11402 type = '?';
    11403 SCIPerrorMessage("unknown base state %d\n", cstat[j]);
    11404 SCIPABORT();
    11405 }
    11406 SCIPsetDebugMsg(set, "%f (%d) %c%c%c ", primsol[j], j, cstart, type, cend);
    11407 }
    11408 }
    11409 SCIPsetDebugMsg(set, "\n\n");
    11410
    11411 if( !chooseBasic )
    11412 {
    11413 SCIPsetFreeBufferArray(set, &primsol);
    11414 assert(primsol == NULL);
    11415 }
    11416#endif
    11417
    11418 /* count only as round if iterations have been performed */
    11419 ++rounds;
    11420 }
    11421
    11422 ++nruns;
    11423 }
    11424 }
    11425 while( pos >= 0 && nDualDeg > 0 && (set->lp_lexdualmaxrounds == -1 || rounds < set->lp_lexdualmaxrounds) );
    11426
    11427 /* reset bounds, lhs/rhs, and obj */
    11428 SCIP_CALL( SCIPlpiChgBounds(lp->lpi, lp->nlpicols, indallcol, oldlb, oldub) );
    11429 SCIP_CALL( SCIPlpiChgSides(lp->lpi, lp->nlpirows, indallrow, oldlhs, oldrhs) );
    11430 SCIP_CALL( SCIPlpiChgObj(lp->lpi, lp->nlpicols, indallcol, oldobj) );
    11431
    11432 /* resolve to update solvers internal data structures - should only produce few pivots */
    11433 retcode = SCIPlpiSolveDual(lp->lpi);
    11434 if( retcode == SCIP_LPERROR )
    11435 {
    11436 *lperror = TRUE;
    11437 SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
    11438 }
    11439 else
    11440 {
    11441 SCIP_CALL( retcode );
    11442 }
    11443 assert(SCIPlpiIsOptimal(lp->lpi));
    11444
    11445 /* reset objective limit */
    11446 SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_OBJLIM, lp->lpiobjlim, &success) );
    11447 assert(success);
    11448
    11449 /* add LP iterations */
    11450 SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
    11451 lexIterations += iterations;
    11452
    11453 /* SCIP_CALL( lpSetLPInfo(lp, set->disp_lpinfo) ); */
    11454
    11455 /* count number of iterations */
    11456 if( totalIterations == 0 && lexIterations > 0 && !lp->strongbranchprobing )
    11457 SCIPstatIncrement(stat, set, nlps);
    11458
    11459 if( lexIterations > 0 ) /* don't count the resolves after removing unused columns/rows */
    11460 {
    11461 SCIPstatAdd(stat, set, nlpiterations, lexIterations);
    11462 if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
    11463 {
    11464 SCIPstatIncrement(stat, set, nlexdualresolvelps);
    11465 SCIPstatAdd(stat, set, nlexdualresolvelpiterations, lexIterations);
    11466 }
    11467 SCIPstatIncrement(stat, set, nlexduallps);
    11468 SCIPstatAdd(stat, set, nlexduallpiterations, lexIterations);
    11469
    11470 totalIterations += lexIterations;
    11471 }
    11472
    11473 /* free space */
    11474 SCIPsetFreeBufferArray(set, &newobj);
    11475
    11476 SCIPsetFreeBufferArray(set, &fixedr);
    11477 SCIPsetFreeBufferArray(set, &fixedc);
    11478
    11479 SCIPsetFreeBufferArray(set, &indallrow);
    11480 SCIPsetFreeBufferArray(set, &indallcol);
    11481
    11482 SCIPsetFreeBufferArray(set, &indrow);
    11483 SCIPsetFreeBufferArray(set, &newrhs);
    11484 SCIPsetFreeBufferArray(set, &newlhs);
    11485
    11486 SCIPsetFreeBufferArray(set, &indcol);
    11487 SCIPsetFreeBufferArray(set, &newub);
    11488 SCIPsetFreeBufferArray(set, &newlb);
    11489
    11490 SCIPsetFreeBufferArray(set, &oldobj);
    11491 SCIPsetFreeBufferArray(set, &oldrhs);
    11492 SCIPsetFreeBufferArray(set, &oldlhs);
    11493 SCIPsetFreeBufferArray(set, &oldub);
    11494 SCIPsetFreeBufferArray(set, &oldlb);
    11495
    11496 SCIPsetFreeBufferArray(set, &rstat);
    11497 SCIPsetFreeBufferArray(set, &cstat);
    11498
    11499 SCIPsetFreeBufferArray(set, &redcost);
    11500 SCIPsetFreeBufferArray(set, &dualsol);
    11501 if( chooseBasic )
    11502 SCIPsetFreeBufferArray(set, &primsol);
    11503
    11504 /* stop timing */
    11506
    11507 SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with lex dual simplex (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
    11508 stat->lpcount, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
    11509 }
    11511 lp->solisbasic = TRUE;
    11512
    11513 if( totalIterations > 0 && !lp->strongbranchprobing )
    11514 SCIPstatIncrement(stat, set, nlps);
    11515 else
    11516 {
    11517 if( keepsol && !(*lperror) )
    11518 {
    11519 /* the solution didn't change: if the solution was valid before resolve, it is still valid */
    11520 if( lp->validsollp == stat->lpcount-1 )
    11521 lp->validsollp = stat->lpcount;
    11522 if( lp->validfarkaslp == stat->lpcount-1 )
    11523 lp->validfarkaslp = stat->lpcount;
    11524 }
    11525 }
    11526
    11527 return SCIP_OKAY;
    11528}
    11529
    11530/** calls LPI to perform barrier, measures time and counts iterations, gets basis feasibility status */
    11531static
    11533 SCIP_LP* lp, /**< current LP data */
    11534 SCIP_SET* set, /**< global SCIP settings */
    11535 SCIP_STAT* stat, /**< problem statistics */
    11536 SCIP_Bool crossover, /**< should crossover be performed? */
    11537 SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
    11538 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
    11539 )
    11540{
    11541 SCIP_Real timedelta;
    11542 SCIP_RETCODE retcode;
    11543 int iterations;
    11544
    11545 assert(lp != NULL);
    11546 assert(lp->flushed);
    11547 assert(set != NULL);
    11548 assert(stat != NULL);
    11549 assert(lperror != NULL);
    11550
    11551 SCIPsetDebugMsg(set, "solving LP %" SCIP_LONGINT_FORMAT " (%d cols, %d rows) with barrier%s (diving=%d, nbarrierlps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
    11552 stat->lpcount+1, lp->ncols, lp->nrows, crossover ? "/crossover" : "", lp->diving || lp->probing,
    11553 stat->nbarrierlps, stat->ndivinglps);
    11554
    11555 *lperror = FALSE;
    11556
    11557#ifdef SCIP_MORE_DEBUG /* for debugging: write all root node LP's */
    11558 if( stat->nnodes == 1 && !lp->diving && !lp->probing )
    11559 {
    11560 char fname[SCIP_MAXSTRLEN];
    11561 (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
    11562 SCIP_CALL( SCIPlpWrite(lp, fname) );
    11563 SCIPsetDebugMsg(set, "wrote LP to file <%s> (barrier, objlim=%.15g, feastol=%.15g/%.15g, convtol=%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
    11564 fname, lp->lpiobjlim, lp->lpifeastol, lp->lpidualfeastol, lp->lpibarrierconvtol,
    11566 }
    11567#endif
    11568
    11569 /* start timing */
    11570 if( lp->diving || lp->probing )
    11571 {
    11572 if( lp->strongbranchprobing )
    11574 else
    11576
    11577 timedelta = 0.0; /* unused for diving or probing */
    11578 }
    11579 else
    11580 {
    11582 timedelta = -SCIPclockGetTime(stat->barrierlptime);
    11583 }
    11584
    11585 /* call barrier algorithm */
    11586 retcode = SCIPlpiSolveBarrier(lp->lpi, crossover);
    11587 if( retcode == SCIP_LPERROR )
    11588 {
    11589 *lperror = TRUE;
    11590 SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") barrier solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
    11591 }
    11592 else
    11593 {
    11594 SCIP_CALL( retcode );
    11595 }
    11597 lp->solisbasic = crossover;
    11598
    11599 /* stop timing */
    11600 if( lp->diving || lp->probing )
    11601 {
    11602 if( lp->strongbranchprobing )
    11604 else
    11606 }
    11607 else
    11608 {
    11610 timedelta += SCIPclockGetTime(stat->barrierlptime);
    11611 }
    11612
    11613 /* count number of iterations */
    11614 SCIPstatIncrement(stat, set, lpcount);
    11615 SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
    11616 if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
    11617 {
    11618 if( !lp->strongbranchprobing )
    11619 {
    11620 SCIPstatIncrement(stat, set, nlps);
    11621 SCIPstatAdd(stat, set, nlpiterations, iterations);
    11622 }
    11623 if( lp->diving || lp->probing )
    11624 {
    11625 if( lp->strongbranchprobing )
    11626 {
    11627 SCIPstatIncrement(stat, set, nsbdivinglps);
    11628 SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
    11629 }
    11630 else
    11631 {
    11632 SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
    11633 SCIPstatIncrement(stat, set, ndivinglps);
    11634 SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
    11635 }
    11636 }
    11637 else
    11638 {
    11639 SCIPstatIncrement(stat, set, nbarrierlps);
    11640 SCIPstatAdd(stat, set, nbarrierlpiterations, iterations);
    11641 }
    11642 }
    11643 else
    11644 {
    11645 if ( ! lp->diving && ! lp->probing )
    11646 {
    11647 SCIPstatIncrement(stat, set, nbarrierzeroitlps);
    11648 SCIPstatAdd(stat, set, barrierzeroittime, timedelta);
    11649 }
    11650
    11651 if( keepsol && !(*lperror) )
    11652 {
    11653 /* the solution didn't change: if the solution was valid before resolve, it is still valid */
    11654 if( lp->validsollp == stat->lpcount-1 )
    11655 lp->validsollp = stat->lpcount;
    11656 if( lp->validfarkaslp == stat->lpcount-1 )
    11657 lp->validfarkaslp = stat->lpcount;
    11658 }
    11659 }
    11660
    11661 SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with barrier%s (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", nbarrierlps=%" SCIP_LONGINT_FORMAT ")\n",
    11662 stat->lpcount, crossover ? "/crossover" : "", lp->diving || lp->probing, stat->nbarrierlps, stat->ndivinglps);
    11663
    11664 return SCIP_OKAY;
    11665}
    11666
    11667/** solves the LP with the given algorithm */
    11668static
    11670 SCIP_LP* lp, /**< current LP data */
    11671 SCIP_SET* set, /**< global SCIP settings */
    11672 SCIP_STAT* stat, /**< problem statistics */
    11673 SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
    11674 SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
    11675 SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
    11676 SCIP_Bool instable, /**< is this a resolving call to avoid instable LPs? */
    11677 SCIP_Bool* timelimit, /**< pointer to store whether the time limit was hit */
    11678 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
    11679 )
    11680{
    11681 SCIP_Real lptimelimit;
    11682 SCIP_Bool success;
    11683
    11684 assert(lp != NULL);
    11685 assert(lp->flushed);
    11686 assert(lperror != NULL);
    11687
    11688 /* check if a time limit is set, and set time limit for LP solver accordingly */
    11689 lptimelimit = SCIPlpiInfinity(lp->lpi);
    11690 if( set->istimelimitfinite )
    11691 lptimelimit = set->limit_time - SCIPclockGetTime(stat->solvingtime);
    11692
    11693 success = FALSE;
    11694 if( lptimelimit > 0.0 )
    11695 SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_LPTILIM, lptimelimit, &success) );
    11696
    11697 if( lptimelimit <= 0.0 || !success )
    11698 {
    11699 SCIPsetDebugMsg(set, "time limit of %f seconds could not be set\n", lptimelimit);
    11700 *lperror = ((lptimelimit > 0.0) ? TRUE : FALSE);
    11701 *timelimit = TRUE;
    11702 return SCIP_OKAY;
    11703 }
    11704 SCIPsetDebugMsg(set, "calling LP algorithm <%s> with a time limit of %g seconds\n", lpalgoName(lpalgo), lptimelimit);
    11705
    11706 /* call appropriate LP algorithm */
    11707 switch( lpalgo )
    11708 {
    11710 SCIP_CALL( lpPrimalSimplex(lp, set, stat, resolve, keepsol, instable, lperror) );
    11711 break;
    11712
    11714 /* run dual lexicographic simplex if required */
    11715 if( set->lp_lexdualalgo && (!set->lp_lexdualrootonly || stat->maxdepth == 0) && (!set->lp_lexdualstalling || lp->installing) )
    11716 {
    11717 SCIP_CALL( lpLexDualSimplex(lp, set, stat, resolve, keepsol, lperror) );
    11718 }
    11719 else
    11720 {
    11721 SCIP_CALL( lpDualSimplex(lp, set, stat, resolve, keepsol, instable, lperror) );
    11722 }
    11723 break;
    11724
    11726 SCIP_CALL( lpBarrier(lp, set, stat, FALSE, keepsol, lperror) );
    11727 break;
    11728
    11730 SCIP_CALL( lpBarrier(lp, set, stat, TRUE, keepsol, lperror) );
    11731 break;
    11732
    11733 default:
    11734 SCIPerrorMessage("invalid LP algorithm\n");
    11735 return SCIP_INVALIDDATA;
    11736 }
    11737
    11738 if( !(*lperror) )
    11739 {
    11740 /* check for primal and dual feasibility */
    11742
    11743 SCIPsetDebugMsg(set, "LP feasibility: primalfeasible=%u, dualfeasible=%u\n", lp->primalfeasible, lp->dualfeasible);
    11744 }
    11745
    11746 return SCIP_OKAY;
    11747}
    11748
    11749/** maximal number of verblevel-high messages about numerical trouble in LP that will be printed
    11750 * when this number is reached and display/verblevel is not full, then further messages are suppressed in this run
    11751 */
    11752#define MAXNUMTROUBLELPMSGS 10
    11753
    11754/** prints message about numerical trouble
    11755 *
    11756 * If message has verblevel at most high and display/verblevel is not full,
    11757 * then the message is not printed if already MAXNUMTROUBLELPMSGS messages
    11758 * were printed before in the current run.
    11759 */
    11760static
    11762 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    11763 SCIP_SET* set, /**< global SCIP settings */
    11764 SCIP_STAT* stat, /**< problem statistics */
    11765 SCIP_VERBLEVEL verblevel, /**< verbosity level of message */
    11766 const char* formatstr, /**< message format string */
    11767 ... /**< arguments to format string */
    11768 )
    11769{
    11770 va_list ap;
    11771
    11772 assert(verblevel > SCIP_VERBLEVEL_NONE);
    11773 assert(verblevel <= SCIP_VERBLEVEL_FULL);
    11774 assert(set->disp_verblevel <= SCIP_VERBLEVEL_FULL);
    11775
    11776 if( set->disp_verblevel < SCIP_VERBLEVEL_FULL )
    11777 {
    11778 if( verblevel <= SCIP_VERBLEVEL_HIGH )
    11779 {
    11780 /* if already max number of messages about numerical trouble in LP on verblevel at most high, then skip message */
    11782 return;
    11783
    11784 /* increase count on messages with verblevel high */
    11785 ++stat->nnumtroublelpmsgs ;
    11786 }
    11787
    11788 /* if messages wouldn't be printed, then return already */
    11789 if( verblevel > set->disp_verblevel )
    11790 return;
    11791 }
    11792
    11793 /* print common begin of message */
    11794 SCIPmessagePrintInfo(messagehdlr,
    11795 "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- ",
    11796 stat->nnodes, stat->nlps);
    11797
    11798 /* print individual part of message */
    11799 va_start(ap, formatstr); /*lint !e838*/
    11800 SCIPmessageVFPrintInfo(messagehdlr, NULL, formatstr, ap);
    11801 va_end(ap);
    11802
    11803 /* warn that further messages will be suppressed */
    11804 if( set->disp_verblevel < SCIP_VERBLEVEL_FULL && verblevel <= SCIP_VERBLEVEL_HIGH && stat->nnumtroublelpmsgs > MAXNUMTROUBLELPMSGS )
    11805 {
    11806 SCIPmessagePrintInfo(messagehdlr, " -- further messages will be suppressed (use display/verblevel=5 to see all)");
    11807 }
    11808
    11809 /* print closing new-line */
    11810 SCIPmessagePrintInfo(messagehdlr, "\n");
    11811}
    11812
    11813static
    11815 SCIP_LP* lp, /**< current LP data */
    11816 SCIP_SET* set, /**< global SCIP settings */
    11817 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    11818 SCIP_STAT* stat, /**< problem statistics */
    11819 SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
    11820 SCIP_Bool* success /**< was instability successfully ignored */
    11821 )
    11822{
    11823 assert(lp != NULL);
    11824 assert(set != NULL);
    11825
    11826 SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, success) );
    11827
    11828 if( *success )
    11829 {
    11830 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
    11831 if( !set->lp_checkdualfeas )
    11832 lp->dualfeasible = TRUE;
    11833 if( !set->lp_checkprimfeas )
    11834 lp->primalchecked = TRUE;
    11835 }
    11836
    11837 return SCIP_OKAY;
    11838}
    11839
    11840#define FEASTOLTIGHTFAC 0.001
    11841/** solves the LP with the given LP algorithm, and tries to resolve numerical problems */
    11842static
    11844 SCIP_LP* lp, /**< current LP data */
    11845 SCIP_SET* set, /**< global SCIP settings */
    11846 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    11847 SCIP_STAT* stat, /**< problem statistics */
    11848 SCIP_PROB* prob, /**< problem data */
    11849 SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
    11850 int itlim, /**< maximal number of LP iterations to perform in first LP calls (before solving from scratch), or -1 for no limit */
    11851 int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
    11852 SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
    11853 int fastmip, /**< which FASTMIP setting of LP solver should be used? */
    11854 SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
    11855 SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
    11856 SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
    11857 int scaling, /**< LP scaling (0: none, 1: normal, 2: aggressive) */
    11858 SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
    11859 SCIP_Bool* timelimit, /**< pointer to store whether the time limit was hit */
    11860 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
    11861 )
    11862{
    11863 SCIP_Bool success;
    11864 SCIP_Bool success2;
    11865 SCIP_Bool success3;
    11866 SCIP_Bool simplex;
    11867 SCIP_Bool itlimishard;
    11868 SCIP_Bool usepolishing;
    11869
    11870 assert(lp != NULL);
    11871 assert(lp->flushed);
    11872 assert(set != NULL);
    11873 assert(stat != NULL);
    11874 assert(lperror != NULL);
    11875 assert(timelimit != NULL);
    11876
    11877 *lperror = FALSE;
    11878
    11879 /**@todo implement solving the LP when loose variables with infinite best bound are present; for this, we need to
    11880 * solve with deactivated objective limit in order to determine whether we are (a) infeasible or (b) feasible
    11881 * and hence unbounded; to handle case (b) we need to store an array of loose variables with best bound in
    11882 * SCIP_LP such that we can return a primal ray
    11883 */
    11884 if( lp->looseobjvalinf > 0 )
    11885 {
    11886 SCIPerrorMessage("cannot solve LP when loose variable with infinite best bound is present\n");
    11887 return SCIP_ERROR;
    11888 }
    11889
    11890 /* check, whether we solve with a simplex algorithm */
    11891 simplex = (lpalgo == SCIP_LPALGO_PRIMALSIMPLEX || lpalgo == SCIP_LPALGO_DUALSIMPLEX);
    11892
    11893 /* check whether the iteration limit is a hard one */
    11894 itlimishard = (itlim == harditlim);
    11895
    11896 /* check whether solution polishing should be used */
    11897 if( lp->lpihaspolishing && (set->lp_solutionpolishing == 2 || (set->lp_solutionpolishing == 1 && stat->nnodes == 1 && !lp->probing)
    11898 || (set->lp_solutionpolishing == 3 && ((lp->probing && !lp->strongbranchprobing) || lp->diving))) )
    11899 {
    11900 usepolishing = TRUE;
    11901 if( lp->updateintegrality )
    11902 {
    11904 }
    11905 }
    11906 else
    11907 usepolishing = FALSE;
    11908
    11909 /* solve with given settings (usually fast but imprecise) */
    11911 {
    11912 SCIP_CALL( lpSetObjlim(lp, set, prob, lp->cutoffbound, &success) );
    11913 }
    11914 else
    11915 {
    11916 SCIP_CALL( lpSetObjlim(lp, set, prob, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob), &success) );
    11917 SCIP_CALL( lpAdjustObjlimForExactSolve(lp, set, prob, stat, &success) );
    11918 }
    11919 SCIP_CALL( lpSetIterationLimit(lp, itlim) );
    11920 SCIP_CALL( lpSetFeastol(lp, tightprimfeastol ? FEASTOLTIGHTFAC * lp->feastol : lp->feastol, &success) );
    11922 &success) );
    11923 SCIP_CALL( lpSetBarrierconvtol(lp, (tightprimfeastol || tightdualfeastol) ? FEASTOLTIGHTFAC * SCIPsetBarrierconvtol(set)
    11924 : SCIPsetBarrierconvtol(set), &success) );
    11925 SCIP_CALL( lpSetFromscratch(lp, fromscratch, &success) );
    11926 SCIP_CALL( lpSetFastmip(lp, fastmip, &success) );
    11927 SCIP_CALL( lpSetScaling(lp, scaling, &success) );
    11928 SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
    11929 SCIP_CALL( lpSetRowrepswitch(lp, set->lp_rowrepswitch, &success) );
    11930 SCIP_CALL( lpSetPricingChar(lp, set->lp_pricing) );
    11931 SCIP_CALL( lpSetThreads(lp, set->lp_threads, &success) );
    11932 SCIP_CALL( lpSetLPInfo(lp, set->disp_lpinfo) );
    11933 SCIP_CALL( lpSetConditionLimit(lp, set->lp_conditionlimit, &success) );
    11934 SCIP_CALL( lpSetMarkowitz(lp, set->lp_markowitz, &success) );
    11935 SCIP_CALL( lpSetTiming(lp, set->time_clocktype, set->time_enabled, &success) );
    11936 SCIP_CALL( lpSetRandomseed(lp, (int) (SCIPsetInitializeRandomSeed(set, (unsigned) set->random_randomseed) % INT_MAX), &success) );
    11937 SCIP_CALL( lpSetSolutionPolishing(lp, usepolishing, &success) );
    11938 SCIP_CALL( lpSetRefactorInterval(lp, set->lp_refactorinterval, &success) );
    11939
    11940 SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, FALSE, timelimit, lperror) );
    11941
    11942 /* after the first solve, do not use starting basis, since otherwise the solver will probably think the basis is
    11943 * optimal without preforming scaling/change tolerances/presolving */
    11944 resolve = FALSE;
    11945
    11946 /* check for stability; iteration limit exceeded is also treated like instability if the iteration limit is soft */
    11947 if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
    11948 return SCIP_OKAY;
    11949
    11950 if( !set->lp_checkstability )
    11951 {
    11952 SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
    11953
    11954 if( success )
    11955 return SCIP_OKAY;
    11956 }
    11957
    11958 /* In the following, whenever the LP iteration limit is exceeded in an LP solving call, we leave out the
    11959 * remaining resolving calls with changed settings and go directly to solving the LP from scratch.
    11960 */
    11961
    11962 /* if FASTMIP is turned on, solve again without FASTMIP (starts from the solution of the last LP solving call);
    11963 * do this only if the iteration limit was not exceeded in the last LP solving call
    11964 */
    11965 if( fastmip > 0 && simplex && ((*lperror) || !SCIPlpiIsIterlimExc(lp->lpi)) )
    11966 {
    11967 SCIP_CALL( lpSetFastmip(lp, 0, &success) );
    11968 if( success )
    11969 {
    11970 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s without FASTMIP", lpalgoName(lpalgo));
    11971 SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
    11972
    11973 /* check for stability */
    11974 if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
    11975 return SCIP_OKAY;
    11976
    11977 if( !set->lp_checkstability )
    11978 {
    11979 SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
    11980
    11981 if( success )
    11982 return SCIP_OKAY;
    11983 }
    11984 }
    11985 }
    11986
    11987 /* if the iteration limit was exceeded in the last LP solving call, we leave out the remaining resolving calls with changed settings
    11988 * and go directly to solving the LP from scratch
    11989 */
    11990 if( (*lperror) || !SCIPlpiIsIterlimExc(lp->lpi) )
    11991 {
    11992 /* solve again with opposite scaling setting (starts from the solution of the last LP solving call) */
    11993 SCIP_CALL( lpSetScaling(lp, (scaling > 0) ? 0 : 1, &success) );
    11994 if( success )
    11995 {
    11996 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s %s scaling",
    11997 lpalgoName(lpalgo), (scaling == 0) ? "with" : "without");
    11998 SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
    11999
    12000 /* check for stability */
    12001 if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
    12002 return SCIP_OKAY;
    12003
    12004 if( !set->lp_checkstability )
    12005 {
    12006 SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
    12007
    12008 if( success )
    12009 return SCIP_OKAY;
    12010 }
    12011
    12012 /* reset scaling */
    12013 SCIP_CALL( lpSetScaling(lp, scaling, &success) );
    12014 assert(success);
    12015 }
    12016 }
    12017
    12018 /* if the iteration limit was exceeded in the last LP solving call, we leave out the remaining resolving calls with changed settings
    12019 * and go directly to solving the LP from scratch */
    12020 if( (*lperror) || !SCIPlpiIsIterlimExc(lp->lpi) )
    12021 {
    12022 /* solve again with opposite presolving setting (starts from the solution of the last LP solving call) */
    12023 SCIP_CALL( lpSetPresolving(lp, !set->lp_presolving, &success) );
    12024 if( success )
    12025 {
    12026 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s %s presolving",
    12027 lpalgoName(lpalgo), !set->lp_presolving ? "with" : "without");
    12028 SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
    12029
    12030 /* check for stability */
    12031 if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
    12032 return SCIP_OKAY;
    12033
    12034 if( !set->lp_checkstability )
    12035 {
    12036 SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
    12037
    12038 if( success )
    12039 return SCIP_OKAY;
    12040 }
    12041
    12042 /* reset presolving */
    12043 SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
    12044 assert(success);
    12045 }
    12046 }
    12047
    12048 /* solve again with a tighter feasibility tolerance (starts from the solution of the last LP solving call);
    12049 * do this only if the iteration limit was not exceeded in the last LP solving call
    12050 */
    12051 if( ((simplex && (!tightprimfeastol || !tightdualfeastol)) || (!tightprimfeastol && !tightdualfeastol)) &&
    12052 ((*lperror) || !SCIPlpiIsIterlimExc(lp->lpi)) )
    12053 {
    12054 success = FALSE;
    12055 if( !tightprimfeastol )
    12056 {
    12057 SCIP_CALL( lpSetFeastol(lp, FEASTOLTIGHTFAC * lp->feastol, &success) );
    12058 }
    12059
    12060 success2 = FALSE;
    12061 if( !tightdualfeastol )
    12062 {
    12064 }
    12065
    12066 success3 = FALSE;
    12067 if( !simplex && !tightprimfeastol && !tightdualfeastol )
    12068 {
    12070 }
    12071
    12072 /* only resolve if at least one of the parameters was actually changed in the LP solver */
    12073 if( success || success2 || success3 )
    12074 {
    12075 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s with tighter primal and dual feasibility tolerance",
    12076 lpalgoName(lpalgo));
    12077 SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
    12078
    12079 /* check for stability */
    12080 if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
    12081 return SCIP_OKAY;
    12082
    12083 if( !set->lp_checkstability )
    12084 {
    12085 SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
    12086
    12087 if( success )
    12088 return SCIP_OKAY;
    12089 }
    12090
    12091 /* reset feasibility tolerance */
    12092 if( !tightprimfeastol )
    12093 {
    12094 SCIP_CALL( lpSetFeastol(lp, lp->feastol, &success) );
    12095 }
    12096 if( !tightdualfeastol )
    12097 {
    12099 }
    12100 if( !simplex && !tightprimfeastol && !tightdualfeastol )
    12101 {
    12103 }
    12104 }
    12105 }
    12106
    12107 /* all LPs solved after this point are solved from scratch, so set the LP iteration limit to the hard limit;
    12108 * the given iteration limit might be a soft one to restrict resolving calls only */
    12109 SCIP_CALL( lpSetIterationLimit(lp, harditlim) );
    12110
    12111 /* if not already done, solve again from scratch */
    12112 if( !fromscratch && simplex )
    12113 {
    12114 SCIP_CALL( lpSetFromscratch(lp, TRUE, &success) );
    12115 if( success )
    12116 {
    12117 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s", lpalgoName(lpalgo));
    12118 SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
    12119
    12120 /* check for stability */
    12121 if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
    12122 return SCIP_OKAY;
    12123
    12124 if( !set->lp_checkstability )
    12125 {
    12126 SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
    12127
    12128 if( success )
    12129 return SCIP_OKAY;
    12130 }
    12131 }
    12132 }
    12133
    12134 /* solve again, use other simplex this time */
    12135 if( simplex )
    12136 {
    12138 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s", lpalgoName(lpalgo));
    12139 SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
    12140
    12141 /* check for stability */
    12142 if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
    12143 return SCIP_OKAY;
    12144
    12145 if( !set->lp_checkstability )
    12146 {
    12147 SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
    12148
    12149 if( success )
    12150 return SCIP_OKAY;
    12151 }
    12152
    12153 /* solve again with opposite scaling and other simplex */
    12154 SCIP_CALL( lpSetScaling(lp, (scaling > 0) ? 0 : 1, &success) );
    12155 if( success )
    12156 {
    12157 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s %s scaling",
    12158 lpalgoName(lpalgo), (scaling == 0) ? "with" : "without");
    12159 SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
    12160
    12161 /* check for stability */
    12162 if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
    12163 return SCIP_OKAY;
    12164
    12165 if( !set->lp_checkstability )
    12166 {
    12167 SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
    12168
    12169 if( success )
    12170 return SCIP_OKAY;
    12171 }
    12172
    12173 /* reset scaling */
    12174 SCIP_CALL( lpSetScaling(lp, scaling, &success) );
    12175 assert(success);
    12176 }
    12177
    12178 /* solve again with opposite presolving and other simplex */
    12179 SCIP_CALL( lpSetPresolving(lp, !set->lp_presolving, &success) );
    12180 if( success )
    12181 {
    12182 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s %s presolving",
    12183 lpalgoName(lpalgo), !set->lp_presolving ? "with" : "without");
    12184 SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
    12185
    12186 /* check for stability */
    12187 if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
    12188 return SCIP_OKAY;
    12189
    12190 if( !set->lp_checkstability )
    12191 {
    12192 SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
    12193
    12194 if( success )
    12195 return SCIP_OKAY;
    12196 }
    12197
    12198 /* reset presolving */
    12199 SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
    12200 assert(success);
    12201 }
    12202
    12203 /* solve again with tighter feasibility tolerance, use other simplex this time */
    12204 if( !tightprimfeastol || !tightdualfeastol )
    12205 {
    12206 success = FALSE;
    12207 if( !tightprimfeastol )
    12208 {
    12209 SCIP_CALL( lpSetFeastol(lp, FEASTOLTIGHTFAC * lp->feastol, &success) );
    12210 }
    12211
    12212 success2 = FALSE;
    12213 if( !tightdualfeastol )
    12214 {
    12216 }
    12217
    12218 /* only resolve if at least one of the parameters was actually changed in the LP solver */
    12219 if( success || success2 )
    12220 {
    12221 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s with tighter feasibility tolerance",
    12222 lpalgoName(lpalgo));
    12223 SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
    12224
    12225 /* check for stability */
    12226 if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
    12227 return SCIP_OKAY;
    12228
    12229 if( !set->lp_checkstability )
    12230 {
    12231 SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
    12232
    12233 if( success )
    12234 return SCIP_OKAY;
    12235 }
    12236
    12237 /* reset feasibility tolerance */
    12238 if( !tightprimfeastol )
    12239 {
    12240 SCIP_CALL( lpSetFeastol(lp, lp->feastol, &success) );
    12241 }
    12242 if( !tightdualfeastol )
    12243 {
    12245 }
    12246 SCIP_UNUSED(success);
    12247 }
    12248 }
    12249 }
    12250
    12251 /* nothing worked -- exit with an LPERROR */
    12252 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_HIGH, "unresolved");
    12253 *lperror = TRUE;
    12254
    12255 return SCIP_OKAY;
    12256}
    12257
    12258/** adjust the LP objective value if it is greater/less than +/- SCIPsetInfinity() */
    12259static
    12261 SCIP_LP* lp, /**< current LP data */
    12262 SCIP_SET* set, /**< global SCIP settings */
    12263 SCIP_MESSAGEHDLR* messagehdlr /**< message handler */
    12264 )
    12265{
    12266 assert(lp != NULL);
    12267 assert(set != NULL);
    12268
    12269 if( SCIPsetIsInfinity(set, lp->lpobjval) && lp->lpobjval != SCIPsetInfinity(set) ) /*lint !e777*/
    12270 {
    12271 if( !lp->adjustlpval && messagehdlr != NULL )
    12272 {
    12273 SCIPmessagePrintWarning(messagehdlr, "LP solution value is above SCIP's infinity value\n");
    12274 lp->adjustlpval = TRUE;
    12275 }
    12277 }
    12278 else if( SCIPsetIsInfinity(set, -lp->lpobjval) && lp->lpobjval != -SCIPsetInfinity(set) ) /*lint !e777*/
    12279 {
    12280 if( !lp->adjustlpval && messagehdlr != NULL )
    12281 {
    12282 SCIPmessagePrintWarning(messagehdlr, "LP solution value is below SCIP's -infinity value\n");
    12283 lp->adjustlpval = TRUE;
    12284 }
    12286 }
    12287}
    12288
    12289/** solves the LP with the given algorithm and evaluates return status */
    12290static
    12292 SCIP_LP* lp, /**< current LP data */
    12293 SCIP_SET* set, /**< global SCIP settings */
    12294 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    12295 SCIP_STAT* stat, /**< problem statistics */
    12296 SCIP_PROB* prob, /**< problem data */
    12297 SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
    12298 int resolveitlim, /**< maximal number of LP iterations to perform in resolving calls, or -1 for no limit */
    12299 int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
    12300 SCIP_Bool needprimalray, /**< if the LP is unbounded, do we need a primal ray? */
    12301 SCIP_Bool needdualray, /**< if the LP is infeasible, do we need a dual ray? */
    12302 SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
    12303 int fastmip, /**< which FASTMIP setting of LP solver should be used? */
    12304 SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
    12305 SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
    12306 SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
    12307 int scaling, /**< LP scaling (0: none, 1: normal, 2: aggressive) */
    12308 SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
    12309 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
    12310 )
    12311{
    12312 SCIP_Bool solvedprimal;
    12313 SCIP_Bool solveddual;
    12314 SCIP_Bool timelimit;
    12315 int itlim;
    12316
    12317 assert(lp != NULL);
    12318 assert(lp->flushed);
    12319 assert(set != NULL);
    12320 assert(stat != NULL);
    12321 assert(lperror != NULL);
    12322
    12323 checkLinks(lp);
    12324
    12325 solvedprimal = FALSE;
    12326 solveddual = FALSE;
    12327 timelimit = FALSE;
    12328
    12329 /* select the basic iteration limit depending on whether this is a resolving call or not */
    12330 itlim = ( resolve ? resolveitlim : harditlim );
    12331
    12332 SOLVEAGAIN:
    12333 /* call simplex */
    12334 SCIP_CALL( lpSolveStable(lp, set, messagehdlr, stat, prob, lpalgo, itlim, harditlim, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch,
    12335 scaling, keepsol, &timelimit, lperror) );
    12336 resolve = FALSE; /* only the first solve should be counted as resolving call */
    12337 solvedprimal = solvedprimal || (lp->lastlpalgo == SCIP_LPALGO_PRIMALSIMPLEX);
    12338 solveddual = solveddual || (lp->lastlpalgo == SCIP_LPALGO_DUALSIMPLEX);
    12339
    12340 /* check, if an error occurred */
    12341 if( *lperror )
    12342 {
    12343 SCIPsetDebugMsg(set, "unresolved error while solving LP with %s\n", lpalgoName(lp->lastlpalgo));
    12344 lp->solved = FALSE;
    12346 return SCIP_OKAY;
    12347 }
    12348
    12349 /* check, if a time limit was exceeded */
    12350 if( timelimit )
    12351 {
    12352 SCIPsetDebugMsg(set, "time limit exceeded before solving LP\n");
    12353 lp->solved = TRUE;
    12356 return SCIP_OKAY;
    12357 }
    12358
    12359 /* only one should return true */
    12362
    12363 /* evaluate solution status */
    12364 if( SCIPlpiIsOptimal(lp->lpi) )
    12365 {
    12366 assert(lp->primalfeasible);
    12367 assert(lp->dualfeasible);
    12369 SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
    12370 adjustLPobjval(lp, set, messagehdlr);
    12371
    12373 {
    12374 /* the solver may return the optimal value, even if this is greater or equal than the upper bound */
    12375 SCIPsetDebugMsg(set, "optimal solution %.15g exceeds objective limit %.15g\n", lp->lpobjval, lp->lpiobjlim);
    12378 }
    12379 /* if we did not disable the cutoff bound in the LP solver, the LP solution status should be objective limit
    12380 * reached if the LP objective value is greater than the cutoff bound
    12381 */
    12382 assert(lpCutoffDisabled(set, prob, lp) || set->exact_enable || lp->lpsolstat == SCIP_LPSOLSTAT_OBJLIMIT
    12384 || SCIPsetIsLE(set, lp->lpobjval + getFiniteLooseObjval(lp, set, prob), lp->cutoffbound));
    12385 }
    12386 else if( SCIPlpiIsObjlimExc(lp->lpi) )
    12387 {
    12388 assert(!lpCutoffDisabled(set, prob, lp));
    12389
    12390#ifndef NDEBUG
    12391 /* the LP solution objective should exceed the limit in this case; if this assert is triggered, it typically means
    12392 * that the LP interface method SCIPlpiIsStable() lacks a check for this event and incorrectly returned TRUE */
    12393 SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
    12394 assert(!set->lp_checkstability || SCIPsetIsRelGE(set, lp->lpobjval, lp->lpiobjlim));
    12395#endif
    12396
    12399 }
    12400 else if( SCIPlpiIsPrimalInfeasible(lp->lpi) )
    12401 {
    12402 /* because of numerical instability lpalgo != lp->lastlpalgo might happen - hence, we have to check both */
    12403 if( needdualray && !SCIPlpiHasDualRay(lp->lpi) && !solveddual && lpalgo != SCIP_LPALGO_DUALSIMPLEX )
    12404 {
    12405 assert(lp->lastlpalgo != SCIP_LPALGO_DUALSIMPLEX);
    12406 lpalgo = SCIP_LPALGO_DUALSIMPLEX;
    12407 goto SOLVEAGAIN;
    12408 }
    12411 }
    12412 else if( SCIPlpiExistsPrimalRay(lp->lpi) )
    12413 {
    12414 /* because of numerical instability lpalgo != lp->lastlpalgo might happen - hence, we have to check both */
    12415 if( needprimalray && !SCIPlpiIsPrimalUnbounded(lp->lpi) && !solvedprimal && lpalgo != SCIP_LPALGO_PRIMALSIMPLEX )
    12416 {
    12417 /* unboundedness includes that the primal is feasible: ensure a primal solution here */
    12420 goto SOLVEAGAIN;
    12421 }
    12424 }
    12425 else if( SCIPlpiIsIterlimExc(lp->lpi) )
    12426 {
    12427 SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
    12428
    12429 /* The lpobjval might be infinite, e.g. if the LP solver was not able to produce a valid bound while reaching the
    12430 iteration limit. In this case, we avoid the warning in adjustLPobjval() by setting the messagehdlr to NULL. */
    12431 if ( REALABS(lp->lpobjval) == SCIPlpiInfinity(lp->lpi) ) /*lint !e777*/
    12432 adjustLPobjval(lp, set, NULL);
    12433 else
    12434 adjustLPobjval(lp, set, messagehdlr);
    12435
    12437 }
    12438 else if( SCIPlpiIsTimelimExc(lp->lpi) )
    12439 {
    12442 }
    12443 else if( !solveddual && lpalgo != SCIP_LPALGO_DUALSIMPLEX)
    12444 {
    12445 assert(lp->lastlpalgo != SCIP_LPALGO_DUALSIMPLEX);
    12446 lpalgo = SCIP_LPALGO_DUALSIMPLEX;
    12447 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    12448 "(node %" SCIP_LONGINT_FORMAT ") solution status of LP %" SCIP_LONGINT_FORMAT " could not be proven (internal status:%d) -- solve again with %s\n",
    12449 stat->nnodes, stat->nlps, SCIPlpiGetInternalStatus(lp->lpi), lpalgoName(lpalgo));
    12450 goto SOLVEAGAIN;
    12451 }
    12452 else if( !solvedprimal && lpalgo != SCIP_LPALGO_PRIMALSIMPLEX)
    12453 {
    12456 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    12457 "(node %" SCIP_LONGINT_FORMAT ") solution status of LP %" SCIP_LONGINT_FORMAT " could not be proven (internal status:%d) -- solve again with %s\n",
    12458 stat->nnodes, stat->nlps, SCIPlpiGetInternalStatus(lp->lpi), lpalgoName(lpalgo));
    12459 goto SOLVEAGAIN;
    12460 }
    12461 else
    12462 {
    12463 SCIPerrorMessage("(node %" SCIP_LONGINT_FORMAT ") error or unknown return status of %s in LP %" SCIP_LONGINT_FORMAT " (internal status: %d)\n",
    12464 stat->nnodes, lpalgoName(lp->lastlpalgo), stat->nlps, SCIPlpiGetInternalStatus(lp->lpi));
    12466 return SCIP_LPERROR;
    12467 }
    12468
    12469 lp->solved = TRUE;
    12470
    12471 SCIPsetDebugMsg(set, "solving LP with %s returned solstat=%d (internal status: %d, primalfeasible=%u, dualfeasible=%u)\n",
    12474
    12475 return SCIP_OKAY;
    12476}
    12477
    12478/** flushes the LP and solves it with the primal or dual simplex algorithm, depending on the current basis feasibility */
    12479static
    12481 SCIP_LP* lp, /**< current LP data */
    12482 BMS_BLKMEM* blkmem, /**< block memory */
    12483 SCIP_SET* set, /**< global SCIP settings */
    12484 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    12485 SCIP_STAT* stat, /**< problem statistics */
    12486 SCIP_PROB* prob, /**< problem data */
    12487 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    12488 int resolveitlim, /**< maximal number of LP iterations to perform in resolving calls, or -1 for no limit */
    12489 int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
    12490 SCIP_Bool needprimalray, /**< if the LP is unbounded, do we need a primal ray? */
    12491 SCIP_Bool needdualray, /**< if the LP is infeasible, do we need a dual ray? */
    12492 int fastmip, /**< which FASTMIP setting of LP solver should be used? */
    12493 SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
    12494 SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
    12495 SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
    12496 int scaling, /**< LP scaling (0: none, 1: normal, 2: aggressive) */
    12497 SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
    12498 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
    12499 )
    12500{
    12501 SCIP_Bool resolve;
    12502 char algo;
    12503
    12504 assert(lp != NULL);
    12505 assert(set != NULL);
    12506 assert(lperror != NULL);
    12507
    12508 /* flush changes to the LP solver */
    12509 SCIP_CALL( SCIPlpFlush(lp, blkmem, set, prob, eventqueue) );
    12510 fastmip = ((!lp->flushaddedcols && !lp->flushdeletedcols) ? fastmip : 0); /* turn off FASTMIP if columns were changed */
    12511
    12512 /* select LP algorithm to apply */
    12513 resolve = lp->solisbasic && (lp->dualfeasible || lp->primalfeasible) && !fromscratch;
    12514 algo = resolve ? set->lp_resolvealgorithm : set->lp_initalgorithm;
    12515 lp->hasprovedbound = FALSE;
    12516
    12517 switch( algo )
    12518 {
    12519 case 's':
    12520 /* select simplex method */
    12521 if( lp->dualfeasible || !lp->primalfeasible )
    12522 {
    12523 SCIPsetDebugMsg(set, "solving dual LP\n");
    12524 SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, resolveitlim, harditlim, needprimalray,
    12525 needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
    12526 }
    12527 else
    12528 {
    12529 SCIPsetDebugMsg(set, "solving primal LP\n");
    12530 SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_PRIMALSIMPLEX, resolveitlim, harditlim, needprimalray,
    12531 needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
    12532 }
    12533 break;
    12534
    12535 case 'p':
    12536 SCIPsetDebugMsg(set, "solving primal LP\n");
    12537 SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_PRIMALSIMPLEX, resolveitlim, harditlim, needprimalray,
    12538 needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
    12539 break;
    12540
    12541 case 'd':
    12542 SCIPsetDebugMsg(set, "solving dual LP\n");
    12543 SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, resolveitlim, harditlim, needprimalray,
    12544 needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
    12545 break;
    12546
    12547 case 'b':
    12548 SCIPsetDebugMsg(set, "solving barrier LP\n");
    12549 SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_BARRIER, resolveitlim, harditlim, needprimalray,
    12550 needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
    12551 break;
    12552
    12553 case 'c':
    12554 SCIPsetDebugMsg(set, "solving barrier LP with crossover\n");
    12555 SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_BARRIERCROSSOVER, resolveitlim, harditlim, needprimalray,
    12556 needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
    12557 break;
    12558
    12559 default:
    12560 SCIPerrorMessage("invalid parameter setting <%c> for LP algorithm\n", algo);
    12562 }
    12563 assert(!(*lperror) || !lp->solved);
    12564
    12565 return SCIP_OKAY;
    12566}
    12567
    12568#ifndef NDEBUG
    12569/** checks if the lazy bounds are valid */
    12570static
    12572 SCIP_LP* lp, /**< LP data */
    12573 SCIP_SET* set /**< global SCIP settings */
    12574 )
    12575{
    12576 SCIP_COL* col;
    12577 int c;
    12578
    12579 assert(lp->flushed);
    12580
    12581 for( c = 0; c < lp->nlazycols; ++c )
    12582 {
    12583 col = lp->lazycols[c];
    12584
    12585 /* in case lazy bounds are given, check that the primal solution satisfies them */
    12586 assert(SCIPsetIsInfinity(set, -col->lazylb) || SCIPsetIsFeasGE(set, col->primsol, col->lazylb));
    12587 assert(SCIPsetIsInfinity(set, col->lazyub) || SCIPsetIsFeasLE(set, col->primsol, col->lazyub));
    12588 }
    12589}
    12590#else
    12591#define checkLazyBounds(lp, set) /**/
    12592#endif
    12593
    12594/** marks all lazy columns to be changed; this is needed for reloading/removing bounds of these columns before and after
    12595 * diving
    12596 */
    12597static
    12599 SCIP_LP* lp, /**< LP data */
    12600 SCIP_SET* set /**< global SCIP settings */
    12601 )
    12602{
    12603 SCIP_COL* col;
    12604 int c;
    12605
    12606 assert(lp->nlazycols > 0);
    12607
    12608 /* return, if we are in diving, and bounds were already applied
    12609 * or if we are not in diving and bounds were not applied
    12610 */
    12611 if( lp->diving == lp->divinglazyapplied )
    12612 return SCIP_OKAY;
    12613
    12614 SCIPsetDebugMsg(set, "mark all lazy columns as changed in order to reload bounds (diving=%u, applied=%u)\n",
    12615 lp->diving, lp->divinglazyapplied);
    12616
    12617 for( c = 0; c < lp->nlazycols; ++c )
    12618 {
    12619 col = lp->lazycols[c];
    12620
    12621 /* if the column has a lazy lower bound, mark its lower bounds as changed */
    12622 if( !SCIPsetIsInfinity(set, -col->lazylb) )
    12623 {
    12624 assert((!(lp->divinglazyapplied)) || (col->flushedlb == col->lb) || col->lbchanged); /*lint !e777*/
    12625 assert(lp->divinglazyapplied || SCIPsetIsGT(set, col->lb, col->lazylb)
    12626 || (col->flushedlb == -SCIPlpiInfinity(lp->lpi)) || col->lbchanged); /*lint !e777*/
    12627
    12628 /* insert column in the chgcols list (if not already there) */
    12629 SCIP_CALL( insertColChgcols(col, set, lp) );
    12630
    12631 /* mark bound change in the column */
    12632 col->lbchanged = TRUE;
    12633 }
    12634
    12635 /* if the column has a lazy upper bound, mark its upper bounds as changed */
    12636 if( !SCIPsetIsInfinity(set, col->lazyub) )
    12637 {
    12638 assert((!(lp->divinglazyapplied)) || (col->flushedub == col->ub) || col->ubchanged); /*lint !e777*/
    12639 assert(lp->divinglazyapplied || SCIPsetIsLT(set, col->ub, col->lazyub)
    12640 || (col->flushedub == SCIPlpiInfinity(lp->lpi)) || col->ubchanged); /*lint !e777*/
    12641
    12642 /* insert column in the chgcols list (if not already there) */
    12643 SCIP_CALL( insertColChgcols(col, set, lp) );
    12644
    12645 /* mark bound change in the column */
    12646 col->ubchanged = TRUE;
    12647 }
    12648 }
    12649
    12650 /* update lp->divinglazyapplied flag: if we are in diving mode, we just applied the lazy bounds,
    12651 * if not, we just removed them
    12652 */
    12653 lp->divinglazyapplied = lp->diving;
    12654
    12655 return SCIP_OKAY;
    12656}
    12657
    12658/** returns the iteration limit for an LP resolving call */
    12659static
    12661 SCIP_SET* set, /**< global SCIP settings */
    12662 SCIP_STAT* stat, /**< dynamic problem statistics */
    12663 int itlim /**< hard iteration limit */
    12664 )
    12665{
    12666 /* no limit set or average not yet reliable */
    12667 if( (set->lp_resolveiterfac == -1) || stat->nlps - stat->nrootlps < 5 )
    12668 return itlim;
    12669 /* set itlim to INT_MAX if it is -1 to reduce the number of cases to be regarded in the following */
    12670 if( itlim == -1 )
    12671 itlim = INT_MAX;
    12672 /* return resolveiterfac * average iteration number per call after root, but at least resolveitermin and at most the hard iteration limit */
    12673 return (int) MIN(itlim, MAX(set->lp_resolveitermin, \
    12674 (set->lp_resolveiterfac * (stat->nlpiterations - stat->nrootlpiterations) / (SCIP_Real)(stat->nlps - stat->nrootlps))));
    12675}
    12676
    12677
    12678
    12679/** solves the LP with simplex algorithm, and copy the solution into the column's data */
    12681 SCIP_LP* lp, /**< LP data */
    12682 SCIP_SET* set, /**< global SCIP settings */
    12683 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    12684 BMS_BLKMEM* blkmem, /**< block memory buffers */
    12685 SCIP_STAT* stat, /**< problem statistics */
    12686 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    12687 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    12688 SCIP_PROB* prob, /**< problem data */
    12689 SCIP_Longint itlim, /**< maximal number of LP iterations to perform, or -1 for no limit */
    12690 SCIP_Bool limitresolveiters, /**< should LP iterations for resolving calls be limited?
    12691 * (limit is computed within the method w.r.t. the average LP iterations) */
    12692 SCIP_Bool aging, /**< should aging and removal of obsolete cols/rows be applied? */
    12693 SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
    12694 SCIP_Bool forcedlpsolve, /**< would SCIP abort if the LP is not solved? */
    12695 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
    12696 )
    12697{
    12698 SCIP_RETCODE retcode;
    12699 SCIP_Bool needprimalray;
    12700 SCIP_Bool needdualray;
    12701 int harditlim;
    12702 int resolveitlim;
    12703
    12704 assert(lp != NULL);
    12705 assert(prob != NULL);
    12706 assert(prob->nvars >= lp->ncols);
    12707 assert(lperror != NULL);
    12708
    12709 retcode = SCIP_OKAY;
    12710 *lperror = FALSE;
    12711
    12712 if( lp->flushed && lp->solved )
    12713 {
    12714 SCIPsetDebugMsg(set, "skipping LP solve: already flushed and solved)\n");
    12715 return SCIP_OKAY;
    12716 }
    12717
    12718 SCIPsetDebugMsg(set, "solving LP: %d rows, %d cols, primalfeasible=%u, dualfeasible=%u, solved=%u, diving=%u, probing=%u, cutoffbnd=%g\n",
    12719 lp->nrows, lp->ncols, lp->primalfeasible, lp->dualfeasible, lp->solved, lp->diving, lp->probing, lp->cutoffbound);
    12720
    12721 /* check whether we need a proof of unboundedness or infeasibility by a primal or dual ray */
    12722 needprimalray = TRUE;
    12723 needdualray = (!SCIPprobAllColsInLP(prob, set, lp) || set->exact_enable || (set->conf_enable && set->conf_useinflp != 'o'));
    12724
    12725 /* compute the limit for the number of LP resolving iterations, if needed (i.e. if limitresolveiters == TRUE) */
    12726 harditlim = (int) MIN(itlim, INT_MAX);
    12727 resolveitlim = ( limitresolveiters ? lpGetResolveItlim(set, stat, harditlim) : harditlim );
    12728 assert(harditlim == -1 || (resolveitlim <= harditlim));
    12729
    12730 /* if there are lazy bounds, check whether the bounds should explicitly be put into the LP (diving was started)
    12731 * or removed from the LP (diving was ended)
    12732 */
    12733 if( lp->nlazycols > 0 )
    12734 {
    12735 /* @todo avoid loosing primal feasibility here after changing the objective already did destroy dual feasibility;
    12736 * first resolve LP?
    12737 */
    12739 assert(lp->diving == lp->divinglazyapplied);
    12740 }
    12741
    12742 /* flush changes to the LP solver */
    12743 SCIP_CALL( SCIPlpFlush(lp, blkmem, set, prob, eventqueue) );
    12744 assert(lp->flushed);
    12745
    12746 /* if the time limit was reached in the last call and the LP did not change, lp->solved is set to TRUE, but we want
    12747 * to run again anyway, since there seems to be some time left / the time limit was increased
    12748 */
    12749 if( !lp->solved || (lp->lpsolstat == SCIP_LPSOLSTAT_TIMELIMIT && stat->status != SCIP_STATUS_TIMELIMIT) )
    12750 {
    12751 SCIP_Bool* primalfeaspointer;
    12752 SCIP_Bool* dualfeaspointer;
    12753 SCIP_Bool primalfeasible;
    12754 SCIP_Bool dualfeasible;
    12755 SCIP_Bool farkasvalid;
    12756 SCIP_Bool rayfeasible;
    12757 SCIP_Bool tightprimfeastol;
    12758 SCIP_Bool tightdualfeastol;
    12759 SCIP_Bool fromscratch;
    12760 SCIP_Bool wasfromscratch;
    12761 int scaling;
    12762 SCIP_Longint oldnlps;
    12763 int fastmip;
    12764
    12765 /* set initial LP solver settings */
    12766 fastmip = ((lp->lpihasfastmip && !lp->flushaddedcols && !lp->flushdeletedcols && stat->nnodes > 1) ? set->lp_fastmip : 0);
    12767 tightprimfeastol = FALSE;
    12768 tightdualfeastol = FALSE;
    12769 fromscratch = FALSE;
    12770 primalfeasible = FALSE;
    12771 dualfeasible = FALSE;
    12772 wasfromscratch = (stat->nlps == 0);
    12773 scaling = set->lp_scaling;
    12774
    12775 SOLVEAGAIN:
    12776 /* solve the LP */
    12777 oldnlps = stat->nlps;
    12778 SCIP_CALL( lpFlushAndSolve(lp, blkmem, set, messagehdlr, stat, prob, eventqueue, resolveitlim, harditlim, needprimalray,
    12779 needdualray, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
    12780 SCIPsetDebugMsg(set, "lpFlushAndSolve() returned solstat %d (error=%u)\n", SCIPlpGetSolstat(lp), *lperror);
    12781 assert(!(*lperror) || !lp->solved);
    12782
    12783 /* check for error */
    12784 if( *lperror )
    12785 {
    12786 retcode = SCIP_OKAY;
    12787 goto TERMINATE;
    12788 }
    12789
    12790 /* compute safe bound might change the solstat so we have to compute it before we evaluate the solution status */
    12792 {
    12794 SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat, FALSE, &farkasvalid) );
    12795 else
    12796 SCIP_CALL( SCIPlpGetSol(lp, set, stat, &primalfeasible, &dualfeasible) );
    12797
    12798 /* in objlimit case, the lp objval is set to infinity, get the real objval to correct */
    12800 {
    12801 SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
    12802 }
    12803
    12804 SCIP_CALL( SCIPlpExactComputeSafeBound(lp, lp->lpexact, set, messagehdlr, blkmem, stat, eventqueue,
    12805 prob, lperror, SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_INFEASIBLE, &(lp->lpobjval), &primalfeasible, &dualfeasible ) );
    12806
    12807 /* handle error case in objlimit */
    12808 if( SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OBJLIMIT && !lp->hasprovedbound && !(lp->probing || lp->diving) )
    12809 {
    12810 /* if safe bounding did fail, we have not managed to get a dual bound exceeding the cutoffbound, therefore just disable cutoffbound
    12811 * and resolve the lp with another bounding step */
    12813 lp->cutoffbound = SCIPlpiInfinity(lp->lpi);
    12814 goto SOLVEAGAIN;
    12815 }
    12816 /* restore the old cutoffbound if it was disabled prior and reset the saved value to inf */
    12818 {
    12821 }
    12822
    12823 /* check for error */
    12824 if( *lperror )
    12825 {
    12826 retcode = SCIP_OKAY;
    12827 goto TERMINATE;
    12828 }
    12829 }
    12830
    12831 /* evaluate solution status */
    12832 switch( SCIPlpGetSolstat(lp) )
    12833 {
    12835 /* get LP solution and possibly check the solution's feasibility again */
    12836 if( set->lp_checkprimfeas )
    12837 {
    12838 primalfeaspointer = &primalfeasible;
    12839 lp->primalchecked = TRUE;
    12840 }
    12841 else
    12842 {
    12843 /* believe in the primal feasibility of the LP solution */
    12844 primalfeasible = TRUE;
    12845 primalfeaspointer = NULL;
    12846 lp->primalchecked = FALSE;
    12847 }
    12848 if( set->lp_checkdualfeas )
    12849 {
    12850 dualfeaspointer = &dualfeasible;
    12851 lp->dualchecked = TRUE;
    12852 }
    12853 else
    12854 {
    12855 /* believe in the dual feasibility of the LP solution */
    12856 dualfeasible = TRUE;
    12857 dualfeaspointer = NULL;
    12858 lp->dualchecked = FALSE;
    12859 }
    12860
    12861 if( !set->exact_enable )
    12862 {
    12863 SCIP_CALL( SCIPlpGetSol(lp, set, stat, primalfeaspointer, dualfeaspointer) );
    12864 }
    12865
    12866 /* in debug mode, check that lazy bounds (if present) are not violated */
    12867 checkLazyBounds(lp, set);
    12868
    12869 if( primalfeasible && dualfeasible && aging && !lp->diving && stat->nlps > oldnlps )
    12870 {
    12871 /* update ages and remove obsolete columns and rows from LP */
    12872 SCIP_CALL( SCIPlpUpdateAges(lp, stat) );
    12873 if( stat->nlps % ((set->lp_rowagelimit+1)/2 + 1) == 0 ) /*lint !e776*/
    12874 {
    12875 SCIP_CALL( SCIPlpRemoveNewObsoletes(lp, blkmem, set, stat, eventqueue, eventfilter) );
    12876 }
    12877
    12878 if( !lp->solved )
    12879 {
    12880 /* resolve LP after removing obsolete columns and rows */
    12881 SCIPsetDebugMsg(set, "removed obsoletes - resolve LP again: %d rows, %d cols\n", lp->nrows, lp->ncols);
    12882 aging = FALSE; /* to prevent infinite loops */
    12883 goto SOLVEAGAIN;
    12884 }
    12885 }
    12886 if( !primalfeasible || !dualfeasible )
    12887 {
    12889
    12890 if( set->exact_enable && lp->lpexact->wasforcedsafebound )
    12892
    12893 if( (fastmip > 0) && simplex )
    12894 {
    12895 /* solution is infeasible (this can happen due to numerical problems): solve again without FASTMIP */
    12896 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    12897 "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, dfeas=%u) -- solving again without FASTMIP\n",
    12898 stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
    12899 fastmip = 0;
    12900 goto SOLVEAGAIN;
    12901 }
    12902 else if( (!primalfeasible && !tightprimfeastol) || (!dualfeasible && !tightdualfeastol) )
    12903 {
    12904 /* solution is infeasible (this can happen due to numerical problems): solve again with tighter feasibility
    12905 * tolerance
    12906 */
    12907 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    12908 "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, dfeas=%u) -- solving again with tighter feasibility tolerance\n",
    12909 stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
    12910 tightprimfeastol = tightprimfeastol || !primalfeasible;
    12911 tightdualfeastol = tightdualfeastol || !dualfeasible;
    12912 goto SOLVEAGAIN;
    12913 }
    12914 else if( !fromscratch && !wasfromscratch && simplex )
    12915 {
    12916 /* solution is infeasible (this can happen due to numerical problems): solve again from scratch */
    12917 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    12918 "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, dfeas=%u) -- solving again from scratch\n",
    12919 stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
    12920 fromscratch = TRUE;
    12921 goto SOLVEAGAIN;
    12922 }
    12923 else
    12924 {
    12925 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved");
    12926 lp->solved = FALSE;
    12928 *lperror = TRUE;
    12929 }
    12930 }
    12931 SCIPsetDebugMsg(set, " -> LP objective value: %g + %g = %g (solstat=%d, cutoff=%g)\n",
    12932 lp->lpobjval, getFiniteLooseObjval(lp, set, prob), lp->lpobjval + getFiniteLooseObjval(lp, set, prob),
    12933 lp->lpsolstat, lp->cutoffbound);
    12934 break;
    12935
    12937 SCIPsetDebugMsg(set, " -> LP infeasible\n");
    12938 if( set->lp_checkfarkas || set->lp_alwaysgetduals || set->exact_enable || !SCIPprobAllColsInLP(prob, set, lp) )
    12939 {
    12940 if( set->exact_enable && SCIPlpiExactHasDualRay(lp->lpexact->lpiexact) )
    12941 farkasvalid = TRUE;
    12942 else if( SCIPlpiHasDualRay(lp->lpi) )
    12943 {
    12944 SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat, forcedlpsolve, &farkasvalid) );
    12945 }
    12946 /* it might happen that we have no infeasibility proof for the current LP (e.g. if the LP was always solved
    12947 * with the primal simplex due to numerical problems) - treat this case like an LP error
    12948 */
    12949 else
    12950 {
    12951 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    12952 "(node %" SCIP_LONGINT_FORMAT ") infeasibility of LP %" SCIP_LONGINT_FORMAT " could not be proven by dual ray\n", stat->nnodes, stat->nlps);
    12953 lp->solved = FALSE;
    12955 farkasvalid = FALSE;
    12956 *lperror = TRUE;
    12957 }
    12958 }
    12959 else
    12960 farkasvalid = TRUE;
    12961
    12962 /* if the LP solver does not provide a Farkas proof we don't want to resolve the LP */
    12963 if( !farkasvalid && !(*lperror) )
    12964 {
    12966
    12967 if( (fastmip > 0) && simplex )
    12968 {
    12969 /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems): solve again
    12970 * without FASTMIP
    12971 */
    12972 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    12973 "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again without FASTMIP\n",
    12974 stat->nnodes, stat->nlps);
    12975 fastmip = 0;
    12976 goto SOLVEAGAIN;
    12977 }
    12978 else if( !tightdualfeastol )
    12979 {
    12980 /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems):
    12981 * solve again with tighter feasibility tolerance
    12982 */
    12983 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    12984 "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again with tighter dual feasibility tolerance\n",
    12985 stat->nnodes, stat->nlps);
    12986 tightdualfeastol = TRUE;
    12987 goto SOLVEAGAIN;
    12988 }
    12989 else if( !fromscratch && simplex )
    12990 {
    12991 /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems): solve again
    12992 * from scratch
    12993 */
    12994 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    12995 "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again from scratch\n",
    12996 stat->nnodes, stat->nlps);
    12997 fromscratch = TRUE;
    12998 goto SOLVEAGAIN;
    12999 }
    13000 else
    13001 {
    13002 /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems) and nothing
    13003 * helped forget about the LP at this node and mark it to be unsolved
    13004 */
    13005 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, LP infeasible");
    13006 lp->solved = FALSE;
    13008 *lperror = TRUE;
    13009 }
    13010 }
    13011
    13012 break;
    13013
    13015 if( set->lp_checkprimfeas )
    13016 {
    13017 /* get unbounded LP solution and check the solution's feasibility again */
    13018 SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, &primalfeasible, &rayfeasible) );
    13019
    13020 lp->primalchecked = TRUE;
    13021 }
    13022 else
    13023 {
    13024 /* get unbounded LP solution believing in the feasibility of the LP solution */
    13026
    13027 primalfeasible = TRUE;
    13028 rayfeasible = TRUE;
    13029 lp->primalchecked = FALSE;
    13030 }
    13031
    13032 /* in debug mode, check that lazy bounds (if present) are not violated */
    13033 checkLazyBounds(lp, set);
    13034
    13035 SCIPsetDebugMsg(set, " -> LP has unbounded primal ray (primalfeas=%u, rayfeas=%u)\n",
    13036 primalfeasible, rayfeasible);
    13037
    13038 if( !primalfeasible || !rayfeasible )
    13039 {
    13041
    13042 if( (fastmip > 0) && simplex )
    13043 {
    13044 /* unbounded solution is infeasible (this can happen due to numerical problems): solve again without FASTMIP */
    13045 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    13046 "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, rfeas=%u) -- solving again without FASTMIP\n",
    13047 stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
    13048 fastmip = 0;
    13049 goto SOLVEAGAIN;
    13050 }
    13051 else if( !tightprimfeastol )
    13052 {
    13053 /* unbounded solution is infeasible (this can happen due to numerical problems): solve again with tighter feasibility
    13054 * tolerance
    13055 */
    13056 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    13057 "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, rfeas=%u) -- solving again with tighter primal feasibility tolerance\n",
    13058 stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
    13059 tightprimfeastol = TRUE;
    13060 goto SOLVEAGAIN;
    13061 }
    13062 else if( !fromscratch && simplex )
    13063 {
    13064 /* unbounded solution is infeasible (this can happen due to numerical problems): solve again from scratch */
    13065 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    13066 "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, rfeas=%u) -- solving again from scratch\n",
    13067 stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
    13068 fromscratch = TRUE;
    13069 goto SOLVEAGAIN;
    13070 }
    13071 else if( scaling > 0 )
    13072 {
    13073 /* unbounded solution is infeasible (this can happen due to numerical problems): solve again without scaling */
    13074 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    13075 "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, rfeas=%u) -- solving without scaling\n",
    13076 stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
    13077 scaling = 0;
    13078 goto SOLVEAGAIN;
    13079 }
    13080 else
    13081 {
    13082 /* unbounded solution is infeasible (this can happen due to numerical problems) and nothing helped:
    13083 * forget about the LP at this node and mark it to be unsolved
    13084 */
    13085 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, LP unbounded");
    13086 lp->solved = FALSE;
    13088 *lperror = TRUE;
    13089 }
    13090 }
    13091
    13092 break;
    13093
    13095 assert(!lpCutoffDisabled(set, prob, lp));
    13096 /* Some LP solvers, e.g. CPLEX With FASTMIP setting, do not apply the final pivot to reach the dual solution
    13097 * exceeding the objective limit. In some cases like branch-and-price, however, we must make sure that a dual
    13098 * feasible solution exists that exceeds the objective limit. Therefore, we have to continue solving it without
    13099 * objective limit for at least one iteration. We first try to continue with FASTMIP for one additional simplex
    13100 * iteration using the steepest edge pricing rule. If this does not fix the problem, we temporarily disable
    13101 * FASTMIP and solve again.
    13102 */
    13103 if( !set->exact_enable && !SCIPprobAllColsInLP(prob, set, lp) )
    13104 {
    13105 SCIP_LPI* lpi;
    13106 SCIP_Real objval;
    13107
    13108 lpi = SCIPlpGetLPI(lp);
    13109
    13110 assert(lpi != NULL);
    13111 /* actually, SCIPsetIsGE(set, lp->lpobjval, lp->lpiuobjlim) should hold, but we are a bit less strict in
    13112 * the assert by using !SCIPsetIsFeasNegative()
    13113 */
    13114 assert(SCIPlpiIsObjlimExc(lpi) || !SCIPsetIsFeasNegative(set, lp->lpobjval - lp->lpiobjlim));
    13115
    13116 SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
    13117
    13118 /* do one additional simplex step if the computed dual solution doesn't exceed the objective limit */
    13119 if( SCIPsetIsLT(set, objval, lp->lpiobjlim) )
    13120 {
    13121 SCIP_Real tmpcutoff;
    13122 char tmppricingchar;
    13123 SCIP_LPSOLSTAT solstat;
    13124
    13125 SCIPsetDebugMsg(set, "objval = %f < %f = lp->lpiobjlim, but status objlimit\n", objval, lp->lpiobjlim);
    13126
    13127 /* we want to resolve from the current basis (also if the LP had to be solved from scratch) */
    13128 fromscratch = FALSE;
    13129
    13130 /* temporarily disable cutoffbound, which also disables the objective limit */
    13131 tmpcutoff = lp->cutoffbound;
    13132 lp->cutoffbound = SCIPlpiInfinity(lpi);
    13133
    13134 /* set lp pricing strategy to steepest edge */
    13135 SCIP_CALL( SCIPsetGetCharParam(set, "lp/pricing", &tmppricingchar) );
    13136 SCIP_CALL( SCIPsetSetCharParam(set, messagehdlr, "lp/pricing", 's') );
    13137
    13138 /* resolve LP with an iteration limit of 1 */
    13139 SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, 1, 1,
    13140 FALSE, FALSE, TRUE, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
    13141
    13142 /* reinstall old cutoff bound and lp pricing strategy */
    13143 lp->cutoffbound = tmpcutoff;
    13144 SCIP_CALL( SCIPsetSetCharParam(set, messagehdlr, "lp/pricing", tmppricingchar) );
    13145
    13146 /* get objective value */
    13147 SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
    13148
    13149 /* get solution status for the lp */
    13150 solstat = SCIPlpGetSolstat(lp);
    13151 assert(solstat != SCIP_LPSOLSTAT_OBJLIMIT);
    13152
    13153 SCIPsetDebugMsg(set, " ---> new objval = %f (solstat: %d, 1 add. step)\n", objval, solstat);
    13154
    13155 /* the solution is still not exceeding the objective limit and the solving process
    13156 * was stopped due to time or iteration limit, solve again with fastmip turned off
    13157 */
    13158 if( solstat == SCIP_LPSOLSTAT_ITERLIMIT &&
    13159 SCIPsetIsLT(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) )
    13160 {
    13162 if( !(*lperror) && (fastmip > 0) && simplex )
    13163 {
    13164 fastmip = 0;
    13165 SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, -1, -1,
    13166 FALSE, FALSE, TRUE, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
    13167
    13168 /* get objective value */
    13169 SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
    13170
    13171 /* get solution status for the lp */
    13172 solstat = SCIPlpGetSolstat(lp);
    13173
    13174 SCIPsetDebugMsg(set, " ---> new objval = %f (solstat: %d, without fastmip)\n", objval, solstat);
    13175 }
    13176 }/*lint !e438*/
    13177
    13178 /* check for lp errors */
    13179 if( *lperror || solstat == SCIP_LPSOLSTAT_ERROR || solstat == SCIP_LPSOLSTAT_NOTSOLVED )
    13180 {
    13181 SCIPsetDebugMsg(set, "unresolved error while resolving LP in order to exceed the objlimit\n");
    13182 lp->solved = FALSE;
    13184
    13185 retcode = *lperror ? SCIP_OKAY : SCIP_LPERROR;
    13186 goto TERMINATE;
    13187 }
    13188
    13189 lp->solved = TRUE;
    13190
    13191 /* optimal solution / objlimit / itlimit or timelimit, but objlimit exceeded */
    13192 if( solstat == SCIP_LPSOLSTAT_OPTIMAL || solstat == SCIP_LPSOLSTAT_OBJLIMIT
    13193 || ( (solstat == SCIP_LPSOLSTAT_ITERLIMIT || solstat == SCIP_LPSOLSTAT_TIMELIMIT)
    13194 && SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) ) )
    13195 {
    13196 /* get LP solution and possibly check the solution's feasibility again */
    13197 if( set->lp_checkprimfeas )
    13198 {
    13199 primalfeaspointer = &primalfeasible;
    13200 lp->primalchecked = TRUE;
    13201 }
    13202 else
    13203 {
    13204 /* believe in the primal feasibility of the LP solution */
    13205 primalfeasible = TRUE;
    13206 primalfeaspointer = NULL;
    13207 lp->primalchecked = FALSE;
    13208 }
    13209 if( set->lp_checkdualfeas )
    13210 {
    13211 dualfeaspointer = &dualfeasible;
    13212 lp->dualchecked = TRUE;
    13213 }
    13214 else
    13215 {
    13216 /* believe in the dual feasibility of the LP solution */
    13217 dualfeasible = TRUE;
    13218 dualfeaspointer = NULL;
    13219 lp->dualchecked = FALSE;
    13220 }
    13221
    13222 SCIP_CALL( SCIPlpGetSol(lp, set, stat, primalfeaspointer, dualfeaspointer) );
    13223
    13224 /* in debug mode, check that lazy bounds (if present) are not violated by an optimal LP solution */
    13225 if( solstat == SCIP_LPSOLSTAT_OPTIMAL )
    13226 {
    13227 checkLazyBounds(lp, set);
    13228 }
    13229
    13230 /* if objective value is larger than the cutoff bound, set solution status to objective
    13231 * limit reached and objective value to infinity, in case solstat = SCIP_LPSOLSTAT_OBJLIMIT,
    13232 * this was already done in the lpSolve() method
    13233 */
    13234 if( SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) )
    13235 {
    13238 }
    13239
    13240 /* LP solution is not feasible or objective limit was reached without the LP value really exceeding
    13241 * the cutoffbound; mark the LP to be unsolved
    13242 */
    13243 if( !primalfeasible || !dualfeasible
    13244 || (solstat == SCIP_LPSOLSTAT_OBJLIMIT &&
    13245 !SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob))) )
    13246 {
    13247 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_HIGH, "unresolved");
    13248 lp->solved = FALSE;
    13250 *lperror = TRUE;
    13251 }
    13252
    13253 SCIPsetDebugMsg(set, " -> LP objective value: %g + %g = %g (solstat=%d, cutoff=%g)\n",
    13254 lp->lpobjval, getFiniteLooseObjval(lp, set, prob), lp->lpobjval + getFiniteLooseObjval(lp, set, prob),
    13255 lp->lpsolstat, lp->cutoffbound);
    13256 }
    13257 /* infeasible solution */
    13258 else if( solstat == SCIP_LPSOLSTAT_INFEASIBLE )
    13259 {
    13260 SCIPsetDebugMsg(set, " -> LP infeasible\n");
    13261
    13262 if( set->lp_checkfarkas || set->exact_enable || !SCIPprobAllColsInLP(prob, set, lp) )
    13263 {
    13264 if( SCIPlpiHasDualRay(lp->lpi) )
    13265 {
    13266 SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat, forcedlpsolve, &farkasvalid) );
    13267 }
    13268 /* it might happen that we have no infeasibility proof for the current LP (e.g. if the LP was always solved
    13269 * with the primal simplex due to numerical problems) - treat this case like an LP error
    13270 */
    13271 else
    13272 {
    13273 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    13274 "(node %" SCIP_LONGINT_FORMAT ") infeasibility of LP %" SCIP_LONGINT_FORMAT " could not be proven by dual ray\n", stat->nnodes, stat->nlps);
    13275 lp->solved = FALSE;
    13277 farkasvalid = FALSE;
    13278 *lperror = TRUE;
    13279 }
    13280 }
    13281 else
    13282 farkasvalid = TRUE;
    13283
    13284 if( !farkasvalid )
    13285 {
    13287
    13288 if( !tightprimfeastol )
    13289 {
    13290 /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems):
    13291 * solve again with tighter feasibility tolerance
    13292 */
    13293 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    13294 "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again with tighter primal feasibility tolerance\n",
    13295 stat->nnodes, stat->nlps);
    13296 tightprimfeastol = TRUE;
    13297 goto SOLVEAGAIN;
    13298 }
    13299 else if( simplex )
    13300 {
    13301 /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems): solve again
    13302 * from scratch
    13303 */
    13304 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    13305 "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again from scratch\n",
    13306 stat->nnodes, stat->nlps);
    13307 fromscratch = TRUE;
    13308 goto SOLVEAGAIN;
    13309 }
    13310 else
    13311 {
    13312 /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems) and nothing
    13313 * helped forget about the LP at this node and mark it to be unsolved
    13314 */
    13315 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, LP infeasible");
    13316 lp->solved = FALSE;
    13318 *lperror = TRUE;
    13319 }
    13320 }
    13321 }
    13322 /* unbounded solution */
    13323 else if( solstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY )
    13324 {
    13325 if( set->lp_checkprimfeas )
    13326 {
    13327 /* get unbounded LP solution and check the solution's feasibility again */
    13328 SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, &primalfeasible, &rayfeasible) );
    13329
    13330 lp->primalchecked = TRUE;
    13331 }
    13332 else
    13333 {
    13334 /* get unbounded LP solution believing in its feasibility */
    13336
    13337 primalfeasible = TRUE;
    13338 rayfeasible = TRUE;
    13339 lp->primalchecked = FALSE;
    13340 }
    13341
    13342 SCIPsetDebugMsg(set, " -> LP has unbounded primal ray\n");
    13343
    13344 /* in debug mode, check that lazy bounds (if present) are not violated */
    13345 checkLazyBounds(lp, set);
    13346
    13347 if( !primalfeasible || !rayfeasible )
    13348 {
    13349 /* unbounded solution is infeasible (this can happen due to numerical problems):
    13350 * forget about the LP at this node and mark it to be unsolved
    13351 *
    13352 * @todo: like in the default LP solving evaluation, solve without fastmip,
    13353 * with tighter feasibility tolerance and from scratch
    13354 */
    13355 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, unbounded LP");
    13356 lp->solved = FALSE;
    13358 *lperror = TRUE;
    13359 }
    13360 }
    13361
    13362 assert(lp->lpsolstat != SCIP_LPSOLSTAT_ITERLIMIT);
    13363 assert(SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob))
    13365 }
    13366 else
    13367 {
    13368 SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
    13369 }
    13370 }
    13371 SCIPsetDebugMsg(set, " -> LP objective limit reached\n");
    13372 break;
    13373
    13375 SCIPsetDebugMsg(set, " -> LP iteration limit exceeded\n");
    13376 break;
    13377
    13379 SCIPsetDebugMsg(set, " -> LP time limit exceeded\n");
    13380
    13381 /* make sure that we evaluate the time limit exactly in order to avoid erroneous warning */
    13382 stat->nclockskipsleft = 0;
    13383 if( !stat->userinterrupt && !SCIPsolveIsStopped(set, stat, FALSE) )
    13384 {
    13385 SCIPmessagePrintWarning(messagehdlr, "LP solver reached time limit, but SCIP time limit is not exceeded yet; "
    13386 "you might consider switching the clock type of SCIP\n");
    13388 }
    13389 break;
    13390
    13393 SCIPerrorMessage("error in LP solver\n");
    13394 retcode = SCIP_LPERROR;
    13395 goto TERMINATE;
    13396
    13397 default:
    13398 SCIPerrorMessage("unknown LP solution status\n");
    13399 retcode = SCIP_ERROR;
    13400 goto TERMINATE;
    13401 }
    13402 }
    13403 assert(!(*lperror) || !lp->solved);
    13404
    13405 TERMINATE:
    13406 /* if the LP had to be solved from scratch, we have to reset this flag since it is stored in the LPI; otherwise it
    13407 * may happen that we continue to solve from scratch during strong branching */
    13408 if( lp->lpifromscratch )
    13409 {
    13410 SCIP_Bool success;
    13411 (void) lpSetFromscratch(lp, FALSE, &success);
    13412 SCIPsetDebugMsg(set, "resetting parameter SCIP_LPPARAM_FROMSCRATCH to FALSE %s\n", success ? "" : "failed");
    13413 SCIP_UNUSED(success);
    13414 }
    13415
    13416 return retcode;
    13417}
    13418
    13419/** gets solution status of current LP */
    13421 SCIP_LP* lp /**< current LP data */
    13422 )
    13423{
    13424 assert(lp != NULL);
    13425 assert(lp->solved || lp->lpsolstat == SCIP_LPSOLSTAT_NOTSOLVED);
    13426
    13427 return (lp->flushed ? lp->lpsolstat : SCIP_LPSOLSTAT_NOTSOLVED);
    13428}
    13429
    13430/** gets objective value of current LP
    13431 *
    13432 * @note This method returns the objective value of the current LP solution, which might be primal or dual infeasible
    13433 * if a limit was hit during solving. It must not be used as a dual bound if the LP solution status is
    13434 * SCIP_LPSOLSTAT_ITERLIMIT or SCIP_LPSOLSTAT_TIMELIMIT.
    13435 */
    13437 SCIP_LP* lp, /**< current LP data */
    13438 SCIP_SET* set, /**< global SCIP settings */
    13439 SCIP_PROB* prob /**< problem data */
    13440 )
    13441{
    13442 assert(lp != NULL);
    13443 assert(lp->solved);
    13444 assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
    13445 assert(set != NULL);
    13446
    13447 if( !lp->flushed )
    13448 return SCIP_INVALID;
    13450 return lp->lpobjval;
    13451 else if( lp->looseobjvalinf > 0 )
    13452 return -SCIPsetInfinity(set);
    13453 else
    13454 {
    13455 /* recalculate the loose objective value, if needed */
    13456 if( !lp->looseobjvalid )
    13458
    13459 return lp->lpobjval + lp->looseobjval;
    13460 }
    13461}
    13462
    13463/** gets part of objective value of current LP that results from COLUMN variables only */
    13465 SCIP_LP* lp /**< current LP data */
    13466 )
    13467{
    13468 assert(lp != NULL);
    13469 assert(lp->solved);
    13470
    13471 return (lp->flushed ? lp->lpobjval : SCIP_INVALID);
    13472}
    13473
    13474/** gets part of objective value of current LP that results from LOOSE variables only */
    13476 SCIP_LP* lp, /**< current LP data */
    13477 SCIP_SET* set, /**< global SCIP settings */
    13478 SCIP_PROB* prob /**< problem data */
    13479 )
    13480{
    13481 assert(lp != NULL);
    13482 assert(lp->solved);
    13483 assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
    13484 assert(set != NULL);
    13485
    13486 if( !lp->flushed )
    13487 return SCIP_INVALID;
    13488 else if( lp->looseobjvalinf > 0 )
    13489 return -SCIPsetInfinity(set);
    13490 else
    13491 return getFiniteLooseObjval(lp, set, prob);
    13492}
    13493
    13494/** remembers the current LP objective value as root solution value */
    13496 SCIP_LP* lp, /**< current LP data */
    13497 SCIP_SET* set, /**< global SCIP settings */
    13498 SCIP_PROB* prob /**< problem data */
    13499 )
    13500{
    13501 assert(lp != NULL);
    13502
    13504 lp->rootlooseobjval = SCIPlpGetLooseObjval(lp, set, prob);
    13505}
    13506
    13507/** invalidates the root LP solution value */
    13509 SCIP_LP* lp /**< current LP data */
    13510 )
    13511{
    13512 assert(lp != NULL);
    13513
    13516}
    13517
    13518/** recomputes local and global pseudo objective values */
    13520 SCIP_LP* lp, /**< current LP data */
    13521 SCIP_SET* set, /**< global SCIP settings */
    13522 SCIP_PROB* prob /**< problem data */
    13523 )
    13524{
    13525 SCIP_VAR** vars;
    13526 int nvars;
    13527 int v;
    13528
    13529 assert(lp != NULL);
    13530 assert(set != NULL);
    13531 assert(prob != NULL);
    13532
    13533 vars = prob->vars;
    13534 nvars = prob->nvars;
    13535
    13536 lp->glbpseudoobjvalinf = 0;
    13537 lp->glbpseudoobjval = 0.0;
    13538
    13539 lp->pseudoobjvalinf = 0;
    13540 lp->pseudoobjval = 0.0;
    13541
    13542 for( v = 0; v < nvars; ++v )
    13543 {
    13544 SCIP_Real obj = SCIPvarGetObj(vars[v]);
    13545
    13546 if( SCIPsetIsPositive(set, obj) )
    13547 {
    13548 /* update the global pseudo objective value */
    13549 if( SCIPsetIsInfinity(set, -SCIPvarGetLbGlobal(vars[v])) )
    13550 ++(lp->glbpseudoobjvalinf);
    13551 else
    13552 lp->glbpseudoobjval += obj * SCIPvarGetLbGlobal(vars[v]);
    13553
    13554 /* update the local pseudo objective value */
    13555 if( SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(vars[v])) )
    13556 ++(lp->pseudoobjvalinf);
    13557 else
    13558 lp->pseudoobjval += obj * SCIPvarGetLbLocal(vars[v]);
    13559 }
    13560
    13561 if( SCIPsetIsNegative(set, obj) )
    13562 {
    13563 /* update the global pseudo objective value */
    13565 ++(lp->glbpseudoobjvalinf);
    13566 else
    13567 lp->glbpseudoobjval += obj * SCIPvarGetUbGlobal(vars[v]);
    13568
    13569 /* update the local pseudo objective value */
    13570 if( SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
    13571 ++(lp->pseudoobjvalinf);
    13572 else
    13573 lp->pseudoobjval += obj * SCIPvarGetUbLocal(vars[v]);
    13574 }
    13575 }
    13576
    13577 /* the recomputed values are reliable */
    13579 lp->glbpseudoobjvalid = TRUE;
    13580 lp->relpseudoobjval = lp->pseudoobjval;
    13581 lp->pseudoobjvalid = TRUE;
    13582}
    13583
    13584/** gets the global pseudo objective value; that is all variables set to their best (w.r.t. the objective function)
    13585 * global bound
    13586 */
    13588 SCIP_LP* lp, /**< current LP data */
    13589 SCIP_SET* set, /**< global SCIP settings */
    13590 SCIP_PROB* prob /**< problem data */
    13591 )
    13592{
    13593 assert(lp != NULL);
    13594 assert(lp->glbpseudoobjvalinf >= 0);
    13595 assert(set != NULL);
    13596
    13597 if( lp->glbpseudoobjvalinf > 0 || set->nactivepricers > 0 )
    13598 return -SCIPsetInfinity(set);
    13599 else
    13600 {
    13601 /* recalculate the global pseudo solution value, if needed */
    13602 if( !lp->glbpseudoobjvalid )
    13604
    13605 /* if the global pseudo objective value is smaller than -infinity, we just return -infinity */
    13607 return -SCIPsetInfinity(set);
    13608
    13610 return SCIPsetInfinity(set);
    13611
    13612 return lp->glbpseudoobjval;
    13613 }
    13614}
    13615
    13616/** gets the pseudo objective value for the current search node; that is all variables set to their best (w.r.t. the
    13617 * objective function) local bound
    13618 */
    13620 SCIP_LP* lp, /**< current LP data */
    13621 SCIP_SET* set, /**< global SCIP settings */
    13622 SCIP_PROB* prob /**< problem data */
    13623 )
    13624{
    13625 assert(lp != NULL);
    13626 assert(lp->pseudoobjvalinf >= 0);
    13627 assert(set != NULL);
    13628
    13629 if( lp->pseudoobjvalinf > 0 || set->nactivepricers > 0 )
    13630 return -SCIPsetInfinity(set);
    13631 else
    13632 {
    13633 /* recalculate the pseudo solution value, if needed */
    13634 if( !lp->pseudoobjvalid )
    13636
    13637 /* if the pseudo objective value is smaller than -infinity, we just return -infinity */
    13639 return -SCIPsetInfinity(set);
    13640
    13642 return SCIPsetInfinity(set);
    13643
    13644 return lp->pseudoobjval;
    13645 }
    13646}
    13647
    13648/** gets safe pseudo objective value, if a bound of the given variable would be modified in the given way;
    13649 * perform calculations with interval arithmetic to get an exact lower bound
    13650 */
    13651static
    13653 SCIP_LP* lp, /**< current LP data */
    13654 SCIP_SET* set, /**< global SCIP settings */
    13655 SCIP_PROB* prob, /**< problem data */
    13656 SCIP_VAR* var, /**< problem variable */
    13657 SCIP_Real oldbound, /**< old value for bound */
    13658 SCIP_Real newbound, /**< new value for bound */
    13659 SCIP_BOUNDTYPE boundtype /**< type of bound: lower or upper bound */
    13660 )
    13661{
    13662 SCIP_Real pseudoobjval;
    13663 int pseudoobjvalinf;
    13664 SCIP_Real obj;
    13665
    13666 pseudoobjval = getFinitePseudoObjval(lp, set, prob);
    13667 pseudoobjvalinf = lp->pseudoobjvalinf;
    13668 obj = SCIPvarGetObj(var);
    13669 if( !SCIPsetIsZero(set, obj) && boundtype == SCIPvarGetBestBoundType(var) )
    13670 {
    13671 SCIP_INTERVAL objint;
    13672 SCIP_INTERVAL bd;
    13673 SCIP_INTERVAL prod;
    13674 SCIP_INTERVAL psval;
    13675
    13676 SCIPintervalSet(&psval, pseudoobjval);
    13678 SCIPintervalSet(&objint, SCIPvarGetObj(var));
    13679 else
    13681
    13682 if( SCIPsetIsInfinity(set, REALABS(oldbound)) )
    13683 pseudoobjvalinf--;
    13684 else
    13685 {
    13686 SCIPintervalSet(&bd, oldbound);
    13687 SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, objint);
    13688 SCIPintervalSub(SCIPsetInfinity(set), &psval, psval, prod);
    13689 }
    13690 assert(pseudoobjvalinf >= 0);
    13691 if( SCIPsetIsInfinity(set, REALABS(newbound)) )
    13692 pseudoobjvalinf++;
    13693 else
    13694 {
    13695 SCIPintervalSet(&bd, newbound);
    13696 SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, objint);
    13697 SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, prod);
    13698 }
    13699
    13700 pseudoobjval = SCIPintervalGetInf(psval);
    13701 }
    13702 assert(pseudoobjvalinf >= 0);
    13703
    13704 if( pseudoobjvalinf > 0 || set->nactivepricers > 0 )
    13705 return -SCIPsetInfinity(set);
    13706 else
    13707 return pseudoobjval;
    13708}
    13709
    13710/** gets pseudo objective value, if a bound of the given variable would be modified in the given way */
    13712 SCIP_LP* lp, /**< current LP data */
    13713 SCIP_SET* set, /**< global SCIP settings */
    13714 SCIP_PROB* prob, /**< problem data */
    13715 SCIP_VAR* var, /**< problem variable */
    13716 SCIP_Real oldbound, /**< old value for bound */
    13717 SCIP_Real newbound, /**< new value for bound */
    13718 SCIP_BOUNDTYPE boundtype /**< type of bound: lower or upper bound */
    13719 )
    13720{
    13721 SCIP_Real pseudoobjval;
    13722 int pseudoobjvalinf;
    13723 SCIP_Real obj;
    13724
    13725 if( set->exact_enable )
    13726 return lpGetModifiedPseudoObjvalExact(lp, set, prob, var, oldbound, newbound, boundtype);
    13727
    13728 pseudoobjval = getFinitePseudoObjval(lp, set, prob);
    13729 pseudoobjvalinf = lp->pseudoobjvalinf;
    13730 obj = SCIPvarGetObj(var);
    13731 if( !SCIPsetIsZero(set, obj) && boundtype == SCIPvarGetBestBoundType(var) )
    13732 {
    13733 if( SCIPsetIsInfinity(set, REALABS(oldbound)) )
    13734 pseudoobjvalinf--;
    13735 else
    13736 pseudoobjval -= oldbound * obj;
    13737 assert(pseudoobjvalinf >= 0);
    13738 if( SCIPsetIsInfinity(set, REALABS(newbound)) )
    13739 pseudoobjvalinf++;
    13740 else
    13741 pseudoobjval += newbound * obj;
    13742 }
    13743 assert(pseudoobjvalinf >= 0);
    13744
    13745 if( pseudoobjvalinf > 0 || set->nactivepricers > 0 )
    13746 return -SCIPsetInfinity(set);
    13747 else
    13748 return pseudoobjval;
    13749}
    13750
    13751/** compute the objective delta due the new objective coefficient */
    13752static
    13754 SCIP_SET* set, /**< global SCIP settings */
    13755 SCIP_Real oldobj, /**< old objective value of variable */
    13756 SCIP_Real newobj, /**< new objective value of variable */
    13757 SCIP_Real lb, /**< lower bound of variable */
    13758 SCIP_Real ub, /**< upper bound of variable */
    13759 SCIP_Real* deltaval, /**< pointer to store the delta value */
    13760 int* deltainf /**< pointer to store the number of variables with infinite best bound */
    13761 )
    13762{
    13763 assert(!SCIPsetIsInfinity(set, REALABS(oldobj)));
    13764 assert(!SCIPsetIsInfinity(set, REALABS(newobj)));
    13765 assert(!SCIPsetIsInfinity(set, lb));
    13766 assert(!SCIPsetIsInfinity(set, -ub));
    13767 assert(!SCIPsetIsEQ(set, oldobj, newobj));
    13768
    13769 (*deltaval) = 0.0;
    13770 (*deltainf) = 0;
    13771
    13772 if( SCIPsetIsPositive(set, oldobj) )
    13773 {
    13774 /* sign of objective did not change */
    13775 if( SCIPsetIsPositive(set, newobj) )
    13776 {
    13777 /* if the bound is finite, calculate the deltaval */
    13778 if( !SCIPsetIsInfinity(set, -lb) )
    13779 (*deltaval) = lb * (newobj - oldobj);
    13780 }
    13781 /* sign of objective did change, so the best bound does change */
    13782 else if( SCIPsetIsNegative(set, newobj) )
    13783 {
    13784 if( SCIPsetIsInfinity(set, -lb) )
    13785 {
    13786 /* old best bound was infinite while new one is not */
    13787 if( !SCIPsetIsInfinity(set, ub) )
    13788 {
    13789 (*deltainf) = -1;
    13790 (*deltaval) = ub * newobj;
    13791 }
    13792 }
    13793 else
    13794 {
    13795 /* new best bound is infinite while old one was not */
    13796 if( SCIPsetIsInfinity(set, ub) )
    13797 {
    13798 (*deltainf) = 1;
    13799 (*deltaval) = -lb * oldobj;
    13800 }
    13801 /* neither old nor new best bound is infinite, so just calculate the deltaval */
    13802 else
    13803 {
    13804 (*deltaval) = (ub * newobj) - (lb * oldobj);
    13805 }
    13806 }
    13807 }
    13808 /* new objective is 0.0 */
    13809 else
    13810 {
    13811 if( SCIPsetIsInfinity(set, -lb) )
    13812 (*deltainf) = -1;
    13813 else
    13814 (*deltaval) = -lb * oldobj;
    13815 }
    13816 }
    13817 else if( SCIPsetIsNegative(set, oldobj) )
    13818 {
    13819 /* sign of objective did not change */
    13820 if( SCIPsetIsNegative(set, newobj) )
    13821 {
    13822 /* if the bound is finite, calculate the deltaval */
    13823 if( !SCIPsetIsInfinity(set, ub) )
    13824 (*deltaval) = ub * (newobj - oldobj);
    13825 }
    13826 /* sign of objective did change, so the best bound does change */
    13827 else if( SCIPsetIsPositive(set, newobj) )
    13828 {
    13829 if( SCIPsetIsInfinity(set, ub) )
    13830 {
    13831 /* old best bound was infinite while new one is not */
    13832 if( !SCIPsetIsInfinity(set, -lb) )
    13833 {
    13834 (*deltainf) = -1;
    13835 (*deltaval) = lb * newobj;
    13836 }
    13837 }
    13838 else
    13839 {
    13840 /* new best bound is infinite while old one was not */
    13841 if( SCIPsetIsInfinity(set, -lb) )
    13842 {
    13843 (*deltainf) = 1;
    13844 (*deltaval) = -ub * oldobj;
    13845 }
    13846 /* neither old nor new best bound is infinite, so just calculate the deltaval */
    13847 else
    13848 {
    13849 (*deltaval) = (lb * newobj) - (ub * oldobj);
    13850 }
    13851 }
    13852 }
    13853 /* new objective is 0.0 */
    13854 else
    13855 {
    13856 if( SCIPsetIsInfinity(set, ub) )
    13857 (*deltainf) = -1;
    13858 else
    13859 (*deltaval) = -ub * oldobj;
    13860 }
    13861 }
    13862 /* old objective was 0.0 */
    13863 else
    13864 {
    13865 if( SCIPsetIsNegative(set, newobj) )
    13866 {
    13867 if( SCIPsetIsInfinity(set, ub) )
    13868 (*deltainf) = 1;
    13869 else
    13870 (*deltaval) = ub * newobj;
    13871 }
    13872 else if( SCIPsetIsPositive(set, newobj) )
    13873 {
    13874 if( SCIPsetIsInfinity(set, -lb) )
    13875 (*deltainf) = 1;
    13876 else
    13877 (*deltaval) = lb * newobj;
    13878 }
    13879 }
    13880}
    13881
    13882/** compute the objective delta due the new lower bound */
    13883static
    13885 SCIP_SET* set, /**< global SCIP settings */
    13886 SCIP_Real obj, /**< objective value of variable */
    13887 SCIP_Real oldlb, /**< old lower bound of variable */
    13888 SCIP_Real newlb, /**< new lower bound of variable */
    13889 SCIP_Real* deltaval, /**< pointer to store the delta value */
    13890 int* deltainf /**< pointer to store the number of variables with infinite best bound */
    13891 )
    13892{
    13893 assert(obj > 0.0);
    13894 assert(!SCIPsetIsInfinity(set, obj));
    13895 assert(!SCIPsetIsInfinity(set, oldlb));
    13896 assert(!SCIPsetIsInfinity(set, newlb));
    13897 assert(newlb != oldlb); /*lint !e777*/
    13898
    13899 if( SCIPsetIsInfinity(set, -newlb) )
    13900 {
    13901 assert(!SCIPsetIsInfinity(set, -oldlb));
    13902
    13903 *deltainf = 1;
    13904 *deltaval = -obj * oldlb;
    13905 }
    13906 else if( SCIPsetIsInfinity(set, -oldlb) )
    13907 {
    13908 assert(!SCIPsetIsInfinity(set, -newlb));
    13909
    13910 *deltainf = -1;
    13911 *deltaval = obj * newlb;
    13912 }
    13913 else
    13914 {
    13915 *deltainf = 0;
    13916 *deltaval = obj * (newlb - oldlb);
    13917 }
    13918}
    13919
    13920/** compute the objective delta due the new upper bound */
    13921static
    13923 SCIP_SET* set, /**< global SCIP settings */
    13924 SCIP_Real obj, /**< objective value of variable */
    13925 SCIP_Real oldub, /**< old upper bound of variable */
    13926 SCIP_Real newub, /**< new upper bound of variable */
    13927 SCIP_Real* deltaval, /**< pointer to store the delta value */
    13928 int* deltainf /**< pointer to store the number of variables with infinite best bound */
    13929 )
    13930{
    13931 assert(obj < 0.0);
    13932 assert(!SCIPsetIsInfinity(set, -obj));
    13933 assert(!SCIPsetIsInfinity(set, -oldub));
    13934 assert(!SCIPsetIsInfinity(set, -newub));
    13935 assert(newub != oldub); /*lint !e777*/
    13936
    13937 if( SCIPsetIsInfinity(set, newub) )
    13938 {
    13939 assert(!SCIPsetIsInfinity(set, oldub));
    13940
    13941 *deltainf = 1;
    13942 *deltaval = -obj * oldub;
    13943 }
    13944 else if( SCIPsetIsInfinity(set, oldub) )
    13945 {
    13946 assert(!SCIPsetIsInfinity(set, newub));
    13947
    13948 *deltainf = -1;
    13949 *deltaval = obj * newub;
    13950 }
    13951 else
    13952 {
    13953 *deltainf = 0;
    13954 *deltaval = obj * (newub - oldub);
    13955 }
    13956}
    13957
    13958/** updates current pseudo and loose objective values for a change in a variable's objective value or bounds */
    13959static
    13961 SCIP_LP* lp, /**< current LP data */
    13962 SCIP_SET* set, /**< global SCIP settings */
    13963 SCIP_VAR* var, /**< problem variable that changed */
    13964 SCIP_Real deltaval, /**< delta value in the objective function */
    13965 int deltainf, /**< delta value for the number of variables with infinite best bound */
    13966 SCIP_Bool local, /**< should the local pseudo objective value be updated? */
    13967 SCIP_Bool loose, /**< should the loose objective value be updated? */
    13968 SCIP_Bool global /**< should the global pseudo objective value be updated? */
    13969 )
    13970{
    13971 assert(lp != NULL);
    13972 assert(lp->looseobjvalinf >= 0);
    13973 assert(lp->pseudoobjvalinf >= 0);
    13974 assert(lp->glbpseudoobjvalinf >= 0);
    13975
    13976 /* update the pseudo objective value */
    13977 if( local )
    13978 {
    13979 lp->pseudoobjvalinf += deltainf;
    13980 if( lp->pseudoobjvalid )
    13981 {
    13982 lp->pseudoobjval += deltaval;
    13983
    13984 /* if the absolute value was increased, this is regarded as reliable,
    13985 * otherwise, we check whether we can still trust the updated value
    13986 */
    13988 lp->relpseudoobjval = lp->pseudoobjval;
    13990 lp->pseudoobjvalid = FALSE;
    13991 }
    13992
    13993 /* after changing a local bound on a LOOSE variable, we have to update the loose objective value, too */
    13995 loose = TRUE;
    13996 }
    13997 /* update the loose objective value */
    13998 if( loose )
    13999 {
    14000 lp->looseobjvalinf += deltainf;
    14001
    14002 if( deltaval != 0.0 && lp->looseobjvalid )
    14003 {
    14004 lp->looseobjval += deltaval;
    14005
    14006 /* if the absolute value was increased, this is regarded as reliable,
    14007 * otherwise, we check whether we can still trust the updated value
    14008 */
    14009 if( REALABS(lp->rellooseobjval) < REALABS(lp->looseobjval) )
    14010 lp->rellooseobjval = lp->looseobjval;
    14012 lp->looseobjvalid = FALSE;
    14013 }
    14014 }
    14015 /* update the root pseudo objective values */
    14016 if( global )
    14017 {
    14018 lp->glbpseudoobjvalinf += deltainf;
    14019 if( lp->glbpseudoobjvalid )
    14020 {
    14021 lp->glbpseudoobjval += deltaval;
    14022
    14023 /* if the absolute value was increased, this is regarded as reliable,
    14024 * otherwise, we check whether we can still trust the updated value
    14025 */
    14030 }
    14031 }
    14032
    14033 assert(lp->looseobjvalinf >= 0);
    14034 assert(lp->pseudoobjvalinf >= 0);
    14035 assert(lp->glbpseudoobjvalinf >= 0);
    14036}
    14037
    14038/** updates current pseudo and loose objective values for a change in a variable's objective value or bounds;
    14039 * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
    14040 */
    14041static
    14043 SCIP_LP* lp, /**< current LP data */
    14044 SCIP_SET* set, /**< global SCIP settings */
    14045 SCIP_VAR* var, /**< problem variable that changed */
    14046 SCIP_Real oldobj, /**< old objective value of variable */
    14047 SCIP_Real oldlb, /**< old objective value of variable */
    14048 SCIP_Real oldub, /**< old objective value of variable */
    14049 SCIP_Real newobj, /**< new objective value of variable */
    14050 SCIP_Real newlb, /**< new objective value of variable */
    14051 SCIP_Real newub, /**< new objective value of variable */
    14052 SCIP_Bool global /**< is the change global? */
    14053 )
    14054{
    14055 SCIP_INTERVAL deltaval;
    14056 SCIP_INTERVAL bd;
    14057 SCIP_INTERVAL obj;
    14058 SCIP_INTERVAL prod;
    14059 SCIP_INTERVAL psval;
    14060 int deltainf;
    14061
    14062 assert(lp != NULL);
    14063 assert(lp->pseudoobjvalinf >= 0);
    14064 assert(lp->looseobjvalinf >= 0);
    14065 assert(!SCIPsetIsInfinity(set, REALABS(oldobj)));
    14066 assert(!SCIPsetIsInfinity(set, oldlb));
    14067 assert(!SCIPsetIsInfinity(set, -oldub));
    14068 assert(!SCIPsetIsInfinity(set, REALABS(newobj)));
    14069 assert(!SCIPsetIsInfinity(set, newlb));
    14070 assert(!SCIPsetIsInfinity(set, -newub));
    14071 assert(var != NULL);
    14072
    14074 {
    14075 SCIPerrorMessage("LP was informed of an objective change of a non-active variable\n");
    14076 return SCIP_INVALIDDATA;
    14077 }
    14078
    14079 assert(SCIPvarGetProbindex(var) >= 0);
    14080
    14081 SCIPintervalSet(&deltaval, 0.0);
    14082 deltainf = 0;
    14083
    14084 /* subtract old pseudo objective value */
    14085 if( oldobj > 0.0 )
    14086 {
    14087 if( SCIPsetIsInfinity(set, -oldlb) )
    14088 deltainf--;
    14089 else
    14090 {
    14091 SCIPintervalSet(&bd, oldlb);
    14092 SCIPintervalSet(&obj, oldobj);
    14093 SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
    14094 SCIPintervalSub(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval -= oldlb * oldobj; */
    14095 }
    14096 }
    14097 else if( oldobj < 0.0 )
    14098 {
    14099 if( SCIPsetIsInfinity(set, oldub) )
    14100 deltainf--;
    14101 else
    14102 {
    14103 SCIPintervalSet(&bd, oldub);
    14104 SCIPintervalSet(&obj, oldobj);
    14105 SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
    14106 SCIPintervalSub(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval -= oldub * oldobj; */
    14107 }
    14108 }
    14109
    14110 /* add new pseudo objective value */
    14111 if( newobj > 0.0 )
    14112 {
    14113 if( SCIPsetIsInfinity(set, -newlb) )
    14114 deltainf++;
    14115 else
    14116 {
    14117 SCIPintervalSet(&bd, newlb);
    14118 SCIPintervalSet(&obj, newobj);
    14119 SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
    14120 SCIPintervalAdd(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval += newlb * newobj; */
    14121 }
    14122 }
    14123 else if( newobj < 0.0 )
    14124 {
    14125 if( SCIPsetIsInfinity(set, newub) )
    14126 deltainf++;
    14127 else
    14128 {
    14129 SCIPintervalSet(&bd, newub);
    14130 SCIPintervalSet(&obj, newobj);
    14131 SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
    14132 SCIPintervalAdd(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval += newub * newobj; */
    14133 }
    14134 }
    14135
    14136 /* update the pseudo and loose objective values */
    14137 if( global )
    14138 {
    14139 SCIPintervalSet(&psval, lp->glbpseudoobjval);
    14140 SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, deltaval);
    14142 lp->glbpseudoobjvalinf += deltainf;
    14143 }
    14144 else
    14145 {
    14146 SCIPintervalSet(&psval, lp->pseudoobjval);
    14147 SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, deltaval);
    14148 lp->pseudoobjval = SCIPintervalGetInf(psval);
    14149 lp->pseudoobjvalinf += deltainf;
    14151 {
    14152 SCIPintervalSet(&psval, lp->looseobjval);
    14153 SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, deltaval);
    14154 lp->looseobjval = SCIPintervalGetInf(psval);
    14155 lp->looseobjvalinf += deltainf;
    14156 }
    14157
    14158 assert(lp->pseudoobjvalinf >= 0);
    14159 assert(lp->looseobjvalinf >= 0);
    14160 }
    14161
    14162 return SCIP_OKAY;
    14163}
    14164
    14165/** updates current pseudo and loose objective value for a change in a variable's objective coefficient */
    14167 SCIP_LP* lp, /**< current LP data */
    14168 SCIP_SET* set, /**< global SCIP settings */
    14169 SCIP_VAR* var, /**< problem variable that changed */
    14170 SCIP_Real oldobj, /**< old objective coefficient of variable */
    14171 SCIP_Real newobj /**< new objective coefficient of variable */
    14172 )
    14173{
    14174 assert(set != NULL);
    14175 assert(var != NULL);
    14176
    14177 if( set->exact_enable )
    14178 {
    14179 if( oldobj != newobj ) /*lint !e777*/
    14180 {
    14182 newobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var), FALSE) );
    14183 /* the global ps objval can be set directly because the global and local bounds have to be the same here (see below) */
    14186
    14187 lp->glbpseudoobjval = lp->pseudoobjval;
    14189 }
    14190 }
    14191 else
    14192 {
    14193 if( !SCIPsetIsEQ(set, oldobj, newobj) )
    14194 {
    14195 SCIP_Real deltaval;
    14196 int deltainf;
    14197
    14199 assert(SCIPvarGetProbindex(var) >= 0);
    14200
    14201 /* the objective coefficient can only be changed during presolving, that implies that the global and local
    14202 * domain of the variable are the same
    14203 */
    14204 assert(lp->probing || SCIPsetIsEQ(set, SCIPvarGetLbGlobal(var), SCIPvarGetLbLocal(var)));
    14205 assert(lp->probing || SCIPsetIsEQ(set, SCIPvarGetUbGlobal(var), SCIPvarGetUbLocal(var)));
    14206
    14207 /* compute the pseudo objective delta due the new objective coefficient */
    14208 getObjvalDeltaObj(set, oldobj, newobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var), &deltaval, &deltainf);
    14209
    14210 /* update the local pseudo objective value */
    14211 lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
    14212
    14213 /* compute the pseudo objective delta due the new objective coefficient */
    14214 getObjvalDeltaObj(set, oldobj, newobj, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var), &deltaval, &deltainf);
    14215
    14216 /* update the global pseudo objective value */
    14217 lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
    14218 }
    14219 }
    14220
    14221 return SCIP_OKAY;
    14222}
    14223
    14224
    14225/** updates current root pseudo objective value for a global change in a variable's lower bound */
    14227 SCIP_LP* lp, /**< current LP data */
    14228 SCIP_SET* set, /**< global SCIP settings */
    14229 SCIP_VAR* var, /**< problem variable that changed */
    14230 SCIP_Real oldlb, /**< old lower bound of variable */
    14231 SCIP_Real newlb /**< new lower bound of variable */
    14232 )
    14233{
    14234 assert(set != NULL);
    14235 assert(var != NULL);
    14236
    14237 if( set->exact_enable )
    14238 {
    14239 if( oldlb != newlb && SCIPvarGetObj(var) > 0.0 ) /*lint !e777*/
    14240 {
    14241 SCIP_CALL( lpUpdateVarProved(lp, set, var, SCIPvarGetObj(var), oldlb, SCIPvarGetUbGlobal(var),
    14242 SCIPvarGetObj(var), newlb, SCIPvarGetUbGlobal(var), TRUE) );
    14243 }
    14244 }
    14245 else
    14246 {
    14247 if( !SCIPsetIsEQ(set, oldlb, newlb) && SCIPsetIsPositive(set, SCIPvarGetObj(var)) )
    14248 {
    14249 SCIP_Real deltaval;
    14250 int deltainf;
    14251
    14252 /* compute the pseudo objective delta due the new lower bound */
    14253 getObjvalDeltaLb(set, SCIPvarGetObj(var), oldlb, newlb, &deltaval, &deltainf);
    14254
    14255 /* update the root pseudo objective values */
    14256 lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
    14257 }
    14258 }
    14259
    14260 return SCIP_OKAY;
    14261}
    14262
    14263/** updates current pseudo and loose objective value for a change in a variable's lower bound */
    14265 SCIP_LP* lp, /**< current LP data */
    14266 SCIP_SET* set, /**< global SCIP settings */
    14267 SCIP_VAR* var, /**< problem variable that changed */
    14268 SCIP_Real oldlb, /**< old lower bound of variable */
    14269 SCIP_Real newlb /**< new lower bound of variable */
    14270 )
    14271{
    14272 assert(set != NULL);
    14273 assert(var != NULL);
    14274
    14275 if( set->exact_enable )
    14276 {
    14277 if( oldlb != newlb && SCIPvarGetObj(var) > 0.0 ) /*lint !e777*/
    14278 {
    14279 SCIP_CALL( lpUpdateVarProved(lp, set, var, SCIPvarGetObj(var), oldlb, SCIPvarGetUbLocal(var),
    14280 SCIPvarGetObj(var), newlb, SCIPvarGetUbLocal(var), FALSE) );
    14281 }
    14282 }
    14283 else
    14284 {
    14285 if( !SCIPsetIsEQ(set, oldlb, newlb) && SCIPsetIsPositive(set, SCIPvarGetObj(var)) )
    14286 {
    14287 SCIP_Real deltaval;
    14288 int deltainf;
    14289
    14291 assert(SCIPvarGetProbindex(var) >= 0);
    14292
    14293 /* compute the pseudo objective delta due the new lower bound */
    14294 getObjvalDeltaLb(set, SCIPvarGetObj(var), oldlb, newlb, &deltaval, &deltainf);
    14295
    14296 /* update the pseudo and loose objective values */
    14297 lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
    14298 }
    14299 }
    14300
    14301 return SCIP_OKAY;
    14302}
    14303
    14304/** updates current root pseudo objective value for a global change in a variable's upper bound */
    14306 SCIP_LP* lp, /**< current LP data */
    14307 SCIP_SET* set, /**< global SCIP settings */
    14308 SCIP_VAR* var, /**< problem variable that changed */
    14309 SCIP_Real oldub, /**< old upper bound of variable */
    14310 SCIP_Real newub /**< new upper bound of variable */
    14311 )
    14312{
    14313 assert(set != NULL);
    14314 assert(var != NULL);
    14315
    14316 if( set->exact_enable )
    14317 {
    14318 if( oldub != newub && SCIPvarGetObj(var) < 0.0 ) /*lint !e777*/
    14319 {
    14320 SCIP_CALL( lpUpdateVarProved(lp, set, var, SCIPvarGetObj(var), SCIPvarGetLbGlobal(var), oldub,
    14321 SCIPvarGetObj(var), SCIPvarGetLbGlobal(var), newub, TRUE) );
    14322 }
    14323 }
    14324 else
    14325 {
    14326 if( !SCIPsetIsEQ(set, oldub, newub) && SCIPsetIsNegative(set, SCIPvarGetObj(var)) )
    14327 {
    14328 SCIP_Real deltaval;
    14329 int deltainf;
    14330
    14331 /* compute the pseudo objective delta due the new upper bound */
    14332 getObjvalDeltaUb(set, SCIPvarGetObj(var), oldub, newub, &deltaval, &deltainf);
    14333
    14334 /* update the root pseudo objective values */
    14335 lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
    14336 }
    14337 }
    14338
    14339 return SCIP_OKAY;
    14340}
    14341
    14342/** updates current pseudo objective value for a change in a variable's upper bound */
    14344 SCIP_LP* lp, /**< current LP data */
    14345 SCIP_SET* set, /**< global SCIP settings */
    14346 SCIP_VAR* var, /**< problem variable that changed */
    14347 SCIP_Real oldub, /**< old upper bound of variable */
    14348 SCIP_Real newub /**< new upper bound of variable */
    14349 )
    14350{
    14351 assert(set != NULL);
    14352 assert(var != NULL);
    14353
    14354 if( set->exact_enable )
    14355 {
    14356 if( oldub != newub && SCIPvarGetObj(var) < 0.0 ) /*lint !e777*/
    14357 {
    14358 SCIP_CALL( lpUpdateVarProved(lp, set, var, SCIPvarGetObj(var), SCIPvarGetLbLocal(var), oldub,
    14359 SCIPvarGetObj(var), SCIPvarGetLbLocal(var), newub, FALSE) );
    14360 }
    14361 }
    14362 else
    14363 {
    14364 if( !SCIPsetIsEQ(set, oldub, newub) && SCIPsetIsNegative(set, SCIPvarGetObj(var)) )
    14365 {
    14366 SCIP_Real deltaval;
    14367 int deltainf;
    14368
    14370 assert(SCIPvarGetProbindex(var) >= 0);
    14371
    14372 /* compute the pseudo objective delta due the new upper bound */
    14373 getObjvalDeltaUb(set, SCIPvarGetObj(var), oldub, newub, &deltaval, &deltainf);
    14374
    14375 /* update the pseudo and loose objective values */
    14376 lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
    14377 }
    14378 }
    14379
    14380 return SCIP_OKAY;
    14381}
    14382
    14383/** informs LP, that given variable was added to the problem */
    14385 SCIP_LP* lp, /**< current LP data */
    14386 SCIP_SET* set, /**< global SCIP settings */
    14387 SCIP_VAR* var /**< variable that is now a LOOSE problem variable */
    14388 )
    14389{
    14390 assert(lp != NULL);
    14392 assert(SCIPvarGetProbindex(var) >= 0);
    14393
    14394 /* add the variable to the loose objective value sum */
    14395 SCIP_CALL( SCIPlpUpdateVarObj(lp, set, var, 0.0, SCIPvarGetObj(var)) );
    14396
    14397 /* update the loose variables counter */
    14399 lp->nloosevars++;
    14400
    14401 return SCIP_OKAY;
    14402}
    14403
    14404/** informs LP, that given variable is to be deleted from the problem */
    14406 SCIP_LP* lp, /**< current LP data */
    14407 SCIP_SET* set, /**< global SCIP settings */
    14408 SCIP_VAR* var /**< variable that will be deleted from the problem */
    14409 )
    14410{
    14411 assert(lp != NULL);
    14413 assert(SCIPvarGetProbindex(var) >= 0);
    14414
    14415 /* subtract the variable from the loose objective value sum */
    14416 SCIP_CALL( SCIPlpUpdateVarObj(lp, set, var, SCIPvarGetObj(var), 0.0) );
    14417
    14418 /* update the loose variables counter */
    14420 {
    14422 }
    14423
    14424 return SCIP_OKAY;
    14425}
    14426
    14427/** informs LP, that given formerly loose problem variable is now a column variable */
    14428static
    14430 SCIP_LP* lp, /**< current LP data */
    14431 SCIP_SET* set, /**< global SCIP settings */
    14432 SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
    14433 )
    14434{
    14435 SCIP_Real obj;
    14436 SCIP_Real lb;
    14437 SCIP_Real ub;
    14438
    14439 assert(lp != NULL);
    14440 assert(lp->nloosevars > 0);
    14442 assert(SCIPvarGetProbindex(var) >= 0);
    14443 assert(lp->looseobjvalinf >= 0);
    14444
    14445 obj = SCIPvarGetObj(var);
    14446
    14447 /* update loose objective value */
    14448 if( SCIPsetIsPositive(set, obj) )
    14449 {
    14450 lb = SCIPvarGetLbLocal(var);
    14451 if( SCIPsetIsInfinity(set, -lb) )
    14452 lp->looseobjvalinf--;
    14453 else
    14454 lpUpdateObjval(lp, set, var, -lb * obj, 0, FALSE, TRUE, FALSE);
    14455 }
    14456 else if( SCIPsetIsNegative(set, obj) )
    14457 {
    14458 ub = SCIPvarGetUbLocal(var);
    14459 if( SCIPsetIsInfinity(set, ub) )
    14460 lp->looseobjvalinf--;
    14461 else
    14462 lpUpdateObjval(lp, set, var, -ub * obj, 0, FALSE, TRUE, FALSE);
    14463 }
    14464
    14466
    14467 assert(lp->looseobjvalinf >= 0);
    14468
    14469 return SCIP_OKAY;
    14470}
    14471
    14472/** informs LP, that given formerly loose problem variable is now a column variable
    14473 * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
    14474 */
    14475static
    14477 SCIP_LP* lp, /**< current LP data */
    14478 SCIP_SET* set, /**< global SCIP settings */
    14479 SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
    14480 )
    14481{
    14482 SCIP_INTERVAL bd;
    14483 SCIP_INTERVAL ob;
    14484 SCIP_INTERVAL prod;
    14485 SCIP_INTERVAL loose;
    14486 SCIP_Real obj;
    14487 SCIP_Real lb;
    14488 SCIP_Real ub;
    14489
    14490 assert(lp != NULL);
    14491 assert(lp->nloosevars > 0);
    14493 assert(SCIPvarGetProbindex(var) >= 0);
    14494
    14495 obj = SCIPvarGetObj(var);
    14496
    14497 SCIPintervalSet(&loose, lp->looseobjval);
    14498
    14499 /* update loose objective value corresponding to the deletion of variable */
    14500 if( obj > 0.0 )
    14501 {
    14502 lb = SCIPvarGetLbLocal(var);
    14503 if( SCIPsetIsInfinity(set, -lb) )
    14504 lp->looseobjvalinf--;
    14505 else
    14506 {
    14507 SCIPintervalSet(&bd, lb);
    14508 SCIPintervalSet(&ob, obj);
    14509 SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
    14510 SCIPintervalSub(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval -= lb * obj; */
    14511 }
    14512 }
    14513 else if( obj < 0.0 )
    14514 {
    14515 ub = SCIPvarGetUbLocal(var);
    14516 if( SCIPsetIsInfinity(set, ub) )
    14517 lp->looseobjvalinf--;
    14518 else
    14519 {
    14520 SCIPintervalSet(&bd, ub);
    14521 SCIPintervalSet(&ob, obj);
    14522 SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
    14523 SCIPintervalSub(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval -= ub * obj; */
    14524 }
    14525 }
    14526 lp->nloosevars--;
    14527
    14528 /* get rid of numerical problems: set loose objective value explicitly to zero, if no loose variables remain */
    14529 if( lp->nloosevars == 0 )
    14530 {
    14531 assert(lp->looseobjvalinf == 0);
    14532 lp->looseobjval = 0.0;
    14533 }
    14534 else
    14535 lp->looseobjval = SCIPintervalGetInf(loose);
    14536
    14537 return SCIP_OKAY;
    14538}
    14539
    14540/** informs LP, that given formerly loose problem variable is now a column variable */
    14542 SCIP_LP* lp, /**< current LP data */
    14543 SCIP_SET* set, /**< global SCIP settings */
    14544 SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
    14545 )
    14546{
    14547 assert(set != NULL);
    14548
    14549 if( set->exact_enable )
    14550 {
    14552 }
    14553 else
    14554 {
    14555 SCIP_CALL( lpUpdateVarColumn(lp, set, var) );
    14556 }
    14557
    14558 return SCIP_OKAY;
    14559}
    14560
    14561/** informs LP, that given formerly column problem variable is now again a loose variable */
    14562static
    14564 SCIP_LP* lp, /**< current LP data */
    14565 SCIP_SET* set, /**< global SCIP settings */
    14566 SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
    14567 )
    14568{
    14569 SCIP_Real obj;
    14570 SCIP_Real lb;
    14571 SCIP_Real ub;
    14572
    14573 assert(lp != NULL);
    14574 assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE);
    14575 assert(SCIPvarGetProbindex(var) >= 0);
    14576 assert(lp->looseobjvalinf >= 0);
    14577
    14578 obj = SCIPvarGetObj(var);
    14579
    14580 /* update loose objective value corresponding to the addition of variable */
    14581 if( SCIPsetIsPositive(set, obj) )
    14582 {
    14583 lb = SCIPvarGetLbLocal(var);
    14584 if( SCIPsetIsInfinity(set, -lb) )
    14585 lp->looseobjvalinf++;
    14586 else
    14587 lpUpdateObjval(lp, set, var, lb * obj, 0, FALSE, TRUE, FALSE);
    14588 }
    14589 else if( SCIPsetIsNegative(set, obj) )
    14590 {
    14591 ub = SCIPvarGetUbLocal(var);
    14592 if( SCIPsetIsInfinity(set, ub) )
    14593 lp->looseobjvalinf++;
    14594 else
    14595 lpUpdateObjval(lp, set, var, ub * obj, 0, FALSE, TRUE, FALSE);
    14596 }
    14597 lp->nloosevars++;
    14598
    14599 assert(lp->looseobjvalinf >= 0);
    14600
    14601 return SCIP_OKAY;
    14602}
    14603
    14604/** informs LP, that given formerly column problem variable is now again a loose variable
    14605 * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
    14606 */
    14607static
    14609 SCIP_LP* lp, /**< current LP data */
    14610 SCIP_SET* set, /**< global SCIP settings */
    14611 SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
    14612 )
    14613{
    14614 SCIP_INTERVAL bd;
    14615 SCIP_INTERVAL ob;
    14616 SCIP_INTERVAL prod;
    14617 SCIP_INTERVAL loose;
    14618 SCIP_Real obj;
    14619 SCIP_Real lb;
    14620 SCIP_Real ub;
    14621
    14622 assert(lp != NULL);
    14623 assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE);
    14624 assert(SCIPvarGetProbindex(var) >= 0);
    14625
    14626 obj = SCIPvarGetObj(var);
    14627
    14628 SCIPintervalSet(&loose, lp->looseobjval);
    14629
    14630 /* update loose objective value corresponding to the deletion of variable */
    14631 if( obj > 0.0 )
    14632 {
    14633 lb = SCIPvarGetLbLocal(var);
    14634 if( SCIPsetIsInfinity(set, -lb) )
    14635 lp->looseobjvalinf++;
    14636 else
    14637 {
    14638 SCIPintervalSet(&bd, lb);
    14639 SCIPintervalSet(&ob, obj);
    14640 SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
    14641 SCIPintervalAdd(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval += lb * obj; */
    14642 }
    14643 }
    14644 else if( SCIPsetIsNegative(set, obj) )
    14645 {
    14646 ub = SCIPvarGetUbLocal(var);
    14647 if( SCIPsetIsInfinity(set, ub) )
    14648 lp->looseobjvalinf++;
    14649 else
    14650 {
    14651 SCIPintervalSet(&bd, ub);
    14652 SCIPintervalSet(&ob, obj);
    14653 SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
    14654 SCIPintervalAdd(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval += ub * obj; */
    14655 }
    14656 }
    14657 lp->nloosevars++;
    14658
    14659 lp->looseobjval = SCIPintervalGetInf(loose);
    14660
    14661 return SCIP_OKAY;
    14662}
    14663
    14664/** informs LP, that given formerly column problem variable is now again a loose variable */
    14666 SCIP_LP* lp, /**< current LP data */
    14667 SCIP_SET* set, /**< global SCIP settings */
    14668 SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
    14669 )
    14670{
    14671 assert(set != NULL);
    14672
    14673 if( set->exact_enable )
    14674 {
    14676 }
    14677 else
    14678 {
    14679 SCIP_CALL( lpUpdateVarLoose(lp, set, var) );
    14680 }
    14681
    14682 return SCIP_OKAY;
    14683}
    14684
    14685/** decrease the number of loose variables by one */
    14687 SCIP_LP* lp /**< current LP data */
    14688 )
    14689{
    14690 assert(lp != NULL);
    14691 assert(lp->nloosevars > 0);
    14692
    14693 lp->nloosevars--;
    14694
    14695 /* get rid of numerical problems: set loose objective value explicitly to zero, if no loose variables remain */
    14696 if( lp->nloosevars == 0 )
    14697 {
    14698 assert(lp->looseobjvalinf == 0);
    14699 lp->looseobjval = 0.0;
    14700 }
    14701}
    14702
    14703/** stores the LP solution in the columns and rows */
    14705 SCIP_LP* lp, /**< current LP data */
    14706 SCIP_SET* set, /**< global SCIP settings */
    14707 SCIP_STAT* stat, /**< problem statistics */
    14708 SCIP_Bool* primalfeasible, /**< pointer to store whether the solution is primal feasible, or NULL */
    14709 SCIP_Bool* dualfeasible /**< pointer to store whether the solution is dual feasible, or NULL */
    14710 )
    14711{
    14712 SCIP_COL** lpicols;
    14713 SCIP_ROW** lpirows;
    14714 SCIP_Real* primsol;
    14715 SCIP_Real* dualsol;
    14716 SCIP_Real* activity = NULL;
    14717 SCIP_Real* redcost;
    14718 SCIP_Real primalbound;
    14719 SCIP_Real dualbound;
    14720 SCIP_Bool stillprimalfeasible;
    14721 SCIP_Bool stilldualfeasible;
    14722 int* cstat;
    14723 int* rstat;
    14724 SCIP_Longint lpcount;
    14725 int nlpicols;
    14726 int nlpirows;
    14727 int c;
    14728 int r;
    14729
    14730 assert(lp != NULL);
    14731 assert(lp->flushed);
    14732 assert(lp->solved);
    14733 assert(set != NULL);
    14734 assert(stat != NULL);
    14735 assert(lp->validsollp <= stat->lpcount);
    14736
    14737 /* initialize return and feasibility flags; if primal oder dual feasibility shall not be checked, we set the
    14738 * corresponding flag immediately to FALSE to skip all checks
    14739 */
    14740 if( primalfeasible == NULL )
    14741 stillprimalfeasible = FALSE;
    14742 else
    14743 {
    14744 *primalfeasible = TRUE;
    14745 stillprimalfeasible = TRUE;
    14746 }
    14747 if( dualfeasible == NULL )
    14748 stilldualfeasible = FALSE;
    14749 else
    14750 {
    14751 *dualfeasible = TRUE;
    14752 stilldualfeasible = TRUE;
    14753 }
    14754
    14755 /* check if the values are already calculated */
    14756 if( lp->validsollp == stat->lpcount )
    14757 return SCIP_OKAY;
    14758 lp->validsollp = stat->lpcount;
    14759
    14760 SCIPsetDebugMsg(set, "getting new LP solution %" SCIP_LONGINT_FORMAT " for solstat %d\n",
    14761 stat->lpcount, SCIPlpGetSolstat(lp));
    14762
    14763 lpicols = lp->lpicols;
    14764 lpirows = lp->lpirows;
    14765 nlpicols = lp->nlpicols;
    14766 nlpirows = lp->nlpirows;
    14767 lpcount = stat->lpcount;
    14768
    14769 /* get temporary memory */
    14770 SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, nlpicols) );
    14771 SCIP_CALL( SCIPsetAllocBufferArray(set, &dualsol, nlpirows) );
    14772#ifdef SCIP_USE_LPSOLVER_ACTIVITY
    14773 SCIP_CALL( SCIPsetAllocBufferArray(set, &activity, nlpirows) );
    14774#endif
    14775 SCIP_CALL( SCIPsetAllocBufferArray(set, &redcost, nlpicols) );
    14776 SCIP_CALL( SCIPsetAllocBufferArray(set, &cstat, nlpicols) );
    14777 SCIP_CALL( SCIPsetAllocBufferArray(set, &rstat, nlpirows) );
    14778
    14779 SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, dualsol, activity, redcost) );
    14780 if( lp->solisbasic )
    14781 {
    14782 SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
    14783 }
    14784 else
    14785 {
    14786 BMSclearMemoryArray(cstat, nlpicols);
    14787 BMSclearMemoryArray(rstat, nlpirows);
    14788 }
    14789
    14790 primalbound = 0.0;
    14791 dualbound = 0.0;
    14792
    14793 /* copy primal solution and reduced costs into columns */
    14794 for( c = 0; c < nlpicols; ++c )
    14795 {
    14796 assert( 0 <= cstat[c] && cstat[c] < 4 );
    14797 lpicols[c]->primsol = primsol[c];
    14798 if( !SCIPisFinite(lpicols[c]->primsol) )
    14799 {
    14800 /* calculating with nan or +/-inf can have many unexpected effects
    14801 * thus change the solution here to a reasonable value (0.0) and declare it as neither primal nor dual feasible
    14802 * this should trigger a resolve of the LP, or a stop with an LP error
    14803 */
    14804 stillprimalfeasible = FALSE;
    14805 stilldualfeasible = FALSE;
    14806 lpicols[c]->primsol = 0.0;
    14807 SCIPsetDebugMsg(set, " col <%s>: primsol=%.9f is not finite\n", SCIPvarGetName(lpicols[c]->var), primsol[c]);
    14808 }
    14809 lpicols[c]->minprimsol = MIN(lpicols[c]->minprimsol, primsol[c]);
    14810 lpicols[c]->maxprimsol = MAX(lpicols[c]->maxprimsol, primsol[c]);
    14811 lpicols[c]->redcost = redcost[c];
    14812 lpicols[c]->basisstatus = (unsigned int) cstat[c];
    14813 lpicols[c]->validredcostlp = lpcount;
    14814 if( stillprimalfeasible )
    14815 {
    14816 stillprimalfeasible =
    14817 (SCIPsetIsInfinity(set, -lpicols[c]->lb) || SCIPlpIsFeasGE(set, lp, lpicols[c]->primsol, lpicols[c]->lb))
    14818 && (SCIPsetIsInfinity(set, lpicols[c]->ub) || SCIPlpIsFeasLE(set, lp, lpicols[c]->primsol, lpicols[c]->ub));
    14819 primalbound += (lpicols[c]->primsol * lpicols[c]->obj);
    14820 }
    14821 if( lp->lastlpalgo == SCIP_LPALGO_BARRIER )
    14822 {
    14823 double compslack;
    14824
    14825 /* complementary slackness in barrier solutions is measured as product of primal slack and dual multiplier;
    14826 * we use a slack of at most 1, because otherwise we multiply by something like SCIPinfinty() for unbounded
    14827 * variables, which would magnify even the tiniest violation in the dual multiplier
    14828 */
    14829 if( stilldualfeasible )
    14830 {
    14831 compslack = MIN((lpicols[c]->primsol - lpicols[c]->lb), 1.0) * lpicols[c]->redcost;
    14832 stilldualfeasible = !SCIPsetIsDualfeasPositive(set, compslack);
    14833 }
    14834 if( stilldualfeasible )
    14835 {
    14836 compslack = MIN((lpicols[c]->ub - lpicols[c]->primsol), 1.0) * lpicols[c]->redcost;
    14837 stilldualfeasible = !SCIPsetIsDualfeasNegative(set, compslack);
    14838 }
    14839
    14840 SCIPsetDebugMsg(set, " col <%s> [%.9g,%.9g]: primsol=%.9f, redcost=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
    14841 SCIPvarGetName(lpicols[c]->var), lpicols[c]->lb, lpicols[c]->ub, lpicols[c]->primsol, lpicols[c]->redcost,
    14842 SCIPlpIsFeasGE(set, lp, lpicols[c]->primsol, lpicols[c]->lb),
    14843 SCIPlpIsFeasLE(set, lp, lpicols[c]->primsol, lpicols[c]->ub),
    14844 primalfeasible != NULL ? stillprimalfeasible : TRUE,
    14845 !SCIPsetIsDualfeasPositive(set, MIN((lpicols[c]->primsol - lpicols[c]->lb), 1.0) * lpicols[c]->redcost),
    14846 !SCIPsetIsDualfeasNegative(set, MIN((lpicols[c]->ub - lpicols[c]->primsol), 1.0) * lpicols[c]->redcost),
    14847 dualfeasible != NULL ? stilldualfeasible : TRUE);
    14848 }
    14849 else
    14850 {
    14851 /* if dual feasibility check is disabled, set reduced costs of basic variables to 0 */
    14852 if( dualfeasible == NULL && lpicols[c]->basisstatus == (unsigned int) SCIP_BASESTAT_BASIC )
    14853 {
    14854 lpicols[c]->redcost = 0.0;
    14855 }
    14856
    14857 /* complementary slackness means that if a variable is not at its lower or upper bound, its reduced costs
    14858 * must be non-positive or non-negative, respectively; in particular, if a variable is strictly within its
    14859 * bounds, its reduced cost must be zero
    14860 */
    14861 if( stilldualfeasible
    14862 && (SCIPsetIsInfinity(set, -lpicols[c]->lb) || SCIPlpIsFeasGT(set, lp, lpicols[c]->primsol, lpicols[c]->lb)) )
    14863 stilldualfeasible = !SCIPsetIsDualfeasPositive(set, lpicols[c]->redcost);
    14864 if( stilldualfeasible
    14865 && (SCIPsetIsInfinity(set, lpicols[c]->ub) || SCIPlpIsFeasLT(set, lp, lpicols[c]->primsol, lpicols[c]->ub)) )
    14866 stilldualfeasible = !SCIPsetIsDualfeasNegative(set, lpicols[c]->redcost);
    14867
    14868 SCIPsetDebugMsg(set, " col <%s> [%.9g,%.9g]: primsol=%.9f, redcost=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
    14869 SCIPvarGetName(lpicols[c]->var), lpicols[c]->lb, lpicols[c]->ub, lpicols[c]->primsol, lpicols[c]->redcost,
    14870 SCIPlpIsFeasGE(set, lp, lpicols[c]->primsol, lpicols[c]->lb),
    14871 SCIPlpIsFeasLE(set, lp, lpicols[c]->primsol, lpicols[c]->ub),
    14872 primalfeasible != NULL ? stillprimalfeasible : TRUE,
    14873 !SCIPlpIsFeasGT(set, lp, lpicols[c]->primsol, lpicols[c]->lb) || !SCIPsetIsDualfeasPositive(set, lpicols[c]->redcost),
    14874 !SCIPlpIsFeasLT(set, lp, lpicols[c]->primsol, lpicols[c]->ub) || !SCIPsetIsDualfeasNegative(set, lpicols[c]->redcost),
    14875 dualfeasible != NULL ? stilldualfeasible : TRUE);
    14876 }
    14877
    14878 /* we intentionally use an exact positive/negative check because ignoring small reduced cost values may lead to a
    14879 * wrong bound value; if the corresponding bound is +/-infinity, we use zero reduced cost (if stilldualfeasible is
    14880 * TRUE, we are in the case that the reduced cost is tiny with wrong sign)
    14881 */
    14882 if( stilldualfeasible )
    14883 {
    14884 if( lpicols[c]->redcost > 0.0 && !SCIPsetIsInfinity(set, -lpicols[c]->lb) )
    14885 dualbound += (lpicols[c]->redcost * lpicols[c]->lb);
    14886 else if( lpicols[c]->redcost < 0.0 && !SCIPsetIsInfinity(set, lpicols[c]->ub) )
    14887 dualbound += (lpicols[c]->redcost * lpicols[c]->ub);
    14888 }
    14889 }
    14890
    14891 /* copy dual solution and activities into rows */
    14892 for( r = 0; r < nlpirows; ++r )
    14893 {
    14894 assert( 0 <= rstat[r] && rstat[r] < 4 );
    14895 lpirows[r]->dualsol = dualsol[r];
    14896#ifdef SCIP_USE_LPSOLVER_ACTIVITY
    14897 lpirows[r]->activity = activity[r] + lpirows[r]->constant;
    14898#else
    14899 /* calculate row activity if invalid */
    14900 if( lpirows[r]->validactivitylp != stat->lpcount )
    14901 SCIProwRecalcLPActivity(lpirows[r], stat);
    14902#endif
    14903 lpirows[r]->basisstatus = (unsigned int) rstat[r]; /*lint !e732*/
    14904 lpirows[r]->validactivitylp = lpcount;
    14905 if( stillprimalfeasible )
    14906 {
    14907 stillprimalfeasible =
    14908 (SCIPsetIsInfinity(set, -lpirows[r]->lhs) || SCIPlpIsFeasGE(set, lp, lpirows[r]->activity, lpirows[r]->lhs))
    14909 && (SCIPsetIsInfinity(set, lpirows[r]->rhs) || SCIPlpIsFeasLE(set, lp, lpirows[r]->activity, lpirows[r]->rhs));
    14910 }
    14911 if( lp->lastlpalgo == SCIP_LPALGO_BARRIER )
    14912 {
    14913 double compslack;
    14914
    14915 /* complementary slackness in barrier solutions is measured as product of primal slack and dual multiplier;
    14916 * we use a slack of at most 1, because otherwise we multiply by something like SCIPinfinity() for unbounded
    14917 * variables, which would magnify even the tiniest violation in the dual multiplier
    14918 */
    14919 if( stilldualfeasible )
    14920 {
    14921 compslack = MIN((lpirows[r]->activity - lpirows[r]->lhs), 1.0) * lpirows[r]->dualsol;
    14922 stilldualfeasible = !SCIPsetIsDualfeasPositive(set, compslack);
    14923 }
    14924 if( stilldualfeasible )
    14925 {
    14926 compslack = MIN((lpirows[r]->rhs - lpirows[r]->activity), 1.0) * lpirows[r]->dualsol;
    14927 stilldualfeasible = !SCIPsetIsDualfeasNegative(set, compslack);
    14928 }
    14929
    14930 SCIPsetDebugMsg(set, " row <%s> [%.9g,%.9g]: activity=%.9f, dualsol=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
    14931 lpirows[r]->name, lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->activity, lpirows[r]->dualsol,
    14932 SCIPlpIsFeasGE(set, lp, lpirows[r]->activity, lpirows[r]->lhs),
    14933 SCIPlpIsFeasLE(set, lp, lpirows[r]->activity, lpirows[r]->rhs),
    14934 primalfeasible != NULL ? stillprimalfeasible : TRUE,
    14935 !SCIPsetIsDualfeasPositive(set, MIN((lpirows[r]->activity - lpirows[r]->lhs), 1.0) * lpirows[r]->dualsol),
    14936 !SCIPsetIsDualfeasNegative(set, MIN((lpirows[r]->rhs - lpirows[r]->activity), 1.0) * lpirows[r]->dualsol),
    14937 dualfeasible != NULL ? stilldualfeasible : TRUE);
    14938 }
    14939 else
    14940 {
    14941 /* complementary slackness means that if the activity of a row is not at its left-hand or right-hand side,
    14942 * its dual multiplier must be non-positive or non-negative, respectively; in particular, if the activity is
    14943 * strictly within left-hand and right-hand side, its dual multiplier must be zero
    14944 */
    14945 if( stilldualfeasible &&
    14946 (SCIPsetIsInfinity(set, -lpirows[r]->lhs) || SCIPlpIsFeasGT(set, lp, lpirows[r]->activity, lpirows[r]->lhs)) )
    14947 stilldualfeasible = !SCIPsetIsDualfeasPositive(set, lpirows[r]->dualsol);
    14948 if( stilldualfeasible &&
    14949 (SCIPsetIsInfinity(set,lpirows[r]->rhs) || SCIPlpIsFeasLT(set, lp, lpirows[r]->activity, lpirows[r]->rhs)) )
    14950 stilldualfeasible = !SCIPsetIsDualfeasNegative(set, lpirows[r]->dualsol);
    14951
    14952 SCIPsetDebugMsg(set, " row <%s> [%.9g,%.9g] + %.9g: activity=%.9f, dualsol=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
    14953 lpirows[r]->name, lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->constant, lpirows[r]->activity, lpirows[r]->dualsol,
    14954 SCIPlpIsFeasGE(set, lp, lpirows[r]->activity, lpirows[r]->lhs),
    14955 SCIPlpIsFeasLE(set, lp, lpirows[r]->activity, lpirows[r]->rhs),
    14956 primalfeasible != NULL ? stillprimalfeasible : TRUE,
    14957 !SCIPlpIsFeasGT(set, lp, lpirows[r]->activity, lpirows[r]->lhs) || !SCIPsetIsDualfeasPositive(set, lpirows[r]->dualsol),
    14958 !SCIPlpIsFeasLT(set, lp, lpirows[r]->activity, lpirows[r]->rhs) || !SCIPsetIsDualfeasNegative(set, lpirows[r]->dualsol),
    14959 dualfeasible != NULL ? stilldualfeasible : TRUE);
    14960 }
    14961
    14962 /* we intentionally use an exact positive/negative check because ignoring small dual multipliers may lead to a
    14963 * wrong bound value; if the corresponding side is +/-infinity, we use a zero dual multiplier (if
    14964 * stilldualfeasible is TRUE, we are in the case that the dual multiplier is tiny with wrong sign)
    14965 */
    14966 if( stilldualfeasible )
    14967 {
    14968 if( lpirows[r]->dualsol > 0.0 && !SCIPsetIsInfinity(set, -lpirows[r]->lhs) )
    14969 dualbound += (lpirows[r]->dualsol * (lpirows[r]->lhs - lpirows[r]->constant));
    14970 else if( lpirows[r]->dualsol < 0.0 && !SCIPsetIsInfinity(set, lpirows[r]->rhs) )
    14971 dualbound += (lpirows[r]->dualsol * (lpirows[r]->rhs - lpirows[r]->constant));
    14972 }
    14973 }
    14974
    14975 /* if the objective value returned by the LP solver is smaller than the internally computed primal bound, then we
    14976 * declare the solution primal infeasible; we assume primalbound and lp->lpobjval to be equal if they are both +/-
    14977 * infinity
    14978 */
    14979 /**@todo alternatively, if otherwise the LP solution is feasible, we could simply update the objective value */
    14980 if( stillprimalfeasible && !(SCIPsetIsInfinity(set, primalbound) && SCIPsetIsInfinity(set, lp->lpobjval))
    14981 && !(SCIPsetIsInfinity(set, -primalbound) && SCIPsetIsInfinity(set, -lp->lpobjval)) )
    14982 {
    14983 stillprimalfeasible = SCIPsetIsFeasLE(set, primalbound, lp->lpobjval);
    14984 SCIPsetDebugMsg(set, " primalbound=%.9f, lpbound=%.9g, pfeas=%u(%u)\n", primalbound, lp->lpobjval,
    14985 SCIPsetIsFeasLE(set, primalbound, lp->lpobjval), primalfeasible != NULL ? stillprimalfeasible : TRUE);
    14986 }
    14987
    14988 /* if the objective value returned by the LP solver is smaller than the internally computed dual bound, we declare
    14989 * the solution dual infeasible; we assume dualbound and lp->lpobjval to be equal if they are both +/- infinity
    14990 */
    14991 /**@todo alternatively, if otherwise the LP solution is feasible, we could simply update the objective value */
    14992 if( stilldualfeasible && !(SCIPsetIsInfinity(set, dualbound) && SCIPsetIsInfinity(set, lp->lpobjval))
    14993 && !(SCIPsetIsInfinity(set, -dualbound) && SCIPsetIsInfinity(set, -lp->lpobjval)) )
    14994 {
    14995 stilldualfeasible = SCIPsetIsFeasGE(set, dualbound, lp->lpobjval);
    14996 SCIPsetDebugMsg(set, " dualbound=%.9f, lpbound=%.9g, dfeas=%u(%u)\n", dualbound, lp->lpobjval,
    14997 SCIPsetIsFeasGE(set, dualbound, lp->lpobjval), dualfeasible != NULL ? stilldualfeasible : TRUE);
    14998 }
    14999
    15000 if( primalfeasible != NULL )
    15001 *primalfeasible = stillprimalfeasible;
    15002 if( dualfeasible != NULL )
    15003 *dualfeasible = stilldualfeasible;
    15004
    15005 /* free temporary memory */
    15006 SCIPsetFreeBufferArray(set, &rstat);
    15007 SCIPsetFreeBufferArray(set, &cstat);
    15008 SCIPsetFreeBufferArray(set, &redcost);
    15009#ifdef SCIP_USE_LPSOLVER_ACTIVITY
    15010 SCIPsetFreeBufferArray(set, &activity);
    15011#endif
    15012 SCIPsetFreeBufferArray(set, &dualsol);
    15013 SCIPsetFreeBufferArray(set, &primsol);
    15014
    15015 return SCIP_OKAY;
    15016}
    15017
    15018/** stores LP solution with infinite objective value in the columns and rows */
    15020 SCIP_LP* lp, /**< current LP data */
    15021 SCIP_SET* set, /**< global SCIP settings */
    15022 SCIP_STAT* stat, /**< problem statistics */
    15023 SCIP_Bool* primalfeasible, /**< pointer to store whether the solution is primal feasible, or NULL */
    15024 SCIP_Bool* rayfeasible /**< pointer to store whether the primal ray is a feasible unboundedness proof, or NULL */
    15025 )
    15026{
    15027 SCIP_COL** lpicols;
    15028 SCIP_ROW** lpirows;
    15029 SCIP_Real* primsol;
    15030 SCIP_Real* activity;
    15031 SCIP_Real* ray;
    15032 SCIP_Real rayobjval;
    15033 SCIP_Real rayscale;
    15034 SCIP_Longint lpcount;
    15035 SCIP_COL* col;
    15036 int nlpicols;
    15037 int nlpirows;
    15038 int c;
    15039 int r;
    15040
    15041 assert(lp != NULL);
    15042 assert(lp->flushed);
    15043 assert(lp->solved);
    15045 assert(SCIPsetIsInfinity(set, -lp->lpobjval));
    15046 assert(set != NULL);
    15047 assert(stat != NULL);
    15048 assert(lp->validsollp <= stat->lpcount);
    15049
    15050 if( primalfeasible != NULL )
    15051 *primalfeasible = TRUE;
    15052 if( rayfeasible != NULL )
    15053 *rayfeasible = TRUE;
    15054
    15055 /* check if the values are already calculated */
    15056 if( lp->validsollp == stat->lpcount )
    15057 return SCIP_OKAY;
    15058 lp->validsollp = stat->lpcount;
    15059
    15060 /* check if the LP solver is able to provide a primal unbounded ray */
    15061 if( !SCIPlpiHasPrimalRay(lp->lpi) )
    15062 {
    15063 SCIPerrorMessage("LP solver has no primal ray to prove unboundedness.\n");
    15064 return SCIP_LPERROR;
    15065 }
    15066
    15067 SCIPsetDebugMsg(set, "getting new unbounded LP solution %" SCIP_LONGINT_FORMAT "\n", stat->lpcount);
    15068
    15069 /* get temporary memory */
    15070 SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
    15071 SCIP_CALL( SCIPsetAllocBufferArray(set, &activity, lp->nlpirows) );
    15073
    15074 /* get primal unbounded ray */
    15075 SCIP_CALL( SCIPlpiGetPrimalRay(lp->lpi, ray) );
    15076
    15077 lpicols = lp->lpicols;
    15078 lpirows = lp->lpirows;
    15079 nlpicols = lp->nlpicols;
    15080 nlpirows = lp->nlpirows;
    15081 lpcount = stat->lpcount;
    15082
    15083 /* calculate the objective value decrease of the ray and heuristically try to construct primal solution */
    15084 rayobjval = 0.0;
    15085 for( c = 0; c < nlpicols; ++c )
    15086 {
    15087 assert(lpicols[c] != NULL);
    15088 assert(lpicols[c]->var != NULL);
    15089
    15090 col = lpicols[c];
    15091
    15092 /* there should only be a nonzero value in the ray if there is no finite bound in this direction */
    15093 if( rayfeasible != NULL )
    15094 {
    15095 *rayfeasible = *rayfeasible
    15096 && (!SCIPsetIsNegative(set, ray[c]) || SCIPsetIsInfinity(set, -col->lb))
    15097 && (!SCIPsetIsPositive(set, ray[c]) || SCIPsetIsInfinity(set, col->ub));
    15098 }
    15099
    15100 if( ! SCIPsetIsZero(set, ray[c]) )
    15101 rayobjval += ray[c] * col->obj;
    15102
    15103 /* Many LP solvers cannot directly provide a feasible solution if they detected unboundedness. We therefore first
    15104 * heuristically try to construct a primal solution.
    15105 */
    15106 primsol[c] = 0.0;
    15107 if( SCIPsetIsFeasZero(set, ray[c]) )
    15108 {
    15109 /* if the ray component is 0, we try to satisfy as many rows as possible */
    15110 if( SCIPvarGetNLocksDown(col->var) == 0 && ! SCIPsetIsInfinity(set, -col->lb) )
    15111 primsol[c] = col->lb;
    15112 else if( SCIPvarGetNLocksUp(col->var) == 0 && ! SCIPsetIsInfinity(set, col->ub) )
    15113 primsol[c] = col->ub;
    15114 }
    15115
    15116 /* make sure we respect the bounds */
    15117 primsol[c] = MAX(primsol[c], col->lb);
    15118 primsol[c] = MIN(primsol[c], col->ub);
    15119
    15120 assert( SCIPlpIsFeasGE(set, lp, primsol[c], col->lb) && SCIPlpIsFeasLE(set, lp, primsol[c], col->ub) );
    15121 }
    15122
    15123 /* check feasibility of heuristic primal solution */
    15124 for( r = 0; r < nlpirows; ++r )
    15125 {
    15126 SCIP_Real act;
    15127 SCIP_ROW* row;
    15128
    15129 row = lpirows[r];
    15130 assert( row != NULL );
    15131 act = row->constant;
    15132
    15133 for( c = 0; c < row->nlpcols; ++c )
    15134 {
    15135 col = row->cols[c];
    15136
    15137 assert( col != NULL );
    15138 assert( col->lppos >= 0 );
    15139 assert( row->linkpos[c] >= 0 );
    15140 assert( primsol[col->lppos] != SCIP_INVALID ); /*lint !e777*/
    15141
    15142 act += row->vals[c] * primsol[col->lppos];
    15143 }
    15144
    15145 if( row->nunlinked > 0 )
    15146 {
    15147 for( c = row->nlpcols; c < row->len; ++c )
    15148 {
    15149 col = row->cols[c];
    15150 assert( col != NULL );
    15151
    15152 if( col->lppos >= 0 )
    15153 act += row->vals[c] * primsol[col->lppos];
    15154 }
    15155 }
    15156
    15157 /* check feasibility */
    15158 if( (! SCIPsetIsInfinity(set, -row->lhs) && SCIPlpIsFeasLT(set, lp, act, row->lhs) ) ||
    15159 (! SCIPsetIsInfinity(set, row->rhs) && SCIPlpIsFeasGT(set, lp, act, row->rhs) ) )
    15160 break;
    15161 }
    15162
    15163 /* if heuristic primal solution is not feasible, try to obtain solution from LPI */
    15164 if( r < nlpirows )
    15165 {
    15166 /* get primal feasible point */
    15167 SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, NULL, NULL) );
    15168
    15169 /* check bounds of primal solution */
    15170 if( primalfeasible != NULL )
    15171 {
    15172 assert( *primalfeasible );
    15173 for( c = 0; c < nlpicols; ++c )
    15174 {
    15175 assert( lpicols[c] != NULL );
    15176 assert( lpicols[c]->var != NULL );
    15177
    15178 /* check whether primal solution satisfies the bounds; note that we also ensure that the primal
    15179 * solution is within SCIP's infinity bounds; otherwise the rayscale below is not well-defined */
    15180 if( SCIPsetIsInfinity(set, REALABS(primsol[c])) || SCIPlpIsFeasLT(set, lp, primsol[c], lpicols[c]->lb) ||
    15181 SCIPlpIsFeasGT(set, lp, primsol[c], lpicols[c]->ub) )
    15182 {
    15183 *primalfeasible = FALSE;
    15184 break;
    15185 }
    15186 }
    15187 }
    15188 }
    15189
    15190 /* compute activity and check feasibility of primal solution and ray */
    15191 for( r = 0; r < nlpirows; ++r )
    15192 {
    15193 SCIP_Real primact;
    15194 SCIP_Real rayact = 0.0;
    15195 SCIP_ROW* row;
    15196
    15197 row = lpirows[r];
    15198 assert( row != NULL );
    15199
    15200 primact = row->constant;
    15201
    15202 for( c = 0; c < row->nlpcols; ++c )
    15203 {
    15204 col = row->cols[c];
    15205
    15206 assert( col != NULL );
    15207 assert( col->lppos >= 0 );
    15208 assert( row->linkpos[c] >= 0 );
    15209 assert( primsol[col->lppos] != SCIP_INVALID ); /*lint !e777*/
    15210
    15211 primact += row->vals[c] * primsol[col->lppos];
    15212 rayact += row->vals[c] * ray[col->lppos];
    15213 }
    15214
    15215 if( row->nunlinked > 0 )
    15216 {
    15217 for( c = row->nlpcols; c < row->len; ++c )
    15218 {
    15219 col = row->cols[c];
    15220 assert( col != NULL );
    15221
    15222 if( col->lppos >= 0 )
    15223 {
    15224 primact += row->vals[c] * primsol[col->lppos];
    15225 rayact += row->vals[c] * ray[col->lppos];
    15226 }
    15227 }
    15228 }
    15229
    15230 /* check feasibility of primal solution */
    15231 if( primalfeasible != NULL && *primalfeasible )
    15232 {
    15233 if(( ! SCIPsetIsInfinity(set, -row->lhs) && SCIPlpIsFeasLT(set, lp, primact, row->lhs) ) ||
    15234 ( ! SCIPsetIsInfinity(set, row->rhs) && SCIPlpIsFeasGT(set, lp, primact, row->rhs) ) )
    15235 *primalfeasible = FALSE;
    15236 }
    15237
    15238 /* check feasibility of ray */
    15239 if( rayfeasible != NULL && *rayfeasible )
    15240 {
    15241 if(( ! SCIPsetIsInfinity(set, -row->lhs) && SCIPlpIsFeasLT(set, lp, rayact, 0.0) ) ||
    15242 ( ! SCIPsetIsInfinity(set, row->rhs) && SCIPlpIsFeasGT(set, lp, rayact, 0.0) ) )
    15243 *rayfeasible = FALSE;
    15244 }
    15245
    15246 /* store activity of primal solution */
    15247 activity[r] = primact;
    15248 }
    15249
    15250 if( primalfeasible != NULL && !(*primalfeasible) )
    15251 {
    15252 /* if the finite point is already infeasible, we do not have to add the ray */
    15253 rayscale = 0.0;
    15254 }
    15255 else if( rayfeasible != NULL && !(*rayfeasible) )
    15256 {
    15257 /* if the ray is already infeasible (due to numerics), we do not want to add the ray */
    15258 rayscale = 0.0;
    15259 }
    15260 else if( !SCIPsetIsNegative(set, rayobjval) )
    15261 {
    15262 /* due to numerical problems, the objective of the ray might be nonnegative
    15263 *
    15264 * @todo How to check for negative objective value here?
    15265 */
    15266 if( rayfeasible != NULL )
    15267 *rayfeasible = FALSE;
    15268
    15269 rayscale = 0.0;
    15270 }
    15271 else
    15272 {
    15273 assert(rayobjval != 0.0);
    15274
    15275 /* scale the ray, such that the resulting point has infinite objective value */
    15276 rayscale = -2.0 * SCIPsetInfinity(set) / rayobjval;
    15277 assert(SCIPsetIsFeasPositive(set, rayscale));
    15278
    15279 /* ensure that unbounded point does not violate the bounds of the variables */
    15280 for( c = 0; c < nlpicols; ++c )
    15281 {
    15282 if( SCIPsetIsPositive(set, ray[c]) )
    15283 {
    15284 if( !SCIPsetIsInfinity(set, primsol[c]) )
    15285 rayscale = MIN(rayscale, (lpicols[c]->ub - primsol[c]) / ray[c]);
    15286 /* if primsol is infinity, as well as the bound, don't scale the ray to 0 */
    15287 else
    15288 {
    15289 assert(SCIPsetIsInfinity(set, lpicols[c]->ub));
    15290 rayscale = MIN(rayscale, 1.0 / ray[c]);
    15291 }
    15292 }
    15293 else if( SCIPsetIsNegative(set, ray[c]) )
    15294 {
    15295 if( !SCIPsetIsInfinity(set, -primsol[c]) )
    15296 rayscale = MIN(rayscale, (lpicols[c]->lb - primsol[c]) / ray[c]);
    15297 /* if primsol is infinity, as well as the bound, don't scale the ray to 0 */
    15298 else
    15299 {
    15300 assert(SCIPsetIsInfinity(set, -lpicols[c]->lb));
    15301 rayscale = MIN(rayscale, -1.0 / ray[c]);
    15302 }
    15303 }
    15304
    15305 assert(SCIPsetIsFeasPositive(set, rayscale));
    15306 }
    15307 }
    15308
    15309 SCIPsetDebugMsg(set, "unbounded LP solution: rayobjval=%f, rayscale=%f\n", rayobjval, rayscale);
    15310
    15311 /* calculate the unbounded point: x' = x + rayscale * ray */
    15312 /* Note: We do not check the feasibility of the unbounded solution, because it will likely be infeasible due to the
    15313 * typically large values in scaling. */
    15314 for( c = 0; c < nlpicols; ++c )
    15315 {
    15316 if( SCIPsetIsZero(set, ray[c]) )
    15317 lpicols[c]->primsol = primsol[c];
    15318 else
    15319 {
    15320 SCIP_Real primsolval;
    15321 primsolval = primsol[c] + rayscale * ray[c];
    15322 lpicols[c]->primsol = MAX(-SCIPsetInfinity(set), MIN(SCIPsetInfinity(set), primsolval)); /*lint !e666*/
    15323 }
    15324 lpicols[c]->redcost = SCIP_INVALID;
    15325 lpicols[c]->validredcostlp = -1;
    15326 }
    15327
    15328 /* transfer solution */
    15329 for( r = 0; r < nlpirows; ++r )
    15330 {
    15331 lpirows[r]->dualsol = SCIP_INVALID;
    15332 lpirows[r]->activity = activity[r] + lpirows[r]->constant;
    15333 lpirows[r]->validactivitylp = lpcount;
    15334 }
    15335
    15336 /* free temporary memory */
    15338 SCIPsetFreeBufferArray(set, &activity);
    15339 SCIPsetFreeBufferArray(set, &primsol);
    15340
    15341 return SCIP_OKAY;
    15342}
    15343
    15344/** returns primal ray proving the unboundedness of the current LP */
    15346 SCIP_LP* lp, /**< current LP data */
    15347 SCIP_SET* set, /**< global SCIP settings */
    15348 SCIP_Real* ray /**< array for storing primal ray values, they are stored w.r.t. the problem index of the variables,
    15349 * so the size of this array should be at least number of active variables
    15350 * (all entries have to be initialized to 0 before) */
    15351 )
    15352{
    15353 SCIP_COL** lpicols;
    15354 SCIP_Real* lpiray;
    15355 SCIP_VAR* var;
    15356 int nlpicols;
    15357 int c;
    15358
    15359 assert(lp != NULL);
    15360 assert(set != NULL);
    15361 assert(ray != NULL);
    15362 assert(lp->flushed);
    15363 assert(lp->solved);
    15365 assert(SCIPsetIsInfinity(set, -lp->lpobjval));
    15366
    15367 /* check if the LP solver is able to provide a primal unbounded ray */
    15368 if( !SCIPlpiHasPrimalRay(lp->lpi) )
    15369 {
    15370 SCIPerrorMessage("LP solver has no primal ray for unbounded LP\n");
    15371 return SCIP_LPERROR;
    15372 }
    15373
    15374 /* get temporary memory */
    15376
    15377 SCIPsetDebugMsg(set, "getting primal ray values\n");
    15378
    15379 /* get primal unbounded ray */
    15380 SCIP_CALL( SCIPlpiGetPrimalRay(lp->lpi, lpiray) );
    15381
    15382 lpicols = lp->lpicols;
    15383 nlpicols = lp->nlpicols;
    15384
    15385 /* store the ray values of active problem variables */
    15386 for( c = 0; c < nlpicols; c++ )
    15387 {
    15388 assert(lpicols[c] != NULL);
    15389
    15390 var = lpicols[c]->var;
    15391 assert(var != NULL);
    15392 assert(SCIPvarGetProbindex(var) != -1);
    15393 ray[SCIPvarGetProbindex(var)] = lpiray[c];
    15394 }
    15395
    15396 SCIPsetFreeBufferArray(set, &lpiray);
    15397
    15398 return SCIP_OKAY;
    15399}
    15400
    15401/** stores the dual Farkas multipliers for infeasibility proof in rows. besides, the proof is checked for validity if
    15402 * lp/checkfarkas = TRUE.
    15403 *
    15404 * @note the check will not be performed if @p valid is NULL.
    15405 */
    15407 SCIP_LP* lp, /**< current LP data */
    15408 SCIP_SET* set, /**< global SCIP settings */
    15409 SCIP_STAT* stat, /**< problem statistics */
    15410 SCIP_Bool forcedlpsolve, /**< would SCIP abort if the LP is not solved? */
    15411 SCIP_Bool* valid /**< pointer to store whether the Farkas proof is valid or NULL */
    15412 )
    15413{
    15414 SCIP_COL** lpicols;
    15415 SCIP_ROW** lpirows;
    15416 SCIP_Real* dualfarkas;
    15417 SCIP_Real* farkascoefs;
    15418 SCIP_Real farkaslhs;
    15419 SCIP_Real maxactivity;
    15420 SCIP_Bool checkfarkas;
    15421 int nlpicols;
    15422 int nlpirows;
    15423 int c;
    15424 int r;
    15425
    15426 assert(lp != NULL);
    15427 assert(lp->flushed);
    15428 assert(lp->solved);
    15429 assert(lp->lpsolstat == SCIP_LPSOLSTAT_INFEASIBLE);
    15430 assert(set != NULL);
    15431 assert(stat != NULL);
    15432 assert(lp->validfarkaslp <= stat->lpcount);
    15433
    15434 if( valid != NULL )
    15435 *valid = TRUE;
    15436
    15437 /* check if the values are already calculated */
    15438 if( lp->validfarkaslp == stat->lpcount )
    15439 return SCIP_OKAY;
    15440 lp->validfarkaslp = stat->lpcount;
    15441
    15442 farkascoefs = NULL;
    15443 maxactivity = 0.0;
    15444 farkaslhs = 0.0;
    15445 checkfarkas = set->lp_checkfarkas && valid != NULL;
    15446
    15447 /* get temporary memory */
    15448 SCIP_CALL( SCIPsetAllocBufferArray(set, &dualfarkas, lp->nlpirows) );
    15449
    15450 if( checkfarkas )
    15451 {
    15452 SCIP_CALL( SCIPsetAllocBufferArray(set, &farkascoefs, lp->nlpicols) );
    15453 BMSclearMemoryArray(farkascoefs, lp->nlpicols);
    15454 }
    15455
    15456 /* get dual Farkas infeasibility proof */
    15457 SCIP_CALL( SCIPlpiGetDualfarkas(lp->lpi, dualfarkas) );
    15458
    15459 lpicols = lp->lpicols;
    15460 lpirows = lp->lpirows;
    15461 nlpicols = lp->nlpicols;
    15462 nlpirows = lp->nlpirows;
    15463
    15464 /* store infeasibility proof in rows */
    15465 SCIPsetDebugMsg(set, "LP is infeasible:\n");
    15466 for( r = 0; r < nlpirows; ++r )
    15467 {
    15468 SCIPsetDebugMsg(set, " row <%s>: dualfarkas=%f\n", lpirows[r]->name, dualfarkas[r]);
    15469 lpirows[r]->dualfarkas = dualfarkas[r];
    15470 lpirows[r]->dualsol = SCIP_INVALID;
    15471 lpirows[r]->activity = 0.0;
    15472 lpirows[r]->validactivitylp = -1L;
    15473 lpirows[r]->basisstatus = (unsigned int) SCIP_BASESTAT_BASIC;
    15474
    15475 if( checkfarkas && dualfarkas[r] != 0.0 ) /*lint !e777*/
    15476 {
    15477 assert(valid != NULL);
    15478 assert(farkascoefs != NULL);
    15479
    15480 /* the infeasibility proof would be invalid if
    15481 * (i) dualfarkas[r] > 0 and lhs = -inf
    15482 * (ii) dualfarkas[r] < 0 and rhs = inf
    15483 * however, due to numerics we accept slightly negative / positive values
    15484 */
    15485 if( (SCIPsetIsDualfeasGT(set, dualfarkas[r], 0.0) && SCIPsetIsInfinity(set, -lpirows[r]->lhs))
    15486 || (SCIPsetIsDualfeasLT(set, dualfarkas[r], 0.0) && SCIPsetIsInfinity(set, lpirows[r]->rhs)) )
    15487 {
    15488 SCIPsetDebugMsg(set, "farkas proof is invalid: row <%s>[lhs=%g,rhs=%g,c=%g] has multiplier %g\n",
    15489 SCIProwGetName(lpirows[r]), lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->constant, dualfarkas[r]);
    15490
    15491 *valid = FALSE;
    15492 goto TERMINATE;
    15493 }
    15494
    15495 /* dual multipliers, for which the corresponding row side in infinite, are treated as zero if they are zero
    15496 * within tolerances (see above) but slighty positive / negative
    15497 */
    15498 if( (dualfarkas[r] > 0.0 && SCIPsetIsInfinity(set, -lpirows[r]->lhs))
    15499 || (dualfarkas[r] < 0.0 && SCIPsetIsInfinity(set, lpirows[r]->rhs)) )
    15500 continue;
    15501
    15502 /* iterate over all columns and scale with dual solution */
    15503 for( c = 0; c < lpirows[r]->len; c++ )
    15504 {
    15505 int pos = SCIPcolGetLPPos(lpirows[r]->cols[c]);
    15506
    15507 if( pos == -1 )
    15508 continue;
    15509
    15510 assert(pos >= 0 && pos < nlpicols);
    15511
    15512 farkascoefs[pos] += dualfarkas[r] * lpirows[r]->vals[c];
    15513 }
    15514
    15515 /* the row contributes with its left-hand side to the proof */
    15516 if( dualfarkas[r] > 0.0 )
    15517 {
    15518 assert(!SCIPsetIsInfinity(set, -lpirows[r]->lhs));
    15519
    15520 farkaslhs += dualfarkas[r] * lpirows[r]->lhs;
    15521 }
    15522 /* the row contributes with its right-hand side to the proof */
    15523 else if( dualfarkas[r] < 0.0 )
    15524 {
    15525 assert(!SCIPsetIsInfinity(set, lpirows[r]->rhs));
    15526
    15527 farkaslhs += dualfarkas[r] * lpirows[r]->rhs;
    15528 }
    15529
    15530 maxactivity += dualfarkas[r] * lpirows[r]->constant;
    15531 }
    15532 }
    15533
    15534 /* set columns as invalid */
    15535 for( c = 0; c < nlpicols; ++c )
    15536 {
    15537 lpicols[c]->primsol = SCIP_INVALID;
    15538 lpicols[c]->redcost = SCIP_INVALID;
    15539 lpicols[c]->validredcostlp = -1L;
    15540 lpicols[c]->validfarkaslp = -1L;
    15541
    15542 if( checkfarkas )
    15543 {
    15544 assert(valid != NULL);
    15545 assert(farkascoefs != NULL);
    15546 assert(SCIPcolGetLPPos(lpicols[c]) == c);
    15547
    15548 /* skip coefficients that are too close to zero */
    15549 if( SCIPsetIsDualfeasZero(set, farkascoefs[c]) )
    15550 continue;
    15551
    15552 /* calculate the maximal activity */
    15553 if( farkascoefs[c] > 0.0 )
    15554 {
    15555 maxactivity += farkascoefs[c] * lpicols[c]->ub;
    15556
    15557 if( SCIPsetIsInfinity(set, lpicols[c]->ub) )
    15558 {
    15559 SCIPsetDebugMsg(set, "farkas proof is invalid: col <%s>[lb=%g,ub=%g] has coefficient %g\n",
    15560 SCIPvarGetName(SCIPcolGetVar(lpicols[c])), lpicols[c]->lb, lpicols[c]->ub, farkascoefs[c]);
    15561
    15562 *valid = FALSE;
    15563 goto TERMINATE;
    15564 }
    15565 }
    15566 else
    15567 {
    15568 maxactivity += farkascoefs[c] * lpicols[c]->lb;
    15569
    15570 if( SCIPsetIsInfinity(set, -lpicols[c]->lb) )
    15571 {
    15572 SCIPsetDebugMsg(set, "farkas proof is invalid: col <%s>[lb=%g,ub=%g] has coefficient %g\n",
    15573 SCIPvarGetName(SCIPcolGetVar(lpicols[c])), lpicols[c]->lb, lpicols[c]->ub, farkascoefs[c]);
    15574
    15575 *valid = FALSE;
    15576 goto TERMINATE;
    15577 }
    15578 }
    15579 }
    15580 }
    15581
    15582 /* check whether the farkasproof is valid for relative epsilon tolerance to allow feasibility tightening */
    15583 if( checkfarkas
    15584 && ( SCIPsetIsInfinity(set, maxactivity) || SCIPsetIsInfinity(set, -farkaslhs) || SCIPsetIsRelGE(set, maxactivity, farkaslhs) ) )
    15585 {
    15586 assert(valid != NULL);
    15587
    15588 SCIPsetDebugMsg(set, "farkas proof is invalid: maxactivity=%.12f, lhs=%.12f\n", maxactivity, farkaslhs);
    15589
    15590 if( forcedlpsolve && SCIPsetIsLT(set, maxactivity, farkaslhs) )
    15591 SCIPmessagePrintWarning(set->scip->messagehdlr, "Unreliable farkas proof forced valid, result might not be optimal.\n");
    15592 else
    15593 *valid = FALSE;
    15594 }
    15595
    15596 TERMINATE:
    15597 /* free temporary memory */
    15598 if( checkfarkas )
    15599 SCIPsetFreeBufferArray(set, &farkascoefs);
    15600
    15601 SCIPsetFreeBufferArray(set, &dualfarkas);
    15602
    15603 return SCIP_OKAY;
    15604}
    15605
    15606/** get number of iterations used in last LP solve */
    15608 SCIP_LP* lp, /**< current LP data */
    15609 int* iterations /**< pointer to store the iteration count */
    15610 )
    15611{
    15612 assert(lp != NULL);
    15613
    15614 SCIP_CALL( SCIPlpiGetIterations(lp->lpi, iterations) );
    15615
    15616 return SCIP_OKAY;
    15617}
    15618
    15619/** increases age of columns with solution value 0.0 and basic rows with activity not at its bounds,
    15620 * resets age of non-zero columns and sharp rows
    15621 */
    15623 SCIP_LP* lp, /**< current LP data */
    15624 SCIP_STAT* stat /**< problem statistics */
    15625 )
    15626{
    15627 SCIP_COL** lpicols;
    15628 SCIP_ROW** lpirows;
    15629 int nlpicols;
    15630 int nlpirows;
    15631 int c;
    15632 int r;
    15633
    15634 assert(lp != NULL);
    15635 assert(lp->flushed);
    15636 assert(lp->solved);
    15637 assert(lp->nlpicols == lp->ncols);
    15638 assert(lp->nlpirows == lp->nrows);
    15639 assert(stat != NULL);
    15640 assert(lp->validsollp == stat->lpcount);
    15641
    15642 SCIPdebugMessage("updating LP ages\n");
    15643
    15644 lpicols = lp->lpicols;
    15645 lpirows = lp->lpirows;
    15646 nlpicols = lp->nlpicols;
    15647 nlpirows = lp->nlpirows;
    15648
    15649 for( c = 0; c < nlpicols; ++c )
    15650 {
    15651 assert(lpicols[c] == lp->cols[c]);
    15652 if( lpicols[c]->primsol == 0.0 ) /* non-basic columns to remove are exactly at 0.0 */
    15653 lpicols[c]->age++;
    15654 else
    15655 lpicols[c]->age = 0;
    15656 /*SCIPstatDebugMsg(stat, " -> col <%s>: primsol=%f, age=%d\n",
    15657 SCIPvarGetName(lpicols[c]->var), lpicols[c]->primsol, lpicols[c]->age);*/
    15658 }
    15659
    15660 for( r = 0; r < nlpirows; ++r )
    15661 {
    15662 lpirows[r]->nlpsaftercreation++;
    15663 assert(lpirows[r] == lp->rows[r]);
    15664
    15665 if( lpirows[r]->dualsol == 0.0 ) /* basic rows to remove are exactly at 0.0 */
    15666 {
    15667 lpirows[r]->age++;
    15668 }
    15669 else
    15670 {
    15671 lpirows[r]->activeinlpcounter++;
    15672 lpirows[r]->age = 0;
    15673 }
    15674 /*debugMsg(scip, " -> row <%s>: activity=%f, age=%d\n", lpirows[r]->name, lpirows[r]->activity, lpirows[r]->age);*/
    15675 }
    15676
    15677 return SCIP_OKAY;
    15678}
    15679
    15680/* deletes the marked columns from the LP and the LP interface */
    15681static
    15683 SCIP_LP* lp, /**< current LP data */
    15684 SCIP_SET* set, /**< global SCIP settings */
    15685 int* coldstat /**< deletion status of columns: 1 if column should be deleted, 0 if not */
    15686 )
    15687{
    15688 SCIP_COL* col;
    15689 int ncols;
    15690 int c;
    15691
    15692 assert(lp != NULL);
    15693 assert(lp->flushed);
    15694 assert(lp->ncols == lp->nlpicols);
    15695 assert(!lp->diving);
    15696 assert(coldstat != NULL);
    15697 assert(lp->nlazycols <= lp->ncols);
    15698
    15699 ncols = lp->ncols;
    15700
    15701 /* delete columns in LP solver */
    15702 SCIP_CALL( SCIPlpiDelColset(lp->lpi, coldstat) );
    15703
    15704 /* update LP data respectively */
    15705 for( c = 0; c < ncols; ++c )
    15706 {
    15707 col = lp->cols[c];
    15708 assert(col != NULL);
    15709 assert(col == lp->lpicols[c]);
    15710 assert(coldstat[c] <= c);
    15711 col->lppos = coldstat[c];
    15712 if( coldstat[c] == -1 )
    15713 {
    15714 assert(col->removable);
    15715
    15716 /* mark column to be deleted from the LPI, update column arrays of all linked rows, and update the objective
    15717 * function vector norms
    15718 */
    15719 markColDeleted(col);
    15720 colUpdateDelLP(col, set);
    15721 lpUpdateObjNorms(lp, set, col->unchangedobj, 0.0);
    15722 col->lpdepth = -1;
    15723
    15724 lp->cols[c] = NULL;
    15725 lp->lpicols[c] = NULL;
    15726 lp->ncols--;
    15727 lp->nremovablecols--;
    15728 lp->nlpicols--;
    15729 }
    15730 else if( coldstat[c] < c )
    15731 {
    15732 assert(lp->cols[coldstat[c]] == NULL);
    15733 assert(lp->lpicols[coldstat[c]] == NULL);
    15734 lp->cols[coldstat[c]] = col;
    15735 lp->lpicols[coldstat[c]] = col;
    15736 lp->cols[coldstat[c]]->lppos = coldstat[c];
    15737 lp->cols[coldstat[c]]->lpipos = coldstat[c];
    15738 lp->cols[c] = NULL;
    15739 lp->lpicols[c] = NULL;
    15740 }
    15741 }
    15742
    15743 /* remove columns which are deleted from the lazy column array */
    15744 c = 0;
    15745 while( c < lp->nlazycols )
    15746 {
    15747 if( lp->lazycols[c]->lpipos < 0 )
    15748 {
    15749 lp->lazycols[c] = lp->lazycols[lp->nlazycols-1];
    15750 lp->nlazycols--;
    15751 }
    15752 else
    15753 c++;
    15754 }
    15755
    15756 /* mark LP to be unsolved */
    15757 if( lp->ncols < ncols )
    15758 {
    15759 assert(lp->ncols == lp->nlpicols);
    15760 assert(lp->nchgcols == 0);
    15761 assert(lp->flushed);
    15762
    15763 lp->lpifirstchgcol = lp->nlpicols;
    15764
    15765 /* mark the current solution invalid */
    15766 lp->solved = FALSE;
    15767 lp->primalfeasible = FALSE;
    15768 lp->primalchecked = FALSE;
    15769 lp->lpobjval = SCIP_INVALID;
    15771 }
    15772
    15774 checkLinks(lp);
    15775
    15776 return SCIP_OKAY;
    15777}
    15778
    15779/* deletes the marked rows from the LP and the LP interface */
    15780static
    15782 SCIP_LP* lp, /**< current LP data */
    15783 BMS_BLKMEM* blkmem, /**< block memory buffers */
    15784 SCIP_SET* set, /**< global SCIP settings */
    15785 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    15786 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    15787 int* rowdstat /**< deletion status of rows: 1 if row should be deleted, 0 if not */
    15788 )
    15789{
    15790 SCIP_ROW* row;
    15791 int nrows;
    15792 int r;
    15793
    15794 assert(lp != NULL);
    15795 assert(lp->flushed);
    15796 assert(lp->nrows == lp->nlpirows);
    15797 assert(!lp->diving);
    15798 assert(rowdstat != NULL);
    15799
    15800 nrows = lp->nrows;
    15801
    15802 /* delete rows in LP solver */
    15803 SCIP_CALL( SCIPlpiDelRowset(lp->lpi, rowdstat) );
    15804
    15805 /* update LP data respectively */
    15806 for( r = 0; r < nrows; ++r )
    15807 {
    15808 row = lp->rows[r];
    15809 assert(row == lp->lpirows[r]);
    15810 assert(rowdstat[r] <= r);
    15811 assert(row != NULL);
    15812 row->lppos = rowdstat[r];
    15813 if( rowdstat[r] == -1 )
    15814 {
    15815 if( row->removable )
    15816 lp->nremovablerows--;
    15817
    15818 /* mark row to be deleted from the LPI and update row arrays of all linked columns */
    15819 markRowDeleted(row);
    15820 rowUpdateDelLP(row);
    15821 row->lpdepth = -1;
    15822
    15823 /* check, if row deletion events are tracked
    15824 * if so, issue ROWDELETEDLP event
    15825 */
    15826 if( eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWDELETEDLP) != 0 ) /*lint !e587*/
    15827 {
    15828 SCIP_EVENT* event;
    15829
    15830 SCIP_CALL( SCIPeventCreateRowDeletedLP(&event, blkmem, row) );
    15831 SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
    15832 }
    15833
    15834 SCIP_CALL( SCIProwRelease(&lp->lpirows[r], blkmem, set, lp) );
    15835 SCIProwUnlock(lp->rows[r]);
    15836 SCIP_CALL( SCIProwRelease(&lp->rows[r], blkmem, set, lp) );
    15837 assert(lp->lpirows[r] == NULL);
    15838 assert(lp->rows[r] == NULL);
    15839 lp->nrows--;
    15840 lp->nlpirows--;
    15841 }
    15842 else if( rowdstat[r] < r )
    15843 {
    15844 assert(lp->rows[rowdstat[r]] == NULL);
    15845 assert(lp->lpirows[rowdstat[r]] == NULL);
    15846 lp->rows[rowdstat[r]] = row;
    15847 lp->lpirows[rowdstat[r]] = row;
    15848 lp->rows[rowdstat[r]]->lppos = rowdstat[r];
    15849 lp->rows[rowdstat[r]]->lpipos = rowdstat[r];
    15850 lp->rows[r] = NULL;
    15851 lp->lpirows[r] = NULL;
    15852 }
    15853 }
    15854
    15855 /* mark LP to be unsolved */
    15856 if( lp->nrows < nrows )
    15857 {
    15858 assert(lp->nrows == lp->nlpirows);
    15859 assert(lp->nchgrows == 0);
    15860 assert(lp->flushed);
    15861
    15862 lp->lpifirstchgrow = lp->nlpirows;
    15863
    15864 /* mark the current solution invalid */
    15865 lp->solved = FALSE;
    15866 lp->dualfeasible = FALSE;
    15867 lp->dualchecked = FALSE;
    15868 lp->lpobjval = SCIP_INVALID;
    15870 }
    15871
    15872 checkLinks(lp);
    15873
    15874 return SCIP_OKAY;
    15875}
    15876
    15877/** removes all non-basic columns, that are too old, beginning with the given firstcol */
    15878static
    15880 SCIP_LP* lp, /**< current LP data */
    15881 SCIP_SET* set, /**< global SCIP settings */
    15882 SCIP_STAT* stat, /**< problem statistics */
    15883 int firstcol /**< first column to check for clean up */
    15884 )
    15885{
    15886 SCIP_COL** cols;
    15887#ifndef NDEBUG
    15888 SCIP_COL** lpicols;
    15889#endif
    15890 int* coldstat;
    15891 int ncols;
    15892 int ndelcols;
    15893 int c;
    15894
    15895 assert(lp != NULL);
    15896 assert(lp->flushed);
    15897 assert(lp->ncols == lp->nlpicols);
    15898 assert(lp->nremovablecols <= lp->ncols);
    15899 assert(!lp->diving);
    15900 assert(set != NULL);
    15901 assert(stat != NULL);
    15902
    15903 if( lp->nremovablecols == 0 || set->lp_colagelimit == -1 || !lp->solisbasic )
    15904 return SCIP_OKAY;
    15905
    15906 ncols = lp->ncols;
    15907 cols = lp->cols;
    15908#ifndef NDEBUG
    15909 lpicols = lp->lpicols;
    15910#endif
    15911
    15912 /* get temporary memory */
    15913 SCIP_CALL( SCIPsetAllocBufferArray(set, &coldstat, ncols) );
    15914
    15915 /* mark obsolete columns to be deleted */
    15916 ndelcols = 0;
    15917 BMSclearMemoryArray(coldstat, ncols);
    15918 for( c = firstcol; c < ncols; ++c )
    15919 {
    15920 assert(cols[c] == lpicols[c]);
    15921 assert(cols[c]->lppos == c);
    15922 assert(cols[c]->lpipos == c);
    15923 if( cols[c]->removable
    15924 && cols[c]->obsoletenode != stat->nnodes /* don't remove column a second time from same node (avoid cycling), or a first time if marked nonremovable locally */
    15925 && cols[c]->age > set->lp_colagelimit
    15927 && SCIPsetIsZero(set, SCIPcolGetBestBound(cols[c])) ) /* bestbd != 0 -> column would be priced in next time */
    15928 {
    15929 assert(cols[c]->primsol == 0.0);
    15930 coldstat[c] = 1;
    15931 ndelcols++;
    15932 cols[c]->obsoletenode = stat->nnodes;
    15933 SCIPsetDebugMsg(set, "removing obsolete col <%s>: primsol=%f, bounds=[%g,%g]\n",
    15934 SCIPvarGetName(cols[c]->var), cols[c]->primsol, cols[c]->lb, cols[c]->ub);
    15935 }
    15936 }
    15937
    15938 SCIPsetDebugMsg(set, "removing %d/%d obsolete columns from LP\n", ndelcols, ncols);
    15939
    15940 /* delete the marked columns in the LP solver interface, update the LP respectively */
    15941 if( ndelcols > 0 )
    15942 {
    15943 SCIP_CALL( lpDelColset(lp, set, coldstat) );
    15944 }
    15945 assert(lp->ncols == ncols - ndelcols);
    15946
    15947 /* release temporary memory */
    15948 SCIPsetFreeBufferArray(set, &coldstat);
    15949
    15950 return SCIP_OKAY;
    15951}
    15952
    15953/** removes all basic rows, that are too old, beginning with the given firstrow */
    15954static
    15956 SCIP_LP* lp, /**< current LP data */
    15957 BMS_BLKMEM* blkmem, /**< block memory buffers */
    15958 SCIP_SET* set, /**< global SCIP settings */
    15959 SCIP_STAT* stat, /**< problem statistics */
    15960 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    15961 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    15962 int firstrow /**< first row to check for clean up */
    15963 )
    15964{
    15965 SCIP_ROW** rows;
    15966#ifndef NDEBUG
    15967 SCIP_ROW** lpirows;
    15968#endif
    15969 int* rowdstat;
    15970 int nrows;
    15971 int ndelrows;
    15972 int r;
    15973
    15974 assert(lp != NULL);
    15975 assert(lp->flushed);
    15976 assert(lp->nrows == lp->nlpirows);
    15977 assert(lp->nremovablerows <= lp->nrows);
    15978 assert(!lp->diving);
    15979 assert(set != NULL);
    15980 assert(stat != NULL);
    15981
    15982 if( lp->nremovablerows == 0 || set->lp_rowagelimit == -1 || !lp->solisbasic )
    15983 return SCIP_OKAY;
    15984
    15985 nrows = lp->nrows;
    15986 rows = lp->rows;
    15987#ifndef NDEBUG
    15988 lpirows = lp->lpirows;
    15989#endif
    15990
    15991 /* get temporary memory */
    15992 SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
    15993
    15994 /* mark obsolete rows to be deleted */
    15995 ndelrows = 0;
    15996 BMSclearMemoryArray(rowdstat, nrows);
    15997 for( r = firstrow; r < nrows; ++r )
    15998 {
    15999 assert(rows[r] == lpirows[r]);
    16000 assert(rows[r]->lppos == r);
    16001 assert(rows[r]->lpipos == r);
    16002 if( rows[r]->removable
    16003 && rows[r]->obsoletenode != stat->nnodes /* don't remove row a second time from same node (avoid cycling), or a first time if marked nonremovable locally */
    16004 && rows[r]->age > set->lp_rowagelimit
    16006 {
    16007 rowdstat[r] = 1;
    16008 ndelrows++;
    16009 rows[r]->obsoletenode = stat->nnodes;
    16010 SCIPsetDebugMsg(set, "removing obsolete row <%s>: activity=%f, sides=[%g,%g]\n",
    16011 rows[r]->name, rows[r]->activity, rows[r]->lhs, rows[r]->rhs);
    16012 }
    16013 }
    16014
    16015 SCIPsetDebugMsg(set, "removing %d/%d obsolete rows from LP\n", ndelrows, nrows);
    16016
    16017 /* delete the marked rows in the LP solver interface, update the LP respectively */
    16018 if( ndelrows > 0 )
    16019 {
    16020 SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
    16021 }
    16022 assert(lp->nrows == nrows - ndelrows);
    16023
    16024 /* release temporary memory */
    16025 SCIPsetFreeBufferArray(set, &rowdstat);
    16026
    16027 return SCIP_OKAY;
    16028}
    16029
    16030/** removes all non-basic columns and basic rows in the part of the LP created at the current node, that are too old */
    16032 SCIP_LP* lp, /**< current LP data */
    16033 BMS_BLKMEM* blkmem, /**< block memory buffers */
    16034 SCIP_SET* set, /**< global SCIP settings */
    16035 SCIP_STAT* stat, /**< problem statistics */
    16036 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    16037 SCIP_EVENTFILTER* eventfilter /**< global event filter */
    16038 )
    16039{
    16040 assert(lp != NULL);
    16041 assert(lp->solved);
    16042 assert(!lp->diving);
    16044 assert(set != NULL);
    16045
    16046 SCIPsetDebugMsg(set, "removing obsolete columns starting with %d/%d, obsolete rows starting with %d/%d\n",
    16047 lp->firstnewcol, lp->ncols, lp->firstnewrow, lp->nrows);
    16048
    16049 if( lp->firstnewcol < lp->ncols )
    16050 {
    16051 SCIP_CALL( lpRemoveObsoleteCols(lp, set, stat, lp->firstnewcol) );
    16052 }
    16053 if( lp->firstnewrow < lp->nrows )
    16054 {
    16055 SCIP_CALL( lpRemoveObsoleteRows(lp, blkmem, set, stat, eventqueue, eventfilter, lp->firstnewrow) );
    16056 }
    16057
    16058 return SCIP_OKAY;
    16059}
    16060
    16061/** removes all non-basic columns and basic rows in whole LP, that are too old */
    16063 SCIP_LP* lp, /**< current LP data */
    16064 BMS_BLKMEM* blkmem, /**< block memory buffers */
    16065 SCIP_SET* set, /**< global SCIP settings */
    16066 SCIP_STAT* stat, /**< problem statistics */
    16067 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    16068 SCIP_EVENTFILTER* eventfilter /**< global event filter */
    16069 )
    16070{
    16071 assert(lp != NULL);
    16072 assert(lp->solved);
    16073 assert(!lp->diving);
    16075 assert(set != NULL);
    16076
    16077 SCIPsetDebugMsg(set, "removing all obsolete columns and rows\n");
    16078
    16079 if( 0 < lp->ncols )
    16080 {
    16081 SCIP_CALL( lpRemoveObsoleteCols(lp, set, stat, 0) );
    16082 }
    16083 if( 0 < lp->nrows )
    16084 {
    16085 SCIP_CALL( lpRemoveObsoleteRows(lp, blkmem, set, stat, eventqueue, eventfilter, 0) );
    16086 }
    16087
    16088 return SCIP_OKAY;
    16089}
    16090
    16091/** removes all non-basic columns at 0.0 beginning with the given firstcol */
    16092static
    16094 SCIP_LP* lp, /**< current LP data */
    16095 SCIP_SET* set, /**< global SCIP settings */
    16096 SCIP_STAT* stat, /**< problem statistics */
    16097 int firstcol /**< first column to check for clean up */
    16098 )
    16099{
    16100 SCIP_COL** cols;
    16101 SCIP_COL** lpicols;
    16102 int* coldstat;
    16103 int ncols;
    16104 int ndelcols;
    16105 int c;
    16106
    16107 assert(lp != NULL);
    16108 assert(lp->flushed);
    16109 assert(lp->ncols == lp->nlpicols);
    16110 assert(!lp->diving);
    16111 assert(stat != NULL);
    16112 assert(lp->validsollp == stat->lpcount);
    16113 assert(0 <= firstcol && firstcol < lp->ncols);
    16114
    16115 if( lp->nremovablecols == 0 || !lp->solisbasic )
    16116 return SCIP_OKAY;
    16117
    16118 ncols = lp->ncols;
    16119 cols = lp->cols;
    16120 lpicols = lp->lpicols;
    16121
    16122 /* get temporary memory */
    16123 SCIP_CALL( SCIPsetAllocBufferArray(set, &coldstat, ncols) );
    16124
    16125 /* mark unused columns to be deleted */
    16126 ndelcols = 0;
    16127 BMSclearMemoryArray(coldstat, ncols);
    16128 for( c = firstcol; c < ncols; ++c )
    16129 {
    16130 assert(cols[c] == lpicols[c]);
    16131 assert(cols[c]->lppos == c);
    16132 assert(cols[c]->lpipos == c);
    16133 if( lpicols[c]->removable
    16134 && (SCIP_BASESTAT)lpicols[c]->basisstatus != SCIP_BASESTAT_BASIC
    16135 && lpicols[c]->primsol == 0.0 /* non-basic columns to remove are exactly at 0.0 */
    16136 && SCIPsetIsZero(set, SCIPcolGetBestBound(cols[c])) ) /* bestbd != 0 -> column would be priced in next time */
    16137 {
    16138 coldstat[c] = 1;
    16139 ndelcols++;
    16140 }
    16141 }
    16142
    16143 SCIPsetDebugMsg(set, "removing %d/%d unused columns from LP\n", ndelcols, ncols);
    16144
    16145 /* delete the marked columns in the LP solver interface, update the LP respectively */
    16146 if( ndelcols > 0 )
    16147 {
    16148 SCIP_CALL( lpDelColset(lp, set, coldstat) );
    16149 }
    16150 assert(lp->ncols == ncols - ndelcols);
    16151
    16152 /* release temporary memory */
    16153 SCIPsetFreeBufferArray(set, &coldstat);
    16154
    16155 return SCIP_OKAY;
    16156}
    16157
    16158/** removes all basic rows beginning with the given firstrow */
    16159static
    16161 SCIP_LP* lp, /**< current LP data */
    16162 BMS_BLKMEM* blkmem, /**< block memory buffers */
    16163 SCIP_SET* set, /**< global SCIP settings */
    16164 SCIP_STAT* stat, /**< problem statistics */
    16165 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    16166 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    16167 int firstrow /**< first row to check for clean up */
    16168 )
    16169{
    16170#ifndef NDEBUG
    16171 SCIP_ROW** rows;
    16172#endif
    16173 SCIP_ROW** lpirows;
    16174 int* rowdstat;
    16175 int nrows;
    16176 int ndelrows;
    16177 int r;
    16178
    16179 assert(lp != NULL);
    16180 assert(lp->flushed);
    16181 assert(lp->ncols == lp->nlpicols);
    16182 assert(lp->nrows == lp->nlpirows);
    16183 assert(!lp->diving);
    16184 assert(stat != NULL);
    16185 assert(lp->validsollp == stat->lpcount);
    16186 assert(0 <= firstrow && firstrow < lp->nrows);
    16187
    16188 if( lp->nremovablerows == 0 || !lp->solisbasic )
    16189 return SCIP_OKAY;
    16190
    16191#ifndef NDEBUG
    16192 rows = lp->rows;
    16193#endif
    16194 nrows = lp->nrows;
    16195 lpirows = lp->lpirows;
    16196
    16197 /* get temporary memory */
    16198 SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
    16199
    16200 /* mark unused rows to be deleted */
    16201 ndelrows = 0;
    16202 BMSclearMemoryArray(rowdstat, nrows);
    16203 for( r = firstrow; r < nrows; ++r )
    16204 {
    16205 assert(rows[r] == lpirows[r]);
    16206 assert(rows[r]->lppos == r);
    16207 assert(rows[r]->lpipos == r);
    16208 if( lpirows[r]->removable && (SCIP_BASESTAT)lpirows[r]->basisstatus == SCIP_BASESTAT_BASIC )
    16209 {
    16210 rowdstat[r] = 1;
    16211 ndelrows++;
    16212 }
    16213 }
    16214
    16215 SCIPsetDebugMsg(set, "removing %d/%d unused rows from LP\n", ndelrows, nrows);
    16216
    16217 /* delete the marked rows in the LP solver interface, update the LP respectively */
    16218 if( ndelrows > 0 )
    16219 {
    16220 SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
    16221 }
    16222 assert(lp->nrows == nrows - ndelrows);
    16223
    16224 /* release temporary memory */
    16225 SCIPsetFreeBufferArray(set, &rowdstat);
    16226
    16227 return SCIP_OKAY;
    16228}
    16229
    16230/** removes all non-basic columns at 0.0 and basic rows in the part of the LP created at the current node */
    16232 SCIP_LP* lp, /**< current LP data */
    16233 BMS_BLKMEM* blkmem, /**< block memory buffers */
    16234 SCIP_SET* set, /**< global SCIP settings */
    16235 SCIP_STAT* stat, /**< problem statistics */
    16236 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    16237 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    16238 SCIP_Bool root /**< are we at the root node? */
    16239 )
    16240{
    16241 SCIP_Bool cleanupcols;
    16242 SCIP_Bool cleanuprows;
    16243
    16244 assert(lp != NULL);
    16245 assert(lp->solved);
    16246 assert(!lp->diving);
    16248 assert(set != NULL);
    16249
    16250 /* check, if we want to clean up the columns and rows */
    16251 cleanupcols = (root ? set->lp_cleanupcolsroot : set->lp_cleanupcols);
    16252 cleanuprows = (root ? set->lp_cleanuprowsroot : set->lp_cleanuprows);
    16253
    16254 SCIPsetDebugMsg(set, "removing unused columns starting with %d/%d (%u), unused rows starting with %d/%d (%u), LP algo: %d, basic sol: %u\n",
    16255 lp->firstnewcol, lp->ncols, cleanupcols, lp->firstnewrow, lp->nrows, cleanuprows, lp->lastlpalgo, lp->solisbasic);
    16256
    16257 if( cleanupcols && lp->firstnewcol < lp->ncols )
    16258 {
    16259 SCIP_CALL( lpCleanupCols(lp, set, stat, lp->firstnewcol) );
    16260 }
    16261 if( cleanuprows && lp->firstnewrow < lp->nrows )
    16262 {
    16263 SCIP_CALL( lpCleanupRows(lp, blkmem, set, stat, eventqueue, eventfilter, lp->firstnewrow) );
    16264 }
    16265
    16266 return SCIP_OKAY;
    16267}
    16268
    16269/** removes all non-basic columns at 0.0 and basic rows in the whole LP */
    16271 SCIP_LP* lp, /**< current LP data */
    16272 BMS_BLKMEM* blkmem, /**< block memory buffers */
    16273 SCIP_SET* set, /**< global SCIP settings */
    16274 SCIP_STAT* stat, /**< problem statistics */
    16275 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    16276 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    16277 SCIP_Bool root /**< are we at the root node? */
    16278 )
    16279{
    16280 SCIP_Bool cleanupcols;
    16281 SCIP_Bool cleanuprows;
    16282
    16283 assert(lp != NULL);
    16284 assert(lp->solved);
    16285 assert(!lp->diving);
    16287 assert(set != NULL);
    16288
    16289 /* check, if we want to clean up the columns and rows */
    16290 cleanupcols = (root ? set->lp_cleanupcolsroot : set->lp_cleanupcols);
    16291 cleanuprows = (root ? set->lp_cleanuprowsroot : set->lp_cleanuprows);
    16292
    16293 SCIPsetDebugMsg(set, "removing all unused columns (%u) and rows (%u), LP algo: %d, basic sol: %u\n",
    16294 cleanupcols, cleanuprows, lp->lastlpalgo, lp->solisbasic);
    16295
    16296 if( cleanupcols && 0 < lp->ncols )
    16297 {
    16298 SCIP_CALL( lpCleanupCols(lp, set, stat, 0) );
    16299 }
    16300 if( cleanuprows && 0 < lp->nrows )
    16301 {
    16302 SCIP_CALL( lpCleanupRows(lp, blkmem, set, stat, eventqueue, eventfilter, 0) );
    16303 }
    16304
    16305 return SCIP_OKAY;
    16306}
    16307
    16308/** removes all redundant rows that were added at the current node */
    16310 SCIP_LP* lp, /**< current LP data */
    16311 BMS_BLKMEM* blkmem, /**< block memory buffers */
    16312 SCIP_SET* set, /**< global SCIP settings */
    16313 SCIP_STAT* stat, /**< problem statistics */
    16314 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    16315 SCIP_EVENTFILTER* eventfilter /**< global event filter */
    16316 )
    16317{
    16318#ifndef NDEBUG
    16319 SCIP_ROW** rows;
    16320#endif
    16321 SCIP_ROW** lpirows;
    16322 int* rowdstat;
    16323 int nrows;
    16324 int ndelrows;
    16325 int r;
    16326
    16327 assert(lp != NULL);
    16328 assert(lp->flushed);
    16329 assert(lp->ncols == lp->nlpicols);
    16330 assert(lp->nrows == lp->nlpirows);
    16331 assert(!lp->diving);
    16332 assert(stat != NULL);
    16333 assert(lp->validsollp == stat->lpcount);
    16334 assert(lp->firstnewrow <= lp->nrows);
    16335
    16336 if( lp->firstnewrow == lp->nrows )
    16337 return SCIP_OKAY;
    16338
    16339#ifndef NDEBUG
    16340 rows = lp->rows;
    16341#endif
    16342 nrows = lp->nrows;
    16343 lpirows = lp->lpirows;
    16344
    16345 /* get temporary memory */
    16346 SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
    16347
    16348 /* mark redundant rows to be deleted (only delete basic rows!) */
    16349 ndelrows = 0;
    16350 BMSclearMemoryArray(rowdstat, nrows);
    16351 for( r = lp->firstnewrow; r < nrows; ++r )
    16352 {
    16353 assert(rows[r] == lpirows[r]);
    16354 assert(rows[r]->lppos == r);
    16355 assert(rows[r]->lpipos == r);
    16356 if( (!lp->solisbasic || (SCIP_BASESTAT)lpirows[r]->basisstatus == SCIP_BASESTAT_BASIC)
    16357 && SCIProwIsRedundant(lpirows[r], set, stat) )
    16358 {
    16359 SCIPsetDebugMsg(set, "basic row <%s> is redundant: sides=[%g,%g], act=[%g,%g]\n",
    16360 SCIProwGetName(lpirows[r]), SCIProwGetLhs(lpirows[r]), SCIProwGetRhs(lpirows[r]),
    16361 SCIProwGetMinActivity(lpirows[r], set, stat), SCIProwGetMaxActivity(lpirows[r], set, stat));
    16362 rowdstat[r] = 1;
    16363 ndelrows++;
    16364 }
    16365 }
    16366
    16367 SCIPsetDebugMsg(set, "removing %d/%d redundant basic rows from LP\n", ndelrows, nrows);
    16368
    16369 /* delete the marked rows in the LP solver interface, update the LP respectively */
    16370 if( ndelrows > 0 )
    16371 {
    16372 SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
    16373 }
    16374 assert(lp->nrows == nrows - ndelrows);
    16375
    16376 /* release temporary memory */
    16377 SCIPsetFreeBufferArray(set, &rowdstat);
    16378
    16379 return SCIP_OKAY;
    16380}
    16381
    16382/** initiates LP diving */
    16384 SCIP_LP* lp, /**< current LP data */
    16385 BMS_BLKMEM* blkmem, /**< block memory */
    16386 SCIP_SET* set, /**< global SCIP settings */
    16387 SCIP_STAT* stat /**< problem statistics */
    16388 )
    16389{
    16390 int c;
    16391 int r;
    16392
    16393 assert(lp != NULL);
    16394 assert(lp->flushed || !lp->solved);
    16395 assert(!lp->diving);
    16396 assert(!lp->probing);
    16397 assert(lp->divelpistate == NULL);
    16398 assert(lp->divelpwasprimfeas);
    16399 assert(lp->divelpwasdualfeas);
    16400 assert(lp->validsollp <= stat->lpcount);
    16401 assert(blkmem != NULL);
    16402 assert(set != NULL);
    16403 assert(lp->ndivechgsides == 0);
    16404
    16405 SCIPsetDebugMsg(set, "diving started (LP flushed: %u, LP solved: %u, solstat: %d)\n",
    16406 lp->flushed, lp->solved, SCIPlpGetSolstat(lp));
    16407
    16408#ifndef NDEBUG
    16409 for( c = 0; c < lp->ncols; ++c )
    16410 {
    16411 assert(lp->cols[c] != NULL);
    16412 assert(lp->cols[c]->var != NULL);
    16413 assert(SCIPvarGetStatus(lp->cols[c]->var) == SCIP_VARSTATUS_COLUMN);
    16414 assert(SCIPvarGetCol(lp->cols[c]->var) == lp->cols[c]);
    16415 assert(SCIPsetIsFeasEQ(set, SCIPvarGetObj(lp->cols[c]->var), lp->cols[c]->obj));
    16416 assert(SCIPsetIsFeasEQ(set, SCIPvarGetLbLocal(lp->cols[c]->var), lp->cols[c]->lb));
    16417 assert(SCIPsetIsFeasEQ(set, SCIPvarGetUbLocal(lp->cols[c]->var), lp->cols[c]->ub));
    16418 }
    16419#endif
    16420
    16421 /* save current LPI state (basis information) */
    16422 SCIP_CALL( SCIPlpiGetState(lp->lpi, blkmem, &lp->divelpistate) );
    16427
    16428 /* save current LP values dependent on the solution */
    16429 SCIP_CALL( lpStoreSolVals(lp, stat, blkmem) );
    16430 assert(lp->storedsolvals != NULL);
    16431 if( !set->lp_resolverestore && lp->solved )
    16432 {
    16433 SCIP_Bool store = TRUE;
    16434
    16435 switch ( lp->lpsolstat )
    16436 {
    16438 SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
    16439 assert(lp->validsollp == stat->lpcount);
    16440 break;
    16443 assert(lp->validsollp == stat->lpcount);
    16444 break;
    16448 SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
    16449 assert(lp->validsollp == stat->lpcount);
    16450 break;
    16452 SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat, FALSE, NULL) );
    16453 break;
    16456 default:
    16457 store = FALSE;
    16458 }
    16459
    16460 if ( store )
    16461 {
    16462 for( c = 0; c < lp->ncols; ++c )
    16463 {
    16464 SCIP_CALL( colStoreSolVals(lp->cols[c], blkmem) );
    16465 }
    16466 for( r = 0; r < lp->nrows; ++r )
    16467 {
    16469 }
    16470 }
    16471 }
    16472
    16473 /* store LPI iteration limit */
    16475
    16476 /* remember the number of domain changes */
    16477 lp->divenolddomchgs = stat->domchgcount;
    16478
    16479 /* store current number of rows */
    16480 lp->ndivingrows = lp->nrows;
    16481
    16482 /* switch to diving mode */
    16483 lp->diving = TRUE;
    16484
    16485 return SCIP_OKAY;
    16486}
    16487
    16488/** quits LP diving and resets bounds and objective values of columns to the current node's values */
    16490 SCIP_LP* lp, /**< current LP data */
    16491 BMS_BLKMEM* blkmem, /**< block memory */
    16492 SCIP_SET* set, /**< global SCIP settings */
    16493 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    16494 SCIP_STAT* stat, /**< problem statistics */
    16495 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    16496 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    16497 SCIP_PROB* prob, /**< problem data */
    16498 SCIP_VAR** vars, /**< array with all active variables */
    16499 int nvars /**< number of active variables */
    16500 )
    16501{
    16502 SCIP_VAR* var;
    16503 int v;
    16504
    16505 assert(lp != NULL);
    16506 assert(lp->diving);
    16507 assert(blkmem != NULL);
    16508 assert(nvars == 0 || vars != NULL);
    16509
    16510 SCIPsetDebugMsg(set, "diving ended (LP flushed: %u, solstat: %d)\n", lp->flushed, SCIPlpGetSolstat(lp));
    16511
    16512 /* reset all columns' objective values and bounds to its original values */
    16513 for( v = 0; v < nvars; ++v )
    16514 {
    16515 var = vars[v];
    16516 assert(var != NULL);
    16518 {
    16522 }
    16523 }
    16524
    16525 /* remove rows which were added in diving mode */
    16526 SCIP_CALL( SCIPlpShrinkRows(lp, blkmem, set, eventqueue, eventfilter, lp->ndivingrows) );
    16527
    16528 /* undo changes to left hand sides and right hand sides */
    16529 while( lp->ndivechgsides > 0 )
    16530 {
    16531 SCIP_Real oldside;
    16532 SCIP_SIDETYPE sidetype;
    16533 SCIP_ROW* row;
    16534
    16535 lp->ndivechgsides--;
    16536 oldside = lp->divechgsides[lp->ndivechgsides];
    16537 sidetype = lp->divechgsidetypes[lp->ndivechgsides];
    16538 row = lp->divechgrows[lp->ndivechgsides];
    16539
    16540 if( sidetype == SCIP_SIDETYPE_LEFT )
    16541 {
    16542 SCIP_CALL( SCIProwChgLhs(row, blkmem, set, eventqueue, lp, oldside) );
    16543 }
    16544 else
    16545 {
    16546 SCIP_CALL( SCIProwChgRhs(row, blkmem, set, eventqueue, lp, oldside) );
    16547 }
    16548 }
    16549
    16550 /* restore LPI iteration limit */
    16552
    16553 /* reload LPI state saved at start of diving and free it afterwards; it may be NULL, in which case simply nothing
    16554 * happens
    16555 */
    16556 SCIP_CALL( SCIPlpSetState(lp, blkmem, set, prob, eventqueue, lp->divelpistate,
    16558 SCIP_CALL( SCIPlpFreeState(lp, blkmem, &lp->divelpistate) );
    16559 lp->divelpwasprimfeas = TRUE;
    16560 lp->divelpwasdualfeas = TRUE;
    16563 assert(lp->divelpistate == NULL);
    16564
    16565 /* switch to standard (non-diving) mode */
    16566 lp->diving = FALSE;
    16567 lp->divingobjchg = FALSE;
    16568
    16569 /* if the LP was solved before starting the dive, but not to optimality (or unboundedness), then we need to solve the
    16570 * LP again to reset the solution (e.g. we do not save the Farkas proof for infeasible LPs, because we assume that we
    16571 * are not called in this case, anyway); restoring by solving the LP again in either case can be forced by setting
    16572 * the parameter resolverestore to TRUE
    16573 * restoring an unbounded ray after solve does not seem to work currently (bug 631), so we resolve also in this case
    16574 */
    16575 assert(lp->storedsolvals != NULL);
    16576 if( lp->storedsolvals->lpissolved && !set->exact_enable
    16577 && (set->lp_resolverestore || lp->storedsolvals->lpsolstat != SCIP_LPSOLSTAT_OPTIMAL || lp->divenolddomchgs < stat->domchgcount) )
    16578 {
    16579 SCIP_Bool lperror;
    16580
    16581 SCIP_CALL( SCIPlpSolveAndEval(lp, set, messagehdlr, blkmem, stat, eventqueue, eventfilter, prob, -1LL, FALSE, FALSE, FALSE, FALSE, &lperror) );
    16582 if( lperror )
    16583 {
    16584 lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved when resolving LP after diving");
    16585 lp->resolvelperror = TRUE;
    16586 }
    16591 {
    16592 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    16593 "LP was not resolved to a sufficient status after diving\n");
    16594 lp->resolvelperror = TRUE;
    16595 }
    16596 }
    16597 /* otherwise, we can just reload the buffered LP solution values at start of diving; this has the advantage that we
    16598 * are guaranteed to continue with the same LP status as before diving, while in numerically difficult cases, a
    16599 * re-solve as above can lead to a different LP status
    16600 */
    16601 else
    16602 {
    16603 int c;
    16604 int r;
    16605
    16606 /* if there are lazy bounds, remove them from the LP */
    16607 if( lp->nlazycols > 0 )
    16608 {
    16609 /* @todo avoid loosing primal feasibility here after changing the objective already did destroy dual feasibility;
    16610 * first resolve LP?
    16611 */
    16613 assert(lp->diving == lp->divinglazyapplied);
    16614
    16615 /* flush changes to the LP solver */
    16616 SCIP_CALL( SCIPlpFlush(lp, blkmem, set, prob, eventqueue) );
    16617 }
    16618
    16619 /* increment lp counter to ensure that we do not use solution values from the last solved diving lp; only when we
    16620 * are in exact diving mode, we do not want to increase it since we want to use the exact diving solution added
    16621 * by the exactsol constraint handler
    16622 */
    16623 if( !SCIPlpExactDiving(lp->lpexact) )
    16624 SCIPstatIncrement(stat, set, lpcount);
    16625
    16626 /* restore LP solution values in lp data, columns and rows */
    16627 if( lp->storedsolvals->lpissolved &&
    16634 )
    16635 {
    16636 SCIP_CALL( lpRestoreSolVals(lp, blkmem, stat->lpcount) );
    16637
    16638 for( c = 0; c < lp->ncols; ++c )
    16639 {
    16640 SCIP_CALL( colRestoreSolVals(lp->cols[c], blkmem, stat->lpcount, set->lp_freesolvalbuffers) );
    16641 }
    16642 for( r = 0; r < lp->nrows; ++r )
    16643 {
    16644 SCIP_CALL( rowRestoreSolVals(lp->rows[r], blkmem, stat->lpcount, set->lp_freesolvalbuffers, lp->storedsolvals->lpsolstat == SCIP_LPSOLSTAT_INFEASIBLE) );
    16645 }
    16646 }
    16647 else
    16648 {
    16649 SCIP_CALL( lpRestoreSolVals(lp, blkmem, -1LL) );
    16650 }
    16651 }
    16652
    16653#ifndef NDEBUG
    16654 {
    16655 int c;
    16656 for( c = 0; c < lp->ncols; ++c )
    16657 {
    16658 assert(lp->cols[c] != NULL);
    16659 assert(lp->cols[c]->var != NULL);
    16660 assert(SCIPvarGetStatus(lp->cols[c]->var) == SCIP_VARSTATUS_COLUMN);
    16661 assert(SCIPvarGetCol(lp->cols[c]->var) == lp->cols[c]);
    16662 assert(SCIPsetIsEQ(set, SCIPvarGetObj(lp->cols[c]->var), lp->cols[c]->obj));
    16663 assert(SCIPsetIsEQ(set, SCIPvarGetLbLocal(lp->cols[c]->var), lp->cols[c]->lb));
    16664 assert(SCIPsetIsEQ(set, SCIPvarGetUbLocal(lp->cols[c]->var), lp->cols[c]->ub));
    16665 }
    16666 }
    16667#endif
    16668
    16669 return SCIP_OKAY;
    16670}
    16671
    16672#define DIVESTACKGROWFACT 1.5
    16673
    16674/** records a current row side such that any change will be undone after diving */
    16676 SCIP_LP* lp, /**< LP data object */
    16677 SCIP_ROW* row, /**< row affected by the change */
    16678 SCIP_SIDETYPE sidetype /**< side type */
    16679 )
    16680{
    16681 assert(lp != NULL);
    16682 assert(row != NULL);
    16683
    16684 if( lp->ndivechgsides == lp->divechgsidessize )
    16685 {
    16687 }
    16688 assert(lp->ndivechgsides < lp->divechgsidessize);
    16689
    16690 lp->divechgsides[lp->ndivechgsides] = (sidetype == SCIP_SIDETYPE_LEFT) ? row->lhs : row->rhs;
    16691 lp->divechgsidetypes[lp->ndivechgsides] = sidetype;
    16692 lp->divechgrows[lp->ndivechgsides] = row;
    16693 lp->ndivechgsides++;
    16694
    16695 return SCIP_OKAY;
    16696}
    16697
    16698/** informs the LP that probing mode was initiated */
    16700 SCIP_LP* lp /**< current LP data */
    16701 )
    16702{
    16703 assert(lp != NULL);
    16704 assert(!lp->probing);
    16705 assert(!lp->strongbranching);
    16706 assert(!lp->strongbranchprobing);
    16707
    16708 lp->probing = TRUE;
    16709
    16710 return SCIP_OKAY;
    16711}
    16712
    16713/** informs the LP that probing mode was finished */
    16715 SCIP_LP* lp /**< current LP data */
    16716 )
    16717{
    16718 assert(lp != NULL);
    16719 assert(lp->probing);
    16720 assert(!lp->strongbranching);
    16721 assert(!lp->strongbranchprobing);
    16722
    16723 lp->probing = FALSE;
    16724
    16725 return SCIP_OKAY;
    16726}
    16727
    16728/** informs the LP that the probing mode is now used for strongbranching */
    16730 SCIP_LP* lp /**< current LP data */
    16731 )
    16732{
    16733 assert(lp != NULL);
    16734 assert(lp->probing);
    16735 assert(!lp->strongbranching);
    16736 assert(!lp->strongbranchprobing);
    16737
    16739}
    16740
    16741/** informs the LP that the probing mode is not used for strongbranching anymore */
    16743 SCIP_LP* lp /**< current LP data */
    16744 )
    16745{
    16746 assert(lp != NULL);
    16747 assert(lp->probing);
    16748 assert(!lp->strongbranching);
    16749 assert(lp->strongbranchprobing);
    16750
    16752}
    16753
    16754/** calculates y*b + min{(c - y*A)*x | lb <= x <= ub} for given vectors y and c;
    16755 * the vector b is defined with b[i] = lhs[i] if y[i] >= 0, b[i] = rhs[i] if y[i] < 0
    16756 * Calculating this value in interval arithmetics gives a proved lower LP bound for the following reason (assuming,
    16757 * we have only left hand sides):
    16758 * min{cx | b <= Ax, lb <= x <= ub}
    16759 * >= min{cx | yb <= yAx, lb <= x <= ub} (restriction in minimum is relaxed)
    16760 * == yb + min{cx - yb | yb <= yAx, lb <= x <= ub} (added yb - yb == 0)
    16761 * >= yb + min{cx - yAx | yb <= yAx, lb <= x <= ub} (because yAx >= yb inside minimum)
    16762 * >= yb + min{cx - yAx | lb <= x <= ub} (restriction in minimum is relaxed)
    16763 */
    16764static
    16766 SCIP_LP* lp, /**< current LP data */
    16767 SCIP_SET* set, /**< global SCIP settings */
    16768 SCIP_Bool usefarkas, /**< use y = dual Farkas and c = 0 instead of y = dual solution and c = obj? */
    16769 SCIP_Real* bound /**< result of interval arithmetic minimization */
    16770 )
    16771{
    16772 SCIP_INTERVAL* yinter;
    16774 SCIP_INTERVAL ytb;
    16775 SCIP_INTERVAL prod;
    16776 SCIP_INTERVAL diff;
    16778 SCIP_INTERVAL minprod;
    16780 SCIP_ROW* row;
    16781 SCIP_COL* col;
    16782 SCIP_Real y;
    16783 SCIP_Real c;
    16784 int i;
    16785 int j;
    16786
    16787 assert(lp != NULL);
    16788 assert(lp->solved);
    16789 assert(set != NULL);
    16790 assert(bound != NULL);
    16791
    16792 /* allocate buffer for storing y in interval arithmetic */
    16793 SCIP_CALL( SCIPsetAllocBufferArray(set, &yinter, lp->nrows) );
    16794
    16795 /* create y vector in interval arithmetic, setting near zeros to zero; calculate y^Tb */
    16796 SCIPintervalSet(&ytb, 0.0);
    16797 for( j = 0; j < lp->nrows; ++j )
    16798 {
    16799 row = lp->rows[j];
    16800 assert(row != NULL);
    16801
    16802 y = (usefarkas ? row->dualfarkas : row->dualsol);
    16803
    16805 {
    16806 SCIPintervalSet(&yinter[j], y);
    16807 SCIPintervalSet(&b, row->lhs - row->constant);
    16808 }
    16809 else if( SCIPsetIsFeasNegative(set, y) )
    16810 {
    16811 SCIPintervalSet(&yinter[j], y);
    16812 SCIPintervalSet(&b, row->rhs - row->constant);
    16813 }
    16814 else
    16815 {
    16816 SCIPintervalSet(&yinter[j], 0.0);
    16817 SCIPintervalSet(&b, 0.0);
    16818 }
    16819
    16820 SCIPintervalMul(SCIPsetInfinity(set), &prod, yinter[j], b);
    16821 SCIPintervalAdd(SCIPsetInfinity(set), &ytb, ytb, prod);
    16822 }
    16823
    16824 /* calculate min{(c^T - y^TA)x} */
    16825 SCIPintervalSet(&minprod, 0.0);
    16826 for( j = 0; j < lp->ncols; ++j )
    16827 {
    16828 col = lp->cols[j];
    16829 assert(col != NULL);
    16830 assert(col->nunlinked == 0);
    16831
    16833
    16834 c = usefarkas ? 0.0 : col->obj;
    16835 SCIPintervalSet(&diff, c);
    16836
    16837 for( i = 0; i < col->nlprows; ++i )
    16838 {
    16839 assert(col->rows[i] != NULL);
    16840 assert(col->rows[i]->lppos >= 0);
    16841 assert(col->linkpos[i] >= 0);
    16842 SCIPintervalSet(&a, col->vals[i]);
    16843 SCIPintervalMul(SCIPsetInfinity(set), &prod, yinter[col->rows[i]->lppos], a);
    16844 SCIPintervalSub(SCIPsetInfinity(set), &diff, diff, prod);
    16845 }
    16846
    16847#ifndef NDEBUG
    16848 for( i = col->nlprows; i < col->len; ++i )
    16849 {
    16850 assert(col->rows[i] != NULL);
    16851 assert(col->rows[i]->lppos == -1);
    16852 assert(col->rows[i]->dualsol == 0.0);
    16853 assert(col->rows[i]->dualfarkas == 0.0);
    16854 assert(col->linkpos[i] >= 0);
    16855 }
    16856#endif
    16857
    16858 SCIPintervalSetBounds(&x, col->lb, col->ub);
    16859 SCIPintervalMul(SCIPsetInfinity(set), &diff, diff, x);
    16860 SCIPintervalAdd(SCIPsetInfinity(set), &minprod, minprod, diff);
    16861 }
    16862
    16863 /* add y^Tb */
    16864 SCIPintervalAdd(SCIPsetInfinity(set), &minprod, minprod, ytb);
    16865
    16866 /* free buffer for storing y in interval arithmetic */
    16867 SCIPsetFreeBufferArray(set, &yinter);
    16868
    16869 *bound = SCIPintervalGetInf(minprod);
    16870
    16871 return SCIP_OKAY;
    16872}
    16873
    16874/** gets proven lower (dual) bound of last LP solution */
    16876 SCIP_LP* lp, /**< current LP data */
    16877 SCIP_SET* set, /**< global SCIP settings */
    16878 SCIP_Real* bound /**< pointer to store proven dual bound */
    16879 )
    16880{
    16882
    16883 SCIPsetDebugMsg(set, "proved lower bound of LP: %.15g\n", *bound);
    16884
    16885 return SCIP_OKAY;
    16886}
    16887
    16888/** gets proven dual bound of last LP solution */
    16890 SCIP_LP* lp, /**< current LP data */
    16891 SCIP_SET* set, /**< global SCIP settings */
    16892 SCIP_Bool* proved /**< pointer to store whether infeasibility is proven */
    16893 )
    16894{
    16896
    16897 assert(proved != NULL);
    16898
    16899 SCIP_CALL( provedBound(lp, set, TRUE, &bound) );
    16900
    16901 *proved = (bound > 0.0);
    16902
    16903 SCIPsetDebugMsg(set, "proved Farkas value of LP: %g -> infeasibility %sproved\n", bound, *proved ? "" : "not ");
    16904
    16905 return SCIP_OKAY;
    16906}
    16907
    16908
    16909
    16910/** writes LP to a file */
    16912 SCIP_LP* lp, /**< current LP data */
    16913 const char* fname /**< file name */
    16914 )
    16915{
    16916 assert(lp != NULL);
    16917 assert(fname != NULL);
    16918
    16919 SCIP_CALL( SCIPlpiWriteLP(lp->lpi, fname) );
    16920
    16921 return SCIP_OKAY;
    16922}
    16923
    16924/** writes MIP relaxation of the current B&B node to a file */
    16926 SCIP_LP* lp, /**< current LP data */
    16927 SCIP_SET* set, /**< global SCIP settings */
    16928 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    16929 const char* fname, /**< file name */
    16930 SCIP_Bool genericnames, /**< should generic names like x_i and row_j be used in order to avoid
    16931 * troubles with reserved symbols? */
    16932 SCIP_Bool origobj, /**< should the original objective function be used? */
    16933 SCIP_OBJSENSE objsense, /**< objective sense */
    16934 SCIP_Real objscale, /**< objective scaling factor */
    16935 SCIP_Real objoffset, /**< objective offset, e.g., caused by variable fixings in presolving */
    16936 SCIP_Bool lazyconss /**< output removable rows as lazy constraints? */
    16937 )
    16938{
    16939 FILE* file;
    16940 int i;
    16941 int j;
    16942 char rowname[SCIP_MAXSTRLEN];
    16943 SCIP_Real coeff;
    16944
    16945 assert(lp != NULL);
    16946 assert(fname != NULL);
    16947
    16948 SCIPsetDebugMsg(set, "Start to write MIP to file <%s>\n", fname);
    16949 file = fopen(fname, "w");
    16950 if( file == NULL )
    16951 {
    16952 SCIPerrorMessage("cannot open file <%s> for writing\n", fname);
    16953 SCIPprintSysError(fname);
    16954 return SCIP_FILECREATEERROR;
    16955 }
    16956
    16957 /* print comments */
    16958 if( genericnames )
    16959 SCIPmessageFPrintInfo(messagehdlr, file, "\\ Original Variable and Constraint Names have been replaced by generic names.\n");
    16960 else
    16961 {
    16962 SCIPmessageFPrintInfo(messagehdlr, file, "\\ Warning: Variable and Constraint Names should not contain special characters like '+', '=' etc.\n");
    16963 SCIPmessageFPrintInfo(messagehdlr, file, "\\ If this is the case, the model may be corrupted!\n");
    16964 }
    16965
    16966 if( origobj && objoffset != 0.0 )
    16967 {
    16968 SCIPmessageFPrintInfo(messagehdlr, file, "\\ An artificial variable 'objoffset' has been added and fixed to 1.\n");
    16969 SCIPmessageFPrintInfo(messagehdlr, file, "\\ Switching this variable to 0 will disable the offset in the objective.\n\n");
    16970 }
    16971
    16972 /* print objective function */
    16973 /**@note the transformed problem in SCIP is always a minimization problem */
    16974 if( !origobj || objsense == SCIP_OBJSENSE_MINIMIZE )
    16975 SCIPmessageFPrintInfo(messagehdlr, file, "Minimize");
    16976 else
    16977 SCIPmessageFPrintInfo(messagehdlr, file, "Maximize");
    16978
    16979 /* print objective */
    16980 SCIPmessageFPrintInfo(messagehdlr, file, "\nObj:");
    16981 j = 0;
    16982 for( i = 0; i < lp->ncols; ++i )
    16983 {
    16984 if( lp->cols[i]->obj != 0.0 )
    16985 {
    16986 coeff = lp->cols[i]->obj;
    16987 if( origobj )
    16988 {
    16989 coeff *= (SCIP_Real) objsense;
    16990 coeff *= objscale;
    16991 }
    16992
    16993 if( genericnames )
    16994 SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", coeff, lp->cols[i]->lppos);
    16995 else
    16996 SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", coeff, lp->cols[i]->var->name);
    16997
    16998 ++j;
    16999 if( j % 10 == 0 )
    17000 SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
    17001 }
    17002 }
    17003 /* add artificial variable 'objoffset' to transfer objective offset */
    17004 if( origobj && objoffset != 0.0 )
    17005 SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g objoffset", objoffset * (SCIP_Real) objsense * objscale);
    17006
    17007 /* print constraint section */
    17008 SCIPmessageFPrintInfo(messagehdlr, file, "\nSubject to\n");
    17009 for( i = 0; i < lp->nrows; i++ )
    17010 {
    17011 char type = 'i';
    17012
    17013 /* skip removable rows if we want to write them as lazy constraints */
    17014 if ( lazyconss && SCIProwIsRemovable(lp->rows[i]) )
    17015 continue;
    17016
    17017 /* constraint types: 'l' means: only lhs exists, 'r' means: only rhs exists, 'e' means: both sides exist and are
    17018 * equal, 'b' and 'B' mean: both sides exist, if the type is 'b', the lhs will be written, if the type is 'B',
    17019 * the rhs will be written. Ergo: set type to b first, change it to 'B' afterwards and go back to WRITEROW.
    17020 * type 'i' means: lhs and rhs are both infinite */
    17021 if( SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
    17022 type = 'r';
    17023 else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
    17024 type = 'l';
    17025 else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsEQ(set, lp->rows[i]->lhs, lp->rows[i]->rhs) )
    17026 type = 'e';
    17027 else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
    17028 type = 'b';
    17029
    17030 /* print name of row */
    17031 if( genericnames )
    17032 (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "row_%d", lp->rows[i]->lppos);
    17033 else
    17034 (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s", lp->rows[i]->name);
    17035
    17036 WRITEROW:
    17037 switch( type )
    17038 {
    17039 case 'r':
    17040 case 'l':
    17041 case 'e':
    17042 if( strlen(rowname) > 0 )
    17043 SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", rowname);
    17044 break;
    17045 case 'i':
    17046 SCIPmessageFPrintInfo(messagehdlr, file, "\\\\ WARNING: The lhs and the rhs of the row with original name <%s>", lp->rows[i]->name);
    17047 SCIPmessageFPrintInfo(messagehdlr, file, "are not in a valid range. The following two constraints may be corrupted!\n");
    17048 SCIPmessagePrintWarning(messagehdlr, "The lhs and rhs of row <%s> are not in a valid range.\n", lp->rows[i]->name);
    17049 type = 'b';
    17050 /*lint -fallthrough*/
    17051 case 'b':
    17052 SCIPmessageFPrintInfo(messagehdlr, file, "%s_lhs: ", rowname);
    17053 break;
    17054 default:
    17055 assert(type == 'B');
    17056 SCIPmessageFPrintInfo(messagehdlr, file, "%s_rhs: ", rowname);
    17057 break;
    17058 }
    17059
    17060 /* print coefficients and variables */
    17061 for( j = 0; j < lp->rows[i]->nlpcols; ++j )
    17062 {
    17063 if( genericnames )
    17064 SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->lppos);
    17065 else
    17066 SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->var->name);
    17067
    17068 if( (j+1) % 10 == 0 )
    17069 SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
    17070 }
    17071
    17072 /* print right hand side */
    17073 switch( type )
    17074 {
    17075 case 'b':
    17076 SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
    17077 type = 'B';
    17078 goto WRITEROW;
    17079 case 'l':
    17080 SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
    17081 break;
    17082 case 'B':
    17083 case 'r':
    17084 SCIPmessageFPrintInfo(messagehdlr, file, " <= %.15g\n", lp->rows[i]->rhs - lp->rows[i]->constant);
    17085 break;
    17086 case 'e':
    17087 SCIPmessageFPrintInfo(messagehdlr, file, " = %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
    17088 break;
    17089 default:
    17090 SCIPerrorMessage("Undefined row type!\n");
    17091 fclose(file);
    17092 return SCIP_ERROR;
    17093 }
    17094 }
    17095
    17096 if ( lazyconss )
    17097 {
    17098 /* print lazy constraint section */
    17099 SCIPmessageFPrintInfo(messagehdlr, file, "lazy constraints\n");
    17100 for( i = 0; i < lp->nrows; i++ )
    17101 {
    17102 char type = 'i';
    17103
    17104 /* skip non-removable rows if we want to write lazy constraints */
    17105 if ( ! SCIProwIsRemovable(lp->rows[i]) )
    17106 continue;
    17107
    17108 /* constraint types: 'l' means: only lhs exists, 'r' means: only rhs exists, 'e' means: both sides exist and are
    17109 * equal, 'b' and 'B' mean: both sides exist, if the type is 'b', the lhs will be written, if the type is 'B',
    17110 * the rhs will be written. Ergo: set type to b first, change it to 'B' afterwards and go back to WRITEROW.
    17111 * type 'i' means: lhs and rhs are both infinite */
    17112 if( SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
    17113 type = 'r';
    17114 else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
    17115 type = 'l';
    17116 else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsEQ(set, lp->rows[i]->lhs, lp->rows[i]->rhs) )
    17117 type = 'e';
    17118 else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
    17119 type = 'b';
    17120
    17121 /* print name of row */
    17122 if( genericnames )
    17123 (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "row_%d", lp->rows[i]->lppos);
    17124 else
    17125 (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s", lp->rows[i]->name);
    17126
    17127 WRITELAZYROW:
    17128 switch( type )
    17129 {
    17130 case 'r':
    17131 case 'l':
    17132 case 'e':
    17133 if( strlen(rowname) > 0 )
    17134 SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", rowname);
    17135 break;
    17136 case 'i':
    17137 SCIPmessageFPrintInfo(messagehdlr, file, "\\\\ WARNING: The lhs and the rhs of the row with original name <%s>", lp->rows[i]->name);
    17138 SCIPmessageFPrintInfo(messagehdlr, file, "are not in a valid range. The following two constraints may be corrupted!\n");
    17139 SCIPmessagePrintWarning(messagehdlr, "The lhs and rhs of row <%s> are not in a valid range.\n",lp->rows[i]->name);
    17140 type = 'b';
    17141 /*lint -fallthrough*/
    17142 case 'b':
    17143 SCIPmessageFPrintInfo(messagehdlr, file, "%s_lhs: ", rowname);
    17144 break;
    17145 default:
    17146 assert(type == 'B');
    17147 SCIPmessageFPrintInfo(messagehdlr, file, "%s_rhs: ", rowname);
    17148 break;
    17149 }
    17150
    17151 /* print coefficients and variables */
    17152 for( j = 0; j < lp->rows[i]->nlpcols; ++j )
    17153 {
    17154 if( genericnames )
    17155 SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->lppos);
    17156 else
    17157 SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->var->name);
    17158
    17159 if( (j+1) % 10 == 0 )
    17160 SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
    17161 }
    17162
    17163 /* print right hand side */
    17164 switch( type )
    17165 {
    17166 case 'b':
    17167 SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
    17168 type = 'B';
    17169 goto WRITELAZYROW;
    17170 case 'l':
    17171 SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
    17172 break;
    17173 case 'B':
    17174 case 'r':
    17175 SCIPmessageFPrintInfo(messagehdlr, file, " <= %.15g\n", lp->rows[i]->rhs - lp->rows[i]->constant);
    17176 break;
    17177 case 'e':
    17178 SCIPmessageFPrintInfo(messagehdlr, file, " = %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
    17179 break;
    17180 default:
    17181 SCIPerrorMessage("Undefined row type!\n");
    17182 fclose(file);
    17183 return SCIP_ERROR;
    17184 }
    17185 }
    17186 }
    17187
    17188 /* print variable bounds */
    17189 SCIPmessageFPrintInfo(messagehdlr, file, "Bounds\n");
    17190 for( i = 0; i < lp->ncols; ++i )
    17191 {
    17192 if( !SCIPsetIsInfinity(set,-lp->cols[i]->lb) || !SCIPsetIsInfinity(set,lp->cols[i]->ub) )
    17193 {
    17194 /* print lower bound as far this one is not infinity */
    17195 if( !SCIPsetIsInfinity(set,-lp->cols[i]->lb) )
    17196 SCIPmessageFPrintInfo(messagehdlr, file, " %.15g <=", lp->cols[i]->lb);
    17197
    17198 /* print variable name */
    17199 if( genericnames )
    17200 SCIPmessageFPrintInfo(messagehdlr, file, " x_%d ", lp->cols[i]->lppos);
    17201 else
    17202 SCIPmessageFPrintInfo(messagehdlr, file, " %s ", lp->cols[i]->var->name);
    17203
    17204 /* print upper bound as far this one is not infinity */
    17205 if( !SCIPsetIsInfinity(set,lp->cols[i]->ub) )
    17206 SCIPmessageFPrintInfo(messagehdlr, file, "<= %.15g", lp->cols[i]->ub);
    17207 SCIPmessageFPrintInfo(messagehdlr, file, "\n");
    17208 }
    17209 }
    17210 if( origobj && objoffset != 0.0 )
    17211 SCIPmessageFPrintInfo(messagehdlr, file, " objoffset = 1\n");
    17212
    17213 /* print integer variables */
    17214 SCIPmessageFPrintInfo(messagehdlr, file, "Generals\n");
    17215 j = 0;
    17216 for( i = 0; i < lp->ncols; ++i )
    17217 {
    17218 if( SCIPvarIsIntegral(lp->cols[i]->var) )
    17219 {
    17220 /* print variable name */
    17221 if( genericnames )
    17222 SCIPmessageFPrintInfo(messagehdlr, file, " x_%d ", lp->cols[i]->lppos);
    17223 else
    17224 SCIPmessageFPrintInfo(messagehdlr, file, " %s ", lp->cols[i]->var->name);
    17225
    17226 j++;
    17227 if( j % 10 == 0 )
    17228 SCIPmessageFPrintInfo(messagehdlr, file, "\n");
    17229 }
    17230 }
    17231
    17232 SCIPmessageFPrintInfo(messagehdlr, file, "\nEnd");
    17233 fclose(file);
    17234
    17235 return SCIP_OKAY;
    17236}
    17237
    17238/*
    17239 * simple functions implemented as defines
    17240 */
    17241
    17242/* In debug mode, the following methods are implemented as function calls to ensure
    17243 * type validity.
    17244 * In optimized mode, the methods are implemented as defines to improve performance.
    17245 * However, we want to have them in the library anyways, so we have to undef the defines.
    17246 */
    17247
    17248#undef SCIPcolGetObj
    17249#undef SCIPcolGetLb
    17250#undef SCIPcolGetUb
    17251#undef SCIPcolGetBestBound
    17252#undef SCIPcolGetPrimsol
    17253#undef SCIPcolGetMinPrimsol
    17254#undef SCIPcolGetMaxPrimsol
    17255#undef SCIPcolGetBasisStatus
    17256#undef SCIPcolGetVar
    17257#undef SCIPcolGetIndex
    17258#undef SCIPcolGetVarProbindex
    17259#undef SCIPcolIsIntegral
    17260#undef SCIPcolIsRemovable
    17261#undef SCIPcolGetLPPos
    17262#undef SCIPcolGetLPDepth
    17263#undef SCIPcolIsInLP
    17264#undef SCIPcolGetNNonz
    17265#undef SCIPcolGetNLPNonz
    17266#undef SCIPcolGetRows
    17267#undef SCIPcolGetVals
    17268#undef SCIPcolGetStrongbranchNode
    17269#undef SCIPcolGetNStrongbranchs
    17270#undef SCIPcolGetAge
    17271#undef SCIPboundtypeOpposite
    17272#undef SCIProwGetNNonz
    17273#undef SCIProwGetNLPNonz
    17274#undef SCIProwGetCols
    17275#undef SCIProwGetVals
    17276#undef SCIProwGetConstant
    17277#undef SCIProwGetNorm
    17278#undef SCIProwGetSumNorm
    17279#undef SCIProwGetLhs
    17280#undef SCIProwGetRhs
    17281#undef SCIProwGetDualsol
    17282#undef SCIProwGetDualfarkas
    17283#undef SCIProwGetBasisStatus
    17284#undef SCIProwGetName
    17285#undef SCIProwGetIndex
    17286#undef SCIProwGetAge
    17287#undef SCIProwGetRank
    17288#undef SCIProwIsIntegral
    17289#undef SCIProwIsLocal
    17290#undef SCIProwIsModifiable
    17291#undef SCIProwIsRemovable
    17292#undef SCIProwGetOrigintype
    17293#undef SCIProwGetOriginCons
    17294#undef SCIProwGetOriginConshdlr
    17295#undef SCIProwGetOriginSepa
    17296#undef SCIProwIsInGlobalCutpool
    17297#undef SCIProwGetLPPos
    17298#undef SCIProwGetLPDepth
    17299#undef SCIProwIsInLP
    17300#undef SCIProwGetActiveLPCount
    17301#undef SCIProwGetNLPsAfterCreation
    17302#undef SCIProwChgRank
    17303#undef SCIProwGetRowExact
    17304#undef SCIPlpGetCols
    17305#undef SCIPlpGetNCols
    17306#undef SCIPlpGetRows
    17307#undef SCIPlpGetNRows
    17308#undef SCIPlpGetNewcols
    17309#undef SCIPlpGetNNewcols
    17310#undef SCIPlpGetNewrows
    17311#undef SCIPlpGetNNewrows
    17312#undef SCIPlpGetObjNorm
    17313#undef SCIPlpGetRootObjval
    17314#undef SCIPlpGetRootColumnObjval
    17315#undef SCIPlpGetRootLooseObjval
    17316#undef SCIPlpGetLPI
    17317#undef SCIPlpSetIsRelax
    17318#undef SCIPlpIsRelax
    17319#undef SCIPlpIsSolved
    17320#undef SCIPlpIsSolBasic
    17321#undef SCIPlpDiving
    17322#undef SCIPlpDivingObjChanged
    17323#undef SCIPlpMarkDivingObjChanged
    17324#undef SCIPlpUnmarkDivingObjChanged
    17325#undef SCIPlpDivingRowsChanged
    17326#undef SCIPlpIsFeasEQ
    17327#undef SCIPlpIsFeasLT
    17328#undef SCIPlpIsFeasLE
    17329#undef SCIPlpIsFeasGT
    17330#undef SCIPlpIsFeasGE
    17331#undef SCIPlpIsFeasZero
    17332#undef SCIPlpIsFeasPositive
    17333#undef SCIPlpIsFeasNegative
    17334
    17335/** gets objective value of column */
    17337 SCIP_COL* col /**< LP column */
    17338 )
    17339{
    17340 assert(col != NULL);
    17341
    17342 return col->obj;
    17343}
    17344
    17345/** gets lower bound of column */
    17347 SCIP_COL* col /**< LP column */
    17348 )
    17349{
    17350 assert(col != NULL);
    17351
    17352 return col->lb;
    17353}
    17354
    17355/** gets upper bound of column */
    17357 SCIP_COL* col /**< LP column */
    17358 )
    17359{
    17360 assert(col != NULL);
    17361
    17362 return col->ub;
    17363}
    17364
    17365/** gets best bound of column with respect to the objective function */
    17367 SCIP_COL* col /**< LP column */
    17368 )
    17369{
    17370 assert(col != NULL);
    17371
    17372 if( col->obj >= 0.0 )
    17373 return col->lb;
    17374 else
    17375 return col->ub;
    17376}
    17377
    17378/** gets the primal LP solution of a column */
    17380 SCIP_COL* col /**< LP column */
    17381 )
    17382{
    17383 assert(col != NULL);
    17384
    17385 if( col->lppos >= 0 )
    17386 return col->primsol;
    17387 else
    17388 return 0.0;
    17389}
    17390
    17391/** gets the minimal LP solution value, this column ever assumed */
    17393 SCIP_COL* col /**< LP column */
    17394 )
    17395{
    17396 assert(col != NULL);
    17397
    17398 return col->minprimsol;
    17399}
    17400
    17401/** gets the maximal LP solution value, this column ever assumed */
    17403 SCIP_COL* col /**< LP column */
    17404 )
    17405{
    17406 assert(col != NULL);
    17407
    17408 return col->maxprimsol;
    17409}
    17410
    17411/** gets the basis status of a column in the LP solution; only valid for LPs with status SCIP_LPSOLSTAT_OPTIMAL
    17412 * and with SCIPisLPSolBasic(scip) == TRUE; returns SCIP_BASESTAT_ZERO for columns not in the current SCIP_LP
    17413 */
    17415 SCIP_COL* col /**< LP column */
    17416 )
    17417{
    17418 assert(col != NULL);
    17419 assert(col->lppos >= 0 || (SCIP_BASESTAT)col->basisstatus == SCIP_BASESTAT_ZERO);
    17420
    17421 return (SCIP_BASESTAT)col->basisstatus;
    17422}
    17423
    17424/** gets variable this column represents */
    17426 SCIP_COL* col /**< LP column */
    17427 )
    17428{
    17429 assert(col != NULL);
    17430
    17431 return col->var;
    17432}
    17433
    17434/** gets unique index of col */
    17436 SCIP_COL* col /**< LP col */
    17437 )
    17438{
    17439 assert(col != NULL);
    17440
    17441 return col->index;
    17442}
    17443
    17444/** gets probindex of corresponding variable */
    17446 SCIP_COL* col /**< LP col */
    17447 )
    17448{
    17449 assert(col != NULL);
    17450
    17451 return col->var_probindex;
    17452}
    17453
    17454/** returns whether the associated variable is of integral type (binary, integer, or implied integral) */
    17456 SCIP_COL* col /**< LP column */
    17457 )
    17458{
    17459 assert(col != NULL);
    17460 assert(SCIPvarIsIntegral(col->var) == col->integral);
    17461
    17462 return col->integral;
    17463}
    17464
    17465/** returns whether the associated variable is implied integral */
    17467 SCIP_COL* col /**< LP column */
    17468 )
    17469{
    17470 assert(col != NULL);
    17471 assert(SCIPvarIsImpliedIntegral(col->var) == col->impliedintegral);
    17472
    17473 return col->impliedintegral;
    17474}
    17475
    17476/** returns TRUE iff column is removable from the LP (due to aging or cleanup) */
    17478 SCIP_COL* col /**< LP column */
    17479 )
    17480{
    17481 assert(col != NULL);
    17482
    17483 return col->removable;
    17484}
    17485
    17486/** gets position of column in current LP, or -1 if it is not in LP */
    17488 SCIP_COL* col /**< LP column */
    17489 )
    17490{
    17491 assert(col != NULL);
    17492 assert((col->lppos == -1) == (col->lpdepth == -1));
    17493
    17494 return col->lppos;
    17495}
    17496
    17497/** gets depth in the tree where the column entered the LP, or -1 if it is not in LP */
    17499 SCIP_COL* col /**< LP column */
    17500 )
    17501{
    17502 assert(col != NULL);
    17503 assert((col->lppos == -1) == (col->lpdepth == -1));
    17504
    17505 return col->lpdepth;
    17506}
    17507
    17508/** returns TRUE iff column is member of current LP */
    17510 SCIP_COL* col /**< LP column */
    17511 )
    17512{
    17513 assert(col != NULL);
    17514 assert((col->lppos == -1) == (col->lpdepth == -1));
    17515
    17516 return (col->lppos >= 0);
    17517}
    17518
    17519/** get number of nonzero entries in column vector */
    17521 SCIP_COL* col /**< LP column */
    17522 )
    17523{
    17524 assert(col != NULL);
    17525
    17526 return col->len;
    17527}
    17528
    17529/** get number of nonzero entries in column vector, that correspond to rows currently in the SCIP_LP;
    17530 *
    17531 * @warning This method is only applicable on columns, that are completely linked to their rows (e.g. a column
    17532 * that is in the current LP and the LP was solved, or a column that was in a solved LP and didn't change afterwards
    17533 */
    17535 SCIP_COL* col /**< LP column */
    17536 )
    17537{
    17538 assert(col != NULL);
    17539 assert(col->nunlinked == 0);
    17540
    17541 return col->nlprows;
    17542}
    17543
    17544/** gets array with rows of nonzero entries */
    17546 SCIP_COL* col /**< LP column */
    17547 )
    17548{
    17549 assert(col != NULL);
    17550
    17551 return col->rows;
    17552}
    17553
    17554/** gets array with coefficients of nonzero entries */
    17556 SCIP_COL* col /**< LP column */
    17557 )
    17558{
    17559 assert(col != NULL);
    17560
    17561 return col->vals;
    17562}
    17563
    17564/** gets node number of the last node in current branch and bound run, where strong branching was used on the
    17565 * given column, or -1 if strong branching was never applied to the column in current run
    17566 */
    17568 SCIP_COL* col /**< LP column */
    17569 )
    17570{
    17571 assert(col != NULL);
    17572
    17573 return col->sbnode;
    17574}
    17575
    17576/** gets number of times, strong branching was applied in current run on the given column */
    17578 SCIP_COL* col /**< LP column */
    17579 )
    17580{
    17581 assert(col != NULL);
    17582
    17583 return col->nsbcalls;
    17584}
    17585
    17586/** gets the age of a column, i.e., the total number of successive times a column was in the LP and was 0.0 in the solution */
    17588 SCIP_COL* col /**< LP column */
    17589 )
    17590{
    17591 assert(col != NULL);
    17592
    17593 return col->age;
    17594}
    17595
    17596/** gets opposite bound type of given bound type */
    17598 SCIP_BOUNDTYPE boundtype /**< type of bound (lower or upper) */
    17599 )
    17600{
    17601 assert(boundtype == SCIP_BOUNDTYPE_LOWER || boundtype == SCIP_BOUNDTYPE_UPPER);
    17602
    17604}
    17605
    17606/** get number of nonzero entries in row vector */
    17608 SCIP_ROW* row /**< LP row */
    17609 )
    17610{
    17611 assert(row != NULL);
    17612
    17613 return row->len;
    17614}
    17615
    17616/** get number of nonzero entries in row vector, that correspond to columns currently in the SCIP_LP;
    17617 *
    17618 * @warning This method is only applicable on rows, that are completely linked to their columns (e.g. a row
    17619 * that is in the current LP and the LP was solved, or a row that was in a solved LP and didn't change afterwards
    17620 */
    17622 SCIP_ROW* row /**< LP row */
    17623 )
    17624{
    17625 assert(row != NULL);
    17626 assert(row->nunlinked == 0);
    17627
    17628 return row->nlpcols;
    17629}
    17630
    17631/** gets array with columns of nonzero entries */
    17633 SCIP_ROW* row /**< LP row */
    17634 )
    17635{
    17636 assert(row != NULL);
    17637
    17638 return row->cols;
    17639}
    17640
    17641/** gets array with coefficients of nonzero entries */
    17643 SCIP_ROW* row /**< LP row */
    17644 )
    17645{
    17646 assert(row != NULL);
    17647
    17648 return row->vals;
    17649}
    17650
    17651/** gets constant shift of row */
    17653 SCIP_ROW* row /**< LP row */
    17654 )
    17655{
    17656 assert(row != NULL);
    17657
    17658 return row->constant;
    17659}
    17660
    17661/** gets Euclidean norm of row vector */
    17663 SCIP_ROW* row /**< LP row */
    17664 )
    17665{
    17666 assert(row != NULL);
    17667
    17668 checkRowSqrnorm(row);
    17669
    17670 return sqrt(row->sqrnorm);
    17671}
    17672
    17673/** gets sum norm of row vector (sum of absolute values of coefficients) */
    17675 SCIP_ROW* row /**< LP row */
    17676 )
    17677{
    17678 assert(row != NULL);
    17679
    17680 checkRowSumnorm(row);
    17681
    17682 return row->sumnorm;
    17683}
    17684
    17685/** returns the left hand side of the row */
    17687 SCIP_ROW* row /**< LP row */
    17688 )
    17689{
    17690 assert(row != NULL);
    17691
    17692 return row->lhs;
    17693}
    17694
    17695/** returns the right hand side of the row */
    17697 SCIP_ROW* row /**< LP row */
    17698 )
    17699{
    17700 assert(row != NULL);
    17701
    17702 return row->rhs;
    17703}
    17704
    17705/** gets the dual LP solution of a row */
    17707 SCIP_ROW* row /**< LP row */
    17708 )
    17709{
    17710 assert(row != NULL);
    17711
    17712 if( row->lppos >= 0 )
    17713 return row->dualsol;
    17714 else
    17715 return 0.0;
    17716}
    17717
    17718/** gets the dual Farkas coefficient of a row in an infeasible LP */
    17720 SCIP_ROW* row /**< LP row */
    17721 )
    17722{
    17723 assert(row != NULL);
    17724
    17725 if( row->lppos >= 0 )
    17726 return row->dualfarkas;
    17727 else
    17728 return 0.0;
    17729}
    17730
    17731/** gets the basis status of a row in the LP solution; only valid for LPs with status SCIP_LPSOLSTAT_OPTIMAL
    17732 * and with SCIPisLPSolBasic(scip) == TRUE; returns SCIP_BASESTAT_BASIC for rows not in the current SCIP_LP
    17733 */
    17735 SCIP_ROW* row /**< LP row */
    17736 )
    17737{
    17738 assert(row != NULL);
    17739 assert(row->lppos >= 0 || (SCIP_BASESTAT)row->basisstatus == SCIP_BASESTAT_BASIC);
    17740
    17741 return (SCIP_BASESTAT)row->basisstatus;
    17742}
    17743
    17744/** returns the name of the row */
    17745const char* SCIProwGetName(
    17746 SCIP_ROW* row /**< LP row */
    17747 )
    17748{
    17749 assert(row != NULL);
    17750
    17751 return row->name;
    17752}
    17753
    17754/** gets unique index of row */
    17756 SCIP_ROW* row /**< LP row */
    17757 )
    17758{
    17759 assert(row != NULL);
    17760
    17761 return row->index;
    17762}
    17763
    17764/** gets age of row */
    17766 SCIP_ROW* row /**< LP row */
    17767 )
    17768{
    17769 assert(row != NULL);
    17770
    17771 return row->age;
    17772}
    17773
    17774/** gets rank of row */
    17776 SCIP_ROW* row /**< LP row */
    17777 )
    17778{
    17779 assert(row != NULL);
    17780
    17781 return row->rank;
    17782}
    17783
    17784/** returns TRUE if the activity of the row (without the row's constant) is integral for an optimal solution */
    17786 SCIP_ROW* row /**< LP row */
    17787 )
    17788{
    17789 assert(row != NULL);
    17790
    17791 return row->integral;
    17792}
    17793
    17794/** returns TRUE iff row is only valid locally */
    17796 SCIP_ROW* row /**< LP row */
    17797 )
    17798{
    17799 assert(row != NULL);
    17800
    17801 return row->local;
    17802}
    17803
    17804/** returns TRUE iff row is modifiable during node processing (subject to column generation) */
    17806 SCIP_ROW* row /**< LP row */
    17807 )
    17808{
    17809 assert(row != NULL);
    17810
    17811 return row->modifiable;
    17812}
    17813
    17814/** returns TRUE iff row is removable from the LP (due to aging or cleanup) */
    17816 SCIP_ROW* row /**< LP row */
    17817 )
    17818{
    17819 assert(row != NULL);
    17820
    17821 return row->removable;
    17822}
    17823
    17824/** returns type of origin that created the row */
    17826 SCIP_ROW* row /**< LP row */
    17827 )
    17828{
    17829 assert( row != NULL );
    17830
    17831 return (SCIP_ROWORIGINTYPE) row->origintype;
    17832}
    17833
    17834/** returns origin constraint that created the row (NULL if not available) */
    17836 SCIP_ROW* row /**< LP row */
    17837 )
    17838{
    17839 assert( row != NULL );
    17840
    17842 {
    17843 assert( row->origin != NULL );
    17844 return (SCIP_CONS*) row->origin;
    17845 }
    17846 return NULL;
    17847}
    17848
    17849/** returns origin constraint handler that created the row (NULL if not available) */
    17851 SCIP_ROW* row /**< LP row */
    17852 )
    17853{
    17854 assert( row != NULL );
    17855
    17857 {
    17858 assert( row->origin != NULL );
    17859 return (SCIP_CONSHDLR*) row->origin;
    17860 }
    17862 {
    17863 assert(row->origin != NULL);
    17864 return SCIPconsGetHdlr((SCIP_CONS*)row->origin);
    17865 }
    17866 return NULL;
    17867}
    17868
    17869/** returns origin separator that created the row (NULL if not available) */
    17871 SCIP_ROW* row /**< LP row */
    17872 )
    17873{
    17874 assert( row != NULL );
    17875
    17877 {
    17878 assert( row->origin != NULL );
    17879 return (SCIP_SEPA*) row->origin;
    17880 }
    17881 return NULL;
    17882}
    17883
    17884/** returns TRUE iff row is member of the global cut pool */
    17886 SCIP_ROW* row /**< LP row */
    17887 )
    17888{
    17889 assert(row != NULL);
    17890
    17891 return row->inglobalcutpool;
    17892}
    17893
    17894/** gets position of row in current LP, or -1 if it is not in LP */
    17896 SCIP_ROW* row /**< LP row */
    17897 )
    17898{
    17899 assert(row != NULL);
    17900 assert((row->lppos == -1) == (row->lpdepth == -1));
    17901
    17902 return row->lppos;
    17903}
    17904
    17905/** gets depth in the tree where the row entered the LP, or -1 if it is not in LP */
    17907 SCIP_ROW* row /**< LP row */
    17908 )
    17909{
    17910 assert(row != NULL);
    17911 assert((row->lppos == -1) == (row->lpdepth == -1));
    17912
    17913 return row->lpdepth;
    17914}
    17915
    17916/** returns TRUE iff row is member of current LP */
    17918 SCIP_ROW* row /**< LP row */
    17919 )
    17920{
    17921 assert(row != NULL);
    17922 assert((row->lppos == -1) == (row->lpdepth == -1));
    17923
    17924 return (row->lppos >= 0);
    17925}
    17926
    17927/** changes the rank of LP row */
    17929 SCIP_ROW* row, /**< LP row */
    17930 int rank /**< new value for rank */
    17931 )
    17932{
    17933 assert(row != NULL);
    17934
    17935 row->rank = rank;
    17936}
    17937
    17938/** returns the number of times that this row has been sharp in an optimal LP solution */
    17940 SCIP_ROW* row /**< row */
    17941 )
    17942{
    17943 assert(row != NULL);
    17944
    17945 return row->activeinlpcounter;
    17946}
    17947
    17948/** returns the number of LPs since this row has been created */
    17950 SCIP_ROW* row /**< row */
    17951 )
    17952{
    17953 assert(row != NULL);
    17954
    17955 return row->nlpsaftercreation;
    17956}
    17957
    17958/** returns exact row corresponding to fprow, if it exists. Otherwise returns NULL */
    17960 SCIP_ROW* row /**< SCIP row */
    17961 )
    17962{
    17963 assert(row != NULL);
    17964
    17965 return row->rowexact;
    17966}
    17967
    17968/** gets array with columns of the LP */
    17970 SCIP_LP* lp /**< current LP data */
    17971 )
    17972{
    17973 assert(lp != NULL);
    17974
    17975 return lp->cols;
    17976}
    17977
    17978/** gets current number of columns in LP */
    17980 SCIP_LP* lp /**< current LP data */
    17981 )
    17982{
    17983 assert(lp != NULL);
    17984
    17985 return lp->ncols;
    17986}
    17987
    17988/** gets current number of unfixed columns in LP */
    17990 SCIP_LP* lp, /**< current LP data */
    17991 SCIP_Real eps /**< numerical tolerance */
    17992 )
    17993{
    17994 SCIP_COL** lpcols;
    17995 int nlpcols;
    17996 int nunfixedcols;
    17997 int c;
    17998
    17999 assert(lp != NULL);
    18000 assert(eps > 0.0);
    18001
    18002 lpcols = lp->cols;
    18003 nlpcols = lp->ncols;
    18004
    18005 nunfixedcols = 0;
    18006 for( c = 0; c < nlpcols; ++c )
    18007 {
    18008 if( lpcols[c]->ub - lpcols[c]->lb > eps )
    18009 ++nunfixedcols;
    18010 }
    18011
    18012 return nunfixedcols;
    18013}
    18014
    18015/** gets array with rows of the LP */
    18017 SCIP_LP* lp /**< current LP data */
    18018 )
    18019{
    18020 assert(lp != NULL);
    18021
    18022 return lp->rows;
    18023}
    18024
    18025/** gets current number of rows in LP */
    18027 SCIP_LP* lp /**< current LP data */
    18028 )
    18029{
    18030 assert(lp != NULL);
    18031
    18032 return lp->nrows;
    18033}
    18034
    18035/** gets array with newly added columns after the last mark */
    18037 SCIP_LP* lp /**< current LP data */
    18038 )
    18039{
    18040 assert(lp != NULL);
    18041 assert(0 <= lp->firstnewcol && lp->firstnewcol <= lp->ncols);
    18042
    18043 return &(lp->cols[lp->firstnewcol]);
    18044}
    18045
    18046/** gets number of newly added columns after the last mark */
    18048 SCIP_LP* lp /**< current LP data */
    18049 )
    18050{
    18051 assert(lp != NULL);
    18052 assert(0 <= lp->firstnewcol && lp->firstnewcol <= lp->ncols);
    18053
    18054 return lp->ncols - lp->firstnewcol;
    18055}
    18056
    18057/** gets array with newly added rows after the last mark */
    18059 SCIP_LP* lp /**< current LP data */
    18060 )
    18061{
    18062 assert(lp != NULL);
    18063 assert(0 <= lp->firstnewrow && lp->firstnewrow <= lp->nrows);
    18064
    18065 return &(lp->rows[lp->firstnewrow]);
    18066}
    18067
    18068/** gets number of newly added rows after the last mark */
    18070 SCIP_LP* lp /**< current LP data */
    18071 )
    18072{
    18073 assert(lp != NULL);
    18074 assert(0 <= lp->firstnewrow && lp->firstnewrow <= lp->nrows);
    18075
    18076 return lp->nrows - lp->firstnewrow;
    18077}
    18078
    18079/** recalculates Euclidean norm of objective function vector of column variables if it have gotten unreliable during calculation */
    18081 SCIP_SET* set, /**< global SCIP settings */
    18082 SCIP_LP* lp /**< LP data */
    18083 )
    18084{
    18085 if( lp->objsqrnormunreliable )
    18086 {
    18087 SCIP_COL** cols;
    18088 int c;
    18089
    18090 cols = lp->cols;
    18091 assert(cols != NULL || lp->ncols == 0);
    18092
    18093 lp->objsqrnorm = 0.0;
    18094
    18095 for( c = lp->ncols - 1; c >= 0; --c )
    18096 {
    18097 lp->objsqrnorm += SQR(cols[c]->unchangedobj); /*lint !e613*/
    18098 }
    18099 assert(SCIPsetIsGE(set, lp->objsqrnorm, 0.0));
    18100
    18101 /* due to numerical troubles it still can appear that lp->objsqrnorm is a little bit smaller than 0 */
    18102 lp->objsqrnorm = MAX(lp->objsqrnorm, 0.0);
    18103
    18105 }
    18106 return;
    18107}
    18108
    18109/** gets Euclidean norm of objective function vector of column variables, only use this method if
    18110 * lp->objsqrnormunreliable == FALSE, so probably you have to call SCIPlpRecalculateObjSqrNorm before */
    18112 SCIP_LP* lp /**< LP data */
    18113 )
    18114{
    18115 assert(lp != NULL);
    18116 assert(!lp->objsqrnormunreliable);
    18117 assert(lp->objsqrnorm >= 0.0);
    18118
    18119 return sqrt(lp->objsqrnorm);
    18120}
    18121
    18122/** sets whether the root lp is a relaxation of the problem and its optimal objective value is a global lower bound */
    18124 SCIP_LP* lp, /**< LP data */
    18125 SCIP_Bool isrelax /**< is the root lp a relaxation of the problem? */
    18126 )
    18127{
    18128 assert(lp != NULL);
    18129
    18130 lp->rootlpisrelax = isrelax;
    18131}
    18132
    18133/** returns whether the root lp is a relaxation of the problem and its optimal objective value is a global lower bound */
    18135 SCIP_LP* lp /**< LP data */
    18136 )
    18137{
    18138 assert(lp != NULL);
    18139
    18140 return lp->rootlpisrelax;
    18141}
    18142
    18143/** gets the objective value of the root node LP; returns SCIP_INVALID if the root node LP was not (yet) solved */
    18145 SCIP_LP* lp /**< LP data */
    18146 )
    18147{
    18148 assert(lp != NULL);
    18149
    18150 return MIN(lp->rootlpobjval + lp->rootlooseobjval, SCIP_INVALID);
    18151}
    18152
    18153/** gets part of the objective value of the root node LP that results from COLUMN variables only;
    18154 * returns SCIP_INVALID if the root node LP was not (yet) solved
    18155 */
    18157 SCIP_LP* lp /**< LP data */
    18158 )
    18159{
    18160 assert(lp != NULL);
    18161
    18162 return lp->rootlpobjval;
    18163}
    18164
    18165/** gets part of the objective value of the root node LP that results from LOOSE variables only;
    18166 * returns SCIP_INVALID if the root node LP was not (yet) solved
    18167 */
    18169 SCIP_LP* lp /**< LP data */
    18170 )
    18171{
    18172 assert(lp != NULL);
    18173
    18174 return lp->rootlooseobjval;
    18175}
    18176
    18177/** gets the LP solver interface */
    18179 SCIP_LP* lp /**< current LP data */
    18180 )
    18181{
    18182 assert(lp != NULL);
    18183
    18184 return lp->lpi;
    18185}
    18186
    18187/** sets whether the current LP is a relaxation of the current problem and its optimal objective value is a local lower bound */
    18189 SCIP_LP* lp, /**< LP data */
    18190 SCIP_Bool relax /**< is the current lp a relaxation? */
    18191 )
    18192{
    18193 assert(lp != NULL);
    18194
    18195 lp->isrelax = relax;
    18196}
    18197
    18198/** returns whether the current LP is a relaxation of the problem for which it has been solved and its
    18199 * solution value a valid local lower bound?
    18200 */
    18202 SCIP_LP* lp /**< LP data */
    18203 )
    18204{
    18205 assert(lp != NULL);
    18206
    18207 return lp->isrelax;
    18208}
    18209
    18210/** returns whether the current LP is flushed and solved */
    18212 SCIP_LP* lp /**< current LP data */
    18213 )
    18214{
    18215 assert(lp != NULL);
    18216
    18217 return lp->flushed && lp->solved;
    18218}
    18219
    18220/** return whether the current LP solution passed the primal feasibility check */
    18222 SCIP_LP* lp /**< current LP data */
    18223 )
    18224{
    18225 assert(lp != NULL);
    18226
    18227 return (lp->primalchecked && lp->primalfeasible);
    18228}
    18229
    18230/** return whether the current LP solution passed the dual feasibility check */
    18232 SCIP_LP* lp /**< current LP data */
    18233 )
    18234{
    18235 assert(lp != NULL);
    18236
    18237 return (lp->dualchecked && lp->dualfeasible);
    18238}
    18239
    18240/** returns whether the current LP solution is a basic solution */
    18242 SCIP_LP* lp /**< current LP data */
    18243 )
    18244{
    18245 assert(lp != NULL);
    18246
    18247 return lp->solisbasic;
    18248}
    18249
    18250/** returns whether the LP is in diving mode */
    18252 SCIP_LP* lp /**< current LP data */
    18253 )
    18254{
    18255 assert(lp != NULL);
    18256
    18257 return lp->diving;
    18258}
    18259
    18260/** returns whether the LP is in diving mode and the objective value of at least one column was changed */
    18262 SCIP_LP* lp /**< current LP data */
    18263 )
    18264{
    18265 assert(lp != NULL);
    18266
    18267 return lp->divingobjchg;
    18268}
    18269
    18270/** marks the diving LP to have a changed objective function */
    18272 SCIP_LP* lp /**< current LP data */
    18273 )
    18274{
    18275 assert(lp != NULL);
    18276 assert(lp->diving || lp->probing);
    18277
    18278 lp->divingobjchg = TRUE;
    18279}
    18280
    18281/** marks the diving LP to not have a changed objective function anymore */
    18283 SCIP_LP* lp /**< current LP data */
    18284 )
    18285{
    18286 assert(lp != NULL);
    18287 assert(lp->diving || lp->probing);
    18288
    18289 lp->divingobjchg = FALSE;
    18290}
    18291
    18292/* returns TRUE if at least one left/right hand side of an LP row was changed during diving mode */
    18294 SCIP_LP* lp /**< current LP data */
    18295 )
    18296{
    18297 assert(lp != NULL);
    18298 assert(lp->diving || lp->ndivechgsides == 0);
    18299
    18300 return (lp->ndivechgsides > 0);
    18301}
    18302
    18303/** compute relative interior point with auxiliary lpi, see SCIPlpComputeRelIntPoint() */
    18304static
    18306 SCIP_LPI* lpi, /**< auxiliary LP interface */
    18307 SCIP_SET* set, /**< global SCIP settings */
    18308 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    18309 SCIP_LP* lp, /**< LP data */
    18310 SCIP_PROB* prob, /**< problem data */
    18311 SCIP_Bool relaxrows, /**< should the rows be relaxed */
    18312 SCIP_Bool inclobjcutoff, /**< should a row for the objective cutoff be included */
    18313 SCIP_Real timelimit, /**< time limit for LP solver */
    18314 int iterlimit, /**< iteration limit for LP solver */
    18315 SCIP_Real* point, /**< array to store relative interior point on exit */
    18316 SCIP_Bool* success /**< buffer to indicate whether interior point was successfully computed */
    18317 )
    18318{
    18319 SCIP_RETCODE retcode;
    18320 SCIP_Real* primal;
    18321 SCIP_Real* obj;
    18322 SCIP_Real* lb;
    18323 SCIP_Real* ub;
    18324 SCIP_Real* matvals;
    18325 SCIP_Real* matlhs;
    18326 SCIP_Real* matrhs;
    18327 SCIP_Real objval;
    18328 SCIP_Real alpha;
    18329 int* matinds;
    18330 int* matbeg;
    18331#ifndef NDEBUG
    18332 int nslacks;
    18333#endif
    18334 int nnewcols;
    18335 int ntotnonz = 0;
    18336 int ntotrows = 0;
    18337 int matrowidx;
    18338 int matidx;
    18339 int cnt;
    18340 int j;
    18341 int i;
    18342
    18343 assert(lpi != NULL);
    18344
    18345 retcode = SCIPlpiSetRealpar(lpi, SCIP_LPPAR_FEASTOL, lp->feastol);
    18346 if( retcode != SCIP_OKAY )
    18347 {
    18348 /* stop execution on error, since result is likely to be unsuable */
    18349 SCIPmessagePrintWarning(messagehdlr, "Could not set feasibility tolerance of LP solver for relative interior point computation.\n");
    18350 return SCIP_LPERROR;
    18351 }
    18352
    18354 if( retcode != SCIP_OKAY )
    18355 {
    18356 /* stop execution on error, since result is likely to be unsuable */
    18357 SCIPmessagePrintWarning(messagehdlr, "Could not set dual feasibility tolerance of LP solver for relative interior point computation.\n");
    18358 return SCIP_LPERROR;
    18359 }
    18360
    18361 /* get storage */
    18362 nnewcols = 3*lp->ncols + 2*lp->nrows + (inclobjcutoff ? 1 : 0) + 1;
    18363 SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, nnewcols) );
    18364 SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, nnewcols) );
    18365 SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, nnewcols) );
    18366
    18367 /* create original columns (bounds are relaxed below, unless the variable is fixed) */
    18368 for( j = 0; j < lp->ncols; ++j )
    18369 {
    18370 /* note: if the variable is fixed we cannot simply fix the variables (because alpha scales the problem) */
    18371 obj[j] = 0.0;
    18372 lb[j] = -SCIPlpiInfinity(lpi);
    18373 ub[j] = SCIPlpiInfinity(lpi);
    18374 /* note: we could also use the original bounds - free variables seem to be faster. */
    18375 }
    18376
    18377 /* add artificial alpha variable */
    18378 nnewcols = lp->ncols;
    18379 obj[nnewcols] = 0.0;
    18380 lb[nnewcols] = 1.0;
    18381 ub[nnewcols] = SCIPlpiInfinity(lpi);
    18382 ++nnewcols;
    18383
    18384 /* create slacks for rows */
    18385 for( i = 0; i < lp->nrows; ++i )
    18386 {
    18387 SCIP_ROW* row;
    18388
    18389 row = lp->rows[i];
    18390 assert( row != NULL );
    18391
    18392 if( SCIProwIsModifiable(row) )
    18393 continue;
    18394
    18395 /* make sure row is sorted */
    18396 rowSortLP(row);
    18397 assert( row->lpcolssorted );
    18398
    18399 /* check whether we have an equation */
    18400 if( SCIPsetIsEQ(set, row->lhs, row->rhs) )
    18401 {
    18402 assert( !SCIPsetIsInfinity(set, REALABS(row->lhs)) );
    18403 assert( !SCIPsetIsInfinity(set, REALABS(row->rhs)) );
    18404 ntotnonz += row->nlpcols + 1;
    18405 ++ntotrows;
    18406 }
    18407 else
    18408 {
    18409 /* otherwise add slacks for each side if necessary */
    18410 if ( ! SCIPsetIsInfinity(set, REALABS(row->lhs)) )
    18411 {
    18412 if ( relaxrows )
    18413 {
    18414 lb[nnewcols] = 0.0;
    18415 ub[nnewcols] = 1.0;
    18416 obj[nnewcols++] = 1.0;
    18417 ntotnonz += row->nlpcols + 2;
    18418 }
    18419 else
    18420 ntotnonz += row->nlpcols + 1;
    18421 ++ntotrows;
    18422 }
    18423 if ( ! SCIPsetIsInfinity(set, REALABS(row->rhs)) )
    18424 {
    18425 if ( relaxrows )
    18426 {
    18427 lb[nnewcols] = 0.0;
    18428 ub[nnewcols] = 1.0;
    18429 obj[nnewcols++] = 1.0;
    18430 ntotnonz += row->nlpcols + 2;
    18431 }
    18432 else
    18433 ntotnonz += row->nlpcols + 1;
    18434 ++ntotrows;
    18435 }
    18436 }
    18437 }
    18438
    18439 /* create slacks for objective cutoff row */
    18440 if( inclobjcutoff && relaxrows )
    18441 {
    18442 /* add slacks for right hand side */
    18443 lb[nnewcols] = 0.0;
    18444 ub[nnewcols] = 1.0;
    18445 obj[nnewcols++] = 1.0;
    18446 ntotnonz += lp->ncols + 2;
    18447 ++ntotrows;
    18448 }
    18449
    18450 /* create slacks for bounds */
    18451 for( j = 0; j < lp->ncols; ++j )
    18452 {
    18453 SCIP_COL* col;
    18454
    18455 col = lp->cols[j];
    18456 assert( col != NULL );
    18457
    18458 /* no slacks for fixed variables */
    18459 if( SCIPsetIsEQ(set, col->lb, col->ub) )
    18460 {
    18461 ++ntotrows;
    18462 ntotnonz += 2;
    18463 }
    18464 else
    18465 {
    18466 /* add slacks for each bound if necessary */
    18467 if ( ! SCIPsetIsInfinity(set, REALABS(col->lb)) )
    18468 {
    18469 lb[nnewcols] = 0.0;
    18470 ub[nnewcols] = 1.0;
    18471 obj[nnewcols++] = 1.0;
    18472 ntotnonz += 3;
    18473 ++ntotrows;
    18474 }
    18475 if( ! SCIPsetIsInfinity(set, REALABS(col->ub)) )
    18476 {
    18477 lb[nnewcols] = 0.0;
    18478 ub[nnewcols] = 1.0;
    18479 obj[nnewcols++] = 1.0;
    18480 ntotnonz += 3;
    18481 ++ntotrows;
    18482 }
    18483 }
    18484 }
    18485#ifndef NDEBUG
    18486 nslacks = nnewcols - lp->ncols - 1;
    18487 assert( nslacks >= 0 );
    18488 assert( nnewcols <= 3*lp->ncols + 2*lp->nrows + (inclobjcutoff ? 1 : 0) + 1 );
    18489#endif
    18490
    18491 /* add columns */
    18492 SCIP_CALL( SCIPlpiAddCols(lpi, nnewcols, obj, lb, ub, NULL, 0, NULL, NULL, NULL) );
    18493
    18494 /* free storage */
    18498
    18499 /* prepare storage for rows */
    18500 SCIP_CALL( SCIPsetAllocBufferArray(set, &matinds, ntotnonz) );
    18501 SCIP_CALL( SCIPsetAllocBufferArray(set, &matvals, ntotnonz) );
    18502 SCIP_CALL( SCIPsetAllocBufferArray(set, &matbeg, ntotrows) );
    18503 SCIP_CALL( SCIPsetAllocBufferArray(set, &matlhs, ntotrows) );
    18504 SCIP_CALL( SCIPsetAllocBufferArray(set, &matrhs, ntotrows) );
    18505
    18506 /* create rows arising from original rows */
    18507 cnt = 0;
    18508 matrowidx = 0;
    18509 matidx = 0;
    18510 for( i = 0; i < lp->nrows; ++i )
    18511 {
    18512 SCIP_ROW* row;
    18513 SCIP_COL** rowcols;
    18514 SCIP_Real* rowvals;
    18515 SCIP_Real lhs;
    18516 SCIP_Real rhs;
    18517 int nnonz;
    18518
    18519 row = lp->rows[i];
    18520 assert( row != NULL );
    18521
    18522 if( SCIProwIsModifiable(row) )
    18523 continue;
    18524 assert( row->lpcolssorted );
    18525
    18526 /* get row data */
    18527 lhs = row->lhs - (SCIPsetIsInfinity(set, -row->lhs) ? 0.0 : row->constant);
    18528 rhs = row->rhs - (SCIPsetIsInfinity(set, row->rhs) ? 0.0 : row->constant);
    18529 nnonz = row->nlpcols;
    18530 assert( nnonz <= lp->ncols );
    18531 rowcols = row->cols;
    18532 rowvals = row->vals;
    18533
    18534 /* if we have an equation */
    18535 if( SCIPsetIsEQ(set, lhs, rhs) )
    18536 {
    18537 /* set up indices */
    18538 matbeg[matrowidx] = matidx;
    18539 for( j = 0; j < nnonz; ++j )
    18540 {
    18541 assert( rowcols[j] != NULL );
    18542 assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
    18543 assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
    18544 assert( ! SCIPsetIsZero(set, rowvals[j]) );
    18545 matinds[matidx] = rowcols[j]->lppos;
    18546 matvals[matidx++] = rowvals[j];
    18547 assert( matidx <= ntotnonz );
    18548 }
    18549
    18550 /* add artificial variable */
    18551 if ( ! SCIPsetIsZero(set, rhs) )
    18552 {
    18553 matinds[matidx] = lp->ncols;
    18554 matvals[matidx++] = -rhs;
    18555 assert( matidx <= ntotnonz );
    18556 }
    18557
    18558 matlhs[matrowidx] = 0.0;
    18559 matrhs[matrowidx++] = 0.0;
    18560 assert( matrowidx <= ntotrows );
    18561 }
    18562 else
    18563 {
    18564 SCIP_Real abslhs = REALABS(lhs);
    18565 SCIP_Real absrhs = REALABS(rhs);
    18566
    18567 assert(!SCIPsetIsEQ(set, lhs, rhs));
    18568
    18569 /* treat lhs */
    18570 if( !SCIPsetIsInfinity(set, abslhs) )
    18571 {
    18572 /* set up indices */
    18573 matbeg[matrowidx] = matidx;
    18574 for( j = 0; j < nnonz; ++j )
    18575 {
    18576 assert( rowcols[j] != NULL );
    18577 assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
    18578 assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
    18579 assert( ! SCIPsetIsZero(set, rowvals[j]) );
    18580 matinds[matidx] = rowcols[j]->lppos;
    18581 matvals[matidx++] = rowvals[j];
    18582 assert( matidx <= ntotnonz );
    18583 }
    18584
    18585 /* add artificial variable */
    18586 if ( ! SCIPsetIsZero(set, lhs) )
    18587 {
    18588 matinds[matidx] = lp->ncols;
    18589 matvals[matidx++] = -lhs;
    18590 assert( matidx <= ntotnonz );
    18591 }
    18592
    18593 if( relaxrows )
    18594 {
    18595 /* add slack variable */
    18596 matvals[matidx] = -MAX(1.0, lhs); /*lint !e679*/
    18597 matinds[matidx++] = lp->ncols + 1 + cnt; /*lint !e679*/
    18598 assert( matidx <= ntotnonz );
    18599 ++cnt;
    18600 }
    18601
    18602 matlhs[matrowidx] = 0.0;
    18603 matrhs[matrowidx++] = SCIPlpiInfinity(lpi);
    18604 assert( matrowidx <= ntotrows );
    18605 }
    18606
    18607 /* treat rhs */
    18608 if( !SCIPsetIsInfinity(set, absrhs) )
    18609 {
    18610 /* set up indices */
    18611 matbeg[matrowidx] = matidx;
    18612 for( j = 0; j < nnonz; ++j )
    18613 {
    18614 assert( rowcols[j] != NULL );
    18615 assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
    18616 assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
    18617 assert( ! SCIPsetIsZero(set, rowvals[j]) );
    18618 matinds[matidx] = rowcols[j]->lppos;
    18619 matvals[matidx++] = rowvals[j];
    18620 assert( matidx <= ntotnonz );
    18621 }
    18622
    18623 /* add artificial variable */
    18624 if ( ! SCIPsetIsZero(set, rhs) )
    18625 {
    18626 matinds[matidx] = lp->ncols;
    18627 matvals[matidx++] = -rhs;
    18628 assert( matidx <= ntotnonz );
    18629 }
    18630
    18631 if( relaxrows )
    18632 {
    18633 /* add slack variable */
    18634 matvals[matidx] = MAX(1.0, absrhs); /*lint !e679*/
    18635 matinds[matidx++] = lp->ncols + 1 + cnt; /*lint !e679*/
    18636 ++cnt;
    18637 }
    18638
    18639 matlhs[matrowidx] = -SCIPlpiInfinity(lpi);
    18640 matrhs[matrowidx++] = 0.0;
    18641 assert( matrowidx <= ntotrows );
    18642 }
    18643 }
    18644 }
    18645
    18646 /* create row arising from objective cutoff */
    18647 if( inclobjcutoff )
    18648 {
    18649 SCIP_Real rhs;
    18650
    18651 /* get row data */
    18652 assert(lp->looseobjvalinf == 0);
    18653 rhs = lp->cutoffbound - getFiniteLooseObjval(lp, set, prob);
    18654
    18655 /* set up indices and coefficients */
    18656 matbeg[matrowidx] = matidx;
    18657 for( j = 0; j < lp->ncols; ++j )
    18658 {
    18659 assert( lp->cols[j] != NULL );
    18660 assert( 0 <= lp->cols[j]->lppos && lp->cols[j]->lppos < lp->ncols );
    18661 assert( lp->cols[lp->cols[j]->lppos] == lp->cols[j] );
    18662
    18663 if( ! SCIPsetIsZero(set, lp->cols[j]->obj) )
    18664 {
    18665 matinds[matidx] = lp->cols[j]->lppos;
    18666 matvals[matidx++] = lp->cols[j]->obj;
    18667 assert( matidx <= ntotnonz );
    18668 }
    18669 }
    18670
    18671 /* treat rhs */
    18672
    18673 /* add artificial variable */
    18674 if ( ! SCIPsetIsZero(set, rhs) )
    18675 {
    18676 matinds[matidx] = lp->ncols;
    18677 matvals[matidx++] = -rhs;
    18678 assert( matidx <= ntotnonz );
    18679 }
    18680
    18681 if( relaxrows )
    18682 {
    18683 SCIP_Real absrhs = REALABS(rhs);
    18684
    18685 /* add slack variable */
    18686 matvals[matidx] = MAX(1.0, absrhs);
    18687 matinds[matidx++] = lp->ncols + 1 + cnt;
    18688 assert( matidx <= ntotnonz );
    18689 ++cnt;
    18690 }
    18691 matlhs[matrowidx] = -SCIPsetInfinity(set);
    18692 matrhs[matrowidx++] = 0.0;
    18693 assert( matrowidx <= ntotrows );
    18694 }
    18695
    18696 /* create rows arising from bounds */
    18697 for( j = 0; j < lp->ncols; ++j )
    18698 {
    18699 SCIP_COL* col;
    18700 SCIP_Real abscollb;
    18701 SCIP_Real abscolub;
    18702
    18703 col = lp->cols[j];
    18704 assert( col != NULL );
    18705 assert( col->lppos == j );
    18706
    18707 /* fixed variable */
    18708 if( SCIPsetIsEQ(set, col->lb, col->ub) )
    18709 {
    18710 /* set up index of column */
    18711 matbeg[matrowidx] = matidx;
    18712
    18713 matinds[matidx] = j;
    18714 matvals[matidx++] = 1.0;
    18715 assert( matidx <= ntotnonz );
    18716
    18717 /* add artificial variable */
    18718 if ( ! SCIPsetIsZero(set, col->ub) )
    18719 {
    18720 matinds[matidx] = lp->ncols;
    18721 matvals[matidx++] = -col->ub;
    18722 assert( matidx <= ntotnonz );
    18723 }
    18724
    18725 matlhs[matrowidx] = 0.0;
    18726 matrhs[matrowidx++] = 0.0;
    18727 assert( matrowidx <= ntotrows );
    18728
    18729 continue;
    18730 }
    18731
    18732 abscollb = REALABS(col->lb);
    18733 abscolub = REALABS(col->ub);
    18734
    18735 /* lower bound */
    18736 if ( ! SCIPsetIsInfinity(set, abscollb) )
    18737 {
    18738 /* set up index of column */
    18739 matbeg[matrowidx] = matidx;
    18740
    18741 matinds[matidx] = j;
    18742 matvals[matidx++] = 1.0;
    18743 assert( matidx <= ntotnonz );
    18744
    18745 /* add artificial variable */
    18746 if ( ! SCIPsetIsZero(set, col->lb) )
    18747 {
    18748 matinds[matidx] = lp->ncols;
    18749 matvals[matidx++] = -col->lb;
    18750 assert( matidx <= ntotnonz );
    18751 }
    18752
    18753 /* add slack variable */
    18754 matvals[matidx] = -MAX(1.0, abscollb);
    18755 matinds[matidx++] = lp->ncols + 1 + cnt;
    18756 assert( matidx <= ntotnonz );
    18757 ++cnt;
    18758
    18759 matlhs[matrowidx] = 0.0;
    18760 matrhs[matrowidx++] = SCIPsetInfinity(set);
    18761 assert( matrowidx <= ntotrows );
    18762 }
    18763
    18764 /* upper bound */
    18765 if ( ! SCIPsetIsInfinity(set, abscolub) )
    18766 {
    18767 /* set up index of column */
    18768 matbeg[matrowidx] = matidx;
    18769
    18770 matinds[matidx] = j;
    18771 matvals[matidx++] = 1.0;
    18772 assert( matidx <= ntotnonz );
    18773
    18774 /* add artificial variable */
    18775 if ( ! SCIPsetIsZero(set, col->ub) )
    18776 {
    18777 matinds[matidx] = lp->ncols;
    18778 matvals[matidx++] = -col->ub;
    18779 assert( matidx <= ntotnonz );
    18780 }
    18781
    18782 /* add slack variable */
    18783 matvals[matidx] = MAX(1.0, abscolub);
    18784 matinds[matidx++] = lp->ncols + 1 + cnt;
    18785 assert( matidx <= ntotnonz );
    18786 ++cnt;
    18787
    18788 matlhs[matrowidx] = -SCIPsetInfinity(set);
    18789 matrhs[matrowidx++] = 0.0;
    18790 assert( matrowidx <= ntotrows );
    18791 }
    18792 }
    18793 assert( cnt == nslacks );
    18794 assert( matrowidx == ntotrows );
    18795
    18796 /* add rows */
    18797 SCIP_CALL( SCIPlpiAddRows(lpi, ntotrows, matlhs, matrhs, NULL, matidx, matbeg, matinds, matvals) );
    18798
    18799 SCIPsetFreeBufferArray(set, &matrhs);
    18800 SCIPsetFreeBufferArray(set, &matlhs);
    18801 SCIPsetFreeBufferArray(set, &matbeg);
    18802 SCIPsetFreeBufferArray(set, &matvals);
    18803 SCIPsetFreeBufferArray(set, &matinds);
    18804
    18805#ifdef SCIP_OUTPUT
    18806 SCIP_CALL( SCIPlpiWriteLP(lpi, "relativeInterior.lp") );
    18807#endif
    18808
    18809#ifndef NDEBUG
    18810 {
    18811 int ncols;
    18812 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    18813 assert( ncols == nnewcols );
    18814 }
    18815#endif
    18816
    18817 /* set time limit */
    18818 if( SCIPsetIsInfinity(set, timelimit) )
    18819 timelimit = SCIPlpiInfinity(lpi);
    18820 retcode = SCIPlpiSetRealpar(lpi, SCIP_LPPAR_LPTILIM, timelimit);
    18821
    18822 /* check, if parameter is unknown */
    18823 if( retcode == SCIP_PARAMETERUNKNOWN )
    18824 SCIPmessagePrintWarning(messagehdlr, "Could not set time limit of LP solver for relative interior point computation.\n");
    18825 else if ( retcode != SCIP_OKAY )
    18826 return retcode;
    18827
    18828 /* set iteration limit */
    18829 retcode = SCIPlpiSetIntpar(lpi, SCIP_LPPAR_LPITLIM, iterlimit);
    18830
    18831 /* check, if parameter is unknown */
    18832 if( retcode == SCIP_PARAMETERUNKNOWN )
    18833 SCIPmessagePrintWarning(messagehdlr, "Could not set iteration limit of LP solver for relative interior point computation.\n");
    18834 else if ( retcode != SCIP_OKAY )
    18835 return retcode;
    18836
    18837 /* solve and store point */
    18838 /* SCIP_CALL( SCIPlpiSolvePrimal(lpi) ); */
    18839 SCIP_CALL( SCIPlpiSolveDual(lpi) ); /* dual is usually faster */
    18840
    18841#ifndef NDEBUG
    18842 if ( SCIPlpiIsIterlimExc(lpi) )
    18843 SCIPmessagePrintWarning(messagehdlr, "Iteration limit exceeded in relative interior point computation.\n");
    18844 if ( SCIPlpiIsTimelimExc(lpi) )
    18845 SCIPmessagePrintWarning(messagehdlr, "Time limit exceeded in relative interior point computation.\n");
    18846#endif
    18847
    18848 if( SCIPlpiIsOptimal(lpi) )
    18849 {
    18850 /* get primal solution */
    18851 SCIP_CALL( SCIPsetAllocBufferArray(set, &primal, nnewcols) );
    18852 SCIP_CALL( SCIPlpiGetSol(lpi, &objval, primal, NULL, NULL, NULL) );
    18853 alpha = primal[lp->ncols];
    18854 assert( SCIPsetIsFeasGE(set, alpha, 1.0) );
    18855
    18856 SCIPsetDebugMsg(set, "Solved relative interior lp with objective %g.\n", objval);
    18857
    18858 /* construct relative interior point */
    18859 for( j = 0; j < lp->ncols; ++j )
    18860 point[j] = primal[j]/alpha;
    18861
    18862#ifdef SCIP_DEBUG
    18863 /* check whether the point is a relative interior point */
    18864 cnt = 0;
    18865 if( relaxrows )
    18866 {
    18867 for( i = 0; i < lp->nrows; ++i )
    18868 {
    18869 SCIP_ROW* row;
    18870 SCIP_COL** rowcols;
    18871 SCIP_Real* rowvals;
    18872 SCIP_Real lhs;
    18873 SCIP_Real rhs;
    18874 SCIP_Real sum;
    18875 int nnonz;
    18876
    18877 row = lp->rows[i];
    18878 assert( row != NULL );
    18879
    18880 /* get row data */
    18881 lhs = row->lhs - (SCIPsetIsInfinity(set, -row->lhs) ? 0.0 : row->constant);
    18882 rhs = row->rhs - (SCIPsetIsInfinity(set, row->rhs) ? 0.0 : row->constant);
    18883 nnonz = row->nlpcols;
    18884 assert( nnonz <= lp->ncols );
    18885 rowcols = row->cols;
    18886 rowvals = row->vals;
    18887
    18888 sum = 0.0;
    18889 for( j = 0; j < nnonz; ++j )
    18890 sum += rowvals[j] * primal[rowcols[j]->lppos];
    18891 sum /= alpha;
    18892
    18893 /* if we have an equation */
    18894 if( SCIPsetIsEQ(set, lhs, rhs) )
    18895 {
    18896 assert( SCIPsetIsFeasEQ(set, sum, lhs) );
    18897 }
    18898 else
    18899 {
    18900 /* treat lhs */
    18901 if( !SCIPsetIsInfinity(set, REALABS(lhs)) )
    18902 {
    18903 assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasGT(set, sum, lhs) );
    18904 ++cnt;
    18905 }
    18906 /* treat rhs */
    18907 if( !SCIPsetIsInfinity(set, REALABS(rhs)) )
    18908 {
    18909 assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, sum, rhs) );
    18910 ++cnt;
    18911 }
    18912 }
    18913 }
    18914 if( inclobjcutoff )
    18915 {
    18916 SCIP_Real sum;
    18917#ifndef NDEBUG
    18918 SCIP_Real rhs;
    18919
    18920 rhs = lp->cutoffbound - getFiniteLooseObjval(lp, set, prob);
    18921#endif
    18922 sum = 0.0;
    18923 for( j = 0; j < lp->ncols; ++j )
    18924 sum += lp->cols[j]->obj * primal[lp->cols[j]->lppos];
    18925 sum /= alpha;
    18926
    18927 assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, sum, rhs) );
    18928 ++cnt;
    18929 }
    18930 }
    18931 /* check bounds */
    18932 for( j = 0; j < lp->ncols; ++j )
    18933 {
    18934 SCIP_COL* col;
    18935#ifndef NDEBUG
    18936 SCIP_Real val;
    18937#endif
    18938
    18939 col = lp->cols[j];
    18940 assert( col != NULL );
    18941#ifndef NDEBUG
    18942 val = primal[col->lppos] / alpha;
    18943#endif
    18944 /* if the variable is not fixed */
    18945 if( !SCIPsetIsEQ(set, col->lb, col->ub) )
    18946 {
    18947 /* treat lb */
    18948 if( !SCIPsetIsInfinity(set, REALABS(col->lb)) )
    18949 {
    18950 assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasGT(set, val, col->lb) );
    18951 ++cnt;
    18952 }
    18953 /* treat rhs */
    18954 if( !SCIPsetIsInfinity(set, REALABS(col->ub)) )
    18955 {
    18956 assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, val, col->ub) );
    18957 ++cnt;
    18958 }
    18959 }
    18960 }
    18961#endif
    18962
    18963 /* free */
    18964 SCIPsetFreeBufferArray(set, &primal);
    18965
    18966 *success = TRUE;
    18967 }
    18968
    18969 return SCIP_OKAY;
    18970}
    18971
    18972/** compute relative interior point
    18973 *
    18974 * We use the approach of@par
    18975 * R. Freund, R. Roundy, M. J. Todd@par
    18976 * "Identifying the Set of Always-Active Constraints in a System of Linear Inequalities by a Single Linear Program"@par
    18977 * Tech. Rep, No. 1674-85, Sloan School, M.I.T., 1985
    18978 *
    18979 * to compute a relative interior point for the current LP.
    18980 *
    18981 * Assume the original LP looks as follows:
    18982 * \f[
    18983 * \begin{array}{rrl}
    18984 * \min & c^T x &\\
    18985 * & A x & \geq a\\
    18986 * & B x & \leq b\\
    18987 * & D x & = d.
    18988 * \end{array}
    18989 * \f]
    18990 * Note that bounds should be included in the system.
    18991 *
    18992 * To find an interior point the following LP does the job:
    18993 * \f[
    18994 * \begin{array}{rrl}
    18995 * \max & 1^T y &\\
    18996 * & A x - y - \alpha a & \geq 0\\
    18997 * & B x + y - \alpha b & \leq 0\\
    18998 * & D x - \alpha d & = 0\\
    18999 * & 0 \leq y & \leq 1\\
    19000 * & \alpha & \geq 1.
    19001 * \end{array}
    19002 * \f]
    19003 * If the original LP is feasible, this LP is feasible as well. Any optimal solution yields the relative interior point
    19004 * \f$x^*_j/\alpha^*\f$. Note that this will just produce some relative interior point. It does not produce a
    19005 * particular relative interior point, e.g., one that maximizes the distance to the boundary in some norm.
    19006 */
    19008 SCIP_SET* set, /**< global SCIP settings */
    19009 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    19010 SCIP_LP* lp, /**< LP data */
    19011 SCIP_PROB* prob, /**< problem data */
    19012 SCIP_Bool relaxrows, /**< should the rows be relaxed */
    19013 SCIP_Bool inclobjcutoff, /**< should a row for the objective cutoff be included */
    19014 SCIP_Real timelimit, /**< time limit for LP solver */
    19015 int iterlimit, /**< iteration limit for LP solver */
    19016 SCIP_Real* point, /**< array to store relative interior point on exit */
    19017 SCIP_Bool* success /**< buffer to indicate whether interior point was successfully computed */
    19018 )
    19019{
    19020 SCIP_LPI* lpi;
    19021 SCIP_RETCODE retcode;
    19022
    19023 assert(set != NULL);
    19024 assert(lp != NULL);
    19025 assert(point != NULL);
    19026 assert(success != NULL);
    19027
    19028 *success = FALSE;
    19029
    19030 /* check time and iteration limits */
    19031 if ( timelimit <= 0.0 || iterlimit <= 0 )
    19032 return SCIP_OKAY;
    19033
    19034 /* exit if there are no columns */
    19035 assert(lp->nrows >= 0);
    19036 assert(lp->ncols >= 0);
    19037 if( lp->ncols == 0 )
    19038 return SCIP_OKAY;
    19039
    19040 /* disable objective cutoff if we have none */
    19041 if( inclobjcutoff && (SCIPsetIsInfinity(set, lp->cutoffbound) || lp->looseobjvalinf > 0 || lp->looseobjval == SCIP_INVALID) ) /*lint !e777 */
    19042 inclobjcutoff = FALSE;
    19043
    19044 SCIPsetDebugMsg(set, "Computing relative interior point to current LP.\n");
    19045
    19046 /* if there are no rows, we return the zero point */
    19047 if( lp->nrows == 0 && !inclobjcutoff )
    19048 {
    19049 /* create zero point */
    19050 BMSclearMemoryArray(point, lp->ncols);
    19051 *success = TRUE;
    19052
    19053 return SCIP_OKAY;
    19054 }
    19055
    19056 /* create auxiliary LP */
    19057 SCIP_CALL( SCIPlpiCreate(&lpi, messagehdlr, "relativeInterior", SCIP_OBJSEN_MAXIMIZE) );
    19058
    19059 /* catch return code and ensure that lpi is freed, anyway */
    19060 retcode = computeRelIntPoint(lpi, set, messagehdlr, lp, prob, relaxrows, inclobjcutoff, timelimit, iterlimit, point, success);
    19061
    19062 SCIP_CALL( SCIPlpiFree(&lpi) );
    19063
    19064 /* return error, unless we obtained an LP error */
    19065 if ( retcode != SCIP_OKAY && retcode != SCIP_LPERROR )
    19066 {
    19067 SCIP_CALL( retcode );
    19068 }
    19069
    19070 return SCIP_OKAY;
    19071}
    19072
    19073/** computes two measures for dual degeneracy (dual degeneracy rate and variable-constraint ratio)
    19074 * based on the changes applied when reducing the problem to the optimal face
    19075 *
    19076 * returns the dual degeneracy rate, i.e., the share of nonbasic variables with reduced cost 0
    19077 * and the variable-constraint ratio, i.e., the number of unfixed variables in relation to the basis size
    19078 */
    19080 SCIP_LP* lp, /**< LP data */
    19081 SCIP_SET* set, /**< global SCIP settings */
    19082 SCIP_STAT* stat, /**< problem statistics */
    19083 SCIP_Real* degeneracy, /**< pointer to store the dual degeneracy rate */
    19084 SCIP_Real* varconsratio /**< pointer to store the variable-constraint ratio */
    19085 )
    19086{
    19087 assert(lp != NULL);
    19088 assert(lp->solved);
    19089 assert(lp->flushed);
    19090
    19091 if( lp->validdegeneracylp != stat->nlps )
    19092 {
    19093 lp->validdegeneracylp = stat->nlps;
    19094
    19095 /* if the LP was solved to optimality, we determine the dual degeneracy */
    19097 {
    19098 SCIP_COL** cols;
    19099 SCIP_ROW** rows;
    19100 SCIP_COL* col;
    19101 int ncols;
    19102 int nrows;
    19103 int nfixedcols = 0;
    19104 int nalreadyfixedcols = 0;
    19105 int nfixedrows = 0;
    19106#ifndef NDEBUG
    19107 int nimplicitfixedrows = 0;
    19108#endif
    19109 int nineq = 0;
    19110 int c;
    19111 int r;
    19112 int nbasicequalities = 0;
    19113
    19114 cols = lp->cols;
    19115 rows = lp->rows;
    19116 ncols = lp->ncols;
    19117 nrows = lp->nrows;
    19118
    19119 /* count number of columns that will be fixed when reducing the LP to the optimal face */
    19120 for( c = ncols - 1 ; c >= 0; --c )
    19121 {
    19122 col = cols[c];
    19123 assert(SCIPcolIsInLP(col));
    19124
    19125 /* column is not basic and not fixed already */
    19127 {
    19128 /* variable with nonzero reduced costs are fixed */
    19129 /* @todo which tolerance should be used here? epsilon or dualfeastol? */
    19130 if( !SCIPsetIsZero(set, SCIPcolGetRedcost(col, stat, lp)) )
    19131 ++nfixedcols;
    19132 else if( SCIPsetIsEQ(set, SCIPcolGetLb(col), SCIPcolGetUb(col)) )
    19133 ++nalreadyfixedcols;
    19134 }
    19135 }
    19136
    19137 /* count number of rows that will be turned into equations when reducing the LP to the optimal face */
    19138 for( r = nrows - 1; r >= 0; --r )
    19139 {
    19140 SCIP_ROW* row = rows[r];
    19141
    19142 assert(SCIProwIsInLP(row));
    19143
    19144 if( !SCIPsetIsEQ(set, SCIProwGetLhs(row), SCIProwGetRhs(row)) )
    19145 {
    19146 SCIP_Real dualsol = SCIProwGetDualsol(row);
    19147
    19148 ++nineq;
    19149
    19151 {
    19152 /* rows with nonzero dual solution are turned into equations */
    19153 /* @todo which tolerance should be used here? epsilon or dualfeastol? */
    19154 if( !SCIPsetIsZero(set, dualsol) )
    19155 {
    19156 if( SCIPsetIsEQ(set, SCIProwGetLhs(row), SCIProwGetLPActivity(row, set, stat, lp)) )
    19157 {
    19158 assert(!SCIPlpIsDualReliable(lp) || !SCIPsetIsDualfeasNegative(set, dualsol) || set->exact_enable);
    19159 ++nfixedrows;
    19160 }
    19161 else if( SCIPsetIsEQ(set, SCIProwGetRhs(row), SCIProwGetLPActivity(row, set, stat, lp)) )
    19162 {
    19163 assert(!SCIPlpIsDualReliable(lp) || !SCIPsetIsDualfeasPositive(set, dualsol)|| set->exact_enable);
    19164 ++nfixedrows;
    19165 }
    19166 }
    19167#ifndef NDEBUG
    19168 else if( SCIPsetIsEQ(set, SCIProwGetLhs(row), SCIProwGetMaxActivity(row, set, stat))
    19169 || SCIPsetIsEQ(set, SCIProwGetRhs(row), SCIProwGetMinActivity(row, set, stat)) )
    19170 {
    19171 ++nimplicitfixedrows;
    19172 }
    19173#endif
    19174 }
    19175 }
    19177 ++nbasicequalities;
    19178 }
    19179 assert(nfixedcols + nfixedrows <= ncols + nineq + nbasicequalities - nrows - nalreadyfixedcols - nimplicitfixedrows);
    19180
    19181 if( ncols + nineq - nrows + nbasicequalities - nalreadyfixedcols > 0 )
    19182 lp->degeneracy = 1.0 - 1.0 * (nfixedcols + nfixedrows) / (ncols + nineq - nrows + nbasicequalities - nalreadyfixedcols);
    19183 else
    19184 lp->degeneracy = 0.0;
    19185
    19186 if( nrows > 0 )
    19187 lp->varconsratio = 1.0 * (ncols + nineq + nbasicequalities - nfixedcols - nfixedrows - nalreadyfixedcols) / nrows;
    19188 else
    19189 lp->varconsratio = 1.0; /* @todo should this rather be set to a large value? */
    19190 assert(lp->degeneracy >= 0);
    19191 assert(SCIPsetIsLE(set, lp->degeneracy, 1.0));
    19192 assert(SCIPsetIsGE(set, lp->varconsratio, 1.0));
    19193 }
    19194 else
    19195 {
    19196 lp->degeneracy = 0.0;
    19197 lp->varconsratio = 0.0;
    19198 }
    19199 }
    19200
    19201 *degeneracy = lp->degeneracy;
    19202 *varconsratio = lp->varconsratio;
    19203
    19204 return SCIP_OKAY;
    19205}
    19206
    19207/** checks if absolute difference of values is in range of LP primal feastol */
    19209 SCIP_SET* set, /**< global SCIP settings */
    19210 SCIP_LP* lp, /**< current LP data */
    19211 SCIP_Real val1, /**< first value to be compared */
    19212 SCIP_Real val2 /**< second value to be compared */
    19213 )
    19214{
    19215 assert(set != NULL);
    19216 assert(lp != NULL);
    19217
    19218 /* avoid to compare two different infinities; the reason for that is
    19219 * that such a comparison can lead to unexpected results */
    19220 assert( ((!SCIPsetIsInfinity(set, val1) || !SCIPsetIsInfinity(set, val2))
    19221 && (!SCIPsetIsInfinity(set, -val1) || !SCIPsetIsInfinity(set, -val2)))
    19222 || val1 == val2 ); /*lint !e777*/
    19223
    19224 return EPSEQ(val1, val2, lp->feastol);
    19225}
    19226
    19227/** checks if absolute difference of val1 and val2 is lower than LP primal feastol */
    19229 SCIP_SET* set, /**< global SCIP settings */
    19230 SCIP_LP* lp, /**< current LP data */
    19231 SCIP_Real val1, /**< first value to be compared */
    19232 SCIP_Real val2 /**< second value to be compared */
    19233 )
    19234{
    19235 assert(set != NULL);
    19236 assert(lp != NULL);
    19237
    19238 /* avoid to compare two different infinities; the reason for that is
    19239 * that such a comparison can lead to unexpected results */
    19240 assert( ((!SCIPsetIsInfinity(set, val1) || !SCIPsetIsInfinity(set, val2))
    19241 && (!SCIPsetIsInfinity(set, -val1) || !SCIPsetIsInfinity(set, -val2)))
    19242 || val1 == val2 ); /*lint !e777*/
    19243
    19244 return EPSLT(val1, val2, lp->feastol);
    19245}
    19246
    19247/** checks if absolute difference of val1 and val2 is not greater than LP primal feastol */
    19249 SCIP_SET* set, /**< global SCIP settings */
    19250 SCIP_LP* lp, /**< current LP data */
    19251 SCIP_Real val1, /**< first value to be compared */
    19252 SCIP_Real val2 /**< second value to be compared */
    19253 )
    19254{
    19255 assert(set != NULL);
    19256 assert(lp != NULL);
    19257
    19258 /* avoid to compare two different infinities; the reason for that is
    19259 * that such a comparison can lead to unexpected results */
    19260 assert( ((!SCIPsetIsInfinity(set, val1) || !SCIPsetIsInfinity(set, val2))
    19261 && (!SCIPsetIsInfinity(set, -val1) || !SCIPsetIsInfinity(set, -val2)))
    19262 || val1 == val2 ); /*lint !e777*/
    19263
    19264 return EPSLE(val1, val2, lp->feastol);
    19265}
    19266
    19267/** checks if absolute difference of val1 and val2 is greater than LP primal feastol */
    19269 SCIP_SET* set, /**< global SCIP settings */
    19270 SCIP_LP* lp, /**< current LP data */
    19271 SCIP_Real val1, /**< first value to be compared */
    19272 SCIP_Real val2 /**< second value to be compared */
    19273 )
    19274{
    19275 assert(set != NULL);
    19276 assert(lp != NULL);
    19277
    19278 /* avoid to compare two different infinities; the reason for that is
    19279 * that such a comparison can lead to unexpected results */
    19280 assert( ((!SCIPsetIsInfinity(set, val1) || !SCIPsetIsInfinity(set, val2))
    19281 && (!SCIPsetIsInfinity(set, -val1) || !SCIPsetIsInfinity(set, -val2)))
    19282 || val1 == val2 ); /*lint !e777*/
    19283
    19284 return EPSGT(val1, val2, lp->feastol);
    19285}
    19286
    19287/** checks if absolute difference of val1 and val2 is not lower than -LP primal feastol */
    19289 SCIP_SET* set, /**< global SCIP settings */
    19290 SCIP_LP* lp, /**< current LP data */
    19291 SCIP_Real val1, /**< first value to be compared */
    19292 SCIP_Real val2 /**< second value to be compared */
    19293 )
    19294{
    19295 assert(set != NULL);
    19296 assert(lp != NULL);
    19297
    19298 /* avoid to compare two different infinities; the reason for that is
    19299 * that such a comparison can lead to unexpected results */
    19300 assert( ((!SCIPsetIsInfinity(set, val1) || !SCIPsetIsInfinity(set, val2))
    19301 && (!SCIPsetIsInfinity(set, -val1) || !SCIPsetIsInfinity(set, -val2)))
    19302 || val1 == val2 ); /*lint !e777*/
    19303
    19304 return EPSGE(val1, val2, lp->feastol);
    19305}
    19306
    19307/** checks if value is in range LP primal feasibility tolerance of 0.0 */
    19309 SCIP_LP* lp, /**< current LP data */
    19310 SCIP_Real val /**< value to process */
    19311 )
    19312{
    19313 assert(lp != NULL);
    19314
    19315 return EPSZ(val, lp->feastol);
    19316}
    19317
    19318/** checks if value is greater than LP primal feasibility tolerance */
    19320 SCIP_LP* lp, /**< current LP data */
    19321 SCIP_Real val /**< value to process */
    19322 )
    19323{
    19324 assert(lp != NULL);
    19325
    19326 return EPSP(val, lp->feastol);
    19327}
    19328
    19329/** checks if value is lower than -LP primal feasibility tolerance */
    19331 SCIP_LP* lp, /**< current LP data */
    19332 SCIP_Real val /**< value to process */
    19333 )
    19334{
    19335 assert(lp != NULL);
    19336
    19337 return EPSN(val, lp->feastol);
    19338}
    static long bound
    SCIP_RETCODE SCIPcertificateFreeRowInfo(SCIP *scip, SCIP_ROW *row)
    methods for certificate output
    SCIP_VAR * a
    Definition: circlepacking.c:66
    SCIP_VAR ** b
    Definition: circlepacking.c:65
    SCIP_VAR ** y
    Definition: circlepacking.c:64
    SCIP_Real * r
    Definition: circlepacking.c:59
    SCIP_VAR ** x
    Definition: circlepacking.c:63
    void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
    Definition: clock.c:360
    void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
    Definition: clock.c:290
    SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
    Definition: clock.c:438
    internal methods for clocks and timing issues
    void SCIPconsCapture(SCIP_CONS *cons)
    Definition: cons.c:6427
    SCIP_RETCODE SCIPconsRelease(SCIP_CONS **cons, BMS_BLKMEM *blkmem, SCIP_SET *set)
    Definition: cons.c:6439
    internal methods for constraints and constraint handlers
    #define NULL
    Definition: def.h:248
    #define SCIP_MAXSTRLEN
    Definition: def.h:269
    #define EPSGE(x, y, eps)
    Definition: def.h:187
    #define SCIP_Longint
    Definition: def.h:141
    #define SCIP_UNUSED(x)
    Definition: def.h:409
    #define EPSISINT(x, eps)
    Definition: def.h:195
    #define SCIP_DEFAULT_SUMEPSILON
    Definition: def.h:165
    #define EPSP(x, eps)
    Definition: def.h:189
    #define SCIP_REAL_MAX
    Definition: def.h:158
    #define SCIP_INVALID
    Definition: def.h:178
    #define SCIP_Bool
    Definition: def.h:91
    #define SCIP_DEFAULT_EPSILON
    Definition: def.h:164
    #define EPSLE(x, y, eps)
    Definition: def.h:185
    #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 EPSLT(x, y, eps)
    Definition: def.h:184
    #define ABS(x)
    Definition: def.h:216
    #define SQR(x)
    Definition: def.h:199
    #define EPSEQ(x, y, eps)
    Definition: def.h:183
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define MAX(x, y)
    Definition: def.h:220
    #define SCIP_CALL_ABORT(x)
    Definition: def.h:334
    #define EPSN(x, eps)
    Definition: def.h:190
    #define SCIP_LONGINT_FORMAT
    Definition: def.h:148
    #define SCIPABORT()
    Definition: def.h:327
    #define REALABS(x)
    Definition: def.h:182
    #define EPSGT(x, y, eps)
    Definition: def.h:186
    #define SCIP_LONGINT_MAX
    Definition: def.h:142
    #define EPSZ(x, eps)
    Definition: def.h:188
    #define SCIP_CALL(x)
    Definition: def.h:355
    SCIP_RETCODE SCIPeventCreateRowDeletedLP(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
    Definition: event.c:1055
    SCIP_RETCODE SCIPeventqueueAdd(SCIP_EVENTQUEUE *eventqueue, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTFILTER *eventfilter, SCIP_EVENT **event)
    Definition: event.c:2561
    SCIP_RETCODE SCIPeventfilterFree(SCIP_EVENTFILTER **eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set)
    Definition: event.c:2167
    SCIP_RETCODE SCIPeventCreateRowSideChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_SIDETYPE side, SCIP_Real oldval, SCIP_Real newval)
    Definition: event.c:1122
    SCIP_RETCODE SCIPeventfilterDel(SCIP_EVENTFILTER *eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
    Definition: event.c:2300
    SCIP_RETCODE SCIPeventfilterCreate(SCIP_EVENTFILTER **eventfilter, BMS_BLKMEM *blkmem)
    Definition: event.c:2142
    SCIP_RETCODE SCIPeventCreateRowConstChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_Real oldval, SCIP_Real newval)
    Definition: event.c:1099
    SCIP_RETCODE SCIPeventfilterAdd(SCIP_EVENTFILTER *eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
    Definition: event.c:2207
    SCIP_RETCODE SCIPeventCreateRowCoefChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_COL *col, SCIP_Real oldval, SCIP_Real newval)
    Definition: event.c:1074
    SCIP_RETCODE SCIPeventCreateRowAddedLP(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
    Definition: event.c:1036
    internal methods for managing events
    SCIP_Bool SCIPlpiExactHasDualRay(SCIP_LPIEXACT *lpi)
    SCIP_RETCODE SCIPlpiChgSides(SCIP_LPI *lpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
    Definition: lpi_clp.cpp:1179
    SCIP_RETCODE SCIPlpiSetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPISTATE *lpistate)
    Definition: lpi_clp.cpp:3457
    SCIP_RETCODE SCIPlpiGetBInvACol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
    Definition: lpi_clp.cpp:3377
    SCIP_RETCODE SCIPlpiGetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
    Definition: lpi_clp.cpp:3824
    SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
    Definition: lpi_clp.cpp:3947
    SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
    Definition: lpi_clp.cpp:2718
    SCIP_Bool SCIPlpiExistsPrimalRay(SCIP_LPI *lpi)
    Definition: lpi_clp.cpp:2478
    SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
    Definition: lpi_clp.cpp:2995
    SCIP_RETCODE SCIPlpiAddRows(SCIP_LPI *lpi, int nrows, const SCIP_Real *lhs, const SCIP_Real *rhs, char **rownames, int nnonz, const int *beg, const int *ind, const SCIP_Real *val)
    Definition: lpi_clp.cpp:920
    SCIP_RETCODE SCIPlpiGetPrimalRay(SCIP_LPI *lpi, SCIP_Real *ray)
    Definition: lpi_clp.cpp:2860
    SCIP_RETCODE SCIPlpiGetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int *ival)
    Definition: lpi_clp.cpp:3676
    SCIP_RETCODE SCIPlpiWriteLP(SCIP_LPI *lpi, const char *fname)
    Definition: lpi_clp.cpp:4029
    SCIP_RETCODE SCIPlpiSetIntegralityInformation(SCIP_LPI *lpi, int ncols, int *intInfo)
    Definition: lpi_clp.cpp:480
    SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
    Definition: lpi_clp.cpp:3861
    SCIP_RETCODE SCIPlpiStrongbranchFrac(SCIP_LPI *lpi, int col, SCIP_Real psol, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
    Definition: lpi_clp.cpp:2311
    SCIP_RETCODE SCIPlpiSetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPINORMS *lpinorms)
    Definition: lpi_clp.cpp:3638
    SCIP_RETCODE SCIPlpiStrongbranchInt(SCIP_LPI *lpi, int col, SCIP_Real psol, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
    Definition: lpi_clp.cpp:2357
    SCIP_RETCODE SCIPlpiGetBounds(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lbs, SCIP_Real *ubs)
    Definition: lpi_clp.cpp:1733
    SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
    Definition: lpi_clp.cpp:2885
    SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
    Definition: lpi_clp.cpp:2794
    int SCIPlpiGetInternalStatus(SCIP_LPI *lpi)
    Definition: lpi_clp.cpp:2780
    SCIP_RETCODE SCIPlpiStartStrongbranch(SCIP_LPI *lpi)
    Definition: lpi_clp.cpp:2034
    SCIP_RETCODE SCIPlpiGetSolFeasibility(SCIP_LPI *lpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
    Definition: lpi_clp.cpp:2433
    SCIP_RETCODE SCIPlpiFreeNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
    Definition: lpi_clp.cpp:3651
    SCIP_Bool SCIPlpiIsIterlimExc(SCIP_LPI *lpi)
    Definition: lpi_clp.cpp:2748
    SCIP_RETCODE SCIPlpiChgBounds(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
    Definition: lpi_clp.cpp:1096
    SCIP_Bool SCIPlpiIsPrimalUnbounded(SCIP_LPI *lpi)
    Definition: lpi_clp.cpp:2516
    SCIP_RETCODE SCIPlpiIgnoreInstability(SCIP_LPI *lpi, SCIP_Bool *success)
    Definition: lpi_clp.cpp:1669
    SCIP_RETCODE SCIPlpiFree(SCIP_LPI **lpi)
    Definition: lpi_clp.cpp:643
    SCIP_RETCODE SCIPlpiStrongbranchesFrac(SCIP_LPI *lpi, int *cols, int ncols, SCIP_Real *psols, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
    Definition: lpi_clp.cpp:2332
    SCIP_Bool SCIPlpiIsPrimalFeasible(SCIP_LPI *lpi)
    Definition: lpi_clp.cpp:2549
    SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
    Definition: lpi_clp.cpp:2637
    SCIP_RETCODE SCIPlpiGetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
    Definition: lpi_clp.cpp:3620
    SCIP_Bool SCIPlpiIsTimelimExc(SCIP_LPI *lpi)
    Definition: lpi_clp.cpp:2764
    SCIP_Bool SCIPlpiHasStateBasis(SCIP_LPI *lpi, SCIP_LPISTATE *lpistate)
    Definition: lpi_clp.cpp:3550
    SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
    Definition: lpi_clp.cpp:3720
    const char * SCIPlpiGetSolverName(void)
    Definition: lpi_clp.cpp:454
    SCIP_Bool SCIPlpiHasPrimalRay(SCIP_LPI *lpi)
    Definition: lpi_clp.cpp:2496
    SCIP_RETCODE SCIPlpiGetBInvRow(SCIP_LPI *lpi, int r, SCIP_Real *coef, int *inds, int *ninds)
    Definition: lpi_clp.cpp:3269
    SCIP_RETCODE SCIPlpiDelRows(SCIP_LPI *lpi, int firstrow, int lastrow)
    Definition: lpi_clp.cpp:992
    SCIP_RETCODE SCIPlpiGetBInvCol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
    Definition: lpi_clp.cpp:3304
    SCIP_RETCODE SCIPlpiGetBInvARow(SCIP_LPI *lpi, int r, const SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
    Definition: lpi_clp.cpp:3342
    SCIP_RETCODE SCIPlpiSolveBarrier(SCIP_LPI *lpi, SCIP_Bool crossover)
    Definition: lpi_clp.cpp:1985
    SCIP_Bool SCIPlpiIsOptimal(SCIP_LPI *lpi)
    Definition: lpi_clp.cpp:2651
    SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
    Definition: lpi_clp.cpp:2046
    SCIP_RETCODE SCIPlpiGetSides(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhss, SCIP_Real *rhss)
    Definition: lpi_clp.cpp:1766
    SCIP_RETCODE SCIPlpiStrongbranchesInt(SCIP_LPI *lpi, int *cols, int ncols, SCIP_Real *psols, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
    Definition: lpi_clp.cpp:2378
    SCIP_RETCODE SCIPlpiGetSol(SCIP_LPI *lpi, SCIP_Real *objval, SCIP_Real *primsol, SCIP_Real *dualsol, SCIP_Real *activity, SCIP_Real *redcost)
    Definition: lpi_clp.cpp:2816
    SCIP_Bool SCIPlpiHasDualRay(SCIP_LPI *lpi)
    Definition: lpi_clp.cpp:2584
    SCIP_RETCODE SCIPlpiDelColset(SCIP_LPI *lpi, int *dstat)
    Definition: lpi_clp.cpp:874
    SCIP_RETCODE SCIPlpiGetObj(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *vals)
    Definition: lpi_clp.cpp:1708
    SCIP_RETCODE SCIPlpiFreeState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
    Definition: lpi_clp.cpp:3531
    SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
    Definition: lpi_clp.cpp:2530
    SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
    Definition: lpi_clp.cpp:1908
    SCIP_RETCODE SCIPlpiAddCols(SCIP_LPI *lpi, int ncols, const SCIP_Real *obj, const SCIP_Real *lb, const SCIP_Real *ub, char **colnames, int nnonz, const int *beg, const int *ind, const SCIP_Real *val)
    Definition: lpi_clp.cpp:758
    SCIP_RETCODE SCIPlpiSolvePrimal(SCIP_LPI *lpi)
    Definition: lpi_clp.cpp:1833
    SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
    Definition: lpi_clp.cpp:2949
    SCIP_RETCODE SCIPlpiGetBasisInd(SCIP_LPI *lpi, int *bind)
    Definition: lpi_clp.cpp:3217
    SCIP_RETCODE SCIPlpiCreate(SCIP_LPI **lpi, SCIP_MESSAGEHDLR *messagehdlr, const char *name, SCIP_OBJSEN objsen)
    Definition: lpi_clp.cpp:531
    SCIP_RETCODE SCIPlpiChgObj(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *obj)
    Definition: lpi_clp.cpp:1252
    SCIP_Bool SCIPlpiIsStable(SCIP_LPI *lpi)
    Definition: lpi_clp.cpp:2675
    SCIP_RETCODE SCIPlpiGetNCols(SCIP_LPI *lpi, int *ncols)
    Definition: lpi_clp.cpp:1447
    SCIP_RETCODE SCIPlpiInterrupt(SCIP_LPI *lpi, SCIP_Bool interrupt)
    Definition: lpi_clp.cpp:3923
    SCIP_RETCODE SCIPlpiDelCols(SCIP_LPI *lpi, int firstcol, int lastcol)
    Definition: lpi_clp.cpp:837
    SCIP_RETCODE SCIPlpiDelRowset(SCIP_LPI *lpi, int *dstat)
    Definition: lpi_clp.cpp:1030
    SCIP_RETCODE SCIPlpiGetNRows(SCIP_LPI *lpi, int *nrows)
    Definition: lpi_clp.cpp:1429
    SCIP_RETCODE SCIPlpiGetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
    Definition: lpi_clp.cpp:3417
    SCIP_Longint SCIPcalcGreComDiv(SCIP_Longint val1, SCIP_Longint val2)
    Definition: misc.c:9197
    SCIP_Bool SCIPrealIsExactlyIntegral(SCIP_Real val)
    Definition: misc.c:9604
    SCIP_Bool SCIPrealToRational(SCIP_Real val, SCIP_Real mindelta, SCIP_Real maxdelta, SCIP_Longint maxdnom, SCIP_Longint *numerator, SCIP_Longint *denominator)
    Definition: misc.c:9470
    SCIP_Real SCIPrelDiff(SCIP_Real val1, SCIP_Real val2)
    Definition: misc.c:11162
    void SCIPswapPointers(void **pointer1, void **pointer2)
    Definition: misc.c:10511
    SCIP_Real SCIPcolGetMinPrimsol(SCIP_COL *col)
    Definition: lp.c:17392
    int SCIPcolGetLPPos(SCIP_COL *col)
    Definition: lp.c:17487
    int SCIPcolGetVarProbindex(SCIP_COL *col)
    Definition: lp.c:17445
    SCIP_Bool SCIPcolIsRemovable(SCIP_COL *col)
    Definition: lp.c:17477
    SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
    Definition: lp.c:17425
    SCIP_Bool SCIPcolIsIntegral(SCIP_COL *col)
    Definition: lp.c:17455
    SCIP_Bool SCIPcolIsImpliedIntegral(SCIP_COL *col)
    Definition: lp.c:17466
    SCIP_Real SCIPcolGetObj(SCIP_COL *col)
    Definition: lp.c:17336
    int SCIPcolGetNNonz(SCIP_COL *col)
    Definition: lp.c:17520
    SCIP_Real * SCIPcolGetVals(SCIP_COL *col)
    Definition: lp.c:17555
    SCIP_ROW ** SCIPcolGetRows(SCIP_COL *col)
    Definition: lp.c:17545
    void SCIPcolSort(SCIP_COL *col)
    Definition: lp.c:3630
    int SCIPcolGetIndex(SCIP_COL *col)
    Definition: lp.c:17435
    SCIP_Real SCIPcolGetBestBound(SCIP_COL *col)
    Definition: lp.c:17366
    SCIP_Real SCIPcolGetLb(SCIP_COL *col)
    Definition: lp.c:17346
    SCIP_Real SCIPcolGetPrimsol(SCIP_COL *col)
    Definition: lp.c:17379
    SCIP_Real SCIPcolGetUb(SCIP_COL *col)
    Definition: lp.c:17356
    SCIP_Longint SCIPcolGetStrongbranchNode(SCIP_COL *col)
    Definition: lp.c:17567
    int SCIPcolGetNLPNonz(SCIP_COL *col)
    Definition: lp.c:17534
    int SCIPcolGetNStrongbranchs(SCIP_COL *col)
    Definition: lp.c:17577
    int SCIPcolGetAge(SCIP_COL *col)
    Definition: lp.c:17587
    SCIP_Bool SCIPcolIsInLP(SCIP_COL *col)
    Definition: lp.c:17509
    int SCIPcolGetLPDepth(SCIP_COL *col)
    Definition: lp.c:17498
    SCIP_BASESTAT SCIPcolGetBasisStatus(SCIP_COL *col)
    Definition: lp.c:17414
    SCIP_BOUNDTYPE SCIPboundtypeOpposite(SCIP_BOUNDTYPE boundtype)
    Definition: lp.c:17597
    SCIP_Real SCIPcolGetMaxPrimsol(SCIP_COL *col)
    Definition: lp.c:17402
    SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
    Definition: cons.c:8409
    SCIP_Real SCIPintervalGetInf(SCIP_INTERVAL interval)
    void SCIPintervalSub(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
    void SCIPintervalSet(SCIP_INTERVAL *resultant, SCIP_Real value)
    void SCIPintervalSetBounds(SCIP_INTERVAL *resultant, SCIP_Real inf, SCIP_Real sup)
    void SCIPintervalMul(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
    void SCIPintervalAdd(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
    void SCIPintervalSetRational(SCIP_INTERVAL *resultant, SCIP_RATIONAL *value)
    SCIP_Bool SCIPrationalIsFpRepresentable(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1710
    SCIP_Bool SCIProwIsIntegral(SCIP_ROW *row)
    Definition: lp.c:17785
    void SCIProwSort(SCIP_ROW *row)
    Definition: lp.c:6232
    SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
    Definition: lp.c:17686
    SCIP_Bool SCIProwIsModifiable(SCIP_ROW *row)
    Definition: lp.c:17805
    SCIP_Longint SCIProwGetActiveLPCount(SCIP_ROW *row)
    Definition: lp.c:17939
    SCIP_Real SCIProwGetOrthogonality(SCIP_ROW *row1, SCIP_ROW *row2, char orthofunc)
    Definition: lp.c:8034
    SCIP_Real SCIProwGetScalarProduct(SCIP_ROW *row1, SCIP_ROW *row2)
    Definition: lp.c:7254
    int SCIProwGetLPDepth(SCIP_ROW *row)
    Definition: lp.c:17906
    SCIP_Real SCIProwGetParallelism(SCIP_ROW *row1, SCIP_ROW *row2, char orthofunc)
    Definition: lp.c:7970
    SCIP_CONS * SCIProwGetOriginCons(SCIP_ROW *row)
    Definition: lp.c:17835
    int SCIProwGetNNonz(SCIP_ROW *row)
    Definition: lp.c:17607
    SCIP_COL ** SCIProwGetCols(SCIP_ROW *row)
    Definition: lp.c:17632
    SCIP_Bool SCIProwIsInGlobalCutpool(SCIP_ROW *row)
    Definition: lp.c:17885
    SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
    Definition: lp.c:17696
    int SCIProwGetAge(SCIP_ROW *row)
    Definition: lp.c:17765
    int SCIProwGetNLPNonz(SCIP_ROW *row)
    Definition: lp.c:17621
    SCIP_Real SCIProwGetNorm(SCIP_ROW *row)
    Definition: lp.c:17662
    int SCIProwGetLPPos(SCIP_ROW *row)
    Definition: lp.c:17895
    SCIP_Bool SCIProwIsLocal(SCIP_ROW *row)
    Definition: lp.c:17795
    SCIP_CONSHDLR * SCIProwGetOriginConshdlr(SCIP_ROW *row)
    Definition: lp.c:17850
    SCIP_Longint SCIProwGetNLPsAfterCreation(SCIP_ROW *row)
    Definition: lp.c:17949
    void SCIProwLock(SCIP_ROW *row)
    Definition: lp.c:5594
    SCIP_Bool SCIProwIsRemovable(SCIP_ROW *row)
    Definition: lp.c:17815
    const char * SCIProwGetName(SCIP_ROW *row)
    Definition: lp.c:17745
    SCIP_SEPA * SCIProwGetOriginSepa(SCIP_ROW *row)
    Definition: lp.c:17870
    void SCIProwUnlock(SCIP_ROW *row)
    Definition: lp.c:5609
    SCIP_Real SCIProwGetSumNorm(SCIP_ROW *row)
    Definition: lp.c:17674
    SCIP_DECL_SORTPTRCOMP(SCIProwComp)
    Definition: lp.c:1079
    int SCIProwGetRank(SCIP_ROW *row)
    Definition: lp.c:17775
    SCIP_Real SCIProwGetDualfarkas(SCIP_ROW *row)
    Definition: lp.c:17719
    int SCIProwGetIndex(SCIP_ROW *row)
    Definition: lp.c:17755
    void SCIProwChgRank(SCIP_ROW *row, int rank)
    Definition: lp.c:17928
    SCIP_Real SCIProwGetConstant(SCIP_ROW *row)
    Definition: lp.c:17652
    SCIP_ROWEXACT * SCIProwGetRowExact(SCIP_ROW *row)
    Definition: lp.c:17959
    SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
    Definition: lp.c:17917
    SCIP_Real SCIProwGetDualsol(SCIP_ROW *row)
    Definition: lp.c:17706
    SCIP_Real * SCIProwGetVals(SCIP_ROW *row)
    Definition: lp.c:17642
    SCIP_ROWORIGINTYPE SCIProwGetOrigintype(SCIP_ROW *row)
    Definition: lp.c:17825
    SCIP_BASESTAT SCIProwGetBasisStatus(SCIP_ROW *row)
    Definition: lp.c:17734
    SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
    Definition: var.c:23683
    SCIP_BOUNDTYPE SCIPvarGetBestBoundType(SCIP_VAR *var)
    Definition: var.c:24372
    SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
    Definition: var.c:23478
    SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
    Definition: var.c:23386
    SCIP_Bool SCIPvarIsImpliedIntegral(SCIP_VAR *var)
    Definition: var.c:23498
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24268
    int SCIPvarGetNLocksDown(SCIP_VAR *var)
    Definition: var.c:4449
    SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
    Definition: var.c:23900
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24142
    int SCIPvarGetProbindex(SCIP_VAR *var)
    Definition: var.c:23662
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23267
    SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
    Definition: var.c:23490
    SCIP_Real SCIPvarGetUbLazy(SCIP_VAR *var)
    Definition: var.c:24438
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24234
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24120
    int SCIPvarGetNLocksUp(SCIP_VAR *var)
    Definition: var.c:4462
    SCIP_Real SCIPvarGetNLPSol(SCIP_VAR *var)
    Definition: var.c:24691
    SCIP_RATIONAL * SCIPvarGetObjExact(SCIP_VAR *var)
    Definition: var.c:23910
    SCIP_Real SCIPvarGetUnchangedObj(SCIP_VAR *var)
    Definition: var.c:23932
    SCIP_Real SCIPvarGetLbLazy(SCIP_VAR *var)
    Definition: var.c:24428
    void SCIPsortPtrRealInt(void **ptrarray, SCIP_Real *realarray, int *intarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), int len)
    void SCIPsortIntPtrIntReal(int *intarray1, void **ptrarray, int *intarray2, SCIP_Real *realarray, int len)
    int SCIPsnprintf(char *t, int len, const char *s,...)
    Definition: misc.c:10827
    void SCIPprintSysError(const char *message)
    Definition: misc.c:10719
    interval arithmetics for provable bounds
    static SCIP_RETCODE lpFlushDelRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set)
    Definition: lp.c:8425
    static void rowCalcIdxsAndVals(SCIP_ROW *row, SCIP_SET *set)
    Definition: lp.c:5023
    SCIP_RETCODE SCIPlpCleanupNew(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_Bool root)
    Definition: lp.c:16231
    SCIP_Bool SCIPlpIsSolBasic(SCIP_LP *lp)
    Definition: lp.c:18241
    #define debugColPrint(x, y)
    Definition: lp.c:164
    static void getObjvalDeltaObj(SCIP_SET *set, SCIP_Real oldobj, SCIP_Real newobj, SCIP_Real lb, SCIP_Real ub, SCIP_Real *deltaval, int *deltainf)
    Definition: lp.c:13753
    static SCIP_RETCODE lpSetObjlim(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_Real objlim, SCIP_Bool *success)
    Definition: lp.c:2789
    static SCIP_RETCODE insertColChgcols(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp)
    Definition: lp.c:3814
    SCIP_Real SCIProwGetMaxval(SCIP_ROW *row, SCIP_SET *set)
    Definition: lp.c:6901
    SCIP_Real SCIProwGetRelaxEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
    Definition: lp.c:7170
    SCIP_RETCODE SCIPcolChgUb(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newub)
    Definition: lp.c:3997
    SCIP_Real SCIProwGetLPFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
    Definition: lp.c:6484
    SCIP_Real SCIPcolCalcRedcost(SCIP_COL *col, SCIP_Real *dualsol)
    Definition: lp.c:4042
    SCIP_RETCODE SCIPlpGetBInvRow(SCIP_LP *lp, int r, SCIP_Real *coef, int *inds, int *ninds)
    Definition: lp.c:10100
    static SCIP_RETCODE lpSetRefactorInterval(SCIP_LP *lp, int refactor, SCIP_Bool *success)
    Definition: lp.c:3446
    SCIP_Real SCIProwGetNLPFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
    Definition: lp.c:6566
    SCIP_RETCODE SCIPcolFree(SCIP_COL **col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
    Definition: lp.c:3572
    static SCIP_RETCODE lpSolveStable(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_LPALGO lpalgo, int itlim, int harditlim, SCIP_Bool resolve, int fastmip, SCIP_Bool tightprimfeastol, SCIP_Bool tightdualfeastol, SCIP_Bool fromscratch, int scaling, SCIP_Bool keepsol, SCIP_Bool *timelimit, SCIP_Bool *lperror)
    Definition: lp.c:11843
    void SCIProwCapture(SCIP_ROW *row)
    Definition: lp.c:5554
    SCIP_RETCODE SCIPlpFreeState(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
    Definition: lp.c:10350
    SCIP_Real SCIProwGetPseudoFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
    Definition: lp.c:6680
    SCIP_RETCODE SCIPlpUpdateAges(SCIP_LP *lp, SCIP_STAT *stat)
    Definition: lp.c:15622
    SCIP_RETCODE SCIPlpGetBInvCol(SCIP_LP *lp, int c, SCIP_Real *coef, int *inds, int *ninds)
    Definition: lp.c:10122
    SCIP_RETCODE SCIPcolChgLb(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newlb)
    Definition: lp.c:3952
    #define DIVESTACKGROWFACT
    Definition: lp.c:16672
    static SCIP_RETCODE lpSetTiming(SCIP_LP *lp, SCIP_CLOCKTYPE timing, SCIP_Bool enabled, SCIP_Bool *success)
    Definition: lp.c:3359
    SCIP_RETCODE SCIPlpInterrupt(SCIP_LP *lp, SCIP_Bool interrupt)
    Definition: lp.c:10367
    static SCIP_RETCODE lpLexDualSimplex(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool resolve, SCIP_Bool keepsol, SCIP_Bool *lperror)
    Definition: lp.c:10923
    static void rowDelNorms(SCIP_ROW *row, SCIP_SET *set, SCIP_COL *col, SCIP_Real val, SCIP_Bool forcenormupdate, SCIP_Bool updateindex, SCIP_Bool updateval)
    Definition: lp.c:2116
    SCIP_RETCODE SCIProwChgCoef(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_COL *col, SCIP_Real val)
    Definition: lp.c:5692
    static SCIP_RETCODE lpSetFromscratch(SCIP_LP *lp, SCIP_Bool fromscratch, SCIP_Bool *success)
    Definition: lp.c:3029
    static void colSortNonLP(SCIP_COL *col)
    Definition: lp.c:1131
    static SCIP_RETCODE ensureLpicolsSize(SCIP_LP *lp, SCIP_SET *set, int num)
    Definition: lp.c:219
    SCIP_Real SCIPcolCalcFarkasCoef(SCIP_COL *col, SCIP_Real *dualfarkas)
    Definition: lp.c:4225
    static void rowMoveCoef(SCIP_ROW *row, int oldpos, int newpos)
    Definition: lp.c:1493
    static SCIP_RETCODE lpSetFastmip(SCIP_LP *lp, int fastmip, SCIP_Bool *success)
    Definition: lp.c:3054
    SCIP_RETCODE SCIPlpGetNorms(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
    Definition: lp.c:10383
    static SCIP_RETCODE lpSetRealpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Real value, SCIP_Bool *success)
    Definition: lp.c:2689
    static SCIP_RETCODE lpCopyIntegrality(SCIP_LP *lp, SCIP_SET *set)
    Definition: lp.c:8869
    static SCIP_RETCODE lpStoreSolVals(SCIP_LP *lp, SCIP_STAT *stat, BMS_BLKMEM *blkmem)
    Definition: lp.c:381
    void SCIPlpMarkSize(SCIP_LP *lp)
    Definition: lp.c:10040
    static SCIP_RETCODE lpUpdateVarProved(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real oldlb, SCIP_Real oldub, SCIP_Real newobj, SCIP_Real newlb, SCIP_Real newub, SCIP_Bool global)
    Definition: lp.c:14042
    int SCIProwGetNumIntCols(SCIP_ROW *row, SCIP_SET *set)
    Definition: lp.c:6965
    static SCIP_RETCODE lpSetLPInfo(SCIP_LP *lp, SCIP_Bool lpinfo)
    Definition: lp.c:3286
    SCIP_RETCODE SCIPlpGetState(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
    Definition: lp.c:10283
    void SCIPlpRecalculateObjSqrNorm(SCIP_SET *set, SCIP_LP *lp)
    Definition: lp.c:18080
    static void lpUpdateObjNorms(SCIP_LP *lp, SCIP_SET *set, SCIP_Real oldobj, SCIP_Real newobj)
    Definition: lp.c:3857
    static SCIP_RETCODE lpRemoveObsoleteRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int firstrow)
    Definition: lp.c:15955
    int SCIPlpGetNNewcols(SCIP_LP *lp)
    Definition: lp.c:18047
    SCIP_Real SCIProwGetSolFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
    Definition: lp.c:6738
    void SCIProwRecalcPseudoActivity(SCIP_ROW *row, SCIP_STAT *stat)
    Definition: lp.c:6625
    SCIP_RETCODE SCIProwEnsureSize(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
    Definition: lp.c:636
    SCIP_Bool SCIPlpIsFeasPositive(SCIP_LP *lp, SCIP_Real val)
    Definition: lp.c:19319
    SCIP_Bool SCIPlpIsFeasGT(SCIP_SET *set, SCIP_LP *lp, SCIP_Real val1, SCIP_Real val2)
    Definition: lp.c:19268
    SCIP_RETCODE SCIPlpIsInfeasibilityProved(SCIP_LP *lp, SCIP_SET *set, SCIP_Bool *proved)
    Definition: lp.c:16889
    SCIP_Real SCIProwGetRelaxFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
    Definition: lp.c:6504
    SCIP_RETCODE SCIPlpAddCol(SCIP_LP *lp, SCIP_SET *set, SCIP_COL *col, int depth)
    Definition: lp.c:9699
    #define MAXNUMTROUBLELPMSGS
    Definition: lp.c:11752
    SCIP_Real SCIPlpGetLooseObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
    Definition: lp.c:13475
    SCIP_RETCODE SCIPlpSetState(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PROB *prob, SCIP_EVENTQUEUE *eventqueue, SCIP_LPISTATE *lpistate, SCIP_Bool wasprimfeas, SCIP_Bool wasprimchecked, SCIP_Bool wasdualfeas, SCIP_Bool wasdualchecked)
    Definition: lp.c:10307
    static SCIP_RETCODE colDelCoefPos(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, int pos)
    Definition: lp.c:1949
    static void colSwapCoefs(SCIP_COL *col, int pos1, int pos2)
    Definition: lp.c:1433
    static void rowCalcActivityBounds(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
    Definition: lp.c:6756
    SCIP_Real SCIPlpGetObjNorm(SCIP_LP *lp)
    Definition: lp.c:18111
    SCIP_Real SCIProwGetMaxActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
    Definition: lp.c:6849
    SCIP_RETCODE SCIProwMakeIntegral(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_STAT *stat, SCIP_LP *lp, SCIP_Real mindelta, SCIP_Real maxdelta, SCIP_Longint maxdnom, SCIP_Real maxscale, SCIP_Bool usecontvars, SCIP_Bool *success)
    Definition: lp.c:6197
    static SCIP_RETCODE lpSetPresolving(SCIP_LP *lp, SCIP_Bool presolving, SCIP_Bool *success)
    Definition: lp.c:3135
    SCIP_RETCODE SCIPlpRemoveNewObsoletes(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
    Definition: lp.c:16031
    SCIP_Bool SCIProwIsLPEfficacious(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_Bool root)
    Definition: lp.c:7095
    SCIP_Real SCIProwGetSolEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
    Definition: lp.c:7111
    static int colSearchCoefPart(SCIP_COL *col, const SCIP_ROW *row, int minpos, int maxpos)
    Definition: lp.c:1230
    SCIP_RETCODE SCIPlpStartStrongbranch(SCIP_LP *lp)
    Definition: lp.c:4375
    static int rowSearchCoefPart(SCIP_ROW *row, const SCIP_COL *col, int minpos, int maxpos)
    Definition: lp.c:1305
    SCIP_Bool SCIPlpDivingObjChanged(SCIP_LP *lp)
    Definition: lp.c:18261
    #define checkRowSumnorm(row)
    Definition: lp.c:776
    static int colSearchCoef(SCIP_COL *col, const SCIP_ROW *row)
    Definition: lp.c:1266
    SCIP_RETCODE SCIPlpFlush(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PROB *prob, SCIP_EVENTQUEUE *eventqueue)
    Definition: lp.c:8917
    static SCIP_RETCODE rowDelCoefPos(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, int pos)
    Definition: lp.c:2318
    SCIP_RETCODE SCIPlpUpdateVarLb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb)
    Definition: lp.c:14264
    void SCIPlpDecNLoosevars(SCIP_LP *lp)
    Definition: lp.c:14686
    static void rowSwapCoefs(SCIP_ROW *row, int pos1, int pos2)
    Definition: lp.c:1530
    SCIP_RETCODE SCIProwAddConstant(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_Real addval)
    Definition: lp.c:5856
    static SCIP_RETCODE rowChgCoefPos(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, int pos, SCIP_Real val)
    Definition: lp.c:2377
    static SCIP_RETCODE rowEventCoefChanged(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_COL *col, SCIP_Real oldval, SCIP_Real newval)
    Definition: lp.c:1595
    static SCIP_RETCODE lpAdjustObjlimForExactSolve(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_STAT *stat, SCIP_Bool *success)
    Definition: lp.c:2841
    static void recomputePseudoObjectiveValue(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
    Definition: lp.c:948
    void SCIPlpSetFeastol(SCIP_LP *lp, SCIP_SET *set, SCIP_Real newfeastol)
    Definition: lp.c:10509
    SCIP_RETCODE SCIPcolChgCoef(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_ROW *row, SCIP_Real val)
    Definition: lp.c:3708
    SCIP_RETCODE rowUnlink(SCIP_ROW *row, SCIP_SET *set, SCIP_LP *lp)
    Definition: lp.c:2611
    #define lpCutoffDisabled(set, prob, lp)
    Definition: lp.c:2782
    SCIP_RETCODE SCIPlpWrite(SCIP_LP *lp, const char *fname)
    Definition: lp.c:16911
    int SCIProwGetMaxidx(SCIP_ROW *row, SCIP_SET *set)
    Definition: lp.c:6933
    static void colSortLP(SCIP_COL *col)
    Definition: lp.c:1098
    static void adjustLPobjval(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr)
    Definition: lp.c:12260
    static SCIP_RETCODE lpFlushAddRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
    Definition: lp.c:8474
    SCIP_Real SCIPlpGetModifiedPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound, SCIP_BOUNDTYPE boundtype)
    Definition: lp.c:13711
    static int rowSearchCoef(SCIP_ROW *row, const SCIP_COL *col)
    Definition: lp.c:1344
    SCIP_Real SCIProwGetLPActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
    Definition: lp.c:6454
    void SCIProwMarkNotRemovableLocal(SCIP_ROW *row, SCIP_STAT *stat)
    Definition: lp.c:8124
    static SCIP_RETCODE lpSetPricing(SCIP_LP *lp, SCIP_PRICING pricing)
    Definition: lp.c:3221
    SCIP_RETCODE SCIPlpUpdateVarLbGlobal(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb)
    Definition: lp.c:14226
    static SCIP_RETCODE colRestoreSolVals(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_Longint validlp, SCIP_Bool freebuffer)
    Definition: lp.c:504
    SCIP_LPSOLSTAT SCIPlpGetSolstat(SCIP_LP *lp)
    Definition: lp.c:13420
    SCIP_RETCODE SCIPlpShrinkCols(SCIP_LP *lp, SCIP_SET *set, int newncols)
    Definition: lp.c:9883
    void SCIPlpStoreRootObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
    Definition: lp.c:13495
    static SCIP_RETCODE lpSetPricingChar(SCIP_LP *lp, char pricingchar)
    Definition: lp.c:3244
    SCIP_RETCODE SCIProwCreate(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, const char *name, int len, SCIP_COL **cols, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_ROWORIGINTYPE origintype, void *origin, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool removable)
    Definition: lp.c:5313
    static SCIP_RETCODE colStoreSolVals(SCIP_COL *col, BMS_BLKMEM *blkmem)
    Definition: lp.c:477
    static SCIP_RETCODE rowAddCoef(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_COL *col, SCIP_Real val, int linkpos)
    Definition: lp.c:2174
    SCIP_ROW ** SCIPlpGetNewrows(SCIP_LP *lp)
    Definition: lp.c:18058
    static SCIP_RETCODE ensureSoldirectionSize(SCIP_LP *lp, int num)
    Definition: lp.c:288
    void SCIPlpRecomputeLocalAndGlobalPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
    Definition: lp.c:13519
    static SCIP_RETCODE lpSetMarkowitz(SCIP_LP *lp, SCIP_Real threshhold, SCIP_Bool *success)
    Definition: lp.c:3334
    static void rowUpdateAddLP(SCIP_ROW *row)
    Definition: lp.c:9149
    static SCIP_RETCODE lpCheckIntpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, int value)
    Definition: lp.c:2717
    SCIP_Real SCIPlpGetColumnObjval(SCIP_LP *lp)
    Definition: lp.c:13464
    SCIP_RETCODE SCIPlpUpdateAddVar(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
    Definition: lp.c:14384
    SCIP_RETCODE SCIPlpClear(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
    Definition: lp.c:10021
    SCIP_Bool SCIPlpIsPrimalReliable(SCIP_LP *lp)
    Definition: lp.c:18221
    static SCIP_RETCODE colEnsureSize(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
    Definition: lp.c:354
    static void rowSortNonLP(SCIP_ROW *row)
    Definition: lp.c:1195
    void SCIPlpSetIsRelax(SCIP_LP *lp, SCIP_Bool relax)
    Definition: lp.c:18188
    static SCIP_RETCODE ensureChgcolsSize(SCIP_LP *lp, SCIP_SET *set, int num)
    Definition: lp.c:173
    SCIP_RETCODE SCIProwDelCoef(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_COL *col)
    Definition: lp.c:5646
    SCIP_RETCODE SCIPlpGetBase(SCIP_LP *lp, int *cstat, int *rstat)
    Definition: lp.c:10083
    SCIP_Bool SCIPlpIsRelax(SCIP_LP *lp)
    Definition: lp.c:18201
    #define FEASTOLTIGHTFAC
    Definition: lp.c:11840
    static SCIP_RETCODE rowEventConstantChanged(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_Real oldval, SCIP_Real newval)
    Definition: lp.c:1625
    void SCIPcolInvalidateStrongbranchData(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
    Definition: lp.c:4459
    static SCIP_RETCODE lpSolve(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_LPALGO lpalgo, int resolveitlim, int harditlim, SCIP_Bool needprimalray, SCIP_Bool needdualray, SCIP_Bool resolve, int fastmip, SCIP_Bool tightprimfeastol, SCIP_Bool tightdualfeastol, SCIP_Bool fromscratch, int scaling, SCIP_Bool keepsol, SCIP_Bool *lperror)
    Definition: lp.c:12291
    static int lpGetResolveItlim(SCIP_SET *set, SCIP_STAT *stat, int itlim)
    Definition: lp.c:12660
    SCIP_RETCODE SCIPlpSolveAndEval(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_PROB *prob, SCIP_Longint itlim, SCIP_Bool limitresolveiters, SCIP_Bool aging, SCIP_Bool keepsol, SCIP_Bool forcedlpsolve, SCIP_Bool *lperror)
    Definition: lp.c:12680
    SCIP_RETCODE SCIPcolGetStrongbranch(SCIP_COL *col, SCIP_Bool integral, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_LP *lp, int itlim, SCIP_Bool updatecol, SCIP_Bool updatestat, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Bool *lperror)
    Definition: lp.c:4494
    static SCIP_RETCODE lpCheckRealpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Real value)
    Definition: lp.c:2753
    SCIP_RETCODE SCIPcolDelCoef(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_ROW *row)
    Definition: lp.c:3663
    static void rowMerge(SCIP_ROW *row, SCIP_SET *set)
    Definition: lp.c:6265
    static void colMoveCoef(SCIP_COL *col, int oldpos, int newpos)
    Definition: lp.c:1397
    static SCIP_Bool isIntegralScalar(SCIP_Real val, SCIP_Real scalar, SCIP_Real mindelta, SCIP_Real maxdelta, SCIP_Real *intval)
    Definition: lp.c:5099
    SCIP_Real SCIPlpGetObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
    Definition: lp.c:13436
    static void computeLPBounds(SCIP_LP *lp, SCIP_SET *set, SCIP_COL *col, SCIP_Real lpiinf, SCIP_Real *lb, SCIP_Real *ub)
    Definition: lp.c:8216
    SCIP_RETCODE SCIPlpCleanupAll(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_Bool root)
    Definition: lp.c:16270
    void SCIProwRecalcLPActivity(SCIP_ROW *row, SCIP_STAT *stat)
    Definition: lp.c:6402
    static SCIP_Bool isNewValueUnreliable(SCIP_SET *set, SCIP_Real newvalue, SCIP_Real oldvalue)
    Definition: lp.c:3839
    static SCIP_RETCODE provedBound(SCIP_LP *lp, SCIP_SET *set, SCIP_Bool usefarkas, SCIP_Real *bound)
    Definition: lp.c:16765
    SCIP_Real SCIProwGetMinval(SCIP_ROW *row, SCIP_SET *set)
    Definition: lp.c:6917
    SCIP_RETCODE SCIPlpEndStrongbranch(SCIP_LP *lp)
    Definition: lp.c:4390
    SCIP_Longint SCIPcolGetStrongbranchLPAge(SCIP_COL *col, SCIP_STAT *stat)
    Definition: lp.c:4932
    static SCIP_RETCODE lpDelColset(SCIP_LP *lp, SCIP_SET *set, int *coldstat)
    Definition: lp.c:15682
    static SCIP_RETCODE lpRemoveObsoleteCols(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, int firstcol)
    Definition: lp.c:15879
    SCIP_Real SCIPlpGetRootObjval(SCIP_LP *lp)
    Definition: lp.c:18144
    static SCIP_RETCODE rowScale(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_STAT *stat, SCIP_LP *lp, SCIP_Real scaleval, SCIP_Bool integralcontvars, SCIP_Real minrounddelta, SCIP_Real maxrounddelta)
    Definition: lp.c:5139
    static SCIP_RETCODE ensureLazycolsSize(SCIP_LP *lp, SCIP_SET *set, int num)
    Definition: lp.c:308
    SCIP_Bool SCIPlpIsFeasGE(SCIP_SET *set, SCIP_LP *lp, SCIP_Real val1, SCIP_Real val2)
    Definition: lp.c:19288
    static SCIP_RETCODE ignoreInstability(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_LPALGO lpalgo, SCIP_Bool *success)
    Definition: lp.c:11814
    SCIP_RETCODE SCIPlpGetProvedLowerbound(SCIP_LP *lp, SCIP_SET *set, SCIP_Real *bound)
    Definition: lp.c:16875
    static void checkLazyColArray(SCIP_LP *lp, SCIP_SET *set)
    Definition: lp.c:9830
    SCIP_RETCODE SCIPcolChgObj(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newobj)
    Definition: lp.c:3893
    static void colUpdateAddLP(SCIP_COL *col, SCIP_SET *set)
    Definition: lp.c:9109
    SCIP_Real SCIProwGetLPSolCutoffDistance(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol, SCIP_LP *lp)
    Definition: lp.c:6997
    static SCIP_RETCODE lpSetRandomseed(SCIP_LP *lp, int randomseed, SCIP_Bool *success)
    Definition: lp.c:3393
    static SCIP_RETCODE rowRestoreSolVals(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_Longint validlp, SCIP_Bool freebuffer, SCIP_Bool infeasible)
    Definition: lp.c:588
    static SCIP_RETCODE ensureChgrowsSize(SCIP_LP *lp, SCIP_SET *set, int num)
    Definition: lp.c:196
    SCIP_Real SCIProwGetSolActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
    Definition: lp.c:6696
    static SCIP_RETCODE lpSetScaling(SCIP_LP *lp, int scaling, SCIP_Bool *success)
    Definition: lp.c:3085
    static SCIP_RETCODE colChgCoefPos(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, int pos, SCIP_Real val)
    Definition: lp.c:1994
    SCIP_RETCODE SCIPlpFree(SCIP_LP **lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
    Definition: lp.c:9619
    static SCIP_RETCODE lpSetIntpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, int value, SCIP_Bool *success)
    Definition: lp.c:2650
    void SCIPlpMarkDivingObjChanged(SCIP_LP *lp)
    Definition: lp.c:18271
    SCIP_COL ** SCIPlpGetNewcols(SCIP_LP *lp)
    Definition: lp.c:18036
    SCIP_RETCODE SCIPlpFreeNorms(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
    Definition: lp.c:10427
    static SCIP_RETCODE lpBarrier(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool crossover, SCIP_Bool keepsol, SCIP_Bool *lperror)
    Definition: lp.c:11532
    SCIP_RETCODE SCIProwAddCoef(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_COL *col, SCIP_Real val)
    Definition: lp.c:5625
    static void freeDiveChgSideArrays(SCIP_LP *lp)
    Definition: lp.c:9305
    SCIP_RETCODE SCIPlpGetBInvARow(SCIP_LP *lp, int r, SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
    Definition: lp.c:10148
    SCIP_LPI * SCIPlpGetLPI(SCIP_LP *lp)
    Definition: lp.c:18178
    SCIP_Bool SCIPlpIsFeasLT(SCIP_SET *set, SCIP_LP *lp, SCIP_Real val1, SCIP_Real val2)
    Definition: lp.c:19228
    static SCIP_RETCODE rowStoreSolVals(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_Bool infeasible)
    Definition: lp.c:551
    SCIP_RETCODE SCIProwIncCoef(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_COL *col, SCIP_Real incval)
    Definition: lp.c:5744
    static SCIP_RETCODE lpUpdateVarColumnProved(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
    Definition: lp.c:14476
    #define debugRowPrint(x, y)
    Definition: lp.c:131
    SCIP_RETCODE SCIPlpRemoveRedundantRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
    Definition: lp.c:16309
    SCIP_Bool SCIPlpDiving(SCIP_LP *lp)
    Definition: lp.c:18251
    static void rowUpdateDelLP(SCIP_ROW *row)
    Definition: lp.c:9223
    void SCIPlpUnmarkDivingObjChanged(SCIP_LP *lp)
    Definition: lp.c:18282
    SCIP_RETCODE SCIPlpGetBasisInd(SCIP_LP *lp, int *basisind)
    Definition: lp.c:10066
    SCIP_Real SCIProwGetNLPEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
    Definition: lp.c:7210
    SCIP_RETCODE SCIPlpSetNorms(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPINORMS *lpinorms)
    Definition: lp.c:10407
    SCIP_RETCODE SCIProwChgLocal(SCIP_ROW *row, SCIP_Bool local)
    Definition: lp.c:5946
    SCIP_RETCODE SCIPlpComputeRelIntPoint(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_LP *lp, SCIP_PROB *prob, SCIP_Bool relaxrows, SCIP_Bool inclobjcutoff, SCIP_Real timelimit, int iterlimit, SCIP_Real *point, SCIP_Bool *success)
    Definition: lp.c:19007
    #define DIVESTACKINITSIZE
    Definition: lp.c:9322
    SCIP_RETCODE SCIPlpGetDualDegeneracy(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real *degeneracy, SCIP_Real *varconsratio)
    Definition: lp.c:19079
    static SCIP_RETCODE lpSetBoolpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Bool value, SCIP_Bool *success)
    Definition: lp.c:2677
    static SCIP_RETCODE ensureColsSize(SCIP_LP *lp, SCIP_SET *set, int num)
    Definition: lp.c:265
    static void rowCalcNorms(SCIP_ROW *row, SCIP_SET *set)
    Definition: lp.c:4964
    SCIP_Real SCIProwGetLPEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
    Definition: lp.c:7054
    SCIP_RETCODE SCIPlpGetSol(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
    Definition: lp.c:14704
    static void markRowDeleted(SCIP_ROW *row)
    Definition: lp.c:8409
    void SCIProwRecalcNorms(SCIP_ROW *row, SCIP_SET *set)
    Definition: lp.c:6393
    static void rowAddNorms(SCIP_ROW *row, SCIP_SET *set, SCIP_COL *col, SCIP_Real val, SCIP_Bool updateidxvals)
    Definition: lp.c:2039
    static void lpUpdateObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real deltaval, int deltainf, SCIP_Bool local, SCIP_Bool loose, SCIP_Bool global)
    Definition: lp.c:13960
    static const int nscalars
    Definition: lp.c:5960
    void SCIPcolGetStrongbranchLast(SCIP_COL *col, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Real *solval, SCIP_Real *lpobjval)
    Definition: lp.c:4900
    SCIP_RETCODE SCIPcolAddCoef(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_ROW *row, SCIP_Real val)
    Definition: lp.c:3642
    static SCIP_RETCODE computeRelIntPoint(SCIP_LPI *lpi, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_LP *lp, SCIP_PROB *prob, SCIP_Bool relaxrows, SCIP_Bool inclobjcutoff, SCIP_Real timelimit, int iterlimit, SCIP_Real *point, SCIP_Bool *success)
    Definition: lp.c:18305
    SCIP_RETCODE SCIPcolIncCoef(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_ROW *row, SCIP_Real incval)
    Definition: lp.c:3759
    SCIP_Real SCIPlpGetRootLooseObjval(SCIP_LP *lp)
    Definition: lp.c:18168
    SCIP_RETCODE SCIPlpGetDualfarkas(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool forcedlpsolve, SCIP_Bool *valid)
    Definition: lp.c:15406
    void SCIProwPrint(SCIP_ROW *row, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
    Definition: lp.c:5514
    SCIP_RETCODE SCIPlpSetCutoffbound(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_Real cutoffbound)
    Definition: lp.c:10451
    SCIP_RETCODE SCIPlpRecordOldRowSideDive(SCIP_LP *lp, SCIP_ROW *row, SCIP_SIDETYPE sidetype)
    Definition: lp.c:16675
    static SCIP_RETCODE lpCleanupCols(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, int firstcol)
    Definition: lp.c:16093
    SCIP_RETCODE SCIPlpMarkFlushed(SCIP_LP *lp, SCIP_SET *set)
    Definition: lp.c:8981
    static SCIP_RETCODE lpAlgorithm(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_LPALGO lpalgo, SCIP_Bool resolve, SCIP_Bool keepsol, SCIP_Bool instable, SCIP_Bool *timelimit, SCIP_Bool *lperror)
    Definition: lp.c:11669
    SCIP_Real SCIPcolGetFeasibility(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
    Definition: lp.c:4171
    #define checkRowSqrnorm(row)
    Definition: lp.c:775
    SCIP_RETCODE SCIPlpShrinkRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int newnrows)
    Definition: lp.c:9955
    SCIP_Bool SCIProwIsRedundant(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
    Definition: lp.c:6870
    void SCIPlpStartStrongbranchProbing(SCIP_LP *lp)
    Definition: lp.c:16729
    static SCIP_RETCODE lpFlushDelCols(SCIP_LP *lp)
    Definition: lp.c:8165
    static SCIP_RETCODE lpSetRowrepswitch(SCIP_LP *lp, SCIP_Real rowrepswitch, SCIP_Bool *success)
    Definition: lp.c:3160
    SCIP_RETCODE SCIPlpGetIterations(SCIP_LP *lp, int *iterations)
    Definition: lp.c:15607
    static void recomputeLooseObjectiveValue(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
    Definition: lp.c:844
    static void colUpdateDelLP(SCIP_COL *col, SCIP_SET *set)
    Definition: lp.c:9184
    SCIP_RETCODE SCIProwChgConstant(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_Real constant)
    Definition: lp.c:5801
    SCIP_RETCODE SCIPlpStartProbing(SCIP_LP *lp)
    Definition: lp.c:16699
    SCIP_Real SCIPlpGetFeastol(SCIP_LP *lp)
    Definition: lp.c:10499
    static SCIP_RETCODE lpSetFeastol(SCIP_LP *lp, SCIP_Real feastol, SCIP_Bool *success)
    Definition: lp.c:2899
    SCIP_Bool SCIProwIsSolEfficacious(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol, SCIP_Bool root)
    Definition: lp.c:7154
    static SCIP_RETCODE lpUpdateVarColumn(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
    Definition: lp.c:14429
    SCIP_RETCODE SCIPlpUpdateDelVar(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
    Definition: lp.c:14405
    void SCIPlpEndStrongbranchProbing(SCIP_LP *lp)
    Definition: lp.c:16742
    SCIP_RETCODE SCIPlpGetBInvACol(SCIP_LP *lp, int c, SCIP_Real *coef, int *inds, int *ninds)
    Definition: lp.c:10173
    SCIP_Bool SCIPlpIsFeasZero(SCIP_LP *lp, SCIP_Real val)
    Definition: lp.c:19308
    static SCIP_RETCODE lpSetThreads(SCIP_LP *lp, int threads, SCIP_Bool *success)
    Definition: lp.c:3110
    SCIP_RETCODE SCIPlpRemoveAllObsoletes(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
    Definition: lp.c:16062
    static SCIP_RETCODE lpFlushChgCols(SCIP_LP *lp, SCIP_SET *set)
    Definition: lp.c:8622
    static SCIP_RETCODE lpUpdateVarLooseProved(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
    Definition: lp.c:14608
    SCIP_RETCODE SCIProwCatchEvent(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
    Definition: lp.c:8079
    SCIP_RETCODE colLink(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
    Definition: lp.c:2488
    SCIP_RETCODE SCIProwFree(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
    Definition: lp.c:5464
    static SCIP_Real getFiniteLooseObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
    Definition: lp.c:1034
    SCIP_Real SCIPcolGetFarkasValue(SCIP_COL *col, SCIP_STAT *stat, SCIP_LP *lp)
    Definition: lp.c:4356
    static SCIP_RETCODE lpDualSimplex(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool resolve, SCIP_Bool keepsol, SCIP_Bool instable, SCIP_Bool *lperror)
    Definition: lp.c:10732
    static const char * lpalgoName(SCIP_LPALGO lpalgo)
    Definition: lp.c:10551
    static void coefChanged(SCIP_ROW *row, SCIP_COL *col, SCIP_LP *lp)
    Definition: lp.c:1762
    static SCIP_RETCODE lpUpdateVarLoose(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
    Definition: lp.c:14563
    static void getObjvalDeltaUb(SCIP_SET *set, SCIP_Real obj, SCIP_Real oldub, SCIP_Real newub, SCIP_Real *deltaval, int *deltainf)
    Definition: lp.c:13922
    static SCIP_RETCODE lpRestoreSolVals(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_Longint validlp)
    Definition: lp.c:416
    static SCIP_RETCODE rowSideChanged(SCIP_ROW *row, SCIP_SET *set, SCIP_LP *lp, SCIP_SIDETYPE sidetype)
    Definition: lp.c:2436
    static void rowSortLP(SCIP_ROW *row)
    Definition: lp.c:1162
    static SCIP_Real colCalcInternalFarkasCoef(SCIP_COL *col)
    Definition: lp.c:4277
    SCIP_RETCODE colUnlink(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
    Definition: lp.c:2531
    SCIP_RETCODE SCIPlpCreate(SCIP_LP **lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, const char *name)
    Definition: lp.c:9325
    SCIP_Bool SCIPlpDivingRowsChanged(SCIP_LP *lp)
    Definition: lp.c:18293
    SCIP_RETCODE SCIPlpUpdateVarUbGlobal(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub)
    Definition: lp.c:14305
    static SCIP_RETCODE lpFlushAndSolve(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_EVENTQUEUE *eventqueue, int resolveitlim, int harditlim, SCIP_Bool needprimalray, SCIP_Bool needdualray, int fastmip, SCIP_Bool tightprimfeastol, SCIP_Bool tightdualfeastol, SCIP_Bool fromscratch, int scaling, SCIP_Bool keepsol, SCIP_Bool *lperror)
    Definition: lp.c:12480
    SCIP_RETCODE SCIPlpReset(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PROB *prob, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
    Definition: lp.c:9664
    static void recomputeSafeLooseObjectiveValue(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
    Definition: lp.c:789
    static SCIP_RETCODE lpCheckBoolpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Bool value)
    Definition: lp.c:2742
    SCIP_Real SCIPcolGetRedcost(SCIP_COL *col, SCIP_STAT *stat, SCIP_LP *lp)
    Definition: lp.c:4147
    SCIP_RETCODE SCIPlpEndProbing(SCIP_LP *lp)
    Definition: lp.c:16714
    SCIP_RETCODE SCIProwDropEvent(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
    Definition: lp.c:8103
    static SCIP_RETCODE colAddCoef(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_ROW *row, SCIP_Real val, int linkpos)
    Definition: lp.c:1827
    static SCIP_Real lpGetModifiedPseudoObjvalExact(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound, SCIP_BOUNDTYPE boundtype)
    Definition: lp.c:13652
    SCIP_RETCODE SCIPcolCreate(SCIP_COL **col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var, int len, SCIP_ROW **rows, SCIP_Real *vals, SCIP_Bool removable)
    Definition: lp.c:3473
    SCIP_Bool SCIPlpIsRootLPRelax(SCIP_LP *lp)
    Definition: lp.c:18134
    SCIP_Bool SCIPlpIsSolved(SCIP_LP *lp)
    Definition: lp.c:18211
    SCIP_RETCODE SCIPlpUpdateVarUb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub)
    Definition: lp.c:14343
    static SCIP_RETCODE lpSetConditionLimit(SCIP_LP *lp, SCIP_Real condlimit, SCIP_Bool *success)
    Definition: lp.c:3309
    SCIP_RETCODE SCIPlpUpdateVarObj(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
    Definition: lp.c:14166
    static void lpNumericalTroubleMessage(SCIP_MESSAGEHDLR *messagehdlr, SCIP_SET *set, SCIP_STAT *stat, SCIP_VERBLEVEL verblevel, const char *formatstr,...)
    Definition: lp.c:11761
    SCIP_Real SCIPcolGetFarkasCoef(SCIP_COL *col, SCIP_STAT *stat, SCIP_LP *lp)
    Definition: lp.c:4330
    SCIP_RETCODE SCIPlpUpdateVarLoose(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
    Definition: lp.c:14665
    SCIP_Real SCIPlpGetGlobalPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
    Definition: lp.c:13587
    static SCIP_RETCODE reallocDiveChgSideArrays(SCIP_LP *lp, int minsize, SCIP_Real growfact)
    Definition: lp.c:9279
    SCIP_Bool SCIPlpIsDualReliable(SCIP_LP *lp)
    Definition: lp.c:18231
    SCIP_RETCODE SCIPlpAddRow(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_ROW *row, int depth)
    Definition: lp.c:9759
    SCIP_RETCODE SCIPlpWriteMip(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, const char *fname, SCIP_Bool genericnames, SCIP_Bool origobj, SCIP_OBJSENSE objsense, SCIP_Real objscale, SCIP_Real objoffset, SCIP_Bool lazyconss)
    Definition: lp.c:16925
    static void getObjvalDeltaLb(SCIP_SET *set, SCIP_Real obj, SCIP_Real oldlb, SCIP_Real newlb, SCIP_Real *deltaval, int *deltainf)
    Definition: lp.c:13884
    int SCIProwGetMinidx(SCIP_ROW *row, SCIP_SET *set)
    Definition: lp.c:6949
    static SCIP_Real colCalcInternalRedcost(SCIP_COL *col)
    Definition: lp.c:4094
    static void recomputeSafePseudoObjectiveValue(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
    Definition: lp.c:895
    SCIP_RETCODE SCIPlpStartDive(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat)
    Definition: lp.c:16383
    SCIP_Bool SCIPlpIsFeasNegative(SCIP_LP *lp, SCIP_Real val)
    Definition: lp.c:19330
    SCIP_RETCODE SCIPlpEndDive(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_PROB *prob, SCIP_VAR **vars, int nvars)
    Definition: lp.c:16489
    SCIP_COL ** SCIPlpGetCols(SCIP_LP *lp)
    Definition: lp.c:17969
    int SCIPlpGetNCols(SCIP_LP *lp)
    Definition: lp.c:17979
    static SCIP_RETCODE lpSetBarrierconvtol(SCIP_LP *lp, SCIP_Real barrierconvtol, SCIP_Bool *success)
    Definition: lp.c:2985
    SCIP_RETCODE SCIProwChgRhs(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_Real rhs)
    Definition: lp.c:5914
    SCIP_Real SCIPlpGetRootColumnObjval(SCIP_LP *lp)
    Definition: lp.c:18156
    static SCIP_RETCODE rowEventSideChanged(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_SIDETYPE side, SCIP_Real oldval, SCIP_Real newval)
    Definition: lp.c:1653
    SCIP_RETCODE SCIPlpGetUnboundedSol(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *primalfeasible, SCIP_Bool *rayfeasible)
    Definition: lp.c:15019
    static SCIP_RETCODE lpSetDualfeastol(SCIP_LP *lp, SCIP_Real dualfeastol, SCIP_Bool *success)
    Definition: lp.c:2942
    SCIP_RETCODE SCIProwCalcIntegralScalar(SCIP_ROW *row, SCIP_SET *set, SCIP_Real mindelta, SCIP_Real maxdelta, SCIP_Longint maxdnom, SCIP_Real maxscale, SCIP_Bool usecontvars, SCIP_Real *intscalar, SCIP_Bool *success)
    Definition: lp.c:5963
    SCIP_Real SCIPlpGetCutoffbound(SCIP_LP *lp)
    Definition: lp.c:10441
    SCIP_Bool SCIPlpIsFeasEQ(SCIP_SET *set, SCIP_LP *lp, SCIP_Real val1, SCIP_Real val2)
    Definition: lp.c:19208
    static void markColDeleted(SCIP_COL *col)
    Definition: lp.c:8143
    SCIP_Real SCIProwGetPseudoActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
    Definition: lp.c:6652
    static void checkLazyBounds(SCIP_LP *lp, SCIP_SET *set)
    Definition: lp.c:12571
    static SCIP_RETCODE lpSetIterationLimit(SCIP_LP *lp, int itlim)
    Definition: lp.c:3185
    static SCIP_RETCODE ensureRowsSize(SCIP_LP *lp, SCIP_SET *set, int num)
    Definition: lp.c:331
    static SCIP_Real getFinitePseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
    Definition: lp.c:1056
    static SCIP_RETCODE allocDiveChgSideArrays(SCIP_LP *lp, int initsize)
    Definition: lp.c:9257
    SCIP_ROW ** SCIPlpGetRows(SCIP_LP *lp)
    Definition: lp.c:18016
    void SCIPlpSetRootLPIsRelax(SCIP_LP *lp, SCIP_Bool isrelax)
    Definition: lp.c:18123
    static SCIP_RETCODE ensureLpirowsSize(SCIP_LP *lp, SCIP_SET *set, int num)
    Definition: lp.c:242
    SCIP_RETCODE SCIProwChgLhs(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_Real lhs)
    Definition: lp.c:5882
    void SCIProwForceSort(SCIP_ROW *row, SCIP_SET *set)
    Definition: lp.c:6380
    void SCIPcolMarkNotRemovableLocal(SCIP_COL *col, SCIP_STAT *stat)
    Definition: lp.c:4944
    static SCIP_RETCODE updateLazyBounds(SCIP_LP *lp, SCIP_SET *set)
    Definition: lp.c:12598
    SCIP_RETCODE rowLink(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
    Definition: lp.c:2569
    int SCIPlpGetNUnfixedCols(SCIP_LP *lp, SCIP_Real eps)
    Definition: lp.c:17989
    SCIP_Real SCIProwGetMinActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
    Definition: lp.c:6828
    #define checkRowObjprod(row)
    Definition: lp.c:777
    static const SCIP_Real scalars[]
    Definition: lp.c:5959
    void SCIPcolSetStrongbranchData(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_Real lpobjval, SCIP_Real primsol, SCIP_Real sbdown, SCIP_Real sbup, SCIP_Bool sbdownvalid, SCIP_Bool sbupvalid, SCIP_Longint iter, int itlim)
    Definition: lp.c:4405
    SCIP_Bool SCIPlpIsFeasLE(SCIP_SET *set, SCIP_LP *lp, SCIP_Real val1, SCIP_Real val2)
    Definition: lp.c:19248
    int SCIPlpGetNNewrows(SCIP_LP *lp)
    Definition: lp.c:18069
    void SCIPlpResetFeastol(SCIP_LP *lp, SCIP_SET *set)
    Definition: lp.c:10534
    SCIP_RETCODE SCIPlpGetPrimalRay(SCIP_LP *lp, SCIP_SET *set, SCIP_Real *ray)
    Definition: lp.c:15345
    #define checkRow(row)
    Definition: lp.c:702
    int SCIProwGetNumImpliedIntCols(SCIP_ROW *row, SCIP_SET *set)
    Definition: lp.c:6981
    void SCIProwDelaySort(SCIP_ROW *row)
    Definition: lp.c:6369
    static SCIP_RETCODE lpSetSolutionPolishing(SCIP_LP *lp, SCIP_Bool polishing, SCIP_Bool *success)
    Definition: lp.c:3423
    void SCIPlpInvalidateRootObjval(SCIP_LP *lp)
    Definition: lp.c:13508
    int SCIPlpGetNRows(SCIP_LP *lp)
    Definition: lp.c:18026
    static SCIP_RETCODE lpFlushChgRows(SCIP_LP *lp, SCIP_SET *set)
    Definition: lp.c:8770
    static SCIP_RETCODE lpPrimalSimplex(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool resolve, SCIP_Bool keepsol, SCIP_Bool instable, SCIP_Bool *lperror)
    Definition: lp.c:10574
    SCIP_Real SCIProwGetObjParallelism(SCIP_ROW *row, SCIP_SET *set, SCIP_LP *lp)
    Definition: lp.c:8046
    static void recomputeGlbPseudoObjectiveValue(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
    Definition: lp.c:994
    SCIP_RETCODE SCIPlpSumRows(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_Real *weights, SCIP_REALARRAY *sumcoef, SCIP_Real *sumlhs, SCIP_Real *sumrhs)
    Definition: lp.c:10197
    SCIP_RETCODE SCIPcolGetStrongbranches(SCIP_COL **cols, int ncols, SCIP_Bool integral, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_LP *lp, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Bool *lperror)
    Definition: lp.c:4677
    static SCIP_RETCODE lpCleanupRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int firstrow)
    Definition: lp.c:16160
    SCIP_Real SCIPlpGetPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
    Definition: lp.c:13619
    static SCIP_RETCODE lpDelRowset(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int *rowdstat)
    Definition: lp.c:15781
    void SCIPlpSetSizeMark(SCIP_LP *lp, int nrows, int ncols)
    Definition: lp.c:10052
    static int SCIProwGetDiscreteScalarProduct(SCIP_ROW *row1, SCIP_ROW *row2)
    Definition: lp.c:7611
    SCIP_RETCODE SCIPlpUpdateVarColumn(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
    Definition: lp.c:14541
    SCIP_RETCODE SCIProwRelease(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
    Definition: lp.c:5567
    #define checkLinks(lp)
    Definition: lp.c:1753
    static SCIP_RETCODE lpFlushAddCols(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
    Definition: lp.c:8251
    void SCIPcolPrint(SCIP_COL *col, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
    Definition: lp.c:3602
    internal methods for LP management
    SCIP_RETCODE SCIProwExactRelease(SCIP_ROWEXACT **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LPEXACT *lpexact)
    Definition: lpexact.c:5583
    SCIP_Bool SCIPlpExactDiving(SCIP_LPEXACT *lpexact)
    Definition: lpexact.c:8423
    SCIP_RETCODE SCIPlpExactSetCutoffbound(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_Real cutoffbound)
    Definition: lpexact.c:4178
    void SCIPlpExactForceSafeBound(SCIP_LPEXACT *lpexact, SCIP_SET *set)
    Definition: lpexact.c:7614
    SCIP_RETCODE SCIPlpExactComputeSafeBound(SCIP_LP *lp, SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_PROB *prob, SCIP_Bool *lperror, SCIP_Bool usefarkas, SCIP_Real *safebound, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
    safe exact rational bounding methods
    interface methods for specific LP solvers
    interface methods for specific exact LP solvers
    #define BMSduplicateBlockMemoryArray(mem, ptr, source, num)
    Definition: memory.h:462
    #define BMSfreeMemory(ptr)
    Definition: memory.h:145
    #define BMSfreeBlockMemory(mem, ptr)
    Definition: memory.h:465
    #define BMSallocBlockMemory(mem, ptr)
    Definition: memory.h:451
    #define BMSreallocMemoryArray(ptr, num)
    Definition: memory.h:127
    #define BMSfreeBlockMemoryArrayNull(mem, ptr, num)
    Definition: memory.h:468
    #define BMSfreeMemoryNull(ptr)
    Definition: memory.h:146
    #define BMSallocMemoryArray(ptr, num)
    Definition: memory.h:123
    #define BMSallocBlockMemoryArray(mem, ptr, num)
    Definition: memory.h:454
    #define BMSfreeBlockMemoryNull(mem, ptr)
    Definition: memory.h:466
    #define BMSfreeBlockMemoryArray(mem, ptr, num)
    Definition: memory.h:467
    #define BMSreallocBlockMemoryArray(mem, ptr, oldnum, newnum)
    Definition: memory.h:458
    #define BMSclearMemoryArray(ptr, num)
    Definition: memory.h:130
    struct BMS_BlkMem BMS_BLKMEM
    Definition: memory.h:437
    #define BMSfreeMemoryArrayNull(ptr)
    Definition: memory.h:148
    #define BMSallocMemory(ptr)
    Definition: memory.h:118
    void SCIPmessageFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr,...)
    Definition: message.c:618
    void SCIPmessageVFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr, va_list ap)
    Definition: message.c:633
    void SCIPmessagePrintInfo(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
    Definition: message.c:594
    void SCIPmessagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
    Definition: message.c:427
    void SCIPmessagePrintVerbInfo(SCIP_MESSAGEHDLR *messagehdlr, SCIP_VERBLEVEL verblevel, SCIP_VERBLEVEL msgverblevel, const char *formatstr,...)
    Definition: message.c:678
    SCIP_RETCODE SCIPrealarrayExtend(SCIP_REALARRAY *realarray, int arraygrowinit, SCIP_Real arraygrowfac, int minidx, int maxidx)
    Definition: misc.c:4131
    SCIP_RETCODE SCIPrealarrayIncVal(SCIP_REALARRAY *realarray, int arraygrowinit, SCIP_Real arraygrowfac, int idx, SCIP_Real incval)
    Definition: misc.c:4407
    SCIP_RETCODE SCIPrealarrayClear(SCIP_REALARRAY *realarray)
    Definition: misc.c:4286
    internal miscellaneous methods
    SCIP_Longint denominator(Rational &r)
    SCIP_Longint numerator(Rational &r)
    real eps
    SCIP_Bool SCIPprobAllColsInLP(SCIP_PROB *prob, SCIP_SET *set, SCIP_LP *lp)
    Definition: prob.c:2825
    internal methods for storing and manipulating the main problem
    public methods for LP management
    public methods for LP management
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    #define SCIPdebug(x)
    Definition: pub_message.h:93
    #define SCIPdebugMessage
    Definition: pub_message.h:96
    public data structures and miscellaneous methods
    #define SCIPisFinite(x)
    Definition: pub_misc.h:82
    methods for sorting joint arrays of various types
    public methods for problem variables
    SCIP_Bool SCIPsetIsDualfeasZero(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:7292
    SCIP_Bool SCIPsetIsEfficacious(SCIP_SET *set, SCIP_Bool root, SCIP_Real efficacy)
    Definition: set.c:7447
    SCIP_Bool SCIPsetIsFeasPositive(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:7076
    SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6617
    SCIP_RETCODE SCIPsetGetCharParam(SCIP_SET *set, const char *name, char *value)
    Definition: set.c:3424
    SCIP_Real SCIPsetSumFloor(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6897
    SCIP_Bool SCIPsetIsFeasNegative(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:7087
    SCIP_Real SCIPsetFeastol(SCIP_SET *set)
    Definition: set.c:6422
    SCIP_Bool SCIPsetIsDualfeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:7196
    SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:7017
    SCIP_Bool SCIPsetIsFeasLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6993
    SCIP_Bool SCIPsetIsFeasEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6945
    SCIP_Bool SCIPsetIsPositive(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6648
    SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6577
    SCIP_Real SCIPsetRelaxfeastol(SCIP_SET *set)
    Definition: set.c:6494
    SCIP_Bool SCIPsetIsSumLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6804
    SCIP_Bool SCIPsetIsDualfeasNegative(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:7314
    SCIP_Real SCIPsetDualfeastol(SCIP_SET *set)
    Definition: set.c:6432
    SCIP_Bool SCIPsetIsSumGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6844
    SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6537
    SCIP_Bool SCIPsetIsFeasZero(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:7065
    SCIP_Bool SCIPsetIsFeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6969
    SCIP_RETCODE SCIPsetSetCharParam(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, const char *name, char value)
    Definition: set.c:3669
    SCIP_Real SCIPsetLPFeastolFactor(SCIP_SET *set)
    Definition: set.c:6442
    SCIP_Real SCIPsetInfinity(SCIP_SET *set)
    Definition: set.c:6380
    SCIP_Real SCIPsetSumepsilon(SCIP_SET *set)
    Definition: set.c:6412
    SCIP_Bool SCIPsetIsLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6557
    SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6515
    SCIP_Bool SCIPsetIsSumZero(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6864
    SCIP_Bool SCIPsetIsRelGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:7559
    SCIP_Bool SCIPsetIsDualfeasPositive(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:7303
    SCIP_Bool SCIPsetIsDualfeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:7244
    SCIP_Bool SCIPsetIsGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6597
    SCIP_Bool SCIPsetIsSumEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6764
    SCIP_Bool SCIPsetIsIntegral(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6670
    SCIP_Bool SCIPsetIsZero(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6637
    SCIP_Bool SCIPsetIsUpdateUnreliable(SCIP_SET *set, SCIP_Real newvalue, SCIP_Real oldvalue)
    Definition: set.c:7723
    SCIP_Real SCIPsetSumCeil(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6909
    SCIP_Bool SCIPsetIsFeasGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:7041
    SCIP_Real SCIPsetBarrierconvtol(SCIP_SET *set)
    Definition: set.c:6450
    SCIP_Real SCIPsetRound(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6740
    int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
    Definition: set.c:6080
    SCIP_Bool SCIPsetIsFeasIntegral(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:7098
    SCIP_Bool SCIPsetIsNegative(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6659
    unsigned int SCIPsetInitializeRandomSeed(SCIP_SET *set, unsigned int initialseedvalue)
    Definition: set.c:7800
    internal methods for global SCIP settings
    #define SCIPsetFreeBufferArray(set, ptr)
    Definition: set.h:1782
    #define SCIPsetDebugMsgPrint
    Definition: set.h:1812
    #define SCIPsetAllocBufferArray(set, ptr, num)
    Definition: set.h:1775
    #define SCIPsetDebugMsg
    Definition: set.h:1811
    SCIP_Real SCIPsolGetVal(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var)
    Definition: sol.c: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
    #define SCIPstatUpdate(stat, set, field, val)
    Definition: stat.h:239
    SCIP_Real primsol
    Definition: struct_lp.h:96
    unsigned int basisstatus
    Definition: struct_lp.h:98
    SCIP_Real redcost
    Definition: struct_lp.h:97
    SCIP_Real lb
    Definition: struct_lp.h:140
    SCIP_Real maxprimsol
    Definition: struct_lp.h:154
    SCIP_Real ub
    Definition: struct_lp.h:141
    unsigned int lbchanged
    Definition: struct_lp.h:185
    SCIP_ROW ** rows
    Definition: struct_lp.h:163
    unsigned int objchanged
    Definition: struct_lp.h:184
    int lpdepth
    Definition: struct_lp.h:176
    int nlprows
    Definition: struct_lp.h:172
    SCIP_Real sbsolval
    Definition: struct_lp.h:157
    SCIP_Real sbdown
    Definition: struct_lp.h:155
    SCIP_Real sbup
    Definition: struct_lp.h:156
    SCIP_Real lazylb
    Definition: struct_lp.h:143
    SCIP_COLSOLVALS * storedsolvals
    Definition: struct_lp.h:161
    unsigned int basisstatus
    Definition: struct_lp.h:181
    SCIP_Real redcost
    Definition: struct_lp.h:151
    SCIP_Real lazyub
    Definition: struct_lp.h:145
    SCIP_Real minprimsol
    Definition: struct_lp.h:153
    SCIP_Real sblpobjval
    Definition: struct_lp.h:158
    SCIP_Real flushedobj
    Definition: struct_lp.h:147
    int len
    Definition: struct_lp.h:171
    unsigned int coefchanged
    Definition: struct_lp.h:187
    SCIP_Real flushedlb
    Definition: struct_lp.h:148
    unsigned int removable
    Definition: struct_lp.h:190
    unsigned int impliedintegral
    Definition: struct_lp.h:189
    SCIP_Real farkascoef
    Definition: struct_lp.h:152
    unsigned int sbupvalid
    Definition: struct_lp.h:193
    SCIP_Longint obsoletenode
    Definition: struct_lp.h:160
    unsigned int lprowssorted
    Definition: struct_lp.h:182
    SCIP_Longint validredcostlp
    Definition: struct_lp.h:165
    int lppos
    Definition: struct_lp.h:174
    int age
    Definition: struct_lp.h:179
    SCIP_Real flushedub
    Definition: struct_lp.h:149
    unsigned int nonlprowssorted
    Definition: struct_lp.h:183
    int nsbcalls
    Definition: struct_lp.h:178
    int * linkpos
    Definition: struct_lp.h:168
    SCIP_Real * vals
    Definition: struct_lp.h:164
    unsigned int ubchanged
    Definition: struct_lp.h:186
    SCIP_Real primsol
    Definition: struct_lp.h:150
    SCIP_Longint validfarkaslp
    Definition: struct_lp.h:166
    int nunlinked
    Definition: struct_lp.h:173
    int lpipos
    Definition: struct_lp.h:175
    unsigned int integral
    Definition: struct_lp.h:188
    SCIP_Longint validsblp
    Definition: struct_lp.h:167
    int size
    Definition: struct_lp.h:170
    int sbitlim
    Definition: struct_lp.h:177
    SCIP_Longint sbnode
    Definition: struct_lp.h:159
    SCIP_Real obj
    Definition: struct_lp.h:139
    int index
    Definition: struct_lp.h:169
    unsigned int sbdownvalid
    Definition: struct_lp.h:191
    SCIP_Real unchangedobj
    Definition: struct_lp.h:142
    SCIP_VAR * var
    Definition: struct_lp.h:162
    int var_probindex
    Definition: struct_lp.h:180
    SCIP_EVENTTYPE eventmask
    Definition: struct_event.h:211
    SCIP_Real sup
    Definition: intervalarith.h:57
    SCIP_Real inf
    Definition: intervalarith.h:56
    SCIP_Bool wasforcedsafebound
    SCIP_LPIEXACT * lpiexact
    SCIP_Real oldcutoffbound
    SCIP_Bool dualchecked
    Definition: struct_lp.h:124
    SCIP_Bool solisbasic
    Definition: struct_lp.h:125
    SCIP_Bool dualfeasible
    Definition: struct_lp.h:123
    SCIP_Bool primalfeasible
    Definition: struct_lp.h:121
    SCIP_Bool primalchecked
    Definition: struct_lp.h:122
    SCIP_Real lpobjval
    Definition: struct_lp.h:120
    SCIP_Bool lpissolved
    Definition: struct_lp.h:126
    SCIP_Bool hasprovedboundexact
    Definition: struct_lp.h:127
    SCIP_LPSOLSTAT lpsolstat
    Definition: struct_lp.h:119
    SCIP_Bool glbpseudoobjvalid
    Definition: struct_lp.h:365
    SCIP_Real * divechgsides
    Definition: struct_lp.h:312
    SCIP_ROW ** rows
    Definition: struct_lp.h:308
    SCIP_Real feastol
    Definition: struct_lp.h:290
    SCIP_Real lpirowrepswitch
    Definition: struct_lp.h:403
    SCIP_Real objsumnorm
    Definition: struct_lp.h:298
    SCIP_Longint validsoldirlp
    Definition: struct_lp.h:319
    SCIP_Real pseudoobjval
    Definition: struct_lp.h:284
    SCIP_Real relglbpseudoobjval
    Definition: struct_lp.h:283
    int glbpseudoobjvalinf
    Definition: struct_lp.h:345
    SCIP_Real objsqrnorm
    Definition: struct_lp.h:297
    SCIP_Bool flushaddedcols
    Definition: struct_lp.h:368
    SCIP_ROW ** lpirows
    Definition: struct_lp.h:303
    SCIP_SIDETYPE * divechgsidetypes
    Definition: struct_lp.h:313
    int lpicolssize
    Definition: struct_lp.h:322
    int lpiitlim
    Definition: struct_lp.h:351
    SCIP_Bool strongbranching
    Definition: struct_lp.h:383
    SCIP_Bool probing
    Definition: struct_lp.h:384
    SCIP_Real rellooseobjval
    Definition: struct_lp.h:279
    SCIP_Bool updateintegrality
    Definition: struct_lp.h:371
    SCIP_Bool isrelax
    Definition: struct_lp.h:380
    SCIP_Bool lpipresolving
    Definition: struct_lp.h:392
    int lpirefactorinterval
    Definition: struct_lp.h:357
    SCIP_Real varconsratio
    Definition: struct_lp.h:300
    int lpifirstchgrow
    Definition: struct_lp.h:327
    SCIP_Bool lpifromscratch
    Definition: struct_lp.h:391
    SCIP_Bool objsqrnormunreliable
    Definition: struct_lp.h:361
    SCIP_Bool primalfeasible
    Definition: struct_lp.h:374
    SCIP_Real lpiconditionlimit
    Definition: struct_lp.h:295
    SCIP_COL ** cols
    Definition: struct_lp.h:306
    SCIP_LPALGO lastlpalgo
    Definition: struct_lp.h:360
    int lpifirstchgcol
    Definition: struct_lp.h:324
    int divinglpiitlim
    Definition: struct_lp.h:350
    int nlazycols
    Definition: struct_lp.h:336
    SCIP_Real rootlpobjval
    Definition: struct_lp.h:287
    SCIP_Real * soldirection
    Definition: struct_lp.h:310
    int rowssize
    Definition: struct_lp.h:339
    int ncols
    Definition: struct_lp.h:334
    SCIP_Real cutoffbound
    Definition: struct_lp.h:289
    SCIP_Bool strongbranchprobing
    Definition: struct_lp.h:385
    int nremovablerows
    Definition: struct_lp.h:341
    SCIP_Real lpidualfeastol
    Definition: struct_lp.h:293
    SCIP_Bool installing
    Definition: struct_lp.h:382
    SCIP_Real rootlooseobjval
    Definition: struct_lp.h:288
    SCIP_LPEXACT * lpexact
    Definition: struct_lp.h:309
    SCIP_Bool dualfeasible
    Definition: struct_lp.h:376
    int nchgrows
    Definition: struct_lp.h:331
    int firstnewcol
    Definition: struct_lp.h:338
    int lpithreads
    Definition: struct_lp.h:353
    SCIP_Bool solisbasic
    Definition: struct_lp.h:378
    SCIP_Bool divelpwasdualfeas
    Definition: struct_lp.h:407
    SCIP_Bool rootlpisrelax
    Definition: struct_lp.h:379
    SCIP_Bool lpisolutionpolishing
    Definition: struct_lp.h:363
    SCIP_PRICING lpipricing
    Definition: struct_lp.h:358
    SCIP_Real looseobjval
    Definition: struct_lp.h:277
    SCIP_Bool divelpwasprimchecked
    Definition: struct_lp.h:406
    SCIP_Bool flushaddedrows
    Definition: struct_lp.h:370
    SCIP_COL ** chgcols
    Definition: struct_lp.h:304
    int nrows
    Definition: struct_lp.h:340
    SCIP_Bool primalchecked
    Definition: struct_lp.h:375
    SCIP_LPSOLVALS * storedsolvals
    Definition: struct_lp.h:315
    int lpiscaling
    Definition: struct_lp.h:356
    int lpirandomseed
    Definition: struct_lp.h:355
    int lpifastmip
    Definition: struct_lp.h:352
    SCIP_LPISTATE * divelpistate
    Definition: struct_lp.h:311
    SCIP_Real lpifeastol
    Definition: struct_lp.h:292
    SCIP_Longint validsollp
    Definition: struct_lp.h:317
    SCIP_Bool lpihasfastmip
    Definition: struct_lp.h:397
    SCIP_SOL * validsoldirsol
    Definition: struct_lp.h:316
    SCIP_Bool divingobjchg
    Definition: struct_lp.h:387
    int ndivechgsides
    Definition: struct_lp.h:348
    int lazycolssize
    Definition: struct_lp.h:335
    SCIP_ROW ** chgrows
    Definition: struct_lp.h:305
    SCIP_Real lpimarkowitz
    Definition: struct_lp.h:296
    int firstnewrow
    Definition: struct_lp.h:342
    int ndivingrows
    Definition: struct_lp.h:347
    SCIP_Bool lpilpinfo
    Definition: struct_lp.h:393
    SCIP_Real relpseudoobjval
    Definition: struct_lp.h:286
    SCIP_LPSOLSTAT lpsolstat
    Definition: struct_lp.h:359
    int colssize
    Definition: struct_lp.h:332
    SCIP_Real lpibarrierconvtol
    Definition: struct_lp.h:294
    SCIP_ROW ** divechgrows
    Definition: struct_lp.h:314
    int nloosevars
    Definition: struct_lp.h:344
    int chgrowssize
    Definition: struct_lp.h:330
    SCIP_Longint validdegeneracylp
    Definition: struct_lp.h:320
    int nlpicols
    Definition: struct_lp.h:323
    SCIP_Real lpobjval
    Definition: struct_lp.h:276
    int nlpirows
    Definition: struct_lp.h:326
    int chgcolssize
    Definition: struct_lp.h:328
    SCIP_Longint divenolddomchgs
    Definition: struct_lp.h:321
    int pseudoobjvalinf
    Definition: struct_lp.h:346
    SCIP_Bool solved
    Definition: struct_lp.h:373
    SCIP_Bool divinglazyapplied
    Definition: struct_lp.h:388
    int lpitiming
    Definition: struct_lp.h:354
    SCIP_Bool resolvelperror
    Definition: struct_lp.h:389
    SCIP_Bool dualchecked
    Definition: struct_lp.h:377
    SCIP_Bool divelpwasdualchecked
    Definition: struct_lp.h:408
    SCIP_Bool pseudoobjvalid
    Definition: struct_lp.h:366
    int nchgcols
    Definition: struct_lp.h:329
    SCIP_Longint validfarkaslp
    Definition: struct_lp.h:318
    SCIP_Bool looseobjvalid
    Definition: struct_lp.h:364
    SCIP_Bool adjustlpval
    Definition: struct_lp.h:390
    SCIP_Bool diving
    Definition: struct_lp.h:386
    SCIP_Bool hasprovedbound
    Definition: struct_lp.h:409
    SCIP_Real glbpseudoobjval
    Definition: struct_lp.h:281
    int divechgsidessize
    Definition: struct_lp.h:349
    SCIP_Bool lpihaspolishing
    Definition: struct_lp.h:401
    SCIP_COL ** lpicols
    Definition: struct_lp.h:302
    int lpirowssize
    Definition: struct_lp.h:325
    int nremovablecols
    Definition: struct_lp.h:337
    SCIP_LPI * lpi
    Definition: struct_lp.h:301
    SCIP_Bool flushdeletedrows
    Definition: struct_lp.h:369
    int looseobjvalinf
    Definition: struct_lp.h:343
    int soldirectionsize
    Definition: struct_lp.h:333
    SCIP_COL ** lazycols
    Definition: struct_lp.h:307
    SCIP_Real degeneracy
    Definition: struct_lp.h:299
    SCIP_Bool flushed
    Definition: struct_lp.h:372
    SCIP_Bool divelpwasprimfeas
    Definition: struct_lp.h:405
    SCIP_Real lpiobjlim
    Definition: struct_lp.h:291
    SCIP_Bool flushdeletedcols
    Definition: struct_lp.h:367
    SCIP_VAR ** vars
    Definition: struct_prob.h:67
    SCIP_ROW * fprow
    SCIP_Real activity
    Definition: struct_lp.h:109
    unsigned int basisstatus
    Definition: struct_lp.h:110
    SCIP_Real dualsol
    Definition: struct_lp.h:108
    SCIP_Longint nlpsaftercreation
    Definition: struct_lp.h:226
    int rank
    Definition: struct_lp.h:253
    unsigned int basisstatus
    Definition: struct_lp.h:255
    int nlpcols
    Definition: struct_lp.h:240
    SCIP_Real minactivity
    Definition: struct_lp.h:220
    SCIP_Longint activeinlpcounter
    Definition: struct_lp.h:225
    unsigned int lpcolssorted
    Definition: struct_lp.h:256
    unsigned int inglobalcutpool
    Definition: struct_lp.h:267
    SCIP_Real rhs
    Definition: struct_lp.h:208
    SCIP_Real maxactivity
    Definition: struct_lp.h:221
    int nunlinked
    Definition: struct_lp.h:241
    SCIP_Real dualfarkas
    Definition: struct_lp.h:218
    int lppos
    Definition: struct_lp.h:243
    SCIP_Longint obsoletenode
    Definition: struct_lp.h:224
    unsigned int delaysort
    Definition: struct_lp.h:258
    SCIP_Real flushedrhs
    Definition: struct_lp.h:210
    int index
    Definition: struct_lp.h:237
    unsigned int lhschanged
    Definition: struct_lp.h:260
    int size
    Definition: struct_lp.h:238
    unsigned int nonlpcolssorted
    Definition: struct_lp.h:257
    char * name
    Definition: struct_lp.h:229
    unsigned int origintype
    Definition: struct_lp.h:270
    SCIP_Real * vals
    Definition: struct_lp.h:232
    unsigned int validminmaxidx
    Definition: struct_lp.h:259
    unsigned int removable
    Definition: struct_lp.h:266
    int numintcols
    Definition: struct_lp.h:248
    unsigned int local
    Definition: struct_lp.h:264
    SCIP_Real maxval
    Definition: struct_lp.h:214
    SCIP_Longint validpsactivitydomchg
    Definition: struct_lp.h:222
    SCIP_Real flushedlhs
    Definition: struct_lp.h:209
    int numminval
    Definition: struct_lp.h:251
    SCIP_Longint validactivitybdsdomchg
    Definition: struct_lp.h:223
    SCIP_Real lhs
    Definition: struct_lp.h:207
    int lpipos
    Definition: struct_lp.h:244
    int maxidx
    Definition: struct_lp.h:247
    int * linkpos
    Definition: struct_lp.h:233
    SCIP_Real sqrnorm
    Definition: struct_lp.h:211
    SCIP_COL ** cols
    Definition: struct_lp.h:230
    SCIP_ROWEXACT * rowexact
    Definition: struct_lp.h:235
    SCIP_Real objprod
    Definition: struct_lp.h:213
    unsigned int integral
    Definition: struct_lp.h:263
    int nummaxval
    Definition: struct_lp.h:250
    void * origin
    Definition: struct_lp.h:228
    SCIP_Real constant
    Definition: struct_lp.h:206
    SCIP_ROWSOLVALS * storedsolvals
    Definition: struct_lp.h:227
    unsigned int coefchanged
    Definition: struct_lp.h:262
    SCIP_Real activity
    Definition: struct_lp.h:217
    SCIP_EVENTFILTER * eventfilter
    Definition: struct_lp.h:234
    SCIP_Real minval
    Definition: struct_lp.h:215
    SCIP_Real pseudoactivity
    Definition: struct_lp.h:219
    SCIP_Real sumnorm
    Definition: struct_lp.h:212
    int * cols_index
    Definition: struct_lp.h:231
    int minidx
    Definition: struct_lp.h:246
    unsigned int rhschanged
    Definition: struct_lp.h:261
    int age
    Definition: struct_lp.h:252
    SCIP_Real dualsol
    Definition: struct_lp.h:216
    int lpdepth
    Definition: struct_lp.h:245
    unsigned int modifiable
    Definition: struct_lp.h:265
    unsigned int nlocks
    Definition: struct_lp.h:269
    SCIP_Longint validactivitylp
    Definition: struct_lp.h:236
    int nuses
    Definition: struct_lp.h:242
    int numimplintcols
    Definition: struct_lp.h:249
    int len
    Definition: struct_lp.h:239
    SCIP_STATUS status
    Definition: struct_stat.h:201
    SCIP_Longint ndualresolvelpiterations
    Definition: struct_stat.h:72
    SCIP_Longint nprimalresolvelpiterations
    Definition: struct_stat.h:71
    SCIP_Longint nprimallps
    Definition: struct_stat.h:209
    SCIP_Real boundingerrorps
    Definition: struct_stat.h:164
    SCIP_Longint nnodes
    Definition: struct_stat.h:84
    SCIP_Longint nboundshift
    Definition: struct_stat.h:236
    SCIP_CLOCK * strongbranchtime
    Definition: struct_stat.h:178
    SCIP_CLOCK * barrierlptime
    Definition: struct_stat.h:175
    SCIP_Longint nduallps
    Definition: struct_stat.h:211
    SCIP_Longint nduallpiterations
    Definition: struct_stat.h:68
    int nclockskipsleft
    Definition: struct_stat.h:311
    SCIP_Longint nlps
    Definition: struct_stat.h:207
    SCIP_Longint ndualresolvelps
    Definition: struct_stat.h:217
    SCIP_Longint domchgcount
    Definition: struct_stat.h:116
    SCIP_CLOCK * divinglptime
    Definition: struct_stat.h:177
    SCIP_Longint lpcount
    Definition: struct_stat.h:205
    SCIP_Longint nlpiterations
    Definition: struct_stat.h:64
    SCIP_Longint nprimalresolvelps
    Definition: struct_stat.h:216
    SCIP_Longint nrootlpiterations
    Definition: struct_stat.h:65
    SCIP_Longint nnumtroublelpmsgs
    Definition: struct_stat.h:225
    SCIP_CLOCK * resolveinstablelptime
    Definition: struct_stat.h:176
    SCIP_Longint nexlp
    Definition: struct_stat.h:231
    SCIP_Real boundingerrorbs
    Definition: struct_stat.h:163
    SCIP_CLOCK * duallptime
    Definition: struct_stat.h:173
    SCIP_Longint nprojshift
    Definition: struct_stat.h:242
    SCIP_Longint ndivinglps
    Definition: struct_stat.h:222
    int maxdepth
    Definition: struct_stat.h:272
    SCIP_Longint nrootlps
    Definition: struct_stat.h:208
    SCIP_Real boundingerrorexlp
    Definition: struct_stat.h:165
    SCIP_CLOCK * primallptime
    Definition: struct_stat.h:172
    SCIP_Longint nprimallpiterations
    Definition: struct_stat.h:67
    SCIP_CLOCK * solvingtime
    Definition: struct_stat.h:168
    SCIP_Longint nbarrierlps
    Definition: struct_stat.h:214
    SCIP_Bool userinterrupt
    Definition: struct_stat.h:314
    SCIP_CLOCK * lexduallptime
    Definition: struct_stat.h:174
    char * name
    Definition: struct_var.h:291
    SCIP_Real obj
    Definition: struct_var.h:263
    datastructures for managing events
    data structures for LP management
    data structures for exact LP management
    datastructures for storing and manipulating the main problem
    SCIP main data structure.
    datastructures for global SCIP settings
    datastructures for problem statistics
    datastructures for problem variables
    Definition: heur_padm.c:135
    enum SCIP_ClockType SCIP_CLOCKTYPE
    Definition: type_clock.h:47
    @ SCIP_CLOCKTYPE_WALL
    Definition: type_clock.h:45
    @ SCIP_CLOCKTYPE_CPU
    Definition: type_clock.h:44
    #define SCIP_EVENTTYPE_ROWSIDECHANGED
    Definition: type_event.h:115
    #define SCIP_EVENTTYPE_ROWADDEDLP
    Definition: type_event.h:111
    struct SCIP_EventData SCIP_EVENTDATA
    Definition: type_event.h:179
    #define SCIP_EVENTTYPE_ROWCHANGED
    Definition: type_event.h:153
    #define SCIP_EVENTTYPE_FORMAT
    Definition: type_event.h:157
    #define SCIP_EVENTTYPE_ROWDELETEDLP
    Definition: type_event.h:112
    uint64_t SCIP_EVENTTYPE
    Definition: type_event.h:156
    #define SCIP_EVENTTYPE_ROWCOEFCHANGED
    Definition: type_event.h:113
    #define SCIP_EVENTTYPE_ROWCONSTCHANGED
    Definition: type_event.h:114
    enum SCIP_RowOriginType SCIP_ROWORIGINTYPE
    Definition: type_lp.h:79
    @ SCIP_LPALGO_BARRIER
    Definition: type_lp.h:86
    @ SCIP_LPALGO_PRIMALSIMPLEX
    Definition: type_lp.h:84
    @ SCIP_LPALGO_BARRIERCROSSOVER
    Definition: type_lp.h:87
    @ SCIP_LPALGO_DUALSIMPLEX
    Definition: type_lp.h:85
    enum SCIP_LPSolStat SCIP_LPSOLSTAT
    Definition: type_lp.h:52
    @ SCIP_ROWORIGINTYPE_CONSHDLR
    Definition: type_lp.h:74
    @ SCIP_ROWORIGINTYPE_SEPA
    Definition: type_lp.h:76
    @ SCIP_ROWORIGINTYPE_CONS
    Definition: type_lp.h:75
    @ SCIP_BOUNDTYPE_UPPER
    Definition: type_lp.h:58
    @ SCIP_BOUNDTYPE_LOWER
    Definition: type_lp.h:57
    enum SCIP_BoundType SCIP_BOUNDTYPE
    Definition: type_lp.h:60
    @ SCIP_SIDETYPE_RIGHT
    Definition: type_lp.h:66
    @ SCIP_SIDETYPE_LEFT
    Definition: type_lp.h:65
    @ SCIP_LPSOLSTAT_ERROR
    Definition: type_lp.h:50
    @ SCIP_LPSOLSTAT_NOTSOLVED
    Definition: type_lp.h:43
    @ SCIP_LPSOLSTAT_OPTIMAL
    Definition: type_lp.h:44
    @ SCIP_LPSOLSTAT_TIMELIMIT
    Definition: type_lp.h:49
    @ SCIP_LPSOLSTAT_UNBOUNDEDRAY
    Definition: type_lp.h:46
    @ SCIP_LPSOLSTAT_INFEASIBLE
    Definition: type_lp.h:45
    @ SCIP_LPSOLSTAT_OBJLIMIT
    Definition: type_lp.h:47
    @ SCIP_LPSOLSTAT_ITERLIMIT
    Definition: type_lp.h:48
    enum SCIP_LPAlgo SCIP_LPALGO
    Definition: type_lp.h:89
    enum SCIP_SideType SCIP_SIDETYPE
    Definition: type_lp.h:68
    @ SCIP_PRICING_STEEPQSTART
    Definition: type_lpi.h:83
    @ SCIP_PRICING_AUTO
    Definition: type_lpi.h:79
    @ SCIP_PRICING_DEVEX
    Definition: type_lpi.h:84
    @ SCIP_PRICING_STEEP
    Definition: type_lpi.h:82
    @ SCIP_PRICING_FULL
    Definition: type_lpi.h:80
    @ SCIP_PRICING_LPIDEFAULT
    Definition: type_lpi.h:78
    @ SCIP_PRICING_PARTIAL
    Definition: type_lpi.h:81
    enum SCIP_Pricing SCIP_PRICING
    Definition: type_lpi.h:86
    enum SCIP_LPParam SCIP_LPPARAM
    Definition: type_lpi.h:73
    @ SCIP_LPPAR_PRICING
    Definition: type_lpi.h:54
    @ SCIP_LPPAR_REFACTOR
    Definition: type_lpi.h:71
    @ SCIP_LPPAR_THREADS
    Definition: type_lpi.h:66
    @ SCIP_LPPAR_LPINFO
    Definition: type_lpi.h:55
    @ SCIP_LPPAR_POLISHING
    Definition: type_lpi.h:70
    @ SCIP_LPPAR_SCALING
    Definition: type_lpi.h:52
    @ SCIP_LPPAR_TIMING
    Definition: type_lpi.h:68
    @ SCIP_LPPAR_LPTILIM
    Definition: type_lpi.h:61
    @ SCIP_LPPAR_BARRIERCONVTOL
    Definition: type_lpi.h:58
    @ SCIP_LPPAR_PRESOLVING
    Definition: type_lpi.h:53
    @ SCIP_LPPAR_CONDITIONLIMIT
    Definition: type_lpi.h:67
    @ SCIP_LPPAR_RANDOMSEED
    Definition: type_lpi.h:69
    @ SCIP_LPPAR_FASTMIP
    Definition: type_lpi.h:51
    @ SCIP_LPPAR_DUALFEASTOL
    Definition: type_lpi.h:57
    @ SCIP_LPPAR_FROMSCRATCH
    Definition: type_lpi.h:50
    @ SCIP_LPPAR_MARKOWITZ
    Definition: type_lpi.h:62
    @ SCIP_LPPAR_FEASTOL
    Definition: type_lpi.h:56
    @ SCIP_LPPAR_LPITLIM
    Definition: type_lpi.h:60
    @ SCIP_LPPAR_ROWREPSWITCH
    Definition: type_lpi.h:63
    @ SCIP_LPPAR_OBJLIM
    Definition: type_lpi.h:59
    @ SCIP_BASESTAT_BASIC
    Definition: type_lpi.h:92
    @ SCIP_BASESTAT_UPPER
    Definition: type_lpi.h:93
    @ SCIP_BASESTAT_LOWER
    Definition: type_lpi.h:91
    @ SCIP_BASESTAT_ZERO
    Definition: type_lpi.h:94
    @ SCIP_OBJSEN_MAXIMIZE
    Definition: type_lpi.h:42
    @ SCIP_OBJSEN_MINIMIZE
    Definition: type_lpi.h:43
    enum SCIP_BaseStat SCIP_BASESTAT
    Definition: type_lpi.h:96
    enum SCIP_VerbLevel SCIP_VERBLEVEL
    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_OBJSENSE_MINIMIZE
    Definition: type_prob.h:48
    enum SCIP_Objsense SCIP_OBJSENSE
    Definition: type_prob.h:50
    @ SCIP_FILECREATEERROR
    Definition: type_retcode.h:48
    @ SCIP_LPERROR
    Definition: type_retcode.h:49
    @ SCIP_INVALIDDATA
    Definition: type_retcode.h:52
    @ SCIP_PARAMETERUNKNOWN
    Definition: type_retcode.h:55
    @ SCIP_PARAMETERWRONGVAL
    Definition: type_retcode.h:57
    @ 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_Real SCIPvarGetRelaxSol(SCIP_VAR *var, SCIP_SET *set)
    Definition: var.c:19688
    internal methods for problem variables