SCIP

    Solving Constraint Integer Programs

    reader_mps.c
    Go to the documentation of this file.
    1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    2/* */
    3/* This file is part of the program and library */
    4/* SCIP --- Solving Constraint Integer Programs */
    5/* */
    6/* Copyright (c) 2002-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 reader_mps.c
    26 * @ingroup DEFPLUGINS_READER
    27 * @brief (extended) MPS file reader
    28 * @author Thorsten Koch
    29 * @author Tobias Achterberg
    30 * @author Marc Pfetsch
    31 * @author Stefan Heinz
    32 * @author Stefan Vigerske
    33 * @author Michael Winkler
    34 *
    35 * This reader/writer handles MPS files in extended MPS format, as it
    36 * is used by CPLEX. In the extended format the limits on variable
    37 * name lengths and coefficients are considerably relaxed. The columns
    38 * in the format are then separated by whitespaces.
    39 *
    40 * @todo Check whether constructing the names for aggregated constraint yields name clashes (aggrXXX).
    41 */
    42
    43/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    44
    46#include <ctype.h>
    47#include "scip/cons_and.h"
    49#include "scip/cons_nonlinear.h"
    51#include "scip/cons_indicator.h"
    52#include "scip/cons_knapsack.h"
    53#include "scip/cons_linear.h"
    54#include "scip/cons_logicor.h"
    55#include "scip/cons_setppc.h"
    56#include "scip/cons_sos1.h"
    57#include "scip/cons_sos2.h"
    58#include "scip/cons_varbound.h"
    59#include "scip/pub_cons.h"
    60#include "scip/pub_fileio.h"
    61#include "scip/pub_message.h"
    62#include "scip/pub_misc.h"
    63#include "scip/pub_misc_sort.h"
    64#include "scip/pub_reader.h"
    65#include "scip/pub_var.h"
    66#include "scip/reader_mps.h"
    67#include "scip/rational.h"
    68#include "scip/scip_cons.h"
    69#include "scip/scip_exact.h"
    70#include "scip/scip_mem.h"
    71#include "scip/scip_message.h"
    72#include "scip/scip_numerics.h"
    73#include "scip/scip_param.h"
    74#include "scip/scip_prob.h"
    75#include "scip/scip_reader.h"
    77#include "scip/scip_var.h"
    78#include <stdlib.h>
    79
    80
    81#define READER_NAME "mpsreader"
    82#define READER_DESC "file reader for MIQPs in IBM's Mathematical Programming System format"
    83#define READER_EXTENSION "mps"
    84
    85#define DEFAULT_LINEARIZE_ANDS TRUE /**< should possible \"and\" constraint be linearized when writing the mps file? */
    86#define DEFAULT_AGGRLINEARIZATION_ANDS TRUE /**< should an aggregated linearization for and constraints be used? */
    87
    88/*
    89 * mps reader internal methods
    90 */
    91
    92#define MPS_MAX_LINELEN 1024
    93#define MPS_MAX_NAMELEN 256
    94#define MPS_MAX_VALUELEN 26
    95#define MPS_MAX_FIELDLEN 20
    96
    97#define PATCH_CHAR '_'
    98#define BLANK ' '
    99
    100/** MPS reading data */
    101struct SCIP_ReaderData
    102{
    103 SCIP_Bool linearizeands;
    104 SCIP_Bool aggrlinearizationands;
    105};
    106
    107/** enum containing all mps sections */
    109{
    128
    129/** mps input structure */
    130struct MpsInput
    131{
    132 MPSSECTION section;
    133 SCIP_FILE* fp;
    134 int lineno;
    135 SCIP_OBJSENSE objsense;
    136 SCIP_Bool haserror;
    137 char buf[MPS_MAX_LINELEN];
    138 const char* f0;
    139 const char* f1;
    140 const char* f2;
    141 const char* f3;
    142 const char* f4;
    143 const char* f5;
    144 char probname[MPS_MAX_NAMELEN];
    145 char objname [MPS_MAX_NAMELEN];
    146 SCIP_Bool initialconss; /**< should model constraints be marked as initial? */
    147 SCIP_Bool dynamicconss; /**< should model constraints be subject to aging? */
    148 SCIP_Bool dynamiccols; /**< should columns be added and removed dynamically to the LP? */
    149 SCIP_Bool dynamicrows; /**< should rows be added and removed dynamically to the LP? */
    150 SCIP_Bool isinteger;
    151 SCIP_Bool isnewformat;
    152};
    153typedef struct MpsInput MPSINPUT;
    154
    155/** sparse matrix representation */
    156struct SparseMatrix
    157{
    158 SCIP_Real* values; /**< matrix element */
    159 SCIP_VAR** columns; /**< corresponding variables */
    160 const char** rows; /**< corresponding constraint names */
    161 int nentries; /**< number of elements in the arrays */
    162 int sentries; /**< number of slots in the arrays */
    163};
    164typedef struct SparseMatrix SPARSEMATRIX;
    165
    166/** struct for mapping cons names to numbers */
    168{
    169 const char* consname; /**< name of the constraint */
    170 int freq; /**< how often we have seen the name */
    171};
    173
    174/** creates the mps input structure */
    175static
    177 SCIP* scip, /**< SCIP data structure */
    178 MPSINPUT** mpsi, /**< mps input structure */
    179 SCIP_FILE* fp /**< file object for the input file */
    180 )
    181{
    182 assert(mpsi != NULL);
    183 assert(fp != NULL);
    184
    186
    187 (*mpsi)->section = MPS_NAME;
    188 (*mpsi)->fp = fp;
    189 (*mpsi)->lineno = 0;
    190 (*mpsi)->objsense = SCIP_OBJSENSE_MINIMIZE;
    191 (*mpsi)->haserror = FALSE;
    192 (*mpsi)->isinteger = FALSE;
    193 (*mpsi)->isnewformat = FALSE;
    194 (*mpsi)->buf [0] = '\0';
    195 (*mpsi)->probname[0] = '\0';
    196 (*mpsi)->objname [0] = '\0';
    197 (*mpsi)->f0 = NULL;
    198 (*mpsi)->f1 = NULL;
    199 (*mpsi)->f2 = NULL;
    200 (*mpsi)->f3 = NULL;
    201 (*mpsi)->f4 = NULL;
    202 (*mpsi)->f5 = NULL;
    203
    204 SCIP_CALL( SCIPgetBoolParam(scip, "reading/initialconss", &((*mpsi)->initialconss)) );
    205 SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicconss", &((*mpsi)->dynamicconss)) );
    206 SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamiccols", &((*mpsi)->dynamiccols)) );
    207 SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicrows", &((*mpsi)->dynamicrows)) );
    208
    209 return SCIP_OKAY;
    210}
    211
    212/** free the mps input structure */
    213static
    215 SCIP* scip, /**< SCIP data structure */
    216 MPSINPUT** mpsi /**< mps input structure */
    217 )
    218{
    220}
    221
    222/** returns the current section */
    223static
    225 const MPSINPUT* mpsi /**< mps input structure */
    226 )
    227{
    228 assert(mpsi != NULL);
    229
    230 return mpsi->section;
    231}
    232
    233/** return the current value of field 0 */
    234static
    235const char* mpsinputField0(
    236 const MPSINPUT* mpsi /**< mps input structure */
    237 )
    238{
    239 assert(mpsi != NULL);
    240
    241 return mpsi->f0;
    242}
    243
    244/** return the current value of field 1 */
    245static
    246const char* mpsinputField1(
    247 const MPSINPUT* mpsi /**< mps input structure */
    248 )
    249{
    250 assert(mpsi != NULL);
    251
    252 return mpsi->f1;
    253}
    254
    255/** return the current value of field 2 */
    256static
    257const char* mpsinputField2(
    258 const MPSINPUT* mpsi /**< mps input structure */
    259 )
    260{
    261 assert(mpsi != NULL);
    262
    263 return mpsi->f2;
    264}
    265
    266/** return the current value of field 3 */
    267static
    268const char* mpsinputField3(
    269 const MPSINPUT* mpsi /**< mps input structure */
    270 )
    271{
    272 assert(mpsi != NULL);
    273
    274 return mpsi->f3;
    275}
    276
    277/** return the current value of field 4 */
    278static
    279const char* mpsinputField4(
    280 const MPSINPUT* mpsi /**< mps input structure */
    281 )
    282{
    283 assert(mpsi != NULL);
    284
    285 return mpsi->f4;
    286}
    287
    288/** return the current value of field 5 */
    289static
    290const char* mpsinputField5(
    291 const MPSINPUT* mpsi /**< mps input structure */
    292 )
    293{
    294 assert(mpsi != NULL);
    295
    296 return mpsi->f5;
    297}
    298
    299/** returns the objective name */
    300static
    301const char* mpsinputObjname(
    302 const MPSINPUT* mpsi /**< mps input structure */
    303 )
    304{
    305 assert(mpsi != NULL);
    306
    307 return mpsi->objname;
    308}
    309
    310/** returns the objective sense */
    311static
    313 const MPSINPUT* mpsi /**< mps input structure */
    314 )
    315{
    316 assert(mpsi != NULL);
    317
    318 return mpsi->objsense;
    319}
    320
    321/** returns if an error was detected */
    322static
    324 const MPSINPUT* mpsi /**< mps input structure */
    325 )
    326{
    327 assert(mpsi != NULL);
    328
    329 return mpsi->haserror;
    330}
    331
    332/** returns the value of the Bool "is integer" in the mps input */
    333static
    335 const MPSINPUT* mpsi /**< mps input structure */
    336 )
    337{
    338 assert(mpsi != NULL);
    339
    340 return mpsi->isinteger;
    341}
    342
    343/** set the section in the mps input structure to given section */
    344static
    346 MPSINPUT* mpsi, /**< mps input structure */
    347 MPSSECTION section /**< section that is set */
    348 )
    349{
    350 assert(mpsi != NULL);
    351
    352 mpsi->section = section;
    353}
    354
    355/** set the problem name in the mps input structure to given problem name */
    356static
    358 MPSINPUT* mpsi, /**< mps input structure */
    359 const char* probname /**< name of the problem to set */
    360 )
    361{
    362 assert(mpsi != NULL);
    363 assert(probname != NULL);
    364 assert(strlen(probname) < sizeof(mpsi->probname));
    365
    366 (void)SCIPmemccpy(mpsi->probname, probname, '\0', MPS_MAX_NAMELEN - 1);
    367}
    368
    369/** set the objective name in the mps input structure to given objective name */
    370static
    372 MPSINPUT* mpsi, /**< mps input structure */
    373 const char* objname /**< name of the objective function to set */
    374 )
    375{
    376 assert(mpsi != NULL);
    377 assert(objname != NULL);
    378 assert(strlen(objname) < sizeof(mpsi->objname));
    379
    380 (void)SCIPmemccpy(mpsi->objname, objname, '\0', MPS_MAX_NAMELEN - 1);
    381}
    382
    383/** set the objective sense in the mps input structure to given objective sense */
    384static
    386 MPSINPUT* mpsi, /**< mps input structure */
    387 SCIP_OBJSENSE sense /**< sense of the objective function */
    388 )
    389{
    390 assert(mpsi != NULL);
    391
    392 mpsi->objsense = sense;
    393}
    394
    395static
    397 MPSINPUT* mpsi /**< mps input structure */
    398 )
    399{
    400 assert(mpsi != NULL);
    401
    402 SCIPerrorMessage("Syntax error in line %d\n", mpsi->lineno);
    403 mpsi->section = MPS_ENDATA;
    404 mpsi->haserror = TRUE;
    405}
    406
    407/** method post a ignore message */
    408static
    410 SCIP* scip, /**< SCIP data structure */
    411 MPSINPUT* mpsi, /**< mps input structure */
    412 const char* what, /**< what get ignored */
    413 const char* what_name, /**< name of that object */
    414 const char* entity, /**< entity */
    415 const char* entity_name, /**< entity name */
    416 SCIP_VERBLEVEL verblevel /**< SCIP verblevel for this message */
    417 )
    418{
    419 assert(mpsi != NULL);
    420 assert(what != NULL);
    421 assert(what_name != NULL);
    422 assert(entity != NULL);
    423 assert(entity_name != NULL);
    424
    425 SCIPverbMessage(scip, verblevel, NULL,
    426 "Warning line %d: %s \"%s\" for %s \"%s\" ignored\n", mpsi->lineno, what, what_name, entity, entity_name);
    427}
    428
    429/** fill the line from \p pos up to column 80 with blanks. */
    430static
    432 char* buf, /**< buffer to clear */
    433 unsigned int pos /**< position to start the clearing process */
    434 )
    435{
    436 unsigned int i;
    437
    438 for(i = pos; i < 80; i++)
    439 buf[i] = BLANK;
    440 buf[80] = '\0';
    441}
    442
    443/** change all blanks inside a field to #PATCH_CHAR. */
    444static
    446 char* buf, /**< buffer to patch */
    447 int beg, /**< position to begin */
    448 int end /**< position to end */
    449 )
    450{
    451 int i;
    452
    453 while( (beg <= end) && (buf[end] == BLANK) )
    454 end--;
    455
    456 while( (beg <= end) && (buf[beg] == BLANK) )
    457 beg++;
    458
    459 for( i = beg; i <= end; i++ )
    460 if( buf[i] == BLANK )
    461 buf[i] = PATCH_CHAR;
    462}
    463
    464/** read a mps format data line and parse the fields. */
    465static
    467 MPSINPUT* mpsi /**< mps input structure */
    468 )
    469{
    470 unsigned int len;
    471 unsigned int i;
    472 int space;
    473 char* s;
    474 SCIP_Bool is_marker;
    475 SCIP_Bool is_empty;
    476 char* nexttok;
    477
    478 do
    479 {
    480 mpsi->f0 = mpsi->f1 = mpsi->f2 = mpsi->f3 = mpsi->f4 = mpsi->f5 = 0;
    481 is_marker = FALSE;
    482
    483 /* Read until we have not a comment line. */
    484 do
    485 {
    486 mpsi->buf[MPS_MAX_LINELEN-1] = '\0';
    487 if( NULL == SCIPfgets(mpsi->buf, (int) sizeof(mpsi->buf), mpsi->fp) )
    488 return FALSE;
    489 mpsi->lineno++;
    490 }
    491 while( *mpsi->buf == '*' ); /* coverity[a_loop_bound] */
    492
    493 /* Normalize line */
    494 len = (unsigned int) strlen(mpsi->buf);
    495
    496 for( i = 0; i < len; i++ )
    497 {
    498 if( (mpsi->buf[i] == '\t') || (mpsi->buf[i] == '\n') || (mpsi->buf[i] == '\r') )
    499 mpsi->buf[i] = BLANK;
    500 }
    501
    502 /* remove trailing whitespace, for len < 14 check to succeed on forplan.mps again */
    503 assert(len < MPS_MAX_LINELEN);
    504 while( len > 0 && mpsi->buf[len-1] == BLANK )
    505 --len;
    506
    507 if( len < 80 )
    508 clearFrom(mpsi->buf, len);
    509
    510 SCIPdebugMessage("line %d: <%s>\n", mpsi->lineno, mpsi->buf);
    511
    512 assert(strlen(mpsi->buf) >= 80);
    513
    514 /* Look for new section */
    515 if( *mpsi->buf != BLANK )
    516 {
    517 mpsi->f0 = SCIPstrtok(&mpsi->buf[0], " ", &nexttok);
    518
    519 assert(mpsi->f0 != 0);
    520
    521 mpsi->f1 = SCIPstrtok(NULL, " ", &nexttok);
    522
    523 return TRUE;
    524 }
    525
    526 /* If we decide to use the new format we never revert this decision */
    527 if( !mpsi->isnewformat )
    528 {
    529 /* Test for fixed format comments */
    530 if( (mpsi->buf[14] == '$') && (mpsi->buf[13] == ' ') )
    531 clearFrom(mpsi->buf, 14);
    532 else if( (mpsi->buf[39] == '$') && (mpsi->buf[38] == ' ') )
    533 clearFrom(mpsi->buf, 39);
    534
    535 /* Test for fixed format */
    536 space = mpsi->buf[12] | mpsi->buf[13]
    537 | mpsi->buf[22] | mpsi->buf[23]
    538 | mpsi->buf[36] | mpsi->buf[37] | mpsi->buf[38]
    539 | mpsi->buf[47] | mpsi->buf[48]
    540 | mpsi->buf[61] | mpsi->buf[62] | mpsi->buf[63];
    541
    542 if( space == BLANK )
    543 {
    544 /* Now we have space at the right positions.
    545 * But are there also the non space where they
    546 * should be ?
    547 */
    549
    550 number = isdigit((unsigned char)mpsi->buf[24]) || isdigit((unsigned char)mpsi->buf[25])
    551 || isdigit((unsigned char)mpsi->buf[26]) || isdigit((unsigned char)mpsi->buf[27])
    552 || isdigit((unsigned char)mpsi->buf[28]) || isdigit((unsigned char)mpsi->buf[29])
    553 || isdigit((unsigned char)mpsi->buf[30]) || isdigit((unsigned char)mpsi->buf[31])
    554 || isdigit((unsigned char)mpsi->buf[32]) || isdigit((unsigned char)mpsi->buf[33])
    555 || isdigit((unsigned char)mpsi->buf[34]) || isdigit((unsigned char)mpsi->buf[35]);
    556
    557 /* len < 14 is to handle ROW lines with embedded spaces
    558 * in the names correctly
    559 */
    560 if( number || (len < 14 && mpsi->section == MPS_ROWS) )
    561 {
    562 /* We assume fixed format, so we patch possible embedded spaces. */
    563 patchField(mpsi->buf, 4, 12);
    564 patchField(mpsi->buf, 14, 22);
    565 patchField(mpsi->buf, 39, 47);
    566 }
    567 else
    568 {
    569 if( mpsi->section == MPS_COLUMNS || mpsi->section == MPS_RHS
    570 || mpsi->section == MPS_RANGES || mpsi->section == MPS_BOUNDS )
    571 mpsi->isnewformat = TRUE;
    572 }
    573 }
    574 else
    575 {
    576 mpsi->isnewformat = TRUE;
    577 }
    578 }
    579 s = &mpsi->buf[1];
    580
    581 /* At this point it is not clear if we have a indicator field.
    582 * If there is none (e.g. empty) f1 will be the first name field.
    583 * If there is one, f2 will be the first name field.
    584 *
    585 * Initially comment marks '$' are only allowed in the beginning
    586 * of the 2nd and 3rd name field. We test all fields but the first.
    587 * This makes no difference, since if the $ is at the start of a value
    588 * field, the line will be erroneous anyway.
    589 */
    590 do
    591 {
    592 if( NULL == (mpsi->f1 = SCIPstrtok(s, " ", &nexttok)) )
    593 break;
    594
    595 if( (NULL == (mpsi->f2 = SCIPstrtok(NULL, " ", &nexttok))) || (*mpsi->f2 == '$') )
    596 {
    597 mpsi->f2 = 0;
    598 break;
    599 }
    600 if( !strcmp(mpsi->f2, "'MARKER'") )
    601 is_marker = TRUE;
    602
    603 if( (NULL == (mpsi->f3 = SCIPstrtok(NULL, " ", &nexttok))) || (*mpsi->f3 == '$') )
    604 {
    605 mpsi->f3 = 0;
    606 break;
    607 }
    608 if( is_marker )
    609 {
    610 if( !strcmp(mpsi->f3, "'INTORG'") )
    611 mpsi->isinteger = TRUE;
    612 else if( !strcmp(mpsi->f3, "'INTEND'") )
    613 mpsi->isinteger = FALSE;
    614 else
    615 break; /* unknown marker */
    616 }
    617 if( !strcmp(mpsi->f3, "'MARKER'") )
    618 is_marker = TRUE;
    619
    620 if( (NULL == (mpsi->f4 = SCIPstrtok(NULL, " ", &nexttok))) || (*mpsi->f4 == '$') )
    621 {
    622 mpsi->f4 = 0;
    623 break;
    624 }
    625 if( is_marker )
    626 {
    627 if( !strcmp(mpsi->f4, "'INTORG'") )
    628 mpsi->isinteger = TRUE;
    629 else if( !strcmp(mpsi->f4, "'INTEND'") )
    630 mpsi->isinteger = FALSE;
    631 else
    632 break; /* unknown marker */
    633 }
    634 if( (NULL == (mpsi->f5 = SCIPstrtok(NULL, " ", &nexttok))) || (*mpsi->f5 == '$') )
    635 mpsi->f5 = 0;
    636 }
    637 while( FALSE );
    638
    639 /* check for empty lines */
    640 is_empty = (mpsi->f0 == NULL && mpsi->f1 == NULL);
    641 }
    642 while( is_marker || is_empty );
    643
    644 return TRUE;
    645}
    646
    647/** Insert \p str as field 4 and shift all other fields up. */
    648static
    650 MPSINPUT* mpsi, /**< mps input structure */
    651 const char* str /**< str to insert */
    652 )
    653{
    654 assert(mpsi != NULL);
    655 assert(str != NULL);
    656
    657 mpsi->f5 = mpsi->f4;
    658 mpsi->f4 = str;
    659}
    660
    661/** Insert \p name as field 1 or 2 and shift all other fields up. */
    662static
    664 MPSINPUT* mpsi, /**< mps input structure */
    665 const char* name, /**< name to insert */
    666 SCIP_Bool second /**< insert as second field? */
    667 )
    668{
    669 assert(mpsi != NULL);
    670 assert(name != NULL);
    671
    672 mpsi->f5 = mpsi->f4;
    673 mpsi->f4 = mpsi->f3;
    674 mpsi->f3 = mpsi->f2;
    675
    676 if( second )
    677 mpsi->f2 = name;
    678 else
    679 {
    680 mpsi->f2 = mpsi->f1;
    681 mpsi->f1 = name;
    682 }
    683}
    684
    685/** Add variable name to storage */
    686static
    688 SCIP* scip, /**< SCIP data structure */
    689 const char*** varnames, /**< the variable name storage */
    690 int* varnamessize, /**< the size of the variable names storage */
    691 int* nvars, /**< the number of variables */
    692 const char* colname /**< the name of the variable */
    693 )
    694{
    695 assert(scip != NULL);
    696
    697 if( varnames != NULL )
    698 {
    699 SCIP_CALL( SCIPensureBlockMemoryArray(scip, varnames, varnamessize, (*nvars) + 1) );
    700 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*varnames)[(*nvars)], colname, strlen(colname) + 1) ); /*lint !e866*/
    701 (*nvars)++;
    702 }
    703
    704 return SCIP_OKAY;
    705}
    706
    707/** Add constraint name to storage */
    708static
    710 SCIP* scip, /**< SCIP data structure */
    711 const char*** consnames, /**< the constraint name storage */
    712 int* consnamessize, /**< the size of the constraint names storage */
    713 int* ncons, /**< the number of constraint */
    714 const char* rowname /**< the name of the constraint */
    715 )
    716{
    717 assert(scip != NULL);
    718
    719 if( consnames != NULL )
    720 {
    721 SCIP_CALL( SCIPensureBlockMemoryArray(scip, consnames, consnamessize, (*ncons) + 1) );
    722 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consnames)[(*ncons)], rowname, strlen(rowname) + 1) ); /*lint !e866*/
    723 (*ncons)++;
    724 }
    725
    726 return SCIP_OKAY;
    727}
    728
    729/** Process NAME section. */
    730static
    732 SCIP* scip, /**< SCIP data structure */
    733 MPSINPUT* mpsi /**< mps input structure */
    734 )
    735{
    736 assert(mpsi != NULL);
    737
    738 SCIPdebugMsg(scip, "read problem name\n");
    739
    740 /* This has to be the Line with the NAME section. */
    741 if( !mpsinputReadLine(mpsi) || mpsinputField0(mpsi) == NULL || strcmp(mpsinputField0(mpsi), "NAME") )
    742 {
    744 return SCIP_OKAY;
    745 }
    746
    747 /* Sometimes the name is omitted. */
    748 mpsinputSetProbname(mpsi, (mpsinputField1(mpsi) == 0) ? "_MPS_" : mpsinputField1(mpsi));
    749
    750 /* This hat to be a new section */
    751 /* coverity[tainted_data] */
    752 if( !mpsinputReadLine(mpsi) || (mpsinputField0(mpsi) == NULL) )
    753 {
    755 return SCIP_OKAY;
    756 }
    757
    758 if( !strncmp(mpsinputField0(mpsi), "ROWS", 4) )
    760 else if( !strncmp(mpsinputField0(mpsi), "USERCUTS", 8) )
    762 else if( !strncmp(mpsinputField0(mpsi), "LAZYCONS", 8) )
    764 else if( !strncmp(mpsinputField0(mpsi), "OBJSEN", 6) )
    766 else if( !strncmp(mpsinputField0(mpsi), "OBJNAME", 7) )
    768 else
    769 {
    771 return SCIP_OKAY;
    772 }
    773
    774 return SCIP_OKAY;
    775}
    776
    777/** Process OBJSEN section. This Section is a CPLEX extension. */
    778static
    780 SCIP* scip, /**< SCIP data structure */
    781 MPSINPUT* mpsi /**< mps input structure */
    782 )
    783{
    784 assert(mpsi != NULL);
    785
    786 SCIPdebugMsg(scip, "read objective sense\n");
    787
    788 /* Although this is not explicitly in the MPS extensions as provided by CPLEX, some other MIP solvers
    789 * (in particular gurobi), put 'MIN' or 'MAX' as the input field on the same line as the section declaration */
    790 if( mpsinputField1(mpsi) == NULL){
    791 /* Normal Cplex extension; info should be on the next line, in field 1 */
    792 /* This has to be the Line with MIN or MAX. */
    793 if( !mpsinputReadLine(mpsi) || (mpsinputField1(mpsi) == NULL) )
    794 {
    796 return SCIP_OKAY;
    797 }
    798 }
    799 /* Otherwise, the input should read e.g. "OBJSENSE MAX" so that MAX is also the first field */
    800
    801 if( !strncmp(mpsinputField1(mpsi), "MIN", 3) )
    803 else if( !strncmp(mpsinputField1(mpsi), "MAX", 3) )
    805 else
    806 {
    808 return SCIP_OKAY;
    809 }
    810
    811 /* Look for ROWS, USERCUTS, LAZYCONS, or OBJNAME Section */
    812 /* coverity[tainted_data] */
    813 if( !mpsinputReadLine(mpsi) || mpsinputField0(mpsi) == NULL )
    814 {
    816 return SCIP_OKAY;
    817 }
    818
    819 if( !strcmp(mpsinputField0(mpsi), "ROWS") )
    821 else if( !strcmp(mpsinputField0(mpsi), "USERCUTS") )
    823 else if( !strcmp(mpsinputField0(mpsi), "LAZYCONS") )
    825 else if( !strcmp(mpsinputField0(mpsi), "OBJNAME") )
    827 else
    828 {
    830 return SCIP_OKAY;
    831 }
    832
    833 return SCIP_OKAY;
    834}
    835
    836/** Process OBJNAME section. This Section is a CPLEX extension. */
    837static
    839 SCIP* scip, /**< SCIP data structure */
    840 MPSINPUT* mpsi /**< mps input structure */
    841 )
    842{
    843 assert(mpsi != NULL);
    844
    845 SCIPdebugMsg(scip, "read objective name\n");
    846
    847 /* This has to be the Line with the name. */
    848 if( !mpsinputReadLine(mpsi) || mpsinputField1(mpsi) == NULL )
    849 {
    851 return SCIP_OKAY;
    852 }
    853
    855
    856 /* Look for ROWS, USERCUTS, or LAZYCONS Section */
    857 /* coverity[tainted_data] */
    858 if( !mpsinputReadLine(mpsi) || mpsinputField0(mpsi) == NULL )
    859 {
    861 return SCIP_OKAY;
    862 }
    863 if( !strcmp(mpsinputField0(mpsi), "ROWS") )
    865 else if( !strcmp(mpsinputField0(mpsi), "USERCUTS") )
    867 else if( !strcmp(mpsinputField0(mpsi), "LAZYCONS") )
    869 else
    871
    872 return SCIP_OKAY;
    873}
    874
    875/** Process ROWS, USERCUTS, or LAZYCONS section. */
    876static
    878 MPSINPUT* mpsi, /**< mps input structure */
    879 SCIP* scip, /**< SCIP data structure */
    880 const char*** consnames, /**< storage for the constraint names, or NULL */
    881 int* consnamessize, /**< the size of the constraint names storage, or NULL */
    882 int* nconsnames /**< the number of stored constraint names, or NULL */
    883 )
    884{
    885 SCIPdebugMsg(scip, "read rows\n");
    886
    887 /* coverity[tainted_data] */
    888 while( mpsinputReadLine(mpsi) )
    889 {
    890 if( mpsinputField0(mpsi) != NULL )
    891 {
    892 if( !strcmp(mpsinputField0(mpsi), "ROWS") )
    894 else if( !strcmp(mpsinputField0(mpsi), "USERCUTS") )
    896 else if( !strcmp(mpsinputField0(mpsi), "LAZYCONS") )
    898 else if( !strcmp(mpsinputField0(mpsi), "COLUMNS") )
    900 else
    902
    903 return SCIP_OKAY;
    904 }
    905
    906 if( *mpsinputField1(mpsi) == 'N' )
    907 {
    908 if( *mpsinputObjname(mpsi) == '\0' )
    910 else if( strcmp(mpsinputObjname(mpsi), mpsinputField2(mpsi)) != 0 )
    911 /* if OBJNAME was given and N-row is named differently, then warn that the N-row is not used as objective (OBJNAME takes precedence) */
    912 mpsinputEntryIgnored(scip, mpsi, "row", mpsinputField2(mpsi), "objective function", "N", SCIP_VERBLEVEL_NORMAL);
    913 }
    914 else
    915 {
    916 SCIP_CONS* cons;
    917 SCIP_Bool initial;
    919 SCIP_Bool enforce;
    920 SCIP_Bool check;
    921 SCIP_Bool propagate;
    922 SCIP_Bool local;
    923 SCIP_Bool modifiable;
    924 SCIP_Bool dynamic;
    925 SCIP_Bool removable;
    926
    927 cons = SCIPfindCons(scip, mpsinputField2(mpsi));
    928 if( cons != NULL )
    929 break;
    930
    931 initial = mpsi->initialconss && (mpsinputSection(mpsi) == MPS_ROWS);
    932 separate = TRUE;
    933 enforce = (mpsinputSection(mpsi) != MPS_USERCUTS);
    934 check = (mpsinputSection(mpsi) != MPS_USERCUTS);
    935 propagate = TRUE;
    936 local = FALSE;
    937 modifiable = FALSE;
    938 dynamic = mpsi->dynamicconss;
    939 removable = mpsi->dynamicrows || (mpsinputSection(mpsi) == MPS_USERCUTS);
    940
    941 switch(*mpsinputField1(mpsi))
    942 {
    943 case 'G' :
    945 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE) );
    946 break;
    947 case 'E' :
    948 SCIP_CALL( SCIPcreateConsLinear(scip, &cons, mpsinputField2(mpsi), 0, NULL, NULL, 0.0, 0.0,
    949 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE) );
    950 break;
    951 case 'L' :
    953 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE) );
    954 break;
    955 default :
    957 return SCIP_OKAY;
    958 }
    959 SCIP_CALL( SCIPaddCons(scip, cons) );
    960 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
    961
    962 /* if the file is of type cor, then the constraint names must be stored */
    963 SCIP_CALL( addConsNameToStorage(scip, consnames, consnamessize, nconsnames, mpsinputField2(mpsi)) );
    964 }
    965 }
    967
    968 return SCIP_OKAY;
    969}
    970
    971/** Process ROWS, USERCUTS, or LAZYCONS section. (exact version) */
    972static
    974 MPSINPUT* mpsi, /**< mps input structure */
    975 SCIP* scip, /**< SCIP data structure */
    976 const char*** consnames, /**< storage for the constraint names, or NULL */
    977 int* consnamessize, /**< the size of the constraint names storage, or NULL */
    978 int* nconsnames /**< the number of stored constraint names, or NULL */
    979 )
    980{
    981 SCIPdebugMsg(scip, "read rows\n");
    982
    983 while( mpsinputReadLine(mpsi) )
    984 {
    985 if( mpsinputField0(mpsi) != NULL )
    986 {
    987 if( !strcmp(mpsinputField0(mpsi), "ROWS") )
    989 else if( !strcmp(mpsinputField0(mpsi), "USERCUTS") )
    991 else if( !strcmp(mpsinputField0(mpsi), "LAZYCONS") )
    993 else if( !strcmp(mpsinputField0(mpsi), "COLUMNS") )
    995 else
    997
    998 return SCIP_OKAY;
    999 }
    1000
    1001 if( *mpsinputField1(mpsi) == 'N' )
    1002 {
    1003 if( *mpsinputObjname(mpsi) == '\0' )
    1005 else
    1006 mpsinputEntryIgnored(scip, mpsi, "row", mpsinputField2(mpsi), "objective function", "N", SCIP_VERBLEVEL_NORMAL);
    1007 }
    1008 else
    1009 {
    1010 SCIP_RATIONAL* lhs;
    1011 SCIP_RATIONAL* rhs;
    1012 SCIP_CONS* cons;
    1013 SCIP_Bool initial;
    1015 SCIP_Bool enforce;
    1016 SCIP_Bool check;
    1017 SCIP_Bool propagate;
    1018 SCIP_Bool local;
    1019 SCIP_Bool modifiable;
    1020 SCIP_Bool dynamic;
    1021 SCIP_Bool removable;
    1022
    1023 cons = SCIPfindCons(scip, mpsinputField2(mpsi));
    1024 if( cons != NULL )
    1025 break;
    1026
    1027 initial = mpsi->initialconss && (mpsinputSection(mpsi) == MPS_ROWS);
    1028 separate = TRUE;
    1029 enforce = (mpsinputSection(mpsi) != MPS_USERCUTS);
    1030 check = (mpsinputSection(mpsi) != MPS_USERCUTS);
    1031 propagate = TRUE;
    1032 local = FALSE;
    1033 modifiable = FALSE;
    1034 dynamic = mpsi->dynamicconss;
    1035 removable = mpsi->dynamicrows || (mpsinputSection(mpsi) == MPS_USERCUTS);
    1036
    1039
    1040 switch(*mpsinputField1(mpsi))
    1041 {
    1042 case 'G' :
    1044 SCIPrationalSetReal(lhs, 0.0);
    1045 break;
    1046 case 'E' :
    1047 SCIPrationalSetReal(rhs, 0.0);
    1048 SCIPrationalSetReal(lhs, 0.0);
    1049 break;
    1050 case 'L' :
    1052 SCIPrationalSetReal(rhs, 0.0);
    1053 break;
    1054 default :
    1055 mpsinputSyntaxerror(mpsi);
    1056 return SCIP_OKAY;
    1057 }
    1058
    1059 SCIP_CALL( SCIPcreateConsExactLinear(scip, &cons, mpsinputField2(mpsi), 0, NULL, NULL, lhs, rhs,
    1060 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE) );
    1061
    1062 SCIP_CALL( SCIPaddCons(scip, cons) );
    1063 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
    1064
    1067
    1068 /* if the file is of type cor, then the constraint names must be stored */
    1069 SCIP_CALL( addConsNameToStorage(scip, consnames, consnamessize, nconsnames, mpsinputField2(mpsi)) );
    1070 }
    1071 }
    1072 mpsinputSyntaxerror(mpsi);
    1073
    1074 return SCIP_OKAY;
    1075}
    1076
    1077/** Process COLUMNS section. */
    1078static
    1080 MPSINPUT* mpsi, /**< mps input structure */
    1081 SCIP* scip, /**< SCIP data structure */
    1082 const char*** varnames, /**< storage for the variable names, or NULL */
    1083 int* varnamessize, /**< the size of the variable names storage, or NULL */
    1084 int* nvarnames /**< the number of stored variable names, or NULL */
    1085 )
    1086{
    1087 char colname[MPS_MAX_NAMELEN] = { '\0' };
    1088 SCIP_CONS* cons;
    1089 SCIP_VAR* var;
    1090 SCIP_Real val;
    1091 SCIP_Bool usevartable;
    1092
    1093 SCIPdebugMsg(scip, "read columns\n");
    1094
    1095 var = NULL;
    1096 SCIP_CALL( SCIPgetBoolParam(scip, "misc/usevartable", &usevartable) );
    1097
    1098 while( mpsinputReadLine(mpsi) )
    1099 {
    1100 if( mpsinputField0(mpsi) != 0 )
    1101 {
    1102 if( strcmp(mpsinputField0(mpsi), "RHS") )
    1103 break;
    1104
    1105 /* add the last variable to the problem */
    1106 if( var != NULL )
    1107 {
    1108 SCIP_CALL( SCIPaddVar(scip, var) );
    1109 SCIP_CALL( SCIPreleaseVar(scip, &var) );
    1110 }
    1111 assert(var == NULL);
    1112
    1114 return SCIP_OKAY;
    1115 }
    1116 if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL || mpsinputField3(mpsi) == NULL )
    1117 break;
    1118
    1119 /* new column? */
    1120 if( strcmp(colname, mpsinputField1(mpsi)) )
    1121 {
    1122 /* add the last variable to the problem */
    1123 if( var != NULL )
    1124 {
    1125 SCIP_CALL( SCIPaddVar(scip, var) );
    1126 SCIP_CALL( SCIPreleaseVar(scip, &var) );
    1127 }
    1128 assert(var == NULL);
    1129
    1130 (void)SCIPmemccpy(colname, mpsinputField1(mpsi), '\0', MPS_MAX_NAMELEN - 1);
    1131
    1132 /* check whether we have seen this variable before, this would not allowed */
    1133 if( usevartable && SCIPfindVar(scip, colname) != NULL )
    1134 {
    1135 SCIPerrorMessage("Coeffients of column <%s> don't appear consecutively (line: %d)\n",
    1136 colname, mpsi->lineno);
    1137
    1138 return SCIP_READERROR;
    1139 }
    1140
    1141 /* if the file type is a cor file, the the variable name must be stored */
    1142 SCIP_CALL( addVarNameToStorage(scip, varnames, varnamessize, nvarnames, colname) );
    1143
    1144 if( mpsinputIsInteger(mpsi) )
    1145 {
    1146 /* for integer variables, default bounds are 0 <= x < 1(not +infinity, like it is for continuous variables), and default cost is 0 */
    1147 SCIP_CALL( SCIPcreateVar(scip, &var, colname, 0.0, 1.0, 0.0, SCIP_VARTYPE_BINARY,
    1148 !mpsi->dynamiccols, mpsi->dynamiccols, NULL, NULL, NULL, NULL, NULL) );
    1149 }
    1150 else
    1151 {
    1152 /* for continuous variables, default bounds are 0 <= x, and default cost is 0 */
    1154 !mpsi->dynamiccols, mpsi->dynamiccols, NULL, NULL, NULL, NULL, NULL) );
    1155 }
    1156 }
    1157 assert(var != NULL);
    1158
    1159 val = atof(mpsinputField3(mpsi));
    1160
    1161 if( !strcmp(mpsinputField2(mpsi), mpsinputObjname(mpsi)) )
    1162 {
    1163 SCIP_CALL( SCIPchgVarObj(scip, var, val) );
    1164 }
    1165 else
    1166 {
    1167 cons = SCIPfindCons(scip, mpsinputField2(mpsi));
    1168 if( cons == NULL )
    1169 mpsinputEntryIgnored(scip, mpsi, "Column", mpsinputField1(mpsi), "row", mpsinputField2(mpsi), SCIP_VERBLEVEL_FULL);
    1170 else if( !SCIPisZero(scip, val) )
    1171 {
    1172 /* warn the user in case the coefficient is infinite */
    1173 if( SCIPisInfinity(scip, REALABS(val)) )
    1174 {
    1175 SCIPwarningMessage(scip, "Coefficient of variable <%s> in constraint <%s> contains infinite value <%e>,"
    1176 " consider adjusting SCIP infinity.\n", SCIPvarGetName(var), SCIPconsGetName(cons), val);
    1177 }
    1178 SCIP_CALL( SCIPaddCoefLinear(scip, cons, var, val) );
    1179 }
    1180 }
    1181 if( mpsinputField5(mpsi) != NULL )
    1182 {
    1183 assert(mpsinputField4(mpsi) != NULL);
    1184
    1185 val = atof(mpsinputField5(mpsi));
    1186
    1187 if( !strcmp(mpsinputField4(mpsi), mpsinputObjname(mpsi)) )
    1188 {
    1189 SCIP_CALL( SCIPchgVarObj(scip, var, val) );
    1190 }
    1191 else
    1192 {
    1193 cons = SCIPfindCons(scip, mpsinputField4(mpsi));
    1194 if( cons == NULL )
    1195 mpsinputEntryIgnored(scip, mpsi, "Column", mpsinputField1(mpsi), "row", mpsinputField4(mpsi), SCIP_VERBLEVEL_FULL);
    1196 else if( !SCIPisZero(scip, val) )
    1197 {
    1198 SCIP_CALL( SCIPaddCoefLinear(scip, cons, var, val) );
    1199 }
    1200 }
    1201 }
    1202 }
    1203 mpsinputSyntaxerror(mpsi);
    1204
    1205 return SCIP_OKAY;
    1206}
    1207
    1208/** Process COLUMNS section. (exact version) */
    1209static
    1211 MPSINPUT* mpsi, /**< mps input structure */
    1212 SCIP* scip, /**< SCIP data structure */
    1213 const char*** varnames, /**< storage for the variable names, or NULL */
    1214 int* varnamessize, /**< the size of the variable names storage, or NULL */
    1215 int* nvarnames /**< the number of stored variable names, or NULL */
    1216 )
    1217{
    1218 SCIP_RETCODE retcode = SCIP_OKAY;
    1219 char colname[MPS_MAX_NAMELEN] = { '\0' };
    1220 SCIP_CONS* cons;
    1221 SCIP_VAR* var;
    1222 SCIP_RATIONAL* val;
    1223 SCIP_Bool usevartable;
    1224
    1225 SCIPdebugMsg(scip, "read columns\n");
    1226
    1227 var = NULL;
    1228 SCIP_CALL( SCIPgetBoolParam(scip, "misc/usevartable", &usevartable) );
    1229
    1230 while( mpsinputReadLine(mpsi) )
    1231 {
    1232 if( mpsinputField0(mpsi) != 0 )
    1233 {
    1234 if( strcmp(mpsinputField0(mpsi), "RHS") )
    1235 break;
    1236
    1237 /* add the last variable to the problem */
    1238 if( var != NULL )
    1239 {
    1240 SCIP_CALL( SCIPaddVar(scip, var) );
    1241 SCIP_CALL( SCIPreleaseVar(scip, &var) );
    1242 }
    1243 assert(var == NULL);
    1244
    1246 return SCIP_OKAY;
    1247 }
    1248 if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL || mpsinputField3(mpsi) == NULL )
    1249 break;
    1250
    1251 /* new column? */
    1252 if( strcmp(colname, mpsinputField1(mpsi)) )
    1253 {
    1254 /* add the last variable to the problem */
    1255 if( var != NULL )
    1256 {
    1257 SCIP_CALL( SCIPaddVar(scip, var) );
    1258 SCIP_CALL( SCIPreleaseVar(scip, &var) );
    1259 }
    1260 assert(var == NULL);
    1261
    1262 (void)SCIPmemccpy(colname, mpsinputField1(mpsi), '\0', MPS_MAX_NAMELEN - 1);
    1263
    1264 /* check whether we have seen this variable before, this would not allowed */
    1265 if( usevartable && SCIPfindVar(scip, colname) != NULL )
    1266 {
    1267 SCIPerrorMessage("Coeffients of column <%s> don't appear consecutively (line: %d)\n",
    1268 colname, mpsi->lineno);
    1269
    1270 return SCIP_READERROR;
    1271 }
    1272
    1273 /* if the file type is a cor file, the the variable name must be stored */
    1274 SCIP_CALL( addVarNameToStorage(scip, varnames, varnamessize, nvarnames, colname) );
    1275
    1276 if( mpsinputIsInteger(mpsi) )
    1277 {
    1278 /* for integer variables, default bounds are 0 <= x < 1(not +infinity, like it is for continuous variables), and default cost is 0 */
    1279 SCIP_CALL( SCIPcreateVar(scip, &var, colname, 0.0, 1.0, 0.0, SCIP_VARTYPE_BINARY,
    1280 !mpsi->dynamiccols, mpsi->dynamiccols, NULL, NULL, NULL, NULL, NULL) );
    1281 }
    1282 else
    1283 {
    1284 /* for continuous variables, default bounds are 0 <= x, and default cost is 0 */
    1286 !mpsi->dynamiccols, mpsi->dynamiccols, NULL, NULL, NULL, NULL, NULL) );
    1287 }
    1288 /* create exact data if we are in exact solving mode */
    1289 if( SCIPisExact(scip) )
    1290 {
    1292 }
    1293 }
    1294 assert(var != NULL);
    1295
    1299
    1300 if( !strcmp(mpsinputField2(mpsi), mpsinputObjname(mpsi)) )
    1301 {
    1302 SCIP_CALL_TERMINATE( retcode, SCIPchgVarObjExact(scip, var, val), TERMINATE );
    1303 }
    1304 else
    1305 {
    1306 cons = SCIPfindCons(scip, mpsinputField2(mpsi));
    1307 if( cons == NULL )
    1308 mpsinputEntryIgnored(scip, mpsi, "Column", mpsinputField1(mpsi), "row", mpsinputField2(mpsi), SCIP_VERBLEVEL_FULL);
    1309 else if( !SCIPrationalIsZero(val) )
    1310 {
    1311 /* this method returns an error if the coefficient is infinite */
    1312 SCIP_CALL_TERMINATE( retcode, SCIPaddCoefExactLinear(scip, cons, var, val), TERMINATE );
    1313 }
    1314 }
    1315 if( mpsinputField5(mpsi) != NULL )
    1316 {
    1317 assert(mpsinputField4(mpsi) != NULL);
    1318
    1321
    1322 if( !strcmp(mpsinputField4(mpsi), mpsinputObjname(mpsi)) )
    1323 {
    1324 SCIP_CALL_TERMINATE( retcode, SCIPchgVarObjExact(scip, var, val), TERMINATE );
    1325 }
    1326 else
    1327 {
    1328 cons = SCIPfindCons(scip, mpsinputField4(mpsi));
    1329 if( cons == NULL )
    1330 {
    1331 mpsinputEntryIgnored(scip, mpsi, "Column", mpsinputField1(mpsi), "row", mpsinputField4(mpsi), SCIP_VERBLEVEL_FULL);
    1332 }
    1333 else if( !SCIPrationalIsZero(val) )
    1334 {
    1335 SCIP_CALL_TERMINATE( retcode, SCIPaddCoefExactLinear(scip, cons, var, val), TERMINATE );
    1336 }
    1337 }
    1338 }
    1339 TERMINATE:
    1340 /* free rational buffer */
    1342 if( retcode != SCIP_OKAY )
    1343 {
    1344 SCIP_CALL( SCIPreleaseVar(scip, &var) );
    1345 return retcode;
    1346 }
    1347 }
    1348 mpsinputSyntaxerror(mpsi);
    1349
    1350 return SCIP_OKAY;
    1351}
    1352
    1353/** Process RHS section. */
    1354static
    1356 MPSINPUT* mpsi, /**< mps input structure */
    1357 SCIP* scip /**< SCIP data structure */
    1358 )
    1359{
    1360 char rhsname[MPS_MAX_NAMELEN] = { '\0' };
    1361 SCIP_CONS* cons;
    1362 SCIP_Real lhs;
    1363 SCIP_Real rhs;
    1364 SCIP_Real val;
    1365
    1366 SCIPdebugMsg(scip, "read right hand sides\n");
    1367
    1368 while( mpsinputReadLine(mpsi) )
    1369 {
    1370 if( mpsinputField0(mpsi) != NULL )
    1371 {
    1372 if( !strcmp(mpsinputField0(mpsi), "RANGES") )
    1374 else if( !strcmp(mpsinputField0(mpsi), "BOUNDS") )
    1376 else if( !strcmp(mpsinputField0(mpsi), "SOS") )
    1378 else if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
    1380 else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
    1382 else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
    1384 else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
    1386 else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
    1388 else
    1389 break;
    1390 return SCIP_OKAY;
    1391 }
    1392 if( (mpsinputField2(mpsi) != NULL && mpsinputField3(mpsi) == NULL)
    1393 || (mpsinputField4(mpsi) != NULL && mpsinputField5(mpsi) == NULL) )
    1394 {
    1395 SCIPwarningMessage(scip, "reading rhs section, a field is missing, assuming that the vector name is the missing one(, row identfier <%s>)\n", mpsinputField2(mpsi));
    1396
    1397 mpsinputInsertName(mpsi, "_RHS_", FALSE);
    1398 }
    1399
    1400 if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL || mpsinputField3(mpsi) == NULL )
    1401 break;
    1402
    1403 if( *rhsname == '\0' )
    1404 (void)SCIPmemccpy(rhsname, mpsinputField1(mpsi), '\0', MPS_MAX_NAMELEN - 1);
    1405
    1406 if( !strcmp(rhsname, mpsinputField1(mpsi)) )
    1407 {
    1408 cons = SCIPfindCons(scip, mpsinputField2(mpsi));
    1409 if( cons == NULL )
    1410 {
    1411 /* the rhs of the objective row is treated as objective constant */
    1412 if( strcmp(mpsinputField2(mpsi), mpsinputObjname(mpsi)) == 0 )
    1413 {
    1414 val = atof(mpsinputField3(mpsi));
    1416 }
    1417 else
    1419 }
    1420 else
    1421 {
    1422 val = atof(mpsinputField3(mpsi));
    1423
    1424 /* find out the row sense */
    1425 lhs = SCIPgetLhsLinear(scip, cons);
    1426 rhs = SCIPgetRhsLinear(scip, cons);
    1427 if( SCIPisInfinity(scip, -lhs) )
    1428 {
    1429 /* lhs = -infinity -> lower or equal */
    1430 assert(SCIPisZero(scip, rhs));
    1431 SCIP_CALL( SCIPchgRhsLinear(scip, cons, val) );
    1432 }
    1433 else if( SCIPisInfinity(scip, rhs) )
    1434 {
    1435 /* rhs = +infinity -> greater or equal */
    1436 assert(SCIPisZero(scip, lhs));
    1437 SCIP_CALL( SCIPchgLhsLinear(scip, cons, val) );
    1438 }
    1439 else
    1440 {
    1441 /* lhs > -infinity, rhs < infinity -> equality */
    1442 assert(SCIPisZero(scip, lhs));
    1443 assert(SCIPisZero(scip, rhs));
    1444 SCIP_CALL( SCIPchgLhsLinear(scip, cons, val) );
    1445 SCIP_CALL( SCIPchgRhsLinear(scip, cons, val) );
    1446 }
    1447 SCIPdebugMsg(scip, "RHS <%s> lhs: %g rhs: %g val: <%22.12g>\n", mpsinputField2(mpsi), lhs, rhs, val);
    1448 }
    1449 if( mpsinputField5(mpsi) != NULL )
    1450 {
    1451 cons = SCIPfindCons(scip, mpsinputField4(mpsi));
    1452 if( cons == NULL )
    1453 {
    1454 /* the rhs of the objective row is treated as objective constant */
    1455 if( strcmp(mpsinputField4(mpsi), mpsinputObjname(mpsi)) == 0 )
    1456 {
    1457 val = atof(mpsinputField5(mpsi));
    1459 }
    1460 else
    1462 }
    1463 else
    1464 {
    1465 val = atof(mpsinputField5(mpsi));
    1466
    1467 /* find out the row sense */
    1468 lhs = SCIPgetLhsLinear(scip, cons);
    1469 rhs = SCIPgetRhsLinear(scip, cons);
    1470 if( SCIPisInfinity(scip, -lhs) )
    1471 {
    1472 /* lhs = -infinity -> lower or equal */
    1473 assert(SCIPisZero(scip, rhs));
    1474 SCIP_CALL( SCIPchgRhsLinear(scip, cons, val) );
    1475 }
    1476 else if( SCIPisInfinity(scip, rhs) )
    1477 {
    1478 /* rhs = +infinity -> greater or equal */
    1479 assert(SCIPisZero(scip, lhs));
    1480 SCIP_CALL( SCIPchgLhsLinear(scip, cons, val) );
    1481 }
    1482 else
    1483 {
    1484 /* lhs > -infinity, rhs < infinity -> equality */
    1485 assert(SCIPisZero(scip, lhs));
    1486 assert(SCIPisZero(scip, rhs));
    1487 SCIP_CALL( SCIPchgLhsLinear(scip, cons, val) );
    1488 SCIP_CALL( SCIPchgRhsLinear(scip, cons, val) );
    1489 }
    1490 SCIPdebugMsg(scip, "RHS <%s> lhs: %g rhs: %g val: <%22.12g>\n", mpsinputField4(mpsi), lhs, rhs, val);
    1491 }
    1492 }
    1493 }
    1494 }
    1495 mpsinputSyntaxerror(mpsi);
    1496
    1497 return SCIP_OKAY;
    1498}
    1499
    1500/** Process RHS section (exact version). */
    1501static
    1503 MPSINPUT* mpsi, /**< mps input structure */
    1504 SCIP* scip /**< SCIP data structure */
    1505 )
    1506{
    1507 char rhsname[MPS_MAX_NAMELEN] = { '\0' };
    1508 SCIP_CONS* cons;
    1509 SCIP_Real val;
    1510 SCIP_RATIONAL* lhs;
    1511 SCIP_RATIONAL* rhs;
    1512 SCIP_RATIONAL* valexact;
    1513
    1515
    1516 SCIPdebugMsg(scip, "read right hand sides\n");
    1517
    1518 while( mpsinputReadLine(mpsi) )
    1519 {
    1520 if( mpsinputField0(mpsi) != NULL )
    1521 {
    1522 if( !strcmp(mpsinputField0(mpsi), "RANGES") )
    1524 else if( !strcmp(mpsinputField0(mpsi), "BOUNDS") )
    1526 else if( !strcmp(mpsinputField0(mpsi), "SOS") )
    1528 else if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
    1530 else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
    1532 else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
    1534 else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
    1536 else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
    1538 else
    1539 break;
    1540
    1542
    1543 return SCIP_OKAY;
    1544 }
    1545 if( (mpsinputField2(mpsi) != NULL && mpsinputField3(mpsi) == NULL)
    1546 || (mpsinputField4(mpsi) != NULL && mpsinputField5(mpsi) == NULL) )
    1547 {
    1548 SCIPwarningMessage(scip, "reading rhs section, a field is missing, assuming that the vector name is the missing one(, row identfier <%s>)\n", mpsinputField2(mpsi));
    1549
    1550 mpsinputInsertName(mpsi, "_RHS_", FALSE);
    1551 }
    1552
    1553 if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL || mpsinputField3(mpsi) == NULL )
    1554 break;
    1555
    1556 if( *rhsname == '\0' )
    1557 (void)SCIPmemccpy(rhsname, mpsinputField1(mpsi), '\0', MPS_MAX_NAMELEN - 1);
    1558
    1559 if( !strcmp(rhsname, mpsinputField1(mpsi)) )
    1560 {
    1561 cons = SCIPfindCons(scip, mpsinputField2(mpsi));
    1562 if( cons == NULL )
    1563 {
    1564 /* the rhs of the objective row is treated as objective constant */
    1565 if( !strcmp(mpsinputField2(mpsi), mpsinputObjname(mpsi)) )
    1566 {
    1567 val = atof(mpsinputField3(mpsi));
    1569 }
    1570 else
    1572 }
    1573 else
    1574 {
    1575 SCIPrationalSetString(valexact, mpsinputField3(mpsi));
    1576 SCIPrationalCanonicalize(valexact);
    1577
    1578 /* find out the row sense */
    1579 lhs = SCIPgetLhsExactLinear(scip, cons);
    1580 rhs = SCIPgetRhsExactLinear(scip, cons);
    1581 if( SCIPrationalIsNegInfinity(lhs) )
    1582 {
    1583 /* lhs = -infinity -> lower or equal */
    1584 assert(SCIPrationalIsZero(rhs));
    1585 SCIP_CALL( SCIPchgRhsExactLinear(scip, cons, valexact) );
    1586 }
    1587 else if( SCIPrationalIsInfinity(rhs) )
    1588 {
    1589 /* rhs = +infinity -> greater or equal */
    1590 assert(SCIPrationalIsZero(lhs));
    1591 SCIP_CALL( SCIPchgLhsExactLinear(scip, cons, valexact) );
    1592 }
    1593 else
    1594 {
    1595 /* lhs > -infinity, rhs < infinity -> equality */
    1596 assert(SCIPrationalIsZero(lhs));
    1597 assert(SCIPrationalIsZero(rhs));
    1598 SCIP_CALL( SCIPchgLhsExactLinear(scip, cons, valexact) );
    1599 SCIP_CALL( SCIPchgRhsExactLinear(scip, cons, valexact) );
    1600 }
    1601 SCIPrationalDebugMessage("RHS <%s> lhs: %q rhs: %q val: <%q>\n", mpsinputField2(mpsi), lhs, rhs, valexact);
    1602 }
    1603 if( mpsinputField5(mpsi) != NULL )
    1604 {
    1605 cons = SCIPfindCons(scip, mpsinputField4(mpsi));
    1606 if( cons == NULL )
    1607 {
    1608 /* the rhs of the objective row is treated as objective constant */
    1609 if( !strcmp(mpsinputField2(mpsi), mpsinputObjname(mpsi)) )
    1610 {
    1611 val = atof(mpsinputField3(mpsi));
    1613 }
    1614 else
    1616 }
    1617 else
    1618 {
    1619 SCIPrationalSetString(valexact, mpsinputField5(mpsi));
    1620 SCIPrationalCanonicalize(valexact);
    1621
    1622 /* find out the row sense */
    1623 lhs = SCIPgetLhsExactLinear(scip, cons);
    1624 rhs = SCIPgetRhsExactLinear(scip, cons);
    1625 if( SCIPrationalIsNegInfinity(lhs) )
    1626 {
    1627 /* lhs = -infinity -> lower or equal */
    1628 assert(SCIPrationalIsZero(rhs));
    1629 SCIP_CALL( SCIPchgRhsExactLinear(scip, cons, valexact) );
    1630 }
    1631 else if( SCIPrationalIsInfinity(rhs) )
    1632 {
    1633 /* rhs = +infinity -> greater or equal */
    1634 assert(SCIPrationalIsZero(lhs));
    1635 SCIP_CALL( SCIPchgLhsExactLinear(scip, cons, valexact) );
    1636 }
    1637 else
    1638 {
    1639 /* lhs > -infinity, rhs < infinity -> equality */
    1640 assert(SCIPrationalIsZero(lhs));
    1641 assert(SCIPrationalIsZero(rhs));
    1642 SCIP_CALL( SCIPchgLhsExactLinear(scip, cons, valexact) );
    1643 SCIP_CALL( SCIPchgRhsExactLinear(scip, cons, valexact) );
    1644 }
    1645 SCIPrationalDebugMessage("RHS <%s> lhs: %q rhs: %q val: <%q>\n", mpsinputField4(mpsi), lhs, rhs, valexact);
    1646 }
    1647 }
    1648 }
    1649 }
    1650 mpsinputSyntaxerror(mpsi);
    1651
    1652 return SCIP_OKAY;
    1653}
    1654
    1655/** Process RANGES section */
    1656static
    1658 MPSINPUT* mpsi, /**< mps input structure */
    1659 SCIP* scip /**< SCIP data structure */
    1660 )
    1661{
    1662 char rngname[MPS_MAX_NAMELEN] = { '\0' };
    1663 SCIP_CONS* cons;
    1664 SCIP_Real lhs;
    1665 SCIP_Real rhs;
    1666 SCIP_Real val;
    1667
    1668 SCIPdebugMsg(scip, "read ranges\n");
    1669
    1670 while( mpsinputReadLine(mpsi) )
    1671 {
    1672 if( mpsinputField0(mpsi) != NULL )
    1673 {
    1674 if( !strcmp(mpsinputField0(mpsi), "BOUNDS") )
    1676 else if( !strcmp(mpsinputField0(mpsi), "SOS") )
    1678 else if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
    1680 else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
    1682 else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
    1684 else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
    1686 else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
    1688 else
    1689 break;
    1690 return SCIP_OKAY;
    1691 }
    1692 if( (mpsinputField2(mpsi) != NULL && mpsinputField3(mpsi) == NULL)
    1693 || (mpsinputField4(mpsi) != NULL && mpsinputField5(mpsi) == NULL) )
    1694 {
    1695 SCIPwarningMessage(scip, "reading ranged section, a field is missing, assuming that the vector name is the missing one(, row identfier <%s>)\n", mpsinputField2(mpsi));
    1696
    1697 mpsinputInsertName(mpsi, "_RNG_", FALSE);
    1698 }
    1699
    1700 if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL || mpsinputField3(mpsi) == NULL )
    1701 break;
    1702
    1703 if( *rngname == '\0' )
    1704 (void)SCIPmemccpy(rngname, mpsinputField1(mpsi), '\0', MPS_MAX_NAMELEN - 1);
    1705
    1706 /* The rules are:
    1707 * Row Sign LHS RHS
    1708 * ----------------------------------------
    1709 * G +/- rhs rhs + |range|
    1710 * L +/- rhs - |range| rhs
    1711 * E + rhs rhs + range
    1712 * E - rhs + range rhs
    1713 * ----------------------------------------
    1714 */
    1715 if( !strcmp(rngname, mpsinputField1(mpsi)) )
    1716 {
    1717 cons = SCIPfindCons(scip, mpsinputField2(mpsi));
    1718 if( cons == NULL )
    1719 mpsinputEntryIgnored(scip, mpsi, "Range", mpsinputField1(mpsi), "row", mpsinputField2(mpsi), SCIP_VERBLEVEL_NORMAL);
    1720 else
    1721 {
    1722 val = atof(mpsinputField3(mpsi));
    1723
    1724 /* find out the row sense */
    1725 lhs = SCIPgetLhsLinear(scip, cons);
    1726 rhs = SCIPgetRhsLinear(scip, cons);
    1727 if( SCIPisInfinity(scip, -lhs) )
    1728 {
    1729 /* lhs = -infinity -> lower or equal */
    1730 SCIP_CALL( SCIPchgLhsLinear(scip, cons, rhs - REALABS(val)) );
    1731 }
    1732 else if( SCIPisInfinity(scip, rhs) )
    1733 {
    1734 /* rhs = +infinity -> greater or equal */
    1735 SCIP_CALL( SCIPchgRhsLinear(scip, cons, lhs + REALABS(val)) );
    1736 }
    1737 else
    1738 {
    1739 /* lhs > -infinity, rhs < infinity -> equality */
    1740 assert(SCIPisEQ(scip, lhs, rhs));
    1741 if( val >= 0.0 )
    1742 {
    1743 SCIP_CALL( SCIPchgRhsLinear(scip, cons, rhs + val) );
    1744 }
    1745 else
    1746 {
    1747 SCIP_CALL( SCIPchgLhsLinear(scip, cons, lhs + val) );
    1748 }
    1749 }
    1750 }
    1751 if( mpsinputField5(mpsi) != NULL )
    1752 {
    1753 cons = SCIPfindCons(scip, mpsinputField4(mpsi));
    1754 if( cons == NULL )
    1755 mpsinputEntryIgnored(scip, mpsi, "Range", mpsinputField1(mpsi), "row", mpsinputField4(mpsi), SCIP_VERBLEVEL_NORMAL);
    1756 else
    1757 {
    1758 val = atof(mpsinputField5(mpsi));
    1759
    1760 /* find out the row sense */
    1761 lhs = SCIPgetLhsLinear(scip, cons);
    1762 rhs = SCIPgetRhsLinear(scip, cons);
    1763 if( SCIPisInfinity(scip, -lhs) )
    1764 {
    1765 /* lhs = -infinity -> lower or equal */
    1766 SCIP_CALL( SCIPchgLhsLinear(scip, cons, rhs - REALABS(val)) );
    1767 }
    1768 else if( SCIPisInfinity(scip, rhs) )
    1769 {
    1770 /* rhs = +infinity -> greater or equal */
    1771 SCIP_CALL( SCIPchgRhsLinear(scip, cons, lhs + REALABS(val)) );
    1772 }
    1773 else
    1774 {
    1775 /* lhs > -infinity, rhs < infinity -> equality */
    1776 assert(SCIPisEQ(scip, lhs, rhs));
    1777 if( val >= 0.0 )
    1778 {
    1779 SCIP_CALL( SCIPchgRhsLinear(scip, cons, rhs + val) );
    1780 }
    1781 else
    1782 {
    1783 SCIP_CALL( SCIPchgLhsLinear(scip, cons, lhs + val) );
    1784 }
    1785 }
    1786 }
    1787 }
    1788 }
    1789 }
    1790 mpsinputSyntaxerror(mpsi);
    1791
    1792 return SCIP_OKAY;
    1793}
    1794
    1795/** Process RANGES section (exact version) */
    1796static
    1798 MPSINPUT* mpsi, /**< mps input structure */
    1799 SCIP* scip /**< SCIP data structure */
    1800 )
    1801{
    1802 char rngname[MPS_MAX_NAMELEN] = { '\0' };
    1803 SCIP_CONS* cons;
    1804 SCIP_RATIONAL* lhs;
    1805 SCIP_RATIONAL* rhs;
    1806 SCIP_RATIONAL* val;
    1807
    1808 SCIPdebugMsg(scip, "read ranges\n");
    1809
    1811
    1812 while( mpsinputReadLine(mpsi) )
    1813 {
    1814 if( mpsinputField0(mpsi) != NULL )
    1815 {
    1816 if( !strcmp(mpsinputField0(mpsi), "BOUNDS") )
    1818 else if( !strcmp(mpsinputField0(mpsi), "SOS") )
    1820 else if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
    1822 else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
    1824 else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
    1826 else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
    1828 else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
    1830 else
    1831 break;
    1832
    1834
    1835 return SCIP_OKAY;
    1836 }
    1837 if( (mpsinputField2(mpsi) != NULL && mpsinputField3(mpsi) == NULL)
    1838 || (mpsinputField4(mpsi) != NULL && mpsinputField5(mpsi) == NULL) )
    1839 {
    1840 SCIPwarningMessage(scip, "reading ranged section, a field is missing, assuming that the vector name is the missing one(, row identfier <%s>)\n", mpsinputField2(mpsi));
    1841
    1842 mpsinputInsertName(mpsi, "_RNG_", FALSE);
    1843 }
    1844
    1845 if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL || mpsinputField3(mpsi) == NULL )
    1846 break;
    1847
    1848 if( *rngname == '\0' )
    1849 (void)SCIPmemccpy(rngname, mpsinputField1(mpsi), '\0', MPS_MAX_NAMELEN - 1);
    1850
    1851 /* The rules are:
    1852 * Row Sign LHS RHS
    1853 * ----------------------------------------
    1854 * G +/- rhs rhs + |range|
    1855 * L +/- rhs - |range| rhs
    1856 * E + rhs rhs + range
    1857 * E - rhs + range rhs
    1858 * ----------------------------------------
    1859 */
    1860 if( !strcmp(rngname, mpsinputField1(mpsi)) )
    1861 {
    1862 cons = SCIPfindCons(scip, mpsinputField2(mpsi));
    1863 if( cons == NULL )
    1864 mpsinputEntryIgnored(scip, mpsi, "Range", mpsinputField1(mpsi), "row", mpsinputField2(mpsi), SCIP_VERBLEVEL_NORMAL);
    1865 else
    1866 {
    1869
    1870 /* find out the row sense */
    1871 lhs = SCIPgetLhsExactLinear(scip, cons);
    1872 rhs = SCIPgetRhsExactLinear(scip, cons);
    1873 if( SCIPrationalIsNegInfinity(lhs) )
    1874 {
    1875 /* lhs = -infinity -> lower or equal */
    1876 SCIPrationalAbs(val, val);
    1877 SCIPrationalDiff(val, rhs, val);
    1878 SCIP_CALL( SCIPchgLhsExactLinear(scip, cons, val) );
    1879 }
    1880 else if( SCIPrationalIsInfinity(rhs) )
    1881 {
    1882 /* rhs = +infinity -> greater or equal */
    1883 SCIPrationalAbs(val, val);
    1884 SCIPrationalAdd(val, val, lhs);
    1885 SCIP_CALL( SCIPchgRhsExactLinear(scip, cons, val) );
    1886 }
    1887 else
    1888 {
    1889 /* lhs > -infinity, rhs < infinity -> equality */
    1890 assert(SCIPrationalIsEQ(lhs, rhs));
    1891 if( !SCIPrationalIsNegative(val) )
    1892 {
    1893 SCIPrationalAdd(val, val, rhs);
    1894 SCIP_CALL( SCIPchgRhsExactLinear(scip, cons, val) );
    1895 }
    1896 else
    1897 {
    1898 SCIPrationalAdd(val, val, lhs);
    1899 SCIP_CALL( SCIPchgLhsExactLinear(scip, cons, val) );
    1900 }
    1901 }
    1902 }
    1903 if( mpsinputField5(mpsi) != NULL )
    1904 {
    1905 cons = SCIPfindCons(scip, mpsinputField4(mpsi));
    1906 if( cons == NULL )
    1907 mpsinputEntryIgnored(scip, mpsi, "Range", mpsinputField1(mpsi), "row", mpsinputField4(mpsi), SCIP_VERBLEVEL_NORMAL);
    1908 else
    1909 {
    1912
    1913 /* find out the row sense */
    1914 lhs = SCIPgetLhsExactLinear(scip, cons);
    1915 rhs = SCIPgetRhsExactLinear(scip, cons);
    1916 if( SCIPrationalIsNegInfinity(lhs) )
    1917 {
    1918 /* lhs = -infinity -> lower or equal */
    1919 SCIPrationalAbs(val, val);
    1920 SCIPrationalDiff(val, rhs, val);
    1921 SCIP_CALL( SCIPchgLhsExactLinear(scip, cons, val) );
    1922 }
    1923 else if( SCIPrationalIsInfinity(rhs) )
    1924 {
    1925 /* rhs = +infinity -> greater or equal */
    1926 SCIPrationalAbs(val, val);
    1927 SCIPrationalAdd(val, lhs, val);
    1928 SCIP_CALL( SCIPchgRhsExactLinear(scip, cons, val) );
    1929 }
    1930 else
    1931 {
    1932 /* lhs > -infinity, rhs < infinity -> equality */
    1933 assert(SCIPrationalIsEQ(lhs, rhs));
    1934 if( !SCIPrationalIsNegative(val) )
    1935 {
    1936 SCIPrationalAdd(val, val, rhs);
    1937 SCIP_CALL( SCIPchgRhsExactLinear(scip, cons, val) );
    1938 }
    1939 else
    1940 {
    1941 SCIPrationalAdd(val, val, lhs);
    1942 SCIP_CALL( SCIPchgLhsExactLinear(scip, cons, val) );
    1943 }
    1944 }
    1945 }
    1946 }
    1947 }
    1948 }
    1949 mpsinputSyntaxerror(mpsi);
    1950
    1951 return SCIP_OKAY;
    1952}
    1953
    1954/** Process BOUNDS section. */
    1955static
    1957 MPSINPUT* mpsi, /**< mps input structure */
    1958 SCIP* scip /**< SCIP data structure */
    1959 )
    1960{
    1961 char bndname[MPS_MAX_NAMELEN] = { '\0' };
    1962 SCIP_VAR* var;
    1963 SCIP_RETCODE retcode;
    1964 SCIP_Real val;
    1965 SCIP_Bool shifted;
    1966
    1967 SCIP_VAR** semicont;
    1968 int nsemicont;
    1969 int semicontsize;
    1970
    1971 retcode = SCIP_OKAY;
    1972
    1973 semicont = NULL;
    1974 nsemicont = 0;
    1975 semicontsize = 0;
    1976
    1977 SCIPdebugMsg(scip, "read bounds\n");
    1978
    1979 while( mpsinputReadLine(mpsi) )
    1980 {
    1981 if( mpsinputField0(mpsi) != 0 )
    1982 {
    1983 if( !strcmp(mpsinputField0(mpsi), "SOS") )
    1985 else if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
    1987 else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
    1989 else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
    1991 else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
    1993 else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
    1995 else
    1996 break;
    1997 goto READBOUNDS_FINISH;
    1998 }
    1999
    2000 shifted = FALSE;
    2001
    2002 /* Is the value field used ? */
    2003 if( !strcmp(mpsinputField1(mpsi), "LO") /* lower bound given in field 4 */
    2004 || !strcmp(mpsinputField1(mpsi), "UP") /* upper bound given in field 4 */
    2005 || !strcmp(mpsinputField1(mpsi), "FX") /* fixed value given in field 4 */
    2006 || !strcmp(mpsinputField1(mpsi), "LI") /* CPLEX extension: lower bound of integer variable given in field 4 */
    2007 || !strcmp(mpsinputField1(mpsi), "UI") /* CPLEX extension: upper bound of integer variable given in field 4 */
    2008 || !strcmp(mpsinputField1(mpsi), "SC") /* CPLEX extension: semi-continuous variable, upper bound given in field 4 */
    2009 || !strcmp(mpsinputField1(mpsi), "SI") )/* CPLEX extension: semi-integer variable, upper bound given in field 4 */
    2010 {
    2011 if( mpsinputField3(mpsi) != NULL && mpsinputField4(mpsi) == NULL )
    2012 {
    2013 int l;
    2014
    2015 /* check what might be missing, if field 3 is a number the bound name might be missing */
    2016 for( l = (int) strlen(mpsinputField3(mpsi)) - 1; l >= 0; --l )
    2017 {
    2018 if( mpsinputField3(mpsi)[l] != '.' && !isdigit((unsigned char)mpsinputField3(mpsi)[l]) )
    2019 break;
    2020 }
    2021
    2022 /* the bound name?! is missing */
    2023 if( l < 0 )
    2024 {
    2025 SCIPwarningMessage(scip, "in bound section a name for value <%s> might be missing\n", mpsinputField3(mpsi));
    2026
    2027 mpsinputInsertName(mpsi, "_BND_", TRUE);
    2028 shifted = TRUE;
    2029 }
    2030 /* the bound is be missing */
    2031 else
    2032 {
    2033 SCIPwarningMessage(scip, "in bound section a value for column <%s> is missing, assuming 0.0\n", mpsinputField3(mpsi));
    2034
    2035 mpsinputInsertField4(mpsi, "0.0");
    2036 shifted = TRUE;
    2037 }
    2038 }
    2039 }
    2040 else if( !strcmp(mpsinputField1(mpsi), "FR") /* free variable */
    2041 || !strcmp(mpsinputField1(mpsi), "MI") /* lower bound is minus infinity */
    2042 || !strcmp(mpsinputField1(mpsi), "PL") /* upper bound is plus infinity */
    2043 || !strcmp(mpsinputField1(mpsi), "BV") ) /* CPLEX extension: binary variable */
    2044 {
    2045 if( mpsinputField2(mpsi) != NULL && mpsinputField3(mpsi) == NULL )
    2046 {
    2047 SCIPwarningMessage(scip, "in bound section a name for a column is missing\n");
    2048
    2049 mpsinputInsertName(mpsi, "_BND_", TRUE);
    2050 shifted = TRUE;
    2051 }
    2052 }
    2053 else
    2054 {
    2055 mpsinputSyntaxerror(mpsi);
    2056 return SCIP_OKAY;
    2057 }
    2058
    2059 if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL || mpsinputField3(mpsi) == NULL )
    2060 break;
    2061
    2062 if( *bndname == '\0' )
    2063 (void)SCIPmemccpy(bndname, mpsinputField2(mpsi), '\0', MPS_MAX_NAMELEN - 1);
    2064
    2065 /* Only read the first Bound in section */
    2066 if( !strcmp(bndname, mpsinputField2(mpsi)) )
    2067 {
    2068 SCIP_VARTYPE oldvartype;
    2069 SCIP_Bool infeasible;
    2070
    2071 var = SCIPfindVar(scip, mpsinputField3(mpsi));
    2072 /* if variable did not appear in columns section before, then it may still come in later sections (QCMATRIX, QMATRIX, SOS, ...)
    2073 * thus add it as continuous variables, which has default bounds 0.0 <= x, and default cost 0.0 */
    2074 if( var == NULL )
    2075 {
    2076 SCIP_VAR* varcpy;
    2077
    2078 SCIP_CALL( SCIPcreateVar(scip, &var, mpsinputField3(mpsi), 0.0, SCIPinfinity(scip), 0.0,
    2079 SCIP_VARTYPE_CONTINUOUS, !mpsi->dynamiccols, mpsi->dynamiccols, NULL, NULL, NULL, NULL, NULL) );
    2080
    2081 SCIP_CALL( SCIPaddVar(scip, var) );
    2082 varcpy = var;
    2083 SCIP_CALL( SCIPreleaseVar(scip, &varcpy) );
    2084 /* mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField3(mpsi), "bound", bndname, SCIP_VERBLEVEL_NORMAL); */
    2085 }
    2086 assert(var != NULL);
    2087
    2088 if( mpsinputField4(mpsi) == NULL )
    2089 val = 0.0;
    2090 else
    2091 val = atof(mpsinputField4(mpsi));
    2092
    2093 /* remember variable type */
    2094 oldvartype = SCIPvarGetType(var);
    2095 assert(!SCIPvarIsImpliedIntegral(var));
    2096
    2097 /* convert into an integer variable with default bounds 0 <= x <= infinity if binary variable is not declared
    2098 * binary and not equipped with binary bounds, note that the default integer type is binary
    2099 */
    2100 if( oldvartype == SCIP_VARTYPE_BINARY
    2101 && ( mpsinputField1(mpsi)[0] != 'B' || mpsinputField1(mpsi)[1] != 'V' )
    2102 && ( mpsinputField1(mpsi)[0] != 'U' || SCIPisFeasGT(scip, val, 1.0) )
    2103 && ( mpsinputField1(mpsi)[0] != 'F' || mpsinputField1(mpsi)[1] != 'X'
    2104 || SCIPisFeasNegative(scip, val) || SCIPisFeasGT(scip, val, 1.0) ) )
    2105 {
    2106 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
    2107 assert(!infeasible);
    2108
    2109 oldvartype = SCIP_VARTYPE_INTEGER;
    2111 }
    2112
    2113 /* switch variable type to continuous before applying the bound, this is necessary for stupid non-integral
    2114 * bounds on general variables, which even might lead to infeasibility
    2115 */
    2116 if( oldvartype != SCIP_VARTYPE_CONTINUOUS )
    2117 {
    2118 /* relaxing variable type */
    2120 }
    2122
    2123 switch( mpsinputField1(mpsi)[0] )
    2124 {
    2125 case 'L':
    2127 {
    2128 SCIPwarningMessage(scip, "Relaxing already defined lower bound %g of variable <%s> to %g not allowed.\n", SCIPvarGetLbGlobal(var), SCIPvarGetName(var), val);
    2129 }
    2130
    2131 SCIP_CALL( SCIPchgVarLb(scip, var, val) );
    2132
    2133 if( mpsinputField1(mpsi)[1] == 'I' ) /* CPLEX extension (Integer Bound) */
    2134 {
    2135 if( !SCIPisFeasIntegral(scip, val) )
    2136 {
    2137 SCIPwarningMessage(scip, "variable <%s> declared as integral has a non-integral lower bound (%.14g) -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), val);
    2138 }
    2139 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
    2140 /* don't assert feasibility here because the presolver will and should detect a infeasibility */
    2141 }
    2142 else if( oldvartype < SCIP_VARTYPE_CONTINUOUS )
    2143 {
    2144 if( !SCIPisFeasIntegral(scip, val) )
    2145 {
    2146 SCIPwarningMessage(scip, "variable <%s> declared as integral has a non-integral lower bound (%.14g) -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), val);
    2147 }
    2148 }
    2149
    2150 break;
    2151 case 'U':
    2152 if( SCIPisGT(scip, val, SCIPvarGetUbGlobal(var)) )
    2153 {
    2154 SCIPwarningMessage(scip, "Relaxing already defined upper bound %g of variable <%s> to %g not allowed.\n", SCIPvarGetUbGlobal(var), SCIPvarGetName(var), val);
    2155 }
    2156
    2157 SCIP_CALL( SCIPchgVarUb(scip, var, val) );
    2158 if( mpsinputField1(mpsi)[1] == 'I' ) /* CPLEX extension (Integer Bound) */
    2159 {
    2160 if( !SCIPisFeasIntegral(scip, val) )
    2161 {
    2162 SCIPwarningMessage(scip, "variable <%s> declared as integral has a non-integral upper bound (%.14g) -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), val);
    2163 }
    2164
    2165 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
    2166 /* don't assert feasibility here because the presolver will and should detect an infeasibility */
    2167 }
    2168 else if( oldvartype < SCIP_VARTYPE_CONTINUOUS )
    2169 {
    2170 if( !SCIPisFeasIntegral(scip, val) )
    2171 {
    2172 SCIPwarningMessage(scip, "variable <%s> declared as integral has a non-integral upper bound (%.14g) -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), val);
    2173 }
    2174 }
    2175 break;
    2176 case 'S':
    2177 assert(mpsinputField1(mpsi)[1] == 'C' || mpsinputField1(mpsi)[1] == 'I'); /* semi-continuous or semi-integer (CPLEX extension) */
    2178 /* remember that variable is semi-continuous/-integer */
    2179 if( semicontsize <= nsemicont )
    2180 {
    2181 semicontsize = SCIPcalcMemGrowSize(scip, nsemicont+1);
    2182 if( semicont == NULL )
    2183 {
    2184 SCIP_CALL( SCIPallocBufferArray(scip, &semicont, semicontsize) );
    2185 }
    2186 else
    2187 {
    2188 SCIP_CALL( SCIPreallocBufferArray(scip, &semicont, semicontsize) );
    2189 }
    2190 }
    2191 assert(semicont != NULL);
    2192 semicont[nsemicont] = var;
    2193 ++nsemicont;
    2194
    2195 if( mpsinputField1(mpsi)[1] == 'I' ) /* variable is semi-integer, hence change its type to integer (the "semi" part will be handled below) */
    2196 {
    2197 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
    2198 /* don't assert feasibility here because the presolver will and should detect an infeasibility */
    2199 }
    2200
    2201 /* if both bounds are infinite anyway, we do not need to print a warning or change the bound */
    2203 {
    2204 if( SCIPisGT(scip, val, SCIPvarGetUbGlobal(var)) )
    2205 {
    2206 SCIPwarningMessage(scip, "Relaxing already defined upper bound %g of variable <%s> to %g not allowed.\n", SCIPvarGetUbGlobal(var), SCIPvarGetName(var), val);
    2207 }
    2208
    2209 SCIP_CALL( SCIPchgVarUb(scip, var, val) );
    2210 }
    2211 break;
    2212 case 'F':
    2213 if( mpsinputField1(mpsi)[1] == 'X' )
    2214 {
    2215 SCIP_CALL( SCIPchgVarLb(scip, var, val) );
    2216 SCIP_CALL( SCIPchgVarUb(scip, var, val) );
    2217 }
    2218 else
    2219 {
    2222 }
    2223 break;
    2224 case 'M':
    2226 break;
    2227 case 'P':
    2229 break;
    2230 case 'B':
    2231 if( oldvartype != SCIP_VARTYPE_BINARY )
    2232 {
    2233 SCIP_CALL( SCIPtightenVarLb(scip, var, 0.0, TRUE, &infeasible, NULL) );
    2234 SCIP_CALL( SCIPtightenVarUb(scip, var, 1.0, TRUE, &infeasible, NULL) );
    2235 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
    2236 /* presolving detects infeasibility */
    2237 }
    2238 break;
    2239 default:
    2240 mpsinputSyntaxerror(mpsi);
    2241 return SCIP_OKAY;
    2242 }
    2243
    2244 /* switch variable type back to old type if necessary */
    2245 if( oldvartype < SCIPvarGetType(var) )
    2246 {
    2247 SCIP_CALL( SCIPchgVarType(scip, var, oldvartype, &infeasible) );
    2248 }
    2249 }
    2250 else
    2251 {
    2252 /* check for syntax error */
    2253 assert(*bndname != '\0');
    2254 if( strcmp(bndname, mpsinputField3(mpsi)) == 0 && shifted )
    2255 {
    2256 mpsinputSyntaxerror(mpsi);
    2257 return SCIP_OKAY;
    2258 }
    2259
    2260 mpsinputEntryIgnored(scip, mpsi, "bound", mpsinputField2(mpsi), "variable", mpsinputField3(mpsi), SCIP_VERBLEVEL_NORMAL);
    2261 }
    2262 }
    2263 mpsinputSyntaxerror(mpsi);
    2264
    2265 READBOUNDS_FINISH:
    2266 if( nsemicont > 0 )
    2267 {
    2268 SCIP_CONS* cons;
    2269 SCIP_VAR* vars[2];
    2270 SCIP_BOUNDTYPE boundtypes[2];
    2271 SCIP_Real bounds[2];
    2272 char name[SCIP_MAXSTRLEN];
    2273 SCIP_Real oldlb;
    2274 int i;
    2275
    2276 assert(semicont != NULL);
    2277
    2278 /* add bound disjunction constraints for semi-continuous and semi-integer variables */
    2279 for( i = 0; i < nsemicont; ++i )
    2280 {
    2281 var = semicont[i];
    2283
    2284 oldlb = SCIPvarGetLbGlobal(var);
    2285 assert(oldlb >= 0.0);
    2286
    2287 /* if no bound was specified (which we assume if we see lower bound 0.0),
    2288 * then the default lower bound for a semi-continuous variable is 1.0 */
    2289 if( oldlb == 0.0 )
    2290 oldlb = 1.0;
    2291
    2292 /* change the lower bound to 0.0 */
    2293 SCIP_CALL( SCIPchgVarLb(scip, var, 0.0) );
    2294
    2295 /* add a bound disjunction constraint to say var <= 0.0 or var >= oldlb */
    2296 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "semicont_%s", SCIPvarGetName(var));
    2297
    2298 vars[0] = var;
    2299 vars[1] = var;
    2300 boundtypes[0] = SCIP_BOUNDTYPE_UPPER;
    2301 boundtypes[1] = SCIP_BOUNDTYPE_LOWER;
    2302 bounds[0] = 0.0;
    2303 bounds[1] = oldlb;
    2304
    2305 retcode = SCIPcreateConsBounddisjunction(scip, &cons, name, 2, vars, boundtypes, bounds,
    2306 !mpsi->dynamiccols, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, mpsi->dynamicconss, mpsi->dynamiccols, FALSE);
    2307
    2308 if( retcode != SCIP_OKAY )
    2309 break;
    2310
    2311 SCIP_CALL( SCIPaddCons(scip, cons) );
    2312
    2313 SCIPdebugMsg(scip, "add bound disjunction constraint for semi-continuity/-integrality of <%s>:\n\t", SCIPvarGetName(var));
    2315
    2316 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
    2317 }
    2318 }
    2319
    2320 SCIPfreeBufferArrayNull(scip, &semicont);
    2321
    2322 SCIP_CALL( retcode );
    2323
    2324 return SCIP_OKAY;
    2325}
    2326
    2327/** Process BOUNDS section. */
    2328static
    2330 MPSINPUT* mpsi, /**< mps input structure */
    2331 SCIP* scip /**< SCIP data structure */
    2332 )
    2333{
    2334 char bndname[MPS_MAX_NAMELEN] = { '\0' };
    2335 SCIP_VAR* var;
    2336 SCIP_RETCODE retcode;
    2337 SCIP_RATIONAL* val;
    2338 SCIP_Bool shifted;
    2339
    2340 SCIP_VAR** semicont;
    2341 int nsemicont;
    2342 int semicontsize;
    2343
    2344 retcode = SCIP_OKAY;
    2345
    2346 semicont = NULL;
    2347 nsemicont = 0;
    2348 semicontsize = 0;
    2349
    2351
    2352 SCIPdebugMsg(scip, "read bounds\n");
    2353
    2354 while( mpsinputReadLine(mpsi) )
    2355 {
    2356 if( mpsinputField0(mpsi) != 0 )
    2357 {
    2358 if( !strcmp(mpsinputField0(mpsi), "SOS") )
    2360 else if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
    2362 else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
    2364 else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
    2366 else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
    2368 else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
    2370 else
    2371 break;
    2372 goto READBOUNDS_FINISH;
    2373 }
    2374
    2375 shifted = FALSE;
    2376
    2377 /* Is the value field used ? */
    2378 if( !strcmp(mpsinputField1(mpsi), "LO") /* lower bound given in field 4 */
    2379 || !strcmp(mpsinputField1(mpsi), "UP") /* upper bound given in field 4 */
    2380 || !strcmp(mpsinputField1(mpsi), "FX") /* fixed value given in field 4 */
    2381 || !strcmp(mpsinputField1(mpsi), "LI") /* CPLEX extension: lower bound of integer variable given in field 4 */
    2382 || !strcmp(mpsinputField1(mpsi), "UI") /* CPLEX extension: upper bound of integer variable given in field 4 */
    2383 || !strcmp(mpsinputField1(mpsi), "SC") /* CPLEX extension: semi-continuous variable, upper bound given in field 4 */
    2384 || !strcmp(mpsinputField1(mpsi), "SI") )/* CPLEX extension: semi-integer variable, upper bound given in field 4 */
    2385 {
    2386 if( mpsinputField3(mpsi) != NULL && mpsinputField4(mpsi) == NULL )
    2387 {
    2388 int l;
    2389
    2390 /* check what might be missing, if field 3 is a number the bound name might be missing */
    2391 for( l = (int) strlen(mpsinputField3(mpsi)) - 1; l >= 0; --l )
    2392 {
    2393 if( mpsinputField3(mpsi)[l] != '.' && !isdigit((unsigned char)mpsinputField3(mpsi)[l]) )
    2394 break;
    2395 }
    2396
    2397 /* the bound name?! is missing */
    2398 if( l < 0 )
    2399 {
    2400 SCIPwarningMessage(scip, "in bound section a name for value <%s> might be missing\n", mpsinputField3(mpsi));
    2401
    2402 mpsinputInsertName(mpsi, "_BND_", TRUE);
    2403 shifted = TRUE;
    2404 }
    2405 /* the bound is be missing */
    2406 else
    2407 {
    2408 SCIPwarningMessage(scip, "in bound section a value for column <%s> is missing, assuming 0.0\n", mpsinputField3(mpsi));
    2409
    2410 mpsinputInsertField4(mpsi, "0.0");
    2411 shifted = TRUE;
    2412 }
    2413 }
    2414 }
    2415 else if( !strcmp(mpsinputField1(mpsi), "FR") /* free variable */
    2416 || !strcmp(mpsinputField1(mpsi), "MI") /* lower bound is minus infinity */
    2417 || !strcmp(mpsinputField1(mpsi), "PL") /* upper bound is plus infinity */
    2418 || !strcmp(mpsinputField1(mpsi), "BV") ) /* CPLEX extension: binary variable */
    2419 {
    2420 if( mpsinputField2(mpsi) != NULL && mpsinputField3(mpsi) == NULL )
    2421 {
    2422 SCIPwarningMessage(scip, "in bound section a name for a column is missing\n");
    2423
    2424 mpsinputInsertName(mpsi, "_BND_", TRUE);
    2425 shifted = TRUE;
    2426 }
    2427 }
    2428 else
    2429 {
    2430 mpsinputSyntaxerror(mpsi);
    2431 return SCIP_OKAY;
    2432 }
    2433
    2434 if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL || mpsinputField3(mpsi) == NULL )
    2435 break;
    2436
    2437 if( *bndname == '\0' )
    2438 (void)SCIPmemccpy(bndname, mpsinputField2(mpsi), '\0', MPS_MAX_NAMELEN - 1);
    2439
    2440 /* Only read the first Bound in section */
    2441 if( !strcmp(bndname, mpsinputField2(mpsi)) )
    2442 {
    2443 SCIP_VARTYPE oldvartype;
    2444 SCIP_Bool infeasible;
    2445
    2446 var = SCIPfindVar(scip, mpsinputField3(mpsi));
    2447 /* if variable did not appear in columns section before, then it may still come in later sections (QCMATRIX, QMATRIX, SOS, ...)
    2448 * thus add it as continuous variables, which has default bounds 0.0 <= x, and default cost 0.0 */
    2449 if( var == NULL )
    2450 {
    2451 SCIP_VAR* varcpy;
    2452
    2453 SCIP_CALL( SCIPcreateVar(scip, &var, mpsinputField3(mpsi), 0.0, SCIPinfinity(scip), 0.0,
    2454 SCIP_VARTYPE_CONTINUOUS, !mpsi->dynamiccols, mpsi->dynamiccols, NULL, NULL, NULL, NULL, NULL) );
    2455
    2457
    2458 SCIP_CALL( SCIPaddVar(scip, var) );
    2459 varcpy = var;
    2460 SCIP_CALL( SCIPreleaseVar(scip, &varcpy) );
    2461 /* mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField3(mpsi), "bound", bndname, SCIP_VERBLEVEL_NORMAL); */
    2462 }
    2463 assert(var != NULL);
    2464
    2465 if( mpsinputField4(mpsi) == NULL )
    2466 SCIPrationalSetReal(val, 0.0);
    2467 else
    2468 {
    2471 }
    2472
    2473 /* remember variable type */
    2474 oldvartype = SCIPvarGetType(var);
    2475 assert(!SCIPvarIsImpliedIntegral(var));
    2476
    2477 /* convert into an integer variable with default bounds 0 <= x <= infinity if binary variable is not declared
    2478 * binary and not equipped with binary bounds, note that the default integer type is binary
    2479 */
    2480 if( oldvartype == SCIP_VARTYPE_BINARY
    2481 && ( mpsinputField1(mpsi)[0] != 'B' || mpsinputField1(mpsi)[1] != 'V' )
    2482 && ( mpsinputField1(mpsi)[0] != 'U' || SCIPrationalIsGTReal(val, 1.0) )
    2483 && ( mpsinputField1(mpsi)[0] != 'F' || mpsinputField1(mpsi)[1] != 'X'
    2484 || SCIPrationalIsNegative(val) || SCIPrationalIsGTReal(val, 1.0) ) )
    2485 {
    2486 SCIP_RATIONAL* tmp;
    2487 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
    2488 assert(!infeasible);
    2489
    2492
    2493 oldvartype = SCIP_VARTYPE_INTEGER;
    2494
    2495 SCIP_CALL( SCIPchgVarUbExact(scip, var, tmp) );
    2497 }
    2498
    2499 /* switch variable type to continuous before applying the bound, this is necessary for stupid non-integral
    2500 * bounds on general variables, which even might lead to infeasibility
    2501 */
    2502 if( oldvartype != SCIP_VARTYPE_CONTINUOUS )
    2503 {
    2504 /* relaxing variable type */
    2506 }
    2508
    2509 switch( mpsinputField1(mpsi)[0] )
    2510 {
    2511 case 'L':
    2513 {
    2514 SCIPwarningMessage(scip, "Relaxing already defined lower bound (%.14g) of variable <%s> to (%.14g) not allowed.\n", SCIPvarGetLbGlobal(var), SCIPvarGetName(var), SCIPrationalGetReal(val));
    2515 }
    2516
    2517 SCIP_CALL( SCIPchgVarLbExact(scip, var, val) );
    2518
    2519 if( mpsinputField1(mpsi)[1] == 'I' ) /* CPLEX extension (Integer Bound) */
    2520 {
    2521 if( !SCIPrationalIsIntegral(val) )
    2522 {
    2523 SCIPwarningMessage(scip, "variable <%s> declared as integral has a non-integral lower bound (%.14g) -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), SCIPrationalGetReal(val));
    2524 }
    2525 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
    2526 /* don't assert feasibility here because the presolver will and should detect a infeasibility */
    2527 }
    2528 else if( oldvartype < SCIP_VARTYPE_CONTINUOUS )
    2529 {
    2530 if( !SCIPrationalIsIntegral(val) )
    2531 {
    2532 SCIPwarningMessage(scip, "variable <%s> declared as integral has a non-integral lower bound (%.14g) -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), SCIPrationalGetReal(val));
    2533 }
    2534 }
    2535
    2536 break;
    2537 case 'U':
    2539 {
    2540 SCIPwarningMessage(scip, "Relaxing already defined upper bound %g of variable <%s> to %g not allowed.\n", SCIPvarGetUbGlobal(var), SCIPvarGetName(var), SCIPrationalGetReal(val));
    2541 }
    2542
    2543 SCIP_CALL( SCIPchgVarUbExact(scip, var, val) );
    2544 if( mpsinputField1(mpsi)[1] == 'I' ) /* CPLEX extension (Integer Bound) */
    2545 {
    2546 if( !SCIPrationalIsIntegral(val) )
    2547 {
    2548 SCIPwarningMessage(scip, "variable <%s> declared as integral has a non-integral upper bound (%.14g) -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), SCIPrationalGetReal(val));
    2549 }
    2550
    2551 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
    2552 /* don't assert feasibility here because the presolver will and should detect an infeasibility */
    2553 }
    2554 else if( oldvartype < SCIP_VARTYPE_CONTINUOUS )
    2555 {
    2556 if( !SCIPrationalIsIntegral(val) )
    2557 {
    2558 SCIPwarningMessage(scip, "variable <%s> declared as integral has a non-integral upper bound (%.14g) -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), SCIPrationalGetReal(val));
    2559 }
    2560 }
    2561 break;
    2562 case 'S':
    2563 assert(mpsinputField1(mpsi)[1] == 'C' || mpsinputField1(mpsi)[1] == 'I'); /* semi-continuous or semi-integer (CPLEX extension) */
    2564 /* remember that variable is semi-continuous/-integer */
    2565 if( semicontsize <= nsemicont )
    2566 {
    2567 semicontsize = SCIPcalcMemGrowSize(scip, nsemicont+1);
    2568 if( semicont == NULL )
    2569 {
    2570 SCIP_CALL( SCIPallocBufferArray(scip, &semicont, semicontsize) );
    2571 }
    2572 else
    2573 {
    2574 SCIP_CALL( SCIPreallocBufferArray(scip, &semicont, semicontsize) );
    2575 }
    2576 }
    2577 assert(semicont != NULL);
    2578 semicont[nsemicont] = var;
    2579 ++nsemicont;
    2580
    2581 if( mpsinputField1(mpsi)[1] == 'I' ) /* variable is semi-integer, hence change its type to integer (the "semi" part will be handled below) */
    2582 {
    2583 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
    2584 /* don't assert feasibility here because the presolver will and should detect an infeasibility */
    2585 }
    2586
    2587 /* if both bounds are infinite anyway, we do not need to print a warning or change the bound */
    2589 {
    2591 {
    2592 SCIPwarningMessage(scip, "Relaxing already defined upper bound %g of variable <%s> to %g not allowed.\n", SCIPvarGetUbGlobal(var), SCIPvarGetName(var), SCIPrationalGetReal(val));
    2593 }
    2594
    2595 SCIP_CALL( SCIPchgVarUbExact(scip, var, val) );
    2596 }
    2597 break;
    2598 case 'F':
    2599 if( mpsinputField1(mpsi)[1] == 'X' )
    2600 {
    2601 SCIP_CALL( SCIPchgVarLbExact(scip, var, val) );
    2602 SCIP_CALL( SCIPchgVarUbExact(scip, var, val) );
    2603 }
    2604 else
    2605 {
    2607 SCIP_CALL( SCIPchgVarLbExact(scip, var, val) );
    2609 SCIP_CALL( SCIPchgVarUbExact(scip, var, val) );
    2610 }
    2611 break;
    2612 case 'M':
    2614 SCIP_CALL( SCIPchgVarLbExact(scip, var, val) );
    2615 break;
    2616 case 'P':
    2618 SCIP_CALL( SCIPchgVarUbExact(scip, var, val) );
    2619 break;
    2620 case 'B':
    2621 if( oldvartype != SCIP_VARTYPE_BINARY )
    2622 {
    2623 SCIPrationalSetReal(val, 0.0);
    2624 SCIP_CALL( SCIPtightenVarLbExact(scip, var, val, &infeasible, NULL) );
    2625 SCIPrationalSetReal(val, 1.0);
    2626 SCIP_CALL( SCIPtightenVarUbExact(scip, var, val, &infeasible, NULL) );
    2627 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
    2628 /* presolving detects infeasibility */
    2629 }
    2630 break;
    2631 default:
    2632 mpsinputSyntaxerror(mpsi);
    2633 return SCIP_OKAY;
    2634 }
    2635
    2636 /* switch variable type back to old type if necessary */
    2637 if( oldvartype < SCIPvarGetType(var) )
    2638 {
    2639 SCIP_CALL( SCIPchgVarType(scip, var, oldvartype, &infeasible) );
    2640 }
    2641 }
    2642 else
    2643 {
    2644 /* check for syntax error */
    2645 assert(*bndname != '\0');
    2646 if( strcmp(bndname, mpsinputField3(mpsi)) == 0 && shifted )
    2647 {
    2648 mpsinputSyntaxerror(mpsi);
    2649 return SCIP_OKAY;
    2650 }
    2651
    2652 mpsinputEntryIgnored(scip, mpsi, "bound", mpsinputField2(mpsi), "variable", mpsinputField3(mpsi), SCIP_VERBLEVEL_NORMAL);
    2653 }
    2654 }
    2655 mpsinputSyntaxerror(mpsi);
    2656
    2657 READBOUNDS_FINISH:
    2658 if( nsemicont > 0 )
    2659 {
    2660 SCIPerrorMessage("Exact solving mode cannot handle semicontinous variables at the moment \n");
    2661 SCIPABORT();
    2662 }
    2663
    2664 SCIPfreeBufferArrayNull(scip, &semicont);
    2666
    2667 SCIP_CALL( retcode );
    2668
    2669 return SCIP_OKAY;
    2670}
    2671
    2672
    2673/** Process SOS section.
    2674 *
    2675 * We read the SOS section, which is a nonstandard section introduced by CPLEX.
    2676 *
    2677 * @note Currently we do not support the standard way of specifying SOS constraints via markers.
    2678 */
    2679static
    2681 MPSINPUT* mpsi, /**< mps input structure */
    2682 SCIP* scip /**< SCIP data structure */
    2683 )
    2684{
    2685 SCIP_Bool initial;
    2687 SCIP_Bool enforce;
    2688 SCIP_Bool check;
    2689 SCIP_Bool propagate;
    2690 SCIP_Bool local;
    2691 SCIP_Bool dynamic;
    2692 SCIP_Bool removable;
    2693 char name[MPS_MAX_NAMELEN] = { '\0' };
    2694 SCIP_CONS* cons = NULL;
    2695 int consType = -1;
    2696 int cnt = 0;
    2697
    2698 SCIPdebugMsg(scip, "read SOS constraints\n");
    2699
    2700 /* standard settings for SOS constraints: */
    2701 initial = mpsi->initialconss;
    2702 separate = TRUE;
    2703 enforce = TRUE;
    2704 check = TRUE;
    2705 propagate = TRUE;
    2706 local = FALSE;
    2707 dynamic = mpsi->dynamicconss;
    2708 removable = mpsi->dynamicrows;
    2709
    2710 if( SCIPisExact(scip) )
    2711 {
    2712 SCIPerrorMessage("Exact solving mode cannot handle SOS constraints currently \n");
    2713 return SCIP_READERROR;
    2714 }
    2715
    2716 /* loop through section */
    2717 while( mpsinputReadLine(mpsi) )
    2718 {
    2719 int type = -1;
    2720
    2721 /* check if next section is found */
    2722 if( mpsinputField0(mpsi) != NULL )
    2723 {
    2724 if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
    2726 else if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
    2728 else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
    2730 else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
    2732 else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
    2734 break;
    2735 }
    2736 if( mpsinputField1(mpsi) == NULL )
    2737 {
    2738 SCIPerrorMessage("empty data in a non-comment line.\n");
    2739 mpsinputSyntaxerror(mpsi);
    2740 return SCIP_OKAY;
    2741 }
    2742
    2743 /* check for new SOS set */
    2744 if( strcmp(mpsinputField1(mpsi), "S1") == 0 )
    2745 type = 1;
    2746 if( strcmp(mpsinputField1(mpsi), "S2") == 0 )
    2747 type = 2;
    2748
    2749 /* add last constraint and create a new one */
    2750 if( type > 0 )
    2751 {
    2752 assert( type == 1 || type == 2 );
    2753 if( cons != NULL )
    2754 {
    2755 /* add last constraint */
    2756 SCIP_CALL( SCIPaddCons(scip, cons) );
    2757 SCIPdebugMsg(scip, "(line %d) added constraint <%s>: ", mpsi->lineno, SCIPconsGetName(cons));
    2759 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
    2760 }
    2761
    2762 /* check name */
    2763 if( mpsinputField2(mpsi) != NULL )
    2764 (void)SCIPmemccpy(name, mpsinputField2(mpsi), '\0', MPS_MAX_NAMELEN - 1);
    2765 else
    2766 {
    2767 /* create new name */
    2768 (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "SOS%d", ++cnt);
    2769 }
    2770
    2771 /* create new SOS constraint */
    2772 if( type == 1 )
    2773 {
    2774 /* we do not know the name of the constraint */
    2775 SCIP_CALL( SCIPcreateConsSOS1(scip, &cons, name, 0, NULL, NULL, initial, separate, enforce, check, propagate,
    2776 local, dynamic, removable, FALSE) );
    2777 }
    2778 else
    2779 {
    2780 assert( type == 2 );
    2781 SCIP_CALL( SCIPcreateConsSOS2(scip, &cons, name, 0, NULL, NULL, initial, separate, enforce, check, propagate,
    2782 local, dynamic, removable, FALSE) );
    2783 }
    2784 consType = type;
    2785 SCIPdebugMsg(scip, "created constraint <%s> of type %d.\n", name, type);
    2786 /* note: we ignore the priorities! */
    2787 }
    2788 else
    2789 {
    2790 /* otherwise we are in the section given variables */
    2791 SCIP_VAR* var;
    2792 SCIP_Real weight;
    2793 char* endptr;
    2794
    2795 if( consType != 1 && consType != 2 )
    2796 {
    2797 SCIPerrorMessage("missing SOS type specification.\n");
    2798 mpsinputSyntaxerror(mpsi);
    2799 return SCIP_OKAY;
    2800 }
    2801
    2802 /* get variable */
    2803 var = SCIPfindVar(scip, mpsinputField1(mpsi));
    2804 if( var == NULL )
    2805 {
    2806 /* ignore unknown variables - we would not know the type anyway */
    2807 mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField1(mpsi), "SOS", name, SCIP_VERBLEVEL_NORMAL);
    2808 }
    2809 else
    2810 {
    2811 /* get weight */
    2812 if( NULL == mpsinputField2(mpsi) )
    2813 {
    2814 SCIPerrorMessage("weight for variable <%s> not specified.\n", mpsinputField1(mpsi));
    2815 mpsinputSyntaxerror(mpsi);
    2816 return SCIP_OKAY;
    2817 }
    2818
    2819 weight = strtod(mpsinputField2(mpsi), &endptr);
    2820 if( endptr == mpsinputField2(mpsi) || *endptr != '\0' )
    2821 {
    2822 SCIPerrorMessage("weight for variable <%s> not specified.\n", mpsinputField1(mpsi));
    2823 mpsinputSyntaxerror(mpsi);
    2824 return SCIP_OKAY;
    2825 }
    2826
    2827 /* add variable and weight */
    2828 assert( consType == 1 || consType == 2 );
    2829 switch( consType )
    2830 {
    2831 case 1:
    2832 SCIP_CALL( SCIPaddVarSOS1(scip, cons, var, weight) );
    2833 break;
    2834 case 2:
    2835 SCIP_CALL( SCIPaddVarSOS2(scip, cons, var, weight) );
    2836 break;
    2837 /* coverity[dead_error_begin] */
    2838 default:
    2839 SCIPerrorMessage("unknown SOS type: <%d>\n", type); /* should not happen */
    2840 SCIPABORT();
    2841 return SCIP_INVALIDDATA; /*lint !e527*/
    2842 }
    2843 SCIPdebugMsg(scip, "added variable <%s> with weight %g.\n", SCIPvarGetName(var), weight);
    2844 }
    2845 /* check other fields */
    2846 if( (mpsinputField3(mpsi) != NULL && *mpsinputField3(mpsi) != '\0' ) ||
    2847 (mpsinputField4(mpsi) != NULL && *mpsinputField4(mpsi) != '\0' ) ||
    2848 (mpsinputField5(mpsi) != NULL && *mpsinputField5(mpsi) != '\0' ) )
    2849 {
    2850 SCIPwarningMessage(scip, "ignoring data in fields 3-5 <%s> <%s> <%s>.\n",
    2851 mpsinputField3(mpsi), mpsinputField4(mpsi), mpsinputField5(mpsi));
    2852 }
    2853 }
    2854 }
    2855
    2856 if( cons != NULL )
    2857 {
    2858 /* add last constraint */
    2859 SCIP_CALL( SCIPaddCons(scip, cons) );
    2860 SCIPdebugMsg(scip, "(line %d) added constraint <%s>: ", mpsi->lineno, SCIPconsGetName(cons));
    2862 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
    2863 }
    2864
    2865 return SCIP_OKAY;
    2866}
    2867
    2868
    2869/** Process QMATRIX or QUADOBJ section.
    2870 *
    2871 * - We read the QMATRIX or QUADOBJ section, which is a nonstandard section introduced by CPLEX.
    2872 * - We create a quadratic constraint for this matrix and add a variable to the objective to
    2873 * represent the value of the QMATRIX.
    2874 * - For a QMATRIX, we expect that both lower and upper diagonal elements are given and every
    2875 * coefficient has to be divided by 2.0.
    2876 * - For a QUADOBJ, we expect that only the upper diagonal elements are given and thus only
    2877 * coefficients on the diagonal have to be divided by 2.0.
    2878 */
    2879static
    2881 MPSINPUT* mpsi, /**< mps input structure */
    2882 SCIP_Bool isQuadObj, /**< whether we actually read a QUADOBJ section */
    2883 SCIP* scip /**< SCIP data structure */
    2884 )
    2885{
    2886 SCIP_VAR** quadvars1;
    2887 SCIP_VAR** quadvars2;
    2888 SCIP_Real* quadcoefs;
    2889 SCIP_RETCODE retcode;
    2890 int cnt = 0; /* number of qmatrix elements processed so far */
    2891 int size; /* size of quad* arrays */
    2892
    2893 SCIPdebugMsg(scip, "read %s objective\n", isQuadObj ? "QUADOBJ" : "QMATRIX");
    2894
    2895 if( SCIPisExact(scip) )
    2896 {
    2897 SCIPerrorMessage("Exact solving mode cannot handle QMatrix constraints currently \n");
    2898 return SCIP_READERROR;
    2899 }
    2900
    2901 retcode = SCIP_OKAY;
    2902
    2903 size = 1;
    2904 SCIP_CALL( SCIPallocBufferArray(scip, &quadvars1, size) );
    2905 SCIP_CALL( SCIPallocBufferArray(scip, &quadvars2, size) );
    2906 SCIP_CALL( SCIPallocBufferArray(scip, &quadcoefs, size) );
    2907
    2908 /* loop through section */
    2909 /* coverity[tainted_data] */
    2910 while( mpsinputReadLine(mpsi) )
    2911 {
    2912 /* otherwise we are in the section given variables */
    2913 SCIP_VAR* var1;
    2914 SCIP_VAR* var2;
    2915 SCIP_Real coef;
    2916
    2917 /* check if next section is found */
    2918 if( mpsinputField0(mpsi) != NULL )
    2919 {
    2920 if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
    2922 else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
    2924 else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
    2926 break;
    2927 }
    2928 if( mpsinputField1(mpsi) == NULL && mpsinputField2(mpsi) == NULL )
    2929 {
    2930 SCIPerrorMessage("empty data in a non-comment line.\n");
    2931 mpsinputSyntaxerror(mpsi);
    2932 SCIPfreeBufferArray(scip, &quadvars1);
    2933 SCIPfreeBufferArray(scip, &quadvars2);
    2934 SCIPfreeBufferArray(scip, &quadcoefs);
    2935 return SCIP_OKAY;
    2936 }
    2937
    2938 /* get first variable */
    2939 var1 = SCIPfindVar(scip, mpsinputField1(mpsi));
    2940 if( var1 == NULL )
    2941 {
    2942 /* ignore unknown variables - we would not know the type anyway */
    2943 mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField1(mpsi), "QMatrix", "QMATRIX", SCIP_VERBLEVEL_NORMAL);
    2944 }
    2945 else
    2946 {
    2947 int k;
    2948 for( k = 1; k <= 2; ++k )
    2949 {
    2950 /* get second variable */
    2951 var2 = SCIPfindVar(scip, k == 1 ? mpsinputField2(mpsi) : mpsinputField4(mpsi));
    2952 if( var2 == NULL )
    2953 {
    2954 /* ignore unknown variables - we would not know the type anyway */
    2955 mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField2(mpsi), "QMatrix", "QMATRIX", SCIP_VERBLEVEL_NORMAL);
    2956 }
    2957 else
    2958 {
    2959 const char* field;
    2960 char* endptr;
    2961
    2962 /* get coefficient */
    2963 field = (k == 1 ? mpsinputField3(mpsi) : mpsinputField5(mpsi));
    2964 if( NULL == field )
    2965 {
    2966 SCIPerrorMessage("coefficient of term <%s>*<%s> not specified.\n", SCIPvarGetName(var1), SCIPvarGetName(var2));
    2967 mpsinputSyntaxerror(mpsi);
    2968 SCIPfreeBufferArray(scip, &quadvars1);
    2969 SCIPfreeBufferArray(scip, &quadvars2);
    2970 SCIPfreeBufferArray(scip, &quadcoefs);
    2971 return SCIP_OKAY;
    2972 }
    2973
    2974 coef = strtod(field, &endptr);
    2975 if( endptr == field || *endptr != '\0' )
    2976 {
    2977 SCIPerrorMessage("coefficient of term <%s>*<%s> not specified.\n", SCIPvarGetName(var1), SCIPvarGetName(var2));
    2978 mpsinputSyntaxerror(mpsi);
    2979 SCIPfreeBufferArray(scip, &quadvars1);
    2980 SCIPfreeBufferArray(scip, &quadvars2);
    2981 SCIPfreeBufferArray(scip, &quadcoefs);
    2982 return SCIP_OKAY;
    2983 }
    2984
    2985 /* store variables and coefficient */
    2986 if( cnt >= size )
    2987 {
    2988 int newsize = SCIPcalcMemGrowSize(scip, size+1);
    2989 assert(newsize > size);
    2990 SCIP_CALL( SCIPreallocBufferArray(scip, &quadvars1, newsize) );
    2991 SCIP_CALL( SCIPreallocBufferArray(scip, &quadvars2, newsize) );
    2992 SCIP_CALL( SCIPreallocBufferArray(scip, &quadcoefs, newsize) );
    2993 size = newsize;
    2994 }
    2995 assert(cnt < size);
    2996 quadvars1[cnt] = var1;
    2997 quadvars2[cnt] = var2;
    2998 quadcoefs[cnt] = coef;
    2999
    3000 /* diagonal elements have to be divided by 2.0
    3001 * in a QMATRIX section also off-diagonal have to be divided by 2.0, since both lower and upper diagonal elements are given
    3002 */
    3003 if( var1 == var2 || !isQuadObj )
    3004 quadcoefs[cnt] /= 2.0;
    3005 ++cnt;
    3006
    3007 SCIPdebugMsg(scip, "stored term %g*<%s>*<%s>.\n", coef, SCIPvarGetName(var1), SCIPvarGetName(var2));
    3008 }
    3009
    3010 if( mpsinputField4(mpsi) == NULL || *mpsinputField4(mpsi) == '\0' )
    3011 break;
    3012
    3013 if( mpsinputField5(mpsi) == NULL || *mpsinputField5(mpsi) == '\0' )
    3014 {
    3015 /* ignore unknown variables - we would not know the type anyway */
    3016 mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField4(mpsi), "QMatrix", "QMATRIX", SCIP_VERBLEVEL_NORMAL);
    3017 break;
    3018 }
    3019 }
    3020 }
    3021 }
    3022
    3023 /* add constraint */
    3024 if( cnt )
    3025 {
    3026 SCIP_Bool initial, separate, enforce, check, propagate;
    3027 SCIP_Bool local, modifiable, dynamic, removable;
    3028 SCIP_CONS* cons = NULL;
    3029 SCIP_VAR* qmatrixvar = NULL;
    3030 SCIP_Real lhs, rhs;
    3031 SCIP_Real minusone = -1.0;
    3032
    3033 /* determine settings; note that reading/{initialconss,dynamicconss,dynamicrows,dynamiccols} apply only to model
    3034 * constraints and variables, not to an auxiliary objective constraint (otherwise it can happen that an auxiliary
    3035 * objective variable is loose with infinite best bound, triggering the problem that an LP that is unbounded
    3036 * because of loose variables with infinite best bound cannot be solved)
    3037 */
    3038 initial = TRUE;
    3039 separate = TRUE;
    3040 enforce = TRUE;
    3041 check = TRUE;
    3042 propagate = TRUE;
    3043 local = FALSE;
    3044 modifiable = FALSE;
    3045 dynamic = FALSE;
    3046 removable = FALSE;
    3047
    3048 SCIP_CALL( SCIPcreateVar(scip, &qmatrixvar, "qmatrixvar", -SCIPinfinity(scip), SCIPinfinity(scip), 1.0,
    3050 SCIP_CALL( SCIPaddVar(scip, qmatrixvar) );
    3051
    3053 {
    3054 lhs = -SCIPinfinity(scip);
    3055 rhs = 0.0;
    3056 }
    3057 else
    3058 {
    3059 lhs = 0.0;
    3060 rhs = SCIPinfinity(scip);
    3061 }
    3062
    3063 retcode = SCIPcreateConsQuadraticNonlinear(scip, &cons, "qmatrix", 1, &qmatrixvar, &minusone, cnt, quadvars1, quadvars2, quadcoefs, lhs, rhs,
    3064 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable);
    3065
    3066 if( retcode == SCIP_OKAY )
    3067 {
    3068 SCIP_CALL( SCIPaddCons(scip, cons) );
    3069 SCIPdebugMsg(scip, "(line %d) added constraint <%s>: ", mpsi->lineno, SCIPconsGetName(cons));
    3071
    3072 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
    3073 SCIP_CALL( SCIPreleaseVar(scip, &qmatrixvar) );
    3074 }
    3075 }
    3076 else
    3077 {
    3078 SCIPwarningMessage(scip, "%s section has no entries.\n", isQuadObj ? "QUADOBJ" : "QMATRIX");
    3079 }
    3080
    3081 SCIPfreeBufferArray(scip, &quadvars1);
    3082 SCIPfreeBufferArray(scip, &quadvars2);
    3083 SCIPfreeBufferArray(scip, &quadcoefs);
    3084
    3085 SCIP_CALL( retcode );
    3086
    3087 return SCIP_OKAY;
    3088}
    3089
    3090
    3091/** Process QCMATRIX section.
    3092 *
    3093 * We read the QCMATRIX section, which is a nonstandard section introduced by CPLEX.
    3094 *
    3095 * We replace the corresponding linear constraint by a quadratic constraint which contains the
    3096 * original linear constraint plus the quadratic part specified in the QCMATRIX.
    3097 */
    3098static
    3100 MPSINPUT* mpsi, /**< mps input structure */
    3101 SCIP* scip /**< SCIP data structure */
    3102 )
    3103{
    3104 SCIP_CONS* lincons; /* the linear constraint that was added for the corresponding row */
    3105 SCIP_VAR** quadvars1;
    3106 SCIP_VAR** quadvars2;
    3107 SCIP_Real* quadcoefs;
    3108 SCIP_RETCODE retcode;
    3109 int cnt = 0; /* number of qcmatrix elements processed so far */
    3110 int size; /* size of quad* arrays */
    3111
    3112 if( mpsinputField1(mpsi) == NULL )
    3113 {
    3114 SCIPerrorMessage("no row name in QCMATRIX line.\n");
    3115 mpsinputSyntaxerror(mpsi);
    3116 return SCIP_OKAY;
    3117 }
    3118
    3119 if( SCIPisExact(scip) )
    3120 {
    3121 SCIPerrorMessage("Exact solving mode cannot handle QCMatrix constraints currently \n");
    3122 return SCIP_READERROR;
    3123 }
    3124
    3125 retcode = SCIP_OKAY;
    3126
    3127 SCIPdebugMsg(scip, "read QCMATRIX section for row <%s>\n", mpsinputField1(mpsi));
    3128
    3129 lincons = SCIPfindCons(scip, mpsinputField1(mpsi));
    3130 if( lincons == NULL )
    3131 {
    3132 SCIPerrorMessage("no row under name <%s> processed so far.\n", mpsinputField1(mpsi));
    3133 mpsinputSyntaxerror(mpsi);
    3134 return SCIP_OKAY;
    3135 }
    3136
    3137 size = 1;
    3138 SCIP_CALL( SCIPallocBufferArray(scip, &quadvars1, size) );
    3139 SCIP_CALL( SCIPallocBufferArray(scip, &quadvars2, size) );
    3140 SCIP_CALL( SCIPallocBufferArray(scip, &quadcoefs, size) );
    3141
    3142 /* loop through section */
    3143 /* coverity[tainted_data] */
    3144 while( mpsinputReadLine(mpsi) )
    3145 {
    3146 /* otherwise we are in the section given variables */
    3147 SCIP_VAR* var1;
    3148 SCIP_VAR* var2;
    3149 SCIP_Real coef;
    3150
    3151 /* check if next section is found */
    3152 if( mpsinputField0(mpsi) != NULL )
    3153 {
    3154 if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
    3156 else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
    3158 else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
    3160 else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
    3162 else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
    3164 break;
    3165 }
    3166 if( mpsinputField1(mpsi) == NULL && mpsinputField2(mpsi) == NULL )
    3167 {
    3168 SCIPerrorMessage("empty data in a non-comment line.\n");
    3169 mpsinputSyntaxerror(mpsi);
    3170
    3171 goto TERMINATE;
    3172 }
    3173
    3174 /* get first variable */
    3175 var1 = SCIPfindVar(scip, mpsinputField1(mpsi));
    3176 if( var1 == NULL )
    3177 {
    3178 /* ignore unknown variables - we would not know the type anyway */
    3179 mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField1(mpsi), "QCMatrix", SCIPconsGetName(lincons), SCIP_VERBLEVEL_NORMAL);
    3180 }
    3181 else
    3182 {
    3183 /* get second variable */
    3184 var2 = SCIPfindVar(scip, mpsinputField2(mpsi));
    3185 if( var2 == NULL )
    3186 {
    3187 /* ignore unknown variables - we would not know the type anyway */
    3188 mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField2(mpsi), "QCMatrix", SCIPconsGetName(lincons), SCIP_VERBLEVEL_NORMAL);
    3189 }
    3190 else
    3191 {
    3192 char* endptr;
    3193 if( mpsinputField3(mpsi) == NULL )
    3194 {
    3195 SCIPerrorMessage("coefficient of term <%s>*<%s> not specified.\n", mpsinputField1(mpsi), mpsinputField2(mpsi));
    3196 mpsinputSyntaxerror(mpsi);
    3197
    3198 goto TERMINATE;
    3199 }
    3200
    3201 /* get coefficient */
    3202 coef = strtod(mpsinputField3(mpsi), &endptr);
    3203 if( endptr == mpsinputField3(mpsi) || *endptr != '\0' )
    3204 {
    3205 SCIPerrorMessage("coefficient of term <%s>*<%s> not specified.\n", mpsinputField1(mpsi), mpsinputField2(mpsi));
    3206 mpsinputSyntaxerror(mpsi);
    3207
    3208 goto TERMINATE;
    3209 }
    3210
    3211 /* store variables and coefficient */
    3212 if( cnt >= size )
    3213 {
    3214 int newsize = SCIPcalcMemGrowSize(scip, size+1);
    3215 assert(newsize > size);
    3216 SCIP_CALL( SCIPreallocBufferArray(scip, &quadvars1, newsize) );
    3217 SCIP_CALL( SCIPreallocBufferArray(scip, &quadvars2, newsize) );
    3218 SCIP_CALL( SCIPreallocBufferArray(scip, &quadcoefs, newsize) );
    3219 size = newsize;
    3220 }
    3221 assert(cnt < size);
    3222 quadvars1[cnt] = var1;
    3223 quadvars2[cnt] = var2;
    3224 quadcoefs[cnt] = coef;
    3225 ++cnt;
    3226
    3227 SCIPdebugMsg(scip, "stored term %g*<%s>*<%s>.\n", coef, SCIPvarGetName(var1), SCIPvarGetName(var2));
    3228
    3229 /* check other fields */
    3230 if( (mpsinputField4(mpsi) != NULL && *mpsinputField4(mpsi) != '\0' ) ||
    3231 (mpsinputField5(mpsi) != NULL && *mpsinputField5(mpsi) != '\0' ) )
    3232 {
    3233 SCIPwarningMessage(scip, "ignoring data in fields 4 and 5 <%s> <%s>.\n", mpsinputField4(mpsi), mpsinputField5(mpsi));
    3234 }
    3235 }
    3236 }
    3237 }
    3238
    3239 /* replace linear constraint by quadratic constraint */
    3240 if( cnt )
    3241 {
    3242 SCIP_CONS* cons = NULL;
    3243
    3244 retcode = SCIPcreateConsQuadraticNonlinear(scip, &cons, SCIPconsGetName(lincons),
    3245 SCIPgetNVarsLinear(scip, lincons), SCIPgetVarsLinear(scip, lincons), SCIPgetValsLinear(scip, lincons),
    3246 cnt, quadvars1, quadvars2, quadcoefs, SCIPgetLhsLinear(scip, lincons), SCIPgetRhsLinear(scip, lincons),
    3247 SCIPconsIsInitial(lincons), SCIPconsIsSeparated(lincons), SCIPconsIsEnforced(lincons), SCIPconsIsChecked(lincons),
    3248 SCIPconsIsPropagated(lincons), SCIPconsIsLocal(lincons), SCIPconsIsModifiable(lincons), SCIPconsIsDynamic(lincons),
    3249 SCIPconsIsRemovable(lincons));
    3250
    3251 if( retcode != SCIP_OKAY )
    3252 goto TERMINATE;
    3253
    3254 SCIP_CALL( SCIPaddCons(scip, cons) );
    3255 SCIPdebugMsg(scip, "(line %d) added constraint <%s>: ", mpsi->lineno, SCIPconsGetName(cons));
    3257
    3258 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
    3259
    3260 SCIP_CALL( SCIPdelCons(scip, lincons) );
    3261 }
    3262 else
    3263 {
    3264 SCIPwarningMessage(scip, "QCMATRIX section for constraint <%s> has no entries.\n", SCIPconsGetName(lincons));
    3265 }
    3266
    3267 TERMINATE:
    3268 SCIPfreeBufferArray(scip, &quadcoefs);
    3269 SCIPfreeBufferArray(scip, &quadvars2);
    3270 SCIPfreeBufferArray(scip, &quadvars1);
    3271
    3272 SCIP_CALL( retcode );
    3273
    3274 return SCIP_OKAY;
    3275}
    3276
    3277
    3278/** Process INDICATORS section.
    3279 *
    3280 * We read the INDICATORS section, which is a nonstandard section introduced by CPLEX.
    3281 * Note that CPLEX does not allow ranged rows.
    3282 *
    3283 * If the linear constraints are equations or ranged rows, we generate two indicator
    3284 * constraints.
    3285 *
    3286 * The section has to come after the QMATRIX* sections.
    3287 */
    3288static
    3290 MPSINPUT* mpsi, /**< mps input structure */
    3291 SCIP* scip /**< SCIP data structure */
    3292 )
    3293{
    3294 SCIP_Bool initial;
    3296 SCIP_Bool enforce;
    3297 SCIP_Bool check;
    3298 SCIP_Bool propagate;
    3299 SCIP_Bool local;
    3300 SCIP_Bool dynamic;
    3301 SCIP_Bool removable;
    3302 SCIP_Bool stickingatnode;
    3303 char name[MPS_MAX_NAMELEN] = { '\0' };
    3304
    3305 SCIPdebugMsg(scip, "read INDICATORS constraints\n");
    3306
    3307 if( SCIPisExact(scip) )
    3308 {
    3309 SCIPerrorMessage("Exact solving mode cannot handle indicator constraints currently \n");
    3310 return SCIP_READERROR;
    3311 }
    3312
    3313 /* standard settings for indicator constraints: */
    3314 initial = mpsi->initialconss;
    3315 separate = TRUE;
    3316 enforce = TRUE;
    3317 check = TRUE;
    3318 propagate = TRUE;
    3319 local = FALSE;
    3320 dynamic = mpsi->dynamicconss;
    3321 removable = mpsi->dynamicrows;
    3322 stickingatnode = FALSE;
    3323
    3324 /* loop through section */
    3325 while( mpsinputReadLine(mpsi) )
    3326 {
    3327 SCIP_CONSHDLR* conshdlr;
    3328 SCIP_CONS* cons;
    3329 SCIP_CONS* lincons;
    3330 SCIP_VAR* binvar;
    3331 SCIP_Real lhs;
    3332 SCIP_Real rhs;
    3333
    3334 /* check if next section is found */
    3335 if( mpsinputField0(mpsi) != NULL )
    3336 {
    3337 if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
    3339 break;
    3340 }
    3341
    3342 if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL )
    3343 {
    3344 SCIPerrorMessage("empty data in a non-comment line.\n");
    3345 mpsinputSyntaxerror(mpsi);
    3346 return SCIP_OKAY;
    3347 }
    3348
    3349 /* check for new indicator constraint */
    3350 if( strcmp(mpsinputField1(mpsi), "IF") != 0 )
    3351 {
    3352 SCIPerrorMessage("Indicator constraints need to be introduced by 'IF' in column 1.\n");
    3353 mpsinputSyntaxerror(mpsi);
    3354 return SCIP_OKAY;
    3355 }
    3356
    3357 /* get linear constraint (row) */
    3358 lincons = SCIPfindCons(scip, mpsinputField2(mpsi));
    3359 if( lincons == NULL )
    3360 {
    3361 SCIPerrorMessage("row <%s> does not exist.\n", mpsinputField2(mpsi));
    3362 mpsinputSyntaxerror(mpsi);
    3363 return SCIP_OKAY;
    3364 }
    3365
    3366 /* check whether constraint is really linear */
    3367 conshdlr = SCIPconsGetHdlr(lincons);
    3368 if( strcmp(SCIPconshdlrGetName(conshdlr), "linear") != 0 )
    3369 {
    3370 SCIPerrorMessage("constraint <%s> is not linear.\n", mpsinputField2(mpsi));
    3371 mpsinputSyntaxerror(mpsi);
    3372 return SCIP_OKAY;
    3373 }
    3374
    3375 /* get binary variable */
    3376 binvar = SCIPfindVar(scip, mpsinputField3(mpsi));
    3377 if( binvar == NULL )
    3378 {
    3379 SCIPerrorMessage("binary variable <%s> does not exist.\n", mpsinputField3(mpsi));
    3380 mpsinputSyntaxerror(mpsi);
    3381 return SCIP_OKAY;
    3382 }
    3383
    3384 /* check type */
    3385 if( SCIPvarGetType(binvar) != SCIP_VARTYPE_BINARY )
    3386 {
    3387 SCIPerrorMessage("variable <%s> is not binary.\n", mpsinputField3(mpsi));
    3388 mpsinputSyntaxerror(mpsi);
    3389 return SCIP_OKAY;
    3390 }
    3391
    3392 /* check whether we need the negated variable */
    3393 if( mpsinputField4(mpsi) != NULL )
    3394 {
    3395 if( *mpsinputField4(mpsi) == '0' )
    3396 {
    3397 SCIP_VAR* var;
    3398 SCIP_CALL( SCIPgetNegatedVar(scip, binvar, &var) );
    3399 binvar = var;
    3400 assert( binvar != NULL );
    3401 }
    3402 else
    3403 {
    3404 if( *mpsinputField4(mpsi) != '1' )
    3405 {
    3406 SCIPerrorMessage("binary variable <%s> can only take values 0/1 (%s).\n", mpsinputField3(mpsi), mpsinputField4(mpsi));
    3407 mpsinputSyntaxerror(mpsi);
    3408 return SCIP_OKAY;
    3409 }
    3410 }
    3411 }
    3412
    3413 /* get lhs/rhs */
    3414 lhs = SCIPgetLhsLinear(scip, lincons);
    3415 rhs = SCIPgetRhsLinear(scip, lincons);
    3416
    3417 if( !SCIPisInfinity(scip, -lhs) )
    3418 {
    3419 if( ! SCIPisInfinity(scip, rhs) )
    3420 {
    3421 /* create second indicator constraint */
    3422 SCIP_VAR** vars;
    3423 SCIP_Real* vals;
    3424 SCIP_RETCODE retcode;
    3425 SCIP_VAR** linvars;
    3426 SCIP_Real* linvals;
    3427 int nlinvars;
    3428 int i;
    3429
    3430 nlinvars = SCIPgetNVarsLinear(scip, lincons);
    3431 linvars = SCIPgetVarsLinear(scip, lincons);
    3432 linvals = SCIPgetValsLinear(scip, lincons);
    3433
    3434 SCIP_CALL( SCIPallocBufferArray(scip, &vars, nlinvars) );
    3435 SCIP_CALL( SCIPallocBufferArray(scip, &vals, nlinvars) );
    3436 for( i = 0; i < nlinvars; ++i )
    3437 {
    3438 vars[i] = linvars[i];
    3439 vals[i] = -linvals[i];
    3440 }
    3441
    3442 /* create new name */
    3443 (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "indlhs_%s", SCIPconsGetName(lincons));
    3444
    3445 /* create indicator constraint */
    3446 retcode = SCIPcreateConsIndicator(scip, &cons, name, binvar, nlinvars, vars, vals, -lhs,
    3447 initial, separate, enforce, check, propagate, local, dynamic, removable, stickingatnode);
    3448
    3449 if( retcode == SCIP_OKAY )
    3450 {
    3451 SCIP_CALL( SCIPaddCons(scip, cons) );
    3452 SCIPdebugMsg(scip, "created indicator constraint <%s>\n", mpsinputField2(mpsi));
    3454 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
    3455 }
    3456
    3457 SCIPfreeBufferArray(scip, &vals);
    3458 SCIPfreeBufferArray(scip, &vars);
    3459
    3460 SCIP_CALL( retcode );
    3461 }
    3462 }
    3463
    3464 /* correct linear constraint and create new name */
    3465 if ( ! SCIPisInfinity(scip, -lhs) && ! SCIPisInfinity(scip, rhs) )
    3466 {
    3467 /* we have added lhs above and only need the rhs */
    3469 (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "indrhs_%s", SCIPconsGetName(lincons));
    3470 }
    3471 else
    3472 (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "ind_%s", SCIPconsGetName(lincons));
    3473
    3474 /* create indicator constraint */
    3475 SCIP_CALL( SCIPcreateConsIndicatorLinConsPure(scip, &cons, name, binvar, lincons,
    3476 initial, separate, enforce, check, propagate, local, dynamic, removable, stickingatnode) );
    3477
    3478 SCIP_CALL( SCIPaddCons(scip, cons) );
    3479 SCIPdebugMsg(scip, "created indicator constraint <%s>", mpsinputField2(mpsi));
    3481 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
    3482 }
    3483
    3484 return SCIP_OKAY;
    3485}
    3486
    3487
    3488/** Read LP in "MPS File Format".
    3489 *
    3490 * A specification of the MPS format can be found at
    3491 *
    3492 * http://plato.asu.edu/ftp/mps_format.txt,
    3493 * ftp://ftp.caam.rice.edu/pub/people/bixby/miplib/mps_format,
    3494 *
    3495 * and in the
    3496 *
    3497 * CPLEX Reference Manual
    3498 *
    3499 * This routine should read all valid MPS format files.
    3500 * What it will not do, is to find all cases where a file is ill formed.
    3501 * If this happens it may complain and read nothing or read "something".
    3502 */
    3503static
    3505 SCIP* scip, /**< SCIP data structure */
    3506 const char* filename, /**< name of the input file */
    3507 const char*** varnames, /**< storage for the variable names, or NULL */
    3508 const char*** consnames, /**< storage for the constraint names, or NULL */
    3509 int* varnamessize, /**< the size of the variable names storage, or NULL */
    3510 int* consnamessize, /**< the size of the constraint names storage, or NULL */
    3511 int* nvarnames, /**< the number of stored variable names, or NULL */
    3512 int* nconsnames /**< the number of stored constraint names, or NULL */
    3513 )
    3514{
    3515 SCIP_FILE* fp;
    3516 MPSINPUT* mpsi;
    3517 SCIP_RETCODE retcode;
    3518
    3519 assert(scip != NULL);
    3520 assert(filename != NULL);
    3521
    3522 fp = SCIPfopen(filename, "r");
    3523 if( fp == NULL )
    3524 {
    3525 SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
    3526 SCIPprintSysError(filename);
    3527 return SCIP_NOFILE;
    3528 }
    3529
    3530 SCIP_CALL( mpsinputCreate(scip, &mpsi, fp) );
    3531
    3532 SCIP_CALL_TERMINATE( retcode, readName(scip, mpsi), TERMINATE );
    3533
    3534 SCIP_CALL_TERMINATE( retcode, SCIPcreateProb(scip, mpsi->probname, NULL, NULL, NULL, NULL, NULL, NULL, NULL), TERMINATE );
    3535
    3536 if( mpsinputSection(mpsi) == MPS_OBJSEN )
    3537 {
    3538 SCIP_CALL_TERMINATE( retcode, readObjsen(scip, mpsi), TERMINATE );
    3539 }
    3540 if( mpsinputSection(mpsi) == MPS_OBJNAME )
    3541 {
    3542 SCIP_CALL_TERMINATE( retcode, readObjname(scip, mpsi), TERMINATE );
    3543 }
    3544 while( mpsinputSection(mpsi) == MPS_ROWS
    3545 || mpsinputSection(mpsi) == MPS_USERCUTS
    3546 || mpsinputSection(mpsi) == MPS_LAZYCONS )
    3547 {
    3548 SCIP_CALL_TERMINATE( retcode, readRows(mpsi, scip, consnames, consnamessize, nconsnames), TERMINATE );
    3549 }
    3550 if( mpsinputSection(mpsi) == MPS_COLUMNS )
    3551 {
    3552 SCIP_CALL_TERMINATE( retcode, readCols(mpsi, scip, varnames, varnamessize, nvarnames), TERMINATE );
    3553 }
    3554 if( mpsinputSection(mpsi) == MPS_RHS )
    3555 {
    3556 SCIP_CALL_TERMINATE( retcode, readRhs(mpsi, scip), TERMINATE );
    3557 }
    3558 if( mpsinputSection(mpsi) == MPS_RANGES )
    3559 {
    3560 SCIP_CALL_TERMINATE( retcode, readRanges(mpsi, scip), TERMINATE );
    3561 }
    3562 if( mpsinputSection(mpsi) == MPS_BOUNDS )
    3563 {
    3564 SCIP_CALL_TERMINATE( retcode, readBounds(mpsi, scip), TERMINATE );
    3565 }
    3566 if( mpsinputSection(mpsi) == MPS_SOS )
    3567 {
    3568 SCIP_CALL_TERMINATE( retcode, readSOS(mpsi, scip), TERMINATE );
    3569 }
    3570 while( mpsinputSection(mpsi) == MPS_QCMATRIX )
    3571 {
    3572 SCIP_CALL_TERMINATE( retcode, readQCMatrix(mpsi, scip), TERMINATE );
    3573 }
    3574 if( mpsinputSection(mpsi) == MPS_QMATRIX )
    3575 {
    3576 SCIP_CALL_TERMINATE( retcode, readQMatrix(mpsi, FALSE, scip), TERMINATE );
    3577 }
    3578 if( mpsinputSection(mpsi) == MPS_QUADOBJ )
    3579 {
    3580 SCIP_CALL_TERMINATE( retcode, readQMatrix(mpsi, TRUE, scip), TERMINATE );
    3581 }
    3582 while( mpsinputSection(mpsi) == MPS_QCMATRIX )
    3583 {
    3584 SCIP_CALL_TERMINATE( retcode, readQCMatrix(mpsi, scip), TERMINATE );
    3585 }
    3586 if( mpsinputSection(mpsi) == MPS_INDICATORS )
    3587 {
    3588 SCIP_CALL_TERMINATE( retcode, readIndicators(mpsi, scip), TERMINATE );
    3589 }
    3590 if( mpsinputSection(mpsi) != MPS_ENDATA )
    3591 mpsinputSyntaxerror(mpsi);
    3592
    3593 if( mpsinputHasError(mpsi) )
    3594 {
    3595 retcode = SCIP_READERROR;
    3596 goto TERMINATE;
    3597 }
    3598
    3599 SCIP_CALL_TERMINATE( retcode, SCIPsetObjsense(scip, mpsinputObjsense(mpsi)), TERMINATE );
    3600
    3601 TERMINATE:
    3602 mpsinputFree(scip, &mpsi);
    3603 SCIPfclose(fp);
    3604
    3605 return retcode;
    3606}
    3607
    3608/** Read LP in "MPS File Format" (version for exact solving mode, numbers can also be rationals).
    3609 *
    3610 * A specification of the MPS format can be found at
    3611 *
    3612 * http://plato.asu.edu/ftp/mps_format.txt,
    3613 * ftp://ftp.caam.rice.edu/pub/people/bixby/miplib/mps_format,
    3614 *
    3615 * and in the
    3616 *
    3617 * CPLEX Reference Manual
    3618 *
    3619 * This routine should read all valid MPS format files.
    3620 * What it will not do, is to find all cases where a file is ill formed.
    3621 * If this happens it may complain and read nothing or read "something".
    3622 */
    3623static
    3625 SCIP* scip, /**< SCIP data structure */
    3626 const char* filename, /**< name of the input file */
    3627 const char*** varnames, /**< storage for the variable names, or NULL */
    3628 const char*** consnames, /**< storage for the constraint names, or NULL */
    3629 int* varnamessize, /**< the size of the variable names storage, or NULL */
    3630 int* consnamessize, /**< the size of the constraint names storage, or NULL */
    3631 int* nvarnames, /**< the number of stored variable names, or NULL */
    3632 int* nconsnames /**< the number of stored constraint names, or NULL */
    3633 )
    3634{
    3635 SCIP_FILE* fp;
    3636 MPSINPUT* mpsi;
    3637 SCIP_RETCODE retcode;
    3638
    3639 assert(scip != NULL);
    3640 assert(filename != NULL);
    3641 assert(SCIPisExact(scip));
    3642
    3643 fp = SCIPfopen(filename, "r");
    3644 if( fp == NULL )
    3645 {
    3646 SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
    3647 SCIPprintSysError(filename);
    3648 return SCIP_NOFILE;
    3649 }
    3650
    3651 SCIP_CALL( mpsinputCreate(scip, &mpsi, fp) );
    3652
    3653 SCIP_CALL_TERMINATE( retcode, readName(scip, mpsi), TERMINATE );
    3654
    3655 SCIP_CALL_TERMINATE( retcode, SCIPcreateProb(scip, mpsi->probname, NULL, NULL, NULL, NULL, NULL, NULL, NULL), TERMINATE );
    3656
    3657 if( mpsinputSection(mpsi) == MPS_OBJSEN )
    3658 {
    3659 SCIP_CALL_TERMINATE( retcode, readObjsen(scip, mpsi), TERMINATE );
    3660 }
    3661 if( mpsinputSection(mpsi) == MPS_OBJNAME )
    3662 {
    3663 SCIP_CALL_TERMINATE( retcode, readObjname(scip, mpsi), TERMINATE );
    3664 }
    3665 while( mpsinputSection(mpsi) == MPS_ROWS
    3666 || mpsinputSection(mpsi) == MPS_USERCUTS
    3667 || mpsinputSection(mpsi) == MPS_LAZYCONS )
    3668 {
    3669 SCIP_CALL_TERMINATE( retcode, readRowsExact(mpsi, scip, consnames, consnamessize, nconsnames), TERMINATE );
    3670 }
    3671 if( mpsinputSection(mpsi) == MPS_COLUMNS )
    3672 {
    3673 SCIP_CALL_TERMINATE( retcode, readColsExact(mpsi, scip, varnames, varnamessize, nvarnames), TERMINATE );
    3674 }
    3675 if( mpsinputSection(mpsi) == MPS_RHS )
    3676 {
    3677 SCIP_CALL_TERMINATE( retcode, readRhsExact(mpsi, scip), TERMINATE );
    3678 }
    3679 if( mpsinputSection(mpsi) == MPS_RANGES )
    3680 {
    3681 SCIP_CALL_TERMINATE( retcode, readRangesExact(mpsi, scip), TERMINATE );
    3682 }
    3683 if( mpsinputSection(mpsi) == MPS_BOUNDS )
    3684 {
    3685 SCIP_CALL_TERMINATE( retcode, readBoundsExact(mpsi, scip), TERMINATE );
    3686 }
    3687 if( mpsinputSection(mpsi) == MPS_SOS )
    3688 {
    3689 SCIP_CALL_TERMINATE( retcode, readSOS(mpsi, scip), TERMINATE );
    3690 }
    3691 while( mpsinputSection(mpsi) == MPS_QCMATRIX )
    3692 {
    3693 SCIP_CALL_TERMINATE( retcode, readQCMatrix(mpsi, scip), TERMINATE );
    3694 }
    3695 if( mpsinputSection(mpsi) == MPS_QMATRIX )
    3696 {
    3697 SCIP_CALL_TERMINATE( retcode, readQMatrix(mpsi, FALSE, scip), TERMINATE );
    3698 }
    3699 if( mpsinputSection(mpsi) == MPS_QUADOBJ )
    3700 {
    3701 SCIP_CALL_TERMINATE( retcode, readQMatrix(mpsi, TRUE, scip), TERMINATE );
    3702 }
    3703 while( mpsinputSection(mpsi) == MPS_QCMATRIX )
    3704 {
    3705 SCIP_CALL_TERMINATE( retcode, readQCMatrix(mpsi, scip), TERMINATE );
    3706 }
    3707 if( mpsinputSection(mpsi) == MPS_INDICATORS )
    3708 {
    3709 SCIP_CALL_TERMINATE( retcode, readIndicators(mpsi, scip), TERMINATE );
    3710 }
    3711 if( mpsinputSection(mpsi) != MPS_ENDATA )
    3712 mpsinputSyntaxerror(mpsi);
    3713
    3714 if( mpsinputHasError(mpsi) )
    3715 {
    3716 retcode = SCIP_READERROR;
    3717 goto TERMINATE;
    3718 }
    3719
    3720 SCIP_CALL_TERMINATE( retcode, SCIPsetObjsense(scip, mpsinputObjsense(mpsi)), TERMINATE );
    3721
    3722 TERMINATE:
    3723 mpsinputFree(scip, &mpsi);
    3724 SCIPfclose(fp);
    3725
    3726 return retcode;
    3727}
    3728
    3729/*
    3730 * local methods for writing problem
    3731 */
    3732
    3733/** gets the key (i.e. the name) of the given namefreq */
    3734static
    3735SCIP_DECL_HASHGETKEY(hashGetKeyNamefreq)
    3736{ /*lint --e{715}*/
    3737 CONSNAMEFREQ* consnamefreq = (CONSNAMEFREQ*)elem;
    3738
    3739 assert(consnamefreq != NULL);
    3740 assert(consnamefreq->consname != NULL);
    3741
    3742 return (void*)consnamefreq->consname;
    3743}
    3744
    3745/** returns TRUE iff both keys (i.e. strings) are equal up to max length*/
    3746static
    3747SCIP_DECL_HASHKEYEQ(hashKeyEqString)
    3748{ /*lint --e{715}*/
    3749 const char* string1 = (const char*)key1;
    3750 const char* string2 = (const char*)key2;
    3751
    3752 return (strncmp(string1, string2, MPS_MAX_NAMELEN - 1) == 0);
    3753}
    3754
    3755/** hash key retrieval function for variables */
    3756static
    3758{ /*lint --e{715}*/
    3759 return elem;
    3760}
    3761
    3762/** returns TRUE iff the indices of both variables are equal */
    3763static
    3765{ /*lint --e{715}*/
    3766 if( key1 == key2 )
    3767 return TRUE;
    3768 return FALSE;
    3769}
    3770
    3771/** returns the hash value of the key */
    3772static
    3774{ /*lint --e{715}*/
    3775 assert( SCIPvarGetIndex((SCIP_VAR*) key) >= 0 );
    3776 return (unsigned int) SCIPvarGetIndex((SCIP_VAR*) key);
    3777}
    3778
    3779
    3780/** computes the field width such that the output file is nicely arranged */
    3781static
    3783 unsigned int width /**< required width */
    3784 )
    3785{
    3786 width = MAX(8u, width);
    3787 return MIN(MPS_MAX_FIELDLEN, width);
    3788}
    3789
    3790
    3791/** output two strings in columns 1 and 2 with computed widths */
    3792static
    3794 SCIP* scip, /**< SCIP data structure */
    3795 FILE* file, /**< output file (or NULL for standard output) */
    3796 const char* col1, /**< column 1 */
    3797 const char* col2, /**< column 2 */
    3798 unsigned int maxnamelen /**< maximum name length */
    3799 )
    3800{
    3801 unsigned int fieldwidth;
    3802 char format[32];
    3803
    3804 assert( scip != NULL );
    3805 assert( col1 != NULL );
    3806 assert( col2 != NULL );
    3807 assert( strlen(col1) < MPS_MAX_NAMELEN );
    3808 assert( strlen(col2) < MPS_MAX_VALUELEN );
    3809 assert( maxnamelen > 0 );
    3810
    3811 fieldwidth = computeFieldWidth(maxnamelen);
    3812 (void) SCIPsnprintf(format, 32," %%-%ds %%%ds ", fieldwidth, MPS_MAX_VALUELEN - 1);
    3813
    3814 SCIPinfoMessage(scip, file, (const char *)format, col1, col2);
    3815}
    3816
    3817/** output two strings in columns 1 (width 2) and 2 (width 8) */
    3818static
    3820 SCIP* scip, /**< SCIP data structure */
    3821 FILE* file, /**< output file (or NULL for standard output) */
    3822 const char* col1, /**< column 1 */
    3823 const char* col2, /**< column 2 */
    3824 int maxnamelen /**< maximum name length (-1 if irrelevant) */
    3825 )
    3826{
    3827 unsigned int fieldwidth;
    3828 char format[32];
    3829
    3830 assert( scip != NULL );
    3831 assert( col1 != NULL );
    3832 assert( col2 != NULL );
    3833 assert( strlen(col1) <= 2 );
    3834 assert( strlen(col2) < MPS_MAX_NAMELEN );
    3835 assert( maxnamelen == -1 || maxnamelen > 0 );
    3836
    3837 if( maxnamelen < 0 )
    3838 {
    3839 /* format does not matter */
    3840 (void) SCIPsnprintf(format, 32, " %%-2.2s %%-s ");
    3841 }
    3842 else
    3843 {
    3844 fieldwidth = computeFieldWidth((unsigned int) maxnamelen);
    3845 (void) SCIPsnprintf(format, 32, " %%-2.2s %%-%ds ", fieldwidth);
    3846 }
    3847
    3848 SCIPinfoMessage(scip, file, (const char*)format, col1, col2);
    3849}
    3850
    3851/** prints the given data as column entry */
    3852static
    3854 SCIP* scip, /**< SCIP data structure */
    3855 FILE* file, /**< output file (or NULL for standard output) */
    3856 const char* varname, /**< variable name */
    3857 const char* consname, /**< constraint name */
    3858 SCIP_Real value, /**< value to display */
    3859 int* recordcnt, /**< pointer to store the number of records per line */
    3860 unsigned int maxnamelen /**< maximum name length */
    3861 )
    3862{
    3863 char valuestr[MPS_MAX_VALUELEN] = { '\0' };
    3864
    3865 assert( scip != NULL );
    3866 assert( recordcnt != NULL );
    3867 assert( *recordcnt >= 0 && *recordcnt < 2 );
    3868
    3869 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", value);
    3870
    3871 if( *recordcnt == 0 )
    3872 {
    3873 /* start new line with an empty first column and the variable name in the second column */
    3874 printStart(scip, file, "", varname, (int) maxnamelen);
    3875 *recordcnt = 0;
    3876 }
    3877
    3878 printRecord(scip, file, consname, valuestr, maxnamelen);
    3879 (*recordcnt)++;
    3880
    3881 if( *recordcnt == 2 )
    3882 {
    3883 /* each line can have at most two records */
    3884 SCIPinfoMessage(scip, file, "\n");
    3885 *recordcnt = 0;
    3886 }
    3887}
    3888
    3889/** prints the constraint type to file stream */
    3890static
    3892 SCIP* scip, /**< SCIP data structure */
    3893 FILE* file, /**< output file (or NULL for standard output) */
    3894 SCIP_Real lhs, /**< left hand side */
    3895 SCIP_Real rhs, /**< right hand side */
    3896 const char* name /**< constraint name */
    3897 )
    3898{
    3899 char rowtype[2];
    3900
    3901 assert( scip != NULL );
    3902 assert( !SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs) );
    3903 assert( SCIPisGT(scip, rhs, lhs) || SCIPisEQ(scip, lhs, rhs) );
    3904 assert( name != NULL );
    3905
    3906 if( SCIPisEQ(scip, lhs, rhs) )
    3907 (void) SCIPsnprintf(rowtype, 2, "%s", "E");
    3908 else
    3909 {
    3910 /* in case the right hand side and the left hand side are not infinity we print a
    3911 * less or equal constraint and put the right hand side in the RHS section and the
    3912 * left hand side (hidden) in the RANGE section */
    3913 if( !SCIPisInfinity(scip, rhs) )
    3914 (void) SCIPsnprintf(rowtype, 2, "%s", "L");
    3915 else
    3916 {
    3917 assert( !SCIPisInfinity(scip, -lhs) );
    3918 (void) SCIPsnprintf(rowtype, 2, "%s", "G");
    3919 }
    3920 }
    3921
    3922 printStart(scip, file, rowtype, name, -1);
    3923 SCIPinfoMessage(scip, file, "\n");
    3924}
    3925
    3926
    3927/** initializes the sparse matrix */
    3928static
    3930 SCIP* scip, /**< SCIP data structure */
    3931 SPARSEMATRIX** matrix, /**< pointer to sparse matrix containing the entries */
    3932 int slots /**< number of slots */
    3933 )
    3934{
    3935 SCIP_CALL( SCIPallocBuffer(scip, matrix) );
    3936 (*matrix)->nentries = 0;
    3937 (*matrix)->sentries = slots;
    3938 SCIP_CALL( SCIPallocBufferArray(scip, &(*matrix)->values, (*matrix)->sentries) );
    3939 SCIP_CALL( SCIPallocBufferArray(scip, &(*matrix)->columns, (*matrix)->sentries) );
    3940 SCIP_CALL( SCIPallocBufferArray(scip, &(*matrix)->rows, (*matrix)->sentries) );
    3941
    3942 return SCIP_OKAY;
    3943}
    3944
    3945/** this method takes care that the required capacity is available in the sparse matrix */
    3946static
    3948 SCIP* scip, /**< SCIP data structure */
    3949 SPARSEMATRIX* matrix, /**< sparse matrix for storing the coefficient */
    3950 int capacity /**< needed capacity */
    3951 )
    3952{
    3953 if( matrix->nentries + capacity >= matrix->sentries )
    3954 {
    3955 matrix->sentries = matrix->sentries * 2 + capacity;
    3956 SCIP_CALL( SCIPreallocBufferArray(scip, &matrix->values, matrix->sentries) );
    3957 SCIP_CALL( SCIPreallocBufferArray(scip, &matrix->columns, matrix->sentries) );
    3958 SCIP_CALL( SCIPreallocBufferArray(scip, &matrix->rows, matrix->sentries) );
    3959 }
    3960 return SCIP_OKAY;
    3961}
    3962
    3963/** frees the sparse matrix */
    3964static
    3966 SCIP* scip, /**< SCIP data structure */
    3967 SPARSEMATRIX* matrix /**< sparse matrix to free */
    3968 )
    3969{
    3970 SCIPfreeBufferArray(scip, &matrix->rows);
    3971 SCIPfreeBufferArray(scip, &matrix->columns);
    3972 SCIPfreeBufferArray(scip, &matrix->values);
    3973
    3974 SCIPfreeBuffer(scip, &matrix);
    3975}
    3976
    3977
    3978/** computes the coefficient for the given variables and linear constraint information */
    3979static
    3981 SCIP* scip, /**< SCIP data structure */
    3982 const char* consname, /**< name of the constraint */
    3983 SCIP_VAR** vars, /**< array of variables */
    3984 SCIP_Real* vals, /**< array of coefficients values (or NULL if all coefficient values are 1) */
    3985 int nvars, /**< number of variables */
    3986 SCIP_Bool transformed, /**< transformed constraint? */
    3987 SPARSEMATRIX* matrix, /**< sparse matrix for storing the coefficient */
    3988 SCIP_Real* rhs /**< pointer to right hand side */
    3989 )
    3990{
    3991 SCIP_VAR** activevars;
    3992 SCIP_Real* activevals;
    3993 SCIP_Real activeconstant = 0.0;
    3994
    3995 int nactivevars;
    3996 int requiredsize;
    3997 int v;
    3998
    3999 assert( scip != NULL );
    4000 assert( nvars == 0 || vars != NULL );
    4001 assert( !SCIPisInfinity(scip, *rhs) );
    4002 assert( matrix != NULL );
    4003
    4004 /* if the variables array contains no variables, then return without
    4005 * doing any thing; The MPS format and LP format do not forbid this
    4006 * situation */
    4007 if( nvars == 0 )
    4008 return SCIP_OKAY;
    4009
    4010 /* duplicate variable and value array */
    4011 nactivevars = nvars;
    4012 SCIP_CALL( SCIPduplicateBufferArray(scip, &activevars, vars, nactivevars ) );
    4013
    4014 if( vals != NULL )
    4015 {
    4016 SCIP_CALL( SCIPduplicateBufferArray(scip, &activevals, vals, nactivevars ) );
    4017 }
    4018 else
    4019 {
    4020 SCIP_CALL( SCIPallocBufferArray(scip, &activevals, nactivevars) );
    4021
    4022 for( v = 0; v < nactivevars; ++v )
    4023 activevals[v] = 1.0;
    4024 }
    4025
    4026 /* retransform given variables to active variables */
    4027 if( transformed )
    4028 {
    4029 SCIP_CALL( SCIPgetProbvarLinearSum(scip, activevars, activevals, &nactivevars, nactivevars, &activeconstant, &requiredsize) );
    4030
    4031 if( requiredsize > nactivevars )
    4032 {
    4033 SCIP_CALL( SCIPreallocBufferArray(scip, &activevars, requiredsize) );
    4034 SCIP_CALL( SCIPreallocBufferArray(scip, &activevals, requiredsize) );
    4035
    4036 SCIP_CALL( SCIPgetProbvarLinearSum(scip, activevars, activevals, &nactivevars, requiredsize, &activeconstant, &requiredsize) );
    4037 }
    4038 assert( requiredsize == nactivevars );
    4039 }
    4040 else
    4041 {
    4042 for( v = 0; v < nactivevars; ++v )
    4043 {
    4044 SCIP_CALL( SCIPvarGetOrigvarSum(&activevars[v], &activevals[v], &activeconstant) );
    4045
    4046 /* negated variables with an original counterpart may also be returned by SCIPvarGetOrigvarSum();
    4047 * make sure we get the original variable in that case
    4048 */
    4049 if( SCIPvarGetStatus(activevars[v]) == SCIP_VARSTATUS_NEGATED )
    4050 {
    4051 activevars[v] = SCIPvarGetNegatedVar(activevars[v]);
    4052 activeconstant += activevals[v];
    4053 activevals[v] *= -1.0;
    4054 }
    4055 }
    4056 }
    4057
    4058 /* copy the (matrix) row into the sparse matrix */
    4059 SCIP_CALL( checkSparseMatrixCapacity(scip, matrix, nactivevars) );
    4060 assert( matrix->nentries + nactivevars < matrix->sentries );
    4061
    4062 for( v = 0; v < nactivevars; ++v )
    4063 {
    4064 matrix->values[matrix->nentries] = activevals[v];
    4065 matrix->columns[matrix->nentries] = activevars[v];
    4066 matrix->rows[matrix->nentries] = consname;
    4067 matrix->nentries++;
    4068 }
    4069
    4070 /* adjust right hand side */
    4071 (*rhs) -= activeconstant;
    4072
    4073 /* free buffer arrays */
    4074 SCIPfreeBufferArray(scip, &activevals);
    4075 SCIPfreeBufferArray(scip, &activevars);
    4076
    4077 return SCIP_OKAY;
    4078}
    4079
    4080
    4081/** check whether given variables are aggregated and put them into an array without duplication */
    4082static
    4084 SCIP* scip, /**< SCIP data structure */
    4085 SCIP_VAR** vars, /**< variable array */
    4086 int nvars, /**< number of active variables in the problem */
    4087 SCIP_VAR*** aggvars, /**< pointer to array storing the aggregated variables on output */
    4088 int* naggvars, /**< pointer to number of aggregated variables on output */
    4089 int* saggvars, /**< pointer to number of slots in aggvars array */
    4090 SCIP_HASHTABLE* varAggregated /**< hashtable for checking duplicates */
    4091 )
    4092{
    4093 int v;
    4094
    4095 assert( scip != NULL );
    4096 assert( aggvars != NULL );
    4097 assert( naggvars != NULL );
    4098 assert( saggvars != NULL );
    4099
    4100 /* check variables */
    4101 for( v = 0; v < nvars; ++v )
    4102 {
    4103 SCIP_VARSTATUS status;
    4104 SCIP_VAR* var;
    4105
    4106 var = vars[v];
    4107 status = SCIPvarGetStatus(var);
    4108
    4109 /* collect aggregated variables in a list */
    4110 if( status >= SCIP_VARSTATUS_AGGREGATED )
    4111 {
    4112 assert( status == SCIP_VARSTATUS_AGGREGATED || status == SCIP_VARSTATUS_MULTAGGR || status == SCIP_VARSTATUS_NEGATED );
    4113 assert( varAggregated != NULL );
    4114
    4115 if( ! SCIPhashtableExists(varAggregated, (void*) var) )
    4116 {
    4117 /* possibly enlarge array */
    4118 if ( *saggvars <= *naggvars )
    4119 {
    4120 int newsize;
    4121 newsize = SCIPcalcMemGrowSize(scip, *naggvars + 1);
    4122 assert( newsize > *saggvars );
    4123 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &aggvars, *saggvars, newsize) );
    4124 *saggvars = newsize;
    4125 }
    4126
    4127 (*aggvars)[*naggvars] = var;
    4128 (*naggvars)++;
    4129 SCIP_CALL( SCIPhashtableInsert(varAggregated, (void*) var) );
    4130 assert( *naggvars <= *saggvars );
    4131 }
    4132 }
    4133 }
    4134 return SCIP_OKAY;
    4135}
    4136
    4137
    4138/** method check if the variable names are not longer than MPS_MAX_NAMELEN - 1*/
    4139static
    4141 SCIP* scip, /**< SCIP data structure */
    4142 SCIP_VAR** vars, /**< array of variables */
    4143 int nvars, /**< number of variables */
    4144 unsigned int* maxnamelen, /**< pointer to store the maximum name length */
    4145 const char*** varnames, /**< pointer to array of variable names */
    4146 SCIP_HASHMAP** varnameHashmap /**< pointer to hash map storing variable, variable name mapping */
    4147 )
    4148{
    4149 int v;
    4150 int faulty;
    4151 char* varname;
    4152 SCIP_VAR* var;
    4153
    4154 assert( scip != NULL );
    4155 assert( vars != NULL );
    4156 assert( maxnamelen != NULL );
    4157
    4158 faulty = 0;
    4159
    4160 /* allocate memory */
    4161 SCIP_CALL( SCIPhashmapCreate(varnameHashmap, SCIPblkmem(scip), nvars) );
    4162 SCIP_CALL( SCIPallocBufferArray(scip, varnames, nvars) );
    4163
    4164 /* check if the variable names are not to long */
    4165 for( v = 0; v < nvars; ++v )
    4166 {
    4167 size_t l;
    4168
    4169 var = vars[v];
    4170 assert( var != NULL );
    4171
    4172 l = strlen(SCIPvarGetName(var));
    4173
    4174 if( l >= MPS_MAX_NAMELEN )
    4175 {
    4176 faulty++;
    4177 (*maxnamelen) = MPS_MAX_NAMELEN - 1;
    4178 }
    4179 else
    4180 {
    4181 (*maxnamelen) = MAX(*maxnamelen, (unsigned int) l);
    4182 }
    4183
    4184 SCIP_CALL( SCIPallocBufferArray(scip, &varname, (int) *maxnamelen + 1) );
    4185 (void) SCIPsnprintf(varname, (int)(*maxnamelen) + 1, "%s", SCIPvarGetName(var) );
    4186
    4187 /* insert variable with variable name into hash map */
    4188 assert( !SCIPhashmapExists(*varnameHashmap, var) );
    4189 SCIP_CALL( SCIPhashmapInsert(*varnameHashmap, var, (void*) varname) );
    4190
    4191 (*varnames)[v] = varname;
    4192 }
    4193
    4194 if( faulty > 0 )
    4195 {
    4196 SCIPwarningMessage(scip, "there are %d variable names which have to be cut down to %d characters; LP might be corrupted\n",
    4197 faulty, MPS_MAX_NAMELEN - 1);
    4198 }
    4199 return SCIP_OKAY;
    4200}
    4201
    4202/** method check if the constraint names are not longer than MPS_MAX_NAMELEN - 1 */
    4203static
    4205 SCIP* scip, /**< SCIP data structure */
    4206 SCIP_CONS** conss, /**< array of all constraints */
    4207 int nconss, /**< number of all constraints */
    4208 SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
    4209 unsigned int* maxnamelen, /**< pointer to store the maximum name length */
    4210 const char*** consnames, /**< pointer to array of constraint names */
    4211 SCIP_Bool* error /**< pointer to store whether all constraint names exist */
    4212 )
    4213{
    4214 SCIP_HASHTABLE* consfreq;
    4215 CONSNAMEFREQ* consnamefreqs;
    4216 SCIP_CONS* cons;
    4217 char* consname;
    4218 int i;
    4219
    4220 assert(scip != NULL);
    4221 assert(maxnamelen != NULL);
    4222
    4223 *error = FALSE;
    4224
    4225 /* allocate memory */
    4226 SCIP_CALL( SCIPallocBufferArray(scip, &consnamefreqs, nconss) );
    4227 SCIP_CALL( SCIPallocBufferArray(scip, consnames, nconss) );
    4229 hashGetKeyNamefreq, hashKeyEqString, SCIPhashKeyValString, NULL) );
    4230
    4231 for( i = 0; i < nconss; ++i )
    4232 {
    4233 CONSNAMEFREQ* consnamefreq;
    4234 size_t l;
    4235 int freq;
    4236
    4237 cons = conss[i];
    4238 assert( cons != NULL );
    4239
    4240 /* in case the transformed problem is written, only constraints are posted which are enabled in the current node */
    4241 assert(!transformed || SCIPconsIsEnabled(cons));
    4242
    4243 l = strlen(SCIPconsGetName(cons));
    4244
    4245 if( l == 0 )
    4246 {
    4247 SCIPwarningMessage(scip, "At least one name of a constraint is empty, so file will be written with generic names.\n");
    4248 *error = TRUE;
    4249
    4250 goto TERMINATE;
    4251 }
    4252
    4253 consnamefreqs[i].consname = SCIPconsGetName(cons);
    4254 consnamefreqs[i].freq = 0;
    4255 freq = 0;
    4256
    4257 /* check for duplicate names */
    4258 if( NULL != (consnamefreq = (CONSNAMEFREQ *)SCIPhashtableRetrieve(consfreq, (void*)SCIPconsGetName(cons))) )
    4259 {
    4260 consnamefreq->freq += 1;
    4261 consnamefreqs[i] = *consnamefreq;
    4262 freq = consnamefreq->freq;
    4263 }
    4264 SCIP_CALL( SCIPhashtableInsert(consfreq, (void*)(&consnamefreqs[i])) );
    4265
    4266 /* the new length is the length of the old name + a '_' and the freq number which has floor(log10(freq)) + 1 characters */
    4267 if( freq > 0 )
    4268 l = l + 1 + (size_t)log10((SCIP_Real) freq) + 1;
    4269
    4270 if( l >= MPS_MAX_NAMELEN )
    4271 {
    4272 SCIPwarningMessage(scip, "Constraints have duplicate name and are too long to fix, so file will be written with generic names.\n");
    4273 *error = TRUE;
    4274
    4275 goto TERMINATE;
    4276 }
    4277
    4278 (*maxnamelen) = MAX(*maxnamelen, (unsigned int) l);
    4279
    4280 SCIP_CALL( SCIPallocBufferArray(scip, &consname, (int) l + 1) );
    4281 if( freq > 0 )
    4282 (void) SCIPsnprintf(consname, (int)l + 1, "%s_%d", SCIPconsGetName(cons), freq);
    4283 else
    4284 (void) SCIPsnprintf(consname, (int)l + 1, "%s", SCIPconsGetName(cons));
    4285
    4286 (*consnames)[i] = consname;
    4287 }
    4288
    4289TERMINATE:
    4290 SCIPfreeBufferArray(scip, &consnamefreqs);
    4291
    4292 if( *error )
    4293 {
    4294 --i; /*lint !e445*/
    4295 for( ; i >= 0; --i) /*lint !e445*/
    4296 {
    4297 SCIPfreeBufferArray(scip, &((*consnames)[i]));
    4298 }
    4299 SCIPfreeBufferArray(scip, consnames);
    4300 }
    4301
    4302 SCIPhashtableFree(&consfreq);
    4303
    4304 return SCIP_OKAY;
    4305}
    4306
    4307/** returns whether to print an integrality constraint for the given variable */
    4308static
    4310 SCIP_VAR* var, /**< variable to check */
    4311 int implintlevel /**< implied integral level */
    4312 )
    4313{
    4314 assert(implintlevel >= -2);
    4315 assert(implintlevel <= 2);
    4316
    4318 return (int)SCIPvarGetImplType(var) > 2 - implintlevel;
    4319 else
    4320 return (int)SCIPvarGetImplType(var) <= 2 + implintlevel;
    4321}
    4322
    4323/** template implementation of mpsIntComp for given implied integral level */
    4324#define MPSINTCOMP_LEVEL(IMPLINTLEVEL) \
    4325{ \
    4326 SCIP_Bool integral1 = writeVarIsIntegral((SCIP_VAR*)elem1, IMPLINTLEVEL); \
    4327 SCIP_Bool integral2 = writeVarIsIntegral((SCIP_VAR*)elem2, IMPLINTLEVEL); \
    4328 \
    4329 if( integral1 != integral2 ) \
    4330 return integral1 ? -1 : +1; \
    4331 \
    4332 return SCIPvarComp(elem1, elem2); \
    4333}
    4334
    4335/* comparison methods for sorting variables along their original indices grouping integer variables at the front */
    4337static SCIP_DECL_SORTPTRCOMP(mpsIntCompM1) MPSINTCOMP_LEVEL(-1)
    4338static SCIP_DECL_SORTPTRCOMP(mpsIntCompZ) MPSINTCOMP_LEVEL(0)
    4339static SCIP_DECL_SORTPTRCOMP(mpsIntCompP1) MPSINTCOMP_LEVEL(1)
    4340static SCIP_DECL_SORTPTRCOMP(mpsIntCompP2) MPSINTCOMP_LEVEL(2)
    4341
    4342/** outputs the COLUMNS section of the MPS format */
    4343static
    4344void printColumnSection(
    4345 SCIP* scip, /**< SCIP data structure */
    4346 FILE* file, /**< output file, or NULL if standard output should be used */
    4347 SPARSEMATRIX* matrix, /**< sparse matrix containing the entries */
    4348 SCIP_HASHMAP* varnameHashmap, /**< map from SCIP_VAR* to variable name */
    4349 SCIP_HASHTABLE* indicatorSlackHash, /**< hashtable containing slack variables from indicators (or NULL) */
    4350 unsigned int maxnamelen, /**< maximum name length */
    4351 int implintlevel /**< implied integral level */
    4352 )
    4353{
    4354 SCIP_Bool intSection;
    4355 SCIP_VAR* var;
    4356 const char* varname;
    4357 SCIP_Real value;
    4358 int v;
    4359 int recordcnt;
    4360
    4361 /* @todo: create column matrix instead of sort sparse entries */
    4362 /* sort sparse matrix w.r.t. the written integralities and variable indices */
    4363 switch( implintlevel )
    4364 {
    4365 case -2:
    4366 SCIPsortPtrPtrReal((void**) matrix->columns, (void**) matrix->rows, matrix->values, mpsIntCompM2, matrix->nentries);
    4367 break;
    4368 case -1:
    4369 SCIPsortPtrPtrReal((void**) matrix->columns, (void**) matrix->rows, matrix->values, mpsIntCompM1, matrix->nentries);
    4370 break;
    4371 case 0:
    4372 SCIPsortPtrPtrReal((void**) matrix->columns, (void**) matrix->rows, matrix->values, mpsIntCompZ, matrix->nentries);
    4373 break;
    4374 case 1:
    4375 SCIPsortPtrPtrReal((void**) matrix->columns, (void**) matrix->rows, matrix->values, mpsIntCompP1, matrix->nentries);
    4376 break;
    4377 case 2:
    4378 SCIPsortPtrPtrReal((void**) matrix->columns, (void**) matrix->rows, matrix->values, mpsIntCompP2, matrix->nentries);
    4379 break;
    4380 default:
    4381 SCIPerrorMessage("invalid implintlevel\n");
    4382 SCIPABORT();
    4383 }
    4384
    4385 /* print COLUMNS section */
    4386 SCIPinfoMessage(scip, file, "COLUMNS\n");
    4387
    4388 intSection = FALSE;
    4389
    4390 for( v = 0; v < matrix->nentries; )
    4391 {
    4392 var = matrix->columns[v];
    4393 assert( var != NULL );
    4394
    4395 /* skip slack variables in output */
    4396 if( indicatorSlackHash != NULL && SCIPhashtableExists(indicatorSlackHash, var) )
    4397 {
    4398 ++v;
    4399 continue;
    4400 }
    4401
    4402 /* section integer variables */
    4403 if( writeVarIsIntegral(var, implintlevel) != intSection )
    4404 {
    4405 /* end integer section in MPS format */
    4406 if( intSection )
    4407 {
    4408 printStart(scip, file, "", "INTEND", (int) maxnamelen);
    4409 printRecord(scip, file, "'MARKER'", "", maxnamelen);
    4410 printRecord(scip, file, "'INTEND'", "", maxnamelen);
    4411 SCIPinfoMessage(scip, file, "\n");
    4412 intSection = FALSE;
    4413 }
    4414 /* start integer section in MPS format */
    4415 else
    4416 {
    4417 printStart(scip, file, "", "INTSTART", (int) maxnamelen);
    4418 printRecord(scip, file, "'MARKER'", "", maxnamelen);
    4419 printRecord(scip, file, "'INTORG'", "", maxnamelen);
    4420 SCIPinfoMessage(scip, file, "\n");
    4421 intSection = TRUE;
    4422 }
    4423 }
    4424
    4425 SCIPdebugMsg(scip, "create entries for variable <%s>\n", SCIPvarGetName(var));
    4426
    4427 /* record count; there are at most two records per line */
    4428 recordcnt = 0;
    4429
    4430 /* get variable name */
    4431 assert ( SCIPhashmapExists(varnameHashmap, var) );
    4432 varname = (const char*) SCIPhashmapGetImage(varnameHashmap, var);
    4433
    4434 /* output all entries of the same variable */
    4435 do
    4436 {
    4437 value = matrix->values[v];
    4438
    4439 /* print record to file */
    4440 printEntry(scip, file, varname, matrix->rows[v], value, &recordcnt, maxnamelen);
    4441 v++;
    4442 }
    4443 while( v < matrix->nentries && var == matrix->columns[v] );
    4444
    4445 if( recordcnt == 1 )
    4446 SCIPinfoMessage(scip, file, "\n");
    4447 }
    4448 /* end integer section, if the columns sections ends with integer variables */
    4449 if( intSection )
    4450 {
    4451 /* end integer section in MPS format */
    4452 printStart(scip, file, "", "INTEND", (int) maxnamelen);
    4453 printRecord(scip, file, "'MARKER'", "", maxnamelen);
    4454 printRecord(scip, file, "'INTEND'", "", maxnamelen);
    4455 SCIPinfoMessage(scip, file, "\n");
    4456 }
    4457}
    4458
    4459/** outputs the right hand side section */
    4460static
    4462 SCIP* scip, /**< SCIP data structure */
    4463 FILE* file, /**< output file, or NULL if standard output should be used */
    4464 int nconss, /**< number of constraints */
    4465 const char** consnames, /**< constraint names */
    4466 SCIP_Real* rhss, /**< right hand side array */
    4467 unsigned int maxnamelen, /**< maximum name length */
    4468 SCIP_Real objoffset /**< objective offset */
    4469 )
    4470{
    4471 int recordcnt = 0;
    4472 int c;
    4473
    4474 assert( rhss != NULL );
    4475
    4476 SCIPinfoMessage(scip, file, "RHS\n");
    4477 SCIPdebugMsg(scip, "start printing RHS section\n");
    4478
    4479 /* take care of the linear constraints */
    4480 for( c = 0; c < nconss; ++c )
    4481 {
    4482 /* skip all constraints which have a right hand side of infinity */
    4483 if( SCIPisInfinity(scip, rhss[c]) )
    4484 continue;
    4485
    4486 assert(consnames[c] != NULL);
    4487
    4488 printEntry(scip, file, "RHS", consnames[c], rhss[c], &recordcnt, maxnamelen);
    4489 }
    4490
    4491 if( ! SCIPisZero(scip, objoffset) )
    4492 {
    4493 /* write objective offset (-1 because it is moved to the rhs) */
    4494 printEntry(scip, file, "RHS", "Obj", -objoffset, &recordcnt, maxnamelen);
    4495 }
    4496
    4497 if( recordcnt == 1 )
    4498 SCIPinfoMessage(scip, file, "\n");
    4499}
    4500
    4501/** outputs the range section */
    4502static
    4504 SCIP* scip, /**< SCIP data structure */
    4505 FILE* file, /**< output file, or NULL if standard output should be used */
    4506 SCIP_CONS** conss, /**< constraint array */
    4507 int nconss, /**< number of constraints */
    4508 const char** consnames, /**< constraint names */
    4509 SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
    4510 unsigned int maxnamelen /**< maximum name length */
    4511 )
    4512{
    4513 int c;
    4514 int recordcnt = 0;
    4515
    4516 SCIP_CONSHDLR* conshdlr;
    4517 const char* conshdlrname;
    4518
    4519 SCIP_CONS* cons;
    4520 SCIP_Real lhs;
    4521 SCIP_Real rhs;
    4522
    4523 SCIPinfoMessage(scip, file, "RANGES\n");
    4524 SCIPdebugMsg(scip, "start printing RANGES section\n");
    4525
    4526 for( c = 0; c < nconss; ++c )
    4527 {
    4528 cons = conss[c];
    4529 assert( cons != NULL);
    4530
    4531 /* in case the transformed problems is written only constraint are posted which are enabled in the current node;
    4532 * the conss array should only contain relevant constraints
    4533 */
    4534 assert( !transformed || SCIPconsIsEnabled(cons) );
    4535
    4536 assert( consnames[c] != NULL );
    4537
    4538 conshdlr = SCIPconsGetHdlr(cons);
    4539 assert( conshdlr != NULL );
    4540
    4541 conshdlrname = SCIPconshdlrGetName(conshdlr);
    4542
    4543 if( strcmp(conshdlrname, "linear") == 0 )
    4544 {
    4545 lhs = SCIPgetLhsLinear(scip, cons);
    4546 rhs = SCIPgetRhsLinear(scip, cons);
    4547 }
    4548 else if( strcmp(conshdlrname, "varbound") == 0 )
    4549 {
    4550 lhs = SCIPgetLhsVarbound(scip, cons);
    4551 rhs = SCIPgetRhsVarbound(scip, cons);
    4552 }
    4553 else
    4554 continue;
    4555
    4556 if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && !SCIPisEQ(scip, rhs, lhs) )
    4557 {
    4558 assert( SCIPisGT(scip, rhs, lhs) );
    4559 printEntry(scip, file, "RANGE", consnames[c], rhs - lhs, &recordcnt, maxnamelen);
    4560 }
    4561 }
    4562 if(recordcnt == 1 )
    4563 SCIPinfoMessage(scip, file, "\n");
    4564}
    4565
    4566/** print bound section name */
    4567static
    4569 SCIP* scip, /**< SCIP data structure */
    4570 FILE* file /**< output file, or NULL if standard output should be used */
    4571 )
    4572{
    4573 SCIPinfoMessage(scip, file, "BOUNDS\n");
    4574 SCIPdebugMsg(scip, "start printing BOUNDS section\n");
    4575}
    4576
    4577/** output bound section */
    4578static
    4580 SCIP* scip, /**< SCIP data structure */
    4581 FILE* file, /**< output file, or NULL if standard output should be used */
    4582 SCIP_VAR** vars, /**< active variables */
    4583 int nvars, /**< number of active variables */
    4584 SCIP_VAR** aggvars, /**< needed aggregated variables */
    4585 int naggvars, /**< number of aggregated variables */
    4586 SCIP_VAR** fixvars, /**< all fixed variables (or NULL if nfixvars is 0) */
    4587 int nfixvars, /**< number of fixed variables */
    4588 SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
    4589 const char** varnames, /**< array with variable names */
    4590 SCIP_HASHTABLE* indicatorSlackHash, /**< hashtable containing slack variables from indicators (or NULL) */
    4591 unsigned int maxnamelen /**< maximum name length */
    4592 )
    4593{
    4594 int v;
    4595 SCIP_VAR* var;
    4596 SCIP_Real lb;
    4597 SCIP_Real ub;
    4598 SCIP_Bool sectionName;
    4599 const char* varname;
    4600 char valuestr[MPS_MAX_VALUELEN] = { '\0' };
    4601
    4602 assert(scip != NULL);
    4603 assert(vars != NULL);
    4604 assert(nfixvars == 0 || fixvars != NULL);
    4605
    4606 sectionName = FALSE;
    4607
    4608 /* output the active variables */
    4609 for( v = 0; v < nvars; ++v )
    4610 {
    4611 var = vars[v];
    4612 assert( var != NULL );
    4613
    4614 /* skip slack variables in output */
    4615 if( indicatorSlackHash != NULL && SCIPhashtableExists(indicatorSlackHash, var) )
    4616 continue;
    4617
    4618 /* get variable name */
    4619 varname = varnames[v];
    4620 assert(strncmp(varname, SCIPvarGetName(var), maxnamelen) == 0);
    4621
    4622 if( transformed )
    4623 {
    4624 /* in case the transformed is written only local bounds are posted
    4625 * which are valid in the current node */
    4626 lb = SCIPvarGetLbLocal(var);
    4627 ub = SCIPvarGetUbLocal(var);
    4628 }
    4629 else
    4630 {
    4631 lb = SCIPvarGetLbOriginal(var);
    4632 ub = SCIPvarGetUbOriginal(var);
    4633 }
    4634
    4635 /* take care of binary variables */
    4637 {
    4638 if( !sectionName )
    4639 {
    4641 sectionName = TRUE;
    4642 }
    4643
    4644 if( !SCIPisFeasZero(scip, lb) || !SCIPisFeasEQ(scip, ub, 1.0) )
    4645 {
    4646 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", lb);
    4647 printStart(scip, file, "LO", "Bound", (int) maxnamelen);
    4648 printRecord(scip, file, varname, valuestr, maxnamelen);
    4649 SCIPinfoMessage(scip, file, "\n");
    4650
    4651 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", ub);
    4652 printStart(scip, file, "UP", "Bound", (int) maxnamelen);
    4653 printRecord(scip, file, varname, valuestr, maxnamelen);
    4654 }
    4655 else
    4656 {
    4657 printStart(scip, file, "BV", "Bound", (int) maxnamelen);
    4658 printRecord(scip, file, varname, "", maxnamelen);
    4659 }
    4660 SCIPinfoMessage(scip, file, "\n");
    4661
    4662 continue;
    4663 }
    4664
    4665 /* take care of free variables */
    4666 if( SCIPisInfinity(scip, -lb) && SCIPisInfinity(scip, ub) )
    4667 {
    4668 if( !sectionName )
    4669 {
    4671 sectionName = TRUE;
    4672 }
    4673
    4674 /* variable is free */
    4675 printStart(scip, file, "FR", "Bound", (int) maxnamelen);
    4676 printRecord(scip, file, varname, "", maxnamelen);
    4677 SCIPinfoMessage(scip, file, "\n");
    4678 continue;
    4679 }
    4680
    4681 /* take care of fixed variables */
    4682 if( SCIPisEQ(scip, lb, ub) )
    4683 {
    4684 if( !sectionName )
    4685 {
    4687 sectionName = TRUE;
    4688 }
    4689
    4690 /* variable is fixed */
    4691 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", lb);
    4692 printStart(scip, file, "FX", "Bound", (int) maxnamelen);
    4693 printRecord(scip, file, varname, valuestr, maxnamelen);
    4694 SCIPinfoMessage(scip, file, "\n");
    4695 continue;
    4696 }
    4697
    4698 /* print lower bound */
    4699 if( SCIPisInfinity(scip, -lb) )
    4700 {
    4701 if( !sectionName )
    4702 {
    4704 sectionName = TRUE;
    4705 }
    4706
    4707 /* the free variables are processed above */
    4708 assert( !SCIPisInfinity(scip, ub) );
    4709 printStart(scip, file, "MI", "Bound", (int) maxnamelen);
    4710 printRecord(scip, file, varname, "", maxnamelen);
    4711 SCIPinfoMessage(scip, file, "\n");
    4712 }
    4713 else
    4714 {
    4715 if( SCIPisZero(scip, lb) )
    4716 {
    4717 lb = 0.0;
    4718 }
    4719 else
    4720 {
    4721 if( !sectionName )
    4722 {
    4724 sectionName = TRUE;
    4725 }
    4726
    4727 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", lb);
    4728 printStart(scip, file, "LO", "Bound", (int) maxnamelen);
    4729 printRecord(scip, file, varname, valuestr, maxnamelen);
    4730 SCIPinfoMessage(scip, file, "\n");
    4731 }
    4732 }
    4733
    4734 /* print upper bound, infinity has to be printed for integer (!) variables, because during
    4735 * reading an mps file no upper bound of an integer variable means that the upper bound will
    4736 * be set to 1 instead of +infinity (like it is for continuous variables) */
    4737 if( SCIPisInfinity(scip, ub) )
    4738 {
    4739 if( !sectionName )
    4740 {
    4742 sectionName = TRUE;
    4743 }
    4744
    4745 /* the free variables are processed above */
    4746 assert( !SCIPisInfinity(scip, -lb) );
    4747 printStart(scip, file, "PL", "Bound", (int) maxnamelen);
    4748 printRecord(scip, file, varname, "", maxnamelen);
    4749 SCIPinfoMessage(scip, file, "\n");
    4750 }
    4751 else
    4752 {
    4753 if( !sectionName )
    4754 {
    4756 sectionName = TRUE;
    4757 }
    4758
    4759 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", ub);
    4760 printStart(scip, file, "UP", "Bound", (int) maxnamelen);
    4761 printRecord(scip, file, varname, valuestr, maxnamelen);
    4762 SCIPinfoMessage(scip, file, "\n");
    4763 }
    4764 }
    4765
    4766 /* output aggregated variables as 'free', except if they are binary */
    4767 for( v = 0; v < naggvars; ++v )
    4768 {
    4769 if( !sectionName )
    4770 {
    4772 sectionName = TRUE;
    4773 }
    4774
    4775 var = aggvars[v];
    4776 assert( var != NULL );
    4777
    4778 /* get variable name */
    4779 varname = varnames[nvars + v];
    4780 assert(strncmp(varname, SCIPvarGetName(var), maxnamelen) == 0);
    4781
    4782 /* take care of binary variables */
    4784 {
    4785 printStart(scip, file, "BV", "Bound", (int) maxnamelen);
    4786 printRecord(scip, file, varname, "", maxnamelen);
    4787 SCIPinfoMessage(scip, file, "\n");
    4788 }
    4789 else
    4790 {
    4791 /* variable is free */
    4792 printStart(scip, file, "FR", "Bound", (int) maxnamelen);
    4793 printRecord(scip, file, varname, "", maxnamelen);
    4794 SCIPinfoMessage(scip, file, "\n");
    4795 }
    4796 }
    4797
    4798 /* output all fixed variables */
    4799 for( v = 0; v < nfixvars; ++v )
    4800 {
    4801 /* we should print the transformed problem, otherwise no fixed variable should exists */
    4802 assert(transformed);
    4803 assert(fixvars != NULL && fixvars[v] != NULL);
    4804
    4805 var = fixvars[v];
    4806
    4807 assert(var != NULL);
    4808 assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_FIXED);
    4809
    4810 /* get variable name */
    4811 varname = varnames[nvars + naggvars + v];
    4812 assert(strncmp(varname, SCIPvarGetName(var), maxnamelen) == 0);
    4813
    4814 /* only local bounds are posted which are valid in the current node */
    4815 lb = SCIPvarGetLbLocal(var);
    4816 ub = SCIPvarGetUbLocal(var);
    4817 assert(SCIPisEQ(scip, lb, ub));
    4818
    4819 if( !sectionName )
    4820 {
    4822 sectionName = TRUE;
    4823 }
    4824
    4825 /* print fixed variable */
    4826 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", lb);
    4827 printStart(scip, file, "FX", "Bound", (int) maxnamelen);
    4828 printRecord(scip, file, varname, valuestr, maxnamelen);
    4829 SCIPinfoMessage(scip, file, "\n");
    4830 }
    4831}
    4832
    4833
    4834/*
    4835 * Callback methods of reader
    4836 */
    4837
    4838/** copy method for reader plugins (called when SCIP copies plugins) */
    4839/**! [SnippetReaderCopyMps] */
    4840static
    4842{ /*lint --e{715}*/
    4843 assert(scip != NULL);
    4844 assert(reader != NULL);
    4845
    4847
    4848 /* call inclusion method of reader */
    4850
    4851 return SCIP_OKAY;
    4852}
    4853/**! [SnippetReaderCopyMps] */
    4854
    4855/** destructor of reader to free user data (called when SCIP is exiting) */
    4856/**! [SnippetReaderFreeMps] */
    4857static
    4859{
    4860 SCIP_READERDATA* readerdata;
    4861
    4863
    4864 readerdata = SCIPreaderGetData(reader);
    4865 assert(readerdata != NULL);
    4866 SCIPfreeBlockMemory(scip, &readerdata);
    4867
    4868 return SCIP_OKAY;
    4869}
    4870/**! [SnippetReaderFreeMps] */
    4871
    4872/** problem reading method of reader */
    4873static
    4875{ /*lint --e{715}*/
    4876 assert(reader != NULL);
    4877
    4879
    4880 SCIP_CALL( SCIPreadMps(scip, reader, filename, result, NULL, NULL, NULL, NULL, NULL, NULL) );
    4881
    4882 return SCIP_OKAY;
    4883}
    4884
    4885
    4886/** problem writing method of reader */
    4887static
    4889{ /*lint --e{715}*/
    4890 assert(reader != NULL);
    4891
    4893
    4894 if( SCIPisExact(scip) )
    4895 {
    4896 SCIPerrorMessage("MPS reader cannot yet write problems in exact solving mode\n");
    4897 return SCIP_WRITEERROR;
    4898 }
    4899
    4900 SCIP_CALL( SCIPwriteMps(scip, reader, file, name, transformed, objsense, objoffset, objscale, objoffsetexact, objscaleexact,
    4901 vars, nvars, nbinvars, nintvars, nimplvars, ncontvars, fixedvars, nfixedvars, conss, nconss, result) );
    4902
    4903 return SCIP_OKAY;
    4904}
    4905
    4906
    4907/*
    4908 * mps file reader specific interface methods
    4909 */
    4910
    4911/** includes the mps file reader in SCIP */
    4913 SCIP* scip /**< SCIP data structure */
    4914 )
    4915{
    4916 SCIP_READERDATA* readerdata;
    4917 SCIP_READER* reader;
    4918
    4919 /* create reader data */
    4920 SCIP_CALL( SCIPallocBlockMemory(scip, &readerdata) );
    4921
    4922 /* include reader */
    4924
    4925 /* reader is safe to use in exact solving mode, but exact writing still needs to be implemented */
    4926 SCIPreaderMarkExact(reader);
    4927
    4928 /* set non fundamental callbacks via setter functions */
    4929 SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopyMps) );
    4930 SCIP_CALL( SCIPsetReaderFree(scip, reader, readerFreeMps) );
    4931 SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadMps) );
    4932 SCIP_CALL( SCIPsetReaderWrite(scip, reader, readerWriteMps) );
    4933
    4934 /* add lp-reader parameters */
    4936 "reading/" READER_NAME "/linearize-and-constraints",
    4937 "should possible \"and\" constraint be linearized when writing the mps file?",
    4938 &readerdata->linearizeands, TRUE, DEFAULT_LINEARIZE_ANDS, NULL, NULL) );
    4940 "reading/" READER_NAME "/aggrlinearization-ands",
    4941 "should an aggregated linearization for and constraints be used?",
    4942 &readerdata->aggrlinearizationands, TRUE, DEFAULT_AGGRLINEARIZATION_ANDS, NULL, NULL) );
    4943
    4944 return SCIP_OKAY;
    4945}
    4946
    4947
    4948/** reads problem from file */
    4950 SCIP* scip, /**< SCIP data structure */
    4951 SCIP_READER* reader, /**< the file reader itself */
    4952 const char* filename, /**< full path and name of file to read, or NULL if stdin should be used */
    4953 SCIP_RESULT* result, /**< pointer to store the result of the file reading call */
    4954 const char*** varnames, /**< storage for the variable names, or NULL */
    4955 const char*** consnames, /**< storage for the constraint names, or NULL */
    4956 int* varnamessize, /**< the size of the variable names storage, or NULL */
    4957 int* consnamessize, /**< the size of the constraint names storage, or NULL */
    4958 int* nvarnames, /**< the number of stored variable names, or NULL */
    4959 int* nconsnames /**< the number of stored constraint names, or NULL */
    4960 )
    4961{
    4962 SCIP_RETCODE retcode;
    4963
    4964 assert(reader != NULL);
    4965 assert(scip != NULL);
    4966 assert(result != NULL);
    4967
    4968 if( !SCIPisExact(scip) )
    4969 retcode = readMps(scip, filename, varnames, consnames, varnamessize, consnamessize, nvarnames, nconsnames);
    4970 else
    4971 retcode = readMpsExact(scip, filename, varnames, consnames, varnamessize, consnamessize, nvarnames, nconsnames);
    4972
    4973 if( retcode == SCIP_PLUGINNOTFOUND )
    4974 retcode = SCIP_READERROR;
    4975
    4976 if( retcode == SCIP_NOFILE || retcode == SCIP_READERROR )
    4977 return retcode;
    4978
    4979 SCIP_CALL( retcode );
    4980
    4981 *result = SCIP_SUCCESS;
    4982
    4983 return SCIP_OKAY;
    4984}
    4985
    4986/** writes problem to file */
    4988 SCIP* scip, /**< SCIP data structure */
    4989 SCIP_READER* reader, /**< the file reader itself */
    4990 FILE* file, /**< output file, or NULL if standard output should be used */
    4991 const char* name, /**< problem name */
    4992 SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
    4993 SCIP_OBJSENSE objsense, /**< objective sense */
    4994 SCIP_Real objoffset, /**< objective offset from bound shifting and fixing */
    4995 SCIP_Real objscale, /**< scalar applied to objective function; external objective value is
    4996 * extobj = objsense * objscale * (intobj + objoffset) */
    4997 SCIP_RATIONAL* objoffsetexact, /**< exact objective offset from bound shifting and fixing */
    4998 SCIP_RATIONAL* objscaleexact, /**< exact scalar applied to objective function; external objective value is
    4999 * extobjexact = objsense * objscaleexact * (intobjexact + objoffsetexact) */
    5000 SCIP_VAR** vars, /**< array with active variables ordered binary, integer, implicit, continuous */
    5001 int nvars, /**< number of active variables in the problem */
    5002 int nbinvars, /**< number of binary variables */
    5003 int nintvars, /**< number of general integer variables */
    5004 int nimplvars, /**< number of implicit integer variables */
    5005 int ncontvars, /**< number of continuous variables */
    5006 SCIP_VAR** fixedvars, /**< array with fixed and aggregated variables */
    5007 int nfixedvars, /**< number of fixed and aggregated variables in the problem */
    5008 SCIP_CONS** conss, /**< array with constraints of the problem */
    5009 int nconss, /**< number of constraints in the problem */
    5010 SCIP_RESULT* result /**< pointer to store the result of the file writing call */
    5011 )
    5012{
    5013 SCIP_READERDATA* readerdata;
    5014 int naddrows;
    5015 int faulty = 0;
    5016 int c;
    5017 int v;
    5018 int k;
    5019 char* namestr;
    5020
    5021 SCIP_CONS* cons = NULL;
    5022 const char* consname;
    5023 const char** consnames;
    5024
    5025 SCIP_CONSHDLR* conshdlr;
    5026 const char* conshdlrname;
    5027
    5028 SCIP_Real lhs;
    5029 SCIP_Real rhs;
    5030 SCIP_Real* rhss;
    5031 SCIP_Real value;
    5032
    5033 SCIP_VAR* var = NULL;
    5034 const char* varname;
    5035 const char** varnames;
    5036
    5037 char valuestr[MPS_MAX_VALUELEN] = { '\0' };
    5038
    5039 SCIP_CONS** consIndicator;
    5040 SCIP_CONS** consSOS1;
    5041 SCIP_CONS** consSOS2;
    5042 SCIP_CONS** consQuadratic;
    5043 SCIP_EXPR** exprQuadratic; /* expressions to quadratic constraints */
    5044 int nConsIndicator;
    5045 int nConsSOS1;
    5046 int nConsSOS2;
    5047 int nConsQuadratic;
    5048
    5049 SCIP_HASHMAP* varnameHashmap; /* hash map from SCIP_VAR* to variable name */
    5050 SPARSEMATRIX* matrix;
    5051
    5052 SCIP_VAR** aggvars;
    5053 int naggvars = 0;
    5054 int saggvars;
    5055 SCIP_HASHTABLE* varFixedHash;
    5056 SCIP_HASHTABLE* indicatorSlackHash;
    5057
    5058 SCIP_VAR** fixvars = NULL;
    5059 int nfixvars = 0;
    5060
    5061 SCIP_VAR** consvars;
    5062 int nconsvars;
    5063 SCIP_Real* vals;
    5064 SCIP_Longint* weights;
    5065
    5066 SCIP_Bool needRANGES;
    5067 unsigned int maxnamelen;
    5068 int implintlevel;
    5069
    5070 SCIP_Bool error;
    5071
    5072 assert(reader != NULL);
    5073 assert(scip != NULL);
    5074 assert(result != NULL);
    5075
    5077
    5078 /* get implied integral level for writeVarIsIntegral() and printColumnSection() */
    5079 SCIP_CALL( SCIPgetIntParam(scip, "write/implintlevel", &implintlevel) );
    5080
    5081 /**@todo write exact offset */
    5082 if( objoffsetexact != NULL )
    5083 {
    5084 assert(SCIPisExact(scip));
    5085 objoffset = SCIPrationalGetReal(objoffsetexact);
    5086 }
    5087
    5088 /**@todo write exact scale */
    5089 if( objscaleexact != NULL )
    5090 {
    5091 assert(SCIPisExact(scip));
    5092 objscale = SCIPrationalGetReal(objscaleexact);
    5093 }
    5094
    5095 needRANGES = FALSE;
    5096 maxnamelen = 0;
    5097 nConsSOS1 = 0;
    5098 nConsSOS2 = 0;
    5099 nConsQuadratic = 0;
    5100 nConsIndicator = 0;
    5101
    5102 /* check if the constraint names are too long and build the constraint names */
    5103 SCIP_CALL( checkConsnames(scip, conss, nconss, transformed, &maxnamelen, &consnames, &error) );
    5104 if( error )
    5105 {
    5106 /* call writing with generic names */
    5107 if( transformed )
    5108 {
    5109 SCIPwarningMessage(scip, "write transformed problem with generic variable and constraint names\n");
    5110 SCIP_CALL( SCIPprintTransProblem(scip, file, "mps", TRUE) );
    5111 }
    5112 else
    5113 {
    5114 SCIPwarningMessage(scip, "write original problem with generic variable and constraint names\n");
    5115 SCIP_CALL( SCIPprintOrigProblem(scip, file, "mps", TRUE) );
    5116 }
    5117 *result = SCIP_SUCCESS;
    5118
    5119 return SCIP_OKAY;
    5120 }
    5121
    5122 /* check if the variable names are not too long and build the "variable" -> "variable name" hash map */
    5123 SCIP_CALL( checkVarnames(scip, vars, nvars, &maxnamelen, &varnames, &varnameHashmap) );
    5124
    5125 /* collect SOS, quadratic, and indicator constraints in array for later output */
    5126 SCIP_CALL( SCIPallocBufferArray(scip, &consSOS1, nconss) );
    5127 SCIP_CALL( SCIPallocBufferArray(scip, &consSOS2, nconss) );
    5128 SCIP_CALL( SCIPallocBufferArray(scip, &consQuadratic, nconss) );
    5129 SCIP_CALL( SCIPallocBufferArray(scip, &exprQuadratic, nconss) );
    5130 SCIP_CALL( SCIPallocBufferArray(scip, &consIndicator, nconss) );
    5131
    5132 /* nfixedvars counts all variables with status SCIP_VARSTATUS_FIXED, SCIP_VARSTATUS_AGGREGATED, SCIP_VARSTATUS_MULTAGGR, but not SCIP_VARSTATUS_NEGATED */
    5133 saggvars = nfixedvars;
    5134 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &aggvars, saggvars) );
    5135
    5136 /* create hashtable for storing aggregated variables */
    5137 if( nfixedvars > 0 )
    5138 {
    5139 SCIP_CALL( SCIPhashtableCreate(&varFixedHash, SCIPblkmem(scip), nfixedvars, hashGetKeyVar, hashKeyEqVar, hashKeyValVar, NULL) );
    5140 }
    5141 else
    5142 varFixedHash = NULL;
    5143
    5144 if( nvars > 0 )
    5145 {
    5146 SCIP_CALL( SCIPhashtableCreate(&indicatorSlackHash, SCIPblkmem(scip), nvars, hashGetKeyVar, hashKeyEqVar, hashKeyValVar, NULL) );
    5147 }
    5148 else
    5149 indicatorSlackHash = NULL;
    5150
    5151 /* initialize sparse matrix */
    5152 SCIP_CALL( initializeMatrix(scip, &matrix, (nvars * 2 + nfixedvars)) );
    5153 assert( matrix->sentries >= nvars );
    5154
    5155 readerdata = SCIPreaderGetData(reader);
    5156 assert(readerdata != NULL);
    5157
    5158 naddrows = 0;
    5159
    5160 /* determine and-constraints and printing format to resize necessary arrays */
    5161 if( readerdata->linearizeands )
    5162 {
    5163 SCIP_CONSHDLR* andconshdlr = SCIPfindConshdlr(scip, "and");
    5164
    5165 if( andconshdlr != NULL )
    5166 {
    5167 /* need to check for and-constraints, note that in the original problem you cannot get the number of
    5168 * and-constraints by one call */
    5169 for( c = nconss - 1; c >= 0; --c )
    5170 {
    5171 conshdlr = SCIPconsGetHdlr(conss[c]);
    5172 assert(conshdlr != NULL);
    5173
    5174 conshdlrname = SCIPconshdlrGetName(conshdlr);
    5175
    5176 if( strcmp(conshdlrname, "and") == 0 )
    5177 {
    5178 if( readerdata->aggrlinearizationands )
    5179 ++naddrows;
    5180 else
    5181 naddrows += SCIPgetNVarsAnd(scip, conss[c]);
    5182 }
    5183 }
    5184 assert(naddrows >= 0);
    5185
    5186 if( naddrows > 0 )
    5187 {
    5188 /* resize consnames vector */
    5189 SCIP_CALL( SCIPreallocBufferArray(scip, &consnames, nconss + naddrows) );
    5190 }
    5191 }
    5192 }
    5193
    5194 /* initialize rhs vector */
    5195 SCIP_CALL( SCIPallocBufferArray(scip, &rhss, nconss + naddrows) );
    5196
    5197 /* print statistics as comment to file stream */
    5198 SCIPinfoMessage(scip, file, "* SCIP STATISTICS\n");
    5199 SCIPinfoMessage(scip, file, "* Problem name : %s\n", name);
    5200 SCIPinfoMessage(scip, file, "* Variables : %d (%d binary, %d integer, %d implicit integer, %d continuous)\n",
    5201 nvars, nbinvars, nintvars, nimplvars, ncontvars);
    5202 SCIPinfoMessage(scip, file, "* Constraints : %d\n", nconss);
    5203
    5204 /* print NAME of the problem */
    5205 SCIPinfoMessage(scip, file, "%-14s%s\n", "NAME", name);
    5206
    5207 /* print OBJSENSE of the problem */
    5208 SCIPinfoMessage(scip, file, "OBJSENSE\n");
    5209 SCIPinfoMessage(scip, file, "%s\n", objsense == SCIP_OBJSENSE_MAXIMIZE ? " MAX" : " MIN");
    5210
    5211 /* start ROWS section */
    5212 SCIPinfoMessage(scip, file, "ROWS\n");
    5213
    5214 /* print row type for the objective function */
    5215 printStart(scip, file, "N", "Obj", -1);
    5216 SCIPinfoMessage(scip, file, "\n");
    5217
    5218 /* first fill the matrix with the objective coefficients */
    5219 for( v = 0; v < nvars; ++v )
    5220 {
    5221 /* take care of the objective entry */
    5222 var = vars[v];
    5223 value = SCIPvarGetObj(var);
    5224
    5225 /* @todo: only add entry for empty column */
    5226 /* we also want to add integer variables to the columns section, even if the objective value is 0, because it
    5227 * might happen that they only exist in non-linear constraints, which leads to no other line in the column section
    5228 * and therefore do not mark the variable as an integer
    5229 */
    5230 if( !SCIPisZero(scip, value) || writeVarIsIntegral(var, implintlevel)
    5233 {
    5234 assert( matrix->nentries < matrix->sentries );
    5235
    5236 matrix->values[matrix->nentries] = objscale * value;
    5237 matrix->columns[matrix->nentries] = var;
    5238 matrix->rows[matrix->nentries] = "Obj";
    5239 matrix->nentries++;
    5240 }
    5241 }
    5242
    5243 /* loop over all constraints */
    5244 k = nconss;
    5245 for( c = 0; c < nconss; ++c )
    5246 {
    5247 cons = conss[c];
    5248 assert( cons != NULL);
    5249
    5250 /* in case the transformed problems is written only constraint are posted which are enabled in the current node;
    5251 * the conss array should only contain relevant constraints
    5252 */
    5253 assert( !transformed || SCIPconsIsEnabled(cons) );
    5254
    5255 conshdlr = SCIPconsGetHdlr(cons);
    5256 assert( conshdlr != NULL );
    5257
    5258 conshdlrname = SCIPconshdlrGetName(conshdlr);
    5259
    5260 /* construct constraint name */
    5261 consname = consnames[c];
    5262
    5263 /* init rhs value to infinity (would then ignored) */
    5264 rhss[c] = SCIPinfinity(scip);
    5265
    5266 if( strcmp(conshdlrname, "linear") == 0 )
    5267 {
    5268 lhs = SCIPgetLhsLinear(scip, cons);
    5269 rhs = SCIPgetRhsLinear(scip, cons);
    5270
    5271 /* there is nothing to do if the left hand side is minus infinity and the right side is infinity */
    5272 if( !SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs) )
    5273 {
    5274 if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && !SCIPisEQ(scip, lhs, rhs) )
    5275 needRANGES = TRUE;
    5276
    5277 /* print row entry */
    5278 printRowType(scip, file, lhs, rhs, consname);
    5279
    5280 if( SCIPisInfinity(scip, rhs) )
    5281 rhss[c] = lhs;
    5282 else
    5283 rhss[c] = rhs;
    5284
    5285 assert( !SCIPisInfinity(scip, rhss[c]) );
    5286
    5287 /* compute column entries */
    5289 SCIPgetNVarsLinear(scip, cons), transformed, matrix, &rhss[c]) );
    5290 }
    5291 }
    5292 else if( strcmp(conshdlrname, "setppc") == 0 )
    5293 {
    5294 /* print row entry */
    5295 switch( SCIPgetTypeSetppc(scip, cons) )
    5296 {
    5298 printRowType(scip, file, 1.0, 1.0, consname);
    5299 break;
    5301 printRowType(scip, file, -SCIPinfinity(scip), 1.0, consname);
    5302 break;
    5305 break;
    5306 }
    5307
    5308 rhss[c] = 1.0;
    5309
    5310 /* compute column entries */
    5311 SCIP_CALL( getLinearCoeffs(scip, consname, SCIPgetVarsSetppc(scip, cons), NULL, SCIPgetNVarsSetppc(scip, cons), transformed, matrix, &rhss[c]) );
    5312 }
    5313 else if( strcmp(conshdlrname, "logicor") == 0 )
    5314 {
    5315 /* print row entry */
    5317
    5318 rhss[c] = 1.0;
    5319
    5320 /* compute column entries */
    5321 SCIP_CALL( getLinearCoeffs(scip, consname, SCIPgetVarsLogicor(scip, cons), NULL, SCIPgetNVarsLogicor(scip, cons), transformed, matrix, &rhss[c]) );
    5322 }
    5323 else if( strcmp(conshdlrname, "knapsack") == 0 )
    5324 {
    5325 int i;
    5326
    5327 /* print row entry */
    5329
    5330 nconsvars = SCIPgetNVarsKnapsack(scip, cons);
    5331 weights = SCIPgetWeightsKnapsack(scip, cons);
    5332
    5333 /* copy Longint array to SCIP_Real array */
    5334 SCIP_CALL( SCIPallocBufferArray(scip, &vals, nconsvars ) );
    5335 for( i = 0; i < nconsvars; ++i )
    5336 vals[i] = (SCIP_Real)weights[i];
    5337
    5338 rhss[c] = (SCIP_Real) SCIPgetCapacityKnapsack(scip, cons);
    5339
    5340 /* compute column entries */
    5341 SCIP_CALL( getLinearCoeffs(scip, consname, SCIPgetVarsKnapsack(scip, cons), vals, nconsvars, transformed, matrix, &rhss[c]) );
    5342
    5343 SCIPfreeBufferArray(scip, &vals);
    5344 }
    5345 else if( strcmp(conshdlrname, "varbound") == 0 )
    5346 {
    5347 lhs = SCIPgetLhsVarbound(scip, cons);
    5348 rhs = SCIPgetRhsVarbound(scip, cons);
    5349
    5350 /* there is nothing to do if the left hand side is minus infinity and the right side is infinity */
    5351 if( !SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs) )
    5352 {
    5353 if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && !SCIPisEQ(scip, lhs, rhs) )
    5354 needRANGES = TRUE;
    5355
    5356 /* print row entry */
    5357 printRowType(scip, file, lhs, rhs, consname);
    5358
    5359 /* allocate memory */
    5360 SCIP_CALL( SCIPallocBufferArray(scip, &consvars, 2) );
    5361 SCIP_CALL( SCIPallocBufferArray(scip, &vals, 2) );
    5362
    5363 consvars[0] = SCIPgetVarVarbound(scip, cons);
    5364 consvars[1] = SCIPgetVbdvarVarbound(scip, cons);
    5365
    5366 vals[0] = 1.0;
    5367 vals[1] = SCIPgetVbdcoefVarbound(scip, cons);
    5368
    5369 if( SCIPisInfinity(scip, rhs) )
    5370 rhss[c] = lhs;
    5371 else
    5372 rhss[c] = rhs;
    5373
    5374 assert( !SCIPisInfinity(scip, rhss[c]) );
    5375
    5376 /* compute column entries */
    5377 SCIP_CALL( getLinearCoeffs(scip, consname, consvars, vals, 2, transformed, matrix, &rhss[c]) );
    5378
    5379 SCIPfreeBufferArray(scip, &vals);
    5380 SCIPfreeBufferArray(scip, &consvars);
    5381 }
    5382 }
    5383 else if( strcmp(conshdlrname, "indicator") == 0 )
    5384 {
    5385 SCIP_VAR* slackvar;
    5386 SCIP_VAR* binvar;
    5387
    5388 /* store slack variable in hash */
    5389 slackvar = SCIPgetSlackVarIndicator(cons);
    5390 assert( slackvar != NULL );
    5391 assert( indicatorSlackHash != NULL );
    5392 assert( !SCIPhashtableExists(indicatorSlackHash, (void*) slackvar) );
    5393 SCIP_CALL( SCIPhashtableInsert(indicatorSlackHash, (void*) slackvar) );
    5394
    5395 /* if slackvariable is aggregated, we store it in the list of aggregated variables */
    5397 {
    5398 SCIP_CALL( collectAggregatedVars(scip, &slackvar, 1, &aggvars, &naggvars, &saggvars, varFixedHash) );
    5399 }
    5400
    5401 /* store aggregated variables */
    5402 binvar = SCIPgetBinaryVarIndicator(cons);
    5403 if( SCIPvarIsNegated(binvar) )
    5404 binvar = SCIPvarGetNegatedVar(binvar);
    5405 assert( binvar != NULL );
    5406 SCIP_CALL( collectAggregatedVars(scip, &binvar, 1, &aggvars, &naggvars, &saggvars, varFixedHash) );
    5407
    5408 /* indicator constraint do not have a right hand side; mark this with SCIPinfinity(scip) */
    5409 rhss[c] = SCIPinfinity(scip);
    5410
    5411 /* store constraint */
    5412 consIndicator[nConsIndicator++] = cons;
    5413 continue;
    5414 }
    5415 else if( strcmp(conshdlrname, "SOS1") == 0 )
    5416 {
    5417 /* store constraint */
    5418 consSOS1[nConsSOS1++] = cons;
    5419
    5420 /* check for aggregated variables in SOS1 constraints for later output
    5421 * of aggregations as linear constraints */
    5422 consvars = SCIPgetVarsSOS1(scip, cons);
    5423 nconsvars = SCIPgetNVarsSOS1(scip, cons);
    5424
    5425 /* SOS constraint do not have a right hand side; mark this with SCIPinfinity(scip) */
    5426 rhss[c] = SCIPinfinity(scip);
    5427
    5428 SCIP_CALL( collectAggregatedVars(scip, consvars, nconsvars, &aggvars, &naggvars, &saggvars, varFixedHash) );
    5429 }
    5430 else if( strcmp(conshdlrname, "SOS2") == 0 )
    5431 {
    5432 /* store constraint */
    5433 consSOS2[nConsSOS2++] = cons;
    5434
    5435 /* check for aggregated variables in SOS2 constraints for later output aggregations as linear constraints */
    5436 consvars = SCIPgetVarsSOS2(scip, cons);
    5437 nconsvars = SCIPgetNVarsSOS2(scip, cons);
    5438
    5439 /* SOS constraint do not have a right hand side; mark this with SCIPinfinity(scip) */
    5440 rhss[c] = SCIPinfinity(scip);
    5441
    5442 SCIP_CALL( collectAggregatedVars(scip, consvars, nconsvars, &aggvars, &naggvars, &saggvars, varFixedHash) );
    5443 }
    5444 else if( strcmp(conshdlrname, "nonlinear") == 0 )
    5445 {
    5446 SCIP_EXPR* expr;
    5447 SCIP_VAR** quadvars;
    5448 SCIP_Real* quadvarlincoefs;
    5449 SCIP_Real* lincoefs;
    5450 SCIP_Real constant;
    5451 SCIP_EXPR** linexprs;
    5452 SCIP_Bool isquadratic;
    5453 int nquadexprs;
    5454 int nlinexprs;
    5455 int j;
    5456
    5457 /* check if it is a quadratic constraint */
    5458 expr = SCIPgetExprNonlinear(cons);
    5459 SCIP_CALL( SCIPcheckExprQuadratic(scip, expr, &isquadratic) );
    5460 if( !isquadratic || !SCIPexprAreQuadraticExprsVariables(expr) )
    5461 {
    5462 SCIP_EXPR* exprcopy;
    5463 SCIP_Bool changed;
    5464 SCIP_Bool infeasible;
    5465
    5466 SCIP_CALL( SCIPduplicateExpr(scip, expr, &exprcopy, NULL, NULL, NULL, NULL) );
    5467 SCIP_CALL( SCIPsimplifyExpr(scip, exprcopy, &expr, &changed, &infeasible, NULL, NULL) );
    5468 SCIP_CALL( SCIPreleaseExpr(scip, &exprcopy) );
    5469 /* the corresponding releaseExpr is in the writing of the QCMATRIX sections at the end */
    5470 if( changed && !infeasible )
    5471 {
    5472 SCIP_CALL( SCIPcheckExprQuadratic(scip, expr, &isquadratic) );
    5473 isquadratic &= SCIPexprAreQuadraticExprsVariables(expr);
    5474 }
    5475 }
    5476
    5477 if( !isquadratic )
    5478 {
    5479 /* unknown constraint type; mark this with SCIPinfinity(scip) */
    5480 rhss[c] = SCIPinfinity(scip);
    5481
    5482 SCIPwarningMessage(scip, "nonlinear constraint <%s> not recognized as quadratic: cannot print as MPS\n", SCIPconsGetName(cons));
    5483 if( expr != SCIPgetExprNonlinear(cons) )
    5484 {
    5485 SCIP_CALL( SCIPreleaseExpr(scip, &expr) );
    5486 }
    5487 continue;
    5488 }
    5489
    5490 /* store constraint and corresponding expression (may be the simplified one) */
    5491 consQuadratic[nConsQuadratic] = cons;
    5492 exprQuadratic[nConsQuadratic] = expr;
    5493 ++nConsQuadratic;
    5494
    5495 /* collect linear coefficients of quadratic part */
    5496 SCIPexprGetQuadraticData(expr, &constant, &nlinexprs, &linexprs, &lincoefs, &nquadexprs, NULL, NULL,
    5497 NULL);
    5498
    5499 SCIP_CALL( SCIPallocBufferArray(scip, &quadvars, nquadexprs) );
    5500 SCIP_CALL( SCIPallocBufferArray(scip, &quadvarlincoefs, nquadexprs) );
    5501 for( j = 0; j < nquadexprs; ++j )
    5502 {
    5503 SCIP_EXPR* qexpr;
    5504
    5505 SCIPexprGetQuadraticQuadTerm(expr, j, &qexpr, &quadvarlincoefs[j], NULL, NULL, NULL, NULL);
    5506
    5507 assert(SCIPisExprVar(scip, qexpr));
    5508 quadvars[j] = SCIPgetVarExprVar(qexpr);
    5509 }
    5510
    5511 lhs = SCIPgetLhsNonlinear(cons);
    5512 rhs = SCIPgetRhsNonlinear(cons);
    5513
    5514 /* correct side by constant */
    5515 lhs -= SCIPisInfinity(scip, -lhs) ? 0.0 : constant;
    5516 rhs -= SCIPisInfinity(scip, rhs) ? 0.0 : constant;
    5517
    5518 /* there is nothing to do if the left hand side is minus infinity and the right side is infinity */
    5519 if( !SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs) )
    5520 {
    5521 SCIP_VAR** linvars;
    5522
    5523 if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && !SCIPisEQ(scip, lhs, rhs) )
    5524 needRANGES = TRUE;
    5525
    5526 /* print row entry */
    5527 printRowType(scip, file, lhs, rhs, consname);
    5528
    5529 if( SCIPisInfinity(scip, rhs) )
    5530 rhss[c] = lhs;
    5531 else
    5532 rhss[c] = rhs;
    5533
    5534 assert( !SCIPisInfinity(scip, rhss[c]) );
    5535
    5536 /* get linear vars */
    5537 SCIP_CALL( SCIPallocBufferArray(scip, &linvars, nlinexprs) );
    5538 for( j = 0; j < nlinexprs; ++j )
    5539 linvars[j] = SCIPgetVarExprVar(linexprs[j]);
    5540
    5541 /* compute column entries for linear part */
    5542 SCIP_CALL( getLinearCoeffs(scip, consname, linvars, lincoefs, nlinexprs, transformed, matrix, &rhss[c]) );
    5543
    5544 /* compute column entries for linear part in quadratic part */
    5545 SCIP_CALL( getLinearCoeffs(scip, consname, quadvars, quadvarlincoefs, nquadexprs, transformed, matrix,
    5546 &rhss[c]) );
    5547
    5548 SCIPfreeBufferArray(scip, &linvars);
    5549 }
    5550
    5551 /* check for aggregated variables in quadratic part of quadratic constraints for later output of
    5552 * aggregations as linear constraints */
    5553 consvars = quadvars;
    5554 nconsvars = nquadexprs;
    5555
    5556 SCIP_CALL( collectAggregatedVars(scip, consvars, nconsvars, &aggvars, &naggvars, &saggvars, varFixedHash) );
    5557
    5558 SCIPfreeBufferArray(scip, &quadvars);
    5559 SCIPfreeBufferArray(scip, &quadvarlincoefs);
    5560 }
    5561 else if( strcmp(conshdlrname, "and") == 0 )
    5562 {
    5563 if( readerdata->linearizeands )
    5564 {
    5565 SCIP_VAR** rowvars;
    5566 SCIP_VAR** operands;
    5567 SCIP_VAR* resultant;
    5568 SCIP_Real* rowvals;
    5569 char* rowname;
    5570 int nrowvars;
    5571 int l;
    5572 int n;
    5573
    5574 nrowvars = SCIPgetNVarsAnd(scip, cons);
    5575 operands = SCIPgetVarsAnd(scip, cons);
    5576 resultant = SCIPgetResultantAnd(scip, cons);
    5577
    5578 /* allocate buffer array */
    5579 SCIP_CALL( SCIPallocBufferArray(scip, &rowvars, nrowvars + 1) );
    5580 SCIP_CALL( SCIPallocBufferArray(scip, &rowvals, nrowvars + 1) );
    5581
    5582 /* get length of constraint name */
    5583 l = (int) strlen(consname);
    5584
    5585 /* the tight relaxtion, number of and-constraint operands rows */
    5586 if( !readerdata->aggrlinearizationands )
    5587 {
    5588 rowvars[0] = resultant;
    5589 rowvals[0] = 1.0;
    5590 rowvals[1] = -1.0;
    5591
    5592 /* compute maximal length for rowname */
    5593 /* coverity[negative_returns] */
    5594 n = (int) log10((double)nrowvars) + 1 + l;
    5595
    5596 /* assure maximal allowed value */
    5597 if( n >= MPS_MAX_NAMELEN )
    5598 n = MPS_MAX_NAMELEN - 1;
    5599
    5600 /* update maxnamelen */
    5601 maxnamelen = MAX(maxnamelen, (unsigned int) n);
    5602
    5603 /* print operator rows */
    5604 for( v = 0; v < nrowvars; ++v )
    5605 {
    5606 /* compute maximal length for rowname */
    5607 if( v == 0 )
    5608 n = 2;
    5609 else
    5610 n = (int) log10((double)v) + 2;
    5611 n += l;
    5612
    5613 /* assure maximal allowed value */
    5614 if( n >= MPS_MAX_NAMELEN )
    5615 {
    5616 n = MPS_MAX_NAMELEN - 1;
    5617 ++faulty;
    5618 }
    5619
    5620 /* need memory for additional row */
    5621 SCIP_CALL( SCIPallocBufferArray(scip, &rowname, n + 1) );
    5622
    5623 assert(k < nconss + naddrows);
    5624 consnames[k] = rowname;
    5625
    5626 (void) SCIPsnprintf(rowname, n + 1, "%s_%d", consname, v);
    5627 rowvars[1] = operands[v];
    5628
    5629 /* print row entry */
    5630 printRowType(scip, file, -SCIPinfinity(scip), 0.0, rowname);
    5631
    5632 rhss[k] = 0.0;
    5633
    5634 /* compute column entries */
    5635 SCIP_CALL( getLinearCoeffs(scip, rowname, rowvars, rowvals, 2, transformed, matrix, &rhss[k]) );
    5636 ++k;
    5637 }
    5638 }
    5639
    5640 /* prepare for next row */
    5641 for( v = nrowvars - 1; v >= 0; --v )
    5642 {
    5643 rowvars[v] = operands[v];
    5644 rowvals[v] = -1.0;
    5645 }
    5646
    5647 rowvars[nrowvars] = resultant;
    5648
    5649 /* the weak relaxtion, only one constraint */
    5650 if( readerdata->aggrlinearizationands )
    5651 {
    5652 /* compute maximal length for rowname */
    5653 n = l + 3;
    5654
    5655 /* assure maximal allowed value */
    5656 if( n >= MPS_MAX_NAMELEN )
    5657 {
    5658 n = MPS_MAX_NAMELEN - 1;
    5659 ++faulty;
    5660 }
    5661
    5662 /* update maxnamelen */
    5663 maxnamelen = MAX(maxnamelen, (unsigned int) n);
    5664
    5665 /* need memory for additional row */
    5666 SCIP_CALL( SCIPallocBufferArray(scip, &rowname, n + 1) );
    5667
    5668 assert(k < nconss + naddrows);
    5669 consnames[k] = rowname;
    5670
    5671 /* adjust rowname of constraint */
    5672 (void) SCIPsnprintf(rowname, n + 1, "%s_op", consname);
    5673
    5674 rowvals[nrowvars] = (SCIP_Real) nrowvars;
    5675
    5676 /* print row entry */
    5677 printRowType(scip, file, -SCIPinfinity(scip), 0.0, rowname);
    5678
    5679 rhss[k] = 0.0;
    5680
    5681 /* compute column entries */
    5682 SCIP_CALL( getLinearCoeffs(scip, rowname, rowvars, rowvals, nrowvars + 1, transformed, matrix, &rhss[k]) );
    5683
    5684 SCIPdebugMsg(scip, "%g, %g\n", rowvals[1], rhss[k]);
    5685 ++k;
    5686 }
    5687
    5688 rowvals[nrowvars] = 1.0;
    5689
    5690 /* print row entry */
    5691 printRowType(scip, file, -nrowvars + 1.0, SCIPinfinity(scip), consname);
    5692
    5693 rhss[c] = -nrowvars + 1.0;
    5694
    5695 /* compute column entries */
    5696 SCIP_CALL( getLinearCoeffs(scip, consname, rowvars, rowvals, nrowvars + 1, transformed, matrix, &rhss[c]) );
    5697
    5698 /* free buffer array */
    5699 SCIPfreeBufferArray(scip, &rowvals);
    5700 SCIPfreeBufferArray(scip, &rowvars);
    5701 }
    5702 else
    5703 {
    5704 /* and constraint printing not enabled; mark this with SCIPinfinity(scip) */
    5705 rhss[c] = SCIPinfinity(scip);
    5706
    5707 SCIPwarningMessage(scip, "change parameter \"reading/" READER_NAME "/linearize-and-constraints\" to TRUE to print and-constraints\n");
    5708 }
    5709 }
    5710 else
    5711 {
    5712 /* unknown constraint type; mark this with SCIPinfinity(scip) */
    5713 rhss[c] = SCIPinfinity(scip);
    5714
    5715 SCIPwarningMessage(scip, "constraint handler <%s> cannot print requested format\n", conshdlrname );
    5716 }
    5717 }
    5718
    5719 if( faulty > 0 )
    5720 {
    5721 SCIPwarningMessage(scip, "there are %d and-constraint-rownames which have to be cut down to %d characters; MPS file might be corrupted\n",
    5722 faulty, MPS_MAX_NAMELEN - 1);
    5723 }
    5724
    5725 /* free hash table */
    5726 if( varFixedHash != NULL )
    5727 SCIPhashtableFree(&varFixedHash);
    5728
    5729 if( indicatorSlackHash != NULL && nConsIndicator == 0 )
    5730 {
    5731 SCIPhashtableFree(&indicatorSlackHash);
    5732 assert( indicatorSlackHash == NULL );
    5733 }
    5734
    5735 if( naggvars > 0 )
    5736 {
    5737 /* construct variables name of the needed aggregated variables and the constraint names for the aggregation constraints */
    5738
    5739 /* realloc memory */
    5740 SCIP_CALL( SCIPreallocBufferArray(scip, &consnames, nconss + naddrows + naggvars) );
    5741 SCIP_CALL( SCIPreallocBufferArray(scip, &rhss, nconss + naddrows + naggvars) );
    5742 SCIP_CALL( SCIPreallocBufferArray(scip, &varnames, nvars + naggvars) );
    5743
    5744 for( c = 0; c < naggvars; ++c )
    5745 {
    5746 size_t l;
    5747
    5748 /* create variable name */
    5749 var = aggvars[c];
    5750
    5751 l = strlen(SCIPvarGetName(var));
    5752 if( l >= MPS_MAX_NAMELEN )
    5753 maxnamelen = MPS_MAX_NAMELEN - 1;
    5754 else
    5755 maxnamelen = MAX(maxnamelen, (unsigned int) l);
    5756
    5758 (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
    5759
    5760 /* insert variable with variable name into hash map */
    5761 varnames[nvars + c] = namestr;
    5762 assert( !SCIPhashmapExists(varnameHashmap, var) );
    5763 SCIP_CALL( SCIPhashmapInsert(varnameHashmap, var, (void*) namestr) );
    5764
    5765 /* output row type (it is an equation) */
    5766 SCIP_CALL( SCIPallocBufferArray(scip, &namestr, MPS_MAX_NAMELEN) ); /* note that namestr above is freed via varnames */
    5767 (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "aggr_%s", SCIPvarGetName(var));
    5768 printRowType(scip, file, 1.0, 1.0, namestr);
    5769
    5770 l = strlen(namestr);
    5771 maxnamelen = MAX(maxnamelen, (unsigned int) l);
    5772 consnames[nconss + naddrows + c] = namestr;
    5773 rhss[nconss + naddrows + c] = 0.0;
    5774
    5775 /* compute column entries */
    5776 SCIP_CALL( getLinearCoeffs(scip, namestr, &(aggvars[c]), NULL, 1, transformed, matrix, &rhss[nconss + naddrows + c]) );
    5777
    5778 /* add the aggregated variables to the sparse matrix */
    5780 matrix->values[matrix->nentries] = -1.0;
    5781 matrix->columns[matrix->nentries] = aggvars[c];
    5782 matrix->rows[matrix->nentries] = namestr;
    5783 matrix->nentries++;
    5784 }
    5785 }
    5786
    5787 /* collect also fixed variables, because they might not be removed from all constraints */
    5788 /* @todo only collect fixed variables in the non-linear constraint types, where they (could not be)/(were not) removed */
    5789 if( nfixedvars > 0 )
    5790 {
    5791 int startpos = nvars + naggvars;
    5792 /* construct variables name of fixed variables */
    5793
    5794 /* realloc memory */
    5795 SCIP_CALL( SCIPreallocBufferArray(scip, &varnames, startpos + nfixedvars) );
    5796
    5797 /* allocate memory for fixed variables */
    5798 SCIP_CALL( SCIPallocBufferArray(scip, &fixvars, nfixedvars) );
    5799
    5800 for( v = nfixedvars - 1; v >= 0; --v )
    5801 {
    5802 /* create variable name */
    5803 var = fixedvars[v];
    5804
    5806 {
    5807 size_t l;
    5808 l = strlen(SCIPvarGetName(var));
    5809 if( l >= MPS_MAX_NAMELEN )
    5810 maxnamelen = MPS_MAX_NAMELEN - 1;
    5811 else
    5812 maxnamelen = MAX(maxnamelen, (unsigned int) l);
    5813
    5815 (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
    5816
    5817 varnames[startpos + nfixvars] = namestr;
    5818 fixvars[nfixvars] = var;
    5819 ++nfixvars;
    5820
    5821 /* insert variable with variable name into hash map */
    5822 assert(!SCIPhashmapExists(varnameHashmap, var));
    5823 SCIP_CALL( SCIPhashmapInsert(varnameHashmap, var, (void*) namestr) );
    5824
    5825 /* add the fixed variables to the sparse matrix, needed for columns section */
    5827 matrix->values[matrix->nentries] = 0.0;
    5828 matrix->columns[matrix->nentries] = var;
    5829 matrix->rows[matrix->nentries] = "Obj";
    5830 matrix->nentries++;
    5831 }
    5832 }
    5833 }
    5834
    5835 /* output COLUMNS section */
    5836 printColumnSection(scip, file, matrix, varnameHashmap, indicatorSlackHash, maxnamelen, implintlevel);
    5837
    5838 /* output RHS section */
    5839 printRhsSection(scip, file, nconss + naddrows +naggvars, consnames, rhss, maxnamelen, objscale * objoffset);
    5840
    5841 /* output RANGES section */
    5842 if( needRANGES )
    5843 printRangeSection(scip, file, conss, nconss, consnames, transformed, maxnamelen);
    5844
    5845 /* output BOUNDS section */
    5846 printBoundSection(scip, file, vars, nvars, aggvars, naggvars, fixvars, nfixvars, transformed, varnames, indicatorSlackHash, maxnamelen);
    5847
    5848 if( nfixedvars > 0 )
    5849 {
    5850 SCIPfreeBufferArray(scip, &fixvars);
    5851 }
    5852
    5853 /* print SOS section */
    5854 if( nConsSOS1 > 0 || nConsSOS2 > 0 )
    5855 {
    5856 SCIP_Real* sosweights;
    5857
    5858 SCIPinfoMessage(scip, file, "SOS\n");
    5859 SCIPdebugMsg(scip, "start printing SOS section\n");
    5860
    5862
    5863 /* first output SOS1 constraints */
    5864 for( c = 0; c < nConsSOS1; ++c )
    5865 {
    5866 cons = consSOS1[c];
    5867 consvars = SCIPgetVarsSOS1(scip, cons);
    5868 nconsvars = SCIPgetNVarsSOS1(scip, cons);
    5869 sosweights = SCIPgetWeightsSOS1(scip, cons);
    5870 (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "%s", SCIPconsGetName(cons) );
    5871
    5872 printStart(scip, file, "S1", namestr, -1);
    5873 SCIPinfoMessage(scip, file, "\n");
    5874
    5875 for( v = 0; v < nconsvars; ++v )
    5876 {
    5877 /* get variable name */
    5878 assert ( SCIPhashmapExists(varnameHashmap, consvars[v]) );
    5879 varname = (const char*) SCIPhashmapGetImage(varnameHashmap, consvars[v]);
    5880
    5881 printStart(scip, file, "", varname, (int) maxnamelen);
    5882
    5883 if( sosweights != NULL )
    5884 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", sosweights[v]);
    5885 else
    5886 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25d ", v);
    5887
    5888 SCIPinfoMessage(scip, file, "%25s\n", valuestr);
    5889 }
    5890 }
    5891
    5892 /* next output SOS2 constraints */
    5893 for( c = 0; c < nConsSOS2; ++c )
    5894 {
    5895 cons = consSOS2[c];
    5896 consvars = SCIPgetVarsSOS2(scip, cons);
    5897 nconsvars = SCIPgetNVarsSOS2(scip, cons);
    5898 sosweights = SCIPgetWeightsSOS2(scip, cons);
    5899 (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "%s", SCIPconsGetName(cons) );
    5900
    5901 printStart(scip, file, "S2", namestr, -1);
    5902 SCIPinfoMessage(scip, file, "\n");
    5903
    5904 for( v = 0; v < nconsvars; ++v )
    5905 {
    5906 /* get variable name */
    5907 assert ( SCIPhashmapExists(varnameHashmap, consvars[v]) );
    5908 varname = (const char*) SCIPhashmapGetImage(varnameHashmap, consvars[v]);
    5909
    5910 printStart(scip, file, "", varname, (int) maxnamelen);
    5911
    5912 if( sosweights != NULL )
    5913 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", sosweights[v]);
    5914 else
    5915 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25d ", v);
    5916
    5917 SCIPinfoMessage(scip, file, "%25s\n", valuestr);
    5918 }
    5919 }
    5920 SCIPfreeBufferArray(scip, &namestr);
    5921 }
    5922
    5923 /* print QCMATRIX sections for quadratic constraints
    5924 * in difference to a quadratic term in the objective function, the quadratic part is not divided by 2 here
    5925 */
    5926 if( nConsQuadratic > 0 )
    5927 {
    5928 const char* varname2;
    5929 int nbilin;
    5930
    5931 SCIPdebugMsg(scip, "start printing QCMATRIX sections for quadratic constraints\n");
    5933
    5934 for( c = 0; c < nConsQuadratic; ++c )
    5935 {
    5936 SCIP_EXPR* expr;
    5937
    5938 cons = consQuadratic[c];
    5939 expr = exprQuadratic[c];
    5940
    5941 SCIPexprGetQuadraticData(expr, NULL, NULL, NULL, NULL, &nconsvars, &nbilin, NULL, NULL);
    5942
    5943 (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "%s", SCIPconsGetName(cons) );
    5944
    5945 SCIPinfoMessage(scip, file, "QCMATRIX %s\n", namestr);
    5946
    5947 /* print x^2 terms */
    5948 for( v = 0; v < nconsvars; ++v )
    5949 {
    5950 SCIP_EXPR* qexpr;
    5951 SCIP_VAR* qvar;
    5952 SCIP_Real sqrcoef;
    5953
    5954 SCIPexprGetQuadraticQuadTerm(expr, v, &qexpr, NULL, &sqrcoef, NULL, NULL, NULL);
    5955 if( sqrcoef == 0.0 )
    5956 continue;
    5957
    5958 assert(SCIPisExprVar(scip, qexpr));
    5959 qvar = SCIPgetVarExprVar(qexpr);
    5960
    5961 /* get variable name */
    5962 assert(SCIPhashmapExists(varnameHashmap, qvar));
    5963 varname = (const char*) SCIPhashmapGetImage(varnameHashmap, qvar);
    5964
    5965 /* get coefficient as string */
    5966 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", sqrcoef);
    5967
    5968 /* print "x x coeff" line */
    5969 printStart(scip, file, "", varname, (int) maxnamelen);
    5970 printRecord(scip, file, varname, valuestr, maxnamelen);
    5971 SCIPinfoMessage(scip, file, "\n");
    5972 }
    5973
    5974 /* print bilinear terms; CPLEX format expects a symmetric matrix with all coefficients specified,
    5975 * i.e., we have to split bilinear coefficients into two off diagonal elements */
    5976 for( v = 0; v < nbilin; ++v )
    5977 {
    5978 SCIP_EXPR* expr1;
    5979 SCIP_EXPR* expr2;
    5980 SCIP_VAR* var1;
    5981 SCIP_VAR* var2;
    5982 SCIP_Real coef;
    5983
    5984 SCIPexprGetQuadraticBilinTerm(expr, v, &expr1, &expr2, &coef, NULL, NULL);
    5985 assert(SCIPisExprVar(scip, expr1));
    5986 assert(SCIPisExprVar(scip, expr2));
    5987
    5988 if( coef == 0.0 )
    5989 continue;
    5990
    5991 var1 = SCIPgetVarExprVar(expr1);
    5992 var2 = SCIPgetVarExprVar(expr2);
    5993
    5994 /* get name of first variable */
    5995 assert ( SCIPhashmapExists(varnameHashmap, var1) );
    5996 varname = (const char*) SCIPhashmapGetImage(varnameHashmap, var1);
    5997
    5998 /* get name of second variable */
    5999 assert ( SCIPhashmapExists(varnameHashmap, var2) );
    6000 varname2 = (const char*) SCIPhashmapGetImage(varnameHashmap, var2);
    6001
    6002 /* get coefficient as string */
    6003 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", 0.5*coef);
    6004
    6005 /* print "x y coeff/2" line */
    6006 printStart(scip, file, "", varname, (int) maxnamelen);
    6007 printRecord(scip, file, varname2, valuestr, maxnamelen);
    6008 SCIPinfoMessage(scip, file, "\n");
    6009
    6010 /* print "y x coeff/2" line */
    6011 printStart(scip, file, "", varname2, (int) maxnamelen);
    6012 printRecord(scip, file, varname, valuestr, maxnamelen);
    6013 SCIPinfoMessage(scip, file, "\n");
    6014 }
    6015
    6016 if( expr != SCIPgetExprNonlinear(cons) )
    6017 {
    6018 SCIP_CALL( SCIPreleaseExpr(scip, &expr) );
    6019 }
    6020 }
    6021
    6022 SCIPfreeBufferArray(scip, &namestr);
    6023 }
    6024
    6025 /* print indicator section */
    6026 if( nConsIndicator > 0 )
    6027 {
    6029
    6030 SCIPinfoMessage(scip, file, "INDICATORS\n");
    6031 SCIPdebugMsg(scip, "start printing INDICATOR section\n");
    6032
    6033 /* output each indicator constraint */
    6034 for( c = 0; c < nConsIndicator; ++c )
    6035 {
    6036 SCIP_CONS* lincons;
    6037 SCIP_VAR* slackvar;
    6038 SCIP_VAR* binvar;
    6039
    6040 cons = consIndicator[c];
    6041 binvar = SCIPgetBinaryVarIndicator(cons);
    6042 lincons = SCIPgetLinearConsIndicator(cons);
    6043 slackvar = SCIPgetSlackVarIndicator(cons);
    6044
    6045 /* linvars always contains slack variable, thus nlinvars >= 1 */
    6046 if( SCIPgetNVarsLinear(scip, lincons) <= 1 || SCIPconsIsDeleted(lincons) )
    6047 continue;
    6048
    6049 /* create variable and value strings */
    6050 if( SCIPvarIsNegated(binvar) )
    6051 {
    6052 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25d", 0);
    6053 assert( SCIPvarGetNegatedVar(binvar) != NULL );
    6054 assert( SCIPhashmapExists(varnameHashmap, SCIPvarGetNegatedVar(binvar)) );
    6055 varname = (const char*) SCIPhashmapGetImage(varnameHashmap, SCIPvarGetNegatedVar(binvar));
    6056 }
    6057 else
    6058 {
    6059 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25d", 1);
    6060 assert ( SCIPhashmapExists(varnameHashmap, binvar) );
    6061 varname = (const char*) SCIPhashmapGetImage(varnameHashmap, binvar);
    6062 }
    6063
    6064 /* write records */
    6066 {
    6067 /* for aggregated variables output name of aggregating constraint */
    6068 (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "aggr_%s", SCIPvarGetName(slackvar));
    6069 printStart(scip, file, "IF", namestr, (int) maxnamelen);
    6070 printRecord(scip, file, varname, valuestr, maxnamelen);
    6071 SCIPinfoMessage(scip, file, "\n");
    6072 }
    6073 else
    6074 {
    6075 printStart(scip, file, "IF", SCIPconsGetName(lincons), (int) maxnamelen);
    6076 printRecord(scip, file, varname, valuestr, maxnamelen);
    6077 SCIPinfoMessage(scip, file, "\n");
    6078 }
    6079 }
    6080 SCIPfreeBufferArray(scip, &namestr);
    6081 }
    6082
    6083 /* free matrix data structure */
    6084 freeMatrix(scip, matrix);
    6085
    6086 /* free slackvar hashtable */
    6087 if( indicatorSlackHash != NULL )
    6088 SCIPhashtableFree(&indicatorSlackHash);
    6089
    6090 /* free variable hashmap */
    6091 SCIPhashmapFree(&varnameHashmap);
    6092
    6093 SCIPfreeBlockMemoryArray(scip, &aggvars, saggvars);
    6094 SCIPfreeBufferArray(scip, &rhss);
    6095
    6096 /* free buffer arrays for SOS1, SOS2, and quadratic */
    6097 SCIPfreeBufferArray(scip, &consIndicator);
    6098 SCIPfreeBufferArray(scip, &exprQuadratic);
    6099 SCIPfreeBufferArray(scip, &consQuadratic);
    6100 SCIPfreeBufferArray(scip, &consSOS2);
    6101 SCIPfreeBufferArray(scip, &consSOS1);
    6102
    6103 /* free variable and constraint name array */
    6104 for( v = nvars + naggvars + nfixvars - 1; v >= 0; --v )
    6105 SCIPfreeBufferArray(scip, &varnames[v]);
    6106 SCIPfreeBufferArray(scip, &varnames);
    6107
    6108 for( c = nconss + naddrows + naggvars - 1; c >= 0; --c )
    6109 SCIPfreeBufferArray(scip, &consnames[c]);
    6110 SCIPfreeBufferArray(scip, &consnames);
    6111
    6112 /* print end of data line */
    6113 SCIPinfoMessage(scip, file, "ENDATA");
    6114
    6115 *result = SCIP_SUCCESS;
    6116
    6117 return SCIP_OKAY;
    6118}
    static long * number
    Constraint handler for AND constraints, .
    constraint handler for bound disjunction constraints
    Constraint handler for linear constraints in their most general form, .
    constraint handler for indicator constraints
    Constraint handler for knapsack constraints of the form , x binary and .
    Constraint handler for linear constraints in their most general form, .
    Constraint handler for logicor constraints (equivalent to set covering, but algorithms are suited fo...
    constraint handler for nonlinear constraints specified by algebraic expressions
    Constraint handler for the set partitioning / packing / covering constraints .
    constraint handler for SOS type 1 constraints
    constraint handler for SOS type 2 constraints
    Constraint handler for variable bound constraints .
    #define NULL
    Definition: def.h:257
    #define SCIP_MAXSTRLEN
    Definition: def.h:278
    #define SCIP_Longint
    Definition: def.h:150
    #define SCIP_Bool
    Definition: def.h:100
    #define MIN(x, y)
    Definition: def.h:233
    #define SCIP_STRINGEQ(name, reference, retcode)
    Definition: def.h:454
    #define SCIP_Real
    Definition: def.h:165
    #define SCIP_HASHSIZE_NAMES
    Definition: def.h:289
    #define TRUE
    Definition: def.h:102
    #define FALSE
    Definition: def.h:103
    #define MAX(x, y)
    Definition: def.h:229
    #define SCIP_CALL_TERMINATE(retcode, x, TERM)
    Definition: def.h:385
    #define SCIPABORT()
    Definition: def.h:336
    #define REALABS(x)
    Definition: def.h:191
    #define SCIP_CALL(x)
    Definition: def.h:364
    SCIP_FILE * SCIPfopen(const char *path, const char *mode)
    Definition: fileio.c:153
    int SCIPfclose(SCIP_FILE *fp)
    Definition: fileio.c:232
    char * SCIPfgets(char *s, int size, SCIP_FILE *stream)
    Definition: fileio.c:200
    int SCIPgetNVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPchgLhsExactLinear(SCIP *scip, SCIP_CONS *cons, SCIP_RATIONAL *lhs)
    SCIP_Real SCIPgetVbdcoefVarbound(SCIP *scip, SCIP_CONS *cons)
    SCIP_RATIONAL * SCIPgetLhsExactLinear(SCIP *scip, SCIP_CONS *cons)
    int SCIPgetNVarsLogicor(SCIP *scip, SCIP_CONS *cons)
    SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_VAR ** SCIPgetVarsLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPchgRhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real rhs)
    SCIP_RATIONAL * SCIPgetRhsExactLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPchgRhsExactLinear(SCIP *scip, SCIP_CONS *cons, SCIP_RATIONAL *rhs)
    SCIP_RETCODE SCIPcreateConsExactLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_RATIONAL **vals, SCIP_RATIONAL *lhs, SCIP_RATIONAL *rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    SCIP_Real * SCIPgetWeightsSOS2(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_sos2.c:2791
    SCIP_VAR ** SCIPgetVarsSOS2(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_sos2.c:2771
    SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
    SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
    int SCIPgetNVarsLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_VAR * SCIPgetResultantAnd(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_and.c:5238
    SCIP_RETCODE SCIPaddVarSOS1(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real weight)
    Definition: cons_sos1.c:10746
    SCIP_RETCODE SCIPcreateConsBounddisjunction(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_BOUNDTYPE *boundtypes, SCIP_Real *bounds, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    SCIP_RETCODE SCIPcreateConsIndicator(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *binvar, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    int SCIPgetNVarsAnd(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_and.c:5199
    SCIP_Real * SCIPgetValsLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPcreateConsSOS1(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *weights, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    Definition: cons_sos1.c:10600
    SCIP_RETCODE SCIPaddCoefExactLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_RATIONAL *val)
    SCIP_VAR * SCIPgetVbdvarVarbound(SCIP *scip, SCIP_CONS *cons)
    int SCIPgetNVarsSetppc(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:9683
    int SCIPgetNVarsSOS2(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_sos2.c:2751
    SCIP_Real * SCIPgetWeightsSOS1(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_sos1.c:10849
    SCIP_VAR ** SCIPgetVarsSetppc(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:9701
    SCIP_EXPR * SCIPgetExprNonlinear(SCIP_CONS *cons)
    SCIP_Real SCIPgetRhsNonlinear(SCIP_CONS *cons)
    SCIP_VAR * SCIPgetBinaryVarIndicator(SCIP_CONS *cons)
    SCIP_VAR * SCIPgetVarVarbound(SCIP *scip, SCIP_CONS *cons)
    SCIP_Longint * SCIPgetWeightsKnapsack(SCIP *scip, SCIP_CONS *cons)
    SCIP_VAR * SCIPgetSlackVarIndicator(SCIP_CONS *cons)
    SCIP_Longint SCIPgetCapacityKnapsack(SCIP *scip, SCIP_CONS *cons)
    SCIP_Real SCIPgetLhsVarbound(SCIP *scip, SCIP_CONS *cons)
    SCIP_SETPPCTYPE SCIPgetTypeSetppc(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:9719
    SCIP_CONS * SCIPgetLinearConsIndicator(SCIP_CONS *cons)
    SCIP_RETCODE SCIPcreateConsSOS2(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *weights, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    Definition: cons_sos2.c:2597
    SCIP_RETCODE SCIPcreateConsLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    SCIP_VAR ** SCIPgetVarsSOS1(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_sos1.c:10829
    SCIP_VAR ** SCIPgetVarsLogicor(SCIP *scip, SCIP_CONS *cons)
    SCIP_Real SCIPgetRhsVarbound(SCIP *scip, SCIP_CONS *cons)
    SCIP_VAR ** SCIPgetVarsAnd(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_and.c:5218
    SCIP_VAR ** SCIPgetVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPcreateConsQuadraticNonlinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nlinvars, SCIP_VAR **linvars, SCIP_Real *lincoefs, int nquadterms, SCIP_VAR **quadvars1, SCIP_VAR **quadvars2, SCIP_Real *quadcoefs, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable)
    SCIP_RETCODE SCIPcreateConsIndicatorLinConsPure(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *binvar, SCIP_CONS *lincons, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    SCIP_RETCODE SCIPchgLhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real lhs)
    int SCIPgetNVarsSOS1(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_sos1.c:10809
    SCIP_Real SCIPgetLhsNonlinear(SCIP_CONS *cons)
    SCIP_RETCODE SCIPaddVarSOS2(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real weight)
    Definition: cons_sos2.c:2706
    @ SCIP_SETPPCTYPE_PARTITIONING
    Definition: cons_setppc.h:87
    @ SCIP_SETPPCTYPE_COVERING
    Definition: cons_setppc.h:89
    @ SCIP_SETPPCTYPE_PACKING
    Definition: cons_setppc.h:88
    SCIP_RETCODE SCIPwriteMps(SCIP *scip, SCIP_READER *reader, FILE *file, const char *name, SCIP_Bool transformed, SCIP_OBJSENSE objsense, SCIP_Real objoffset, SCIP_Real objscale, SCIP_RATIONAL *objoffsetexact, SCIP_RATIONAL *objscaleexact, SCIP_VAR **vars, int nvars, int nbinvars, int nintvars, int nimplvars, int ncontvars, SCIP_VAR **fixedvars, int nfixedvars, SCIP_CONS **conss, int nconss, SCIP_RESULT *result)
    Definition: reader_mps.c:4987
    SCIP_RETCODE SCIPreadMps(SCIP *scip, SCIP_READER *reader, const char *filename, SCIP_RESULT *result, const char ***varnames, const char ***consnames, int *varnamessize, int *consnamessize, int *nvarnames, int *nconsnames)
    Definition: reader_mps.c:4949
    SCIP_RETCODE SCIPincludeReaderMps(SCIP *scip)
    Definition: reader_mps.c:4912
    SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
    Definition: scip_prob.c:1907
    SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_prob.c:3274
    SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_prob.c:3420
    SCIP_RETCODE SCIPprintTransProblem(SCIP *scip, FILE *file, const char *extension, SCIP_Bool genericnames)
    Definition: scip_prob.c:696
    SCIP_RETCODE SCIPprintOrigProblem(SCIP *scip, FILE *file, const char *extension, SCIP_Bool genericnames)
    Definition: scip_prob.c:652
    SCIP_RETCODE SCIPsetObjsense(SCIP *scip, SCIP_OBJSENSE objsense)
    Definition: scip_prob.c:1417
    SCIP_RETCODE SCIPaddOrigObjoffset(SCIP *scip, SCIP_Real addval)
    Definition: scip_prob.c:1486
    SCIP_RETCODE SCIPcreateProb(SCIP *scip, const char *name, SCIP_DECL_PROBDELORIG((*probdelorig)), SCIP_DECL_PROBTRANS((*probtrans)), SCIP_DECL_PROBDELTRANS((*probdeltrans)), SCIP_DECL_PROBINITSOL((*probinitsol)), SCIP_DECL_PROBEXITSOL((*probexitsol)), SCIP_DECL_PROBCOPY((*probcopy)), SCIP_PROBDATA *probdata)
    Definition: scip_prob.c:119
    SCIP_VAR * SCIPfindVar(SCIP *scip, const char *name)
    Definition: scip_prob.c:3189
    SCIP_CONS * SCIPfindCons(SCIP *scip, const char *name)
    Definition: scip_prob.c:3525
    void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
    Definition: misc.c:3095
    void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
    Definition: misc.c:3284
    SCIP_RETCODE SCIPhashmapInsert(SCIP_HASHMAP *hashmap, void *origin, void *image)
    Definition: misc.c:3143
    SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
    Definition: misc.c:3061
    SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
    Definition: misc.c:3466
    void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
    Definition: misc.c:2348
    SCIP_Bool SCIPhashtableExists(SCIP_HASHTABLE *hashtable, void *element)
    Definition: misc.c:2647
    SCIP_RETCODE SCIPhashtableCreate(SCIP_HASHTABLE **hashtable, BMS_BLKMEM *blkmem, int tablesize, SCIP_DECL_HASHGETKEY((*hashgetkey)), SCIP_DECL_HASHKEYEQ((*hashkeyeq)), SCIP_DECL_HASHKEYVAL((*hashkeyval)), void *userptr)
    Definition: misc.c:2298
    void * SCIPhashtableRetrieve(SCIP_HASHTABLE *hashtable, void *key)
    Definition: misc.c:2596
    SCIP_RETCODE SCIPhashtableInsert(SCIP_HASHTABLE *hashtable, void *element)
    Definition: misc.c:2535
    void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:208
    void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:225
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
    Definition: scip_message.c:120
    SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
    Definition: scip_param.c:250
    SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:57
    SCIP_RETCODE SCIPgetIntParam(SCIP *scip, const char *name, int *value)
    Definition: scip_param.c:269
    const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4320
    SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
    Definition: scip_cons.c:940
    SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
    Definition: cons.c:8652
    SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
    Definition: cons.c:8413
    SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
    Definition: cons.c:8562
    SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
    Definition: cons.c:8592
    SCIP_Bool SCIPconsIsDeleted(SCIP_CONS *cons)
    Definition: cons.c:8522
    SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
    Definition: cons.c:8582
    SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
    Definition: cons.c:8612
    SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
    Definition: cons.c:8632
    SCIP_Bool SCIPconsIsEnabled(SCIP_CONS *cons)
    Definition: cons.c:8490
    const char * SCIPconsGetName(SCIP_CONS *cons)
    Definition: cons.c:8393
    SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
    Definition: cons.c:8642
    SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
    Definition: scip_cons.c:1173
    SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
    Definition: cons.c:8572
    SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
    Definition: cons.c:8662
    SCIP_Bool SCIPisExact(SCIP *scip)
    Definition: scip_exact.c:193
    void SCIPexprGetQuadraticBilinTerm(SCIP_EXPR *expr, int termidx, SCIP_EXPR **expr1, SCIP_EXPR **expr2, SCIP_Real *coef, int *pos2, SCIP_EXPR **prodexpr)
    Definition: expr.c:4226
    SCIP_Bool SCIPexprAreQuadraticExprsVariables(SCIP_EXPR *expr)
    Definition: expr.c:4262
    void SCIPexprGetQuadraticData(SCIP_EXPR *expr, SCIP_Real *constant, int *nlinexprs, SCIP_EXPR ***linexprs, SCIP_Real **lincoefs, int *nquadexprs, int *nbilinexprs, SCIP_Real **eigenvalues, SCIP_Real **eigenvectors)
    Definition: expr.c:4141
    SCIP_RETCODE SCIPreleaseExpr(SCIP *scip, SCIP_EXPR **expr)
    Definition: scip_expr.c:1443
    SCIP_Bool SCIPisExprVar(SCIP *scip, SCIP_EXPR *expr)
    Definition: scip_expr.c:1457
    SCIP_RETCODE SCIPcheckExprQuadratic(SCIP *scip, SCIP_EXPR *expr, SCIP_Bool *isquadratic)
    Definition: scip_expr.c:2402
    SCIP_VAR * SCIPgetVarExprVar(SCIP_EXPR *expr)
    Definition: expr_var.c:423
    void SCIPexprGetQuadraticQuadTerm(SCIP_EXPR *quadexpr, int termidx, SCIP_EXPR **expr, SCIP_Real *lincoef, SCIP_Real *sqrcoef, int *nadjbilin, int **adjbilin, SCIP_EXPR **sqrexpr)
    Definition: expr.c:4186
    SCIP_RETCODE SCIPduplicateExpr(SCIP *scip, SCIP_EXPR *expr, SCIP_EXPR **copyexpr, SCIP_DECL_EXPR_MAPEXPR((*mapexpr)), void *mapexprdata, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
    Definition: scip_expr.c:1307
    SCIP_RETCODE SCIPsimplifyExpr(SCIP *scip, SCIP_EXPR *rootexpr, SCIP_EXPR **simplified, SCIP_Bool *changed, SCIP_Bool *infeasible, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
    Definition: scip_expr.c:1798
    #define SCIPfreeBuffer(scip, ptr)
    Definition: scip_mem.h:134
    #define SCIPfreeBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:110
    BMS_BLKMEM * SCIPblkmem(SCIP *scip)
    Definition: scip_mem.c:57
    #define SCIPensureBlockMemoryArray(scip, ptr, arraysizeptr, minsize)
    Definition: scip_mem.h:107
    BMS_BUFMEM * SCIPbuffer(SCIP *scip)
    Definition: scip_mem.c:72
    int SCIPcalcMemGrowSize(SCIP *scip, int num)
    Definition: scip_mem.c:139
    #define SCIPallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:124
    #define SCIPreallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:128
    #define SCIPfreeBufferArray(scip, ptr)
    Definition: scip_mem.h:136
    #define SCIPduplicateBufferArray(scip, ptr, source, num)
    Definition: scip_mem.h:132
    #define SCIPallocBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:93
    #define SCIPallocBuffer(scip, ptr)
    Definition: scip_mem.h:122
    #define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
    Definition: scip_mem.h:99
    #define SCIPfreeBlockMemory(scip, ptr)
    Definition: scip_mem.h:108
    #define SCIPfreeBufferArrayNull(scip, ptr)
    Definition: scip_mem.h:137
    #define SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    #define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
    Definition: scip_mem.h:105
    void SCIPrationalSetInfinity(SCIP_RATIONAL *res)
    Definition: rational.cpp:619
    void SCIPrationalAdd(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:936
    SCIP_Real SCIPrationalGetReal(SCIP_RATIONAL *rational)
    Definition: rational.cpp:2084
    #define SCIPrationalDebugMessage
    Definition: rational.h:641
    void SCIPrationalAbs(SCIP_RATIONAL *res, SCIP_RATIONAL *op)
    Definition: rational.cpp:1311
    SCIP_Bool SCIPrationalIsLT(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
    Definition: rational.cpp:1504
    void SCIPrationalSetReal(SCIP_RATIONAL *res, SCIP_Real real)
    Definition: rational.cpp:604
    SCIP_Bool SCIPrationalIsGT(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
    Definition: rational.cpp:1475
    void SCIPrationalFreeBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
    Definition: rational.cpp:474
    void SCIPrationalDiff(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:984
    SCIP_RETCODE SCIPrationalCreateBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
    Definition: rational.cpp:124
    SCIP_Bool SCIPrationalIsZero(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1625
    void SCIPrationalSetString(SCIP_RATIONAL *res, const char *desc)
    Definition: rational.cpp:717
    SCIP_Bool SCIPrationalIsIntegral(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1692
    void SCIPrationalCanonicalize(SCIP_RATIONAL *rational)
    Definition: rational.cpp:539
    void SCIPrationalSetNegInfinity(SCIP_RATIONAL *res)
    Definition: rational.cpp:631
    SCIP_Bool SCIPrationalIsNegative(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1651
    SCIP_Bool SCIPrationalIsInfinity(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1661
    SCIP_Bool SCIPrationalIsNegInfinity(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1671
    SCIP_Bool SCIPrationalIsGTReal(SCIP_RATIONAL *rat, SCIP_Real real)
    Definition: rational.cpp:1547
    SCIP_Bool SCIPrationalIsEQ(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
    Definition: rational.cpp:1405
    SCIP_RETCODE SCIPincludeReaderBasic(SCIP *scip, SCIP_READER **readerptr, const char *name, const char *desc, const char *extension, SCIP_READERDATA *readerdata)
    Definition: scip_reader.c:109
    SCIP_RETCODE SCIPsetReaderCopy(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERCOPY((*readercopy)))
    Definition: scip_reader.c:147
    SCIP_READERDATA * SCIPreaderGetData(SCIP_READER *reader)
    Definition: reader.c:625
    SCIP_RETCODE SCIPsetReaderFree(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERFREE((*readerfree)))
    Definition: scip_reader.c:171
    const char * SCIPreaderGetName(SCIP_READER *reader)
    Definition: reader.c:700
    SCIP_RETCODE SCIPsetReaderRead(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERREAD((*readerread)))
    Definition: scip_reader.c:195
    void SCIPreaderMarkExact(SCIP_READER *reader)
    Definition: reader.c:690
    SCIP_RETCODE SCIPsetReaderWrite(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERWRITE((*readerwrite)))
    Definition: scip_reader.c:219
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisFeasNegative(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_RETCODE SCIPtightenVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
    Definition: scip_var.c:6401
    SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
    Definition: var.c:18365
    SCIP_RETCODE SCIPtightenVarUbExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *newbound, SCIP_Bool *infeasible, SCIP_Bool *tightened)
    Definition: scip_var.c:6768
    SCIP_VAR * SCIPvarGetNegatedVar(SCIP_VAR *var)
    Definition: var.c:23900
    SCIP_RETCODE SCIPchgVarUbExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *newbound)
    Definition: scip_var.c:5964
    SCIP_RETCODE SCIPchgVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
    Definition: scip_var.c:5697
    SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
    Definition: var.c:23418
    int SCIPvarGetNLocksUpType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
    Definition: var.c:4380
    SCIP_Bool SCIPvarIsImpliedIntegral(SCIP_VAR *var)
    Definition: var.c:23530
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24300
    SCIP_Real SCIPvarGetLbOriginal(SCIP_VAR *var)
    Definition: var.c:24052
    SCIP_RETCODE SCIPaddVarExactData(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *lb, SCIP_RATIONAL *ub, SCIP_RATIONAL *obj)
    Definition: scip_var.c:299
    SCIP_RETCODE SCIPchgVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
    Definition: scip_var.c:5875
    SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
    Definition: var.c:23932
    SCIP_RETCODE SCIPtightenVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
    Definition: scip_var.c:6651
    SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
    Definition: var.c:23485
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24174
    int SCIPvarGetIndex(SCIP_VAR *var)
    Definition: var.c:23684
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23299
    SCIP_Real SCIPvarGetUbOriginal(SCIP_VAR *var)
    Definition: var.c:24095
    SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
    Definition: scip_var.c:1887
    SCIP_RETCODE SCIPgetProbvarLinearSum(SCIP *scip, SCIP_VAR **vars, SCIP_Real *scalars, int *nvars, int varssize, SCIP_Real *constant, int *requiredsize)
    Definition: scip_var.c:2378
    SCIP_RETCODE SCIPchgVarType(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
    Definition: scip_var.c:10113
    SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
    Definition: scip_var.c:2166
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24266
    SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
    Definition: var.c:23475
    SCIP_RATIONAL * SCIPvarGetLbGlobalExact(SCIP_VAR *var)
    Definition: var.c:24162
    SCIP_RETCODE SCIPcreateVar(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_DECL_VARCOPY((*varcopy)), SCIP_VARDATA *vardata)
    Definition: scip_var.c:120
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24152
    SCIP_IMPLINTTYPE SCIPvarGetImplType(SCIP_VAR *var)
    Definition: var.c:23495
    SCIP_RETCODE SCIPchgVarObjExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *newobj)
    Definition: scip_var.c:5420
    SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
    Definition: scip_var.c:5372
    SCIP_RETCODE SCIPchgVarLbExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *newbound)
    Definition: scip_var.c:5786
    int SCIPvarGetNLocksDownType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
    Definition: var.c:4322
    SCIP_RETCODE SCIPtightenVarLbExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *newbound, SCIP_Bool *infeasible, SCIP_Bool *tightened)
    Definition: scip_var.c:6518
    SCIP_RATIONAL * SCIPvarGetUbGlobalExact(SCIP_VAR *var)
    Definition: var.c:24184
    void SCIPsortPtrPtrReal(void **ptrarray1, void **ptrarray2, SCIP_Real *realarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), int len)
    int SCIPsnprintf(char *t, int len, const char *s,...)
    Definition: misc.c:10827
    void SCIPprintSysError(const char *message)
    Definition: misc.c:10719
    char * SCIPstrtok(char *s, const char *delim, char **ptrptr)
    Definition: misc.c:10768
    int SCIPmemccpy(char *dest, const char *src, char stop, unsigned int cnt)
    Definition: misc.c:10694
    memory allocation routines
    public methods for managing constraints
    wrapper functions to map file i/o to standard or zlib file i/o
    struct SCIP_File SCIP_FILE
    Definition: pub_fileio.h:43
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    #define SCIPdebugPrintCons(x, y, z)
    Definition: pub_message.h:102
    #define SCIPdebugMessage
    Definition: pub_message.h:96
    public data structures and miscellaneous methods
    methods for sorting joint arrays of various types
    public methods for input file readers
    public methods for problem variables
    wrapper for rational number arithmetic
    static void mpsinputEntryIgnored(SCIP *scip, MPSINPUT *mpsi, const char *what, const char *what_name, const char *entity, const char *entity_name, SCIP_VERBLEVEL verblevel)
    Definition: reader_mps.c:409
    static void mpsinputInsertField4(MPSINPUT *mpsi, const char *str)
    Definition: reader_mps.c:649
    static const char * mpsinputField5(const MPSINPUT *mpsi)
    Definition: reader_mps.c:290
    static SCIP_RETCODE checkVarnames(SCIP *scip, SCIP_VAR **vars, int nvars, unsigned int *maxnamelen, const char ***varnames, SCIP_HASHMAP **varnameHashmap)
    Definition: reader_mps.c:4140
    static SCIP_RETCODE readMpsExact(SCIP *scip, const char *filename, const char ***varnames, const char ***consnames, int *varnamessize, int *consnamessize, int *nvarnames, int *nconsnames)
    Definition: reader_mps.c:3624
    static SCIP_RETCODE readSOS(MPSINPUT *mpsi, SCIP *scip)
    Definition: reader_mps.c:2680
    static void printRhsSection(SCIP *scip, FILE *file, int nconss, const char **consnames, SCIP_Real *rhss, unsigned int maxnamelen, SCIP_Real objoffset)
    Definition: reader_mps.c:4461
    static SCIP_DECL_READERWRITE(readerWriteMps)
    Definition: reader_mps.c:4888
    struct SparseMatrix SPARSEMATRIX
    Definition: reader_mps.c:164
    static const char * mpsinputField1(const MPSINPUT *mpsi)
    Definition: reader_mps.c:246
    static SCIP_DECL_HASHKEYEQ(hashKeyEqString)
    Definition: reader_mps.c:3747
    MpsSection
    Definition: reader_mps.c:109
    @ MPS_QCMATRIX
    Definition: reader_mps.c:123
    @ MPS_COLUMNS
    Definition: reader_mps.c:116
    @ MPS_NAME
    Definition: reader_mps.c:110
    @ MPS_BOUNDS
    Definition: reader_mps.c:119
    @ MPS_USERCUTS
    Definition: reader_mps.c:114
    @ MPS_SOS
    Definition: reader_mps.c:120
    @ MPS_ROWS
    Definition: reader_mps.c:113
    @ MPS_LAZYCONS
    Definition: reader_mps.c:115
    @ MPS_INDICATORS
    Definition: reader_mps.c:124
    @ MPS_OBJSEN
    Definition: reader_mps.c:111
    @ MPS_OBJNAME
    Definition: reader_mps.c:112
    @ MPS_QMATRIX
    Definition: reader_mps.c:122
    @ MPS_RHS
    Definition: reader_mps.c:117
    @ MPS_RANGES
    Definition: reader_mps.c:118
    @ MPS_ENDATA
    Definition: reader_mps.c:125
    @ MPS_QUADOBJ
    Definition: reader_mps.c:121
    static SCIP_RETCODE readObjsen(SCIP *scip, MPSINPUT *mpsi)
    Definition: reader_mps.c:779
    static SCIP_RETCODE checkSparseMatrixCapacity(SCIP *scip, SPARSEMATRIX *matrix, int capacity)
    Definition: reader_mps.c:3947
    static SCIP_RETCODE readQMatrix(MPSINPUT *mpsi, SCIP_Bool isQuadObj, SCIP *scip)
    Definition: reader_mps.c:2880
    #define MPSINTCOMP_LEVEL(IMPLINTLEVEL)
    Definition: reader_mps.c:4324
    static SCIP_Bool mpsinputHasError(const MPSINPUT *mpsi)
    Definition: reader_mps.c:323
    static SCIP_DECL_READERFREE(readerFreeMps)
    Definition: reader_mps.c:4858
    static SCIP_RETCODE readRows(MPSINPUT *mpsi, SCIP *scip, const char ***consnames, int *consnamessize, int *nconsnames)
    Definition: reader_mps.c:877
    static void printBoundSectionName(SCIP *scip, FILE *file)
    Definition: reader_mps.c:4568
    static const char * mpsinputField2(const MPSINPUT *mpsi)
    Definition: reader_mps.c:257
    static void clearFrom(char *buf, unsigned int pos)
    Definition: reader_mps.c:431
    static SCIP_RETCODE readColsExact(MPSINPUT *mpsi, SCIP *scip, const char ***varnames, int *varnamessize, int *nvarnames)
    Definition: reader_mps.c:1210
    static SCIP_RETCODE readRhs(MPSINPUT *mpsi, SCIP *scip)
    Definition: reader_mps.c:1355
    static void mpsinputSetObjname(MPSINPUT *mpsi, const char *objname)
    Definition: reader_mps.c:371
    static SCIP_RETCODE initializeMatrix(SCIP *scip, SPARSEMATRIX **matrix, int slots)
    Definition: reader_mps.c:3929
    static void freeMatrix(SCIP *scip, SPARSEMATRIX *matrix)
    Definition: reader_mps.c:3965
    static SCIP_RETCODE readObjname(SCIP *scip, MPSINPUT *mpsi)
    Definition: reader_mps.c:838
    enum MpsSection MPSSECTION
    Definition: reader_mps.c:127
    static SCIP_Bool mpsinputIsInteger(const MPSINPUT *mpsi)
    Definition: reader_mps.c:334
    struct MpsInput MPSINPUT
    Definition: reader_mps.c:153
    static SCIP_RETCODE getLinearCoeffs(SCIP *scip, const char *consname, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_Bool transformed, SPARSEMATRIX *matrix, SCIP_Real *rhs)
    Definition: reader_mps.c:3980
    static void mpsinputSetProbname(MPSINPUT *mpsi, const char *probname)
    Definition: reader_mps.c:357
    static SCIP_DECL_HASHGETKEY(hashGetKeyNamefreq)
    Definition: reader_mps.c:3735
    static void printRangeSection(SCIP *scip, FILE *file, SCIP_CONS **conss, int nconss, const char **consnames, SCIP_Bool transformed, unsigned int maxnamelen)
    Definition: reader_mps.c:4503
    #define BLANK
    Definition: reader_mps.c:98
    static SCIP_OBJSENSE mpsinputObjsense(const MPSINPUT *mpsi)
    Definition: reader_mps.c:312
    static SCIP_RETCODE readCols(MPSINPUT *mpsi, SCIP *scip, const char ***varnames, int *varnamessize, int *nvarnames)
    Definition: reader_mps.c:1079
    static SCIP_Bool mpsinputReadLine(MPSINPUT *mpsi)
    Definition: reader_mps.c:466
    static void mpsinputSetObjsense(MPSINPUT *mpsi, SCIP_OBJSENSE sense)
    Definition: reader_mps.c:385
    static void mpsinputInsertName(MPSINPUT *mpsi, const char *name, SCIP_Bool second)
    Definition: reader_mps.c:663
    static MPSSECTION mpsinputSection(const MPSINPUT *mpsi)
    Definition: reader_mps.c:224
    static SCIP_RETCODE addVarNameToStorage(SCIP *scip, const char ***varnames, int *varnamessize, int *nvars, const char *colname)
    Definition: reader_mps.c:687
    #define READER_DESC
    Definition: reader_mps.c:82
    static const char * mpsinputField3(const MPSINPUT *mpsi)
    Definition: reader_mps.c:268
    static SCIP_RETCODE checkConsnames(SCIP *scip, SCIP_CONS **conss, int nconss, SCIP_Bool transformed, unsigned int *maxnamelen, const char ***consnames, SCIP_Bool *error)
    Definition: reader_mps.c:4204
    #define MPS_MAX_FIELDLEN
    Definition: reader_mps.c:95
    static SCIP_DECL_READERCOPY(readerCopyMps)
    Definition: reader_mps.c:4841
    static SCIP_RETCODE readRhsExact(MPSINPUT *mpsi, SCIP *scip)
    Definition: reader_mps.c:1502
    static SCIP_RETCODE addConsNameToStorage(SCIP *scip, const char ***consnames, int *consnamessize, int *ncons, const char *rowname)
    Definition: reader_mps.c:709
    #define MPS_MAX_VALUELEN
    Definition: reader_mps.c:94
    #define READER_EXTENSION
    Definition: reader_mps.c:83
    static SCIP_RETCODE readMps(SCIP *scip, const char *filename, const char ***varnames, const char ***consnames, int *varnamessize, int *consnamessize, int *nvarnames, int *nconsnames)
    Definition: reader_mps.c:3504
    static SCIP_DECL_READERREAD(readerReadMps)
    Definition: reader_mps.c:4874
    static void printRowType(SCIP *scip, FILE *file, SCIP_Real lhs, SCIP_Real rhs, const char *name)
    Definition: reader_mps.c:3891
    static SCIP_RETCODE readRanges(MPSINPUT *mpsi, SCIP *scip)
    Definition: reader_mps.c:1657
    static SCIP_DECL_SORTPTRCOMP(mpsIntCompM2)
    Definition: reader_mps.c:4336
    static SCIP_RETCODE mpsinputCreate(SCIP *scip, MPSINPUT **mpsi, SCIP_FILE *fp)
    Definition: reader_mps.c:176
    static unsigned int computeFieldWidth(unsigned int width)
    Definition: reader_mps.c:3782
    static void printBoundSection(SCIP *scip, FILE *file, SCIP_VAR **vars, int nvars, SCIP_VAR **aggvars, int naggvars, SCIP_VAR **fixvars, int nfixvars, SCIP_Bool transformed, const char **varnames, SCIP_HASHTABLE *indicatorSlackHash, unsigned int maxnamelen)
    Definition: reader_mps.c:4579
    static const char * mpsinputField4(const MPSINPUT *mpsi)
    Definition: reader_mps.c:279
    static void printEntry(SCIP *scip, FILE *file, const char *varname, const char *consname, SCIP_Real value, int *recordcnt, unsigned int maxnamelen)
    Definition: reader_mps.c:3853
    static void printStart(SCIP *scip, FILE *file, const char *col1, const char *col2, int maxnamelen)
    Definition: reader_mps.c:3819
    static SCIP_RETCODE readIndicators(MPSINPUT *mpsi, SCIP *scip)
    Definition: reader_mps.c:3289
    #define READER_NAME
    Definition: reader_mps.c:81
    static SCIP_DECL_HASHKEYVAL(hashKeyValVar)
    Definition: reader_mps.c:3773
    static void mpsinputSetSection(MPSINPUT *mpsi, MPSSECTION section)
    Definition: reader_mps.c:345
    static void printRecord(SCIP *scip, FILE *file, const char *col1, const char *col2, unsigned int maxnamelen)
    Definition: reader_mps.c:3793
    static SCIP_RETCODE readRowsExact(MPSINPUT *mpsi, SCIP *scip, const char ***consnames, int *consnamessize, int *nconsnames)
    Definition: reader_mps.c:973
    static const char * mpsinputObjname(const MPSINPUT *mpsi)
    Definition: reader_mps.c:301
    #define DEFAULT_AGGRLINEARIZATION_ANDS
    Definition: reader_mps.c:86
    static const char * mpsinputField0(const MPSINPUT *mpsi)
    Definition: reader_mps.c:235
    static void mpsinputSyntaxerror(MPSINPUT *mpsi)
    Definition: reader_mps.c:396
    static SCIP_RETCODE collectAggregatedVars(SCIP *scip, SCIP_VAR **vars, int nvars, SCIP_VAR ***aggvars, int *naggvars, int *saggvars, SCIP_HASHTABLE *varAggregated)
    Definition: reader_mps.c:4083
    static SCIP_RETCODE readName(SCIP *scip, MPSINPUT *mpsi)
    Definition: reader_mps.c:731
    #define MPS_MAX_NAMELEN
    Definition: reader_mps.c:93
    #define PATCH_CHAR
    Definition: reader_mps.c:97
    static SCIP_RETCODE readQCMatrix(MPSINPUT *mpsi, SCIP *scip)
    Definition: reader_mps.c:3099
    static SCIP_RETCODE readRangesExact(MPSINPUT *mpsi, SCIP *scip)
    Definition: reader_mps.c:1797
    static SCIP_RETCODE readBounds(MPSINPUT *mpsi, SCIP *scip)
    Definition: reader_mps.c:1956
    #define MPS_MAX_LINELEN
    Definition: reader_mps.c:92
    static SCIP_RETCODE readBoundsExact(MPSINPUT *mpsi, SCIP *scip)
    Definition: reader_mps.c:2329
    #define DEFAULT_LINEARIZE_ANDS
    Definition: reader_mps.c:85
    static SCIP_Bool writeVarIsIntegral(SCIP_VAR *var, int implintlevel)
    Definition: reader_mps.c:4309
    static void patchField(char *buf, int beg, int end)
    Definition: reader_mps.c:445
    static void mpsinputFree(SCIP *scip, MPSINPUT **mpsi)
    Definition: reader_mps.c:214
    (extended) MPS file reader
    public methods for constraint handler plugins and constraints
    public methods for exact solving
    public methods for memory management
    public methods for message handling
    public methods for numerical tolerances
    public methods for SCIP parameter handling
    public methods for global and local (sub)problems
    public methods for reader plugins
    public methods for querying solving statistics
    public methods for SCIP variables
    static SCIP_RETCODE separate(SCIP *scip, SCIP_SEPA *sepa, SCIP_SOL *sol, SCIP_RESULT *result)
    Main separation function.
    Definition: sepa_flower.c:1219
    const char * consname
    Definition: reader_mps.c:169
    @ SCIP_BOUNDTYPE_UPPER
    Definition: type_lp.h:58
    @ SCIP_BOUNDTYPE_LOWER
    Definition: type_lp.h:57
    enum SCIP_BoundType SCIP_BOUNDTYPE
    Definition: type_lp.h:60
    enum SCIP_VerbLevel SCIP_VERBLEVEL
    Definition: type_message.h:64
    @ SCIP_VERBLEVEL_NORMAL
    Definition: type_message.h:60
    @ SCIP_VERBLEVEL_FULL
    Definition: type_message.h:62
    @ SCIP_OBJSENSE_MAXIMIZE
    Definition: type_prob.h:47
    @ SCIP_OBJSENSE_MINIMIZE
    Definition: type_prob.h:48
    enum SCIP_Objsense SCIP_OBJSENSE
    Definition: type_prob.h:50
    struct SCIP_ReaderData SCIP_READERDATA
    Definition: type_reader.h:54
    @ SCIP_SUCCESS
    Definition: type_result.h:58
    enum SCIP_Result SCIP_RESULT
    Definition: type_result.h:61
    @ SCIP_NOFILE
    Definition: type_retcode.h:47
    @ SCIP_READERROR
    Definition: type_retcode.h:45
    @ SCIP_INVALIDDATA
    Definition: type_retcode.h:52
    @ SCIP_PLUGINNOTFOUND
    Definition: type_retcode.h:54
    @ SCIP_WRITEERROR
    Definition: type_retcode.h:46
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_INVALIDCALL
    Definition: type_retcode.h:51
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_VARTYPE_INTEGER
    Definition: type_var.h:65
    @ SCIP_VARTYPE_CONTINUOUS
    Definition: type_var.h:71
    @ SCIP_VARTYPE_BINARY
    Definition: type_var.h:64
    @ SCIP_VARSTATUS_FIXED
    Definition: type_var.h:54
    @ SCIP_VARSTATUS_MULTAGGR
    Definition: type_var.h:56
    @ SCIP_VARSTATUS_NEGATED
    Definition: type_var.h:57
    @ SCIP_VARSTATUS_AGGREGATED
    Definition: type_var.h:55
    @ SCIP_LOCKTYPE_MODEL
    Definition: type_var.h:141
    enum SCIP_Vartype SCIP_VARTYPE
    Definition: type_var.h:73
    enum SCIP_Varstatus SCIP_VARSTATUS
    Definition: type_var.h:59