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