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