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