Scippy

    SCIP

    Solving Constraint Integer Programs

    lpi_grb.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_grb.c
    26 * @ingroup LPIS
    27 * @brief LP interface for Gurobi
    28 * @author Marc Pfetsch
    29 * @author Tobias Achterberg
    30 * @author Michael Winkler
    31 *
    32 * This LPI only works with Gurobi versions >= 7.0.2.
    33 *
    34 * @todo Try quad-precision and concurrent runs.
    35 */
    36
    37/*--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    38
    39#include <assert.h>
    40#include <string.h>
    41
    42#include "gurobi_c.h"
    43#include "lpi/lpi.h"
    44#include "scip/pub_message.h"
    45#include "scip/pub_misc_sort.h"
    46#include "tinycthread/tinycthread.h"
    47
    48#ifdef _WIN32
    49#define snprintf _snprintf
    50#endif
    51
    52#if ( GRB_VERSION_MAJOR < 6 || ( GRB_VERSION_MAJOR == 7 && GRB_VERSION_MINOR == 0 && GRB_VERSION_TECHNICAL < 2 ) )
    53#error "The Gurobi interface only works for Gurobi versions at least 7.0.2"
    54#endif
    55
    56#ifdef SCIP_THREADSAFE
    57 #if defined(_Thread_local)
    58 /* Use thread local environment in order to not create a new environment for each new LP. */
    59 static _Thread_local GRBenv* reusegrbenv = NULL; /**< thread local Gurobi environment */
    60 static _Thread_local int numlp = 0; /**< number of open LP objects */
    61 #define SCIP_REUSEENV
    62 #endif
    63#else
    64 /* Global Gurobi environment in order to not create a new environment for each new LP. This is not thread safe. */
    65 static GRBenv* reusegrbenv = NULL; /**< global Gurobi environment */
    66 static int numlp = 0; /**< number of open LP objects */
    67 #define SCIP_REUSEENV
    68#endif
    69
    70/* macro for checking return codes of Gurobi */
    71#define CHECK_ZERO(messagehdlr, x) do { int _restat_; \
    72 if( (_restat_ = (x)) != 0 ) \
    73 { \
    74 SCIPmessagePrintWarning((messagehdlr), "Gurobi error %d: %s\n", _restat_, GRBgeterrormsg(lpi->grbenv)); \
    75 return SCIP_LPERROR; \
    76 } \
    77 } while(0)
    78
    79/* variant of macro for checking return codes of Gurobi */
    80#define CHECK_ZERO_STAR(messagehdlr, x) do { int _restat_; \
    81 if( (_restat_ = (x)) != 0 ) \
    82 { \
    83 SCIPmessagePrintWarning((messagehdlr), "Gurobi error %d: %s\n", _restat_, GRBgeterrormsg((*lpi)->grbenv)); \
    84 return SCIP_LPERROR; \
    85 } \
    86 } while(0)
    87
    88#ifndef SVECTOR
    89#define SVECTOR GRBsvec
    90#endif
    91
    92typedef unsigned int SCIP_DUALPACKET; /**< storing bit pairs in packed format */
    93#define SCIP_DUALPACKETSIZE (sizeof(SCIP_DUALPACKET)*4) /**< each entry needs two bits of information */
    94
    95typedef SCIP_DUALPACKET COLPACKET; /**< each column needs two bits of information (basic/on_lower/on_upper) */
    96#define COLS_PER_PACKET SCIP_DUALPACKETSIZE
    97typedef SCIP_DUALPACKET ROWPACKET; /**< each row needs two bit of information (basic/on_lower/on_upper) */
    98#define ROWS_PER_PACKET SCIP_DUALPACKETSIZE
    99
    100
    101/* At several places we need to guarantee to have a factorization of an optimal basis and call the simplex to produce
    102 * it. In a numerical perfect world, this should need no iterations. However, due to numerical inaccuracies after
    103 * refactorization, it might be necessary to do a few extra pivot steps. */
    104#define GRB_REFACTORMAXITERS 50 /**< maximal number of iterations allowed for producing a refactorization of the basis */
    105
    106
    107/** number of Gurobi integer parameters that can be changed */
    108#define NUMINTPARAM 6
    109
    110static const char* intparam[NUMINTPARAM] =
    111{
    112 GRB_INT_PAR_SCALEFLAG,
    113 GRB_INT_PAR_PRESOLVE,
    114 GRB_INT_PAR_SIMPLEXPRICING,
    115 GRB_INT_PAR_OUTPUTFLAG,
    116 GRB_INT_PAR_THREADS,
    117 GRB_INT_PAR_SEED
    118};
    119
    120/** number of Gurobi double parameters that can be changed */
    121#define NUMDBLPARAM 7
    122
    123static const char* dblparam[NUMDBLPARAM] =
    124{
    125 GRB_DBL_PAR_FEASIBILITYTOL,
    126 GRB_DBL_PAR_OPTIMALITYTOL,
    127 GRB_DBL_PAR_BARCONVTOL,
    128 GRB_DBL_PAR_CUTOFF,
    129 GRB_DBL_PAR_TIMELIMIT,
    130 GRB_DBL_PAR_ITERATIONLIMIT,
    131 GRB_DBL_PAR_MARKOWITZTOL
    132};
    133
    134/** minimal values for double parameters */
    135static const double dblparammin[NUMDBLPARAM] =
    136{
    137 +1e-09, /* GRB_DBL_PAR_FEASIBILITYTOL */
    138 +1e-09, /* GRB_DBL_PAR_OPTIMALITYTOL */
    139 0.0, /* GRB_DBL_PAR_BARCONVTOL */
    140 -GRB_INFINITY, /* GRB_DBL_PAR_CUTOFF */
    141 0, /* GRB_DBL_PAR_TIMELIMIT */
    142 0, /* GRB_DBL_PAR_ITERATIONLIMIT */
    143 1e-04 /* GRB_DBL_PAR_MARKOWITZTOL */
    144};
    145
    146/** Gurobi parameter settings */
    147struct GRBParam
    148{
    149 int intparval[NUMINTPARAM]; /**< integer parameter values */
    150 double dblparval[NUMDBLPARAM]; /**< double parameter values */
    151};
    152typedef struct GRBParam GRBPARAM;
    153
    154
    155/** LP interface */
    156struct SCIP_LPi
    157{
    158 GRBenv* grbenv; /**< environment corresponding to model */
    159#ifdef SCIP_REUSEENV
    160 int* numlp; /**< pointer to count on number of models in environment */
    161 GRBenv** reusegrbenv; /**< pointer to reused Gurobi environment */
    162#endif
    163 GRBmodel* grbmodel; /**< Gurobi model pointer */
    164 int solstat; /**< solution status of last optimization call */
    165 GRBPARAM defparam; /**< default parameter values */
    166 GRBPARAM curparam; /**< current parameter values stored in Gurobi LP */
    167 GRBPARAM grbparam; /**< current parameter values for this LP */
    168 char* senarray; /**< array for storing row senses */
    169 SCIP_Real* rhsarray; /**< array for storing rhs values */
    170 SCIP_Real* rngarray; /**< array for storing range values */
    171 int* rngidxarray; /**< array for storing the indices of ranged rows in sen/rhs/rngarray */
    172 SCIP_Real* valarray; /**< array for storing coefficient values */
    173 int* cstat; /**< array for storing column basis status */
    174 int* rstat; /**< array for storing row basis status */
    175 int* indarray; /**< array for storing coefficient indices */
    176 int sidechgsize; /**< size of senarray */
    177 int valsize; /**< size of valarray and indarray */
    178 int cstatsize; /**< size of cstat array */
    179 int rstatsize; /**< size of rstat array */
    180 int iterations; /**< number of iterations used in the last solving call */
    181 SCIP_Bool solisbasic; /**< is current LP solution a basic solution? */
    182 SCIP_Bool fromscratch; /**< should each solve be performed without previous basis state? */
    183 SCIP_PRICING pricing; /**< SCIP pricing setting */
    184 SCIP_Real conditionlimit; /**< maximum condition number of LP basis counted as stable (-1.0: no limit) */
    185 SCIP_Bool checkcondition; /**< should condition number of LP basis be checked for stability? */
    186 SCIP_MESSAGEHDLR* messagehdlr; /**< messagehdlr handler to printing messages, or NULL */
    187 int* rngrowmap; /**< maps row id to rngrows array position, or -1 if not a ranged row
    188 * (can be NULL, which means that no ranged rows exist) */
    189 int* rngrows; /**< indices of ranged rows */
    190 SCIP_Real* rngvals; /**< range values of ranged rows */
    191 int rngrowmapsize; /**< size of rngrowmap array */
    192 int nrngrows; /**< number of ranged rows in the LP */
    193 int rngrowssize; /**< size of rngrows and rngvals arrays */
    194 SCIP_Bool rngvarsadded; /**< did we add the range variables to the Gurobi model? */
    195};
    196
    197/** LPi state stores basis information */
    198struct SCIP_LPiState
    199{
    200 int ncols; /**< number of LP columns */
    201 int nrows; /**< number of LP rows */
    202 int nrngrows; /**< number of ranged rows in LP */
    203 COLPACKET* packcstat; /**< column basis status in compressed form */
    204 ROWPACKET* packrstat; /**< row basis status in compressed form */
    205};
    206
    207/** LPi norms stores pricing norms */
    208struct SCIP_LPiNorms
    209{
    210 int ncols; /**< number of columns for which dual norm is stored */
    211 int nrows; /**< number of rows for which dual norm is stored */
    212 double* colnorm; /**< dual norms for columns */
    213 double* rownorm; /**< dual norms for rows */
    214};
    215
    216
    217
    218/*
    219 * dynamic memory arrays
    220 */
    221
    222/** resizes senarray to have at least num entries */
    223static
    225 SCIP_LPI* lpi, /**< LP interface structure */
    226 int num /**< minimal number of entries in array */
    227 )
    228{
    229 assert(lpi != NULL);
    230
    231 if( num > lpi->sidechgsize )
    232 {
    233 int newsize;
    234
    235 newsize = MAX(2*lpi->sidechgsize, num);
    236 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->senarray, newsize) );
    237 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rhsarray, newsize) );
    238 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rngarray, newsize) );
    240 lpi->sidechgsize = newsize;
    241 }
    242 assert(num <= lpi->sidechgsize);
    243
    244 return SCIP_OKAY;
    245}
    246
    247/** resizes valarray and indarray to have at least num entries */
    248static
    250 SCIP_LPI* lpi, /**< LP interface structure */
    251 int num /**< minimal number of entries in array */
    252 )
    253{
    254 assert(lpi != NULL);
    255
    256 if( num > lpi->valsize )
    257 {
    258 int newsize;
    259
    260 newsize = MAX(2*lpi->valsize, num);
    261 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->valarray, newsize) );
    262 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->indarray, newsize) );
    263 lpi->valsize = newsize;
    264 }
    265 assert(num <= lpi->valsize);
    266
    267 return SCIP_OKAY;
    268}
    269
    270/** resizes cstat array to have at least num entries */
    271static
    273 SCIP_LPI* lpi, /**< LP interface structure */
    274 int num /**< minimal number of entries in array */
    275 )
    276{
    277 assert(lpi != NULL);
    278
    279 if( num > lpi->cstatsize )
    280 {
    281 int newsize;
    282
    283 newsize = MAX(2*lpi->cstatsize, num);
    284 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->cstat, newsize) );
    285 lpi->cstatsize = newsize;
    286 }
    287 assert(num <= lpi->cstatsize);
    288
    289 return SCIP_OKAY;
    290}
    291
    292/** resizes rstat array to have at least num entries */
    293static
    295 SCIP_LPI* lpi, /**< LP interface structure */
    296 int num /**< minimal number of entries in array */
    297 )
    298{
    299 assert(lpi != NULL);
    300
    301 if( num > lpi->rstatsize )
    302 {
    303 int newsize;
    304
    305 newsize = MAX(2*lpi->rstatsize, num);
    306 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rstat, newsize) );
    307 lpi->rstatsize = newsize;
    308 }
    309 assert(num <= lpi->rstatsize);
    310
    311 return SCIP_OKAY;
    312}
    313
    314/** resizes rngrowmap array to have at least num entries */
    315static
    317 SCIP_LPI* lpi, /**< LP interface structure */
    318 int num /**< minimal number of entries in array */
    319 )
    320{
    321 assert(lpi != NULL);
    322
    323 if( num > lpi->rngrowmapsize )
    324 {
    325 int newsize;
    326 int r;
    327
    328 newsize = MAX(2*lpi->rngrowmapsize, num);
    329 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rngrowmap, newsize) );
    330 for (r = lpi->rngrowmapsize; r < newsize; r++)
    331 lpi->rngrowmap[r] = -1;
    332 lpi->rngrowmapsize = newsize;
    333 }
    334 assert(num <= lpi->rngrowmapsize);
    335
    336 return SCIP_OKAY;
    337}
    338
    339/** resizes rngrows and rngvals arrays to have at least num entries */
    340static
    342 SCIP_LPI* lpi, /**< LP interface structure */
    343 int num /**< minimal number of entries in array */
    344 )
    345{
    346 assert(lpi != NULL);
    347
    348 if( num > lpi->rngrowssize )
    349 {
    350 int newsize;
    351
    352 newsize = MAX(2*lpi->rngrowssize, num);
    353 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rngrows, newsize) );
    354 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rngvals, newsize) );
    355 lpi->rngrowssize = newsize;
    356 }
    357 assert(num <= lpi->rngrowssize);
    358
    359 return SCIP_OKAY;
    360}
    361
    362/** stores current basis in internal arrays of LPI data structure */
    363static
    365 SCIP_LPI* lpi, /**< LP interface structure */
    366 SCIP_Bool* success /**< whether basis information has successfully been obtained */
    367 )
    368{
    369 int ncols;
    370 int nrows;
    371 int res;
    372
    373 assert( lpi != NULL );
    374 assert( lpi->grbmodel != NULL );
    375 assert( lpi->grbenv != NULL );
    376
    377 SCIPdebugMessage("getBase()\n");
    378 if ( success != NULL )
    379 *success = TRUE;
    380
    381 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMVARS, &ncols) );
    382 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMCONSTRS, &nrows) );
    383
    384 /* allocate enough memory for storing uncompressed basis information */
    385 SCIP_CALL( ensureCstatMem(lpi, ncols) );
    386 SCIP_CALL( ensureRstatMem(lpi, nrows) );
    387
    388 /* get unpacked basis information from Gurobi */
    389 res = GRBgetintattrarray(lpi->grbmodel, GRB_INT_ATTR_VBASIS, 0, ncols, lpi->cstat);
    390 if ( res == GRB_ERROR_DATA_NOT_AVAILABLE )
    391 {
    392 /* if the model is infeasible, Gurobi does not currently return basis information */
    393 if ( success != NULL )
    394 *success = FALSE;
    395 return SCIP_OKAY;
    396 }
    397 else if ( res != 0 )
    398 {
    399 SCIPerrorMessage("Gurobi error %d: %s\n", res, GRBgeterrormsg(lpi->grbenv));
    400 return SCIP_LPERROR;
    401 }
    402
    403 res = GRBgetintattrarray(lpi->grbmodel, GRB_INT_ATTR_CBASIS, 0, nrows, lpi->rstat);
    404 if ( res == GRB_ERROR_DATA_NOT_AVAILABLE )
    405 {
    406 /* if the model is infeasible Gurobi does not currently return basis information */
    407 if ( success != NULL )
    408 *success = FALSE;
    409 return SCIP_OKAY;
    410 }
    411 else if ( res != 0 )
    412 {
    413 SCIPerrorMessage("Gurobi error %d: %s\n", res, GRBgeterrormsg(lpi->grbenv));
    414 return SCIP_LPERROR;
    415 }
    416
    417 return SCIP_OKAY;
    418}
    419
    420/** loads basis stored in internal arrays of LPI data structure into Gurobi */
    421static
    423 SCIP_LPI* lpi /**< LP interface structure */
    424 )
    425{
    426 int ncols;
    427 int nrows;
    428
    429 assert( lpi != NULL );
    430 assert( lpi->grbmodel != NULL );
    431
    432 SCIPdebugMessage("setBase()\n");
    433
    434 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMVARS, &ncols) );
    435 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMCONSTRS, &nrows) );
    436
    437 /* load basis information into Gurobi */
    438 CHECK_ZERO( lpi->messagehdlr, GRBsetintattrarray(lpi->grbmodel, GRB_INT_ATTR_VBASIS, 0, ncols, lpi->cstat) );
    439 CHECK_ZERO( lpi->messagehdlr, GRBsetintattrarray(lpi->grbmodel, GRB_INT_ATTR_CBASIS, 0, nrows, lpi->rstat) );
    440
    441 CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
    442
    443 return SCIP_OKAY;
    444}
    445
    446
    447
    448
    449/*
    450 * LPi state methods
    451 */
    452
    453/** returns the number of packets needed to store column packet information */
    454static
    456 int ncols /**< number of columns to store */
    457 )
    458{
    459 return (ncols+(int)COLS_PER_PACKET-1)/(int)COLS_PER_PACKET;
    460}
    461
    462/** returns the number of packets needed to store row packet information */
    463static
    465 int nrows /**< number of rows to store */
    466 )
    467{
    468 return (nrows+(int)ROWS_PER_PACKET-1)/(int)ROWS_PER_PACKET;
    469}
    470
    471
    472/* The basis information for Gurobi is negative. So we cannot use the functions in bitencode.h/c. The functions below are a modified copy. */
    473
    474/** encode a negated dual bit vector into packed format */
    475static
    477 const int* inp, /**< unpacked input vector */
    478 SCIP_DUALPACKET* out, /**< buffer to store the packed vector */
    479 int count /**< number of elements */
    480 )
    481{
    482 static const SCIP_DUALPACKET mask[SCIP_DUALPACKETSIZE][4] = { /* if the packet size changes, the mask has to be updated */
    483 {0x00000000, 0x00000001, 0x00000002, 0x00000003},
    484 {0x00000000, 0x00000004, 0x00000008, 0x0000000C},
    485 {0x00000000, 0x00000010, 0x00000020, 0x00000030},
    486 {0x00000000, 0x00000040, 0x00000080, 0x000000C0},
    487 {0x00000000, 0x00000100, 0x00000200, 0x00000300},
    488 {0x00000000, 0x00000400, 0x00000800, 0x00000C00},
    489 {0x00000000, 0x00001000, 0x00002000, 0x00003000},
    490 {0x00000000, 0x00004000, 0x00008000, 0x0000C000},
    491 {0x00000000, 0x00010000, 0x00020000, 0x00030000},
    492 {0x00000000, 0x00040000, 0x00080000, 0x000C0000},
    493 {0x00000000, 0x00100000, 0x00200000, 0x00300000},
    494 {0x00000000, 0x00400000, 0x00800000, 0x00C00000},
    495 {0x00000000, 0x01000000, 0x02000000, 0x03000000},
    496 {0x00000000, 0x04000000, 0x08000000, 0x0C000000},
    497 {0x00000000, 0x10000000, 0x20000000, 0x30000000},
    498 {0x00000000, 0x40000000, 0x80000000, 0xC0000000}
    499 };
    500 int i;
    501 int rest;
    502 int nfull;
    503
    504 assert(inp != NULL || count == 0);
    505 assert(out != NULL || count == 0);
    506 assert(count >= 0);
    507 assert(SCIP_DUALPACKETSIZE == 16); /*lint !e506*/
    508
    509 rest = count % (int)SCIP_DUALPACKETSIZE;
    510 nfull = count - rest;
    511
    512 for( i = 0; i < nfull; i += (int)SCIP_DUALPACKETSIZE, inp += (int)SCIP_DUALPACKETSIZE ) /*lint !e679*/
    513 {
    514 assert(inp != NULL);
    515 assert(out != NULL);
    516
    517#ifndef NDEBUG
    518 {
    519 unsigned int j;
    520 for( j = 0; j < SCIP_DUALPACKETSIZE; ++j )
    521 assert(0 <= -inp[j] && -inp[j] <= 3);
    522 }
    523#endif
    524 *out++ =
    525 mask[0][-inp[0]] | mask[1][-inp[1]] | mask[2][-inp[2]] | mask[3][-inp[3]]
    526 | mask[4][-inp[4]] | mask[5][-inp[5]] | mask[6][-inp[6]]
    527 | mask[7][-inp[7]] | mask[8][-inp[8]] | mask[9][-inp[9]]
    528 | mask[10][-inp[10]] | mask[11][-inp[11]] | mask[12][-inp[12]]
    529 | mask[13][-inp[13]] | mask[14][-inp[14]] | mask[15][-inp[15]];
    530 }
    531
    532 if( rest > 0 )
    533 {
    535
    536 assert(inp != NULL);
    537 assert(out != NULL);
    538
    539 for( i = 0; i < rest; i++ )
    540 m |= mask[i][-inp[i]]; /*lint !e661*/
    541 *out = m;
    542 }
    543}
    544
    545/** decode a packed dual bit vector into negated unpacked format */
    546static
    548 const SCIP_DUALPACKET* inp, /**< packed input vector */
    549 int* out, /**< buffer to store unpacked vector */
    550 int count /**< number of elements */
    551 )
    552{
    554 int rest;
    555 int nfull;
    556 int i;
    557
    558 assert(inp != NULL || count == 0);
    559 assert(out != NULL || count == 0);
    560 assert(count >= 0);
    561 assert(SCIP_DUALPACKETSIZE == 16); /*lint !e506*/
    562
    563 rest = count % (int)SCIP_DUALPACKETSIZE;
    564 nfull = count - rest;
    565
    566 for( i = 0; i < nfull; i += (int)SCIP_DUALPACKETSIZE )
    567 {
    568 assert(inp != NULL);
    569 assert(out != NULL);
    570
    571 m = *inp++;
    572
    573 *out++ = -(int)(m & 3);
    574 m >>= 2;
    575 *out++ = -(int)(m & 3);
    576 m >>= 2;
    577 *out++ = -(int)(m & 3);
    578 m >>= 2;
    579 *out++ = -(int)(m & 3);
    580 m >>= 2;
    581 *out++ = -(int)(m & 3);
    582 m >>= 2;
    583 *out++ = -(int)(m & 3);
    584 m >>= 2;
    585 *out++ = -(int)(m & 3);
    586 m >>= 2;
    587 *out++ = -(int)(m & 3);
    588 m >>= 2;
    589 *out++ = -(int)(m & 3);
    590 m >>= 2;
    591 *out++ = -(int)(m & 3);
    592 m >>= 2;
    593 *out++ = -(int)(m & 3);
    594 m >>= 2;
    595 *out++ = -(int)(m & 3);
    596 m >>= 2;
    597 *out++ = -(int)(m & 3);
    598 m >>= 2;
    599 *out++ = -(int)(m & 3);
    600 m >>= 2;
    601 *out++ = -(int)(m & 3);
    602 m >>= 2;
    603 *out++ = -(int)(m & 3);
    604 assert(m >> 2 == 0);
    605 }
    606
    607 if( rest > 0 )
    608 {
    609 assert(inp != NULL);
    610 assert(out != NULL);
    611
    612 m = *inp;
    613 for( i = 0; i < rest; i++ )
    614 {
    615 *out++ = -(int)(m & 3);
    616 m >>= 2;
    617 }
    618 }
    619}
    620
    621/** store row and column basis status in a packed LPi state object */
    622static
    624 SCIP_LPISTATE* lpistate, /**< pointer to LPi state data */
    625 const int* cstat, /**< basis status of columns in unpacked format */
    626 const int* rstat /**< basis status of rows in unpacked format */
    627 )
    628{
    629 assert(lpistate != NULL);
    630 assert(lpistate->packcstat != NULL);
    631 assert(lpistate->packrstat != NULL);
    632
    633 SCIPencodeDualBitNeg(cstat, lpistate->packcstat, lpistate->ncols + lpistate->nrngrows);
    634 SCIPencodeDualBitNeg(rstat, lpistate->packrstat, lpistate->nrows);
    635}
    636
    637/** unpacks row and column basis status from a packed LPi state object */
    638static
    640 const SCIP_LPISTATE* lpistate, /**< pointer to LPi state data */
    641 int* cstat, /**< buffer for storing basis status of columns in unpacked format */
    642 int* rstat /**< buffer for storing basis status of rows in unpacked format */
    643 )
    644{
    645 assert(lpistate != NULL);
    646 assert(lpistate->packcstat != NULL);
    647 assert(lpistate->packrstat != NULL);
    648
    649 SCIPdecodeDualBitNeg(lpistate->packcstat, cstat, lpistate->ncols + lpistate->nrngrows);
    650 SCIPdecodeDualBitNeg(lpistate->packrstat, rstat, lpistate->nrows);
    651}
    652
    653/** creates LPi state information object */
    654static
    656 SCIP_LPISTATE** lpistate, /**< pointer to LPi state */
    657 BMS_BLKMEM* blkmem, /**< block memory */
    658 int ncols, /**< number of columns to store */
    659 int nrows, /**< number of rows to store */
    660 int nrngrows /**< number of ranged rows */
    661 )
    662{
    663 assert(lpistate != NULL);
    664 assert(blkmem != NULL);
    665 assert(ncols >= 0);
    666 assert(nrows >= 0);
    667
    668 SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpistate) );
    669 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->packcstat, colpacketNum(ncols + nrngrows)) );
    670 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->packrstat, rowpacketNum(nrows)) );
    671
    672 return SCIP_OKAY;
    673}
    674
    675/** frees LPi state information */
    676static
    678 SCIP_LPISTATE** lpistate, /**< pointer to LPi state information (like basis information) */
    679 BMS_BLKMEM* blkmem /**< block memory */
    680 )
    681{
    682 assert(blkmem != NULL);
    683 assert(lpistate != NULL);
    684 assert(*lpistate != NULL);
    685
    686 BMSfreeBlockMemoryArrayNull(blkmem, &(*lpistate)->packcstat, colpacketNum((*lpistate)->ncols + (*lpistate)->nrngrows));
    687 BMSfreeBlockMemoryArrayNull(blkmem, &(*lpistate)->packrstat, rowpacketNum((*lpistate)->nrows));
    688 BMSfreeBlockMemory(blkmem, lpistate);
    689}
    690
    691
    692
    693/*
    694 * local methods
    695 */
    696
    697/** gets all Gurobi parameters used in LPI */
    698static
    700 SCIP_LPI* lpi, /**< LP interface structure */
    701 GRBPARAM* grbparam /**< Gurobi parameters */
    702 )
    703{
    704 int i;
    705
    706 assert( lpi != NULL );
    707 assert( lpi->grbenv != NULL );
    708 assert( grbparam != NULL );
    709
    710 SCIPdebugMessage("getParameterValues()\n");
    711
    712 for( i = 0; i < NUMINTPARAM; ++i )
    713 {
    714 CHECK_ZERO( lpi->messagehdlr, GRBgetintparam(lpi->grbenv, intparam[i], &(grbparam->intparval[i])) );
    715 }
    716 for( i = 0; i < NUMDBLPARAM; ++i )
    717 {
    718 CHECK_ZERO( lpi->messagehdlr, GRBgetdblparam(lpi->grbenv, dblparam[i], &(grbparam->dblparval[i])) );
    719 }
    720
    721 return SCIP_OKAY;
    722}
    723
    724/** in debug mode, checks validity of Gurobi parameters */
    725static
    727 SCIP_LPI* lpi /**< LP interface structure */
    728 )
    729{
    730#ifndef NDEBUG
    731 GRBPARAM par;
    732 int i;
    733
    734 SCIP_CALL( getParameterValues(lpi, &par) );
    735 for (i = 0; i < NUMINTPARAM; ++i)
    736 assert( lpi->curparam.intparval[i] == par.intparval[i] );
    737 for (i = 0; i < NUMDBLPARAM; ++i)
    738 assert(MAX(lpi->curparam.dblparval[i], dblparammin[i]) == par.dblparval[i]); /*lint !e777*/
    739#endif
    740
    741 return SCIP_OKAY;
    742}
    743
    744/** sets all Gurobi parameters used in LPI */
    745static
    747 SCIP_LPI* lpi, /**< LP interface structure */
    748 GRBPARAM* grbparam /**< Gurobi parameters */
    749 )
    750{
    751 int i;
    752
    753 assert( lpi != NULL );
    754 assert( lpi->grbenv != NULL );
    755 assert( grbparam != NULL );
    756
    757 SCIPdebugMessage("setParameterValues()\n");
    758
    759 for( i = 0; i < NUMINTPARAM; ++i )
    760 {
    761 if( lpi->curparam.intparval[i] != grbparam->intparval[i] )
    762 {
    763 SCIPdebugMessage("setting Gurobi int parameter %s from %d to %d\n",
    764 intparam[i], lpi->curparam.intparval[i], grbparam->intparval[i]);
    765 lpi->curparam.intparval[i] = grbparam->intparval[i];
    766 CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, intparam[i], lpi->curparam.intparval[i]) );
    767 }
    768 }
    769 for( i = 0; i < NUMDBLPARAM; ++i )
    770 {
    771 if( lpi->curparam.dblparval[i] != grbparam->dblparval[i] ) /*lint !e777*/
    772 {
    773 SCIPdebugMessage("setting Gurobi dbl parameter %s from %g to %g\n",
    774 dblparam[i], lpi->curparam.dblparval[i], MAX(grbparam->dblparval[i], dblparammin[i]));
    775 lpi->curparam.dblparval[i] = MAX(grbparam->dblparval[i], dblparammin[i]);
    776 CHECK_ZERO( lpi->messagehdlr, GRBsetdblparam(lpi->grbenv, dblparam[i], lpi->curparam.dblparval[i]) );
    777 }
    778 }
    779
    781
    782 return SCIP_OKAY;
    783}
    784
    785/** copies Gurobi parameters from source to dest */
    786static
    788 GRBPARAM* dest, /**< destination Gurobi parameters */
    789 const GRBPARAM* source /**< original Gurobi parameters */
    790 )
    791{
    792 int i;
    793
    794 for( i = 0; i < NUMINTPARAM; ++i )
    795 dest->intparval[i] = source->intparval[i];
    796 for( i = 0; i < NUMDBLPARAM; ++i )
    797 dest->dblparval[i] = source->dblparval[i];
    798}
    799
    800/** gets a single integer parameter value */
    801static
    803 SCIP_LPI* lpi, /**< LP interface structure */
    804 const char* param, /**< parameter name */
    805 int* p /**< value of parameter */
    806 )
    807{
    808 int i;
    809
    810 assert( lpi != NULL );
    811
    812 for( i = 0; i < NUMINTPARAM; ++i )
    813 {
    814 if( strcmp(intparam[i], param) == 0 )
    815 {
    816 *p = lpi->grbparam.intparval[i];
    817 return SCIP_OKAY;
    818 }
    819 }
    820
    821 SCIPerrorMessage("unknown Gurobi integer parameter <%s>.\n", param);
    822 return SCIP_LPERROR;
    823}
    824
    825/** sets a single integer parameter value */
    826static
    828 SCIP_LPI* lpi, /**< LP interface structure */
    829 const char* param, /**< parameter name */
    830 int parval /**< value of parameter */
    831 )
    832{
    833 int i;
    834
    835 assert( lpi != NULL );
    836
    837 for( i = 0; i < NUMINTPARAM; ++i )
    838 {
    839 if( strcmp(intparam[i], param) == 0 )
    840 {
    841 lpi->grbparam.intparval[i] = parval;
    842 return SCIP_OKAY;
    843 }
    844 }
    845
    846 SCIPerrorMessage("unknown Gurobi integer parameter <%s>.\n", param);
    847 return SCIP_LPERROR;
    848}
    849
    850/** gets a single double parameter value */
    851static
    853 SCIP_LPI* lpi, /**< LP interface structure */
    854 const char* param, /**< parameter name */
    855 double* p /**< value of parameter */
    856 )
    857{
    858 int i;
    859
    860 assert(lpi != NULL);
    861
    862 for( i = 0; i < NUMDBLPARAM; ++i )
    863 {
    864 if( strcmp(dblparam[i], param) == 0 )
    865 {
    866 *p = lpi->grbparam.dblparval[i];
    867 return SCIP_OKAY;
    868 }
    869 }
    870
    871 SCIPerrorMessage("unknown Gurobi double parameter <%s>.\n", param);
    872 return SCIP_LPERROR;
    873}
    874
    875/** sets a single double parameter value */
    876static
    878 SCIP_LPI* lpi, /**< LP interface structure */
    879 const char* param, /**< parameter name */
    880 double parval /**< value of parameter */
    881 )
    882{
    883 int i;
    884
    885 assert( lpi != NULL );
    886
    887 for( i = 0; i < NUMDBLPARAM; ++i )
    888 {
    889 if( strcmp(dblparam[i], param) == 0 )
    890 {
    891 lpi->grbparam.dblparval[i] = parval;
    892 return SCIP_OKAY;
    893 }
    894 }
    895
    896 SCIPerrorMessage("unknown Gurobi double parameter <%s>.\n", param);
    897 return SCIP_LPERROR;
    898}
    899
    900/** marks the current LP to be unsolved */
    901static
    903 SCIP_LPI* lpi /**< LP interface structure */
    904 )
    905{
    906 assert(lpi != NULL);
    907 lpi->solstat = -1;
    908}
    909
    910/** converts SCIP's lhs/rhs pairs into Gurobi's sen/rhs */
    911static
    913 SCIP_LPI* lpi, /**< LP interface structure */
    914 int nrows, /**< number of rows */
    915 const SCIP_Real* lhs, /**< left hand side vector */
    916 const SCIP_Real* rhs, /**< right hand side vector */
    917 int* rngcount /**< number of ranged rows found */
    918 )
    919{
    920 int i;
    921
    922 assert(lpi != NULL);
    923 assert(nrows >= 0);
    924 assert(lhs != NULL);
    925 assert(rhs != NULL);
    926 assert(rngcount != NULL);
    927
    928 /* convert lhs/rhs into sen/rhs */
    929 *rngcount = 0;
    930 for( i = 0; i < nrows; ++i )
    931 {
    932 assert(lhs[i] <= rhs[i]);
    933
    934 if( lhs[i] == rhs[i] ) /*lint !e777*/
    935 {
    936 assert(-GRB_INFINITY < rhs[i] && rhs[i] < GRB_INFINITY);
    937 lpi->senarray[i] = GRB_EQUAL;
    938 lpi->rhsarray[i] = rhs[i];
    939 lpi->rngarray[i] = 0.0;
    940 }
    941 else if( lhs[i] <= -GRB_INFINITY )
    942 {
    943 /* this includes the case of free rows */
    944 assert(-GRB_INFINITY < rhs[i]);
    945 lpi->senarray[i] = GRB_LESS_EQUAL;
    946 lpi->rhsarray[i] = rhs[i];
    947 }
    948 else if( rhs[i] >= GRB_INFINITY )
    949 {
    950 assert(-GRB_INFINITY < lhs[i] && lhs[i] < GRB_INFINITY);
    951 lpi->senarray[i] = GRB_GREATER_EQUAL;
    952 lpi->rhsarray[i] = lhs[i];
    953 }
    954 else
    955 {
    956 /* we treat ranged rows as equations with an extra slack variable */
    957 assert(-GRB_INFINITY < lhs[i] && lhs[i] < GRB_INFINITY);
    958 assert(-GRB_INFINITY < rhs[i] && rhs[i] < GRB_INFINITY);
    959 lpi->senarray[i] = GRB_EQUAL;
    960 lpi->rhsarray[i] = lhs[i];
    961 lpi->rngarray[i] = rhs[i] - lhs[i];
    962 lpi->rngidxarray[(*rngcount)++] = i;
    963 }
    964 }
    965 return SCIP_OKAY;
    966}
    967
    968/** converts Gurobi's sen/rhs pairs into SCIP's lhs/rhs pairs */
    969static
    971 SCIP_LPI* lpi, /**< LP interface structure */
    972 int firstrow, /**< first row to get sides for */
    973 int lastrow, /**< last row to get sides for */
    974 SCIP_Real* lhs, /**< buffer to store the left hand side vector, or NULL */
    975 SCIP_Real* rhs /**< buffer to store the right hand side vector, or NULL */
    976 )
    977{
    978 int nrows;
    979 int i;
    980
    981 assert(lpi != NULL);
    982 assert(firstrow >= 0);
    983 nrows = lastrow - firstrow + 1;
    984 assert(nrows >= 0);
    985#ifndef NDEBUG
    986 {
    987 int ntotalrows;
    988 SCIP_CALL( SCIPlpiGetNRows(lpi, &ntotalrows) );
    989 assert(lastrow < ntotalrows);
    990 }
    991#endif
    992
    993 for (i = 0; i < nrows; ++i)
    994 {
    995 switch( lpi->senarray[i] )
    996 {
    997 case GRB_EQUAL:
    998 if ( lhs != NULL )
    999 lhs[i] = lpi->rhsarray[i];
    1000 if ( rhs != NULL )
    1001 {
    1002 int row;
    1003
    1004 rhs[i] = lpi->rhsarray[i];
    1005 row = firstrow+i;
    1006 if ( lpi->rngrowmap != NULL && lpi->rngrowmap[row] >= 0 )
    1007 {
    1008 assert(lpi->rngrowmap[row] < lpi->nrngrows);
    1009 rhs[i] += lpi->rngvals[lpi->rngrowmap[row]];
    1010 }
    1011 }
    1012 break;
    1013
    1014 case GRB_LESS_EQUAL:
    1015 if ( lhs != NULL )
    1016 lhs[i] = -GRB_INFINITY;
    1017 if ( rhs != NULL )
    1018 rhs[i] = lpi->rhsarray[i];
    1019 break;
    1020
    1021 case GRB_GREATER_EQUAL:
    1022 if ( lhs != NULL )
    1023 lhs[i] = lpi->rhsarray[i];
    1024 if ( rhs != NULL )
    1025 rhs[i] = GRB_INFINITY;
    1026 break;
    1027
    1028 default:
    1029 SCIPerrorMessage("invalid row sense\n");
    1030 SCIPABORT();
    1031 return SCIP_LPERROR; /*lint !e527*/
    1032 }
    1033 assert(lhs == NULL || rhs == NULL || lhs[i] <= rhs[i]);
    1034 }
    1035 return SCIP_OKAY;
    1036}
    1037
    1038/** after restoring old LP data, need to resolve the LP to be able to retrieve correct information */
    1039static
    1041 SCIP_LPI* lpi /**< LP interface structure */
    1042 )
    1043{
    1044 assert( lpi != NULL );
    1045
    1046 /* set dual simplex */
    1047 CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, GRB_METHOD_DUAL) );
    1048 CHECK_ZERO( lpi->messagehdlr, GRBoptimize(lpi->grbmodel) );
    1049
    1050#ifndef NDEBUG
    1051 {
    1052 double cnt;
    1053
    1054 /* modifying the LP, restoring the old LP, and loading the old basis is not enough for Gurobi to be able to return
    1055 * the basis -> we have to resolve the LP;
    1056 *
    1057 * In a numerical perfect world, GRB_REFACTORMAXITERS below should be zero. However, due to numerical inaccuracies
    1058 * after refactorization, it might be necessary to do a few extra pivot steps.
    1059 */
    1060 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
    1061 if ( cnt > (double) GRB_REFACTORMAXITERS )
    1062 SCIPmessagePrintWarning(lpi->messagehdlr, "Gurobi needed %d iterations to restore optimal basis.\n", (int) cnt);
    1063 }
    1064#endif
    1065
    1066 return SCIP_OKAY;
    1067}
    1068
    1069#ifndef NDEBUG
    1070/** verifies in debug mode that ranged row information is consistent */
    1071static
    1073 SCIP_LPI* lpi /**< LP interface structure */
    1074 )
    1075{
    1076 assert(lpi->rngrowssize >= lpi->nrngrows);
    1077
    1078 if ( lpi->nrngrows > 0 )
    1079 {
    1080 int nrngrows = 0;
    1081 int nrows;
    1082 int i;
    1083
    1084 assert(lpi->rngrowmap != NULL);
    1085 assert(lpi->rngrows != NULL);
    1086 assert(lpi->rngvals != NULL);
    1087
    1088 SCIP_CALL_ABORT( SCIPlpiGetNRows(lpi, &nrows) );
    1089
    1090 assert(lpi->rngrowmapsize >= nrows);
    1091
    1092 for (i = 0; i < nrows; i++)
    1093 {
    1094 int rngrow;
    1095
    1096 rngrow = lpi->rngrowmap[i];
    1097 assert(-1 <= rngrow && rngrow < lpi->nrngrows);
    1098 if ( rngrow >= 0 )
    1099 {
    1100 assert(lpi->rngrows[rngrow] == i);
    1101 assert(lpi->rngvals[rngrow] > 0.0);
    1102 nrngrows++;
    1103 }
    1104 }
    1105 assert(lpi->nrngrows == nrngrows);
    1106 }
    1107}
    1108#else
    1109#define checkRangeInfo(lpi) /**/
    1110#endif
    1111
    1112/** adds range variables to Gurobi LP */
    1113static
    1115 SCIP_LPI* lpi /**< LP interface structure */
    1116 )
    1117{
    1118 int i;
    1119
    1120 assert(!lpi->rngvarsadded);
    1121 assert(lpi->nrngrows > 0);
    1122 assert(lpi->rngrowmap != NULL);
    1123 assert(lpi->rngrows != NULL);
    1124
    1125 for (i = 0; i < lpi->nrngrows; i++)
    1126 {
    1127 double coeff = -1.0;
    1128 int row;
    1129
    1130 row = lpi->rngrows[i];
    1131
    1132 CHECK_ZERO( lpi->messagehdlr, GRBaddvar(lpi->grbmodel, 1, &row, &coeff, 0.0, 0.0, lpi->rngvals[i], GRB_CONTINUOUS, NULL) );
    1133 }
    1134
    1135 /* flush model changes */
    1136 CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
    1137
    1138 lpi->rngvarsadded = TRUE;
    1139
    1140 return SCIP_OKAY;
    1141}
    1142
    1143/** deletes range variables from Gurobi LP */
    1144static
    1146 SCIP_LPI* lpi /**< LP interface structure */
    1147 )
    1148{
    1149 int* which;
    1150 int ncols;
    1151 int i;
    1152
    1153 assert(lpi->rngvarsadded);
    1154 assert(lpi->nrngrows > 0);
    1155
    1156 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    1157
    1158 /* Gurobi can't delete a range of columns, we have to set up an index array */
    1159 SCIP_ALLOC( BMSallocMemoryArray(&which, lpi->nrngrows) );
    1160 for (i = 0; i < lpi->nrngrows; i++)
    1161 which[i] = ncols+i;
    1162
    1163 CHECK_ZERO( lpi->messagehdlr, GRBdelvars(lpi->grbmodel, lpi->nrngrows, which) );
    1164 CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
    1165
    1166 BMSfreeMemoryArray( &which );
    1167
    1168 lpi->rngvarsadded = FALSE;
    1169
    1170 return SCIP_OKAY;
    1171}
    1172
    1173/** clear ranged row information */
    1174static
    1176 SCIP_LPI* lpi /**< LP interface structure */
    1177 )
    1178{
    1179 assert(!lpi->rngvarsadded);
    1180
    1184
    1185 lpi->nrngrows = 0;
    1186 lpi->rngrowssize = 0;
    1187 lpi->rngrowmapsize = 0;
    1188}
    1189
    1190/** creates or updates maps for ranged rows after new rows have been added */
    1191static
    1193 SCIP_LPI* lpi, /**< LP interface structure */
    1194 int rngcount, /**< number of ranged rows added */
    1195 int firstrow /**< index of first row that was added */
    1196 )
    1197{
    1198 int ncols;
    1199 int nrows;
    1200 int r;
    1201 int i;
    1202
    1203 assert(lpi != NULL);
    1204 assert(rngcount >= 0);
    1205 assert(firstrow >= 0);
    1206
    1207 /* get rid of range variables */
    1208 if( lpi->rngvarsadded )
    1209 {
    1210 SCIP_CALL( delRangeVars(lpi) );
    1211 }
    1212 assert(!lpi->rngvarsadded);
    1213
    1214 /* query problem size in terms of SCIP's view */
    1215 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    1216 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
    1217
    1218 /* set up and extend rngrowmap array */
    1219 SCIP_CALL( ensureRngrowmapMem(lpi, nrows) );
    1220 for( r = firstrow; r < nrows; r++ )
    1221 lpi->rngrowmap[r] = -1;
    1222
    1223 /* extend rngrows and rngvals arrays */
    1224 SCIP_CALL( ensureRngrowsMem(lpi, lpi->nrngrows + rngcount) );
    1225
    1226 /* update maps for ranged rows */
    1227 for( i = 0; i < rngcount; i++ )
    1228 {
    1229 int pos;
    1230 int row;
    1231
    1232 pos = lpi->rngidxarray[i];
    1233 row = firstrow + pos;
    1234
    1235 lpi->rngrowmap[row] = lpi->nrngrows;
    1236 lpi->rngrows[lpi->nrngrows] = row;
    1237 lpi->rngvals[lpi->nrngrows] = lpi->rngarray[pos];
    1238 lpi->nrngrows++;
    1239 }
    1240
    1241 return SCIP_OKAY;
    1242}
    1243
    1244
    1245
    1246/*
    1247 * LP Interface Methods
    1248 */
    1249
    1250
    1251/*
    1252 * Miscellaneous Methods
    1253 */
    1254
    1255static const char grbname[] = {'G', 'u', 'r', 'o', 'b', 'i', ' ',
    1256#if GRB_VERSION_MAJOR < 10
    1257 GRB_VERSION_MAJOR + '0',
    1258#else
    1259 (GRB_VERSION_MAJOR/10) + '0', (GRB_VERSION_MAJOR%10) + '0', /*lint !e778*/
    1260#endif
    1261 '.', GRB_VERSION_MINOR + '0', '.', GRB_VERSION_TECHNICAL + '0', '\0'}; /*lint !e835*/
    1262
    1263/**@name Miscellaneous Methods */
    1264/**@{ */
    1265
    1266/** gets name and version of LP solver */
    1268 void
    1269 )
    1270{
    1271 return grbname;
    1272}
    1273
    1274/** gets description of LP solver (developer, webpage, ...) */
    1276 void
    1277 )
    1278{
    1279 return "Linear Programming Solver developed by Gurobi Optimization (www.gurobi.com)";
    1280}
    1281
    1282/** gets pointer for LP solver - use only with great care
    1283 *
    1284 * Here we return the pointer to the model.
    1285 */
    1287 SCIP_LPI* lpi /**< pointer to an LP interface structure */
    1288 )
    1289{
    1290 return (void*) lpi->grbmodel;
    1291}
    1292
    1293/** pass integrality information to LP solver */
    1295 SCIP_LPI* lpi, /**< pointer to an LP interface structure */
    1296 int ncols, /**< length of integrality array */
    1297 int* intInfo /**< integrality array (0: continuous, 1: integer). May be NULL iff ncols is 0. */
    1298 )
    1299{ /*lint --e{715}*/
    1300 assert( lpi != NULL );
    1301 assert( ncols >= 0 );
    1302 assert( ncols == 0 || intInfo != NULL );
    1303
    1304 SCIPerrorMessage("SCIPlpiSetIntegralityInformation() has not been implemented yet.\n");
    1305 return SCIP_LPERROR;
    1306}
    1307
    1308/** informs about availability of a primal simplex solving method */
    1310 void
    1311 )
    1312{
    1313 return TRUE;
    1314}
    1315
    1316/** informs about availability of a dual simplex solving method */
    1318 void
    1319 )
    1320{
    1321 return TRUE;
    1322}
    1323
    1324/** informs about availability of a barrier solving method */
    1326 void
    1327 )
    1328{
    1329 return TRUE;
    1330}
    1331
    1332/**@} */
    1333
    1334
    1335
    1336
    1337/*
    1338 * LPI Creation and Destruction Methods
    1339 */
    1340
    1341/**@name LPI Creation and Destruction Methods */
    1342/**@{ */
    1343
    1344/** creates an LP problem object */
    1346 SCIP_LPI** lpi, /**< pointer to an LP interface structure */
    1347 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler to use for printing messages, or NULL */
    1348 const char* name, /**< problem name */
    1349 SCIP_OBJSEN objsen /**< objective sense */
    1350 )
    1351{
    1352 assert(sizeof(SCIP_Real) == sizeof(double)); /*lint !e506*/ /* Gurobi only works with doubles as floating points */
    1353 assert(sizeof(SCIP_Bool) == sizeof(int)); /*lint !e506*/ /* Gurobi only works with ints as bools */
    1354 assert(lpi != NULL);
    1355 assert(name != NULL);
    1356#ifdef SCIP_REUSEENV
    1357 assert(numlp >= 0);
    1358#endif
    1359
    1360 SCIPdebugMessage("SCIPlpiCreate()\n");
    1361
    1362 /* create empty LPI */
    1363 SCIP_ALLOC( BMSallocMemory(lpi) );
    1364
    1365 /* create environment */
    1366#ifdef SCIP_REUSEENV
    1367 /* temporarily set environment for error messages (might be NULL) */
    1368 (*lpi)->grbenv = reusegrbenv;
    1369
    1370 /* Try to reuse Gurobi environment (either thread local or not being thread safe). */
    1371 if ( reusegrbenv == NULL )
    1372 {
    1373 int restat;
    1374
    1375 assert( numlp == 0 );
    1376
    1377 /* create environment */
    1378#if GRB_VERSION_MAJOR >= 8
    1379 restat = GRBemptyenv(&reusegrbenv);
    1380 if ( restat != 0 )
    1381 {
    1382 SCIPmessagePrintWarning(messagehdlr, "Gurobi error %d: Something went wrong with creating the environment.\n", restat);
    1383 return SCIP_LPERROR;
    1384 }
    1385
    1386 /* turn off output for all models */
    1387 CHECK_ZERO_STAR( messagehdlr, GRBsetintparam(reusegrbenv, GRB_INT_PAR_OUTPUTFLAG, 0) );
    1388
    1389 CHECK_ZERO_STAR( messagehdlr, GRBstartenv(reusegrbenv) );
    1390#else
    1391 restat = GRBloadenv(&reusegrbenv, NULL);
    1392 if ( restat != 0 )
    1393 {
    1394 SCIPmessagePrintWarning(messagehdlr, "Gurobi error %d: Something went wrong with creating the environment.\n", restat);
    1395 return SCIP_LPERROR;
    1396 }
    1397
    1398 /* turn off output for all models */
    1399 CHECK_ZERO_STAR( messagehdlr, GRBsetintparam(reusegrbenv, GRB_INT_PAR_OUTPUTFLAG, 0) );
    1400#endif
    1401
    1402 /* turn on that basis information for infeasible and unbounded models is available */
    1403 CHECK_ZERO_STAR( messagehdlr, GRBsetintparam(reusegrbenv, GRB_INT_PAR_INFUNBDINFO, 1) );
    1404 }
    1405
    1406 /* create empty model */
    1407 CHECK_ZERO_STAR( messagehdlr, GRBnewmodel(reusegrbenv, &(*lpi)->grbmodel, name, 0, NULL, NULL, NULL, NULL, NULL) );
    1408
    1409 /* replace by local copy of environment */
    1410 (*lpi)->grbenv = GRBgetenv((*lpi)->grbmodel);
    1411
    1412 /* remember address of numlp and reusegrbenv, in case they are thread-local and SCIPlpiFree is called from different thread */
    1413 (*lpi)->numlp = &numlp;
    1414 (*lpi)->reusegrbenv = &reusegrbenv;
    1415 ++numlp;
    1416
    1417#else
    1418
    1419 /* Create new environment for each new instantiation; note that this involves additional work and
    1420 * uses a new license for each new instantiation. */
    1421#if GRB_VERSION_MAJOR >= 8
    1422 CHECK_ZERO_STAR( messagehdlr, GRBemptyenv(&(*lpi)->grbenv) );
    1423
    1424 /* turn off output for all models */
    1425 CHECK_ZERO_STAR( messagehdlr, GRBsetintparam((*lpi)->grbenv, GRB_INT_PAR_OUTPUTFLAG, 0) );
    1426
    1427 CHECK_ZERO_STAR( messagehdlr, GRBstartenv((*lpi)->grbenv) );
    1428#else
    1429 CHECK_ZERO_STAR( messagehdlr, GRBloadenv(&(*lpi)->grbenv, NULL) );
    1430
    1431 /* turn off output for all models */
    1432 CHECK_ZERO_STAR( messagehdlr, GRBsetintparam((*lpi)->grbenv, GRB_INT_PAR_OUTPUTFLAG, 0) );
    1433#endif
    1434
    1435 /* turn on that basis information for infeasible and unbounded models is available */
    1436 CHECK_ZERO_STAR( messagehdlr, GRBsetintparam((*lpi)->grbenv, GRB_INT_PAR_INFUNBDINFO, 1) );
    1437
    1438 /* create empty model */
    1439 CHECK_ZERO_STAR( messagehdlr, GRBnewmodel((*lpi)->grbenv, &(*lpi)->grbmodel, name, 0, NULL, NULL, NULL, NULL, NULL) );
    1440
    1441#endif
    1442 assert( (*lpi)->grbenv != NULL );
    1443
    1444 (*lpi)->senarray = NULL;
    1445 (*lpi)->rhsarray = NULL;
    1446 (*lpi)->rngarray = NULL;
    1447 (*lpi)->rngidxarray = NULL;
    1448 (*lpi)->valarray = NULL;
    1449 (*lpi)->cstat = NULL;
    1450 (*lpi)->rstat = NULL;
    1451 (*lpi)->indarray = NULL;
    1452 (*lpi)->rngrowmap = NULL;
    1453 (*lpi)->rngrows = NULL;
    1454 (*lpi)->rngvals = NULL;
    1455 (*lpi)->sidechgsize = 0;
    1456 (*lpi)->valsize = 0;
    1457 (*lpi)->cstatsize = 0;
    1458 (*lpi)->rstatsize = 0;
    1459 (*lpi)->rngrowmapsize = 0;
    1460 (*lpi)->nrngrows = 0;
    1461 (*lpi)->rngrowssize = 0;
    1462 (*lpi)->rngvarsadded = FALSE;
    1463 (*lpi)->iterations = 0;
    1464 (*lpi)->solisbasic = FALSE;
    1465 (*lpi)->fromscratch = FALSE;
    1466 (*lpi)->conditionlimit = -1.0;
    1467 (*lpi)->checkcondition = FALSE;
    1468 (*lpi)->pricing = SCIP_PRICING_LPIDEFAULT;
    1469 (*lpi)->messagehdlr = messagehdlr;
    1470 invalidateSolution(*lpi);
    1471
    1472 /* get default parameter values */
    1473 SCIP_CALL( getParameterValues((*lpi), &((*lpi)->defparam)) );
    1474 copyParameterValues(&((*lpi)->curparam), &((*lpi)->defparam));
    1475 copyParameterValues(&((*lpi)->grbparam), &((*lpi)->defparam));
    1476
    1477 /* set objective sense */
    1478 SCIP_CALL( SCIPlpiChgObjsen(*lpi, objsen) );
    1479
    1480 /* set default pricing */
    1481 SCIP_CALL( SCIPlpiSetIntpar(*lpi, SCIP_LPPAR_PRICING, (int) (*lpi)->pricing) );
    1482
    1483 checkRangeInfo(*lpi);
    1484
    1485 return SCIP_OKAY;
    1486}
    1487
    1488/** deletes an LP problem object */
    1490 SCIP_LPI** lpi /**< pointer to an LP interface structure */
    1491 )
    1492{
    1493 assert(lpi != NULL);
    1494 assert(*lpi != NULL);
    1495 assert((*lpi)->grbenv != NULL);
    1496
    1497 SCIPdebugMessage("SCIPlpiFree()\n");
    1498
    1499 /* free model */
    1500 CHECK_ZERO_STAR( (*lpi)->messagehdlr, GRBfreemodel((*lpi)->grbmodel) );
    1501
    1502 /* free memory */
    1503 BMSfreeMemoryArrayNull(&(*lpi)->senarray);
    1504 BMSfreeMemoryArrayNull(&(*lpi)->rhsarray);
    1505 BMSfreeMemoryArrayNull(&(*lpi)->rngarray);
    1506 BMSfreeMemoryArrayNull(&(*lpi)->rngidxarray);
    1507 BMSfreeMemoryArrayNull(&(*lpi)->cstat);
    1508 BMSfreeMemoryArrayNull(&(*lpi)->rstat);
    1509 BMSfreeMemoryArrayNull(&(*lpi)->rngrowmap);
    1510 BMSfreeMemoryArrayNull(&(*lpi)->rngrows);
    1511 BMSfreeMemoryArrayNull(&(*lpi)->rngvals);
    1512 BMSfreeMemoryArrayNull(&(*lpi)->indarray);
    1513 BMSfreeMemoryArrayNull(&(*lpi)->valarray);
    1514
    1515 /* free environment */
    1516#ifdef SCIP_REUSEENV
    1517 /* decrement the numlp that belongs to the thread where SCIPlpiCreate was called */
    1518 assert(*(*lpi)->numlp > 0);
    1519 --(*(*lpi)->numlp);
    1520 /* if numlp reached zero, then also free the Gurobi environment (that belongs to the thread where SCIPlpiCreate was called) */
    1521 if( *(*lpi)->numlp == 0 )
    1522 {
    1523 /* free reused environment */
    1524 GRBfreeenv(*(*lpi)->reusegrbenv);
    1525 *(*lpi)->reusegrbenv = NULL;
    1526 }
    1527#else
    1528 /* free local environment */
    1529 GRBfreeenv((*lpi)->grbenv);
    1530#endif
    1531
    1532 BMSfreeMemory(lpi);
    1533
    1534 return SCIP_OKAY;
    1535}
    1536
    1537/**@} */
    1538
    1539
    1540
    1541
    1542/*
    1543 * Modification Methods
    1544 */
    1545
    1546/**@name Modification Methods */
    1547/**@{ */
    1548
    1549/** copies LP data with column matrix into LP solver */
    1551 SCIP_LPI* lpi, /**< LP interface structure */
    1552 SCIP_OBJSEN objsen, /**< objective sense */
    1553 int ncols, /**< number of columns */
    1554 const SCIP_Real* obj, /**< objective function values of columns */
    1555 const SCIP_Real* lb, /**< lower bounds of columns */
    1556 const SCIP_Real* ub, /**< upper bounds of columns */
    1557 char** colnames, /**< column names, or NULL */
    1558 int nrows, /**< number of rows */
    1559 const SCIP_Real* lhs, /**< left hand sides of rows */
    1560 const SCIP_Real* rhs, /**< right hand sides of rows */
    1561 char** rownames, /**< row names, or NULL */
    1562 int nnonz, /**< number of nonzero elements in the constraint matrix */
    1563 const int* beg, /**< start index of each column in ind- and val-array */
    1564 const int* ind, /**< row indices of constraint matrix entries */
    1565 const SCIP_Real* val /**< values of constraint matrix entries */
    1566 )
    1567{
    1568 int grbobjsen;
    1569 int* cnt;
    1570 int rngcount;
    1571 int c;
    1572
    1573#ifndef NDEBUG
    1574 {
    1575 int j;
    1576 for( j = 0; j < nnonz; j++ )
    1577 assert( val[j] != 0 );
    1578 }
    1579#endif
    1580
    1581 assert(lpi != NULL);
    1582 assert(lpi->grbmodel != NULL);
    1583 assert(lpi->grbenv != NULL);
    1584 assert(obj != NULL);
    1585 assert(lb != NULL);
    1586 assert(ub != NULL);
    1587 assert(beg != NULL);
    1588 assert(ind != NULL);
    1589 assert(val != NULL);
    1590
    1591 assert(objsen == SCIP_OBJSEN_MAXIMIZE || objsen == SCIP_OBJSEN_MINIMIZE);
    1592
    1593 SCIPdebugMessage("loading LP in column format into Gurobi: %d cols, %d rows\n", ncols, nrows);
    1594
    1595 invalidateSolution(lpi);
    1596
    1597 SCIP_CALL( ensureSidechgMem(lpi, nrows) );
    1598
    1599 /* convert objective sense */
    1600 grbobjsen = (objsen == SCIP_OBJSEN_MINIMIZE) ? GRB_MINIMIZE : GRB_MAXIMIZE;
    1601
    1602 /* convert lhs/rhs into sen/rhs/range tuples */
    1603 SCIP_CALL( convertSides(lpi, nrows, lhs, rhs, &rngcount) );
    1604
    1605 /* calculate column lengths */
    1606 SCIP_ALLOC( BMSallocMemoryArray(&cnt, ncols) );
    1607 for( c = 0; c < ncols-1; ++c )
    1608 {
    1609 cnt[c] = beg[c+1] - beg[c];
    1610 assert(cnt[c] >= 0);
    1611 }
    1612 cnt[ncols-1] = nnonz - beg[ncols-1];
    1613 assert(cnt[ncols-1] >= 0);
    1614
    1615 /* load model - all variables are continuous */
    1616 CHECK_ZERO( lpi->messagehdlr, GRBloadmodel(lpi->grbenv, &(lpi->grbmodel), NULL, ncols, nrows, grbobjsen, 0.0, (SCIP_Real*)obj,
    1617 lpi->senarray, lpi->rhsarray, (int*)beg, cnt, (int*)ind, (SCIP_Real*)val, (SCIP_Real*)lb, (SCIP_Real*)ub, NULL, colnames, rownames) );
    1618
    1619 CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
    1620
    1621 /* free temporary memory */
    1622 BMSfreeMemoryArray(&cnt);
    1623
    1624 /* update maps for ranged rows */
    1625 if ( rngcount > 0 )
    1626 {
    1627 SCIP_CALL( addRangeInfo(lpi, rngcount, 0) );
    1628 }
    1629
    1630#ifndef NDEBUG
    1631 {
    1632 int temp;
    1633
    1634 SCIP_CALL( SCIPlpiGetNCols(lpi, &temp) );
    1635 assert(temp == ncols);
    1636
    1637 SCIP_CALL( SCIPlpiGetNRows(lpi, &temp) );
    1638 assert(temp == nrows);
    1639
    1640 SCIP_CALL( SCIPlpiGetNNonz(lpi, &temp) );
    1641 assert(temp == nnonz);
    1642 }
    1643#endif
    1644
    1645 checkRangeInfo(lpi);
    1646
    1647 return SCIP_OKAY;
    1648}
    1649
    1650/** adds columns to the LP */
    1652 SCIP_LPI* lpi, /**< LP interface structure */
    1653 int ncols, /**< number of columns to be added */
    1654 const SCIP_Real* obj, /**< objective function values of new columns */
    1655 const SCIP_Real* lb, /**< lower bounds of new columns */
    1656 const SCIP_Real* ub, /**< upper bounds of new columns */
    1657 char** colnames, /**< column names, or NULL */
    1658 int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
    1659 const int* beg, /**< start index of each column in ind- and val-array, or NULL if nnonz == 0 */
    1660 const int* ind, /**< row indices of constraint matrix entries, or NULL if nnonz == 0 */
    1661 const SCIP_Real* val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
    1662 )
    1663{
    1664 assert(lpi != NULL);
    1665 assert(lpi->grbmodel != NULL);
    1666 assert(obj != NULL);
    1667 assert(lb != NULL);
    1668 assert(ub != NULL);
    1669 assert(nnonz == 0 || beg != NULL);
    1670 assert(nnonz == 0 || ind != NULL);
    1671 assert(nnonz == 0 || val != NULL);
    1672 assert(nnonz >= 0);
    1673 assert(ncols >= 0);
    1674
    1675 SCIPdebugMessage("adding %d columns with %d nonzeros to Gurobi\n", ncols, nnonz);
    1676
    1677 invalidateSolution(lpi);
    1678
    1679#ifndef NDEBUG
    1680 if ( nnonz > 0 )
    1681 {
    1682 /* perform check that no new rows are added - this is forbidden */
    1683 int nrows;
    1684 int j;
    1685
    1686 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
    1687 for (j = 0; j < nnonz; ++j)
    1688 {
    1689 assert( 0 <= ind[j] && ind[j] < nrows );
    1690 assert( val[j] != 0.0 );
    1691 }
    1692 }
    1693#endif
    1694
    1695 /* delete range variables from Gurobi LP, so that structural variables always come first */
    1696 if ( lpi->nrngrows > 0 && lpi->rngvarsadded )
    1697 {
    1698 /**@todo Save and restore basis - currently, the basis is destroyed if we discard (and later re-add) range variables */
    1699 SCIP_CALL( delRangeVars(lpi) );
    1700 }
    1701
    1702 /* add columns - all new variables are continuous */
    1703 CHECK_ZERO( lpi->messagehdlr, GRBaddvars(lpi->grbmodel, ncols, nnonz, (int*)beg, (int*)ind, (SCIP_Real*)val,
    1704 (SCIP_Real*)obj, (SCIP_Real*)lb, (SCIP_Real*)ub, NULL, colnames) );
    1705 CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
    1706
    1707 checkRangeInfo(lpi);
    1708
    1709 return SCIP_OKAY;
    1710}
    1711
    1712/** deletes all columns in the given range from LP */
    1714 SCIP_LPI* lpi, /**< LP interface structure */
    1715 int firstcol, /**< first column to be deleted */
    1716 int lastcol /**< last column to be deleted */
    1717 )
    1718{
    1719 int ndelcols;
    1720 int* which;
    1721 int j;
    1722
    1723 assert(lpi != NULL);
    1724 assert(lpi->grbmodel != NULL);
    1725 assert(firstcol >= 0);
    1726 ndelcols = lastcol - firstcol + 1;
    1727 assert(ndelcols >= 0);
    1728#ifndef NDEBUG
    1729 {
    1730 int ncols;
    1731 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    1732 assert(lastcol < ncols);
    1733 }
    1734#endif
    1735
    1736 SCIPdebugMessage("deleting %d columns from Gurobi\n", ndelcols);
    1737
    1738 /* handle empty range */
    1739 if( ndelcols <= 0 )
    1740 return SCIP_OKAY;
    1741
    1742 invalidateSolution(lpi);
    1743
    1744 /* Gurobi can't delete a range of columns, we have to set up an index array */
    1745 SCIP_ALLOC( BMSallocMemoryArray(&which, ndelcols) );
    1746 for( j = firstcol; j <= lastcol; ++j )
    1747 which[j - firstcol] = j;
    1748
    1749 CHECK_ZERO( lpi->messagehdlr, GRBdelvars(lpi->grbmodel, ndelcols, which) );
    1750 CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
    1751
    1752 BMSfreeMemoryArray( &which );
    1753
    1754 checkRangeInfo(lpi);
    1755
    1756 return SCIP_OKAY;
    1757}
    1758
    1759/** deletes columns from LP; the new position of a column must not be greater that its old position */
    1761 SCIP_LPI* lpi, /**< LP interface structure */
    1762 int* dstat /**< deletion status of columns
    1763 * input: 1 if column should be deleted, 0 if not
    1764 * output: new position of column, -1 if column was deleted */
    1765 )
    1766{
    1767 int* which;
    1768 int ncols;
    1769 int num;
    1770 int j;
    1771
    1772 assert(lpi != NULL);
    1773 assert(lpi->grbmodel != NULL);
    1774 assert(dstat != NULL);
    1775
    1776 SCIPdebugMessage("deleting a column set from Gurobi\n");
    1777
    1778 invalidateSolution(lpi);
    1779
    1780 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    1781
    1782 /* Gurobi can't delete a set of marked columns, we have to set up an index array */
    1783 SCIP_ALLOC( BMSallocMemoryArray(&which, ncols) );
    1784 num = 0;
    1785 for( j = 0; j < ncols; ++j )
    1786 {
    1787 if( dstat[j] )
    1788 which[num++] = j;
    1789 }
    1790
    1791 CHECK_ZERO( lpi->messagehdlr, GRBdelvars(lpi->grbmodel, num, which) );
    1792 CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
    1793
    1794 /* update dstat */
    1795 num = 0;
    1796 for( j = 0; j < ncols; ++j )
    1797 {
    1798 if( dstat[j] )
    1799 {
    1800 dstat[j] = -1;
    1801 ++num;
    1802 }
    1803 else
    1804 dstat[j] = j - num;
    1805 }
    1806
    1807 BMSfreeMemoryArray( &which );
    1808
    1809 checkRangeInfo(lpi);
    1810
    1811 return SCIP_OKAY;
    1812}
    1813
    1814/** adds rows to the LP */
    1816 SCIP_LPI* lpi, /**< LP interface structure */
    1817 int nrows, /**< number of rows to be added */
    1818 const SCIP_Real* lhs, /**< left hand sides of new rows */
    1819 const SCIP_Real* rhs, /**< right hand sides of new rows */
    1820 char** rownames, /**< row names, or NULL */
    1821 int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
    1822 const int* beg, /**< start index of each row in ind- and val-array, or NULL if nnonz == 0 */
    1823 const int* ind, /**< column indices of constraint matrix entries, or NULL if nnonz == 0 */
    1824 const SCIP_Real* val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
    1825 )
    1826{
    1827 int rngcount;
    1828 int oldnrows = -1;
    1829
    1830 assert(lpi != NULL);
    1831 assert(lpi->grbmodel != NULL);
    1832 assert((lpi->nrngrows > 0) == (lpi->rngrowmap != NULL));
    1833 assert(lhs != NULL);
    1834 assert(rhs != NULL);
    1835 assert(nnonz == 0 || beg != NULL);
    1836 assert(nnonz == 0 || ind != NULL);
    1837 assert(nnonz == 0 || val != NULL);
    1838
    1839 SCIPdebugMessage("adding %d rows with %d nonzeros to Gurobi\n", nrows, nnonz);
    1840
    1841 invalidateSolution(lpi);
    1842
    1843#ifndef NDEBUG
    1844 if ( nnonz > 0 )
    1845 {
    1846 /* perform check that no new cols are added - this is forbidden */
    1847 int ncols;
    1848 int j;
    1849
    1850 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    1851 for (j = 0; j < nnonz; ++j) {
    1852 assert( 0 <= ind[j] && ind[j] < ncols );
    1853 assert( val[j] != 0.0 );
    1854 }
    1855 }
    1856#endif
    1857
    1858 SCIP_CALL( ensureSidechgMem(lpi, nrows) );
    1859
    1860 /* convert lhs/rhs into sen/rhs/range tuples */
    1861 SCIP_CALL( convertSides(lpi, nrows, lhs, rhs, &rngcount) );
    1862 if ( lpi->nrngrows > 0 || rngcount > 0 )
    1863 {
    1864 SCIP_CALL( SCIPlpiGetNRows(lpi, &oldnrows) );
    1865 }
    1866
    1867 /* add rows to LP */
    1868 CHECK_ZERO( lpi->messagehdlr, GRBaddconstrs(lpi->grbmodel, nrows, nnonz, (int*)beg, (int*)ind, (SCIP_Real*)val, lpi->senarray, lpi->rhsarray, rownames) );
    1869 CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
    1870
    1871 /* update maps for ranged rows */
    1872 if ( rngcount > 0 )
    1873 {
    1874 SCIP_CALL( addRangeInfo(lpi, rngcount, oldnrows) );
    1875 }
    1876 else if ( lpi->nrngrows > 0 )
    1877 {
    1878 int r;
    1879
    1880 /* extend existing rngrowmap array */
    1881 assert(lpi->rngrowmap != NULL);
    1882 assert(lpi->rngrows != NULL);
    1883 SCIP_CALL( ensureRngrowmapMem(lpi, oldnrows+nrows) );
    1884 for (r = oldnrows; r < oldnrows+nrows; r++)
    1885 lpi->rngrowmap[r] = -1;
    1886 }
    1887
    1888 checkRangeInfo(lpi);
    1889
    1890 return SCIP_OKAY;
    1891}
    1892
    1893/** deletes all rows in the given range from LP */
    1895 SCIP_LPI* lpi, /**< LP interface structure */
    1896 int firstrow, /**< first row to be deleted */
    1897 int lastrow /**< last row to be deleted */
    1898 )
    1899{
    1900 int ndelrows;
    1901 int* which;
    1902 int i;
    1903
    1904 assert(lpi != NULL);
    1905 assert(lpi->grbmodel != NULL);
    1906 assert(firstrow >= 0);
    1907 ndelrows = lastrow - firstrow + 1;
    1908 assert(ndelrows >= 0);
    1909#ifndef NDEBUG
    1910 {
    1911 int nrows;
    1912 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
    1913 assert(lastrow < nrows);
    1914 }
    1915#endif
    1916
    1917 SCIPdebugMessage("deleting %d rows from Gurobi\n", ndelrows);
    1918
    1919 /* handle empty range */
    1920 if( ndelrows <= 0 )
    1921 return SCIP_OKAY;
    1922
    1923 invalidateSolution(lpi);
    1924
    1925 /* Gurobi can't delete a range of rows, we have to set up an index array */
    1926 SCIP_ALLOC( BMSallocMemoryArray(&which, ndelrows) );
    1927 for( i = firstrow; i <= lastrow; ++i )
    1928 which[i - firstrow] = i;
    1929
    1930 CHECK_ZERO( lpi->messagehdlr, GRBdelconstrs(lpi->grbmodel, ndelrows, which) );
    1931 CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
    1932
    1933 BMSfreeMemoryArray( &which );
    1934
    1935 /* update ranged row info */
    1936 if ( lpi->nrngrows > 0 )
    1937 {
    1938 int nrngrows;
    1939 int nrows;
    1940
    1941 assert(lpi->rngrowmap != NULL);
    1942 assert(lpi->rngrows != NULL);
    1943
    1944 /* find first ranged row that has been deleted */
    1945 for (i = 0; i < lpi->nrngrows; i++)
    1946 {
    1947 if ( lpi->rngrows[i] >= firstrow )
    1948 break;
    1949 }
    1950 nrngrows = i;
    1951
    1952 /* skip all deleted ranged rows */
    1953 for (; i < lpi->nrngrows; i++)
    1954 {
    1955 if ( lpi->rngrows[i] > lastrow )
    1956 break;
    1957 }
    1958
    1959 /* move remaining ranged rows to the front */
    1960 for (; i < lpi->nrngrows; i++)
    1961 {
    1962 int oldrow = lpi->rngrows[i];
    1963 lpi->rngrowmap[oldrow] = nrngrows; /* store at old place for now */
    1964 lpi->rngrows[nrngrows] = oldrow - ndelrows;
    1965 lpi->rngvals[nrngrows] = lpi->rngvals[i];
    1966 nrngrows++;
    1967 }
    1968
    1969 if ( nrngrows < lpi->nrngrows && lpi->rngvarsadded )
    1970 {
    1971 /* For simplicity, just delete all range variables from Gurobi LP - it would suffice to only delete those
    1972 * corresponding to deleted ranged rows, but this should not matter much. */
    1973 SCIP_CALL( delRangeVars(lpi) );
    1974 }
    1975
    1976 lpi->nrngrows = nrngrows;
    1977
    1978 if ( nrngrows == 0 )
    1979 clearRangeInfo(lpi);
    1980 else
    1981 {
    1982 /* move rngrowmap entries */
    1983 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
    1984 for (i = firstrow; i < nrows; i++)
    1985 {
    1986 lpi->rngrowmap[i] = lpi->rngrowmap[i+ndelrows];
    1987 assert(-1 <= lpi->rngrowmap[i] && lpi->rngrowmap[i] < lpi->nrngrows);
    1988 }
    1989 }
    1990 }
    1991
    1992 checkRangeInfo(lpi);
    1993
    1994 return SCIP_OKAY;
    1995}
    1996
    1997/** deletes rows from SCIP_LP; the new position of a row must not be greater that its old position */
    1999 SCIP_LPI* lpi, /**< LP interface structure */
    2000 int* dstat /**< deletion status of rows
    2001 * input: 1 if row should be deleted, 0 if not
    2002 * output: new position of row, -1 if row was deleted */
    2003 )
    2004{
    2005 int i;
    2006 int num = 0;
    2007 int nrows;
    2008 int* which;
    2009
    2010 assert(lpi != NULL);
    2011 assert(lpi->grbmodel != NULL);
    2012
    2013 SCIPdebugMessage("deleting a row set from Gurobi\n");
    2014
    2015 invalidateSolution(lpi);
    2016
    2017 /* Gurobi can't delete a range of rows, we have to set up an index array */
    2018 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
    2019 SCIP_ALLOC( BMSallocMemoryArray(&which, nrows) );
    2020 for( i = 0; i < nrows; ++i )
    2021 {
    2022 if( dstat[i] )
    2023 which[num++] = i;
    2024 }
    2025 CHECK_ZERO( lpi->messagehdlr, GRBdelconstrs(lpi->grbmodel, num, which) );
    2026 CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
    2027
    2028 /* update dstat */
    2029 num = 0;
    2030 for( i = 0; i < nrows; ++i )
    2031 {
    2032 if( dstat[i] )
    2033 {
    2034 dstat[i] = -1;
    2035 ++num;
    2036 }
    2037 else
    2038 dstat[i] = i - num;
    2039 }
    2040
    2041 /* update ranged row info */
    2042 if ( lpi->nrngrows > 0 )
    2043 {
    2044 int nrngrows = 0;
    2045
    2046 assert(lpi->rngrowmap != NULL);
    2047 assert(lpi->rngrows != NULL);
    2048
    2049 for (i = 0; i < lpi->nrngrows; i++)
    2050 {
    2051 int oldrow = lpi->rngrows[i];
    2052 int newrow = dstat[oldrow];
    2053 if ( newrow >= 0 )
    2054 {
    2055 lpi->rngrowmap[oldrow] = nrngrows; /* store at old place for now */
    2056 lpi->rngrows[nrngrows] = newrow;
    2057 lpi->rngvals[nrngrows] = lpi->rngvals[i];
    2058 nrngrows++;
    2059 }
    2060 }
    2061
    2062 if ( nrngrows < lpi->nrngrows && lpi->rngvarsadded )
    2063 {
    2064 /* for simplicity, just delete all range variables from
    2065 * Gurobi LP - it would suffice to only delete those
    2066 * corresponding to deleted ranged rows, but this should
    2067 * not matter much
    2068 */
    2069 SCIP_CALL( delRangeVars(lpi) );
    2070 }
    2071
    2072 lpi->nrngrows = nrngrows;
    2073
    2074 if ( nrngrows == 0 )
    2075 clearRangeInfo(lpi);
    2076 else
    2077 {
    2078 /* move rngrowmap entries */
    2079 for (i = 0; i < nrows; i++)
    2080 {
    2081 int newrow = dstat[i];
    2082 assert(newrow <= i);
    2083 if ( newrow >= 0 )
    2084 {
    2085 lpi->rngrowmap[newrow] = lpi->rngrowmap[i];
    2086 assert(-1 <= lpi->rngrowmap[newrow] && lpi->rngrowmap[newrow] < lpi->nrngrows);
    2087 }
    2088 }
    2089 }
    2090 }
    2091
    2092 BMSfreeMemoryArray( &which );
    2093
    2094 checkRangeInfo(lpi);
    2095
    2096 return SCIP_OKAY;
    2097}
    2098
    2099/** clears the whole LP */
    2101 SCIP_LPI* lpi /**< LP interface structure */
    2102 )
    2103{
    2104 int nrows;
    2105 int ncols;
    2106
    2107 assert( lpi != NULL );
    2108 assert( lpi->grbmodel != NULL );
    2109 assert( lpi->grbenv != NULL );
    2110
    2111 SCIPdebugMessage("clearing Gurobi LP\n");
    2112
    2113 invalidateSolution(lpi);
    2114
    2115 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
    2116 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    2117
    2118 if ( nrows >= 1 )
    2119 {
    2120 SCIP_CALL( SCIPlpiDelRows(lpi, 0, nrows-1) );
    2121 }
    2122 if ( ncols >= 1 )
    2123 {
    2124 SCIP_CALL( SCIPlpiDelCols(lpi, 0, ncols-1) );
    2125 }
    2126
    2127#ifdef SCIP_DISABLED_CODE
    2128 /* the following seems to be slower */
    2129 CHECK_ZERO( lpi->messagehdlr, GRBfreemodel(lpi->grbmodel) );
    2130 CHECK_ZERO( lpi->messagehdlr, GRBnewmodel(lpi->grbenv, &(lpi->grbmodel), "", 0, NULL, NULL, NULL, NULL, NULL) );
    2131 CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
    2132#endif
    2133
    2134 /* clear ranged row info */
    2135 clearRangeInfo(lpi);
    2136
    2137 checkRangeInfo(lpi);
    2138
    2139 return SCIP_OKAY;
    2140}
    2141
    2142/** changes lower and upper bounds of columns */
    2144 SCIP_LPI* lpi, /**< LP interface structure */
    2145 int ncols, /**< number of columns to change bounds for */
    2146 const int* ind, /**< column indices or NULL if ncols is zero */
    2147 const SCIP_Real* lb, /**< values for the new lower bounds or NULL if ncols is zero */
    2148 const SCIP_Real* ub /**< values for the new upper bounds or NULL if ncols is zero*/
    2149 )
    2150{
    2151 int i;
    2152
    2153 assert(lpi != NULL);
    2154 assert(lpi->grbmodel != NULL);
    2155 assert(ncols == 0 || (ind != NULL && lb != NULL && ub != NULL));
    2156
    2157 SCIPdebugMessage("changing %d bounds in Gurobi\n", ncols);
    2158 if( ncols <= 0 )
    2159 return SCIP_OKAY;
    2160
    2161 for (i = 0; i < ncols; ++i)
    2162 {
    2163 SCIPdebugPrintf(" col %d: [%g,%g]\n", ind[i], lb[i], ub[i]);
    2164
    2165 if ( SCIPlpiIsInfinity(lpi, lb[i]) )
    2166 {
    2167 SCIPerrorMessage("LP Error: fixing lower bound for variable %d to infinity.\n", ind[i]);
    2168 return SCIP_LPERROR;
    2169 }
    2170 if ( SCIPlpiIsInfinity(lpi, -ub[i]) )
    2171 {
    2172 SCIPerrorMessage("LP Error: fixing upper bound for variable %d to -infinity.\n", ind[i]);
    2173 return SCIP_LPERROR;
    2174 }
    2175 }
    2176
    2177 invalidateSolution(lpi);
    2178
    2179 CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrlist(lpi->grbmodel, GRB_DBL_ATTR_LB, ncols, (int*)ind, (SCIP_Real*)lb) );
    2180 CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrlist(lpi->grbmodel, GRB_DBL_ATTR_UB, ncols, (int*)ind, (SCIP_Real*)ub) );
    2181
    2182 CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
    2183
    2184 checkRangeInfo(lpi);
    2185
    2186 return SCIP_OKAY;
    2187}
    2188
    2189/** changes left and right hand sides of rows */
    2191 SCIP_LPI* lpi, /**< LP interface structure */
    2192 int nrows, /**< number of rows to change sides for */
    2193 const int* ind, /**< row indices */
    2194 const SCIP_Real* lhs, /**< new values for left hand sides */
    2195 const SCIP_Real* rhs /**< new values for right hand sides */
    2196 )
    2197{
    2198 int rngcount;
    2199
    2200 assert(lpi != NULL);
    2201 assert(lpi->grbmodel != NULL);
    2202 assert(ind != NULL);
    2203
    2204 SCIPdebugMessage("changing %d sides in Gurobi\n", nrows);
    2205 if( nrows <= 0)
    2206 return SCIP_OKAY;
    2207
    2208 invalidateSolution(lpi);
    2209
    2210 /* convert lhs/rhs into sen/rhs/range tuples */
    2211 SCIP_CALL( ensureSidechgMem(lpi, nrows) );
    2212 SCIP_CALL( convertSides(lpi, nrows, lhs, rhs, &rngcount) );
    2213
    2214 /* change row sides */
    2215 CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrlist(lpi->grbmodel, GRB_DBL_ATTR_RHS, nrows, (int*)ind, lpi->rhsarray) );
    2216 CHECK_ZERO( lpi->messagehdlr, GRBsetcharattrlist(lpi->grbmodel, GRB_CHAR_ATTR_SENSE, nrows, (int*)ind, lpi->senarray) );
    2217
    2218 CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
    2219
    2220 /* update ranged row info */
    2221 if ( rngcount > 0 || lpi->nrngrows > 0 )
    2222 {
    2223 int modified = 0;
    2224 int nnewrngrows = 0;
    2225 int ntotrows;
    2226 int ncols;
    2227 int i;
    2228
    2229 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    2230 SCIP_CALL( SCIPlpiGetNRows(lpi, &ntotrows) );
    2231
    2232 SCIP_CALL( ensureRngrowmapMem(lpi, ntotrows) );
    2233
    2234 for (i = 0; i < nrows; i++)
    2235 {
    2236 int rngrowidx;
    2237 int row;
    2238
    2239 row = ind[i];
    2240 rngrowidx = lpi->rngrowmap[row];
    2241
    2242 assert(-1 <= rngrowidx && rngrowidx < lpi->nrngrows);
    2243
    2244 if ( lpi->senarray[i] == GRB_EQUAL && lpi->rngarray[i] > 0.0 )
    2245 {
    2246 /* row is (now) a ranged row */
    2247 if ( rngrowidx >= 0 )
    2248 {
    2249 /* row was already a ranged row: just update rngval and ub of associated column */
    2250 lpi->rngvals[rngrowidx] = lpi->rngarray[i];
    2251 if ( !modified && lpi->rngvarsadded )
    2252 {
    2253 CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_UB, ncols+rngrowidx, lpi->rngvals[rngrowidx]) );
    2254 }
    2255 }
    2256 else
    2257 {
    2258 /* row was not ranged before: we need to reset range variables */
    2259 modified = 1;
    2260
    2261 /* for now, add row to end of rngrows/rngvals arrays */
    2262 SCIP_CALL( ensureRngrowsMem(lpi, lpi->nrngrows + nnewrngrows + 1) );
    2263 lpi->rngrowmap[row] = lpi->nrngrows + nnewrngrows;
    2264 lpi->rngrows[lpi->nrngrows + nnewrngrows] = row;
    2265 lpi->rngvals[lpi->nrngrows + nnewrngrows] = lpi->rngarray[i];
    2266 nnewrngrows++;
    2267 }
    2268 }
    2269 else
    2270 {
    2271 /* row is not (no longer) a ranged row */
    2272 if ( rngrowidx >= 0 )
    2273 {
    2274 /* row was a ranged row before: we need to reset range variables */
    2275 modified = 1;
    2276 lpi->rngrowmap[row] = -1;
    2277 }
    2278 }
    2279 }
    2280
    2281 if ( modified )
    2282 {
    2283 int nrngrows = 0;
    2284
    2285 /* the range status of at least one row changed: discard range variables */
    2286 if ( lpi->rngvarsadded )
    2287 {
    2288 /**@todo Save and restore basis - currently, the basis is destroyed if we discard (and later re-add) range variables */
    2289 SCIP_CALL( delRangeVars(lpi) );
    2290 }
    2291 assert(!lpi->rngvarsadded);
    2292
    2293 if ( nnewrngrows > 0 )
    2294 {
    2295 /* integrate new ranged rows into arrays */
    2296 lpi->nrngrows += nnewrngrows;
    2297 SCIPsortIntReal(lpi->rngrows, lpi->rngvals, lpi->nrngrows);
    2298 }
    2299
    2300 /* update rngrowmap and discard rows that are no longer ranged */
    2301 for (i = 0; i < lpi->nrngrows; i++)
    2302 {
    2303 int row = lpi->rngrows[i];
    2304 if ( lpi->rngrowmap[row] >= 0 )
    2305 {
    2306 lpi->rngrowmap[row] = nrngrows;
    2307 lpi->rngrows[nrngrows] = row;
    2308 lpi->rngvals[nrngrows] = lpi->rngvals[i];
    2309 nrngrows++;
    2310 }
    2311 }
    2312 lpi->nrngrows = nrngrows;
    2313
    2314 /* discard ranged row info if no ranged rows remain */
    2315 if ( nrngrows == 0 )
    2316 clearRangeInfo(lpi);
    2317 }
    2318 }
    2319
    2320 checkRangeInfo(lpi);
    2321
    2322 return SCIP_OKAY;
    2323}
    2324
    2325/** changes a single coefficient */
    2327 SCIP_LPI* lpi, /**< LP interface structure */
    2328 int row, /**< row number of coefficient to change */
    2329 int col, /**< column number of coefficient to change */
    2330 SCIP_Real newval /**< new value of coefficient */
    2331 )
    2332{
    2333 assert(lpi != NULL);
    2334 assert(lpi->grbmodel != NULL);
    2335
    2336 SCIPdebugMessage("changing coefficient row %d, column %d in Gurobi to %g\n", row, col, newval);
    2337
    2338 invalidateSolution(lpi);
    2339
    2340 CHECK_ZERO( lpi->messagehdlr, GRBchgcoeffs(lpi->grbmodel, 1, &row, &col, &newval) );
    2341 CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
    2342
    2343 return SCIP_OKAY;
    2344}
    2345
    2346/** changes the objective sense */
    2348 SCIP_LPI* lpi, /**< LP interface structure */
    2349 SCIP_OBJSEN objsen /**< new objective sense */
    2350 )
    2351{
    2352 int grbobjsen;
    2353
    2354 assert(lpi != NULL);
    2355 assert(lpi->grbmodel != NULL);
    2356 assert(objsen == SCIP_OBJSEN_MAXIMIZE || objsen == SCIP_OBJSEN_MINIMIZE);
    2357
    2358 /* convert objective sense */
    2359 grbobjsen = (objsen == SCIP_OBJSEN_MINIMIZE) ? GRB_MINIMIZE : GRB_MAXIMIZE;
    2360
    2361 SCIPdebugMessage("changing objective sense in Gurobi to %d\n", grbobjsen);
    2362
    2363 invalidateSolution(lpi);
    2364
    2365 /* The objective sense of Gurobi and SCIP are equal */
    2366 CHECK_ZERO( lpi->messagehdlr, GRBsetintattr(lpi->grbmodel, GRB_INT_ATTR_MODELSENSE, grbobjsen) );
    2367 CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
    2368
    2369 return SCIP_OKAY;
    2370}
    2371
    2372/** changes objective values of columns in the LP */
    2374 SCIP_LPI* lpi, /**< LP interface structure */
    2375 int ncols, /**< number of columns to change objective value for */
    2376 const int* ind, /**< column indices to change objective value for */
    2377 const SCIP_Real* obj /**< new objective values for columns */
    2378 )
    2379{
    2380 assert(lpi != NULL);
    2381 assert(lpi->grbmodel != NULL);
    2382 assert(ind != NULL);
    2383 assert(obj != NULL);
    2384
    2385 SCIPdebugMessage("changing %d objective values in Gurobi\n", ncols);
    2386
    2387 invalidateSolution(lpi);
    2388
    2389 CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrlist(lpi->grbmodel, GRB_DBL_ATTR_OBJ, ncols, (int*)ind, (SCIP_Real*)obj) );
    2390 CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
    2391
    2392 return SCIP_OKAY;
    2393}
    2394
    2395/** multiplies a row with a non-zero scalar; for negative scalars, the row's sense is switched accordingly */
    2397 SCIP_LPI* lpi, /**< LP interface structure */
    2398 int row, /**< row number to scale */
    2399 SCIP_Real scaleval /**< scaling multiplier */
    2400 )
    2401{
    2402 SCIP_Real lhs;
    2403 SCIP_Real rhs;
    2404 int nnonz;
    2405 int ncols;
    2406 int beg;
    2407 int i;
    2408
    2409 assert(lpi != NULL);
    2410 assert(lpi->grbmodel != NULL);
    2411 assert(scaleval != 0.0);
    2412
    2413 SCIPdebugMessage("scaling row %d with factor %g in Gurobi\n", row, scaleval);
    2414
    2415 invalidateSolution(lpi);
    2416
    2417 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    2418 SCIP_CALL( ensureValMem(lpi, ncols+1) ); /* +1 for range variable */
    2419
    2420 /* get the row */
    2421 SCIP_CALL( SCIPlpiGetRows(lpi, row, row, &lhs, &rhs, &nnonz, &beg, lpi->indarray, lpi->valarray) );
    2422
    2423 /* scale row coefficients */
    2424 for ( i = 0; i < nnonz; ++i )
    2425 {
    2426 SCIP_CALL( SCIPlpiChgCoef(lpi, row, lpi->indarray[i], lpi->valarray[i] * scaleval) );
    2427 }
    2428
    2429 /* scale row sides */
    2430 if( lhs > -GRB_INFINITY )
    2431 lhs *= scaleval;
    2432 else if( scaleval < 0.0 )
    2433 lhs = GRB_INFINITY;
    2434 if( rhs < GRB_INFINITY )
    2435 rhs *= scaleval;
    2436 else if( scaleval < 0.0 )
    2437 rhs = -GRB_INFINITY;
    2438 if( scaleval > 0.0 )
    2439 {
    2440 SCIP_CALL( SCIPlpiChgSides(lpi, 1, &row, &lhs, &rhs) );
    2441 }
    2442 else
    2443 {
    2444 SCIP_CALL( SCIPlpiChgSides(lpi, 1, &row, &rhs, &lhs) );
    2445 }
    2446
    2447 checkRangeInfo(lpi);
    2448
    2449 return SCIP_OKAY;
    2450}
    2451
    2452/** multiplies a column with a non-zero scalar; the objective value is multiplied with the scalar, and the bounds
    2453 * are divided by the scalar; for negative scalars, the column's bounds are switched
    2454 */
    2456 SCIP_LPI* lpi, /**< LP interface structure */
    2457 int col, /**< column number to scale */
    2458 SCIP_Real scaleval /**< scaling multiplier */
    2459 )
    2460{
    2461 SCIP_Real lb;
    2462 SCIP_Real ub;
    2463 SCIP_Real obj;
    2464 int nnonz;
    2465 int nrows;
    2466 int beg;
    2467 int i;
    2468
    2469 assert(lpi != NULL);
    2470 assert(lpi->grbmodel != NULL);
    2471 assert(scaleval != 0.0);
    2472
    2473 SCIPdebugMessage("scaling column %d with factor %g in Gurobi\n", col, scaleval);
    2474
    2475 invalidateSolution(lpi);
    2476
    2477 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
    2478 SCIP_CALL( ensureValMem(lpi, nrows) );
    2479
    2480 /* get the column */
    2481 SCIP_CALL( SCIPlpiGetCols(lpi, col, col, &lb, &ub, &nnonz, &beg, lpi->indarray, lpi->valarray) );
    2482
    2483 /* get objective coefficient */
    2484 SCIP_CALL( SCIPlpiGetObj(lpi, col, col, &obj) );
    2485
    2486 /* scale column coefficients */
    2487 for( i = 0; i < nnonz; ++i )
    2488 {
    2489 SCIP_CALL( SCIPlpiChgCoef(lpi, lpi->indarray[i], col, lpi->valarray[i] * scaleval) );
    2490 }
    2491
    2492 /* scale objective value */
    2493 obj *= scaleval;
    2494 SCIP_CALL( SCIPlpiChgObj(lpi, 1, &col, &obj) );
    2495
    2496 /* scale column bounds */
    2497 if( lb > -GRB_INFINITY )
    2498 lb /= scaleval;
    2499 else if( scaleval < 0.0 )
    2500 lb = GRB_INFINITY;
    2501 if( ub < GRB_INFINITY )
    2502 ub /= scaleval;
    2503 else if( scaleval < 0.0 )
    2504 ub = -GRB_INFINITY;
    2505 if( scaleval > 0.0 )
    2506 {
    2507 SCIP_CALL( SCIPlpiChgBounds(lpi, 1, &col, &lb, &ub) );
    2508 }
    2509 else
    2510 {
    2511 SCIP_CALL( SCIPlpiChgBounds(lpi, 1, &col, &ub, &lb) );
    2512 }
    2513
    2514 checkRangeInfo(lpi);
    2515
    2516 return SCIP_OKAY;
    2517}
    2518
    2519/**@} */
    2520
    2521
    2522
    2523
    2524/*
    2525 * Data Accessing Methods
    2526 */
    2527
    2528/**@name Data Accessing Methods */
    2529/**@{ */
    2530
    2531/** gets the number of rows in the LP */
    2533 SCIP_LPI* lpi, /**< LP interface structure */
    2534 int* nrows /**< pointer to store the number of rows */
    2535 )
    2536{
    2537 assert(lpi != NULL);
    2538 assert(lpi->grbmodel != NULL);
    2539 assert(nrows != NULL);
    2540
    2541 SCIPdebugMessage("getting number of rows\n");
    2542
    2543 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMCONSTRS, nrows) );
    2544
    2545 return SCIP_OKAY;
    2546}
    2547
    2548/** gets the number of columns in the LP */
    2550 SCIP_LPI* lpi, /**< LP interface structure */
    2551 int* ncols /**< pointer to store the number of cols */
    2552 )
    2553{
    2554 assert(lpi != NULL);
    2555 assert(lpi->grbmodel != NULL);
    2556 assert(ncols != NULL);
    2557
    2558 SCIPdebugMessage("getting number of columns\n");
    2559
    2560 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMVARS, ncols) );
    2561
    2562 /* subtract number of ranged rows, as these are the LPI internal columns */
    2563 if ( lpi->rngvarsadded )
    2564 (*ncols) -= lpi->nrngrows;
    2565
    2566 return SCIP_OKAY;
    2567}
    2568
    2569/** gets the number of nonzero elements in the LP constraint matrix */
    2571 SCIP_LPI* lpi, /**< LP interface structure */
    2572 int* nnonz /**< pointer to store the number of nonzeros */
    2573 )
    2574{
    2575 assert(lpi != NULL);
    2576 assert(lpi->grbmodel != NULL);
    2577 assert(nnonz != NULL);
    2578
    2579 SCIPdebugMessage("getting number of non-zeros\n");
    2580
    2581 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMNZS, nnonz) );
    2582
    2583 /* subtract number of ranged rows, as these are non-zeros for the LPI internal columns */
    2584 if ( lpi->rngvarsadded )
    2585 (*nnonz) -= lpi->nrngrows;
    2586
    2587 return SCIP_OKAY;
    2588}
    2589
    2590/** gets columns from LP problem object; the arrays have to be large enough to store all values;
    2591 * Either both, lb and ub, have to be NULL, or both have to be non-NULL,
    2592 * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
    2593 */
    2595 SCIP_LPI* lpi, /**< LP interface structure */
    2596 int firstcol, /**< first column to get from LP */
    2597 int lastcol, /**< last column to get from LP */
    2598 SCIP_Real* lb, /**< buffer to store the lower bound vector, or NULL */
    2599 SCIP_Real* ub, /**< buffer to store the upper bound vector, or NULL */
    2600 int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
    2601 int* beg, /**< buffer to store start index of each column in ind- and val-array, or NULL */
    2602 int* ind, /**< buffer to store row indices of constraint matrix entries, or NULL */
    2603 SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
    2604 )
    2605{
    2606 assert(lpi != NULL);
    2607 assert(lpi->grbmodel != NULL);
    2608 assert((lb != NULL && ub != NULL) || (lb == NULL && ub == NULL));
    2609 assert((nnonz != NULL && beg != NULL && ind != NULL && val != NULL) || (nnonz == NULL && beg == NULL && ind == NULL && val == NULL));
    2610 assert(firstcol >= 0);
    2611 assert(firstcol <= lastcol + 1);
    2612#ifndef NDEBUG
    2613 {
    2614 int ncols;
    2615 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    2616 assert(lastcol < ncols);
    2617 }
    2618#endif
    2619
    2620 SCIPdebugMessage("getting columns %d to %d\n", firstcol, lastcol);
    2621
    2622 if( lb != NULL )
    2623 {
    2624 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_LB, firstcol, lastcol-firstcol+1, lb) );
    2625 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_UB, firstcol, lastcol-firstcol+1, ub) );
    2626 }
    2627
    2628 if( nnonz != NULL )
    2629 {
    2630 /* get matrix entries */
    2631 CHECK_ZERO( lpi->messagehdlr, GRBgetvars(lpi->grbmodel, nnonz, beg, ind, val, firstcol, lastcol-firstcol+1) );
    2632 }
    2633
    2634 return SCIP_OKAY;
    2635}
    2636
    2637/** gets rows from LP problem object; the arrays have to be large enough to store all values.
    2638 * Either both, lhs and rhs, have to be NULL, or both have to be non-NULL,
    2639 * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
    2640 */
    2642 SCIP_LPI* lpi, /**< LP interface structure */
    2643 int firstrow, /**< first row to get from LP */
    2644 int lastrow, /**< last row to get from LP */
    2645 SCIP_Real* lhs, /**< buffer to store left hand side vector, or NULL */
    2646 SCIP_Real* rhs, /**< buffer to store right hand side vector, or NULL */
    2647 int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
    2648 int* beg, /**< buffer to store start index of each row in ind- and val-array, or NULL */
    2649 int* ind, /**< buffer to store column indices of constraint matrix entries, or NULL */
    2650 SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
    2651 )
    2652{
    2653 assert(lpi != NULL);
    2654 assert(lpi->grbmodel != NULL);
    2655 assert((lhs == NULL && rhs == NULL) || (rhs != NULL && lhs != NULL));
    2656 assert((nnonz != NULL && beg != NULL && ind != NULL && val != NULL) || (nnonz == NULL && beg == NULL && ind == NULL && val == NULL));
    2657 assert(firstrow >= 0);
    2658 assert(firstrow <= lastrow + 1);
    2659#ifndef NDEBUG
    2660 {
    2661 int nrows;
    2662 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
    2663 assert(lastrow < nrows);
    2664 }
    2665#endif
    2666
    2667 SCIPdebugMessage("getting rows %d to %d\n", firstrow, lastrow);
    2668
    2669 if( lhs != NULL )
    2670 {
    2671 /* get row sense and rhs */
    2672 SCIP_CALL( ensureSidechgMem(lpi, lastrow - firstrow + 1) );
    2673 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_RHS, firstrow, lastrow-firstrow+1, lpi->rhsarray) );
    2674 CHECK_ZERO( lpi->messagehdlr, GRBgetcharattrarray(lpi->grbmodel, GRB_CHAR_ATTR_SENSE, firstrow, lastrow-firstrow+1, lpi->senarray) );
    2675
    2676 /* convert sen and rhs into lhs/rhs tuples */
    2677 SCIP_CALL( reconvertSides(lpi, firstrow, lastrow, lhs, rhs) );
    2678 }
    2679
    2680 if( nnonz != NULL )
    2681 {
    2682 assert(beg != NULL && ind != NULL && val != NULL); /* for lint */
    2683
    2684 /* get matrix entries */
    2685 CHECK_ZERO( lpi->messagehdlr, GRBgetconstrs(lpi->grbmodel, nnonz, beg, ind, val, firstrow, lastrow-firstrow+1) );
    2686
    2687 if( lpi->rngvarsadded )
    2688 {
    2689 int i;
    2690
    2691 assert(lpi->rngrowmap != NULL);
    2692 assert(lpi->rngrows != NULL);
    2693
    2694 /* remove non-zeros for range variables from rows */
    2695 for( i = firstrow; i <= lastrow; i++ )
    2696 {
    2697 assert(-1 <= lpi->rngrowmap[i] && lpi->rngrowmap[i] < lpi->nrngrows);
    2698 if( lpi->rngrowmap[i] >= 0 )
    2699 break;
    2700 }
    2701 if( i <= lastrow )
    2702 {
    2703 /* skip last non-zero of this first ranged row */
    2704 int newnz = (i < lastrow ? beg[i - firstrow +1]-1 : (*nnonz)-1); /*lint !e661*/
    2705
    2706 /* process remaining rows, moving non-zeros to the front */
    2707 for( ; i <= lastrow; i++ )
    2708 {
    2709 int thebeg;
    2710 int theend;
    2711
    2712 assert(i >= firstrow);
    2713 thebeg = beg[i - firstrow]; /*lint !e661*/
    2714 theend = (i < lastrow ? beg[i - firstrow +1] : *nnonz);
    2715
    2716 assert(-1 <= lpi->rngrowmap[i] && lpi->rngrowmap[i] < lpi->nrngrows);
    2717 if( lpi->rngrowmap[i] >= 0 )
    2718 theend--;
    2719
    2720 assert(theend >= thebeg);
    2721 memmove(&ind[newnz], &ind[thebeg], ((size_t) (theend - thebeg)) * sizeof(*ind)); /*lint !e776 !e571*/
    2722 memmove(&val[newnz], &val[thebeg], ((size_t) (theend - thebeg)) * sizeof(*val)); /*lint !e776 !e571*/
    2723 beg[i - firstrow] = newnz; /*lint !e661*/
    2724 newnz += theend - thebeg;
    2725 }
    2726 assert(newnz < *nnonz);
    2727 *nnonz = newnz;
    2728 }
    2729 }
    2730 }
    2731
    2732 return SCIP_OKAY;
    2733}
    2734
    2735/** gets column names */
    2737 SCIP_LPI* lpi, /**< LP interface structure */
    2738 int firstcol, /**< first column to get name from LP */
    2739 int lastcol, /**< last column to get name from LP */
    2740 char** colnames, /**< pointers to column names (of size at least lastcol-firstcol+1) or NULL if namestoragesize is zero */
    2741 char* namestorage, /**< storage for col names or NULL if namestoragesize is zero */
    2742 int namestoragesize, /**< size of namestorage (if 0, storageleft returns the storage needed) */
    2743 int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) or NULL if namestoragesize is zero */
    2744 )
    2745{ /*lint --e{715}*/
    2746 assert(lpi != NULL);
    2747 assert(lpi->grbmodel != NULL);
    2748 assert(colnames != NULL || namestoragesize == 0);
    2749 assert(namestorage != NULL || namestoragesize == 0);
    2750 assert(namestoragesize >= 0);
    2751 assert(storageleft != NULL);
    2752 assert(firstcol >= 0);
    2753 assert(firstcol <= lastcol + 1);
    2754#ifndef NDEBUG
    2755 {
    2756 int ncols;
    2757 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    2758 assert(lastcol < ncols);
    2759 }
    2760#endif
    2761
    2762 SCIPerrorMessage("SCIPlpiGetColNames() has not been implemented yet.\n");
    2763
    2764 return SCIP_LPERROR;
    2765}
    2766
    2767/** gets row names */
    2769 SCIP_LPI* lpi, /**< LP interface structure */
    2770 int firstrow, /**< first row to get name from LP */
    2771 int lastrow, /**< last row to get name from LP */
    2772 char** rownames, /**< pointers to row names (of size at least lastrow-firstrow+1) or NULL if namestoragesize is zero */
    2773 char* namestorage, /**< storage for row names or NULL if namestoragesize is zero */
    2774 int namestoragesize, /**< size of namestorage (if 0, -storageleft returns the storage needed) */
    2775 int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) or NULL if namestoragesize is zero */
    2776 )
    2777{ /*lint --e{715}*/
    2778 assert(lpi != NULL);
    2779 assert(lpi->grbmodel != NULL);
    2780 assert(rownames != NULL || namestoragesize == 0);
    2781 assert(namestorage != NULL || namestoragesize == 0);
    2782 assert(namestoragesize >= 0);
    2783 assert(storageleft != NULL);
    2784 assert(firstrow >= 0);
    2785 assert(firstrow <= lastrow + 1);
    2786#ifndef NDEBUG
    2787 {
    2788 int nrows;
    2789 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
    2790 assert(lastrow < nrows);
    2791 }
    2792#endif
    2793
    2794 SCIPerrorMessage("SCIPlpiGetRowNames() has not been implemented yet.\n");
    2795
    2796 return SCIP_LPERROR;
    2797}
    2798
    2799/** gets the objective sense of the LP */
    2801 SCIP_LPI* lpi, /**< LP interface structure */
    2802 SCIP_OBJSEN* objsen /**< pointer to store objective sense */
    2803 )
    2804{
    2805 int grbobjsen;
    2806
    2807 assert( lpi != NULL );
    2808 assert( lpi->grbmodel != NULL );
    2809 assert( objsen != NULL );
    2810
    2811 SCIPdebugMessage("getting objective sense\n");
    2812
    2813 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_MODELSENSE, &grbobjsen) );
    2814 assert(grbobjsen == GRB_MINIMIZE || grbobjsen == GRB_MAXIMIZE);
    2815
    2816 *objsen = (grbobjsen == GRB_MINIMIZE) ? SCIP_OBJSEN_MINIMIZE : SCIP_OBJSEN_MAXIMIZE;
    2817
    2818 return SCIP_OKAY;
    2819}
    2820
    2821/** gets objective coefficients from LP problem object */
    2823 SCIP_LPI* lpi, /**< LP interface structure */
    2824 int firstcol, /**< first column to get objective coefficient for */
    2825 int lastcol, /**< last column to get objective coefficient for */
    2826 SCIP_Real* vals /**< array to store objective coefficients */
    2827 )
    2828{
    2829 assert(lpi != NULL);
    2830 assert(lpi->grbmodel != NULL);
    2831 assert(vals != NULL);
    2832 assert(firstcol >= 0);
    2833 assert(firstcol <= lastcol + 1);
    2834#ifndef NDEBUG
    2835 {
    2836 int ncols;
    2837 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    2838 assert(lastcol < ncols);
    2839 }
    2840#endif
    2841
    2842 SCIPdebugMessage("getting objective values %d to %d\n", firstcol, lastcol);
    2843
    2844 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_OBJ, firstcol, lastcol-firstcol+1, vals) );
    2845
    2846 return SCIP_OKAY;
    2847}
    2848
    2849/** gets current bounds from LP problem object */
    2851 SCIP_LPI* lpi, /**< LP interface structure */
    2852 int firstcol, /**< first column to get bounds for */
    2853 int lastcol, /**< last column to get bounds for */
    2854 SCIP_Real* lbs, /**< array to store lower bound values, or NULL */
    2855 SCIP_Real* ubs /**< array to store upper bound values, or NULL */
    2856 )
    2857{
    2858 assert(lpi != NULL);
    2859 assert(lpi->grbmodel != NULL);
    2860 assert(firstcol >= 0);
    2861 assert(firstcol <= lastcol + 1);
    2862#ifndef NDEBUG
    2863 {
    2864 int ncols;
    2865 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    2866 assert(lastcol < ncols);
    2867 }
    2868#endif
    2869
    2870 SCIPdebugMessage("getting bounds %d to %d\n", firstcol, lastcol);
    2871
    2872 if( lbs != NULL )
    2873 {
    2874 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_LB, firstcol, lastcol-firstcol+1, lbs) );
    2875 }
    2876
    2877 if( ubs != NULL )
    2878 {
    2879 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_UB, firstcol, lastcol-firstcol+1, ubs) );
    2880 }
    2881
    2882 return SCIP_OKAY;
    2883}
    2884
    2885/** gets current row sides from LP problem object */
    2887 SCIP_LPI* lpi, /**< LP interface structure */
    2888 int firstrow, /**< first row to get sides for */
    2889 int lastrow, /**< last row to get sides for */
    2890 SCIP_Real* lhss, /**< array to store left hand side values, or NULL */
    2891 SCIP_Real* rhss /**< array to store right hand side values, or NULL */
    2892 )
    2893{
    2894 assert(lpi != NULL);
    2895 assert(lpi->grbmodel != NULL);
    2896 assert(firstrow >= 0);
    2897 assert(firstrow <= lastrow + 1);
    2898#ifndef NDEBUG
    2899 {
    2900 int nrows;
    2901 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
    2902 assert(lastrow < nrows);
    2903 }
    2904#endif
    2905
    2906 SCIPdebugMessage("getting row sides %d to %d\n", firstrow, lastrow);
    2907
    2908 /* get row sense, rhs, and ranges */
    2909 SCIP_CALL( ensureSidechgMem(lpi, lastrow - firstrow + 1) );
    2910
    2911 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_RHS, firstrow, lastrow-firstrow+1, lpi->rhsarray) );
    2912 CHECK_ZERO( lpi->messagehdlr, GRBgetcharattrarray(lpi->grbmodel, GRB_CHAR_ATTR_SENSE, firstrow, lastrow-firstrow+1, lpi->senarray) );
    2913
    2914 /* convert sen and rhs into lhs/rhs tuples */
    2915 SCIP_CALL( reconvertSides(lpi, firstrow, lastrow, lhss, rhss) );
    2916
    2917 return SCIP_OKAY;
    2918}
    2919
    2920/** gets a single coefficient */
    2922 SCIP_LPI* lpi, /**< LP interface structure */
    2923 int row, /**< row number of coefficient */
    2924 int col, /**< column number of coefficient */
    2925 SCIP_Real* val /**< pointer to store the value of the coefficient */
    2926 )
    2927{
    2928 assert(lpi != NULL);
    2929 assert(lpi->grbmodel != NULL);
    2930 assert(val != NULL);
    2931
    2932 SCIPdebugMessage("getting coefficient of row %d col %d\n", row, col);
    2933
    2934 CHECK_ZERO( lpi->messagehdlr, GRBgetcoeff(lpi->grbmodel, row, col, val) );
    2935
    2936 return SCIP_OKAY;
    2937}
    2938
    2939/**@} */
    2940
    2941
    2942
    2943
    2944/*
    2945 * Solving Methods
    2946 */
    2947
    2948/**@name Solving Methods */
    2949/**@{ */
    2950
    2951/** calls primal simplex to solve the LP
    2952 *
    2953 * @todo Check concurrent (GRB_METHOD_CONCURRENT or GRB_METHOD_DETERMINISTIC_CONCURRENT)
    2954 */
    2956 SCIP_LPI* lpi /**< LP interface structure */
    2957 )
    2958{
    2959 double cnt;
    2960 int retval;
    2961
    2962 assert( lpi != NULL );
    2963 assert( lpi->grbmodel != NULL );
    2964 assert( lpi->grbenv != NULL );
    2965
    2966#ifdef SCIP_DEBUG
    2967 {
    2968 int ncols, nrows;
    2969 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    2970 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
    2971 SCIPdebugMessage("calling Gurobi primal simplex: %d cols, %d rows\n", ncols, nrows);
    2972 }
    2973#endif
    2974
    2975 invalidateSolution(lpi);
    2976
    2977 if ( lpi->fromscratch )
    2978 {
    2979#if GRB_VERSION_MAJOR < 8
    2980 CHECK_ZERO( lpi->messagehdlr, GRBresetmodel(lpi->grbmodel) );
    2981#else
    2982 CHECK_ZERO( lpi->messagehdlr, GRBreset(lpi->grbmodel, 1) );
    2983#endif
    2984 }
    2985
    2986 SCIPdebugMessage("calling GRBoptimize() - primal\n");
    2987
    2988 /* set primal simplex */
    2989 SCIP_CALL( setParameterValues(lpi, &(lpi->grbparam)) );
    2990 CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, GRB_METHOD_PRIMAL) );
    2991
    2992 /* add range variables */
    2993 if ( lpi->nrngrows > 0 && !lpi->rngvarsadded )
    2994 {
    2995 SCIP_CALL( addRangeVars(lpi) );
    2996 }
    2997
    2998 retval = GRBoptimize(lpi->grbmodel);
    2999 switch( retval )
    3000 {
    3001 case 0:
    3002 break;
    3003 case GRB_ERROR_OUT_OF_MEMORY:
    3004 return SCIP_NOMEMORY;
    3005 default:
    3006 return SCIP_LPERROR;
    3007 }
    3008
    3009 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
    3010 lpi->iterations = (int) cnt;
    3011
    3012 lpi->solisbasic = TRUE;
    3013 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &lpi->solstat) );
    3014
    3015 SCIPdebugMessage("Gurobi primal simplex needed %d iterations to gain LP status %d\n", (int) cnt, lpi->solstat);
    3016
    3017 /* maybe the preprocessor solved the problem; but we need a solution, so solve again without preprocessing */
    3018 assert( lpi->solstat != GRB_INF_OR_UNBD );
    3019 if( lpi->solstat == GRB_INFEASIBLE )
    3020 {
    3021 int presolve;
    3022
    3023 CHECK_ZERO( lpi->messagehdlr, GRBgetintparam(lpi->grbenv, GRB_INT_PAR_PRESOLVE, &presolve) );
    3024
    3025 if( presolve != GRB_PRESOLVE_OFF )
    3026 {
    3027 SCIPdebugMessage("presolver may have solved the problem -> calling Gurobi primal simplex again without presolve\n");
    3028
    3029 /* switch off preprocessing */
    3030 CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_OFF) );
    3031
    3032 retval = GRBoptimize(lpi->grbmodel);
    3033 switch( retval )
    3034 {
    3035 case 0:
    3036 break;
    3037 case GRB_ERROR_OUT_OF_MEMORY:
    3038 return SCIP_NOMEMORY;
    3039 default:
    3040 return SCIP_LPERROR;
    3041 }
    3042
    3043 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
    3044 lpi->iterations += (int) cnt;
    3045 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &lpi->solstat) );
    3046 SCIPdebugMessage(" -> Gurobi returned solstat=%d (%d iterations)\n", lpi->solstat, lpi->iterations);
    3047
    3048 /* reset parameters */
    3049 CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_PRESOLVE, presolve) );
    3050 }
    3051
    3052 if( lpi->solstat == GRB_INF_OR_UNBD )
    3053 {
    3054 /* preprocessing was not the problem; issue a warning message and treat LP as infeasible */
    3055 SCIPerrorMessage("Gurobi primal simplex returned GRB_INF_OR_UNBD after presolving was turned off\n");
    3056 return SCIP_LPERROR;
    3057 }
    3058 }
    3059 else if ( lpi->solstat == GRB_UNBOUNDED )
    3060 {
    3061 /* Unbounded means that there exists an unbounded primal ray. However, this does not state whether the problem is
    3062 * feasible. Thus, we temporarily set the objective to 0 and solve again. */
    3063 SCIP_Real* zeroobjcoefs;
    3064 SCIP_Real* objcoefs;
    3065 SCIP_Real oldobjcutoff;
    3066 int grbobjsen;
    3067 int status;
    3068 int ncols;
    3069
    3070 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    3071 SCIP_ALLOC( BMSallocMemoryArray(&objcoefs, ncols) );
    3072 SCIP_ALLOC( BMSallocClearMemoryArray(&zeroobjcoefs, ncols) );
    3073
    3074 /* preserve objective coefficients */
    3075 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_OBJ, 0, ncols, objcoefs) );
    3076
    3077 /* set objective to 0 */
    3078 CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_OBJ, 0, ncols, zeroobjcoefs) );
    3079
    3080 /* disable cutoff */
    3081 CHECK_ZERO( lpi->messagehdlr, GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_CUTOFF, &oldobjcutoff) );
    3082
    3083 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_MODELSENSE, &grbobjsen) );
    3084 if ( grbobjsen == GRB_MINIMIZE )
    3085 {
    3086 CHECK_ZERO( lpi->messagehdlr, GRBsetdblparam(lpi->grbenv, GRB_DBL_PAR_CUTOFF, GRB_INFINITY) );
    3087 }
    3088 else
    3089 {
    3090 CHECK_ZERO( lpi->messagehdlr, GRBsetdblparam(lpi->grbenv, GRB_DBL_PAR_CUTOFF, -GRB_INFINITY) );
    3091 assert( grbobjsen == GRB_MAXIMIZE );
    3092 }
    3093
    3094 /* solve problem again */
    3095 CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
    3096 CHECK_ZERO( lpi->messagehdlr, GRBoptimize(lpi->grbmodel) );
    3097
    3098 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
    3099 lpi->iterations += (int) cnt;
    3100
    3101 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &status) );
    3102
    3103 /* restore objective */
    3104 CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_OBJ, 0, ncols, objcoefs) );
    3105 CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
    3106
    3107 /* restore objective limit */
    3108 CHECK_ZERO( lpi->messagehdlr, GRBsetdblparam(lpi->grbenv, GRB_DBL_PAR_CUTOFF, oldobjcutoff) );
    3109
    3110 BMSfreeMemoryArray(&zeroobjcoefs);
    3111 BMSfreeMemoryArray(&objcoefs);
    3112
    3113 /* possibly correct status */
    3114 switch ( status )
    3115 {
    3116 case GRB_INF_OR_UNBD:
    3117 case GRB_INFEASIBLE:
    3118 lpi->solstat = GRB_INFEASIBLE;
    3119 break;
    3120
    3121 case GRB_OPTIMAL:
    3122 /* We again have to solve the problem to restore possible unbounded rays. */
    3123 CHECK_ZERO( lpi->messagehdlr, GRBoptimize(lpi->grbmodel) );
    3124 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
    3125 lpi->iterations += (int) cnt;
    3126 break;
    3127
    3128 case GRB_ITERATION_LIMIT:
    3129 case GRB_TIME_LIMIT:
    3130 /* do nothing */
    3131 break;
    3132
    3133 /* GRB_LOADED, GRB_NODE_LIMIT, GRB_CUTOFF, GRB_SOLUTION_LIMIT, GRB_INTERRUPTED, GRB_NUMERIC, GRB_SUBOPTIMAL, GRB_INPROGRESS, GRB_USER_OBJ_LIMIT */
    3134 default:
    3135 SCIPerrorMessage("Gurobi returned wrong status %d.\n", status);
    3136 return SCIP_LPERROR;
    3137 }
    3138 }
    3139
    3140 checkRangeInfo(lpi);
    3141
    3142 return SCIP_OKAY;
    3143}
    3144
    3145/** calls dual simplex to solve the LP
    3146 *
    3147 * @todo Check concurrent (GRB_METHOD_CONCURRENT or GRB_METHOD_DETERMINISTIC_CONCURRENT)
    3148 */
    3150 SCIP_LPI* lpi /**< LP interface structure */
    3151 )
    3152{
    3153 int oldprimdual = 0;
    3154 int oldpresolve = GRB_PRESOLVE_OFF;
    3155 int retval;
    3156 double cnt;
    3157 double itlim;
    3158
    3159 assert( lpi != NULL );
    3160 assert( lpi->grbmodel != NULL );
    3161 assert( lpi->grbenv != NULL );
    3162
    3163#ifdef SCIP_DEBUG
    3164 {
    3165 int ncols, nrows;
    3166 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    3167 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
    3168 SCIPdebugMessage("calling Gurobi dual simplex: %d cols, %d rows\n", ncols, nrows);
    3169 }
    3170#endif
    3171
    3172 invalidateSolution(lpi);
    3173
    3174 if ( lpi->fromscratch )
    3175 {
    3176#if GRB_VERSION_MAJOR < 8
    3177 CHECK_ZERO( lpi->messagehdlr, GRBresetmodel(lpi->grbmodel) );
    3178#else
    3179 CHECK_ZERO( lpi->messagehdlr, GRBreset(lpi->grbmodel, 1) );
    3180#endif
    3181 }
    3182
    3183 SCIPdebugMessage("calling GRBoptimize() - dual\n");
    3184
    3185 SCIP_CALL( setParameterValues(lpi, &(lpi->grbparam)) );
    3186
    3187 /* set dual simplex */
    3188 CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, GRB_METHOD_DUAL) );
    3189
    3190 /* add range variables */
    3191 if ( lpi->nrngrows > 0 && !lpi->rngvarsadded )
    3192 {
    3193 SCIP_CALL( addRangeVars(lpi) );
    3194 }
    3195
    3196 SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_ITERATIONLIMIT, &itlim) );
    3197 if ( itlim < GRB_INFINITY )
    3198 {
    3199 /* turn off primal-dual switching for an LP solve that might be a strong branching LP solve */
    3200 CHECK_ZERO( lpi->messagehdlr, GRBgetintparam(lpi->grbenv, "GURO_PAR_PRIMDUALSWITCH", &oldprimdual) );
    3201 if ( oldprimdual != 0 )
    3202 {
    3203 CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, "GURO_PAR_PRIMDUALSWITCH", 0) );
    3204 }
    3205
    3206 /* turn off presolve to avoid the case where the iteration limit is reached
    3207 * and we do not get a valid dual bound installed for the original model */
    3208 CHECK_ZERO( lpi->messagehdlr, GRBgetintparam(lpi->grbenv, GRB_INT_PAR_PRESOLVE, &oldpresolve) );
    3209 if ( oldpresolve != GRB_PRESOLVE_OFF )
    3210 {
    3211 CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_OFF) );
    3212 }
    3213 }
    3214
    3215 retval = GRBoptimize(lpi->grbmodel);
    3216 switch( retval )
    3217 {
    3218 case 0:
    3219 break;
    3220 case GRB_ERROR_OUT_OF_MEMORY:
    3221 return SCIP_NOMEMORY;
    3222 default:
    3223 return SCIP_LPERROR;
    3224 }
    3225
    3226 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
    3227 lpi->iterations = (int) cnt;
    3228
    3229 lpi->solisbasic = TRUE;
    3230 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &lpi->solstat) );
    3231
    3232 SCIPdebugMessage("Gurobi dual simplex needed %d iterations to gain LP status %d\n", (int) cnt, lpi->solstat);
    3233
    3234 if( lpi->solstat == GRB_INF_OR_UNBD )
    3235 {
    3236 int presolve;
    3237 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_PAR_PRESOLVE, &presolve) );
    3238
    3239 if( presolve != GRB_PRESOLVE_OFF )
    3240 {
    3241 /* maybe the preprocessor solved the problem; but we need a solution, so solve again without preprocessing */
    3242 SCIPdebugMessage("presolver may have solved the problem -> calling Gurobi dual simplex again without presolve\n");
    3243
    3244 /* switch off preprocessing */
    3245 CHECK_ZERO( lpi->messagehdlr, GRBsetintattr(lpi->grbmodel, GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_OFF) );
    3246 SCIP_CALL( setParameterValues(lpi, &(lpi->grbparam)) );
    3247
    3248 retval = GRBoptimize(lpi->grbmodel);
    3249 switch( retval )
    3250 {
    3251 case 0:
    3252 break;
    3253 case GRB_ERROR_OUT_OF_MEMORY:
    3254 return SCIP_NOMEMORY;
    3255 default:
    3256 return SCIP_LPERROR;
    3257 }
    3258
    3259 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
    3260 lpi->iterations += (int) cnt;
    3261 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &lpi->solstat) );
    3262 SCIPdebugMessage(" -> Gurobi returned solstat=%d (%d iterations)\n", lpi->solstat, lpi->iterations);
    3263
    3264 /* switch on preprocessing again */
    3265 CHECK_ZERO( lpi->messagehdlr, GRBsetintattr(lpi->grbmodel, GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_AUTO) );
    3266 }
    3267
    3268 if( lpi->solstat == GRB_INF_OR_UNBD )
    3269 {
    3270 /* preprocessing was not the problem; issue a warning message and treat LP as infeasible */
    3271 SCIPerrorMessage("Gurobi dual simplex returned GRB_INF_OR_UNBD after presolving was turned off.\n");
    3272 return SCIP_LPERROR;
    3273 }
    3274 }
    3275
    3276 checkRangeInfo(lpi);
    3277
    3278 /* reset parameters to their original values */
    3279 if ( oldprimdual != 0 )
    3280 {
    3281 CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, "GURO_PAR_PRIMDUALSWITCH", oldprimdual) );
    3282 }
    3283 if ( oldpresolve != GRB_PRESOLVE_OFF )
    3284 {
    3285 CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_PRESOLVE, oldpresolve) );
    3286 }
    3287
    3288 return SCIP_OKAY;
    3289}
    3290
    3291/** calls barrier or interior point algorithm to solve the LP with crossover to simplex basis */
    3293 SCIP_LPI* lpi, /**< LP interface structure */
    3294 SCIP_Bool crossover /**< perform crossover */
    3295 )
    3296{
    3297 int retval;
    3298 double cnt;
    3299
    3300 assert( lpi != NULL );
    3301 assert( lpi->grbmodel != NULL );
    3302 assert( lpi->grbenv != NULL );
    3303
    3304#ifdef SCIP_DEBUG
    3305 {
    3306 int ncols, nrows;
    3307 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    3308 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
    3309 SCIPdebugMessage("calling Gurobi barrier: %d cols, %d rows\n", ncols, nrows);
    3310 }
    3311#endif
    3312
    3313 invalidateSolution(lpi);
    3314
    3315 if ( lpi->fromscratch )
    3316 {
    3317#if GRB_VERSION_MAJOR < 8
    3318 CHECK_ZERO( lpi->messagehdlr, GRBresetmodel(lpi->grbmodel) );
    3319#else
    3320 CHECK_ZERO( lpi->messagehdlr, GRBreset(lpi->grbmodel, 1) );
    3321#endif
    3322 }
    3323
    3324 SCIPdebugMessage("calling GRBoptimize() - barrier\n");
    3325
    3326 /* set barrier */
    3327 SCIP_CALL( setParameterValues(lpi, &(lpi->grbparam)) );
    3328
    3329 if( crossover )
    3330 {
    3331 /* turn on crossover to automatic setting (-1) */
    3332 CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_CROSSOVER, -1) );
    3333 }
    3334 else
    3335 {
    3336 /* turn off crossover */
    3337 CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_CROSSOVER, 0) );
    3338 }
    3339
    3340 CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, GRB_METHOD_BARRIER) );
    3341
    3342 /* add range variables */
    3343 if ( lpi->nrngrows > 0 && !lpi->rngvarsadded )
    3344 {
    3345 SCIP_CALL( addRangeVars(lpi) );
    3346 }
    3347
    3348 retval = GRBoptimize(lpi->grbmodel);
    3349 switch( retval )
    3350 {
    3351 case 0:
    3352 break;
    3353 case GRB_ERROR_OUT_OF_MEMORY:
    3354 return SCIP_NOMEMORY;
    3355 default:
    3356 return SCIP_LPERROR;
    3357 }
    3358
    3359 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
    3360 lpi->iterations = (int) cnt;
    3361
    3362 lpi->solisbasic = crossover;
    3363 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &lpi->solstat) );
    3364
    3365 SCIPdebugMessage("Gurobi barrier needed %d iterations to gain LP status %d\n", (int) cnt, lpi->solstat);
    3366
    3367 if( lpi->solstat == GRB_INF_OR_UNBD )
    3368 {
    3369 int presolve;
    3370 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_PAR_PRESOLVE, &presolve) );
    3371
    3372 if( presolve != GRB_PRESOLVE_OFF )
    3373 {
    3374 /* maybe the preprocessor solved the problem; but we need a solution, so solve again without preprocessing */
    3375 SCIPdebugMessage("presolver may have solved the problem -> calling Gurobi barrier again without presolve\n");
    3376
    3377 /* switch off preprocessing */
    3378 CHECK_ZERO( lpi->messagehdlr, GRBsetintattr(lpi->grbmodel, GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_OFF) );
    3379 SCIP_CALL( setParameterValues(lpi, &(lpi->grbparam)) );
    3380
    3381 retval = GRBoptimize(lpi->grbmodel);
    3382 switch( retval )
    3383 {
    3384 case 0:
    3385 break;
    3386 case GRB_ERROR_OUT_OF_MEMORY:
    3387 return SCIP_NOMEMORY;
    3388 default:
    3389 return SCIP_LPERROR;
    3390 }
    3391
    3392 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
    3393 lpi->iterations += (int) cnt;
    3394 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &lpi->solstat) );
    3395 SCIPdebugMessage(" -> Gurobi returned solstat=%d (%d iterations)\n", lpi->solstat, lpi->iterations);
    3396
    3397 /* switch on preprocessing again */
    3398 CHECK_ZERO( lpi->messagehdlr, GRBsetintattr(lpi->grbmodel, GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_AUTO) );
    3399 }
    3400
    3401 if( lpi->solstat == GRB_INF_OR_UNBD )
    3402 {
    3403 /* preprocessing was not the problem; issue a warning message and treat LP as infeasible */
    3404 SCIPerrorMessage("Gurobi barrier returned GRB_INF_OR_UNBD after presolving was turned off\n");
    3405 return SCIP_LPERROR;
    3406 }
    3407 }
    3408
    3409 checkRangeInfo(lpi);
    3410
    3411 return SCIP_OKAY;
    3412}
    3413
    3414/** start strong branching - call before any strong branching */
    3416 SCIP_LPI* lpi /**< LP interface structure */
    3417 )
    3418{ /*lint --e{715}*/
    3419 assert( lpi != NULL );
    3420 assert( lpi->grbmodel != NULL );
    3421 assert( lpi->grbenv != NULL );
    3422
    3423 /* currently do nothing */
    3424 return SCIP_OKAY;
    3425}
    3426
    3427/** end strong branching - call after any strong branching */
    3429 SCIP_LPI* lpi /**< LP interface structure */
    3430 )
    3431{ /*lint --e{715}*/
    3432 assert( lpi != NULL );
    3433 assert( lpi->grbmodel != NULL );
    3434 assert( lpi->grbenv != NULL );
    3435
    3436 /* currently do nothing */
    3437 return SCIP_OKAY;
    3438}
    3439
    3440/** performs strong branching iterations on one candidate */
    3441static
    3443 SCIP_LPI* lpi, /**< LP interface structure */
    3444 int col, /**< column to apply strong branching on */
    3445 SCIP_Real psol, /**< current primal solution value of column */
    3446 int itlim, /**< iteration limit for strong branchings */
    3447 SCIP_Real* down, /**< stores dual bound after branching column down */
    3448 SCIP_Real* up, /**< stores dual bound after branching column up */
    3449 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
    3450 * otherwise, it can only be used as an estimate value */
    3451 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
    3452 * otherwise, it can only be used as an estimate value */
    3453 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
    3454 )
    3455{
    3456 SCIP_Real oldlb;
    3457 SCIP_Real oldub;
    3458 SCIP_Real newlb;
    3459 SCIP_Real newub;
    3460 SCIP_Real olditlim;
    3461 SCIP_Bool error = FALSE;
    3462 SCIP_Bool success;
    3463 int it;
    3464
    3465 assert( lpi != NULL );
    3466 assert( lpi->grbmodel != NULL );
    3467 assert( lpi->grbenv != NULL );
    3468 assert( down != NULL );
    3469 assert( up != NULL );
    3470 assert( downvalid != NULL );
    3471 assert( upvalid != NULL );
    3472
    3473 SCIPdebugMessage("performing strong branching on variable %d (%d iterations)\n", col, itlim);
    3474
    3475 SCIP_CALL( setParameterValues(lpi, &(lpi->grbparam)) );
    3476
    3477 *downvalid = FALSE;
    3478 *upvalid = FALSE;
    3479 if( iter != NULL )
    3480 *iter = 0;
    3481
    3482 /* save current LP basis and bounds*/
    3483 SCIP_CALL( getBase(lpi, &success) );
    3484 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_LB, col, &oldlb) );
    3485 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_UB, col, &oldub) );
    3486
    3487 if ( lpi->fromscratch )
    3488 {
    3489#if GRB_VERSION_MAJOR < 8
    3490 CHECK_ZERO( lpi->messagehdlr, GRBresetmodel(lpi->grbmodel) );
    3491#else
    3492 CHECK_ZERO( lpi->messagehdlr, GRBreset(lpi->grbmodel, 1) );
    3493#endif
    3494 }
    3495
    3496 /* save old iteration limit and set iteration limit to strong branching limit */
    3497 if( itlim < 0 )
    3498 itlim = INT_MAX;
    3499
    3500 SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_ITERATIONLIMIT, &olditlim) );
    3501 SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_ITERATIONLIMIT, (double) itlim) );
    3502
    3503 /* add range variables */
    3504 if ( lpi->nrngrows > 0 && !lpi->rngvarsadded )
    3505 {
    3506 SCIP_CALL( addRangeVars(lpi) );
    3507 }
    3508
    3509 /* down branch */
    3510 newub = EPSCEIL(psol-1.0, 1e-06);
    3511 if( newub >= oldlb - 0.5 )
    3512 {
    3513 SCIPdebugMessage("strong branching down (%g) on x%d (%g) with %d iterations\n", newub, col, psol, itlim);
    3514
    3515 CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_UB, col, newub) );
    3516
    3518 /* when iteration limit was reached the objective value is not computed */
    3519 if( SCIPlpiIsOptimal(lpi) ) /*|| SCIPlpiIsIterlimExc(lpi) ) */
    3520 {
    3521 SCIP_CALL( SCIPlpiGetObjval(lpi, down) );
    3522 *downvalid = TRUE;
    3523 }
    3524 else if( SCIPlpiIsPrimalInfeasible(lpi) || SCIPlpiIsObjlimExc(lpi) )
    3525 {
    3526 CHECK_ZERO( lpi->messagehdlr, GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_CUTOFF, down) );
    3527 }
    3528 else if( !SCIPlpiIsIterlimExc(lpi) )
    3529 error = TRUE;
    3530
    3531 if( iter != NULL )
    3532 {
    3533 SCIP_CALL( SCIPlpiGetIterations(lpi, &it) );
    3534 *iter += it;
    3535 }
    3536 SCIPdebugMessage(" -> down (x%d <= %g): %g\n", col, newub, *down);
    3537
    3538 CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_UB, col, oldub) );
    3539 CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
    3540#ifdef SCIP_DEBUG
    3541 {
    3542 double b;
    3543 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_UB, col, &b) );
    3544 assert( b == oldub );
    3545 }
    3546#endif
    3547
    3548 if ( success )
    3549 {
    3550 SCIP_CALL( setBase(lpi) );
    3551 }
    3552 }
    3553 else
    3554 {
    3555 CHECK_ZERO( lpi->messagehdlr, GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_CUTOFF, down) );
    3556 *downvalid = TRUE;
    3557 }
    3558
    3559 /* up branch */
    3560 if( !error )
    3561 {
    3562 newlb = EPSFLOOR(psol+1.0, 1e-06);
    3563 if( newlb <= oldub + 0.5 )
    3564 {
    3565 SCIPdebugMessage("strong branching up (%g) on x%d (%g) with %d iterations\n", newlb, col, psol, itlim);
    3566
    3567 CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_LB, col, newlb) );
    3568
    3570 /* when iteration limit was reached the objective value is not computed */
    3571 if( SCIPlpiIsOptimal(lpi) ) /*|| SCIPlpiIsIterlimExc(lpi) ) */
    3572 {
    3573 SCIP_CALL( SCIPlpiGetObjval(lpi, up) );
    3574 *upvalid = TRUE;
    3575 }
    3576 else if( SCIPlpiIsPrimalInfeasible(lpi) || SCIPlpiIsObjlimExc(lpi) )
    3577 {
    3578 CHECK_ZERO( lpi->messagehdlr, GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_CUTOFF, up) );
    3579 }
    3580 else if( !SCIPlpiIsIterlimExc(lpi) )
    3581 error = TRUE;
    3582
    3583 if( iter != NULL )
    3584 {
    3585 SCIP_CALL( SCIPlpiGetIterations(lpi, &it) );
    3586 *iter += it;
    3587 }
    3588 SCIPdebugMessage(" -> up (x%d >= %g): %g\n", col, newlb, *up);
    3589
    3590 CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_LB, col, oldlb) );
    3591 CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
    3592#ifdef SCIP_DEBUG
    3593 {
    3594 double b;
    3595 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_LB, col, &b) );
    3596 assert( b == oldlb );
    3597 }
    3598#endif
    3599
    3600 if ( success )
    3601 {
    3602 SCIP_CALL( setBase(lpi) );
    3603 }
    3604 }
    3605 else
    3606 {
    3607 CHECK_ZERO( lpi->messagehdlr, GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_CUTOFF, up) );
    3608 *upvalid = TRUE;
    3609 }
    3610 }
    3611
    3612 /* reset iteration limit */
    3613 SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_ITERATIONLIMIT, olditlim) );
    3614 /* CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) ); */
    3615
    3616 if( error )
    3617 {
    3618 SCIPerrorMessage("LP error in strong branching.\n");
    3619 return SCIP_LPERROR;
    3620 }
    3621
    3622 return SCIP_OKAY;
    3623}
    3624
    3625/** performs strong branching iterations on one @b fractional candidate */
    3627 SCIP_LPI* lpi, /**< LP interface structure */
    3628 int col, /**< column to apply strong branching on */
    3629 SCIP_Real psol, /**< fractional current primal solution value of column */
    3630 int itlim, /**< iteration limit for strong branchings */
    3631 SCIP_Real* down, /**< stores dual bound after branching column down */
    3632 SCIP_Real* up, /**< stores dual bound after branching column up */
    3633 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
    3634 * otherwise, it can only be used as an estimate value */
    3635 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
    3636 * otherwise, it can only be used as an estimate value */
    3637 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
    3638 )
    3639{
    3640 /* pass call on to lpiStrongbranch() */
    3641 SCIP_CALL( lpiStrongbranch(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter) );
    3642
    3643 checkRangeInfo(lpi);
    3644
    3645 return SCIP_OKAY;
    3646}
    3647
    3648/** performs strong branching iterations on given @b fractional candidates */
    3650 SCIP_LPI* lpi, /**< LP interface structure */
    3651 int* cols, /**< columns to apply strong branching on */
    3652 int ncols, /**< number of columns */
    3653 SCIP_Real* psols, /**< fractional current primal solution values of columns */
    3654 int itlim, /**< iteration limit for strong branchings */
    3655 SCIP_Real* down, /**< stores dual bounds after branching columns down */
    3656 SCIP_Real* up, /**< stores dual bounds after branching columns up */
    3657 SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
    3658 * otherwise, they can only be used as an estimate values */
    3659 SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
    3660 * otherwise, they can only be used as an estimate values */
    3661 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
    3662 )
    3663{
    3664 int j;
    3665
    3666 assert( cols != NULL );
    3667 assert( psols != NULL );
    3668 assert( down != NULL );
    3669 assert( up != NULL );
    3670 assert( downvalid != NULL );
    3671 assert( upvalid != NULL );
    3672 assert( down != NULL );
    3673
    3674 if( iter != NULL )
    3675 *iter = 0;
    3676
    3677 for( j = 0; j < ncols; ++j )
    3678 {
    3679 /* pass call on to lpiStrongbranch() */
    3680 SCIP_CALL( lpiStrongbranch(lpi, cols[j], psols[j], itlim, &(down[j]), &(up[j]), &(downvalid[j]), &(upvalid[j]), iter) );
    3681 }
    3682
    3683 checkRangeInfo(lpi);
    3684
    3685 return SCIP_OKAY;
    3686}
    3687
    3688/** performs strong branching iterations on one candidate with @b integral value */
    3690 SCIP_LPI* lpi, /**< LP interface structure */
    3691 int col, /**< column to apply strong branching on */
    3692 SCIP_Real psol, /**< current integral primal solution value of column */
    3693 int itlim, /**< iteration limit for strong branchings */
    3694 SCIP_Real* down, /**< stores dual bound after branching column down */
    3695 SCIP_Real* up, /**< stores dual bound after branching column up */
    3696 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
    3697 * otherwise, it can only be used as an estimate value */
    3698 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
    3699 * otherwise, it can only be used as an estimate value */
    3700 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
    3701 )
    3702{
    3703 /* pass call on to lpiStrongbranch() */
    3704 SCIP_CALL( lpiStrongbranch(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter) );
    3705
    3706 checkRangeInfo(lpi);
    3707
    3708 return SCIP_OKAY;
    3709}
    3710
    3711/** performs strong branching iterations on given candidates with @b integral values */
    3713 SCIP_LPI* lpi, /**< LP interface structure */
    3714 int* cols, /**< columns to apply strong branching on */
    3715 int ncols, /**< number of columns */
    3716 SCIP_Real* psols, /**< current integral primal solution values of columns */
    3717 int itlim, /**< iteration limit for strong branchings */
    3718 SCIP_Real* down, /**< stores dual bounds after branching columns down */
    3719 SCIP_Real* up, /**< stores dual bounds after branching columns up */
    3720 SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
    3721 * otherwise, they can only be used as an estimate values */
    3722 SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
    3723 * otherwise, they can only be used as an estimate values */
    3724 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
    3725 )
    3726{
    3727 int j;
    3728
    3729 assert( cols != NULL );
    3730 assert( psols != NULL );
    3731 assert( down != NULL );
    3732 assert( up != NULL );
    3733 assert( downvalid != NULL );
    3734 assert( upvalid != NULL );
    3735 assert( down != NULL );
    3736
    3737 if( iter != NULL )
    3738 *iter = 0;
    3739
    3740 for( j = 0; j < ncols; ++j )
    3741 {
    3742 /* pass call on to lpiStrongbranch() */
    3743 SCIP_CALL( lpiStrongbranch(lpi, cols[j], psols[j], itlim, &(down[j]), &(up[j]), &(downvalid[j]), &(upvalid[j]), iter) );
    3744 }
    3745
    3746 checkRangeInfo(lpi);
    3747
    3748 return SCIP_OKAY;
    3749}
    3750/**@} */
    3751
    3752
    3753
    3754
    3755/*
    3756 * Solution Information Methods
    3757 */
    3758
    3759/**@name Solution Information Methods */
    3760/**@{ */
    3761
    3762/** returns whether a solve method was called after the last modification of the LP */
    3764 SCIP_LPI* lpi /**< LP interface structure */
    3765 )
    3766{
    3767 assert(lpi != NULL);
    3768
    3769 return (lpi->solstat != -1);
    3770}
    3771
    3772/** gets information about primal and dual feasibility of the current LP solution
    3773 *
    3774 * The feasibility information is with respect to the last solving call and it is only relevant if SCIPlpiWasSolved()
    3775 * returns true. If the LP is changed, this information might be invalidated.
    3776 *
    3777 * Note that @a primalfeasible and @a dualfeasible should only return true if the solver has proved the respective LP to
    3778 * be feasible. Thus, the return values should be equal to the values of SCIPlpiIsPrimalFeasible() and
    3779 * SCIPlpiIsDualFeasible(), respectively. Note that if feasibility cannot be proved, they should return false (even if
    3780 * the problem might actually be feasible).
    3781 */
    3783 SCIP_LPI* lpi, /**< LP interface structure */
    3784 SCIP_Bool* primalfeasible, /**< pointer to store primal feasibility status */
    3785 SCIP_Bool* dualfeasible /**< pointer to store dual feasibility status */
    3786 )
    3787{
    3788 assert( lpi != NULL );
    3789 assert( lpi->grbmodel != NULL );
    3790 assert( lpi->grbenv != NULL );
    3791 assert( lpi->solstat >= 1 );
    3792 assert( primalfeasible != NULL );
    3793 assert( dualfeasible != NULL );
    3794
    3795 SCIPdebugMessage("getting solution feasibility\n");
    3796
    3797 *primalfeasible = SCIPlpiIsPrimalFeasible(lpi);
    3798 *dualfeasible = SCIPlpiIsDualFeasible(lpi);
    3799
    3800 return SCIP_OKAY;
    3801}
    3802
    3803/** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point);
    3804 * this does not necessarily mean, that the solver knows and can return the primal ray
    3805 */
    3807 SCIP_LPI* lpi /**< LP interface structure */
    3808 )
    3809{
    3810 assert(lpi != NULL);
    3811 assert(lpi->grbmodel != NULL);
    3812 assert(lpi->solstat >= 0);
    3813
    3814 return (lpi->solstat == GRB_UNBOUNDED);
    3815}
    3816
    3817/** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point),
    3818 * and the solver knows and can return the primal ray
    3819 */
    3821 SCIP_LPI* lpi /**< LP interface structure */
    3822 )
    3823{
    3824 int algo;
    3825 int res;
    3826
    3827 assert( lpi != NULL );
    3828 assert( lpi->grbmodel != NULL );
    3829 assert( lpi->grbenv != NULL );
    3830 assert( lpi->solstat >= 0 );
    3831
    3832 res = GRBgetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, &algo);
    3833 if ( res != 0 )
    3834 {
    3835 SCIPABORT();
    3836 return FALSE; /*lint !e527*/
    3837 }
    3838
    3839 return (lpi->solstat == GRB_UNBOUNDED && algo == GRB_METHOD_PRIMAL);
    3840}
    3841
    3842/** returns TRUE iff LP is proven to be primal unbounded */
    3844 SCIP_LPI* lpi /**< LP interface structure */
    3845 )
    3846{
    3847 int algo;
    3848 int res;
    3849
    3850 assert( lpi != NULL );
    3851 assert( lpi->grbmodel != NULL );
    3852 assert( lpi->grbenv != NULL );
    3853 assert( lpi->solstat >= 0 );
    3854
    3855 res = GRBgetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, &algo);
    3856 if ( res != 0 )
    3857 {
    3858 SCIPABORT();
    3859 return FALSE; /*lint !e527*/
    3860 }
    3861
    3862 /* GRB_UNBOUNDED means that there exists a primal ray. SCIPlpiSolvePrimal() will determine whether the problem is
    3863 * actually infeasible or (feasible and) unbounded. In the latter case, the status will be GRB_UNBOUNDED.
    3864 */
    3865 return (lpi->solstat == GRB_UNBOUNDED && algo == GRB_METHOD_PRIMAL);
    3866}
    3867
    3868/** returns TRUE iff LP is proven to be primal infeasible */
    3870 SCIP_LPI* lpi /**< LP interface structure */
    3871 )
    3872{
    3873 assert(lpi != NULL);
    3874 assert(lpi->grbmodel != NULL);
    3875 assert(lpi->solstat >= 0);
    3876
    3877 SCIPdebugMessage("checking for primal infeasibility\n");
    3878
    3879 assert( lpi->solstat != GRB_INF_OR_UNBD );
    3880 return (lpi->solstat == GRB_INFEASIBLE);
    3881}
    3882
    3883/** returns TRUE iff LP is proven to be primal feasible */
    3885 SCIP_LPI* lpi /**< LP interface structure */
    3886 )
    3887{
    3888 int algo;
    3889 int res;
    3890
    3891 assert( lpi != NULL );
    3892 assert( lpi->grbmodel != NULL );
    3893 assert( lpi->grbenv != NULL );
    3894 assert( lpi->solstat >= 0 );
    3895
    3896 SCIPdebugMessage("checking for primal feasibility\n");
    3897
    3898 if ( lpi->solstat == GRB_OPTIMAL )
    3899 return TRUE;
    3900
    3901 res = GRBgetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, &algo);
    3902 if ( res != 0 )
    3903 {
    3904 SCIPABORT();
    3905 return FALSE; /*lint !e527*/
    3906 }
    3907 if ( algo != GRB_METHOD_PRIMAL )
    3908 return FALSE;
    3909
    3910 if( lpi->solstat == GRB_ITERATION_LIMIT )
    3911 {
    3912 double consviol;
    3913 double boundviol;
    3914 double eps;
    3915
    3916 /* get feasibility tolerance */
    3917 res = GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_FEASIBILITYTOL, &eps);
    3918 if ( res != 0 )
    3919 {
    3920 SCIPABORT();
    3921 return FALSE; /*lint !e527*/
    3922 }
    3923 res = GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_CONSTR_VIO, &consviol);
    3924 if ( res != 0 )
    3925 {
    3926 /* If Gurobi cannot return the constraint violation, there is no feasible solution available. */
    3927 return FALSE;
    3928 }
    3929 res = GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_BOUND_VIO, &boundviol);
    3930 if ( res != 0 )
    3931 {
    3932 /* If Gurobi cannot return the bound violation, there is no feasible solution available. */
    3933 return FALSE;
    3934 }
    3935
    3936 if ( consviol <= eps && boundviol <= eps )
    3937 return TRUE;
    3938 }
    3939
    3940 return FALSE;
    3941}
    3942
    3943/** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point);
    3944 * this does not necessarily mean, that the solver knows and can return the dual ray
    3945 */
    3947 SCIP_LPI* lpi /**< LP interface structure */
    3948 )
    3949{
    3950 assert(lpi != NULL);
    3951 assert(lpi->grbmodel != NULL);
    3952 assert(lpi->solstat >= 0);
    3953
    3954 return (lpi->solstat == GRB_INFEASIBLE);
    3955}
    3956
    3957/** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point),
    3958 * and the solver knows and can return the dual ray
    3959 */
    3961 SCIP_LPI* lpi /**< LP interface structure */
    3962 )
    3963{
    3964 int algo;
    3965 int res;
    3966
    3967 assert( lpi != NULL );
    3968 assert( lpi->grbmodel != NULL );
    3969 assert( lpi->grbenv != NULL );
    3970 assert( lpi->solstat >= 0 );
    3971
    3972 res = GRBgetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, &algo);
    3973 if ( res != 0 )
    3974 {
    3975 SCIPABORT();
    3976 return FALSE; /*lint !e527*/
    3977 }
    3978
    3979 return (lpi->solstat == GRB_INFEASIBLE && algo == GRB_METHOD_DUAL);
    3980}
    3981
    3982/** returns TRUE iff LP is proven to be dual unbounded */
    3984 SCIP_LPI* lpi /**< LP interface structure */
    3985 )
    3986{
    3987 int algo;
    3988 int res;
    3989
    3990 assert( lpi != NULL );
    3991 assert( lpi->grbmodel != NULL );
    3992 assert( lpi->grbenv != NULL );
    3993 assert( lpi->solstat >= 0 );
    3994
    3995 SCIPdebugMessage("checking for dual unboundedness\n");
    3996
    3997 res = GRBgetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, &algo);
    3998 if ( res != 0 )
    3999 {
    4000 SCIPABORT();
    4001 return FALSE; /*lint !e527*/
    4002 }
    4003
    4004 return (lpi->solstat == GRB_INFEASIBLE && algo == GRB_METHOD_DUAL);
    4005}
    4006
    4007/** returns TRUE iff LP is proven to be dual infeasible */
    4009 SCIP_LPI* lpi /**< LP interface structure */
    4010 )
    4011{
    4012 assert( lpi != NULL );
    4013 assert( lpi->grbmodel != NULL );
    4014 assert( lpi->solstat >= 0 );
    4015
    4016 SCIPdebugMessage("checking for dual infeasibility\n");
    4017
    4018 return (lpi->solstat == GRB_UNBOUNDED);
    4019}
    4020
    4021/** returns TRUE iff LP is proven to be dual feasible */
    4023 SCIP_LPI* lpi /**< LP interface structure */
    4024 )
    4025{
    4026 int algo;
    4027 int res;
    4028
    4029 assert( lpi != NULL );
    4030 assert( lpi->grbmodel != NULL );
    4031 assert( lpi->grbenv != NULL );
    4032 assert( lpi->solstat >= 0 );
    4033
    4034 SCIPdebugMessage("checking for dual feasibility\n");
    4035
    4036 res = GRBgetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, &algo);
    4037 if ( res != 0 )
    4038 {
    4039 SCIPABORT();
    4040 return FALSE; /*lint !e527*/
    4041 }
    4042
    4043 return (lpi->solstat == GRB_OPTIMAL ||
    4044 (lpi->solstat == GRB_INFEASIBLE && algo == GRB_METHOD_DUAL) ||
    4045 (lpi->solstat == GRB_ITERATION_LIMIT && algo == GRB_METHOD_DUAL) );
    4046}
    4047
    4048/** returns TRUE iff LP was solved to optimality */
    4050 SCIP_LPI* lpi /**< LP interface structure */
    4051 )
    4052{
    4053 assert(lpi != NULL);
    4054 assert(lpi->grbmodel != NULL);
    4055 assert(lpi->solstat >= 0);
    4056
    4057 return (lpi->solstat == GRB_OPTIMAL);
    4058}
    4059
    4060/** returns TRUE iff current LP solution is stable
    4061 *
    4062 * This function should return true if the solution is reliable, i.e., feasible and optimal (or proven
    4063 * infeasible/unbounded) with respect to the original problem. The optimality status might be with respect to a scaled
    4064 * version of the problem, but the solution might not be feasible to the unscaled original problem; in this case,
    4065 * SCIPlpiIsStable() should return false.
    4066 */
    4068 SCIP_LPI* lpi /**< LP interface structure */
    4069 )
    4070{
    4071 double consviol;
    4072 double boundviol;
    4073 double dualviol;
    4074 double feastol;
    4075 double optimalitytol;
    4076 int res;
    4077
    4078 assert(lpi != NULL);
    4079 assert(lpi->grbmodel != NULL);
    4080 assert(lpi->solstat >= 0);
    4081
    4082 SCIPdebugMessage("checking for stability: Gurobi solstat = %d\n", lpi->solstat);
    4083
    4084 /* If the condition number of the basis should be checked, everything above the specified threshold is counted as
    4085 * instable. */
    4086 if ( lpi->checkcondition && (SCIPlpiIsOptimal(lpi) || SCIPlpiIsObjlimExc(lpi)) )
    4087 {
    4088 SCIP_Real kappa;
    4089 SCIP_RETCODE retcode;
    4090
    4092 if ( retcode != SCIP_OKAY ) /*lint !e774*/
    4093 {
    4094 SCIPABORT();
    4095 return FALSE; /*lint !e527*/
    4096 }
    4097
    4098 /* if the kappa could not be computed (e.g., because we do not have a basis), we cannot check the condition */
    4099 if ( kappa != SCIP_INVALID || kappa > lpi->conditionlimit ) /*lint !e777*/
    4100 return FALSE;
    4101 }
    4102
    4103 /* test whether we have unscaled infeasibilities */
    4104 if ( SCIPlpiIsOptimal(lpi) )
    4105 {
    4106 /* first get tolerances */
    4107 res = GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_FEASIBILITYTOL, &feastol);
    4108 if ( res != 0 )
    4109 {
    4110 SCIPABORT();
    4111 return FALSE; /*lint !e527*/
    4112 }
    4113 res = GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_OPTIMALITYTOL, &optimalitytol);
    4114 if ( res != 0 )
    4115 {
    4116 SCIPABORT();
    4117 return FALSE; /*lint !e527*/
    4118 }
    4119
    4120 /* next get constraint, bound, and reduced cost violations */
    4121 res = GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_CONSTR_VIO, &consviol);
    4122 if ( res != 0 )
    4123 {
    4124 SCIPABORT();
    4125 return FALSE; /*lint !e527*/
    4126 }
    4127 res = GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_BOUND_VIO, &boundviol);
    4128 if ( res != 0 )
    4129 {
    4130 SCIPABORT();
    4131 return FALSE; /*lint !e527*/
    4132 }
    4133 res = GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_DUAL_VIO, &dualviol);
    4134 if ( res != 0 )
    4135 {
    4136 SCIPABORT();
    4137 return FALSE; /*lint !e527*/
    4138 }
    4139
    4140 return ( consviol <= feastol && boundviol <= feastol && dualviol <= optimalitytol );
    4141 }
    4142
    4143 return (lpi->solstat != GRB_NUMERIC);
    4144}
    4145
    4146/** returns TRUE iff the objective limit was reached */
    4148 SCIP_LPI* lpi /**< LP interface structure */
    4149 )
    4150{
    4151 assert(lpi != NULL);
    4152 assert(lpi->grbmodel != NULL);
    4153 assert(lpi->solstat >= 0);
    4154
    4155 return (lpi->solstat == GRB_CUTOFF);
    4156}
    4157
    4158/** returns TRUE iff the iteration limit was reached */
    4160 SCIP_LPI* lpi /**< LP interface structure */
    4161 )
    4162{
    4163 assert(lpi != NULL);
    4164 assert(lpi->grbmodel != NULL);
    4165 assert(lpi->solstat >= 0);
    4166
    4167 return (lpi->solstat == GRB_ITERATION_LIMIT);
    4168}
    4169
    4170/** returns TRUE iff the time limit was reached */
    4172 SCIP_LPI* lpi /**< LP interface structure */
    4173 )
    4174{
    4175 assert(lpi != NULL);
    4176 assert(lpi->grbmodel != NULL);
    4177 assert(lpi->solstat >= 0);
    4178
    4179 return (lpi->solstat == GRB_TIME_LIMIT);
    4180}
    4181
    4182/** returns the internal solution status of the solver */
    4184 SCIP_LPI* lpi /**< LP interface structure */
    4185 )
    4186{
    4187 assert(lpi != NULL);
    4188 assert(lpi->grbmodel != NULL);
    4189
    4190 return lpi->solstat;
    4191}
    4192
    4193/** tries to reset the internal status of the LP solver in order to ignore an instability of the last solving call */
    4195 SCIP_LPI* lpi, /**< LP interface structure */
    4196 SCIP_Bool* success /**< pointer to store, whether the instability could be ignored */
    4197 )
    4198{
    4199 assert(lpi != NULL);
    4200 assert(lpi->grbmodel != NULL);
    4201 assert(success != NULL);
    4202
    4203 *success = FALSE;
    4204
    4205 return SCIP_OKAY;
    4206}
    4207
    4208/** gets objective value of solution */
    4210 SCIP_LPI* lpi, /**< LP interface structure */
    4211 SCIP_Real* objval /**< stores the objective value */
    4212 )
    4213{
    4214 int ret;
    4215
    4216 assert(lpi != NULL);
    4217 assert(lpi->grbmodel != NULL);
    4218 assert(objval != NULL);
    4219
    4220 SCIPdebugMessage("getting solution's objective value\n");
    4221
    4222 /* obtain objective value */
    4223 ret = GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_OBJVAL, objval);
    4224 assert( ret == 0 || ret == GRB_ERROR_DATA_NOT_AVAILABLE );
    4225 SCIP_UNUSED(ret);
    4226
    4227#ifndef NDEBUG
    4228 {
    4229 /* in older version the barrier method does not seem to return valid objective bounds */
    4230#if GRB_VERSION_MAJOR < 12
    4231 double obnd = -GRB_INFINITY;
    4232 int algo;
    4233 (void)GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_OBJBOUND, &obnd);
    4234 (void)GRBgetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, &algo);
    4235 assert(algo == GRB_METHOD_BARRIER || lpi->solstat != GRB_OPTIMAL || *objval == obnd); /*lint !e777*/
    4236#else
    4237 double obnd;
    4238 double eps;
    4239 (void)GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_OBJBOUND, &obnd);
    4240 (void)GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_FEASIBILITYTOL, &eps);
    4241 assert(lpi->solstat != GRB_OPTIMAL || fabs(*objval - obnd) <= eps); /*lint !e777*/
    4242#endif
    4243 }
    4244#endif
    4245
    4246 /* return minus infinity if value not available and we reached the iteration limit (see lpi_cpx) */
    4247 if( lpi->solstat == GRB_ITERATION_LIMIT )
    4248 {
    4249 (void)GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_OBJBOUND, objval);
    4250 }
    4251 else if( lpi->solstat == GRB_CUTOFF )
    4252 {
    4253 SCIP_Real cutoff;
    4254
    4255 /* if we reached the cutoff, then OBJBOUND seems to be -infinity; we set the value to the cutoff in this case */
    4256 SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_CUTOFF, &cutoff) );
    4257 *objval = cutoff;
    4258
    4259#ifdef SCIP_DISABLED_CODE
    4260 /**@todo The following is some kind of hack which works with the current SCIP implementation and should be fixed. In
    4261 * the case that the LP status is GRB_CUTOFF it might be that certain attributes cannot be queried (e.g., objval,
    4262 * primal and dual solution), in this case we just return the installed cutoff value minus some epsilon. This is some
    4263 * kind of hack for the code in conflict.c:7595 were some extra code handles CPLEX' FASTMIP case that is similar to
    4264 * this case.
    4265 */
    4266 SCIP_Real dval;
    4267 SCIP_OBJSEN objsense;
    4268
    4269 SCIP_CALL( SCIPlpiGetObjsen(lpi, &objsense) );
    4270 SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_CUTOFF, &dval) );
    4271
    4272 if( objsense == SCIP_OBJSEN_MINIMIZE )
    4273 *objval = dval - 1e-06;
    4274 else
    4275 *objval = dval + 1e-06;
    4276#endif
    4277 }
    4278
    4279 return SCIP_OKAY;
    4280}
    4281
    4282/** gets primal and dual solution vectors for feasible LPs
    4283 *
    4284 * Before calling this function, the caller must ensure that the LP has been solved to optimality, i.e., that
    4285 * SCIPlpiIsOptimal() returns true.
    4286 */
    4288 SCIP_LPI* lpi, /**< LP interface structure */
    4289 SCIP_Real* objval, /**< stores the objective value, may be NULL if not needed */
    4290 SCIP_Real* primsol, /**< primal solution vector, may be NULL if not needed */
    4291 SCIP_Real* dualsol, /**< dual solution vector, may be NULL if not needed */
    4292 SCIP_Real* activity, /**< row activity vector, may be NULL if not needed */
    4293 SCIP_Real* redcost /**< reduced cost vector, may be NULL if not needed */
    4294 )
    4295{
    4296 int ncols;
    4297 int nrows;
    4298
    4299 assert(lpi != NULL);
    4300 assert(lpi->grbmodel != NULL);
    4301 assert(lpi->solstat >= 0);
    4302
    4303 SCIPdebugMessage("getting solution\n");
    4304
    4305 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    4306 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
    4307 assert( ncols >= 0 && nrows >= 0 );
    4308
    4309 if( objval != NULL )
    4310 {
    4311 SCIP_CALL( SCIPlpiGetObjval(lpi, objval) );
    4312 }
    4313
    4314 if( primsol != NULL )
    4315 {
    4316 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_X, 0, ncols, primsol) );
    4317 }
    4318
    4319 if( dualsol != NULL )
    4320 {
    4321 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_PI, 0, nrows, dualsol) );
    4322 }
    4323
    4324 if( activity != NULL )
    4325 {
    4326 int i;
    4327
    4328 /* first get the values of the slack variables */
    4329 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_SLACK, 0, nrows, activity) );
    4330
    4331 SCIP_CALL( ensureSidechgMem(lpi, nrows) );
    4332
    4333 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_RHS, 0, nrows, lpi->rhsarray) );
    4334 CHECK_ZERO( lpi->messagehdlr, GRBgetcharattrarray(lpi->grbmodel, GRB_CHAR_ATTR_SENSE, 0, nrows, lpi->senarray) );
    4335
    4336 for( i = 0; i < nrows; ++i )
    4337 {
    4338 switch(lpi->senarray[i])
    4339 {
    4340 case GRB_EQUAL:
    4341 if ( lpi->rngrowmap != NULL && lpi->rngrowmap[i] >= 0 )
    4342 {
    4343 /* get solution value of range variable */
    4344 SCIP_Real solval;
    4345 assert(lpi->rngrowmap[i] < lpi->nrngrows);
    4346 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_X, ncols + lpi->rngrowmap[i], &solval) );
    4347 activity[i] = lpi->rhsarray[i] + solval;
    4348 }
    4349 else
    4350 {
    4351 activity[i] = lpi->rhsarray[i] - activity[i];
    4352 }
    4353 break;
    4354 case GRB_LESS_EQUAL:
    4355 activity[i] = lpi->rhsarray[i] - activity[i];
    4356 break;
    4357 case GRB_GREATER_EQUAL:
    4358 activity[i] = lpi->rhsarray[i] - activity[i];
    4359 break;
    4360 default:
    4361 SCIPerrorMessage("Unkown sense %c.\n", lpi->senarray[i]);
    4362 SCIPABORT();
    4363 return SCIP_INVALIDDATA; /*lint !e527*/
    4364 }
    4365 }
    4366 }
    4367
    4368 if( redcost != NULL )
    4369 {
    4370 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_RC, 0, ncols, redcost) );
    4371 }
    4372
    4373 return SCIP_OKAY;
    4374}
    4375
    4376/** gets primal ray for unbounded LPs */
    4378 SCIP_LPI* lpi, /**< LP interface structure */
    4379 SCIP_Real* ray /**< primal ray */
    4380 )
    4381{
    4382 int ncols;
    4383
    4384 assert(lpi != NULL);
    4385 assert(lpi->grbmodel != NULL);
    4386 assert(lpi->solstat >= 0);
    4387 assert(ray != NULL);
    4388
    4389 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    4390 assert( ncols >= 0 );
    4391
    4392 SCIPdebugMessage("calling Gurobi get primal ray: %d cols\n", ncols);
    4393
    4394 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_UNBDRAY, 0, ncols, ray) );
    4395
    4396 return SCIP_OKAY;
    4397}
    4398
    4399/** gets dual Farkas proof for infeasibility */
    4401 SCIP_LPI* lpi, /**< LP interface structure */
    4402 SCIP_Real* dualfarkas /**< dual Farkas row multipliers */
    4403 )
    4404{
    4405 int nrows;
    4406 int i;
    4407
    4408 assert(lpi != NULL);
    4409 assert(lpi->grbmodel != NULL);
    4410 assert(lpi->solstat >= 0);
    4411 assert(dualfarkas != NULL);
    4412
    4413 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
    4414 assert( nrows >= 0 );
    4415
    4416 SCIPdebugMessage("calling Gurobi dual Farkas: %d rows\n", nrows);
    4417
    4418 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_FARKASDUAL, 0, nrows, dualfarkas) );
    4419
    4420 /* correct sign of ray */
    4421 for (i = 0; i < nrows; ++i)
    4422 dualfarkas[i] *= -1.0;
    4423
    4424 return SCIP_OKAY;
    4425}
    4426
    4427/** gets the number of LP iterations of the last solve call */
    4429 SCIP_LPI* lpi, /**< LP interface structure */
    4430 int* iterations /**< pointer to store the number of iterations of the last solve call */
    4431 )
    4432{
    4433 assert(lpi != NULL);
    4434 assert(lpi->grbmodel != NULL);
    4435 assert(iterations != NULL);
    4436
    4437 *iterations = lpi->iterations;
    4438
    4439 return SCIP_OKAY;
    4440}
    4441
    4442/** gets information about the quality of an LP solution
    4443 *
    4444 * Such information is usually only available, if also a (maybe not optimal) solution is available.
    4445 * The LPI should return SCIP_INVALID for @p quality, if the requested quantity is not available.
    4446 */
    4448 SCIP_LPI* lpi, /**< LP interface structure */
    4449 SCIP_LPSOLQUALITY qualityindicator, /**< indicates which quality should be returned */
    4450 SCIP_Real* quality /**< pointer to store quality number */
    4451 )
    4452{ /*lint --e{715}*/
    4453 const char* what;
    4454 int ret;
    4455
    4456 assert(lpi != NULL);
    4457 assert(lpi->grbmodel != NULL);
    4458 assert(quality != NULL);
    4459
    4460 SCIPdebugMessage("requesting solution quality from Gurobi: quality %d\n", qualityindicator);
    4461
    4462 switch( qualityindicator )
    4463 {
    4465 what = GRB_DBL_ATTR_KAPPA;
    4466 break;
    4467
    4469 what = GRB_DBL_ATTR_KAPPA_EXACT;
    4470 break;
    4471
    4472 default:
    4473 SCIPerrorMessage("Solution quality %d unknown.\n", qualityindicator);
    4474 return SCIP_INVALIDDATA;
    4475 }
    4476
    4477 ret = GRBgetdblattr(lpi->grbmodel, what, quality);
    4478 if( ret != 0 )
    4479 *quality = SCIP_INVALID;
    4480
    4481 return SCIP_OKAY;
    4482}
    4483
    4484/**@} */
    4485
    4486
    4487
    4488
    4489/*
    4490 * LP Basis Methods
    4491 */
    4492
    4493/**@name LP Basis Methods */
    4494/**@{ */
    4495
    4496/** gets current basis status for columns and rows; arrays must be large enough to store the basis status */
    4498 SCIP_LPI* lpi, /**< LP interface structure */
    4499 int* cstat, /**< array to store column basis status, or NULL */
    4500 int* rstat /**< array to store row basis status, or NULL */
    4501 )
    4502{
    4503 int nrows;
    4504 int ncols;
    4505
    4506 assert(lpi != NULL);
    4507 assert(lpi->grbmodel != NULL);
    4508
    4509 SCIPdebugMessage("saving Gurobi basis into %p/%p\n", (void*) cstat, (void*) rstat);
    4510
    4511 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
    4512 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    4513
    4514 if( rstat != NULL )
    4515 {
    4516 int i;
    4517
    4518 SCIP_CALL( ensureSidechgMem(lpi, nrows) );
    4519
    4520 CHECK_ZERO( lpi->messagehdlr, GRBgetintattrarray(lpi->grbmodel, GRB_INT_ATTR_CBASIS, 0, nrows, rstat) );
    4521 CHECK_ZERO( lpi->messagehdlr, GRBgetcharattrarray(lpi->grbmodel, GRB_CHAR_ATTR_SENSE, 0, nrows, lpi->senarray) );
    4522
    4523 for( i = 0; i < nrows; ++i )
    4524 {
    4525 if ( lpi->rngrowmap != NULL && lpi->rngrowmap[i] >= 0 && rstat[i] != GRB_BASIC )
    4526 {
    4527 int idx;
    4528
    4529 /* get range row basis status from corresponding range variable */
    4530 idx = ncols + lpi->rngrowmap[i];
    4531 assert(lpi->rngrowmap[i] < lpi->nrngrows);
    4532 CHECK_ZERO( lpi->messagehdlr, GRBgetintattrelement(lpi->grbmodel, GRB_INT_ATTR_VBASIS, idx, &rstat[i]) );
    4533
    4534 switch( rstat[i] )
    4535 {
    4536 case GRB_BASIC:
    4537 rstat[i] = (int) SCIP_BASESTAT_BASIC;
    4538 break;
    4539
    4540 case GRB_NONBASIC_LOWER:
    4541 rstat[i] = (int) SCIP_BASESTAT_LOWER;
    4542 break;
    4543
    4544 case GRB_NONBASIC_UPPER:
    4545 rstat[i] = (int) SCIP_BASESTAT_UPPER;
    4546 break;
    4547
    4548 /*lint -fallthrough*/
    4549 case GRB_SUPERBASIC:
    4550 default:
    4551 SCIPerrorMessage("invalid basis status %d for ranged row.\n", rstat[i]);
    4552 SCIPABORT();
    4553 return SCIP_INVALIDDATA; /*lint !e527*/
    4554 }
    4555 }
    4556 else
    4557 {
    4558 /* Slack variables can only be basic or at their lower bounds in Gurobi. */
    4559 switch( rstat[i] )
    4560 {
    4561 case GRB_BASIC:
    4562 rstat[i] = (int) SCIP_BASESTAT_BASIC;
    4563 break;
    4564
    4565 case GRB_NONBASIC_LOWER:
    4566 if ( lpi->senarray[i] == '>' || lpi->senarray[i] == '=' )
    4567 rstat[i] = (int) SCIP_BASESTAT_LOWER;
    4568 else
    4569 {
    4570 assert( lpi->senarray[i] == '<' );
    4571 rstat[i] = (int) SCIP_BASESTAT_UPPER;
    4572 }
    4573 break;
    4574
    4575 /*lint -fallthrough*/
    4576 case GRB_NONBASIC_UPPER:
    4577 case GRB_SUPERBASIC:
    4578 default:
    4579 SCIPerrorMessage("invalid basis status %d for row.\n", rstat[i]);
    4580 SCIPABORT();
    4581 return SCIP_INVALIDDATA; /*lint !e527*/
    4582 }
    4583 }
    4584 }
    4585 }
    4586
    4587 if( cstat != 0 )
    4588 {
    4589 int j;
    4590
    4591 CHECK_ZERO( lpi->messagehdlr, GRBgetintattrarray(lpi->grbmodel, GRB_INT_ATTR_VBASIS, 0, ncols, cstat) );
    4592
    4593 for( j = 0; j < ncols; ++j )
    4594 {
    4595 switch( cstat[j] )
    4596 {
    4597 case GRB_BASIC:
    4598 cstat[j] = (int) SCIP_BASESTAT_BASIC;
    4599 break;
    4600
    4601 case GRB_NONBASIC_LOWER:
    4602 cstat[j] = (int) SCIP_BASESTAT_LOWER;
    4603 break;
    4604
    4605 case GRB_NONBASIC_UPPER:
    4606 cstat[j] = (int) SCIP_BASESTAT_UPPER;
    4607 break;
    4608
    4609 case GRB_SUPERBASIC:
    4610 cstat[j] = (int) SCIP_BASESTAT_ZERO;
    4611 break;
    4612
    4613 default:
    4614 SCIPerrorMessage("invalid basis status %d for column.\n", cstat[j]);
    4615 SCIPABORT();
    4616 return SCIP_INVALIDDATA; /*lint !e527*/
    4617 }
    4618 }
    4619 }
    4620
    4621 return SCIP_OKAY;
    4622}
    4623
    4624/** sets current basis status for columns and rows */
    4626 SCIP_LPI* lpi, /**< LP interface structure */
    4627 const int* cstat, /**< array with column basis status */
    4628 const int* rstat /**< array with row basis status */
    4629 )
    4630{
    4631 int i, j;
    4632 int nrows, ncols;
    4633#ifndef NDEBUG
    4634 int nrngsfound = 0;
    4635#endif
    4636
    4637 assert(lpi != NULL);
    4638 assert(lpi->grbmodel != NULL);
    4639
    4640 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    4641 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
    4642
    4643 assert(cstat != NULL || ncols == 0);
    4644 assert(rstat != NULL || nrows == 0);
    4645
    4646 SCIPdebugMessage("loading basis %p/%p into Gurobi\n", (void*) cstat, (void*) rstat);
    4647
    4648 invalidateSolution(lpi);
    4649
    4650 SCIP_CALL( ensureCstatMem(lpi, ncols+lpi->nrngrows) );
    4651 SCIP_CALL( ensureRstatMem(lpi, nrows) );
    4652
    4653 for( i = 0; i < nrows; ++i )
    4654 {
    4655 if ( lpi->rngrowmap != NULL && lpi->rngrowmap[i] >= 0 )
    4656 {
    4657 int idx;
    4658
    4659 /* set basis status of corresponding range variable; ranged row is always non-basic */
    4660 idx = ncols + lpi->rngrowmap[i];
    4661 assert(lpi->rngrowmap[i] < lpi->nrngrows);
    4662 lpi->cstat[idx] = lpi->rstat[i];
    4663 lpi->rstat[i] = GRB_NONBASIC_LOWER;
    4664#ifndef NDEBUG
    4665 nrngsfound++;
    4666#endif
    4667 }
    4668 else
    4669 {
    4670 switch( rstat[i] ) /*lint !e613*/
    4671 {
    4673 lpi->rstat[i] = GRB_BASIC;
    4674 break;
    4675
    4677 {
    4678#ifndef NDEBUG
    4679 char sense;
    4680 CHECK_ZERO( lpi->messagehdlr, GRBgetcharattrarray(lpi->grbmodel, GRB_CHAR_ATTR_SENSE, i, 1, &sense) );
    4681 assert( sense == '<' );
    4682#endif
    4683 /* Slack variables can only be basic or at their lower bounds in Gurobi. */
    4684 lpi->rstat[i] = GRB_NONBASIC_LOWER;
    4685 break;
    4686 }
    4687
    4689 {
    4690#ifndef NDEBUG
    4691 char sense;
    4692 CHECK_ZERO( lpi->messagehdlr, GRBgetcharattrarray(lpi->grbmodel, GRB_CHAR_ATTR_SENSE, i, 1, &sense) );
    4693 assert( sense == '>' || sense == '=' );
    4694#endif
    4695 lpi->rstat[i] = GRB_NONBASIC_LOWER;
    4696 break;
    4697 }
    4698
    4699 case SCIP_BASESTAT_ZERO:
    4700 default:
    4701 SCIPerrorMessage("invalid basis status %d for row.\n", rstat[i]); /*lint !e613*/
    4702 SCIPABORT();
    4703 return SCIP_INVALIDDATA; /*lint !e527*/
    4704 }
    4705 }
    4706 }
    4707
    4708 for( j = 0; j < ncols; ++j )
    4709 {
    4710 switch( cstat[j] ) /*lint !e613*/
    4711 {
    4713 lpi->cstat[j] = GRB_BASIC;
    4714 break;
    4715
    4717 lpi->cstat[j] = GRB_NONBASIC_LOWER;
    4718 break;
    4719
    4721 lpi->cstat[j] = GRB_NONBASIC_UPPER;
    4722 break;
    4723
    4724 case SCIP_BASESTAT_ZERO:
    4725 lpi->cstat[j] = GRB_SUPERBASIC;
    4726 break;
    4727
    4728 default:
    4729 SCIPerrorMessage("invalid basis status %d\n", cstat[j]); /*lint !e613*/
    4730 SCIPABORT();
    4731 return SCIP_INVALIDDATA; /*lint !e527*/
    4732 }
    4733 }
    4734
    4735#ifndef NDEBUG
    4736 assert(nrngsfound == lpi->nrngrows);
    4737#endif
    4738
    4739 CHECK_ZERO( lpi->messagehdlr, GRBsetintattrarray(lpi->grbmodel, GRB_INT_ATTR_CBASIS, 0, nrows, lpi->rstat) );
    4740 CHECK_ZERO( lpi->messagehdlr, GRBsetintattrarray(lpi->grbmodel, GRB_INT_ATTR_VBASIS, 0, ncols+lpi->nrngrows, lpi->cstat) );
    4741
    4742 /* flush model changes */
    4743 CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
    4744
    4745 return SCIP_OKAY;
    4746}
    4747
    4748/** returns the indices of the basic columns and rows; basic column n gives value n, basic row m gives value -1-m */
    4750 SCIP_LPI* lpi, /**< LP interface structure */
    4751 int* bind /**< pointer to store basis indices ready to keep number of rows entries */
    4752 )
    4753{
    4754 int i;
    4755 int nrows;
    4756 int ncols;
    4757 int ngrbcols;
    4758 int* bhead;
    4759 int status;
    4760
    4761 assert(lpi != NULL);
    4762 assert(lpi->grbmodel != NULL);
    4763 assert(bind != NULL);
    4764
    4765 SCIPdebugMessage("getting basis information\n");
    4766
    4767 /* check whether we have to reoptimize */
    4768 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &status) );
    4769 if ( status == GRB_LOADED || status == GRB_INTERRUPTED || status == GRB_INPROGRESS )
    4770 {
    4772 }
    4773
    4774 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
    4775 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    4776 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMVARS, &ngrbcols) );
    4777
    4778 /**@todo avoid memory allocation by using bind directly */
    4779 /* get space for bhead */
    4780 SCIP_ALLOC( BMSallocMemoryArray(&bhead, nrows) );
    4781
    4782 /* get basis indices */
    4783 CHECK_ZERO( lpi->messagehdlr, GRBgetBasisHead(lpi->grbmodel, bhead) );
    4784
    4785 for (i = 0; i < nrows; ++i)
    4786 {
    4787 /* entries >= ncols refer to slack variables */
    4788 if ( bhead[i] < ncols )
    4789 bind[i] = bhead[i];
    4790 else if ( bhead[i] < ngrbcols )
    4791 {
    4792 /* a range variable: use corresponding ranged row */
    4793 int rngrow = bhead[i]-ncols;
    4794 assert(rngrow < lpi->nrngrows);
    4795 assert(lpi->rngrowmap != NULL);
    4796 assert(lpi->rngrows != NULL);
    4797 assert(lpi->rngrowmap[lpi->rngrows[rngrow]] == rngrow);
    4798 bind[i] = -1 - lpi->rngrows[rngrow];
    4799 }
    4800 else
    4801 {
    4802 /* a regular slack variable */
    4803 bind[i] = -1 - (bhead[i] - ngrbcols);
    4804 }
    4805 }
    4806 BMSfreeMemoryArray(&bhead);
    4807
    4808 return SCIP_OKAY;
    4809}
    4810
    4811/** get row of inverse basis matrix B^-1
    4812 *
    4813 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
    4814 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
    4815 * see also the explanation in lpi.h.
    4816 *
    4817 * @todo check that the result is in terms of the LP interface definition
    4818 */
    4820 SCIP_LPI* lpi, /**< LP interface structure */
    4821 int r, /**< row number */
    4822 SCIP_Real* coef, /**< pointer to store the coefficients of the row */
    4823 int* inds, /**< array to store the non-zero indices, or NULL */
    4824 int* ninds /**< pointer to store the number of non-zero indices, or NULL
    4825 * (-1: if we do not store sparsity information) */
    4826 )
    4827{
    4828 SVECTOR x;
    4829 SVECTOR b;
    4830 int nrows;
    4831 double val;
    4832 int ind;
    4833 int status;
    4834 int ncols;
    4835 int ngrbcols;
    4836
    4837 assert(lpi != NULL);
    4838 assert(lpi->grbmodel != NULL);
    4839 assert(coef != NULL);
    4840
    4841 SCIPdebugMessage("getting binv-row %d\n", r);
    4842
    4843 /* check whether we have to reoptimize */
    4844 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &status) );
    4845 if ( status == GRB_LOADED || status == GRB_INTERRUPTED || status == GRB_INPROGRESS )
    4846 {
    4848 }
    4849
    4850 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
    4851 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    4852 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMVARS, &ngrbcols) );
    4853
    4854 /* set up solution vector */
    4855 x.len = 0;
    4856 SCIP_ALLOC( BMSallocMemoryArray(&(x.ind), nrows) );
    4857 SCIP_ALLOC( BMSallocMemoryArray(&(x.val), nrows) );
    4858
    4859 /* get basis indices, temporarily using memory of x.ind */
    4860 CHECK_ZERO( lpi->messagehdlr, GRBgetBasisHead(lpi->grbmodel, x.ind) );
    4861
    4862 /* set up rhs */
    4863 b.len = 1;
    4864 ind = r;
    4865 val = 1.0;
    4866 if ( x.ind[r] > ncols )
    4867 {
    4868 /* the sign of the slack variables seems to be 1 for <= inequalities, equations, but -1 for >= inequalities and ranged rows */
    4869 if ( x.ind[r] < ngrbcols )
    4870 val = -1.0;
    4871 else
    4872 {
    4873 char sense;
    4874 CHECK_ZERO( lpi->messagehdlr, GRBgetcharattrarray(lpi->grbmodel, GRB_CHAR_ATTR_SENSE, x.ind[r] - ngrbcols, 1, &sense) );
    4875 if ( sense == '>' )
    4876 val = -1.0;
    4877 }
    4878 }
    4879 b.ind = &ind;
    4880 b.val = &val;
    4881
    4882 /* solve B^T x = e_r, which results in the r-th row of the basis inverse */
    4883 CHECK_ZERO( lpi->messagehdlr, GRBBSolve(lpi->grbmodel, &b, &x) );
    4884
    4885 /* size should be at most the number of rows */
    4886 assert( x.len <= nrows );
    4887
    4888 /* check whether we require a dense or sparse result vector */
    4889 if ( ninds != NULL && inds != NULL )
    4890 {
    4891 int idx;
    4892 int i;
    4893
    4894 /* copy sparse solution */
    4895 for (i = 0; i < x.len; ++i)
    4896 {
    4897 idx = (x.ind)[i];
    4898 assert( idx >= 0 && idx < nrows );
    4899 inds[i] = idx;
    4900 coef[idx] = (x.val)[i];
    4901 }
    4902 *ninds = x.len;
    4903 }
    4904 else
    4905 {
    4906 int idx;
    4907 int i;
    4908
    4909 /* copy solution to dense vector */
    4910 BMSclearMemoryArray(coef, nrows);
    4911 for (i = 0; i < x.len; ++i)
    4912 {
    4913 idx = (x.ind)[i];
    4914 assert( idx >= 0 && idx < nrows );
    4915 coef[idx] = (x.val)[i];
    4916 }
    4917 }
    4918
    4919 /* free solution space */
    4920 BMSfreeMemoryArray(&(x.val));
    4921 BMSfreeMemoryArray(&(x.ind));
    4922
    4923 return SCIP_OKAY;
    4924}
    4925
    4926/** get column of inverse basis matrix B^-1
    4927 *
    4928 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
    4929 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
    4930 * see also the explanation in lpi.h.
    4931 *
    4932 * @todo check that the result is in terms of the LP interface definition
    4933 */
    4935 SCIP_LPI* lpi, /**< LP interface structure */
    4936 int c, /**< column number of B^-1; this is NOT the number of the column in the LP;
    4937 * you have to call SCIPlpiGetBasisInd() to get the array which links the
    4938 * B^-1 column numbers to the row and column numbers of the LP!
    4939 * c must be between 0 and nrows-1, since the basis has the size
    4940 * nrows * nrows */
    4941 SCIP_Real* coef, /**< pointer to store the coefficients of the column */
    4942 int* inds, /**< array to store the non-zero indices, or NULL */
    4943 int* ninds /**< pointer to store the number of non-zero indices, or NULL
    4944 * (-1: if we do not store sparsity information) */
    4945 )
    4946{
    4947 SVECTOR x;
    4948 SVECTOR b;
    4949 int nrows;
    4950 double val;
    4951 int ind;
    4952 int status;
    4953 int ncols;
    4954 int ngrbcols;
    4955
    4956 assert(lpi != NULL);
    4957 assert(lpi->grbmodel != NULL);
    4958 assert(coef != NULL);
    4959
    4960 SCIPdebugMessage("getting binv-col %d\n", c);
    4961
    4962 /* check whether we have to reoptimize */
    4963 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &status) );
    4964 if ( status == GRB_LOADED || status == GRB_INTERRUPTED || status == GRB_INPROGRESS )
    4965 {
    4967 }
    4968
    4969 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
    4970 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    4971 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMVARS, &ngrbcols) );
    4972
    4973 /* set up solution vector */
    4974 x.len = 0;
    4975 SCIP_ALLOC( BMSallocMemoryArray(&(x.ind), nrows) );
    4976 SCIP_ALLOC( BMSallocMemoryArray(&(x.val), nrows) );
    4977
    4978 /* get basis indices, temporarily using memory of x.ind */
    4979 CHECK_ZERO( lpi->messagehdlr, GRBgetBasisHead(lpi->grbmodel, x.ind) );
    4980
    4981 /* set up rhs */
    4982 b.len = 1;
    4983 ind = c;
    4984 val = 1.0;
    4985 if ( x.ind[c] > ncols )
    4986 {
    4987 /* the sign of the slack variables seems to be 1 for <= inequalities, equations, but -1 for >= inequalities and ranged rows */
    4988 if ( x.ind[c] < ngrbcols )
    4989 val = -1.0;
    4990 else
    4991 {
    4992 char sense;
    4993 CHECK_ZERO( lpi->messagehdlr, GRBgetcharattrarray(lpi->grbmodel, GRB_CHAR_ATTR_SENSE, x.ind[c] - ngrbcols, 1, &sense) );
    4994 if ( sense == '>' )
    4995 val = -1.0;
    4996 }
    4997 }
    4998 b.ind = &ind;
    4999 b.val = &val;
    5000
    5001 /* solve B x = e_c, which results in the c-th columns of the basis inverse */
    5002 CHECK_ZERO( lpi->messagehdlr, GRBFSolve(lpi->grbmodel, &b, &x) );
    5003
    5004 /* size should be at most the number of rows */
    5005 assert( x.len <= nrows );
    5006
    5007 /* check whether we require a dense or sparse result vector */
    5008 if ( ninds != NULL && inds != NULL )
    5009 {
    5010 int idx;
    5011 int i;
    5012
    5013 /* copy sparse solution */
    5014 for (i = 0; i < x.len; ++i)
    5015 {
    5016 idx = (x.ind)[i];
    5017 assert( idx >= 0 && idx < nrows );
    5018 inds[i] = idx;
    5019 coef[idx] = (x.val)[i];
    5020 }
    5021 *ninds = x.len;
    5022 }
    5023 else
    5024 {
    5025 int idx;
    5026 int i;
    5027
    5028 /* copy solution to dense vector */
    5029 BMSclearMemoryArray(coef, nrows);
    5030 for (i = 0; i < x.len; ++i)
    5031 {
    5032 idx = (x.ind)[i];
    5033 assert( idx >= 0 && idx < nrows );
    5034 coef[idx] = (x.val)[i];
    5035 }
    5036 }
    5037
    5038 /* free solution space and basis index array */
    5039 BMSfreeMemoryArray(&(x.val));
    5040 BMSfreeMemoryArray(&(x.ind));
    5041
    5042 return SCIP_OKAY;
    5043}
    5044
    5045/** get row of inverse basis matrix times constraint matrix B^-1 * A
    5046 *
    5047 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
    5048 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
    5049 * see also the explanation in lpi.h.
    5050 *
    5051 * @todo check that the result is in terms of the LP interface definition
    5052 */
    5054 SCIP_LPI* lpi, /**< LP interface structure */
    5055 int r, /**< row number */
    5056 const SCIP_Real* binvrow, /**< row in (A_B)^-1 from prior call to SCIPlpiGetBInvRow(), or NULL */
    5057 SCIP_Real* coef, /**< vector to return coefficients of the row */
    5058 int* inds, /**< array to store the non-zero indices, or NULL */
    5059 int* ninds /**< pointer to store the number of non-zero indices, or NULL
    5060 * (-1: if we do not store sparsity information) */
    5061 )
    5062{ /*lint --e{715}*/
    5063 SVECTOR x;
    5064 int nrows;
    5065 int ncols;
    5066 int ngrbcols;
    5067 int status;
    5068 SCIP_Bool isslackvar;
    5069
    5070 assert(lpi != NULL);
    5071 assert(lpi->grbmodel != NULL);
    5072 assert(coef != NULL);
    5073 SCIP_UNUSED( binvrow );
    5074
    5075 SCIPdebugMessage("getting binv-row %d\n", r);
    5076
    5077 /* check whether we have to reoptimize */
    5078 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &status) );
    5079 if ( status == GRB_LOADED || status == GRB_INTERRUPTED || status == GRB_INPROGRESS )
    5080 {
    5082 }
    5083
    5084 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
    5085 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    5086 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMVARS, &ngrbcols) );
    5087 assert( r >= 0 && r < nrows );
    5088
    5089 x.len = 0;
    5090 SCIP_ALLOC( BMSallocMemoryArray(&(x.ind), ngrbcols + nrows) );
    5091 SCIP_ALLOC( BMSallocMemoryArray(&(x.val), ngrbcols + nrows) );
    5092
    5093 /* get basis indices, temporarily using memory of x.ind: if r corresponds to a slack variable with coefficient -1 we
    5094 * have to negate all values
    5095 */
    5096 SCIP_CALL( SCIPlpiGetBasisInd(lpi, x.ind) );
    5097 isslackvar = ((x.ind)[r] < 0);
    5098
    5099 /* retrieve row */
    5100 CHECK_ZERO( lpi->messagehdlr, GRBBinvRowi(lpi->grbmodel, r, &x) );
    5101
    5102 /* size should be at most the number of columns plus rows for slack variables */
    5103 assert( x.len <= ngrbcols + nrows );
    5104
    5105 /* check whether we require a dense or sparse result vector */
    5106 if ( ninds != NULL && inds != NULL )
    5107 {
    5108 int idx;
    5109 int k;
    5110 int j;
    5111
    5112 /* Copy sparse solution: Column indices ngrbcols and larger correspond to slack variables artificially introduced
    5113 * by Gurobi; column indices ncols, ncols+1, ..., ngrbcols-1 correspond to slack variables introduced by the LPI
    5114 * implementation. Both must simply be ignored.
    5115 */
    5116 k = 0;
    5117 for (j = 0; j < x.len; ++j)
    5118 {
    5119 idx = (x.ind)[j];
    5120 assert( idx >= 0 && idx < ngrbcols+nrows );
    5121 if ( idx < ncols )
    5122 {
    5123 inds[k++] = idx;
    5124 coef[idx] = (x.val)[j];
    5125 if( isslackvar )
    5126 coef[idx] *= -1.0;
    5127 }
    5128 }
    5129 *ninds = k;
    5130 }
    5131 else
    5132 {
    5133 int idx;
    5134 int j;
    5135
    5136 /* Copy dense solution (see comment above). */
    5137 BMSclearMemoryArray(coef, ncols);
    5138 for (j = 0; j < x.len; ++j)
    5139 {
    5140 idx = (x.ind)[j];
    5141 assert( idx >= 0 && idx < ngrbcols+nrows );
    5142 if ( idx < ncols )
    5143 {
    5144 coef[idx] = (x.val)[j];
    5145 if( isslackvar )
    5146 coef[idx] *= -1.0;
    5147 }
    5148 }
    5149 }
    5150
    5151 /* free solution space */
    5152 BMSfreeMemoryArray(&(x.val));
    5153 BMSfreeMemoryArray(&(x.ind));
    5154
    5155 return SCIP_OKAY;
    5156}
    5157
    5158/** get column of inverse basis matrix times constraint matrix B^-1 * A
    5159 *
    5160 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
    5161 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
    5162 * see also the explanation in lpi.h.
    5163 *
    5164 * @todo check that the result is in terms of the LP interface definition
    5165 */
    5167 SCIP_LPI* lpi, /**< LP interface structure */
    5168 int c, /**< column number */
    5169 SCIP_Real* coef, /**< vector to return coefficients of the column */
    5170 int* inds, /**< array to store the non-zero indices, or NULL */
    5171 int* ninds /**< pointer to store the number of non-zero indices, or NULL
    5172 * (-1: if we do not store sparsity information) */
    5173 )
    5174{ /*lint --e{715}*/
    5175 SVECTOR x;
    5176 int* bind;
    5177 int nrows;
    5178 int status;
    5179
    5180 assert(lpi != NULL);
    5181 assert(lpi->grbmodel != NULL);
    5182 assert(coef != NULL);
    5183
    5184 SCIPdebugMessage("getting binv-col %d\n", c);
    5185
    5186 /* check whether we have to reoptimize */
    5187 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &status) );
    5188 if ( status == GRB_LOADED || status == GRB_INTERRUPTED || status == GRB_INPROGRESS )
    5189 {
    5191 }
    5192
    5193 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
    5194
    5195 x.len = 0;
    5196 SCIP_ALLOC( BMSallocMemoryArray(&(x.ind), nrows) );
    5197 SCIP_ALLOC( BMSallocMemoryArray(&(x.val), nrows) );
    5198
    5199 CHECK_ZERO( lpi->messagehdlr, GRBBinvColj(lpi->grbmodel, c, &x) );
    5200
    5201 /* size should be at most the number of rows */
    5202 assert( x.len <= nrows );
    5203
    5204 /* get basis indices: entries that correspond to slack variables with coefficient -1 must be negated */
    5205 SCIP_ALLOC( BMSallocMemoryArray(&bind, nrows) );
    5206 SCIP_CALL( SCIPlpiGetBasisInd(lpi, bind) );
    5207
    5208 /* check whether we require a dense or sparse result vector */
    5209 if ( ninds != NULL && inds != NULL )
    5210 {
    5211 int idx;
    5212 int j;
    5213
    5214 /* copy sparse solution */
    5215 for (j = 0; j < x.len; ++j)
    5216 {
    5217 idx = (x.ind)[j];
    5218 assert( idx >= 0 && idx < nrows );
    5219 inds[j] = idx;
    5220 coef[idx] = (x.val)[j];
    5221 if( bind[idx] < 0 )
    5222 coef[idx] *= -1.0;
    5223 }
    5224 *ninds = x.len;
    5225 }
    5226 else
    5227 {
    5228 int idx;
    5229 int j;
    5230
    5231 /* copy dense solution */
    5232 BMSclearMemoryArray(coef, nrows);
    5233 for (j = 0; j < x.len; ++j)
    5234 {
    5235 idx = (x.ind)[j];
    5236 assert( idx >= 0 && idx < nrows );
    5237 coef[idx] = (x.val)[j];
    5238 if( bind[idx] < 0 )
    5239 coef[idx] *= -1.0;
    5240 }
    5241 }
    5242
    5243 /* free solution space and basis index array */
    5244 BMSfreeMemoryArray(&bind);
    5245 BMSfreeMemoryArray(&(x.val));
    5246 BMSfreeMemoryArray(&(x.ind));
    5247
    5248 return SCIP_OKAY;
    5249}
    5250
    5251/**@} */
    5252
    5253
    5254
    5255
    5256/*
    5257 * LP State Methods
    5258 */
    5259
    5260/**@name LP State Methods */
    5261/**@{ */
    5262
    5263/** stores LPi state (like basis information) into lpistate object */
    5265 SCIP_LPI* lpi, /**< LP interface structure */
    5266 BMS_BLKMEM* blkmem, /**< block memory */
    5267 SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
    5268 )
    5269{
    5270 SCIP_Bool success;
    5271 int ncols;
    5272 int nrows;
    5273
    5274 assert(blkmem != NULL);
    5275 assert(lpi != NULL);
    5276 assert(lpi->grbmodel != NULL);
    5277 assert(lpistate != NULL);
    5278
    5279 /* if there is no basis information available, no state can be saved */
    5280 if( !lpi->solisbasic )
    5281 {
    5282 *lpistate = NULL;
    5283 return SCIP_OKAY;
    5284 }
    5285
    5286 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
    5287 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    5288 assert(ncols >= 0);
    5289 assert(nrows >= 0);
    5290
    5291 /* get unpacked basis information from Gurobi */
    5292 SCIP_CALL( getBase(lpi, &success) );
    5293
    5294 if ( success )
    5295 {
    5296 /* allocate lpistate data */
    5297 SCIP_CALL( lpistateCreate(lpistate, blkmem, ncols, nrows, lpi->nrngrows) );
    5298 (*lpistate)->ncols = ncols;
    5299 (*lpistate)->nrows = nrows;
    5300 (*lpistate)->nrngrows = lpi->nrngrows;
    5301
    5302 SCIPdebugMessage("stored Gurobi LPI state in %p (%d cols, %d rows, %d ranged rows)\n",
    5303 (void*) *lpistate, ncols, nrows, lpi->nrngrows);
    5304
    5305 /* pack LPi state data */
    5306 lpistatePack(*lpistate, lpi->cstat, lpi->rstat);
    5307 }
    5308 else
    5309 {
    5310 /* In this case no basis information is available. Since SCIP expects the information to work in any case, we
    5311 * allocate the lpistate, but do not use the packed information. This might happen if the model is infeasible,
    5312 * since Gurobi currently does not return basis information in this case. */
    5313 SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpistate) );
    5314 (*lpistate)->ncols = ncols;
    5315 (*lpistate)->nrows = nrows;
    5316 (*lpistate)->nrngrows = lpi->nrngrows;
    5317 (*lpistate)->packrstat = NULL;
    5318 (*lpistate)->packcstat = NULL;
    5319 }
    5320
    5321 return SCIP_OKAY;
    5322}
    5323
    5324/** loads LPi state (like basis information) into solver; note that the LP might have been extended with additional
    5325 * columns and rows since the state was stored with SCIPlpiGetState()
    5326 */
    5328 SCIP_LPI* lpi, /**< LP interface structure */
    5329 BMS_BLKMEM* blkmem, /**< block memory */
    5330 const SCIP_LPISTATE* lpistate /**< LPi state information (like basis information), or NULL */
    5331 )
    5332{
    5333 int ncols;
    5334 int nrows;
    5335 int i;
    5336
    5337 assert(blkmem != NULL);
    5338 assert(lpi != NULL);
    5339 assert(lpi->grbmodel != NULL);
    5340
    5341 /* if there was no basis information available, the LPI state was not stored */
    5342 if( lpistate == NULL || lpistate->packrstat == NULL || lpistate->packcstat == NULL )
    5343 return SCIP_OKAY;
    5344
    5345 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
    5346 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    5347 assert(lpistate->ncols <= ncols);
    5348 assert(lpistate->nrows <= nrows);
    5349 assert(lpistate->nrngrows <= lpi->nrngrows);
    5350
    5351 SCIPdebugMessage("loading LPI state %p (%d cols, %d rows, %d ranged rows) into Gurobi LP with %d cols, %d rows, and %d ranged rows\n",
    5352 (void*) lpistate, lpistate->ncols, lpistate->nrows, lpistate->nrngrows, ncols, nrows, lpi->nrngrows);
    5353
    5354 if( lpistate->ncols == 0 || lpistate->nrows == 0 )
    5355 return SCIP_OKAY;
    5356
    5357 /* allocate enough memory for storing uncompressed basis information */
    5358 SCIP_CALL( ensureCstatMem(lpi, ncols + lpi->nrngrows) );
    5359 SCIP_CALL( ensureRstatMem(lpi, nrows) );
    5360
    5361 /* unpack LPi state data */
    5362 lpistateUnpack(lpistate, lpi->cstat, lpi->rstat);
    5363
    5364 if ( lpistate->nrngrows > 0 && lpistate->ncols < ncols )
    5365 {
    5366 /* New columns have been added: need to move range variable information */
    5367 memmove(&lpi->cstat[ncols], &lpi->cstat[lpistate->ncols], (size_t) lpistate->nrngrows * sizeof(*lpi->cstat)); /*lint !e571*/
    5368 }
    5369
    5370 /* extend the basis to the current LP beyond the previously existing columns */
    5371 for( i = lpistate->ncols; i < ncols; ++i )
    5372 {
    5373 SCIP_Real bnd;
    5374 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_LB, i, &bnd) );
    5375 if ( SCIPlpiIsInfinity(lpi, REALABS(bnd)) )
    5376 {
    5377 /* if lower bound is +/- infinity -> try upper bound */
    5378 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_UB, i, &bnd) );
    5379 if ( SCIPlpiIsInfinity(lpi, REALABS(bnd)) )
    5380 lpi->cstat[i] = (int) SCIP_BASESTAT_ZERO; /* variable is free */
    5381 else
    5382 lpi->cstat[i] = (int) SCIP_BASESTAT_UPPER; /* use finite upper bound */
    5383 }
    5384 else
    5385 lpi->cstat[i] = (int) SCIP_BASESTAT_LOWER; /* use finite lower bound */
    5386 }
    5387 for( i = lpistate->nrngrows; i < lpi->nrngrows; ++i )
    5388 lpi->cstat[ncols + i] = (int) SCIP_BASESTAT_LOWER;
    5389 for( i = lpistate->nrows; i < nrows; ++i )
    5390 lpi->rstat[i] = (int) SCIP_BASESTAT_BASIC;
    5391
    5392 /* load basis information into Gurobi */
    5393 SCIP_CALL( setBase(lpi) );
    5394
    5395 return SCIP_OKAY;
    5396}
    5397
    5398/** clears current LPi state (like basis information) of the solver */
    5400 SCIP_LPI* lpi /**< LP interface structure */
    5401 )
    5402{
    5403 assert(lpi != NULL);
    5404 assert(lpi->grbmodel != NULL);
    5405
    5406#if GRB_VERSION_MAJOR < 8
    5407 CHECK_ZERO( lpi->messagehdlr, GRBresetmodel(lpi->grbmodel) );
    5408#else
    5409 CHECK_ZERO( lpi->messagehdlr, GRBreset(lpi->grbmodel, 1) );
    5410#endif
    5411
    5412 return SCIP_OKAY;
    5413}
    5414
    5415/** frees LPi state information */
    5417 SCIP_LPI* lpi, /**< LP interface structure */
    5418 BMS_BLKMEM* blkmem, /**< block memory */
    5419 SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
    5420 )
    5421{
    5422 assert(lpi != NULL);
    5423 assert(lpistate != NULL);
    5424 assert(blkmem != NULL);
    5425
    5426 if( *lpistate != NULL )
    5427 lpistateFree(lpistate, blkmem);
    5428
    5429 return SCIP_OKAY;
    5430}
    5431
    5432/** checks whether the given LP state contains simplex basis information */
    5434 SCIP_LPI* lpi, /**< LP interface structure */
    5435 SCIP_LPISTATE* lpistate /**< LP state information (like basis information), or NULL */
    5436 )
    5437{ /*lint --e{715}*/
    5438 assert(lpi != NULL);
    5439 return (lpistate != NULL && lpistate->packcstat != NULL);
    5440}
    5441
    5442/** reads LP state (like basis information from a file */
    5444 SCIP_LPI* lpi, /**< LP interface structure */
    5445 const char* fname /**< file name */
    5446 )
    5447{
    5448 size_t l;
    5449
    5450 assert(lpi != NULL);
    5451 assert(lpi->grbmodel != NULL);
    5452 assert(fname != NULL);
    5453
    5454 SCIPdebugMessage("reading LP state from file <%s>\n", fname);
    5455
    5456 /* gurobi reads a basis if the extension is ".bas" */
    5457 l = strlen(fname);
    5458 if ( l > 4 && fname[l-4] == '.' && fname[l-3] == 'b' && fname[l-2] == 'a' && fname[l-1] == 's' )
    5459 {
    5460 CHECK_ZERO( lpi->messagehdlr, GRBread(lpi->grbmodel, fname) );
    5461 }
    5462 else
    5463 {
    5464 SCIPerrorMessage("To read a basis with gurobi, the extension has to be '.bas'.\n");
    5465 return SCIP_LPERROR;
    5466 }
    5467
    5468 return SCIP_OKAY;
    5469}
    5470
    5471/** writes LPi state (i.e. basis information) to a file */
    5473 SCIP_LPI* lpi, /**< LP interface structure */
    5474 const char* fname /**< file name */
    5475 )
    5476{
    5477 size_t l;
    5478
    5479 assert(lpi != NULL);
    5480 assert(lpi->grbmodel != NULL);
    5481 assert(fname != NULL);
    5482
    5483 SCIPdebugMessage("writing basis state to file <%s>\n", fname);
    5484
    5485 /* gurobi writes the basis if the extension is ".bas" */
    5486 l = strlen(fname);
    5487 if ( l > 4 && fname[l-4] == '.' && fname[l-3] == 'b' && fname[l-2] == 'a' && fname[l-1] == 's' )
    5488 {
    5489 CHECK_ZERO( lpi->messagehdlr, GRBwrite(lpi->grbmodel, fname) );
    5490 }
    5491 else
    5492 {
    5493 char name[SCIP_MAXSTRLEN];
    5494
    5495 /* force extension to be ".bas" */
    5496 if ( strlen(fname) > SCIP_MAXSTRLEN-4)
    5497 {
    5498 SCIPerrorMessage("Basis file name too long.\n");
    5499 return SCIP_LPERROR;
    5500 }
    5501 (void) snprintf(name, SCIP_MAXSTRLEN, "%s.bas", fname);
    5502 CHECK_ZERO( lpi->messagehdlr, GRBwrite(lpi->grbmodel, fname) );
    5503 }
    5504
    5505 return SCIP_OKAY;
    5506}
    5507
    5508/**@} */
    5509
    5510
    5511
    5512
    5513/*
    5514 * LP Pricing Norms Methods
    5515 */
    5516
    5517/**@name LP Pricing Norms Methods */
    5518/**@{ */
    5519
    5520/** stores LPi pricing norms information */
    5522 SCIP_LPI* lpi, /**< LP interface structure */
    5523 BMS_BLKMEM* blkmem, /**< block memory */
    5524 SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information */
    5525 )
    5526{ /*lint --e{715}*/
    5527 int hasnorm;
    5528 int ncols;
    5529 int nrows;
    5530
    5531 assert(blkmem != NULL);
    5532 assert(lpi != NULL);
    5533 assert(lpi->grbmodel != NULL);
    5534 assert(lpinorms != NULL);
    5535
    5536 *lpinorms = NULL;
    5537
    5538 /* if there is no basis information available (e.g. after barrier without crossover), norms cannot be saved */
    5539 if( !lpi->solisbasic )
    5540 return SCIP_OKAY;
    5541
    5542 /* check if dual norms are available:
    5543 * value 0: no basis, so no norms available
    5544 * value 1: basis exists, so norms can be computed
    5545 * value 2: norms are available
    5546 */
    5547 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_HASDUALNORM, &hasnorm) );
    5548 if( hasnorm <= 1 )
    5549 return SCIP_OKAY;
    5550
    5551 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMVARS, &ncols) );
    5552 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMCONSTRS, &nrows) );
    5553
    5554 /* allocate lpinorms data */
    5555 SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpinorms) );
    5556 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpinorms)->colnorm, ncols) );
    5557 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpinorms)->rownorm, nrows) );
    5558 (*lpinorms)->ncols = ncols;
    5559 (*lpinorms)->nrows = nrows;
    5560
    5561 /* query dual norms from Gurobi */
    5562 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_VDUALNORM, 0, ncols, (*lpinorms)->colnorm) );
    5563 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_CDUALNORM, 0, nrows, (*lpinorms)->rownorm) );
    5564
    5565 return SCIP_OKAY;
    5566}
    5567
    5568/** loads LPi pricing norms into solver; note that the LP might have been extended with additional
    5569 * columns and rows since the state was stored with SCIPlpiGetNorms()
    5570 */
    5572 SCIP_LPI* lpi, /**< LP interface structure */
    5573 BMS_BLKMEM* blkmem, /**< block memory */
    5574 const SCIP_LPINORMS* lpinorms /**< LPi pricing norms information, or NULL */
    5575 )
    5576{ /*lint --e{715}*/
    5577 int error;
    5578
    5579 assert(blkmem != NULL);
    5580 assert(lpi != NULL);
    5581
    5582 /* if there was no pricing norms information available, the LPI norms were not stored */
    5583 if( lpinorms == NULL )
    5584 return SCIP_OKAY;
    5585
    5586 /* store dual norms in Gurobi */
    5587 error = GRBsetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_VDUALNORM, 0, lpinorms->ncols, lpinorms->colnorm);
    5588 /* it can fail to set the norms if no basis was previously set, e.g.,
    5589 * this can happen if flushing an LP did not change anything and
    5590 * therefore no basis was set, as a result Gurobi has no extra user
    5591 * warmstart information and cannot set norms */
    5592#ifdef SCIP_DEBUG
    5593 if( error )
    5594 SCIPmessagePrintWarning(lpi->messagehdlr, "Warning: setting dual variable norms failed with Gurobi error %d\n", error);
    5595#else
    5596 (void)error;
    5597#endif
    5598
    5599 error = GRBsetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_CDUALNORM, 0, lpinorms->nrows, lpinorms->rownorm);
    5600 /* it can fail to set the norms if no basis was previously set, e.g.,
    5601 * this can happen if flushing an LP did not change anything and
    5602 * therefore no basis was set, as a result Gurobi has no extra user
    5603 * warmstart information and cannot set norms */
    5604#ifdef SCIP_DEBUG
    5605 if( error )
    5606 SCIPmessagePrintWarning(lpi->messagehdlr, "Warning: setting dual constraint norms failed with Gurobi error %d\n", error);
    5607#else
    5608 (void)error;
    5609#endif
    5610
    5611 return SCIP_OKAY;
    5612}
    5613
    5614/** frees pricing norms information */
    5616 SCIP_LPI* lpi, /**< LP interface structure */
    5617 BMS_BLKMEM* blkmem, /**< block memory */
    5618 SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information, or NULL */
    5619 )
    5620{ /*lint --e{715}*/
    5621 assert(lpi != NULL);
    5622 assert(lpinorms != NULL);
    5623
    5624 if ( *lpinorms != NULL )
    5625 {
    5626 BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->colnorm, (*lpinorms)->ncols);
    5627 BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->rownorm, (*lpinorms)->nrows);
    5628 BMSfreeBlockMemory(blkmem, lpinorms);
    5629 }
    5630
    5631 return SCIP_OKAY;
    5632}
    5633
    5634/**@} */
    5635
    5636
    5637
    5638
    5639/*
    5640 * Parameter Methods
    5641 */
    5642
    5643/**@name Parameter Methods */
    5644/**@{ */
    5645
    5646/** gets integer parameter of LP */
    5648 SCIP_LPI* lpi, /**< LP interface structure */
    5649 SCIP_LPPARAM type, /**< parameter number */
    5650 int* ival /**< buffer to store the parameter value */
    5651 )
    5652{
    5653 int temp;
    5654 SCIP_Real dtemp;
    5655
    5656 assert(lpi != NULL);
    5657 assert(lpi->grbmodel != NULL);
    5658 assert(ival != NULL);
    5659
    5660 SCIPdebugMessage("getting int parameter %d\n", type);
    5661
    5662 switch( type )
    5663 {
    5665 *ival = (int) lpi->fromscratch;
    5666 break;
    5667 case SCIP_LPPAR_FASTMIP:
    5668 /* maybe set perturbation */
    5669 return SCIP_PARAMETERUNKNOWN;
    5670 case SCIP_LPPAR_SCALING:
    5671 SCIP_CALL( getIntParam(lpi, GRB_INT_PAR_SCALEFLAG, &temp) );
    5672 assert(temp >= -1 && temp <= 3);
    5673 if( temp == -1 )
    5674 *ival = 1;
    5675 else
    5676 *ival = temp;
    5677 break;
    5679 SCIP_CALL( getIntParam(lpi, GRB_INT_PAR_PRESOLVE, &temp) );
    5680 assert( temp == GRB_PRESOLVE_AUTO || temp == GRB_PRESOLVE_OFF || temp == GRB_PRESOLVE_CONSERVATIVE || temp == GRB_PRESOLVE_AGGRESSIVE );
    5681 *ival = (temp == GRB_PRESOLVE_OFF) ? FALSE : TRUE;
    5682 break;
    5683 case SCIP_LPPAR_PRICING:
    5684 *ival = (int) lpi->pricing;
    5685 break;
    5686 case SCIP_LPPAR_LPINFO:
    5687 SCIP_CALL( getIntParam(lpi, GRB_INT_PAR_OUTPUTFLAG, &temp) );
    5688 assert( temp == 0 || temp == 1 );
    5689 *ival = (temp == 1) ? TRUE : FALSE;
    5690 break;
    5691 case SCIP_LPPAR_LPITLIM:
    5692 SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_ITERATIONLIMIT, &dtemp) );
    5693 assert( dtemp >= 0.0 );
    5694 if( dtemp >= INT_MAX )
    5695 *ival = INT_MAX;
    5696 else
    5697 *ival = (int) dtemp;
    5698 break;
    5699 case SCIP_LPPAR_THREADS:
    5700 SCIP_CALL( getIntParam(lpi, GRB_INT_PAR_THREADS, ival) );
    5701 break;
    5703 SCIP_CALL( getIntParam(lpi, GRB_INT_PAR_SEED, ival) );
    5704 break;
    5705 default:
    5706 return SCIP_PARAMETERUNKNOWN;
    5707 } /*lint !e788*/
    5708
    5709 return SCIP_OKAY;
    5710}
    5711
    5712/** sets integer parameter of LP */
    5714 SCIP_LPI* lpi, /**< LP interface structure */
    5715 SCIP_LPPARAM type, /**< parameter number */
    5716 int ival /**< parameter value */
    5717 )
    5718{
    5719 assert(lpi != NULL);
    5720 assert(lpi->grbmodel != NULL);
    5721
    5722 SCIPdebugMessage("setting int parameter %d to %d\n", type, ival);
    5723
    5724 switch( type )
    5725 {
    5727 assert(ival == TRUE || ival == FALSE);
    5728 lpi->fromscratch = (SCIP_Bool) ival;
    5729 break;
    5730 case SCIP_LPPAR_FASTMIP:
    5731 assert(ival == TRUE || ival == FALSE);
    5732 return SCIP_PARAMETERUNKNOWN;
    5733 case SCIP_LPPAR_SCALING:
    5734 if( ival == 1 )
    5735 SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SCALEFLAG, -1) );
    5736 else
    5737 SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SCALEFLAG, ival) );
    5738 break;
    5740 assert(ival == TRUE || ival == FALSE);
    5741 if( ival )
    5742 SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_AUTO) );
    5743 else
    5744 SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_OFF) );
    5745 break;
    5746 case SCIP_LPPAR_PRICING:
    5747 lpi->pricing = (SCIP_PRICING)ival;
    5748 switch( (SCIP_PRICING)ival )
    5749 {
    5751 case SCIP_PRICING_AUTO:
    5752 SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SIMPLEXPRICING, GRB_SIMPLEXPRICING_AUTO) );
    5753 break;
    5754 case SCIP_PRICING_FULL:
    5755 /* full does not seem to exist -> use auto */
    5756 SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SIMPLEXPRICING, GRB_SIMPLEXPRICING_AUTO) );
    5757 break;
    5759 SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SIMPLEXPRICING, GRB_SIMPLEXPRICING_PARTIAL) );
    5760 break;
    5761 case SCIP_PRICING_STEEP:
    5762 SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SIMPLEXPRICING, GRB_SIMPLEXPRICING_STEEPEST_EDGE) );
    5763 break;
    5765 SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SIMPLEXPRICING, GRB_SIMPLEXPRICING_STEEPEST_QUICK) );
    5766 break;
    5767 case SCIP_PRICING_DEVEX:
    5768 SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SIMPLEXPRICING, GRB_SIMPLEXPRICING_DEVEX) );
    5769 break;
    5770 default:
    5771 return SCIP_PARAMETERUNKNOWN;
    5772 }
    5773 break;
    5774 case SCIP_LPPAR_LPINFO:
    5775 assert(ival == TRUE || ival == FALSE);
    5776 if( ival )
    5777 SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_OUTPUTFLAG, 1) );
    5778 else
    5779 SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_OUTPUTFLAG, 0) );
    5780 break;
    5781 case SCIP_LPPAR_LPITLIM:
    5782 assert( ival >= 0 );
    5783 /* 0 <= ival, 0 stopping immediately */
    5784 {
    5785 double itlim;
    5786 itlim = (ival >= INT_MAX ? GRB_INFINITY : ival);
    5787 SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_ITERATIONLIMIT, itlim) );
    5788 }
    5789 break;
    5790 case SCIP_LPPAR_THREADS:
    5791 assert( ival >= 0 );
    5792 SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_THREADS, ival) );
    5793 break;
    5795 assert( ival >= 0 );
    5796 SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SEED, ival) );
    5797 break;
    5798 default:
    5799 return SCIP_PARAMETERUNKNOWN;
    5800 } /*lint !e788*/
    5801
    5802 return SCIP_OKAY;
    5803}
    5804
    5805/** gets floating point parameter of LP */
    5807 SCIP_LPI* lpi, /**< LP interface structure */
    5808 SCIP_LPPARAM type, /**< parameter number */
    5809 SCIP_Real* dval /**< buffer to store the parameter value */
    5810 )
    5811{
    5812 assert(lpi != NULL);
    5813 assert(lpi->grbmodel != NULL);
    5814 assert(dval != NULL);
    5815
    5816 SCIPdebugMessage("getting real parameter %d\n", type);
    5817
    5818 switch( type )
    5819 {
    5820 case SCIP_LPPAR_FEASTOL:
    5821 SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_FEASIBILITYTOL, dval) );
    5822 break;
    5824 SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_OPTIMALITYTOL, dval) );
    5825 break;
    5827 SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_BARCONVTOL, dval) );
    5828 break;
    5829 case SCIP_LPPAR_OBJLIM:
    5830 SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_CUTOFF, dval) );
    5831 break;
    5832 case SCIP_LPPAR_LPTILIM:
    5833 SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_TIMELIMIT, dval) );
    5834 break;
    5836 SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_MARKOWITZTOL, dval) );
    5837 break;
    5839 *dval = lpi->conditionlimit;
    5840 break;
    5841 default:
    5842 return SCIP_PARAMETERUNKNOWN;
    5843 } /*lint !e788*/
    5844
    5845 return SCIP_OKAY;
    5846}
    5847
    5848/** sets floating point parameter of LP */
    5850 SCIP_LPI* lpi, /**< LP interface structure */
    5851 SCIP_LPPARAM type, /**< parameter number */
    5852 SCIP_Real dval /**< parameter value */
    5853 )
    5854{
    5855 assert(lpi != NULL);
    5856 assert(lpi->grbmodel != NULL);
    5857
    5858 SCIPdebugMessage("setting real parameter %d to %g\n", type, dval);
    5859
    5860 switch( type )
    5861 {
    5862 case SCIP_LPPAR_FEASTOL:
    5863 assert( dval > 0.0 );
    5864 /* 1e-9 <= dval <= 1e-2 */
    5865 if( dval < 1e-9 )
    5866 dval = 1e-9;
    5867 else if( dval > 1e-2 )
    5868 dval = 1e-2;
    5869
    5870 SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_FEASIBILITYTOL, dval) );
    5871 break;
    5873 assert( dval > 0.0 );
    5874 /* 1e-9 <= dval <= 1e-2 */
    5875 if (dval < 1e-9)
    5876 dval = 1e-9;
    5877 else if( dval > 1e-2 )
    5878 dval = 1e-2;
    5879
    5880 SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_OPTIMALITYTOL, dval) );
    5881 break;
    5883 /* 0 <= dval <= 1 */
    5884 assert( dval >= 0.0 );
    5885 if( dval > 1.0 )
    5886 dval = 1.0;
    5887
    5888 SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_BARCONVTOL, dval) );
    5889 break;
    5890 case SCIP_LPPAR_OBJLIM:
    5891 /* no restriction on dval */
    5892
    5893 SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_CUTOFF, dval) );
    5894 break;
    5895 case SCIP_LPPAR_LPTILIM:
    5896 assert( dval > 0.0 );
    5897 /* gurobi requires 0 <= dval
    5898 *
    5899 * However for consistency we assert the timelimit to be strictly positive.
    5900 */
    5901
    5902 SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_TIMELIMIT, dval) );
    5903 break;
    5905 /* 1e-4 <= dval <= 0.999 */
    5906 if( dval < 1e-4 )
    5907 dval = 1e-4;
    5908 else if( dval > 0.999 )
    5909 dval = 0.999;
    5910
    5911 SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_MARKOWITZTOL, dval) );
    5912 break;
    5914 lpi->conditionlimit = dval;
    5915 lpi->checkcondition = (dval >= 0.0) ? TRUE : FALSE;
    5916 break;
    5917 default:
    5918 return SCIP_PARAMETERUNKNOWN;
    5919 } /*lint !e788*/
    5920
    5921 return SCIP_OKAY;
    5922}
    5923
    5924/** interrupts the currently ongoing lp solve or disables the interrupt */ /*lint -e{715}*/
    5926 SCIP_LPI* lpi, /**< LP interface structure */
    5927 SCIP_Bool interrupt /**< TRUE if interrupt should be set, FALSE if it should be disabled */
    5928 )
    5929{ /*lint --e{715}*/
    5930 assert(lpi != NULL);
    5931
    5932 return SCIP_OKAY;
    5933}
    5934
    5935/**@} */
    5936
    5937
    5938
    5939
    5940/*
    5941 * Numerical Methods
    5942 */
    5943
    5944/**@name Numerical Methods */
    5945/**@{ */
    5946
    5947/** returns value treated as infinity in the LP solver */
    5949 SCIP_LPI* lpi /**< LP interface structure */
    5950 )
    5951{ /*lint --e{715}*/
    5952 assert(lpi != NULL);
    5953 return GRB_INFINITY;
    5954}
    5955
    5956/** checks if given value is treated as infinity in the LP solver */
    5958 SCIP_LPI* lpi, /**< LP interface structure */
    5959 SCIP_Real val /**< value to be checked for infinity */
    5960 )
    5961{ /*lint --e{715}*/
    5962 assert(lpi != NULL);
    5963 return (val >= GRB_INFINITY);
    5964}
    5965
    5966/**@} */
    5967
    5968
    5969
    5970
    5971/*
    5972 * File Interface Methods
    5973 */
    5974
    5975/**@name File Interface Methods */
    5976/**@{ */
    5977
    5978/** reads LP from a file */
    5980 SCIP_LPI* lpi, /**< LP interface structure */
    5981 const char* fname /**< file name */
    5982 )
    5983{
    5984 assert(lpi != NULL);
    5985 assert(lpi->grbmodel != NULL);
    5986 assert(fname != NULL);
    5987
    5988 SCIPdebugMessage("reading LP from file <%s>\n", fname);
    5989
    5990 CHECK_ZERO( lpi->messagehdlr, GRBreadmodel(lpi->grbenv, fname, &lpi->grbmodel) );
    5991
    5992 /* the model name seems to be empty, use filename */
    5993 CHECK_ZERO( lpi->messagehdlr, GRBsetstrattr(lpi->grbmodel, GRB_STR_ATTR_MODELNAME, fname) );
    5994
    5995 return SCIP_OKAY;
    5996}
    5997
    5998/** writes LP to a file */
    6000 SCIP_LPI* lpi, /**< LP interface structure */
    6001 const char* fname /**< file name */
    6002 )
    6003{
    6004 assert(lpi != NULL);
    6005 assert(lpi->grbmodel != NULL);
    6006 assert(fname != NULL);
    6007
    6008 SCIPdebugMessage("writing LP to file <%s>\n", fname);
    6009
    6010 /* if range rows were not added, add, print and remove them; otherwise, just print */
    6011 if ( lpi->nrngrows > 0 && !lpi->rngvarsadded )
    6012 {
    6013 SCIP_CALL( addRangeVars(lpi) );
    6014 CHECK_ZERO( lpi->messagehdlr, GRBwrite(lpi->grbmodel, fname) );
    6015 SCIP_CALL( delRangeVars(lpi) );
    6016 }
    6017 else
    6018 {
    6019 CHECK_ZERO( lpi->messagehdlr, GRBwrite(lpi->grbmodel, fname) );
    6020 }
    6021
    6022 return SCIP_OKAY;
    6023}
    6024
    6025/**@} */
    unsigned int SCIP_DUALPACKET
    Definition: bitencode.h:42
    SCIP_VAR ** b
    Definition: circlepacking.c:65
    SCIP_Real * r
    Definition: circlepacking.c:59
    SCIP_VAR ** x
    Definition: circlepacking.c:63
    #define NULL
    Definition: def.h:248
    #define SCIP_MAXSTRLEN
    Definition: def.h:269
    #define SCIP_UNUSED(x)
    Definition: def.h:409
    #define SCIP_INVALID
    Definition: def.h:178
    #define SCIP_Bool
    Definition: def.h:91
    #define SCIP_CALL_QUIET(x)
    Definition: def.h:330
    #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 SCIP_CALL_ABORT(x)
    Definition: def.h:334
    #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 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_grb.c:2190
    SCIP_RETCODE SCIPlpiSetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPISTATE *lpistate)
    Definition: lpi_grb.c:5327
    SCIP_RETCODE SCIPlpiGetBInvACol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
    Definition: lpi_grb.c:5166
    SCIP_RETCODE SCIPlpiGetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
    Definition: lpi_grb.c:5806
    SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
    Definition: lpi_grb.c:5948
    SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
    Definition: lpi_grb.c:4147
    SCIP_RETCODE SCIPlpiChgObjsen(SCIP_LPI *lpi, SCIP_OBJSEN objsen)
    Definition: lpi_grb.c:2347
    SCIP_Bool SCIPlpiIsInfinity(SCIP_LPI *lpi, SCIP_Real val)
    Definition: lpi_grb.c:5957
    SCIP_RETCODE SCIPlpiClear(SCIP_LPI *lpi)
    Definition: lpi_grb.c:2100
    SCIP_RETCODE SCIPlpiClearState(SCIP_LPI *lpi)
    Definition: lpi_grb.c:5399
    SCIP_Bool SCIPlpiExistsDualRay(SCIP_LPI *lpi)
    Definition: lpi_grb.c:3946
    SCIP_Bool SCIPlpiExistsPrimalRay(SCIP_LPI *lpi)
    Definition: lpi_grb.c:3806
    SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
    Definition: lpi_grb.c:4497
    SCIP_RETCODE SCIPlpiReadState(SCIP_LPI *lpi, const char *fname)
    Definition: lpi_grb.c:5443
    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_grb.c:1815
    SCIP_RETCODE SCIPlpiGetPrimalRay(SCIP_LPI *lpi, SCIP_Real *ray)
    Definition: lpi_grb.c:4377
    SCIP_RETCODE SCIPlpiGetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int *ival)
    Definition: lpi_grb.c:5647
    SCIP_RETCODE SCIPlpiWriteLP(SCIP_LPI *lpi, const char *fname)
    Definition: lpi_grb.c:5999
    SCIP_RETCODE SCIPlpiSetIntegralityInformation(SCIP_LPI *lpi, int ncols, int *intInfo)
    Definition: lpi_grb.c:1294
    SCIP_Bool SCIPlpiIsDualInfeasible(SCIP_LPI *lpi)
    Definition: lpi_grb.c:4008
    SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
    Definition: lpi_grb.c:5849
    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_grb.c:3626
    SCIP_RETCODE SCIPlpiSetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPINORMS *lpinorms)
    Definition: lpi_grb.c:5571
    SCIP_RETCODE SCIPlpiGetNNonz(SCIP_LPI *lpi, int *nnonz)
    Definition: lpi_grb.c:2570
    SCIP_Bool SCIPlpiHasPrimalSolve(void)
    Definition: lpi_grb.c:1309
    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_grb.c:3689
    SCIP_RETCODE SCIPlpiGetBounds(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lbs, SCIP_Real *ubs)
    Definition: lpi_grb.c:2850
    SCIP_Bool SCIPlpiHasBarrierSolve(void)
    Definition: lpi_grb.c:1325
    SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
    Definition: lpi_grb.c:4400
    SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
    Definition: lpi_grb.c:4209
    SCIP_RETCODE SCIPlpiScaleCol(SCIP_LPI *lpi, int col, SCIP_Real scaleval)
    Definition: lpi_grb.c:2455
    int SCIPlpiGetInternalStatus(SCIP_LPI *lpi)
    Definition: lpi_grb.c:4183
    SCIP_RETCODE SCIPlpiStartStrongbranch(SCIP_LPI *lpi)
    Definition: lpi_grb.c:3415
    SCIP_RETCODE SCIPlpiGetSolFeasibility(SCIP_LPI *lpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
    Definition: lpi_grb.c:3782
    SCIP_RETCODE SCIPlpiFreeNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
    Definition: lpi_grb.c:5615
    SCIP_Bool SCIPlpiIsIterlimExc(SCIP_LPI *lpi)
    Definition: lpi_grb.c:4159
    SCIP_RETCODE SCIPlpiChgBounds(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
    Definition: lpi_grb.c:2143
    SCIP_Bool SCIPlpiIsPrimalUnbounded(SCIP_LPI *lpi)
    Definition: lpi_grb.c:3843
    SCIP_RETCODE SCIPlpiIgnoreInstability(SCIP_LPI *lpi, SCIP_Bool *success)
    Definition: lpi_grb.c:4194
    SCIP_RETCODE SCIPlpiWriteState(SCIP_LPI *lpi, const char *fname)
    Definition: lpi_grb.c:5472
    SCIP_RETCODE SCIPlpiFree(SCIP_LPI **lpi)
    Definition: lpi_grb.c:1489
    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_grb.c:3649
    SCIP_RETCODE SCIPlpiGetCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real *val)
    Definition: lpi_grb.c:2921
    SCIP_Bool SCIPlpiIsPrimalFeasible(SCIP_LPI *lpi)
    Definition: lpi_grb.c:3884
    SCIP_RETCODE SCIPlpiReadLP(SCIP_LPI *lpi, const char *fname)
    Definition: lpi_grb.c:5979
    SCIP_RETCODE SCIPlpiGetRealSolQuality(SCIP_LPI *lpi, SCIP_LPSOLQUALITY qualityindicator, SCIP_Real *quality)
    Definition: lpi_grb.c:4447
    SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
    Definition: lpi_grb.c:4022
    static SCIP_RETCODE lpiStrongbranch(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_grb.c:3442
    SCIP_RETCODE SCIPlpiGetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
    Definition: lpi_grb.c:5521
    SCIP_Bool SCIPlpiIsTimelimExc(SCIP_LPI *lpi)
    Definition: lpi_grb.c:4171
    SCIP_Bool SCIPlpiHasStateBasis(SCIP_LPI *lpi, SCIP_LPISTATE *lpistate)
    Definition: lpi_grb.c:5433
    SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
    Definition: lpi_grb.c:5713
    const char * SCIPlpiGetSolverName(void)
    Definition: lpi_grb.c:1267
    SCIP_RETCODE SCIPlpiSetBase(SCIP_LPI *lpi, const int *cstat, const int *rstat)
    Definition: lpi_grb.c:4625
    SCIP_Bool SCIPlpiHasPrimalRay(SCIP_LPI *lpi)
    Definition: lpi_grb.c:3820
    SCIP_RETCODE SCIPlpiGetBInvRow(SCIP_LPI *lpi, int r, SCIP_Real *coef, int *inds, int *ninds)
    Definition: lpi_grb.c:4819
    SCIP_RETCODE SCIPlpiDelRows(SCIP_LPI *lpi, int firstrow, int lastrow)
    Definition: lpi_grb.c:1894
    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_grb.c:2594
    SCIP_RETCODE SCIPlpiGetBInvCol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
    Definition: lpi_grb.c:4934
    SCIP_RETCODE SCIPlpiGetColNames(SCIP_LPI *lpi, int firstcol, int lastcol, char **colnames, char *namestorage, int namestoragesize, int *storageleft)
    Definition: lpi_grb.c:2736
    SCIP_RETCODE SCIPlpiGetBInvARow(SCIP_LPI *lpi, int r, const SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
    Definition: lpi_grb.c:5053
    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_grb.c:2641
    SCIP_Bool SCIPlpiWasSolved(SCIP_LPI *lpi)
    Definition: lpi_grb.c:3763
    const char * SCIPlpiGetSolverDesc(void)
    Definition: lpi_grb.c:1275
    SCIP_RETCODE SCIPlpiSolveBarrier(SCIP_LPI *lpi, SCIP_Bool crossover)
    Definition: lpi_grb.c:3292
    SCIP_Bool SCIPlpiIsOptimal(SCIP_LPI *lpi)
    Definition: lpi_grb.c:4049
    SCIP_RETCODE SCIPlpiGetRowNames(SCIP_LPI *lpi, int firstrow, int lastrow, char **rownames, char *namestorage, int namestoragesize, int *storageleft)
    Definition: lpi_grb.c:2768
    SCIP_Bool SCIPlpiHasDualSolve(void)
    Definition: lpi_grb.c:1317
    SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
    Definition: lpi_grb.c:3428
    SCIP_RETCODE SCIPlpiGetSides(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhss, SCIP_Real *rhss)
    Definition: lpi_grb.c:2886
    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_grb.c:3712
    SCIP_RETCODE SCIPlpiGetSol(SCIP_LPI *lpi, SCIP_Real *objval, SCIP_Real *primsol, SCIP_Real *dualsol, SCIP_Real *activity, SCIP_Real *redcost)
    Definition: lpi_grb.c:4287
    SCIP_Bool SCIPlpiHasDualRay(SCIP_LPI *lpi)
    Definition: lpi_grb.c:3960
    SCIP_RETCODE SCIPlpiDelColset(SCIP_LPI *lpi, int *dstat)
    Definition: lpi_grb.c:1760
    SCIP_RETCODE SCIPlpiGetObj(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *vals)
    Definition: lpi_grb.c:2822
    SCIP_RETCODE SCIPlpiFreeState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
    Definition: lpi_grb.c:5416
    SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
    Definition: lpi_grb.c:3869
    SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
    Definition: lpi_grb.c:3149
    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_grb.c:1651
    SCIP_RETCODE SCIPlpiSolvePrimal(SCIP_LPI *lpi)
    Definition: lpi_grb.c:2955
    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_grb.c:1550
    SCIP_Bool SCIPlpiIsDualUnbounded(SCIP_LPI *lpi)
    Definition: lpi_grb.c:3983
    SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
    Definition: lpi_grb.c:4428
    SCIP_RETCODE SCIPlpiGetBasisInd(SCIP_LPI *lpi, int *bind)
    Definition: lpi_grb.c:4749
    SCIP_RETCODE SCIPlpiCreate(SCIP_LPI **lpi, SCIP_MESSAGEHDLR *messagehdlr, const char *name, SCIP_OBJSEN objsen)
    Definition: lpi_grb.c:1345
    void * SCIPlpiGetSolverPointer(SCIP_LPI *lpi)
    Definition: lpi_grb.c:1286
    SCIP_RETCODE SCIPlpiChgObj(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *obj)
    Definition: lpi_grb.c:2373
    SCIP_RETCODE SCIPlpiGetObjsen(SCIP_LPI *lpi, SCIP_OBJSEN *objsen)
    Definition: lpi_grb.c:2800
    SCIP_Bool SCIPlpiIsStable(SCIP_LPI *lpi)
    Definition: lpi_grb.c:4067
    SCIP_RETCODE SCIPlpiGetNCols(SCIP_LPI *lpi, int *ncols)
    Definition: lpi_grb.c:2549
    SCIP_RETCODE SCIPlpiInterrupt(SCIP_LPI *lpi, SCIP_Bool interrupt)
    Definition: lpi_grb.c:5925
    SCIP_RETCODE SCIPlpiDelCols(SCIP_LPI *lpi, int firstcol, int lastcol)
    Definition: lpi_grb.c:1713
    SCIP_RETCODE SCIPlpiDelRowset(SCIP_LPI *lpi, int *dstat)
    Definition: lpi_grb.c:1998
    SCIP_RETCODE SCIPlpiScaleRow(SCIP_LPI *lpi, int row, SCIP_Real scaleval)
    Definition: lpi_grb.c:2396
    SCIP_RETCODE SCIPlpiGetNRows(SCIP_LPI *lpi, int *nrows)
    Definition: lpi_grb.c:2532
    SCIP_RETCODE SCIPlpiGetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
    Definition: lpi_grb.c:5264
    SCIP_RETCODE SCIPlpiChgCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real newval)
    Definition: lpi_grb.c:2326
    void SCIPsortIntReal(int *intarray, SCIP_Real *realarray, int len)
    interface methods for specific LP solvers
    SCIP_DUALPACKET ROWPACKET
    Definition: lpi_clp.cpp:128
    SCIP_DUALPACKET COLPACKET
    Definition: lpi_clp.cpp:126
    static void SCIPdecodeDualBitNeg(const SCIP_DUALPACKET *inp, int *out, int count)
    Definition: lpi_grb.c:547
    static SCIP_RETCODE setBase(SCIP_LPI *lpi)
    Definition: lpi_grb.c:422
    static void lpistatePack(SCIP_LPISTATE *lpistate, const int *cstat, const int *rstat)
    Definition: lpi_grb.c:623
    static SCIP_RETCODE getDblParam(SCIP_LPI *lpi, const char *param, double *p)
    Definition: lpi_grb.c:852
    static SCIP_RETCODE getBase(SCIP_LPI *lpi, SCIP_Bool *success)
    Definition: lpi_grb.c:364
    static void lpistateUnpack(const SCIP_LPISTATE *lpistate, int *cstat, int *rstat)
    Definition: lpi_grb.c:639
    static int rowpacketNum(int nrows)
    Definition: lpi_grb.c:464
    static SCIP_RETCODE reconvertSides(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhs, SCIP_Real *rhs)
    Definition: lpi_grb.c:970
    struct GRBParam GRBPARAM
    Definition: lpi_grb.c:152
    static SCIP_RETCODE addRangeVars(SCIP_LPI *lpi)
    Definition: lpi_grb.c:1114
    static void copyParameterValues(GRBPARAM *dest, const GRBPARAM *source)
    Definition: lpi_grb.c:787
    SCIP_DUALPACKET ROWPACKET
    Definition: lpi_grb.c:97
    static SCIP_RETCODE ensureCstatMem(SCIP_LPI *lpi, int num)
    Definition: lpi_grb.c:272
    static GRBenv * reusegrbenv
    Definition: lpi_grb.c:65
    static SCIP_RETCODE getIntParam(SCIP_LPI *lpi, const char *param, int *p)
    Definition: lpi_grb.c:802
    #define COLS_PER_PACKET
    Definition: lpi_grb.c:96
    static void checkRangeInfo(SCIP_LPI *lpi)
    Definition: lpi_grb.c:1072
    static SCIP_RETCODE ensureRngrowmapMem(SCIP_LPI *lpi, int num)
    Definition: lpi_grb.c:316
    static int numlp
    Definition: lpi_grb.c:66
    static SCIP_RETCODE convertSides(SCIP_LPI *lpi, int nrows, const SCIP_Real *lhs, const SCIP_Real *rhs, int *rngcount)
    Definition: lpi_grb.c:912
    static SCIP_RETCODE delRangeVars(SCIP_LPI *lpi)
    Definition: lpi_grb.c:1145
    static void lpistateFree(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem)
    Definition: lpi_grb.c:677
    SCIP_DUALPACKET COLPACKET
    Definition: lpi_grb.c:95
    static SCIP_RETCODE restoreLPData(SCIP_LPI *lpi)
    Definition: lpi_grb.c:1040
    static void SCIPencodeDualBitNeg(const int *inp, SCIP_DUALPACKET *out, int count)
    Definition: lpi_grb.c:476
    #define CHECK_ZERO(messagehdlr, x)
    Definition: lpi_grb.c:71
    static const double dblparammin[NUMDBLPARAM]
    Definition: lpi_grb.c:135
    #define NUMINTPARAM
    Definition: lpi_grb.c:108
    #define SCIP_DUALPACKETSIZE
    Definition: lpi_grb.c:93
    static SCIP_RETCODE ensureRstatMem(SCIP_LPI *lpi, int num)
    Definition: lpi_grb.c:294
    static int colpacketNum(int ncols)
    Definition: lpi_grb.c:455
    static SCIP_RETCODE ensureRngrowsMem(SCIP_LPI *lpi, int num)
    Definition: lpi_grb.c:341
    static SCIP_RETCODE setParameterValues(SCIP_LPI *lpi, GRBPARAM *grbparam)
    Definition: lpi_grb.c:746
    static SCIP_RETCODE ensureSidechgMem(SCIP_LPI *lpi, int num)
    Definition: lpi_grb.c:224
    static const char * dblparam[NUMDBLPARAM]
    Definition: lpi_grb.c:123
    static SCIP_RETCODE getParameterValues(SCIP_LPI *lpi, GRBPARAM *grbparam)
    Definition: lpi_grb.c:699
    #define NUMDBLPARAM
    Definition: lpi_grb.c:121
    static void clearRangeInfo(SCIP_LPI *lpi)
    Definition: lpi_grb.c:1175
    static const char grbname[]
    Definition: lpi_grb.c:1255
    static SCIP_RETCODE addRangeInfo(SCIP_LPI *lpi, int rngcount, int firstrow)
    Definition: lpi_grb.c:1192
    static const char * intparam[NUMINTPARAM]
    Definition: lpi_grb.c:110
    #define CHECK_ZERO_STAR(messagehdlr, x)
    Definition: lpi_grb.c:80
    static SCIP_RETCODE setIntParam(SCIP_LPI *lpi, const char *param, int parval)
    Definition: lpi_grb.c:827
    #define ROWS_PER_PACKET
    Definition: lpi_grb.c:98
    static SCIP_RETCODE checkParameterValues(SCIP_LPI *lpi)
    Definition: lpi_grb.c:726
    static SCIP_RETCODE lpistateCreate(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem, int ncols, int nrows, int nrngrows)
    Definition: lpi_grb.c:655
    static SCIP_RETCODE setDblParam(SCIP_LPI *lpi, const char *param, double parval)
    Definition: lpi_grb.c:877
    static void invalidateSolution(SCIP_LPI *lpi)
    Definition: lpi_grb.c:902
    #define GRB_REFACTORMAXITERS
    Definition: lpi_grb.c:104
    #define SVECTOR
    Definition: lpi_grb.c:89
    unsigned int SCIP_DUALPACKET
    Definition: lpi_grb.c:92
    static SCIP_RETCODE ensureValMem(SCIP_LPI *lpi, int num)
    Definition: lpi_grb.c:249
    #define BMSfreeMemory(ptr)
    Definition: memory.h:145
    #define BMSfreeBlockMemory(mem, ptr)
    Definition: memory.h:465
    #define BMSallocBlockMemory(mem, ptr)
    Definition: memory.h:451
    #define BMSreallocMemoryArray(ptr, num)
    Definition: memory.h:127
    #define BMSfreeBlockMemoryArrayNull(mem, ptr, num)
    Definition: memory.h:468
    #define 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
    #define BMSallocClearMemoryArray(ptr, num)
    Definition: memory.h:125
    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
    methods for sorting joint arrays of various types
    static SCIP_RETCODE presolve(SCIP *scip, SCIP_Bool *unbounded, SCIP_Bool *infeasible, SCIP_Bool *vanished)
    Definition: scip_solve.c:1138
    double dblparval[NUMDBLPARAM]
    Definition: lpi_cpx.c:138
    int intparval[NUMINTPARAM]
    Definition: lpi_cpx.c:137
    double * rownorm
    Definition: lpi_grb.c:213
    double * colnorm
    Definition: lpi_grb.c:212
    COLPACKET * packcstat
    Definition: lpi_clp.cpp:136
    ROWPACKET * packrstat
    Definition: lpi_clp.cpp:137
    int nrngrows
    Definition: lpi_grb.c:202
    GRBPARAM grbparam
    Definition: lpi_grb.c:167
    int rngrowmapsize
    Definition: lpi_grb.c:191
    GRBPARAM curparam
    Definition: lpi_grb.c:166
    int * rngrows
    Definition: lpi_grb.c:189
    int rngrowssize
    Definition: lpi_grb.c:193
    int iterations
    Definition: lpi_cpx.c:167
    GRBenv * grbenv
    Definition: lpi_grb.c:158
    SCIP_Real * valarray
    Definition: lpi_cpx.c:157
    GRBPARAM defparam
    Definition: lpi_grb.c:165
    int valsize
    Definition: lpi_cpx.c:164
    int * rngrowmap
    Definition: lpi_grb.c:187
    GRBmodel * grbmodel
    Definition: lpi_grb.c:163
    SCIP_Bool rngvarsadded
    Definition: lpi_grb.c:194
    GRBenv ** reusegrbenv
    Definition: lpi_grb.c:161
    SCIP_CPXPARAM curparam
    Definition: lpi_cpx.c:147
    int * indarray
    Definition: lpi_cpx.c:161
    SCIP_Real conditionlimit
    Definition: lpi_cpx.c:174
    int * numlp
    Definition: lpi_grb.c:160
    int * cstat
    Definition: lpi_clp.cpp:107
    SCIP_Real * rngvals
    Definition: lpi_grb.c:190
    SCIP_Bool solisbasic
    Definition: lpi_cpx.c:169
    int solstat
    Definition: lpi_cpx.c:149
    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_MESSAGEHDLR * messagehdlr
    Definition: lpi_cpx.c:185
    SCIP_Real * rngarray
    Definition: lpi_cpx.c:156
    int * rngidxarray
    Definition: lpi_grb.c:171
    SCIP_Bool checkcondition
    Definition: lpi_cpx.c:175
    int nrngrows
    Definition: lpi_grb.c:192
    @ 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_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