Scippy

    SCIP

    Solving Constraint Integer Programs

    lpi_cpx.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 lpi_cpx.c
    26 * @ingroup LPIS
    27 * @brief LP interface for CPLEX >= 8.0
    28 * @author Tobias Achterberg
    29 * @author Timo Berthold
    30 * @author Stefan Heinz
    31 * @author Gerald Gamrath
    32 * @author Ambros Gleixner
    33 * @author Marc Pfetsch
    34 * @author Stefan Vigerske
    35 * @author Michael Winkler
    36 * @author Kati Wolter
    37 * @author Felipe Serrano
    38 */
    39
    40/*--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    41
    42#include <assert.h>
    43
    44#include "cplex.h"
    45#ifndef CPX_SUBVERSION
    46#define CPX_SUBVERSION 0
    47#endif
    48#include "scip/bitencode.h"
    49#include "lpi/lpi.h"
    50#include "scip/pub_message.h"
    51
    52
    53
    54#define CHECK_ZERO(messagehdlr, x) { int _restat_; \
    55 if( (_restat_ = (x)) != 0 ) \
    56 { \
    57 SCIPmessagePrintWarning((messagehdlr), "LP Error: CPLEX returned %d\n", _restat_); \
    58 return SCIP_LPERROR; \
    59 } \
    60 }
    61
    62/* this macro is only called in functions returning SCIP_Bool; thus, we return FALSE if there is an error in optimized mode */
    63#define ABORT_ZERO(x) { /*lint --e{527}*/ int _restat_; \
    64 if( (_restat_ = (x)) != 0 ) \
    65 { \
    66 SCIPerrorMessage("LP Error: CPLEX returned %d\n", _restat_); \
    67 SCIPABORT(); \
    68 return FALSE; \
    69 } \
    70 }
    71
    72#define CPX_INT_MAX 2100000000 /* CPLEX doesn't accept larger values in integer parameters */
    73
    74/* At several places we need to guarantee to have a factorization of an optimal basis and call the simplex to produce
    75 * it. In a numerical perfect world, this should need no iterations. However, due to numerical inaccuracies after
    76 * refactorization, it might be necessary to do a few extra pivot steps. */
    77#define CPX_REFACTORMAXITERS 50 /* maximal number of iterations allowed for producing a refactorization of the basis */
    78
    79/* CPLEX seems to ignore bounds with absolute value less than 1e-10. There is no interface define for this constant yet,
    80 * so we define it here. */
    81#define CPX_MAGICZEROCONSTANT 1e-10
    82
    83typedef SCIP_DUALPACKET COLPACKET; /* each column needs two bits of information (basic/on_lower/on_upper) */
    84#define COLS_PER_PACKET SCIP_DUALPACKETSIZE
    85typedef SCIP_DUALPACKET ROWPACKET; /* each row needs two bit of information (basic/on_lower/on_upper) */
    86#define ROWS_PER_PACKET SCIP_DUALPACKETSIZE
    87
    88/* CPLEX parameter lists which can be changed */
    89#if (CPX_VERSION < 12060100)
    90#define NUMINTPARAM 11
    91#else
    92#define NUMINTPARAM 10
    93#endif
    94static const int intparam[NUMINTPARAM] =
    95{
    96 CPX_PARAM_ADVIND,
    97 CPX_PARAM_ITLIM,
    98#if (CPX_VERSION < 12060100)
    99 CPX_PARAM_FASTMIP,
    100#endif
    101 CPX_PARAM_SCAIND,
    102 CPX_PARAM_PREIND,
    103 CPX_PARAM_PPRIIND,
    104 CPX_PARAM_DPRIIND,
    105 CPX_PARAM_SIMDISPLAY,
    106 CPX_PARAM_SCRIND,
    107 CPX_PARAM_THREADS,
    108 CPX_PARAM_RANDOMSEED
    109};
    110
    111#define NUMDBLPARAM 7
    112static const int dblparam[NUMDBLPARAM] =
    113{
    114 CPX_PARAM_EPRHS,
    115 CPX_PARAM_EPOPT,
    116 CPX_PARAM_BAREPCOMP,
    117 CPX_PARAM_OBJLLIM,
    118 CPX_PARAM_OBJULIM,
    119 CPX_PARAM_TILIM,
    120 CPX_PARAM_EPMRK
    121};
    122
    123static const double dblparammin[NUMDBLPARAM] =
    124{
    125 +1e-09, /*CPX_PARAM_EPRHS*/
    126 +1e-09, /*CPX_PARAM_EPOPT*/
    127 +1e-12, /*CPX_PARAM_BAREPCOMP*/
    128 -1e+99, /*CPX_PARAM_OBJLLIM*/
    129 -1e+99, /*CPX_PARAM_OBJULIM*/
    130 -1e+99, /*CPX_PARAM_TILIM*/
    131 0.0001 /*CPX_PARAM_EPMRK*/
    132};
    133
    134/** CPLEX parameter settings */
    136{
    137 int intparval[NUMINTPARAM]; /**< integer parameter values */
    138 double dblparval[NUMDBLPARAM]; /**< double parameter values */
    139};
    141
    142/** LP interface */
    143struct SCIP_LPi
    144{
    145 CPXENVptr cpxenv; /**< CPLEX environment */
    146 SCIP_CPXPARAM defparam; /**< default CPLEX parameters */
    147 SCIP_CPXPARAM curparam; /**< current CPLEX parameters in the environment */
    148 CPXLPptr cpxlp; /**< CPLEX LP pointer */
    149 int solstat; /**< solution status of last optimization call */
    150 int method; /**< solution method of last optimization call */
    151 SCIP_CPXPARAM cpxparam; /**< current parameter values for this LP */
    152 char* larray; /**< array with 'L' entries for changing lower bounds */
    153 char* uarray; /**< array with 'U' entries for changing upper bounds */
    154 char* senarray; /**< array for storing row senses */
    155 SCIP_Real* rhsarray; /**< array for storing rhs values */
    156 SCIP_Real* rngarray; /**< array for storing range values */
    157 SCIP_Real* valarray; /**< array for storing coefficient values */
    158 int* rngindarray; /**< array for storing row indices with range values */
    159 int* cstat; /**< array for storing column basis status */
    160 int* rstat; /**< array for storing row basis status */
    161 int* indarray; /**< array for storing coefficient indices */
    162 int boundchgsize; /**< size of larray and uarray */
    163 int sidechgsize; /**< size of senarray, rngarray, and rngindarray */
    164 int valsize; /**< size of valarray and indarray */
    165 int cstatsize; /**< size of cstat array */
    166 int rstatsize; /**< size of rstat array */
    167 int iterations; /**< number of iterations used in the last solving call */
    168 SCIP_PRICING pricing; /**< SCIP pricing setting */
    169 SCIP_Bool solisbasic; /**< is current LP solution a basic solution? */
    170 SCIP_Bool instabilityignored; /**< was the instability of the last LP ignored? */
    171 SCIP_Bool fromscratch; /**< shall solves be performed with CPX_PARAM_ADVIND turned off? */
    172 SCIP_Bool clearstate; /**< shall next solve be performed with CPX_PARAM_ADVIND turned off? */
    173 SCIP_Real feastol; /**< feasibility tolerance for integrality */
    174 SCIP_Real conditionlimit; /**< maximum condition number of LP basis counted as stable (-1.0: no limit) */
    175 SCIP_Bool checkcondition; /**< should condition number of LP basis be checked for stability? */
    176#if (CPX_VERSION <= 1100)
    177 SCIP_Bool rngfound; /**< was ranged row found; scaling is disabled, because there is a bug
    178 * in the scaling algorithm for ranged rows in CPLEX up to version 11.0 */
    179#endif
    180#if (CPX_VERSION == 1100 || (CPX_VERSION == 1220 && (CPX_SUBVERSION == 0 || CPX_SUBVERSION == 2)))
    181 int pseudonthreads; /**< number of threads that SCIP set for the LP solver, but due to CPLEX bug,
    182 * we set the thread count to 1. In order to fulfill assert in lp.c,
    183 * we have to return the value set by SCIP and not the real thread count */
    184#endif
    185 SCIP_MESSAGEHDLR* messagehdlr; /**< messagehdlr handler to printing messages, or NULL */
    186};
    187
    188/** LPi state stores basis information */
    189struct SCIP_LPiState
    190{
    191 int ncols; /**< number of LP columns */
    192 int nrows; /**< number of LP rows */
    193 COLPACKET* packcstat; /**< column basis status in compressed form */
    194 ROWPACKET* packrstat; /**< row basis status in compressed form */
    195};
    196
    197/** LPi norms stores pricing norms */
    199{
    200 int normlen; /**< number of rows for which dual norm is stored */
    201 double* norm; /**< dual norms */
    202 int* head; /**< row/column indices corresponding to norms */
    203};
    204
    205
    206/*
    207 * dynamic memory arrays
    208 */
    209
    210/** resizes larray and uarray to have at least num entries */
    211static
    213 SCIP_LPI* lpi, /**< LP interface structure */
    214 int num /**< minimal number of entries in array */
    215 )
    216{
    217 assert(lpi != NULL);
    218
    219 if( num > lpi->boundchgsize )
    220 {
    221 int newsize;
    222 int i;
    223
    224 newsize = MAX(2*lpi->boundchgsize, num);
    225 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->larray, newsize) );
    226 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->uarray, newsize) );
    227 for( i = lpi->boundchgsize; i < newsize; ++i )
    228 {
    229 lpi->larray[i] = 'L';
    230 lpi->uarray[i] = 'U';
    231 }
    232 lpi->boundchgsize = newsize;
    233 }
    234 assert(num <= lpi->boundchgsize);
    235
    236 return SCIP_OKAY;
    237}
    238
    239/** resizes senarray, rngarray, and rngindarray to have at least num entries */
    240static
    242 SCIP_LPI* lpi, /**< LP interface structure */
    243 int num /**< minimal number of entries in array */
    244 )
    245{
    246 assert(lpi != NULL);
    247
    248 if( num > lpi->sidechgsize )
    249 {
    250 int newsize;
    251
    252 newsize = MAX(2*lpi->sidechgsize, num);
    253 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->senarray, newsize) );
    254 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rhsarray, newsize) );
    255 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rngarray, newsize) );
    257 lpi->sidechgsize = newsize;
    258 }
    259 assert(num <= lpi->sidechgsize);
    260
    261 return SCIP_OKAY;
    262}
    263
    264/** resizes valarray and indarray to have at least num entries */
    265static
    267 SCIP_LPI* lpi, /**< LP interface structure */
    268 int num /**< minimal number of entries in array */
    269 )
    270{
    271 assert(lpi != NULL);
    272
    273 if( num > lpi->valsize )
    274 {
    275 int newsize;
    276
    277 newsize = MAX(2*lpi->valsize, num);
    278 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->valarray, newsize) );
    279 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->indarray, newsize) );
    280 lpi->valsize = newsize;
    281 }
    282 assert(num <= lpi->valsize);
    283
    284 return SCIP_OKAY;
    285}
    286
    287/** resizes cstat array to have at least num entries */
    288static
    290 SCIP_LPI* lpi, /**< LP interface structure */
    291 int num /**< minimal number of entries in array */
    292 )
    293{
    294 assert(lpi != NULL);
    295
    296 if( num > lpi->cstatsize )
    297 {
    298 int newsize;
    299
    300 newsize = MAX(2*lpi->cstatsize, num);
    301 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->cstat, newsize) );
    302 lpi->cstatsize = newsize;
    303 }
    304 assert(num <= lpi->cstatsize);
    305
    306 return SCIP_OKAY;
    307}
    308
    309/** resizes rstat array to have at least num entries */
    310static
    312 SCIP_LPI* lpi, /**< LP interface structure */
    313 int num /**< minimal number of entries in array */
    314 )
    315{
    316 assert(lpi != NULL);
    317
    318 if( num > lpi->rstatsize )
    319 {
    320 int newsize;
    321
    322 newsize = MAX(2*lpi->rstatsize, num);
    323 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rstat, newsize) );
    324 lpi->rstatsize = newsize;
    325 }
    326 assert(num <= lpi->rstatsize);
    327
    328 return SCIP_OKAY;
    329}
    330
    331/** stores current basis in internal arrays of LPI data structure */
    332static
    334 SCIP_LPI* lpi /**< LP interface structure */
    335 )
    336{
    337 int ncols;
    338 int nrows;
    339
    340 assert(lpi != NULL);
    341 assert(lpi->cpxenv != NULL);
    342
    343 SCIPdebugMessage("getBase()\n");
    344
    345 ncols = CPXgetnumcols(lpi->cpxenv, lpi->cpxlp);
    346 nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
    347
    348 /* allocate enough memory for storing uncompressed basis information */
    349 SCIP_CALL( ensureCstatMem(lpi, ncols) );
    350 SCIP_CALL( ensureRstatMem(lpi, nrows) );
    351
    352 /* get unpacked basis information from CPLEX */
    353 CHECK_ZERO( lpi->messagehdlr, CPXgetbase(lpi->cpxenv, lpi->cpxlp, lpi->cstat, lpi->rstat) );
    354
    355 return SCIP_OKAY;
    356}
    357
    358/** loads basis stored in internal arrays of LPI data structure into CPLEX */
    359static
    361 SCIP_LPI* lpi /**< LP interface structure */
    362 )
    363{
    364 assert(lpi != NULL);
    365 assert(lpi->cpxenv != NULL);
    366
    367 SCIPdebugMessage("setBase()\n");
    368
    369 /* load basis information into CPLEX */
    370 CHECK_ZERO( lpi->messagehdlr, CPXcopybase(lpi->cpxenv, lpi->cpxlp, lpi->cstat, lpi->rstat) );
    371
    372 /* because the basis status values are equally defined in SCIP and CPLEX, they don't need to be transformed */
    373 assert((int)SCIP_BASESTAT_LOWER == CPX_AT_LOWER); /*lint !e506*/
    374 assert((int)SCIP_BASESTAT_BASIC == CPX_BASIC); /*lint !e506*/
    375 assert((int)SCIP_BASESTAT_UPPER == CPX_AT_UPPER); /*lint !e506*/
    376 assert((int)SCIP_BASESTAT_ZERO == CPX_FREE_SUPER); /*lint !e506*/
    377
    378 return SCIP_OKAY;
    379}
    380
    381
    382
    383
    384/*
    385 * LPi state methods
    386 */
    387
    388/** returns the number of packets needed to store column packet information */
    389static
    391 int ncols /**< number of columns to store */
    392 )
    393{
    394 return (ncols+(int)COLS_PER_PACKET-1)/(int)COLS_PER_PACKET;
    395}
    396
    397/** returns the number of packets needed to store row packet information */
    398static
    400 int nrows /**< number of rows to store */
    401 )
    402{
    403 return (nrows+(int)ROWS_PER_PACKET-1)/(int)ROWS_PER_PACKET;
    404}
    405
    406/** store row and column basis status in a packed LPi state object */
    407static
    409 SCIP_LPISTATE* lpistate, /**< pointer to LPi state data */
    410 const int* cstat, /**< basis status of columns in unpacked format */
    411 const int* rstat /**< basis status of rows in unpacked format */
    412 )
    413{
    414 assert(lpistate != NULL);
    415 assert(lpistate->packcstat != NULL);
    416 assert(lpistate->packrstat != NULL);
    417
    418 SCIPencodeDualBit(cstat, lpistate->packcstat, lpistate->ncols);
    419 SCIPencodeDualBit(rstat, lpistate->packrstat, lpistate->nrows);
    420}
    421
    422/** unpacks row and column basis status from a packed LPi state object */
    423static
    425 const SCIP_LPISTATE* lpistate, /**< pointer to LPi state data */
    426 int* cstat, /**< buffer for storing basis status of columns in unpacked format */
    427 int* rstat /**< buffer for storing basis status of rows in unpacked format */
    428 )
    429{
    430 assert(lpistate != NULL);
    431 assert(lpistate->packcstat != NULL);
    432 assert(lpistate->packrstat != NULL);
    433
    434 SCIPdecodeDualBit(lpistate->packcstat, cstat, lpistate->ncols);
    435 SCIPdecodeDualBit(lpistate->packrstat, rstat, lpistate->nrows);
    436}
    437
    438/** creates LPi state information object */
    439static
    441 SCIP_LPISTATE** lpistate, /**< pointer to LPi state */
    442 BMS_BLKMEM* blkmem, /**< block memory */
    443 int ncols, /**< number of columns to store */
    444 int nrows /**< number of rows to store */
    445 )
    446{
    447 assert(lpistate != NULL);
    448 assert(blkmem != NULL);
    449 assert(ncols >= 0);
    450 assert(nrows >= 0);
    451
    452 SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpistate) );
    453 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->packcstat, colpacketNum(ncols)) );
    454 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->packrstat, rowpacketNum(nrows)) );
    455
    456 return SCIP_OKAY;
    457}
    458
    459/** frees LPi state information */
    460static
    462 SCIP_LPISTATE** lpistate, /**< pointer to LPi state information (like basis information) */
    463 BMS_BLKMEM* blkmem /**< block memory */
    464 )
    465{
    466 assert(blkmem != NULL);
    467 assert(lpistate != NULL);
    468 assert(*lpistate != NULL);
    469
    470 BMSfreeBlockMemoryArray(blkmem, &(*lpistate)->packcstat, colpacketNum((*lpistate)->ncols));
    471 BMSfreeBlockMemoryArray(blkmem, &(*lpistate)->packrstat, rowpacketNum((*lpistate)->nrows));
    472 BMSfreeBlockMemory(blkmem, lpistate);
    473}
    474
    475
    476
    477/*
    478 * local methods
    479 */
    480
    481/** gets all CPLEX parameters used in LPI */
    482static
    484 SCIP_LPI* lpi, /**< LP interface structure */
    485 SCIP_CPXPARAM* cpxparam /**< current parameter values for this LP */
    486 )
    487{
    488 int i;
    489
    490 assert(lpi != NULL);
    491 assert(cpxparam != NULL);
    492
    493 SCIPdebugMessage("getParameterValues()\n");
    494
    495 for( i = 0; i < NUMINTPARAM; ++i )
    496 {
    497 CHECK_ZERO( lpi->messagehdlr, CPXgetintparam(lpi->cpxenv, intparam[i], &(cpxparam->intparval[i])) );
    498 }
    499 for( i = 0; i < NUMDBLPARAM; ++i )
    500 {
    501 CHECK_ZERO( lpi->messagehdlr, CPXgetdblparam(lpi->cpxenv, dblparam[i], &(cpxparam->dblparval[i])) );
    502 }
    503
    504 return SCIP_OKAY;
    505}
    506
    507/** in debug mode, checks validity of CPLEX parameters */
    508static
    510 SCIP_LPI*const lpi /**< LP interface structure */
    511 )
    512{
    513#ifndef NDEBUG
    514 SCIP_CPXPARAM par;
    515 int i;
    516
    517 assert(lpi != NULL);
    518 assert(lpi->cpxenv != NULL);
    519
    520 SCIP_CALL( getParameterValues(lpi, &par) );
    521 for( i = 0; i < NUMINTPARAM; ++i )
    522 {
    523#if (CPX_VERSION == 12070100 || CPX_VERSION == 12070000)
    524 /* due to a bug in CPLEX 12.7.0 and CPLEX 12.7.1, we need to disable scaling for these versions */
    525 if ( intparam[i] != CPX_PARAM_SCAIND )
    526#endif
    527 assert(lpi->curparam.intparval[i] == par.intparval[i]
    528 || (lpi->curparam.intparval[i] == CPX_INT_MAX && par.intparval[i] >= CPX_INT_MAX));
    529 }
    530 for( i = 0; i < NUMDBLPARAM; ++i )
    531 assert(MAX(lpi->curparam.dblparval[i], dblparammin[i]) == par.dblparval[i]); /*lint !e777*/
    532#endif
    533
    534 return SCIP_OKAY;
    535}
    536
    537/** sets all CPLEX parameters used in LPI */
    538static
    540 SCIP_LPI*const lpi, /**< LP interface structure */
    541 SCIP_CPXPARAM*const cpxparam /**< current parameter values for this LP */
    542 )
    543{
    544 int i;
    545
    546 assert(lpi != NULL);
    547 assert(lpi->cpxenv != NULL);
    548 assert(cpxparam != NULL);
    549
    550 SCIPdebugMessage("setParameterValues()\n");
    551
    552 for( i = 0; i < NUMINTPARAM; ++i )
    553 {
    554 if( lpi->curparam.intparval[i] != cpxparam->intparval[i] )
    555 {
    556 SCIPdebugMessage("setting CPLEX int parameter %d from %d to %d\n",
    557 intparam[i], lpi->curparam.intparval[i], cpxparam->intparval[i]);
    558 lpi->curparam.intparval[i] = cpxparam->intparval[i];
    559#if (CPX_VERSION == 12070000)
    560 /* due to a bug in CPLEX 12.7.0, we need to disable scaling for this version */
    561 if ( intparam[i] != CPX_PARAM_SCAIND )
    562#endif
    563 {
    564 CHECK_ZERO( lpi->messagehdlr, CPXsetintparam(lpi->cpxenv, intparam[i], lpi->curparam.intparval[i]) );
    565 }
    566 }
    567 }
    568 for( i = 0; i < NUMDBLPARAM; ++i )
    569 {
    570 if( lpi->curparam.dblparval[i] != cpxparam->dblparval[i] ) /*lint !e777*/
    571 {
    572 SCIPdebugMessage("setting CPLEX dbl parameter %d from %g to %g\n",
    573 dblparam[i], lpi->curparam.dblparval[i], MAX(cpxparam->dblparval[i], dblparammin[i]));
    574 lpi->curparam.dblparval[i] = MAX(cpxparam->dblparval[i], dblparammin[i]);
    575 CHECK_ZERO( lpi->messagehdlr, CPXsetdblparam(lpi->cpxenv, dblparam[i], lpi->curparam.dblparval[i]) );
    576 }
    577 }
    578
    580
    581 return SCIP_OKAY;
    582}
    583
    584/** copies CPLEX parameters from source to dest */
    585static
    587 SCIP_CPXPARAM* dest, /**< CPLEX parameters to copy to */
    588 SCIP_CPXPARAM*const source /**< CPLEX parameters which will be copied */
    589 )
    590{
    591 int i;
    592
    593 for( i = 0; i < NUMINTPARAM; ++i )
    594 dest->intparval[i] = source->intparval[i];
    595 for( i = 0; i < NUMDBLPARAM; ++i )
    596 dest->dblparval[i] = source->dblparval[i];
    597}
    598
    599/** gets a single integer parameter value */
    600static
    602 SCIP_LPI* lpi, /**< LP interface structure */
    603 int const param /**< parameter to get value for */
    604 )
    605{
    606 int i;
    607
    608 assert(lpi != NULL);
    609
    610 for( i = 0; i < NUMINTPARAM; ++i )
    611 {
    612 if( intparam[i] == param )
    613 return lpi->cpxparam.intparval[i];
    614 }
    615
    616 SCIPerrorMessage("unknown CPLEX integer parameter\n");
    617 SCIPABORT();
    618 return 0; /*lint !e527*/
    619}
    620
    621/** gets a single double parameter value */
    622static
    624 SCIP_LPI* lpi, /**< LP interface structure */
    625 int const param /**< parameter to get value for */
    626 )
    627{
    628 SCIP_Real val;
    629 int i;
    630
    631 assert(lpi != NULL);
    632
    633 for( i = 0; i < NUMDBLPARAM; ++i )
    634 {
    635 if( dblparam[i] == param )
    636 {
    637 val = lpi->cpxparam.dblparval[i];
    638 if( val >= CPX_INFBOUND )
    639 return CPX_INFBOUND;
    640 else if( val <= -CPX_INFBOUND )
    641 return -CPX_INFBOUND;
    642 else
    643 return val;
    644 }
    645 }
    646
    647 SCIPerrorMessage("unknown CPLEX double parameter\n");
    648 SCIPABORT();
    649 return 0.0; /*lint !e527*/
    650}
    651
    652/** sets a single integer parameter value */
    653static
    655 SCIP_LPI* lpi, /**< LP interface structure */
    656 int const param, /**< parameter to set value */
    657 int const parval /**< new value for parameter */
    658 )
    659{
    660 int i;
    661
    662 assert(lpi != NULL);
    663
    664 for( i = 0; i < NUMINTPARAM; ++i )
    665 {
    666 if( intparam[i] == param )
    667 {
    668 lpi->cpxparam.intparval[i] = parval;
    669 return;
    670 }
    671 }
    672
    673 SCIPerrorMessage("unknown CPLEX integer parameter\n");
    674 SCIPABORT();
    675}
    676
    677/** sets a single double parameter value */
    678static
    680 SCIP_LPI* lpi, /**< LP interface structure */
    681 int const param, /**< parameter to set value */
    682 double parval /**< new value for parameter */
    683 )
    684{
    685 int i;
    686
    687 assert(lpi != NULL);
    688
    689 if( parval >= CPX_INFBOUND )
    690 parval = 1e+75;
    691 else if( parval <= -CPX_INFBOUND )
    692 parval = -1e+75;
    693
    694 for( i = 0; i < NUMDBLPARAM; ++i )
    695 {
    696 if( dblparam[i] == param )
    697 {
    698 lpi->cpxparam.dblparval[i] = parval;
    699 return;
    700 }
    701 }
    702
    703 SCIPerrorMessage("unknown CPLEX double parameter\n");
    704 SCIPABORT();
    705}
    706
    707/** marks the current LP to be unsolved */
    708static
    710 SCIP_LPI* const lpi /**< LP interface structure */
    711 )
    712{
    713 assert(lpi != NULL);
    714 lpi->solstat = -1;
    715 lpi->method = CPX_ALG_NONE;
    717}
    718
    719/** converts SCIP's objective sense into CPLEX's objective sense */
    720static
    722 SCIP_OBJSEN const objsen /**< objective sense */
    723 )
    724{
    725 switch( objsen )
    726 {
    728 return CPX_MAX;
    730 return CPX_MIN;
    731 default:
    732 SCIPerrorMessage("invalid objective sense\n");
    733 SCIPABORT();
    734 return 0; /*lint !e527*/
    735 }
    736}
    737
    738/** converts SCIP's lhs/rhs pairs into CPLEX's sen/rhs/rng */
    739static
    741 SCIP_LPI* lpi, /**< LP interface structure */
    742 int nrows, /**< number of rows */
    743 const SCIP_Real* lhs, /**< left hand side vector */
    744 const SCIP_Real* rhs, /**< right hand side vector */
    745 int indoffset, /**< index of first row in LP */
    746 int* rngcount /**< pointer to store the number of range rows */
    747 )
    748{
    749 int i;
    750
    751 assert(lpi != NULL);
    752 assert(nrows >= 0);
    753 assert(lhs != NULL);
    754 assert(rhs != NULL);
    755 assert(rngcount != NULL);
    756
    757 /* convert lhs/rhs into sen/rhs/rng */
    758 *rngcount = 0;
    759 for( i = 0; i < nrows; ++i )
    760 {
    761 assert(lhs[i] <= rhs[i]);
    762 if( lhs[i] == rhs[i] ) /*lint !e777*/
    763 {
    764 assert(-CPX_INFBOUND < rhs[i] && rhs[i] < CPX_INFBOUND);
    765 lpi->senarray[i] = 'E';
    766 lpi->rhsarray[i] = rhs[i];
    767 }
    768 else if( lhs[i] <= -CPX_INFBOUND )
    769 {
    770 lpi->senarray[i] = 'L';
    771 lpi->rhsarray[i] = rhs[i];
    772 }
    773 else if( rhs[i] >= CPX_INFBOUND )
    774 {
    775 lpi->senarray[i] = 'G';
    776 lpi->rhsarray[i] = lhs[i];
    777 }
    778 else
    779 {
    780 /* CPLEX defines a ranged row to be within rhs and rhs+rng.
    781 * -> To keep SCIP's meaning of the rhs value, we would like to use negative range values: rng := lhs - rhs,
    782 * but there seems to be a bug in CPLEX's presolve with negative range values:
    783 * the ranged row
    784 * 0 <= -x <= 100000 with x >= 0 (rhs=0, rng=-100000)
    785 * would lead to the CPLEX row
    786 * -x -Rg = 100000
    787 * Rg = 0
    788 * instead of the correct presolving implication Rg = -100000.
    789 * -> Because of this bug, we have to use an additional rhsarray[] for the converted right hand sides and
    790 * use rhsarray[i] = lhs[i] and rngarray[i] = rhs[i] - lhs[i] for ranged rows to keep the range values
    791 * non-negative.
    792 */
    793 lpi->senarray[i] = 'R';
    794 lpi->rhsarray[i] = lhs[i];
    795 lpi->rngarray[*rngcount] = rhs[i] - lhs[i];
    796 lpi->rngindarray[*rngcount] = i + indoffset;
    797 (*rngcount)++;
    798 }
    799 }
    800}
    801
    802/** converts CPLEX's sen/rhs/rng triplets into SCIP's lhs/rhs pairs */
    803static
    805 SCIP_LPI* lpi, /**< LP interface structure */
    806 int nrows, /**< number of rows */
    807 SCIP_Real* lhs, /**< buffer to store the left hand side vector */
    808 SCIP_Real* rhs /**< buffer to store the right hand side vector */
    809 )
    810{
    811 int i;
    812
    813 assert(lpi != NULL);
    814 assert(nrows >= 0);
    815 assert(lhs != NULL);
    816 assert(rhs != NULL);
    817
    818 for( i = 0; i < nrows; ++i )
    819 {
    820 switch( lpi->senarray[i] )
    821 {
    822 case 'E':
    823 lhs[i] = lpi->rhsarray[i];
    824 rhs[i] = lpi->rhsarray[i];
    825 break;
    826
    827 case 'L':
    828 lhs[i] = -CPX_INFBOUND;
    829 rhs[i] = lpi->rhsarray[i];
    830 break;
    831
    832 case 'G':
    833 lhs[i] = lpi->rhsarray[i];
    834 rhs[i] = CPX_INFBOUND;
    835 break;
    836
    837 case 'R':
    838 assert(lpi->rngarray[i] != 0.0);
    839 if( lpi->rngarray[i] > 0.0 )
    840 {
    841 lhs[i] = lpi->rhsarray[i];
    842 rhs[i] = lpi->rhsarray[i] + lpi->rngarray[i];
    843 }
    844 else
    845 {
    846 lhs[i] = lpi->rhsarray[i] + lpi->rngarray[i];
    847 rhs[i] = lpi->rhsarray[i];
    848 }
    849 break;
    850
    851 default:
    852 SCIPerrorMessage("invalid row sense\n");
    853 SCIPABORT();
    854 }
    855 assert(lhs[i] <= rhs[i]);
    856 }
    857}
    858
    859/** converts CPLEX's sen/rhs/rng triplets into SCIP's lhs/rhs pairs, only storing the left hand side */
    860static
    862 SCIP_LPI* lpi, /**< LP interface structure */
    863 int nrows, /**< number of rows */
    864 SCIP_Real* lhs /**< buffer to store the left hand side vector */
    865 )
    866{
    867 int i;
    868
    869 assert(lpi != NULL);
    870 assert(nrows >= 0);
    871 assert(lhs != NULL);
    872
    873 for( i = 0; i < nrows; ++i )
    874 {
    875 switch( lpi->senarray[i] )
    876 {
    877 case 'E':
    878 assert(lpi->rngarray[i] == 0.0);
    879 lhs[i] = lpi->rhsarray[i];
    880 break;
    881
    882 case 'L':
    883 assert(lpi->rngarray[i] == 0.0);
    884 lhs[i] = -CPX_INFBOUND;
    885 break;
    886
    887 case 'G':
    888 assert(lpi->rngarray[i] == 0.0);
    889 lhs[i] = lpi->rhsarray[i];
    890 break;
    891
    892 case 'R':
    893 assert(lpi->rngarray[i] != 0.0);
    894 if( lpi->rngarray[i] > 0.0 )
    895 lhs[i] = lpi->rhsarray[i];
    896 else
    897 lhs[i] = lpi->rhsarray[i] + lpi->rngarray[i];
    898 break;
    899
    900 default:
    901 SCIPerrorMessage("invalid row sense\n");
    902 SCIPABORT();
    903 }
    904 }
    905}
    906
    907/** converts CPLEX's sen/rhs/rng triplets into SCIP's lhs/rhs pairs, only storing the right hand side */
    908static
    910 SCIP_LPI* lpi, /**< LP interface structure */
    911 int nrows, /**< number of rows */
    912 SCIP_Real* rhs /**< buffer to store the right hand side vector */
    913 )
    914{
    915 int i;
    916
    917 assert(lpi != NULL);
    918 assert(nrows >= 0);
    919 assert(rhs != NULL);
    920
    921 for( i = 0; i < nrows; ++i )
    922 {
    923 switch( lpi->senarray[i] )
    924 {
    925 case 'E':
    926 assert(lpi->rngarray[i] == 0.0);
    927 rhs[i] = lpi->rhsarray[i];
    928 break;
    929
    930 case 'L':
    931 assert(lpi->rngarray[i] == 0.0);
    932 rhs[i] = lpi->rhsarray[i];
    933 break;
    934
    935 case 'G':
    936 assert(lpi->rngarray[i] == 0.0);
    937 rhs[i] = CPX_INFBOUND;
    938 break;
    939
    940 case 'R':
    941 assert(lpi->rngarray[i] != 0.0);
    942 if( lpi->rngarray[i] > 0.0 )
    943 rhs[i] = lpi->rhsarray[i] + lpi->rngarray[i];
    944 else
    945 rhs[i] = lpi->rhsarray[i];
    946 break;
    947
    948 default:
    949 SCIPerrorMessage("invalid row sense\n");
    950 SCIPABORT();
    951 }
    952 }
    953}
    954
    955/** converts CPLEX's sen/rhs/rng triplets into SCIP's lhs/rhs pairs */
    956static
    958 SCIP_LPI* lpi, /**< LP interface structure */
    959 int nrows, /**< number of rows */
    960 SCIP_Real* lhs, /**< buffer to store the left hand side vector, or NULL */
    961 SCIP_Real* rhs /**< buffer to store the right hand side vector, or NULL */
    962 )
    963{
    964 if( lhs != NULL && rhs != NULL )
    965 reconvertBothSides(lpi, nrows, lhs, rhs);
    966 else if( lhs != NULL )
    967 reconvertLhs(lpi, nrows, lhs);
    968 else if( rhs != NULL )
    969 reconvertRhs(lpi, nrows, rhs);
    970}
    971
    972
    973/** after restoring the old lp data in CPLEX we need to resolve the lp to be able to retrieve correct information */
    974static
    976 SCIP_LPI* lpi /**< LP interface structure */
    977 )
    978{
    979 assert(lpi != NULL);
    980
    981 /* modifying the LP, restoring the old LP, and loading the old basis is not enough for CPLEX to be able to return the
    982 * basis -> we have to resolve the LP;
    983 *
    984 * this may happen after manual strong branching on an integral variable, or after conflict analysis on a strong
    985 * branching conflict created a constraint that is not able to modify the LP but trigger the additional call of the
    986 * separators, in particular, the Gomory separator
    987 *
    988 * In a numerical perfect world, CPX_REFACTORMAXITERS below should be zero. However, due to numerical inaccuracies
    989 * after refactorization, it might be necessary to do a few extra pivot steps.
    990 */
    991 CHECK_ZERO( lpi->messagehdlr, CPXdualopt(lpi->cpxenv, lpi->cpxlp) );
    992#ifndef NDEBUG
    993 if ( CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) > CPX_REFACTORMAXITERS )
    994 SCIPmessagePrintWarning(lpi->messagehdlr, "CPLEX needed %d phase 1 iterations to restore optimal basis.\n", CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp));
    995 if ( CPXgetitcnt(lpi->cpxenv, lpi->cpxlp) > CPX_REFACTORMAXITERS )
    996 SCIPmessagePrintWarning(lpi->messagehdlr, "CPLEX needed %d iterations to restore optimal basis.\n", CPXgetitcnt(lpi->cpxenv, lpi->cpxlp));
    997#endif
    998
    999 return SCIP_OKAY;
    1000}
    1001
    1002
    1003/*
    1004 * LP Interface Methods
    1005 */
    1006
    1007
    1008/*
    1009 * Miscellaneous Methods
    1010 */
    1011/*lint --e{778}*/
    1012/*lint --e{835}*/
    1013static const char cpxname[]= {'C', 'P', 'L', 'E', 'X', ' ',
    1014#if (defined CPX_VERSION_VERSION) && (CPX_VERSION_VERSION >= 10) && (CPX_VERSION_RELEASE >= 10)
    1015 (CPX_VERSION_VERSION/10) + '0', (CPX_VERSION_VERSION%10) + '0', '.', (CPX_VERSION_RELEASE/10) + '0', (CPX_VERSION_RELEASE%10) + '0', '.', CPX_VERSION_MODIFICATION + '0', '.', CPX_VERSION_FIX + '0'
    1016#elif (defined CPX_VERSION_VERSION) && (CPX_VERSION_VERSION <= 9) && (CPX_VERSION_RELEASE <= 9)
    1017 CPX_VERSION_VERSION + '0', '.',CPX_VERSION_RELEASE + '0', '.', CPX_VERSION_MODIFICATION + '0', '.', CPX_VERSION_FIX + '0'
    1018#elif (defined CPX_VERSION_VERSION) && (CPX_VERSION_VERSION >= 10) && (CPX_VERSION_RELEASE <= 9)
    1019 (CPX_VERSION_VERSION/10) + '0', (CPX_VERSION_VERSION%10) + '0', '.', CPX_VERSION_RELEASE + '0', '.', CPX_VERSION_MODIFICATION + '0', '.', CPX_VERSION_FIX + '0'
    1020#elif (defined CPX_VERSION_VERSION) && (CPX_VERSION_VERSION <= 9) && (CPX_VERSION_RELEASE >= 10)
    1021 CPX_VERSION_VERSION + '0', '.', (CPX_VERSION_RELEASE/10) + '0', (CPX_VERSION_RELEASE%10) + '0', '.', CPX_VERSION_MODIFICATION + '0', '.', CPX_VERSION_FIX + '0'
    1022#else
    1023 (CPX_VERSION / 100) + '0', '.', ((CPX_VERSION % 100) / 10) + '0', '.', (CPX_VERSION % 10) + '0', '.', CPX_SUBVERSION + '0'
    1024#endif
    1025 , '\0'
    1026};
    1027
    1028
    1029/**@name Miscellaneous Methods */
    1030/**@{ */
    1031
    1032/** gets name and version of LP solver */
    1034 void
    1035 )
    1036{
    1037 return cpxname;
    1038}
    1039
    1040/** gets description of LP solver (developer, webpage, ...) */
    1042 void
    1043 )
    1044{
    1045 return "Linear Programming Solver developed by IBM (www.cplex.com)";
    1046}
    1047
    1048/** gets pointer for LP solver - use only with great care
    1049 *
    1050 * Here we return the pointer to the LP environment.
    1051 */
    1053 SCIP_LPI* lpi /**< pointer to an LP interface structure */
    1054 )
    1055{
    1056 return (void*) lpi->cpxlp;
    1057}
    1058
    1059/** pass integrality information to LP solver */
    1061 SCIP_LPI* lpi, /**< pointer to an LP interface structure */
    1062 int ncols, /**< length of integrality array */
    1063 int* intInfo /**< integrality array (0: continuous, 1: integer). May be NULL iff ncols is 0. */
    1064 )
    1065{ /*lint --e{715}*/
    1066 assert( lpi != NULL );
    1067 assert( ncols >= 0 );
    1068 assert( ncols == 0 || intInfo != NULL );
    1069
    1070 SCIPerrorMessage("SCIPlpiSetIntegralityInformation() has not been implemented yet.\n");
    1071 return SCIP_LPERROR;
    1072}
    1073
    1074/** informs about availability of a primal simplex solving method */
    1076 void
    1077 )
    1078{
    1079 return TRUE;
    1080}
    1081
    1082/** informs about availability of a dual simplex solving method */
    1084 void
    1085 )
    1086{
    1087 return TRUE;
    1088}
    1089
    1090/** informs about availability of a barrier solving method */
    1092 void
    1093 )
    1094{
    1095 return TRUE;
    1096}
    1097
    1098/**@} */
    1099
    1100
    1101
    1102
    1103/*
    1104 * LPI Creation and Destruction Methods
    1105 */
    1106
    1107/**@name LPI Creation and Destruction Methods */
    1108/**@{ */
    1109
    1110/** creates an LP problem object */
    1112 SCIP_LPI** lpi, /**< pointer to an LP interface structure */
    1113 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler to use for printing messages, or NULL */
    1114 const char* name, /**< problem name */
    1115 SCIP_OBJSEN objsen /**< objective sense */
    1116 )
    1117{
    1118 int restat;
    1119
    1120 assert(sizeof(SCIP_Real) == sizeof(double)); /* CPLEX only works with doubles as floating points */ /*lint !e506*/
    1121 assert(lpi != NULL);
    1122 assert(name != NULL);
    1123
    1124 SCIPdebugMessage("SCIPlpiCreate()\n");
    1125
    1126 SCIP_ALLOC( BMSallocMemory(lpi) );
    1127
    1128 /* create environment */
    1129 (*lpi)->cpxenv = CPXopenCPLEX(&restat);
    1130 CHECK_ZERO( messagehdlr, restat );
    1131
    1132#if (CPX_VERSION == 1100 || (CPX_VERSION == 1220 && (CPX_SUBVERSION == 0 || CPX_SUBVERSION == 2)))
    1133 /* manually set number of threads to 1 to avoid huge system load due to CPLEX bug (version 1100) or segmentation fault (version 1220) */
    1134 CHECK_ZERO( messagehdlr, CPXsetintparam((*lpi)->cpxenv, CPX_PARAM_THREADS, 1) );
    1135#endif
    1136
    1137#ifdef SCIP_DISABLED_CODE /* turning presolve off seems to be faster than turning it off on demand (if presolve detects infeasibility) */
    1138 /* turn presolve off, s.t. for an infeasible problem, a ray is always available */
    1139 CHECK_ZERO( messagehdlr, CPXsetintparam((*lpi)->cpxenv, CPX_PARAM_PREIND, CPX_OFF) );
    1140#endif
    1141
    1142#if (CPX_VERSION == 12070000)
    1143 /* due to a bug in CPLEX 12.7.0, we need to disable scaling for this version */
    1144 CHECK_ZERO( messagehdlr, CPXsetintparam((*lpi)->cpxenv, CPX_PARAM_SCAIND, -1) );
    1145#endif
    1146
    1147 /* get default parameter values */
    1148 SCIP_CALL( getParameterValues((*lpi), &((*lpi)->defparam)) );
    1149 copyParameterValues(&((*lpi)->curparam), &((*lpi)->defparam));
    1150
    1151 /* create LP */
    1152 (*lpi)->larray = NULL;
    1153 (*lpi)->uarray = NULL;
    1154 (*lpi)->senarray = NULL;
    1155 (*lpi)->rhsarray = NULL;
    1156 (*lpi)->rngarray = NULL;
    1157 (*lpi)->valarray = NULL;
    1158 (*lpi)->rngindarray = NULL;
    1159 (*lpi)->cstat = NULL;
    1160 (*lpi)->rstat = NULL;
    1161 (*lpi)->indarray = NULL;
    1162 (*lpi)->boundchgsize = 0;
    1163 (*lpi)->sidechgsize = 0;
    1164 (*lpi)->valsize = 0;
    1165 (*lpi)->cstatsize = 0;
    1166 (*lpi)->rstatsize = 0;
    1167 (*lpi)->iterations = 0;
    1168 (*lpi)->pricing = SCIP_PRICING_LPIDEFAULT;
    1169 (*lpi)->solisbasic = FALSE;
    1170 (*lpi)->cpxlp = CPXcreateprob((*lpi)->cpxenv, &restat, name);
    1171 (*lpi)->instabilityignored = FALSE;
    1172 (*lpi)->fromscratch = FALSE;
    1173 (*lpi)->clearstate = FALSE;
    1174 (*lpi)->feastol = 1e-06;
    1175 (*lpi)->conditionlimit = -1.0;
    1176 (*lpi)->checkcondition = FALSE;
    1177#if (CPX_VERSION <= 1100)
    1178 (*lpi)->rngfound = FALSE;
    1179#endif
    1180 (*lpi)->messagehdlr = messagehdlr;
    1181
    1182 CHECK_ZERO( messagehdlr, restat );
    1183 invalidateSolution(*lpi);
    1184 copyParameterValues(&((*lpi)->cpxparam), &((*lpi)->defparam));
    1185
    1186 /* set objective sense */
    1187 SCIP_CALL( SCIPlpiChgObjsen(*lpi, objsen) );
    1188
    1189 /* set default pricing */
    1190 SCIP_CALL( SCIPlpiSetIntpar(*lpi, SCIP_LPPAR_PRICING, (int)(*lpi)->pricing) );
    1191
    1192 return SCIP_OKAY;
    1193}
    1194
    1195/** deletes an LP problem object */
    1197 SCIP_LPI** lpi /**< pointer to an LP interface structure */
    1198 )
    1199{
    1200 assert(lpi != NULL);
    1201 assert(*lpi != NULL);
    1202 assert((*lpi)->cpxenv != NULL);
    1203
    1204 SCIPdebugMessage("SCIPlpiFree()\n");
    1205
    1206 /* free LP */
    1207 CHECK_ZERO( (*lpi)->messagehdlr, CPXfreeprob((*lpi)->cpxenv, &((*lpi)->cpxlp)) );
    1208
    1209 /* free memory */
    1210 BMSfreeMemoryArrayNull(&(*lpi)->larray);
    1211 BMSfreeMemoryArrayNull(&(*lpi)->uarray);
    1212 BMSfreeMemoryArrayNull(&(*lpi)->senarray);
    1213 BMSfreeMemoryArrayNull(&(*lpi)->rhsarray);
    1214 BMSfreeMemoryArrayNull(&(*lpi)->rngarray);
    1215 BMSfreeMemoryArrayNull(&(*lpi)->valarray);
    1216 BMSfreeMemoryArrayNull(&(*lpi)->rngindarray);
    1217 BMSfreeMemoryArrayNull(&(*lpi)->cstat);
    1218 BMSfreeMemoryArrayNull(&(*lpi)->rstat);
    1219 BMSfreeMemoryArrayNull(&(*lpi)->indarray);
    1220
    1221 /* free environment */
    1222 CHECK_ZERO( (*lpi)->messagehdlr, CPXcloseCPLEX(&((*lpi)->cpxenv)) );
    1223
    1224 BMSfreeMemory(lpi);
    1225
    1226 return SCIP_OKAY;
    1227}
    1228
    1229/**@} */
    1230
    1231
    1232
    1233
    1234/*
    1235 * Modification Methods
    1236 */
    1237
    1238/**@name Modification Methods */
    1239/**@{ */
    1240
    1241/** copies LP data with column matrix into LP solver */
    1243 SCIP_LPI* lpi, /**< LP interface structure */
    1244 SCIP_OBJSEN objsen, /**< objective sense */
    1245 int ncols, /**< number of columns */
    1246 const SCIP_Real* obj, /**< objective function values of columns */
    1247 const SCIP_Real* lb, /**< lower bounds of columns */
    1248 const SCIP_Real* ub, /**< upper bounds of columns */
    1249 char** colnames, /**< column names, or NULL */
    1250 int nrows, /**< number of rows */
    1251 const SCIP_Real* lhs, /**< left hand sides of rows */
    1252 const SCIP_Real* rhs, /**< right hand sides of rows */
    1253 char** rownames, /**< row names, or NULL */
    1254 int nnonz, /**< number of nonzero elements in the constraint matrix */
    1255 const int* beg, /**< start index of each column in ind- and val-array */
    1256 const int* ind, /**< row indices of constraint matrix entries */
    1257 const SCIP_Real* val /**< values of constraint matrix entries */
    1258 )
    1259{
    1260 int* cnt;
    1261 int rngcount;
    1262 int c;
    1263
    1264#ifndef NDEBUG
    1265 {
    1266 int j;
    1267 for( j = 0; j < nnonz; j++ )
    1268 assert( val[j] != 0 );
    1269 }
    1270#endif
    1271
    1272 assert(lpi != NULL);
    1273 assert(lpi->cpxlp != NULL);
    1274 assert(lpi->cpxenv != NULL);
    1275 assert(obj != NULL);
    1276 assert(lb != NULL);
    1277 assert(ub != NULL);
    1278 assert(beg != NULL);
    1279 assert(ind != NULL);
    1280 assert(val != NULL);
    1281
    1282 SCIPdebugMessage("loading LP in column format into CPLEX: %d cols, %d rows\n", ncols, nrows);
    1283
    1284 invalidateSolution(lpi);
    1285
    1286 SCIP_CALL( ensureSidechgMem(lpi, nrows) );
    1287
    1288 /* convert lhs/rhs into sen/rhs/range tuples */
    1289 convertSides(lpi, nrows, lhs, rhs, 0, &rngcount);
    1290
    1291 /* calculate column lengths */
    1292 SCIP_ALLOC( BMSallocMemoryArray(&cnt, ncols) );
    1293 for( c = 0; c < ncols-1; ++c )
    1294 {
    1295 cnt[c] = beg[c+1] - beg[c];
    1296 assert(cnt[c] >= 0);
    1297 }
    1298 cnt[ncols-1] = nnonz - beg[ncols-1];
    1299 assert(cnt[ncols-1] >= 0);
    1300
    1301 /* copy data into CPLEX */
    1302 CHECK_ZERO( lpi->messagehdlr, CPXcopylpwnames(lpi->cpxenv, lpi->cpxlp, ncols, nrows, cpxObjsen(objsen), obj,
    1303 lpi->rhsarray, lpi->senarray, beg, cnt, ind, val, lb, ub, lpi->rngarray, colnames, rownames) );
    1304
    1305 /* free temporary memory */
    1306 BMSfreeMemoryArray(&cnt);
    1307
    1308 assert(CPXgetnumcols(lpi->cpxenv, lpi->cpxlp) == ncols);
    1309 assert(CPXgetnumrows(lpi->cpxenv, lpi->cpxlp) == nrows);
    1310 assert(CPXgetnumnz(lpi->cpxenv, lpi->cpxlp) == nnonz);
    1311
    1312 return SCIP_OKAY;
    1313}
    1314
    1315/** adds columns to the LP */
    1317 SCIP_LPI* lpi, /**< LP interface structure */
    1318 int ncols, /**< number of columns to be added */
    1319 const SCIP_Real* obj, /**< objective function values of new columns */
    1320 const SCIP_Real* lb, /**< lower bounds of new columns */
    1321 const SCIP_Real* ub, /**< upper bounds of new columns */
    1322 char** colnames, /**< column names, or NULL */
    1323 int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
    1324 const int* beg, /**< start index of each column in ind- and val-array, or NULL if nnonz == 0 */
    1325 const int* ind, /**< row indices of constraint matrix entries, or NULL if nnonz == 0 */
    1326 const SCIP_Real* val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
    1327 )
    1328{
    1329 assert(lpi != NULL);
    1330 assert(lpi->cpxlp != NULL);
    1331 assert(lpi->cpxenv != NULL);
    1332 assert(obj != NULL);
    1333 assert(lb != NULL);
    1334 assert(ub != NULL);
    1335 assert(nnonz == 0 || beg != NULL);
    1336 assert(nnonz == 0 || ind != NULL);
    1337 assert(nnonz == 0 || val != NULL);
    1338 assert(nnonz >= 0);
    1339 assert(ncols >= 0);
    1340
    1341 SCIPdebugMessage("adding %d columns with %d nonzeros to CPLEX\n", ncols, nnonz);
    1342
    1343 invalidateSolution(lpi);
    1344
    1345 if( nnonz > 0 )
    1346 {
    1347#ifndef NDEBUG
    1348 /* perform check that no new rows are added - this is forbidden, see the CPLEX documentation */
    1349 int nrows;
    1350 int j;
    1351
    1352 nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
    1353 for (j = 0; j < nnonz; ++j)
    1354 {
    1355 assert( 0 <= ind[j] && ind[j] < nrows );
    1356 assert( val[j] != 0.0 );
    1357 }
    1358#endif
    1359
    1360 CHECK_ZERO( lpi->messagehdlr, CPXaddcols(lpi->cpxenv, lpi->cpxlp, ncols, nnonz, obj, beg, ind, val, lb, ub, colnames) );
    1361 }
    1362 else
    1363 {
    1364 CHECK_ZERO( lpi->messagehdlr, CPXnewcols(lpi->cpxenv, lpi->cpxlp, ncols, obj, lb, ub, NULL, colnames) );
    1365 }
    1366
    1367 return SCIP_OKAY;
    1368}
    1369
    1370/** deletes all columns in the given range from LP */
    1372 SCIP_LPI* lpi, /**< LP interface structure */
    1373 int firstcol, /**< first column to be deleted */
    1374 int lastcol /**< last column to be deleted */
    1375 )
    1376{
    1377 assert(lpi != NULL);
    1378 assert(lpi->cpxlp != NULL);
    1379 assert(lpi->cpxenv != NULL);
    1380 assert(firstcol >= 0);
    1381 assert(lastcol < CPXgetnumcols(lpi->cpxenv, lpi->cpxlp));
    1382 assert(firstcol <= lastcol + 1);
    1383
    1384 SCIPdebugMessage("deleting %d columns from CPLEX\n", lastcol - firstcol + 1);
    1385
    1386 /* handle empty range */
    1387 if( firstcol > lastcol )
    1388 return SCIP_OKAY;
    1389
    1390 invalidateSolution(lpi);
    1391
    1392 CHECK_ZERO( lpi->messagehdlr, CPXdelcols(lpi->cpxenv, lpi->cpxlp, firstcol, lastcol) );
    1393
    1394 return SCIP_OKAY;
    1395}
    1396
    1397/** deletes columns from SCIP_LP; the new position of a column must not be greater that its old position */
    1399 SCIP_LPI* lpi, /**< LP interface structure */
    1400 int* dstat /**< deletion status of columns
    1401 * input: 1 if column should be deleted, 0 if not
    1402 * output: new position of column, -1 if column was deleted */
    1403 )
    1404{
    1405 assert(lpi != NULL);
    1406 assert(lpi->cpxlp != NULL);
    1407 assert(lpi->cpxenv != NULL);
    1408 assert(dstat != NULL);
    1409
    1410 SCIPdebugMessage("deleting a column set from CPLEX\n");
    1411
    1412 invalidateSolution(lpi);
    1413
    1414 CHECK_ZERO( lpi->messagehdlr, CPXdelsetcols(lpi->cpxenv, lpi->cpxlp, dstat) );
    1415
    1416 return SCIP_OKAY;
    1417}
    1418
    1419/** adds rows to the LP */
    1421 SCIP_LPI* lpi, /**< LP interface structure */
    1422 int nrows, /**< number of rows to be added */
    1423 const SCIP_Real* lhs, /**< left hand sides of new rows */
    1424 const SCIP_Real* rhs, /**< right hand sides of new rows */
    1425 char** rownames, /**< row names, or NULL */
    1426 int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
    1427 const int* beg, /**< start index of each row in ind- and val-array, or NULL if nnonz == 0 */
    1428 const int* ind, /**< column indices of constraint matrix entries, or NULL if nnonz == 0 */
    1429 const SCIP_Real* val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
    1430 )
    1431{
    1432 int rngcount;
    1433
    1434 assert(lpi != NULL);
    1435 assert(lpi->cpxlp != NULL);
    1436 assert(lpi->cpxenv != NULL);
    1437 assert(lhs != NULL);
    1438 assert(rhs != NULL);
    1439 assert(nnonz == 0 || beg != NULL);
    1440 assert(nnonz == 0 || ind != NULL);
    1441 assert(nnonz == 0 || val != NULL);
    1442
    1443 SCIPdebugMessage("adding %d rows with %d nonzeros to CPLEX\n", nrows, nnonz);
    1444
    1445 invalidateSolution(lpi);
    1446
    1447 SCIP_CALL( ensureSidechgMem(lpi, nrows) );
    1448
    1449 /* convert lhs/rhs into sen/rhs/range tuples */
    1450 convertSides(lpi, nrows, lhs, rhs, CPXgetnumrows(lpi->cpxenv, lpi->cpxlp), &rngcount);
    1451
    1452 /* add rows to LP */
    1453 if( nnonz > 0 )
    1454 {
    1455#ifndef NDEBUG
    1456 /* perform check that no new columns are added - this is likely to be a mistake */
    1457 int ncols;
    1458 int j;
    1459
    1460 ncols = CPXgetnumcols(lpi->cpxenv, lpi->cpxlp);
    1461 for (j = 0; j < nnonz; ++j) {
    1462 assert( val[j] != 0.0 );
    1463 assert( 0 <= ind[j] && ind[j] < ncols );
    1464 }
    1465#endif
    1466 CHECK_ZERO( lpi->messagehdlr, CPXaddrows(lpi->cpxenv, lpi->cpxlp, 0, nrows, nnonz, lpi->rhsarray, lpi->senarray, beg, ind, val, NULL,
    1467 rownames) );
    1468 }
    1469 else
    1470 {
    1471 CHECK_ZERO( lpi->messagehdlr, CPXnewrows(lpi->cpxenv, lpi->cpxlp, nrows, lpi->rhsarray, lpi->senarray, NULL, rownames) );
    1472 }
    1473 if( rngcount > 0 )
    1474 {
    1475#if (CPX_VERSION <= 1100)
    1476 if( lpi->rngfound == FALSE )
    1477 {
    1479 lpi->rngfound = TRUE;
    1480 }
    1481#endif
    1482 CHECK_ZERO( lpi->messagehdlr, CPXchgrngval(lpi->cpxenv, lpi->cpxlp, rngcount, lpi->rngindarray, lpi->rngarray) );
    1483 }
    1484
    1485 return SCIP_OKAY;
    1486}
    1487
    1488/** deletes all rows in the given range from LP */
    1490 SCIP_LPI* lpi, /**< LP interface structure */
    1491 int firstrow, /**< first row to be deleted */
    1492 int lastrow /**< last row to be deleted */
    1493 )
    1494{
    1495 assert(lpi != NULL);
    1496 assert(lpi->cpxlp != NULL);
    1497 assert(lpi->cpxenv != NULL);
    1498 assert(firstrow >= 0);
    1499 assert(lastrow < CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
    1500 assert(firstrow <= lastrow + 1);
    1501
    1502 SCIPdebugMessage("deleting %d rows from CPLEX\n", lastrow - firstrow + 1);
    1503
    1504 /* handle empty range */
    1505 if( firstrow > lastrow )
    1506 return SCIP_OKAY;
    1507
    1508 invalidateSolution(lpi);
    1509
    1510 CHECK_ZERO( lpi->messagehdlr, CPXdelrows(lpi->cpxenv, lpi->cpxlp, firstrow, lastrow) );
    1511
    1512 return SCIP_OKAY;
    1513}
    1514
    1515/** deletes rows from SCIP_LP; the new position of a row must not be greater that its old position */
    1517 SCIP_LPI* lpi, /**< LP interface structure */
    1518 int* dstat /**< deletion status of rows
    1519 * input: 1 if row should be deleted, 0 if not
    1520 * output: new position of row, -1 if row was deleted */
    1521 )
    1522{
    1523 assert(lpi != NULL);
    1524 assert(lpi->cpxlp != NULL);
    1525 assert(lpi->cpxenv != NULL);
    1526
    1527 SCIPdebugMessage("deleting a row set from CPLEX\n");
    1528
    1529 invalidateSolution(lpi);
    1530
    1531 CHECK_ZERO( lpi->messagehdlr, CPXdelsetrows(lpi->cpxenv, lpi->cpxlp, dstat) );
    1532
    1533 return SCIP_OKAY;
    1534}
    1535
    1536/** clears the whole LP */
    1538 SCIP_LPI* lpi /**< LP interface structure */
    1539 )
    1540{
    1541 int ncols;
    1542 int nrows;
    1543
    1544 assert(lpi != NULL);
    1545 assert(lpi->cpxlp != NULL);
    1546 assert(lpi->cpxenv != NULL);
    1547
    1548 SCIPdebugMessage("clearing CPLEX LP\n");
    1549
    1550 invalidateSolution(lpi);
    1551
    1552 ncols = CPXgetnumcols(lpi->cpxenv, lpi->cpxlp);
    1553 nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
    1554 if( ncols >= 1 )
    1555 {
    1556 CHECK_ZERO( lpi->messagehdlr, CPXdelcols(lpi->cpxenv, lpi->cpxlp, 0, ncols-1) );
    1557 }
    1558 if( nrows >= 1 )
    1559 {
    1560 CHECK_ZERO( lpi->messagehdlr, CPXdelrows(lpi->cpxenv, lpi->cpxlp, 0, nrows-1) );
    1561 }
    1562
    1563 return SCIP_OKAY;
    1564}
    1565
    1566/** changes lower and upper bounds of columns */
    1568 SCIP_LPI* lpi, /**< LP interface structure */
    1569 int ncols, /**< number of columns to change bounds for */
    1570 const int* ind, /**< column indices or NULL if ncols is zero */
    1571 const SCIP_Real* lb, /**< values for the new lower bounds or NULL if ncols is zero */
    1572 const SCIP_Real* ub /**< values for the new upper bounds or NULL if ncols is zero */
    1573 )
    1574{
    1575 int i;
    1576
    1577 assert(lpi != NULL);
    1578 assert(lpi->cpxlp != NULL);
    1579 assert(lpi->cpxenv != NULL);
    1580 assert(ncols == 0 || (ind != NULL && lb != NULL && ub != NULL));
    1581
    1582 SCIPdebugMessage("changing %d bounds in CPLEX\n", ncols);
    1583 if( ncols <= 0 )
    1584 return SCIP_OKAY;
    1585
    1586 for( i = 0; i < ncols; ++i )
    1587 {
    1588 SCIPdebugPrintf(" col %d: [%g,%g]\n", ind[i], lb[i], ub[i]);
    1589
    1590 if ( SCIPlpiIsInfinity(lpi, lb[i]) )
    1591 {
    1592 SCIPerrorMessage("LP Error: fixing lower bound for variable %d to infinity.\n", ind[i]);
    1593 return SCIP_LPERROR;
    1594 }
    1595 if ( SCIPlpiIsInfinity(lpi, -ub[i]) )
    1596 {
    1597 SCIPerrorMessage("LP Error: fixing upper bound for variable %d to -infinity.\n", ind[i]);
    1598 return SCIP_LPERROR;
    1599 }
    1600 }
    1601
    1602 invalidateSolution(lpi);
    1603
    1604 SCIP_CALL( ensureBoundchgMem(lpi, ncols) );
    1605
    1606 CHECK_ZERO( lpi->messagehdlr, CPXchgbds(lpi->cpxenv, lpi->cpxlp, ncols, ind, lpi->larray, (SCIP_Real*)lb) );
    1607 CHECK_ZERO( lpi->messagehdlr, CPXchgbds(lpi->cpxenv, lpi->cpxlp, ncols, ind, lpi->uarray, (SCIP_Real*)ub) );
    1608
    1609#ifndef NDEBUG
    1610 {
    1611 for( i = 0; i < ncols; ++i )
    1612 {
    1613 SCIP_Real cpxlb;
    1614 SCIP_Real cpxub;
    1615
    1616 CHECK_ZERO( lpi->messagehdlr, CPXgetlb(lpi->cpxenv, lpi->cpxlp, &cpxlb, ind[i], ind[i]) );
    1617 CHECK_ZERO( lpi->messagehdlr, CPXgetub(lpi->cpxenv, lpi->cpxlp, &cpxub, ind[i], ind[i]) );
    1618
    1619 /* Note that CPLEX seems to set bounds below 1e-10 in absolute value to 0.*/
    1620 assert( EPSZ(cpxlb, CPX_MAGICZEROCONSTANT) || cpxlb == lb[i] ); /*lint !e777*/
    1621 assert( EPSZ(cpxub, CPX_MAGICZEROCONSTANT) || cpxub == ub[i] ); /*lint !e777*/
    1622 }
    1623 }
    1624#endif
    1625
    1626 return SCIP_OKAY;
    1627}
    1628
    1629/** changes left and right hand sides of rows */
    1631 SCIP_LPI* lpi, /**< LP interface structure */
    1632 int nrows, /**< number of rows to change sides for */
    1633 const int* ind, /**< row indices */
    1634 const SCIP_Real* lhs, /**< new values for left hand sides */
    1635 const SCIP_Real* rhs /**< new values for right hand sides */
    1636 )
    1637{
    1638 int rngcount;
    1639 int i;
    1640
    1641 assert(lpi != NULL);
    1642 assert(lpi->cpxlp != NULL);
    1643 assert(lpi->cpxenv != NULL);
    1644
    1645 if( nrows <= 0 )
    1646 return SCIP_OKAY;
    1647
    1648 SCIPdebugMessage("changing %d sides in CPLEX\n", nrows);
    1649
    1650 invalidateSolution(lpi);
    1651
    1652 SCIP_CALL( ensureSidechgMem(lpi, nrows) );
    1653
    1654 /* convert lhs/rhs into sen/rhs/range tuples */
    1655 convertSides(lpi, nrows, lhs, rhs, 0, &rngcount);
    1656
    1657 /* change row sides */
    1658 CHECK_ZERO( lpi->messagehdlr, CPXchgsense(lpi->cpxenv, lpi->cpxlp, nrows, ind, lpi->senarray) );
    1659 CHECK_ZERO( lpi->messagehdlr, CPXchgrhs(lpi->cpxenv, lpi->cpxlp, nrows, ind, lpi->rhsarray) );
    1660 if( rngcount > 0 )
    1661 {
    1662 /* adjust the range count indices to the correct row indices */
    1663 for( i = 0; i < rngcount; ++i )
    1664 {
    1665 assert(0 <= lpi->rngindarray[i] && lpi->rngindarray[i] < nrows);
    1666 assert(lpi->senarray[lpi->rngindarray[i]] == 'R');
    1667 lpi->rngindarray[i] = ind[lpi->rngindarray[i]];
    1668 }
    1669
    1670 /* change the range values in CPLEX */
    1671 CHECK_ZERO( lpi->messagehdlr, CPXchgrngval(lpi->cpxenv, lpi->cpxlp, rngcount, lpi->rngindarray, lpi->rngarray) );
    1672 }
    1673
    1674 return SCIP_OKAY;
    1675}
    1676
    1677/** changes a single coefficient */
    1679 SCIP_LPI* lpi, /**< LP interface structure */
    1680 int row, /**< row number of coefficient to change */
    1681 int col, /**< column number of coefficient to change */
    1682 SCIP_Real newval /**< new value of coefficient */
    1683 )
    1684{
    1685 assert(lpi != NULL);
    1686 assert(lpi->cpxlp != NULL);
    1687 assert(lpi->cpxenv != NULL);
    1688
    1689 SCIPdebugMessage("changing coefficient row %d, column %d in CPLEX to %g\n", row, col, newval);
    1690
    1691 invalidateSolution(lpi);
    1692
    1693 CHECK_ZERO( lpi->messagehdlr, CPXchgcoef(lpi->cpxenv, lpi->cpxlp, row, col, newval) );
    1694
    1695 return SCIP_OKAY;
    1696}
    1697
    1698/** changes the objective sense */
    1700 SCIP_LPI* lpi, /**< LP interface structure */
    1701 SCIP_OBJSEN objsen /**< new objective sense */
    1702 )
    1703{
    1704 assert(lpi != NULL);
    1705 assert(lpi->cpxlp != NULL);
    1706 assert(lpi->cpxenv != NULL);
    1707
    1708 SCIPdebugMessage("changing objective sense in CPLEX to %d\n", objsen);
    1709
    1710 invalidateSolution(lpi);
    1711
    1712#if (CPX_VERSION >= 12050000)
    1713 CHECK_ZERO( lpi->messagehdlr, CPXchgobjsen(lpi->cpxenv, lpi->cpxlp, cpxObjsen(objsen)) );
    1714#else
    1715 CPXchgobjsen(lpi->cpxenv, lpi->cpxlp, cpxObjsen(objsen));
    1716#endif
    1717
    1718 return SCIP_OKAY;
    1719}
    1720
    1721/** changes objective values of columns in the LP */
    1723 SCIP_LPI* lpi, /**< LP interface structure */
    1724 int ncols, /**< number of columns to change objective value for */
    1725 const int* ind, /**< column indices to change objective value for */
    1726 const SCIP_Real* obj /**< new objective values for columns */
    1727 )
    1728{
    1729 assert(lpi != NULL);
    1730 assert(lpi->cpxlp != NULL);
    1731 assert(lpi->cpxenv != NULL);
    1732 assert(ind != NULL);
    1733 assert(obj != NULL);
    1734
    1735 SCIPdebugMessage("changing %d objective values in CPLEX\n", ncols);
    1736
    1737 invalidateSolution(lpi);
    1738
    1739 CHECK_ZERO( lpi->messagehdlr, CPXchgobj(lpi->cpxenv, lpi->cpxlp, ncols, ind, obj) );
    1740
    1741 return SCIP_OKAY;
    1742}
    1743
    1744/** multiplies a row with a non-zero scalar; for negative scalars, the row's sense is switched accordingly */
    1746 SCIP_LPI* lpi, /**< LP interface structure */
    1747 int row, /**< row number to scale */
    1748 SCIP_Real scaleval /**< scaling multiplier */
    1749 )
    1750{
    1751 SCIP_Real lhs;
    1752 SCIP_Real rhs;
    1753 int nnonz;
    1754 int beg;
    1755 int i;
    1756
    1757 assert(lpi != NULL);
    1758 assert(lpi->cpxlp != NULL);
    1759 assert(lpi->cpxenv != NULL);
    1760 assert(scaleval != 0.0);
    1761
    1762 SCIPdebugMessage("scaling row %d with factor %g in CPLEX\n", row, scaleval);
    1763
    1764 invalidateSolution(lpi);
    1765
    1766 SCIP_CALL( ensureValMem(lpi, CPXgetnumcols(lpi->cpxenv, lpi->cpxlp)) );
    1767
    1768 /* get the row */
    1769 SCIP_CALL( SCIPlpiGetRows(lpi, row, row, &lhs, &rhs, &nnonz, &beg, lpi->indarray, lpi->valarray) );
    1770
    1771 /* scale row coefficients */
    1772 for( i = 0; i < nnonz; ++i )
    1773 {
    1774 SCIP_CALL( SCIPlpiChgCoef(lpi, row, lpi->indarray[i], lpi->valarray[i] * scaleval) );
    1775 }
    1776
    1777 /* scale row sides */
    1778 if( lhs > -CPX_INFBOUND )
    1779 lhs *= scaleval;
    1780 else if( scaleval < 0.0 )
    1781 lhs = CPX_INFBOUND;
    1782 if( rhs < CPX_INFBOUND )
    1783 rhs *= scaleval;
    1784 else if( scaleval < 0.0 )
    1785 rhs = -CPX_INFBOUND;
    1786 if( scaleval > 0.0 )
    1787 {
    1788 SCIP_CALL( SCIPlpiChgSides(lpi, 1, &row, &lhs, &rhs) );
    1789 }
    1790 else
    1791 {
    1792 SCIP_CALL( SCIPlpiChgSides(lpi, 1, &row, &rhs, &lhs) );
    1793 }
    1794
    1795 return SCIP_OKAY;
    1796}
    1797
    1798/** multiplies a column with a non-zero scalar; the objective value is multiplied with the scalar, and the bounds
    1799 * are divided by the scalar; for negative scalars, the column's bounds are switched
    1800 */
    1802 SCIP_LPI* lpi, /**< LP interface structure */
    1803 int col, /**< column number to scale */
    1804 SCIP_Real scaleval /**< scaling multiplier */
    1805 )
    1806{
    1807 SCIP_Real lb;
    1808 SCIP_Real ub;
    1809 SCIP_Real obj;
    1810 int nnonz;
    1811 int beg;
    1812 int i;
    1813
    1814 assert(lpi != NULL);
    1815 assert(lpi->cpxlp != NULL);
    1816 assert(lpi->cpxenv != NULL);
    1817 assert(scaleval != 0.0);
    1818
    1819 SCIPdebugMessage("scaling column %d with factor %g in CPLEX\n", col, scaleval);
    1820
    1821 invalidateSolution(lpi);
    1822
    1823 SCIP_CALL( ensureValMem(lpi, CPXgetnumrows(lpi->cpxenv, lpi->cpxlp)) );
    1824
    1825 /* get the column */
    1826 SCIP_CALL( SCIPlpiGetCols(lpi, col, col, &lb, &ub, &nnonz, &beg, lpi->indarray, lpi->valarray) );
    1827
    1828 /* get objective coefficient */
    1829 SCIP_CALL( SCIPlpiGetObj(lpi, col, col, &obj) );
    1830
    1831 /* scale column coefficients */
    1832 for( i = 0; i < nnonz; ++i )
    1833 {
    1834 SCIP_CALL( SCIPlpiChgCoef(lpi, lpi->indarray[i], col, lpi->valarray[i] * scaleval) );
    1835 }
    1836
    1837 /* scale objective value */
    1838 obj *= scaleval;
    1839 SCIP_CALL( SCIPlpiChgObj(lpi, 1, &col, &obj) );
    1840
    1841 /* scale column bounds */
    1842 if( lb > -CPX_INFBOUND )
    1843 lb /= scaleval;
    1844 else if( scaleval < 0.0 )
    1845 lb = CPX_INFBOUND;
    1846 if( ub < CPX_INFBOUND )
    1847 ub /= scaleval;
    1848 else if( scaleval < 0.0 )
    1849 ub = -CPX_INFBOUND;
    1850 if( scaleval > 0.0 )
    1851 {
    1852 SCIP_CALL( SCIPlpiChgBounds(lpi, 1, &col, &lb, &ub) );
    1853 }
    1854 else
    1855 {
    1856 SCIP_CALL( SCIPlpiChgBounds(lpi, 1, &col, &ub, &lb) );
    1857 }
    1858
    1859 return SCIP_OKAY;
    1860}
    1861
    1862/**@} */
    1863
    1864
    1865
    1866
    1867/*
    1868 * Data Accessing Methods
    1869 */
    1870
    1871/**@name Data Accessing Methods */
    1872/**@{ */
    1873
    1874/** gets the number of rows in the LP */
    1876 SCIP_LPI* lpi, /**< LP interface structure */
    1877 int* nrows /**< pointer to store the number of rows */
    1878 )
    1879{
    1880 assert(lpi != NULL);
    1881 assert(lpi->cpxenv != NULL);
    1882 assert(nrows != NULL);
    1883
    1884 SCIPdebugMessage("getting number of rows\n");
    1885
    1886 *nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
    1887
    1888 return SCIP_OKAY;
    1889}
    1890
    1891/** gets the number of columns in the LP */
    1893 SCIP_LPI* lpi, /**< LP interface structure */
    1894 int* ncols /**< pointer to store the number of cols */
    1895 )
    1896{
    1897 assert(lpi != NULL);
    1898 assert(lpi->cpxenv != NULL);
    1899 assert(ncols != NULL);
    1900
    1901 SCIPdebugMessage("getting number of columns\n");
    1902
    1903 *ncols = CPXgetnumcols(lpi->cpxenv, lpi->cpxlp);
    1904
    1905 return SCIP_OKAY;
    1906}
    1907
    1908/** gets the number of nonzero elements in the LP constraint matrix */
    1910 SCIP_LPI* lpi, /**< LP interface structure */
    1911 int* nnonz /**< pointer to store the number of nonzeros */
    1912 )
    1913{
    1914 assert(lpi != NULL);
    1915 assert(lpi->cpxenv != NULL);
    1916 assert(nnonz != NULL);
    1917
    1918 SCIPdebugMessage("getting number of non-zeros\n");
    1919
    1920 *nnonz = CPXgetnumnz(lpi->cpxenv, lpi->cpxlp);
    1921
    1922 return SCIP_OKAY;
    1923}
    1924
    1925/** gets columns from LP problem object; the arrays have to be large enough to store all values
    1926 * Either both, lb and ub, have to be NULL, or both have to be non-NULL,
    1927 * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
    1928 */
    1930 SCIP_LPI* lpi, /**< LP interface structure */
    1931 int firstcol, /**< first column to get from LP */
    1932 int lastcol, /**< last column to get from LP */
    1933 SCIP_Real* lb, /**< buffer to store the lower bound vector, or NULL */
    1934 SCIP_Real* ub, /**< buffer to store the upper bound vector, or NULL */
    1935 int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
    1936 int* beg, /**< buffer to store start index of each column in ind- and val-array, or NULL */
    1937 int* ind, /**< buffer to store row indices of constraint matrix entries, or NULL */
    1938 SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
    1939 )
    1940{
    1941 assert(lpi != NULL);
    1942 assert(lpi->cpxlp != NULL);
    1943 assert(lpi->cpxenv != NULL);
    1944 assert((lb != NULL && ub != NULL) || (lb == NULL && ub == NULL));
    1945 assert((nnonz != NULL && beg != NULL && ind != NULL && val != NULL) || (nnonz == NULL && beg == NULL && ind == NULL && val == NULL));
    1946 assert(firstcol >= 0);
    1947 assert(lastcol < CPXgetnumcols(lpi->cpxenv, lpi->cpxlp));
    1948 assert(firstcol <= lastcol + 1);
    1949
    1950 SCIPdebugMessage("getting columns %d to %d\n", firstcol, lastcol);
    1951
    1952 if( lb != NULL )
    1953 {
    1954 CHECK_ZERO( lpi->messagehdlr, CPXgetlb(lpi->cpxenv, lpi->cpxlp, lb, firstcol, lastcol) );
    1955 CHECK_ZERO( lpi->messagehdlr, CPXgetub(lpi->cpxenv, lpi->cpxlp, ub, firstcol, lastcol) );
    1956 }
    1957
    1958 if( nnonz != NULL )
    1959 {
    1960 int surplus;
    1961
    1962 /* get matrix entries */
    1963 CHECK_ZERO( lpi->messagehdlr, CPXgetcols(lpi->cpxenv, lpi->cpxlp, nnonz, beg, ind, val,
    1964 CPXgetnumnz(lpi->cpxenv, lpi->cpxlp), &surplus, firstcol, lastcol) );
    1965 assert(surplus >= 0);
    1966 }
    1967
    1968 return SCIP_OKAY;
    1969}
    1970
    1971/** gets rows from LP problem object; the arrays have to be large enough to store all values.
    1972 * Either both, lhs and rhs, have to be NULL, or both have to be non-NULL,
    1973 * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
    1974 */
    1976 SCIP_LPI* lpi, /**< LP interface structure */
    1977 int firstrow, /**< first row to get from LP */
    1978 int lastrow, /**< last row to get from LP */
    1979 SCIP_Real* lhs, /**< buffer to store left hand side vector, or NULL */
    1980 SCIP_Real* rhs, /**< buffer to store right hand side vector, or NULL */
    1981 int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
    1982 int* beg, /**< buffer to store start index of each row in ind- and val-array, or NULL */
    1983 int* ind, /**< buffer to store column indices of constraint matrix entries, or NULL */
    1984 SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
    1985 )
    1986{
    1987#if CPX_VERSION < 12070000
    1988 int retcode;
    1989#endif
    1990
    1991 assert(lpi != NULL);
    1992 assert(lpi->cpxlp != NULL);
    1993 assert(lpi->cpxenv != NULL);
    1994 assert((lhs == NULL && rhs == NULL) || (rhs != NULL && lhs != NULL));
    1995 assert((nnonz != NULL && beg != NULL && ind != NULL && val != NULL) || (nnonz == NULL && beg == NULL && ind == NULL && val == NULL));
    1996 assert(firstrow >= 0);
    1997 assert(lastrow < CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
    1998 assert(firstrow <= lastrow + 1);
    1999
    2000 SCIPdebugMessage("getting rows %d to %d\n", firstrow, lastrow);
    2001
    2002 if( lhs != NULL )
    2003 {
    2004 /* get row sense, rhs, and ranges */
    2005 SCIP_CALL( ensureSidechgMem(lpi, lastrow - firstrow + 1) );
    2006 CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, lpi->senarray, firstrow, lastrow) );
    2007 CHECK_ZERO( lpi->messagehdlr, CPXgetrhs(lpi->cpxenv, lpi->cpxlp, lpi->rhsarray, firstrow, lastrow) );
    2008#if CPX_VERSION < 12070000
    2009 retcode = CPXgetrngval(lpi->cpxenv, lpi->cpxlp, lpi->rngarray, firstrow, lastrow);
    2010 if( retcode != CPXERR_NO_RNGVAL ) /* ignore "No range values" error */
    2011 {
    2012 CHECK_ZERO( lpi->messagehdlr, retcode );
    2013 }
    2014 else
    2015 BMSclearMemoryArray(lpi->rngarray, lastrow-firstrow+1);
    2016#else
    2017 CHECK_ZERO( lpi->messagehdlr, CPXgetrngval(lpi->cpxenv, lpi->cpxlp, lpi->rngarray, firstrow, lastrow) );
    2018#endif
    2019
    2020 /* convert sen/rhs/range into lhs/rhs tuples */
    2021 reconvertSides(lpi, lastrow - firstrow + 1, lhs, rhs);
    2022 }
    2023
    2024 if( nnonz != NULL )
    2025 {
    2026 int surplus;
    2027
    2028 /* get matrix entries */
    2029 CHECK_ZERO( lpi->messagehdlr, CPXgetrows(lpi->cpxenv, lpi->cpxlp, nnonz, beg, ind, val,
    2030 CPXgetnumnz(lpi->cpxenv, lpi->cpxlp), &surplus, firstrow, lastrow) );
    2031 assert(surplus >= 0);
    2032 }
    2033
    2034 return SCIP_OKAY;
    2035}
    2036
    2037/** gets column names */
    2039 SCIP_LPI* lpi, /**< LP interface structure */
    2040 int firstcol, /**< first column to get name from LP */
    2041 int lastcol, /**< last column to get name from LP */
    2042 char** colnames, /**< pointers to column names (of size at least lastcol-firstcol+1) or NULL if namestoragesize is zero */
    2043 char* namestorage, /**< storage for col names or NULL if namestoragesize is zero */
    2044 int namestoragesize, /**< size of namestorage (if 0, storageleft returns the storage needed) */
    2045 int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) or NULL if namestoragesize is zero */
    2046 )
    2047{
    2048 int retcode;
    2049
    2050 assert(lpi != NULL);
    2051 assert(lpi->cpxlp != NULL);
    2052 assert(lpi->cpxenv != NULL);
    2053 assert(colnames != NULL || namestoragesize == 0);
    2054 assert(namestorage != NULL || namestoragesize == 0);
    2055 assert(namestoragesize >= 0);
    2056 assert(storageleft != NULL);
    2057 assert(firstcol >= 0);
    2058 assert(lastcol < CPXgetnumcols(lpi->cpxenv, lpi->cpxlp));
    2059 assert(firstcol <= lastcol + 1);
    2060
    2061 SCIPdebugMessage("getting column names %d to %d\n", firstcol, lastcol);
    2062
    2063 retcode = CPXgetcolname(lpi->cpxenv, lpi->cpxlp, colnames, namestorage, namestoragesize, storageleft, firstcol, lastcol);
    2064 assert( namestoragesize != 0 || retcode == CPXERR_NEGATIVE_SURPLUS );
    2065 if( namestoragesize != 0 )
    2066 {
    2067 CHECK_ZERO( lpi->messagehdlr, retcode );
    2068 }
    2069
    2070 return SCIP_OKAY;
    2071}
    2072
    2073/** gets row names */
    2075 SCIP_LPI* lpi, /**< LP interface structure */
    2076 int firstrow, /**< first row to get name from LP */
    2077 int lastrow, /**< last row to get name from LP */
    2078 char** rownames, /**< pointers to row names (of size at least lastrow-firstrow+1) or NULL if namestoragesize is zero */
    2079 char* namestorage, /**< storage for row names or NULL if namestoragesize is zero */
    2080 int namestoragesize, /**< size of namestorage (if 0, -storageleft returns the storage needed) */
    2081 int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) or NULL if namestoragesize is zero */
    2082 )
    2083{
    2084 int retcode;
    2085
    2086 assert(lpi != NULL);
    2087 assert(lpi->cpxlp != NULL);
    2088 assert(lpi->cpxenv != NULL);
    2089 assert(rownames != NULL || namestoragesize == 0);
    2090 assert(namestorage != NULL || namestoragesize == 0);
    2091 assert(namestoragesize >= 0);
    2092 assert(storageleft != NULL);
    2093 assert(firstrow >= 0);
    2094 assert(lastrow < CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
    2095 assert(firstrow <= lastrow + 1);
    2096
    2097 SCIPdebugMessage("getting row names %d to %d\n", firstrow, lastrow);
    2098
    2099 retcode = CPXgetrowname(lpi->cpxenv, lpi->cpxlp, rownames, namestorage, namestoragesize, storageleft, firstrow, lastrow);
    2100 assert( namestoragesize != 0 || retcode == CPXERR_NEGATIVE_SURPLUS );
    2101 if( namestoragesize != 0 )
    2102 {
    2103 CHECK_ZERO( lpi->messagehdlr, retcode );
    2104 }
    2105
    2106 return SCIP_OKAY;
    2107}
    2108
    2109/** gets objective sense of the LP */
    2111 SCIP_LPI* lpi, /**< LP interface structure */
    2112 SCIP_OBJSEN* objsen /**< pointer to store objective sense */
    2113 )
    2114{
    2115 assert(lpi != NULL);
    2116 assert(lpi->cpxlp != NULL);
    2117 assert(lpi->cpxenv != NULL);
    2118 assert(objsen != NULL);
    2119 assert(CPXgetobjsen(lpi->cpxenv, lpi->cpxlp) == CPX_MIN || CPXgetobjsen(lpi->cpxenv, lpi->cpxlp) == CPX_MAX);
    2120
    2121 SCIPdebugMessage("getting objective sense\n");
    2122
    2123 *objsen = (CPXgetobjsen(lpi->cpxenv, lpi->cpxlp) == CPX_MIN) ? SCIP_OBJSEN_MINIMIZE : SCIP_OBJSEN_MAXIMIZE;
    2124
    2125 return SCIP_OKAY;
    2126}
    2127
    2128/** gets objective coefficients from LP problem object */
    2130 SCIP_LPI* lpi, /**< LP interface structure */
    2131 int firstcol, /**< first column to get objective coefficient for */
    2132 int lastcol, /**< last column to get objective coefficient for */
    2133 SCIP_Real* vals /**< array to store objective coefficients */
    2134 )
    2135{
    2136 assert(lpi != NULL);
    2137 assert(lpi->cpxlp != NULL);
    2138 assert(lpi->cpxenv != NULL);
    2139 assert(vals != NULL);
    2140 assert(firstcol >= 0);
    2141 assert(lastcol < CPXgetnumcols(lpi->cpxenv, lpi->cpxlp));
    2142 assert(firstcol <= lastcol + 1);
    2143
    2144 SCIPdebugMessage("getting objective values %d to %d\n", firstcol, lastcol);
    2145
    2146 CHECK_ZERO( lpi->messagehdlr, CPXgetobj(lpi->cpxenv, lpi->cpxlp, vals, firstcol, lastcol) );
    2147
    2148 return SCIP_OKAY;
    2149}
    2150
    2151/** gets current bounds from LP problem object */
    2153 SCIP_LPI* lpi, /**< LP interface structure */
    2154 int firstcol, /**< first column to get bounds for */
    2155 int lastcol, /**< last column to get bounds for */
    2156 SCIP_Real* lbs, /**< array to store lower bound values, or NULL */
    2157 SCIP_Real* ubs /**< array to store upper bound values, or NULL */
    2158 )
    2159{
    2160 assert(lpi != NULL);
    2161 assert(lpi->cpxlp != NULL);
    2162 assert(lpi->cpxenv != NULL);
    2163 assert(firstcol >= 0);
    2164 assert(lastcol < CPXgetnumcols(lpi->cpxenv, lpi->cpxlp));
    2165 assert(firstcol <= lastcol + 1);
    2166
    2167 SCIPdebugMessage("getting bounds %d to %d\n", firstcol, lastcol);
    2168
    2169 if( lbs != NULL )
    2170 {
    2171 CHECK_ZERO( lpi->messagehdlr, CPXgetlb(lpi->cpxenv, lpi->cpxlp, lbs, firstcol, lastcol) );
    2172 }
    2173
    2174 if( ubs != NULL )
    2175 {
    2176 CHECK_ZERO( lpi->messagehdlr, CPXgetub(lpi->cpxenv, lpi->cpxlp, ubs, firstcol, lastcol) );
    2177 }
    2178
    2179 return SCIP_OKAY;
    2180}
    2181
    2182/** gets current row sides from LP problem object */
    2184 SCIP_LPI* lpi, /**< LP interface structure */
    2185 int firstrow, /**< first row to get sides for */
    2186 int lastrow, /**< last row to get sides for */
    2187 SCIP_Real* lhss, /**< array to store left hand side values, or NULL */
    2188 SCIP_Real* rhss /**< array to store right hand side values, or NULL */
    2189 )
    2190{
    2191#if CPX_VERSION < 12070000
    2192 int retval;
    2193#endif
    2194
    2195 assert(lpi != NULL);
    2196 assert(lpi->cpxlp != NULL);
    2197 assert(lpi->cpxenv != NULL);
    2198 assert(firstrow >= 0);
    2199 assert(lastrow < CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
    2200 assert(firstrow <= lastrow + 1);
    2201
    2202 SCIPdebugMessage("getting row sides %d to %d\n", firstrow, lastrow);
    2203
    2204 /* get row sense, rhs, and ranges */
    2205 SCIP_CALL( ensureSidechgMem(lpi, lastrow - firstrow + 1) );
    2206 CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, lpi->senarray, firstrow, lastrow) );
    2207 CHECK_ZERO( lpi->messagehdlr, CPXgetrhs(lpi->cpxenv, lpi->cpxlp, lpi->rhsarray, firstrow, lastrow) );
    2208#if CPX_VERSION < 12070000
    2209 retval = CPXgetrngval(lpi->cpxenv, lpi->cpxlp, lpi->rngarray, firstrow, lastrow);
    2210 if( retval != CPXERR_NO_RNGVAL ) /* ignore "No range values" error */
    2211 {
    2212 CHECK_ZERO( lpi->messagehdlr, retval );
    2213 }
    2214 else
    2215 BMSclearMemoryArray(lpi->rngarray, lastrow-firstrow+1);
    2216#else
    2217 CHECK_ZERO( lpi->messagehdlr, CPXgetrngval(lpi->cpxenv, lpi->cpxlp, lpi->rngarray, firstrow, lastrow) );
    2218#endif
    2219
    2220 /* convert sen/rhs/range into lhs/rhs tuples */
    2221 reconvertSides(lpi, lastrow - firstrow + 1, lhss, rhss);
    2222
    2223 return SCIP_OKAY;
    2224}
    2225
    2226/** gets a single coefficient */
    2228 SCIP_LPI* lpi, /**< LP interface structure */
    2229 int row, /**< row number of coefficient */
    2230 int col, /**< column number of coefficient */
    2231 SCIP_Real* val /**< pointer to store the value of the coefficient */
    2232 )
    2233{
    2234 assert(lpi != NULL);
    2235 assert(lpi->cpxlp != NULL);
    2236 assert(lpi->cpxenv != NULL);
    2237 assert(val != NULL);
    2238
    2239 SCIPdebugMessage("getting coefficient of row %d col %d\n", row, col);
    2240
    2241 CHECK_ZERO( lpi->messagehdlr, CPXgetcoef(lpi->cpxenv, lpi->cpxlp, row, col, val) );
    2242
    2243 return SCIP_OKAY;
    2244}
    2245
    2246/**@} */
    2247
    2248
    2249
    2250
    2251/*
    2252 * Solving Methods
    2253 */
    2254
    2255/**@name Solving Methods */
    2256/**@{ */
    2257
    2258/** calls primal simplex to solve the LP */
    2260 SCIP_LPI* lpi /**< LP interface structure */
    2261 )
    2262{
    2263 int retval;
    2264 int primalfeasible;
    2265 int dualfeasible;
    2266 int solntype;
    2267#if CPX_VERSION == 12070100
    2268 int presolving;
    2269#endif
    2270
    2271 assert(lpi != NULL);
    2272 assert(lpi->cpxlp != NULL);
    2273 assert(lpi->cpxenv != NULL);
    2274
    2275 SCIPdebugMessage("calling CPLEX primal simplex: %d cols, %d rows\n",
    2276 CPXgetnumcols(lpi->cpxenv, lpi->cpxlp), CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
    2277
    2278 invalidateSolution(lpi);
    2279
    2280#if (CPX_VERSION == 12070000)
    2281 {
    2282 int scaling;
    2283 /* due to a bug in CPLEX 12.7.0, we need to disable scaling for this version */
    2284 CHECK_ZERO( lpi->messagehdlr, CPXgetintparam(lpi->cpxenv, CPX_PARAM_SCAIND, &scaling) );
    2285 assert( scaling == -1 );
    2286 }
    2287#endif
    2288
    2289 setIntParam(lpi, CPX_PARAM_ADVIND, lpi->fromscratch || lpi->clearstate ? CPX_OFF : CPX_ON);
    2290 lpi->clearstate = FALSE;
    2291
    2292 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
    2293
    2294#if CPX_VERSION == 12070100
    2295 /* due to a bug in CPLEX 12.7.1.0, we need to enable presolving on trivial problems (see comment below) */
    2296 if( CPXgetnumrows(lpi->cpxenv, lpi->cpxlp) == 0 )
    2297 {
    2298 CHECK_ZERO( lpi->messagehdlr, CPXgetintparam(lpi->cpxenv, CPX_PARAM_PREIND, &presolving) );
    2299 CHECK_ZERO( lpi->messagehdlr, CPXsetintparam(lpi->cpxenv, CPX_PARAM_PREIND, CPX_ON) );
    2300 }
    2301#endif
    2302
    2303 SCIPdebugMessage("calling CPXprimopt()\n");
    2304 retval = CPXprimopt(lpi->cpxenv, lpi->cpxlp);
    2305
    2306#if CPX_VERSION == 12070100
    2307 /* restore previous value for presolving */
    2308 if( CPXgetnumrows(lpi->cpxenv, lpi->cpxlp) == 0 )
    2309 {
    2310 CHECK_ZERO( lpi->messagehdlr, CPXsetintparam(lpi->cpxenv, CPX_PARAM_PREIND, presolving) ); /*lint !e644*/
    2311 }
    2312#endif
    2313
    2314 switch( retval )
    2315 {
    2316 case 0:
    2317 break;
    2318 case CPXERR_NO_MEMORY:
    2319 return SCIP_NOMEMORY;
    2320 default:
    2321 return SCIP_LPERROR;
    2322 }
    2323
    2324 lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
    2325 lpi->method = CPX_ALG_PRIMAL;
    2327
    2328 /* CPLEX outputs an error if the status is CPX_STAT_INForUNBD and the iterations are determined */
    2329 CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, &primalfeasible, &dualfeasible) );
    2330 if( lpi->solstat != CPX_STAT_INForUNBD && solntype != CPX_NO_SOLN )
    2331 lpi->iterations = CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) + CPXgetitcnt(lpi->cpxenv, lpi->cpxlp);
    2332 else
    2333 lpi->iterations = 0;
    2334
    2335 SCIPdebugMessage(" -> CPLEX returned solstat=%d, pfeas=%d, dfeas=%d (%d iterations)\n",
    2336 lpi->solstat, primalfeasible, dualfeasible, lpi->iterations);
    2337
    2338#if CPX_VERSION == 12070100
    2339 /* CPLEX 12.7.1.0 primal simplex without presolve (called next in certain situations) does not return on a problem like
    2340 * min x + sum_{i=1}^n 0*y_i when all variables are free and n >= 59
    2341 * With this workaround, we claim that LPs without rows, which are returned as infeasible-or-unbounded by CPLEX with presolve,
    2342 * are in fact unbounded. This assumes that CPLEX with presolve checked that no variable has an empty domain before.
    2343 */
    2344 if( lpi->solstat == CPX_STAT_INForUNBD && CPXgetnumrows(lpi->cpxenv, lpi->cpxlp) == 0 )
    2345 {
    2346 lpi->solstat = CPX_STAT_UNBOUNDED;
    2347 primalfeasible = 1;
    2348 dualfeasible = 0;
    2349 }
    2350#endif
    2351
    2352 if( lpi->solstat == CPX_STAT_INForUNBD
    2353 || (lpi->solstat == CPX_STAT_INFEASIBLE && !dualfeasible)
    2354 || (lpi->solstat == CPX_STAT_UNBOUNDED && !primalfeasible) )
    2355 {
    2356 if( getIntParam(lpi, CPX_PARAM_PREIND) == CPX_ON )
    2357 {
    2358 /* maybe the preprocessor solved the problem; but we need a solution, so solve again without preprocessing */
    2359 SCIPdebugMessage("presolver may have solved the problem -> calling CPLEX primal simplex again without presolve\n");
    2360
    2361 /* switch off preprocessing */
    2362 setIntParam(lpi, CPX_PARAM_PREIND, CPX_OFF);
    2363 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
    2364
    2365 retval = CPXprimopt(lpi->cpxenv, lpi->cpxlp);
    2366 switch( retval )
    2367 {
    2368 case 0:
    2369 break;
    2370 case CPXERR_NO_MEMORY:
    2371 return SCIP_NOMEMORY;
    2372 default:
    2373 return SCIP_LPERROR;
    2374 }
    2375
    2376 lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
    2378 assert( lpi->solstat != CPX_STAT_INForUNBD );
    2379
    2380 lpi->iterations += CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) + CPXgetitcnt(lpi->cpxenv, lpi->cpxlp);
    2381 CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, NULL, NULL) );
    2382
    2383 SCIPdebugMessage(" -> CPLEX returned solstat=%d (%d iterations)\n", lpi->solstat, lpi->iterations);
    2384
    2385 /* switch on preprocessing again */
    2386 setIntParam(lpi, CPX_PARAM_PREIND, CPX_ON);
    2387 }
    2388
    2389 if( lpi->solstat == CPX_STAT_INForUNBD )
    2390 {
    2391 /* preprocessing was not the problem; issue a warning message and treat LP as infeasible */
    2392 SCIPerrorMessage("CPLEX primal simplex returned CPX_STAT_INForUNBD after presolving was turned off.\n");
    2393 }
    2394 }
    2395
    2396 /* check whether the solution is basic: if Cplex, e.g., hits a time limit in data setup, this might not be the case,
    2397 * also for some pathological cases of infeasibility, e.g., contradictory bounds */
    2398 lpi->solisbasic = (solntype == CPX_BASIC_SOLN);
    2399 assert( lpi->solisbasic || lpi->solstat != CPX_STAT_OPTIMAL );
    2400
    2401 return SCIP_OKAY;
    2402}
    2403
    2404/** calls dual simplex to solve the LP */
    2406 SCIP_LPI* lpi /**< LP interface structure */
    2407 )
    2408{
    2409 int retval;
    2410 int primalfeasible;
    2411 int dualfeasible;
    2412 int solntype;
    2413
    2414 assert(lpi != NULL);
    2415 assert(lpi->cpxlp != NULL);
    2416 assert(lpi->cpxenv != NULL);
    2417
    2418 SCIPdebugMessage("calling CPLEX dual simplex: %d cols, %d rows\n",
    2419 CPXgetnumcols(lpi->cpxenv, lpi->cpxlp), CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
    2420
    2421 invalidateSolution(lpi);
    2422
    2423 setIntParam(lpi, CPX_PARAM_ADVIND, lpi->fromscratch || lpi->clearstate ? CPX_OFF : CPX_ON);
    2424 lpi->clearstate = FALSE;
    2425
    2426 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
    2427
    2428#if (CPX_VERSION == 12070000)
    2429 {
    2430 int scaling;
    2431 /* due to a bug in CPLEX 12.7.0 we need to disable scaling */
    2432 CHECK_ZERO( lpi->messagehdlr, CPXgetintparam(lpi->cpxenv, CPX_PARAM_SCAIND, &scaling) );
    2433 assert( scaling == -1 );
    2434 }
    2435#endif
    2436
    2437 SCIPdebugMessage("calling CPXdualopt()\n");
    2438 retval = CPXdualopt(lpi->cpxenv, lpi->cpxlp);
    2439 switch( retval )
    2440 {
    2441 case 0:
    2442 break;
    2443 case CPXERR_NO_MEMORY:
    2444 return SCIP_NOMEMORY;
    2445 default:
    2446 return SCIP_LPERROR;
    2447 }
    2448
    2449 lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
    2450 lpi->method = CPX_ALG_DUAL;
    2452
    2453 /* CPLEX outputs an error if the status is CPX_STAT_INForUNBD and the iterations are determined */
    2454 CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, &primalfeasible, &dualfeasible) );
    2455 if( lpi->solstat != CPX_STAT_INForUNBD && solntype != CPX_NO_SOLN )
    2456 lpi->iterations = CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) + CPXgetitcnt(lpi->cpxenv, lpi->cpxlp);
    2457 else
    2458 lpi->iterations = 0;
    2459
    2460 SCIPdebugMessage(" -> CPLEX returned solstat=%d, pfeas=%d, dfeas=%d (%d iterations)\n",
    2461 lpi->solstat, primalfeasible, dualfeasible, lpi->iterations);
    2462
    2463 if( lpi->solstat == CPX_STAT_INForUNBD
    2464 || (lpi->solstat == CPX_STAT_INFEASIBLE && !dualfeasible)
    2465 || (lpi->solstat == CPX_STAT_UNBOUNDED && !primalfeasible) )
    2466 {
    2467 if( getIntParam(lpi, CPX_PARAM_PREIND) == CPX_ON )
    2468 {
    2469 /* maybe the preprocessor solved the problem; but we need a solution, so solve again without preprocessing */
    2470 SCIPdebugMessage("presolver may have solved the problem -> calling CPLEX dual simplex again without presolve\n");
    2471
    2472 /* switch off preprocessing */
    2473 setIntParam(lpi, CPX_PARAM_PREIND, CPX_OFF);
    2474 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
    2475
    2476 retval = CPXdualopt(lpi->cpxenv, lpi->cpxlp);
    2477 switch( retval )
    2478 {
    2479 case 0:
    2480 break;
    2481 case CPXERR_NO_MEMORY:
    2482 return SCIP_NOMEMORY;
    2483 default:
    2484 return SCIP_LPERROR;
    2485 }
    2486
    2487 lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
    2489 assert( lpi->solstat != CPX_STAT_INForUNBD );
    2490
    2491 lpi->iterations += CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) + CPXgetitcnt(lpi->cpxenv, lpi->cpxlp);
    2492 CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, NULL, NULL) );
    2493
    2494 SCIPdebugMessage(" -> CPLEX returned solstat=%d (%d iterations)\n", lpi->solstat, lpi->iterations);
    2495
    2496 /* switch on preprocessing again */
    2497 setIntParam(lpi, CPX_PARAM_PREIND, CPX_ON);
    2498 }
    2499
    2500 if( lpi->solstat == CPX_STAT_INForUNBD )
    2501 {
    2502 /* preprocessing was not the problem; issue a warning message and treat LP as infeasible */
    2503 SCIPerrorMessage("CPLEX dual simplex returned CPX_STAT_INForUNBD after presolving was turned off\n");
    2504 }
    2505 }
    2506
    2507 /* check whether the solution is basic: if Cplex, e.g., hits a time limit in data setup, this might not be the case,
    2508 * also for some pathological cases of infeasibility, e.g., contradictory bounds
    2509 */
    2510 lpi->solisbasic = (solntype == CPX_BASIC_SOLN);
    2511 assert( lpi->solisbasic || lpi->solstat != CPX_STAT_OPTIMAL );
    2512
    2513#ifdef SCIP_DISABLED_CODE
    2514 /* this fixes the strange behavior of CPLEX, that in case of the objective limit exceedance, it returns the
    2515 * solution for the basis preceeding the one with exceeding objective limit
    2516 * (using this "wrong" dual solution can cause column generation algorithms to fail to find an improving column)
    2517 */
    2518 if( SCIPlpiIsObjlimExc(lpi) )
    2519 {
    2520 SCIP_Real objval;
    2521 SCIP_Real llim;
    2522 SCIP_Real ulim;
    2523 SCIP_Real eps;
    2524
    2525 /* check, if the dual solution returned by CPLEX really exceeds the objective limit;
    2526 * CPLEX usually returns the basis one iteration before the one that exceeds the limit
    2527 */
    2528 SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
    2529 llim = getDblParam(lpi, CPX_PARAM_OBJLLIM);
    2530 ulim = getDblParam(lpi, CPX_PARAM_OBJULIM);
    2531 eps = getDblParam(lpi, CPX_PARAM_EPOPT);
    2532 if( objval >= llim - eps && objval <= ulim + eps )
    2533 {
    2534 int itlim;
    2535 int advind;
    2536
    2537 /* perform one additional simplex iteration without objective limit */
    2538 SCIPdebugMessage("dual solution %g does not exceed objective limit [%g,%g] (%d iterations) -> calling CPLEX dual simplex again for one iteration\n",
    2539 objval, llim, ulim, lpi->iterations);
    2540 itlim = getIntParam(lpi, CPX_PARAM_ITLIM);
    2541 setIntParam(lpi, CPX_PARAM_ITLIM, 1);
    2542 advind = getIntParam(lpi, CPX_PARAM_ADVIND);
    2543 setIntParam(lpi, CPX_PARAM_ADVIND, CPX_ON);
    2544 setDblParam(lpi, CPX_PARAM_OBJLLIM, -CPX_INFBOUND);
    2545 setDblParam(lpi, CPX_PARAM_OBJULIM, CPX_INFBOUND);
    2546 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
    2547 CHECK_ZERO( lpi->messagehdlr, CPXsetintparam(lpi->cpxenv, CPX_PARAM_FINALFACTOR, FALSE) );
    2548
    2549 retval = CPXdualopt(lpi->cpxenv, lpi->cpxlp);
    2550 switch( retval )
    2551 {
    2552 case 0:
    2553 break;
    2554 case CPXERR_NO_MEMORY:
    2555 return SCIP_NOMEMORY;
    2556 default:
    2557 return SCIP_LPERROR;
    2558 }
    2559
    2560 lpi->iterations += CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) + CPXgetitcnt(lpi->cpxenv, lpi->cpxlp);
    2561
    2562 /* reset the iteration limit and objective bounds */
    2563 setIntParam(lpi, CPX_PARAM_ITLIM, itlim);
    2564 setIntParam(lpi, CPX_PARAM_ADVIND, advind);
    2565 setDblParam(lpi, CPX_PARAM_OBJLLIM, llim);
    2566 setDblParam(lpi, CPX_PARAM_OBJULIM, ulim);
    2567 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
    2568 CHECK_ZERO( lpi->messagehdlr, CPXsetintparam(lpi->cpxenv, CPX_PARAM_FINALFACTOR, TRUE) );
    2569
    2570 /* resolve LP again in order to restore the status of exceeded objective limit */
    2571 retval = CPXdualopt(lpi->cpxenv, lpi->cpxlp);
    2572 switch( retval )
    2573 {
    2574 case 0:
    2575 break;
    2576 case CPXERR_NO_MEMORY:
    2577 return SCIP_NOMEMORY;
    2578 default:
    2579 return SCIP_LPERROR;
    2580 }
    2581
    2582 lpi->iterations += CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) + CPXgetitcnt(lpi->cpxenv, lpi->cpxlp);
    2583 lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
    2585 SCIPdebugMessage(" -> CPLEX returned solstat=%d (%d iterations)\n", lpi->solstat, lpi->iterations);
    2586 }
    2587 }
    2588#endif
    2589
    2590 return SCIP_OKAY;
    2591}
    2592
    2593/** calls barrier or interior point algorithm to solve the LP with crossover to simplex basis */
    2595 SCIP_LPI* lpi, /**< LP interface structure */
    2596 SCIP_Bool crossover /**< perform crossover */
    2597 )
    2598{
    2599 int solntype;
    2600 int retval;
    2601
    2602 assert(lpi != NULL);
    2603 assert(lpi->cpxlp != NULL);
    2604 assert(lpi->cpxenv != NULL);
    2605
    2606 SCIPdebugMessage("calling CPLEX barrier: %d cols, %d rows\n",
    2607 CPXgetnumcols(lpi->cpxenv, lpi->cpxlp), CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
    2608
    2609 invalidateSolution(lpi);
    2610
    2611 setIntParam(lpi, CPX_PARAM_ADVIND, lpi->fromscratch || lpi->clearstate ? CPX_OFF : CPX_ON);
    2612 lpi->clearstate = FALSE;
    2613
    2614 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
    2615
    2616 SCIPdebugMessage("calling CPXhybaropt()\n");
    2617 retval = CPXhybbaropt(lpi->cpxenv, lpi->cpxlp, crossover ? 0 : CPX_ALG_NONE);
    2618 switch( retval )
    2619 {
    2620 case 0:
    2621 break;
    2622 case CPXERR_NO_MEMORY:
    2623 return SCIP_NOMEMORY;
    2624 default:
    2625 return SCIP_LPERROR;
    2626 }
    2627
    2628 CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, NULL, NULL) );
    2629
    2630 lpi->solisbasic = (solntype == CPX_BASIC_SOLN);
    2631 lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
    2632 lpi->method = CPX_ALG_BARRIER;
    2634
    2635 if( lpi->solstat != CPX_STAT_INForUNBD && solntype != CPX_NO_SOLN )
    2636 lpi->iterations = CPXgetbaritcnt(lpi->cpxenv, lpi->cpxlp);
    2637 else
    2638 lpi->iterations = 0;
    2639
    2640 SCIPdebugMessage(" -> CPLEX returned solstat=%d (%d iterations)\n", lpi->solstat, lpi->iterations);
    2641
    2642 if( lpi->solstat == CPX_STAT_INForUNBD )
    2643 {
    2644 /* maybe the preprocessor solved the problem; but we need a solution, so solve again without preprocessing */
    2645 SCIPdebugMessage("CPLEX returned INForUNBD -> calling CPLEX barrier again without presolve\n");
    2646
    2647 /* switch off preprocessing */
    2648 setIntParam(lpi, CPX_PARAM_PREIND, CPX_OFF);
    2649 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
    2650
    2651 retval = CPXhybbaropt(lpi->cpxenv, lpi->cpxlp, crossover ? 0 : CPX_ALG_NONE);
    2652 switch( retval )
    2653 {
    2654 case 0:
    2655 break;
    2656 case CPXERR_NO_MEMORY:
    2657 return SCIP_NOMEMORY;
    2658 default:
    2659 return SCIP_LPERROR;
    2660 }
    2661
    2662 CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, NULL, NULL) );
    2663
    2664 lpi->solisbasic = (solntype == CPX_BASIC_SOLN);
    2665 lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
    2667
    2668 lpi->iterations += CPXgetbaritcnt(lpi->cpxenv, lpi->cpxlp);
    2669 SCIPdebugMessage(" -> CPLEX returned solstat=%d\n", lpi->solstat);
    2670
    2671 setIntParam(lpi, CPX_PARAM_PREIND, CPX_ON);
    2672
    2673 if( lpi->solstat == CPX_STAT_INForUNBD )
    2674 {
    2675 /* if we could not resolve CPX_STAT_INForUNBD, we use the dual simplex */
    2677 }
    2678 }
    2679
    2680 return SCIP_OKAY;
    2681}
    2682
    2683/** manually performs strong branching on one integral variable */
    2684static
    2686 SCIP_LPI* lpi, /**< LP interface structure */
    2687 int col, /**< column to apply strong branching on */
    2688 SCIP_Real psol, /**< current integral primal solution value of column */
    2689 int itlim, /**< iteration limit for strong branchings */
    2690 SCIP_Real* down, /**< stores dual bound after branching column down */
    2691 SCIP_Real* up, /**< stores dual bound after branching column up */
    2692 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
    2693 * otherwise, it can only be used as an estimate value */
    2694 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
    2695 * otherwise, it can only be used as an estimate value */
    2696 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
    2697 )
    2698{
    2699 const char lbound = 'L';
    2700 const char ubound = 'U';
    2701 SCIP_Real oldlb;
    2702 SCIP_Real oldub;
    2703 SCIP_Real newlb;
    2704 SCIP_Real newub;
    2705 int objsen;
    2706 int olditlim;
    2707 int it;
    2708
    2709 SCIPdebugMessage(" -> strong branching on integral variable %d\n", col);
    2710
    2711 assert( EPSISINT(psol, lpi->feastol) );
    2712
    2713 objsen = CPXgetobjsen(lpi->cpxenv, lpi->cpxlp);
    2714
    2715 /* results of CPLEX are valid in any case */
    2716 *downvalid = TRUE;
    2717 *upvalid = TRUE;
    2718
    2719 /* save current LP basis and bounds*/
    2720 SCIP_CALL( getBase(lpi) );
    2721 CHECK_ZERO( lpi->messagehdlr, CPXgetlb(lpi->cpxenv, lpi->cpxlp, &oldlb, col, col) );
    2722 CHECK_ZERO( lpi->messagehdlr, CPXgetub(lpi->cpxenv, lpi->cpxlp, &oldub, col, col) );
    2723
    2724 /* save old iteration limit and set iteration limit to strong branching limit */
    2725 if( itlim > CPX_INT_MAX )
    2726 itlim = CPX_INT_MAX;
    2727 olditlim = getIntParam(lpi, CPX_PARAM_ITLIM);
    2728 setIntParam(lpi, CPX_PARAM_ITLIM, itlim);
    2729
    2730 /* down branch */
    2731 newub = EPSCEIL(psol-1.0, lpi->feastol);
    2732 if( newub >= oldlb - 0.5 )
    2733 {
    2734 CHECK_ZERO( lpi->messagehdlr, CPXchgbds(lpi->cpxenv, lpi->cpxlp, 1, &col, &ubound, &newub) );
    2737 *down = objsen == CPX_MIN ? getDblParam(lpi, CPX_PARAM_OBJULIM) : getDblParam(lpi, CPX_PARAM_OBJLLIM);
    2738 else if( SCIPlpiIsOptimal(lpi) || SCIPlpiIsIterlimExc(lpi) )
    2739 {
    2740 SCIP_CALL( SCIPlpiGetObjval(lpi, down) );
    2741 }
    2742 else
    2743 *down = objsen == CPX_MIN ? getDblParam(lpi, CPX_PARAM_OBJLLIM) : getDblParam(lpi, CPX_PARAM_OBJULIM);
    2744 if( iter != NULL )
    2745 {
    2746 SCIP_CALL( SCIPlpiGetIterations(lpi, &it) );
    2747 *iter += it;
    2748 }
    2749 SCIPdebugMessage(" -> down (x%d <= %g): %g\n", col, newub, *down);
    2750
    2751 CHECK_ZERO( lpi->messagehdlr, CPXchgbds(lpi->cpxenv, lpi->cpxlp, 1, &col, &ubound, &oldub) );
    2752 SCIP_CALL( setBase(lpi) );
    2753 }
    2754 else
    2755 *down = objsen == CPX_MIN ? getDblParam(lpi, CPX_PARAM_OBJULIM) : getDblParam(lpi, CPX_PARAM_OBJLLIM);
    2756
    2757 /* up branch */
    2758 newlb = EPSFLOOR(psol+1.0, lpi->feastol);
    2759 if( newlb <= oldub + 0.5 )
    2760 {
    2761 CHECK_ZERO( lpi->messagehdlr, CPXchgbds(lpi->cpxenv, lpi->cpxlp, 1, &col, &lbound, &newlb) );
    2764 *up = objsen == CPX_MIN ? getDblParam(lpi, CPX_PARAM_OBJULIM) : getDblParam(lpi, CPX_PARAM_OBJLLIM);
    2765 else if( SCIPlpiIsOptimal(lpi) || SCIPlpiIsIterlimExc(lpi) )
    2766 {
    2767 SCIP_CALL( SCIPlpiGetObjval(lpi, up) );
    2768 }
    2769 else
    2770 *up = objsen == CPX_MIN ? getDblParam(lpi, CPX_PARAM_OBJLLIM) : getDblParam(lpi, CPX_PARAM_OBJULIM);
    2771 if( iter != NULL )
    2772 {
    2773 SCIP_CALL( SCIPlpiGetIterations(lpi, &it) );
    2774 *iter += it;
    2775 }
    2776 SCIPdebugMessage(" -> up (x%d >= %g): %g\n", col, newlb, *up);
    2777
    2778 CHECK_ZERO( lpi->messagehdlr, CPXchgbds(lpi->cpxenv, lpi->cpxlp, 1, &col, &lbound, &oldlb) );
    2779 SCIP_CALL( setBase(lpi) );
    2780 }
    2781 else
    2782 *up = objsen == CPX_MIN ? getDblParam(lpi, CPX_PARAM_OBJLLIM) : getDblParam(lpi, CPX_PARAM_OBJULIM);
    2783
    2784 /* reset iteration limit */
    2785 setIntParam(lpi, CPX_PARAM_ITLIM, olditlim);
    2786
    2787 return SCIP_OKAY;
    2788}
    2789
    2790/** start strong branching */
    2792 SCIP_LPI* lpi /**< LP interface structure */
    2793 )
    2794{ /*lint --e{715}*/
    2795 assert(lpi != NULL);
    2796 assert(lpi->cpxlp != NULL);
    2797 assert(lpi->cpxenv != NULL);
    2798
    2799 /* no work necessary */
    2800 return SCIP_OKAY;
    2801}
    2802
    2803/** end strong branching */
    2805 SCIP_LPI* lpi /**< LP interface structure */
    2806 )
    2807{ /*lint --e{715}*/
    2808 assert(lpi != NULL);
    2809 assert(lpi->cpxlp != NULL);
    2810 assert(lpi->cpxenv != NULL);
    2811
    2812 /* no work necessary */
    2813 return SCIP_OKAY;
    2814}
    2815
    2816/** performs strong branching iterations on one @b fractional candidate */
    2818 SCIP_LPI* lpi, /**< LP interface structure */
    2819 int col, /**< column to apply strong branching on */
    2820 SCIP_Real psol, /**< fractional current primal solution value of column */
    2821 int itlim, /**< iteration limit for strong branchings */
    2822 SCIP_Real* down, /**< stores dual bound after branching column down */
    2823 SCIP_Real* up, /**< stores dual bound after branching column up */
    2824 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
    2825 * otherwise, it can only be used as an estimate value */
    2826 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
    2827 * otherwise, it can only be used as an estimate value */
    2828 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
    2829 )
    2830{
    2831 int retval;
    2832
    2833 assert(lpi != NULL);
    2834 assert(lpi->cpxlp != NULL);
    2835 assert(lpi->cpxenv != NULL);
    2836 assert(down != NULL);
    2837 assert(up != NULL);
    2838 assert(downvalid != NULL);
    2839 assert(upvalid != NULL);
    2840
    2841 SCIPdebugMessage("calling CPLEX strongbranching on fractional variable %d (%d iterations)\n", col, itlim);
    2842
    2843 assert( !EPSISINT(psol, lpi->feastol) );
    2844
    2845 /* results of CPLEX are valid in any case */
    2846 *downvalid = TRUE;
    2847 *upvalid = TRUE;
    2848
    2849 setIntParam(lpi, CPX_PARAM_ADVIND, lpi->fromscratch || lpi->clearstate ? CPX_OFF : CPX_ON);
    2850 lpi->clearstate = FALSE;
    2851
    2852 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
    2853
    2854 retval = CPXstrongbranch(lpi->cpxenv, lpi->cpxlp, &col, 1, down, up, itlim);
    2855 if( retval == CPXERR_NEED_OPT_SOLN )
    2856 {
    2857 SCIPdebugMessage(" -> no optimal solution available\n");
    2858 return SCIP_LPERROR;
    2859 }
    2860 else if( retval == CPXERR_TILIM_STRONGBRANCH )
    2861 {
    2862 SCIPdebugMessage(" -> time limit exceeded during strong branching\n");
    2863 return SCIP_LPERROR;
    2864 }
    2865 else if( retval == CPXERR_SINGULAR )
    2866 {
    2867 SCIPdebugMessage(" -> numerical troubles (basis singular)\n");
    2868 return SCIP_LPERROR;
    2869 }
    2870 CHECK_ZERO( lpi->messagehdlr, retval );
    2871 SCIPdebugMessage(" -> down: %g, up:%g\n", *down, *up);
    2872
    2873 /* CPLEX is not able to return the iteration counts in strong branching */
    2874 if( iter != NULL )
    2875 *iter = -1;
    2876
    2877 return SCIP_OKAY;
    2878}
    2879
    2880/** performs strong branching iterations on given @b fractional candidates */
    2882 SCIP_LPI* lpi, /**< LP interface structure */
    2883 int* cols, /**< columns to apply strong branching on */
    2884 int ncols, /**< number of columns */
    2885 SCIP_Real* psols, /**< fractional current primal solution values of columns */
    2886 int itlim, /**< iteration limit for strong branchings */
    2887 SCIP_Real* down, /**< stores dual bounds after branching columns down */
    2888 SCIP_Real* up, /**< stores dual bounds after branching columns up */
    2889 SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
    2890 * otherwise, they can only be used as an estimate values */
    2891 SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
    2892 * otherwise, they can only be used as an estimate values */
    2893 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
    2894 )
    2895{
    2896 int retval;
    2897 int j;
    2898
    2899 assert(lpi != NULL);
    2900 assert(lpi->cpxlp != NULL);
    2901 assert(lpi->cpxenv != NULL);
    2902 assert(cols != NULL);
    2903 assert(psols != NULL);
    2904 assert(down != NULL);
    2905 assert(up != NULL);
    2906 assert(downvalid != NULL);
    2907 assert(upvalid != NULL);
    2908
    2909 SCIPdebugMessage("calling CPLEX strongbranching on %d fractional variables (%d iterations)\n", ncols, itlim);
    2910
    2911 setIntParam(lpi, CPX_PARAM_ADVIND, lpi->fromscratch || lpi->clearstate ? CPX_OFF : CPX_ON);
    2912 lpi->clearstate = FALSE;
    2913
    2914 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
    2915
    2916 /* initialize */
    2917 for( j = 0; j < ncols; ++j )
    2918 {
    2919 /* results of CPLEX are valid in any case */
    2920 downvalid[j] = TRUE;
    2921 upvalid[j] = TRUE;
    2922
    2923 assert( !EPSISINT(psols[j], lpi->feastol) );
    2924 }
    2925
    2926 retval = CPXstrongbranch(lpi->cpxenv, lpi->cpxlp, cols, ncols, down, up, itlim);
    2927 if( retval == CPXERR_NEED_OPT_SOLN )
    2928 {
    2929 SCIPdebugMessage(" -> no optimal solution available\n");
    2930 return SCIP_LPERROR;
    2931 }
    2932 else if( retval == CPXERR_TILIM_STRONGBRANCH )
    2933 {
    2934 SCIPdebugMessage(" -> time limit exceeded during strong branching\n");
    2935 return SCIP_LPERROR;
    2936 }
    2937 CHECK_ZERO( lpi->messagehdlr, retval );
    2938
    2939 /* CPLEX is not able to return the iteration counts in strong branching */
    2940 if( iter != NULL )
    2941 *iter = -1;
    2942
    2943 return SCIP_OKAY;
    2944}
    2945
    2946/** performs strong branching iterations on one candidate with @b integral value */
    2948 SCIP_LPI* lpi, /**< LP interface structure */
    2949 int col, /**< column to apply strong branching on */
    2950 SCIP_Real psol, /**< current integral primal solution value of column */
    2951 int itlim, /**< iteration limit for strong branchings */
    2952 SCIP_Real* down, /**< stores dual bound after branching column down */
    2953 SCIP_Real* up, /**< stores dual bound after branching column up */
    2954 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
    2955 * otherwise, it can only be used as an estimate value */
    2956 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
    2957 * otherwise, it can only be used as an estimate value */
    2958 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
    2959 )
    2960{
    2961 assert(lpi != NULL);
    2962 assert(lpi->cpxlp != NULL);
    2963 assert(down != NULL);
    2964 assert(up != NULL);
    2965 assert(downvalid != NULL);
    2966 assert(upvalid != NULL);
    2967
    2968 SCIPdebugMessage("calling CPLEX strongbranching on variable %d with integral value (%d iterations)\n", col, itlim);
    2969
    2970 assert( EPSISINT(psol, lpi->feastol) );
    2971
    2972 if( iter != NULL )
    2973 *iter = 0;
    2974
    2975 SCIP_CALL( lpiStrongbranchIntegral(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter) );
    2976
    2977 return SCIP_OKAY;
    2978}
    2979
    2980/** performs strong branching iterations on given candidates with @b integral values */
    2982 SCIP_LPI* lpi, /**< LP interface structure */
    2983 int* cols, /**< columns to apply strong branching on */
    2984 int ncols, /**< number of columns */
    2985 SCIP_Real* psols, /**< current integral primal solution values of columns */
    2986 int itlim, /**< iteration limit for strong branchings */
    2987 SCIP_Real* down, /**< stores dual bounds after branching columns down */
    2988 SCIP_Real* up, /**< stores dual bounds after branching columns up */
    2989 SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
    2990 * otherwise, they can only be used as an estimate values */
    2991 SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
    2992 * otherwise, they can only be used as an estimate values */
    2993 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
    2994 )
    2995{
    2996 int j;
    2997
    2998 assert(lpi != NULL);
    2999 assert(lpi->cpxlp != NULL);
    3000 assert(cols != NULL);
    3001 assert(psols != NULL);
    3002 assert(down != NULL);
    3003 assert(up != NULL);
    3004 assert(downvalid != NULL);
    3005 assert(upvalid != NULL);
    3006
    3007 SCIPdebugMessage("calling CPLEX strongbranching on %d variables with integer values (%d iterations)\n", ncols, itlim);
    3008
    3009 if( iter != NULL )
    3010 *iter = 0;
    3011
    3012 /* initialize */
    3013 for( j = 0; j < ncols; ++j )
    3014 {
    3015 assert( EPSISINT(psols[j], lpi->feastol) );
    3016 SCIP_CALL( lpiStrongbranchIntegral(lpi, cols[j], psols[j], itlim, &(down[j]), &(up[j]), &(downvalid[j]), &(upvalid[j]), iter) );
    3017 }
    3018
    3019 return SCIP_OKAY;
    3020}
    3021/**@} */
    3022
    3023
    3024
    3025
    3026/*
    3027 * Solution Information Methods
    3028 */
    3029
    3030/**@name Solution Information Methods */
    3031/**@{ */
    3032
    3033/** returns whether a solve method was called after the last modification of the LP */
    3035 SCIP_LPI* lpi /**< LP interface structure */
    3036 )
    3037{
    3038 assert(lpi != NULL);
    3039 assert(lpi->cpxlp != NULL);
    3040 assert(lpi->cpxenv != NULL);
    3041
    3042 return (lpi->solstat != -1);
    3043}
    3044
    3045/** gets information about primal and dual feasibility of the current LP solution
    3046 *
    3047 * The feasibility information is with respect to the last solving call and it is only relevant if SCIPlpiWasSolved()
    3048 * returns true. If the LP is changed, this information might be invalidated.
    3049 *
    3050 * Note that @a primalfeasible and @a dualfeasible should only return true if the solver has proved the respective LP to
    3051 * be feasible. Thus, the return values should be equal to the values of SCIPlpiIsPrimalFeasible() and
    3052 * SCIPlpiIsDualFeasible(), respectively. Note that if feasibility cannot be proved, they should return false (even if
    3053 * the problem might actually be feasible).
    3054 */
    3056 SCIP_LPI* lpi, /**< LP interface structure */
    3057 SCIP_Bool* primalfeasible, /**< pointer to store primal feasibility status */
    3058 SCIP_Bool* dualfeasible /**< pointer to store dual feasibility status */
    3059 )
    3060{
    3061 int pfeas;
    3062 int dfeas;
    3063
    3064 assert(lpi != NULL);
    3065 assert(lpi->cpxlp != NULL);
    3066 assert(lpi->cpxenv != NULL);
    3067 assert(primalfeasible != NULL);
    3068 assert(dualfeasible != NULL);
    3069
    3070 SCIPdebugMessage("getting solution feasibility\n");
    3071
    3072 CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, &pfeas, &dfeas) );
    3073 *primalfeasible = (SCIP_Bool)pfeas;
    3074 *dualfeasible = (SCIP_Bool)dfeas;
    3075
    3076 return SCIP_OKAY;
    3077}
    3078
    3079/** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point);
    3080 * this does not necessarily mean, that the solver knows and can return the primal ray
    3081 */
    3083 SCIP_LPI* lpi /**< LP interface structure */
    3084 )
    3085{
    3086 assert(lpi != NULL);
    3087 assert(lpi->cpxlp != NULL);
    3088 assert(lpi->solstat >= 0);
    3089
    3090 return (lpi->solstat == CPX_STAT_UNBOUNDED || lpi->solstat == CPX_STAT_OPTIMAL_FACE_UNBOUNDED);
    3091}
    3092
    3093/** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point),
    3094 * and the solver knows and can return the primal ray
    3095 */
    3097 SCIP_LPI* lpi /**< LP interface structure */
    3098 )
    3099{
    3100 assert(lpi != NULL);
    3101 assert(lpi->cpxlp != NULL);
    3102 assert(lpi->cpxenv != NULL);
    3103 assert(lpi->solstat >= 0);
    3104
    3105 return (lpi->solstat == CPX_STAT_UNBOUNDED );
    3106}
    3107
    3108/** returns TRUE iff LP is proven to be primal unbounded */
    3110 SCIP_LPI* lpi /**< LP interface structure */
    3111 )
    3112{
    3113 int primalfeasible;
    3114
    3115 assert(lpi != NULL);
    3116 assert(lpi->cpxlp != NULL);
    3117 assert(lpi->cpxenv != NULL);
    3118 assert(lpi->solstat >= 0);
    3119
    3120 SCIPdebugMessage("checking for primal unboundedness\n");
    3121
    3122 ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, &primalfeasible, NULL) );
    3123
    3124 /* If the solution status of CPLEX is CPX_STAT_UNBOUNDED, it only means, there is an unbounded ray,
    3125 * but not necessarily a feasible primal solution. If primalfeasible == FALSE, we cannot conclude,
    3126 * that the problem is unbounded.
    3127 */
    3128 return ((primalfeasible && (lpi->solstat == CPX_STAT_UNBOUNDED || lpi->solstat == CPX_STAT_INForUNBD))
    3129 || lpi->solstat == CPX_STAT_OPTIMAL_FACE_UNBOUNDED || (primalfeasible && lpi->solstat == CPX_STAT_ABORT_PRIM_OBJ_LIM && lpi->method == CPX_ALG_BARRIER));
    3130}
    3131
    3132/** returns TRUE iff LP is proven to be primal infeasible */
    3134 SCIP_LPI* lpi /**< LP interface structure */
    3135 )
    3136{
    3137 int dualfeasible;
    3138
    3139 assert(lpi != NULL);
    3140 assert(lpi->cpxlp != NULL);
    3141 assert(lpi->cpxenv != NULL);
    3142 assert(lpi->solstat >= 0);
    3143
    3144 SCIPdebugMessage("checking for primal infeasibility\n");
    3145
    3146 ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, NULL, &dualfeasible) );
    3147
    3148 return (lpi->solstat == CPX_STAT_INFEASIBLE || (lpi->solstat == CPX_STAT_INForUNBD && dualfeasible)
    3149 || (lpi->solstat == CPX_STAT_ABORT_DUAL_OBJ_LIM && lpi->method == CPX_ALG_BARRIER));
    3150}
    3151
    3152/** returns TRUE iff LP is proven to be primal feasible */
    3154 SCIP_LPI* lpi /**< LP interface structure */
    3155 )
    3156{
    3157 int primalfeasible;
    3158
    3159 assert(lpi != NULL);
    3160 assert(lpi->cpxlp != NULL);
    3161 assert(lpi->cpxenv != NULL);
    3162 assert(lpi->solstat >= 0);
    3163
    3164 SCIPdebugMessage("checking for primal feasibility\n");
    3165
    3166 ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, &primalfeasible, NULL) );
    3167
    3168 return (SCIP_Bool)primalfeasible;
    3169}
    3170
    3171/** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point);
    3172 * this does not necessarily mean, that the solver knows and can return the dual ray
    3173 */
    3175 SCIP_LPI* lpi /**< LP interface structure */
    3176 )
    3177{
    3178 assert(lpi != NULL);
    3179 assert(lpi->solstat >= 0);
    3180
    3181 return (lpi->solstat == CPX_STAT_INFEASIBLE);
    3182}
    3183
    3184/** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point),
    3185 * and the solver knows and can return the dual ray
    3186 */
    3188 SCIP_LPI* lpi /**< LP interface structure */
    3189 )
    3190{
    3191 assert(lpi != NULL);
    3192 assert(lpi->cpxlp != NULL);
    3193 assert(lpi->cpxenv != NULL);
    3194 assert(lpi->solstat >= 0);
    3195
    3196 return (lpi->solstat == CPX_STAT_INFEASIBLE && lpi->method == CPX_ALG_DUAL);
    3197}
    3198
    3199/** returns TRUE iff LP is proven to be dual unbounded */
    3201 SCIP_LPI* lpi /**< LP interface structure */
    3202 )
    3203{
    3204 int dualfeasible;
    3205
    3206 assert(lpi != NULL);
    3207 assert(lpi->cpxlp != NULL);
    3208 assert(lpi->cpxenv != NULL);
    3209 assert(lpi->solstat >= 0);
    3210
    3211 SCIPdebugMessage("checking for dual unboundedness\n");
    3212
    3213 ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, NULL, &dualfeasible) );
    3214
    3215 return (dualfeasible && ((lpi->solstat == CPX_STAT_INFEASIBLE || lpi->solstat == CPX_STAT_INForUNBD)
    3216 || (lpi->solstat == CPX_STAT_ABORT_DUAL_OBJ_LIM && lpi->method == CPX_ALG_BARRIER)));
    3217}
    3218
    3219/** returns TRUE iff LP is proven to be dual infeasible */
    3221 SCIP_LPI* lpi /**< LP interface structure */
    3222 )
    3223{
    3224 int primalfeasible;
    3225
    3226 assert(lpi != NULL);
    3227 assert(lpi->cpxlp != NULL);
    3228 assert(lpi->cpxenv != NULL);
    3229 assert(lpi->solstat >= 0);
    3230
    3231 SCIPdebugMessage("checking for dual infeasibility\n");
    3232
    3233 ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, &primalfeasible, NULL) );
    3234
    3235 return (lpi->solstat == CPX_STAT_UNBOUNDED
    3236 || lpi->solstat == CPX_STAT_OPTIMAL_FACE_UNBOUNDED
    3237 || (lpi->solstat == CPX_STAT_INForUNBD && primalfeasible)
    3238 || (lpi->solstat == CPX_STAT_ABORT_PRIM_OBJ_LIM && lpi->method == CPX_ALG_BARRIER));
    3239}
    3240
    3241/** returns TRUE iff LP is proven to be dual feasible */
    3243 SCIP_LPI* lpi /**< LP interface structure */
    3244 )
    3245{
    3246 int dualfeasible;
    3247
    3248 assert(lpi != NULL);
    3249 assert(lpi->cpxlp != NULL);
    3250 assert(lpi->cpxenv != NULL);
    3251 assert(lpi->solstat >= 0);
    3252
    3253 SCIPdebugMessage("checking for dual feasibility\n");
    3254
    3255 ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, NULL, &dualfeasible) );
    3256
    3257 return (SCIP_Bool)dualfeasible;
    3258}
    3259
    3260/** returns TRUE iff LP was solved to optimality */
    3262 SCIP_LPI* lpi /**< LP interface structure */
    3263 )
    3264{
    3265 assert(lpi != NULL);
    3266 assert(lpi->solstat >= 0);
    3267
    3268 return (lpi->solstat == CPX_STAT_OPTIMAL);
    3269}
    3270
    3271/** returns TRUE iff current LP solution is stable
    3272 *
    3273 * This function should return true if the solution is reliable, i.e., feasible and optimal (or proven
    3274 * infeasible/unbounded) with respect to the original problem. The optimality status might be with respect to a scaled
    3275 * version of the problem, but the solution might not be feasible to the unscaled original problem; in this case,
    3276 * SCIPlpiIsStable() should return false.
    3277 */
    3279 SCIP_LPI* lpi /**< LP interface structure */
    3280 )
    3281{
    3282 assert(lpi != NULL);
    3283 assert(lpi->cpxlp != NULL);
    3284 assert(lpi->cpxenv != NULL);
    3285 assert(lpi->solstat >= 0);
    3286
    3287 SCIPdebugMessage("checking for stability: CPLEX solstat = %d\n", lpi->solstat);
    3288
    3289#ifdef SCIP_DISABLED_CODE
    3290 /* The following workaround is not needed anymore for SCIP, since it tries to heuristically construct a feasible
    3291 * solution or automatically resolves the problem if the status is "unbounded"; see SCIPlpGetUnboundedSol().
    3292 */
    3293
    3294 /* If the solution status of CPLEX is CPX_STAT_UNBOUNDED, it only means, there is an unbounded ray,
    3295 * but not necessarily a feasible primal solution. If primalfeasible == FALSE, we interpret this
    3296 * result as instability, s.t. the problem is resolved from scratch
    3297 */
    3298 if( lpi->solstat == CPX_STAT_UNBOUNDED )
    3299 {
    3300 int primalfeasible;
    3301
    3302 ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, &primalfeasible, NULL) );
    3303
    3304 if( !primalfeasible )
    3305 return FALSE;
    3306 }
    3307#endif
    3308
    3309 /* If the condition number of the basis should be checked, everything above the specified threshold is counted
    3310 * as instable.
    3311 */
    3312 if( lpi->checkcondition && (SCIPlpiIsOptimal(lpi) || SCIPlpiIsObjlimExc(lpi)) )
    3313 {
    3314 SCIP_Real kappa;
    3315 SCIP_RETCODE retcode;
    3316
    3318 if ( retcode != SCIP_OKAY )
    3319 {
    3320 SCIPABORT();
    3321 return FALSE; /*lint !e527*/
    3322 }
    3323
    3324 /* if the kappa could not be computed (e.g., because we do not have a basis), we cannot check the condition */
    3325 if( kappa != SCIP_INVALID || kappa > lpi->conditionlimit ) /*lint !e777*/
    3326 return FALSE;
    3327 }
    3328
    3329 return (lpi->solstat != CPX_STAT_NUM_BEST && lpi->solstat != CPX_STAT_OPTIMAL_INFEAS);
    3330}
    3331
    3332/** returns TRUE iff the objective limit was reached */
    3334 SCIP_LPI* lpi /**< LP interface structure */
    3335 )
    3336{
    3337 assert(lpi != NULL);
    3338 assert(lpi->solstat >= 0);
    3339
    3340 if( lpi->solstat == CPX_STAT_ABORT_OBJ_LIM )
    3341 return TRUE;
    3342 else if( lpi->solstat == CPX_STAT_ABORT_DUAL_OBJ_LIM || lpi->solstat == CPX_STAT_ABORT_PRIM_OBJ_LIM )
    3343 {
    3344 if( lpi->method != CPX_ALG_BARRIER )
    3345 return TRUE;
    3346 }
    3347 return FALSE;
    3348}
    3349
    3350/** returns TRUE iff the iteration limit was reached */
    3352 SCIP_LPI* lpi /**< LP interface structure */
    3353 )
    3354{
    3355 assert(lpi != NULL);
    3356 assert(lpi->solstat >= 0);
    3357
    3358 return (lpi->solstat == CPX_STAT_ABORT_IT_LIM);
    3359}
    3360
    3361/** returns TRUE iff the time limit was reached */
    3363 SCIP_LPI* lpi /**< LP interface structure */
    3364 )
    3365{
    3366 assert(lpi != NULL);
    3367 assert(lpi->solstat >= 0);
    3368
    3369 return (lpi->solstat == CPX_STAT_ABORT_TIME_LIM);
    3370}
    3371
    3372/** returns the internal solution status of the solver */
    3374 SCIP_LPI* lpi /**< LP interface structure */
    3375 )
    3376{
    3377 assert(lpi != NULL);
    3378 assert(lpi->cpxlp != NULL);
    3379
    3380 return lpi->solstat;
    3381}
    3382
    3383/** tries to reset the internal status of the LP solver in order to ignore an instability of the last solving call */
    3385 SCIP_LPI* lpi, /**< LP interface structure */
    3386 SCIP_Bool* success /**< pointer to store, whether the instability could be ignored */
    3387 )
    3388{
    3389 assert(lpi != NULL);
    3390 assert(lpi->cpxlp != NULL);
    3391 assert(success != NULL);
    3392 assert(lpi->solstat == CPX_STAT_UNBOUNDED
    3393 || lpi->solstat == CPX_STAT_NUM_BEST
    3394 || lpi->solstat == CPX_STAT_OPTIMAL_INFEAS);
    3395
    3396 /* replace instable status with optimal status */
    3397 if( lpi->solstat == CPX_STAT_NUM_BEST || lpi->solstat == CPX_STAT_OPTIMAL_INFEAS )
    3398 lpi->solstat = CPX_STAT_OPTIMAL;
    3399
    3400 *success = TRUE;
    3401 lpi->instabilityignored = TRUE;
    3402
    3403 return SCIP_OKAY;
    3404}
    3405
    3406/** gets objective value of solution */
    3408 SCIP_LPI* lpi, /**< LP interface structure */
    3409 SCIP_Real* objval /**< stores the objective value */
    3410 )
    3411{
    3412 int retcode;
    3413
    3414 assert(lpi != NULL);
    3415 assert(lpi->cpxlp != NULL);
    3416 assert(lpi->cpxenv != NULL);
    3417 assert(objval != NULL);
    3418
    3419 SCIPdebugMessage("getting solution's objective value\n");
    3420
    3421 retcode = CPXgetobjval(lpi->cpxenv, lpi->cpxlp, objval);
    3422
    3423 /* if CPLEX has no solution, e.g., because of a reached time limit, we return -infinity */
    3424 if( retcode == CPXERR_NO_SOLN )
    3425 {
    3426 *objval = -SCIPlpiInfinity(lpi);
    3427 }
    3428 else
    3429 {
    3430 CHECK_ZERO( lpi->messagehdlr, retcode );
    3431 }
    3432
    3433 return SCIP_OKAY;
    3434}
    3435
    3436/** gets primal and dual solution vectors for feasible LPs
    3437 *
    3438 * Before calling this function, the caller must ensure that the LP has been solved to optimality, i.e., that
    3439 * SCIPlpiIsOptimal() returns true.
    3440 */
    3442 SCIP_LPI* lpi, /**< LP interface structure */
    3443 SCIP_Real* objval, /**< stores the objective value, may be NULL if not needed */
    3444 SCIP_Real* primsol, /**< primal solution vector, may be NULL if not needed */
    3445 SCIP_Real* dualsol, /**< dual solution vector, may be NULL if not needed */
    3446 SCIP_Real* activity, /**< row activity vector, may be NULL if not needed */
    3447 SCIP_Real* redcost /**< reduced cost vector, may be NULL if not needed */
    3448 )
    3449{
    3450 int dummy;
    3451
    3452 assert(lpi != NULL);
    3453 assert(lpi->cpxlp != NULL);
    3454 assert(lpi->cpxenv != NULL);
    3455 assert(lpi->solstat >= 0);
    3456
    3457 SCIPdebugMessage("getting solution\n");
    3458
    3459 CHECK_ZERO( lpi->messagehdlr, CPXsolution(lpi->cpxenv, lpi->cpxlp, &dummy, objval, primsol, dualsol, NULL, redcost) );
    3460 assert(dummy == lpi->solstat || lpi->instabilityignored);
    3461
    3462 if( activity != NULL )
    3463 {
    3464 CHECK_ZERO( lpi->messagehdlr, CPXgetax(lpi->cpxenv, lpi->cpxlp, activity, 0, CPXgetnumrows(lpi->cpxenv, lpi->cpxlp)-1) );
    3465 }
    3466
    3467 return SCIP_OKAY;
    3468}
    3469
    3470/** gets primal ray for unbounded LPs */
    3472 SCIP_LPI* lpi, /**< LP interface structure */
    3473 SCIP_Real* ray /**< primal ray */
    3474 )
    3475{
    3476 assert(lpi != NULL);
    3477 assert(lpi->cpxlp != NULL);
    3478 assert(lpi->cpxenv != NULL);
    3479 assert(lpi->solstat >= 0);
    3480 assert(ray != NULL);
    3481
    3482 SCIPdebugMessage("calling CPLEX get primal ray: %d cols, %d rows\n",
    3483 CPXgetnumcols(lpi->cpxenv, lpi->cpxlp), CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
    3484
    3485 CHECK_ZERO( lpi->messagehdlr, CPXgetray(lpi->cpxenv, lpi->cpxlp, ray) );
    3486
    3487 return SCIP_OKAY;
    3488}
    3489
    3490/** gets dual Farkas proof for infeasibility */
    3492 SCIP_LPI* lpi, /**< LP interface structure */
    3493 SCIP_Real* dualfarkas /**< dual Farkas row multipliers */
    3494 )
    3495{
    3496 assert(lpi != NULL);
    3497 assert(lpi->cpxlp != NULL);
    3498 assert(lpi->cpxenv != NULL);
    3499 assert(lpi->solstat >= 0);
    3500 assert(dualfarkas != NULL);
    3501
    3502 SCIPdebugMessage("calling CPLEX dual Farkas: %d cols, %d rows\n",
    3503 CPXgetnumcols(lpi->cpxenv, lpi->cpxlp), CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
    3504
    3505 CHECK_ZERO( lpi->messagehdlr, CPXdualfarkas(lpi->cpxenv, lpi->cpxlp, dualfarkas, NULL) );
    3506
    3507 return SCIP_OKAY;
    3508}
    3509
    3510/** gets the number of LP iterations of the last solve call */
    3512 SCIP_LPI* lpi, /**< LP interface structure */
    3513 int* iterations /**< pointer to store the number of iterations of the last solve call */
    3514 )
    3515{
    3516 assert(lpi != NULL);
    3517 assert(iterations != NULL);
    3518
    3519 *iterations = lpi->iterations;
    3520
    3521 return SCIP_OKAY;
    3522}
    3523
    3524/** gets information about the quality of an LP solution
    3525 *
    3526 * Such information is usually only available, if also a (maybe not optimal) solution is available.
    3527 * The LPI should return SCIP_INVALID for @p quality, if the requested quantity is not available.
    3528 */
    3530 SCIP_LPI* lpi, /**< LP interface structure */
    3531 SCIP_LPSOLQUALITY qualityindicator, /**< indicates which quality should be returned */
    3532 SCIP_Real* quality /**< pointer to store quality number */
    3533 )
    3534{
    3535 int solntype;
    3536
    3537 assert(lpi != NULL);
    3538 assert(lpi->cpxlp != NULL);
    3539 assert(lpi->cpxenv != NULL);
    3540 assert(quality != NULL);
    3541
    3542 *quality = SCIP_INVALID;
    3543
    3544 SCIPdebugMessage("requesting solution quality from CPLEX: quality %d\n", qualityindicator);
    3545
    3546 CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, NULL, NULL) );
    3547
    3548 if( solntype == CPX_BASIC_SOLN )
    3549 {
    3550 int what;
    3551
    3552 switch( qualityindicator )
    3553 {
    3555 what = CPX_KAPPA;
    3556 break;
    3557
    3559 what = CPX_EXACT_KAPPA;
    3560 break;
    3561
    3562 default:
    3563 SCIPerrorMessage("Solution quality %d unknown.\n", qualityindicator);
    3564 return SCIP_INVALIDDATA;
    3565 }
    3566
    3567 (void) CPXgetdblquality(lpi->cpxenv, lpi->cpxlp, quality, what);
    3568 }
    3569
    3570 return SCIP_OKAY;
    3571}
    3572
    3573/**@} */
    3574
    3575
    3576
    3577
    3578/*
    3579 * LP Basis Methods
    3580 */
    3581
    3582/**@name LP Basis Methods */
    3583/**@{ */
    3584
    3585/** gets current basis status for columns and rows; arrays must be large enough to store the basis status */
    3587 SCIP_LPI* lpi, /**< LP interface structure */
    3588 int* cstat, /**< array to store column basis status, or NULL */
    3589 int* rstat /**< array to store row basis status, or NULL */
    3590 )
    3591{
    3592 int i;
    3593 int nrows;
    3594 char sense;
    3595
    3596 assert(lpi != NULL);
    3597 assert(lpi->cpxlp != NULL);
    3598 assert(lpi->cpxenv != NULL);
    3599
    3600 SCIPdebugMessage("saving CPLEX basis into %p/%p\n", (void *) cstat, (void *) rstat);
    3601
    3602 CHECK_ZERO( lpi->messagehdlr, CPXgetbase(lpi->cpxenv, lpi->cpxlp, cstat, rstat) );
    3603
    3604 /* correct rstat values for "<=" constraints: Here CPX_AT_LOWER bound means that the slack is 0, i.e., the upper bound is tight */
    3605 nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
    3606 for (i = 0; i < nrows; ++i)
    3607 {
    3608 if ( rstat[i] == CPX_AT_LOWER )
    3609 {
    3610 CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, &sense, i, i) );
    3611 if ( sense == 'L' )
    3612 rstat[i] = (int) SCIP_BASESTAT_UPPER;
    3613 }
    3614 }
    3615
    3616 /* because the basis status values are equally defined in SCIP and CPLEX, they don't need to be transformed */
    3617 assert((int)SCIP_BASESTAT_LOWER == CPX_AT_LOWER); /*lint !e506*/
    3618 assert((int)SCIP_BASESTAT_BASIC == CPX_BASIC); /*lint !e506*/
    3619 assert((int)SCIP_BASESTAT_UPPER == CPX_AT_UPPER); /*lint !e506*/
    3620 assert((int)SCIP_BASESTAT_ZERO == CPX_FREE_SUPER); /*lint !e506*/
    3621
    3622 return SCIP_OKAY;
    3623}
    3624
    3625/** sets current basis status for columns and rows */
    3627 SCIP_LPI* lpi, /**< LP interface structure */
    3628 const int* cstat, /**< array with column basis status */
    3629 const int* rstat /**< array with row basis status */
    3630 )
    3631{
    3632 int i;
    3633 int nrows;
    3634 int ncols;
    3635 char sense;
    3636
    3637 assert(lpi != NULL);
    3638 assert(lpi->cpxlp != NULL);
    3639 assert(lpi->cpxenv != NULL);
    3640
    3641 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    3642 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
    3643
    3644 assert(cstat != NULL || ncols == 0);
    3645 assert(rstat != NULL || nrows == 0);
    3646
    3647 SCIPdebugMessage("loading basis %p/%p into CPLEX\n", (void *) cstat, (void *) rstat);
    3648
    3649 invalidateSolution(lpi);
    3650
    3651 /* because the basis status values are equally defined in SCIP and CPLEX, they don't need to be transformed */
    3652 assert((int)SCIP_BASESTAT_LOWER == CPX_AT_LOWER); /*lint !e506*/
    3653 assert((int)SCIP_BASESTAT_BASIC == CPX_BASIC); /*lint !e506*/
    3654 assert((int)SCIP_BASESTAT_UPPER == CPX_AT_UPPER); /*lint !e506*/
    3655 assert((int)SCIP_BASESTAT_ZERO == CPX_FREE_SUPER); /*lint !e506*/
    3656
    3657 /* Copy rstat to internal structure and correct rstat values for ">=" constraints: Here CPX_AT_LOWER bound means that
    3658 * the slack is 0, i.e., the upper bound is tight. */
    3659 SCIP_CALL( ensureRstatMem(lpi, nrows) );
    3660 for (i = 0; i < nrows; ++i)
    3661 {
    3662 if ( rstat[i] == (int) SCIP_BASESTAT_UPPER ) /*lint !e613*/
    3663 {
    3664 CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, &sense, i, i) );
    3665 if ( sense == 'L' )
    3666 lpi->rstat[i] = CPX_AT_LOWER;
    3667 }
    3668 else
    3669 lpi->rstat[i] = rstat[i]; /*lint !e613*/
    3670 }
    3671
    3672 CHECK_ZERO( lpi->messagehdlr, CPXcopybase(lpi->cpxenv, lpi->cpxlp, cstat, lpi->rstat) );
    3673
    3674 return SCIP_OKAY;
    3675}
    3676
    3677/** returns the indices of the basic columns and rows; basic column n gives value n, basic row m gives value -1-m */
    3679 SCIP_LPI* lpi, /**< LP interface structure */
    3680 int* bind /**< pointer to store basis indices ready to keep number of rows entries */
    3681 )
    3682{
    3683 int retval;
    3684
    3685 assert(lpi != NULL);
    3686 assert(lpi->cpxlp != NULL);
    3687 assert(lpi->cpxenv != NULL);
    3688 assert(bind != NULL);
    3689
    3690 SCIPdebugMessage("getting basis information\n");
    3691
    3692 /* this might be turned off if the user as called SCIPlpiClearState() or set SCIP_LPPAR_FROMSCRATCH to TRUE */
    3693 setIntParam(lpi, CPX_PARAM_ADVIND, CPX_ON);
    3694 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
    3695
    3696 retval = CPXgetbhead(lpi->cpxenv, lpi->cpxlp, bind, NULL);
    3697 if( retval == CPXERR_NO_SOLN || retval == CPXERR_NO_LU_FACTOR || retval == CPXERR_NO_BASIC_SOLN || retval == CPXERR_NO_BASIS )
    3698 {
    3700 retval = CPXgetbhead(lpi->cpxenv, lpi->cpxlp, bind, NULL);
    3701 }
    3702 CHECK_ZERO( lpi->messagehdlr, retval );
    3703
    3704 return SCIP_OKAY;
    3705}
    3706
    3707/** get row of inverse basis matrix B^-1
    3708 *
    3709 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
    3710 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
    3711 * see also the explanation in lpi.h.
    3712 */ /*lint -e{715}*/
    3714 SCIP_LPI* lpi, /**< LP interface structure */
    3715 int r, /**< row number */
    3716 SCIP_Real* coef, /**< pointer to store the coefficients of the row */
    3717 int* inds, /**< array to store the non-zero indices, or NULL */
    3718 int* ninds /**< pointer to store the number of non-zero indices, or NULL
    3719 * (-1: if we do not store sparsity information) */
    3720 )
    3721{ /*lint --e{715}*/
    3722 int retval;
    3723 int nrows;
    3724
    3725 assert(lpi != NULL);
    3726 assert(lpi->cpxlp != NULL);
    3727 assert(lpi->cpxenv != NULL);
    3728 assert(coef != NULL);
    3729
    3730 SCIPdebugMessage("getting binv-row %d\n", r);
    3731
    3732 /* can only return dense result */
    3733 if ( ninds != NULL )
    3734 *ninds = -1;
    3735
    3736 /* this might be turned off if the user as called SCIPlpiClearState() or set SCIP_LPPAR_FROMSCRATCH to TRUE */
    3737 setIntParam(lpi, CPX_PARAM_ADVIND, CPX_ON);
    3738 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
    3739
    3740 retval = CPXbinvrow(lpi->cpxenv, lpi->cpxlp, r, coef);
    3741 if( retval == CPXERR_NO_SOLN || retval == CPXERR_NO_LU_FACTOR || retval == CPXERR_NO_BASIC_SOLN || retval == CPXERR_NO_BASIS )
    3742 {
    3744 retval = CPXbinvrow(lpi->cpxenv, lpi->cpxlp, r, coef);
    3745 }
    3746 CHECK_ZERO( lpi->messagehdlr, retval );
    3747
    3748 /* the LPi expects slack variables with coefficient +1; CPLEX adds slack variables with a coefficient -1 for 'G'
    3749 * constraints, so we have to change the sign of the corresponding rows
    3750 */
    3751 nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
    3752 SCIP_CALL( ensureValMem(lpi, nrows) );
    3753 CHECK_ZERO( lpi->messagehdlr, CPXgetbhead(lpi->cpxenv, lpi->cpxlp, lpi->indarray, NULL) );
    3754
    3755 if( lpi->indarray[r] < 0 )
    3756 {
    3757 int basicrow;
    3758 char rowsense;
    3759
    3760 basicrow = -lpi->indarray[r] - 1;
    3761 assert(basicrow >= 0);
    3762 assert(basicrow < nrows);
    3763
    3764 CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, &rowsense, basicrow, basicrow) );
    3765
    3766 /* slacks for 'G' and 'R' rows are added with -1 in CPLEX */
    3767 if( rowsense == 'G' || rowsense == 'R' )
    3768 {
    3769 int i;
    3770
    3771 for( i = 0; i < nrows; i++ )
    3772 coef[i] *= -1.0;
    3773 }
    3774 }
    3775
    3776 return SCIP_OKAY;
    3777}
    3778
    3779/** get column of inverse basis matrix B^-1
    3780 *
    3781 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
    3782 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
    3783 * see also the explanation in lpi.h.
    3784 */ /*lint -e{715}*/
    3786 SCIP_LPI* lpi, /**< LP interface structure */
    3787 int c, /**< column number of B^-1; this is NOT the number of the column in the LP;
    3788 * you have to call SCIPlpiGetBasisInd() to get the array which links the
    3789 * B^-1 column numbers to the row and column numbers of the LP!
    3790 * c must be between 0 and nrows-1, since the basis has the size
    3791 * nrows * nrows */
    3792 SCIP_Real* coef, /**< pointer to store the coefficients of the column */
    3793 int* inds, /**< array to store the non-zero indices, or NULL */
    3794 int* ninds /**< pointer to store the number of non-zero indices, or NULL
    3795 * (-1: if we do not store sparsity information) */
    3796 )
    3797{ /*lint --e{715}*/
    3798 int retval;
    3799 int nrows;
    3800 int r;
    3801
    3802 assert(lpi != NULL);
    3803 assert(lpi->cpxlp != NULL);
    3804 assert(lpi->cpxenv != NULL);
    3805 assert(coef != NULL);
    3806
    3807 SCIPdebugMessage("getting binv-col %d\n", c);
    3808
    3809 /* can only return dense result */
    3810 if ( ninds != NULL )
    3811 *ninds = -1;
    3812
    3813 /* this might be turned off if the user as called SCIPlpiClearState() or set SCIP_LPPAR_FROMSCRATCH to TRUE */
    3814 setIntParam(lpi, CPX_PARAM_ADVIND, CPX_ON);
    3815 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
    3816
    3817 retval = CPXbinvcol(lpi->cpxenv, lpi->cpxlp, c, coef);
    3818 if( retval == CPXERR_NO_SOLN || retval == CPXERR_NO_LU_FACTOR || retval == CPXERR_NO_BASIC_SOLN || retval == CPXERR_NO_BASIS )
    3819 {
    3821 retval = CPXbinvcol(lpi->cpxenv, lpi->cpxlp, c, coef);
    3822 }
    3823 CHECK_ZERO( lpi->messagehdlr, retval );
    3824
    3825 /* the LPi expects slack variables with coefficient +1; CPLEX adds slack variables with a coefficient -1 for 'G'
    3826 * constraints, so we have to change the sign of the corresponding rows
    3827 */
    3828 nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
    3829 SCIP_CALL( ensureValMem(lpi, nrows) );
    3830 CHECK_ZERO( lpi->messagehdlr, CPXgetbhead(lpi->cpxenv, lpi->cpxlp, lpi->indarray, NULL) );
    3831 SCIP_CALL( ensureSidechgMem(lpi, nrows) );
    3832 CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, lpi->senarray, 0, nrows - 1) );
    3833
    3834 for( r = 0; r < nrows; r++ )
    3835 {
    3836 if( lpi->indarray[r] < 0 )
    3837 {
    3838 int basicrow;
    3839
    3840 basicrow = -lpi->indarray[r] - 1;
    3841 assert(basicrow >= 0);
    3842 assert(basicrow < nrows);
    3843
    3844 /* slacks for 'G' and 'R' rows are added with -1 in CPLEX */
    3845 if( basicrow >= 0 && basicrow < nrows && (lpi->senarray[basicrow] == 'G' || lpi->senarray[basicrow] == 'R') )
    3846 coef[r] *= -1.0;
    3847 }
    3848 }
    3849
    3850 return SCIP_OKAY;
    3851}
    3852
    3853/** get row of inverse basis matrix times constraint matrix B^-1 * A
    3854 *
    3855 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
    3856 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
    3857 * see also the explanation in lpi.h.
    3858 */ /*lint -e{715}*/
    3860 SCIP_LPI* lpi, /**< LP interface structure */
    3861 int r, /**< row number */
    3862 const SCIP_Real* binvrow, /**< row in (A_B)^-1 from prior call to SCIPlpiGetBInvRow(), or NULL */
    3863 SCIP_Real* coef, /**< vector to return coefficients of the row */
    3864 int* inds, /**< array to store the non-zero indices, or NULL */
    3865 int* ninds /**< pointer to store the number of non-zero indices, or NULL
    3866 * (-1: if we do not store sparsity information) */
    3867 )
    3868{ /*lint --e{715}*/
    3869 int retval;
    3870 int nrows;
    3871
    3872 assert(lpi != NULL);
    3873 assert(lpi->cpxlp != NULL);
    3874 assert(lpi->cpxenv != NULL);
    3875 assert(coef != NULL);
    3876
    3877 SCIPdebugMessage("getting binva-row %d\n", r);
    3878
    3879 /* can only return dense result */
    3880 if ( ninds != NULL )
    3881 *ninds = -1;
    3882
    3883 /* this might be turned off if the user as called SCIPlpiClearState() or set SCIP_LPPAR_FROMSCRATCH to TRUE */
    3884 setIntParam(lpi, CPX_PARAM_ADVIND, CPX_ON);
    3885 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
    3886
    3887 retval = CPXbinvarow(lpi->cpxenv, lpi->cpxlp, r, coef);
    3888 if( retval == CPXERR_NO_SOLN || retval == CPXERR_NO_LU_FACTOR || retval == CPXERR_NO_BASIC_SOLN || retval == CPXERR_NO_BASIS )
    3889 {
    3891 retval = CPXbinvarow(lpi->cpxenv, lpi->cpxlp, r, coef);
    3892 }
    3893 CHECK_ZERO( lpi->messagehdlr, retval );
    3894
    3895 /* the LPi expects slack variables with coefficient +1; CPLEX adds slack variables with a coefficient -1 for 'G'
    3896 * constraints, so we have to change the sign of the corresponding rows
    3897 */
    3898 nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
    3899 SCIP_CALL( ensureValMem(lpi, nrows) );
    3900 CHECK_ZERO( lpi->messagehdlr, CPXgetbhead(lpi->cpxenv, lpi->cpxlp, lpi->indarray, NULL) );
    3901
    3902 if( lpi->indarray[r] < 0 )
    3903 {
    3904 int basicrow;
    3905 char rowsense;
    3906
    3907 basicrow = -lpi->indarray[r] - 1;
    3908 assert(basicrow >= 0);
    3909 assert(basicrow < nrows);
    3910
    3911 CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, &rowsense, basicrow, basicrow) );
    3912
    3913 /* slacks for 'G' and 'R' rows are added with -1 in CPLEX */
    3914 if( rowsense == 'G' || rowsense == 'R' )
    3915 {
    3916 int ncols;
    3917 int j;
    3918
    3919 ncols = CPXgetnumcols(lpi->cpxenv, lpi->cpxlp);
    3920 for( j = 0; j < ncols; j++ )
    3921 coef[j] *= -1.0;
    3922 }
    3923 }
    3924
    3925 return SCIP_OKAY;
    3926}
    3927
    3928/** get column of inverse basis matrix times constraint matrix B^-1 * A
    3929 *
    3930 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
    3931 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
    3932 * see also the explanation in lpi.h.
    3933 *//*lint -e{715}*/
    3935 SCIP_LPI* lpi, /**< LP interface structure */
    3936 int c, /**< column number */
    3937 SCIP_Real* coef, /**< vector to return coefficients of the column */
    3938 int* inds, /**< array to store the non-zero indices, or NULL */
    3939 int* ninds /**< pointer to store the number of non-zero indices, or NULL
    3940 * (-1: if we do not store sparsity information) */
    3941 )
    3942{ /*lint --e{715}*/
    3943 int retval;
    3944 int nrows;
    3945 int r;
    3946
    3947 assert(lpi != NULL);
    3948 assert(lpi->cpxenv != NULL);
    3949 assert(lpi->cpxlp != NULL);
    3950 assert(coef != NULL);
    3951
    3952 SCIPdebugMessage("getting binva-col %d\n", c);
    3953
    3954 /* can only return dense result */
    3955 if ( ninds != NULL )
    3956 *ninds = -1;
    3957
    3958 /* this might be turned off if the user as called SCIPlpiClearState() or set SCIP_LPPAR_FROMSCRATCH to TRUE */
    3959 setIntParam(lpi, CPX_PARAM_ADVIND, CPX_ON);
    3960 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
    3961
    3962 retval = CPXbinvacol(lpi->cpxenv, lpi->cpxlp, c, coef);
    3963 if( retval == CPXERR_NO_SOLN || retval == CPXERR_NO_LU_FACTOR || retval == CPXERR_NO_BASIC_SOLN || retval == CPXERR_NO_BASIS )
    3964 {
    3966 retval = CPXbinvacol(lpi->cpxenv, lpi->cpxlp, c, coef);
    3967 }
    3968 CHECK_ZERO( lpi->messagehdlr, retval );
    3969
    3970 /* the LPi expects slack variables with coefficient +1; CPLEX adds slack variables with a coefficient -1 for 'G'
    3971 * constraints, so we have to change the sign of the corresponding rows
    3972 */
    3973 nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
    3974 SCIP_CALL( ensureValMem(lpi, nrows) );
    3975 CHECK_ZERO( lpi->messagehdlr, CPXgetbhead(lpi->cpxenv, lpi->cpxlp, lpi->indarray, NULL) );
    3976 SCIP_CALL( ensureSidechgMem(lpi, nrows) );
    3977 CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, lpi->senarray, 0, nrows - 1) );
    3978
    3979 for( r = 0; r < nrows; r++ )
    3980 {
    3981 if( lpi->indarray[r] < 0 )
    3982 {
    3983 int basicrow;
    3984
    3985 basicrow = -lpi->indarray[r] - 1;
    3986 assert(basicrow >= 0);
    3987 assert(basicrow < nrows);
    3988
    3989 /* slacks for 'G' and 'R' rows are added with -1 in CPLEX */
    3990 if( basicrow >= 0 && basicrow < nrows && (lpi->senarray[basicrow] == 'G' || lpi->senarray[basicrow] == 'R') )
    3991 coef[r] *= -1.0;
    3992 }
    3993 }
    3994
    3995 return SCIP_OKAY;
    3996}
    3997
    3998/**@} */
    3999
    4000
    4001
    4002
    4003/*
    4004 * LP State Methods
    4005 */
    4006
    4007/**@name LP State Methods */
    4008/**@{ */
    4009
    4010/** stores LPi state (like basis information) into lpistate object */
    4012 SCIP_LPI* lpi, /**< LP interface structure */
    4013 BMS_BLKMEM* blkmem, /**< block memory */
    4014 SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
    4015 )
    4016{
    4017 int ncols;
    4018 int nrows;
    4019
    4020 assert(blkmem != NULL);
    4021 assert(lpi != NULL);
    4022 assert(lpi->cpxlp != NULL);
    4023 assert(lpi->cpxenv != NULL);
    4024 assert(lpistate != NULL);
    4025
    4026 /* if there is no basis information available (e.g. after barrier without crossover), or no state can be saved; if
    4027 * SCIPlpiClearState() has been called, do not return the state
    4028 */
    4029 if( !lpi->solisbasic || lpi->clearstate )
    4030 {
    4031 *lpistate = NULL;
    4032 return SCIP_OKAY;
    4033 }
    4034
    4035 ncols = CPXgetnumcols(lpi->cpxenv, lpi->cpxlp);
    4036 nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
    4037 assert(ncols >= 0);
    4038 assert(nrows >= 0);
    4039
    4040 /* allocate lpistate data */
    4041 SCIP_CALL( lpistateCreate(lpistate, blkmem, ncols, nrows) );
    4042
    4043 SCIPdebugMessage("storing CPLEX LPI state in %p (%d cols, %d rows)\n", (void *) *lpistate, ncols, nrows);
    4044
    4045 /* get unpacked basis information from CPLEX */
    4046 SCIP_CALL( getBase(lpi) );
    4047
    4048 /* pack LPi state data */
    4049 (*lpistate)->ncols = ncols;
    4050 (*lpistate)->nrows = nrows;
    4051 lpistatePack(*lpistate, lpi->cstat, lpi->rstat);
    4052
    4053 return SCIP_OKAY;
    4054}
    4055
    4056/** loads LPi state (like basis information) into solver; note that the LP might have been extended with additional
    4057 * columns and rows since the state was stored with SCIPlpiGetState()
    4058 */
    4060 SCIP_LPI* lpi, /**< LP interface structure */
    4061 BMS_BLKMEM* blkmem, /**< block memory */
    4062 const SCIP_LPISTATE* lpistate /**< LPi state information (like basis information), or NULL */
    4063 )
    4064{
    4065 int lpncols;
    4066 int lpnrows;
    4067 int i;
    4068
    4069 assert(blkmem != NULL);
    4070 assert(lpi != NULL);
    4071 assert(lpi->cpxlp != NULL);
    4072 assert(lpi->cpxenv != NULL);
    4073
    4074 /* if there was no basis information available, the LPI state was not stored */
    4075 if( lpistate == NULL )
    4076 return SCIP_OKAY;
    4077
    4078 lpncols = CPXgetnumcols(lpi->cpxenv, lpi->cpxlp);
    4079 lpnrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
    4080 assert(lpistate->ncols <= lpncols);
    4081 assert(lpistate->nrows <= lpnrows);
    4082
    4083 SCIPdebugMessage("loading LPI state %p (%d cols, %d rows) into CPLEX LP with %d cols and %d rows\n",
    4084 (void *) lpistate, lpistate->ncols, lpistate->nrows, lpncols, lpnrows);
    4085
    4086 if( lpistate->ncols == 0 || lpistate->nrows == 0 )
    4087 return SCIP_OKAY;
    4088
    4089 /* allocate enough memory for storing uncompressed basis information */
    4090 SCIP_CALL( ensureCstatMem(lpi, lpncols) );
    4091 SCIP_CALL( ensureRstatMem(lpi, lpnrows) );
    4092
    4093 /* unpack LPi state data */
    4094 lpistateUnpack(lpistate, lpi->cstat, lpi->rstat);
    4095
    4096 /* extend the basis to the current LP beyond the previously existing columns */
    4097 for( i = lpistate->ncols; i < lpncols; ++i )
    4098 {
    4099 SCIP_Real bnd;
    4100 CHECK_ZERO( lpi->messagehdlr, CPXgetlb(lpi->cpxenv, lpi->cpxlp, &bnd, i, i) );
    4101 if ( SCIPlpiIsInfinity(lpi, REALABS(bnd)) )
    4102 {
    4103 /* if lower bound is +/- infinity -> try upper bound */
    4104 CHECK_ZERO( lpi->messagehdlr, CPXgetub(lpi->cpxenv, lpi->cpxlp, &bnd, i, i) );
    4105 if ( SCIPlpiIsInfinity(lpi, REALABS(bnd)) )
    4106 lpi->cstat[i] = (int) SCIP_BASESTAT_ZERO; /* variable is free -> super basic */
    4107 else
    4108 lpi->cstat[i] = (int) SCIP_BASESTAT_UPPER; /* use finite upper bound */
    4109 }
    4110 else
    4111 lpi->cstat[i] = (int) SCIP_BASESTAT_LOWER; /* use finite lower bound */
    4112 }
    4113 for( i = lpistate->nrows; i < lpnrows; ++i )
    4114 lpi->rstat[i] = (int) SCIP_BASESTAT_BASIC;
    4115
    4116 /* load basis information into CPLEX */
    4117 SCIP_CALL( setBase(lpi) );
    4118
    4119 return SCIP_OKAY;
    4120}
    4121
    4122/** clears current LPi state (like basis information) of the solver */
    4124 SCIP_LPI* lpi /**< LP interface structure */
    4125 )
    4126{
    4127 assert(lpi != NULL);
    4128
    4129 /* set CPX_PARAM_ADVIND to CPX_OFF for the next solve */
    4130 lpi->clearstate = TRUE;
    4131
    4132 return SCIP_OKAY;
    4133}
    4134
    4135/** frees LPi state information */
    4137 SCIP_LPI* lpi, /**< LP interface structure */
    4138 BMS_BLKMEM* blkmem, /**< block memory */
    4139 SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
    4140 )
    4141{
    4142 assert(lpi != NULL);
    4143 assert(lpistate != NULL);
    4144 assert(blkmem != NULL);
    4145
    4146 if( *lpistate != NULL )
    4147 {
    4148 lpistateFree(lpistate, blkmem);
    4149 }
    4150
    4151 return SCIP_OKAY;
    4152}
    4153
    4154/** checks whether the given LP state contains simplex basis information */
    4156 SCIP_LPI* lpi, /**< LP interface structure */
    4157 SCIP_LPISTATE* lpistate /**< LP state information (like basis information), or NULL */
    4158 )
    4159{ /*lint --e{715}*/
    4160 assert(lpi != NULL);
    4161 return (lpistate != NULL);
    4162}
    4163
    4164/** reads LP state (like basis information from a file */
    4166 SCIP_LPI* lpi, /**< LP interface structure */
    4167 const char* fname /**< file name */
    4168 )
    4169{
    4170 assert(lpi != NULL);
    4171 assert(lpi->cpxlp != NULL);
    4172 assert(lpi->cpxenv != NULL);
    4173 assert(fname != NULL);
    4174
    4175 SCIPdebugMessage("reading LP state from file <%s>\n", fname);
    4176
    4177 CHECK_ZERO( lpi->messagehdlr, CPXreadcopybase(lpi->cpxenv, lpi->cpxlp, fname) );
    4178
    4179 return SCIP_OKAY;
    4180}
    4181
    4182/** writes LPi state (i.e. basis information) to a file */
    4184 SCIP_LPI* lpi, /**< LP interface structure */
    4185 const char* fname /**< file name */
    4186 )
    4187{
    4188 assert(lpi != NULL);
    4189 assert(lpi->cpxlp != NULL);
    4190 assert(lpi->cpxenv != NULL);
    4191 assert(fname != NULL);
    4192
    4193 SCIPdebugMessage("writing LP state to file <%s>\n", fname);
    4194
    4195 CHECK_ZERO( lpi->messagehdlr, CPXmbasewrite(lpi->cpxenv, lpi->cpxlp, fname) );
    4196
    4197 return SCIP_OKAY;
    4198}
    4199
    4200/**@} */
    4201
    4202
    4203
    4204
    4205/*
    4206 * LP Pricing Norms Methods
    4207 */
    4208
    4209/**@name LP Pricing Norms Methods */
    4210/**@{ */
    4211
    4212/** stores LPi pricing norms information
    4213 *
    4214 * @todo store primal norms as well?
    4215 */
    4217 SCIP_LPI* lpi, /**< LP interface structure */
    4218 BMS_BLKMEM* blkmem, /**< block memory */
    4219 SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information */
    4220 )
    4221{
    4222 int nrows;
    4223 int retval;
    4224
    4225 assert(blkmem != NULL);
    4226 assert(lpi != NULL);
    4227 assert(lpi->cpxlp != NULL);
    4228 assert(lpi->cpxenv != NULL);
    4229 assert(lpi->messagehdlr != NULL);
    4230 assert(lpinorms != NULL);
    4231
    4232 /* if there is no basis information available (e.g. after barrier without crossover), norms cannot be saved; if
    4233 * SCIPlpiClearState() has been called, do not return the state
    4234 */
    4235 if( !lpi->solisbasic || lpi->clearstate )
    4236 {
    4237 *lpinorms = NULL;
    4238 return SCIP_OKAY;
    4239 }
    4240
    4241 nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
    4242 assert(nrows >= 0);
    4243
    4244 /* allocate lpinorms data */
    4245 SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpinorms) );
    4246 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpinorms)->norm, nrows) );
    4247 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpinorms)->head, nrows) );
    4248 (*lpinorms)->normlen = 0;
    4249
    4250 SCIPdebugMessage("storing CPLEX LPI pricing norms in %p (%d rows)\n", (void *) *lpinorms, nrows);
    4251
    4252 /* get dual norms */
    4253 retval = CPXgetdnorms(lpi->cpxenv, lpi->cpxlp, (*lpinorms)->norm, (*lpinorms)->head, &((*lpinorms)->normlen));
    4254
    4255 /* if CPLEX used the primal simplex in the last optimization call, we do not have dual norms (error 1264) */
    4256 if( retval == 1264 )
    4257 {
    4258 /* no norms available, free lpinorms data */
    4259 BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->head, nrows);
    4260 BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->norm, nrows);
    4261 BMSfreeBlockMemory(blkmem, lpinorms);
    4262 assert(*lpinorms == NULL);
    4263 }
    4264 else
    4265 {
    4266 assert((*lpinorms)->normlen == nrows);
    4267 CHECK_ZERO( lpi->messagehdlr, retval );
    4268 }
    4269
    4270 return SCIP_OKAY;
    4271}
    4272
    4273/** loads LPi pricing norms into solver; note that the LP might have been extended with additional
    4274 * columns and rows since the state was stored with SCIPlpiGetNorms()
    4275 */
    4277 SCIP_LPI* lpi, /**< LP interface structure */
    4278 BMS_BLKMEM* blkmem, /**< block memory */
    4279 const SCIP_LPINORMS* lpinorms /**< LPi pricing norms information, or NULL */
    4280 )
    4281{
    4282 int lpnrows;
    4283
    4284 assert(blkmem != NULL);
    4285 assert(lpi != NULL);
    4286 assert(lpi->cpxlp != NULL);
    4287 assert(lpi->cpxenv != NULL);
    4288
    4289 /* if there was no pricing norms information available, the LPI norms were not stored */
    4290 if( lpinorms == NULL )
    4291 return SCIP_OKAY;
    4292
    4293 lpnrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
    4294 assert(lpinorms->normlen <= lpnrows);
    4295
    4296 SCIPdebugMessage("loading LPI simplex norms %p (%d rows) into CPLEX LP with %d rows\n",
    4297 (void *) lpinorms, lpinorms->normlen, lpnrows);
    4298
    4299 if( lpinorms->normlen == 0 )
    4300 return SCIP_OKAY;
    4301
    4302 /* load pricing norms information into CPLEX */
    4303 CHECK_ZERO( lpi->messagehdlr, CPXcopydnorms(lpi->cpxenv, lpi->cpxlp, lpinorms->norm, lpinorms->head, lpinorms->normlen) );
    4304
    4305 return SCIP_OKAY;
    4306}
    4307
    4308/** frees pricing norms information */
    4310 SCIP_LPI* lpi, /**< LP interface structure */
    4311 BMS_BLKMEM* blkmem, /**< block memory */
    4312 SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information, or NULL */
    4313 )
    4314{
    4315 assert(lpi != NULL);
    4316 assert(lpinorms != NULL);
    4317
    4318 BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->head, (*lpinorms)->normlen);
    4319 BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->norm, (*lpinorms)->normlen);
    4320 BMSfreeBlockMemory(blkmem, lpinorms);
    4321
    4322 return SCIP_OKAY;
    4323}
    4324
    4325/**@} */
    4326
    4327
    4328
    4329
    4330/*
    4331 * Parameter Methods
    4332 */
    4333
    4334/**@name Parameter Methods */
    4335/**@{ */
    4336
    4337/** gets integer parameter of LP
    4338 *
    4339 * CPLEX supported FASTMIP in versions up to 12.6.1. FASTMIP fastens the lp solving process but therefor it might happen
    4340 * that there will be a loss in precision (because e.g. the optimal basis will not be factorized again).
    4341 */
    4343 SCIP_LPI* lpi, /**< LP interface structure */
    4344 SCIP_LPPARAM type, /**< parameter number */
    4345 int* ival /**< buffer to store the parameter value */
    4346 )
    4347{
    4348 assert(lpi != NULL);
    4349 assert(lpi->cpxlp != NULL);
    4350 assert(ival != NULL);
    4351
    4352 SCIPdebugMessage("getting int parameter %d\n", type);
    4353
    4354 switch( type )
    4355 {
    4357 *ival = (int) lpi->fromscratch;
    4358 break;
    4359#if (CPX_VERSION < 12060100)
    4360 case SCIP_LPPAR_FASTMIP:
    4361 *ival = getIntParam(lpi, CPX_PARAM_FASTMIP);
    4362 break;
    4363#endif
    4364 case SCIP_LPPAR_SCALING:
    4365#if (CPX_VERSION <= 1100)
    4366 if( lpi->rngfound )
    4367 return SCIP_PARAMETERUNKNOWN;
    4368#endif
    4369 *ival = getIntParam(lpi, CPX_PARAM_SCAIND) + 1;
    4370 break;
    4372 *ival = (getIntParam(lpi, CPX_PARAM_PREIND) == CPX_ON);
    4373 break;
    4374 case SCIP_LPPAR_PRICING:
    4375 *ival = (int)lpi->pricing; /* store pricing method in LPI struct */
    4376 break;
    4377 case SCIP_LPPAR_LPINFO:
    4378 *ival = (getIntParam(lpi, CPX_PARAM_SCRIND) == CPX_ON);
    4379 break;
    4380 case SCIP_LPPAR_LPITLIM:
    4381 *ival = getIntParam(lpi, CPX_PARAM_ITLIM);
    4382#if (CPX_VERSION <= 1230)
    4383 if( *ival >= CPX_INT_MAX )
    4384 *ival = INT_MAX;
    4385#endif
    4386 break;
    4387 case SCIP_LPPAR_THREADS:
    4388#if (CPX_VERSION == 1100 || (CPX_VERSION == 1220 && (CPX_SUBVERSION == 0 || CPX_SUBVERSION == 2)))
    4389 /* Due to CPLEX bug, we always set the thread count to 1. In order to fulfill an assert in lp.c, we have to
    4390 * return the value set by SCIP and not the real thread count */
    4391 *ival = lpi->pseudonthreads;
    4392 assert(getIntParam(lpi, CPX_PARAM_THREADS) == 1);
    4393#else
    4394 *ival = getIntParam(lpi, CPX_PARAM_THREADS);
    4395#endif
    4396 break;
    4397 default:
    4398 return SCIP_PARAMETERUNKNOWN;
    4399 } /*lint !e788*/
    4400
    4401 return SCIP_OKAY;
    4402}
    4403
    4404/** sets integer parameter of LP */
    4406 SCIP_LPI* lpi, /**< LP interface structure */
    4407 SCIP_LPPARAM type, /**< parameter number */
    4408 int ival /**< parameter value */
    4409 )
    4410{
    4411 assert(lpi != NULL);
    4412 assert(lpi->cpxlp != NULL);
    4413
    4414 SCIPdebugMessage("setting int parameter %d to %d\n", type, ival);
    4415
    4416 switch( type )
    4417 {
    4419 assert(ival == TRUE || ival == FALSE);
    4420 lpi->fromscratch = (SCIP_Bool) ival;
    4421 break;
    4422#if (CPX_VERSION < 12060100)
    4423 case SCIP_LPPAR_FASTMIP:
    4424 assert(0 <= ival && ival <= 1);
    4425 setIntParam(lpi, CPX_PARAM_FASTMIP, ival);
    4426 break;
    4427#endif
    4428 case SCIP_LPPAR_SCALING:
    4429 assert(0 <= ival && ival <= 2);
    4430#if (CPX_VERSION <= 1100)
    4431 if( lpi->rngfound )
    4432 return SCIP_PARAMETERUNKNOWN;
    4433#endif
    4434 setIntParam(lpi, CPX_PARAM_SCAIND, ival - 1);
    4435 break;
    4437 assert(ival == TRUE || ival == FALSE);
    4438 setIntParam(lpi, CPX_PARAM_PREIND, ival == TRUE ? CPX_ON : CPX_OFF);
    4439 break;
    4440 case SCIP_LPPAR_PRICING:
    4441 lpi->pricing = (SCIP_PRICING)ival;
    4442 switch( (SCIP_PRICING)ival )
    4443 {
    4444 case SCIP_PRICING_AUTO:
    4445 setIntParam(lpi, CPX_PARAM_PPRIIND, CPX_PPRIIND_AUTO);
    4446 setIntParam(lpi, CPX_PARAM_DPRIIND, CPX_DPRIIND_AUTO);
    4447 break;
    4448 case SCIP_PRICING_FULL:
    4449 setIntParam(lpi, CPX_PARAM_PPRIIND, CPX_PPRIIND_FULL);
    4450 setIntParam(lpi, CPX_PARAM_DPRIIND, CPX_DPRIIND_FULL);
    4451 break;
    4453 setIntParam(lpi, CPX_PARAM_PPRIIND, CPX_PPRIIND_PARTIAL);
    4454 setIntParam(lpi, CPX_PARAM_DPRIIND, CPX_DPRIIND_AUTO);
    4455 break;
    4457 case SCIP_PRICING_STEEP:
    4458 setIntParam(lpi, CPX_PARAM_PPRIIND, CPX_PPRIIND_STEEP);
    4459 setIntParam(lpi, CPX_PARAM_DPRIIND, CPX_DPRIIND_STEEP);
    4460 break;
    4462 setIntParam(lpi, CPX_PARAM_PPRIIND, CPX_PPRIIND_STEEPQSTART);
    4463 setIntParam(lpi, CPX_PARAM_DPRIIND, CPX_DPRIIND_STEEPQSTART);
    4464 break;
    4465#if (CPX_VERSION >= 900)
    4466 case SCIP_PRICING_DEVEX:
    4467 setIntParam(lpi, CPX_PARAM_PPRIIND, CPX_PPRIIND_DEVEX);
    4468 setIntParam(lpi, CPX_PARAM_DPRIIND, CPX_DPRIIND_DEVEX);
    4469 break;
    4470#endif
    4471 default:
    4472 return SCIP_LPERROR;
    4473 }
    4474 break;
    4475 case SCIP_LPPAR_LPINFO:
    4476 assert(ival == TRUE || ival == FALSE);
    4477 if( ival )
    4478 setIntParam(lpi, CPX_PARAM_SCRIND, CPX_ON);
    4479 else
    4480 setIntParam(lpi, CPX_PARAM_SCRIND, CPX_OFF);
    4481 break;
    4482 case SCIP_LPPAR_LPITLIM:
    4483 assert( ival >= 0 );
    4484 /* 0 <= ival, 0 stopping immediately */
    4485#if (CPX_VERSION <= 1230)
    4486 ival = MIN(ival, CPX_INT_MAX);
    4487#endif
    4488 setIntParam(lpi, CPX_PARAM_ITLIM, ival);
    4489 break;
    4490 case SCIP_LPPAR_THREADS:
    4491#if (CPX_VERSION == 1100 || (CPX_VERSION == 1220 && (CPX_SUBVERSION == 0 || CPX_SUBVERSION == 2)))
    4492 /* Due to CPLEX bug, we always set the thread count to 1. In order to fulfill an assert in lp.c, we have to
    4493 * store the value set by SCIP and return it later instead of the real thread count */
    4494 lpi->pseudonthreads = ival;
    4495 ival = 1;
    4496#else
    4497 ival = MIN(ival, CPX_INT_MAX);
    4498#endif
    4499 setIntParam(lpi, CPX_PARAM_THREADS, ival);
    4500 break;
    4502 setIntParam(lpi, CPX_PARAM_RANDOMSEED, ival % CPX_INT_MAX);
    4503 break;
    4504 default:
    4505 return SCIP_PARAMETERUNKNOWN;
    4506 } /*lint !e788*/
    4507
    4508 return SCIP_OKAY;
    4509}
    4510
    4511/** gets floating point parameter of LP */
    4513 SCIP_LPI* lpi, /**< LP interface structure */
    4514 SCIP_LPPARAM type, /**< parameter number */
    4515 SCIP_Real* dval /**< buffer to store the parameter value */
    4516 )
    4517{
    4518 assert(lpi != NULL);
    4519 assert(lpi->cpxlp != NULL);
    4520 assert(dval != NULL);
    4521
    4522 SCIPdebugMessage("getting real parameter %d\n", type);
    4523
    4524 switch( type )
    4525 {
    4526 case SCIP_LPPAR_FEASTOL:
    4527 *dval = getDblParam(lpi, CPX_PARAM_EPRHS);
    4528 break;
    4530 *dval = getDblParam(lpi, CPX_PARAM_EPOPT);
    4531 break;
    4533 *dval = getDblParam(lpi, CPX_PARAM_BAREPCOMP);
    4534 break;
    4535 case SCIP_LPPAR_OBJLIM:
    4536 if ( CPXgetobjsen(lpi->cpxenv, lpi->cpxlp) == CPX_MIN )
    4537 *dval = getDblParam(lpi, CPX_PARAM_OBJULIM);
    4538 else
    4539 *dval = getDblParam(lpi, CPX_PARAM_OBJLLIM);
    4540 break;
    4541 case SCIP_LPPAR_LPTILIM:
    4542 *dval = getDblParam(lpi, CPX_PARAM_TILIM);
    4543 break;
    4545 *dval = getDblParam(lpi, CPX_PARAM_EPMRK);
    4546 break;
    4548 *dval = lpi->conditionlimit;
    4549 break;
    4550 default:
    4551 return SCIP_PARAMETERUNKNOWN;
    4552 } /*lint !e788*/
    4553
    4554 return SCIP_OKAY;
    4555}
    4556
    4557/** sets floating point parameter of LP */
    4559 SCIP_LPI* lpi, /**< LP interface structure */
    4560 SCIP_LPPARAM type, /**< parameter number */
    4561 SCIP_Real dval /**< parameter value */
    4562 )
    4563{
    4564 assert(lpi != NULL);
    4565 assert(lpi->cpxlp != NULL);
    4566
    4567 SCIPdebugMessage("setting real parameter %d to %.15g\n", type, dval);
    4568
    4569 switch( type )
    4570 {
    4571 case SCIP_LPPAR_FEASTOL:
    4572 assert( dval > 0.0 );
    4573 /* 1e-09 <= dval <= 1e-01 */
    4574 if( dval < 1e-09 )
    4575 dval = 1e-09;
    4576 else if( dval > 1e-01 )
    4577 dval = 1e-01;
    4578
    4579 setDblParam(lpi, CPX_PARAM_EPRHS, dval);
    4580 lpi->feastol = dval;
    4581 break;
    4583 assert( dval > 0.0 );
    4584 /* 1e-09 <= dval <= 1e-01 */
    4585 if( dval < 1e-09 )
    4586 dval = 1e-09;
    4587 else if( dval > 1e-01 )
    4588 dval = 1e-01;
    4589
    4590 setDblParam(lpi, CPX_PARAM_EPOPT, dval);
    4591 break;
    4593 /* 1e-12 <= dval */
    4594 assert( dval >= 0.0 );
    4595 if( dval < 1e-12 )
    4596 dval = 1e-12;
    4597
    4598 setDblParam(lpi, CPX_PARAM_BAREPCOMP, dval);
    4599 break;
    4600 case SCIP_LPPAR_OBJLIM:
    4601 /* Cplex poses no restriction on dval */
    4602 if ( CPXgetobjsen(lpi->cpxenv, lpi->cpxlp) == CPX_MIN )
    4603 setDblParam(lpi, CPX_PARAM_OBJULIM, dval);
    4604 else
    4605 setDblParam(lpi, CPX_PARAM_OBJLLIM, dval);
    4606 break;
    4607 case SCIP_LPPAR_LPTILIM:
    4608 assert( dval > 0.0 );
    4609 /* Cplex requires dval non-negative
    4610 *
    4611 * However for consistency we assert the timelimit to be strictly positive.
    4612 */
    4613 setDblParam(lpi, CPX_PARAM_TILIM, dval);
    4614 break;
    4616 /* 1e-04 <= dval <= .99999 */
    4617 if( dval < 1e-04 )
    4618 dval = 1e-04;
    4619 else if( dval > .99999 )
    4620 dval = .99999;
    4621
    4622 setDblParam(lpi, CPX_PARAM_EPMRK, dval);
    4623 break;
    4625 lpi->conditionlimit = dval;
    4626 lpi->checkcondition = (dval >= 0);
    4627 break;
    4628 default:
    4629 return SCIP_PARAMETERUNKNOWN;
    4630 } /*lint !e788*/
    4631
    4632 return SCIP_OKAY;
    4633}
    4634
    4635/** interrupts the currently ongoing lp solve or disables the interrupt */ /*lint -e{715}*/
    4637 SCIP_LPI* lpi, /**< LP interface structure */
    4638 SCIP_Bool interrupt /**< TRUE if interrupt should be set, FALSE if it should be disabled */
    4639 )
    4640{ /*lint --e{715}*/
    4641 assert(lpi != NULL);
    4642
    4643 return SCIP_OKAY;
    4644}
    4645
    4646/**@} */
    4647
    4648
    4649
    4650
    4651/*
    4652 * Numerical Methods
    4653 */
    4654
    4655/**@name Numerical Methods */
    4656/**@{ */
    4657
    4658/** returns value treated as infinity in the LP solver */
    4660 SCIP_LPI* lpi /**< LP interface structure */
    4661 )
    4662{ /*lint --e{715}*/
    4663 assert(lpi != NULL);
    4664 return CPX_INFBOUND;
    4665}
    4666
    4667/** checks if given value is treated as infinity in the LP solver */
    4669 SCIP_LPI* lpi, /**< LP interface structure */
    4670 SCIP_Real val /**< value to be checked for infinity */
    4671 )
    4672{ /*lint --e{715}*/
    4673 assert(lpi != NULL);
    4674 return (val >= CPX_INFBOUND);
    4675}
    4676
    4677/**@} */
    4678
    4679
    4680
    4681
    4682/*
    4683 * File Interface Methods
    4684 */
    4685
    4686/**@name File Interface Methods */
    4687/**@{ */
    4688
    4689/** reads LP from a file */
    4691 SCIP_LPI* lpi, /**< LP interface structure */
    4692 const char* fname /**< file name */
    4693 )
    4694{
    4695 int restat;
    4696
    4697 assert(lpi != NULL);
    4698 assert(lpi->cpxlp != NULL);
    4699 assert(lpi->cpxenv != NULL);
    4700 assert(fname != NULL);
    4701
    4702 SCIPdebugMessage("reading LP from file <%s>\n", fname);
    4703
    4704 restat = CPXreadcopyprob(lpi->cpxenv, lpi->cpxlp, fname, NULL);
    4705 if( restat != 0 )
    4706 {
    4707 SCIPerrorMessage("LP Error: CPLEX returned %d\n", restat);
    4708 return SCIP_READERROR;
    4709 }
    4710
    4711 return SCIP_OKAY;
    4712}
    4713
    4714/** writes LP to a file */
    4716 SCIP_LPI* lpi, /**< LP interface structure */
    4717 const char* fname /**< file name */
    4718 )
    4719{
    4720 int restat;
    4721
    4722 assert(lpi != NULL);
    4723 assert(lpi->cpxlp != NULL);
    4724 assert(lpi->cpxenv != NULL);
    4725 assert(fname != NULL);
    4726
    4727 SCIPdebugMessage("writing LP to file <%s>\n", fname);
    4728
    4729 restat = CPXwriteprob(lpi->cpxenv, lpi->cpxlp, fname, NULL);
    4730 if( restat != 0 )
    4731 {
    4732 SCIPerrorMessage("LP Error: CPLEX returned %d\n", restat);
    4733 return SCIP_READERROR;
    4734 }
    4735
    4736 return SCIP_OKAY;
    4737}
    4738
    4739/**@} */
    void SCIPdecodeDualBit(const SCIP_DUALPACKET *inp, int *out, int count)
    Definition: bitencode.c:308
    void SCIPencodeDualBit(const int *inp, SCIP_DUALPACKET *out, int count)
    Definition: bitencode.c:238
    packing single and dual bit values
    unsigned int SCIP_DUALPACKET
    Definition: bitencode.h:42
    SCIP_Real * r
    Definition: circlepacking.c:59
    #define NULL
    Definition: def.h:248
    #define EPSISINT(x, eps)
    Definition: def.h:195
    #define SCIP_INVALID
    Definition: def.h:178
    #define SCIP_Bool
    Definition: def.h:91
    #define SCIP_CALL_QUIET(x)
    Definition: def.h:330
    #define MIN(x, y)
    Definition: def.h:224
    #define SCIP_ALLOC(x)
    Definition: def.h:366
    #define SCIP_Real
    Definition: def.h:156
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define MAX(x, y)
    Definition: def.h:220
    #define EPSCEIL(x, eps)
    Definition: def.h:192
    #define SCIPABORT()
    Definition: def.h:327
    #define EPSFLOOR(x, eps)
    Definition: def.h:191
    #define REALABS(x)
    Definition: def.h:182
    #define EPSZ(x, eps)
    Definition: def.h:188
    #define SCIP_CALL(x)
    Definition: def.h:355
    SCIP_RETCODE SCIPlpiChgSides(SCIP_LPI *lpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
    Definition: lpi_cpx.c:1630
    SCIP_RETCODE SCIPlpiSetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPISTATE *lpistate)
    Definition: lpi_cpx.c:4059
    SCIP_RETCODE SCIPlpiGetBInvACol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
    Definition: lpi_cpx.c:3934
    SCIP_RETCODE SCIPlpiGetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
    Definition: lpi_cpx.c:4512
    SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
    Definition: lpi_cpx.c:4659
    SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
    Definition: lpi_cpx.c:3333
    SCIP_RETCODE SCIPlpiChgObjsen(SCIP_LPI *lpi, SCIP_OBJSEN objsen)
    Definition: lpi_cpx.c:1699
    SCIP_Bool SCIPlpiIsInfinity(SCIP_LPI *lpi, SCIP_Real val)
    Definition: lpi_cpx.c:4668
    SCIP_RETCODE SCIPlpiClear(SCIP_LPI *lpi)
    Definition: lpi_cpx.c:1537
    SCIP_RETCODE SCIPlpiClearState(SCIP_LPI *lpi)
    Definition: lpi_cpx.c:4123
    SCIP_Bool SCIPlpiExistsDualRay(SCIP_LPI *lpi)
    Definition: lpi_cpx.c:3174
    SCIP_Bool SCIPlpiExistsPrimalRay(SCIP_LPI *lpi)
    Definition: lpi_cpx.c:3082
    SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
    Definition: lpi_cpx.c:3586
    SCIP_RETCODE SCIPlpiReadState(SCIP_LPI *lpi, const char *fname)
    Definition: lpi_cpx.c:4165
    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_cpx.c:1420
    SCIP_RETCODE SCIPlpiGetPrimalRay(SCIP_LPI *lpi, SCIP_Real *ray)
    Definition: lpi_cpx.c:3471
    SCIP_RETCODE SCIPlpiGetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int *ival)
    Definition: lpi_cpx.c:4342
    SCIP_RETCODE SCIPlpiWriteLP(SCIP_LPI *lpi, const char *fname)
    Definition: lpi_cpx.c:4715
    SCIP_RETCODE SCIPlpiSetIntegralityInformation(SCIP_LPI *lpi, int ncols, int *intInfo)
    Definition: lpi_cpx.c:1060
    SCIP_Bool SCIPlpiIsDualInfeasible(SCIP_LPI *lpi)
    Definition: lpi_cpx.c:3220
    SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
    Definition: lpi_cpx.c:4558
    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_cpx.c:2817
    SCIP_RETCODE SCIPlpiSetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPINORMS *lpinorms)
    Definition: lpi_cpx.c:4276
    SCIP_RETCODE SCIPlpiGetNNonz(SCIP_LPI *lpi, int *nnonz)
    Definition: lpi_cpx.c:1909
    SCIP_Bool SCIPlpiHasPrimalSolve(void)
    Definition: lpi_cpx.c:1075
    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_cpx.c:2947
    SCIP_RETCODE SCIPlpiGetBounds(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lbs, SCIP_Real *ubs)
    Definition: lpi_cpx.c:2152
    SCIP_Bool SCIPlpiHasBarrierSolve(void)
    Definition: lpi_cpx.c:1091
    SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
    Definition: lpi_cpx.c:3491
    SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
    Definition: lpi_cpx.c:3407
    SCIP_RETCODE SCIPlpiScaleCol(SCIP_LPI *lpi, int col, SCIP_Real scaleval)
    Definition: lpi_cpx.c:1801
    int SCIPlpiGetInternalStatus(SCIP_LPI *lpi)
    Definition: lpi_cpx.c:3373
    SCIP_RETCODE SCIPlpiStartStrongbranch(SCIP_LPI *lpi)
    Definition: lpi_cpx.c:2791
    SCIP_RETCODE SCIPlpiGetSolFeasibility(SCIP_LPI *lpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
    Definition: lpi_cpx.c:3055
    SCIP_RETCODE SCIPlpiFreeNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
    Definition: lpi_cpx.c:4309
    SCIP_Bool SCIPlpiIsIterlimExc(SCIP_LPI *lpi)
    Definition: lpi_cpx.c:3351
    SCIP_RETCODE SCIPlpiChgBounds(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
    Definition: lpi_cpx.c:1567
    SCIP_Bool SCIPlpiIsPrimalUnbounded(SCIP_LPI *lpi)
    Definition: lpi_cpx.c:3109
    SCIP_RETCODE SCIPlpiIgnoreInstability(SCIP_LPI *lpi, SCIP_Bool *success)
    Definition: lpi_cpx.c:3384
    SCIP_RETCODE SCIPlpiWriteState(SCIP_LPI *lpi, const char *fname)
    Definition: lpi_cpx.c:4183
    SCIP_RETCODE SCIPlpiFree(SCIP_LPI **lpi)
    Definition: lpi_cpx.c:1196
    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_cpx.c:2881
    SCIP_RETCODE SCIPlpiGetCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real *val)
    Definition: lpi_cpx.c:2227
    SCIP_Bool SCIPlpiIsPrimalFeasible(SCIP_LPI *lpi)
    Definition: lpi_cpx.c:3153
    SCIP_RETCODE SCIPlpiReadLP(SCIP_LPI *lpi, const char *fname)
    Definition: lpi_cpx.c:4690
    SCIP_RETCODE SCIPlpiGetRealSolQuality(SCIP_LPI *lpi, SCIP_LPSOLQUALITY qualityindicator, SCIP_Real *quality)
    Definition: lpi_cpx.c:3529
    SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
    Definition: lpi_cpx.c:3242
    SCIP_RETCODE SCIPlpiGetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
    Definition: lpi_cpx.c:4216
    SCIP_Bool SCIPlpiIsTimelimExc(SCIP_LPI *lpi)
    Definition: lpi_cpx.c:3362
    SCIP_Bool SCIPlpiHasStateBasis(SCIP_LPI *lpi, SCIP_LPISTATE *lpistate)
    Definition: lpi_cpx.c:4155
    SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
    Definition: lpi_cpx.c:4405
    const char * SCIPlpiGetSolverName(void)
    Definition: lpi_cpx.c:1033
    SCIP_RETCODE SCIPlpiSetBase(SCIP_LPI *lpi, const int *cstat, const int *rstat)
    Definition: lpi_cpx.c:3626
    SCIP_Bool SCIPlpiHasPrimalRay(SCIP_LPI *lpi)
    Definition: lpi_cpx.c:3096
    SCIP_RETCODE SCIPlpiGetBInvRow(SCIP_LPI *lpi, int r, SCIP_Real *coef, int *inds, int *ninds)
    Definition: lpi_cpx.c:3713
    SCIP_RETCODE SCIPlpiDelRows(SCIP_LPI *lpi, int firstrow, int lastrow)
    Definition: lpi_cpx.c:1489
    SCIP_RETCODE SCIPlpiGetCols(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lb, SCIP_Real *ub, int *nnonz, int *beg, int *ind, SCIP_Real *val)
    Definition: lpi_cpx.c:1929
    SCIP_RETCODE SCIPlpiGetBInvCol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
    Definition: lpi_cpx.c:3785
    SCIP_RETCODE SCIPlpiGetColNames(SCIP_LPI *lpi, int firstcol, int lastcol, char **colnames, char *namestorage, int namestoragesize, int *storageleft)
    Definition: lpi_cpx.c:2038
    static SCIP_RETCODE lpiStrongbranchIntegral(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_cpx.c:2685
    SCIP_RETCODE SCIPlpiGetBInvARow(SCIP_LPI *lpi, int r, const SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
    Definition: lpi_cpx.c:3859
    SCIP_RETCODE SCIPlpiGetRows(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhs, SCIP_Real *rhs, int *nnonz, int *beg, int *ind, SCIP_Real *val)
    Definition: lpi_cpx.c:1975
    SCIP_Bool SCIPlpiWasSolved(SCIP_LPI *lpi)
    Definition: lpi_cpx.c:3034
    const char * SCIPlpiGetSolverDesc(void)
    Definition: lpi_cpx.c:1041
    SCIP_RETCODE SCIPlpiSolveBarrier(SCIP_LPI *lpi, SCIP_Bool crossover)
    Definition: lpi_cpx.c:2594
    SCIP_Bool SCIPlpiIsOptimal(SCIP_LPI *lpi)
    Definition: lpi_cpx.c:3261
    SCIP_RETCODE SCIPlpiGetRowNames(SCIP_LPI *lpi, int firstrow, int lastrow, char **rownames, char *namestorage, int namestoragesize, int *storageleft)
    Definition: lpi_cpx.c:2074
    SCIP_Bool SCIPlpiHasDualSolve(void)
    Definition: lpi_cpx.c:1083
    SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
    Definition: lpi_cpx.c:2804
    SCIP_RETCODE SCIPlpiGetSides(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhss, SCIP_Real *rhss)
    Definition: lpi_cpx.c:2183
    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_cpx.c:2981
    SCIP_RETCODE SCIPlpiGetSol(SCIP_LPI *lpi, SCIP_Real *objval, SCIP_Real *primsol, SCIP_Real *dualsol, SCIP_Real *activity, SCIP_Real *redcost)
    Definition: lpi_cpx.c:3441
    SCIP_Bool SCIPlpiHasDualRay(SCIP_LPI *lpi)
    Definition: lpi_cpx.c:3187
    SCIP_RETCODE SCIPlpiDelColset(SCIP_LPI *lpi, int *dstat)
    Definition: lpi_cpx.c:1398
    SCIP_RETCODE SCIPlpiGetObj(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *vals)
    Definition: lpi_cpx.c:2129
    SCIP_RETCODE SCIPlpiFreeState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
    Definition: lpi_cpx.c:4136
    SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
    Definition: lpi_cpx.c:3133
    SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
    Definition: lpi_cpx.c:2405
    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_cpx.c:1316
    SCIP_RETCODE SCIPlpiSolvePrimal(SCIP_LPI *lpi)
    Definition: lpi_cpx.c:2259
    SCIP_RETCODE SCIPlpiLoadColLP(SCIP_LPI *lpi, SCIP_OBJSEN objsen, int ncols, const SCIP_Real *obj, const SCIP_Real *lb, const SCIP_Real *ub, char **colnames, 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_cpx.c:1242
    SCIP_Bool SCIPlpiIsDualUnbounded(SCIP_LPI *lpi)
    Definition: lpi_cpx.c:3200
    SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
    Definition: lpi_cpx.c:3511
    SCIP_RETCODE SCIPlpiGetBasisInd(SCIP_LPI *lpi, int *bind)
    Definition: lpi_cpx.c:3678
    SCIP_RETCODE SCIPlpiCreate(SCIP_LPI **lpi, SCIP_MESSAGEHDLR *messagehdlr, const char *name, SCIP_OBJSEN objsen)
    Definition: lpi_cpx.c:1111
    void * SCIPlpiGetSolverPointer(SCIP_LPI *lpi)
    Definition: lpi_cpx.c:1052
    SCIP_RETCODE SCIPlpiChgObj(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *obj)
    Definition: lpi_cpx.c:1722
    SCIP_RETCODE SCIPlpiGetObjsen(SCIP_LPI *lpi, SCIP_OBJSEN *objsen)
    Definition: lpi_cpx.c:2110
    SCIP_Bool SCIPlpiIsStable(SCIP_LPI *lpi)
    Definition: lpi_cpx.c:3278
    SCIP_RETCODE SCIPlpiGetNCols(SCIP_LPI *lpi, int *ncols)
    Definition: lpi_cpx.c:1892
    SCIP_RETCODE SCIPlpiInterrupt(SCIP_LPI *lpi, SCIP_Bool interrupt)
    Definition: lpi_cpx.c:4636
    SCIP_RETCODE SCIPlpiDelCols(SCIP_LPI *lpi, int firstcol, int lastcol)
    Definition: lpi_cpx.c:1371
    SCIP_RETCODE SCIPlpiDelRowset(SCIP_LPI *lpi, int *dstat)
    Definition: lpi_cpx.c:1516
    SCIP_RETCODE SCIPlpiScaleRow(SCIP_LPI *lpi, int row, SCIP_Real scaleval)
    Definition: lpi_cpx.c:1745
    SCIP_RETCODE SCIPlpiGetNRows(SCIP_LPI *lpi, int *nrows)
    Definition: lpi_cpx.c:1875
    SCIP_RETCODE SCIPlpiGetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
    Definition: lpi_cpx.c:4011
    SCIP_RETCODE SCIPlpiChgCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real newval)
    Definition: lpi_cpx.c:1678
    interface methods for specific LP solvers
    SCIP_DUALPACKET ROWPACKET
    Definition: lpi_clp.cpp:128
    SCIP_DUALPACKET COLPACKET
    Definition: lpi_clp.cpp:126
    static SCIP_RETCODE setBase(SCIP_LPI *lpi)
    Definition: lpi_cpx.c:360
    static void reconvertSides(SCIP_LPI *lpi, int nrows, SCIP_Real *lhs, SCIP_Real *rhs)
    Definition: lpi_cpx.c:957
    static void lpistatePack(SCIP_LPISTATE *lpistate, const int *cstat, const int *rstat)
    Definition: lpi_cpx.c:408
    static void lpistateUnpack(const SCIP_LPISTATE *lpistate, int *cstat, int *rstat)
    Definition: lpi_cpx.c:424
    static int rowpacketNum(int nrows)
    Definition: lpi_cpx.c:399
    static void invalidateSolution(SCIP_LPI *const lpi)
    Definition: lpi_cpx.c:709
    SCIP_DUALPACKET ROWPACKET
    Definition: lpi_cpx.c:85
    #define CPX_SUBVERSION
    Definition: lpi_cpx.c:46
    static SCIP_RETCODE ensureCstatMem(SCIP_LPI *lpi, int num)
    Definition: lpi_cpx.c:289
    static SCIP_RETCODE setParameterValues(SCIP_LPI *const lpi, SCIP_CPXPARAM *const cpxparam)
    Definition: lpi_cpx.c:539
    static void convertSides(SCIP_LPI *lpi, int nrows, const SCIP_Real *lhs, const SCIP_Real *rhs, int indoffset, int *rngcount)
    Definition: lpi_cpx.c:740
    static SCIP_RETCODE checkParameterValues(SCIP_LPI *const lpi)
    Definition: lpi_cpx.c:509
    #define CPX_INT_MAX
    Definition: lpi_cpx.c:72
    #define COLS_PER_PACKET
    Definition: lpi_cpx.c:84
    static int getIntParam(SCIP_LPI *lpi, int const param)
    Definition: lpi_cpx.c:601
    static void setDblParam(SCIP_LPI *lpi, int const param, double parval)
    Definition: lpi_cpx.c:679
    static SCIP_RETCODE ensureBoundchgMem(SCIP_LPI *lpi, int num)
    Definition: lpi_cpx.c:212
    static const char cpxname[]
    Definition: lpi_cpx.c:1013
    static void lpistateFree(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem)
    Definition: lpi_cpx.c:461
    static void setIntParam(SCIP_LPI *lpi, int const param, int const parval)
    Definition: lpi_cpx.c:654
    static const int intparam[NUMINTPARAM]
    Definition: lpi_cpx.c:94
    static SCIP_RETCODE getBase(SCIP_LPI *lpi)
    Definition: lpi_cpx.c:333
    SCIP_DUALPACKET COLPACKET
    Definition: lpi_cpx.c:83
    static SCIP_RETCODE getParameterValues(SCIP_LPI *lpi, SCIP_CPXPARAM *cpxparam)
    Definition: lpi_cpx.c:483
    static SCIP_RETCODE restoreLPData(SCIP_LPI *lpi)
    Definition: lpi_cpx.c:975
    static int cpxObjsen(SCIP_OBJSEN const objsen)
    Definition: lpi_cpx.c:721
    #define CHECK_ZERO(messagehdlr, x)
    Definition: lpi_cpx.c:54
    static const double dblparammin[NUMDBLPARAM]
    Definition: lpi_cpx.c:123
    static void reconvertBothSides(SCIP_LPI *lpi, int nrows, SCIP_Real *lhs, SCIP_Real *rhs)
    Definition: lpi_cpx.c:804
    #define NUMINTPARAM
    Definition: lpi_cpx.c:90
    static SCIP_RETCODE ensureRstatMem(SCIP_LPI *lpi, int num)
    Definition: lpi_cpx.c:311
    static int colpacketNum(int ncols)
    Definition: lpi_cpx.c:390
    static SCIP_RETCODE ensureSidechgMem(SCIP_LPI *lpi, int num)
    Definition: lpi_cpx.c:241
    static void copyParameterValues(SCIP_CPXPARAM *dest, SCIP_CPXPARAM *const source)
    Definition: lpi_cpx.c:586
    #define ABORT_ZERO(x)
    Definition: lpi_cpx.c:63
    #define CPX_REFACTORMAXITERS
    Definition: lpi_cpx.c:77
    static const int dblparam[NUMDBLPARAM]
    Definition: lpi_cpx.c:112
    static void reconvertLhs(SCIP_LPI *lpi, int nrows, SCIP_Real *lhs)
    Definition: lpi_cpx.c:861
    #define NUMDBLPARAM
    Definition: lpi_cpx.c:111
    static void reconvertRhs(SCIP_LPI *lpi, int nrows, SCIP_Real *rhs)
    Definition: lpi_cpx.c:909
    static double getDblParam(SCIP_LPI *lpi, int const param)
    Definition: lpi_cpx.c:623
    static SCIP_RETCODE lpistateCreate(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem, int ncols, int nrows)
    Definition: lpi_cpx.c:440
    #define ROWS_PER_PACKET
    Definition: lpi_cpx.c:86
    #define CPX_MAGICZEROCONSTANT
    Definition: lpi_cpx.c:81
    static SCIP_RETCODE ensureValMem(SCIP_LPI *lpi, int num)
    Definition: lpi_cpx.c:266
    #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 BMSallocMemoryArray(ptr, num)
    Definition: memory.h:123
    #define BMSfreeMemoryArray(ptr)
    Definition: memory.h:147
    #define BMSallocBlockMemoryArray(mem, ptr, num)
    Definition: memory.h:454
    #define BMSfreeBlockMemoryArray(mem, ptr, num)
    Definition: memory.h:467
    #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 SCIPmessagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
    Definition: message.c:427
    real eps
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    #define SCIPdebugMessage
    Definition: pub_message.h:96
    #define SCIPdebugPrintf
    Definition: pub_message.h:99
    double dblparval[NUMDBLPARAM]
    Definition: lpi_cpx.c:138
    int intparval[NUMINTPARAM]
    Definition: lpi_cpx.c:137
    double * norm
    Definition: lpi_cpx.c:201
    int * head
    Definition: lpi_cpx.c:202
    COLPACKET * packcstat
    Definition: lpi_clp.cpp:136
    ROWPACKET * packrstat
    Definition: lpi_clp.cpp:137
    SCIP_Bool clearstate
    Definition: lpi_cpx.c:172
    int iterations
    Definition: lpi_cpx.c:167
    SCIP_Real * valarray
    Definition: lpi_cpx.c:157
    int valsize
    Definition: lpi_cpx.c:164
    CPXLPptr cpxlp
    Definition: lpi_cpx.c:148
    char * uarray
    Definition: lpi_cpx.c:153
    int boundchgsize
    Definition: lpi_cpx.c:162
    SCIP_CPXPARAM curparam
    Definition: lpi_cpx.c:147
    int method
    Definition: lpi_cpx.c:150
    SCIP_Bool instabilityignored
    Definition: lpi_cpx.c:170
    int * indarray
    Definition: lpi_cpx.c:161
    SCIP_Real conditionlimit
    Definition: lpi_cpx.c:174
    int * cstat
    Definition: lpi_clp.cpp:107
    CPXENVptr cpxenv
    Definition: lpi_cpx.c:145
    SCIP_CPXPARAM cpxparam
    Definition: lpi_cpx.c:151
    SCIP_Bool solisbasic
    Definition: lpi_cpx.c:169
    int solstat
    Definition: lpi_cpx.c:149
    SCIP_Bool rngfound
    Definition: lpi_cpx.c:177
    SCIP_Bool fromscratch
    Definition: lpi_cpx.c:171
    int rstatsize
    Definition: lpi_clp.cpp:110
    SCIP_Real * rhsarray
    Definition: lpi_cpx.c:155
    int * rstat
    Definition: lpi_clp.cpp:108
    int sidechgsize
    Definition: lpi_cpx.c:163
    SCIP_PRICING pricing
    Definition: lpi_clp.cpp:112
    int cstatsize
    Definition: lpi_clp.cpp:109
    char * senarray
    Definition: lpi_cpx.c:154
    SCIP_Real feastol
    Definition: lpi_cpx.c:173
    SCIP_MESSAGEHDLR * messagehdlr
    Definition: lpi_cpx.c:185
    SCIP_Real * rngarray
    Definition: lpi_cpx.c:156
    int * rngindarray
    Definition: lpi_cpx.c:158
    char * larray
    Definition: lpi_cpx.c:152
    SCIP_Bool checkcondition
    Definition: lpi_cpx.c:175
    SCIP_CPXPARAM defparam
    Definition: lpi_cpx.c:146
    @ 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_LPSOLQUALITY_EXACTCONDITION
    Definition: type_lpi.h:102
    @ SCIP_LPSOLQUALITY_ESTIMCONDITION
    Definition: type_lpi.h:101
    @ SCIP_LPPAR_PRICING
    Definition: type_lpi.h:54
    @ SCIP_LPPAR_THREADS
    Definition: type_lpi.h:66
    @ SCIP_LPPAR_LPINFO
    Definition: type_lpi.h:55
    @ SCIP_LPPAR_SCALING
    Definition: type_lpi.h:52
    @ 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_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
    enum SCIP_LPSolQuality SCIP_LPSOLQUALITY
    Definition: type_lpi.h:104
    @ SCIP_OBJSEN_MAXIMIZE
    Definition: type_lpi.h:42
    @ SCIP_OBJSEN_MINIMIZE
    Definition: type_lpi.h:43
    enum SCIP_ObjSen SCIP_OBJSEN
    Definition: type_lpi.h:45
    @ SCIP_LPERROR
    Definition: type_retcode.h:49
    @ SCIP_READERROR
    Definition: type_retcode.h:45
    @ SCIP_INVALIDDATA
    Definition: type_retcode.h:52
    @ SCIP_PARAMETERUNKNOWN
    Definition: type_retcode.h:55
    @ SCIP_NOMEMORY
    Definition: type_retcode.h:44
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63