Scippy

SCIP

Solving Constraint Integer Programs

reader_pip.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_pip.c
26 * @ingroup DEFPLUGINS_READER
27 * @brief file reader for polynomial mixed-integer programs in PIP format
28 * @author Stefan Vigerske
29 * @author Marc Pfetsch
30 */
31
32/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
33
34#include <ctype.h>
35
37#include "scip/reader_pip.h"
38#include "scip/cons_and.h"
39#include "scip/cons_nonlinear.h"
40#include "scip/cons_knapsack.h"
41#include "scip/cons_linear.h"
42#include "scip/cons_logicor.h"
43#include "scip/cons_setppc.h"
44#include "scip/cons_varbound.h"
45#include "scip/expr_sum.h"
46#include "scip/expr_var.h"
47#include "scip/pub_cons.h"
48#include "scip/pub_expr.h"
49#include "scip/pub_fileio.h"
50#include "scip/pub_message.h"
51#include "scip/pub_misc.h"
52#include "scip/pub_nlp.h"
53#include "scip/pub_reader.h"
54#include "scip/pub_var.h"
55#include "scip/scip_cons.h"
56#include "scip/scip_mem.h"
57#include "scip/scip_message.h"
58#include "scip/scip_numerics.h"
59#include "scip/scip_param.h"
60#include "scip/scip_prob.h"
61#include "scip/scip_reader.h"
62#include "scip/scip_var.h"
63#include <stdlib.h>
64#include <string.h>
65#include <ctype.h>
66
67#define READER_NAME "pipreader"
68#define READER_DESC "file reader for polynomial mixed-integer programs in PIP format"
69#define READER_EXTENSION "pip"
70
71
72/*
73 * Data structures
74 */
75#define PIP_MAX_LINELEN 65536
76#define PIP_MAX_PUSHEDTOKENS 2
77#define PIP_INIT_MONOMIALSSIZE 128
78#define PIP_INIT_FACTORSSIZE 16
79#define PIP_MAX_PRINTLEN 561 /**< the maximum length of any line is 560 + '\\0' = 561*/
80#define PIP_MAX_NAMELEN 256 /**< the maximum length for any name is 255 + '\\0' = 256 */
81#define PIP_PRINTLEN 100
82
83/** Section in PIP File */
85{
93};
95
97{
103
105{
111typedef enum PipSense PIPSENSE;
112
113/** PIP reading data */
114struct PipInput
115{
116 SCIP_FILE* file;
117 char linebuf[PIP_MAX_LINELEN+1];
118 char probname[PIP_MAX_LINELEN];
119 char objname[PIP_MAX_LINELEN];
120 char* token;
121 char* tokenbuf;
122 char* pushedtokens[PIP_MAX_PUSHEDTOKENS];
123 int npushedtokens;
124 int linenumber;
125 int linepos;
126 PIPSECTION section;
127 SCIP_OBJSENSE objsense;
128 SCIP_Bool initialconss; /**< should model constraints be marked as initial? */
129 SCIP_Bool dynamicconss; /**< should model constraints be subject to aging? */
130 SCIP_Bool dynamiccols; /**< should columns be added and removed dynamically to the LP? */
131 SCIP_Bool dynamicrows; /**< should rows be added and removed dynamically to the LP? */
132 SCIP_Bool haserror;
133};
134typedef struct PipInput PIPINPUT;
135
136static const char delimchars[] = " \f\n\r\t\v";
137static const char tokenchars[] = "-+:<>=*^";
138static const char commentchars[] = "\\";
139static const char namechars[] = "!#$%&;?@_"; /* and characters and numbers */
140
141
142/*
143 * Local methods (for reading)
144 */
145
146/** issues an error message and marks the PIP data to have errors */
147static
149 SCIP* scip, /**< SCIP data structure */
150 PIPINPUT* pipinput, /**< PIP reading data */
151 const char* msg /**< error message */
152 )
153{
154 char formatstr[256];
155
156 assert(pipinput != NULL);
157
158 SCIPerrorMessage("Syntax error in line %d: %s ('%s')\n", pipinput->linenumber, msg, pipinput->token);
159 if( pipinput->linebuf[strlen(pipinput->linebuf)-1] == '\n' )
160 {
161 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, " input: %s", pipinput->linebuf);
162 }
163 else
164 {
165 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, " input: %s\n", pipinput->linebuf);
166 }
167 (void) SCIPsnprintf(formatstr, 256, " %%%ds\n", pipinput->linepos);
169 pipinput->section = PIP_END;
170 pipinput->haserror = TRUE;
171}
172
173/** returns whether a syntax error was detected */
174static
176 PIPINPUT* pipinput /**< PIP reading data */
177 )
178{
179 assert(pipinput != NULL);
180
181 return pipinput->haserror;
182}
183
184/** returns whether the given character is a token delimiter */
185static
187 char c /**< input character */
188 )
189{
190 return (c == '\0') || (strchr(delimchars, c) != NULL);
191}
192
193/** returns whether the given character is a single token */
194static
196 char c /**< input character */
197 )
198{
199 return (strchr(tokenchars, c) != NULL);
200}
201
202/** returns whether the current character is member of a value string */
203static
205 char c, /**< input character */
206 char nextc, /**< next input character */
207 SCIP_Bool firstchar, /**< is the given character the first char of the token? */
208 SCIP_Bool* hasdot, /**< pointer to update the dot flag */
209 PIPEXPTYPE* exptype /**< pointer to update the exponent type */
210 )
211{
212 assert(hasdot != NULL);
213 assert(exptype != NULL);
214
215 if( isdigit((unsigned char)c) )
216 return TRUE;
217 else if( (*exptype == PIP_EXP_NONE) && !(*hasdot) && (c == '.') && isdigit((unsigned char)nextc) )
218 {
219 *hasdot = TRUE;
220 return TRUE;
221 }
222 else if( !firstchar && (*exptype == PIP_EXP_NONE) && (c == 'e' || c == 'E') )
223 {
224 if( nextc == '+' || nextc == '-' )
225 {
226 *exptype = PIP_EXP_SIGNED;
227 return TRUE;
228 }
229 else if( isdigit((unsigned char)nextc) )
230 {
231 *exptype = PIP_EXP_UNSIGNED;
232 return TRUE;
233 }
234 }
235 else if( (*exptype == PIP_EXP_SIGNED) && (c == '+' || c == '-') )
236 {
237 *exptype = PIP_EXP_UNSIGNED;
238 return TRUE;
239 }
240
241 return FALSE;
242}
243
244/** reads the next line from the input file into the line buffer; skips comments;
245 * returns whether a line could be read
246 */
247static
249 SCIP* scip, /**< SCIP data structure */
250 PIPINPUT* pipinput /**< PIP reading data */
251 )
252{
253 int i;
254
255 assert(scip != NULL); /* for lint */
256 assert(pipinput != NULL);
257
258 /* clear the line */
259 BMSclearMemoryArray(pipinput->linebuf, PIP_MAX_LINELEN);
260
261 /* read next line */
262 pipinput->linepos = 0;
263 pipinput->linebuf[PIP_MAX_LINELEN-2] = '\0';
264 if( SCIPfgets(pipinput->linebuf, (int) sizeof(pipinput->linebuf), pipinput->file) == NULL )
265 return FALSE;
266 pipinput->linenumber++;
267 if( pipinput->linebuf[PIP_MAX_LINELEN-2] != '\0' )
268 {
269 SCIPerrorMessage("Error: line %d exceeds %d characters\n", pipinput->linenumber, PIP_MAX_LINELEN-2);
270 pipinput->haserror = TRUE;
271 return FALSE;
272 }
273 pipinput->linebuf[PIP_MAX_LINELEN-1] = '\0'; /* we want to use lookahead of one char -> we need two \0 at the end */
274
275 /* skip characters after comment symbol */
276 for( i = 0; commentchars[i] != '\0'; ++i )
277 {
278 char* commentstart;
279
280 commentstart = strchr(pipinput->linebuf, commentchars[i]);
281 if( commentstart != NULL )
282 {
283 *commentstart = '\0';
284 *(commentstart+1) = '\0'; /* we want to use lookahead of one char -> we need two \0 at the end */
285 }
286 }
287
288 return TRUE;
289}
290
291/** swaps the addresses of two pointers */
292static
294 char** pointer1, /**< first pointer */
295 char** pointer2 /**< second pointer */
296 )
297{
298 char* tmp;
299
300 tmp = *pointer1;
301 *pointer1 = *pointer2;
302 *pointer2 = tmp;
303}
304
305/** reads the next token from the input file into the token buffer; returns whether a token was read */
306static
308 SCIP* scip, /**< SCIP data structure */
309 PIPINPUT* pipinput /**< PIP reading data */
310 )
311{
312 SCIP_Bool hasdot;
313 PIPEXPTYPE exptype;
314 char* buf;
315 int tokenlen;
316
317 assert(pipinput != NULL);
318 assert(pipinput->linepos < PIP_MAX_LINELEN);
319
320 /* check the token stack */
321 if( pipinput->npushedtokens > 0 )
322 {
323 swapPointers(&pipinput->token, &pipinput->pushedtokens[pipinput->npushedtokens-1]);
324 pipinput->npushedtokens--;
325 SCIPdebugMsg(scip, "(line %d) read token again: '%s'\n", pipinput->linenumber, pipinput->token);
326 return TRUE;
327 }
328
329 /* skip delimiters */
330 buf = pipinput->linebuf;
331 while( isDelimChar(buf[pipinput->linepos]) )
332 {
333 if( buf[pipinput->linepos] == '\0' )
334 {
335 if( !getNextLine(scip, pipinput) )
336 {
337 pipinput->section = PIP_END;
338 SCIPdebugMsg(scip, "(line %d) end of file\n", pipinput->linenumber);
339 return FALSE;
340 }
341 assert(pipinput->linepos == 0);
342 }
343 else
344 pipinput->linepos++;
345 }
346 assert(pipinput->linepos < PIP_MAX_LINELEN);
347 assert(!isDelimChar(buf[pipinput->linepos]));
348
349 /* check if the token is a value */
350 hasdot = FALSE;
351 exptype = PIP_EXP_NONE;
352 if( isValueChar(buf[pipinput->linepos], buf[pipinput->linepos+1], TRUE, &hasdot, &exptype) )
353 {
354 /* read value token */
355 tokenlen = 0;
356 do
357 {
358 assert(tokenlen < PIP_MAX_LINELEN);
359 assert(!isDelimChar(buf[pipinput->linepos]));
360 pipinput->token[tokenlen] = buf[pipinput->linepos];
361 tokenlen++;
362 pipinput->linepos++;
363 }
364 while( isValueChar(buf[pipinput->linepos], buf[pipinput->linepos+1], FALSE, &hasdot, &exptype) );
365 }
366 else
367 {
368 /* read non-value token */
369 tokenlen = 0;
370 do
371 {
372 assert(tokenlen < PIP_MAX_LINELEN);
373 pipinput->token[tokenlen] = buf[pipinput->linepos];
374 tokenlen++;
375 pipinput->linepos++;
376 if( tokenlen == 1 && isTokenChar(pipinput->token[0]) )
377 break;
378 }
379 while( !isDelimChar(buf[pipinput->linepos]) && !isTokenChar(buf[pipinput->linepos]) );
380
381 /* if the token is an equation sense '<', '>', or '=', skip a following '='
382 * if the token is an equality token '=' and the next character is a '<' or '>', replace the token by the inequality sense
383 */
384 if( tokenlen >= 1
385 && (pipinput->token[tokenlen-1] == '<' || pipinput->token[tokenlen-1] == '>' || pipinput->token[tokenlen-1] == '=')
386 && buf[pipinput->linepos] == '=' )
387 {
388 pipinput->linepos++;
389 }
390 else if( pipinput->token[tokenlen-1] == '=' && (buf[pipinput->linepos] == '<' || buf[pipinput->linepos] == '>') )
391 {
392 pipinput->token[tokenlen-1] = buf[pipinput->linepos];
393 pipinput->linepos++;
394 }
395 }
396 assert(tokenlen < PIP_MAX_LINELEN);
397 pipinput->token[tokenlen] = '\0';
398
399 SCIPdebugMsg(scip, "(line %d) read token: '%s'\n", pipinput->linenumber, pipinput->token);
400
401 return TRUE;
402}
403
404/** puts the current token on the token stack, such that it is read at the next call to getNextToken() */
405static
407 PIPINPUT* pipinput /**< PIP reading data */
408 )
409{
410 assert(pipinput != NULL);
411 assert(pipinput->npushedtokens < PIP_MAX_PUSHEDTOKENS);
412
413 swapPointers(&pipinput->pushedtokens[pipinput->npushedtokens], &pipinput->token);
414 pipinput->npushedtokens++;
415}
416
417/** puts the buffered token on the token stack, such that it is read at the next call to getNextToken() */
418static
420 PIPINPUT* pipinput /**< PIP reading data */
421 )
422{
423 assert(pipinput != NULL);
424 assert(pipinput->npushedtokens < PIP_MAX_PUSHEDTOKENS);
425
426 swapPointers(&pipinput->pushedtokens[pipinput->npushedtokens], &pipinput->tokenbuf);
427 pipinput->npushedtokens++;
428}
429
430/** swaps the current token with the token buffer */
431static
433 PIPINPUT* pipinput /**< PIP reading data */
434 )
435{
436 assert(pipinput != NULL);
437
438 swapPointers(&pipinput->token, &pipinput->tokenbuf);
439}
440
441/** checks whether the current token is a section identifier, and if yes, switches to the corresponding section */
442static
444 SCIP* scip, /**< SCIP data structure */
445 PIPINPUT* pipinput /**< PIP reading data */
446 )
447{
448 SCIP_Bool iscolon;
449
450 assert(pipinput != NULL);
451
452 /* remember first token by swapping the token buffer */
453 swapTokenBuffer(pipinput);
454
455 /* look at next token: if this is a ':', the first token is a name and no section keyword */
456 iscolon = FALSE;
457 if( getNextToken(scip, pipinput) )
458 {
459 iscolon = (strcmp(pipinput->token, ":") == 0);
460 pushToken(pipinput);
461 }
462
463 /* reinstall the previous token by swapping back the token buffer */
464 swapTokenBuffer(pipinput);
465
466 /* check for ':' */
467 if( iscolon )
468 return FALSE;
469
470 if( SCIPstrcasecmp(pipinput->token, "MINIMIZE") == 0
471 || SCIPstrcasecmp(pipinput->token, "MINIMUM") == 0
472 || SCIPstrcasecmp(pipinput->token, "MIN") == 0 )
473 {
474 SCIPdebugMsg(scip, "(line %d) new section: OBJECTIVE\n", pipinput->linenumber);
475 pipinput->section = PIP_OBJECTIVE;
476 pipinput->objsense = SCIP_OBJSENSE_MINIMIZE;
477 return TRUE;
478 }
479
480 if( SCIPstrcasecmp(pipinput->token, "MAXIMIZE") == 0
481 || SCIPstrcasecmp(pipinput->token, "MAXIMUM") == 0
482 || SCIPstrcasecmp(pipinput->token, "MAX") == 0 )
483 {
484 SCIPdebugMsg(scip, "(line %d) new section: OBJECTIVE\n", pipinput->linenumber);
485 pipinput->section = PIP_OBJECTIVE;
486 pipinput->objsense = SCIP_OBJSENSE_MAXIMIZE;
487 return TRUE;
488 }
489
490 if( SCIPstrcasecmp(pipinput->token, "SUBJECT") == 0 )
491 {
492 /* check if the next token is 'TO' */
493 swapTokenBuffer(pipinput);
494 if( getNextToken(scip, pipinput) )
495 {
496 if( SCIPstrcasecmp(pipinput->token, "TO") == 0 )
497 {
498 SCIPdebugMsg(scip, "(line %d) new section: CONSTRAINTS\n", pipinput->linenumber);
499 pipinput->section = PIP_CONSTRAINTS;
500 return TRUE;
501 }
502 else
503 pushToken(pipinput);
504 }
505 swapTokenBuffer(pipinput);
506 }
507
508 if( SCIPstrcasecmp(pipinput->token, "SUCH") == 0 )
509 {
510 /* check if the next token is 'THAT' */
511 swapTokenBuffer(pipinput);
512 if( getNextToken(scip, pipinput) )
513 {
514 if( SCIPstrcasecmp(pipinput->token, "THAT") == 0 )
515 {
516 SCIPdebugMsg(scip, "(line %d) new section: CONSTRAINTS\n", pipinput->linenumber);
517 pipinput->section = PIP_CONSTRAINTS;
518 return TRUE;
519 }
520 else
521 pushToken(pipinput);
522 }
523 swapTokenBuffer(pipinput);
524 }
525
526 if( SCIPstrcasecmp(pipinput->token, "st") == 0
527 || SCIPstrcasecmp(pipinput->token, "S.T.") == 0
528 || SCIPstrcasecmp(pipinput->token, "ST.") == 0 )
529 {
530 SCIPdebugMsg(scip, "(line %d) new section: CONSTRAINTS\n", pipinput->linenumber);
531 pipinput->section = PIP_CONSTRAINTS;
532 return TRUE;
533 }
534
535 if( SCIPstrcasecmp(pipinput->token, "BOUNDS") == 0
536 || SCIPstrcasecmp(pipinput->token, "BOUND") == 0 )
537 {
538 SCIPdebugMsg(scip, "(line %d) new section: BOUNDS\n", pipinput->linenumber);
539 pipinput->section = PIP_BOUNDS;
540 return TRUE;
541 }
542
543 if( SCIPstrcasecmp(pipinput->token, "GENERAL") == 0
544 || SCIPstrcasecmp(pipinput->token, "GENERALS") == 0
545 || SCIPstrcasecmp(pipinput->token, "GEN") == 0
546 || SCIPstrcasecmp(pipinput->token, "INTEGER") == 0
547 || SCIPstrcasecmp(pipinput->token, "INTEGERS") == 0
548 || SCIPstrcasecmp(pipinput->token, "INT") == 0 )
549 {
550 SCIPdebugMsg(scip, "(line %d) new section: GENERALS\n", pipinput->linenumber);
551 pipinput->section = PIP_GENERALS;
552 return TRUE;
553 }
554
555 if( SCIPstrcasecmp(pipinput->token, "BINARY") == 0
556 || SCIPstrcasecmp(pipinput->token, "BINARIES") == 0
557 || SCIPstrcasecmp(pipinput->token, "BIN") == 0 )
558 {
559 SCIPdebugMsg(scip, "(line %d) new section: BINARIES\n", pipinput->linenumber);
560 pipinput->section = PIP_BINARIES;
561 return TRUE;
562 }
563
564 if( SCIPstrcasecmp(pipinput->token, "END") == 0 )
565 {
566 SCIPdebugMsg(scip, "(line %d) new section: END\n", pipinput->linenumber);
567 pipinput->section = PIP_END;
568 return TRUE;
569 }
570
571 return FALSE;
572}
573
574/** returns whether the current token is a sign */
575static
577 PIPINPUT* pipinput, /**< PIP reading data */
578 int* sign /**< pointer to update the sign */
579 )
580{
581 assert(pipinput != NULL);
582 assert(sign != NULL);
583 assert(*sign == +1 || *sign == -1);
584
585 if( pipinput->token[1] == '\0' )
586 {
587 if( *pipinput->token == '+' )
588 return TRUE;
589 else if( *pipinput->token == '-' )
590 {
591 *sign *= -1;
592 return TRUE;
593 }
594 }
595
596 return FALSE;
597}
598
599/** returns whether the current token is a value */
600static
602 SCIP* scip, /**< SCIP data structure */
603 PIPINPUT* pipinput, /**< PIP reading data */
604 SCIP_Real* value /**< pointer to store the value (unchanged, if token is no value) */
605 )
606{
607 assert(pipinput != NULL);
608 assert(value != NULL);
609
610 if( SCIPstrcasecmp(pipinput->token, "INFINITY") == 0 || SCIPstrcasecmp(pipinput->token, "INF") == 0 )
611 {
612 *value = SCIPinfinity(scip);
613 return TRUE;
614 }
615 else
616 {
617 double val;
618 char* endptr;
619
620 val = strtod(pipinput->token, &endptr);
621 if( endptr != pipinput->token && *endptr == '\0' )
622 {
623 *value = val;
624 return TRUE;
625 }
626 }
627
628 return FALSE;
629}
630
631/** returns whether the current token is an equation sense */
632static
634 PIPINPUT* pipinput, /**< PIP reading data */
635 PIPSENSE* sense /**< pointer to store the equation sense, or NULL */
636 )
637{
638 assert(pipinput != NULL);
639
640 if( strcmp(pipinput->token, "<") == 0 )
641 {
642 if( sense != NULL )
643 *sense = PIP_SENSE_LE;
644 return TRUE;
645 }
646 else if( strcmp(pipinput->token, ">") == 0 )
647 {
648 if( sense != NULL )
649 *sense = PIP_SENSE_GE;
650 return TRUE;
651 }
652 else if( strcmp(pipinput->token, "=") == 0 )
653 {
654 if( sense != NULL )
655 *sense = PIP_SENSE_EQ;
656 return TRUE;
657 }
658
659 return FALSE;
660}
661
662/** returns the variable with the given name, or creates a new variable if it does not exist */
663static
665 SCIP* scip, /**< SCIP data structure */
666 char* name, /**< name of the variable */
667 SCIP_Bool dynamiccols, /**< should columns be added and removed dynamically to the LP? */
668 SCIP_VAR** var, /**< pointer to store the variable */
669 SCIP_Bool* created /**< pointer to store whether a new variable was created, or NULL */
670 )
671{
672 assert(name != NULL);
673 assert(var != NULL);
674
675 *var = SCIPfindVar(scip, name);
676 if( *var == NULL )
677 {
678 SCIP_VAR* newvar;
679
680 /* create new variable of the given name */
681 SCIPdebugMsg(scip, "creating new variable: <%s>\n", name);
683 !dynamiccols, dynamiccols, NULL, NULL, NULL, NULL, NULL) );
684 SCIP_CALL( SCIPaddVar(scip, newvar) );
685 *var = newvar;
686
687 /* because the variable was added to the problem, it is captured by SCIP and we can safely release it right now
688 * without making the returned *var invalid
689 */
690 SCIP_CALL( SCIPreleaseVar(scip, &newvar) );
691
692 if( created != NULL )
693 *created = TRUE;
694 }
695 else if( created != NULL )
696 *created = FALSE;
697
698 return SCIP_OKAY;
699}
700
701/** reads the header of the file */
702static
704 SCIP* scip, /**< SCIP data structure */
705 PIPINPUT* pipinput /**< PIP reading data */
706 )
707{
708 assert(pipinput != NULL);
709
710 /* everything before first section is treated as comment */
711 do
712 {
713 /* get token */
714 if( !getNextToken(scip, pipinput) )
715 return SCIP_OKAY;
716 }
717 while( !isNewSection(scip, pipinput) );
718
719 return SCIP_OKAY;
720}
721
722/** ensure that an array of monomials can hold a minimum number of entries */
723static
725 SCIP* scip, /**< SCIP data structure */
726 SCIP_EXPR*** monomials, /**< pointer to current array of monomials */
727 SCIP_Real** monomialscoef, /**< pointer to current array of monomial coefficients */
728 int* monomialssize, /**< current size of monomials array at input; new size at exit */
729 int minnmonomials /**< required minimal size of monomials array */
730 )
731{
732 int newsize;
733
734 assert(scip != NULL);
735 assert(monomials != NULL);
736 assert(monomialscoef != NULL);
737 assert(monomialssize != NULL);
738 assert(*monomials != NULL || *monomialssize == 0);
739
740 if( minnmonomials <= *monomialssize )
741 return SCIP_OKAY;
742
743 newsize = SCIPcalcMemGrowSize(scip, minnmonomials);
744
745 if( *monomials != NULL )
746 {
747 SCIP_CALL( SCIPreallocBufferArray(scip, monomials, newsize) );
748 }
749 else
750 {
751 SCIP_CALL( SCIPallocBufferArray(scip, monomials, newsize) );
752 }
753 if( *monomialscoef != NULL )
754 {
755 SCIP_CALL( SCIPreallocBufferArray(scip, monomialscoef, newsize) );
756 }
757 else
758 {
759 SCIP_CALL( SCIPallocBufferArray(scip, monomialscoef, newsize) );
760 }
761 *monomialssize = newsize;
762
763 return SCIP_OKAY;
764}
765
766/** ensure that arrays of exponents and variable indices can hold a minimum number of entries */
767static
769 SCIP* scip, /**< SCIP data structure */
770 SCIP_VAR*** vars, /**< pointer to current array of variables */
771 SCIP_Real** exponents, /**< pointer to current array of exponents */
772 int* factorssize, /**< current size of arrays at input; new size at exit */
773 int minnfactors /**< required minimal size of arrays */
774 )
775{
776 int newsize;
777
778 assert(scip != NULL);
779 assert(vars != NULL);
780 assert(exponents != NULL);
781 assert(factorssize != NULL);
782 assert(*exponents != NULL || *factorssize == 0);
783 assert(*vars != NULL || *factorssize == 0);
784
785 if( minnfactors <= *factorssize )
786 return SCIP_OKAY;
787
788 newsize = SCIPcalcMemGrowSize(scip, minnfactors);
789
790 if( *exponents != NULL )
791 {
792 SCIP_CALL( SCIPreallocBufferArray(scip, exponents, newsize) );
793 SCIP_CALL( SCIPreallocBufferArray(scip, vars, newsize) );
794 }
795 else
796 {
797 SCIP_CALL( SCIPallocBufferArray(scip, exponents, newsize) );
798 SCIP_CALL( SCIPallocBufferArray(scip, vars, newsize) );
799 }
800 *factorssize = newsize;
801
802 return SCIP_OKAY;
803}
804
805/** reads an objective or constraint with name and coefficients */
806static
808 SCIP* scip, /**< SCIP data structure */
809 PIPINPUT* pipinput, /**< PIP reading data */
810 char* name, /**< pointer to store the name of the line; must be at least of size
811 * PIP_MAX_LINELEN */
812 SCIP_EXPR** expr, /**< pointer to store the constraint function as expression */
813 SCIP_Bool* islinear, /**< pointer to store polynomial is linear */
814 SCIP_Bool* newsection /**< pointer to store whether a new section was encountered */
815 )
816{
817 SCIP_Bool havesign;
818 SCIP_Bool havevalue;
819 SCIP_Real coef;
820 int coefsign;
821 int nextcoefsign;
822 int monomialdegree;
823 int i;
824
825 SCIP_VAR** vars;
826 SCIP_Real constant;
827
828 SCIP_EXPR** monomials;
829 SCIP_Real* monomialscoef;
830 int monomialssize;
831 int nmonomials;
832
833 int nfactors;
834 int factorssize;
835 SCIP_Real* exponents;
836
837 assert(scip != NULL);
838 assert(pipinput != NULL);
839 assert(name != NULL);
840 assert(expr != NULL);
841 assert(islinear != NULL);
842 assert(newsection != NULL);
843
844 *name = '\0';
845 *expr = NULL;
846 *islinear = TRUE;
847 *newsection = FALSE;
848
849 /* read the first token, which may be the name of the line */
850 if( getNextToken(scip, pipinput) )
851 {
852 /* check if we reached a new section */
853 if( isNewSection(scip, pipinput) )
854 {
855 *newsection = TRUE;
856 return SCIP_OKAY;
857 }
858
859 /* remember the token in the token buffer */
860 swapTokenBuffer(pipinput);
861
862 /* get the next token and check, whether it is a colon */
863 if( getNextToken(scip, pipinput) )
864 {
865 if( strcmp(pipinput->token, ":") == 0 )
866 {
867 /* the second token was a colon: the first token is the line name */
868 (void)SCIPstrncpy(name, pipinput->tokenbuf, PIP_MAX_LINELEN);
869 SCIPdebugMsg(scip, "(line %d) read constraint name: '%s'\n", pipinput->linenumber, name);
870 }
871 else
872 {
873 /* the second token was no colon: push the tokens back onto the token stack and parse them as coefficients */
874 pushToken(pipinput);
875 pushBufferToken(pipinput);
876 }
877 }
878 else
879 {
880 /* there was only one token left: push it back onto the token stack and parse it as coefficient */
881 pushBufferToken(pipinput);
882 }
883 }
884
885 /* initialize buffer for storing the monomials */
886 monomialssize = PIP_INIT_MONOMIALSSIZE;
887 SCIP_CALL( SCIPallocBufferArray(scip, &monomials, monomialssize) );
888 SCIP_CALL( SCIPallocBufferArray(scip, &monomialscoef, monomialssize) );
889
890 /* initialize buffer for storing the factors in a monomial */
891 factorssize = PIP_INIT_FACTORSSIZE;
892 SCIP_CALL( SCIPallocBufferArray(scip, &exponents, factorssize) );
893 SCIP_CALL( SCIPallocBufferArray(scip, &vars, factorssize) );
894
895 /* read the coefficients */
896 coefsign = +1;
897 nextcoefsign = +1;
898 coef = 1.0;
899 havesign = FALSE;
900 havevalue = FALSE;
901 nmonomials = 0;
902 nfactors = 0;
903 monomialdegree = 0;
904 constant = 0.0;
905 while( getNextToken(scip, pipinput) )
906 {
907 SCIP_VAR* var;
908 SCIP_Bool issense;
909 SCIP_Bool issign;
910 SCIP_Bool isnewsection;
911 SCIP_Real exponent;
912
913 issign = FALSE; /* fix compiler warning */
914 issense = FALSE; /* fix lint warning */
915 if( (isnewsection = isNewSection(scip, pipinput)) || /*lint !e820*/
916 (issense = isSense(pipinput, NULL)) || /*lint !e820*/
917 ((nfactors > 0 || havevalue) && (issign = isSign(pipinput, &nextcoefsign))) ) /*lint !e820*/
918 {
919 /* finish the current monomial */
920 if( nfactors > 0 )
921 {
922 if( coefsign * coef != 0.0 )
923 {
924 SCIP_CALL( ensureMonomialsSize(scip, &monomials, &monomialscoef, &monomialssize, nmonomials + 1) );
925 SCIP_CALL( SCIPcreateExprMonomial(scip, &monomials[nmonomials], nfactors, vars, exponents, NULL, NULL) );
926 monomialscoef[nmonomials] = coefsign * coef;
927 ++nmonomials;
928 }
929 }
930 else if( havevalue )
931 {
932 constant += coefsign * coef;
933 }
934
935 if( monomialdegree > 1 )
936 *islinear = FALSE;
937
938 /* reset variables */
939 nfactors = 0;
940 coef = 1.0;
941 coefsign = +1;
942 havesign = FALSE;
943 havevalue = FALSE;
944 monomialdegree = 0;
945
946 if( isnewsection )
947 {
948 *newsection = TRUE;
949 break;
950 }
951
952 if( issense )
953 {
954 /* put the sense back onto the token stack */
955 pushToken(pipinput);
956 break;
957 }
958
959 if( issign )
960 {
961 coefsign = nextcoefsign;
962 SCIPdebugMsg(scip, "(line %d) read coefficient sign: %+d\n", pipinput->linenumber, coefsign);
963 havesign = TRUE;
964 nextcoefsign = +1;
965 continue;
966 }
967 }
968
969 /* check if we read a sign */
970 if( isSign(pipinput, &coefsign) )
971 {
972 SCIPdebugMsg(scip, "(line %d) read coefficient sign: %+d\n", pipinput->linenumber, coefsign);
973
974 if( nfactors > 0 || havevalue )
975 {
976 syntaxError(scip, pipinput, "sign can only be at beginning of monomial");
977 goto TERMINATE_READPOLYNOMIAL;
978 }
979
980 havesign = TRUE;
981 continue;
982 }
983
984 /* check if we are in between factors of a monomial */
985 if( strcmp(pipinput->token, "*") == 0 )
986 {
987 if( nfactors == 0 )
988 {
989 syntaxError(scip, pipinput, "cannot have '*' before first variable in monomial");
990 goto TERMINATE_READPOLYNOMIAL;
991 }
992
993 continue;
994 }
995
996 /* all but the first monomial need a sign */
997 if( nmonomials > 0 && !havesign )
998 {
999 syntaxError(scip, pipinput, "expected sign ('+' or '-') or sense ('<' or '>')");
1000 goto TERMINATE_READPOLYNOMIAL;
1001 }
1002
1003 /* check if we are at an exponent for the last variable */
1004 if( strcmp(pipinput->token, "^") == 0 )
1005 {
1006 if( !getNextToken(scip, pipinput) || !isValue(scip, pipinput, &exponent) )
1007 {
1008 syntaxError(scip, pipinput, "expected exponent value after '^'");
1009 goto TERMINATE_READPOLYNOMIAL;
1010 }
1011 if( nfactors == 0 )
1012 {
1013 syntaxError(scip, pipinput, "cannot have '^' before first variable in monomial");
1014 goto TERMINATE_READPOLYNOMIAL;
1015 }
1016 exponents[nfactors-1] = exponent; /*lint !e530*/
1017 if( SCIPisIntegral(scip, exponent) && exponent > 0.0 ) /*lint !e530*/
1018 monomialdegree += (int)exponent - 1; /*lint !e530*//* -1, because we added +1 when we put the variable into varidxs */
1019 else
1020 *islinear = FALSE;
1021
1022 SCIPdebugMsg(scip, "(line %d) read exponent value %g for variable %s\n", pipinput->linenumber, exponent,
1023 SCIPvarGetName(vars[nfactors-1]));
1024 continue;
1025 }
1026
1027 /* check if we read a value */
1028 if( isValue(scip, pipinput, &coef) )
1029 {
1030 SCIPdebugMsg(scip, "(line %d) read coefficient value: %g with sign %+d\n", pipinput->linenumber, coef, coefsign);
1031
1032 if( havevalue )
1033 {
1034 syntaxError(scip, pipinput, "two consecutive values");
1035 goto TERMINATE_READPOLYNOMIAL;
1036 }
1037
1038 if( nfactors > 0 )
1039 {
1040 syntaxError(scip, pipinput, "coefficients can only be at the beginning of a monomial");
1041 goto TERMINATE_READPOLYNOMIAL;
1042 }
1043
1044 havevalue = TRUE;
1045 continue;
1046 }
1047
1048 /* the token is a variable name: get the corresponding variable (or create a new one) */
1049 SCIP_CALL( getVariable(scip, pipinput->token, pipinput->dynamiccols, &var, NULL) );
1050
1051 /* ensure that there is enough memory to store all factors */
1052 SCIP_CALL( ensureFactorsSize(scip, &vars, &exponents, &factorssize, nfactors + 1) );
1053
1054 /* create and store corresponding variable expression */
1055 vars[nfactors] = var;
1056 exponents[nfactors] = 1.0;
1057 ++nfactors;
1058 ++monomialdegree;
1059 }
1060
1061 if( nfactors > 0 )
1062 {
1063 syntaxError(scip, pipinput, "string ended before monomial has finished");
1064 goto TERMINATE_READPOLYNOMIAL;
1065 }
1066
1067 /* create sum expression consisting of all monomial expressions */
1068 SCIP_CALL( SCIPcreateExprSum(scip, expr, nmonomials, monomials, monomialscoef, constant, NULL, NULL) );
1069
1070 /* release monomial expressions */
1071 for( i = 0; i < nmonomials; ++i )
1072 {
1073 assert(monomials[i] != NULL);
1074 SCIP_CALL( SCIPreleaseExpr(scip, &monomials[i]) );
1075 }
1076
1077#ifdef SCIP_DEBUG
1078 SCIPdebugMsg(scip, "read polynomial: ");
1079 SCIP_CALL( SCIPprintExpr(scip, *expr, NULL) );
1080 SCIPinfoMessage(scip, NULL, "\n");
1081#endif
1082
1083 TERMINATE_READPOLYNOMIAL:
1084 SCIPfreeBufferArray(scip, &vars);
1085 SCIPfreeBufferArray(scip, &exponents);
1086 SCIPfreeBufferArray(scip, &monomialscoef);
1087 SCIPfreeBufferArray(scip, &monomials);
1088
1089 return SCIP_OKAY;
1090}
1091
1092/** reads the objective section */
1093static
1095 SCIP* scip, /**< SCIP data structure */
1096 PIPINPUT* pipinput /**< PIP reading data */
1097 )
1098{
1099 char name[PIP_MAX_LINELEN];
1100 SCIP_EXPR* expr;
1101 SCIP_Bool linear;
1102 SCIP_Bool newsection;
1103 SCIP_Bool initial;
1105 SCIP_Bool enforce;
1106 SCIP_Bool check;
1107 SCIP_Bool propagate;
1108 SCIP_Bool local;
1109 SCIP_Bool modifiable;
1110 SCIP_Bool dynamic;
1111 SCIP_Bool removable;
1112
1113 assert(pipinput != NULL);
1114
1115 /* determine settings; note that reading/{initialconss,dynamicconss,dynamicrows,dynamiccols} apply only to model
1116 * constraints and variables, not to an auxiliary objective constraint (otherwise it can happen that an auxiliary
1117 * objective variable is loose with infinite best bound, triggering the problem that an LP that is unbounded because
1118 * of loose variables with infinite best bound cannot be solved)
1119 */
1120 initial = TRUE;
1121 separate = TRUE;
1122 enforce = TRUE;
1123 check = TRUE;
1124 propagate = TRUE;
1125 local = FALSE;
1126 modifiable = FALSE;
1127 dynamic = FALSE;
1128 removable = FALSE;
1129
1130 /* read the objective coefficients */
1131 SCIP_CALL( readPolynomial(scip, pipinput, name, &expr, &linear, &newsection) );
1132 if( !hasError(pipinput) && expr != NULL )
1133 {
1134 SCIP_Real constant = SCIPgetConstantExprSum(expr);
1135
1136 /* always create a variable that represents the constant; otherwise, this might lead to numerical issues on
1137 * instances with a relatively large constant, e.g., popdynm* instances
1138 */
1139 if( constant != 0.0 )
1140 {
1141 SCIP_VAR* objconst;
1142 SCIP_CALL( SCIPcreateVarBasic(scip, &objconst, "objconst", 1.0, 1.0, constant, SCIP_VARTYPE_CONTINUOUS) );
1143 SCIP_CALL( SCIPaddVar(scip, objconst) );
1144 SCIP_CALL( SCIPreleaseVar(scip, &objconst) );
1145
1146 /* remove the constant of the sum expression */
1147 SCIPsetConstantExprSum(expr, 0.0);
1148 }
1149
1150 if( linear )
1151 {
1152 int i;
1153
1154 /* set objective coefficients of variables */
1155 for( i = 0; i < SCIPexprGetNChildren(expr); ++i )
1156 {
1157 SCIP_EXPR* child;
1158 SCIP_VAR* var;
1159 SCIP_Real coef;
1160
1161 child = SCIPexprGetChildren(expr)[i];
1162 assert(child != NULL);
1163 assert(SCIPisExprVar(scip, child));
1164
1165 /* child has to be a variable expression, see SCIPcreateExprMonomial() */
1166 var = SCIPgetVarExprVar(child);
1167 assert(var != NULL);
1168 coef = SCIPgetCoefsExprSum(expr)[i];
1169
1170 /* adjust the objective coefficient */
1171 SCIP_CALL( SCIPchgVarObj(scip, var, SCIPvarGetObj(var) + coef) );
1172 }
1173 }
1174 else /* insert dummy variable and constraint to represent the nonlinear objective */
1175 {
1176 SCIP_EXPR* nonlinobjvarexpr;
1177 SCIP_VAR* nonlinobjvar;
1178 SCIP_CONS* nonlinobjcons;
1179 SCIP_Real lhs;
1180 SCIP_Real rhs;
1181
1182 SCIP_CALL( SCIPcreateVar(scip, &nonlinobjvar, "nonlinobjvar", -SCIPinfinity(scip), SCIPinfinity(scip), 1.0,
1184 SCIP_CALL( SCIPaddVar(scip, nonlinobjvar) );
1185
1186 if ( pipinput->objsense == SCIP_OBJSENSE_MINIMIZE )
1187 {
1188 lhs = -SCIPinfinity(scip);
1189 rhs = 0.0;
1190 }
1191 else
1192 {
1193 lhs = 0.0;
1194 rhs = SCIPinfinity(scip);
1195 }
1196
1197 /* add created objective variable */
1198 SCIP_CALL( SCIPcreateExprVar(scip, &nonlinobjvarexpr, nonlinobjvar, NULL, NULL) );
1199 SCIP_CALL( SCIPappendExprSumExpr(scip, expr, nonlinobjvarexpr, -1.0) );
1200 SCIP_CALL( SCIPreleaseExpr(scip, &nonlinobjvarexpr) );
1201
1202 /* create nonlinear constraint */
1203 SCIP_CALL( SCIPcreateConsNonlinear(scip, &nonlinobjcons, "nonlinobj", expr, lhs, rhs, initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable) );
1204
1205 SCIP_CALL( SCIPaddCons(scip, nonlinobjcons) );
1206 SCIPdebugMsg(scip, "(line %d) added constraint <%s> to represent nonlinear objective: ", pipinput->linenumber, SCIPconsGetName(nonlinobjcons));
1207 SCIPdebugPrintCons(scip, nonlinobjcons, NULL);
1208
1209 SCIP_CALL( SCIPreleaseCons(scip, &nonlinobjcons) );
1210 SCIP_CALL( SCIPreleaseVar(scip, &nonlinobjvar) );
1211 }
1212 }
1213
1214 /* release expression */
1215 if( expr != NULL )
1216 {
1217 SCIP_CALL( SCIPreleaseExpr(scip, &expr) );
1218 }
1219
1220 return SCIP_OKAY;
1221}
1222
1223/** reads the constraints section */
1224static
1226 SCIP* scip, /**< SCIP data structure */
1227 PIPINPUT* pipinput /**< PIP reading data */
1228 )
1229{
1230 char name[PIP_MAX_LINELEN];
1231 SCIP_EXPR* expr;
1232 SCIP_CONS* cons = NULL;
1233 SCIP_Bool linear;
1234
1235 PIPSENSE sense;
1236 SCIP_Real sidevalue;
1237 SCIP_Real lhs;
1238 SCIP_Real rhs;
1239 SCIP_Bool newsection;
1240 SCIP_Bool initial;
1242 SCIP_Bool enforce;
1243 SCIP_Bool check;
1244 SCIP_Bool propagate;
1245 SCIP_Bool local;
1246 SCIP_Bool modifiable;
1247 SCIP_Bool dynamic;
1248 SCIP_Bool removable;
1249 int sidesign;
1250
1251 assert(pipinput != NULL);
1252
1253 /* read polynomial */
1254 SCIP_CALL( readPolynomial(scip, pipinput, name, &expr, &linear, &newsection) );
1255 if ( hasError(pipinput) )
1256 return SCIP_READERROR;
1257 if ( newsection )
1258 {
1259 if ( expr != NULL )
1260 syntaxError(scip, pipinput, "expected constraint sense '<=', '=', or '>='");
1261 return SCIP_OKAY;
1262 }
1263
1264 /* read the constraint sense */
1265 if ( !getNextToken(scip, pipinput) )
1266 {
1267 syntaxError(scip, pipinput, "expected constraint sense.");
1268 return SCIP_READERROR;
1269 }
1270 if ( !isSense(pipinput, &sense) )
1271 {
1272 syntaxError(scip, pipinput, "expected constraint sense '<=', '=', or '>='");
1273 return SCIP_READERROR;
1274 }
1275
1276 /* read the right hand side */
1277 sidesign = +1;
1278 if ( !getNextToken(scip, pipinput) )
1279 {
1280 syntaxError(scip, pipinput, "missing right hand side");
1281 return SCIP_READERROR;
1282 }
1283 if ( isSign(pipinput, &sidesign) )
1284 {
1285 if( !getNextToken(scip, pipinput) )
1286 {
1287 syntaxError(scip, pipinput, "missing value of right hand side");
1288 return SCIP_READERROR;
1289 }
1290 }
1291 if ( !isValue(scip, pipinput, &sidevalue) )
1292 {
1293 syntaxError(scip, pipinput, "expected value as right hand side");
1294 return SCIP_READERROR;
1295 }
1296 sidevalue *= sidesign;
1297
1298 /* determine settings */
1299 initial = pipinput->initialconss;
1300 separate = TRUE;
1301 enforce = TRUE;
1302 check = TRUE;
1303 propagate = TRUE;
1304 local = FALSE;
1305 modifiable = FALSE;
1306 dynamic = pipinput->dynamicconss;
1307 removable = pipinput->dynamicrows;
1308
1309 /* assign the left and right hand side, depending on the constraint sense */
1310 switch ( sense ) /*lint !e530*/
1311 {
1312 case PIP_SENSE_GE:
1313 lhs = sidevalue;
1314 rhs = SCIPinfinity(scip);
1315 break;
1316 case PIP_SENSE_LE:
1317 lhs = -SCIPinfinity(scip);
1318 rhs = sidevalue;
1319 break;
1320 case PIP_SENSE_EQ:
1321 lhs = sidevalue;
1322 rhs = sidevalue;
1323 break;
1324 case PIP_SENSE_NOTHING:
1325 default:
1326 SCIPerrorMessage("invalid constraint sense <%d>\n", sense);
1327 return SCIP_INVALIDDATA;
1328 }
1329
1330 /* linear constraint function */
1331 if( linear )
1332 {
1333 SCIP_VAR** vars;
1334 SCIP_Real* coefs;
1335 SCIP_Real constant;
1336 int nchildren;
1337 int i;
1338
1339 nchildren = SCIPexprGetNChildren(expr);
1340 constant = SCIPgetConstantExprSum(expr);
1341 coefs = SCIPgetCoefsExprSum(expr);
1342
1343 /* allocate memory to store variables */
1344 SCIP_CALL( SCIPallocBufferArray(scip, &vars, nchildren) );
1345
1346 /* collect variables */
1347 for( i = 0; i < nchildren; ++i )
1348 {
1349 SCIP_EXPR* child = SCIPexprGetChildren(expr)[i];
1350 assert(child != NULL);
1351 assert(SCIPisExprVar(scip, child));
1352
1353 vars[i] = SCIPgetVarExprVar(child);
1354 assert(vars[i] != NULL);
1355 }
1356
1357 /* adjust lhs and rhs */
1358 if( !SCIPisInfinity(scip, -lhs) )
1359 lhs -= constant;
1360 if( !SCIPisInfinity(scip, rhs) )
1361 rhs -= constant;
1362
1363 /* create linear constraint */
1364 SCIP_CALL( SCIPcreateConsLinear(scip, &cons, name, nchildren, vars, coefs, lhs, rhs, initial, separate, enforce,
1365 check, propagate, local, modifiable, dynamic, removable, FALSE) );
1366
1367 /* free memory */
1368 SCIPfreeBufferArray(scip, &vars);
1369 }
1370 else /* nonlinear constraint function */
1371 {
1372 SCIP_CALL( SCIPcreateConsNonlinear(scip, &cons, name, expr, lhs, rhs, initial, separate, enforce, check, propagate,
1373 local, modifiable, dynamic, removable) );
1374 }
1375
1376 /* add and release constraint */
1377 assert(cons != NULL);
1378 SCIP_CALL( SCIPaddCons(scip, cons) );
1379 SCIPdebugMsg(scip, "(line %d) created constraint: ", pipinput->linenumber);
1381 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1382
1383 /* release expression */
1384 if( expr != NULL )
1385 {
1386 SCIP_CALL( SCIPreleaseExpr(scip, &expr) );
1387 }
1388
1389 return SCIP_OKAY;
1390}
1391
1392/** reads the bounds section */
1393static
1395 SCIP* scip, /**< SCIP data structure */
1396 PIPINPUT* pipinput /**< PIP reading data */
1397 )
1398{
1399 assert(pipinput != NULL);
1400
1401 while( getNextToken(scip, pipinput) )
1402 {
1403 SCIP_VAR* var;
1404 SCIP_Real value;
1405 SCIP_Real lb;
1406 SCIP_Real ub;
1407 int sign;
1408 SCIP_Bool hassign;
1409 PIPSENSE leftsense;
1410
1411 /* check if we reached a new section */
1412 if( isNewSection(scip, pipinput) )
1413 return SCIP_OKAY;
1414
1415 /* default bounds are [0,+inf] */
1416 lb = 0.0;
1417 ub = SCIPinfinity(scip);
1418 leftsense = PIP_SENSE_NOTHING;
1419
1420 /* check if the first token is a sign */
1421 sign = +1;
1422 hassign = isSign(pipinput, &sign);
1423 if( hassign && !getNextToken(scip, pipinput) )
1424 {
1425 syntaxError(scip, pipinput, "expected value");
1426 return SCIP_OKAY;
1427 }
1428
1429 /* the first token must be either a value or a variable name */
1430 if( isValue(scip, pipinput, &value) )
1431 {
1432 /* first token is a value: the second token must be a sense */
1433 if( !getNextToken(scip, pipinput) || !isSense(pipinput, &leftsense) )
1434 {
1435 syntaxError(scip, pipinput, "expected bound sense '<=', '=', or '>='");
1436 return SCIP_OKAY;
1437 }
1438
1439 /* update the bound corresponding to the sense */
1440 switch( leftsense )
1441 {
1442 case PIP_SENSE_GE:
1443 ub = sign * value;
1444 break;
1445 case PIP_SENSE_LE:
1446 lb = sign * value;
1447 break;
1448 case PIP_SENSE_EQ:
1449 lb = sign * value;
1450 ub = sign * value;
1451 break;
1452 case PIP_SENSE_NOTHING:
1453 default:
1454 SCIPerrorMessage("invalid bound sense <%d>\n", leftsense);
1455 return SCIP_INVALIDDATA;
1456 }
1457 }
1458 else if( hassign )
1459 {
1460 syntaxError(scip, pipinput, "expected value");
1461 return SCIP_OKAY;
1462 }
1463 else
1464 pushToken(pipinput);
1465
1466 /* the next token must be a variable name */
1467 if( !getNextToken(scip, pipinput) )
1468 {
1469 syntaxError(scip, pipinput, "expected variable name");
1470 return SCIP_OKAY;
1471 }
1472 SCIP_CALL( getVariable(scip, pipinput->token, pipinput->dynamiccols, &var, NULL) );
1473
1474 /* the next token might be another sense, or the word "free" */
1475 if( getNextToken(scip, pipinput) )
1476 {
1477 PIPSENSE rightsense;
1478
1479 if( isSense(pipinput, &rightsense) )
1480 {
1481 /* check, if the senses fit */
1482 if( leftsense == PIP_SENSE_NOTHING
1483 || (leftsense == PIP_SENSE_LE && rightsense == PIP_SENSE_LE)
1484 || (leftsense == PIP_SENSE_GE && rightsense == PIP_SENSE_GE) )
1485 {
1486 if( !getNextToken(scip, pipinput) )
1487 {
1488 syntaxError(scip, pipinput, "expected value or sign");
1489 return SCIP_OKAY;
1490 }
1491
1492 /* check if the next token is a sign */
1493 sign = +1;
1494 hassign = isSign(pipinput, &sign);
1495 if( hassign && !getNextToken(scip, pipinput) )
1496 {
1497 syntaxError(scip, pipinput, "expected value");
1498 return SCIP_OKAY;
1499 }
1500
1501 /* the next token must be a value */
1502 if( !isValue(scip, pipinput, &value) )
1503 {
1504 syntaxError(scip, pipinput, "expected value");
1505 return SCIP_OKAY;
1506 }
1507
1508 /* update the bound corresponding to the sense */
1509 switch( rightsense )
1510 {
1511 case PIP_SENSE_GE:
1512 lb = sign * value;
1513 break;
1514 case PIP_SENSE_LE:
1515 ub = sign * value;
1516 break;
1517 case PIP_SENSE_EQ:
1518 lb = sign * value;
1519 ub = sign * value;
1520 break;
1521 case PIP_SENSE_NOTHING:
1522 default:
1523 SCIPerrorMessage("invalid bound sense <%d>\n", leftsense);
1524 return SCIP_INVALIDDATA;
1525 }
1526 }
1527 else
1528 {
1529 syntaxError(scip, pipinput, "the two bound senses do not fit");
1530 return SCIP_OKAY;
1531 }
1532 }
1533 else if( SCIPstrcasecmp(pipinput->token, "FREE") == 0 )
1534 {
1535 if( leftsense != PIP_SENSE_NOTHING )
1536 {
1537 syntaxError(scip, pipinput, "variable with bound is marked as 'free'");
1538 return SCIP_OKAY;
1539 }
1540 lb = -SCIPinfinity(scip);
1541 ub = SCIPinfinity(scip);
1542 }
1543 else
1544 {
1545 /* the token was no sense: push it back to the token stack */
1546 pushToken(pipinput);
1547 }
1548 }
1549
1550 /* change the bounds of the variable if bounds have been given (do not destroy earlier specification of bounds) */
1551 if ( lb != 0.0 )
1552 SCIP_CALL( SCIPchgVarLb(scip, var, lb) );
1553 /*lint --e{777}*/
1554 if ( ub != SCIPinfinity(scip) )
1555 SCIP_CALL( SCIPchgVarUb(scip, var, ub) );
1556 SCIPdebugMsg(scip, "(line %d) new bounds: <%s>[%g,%g]\n", pipinput->linenumber, SCIPvarGetName(var),
1558 }
1559
1560 return SCIP_OKAY;
1561}
1562
1563/** reads the generals section */
1564static
1566 SCIP* scip, /**< SCIP data structure */
1567 PIPINPUT* pipinput /**< PIP reading data */
1568 )
1569{
1570 assert(pipinput != NULL);
1571
1572 while( getNextToken(scip, pipinput) )
1573 {
1574 SCIP_VAR* var;
1575 SCIP_Bool created;
1576 SCIP_Bool infeasible;
1577
1578 /* check if we reached a new section */
1579 if( isNewSection(scip, pipinput) )
1580 return SCIP_OKAY;
1581
1582 /* the token must be the name of an existing variable */
1583 SCIP_CALL( getVariable(scip, pipinput->token, pipinput->dynamiccols, &var, &created) );
1584 if( created )
1585 {
1586 syntaxError(scip, pipinput, "unknown variable in generals section");
1587 return SCIP_OKAY;
1588 }
1589
1590 /* mark the variable to be integral */
1591 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
1592 /* don't assert feasibility here because the presolver will and should detect a infeasibility */
1593 }
1594
1595 return SCIP_OKAY;
1596}
1597
1598/** reads the binaries section */
1599static
1601 SCIP* scip, /**< SCIP data structure */
1602 PIPINPUT* pipinput /**< PIP reading data */
1603 )
1604{
1605 assert(pipinput != NULL);
1606
1607 while( getNextToken(scip, pipinput) )
1608 {
1609 SCIP_VAR* var;
1610 SCIP_Bool created;
1611 SCIP_Bool infeasible;
1612
1613 /* check if we reached a new section */
1614 if( isNewSection(scip, pipinput) )
1615 return SCIP_OKAY;
1616
1617 /* the token must be the name of an existing variable */
1618 SCIP_CALL( getVariable(scip, pipinput->token, pipinput->dynamiccols, &var, &created) );
1619 if( created )
1620 {
1621 syntaxError(scip, pipinput, "unknown variable in binaries section");
1622 return SCIP_OKAY;
1623 }
1624
1625 /* mark the variable to be binary and change its bounds appropriately */
1626 if( SCIPvarGetLbGlobal(var) < 0.0 )
1627 {
1628 SCIP_CALL( SCIPchgVarLb(scip, var, 0.0) );
1629 }
1630 if( SCIPvarGetUbGlobal(var) > 1.0 )
1631 {
1632 SCIP_CALL( SCIPchgVarUb(scip, var, 1.0) );
1633 }
1634 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
1635 /* don't assert feasibility here because the presolver will and should detect a infeasibility */
1636 }
1637
1638 return SCIP_OKAY;
1639}
1640
1641/** reads a PIP file
1642 */
1643static
1645 SCIP* scip, /**< SCIP data structure */
1646 PIPINPUT* pipinput, /**< PIP reading data */
1647 const char* filename /**< name of the input file */
1648 )
1649{
1650 assert(pipinput != NULL);
1651
1652 /* open file */
1653 pipinput->file = SCIPfopen(filename, "r");
1654 if( pipinput->file == NULL )
1655 {
1656 SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
1657 SCIPprintSysError(filename);
1658 return SCIP_NOFILE;
1659 }
1660
1661 /* create problem */
1662 SCIP_CALL( SCIPcreateProb(scip, filename, NULL, NULL, NULL, NULL, NULL, NULL, NULL) );
1663
1664 /* parse the file */
1665 pipinput->section = PIP_START;
1666 while( pipinput->section != PIP_END && !hasError(pipinput) )
1667 {
1668 switch( pipinput->section )
1669 {
1670 case PIP_START:
1671 SCIP_CALL( readStart(scip, pipinput) );
1672 break;
1673
1674 case PIP_OBJECTIVE:
1675 SCIP_CALL( readObjective(scip, pipinput) );
1676 break;
1677
1678 case PIP_CONSTRAINTS:
1679 SCIP_CALL( readConstraints(scip, pipinput) );
1680 break;
1681
1682 case PIP_BOUNDS:
1683 SCIP_CALL( readBounds(scip, pipinput) );
1684 break;
1685
1686 case PIP_GENERALS:
1687 SCIP_CALL( readGenerals(scip, pipinput) );
1688 break;
1689
1690 case PIP_BINARIES:
1691 SCIP_CALL( readBinaries(scip, pipinput) );
1692 break;
1693
1694 case PIP_END: /* this is already handled in the while() loop */
1695 default:
1696 SCIPerrorMessage("invalid PIP file section <%d>\n", pipinput->section);
1697 return SCIP_INVALIDDATA;
1698 }
1699 }
1700
1701 /* close file */
1702 SCIPfclose(pipinput->file);
1703
1704 return SCIP_OKAY;
1705}
1706
1707
1708/*
1709 * Local methods (for writing)
1710 */
1711
1712/** hash key retrieval function for variables */
1713static
1715{ /*lint --e{715}*/
1716 return elem;
1717}
1718
1719/** returns TRUE iff the indices of both variables are equal */
1720static
1722{ /*lint --e{715}*/
1723 if ( key1 == key2 )
1724 return TRUE;
1725 return FALSE;
1726}
1727
1728/** returns the hash value of the key */
1729static
1731{ /*lint --e{715}*/
1732 assert( SCIPvarGetIndex((SCIP_VAR*) key) >= 0 );
1733 return (unsigned int) SCIPvarGetIndex((SCIP_VAR*) key);
1734}
1735
1736/** transforms given variables, scalars, and constant to the corresponding active variables, scalars, and constant */
1737static
1739 SCIP* scip, /**< SCIP data structure */
1740 SCIP_VAR*** vars, /**< pointer to vars array to get active variables for */
1741 SCIP_Real** scalars, /**< pointer to scalars a_1, ..., a_n in linear sum a_1*x_1 + ... + a_n*x_n + c */
1742 int* nvars, /**< pointer to number of variables and values in vars and vals array */
1743 SCIP_Real* constant, /**< pointer to constant c in linear sum a_1*x_1 + ... + a_n*x_n + c */
1744 SCIP_Bool transformed /**< transformed constraint? */
1745 )
1746{
1747 int requiredsize;
1748 int v;
1749
1750 assert(scip != NULL);
1751 assert(vars != NULL);
1752 assert(scalars != NULL);
1753 assert(nvars != NULL);
1754 assert(*vars != NULL || *nvars == 0);
1755 assert(*scalars != NULL || *nvars == 0);
1756 assert(constant != NULL);
1757
1758 if( transformed )
1759 {
1760 SCIP_CALL( SCIPgetProbvarLinearSum(scip, *vars, *scalars, nvars, *nvars, constant, &requiredsize) );
1761
1762 if( requiredsize > *nvars )
1763 {
1764 SCIP_CALL( SCIPreallocBufferArray(scip, vars, requiredsize) );
1765 SCIP_CALL( SCIPreallocBufferArray(scip, scalars, requiredsize) );
1766
1767 SCIP_CALL( SCIPgetProbvarLinearSum(scip, *vars, *scalars, nvars, requiredsize, constant, &requiredsize) );
1768 }
1769 assert( requiredsize == *nvars );
1770 }
1771 else
1772 {
1773 if( *nvars > 0 && ( *vars == NULL || *scalars == NULL ) ) /*lint !e774 !e845*/
1774 {
1775 SCIPerrorMessage("Null pointer in PIP reader\n"); /* should not happen */
1776 SCIPABORT();
1777 return SCIP_INVALIDDATA; /*lint !e527*/
1778 }
1779
1780 for( v = 0; v < *nvars; ++v )
1781 {
1782 SCIP_CALL( SCIPvarGetOrigvarSum(&(*vars)[v], &(*scalars)[v], constant) );
1783
1784 /* negated variables with an original counterpart may also be returned by SCIPvarGetOrigvarSum();
1785 * make sure we get the original variable in that case
1786 */
1787 if( SCIPvarGetStatus((*vars)[v]) == SCIP_VARSTATUS_NEGATED )
1788 {
1789 (*vars)[v] = SCIPvarGetNegatedVar((*vars)[v]);
1790 *constant += (*scalars)[v];
1791 (*scalars)[v] *= -1.0;
1792 }
1793 }
1794 }
1795 return SCIP_OKAY;
1796}
1797
1798/** checks whether a given expression is a signomial
1799 *
1800 * assumes simplified expression
1801 */
1802static
1804 SCIP* scip, /**< SCIP data structure */
1805 SCIP_EXPR* expr /**< expression */
1806 )
1807{
1808 assert(scip != NULL);
1809 assert(expr != NULL);
1810
1811 if( SCIPisExprVar(scip, expr) || SCIPisExprValue(scip, expr) )
1812 return TRUE;
1813
1814 if( SCIPisExprPower(scip, expr) && SCIPisExprVar(scip, SCIPexprGetChildren(expr)[0]) )
1815 return TRUE;
1816
1817 if( SCIPisExprProduct(scip, expr) )
1818 {
1819 SCIP_EXPR* child;
1820 int c;
1821
1822 for( c = 0; c < SCIPexprGetNChildren(expr); ++c )
1823 {
1824 child = SCIPexprGetChildren(expr)[c];
1825
1826 if( SCIPisExprVar(scip, child) )
1827 continue;
1828
1829 if( SCIPisExprPower(scip, child) && SCIPisExprVar(scip, SCIPexprGetChildren(child)[0]) )
1830 continue;
1831
1832 /* the pip format does not allow constants here */
1833
1834 return FALSE;
1835 }
1836
1837 return TRUE;
1838 }
1839
1840 return FALSE;
1841}
1842
1843/** checks whether a given expression is a sum of signomials (i.e., like a polynomial, but negative and fractional exponents allowed)
1844 *
1845 * assumes simplified expression;
1846 * does not check whether variables in powers with fractional exponent are nonnegative;
1847 * does not check whether variables in powers with negative exponent are bounded away from zero (the format specification does not require that, too)
1848 */
1849static
1851 SCIP* scip, /**< SCIP data structure */
1852 SCIP_EXPR* expr /**< expression */
1853 )
1854{
1855 int c;
1856
1857 assert(scip != NULL);
1858 assert(expr != NULL);
1859
1860 if( !SCIPisExprSum(scip, expr) )
1861 return isExprSignomial(scip, expr);
1862
1863 /* check whether every term of sum is signomial */
1864 for( c = 0; c < SCIPexprGetNChildren(expr); ++c )
1865 if( !isExprSignomial(scip, SCIPexprGetChildren(expr)[c]) )
1866 return FALSE;
1867
1868 return TRUE;
1869}
1870
1871/** clears the given line buffer */
1872static
1874 char* linebuffer, /**< line */
1875 int* linecnt /**< number of characters in line */
1876 )
1877{
1878 assert( linebuffer != NULL );
1879 assert( linecnt != NULL );
1880
1881 (*linecnt) = 0;
1882 linebuffer[0] = '\0';
1883}
1884
1885/** ends the given line with '\\0' and prints it to the given file stream */
1886static
1888 SCIP* scip, /**< SCIP data structure */
1889 FILE* file, /**< output file (or NULL for standard output) */
1890 char* linebuffer, /**< line */
1891 int* linecnt /**< number of characters in line */
1892 )
1893{
1894 assert( scip != NULL );
1895 assert( linebuffer != NULL );
1896 assert( linecnt != NULL );
1897 assert( 0 <= *linecnt && *linecnt < PIP_MAX_PRINTLEN );
1898
1899 if( (*linecnt) > 0 )
1900 {
1901 linebuffer[(*linecnt)] = '\0';
1902 SCIPinfoMessage(scip, file, "%s\n", linebuffer);
1903 clearLine(linebuffer, linecnt);
1904 }
1905}
1906
1907/** appends extension to line and prints it to the give file stream if the
1908 * line exceeded the length given in the define PIP_PRINTLEN */
1909static
1911 SCIP* scip, /**< SCIP data structure */
1912 FILE* file, /**< output file (or NULL for standard output) */
1913 char* linebuffer, /**< line */
1914 int* linecnt, /**< number of characters in line */
1915 const char* extension /**< string to extent the line */
1916 )
1917{
1918 assert( scip != NULL );
1919 assert( linebuffer != NULL );
1920 assert( linecnt != NULL );
1921 assert( extension != NULL );
1922 assert( strlen(linebuffer) + strlen(extension) < PIP_MAX_PRINTLEN );
1923
1924 /* NOTE: avoid
1925 * sprintf(linebuffer, "%s%s", linebuffer, extension);
1926 * because of overlapping memory areas in memcpy used in sprintf.
1927 */
1928 (void) strncat(linebuffer, extension, PIP_MAX_PRINTLEN - strlen(linebuffer));
1929
1930 (*linecnt) += (int) strlen(extension);
1931
1932 SCIPdebugMsg(scip, "linebuffer <%s>, length = %lu\n", linebuffer, (unsigned long)strlen(linebuffer));
1933
1934 if( (*linecnt) > PIP_PRINTLEN )
1935 endLine(scip, file, linebuffer, linecnt);
1936}
1937
1938
1939/** print linear or quadratic row in PIP format to file stream */
1940static
1942 SCIP* scip, /**< SCIP data structure */
1943 FILE* file, /**< output file (or NULL for standard output) */
1944 const char* rowname, /**< row name */
1945 const char* rownameextension, /**< row name extension */
1946 const char* type, /**< row type ("=", "<=", or ">=") */
1947 SCIP_VAR** linvars, /**< array of linear variables */
1948 SCIP_Real* linvals, /**< array of linear coefficient values */
1949 int nlinvars, /**< number of linear variables */
1950 SCIP_EXPR* quadexpr, /**< quadratic expression */
1951 SCIP_Real rhs, /**< right hand side */
1952 SCIP_Bool transformed /**< transformed constraint? */
1953 )
1954{
1955 int v;
1956 char linebuffer[PIP_MAX_PRINTLEN+1] = { '\0' };
1957 int linecnt;
1958
1959 char varname[PIP_MAX_NAMELEN];
1960 char varname2[PIP_MAX_NAMELEN];
1961 char consname[PIP_MAX_NAMELEN + 1]; /* an extra character for ':' */
1962 char buffer[PIP_MAX_PRINTLEN];
1963
1964 assert( scip != NULL );
1965 assert( strcmp(type, "=") == 0 || strcmp(type, "<=") == 0 || strcmp(type, ">=") == 0 );
1966 assert( nlinvars == 0 || (linvars != NULL && linvals != NULL) );
1967
1968 clearLine(linebuffer, &linecnt);
1969
1970 /* start each line with a space */
1971 appendLine(scip, file, linebuffer, &linecnt, " ");
1972
1973 /* print row name */
1974 if ( strlen(rowname) > 0 || strlen(rownameextension) > 0 )
1975 {
1976 (void) SCIPsnprintf(consname, PIP_MAX_NAMELEN + 1, "%s%s:", rowname, rownameextension);
1977 appendLine(scip, file, linebuffer, &linecnt, consname);
1978 }
1979
1980 /* print coefficients */
1981 for( v = 0; v < nlinvars; ++v )
1982 {
1983 SCIP_VAR* var;
1984
1985 assert(linvars != NULL); /* for lint */
1986 assert(linvals != NULL);
1987
1988 var = linvars[v];
1989 assert( var != NULL );
1990
1991 /* we start a new line; therefore we tab this line */
1992 if ( linecnt == 0 )
1993 appendLine(scip, file, linebuffer, &linecnt, " ");
1994
1995 (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
1996 (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g %s", linvals[v], varname);
1997
1998 appendLine(scip, file, linebuffer, &linecnt, buffer);
1999 }
2000
2001 /* print quadratic part */
2002 if( quadexpr != NULL )
2003 {
2004 SCIP_EXPR** linexprs;
2005 SCIP_VAR** activevars;
2006 SCIP_Real* activevals;
2007 SCIP_Real* lincoefs;
2008 SCIP_Real constant;
2009 SCIP_Real activeconstant = 0.0;
2010 int nbilinexprterms;
2011 int nactivevars;
2012 int nquadexprs;
2013 int nlinexprs;
2014
2015 /* get data from the quadratic expression */
2016 SCIPexprGetQuadraticData(quadexpr, &constant, &nlinexprs, &linexprs, &lincoefs, &nquadexprs, &nbilinexprterms,
2017 NULL, NULL);
2018
2019 /* allocate memory to store active linear variables */
2020 SCIP_CALL( SCIPallocBufferArray(scip, &activevars, nlinexprs) );
2021 SCIP_CALL( SCIPduplicateBufferArray(scip, &activevals, lincoefs, nlinexprs) );
2022 nactivevars = nlinexprs;
2023
2024 for( v = 0; v < nlinexprs; ++v )
2025 {
2026 assert(linexprs != NULL && linexprs[v] != NULL);
2027 assert(SCIPisExprVar(scip, linexprs[v]));
2028
2029 activevars[v] = SCIPgetVarExprVar(linexprs[v]);
2030 assert(activevars[v] != NULL);
2031 }
2032
2033 /* get active variables */
2034 SCIP_CALL( getActiveVariables(scip, &activevars, &activevals, &nactivevars, &activeconstant, transformed) );
2035 constant += activeconstant;
2036
2037 /* print linear coefficients of linear variables */
2038 for( v = 0; v < nactivevars; ++v )
2039 {
2040 SCIP_VAR* var;
2041
2042 assert(activevars != NULL); /* for lint */
2043 assert(activevals != NULL);
2044
2045 var = activevars[v];
2046 assert( var != NULL );
2047
2048 /* we start a new line; therefore we tab this line */
2049 if( linecnt == 0 )
2050 appendLine(scip, file, linebuffer, &linecnt, " ");
2051
2052 (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
2053 (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g %s", activevals[v], varname);
2054
2055 appendLine(scip, file, linebuffer, &linecnt, buffer);
2056 }
2057
2058 /* free memory for active linear variables */
2059 SCIPfreeBufferArray(scip, &activevals);
2060 SCIPfreeBufferArray(scip, &activevars);
2061
2062 /* adjust rhs if there is a constant */
2063 if( constant != 0.0 && !SCIPisInfinity(scip, rhs) )
2064 rhs -= constant;
2065
2066 /* print linear coefficients of quadratic variables */
2067 for( v = 0; v < nquadexprs; ++v )
2068 {
2069 SCIP_EXPR* expr;
2070 SCIP_VAR* var;
2071 SCIP_Real lincoef;
2072
2073 /* get linear coefficient and variable of quadratic term */
2074 SCIPexprGetQuadraticQuadTerm(quadexpr, v, &expr, &lincoef, NULL, NULL, NULL, NULL);
2075 assert(expr != NULL);
2076 assert(SCIPisExprVar(scip, expr));
2077
2078 var = SCIPgetVarExprVar(expr);
2079 assert(var != NULL);
2080
2081 if( lincoef == 0.0 )
2082 continue;
2083
2084 /* we start a new line; therefore we tab this line */
2085 if( linecnt == 0 )
2086 appendLine(scip, file, linebuffer, &linecnt, " ");
2087
2088 (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
2089 (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g %s", lincoef, varname);
2090
2091 appendLine(scip, file, linebuffer, &linecnt, buffer);
2092 }
2093
2094 /* print square terms */
2095 for( v = 0; v < nquadexprs; ++v )
2096 {
2097 SCIP_EXPR* expr;
2098 SCIP_VAR* var;
2099 SCIP_Real sqrcoef;
2100
2101 /* get square coefficient and variable of quadratic term */
2102 SCIPexprGetQuadraticQuadTerm(quadexpr, v, &expr, NULL, &sqrcoef, NULL, NULL, NULL);
2103 assert(expr != NULL);
2104 assert(SCIPisExprVar(scip, expr));
2105
2106 var = SCIPgetVarExprVar(expr);
2107 assert(var != NULL);
2108
2109 if( sqrcoef == 0.0 )
2110 continue;
2111
2112 /* we start a new line; therefore we tab this line */
2113 if( linecnt == 0 )
2114 appendLine(scip, file, linebuffer, &linecnt, " ");
2115
2116 (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
2117 (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g %s^2", sqrcoef, varname);
2118
2119 appendLine(scip, file, linebuffer, &linecnt, buffer);
2120 }
2121
2122 /* print bilinear terms */
2123 for( v = 0; v < nbilinexprterms; ++v )
2124 {
2125 SCIP_EXPR* expr1;
2126 SCIP_EXPR* expr2;
2127 SCIP_VAR* var1;
2128 SCIP_VAR* var2;
2129 SCIP_Real bilincoef;
2130
2131 /* get coefficient and variables of bilinear */
2132 SCIPexprGetQuadraticBilinTerm(quadexpr, v, &expr1, &expr2, &bilincoef, NULL, NULL);
2133 assert(expr1 != NULL);
2134 assert(SCIPisExprVar(scip, expr1));
2135 assert(expr2 != NULL);
2136 assert(SCIPisExprVar(scip, expr2));
2137
2138 var1 = SCIPgetVarExprVar(expr1);
2139 assert(var1 != NULL);
2140 var2 = SCIPgetVarExprVar(expr2);
2141 assert(var2 != NULL);
2142
2143 /* we start a new line; therefore we tab this line */
2144 if( linecnt == 0 )
2145 appendLine(scip, file, linebuffer, &linecnt, " ");
2146
2147 (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(var1));
2148 (void) SCIPsnprintf(varname2, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(var2));
2149 (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g %s * %s", bilincoef, varname, varname2);
2150
2151 appendLine(scip, file, linebuffer, &linecnt, buffer);
2152 }
2153 }
2154
2155 /* print right hand side */
2156 if( SCIPisZero(scip, rhs) )
2157 rhs = 0.0;
2158
2159 (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %s %+.15g", type, rhs);
2160
2161 /* we start a new line; therefore we tab this line */
2162 if (linecnt == 0 )
2163 appendLine(scip, file, linebuffer, &linecnt, " ");
2164 appendLine(scip, file, linebuffer, &linecnt, buffer);
2165
2166 endLine(scip, file, linebuffer, &linecnt);
2167
2168 return SCIP_OKAY;
2169}
2170
2171/** print signomial in PIP format to file stream */
2172static
2174 SCIP* scip, /**< SCIP data structure */
2175 FILE* file, /**< output file (or NULL for standard output) */
2176 char* linebuffer, /**< line buffer to append to */
2177 int* linecnt, /**< count on line buffer use */
2178 SCIP_EXPR* expr, /**< sigomial expression */
2179 SCIP_Real coef, /**< coefficient */
2180 SCIP_Bool needsign /**< whether a sign needs to be ensured */
2181 )
2182{
2183 char buffer[PIP_MAX_PRINTLEN];
2184 SCIP_EXPR* child;
2185 int c;
2186
2187 assert(isExprSignomial(scip, expr));
2188
2189 if( SCIPisExprProduct(scip, expr) )
2190 coef *= SCIPgetCoefExprProduct(expr);
2191
2192 if( SCIPisExprValue(scip, expr) )
2193 coef *= SCIPgetValueExprValue(expr);
2194
2195 if( REALABS(coef) != 1.0 )
2196 {
2197 (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, needsign ? " %+.15g " : " %.15g ", coef);
2198 appendLine(scip, file, linebuffer, linecnt, buffer);
2199 }
2200 else if( coef == 1.0 && needsign )
2201 {
2202 appendLine(scip, file, linebuffer, linecnt, " + ");
2203 }
2204 else if( coef == -1.0 )
2205 {
2206 appendLine(scip, file, linebuffer, linecnt, " - ");
2207 }
2208 else
2209 {
2210 appendLine(scip, file, linebuffer, linecnt, " ");
2211 }
2212
2213 if( SCIPisExprVar(scip, expr) )
2214 {
2215 appendLine(scip, file, linebuffer, linecnt, SCIPvarGetName(SCIPgetVarExprVar(expr)));
2216 return;
2217 }
2218
2219 if( SCIPisExprValue(scip, expr) )
2220 {
2221 if( REALABS(coef) == 1.0 )
2222 {
2223 /* in this case, we will have printed only a sign or space above, so print also a 1.0 */
2224 appendLine(scip, file, linebuffer, linecnt, "1.0");
2225 }
2226 return;
2227 }
2228
2229 if( SCIPisExprPower(scip, expr) )
2230 {
2231 assert(SCIPisExprVar(scip, SCIPexprGetChildren(expr)[0]));
2232
2234 appendLine(scip, file, linebuffer, linecnt, buffer);
2235
2236 return;
2237 }
2238
2239 assert(SCIPisExprProduct(scip, expr));
2240 for( c = 0; c < SCIPexprGetNChildren(expr); ++c )
2241 {
2242 child = SCIPexprGetChildren(expr)[c];
2243
2244 if( c > 0 )
2245 appendLine(scip, file, linebuffer, linecnt, " ");
2246
2247 if( SCIPisExprVar(scip, child) )
2248 {
2249 appendLine(scip, file, linebuffer, linecnt, SCIPvarGetName(SCIPgetVarExprVar(child)));
2250 continue;
2251 }
2252
2253 assert(SCIPisExprPower(scip, child));
2254 assert(SCIPisExprVar(scip, SCIPexprGetChildren(child)[0]));
2255
2257 appendLine(scip, file, linebuffer, linecnt, buffer);
2258 }
2259}
2260
2261/** print polynomial row in PIP format to file stream */
2262static
2264 SCIP* scip, /**< SCIP data structure */
2265 FILE* file, /**< output file (or NULL for standard output) */
2266 const char* rowname, /**< row name */
2267 const char* rownameextension, /**< row name extension */
2268 const char* type, /**< row type ("=", "<=", or ">=") */
2269 SCIP_EXPR* expr, /**< polynomial expression */
2270 SCIP_Real rhs /**< right hand side */
2271 )
2272{
2273 char consname[PIP_MAX_NAMELEN + 1]; /* an extra character for ':' */
2274 char buffer[PIP_MAX_PRINTLEN];
2275 char linebuffer[PIP_MAX_PRINTLEN+1] = { '\0' };
2276 int linecnt;
2277
2278 assert(scip != NULL);
2279 assert(strcmp(type, "=") == 0 || strcmp(type, "<=") == 0 || strcmp(type, ">=") == 0);
2280 assert(expr != NULL);
2281
2282 clearLine(linebuffer, &linecnt);
2283
2284 /* start each line with a space */
2285 appendLine(scip, file, linebuffer, &linecnt, " ");
2286
2287 /* print row name */
2288 if( strlen(rowname) > 0 || strlen(rownameextension) > 0 )
2289 {
2290 (void) SCIPsnprintf(consname, PIP_MAX_NAMELEN + 1, "%s%s:", rowname, rownameextension);
2291 appendLine(scip, file, linebuffer, &linecnt, consname);
2292 }
2293
2294 if( SCIPisExprSum(scip, expr) )
2295 {
2296 int c;
2297 SCIP_Bool needsign = FALSE;
2298
2299 if( SCIPgetConstantExprSum(expr) != 0.0 )
2300 {
2301 (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g", SCIPgetConstantExprSum(expr));
2302 appendLine(scip, file, linebuffer, &linecnt, buffer);
2303
2304 needsign = TRUE;
2305 }
2306
2307 for( c = 0; c < SCIPexprGetNChildren(expr); ++c )
2308 {
2309 printSignomial(scip, file, linebuffer, &linecnt, SCIPexprGetChildren(expr)[c], SCIPgetCoefsExprSum(expr)[c], needsign);
2310 needsign = TRUE;
2311 }
2312 }
2313 else
2314 {
2315 printSignomial(scip, file, linebuffer, &linecnt, expr, 1.0, FALSE);
2316 }
2317
2318 /* print right hand side */
2319 (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %s %+.15g", type, rhs);
2320
2321 /* we start a new line; therefore we tab this line */
2322 if( linecnt == 0 )
2323 appendLine(scip, file, linebuffer, &linecnt, " ");
2324 appendLine(scip, file, linebuffer, &linecnt, buffer);
2325
2326 endLine(scip, file, linebuffer, &linecnt);
2327}
2328
2329/** print "and" constraint as row in PIP format to file stream */
2330static
2332 SCIP* scip, /**< SCIP data structure */
2333 FILE* file, /**< output file (or NULL for standard output) */
2334 const char* rowname, /**< row name */
2335 SCIP_CONS* cons /**< "and" constraint */
2336 )
2337{
2338 char linebuffer[PIP_MAX_PRINTLEN+1] = { '\0' };
2339 int linecnt;
2340 int i;
2341
2342 assert(scip != NULL);
2343 assert(rowname != NULL);
2344 assert(cons != NULL);
2345
2346 clearLine(linebuffer, &linecnt);
2347
2348 /* start each line with a space */
2349 appendLine(scip, file, linebuffer, &linecnt, " ");
2350
2351 /* print row name */
2352 if( strlen(rowname) > 0 )
2353 {
2354 appendLine(scip, file, linebuffer, &linecnt, rowname);
2355 appendLine(scip, file, linebuffer, &linecnt, ":");
2356 }
2357
2358 for( i = 0; i < SCIPgetNVarsAnd(scip, cons); ++i )
2359 {
2360 appendLine(scip, file, linebuffer, &linecnt, " ");
2361 appendLine(scip, file, linebuffer, &linecnt, SCIPvarGetName(SCIPgetVarsAnd(scip, cons)[i]));
2362 }
2363
2364 appendLine(scip, file, linebuffer, &linecnt, " - ");
2365 appendLine(scip, file, linebuffer, &linecnt, SCIPvarGetName(SCIPgetResultantAnd(scip, cons)));
2366
2367 /* we start a new line; therefore we tab this line */
2368 if( linecnt == 0 )
2369 appendLine(scip, file, linebuffer, &linecnt, " ");
2370
2371 /* print right hand side */
2372 appendLine(scip, file, linebuffer, &linecnt, " = 0");
2373
2374 endLine(scip, file, linebuffer, &linecnt);
2375}
2376
2377/** prints given (linear or) quadratic constraint information in LP format to file stream */
2378static
2380 SCIP* scip, /**< SCIP data structure */
2381 FILE* file, /**< output file (or NULL for standard output) */
2382 const char* rowname, /**< name of the row */
2383 SCIP_VAR** linvars, /**< array of linear variables */
2384 SCIP_Real* linvals, /**< array of linear coefficients values (or NULL if all linear coefficient values are 1) */
2385 int nlinvars, /**< number of linear variables */
2386 SCIP_EXPR* quadexpr, /**< quadratic expression (or NULL if nlinvars > 0) */
2387 SCIP_Real lhs, /**< left hand side */
2388 SCIP_Real rhs, /**< right hand side */
2389 SCIP_Bool transformed /**< transformed constraint? */
2390 )
2391{
2392 int v;
2393 SCIP_VAR** activevars = NULL;
2394 SCIP_Real* activevals = NULL;
2395 int nactivevars;
2396 SCIP_Real activeconstant = 0.0;
2397
2398 assert( scip != NULL );
2399 assert( rowname != NULL );
2400
2401 assert( nlinvars == 0 || linvars != NULL );
2402 assert( quadexpr == NULL || nlinvars == 0);
2403 assert( lhs <= rhs );
2404
2405 if( SCIPisInfinity(scip, -lhs) && SCIPisInfinity(scip, rhs) )
2406 return SCIP_OKAY;
2407
2408 nactivevars = nlinvars;
2409 if( nlinvars > 0 )
2410 {
2411 /* duplicate variable and value array */
2412 SCIP_CALL( SCIPduplicateBufferArray(scip, &activevars, linvars, nactivevars ) );
2413 if( linvals != NULL )
2414 {
2415 SCIP_CALL( SCIPduplicateBufferArray(scip, &activevals, linvals, nactivevars ) );
2416 }
2417 else
2418 {
2419 SCIP_CALL( SCIPallocBufferArray(scip, &activevals, nactivevars) );
2420
2421 for( v = 0; v < nactivevars; ++v )
2422 activevals[v] = 1.0;
2423 }
2424
2425 /* retransform given variables to active variables */
2426 SCIP_CALL( getActiveVariables(scip, &activevars, &activevals, &nactivevars, &activeconstant, transformed) );
2427 }
2428
2429 /* print row(s) in LP format */
2430 if( SCIPisEQ(scip, lhs, rhs) )
2431 {
2432 assert( !SCIPisInfinity(scip, rhs) );
2433
2434 /* equal constraint */
2435 SCIP_CALL( printRow(scip, file, rowname, "", "=", activevars, activevals, nactivevars, quadexpr,
2436 rhs - activeconstant, transformed) );
2437 }
2438 else
2439 {
2440 if( !SCIPisInfinity(scip, -lhs) )
2441 {
2442 /* print inequality ">=" */
2443 SCIP_CALL( printRow(scip, file, rowname, SCIPisInfinity(scip, rhs) ? "" : "_lhs", ">=", activevars,
2444 activevals, nactivevars, quadexpr, lhs - activeconstant, transformed) );
2445 }
2446 if( !SCIPisInfinity(scip, rhs) )
2447 {
2448 /* print inequality "<=" */
2449 SCIP_CALL( printRow(scip, file, rowname, SCIPisInfinity(scip, -lhs) ? "" : "_rhs", "<=", activevars,
2450 activevals, nactivevars, quadexpr, rhs - activeconstant, transformed) );
2451 }
2452 }
2453
2454 if( nlinvars > 0 )
2455 {
2456 /* free buffer arrays */
2457 SCIPfreeBufferArray(scip, &activevars);
2458 SCIPfreeBufferArray(scip, &activevals);
2459 }
2460
2461 return SCIP_OKAY;
2462}
2463
2464/** prints given nonlinear constraint information in LP format to file stream */
2465static
2467 SCIP* scip, /**< SCIP data structure */
2468 FILE* file, /**< output file (or NULL for standard output) */
2469 const char* rowname, /**< name of the row */
2470 SCIP_EXPR* expr, /**< polynomial expression */
2471 SCIP_Real lhs, /**< left hand side */
2472 SCIP_Real rhs /**< right hand side */
2473 )
2474{
2475 assert(scip != NULL);
2476 assert(rowname != NULL);
2477 assert(expr != NULL);
2478 assert(lhs <= rhs);
2479
2480 if( SCIPisInfinity(scip, -lhs) && SCIPisInfinity(scip, rhs) )
2481 return SCIP_OKAY;
2482
2483 /* print row(s) in LP format */
2484 if( SCIPisEQ(scip, lhs, rhs) )
2485 {
2486 assert( !SCIPisInfinity(scip, rhs) );
2487
2488 /* equal constraint */
2489 printRowNl(scip, file, rowname, "", "=", expr, rhs);
2490 }
2491 else
2492 {
2493 if( !SCIPisInfinity(scip, -lhs) )
2494 {
2495 /* print inequality ">=" */
2496 printRowNl(scip, file, rowname, SCIPisInfinity(scip, rhs) ? "" : "_lhs", ">=", expr, lhs);
2497 }
2498 if( !SCIPisInfinity(scip, rhs) )
2499 {
2500 /* print inequality "<=" */
2501 printRowNl(scip, file, rowname, SCIPisInfinity(scip, -lhs) ? "" : "_rhs", "<=", expr, rhs);
2502 }
2503 }
2504
2505 return SCIP_OKAY;
2506}
2507
2508/** check whether given variables are aggregated and put them into an array without duplication */
2509static
2511 int nvars, /**< number of active variables in the problem */
2512 SCIP_VAR** vars, /**< variable array */
2513 int* nAggregatedVars, /**< number of aggregated variables on output */
2514 SCIP_VAR*** aggregatedVars, /**< array storing the aggregated variables on output */
2515 SCIP_HASHTABLE** varAggregated /**< hashtable for checking duplicates */
2516 )
2517{
2518 int j;
2519
2520 /* check variables */
2521 for (j = 0; j < nvars; ++j)
2522 {
2523 SCIP_VARSTATUS status;
2524 SCIP_VAR* var;
2525
2526 var = vars[j];
2527 status = SCIPvarGetStatus(var);
2528
2529 /* collect aggregated variables in a list */
2530 if( status >= SCIP_VARSTATUS_AGGREGATED )
2531 {
2532 assert( status == SCIP_VARSTATUS_AGGREGATED ||
2533 status == SCIP_VARSTATUS_MULTAGGR ||
2534 status == SCIP_VARSTATUS_NEGATED );
2535
2536 if ( ! SCIPhashtableExists(*varAggregated, (void*) var) )
2537 {
2538 (*aggregatedVars)[(*nAggregatedVars)++] = var;
2539 SCIP_CALL( SCIPhashtableInsert(*varAggregated, (void*) var) );
2540 }
2541 }
2542 }
2543
2544 return SCIP_OKAY;
2545}
2546
2547
2548/** print aggregated variable-constraints */
2549static
2551 SCIP* scip, /**< SCIP data structure */
2552 FILE* file, /**< output file (or NULL for standard output) */
2553 SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
2554 int nvars, /**< number of active variables in the problem */
2555 int nAggregatedVars, /**< number of aggregated variables */
2556 SCIP_VAR** aggregatedVars /**< array storing the aggregated variables */
2557 )
2558{
2559 int j;
2560
2561 SCIP_VAR** activevars;
2562 SCIP_Real* activevals;
2563 int nactivevars;
2564 SCIP_Real activeconstant;
2565 char consname[PIP_MAX_NAMELEN];
2566
2567 assert( scip != NULL );
2568
2569 /* write aggregation constraints */
2570 SCIP_CALL( SCIPallocBufferArray(scip, &activevars, nvars) );
2571 SCIP_CALL( SCIPallocBufferArray(scip, &activevals, nvars) );
2572
2573 for (j = 0; j < nAggregatedVars; ++j)
2574 {
2575 /* set up list to obtain substitution variables */
2576 nactivevars = 1;
2577
2578 activevars[0] = aggregatedVars[j];
2579 activevals[0] = 1.0;
2580 activeconstant = 0.0;
2581
2582 /* retransform given variables to active variables */
2583 SCIP_CALL( getActiveVariables(scip, &activevars, &activevals, &nactivevars, &activeconstant, transformed) );
2584
2585 activevals[nactivevars] = -1.0;
2586 activevars[nactivevars] = aggregatedVars[j];
2587 ++nactivevars;
2588
2589 /* output constraint */
2590 (void) SCIPsnprintf(consname, PIP_MAX_NAMELEN, "aggr_%s", SCIPvarGetName(aggregatedVars[j]));
2591 SCIP_CALL( printRow(scip, file, consname, "", "=", activevars, activevals, nactivevars, NULL, - activeconstant,
2592 transformed) );
2593 }
2594
2595 /* free buffer arrays */
2596 SCIPfreeBufferArray(scip, &activevars);
2597 SCIPfreeBufferArray(scip, &activevals);
2598
2599 return SCIP_OKAY;
2600}
2601
2602/** returns whether name is valid according to PIP specification
2603 *
2604 * Checks these two conditions from http://polip.zib.de/pipformat.php:
2605 * - Names/labels can contain at most 255 characters.
2606 * - Name/labels have to consist of the following characters: a-z, A-Z, 0-9, "!", "#", "$", "%", "&", ";", "?", "@", "_". They cannot start with a number.
2607 *
2608 * In addition checks that the length is not zero.
2609 */
2610static
2612 const char* name /**< name to check */
2613 )
2614{
2615 size_t len;
2616 size_t i;
2617
2618 assert(name != NULL);
2619
2620 len = strlen(name); /*lint !e613*/
2621 if( len > (size_t) PIP_MAX_NAMELEN || len == 0 )
2622 return FALSE;
2623
2624 /* names cannot start with a number */
2625 if( isdigit((unsigned char)name[0]) )
2626 return FALSE;
2627
2628 for( i = 0; i < len; ++i )
2629 {
2630 /* a-z, A-Z, 0-9 are ok */
2631 if( isalnum((unsigned char)name[i]) )
2632 continue;
2633
2634 /* characters in namechars are ok, too */
2635 if( strchr(namechars, name[i]) != NULL )
2636 continue;
2637
2638 return FALSE;
2639 }
2640
2641 return TRUE;
2642}
2643
2644
2645/** method check if the variable names are valid according to PIP specification */
2646static
2648 SCIP* scip, /**< SCIP data structure */
2649 SCIP_VAR** vars, /**< array of variables */
2650 int nvars /**< number of variables */
2651 )
2652{
2653 int v;
2654
2655 assert(scip != NULL);
2656 assert(vars != NULL || nvars == 0);
2657
2658 /* check if the variable names are not too long and have only characters allowed by PIP */
2659 for( v = 0; v < nvars; ++v )
2660 {
2661 if( !isNameValid(SCIPvarGetName(vars[v])) )
2662 {
2663 SCIPwarningMessage(scip, "variable name <%s> is not valid (too long or disallowed characters); PIP might be corrupted\n", SCIPvarGetName(vars[v]));
2664 return;
2665 }
2666 }
2667}
2668
2669/** method check if the constraint names are valid according to PIP specification */
2670static
2672 SCIP* scip, /**< SCIP data structure */
2673 SCIP_CONS** conss, /**< array of constraints */
2674 int nconss, /**< number of constraints */
2675 SCIP_Bool transformed /**< TRUE iff problem is the transformed problem */
2676 )
2677{
2678 int c;
2679 SCIP_CONS* cons;
2680 SCIP_CONSHDLR* conshdlr;
2681 const char* conshdlrname;
2682
2683 assert( scip != NULL );
2684 assert( conss != NULL || nconss == 0 );
2685
2686 for( c = 0; c < nconss; ++c )
2687 {
2688 assert(conss != NULL); /* for lint */
2689 cons = conss[c];
2690 assert(cons != NULL );
2691
2692 /* in case the transformed is written only constraints are posted which are enabled in the current node */
2693 assert(!transformed || SCIPconsIsEnabled(cons));
2694
2695 conshdlr = SCIPconsGetHdlr(cons);
2696 assert( conshdlr != NULL );
2697
2698 conshdlrname = SCIPconshdlrGetName(conshdlr);
2699 assert( transformed == SCIPconsIsTransformed(cons) );
2700
2701 if( !isNameValid(SCIPconsGetName(cons)) )
2702 {
2703 SCIPwarningMessage(scip, "constraint name <%s> is not valid (too long or unallowed characters); PIP might be corrupted\n", SCIPconsGetName(cons));
2704 return;
2705 }
2706
2707 if( strcmp(conshdlrname, "linear") == 0 )
2708 {
2709 SCIP_Real lhs = SCIPgetLhsLinear(scip, cons);
2710 SCIP_Real rhs = SCIPgetRhsLinear(scip, cons);
2711
2712 /* for ranged constraints, we need to be able to append _lhs and _rhs to the constraint name, so need additional 4 characters */
2713 if( !SCIPisEQ(scip, lhs, rhs) && strlen(SCIPconsGetName(conss[c])) > (size_t) PIP_MAX_NAMELEN - 4 )
2714 {
2715 SCIPwarningMessage(scip, "name of ranged constraint <%s> has to be cut down to %d characters;\n", SCIPconsGetName(conss[c]),
2716 PIP_MAX_NAMELEN - 1);
2717 return;
2718 }
2719 }
2720 }
2721}
2722
2723/** writes problem to file
2724 * @todo add writing cons_pseudoboolean
2725 */
2727 SCIP* scip, /**< SCIP data structure */
2728 FILE* file, /**< output file, or NULL if standard output should be used */
2729 const char* name, /**< problem name */
2730 SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
2731 SCIP_OBJSENSE objsense, /**< objective sense */
2732 SCIP_Real objscale, /**< scalar applied to objective function; external objective value is
2733 * extobj = objsense * objscale * (intobj + objoffset) */
2734 SCIP_Real objoffset, /**< objective offset from bound shifting and fixing */
2735 SCIP_VAR** vars, /**< array with active variables ordered binary, integer, implicit, continuous */
2736 int nvars, /**< number of active variables in the problem */
2737 int nbinvars, /**< number of binary variables */
2738 int nintvars, /**< number of general integer variables */
2739 int nimplvars, /**< number of implicit integer variables */
2740 int ncontvars, /**< number of continuous variables */
2741 SCIP_CONS** conss, /**< array with constraints of the problem */
2742 int nconss, /**< number of constraints in the problem */
2743 SCIP_RESULT* result /**< pointer to store the result of the file writing call */
2744 )
2745{
2746 int c;
2747 int v;
2748
2749 int linecnt;
2750 char linebuffer[PIP_MAX_PRINTLEN+1];
2751
2752 char varname[PIP_MAX_NAMELEN];
2753 char buffer[PIP_MAX_PRINTLEN];
2754
2755 SCIP_CONSHDLR* conshdlr;
2756 const char* conshdlrname;
2757 SCIP_CONS* cons;
2758 SCIP_CONS** consNonlinear;
2759 int nConsNonlinear;
2760 SCIP_CONS** consAnd;
2761 int nConsAnd;
2762 char consname[PIP_MAX_NAMELEN];
2763
2764 SCIP_VAR** aggregatedVars;
2765 int nAggregatedVars;
2766 SCIP_HASHTABLE* varAggregated;
2767
2768 SCIP_VAR** tmpvars;
2769 int tmpvarssize;
2770
2771 SCIP_VAR** consvars;
2772 SCIP_Real* consvals;
2773 int nconsvars;
2774
2775 SCIP_VAR* var;
2776 SCIP_Real lb;
2777 SCIP_Real ub;
2778
2779 int implintlevel;
2780 int nintegers = nvars - ncontvars;
2781 assert(nintegers >= 0);
2782
2783 nAggregatedVars = 0;
2784 nConsNonlinear = 0;
2785 nConsAnd = 0;
2786
2787 /* check if the variable names are not to long */
2788 checkVarnames(scip, vars, nvars);
2789
2790 /* check if the constraint names are to long */
2791 checkConsnames(scip, conss, nconss, transformed);
2792
2793 /* adjust written integrality constraints on implied integral variables based on the implied integral level */
2794 SCIP_CALL( SCIPgetIntParam(scip, "write/implintlevel", &implintlevel) );
2795 assert(implintlevel >= -2);
2796 assert(implintlevel <= 2);
2797
2798 /* print statistics as comment to file */
2799 SCIPinfoMessage(scip, file, "\\ SCIP STATISTICS\n");
2800 SCIPinfoMessage(scip, file, "\\ Problem name : %s\n", name);
2801 SCIPinfoMessage(scip, file, "\\ Variables : %d (%d binary, %d integer, %d implicit integer, %d continuous)\n",
2802 nvars, nbinvars, nintvars, nimplvars, ncontvars);
2803 SCIPinfoMessage(scip, file, "\\ Constraints : %d\n", nconss);
2804
2805 /* print objective sense */
2806 SCIPinfoMessage(scip, file, "%s\n", objsense == SCIP_OBJSENSE_MINIMIZE ? "Minimize" : "Maximize");
2807
2808 clearLine(linebuffer, &linecnt);
2809 appendLine(scip, file, linebuffer, &linecnt, " Obj:");
2810
2811 for (v = 0; v < nvars; ++v)
2812 {
2813 var = vars[v];
2814
2815#ifndef NDEBUG
2816 /* in case the original problem has to be posted the variables have to be either "original" or "negated" */
2817 if ( !transformed )
2819#endif
2820
2821 if ( SCIPisZero(scip, SCIPvarGetObj(var)) )
2822 continue;
2823
2824 /* we start a new line; therefore we tab this line */
2825 if ( linecnt == 0 )
2826 appendLine(scip, file, linebuffer, &linecnt, " ");
2827
2828 (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
2829 (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g %s", objscale * SCIPvarGetObj(var), varname );
2830
2831 appendLine(scip, file, linebuffer, &linecnt, buffer);
2832 }
2833
2834 if( ! SCIPisZero(scip, objoffset) )
2835 {
2836 (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g", objscale * objoffset);
2837 appendLine(scip, file, linebuffer, &linecnt, buffer);
2838 }
2839
2840 endLine(scip, file, linebuffer, &linecnt);
2841
2842 /* print "Subject to" section */
2843 SCIPinfoMessage(scip, file, "Subject to\n");
2844
2845 /* collect quadratic, nonlinear, absolute power, and, and bivariate constraints in arrays */
2846 SCIP_CALL( SCIPallocBufferArray(scip, &consNonlinear, nconss) );
2847 SCIP_CALL( SCIPallocBufferArray(scip, &consAnd, nconss) );
2848
2849 tmpvarssize = SCIPgetNTotalVars(scip);
2850 SCIP_CALL( SCIPallocBufferArray(scip, &tmpvars, tmpvarssize) );
2851
2852 for (c = 0; c < nconss; ++c)
2853 {
2854 cons = conss[c];
2855 assert( cons != NULL);
2856
2857 /* in case the transformed is written only constraints are posted which are enabled in the current node */
2858 assert(!transformed || SCIPconsIsEnabled(cons));
2859
2860 conshdlr = SCIPconsGetHdlr(cons);
2861 assert( conshdlr != NULL );
2862
2863 (void) SCIPsnprintf(consname, PIP_MAX_NAMELEN, "%s", SCIPconsGetName(cons));
2864 conshdlrname = SCIPconshdlrGetName(conshdlr);
2865 assert( transformed == SCIPconsIsTransformed(cons) );
2866
2867 if( strcmp(conshdlrname, "linear") == 0 )
2868 {
2869 SCIP_CALL( printQuadraticCons(scip, file, consname,
2871 NULL, SCIPgetLhsLinear(scip, cons), SCIPgetRhsLinear(scip, cons), transformed) );
2872 }
2873 else if( strcmp(conshdlrname, "setppc") == 0 )
2874 {
2875 consvars = SCIPgetVarsSetppc(scip, cons);
2876 nconsvars = SCIPgetNVarsSetppc(scip, cons);
2877
2878 switch( SCIPgetTypeSetppc(scip, cons) )
2879 {
2881 SCIP_CALL( printQuadraticCons(scip, file, consname,
2882 consvars, NULL, nconsvars, NULL, 1.0, 1.0, transformed) );
2883 break;
2885 SCIP_CALL( printQuadraticCons(scip, file, consname,
2886 consvars, NULL, nconsvars, NULL, -SCIPinfinity(scip), 1.0, transformed) );
2887 break;
2889 SCIP_CALL( printQuadraticCons(scip, file, consname,
2890 consvars, NULL, nconsvars, NULL, 1.0, SCIPinfinity(scip), transformed) );
2891 break;
2892 }
2893 }
2894 else if ( strcmp(conshdlrname, "logicor") == 0 )
2895 {
2896 SCIP_CALL( printQuadraticCons(scip, file, consname,
2898 NULL, 1.0, SCIPinfinity(scip), transformed) );
2899 }
2900 else if ( strcmp(conshdlrname, "knapsack") == 0 )
2901 {
2902 SCIP_Longint* weights;
2903
2904 consvars = SCIPgetVarsKnapsack(scip, cons);
2905 nconsvars = SCIPgetNVarsKnapsack(scip, cons);
2906
2907 /* copy Longint array to SCIP_Real array */
2908 weights = SCIPgetWeightsKnapsack(scip, cons);
2909 SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nconsvars) );
2910 for( v = 0; v < nconsvars; ++v )
2911 consvals[v] = (SCIP_Real)weights[v];
2912
2913 SCIP_CALL( printQuadraticCons(scip, file, consname, consvars, consvals, nconsvars,
2914 NULL, -SCIPinfinity(scip), (SCIP_Real) SCIPgetCapacityKnapsack(scip, cons), transformed) );
2915
2916 SCIPfreeBufferArray(scip, &consvals);
2917 }
2918 else if ( strcmp(conshdlrname, "varbound") == 0 )
2919 {
2920 SCIP_CALL( SCIPallocBufferArray(scip, &consvars, 2) );
2921 SCIP_CALL( SCIPallocBufferArray(scip, &consvals, 2) );
2922
2923 consvars[0] = SCIPgetVarVarbound(scip, cons);
2924 consvars[1] = SCIPgetVbdvarVarbound(scip, cons);
2925
2926 consvals[0] = 1.0;
2927 consvals[1] = SCIPgetVbdcoefVarbound(scip, cons);
2928
2929 SCIP_CALL( printQuadraticCons(scip, file, consname, consvars, consvals, 2, NULL,
2930 SCIPgetLhsVarbound(scip, cons), SCIPgetRhsVarbound(scip, cons), transformed) );
2931
2932 SCIPfreeBufferArray(scip, &consvars);
2933 SCIPfreeBufferArray(scip, &consvals);
2934 }
2935 else if( strcmp(conshdlrname, "nonlinear") == 0 )
2936 {
2937 SCIP_Bool ispolynomial;
2938 SCIP_Bool isquadratic;
2939 SCIP_EXPR* simplifiedexpr = NULL;
2940
2941 ispolynomial = isExprPolynomial(scip, SCIPgetExprNonlinear(cons));
2942 if( !ispolynomial )
2943 {
2944 /* simplify expression and check again if polynomial
2945 * simplifying the expr owned by the cons can have undesired sideffects onto the consdata (the varhashmap can get messed up), so we copy first
2946 */
2947 SCIP_EXPR* exprcopy;
2948 SCIP_Bool changed;
2949 SCIP_Bool infeasible;
2950
2952 SCIP_CALL( SCIPsimplifyExpr(scip, exprcopy, &simplifiedexpr, &changed, &infeasible, NULL, NULL) );
2953 SCIP_CALL( SCIPreleaseExpr(scip, &exprcopy) );
2954
2955 ispolynomial = isExprPolynomial(scip, simplifiedexpr);
2956 }
2957
2958 /* nonlinear constraints that are not polynomial cannot be printed as PIP */
2959 if( !ispolynomial )
2960 {
2961 SCIPwarningMessage(scip, "nonlinear constraint <%s> is not polynomial\n", SCIPconsGetName(cons));
2962 SCIPinfoMessage(scip, file, "\\ ");
2963 SCIP_CALL( SCIPprintCons(scip, cons, file) );
2964 SCIPinfoMessage(scip, file, ";\n");
2965 }
2966 else
2967 {
2968 /* check whether constraint is even quadratic
2969 * (we could also skip this and print as polynomial, but the code exists already)
2970 */
2971 SCIP_CALL( SCIPcheckExprQuadratic(scip, simplifiedexpr != NULL ? simplifiedexpr : SCIPgetExprNonlinear(cons), &isquadratic) );
2972 if( isquadratic )
2973 isquadratic = SCIPexprAreQuadraticExprsVariables(simplifiedexpr != NULL ? simplifiedexpr : SCIPgetExprNonlinear(cons));
2974
2975 if( isquadratic )
2976 {
2977 SCIP_CALL( printQuadraticCons(scip, file, consname, NULL, NULL, 0, simplifiedexpr != NULL ? simplifiedexpr : SCIPgetExprNonlinear(cons),
2978 SCIPgetLhsNonlinear(cons), SCIPgetRhsNonlinear(cons), transformed) );
2979 }
2980 else
2981 {
2982 SCIP_CALL( printNonlinearCons(scip, file, consname, simplifiedexpr != NULL ? simplifiedexpr : SCIPgetExprNonlinear(cons), SCIPgetLhsNonlinear(cons), SCIPgetRhsNonlinear(cons)) );
2983 }
2984
2985 consNonlinear[nConsNonlinear++] = cons;
2986 }
2987
2988 if( simplifiedexpr != NULL )
2989 {
2990 SCIP_CALL( SCIPreleaseExpr(scip, &simplifiedexpr) );
2991 }
2992 }
2993 else if( strcmp(conshdlrname, "and") == 0 )
2994 {
2995 printRowAnd(scip, file, consname, cons);
2996
2997 consAnd[nConsAnd++] = cons;
2998 }
2999 else
3000 {
3001 SCIPwarningMessage(scip, "constraint handler <%s> cannot print requested format\n", conshdlrname );
3002 SCIPinfoMessage(scip, file, "\\ ");
3003 SCIP_CALL( SCIPprintCons(scip, cons, file) );
3004 SCIPinfoMessage(scip, file, ";\n");
3005 }
3006 }
3007
3008 /* create hashtable for storing aggregated variables */
3009 SCIP_CALL( SCIPallocBufferArray(scip, &aggregatedVars, nvars) );
3010 SCIP_CALL( SCIPhashtableCreate(&varAggregated, SCIPblkmem(scip), nvars/10, hashGetKeyVar, hashKeyEqVar, hashKeyValVar, NULL) );
3011
3012 /* check for aggregated variables in nonlinear constraints and output aggregations as linear constraints */
3013 for( c = 0; c < nConsNonlinear; ++c )
3014 {
3015 SCIP_Bool success;
3016 int ntmpvars;
3017
3018 /* get variables of the nonlinear constraint */
3019 SCIP_CALL( SCIPgetConsNVars(scip, consNonlinear[c], &ntmpvars, &success) );
3020 assert(success);
3021 if( ntmpvars > tmpvarssize )
3022 {
3023 tmpvarssize = SCIPcalcMemGrowSize(scip, ntmpvars);
3024 SCIP_CALL( SCIPreallocBufferArray(scip, &tmpvars, tmpvarssize) );
3025 }
3026 SCIP_CALL( SCIPgetConsVars(scip, consNonlinear[c], tmpvars, tmpvarssize, &success) );
3027 assert(success);
3028
3029 SCIP_CALL( collectAggregatedVars(ntmpvars, tmpvars, &nAggregatedVars, &aggregatedVars, &varAggregated) );
3030 }
3031
3032 /* check for aggregated variables in and constraints and output aggregations as linear constraints */
3033 for (c = 0; c < nConsAnd; ++c)
3034 {
3035 SCIP_VAR* resultant;
3036
3037 cons = consAnd[c];
3038
3039 SCIP_CALL( collectAggregatedVars(SCIPgetNVarsAnd(scip, cons), SCIPgetVarsAnd(scip, cons), &nAggregatedVars, &aggregatedVars, &varAggregated) );
3040
3041 resultant = SCIPgetResultantAnd(scip, cons);
3042 SCIP_CALL( collectAggregatedVars(1, &resultant, &nAggregatedVars, &aggregatedVars, &varAggregated) );
3043 }
3044
3045 /* print aggregation constraints */
3046 SCIP_CALL( printAggregatedCons(scip, file, transformed, nvars, nAggregatedVars, aggregatedVars) );
3047
3048 /* print "Bounds" section */
3049 SCIPinfoMessage(scip, file, "Bounds\n");
3050 for (v = 0; v < nvars; ++v)
3051 {
3052 var = vars[v];
3053 assert( var != NULL );
3054 (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
3055
3056 if( transformed )
3057 {
3058 /* in case the transformed is written only local bounds are posted which are valid in the current node */
3059 lb = SCIPvarGetLbLocal(var);
3060 ub = SCIPvarGetUbLocal(var);
3061 }
3062 else
3063 {
3064 lb = SCIPvarGetLbOriginal(var);
3065 ub = SCIPvarGetUbOriginal(var);
3066 }
3067
3068 if ( SCIPisInfinity(scip, -lb) && SCIPisInfinity(scip, ub) )
3069 SCIPinfoMessage(scip, file, " %s free\n", varname);
3070 else
3071 {
3072 /* print lower bound */
3073 if ( SCIPisInfinity(scip, -lb) )
3074 SCIPinfoMessage(scip, file, " -inf <= ");
3075 else
3076 {
3077 if ( SCIPisZero(scip, lb) )
3078 {
3079 /* variables are nonnegative by default - so we skip these variables */
3080 if ( SCIPisInfinity(scip, ub) )
3081 continue;
3082 lb = 0.0;
3083 }
3084
3085 SCIPinfoMessage(scip, file, " %.15g <= ", lb);
3086 }
3087 /* print variable name */
3088 SCIPinfoMessage(scip, file, "%s", varname);
3089
3090 /* print upper bound as far this one is not infinity */
3091 if( !SCIPisInfinity(scip, ub) )
3092 SCIPinfoMessage(scip, file, " <= %.15g", ub);
3093
3094 SCIPinfoMessage(scip, file, "\n");
3095 }
3096 }
3097
3098 /* output aggregated variables as 'free' */
3099 for (v = 0; v < nAggregatedVars; ++v)
3100 {
3101 var = aggregatedVars[v];
3102 assert( var != NULL );
3103 (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
3104
3105 SCIPinfoMessage(scip, file, " %s free\n", varname);
3106 }
3107
3108 /* free space */
3109 SCIPfreeBufferArray(scip, &aggregatedVars);
3110 SCIPhashtableFree(&varAggregated);
3111
3112 /* print binaries section */
3113 {
3114 SCIP_Bool initial = TRUE;
3115
3116 /* output active variables */
3117 for( v = 0; v < nintegers; ++v )
3118 {
3119 var = vars[v];
3120
3121 if( SCIPvarGetType(var) != SCIP_VARTYPE_BINARY || (int)SCIPvarGetImplType(var) > 2 + implintlevel )
3122 continue;
3123
3124 if( initial )
3125 {
3126 SCIPinfoMessage(scip, file, "Binaries\n");
3127 initial = FALSE;
3128 }
3129
3130 (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
3131 (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %s", varname);
3132 appendLine(scip, file, linebuffer, &linecnt, buffer);
3133 }
3134
3135 endLine(scip, file, linebuffer, &linecnt);
3136 }
3137
3138 /* print generals section */
3139 {
3140 SCIP_Bool initial = TRUE;
3141
3142 /* output active variables */
3143 for( v = nbinvars; v < nintegers; ++v )
3144 {
3145 var = vars[v];
3146
3147 switch( SCIPvarGetType(var) )
3148 {
3150 continue;
3152 if( (int)SCIPvarGetImplType(var) > 2 + implintlevel )
3153 continue;
3154 break;
3156 if( (int)SCIPvarGetImplType(var) <= 2 - implintlevel )
3157 continue;
3158 break;
3159 default:
3160 SCIPerrorMessage("unknown variable type\n");
3161 return SCIP_INVALIDDATA;
3162 } /*lint !e788*/
3163
3164 if( initial )
3165 {
3166 SCIPinfoMessage(scip, file, "Generals\n");
3167 initial = FALSE;
3168 }
3169
3170 (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
3171 (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %s", varname);
3172 appendLine(scip, file, linebuffer, &linecnt, buffer);
3173 }
3174
3175 endLine(scip, file, linebuffer, &linecnt);
3176 }
3177
3178 /* free space */
3179 SCIPfreeBufferArray(scip, &tmpvars);
3180 SCIPfreeBufferArray(scip, &consNonlinear);
3181 SCIPfreeBufferArray(scip, &consAnd);
3182
3183 /* end of lp format */
3184 SCIPinfoMessage(scip, file, "%s\n", "End");
3185
3186 *result = SCIP_SUCCESS;
3187
3188 return SCIP_OKAY;
3189}
3190
3191/*
3192 * Callback methods of reader
3193 */
3194
3195/** copy method for reader plugins (called when SCIP copies plugins) */
3196static
3198{ /*lint --e{715}*/
3199 assert(scip != NULL);
3200 assert(reader != NULL);
3201 assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
3202
3203 /* call inclusion method of reader */
3205
3206 return SCIP_OKAY;
3207}
3208
3209
3210/** problem reading method of reader */
3211static
3213{ /*lint --e{715}*/
3214
3215 SCIP_CALL( SCIPreadPip(scip, reader, filename, result) );
3216
3217 return SCIP_OKAY;
3218}
3219
3220
3221/** problem writing method of reader */
3222static
3224{ /*lint --e{715}*/
3225 SCIP_CALL( SCIPwritePip(scip, file, name, transformed, objsense, objscale, objoffset, vars,
3226 nvars, nbinvars, nintvars, nimplvars, ncontvars, conss, nconss, result) );
3227
3228 return SCIP_OKAY;
3229}
3230
3231
3232/*
3233 * reader specific interface methods
3234 */
3235
3236/** includes the pip file reader in SCIP */
3238 SCIP* scip /**< SCIP data structure */
3239 )
3240{
3241 SCIP_READER* reader;
3242
3243 /* include reader */
3245
3246 /* set non fundamental callbacks via setter functions */
3247 SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopyPip) );
3248 SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadPip) );
3249 SCIP_CALL( SCIPsetReaderWrite(scip, reader, readerWritePip) );
3250
3251 return SCIP_OKAY;
3252}
3253
3254
3255/** reads problem from file */
3257 SCIP* scip, /**< SCIP data structure */
3258 SCIP_READER* reader, /**< the file reader itself */
3259 const char* filename, /**< full path and name of file to read, or NULL if stdin should be used */
3260 SCIP_RESULT* result /**< pointer to store the result of the file reading call */
3261 )
3262{ /*lint --e{715}*/
3263 PIPINPUT pipinput;
3264 SCIP_RETCODE retcode;
3265 int i;
3266
3267 assert(scip != NULL); /* for lint */
3268 assert(reader != NULL);
3269 assert(result != NULL);
3270
3271 *result = SCIP_DIDNOTRUN;
3272
3273 /* initialize PIP input data */
3274 pipinput.file = NULL;
3275 pipinput.linebuf[0] = '\0';
3276 pipinput.probname[0] = '\0';
3277 pipinput.objname[0] = '\0';
3278 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &pipinput.token, PIP_MAX_LINELEN) ); /*lint !e506*/
3279 pipinput.token[0] = '\0';
3280 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &pipinput.tokenbuf, PIP_MAX_LINELEN) ); /*lint !e506*/
3281 pipinput.tokenbuf[0] = '\0';
3282 for( i = 0; i < PIP_MAX_PUSHEDTOKENS; ++i )
3283 {
3284 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &((pipinput.pushedtokens)[i]), PIP_MAX_LINELEN) ); /*lint !e866 !e506*/
3285 }
3286
3287 pipinput.npushedtokens = 0;
3288 pipinput.linenumber = 0;
3289 pipinput.linepos = 0;
3290 pipinput.section = PIP_START;
3291 pipinput.objsense = SCIP_OBJSENSE_MINIMIZE;
3292 pipinput.haserror = FALSE;
3293
3294 SCIP_CALL( SCIPgetBoolParam(scip, "reading/initialconss", &(pipinput.initialconss)) );
3295 SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicconss", &(pipinput.dynamicconss)) );
3296 SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamiccols", &(pipinput.dynamiccols)) );
3297 SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicrows", &(pipinput.dynamicrows)) );
3298
3299 /* read the file */
3300 retcode = readPIPFile(scip, &pipinput, filename);
3301
3302 /* free dynamically allocated memory */
3303 for( i = PIP_MAX_PUSHEDTOKENS - 1; i >= 0 ; --i )
3304 {
3305 SCIPfreeBlockMemoryArray(scip, &pipinput.pushedtokens[i], PIP_MAX_LINELEN);
3306 }
3307 SCIPfreeBlockMemoryArray(scip, &pipinput.tokenbuf, PIP_MAX_LINELEN);
3309
3310 if( retcode == SCIP_PLUGINNOTFOUND )
3311 retcode = SCIP_READERROR;
3312
3313 /* evaluate the result */
3314 if( pipinput.haserror )
3315 retcode = SCIP_READERROR;
3316 else
3317 {
3318 /* set objective sense */
3319 SCIP_CALL( SCIPsetObjsense(scip, pipinput.objsense) );
3320 *result = SCIP_SUCCESS;
3321 }
3322
3323 SCIP_CALL( retcode );
3324
3325 return SCIP_OKAY;
3326}
Constraint handler for AND 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 variable bound constraints .
#define NULL
Definition: def.h:248
#define SCIP_Longint
Definition: def.h:141
#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 SCIPABORT()
Definition: def.h:327
#define REALABS(x)
Definition: def.h:182
#define SCIP_CALL(x)
Definition: def.h:355
sum expression handler
variable expression handler
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_Real SCIPgetVbdcoefVarbound(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_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:5248
int SCIPgetNVarsAnd(SCIP *scip, SCIP_CONS *cons)
Definition: cons_and.c:5199
SCIP_Real * SCIPgetValsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_VAR * SCIPgetVbdvarVarbound(SCIP *scip, SCIP_CONS *cons)
int SCIPgetNVarsSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9596
SCIP_VAR ** SCIPgetVarsSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9619
SCIP_EXPR * SCIPgetExprNonlinear(SCIP_CONS *cons)
SCIP_Real SCIPgetRhsNonlinear(SCIP_CONS *cons)
SCIP_RETCODE SCIPcreateConsNonlinear(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_EXPR *expr, 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_VAR * SCIPgetVarVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_Longint * SCIPgetWeightsKnapsack(SCIP *scip, 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:9642
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 ** 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:5223
SCIP_VAR ** SCIPgetVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPgetLhsNonlinear(SCIP_CONS *cons)
@ 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 SCIPcreateExprVar(SCIP *scip, SCIP_EXPR **expr, SCIP_VAR *var, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr_var.c:398
void SCIPsetConstantExprSum(SCIP_EXPR *expr, SCIP_Real constant)
Definition: expr_sum.c:1138
SCIP_RETCODE SCIPappendExprSumExpr(SCIP *scip, SCIP_EXPR *expr, SCIP_EXPR *child, SCIP_Real childcoef)
Definition: expr_sum.c:1154
SCIP_RETCODE SCIPcreateExprSum(SCIP *scip, SCIP_EXPR **expr, int nchildren, SCIP_EXPR **children, SCIP_Real *coefficients, SCIP_Real constant, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr_sum.c:1117
SCIP_RETCODE SCIPwritePip(SCIP *scip, FILE *file, const char *name, SCIP_Bool transformed, SCIP_OBJSENSE objsense, SCIP_Real objscale, SCIP_Real objoffset, SCIP_VAR **vars, int nvars, int nbinvars, int nintvars, int nimplvars, int ncontvars, SCIP_CONS **conss, int nconss, SCIP_RESULT *result)
Definition: reader_pip.c:2726
SCIP_RETCODE SCIPreadPip(SCIP *scip, SCIP_READER *reader, const char *filename, SCIP_RESULT *result)
Definition: reader_pip.c:3256
SCIP_RETCODE SCIPincludeReaderPip(SCIP *scip)
Definition: reader_pip.c:3237
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 SCIPsetObjsense(SCIP *scip, SCIP_OBJSENSE objsense)
Definition: scip_prob.c:1417
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
int SCIPgetNTotalVars(SCIP *scip)
Definition: scip_prob.c:3064
SCIP_VAR * SCIPfindVar(SCIP *scip, const char *name)
Definition: scip_prob.c:3189
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
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 SCIPgetIntParam(SCIP *scip, const char *name, int *value)
Definition: scip_param.c:269
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4316
SCIP_RETCODE SCIPgetConsNVars(SCIP *scip, SCIP_CONS *cons, int *nvars, SCIP_Bool *success)
Definition: scip_cons.c:2621
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:8409
SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
Definition: scip_cons.c:2536
SCIP_Bool SCIPconsIsTransformed(SCIP_CONS *cons)
Definition: cons.c:8698
SCIP_RETCODE SCIPgetConsVars(SCIP *scip, SCIP_CONS *cons, SCIP_VAR **vars, int varssize, SCIP_Bool *success)
Definition: scip_cons.c:2577
SCIP_Bool SCIPconsIsEnabled(SCIP_CONS *cons)
Definition: cons.c:8486
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:8389
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1173
SCIP_RETCODE SCIPcreateExprMonomial(SCIP *scip, SCIP_EXPR **expr, int nfactors, SCIP_VAR **vars, SCIP_Real *exponents, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: scip_expr.c:1167
int SCIPexprGetNChildren(SCIP_EXPR *expr)
Definition: expr.c:3872
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_Real SCIPgetExponentExprPow(SCIP_EXPR *expr)
Definition: expr_pow.c:3448
SCIP_Bool SCIPisExprProduct(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1490
SCIP_Bool SCIPisExprSum(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1479
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_Real * SCIPgetCoefsExprSum(SCIP_EXPR *expr)
Definition: expr_sum.c:1554
SCIP_Bool SCIPisExprValue(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1468
SCIP_Real SCIPgetCoefExprProduct(SCIP_EXPR *expr)
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 SCIPprintExpr(SCIP *scip, SCIP_EXPR *expr, FILE *file)
Definition: scip_expr.c:1512
SCIP_Real SCIPgetValueExprValue(SCIP_EXPR *expr)
Definition: expr_value.c:298
SCIP_Bool SCIPisExprPower(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1501
SCIP_RETCODE SCIPcheckExprQuadratic(SCIP *scip, SCIP_EXPR *expr, SCIP_Bool *isquadratic)
Definition: scip_expr.c:2402
SCIP_EXPR ** SCIPexprGetChildren(SCIP_EXPR *expr)
Definition: expr.c:3882
SCIP_Real SCIPgetConstantExprSum(SCIP_EXPR *expr)
Definition: expr_sum.c:1569
SCIP_VAR * SCIPgetVarExprVar(SCIP_EXPR *expr)
Definition: expr_var.c:424
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 SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:110
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip_mem.c:57
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
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
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
SCIP_RETCODE SCIPsetReaderWrite(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERWRITE((*readerwrite)))
Definition: scip_reader.c:219
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:18320
SCIP_VAR * SCIPvarGetNegatedVar(SCIP_VAR *var)
Definition: var.c:23868
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:23386
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:24268
SCIP_Real SCIPvarGetLbOriginal(SCIP_VAR *var)
Definition: var.c:24020
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:23900
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:23453
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:24142
int SCIPvarGetIndex(SCIP_VAR *var)
Definition: var.c:23652
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:23267
SCIP_Real SCIPvarGetUbOriginal(SCIP_VAR *var)
Definition: var.c:24063
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_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:24234
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:24120
SCIP_IMPLINTTYPE SCIPvarGetImplType(SCIP_VAR *var)
Definition: var.c:23463
SCIP_RETCODE SCIPcreateVarBasic(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype)
Definition: scip_var.c:184
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip_var.c:5372
int SCIPstrcasecmp(const char *s1, const char *s2)
Definition: misc.c:10863
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10827
void SCIPprintSysError(const char *message)
Definition: misc.c:10719
int SCIPstrncpy(char *t, const char *s, int size)
Definition: misc.c:10897
static const SCIP_Real scalars[]
Definition: lp.c:5959
memory allocation routines
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:130
public methods for managing constraints
public functions to work with algebraic expressions
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
public data structures and miscellaneous methods
public methods for NLP management
public methods for input file readers
public methods for problem variables
static SCIP_Bool isExprSignomial(SCIP *scip, SCIP_EXPR *expr)
Definition: reader_pip.c:1803
static SCIP_RETCODE getActiveVariables(SCIP *scip, SCIP_VAR ***vars, SCIP_Real **scalars, int *nvars, SCIP_Real *constant, SCIP_Bool transformed)
Definition: reader_pip.c:1738
static SCIP_RETCODE readPolynomial(SCIP *scip, PIPINPUT *pipinput, char *name, SCIP_EXPR **expr, SCIP_Bool *islinear, SCIP_Bool *newsection)
Definition: reader_pip.c:807
#define PIP_MAX_PUSHEDTOKENS
Definition: reader_pip.c:76
static SCIP_RETCODE getVariable(SCIP *scip, char *name, SCIP_Bool dynamiccols, SCIP_VAR **var, SCIP_Bool *created)
Definition: reader_pip.c:664
static void clearLine(char *linebuffer, int *linecnt)
Definition: reader_pip.c:1873
static SCIP_Bool hasError(PIPINPUT *pipinput)
Definition: reader_pip.c:175
PipSense
Definition: reader_pip.c:105
@ PIP_SENSE_NOTHING
Definition: reader_pip.c:106
@ PIP_SENSE_GE
Definition: reader_pip.c:108
@ PIP_SENSE_EQ
Definition: reader_pip.c:109
@ PIP_SENSE_LE
Definition: reader_pip.c:107
static SCIP_Bool isNewSection(SCIP *scip, PIPINPUT *pipinput)
Definition: reader_pip.c:443
static SCIP_Bool getNextToken(SCIP *scip, PIPINPUT *pipinput)
Definition: reader_pip.c:307
static SCIP_RETCODE readGenerals(SCIP *scip, PIPINPUT *pipinput)
Definition: reader_pip.c:1565
static SCIP_RETCODE readStart(SCIP *scip, PIPINPUT *pipinput)
Definition: reader_pip.c:703
static SCIP_DECL_HASHGETKEY(hashGetKeyVar)
Definition: reader_pip.c:1714
static SCIP_Bool isExprPolynomial(SCIP *scip, SCIP_EXPR *expr)
Definition: reader_pip.c:1850
static const char tokenchars[]
Definition: reader_pip.c:137
static SCIP_Bool isSign(PIPINPUT *pipinput, int *sign)
Definition: reader_pip.c:576
static SCIP_Bool getNextLine(SCIP *scip, PIPINPUT *pipinput)
Definition: reader_pip.c:248
#define PIP_PRINTLEN
Definition: reader_pip.c:81
static const char commentchars[]
Definition: reader_pip.c:138
static void checkVarnames(SCIP *scip, SCIP_VAR **vars, int nvars)
Definition: reader_pip.c:2647
static SCIP_RETCODE ensureMonomialsSize(SCIP *scip, SCIP_EXPR ***monomials, SCIP_Real **monomialscoef, int *monomialssize, int minnmonomials)
Definition: reader_pip.c:724
static void printSignomial(SCIP *scip, FILE *file, char *linebuffer, int *linecnt, SCIP_EXPR *expr, SCIP_Real coef, SCIP_Bool needsign)
Definition: reader_pip.c:2173
static const char namechars[]
Definition: reader_pip.c:139
static SCIP_RETCODE printAggregatedCons(SCIP *scip, FILE *file, SCIP_Bool transformed, int nvars, int nAggregatedVars, SCIP_VAR **aggregatedVars)
Definition: reader_pip.c:2550
static SCIP_Bool isNameValid(const char *name)
Definition: reader_pip.c:2611
static void swapTokenBuffer(PIPINPUT *pipinput)
Definition: reader_pip.c:432
#define READER_DESC
Definition: reader_pip.c:68
static SCIP_DECL_READERREAD(readerReadPip)
Definition: reader_pip.c:3212
#define PIP_MAX_PRINTLEN
Definition: reader_pip.c:79
static SCIP_Bool isValueChar(char c, char nextc, SCIP_Bool firstchar, SCIP_Bool *hasdot, PIPEXPTYPE *exptype)
Definition: reader_pip.c:204
PipSection
Definition: reader_pip.c:85
@ PIP_END
Definition: reader_pip.c:92
@ PIP_BINARIES
Definition: reader_pip.c:91
@ PIP_START
Definition: reader_pip.c:86
@ PIP_CONSTRAINTS
Definition: reader_pip.c:88
@ PIP_BOUNDS
Definition: reader_pip.c:89
@ PIP_GENERALS
Definition: reader_pip.c:90
@ PIP_OBJECTIVE
Definition: reader_pip.c:87
#define PIP_MAX_NAMELEN
Definition: reader_pip.c:80
static SCIP_RETCODE printNonlinearCons(SCIP *scip, FILE *file, const char *rowname, SCIP_EXPR *expr, SCIP_Real lhs, SCIP_Real rhs)
Definition: reader_pip.c:2466
struct PipInput PIPINPUT
Definition: reader_pip.c:134
static SCIP_RETCODE collectAggregatedVars(int nvars, SCIP_VAR **vars, int *nAggregatedVars, SCIP_VAR ***aggregatedVars, SCIP_HASHTABLE **varAggregated)
Definition: reader_pip.c:2510
static SCIP_RETCODE printQuadraticCons(SCIP *scip, FILE *file, const char *rowname, SCIP_VAR **linvars, SCIP_Real *linvals, int nlinvars, SCIP_EXPR *quadexpr, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool transformed)
Definition: reader_pip.c:2379
#define READER_EXTENSION
Definition: reader_pip.c:69
static SCIP_RETCODE readBinaries(SCIP *scip, PIPINPUT *pipinput)
Definition: reader_pip.c:1600
enum PipSection PIPSECTION
Definition: reader_pip.c:94
#define PIP_INIT_MONOMIALSSIZE
Definition: reader_pip.c:77
enum PipSense PIPSENSE
Definition: reader_pip.c:111
static SCIP_Bool isSense(PIPINPUT *pipinput, PIPSENSE *sense)
Definition: reader_pip.c:633
static void pushBufferToken(PIPINPUT *pipinput)
Definition: reader_pip.c:419
static void endLine(SCIP *scip, FILE *file, char *linebuffer, int *linecnt)
Definition: reader_pip.c:1887
static void pushToken(PIPINPUT *pipinput)
Definition: reader_pip.c:406
#define READER_NAME
Definition: reader_pip.c:67
static SCIP_DECL_READERCOPY(readerCopyPip)
Definition: reader_pip.c:3197
static void syntaxError(SCIP *scip, PIPINPUT *pipinput, const char *msg)
Definition: reader_pip.c:148
static void printRowAnd(SCIP *scip, FILE *file, const char *rowname, SCIP_CONS *cons)
Definition: reader_pip.c:2331
#define PIP_MAX_LINELEN
Definition: reader_pip.c:75
#define PIP_INIT_FACTORSSIZE
Definition: reader_pip.c:78
static SCIP_Bool isDelimChar(char c)
Definition: reader_pip.c:186
static SCIP_RETCODE readConstraints(SCIP *scip, PIPINPUT *pipinput)
Definition: reader_pip.c:1225
static void swapPointers(char **pointer1, char **pointer2)
Definition: reader_pip.c:293
static SCIP_DECL_HASHKEYEQ(hashKeyEqVar)
Definition: reader_pip.c:1721
static void printRowNl(SCIP *scip, FILE *file, const char *rowname, const char *rownameextension, const char *type, SCIP_EXPR *expr, SCIP_Real rhs)
Definition: reader_pip.c:2263
static SCIP_DECL_HASHKEYVAL(hashKeyValVar)
Definition: reader_pip.c:1730
enum PipExpType PIPEXPTYPE
Definition: reader_pip.c:102
static SCIP_RETCODE printRow(SCIP *scip, FILE *file, const char *rowname, const char *rownameextension, const char *type, SCIP_VAR **linvars, SCIP_Real *linvals, int nlinvars, SCIP_EXPR *quadexpr, SCIP_Real rhs, SCIP_Bool transformed)
Definition: reader_pip.c:1941
static SCIP_RETCODE readObjective(SCIP *scip, PIPINPUT *pipinput)
Definition: reader_pip.c:1094
static SCIP_RETCODE ensureFactorsSize(SCIP *scip, SCIP_VAR ***vars, SCIP_Real **exponents, int *factorssize, int minnfactors)
Definition: reader_pip.c:768
static SCIP_DECL_READERWRITE(readerWritePip)
Definition: reader_pip.c:3223
static SCIP_Bool isValue(SCIP *scip, PIPINPUT *pipinput, SCIP_Real *value)
Definition: reader_pip.c:601
static void checkConsnames(SCIP *scip, SCIP_CONS **conss, int nconss, SCIP_Bool transformed)
Definition: reader_pip.c:2671
PipExpType
Definition: reader_pip.c:97
@ PIP_EXP_SIGNED
Definition: reader_pip.c:100
@ PIP_EXP_NONE
Definition: reader_pip.c:98
@ PIP_EXP_UNSIGNED
Definition: reader_pip.c:99
static SCIP_RETCODE readPIPFile(SCIP *scip, PIPINPUT *pipinput, const char *filename)
Definition: reader_pip.c:1644
static const char delimchars[]
Definition: reader_pip.c:136
static void appendLine(SCIP *scip, FILE *file, char *linebuffer, int *linecnt, const char *extension)
Definition: reader_pip.c:1910
static SCIP_RETCODE readBounds(SCIP *scip, PIPINPUT *pipinput)
Definition: reader_pip.c:1394
static SCIP_Bool isTokenChar(char c)
Definition: reader_pip.c:195
file reader for polynomial mixed-integer programs in PIP format
public methods for constraint handler plugins and constraints
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_VERBLEVEL_MINIMAL
Definition: type_message.h:59
@ 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
@ SCIP_DIDNOTRUN
Definition: type_result.h:42
@ 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_OKAY
Definition: type_retcode.h:42
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_ORIGINAL
Definition: type_var.h:51
@ SCIP_VARSTATUS_MULTAGGR
Definition: type_var.h:56
@ SCIP_VARSTATUS_NEGATED
Definition: type_var.h:57
@ SCIP_VARSTATUS_AGGREGATED
Definition: type_var.h:55
enum SCIP_Varstatus SCIP_VARSTATUS
Definition: type_var.h:59