Scippy

    SCIP

    Solving Constraint Integer Programs

    reader_cip.c
    Go to the documentation of this file.
    1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    2/* */
    3/* This file is part of the program and library */
    4/* SCIP --- Solving Constraint Integer Programs */
    5/* */
    6/* Copyright (c) 2002-2025 Zuse Institute Berlin (ZIB) */
    7/* */
    8/* Licensed under the Apache License, Version 2.0 (the "License"); */
    9/* you may not use this file except in compliance with the License. */
    10/* You may obtain a copy of the License at */
    11/* */
    12/* http://www.apache.org/licenses/LICENSE-2.0 */
    13/* */
    14/* Unless required by applicable law or agreed to in writing, software */
    15/* distributed under the License is distributed on an "AS IS" BASIS, */
    16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
    17/* See the License for the specific language governing permissions and */
    18/* limitations under the License. */
    19/* */
    20/* You should have received a copy of the Apache-2.0 license */
    21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
    22/* */
    23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    24
    25/**@file reader_cip.c
    26 * @ingroup DEFPLUGINS_READER
    27 * @brief CIP file reader
    28 * @author Stefan Heinz
    29 * @author Marc Pfetsch
    30 * @author Michael Winkler
    31 *
    32 */
    33
    34/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    35
    37#include "scip/rational.h"
    38#include "scip/cons_linear.h"
    40#include "scip/pub_fileio.h"
    41#include "scip/pub_message.h"
    42#include "scip/pub_misc.h"
    43#include "scip/pub_reader.h"
    44#include "scip/pub_var.h"
    45#include "scip/reader_cip.h"
    46#include "scip/scip_exact.h"
    47#include "scip/scip_cons.h"
    48#include "scip/scip_mem.h"
    49#include "scip/scip_message.h"
    50#include "scip/scip_numerics.h"
    51#include "scip/scip_param.h"
    52#include "scip/scip_prob.h"
    53#include "scip/scip_reader.h"
    54#include "scip/scip_var.h"
    55
    56
    57#define READER_NAME "cipreader"
    58#define READER_DESC "file reader for CIP (Constraint Integer Program) format"
    59#define READER_EXTENSION "cip"
    60
    61#define DEFAULT_CIP_WRITEFIXEDVARS TRUE /**< Should fixed and aggregated variables be written when writing? */
    62
    63
    64/** CIP reading data */
    65struct SCIP_ReaderData
    66{
    67 SCIP_Bool writefixedvars; /**< Should fixed and aggregated variables be written when writing? */
    68};
    69
    70
    71/** Section of the in CIP files */
    73{
    74 CIP_START, /**< start tag */
    75 CIP_STATISTIC, /**< statistics section */
    76 CIP_OBJECTIVE, /**< objective */
    77 CIP_VARS, /**< list of (free) variables */
    78 CIP_FIXEDVARS, /**< list of fixed variables */
    79 CIP_CONSTRAINTS, /**< constraints */
    80 CIP_END /**< end of file tag */
    81};
    82typedef enum CipSection CIPSECTION; /**< Section of the in CIP files */
    83
    84
    85/*
    86 * Data structures
    87 */
    88
    89/** CIP reading data */
    90struct CipInput
    91{
    92 SCIP_FILE* file; /**< input file */
    93 char* strbuf; /**< string buffer for input lines */
    94 int len; /**< length of strbuf */
    95 int readingsize; /**< size of block in which len is increased if necessary */
    96 int linenumber; /**< number of line in input file */
    97 CIPSECTION section; /**< current section */
    98 SCIP_Bool haserror; /**< some error occurred */
    99 SCIP_Bool endfile; /**< we have reached the end of the file */
    100 SCIP_Real objoffset; /**< real objective offset */
    101 SCIP_Real objscale; /**< real objective scale */
    102 SCIP_RATIONAL* objoffsetexact; /**< exact objective offset */
    103 SCIP_RATIONAL* objscaleexact; /**< exact objective scale */
    104};
    105typedef struct CipInput CIPINPUT; /**< CIP reading data */
    106
    107
    108/*
    109 * Local methods for reading/parsing
    110 */
    111
    112/** get next input line; this are all characters until the next semicolon */
    113static
    115 SCIP* scip, /**< SCIP data structure */
    116 CIPINPUT* cipinput /**< CIP parsing data */
    117 )
    118{
    119 char* endline;
    120 char* endcharacter;
    121 char* windowsendlinechar;
    122
    123 assert(cipinput != NULL);
    124
    125 /* read next line */
    126 cipinput->endfile = (SCIPfgets(cipinput->strbuf, cipinput->len, cipinput->file) == NULL);
    127
    128 if( cipinput->endfile )
    129 {
    130 /* clear the line for safety reason */
    131 BMSclearMemoryArray(cipinput->strbuf, cipinput->len);
    132 return SCIP_OKAY;
    133 }
    134
    135 cipinput->linenumber++;
    136 endline = strchr(cipinput->strbuf, '\n');
    137 endcharacter = strchr(cipinput->strbuf, ';');
    138
    139 while( endline == NULL || (endcharacter == NULL && cipinput->section == CIP_CONSTRAINTS && strncmp(cipinput->strbuf, "END", 3) != 0 ) )
    140 {
    141 int pos;
    142
    143 /* we refill the buffer from the '\n' character */
    144 if( endline == NULL )
    145 pos = cipinput->len - 1;
    146 else
    147 pos = (int) (endline - cipinput->strbuf);
    148
    149 /* don't erase the '\n' from all buffers for constraints */
    150 if( endline != NULL && cipinput->section == CIP_CONSTRAINTS )
    151 pos++;
    152
    153 /* if necessary reallocate memory */
    154 if( pos + cipinput->readingsize >= cipinput->len )
    155 {
    156 cipinput->len = SCIPcalcMemGrowSize(scip, pos + cipinput->readingsize);
    157 SCIP_CALL( SCIPreallocBufferArray(scip, &(cipinput->strbuf), cipinput->len) );
    158 }
    159
    160 /* read next line */
    161 cipinput->endfile = (SCIPfgets(&(cipinput->strbuf[pos]), cipinput->len - pos, cipinput->file) == NULL);
    162
    163 if( cipinput->endfile )
    164 {
    165 /* clear the line for safety reason */
    166 BMSclearMemoryArray(cipinput->strbuf, cipinput->len);
    167 return SCIP_OKAY;
    168 }
    169
    170 cipinput->linenumber++;
    171 endline = strrchr(&cipinput->strbuf[pos], '\n');
    172 endcharacter = strchr(&cipinput->strbuf[pos], ';');
    173 }
    174 assert(endline != NULL);
    175
    176 /*SCIPdebugMsg(scip, "read line: %s\n", cipinput->strbuf);*/
    177
    178 /* check for windows "carriage return" endline character */
    179 windowsendlinechar = strrchr(cipinput->strbuf, '\r');
    180 if( windowsendlinechar != NULL && windowsendlinechar + 1 == endline )
    181 --endline;
    182 else
    183 /* if the assert should not hold we found a windows "carriage return" which was not at the end of the line */
    184 assert(windowsendlinechar == NULL);
    185
    186 if( cipinput->section == CIP_CONSTRAINTS && endcharacter != NULL && endline - endcharacter != 1 )
    187 {
    188 SCIPerrorMessage("Constraint line has to end with ';\\n' (line: %d).\n", cipinput->linenumber);
    189 cipinput->haserror = TRUE;
    190 return SCIP_OKAY; /* return error at hightest level */
    191 }
    192
    193 *endline = '\0';
    194
    195 return SCIP_OKAY;
    196}
    197
    198/** read the problem name out of the statistics */
    199static
    201 SCIP* scip, /**< SCIP data structure */
    202 CIPINPUT* cipinput /**< CIP parsing data */
    203 )
    204{
    205 char* buf;
    206
    207 assert(scip != NULL);
    208
    209 buf = cipinput->strbuf;
    210
    211 if( strncmp(buf, "STATISTICS", 9) == 0 )
    212 {
    213 cipinput->section = CIP_STATISTIC;
    214 return;
    215 }
    216
    217 if( strncmp(buf, "VARIABLES", 8) == 0 || strncmp(buf, "FIXED", 5) == 0 || strncmp(buf, "CONSTRAINTS", 11) == 0 || strncmp(buf, "OBJECTIVE", 9) == 0 )
    218 {
    219 SCIPerrorMessage("Syntax Error: File has to start with 'STATISTICS' section.\n");
    220 cipinput->haserror = TRUE;
    221 }
    222}
    223
    224
    225/** read the problem name out of the statistics */
    226static
    228 SCIP* scip, /**< SCIP data structure */
    229 CIPINPUT* cipinput /**< CIP parsing data */
    230 )
    231{
    232 char* buf;
    233
    234 buf = cipinput->strbuf;
    235
    236 if( strncmp(buf, "OBJECTIVE", 9) == 0 )
    237 {
    238 cipinput->section = CIP_OBJECTIVE;
    239 return SCIP_OKAY;
    240 }
    241
    242 SCIPdebugMsg(scip, "parse statistics\n");
    243
    244 if( strncmp(buf, " Problem name", 14) == 0 )
    245 {
    246 char* name;
    247 char* s;
    248
    249 name = strchr(buf, ':');
    250
    251 if( name == NULL )
    252 {
    253 SCIPwarningMessage(scip, "did not find problem name (line: %d):\n%s\n", cipinput->linenumber, cipinput->strbuf);
    254 return SCIP_OKAY; /* no error, might work with empty problem name */
    255 }
    256
    257 /* skip ':' */
    258 ++name;
    259
    260 /* make sure that we terminate the string at comments ('#') or newline ('\r', '\n')*/
    261 if( NULL != (s = strpbrk(name, "#\r\n")) )
    262 *s = '\0';
    263
    264 /* remove white space (tabs, ' ') in front of the name */
    265 SCIP_CALL( SCIPskipSpace(&name) );
    266
    267 /* set problem name */
    269
    270 SCIPdebugMsg(scip, "problem name <%s>\n", name);
    271 }
    272
    273 return SCIP_OKAY;
    274}
    275
    276/** read objective sense, offset, and scale */
    277static
    279 SCIP* scip, /**< SCIP data structure */
    280 CIPINPUT* cipinput /**< CIP parsing data */
    281 )
    282{
    283 SCIP_Bool success;
    284 char* buf;
    285 char* name;
    286
    287 buf = cipinput->strbuf;
    288
    289 if( strncmp(buf, "VARIABLES", 8) == 0 )
    290 cipinput->section = CIP_VARS;
    291 else if( strncmp(buf, "FIXED", 5) == 0 )
    292 cipinput->section = CIP_FIXEDVARS;
    293 else if( strncmp(buf, "CONSTRAINTS", 11) == 0 )
    294 cipinput->section = CIP_CONSTRAINTS;
    295 else if( strncmp(buf, "END", 3) == 0 )
    296 cipinput->section = CIP_END;
    297
    298 if( cipinput->section != CIP_OBJECTIVE )
    299 return SCIP_OKAY;
    300
    301 SCIPdebugMsg(scip, "parse objective information\n");
    302
    303 /* remove white space */
    304 SCIP_CALL( SCIPskipSpace(&buf) );
    305
    306 if( SCIPstrncasecmp(buf, "Sense", 5) == 0 )
    307 {
    308 SCIP_OBJSENSE objsense;
    309
    310 name = strchr(buf, ':');
    311
    312 if( name == NULL )
    313 {
    314 SCIPwarningMessage(scip, "did not find objective sense (line: %d):\n%s\n", cipinput->linenumber, cipinput->strbuf);
    315 return SCIP_OKAY; /* no error - might work with default */
    316 }
    317
    318 /* skip ':' */
    319 ++name;
    320
    321 /* remove white space in front of the name */
    322 SCIP_CALL( SCIPskipSpace(&name) );
    323
    324 if( SCIPstrncasecmp(name, "min", 3) == 0 )
    325 objsense = SCIP_OBJSENSE_MINIMIZE;
    326 else if( SCIPstrncasecmp(name, "max", 3) == 0 )
    327 objsense = SCIP_OBJSENSE_MAXIMIZE;
    328 else
    329 {
    330 SCIPwarningMessage(scip, "unknown objective sense '%s' (line: %d):\n%s\n", name, cipinput->linenumber, cipinput->strbuf);
    331 return SCIP_OKAY; /* no error - might work with default */
    332 }
    333
    334 /* set problem name */
    335 SCIP_CALL( SCIPsetObjsense(scip, objsense) );
    336 SCIPdebugMsg(scip, "objective sense <%s>\n", objsense == SCIP_OBJSENSE_MINIMIZE ? "minimize" : "maximize");
    337 }
    338 else if( SCIPstrncasecmp(buf, "Offset", 6) == 0 )
    339 {
    340 char* endptr;
    341
    342 name = strchr(buf, ':');
    343
    344 if( name == NULL )
    345 {
    346 SCIPwarningMessage(scip, "did not find offset (line: %d)\n", cipinput->linenumber);
    347 return SCIP_OKAY;
    348 }
    349
    350 /* skip ':' */
    351 ++name;
    352
    353 /* read exact offset */
    354 if( cipinput->objoffsetexact != NULL )
    355 {
    356 success = SCIPparseRational(scip, name, cipinput->objoffsetexact, &endptr);
    357
    358 if( success )
    359 SCIPrationalDebugMessage("read exact objoffset %q\n", cipinput->objoffsetexact);
    360 else
    361 SCIPrationalSetReal(cipinput->objoffsetexact, 0.0);
    362 }
    363 /* read real offset */
    364 else
    365 {
    366 success = SCIPparseReal(scip, name, &cipinput->objoffset, &endptr);
    367
    368 if( success )
    369 SCIPdebugMsg(scip, "read real objoffset %g\n", cipinput->objoffset);
    370 else
    371 cipinput->objoffset = 0.0;
    372 }
    373
    374 if( !success )
    375 {
    376 SCIPwarningMessage(scip, "could not parse offset (line: %d)\n%s\n", cipinput->linenumber, cipinput->strbuf);
    377 return SCIP_OKAY;
    378 }
    379 }
    380 else if( SCIPstrncasecmp(buf, "Scale", 5) == 0 )
    381 {
    382 char* endptr;
    383
    384 name = strchr(buf, ':');
    385
    386 if( name == NULL )
    387 {
    388 SCIPwarningMessage(scip, "did not find scale (line: %d)\n", cipinput->linenumber);
    389 return SCIP_OKAY;
    390 }
    391
    392 /* skip ':' */
    393 ++name;
    394
    395 /* read exact scale */
    396 if( cipinput->objscaleexact != NULL )
    397 {
    398 success = SCIPparseRational(scip, name, cipinput->objscaleexact, &endptr);
    399
    400 if( success )
    401 SCIPrationalDebugMessage("read exact objscale %q\n", cipinput->objscaleexact);
    402 else
    403 SCIPrationalSetReal(cipinput->objscaleexact, 1.0);
    404 }
    405 /* read real scale */
    406 else
    407 {
    408 success = SCIPparseReal(scip, name, &cipinput->objscale, &endptr);
    409
    410 if( success )
    411 SCIPdebugMsg(scip, "read real objscale %g\n", cipinput->objscale);
    412 else
    413 cipinput->objscale = 1.0;
    414 }
    415
    416 if( !success )
    417 {
    418 SCIPwarningMessage(scip, "could not parse objective scale (line: %d)\n%s\n", cipinput->linenumber, cipinput->strbuf);
    419 return SCIP_OKAY;
    420 }
    421 }
    422
    423 return SCIP_OKAY;
    424}
    425
    426/** read variable */
    427static
    429 SCIP* scip, /**< SCIP data structure */
    430 CIPINPUT* cipinput, /**< CIP parsing data */
    431 SCIP_Bool initial, /**< should var's column be present in the initial root LP? */
    432 SCIP_Bool removable /**< is var's column removable from the LP (due to aging or cleanup)? */
    433 )
    434{
    435 SCIP_Bool success;
    436 SCIP_VAR* var;
    437 char* buf;
    438 char* endptr;
    439
    440 buf = cipinput->strbuf;
    441
    442 if( strncmp(buf, "FIXED", 5) == 0 )
    443 cipinput->section = CIP_FIXEDVARS;
    444 else if( strncmp(buf, "CONSTRAINTS", 4) == 0 )
    445 cipinput->section = CIP_CONSTRAINTS;
    446 else if( strncmp(buf, "END", 3) == 0 )
    447 cipinput->section = CIP_END;
    448
    449 if( cipinput->section != CIP_VARS )
    450 return SCIP_OKAY;
    451
    452 SCIPdebugMsg(scip, "parse variable\n");
    453
    454 /* parse the variable */
    455 SCIP_CALL( SCIPparseVar(scip, &var, buf, initial, removable, NULL, NULL, NULL, NULL, NULL, &endptr, &success) );
    456
    457 if( !success )
    458 {
    459 SCIPerrorMessage("syntax error in variable information (line: %d):\n%s\n", cipinput->linenumber, cipinput->strbuf);
    460 cipinput->haserror = TRUE;
    461 return SCIP_OKAY;
    462 }
    463
    464 /* scale exact objective */
    465 if( cipinput->objscaleexact != NULL )
    466 {
    467 if( !SCIPrationalIsEQReal(cipinput->objscaleexact, 1.0) )
    468 {
    469 SCIP_RATIONAL* newobjval;
    470
    472
    473 SCIPrationalMult(newobjval, SCIPvarGetObjExact(var), cipinput->objscaleexact);
    474 SCIP_CALL( SCIPchgVarObjExact(scip, var, newobjval) );
    475
    477 }
    478 }
    479 /* scale real objective */
    480 else
    481 {
    482 if( cipinput->objscale != 1.0 ) /*lint !e777*/
    483 {
    484 SCIP_CALL( SCIPchgVarObj(scip, var, SCIPvarGetObj(var) * cipinput->objscale) );
    485 }
    486 }
    487
    488 SCIP_CALL( SCIPaddVar(scip, var) );
    489
    491
    492 SCIP_CALL( SCIPreleaseVar(scip, &var) );
    493
    494 return SCIP_OKAY;
    495}
    496
    497/** read fixed variable */
    498static
    500 SCIP* scip, /**< SCIP data structure */
    501 CIPINPUT* cipinput /**< CIP parsing data */
    502 )
    503{
    504 SCIP_Bool success;
    505 SCIP_VAR* var;
    506 char* buf;
    507 char* endptr;
    508 char name[SCIP_MAXSTRLEN];
    509
    510 buf = cipinput->strbuf;
    511
    512 if( strncmp(buf, "CONSTRAINTS", 11) == 0 )
    513 cipinput->section = CIP_CONSTRAINTS;
    514 else if( strncmp(buf, "END", 3) == 0 )
    515 cipinput->section = CIP_END;
    516
    517 if( cipinput->section != CIP_FIXEDVARS )
    518 return SCIP_OKAY;
    519
    520 SCIPdebugMsg(scip, "parse fixed variable\n");
    521
    522 /* parse the variable */
    523 SCIP_CALL( SCIPparseVar(scip, &var, buf, TRUE, FALSE, NULL, NULL, NULL, NULL, NULL, &endptr, &success) );
    524
    525 if( !success )
    526 {
    527 SCIPerrorMessage("syntax error in variable information (line: %d):\n%s\n", cipinput->linenumber, cipinput->strbuf);
    528 cipinput->haserror = TRUE;
    529 return SCIP_OKAY;
    530 }
    531
    532 /* skip intermediate stuff */
    533 buf = endptr;
    534
    535 while( *buf != '\0' && (*buf == ' ' || *buf == ',') )
    536 ++buf;
    537
    538 /* check whether variable is fixed */
    539 if( strncmp(buf, "fixed:", 6) == 0 )
    540 {
    541 SCIP_CALL( SCIPaddVar(scip, var) );
    543 }
    544 else if( strncmp(buf, "negated:", 8) == 0 )
    545 {
    546 SCIP_CONS* lincons = NULL;
    547 SCIP_VAR* negvar;
    548 SCIP_VAR* vars[2];
    549
    550 buf += 8;
    551
    552 /* we can just parse the next variable (ignoring all other information in between) */
    553 SCIP_CALL( SCIPparseVarName(scip, buf, &negvar, &endptr) );
    554
    555 if( negvar == NULL )
    556 {
    557 SCIPerrorMessage("could not parse negated variable (line: %d):\n%s\n", cipinput->linenumber, cipinput->strbuf);
    558 cipinput->haserror = TRUE;
    559 return SCIP_OKAY;
    560 }
    561
    562 assert(SCIPvarIsBinary(var));
    563 assert(SCIPvarIsBinary(negvar));
    564
    565 SCIP_CALL( SCIPaddVar(scip, var) );
    566
    567 SCIPdebugMsg(scip, "creating negated variable <%s> (of <%s>) ...\n", SCIPvarGetName(var), SCIPvarGetName(negvar) );
    569
    570 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "neg_%s", SCIPvarGetName(var) );
    571 vars[0] = var;
    572 vars[1] = negvar;
    573
    574 /* add exact linear constraint for negation */
    575 if( SCIPisExact(scip) )
    576 {
    577 SCIP_RATIONAL** vals;
    578
    580
    581 SCIPrationalSetReal(vals[0], 1.0);
    582 SCIPrationalSetReal(vals[1], 1.0);
    583 SCIP_CALL( SCIPcreateConsExactLinear(scip, &lincons, name, 2, vars, vals, vals[0], vals[0], TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE) );
    584
    586 }
    587 /* add real linear constraint for negation */
    588 else
    589 {
    590 SCIP_Real vals[2];
    591
    592 vals[0] = 1.0;
    593 vals[1] = 1.0;
    594 SCIP_CALL( SCIPcreateConsLinear(scip, &lincons, name, 2, vars, vals, 1.0, 1.0, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE) );
    595 }
    596
    597 SCIPdebugMsg(scip, "coupling constraint:\n");
    598 SCIPdebugPrintCons(scip, lincons, NULL);
    599 SCIP_CALL( SCIPaddCons(scip, lincons) );
    600 SCIP_CALL( SCIPreleaseCons(scip, &lincons) );
    601 }
    602 else if( strncmp(buf, "aggregated:", 11) == 0 )
    603 {
    604 /* handle (multi-)aggregated variables */
    605 SCIP_CONS* lincons = NULL;
    606 SCIP_VAR** vars;
    607 const char* str;
    608 int nvarssize = 20;
    609 int requsize;
    610 int nvars;
    611
    612 buf += 11;
    613
    614 /* special handling of variables that seem to be slack variables of indicator constraints */
    615 str = SCIPvarGetName(var);
    616 if( strncmp(str, "indslack", 8) == 0 )
    617 {
    618 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "indlin");
    619 (void)strncat(name, str+8, SCIP_MAXSTRLEN-7);
    620 }
    621 else if( strncmp(str, "t_indslack", 10) == 0 )
    622 {
    623 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "indlin");
    624 (void)strncat(name, str+10, SCIP_MAXSTRLEN-7);
    625 }
    626 else
    627 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s", SCIPvarGetName(var) );
    628
    629 SCIPdebugMsg(scip, "parsing aggregated variable <%s> ...\n", SCIPvarGetName(var));
    630
    631 /* add exact linear constraint for (multi-)aggregation */
    632 if( SCIPisExact(scip) )
    633 {
    634 SCIP_RATIONAL** vals;
    635 SCIP_RATIONAL* rhs;
    636
    638
    639 /* parse exact constant */
    640 if( !SCIPparseRational(scip, buf, rhs, &endptr) )
    641 {
    642 SCIPerrorMessage("expected constant when aggregated variable information (line: %d):\n%s\n", cipinput->linenumber, buf);
    643 cipinput->haserror = TRUE;
    645 return SCIP_OKAY;
    646 }
    647
    648 SCIP_CALL( SCIPallocBufferArray(scip, &vars, nvarssize) );
    650
    651 /* check whether constant is 0.0 */
    652 str = endptr;
    653 SCIP_CALL( SCIPskipSpace((char**)&str) );
    654
    655 /* if next char is '<' we found a variable -> constant is 0 */
    656 if( *str != '<' )
    657 {
    658 buf = endptr;
    659
    660 SCIPrationalDebugMessage("constant: %q\n", rhs);
    661
    662 SCIPrationalMultReal(rhs, rhs, -1.0);
    663 }
    664 /* otherwise keep buf */
    665 else
    666 SCIPrationalSetReal(rhs, 0.0);
    667
    668 vars[0] = var;
    669 SCIPrationalSetReal(vals[0], -1.0);
    670 --nvarssize;
    671
    672 /* parse exact linear sum to get variables and coefficients */
    673 SCIP_CALL( SCIPparseVarsLinearsumExact(scip, buf, vars + 1, vals + 1, &nvars, nvarssize, &requsize, &endptr, &success) );
    674 if( success && requsize > nvarssize )
    675 {
    676 SCIP_CALL( SCIPreallocBufferArray(scip, &vars, requsize + 1) );
    677 SCIP_CALL( SCIPrationalReallocBufferArray(SCIPbuffer(scip), &vals, nvarssize + 1, requsize + 1) );
    678 nvarssize = requsize;
    679 SCIP_CALL( SCIPparseVarsLinearsumExact(scip, buf, vars + 1, vals + 1, &nvars, nvarssize, &requsize, &endptr, &success) );
    680 assert(!success || requsize <= nvarssize);
    681 }
    682
    683 if( success )
    684 {
    685 /* add aggregation constraint */
    686 SCIP_CALL( SCIPaddVar(scip, var) );
    687 SCIP_CALL( SCIPcreateConsExactLinear(scip, &lincons, name, nvars + 1, vars, vals, rhs, rhs, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE) );
    688 }
    689
    690 SCIPrationalFreeBufferArray(SCIPbuffer(scip), &vals, nvarssize + 1);
    693 }
    694 /* add real linear constraint for (multi-)aggregation */
    695 else
    696 {
    697 SCIP_Real* vals;
    698 SCIP_Real rhs;
    699
    700 /* parse real constant */
    701 if( !SCIPparseReal(scip, buf, &rhs, &endptr) )
    702 {
    703 SCIPerrorMessage("expected constant when aggregated variable information (line: %d):\n%s\n", cipinput->linenumber, buf);
    704 cipinput->haserror = TRUE;
    705 return SCIP_OKAY;
    706 }
    707
    708 SCIP_CALL( SCIPallocBufferArray(scip, &vars, nvarssize) );
    709 SCIP_CALL( SCIPallocBufferArray(scip, &vals, nvarssize) );
    710
    711 /* check whether constant is 0.0 */
    712 str = endptr;
    713 SCIP_CALL( SCIPskipSpace((char**)&str) );
    714
    715 /* if next char is '<' we found a variable -> constant is 0 */
    716 if( *str != '<' )
    717 {
    718 buf = endptr;
    719
    720 SCIPdebugMsg(scip, "constant: %f\n", rhs);
    721
    722 rhs *= -1.0;
    723 }
    724 /* otherwise keep buf */
    725 else
    726 rhs = 0.0;
    727
    728 vars[0] = var;
    729 vals[0] = -1.0;
    730 --nvarssize;
    731
    732 /* parse linear sum to get variables and coefficients */
    733 SCIP_CALL( SCIPparseVarsLinearsum(scip, buf, vars + 1, vals + 1, &nvars, nvarssize, &requsize, &endptr, &success) );
    734 if( success && requsize > nvarssize )
    735 {
    736 SCIP_CALL( SCIPreallocBufferArray(scip, &vars, requsize + 1) );
    737 SCIP_CALL( SCIPreallocBufferArray(scip, &vals, requsize + 1) );
    738 nvarssize = requsize;
    739 SCIP_CALL( SCIPparseVarsLinearsum(scip, buf, vars + 1, vals + 1, &nvars, nvarssize, &requsize, &endptr, &success) );
    740 assert(!success || requsize <= nvarssize);
    741 }
    742
    743 if( success )
    744 {
    745 /* add aggregation constraint */
    746 SCIP_CALL( SCIPaddVar(scip, var) );
    747 SCIP_CALL( SCIPcreateConsLinear(scip, &lincons, name, nvars + 1, vars, vals, rhs, rhs, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE) );
    748 }
    749
    752 }
    753
    754 if( success )
    755 {
    756 SCIPdebugMsg(scip, "coupling constraint:\n");
    757 SCIPdebugPrintCons(scip, lincons, NULL);
    758 SCIP_CALL( SCIPaddCons(scip, lincons) );
    759 SCIP_CALL( SCIPreleaseCons(scip, &lincons) );
    760 }
    761 else
    762 {
    763 SCIPwarningMessage(scip, "Could not read (multi-)aggregated variable <%s>: dependent variables unkown - consider changing the order (line: %d):\n%s\n",
    764 SCIPvarGetName(var), cipinput->linenumber, buf);
    765 }
    766 }
    767 else
    768 {
    769 SCIPerrorMessage("unknown section when parsing variables (line: %d):\n%s\n", cipinput->linenumber, buf);
    770 cipinput->haserror = TRUE;
    771 return SCIP_OKAY;
    772 }
    773 SCIP_CALL( SCIPreleaseVar(scip, &var) );
    774
    775 return SCIP_OKAY;
    776}
    777
    778/** read constraint */
    779static
    781 SCIP* scip, /**< SCIP data structure */
    782 CIPINPUT* cipinput, /**< CIP parsing data */
    783 SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
    784 * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
    785 SCIP_Bool dynamic, /**< Is constraint subject to aging?
    786 * Usually set to FALSE. Set to TRUE for own cuts which
    787 * are separated as constraints. */
    788 SCIP_Bool removable /**< should the relaxation be removed from the LP due to aging or cleanup?
    789 * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
    790 )
    791{
    792 SCIP_CONS* cons;
    793 char* buf;
    794 char* copybuf;
    795 SCIP_RETCODE retcode;
    797 SCIP_Bool enforce;
    798 SCIP_Bool check;
    799 SCIP_Bool propagate;
    800 SCIP_Bool local;
    801 SCIP_Bool modifiable;
    802 SCIP_Bool success;
    803 int len;
    804
    805 buf = cipinput->strbuf;
    806
    807 if( strncmp(buf, "END", 3) == 0 )
    808 {
    809 cipinput->section = CIP_END;
    810 return SCIP_OKAY;
    811 }
    812
    813 SCIPdebugMsg(scip, "parse constraints in line %d\n", cipinput->linenumber);
    814
    815 separate = TRUE;
    816 enforce = TRUE;
    817 check = TRUE;
    818 propagate = TRUE;
    819 local = FALSE;
    820 modifiable = FALSE;
    821
    822 /* get length of line and check for correct ending of constraint line */
    823 len = (int)strlen(buf);
    824 if( len < 1 )
    825 {
    826 SCIPerrorMessage("syntax error: expected constraint in line %d.\n", cipinput->linenumber);
    827 cipinput->haserror = TRUE;
    828 return SCIP_OKAY;
    829 }
    830 if ( buf[len - 1] != ';' )
    831 {
    832 SCIPerrorMessage("syntax error: line has to end with ';' (line: %d)\n", cipinput->linenumber);
    833 cipinput->haserror = TRUE;
    834 return SCIP_OKAY;
    835 }
    836
    837 /* copy buffer for working purpose */
    838 SCIP_CALL( SCIPduplicateBufferArray(scip, &copybuf, buf, len) );
    839 copybuf[len - 1] = '\0';
    840
    841 /* parse the constraint */
    842 retcode = SCIPparseCons(scip, &cons, copybuf,
    843 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE, &success);
    844
    845 /* free temporary buffer */
    846 SCIPfreeBufferArray(scip, &copybuf);
    847
    848 SCIP_CALL( retcode );
    849
    850 if( !success )
    851 {
    852 SCIPerrorMessage("syntax error when reading constraint (line: %d):\n%s\n", cipinput->linenumber, cipinput->strbuf);
    853 cipinput->haserror = TRUE;
    854 return SCIP_OKAY;
    855 }
    856
    857 SCIP_CALL( SCIPaddCons(scip, cons) );
    859 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
    860
    861 return SCIP_OKAY;
    862}
    863
    864/*
    865 * Callback methods of reader
    866 */
    867
    868/** copy method for reader plugins (called when SCIP copies plugins) */
    869static
    871{ /*lint --e{715}*/
    872 assert(scip != NULL);
    873 assert(reader != NULL);
    874 assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
    875
    876 /* call inclusion method of reader */
    878
    879 return SCIP_OKAY;
    880}
    881
    882/** destructor of reader to free user data (called when SCIP is exiting) */
    883static
    885{
    886 SCIP_READERDATA* readerdata;
    887
    888 assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
    889 readerdata = SCIPreaderGetData(reader);
    890 assert(readerdata != NULL);
    891 SCIPfreeBlockMemory(scip, &readerdata);
    892
    893 return SCIP_OKAY;
    894}
    895
    896
    897/** problem reading method of reader */
    898static
    900{ /*lint --e{715}*/
    901 CIPINPUT cipinput;
    902 SCIP_Bool initialconss;
    903 SCIP_Bool dynamicconss;
    904 SCIP_Bool dynamiccols;
    905 SCIP_Bool dynamicrows;
    906 SCIP_Bool initialvar;
    907 SCIP_Bool removablevar;
    908 SCIP_RETCODE retcode = SCIP_OKAY;
    909
    910 if( NULL == (cipinput.file = SCIPfopen(filename, "r")) )
    911 {
    912 SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
    913 SCIPprintSysError(filename);
    914 return SCIP_NOFILE;
    915 }
    916
    917 cipinput.len = 131071;
    918 SCIP_CALL( SCIPallocBufferArray(scip, &(cipinput.strbuf), cipinput.len) );
    919
    920 cipinput.linenumber = 0;
    921 cipinput.section = CIP_START;
    922 cipinput.haserror = FALSE;
    923 cipinput.endfile = FALSE;
    924 cipinput.readingsize = 65535;
    925 cipinput.objoffset = 0.0;
    926 cipinput.objscale = 1.0;
    927 if( SCIPisExact(scip) )
    928 {
    929 SCIP_CALL( SCIPrationalCreateBuffer(SCIPbuffer(scip), &cipinput.objoffsetexact) );
    930 SCIP_CALL( SCIPrationalCreateBuffer(SCIPbuffer(scip), &cipinput.objscaleexact) );
    931
    932 SCIPrationalSetReal(cipinput.objoffsetexact, 0.0);
    933 SCIPrationalSetReal(cipinput.objscaleexact, 1.0);
    934 }
    935 else
    936 {
    937 cipinput.objoffsetexact = NULL;
    938 cipinput.objscaleexact = NULL;
    939 }
    940
    941 SCIP_CALL_TERMINATE( retcode, SCIPcreateProb(scip, filename, NULL, NULL, NULL, NULL, NULL, NULL, NULL), TERMINATE );
    942
    943 SCIP_CALL_TERMINATE( retcode, SCIPgetBoolParam(scip, "reading/initialconss", &initialconss), TERMINATE );
    944 SCIP_CALL_TERMINATE( retcode, SCIPgetBoolParam(scip, "reading/dynamiccols", &dynamiccols), TERMINATE );
    945 SCIP_CALL_TERMINATE( retcode, SCIPgetBoolParam(scip, "reading/dynamicconss", &dynamicconss), TERMINATE );
    946 SCIP_CALL_TERMINATE( retcode, SCIPgetBoolParam(scip, "reading/dynamicrows", &dynamicrows), TERMINATE );
    947
    948 initialvar = !dynamiccols;
    949 removablevar = dynamiccols;
    950
    951 while( cipinput.section != CIP_END && !cipinput.haserror )
    952 {
    953 /* get next input string */
    954 SCIP_CALL_TERMINATE( retcode, getInputString(scip, &cipinput), TERMINATE );
    955
    956 if( cipinput.endfile )
    957 break;
    958
    959 switch( cipinput.section )
    960 {
    961 case CIP_START:
    962 getStart(scip, &cipinput);
    963 break;
    964 case CIP_STATISTIC:
    965 SCIP_CALL_TERMINATE( retcode, getStatistics(scip, &cipinput), TERMINATE );
    966 break;
    967 case CIP_OBJECTIVE:
    968 SCIP_CALL_TERMINATE( retcode, getObjective(scip, &cipinput), TERMINATE );
    969 break;
    970 case CIP_VARS:
    971 SCIP_CALL_TERMINATE( retcode, getVariable(scip, &cipinput, initialvar, removablevar), TERMINATE );
    972 break;
    973 case CIP_FIXEDVARS:
    974 SCIP_CALL_TERMINATE( retcode, getFixedVariable(scip, &cipinput), TERMINATE );
    975 break;
    976 case CIP_CONSTRAINTS:
    977 SCIP_CALL_TERMINATE( retcode, getConstraint(scip, &cipinput, initialconss, dynamicconss, dynamicrows), TERMINATE );
    978 break;
    979 default:
    980 SCIPerrorMessage("invalid CIP state\n");
    981 SCIPABORT();
    982 retcode = SCIP_INVALIDDATA; /*lint !e527*/
    983 goto TERMINATE;
    984 } /*lint !e788*/
    985 }
    986
    987 if( cipinput.haserror )
    988 goto TERMINATE;
    989
    990 /* offset exact objective */
    991 if( cipinput.objoffsetexact != NULL )
    992 {
    993 if( !SCIPrationalIsZero(cipinput.objoffsetexact) )
    994 {
    995 SCIPrationalMult(cipinput.objoffsetexact, cipinput.objoffsetexact, cipinput.objscaleexact);
    996 SCIP_CALL_TERMINATE( retcode, SCIPaddOrigObjoffsetExact(scip, cipinput.objoffsetexact), TERMINATE );
    997 }
    998 }
    999 /* offset real objective */
    1000 else
    1001 {
    1002 if( cipinput.objoffset != 0.0 ) /*lint !e777*/
    1003 {
    1004 cipinput.objoffset *= cipinput.objscale;
    1005 SCIP_CALL_TERMINATE( retcode, SCIPaddOrigObjoffset(scip, cipinput.objoffset), TERMINATE );
    1006 }
    1007 }
    1008
    1009 if( cipinput.section != CIP_END )
    1010 {
    1011 SCIPerrorMessage("unexpected EOF\n");
    1012 cipinput.haserror = TRUE;
    1013 }
    1014
    1015 TERMINATE:
    1016 /* close file stream */
    1017 SCIPfclose(cipinput.file);
    1018
    1019 if( cipinput.objscaleexact != NULL )
    1020 SCIPrationalFreeBuffer(SCIPbuffer(scip), &cipinput.objscaleexact);
    1021 if( cipinput.objoffsetexact != NULL )
    1022 SCIPrationalFreeBuffer(SCIPbuffer(scip), &cipinput.objoffsetexact);
    1023 SCIPfreeBufferArray(scip, &cipinput.strbuf);
    1024
    1025 if( cipinput.haserror || retcode == SCIP_INVALIDDATA )
    1026 return SCIP_READERROR;
    1027
    1028 /* successfully parsed cip format */
    1029 if( retcode == SCIP_OKAY )
    1030 *result = SCIP_SUCCESS;
    1031
    1032 return retcode;
    1033}
    1034
    1035/** hash key retrieval function for variables */
    1036static
    1038{ /*lint --e{715}*/
    1039 return elem;
    1040}
    1041
    1042/** returns TRUE iff the indices of both variables are equal */
    1043static
    1045{ /*lint --e{715}*/
    1046 if( key1 == key2 )
    1047 return TRUE;
    1048 return FALSE;
    1049}
    1050
    1051/** returns the hash value of the key */
    1052static
    1054{ /*lint --e{715}*/
    1055 assert( SCIPvarGetIndex((SCIP_VAR*) key) >= 0 );
    1056 return (unsigned int) SCIPvarGetIndex((SCIP_VAR*) key);
    1057}
    1058
    1059/** problem writing method of reader */
    1060static
    1062{ /*lint --e{715}*/
    1063 SCIP_HASHTABLE* varhash = NULL;
    1064 SCIP_READERDATA* readerdata;
    1065 int i;
    1066
    1067 assert(reader != NULL);
    1068 assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
    1069
    1070 SCIPinfoMessage(scip, file, "STATISTICS\n");
    1071 SCIPinfoMessage(scip, file, " Problem name : %s\n", name);
    1072 SCIPinfoMessage(scip, file, " Variables : %d (%d binary, %d integer, %d implicit integer, %d continuous)\n",
    1073 nvars, nbinvars, nintvars, nimplvars, ncontvars);
    1074 SCIPinfoMessage(scip, file, " Constraints : %d initial, %d maximal\n", startnconss, maxnconss);
    1075
    1076 SCIPinfoMessage(scip, file, "OBJECTIVE\n");
    1077 SCIPinfoMessage(scip, file, " Sense : %s\n", objsense == SCIP_OBJSENSE_MINIMIZE ? "minimize" : "maximize");
    1078 /* write exact offset */
    1079 if( objoffsetexact != NULL )
    1080 {
    1081 assert(SCIPisExact(scip));
    1082
    1083 if( !SCIPrationalIsZero(objoffsetexact) )
    1084 {
    1085 SCIPinfoMessage(scip, file, " Offset : ");
    1086 SCIPrationalMessage(SCIPgetMessagehdlr(scip), file, objoffsetexact);
    1087 SCIPinfoMessage(scip, file, "\n");
    1088 }
    1089 }
    1090 /* write real offset */
    1091 else
    1092 {
    1093 if( objoffset != 0.0 ) /*lint !e777*/
    1094 SCIPinfoMessage(scip, file, " Offset : %+.15g\n", objoffset);
    1095 }
    1096 /* write exact scale */
    1097 if( objscaleexact != NULL )
    1098 {
    1099 assert(SCIPisExact(scip));
    1100
    1101 if( !SCIPrationalIsEQReal(objscaleexact, 1.0) )
    1102 {
    1103 SCIPinfoMessage(scip, file, " Scale : ");
    1104 SCIPrationalMessage(SCIPgetMessagehdlr(scip), file, objscaleexact);
    1105 SCIPinfoMessage(scip, file, "\n");
    1106 }
    1107 }
    1108 /* write real scale */
    1109 else
    1110 {
    1111 if( objscale != 1.0 ) /*lint !e777*/
    1112 SCIPinfoMessage(scip, file, " Scale : %.15g\n", objscale);
    1113 }
    1114
    1115 if ( nfixedvars > 0 )
    1116 {
    1117 /* set up hash table for variables that have been written property (used for writing out fixed vars in the right order) */
    1118 SCIP_CALL( SCIPhashtableCreate(&varhash, SCIPblkmem(scip), nvars + nfixedvars, hashGetKeyVar, hashKeyEqVar, hashKeyValVar, NULL) );
    1119 }
    1120
    1121 if ( nvars + nfixedvars > 0 )
    1122 {
    1123 SCIPinfoMessage(scip, file, "VARIABLES\n");
    1124 }
    1125
    1126 if( nvars > 0 )
    1127 {
    1128 for( i = 0; i < nvars; ++i )
    1129 {
    1130 SCIP_VAR* var;
    1131
    1132 var = vars[i];
    1133 assert( var != NULL );
    1134 SCIP_CALL( SCIPprintVar(scip, var, file) );
    1135 if ( varhash != NULL )
    1136 {
    1137 /* add free variable to hashtable */
    1138 if ( ! SCIPhashtableExists(varhash, (void*) var) )
    1139 {
    1140 SCIP_CALL( SCIPhashtableInsert(varhash, (void*) var) );
    1141 }
    1142 }
    1143 }
    1144 }
    1145
    1146 readerdata = SCIPreaderGetData(reader);
    1147 assert(readerdata != NULL);
    1148
    1149 if( readerdata->writefixedvars && nfixedvars > 0 )
    1150 {
    1151 int nwritten = 0;
    1152
    1153 SCIPinfoMessage(scip, file, "FIXED\n");
    1154
    1155 /* loop through variables until each has been written after the variables that it depends on have been written; this
    1156 * requires several runs over the variables, but the depth (= number of loops) is usually small. */
    1157 while ( nwritten < nfixedvars )
    1158 {
    1159 SCIPdebugMsg(scip, "written %d of %d fixed variables.\n", nwritten, nfixedvars);
    1160 for (i = 0; i < nfixedvars; ++i)
    1161 {
    1162 SCIP_VAR* var;
    1163 SCIP_VAR* tmpvar;
    1164
    1165 var = fixedvars[i];
    1166 assert( var != NULL );
    1167
    1168 /* skip variables already written */
    1169 if ( SCIPhashtableExists(varhash, (void*) var) )
    1170 continue;
    1171
    1172 switch ( SCIPvarGetStatus(var) )
    1173 {
    1175
    1176 /* fixed variables can simply be output and added to the hashtable */
    1177 SCIP_CALL( SCIPprintVar(scip, var, file) );
    1178 assert( ! SCIPhashtableExists(varhash, (void*) var) );
    1179 SCIP_CALL( SCIPhashtableInsert(varhash, (void*) var) );
    1180 ++nwritten;
    1181
    1182 break;
    1183
    1185
    1186 tmpvar = SCIPvarGetNegationVar(var);
    1187 assert( tmpvar != NULL );
    1188 assert( var == SCIPvarGetNegatedVar(tmpvar) );
    1189
    1190 /* if the negated variable has been written, we can write the current variable */
    1191 if ( SCIPhashtableExists(varhash, (void*) tmpvar) )
    1192 {
    1193 SCIP_CALL( SCIPprintVar(scip, var, file) );
    1194 assert( ! SCIPhashtableExists(varhash, (void*) var) );
    1195 SCIP_CALL( SCIPhashtableInsert(varhash, (void*) var) );
    1196 ++nwritten;
    1197 }
    1198 break;
    1199
    1201
    1202 tmpvar = SCIPvarGetAggrVar(var);
    1203 assert( tmpvar != NULL );
    1204
    1205 /* if the aggregating variable has been written, we can write the current variable */
    1206 if ( SCIPhashtableExists(varhash, (void*) tmpvar) )
    1207 {
    1208 SCIP_CALL( SCIPprintVar(scip, var, file) );
    1209 assert( ! SCIPhashtableExists(varhash, (void*) var) );
    1210 SCIP_CALL( SCIPhashtableInsert(varhash, (void*) var) );
    1211 ++nwritten;
    1212 }
    1213 break;
    1214
    1216 {
    1217 SCIP_VAR** aggrvars;
    1218 int naggrvars;
    1219 int j;
    1220
    1221 /* get the active representation */
    1223
    1224 naggrvars = SCIPvarGetMultaggrNVars(var);
    1225 aggrvars = SCIPvarGetMultaggrVars(var);
    1226 assert(aggrvars != NULL || naggrvars == 0);
    1227
    1228 for (j = 0; j < naggrvars; ++j)
    1229 {
    1230 if( !SCIPhashtableExists(varhash, (void*) aggrvars[j]) ) /*lint !e613*/
    1231 break;
    1232 }
    1233
    1234 /* if all multi-aggregating variables have been written, we can write the current variable */
    1235 if ( j >= naggrvars )
    1236 {
    1237 SCIP_CALL( SCIPprintVar(scip, var, file) );
    1238 assert( ! SCIPhashtableExists(varhash, (void*) var) );
    1239 SCIP_CALL( SCIPhashtableInsert(varhash, (void*) var) );
    1240 ++nwritten;
    1241 }
    1242 break;
    1243 }
    1244
    1248 SCIPerrorMessage("Only fixed variables are allowed to be present in fixedvars list.\n");
    1249 SCIPABORT();
    1250 return SCIP_ERROR; /*lint !e527*/
    1251 }
    1252 }
    1253 }
    1254 }
    1255
    1256 if( nconss > 0 )
    1257 {
    1258 SCIPinfoMessage(scip, file, "CONSTRAINTS\n");
    1259
    1260 for( i = 0; i < nconss; ++i )
    1261 {
    1262 SCIP_CALL( SCIPprintCons(scip, conss[i], file) );
    1263 SCIPinfoMessage(scip, file, ";\n");
    1264 }
    1265 }
    1266 SCIPinfoMessage(scip, file, "END\n");
    1267
    1268 *result = SCIP_SUCCESS;
    1269
    1270 if( nfixedvars > 0 )
    1271 SCIPhashtableFree(&varhash);
    1272 else
    1273 assert(varhash == NULL);
    1274
    1275 return SCIP_OKAY;
    1276}
    1277
    1278
    1279/*
    1280 * reader specific interface methods
    1281 */
    1282
    1283/** includes the cip file reader in SCIP */
    1285 SCIP* scip /**< SCIP data structure */
    1286 )
    1287{
    1288 SCIP_READERDATA* readerdata;
    1289 SCIP_READER* reader;
    1290
    1291 /* create cip reader data */
    1292 SCIP_CALL( SCIPallocBlockMemory(scip, &readerdata) );
    1293
    1294 /* include reader */
    1296
    1297 /* reader is safe to use in exact solving mode */
    1298 SCIPreaderMarkExact(reader);
    1299
    1300 /* set non fundamental callbacks via setter functions */
    1301 SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopyCip) );
    1302 SCIP_CALL( SCIPsetReaderFree(scip, reader, readerFreeCip) );
    1303 SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadCip) );
    1304 SCIP_CALL( SCIPsetReaderWrite(scip, reader, readerWriteCip) );
    1305
    1306 /* add cip reader parameters */
    1308 "reading/cipreader/writefixedvars", "should fixed and aggregated variables be printed (if not, re-parsing might fail)",
    1309 &readerdata->writefixedvars, FALSE, DEFAULT_CIP_WRITEFIXEDVARS, NULL, NULL) );
    1310
    1311 return SCIP_OKAY;
    1312}
    Constraint handler for linear constraints in their most general form, .
    Constraint handler for linear constraints in their most general form, .
    #define NULL
    Definition: def.h:248
    #define SCIP_MAXSTRLEN
    Definition: def.h:269
    #define SCIP_Bool
    Definition: def.h:91
    #define SCIP_Real
    Definition: def.h:156
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define SCIP_CALL_TERMINATE(retcode, x, TERM)
    Definition: def.h:376
    #define SCIPABORT()
    Definition: def.h:327
    #define SCIP_CALL(x)
    Definition: def.h:355
    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
    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_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_RETCODE SCIPincludeReaderCip(SCIP *scip)
    Definition: reader_cip.c:1284
    SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
    Definition: scip_prob.c:1907
    SCIP_RETCODE SCIPsetProbName(SCIP *scip, const char *name)
    Definition: scip_prob.c:1270
    SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_prob.c:3274
    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_RETCODE SCIPaddOrigObjoffsetExact(SCIP *scip, SCIP_RATIONAL *addval)
    Definition: scip_prob.c:1465
    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
    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
    SCIP_MESSAGEHDLR * SCIPgetMessagehdlr(SCIP *scip)
    Definition: scip_message.c:88
    #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 SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
    Definition: scip_cons.c:2536
    SCIP_RETCODE SCIPparseCons(SCIP *scip, SCIP_CONS **cons, const char *str, 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_Bool *success)
    Definition: scip_cons.c:1081
    SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
    Definition: scip_cons.c:1173
    SCIP_Bool SCIPisExact(SCIP *scip)
    Definition: scip_exact.c:193
    BMS_BLKMEM * SCIPblkmem(SCIP *scip)
    Definition: scip_mem.c:57
    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 SCIPfreeBlockMemory(scip, ptr)
    Definition: scip_mem.h:108
    #define SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    void SCIPrationalMult(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:1066
    #define SCIPrationalDebugMessage
    Definition: rational.h:641
    void SCIPrationalSetReal(SCIP_RATIONAL *res, SCIP_Real real)
    Definition: rational.cpp:603
    void SCIPrationalFreeBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
    Definition: rational.cpp:473
    SCIP_RETCODE SCIPrationalCreateBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
    Definition: rational.cpp:123
    SCIP_Bool SCIPrationalIsZero(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1624
    void SCIPrationalMessage(SCIP_MESSAGEHDLR *msg, FILE *file, SCIP_RATIONAL *rational)
    Definition: rational.cpp:1790
    SCIP_Bool SCIPrationalIsEQReal(SCIP_RATIONAL *rat, SCIP_Real real)
    Definition: rational.cpp:1437
    SCIP_RETCODE SCIPrationalCreateBufferArray(BMS_BUFMEM *mem, SCIP_RATIONAL ***rational, int size)
    Definition: rational.cpp:214
    SCIP_RETCODE SCIPrationalReallocBufferArray(BMS_BUFMEM *mem, SCIP_RATIONAL ***result, int oldlen, int newlen)
    Definition: rational.cpp:314
    void SCIPrationalMultReal(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_Real op2)
    Definition: rational.cpp:1097
    void SCIPrationalFreeBufferArray(BMS_BUFMEM *mem, SCIP_RATIONAL ***ratbufarray, int size)
    Definition: rational.cpp:518
    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:605
    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:680
    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:670
    SCIP_RETCODE SCIPsetReaderWrite(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERWRITE((*readerwrite)))
    Definition: scip_reader.c:219
    SCIP_Bool SCIPparseRational(SCIP *scip, const char *str, SCIP_RATIONAL *value, char **endptr)
    SCIP_Bool SCIPparseReal(SCIP *scip, const char *str, SCIP_Real *value, char **endptr)
    SCIP_VAR * SCIPvarGetNegatedVar(SCIP_VAR *var)
    Definition: var.c:23868
    SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
    Definition: var.c:23478
    SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
    Definition: var.c:23386
    SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
    Definition: var.c:23900
    SCIP_RETCODE SCIPparseVarName(SCIP *scip, const char *str, SCIP_VAR **var, char **endptr)
    Definition: scip_var.c:728
    SCIP_RETCODE SCIPparseVar(SCIP *scip, SCIP_VAR **var, const char *str, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARCOPY((*varcopy)), SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_VARDATA *vardata, char **endptr, SCIP_Bool *success)
    Definition: scip_var.c:669
    int SCIPvarGetIndex(SCIP_VAR *var)
    Definition: var.c:23652
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23267
    SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
    Definition: scip_var.c:1887
    SCIP_RETCODE SCIPparseVarsLinearsum(SCIP *scip, const char *str, SCIP_VAR **vars, SCIP_Real *vals, int *nvars, int varssize, int *requiredsize, char **endptr, SCIP_Bool *success)
    Definition: scip_var.c:899
    SCIP_RETCODE SCIPparseVarsLinearsumExact(SCIP *scip, char *str, SCIP_VAR **vars, SCIP_RATIONAL **vals, int *nvars, int varssize, int *requiredsize, char **endptr, SCIP_Bool *success)
    Definition: scip_var.c:1007
    SCIP_RETCODE SCIPflattenVarAggregationGraph(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:2332
    SCIP_VAR ** SCIPvarGetMultaggrVars(SCIP_VAR *var)
    Definition: var.c:23806
    int SCIPvarGetMultaggrNVars(SCIP_VAR *var)
    Definition: var.c:23794
    SCIP_VAR * SCIPvarGetNegationVar(SCIP_VAR *var)
    Definition: var.c:23878
    SCIP_RETCODE SCIPprintVar(SCIP *scip, SCIP_VAR *var, FILE *file)
    Definition: scip_var.c:12465
    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_RATIONAL * SCIPvarGetObjExact(SCIP_VAR *var)
    Definition: var.c:23910
    SCIP_VAR * SCIPvarGetAggrVar(SCIP_VAR *var)
    Definition: var.c:23736
    int SCIPsnprintf(char *t, int len, const char *s,...)
    Definition: misc.c:10827
    void SCIPprintSysError(const char *message)
    Definition: misc.c:10719
    SCIP_RETCODE SCIPskipSpace(char **s)
    Definition: misc.c:10816
    int SCIPstrncasecmp(const char *s1, const char *s2, int length)
    Definition: misc.c:10876
    memory allocation routines
    #define BMSclearMemoryArray(ptr, num)
    Definition: memory.h:130
    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 SCIPdebug(x)
    Definition: pub_message.h:93
    #define SCIPdebugPrintCons(x, y, z)
    Definition: pub_message.h:102
    public data structures and miscellaneous methods
    public methods for input file readers
    public methods for problem variables
    wrapper for rational number arithmetic
    static SCIP_RETCODE getObjective(SCIP *scip, CIPINPUT *cipinput)
    Definition: reader_cip.c:278
    static SCIP_RETCODE getConstraint(SCIP *scip, CIPINPUT *cipinput, SCIP_Bool initial, SCIP_Bool dynamic, SCIP_Bool removable)
    Definition: reader_cip.c:780
    enum CipSection CIPSECTION
    Definition: reader_cip.c:82
    static SCIP_DECL_READERFREE(readerFreeCip)
    Definition: reader_cip.c:884
    static SCIP_RETCODE getInputString(SCIP *scip, CIPINPUT *cipinput)
    Definition: reader_cip.c:114
    static SCIP_DECL_HASHGETKEY(hashGetKeyVar)
    Definition: reader_cip.c:1037
    static SCIP_RETCODE getVariable(SCIP *scip, CIPINPUT *cipinput, SCIP_Bool initial, SCIP_Bool removable)
    Definition: reader_cip.c:428
    #define READER_DESC
    Definition: reader_cip.c:58
    static void getStart(SCIP *scip, CIPINPUT *cipinput)
    Definition: reader_cip.c:200
    static SCIP_DECL_READERCOPY(readerCopyCip)
    Definition: reader_cip.c:870
    CipSection
    Definition: reader_cip.c:73
    @ CIP_CONSTRAINTS
    Definition: reader_cip.c:79
    @ CIP_VARS
    Definition: reader_cip.c:77
    @ CIP_START
    Definition: reader_cip.c:74
    @ CIP_OBJECTIVE
    Definition: reader_cip.c:76
    @ CIP_FIXEDVARS
    Definition: reader_cip.c:78
    @ CIP_STATISTIC
    Definition: reader_cip.c:75
    @ CIP_END
    Definition: reader_cip.c:80
    static SCIP_DECL_READERREAD(readerReadCip)
    Definition: reader_cip.c:899
    static SCIP_RETCODE getStatistics(SCIP *scip, CIPINPUT *cipinput)
    Definition: reader_cip.c:227
    #define READER_EXTENSION
    Definition: reader_cip.c:59
    #define DEFAULT_CIP_WRITEFIXEDVARS
    Definition: reader_cip.c:61
    static SCIP_DECL_READERWRITE(readerWriteCip)
    Definition: reader_cip.c:1061
    #define READER_NAME
    Definition: reader_cip.c:57
    static SCIP_DECL_HASHKEYEQ(hashKeyEqVar)
    Definition: reader_cip.c:1044
    static SCIP_DECL_HASHKEYVAL(hashKeyValVar)
    Definition: reader_cip.c:1053
    struct CipInput CIPINPUT
    Definition: reader_cip.c:105
    static SCIP_RETCODE getFixedVariable(SCIP *scip, CIPINPUT *cipinput)
    Definition: reader_cip.c:499
    CIP 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 SCIP variables
    static SCIP_RETCODE separate(SCIP *scip, SCIP_SEPA *sepa, SCIP_SOL *sol, SCIP_RESULT *result)
    Main separation function.
    Definition: sepa_flower.c:1221
    @ 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
    @ SCIP_NOFILE
    Definition: type_retcode.h:47
    @ SCIP_READERROR
    Definition: type_retcode.h:45
    @ SCIP_INVALIDDATA
    Definition: type_retcode.h:52
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_ERROR
    Definition: type_retcode.h:43
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_VARSTATUS_ORIGINAL
    Definition: type_var.h:51
    @ SCIP_VARSTATUS_FIXED
    Definition: type_var.h:54
    @ SCIP_VARSTATUS_COLUMN
    Definition: type_var.h:53
    @ 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_VARSTATUS_LOOSE
    Definition: type_var.h:52