Scippy

    SCIP

    Solving Constraint Integer Programs

    lpiexact_spx.cpp
    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-2026 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 lpiexact_spx.cpp
    26 * @ingroup LPIEXACTS
    27 * @brief exact LP interface for SoPlex
    28 * @author Leon Eifler
    29 *
    30 * This is an implementation of SCIP's LP interface for SoPlex.
    31 *
    32 * For debugging purposes, the SoPlex results can be double checked with CPLEX if WITH_LPSCHECK is defined. This may
    33 * yield false positives, since the LP is dumped to a file for transferring it to CPLEX, hence, precision may be lost.
    34 */
    35
    36/*--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    37#include "scip/def.h"
    39#include "scip/type_retcode.h"
    41#include "lpiexact/lpiexact.h"
    42#include "scip/rational.h"
    43#include "scip/rationalgmp.h"
    44
    45/* check the return value of setParam methods */
    46#define CHECK_SOPLEX_PARAM(x) \
    47 if( !x ) \
    48 { \
    49 SCIPmessagePrintWarning(_messagehdlr, "SoPlex: unsupported parameter value\n"); \
    50 }
    51
    52/* remember the original value of the SCIP_DEBUG define and undefine it */
    53#ifdef SCIP_DEBUG
    54#define ___DEBUG
    55#undef SCIP_DEBUG
    56#endif
    57
    58/* disable -Wclass-memaccess warnings due to dubious memcpy/realloc calls in SoPlex headers, e.g.,
    59 * dataarray.h:314:16: warning: ‘void* memcpy(void*, const void*, size_t)’ writing to an object of type ‘struct soplex::SPxParMultPR::SPxParMultPr_Tmp’ with no trivial copy-assignment; use copy-assignment or copy-initialization instead [-Wclass-memaccess]
    60 */
    61#ifdef __GNUC__
    62#if __GNUC__ >= 8
    63#pragma GCC diagnostic ignored "-Wclass-memaccess"
    64#endif
    65#endif
    66
    67/* include SoPlex solver */
    68#include "soplex.h"
    69
    70/* define subversion for versions <= 1.5.0.1 */
    71#ifndef SOPLEX_SUBVERSION
    72#define SOPLEX_SUBVERSION 0
    73#endif
    74/* define API version for versions <= 3.0.0 */
    75#ifndef SOPLEX_APIVERSION
    76#define SOPLEX_APIVERSION 0
    77#endif
    78
    79/* check version */
    80#if (SOPLEX_APIVERSION < 11)
    81#error "This interface requires SoPlex with API version 11 or higher, which is available from SoPlex 5.0.0."
    82#endif
    83
    84#if (SOPLEX_APIVERSION <= 5)
    85#include "spxgithash.h"
    86#endif
    87
    88#ifndef SOPLEX_WITH_GMP
    89#error "SOPLEX_WITH_GMP not defined: SoPlex must be build with GMP to be used with LPSEXACT=spx"
    90#endif
    91
    92#ifndef SOPLEX_WITH_MPFR
    93#error "SOPLEX_WITH_MPFR not defined: SoPlex must be build with MPFR to be used with LPSEXACT=spx"
    94#endif
    95
    96#ifndef SOPLEX_WITH_BOOST
    97#error "SOPLEX_WITH_BOOST not defined: SoPlex must be build with BOOST to be used with LPSEXACT=spx"
    98#endif
    99
    100/* reset the SCIP_DEBUG define to its original SCIP value */
    101#undef SCIP_DEBUG
    102#ifdef ___DEBUG
    103#define SCIP_DEBUG
    104#undef ___DEBUG
    105#endif
    106
    107/* define snprintf when using a too old MSVC version */
    108#if defined(_MSC_VER) && _MSC_VER < 1900
    109#ifndef snprintf
    110#define snprintf _snprintf
    111#endif
    112#endif
    113
    114#define SOPLEX_VERBLEVEL 5 /**< verbosity level for LPINFO */
    115
    116#include "scip/pub_message.h"
    117#include "scip/struct_rational.h"
    118
    119/********************************************************************/
    120/*----------------------------- C++ --------------------------------*/
    121/********************************************************************/
    122
    123/* in C++ we have to use "0" instead of "(void*)0" */
    124#undef NULL
    125#define NULL 0
    126
    127#include <cassert>
    128using namespace soplex;
    129
    130
    131/** Macro for a single SoPlex call for which exceptions have to be catched - return an LP error. We
    132 * make no distinction between different exception types, e.g., between memory allocation and other
    133 * exceptions.
    134 */
    135#ifndef NDEBUG
    136#define SOPLEX_TRY(messagehdlr, x) do \
    137 { \
    138 try \
    139 { \
    140 (x); \
    141 } \
    142 catch( const SPxMemoryException& E ) \
    143 { \
    144 std::string s = E.what(); \
    145 SCIPerrorMessage("SoPlex threw a memory exception: %s\n", s.c_str()); \
    146 return SCIP_ERROR; \
    147 } \
    148 catch( const SPxException& E ) \
    149 { \
    150 std::string s = E.what(); \
    151 SCIPmessagePrintWarning((messagehdlr), "SoPlex threw an exception: %s\n", s.c_str()); \
    152 return SCIP_LPERROR; \
    153 } \
    154 } \
    155 while( FALSE )
    156
    157#else
    158#define SOPLEX_TRY(messagehdlr, x) do \
    159 { \
    160 try \
    161 { \
    162 (x); \
    163 } \
    164 catch( const SPxMemoryException& E ) \
    165 { \
    166 std::string s = E.what(); \
    167 SCIPerrorMessage("SoPlex threw a memory exception: %s\n", s.c_str()); \
    168 return SCIP_ERROR; \
    169 } \
    170 catch( const SPxException& ) \
    171 { \
    172 return SCIP_LPERROR; \
    173 } \
    174 } \
    175 while( FALSE )
    176#endif
    177
    178/* Macro for a single SoPlex call for which exceptions have to be catched - abort if they
    179 * arise. SCIP_ABORT() is not accessible here.
    180 */
    181#define SOPLEX_TRY_ABORT(x) do \
    182 { \
    183 try \
    184 { \
    185 (x); \
    186 } \
    187 catch( const SPxException& E ) \
    188 { \
    189 std::string s = E.what(); \
    190 SCIPerrorMessage("SoPlex threw an exception: %s\n", s.c_str()); \
    191 abort(); \
    192 } \
    193 } \
    194 while( FALSE )
    195
    196/* Set the value of a SCIP_RATIONAL* from a SoPlex Rational */
    197static void RsetSpxR(
    198 SCIP_LPIEXACT* lpi, /**< exact lpi*/
    199 SCIP_RATIONAL* r, /**< scip rational */
    200 const soplex::Rational& spxr /**< soplex rational */
    201 )
    202{
    203 if( SCIPlpiExactIsInfinity(lpi, double(spxr)) )
    205 else if( SCIPlpiExactIsInfinity(lpi, -double(spxr)) )
    207 else
    208 {
    209#if defined(SCIP_WITH_BOOST) && defined(SCIP_WITH_GMP)
    210 r->val = spxr;
    211#else
    212 r->val = (double) spxr;
    213#endif
    214 r->isinf = FALSE;
    215 r->isfprepresentable = SCIP_ISFPREPRESENTABLE_UNKNOWN;
    216 }
    217}
    218
    219/* Set the value of a SoPlex Rational vector from a SCIP_RATIONAL** */
    220static void RsetSpxVector(
    221 SCIP_LPIEXACT* lpi, /**< exact LPI */
    222 SCIP_RATIONAL** r, /**< SCIP_RATIONAL array */
    223 VectorRational src /**< SoPlex rational vector */
    224 )
    225{
    226 for( int i = 0; i < src.dim(); ++i )
    227 {
    228 assert(r[i] != NULL);
    229
    230 RsetSpxR(lpi, r[i], src[i]);
    231 }
    232}
    233
    234/** set the value of a SoPlex rational from a SCIP_RATIONAL */
    235static void SpxRSetRat(
    236 SCIP_LPIEXACT* lpi, /**< exact LPI */
    237 soplex::Rational& spxr, /**< SoPlex Rational*/
    238 SCIP_RATIONAL* src /**< SCIP_RATIONAL */
    239 )
    240{
    242 {
    243 if( SCIPrationalIsPositive(src) )
    244 spxr = soplex::Rational(SCIPlpiExactInfinity(lpi));
    245 else
    246 spxr = soplex::Rational(-SCIPlpiExactInfinity(lpi));
    247 }
    248 else
    249 {
    250#if defined(SOPLEX_WITH_GMP) && defined(SCIP_WITH_BOOST) && defined(SCIP_WITH_GMP)
    251 spxr = soplex::Rational(*SCIPrationalGetGMP(src));
    252#else
    253 spxr = soplex::Rational(SCIPrationalGetReal(src));
    254#endif
    255 }
    256}
    257
    258
    259
    260/** SCIP's SoPlex class */
    261class SPxexSCIP : public SoPlex
    262{/*lint !e1790*/
    263 bool _lpinfo;
    264 bool _fromscratch;
    265 char* _probname;
    266 DataArray<SPxSolver::VarStatus> _colStat; /**< column basis status used for strong branching */
    267 DataArray<SPxSolver::VarStatus> _rowStat; /**< row basis status used for strong branching */
    268 SCIP_MESSAGEHDLR* _messagehdlr; /**< messagehdlr handler for printing messages, or NULL */
    269
    270public:
    271 explicit SPxexSCIP(
    272 SCIP_MESSAGEHDLR* messagehdlr = NULL, /**< message handler */
    273 const char* probname = NULL /**< name of problem */
    274 )
    275 : _lpinfo(false),
    276 _fromscratch(false),
    277 _probname(NULL),
    278 _colStat(0),
    279 _rowStat(0),
    280 _messagehdlr(messagehdlr)
    281 {
    282 if ( probname != NULL )
    283 SOPLEX_TRY_ABORT( setProbname(probname) );
    284
    285#if SOPLEX_APIVERSION >= 2
    286 (void) setBoolParam(SoPlex::ENSURERAY, true);
    287#endif
    288 }
    289
    290 virtual ~SPxexSCIP()
    291 {
    292 if( _probname != NULL )
    293 spx_free(_probname); /*lint !e1551*/
    294
    295 freePreStrongbranchingBasis(); /*lint !e1551*/
    296 }/*lint -e1579*/
    297
    298 /** get objective limit according to objective sense */
    299 Real getObjLimit() const
    300 {
    301 return (intParam(SoPlex::OBJSENSE) == SoPlex::OBJSENSE_MINIMIZE)
    302 ? realParam(SoPlex::OBJLIMIT_UPPER)
    303 : realParam(SoPlex::OBJLIMIT_LOWER);
    304 }
    305
    306 // @todo realize this with a member variable as before
    307 bool getFromScratch() const
    308 {
    309 return _fromscratch;
    310 }
    311
    312 void setFromScratch(bool fs)
    313 {
    314 _fromscratch = fs;
    315 }
    316
    317 // @todo member variable?
    318 bool getLpInfo() const
    319 {
    320 return _lpinfo;
    321 }
    322
    323 void setLpInfo(bool lpinfo)
    324 {
    325 _lpinfo = lpinfo;
    326 }
    327
    328 // @todo member variable?
    329 void setProbname(const char* probname)
    330 {
    331 size_t len;
    332
    333 assert(probname != NULL);
    334 if( _probname != NULL )
    335 spx_free(_probname);
    336
    337 len = strlen(probname);
    338 spx_alloc(_probname, (int) len + 1);
    339 memcpy(_probname, probname, len + 1);
    340 }
    341
    342 void setRep(SPxSolver::Representation p_rep)
    343 {
    344 if( p_rep == SPxSolver::COLUMN && intParam(SoPlex::REPRESENTATION) == SoPlex::REPRESENTATION_ROW )
    345 {
    346 SCIPdebugMessage("switching to column representation of the basis\n");
    347 CHECK_SOPLEX_PARAM(setIntParam(SoPlex::REPRESENTATION, (int) SoPlex::REPRESENTATION_COLUMN));
    348 }
    349 else if( (p_rep == SPxSolver::ROW && intParam(SoPlex::REPRESENTATION) == SoPlex::REPRESENTATION_COLUMN) )
    350 {
    351 SCIPdebugMessage("switching to row representation of the basis\n");
    352 CHECK_SOPLEX_PARAM(setIntParam(SoPlex::REPRESENTATION, (int) SoPlex::REPRESENTATION_ROW));
    353 }
    354 }
    355
    356#ifndef NDEBUG
    358 {
    359 for( int i = 0; i < numColsRational(); ++i )
    360 {
    361 if( lowerRational(i) > upperRational(i) )
    362 {
    363 SCIPerrorMessage("inconsistent bounds on column %d: lower=%s, upper=%s\n",
    364 i, lowerRational(i).str().c_str(), upperRational(i).str().c_str());
    365 return false;
    366 }
    367 }
    368
    369 return true;
    370 }
    371
    373 {
    374 for( int i = 0; i < numRowsRational(); ++i )
    375 {
    376 if( lhsRational(i) > rhsRational(i) )
    377 {
    378 SCIPerrorMessage("inconsistent sides on row %d: lhs=%s, rhs=%s\n",
    379 i, lhsRational(i).str().c_str(), rhsRational(i).str().c_str());
    380 return false;
    381 }
    382 }
    383
    384 return true;
    385 }
    386#endif
    387
    388 void trySolve(bool printwarning = true)
    389 {
    390 Real timespent;
    391 Real timelimit;
    392
    393 try
    394 {
    395 (void) optimize();
    396 }
    397 catch(const SPxException& x)
    398 {
    399 std::string s = x.what();
    400 if( printwarning )
    401 {
    402 SCIPmessagePrintWarning(_messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
    403 }
    404
    405 /* since it is not clear if the status in SoPlex are set correctly
    406 * we want to make sure that if an error is thrown the status is
    407 * not OPTIMAL anymore.
    408 */
    409 assert(status() != SPxSolver::OPTIMAL);
    410 }
    411
    412 assert(intParam(ITERLIMIT) < 0 || numIterations() <= intParam(ITERLIMIT));
    413
    414 /* update time limit */
    415 timespent = solveTime();
    416 if( timespent > 0 )
    417 {
    418 /* get current time limit */
    419 timelimit = realParam(TIMELIMIT);
    420 if( timelimit > timespent )
    421 timelimit -= timespent;
    422 else
    423 timelimit = 0;
    424 /* set new time limit */
    425 assert(timelimit >= 0);
    426 CHECK_SOPLEX_PARAM(setRealParam(TIMELIMIT, timelimit));
    427 }
    428 }
    429
    430 SPxSolver::Status doSolve(bool printwarning = true)
    431 {
    432 SPxOut::Verbosity verbosity;
    433
    434 SPxSolver::Status spxStatus;
    435
    436 /* store and set verbosity */
    437 verbosity = spxout.getVerbosity();
    438 spxout.setVerbosity((SPxOut::Verbosity)(getLpInfo() ? SOPLEX_VERBLEVEL : 0));
    439
    440 assert(checkConsistentBounds());
    441 assert(checkConsistentSides());
    442
    443 trySolve(printwarning);
    444 spxStatus = status();
    445
    446 /* restore verbosity */
    447 spxout.setVerbosity(verbosity);
    448
    449 return spxStatus;
    450 }
    451
    452 /** save the current basis */
    454 {
    455 _rowStat.reSize(numRowsRational());
    456 _colStat.reSize(numColsRational());
    457
    458 try
    459 {
    460 getBasis(_rowStat.get_ptr(), _colStat.get_ptr());
    461 }
    462#ifndef NDEBUG
    463 catch(const SPxException& x)
    464 {
    465 std::string s = x.what();
    466 SCIPmessagePrintWarning(_messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
    467
    468 /* since it is not clear if the status in SoPlex are set correctly
    469 * we want to make sure that if an error is thrown the status is
    470 * not OPTIMAL anymore.
    471 */
    472 assert(status() != SPxSolver::OPTIMAL);
    473 }
    474#else
    475 catch(const SPxException&)
    476 { }
    477#endif
    478 }
    479
    480 /** restore basis */
    482 {
    483 assert(_rowStat.size() == numRowsRational());
    484 assert(_colStat.size() == numColsRational());
    485
    486 try
    487 {
    488 setBasis(_rowStat.get_ptr(), _colStat.get_ptr());
    489 }
    490#ifndef NDEBUG
    491 catch(const SPxException& x)
    492 {
    493 std::string s = x.what();
    494 SCIPmessagePrintWarning(_messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
    495#else
    496 catch(const SPxException&)
    497 {
    498#endif
    499 /* since it is not clear if the status in SoPlex are set correctly
    500 * we want to make sure that if an error is thrown the status is
    501 * not OPTIMAL anymore.
    502 */
    503 assert(status() != SPxSolver::OPTIMAL);
    504 }
    505 }
    506
    507 /** if basis is in store, delete it without restoring it */
    509 {
    510 _rowStat.clear();
    511 _colStat.clear();
    512 }
    513
    514 /** is pre-strong-branching basis freed? */
    516 {
    517 return ((_rowStat.size() == 0 ) && (_colStat.size() == 0));
    518 }
    519
    520 /** provides access for temporary storage of basis status of rows */
    521 DataArray<SPxSolver::VarStatus>& rowStat()
    522 {
    523 return _rowStat; /*lint !e1536*/
    524 }
    525
    526 /** provides access for temporary storage of basis status or columns */
    527 DataArray<SPxSolver::VarStatus>& colStat()
    528 {
    529 return _colStat; /*lint !e1536*/
    530 }
    531
    532}; /*lint !e1748*/
    533
    534
    535
    536
    537/********************************************************************/
    538/*----------------------------- C --------------------------------*/
    539/********************************************************************/
    540
    541#include "lpiexact/lpiexact.h"
    542#include "scip/bitencode.h"
    543
    544typedef SCIP_DUALPACKET COLPACKET; /* each column needs two bits of information (basic/on_lower/on_upper) */
    545#define COLS_PER_PACKET SCIP_DUALPACKETSIZE
    546typedef SCIP_DUALPACKET ROWPACKET; /* each row needs two bit of information (basic/on_lower/on_upper) */
    547#define ROWS_PER_PACKET SCIP_DUALPACKETSIZE
    548
    549
    550
    551/** LP interface */
    552struct SCIP_LPiExact
    553{
    554 SPxexSCIP* spx; /**< our SoPlex implementation */
    555 int* cstat; /**< array for storing column basis status */
    556 int* rstat; /**< array for storing row basis status */
    557 int cstatsize; /**< size of cstat array */
    558 int rstatsize; /**< size of rstat array */
    559 SCIP_PRICING pricing; /**< current pricing strategy */
    560 SCIP_Bool solved; /**< was the current LP solved? */
    561 SCIP_Real conditionlimit; /**< maximum condition number of LP basis counted as stable (-1.0: no limit) */
    562 SCIP_Bool checkcondition; /**< should condition number of LP basis be checked for stability? */
    563 SCIP_MESSAGEHDLR* messagehdlr; /**< messagehdlr handler to printing messages, or NULL */
    564};
    565
    566/** LPi state stores basis information */
    567struct SCIP_LPiState
    568{
    569 int ncols; /**< number of LP columns */
    570 int nrows; /**< number of LP rows */
    571 COLPACKET* packcstat; /**< column basis status in compressed form */
    572 ROWPACKET* packrstat; /**< row basis status in compressed form */
    573};
    574
    575
    576/*
    577 * dynamic memory arrays
    578 */
    579
    580/** resizes cstat array to have at least num entries */
    581static
    583 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    584 int num /**< minimal number of entries in array */
    585 )
    586{
    587 assert(lpi != NULL);
    588
    589 if( num > lpi->cstatsize )
    590 {
    591 int newsize;
    592
    593 newsize = MAX(2*lpi->cstatsize, num);
    594 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->cstat, newsize) );
    595 lpi->cstatsize = newsize;
    596 }
    597 assert(num <= lpi->cstatsize);
    598
    599 return SCIP_OKAY;
    600}
    601
    602/** resizes rstat array to have at least num entries */
    603static
    605 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    606 int num /**< minimal number of entries in array */
    607 )
    608{
    609 assert(lpi != NULL);
    610
    611 if( num > lpi->rstatsize )
    612 {
    613 int newsize;
    614
    615 newsize = MAX(2*lpi->rstatsize, num);
    616 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rstat, newsize) );
    617 lpi->rstatsize = newsize;
    618 }
    619 assert(num <= lpi->rstatsize);
    620
    621 return SCIP_OKAY;
    622}
    623
    624
    625
    626
    627/*
    628 * LPi state methods
    629 */
    630
    631/** returns the number of packets needed to store column packet information */
    632static
    634 int ncols /**< number of columns to store */
    635 )
    636{
    637 return (ncols+(int)COLS_PER_PACKET-1)/(int)COLS_PER_PACKET;
    638}
    639
    640/** returns the number of packets needed to store row packet information */
    641static
    643 int nrows /**< number of rows to store */
    644 )
    645{
    646 return (nrows+(int)ROWS_PER_PACKET-1)/(int)ROWS_PER_PACKET;
    647}
    648
    649/** store row and column basis status in a packed LPi state object */
    650static
    652 SCIP_LPISTATE* lpistate, /**< pointer to LPi state data */
    653 const int* cstat, /**< basis status of columns in unpacked format */
    654 const int* rstat /**< basis status of rows in unpacked format */
    655 )
    656{
    657 assert(lpistate != NULL);
    658 assert(lpistate->packcstat != NULL);
    659 assert(lpistate->packrstat != NULL);
    660
    661 SCIPencodeDualBit(cstat, lpistate->packcstat, lpistate->ncols);
    662 SCIPencodeDualBit(rstat, lpistate->packrstat, lpistate->nrows);
    663}
    664
    665/** unpacks row and column basis status from a packed LPi state object */
    666static
    668 const SCIP_LPISTATE* lpistate, /**< pointer to LPi state data */
    669 int* cstat, /**< buffer for storing basis status of columns in unpacked format */
    670 int* rstat /**< buffer for storing basis status of rows in unpacked format */
    671 )
    672{
    673 assert(lpistate != NULL);
    674 assert(lpistate->packcstat != NULL);
    675 assert(lpistate->packrstat != NULL);
    676
    677 SCIPdecodeDualBit(lpistate->packcstat, cstat, lpistate->ncols);
    678 SCIPdecodeDualBit(lpistate->packrstat, rstat, lpistate->nrows);
    679}
    680
    681/** creates LPi state information object */
    682static
    684 SCIP_LPISTATE** lpistate, /**< pointer to LPi state */
    685 BMS_BLKMEM* blkmem, /**< block memory */
    686 int ncols, /**< number of columns to store */
    687 int nrows /**< number of rows to store */
    688 )
    689{
    690 assert(lpistate != NULL);
    691 assert(blkmem != NULL);
    692 assert(ncols >= 0);
    693 assert(nrows >= 0);
    694
    695 int nColPackets = colpacketNum(ncols);
    696 int nRowPackets = rowpacketNum(nrows);
    697
    698 SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpistate) );
    699 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->packcstat, nColPackets) );
    700 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->packrstat, nRowPackets) );
    701
    702 return SCIP_OKAY;
    703}
    704
    705/** frees LPi state information */
    706static
    708 SCIP_LPISTATE** lpistate, /**< pointer to LPi state information (like basis information) */
    709 BMS_BLKMEM* blkmem /**< block memory */
    710 )
    711{
    712 assert(blkmem != NULL);
    713 assert(lpistate != NULL);
    714 assert(*lpistate != NULL);
    715
    716 int nColPackets = colpacketNum((*lpistate)->ncols);
    717 int nRowPackets = rowpacketNum((*lpistate)->nrows);
    718
    719 BMSfreeBlockMemoryArray(blkmem, &(*lpistate)->packcstat, nColPackets);
    720 BMSfreeBlockMemoryArray(blkmem, &(*lpistate)->packrstat, nRowPackets);
    721 BMSfreeBlockMemory(blkmem, lpistate);
    722}
    723
    724
    725
    726
    727/*
    728 * local methods
    729 */
    730
    731
    732/** marks the current LP to be unsolved */
    733static
    735{
    736 assert(lpi != NULL);
    737 lpi->solved = FALSE;
    738}
    739
    740
    741
    742/*
    743 * LP Interface Methods
    744 */
    745
    746
    747/*
    748 * Miscellaneous Methods
    749 */
    750
    751#if (SOPLEX_SUBVERSION > 0)
    752 const static char spxname[20] = {'S', 'o', 'P', 'l', 'e', 'x', ' ', SOPLEX_VERSION/100 + '0', '.', (SOPLEX_VERSION % 100)/10 + '0', '.', SOPLEX_VERSION % 10 + '0', '.', SOPLEX_SUBVERSION + '0', '\0'};
    753#else
    754 const static char spxname[20] = {'S', 'o', 'P', 'l', 'e', 'x', ' ', SOPLEX_VERSION/100 + '0', '.', (SOPLEX_VERSION % 100)/10 + '0', '.', SOPLEX_VERSION % 10 + '0', '\0'};
    755#endif
    756const static char spxdesc[200] = {'L', 'i', 'n', 'e', 'a', 'r', ' ', 'p', 'r', 'o', 'g', 'r', 'a', 'm', 'm', 'i', 'n', 'g',
    757 ' ', 's', 'o', 'l', 'v', 'e', 'r', ' ' , 'd', 'e', 'v', 'e', 'l', 'o', 'p', 'e', 'd',
    758 ' ', 'a', 't', ' ', 'Z', 'u', 's', 'e', ' ', 'I', 'n', 's', 't', 'i', 't', 'u', 't', 'e',
    759 ' ', 'B', 'e', 'r', 'l', 'i', 'n', ' ', '(', 's', 'o', 'p', 'l', 'e', 'x', '.', 'z', 'i', 'b', '.', 'd', 'e', ')',
    760 ' ', '[', 'G', 'i', 't', 'H', 'a', 's', 'h', ':', ' ',
    761 getGitHash()[0], getGitHash()[1], getGitHash()[2], getGitHash()[3],
    762 getGitHash()[4], getGitHash()[5], getGitHash()[6], getGitHash()[7],
    763 ']', '\0'};
    764
    765/**@name Miscellaneous Methods */
    766/**@{ */
    767
    768/** gets name and version of LP solver */
    770 void
    771 )
    772{
    773 SCIPdebugMessage("calling SCIPlpiExactGetSolverName()\n");
    774 return spxname;
    775}
    776
    777/** gets description of LP solver (developer, webpage, ...) */
    779 void
    780 )
    781{
    782 return spxdesc;
    783}
    784
    785/** gets pointer for LP solver - use only with great care */
    787 SCIP_LPIEXACT* lpi /**< pointer to an LP interface structure */
    788 )
    789{
    790 return (void*) lpi->spx;
    791}
    792
    793/** pass integrality information about variables to the solver */
    795 SCIP_LPIEXACT* lpi, /**< pointer to an LP interface structure */
    796 int ncols, /**< length of integrality array */
    797 int* intInfo /**< integrality array (0: continuous, 1: integer). May be NULL iff ncols is 0. */
    798 )
    799{
    800 assert(ncols == lpi->spx->numColsRational() || (ncols == 0 && intInfo == NULL));
    801 lpi->spx->setIntegralityInformation(ncols, intInfo);
    802 return SCIP_OKAY;
    803}
    804
    805/** informs about availability of a primal simplex solving method */
    807 void
    808 )
    809{
    810 return TRUE;
    811}
    812
    813/** informs about availability of a dual simplex solving method */
    815 void
    816 )
    817{
    818 return TRUE;
    819}
    820
    821/** informs about availability of a barrier solving method */
    823 void
    824 )
    825{
    826 return FALSE;
    827}
    828
    829/**@} */
    830
    831
    832/*
    833 * LPI Creation and Destruction Methods
    834 */
    835
    836/**@name LPI Creation and Destruction Methods */
    837/**@{ */
    838
    839/** creates an LP problem object */
    841 SCIP_LPIEXACT** lpi, /**< pointer to an LP interface structure */
    842 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler to use for printing messages, or NULL */
    843 const char* name, /**< problem name */
    844 SCIP_OBJSEN objsen /**< objective sense */
    845 )
    846{
    847 assert(lpi != NULL);
    848 assert(name != NULL);
    849
    850 /* create SoPlex object */
    852
    853 /* we use this construction to allocate the memory for the SoPlex class also via the blockmemshell */
    854 (*lpi)->spx = static_cast<SPxexSCIP*>(BMSallocMemoryCPP(sizeof(SPxexSCIP)));
    855 SOPLEX_TRY( messagehdlr, (*lpi)->spx = new ((*lpi)->spx) SPxexSCIP(messagehdlr, name) );
    856 (void) (*lpi)->spx->setIntParam(SoPlex::SYNCMODE, (int) SoPlex::SYNCMODE_AUTO);
    857 (void) (*lpi)->spx->setIntParam(SoPlex::SOLVEMODE, (int) SoPlex::SOLVEMODE_RATIONAL);
    858 (void) (*lpi)->spx->setRealParam(SoPlex::FEASTOL, 0.0, true);
    859 (void) (*lpi)->spx->setRealParam(SoPlex::OPTTOL, 0.0, true);
    860 (void) (*lpi)->spx->setBoolParam(SoPlex::FORCEBASIC, true);
    861
    862 (*lpi)->cstat = NULL;
    863 (*lpi)->rstat = NULL;
    864 (*lpi)->cstatsize = 0;
    865 (*lpi)->rstatsize = 0;
    866 (*lpi)->pricing = SCIP_PRICING_LPIDEFAULT;
    867 (*lpi)->conditionlimit = -1.0;
    868 (*lpi)->checkcondition = FALSE;
    869 (*lpi)->messagehdlr = messagehdlr;
    870
    871 invalidateSolution(*lpi);
    872
    873 /* set objective sense */
    874 SCIP_CALL( SCIPlpiExactChgObjsen(*lpi, objsen) );
    875
    876 /* set default pricing */
    877 SCIP_CALL( SCIPlpiExactSetIntpar(*lpi, SCIP_LPPAR_PRICING, (int)(*lpi)->pricing) );
    878
    879 {
    880 SPxOut::Verbosity verbosity = (*lpi)->spx->spxout.getVerbosity();
    881 (*lpi)->spx->spxout.setVerbosity((SPxOut::Verbosity)((*lpi)->spx->getLpInfo() ? SOPLEX_VERBLEVEL : 0));
    882 (*lpi)->spx->printVersion();
    883 (*lpi)->spx->spxout.setVerbosity(verbosity);
    884 }
    885
    886 return SCIP_OKAY;
    887}
    888
    889/** deletes an LP problem object */
    891 SCIP_LPIEXACT** lpi /**< pointer to an LP interface structure */
    892 )
    893{
    894 assert(lpi != NULL);
    895 assert(*lpi != NULL);
    896 assert((*lpi)->spx != NULL);
    897
    898 /* free LP using destructor and free memory via blockmemshell */
    899 (*lpi)->spx->~SPxexSCIP();
    900 BMSfreeMemory(&((*lpi)->spx));
    901
    902 /* free memory */
    903 BMSfreeMemoryArrayNull(&(*lpi)->cstat);
    904 BMSfreeMemoryArrayNull(&(*lpi)->rstat);
    905 BMSfreeMemory(lpi);
    906
    907 return SCIP_OKAY;
    908}
    909
    910/**@} */
    911
    912
    913/*
    914 * Modification Methods
    915 */
    916
    917/**@name Modification Methods */
    918/**@{ */
    919
    920/** copies LP data with column matrix into LP solver */
    922 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    923 SCIP_OBJSEN objsen, /**< objective sense */
    924 int ncols, /**< number of columns */
    925 SCIP_RATIONAL** obj, /**< objective function values of columns */
    926 SCIP_RATIONAL** lb, /**< lower bounds of columns */
    927 SCIP_RATIONAL** ub, /**< upper bounds of columns */
    928 char** colnames, /**< column names, or NULL */
    929 int nrows, /**< number of rows */
    930 SCIP_RATIONAL** lhs, /**< left hand sides of rows */
    931 SCIP_RATIONAL** rhs, /**< right hand sides of rows */
    932 char** /*rownames*/, /**< row names, or NULL */
    933 int nnonz, /**< number of nonzero elements in the constraint matrix */
    934 int* beg, /**< start index of each column in ind- and val-array */
    935 int* ind, /**< row indices of constraint matrix entries */
    936 SCIP_RATIONAL** val /**< values of constraint matrix entries */
    937 )
    938{
    939#ifndef NDEBUG
    940 {
    941 int j;
    942 for( j = 0; j < nnonz; j++ )
    943 {
    944 assert(val[j] != NULL);
    945 assert(!SCIPrationalIsZero(val[j]));
    946 }
    947 }
    948#endif
    949
    950 SCIPdebugMessage("calling SCIPlpiExactLoadColLP()\n");
    951
    952 assert(lpi != NULL);
    953 assert(lpi->spx != NULL);
    954 assert(lhs != NULL);
    955 assert(rhs != NULL);
    956 assert(obj != NULL);
    957 assert(lb != NULL);
    958 assert(ub != NULL);
    959 assert(beg != NULL);
    960 assert(ind != NULL);
    961 assert(val != NULL);
    962
    964 assert(lpi->spx->preStrongbranchingBasisFreed());
    965
    966 try
    967 {
    968 SPxexSCIP* spx = lpi->spx;
    969 LPRowSetRational rows(nrows);
    970 DSVectorRational emptyVector(0);
    971 int i;
    972
    973 spx->clearLPRational();
    974
    975 /* set objective sense */
    976 (void) spx->setIntParam(SoPlex::OBJSENSE, (int) (objsen == SCIP_OBJSEN_MINIMIZE ? SoPlex::OBJSENSE_MINIMIZE : SoPlex::OBJSENSE_MAXIMIZE));
    977
    978 /* create empty rows with given sides */
    979 for( i = 0; i < nrows; ++i )
    980 {
    981 soplex::Rational spxlhs;
    982 soplex::Rational spxrhs;
    983 SpxRSetRat(lpi, spxlhs, lhs[i]);
    984 SpxRSetRat(lpi, spxlhs, rhs[i]);
    985 rows.add(spxlhs, emptyVector, spxrhs);
    986 }
    987 spx->addRowsRational(rows);
    988
    989 /* create column vectors with coefficients and bounds */
    990 SCIP_CALL( SCIPlpiExactAddCols(lpi, ncols, obj, lb, ub, colnames, nnonz, beg, ind, val) );
    991 //spx->syncLPReal();
    992 }
    993#ifndef NDEBUG
    994 catch( const SPxException& x )
    995 {
    996 std::string s = x.what();
    997 SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
    998#else
    999 catch( const SPxException& )
    1000 {
    1001#endif
    1002 return SCIP_LPERROR;
    1003 }
    1004
    1005 return SCIP_OKAY;
    1006}
    1007
    1008/** adds columns to the LP */
    1010 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    1011 int ncols, /**< number of columns to be added */
    1012 SCIP_RATIONAL** obj, /**< objective function values of new columns */
    1013 SCIP_RATIONAL** lb, /**< lower bounds of new columns */
    1014 SCIP_RATIONAL** ub, /**< upper bounds of new columns */
    1015 char** colnames, /**< column names, or NULL */
    1016 int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
    1017 int* beg, /**< start index of each column in ind- and val-array, or NULL if nnonz == 0 */
    1018 int* ind, /**< row indices of constraint matrix entries, or NULL if nnonz == 0 */
    1019 SCIP_RATIONAL** val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
    1020 )
    1021{ /*lint --e{715}*/
    1022 SCIPdebugMessage("calling SCIPlpiAddCols()\n");
    1023
    1024 assert(lpi != NULL);
    1025 assert(lpi->spx != NULL);
    1026 assert(obj != NULL);
    1027 assert(lb != NULL);
    1028 assert(ub != NULL);
    1029 assert(nnonz == 0 || beg != NULL);
    1030 assert(nnonz == 0 || ind != NULL);
    1031 assert(nnonz == 0 || val != NULL);
    1032 assert(nnonz >= 0);
    1033 assert(ncols >= 0);
    1034
    1035 invalidateSolution(lpi);
    1036
    1037 assert( lpi->spx->preStrongbranchingBasisFreed() );
    1038
    1039#ifndef NDEBUG
    1040 if ( nnonz > 0 )
    1041 {
    1042 /* perform check that no new rows are added - this is likely to be a mistake */
    1043 int nrows = lpi->spx->numRowsRational();
    1044 for (int j = 0; j < nnonz; ++j)
    1045 {
    1046 assert( 0 <= ind[j] && ind[j] < nrows );
    1047 assert( val[j] != NULL );
    1048 assert( !SCIPrationalIsZero(val[j]) );
    1049 }
    1050 }
    1051#endif
    1052
    1053 SPxexSCIP* spx = lpi->spx;
    1054 try
    1055 {
    1056 LPColSetRational cols(ncols);
    1057 DSVectorRational colVector(ncols);
    1058 int start;
    1059 int last;
    1060 int i;
    1061
    1062 /* create column vectors with coefficients and bounds */
    1063 for( i = 0; i < ncols; ++i )
    1064 {
    1065 int j;
    1066 soplex::Rational spxlb;
    1067 soplex::Rational spxub;
    1068 soplex::Rational spxobj;
    1069 std::vector<soplex::Rational> spxval;
    1070
    1071 SpxRSetRat(lpi, spxlb, lb[i]);
    1072 SpxRSetRat(lpi, spxub, ub[i]);
    1073 SpxRSetRat(lpi, spxobj, obj[i]);
    1074
    1075 colVector.clear();
    1076 if( nnonz > 0 )
    1077 {
    1078 soplex::Rational tmp;
    1079
    1080 start = beg[i];
    1081 last = (i == ncols-1 ? nnonz : beg[i+1]);
    1082 spxval.reserve((size_t) (last - start));
    1083 for( j = start; j < last; ++j )
    1084 {
    1085 spxval.push_back(tmp);
    1086 SpxRSetRat(lpi, spxval[(size_t) (j - start)], val[j]);
    1087 }
    1088 colVector.add(last - start, ind + start, spxval.data());
    1089 }
    1090 cols.add(spxobj, spxlb, colVector, spxub);
    1091 }
    1092 spx->addColsRational(cols);
    1093 }
    1094#ifndef NDEBUG
    1095 catch( const SPxException& x )
    1096 {
    1097 std::string s = x.what();
    1098 SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
    1099#else
    1100 catch( const SPxException& )
    1101 {
    1102#endif
    1103 return SCIP_LPERROR;
    1104 }
    1105
    1106 return SCIP_OKAY;
    1107}
    1108
    1109/** deletes all columns in the given range from LP */
    1111 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    1112 int firstcol, /**< first column to be deleted */
    1113 int lastcol /**< last column to be deleted */
    1114 )
    1115{
    1116 SCIPdebugMessage("calling SCIPlpiDelCols()\n");
    1117
    1118 assert(lpi != NULL);
    1119 assert(lpi->spx != NULL);
    1120 assert(0 <= firstcol && firstcol <= lastcol && lastcol < lpi->spx->numColsRational());
    1121
    1122 invalidateSolution(lpi);
    1123
    1124 assert( lpi->spx->preStrongbranchingBasisFreed() );
    1125
    1126 SOPLEX_TRY( lpi->messagehdlr, lpi->spx->removeColRangeRational(firstcol, lastcol) );
    1127
    1128 return SCIP_OKAY;
    1129}
    1130
    1131/** deletes columns from SCIP_LP; the new position of a column must not be greater that its old position */
    1133 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    1134 int* dstat /**< deletion status of columns
    1135 * input: 1 if column should be deleted, 0 if not
    1136 * output: new position of column, -1 if column was deleted */
    1137 )
    1138{
    1139 int ncols;
    1140 int i;
    1141
    1142 SCIPdebugMessage("calling SCIPlpiDelColset()\n");
    1143
    1144 assert(lpi != NULL);
    1145 assert(lpi->spx != NULL);
    1146 assert(dstat != NULL);
    1147
    1148 invalidateSolution(lpi);
    1149
    1150 assert( lpi->spx->preStrongbranchingBasisFreed() );
    1151
    1152 ncols = lpi->spx->numColsRational();
    1153
    1154 /* SoPlex removeCols() method deletes the columns with dstat[i] < 0, so we have to negate the values */
    1155 for( i = 0; i < ncols; ++i )
    1156 dstat[i] *= -1;
    1157
    1158 SOPLEX_TRY( lpi->messagehdlr, lpi->spx->removeColsRational(dstat) );
    1159
    1160 return SCIP_OKAY;
    1161}
    1162
    1163/** adds rows to the LP */
    1165 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    1166 int nrows, /**< number of rows to be added */
    1167 SCIP_RATIONAL** lhs, /**< left hand sides of new rows */
    1168 SCIP_RATIONAL** rhs, /**< right hand sides of new rows */
    1169 char** rownames, /**< row names, or NULL */
    1170 int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
    1171 int* beg, /**< start index of each row in ind- and val-array, or NULL if nnonz == 0 */
    1172 int* ind, /**< column indices of constraint matrix entries, or NULL if nnonz == 0 */
    1173 SCIP_RATIONAL** val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
    1174 )
    1175{ /*lint --e{715}*/
    1176 SCIPdebugMessage("calling SCIPlpiAddRows()\n");
    1177
    1178 assert(lpi != NULL);
    1179 assert(lpi->spx != NULL);
    1180 assert(lhs != NULL);
    1181 assert(rhs != NULL);
    1182 assert(nnonz == 0 || beg != NULL);
    1183 assert(nnonz == 0 || ind != NULL);
    1184 assert(nnonz == 0 || val != NULL);
    1185
    1186 invalidateSolution(lpi);
    1187
    1188 assert( lpi->spx->preStrongbranchingBasisFreed() );
    1189
    1190#ifndef NDEBUG
    1191 if ( nnonz > 0 )
    1192 {
    1193 /* perform check that no new columns are added - this is likely to be a mistake */
    1194 int ncols = lpi->spx->numColsRational();
    1195 for (int j = 0; j < nnonz; ++j)
    1196 {
    1197 assert( !SCIPrationalIsZero(val[j]) );
    1198 assert( 0 <= ind[j] && ind[j] < ncols );
    1199 }
    1200 }
    1201#endif
    1202
    1203 try
    1204 {
    1205 SPxexSCIP* spx = lpi->spx;
    1206 LPRowSetRational rows(nrows);
    1207 DSVectorRational rowVector;
    1208 int start;
    1209 int last;
    1210 int i;
    1211
    1212 /* create row vectors with given sides */
    1213 for( i = 0; i < nrows; ++i )
    1214 {
    1215 soplex::Rational spxlhs;
    1216 soplex::Rational spxrhs;
    1217 std::vector<soplex::Rational> spxval;
    1218
    1219 SpxRSetRat(lpi, spxlhs, lhs[i]);
    1220 SpxRSetRat(lpi, spxrhs, rhs[i]);
    1221
    1222 rowVector.clear();
    1223 if( nnonz > 0 )
    1224 {
    1225 start = beg[i];
    1226 last = (i == nrows-1 ? nnonz : beg[i+1]);
    1227 spxval.reserve((size_t) (last - start));
    1228
    1229 for( int j = start; j < last; ++j )
    1230 {
    1231 soplex::Rational tmp;
    1232 spxval.push_back(tmp);
    1233 SpxRSetRat(lpi, spxval[(size_t) (j - start)], val[j]);
    1234 }
    1235 rowVector.add(last - start, ind + start, spxval.data());
    1236 }
    1237 rows.add(spxlhs, rowVector, spxrhs);
    1238 }
    1239 spx->addRowsRational(rows);
    1240 }
    1241#ifndef NDEBUG
    1242 catch( const SPxException& x )
    1243 {
    1244 std::string s = x.what();
    1245 SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
    1246#else
    1247 catch( const SPxException& )
    1248 {
    1249#endif
    1250 return SCIP_LPERROR;
    1251 }
    1252
    1253 return SCIP_OKAY;
    1254}
    1255
    1256/** deletes all rows in the given range from LP */
    1258 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    1259 int firstrow, /**< first row to be deleted */
    1260 int lastrow /**< last row to be deleted */
    1261 )
    1262{
    1263 SCIPdebugMessage("calling SCIPlpiDelRows()\n");
    1264
    1265 assert(lpi != NULL);
    1266 assert(lpi->spx != NULL);
    1267 assert(0 <= firstrow && firstrow <= lastrow && lastrow < lpi->spx->numRowsRational());
    1268
    1269 invalidateSolution(lpi);
    1270
    1271 assert( lpi->spx->preStrongbranchingBasisFreed() );
    1272
    1273 SOPLEX_TRY( lpi->messagehdlr, lpi->spx->removeRowRangeRational(firstrow, lastrow) );
    1274
    1275 return SCIP_OKAY;
    1276}
    1277
    1278/** deletes rows from SCIP_LP; the new position of a row must not be greater that its old position */
    1280 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    1281 int* dstat /**< deletion status of rows
    1282 * input: 1 if row should be deleted, 0 if not
    1283 * output: new position of row, -1 if row was deleted */
    1284 )
    1285{
    1286 int nrows;
    1287 int i;
    1288
    1289 SCIPdebugMessage("calling SCIPlpiDelRowset()\n");
    1290
    1291 assert(lpi != NULL);
    1292 assert(lpi->spx != NULL);
    1293
    1294 invalidateSolution(lpi);
    1295
    1296 assert( lpi->spx->preStrongbranchingBasisFreed() );
    1297
    1298 nrows = lpi->spx->numRowsRational();
    1299
    1300 /* SoPlex removeRows() method deletes the rows with dstat[i] < 0, so we have to negate the values */
    1301 for( i = 0; i < nrows; ++i )
    1302 dstat[i] *= -1;
    1303
    1304 SOPLEX_TRY( lpi->messagehdlr, lpi->spx->removeRowsRational(dstat) );
    1305
    1306 return SCIP_OKAY;
    1307}
    1308
    1309/** clears the whole LP */
    1311 SCIP_LPIEXACT* lpi /**< LP interface structure */
    1312 )
    1313{
    1314 SCIPdebugMessage("calling SCIPlpiExactClear()\n");
    1315
    1316 assert(lpi != NULL);
    1317 assert(lpi->spx != NULL);
    1318
    1319 invalidateSolution(lpi);
    1320
    1321 assert( lpi->spx->preStrongbranchingBasisFreed() );
    1322 SOPLEX_TRY( lpi->messagehdlr, lpi->spx->clearLPRational() );
    1323
    1324 return SCIP_OKAY;
    1325}
    1326
    1327/** changes lower and upper bounds of columns */
    1329 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    1330 int ncols, /**< number of columns to change bounds for */
    1331 int* ind, /**< column indices or NULL if ncols is zero */
    1332 SCIP_RATIONAL** lb, /**< values for the new lower bounds or NULL if ncols is zero */
    1333 SCIP_RATIONAL** ub /**< values for the new upper bounds or NULL if ncols is zero */
    1334 )
    1335{
    1336 int i;
    1337
    1338 SCIPdebugMessage("calling SCIPlpiChgBounds()\n");
    1339
    1340 assert(lpi != NULL);
    1341 assert(lpi->spx != NULL);
    1342 assert(ncols == 0 || (ind != NULL && lb != NULL && ub != NULL));
    1343 if( ncols <= 0 )
    1344 return SCIP_OKAY;
    1345
    1346 invalidateSolution(lpi);
    1347
    1348 assert( lpi->spx->preStrongbranchingBasisFreed() );
    1349
    1350 try
    1351 {
    1352 soplex::Rational spxlb;
    1353 soplex::Rational spxub;
    1354
    1355 for( i = 0; i < ncols; ++i )
    1356 {
    1357 assert(0 <= ind[i] && ind[i] < lpi->spx->numColsRational());
    1358 assert(lb[i] != NULL && ub[i] != NULL);
    1359
    1360 if( SCIPrationalIsInfinity(lb[i]) )
    1361 {
    1362 SCIPerrorMessage("LP Error: fixing lower bound for variable %d to infinity.\n", ind[i]);
    1363 return SCIP_LPERROR;
    1364 }
    1365 if( SCIPrationalIsNegInfinity(ub[i]) )
    1366 {
    1367 SCIPerrorMessage("LP Error: fixing upper bound for variable %d to -infinity.\n", ind[i]);
    1368 return SCIP_LPERROR;
    1369 }
    1370
    1371 SpxRSetRat(lpi, spxlb, lb[i]);
    1372 SpxRSetRat(lpi, spxub, ub[i]);
    1373
    1374 lpi->spx->changeBoundsRational(ind[i], spxlb, spxub);
    1375 assert(lpi->spx->lowerRational(ind[i]) <= lpi->spx->upperRational(ind[i]));
    1376 }
    1377 }
    1378#ifndef NDEBUG
    1379 catch( const SPxException& x )
    1380 {
    1381 std::string s = x.what();
    1382 SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
    1383#else
    1384 catch( const SPxException& )
    1385 {
    1386#endif
    1387 return SCIP_LPERROR;
    1388 }
    1389
    1390 return SCIP_OKAY;
    1391}
    1392
    1393/** changes left and right hand sides of rows */
    1395 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    1396 int nrows, /**< number of rows to change sides for */
    1397 int* ind, /**< row indices */
    1398 SCIP_RATIONAL** lhs, /**< new values for left hand sides */
    1399 SCIP_RATIONAL** rhs /**< new values for right hand sides */
    1400 )
    1401{
    1402 int i;
    1403
    1404 SCIPdebugMessage("calling SCIPlpiChgSides()\n");
    1405
    1406 assert(lpi != NULL);
    1407 assert(lpi->spx != NULL);
    1408 assert(ind != NULL);
    1409 assert(lhs != NULL);
    1410 assert(rhs != NULL);
    1411 if( nrows <= 0 )
    1412 return SCIP_OKAY;
    1413
    1414 invalidateSolution(lpi);
    1415
    1416 assert( lpi->spx->preStrongbranchingBasisFreed() );
    1417
    1418 try
    1419 {
    1420 soplex::Rational spxlhs;
    1421 soplex::Rational spxrhs;
    1422
    1423 for( i = 0; i < nrows; ++i )
    1424 {
    1425 assert(0 <= ind[i] && ind[i] < lpi->spx->numRowsRational());
    1426
    1427 SpxRSetRat(lpi, spxlhs, lhs[i]);
    1428 SpxRSetRat(lpi, spxrhs, rhs[i]);
    1429
    1430 lpi->spx->changeRangeRational(ind[i], spxlhs, spxrhs);
    1431 assert(lpi->spx->lhsRational(ind[i]) <= lpi->spx->rhsRational(ind[i]));
    1432 }
    1433 }
    1434#ifndef NDEBUG
    1435 catch( const SPxException& x )
    1436 {
    1437 std::string s = x.what();
    1438 SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
    1439#else
    1440 catch( const SPxException& )
    1441 {
    1442#endif
    1443 return SCIP_LPERROR;
    1444 }
    1445
    1446 return SCIP_OKAY;
    1447}
    1448
    1449/** changes a single coefficient */
    1451 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    1452 int row, /**< row number of coefficient to change */
    1453 int col, /**< column number of coefficient to change */
    1454 SCIP_RATIONAL* newval /**< new value of coefficient */
    1455 )
    1456{
    1457 soplex::Rational spxval;
    1458
    1459 SCIPdebugMessage("calling SCIPlpiChgCoef()\n");
    1460
    1461 assert(lpi != NULL);
    1462 assert(lpi->spx != NULL);
    1463 assert(0 <= row && row < lpi->spx->numRowsRational());
    1464 assert(0 <= col && col < lpi->spx->numColsRational());
    1465
    1466 invalidateSolution(lpi);
    1467
    1468 assert( lpi->spx->preStrongbranchingBasisFreed() );
    1469
    1470 SpxRSetRat(lpi, spxval, newval);
    1471 SOPLEX_TRY( lpi->messagehdlr, lpi->spx->changeElementRational(row, col, spxval) );
    1472
    1473 return SCIP_OKAY;
    1474}
    1475
    1476/** changes the objective sense */
    1478 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    1479 SCIP_OBJSEN objsen /**< new objective sense */
    1480 )
    1481{
    1482 SCIPdebugMessage("calling SCIPlpiChgObjsen()\n");
    1483
    1484 assert(lpi != NULL);
    1485 assert(lpi->spx != NULL);
    1486
    1487 invalidateSolution(lpi);
    1488
    1489 assert( lpi->spx->preStrongbranchingBasisFreed() );
    1490
    1491 SOPLEX_TRY( lpi->messagehdlr, (void) lpi->spx->setIntParam(SoPlex::OBJSENSE, (int) (objsen == SCIP_OBJSEN_MINIMIZE ? SoPlex::OBJSENSE_MINIMIZE : SoPlex::OBJSENSE_MAXIMIZE) ) );
    1492
    1493 return SCIP_OKAY;
    1494}
    1495
    1496/** changes objective values of columns in the LP */
    1498 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    1499 int ncols, /**< number of columns to change objective value for */
    1500 int* ind, /**< column indices to change objective value for */
    1501 SCIP_RATIONAL** obj /**< new objective values for columns */
    1502 )
    1503{
    1504 int i;
    1505
    1506 SCIPdebugMessage("calling SCIPlpiChgObj()\n");
    1507
    1508 assert(lpi != NULL);
    1509 assert(lpi->spx != NULL);
    1510 assert(ind != NULL);
    1511 assert(obj != NULL);
    1512
    1513 invalidateSolution(lpi);
    1514
    1515 assert( lpi->spx->preStrongbranchingBasisFreed() );
    1516
    1517 try
    1518 {
    1519 soplex::Rational spxobj;
    1520
    1521 for( i = 0; i < ncols; ++i )
    1522 {
    1523 assert(obj[i] != NULL);
    1524 assert(0 <= ind[i] && ind[i] < lpi->spx->numColsRational());
    1525
    1526 SpxRSetRat(lpi, spxobj, obj[i]);
    1527 lpi->spx->changeObjRational(ind[i], spxobj);
    1528 }
    1529 }
    1530#ifndef NDEBUG
    1531 catch( const SPxException& x )
    1532 {
    1533 std::string s = x.what();
    1534 SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
    1535#else
    1536 catch( const SPxException& )
    1537 {
    1538#endif
    1539 return SCIP_LPERROR;
    1540 }
    1541
    1542 return SCIP_OKAY;
    1543}
    1544
    1545/**@} */
    1546
    1547
    1548/*
    1549 * Data Accessing Methods
    1550 */
    1551
    1552/**@name Data Accessing Methods */
    1553/**@{ */
    1554
    1555/** gets the number of rows in the LP */
    1557 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    1558 int* nrows /**< pointer to store the number of rows */
    1559 )
    1560{
    1561 SCIPdebugMessage("calling SCIPlpiExactGetNRows()\n");
    1562
    1563 assert(lpi != NULL);
    1564 assert(lpi->spx != NULL);
    1565 assert(nrows != NULL);
    1566
    1567 *nrows = lpi->spx->numRowsRational();
    1568
    1569 return SCIP_OKAY;
    1570}
    1571
    1572/** gets the number of columns in the LP */
    1574 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    1575 int* ncols /**< pointer to store the number of cols */
    1576 )
    1577{
    1578 SCIPdebugMessage("calling SCIPlpiExactGetNCols()\n");
    1579
    1580 assert(lpi != NULL);
    1581 assert(lpi->spx != NULL);
    1582 assert(ncols != NULL);
    1583
    1584 *ncols = lpi->spx->numColsRational();
    1585
    1586 return SCIP_OKAY;
    1587}
    1588
    1589/** gets the number of nonzero elements in the LP constraint matrix */
    1591 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    1592 int* nnonz /**< pointer to store the number of nonzeros */
    1593 )
    1594{
    1595 int i;
    1596
    1597 SCIPdebugMessage("calling SCIPlpiExactGetNNonz()\n");
    1598
    1599 assert(lpi != NULL);
    1600 assert(lpi->spx != NULL);
    1601 assert(nnonz != NULL);
    1602
    1603 /* SoPlex has no direct method to return the number of nonzeros, so we have to count them manually */
    1604 *nnonz = 0;
    1605 if( lpi->spx->numRowsRational() < lpi->spx->numColsRational() )
    1606 {
    1607 for( i = 0; i < lpi->spx->numRowsRational(); ++i )
    1608 (*nnonz) += lpi->spx->rowVectorRational(i).size();
    1609 }
    1610 else
    1611 {
    1612 for( i = 0; i < lpi->spx->numColsRational(); ++i )
    1613 (*nnonz) += lpi->spx->colVectorRational(i).size();
    1614 }
    1615
    1616 return SCIP_OKAY;
    1617}
    1618
    1619/** gets columns from LP problem object; the arrays have to be large enough to store all values
    1620 * Either both, lb and ub, have to be NULL, or both have to be non-NULL,
    1621 * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
    1622 */
    1624 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    1625 int firstcol, /**< first column to get from LP */
    1626 int lastcol, /**< last column to get from LP */
    1627 SCIP_RATIONAL** lb, /**< buffer to store the lower bound vector, or NULL */
    1628 SCIP_RATIONAL** ub, /**< buffer to store the upper bound vector, or NULL */
    1629 int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
    1630 int* beg, /**< buffer to store start index of each column in ind- and val-array, or NULL */
    1631 int* ind, /**< buffer to store row indices of constraint matrix entries, or NULL */
    1632 SCIP_RATIONAL** val /**< buffer to store values of constraint matrix entries, or NULL */
    1633 )
    1634{
    1635 int i;
    1636 int j;
    1637
    1638 SCIPdebugMessage("calling SCIPlpiExactGetCols()\n");
    1639
    1640 assert(lpi != NULL);
    1641 assert(lpi->spx != NULL);
    1642 assert(0 <= firstcol && firstcol <= lastcol && lastcol < lpi->spx->numColsRational());
    1643 assert((lb != NULL && ub != NULL) || (lb == NULL && ub == NULL));
    1644 assert((nnonz != NULL && beg != NULL && ind != NULL && val != NULL) || (nnonz == NULL && beg == NULL && ind == NULL && val == NULL));
    1645
    1646 if( lb != NULL )
    1647 {
    1648 const VectorRational& lbvec = lpi->spx->lowerRational();
    1649 const VectorRational& ubvec = lpi->spx->upperRational();
    1650
    1651 for( i = firstcol; i <= lastcol; ++i )
    1652 {
    1653 RsetSpxR(lpi, lb[i-firstcol], lbvec[i]);
    1654 RsetSpxR(lpi, ub[i-firstcol], ubvec[i]);
    1655 }
    1656 }
    1657
    1658 if( nnonz != NULL )
    1659 {
    1660 *nnonz = 0;
    1661 for( i = firstcol; i <= lastcol; ++i )
    1662 {
    1663 const SVectorRational& cvec = lpi->spx->colVectorRational(i);
    1664 beg[i-firstcol] = *nnonz;
    1665
    1666 for( j = 0; j < cvec.size(); ++j )
    1667 {
    1668 ind[*nnonz] = cvec.index(j);
    1669 RsetSpxR(lpi, val[*nnonz], cvec.value(j));
    1670 (*nnonz)++;
    1671 }
    1672 }
    1673 }
    1674
    1675 return SCIP_OKAY;
    1676}
    1677
    1678/** gets rows from LP problem object; the arrays have to be large enough to store all values.
    1679 * Either both, lhs and rhs, have to be NULL, or both have to be non-NULL,
    1680 * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
    1681 */
    1683 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    1684 int firstrow, /**< first row to get from LP */
    1685 int lastrow, /**< last row to get from LP */
    1686 SCIP_RATIONAL** lhs, /**< buffer to store left hand side vector, or NULL */
    1687 SCIP_RATIONAL** rhs, /**< buffer to store right hand side vector, or NULL */
    1688 int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
    1689 int* beg, /**< buffer to store start index of each row in ind- and val-array, or NULL */
    1690 int* ind, /**< buffer to store column indices of constraint matrix entries, or NULL */
    1691 SCIP_RATIONAL** val /**< buffer to store values of constraint matrix entries, or NULL */
    1692 )
    1693{
    1694 int i;
    1695 int j;
    1696
    1697 SCIPdebugMessage("calling SCIPlpiExactGetRows()\n");
    1698
    1699 assert(lpi != NULL);
    1700 assert(lpi->spx != NULL);
    1701 assert(0 <= firstrow && firstrow <= lastrow && lastrow < lpi->spx->numRowsRational());
    1702 assert((lhs != NULL && rhs != NULL) || (lhs == NULL && rhs == NULL));
    1703 assert((nnonz != NULL && beg != NULL && ind != NULL && val != NULL) || (nnonz == NULL && beg == NULL && ind == NULL && val == NULL));
    1704
    1705 if( lhs != NULL )
    1706 {
    1707 if( lpi->spx->boolParam(SoPlex::PERSISTENTSCALING) && FALSE )
    1708 {
    1709 }
    1710 else
    1711 {
    1712 const VectorRational& lhsvec = lpi->spx->lhsRational();
    1713 const VectorRational& rhsvec = lpi->spx->rhsRational();
    1714 for( i = firstrow; i <= lastrow; ++i )
    1715 {
    1716 RsetSpxR(lpi, lhs[i-firstrow], lhsvec[i]);
    1717 RsetSpxR(lpi, rhs[i-firstrow], rhsvec[i]);
    1718 }
    1719 }
    1720 }
    1721
    1722 if( nnonz != NULL )
    1723 {
    1724 *nnonz = 0;
    1725 for( i = firstrow; i <= lastrow; ++i )
    1726 {
    1727 beg[i-firstrow] = *nnonz;
    1728
    1729 if( lpi->spx->boolParam(SoPlex::PERSISTENTSCALING) )
    1730 {
    1731 }
    1732 else
    1733 {
    1734 const SVectorRational& rvec = lpi->spx->rowVectorRational(i);
    1735 for( j = 0; j < rvec.size(); ++j )
    1736 {
    1737 ind[*nnonz] = rvec.index(j);
    1738 RsetSpxR(lpi, val[*nnonz], rvec.value(j));
    1739 (*nnonz)++;
    1740 }
    1741 }
    1742 }
    1743 }
    1744
    1745 return SCIP_OKAY;
    1746}
    1747
    1748/** gets column names */
    1750 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    1751 int firstcol, /**< first column to get name from LP */
    1752 int lastcol, /**< last column to get name from LP */
    1753 char** colnames, /**< pointers to column names (of size at least lastcol-firstcol+1) or NULL if namestoragesize is zero */
    1754 char* namestorage, /**< storage for col names or NULL if namestoragesize is zero */
    1755 int namestoragesize, /**< size of namestorage (if 0, storageleft returns the storage needed) */
    1756 int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) or NULL if namestoragesize is zero */
    1757 )
    1758{
    1759 assert( lpi != NULL );
    1760 assert( lpi->spx != NULL );
    1761 assert( colnames != NULL || namestoragesize == 0 );
    1762 assert( namestorage != NULL || namestoragesize == 0 );
    1763 assert( namestoragesize >= 0 );
    1764 assert( storageleft != NULL );
    1765 assert( 0 <= firstcol && firstcol <= lastcol && lastcol < lpi->spx->numColsRational() );
    1766
    1767 SCIPdebugMessage("getting column names %d to %d\n", firstcol, lastcol);
    1768
    1769 SCIPerrorMessage("SCIPlpiExactGetColNames() not implemented\n");
    1770
    1771 return SCIP_NOTIMPLEMENTED;
    1772}
    1773
    1774/** gets row names */
    1776 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    1777 int firstrow, /**< first row to get name from LP */
    1778 int lastrow, /**< last row to get name from LP */
    1779 char** rownames, /**< pointers to row names (of size at least lastrow-firstrow+1) or NULL if namestoragesize is zero */
    1780 char* namestorage, /**< storage for row names or NULL if namestoragesize is zero */
    1781 int namestoragesize, /**< size of namestorage (if 0, -storageleft returns the storage needed) */
    1782 int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) or NULL if namestoragesize is zero */
    1783 )
    1784{
    1785 assert( lpi != NULL );
    1786 assert( lpi->spx != NULL );
    1787 assert( rownames != NULL || namestoragesize == 0 );
    1788 assert( namestorage != NULL || namestoragesize == 0 );
    1789 assert( namestoragesize >= 0 );
    1790 assert( storageleft != NULL );
    1791 assert( 0 <= firstrow && firstrow <= lastrow && lastrow < lpi->spx->numRowsRational() );
    1792
    1793 SCIPdebugMessage("getting row names %d to %d\n", firstrow, lastrow);
    1794
    1795 SCIPerrorMessage("SCIPlpiExactGetRowNames() not implemented\n");
    1796
    1797 return SCIP_NOTIMPLEMENTED;
    1798}
    1799
    1800/** gets objective sense of the LP */
    1802 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    1803 SCIP_OBJSEN* objsen /**< pointer to store objective sense */
    1804 )
    1805{
    1806 SCIPdebugMessage("calling SCIPlpiExactGetObjsen()\n");
    1807
    1808 assert(lpi != NULL);
    1809 assert(lpi->spx != NULL);
    1810 assert(objsen != NULL);
    1811
    1812 *objsen = (lpi->spx->intParam(SoPlex::OBJSENSE) == SoPlex::OBJSENSE_MINIMIZE) ? SCIP_OBJSEN_MINIMIZE : SCIP_OBJSEN_MAXIMIZE;
    1813
    1814 return SCIP_OKAY;
    1815}
    1816
    1817/** gets objective coefficients from LP problem object */
    1819 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    1820 int firstcol, /**< first column to get objective coefficient for */
    1821 int lastcol, /**< last column to get objective coefficient for */
    1822 SCIP_RATIONAL** vals /**< array to store objective coefficients */
    1823 )
    1824{
    1825 int i;
    1826
    1827 SCIPdebugMessage("calling SCIPlpiExactGetObj()\n");
    1828
    1829 assert(lpi != NULL);
    1830 assert(lpi->spx != NULL);
    1831 assert(0 <= firstcol && firstcol <= lastcol && lastcol < lpi->spx->numColsRational());
    1832 assert(vals != NULL);
    1833
    1834 for( i = firstcol; i <= lastcol; ++i )
    1835 {
    1836 assert(vals[i-firstcol] != NULL);
    1837 RsetSpxR(lpi, vals[i-firstcol], lpi->spx->objRational(i));
    1838 }
    1839
    1840 return SCIP_OKAY;
    1841}
    1842
    1843/** gets current bounds from LP problem object */
    1845 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    1846 int firstcol, /**< first column to get objective value for */
    1847 int lastcol, /**< last column to get objective value for */
    1848 SCIP_RATIONAL** lbs, /**< array to store lower bound values, or NULL */
    1849 SCIP_RATIONAL** ubs /**< array to store upper bound values, or NULL */
    1850 )
    1851{
    1852 int i;
    1853
    1854 SCIPdebugMessage("calling SCIPlpiExactGetBounds()\n");
    1855
    1856 assert(lpi != NULL);
    1857 assert(lpi->spx != NULL);
    1858 assert(0 <= firstcol && firstcol <= lastcol && lastcol < lpi->spx->numColsRational());
    1859
    1860 for( i = firstcol; i <= lastcol; ++i )
    1861 {
    1862 if( lbs != NULL )
    1863 {
    1864 assert(lbs[i-firstcol] != NULL);
    1865 RsetSpxR(lpi, lbs[i-firstcol], lpi->spx->lowerRational(i));
    1866 }
    1867 if( ubs != NULL )
    1868 {
    1869 assert(ubs[i-firstcol] != NULL);
    1870 RsetSpxR(lpi, ubs[i-firstcol], lpi->spx->upperRational(i));
    1871 }
    1872 }
    1873
    1874 return SCIP_OKAY;
    1875}
    1876
    1877/** gets current row sides from LP problem object */
    1879 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    1880 int firstrow, /**< first row to get sides for */
    1881 int lastrow, /**< last row to get sides for */
    1882 SCIP_RATIONAL** lhss, /**< array to store left hand side values, or NULL */
    1883 SCIP_RATIONAL** rhss /**< array to store right hand side values, or NULL */
    1884 )
    1885{
    1886 int i;
    1887
    1888 SCIPdebugMessage("calling SCIPlpiExactGetSides()\n");
    1889
    1890 assert(lpi != NULL);
    1891 assert(lpi->spx != NULL);
    1892 assert(0 <= firstrow && firstrow <= lastrow && lastrow < lpi->spx->numRowsRational());
    1893
    1894 for( i = firstrow; i <= lastrow; ++i )
    1895 {
    1896 if( lhss != NULL )
    1897 {
    1898 assert(lhss[i-firstrow] != NULL);
    1899 RsetSpxR(lpi, lhss[i-firstrow], lpi->spx->lhsRational(i));
    1900 }
    1901 if( rhss != NULL )
    1902 {
    1903 assert(rhss[i-firstrow] != NULL);
    1904 RsetSpxR(lpi, rhss[i-firstrow], lpi->spx->rhsReal(i));
    1905 }
    1906 }
    1907
    1908 return SCIP_OKAY;
    1909}
    1910
    1911/** gets a single coefficient */
    1913 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    1914 int row, /**< row number of coefficient */
    1915 int col, /**< column number of coefficient */
    1916 SCIP_RATIONAL* val /**< pointer to store the value of the coefficient */
    1917 )
    1918{
    1919 SCIPdebugMessage("calling SCIPlpiExactGetCoef()\n");
    1920
    1921 assert(lpi != NULL);
    1922 assert(lpi->spx != NULL);
    1923 assert(0 <= col && col < lpi->spx->numColsRational());
    1924 assert(0 <= row && row < lpi->spx->numRowsRational());
    1925 assert(val != NULL);
    1926
    1927 RsetSpxR(lpi, val, lpi->spx->colVectorRational(col)[row]);
    1928
    1929 return SCIP_OKAY;
    1930}
    1931
    1932/**@} */
    1933
    1934
    1935/*
    1936 * Solving Methods
    1937 */
    1938
    1939/**@name Solving Methods */
    1940/**@{ */
    1941
    1942/** solves LP -- used for both, primal and dual simplex, because SoPlex doesn't distinct the two cases */
    1943static
    1945 SCIP_LPIEXACT* lpi /**< LP interface structure */
    1946 )
    1947{
    1948 assert( lpi != NULL );
    1949 assert( lpi->spx != NULL );
    1950
    1951 SPxOut::Verbosity verbosity;
    1952 /* store and set verbosity */
    1953 verbosity = lpi->spx->spxout.getVerbosity();
    1954 lpi->spx->spxout.setVerbosity((SPxOut::Verbosity)(lpi->spx->getLpInfo() ? SOPLEX_VERBLEVEL : 0));
    1955
    1956 SCIPdebugMessage("calling exact SoPlex solve(): %d cols, %d rows\n", lpi->spx->numColsRational(), lpi->spx->numRowsRational());
    1957
    1958 invalidateSolution(lpi);
    1959
    1960 assert( lpi->spx->preStrongbranchingBasisFreed() );
    1961
    1962#ifdef WITH_LPSCHECK
    1963 lpi->spx->setDoubleCheck(CHECK_SPXSOLVE);
    1964#endif
    1965
    1966 /* delete starting basis if solving from scratch */
    1967 if( lpi->spx->getFromScratch() )
    1968 {
    1969 try
    1970 {
    1971 lpi->spx->clearBasis();
    1972 }
    1973#ifndef NDEBUG
    1974 catch(const SPxException& x)
    1975 {
    1976 std::string s = x.what();
    1977 SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
    1978#else
    1979 catch(const SPxException&)
    1980 {
    1981#endif
    1982 assert( lpi->spx->status() != SPxSolver::OPTIMAL );
    1983 return SCIP_LPERROR;
    1984 }
    1985 }
    1986 assert(!lpi->spx->getFromScratch() || lpi->spx->status() == SPxSolver::NO_PROBLEM);
    1987
    1988 SPxSolver::Status status = lpi->spx->doSolve();
    1989 SCIPdebugMessage(" -> SoPlex status: %d, basis status: %d\n", lpi->spx->status(), lpi->spx->basisStatus());
    1990 lpi->solved = TRUE;
    1991
    1992 /* restore verbosity */
    1993 lpi->spx->spxout.setVerbosity(verbosity);
    1994
    1995 switch( status )
    1996 {
    1997 case SPxSolver::ABORT_TIME:
    1998 case SPxSolver::ABORT_ITER:
    1999 case SPxSolver::ABORT_VALUE:
    2000 case SPxSolver::SINGULAR:
    2001 case SPxSolver::REGULAR:
    2002 case SPxSolver::OPTIMAL:
    2003#if SOPLEX_APIVERSION >= 3
    2004 case SPxSolver::OPTIMAL_UNSCALED_VIOLATIONS:
    2005#endif
    2006 case SPxSolver::UNBOUNDED:
    2007 case SPxSolver::INFEASIBLE:
    2008 return SCIP_OKAY;
    2009 case SPxSolver::UNKNOWN:
    2010 default:
    2011 return SCIP_LPERROR;
    2012 } /*lint !e788*/
    2013}
    2014
    2015/** calls primal simplex to solve the LP */
    2017 SCIP_LPIEXACT* lpi /**< LP interface structure */
    2018 )
    2019{
    2020 SCIPdebugMessage("calling SCIPlpiSolvePrimal()\n");
    2021
    2022 assert(lpi != NULL);
    2023 assert(lpi->spx != NULL);
    2024
    2025 (void) lpi->spx->setIntParam(SoPlex::ALGORITHM, (int) SoPlex::ALGORITHM_PRIMAL);
    2026 return spxSolve(lpi);
    2027}
    2028
    2029/** calls dual simplex to solve the LP */
    2031 SCIP_LPIEXACT* lpi /**< LP interface structure */
    2032 )
    2033{
    2034 SCIPdebugMessage("calling SCIPlpiSolveDual()\n");
    2035
    2036 assert(lpi != NULL);
    2037 assert(lpi->spx != NULL);
    2038
    2039 (void) lpi->spx->setIntParam(SoPlex::ALGORITHM, (int) SoPlex::ALGORITHM_DUAL);
    2040 return spxSolve(lpi);
    2041}
    2042
    2043/** calls barrier or interior point algorithm to solve the LP with crossover to simplex basis */
    2045 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    2046 SCIP_Bool crossover /**< perform crossover */
    2047 )
    2048{ /*lint --e{715}*/
    2049 assert(lpi != NULL);
    2050 assert(lpi->spx != NULL);
    2051
    2052 SCIPdebugMessage("calling SCIPlpiSolveBarrier()\n");
    2053
    2054 /* Since SoPlex does not support barrier we switch to DUAL */
    2055 return SCIPlpiExactSolveDual(lpi);
    2056}
    2057
    2058/** start strong branching - call before any strongbranching */
    2060 SCIP_LPIEXACT* lpi /**< LP interface structure */
    2061 )
    2062{
    2063 assert(lpi != NULL);
    2064 assert(lpi->spx != NULL);
    2065
    2066 assert( lpi->spx->preStrongbranchingBasisFreed() );
    2068
    2069 return SCIP_OKAY;
    2070}
    2071
    2072/** end strong branching - call after any strongbranching */
    2074 SCIP_LPIEXACT* lpi /**< LP interface structure */
    2075 )
    2076{
    2077 assert(lpi != NULL);
    2078 assert(lpi->spx != NULL);
    2079
    2080 assert( ! lpi->spx->preStrongbranchingBasisFreed() );
    2083
    2084 return SCIP_OKAY;
    2085}
    2086
    2087/**@} */
    2088
    2089
    2090/*
    2091 * Solution Information Methods
    2092 */
    2093
    2094/**@name Solution Information Methods */
    2095/**@{ */
    2096
    2097/** returns whether a solve method was called after the last modification of the LP */
    2099 SCIP_LPIEXACT* lpi /**< LP interface structure */
    2100 )
    2101{
    2102 assert(lpi != NULL);
    2103
    2104 return lpi->solved;
    2105}
    2106
    2107/** gets information about primal and dual feasibility of the current LP solution
    2108 *
    2109 * The feasibility information is with respect to the last solving call and it is only relevant if SCIPlpiWasSolved()
    2110 * returns true. If the LP is changed, this information might be invalidated.
    2111 *
    2112 * Note that @param primalfeasible and @param dualfeasible should only return true if the solver has proved the respective LP to
    2113 * be feasible. Thus, the return values should be equal to the values of SCIPlpiIsPrimalFeasible() and
    2114 * SCIPlpiIsDualFeasible(), respectively. Note that if feasibility cannot be proved, they should return false (even if
    2115 * the problem might actually be feasible).
    2116 */
    2118 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    2119 SCIP_Bool* primalfeasible, /**< pointer to store primal feasibility status */
    2120 SCIP_Bool* dualfeasible /**< pointer to store dual feasibility status */
    2121 )
    2122{
    2123 SCIPdebugMessage("calling SCIPlpiExactGetSolFeasibility()\n");
    2124
    2125 assert(lpi != NULL);
    2126 assert(primalfeasible != NULL);
    2127 assert(dualfeasible != NULL);
    2128
    2129 *primalfeasible = SCIPlpiExactIsPrimalFeasible(lpi);
    2130 *dualfeasible = SCIPlpiExactIsDualFeasible(lpi);
    2131
    2132 return SCIP_OKAY;
    2133}
    2134
    2135/** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point);
    2136 * this does not necessarily mean, that the solver knows and can return the primal ray
    2137 */
    2139 SCIP_LPIEXACT* lpi /**< LP interface structure */
    2140 )
    2141{
    2142 SCIPdebugMessage("calling SCIPlpiExactExistsPrimalRay()\n");
    2143
    2144 assert(lpi != NULL);
    2145 assert(lpi->spx != NULL);
    2146
    2147 return (lpi->spx->status() == SPxSolver::UNBOUNDED);
    2148}
    2149
    2150/** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point),
    2151 * and the solver knows and can return the primal ray
    2152 */
    2154 SCIP_LPIEXACT* lpi /**< LP interface structure */
    2155 )
    2156{
    2157 SCIPdebugMessage("calling SCIPlpiHasPrimalRay()\n");
    2158
    2159 assert(lpi != NULL);
    2160 assert(lpi->spx != NULL);
    2161
    2162 return lpi->spx->hasPrimalRay();
    2163}
    2164
    2165/** returns TRUE iff LP is proven to be primal unbounded */
    2167 SCIP_LPIEXACT* lpi /**< LP interface structure */
    2168 )
    2169{
    2170 SCIPdebugMessage("calling SCIPlpiIsPrimalUnbounded()\n");
    2171
    2172 assert(lpi != NULL);
    2173 assert(lpi->spx != NULL);
    2174
    2175 assert(lpi->spx->status() != SPxSolver::UNBOUNDED || lpi->spx->basisStatus() == SPxBasis::UNBOUNDED);
    2176
    2177 /* if SoPlex returns unbounded, this may only mean that an unbounded ray is available, not necessarily a primal
    2178 * feasible point; hence we have to check the perturbation
    2179 */
    2180 return lpi->spx->status() == SPxSolver::UNBOUNDED;
    2181}
    2182
    2183/** returns TRUE iff LP is proven to be primal infeasible */
    2185 SCIP_LPIEXACT* lpi /**< LP interface structure */
    2186 )
    2187{
    2188 SCIPdebugMessage("calling SCIPlpiIsPrimalInfeasible()\n");
    2189
    2190 assert(lpi != NULL);
    2191 assert(lpi->spx != NULL);
    2192
    2193 return (lpi->spx->status() == SPxSolver::INFEASIBLE);
    2194}
    2195
    2196/** returns TRUE iff LP is proven to be primal feasible */
    2198 SCIP_LPIEXACT* lpi /**< LP interface structure */
    2199 )
    2200{
    2201 SPxBasis::SPxStatus basestatus;
    2202
    2203 SCIPdebugMessage("calling SCIPlpiIsPrimalFeasible()\n");
    2204
    2205 assert(lpi != NULL);
    2206 assert(lpi->spx != NULL);
    2207
    2208 basestatus = lpi->spx->basisStatus();
    2209
    2210 /* note that the solver status may be ABORT_VALUE and the basis status optimal; if we are optimal, isPerturbed() may
    2211 * still return true as long as perturbation plus violation is within tolerances
    2212 */
    2213 assert(basestatus == SPxBasis::OPTIMAL || lpi->spx->status() != SPxSolver::OPTIMAL);
    2214
    2215 return basestatus == SPxBasis::OPTIMAL || basestatus == SPxBasis::PRIMAL;
    2216}
    2217
    2218/** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point);
    2219 * this does not necessarily mean, that the solver knows and can return the dual ray
    2220 */
    2222 SCIP_LPIEXACT* lpi /**< LP interface structure */
    2223 )
    2224{
    2225 SCIPdebugMessage("calling SCIPlpiExactExistsDualRay()\n");
    2226
    2227 assert(lpi != NULL);
    2228 assert(lpi->spx != NULL);
    2229
    2230 return (lpi->spx->status() == SPxSolver::INFEASIBLE);
    2231}
    2232
    2233/** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point),
    2234 * and the solver knows and can return the dual ray
    2235 */
    2237 SCIP_LPIEXACT* lpi /**< LP interface structure */
    2238 )
    2239{
    2240 SCIPdebugMessage("calling SCIPlpiHasDualRay()\n");
    2241
    2242 assert(lpi != NULL);
    2243 assert(lpi->spx != NULL);
    2244
    2245 return lpi->spx->hasDualFarkas();
    2246}
    2247
    2248/** returns TRUE iff LP is dual unbounded */
    2250 SCIP_LPIEXACT* lpi /**< LP interface structure */
    2251 )
    2252{
    2253 SCIPdebugMessage("calling SCIPlpiIsDualUnbounded()\n");
    2254
    2255 assert(lpi != NULL);
    2256 assert(lpi->spx != NULL);
    2257
    2258 return lpi->spx->status() == SPxSolver::INFEASIBLE && lpi->spx->basisStatus() == SPxBasis::DUAL;
    2259}
    2260
    2261/** returns TRUE iff LP is dual infeasible */
    2263 SCIP_LPIEXACT* lpi /**< LP interface structure */
    2264 )
    2265{
    2266 SCIPdebugMessage("calling SCIPlpiIsDualInfeasible()\n");
    2267
    2268 assert(lpi != NULL);
    2269 assert(lpi->spx != NULL);
    2270
    2271 return (lpi->spx->status() == SPxSolver::UNBOUNDED);
    2272}
    2273
    2274/** returns TRUE iff LP is proven to be dual feasible */
    2276 SCIP_LPIEXACT* lpi /**< LP interface structure */
    2277 )
    2278{
    2279 SCIPdebugMessage("calling SCIPlpiIsDualFeasible()\n");
    2280
    2281 assert(lpi != NULL);
    2282 assert(lpi->spx != NULL);
    2283
    2284 /* note that the solver status may be ABORT_VALUE and the basis status optimal; if we are optimal, isPerturbed() may
    2285 * still return true as long as perturbation plus violation is within tolerances
    2286 */
    2287 assert(lpi->spx->basisStatus() == SPxBasis::OPTIMAL || lpi->spx->status() != SPxSolver::OPTIMAL);
    2288
    2289 return (lpi->spx->basisStatus() == SPxBasis::OPTIMAL) || lpi->spx->basisStatus() == SPxBasis::DUAL;
    2290}
    2291
    2292/** returns TRUE iff LP was solved to optimality */
    2294 SCIP_LPIEXACT* lpi /**< LP interface structure */
    2295 )
    2296{
    2297 SCIPdebugMessage("calling SCIPlpiIsOptimal()\n");
    2298
    2299 assert(lpi != NULL);
    2300 assert(lpi->spx != NULL);
    2301 assert((lpi->spx->basisStatus() == SPxBasis::OPTIMAL)
    2303
    2304 /* note that the solver status may be ABORT_VALUE and the basis status optimal; if we are optimal, isPerturbed() may
    2305 * still return true as long as perturbation plus violation is within tolerances
    2306 */
    2307 return (lpi->spx->basisStatus() == SPxBasis::OPTIMAL);
    2308}
    2309
    2310/** returns TRUE iff the objective limit was reached */
    2312 SCIP_LPIEXACT* lpi /**< LP interface structure */
    2313 )
    2314{
    2315 SCIPdebugMessage("calling SCIPlpiIsObjlimExc()\n");
    2316
    2317 assert(lpi != NULL);
    2318 assert(lpi->spx != NULL);
    2319
    2320 return (lpi->spx->status() == SPxSolver::ABORT_VALUE);
    2321}
    2322
    2323/** returns TRUE iff the iteration limit was reached */
    2325 SCIP_LPIEXACT* lpi /**< LP interface structure */
    2326 )
    2327{
    2328 SCIPdebugMessage("calling SCIPlpiIsIterlimExc()\n");
    2329
    2330 assert(lpi != NULL);
    2331 assert(lpi->spx != NULL);
    2332
    2333 return (lpi->spx->status() == SPxSolver::ABORT_ITER);
    2334}
    2335
    2336/** returns TRUE iff the time limit was reached */
    2338 SCIP_LPIEXACT* lpi /**< LP interface structure */
    2339 )
    2340{
    2341 SCIPdebugMessage("calling SCIPlpiIsTimelimExc()\n");
    2342
    2343 assert(lpi != NULL);
    2344 assert(lpi->spx != NULL);
    2345
    2346 return (lpi->spx->status() == SPxSolver::ABORT_TIME);
    2347}
    2348
    2349/** returns the internal solution status of the solver */
    2351 SCIP_LPIEXACT* lpi /**< LP interface structure */
    2352 )
    2353{
    2354 SCIPdebugMessage("calling SCIPlpiExactGetInternalStatus()\n");
    2355
    2356 assert(lpi != NULL);
    2357 assert(lpi->spx != NULL);
    2358
    2359 return static_cast<int>(lpi->spx->status());
    2360}
    2361
    2362/** tries to reset the internal status of the LP solver in order to ignore an instability of the last solving call */
    2364 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    2365 SCIP_Bool* success /**< pointer to store, whether the instability could be ignored */
    2366 )
    2367{ /*lint --e{715}*/
    2368 SCIPdebugMessage("calling SCIPlpiIgnoreInstability()\n");
    2369
    2370 assert(lpi != NULL);
    2371 assert(lpi->spx != NULL);
    2372 assert(success != NULL);
    2373
    2374#if SOPLEX_APIVERSION >= 4
    2375 *success = lpi->spx->ignoreUnscaledViolations();
    2376#else
    2377 *success = FALSE;
    2378#endif
    2379
    2380 return SCIP_OKAY;
    2381}
    2382
    2383/** gets objective value of solution */
    2385 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    2386 SCIP_RATIONAL* objval /**< stores the objective value */
    2387 )
    2388{
    2389 SCIPdebugMessage("calling SCIPlpiExactGetObjval()\n");
    2390
    2391 assert(lpi != NULL);
    2392 assert(lpi->spx != NULL);
    2393 assert(objval != NULL);
    2394
    2395 RsetSpxR(lpi, objval, lpi->spx->objValueRational());
    2396
    2397 return SCIP_OKAY;
    2398}
    2399
    2400
    2401/** gets primal and dual solution vectors for feasible LPs
    2402 *
    2403 * Before calling this function, the caller must ensure that the LP has been solved to optimality, i.e., that
    2404 * SCIPlpiIsOptimal() returns true.
    2405 */
    2407 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    2408 SCIP_RATIONAL* objval, /**< stores the objective value, may be NULL if not needed */
    2409 SCIP_RATIONAL** primsol, /**< primal solution vector, may be NULL if not needed */
    2410 SCIP_RATIONAL** dualsol, /**< dual solution vector, may be NULL if not needed */
    2411 SCIP_RATIONAL** activity, /**< row activity vector, may be NULL if not needed */
    2412 SCIP_RATIONAL** redcost /**< reduced cost vector, may be NULL if not needed */
    2413 )
    2414{
    2415 DVectorRational* tmpvec;
    2416 SCIPdebugMessage("calling SCIPlpiExactGetSol()\n");
    2417
    2418 assert(lpi != NULL);
    2419 assert(lpi->spx != NULL);
    2420
    2421 tmpvec = new DVectorRational(MAX(lpi->spx->numColsRational(), lpi->spx->numRowsRational()));
    2422 tmpvec->clear();
    2423
    2424 if( objval != NULL )
    2425 RsetSpxR(lpi, objval, lpi->spx->objValueRational());
    2426
    2427 try
    2428 {
    2429 if( primsol != NULL )
    2430 {
    2431 VectorRational tmp(lpi->spx->numColsRational(), tmpvec->get_ptr());
    2432 (void)lpi->spx->getPrimalRational(tmp);
    2433 RsetSpxVector(lpi, primsol, tmp);
    2434 }
    2435 if( dualsol != NULL )
    2436 {
    2437 VectorRational tmp(lpi->spx->numRowsRational(), tmpvec->get_ptr());
    2438 (void)lpi->spx->getDualRational(tmp);
    2439 RsetSpxVector(lpi, dualsol, tmp);
    2440 }
    2441 if( activity != NULL )
    2442 {
    2443 VectorRational tmp(lpi->spx->numRowsRational(), tmpvec->get_ptr());
    2444 (void)lpi->spx->getSlacksRational(tmp); /* in SoPlex, the activities are called "slacks" */
    2445 RsetSpxVector(lpi, activity, tmp);
    2446 }
    2447 if( redcost != NULL )
    2448 {
    2449 VectorRational tmp(lpi->spx->numColsRational(), tmpvec->get_ptr());
    2450 (void)lpi->spx->getRedCostRational(tmp);
    2451 RsetSpxVector(lpi, redcost, tmp);
    2452 }
    2453
    2454 delete tmpvec;
    2455 }
    2456#ifndef NDEBUG
    2457 catch( const SPxException& x )
    2458 {
    2459 std::string s = x.what();
    2460 SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
    2461#else
    2462 catch( const SPxException& )
    2463 {
    2464#endif
    2465 return SCIP_LPERROR;
    2466 }
    2467
    2468 return SCIP_OKAY;
    2469}
    2470
    2471
    2472/** gets primal ray for unbounded LPs */
    2474 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    2475 SCIP_RATIONAL** ray /**< primal ray */
    2476 )
    2477{ /*lint --e{715}*/
    2478 DVectorRational* tmpvec;
    2479 SCIPdebugMessage("calling SCIPlpiExactGetPrimalRay()\n");
    2480
    2481 assert(lpi != NULL);
    2482 assert(lpi->spx != NULL);
    2483 assert(lpi->spx->hasPrimalRay());
    2484 assert(ray != NULL);
    2485
    2486 tmpvec = new DVectorRational(MAX(lpi->spx->numColsRational(), lpi->spx->numRowsRational()));
    2487
    2488 try
    2489 {
    2490 VectorRational tmp(lpi->spx->numColsRational(), tmpvec->get_ptr());
    2491 (void)lpi->spx->getPrimalRayRational(tmp);
    2492 RsetSpxVector(lpi, ray, tmp);
    2493 }
    2494#ifndef NDEBUG
    2495 catch( const SPxException& x )
    2496 {
    2497 std::string s = x.what();
    2498 SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
    2499#else
    2500 catch( const SPxException& )
    2501 {
    2502#endif
    2503 delete tmpvec;
    2504 return SCIP_LPERROR;
    2505 }
    2506
    2507 delete tmpvec;
    2508
    2509 return SCIP_OKAY;
    2510}
    2511
    2512/** gets dual farkas proof for infeasibility */
    2514 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    2515 SCIP_RATIONAL** dualfarkas /**< dual farkas row multipliers */
    2516 )
    2517{
    2518 DVectorRational* tmpvec;
    2519 SCIPdebugMessage("calling SCIPlpiExactGetDualfarkas()\n");
    2520
    2521 assert(lpi != NULL);
    2522 assert(lpi->spx != NULL);
    2523 assert(lpi->spx->hasDualFarkas());
    2524 assert(dualfarkas != NULL);
    2525
    2526 tmpvec = new DVectorRational(MAX(lpi->spx->numColsRational(), lpi->spx->numRowsRational()));
    2527
    2528 try
    2529 {
    2530 VectorRational tmp(lpi->spx->numRowsRational(), tmpvec->get_ptr());
    2531 (void)lpi->spx->getDualFarkasRational(tmp);
    2532 RsetSpxVector(lpi, dualfarkas, tmp);
    2533 }
    2534#ifndef NDEBUG
    2535 catch( const SPxException& x )
    2536 {
    2537 std::string s = x.what();
    2538 SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
    2539#else
    2540 catch( const SPxException& )
    2541 {
    2542#endif
    2543 return SCIP_LPERROR;
    2544 }
    2545 delete tmpvec;
    2546
    2547 return SCIP_OKAY;
    2548}
    2549
    2550/** gets the number of LP iterations of the last solve call */
    2552 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    2553 int* iterations /**< pointer to store the number of iterations of the last solve call */
    2554 )
    2555{
    2556 SCIPdebugMessage("calling SCIPlpiExactGetIterations()\n");
    2557
    2558 assert(lpi != NULL);
    2559 assert(lpi->spx != NULL);
    2560 assert(iterations != NULL);
    2561
    2562 *iterations = lpi->spx->numIterations();
    2563
    2564 return SCIP_OKAY;
    2565}
    2566
    2567/**@} */
    2568
    2569
    2570/*
    2571 * LP Basis Methods
    2572 */
    2573
    2574/**@name LP Basis Methods */
    2575/**@{ */
    2576
    2577
    2578/** gets current basis status for columns and rows; arrays must be large enough to store the basis status */
    2580 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    2581 int* cstat, /**< array to store column basis status, or NULL */
    2582 int* rstat /**< array to store row basis status, or NULL */
    2583 )
    2584{
    2585 int i;
    2586
    2587 SCIPdebugMessage("calling SCIPlpiExactGetBase()\n");
    2588
    2589 assert(lpi != NULL);
    2590 assert(lpi->spx != NULL);
    2591
    2592 assert( lpi->spx->preStrongbranchingBasisFreed() );
    2593
    2594 if( rstat != NULL )
    2595 {
    2596 for( i = 0; i < lpi->spx->numRowsRational(); ++i )
    2597 {
    2598 switch( lpi->spx->basisRowStatus(i) )
    2599 {
    2600 case SPxSolver::BASIC:
    2601 rstat[i] = SCIP_BASESTAT_BASIC; /*lint !e641*/
    2602 break;
    2603 case SPxSolver::FIXED:
    2604 case SPxSolver::ON_LOWER:
    2605 rstat[i] = SCIP_BASESTAT_LOWER; /*lint !e641*/
    2606 break;
    2607 case SPxSolver::ON_UPPER:
    2608 rstat[i] = SCIP_BASESTAT_UPPER; /*lint !e641*/
    2609 break;
    2610 case SPxSolver::ZERO:
    2611 SCIPerrorMessage("slack variable has basis status ZERO (should not occur)\n");
    2612 return SCIP_LPERROR;
    2613 case SPxSolver::UNDEFINED:
    2614 default:
    2615 SCIPerrorMessage("invalid basis status\n");
    2616 SCIPABORT();
    2617 return SCIP_INVALIDDATA; /*lint !e527*/
    2618 }
    2619 }
    2620 }
    2621
    2622 if( cstat != NULL )
    2623 {
    2624 for( i = 0; i < lpi->spx->numColsRational(); ++i )
    2625 {
    2626 switch( lpi->spx->basisColStatus(i) )
    2627 {
    2628 case SPxSolver::BASIC:
    2629 cstat[i] = SCIP_BASESTAT_BASIC; /*lint !e641*/
    2630 break;
    2631 case SPxSolver::FIXED:
    2632 /* Get reduced cost estimation. If the estimation is not correct this should not hurt:
    2633 * If the basis is loaded into SoPlex again, the status is converted to FIXED again; in
    2634 * this case there is no problem at all. If the basis is saved and/or used in some other
    2635 * solver, it usually is very cheap to perform the pivots necessary to get an optimal
    2636 * basis.
    2637 * @todo implement getRedCostEst()
    2638 * */
    2639// SCIP_CALL( getRedCostEst(lpi->spx, i, &val) );
    2640// if( val < 0.0 ) /* reduced costs < 0 => UPPER else => LOWER */
    2641// cstat[i] = SCIP_BASESTAT_UPPER; /*lint !e641*/
    2642// else
    2643 cstat[i] = SCIP_BASESTAT_LOWER; /*lint !e641*/
    2644 break;
    2645 case SPxSolver::ON_LOWER:
    2646 cstat[i] = SCIP_BASESTAT_LOWER; /*lint !e641*/
    2647 break;
    2648 case SPxSolver::ON_UPPER:
    2649 cstat[i] = SCIP_BASESTAT_UPPER; /*lint !e641*/
    2650 break;
    2651 case SPxSolver::ZERO:
    2652 cstat[i] = SCIP_BASESTAT_ZERO; /*lint !e641*/
    2653 break;
    2654 case SPxSolver::UNDEFINED:
    2655 default:
    2656 SCIPerrorMessage("invalid basis status\n");
    2657 SCIPABORT();
    2658 return SCIP_INVALIDDATA; /*lint !e527*/
    2659 }
    2660 }
    2661 }
    2662
    2663 return SCIP_OKAY;
    2664}
    2665
    2666/** sets current basis status for columns and rows */
    2668 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    2669 int* cstat, /**< array with column basis status */
    2670 int* rstat /**< array with row basis status */
    2671 )
    2672{
    2673 int i;
    2674 int ncols;
    2675 int nrows;
    2676
    2677 SCIPdebugMessage("calling SCIPlpiExactSetBase()\n");
    2678
    2679 assert(lpi != NULL);
    2680 assert(lpi->spx != NULL);
    2681
    2682 SCIP_CALL( SCIPlpiExactGetNRows(lpi, &nrows) );
    2683 SCIP_CALL( SCIPlpiExactGetNCols(lpi, &ncols) );
    2684
    2685 assert(cstat != NULL || ncols == 0);
    2686 assert(rstat != NULL || nrows == 0);
    2687
    2688 assert( lpi->spx->preStrongbranchingBasisFreed() );
    2689 invalidateSolution(lpi);
    2690
    2691 DataArray<SPxSolver::VarStatus>& _colstat = lpi->spx->colStat();
    2692 DataArray<SPxSolver::VarStatus>& _rowstat = lpi->spx->rowStat();
    2693
    2694 _colstat.reSize(ncols);
    2695 _rowstat.reSize(nrows);
    2696
    2697 for( i = 0; i < nrows; ++i )
    2698 {
    2699 switch( rstat[i] ) /*lint !e613*/
    2700 {
    2702 _rowstat[i] = SPxSolver::ON_LOWER;
    2703 break;
    2705 _rowstat[i] = SPxSolver::BASIC;
    2706 break;
    2708 _rowstat[i] = SPxSolver::ON_UPPER;
    2709 break;
    2710 case SCIP_BASESTAT_ZERO:
    2711 SCIPerrorMessage("slack variable has basis status ZERO (should not occur)\n");
    2712 return SCIP_LPERROR; /*lint !e429*/
    2713 default:
    2714 SCIPerrorMessage("invalid basis status\n");
    2715 SCIPABORT();
    2716 return SCIP_INVALIDDATA; /*lint !e527*/
    2717 }
    2718 }
    2719
    2720 for( i = 0; i < ncols; ++i )
    2721 {
    2722 switch( cstat[i] ) /*lint !e613*/
    2723 {
    2725 _colstat[i] = SPxSolver::ON_LOWER;
    2726 break;
    2728 _colstat[i] = SPxSolver::BASIC;
    2729 break;
    2731 _colstat[i] = SPxSolver::ON_UPPER;
    2732 break;
    2733 case SCIP_BASESTAT_ZERO:
    2734 _colstat[i] = SPxSolver::ZERO;
    2735 break;
    2736 default:
    2737 SCIPerrorMessage("invalid basis status\n");
    2738 SCIPABORT();
    2739 return SCIP_INVALIDDATA; /*lint !e527*/
    2740 }
    2741 }
    2742
    2743 SOPLEX_TRY( lpi->messagehdlr, lpi->spx->setBasis(_rowstat.get_ptr(), _colstat.get_ptr()) );
    2745
    2746 return SCIP_OKAY;
    2747}
    2748
    2749/** returns the indices of the basic columns and rows; basic column n gives value n, basic row m gives value -1-m */
    2751 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    2752 int* bind /**< pointer to store basis indices ready to keep number of rows entries */
    2753 )
    2754{
    2755 SCIPdebugMessage("calling SCIPlpiExactGetBasisInd()\n");
    2756
    2757 assert(lpi != NULL);
    2758 assert(lpi->spx != NULL);
    2759 assert(bind != NULL);
    2760
    2761 assert(lpi->spx->preStrongbranchingBasisFreed());
    2762
    2763 lpi->spx->getBasisInd(bind);
    2764
    2765 return SCIP_OKAY;
    2766}
    2767
    2768/** get row of inverse basis matrix B^-1
    2769 *
    2770 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
    2771 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
    2772 * see also the explanation in lpi.h.
    2773 */
    2775 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    2776 int r, /**< row number */
    2777 SCIP_RATIONAL** coef, /**< pointer to store the coefficients of the row */
    2778 int* inds, /**< array to store the non-zero indices, or NULL */
    2779 int* ninds /**< pointer to store the number of non-zero indices, or NULL
    2780 * (-1: if we do not store sparsity information) */
    2781 )
    2782{
    2783 int i;
    2784 SSVectorBase<soplex::Rational> tmpvec(0);
    2785 SCIPdebugMessage("calling SCIPlpiExactGetBInvRow()\n");
    2786
    2787 assert(lpi != NULL);
    2788 assert(lpi->spx != NULL);
    2789 assert(lpi->spx->preStrongbranchingBasisFreed());
    2790 assert(coef != NULL);
    2791
    2792 assert(r >= 0);
    2793 assert(r < lpi->spx->numRowsRational());
    2794
    2795 if( !lpi->spx->getBasisInverseRowRational(r, tmpvec) )
    2796 return SCIP_LPERROR;
    2797
    2798 for( i = 0; i < tmpvec.size(); ++i )
    2799 {
    2800 inds[i] = tmpvec.index(i);
    2801 RsetSpxR(lpi, coef[i], tmpvec.value(i));
    2802 }
    2803
    2804 *ninds = tmpvec.size();
    2805
    2806 return SCIP_OKAY;
    2807}
    2808
    2809/** get column of inverse basis matrix B^-1
    2810 *
    2811 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
    2812 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
    2813 * see also the explanation in lpi.h.
    2814 */
    2816 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    2817 int c, /**< column number of B^-1; this is NOT the number of the column in the LP;
    2818 * you have to call SCIPlpiExactGetBasisInd() to get the array which links the
    2819 * B^-1 column numbers to the row and column numbers of the LP!
    2820 * c must be between 0 and nrows-1, since the basis has the size
    2821 * nrows * nrows */
    2822 SCIP_RATIONAL** coef, /**< pointer to store the coefficients of the column */
    2823 int* inds, /**< array to store the non-zero indices, or NULL */
    2824 int* ninds /**< pointer to store the number of non-zero indices, or NULL
    2825 * (-1: if we do not store sparsity information) */
    2826 )
    2827{
    2828 int i;
    2829 SSVectorRational tmpvec(0);
    2830
    2831 SCIPdebugMessage("calling SCIPlpiExactGetBInvCol()\n");
    2832
    2833 assert( lpi != NULL );
    2834 assert( lpi->spx != NULL );
    2835 assert( lpi->spx->preStrongbranchingBasisFreed() );
    2836 assert(coef != NULL);
    2837
    2838 if( ! lpi->spx->getBasisInverseColRational(c, tmpvec) )
    2839 return SCIP_LPERROR;
    2840
    2841 for( i = 0; i < tmpvec.size(); ++i )
    2842 {
    2843 inds[i] = tmpvec.index(i);
    2844 RsetSpxR(lpi, coef[i], tmpvec.value(i));
    2845 }
    2846
    2847 *ninds = tmpvec.size();
    2848
    2849
    2850 return SCIP_OKAY;
    2851}
    2852
    2853/**@} */
    2854
    2855
    2856/*
    2857 * LP State Methods
    2858 */
    2859
    2860/**@name LP State Methods */
    2861/**@{ */
    2862
    2863/** stores LPi state (like basis information) into lpistate object */
    2865 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    2866 BMS_BLKMEM* blkmem, /**< block memory */
    2867 SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
    2868 )
    2869{
    2870 int ncols;
    2871 int nrows;
    2872
    2873 SCIPdebugMessage("calling SCIPlpiExactGetState()\n");
    2874
    2875 assert(blkmem != NULL);
    2876 assert(lpi != NULL);
    2877 assert(lpi->spx != NULL);
    2878 assert(lpistate != NULL);
    2879
    2880 assert( lpi->spx->preStrongbranchingBasisFreed() );
    2881
    2882 ncols = lpi->spx->numColsRational();
    2883 nrows = lpi->spx->numRowsRational();
    2884 assert(ncols >= 0);
    2885 assert(nrows >= 0);
    2886
    2887 /* allocate lpistate data */
    2888 SCIP_CALL( lpistateCreate(lpistate, blkmem, ncols, nrows) );
    2889
    2890 /* allocate enough memory for storing uncompressed basis information */
    2891 SCIP_CALL( ensureCstatMem(lpi, ncols) );
    2892 SCIP_CALL( ensureRstatMem(lpi, nrows) );
    2893
    2894 /* get unpacked basis information */
    2895 SCIP_CALL( SCIPlpiExactGetBase(lpi, lpi->cstat, lpi->rstat) );
    2896
    2897 /* pack LPi state data */
    2898 (*lpistate)->ncols = ncols;
    2899 (*lpistate)->nrows = nrows;
    2900 lpistatePack(*lpistate, lpi->cstat, lpi->rstat);
    2901
    2902 return SCIP_OKAY;
    2903}
    2904
    2905/** loads LPi state (like basis information) into solver; note that the LP might have been extended with additional
    2906 * columns and rows since the state was stored with SCIPlpiExactGetState()
    2907 */
    2909 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    2910 BMS_BLKMEM* blkmem, /**< block memory */
    2911 SCIP_LPISTATE* lpistate /**< LPi state information (like basis information), or NULL */
    2912 )
    2913{ /*lint --e{715}*/
    2914 int lpncols;
    2915 int lpnrows;
    2916 int i;
    2917
    2918 SCIPdebugMessage("calling SCIPlpiExactSetState()\n");
    2919
    2920 assert(lpi != NULL);
    2921 assert(lpi->spx != NULL);
    2922 assert(lpistate != NULL);
    2923
    2924 assert( lpi->spx->preStrongbranchingBasisFreed() );
    2925
    2926 lpncols = lpi->spx->numColsRational();
    2927 lpnrows = lpi->spx->numRowsRational();
    2928 assert(lpistate->ncols <= lpncols);
    2929 assert(lpistate->nrows <= lpnrows);
    2930
    2931 /* allocate enough memory for storing uncompressed basis information */
    2932 SCIP_CALL( ensureCstatMem(lpi, lpncols) );
    2933 SCIP_CALL( ensureRstatMem(lpi, lpnrows) );
    2934
    2935 /* unpack LPi state data */
    2936 lpistateUnpack(lpistate, lpi->cstat, lpi->rstat);
    2937
    2938 /* extend the basis to the current LP beyond the previously existing columns */
    2939 for( i = lpistate->ncols; i < lpncols; ++i )
    2940 {
    2941 SCIP_Real bnd = lpi->spx->lowerReal(i);
    2942 if ( SCIPlpiExactIsInfinity(lpi, REALABS(bnd)) )
    2943 {
    2944 /* if lower bound is +/- infinity -> try upper bound */
    2945 bnd = lpi->spx->lowerReal(i);
    2946 if ( SCIPlpiExactIsInfinity(lpi, REALABS(bnd)) )
    2947 /* variable is free */
    2948 lpi->cstat[i] = SCIP_BASESTAT_ZERO; /*lint !e641*/
    2949 else
    2950 /* use finite upper bound */
    2951 lpi->cstat[i] = SCIP_BASESTAT_UPPER; /*lint !e641*/
    2952 }
    2953 else
    2954 /* use finite lower bound */
    2955 lpi->cstat[i] = SCIP_BASESTAT_LOWER; /*lint !e641*/
    2956 }
    2957 for( i = lpistate->nrows; i < lpnrows; ++i )
    2958 lpi->rstat[i] = SCIP_BASESTAT_BASIC; /*lint !e641*/
    2959
    2960 /* load basis information */
    2961 SCIP_CALL( SCIPlpiExactSetBase(lpi, lpi->cstat, lpi->rstat) );
    2962
    2963 return SCIP_OKAY;
    2964}
    2965
    2966/** clears current LPi state (like basis information) of the solver */
    2968 SCIP_LPIEXACT* lpi /**< LP interface structure */
    2969 )
    2970{ /*lint --e{715}*/
    2971 SCIPdebugMessage("calling SCIPlpiClearState()\n");
    2972
    2973 assert(lpi != NULL);
    2974 assert(lpi->spx != NULL);
    2975
    2976 try
    2977 {
    2978 lpi->spx->clearBasis();
    2979 }
    2980#ifndef NDEBUG
    2981 catch( const SPxException& x )
    2982 {
    2983 std::string s = x.what();
    2984 SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
    2985#else
    2986 catch( const SPxException& )
    2987 {
    2988#endif
    2989 assert( lpi->spx->status() != SPxSolver::OPTIMAL );
    2990 return SCIP_LPERROR;
    2991 }
    2992
    2993 return SCIP_OKAY;
    2994}
    2995
    2996/** frees LPi state information */
    2998 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    2999 BMS_BLKMEM* blkmem, /**< block memory */
    3000 SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
    3001 )
    3002{ /*lint --e{715}*/
    3003 SCIPdebugMessage("calling SCIPlpiFreeState()\n");
    3004
    3005 assert(lpi != NULL);
    3006 assert(lpistate != NULL);
    3007 assert(blkmem != NULL);
    3008
    3009 if ( *lpistate != NULL )
    3010 lpistateFree(lpistate, blkmem);
    3011
    3012 return SCIP_OKAY;
    3013}
    3014
    3015/** checks, whether the given LP state contains simplex basis information */
    3017 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    3018 SCIP_LPISTATE* lpistate /**< LP state information (like basis information), or NULL */
    3019 )
    3020{ /*lint --e{715}*/
    3021 assert(lpi != NULL);
    3022 return TRUE;
    3023}
    3024
    3025/** reads LP state (like basis information from a file */
    3027 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    3028 const char* fname /**< file name */
    3029 )
    3030{
    3031 SCIPdebugMessage("calling SCIPlpiReadState()\n");
    3032 assert(lpi != NULL);
    3033 assert(lpi->spx != NULL);
    3034 assert(fname != NULL);
    3035
    3036 assert( lpi->spx->preStrongbranchingBasisFreed() );
    3037
    3038 bool success;
    3039 SOPLEX_TRY( lpi->messagehdlr, success = lpi->spx->readBasisFile(fname, 0, 0) );
    3040
    3041 return success ? SCIP_OKAY : SCIP_LPERROR;
    3042}
    3043
    3044/** writes LPi state (i.e. basis information) to a file */
    3046 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    3047 const char* fname /**< file name */
    3048 )
    3049{
    3050 assert(lpi != NULL);
    3051 assert(lpi->spx != NULL);
    3052 assert(fname != NULL);
    3053 SCIPdebugMessage("calling SCIPlpiWriteState()\n");
    3054
    3055 assert( lpi->spx->preStrongbranchingBasisFreed() );
    3056
    3057 bool res;
    3058 SOPLEX_TRY( lpi->messagehdlr, res = lpi->spx->writeBasisFile(fname, 0, 0) );
    3059
    3060 if ( ! res )
    3061 return SCIP_LPERROR;
    3062
    3063 return SCIP_OKAY;
    3064}
    3065
    3066/**@} */
    3067
    3068/*
    3069 * Parameter Methods
    3070 */
    3071
    3072/**@name Parameter Methods */
    3073/**@{ */
    3074
    3075/** gets integer parameter of LP */
    3077 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    3078 SCIP_LPPARAM type, /**< parameter number */
    3079 int* ival /**< buffer to store the parameter value */
    3080 )
    3081{
    3082 int scaleparam;
    3083
    3084 SCIPdebugMessage("calling SCIPlpiExactGetIntpar()\n");
    3085
    3086 assert(lpi != NULL);
    3087 assert(lpi->spx != NULL);
    3088 assert(ival != NULL);
    3089
    3090 switch( type )
    3091 {
    3093 *ival = (int) lpi->spx->getFromScratch();
    3094 break;
    3095 case SCIP_LPPAR_LPINFO:
    3096 *ival = (int) lpi->spx->getLpInfo();
    3097 break;
    3098 case SCIP_LPPAR_LPITLIM:
    3099 *ival = lpi->spx->intParam(SoPlex::ITERLIMIT);
    3100 if( *ival == -1 )
    3101 *ival = INT_MAX;
    3102 break;
    3104 *ival = lpi->spx->intParam(SoPlex::SIMPLIFIER) == (int) SoPlex::SIMPLIFIER_AUTO;
    3105 break;
    3106 case SCIP_LPPAR_PRICING:
    3107 *ival = (int) lpi->pricing;
    3108 break;
    3109 case SCIP_LPPAR_SCALING:
    3110 scaleparam = lpi->spx->intParam(SoPlex::SCALER);
    3111
    3112 if( scaleparam == SoPlex::SCALER_OFF )
    3113 *ival = 0;
    3114 else if( scaleparam == SoPlex::SCALER_BIEQUI )
    3115 *ival = 1;
    3116#if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 2)
    3117 else
    3118 {
    3119 assert(scaleparam == SoPlex::SCALER_LEASTSQ);
    3120 *ival = 2;
    3121 }
    3122#else
    3123 else
    3124 {
    3125 assert(scaleparam == SoPlex::SCALER_GEO8);
    3126 *ival = 2;
    3127 }
    3128#endif
    3129 break;
    3130#if SOPLEX_VERSION >= 201
    3131 case SCIP_LPPAR_TIMING:
    3132 *ival = (int) (lpi->spx->intParam(SoPlex::TIMER));
    3133 break;
    3134#endif
    3135#if SOPLEX_VERSION >= 230 || (SOPLEX_VERSION == 220 && SOPLEX_SUBVERSION >= 3)
    3137 *ival = (int) lpi->spx->randomSeed();
    3138 break;
    3139#endif
    3140#if SOPLEX_APIVERSION >= 1
    3142 *ival = (int) lpi->spx->intParam(SoPlex::FACTOR_UPDATE_MAX);
    3143 break;
    3144#endif
    3145 default:
    3146 return SCIP_PARAMETERUNKNOWN;
    3147 } /*lint !e788*/
    3148
    3149 return SCIP_OKAY;
    3150}
    3151
    3152/** sets integer parameter of LP */
    3154 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    3155 SCIP_LPPARAM type, /**< parameter number */
    3156 int ival /**< parameter value */
    3157 )
    3158{
    3159 SCIPdebugMessage("calling SCIPlpiExactSetIntpar()\n");
    3160
    3161 assert(lpi != NULL);
    3162 assert(lpi->spx != NULL);
    3163
    3164 switch( type )
    3165 {
    3167 assert(ival == TRUE || ival == FALSE);
    3168 lpi->spx->setFromScratch(bool(ival));
    3169 break;
    3170 case SCIP_LPPAR_LPINFO:
    3171 assert(ival == TRUE || ival == FALSE);
    3172 lpi->spx->setLpInfo(bool(ival));
    3173 break;
    3174 case SCIP_LPPAR_LPITLIM:
    3175 assert( ival >= 0 );
    3176 /* -1 <= ival, -1 meaning no time limit, 0 stopping immediately */
    3177 if( ival >= INT_MAX )
    3178 ival = -1;
    3179 (void) lpi->spx->setIntParam(SoPlex::ITERLIMIT, ival);
    3180 break;
    3182 assert(ival == TRUE || ival == FALSE);
    3183 (void) lpi->spx->setIntParam(SoPlex::SIMPLIFIER, (int) (ival ? SoPlex::SIMPLIFIER_AUTO : SoPlex::SIMPLIFIER_OFF));
    3184 break;
    3185 case SCIP_LPPAR_PRICING:
    3186 lpi->pricing = (SCIP_PRICING)ival;
    3187 switch( lpi->pricing )
    3188 {
    3190 case SCIP_PRICING_AUTO:
    3191 (void) lpi->spx->setIntParam(SoPlex::PRICER, (int) SoPlex::PRICER_AUTO);
    3192 break;
    3193 case SCIP_PRICING_FULL:
    3194 (void) lpi->spx->setIntParam(SoPlex::PRICER, (int) SoPlex::PRICER_STEEP);
    3195 break;
    3197 (void) lpi->spx->setIntParam(SoPlex::PRICER, (int) SoPlex::PRICER_PARMULT);
    3198 break;
    3199 case SCIP_PRICING_STEEP:
    3200 (void) lpi->spx->setIntParam(SoPlex::PRICER, (int) SoPlex::PRICER_STEEP);
    3201 break;
    3203 (void) lpi->spx->setIntParam(SoPlex::PRICER, (int) SoPlex::PRICER_QUICKSTEEP);
    3204 break;
    3205 case SCIP_PRICING_DEVEX:
    3206 (void) lpi->spx->setIntParam(SoPlex::PRICER, (int) SoPlex::PRICER_DEVEX);
    3207 break;
    3208 default:
    3209 return SCIP_LPERROR;
    3210 }
    3211 break;
    3212 case SCIP_LPPAR_SCALING:
    3213 assert(ival >= 0 && ival <= 2);
    3214 if( ival == 0 )
    3215 (void) lpi->spx->setIntParam(SoPlex::SCALER, (int) SoPlex::SCALER_OFF);
    3216 else if( ival == 1 )
    3217 (void) lpi->spx->setIntParam(SoPlex::SCALER, (int) SoPlex::SCALER_BIEQUI);
    3218 else
    3219#if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 2)
    3220 (void) lpi->spx->setIntParam(SoPlex::SCALER, (int) SoPlex::SCALER_LEASTSQ);
    3221#else
    3222 (void) lpi->spx->setIntParam(SoPlex::SCALER, (int) SoPlex::SCALER_GEO8);
    3223#endif
    3224
    3225 break;
    3226#if SOPLEX_VERSION >= 201
    3227 case SCIP_LPPAR_TIMING:
    3228 assert(ival >= 0 && ival < 3);
    3229 (void) lpi->spx->setIntParam(SoPlex::TIMER, ival);
    3230 break;
    3231#endif
    3232#if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 3)
    3234 lpi->spx->setRandomSeed((unsigned long)(long)ival);
    3235 break;
    3236#endif
    3237#if SOPLEX_VERSION > 221 || (SOPLEX_VERSION >= 221 && SOPLEX_SUBVERSION >= 3)
    3239 assert(ival >= 0 && ival < 3);
    3240 (void) lpi->spx->setIntParam(SoPlex::SOLUTION_POLISHING, ival);
    3241 break;
    3242#endif
    3243#if SOPLEX_APIVERSION >= 1
    3245 assert(ival >= 0);
    3246 (void) lpi->spx->setIntParam(SoPlex::FACTOR_UPDATE_MAX, ival);
    3247 break;
    3248#endif
    3249
    3250 default:
    3251 return SCIP_PARAMETERUNKNOWN;
    3252 } /*lint !e788*/
    3253
    3254 return SCIP_OKAY;
    3255}
    3256
    3257/** gets floating point parameter of LP */
    3259 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    3260 SCIP_LPPARAM type, /**< parameter number */
    3261 SCIP_Real* dval /**< buffer to store the parameter value */
    3262 )
    3263{
    3264 SCIPdebugMessage("calling SCIPlpiExactGetRealpar()\n");
    3265
    3266 assert(lpi != NULL);
    3267 assert(lpi->spx != NULL);
    3268 assert(dval != NULL);
    3269
    3270 switch( type )
    3271 {
    3272 case SCIP_LPPAR_FEASTOL:
    3273 *dval = 0.0; //lpi->spx->feastol();
    3274 break;
    3276 *dval = 0.0; //lpi->spx->opttol();
    3277 break;
    3278 case SCIP_LPPAR_OBJLIM:
    3279 if ( lpi->spx->intParam(SoPlex::OBJSENSE) == SoPlex::OBJSENSE_MINIMIZE )
    3280 *dval = lpi->spx->realParam(SoPlex::OBJLIMIT_UPPER);
    3281 else
    3282 *dval = lpi->spx->realParam(SoPlex::OBJLIMIT_LOWER);
    3283 break;
    3284 case SCIP_LPPAR_LPTILIM:
    3285 *dval = lpi->spx->realParam(SoPlex::TIMELIMIT);
    3286 break;
    3288 *dval = lpi->spx->realParam(SoPlex::REPRESENTATION_SWITCH);
    3289 if( *dval >= SCIPlpiExactInfinity(lpi) )
    3290 *dval = -1.0;
    3291 break;
    3293 *dval = lpi->conditionlimit;
    3294 break;
    3295 default:
    3296 return SCIP_PARAMETERUNKNOWN;
    3297 } /*lint !e788*/
    3298
    3299 return SCIP_OKAY;
    3300}
    3301
    3302/** sets floating point parameter of LP */
    3304 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    3305 SCIP_LPPARAM type, /**< parameter number */
    3306 SCIP_Real dval /**< parameter value */
    3307 )
    3308{
    3309 SCIPdebugMessage("calling SCIPlpiExactSetRealpar()\n");
    3310
    3311 assert(lpi != NULL);
    3312 assert(lpi->spx != NULL);
    3313
    3314 switch( type )
    3315 {
    3316 case SCIP_LPPAR_OBJLIM:
    3317 /* no restrictions on dval */
    3318 if ( lpi->spx->intParam(SoPlex::OBJSENSE) == SoPlex::OBJSENSE_MINIMIZE )
    3319 (void) lpi->spx->setRealParam(SoPlex::OBJLIMIT_UPPER, dval);
    3320 else
    3321 (void) lpi->spx->setRealParam(SoPlex::OBJLIMIT_LOWER, dval);
    3322 break;
    3323 case SCIP_LPPAR_LPTILIM:
    3324 assert( dval > 0.0 );
    3325 /* soplex requires 0 < dval < DEFAULT_INFINITY (= 1e100), -1 means unlimited */
    3326 (void) lpi->spx->setRealParam(SoPlex::TIMELIMIT, dval);
    3327 break;
    3329 /* 0 <= dval <= inf */
    3330 assert( dval >= 0.0 || dval == -1.0 );
    3331 if( dval == -1 )
    3332 (void) lpi->spx->setRealParam(SoPlex::REPRESENTATION_SWITCH, SCIPlpiExactInfinity(lpi));
    3333 else
    3334 (void) lpi->spx->setRealParam(SoPlex::REPRESENTATION_SWITCH, dval);
    3335 break;
    3337 lpi->conditionlimit = dval;
    3338 lpi->checkcondition = (dval >= 0.0);
    3339 break;
    3340 default:
    3341 return SCIP_PARAMETERUNKNOWN;
    3342 } /*lint !e788*/
    3343
    3344 return SCIP_OKAY;
    3345}
    3346
    3347/**@} */
    3348
    3349
    3350/*
    3351 * Numerical Methods
    3352 */
    3353
    3354/**@name Numerical Methods */
    3355/**@{ */
    3356
    3357/** returns value treated as infinity in the LP solver */
    3359 SCIP_LPIEXACT* lpi /**< LP interface structure */
    3360 )
    3361{
    3362 assert(lpi != NULL);
    3363 SCIPdebugMessage("calling SCIPlpiInfinity()\n");
    3364
    3365 return lpi->spx->realParam(SoPlex::INFTY);
    3366}
    3367
    3368/** checks if given value is treated as infinity in the LP solver */
    3370 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    3371 SCIP_Real val /**< the value */
    3372 )
    3373{
    3374 assert(lpi != NULL);
    3375 SCIPdebugMessage("calling SCIPlpiExactIsInfinity()\n");
    3376
    3377 return (val >= lpi->spx->realParam(SoPlex::INFTY));
    3378}
    3379
    3380/**@} */
    3381
    3382
    3383/*
    3384 * File Interface Methods
    3385 */
    3386
    3387/**@name File Interface Methods */
    3388/**@{ */
    3389
    3390/** returns, whether the given file exists */
    3391static
    3393 const char* filename /**< file name */
    3394 )
    3395{
    3396 FILE* f;
    3397
    3398 f = fopen(filename, "r");
    3399 if( f == NULL )
    3400 return FALSE;
    3401
    3402 fclose(f);
    3403
    3404 return TRUE;
    3405}
    3406
    3407/** reads LP from a file */
    3409 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    3410 const char* fname /**< file name */
    3411 )
    3412{
    3413 SCIPdebugMessage("calling SCIPlpiReadLP()\n");
    3414
    3415 assert(lpi != NULL);
    3416 assert(lpi->spx != NULL);
    3417 assert(fname != NULL);
    3418
    3419 assert( lpi->spx->preStrongbranchingBasisFreed() );
    3420
    3421 if( !fileExists(fname) )
    3422 return SCIP_NOFILE;
    3423
    3424 try
    3425 {
    3426 assert(lpi->spx->intParam(SoPlex::READMODE) == SoPlex::READMODE_RATIONAL);
    3427 if( !lpi->spx->readFile(fname) )
    3428 return SCIP_READERROR;
    3429 }
    3430#ifndef NDEBUG
    3431 catch( const SPxException& x )
    3432 {
    3433 std::string s = x.what();
    3434 SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
    3435#else
    3436 catch( const SPxException& )
    3437 {
    3438#endif
    3439 return SCIP_READERROR;
    3440 }
    3441
    3442 return SCIP_OKAY;
    3443}
    3444
    3445/** writes LP to a file */
    3447 SCIP_LPIEXACT* lpi, /**< LP interface structure */
    3448 const char* fname /**< file name */
    3449 )
    3450{
    3451 SCIPdebugMessage("calling SCIPlpiWriteLP()\n");
    3452
    3453 assert(lpi != NULL);
    3454 assert(lpi->spx != NULL);
    3455 assert(fname != NULL);
    3456
    3457 try
    3458 {
    3459 (void) lpi->spx->writeFileRational(fname);
    3460 }
    3461#ifndef NDEBUG
    3462 catch( const SPxException& x )
    3463 {
    3464 std::string s = x.what();
    3465 SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
    3466#else
    3467 catch( const SPxException& )
    3468 {
    3469#endif
    3470 return SCIP_WRITEERROR;
    3471 }
    3472
    3473 return SCIP_OKAY;
    3474}
    3475
    3476/**@} */
    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
    SCIP_VAR ** x
    Definition: circlepacking.c:63
    void setProbname(const char *probname)
    DataArray< SPxSolver::VarStatus > & colStat()
    bool checkConsistentSides() const
    bool getFromScratch() const
    SPxSolver::Status doSolve(bool printwarning=true)
    void savePreStrongbranchingBasis()
    bool preStrongbranchingBasisFreed() const
    SPxexSCIP(SCIP_MESSAGEHDLR *messagehdlr=NULL, const char *probname=NULL)
    void freePreStrongbranchingBasis()
    Real getObjLimit() const
    void setRep(SPxSolver::Representation p_rep)
    void trySolve(bool printwarning=true)
    bool getLpInfo() const
    bool checkConsistentBounds() const
    void setFromScratch(bool fs)
    void setLpInfo(bool lpinfo)
    DataArray< SPxSolver::VarStatus > & rowStat()
    virtual ~SPxexSCIP()
    void restorePreStrongbranchingBasis()
    common defines and data types used in all packages of SCIP
    #define SCIP_Bool
    Definition: def.h:98
    #define SCIP_ALLOC(x)
    Definition: def.h:373
    #define SCIP_Real
    Definition: def.h:163
    #define TRUE
    Definition: def.h:100
    #define FALSE
    Definition: def.h:101
    #define MAX(x, y)
    Definition: def.h:227
    #define SCIPABORT()
    Definition: def.h:334
    #define REALABS(x)
    Definition: def.h:189
    #define SCIP_CALL(x)
    Definition: def.h:362
    void * SCIPlpiExactGetSolverPointer(SCIP_LPIEXACT *lpi)
    SCIP_Bool SCIPlpiExactHasDualRay(SCIP_LPIEXACT *lpi)
    SCIP_RETCODE SCIPlpiExactSetRealpar(SCIP_LPIEXACT *lpi, SCIP_LPPARAM type, SCIP_Real dval)
    SCIP_RETCODE SCIPlpiExactSetBase(SCIP_LPIEXACT *lpi, int *cstat, int *rstat)
    SCIP_RETCODE SCIPlpiExactReadState(SCIP_LPIEXACT *lpi, const char *fname)
    SCIP_Bool SCIPlpiExactHasStateBasis(SCIP_LPIEXACT *lpi, SCIP_LPISTATE *lpistate)
    SCIP_RETCODE SCIPlpiExactGetObj(SCIP_LPIEXACT *lpi, int firstcol, int lastcol, SCIP_RATIONAL **vals)
    SCIP_RETCODE SCIPlpiExactStartStrongbranch(SCIP_LPIEXACT *lpi)
    SCIP_RETCODE SCIPlpiExactIgnoreInstability(SCIP_LPIEXACT *lpi, SCIP_Bool *success)
    SCIP_RETCODE SCIPlpiExactGetObjval(SCIP_LPIEXACT *lpi, SCIP_RATIONAL *objval)
    SCIP_Bool SCIPlpiExactIsDualUnbounded(SCIP_LPIEXACT *lpi)
    SCIP_Bool SCIPlpiExactHasBarrierSolve(void)
    SCIP_RETCODE SCIPlpiExactWriteLP(SCIP_LPIEXACT *lpi, const char *fname)
    SCIP_Bool SCIPlpiExactHasPrimalRay(SCIP_LPIEXACT *lpi)
    SCIP_Bool SCIPlpiExactExistsDualRay(SCIP_LPIEXACT *lpi)
    SCIP_RETCODE SCIPlpiExactGetDualfarkas(SCIP_LPIEXACT *lpi, SCIP_RATIONAL **dualfarkas)
    SCIP_RETCODE SCIPlpiExactEndStrongbranch(SCIP_LPIEXACT *lpi)
    SCIP_RETCODE SCIPlpiExactSolveDual(SCIP_LPIEXACT *lpi)
    const char * SCIPlpiExactGetSolverDesc(void)
    SCIP_RETCODE SCIPlpiExactChgObjsen(SCIP_LPIEXACT *lpi, SCIP_OBJSEN objsen)
    SCIP_RETCODE SCIPlpiExactSetIntpar(SCIP_LPIEXACT *lpi, SCIP_LPPARAM type, int ival)
    SCIP_RETCODE SCIPlpiExactWriteState(SCIP_LPIEXACT *lpi, const char *fname)
    SCIP_RETCODE SCIPlpiExactChgCoef(SCIP_LPIEXACT *lpi, int row, int col, SCIP_RATIONAL *newval)
    SCIP_Bool SCIPlpiExactWasSolved(SCIP_LPIEXACT *lpi)
    SCIP_Bool SCIPlpiExactIsPrimalUnbounded(SCIP_LPIEXACT *lpi)
    SCIP_RETCODE SCIPlpiExactGetSides(SCIP_LPIEXACT *lpi, int firstrow, int lastrow, SCIP_RATIONAL **lhss, SCIP_RATIONAL **rhss)
    SCIP_Bool SCIPlpiExactHasDualSolve(void)
    const char * SCIPlpiExactGetSolverName(void)
    SCIP_RETCODE SCIPlpiExactGetCols(SCIP_LPIEXACT *lpi, int firstcol, int lastcol, SCIP_RATIONAL **lb, SCIP_RATIONAL **ub, int *nnonz, int *beg, int *ind, SCIP_RATIONAL **val)
    SCIP_Bool SCIPlpiExactIsPrimalInfeasible(SCIP_LPIEXACT *lpi)
    SCIP_Real SCIPlpiExactInfinity(SCIP_LPIEXACT *lpi)
    SCIP_RETCODE SCIPlpiExactGetRows(SCIP_LPIEXACT *lpi, int firstrow, int lastrow, SCIP_RATIONAL **lhs, SCIP_RATIONAL **rhs, int *nnonz, int *beg, int *ind, SCIP_RATIONAL **val)
    SCIP_RETCODE SCIPlpiExactGetSolFeasibility(SCIP_LPIEXACT *lpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
    SCIP_RETCODE SCIPlpiExactGetBInvCol(SCIP_LPIEXACT *lpi, int c, SCIP_RATIONAL **coef, int *inds, int *ninds)
    SCIP_Bool SCIPlpiExactExistsPrimalRay(SCIP_LPIEXACT *lpi)
    SCIP_Bool SCIPlpiExactIsInfinity(SCIP_LPIEXACT *lpi, SCIP_Real val)
    SCIP_Bool SCIPlpiExactHasPrimalSolve(void)
    SCIP_RETCODE SCIPlpiExactAddRows(SCIP_LPIEXACT *lpi, int nrows, SCIP_RATIONAL **lhs, SCIP_RATIONAL **rhs, char **rownames, int nnonz, int *beg, int *ind, SCIP_RATIONAL **val)
    SCIP_RETCODE SCIPlpiExactCreate(SCIP_LPIEXACT **lpi, SCIP_MESSAGEHDLR *messagehdlr, const char *name, SCIP_OBJSEN objsen)
    SCIP_Bool SCIPlpiExactIsIterlimExc(SCIP_LPIEXACT *lpi)
    SCIP_RETCODE SCIPlpiExactLoadColLP(SCIP_LPIEXACT *lpi, SCIP_OBJSEN objsen, int ncols, SCIP_RATIONAL **obj, SCIP_RATIONAL **lb, SCIP_RATIONAL **ub, char **colnames, int nrows, SCIP_RATIONAL **lhs, SCIP_RATIONAL **rhs, char **, int nnonz, int *beg, int *ind, SCIP_RATIONAL **val)
    SCIP_Bool SCIPlpiExactIsPrimalFeasible(SCIP_LPIEXACT *lpi)
    SCIP_Bool SCIPlpiExactIsDualFeasible(SCIP_LPIEXACT *lpi)
    SCIP_RETCODE SCIPlpiExactReadLP(SCIP_LPIEXACT *lpi, const char *fname)
    SCIP_RETCODE SCIPlpiExactGetBasisInd(SCIP_LPIEXACT *lpi, int *bind)
    SCIP_RETCODE SCIPlpiExactGetObjsen(SCIP_LPIEXACT *lpi, SCIP_OBJSEN *objsen)
    SCIP_Bool SCIPlpiExactIsOptimal(SCIP_LPIEXACT *lpi)
    SCIP_RETCODE SCIPlpiExactGetRowNames(SCIP_LPIEXACT *lpi, int firstrow, int lastrow, char **rownames, char *namestorage, int namestoragesize, int *storageleft)
    SCIP_RETCODE SCIPlpiExactAddCols(SCIP_LPIEXACT *lpi, int ncols, SCIP_RATIONAL **obj, SCIP_RATIONAL **lb, SCIP_RATIONAL **ub, char **colnames, int nnonz, int *beg, int *ind, SCIP_RATIONAL **val)
    SCIP_RETCODE SCIPlpiExactGetBase(SCIP_LPIEXACT *lpi, int *cstat, int *rstat)
    SCIP_RETCODE SCIPlpiExactDelCols(SCIP_LPIEXACT *lpi, int firstcol, int lastcol)
    SCIP_RETCODE SCIPlpiExactChgObj(SCIP_LPIEXACT *lpi, int ncols, int *ind, SCIP_RATIONAL **obj)
    SCIP_RETCODE SCIPlpiExactGetPrimalRay(SCIP_LPIEXACT *lpi, SCIP_RATIONAL **ray)
    SCIP_RETCODE SCIPlpiExactGetBounds(SCIP_LPIEXACT *lpi, int firstcol, int lastcol, SCIP_RATIONAL **lbs, SCIP_RATIONAL **ubs)
    int SCIPlpiExactGetInternalStatus(SCIP_LPIEXACT *lpi)
    SCIP_RETCODE SCIPlpiDelColset(SCIP_LPIEXACT *lpi, int *dstat)
    SCIP_RETCODE SCIPlpiExactGetCoef(SCIP_LPIEXACT *lpi, int row, int col, SCIP_RATIONAL *val)
    SCIP_RETCODE SCIPlpiExactGetColNames(SCIP_LPIEXACT *lpi, int firstcol, int lastcol, char **colnames, char *namestorage, int namestoragesize, int *storageleft)
    SCIP_RETCODE SCIPlpiExactClear(SCIP_LPIEXACT *lpi)
    SCIP_RETCODE SCIPlpiExactGetNNonz(SCIP_LPIEXACT *lpi, int *nnonz)
    SCIP_RETCODE SCIPlpiExactFree(SCIP_LPIEXACT **lpi)
    SCIP_Bool SCIPlpiExactIsDualInfeasible(SCIP_LPIEXACT *lpi)
    SCIP_Bool SCIPlpiExactIsObjlimExc(SCIP_LPIEXACT *lpi)
    SCIP_RETCODE SCIPlpiExactClearState(SCIP_LPIEXACT *lpi)
    SCIP_RETCODE SCIPlpiExactGetNCols(SCIP_LPIEXACT *lpi, int *ncols)
    SCIP_RETCODE SCIPlpiExactSolveBarrier(SCIP_LPIEXACT *lpi, SCIP_Bool crossover)
    SCIP_RETCODE SCIPlpiExactGetBInvRow(SCIP_LPIEXACT *lpi, int r, SCIP_RATIONAL **coef, int *inds, int *ninds)
    SCIP_RETCODE SCIPlpiExactChgSides(SCIP_LPIEXACT *lpi, int nrows, int *ind, SCIP_RATIONAL **lhs, SCIP_RATIONAL **rhs)
    SCIP_RETCODE SCIPlpiExactGetState(SCIP_LPIEXACT *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
    SCIP_RETCODE SCIPlpiExactDelRows(SCIP_LPIEXACT *lpi, int firstrow, int lastrow)
    SCIP_RETCODE SCIPlpiExactGetNRows(SCIP_LPIEXACT *lpi, int *nrows)
    SCIP_Bool SCIPlpiExactIsTimelimExc(SCIP_LPIEXACT *lpi)
    SCIP_RETCODE SCIPlpiExactGetRealpar(SCIP_LPIEXACT *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
    SCIP_RETCODE SCIPlpiExactChgBounds(SCIP_LPIEXACT *lpi, int ncols, int *ind, SCIP_RATIONAL **lb, SCIP_RATIONAL **ub)
    SCIP_RETCODE SCIPlpiExactFreeState(SCIP_LPIEXACT *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
    SCIP_RETCODE SCIPlpiExactDelRowset(SCIP_LPIEXACT *lpi, int *dstat)
    SCIP_RETCODE SCIPlpiExactGetSol(SCIP_LPIEXACT *lpi, SCIP_RATIONAL *objval, SCIP_RATIONAL **primsol, SCIP_RATIONAL **dualsol, SCIP_RATIONAL **activity, SCIP_RATIONAL **redcost)
    SCIP_RETCODE SCIPlpiExactSolvePrimal(SCIP_LPIEXACT *lpi)
    SCIP_RETCODE SCIPlpiExactGetIntpar(SCIP_LPIEXACT *lpi, SCIP_LPPARAM type, int *ival)
    SCIP_RETCODE SCIPlpiExactSetState(SCIP_LPIEXACT *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE *lpistate)
    SCIP_RETCODE SCIPlpiExactGetIterations(SCIP_LPIEXACT *lpi, int *iterations)
    SCIP_RETCODE SCIPlpiExactSetIntegralityInformation(SCIP_LPIEXACT *lpi, int ncols, int *intInfo)
    void SCIPrationalSetInfinity(SCIP_RATIONAL *res)
    Definition: rational.cpp:619
    SCIP_Real SCIPrationalGetReal(SCIP_RATIONAL *rational)
    Definition: rational.cpp:2084
    SCIP_Bool SCIPrationalIsAbsInfinity(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1681
    SCIP_Bool SCIPrationalIsPositive(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1641
    SCIP_Bool SCIPrationalIsZero(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1625
    void SCIPrationalSetNegInfinity(SCIP_RATIONAL *res)
    Definition: rational.cpp:631
    SCIP_Bool SCIPrationalIsInfinity(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1661
    SCIP_Bool SCIPrationalIsNegInfinity(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1671
    static SCIP_RETCODE optimize(SCIP *scip, SCIP_SOL *worksol, SCIP_VAR **vars, int *blockstart, int *blockend, int nblocks, OPTTYPE opttype, SCIP_Real *activities, int nrows, SCIP_Bool *improvement, SCIP_Bool *varboundserr, SCIP_HEURDATA *heurdata)
    Definition: heur_twoopt.c:967
    SCIP_DUALPACKET ROWPACKET
    Definition: lpi_clp.cpp:128
    SCIP_DUALPACKET COLPACKET
    Definition: lpi_clp.cpp:126
    static void setIntParam(SCIP_LPI *lpi, int const param, int const parval)
    Definition: lpi_cpx.c:654
    #define FEASTOL
    Definition: lpi_qso.c:99
    interface methods for specific exact LP solvers
    static void RsetSpxR(SCIP_LPIEXACT *lpi, SCIP_RATIONAL *r, const soplex::Rational &spxr)
    static void lpistatePack(SCIP_LPISTATE *lpistate, const int *cstat, const int *rstat)
    #define NULL
    static void lpistateUnpack(const SCIP_LPISTATE *lpistate, int *cstat, int *rstat)
    static SCIP_Bool fileExists(const char *filename)
    #define SOPLEX_TRY(messagehdlr, x)
    static int rowpacketNum(int nrows)
    SCIP_DUALPACKET ROWPACKET
    #define SOPLEX_VERBLEVEL
    static const char spxdesc[200]
    #define COLS_PER_PACKET
    static void invalidateSolution(SCIP_LPIEXACT *lpi)
    static void lpistateFree(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem)
    SCIP_DUALPACKET COLPACKET
    static SCIP_RETCODE ensureCstatMem(SCIP_LPIEXACT *lpi, int num)
    static SCIP_RETCODE spxSolve(SCIP_LPIEXACT *lpi)
    static int colpacketNum(int ncols)
    static SCIP_RETCODE ensureRstatMem(SCIP_LPIEXACT *lpi, int num)
    #define CHECK_SOPLEX_PARAM(x)
    #define SOPLEX_SUBVERSION
    static void SpxRSetRat(SCIP_LPIEXACT *lpi, soplex::Rational &spxr, SCIP_RATIONAL *src)
    static SCIP_RETCODE lpistateCreate(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem, int ncols, int nrows)
    #define SOPLEX_TRY_ABORT(x)
    #define ROWS_PER_PACKET
    static const char spxname[20]
    static void RsetSpxVector(SCIP_LPIEXACT *lpi, SCIP_RATIONAL **r, VectorRational src)
    memory allocation routines
    #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 BMSallocMemoryCPP(size)
    Definition: memory.h:121
    #define BMSallocBlockMemoryArray(mem, ptr, num)
    Definition: memory.h:454
    #define BMSfreeBlockMemoryArray(mem, ptr, num)
    Definition: memory.h:467
    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
    static int COI_CALLCONV Status(int MODSTA, int SOLSTA, int ITER, double OBJVAL, void *USRMEM)
    Definition: nlpi_conopt.c:569
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    #define SCIPdebugMessage
    Definition: pub_message.h:96
    wrapper for rational number arithmetic
    wrapper for rational number arithmetic that interacts with GMP
    #define UNKNOWN
    Definition: sepa_mcf.c:4110
    SCIP_PRICING pricing
    SCIP_Bool solved
    SCIP_MESSAGEHDLR * messagehdlr
    SPxexSCIP * spx
    SCIP_Bool checkcondition
    SCIP_Real conditionlimit
    COLPACKET * packcstat
    Definition: lpi_clp.cpp:136
    ROWPACKET * packrstat
    Definition: lpi_clp.cpp:137
    definition of wrapper class for rational numbers
    @ SCIP_PRICING_STEEPQSTART
    Definition: type_lpi.h:83
    @ SCIP_PRICING_AUTO
    Definition: type_lpi.h:79
    @ SCIP_PRICING_DEVEX
    Definition: type_lpi.h:84
    @ SCIP_PRICING_STEEP
    Definition: type_lpi.h:82
    @ SCIP_PRICING_FULL
    Definition: type_lpi.h:80
    @ SCIP_PRICING_LPIDEFAULT
    Definition: type_lpi.h:78
    @ SCIP_PRICING_PARTIAL
    Definition: type_lpi.h:81
    enum SCIP_Pricing SCIP_PRICING
    Definition: type_lpi.h:86
    enum SCIP_LPParam SCIP_LPPARAM
    Definition: type_lpi.h:73
    @ SCIP_LPPAR_PRICING
    Definition: type_lpi.h:54
    @ SCIP_LPPAR_REFACTOR
    Definition: type_lpi.h:71
    @ SCIP_LPPAR_LPINFO
    Definition: type_lpi.h:55
    @ SCIP_LPPAR_POLISHING
    Definition: type_lpi.h:70
    @ SCIP_LPPAR_SCALING
    Definition: type_lpi.h:52
    @ SCIP_LPPAR_TIMING
    Definition: type_lpi.h:68
    @ SCIP_LPPAR_LPTILIM
    Definition: type_lpi.h:61
    @ SCIP_LPPAR_PRESOLVING
    Definition: type_lpi.h:53
    @ SCIP_LPPAR_CONDITIONLIMIT
    Definition: type_lpi.h:67
    @ SCIP_LPPAR_RANDOMSEED
    Definition: type_lpi.h:69
    @ SCIP_LPPAR_DUALFEASTOL
    Definition: type_lpi.h:57
    @ SCIP_LPPAR_FROMSCRATCH
    Definition: type_lpi.h:50
    @ SCIP_LPPAR_FEASTOL
    Definition: type_lpi.h:56
    @ SCIP_LPPAR_LPITLIM
    Definition: type_lpi.h:60
    @ SCIP_LPPAR_ROWREPSWITCH
    Definition: type_lpi.h:63
    @ SCIP_LPPAR_OBJLIM
    Definition: type_lpi.h:59
    @ SCIP_BASESTAT_BASIC
    Definition: type_lpi.h:92
    @ SCIP_BASESTAT_UPPER
    Definition: type_lpi.h:93
    @ SCIP_BASESTAT_LOWER
    Definition: type_lpi.h:91
    @ SCIP_BASESTAT_ZERO
    Definition: type_lpi.h:94
    @ SCIP_OBJSEN_MAXIMIZE
    Definition: type_lpi.h:42
    @ SCIP_OBJSEN_MINIMIZE
    Definition: type_lpi.h:43
    enum SCIP_ObjSen SCIP_OBJSEN
    Definition: type_lpi.h:45
    type definitions for specific exact LP solvers interface
    @ SCIP_ISFPREPRESENTABLE_UNKNOWN
    Definition: type_rational.h:48
    type definitions for return codes for SCIP methods
    @ SCIP_LPERROR
    Definition: type_retcode.h:49
    @ SCIP_NOFILE
    Definition: type_retcode.h:47
    @ SCIP_READERROR
    Definition: type_retcode.h:45
    @ SCIP_INVALIDDATA
    Definition: type_retcode.h:52
    @ SCIP_PARAMETERUNKNOWN
    Definition: type_retcode.h:55
    @ SCIP_WRITEERROR
    Definition: type_retcode.h:46
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_NOTIMPLEMENTED
    Definition: type_retcode.h:61
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63