Scippy

    SCIP

    Solving Constraint Integer Programs

    lpi_xprs.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_xprs.c
    26 * @ingroup LPIS
    27 * @brief LP interface for Xpress-MP
    28 * @author Tobias Achterberg
    29 * @author Michael Perregaard
    30 * @author Livio Bertacco
    31 * @author Stefan Heinz
    32 *
    33 * This interface was revised for Xpress 26. Therefore, we removed all legacy code.
    34 *
    35 * Xpress requires that column and row names are unique. Since column and row names are not needed we ignore all column
    36 * and row names to avoid the uniqueness issue.
    37 */
    38
    39/*--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    40
    41#include <assert.h>
    42#include <string.h>
    43#ifdef _MSC_VER
    44#define strcasecmp _stricmp
    45#else
    46#include <strings.h> /*lint --e{766}*/
    47#endif
    48
    49#include "xprs.h"
    50#include "scip/bitencode.h"
    51#include "scip/pub_misc.h"
    52#include "scip/pub_message.h"
    53#include "lpi/lpi.h"
    54#include "tinycthread/tinycthread.h"
    55
    56#ifndef XPRS_LPQUICKPRESOLVE
    57#define XPRS_LPQUICKPRESOLVE 8207
    58#endif
    59
    60/* For SCIP we need an extra LP status which is optimal with scaled infeasibilities. */
    61#define XPRS_LP_OPTIMAL_SCALEDINFEAS 16
    62
    63#define CHECK_ZERO(messagehdlr, x) { int _restat_; \
    64 if( (_restat_ = (x)) != 0 ) \
    65 { \
    66 SCIPmessagePrintWarning((messagehdlr), "%s:%d: LP Error: Xpress returned %d\n", __FILE__, __LINE__, _restat_); \
    67 return SCIP_LPERROR; \
    68 } \
    69 }
    70
    71/* this macro is only called in functions returning SCIP_Bool; thus, we return retval if there is an error in optimized mode */
    72#define ABORT_ZERO(messagehdlr, retval, x) { int _restat_; \
    73 if( (_restat_ = (x)) != 0 ) \
    74 { \
    75 SCIPmessagePrintWarning((messagehdlr), "LP Error: Xpress returned %d\n", _restat_); \
    76 SCIPABORT(); \
    77 return retval; \
    78 } \
    79 }
    80
    81
    82typedef SCIP_DUALPACKET COLPACKET; /* each column needs two bits of information (basic/on_lower/on_upper) */
    83#define COLS_PER_PACKET SCIP_DUALPACKETSIZE
    84typedef SCIP_DUALPACKET ROWPACKET; /* each row needs two bit of information (basic/on_lower/on_upper) */
    85#define ROWS_PER_PACKET SCIP_DUALPACKETSIZE
    86
    87/** LP interface */
    88struct SCIP_LPi
    89{
    90 XPRSprob xprslp; /**< Xpress LP pointer */
    91 char name[200]; /**< problem name */
    92
    93 SCIP_PRICING pricing; /**< SCIP pricing setting */
    94 int notfromscratch; /**< do we not want to solve the lp from scratch */
    95 int solstat; /**< solution status of last optimization call */
    96 char solmethod; /**< method used to solve the LP */
    97
    98 char* larray; /**< array with 'L' entries for changing lower bounds */
    99 char* uarray; /**< array with 'U' entries for changing upper bounds */
    100 char* senarray; /**< array for storing row senses */
    101 SCIP_Real* rhsarray; /**< array for storing rhs values */
    102 SCIP_Real* rngarray; /**< array for storing range values */
    103 SCIP_Real* valarray; /**< array for storing coefficient values */
    104 int* cstat; /**< array for storing column basis status */
    105 int* rstat; /**< array for storing row basis status (row status w.r.t. slack columns) */
    106 int* indarray; /**< array for storing coefficient indices */
    107
    108 int boundchgsize; /**< size of larray and uarray */
    109 int sidechgsize; /**< size of senarray and rngarray */
    110 int valsize; /**< size of valarray and indarray */
    111 int cstatsize; /**< size of cstat array */
    112 int rstatsize; /**< size of rstat array */
    113
    114 int iterations; /**< number of iterations used in the last solving call */
    115 SCIP_Bool solisbasic; /**< is current LP solution a basic solution? */
    116 SCIP_Bool clearstate; /**< should the current basis be ignored with the next LP solve */
    117
    118 SCIP_Real par_lobjlim; /**< objective lower bound */
    119 SCIP_Real par_uobjlim; /**< objective upper bound */
    120 int par_fastlp; /**< special meta parameter for making LP reoptimize go faster */
    121 int par_presolve; /**< need to distinguish between the users setting and the optimizer setting of presolve */
    122
    123 SCIP_MESSAGEHDLR* messagehdlr; /**< messagehdlr handler to printing messages, or NULL */
    124};
    125
    126/** LPi state stores basis information */
    127struct SCIP_LPiState
    128{
    129 int ncols; /**< number of LP columns */
    130 int nrows; /**< number of LP rows */
    131 COLPACKET* packcstat; /**< column basis status in compressed form */
    132 ROWPACKET* packrstat; /**< row basis status in compressed form (row status w.r.t. slack columns) */
    133};
    134
    135/**@name Debug check methods
    136 *
    137 * @{
    138 */
    139
    140#ifndef NDEBUG
    141
    142/** check that the column range fits */
    143static
    145 SCIP_LPI* lpi, /**< LP interface structure */
    146 int firstcol, /**< first column to be deleted */
    147 int lastcol /**< last column to be deleted */
    148 )
    149{
    150 int ncols;
    151
    152 assert(lpi != NULL);
    153 assert(firstcol >= 0);
    154 assert(firstcol <= lastcol + 1);
    155 (void)XPRSgetintattrib(lpi->xprslp, XPRS_COLS, &ncols);
    156 assert(lastcol < ncols);
    157}
    158
    159/** check that the row range fits */
    160static
    162 SCIP_LPI* lpi, /**< LP interface structure */
    163 int firstrow, /**< first row to be deleted */
    164 int lastrow /**< last row to be deleted */
    165 )
    166{
    167 int nrows;
    168
    169 assert(lpi != NULL);
    170 assert(firstrow >= 0);
    171 assert(firstrow <= lastrow + 1);
    172 (void)XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows);
    173 assert(lastrow < nrows);
    174}
    175
    176#else
    177
    178/* in optimized mode the checks are replaced with an empty command */
    179#define debugCheckColrang(lpi, firstcol, lastcol) /* */
    180#define debugCheckRowrang(lpi, firstrow, lastrow) /* */
    181#endif
    182
    183/**@} */
    184
    185
    186/**@name Dynamic memory arrays
    187 *
    188 * @{
    189 */
    190
    191/** resizes larray and uarray to have at least num entries and fill it with 'L' and 'U' for the lower and upper bound
    192 * markers
    193 */
    194static
    196 SCIP_LPI* lpi, /**< LP interface structure */
    197 int num /**< minimal number of entries in array */
    198 )
    199{
    200 assert(lpi != NULL);
    201
    202 if( num > lpi->boundchgsize )
    203 {
    204 int newsize;
    205 int i;
    206
    207 newsize = MAX(2*lpi->boundchgsize, num);
    208 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->larray, newsize) );
    209 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->uarray, newsize) );
    210 for( i = lpi->boundchgsize; i < newsize; ++i )
    211 {
    212 lpi->larray[i] = 'L';
    213 lpi->uarray[i] = 'U';
    214 }
    215 lpi->boundchgsize = newsize;
    216 }
    217 assert(num <= lpi->boundchgsize);
    218
    219 return SCIP_OKAY;
    220}
    221
    222/** resizes senarray, rngarray, and rhsarray 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) );
    239 lpi->sidechgsize = newsize;
    240 }
    241 assert(num <= lpi->sidechgsize);
    242
    243 return SCIP_OKAY;
    244}
    245
    246/** resizes valarray and indarray to have at least num entries */
    247static
    249 SCIP_LPI* lpi, /**< LP interface structure */
    250 int num /**< minimal number of entries in array */
    251 )
    252{
    253 assert(lpi != NULL);
    254
    255 if( num > lpi->valsize )
    256 {
    257 int newsize;
    258
    259 newsize = MAX(2*lpi->valsize, num);
    260 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->valarray, newsize) );
    261 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->indarray, newsize) );
    262 lpi->valsize = newsize;
    263 }
    264 assert(num <= lpi->valsize);
    265
    266 return SCIP_OKAY;
    267}
    268
    269/** resizes cstat array to have at least num entries */
    270static
    272 SCIP_LPI* lpi, /**< LP interface structure */
    273 int num /**< minimal number of entries in array */
    274 )
    275{
    276 assert(lpi != NULL);
    277
    278 if( num > lpi->cstatsize )
    279 {
    280 int newsize;
    281
    282 newsize = MAX(2*lpi->cstatsize, num);
    283 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->cstat, newsize) );
    284 lpi->cstatsize = newsize;
    285 }
    286 assert(num <= lpi->cstatsize);
    287
    288 return SCIP_OKAY;
    289}
    290
    291/** resizes rstat array to have at least num entries */
    292static
    294 SCIP_LPI* lpi, /**< LP interface structure */
    295 int num /**< minimal number of entries in array */
    296 )
    297{
    298 assert(lpi != NULL);
    299
    300 if( num > lpi->rstatsize )
    301 {
    302 int newsize;
    303
    304 newsize = MAX(2*lpi->rstatsize, num);
    305 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rstat, newsize) );
    306 lpi->rstatsize = newsize;
    307 }
    308 assert(num <= lpi->rstatsize);
    309
    310 return SCIP_OKAY;
    311}
    312
    313/**@} */
    314
    315
    316/**@name LPi state methods
    317 *
    318 * @{
    319 */
    320
    321/** returns the number of packets needed to store column packet information */
    322static
    324 int ncols /**< number of columns to store */
    325 )
    326{
    327 return (ncols+(int)COLS_PER_PACKET-1)/(int)COLS_PER_PACKET;
    328}
    329
    330/** returns the number of packets needed to store row packet information */
    331static
    333 int nrows /**< number of rows to store */
    334 )
    335{
    336 return (nrows+(int)ROWS_PER_PACKET-1)/(int)ROWS_PER_PACKET;
    337}
    338
    339/** store row and column basis status in a packed LPi state object */
    340static
    342 SCIP_LPISTATE* lpistate, /**< pointer to LPi state data */
    343 const int* cstat, /**< basis status of columns in unpacked format */
    344 const int* rstat /**< basis status of rows in unpacked format (row status w.r.t. slack columns) */
    345 )
    346{
    347 assert(lpistate != NULL);
    348 assert(lpistate->packcstat != NULL);
    349 assert(lpistate->packrstat != NULL);
    350
    351 SCIPencodeDualBit(cstat, lpistate->packcstat, lpistate->ncols);
    352 SCIPencodeDualBit(rstat, lpistate->packrstat, lpistate->nrows);
    353}
    354
    355/** unpacks row and column basis status from a packed LPi state object */
    356static
    358 const SCIP_LPISTATE* lpistate, /**< pointer to LPi state data */
    359 int* cstat, /**< buffer for storing basis status of columns in unpacked format */
    360 int* rstat /**< buffer for storing basis status of rows in unpacked format (row status w.r.t. slack columns) */
    361 )
    362{
    363 assert(lpistate != NULL);
    364 assert(lpistate->packcstat != NULL);
    365 assert(lpistate->packrstat != NULL);
    366
    367 SCIPdecodeDualBit(lpistate->packcstat, cstat, lpistate->ncols);
    368 SCIPdecodeDualBit(lpistate->packrstat, rstat, lpistate->nrows);
    369}
    370
    371/** creates LPi state information object */
    372static
    374 SCIP_LPISTATE** lpistate, /**< pointer to LPi state */
    375 BMS_BLKMEM* blkmem, /**< block memory */
    376 int ncols, /**< number of columns to store */
    377 int nrows /**< number of rows to store */
    378 )
    379{
    380 assert(lpistate != NULL);
    381 assert(blkmem != NULL);
    382 assert(ncols >= 0);
    383 assert(nrows >= 0);
    384
    385 SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpistate) );
    386 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->packcstat, colpacketNum(ncols)) );
    387 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->packrstat, rowpacketNum(nrows)) );
    388
    389 return SCIP_OKAY;
    390}
    391
    392/** frees LPi state information */
    393static
    395 SCIP_LPISTATE** lpistate, /**< pointer to LPi state information (like basis information) */
    396 BMS_BLKMEM* blkmem /**< block memory */
    397 )
    398{
    399 assert(blkmem != NULL);
    400 assert(lpistate != NULL);
    401 assert(*lpistate != NULL);
    402
    403 BMSfreeBlockMemoryArray(blkmem, &(*lpistate)->packcstat, colpacketNum((*lpistate)->ncols));
    404 BMSfreeBlockMemoryArray(blkmem, &(*lpistate)->packrstat, rowpacketNum((*lpistate)->nrows));
    405 BMSfreeBlockMemory(blkmem, lpistate);
    406}
    407
    408/**@} */
    409
    410
    411/**@name Conversion methods
    412 *
    413 * @{
    414 */
    415
    416/** converts SCIP's objective sense into CPLEX's objective sense */
    417static
    419 SCIP_OBJSEN const objsen /**< objective sense */
    420 )
    421{
    422 switch( objsen )
    423 {
    425 return XPRS_OBJ_MAXIMIZE;
    427 return XPRS_OBJ_MINIMIZE;
    428 default:
    429 SCIPerrorMessage("invalid objective sense\n");
    430 SCIPABORT();
    431 return 0; /*lint !e527*/
    432 }
    433}
    434
    435/** converts SCIP's lhs/rhs pairs into Xpress' sen/rhs/rng */
    436static
    438 SCIP_LPI* lpi, /**< LP interface structure */
    439 int nrows, /**< number of rows */
    440 const SCIP_Real* lhss, /**< left hand side vector */
    441 const SCIP_Real* rhss /**< right hand side vector */
    442 )
    443{
    444 int i;
    445
    446 assert(lpi != NULL);
    447 assert(nrows >= 0);
    448 assert(lhss != NULL);
    449 assert(rhss != NULL);
    450
    451 /* convert lhs/rhs into sen/rhs/rng */
    452 for( i = 0; i < nrows; ++i )
    453 {
    454 assert(lhss[i] <= rhss[i]);
    455 if( lhss[i] == rhss[i] ) /*lint !e777*/
    456 {
    457 assert(XPRS_MINUSINFINITY < rhss[i] && rhss[i] < XPRS_PLUSINFINITY);
    458 lpi->senarray[i] = 'E';
    459 lpi->rhsarray[i] = rhss[i];
    460 lpi->rngarray[i] = 0.0;
    461 }
    462 else if( lhss[i] <= XPRS_MINUSINFINITY )
    463 {
    464 lpi->senarray[i] = 'L';
    465 lpi->rhsarray[i] = rhss[i];
    466 lpi->rngarray[i] = XPRS_PLUSINFINITY;
    467 }
    468 else if( rhss[i] >= XPRS_PLUSINFINITY )
    469 {
    470 lpi->senarray[i] = 'G';
    471 lpi->rhsarray[i] = lhss[i];
    472 lpi->rngarray[i] = XPRS_PLUSINFINITY;
    473 }
    474 else
    475 {
    476 /* Xpress defines a ranged row to be within rhs-rng and rhs. */
    477 lpi->senarray[i] = 'R';
    478 lpi->rhsarray[i] = rhss[i];
    479 lpi->rngarray[i] = rhss[i] - lhss[i];
    480 }
    481 }
    482}
    483
    484/** converts Xpress' sen/rhs/rng triplets into SCIP's lhs/rhs pairs */
    485static
    487 SCIP_LPI* lpi, /**< LP interface structure */
    488 int nrows, /**< number of rows */
    489 SCIP_Real* lhss, /**< buffer to store the left hand side vector */
    490 SCIP_Real* rhss /**< buffer to store the right hand side vector */
    491 )
    492{
    493 int i;
    494
    495 assert(lpi != NULL);
    496 assert(nrows >= 0);
    497 assert(lhss != NULL);
    498 assert(rhss != NULL);
    499
    500 for( i = 0; i < nrows; ++i )
    501 {
    502 switch( lpi->senarray[i] )
    503 {
    504 case 'E':
    505 lhss[i] = lpi->rhsarray[i];
    506 rhss[i] = lpi->rhsarray[i];
    507 break;
    508
    509 case 'L':
    510 lhss[i] = XPRS_MINUSINFINITY;
    511 rhss[i] = lpi->rhsarray[i];
    512 break;
    513
    514 case 'G':
    515 lhss[i] = lpi->rhsarray[i];
    516 rhss[i] = XPRS_PLUSINFINITY;
    517 break;
    518
    519 case 'R':
    520 assert(lpi->rngarray[i] >= 0.0);
    521 rhss[i] = lpi->rhsarray[i];
    522 lhss[i] = lpi->rhsarray[i] - lpi->rngarray[i];
    523 break;
    524
    525 default:
    526 SCIPerrorMessage("invalid row sense\n");
    527 SCIPABORT();
    528 }
    529 assert(lhss[i] <= rhss[i]);
    530 }
    531}
    532
    533/** converts Xpress' sen/rhs/rng triplets into SCIP's lhs/rhs pairs, only storing the left hand side */
    534static
    536 SCIP_LPI* lpi, /**< LP interface structure */
    537 int nrows, /**< number of rows */
    538 SCIP_Real* lhss /**< buffer to store the left hand side vector */
    539 )
    540{
    541 int i;
    542
    543 assert(lpi != NULL);
    544 assert(nrows >= 0);
    545 assert(lhss != NULL);
    546
    547 for( i = 0; i < nrows; ++i )
    548 {
    549 switch( lpi->senarray[i] )
    550 {
    551 case 'E':
    552 assert(lpi->rngarray[i] == 0.0);
    553 lhss[i] = lpi->rhsarray[i];
    554 break;
    555
    556 case 'L':
    557 assert(lpi->rngarray[i] == 0.0);
    558 lhss[i] = XPRS_MINUSINFINITY;
    559 break;
    560
    561 case 'G':
    562 assert(lpi->rngarray[i] == 0.0);
    563 lhss[i] = lpi->rhsarray[i];
    564 break;
    565
    566 case 'R':
    567 assert(lpi->rngarray[i] >= 0.0);
    568 lhss[i] = lpi->rhsarray[i] - lpi->rngarray[i];
    569 break;
    570
    571 default:
    572 SCIPerrorMessage("invalid row sense\n");
    573 SCIPABORT();
    574 }
    575 }
    576}
    577
    578/** converts Xpress' sen/rhs/rng triplets into SCIP's lhs/rhs pairs, only storing the right hand side */
    579static
    581 SCIP_LPI* lpi, /**< LP interface structure */
    582 int nrows, /**< number of rows */
    583 SCIP_Real* rhss /**< buffer to store the right hand side vector */
    584 )
    585{
    586 int i;
    587
    588 assert(lpi != NULL);
    589 assert(nrows >= 0);
    590 assert(rhss != NULL);
    591
    592 for( i = 0; i < nrows; ++i )
    593 {
    594 switch( lpi->senarray[i] )
    595 {
    596 case 'E':
    597 assert(lpi->rngarray[i] == 0.0);
    598 rhss[i] = lpi->rhsarray[i];
    599 break;
    600
    601 case 'L':
    602 assert(lpi->rngarray[i] == 0.0);
    603 rhss[i] = lpi->rhsarray[i];
    604 break;
    605
    606 case 'G':
    607 assert(lpi->rngarray[i] == 0.0);
    608 rhss[i] = XPRS_PLUSINFINITY;
    609 break;
    610
    611 case 'R':
    612 assert(lpi->rngarray[i] >= 0.0);
    613 rhss[i] = lpi->rhsarray[i];
    614 break;
    615
    616 default:
    617 SCIPerrorMessage("invalid row sense\n");
    618 SCIPABORT();
    619 }
    620 }
    621}
    622
    623/** converts Xpress' sen/rhs/rng triplets into SCIP's lhs/rhs pairs */
    624static
    626 SCIP_LPI* lpi, /**< LP interface structure */
    627 int nrows, /**< number of rows */
    628 SCIP_Real* lhs, /**< buffer to store the left hand side vector, or NULL */
    629 SCIP_Real* rhs /**< buffer to store the right hand side vector, or NULL */
    630 )
    631{
    632 if( lhs != NULL && rhs != NULL )
    633 reconvertBothSides(lpi, nrows, lhs, rhs);
    634 else if( lhs != NULL )
    635 reconvertLhs(lpi, nrows, lhs);
    636 else if( rhs != NULL )
    637 reconvertRhs(lpi, nrows, rhs);
    638}
    639
    640/**@} */
    641
    642
    643/** marks the current LP to be unsolved */
    644static
    646 SCIP_LPI* lpi
    647 )
    648{
    649 assert(lpi != NULL);
    650 lpi->solstat = -1;
    651}
    652
    653/*
    654 * LP Interface Methods
    655 */
    656
    657/**@name Miscellaneous Methods
    658 *
    659 * @{
    660 */
    661
    662#ifdef _Thread_local
    663static _Thread_local char xprsname[100];
    664#else
    665static char xprsname[] = {'X', 'p', 'r', 'e', 's', 's', ' ', '0' + XPVERSION / 10, '0' + XPVERSION % 10, '\0'};
    666#endif
    667/** gets name and version of LP solver */
    669 void
    670 )
    671{
    672#ifdef _Thread_local
    673 char version[16];
    674
    675 /* get version of Xpress */
    676 if( XPRSgetversion(version) == 0 )
    677 (void) sprintf(xprsname, "Xpress %s", version);
    678 else
    679 (void) sprintf(xprsname, "Xpress %d", XPVERSION);
    680#endif
    681 return xprsname;
    682}
    683
    684/** gets description of LP solver (developer, webpage, ...) */
    686 void
    687 )
    688{
    689 return "Linear Programming Solver developed by FICO (www.fico.com/en/products/fico-xpress-optimization)";
    690}
    691
    692/** gets pointer for LP solver - use only with great care
    693 *
    694 * Here we return the pointer to the LP environment.
    695 */
    697 SCIP_LPI* lpi /**< pointer to an LP interface structure */
    698 )
    699{ /*lint --e{715}*/
    700 return (void*) lpi->xprslp;
    701}
    702
    703/** pass integrality information to LP solver */
    705 SCIP_LPI* lpi, /**< pointer to an LP interface structure */
    706 int ncols, /**< length of integrality array */
    707 int* intInfo /**< integrality array (0: continuous, 1: integer). May be NULL iff ncols is 0. */
    708 )
    709{ /*lint --e{715}*/
    710 assert(lpi != NULL);
    711 assert(ncols >= 0);
    712 assert(ncols == 0 || intInfo != NULL);
    713
    714 SCIPerrorMessage("SCIPlpiSetIntegralityInformation() has not been implemented yet.\n");
    715 return SCIP_LPERROR;
    716}
    717
    718/** informs about availability of a primal simplex solving method */
    720 void
    721 )
    722{
    723 return TRUE;
    724}
    725
    726/** informs about availability of a dual simplex solving method */
    728 void
    729 )
    730{
    731 return TRUE;
    732}
    733
    734/** informs about availability of a barrier solving method */
    736 void
    737 )
    738{
    739 return TRUE;
    740}
    741
    742/**@} */
    743
    744
    745/**@name LPI Creation and Destruction Methods
    746 *
    747 * @{
    748 */
    749
    750/** creates an LP problem object */
    752 SCIP_LPI** lpi, /**< pointer to an LP interface structure */
    753 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler to use for printing messages, or NULL */
    754 const char* name, /**< problem name */
    755 SCIP_OBJSEN objsen /**< objective sense */
    756 )
    757{
    758 int zero = 0;
    759
    760 assert(sizeof(SCIP_Real) == sizeof(double)); /*lint !e506*/ /* Xpress only works with doubles as floating points */
    761 assert(sizeof(SCIP_Bool) == sizeof(int)); /*lint !e506*/ /* Xpress only works with ints as bools */
    762 assert(lpi != NULL);
    763 assert(name != NULL);
    764
    765 SCIPdebugMessage("SCIPlpiCreate()\n");
    766
    767 /* the interface is revised for Xpress 26 or higher */
    768 if( XPVERSION < 26 ) /*lint !e506 !e774*/
    769 {
    770 SCIPmessagePrintWarning(messagehdlr, "Please use Xpress version 26 or higher, you are using %d\n", XPVERSION);
    771 return SCIP_LPERROR;
    772 }
    773
    774 /* initialize the Xpress library (licensing) */
    775 CHECK_ZERO( messagehdlr, XPRSinit(NULL) );
    776
    777 /* create LPi data structure */
    779
    780 /* copy the problem name */
    781 (void)strncpy((*lpi)->name, name, 199);
    782 (*lpi)->name[199] = '\0';
    783
    784 (*lpi)->larray = NULL;
    785 (*lpi)->uarray = NULL;
    786 (*lpi)->senarray = NULL;
    787 (*lpi)->rhsarray = NULL;
    788 (*lpi)->rngarray = NULL;
    789 (*lpi)->indarray = NULL;
    790 (*lpi)->valarray = NULL;
    791 (*lpi)->cstat = NULL;
    792 (*lpi)->rstat = NULL;
    793 (*lpi)->boundchgsize = 0;
    794 (*lpi)->sidechgsize = 0;
    795 (*lpi)->valsize = 0;
    796 (*lpi)->cstatsize = 0;
    797 (*lpi)->rstatsize = 0;
    798 (*lpi)->iterations = 0;
    799 (*lpi)->solisbasic = TRUE;
    800 (*lpi)->clearstate = FALSE;
    801 (*lpi)->solmethod = ' ';
    802 (*lpi)->par_lobjlim = -1e+40;
    803 (*lpi)->par_uobjlim = +1e+40;
    804 (*lpi)->par_fastlp = 0;
    805 (*lpi)->par_presolve = 0;
    806 (*lpi)->messagehdlr = messagehdlr;
    807
    808 CHECK_ZERO( messagehdlr, XPRScreateprob(&(*lpi)->xprslp) );
    809 invalidateSolution(*lpi);
    810
    811 /* turn logging off until the user explicitly turns it on; this should prevent any unwanted Xpress output from
    812 * appearing in the SCIP log.
    813 */
    814 CHECK_ZERO( messagehdlr, XPRSsetintcontrol((*lpi)->xprslp, XPRS_OUTPUTLOG, 0) );
    815
    816 /* we need to create an empty LP in this prob since SCIP might attempt to add rows or columns to it */
    817 CHECK_ZERO( messagehdlr, XPRSloadlp((*lpi)->xprslp, (*lpi)->name, 0, 0, NULL, NULL, NULL, NULL, &zero, NULL, NULL, NULL, NULL, NULL) );
    818
    819 /* set objective sense */
    820 SCIP_CALL( SCIPlpiChgObjsen(*lpi, objsen) );
    821
    822 return SCIP_OKAY;
    823}
    824
    825/** deletes an LP problem object */
    827 SCIP_LPI** lpi /**< pointer to an LP interface structure */
    828 )
    829{
    830 assert(lpi != NULL);
    831 assert(*lpi != NULL);
    832 assert((*lpi)->xprslp != NULL);
    833
    834 SCIPdebugMessage("SCIPlpiFree()\n");
    835
    836 /* free LP */
    837 CHECK_ZERO( (*lpi)->messagehdlr, XPRSdestroyprob(((*lpi)->xprslp)) );
    838
    839 /* free environment */
    840 CHECK_ZERO( (*lpi)->messagehdlr, XPRSfree() );
    841
    842 /* free memory */
    843 BMSfreeMemoryArrayNull(&(*lpi)->larray);
    844 BMSfreeMemoryArrayNull(&(*lpi)->uarray);
    845 BMSfreeMemoryArrayNull(&(*lpi)->senarray);
    846 BMSfreeMemoryArrayNull(&(*lpi)->rhsarray);
    847 BMSfreeMemoryArrayNull(&(*lpi)->rngarray);
    848 BMSfreeMemoryArrayNull(&(*lpi)->indarray);
    849 BMSfreeMemoryArrayNull(&(*lpi)->valarray);
    850 BMSfreeMemoryArrayNull(&(*lpi)->cstat);
    851 BMSfreeMemoryArrayNull(&(*lpi)->rstat);
    852 BMSfreeMemory(lpi);
    853
    854 return SCIP_OKAY;
    855}
    856
    857/**@} */
    858
    859
    860/**@name Modification Methods
    861 *
    862 * @{
    863 */
    864
    865/** copies LP data with column matrix into LP solver */
    867 SCIP_LPI* lpi, /**< LP interface structure */
    868 SCIP_OBJSEN objsen, /**< objective sense */
    869 int ncols, /**< number of columns */
    870 const SCIP_Real* obj, /**< objective function values of columns */
    871 const SCIP_Real* lb, /**< lower bounds of columns */
    872 const SCIP_Real* ub, /**< upper bounds of columns */
    873 char** colnames, /**< column names, or NULL */
    874 int nrows, /**< number of rows */
    875 const SCIP_Real* lhs, /**< left hand sides of rows */
    876 const SCIP_Real* rhs, /**< right hand sides of rows */
    877 char** rownames, /**< row names, or NULL */
    878 int nnonz, /**< number of nonzero elements in the constraint matrix */
    879 const int* beg, /**< start index of each column in ind- and val-array */
    880 const int* ind, /**< row indices of constraint matrix entries */
    881 const SCIP_Real* val /**< values of constraint matrix entries */
    882 )
    883{ /*lint --e{715}*/
    884 int c;
    885
    886#ifndef NDEBUG
    887 {
    888 int j;
    889 for( j = 0; j < nnonz; j++ )
    890 assert( val[j] != 0 );
    891 }
    892#endif
    893
    894 assert(lpi != NULL);
    895 assert(lpi->xprslp != NULL);
    896 assert(obj != NULL);
    897 assert(lb != NULL);
    898 assert(ub != NULL);
    899 assert(beg != NULL);
    900 assert(ind != NULL);
    901 assert(val != NULL);
    902 SCIP_UNUSED(colnames);
    903 SCIP_UNUSED(rownames);
    904
    905 SCIPdebugMessage("loading LP in column format into Xpress: %d cols, %d rows\n", ncols, nrows);
    906
    908
    909 /* ensure that the temporary arrays for the side conversion are long enough */
    910 SCIP_CALL( ensureSidechgMem(lpi, nrows) );
    911
    912 /* convert lhs/rhs into sen/rhs/range tuples the sen/rhs/range are stored in the temporary arrays in lpi structure */
    913 convertSides(lpi, nrows, lhs, rhs);
    914
    915 /* ensure that the temporary arrays are large enough */
    916 SCIP_CALL( ensureValMem(lpi, ncols) );
    917
    918 /* calculate column lengths */
    919 for( c = 0; c < ncols-1; ++c )
    920 {
    921 lpi->indarray[c] = beg[c+1] - beg[c];
    922 assert(lpi->indarray[c] >= 0);
    923 }
    924 lpi->indarray[ncols-1] = nnonz - beg[ncols-1];
    925 assert(lpi->indarray[ncols-1] >= 0);
    926
    927 /* copy data into Xpress */
    928 CHECK_ZERO( lpi->messagehdlr, XPRSloadlp(lpi->xprslp, lpi->name, ncols, nrows, lpi->senarray, lpi->rhsarray,
    929 lpi->rngarray, obj, beg, lpi->indarray, ind, val, lb, ub) );
    930
    931 /* set objective sense */
    932 SCIP_CALL( SCIPlpiChgObjsen(lpi, objsen) );
    933
    934 return SCIP_OKAY;
    935}
    936
    937/** adds columns to the LP */
    939 SCIP_LPI* lpi, /**< LP interface structure */
    940 int ncols, /**< number of columns to be added */
    941 const SCIP_Real* obj, /**< objective function values of new columns */
    942 const SCIP_Real* lb, /**< lower bounds of new columns */
    943 const SCIP_Real* ub, /**< upper bounds of new columns */
    944 char** colnames, /**< column names, or NULL */
    945 int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
    946 const int* beg, /**< start index of each column in ind- and val-array, or NULL if nnonz == 0 */
    947 const int* ind, /**< row indices of constraint matrix entries, or NULL if nnonz == 0 */
    948 const SCIP_Real* val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
    949 )
    950{ /*lint --e{715}*/
    951 int c;
    952
    953 assert(lpi != NULL);
    954 assert(lpi->xprslp != NULL);
    955 assert(ncols > 0);
    956 assert(obj != NULL);
    957 assert(lb != NULL);
    958 assert(ub != NULL);
    959 assert(nnonz >= 0);
    960 assert(nnonz == 0 || beg != NULL);
    961 assert(nnonz == 0 || ind != NULL);
    962 assert(nnonz == 0 || val != NULL);
    963 SCIP_UNUSED(colnames);
    964
    965 SCIPdebugMessage("adding %d columns with %d nonzeros to Xpress\n", ncols, nnonz);
    966
    968
    969 /* ensure that the temporary arrays are large enough */
    970 SCIP_CALL( ensureValMem(lpi, ncols+1) );
    971
    972#ifndef NDEBUG
    973 {
    974 /* perform check that no new rows are added - this is forbidden */
    975 int nrows;
    976 int j;
    977
    978 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
    979 for (j = 0; j < nnonz; ++j)
    980 {
    981 assert( val[j] != 0.0 );
    982 assert( 0 <= ind[j] && ind[j] < nrows );
    983 }
    984 }
    985#endif
    986
    987 /* only collect the start array if we have at least one non-zero */
    988 if( nnonz > 0 )
    989 {
    990 /* we need ncol+1 entries in the start array for Xpress */
    991 for( c = 0; c < ncols; c++ )
    992 lpi->indarray[c] = beg[c];
    993 lpi->indarray[ncols] = nnonz;
    994 }
    995
    996 /* add the columns with (potential) non-zeros to the Xpress */
    997 CHECK_ZERO( lpi->messagehdlr, XPRSaddcols(lpi->xprslp, ncols, nnonz, obj, lpi->indarray, ind, val, lb, ub) );
    998
    999 return SCIP_OKAY;
    1000}
    1001
    1002/** deletes all columns in the given range from LP */
    1004 SCIP_LPI* lpi, /**< LP interface structure */
    1005 int firstcol, /**< first column to be deleted */
    1006 int lastcol /**< last column to be deleted */
    1007 )
    1008{
    1009 int c;
    1010
    1011 debugCheckColrang(lpi, firstcol, lastcol);
    1012
    1013 SCIPdebugMessage("deleting %d columns from Xpress\n", lastcol - firstcol + 1);
    1014
    1015 /* handle empty range */
    1016 if( firstcol > lastcol )
    1017 return SCIP_OKAY;
    1018
    1019 invalidateSolution(lpi);
    1020
    1021 /* ensure that the temporary arrays are large enough */
    1022 SCIP_CALL( ensureValMem(lpi, lastcol-firstcol+1) );
    1023
    1024 /* collect the columns indices to be deleted */
    1025 for( c = firstcol; c <= lastcol; c++ )
    1026 lpi->indarray[c-firstcol] = c;
    1027
    1028 CHECK_ZERO( lpi->messagehdlr, XPRSdelcols(lpi->xprslp, lastcol-firstcol+1, lpi->indarray) );
    1029
    1030 return SCIP_OKAY;
    1031}
    1032
    1033/** deletes columns from SCIP_LP; the new position of a column must not be greater that its old position */
    1035 SCIP_LPI* lpi, /**< LP interface structure */
    1036 int* dstat /**< deletion status of columns
    1037 * input: 1 if column should be deleted, 0 if not
    1038 * output: new position of column, -1 if column was deleted */
    1039 )
    1040{
    1041 int nkeptcols;
    1042 int ndelcols;
    1043 int ncols;
    1044 int c;
    1045
    1046 assert(lpi != NULL);
    1047 assert(lpi->xprslp != NULL);
    1048 assert(dstat != NULL);
    1049
    1050 SCIPdebugMessage("deleting a column set from Xpress\n");
    1051
    1052 invalidateSolution(lpi);
    1053
    1054 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_COLS, &ncols) );
    1055
    1056 nkeptcols = 0;
    1057 ndelcols = 0;
    1058
    1059 /* ensure that the temporary arrays are large enough */
    1060 SCIP_CALL( ensureValMem(lpi, ncols) );
    1061
    1062 /* collect the column indecies which should be deleted and create a the new column ordering */
    1063 for( c = 0; c < ncols; c++ )
    1064 {
    1065 if( dstat[c] == 1 )
    1066 {
    1067 dstat[c] = -1;
    1068 lpi->indarray[ndelcols] = c;
    1069 ndelcols++;
    1070 }
    1071 else
    1072 {
    1073 dstat[c] = nkeptcols;
    1074 nkeptcols++;
    1075 }
    1076 }
    1077
    1078 CHECK_ZERO( lpi->messagehdlr, XPRSdelcols(lpi->xprslp, ndelcols, lpi->indarray) );
    1079
    1080 return SCIP_OKAY;
    1081}
    1082
    1083/** adds rows to the LP */
    1085 SCIP_LPI* lpi, /**< LP interface structure */
    1086 int nrows, /**< number of rows to be added */
    1087 const SCIP_Real* lhs, /**< left hand sides of new rows */
    1088 const SCIP_Real* rhs, /**< right hand sides of new rows */
    1089 char** rownames, /**< row names, or NULL */
    1090 int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
    1091 const int* beg, /**< start index of each row in ind- and val-array, or NULL if nnonz == 0 */
    1092 const int* ind, /**< column indices of constraint matrix entries, or NULL if nnonz == 0 */
    1093 const SCIP_Real* val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
    1094 )
    1095{ /*lint --e{715}*/
    1096 int r;
    1097
    1098 assert(lpi != NULL);
    1099 assert(lpi->xprslp != NULL);
    1100 assert(nrows >= 0);
    1101 assert(lhs != NULL);
    1102 assert(rhs != NULL);
    1103 assert(nnonz >= 0);
    1104 assert(nnonz == 0 || beg != NULL);
    1105 assert(nnonz == 0 || ind != NULL);
    1106 assert(nnonz == 0 || val != NULL);
    1107 SCIP_UNUSED(rownames);
    1108
    1109 SCIPdebugMessage("adding %d rows with %d nonzeros to Xpress\n", nrows, nnonz);
    1110
    1111 invalidateSolution(lpi);
    1112
    1113#ifndef NDEBUG
    1114 {
    1115 /* perform check that no new cols are added - this is forbidden */
    1116 int ncols;
    1117 int j;
    1118
    1119 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_COLS, &ncols) );
    1120 for (j = 0; j < nnonz; ++j)
    1121 {
    1122 assert( val[j] != 0.0 );
    1123 assert( 0 <= ind[j] && ind[j] < ncols );
    1124 }
    1125 }
    1126#endif
    1127
    1128 /* ensure that the temporary arrays are large enough */
    1129 SCIP_CALL( ensureSidechgMem(lpi, nrows) );
    1130 SCIP_CALL( ensureValMem(lpi, nrows+1) );
    1131
    1132 /* convert lhs/rhs into sen/rhs/range tuples */
    1133 convertSides(lpi, nrows, lhs, rhs);
    1134
    1135 /* only collect the start array if we have at least one non-zero */
    1136 if( nnonz > 0 )
    1137 {
    1138 for( r = 0; r < nrows; r++ )
    1139 lpi->indarray[r] = beg[r];
    1140 lpi->indarray[nrows] = nnonz;
    1141 }
    1142
    1143 CHECK_ZERO( lpi->messagehdlr, XPRSaddrows(lpi->xprslp, nrows, nnonz, lpi->senarray, lpi->rhsarray, lpi->rngarray, lpi->indarray, ind, val) );
    1144
    1145 return SCIP_OKAY;
    1146}
    1147
    1148/** deletes all rows in the given range from LP */
    1150 SCIP_LPI* lpi, /**< LP interface structure */
    1151 int firstrow, /**< first row to be deleted */
    1152 int lastrow /**< last row to be deleted */
    1153 )
    1154{
    1155 int r;
    1156
    1157 debugCheckRowrang(lpi, firstrow, lastrow);
    1158
    1159 SCIPdebugMessage("deleting %d rows from Xpress\n", lastrow - firstrow + 1);
    1160
    1161 /* handle empty range */
    1162 if( firstrow > lastrow )
    1163 return SCIP_OKAY;
    1164
    1165 invalidateSolution(lpi);
    1166
    1167 /* ensure that the temporary arrays are large enough */
    1168 SCIP_CALL( ensureValMem(lpi, lastrow-firstrow+1) );
    1169
    1170 for( r = firstrow; r <= lastrow; r++ )
    1171 lpi->indarray[r-firstrow] = r;
    1172
    1173 CHECK_ZERO( lpi->messagehdlr, XPRSdelrows(lpi->xprslp, lastrow-firstrow+1, lpi->indarray) );
    1174
    1175 return SCIP_OKAY;
    1176}
    1177
    1178/** deletes rows from SCIP_LP; the new position of a row must not be greater that its old position */
    1180 SCIP_LPI* lpi, /**< LP interface structure */
    1181 int* dstat /**< deletion status of rows
    1182 * input: 1 if row should be deleted, 0 if not
    1183 * output: new position of row, -1 if row was deleted */
    1184 )
    1185{
    1186 int nkeptrows;
    1187 int ndelrows;
    1188 int nrows;
    1189 int r;
    1190
    1191 assert(lpi != NULL);
    1192 assert(lpi->xprslp != NULL);
    1193
    1194 SCIPdebugMessage("deleting a row set from Xpress\n");
    1195
    1196 invalidateSolution(lpi);
    1197
    1198 nkeptrows = 0;
    1199 ndelrows = 0;
    1200
    1201 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
    1202
    1203 /* ensure that the temporary arrays are large enough */
    1204 SCIP_CALL( ensureValMem(lpi, nrows) );
    1205
    1206 /* collect the row indecies which should be deleted and create a the new row ordering */
    1207 for( r = 0; r < nrows; r++ )
    1208 {
    1209 if( dstat[r] == 1 )
    1210 {
    1211 dstat[r] = -1;
    1212 lpi->indarray[ndelrows] = r;
    1213 ndelrows++;
    1214 }
    1215 else
    1216 {
    1217 dstat[r] = nkeptrows;
    1218 nkeptrows++;
    1219 }
    1220 }
    1221
    1222 CHECK_ZERO( lpi->messagehdlr, XPRSdelrows(lpi->xprslp, ndelrows, lpi->indarray) );
    1223
    1224 return SCIP_OKAY;
    1225}
    1226
    1227/** clears the whole LP */
    1229 SCIP_LPI* lpi /**< LP interface structure */
    1230 )
    1231{
    1232 int zero = 0;
    1233
    1234 assert(lpi != NULL);
    1235 assert(lpi->xprslp != NULL);
    1236
    1237 SCIPdebugMessage("clearing Xpress LP\n");
    1238
    1239 invalidateSolution(lpi);
    1240
    1241 /* create an empty LP in this */
    1242 CHECK_ZERO( lpi->messagehdlr, XPRSloadlp(lpi->xprslp, lpi->name, 0, 0, NULL, NULL, NULL, NULL, &zero, NULL, NULL, NULL, NULL, NULL) );
    1243
    1244 return SCIP_OKAY;
    1245}
    1246
    1247/** changes lower and upper bounds of columns */
    1249 SCIP_LPI* lpi, /**< LP interface structure */
    1250 int ncols, /**< number of columns to change bounds for */
    1251 const int* ind, /**< column indices or NULL if ncols is zero */
    1252 const SCIP_Real* lb, /**< values for the new lower bounds or NULL if ncols is zero */
    1253 const SCIP_Real* ub /**< values for the new upper bounds or NULL if ncols is zero */
    1254 )
    1255{
    1256 int j;
    1257
    1258 assert(lpi != NULL);
    1259 assert(lpi->xprslp != NULL);
    1260 assert(ncols == 0 || (ind != NULL && lb != NULL && ub != NULL));
    1261
    1262 SCIPdebugMessage("changing %d bounds in Xpress\n", ncols);
    1263 if( ncols <= 0 )
    1264 return SCIP_OKAY;
    1265
    1266 invalidateSolution(lpi);
    1267
    1268 for (j = 0; j < ncols; ++j)
    1269 {
    1270 if ( SCIPlpiIsInfinity(lpi, lb[j]) )
    1271 {
    1272 SCIPerrorMessage("LP Error: fixing lower bound for variable %d to infinity.\n", ind[j]);
    1273 return SCIP_LPERROR;
    1274 }
    1275 if ( SCIPlpiIsInfinity(lpi, -ub[j]) )
    1276 {
    1277 SCIPerrorMessage("LP Error: fixing upper bound for variable %d to -infinity.\n", ind[j]);
    1278 return SCIP_LPERROR;
    1279 }
    1280 }
    1281
    1282 /* ensure that the temporary arrays are large enough */
    1283 SCIP_CALL( ensureBoundchgMem(lpi, ncols) );
    1284
    1285 CHECK_ZERO( lpi->messagehdlr, XPRSchgbounds(lpi->xprslp, ncols, ind, lpi->larray, (SCIP_Real*)lb) );
    1286 CHECK_ZERO( lpi->messagehdlr, XPRSchgbounds(lpi->xprslp, ncols, ind, lpi->uarray, (SCIP_Real*)ub) );
    1287
    1288 return SCIP_OKAY;
    1289}
    1290
    1291/** changes left and right hand sides of rows */
    1293 SCIP_LPI* lpi, /**< LP interface structure */
    1294 int nrows, /**< number of rows to change sides for */
    1295 const int* ind, /**< row indices */
    1296 const SCIP_Real* lhs, /**< new values for left hand sides */
    1297 const SCIP_Real* rhs /**< new values for right hand sides */
    1298 )
    1299{
    1300 assert(lpi != NULL);
    1301 assert(lpi->xprslp != NULL);
    1302 assert(ind != NULL);
    1303
    1304 SCIPdebugMessage("changing %d sides in Xpress\n", nrows);
    1305 if( nrows <= 0 )
    1306 return SCIP_OKAY;
    1307
    1308 invalidateSolution(lpi);
    1309
    1310 /* ensure that the temporary arrays are large enough */
    1311 SCIP_CALL( ensureSidechgMem(lpi, nrows) );
    1312
    1313 /* convert lhs/rhs into sen/rhs/range tuples */
    1314 convertSides(lpi, nrows, lhs, rhs);
    1315
    1316 /* change row sides */
    1317 CHECK_ZERO( lpi->messagehdlr, XPRSchgrowtype(lpi->xprslp, nrows, ind, lpi->senarray) );
    1318 CHECK_ZERO( lpi->messagehdlr, XPRSchgrhs(lpi->xprslp, nrows, ind, lpi->rhsarray) );
    1319 CHECK_ZERO( lpi->messagehdlr, XPRSchgrhsrange(lpi->xprslp, nrows, ind, lpi->rngarray) );
    1320
    1321 return SCIP_OKAY;
    1322}
    1323
    1324/** changes a single coefficient */
    1326 SCIP_LPI* lpi, /**< LP interface structure */
    1327 int row, /**< row number of coefficient to change */
    1328 int col, /**< column number of coefficient to change */
    1329 SCIP_Real newval /**< new value of coefficient */
    1330 )
    1331{
    1332 assert(lpi != NULL);
    1333 assert(lpi->xprslp != NULL);
    1334
    1335 SCIPdebugMessage("changing coefficient row %d, column %d in Xpress to %g\n", row, col, newval);
    1336
    1337 invalidateSolution(lpi);
    1338
    1339 CHECK_ZERO( lpi->messagehdlr, XPRSchgcoef(lpi->xprslp, row, col, newval) );
    1340
    1341 return SCIP_OKAY;
    1342}
    1343
    1344/** changes the objective sense */
    1346 SCIP_LPI* lpi, /**< LP interface structure */
    1347 SCIP_OBJSEN objsense /**< new objective sense */
    1348 )
    1349{
    1350 assert(lpi != NULL);
    1351 assert(lpi->xprslp != NULL);
    1352
    1353 SCIPdebugMessage("changing objective sense in Xpress to %d\n", objsense);
    1354
    1355 invalidateSolution(lpi);
    1356
    1357 CHECK_ZERO( lpi->messagehdlr, XPRSchgobjsense(lpi->xprslp, xprsObjsen(objsense)) );
    1358
    1359 return SCIP_OKAY;
    1360}
    1361
    1362/** changes objective values of columns in the LP */
    1364 SCIP_LPI* lpi, /**< LP interface structure */
    1365 int ncols, /**< number of columns to change objective value for */
    1366 const int* ind, /**< column indices to change objective value for */
    1367 const SCIP_Real* obj /**< new objective values for columns */
    1368 )
    1369{
    1370 assert(lpi != NULL);
    1371 assert(lpi->xprslp != NULL);
    1372 assert(ind != NULL);
    1373 assert(obj != NULL);
    1374
    1375 SCIPdebugMessage("changing %d objective values in Xpress\n", ncols);
    1376
    1377 invalidateSolution(lpi);
    1378
    1379 CHECK_ZERO( lpi->messagehdlr, XPRSchgobj(lpi->xprslp, ncols, ind, obj) );
    1380
    1381 return SCIP_OKAY;
    1382}
    1383
    1384/** multiplies a row with a non-zero scalar; for negative scalars, the row's sense is switched accordingly */
    1386 SCIP_LPI* lpi, /**< LP interface structure */
    1387 int row, /**< row number to scale */
    1388 SCIP_Real scaleval /**< scaling multiplier */
    1389 )
    1390{
    1391 SCIP_Real lhs;
    1392 SCIP_Real rhs;
    1393 int nnonz;
    1394 int ncols;
    1395 int i;
    1396
    1397 assert(lpi != NULL);
    1398 assert(lpi->xprslp != NULL);
    1399 assert(scaleval != 0.0);
    1400
    1401 SCIPdebugMessage("scaling row %d with factor %g in Xpress\n", row, scaleval);
    1402
    1403 invalidateSolution(lpi);
    1404
    1405 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_COLS, &ncols) );
    1406 SCIP_CALL( ensureValMem(lpi, ncols) );
    1407
    1408 /* get the row */
    1409 SCIP_CALL( SCIPlpiGetSides(lpi, row, row, &lhs, &rhs) );
    1410 CHECK_ZERO( lpi->messagehdlr, XPRSgetrows(lpi->xprslp, NULL, lpi->indarray, lpi->valarray, ncols, &nnonz, row, row) );
    1411 assert(nnonz <= ncols);
    1412
    1413 /* scale row coefficients */
    1414 for( i = 0; i < nnonz; ++i )
    1415 {
    1416 SCIP_CALL( SCIPlpiChgCoef(lpi, row, lpi->indarray[i], lpi->valarray[i] * scaleval) );
    1417 }
    1418
    1419 /* scale row sides */
    1420 if( lhs > XPRS_MINUSINFINITY )
    1421 lhs *= scaleval;
    1422 else if( scaleval < 0.0 )
    1423 lhs = XPRS_PLUSINFINITY;
    1424 if( rhs < XPRS_PLUSINFINITY )
    1425 rhs *= scaleval;
    1426 else if( scaleval < 0.0 )
    1427 rhs = XPRS_MINUSINFINITY;
    1428
    1429 if( scaleval > 0.0 )
    1430 {
    1431 SCIP_CALL( SCIPlpiChgSides(lpi, 1, &row, &lhs, &rhs) );
    1432 }
    1433 else
    1434 {
    1435 SCIP_CALL( SCIPlpiChgSides(lpi, 1, &row, &rhs, &lhs) );
    1436 }
    1437
    1438 return SCIP_OKAY;
    1439}
    1440
    1441/** multiplies a column with a non-zero scalar; the objective value is multiplied with the scalar, and the bounds
    1442 * are divided by the scalar; for negative scalars, the column's bounds are switched
    1443 */
    1445 SCIP_LPI* lpi, /**< LP interface structure */
    1446 int col, /**< column number to scale */
    1447 SCIP_Real scaleval /**< scaling multiplier */
    1448 )
    1449{
    1450 SCIP_Real lb;
    1451 SCIP_Real ub;
    1452 SCIP_Real obj;
    1453 int nnonz;
    1454 int nrows;
    1455 int i;
    1456
    1457 assert(lpi != NULL);
    1458 assert(lpi->xprslp != NULL);
    1459 assert(scaleval != 0.0);
    1460
    1461 SCIPdebugMessage("scaling column %d with factor %g in Xpress\n", col, scaleval);
    1462
    1463 invalidateSolution(lpi);
    1464
    1465 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
    1466 SCIP_CALL( ensureValMem(lpi, nrows) );
    1467
    1468 /* get the column */
    1469 CHECK_ZERO( lpi->messagehdlr, XPRSgetlb(lpi->xprslp, &lb, col, col) );
    1470 CHECK_ZERO( lpi->messagehdlr, XPRSgetub(lpi->xprslp, &ub, col, col) );
    1471 CHECK_ZERO( lpi->messagehdlr, XPRSgetcols(lpi->xprslp, NULL, lpi->indarray, lpi->valarray, nrows, &nnonz, col, col) );
    1472 assert(nnonz <= nrows);
    1473
    1474 /* get objective coefficient */
    1475 SCIP_CALL( SCIPlpiGetObj(lpi, col, col, &obj) );
    1476
    1477 /* scale column coefficients */
    1478 for( i = 0; i < nnonz; ++i )
    1479 {
    1480 SCIP_CALL( SCIPlpiChgCoef(lpi, lpi->indarray[i], col, lpi->valarray[i] * scaleval) );
    1481 }
    1482
    1483 /* scale objective value */
    1484 obj *= scaleval;
    1485 SCIP_CALL( SCIPlpiChgObj(lpi, 1, &col, &obj) );
    1486
    1487 /* scale column bounds */
    1488 if( lb > XPRS_MINUSINFINITY )
    1489 lb /= scaleval;
    1490 else if( scaleval < 0.0 )
    1491 lb = XPRS_PLUSINFINITY;
    1492 if( ub < XPRS_PLUSINFINITY )
    1493 ub /= scaleval;
    1494 else if( scaleval < 0.0 )
    1495 ub = XPRS_MINUSINFINITY;
    1496
    1497 if( scaleval > 0.0 )
    1498 {
    1499 SCIP_CALL( SCIPlpiChgBounds(lpi, 1, &col, &lb, &ub) );
    1500 }
    1501 else
    1502 {
    1503 SCIP_CALL( SCIPlpiChgBounds(lpi, 1, &col, &ub, &lb) );
    1504 }
    1505
    1506 return SCIP_OKAY;
    1507}
    1508
    1509/**@} */
    1510
    1511
    1512/**@name Data Accessing Methods
    1513 *
    1514 * @{
    1515 */
    1516
    1517/** gets the number of rows in the LP */
    1519 SCIP_LPI* lpi, /**< LP interface structure */
    1520 int* nrows /**< pointer to store the number of rows */
    1521 )
    1522{
    1523 assert(lpi != NULL);
    1524 assert(lpi->xprslp != NULL);
    1525 assert(nrows != NULL);
    1526
    1527 SCIPdebugMessage("getting number of rows\n");
    1528
    1529 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, nrows) );
    1530
    1531 return SCIP_OKAY;
    1532}
    1533
    1534/** gets the number of columns in the LP */
    1536 SCIP_LPI* lpi, /**< LP interface structure */
    1537 int* ncols /**< pointer to store the number of cols */
    1538 )
    1539{
    1540 assert(lpi != NULL);
    1541 assert(lpi->xprslp != NULL);
    1542 assert(ncols != NULL);
    1543
    1544 SCIPdebugMessage("getting number of columns\n");
    1545
    1546 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_COLS, ncols) );
    1547
    1548 return SCIP_OKAY;
    1549}
    1550
    1551/** gets the number of nonzero elements in the LP constraint matrix */
    1553 SCIP_LPI* lpi, /**< LP interface structure */
    1554 int* nnonz /**< pointer to store the number of nonzeros */
    1555 )
    1556{
    1557 assert(lpi != NULL);
    1558 assert(lpi->xprslp != NULL);
    1559 assert(nnonz != NULL);
    1560
    1561 SCIPdebugMessage("getting number of non-zeros\n");
    1562
    1563 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ELEMS, nnonz) );
    1564
    1565 return SCIP_OKAY;
    1566}
    1567
    1568/** gets columns from LP problem object; the arrays have to be large enough to store all values
    1569 * Either both, lb and ub, have to be NULL, or both have to be non-NULL,
    1570 * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
    1571 */
    1573 SCIP_LPI* lpi, /**< LP interface structure */
    1574 int firstcol, /**< first column to get from LP */
    1575 int lastcol, /**< last column to get from LP */
    1576 SCIP_Real* lb, /**< buffer to store the lower bound vector, or NULL */
    1577 SCIP_Real* ub, /**< buffer to store the upper bound vector, or NULL */
    1578 int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
    1579 int* beg, /**< buffer to store start index of each column in ind- and val-array, or NULL */
    1580 int* ind, /**< buffer to store row indices of constraint matrix entries, or NULL */
    1581 SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
    1582 )
    1583{
    1584 assert((lb != NULL && ub != NULL) || (lb == NULL && ub == NULL));
    1585 assert((nnonz != NULL && beg != NULL && ind != NULL && val != NULL) || (nnonz == NULL && beg == NULL && ind == NULL && val == NULL));
    1586
    1587 debugCheckColrang(lpi, firstcol, lastcol);
    1588
    1589 SCIPdebugMessage("getting columns %d to %d\n", firstcol, lastcol);
    1590
    1591 if( lb != NULL )
    1592 {
    1593 CHECK_ZERO( lpi->messagehdlr, XPRSgetlb(lpi->xprslp, lb, firstcol, lastcol) );
    1594 CHECK_ZERO( lpi->messagehdlr, XPRSgetub(lpi->xprslp, ub, firstcol, lastcol) );
    1595 }
    1596
    1597 if( nnonz != NULL )
    1598 {
    1599 int ntotalnonz;
    1600 int c;
    1601
    1602 /* ensure that the temporary buffer array is large enough */
    1603 SCIP_CALL( ensureValMem(lpi, lastcol-firstcol+2) );
    1604
    1605 /* get number of nonzero in the whole problem; needed to pass a proper size to XPRSgetcols() function call
    1606 *
    1607 * @note We are assuming that the arrays given by SCIP are large enough. Otherwise we are getting invalid writes
    1608 */
    1609 SCIP_CALL( SCIPlpiGetNNonz(lpi, &ntotalnonz) );
    1610
    1611 /* get matrix entries */
    1612 CHECK_ZERO( lpi->messagehdlr, XPRSgetcols(lpi->xprslp, lpi->indarray, ind, val, ntotalnonz, nnonz, firstcol, lastcol) );
    1613 assert(*nnonz <= ntotalnonz);
    1614 assert(lpi->indarray[lastcol-firstcol+1] == *nnonz);
    1615
    1616 assert(beg != NULL); /* for lint */
    1617 for( c = 0; c < lastcol-firstcol+1; c++ )
    1618 beg[c] = lpi->indarray[c];
    1619 }
    1620
    1621 return SCIP_OKAY;
    1622}
    1623
    1624/** gets rows from LP problem object; the arrays have to be large enough to store all values.
    1625 * Either both, lhs and rhs, have to be NULL, or both have to be non-NULL,
    1626 * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
    1627 */
    1629 SCIP_LPI* lpi, /**< LP interface structure */
    1630 int firstrow, /**< first row to get from LP */
    1631 int lastrow, /**< last row to get from LP */
    1632 SCIP_Real* lhss, /**< buffer to store left hand side vector, or NULL */
    1633 SCIP_Real* rhss, /**< buffer to store right hand side vector, or NULL */
    1634 int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
    1635 int* beg, /**< buffer to store start index of each row in ind- and val-array, or NULL */
    1636 int* ind, /**< buffer to store column indices of constraint matrix entries, or NULL */
    1637 SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
    1638 )
    1639{
    1640 assert((lhss != NULL && rhss != NULL) || (lhss == NULL && rhss == NULL));
    1641 assert((nnonz != NULL && beg != NULL && ind != NULL && val != NULL) || (nnonz == NULL && beg == NULL && ind == NULL && val == NULL));
    1642
    1643 debugCheckRowrang(lpi, firstrow, lastrow);
    1644
    1645 SCIPdebugMessage("getting rows %d to %d\n", firstrow, lastrow);
    1646
    1647 if( lhss != NULL )
    1648 {
    1649 /* get left and right sides */
    1650 SCIP_CALL( SCIPlpiGetSides(lpi, firstrow, lastrow, lhss, rhss) );
    1651 }
    1652
    1653 if( nnonz != NULL )
    1654 {
    1655 int ntotalnonz;
    1656 int r;
    1657
    1658 /* ensure that the temporary buffer array is large enough */
    1659 SCIP_CALL( ensureValMem(lpi, lastrow-firstrow+2) );
    1660
    1661 /* get number of nonzero in the whole problem; needed to pass a proper size to XPRSgetrows() function call
    1662 *
    1663 * @note We are assuming that the arrays given by SCIP are large enough. Otherwise we are getting invalid writes
    1664 */
    1665 SCIP_CALL( SCIPlpiGetNNonz(lpi, &ntotalnonz) );
    1666
    1667 /* get matrix entries */
    1668 CHECK_ZERO( lpi->messagehdlr, XPRSgetrows(lpi->xprslp, lpi->indarray, ind, val, ntotalnonz, nnonz, firstrow, lastrow) );
    1669 assert(*nnonz <= ntotalnonz);
    1670 assert(lpi->indarray[lastrow-firstrow+1] == *nnonz);
    1671
    1672 assert(beg != NULL); /* for lint */
    1673 for( r = 0; r < lastrow-firstrow+1; r++ )
    1674 beg[r] = lpi->indarray[r];
    1675 }
    1676
    1677 return SCIP_OKAY;
    1678}
    1679
    1680/** gets column names */
    1682 SCIP_LPI* lpi, /**< LP interface structure */
    1683 int firstcol, /**< first column to get name from LP */
    1684 int lastcol, /**< last column to get name from LP */
    1685 char** colnames, /**< pointers to column names (of size at least lastcol-firstcol+1) or NULL if namestoragesize is zero */
    1686 char* namestorage, /**< storage for col names or NULL if namestoragesize is zero */
    1687 int namestoragesize, /**< size of namestorage (if 0, storageleft returns the storage needed) */
    1688 int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) or NULL if namestoragesize is zero */
    1689 )
    1690{ /*lint --e{715}*/
    1691 assert(colnames != NULL || namestoragesize == 0);
    1692 assert(namestorage != NULL || namestoragesize == 0);
    1693 assert(namestoragesize >= 0);
    1694 assert(storageleft != NULL);
    1695
    1696 debugCheckColrang(lpi, firstcol, lastcol);
    1697
    1698 SCIPerrorMessage("SCIPlpiGetColNames() has not been implemented yet.\n");
    1699
    1700 return SCIP_LPERROR;
    1701}
    1702
    1703/** gets row names */
    1705 SCIP_LPI* lpi, /**< LP interface structure */
    1706 int firstrow, /**< first row to get name from LP */
    1707 int lastrow, /**< last row to get name from LP */
    1708 char** rownames, /**< pointers to row names (of size at least lastrow-firstrow+1) or NULL if namestoragesize is zero */
    1709 char* namestorage, /**< storage for row names or NULL if namestoragesize is zero */
    1710 int namestoragesize, /**< size of namestorage (if 0, -storageleft returns the storage needed) */
    1711 int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) or NULL if namestoragesize is zero */
    1712 )
    1713{ /*lint --e{715}*/
    1714 assert(rownames != NULL || namestoragesize == 0);
    1715 assert(namestorage != NULL || namestoragesize == 0);
    1716 assert(namestoragesize >= 0);
    1717 assert(storageleft != NULL);
    1718
    1719 debugCheckRowrang(lpi, firstrow, lastrow);
    1720
    1721 SCIPerrorMessage("SCIPlpiGetRowNames() has not been implemented yet.\n");
    1722
    1723 return SCIP_LPERROR;
    1724}
    1725
    1726/** gets the objective sense of the LP */
    1728 SCIP_LPI* lpi, /**< LP interface structure */
    1729 SCIP_OBJSEN* objsen /**< pointer to store objective sense */
    1730 )
    1731{
    1732 double xprsobjsen;
    1733 assert(lpi != NULL);
    1734 assert(lpi->xprslp != NULL);
    1735 assert(objsen != NULL);
    1736
    1737 /* check the objective sense attribute for the current objective sense set in Xpress */
    1738 CHECK_ZERO( lpi->messagehdlr, XPRSgetdblattrib(lpi->xprslp, XPRS_OBJSENSE, &xprsobjsen) );
    1739
    1740 /* convert the Xpress objective sense attribute to a SCIP objective sense */
    1741 if( xprsobjsen < 0.0 )
    1742 (*objsen) = SCIP_OBJSEN_MAXIMIZE;
    1743 else
    1744 (*objsen) = SCIP_OBJSEN_MINIMIZE;
    1745
    1746 return SCIP_OKAY;
    1747}
    1748
    1749/** gets objective coefficients from LP problem object */
    1751 SCIP_LPI* lpi, /**< LP interface structure */
    1752 int firstcol, /**< first column to get objective coefficient for */
    1753 int lastcol, /**< last column to get objective coefficient for */
    1754 SCIP_Real* vals /**< array to store objective coefficients */
    1755 )
    1756{
    1757 assert(vals != NULL);
    1758
    1759 debugCheckColrang(lpi, firstcol, lastcol);
    1760
    1761 SCIPdebugMessage("getting objective values %d to %d\n", firstcol, lastcol);
    1762
    1763 CHECK_ZERO( lpi->messagehdlr, XPRSgetobj(lpi->xprslp, vals, firstcol, lastcol) );
    1764
    1765 return SCIP_OKAY;
    1766}
    1767
    1768/** gets current bounds from LP problem object */
    1770 SCIP_LPI* lpi, /**< LP interface structure */
    1771 int firstcol, /**< first column to get bounds for */
    1772 int lastcol, /**< last column to get bounds for */
    1773 SCIP_Real* lbs, /**< array to store lower bound values, or NULL */
    1774 SCIP_Real* ubs /**< array to store upper bound values, or NULL */
    1775 )
    1776{
    1777 debugCheckColrang(lpi, firstcol, lastcol);
    1778
    1779 SCIPdebugMessage("getting bounds %d to %d\n", firstcol, lastcol);
    1780
    1781 if( lbs != NULL )
    1782 {
    1783 CHECK_ZERO( lpi->messagehdlr, XPRSgetlb(lpi->xprslp, lbs, firstcol, lastcol) );
    1784 }
    1785
    1786 if( ubs != NULL )
    1787 {
    1788 CHECK_ZERO( lpi->messagehdlr, XPRSgetub(lpi->xprslp, ubs, firstcol, lastcol) );
    1789 }
    1790
    1791 return SCIP_OKAY;
    1792}
    1793
    1794/** gets current row sides from LP problem object */
    1796 SCIP_LPI* lpi, /**< LP interface structure */
    1797 int firstrow, /**< first row to get sides for */
    1798 int lastrow, /**< last row to get sides for */
    1799 SCIP_Real* lhss, /**< array to store left hand side values, or NULL */
    1800 SCIP_Real* rhss /**< array to store right hand side values, or NULL */
    1801 )
    1802{
    1803 debugCheckRowrang(lpi, firstrow, lastrow);
    1804
    1805 SCIPdebugMessage("getting row sides %d to %d\n", firstrow, lastrow);
    1806
    1807 /* ensure the array size of the temporary buffers */
    1808 SCIP_CALL( ensureSidechgMem(lpi, lastrow - firstrow + 1) );
    1809
    1810 /* get row sense, rhs, and ranges */
    1811 CHECK_ZERO( lpi->messagehdlr, XPRSgetrowtype(lpi->xprslp, lpi->senarray, firstrow, lastrow) );
    1812 CHECK_ZERO( lpi->messagehdlr, XPRSgetrhs(lpi->xprslp, lpi->rhsarray, firstrow, lastrow) );
    1813 CHECK_ZERO( lpi->messagehdlr, XPRSgetrhsrange(lpi->xprslp, lpi->rngarray, firstrow, lastrow) );
    1814
    1815 /* convert sen/rhs/range into lhs/rhs tuples */
    1816 reconvertSides(lpi, lastrow - firstrow + 1, lhss, rhss);
    1817
    1818 return SCIP_OKAY;
    1819}
    1820
    1821/** gets a single coefficient */
    1823 SCIP_LPI* lpi, /**< LP interface structure */
    1824 int row, /**< row number of coefficient */
    1825 int col, /**< column number of coefficient */
    1826 SCIP_Real* val /**< pointer to store the value of the coefficient */
    1827 )
    1828{
    1829 assert(lpi != NULL);
    1830 assert(lpi->xprslp != NULL);
    1831 assert(val != NULL);
    1832
    1833 /* get the coefficient of the column in the corresponding row */
    1834 CHECK_ZERO( lpi->messagehdlr, XPRSgetcoef(lpi->xprslp, row, col, val) );
    1835
    1836 return SCIP_OKAY;
    1837}
    1838
    1839/**@} */
    1840
    1841
    1842/**@name Solving Methods
    1843 *
    1844 * @{
    1845 */
    1846
    1847/** solve LP */
    1849 SCIP_LPI* lpi, /**< LP interface structure */
    1850 const char* method /**< indicates the method to use ('p' - primal, 'd' - dual, 'b' - barrier) */
    1851 )
    1852{
    1853 int primalinfeasible;
    1854 int dualinfeasible;
    1855 int state;
    1856
    1857 assert(lpi != NULL);
    1858 assert(lpi->xprslp != NULL);
    1859
    1860 invalidateSolution(lpi);
    1861
    1862 /* check if the current basis should be ignored */
    1863 if( lpi->clearstate )
    1864 {
    1865 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_KEEPBASIS, 0) );
    1866 lpi->clearstate = FALSE;
    1867 }
    1868
    1869 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_PRESOLVE, 0) );
    1870 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_LPQUICKPRESOLVE, (lpi->par_presolve) ? 1 : 0) );
    1871
    1872 if( lpi->par_fastlp )
    1873 {
    1874 /* Don't refactorize at the end of the solve. */
    1875 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_REFACTOR, 0) );
    1876 }
    1877 else
    1878 {
    1879 /* Use default settings for solving an lp (hopefully) robustly. */
    1880 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_REFACTOR, 1) );
    1881 }
    1882
    1883 /* solve the LP */
    1884 CHECK_ZERO( lpi->messagehdlr, XPRSlpoptimize(lpi->xprslp, method) );
    1885
    1886 /* evaluate the result */
    1887 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_LPSTATUS, &lpi->solstat) );
    1888
    1889 /* Make sure the LP is postsolved in case it was interrupted. */
    1890 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_PRESOLVESTATE, &state) );
    1891
    1892 if( state & (2|4) )
    1893 {
    1894 /* Problem is in a presolve state - postsolve it. */
    1895 CHECK_ZERO( lpi->messagehdlr, XPRSpostsolve(lpi->xprslp) );
    1896 }
    1897
    1898 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_SIMPLEXITER, &lpi->iterations) );
    1899 lpi->solisbasic = TRUE;
    1900
    1901 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_PRIMALINFEAS, &primalinfeasible) );
    1902 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_DUALINFEAS, &dualinfeasible) );
    1903 SCIPdebugMessage(" -> Xpress returned solstat=%d, pinfeas=%d, dinfeas=%d (%d iterations)\n",
    1904 lpi->solstat, primalinfeasible, dualinfeasible, lpi->iterations);
    1905
    1906 /* Make sure that always a primal / dual ray exists */
    1907 if( lpi->solstat == XPRS_LP_INFEAS || lpi->solstat == XPRS_LP_UNBOUNDED )
    1908 {
    1909 int hasray;
    1910 int presolving;
    1911
    1912 /* check whether a dual ray exists, in that case we don't need to resolve the LP w/o presolving */
    1913 CHECK_ZERO( lpi->messagehdlr, XPRSgetdualray(lpi->xprslp, NULL, &hasray) );
    1914
    1915 if( hasray == 1 )
    1916 goto TERMINATE;
    1917
    1918 /* get the current presolving setting */
    1919 CHECK_ZERO( lpi->messagehdlr, XPRSgetintcontrol(lpi->xprslp, XPRS_LPQUICKPRESOLVE, &presolving) );
    1920
    1921 if( presolving != 0 )
    1922 {
    1923 int iterations;
    1924
    1925 /* maybe the preprocessor solved the problem; but we need a solution, so solve again without preprocessing */
    1926 SCIPdebugMessage("presolver may have solved the problem -> calling Xpress %s again without presolve\n",
    1927 strcmp(method, "p") == 0 ? "primal simplex" : strcmp(method, "d") == 0 ? "dual simplex" : "barrier");
    1928
    1929 /* switch off preprocessing */
    1930 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_LPQUICKPRESOLVE, 0) );
    1931
    1932 /* resolve w/o presolving */
    1933 CHECK_ZERO( lpi->messagehdlr, XPRSlpoptimize(lpi->xprslp, method) );
    1934
    1935 /* evaluate the result */
    1936 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_LPSTATUS, &lpi->solstat) );
    1937
    1938 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_SIMPLEXITER, &iterations) );
    1939 lpi->iterations += iterations;
    1940 lpi->solisbasic = TRUE;
    1941
    1942 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_PRIMALINFEAS, &primalinfeasible) );
    1943 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_DUALINFEAS, &dualinfeasible) );
    1944 SCIPdebugMessage(" -> Xpress returned solstat=%d, pinfeas=%d, dinfeas=%d (%d iterations)\n",
    1945 lpi->solstat, primalinfeasible, dualinfeasible, lpi->iterations);
    1946
    1947 /* reinstall the previous setting */
    1948 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_LPQUICKPRESOLVE, presolving) );
    1949 }
    1950 }
    1951
    1952 TERMINATE:
    1953 if( (lpi->solstat == XPRS_LP_OPTIMAL) && (primalinfeasible || dualinfeasible) )
    1955
    1956 return SCIP_OKAY;
    1957}
    1958
    1959/** calls primal simplex to solve the LP */
    1961 SCIP_LPI* lpi /**< LP interface structure */
    1962 )
    1963{
    1964 assert(lpi != NULL);
    1965 assert(lpi->xprslp != NULL);
    1966
    1967 lpi->solmethod = 'p';
    1968 return lpiSolve(lpi, "p");
    1969}
    1970
    1971/** calls dual simplex to solve the LP */
    1973 SCIP_LPI* lpi /**< LP interface structure */
    1974 )
    1975{
    1976 assert(lpi != NULL);
    1977 assert(lpi->xprslp != NULL);
    1978
    1979 lpi->solmethod = 'd';
    1980 return lpiSolve(lpi, "d");
    1981}
    1982
    1983/** calls barrier or interior point algorithm to solve the LP with crossover to simplex basis */
    1985 SCIP_LPI* lpi, /**< LP interface structure */
    1986 SCIP_Bool crossover /**< perform crossover */
    1987 )
    1988{
    1989 SCIP_RETCODE retval;
    1990
    1991 assert(lpi != NULL);
    1992 assert(lpi->xprslp != NULL);
    1993
    1994 lpi->solmethod = 'b';
    1995
    1996 /* enable or disable cross over */
    1997 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_CROSSOVER, crossover == TRUE ? -1 : 0) );
    1998
    1999 retval = lpiSolve(lpi, "b");
    2000 lpi->solisbasic = crossover;
    2001
    2002 return retval;
    2003}
    2004
    2005/** start strong branching - call before any strong branching */
    2007 SCIP_LPI* lpi /**< LP interface structure */
    2008 )
    2009{ /*lint --e{715}*/
    2010 assert(lpi != NULL);
    2011 assert(lpi->xprslp != NULL);
    2012
    2013 /* currently do nothing */
    2014 return SCIP_OKAY;
    2015}
    2016
    2017/** end strong branching - call after any strong branching */
    2019 SCIP_LPI* lpi /**< LP interface structure */
    2020 )
    2021{ /*lint --e{715}*/
    2022 assert(lpi != NULL);
    2023 assert(lpi->xprslp != NULL);
    2024
    2025 /* currently do nothing */
    2026 return SCIP_OKAY;
    2027}
    2028
    2029/** performs strong branching iterations on one candidate */
    2030static
    2032 SCIP_LPI* lpi, /**< LP interface structure */
    2033 int col, /**< column to apply strong branching on */
    2034 SCIP_Real psol, /**< current primal solution value of column */
    2035 int itlim, /**< iteration limit for strong branchings */
    2036 SCIP_Real* down, /**< stores dual bound after branching column down */
    2037 SCIP_Real* up, /**< stores dual bound after branching column up */
    2038 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
    2039 * otherwise, it can only be used as an estimate value */
    2040 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
    2041 * otherwise, it can only be used as an estimate value */
    2042 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
    2043 )
    2044{
    2045 SCIP_OBJSEN objsen;
    2046 double dbndval[2];
    2047 double dobjval[2];
    2048 char cbndtype[2];
    2049 int mbndind[2];
    2050 int mstatus[2];
    2051
    2052 assert(lpi != NULL);
    2053 assert(lpi->xprslp != NULL);
    2054 assert(down != NULL);
    2055 assert(up != NULL);
    2056 assert(downvalid != NULL);
    2057 assert(upvalid != NULL);
    2058
    2059 SCIPdebugMessage("calling Xpress strong branching on variable %d (%d iterations)\n", col, itlim);
    2060
    2061 /* results of Xpress are valid in any case */
    2062 *downvalid = TRUE;
    2063 *upvalid = TRUE;
    2064
    2065 SCIPdebugMessage(" -> strong branching on integral variable\n");
    2066
    2067 if( iter != NULL )
    2068 *iter = 0;
    2069
    2070 /* get objective sense of the current LP */
    2071 SCIP_CALL( SCIPlpiGetObjsen(lpi, &objsen) );
    2072
    2073 /* Set the branching bounds (down first, up second). */
    2074 mbndind[0] = col;
    2075 dbndval[0] = EPSCEIL(psol-1.0, 1e-06);
    2076 cbndtype[0] = 'U';
    2077 mbndind[1] = col;
    2078 dbndval[1] = EPSFLOOR(psol+1.0, 1e-06);
    2079 cbndtype[1] = 'L';
    2080
    2081 /* Apply strong branching to the two branches. */
    2082 CHECK_ZERO( lpi->messagehdlr, XPRSstrongbranch(lpi->xprslp, 2, mbndind, cbndtype, dbndval, itlim, dobjval, mstatus) );
    2083
    2084 /* Get the objective of the down branch. */
    2085 if( (mstatus[0] == XPRS_LP_INFEAS) || (mstatus[0] == XPRS_LP_CUTOFF_IN_DUAL) )
    2086 *down = objsen == SCIP_OBJSEN_MINIMIZE ? 1e+40 : -1e+40;
    2087 else if( (mstatus[0] == XPRS_LP_OPTIMAL) || (mstatus[0] == XPRS_LP_UNFINISHED) )
    2088 *down = dobjval[0];
    2089 else
    2090 {
    2091 /* Something weird happened. */
    2092 *downvalid = FALSE;
    2093 }
    2094
    2095 /* Get the objective of the up branch. */
    2096 if( (mstatus[1] == XPRS_LP_INFEAS) || (mstatus[1] == XPRS_LP_CUTOFF_IN_DUAL) )
    2097 *up = objsen == SCIP_OBJSEN_MINIMIZE ? 1e+40 : -1e+40;
    2098 else if( (mstatus[1] == XPRS_LP_OPTIMAL) || (mstatus[1] == XPRS_LP_UNFINISHED) )
    2099 *up = dobjval[1];
    2100 else
    2101 {
    2102 /* Something weird happened. */
    2103 *upvalid = FALSE;
    2104 }
    2105
    2106 /* When using the XPRSstrongbranch function we are unable to provide an iteration count */
    2107 if( iter != NULL )
    2108 *iter = -1;
    2109
    2110 return SCIP_OKAY;
    2111}
    2112
    2113/** performs strong branching iterations on given candidates */
    2114static
    2116 SCIP_LPI* lpi, /**< LP interface structure */
    2117 int* cols, /**< columns to apply strong branching on */
    2118 int ncols, /**< number of columns */
    2119 SCIP_Real* psols, /**< current primal solution values of columns (might be integral) */
    2120 int itlim, /**< iteration limit for strong branchings */
    2121 SCIP_Real* down, /**< stores dual bounds after branching columns down */
    2122 SCIP_Real* up, /**< stores dual bounds after branching columns up */
    2123 SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
    2124 * otherwise, they can only be used as an estimate values */
    2125 SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
    2126 * otherwise, they can only be used as an estimate values */
    2127 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
    2128 )
    2129{
    2130 double* dbndval;
    2131 double* dobjval;
    2132 char* cbndtype;
    2133 int* mbndind;
    2134 int* mstatus;
    2135 SCIP_OBJSEN objsen;
    2136 int nbranches;
    2137 int j;
    2138
    2139 assert( lpi != NULL );
    2140 assert( lpi->xprslp != NULL );
    2141 assert( cols != NULL );
    2142 assert( psols != NULL );
    2143 assert( down != NULL );
    2144 assert( up != NULL );
    2145 assert( downvalid != NULL );
    2146 assert( upvalid != NULL );
    2147
    2148 SCIPdebugMessage("calling Xpress strong branching on %d variables (%d iterations)\n", ncols, itlim);
    2149
    2150 if( iter != NULL )
    2151 *iter = 0;
    2152
    2153 /* compute the number of branches; for each column we have 2 branches */
    2154 nbranches = 2*ncols;
    2155
    2156 /* get objective sense of the current LP */
    2157 SCIP_CALL( SCIPlpiGetObjsen(lpi, &objsen) );
    2158
    2159 /* Set the branching bounds (down first, up second). */
    2160 SCIP_ALLOC( BMSallocMemoryArray(&mbndind, nbranches) );
    2161 SCIP_ALLOC( BMSallocMemoryArray(&dbndval, nbranches) );
    2162 SCIP_ALLOC( BMSallocMemoryArray(&cbndtype, nbranches) );
    2163 SCIP_ALLOC( BMSallocMemoryArray(&dobjval, nbranches) );
    2164 SCIP_ALLOC( BMSallocMemoryArray(&mstatus, nbranches) );
    2165
    2166 /* construct the bounds for the strong branches */
    2167 for( j = 0; j < ncols; ++j )
    2168 {
    2169 mbndind[2*j] = cols[j];
    2170 dbndval[2*j] = EPSCEIL(psols[j] - 1.0, 1e-06);
    2171 cbndtype[2*j] = 'U';
    2172
    2173 mbndind[2*j+1] = cols[j];
    2174 dbndval[2*j+1] = EPSFLOOR(psols[j] + 1.0, 1e-06);
    2175 cbndtype[2*j+1] = 'L';
    2176 }
    2177
    2178 /* apply strong branching to the 2*ncols branches. */
    2179 CHECK_ZERO( lpi->messagehdlr, XPRSstrongbranch(lpi->xprslp, nbranches, mbndind, cbndtype, dbndval, itlim, dobjval, mstatus) );
    2180
    2181 for( j = 0; j < ncols; ++j )
    2182 {
    2183 upvalid[j] = TRUE;
    2184 downvalid[j] = TRUE;
    2185
    2186 /* Get the objective of the down branch. */
    2187 if( (mstatus[2*j] == XPRS_LP_INFEAS) || (mstatus[2*j] == XPRS_LP_CUTOFF_IN_DUAL) )
    2188 down[j] = objsen == SCIP_OBJSEN_MINIMIZE ? 1e+40 : -1e+40;
    2189 else if( (mstatus[2*j] == XPRS_LP_OPTIMAL) || (mstatus[2*j] == XPRS_LP_UNFINISHED) )
    2190 down[j] = dobjval[2*j];
    2191 else
    2192 {
    2193 /* Something weird happened. */
    2194 downvalid[j] = FALSE;
    2195 }
    2196
    2197 /* Get the objective of the up branch. */
    2198 if( (mstatus[2*j+1] == XPRS_LP_INFEAS) || (mstatus[2*j+1] == XPRS_LP_CUTOFF_IN_DUAL) )
    2199 up[j] = objsen == SCIP_OBJSEN_MINIMIZE ? 1e+40 : -1e+40;
    2200 else if( (mstatus[2*j+1] == XPRS_LP_OPTIMAL) || (mstatus[2*j+1] == XPRS_LP_UNFINISHED) )
    2201 up[j] = dobjval[2*j+1];
    2202 else
    2203 {
    2204 /* Something weird happened. */
    2205 upvalid[j] = FALSE;
    2206 }
    2207 }
    2208
    2209 /* When using the XPRSstrongbranch function we are unable to provide
    2210 * an iteration count.
    2211 */
    2212 if( iter != NULL )
    2213 *iter = -1;
    2214
    2215 BMSfreeMemoryArray(&mstatus);
    2216 BMSfreeMemoryArray(&dobjval);
    2217 BMSfreeMemoryArray(&cbndtype);
    2218 BMSfreeMemoryArray(&dbndval);
    2219 BMSfreeMemoryArray(&mbndind);
    2220
    2221 return SCIP_OKAY;
    2222}
    2223
    2224/** performs strong branching iterations on one @b fractional candidate */
    2226 SCIP_LPI* lpi, /**< LP interface structure */
    2227 int col, /**< column to apply strong branching on */
    2228 SCIP_Real psol, /**< fractional current primal solution value of column */
    2229 int itlim, /**< iteration limit for strong branchings */
    2230 SCIP_Real* down, /**< stores dual bound after branching column down */
    2231 SCIP_Real* up, /**< stores dual bound after branching column up */
    2232 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
    2233 * otherwise, it can only be used as an estimate value */
    2234 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
    2235 * otherwise, it can only be used as an estimate value */
    2236 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
    2237 )
    2238{
    2239 /* pass call on to lpiStrongbranch() */
    2240 SCIP_CALL( lpiStrongbranch(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter) );
    2241
    2242 return SCIP_OKAY;
    2243}
    2244
    2245/** performs strong branching iterations on given @b fractional candidates */
    2247 SCIP_LPI* lpi, /**< LP interface structure */
    2248 int* cols, /**< columns to apply strong branching on */
    2249 int ncols, /**< number of columns */
    2250 SCIP_Real* psols, /**< fractional current primal solution values of columns */
    2251 int itlim, /**< iteration limit for strong branchings */
    2252 SCIP_Real* down, /**< stores dual bounds after branching columns down */
    2253 SCIP_Real* up, /**< stores dual bounds after branching columns up */
    2254 SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
    2255 * otherwise, they can only be used as an estimate values */
    2256 SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
    2257 * otherwise, they can only be used as an estimate values */
    2258 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
    2259 )
    2260{
    2261 /* pass call on to lpiStrongbranches() */
    2262 SCIP_CALL( lpiStrongbranches(lpi, cols, ncols, psols, itlim, down, up, downvalid, upvalid, iter) );
    2263
    2264 return SCIP_OKAY;
    2265}
    2266
    2267/** performs strong branching iterations on one candidate with @b integral value */
    2269 SCIP_LPI* lpi, /**< LP interface structure */
    2270 int col, /**< column to apply strong branching on */
    2271 SCIP_Real psol, /**< current integral primal solution value of column */
    2272 int itlim, /**< iteration limit for strong branchings */
    2273 SCIP_Real* down, /**< stores dual bound after branching column down */
    2274 SCIP_Real* up, /**< stores dual bound after branching column up */
    2275 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
    2276 * otherwise, it can only be used as an estimate value */
    2277 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
    2278 * otherwise, it can only be used as an estimate value */
    2279 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
    2280 )
    2281{
    2282 /* pass call on to lpiStrongbranch() */
    2283 SCIP_CALL( lpiStrongbranch(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter) );
    2284
    2285 return SCIP_OKAY;
    2286}
    2287
    2288/** performs strong branching iterations on given candidates with @b integral values */
    2290 SCIP_LPI* lpi, /**< LP interface structure */
    2291 int* cols, /**< columns to apply strong branching on */
    2292 int ncols, /**< number of columns */
    2293 SCIP_Real* psols, /**< current integral primal solution values of columns */
    2294 int itlim, /**< iteration limit for strong branchings */
    2295 SCIP_Real* down, /**< stores dual bounds after branching columns down */
    2296 SCIP_Real* up, /**< stores dual bounds after branching columns up */
    2297 SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
    2298 * otherwise, they can only be used as an estimate values */
    2299 SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
    2300 * otherwise, they can only be used as an estimate values */
    2301 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
    2302 )
    2303{
    2304 /* pass call on to lpiStrongbranches() */
    2305 SCIP_CALL( lpiStrongbranches(lpi, cols, ncols, psols, itlim, down, up, downvalid, upvalid, iter) );
    2306
    2307 return SCIP_OKAY;
    2308}
    2309
    2310/**@} */
    2311
    2312
    2313/**@name Solution Information Methods
    2314 *
    2315 * @{
    2316 */
    2317
    2318/** returns whether a solve method was called after the last modification of the LP */
    2320 SCIP_LPI* lpi /**< LP interface structure */
    2321 )
    2322{
    2323 assert(lpi != NULL);
    2324
    2325 return (lpi->solstat != -1);
    2326}
    2327
    2328/** gets information about primal and dual feasibility of the current LP solution
    2329 *
    2330 * The feasibility information is with respect to the last solving call and it is only relevant if SCIPlpiWasSolved()
    2331 * returns true. If the LP is changed, this information might be invalidated.
    2332 *
    2333 * Note that @a primalfeasible and @a dualfeasible should only return true if the solver has proved the respective LP to
    2334 * be feasible. Thus, the return values should be equal to the values of SCIPlpiIsPrimalFeasible() and
    2335 * SCIPlpiIsDualFeasible(), respectively. Note that if feasibility cannot be proved, they should return false (even if
    2336 * the problem might actually be feasible).
    2337 */
    2339 SCIP_LPI* lpi, /**< LP interface structure */
    2340 SCIP_Bool* primalfeasible, /**< pointer to store primal feasibility status */
    2341 SCIP_Bool* dualfeasible /**< pointer to store dual feasibility status */
    2342 )
    2343{
    2344 assert(lpi != NULL);
    2345 assert(lpi->xprslp != NULL);
    2346 assert(primalfeasible != NULL);
    2347 assert(dualfeasible != NULL);
    2348
    2349 SCIPdebugMessage("getting solution feasibility\n");
    2350
    2351 *primalfeasible = SCIPlpiIsPrimalFeasible(lpi);
    2352 *dualfeasible = SCIPlpiIsDualFeasible(lpi);
    2353
    2354 return SCIP_OKAY;
    2355}
    2356
    2357/** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point);
    2358 * this does not necessarily mean, that the solver knows and can return the primal ray
    2359 */
    2361 SCIP_LPI* lpi /**< LP interface structure */
    2362 )
    2363{
    2364 assert(lpi != NULL);
    2365 assert(lpi->xprslp != NULL);
    2366 assert(lpi->solstat >= 0);
    2367
    2368 return (lpi->solstat == XPRS_LP_UNBOUNDED);
    2369}
    2370
    2371/** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point),
    2372 * and the solver knows and can return the primal ray
    2373 */
    2375 SCIP_LPI* lpi /**< LP interface structure */
    2376 )
    2377{
    2378 int hasRay;
    2379
    2380 assert(lpi != NULL);
    2381 assert(lpi->xprslp != NULL);
    2382 assert(lpi->solstat >= 0);
    2383
    2384 /* check if the LP solution status is unbounded and that primal was solving the LP */
    2385 if (lpi->solstat != XPRS_LP_UNBOUNDED || lpi->solmethod != 'p')
    2386 return FALSE;
    2387
    2388 /* check if we can construct a primal ray */
    2389 ABORT_ZERO( lpi->messagehdlr, FALSE, XPRSgetprimalray(lpi->xprslp, NULL, &hasRay) );
    2390
    2391 return (SCIP_Bool)hasRay;
    2392}
    2393
    2394/** returns TRUE iff LP is proven to be primal feasible and unbounded */
    2396 SCIP_LPI* lpi /**< LP interface structure */
    2397 )
    2398{
    2399 assert(lpi != NULL);
    2400 assert(lpi->xprslp != NULL);
    2401 assert(lpi->solstat >= 0);
    2402
    2403 SCIPdebugMessage("checking for primal unboundedness\n");
    2404
    2405 /* If the solution status of Xpress is XPRS_LP_UNBOUNDED, it only means, there is an unbounded ray,
    2406 * but not necessarily a feasible primal solution. If problem is declared LP_UNBOUNDED by dual,
    2407 * we have no way to decide primal feasibility.
    2408 */
    2409
    2410 return lpi->solstat == XPRS_LP_UNBOUNDED && lpi->solmethod == 'p';
    2411}
    2412
    2413/** returns TRUE iff LP is proven to be primal infeasible */
    2415 SCIP_LPI* lpi /**< LP interface structure */
    2416 )
    2417{
    2418 assert(lpi != NULL);
    2419 assert(lpi->xprslp != NULL);
    2420 assert(lpi->solstat >= 0);
    2421
    2422 SCIPdebugMessage("checking for primal infeasibility\n");
    2423
    2424 return (lpi->solstat == XPRS_LP_INFEAS);
    2425}
    2426
    2427/** returns TRUE iff LP is proven to be primal feasible */
    2429 SCIP_LPI* lpi /**< LP interface structure */
    2430 )
    2431{
    2432 int nInfeasible;
    2433 int nIter;
    2434
    2435 assert(lpi != NULL);
    2436 assert(lpi->xprslp != NULL);
    2437 assert(lpi->solstat >= 0);
    2438
    2439 SCIPdebugMessage("checking for primal feasibility\n");
    2440
    2441 /* check if problem is solved to optimality */
    2442 if (lpi->solstat == XPRS_LP_OPTIMAL || lpi->solstat == XPRS_LP_OPTIMAL_SCALEDINFEAS)
    2443 return TRUE;
    2444
    2445 /* check if problem is unbounded (found by primal) */
    2446 if (lpi->solstat == XPRS_LP_UNBOUNDED && lpi->solmethod == 'p')
    2447 return TRUE;
    2448
    2449 /* get number of primal infeasibilities and number of simplex iterations */
    2450 ABORT_ZERO( lpi->messagehdlr, FALSE, XPRSgetintattrib(lpi->xprslp, XPRS_PRIMALINFEAS, &nInfeasible) );
    2451 ABORT_ZERO( lpi->messagehdlr, FALSE, XPRSgetintattrib(lpi->xprslp, XPRS_SIMPLEXITER, &nIter) );
    2452
    2453 /* check if the number of primal infeasibilities is zero
    2454 * We need to make sure that the LP was indeed solved by primal, otherwise infeasibility might have been found
    2455 * in setup (e.g. if conflicting bounds x >= 1, x <= 0 are present),
    2456 */
    2457 if (nInfeasible == 0 && nIter > 0 && lpi->solmethod == 'p')
    2458 return TRUE;
    2459
    2460 return FALSE;
    2461}
    2462
    2463/** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point);
    2464 * this does not necessarily mean, that the solver knows and can return the dual ray
    2465 */
    2467 SCIP_LPI* lpi /**< LP interface structure */
    2468 )
    2469{
    2470 assert(lpi != NULL);
    2471 assert(lpi->xprslp != NULL);
    2472 assert(lpi->solstat >= 0);
    2473
    2474 return (lpi->solstat == XPRS_LP_INFEAS);
    2475}
    2476
    2477/** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point),
    2478 * and the solver knows and can return the dual ray
    2479 */
    2481 SCIP_LPI* lpi /**< LP interface structure */
    2482 )
    2483{
    2484 int hasRay;
    2485
    2486 assert(lpi != NULL);
    2487 assert(lpi->xprslp != NULL);
    2488 assert(lpi->solstat >= 0);
    2489
    2490 ABORT_ZERO( lpi->messagehdlr, FALSE, XPRSgetdualray(lpi->xprslp, NULL, &hasRay) );
    2491
    2492 return (SCIP_Bool) hasRay;
    2493}
    2494
    2495/** returns TRUE iff LP is proven to be dual unbounded */
    2497 SCIP_LPI* lpi /**< LP interface structure */
    2498 )
    2499{
    2500 assert(lpi != NULL);
    2501 assert(lpi->xprslp != NULL);
    2502 assert(lpi->solstat >= 0);
    2503
    2504 SCIPdebugMessage("checking for dual unboundedness\n");
    2505
    2506 return ((lpi->solstat == XPRS_LP_INFEAS) && (lpi->solmethod == 'd'));
    2507}
    2508
    2509/** returns TRUE iff LP is proven to be dual infeasible */
    2511 SCIP_LPI* lpi /**< LP interface structure */
    2512 )
    2513{
    2514 assert(lpi != NULL);
    2515 assert(lpi->xprslp != NULL);
    2516 assert(lpi->solstat >= 0);
    2517
    2518 SCIPdebugMessage("checking for dual infeasibility\n");
    2519
    2520 return (lpi->solstat == XPRS_LP_UNBOUNDED);
    2521}
    2522
    2523/** returns TRUE iff LP is proven to be dual feasible */
    2525 SCIP_LPI* lpi /**< LP interface structure */
    2526 )
    2527{
    2528 int nInfeasible;
    2529 int nIter;
    2530
    2531 assert(lpi != NULL);
    2532 assert(lpi->xprslp != NULL);
    2533 assert(lpi->solstat >= 0);
    2534
    2535 SCIPdebugMessage("checking for dual feasibility\n");
    2536
    2537 /* check if problem solved to optimality */
    2538 if (lpi->solstat == XPRS_LP_OPTIMAL || lpi->solstat == XPRS_LP_OPTIMAL_SCALEDINFEAS)
    2539 return TRUE;
    2540
    2541 /* check if problem infeasibility detected by dual */
    2542 if (lpi->solstat == XPRS_LP_INFEAS && lpi->solmethod == 'd')
    2543 return TRUE;
    2544
    2545 /* get number of dual infeasibilities and number of simplex iterations */
    2546 ABORT_ZERO( lpi->messagehdlr, FALSE, XPRSgetintattrib(lpi->xprslp, XPRS_DUALINFEAS, &nInfeasible) );
    2547 ABORT_ZERO( lpi->messagehdlr, FALSE, XPRSgetintattrib(lpi->xprslp, XPRS_SIMPLEXITER, &nIter) );
    2548
    2549 /* check if the number of dual infeasibilities is zero
    2550 * We need to make sure that the LP was indeed solved by primal, otherwise infeasibility might have been found
    2551 * in setup (e.g. if conflicting bounds x >= 1, x <= 0 are present),
    2552 */
    2553 if (nInfeasible == 0 && nIter > 0 && lpi->solmethod == 'd')
    2554 return TRUE;
    2555
    2556 return FALSE;
    2557}
    2558
    2559/** returns TRUE iff LP was solved to optimality */
    2561 SCIP_LPI* lpi /**< LP interface structure */
    2562 )
    2563{
    2564 assert(lpi != NULL);
    2565 assert(lpi->xprslp != NULL);
    2566 assert(lpi->solstat >= 0);
    2567
    2568 return (lpi->solstat == XPRS_LP_OPTIMAL) || (lpi->solstat == XPRS_LP_OPTIMAL_SCALEDINFEAS);
    2569}
    2570
    2571/** returns TRUE iff current LP solution is stable
    2572 *
    2573 * This function should return true if the solution is reliable, i.e., feasible and optimal (or proven
    2574 * infeasible/unbounded) with respect to the original problem. The optimality status might be with respect to a scaled
    2575 * version of the problem, but the solution might not be feasible to the unscaled original problem; in this case,
    2576 * SCIPlpiIsStable() should return false.
    2577 */
    2579 SCIP_LPI* lpi /**< LP interface structure */
    2580 )
    2581{
    2582 assert(lpi != NULL);
    2583 assert(lpi->xprslp != NULL);
    2584 assert(lpi->solstat >= 0);
    2585
    2586 SCIPdebugMessage("checking for stability: Xpress solstat = %d\n", lpi->solstat);
    2587
    2588#ifdef SCIP_DISABLED_CODE
    2589 /* The following workaround is not needed anymore for SCIP, since it tries to heuristically construct a feasible
    2590 * solution or automatically resolves the problem if the status is "unbounded"; see SCIPlpGetUnboundedSol().
    2591 */
    2592
    2593 /* If the solution status of Xpress is XPRS_LP_UNBOUNDED, it only means, there is an unbounded ray,
    2594 * but not necessarily a feasible primal solution. If primalfeasible == FALSE, we interpret this
    2595 * result as instability, s.t. the problem is resolved from scratch
    2596 */
    2597 if( lpi->solstat == XPRS_LP_UNBOUNDED )
    2598 {
    2599 int retcode;
    2600 int pinfeas;
    2601
    2602 retcode = XPRSgetintattrib(lpi->xprslp, XPRS_PRIMALINFEAS, &pinfeas);
    2603
    2604 if( retcode != 0 || pinfeas )
    2605 return FALSE;
    2606 }
    2607#endif
    2608
    2610 {
    2611 /* presolved problem was solved to optimality but infeasibilities were introduced by postsolve */
    2612 return FALSE;
    2613 }
    2614
    2615 return TRUE;
    2616}
    2617
    2618/** returns TRUE iff the objective limit was reached */
    2620 SCIP_LPI* lpi /**< LP interface structure */
    2621 )
    2622{
    2623 assert(lpi != NULL);
    2624 assert(lpi->xprslp != NULL);
    2625 assert(lpi->solstat >= 0);
    2626
    2627 return (lpi->solstat == XPRS_LP_CUTOFF || lpi->solstat == XPRS_LP_CUTOFF_IN_DUAL);
    2628}
    2629
    2630/** returns TRUE iff the iteration limit was reached */
    2632 SCIP_LPI* lpi /**< LP interface structure */
    2633 )
    2634{
    2635 int lpiter;
    2636 int lpiterlimit;
    2637
    2638 assert(lpi != NULL);
    2639 assert(lpi->xprslp != NULL);
    2640 assert(lpi->solstat >= 0);
    2641
    2642 ABORT_ZERO( lpi->messagehdlr, TRUE, XPRSgetintattrib(lpi->xprslp, XPRS_SIMPLEXITER, &lpiter) );
    2643 ABORT_ZERO( lpi->messagehdlr, TRUE, XPRSgetintcontrol(lpi->xprslp, XPRS_LPITERLIMIT, &lpiterlimit) );
    2644
    2645 if( (lpi->solstat == XPRS_LP_UNFINISHED) && (lpiter >= lpiterlimit) )
    2646 return TRUE;
    2647 else
    2648 return FALSE;
    2649}
    2650
    2651/** returns TRUE iff the time limit was reached */
    2653 SCIP_LPI* lpi /**< LP interface structure */
    2654 )
    2655{
    2656 int lpiter;
    2657 int lpiterlimit;
    2658
    2659 assert(lpi != NULL);
    2660 assert(lpi->xprslp != NULL);
    2661 assert(lpi->solstat >= 0);
    2662
    2663 ABORT_ZERO( lpi->messagehdlr, TRUE, XPRSgetintattrib(lpi->xprslp, XPRS_SIMPLEXITER, &lpiter) );
    2664 ABORT_ZERO( lpi->messagehdlr, TRUE, XPRSgetintcontrol(lpi->xprslp, XPRS_LPITERLIMIT, &lpiterlimit) );
    2665
    2666 if( (lpi->solstat == XPRS_LP_UNFINISHED) && (lpiter < lpiterlimit) )
    2667 return TRUE;
    2668 else
    2669 return FALSE;
    2670}
    2671
    2672/** returns the internal solution status of the solver */
    2674 SCIP_LPI* lpi /**< LP interface structure */
    2675 )
    2676{
    2677 assert(lpi != NULL);
    2678 assert(lpi->xprslp != NULL);
    2679
    2680 return lpi->solstat;
    2681}
    2682
    2683/** tries to reset the internal status of the LP solver in order to ignore an instability of the last solving call */
    2685 SCIP_LPI* lpi, /**< LP interface structure */
    2686 SCIP_Bool* success /**< pointer to store, whether the instability could be ignored */
    2687 )
    2688{
    2689 assert(lpi != NULL);
    2690 assert(lpi->xprslp != NULL);
    2691 assert(success != NULL);
    2692
    2693 /* Nothing to do here for Xpress. */
    2694 *success = TRUE;
    2695
    2696 return SCIP_OKAY;
    2697}
    2698
    2699/** gets objective value of solution */
    2701 SCIP_LPI* lpi, /**< LP interface structure */
    2702 SCIP_Real* objval /**< stores the objective value */
    2703 )
    2704{
    2705 assert(lpi != NULL);
    2706 assert(lpi->xprslp != NULL);
    2707 assert(objval != NULL);
    2708
    2709 SCIPdebugMessage("getting solution's objective value\n");
    2710
    2711 CHECK_ZERO( lpi->messagehdlr, XPRSgetdblattrib(lpi->xprslp, XPRS_LPOBJVAL, objval) );
    2712
    2713 return SCIP_OKAY;
    2714}
    2715
    2716/** gets primal and dual solution vectors for feasible LPs
    2717 *
    2718 * Before calling this function, the caller must ensure that the LP has been solved to optimality, i.e., that
    2719 * SCIPlpiIsOptimal() returns true.
    2720 */
    2722 SCIP_LPI* lpi, /**< LP interface structure */
    2723 SCIP_Real* objval, /**< stores the objective value, may be NULL if not needed */
    2724 SCIP_Real* primsol, /**< primal solution vector, may be NULL if not needed */
    2725 SCIP_Real* dualsol, /**< dual solution vector, may be NULL if not needed */
    2726 SCIP_Real* activity, /**< row activity vector, may be NULL if not needed */
    2727 SCIP_Real* redcost /**< reduced cost vector, may be NULL if not needed */
    2728 )
    2729{
    2730 assert(lpi != NULL);
    2731 assert(lpi->xprslp != NULL);
    2732 assert(lpi->solstat >= 0);
    2733
    2734 SCIPdebugMessage("getting solution\n");
    2735
    2736#if XPVERSION <= 40
    2737 CHECK_ZERO( lpi->messagehdlr, XPRSgetsol(lpi->xprslp, primsol, activity, dualsol, redcost) );
    2738#else
    2739 CHECK_ZERO( lpi->messagehdlr, XPRSgetlpsol(lpi->xprslp, primsol, activity, dualsol, redcost) );
    2740#endif
    2741
    2742 if( objval != NULL )
    2743 {
    2744 CHECK_ZERO( lpi->messagehdlr, XPRSgetdblattrib(lpi->xprslp, XPRS_LPOBJVAL, objval) );
    2745 }
    2746
    2747 if( activity != NULL )
    2748 {
    2749 /* Convert the slack values into activity values. */
    2750 int nrows;
    2751 int r;
    2752
    2753 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
    2754
    2755 SCIP_CALL( ensureSidechgMem(lpi, nrows) );
    2756
    2757 CHECK_ZERO( lpi->messagehdlr, XPRSgetrhs(lpi->xprslp, lpi->rhsarray, 0, nrows-1) );
    2758
    2759 for( r = 0; r < nrows; r++ )
    2760 activity[r] = lpi->rhsarray[r] - activity[r];
    2761 }
    2762
    2763 return SCIP_OKAY;
    2764}
    2765
    2766/** gets primal ray for unbounded LPs */
    2768 SCIP_LPI* lpi, /**< LP interface structure */
    2769 SCIP_Real* ray /**< primal ray */
    2770 )
    2771{
    2772 int hasRay;
    2773
    2774 assert(lpi != NULL);
    2775 assert(lpi->xprslp != NULL);
    2776 assert(ray != NULL);
    2777 assert(lpi->solstat >= 0);
    2778
    2779 CHECK_ZERO( lpi->messagehdlr, XPRSgetprimalray(lpi->xprslp, ray, &hasRay) );
    2780
    2781 if( !hasRay )
    2782 return SCIP_LPERROR;
    2783
    2784 return SCIP_OKAY;
    2785}
    2786
    2787/** gets dual Farkas proof for infeasibility */
    2789 SCIP_LPI* lpi, /**< LP interface structure */
    2790 SCIP_Real* dualfarkas /**< dual Farkas row multipliers */
    2791 )
    2792{
    2793 int hasRay;
    2794
    2795 assert(lpi != NULL);
    2796 assert(lpi->xprslp != NULL);
    2797 assert(lpi->solstat >= 0);
    2798 assert(dualfarkas != NULL);
    2799
    2800 /**@note The Farkas proof might be numerically questionable which is indicated by "hasRay" use SCIPlpiHasDualRay() to
    2801 * check that!
    2802 */
    2803 CHECK_ZERO( lpi->messagehdlr, XPRSgetdualray(lpi->xprslp, dualfarkas, &hasRay) );
    2804
    2805 return SCIP_OKAY;
    2806}
    2807
    2808/** gets the number of LP iterations of the last solve call */
    2810 SCIP_LPI* lpi, /**< LP interface structure */
    2811 int* iterations /**< pointer to store the number of iterations of the last solve call */
    2812 )
    2813{
    2814 assert(lpi != NULL);
    2815 assert(lpi->xprslp != NULL);
    2816 assert(iterations != NULL);
    2817
    2818 *iterations = lpi->iterations;
    2819
    2820 return SCIP_OKAY;
    2821}
    2822
    2823/** gets information about the quality of an LP solution
    2824 *
    2825 * Such information is usually only available, if also a (maybe not optimal) solution is available.
    2826 * The LPI should return SCIP_INVALID for @p quality, if the requested quantity is not available.
    2827 */
    2829 SCIP_LPI* lpi, /**< LP interface structure */
    2830 SCIP_LPSOLQUALITY qualityindicator, /**< indicates which quality should be returned */
    2831 SCIP_Real* quality /**< pointer to store quality number */
    2832 )
    2833{ /*lint --e{715}*/
    2834 assert(lpi != NULL);
    2835 assert(quality != NULL);
    2836 SCIP_UNUSED(qualityindicator);
    2837
    2838 *quality = SCIP_INVALID;
    2839
    2840 return SCIP_OKAY;
    2841}
    2842
    2843/**@} */
    2844
    2845
    2846/**@name LP Basis Methods
    2847 *
    2848 * @{
    2849 */
    2850
    2851/** gets current basis status for columns and rows; arrays must be large enough to store the basis status */
    2853 SCIP_LPI* lpi, /**< LP interface structure */
    2854 int* cstat, /**< array to store column basis status, or NULL */
    2855 int* rstat /**< array to store row basis status, or NULL (the status is need for the row and not for the slack column) */
    2856 )
    2857{
    2858 int nrows;
    2859 int r;
    2860
    2861 assert(lpi != NULL);
    2862 assert(lpi->xprslp != NULL);
    2863
    2864 /*lint --e{506}*/
    2865 assert((int) SCIP_BASESTAT_LOWER == 0);
    2866 assert((int) SCIP_BASESTAT_BASIC == 1);
    2867 assert((int) SCIP_BASESTAT_UPPER == 2);
    2868
    2869 SCIPdebugMessage("saving Xpress basis into %p/%p\n", (void*)rstat, (void*)cstat);
    2870
    2871 /* get the basis status */
    2872 CHECK_ZERO( lpi->messagehdlr, XPRSgetbasis(lpi->xprslp, rstat, cstat) );
    2873
    2874 /* get the number of rows */
    2875 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
    2876
    2877 /* XPRSgetbasis collects the basis status for the column and the slack column, since SCIP request the basis for
    2878 * columns and rows we need to convert slack column status to row status
    2879 */
    2880 for( r = 0; r < nrows; ++r )
    2881 {
    2882 if (rstat[r] == (int) SCIP_BASESTAT_LOWER)
    2883 rstat[r] = (int) SCIP_BASESTAT_UPPER;
    2884 else if (rstat[r] == (int) SCIP_BASESTAT_UPPER)
    2885 rstat[r] = (int) SCIP_BASESTAT_LOWER;
    2886 }
    2887
    2888 return SCIP_OKAY;
    2889}
    2890
    2891/** sets current basis status for columns and rows */
    2893 SCIP_LPI* lpi, /**< LP interface structure */
    2894 const int* cstat, /**< array with column basis status */
    2895 const int* rstat /**< array with row basis status */
    2896 )
    2897{
    2898 int* slackstats;
    2899 int ncols;
    2900 int nrows;
    2901 int r;
    2902
    2903 assert(lpi != NULL);
    2904 assert(lpi->xprslp != NULL);
    2905
    2906 /* get the number of rows/columns */
    2907 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
    2908 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    2909
    2910 assert(cstat != NULL || ncols == 0);
    2911 assert(rstat != NULL || nrows == 0);
    2912
    2913 /*lint --e{506}*/
    2914 assert((int) SCIP_BASESTAT_LOWER == 0);
    2915 assert((int) SCIP_BASESTAT_BASIC == 1);
    2916 assert((int) SCIP_BASESTAT_UPPER == 2);
    2917
    2918 SCIPdebugMessage("loading basis %p/%p into Xpress\n", (void*)rstat, (void*)cstat);
    2919
    2920 invalidateSolution(lpi);
    2921
    2922 SCIP_ALLOC( BMSallocMemoryArray(&slackstats, nrows) );
    2923
    2924 /* XPRSloadbasis expects the basis status for the column and the slack column, since SCIP has the basis status for
    2925 * columns and rows we need to convert row status to slack column status
    2926 */
    2927 for( r = 0; r < nrows; ++r )
    2928 {
    2929 if (rstat[r] == (int) SCIP_BASESTAT_LOWER) /*lint !e613*/
    2930 slackstats[r] = (int) SCIP_BASESTAT_UPPER;
    2931 else if (rstat[r] == (int) SCIP_BASESTAT_UPPER) /*lint !e613*/
    2932 slackstats[r] = (int) SCIP_BASESTAT_LOWER;
    2933 else
    2934 slackstats[r] = rstat[r]; /*lint !e613*/
    2935 }
    2936
    2937 /* load basis information into Xpress
    2938 *
    2939 * @note Xpress expects the row status w.r.t. slack columns!
    2940 */
    2941 CHECK_ZERO( lpi->messagehdlr, XPRSloadbasis(lpi->xprslp, slackstats, cstat) );
    2942
    2943 BMSfreeMemoryArray(&slackstats);
    2944
    2945 lpi->clearstate = FALSE;
    2946
    2947 return SCIP_OKAY;
    2948}
    2949
    2950/** returns the indices of the basic columns and rows; basic column n gives value n, basic row m gives value -1-m */
    2952 SCIP_LPI* lpi, /**< LP interface structure */
    2953 int* bind /**< pointer to store basis indices ready to keep number of rows entries */
    2954 )
    2955{
    2956 int irspace;
    2957 int nrows;
    2958 int r;
    2959
    2960 /* In the basis methods we assume that xprs basis flags coincide with scip, so assert it */
    2961 /*lint --e{506}*/
    2962 assert((int) SCIP_BASESTAT_LOWER == 0);
    2963 assert((int) SCIP_BASESTAT_BASIC == 1);
    2964 assert((int) SCIP_BASESTAT_UPPER == 2);
    2965 assert((int) SCIP_BASESTAT_ZERO == 3);
    2966
    2967 assert(lpi != NULL);
    2968 assert(lpi->xprslp != NULL);
    2969 assert(bind != NULL);
    2970
    2971 SCIPdebugMessage("getting basis information\n");
    2972
    2973 CHECK_ZERO( lpi->messagehdlr, XPRSgetpivotorder(lpi->xprslp, bind) );
    2974
    2975 /* Reindex variables to match those of SCIP. */
    2976 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
    2977 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_SPAREROWS, &irspace) );
    2978 irspace += nrows;
    2979
    2980 for( r = 0; r < nrows; r++ )
    2981 {
    2982 if( bind[r] < nrows )
    2983 bind[r] = -bind[r]-1;
    2984 else
    2985 {
    2986 assert(bind[r] >= irspace);
    2987 bind[r] = bind[r] - irspace;
    2988 }
    2989 }
    2990
    2991 return SCIP_OKAY;
    2992}
    2993
    2994/** get row of inverse basis matrix B^-1
    2995 *
    2996 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
    2997 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
    2998 * see also the explanation in lpi.h.
    2999 *
    3000 * @todo check that the result is in terms of the LP interface definition
    3001 */
    3003 SCIP_LPI* lpi, /**< LP interface structure */
    3004 int row, /**< row number */
    3005 SCIP_Real* coef, /**< pointer to store the coefficients of the row */
    3006 int* inds, /**< array to store the non-zero indices, or NULL */
    3007 int* ninds /**< pointer to store the number of non-zero indices, or NULL
    3008 * (-1: if we do not store sparsity information) */
    3009 )
    3010{ /*lint --e{715}*/
    3011 int nrows;
    3012
    3013 assert(lpi != NULL);
    3014 assert(lpi->xprslp != NULL);
    3015 assert(coef != NULL);
    3016 SCIP_UNUSED(inds);
    3017
    3018 SCIPdebugMessage("getting binv-row %d\n", row);
    3019
    3020 /* can only return dense result */
    3021 if ( ninds != NULL )
    3022 *ninds = -1;
    3023
    3024 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
    3025 BMSclearMemoryArray(coef, nrows);
    3026 coef[row] = 1.0;
    3027 CHECK_ZERO( lpi->messagehdlr, XPRSbtran(lpi->xprslp, coef) );
    3028
    3029 return SCIP_OKAY;
    3030}
    3031
    3032/** get column of inverse basis matrix B^-1
    3033 *
    3034 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
    3035 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
    3036 * see also the explanation in lpi.h.
    3037 *
    3038 * @todo check that the result is in terms of the LP interface definition
    3039 */
    3041 SCIP_LPI* lpi, /**< LP interface structure */
    3042 int c, /**< column number of B^-1; this is NOT the number of the column in the LP;
    3043 * you have to call SCIPlpiGetBasisInd() to get the array which links the
    3044 * B^-1 column numbers to the row and column numbers of the LP!
    3045 * c must be between 0 and nrows-1, since the basis has the size
    3046 * nrows * nrows */
    3047 SCIP_Real* coef, /**< pointer to store the coefficients of the column */
    3048 int* inds, /**< array to store the non-zero indices, or NULL */
    3049 int* ninds /**< pointer to store the number of non-zero indices, or NULL
    3050 * (-1: if we do not store sparsity information) */
    3051 )
    3052{ /*lint --e{715}*/
    3053 int nrows;
    3054
    3055 assert(lpi != NULL);
    3056 assert(lpi->xprslp != NULL);
    3057 assert(coef != NULL);
    3058 SCIP_UNUSED(inds);
    3059
    3060 SCIPdebugMessage("getting binv-col %d\n", c);
    3061
    3062 /* can only return dense result */
    3063 if ( ninds != NULL )
    3064 *ninds = -1;
    3065
    3066 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
    3067 BMSclearMemoryArray(coef, nrows);
    3068 coef[c] = 1.0;
    3069 CHECK_ZERO( lpi->messagehdlr, XPRSftran(lpi->xprslp, coef) );
    3070
    3071 return SCIP_OKAY;
    3072}
    3073
    3074/** get row of inverse basis matrix times constraint matrix B^-1 * A
    3075 *
    3076 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
    3077 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
    3078 * see also the explanation in lpi.h.
    3079 *
    3080 * @todo check that the result is in terms of the LP interface definition
    3081 */
    3083 SCIP_LPI* lpi, /**< LP interface structure */
    3084 int r, /**< row number */
    3085 const SCIP_Real* binvrow, /**< row in (A_B)^-1 from prior call to SCIPlpiGetBInvRow(), or NULL */
    3086 SCIP_Real* coef, /**< vector to return coefficients of the row */
    3087 int* inds, /**< array to store the non-zero indices, or NULL */
    3088 int* ninds /**< pointer to store the number of non-zero indices, or NULL
    3089 * (-1: if we do not store sparsity information) */
    3090 )
    3091{ /*lint --e{715}*/
    3092 SCIP_Real* binv;
    3093 SCIP_Real* buffer;
    3094 int ncols;
    3095 int nrows;
    3096 int nnonz;
    3097 int c;
    3098
    3099 assert(lpi != NULL);
    3100 assert(lpi->xprslp != NULL);
    3101 assert(coef != NULL);
    3102
    3103 SCIPdebugMessage("getting binva-row %d\n", r);
    3104
    3105 /* can only return dense result */
    3106 if ( ninds != NULL )
    3107 *ninds = -1;
    3108
    3109 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
    3110 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_COLS, &ncols) );
    3111
    3112 buffer = NULL;
    3113
    3114 /* get (or calculate) the row in B^-1 */
    3115 if( binvrow == NULL )
    3116 {
    3117 SCIP_ALLOC( BMSallocMemoryArray(&buffer, nrows) );
    3118 SCIP_CALL( SCIPlpiGetBInvRow(lpi, r, buffer, inds, ninds) );
    3119 binv = buffer;
    3120 }
    3121 else
    3122 binv = (double*) binvrow;
    3123
    3124 /* We need space to extract a single column. */
    3125 SCIP_CALL( ensureValMem(lpi, nrows) );
    3126
    3127 for( c = 0; c < ncols; c++ )
    3128 {
    3129 int i;
    3130
    3131 coef[c] = 0;
    3132
    3133 /* Extract the column. */
    3134 CHECK_ZERO( lpi->messagehdlr, XPRSgetcols(lpi->xprslp, NULL, lpi->indarray, lpi->valarray, nrows, &nnonz, c, c) );
    3135 assert(nnonz <= nrows);
    3136
    3137 /* Price out the column. */
    3138 for( i = 0; i < nnonz; i++ )
    3139 coef[c] += binv[lpi->indarray[i]] * lpi->valarray[i];
    3140 }
    3141
    3142 /* Free allocated memory. */
    3143 BMSfreeMemoryArrayNull(&buffer);
    3144
    3145 return SCIP_OKAY;
    3146}
    3147
    3148/** get column of inverse basis matrix times constraint matrix B^-1 * A
    3149 *
    3150 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
    3151 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
    3152 * see also the explanation in lpi.h.
    3153 *
    3154 * @todo check that the result is in terms of the LP interface definition
    3155 */
    3157 SCIP_LPI* lpi, /**< LP interface structure */
    3158 int c, /**< column number */
    3159 SCIP_Real* coef, /**< vector to return coefficients of the column */
    3160 int* inds, /**< array to store the non-zero indices, or NULL */
    3161 int* ninds /**< pointer to store the number of non-zero indices, or NULL
    3162 * (-1: if we do not store sparsity information) */
    3163 )
    3164{ /*lint --e{715}*/
    3165 int nrows;
    3166 int nnonz;
    3167 int i;
    3168
    3169 /* Ftran */
    3170
    3171 assert(lpi != NULL);
    3172 assert(lpi->xprslp != NULL);
    3173 assert(coef != NULL);
    3174 SCIP_UNUSED(inds);
    3175
    3176 SCIPdebugMessage("getting binv-col %d\n", c);
    3177
    3178 /* can only return dense result */
    3179 if ( ninds != NULL )
    3180 *ninds = -1;
    3181
    3182 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
    3183
    3184 /* We need space to extract the column. */
    3185 SCIP_CALL( ensureValMem(lpi, nrows) );
    3186
    3187 /* Get the column to transform. */
    3188 CHECK_ZERO( lpi->messagehdlr, XPRSgetcols(lpi->xprslp, NULL, lpi->indarray, lpi->valarray, nrows, &nnonz, c, c) );
    3189 assert(nnonz <= nrows);
    3190
    3191 /* Transform the column. */
    3192 BMSclearMemoryArray(coef, nrows);
    3193 for( i = 0; i < nnonz; i++ )
    3194 coef[lpi->indarray[i]] = lpi->valarray[i];
    3195
    3196 CHECK_ZERO( lpi->messagehdlr, XPRSftran(lpi->xprslp, coef) );
    3197
    3198 return SCIP_OKAY;
    3199}
    3200
    3201/**@} */
    3202
    3203
    3204/**@name LP State Methods
    3205 *
    3206 * @{
    3207 */
    3208
    3209/** stores LPi state (like basis information) into lpistate object */
    3211 SCIP_LPI* lpi, /**< LP interface structure */
    3212 BMS_BLKMEM* blkmem, /**< block memory */
    3213 SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
    3214 )
    3215{
    3216 int ncols;
    3217 int nrows;
    3218
    3219 assert(blkmem != NULL);
    3220 assert(lpi != NULL);
    3221 assert(lpi->xprslp != NULL);
    3222 assert(lpistate != NULL);
    3223
    3224 /* if there is no basis information available (e.g. after barrier without crossover), or no state can be saved; if
    3225 * SCIPlpiClearState() has been called, do not return the state
    3226 */
    3227 if( !lpi->solisbasic || lpi->clearstate )
    3228 {
    3229 *lpistate = NULL;
    3230 return SCIP_OKAY;
    3231 }
    3232
    3233 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
    3234 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_COLS, &ncols) );
    3235 assert(ncols >= 0);
    3236 assert(nrows >= 0);
    3237
    3238 /* allocate lpistate data */
    3239 SCIP_CALL( lpistateCreate(lpistate, blkmem, ncols, nrows) );
    3240
    3241 SCIPdebugMessage("storing Xpress LPI state in %p (%d cols, %d rows)\n", (void*)*lpistate, ncols, nrows);
    3242
    3243 /* allocate enough memory for storing uncompressed basis information */
    3244 SCIP_CALL( ensureCstatMem(lpi, ncols) );
    3245 SCIP_CALL( ensureRstatMem(lpi, nrows) );
    3246
    3247 /* get unpacked basis information from Xpress
    3248 *
    3249 * @note The row status is w.r.t. slack columns!
    3250 */
    3251 CHECK_ZERO( lpi->messagehdlr, XPRSgetbasis(lpi->xprslp, lpi->rstat, lpi->cstat) );
    3252
    3253 /* pack LPi state data */
    3254 (*lpistate)->ncols = ncols;
    3255 (*lpistate)->nrows = nrows;
    3256 lpistatePack(*lpistate, lpi->cstat, lpi->rstat);
    3257
    3258 return SCIP_OKAY;
    3259}
    3260
    3261/** loads LPi state (like basis information) into solver; note that the LP might have been extended with additional
    3262 * columns and rows since the state was stored with SCIPlpiGetState()
    3263 */
    3265 SCIP_LPI* lpi, /**< LP interface structure */
    3266 BMS_BLKMEM* blkmem, /**< block memory */
    3267 const SCIP_LPISTATE* lpistate /**< LPi state information (like basis information), or NULL */
    3268 )
    3269{
    3270 int nrows;
    3271 int ncols;
    3272 int i;
    3273
    3274 assert(blkmem != NULL);
    3275 assert(lpi != NULL);
    3276 assert(lpi->xprslp != NULL);
    3277
    3278 /* if there was no basis information available, the LPI state was not stored */
    3279 if( lpistate == NULL )
    3280 return SCIP_OKAY;
    3281
    3282 if( lpistate->ncols == 0 || lpistate->nrows == 0 )
    3283 return SCIP_OKAY;
    3284
    3285 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
    3286 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_COLS, &ncols) );
    3287
    3288 /* the dimension of the lpi state should not be larger than the current problem; it might be that columns and rows
    3289 * are added since the saving of the lpi state
    3290 */
    3291 assert(lpistate->ncols <= ncols);
    3292 assert(lpistate->nrows <= nrows);
    3293
    3294 SCIPdebugMessage("loading LPI state %p (%d cols, %d rows) into Xpress\n", (void*)lpistate, lpistate->ncols, lpistate->nrows);
    3295
    3296 /* allocate enough memory for storing uncompressed basis information */
    3297 SCIP_CALL( ensureCstatMem(lpi, ncols) );
    3298 SCIP_CALL( ensureRstatMem(lpi, nrows) );
    3299
    3300 /* unpack LPi state data
    3301 *
    3302 * @note The row status is w.r.t. slack column!
    3303 */
    3304 lpistateUnpack(lpistate, lpi->cstat, lpi->rstat);
    3305
    3306 /* extend the basis to the current LP beyond the previously existing columns */
    3307 for( i = lpistate->ncols; i < ncols; ++i )
    3308 {
    3309 SCIP_Real bnd;
    3310
    3311 CHECK_ZERO( lpi->messagehdlr, XPRSgetlb(lpi->xprslp, &bnd, i, i) );
    3312
    3313 if( SCIPlpiIsInfinity(lpi, REALABS(bnd)) )
    3314 {
    3315 /* if lower bound is +/- infinity -> try upper bound */
    3316 CHECK_ZERO( lpi->messagehdlr, XPRSgetub(lpi->xprslp, &bnd, i, i) );
    3317
    3318 if( SCIPlpiIsInfinity(lpi, REALABS(bnd)) )
    3319 lpi->cstat[i] = (int) SCIP_BASESTAT_ZERO; /* variable is free */
    3320 else
    3321 lpi->cstat[i] = (int) SCIP_BASESTAT_UPPER; /* use finite upper bound */
    3322 }
    3323 else
    3324 lpi->cstat[i] = (int) SCIP_BASESTAT_LOWER; /* use finite lower bound */
    3325 }
    3326 for( i = lpistate->nrows; i < nrows; ++i )
    3327 lpi->rstat[i] = (int) SCIP_BASESTAT_BASIC;
    3328
    3329 /* load basis information into Xpress
    3330 *
    3331 * @note Xpress expects the row status w.r.t. slack columns!
    3332 */
    3333 CHECK_ZERO( lpi->messagehdlr, XPRSloadbasis(lpi->xprslp, lpi->rstat, lpi->cstat) );
    3334
    3335 lpi->clearstate = FALSE;
    3336
    3337 return SCIP_OKAY;
    3338}
    3339
    3340/** clears current LPi state (like basis information) of the solver */
    3342 SCIP_LPI* lpi /**< LP interface structure */
    3343 )
    3344{
    3345 assert(lpi != NULL);
    3346
    3347 /* set KEEPBASIS to 0 for the next solve */
    3348 lpi->clearstate = TRUE;
    3349
    3350 return SCIP_OKAY;
    3351}
    3352
    3353/** frees LPi state information */
    3355 SCIP_LPI* lpi, /**< LP interface structure */
    3356 BMS_BLKMEM* blkmem, /**< block memory */
    3357 SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
    3358 )
    3359{
    3360 assert(lpi != NULL);
    3361 assert(lpistate != NULL);
    3362 assert(blkmem != NULL);
    3363
    3364 if( *lpistate != NULL )
    3365 {
    3366 lpistateFree(lpistate, blkmem);
    3367 }
    3368
    3369 return SCIP_OKAY;
    3370}
    3371
    3372/** checks whether the given LP state contains simplex basis information */
    3374 SCIP_LPI* lpi, /**< LP interface structure */
    3375 SCIP_LPISTATE* lpistate /**< LP state information (like basis information), or NULL */
    3376 )
    3377{ /*lint --e{715}*/
    3378 assert(lpi != NULL);
    3379 return (lpistate != NULL);
    3380}
    3381
    3382/** reads LP state (like basis information from a file */
    3384 SCIP_LPI* lpi, /**< LP interface structure */
    3385 const char* fname /**< file name */
    3386 )
    3387{
    3388 assert(lpi != NULL);
    3389 assert(lpi->xprslp != NULL);
    3390 assert(fname != NULL);
    3391
    3392 SCIPdebugMessage("reading LP state from file <%s>\n", fname);
    3393
    3394 CHECK_ZERO( lpi->messagehdlr, XPRSreadbasis(lpi->xprslp, fname, "") );
    3395
    3396 return SCIP_OKAY;
    3397}
    3398
    3399/** writes LPi state (i.e. basis information) to a file */
    3401 SCIP_LPI* lpi, /**< LP interface structure */
    3402 const char* fname /**< file name */
    3403 )
    3404{
    3405 assert(lpi != NULL);
    3406 assert(lpi->xprslp != NULL);
    3407 assert(fname != NULL);
    3408
    3409 SCIPdebugMessage("writing LP state to file <%s>\n", fname);
    3410
    3411 CHECK_ZERO( lpi->messagehdlr, XPRSwritebasis(lpi->xprslp, fname, "") );
    3412
    3413 return SCIP_OKAY;
    3414}
    3415
    3416/**@} */
    3417
    3418
    3419/**@name LP Pricing Norms Methods
    3420 *
    3421 * @{
    3422 */
    3423
    3424/** stores LPi pricing norms information
    3425 * @todo should we store norm information?
    3426 */
    3428 SCIP_LPI* lpi, /**< LP interface structure */
    3429 BMS_BLKMEM* blkmem, /**< block memory */
    3430 SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information */
    3431 )
    3432{ /*lint --e{715}*/
    3433 assert(lpi != NULL);
    3434 assert(blkmem != NULL);
    3435 assert(lpinorms != NULL);
    3436
    3437 (*lpinorms) = NULL;
    3438
    3439 return SCIP_OKAY;
    3440}
    3441
    3442/** loads LPi pricing norms into solver; note that the LP might have been extended with additional
    3443 * columns and rows since the state was stored with SCIPlpiGetNorms()
    3444 */
    3446 SCIP_LPI* lpi, /**< LP interface structure */
    3447 BMS_BLKMEM* blkmem, /**< block memory */
    3448 const SCIP_LPINORMS* lpinorms /**< LPi pricing norms information, or NULL */
    3449 )
    3450{ /*lint --e{715}*/
    3451 assert(lpi != NULL);
    3452 assert(lpinorms == NULL);
    3453 SCIP_UNUSED(blkmem);
    3454
    3455 /* no work necessary */
    3456 return SCIP_OKAY;
    3457}
    3458
    3459/** frees pricing norms information */
    3461 SCIP_LPI* lpi, /**< LP interface structure */
    3462 BMS_BLKMEM* blkmem, /**< block memory */
    3463 SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information, or NULL */
    3464 )
    3465{ /*lint --e{715}*/
    3466 assert(lpi != NULL);
    3467 assert(lpinorms == NULL);
    3468 SCIP_UNUSED(blkmem);
    3469
    3470 /* no work necessary */
    3471 return SCIP_OKAY;
    3472}
    3473
    3474/**@} */
    3475
    3476
    3477/**@name Parameter Methods
    3478 *
    3479 * @{
    3480 */
    3481
    3482/** gets integer parameter of LP */
    3484 SCIP_LPI* lpi, /**< LP interface structure */
    3485 SCIP_LPPARAM type, /**< parameter number */
    3486 int* ival /**< buffer to store the parameter value */
    3487 )
    3488{
    3489 int ictrlval;
    3490
    3491 assert(lpi != NULL);
    3492 assert(lpi->xprslp != NULL);
    3493 assert(ival != NULL);
    3494
    3495 SCIPdebugMessage("getting int parameter %d\n", type);
    3496
    3497 switch( type )
    3498 {
    3499 case SCIP_LPPAR_PRICING:
    3500 *ival = (int)lpi->pricing;
    3501 break;
    3503#if 1
    3504 *ival = (lpi->notfromscratch == 0);
    3505#else
    3506 CHECK_ZERO( lpi->messagehdlr, XPRSgetintcontrol(lpi->xprslp, XPRS_KEEPBASIS, &ictrlval) );
    3507 *ival = (ictrlval == 0);
    3508#endif
    3509 break;
    3510 case SCIP_LPPAR_SCALING:
    3511 CHECK_ZERO( lpi->messagehdlr, XPRSgetintcontrol(lpi->xprslp, XPRS_SCALING, &ictrlval) );
    3512 if( ictrlval == 0 )
    3513 *ival = 0;
    3514 else if( ictrlval == 16 )
    3515 *ival = 2;
    3516 else
    3517 *ival = 1;
    3518 break;
    3520 *ival = lpi->par_presolve;
    3521 break;
    3522 case SCIP_LPPAR_LPINFO:
    3523 CHECK_ZERO( lpi->messagehdlr, XPRSgetintcontrol(lpi->xprslp, XPRS_OUTPUTLOG, &ictrlval) );
    3524 *ival = (ictrlval != 0);
    3525 break;
    3526 case SCIP_LPPAR_LPITLIM:
    3527 CHECK_ZERO( lpi->messagehdlr, XPRSgetintcontrol(lpi->xprslp, XPRS_LPITERLIMIT, &ictrlval) );
    3528 *ival = ictrlval;
    3529 if( *ival >= XPRS_MAXINT )
    3530 *ival = XPRS_MAXINT;
    3531 break;
    3532 case SCIP_LPPAR_THREADS:
    3533 CHECK_ZERO( lpi->messagehdlr, XPRSgetintcontrol(lpi->xprslp, XPRS_THREADS, &ictrlval) );
    3534 *ival = ictrlval;
    3535 break;
    3536 default:
    3537 return SCIP_PARAMETERUNKNOWN;
    3538 } /*lint !e788*/
    3539
    3540 return SCIP_OKAY;
    3541}
    3542
    3543/** sets integer parameter of LP */
    3545 SCIP_LPI* lpi, /**< LP interface structure */
    3546 SCIP_LPPARAM type, /**< parameter number */
    3547 int ival /**< parameter value */
    3548 )
    3549{
    3550 assert(lpi != NULL);
    3551 assert(lpi->xprslp != NULL);
    3552
    3553 SCIPdebugMessage("setting int parameter %d to %d\n", type, ival);
    3554
    3555 switch( type )
    3556 {
    3557 case SCIP_LPPAR_PRICING:
    3558 /* every non-supported pricing strategy is promoted to the default pricing strategy */
    3559 lpi->pricing = (SCIP_PRICING)ival; /* store pricing method in LPI struct */
    3560 switch( lpi->pricing )
    3561 {
    3563 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_PRICINGALG, XPRS_PRICING_PARTIAL) );
    3564 break;
    3565 case SCIP_PRICING_DEVEX:
    3566 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_PRICINGALG, XPRS_PRICING_DEVEX) );
    3567 break;
    3568 case SCIP_PRICING_AUTO:
    3569 case SCIP_PRICING_FULL:
    3571 case SCIP_PRICING_STEEP:
    3573 default:
    3574 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_PRICINGALG, XPRS_PRICING_DEFAULT) );
    3575 break;
    3576 }
    3577 break;
    3579 assert(ival == TRUE || ival == FALSE);
    3580 lpi->notfromscratch = (int)(!ival);
    3581 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_KEEPBASIS, (ival == FALSE) ? 1 : 0) );
    3582 break;
    3583 case SCIP_LPPAR_SCALING:
    3584 assert(ival >= 0 && ival <= 2);
    3585 if( ival == 0 )
    3586 {
    3587 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_SCALING, 0) );
    3588 }
    3589 else if( ival == 1 )
    3590 {
    3591 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_SCALING, 163) );
    3592 }
    3593 else
    3594 {
    3595 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_SCALING, 16) );
    3596 }
    3597
    3598 break;
    3600 assert(ival == TRUE || ival == FALSE);
    3601 lpi->par_presolve = ival;
    3602 break;
    3603 case SCIP_LPPAR_LPINFO:
    3604 assert(ival == TRUE || ival == FALSE);
    3605 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_OUTPUTLOG, (ival == TRUE) ? 1 : 0) );
    3606 break;
    3607 case SCIP_LPPAR_LPITLIM:
    3608 assert( ival >= 0 );
    3609 /* 0 <= ival, 0 stopping immediately */
    3610 ival = MIN(ival, XPRS_MAXINT); /*lint !e685*//*lint !e2650*//*lint !e587*/
    3611 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_LPITERLIMIT, ival) );
    3612 break;
    3613 case SCIP_LPPAR_THREADS:
    3614 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_THREADS, ival) );
    3615 break;
    3616 default:
    3617 return SCIP_PARAMETERUNKNOWN;
    3618 } /*lint !e788*/
    3619
    3620 return SCIP_OKAY;
    3621}
    3622
    3623/** gets floating point parameter of LP */
    3625 SCIP_LPI* lpi, /**< LP interface structure */
    3626 SCIP_LPPARAM type, /**< parameter number */
    3627 SCIP_Real* dval /**< buffer to store the parameter value */
    3628 )
    3629{
    3630#if XPVERSION <= 40
    3631 int ictrlval;
    3632#endif
    3633 double dctrlval;
    3634
    3635 assert(lpi != NULL);
    3636 assert(lpi->xprslp != NULL);
    3637 assert(dval != NULL);
    3638
    3639 SCIPdebugMessage("getting real parameter %d\n", type);
    3640
    3641 switch( type )
    3642 {
    3643 case SCIP_LPPAR_FEASTOL:
    3644 CHECK_ZERO( lpi->messagehdlr, XPRSgetdblcontrol(lpi->xprslp, XPRS_FEASTOL, &dctrlval) );
    3645 *dval = dctrlval;
    3646 break;
    3648 CHECK_ZERO( lpi->messagehdlr, XPRSgetdblcontrol(lpi->xprslp, XPRS_OPTIMALITYTOL, &dctrlval) );
    3649 *dval = dctrlval;
    3650 break;
    3652 CHECK_ZERO( lpi->messagehdlr, XPRSgetdblcontrol(lpi->xprslp, XPRS_BARGAPSTOP, &dctrlval) );
    3653 *dval = dctrlval;
    3654 break;
    3655 case SCIP_LPPAR_LPTILIM:
    3656#if XPVERSION <= 40
    3657 CHECK_ZERO( lpi->messagehdlr, XPRSgetintcontrol(lpi->xprslp, XPRS_MAXTIME, &ictrlval) );
    3658 /* ictrlval is the negative of the timelimit (see SCIPlpiSetRealpar) */
    3659 *dval = (double) -ictrlval;
    3660#else
    3661 CHECK_ZERO( lpi->messagehdlr, XPRSgetdblcontrol(lpi->xprslp, XPRS_TIMELIMIT, &dctrlval) );
    3662 *dval = dctrlval;
    3663#endif
    3664 break;
    3666 CHECK_ZERO( lpi->messagehdlr, XPRSgetdblcontrol(lpi->xprslp, XPRS_MARKOWITZTOL, &dctrlval) );
    3667 *dval = dctrlval;
    3668 break;
    3669 case SCIP_LPPAR_OBJLIM:
    3670 CHECK_ZERO( lpi->messagehdlr, XPRSgetdblcontrol(lpi->xprslp, XPRS_MIPABSCUTOFF, &dctrlval) );
    3671 *dval = dctrlval;
    3672 break;
    3673 default:
    3674 return SCIP_PARAMETERUNKNOWN;
    3675 } /*lint !e788*/
    3676
    3677 return SCIP_OKAY;
    3678}
    3679
    3680/** sets floating point parameter of LP */
    3682 SCIP_LPI* lpi, /**< LP interface structure */
    3683 SCIP_LPPARAM type, /**< parameter number */
    3684 SCIP_Real dval /**< parameter value */
    3685 )
    3686{
    3687 assert(lpi != NULL);
    3688 assert(lpi->xprslp != NULL);
    3689
    3690 SCIPdebugMessage("setting real parameter %d to %g\n", type, dval);
    3691
    3692 switch( type )
    3693 {
    3694 case SCIP_LPPAR_FEASTOL:
    3695 /* Xpress does not pose any restriction on dval, its absolute value is used as tolerance.
    3696 * For consistency we assert it to be strictly positive.
    3697 */
    3698 assert( dval > 0.0 );
    3699 CHECK_ZERO( lpi->messagehdlr, XPRSsetdblcontrol(lpi->xprslp, XPRS_FEASTOL, dval) );
    3700 break;
    3702 /* Xpress does not pose any restriction on dval,
    3703 * however for consistency we assert it to be strictly positive.
    3704 */
    3705 assert( dval > 0.0 );
    3706 CHECK_ZERO( lpi->messagehdlr, XPRSsetdblcontrol(lpi->xprslp, XPRS_OPTIMALITYTOL, dval) );
    3707 break;
    3709 assert( dval >= 0.0 );
    3710 /* Xpress poses no restriction on dval
    3711 * However for consistency we assert it to be nonnegative.
    3712 */
    3713 CHECK_ZERO( lpi->messagehdlr, XPRSsetdblcontrol(lpi->xprslp, XPRS_BARGAPSTOP, dval) );
    3714 break;
    3715 case SCIP_LPPAR_LPTILIM:
    3716 {
    3717#if XPVERSION <= 40
    3718 int ival;
    3719
    3720 /* From the Xpress documentation:
    3721 * dval>0 If an integer solution has been found, stop MIP search after dval seconds,
    3722 * otherwise continue until an integer solution is finally found.
    3723 * dval<0 Stop in LP or MIP search after dval seconds.
    3724 * dval=0 No time limit
    3725 */
    3726 assert( dval > 0.0 );
    3727 if( dval >= INT_MAX )
    3728 ival = 0;
    3729 else
    3730 ival = (int) -floor(dval);
    3731
    3732 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_MAXTIME, ival) );
    3733#else
    3734 CHECK_ZERO( lpi->messagehdlr, XPRSsetdblcontrol(lpi->xprslp, XPRS_TIMELIMIT, dval) );
    3735#endif
    3736 break;
    3737 }
    3739 /* no restriction on dval */
    3740 CHECK_ZERO( lpi->messagehdlr, XPRSsetdblcontrol(lpi->xprslp, XPRS_MARKOWITZTOL, dval) );
    3741 break;
    3742 case SCIP_LPPAR_OBJLIM:
    3743 /* no restriction on dval */
    3744 CHECK_ZERO( lpi->messagehdlr, XPRSsetdblcontrol(lpi->xprslp, XPRS_MIPABSCUTOFF, dval) );
    3745 break;
    3746 default:
    3747 return SCIP_PARAMETERUNKNOWN;
    3748 } /*lint !e788*/
    3749
    3750 return SCIP_OKAY;
    3751}
    3752
    3753/** interrupts the currently ongoing lp solve or disables the interrupt */
    3755 SCIP_LPI* lpi, /**< LP interface structure */
    3756 SCIP_Bool interrupt /**< TRUE if interrupt should be set, FALSE if it should be disabled */
    3757 )
    3758{
    3759 /*lint --e{715}*/
    3760 assert(lpi != NULL);
    3761
    3762 return SCIP_OKAY;
    3763}
    3764
    3765/**@} */
    3766
    3767
    3768/**@name Numerical Methods
    3769 *
    3770 * @{
    3771 */
    3772
    3773/** returns value treated as infinity in the LP solver */
    3775 SCIP_LPI* lpi /**< LP interface structure */
    3776 )
    3777{ /*lint --e{715}*/
    3778 assert(lpi != NULL);
    3779 return XPRS_PLUSINFINITY;
    3780}
    3781
    3782/** checks if given value is treated as infinity in the LP solver */
    3784 SCIP_LPI* lpi, /**< LP interface structure */
    3785 SCIP_Real val /**< value to be checked for infinity */
    3786 )
    3787{ /*lint --e{715}*/
    3788 assert(lpi != NULL);
    3789 return (val >= XPRS_PLUSINFINITY);
    3790}
    3791
    3792/**@} */
    3793
    3794
    3795/**@name File Interface Methods
    3796 *
    3797 * @{
    3798 */
    3799
    3800/** reads LP from a file
    3801 *
    3802 * The file extension defines the format. That can be lp or mps. Any given file name needs to have one of these two
    3803 * extension. If not nothing is read and a SCIP_READERROR is returned.
    3804 */
    3806 SCIP_LPI* lpi, /**< LP interface structure */
    3807 const char* fname /**< file name */
    3808 )
    3809{
    3810 SCIP_RETCODE retcode = SCIP_OKAY;
    3811
    3812 char* basename = NULL;
    3813 char* compression = NULL;
    3814 char* extension = NULL;
    3815 char* filename = NULL;
    3816 char* path = NULL;
    3817 char* xpressfilename = NULL;
    3818
    3819 int size;
    3820
    3821 assert(lpi != NULL);
    3822 assert(lpi->xprslp != NULL);
    3823 assert(fname != NULL);
    3824
    3825 SCIPdebugMessage("reading LP from file <%s>\n", fname);
    3826
    3827 /* get the length of the file name */
    3828 size = (int)strlen(fname)+1;
    3829
    3830 /* check that the file name is longer than Xpress can handle */
    3831 if (size > XPRS_MAXPROBNAMELENGTH)
    3832 return SCIP_WRITEERROR;
    3833
    3834 /* get char array for the file name we pass to Xpress */
    3835 SCIP_ALLOC( BMSallocMemoryArray(&xpressfilename, size) );
    3836
    3837 /* copy filename to be able to split it into its components */
    3838 SCIP_ALLOC( BMSduplicateMemoryArray(&filename, fname, size) );
    3839
    3840 /* get path, base file name, extension, and compression of the given file name */
    3841 SCIPsplitFilename(filename, &path, &basename, &extension, &compression);
    3842
    3843 /* construct file name without extension */
    3844 if (path != NULL)
    3845 (void) SCIPsnprintf(xpressfilename, size, "%s/%s", path, basename);
    3846 else
    3847 (void) SCIPsnprintf(xpressfilename, size, "%s", basename);
    3848
    3849 /* check that the file name did not has a compression extension, has an lp or mps extension, and actually a base name */
    3850 if (compression != NULL || extension == NULL || basename == NULL)
    3851 retcode = SCIP_READERROR;
    3852 if (strcasecmp(extension, "mps") == 0) {
    3853 CHECK_ZERO( lpi->messagehdlr, XPRSreadprob(lpi->xprslp, xpressfilename, "") );
    3854 }
    3855 else if (strcasecmp(extension, "lp") == 0) {
    3856 CHECK_ZERO( lpi->messagehdlr, XPRSreadprob(lpi->xprslp, xpressfilename, "l") );
    3857 }
    3858 else
    3859 retcode = SCIP_READERROR;
    3860
    3861 /* free array */
    3862 BMSfreeMemoryArrayNull(&filename);
    3863 BMSfreeMemoryArrayNull(&xpressfilename);
    3864
    3865 return retcode;
    3866}
    3867
    3868/** writes LP to a file
    3869 *
    3870 * The file extension defines the format. That can be lp or mps. Any given file name needs to have one of these two
    3871 * extension. If not nothing is written and a SCIP_WRITEERROR is returned.
    3872 */
    3874 SCIP_LPI* lpi, /**< LP interface structure */
    3875 const char* fname /**< file name */
    3876 )
    3877{
    3878 SCIP_RETCODE retcode = SCIP_OKAY;
    3879
    3880 char* basename = NULL;
    3881 char* compression = NULL;
    3882 char* extension = NULL;
    3883 char* filename = NULL;
    3884 char* path = NULL;
    3885 char* xpressfilename = NULL;
    3886
    3887 int size;
    3888
    3889 assert(lpi != NULL);
    3890 assert(lpi->xprslp != NULL);
    3891 assert(fname != NULL);
    3892
    3893 SCIPdebugMessage("writing LP to file <%s>\n", fname);
    3894
    3895 /* get the length of the file name */
    3896 size = (int)strlen(fname)+1;
    3897
    3898 /* check that the file name is longer than Xpress can handle */
    3899 if (size > XPRS_MAXPROBNAMELENGTH)
    3900 return SCIP_WRITEERROR;
    3901
    3902 /* get char array for the file name we pass to Xpress */
    3903 SCIP_ALLOC( BMSallocMemoryArray(&xpressfilename, size) );
    3904
    3905 /* copy filename to be able to split it into its components */
    3906 SCIP_ALLOC( BMSduplicateMemoryArray(&filename, fname, size) );
    3907
    3908 /* get path, base file name, extension, and compression of the given file name */
    3909 SCIPsplitFilename(filename, &path, &basename, &extension, &compression);
    3910
    3911 /* construct file name without extension */
    3912 if (path != NULL)
    3913 (void) SCIPsnprintf(xpressfilename, size, "%s/%s", path, basename);
    3914 else
    3915 (void) SCIPsnprintf(xpressfilename, size, "%s", basename);
    3916
    3917 /* check that the file name did not has a compression extension, has an lp or mps extension, and actually a base name */
    3918 if (compression != NULL || extension == NULL || basename == NULL)
    3919 retcode = SCIP_WRITEERROR;
    3920 if (strcasecmp(extension, "mps") == 0) {
    3921 CHECK_ZERO( lpi->messagehdlr, XPRSwriteprob(lpi->xprslp, xpressfilename, "p") );
    3922 }
    3923 else if (strcasecmp(extension, "lp") == 0) {
    3924 CHECK_ZERO( lpi->messagehdlr, XPRSwriteprob(lpi->xprslp, xpressfilename, "lp") );
    3925 }
    3926 else
    3927 retcode = SCIP_WRITEERROR;
    3928
    3929 /* free array */
    3930 BMSfreeMemoryArrayNull(&filename);
    3931 BMSfreeMemoryArrayNull(&xpressfilename);
    3932
    3933 return retcode;
    3934}
    3935
    3936/**@} */
    void SCIPdecodeDualBit(const SCIP_DUALPACKET *inp, int *out, int count)
    Definition: bitencode.c:308
    void SCIPencodeDualBit(const int *inp, SCIP_DUALPACKET *out, int count)
    Definition: bitencode.c:238
    packing single and dual bit values
    unsigned int SCIP_DUALPACKET
    Definition: bitencode.h:42
    SCIP_Real * r
    Definition: circlepacking.c:59
    #define NULL
    Definition: def.h:248
    #define SCIP_UNUSED(x)
    Definition: def.h:409
    #define SCIP_INVALID
    Definition: def.h:178
    #define SCIP_Bool
    Definition: def.h:91
    #define MIN(x, y)
    Definition: def.h:224
    #define SCIP_ALLOC(x)
    Definition: def.h:366
    #define SCIP_Real
    Definition: def.h:156
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define MAX(x, y)
    Definition: def.h:220
    #define EPSCEIL(x, eps)
    Definition: def.h:192
    #define SCIPABORT()
    Definition: def.h:327
    #define EPSFLOOR(x, eps)
    Definition: def.h:191
    #define REALABS(x)
    Definition: def.h:182
    #define SCIP_CALL(x)
    Definition: def.h:355
    void SCIPsplitFilename(char *filename, char **path, char **name, char **extension, char **compression)
    Definition: misc.c:11073
    SCIP_RETCODE SCIPlpiChgSides(SCIP_LPI *lpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
    Definition: lpi_xprs.c:1292
    SCIP_RETCODE SCIPlpiSetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPISTATE *lpistate)
    Definition: lpi_xprs.c:3264
    SCIP_RETCODE SCIPlpiGetBInvACol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
    Definition: lpi_xprs.c:3156
    SCIP_RETCODE SCIPlpiGetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
    Definition: lpi_xprs.c:3624
    SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
    Definition: lpi_xprs.c:3774
    SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
    Definition: lpi_xprs.c:2619
    SCIP_RETCODE SCIPlpiChgObjsen(SCIP_LPI *lpi, SCIP_OBJSEN objsense)
    Definition: lpi_xprs.c:1345
    SCIP_Bool SCIPlpiIsInfinity(SCIP_LPI *lpi, SCIP_Real val)
    Definition: lpi_xprs.c:3783
    SCIP_RETCODE SCIPlpiClear(SCIP_LPI *lpi)
    Definition: lpi_xprs.c:1228
    SCIP_RETCODE SCIPlpiClearState(SCIP_LPI *lpi)
    Definition: lpi_xprs.c:3341
    SCIP_Bool SCIPlpiExistsDualRay(SCIP_LPI *lpi)
    Definition: lpi_xprs.c:2466
    SCIP_Bool SCIPlpiExistsPrimalRay(SCIP_LPI *lpi)
    Definition: lpi_xprs.c:2360
    SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
    Definition: lpi_xprs.c:2852
    SCIP_RETCODE SCIPlpiReadState(SCIP_LPI *lpi, const char *fname)
    Definition: lpi_xprs.c:3383
    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_xprs.c:1084
    SCIP_RETCODE SCIPlpiGetPrimalRay(SCIP_LPI *lpi, SCIP_Real *ray)
    Definition: lpi_xprs.c:2767
    SCIP_RETCODE SCIPlpiGetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int *ival)
    Definition: lpi_xprs.c:3483
    SCIP_RETCODE SCIPlpiWriteLP(SCIP_LPI *lpi, const char *fname)
    Definition: lpi_xprs.c:3873
    SCIP_RETCODE SCIPlpiSetIntegralityInformation(SCIP_LPI *lpi, int ncols, int *intInfo)
    Definition: lpi_xprs.c:704
    SCIP_Bool SCIPlpiIsDualInfeasible(SCIP_LPI *lpi)
    Definition: lpi_xprs.c:2510
    SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
    Definition: lpi_xprs.c:3681
    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_xprs.c:2225
    SCIP_RETCODE SCIPlpiSetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPINORMS *lpinorms)
    Definition: lpi_xprs.c:3445
    SCIP_RETCODE SCIPlpiGetNNonz(SCIP_LPI *lpi, int *nnonz)
    Definition: lpi_xprs.c:1552
    SCIP_Bool SCIPlpiHasPrimalSolve(void)
    Definition: lpi_xprs.c:719
    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_xprs.c:2268
    SCIP_RETCODE SCIPlpiGetBounds(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lbs, SCIP_Real *ubs)
    Definition: lpi_xprs.c:1769
    SCIP_Bool SCIPlpiHasBarrierSolve(void)
    Definition: lpi_xprs.c:735
    SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
    Definition: lpi_xprs.c:2788
    SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
    Definition: lpi_xprs.c:2700
    SCIP_RETCODE SCIPlpiScaleCol(SCIP_LPI *lpi, int col, SCIP_Real scaleval)
    Definition: lpi_xprs.c:1444
    int SCIPlpiGetInternalStatus(SCIP_LPI *lpi)
    Definition: lpi_xprs.c:2673
    SCIP_RETCODE SCIPlpiStartStrongbranch(SCIP_LPI *lpi)
    Definition: lpi_xprs.c:2006
    SCIP_RETCODE SCIPlpiGetSolFeasibility(SCIP_LPI *lpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
    Definition: lpi_xprs.c:2338
    SCIP_RETCODE SCIPlpiFreeNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
    Definition: lpi_xprs.c:3460
    SCIP_Bool SCIPlpiIsIterlimExc(SCIP_LPI *lpi)
    Definition: lpi_xprs.c:2631
    SCIP_RETCODE SCIPlpiChgBounds(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
    Definition: lpi_xprs.c:1248
    SCIP_Bool SCIPlpiIsPrimalUnbounded(SCIP_LPI *lpi)
    Definition: lpi_xprs.c:2395
    SCIP_RETCODE SCIPlpiIgnoreInstability(SCIP_LPI *lpi, SCIP_Bool *success)
    Definition: lpi_xprs.c:2684
    SCIP_RETCODE SCIPlpiWriteState(SCIP_LPI *lpi, const char *fname)
    Definition: lpi_xprs.c:3400
    SCIP_RETCODE SCIPlpiFree(SCIP_LPI **lpi)
    Definition: lpi_xprs.c:826
    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_xprs.c:2246
    SCIP_RETCODE SCIPlpiGetCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real *val)
    Definition: lpi_xprs.c:1822
    SCIP_Bool SCIPlpiIsPrimalFeasible(SCIP_LPI *lpi)
    Definition: lpi_xprs.c:2428
    SCIP_RETCODE SCIPlpiReadLP(SCIP_LPI *lpi, const char *fname)
    Definition: lpi_xprs.c:3805
    SCIP_RETCODE SCIPlpiGetRealSolQuality(SCIP_LPI *lpi, SCIP_LPSOLQUALITY qualityindicator, SCIP_Real *quality)
    Definition: lpi_xprs.c:2828
    SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
    Definition: lpi_xprs.c:2524
    SCIP_RETCODE SCIPlpiGetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
    Definition: lpi_xprs.c:3427
    SCIP_Bool SCIPlpiIsTimelimExc(SCIP_LPI *lpi)
    Definition: lpi_xprs.c:2652
    SCIP_Bool SCIPlpiHasStateBasis(SCIP_LPI *lpi, SCIP_LPISTATE *lpistate)
    Definition: lpi_xprs.c:3373
    SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
    Definition: lpi_xprs.c:3544
    const char * SCIPlpiGetSolverName(void)
    Definition: lpi_xprs.c:668
    SCIP_RETCODE SCIPlpiSetBase(SCIP_LPI *lpi, const int *cstat, const int *rstat)
    Definition: lpi_xprs.c:2892
    SCIP_Bool SCIPlpiHasPrimalRay(SCIP_LPI *lpi)
    Definition: lpi_xprs.c:2374
    SCIP_RETCODE SCIPlpiGetBInvRow(SCIP_LPI *lpi, int row, SCIP_Real *coef, int *inds, int *ninds)
    Definition: lpi_xprs.c:3002
    SCIP_RETCODE SCIPlpiDelRows(SCIP_LPI *lpi, int firstrow, int lastrow)
    Definition: lpi_xprs.c:1149
    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_xprs.c:1572
    SCIP_RETCODE SCIPlpiGetBInvCol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
    Definition: lpi_xprs.c:3040
    SCIP_RETCODE SCIPlpiGetColNames(SCIP_LPI *lpi, int firstcol, int lastcol, char **colnames, char *namestorage, int namestoragesize, int *storageleft)
    Definition: lpi_xprs.c:1681
    SCIP_RETCODE SCIPlpiGetBInvARow(SCIP_LPI *lpi, int r, const SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
    Definition: lpi_xprs.c:3082
    SCIP_RETCODE SCIPlpiGetRows(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhss, SCIP_Real *rhss, int *nnonz, int *beg, int *ind, SCIP_Real *val)
    Definition: lpi_xprs.c:1628
    SCIP_Bool SCIPlpiWasSolved(SCIP_LPI *lpi)
    Definition: lpi_xprs.c:2319
    const char * SCIPlpiGetSolverDesc(void)
    Definition: lpi_xprs.c:685
    SCIP_RETCODE SCIPlpiSolveBarrier(SCIP_LPI *lpi, SCIP_Bool crossover)
    Definition: lpi_xprs.c:1984
    SCIP_Bool SCIPlpiIsOptimal(SCIP_LPI *lpi)
    Definition: lpi_xprs.c:2560
    SCIP_RETCODE SCIPlpiGetRowNames(SCIP_LPI *lpi, int firstrow, int lastrow, char **rownames, char *namestorage, int namestoragesize, int *storageleft)
    Definition: lpi_xprs.c:1704
    SCIP_Bool SCIPlpiHasDualSolve(void)
    Definition: lpi_xprs.c:727
    SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
    Definition: lpi_xprs.c:2018
    SCIP_RETCODE SCIPlpiGetSides(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhss, SCIP_Real *rhss)
    Definition: lpi_xprs.c:1795
    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_xprs.c:2289
    SCIP_RETCODE SCIPlpiGetSol(SCIP_LPI *lpi, SCIP_Real *objval, SCIP_Real *primsol, SCIP_Real *dualsol, SCIP_Real *activity, SCIP_Real *redcost)
    Definition: lpi_xprs.c:2721
    SCIP_Bool SCIPlpiHasDualRay(SCIP_LPI *lpi)
    Definition: lpi_xprs.c:2480
    SCIP_RETCODE SCIPlpiDelColset(SCIP_LPI *lpi, int *dstat)
    Definition: lpi_xprs.c:1034
    SCIP_RETCODE SCIPlpiGetObj(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *vals)
    Definition: lpi_xprs.c:1750
    SCIP_RETCODE SCIPlpiFreeState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
    Definition: lpi_xprs.c:3354
    SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
    Definition: lpi_xprs.c:2414
    SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
    Definition: lpi_xprs.c:1972
    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_xprs.c:938
    SCIP_RETCODE SCIPlpiSolvePrimal(SCIP_LPI *lpi)
    Definition: lpi_xprs.c:1960
    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_xprs.c:866
    SCIP_Bool SCIPlpiIsDualUnbounded(SCIP_LPI *lpi)
    Definition: lpi_xprs.c:2496
    SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
    Definition: lpi_xprs.c:2809
    SCIP_RETCODE SCIPlpiGetBasisInd(SCIP_LPI *lpi, int *bind)
    Definition: lpi_xprs.c:2951
    SCIP_RETCODE SCIPlpiCreate(SCIP_LPI **lpi, SCIP_MESSAGEHDLR *messagehdlr, const char *name, SCIP_OBJSEN objsen)
    Definition: lpi_xprs.c:751
    void * SCIPlpiGetSolverPointer(SCIP_LPI *lpi)
    Definition: lpi_xprs.c:696
    SCIP_RETCODE SCIPlpiChgObj(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *obj)
    Definition: lpi_xprs.c:1363
    SCIP_RETCODE SCIPlpiGetObjsen(SCIP_LPI *lpi, SCIP_OBJSEN *objsen)
    Definition: lpi_xprs.c:1727
    SCIP_Bool SCIPlpiIsStable(SCIP_LPI *lpi)
    Definition: lpi_xprs.c:2578
    SCIP_RETCODE SCIPlpiGetNCols(SCIP_LPI *lpi, int *ncols)
    Definition: lpi_xprs.c:1535
    SCIP_RETCODE SCIPlpiInterrupt(SCIP_LPI *lpi, SCIP_Bool interrupt)
    Definition: lpi_xprs.c:3754
    SCIP_RETCODE SCIPlpiDelCols(SCIP_LPI *lpi, int firstcol, int lastcol)
    Definition: lpi_xprs.c:1003
    SCIP_RETCODE SCIPlpiDelRowset(SCIP_LPI *lpi, int *dstat)
    Definition: lpi_xprs.c:1179
    SCIP_RETCODE SCIPlpiScaleRow(SCIP_LPI *lpi, int row, SCIP_Real scaleval)
    Definition: lpi_xprs.c:1385
    SCIP_RETCODE SCIPlpiGetNRows(SCIP_LPI *lpi, int *nrows)
    Definition: lpi_xprs.c:1518
    SCIP_RETCODE SCIPlpiGetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
    Definition: lpi_xprs.c:3210
    SCIP_RETCODE SCIPlpiChgCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real newval)
    Definition: lpi_xprs.c:1325
    int SCIPsnprintf(char *t, int len, const char *s,...)
    Definition: misc.c:10827
    interface methods for specific LP solvers
    SCIP_DUALPACKET ROWPACKET
    Definition: lpi_clp.cpp:128
    SCIP_DUALPACKET COLPACKET
    Definition: lpi_clp.cpp:126
    static SCIP_RETCODE lpiStrongbranches(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_xprs.c:2115
    static void reconvertSides(SCIP_LPI *lpi, int nrows, SCIP_Real *lhs, SCIP_Real *rhs)
    Definition: lpi_xprs.c:625
    static void lpistatePack(SCIP_LPISTATE *lpistate, const int *cstat, const int *rstat)
    Definition: lpi_xprs.c:341
    static void lpistateUnpack(const SCIP_LPISTATE *lpistate, int *cstat, int *rstat)
    Definition: lpi_xprs.c:357
    static int rowpacketNum(int nrows)
    Definition: lpi_xprs.c:332
    static _Thread_local char xprsname[100]
    Definition: lpi_xprs.c:663
    SCIP_DUALPACKET ROWPACKET
    Definition: lpi_xprs.c:84
    static SCIP_RETCODE ensureCstatMem(SCIP_LPI *lpi, int num)
    Definition: lpi_xprs.c:271
    static void reconvertBothSides(SCIP_LPI *lpi, int nrows, SCIP_Real *lhss, SCIP_Real *rhss)
    Definition: lpi_xprs.c:486
    static SCIP_RETCODE lpiSolve(SCIP_LPI *lpi, const char *method)
    Definition: lpi_xprs.c:1848
    #define COLS_PER_PACKET
    Definition: lpi_xprs.c:83
    static void reconvertRhs(SCIP_LPI *lpi, int nrows, SCIP_Real *rhss)
    Definition: lpi_xprs.c:580
    #define XPRS_LPQUICKPRESOLVE
    Definition: lpi_xprs.c:57
    static SCIP_RETCODE ensureBoundchgMem(SCIP_LPI *lpi, int num)
    Definition: lpi_xprs.c:195
    static void debugCheckRowrang(SCIP_LPI *lpi, int firstrow, int lastrow)
    Definition: lpi_xprs.c:161
    static void lpistateFree(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem)
    Definition: lpi_xprs.c:394
    SCIP_DUALPACKET COLPACKET
    Definition: lpi_xprs.c:82
    static int xprsObjsen(SCIP_OBJSEN const objsen)
    Definition: lpi_xprs.c:418
    #define XPRS_LP_OPTIMAL_SCALEDINFEAS
    Definition: lpi_xprs.c:61
    #define ABORT_ZERO(messagehdlr, retval, x)
    Definition: lpi_xprs.c:72
    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_xprs.c:2031
    #define CHECK_ZERO(messagehdlr, x)
    Definition: lpi_xprs.c:63
    static SCIP_RETCODE ensureRstatMem(SCIP_LPI *lpi, int num)
    Definition: lpi_xprs.c:293
    static int colpacketNum(int ncols)
    Definition: lpi_xprs.c:323
    static void debugCheckColrang(SCIP_LPI *lpi, int firstcol, int lastcol)
    Definition: lpi_xprs.c:144
    static void convertSides(SCIP_LPI *lpi, int nrows, const SCIP_Real *lhss, const SCIP_Real *rhss)
    Definition: lpi_xprs.c:437
    static SCIP_RETCODE ensureSidechgMem(SCIP_LPI *lpi, int num)
    Definition: lpi_xprs.c:224
    static void reconvertLhs(SCIP_LPI *lpi, int nrows, SCIP_Real *lhss)
    Definition: lpi_xprs.c:535
    static SCIP_RETCODE lpistateCreate(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem, int ncols, int nrows)
    Definition: lpi_xprs.c:373
    #define ROWS_PER_PACKET
    Definition: lpi_xprs.c:85
    static void invalidateSolution(SCIP_LPI *lpi)
    Definition: lpi_xprs.c:645
    static SCIP_RETCODE ensureValMem(SCIP_LPI *lpi, int num)
    Definition: lpi_xprs.c:248
    #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 BMSduplicateMemoryArray(ptr, source, num)
    Definition: memory.h:143
    #define BMSallocMemoryArray(ptr, num)
    Definition: memory.h:123
    #define BMSfreeMemoryArray(ptr)
    Definition: memory.h:147
    #define BMSallocBlockMemoryArray(mem, ptr, num)
    Definition: memory.h:454
    #define BMSfreeBlockMemoryArray(mem, ptr, num)
    Definition: memory.h:467
    #define BMSclearMemoryArray(ptr, num)
    Definition: memory.h:130
    struct BMS_BlkMem BMS_BLKMEM
    Definition: memory.h:437
    #define BMSfreeMemoryArrayNull(ptr)
    Definition: memory.h:148
    #define BMSallocMemory(ptr)
    Definition: memory.h:118
    void SCIPmessagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
    Definition: message.c:427
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    #define SCIPdebugMessage
    Definition: pub_message.h:96
    public data structures and miscellaneous methods
    COLPACKET * packcstat
    Definition: lpi_clp.cpp:136
    ROWPACKET * packrstat
    Definition: lpi_clp.cpp:137
    int par_presolve
    Definition: lpi_xprs.c:121
    SCIP_Bool clearstate
    Definition: lpi_cpx.c:172
    int iterations
    Definition: lpi_cpx.c:167
    SCIP_Real * valarray
    Definition: lpi_cpx.c:157
    int valsize
    Definition: lpi_cpx.c:164
    int par_fastlp
    Definition: lpi_xprs.c:120
    SCIP_Real par_lobjlim
    Definition: lpi_xprs.c:118
    char * uarray
    Definition: lpi_cpx.c:153
    XPRSprob xprslp
    Definition: lpi_xprs.c:90
    int boundchgsize
    Definition: lpi_cpx.c:162
    int notfromscratch
    Definition: lpi_xprs.c:94
    int * indarray
    Definition: lpi_cpx.c:161
    int * cstat
    Definition: lpi_clp.cpp:107
    char solmethod
    Definition: lpi_xprs.c:96
    SCIP_Bool solisbasic
    Definition: lpi_cpx.c:169
    int solstat
    Definition: lpi_cpx.c:149
    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
    char name[200]
    Definition: lpi_xprs.c:91
    SCIP_PRICING pricing
    Definition: lpi_clp.cpp:112
    int cstatsize
    Definition: lpi_clp.cpp:109
    char * senarray
    Definition: lpi_cpx.c:154
    SCIP_Real par_uobjlim
    Definition: lpi_xprs.c:119
    SCIP_MESSAGEHDLR * messagehdlr
    Definition: lpi_cpx.c:185
    SCIP_Real * rngarray
    Definition: lpi_cpx.c:156
    char * larray
    Definition: lpi_cpx.c:152
    @ SCIP_PRICING_STEEPQSTART
    Definition: type_lpi.h:83
    @ SCIP_PRICING_AUTO
    Definition: type_lpi.h:79
    @ SCIP_PRICING_DEVEX
    Definition: type_lpi.h:84
    @ SCIP_PRICING_STEEP
    Definition: type_lpi.h:82
    @ SCIP_PRICING_FULL
    Definition: type_lpi.h:80
    @ SCIP_PRICING_LPIDEFAULT
    Definition: type_lpi.h:78
    @ SCIP_PRICING_PARTIAL
    Definition: type_lpi.h:81
    enum SCIP_Pricing SCIP_PRICING
    Definition: type_lpi.h:86
    enum SCIP_LPParam SCIP_LPPARAM
    Definition: type_lpi.h:73
    @ SCIP_LPPAR_PRICING
    Definition: type_lpi.h:54
    @ SCIP_LPPAR_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_DUALFEASTOL
    Definition: type_lpi.h:57
    @ SCIP_LPPAR_FROMSCRATCH
    Definition: type_lpi.h:50
    @ SCIP_LPPAR_MARKOWITZ
    Definition: type_lpi.h:62
    @ SCIP_LPPAR_FEASTOL
    Definition: type_lpi.h:56
    @ SCIP_LPPAR_LPITLIM
    Definition: type_lpi.h:60
    @ SCIP_LPPAR_OBJLIM
    Definition: type_lpi.h:59
    @ SCIP_BASESTAT_BASIC
    Definition: type_lpi.h:92
    @ SCIP_BASESTAT_UPPER
    Definition: type_lpi.h:93
    @ SCIP_BASESTAT_LOWER
    Definition: type_lpi.h:91
    @ SCIP_BASESTAT_ZERO
    Definition: type_lpi.h:94
    enum SCIP_LPSolQuality SCIP_LPSOLQUALITY
    Definition: type_lpi.h:104
    @ SCIP_OBJSEN_MAXIMIZE
    Definition: type_lpi.h:42
    @ SCIP_OBJSEN_MINIMIZE
    Definition: type_lpi.h:43
    enum SCIP_ObjSen SCIP_OBJSEN
    Definition: type_lpi.h:45
    @ SCIP_LPERROR
    Definition: type_retcode.h:49
    @ SCIP_READERROR
    Definition: type_retcode.h:45
    @ SCIP_PARAMETERUNKNOWN
    Definition: type_retcode.h:55
    @ SCIP_WRITEERROR
    Definition: type_retcode.h:46
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63