Scippy

SCIP

Solving Constraint Integer Programs

reader_mps.c
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the program and library */
4/* SCIP --- Solving Constraint Integer Programs */
5/* */
6/* Copyright (c) 2002-2025 Zuse Institute Berlin (ZIB) */
7/* */
8/* Licensed under the Apache License, Version 2.0 (the "License"); */
9/* you may not use this file except in compliance with the License. */
10/* You may obtain a copy of the License at */
11/* */
12/* http://www.apache.org/licenses/LICENSE-2.0 */
13/* */
14/* Unless required by applicable law or agreed to in writing, software */
15/* distributed under the License is distributed on an "AS IS" BASIS, */
16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17/* See the License for the specific language governing permissions and */
18/* limitations under the License. */
19/* */
20/* You should have received a copy of the Apache-2.0 license */
21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22/* */
23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25/**@file reader_mps.c
26 * @ingroup DEFPLUGINS_READER
27 * @brief (extended) MPS file reader
28 * @author Thorsten Koch
29 * @author Tobias Achterberg
30 * @author Marc Pfetsch
31 * @author Stefan Heinz
32 * @author Stefan Vigerske
33 * @author Michael Winkler
34 *
35 * This reader/writer handles MPS files in extended MPS format, as it
36 * is used by CPLEX. In the extended format the limits on variable
37 * name lengths and coefficients are considerably relaxed. The columns
38 * in the format are then separated by whitespaces.
39 *
40 * @todo Check whether constructing the names for aggregated constraint yields name clashes (aggrXXX).
41 */
42
43/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
44
46#include <ctype.h>
47#include "scip/cons_and.h"
49#include "scip/cons_nonlinear.h"
51#include "scip/cons_indicator.h"
52#include "scip/cons_knapsack.h"
53#include "scip/cons_linear.h"
54#include "scip/cons_logicor.h"
55#include "scip/cons_setppc.h"
56#include "scip/cons_sos1.h"
57#include "scip/cons_sos2.h"
58#include "scip/cons_varbound.h"
59#include "scip/pub_cons.h"
60#include "scip/pub_fileio.h"
61#include "scip/pub_message.h"
62#include "scip/pub_misc.h"
63#include "scip/pub_misc_sort.h"
64#include "scip/pub_reader.h"
65#include "scip/pub_var.h"
66#include "scip/reader_mps.h"
67#include "scip/rational.h"
68#include "scip/scip_cons.h"
69#include "scip/scip_exact.h"
70#include "scip/scip_mem.h"
71#include "scip/scip_message.h"
72#include "scip/scip_numerics.h"
73#include "scip/scip_param.h"
74#include "scip/scip_prob.h"
75#include "scip/scip_reader.h"
77#include "scip/scip_var.h"
78#include <stdlib.h>
79#include <string.h>
80
81#define READER_NAME "mpsreader"
82#define READER_DESC "file reader for MIQPs in IBM's Mathematical Programming System format"
83#define READER_EXTENSION "mps"
84
85#define DEFAULT_LINEARIZE_ANDS TRUE /**< should possible \"and\" constraint be linearized when writing the mps file? */
86#define DEFAULT_AGGRLINEARIZATION_ANDS TRUE /**< should an aggregated linearization for and constraints be used? */
87
88/*
89 * mps reader internal methods
90 */
91
92#define MPS_MAX_LINELEN 1024
93#define MPS_MAX_NAMELEN 256
94#define MPS_MAX_VALUELEN 26
95#define MPS_MAX_FIELDLEN 20
96
97#define PATCH_CHAR '_'
98#define BLANK ' '
99
100/** MPS reading data */
101struct SCIP_ReaderData
102{
103 SCIP_Bool linearizeands;
104 SCIP_Bool aggrlinearizationands;
105};
106
107/** enum containing all mps sections */
109{
128
129/** mps input structure */
130struct MpsInput
131{
132 MPSSECTION section;
133 SCIP_FILE* fp;
134 int lineno;
135 SCIP_OBJSENSE objsense;
136 SCIP_Bool haserror;
137 char buf[MPS_MAX_LINELEN];
138 const char* f0;
139 const char* f1;
140 const char* f2;
141 const char* f3;
142 const char* f4;
143 const char* f5;
144 char probname[MPS_MAX_NAMELEN];
145 char objname [MPS_MAX_NAMELEN];
146 SCIP_Bool initialconss; /**< should model constraints be marked as initial? */
147 SCIP_Bool dynamicconss; /**< should model constraints be subject to aging? */
148 SCIP_Bool dynamiccols; /**< should columns be added and removed dynamically to the LP? */
149 SCIP_Bool dynamicrows; /**< should rows be added and removed dynamically to the LP? */
150 SCIP_Bool isinteger;
151 SCIP_Bool isnewformat;
152};
153typedef struct MpsInput MPSINPUT;
154
155/** sparse matrix representation */
156struct SparseMatrix
157{
158 SCIP_Real* values; /**< matrix element */
159 SCIP_VAR** columns; /**< corresponding variables */
160 const char** rows; /**< corresponding constraint names */
161 int nentries; /**< number of elements in the arrays */
162 int sentries; /**< number of slots in the arrays */
163};
164typedef struct SparseMatrix SPARSEMATRIX;
165
166/** struct for mapping cons names to numbers */
168{
169 const char* consname; /**< name of the constraint */
170 int freq; /**< how often we have seen the name */
171};
173
174/** creates the mps input structure */
175static
177 SCIP* scip, /**< SCIP data structure */
178 MPSINPUT** mpsi, /**< mps input structure */
179 SCIP_FILE* fp /**< file object for the input file */
180 )
181{
182 assert(mpsi != NULL);
183 assert(fp != NULL);
184
186
187 (*mpsi)->section = MPS_NAME;
188 (*mpsi)->fp = fp;
189 (*mpsi)->lineno = 0;
190 (*mpsi)->objsense = SCIP_OBJSENSE_MINIMIZE;
191 (*mpsi)->haserror = FALSE;
192 (*mpsi)->isinteger = FALSE;
193 (*mpsi)->isnewformat = FALSE;
194 (*mpsi)->buf [0] = '\0';
195 (*mpsi)->probname[0] = '\0';
196 (*mpsi)->objname [0] = '\0';
197 (*mpsi)->f0 = NULL;
198 (*mpsi)->f1 = NULL;
199 (*mpsi)->f2 = NULL;
200 (*mpsi)->f3 = NULL;
201 (*mpsi)->f4 = NULL;
202 (*mpsi)->f5 = NULL;
203
204 SCIP_CALL( SCIPgetBoolParam(scip, "reading/initialconss", &((*mpsi)->initialconss)) );
205 SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicconss", &((*mpsi)->dynamicconss)) );
206 SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamiccols", &((*mpsi)->dynamiccols)) );
207 SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicrows", &((*mpsi)->dynamicrows)) );
208
209 return SCIP_OKAY;
210}
211
212/** free the mps input structure */
213static
215 SCIP* scip, /**< SCIP data structure */
216 MPSINPUT** mpsi /**< mps input structure */
217 )
218{
220}
221
222/** returns the current section */
223static
225 const MPSINPUT* mpsi /**< mps input structure */
226 )
227{
228 assert(mpsi != NULL);
229
230 return mpsi->section;
231}
232
233/** return the current value of field 0 */
234static
235const char* mpsinputField0(
236 const MPSINPUT* mpsi /**< mps input structure */
237 )
238{
239 assert(mpsi != NULL);
240
241 return mpsi->f0;
242}
243
244/** return the current value of field 1 */
245static
246const char* mpsinputField1(
247 const MPSINPUT* mpsi /**< mps input structure */
248 )
249{
250 assert(mpsi != NULL);
251
252 return mpsi->f1;
253}
254
255/** return the current value of field 2 */
256static
257const char* mpsinputField2(
258 const MPSINPUT* mpsi /**< mps input structure */
259 )
260{
261 assert(mpsi != NULL);
262
263 return mpsi->f2;
264}
265
266/** return the current value of field 3 */
267static
268const char* mpsinputField3(
269 const MPSINPUT* mpsi /**< mps input structure */
270 )
271{
272 assert(mpsi != NULL);
273
274 return mpsi->f3;
275}
276
277/** return the current value of field 4 */
278static
279const char* mpsinputField4(
280 const MPSINPUT* mpsi /**< mps input structure */
281 )
282{
283 assert(mpsi != NULL);
284
285 return mpsi->f4;
286}
287
288/** return the current value of field 5 */
289static
290const char* mpsinputField5(
291 const MPSINPUT* mpsi /**< mps input structure */
292 )
293{
294 assert(mpsi != NULL);
295
296 return mpsi->f5;
297}
298
299/** returns the objective name */
300static
301const char* mpsinputObjname(
302 const MPSINPUT* mpsi /**< mps input structure */
303 )
304{
305 assert(mpsi != NULL);
306
307 return mpsi->objname;
308}
309
310/** returns the objective sense */
311static
313 const MPSINPUT* mpsi /**< mps input structure */
314 )
315{
316 assert(mpsi != NULL);
317
318 return mpsi->objsense;
319}
320
321/** returns if an error was detected */
322static
324 const MPSINPUT* mpsi /**< mps input structure */
325 )
326{
327 assert(mpsi != NULL);
328
329 return mpsi->haserror;
330}
331
332/** returns the value of the Bool "is integer" in the mps input */
333static
335 const MPSINPUT* mpsi /**< mps input structure */
336 )
337{
338 assert(mpsi != NULL);
339
340 return mpsi->isinteger;
341}
342
343/** set the section in the mps input structure to given section */
344static
346 MPSINPUT* mpsi, /**< mps input structure */
347 MPSSECTION section /**< section that is set */
348 )
349{
350 assert(mpsi != NULL);
351
352 mpsi->section = section;
353}
354
355/** set the problem name in the mps input structure to given problem name */
356static
358 MPSINPUT* mpsi, /**< mps input structure */
359 const char* probname /**< name of the problem to set */
360 )
361{
362 assert(mpsi != NULL);
363 assert(probname != NULL);
364 assert(strlen(probname) < sizeof(mpsi->probname));
365
366 (void)SCIPmemccpy(mpsi->probname, probname, '\0', MPS_MAX_NAMELEN - 1);
367}
368
369/** set the objective name in the mps input structure to given objective name */
370static
372 MPSINPUT* mpsi, /**< mps input structure */
373 const char* objname /**< name of the objective function to set */
374 )
375{
376 assert(mpsi != NULL);
377 assert(objname != NULL);
378 assert(strlen(objname) < sizeof(mpsi->objname));
379
380 (void)SCIPmemccpy(mpsi->objname, objname, '\0', MPS_MAX_NAMELEN - 1);
381}
382
383/** set the objective sense in the mps input structure to given objective sense */
384static
386 MPSINPUT* mpsi, /**< mps input structure */
387 SCIP_OBJSENSE sense /**< sense of the objective function */
388 )
389{
390 assert(mpsi != NULL);
391
392 mpsi->objsense = sense;
393}
394
395static
397 MPSINPUT* mpsi /**< mps input structure */
398 )
399{
400 assert(mpsi != NULL);
401
402 SCIPerrorMessage("Syntax error in line %d\n", mpsi->lineno);
403 mpsi->section = MPS_ENDATA;
404 mpsi->haserror = TRUE;
405}
406
407/** method post a ignore message */
408static
410 SCIP* scip, /**< SCIP data structure */
411 MPSINPUT* mpsi, /**< mps input structure */
412 const char* what, /**< what get ignored */
413 const char* what_name, /**< name of that object */
414 const char* entity, /**< entity */
415 const char* entity_name, /**< entity name */
416 SCIP_VERBLEVEL verblevel /**< SCIP verblevel for this message */
417 )
418{
419 assert(mpsi != NULL);
420 assert(what != NULL);
421 assert(what_name != NULL);
422 assert(entity != NULL);
423 assert(entity_name != NULL);
424
425 SCIPverbMessage(scip, verblevel, NULL,
426 "Warning line %d: %s \"%s\" for %s \"%s\" ignored\n", mpsi->lineno, what, what_name, entity, entity_name);
427}
428
429/** fill the line from \p pos up to column 80 with blanks. */
430static
432 char* buf, /**< buffer to clear */
433 unsigned int pos /**< position to start the clearing process */
434 )
435{
436 unsigned int i;
437
438 for(i = pos; i < 80; i++)
439 buf[i] = BLANK;
440 buf[80] = '\0';
441}
442
443/** change all blanks inside a field to #PATCH_CHAR. */
444static
446 char* buf, /**< buffer to patch */
447 int beg, /**< position to begin */
448 int end /**< position to end */
449 )
450{
451 int i;
452
453 while( (beg <= end) && (buf[end] == BLANK) )
454 end--;
455
456 while( (beg <= end) && (buf[beg] == BLANK) )
457 beg++;
458
459 for( i = beg; i <= end; i++ )
460 if( buf[i] == BLANK )
461 buf[i] = PATCH_CHAR;
462}
463
464/** read a mps format data line and parse the fields. */
465static
467 MPSINPUT* mpsi /**< mps input structure */
468 )
469{
470 unsigned int len;
471 unsigned int i;
472 int space;
473 char* s;
474 SCIP_Bool is_marker;
475 SCIP_Bool is_empty;
476 char* nexttok;
477
478 do
479 {
480 mpsi->f0 = mpsi->f1 = mpsi->f2 = mpsi->f3 = mpsi->f4 = mpsi->f5 = 0;
481 is_marker = FALSE;
482
483 /* Read until we have not a comment line. */
484 do
485 {
486 mpsi->buf[MPS_MAX_LINELEN-1] = '\0';
487 if( NULL == SCIPfgets(mpsi->buf, (int) sizeof(mpsi->buf), mpsi->fp) )
488 return FALSE;
489 mpsi->lineno++;
490 }
491 while( *mpsi->buf == '*' ); /* coverity[a_loop_bound] */
492
493 /* Normalize line */
494 len = (unsigned int) strlen(mpsi->buf);
495
496 for( i = 0; i < len; i++ )
497 {
498 if( (mpsi->buf[i] == '\t') || (mpsi->buf[i] == '\n') || (mpsi->buf[i] == '\r') )
499 mpsi->buf[i] = BLANK;
500 }
501
502 /* remove trailing whitespace, for len < 14 check to succeed on forplan.mps again */
503 assert(len < MPS_MAX_LINELEN);
504 while( len > 0 && mpsi->buf[len-1] == BLANK )
505 --len;
506
507 if( len < 80 )
508 clearFrom(mpsi->buf, len);
509
510 SCIPdebugMessage("line %d: <%s>\n", mpsi->lineno, mpsi->buf);
511
512 assert(strlen(mpsi->buf) >= 80);
513
514 /* Look for new section */
515 if( *mpsi->buf != BLANK )
516 {
517 mpsi->f0 = SCIPstrtok(&mpsi->buf[0], " ", &nexttok);
518
519 assert(mpsi->f0 != 0);
520
521 mpsi->f1 = SCIPstrtok(NULL, " ", &nexttok);
522
523 return TRUE;
524 }
525
526 /* If we decide to use the new format we never revert this decision */
527 if( !mpsi->isnewformat )
528 {
529 /* Test for fixed format comments */
530 if( (mpsi->buf[14] == '$') && (mpsi->buf[13] == ' ') )
531 clearFrom(mpsi->buf, 14);
532 else if( (mpsi->buf[39] == '$') && (mpsi->buf[38] == ' ') )
533 clearFrom(mpsi->buf, 39);
534
535 /* Test for fixed format */
536 space = mpsi->buf[12] | mpsi->buf[13]
537 | mpsi->buf[22] | mpsi->buf[23]
538 | mpsi->buf[36] | mpsi->buf[37] | mpsi->buf[38]
539 | mpsi->buf[47] | mpsi->buf[48]
540 | mpsi->buf[61] | mpsi->buf[62] | mpsi->buf[63];
541
542 if( space == BLANK )
543 {
544 /* Now we have space at the right positions.
545 * But are there also the non space where they
546 * should be ?
547 */
549
550 number = isdigit((unsigned char)mpsi->buf[24]) || isdigit((unsigned char)mpsi->buf[25])
551 || isdigit((unsigned char)mpsi->buf[26]) || isdigit((unsigned char)mpsi->buf[27])
552 || isdigit((unsigned char)mpsi->buf[28]) || isdigit((unsigned char)mpsi->buf[29])
553 || isdigit((unsigned char)mpsi->buf[30]) || isdigit((unsigned char)mpsi->buf[31])
554 || isdigit((unsigned char)mpsi->buf[32]) || isdigit((unsigned char)mpsi->buf[33])
555 || isdigit((unsigned char)mpsi->buf[34]) || isdigit((unsigned char)mpsi->buf[35]);
556
557 /* len < 14 is to handle ROW lines with embedded spaces
558 * in the names correctly
559 */
560 if( number || (len < 14 && mpsi->section == MPS_ROWS) )
561 {
562 /* We assume fixed format, so we patch possible embedded spaces. */
563 patchField(mpsi->buf, 4, 12);
564 patchField(mpsi->buf, 14, 22);
565 patchField(mpsi->buf, 39, 47);
566 }
567 else
568 {
569 if( mpsi->section == MPS_COLUMNS || mpsi->section == MPS_RHS
570 || mpsi->section == MPS_RANGES || mpsi->section == MPS_BOUNDS )
571 mpsi->isnewformat = TRUE;
572 }
573 }
574 else
575 {
576 mpsi->isnewformat = TRUE;
577 }
578 }
579 s = &mpsi->buf[1];
580
581 /* At this point it is not clear if we have a indicator field.
582 * If there is none (e.g. empty) f1 will be the first name field.
583 * If there is one, f2 will be the first name field.
584 *
585 * Initially comment marks '$' are only allowed in the beginning
586 * of the 2nd and 3rd name field. We test all fields but the first.
587 * This makes no difference, since if the $ is at the start of a value
588 * field, the line will be erroneous anyway.
589 */
590 do
591 {
592 if( NULL == (mpsi->f1 = SCIPstrtok(s, " ", &nexttok)) )
593 break;
594
595 if( (NULL == (mpsi->f2 = SCIPstrtok(NULL, " ", &nexttok))) || (*mpsi->f2 == '$') )
596 {
597 mpsi->f2 = 0;
598 break;
599 }
600 if( !strcmp(mpsi->f2, "'MARKER'") )
601 is_marker = TRUE;
602
603 if( (NULL == (mpsi->f3 = SCIPstrtok(NULL, " ", &nexttok))) || (*mpsi->f3 == '$') )
604 {
605 mpsi->f3 = 0;
606 break;
607 }
608 if( is_marker )
609 {
610 if( !strcmp(mpsi->f3, "'INTORG'") )
611 mpsi->isinteger = TRUE;
612 else if( !strcmp(mpsi->f3, "'INTEND'") )
613 mpsi->isinteger = FALSE;
614 else
615 break; /* unknown marker */
616 }
617 if( !strcmp(mpsi->f3, "'MARKER'") )
618 is_marker = TRUE;
619
620 if( (NULL == (mpsi->f4 = SCIPstrtok(NULL, " ", &nexttok))) || (*mpsi->f4 == '$') )
621 {
622 mpsi->f4 = 0;
623 break;
624 }
625 if( is_marker )
626 {
627 if( !strcmp(mpsi->f4, "'INTORG'") )
628 mpsi->isinteger = TRUE;
629 else if( !strcmp(mpsi->f4, "'INTEND'") )
630 mpsi->isinteger = FALSE;
631 else
632 break; /* unknown marker */
633 }
634 if( (NULL == (mpsi->f5 = SCIPstrtok(NULL, " ", &nexttok))) || (*mpsi->f5 == '$') )
635 mpsi->f5 = 0;
636 }
637 while( FALSE );
638
639 /* check for empty lines */
640 is_empty = (mpsi->f0 == NULL && mpsi->f1 == NULL);
641 }
642 while( is_marker || is_empty );
643
644 return TRUE;
645}
646
647/** Insert \p str as field 4 and shift all other fields up. */
648static
650 MPSINPUT* mpsi, /**< mps input structure */
651 const char* str /**< str to insert */
652 )
653{
654 assert(mpsi != NULL);
655 assert(str != NULL);
656
657 mpsi->f5 = mpsi->f4;
658 mpsi->f4 = str;
659}
660
661/** Insert \p name as field 1 or 2 and shift all other fields up. */
662static
664 MPSINPUT* mpsi, /**< mps input structure */
665 const char* name, /**< name to insert */
666 SCIP_Bool second /**< insert as second field? */
667 )
668{
669 assert(mpsi != NULL);
670 assert(name != NULL);
671
672 mpsi->f5 = mpsi->f4;
673 mpsi->f4 = mpsi->f3;
674 mpsi->f3 = mpsi->f2;
675
676 if( second )
677 mpsi->f2 = name;
678 else
679 {
680 mpsi->f2 = mpsi->f1;
681 mpsi->f1 = name;
682 }
683}
684
685/** Add variable name to storage */
686static
688 SCIP* scip, /**< SCIP data structure */
689 const char*** varnames, /**< the variable name storage */
690 int* varnamessize, /**< the size of the variable names storage */
691 int* nvars, /**< the number of variables */
692 const char* colname /**< the name of the variable */
693 )
694{
695 assert(scip != NULL);
696
697 if( varnames != NULL )
698 {
699 SCIP_CALL( SCIPensureBlockMemoryArray(scip, varnames, varnamessize, (*nvars) + 1) );
700 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*varnames)[(*nvars)], colname, strlen(colname) + 1) ); /*lint !e866*/
701 (*nvars)++;
702 }
703
704 return SCIP_OKAY;
705}
706
707/** Add constraint name to storage */
708static
710 SCIP* scip, /**< SCIP data structure */
711 const char*** consnames, /**< the constraint name storage */
712 int* consnamessize, /**< the size of the constraint names storage */
713 int* ncons, /**< the number of constraint */
714 const char* rowname /**< the name of the constraint */
715 )
716{
717 assert(scip != NULL);
718
719 if( consnames != NULL )
720 {
721 SCIP_CALL( SCIPensureBlockMemoryArray(scip, consnames, consnamessize, (*ncons) + 1) );
722 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consnames)[(*ncons)], rowname, strlen(rowname) + 1) ); /*lint !e866*/
723 (*ncons)++;
724 }
725
726 return SCIP_OKAY;
727}
728
729/** Process NAME section. */
730static
732 SCIP* scip, /**< SCIP data structure */
733 MPSINPUT* mpsi /**< mps input structure */
734 )
735{
736 assert(mpsi != NULL);
737
738 SCIPdebugMsg(scip, "read problem name\n");
739
740 /* This has to be the Line with the NAME section. */
741 if( !mpsinputReadLine(mpsi) || mpsinputField0(mpsi) == NULL || strcmp(mpsinputField0(mpsi), "NAME") )
742 {
744 return SCIP_OKAY;
745 }
746
747 /* Sometimes the name is omitted. */
748 mpsinputSetProbname(mpsi, (mpsinputField1(mpsi) == 0) ? "_MPS_" : mpsinputField1(mpsi));
749
750 /* This hat to be a new section */
751 /* coverity[tainted_data] */
752 if( !mpsinputReadLine(mpsi) || (mpsinputField0(mpsi) == NULL) )
753 {
755 return SCIP_OKAY;
756 }
757
758 if( !strncmp(mpsinputField0(mpsi), "ROWS", 4) )
760 else if( !strncmp(mpsinputField0(mpsi), "USERCUTS", 8) )
762 else if( !strncmp(mpsinputField0(mpsi), "LAZYCONS", 8) )
764 else if( !strncmp(mpsinputField0(mpsi), "OBJSEN", 6) )
766 else if( !strncmp(mpsinputField0(mpsi), "OBJNAME", 7) )
768 else
769 {
771 return SCIP_OKAY;
772 }
773
774 return SCIP_OKAY;
775}
776
777/** Process OBJSEN section. This Section is a CPLEX extension. */
778static
780 SCIP* scip, /**< SCIP data structure */
781 MPSINPUT* mpsi /**< mps input structure */
782 )
783{
784 assert(mpsi != NULL);
785
786 SCIPdebugMsg(scip, "read objective sense\n");
787
788 /* Although this is not explicitly in the MPS extensions as provided by CPLEX, some other MIP solvers
789 * (in particular gurobi), put 'MIN' or 'MAX' as the input field on the same line as the section declaration */
790 if( mpsinputField1(mpsi) == NULL){
791 /* Normal Cplex extension; info should be on the next line, in field 1 */
792 /* This has to be the Line with MIN or MAX. */
793 if( !mpsinputReadLine(mpsi) || (mpsinputField1(mpsi) == NULL) )
794 {
796 return SCIP_OKAY;
797 }
798 }
799 /* Otherwise, the input should read e.g. "OBJSENSE MAX" so that MAX is also the first field */
800
801 if( !strncmp(mpsinputField1(mpsi), "MIN", 3) )
803 else if( !strncmp(mpsinputField1(mpsi), "MAX", 3) )
805 else
806 {
808 return SCIP_OKAY;
809 }
810
811 /* Look for ROWS, USERCUTS, LAZYCONS, or OBJNAME Section */
812 /* coverity[tainted_data] */
813 if( !mpsinputReadLine(mpsi) || mpsinputField0(mpsi) == NULL )
814 {
816 return SCIP_OKAY;
817 }
818
819 if( !strcmp(mpsinputField0(mpsi), "ROWS") )
821 else if( !strcmp(mpsinputField0(mpsi), "USERCUTS") )
823 else if( !strcmp(mpsinputField0(mpsi), "LAZYCONS") )
825 else if( !strcmp(mpsinputField0(mpsi), "OBJNAME") )
827 else
828 {
830 return SCIP_OKAY;
831 }
832
833 return SCIP_OKAY;
834}
835
836/** Process OBJNAME section. This Section is a CPLEX extension. */
837static
839 SCIP* scip, /**< SCIP data structure */
840 MPSINPUT* mpsi /**< mps input structure */
841 )
842{
843 assert(mpsi != NULL);
844
845 SCIPdebugMsg(scip, "read objective name\n");
846
847 /* This has to be the Line with the name. */
848 if( !mpsinputReadLine(mpsi) || mpsinputField1(mpsi) == NULL )
849 {
851 return SCIP_OKAY;
852 }
853
855
856 /* Look for ROWS, USERCUTS, or LAZYCONS Section */
857 /* coverity[tainted_data] */
858 if( !mpsinputReadLine(mpsi) || mpsinputField0(mpsi) == NULL )
859 {
861 return SCIP_OKAY;
862 }
863 if( !strcmp(mpsinputField0(mpsi), "ROWS") )
865 else if( !strcmp(mpsinputField0(mpsi), "USERCUTS") )
867 else if( !strcmp(mpsinputField0(mpsi), "LAZYCONS") )
869 else
871
872 return SCIP_OKAY;
873}
874
875/** Process ROWS, USERCUTS, or LAZYCONS section. */
876static
878 MPSINPUT* mpsi, /**< mps input structure */
879 SCIP* scip, /**< SCIP data structure */
880 const char*** consnames, /**< storage for the constraint names, or NULL */
881 int* consnamessize, /**< the size of the constraint names storage, or NULL */
882 int* nconsnames /**< the number of stored constraint names, or NULL */
883 )
884{
885 SCIPdebugMsg(scip, "read rows\n");
886
887 /* coverity[tainted_data] */
888 while( mpsinputReadLine(mpsi) )
889 {
890 if( mpsinputField0(mpsi) != NULL )
891 {
892 if( !strcmp(mpsinputField0(mpsi), "ROWS") )
894 else if( !strcmp(mpsinputField0(mpsi), "USERCUTS") )
896 else if( !strcmp(mpsinputField0(mpsi), "LAZYCONS") )
898 else if( !strcmp(mpsinputField0(mpsi), "COLUMNS") )
900 else
902
903 return SCIP_OKAY;
904 }
905
906 if( *mpsinputField1(mpsi) == 'N' )
907 {
908 if( *mpsinputObjname(mpsi) == '\0' )
910 else if( strcmp(mpsinputObjname(mpsi), mpsinputField2(mpsi)) != 0 )
911 /* if OBJNAME was given and N-row is named differently, then warn that the N-row is not used as objective (OBJNAME takes precedence) */
912 mpsinputEntryIgnored(scip, mpsi, "row", mpsinputField2(mpsi), "objective function", "N", SCIP_VERBLEVEL_NORMAL);
913 }
914 else
915 {
916 SCIP_CONS* cons;
917 SCIP_Bool initial;
919 SCIP_Bool enforce;
920 SCIP_Bool check;
921 SCIP_Bool propagate;
922 SCIP_Bool local;
923 SCIP_Bool modifiable;
924 SCIP_Bool dynamic;
925 SCIP_Bool removable;
926
927 cons = SCIPfindCons(scip, mpsinputField2(mpsi));
928 if( cons != NULL )
929 break;
930
931 initial = mpsi->initialconss && (mpsinputSection(mpsi) == MPS_ROWS);
932 separate = TRUE;
933 enforce = (mpsinputSection(mpsi) != MPS_USERCUTS);
934 check = (mpsinputSection(mpsi) != MPS_USERCUTS);
935 propagate = TRUE;
936 local = FALSE;
937 modifiable = FALSE;
938 dynamic = mpsi->dynamicconss;
939 removable = mpsi->dynamicrows || (mpsinputSection(mpsi) == MPS_USERCUTS);
940
941 switch(*mpsinputField1(mpsi))
942 {
943 case 'G' :
945 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE) );
946 break;
947 case 'E' :
948 SCIP_CALL( SCIPcreateConsLinear(scip, &cons, mpsinputField2(mpsi), 0, NULL, NULL, 0.0, 0.0,
949 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE) );
950 break;
951 case 'L' :
953 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE) );
954 break;
955 default :
957 return SCIP_OKAY;
958 }
959 SCIP_CALL( SCIPaddCons(scip, cons) );
960 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
961
962 /* if the file is of type cor, then the constraint names must be stored */
963 SCIP_CALL( addConsNameToStorage(scip, consnames, consnamessize, nconsnames, mpsinputField2(mpsi)) );
964 }
965 }
967
968 return SCIP_OKAY;
969}
970
971/** Process ROWS, USERCUTS, or LAZYCONS section. (exact version) */
972static
974 MPSINPUT* mpsi, /**< mps input structure */
975 SCIP* scip, /**< SCIP data structure */
976 const char*** consnames, /**< storage for the constraint names, or NULL */
977 int* consnamessize, /**< the size of the constraint names storage, or NULL */
978 int* nconsnames /**< the number of stored constraint names, or NULL */
979 )
980{
981 SCIPdebugMsg(scip, "read rows\n");
982
983 while( mpsinputReadLine(mpsi) )
984 {
985 if( mpsinputField0(mpsi) != NULL )
986 {
987 if( !strcmp(mpsinputField0(mpsi), "ROWS") )
989 else if( !strcmp(mpsinputField0(mpsi), "USERCUTS") )
991 else if( !strcmp(mpsinputField0(mpsi), "LAZYCONS") )
993 else if( !strcmp(mpsinputField0(mpsi), "COLUMNS") )
995 else
997
998 return SCIP_OKAY;
999 }
1000
1001 if( *mpsinputField1(mpsi) == 'N' )
1002 {
1003 if( *mpsinputObjname(mpsi) == '\0' )
1005 else
1006 mpsinputEntryIgnored(scip, mpsi, "row", mpsinputField2(mpsi), "objective function", "N", SCIP_VERBLEVEL_NORMAL);
1007 }
1008 else
1009 {
1010 SCIP_RATIONAL* lhs;
1011 SCIP_RATIONAL* rhs;
1012 SCIP_CONS* cons;
1013 SCIP_Bool initial;
1015 SCIP_Bool enforce;
1016 SCIP_Bool check;
1017 SCIP_Bool propagate;
1018 SCIP_Bool local;
1019 SCIP_Bool modifiable;
1020 SCIP_Bool dynamic;
1021 SCIP_Bool removable;
1022
1023 cons = SCIPfindCons(scip, mpsinputField2(mpsi));
1024 if( cons != NULL )
1025 break;
1026
1027 initial = mpsi->initialconss && (mpsinputSection(mpsi) == MPS_ROWS);
1028 separate = TRUE;
1029 enforce = (mpsinputSection(mpsi) != MPS_USERCUTS);
1030 check = (mpsinputSection(mpsi) != MPS_USERCUTS);
1031 propagate = TRUE;
1032 local = FALSE;
1033 modifiable = FALSE;
1034 dynamic = mpsi->dynamicconss;
1035 removable = mpsi->dynamicrows || (mpsinputSection(mpsi) == MPS_USERCUTS);
1036
1039
1040 switch(*mpsinputField1(mpsi))
1041 {
1042 case 'G' :
1044 SCIPrationalSetReal(lhs, 0.0);
1045 break;
1046 case 'E' :
1047 SCIPrationalSetReal(rhs, 0.0);
1048 SCIPrationalSetReal(lhs, 0.0);
1049 break;
1050 case 'L' :
1052 SCIPrationalSetReal(rhs, 0.0);
1053 break;
1054 default :
1055 mpsinputSyntaxerror(mpsi);
1056 return SCIP_OKAY;
1057 }
1058
1059 SCIP_CALL( SCIPcreateConsExactLinear(scip, &cons, mpsinputField2(mpsi), 0, NULL, NULL, lhs, rhs,
1060 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE) );
1061
1062 SCIP_CALL( SCIPaddCons(scip, cons) );
1063 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1064
1067
1068 /* if the file is of type cor, then the constraint names must be stored */
1069 SCIP_CALL( addConsNameToStorage(scip, consnames, consnamessize, nconsnames, mpsinputField2(mpsi)) );
1070 }
1071 }
1072 mpsinputSyntaxerror(mpsi);
1073
1074 return SCIP_OKAY;
1075}
1076
1077/** Process COLUMNS section. */
1078static
1080 MPSINPUT* mpsi, /**< mps input structure */
1081 SCIP* scip, /**< SCIP data structure */
1082 const char*** varnames, /**< storage for the variable names, or NULL */
1083 int* varnamessize, /**< the size of the variable names storage, or NULL */
1084 int* nvarnames /**< the number of stored variable names, or NULL */
1085 )
1086{
1087 char colname[MPS_MAX_NAMELEN] = { '\0' };
1088 SCIP_CONS* cons;
1089 SCIP_VAR* var;
1090 SCIP_Real val;
1091 SCIP_Bool usevartable;
1092
1093 SCIPdebugMsg(scip, "read columns\n");
1094
1095 var = NULL;
1096 SCIP_CALL( SCIPgetBoolParam(scip, "misc/usevartable", &usevartable) );
1097
1098 while( mpsinputReadLine(mpsi) )
1099 {
1100 if( mpsinputField0(mpsi) != 0 )
1101 {
1102 if( strcmp(mpsinputField0(mpsi), "RHS") )
1103 break;
1104
1105 /* add the last variable to the problem */
1106 if( var != NULL )
1107 {
1108 SCIP_CALL( SCIPaddVar(scip, var) );
1109 SCIP_CALL( SCIPreleaseVar(scip, &var) );
1110 }
1111 assert(var == NULL);
1112
1114 return SCIP_OKAY;
1115 }
1116 if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL || mpsinputField3(mpsi) == NULL )
1117 break;
1118
1119 /* new column? */
1120 if( strcmp(colname, mpsinputField1(mpsi)) )
1121 {
1122 /* add the last variable to the problem */
1123 if( var != NULL )
1124 {
1125 SCIP_CALL( SCIPaddVar(scip, var) );
1126 SCIP_CALL( SCIPreleaseVar(scip, &var) );
1127 }
1128 assert(var == NULL);
1129
1130 (void)SCIPmemccpy(colname, mpsinputField1(mpsi), '\0', MPS_MAX_NAMELEN - 1);
1131
1132 /* check whether we have seen this variable before, this would not allowed */
1133 if( usevartable && SCIPfindVar(scip, colname) != NULL )
1134 {
1135 SCIPerrorMessage("Coeffients of column <%s> don't appear consecutively (line: %d)\n",
1136 colname, mpsi->lineno);
1137
1138 return SCIP_READERROR;
1139 }
1140
1141 /* if the file type is a cor file, the the variable name must be stored */
1142 SCIP_CALL( addVarNameToStorage(scip, varnames, varnamessize, nvarnames, colname) );
1143
1144 if( mpsinputIsInteger(mpsi) )
1145 {
1146 /* for integer variables, default bounds are 0 <= x < 1(not +infinity, like it is for continuous variables), and default cost is 0 */
1147 SCIP_CALL( SCIPcreateVar(scip, &var, colname, 0.0, 1.0, 0.0, SCIP_VARTYPE_BINARY,
1148 !mpsi->dynamiccols, mpsi->dynamiccols, NULL, NULL, NULL, NULL, NULL) );
1149 }
1150 else
1151 {
1152 /* for continuous variables, default bounds are 0 <= x, and default cost is 0 */
1154 !mpsi->dynamiccols, mpsi->dynamiccols, NULL, NULL, NULL, NULL, NULL) );
1155 }
1156 }
1157 assert(var != NULL);
1158
1159 val = atof(mpsinputField3(mpsi));
1160
1161 if( !strcmp(mpsinputField2(mpsi), mpsinputObjname(mpsi)) )
1162 {
1163 SCIP_CALL( SCIPchgVarObj(scip, var, val) );
1164 }
1165 else
1166 {
1167 cons = SCIPfindCons(scip, mpsinputField2(mpsi));
1168 if( cons == NULL )
1169 mpsinputEntryIgnored(scip, mpsi, "Column", mpsinputField1(mpsi), "row", mpsinputField2(mpsi), SCIP_VERBLEVEL_FULL);
1170 else if( !SCIPisZero(scip, val) )
1171 {
1172 /* warn the user in case the coefficient is infinite */
1173 if( SCIPisInfinity(scip, REALABS(val)) )
1174 {
1175 SCIPwarningMessage(scip, "Coefficient of variable <%s> in constraint <%s> contains infinite value <%e>,"
1176 " consider adjusting SCIP infinity.\n", SCIPvarGetName(var), SCIPconsGetName(cons), val);
1177 }
1178 SCIP_CALL( SCIPaddCoefLinear(scip, cons, var, val) );
1179 }
1180 }
1181 if( mpsinputField5(mpsi) != NULL )
1182 {
1183 assert(mpsinputField4(mpsi) != NULL);
1184
1185 val = atof(mpsinputField5(mpsi));
1186
1187 if( !strcmp(mpsinputField4(mpsi), mpsinputObjname(mpsi)) )
1188 {
1189 SCIP_CALL( SCIPchgVarObj(scip, var, val) );
1190 }
1191 else
1192 {
1193 cons = SCIPfindCons(scip, mpsinputField4(mpsi));
1194 if( cons == NULL )
1195 mpsinputEntryIgnored(scip, mpsi, "Column", mpsinputField1(mpsi), "row", mpsinputField4(mpsi), SCIP_VERBLEVEL_FULL);
1196 else if( !SCIPisZero(scip, val) )
1197 {
1198 SCIP_CALL( SCIPaddCoefLinear(scip, cons, var, val) );
1199 }
1200 }
1201 }
1202 }
1203 mpsinputSyntaxerror(mpsi);
1204
1205 return SCIP_OKAY;
1206}
1207
1208/** Process COLUMNS section. (exact version) */
1209static
1211 MPSINPUT* mpsi, /**< mps input structure */
1212 SCIP* scip, /**< SCIP data structure */
1213 const char*** varnames, /**< storage for the variable names, or NULL */
1214 int* varnamessize, /**< the size of the variable names storage, or NULL */
1215 int* nvarnames /**< the number of stored variable names, or NULL */
1216 )
1217{
1218 SCIP_RETCODE retcode = SCIP_OKAY;
1219 char colname[MPS_MAX_NAMELEN] = { '\0' };
1220 SCIP_CONS* cons;
1221 SCIP_VAR* var;
1222 SCIP_RATIONAL* val;
1223 SCIP_Bool usevartable;
1224
1225 SCIPdebugMsg(scip, "read columns\n");
1226
1227 var = NULL;
1228 SCIP_CALL( SCIPgetBoolParam(scip, "misc/usevartable", &usevartable) );
1229
1230 while( mpsinputReadLine(mpsi) )
1231 {
1232 if( mpsinputField0(mpsi) != 0 )
1233 {
1234 if( strcmp(mpsinputField0(mpsi), "RHS") )
1235 break;
1236
1237 /* add the last variable to the problem */
1238 if( var != NULL )
1239 {
1240 SCIP_CALL( SCIPaddVar(scip, var) );
1241 SCIP_CALL( SCIPreleaseVar(scip, &var) );
1242 }
1243 assert(var == NULL);
1244
1246 return SCIP_OKAY;
1247 }
1248 if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL || mpsinputField3(mpsi) == NULL )
1249 break;
1250
1251 /* new column? */
1252 if( strcmp(colname, mpsinputField1(mpsi)) )
1253 {
1254 /* add the last variable to the problem */
1255 if( var != NULL )
1256 {
1257 SCIP_CALL( SCIPaddVar(scip, var) );
1258 SCIP_CALL( SCIPreleaseVar(scip, &var) );
1259 }
1260 assert(var == NULL);
1261
1262 (void)SCIPmemccpy(colname, mpsinputField1(mpsi), '\0', MPS_MAX_NAMELEN - 1);
1263
1264 /* check whether we have seen this variable before, this would not allowed */
1265 if( usevartable && SCIPfindVar(scip, colname) != NULL )
1266 {
1267 SCIPerrorMessage("Coeffients of column <%s> don't appear consecutively (line: %d)\n",
1268 colname, mpsi->lineno);
1269
1270 return SCIP_READERROR;
1271 }
1272
1273 /* if the file type is a cor file, the the variable name must be stored */
1274 SCIP_CALL( addVarNameToStorage(scip, varnames, varnamessize, nvarnames, colname) );
1275
1276 if( mpsinputIsInteger(mpsi) )
1277 {
1278 /* for integer variables, default bounds are 0 <= x < 1(not +infinity, like it is for continuous variables), and default cost is 0 */
1279 SCIP_CALL( SCIPcreateVar(scip, &var, colname, 0.0, 1.0, 0.0, SCIP_VARTYPE_BINARY,
1280 !mpsi->dynamiccols, mpsi->dynamiccols, NULL, NULL, NULL, NULL, NULL) );
1281 }
1282 else
1283 {
1284 /* for continuous variables, default bounds are 0 <= x, and default cost is 0 */
1286 !mpsi->dynamiccols, mpsi->dynamiccols, NULL, NULL, NULL, NULL, NULL) );
1287 }
1288 /* create exact data if we are in exact solving mode */
1289 if( SCIPisExact(scip) )
1290 {
1292 }
1293 }
1294 assert(var != NULL);
1295
1299
1300 if( !strcmp(mpsinputField2(mpsi), mpsinputObjname(mpsi)) )
1301 {
1302 SCIP_CALL_TERMINATE( retcode, SCIPchgVarObjExact(scip, var, val), TERMINATE );
1303 }
1304 else
1305 {
1306 cons = SCIPfindCons(scip, mpsinputField2(mpsi));
1307 if( cons == NULL )
1308 mpsinputEntryIgnored(scip, mpsi, "Column", mpsinputField1(mpsi), "row", mpsinputField2(mpsi), SCIP_VERBLEVEL_FULL);
1309 else if( !SCIPrationalIsZero(val) )
1310 {
1311 /* this method returns an error if the coefficient is infinite */
1312 SCIP_CALL_TERMINATE( retcode, SCIPaddCoefExactLinear(scip, cons, var, val), TERMINATE );
1313 }
1314 }
1315 if( mpsinputField5(mpsi) != NULL )
1316 {
1317 assert(mpsinputField4(mpsi) != NULL);
1318
1321
1322 if( !strcmp(mpsinputField4(mpsi), mpsinputObjname(mpsi)) )
1323 {
1324 SCIP_CALL_TERMINATE( retcode, SCIPchgVarObjExact(scip, var, val), TERMINATE );
1325 }
1326 else
1327 {
1328 cons = SCIPfindCons(scip, mpsinputField4(mpsi));
1329 if( cons == NULL )
1330 {
1331 mpsinputEntryIgnored(scip, mpsi, "Column", mpsinputField1(mpsi), "row", mpsinputField4(mpsi), SCIP_VERBLEVEL_FULL);
1332 }
1333 else if( !SCIPrationalIsZero(val) )
1334 {
1335 SCIP_CALL_TERMINATE( retcode, SCIPaddCoefExactLinear(scip, cons, var, val), TERMINATE );
1336 }
1337 }
1338 }
1339 TERMINATE:
1340 /* free rational buffer */
1342 if( retcode != SCIP_OKAY )
1343 {
1344 SCIP_CALL( SCIPreleaseVar(scip, &var) );
1345 return retcode;
1346 }
1347 }
1348 mpsinputSyntaxerror(mpsi);
1349
1350 return SCIP_OKAY;
1351}
1352
1353/** Process RHS section. */
1354static
1356 MPSINPUT* mpsi, /**< mps input structure */
1357 SCIP* scip /**< SCIP data structure */
1358 )
1359{
1360 char rhsname[MPS_MAX_NAMELEN] = { '\0' };
1361 SCIP_CONS* cons;
1362 SCIP_Real lhs;
1363 SCIP_Real rhs;
1364 SCIP_Real val;
1365
1366 SCIPdebugMsg(scip, "read right hand sides\n");
1367
1368 while( mpsinputReadLine(mpsi) )
1369 {
1370 if( mpsinputField0(mpsi) != NULL )
1371 {
1372 if( !strcmp(mpsinputField0(mpsi), "RANGES") )
1374 else if( !strcmp(mpsinputField0(mpsi), "BOUNDS") )
1376 else if( !strcmp(mpsinputField0(mpsi), "SOS") )
1378 else if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
1380 else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
1382 else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
1384 else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
1386 else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
1388 else
1389 break;
1390 return SCIP_OKAY;
1391 }
1392 if( (mpsinputField2(mpsi) != NULL && mpsinputField3(mpsi) == NULL)
1393 || (mpsinputField4(mpsi) != NULL && mpsinputField5(mpsi) == NULL) )
1394 {
1395 SCIPwarningMessage(scip, "reading rhs section, a field is missing, assuming that the vector name is the missing one(, row identfier <%s>)\n", mpsinputField2(mpsi));
1396
1397 mpsinputInsertName(mpsi, "_RHS_", FALSE);
1398 }
1399
1400 if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL || mpsinputField3(mpsi) == NULL )
1401 break;
1402
1403 if( *rhsname == '\0' )
1404 (void)SCIPmemccpy(rhsname, mpsinputField1(mpsi), '\0', MPS_MAX_NAMELEN - 1);
1405
1406 if( !strcmp(rhsname, mpsinputField1(mpsi)) )
1407 {
1408 cons = SCIPfindCons(scip, mpsinputField2(mpsi));
1409 if( cons == NULL )
1410 {
1411 /* the rhs of the objective row is treated as objective constant */
1412 if( strcmp(mpsinputField2(mpsi), mpsinputObjname(mpsi)) == 0 )
1413 {
1414 val = atof(mpsinputField3(mpsi));
1416 }
1417 else
1419 }
1420 else
1421 {
1422 val = atof(mpsinputField3(mpsi));
1423
1424 /* find out the row sense */
1425 lhs = SCIPgetLhsLinear(scip, cons);
1426 rhs = SCIPgetRhsLinear(scip, cons);
1427 if( SCIPisInfinity(scip, -lhs) )
1428 {
1429 /* lhs = -infinity -> lower or equal */
1430 assert(SCIPisZero(scip, rhs));
1431 SCIP_CALL( SCIPchgRhsLinear(scip, cons, val) );
1432 }
1433 else if( SCIPisInfinity(scip, rhs) )
1434 {
1435 /* rhs = +infinity -> greater or equal */
1436 assert(SCIPisZero(scip, lhs));
1437 SCIP_CALL( SCIPchgLhsLinear(scip, cons, val) );
1438 }
1439 else
1440 {
1441 /* lhs > -infinity, rhs < infinity -> equality */
1442 assert(SCIPisZero(scip, lhs));
1443 assert(SCIPisZero(scip, rhs));
1444 SCIP_CALL( SCIPchgLhsLinear(scip, cons, val) );
1445 SCIP_CALL( SCIPchgRhsLinear(scip, cons, val) );
1446 }
1447 SCIPdebugMsg(scip, "RHS <%s> lhs: %g rhs: %g val: <%22.12g>\n", mpsinputField2(mpsi), lhs, rhs, val);
1448 }
1449 if( mpsinputField5(mpsi) != NULL )
1450 {
1451 cons = SCIPfindCons(scip, mpsinputField4(mpsi));
1452 if( cons == NULL )
1453 {
1454 /* the rhs of the objective row is treated as objective constant */
1455 if( strcmp(mpsinputField4(mpsi), mpsinputObjname(mpsi)) == 0 )
1456 {
1457 val = atof(mpsinputField5(mpsi));
1459 }
1460 else
1462 }
1463 else
1464 {
1465 val = atof(mpsinputField5(mpsi));
1466
1467 /* find out the row sense */
1468 lhs = SCIPgetLhsLinear(scip, cons);
1469 rhs = SCIPgetRhsLinear(scip, cons);
1470 if( SCIPisInfinity(scip, -lhs) )
1471 {
1472 /* lhs = -infinity -> lower or equal */
1473 assert(SCIPisZero(scip, rhs));
1474 SCIP_CALL( SCIPchgRhsLinear(scip, cons, val) );
1475 }
1476 else if( SCIPisInfinity(scip, rhs) )
1477 {
1478 /* rhs = +infinity -> greater or equal */
1479 assert(SCIPisZero(scip, lhs));
1480 SCIP_CALL( SCIPchgLhsLinear(scip, cons, val) );
1481 }
1482 else
1483 {
1484 /* lhs > -infinity, rhs < infinity -> equality */
1485 assert(SCIPisZero(scip, lhs));
1486 assert(SCIPisZero(scip, rhs));
1487 SCIP_CALL( SCIPchgLhsLinear(scip, cons, val) );
1488 SCIP_CALL( SCIPchgRhsLinear(scip, cons, val) );
1489 }
1490 SCIPdebugMsg(scip, "RHS <%s> lhs: %g rhs: %g val: <%22.12g>\n", mpsinputField4(mpsi), lhs, rhs, val);
1491 }
1492 }
1493 }
1494 }
1495 mpsinputSyntaxerror(mpsi);
1496
1497 return SCIP_OKAY;
1498}
1499
1500/** Process RHS section (exact version). */
1501static
1503 MPSINPUT* mpsi, /**< mps input structure */
1504 SCIP* scip /**< SCIP data structure */
1505 )
1506{
1507 char rhsname[MPS_MAX_NAMELEN] = { '\0' };
1508 SCIP_CONS* cons;
1509 SCIP_Real val;
1510 SCIP_RATIONAL* lhs;
1511 SCIP_RATIONAL* rhs;
1512 SCIP_RATIONAL* valexact;
1513
1515
1516 SCIPdebugMsg(scip, "read right hand sides\n");
1517
1518 while( mpsinputReadLine(mpsi) )
1519 {
1520 if( mpsinputField0(mpsi) != NULL )
1521 {
1522 if( !strcmp(mpsinputField0(mpsi), "RANGES") )
1524 else if( !strcmp(mpsinputField0(mpsi), "BOUNDS") )
1526 else if( !strcmp(mpsinputField0(mpsi), "SOS") )
1528 else if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
1530 else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
1532 else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
1534 else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
1536 else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
1538 else
1539 break;
1540
1542
1543 return SCIP_OKAY;
1544 }
1545 if( (mpsinputField2(mpsi) != NULL && mpsinputField3(mpsi) == NULL)
1546 || (mpsinputField4(mpsi) != NULL && mpsinputField5(mpsi) == NULL) )
1547 {
1548 SCIPwarningMessage(scip, "reading rhs section, a field is missing, assuming that the vector name is the missing one(, row identfier <%s>)\n", mpsinputField2(mpsi));
1549
1550 mpsinputInsertName(mpsi, "_RHS_", FALSE);
1551 }
1552
1553 if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL || mpsinputField3(mpsi) == NULL )
1554 break;
1555
1556 if( *rhsname == '\0' )
1557 (void)SCIPmemccpy(rhsname, mpsinputField1(mpsi), '\0', MPS_MAX_NAMELEN - 1);
1558
1559 if( !strcmp(rhsname, mpsinputField1(mpsi)) )
1560 {
1561 cons = SCIPfindCons(scip, mpsinputField2(mpsi));
1562 if( cons == NULL )
1563 {
1564 /* the rhs of the objective row is treated as objective constant */
1565 if( !strcmp(mpsinputField2(mpsi), mpsinputObjname(mpsi)) )
1566 {
1567 val = atof(mpsinputField3(mpsi));
1569 }
1570 else
1572 }
1573 else
1574 {
1575 SCIPrationalSetString(valexact, mpsinputField3(mpsi));
1576 SCIPrationalCanonicalize(valexact);
1577
1578 /* find out the row sense */
1579 lhs = SCIPgetLhsExactLinear(scip, cons);
1580 rhs = SCIPgetRhsExactLinear(scip, cons);
1581 if( SCIPrationalIsNegInfinity(lhs) )
1582 {
1583 /* lhs = -infinity -> lower or equal */
1584 assert(SCIPrationalIsZero(rhs));
1585 SCIP_CALL( SCIPchgRhsExactLinear(scip, cons, valexact) );
1586 }
1587 else if( SCIPrationalIsInfinity(rhs) )
1588 {
1589 /* rhs = +infinity -> greater or equal */
1590 assert(SCIPrationalIsZero(lhs));
1591 SCIP_CALL( SCIPchgLhsExactLinear(scip, cons, valexact) );
1592 }
1593 else
1594 {
1595 /* lhs > -infinity, rhs < infinity -> equality */
1596 assert(SCIPrationalIsZero(lhs));
1597 assert(SCIPrationalIsZero(rhs));
1598 SCIP_CALL( SCIPchgLhsExactLinear(scip, cons, valexact) );
1599 SCIP_CALL( SCIPchgRhsExactLinear(scip, cons, valexact) );
1600 }
1601 SCIPrationalDebugMessage("RHS <%s> lhs: %q rhs: %q val: <%q>\n", mpsinputField2(mpsi), lhs, rhs, valexact);
1602 }
1603 if( mpsinputField5(mpsi) != NULL )
1604 {
1605 cons = SCIPfindCons(scip, mpsinputField4(mpsi));
1606 if( cons == NULL )
1607 {
1608 /* the rhs of the objective row is treated as objective constant */
1609 if( !strcmp(mpsinputField2(mpsi), mpsinputObjname(mpsi)) )
1610 {
1611 val = atof(mpsinputField3(mpsi));
1613 }
1614 else
1616 }
1617 else
1618 {
1619 SCIPrationalSetString(valexact, mpsinputField5(mpsi));
1620 SCIPrationalCanonicalize(valexact);
1621
1622 /* find out the row sense */
1623 lhs = SCIPgetLhsExactLinear(scip, cons);
1624 rhs = SCIPgetRhsExactLinear(scip, cons);
1625 if( SCIPrationalIsNegInfinity(lhs) )
1626 {
1627 /* lhs = -infinity -> lower or equal */
1628 assert(SCIPrationalIsZero(rhs));
1629 SCIP_CALL( SCIPchgRhsExactLinear(scip, cons, valexact) );
1630 }
1631 else if( SCIPrationalIsInfinity(rhs) )
1632 {
1633 /* rhs = +infinity -> greater or equal */
1634 assert(SCIPrationalIsZero(lhs));
1635 SCIP_CALL( SCIPchgLhsExactLinear(scip, cons, valexact) );
1636 }
1637 else
1638 {
1639 /* lhs > -infinity, rhs < infinity -> equality */
1640 assert(SCIPrationalIsZero(lhs));
1641 assert(SCIPrationalIsZero(rhs));
1642 SCIP_CALL( SCIPchgLhsExactLinear(scip, cons, valexact) );
1643 SCIP_CALL( SCIPchgRhsExactLinear(scip, cons, valexact) );
1644 }
1645 SCIPrationalDebugMessage("RHS <%s> lhs: %q rhs: %q val: <%q>\n", mpsinputField4(mpsi), lhs, rhs, valexact);
1646 }
1647 }
1648 }
1649 }
1650 mpsinputSyntaxerror(mpsi);
1651
1652 return SCIP_OKAY;
1653}
1654
1655/** Process RANGES section */
1656static
1658 MPSINPUT* mpsi, /**< mps input structure */
1659 SCIP* scip /**< SCIP data structure */
1660 )
1661{
1662 char rngname[MPS_MAX_NAMELEN] = { '\0' };
1663 SCIP_CONS* cons;
1664 SCIP_Real lhs;
1665 SCIP_Real rhs;
1666 SCIP_Real val;
1667
1668 SCIPdebugMsg(scip, "read ranges\n");
1669
1670 while( mpsinputReadLine(mpsi) )
1671 {
1672 if( mpsinputField0(mpsi) != NULL )
1673 {
1674 if( !strcmp(mpsinputField0(mpsi), "BOUNDS") )
1676 else if( !strcmp(mpsinputField0(mpsi), "SOS") )
1678 else if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
1680 else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
1682 else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
1684 else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
1686 else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
1688 else
1689 break;
1690 return SCIP_OKAY;
1691 }
1692 if( (mpsinputField2(mpsi) != NULL && mpsinputField3(mpsi) == NULL)
1693 || (mpsinputField4(mpsi) != NULL && mpsinputField5(mpsi) == NULL) )
1694 {
1695 SCIPwarningMessage(scip, "reading ranged section, a field is missing, assuming that the vector name is the missing one(, row identfier <%s>)\n", mpsinputField2(mpsi));
1696
1697 mpsinputInsertName(mpsi, "_RNG_", FALSE);
1698 }
1699
1700 if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL || mpsinputField3(mpsi) == NULL )
1701 break;
1702
1703 if( *rngname == '\0' )
1704 (void)SCIPmemccpy(rngname, mpsinputField1(mpsi), '\0', MPS_MAX_NAMELEN - 1);
1705
1706 /* The rules are:
1707 * Row Sign LHS RHS
1708 * ----------------------------------------
1709 * G +/- rhs rhs + |range|
1710 * L +/- rhs - |range| rhs
1711 * E + rhs rhs + range
1712 * E - rhs + range rhs
1713 * ----------------------------------------
1714 */
1715 if( !strcmp(rngname, mpsinputField1(mpsi)) )
1716 {
1717 cons = SCIPfindCons(scip, mpsinputField2(mpsi));
1718 if( cons == NULL )
1719 mpsinputEntryIgnored(scip, mpsi, "Range", mpsinputField1(mpsi), "row", mpsinputField2(mpsi), SCIP_VERBLEVEL_NORMAL);
1720 else
1721 {
1722 val = atof(mpsinputField3(mpsi));
1723
1724 /* find out the row sense */
1725 lhs = SCIPgetLhsLinear(scip, cons);
1726 rhs = SCIPgetRhsLinear(scip, cons);
1727 if( SCIPisInfinity(scip, -lhs) )
1728 {
1729 /* lhs = -infinity -> lower or equal */
1730 SCIP_CALL( SCIPchgLhsLinear(scip, cons, rhs - REALABS(val)) );
1731 }
1732 else if( SCIPisInfinity(scip, rhs) )
1733 {
1734 /* rhs = +infinity -> greater or equal */
1735 SCIP_CALL( SCIPchgRhsLinear(scip, cons, lhs + REALABS(val)) );
1736 }
1737 else
1738 {
1739 /* lhs > -infinity, rhs < infinity -> equality */
1740 assert(SCIPisEQ(scip, lhs, rhs));
1741 if( val >= 0.0 )
1742 {
1743 SCIP_CALL( SCIPchgRhsLinear(scip, cons, rhs + val) );
1744 }
1745 else
1746 {
1747 SCIP_CALL( SCIPchgLhsLinear(scip, cons, lhs + val) );
1748 }
1749 }
1750 }
1751 if( mpsinputField5(mpsi) != NULL )
1752 {
1753 cons = SCIPfindCons(scip, mpsinputField4(mpsi));
1754 if( cons == NULL )
1755 mpsinputEntryIgnored(scip, mpsi, "Range", mpsinputField1(mpsi), "row", mpsinputField4(mpsi), SCIP_VERBLEVEL_NORMAL);
1756 else
1757 {
1758 val = atof(mpsinputField5(mpsi));
1759
1760 /* find out the row sense */
1761 lhs = SCIPgetLhsLinear(scip, cons);
1762 rhs = SCIPgetRhsLinear(scip, cons);
1763 if( SCIPisInfinity(scip, -lhs) )
1764 {
1765 /* lhs = -infinity -> lower or equal */
1766 SCIP_CALL( SCIPchgLhsLinear(scip, cons, rhs - REALABS(val)) );
1767 }
1768 else if( SCIPisInfinity(scip, rhs) )
1769 {
1770 /* rhs = +infinity -> greater or equal */
1771 SCIP_CALL( SCIPchgRhsLinear(scip, cons, lhs + REALABS(val)) );
1772 }
1773 else
1774 {
1775 /* lhs > -infinity, rhs < infinity -> equality */
1776 assert(SCIPisEQ(scip, lhs, rhs));
1777 if( val >= 0.0 )
1778 {
1779 SCIP_CALL( SCIPchgRhsLinear(scip, cons, rhs + val) );
1780 }
1781 else
1782 {
1783 SCIP_CALL( SCIPchgLhsLinear(scip, cons, lhs + val) );
1784 }
1785 }
1786 }
1787 }
1788 }
1789 }
1790 mpsinputSyntaxerror(mpsi);
1791
1792 return SCIP_OKAY;
1793}
1794
1795/** Process RANGES section (exact version) */
1796static
1798 MPSINPUT* mpsi, /**< mps input structure */
1799 SCIP* scip /**< SCIP data structure */
1800 )
1801{
1802 char rngname[MPS_MAX_NAMELEN] = { '\0' };
1803 SCIP_CONS* cons;
1804 SCIP_RATIONAL* lhs;
1805 SCIP_RATIONAL* rhs;
1806 SCIP_RATIONAL* val;
1807
1808 SCIPdebugMsg(scip, "read ranges\n");
1809
1811
1812 while( mpsinputReadLine(mpsi) )
1813 {
1814 if( mpsinputField0(mpsi) != NULL )
1815 {
1816 if( !strcmp(mpsinputField0(mpsi), "BOUNDS") )
1818 else if( !strcmp(mpsinputField0(mpsi), "SOS") )
1820 else if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
1822 else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
1824 else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
1826 else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
1828 else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
1830 else
1831 break;
1832
1834
1835 return SCIP_OKAY;
1836 }
1837 if( (mpsinputField2(mpsi) != NULL && mpsinputField3(mpsi) == NULL)
1838 || (mpsinputField4(mpsi) != NULL && mpsinputField5(mpsi) == NULL) )
1839 {
1840 SCIPwarningMessage(scip, "reading ranged section, a field is missing, assuming that the vector name is the missing one(, row identfier <%s>)\n", mpsinputField2(mpsi));
1841
1842 mpsinputInsertName(mpsi, "_RNG_", FALSE);
1843 }
1844
1845 if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL || mpsinputField3(mpsi) == NULL )
1846 break;
1847
1848 if( *rngname == '\0' )
1849 (void)SCIPmemccpy(rngname, mpsinputField1(mpsi), '\0', MPS_MAX_NAMELEN - 1);
1850
1851 /* The rules are:
1852 * Row Sign LHS RHS
1853 * ----------------------------------------
1854 * G +/- rhs rhs + |range|
1855 * L +/- rhs - |range| rhs
1856 * E + rhs rhs + range
1857 * E - rhs + range rhs
1858 * ----------------------------------------
1859 */
1860 if( !strcmp(rngname, mpsinputField1(mpsi)) )
1861 {
1862 cons = SCIPfindCons(scip, mpsinputField2(mpsi));
1863 if( cons == NULL )
1864 mpsinputEntryIgnored(scip, mpsi, "Range", mpsinputField1(mpsi), "row", mpsinputField2(mpsi), SCIP_VERBLEVEL_NORMAL);
1865 else
1866 {
1869
1870 /* find out the row sense */
1871 lhs = SCIPgetLhsExactLinear(scip, cons);
1872 rhs = SCIPgetRhsExactLinear(scip, cons);
1873 if( SCIPrationalIsNegInfinity(lhs) )
1874 {
1875 /* lhs = -infinity -> lower or equal */
1876 SCIPrationalAbs(val, val);
1877 SCIPrationalDiff(val, rhs, val);
1878 SCIP_CALL( SCIPchgLhsExactLinear(scip, cons, val) );
1879 }
1880 else if( SCIPrationalIsInfinity(rhs) )
1881 {
1882 /* rhs = +infinity -> greater or equal */
1883 SCIPrationalAbs(val, val);
1884 SCIPrationalAdd(val, val, lhs);
1885 SCIP_CALL( SCIPchgRhsExactLinear(scip, cons, val) );
1886 }
1887 else
1888 {
1889 /* lhs > -infinity, rhs < infinity -> equality */
1890 assert(SCIPrationalIsEQ(lhs, rhs));
1891 if( !SCIPrationalIsNegative(val) )
1892 {
1893 SCIPrationalAdd(val, val, rhs);
1894 SCIP_CALL( SCIPchgRhsExactLinear(scip, cons, val) );
1895 }
1896 else
1897 {
1898 SCIPrationalAdd(val, val, lhs);
1899 SCIP_CALL( SCIPchgLhsExactLinear(scip, cons, val) );
1900 }
1901 }
1902 }
1903 if( mpsinputField5(mpsi) != NULL )
1904 {
1905 cons = SCIPfindCons(scip, mpsinputField4(mpsi));
1906 if( cons == NULL )
1907 mpsinputEntryIgnored(scip, mpsi, "Range", mpsinputField1(mpsi), "row", mpsinputField4(mpsi), SCIP_VERBLEVEL_NORMAL);
1908 else
1909 {
1912
1913 /* find out the row sense */
1914 lhs = SCIPgetLhsExactLinear(scip, cons);
1915 rhs = SCIPgetRhsExactLinear(scip, cons);
1916 if( SCIPrationalIsNegInfinity(lhs) )
1917 {
1918 /* lhs = -infinity -> lower or equal */
1919 SCIPrationalAbs(val, val);
1920 SCIPrationalDiff(val, rhs, val);
1921 SCIP_CALL( SCIPchgLhsExactLinear(scip, cons, val) );
1922 }
1923 else if( SCIPrationalIsInfinity(rhs) )
1924 {
1925 /* rhs = +infinity -> greater or equal */
1926 SCIPrationalAbs(val, val);
1927 SCIPrationalAdd(val, lhs, val);
1928 SCIP_CALL( SCIPchgRhsExactLinear(scip, cons, val) );
1929 }
1930 else
1931 {
1932 /* lhs > -infinity, rhs < infinity -> equality */
1933 assert(SCIPrationalIsEQ(lhs, rhs));
1934 if( !SCIPrationalIsNegative(val) )
1935 {
1936 SCIPrationalAdd(val, val, rhs);
1937 SCIP_CALL( SCIPchgRhsExactLinear(scip, cons, val) );
1938 }
1939 else
1940 {
1941 SCIPrationalAdd(val, val, lhs);
1942 SCIP_CALL( SCIPchgLhsExactLinear(scip, cons, val) );
1943 }
1944 }
1945 }
1946 }
1947 }
1948 }
1949 mpsinputSyntaxerror(mpsi);
1950
1951 return SCIP_OKAY;
1952}
1953
1954/** Process BOUNDS section. */
1955static
1957 MPSINPUT* mpsi, /**< mps input structure */
1958 SCIP* scip /**< SCIP data structure */
1959 )
1960{
1961 char bndname[MPS_MAX_NAMELEN] = { '\0' };
1962 SCIP_VAR* var;
1963 SCIP_RETCODE retcode;
1964 SCIP_Real val;
1965 SCIP_Bool shifted;
1966
1967 SCIP_VAR** semicont;
1968 int nsemicont;
1969 int semicontsize;
1970
1971 retcode = SCIP_OKAY;
1972
1973 semicont = NULL;
1974 nsemicont = 0;
1975 semicontsize = 0;
1976
1977 SCIPdebugMsg(scip, "read bounds\n");
1978
1979 while( mpsinputReadLine(mpsi) )
1980 {
1981 if( mpsinputField0(mpsi) != 0 )
1982 {
1983 if( !strcmp(mpsinputField0(mpsi), "SOS") )
1985 else if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
1987 else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
1989 else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
1991 else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
1993 else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
1995 else
1996 break;
1997 goto READBOUNDS_FINISH;
1998 }
1999
2000 shifted = FALSE;
2001
2002 /* Is the value field used ? */
2003 if( !strcmp(mpsinputField1(mpsi), "LO") /* lower bound given in field 4 */
2004 || !strcmp(mpsinputField1(mpsi), "UP") /* upper bound given in field 4 */
2005 || !strcmp(mpsinputField1(mpsi), "FX") /* fixed value given in field 4 */
2006 || !strcmp(mpsinputField1(mpsi), "LI") /* CPLEX extension: lower bound of integer variable given in field 4 */
2007 || !strcmp(mpsinputField1(mpsi), "UI") /* CPLEX extension: upper bound of integer variable given in field 4 */
2008 || !strcmp(mpsinputField1(mpsi), "SC") /* CPLEX extension: semi-continuous variable, upper bound given in field 4 */
2009 || !strcmp(mpsinputField1(mpsi), "SI") )/* CPLEX extension: semi-integer variable, upper bound given in field 4 */
2010 {
2011 if( mpsinputField3(mpsi) != NULL && mpsinputField4(mpsi) == NULL )
2012 {
2013 int l;
2014
2015 /* check what might be missing, if field 3 is a number the bound name might be missing */
2016 for( l = (int) strlen(mpsinputField3(mpsi)) - 1; l >= 0; --l )
2017 {
2018 if( mpsinputField3(mpsi)[l] != '.' && !isdigit((unsigned char)mpsinputField3(mpsi)[l]) )
2019 break;
2020 }
2021
2022 /* the bound name?! is missing */
2023 if( l < 0 )
2024 {
2025 SCIPwarningMessage(scip, "in bound section a name for value <%s> might be missing\n", mpsinputField3(mpsi));
2026
2027 mpsinputInsertName(mpsi, "_BND_", TRUE);
2028 shifted = TRUE;
2029 }
2030 /* the bound is be missing */
2031 else
2032 {
2033 SCIPwarningMessage(scip, "in bound section a value for column <%s> is missing, assuming 0.0\n", mpsinputField3(mpsi));
2034
2035 mpsinputInsertField4(mpsi, "0.0");
2036 shifted = TRUE;
2037 }
2038 }
2039 }
2040 else if( !strcmp(mpsinputField1(mpsi), "FR") /* free variable */
2041 || !strcmp(mpsinputField1(mpsi), "MI") /* lower bound is minus infinity */
2042 || !strcmp(mpsinputField1(mpsi), "PL") /* upper bound is plus infinity */
2043 || !strcmp(mpsinputField1(mpsi), "BV") ) /* CPLEX extension: binary variable */
2044 {
2045 if( mpsinputField2(mpsi) != NULL && mpsinputField3(mpsi) == NULL )
2046 {
2047 SCIPwarningMessage(scip, "in bound section a name for a column is missing\n");
2048
2049 mpsinputInsertName(mpsi, "_BND_", TRUE);
2050 shifted = TRUE;
2051 }
2052 }
2053 else
2054 {
2055 mpsinputSyntaxerror(mpsi);
2056 return SCIP_OKAY;
2057 }
2058
2059 if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL || mpsinputField3(mpsi) == NULL )
2060 break;
2061
2062 if( *bndname == '\0' )
2063 (void)SCIPmemccpy(bndname, mpsinputField2(mpsi), '\0', MPS_MAX_NAMELEN - 1);
2064
2065 /* Only read the first Bound in section */
2066 if( !strcmp(bndname, mpsinputField2(mpsi)) )
2067 {
2068 SCIP_VARTYPE oldvartype;
2069 SCIP_Bool infeasible;
2070
2071 var = SCIPfindVar(scip, mpsinputField3(mpsi));
2072 /* if variable did not appear in columns section before, then it may still come in later sections (QCMATRIX, QMATRIX, SOS, ...)
2073 * thus add it as continuous variables, which has default bounds 0.0 <= x, and default cost 0.0 */
2074 if( var == NULL )
2075 {
2076 SCIP_VAR* varcpy;
2077
2078 SCIP_CALL( SCIPcreateVar(scip, &var, mpsinputField3(mpsi), 0.0, SCIPinfinity(scip), 0.0,
2079 SCIP_VARTYPE_CONTINUOUS, !mpsi->dynamiccols, mpsi->dynamiccols, NULL, NULL, NULL, NULL, NULL) );
2080
2081 SCIP_CALL( SCIPaddVar(scip, var) );
2082 varcpy = var;
2083 SCIP_CALL( SCIPreleaseVar(scip, &varcpy) );
2084 /* mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField3(mpsi), "bound", bndname, SCIP_VERBLEVEL_NORMAL); */
2085 }
2086 assert(var != NULL);
2087
2088 if( mpsinputField4(mpsi) == NULL )
2089 val = 0.0;
2090 else
2091 val = atof(mpsinputField4(mpsi));
2092
2093 /* remember variable type */
2094 oldvartype = SCIPvarGetType(var);
2095 assert(!SCIPvarIsImpliedIntegral(var));
2096
2097 /* convert into an integer variable with default bounds 0 <= x <= infinity if binary variable is not declared
2098 * binary and not equipped with binary bounds, note that the default integer type is binary
2099 */
2100 if( oldvartype == SCIP_VARTYPE_BINARY
2101 && ( mpsinputField1(mpsi)[0] != 'B' || mpsinputField1(mpsi)[1] != 'V' )
2102 && ( mpsinputField1(mpsi)[0] != 'U' || SCIPisFeasGT(scip, val, 1.0) )
2103 && ( mpsinputField1(mpsi)[0] != 'F' || mpsinputField1(mpsi)[1] != 'X'
2104 || SCIPisFeasNegative(scip, val) || SCIPisFeasGT(scip, val, 1.0) ) )
2105 {
2106 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
2107 assert(!infeasible);
2108
2109 oldvartype = SCIP_VARTYPE_INTEGER;
2111 }
2112
2113 /* switch variable type to continuous before applying the bound, this is necessary for stupid non-integral
2114 * bounds on general variables, which even might lead to infeasibility
2115 */
2116 if( oldvartype != SCIP_VARTYPE_CONTINUOUS )
2117 {
2118 /* relaxing variable type */
2120 }
2122
2123 switch( mpsinputField1(mpsi)[0] )
2124 {
2125 case 'L':
2127 {
2128 SCIPwarningMessage(scip, "Relaxing already defined lower bound %g of variable <%s> to %g not allowed.\n", SCIPvarGetLbGlobal(var), SCIPvarGetName(var), val);
2129 }
2130
2131 SCIP_CALL( SCIPchgVarLb(scip, var, val) );
2132
2133 if( mpsinputField1(mpsi)[1] == 'I' ) /* CPLEX extension (Integer Bound) */
2134 {
2135 if( !SCIPisFeasIntegral(scip, val) )
2136 {
2137 SCIPwarningMessage(scip, "variable <%s> declared as integral has a non-integral lower bound (%.14g) -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), val);
2138 }
2139 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
2140 /* don't assert feasibility here because the presolver will and should detect a infeasibility */
2141 }
2142 else if( oldvartype < SCIP_VARTYPE_CONTINUOUS )
2143 {
2144 if( !SCIPisFeasIntegral(scip, val) )
2145 {
2146 SCIPwarningMessage(scip, "variable <%s> declared as integral has a non-integral lower bound (%.14g) -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), val);
2147 }
2148 }
2149
2150 break;
2151 case 'U':
2152 if( SCIPisGT(scip, val, SCIPvarGetUbGlobal(var)) )
2153 {
2154 SCIPwarningMessage(scip, "Relaxing already defined upper bound %g of variable <%s> to %g not allowed.\n", SCIPvarGetUbGlobal(var), SCIPvarGetName(var), val);
2155 }
2156
2157 SCIP_CALL( SCIPchgVarUb(scip, var, val) );
2158 if( mpsinputField1(mpsi)[1] == 'I' ) /* CPLEX extension (Integer Bound) */
2159 {
2160 if( !SCIPisFeasIntegral(scip, val) )
2161 {
2162 SCIPwarningMessage(scip, "variable <%s> declared as integral has a non-integral upper bound (%.14g) -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), val);
2163 }
2164
2165 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
2166 /* don't assert feasibility here because the presolver will and should detect an infeasibility */
2167 }
2168 else if( oldvartype < SCIP_VARTYPE_CONTINUOUS )
2169 {
2170 if( !SCIPisFeasIntegral(scip, val) )
2171 {
2172 SCIPwarningMessage(scip, "variable <%s> declared as integral has a non-integral upper bound (%.14g) -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), val);
2173 }
2174 }
2175 break;
2176 case 'S':
2177 assert(mpsinputField1(mpsi)[1] == 'C' || mpsinputField1(mpsi)[1] == 'I'); /* semi-continuous or semi-integer (CPLEX extension) */
2178 /* remember that variable is semi-continuous/-integer */
2179 if( semicontsize <= nsemicont )
2180 {
2181 semicontsize = SCIPcalcMemGrowSize(scip, nsemicont+1);
2182 if( semicont == NULL )
2183 {
2184 SCIP_CALL( SCIPallocBufferArray(scip, &semicont, semicontsize) );
2185 }
2186 else
2187 {
2188 SCIP_CALL( SCIPreallocBufferArray(scip, &semicont, semicontsize) );
2189 }
2190 }
2191 assert(semicont != NULL);
2192 semicont[nsemicont] = var;
2193 ++nsemicont;
2194
2195 if( mpsinputField1(mpsi)[1] == 'I' ) /* variable is semi-integer, hence change its type to integer (the "semi" part will be handled below) */
2196 {
2197 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
2198 /* don't assert feasibility here because the presolver will and should detect an infeasibility */
2199 }
2200
2201 /* if both bounds are infinite anyway, we do not need to print a warning or change the bound */
2203 {
2204 if( SCIPisGT(scip, val, SCIPvarGetUbGlobal(var)) )
2205 {
2206 SCIPwarningMessage(scip, "Relaxing already defined upper bound %g of variable <%s> to %g not allowed.\n", SCIPvarGetUbGlobal(var), SCIPvarGetName(var), val);
2207 }
2208
2209 SCIP_CALL( SCIPchgVarUb(scip, var, val) );
2210 }
2211 break;
2212 case 'F':
2213 if( mpsinputField1(mpsi)[1] == 'X' )
2214 {
2215 SCIP_CALL( SCIPchgVarLb(scip, var, val) );
2216 SCIP_CALL( SCIPchgVarUb(scip, var, val) );
2217 }
2218 else
2219 {
2222 }
2223 break;
2224 case 'M':
2226 break;
2227 case 'P':
2229 break;
2230 case 'B':
2231 if( oldvartype != SCIP_VARTYPE_BINARY )
2232 {
2233 SCIP_CALL( SCIPtightenVarLb(scip, var, 0.0, TRUE, &infeasible, NULL) );
2234 SCIP_CALL( SCIPtightenVarUb(scip, var, 1.0, TRUE, &infeasible, NULL) );
2235 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
2236 /* presolving detects infeasibility */
2237 }
2238 break;
2239 default:
2240 mpsinputSyntaxerror(mpsi);
2241 return SCIP_OKAY;
2242 }
2243
2244 /* switch variable type back to old type if necessary */
2245 if( oldvartype < SCIPvarGetType(var) )
2246 {
2247 SCIP_CALL( SCIPchgVarType(scip, var, oldvartype, &infeasible) );
2248 }
2249 }
2250 else
2251 {
2252 /* check for syntax error */
2253 assert(*bndname != '\0');
2254 if( strcmp(bndname, mpsinputField3(mpsi)) == 0 && shifted )
2255 {
2256 mpsinputSyntaxerror(mpsi);
2257 return SCIP_OKAY;
2258 }
2259
2260 mpsinputEntryIgnored(scip, mpsi, "bound", mpsinputField2(mpsi), "variable", mpsinputField3(mpsi), SCIP_VERBLEVEL_NORMAL);
2261 }
2262 }
2263 mpsinputSyntaxerror(mpsi);
2264
2265 READBOUNDS_FINISH:
2266 if( nsemicont > 0 )
2267 {
2268 SCIP_CONS* cons;
2269 SCIP_VAR* vars[2];
2270 SCIP_BOUNDTYPE boundtypes[2];
2271 SCIP_Real bounds[2];
2272 char name[SCIP_MAXSTRLEN];
2273 SCIP_Real oldlb;
2274 int i;
2275
2276 assert(semicont != NULL);
2277
2278 /* add bound disjunction constraints for semi-continuous and semi-integer variables */
2279 for( i = 0; i < nsemicont; ++i )
2280 {
2281 var = semicont[i];
2283
2284 oldlb = SCIPvarGetLbGlobal(var);
2285 assert(oldlb >= 0.0);
2286
2287 /* if no bound was specified (which we assume if we see lower bound 0.0),
2288 * then the default lower bound for a semi-continuous variable is 1.0 */
2289 if( oldlb == 0.0 )
2290 oldlb = 1.0;
2291
2292 /* change the lower bound to 0.0 */
2293 SCIP_CALL( SCIPchgVarLb(scip, var, 0.0) );
2294
2295 /* add a bound disjunction constraint to say var <= 0.0 or var >= oldlb */
2296 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "semicont_%s", SCIPvarGetName(var));
2297
2298 vars[0] = var;
2299 vars[1] = var;
2300 boundtypes[0] = SCIP_BOUNDTYPE_UPPER;
2301 boundtypes[1] = SCIP_BOUNDTYPE_LOWER;
2302 bounds[0] = 0.0;
2303 bounds[1] = oldlb;
2304
2305 retcode = SCIPcreateConsBounddisjunction(scip, &cons, name, 2, vars, boundtypes, bounds,
2306 !mpsi->dynamiccols, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, mpsi->dynamicconss, mpsi->dynamiccols, FALSE);
2307
2308 if( retcode != SCIP_OKAY )
2309 break;
2310
2311 SCIP_CALL( SCIPaddCons(scip, cons) );
2312
2313 SCIPdebugMsg(scip, "add bound disjunction constraint for semi-continuity/-integrality of <%s>:\n\t", SCIPvarGetName(var));
2315
2316 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
2317 }
2318 }
2319
2320 SCIPfreeBufferArrayNull(scip, &semicont);
2321
2322 SCIP_CALL( retcode );
2323
2324 return SCIP_OKAY;
2325}
2326
2327/** Process BOUNDS section. */
2328static
2330 MPSINPUT* mpsi, /**< mps input structure */
2331 SCIP* scip /**< SCIP data structure */
2332 )
2333{
2334 char bndname[MPS_MAX_NAMELEN] = { '\0' };
2335 SCIP_VAR* var;
2336 SCIP_RETCODE retcode;
2337 SCIP_RATIONAL* val;
2338 SCIP_Bool shifted;
2339
2340 SCIP_VAR** semicont;
2341 int nsemicont;
2342 int semicontsize;
2343
2344 retcode = SCIP_OKAY;
2345
2346 semicont = NULL;
2347 nsemicont = 0;
2348 semicontsize = 0;
2349
2351
2352 SCIPdebugMsg(scip, "read bounds\n");
2353
2354 while( mpsinputReadLine(mpsi) )
2355 {
2356 if( mpsinputField0(mpsi) != 0 )
2357 {
2358 if( !strcmp(mpsinputField0(mpsi), "SOS") )
2360 else if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
2362 else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
2364 else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
2366 else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
2368 else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
2370 else
2371 break;
2372 goto READBOUNDS_FINISH;
2373 }
2374
2375 shifted = FALSE;
2376
2377 /* Is the value field used ? */
2378 if( !strcmp(mpsinputField1(mpsi), "LO") /* lower bound given in field 4 */
2379 || !strcmp(mpsinputField1(mpsi), "UP") /* upper bound given in field 4 */
2380 || !strcmp(mpsinputField1(mpsi), "FX") /* fixed value given in field 4 */
2381 || !strcmp(mpsinputField1(mpsi), "LI") /* CPLEX extension: lower bound of integer variable given in field 4 */
2382 || !strcmp(mpsinputField1(mpsi), "UI") /* CPLEX extension: upper bound of integer variable given in field 4 */
2383 || !strcmp(mpsinputField1(mpsi), "SC") /* CPLEX extension: semi-continuous variable, upper bound given in field 4 */
2384 || !strcmp(mpsinputField1(mpsi), "SI") )/* CPLEX extension: semi-integer variable, upper bound given in field 4 */
2385 {
2386 if( mpsinputField3(mpsi) != NULL && mpsinputField4(mpsi) == NULL )
2387 {
2388 int l;
2389
2390 /* check what might be missing, if field 3 is a number the bound name might be missing */
2391 for( l = (int) strlen(mpsinputField3(mpsi)) - 1; l >= 0; --l )
2392 {
2393 if( mpsinputField3(mpsi)[l] != '.' && !isdigit((unsigned char)mpsinputField3(mpsi)[l]) )
2394 break;
2395 }
2396
2397 /* the bound name?! is missing */
2398 if( l < 0 )
2399 {
2400 SCIPwarningMessage(scip, "in bound section a name for value <%s> might be missing\n", mpsinputField3(mpsi));
2401
2402 mpsinputInsertName(mpsi, "_BND_", TRUE);
2403 shifted = TRUE;
2404 }
2405 /* the bound is be missing */
2406 else
2407 {
2408 SCIPwarningMessage(scip, "in bound section a value for column <%s> is missing, assuming 0.0\n", mpsinputField3(mpsi));
2409
2410 mpsinputInsertField4(mpsi, "0.0");
2411 shifted = TRUE;
2412 }
2413 }
2414 }
2415 else if( !strcmp(mpsinputField1(mpsi), "FR") /* free variable */
2416 || !strcmp(mpsinputField1(mpsi), "MI") /* lower bound is minus infinity */
2417 || !strcmp(mpsinputField1(mpsi), "PL") /* upper bound is plus infinity */
2418 || !strcmp(mpsinputField1(mpsi), "BV") ) /* CPLEX extension: binary variable */
2419 {
2420 if( mpsinputField2(mpsi) != NULL && mpsinputField3(mpsi) == NULL )
2421 {
2422 SCIPwarningMessage(scip, "in bound section a name for a column is missing\n");
2423
2424 mpsinputInsertName(mpsi, "_BND_", TRUE);
2425 shifted = TRUE;
2426 }
2427 }
2428 else
2429 {
2430 mpsinputSyntaxerror(mpsi);
2431 return SCIP_OKAY;
2432 }
2433
2434 if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL || mpsinputField3(mpsi) == NULL )
2435 break;
2436
2437 if( *bndname == '\0' )
2438 (void)SCIPmemccpy(bndname, mpsinputField2(mpsi), '\0', MPS_MAX_NAMELEN - 1);
2439
2440 /* Only read the first Bound in section */
2441 if( !strcmp(bndname, mpsinputField2(mpsi)) )
2442 {
2443 SCIP_VARTYPE oldvartype;
2444 SCIP_Bool infeasible;
2445
2446 var = SCIPfindVar(scip, mpsinputField3(mpsi));
2447 /* if variable did not appear in columns section before, then it may still come in later sections (QCMATRIX, QMATRIX, SOS, ...)
2448 * thus add it as continuous variables, which has default bounds 0.0 <= x, and default cost 0.0 */
2449 if( var == NULL )
2450 {
2451 SCIP_VAR* varcpy;
2452
2453 SCIP_CALL( SCIPcreateVar(scip, &var, mpsinputField3(mpsi), 0.0, SCIPinfinity(scip), 0.0,
2454 SCIP_VARTYPE_CONTINUOUS, !mpsi->dynamiccols, mpsi->dynamiccols, NULL, NULL, NULL, NULL, NULL) );
2455
2457
2458 SCIP_CALL( SCIPaddVar(scip, var) );
2459 varcpy = var;
2460 SCIP_CALL( SCIPreleaseVar(scip, &varcpy) );
2461 /* mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField3(mpsi), "bound", bndname, SCIP_VERBLEVEL_NORMAL); */
2462 }
2463 assert(var != NULL);
2464
2465 if( mpsinputField4(mpsi) == NULL )
2466 SCIPrationalSetReal(val, 0.0);
2467 else
2468 {
2471 }
2472
2473 /* remember variable type */
2474 oldvartype = SCIPvarGetType(var);
2475 assert(!SCIPvarIsImpliedIntegral(var));
2476
2477 /* convert into an integer variable with default bounds 0 <= x <= infinity if binary variable is not declared
2478 * binary and not equipped with binary bounds, note that the default integer type is binary
2479 */
2480 if( oldvartype == SCIP_VARTYPE_BINARY
2481 && ( mpsinputField1(mpsi)[0] != 'B' || mpsinputField1(mpsi)[1] != 'V' )
2482 && ( mpsinputField1(mpsi)[0] != 'U' || SCIPrationalIsGTReal(val, 1.0) )
2483 && ( mpsinputField1(mpsi)[0] != 'F' || mpsinputField1(mpsi)[1] != 'X'
2484 || SCIPrationalIsNegative(val) || SCIPrationalIsGTReal(val, 1.0) ) )
2485 {
2486 SCIP_RATIONAL* tmp;
2487 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
2488 assert(!infeasible);
2489
2492
2493 oldvartype = SCIP_VARTYPE_INTEGER;
2494
2495 SCIP_CALL( SCIPchgVarUbExact(scip, var, tmp) );
2497 }
2498
2499 /* switch variable type to continuous before applying the bound, this is necessary for stupid non-integral
2500 * bounds on general variables, which even might lead to infeasibility
2501 */
2502 if( oldvartype != SCIP_VARTYPE_CONTINUOUS )
2503 {
2504 /* relaxing variable type */
2506 }
2508
2509 switch( mpsinputField1(mpsi)[0] )
2510 {
2511 case 'L':
2513 {
2514 SCIPwarningMessage(scip, "Relaxing already defined lower bound (%.14g) of variable <%s> to (%.14g) not allowed.\n", SCIPvarGetLbGlobal(var), SCIPvarGetName(var), SCIPrationalGetReal(val));
2515 }
2516
2517 SCIP_CALL( SCIPchgVarLbExact(scip, var, val) );
2518
2519 if( mpsinputField1(mpsi)[1] == 'I' ) /* CPLEX extension (Integer Bound) */
2520 {
2521 if( !SCIPrationalIsIntegral(val) )
2522 {
2523 SCIPwarningMessage(scip, "variable <%s> declared as integral has a non-integral lower bound (%.14g) -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), SCIPrationalGetReal(val));
2524 }
2525 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
2526 /* don't assert feasibility here because the presolver will and should detect a infeasibility */
2527 }
2528 else if( oldvartype < SCIP_VARTYPE_CONTINUOUS )
2529 {
2530 if( !SCIPrationalIsIntegral(val) )
2531 {
2532 SCIPwarningMessage(scip, "variable <%s> declared as integral has a non-integral lower bound (%.14g) -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), SCIPrationalGetReal(val));
2533 }
2534 }
2535
2536 break;
2537 case 'U':
2539 {
2540 SCIPwarningMessage(scip, "Relaxing already defined upper bound %g of variable <%s> to %g not allowed.\n", SCIPvarGetUbGlobal(var), SCIPvarGetName(var), SCIPrationalGetReal(val));
2541 }
2542
2543 SCIP_CALL( SCIPchgVarUbExact(scip, var, val) );
2544 if( mpsinputField1(mpsi)[1] == 'I' ) /* CPLEX extension (Integer Bound) */
2545 {
2546 if( !SCIPrationalIsIntegral(val) )
2547 {
2548 SCIPwarningMessage(scip, "variable <%s> declared as integral has a non-integral upper bound (%.14g) -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), SCIPrationalGetReal(val));
2549 }
2550
2551 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
2552 /* don't assert feasibility here because the presolver will and should detect an infeasibility */
2553 }
2554 else if( oldvartype < SCIP_VARTYPE_CONTINUOUS )
2555 {
2556 if( !SCIPrationalIsIntegral(val) )
2557 {
2558 SCIPwarningMessage(scip, "variable <%s> declared as integral has a non-integral upper bound (%.14g) -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), SCIPrationalGetReal(val));
2559 }
2560 }
2561 break;
2562 case 'S':
2563 assert(mpsinputField1(mpsi)[1] == 'C' || mpsinputField1(mpsi)[1] == 'I'); /* semi-continuous or semi-integer (CPLEX extension) */
2564 /* remember that variable is semi-continuous/-integer */
2565 if( semicontsize <= nsemicont )
2566 {
2567 semicontsize = SCIPcalcMemGrowSize(scip, nsemicont+1);
2568 if( semicont == NULL )
2569 {
2570 SCIP_CALL( SCIPallocBufferArray(scip, &semicont, semicontsize) );
2571 }
2572 else
2573 {
2574 SCIP_CALL( SCIPreallocBufferArray(scip, &semicont, semicontsize) );
2575 }
2576 }
2577 assert(semicont != NULL);
2578 semicont[nsemicont] = var;
2579 ++nsemicont;
2580
2581 if( mpsinputField1(mpsi)[1] == 'I' ) /* variable is semi-integer, hence change its type to integer (the "semi" part will be handled below) */
2582 {
2583 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
2584 /* don't assert feasibility here because the presolver will and should detect an infeasibility */
2585 }
2586
2587 /* if both bounds are infinite anyway, we do not need to print a warning or change the bound */
2589 {
2591 {
2592 SCIPwarningMessage(scip, "Relaxing already defined upper bound %g of variable <%s> to %g not allowed.\n", SCIPvarGetUbGlobal(var), SCIPvarGetName(var), SCIPrationalGetReal(val));
2593 }
2594
2595 SCIP_CALL( SCIPchgVarUbExact(scip, var, val) );
2596 }
2597 break;
2598 case 'F':
2599 if( mpsinputField1(mpsi)[1] == 'X' )
2600 {
2601 SCIP_CALL( SCIPchgVarLbExact(scip, var, val) );
2602 SCIP_CALL( SCIPchgVarUbExact(scip, var, val) );
2603 }
2604 else
2605 {
2607 SCIP_CALL( SCIPchgVarLbExact(scip, var, val) );
2609 SCIP_CALL( SCIPchgVarUbExact(scip, var, val) );
2610 }
2611 break;
2612 case 'M':
2614 SCIP_CALL( SCIPchgVarLbExact(scip, var, val) );
2615 break;
2616 case 'P':
2618 SCIP_CALL( SCIPchgVarUbExact(scip, var, val) );
2619 break;
2620 case 'B':
2621 if( oldvartype != SCIP_VARTYPE_BINARY )
2622 {
2623 SCIPrationalSetReal(val, 0.0);
2624 SCIP_CALL( SCIPtightenVarLbExact(scip, var, val, &infeasible, NULL) );
2625 SCIPrationalSetReal(val, 1.0);
2626 SCIP_CALL( SCIPtightenVarUbExact(scip, var, val, &infeasible, NULL) );
2627 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
2628 /* presolving detects infeasibility */
2629 }
2630 break;
2631 default:
2632 mpsinputSyntaxerror(mpsi);
2633 return SCIP_OKAY;
2634 }
2635
2636 /* switch variable type back to old type if necessary */
2637 if( oldvartype < SCIPvarGetType(var) )
2638 {
2639 SCIP_CALL( SCIPchgVarType(scip, var, oldvartype, &infeasible) );
2640 }
2641 }
2642 else
2643 {
2644 /* check for syntax error */
2645 assert(*bndname != '\0');
2646 if( strcmp(bndname, mpsinputField3(mpsi)) == 0 && shifted )
2647 {
2648 mpsinputSyntaxerror(mpsi);
2649 return SCIP_OKAY;
2650 }
2651
2652 mpsinputEntryIgnored(scip, mpsi, "bound", mpsinputField2(mpsi), "variable", mpsinputField3(mpsi), SCIP_VERBLEVEL_NORMAL);
2653 }
2654 }
2655 mpsinputSyntaxerror(mpsi);
2656
2657 READBOUNDS_FINISH:
2658 if( nsemicont > 0 )
2659 {
2660 SCIPerrorMessage("Exact solving mode cannot handle semicontinous variables at the moment \n");
2661 SCIPABORT();
2662 }
2663
2664 SCIPfreeBufferArrayNull(scip, &semicont);
2666
2667 SCIP_CALL( retcode );
2668
2669 return SCIP_OKAY;
2670}
2671
2672
2673/** Process SOS section.
2674 *
2675 * We read the SOS section, which is a nonstandard section introduced by CPLEX.
2676 *
2677 * @note Currently we do not support the standard way of specifying SOS constraints via markers.
2678 */
2679static
2681 MPSINPUT* mpsi, /**< mps input structure */
2682 SCIP* scip /**< SCIP data structure */
2683 )
2684{
2685 SCIP_Bool initial;
2687 SCIP_Bool enforce;
2688 SCIP_Bool check;
2689 SCIP_Bool propagate;
2690 SCIP_Bool local;
2691 SCIP_Bool dynamic;
2692 SCIP_Bool removable;
2693 char name[MPS_MAX_NAMELEN] = { '\0' };
2694 SCIP_CONS* cons = NULL;
2695 int consType = -1;
2696 int cnt = 0;
2697
2698 SCIPdebugMsg(scip, "read SOS constraints\n");
2699
2700 /* standard settings for SOS constraints: */
2701 initial = mpsi->initialconss;
2702 separate = TRUE;
2703 enforce = TRUE;
2704 check = TRUE;
2705 propagate = TRUE;
2706 local = FALSE;
2707 dynamic = mpsi->dynamicconss;
2708 removable = mpsi->dynamicrows;
2709
2710 if( SCIPisExact(scip) )
2711 {
2712 SCIPerrorMessage("Exact solving mode cannot handle SOS constraints currently \n");
2713 return SCIP_READERROR;
2714 }
2715
2716 /* loop through section */
2717 while( mpsinputReadLine(mpsi) )
2718 {
2719 int type = -1;
2720
2721 /* check if next section is found */
2722 if( mpsinputField0(mpsi) != NULL )
2723 {
2724 if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
2726 else if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
2728 else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
2730 else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
2732 else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
2734 break;
2735 }
2736 if( mpsinputField1(mpsi) == NULL )
2737 {
2738 SCIPerrorMessage("empty data in a non-comment line.\n");
2739 mpsinputSyntaxerror(mpsi);
2740 return SCIP_OKAY;
2741 }
2742
2743 /* check for new SOS set */
2744 if( strcmp(mpsinputField1(mpsi), "S1") == 0 )
2745 type = 1;
2746 if( strcmp(mpsinputField1(mpsi), "S2") == 0 )
2747 type = 2;
2748
2749 /* add last constraint and create a new one */
2750 if( type > 0 )
2751 {
2752 assert( type == 1 || type == 2 );
2753 if( cons != NULL )
2754 {
2755 /* add last constraint */
2756 SCIP_CALL( SCIPaddCons(scip, cons) );
2757 SCIPdebugMsg(scip, "(line %d) added constraint <%s>: ", mpsi->lineno, SCIPconsGetName(cons));
2759 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
2760 }
2761
2762 /* check name */
2763 if( mpsinputField2(mpsi) != NULL )
2764 (void)SCIPmemccpy(name, mpsinputField2(mpsi), '\0', MPS_MAX_NAMELEN - 1);
2765 else
2766 {
2767 /* create new name */
2768 (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "SOS%d", ++cnt);
2769 }
2770
2771 /* create new SOS constraint */
2772 if( type == 1 )
2773 {
2774 /* we do not know the name of the constraint */
2775 SCIP_CALL( SCIPcreateConsSOS1(scip, &cons, name, 0, NULL, NULL, initial, separate, enforce, check, propagate,
2776 local, dynamic, removable, FALSE) );
2777 }
2778 else
2779 {
2780 assert( type == 2 );
2781 SCIP_CALL( SCIPcreateConsSOS2(scip, &cons, name, 0, NULL, NULL, initial, separate, enforce, check, propagate,
2782 local, dynamic, removable, FALSE) );
2783 }
2784 consType = type;
2785 SCIPdebugMsg(scip, "created constraint <%s> of type %d.\n", name, type);
2786 /* note: we ignore the priorities! */
2787 }
2788 else
2789 {
2790 /* otherwise we are in the section given variables */
2791 SCIP_VAR* var;
2792 SCIP_Real weight;
2793 char* endptr;
2794
2795 if( consType != 1 && consType != 2 )
2796 {
2797 SCIPerrorMessage("missing SOS type specification.\n");
2798 mpsinputSyntaxerror(mpsi);
2799 return SCIP_OKAY;
2800 }
2801
2802 /* get variable */
2803 var = SCIPfindVar(scip, mpsinputField1(mpsi));
2804 if( var == NULL )
2805 {
2806 /* ignore unknown variables - we would not know the type anyway */
2807 mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField1(mpsi), "SOS", name, SCIP_VERBLEVEL_NORMAL);
2808 }
2809 else
2810 {
2811 /* get weight */
2812 if( NULL == mpsinputField2(mpsi) )
2813 {
2814 SCIPerrorMessage("weight for variable <%s> not specified.\n", mpsinputField1(mpsi));
2815 mpsinputSyntaxerror(mpsi);
2816 return SCIP_OKAY;
2817 }
2818
2819 weight = strtod(mpsinputField2(mpsi), &endptr);
2820 if( endptr == mpsinputField2(mpsi) || *endptr != '\0' )
2821 {
2822 SCIPerrorMessage("weight for variable <%s> not specified.\n", mpsinputField1(mpsi));
2823 mpsinputSyntaxerror(mpsi);
2824 return SCIP_OKAY;
2825 }
2826
2827 /* add variable and weight */
2828 assert( consType == 1 || consType == 2 );
2829 switch( consType )
2830 {
2831 case 1:
2832 SCIP_CALL( SCIPaddVarSOS1(scip, cons, var, weight) );
2833 break;
2834 case 2:
2835 SCIP_CALL( SCIPaddVarSOS2(scip, cons, var, weight) );
2836 break;
2837 /* coverity[dead_error_begin] */
2838 default:
2839 SCIPerrorMessage("unknown SOS type: <%d>\n", type); /* should not happen */
2840 SCIPABORT();
2841 return SCIP_INVALIDDATA; /*lint !e527*/
2842 }
2843 SCIPdebugMsg(scip, "added variable <%s> with weight %g.\n", SCIPvarGetName(var), weight);
2844 }
2845 /* check other fields */
2846 if( (mpsinputField3(mpsi) != NULL && *mpsinputField3(mpsi) != '\0' ) ||
2847 (mpsinputField4(mpsi) != NULL && *mpsinputField4(mpsi) != '\0' ) ||
2848 (mpsinputField5(mpsi) != NULL && *mpsinputField5(mpsi) != '\0' ) )
2849 {
2850 SCIPwarningMessage(scip, "ignoring data in fields 3-5 <%s> <%s> <%s>.\n",
2851 mpsinputField3(mpsi), mpsinputField4(mpsi), mpsinputField5(mpsi));
2852 }
2853 }
2854 }
2855
2856 if( cons != NULL )
2857 {
2858 /* add last constraint */
2859 SCIP_CALL( SCIPaddCons(scip, cons) );
2860 SCIPdebugMsg(scip, "(line %d) added constraint <%s>: ", mpsi->lineno, SCIPconsGetName(cons));
2862 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
2863 }
2864
2865 return SCIP_OKAY;
2866}
2867
2868
2869/** Process QMATRIX or QUADOBJ section.
2870 *
2871 * - We read the QMATRIX or QUADOBJ section, which is a nonstandard section introduced by CPLEX.
2872 * - We create a quadratic constraint for this matrix and add a variable to the objective to
2873 * represent the value of the QMATRIX.
2874 * - For a QMATRIX, we expect that both lower and upper diagonal elements are given and every
2875 * coefficient has to be divided by 2.0.
2876 * - For a QUADOBJ, we expect that only the upper diagonal elements are given and thus only
2877 * coefficients on the diagonal have to be divided by 2.0.
2878 */
2879static
2881 MPSINPUT* mpsi, /**< mps input structure */
2882 SCIP_Bool isQuadObj, /**< whether we actually read a QUADOBJ section */
2883 SCIP* scip /**< SCIP data structure */
2884 )
2885{
2886 SCIP_VAR** quadvars1;
2887 SCIP_VAR** quadvars2;
2888 SCIP_Real* quadcoefs;
2889 SCIP_RETCODE retcode;
2890 int cnt = 0; /* number of qmatrix elements processed so far */
2891 int size; /* size of quad* arrays */
2892
2893 SCIPdebugMsg(scip, "read %s objective\n", isQuadObj ? "QUADOBJ" : "QMATRIX");
2894
2895 if( SCIPisExact(scip) )
2896 {
2897 SCIPerrorMessage("Exact solving mode cannot handle QMatrix constraints currently \n");
2898 return SCIP_READERROR;
2899 }
2900
2901 retcode = SCIP_OKAY;
2902
2903 size = 1;
2904 SCIP_CALL( SCIPallocBufferArray(scip, &quadvars1, size) );
2905 SCIP_CALL( SCIPallocBufferArray(scip, &quadvars2, size) );
2906 SCIP_CALL( SCIPallocBufferArray(scip, &quadcoefs, size) );
2907
2908 /* loop through section */
2909 /* coverity[tainted_data] */
2910 while( mpsinputReadLine(mpsi) )
2911 {
2912 /* otherwise we are in the section given variables */
2913 SCIP_VAR* var1;
2914 SCIP_VAR* var2;
2915 SCIP_Real coef;
2916
2917 /* check if next section is found */
2918 if( mpsinputField0(mpsi) != NULL )
2919 {
2920 if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
2922 else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
2924 else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
2926 break;
2927 }
2928 if( mpsinputField1(mpsi) == NULL && mpsinputField2(mpsi) == NULL )
2929 {
2930 SCIPerrorMessage("empty data in a non-comment line.\n");
2931 mpsinputSyntaxerror(mpsi);
2932 SCIPfreeBufferArray(scip, &quadvars1);
2933 SCIPfreeBufferArray(scip, &quadvars2);
2934 SCIPfreeBufferArray(scip, &quadcoefs);
2935 return SCIP_OKAY;
2936 }
2937
2938 /* get first variable */
2939 var1 = SCIPfindVar(scip, mpsinputField1(mpsi));
2940 if( var1 == NULL )
2941 {
2942 /* ignore unknown variables - we would not know the type anyway */
2943 mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField1(mpsi), "QMatrix", "QMATRIX", SCIP_VERBLEVEL_NORMAL);
2944 }
2945 else
2946 {
2947 int k;
2948 for( k = 1; k <= 2; ++k )
2949 {
2950 /* get second variable */
2951 var2 = SCIPfindVar(scip, k == 1 ? mpsinputField2(mpsi) : mpsinputField4(mpsi));
2952 if( var2 == NULL )
2953 {
2954 /* ignore unknown variables - we would not know the type anyway */
2955 mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField2(mpsi), "QMatrix", "QMATRIX", SCIP_VERBLEVEL_NORMAL);
2956 }
2957 else
2958 {
2959 const char* field;
2960 char* endptr;
2961
2962 /* get coefficient */
2963 field = (k == 1 ? mpsinputField3(mpsi) : mpsinputField5(mpsi));
2964 if( NULL == field )
2965 {
2966 SCIPerrorMessage("coefficient of term <%s>*<%s> not specified.\n", SCIPvarGetName(var1), SCIPvarGetName(var2));
2967 mpsinputSyntaxerror(mpsi);
2968 SCIPfreeBufferArray(scip, &quadvars1);
2969 SCIPfreeBufferArray(scip, &quadvars2);
2970 SCIPfreeBufferArray(scip, &quadcoefs);
2971 return SCIP_OKAY;
2972 }
2973
2974 coef = strtod(field, &endptr);
2975 if( endptr == field || *endptr != '\0' )
2976 {
2977 SCIPerrorMessage("coefficient of term <%s>*<%s> not specified.\n", SCIPvarGetName(var1), SCIPvarGetName(var2));
2978 mpsinputSyntaxerror(mpsi);
2979 SCIPfreeBufferArray(scip, &quadvars1);
2980 SCIPfreeBufferArray(scip, &quadvars2);
2981 SCIPfreeBufferArray(scip, &quadcoefs);
2982 return SCIP_OKAY;
2983 }
2984
2985 /* store variables and coefficient */
2986 if( cnt >= size )
2987 {
2988 int newsize = SCIPcalcMemGrowSize(scip, size+1);
2989 assert(newsize > size);
2990 SCIP_CALL( SCIPreallocBufferArray(scip, &quadvars1, newsize) );
2991 SCIP_CALL( SCIPreallocBufferArray(scip, &quadvars2, newsize) );
2992 SCIP_CALL( SCIPreallocBufferArray(scip, &quadcoefs, newsize) );
2993 size = newsize;
2994 }
2995 assert(cnt < size);
2996 quadvars1[cnt] = var1;
2997 quadvars2[cnt] = var2;
2998 quadcoefs[cnt] = coef;
2999
3000 /* diagonal elements have to be divided by 2.0
3001 * in a QMATRIX section also off-diagonal have to be divided by 2.0, since both lower and upper diagonal elements are given
3002 */
3003 if( var1 == var2 || !isQuadObj )
3004 quadcoefs[cnt] /= 2.0;
3005 ++cnt;
3006
3007 SCIPdebugMsg(scip, "stored term %g*<%s>*<%s>.\n", coef, SCIPvarGetName(var1), SCIPvarGetName(var2));
3008 }
3009
3010 if( mpsinputField4(mpsi) == NULL || *mpsinputField4(mpsi) == '\0' )
3011 break;
3012
3013 if( mpsinputField5(mpsi) == NULL || *mpsinputField5(mpsi) == '\0' )
3014 {
3015 /* ignore unknown variables - we would not know the type anyway */
3016 mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField4(mpsi), "QMatrix", "QMATRIX", SCIP_VERBLEVEL_NORMAL);
3017 break;
3018 }
3019 }
3020 }
3021 }
3022
3023 /* add constraint */
3024 if( cnt )
3025 {
3026 SCIP_Bool initial, separate, enforce, check, propagate;
3027 SCIP_Bool local, modifiable, dynamic, removable;
3028 SCIP_CONS* cons = NULL;
3029 SCIP_VAR* qmatrixvar = NULL;
3030 SCIP_Real lhs, rhs;
3031 SCIP_Real minusone = -1.0;
3032
3033 /* determine settings; note that reading/{initialconss,dynamicconss,dynamicrows,dynamiccols} apply only to model
3034 * constraints and variables, not to an auxiliary objective constraint (otherwise it can happen that an auxiliary
3035 * objective variable is loose with infinite best bound, triggering the problem that an LP that is unbounded
3036 * because of loose variables with infinite best bound cannot be solved)
3037 */
3038 initial = TRUE;
3039 separate = TRUE;
3040 enforce = TRUE;
3041 check = TRUE;
3042 propagate = TRUE;
3043 local = FALSE;
3044 modifiable = FALSE;
3045 dynamic = FALSE;
3046 removable = FALSE;
3047
3048 SCIP_CALL( SCIPcreateVar(scip, &qmatrixvar, "qmatrixvar", -SCIPinfinity(scip), SCIPinfinity(scip), 1.0,
3050 SCIP_CALL( SCIPaddVar(scip, qmatrixvar) );
3051
3053 {
3054 lhs = -SCIPinfinity(scip);
3055 rhs = 0.0;
3056 }
3057 else
3058 {
3059 lhs = 0.0;
3060 rhs = SCIPinfinity(scip);
3061 }
3062
3063 retcode = SCIPcreateConsQuadraticNonlinear(scip, &cons, "qmatrix", 1, &qmatrixvar, &minusone, cnt, quadvars1, quadvars2, quadcoefs, lhs, rhs,
3064 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable);
3065
3066 if( retcode == SCIP_OKAY )
3067 {
3068 SCIP_CALL( SCIPaddCons(scip, cons) );
3069 SCIPdebugMsg(scip, "(line %d) added constraint <%s>: ", mpsi->lineno, SCIPconsGetName(cons));
3071
3072 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
3073 SCIP_CALL( SCIPreleaseVar(scip, &qmatrixvar) );
3074 }
3075 }
3076 else
3077 {
3078 SCIPwarningMessage(scip, "%s section has no entries.\n", isQuadObj ? "QUADOBJ" : "QMATRIX");
3079 }
3080
3081 SCIPfreeBufferArray(scip, &quadvars1);
3082 SCIPfreeBufferArray(scip, &quadvars2);
3083 SCIPfreeBufferArray(scip, &quadcoefs);
3084
3085 SCIP_CALL( retcode );
3086
3087 return SCIP_OKAY;
3088}
3089
3090
3091/** Process QCMATRIX section.
3092 *
3093 * We read the QCMATRIX section, which is a nonstandard section introduced by CPLEX.
3094 *
3095 * We replace the corresponding linear constraint by a quadratic constraint which contains the
3096 * original linear constraint plus the quadratic part specified in the QCMATRIX.
3097 */
3098static
3100 MPSINPUT* mpsi, /**< mps input structure */
3101 SCIP* scip /**< SCIP data structure */
3102 )
3103{
3104 SCIP_CONS* lincons; /* the linear constraint that was added for the corresponding row */
3105 SCIP_VAR** quadvars1;
3106 SCIP_VAR** quadvars2;
3107 SCIP_Real* quadcoefs;
3108 SCIP_RETCODE retcode;
3109 int cnt = 0; /* number of qcmatrix elements processed so far */
3110 int size; /* size of quad* arrays */
3111
3112 if( mpsinputField1(mpsi) == NULL )
3113 {
3114 SCIPerrorMessage("no row name in QCMATRIX line.\n");
3115 mpsinputSyntaxerror(mpsi);
3116 return SCIP_OKAY;
3117 }
3118
3119 if( SCIPisExact(scip) )
3120 {
3121 SCIPerrorMessage("Exact solving mode cannot handle QCMatrix constraints currently \n");
3122 return SCIP_READERROR;
3123 }
3124
3125 retcode = SCIP_OKAY;
3126
3127 SCIPdebugMsg(scip, "read QCMATRIX section for row <%s>\n", mpsinputField1(mpsi));
3128
3129 lincons = SCIPfindCons(scip, mpsinputField1(mpsi));
3130 if( lincons == NULL )
3131 {
3132 SCIPerrorMessage("no row under name <%s> processed so far.\n", mpsinputField1(mpsi));
3133 mpsinputSyntaxerror(mpsi);
3134 return SCIP_OKAY;
3135 }
3136
3137 size = 1;
3138 SCIP_CALL( SCIPallocBufferArray(scip, &quadvars1, size) );
3139 SCIP_CALL( SCIPallocBufferArray(scip, &quadvars2, size) );
3140 SCIP_CALL( SCIPallocBufferArray(scip, &quadcoefs, size) );
3141
3142 /* loop through section */
3143 /* coverity[tainted_data] */
3144 while( mpsinputReadLine(mpsi) )
3145 {
3146 /* otherwise we are in the section given variables */
3147 SCIP_VAR* var1;
3148 SCIP_VAR* var2;
3149 SCIP_Real coef;
3150
3151 /* check if next section is found */
3152 if( mpsinputField0(mpsi) != NULL )
3153 {
3154 if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
3156 else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
3158 else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
3160 else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
3162 else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
3164 break;
3165 }
3166 if( mpsinputField1(mpsi) == NULL && mpsinputField2(mpsi) == NULL )
3167 {
3168 SCIPerrorMessage("empty data in a non-comment line.\n");
3169 mpsinputSyntaxerror(mpsi);
3170
3171 goto TERMINATE;
3172 }
3173
3174 /* get first variable */
3175 var1 = SCIPfindVar(scip, mpsinputField1(mpsi));
3176 if( var1 == NULL )
3177 {
3178 /* ignore unknown variables - we would not know the type anyway */
3179 mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField1(mpsi), "QCMatrix", SCIPconsGetName(lincons), SCIP_VERBLEVEL_NORMAL);
3180 }
3181 else
3182 {
3183 /* get second variable */
3184 var2 = SCIPfindVar(scip, mpsinputField2(mpsi));
3185 if( var2 == NULL )
3186 {
3187 /* ignore unknown variables - we would not know the type anyway */
3188 mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField2(mpsi), "QCMatrix", SCIPconsGetName(lincons), SCIP_VERBLEVEL_NORMAL);
3189 }
3190 else
3191 {
3192 char* endptr;
3193 if( mpsinputField3(mpsi) == NULL )
3194 {
3195 SCIPerrorMessage("coefficient of term <%s>*<%s> not specified.\n", mpsinputField1(mpsi), mpsinputField2(mpsi));
3196 mpsinputSyntaxerror(mpsi);
3197
3198 goto TERMINATE;
3199 }
3200
3201 /* get coefficient */
3202 coef = strtod(mpsinputField3(mpsi), &endptr);
3203 if( endptr == mpsinputField3(mpsi) || *endptr != '\0' )
3204 {
3205 SCIPerrorMessage("coefficient of term <%s>*<%s> not specified.\n", mpsinputField1(mpsi), mpsinputField2(mpsi));
3206 mpsinputSyntaxerror(mpsi);
3207
3208 goto TERMINATE;
3209 }
3210
3211 /* store variables and coefficient */
3212 if( cnt >= size )
3213 {
3214 int newsize = SCIPcalcMemGrowSize(scip, size+1);
3215 assert(newsize > size);
3216 SCIP_CALL( SCIPreallocBufferArray(scip, &quadvars1, newsize) );
3217 SCIP_CALL( SCIPreallocBufferArray(scip, &quadvars2, newsize) );
3218 SCIP_CALL( SCIPreallocBufferArray(scip, &quadcoefs, newsize) );
3219 size = newsize;
3220 }
3221 assert(cnt < size);
3222 quadvars1[cnt] = var1;
3223 quadvars2[cnt] = var2;
3224 quadcoefs[cnt] = coef;
3225 ++cnt;
3226
3227 SCIPdebugMsg(scip, "stored term %g*<%s>*<%s>.\n", coef, SCIPvarGetName(var1), SCIPvarGetName(var2));
3228
3229 /* check other fields */
3230 if( (mpsinputField4(mpsi) != NULL && *mpsinputField4(mpsi) != '\0' ) ||
3231 (mpsinputField5(mpsi) != NULL && *mpsinputField5(mpsi) != '\0' ) )
3232 {
3233 SCIPwarningMessage(scip, "ignoring data in fields 4 and 5 <%s> <%s>.\n", mpsinputField4(mpsi), mpsinputField5(mpsi));
3234 }
3235 }
3236 }
3237 }
3238
3239 /* replace linear constraint by quadratic constraint */
3240 if( cnt )
3241 {
3242 SCIP_CONS* cons = NULL;
3243
3244 retcode = SCIPcreateConsQuadraticNonlinear(scip, &cons, SCIPconsGetName(lincons),
3245 SCIPgetNVarsLinear(scip, lincons), SCIPgetVarsLinear(scip, lincons), SCIPgetValsLinear(scip, lincons),
3246 cnt, quadvars1, quadvars2, quadcoefs, SCIPgetLhsLinear(scip, lincons), SCIPgetRhsLinear(scip, lincons),
3247 SCIPconsIsInitial(lincons), SCIPconsIsSeparated(lincons), SCIPconsIsEnforced(lincons), SCIPconsIsChecked(lincons),
3248 SCIPconsIsPropagated(lincons), SCIPconsIsLocal(lincons), SCIPconsIsModifiable(lincons), SCIPconsIsDynamic(lincons),
3249 SCIPconsIsRemovable(lincons));
3250
3251 if( retcode != SCIP_OKAY )
3252 goto TERMINATE;
3253
3254 SCIP_CALL( SCIPaddCons(scip, cons) );
3255 SCIPdebugMsg(scip, "(line %d) added constraint <%s>: ", mpsi->lineno, SCIPconsGetName(cons));
3257
3258 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
3259
3260 SCIP_CALL( SCIPdelCons(scip, lincons) );
3261 }
3262 else
3263 {
3264 SCIPwarningMessage(scip, "QCMATRIX section for constraint <%s> has no entries.\n", SCIPconsGetName(lincons));
3265 }
3266
3267 TERMINATE:
3268 SCIPfreeBufferArray(scip, &quadcoefs);
3269 SCIPfreeBufferArray(scip, &quadvars2);
3270 SCIPfreeBufferArray(scip, &quadvars1);
3271
3272 SCIP_CALL( retcode );
3273
3274 return SCIP_OKAY;
3275}
3276
3277
3278/** Process INDICATORS section.
3279 *
3280 * We read the INDICATORS section, which is a nonstandard section introduced by CPLEX.
3281 * Note that CPLEX does not allow ranged rows.
3282 *
3283 * If the linear constraints are equations or ranged rows, we generate two indicator
3284 * constraints.
3285 *
3286 * The section has to come after the QMATRIX* sections.
3287 */
3288static
3290 MPSINPUT* mpsi, /**< mps input structure */
3291 SCIP* scip /**< SCIP data structure */
3292 )
3293{
3294 SCIP_Bool initial;
3296 SCIP_Bool enforce;
3297 SCIP_Bool check;
3298 SCIP_Bool propagate;
3299 SCIP_Bool local;
3300 SCIP_Bool dynamic;
3301 SCIP_Bool removable;
3302 SCIP_Bool stickingatnode;
3303 char name[MPS_MAX_NAMELEN] = { '\0' };
3304
3305 SCIPdebugMsg(scip, "read INDICATORS constraints\n");
3306
3307 if( SCIPisExact(scip) )
3308 {
3309 SCIPerrorMessage("Exact solving mode cannot handle indicator constraints currently \n");
3310 return SCIP_READERROR;
3311 }
3312
3313 /* standard settings for indicator constraints: */
3314 initial = mpsi->initialconss;
3315 separate = TRUE;
3316 enforce = TRUE;
3317 check = TRUE;
3318 propagate = TRUE;
3319 local = FALSE;
3320 dynamic = mpsi->dynamicconss;
3321 removable = mpsi->dynamicrows;
3322 stickingatnode = FALSE;
3323
3324 /* loop through section */
3325 while( mpsinputReadLine(mpsi) )
3326 {
3327 SCIP_CONSHDLR* conshdlr;
3328 SCIP_CONS* cons;
3329 SCIP_CONS* lincons;
3330 SCIP_VAR* binvar;
3331 SCIP_Real lhs;
3332 SCIP_Real rhs;
3333
3334 /* check if next section is found */
3335 if( mpsinputField0(mpsi) != NULL )
3336 {
3337 if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
3339 break;
3340 }
3341
3342 if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL )
3343 {
3344 SCIPerrorMessage("empty data in a non-comment line.\n");
3345 mpsinputSyntaxerror(mpsi);
3346 return SCIP_OKAY;
3347 }
3348
3349 /* check for new indicator constraint */
3350 if( strcmp(mpsinputField1(mpsi), "IF") != 0 )
3351 {
3352 SCIPerrorMessage("Indicator constraints need to be introduced by 'IF' in column 1.\n");
3353 mpsinputSyntaxerror(mpsi);
3354 return SCIP_OKAY;
3355 }
3356
3357 /* get linear constraint (row) */
3358 lincons = SCIPfindCons(scip, mpsinputField2(mpsi));
3359 if( lincons == NULL )
3360 {
3361 SCIPerrorMessage("row <%s> does not exist.\n", mpsinputField2(mpsi));
3362 mpsinputSyntaxerror(mpsi);
3363 return SCIP_OKAY;
3364 }
3365
3366 /* check whether constraint is really linear */
3367 conshdlr = SCIPconsGetHdlr(lincons);
3368 if( strcmp(SCIPconshdlrGetName(conshdlr), "linear") != 0 )
3369 {
3370 SCIPerrorMessage("constraint <%s> is not linear.\n", mpsinputField2(mpsi));
3371 mpsinputSyntaxerror(mpsi);
3372 return SCIP_OKAY;
3373 }
3374
3375 /* get binary variable */
3376 binvar = SCIPfindVar(scip, mpsinputField3(mpsi));
3377 if( binvar == NULL )
3378 {
3379 SCIPerrorMessage("binary variable <%s> does not exist.\n", mpsinputField3(mpsi));
3380 mpsinputSyntaxerror(mpsi);
3381 return SCIP_OKAY;
3382 }
3383
3384 /* check type */
3385 if( SCIPvarGetType(binvar) != SCIP_VARTYPE_BINARY )
3386 {
3387 SCIPerrorMessage("variable <%s> is not binary.\n", mpsinputField3(mpsi));
3388 mpsinputSyntaxerror(mpsi);
3389 return SCIP_OKAY;
3390 }
3391
3392 /* check whether we need the negated variable */
3393 if( mpsinputField4(mpsi) != NULL )
3394 {
3395 if( *mpsinputField4(mpsi) == '0' )
3396 {
3397 SCIP_VAR* var;
3398 SCIP_CALL( SCIPgetNegatedVar(scip, binvar, &var) );
3399 binvar = var;
3400 assert( binvar != NULL );
3401 }
3402 else
3403 {
3404 if( *mpsinputField4(mpsi) != '1' )
3405 {
3406 SCIPerrorMessage("binary variable <%s> can only take values 0/1 (%s).\n", mpsinputField3(mpsi), mpsinputField4(mpsi));
3407 mpsinputSyntaxerror(mpsi);
3408 return SCIP_OKAY;
3409 }
3410 }
3411 }
3412
3413 /* get lhs/rhs */
3414 lhs = SCIPgetLhsLinear(scip, lincons);
3415 rhs = SCIPgetRhsLinear(scip, lincons);
3416
3417 if( !SCIPisInfinity(scip, -lhs) )
3418 {
3419 if( ! SCIPisInfinity(scip, rhs) )
3420 {
3421 /* create second indicator constraint */
3422 SCIP_VAR** vars;
3423 SCIP_Real* vals;
3424 SCIP_RETCODE retcode;
3425 SCIP_VAR** linvars;
3426 SCIP_Real* linvals;
3427 int nlinvars;
3428 int i;
3429
3430 nlinvars = SCIPgetNVarsLinear(scip, lincons);
3431 linvars = SCIPgetVarsLinear(scip, lincons);
3432 linvals = SCIPgetValsLinear(scip, lincons);
3433
3434 SCIP_CALL( SCIPallocBufferArray(scip, &vars, nlinvars) );
3435 SCIP_CALL( SCIPallocBufferArray(scip, &vals, nlinvars) );
3436 for( i = 0; i < nlinvars; ++i )
3437 {
3438 vars[i] = linvars[i];
3439 vals[i] = -linvals[i];
3440 }
3441
3442 /* create new name */
3443 (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "indlhs_%s", SCIPconsGetName(lincons));
3444
3445 /* create indicator constraint */
3446 retcode = SCIPcreateConsIndicator(scip, &cons, name, binvar, nlinvars, vars, vals, -lhs,
3447 initial, separate, enforce, check, propagate, local, dynamic, removable, stickingatnode);
3448
3449 if( retcode == SCIP_OKAY )
3450 {
3451 SCIP_CALL( SCIPaddCons(scip, cons) );
3452 SCIPdebugMsg(scip, "created indicator constraint <%s>\n", mpsinputField2(mpsi));
3454 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
3455 }
3456
3457 SCIPfreeBufferArray(scip, &vals);
3458 SCIPfreeBufferArray(scip, &vars);
3459
3460 SCIP_CALL( retcode );
3461 }
3462 }
3463
3464 /* correct linear constraint and create new name */
3465 if ( ! SCIPisInfinity(scip, -lhs) && ! SCIPisInfinity(scip, rhs) )
3466 {
3467 /* we have added lhs above and only need the rhs */
3469 (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "indrhs_%s", SCIPconsGetName(lincons));
3470 }
3471 else
3472 (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "ind_%s", SCIPconsGetName(lincons));
3473
3474 /* create indicator constraint */
3475 SCIP_CALL( SCIPcreateConsIndicatorLinConsPure(scip, &cons, name, binvar, lincons,
3476 initial, separate, enforce, check, propagate, local, dynamic, removable, stickingatnode) );
3477
3478 SCIP_CALL( SCIPaddCons(scip, cons) );
3479 SCIPdebugMsg(scip, "created indicator constraint <%s>", mpsinputField2(mpsi));
3481 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
3482 }
3483
3484 return SCIP_OKAY;
3485}
3486
3487
3488/** Read LP in "MPS File Format".
3489 *
3490 * A specification of the MPS format can be found at
3491 *
3492 * http://plato.asu.edu/ftp/mps_format.txt,
3493 * ftp://ftp.caam.rice.edu/pub/people/bixby/miplib/mps_format,
3494 *
3495 * and in the
3496 *
3497 * CPLEX Reference Manual
3498 *
3499 * This routine should read all valid MPS format files.
3500 * What it will not do, is to find all cases where a file is ill formed.
3501 * If this happens it may complain and read nothing or read "something".
3502 */
3503static
3505 SCIP* scip, /**< SCIP data structure */
3506 const char* filename, /**< name of the input file */
3507 const char*** varnames, /**< storage for the variable names, or NULL */
3508 const char*** consnames, /**< storage for the constraint names, or NULL */
3509 int* varnamessize, /**< the size of the variable names storage, or NULL */
3510 int* consnamessize, /**< the size of the constraint names storage, or NULL */
3511 int* nvarnames, /**< the number of stored variable names, or NULL */
3512 int* nconsnames /**< the number of stored constraint names, or NULL */
3513 )
3514{
3515 SCIP_FILE* fp;
3516 MPSINPUT* mpsi;
3517 SCIP_RETCODE retcode;
3518
3519 assert(scip != NULL);
3520 assert(filename != NULL);
3521
3522 fp = SCIPfopen(filename, "r");
3523 if( fp == NULL )
3524 {
3525 SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
3526 SCIPprintSysError(filename);
3527 return SCIP_NOFILE;
3528 }
3529
3530 SCIP_CALL( mpsinputCreate(scip, &mpsi, fp) );
3531
3532 SCIP_CALL_TERMINATE( retcode, readName(scip, mpsi), TERMINATE );
3533
3534 SCIP_CALL_TERMINATE( retcode, SCIPcreateProb(scip, mpsi->probname, NULL, NULL, NULL, NULL, NULL, NULL, NULL), TERMINATE );
3535
3536 if( mpsinputSection(mpsi) == MPS_OBJSEN )
3537 {
3538 SCIP_CALL_TERMINATE( retcode, readObjsen(scip, mpsi), TERMINATE );
3539 }
3540 if( mpsinputSection(mpsi) == MPS_OBJNAME )
3541 {
3542 SCIP_CALL_TERMINATE( retcode, readObjname(scip, mpsi), TERMINATE );
3543 }
3544 while( mpsinputSection(mpsi) == MPS_ROWS
3545 || mpsinputSection(mpsi) == MPS_USERCUTS
3546 || mpsinputSection(mpsi) == MPS_LAZYCONS )
3547 {
3548 SCIP_CALL_TERMINATE( retcode, readRows(mpsi, scip, consnames, consnamessize, nconsnames), TERMINATE );
3549 }
3550 if( mpsinputSection(mpsi) == MPS_COLUMNS )
3551 {
3552 SCIP_CALL_TERMINATE( retcode, readCols(mpsi, scip, varnames, varnamessize, nvarnames), TERMINATE );
3553 }
3554 if( mpsinputSection(mpsi) == MPS_RHS )
3555 {
3556 SCIP_CALL_TERMINATE( retcode, readRhs(mpsi, scip), TERMINATE );
3557 }
3558 if( mpsinputSection(mpsi) == MPS_RANGES )
3559 {
3560 SCIP_CALL_TERMINATE( retcode, readRanges(mpsi, scip), TERMINATE );
3561 }
3562 if( mpsinputSection(mpsi) == MPS_BOUNDS )
3563 {
3564 SCIP_CALL_TERMINATE( retcode, readBounds(mpsi, scip), TERMINATE );
3565 }
3566 if( mpsinputSection(mpsi) == MPS_SOS )
3567 {
3568 SCIP_CALL_TERMINATE( retcode, readSOS(mpsi, scip), TERMINATE );
3569 }
3570 while( mpsinputSection(mpsi) == MPS_QCMATRIX )
3571 {
3572 SCIP_CALL_TERMINATE( retcode, readQCMatrix(mpsi, scip), TERMINATE );
3573 }
3574 if( mpsinputSection(mpsi) == MPS_QMATRIX )
3575 {
3576 SCIP_CALL_TERMINATE( retcode, readQMatrix(mpsi, FALSE, scip), TERMINATE );
3577 }
3578 if( mpsinputSection(mpsi) == MPS_QUADOBJ )
3579 {
3580 SCIP_CALL_TERMINATE( retcode, readQMatrix(mpsi, TRUE, scip), TERMINATE );
3581 }
3582 while( mpsinputSection(mpsi) == MPS_QCMATRIX )
3583 {
3584 SCIP_CALL_TERMINATE( retcode, readQCMatrix(mpsi, scip), TERMINATE );
3585 }
3586 if( mpsinputSection(mpsi) == MPS_INDICATORS )
3587 {
3588 SCIP_CALL_TERMINATE( retcode, readIndicators(mpsi, scip), TERMINATE );
3589 }
3590 if( mpsinputSection(mpsi) != MPS_ENDATA )
3591 mpsinputSyntaxerror(mpsi);
3592
3593 if( mpsinputHasError(mpsi) )
3594 {
3595 retcode = SCIP_READERROR;
3596 goto TERMINATE;
3597 }
3598
3599 SCIP_CALL_TERMINATE( retcode, SCIPsetObjsense(scip, mpsinputObjsense(mpsi)), TERMINATE );
3600
3601 TERMINATE:
3602 mpsinputFree(scip, &mpsi);
3603 SCIPfclose(fp);
3604
3605 return retcode;
3606}
3607
3608/** Read LP in "MPS File Format" (version for exact solving mode, numbers can also be rationals).
3609 *
3610 * A specification of the MPS format can be found at
3611 *
3612 * http://plato.asu.edu/ftp/mps_format.txt,
3613 * ftp://ftp.caam.rice.edu/pub/people/bixby/miplib/mps_format,
3614 *
3615 * and in the
3616 *
3617 * CPLEX Reference Manual
3618 *
3619 * This routine should read all valid MPS format files.
3620 * What it will not do, is to find all cases where a file is ill formed.
3621 * If this happens it may complain and read nothing or read "something".
3622 */
3623static
3625 SCIP* scip, /**< SCIP data structure */
3626 const char* filename, /**< name of the input file */
3627 const char*** varnames, /**< storage for the variable names, or NULL */
3628 const char*** consnames, /**< storage for the constraint names, or NULL */
3629 int* varnamessize, /**< the size of the variable names storage, or NULL */
3630 int* consnamessize, /**< the size of the constraint names storage, or NULL */
3631 int* nvarnames, /**< the number of stored variable names, or NULL */
3632 int* nconsnames /**< the number of stored constraint names, or NULL */
3633 )
3634{
3635 SCIP_FILE* fp;
3636 MPSINPUT* mpsi;
3637 SCIP_RETCODE retcode;
3638
3639 assert(scip != NULL);
3640 assert(filename != NULL);
3641 assert(SCIPisExact(scip));
3642
3643 fp = SCIPfopen(filename, "r");
3644 if( fp == NULL )
3645 {
3646 SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
3647 SCIPprintSysError(filename);
3648 return SCIP_NOFILE;
3649 }
3650
3651 SCIP_CALL( mpsinputCreate(scip, &mpsi, fp) );
3652
3653 SCIP_CALL_TERMINATE( retcode, readName(scip, mpsi), TERMINATE );
3654
3655 SCIP_CALL_TERMINATE( retcode, SCIPcreateProb(scip, mpsi->probname, NULL, NULL, NULL, NULL, NULL, NULL, NULL), TERMINATE );
3656
3657 if( mpsinputSection(mpsi) == MPS_OBJSEN )
3658 {
3659 SCIP_CALL_TERMINATE( retcode, readObjsen(scip, mpsi), TERMINATE );
3660 }
3661 if( mpsinputSection(mpsi) == MPS_OBJNAME )
3662 {
3663 SCIP_CALL_TERMINATE( retcode, readObjname(scip, mpsi), TERMINATE );
3664 }
3665 while( mpsinputSection(mpsi) == MPS_ROWS
3666 || mpsinputSection(mpsi) == MPS_USERCUTS
3667 || mpsinputSection(mpsi) == MPS_LAZYCONS )
3668 {
3669 SCIP_CALL_TERMINATE( retcode, readRowsExact(mpsi, scip, consnames, consnamessize, nconsnames), TERMINATE );
3670 }
3671 if( mpsinputSection(mpsi) == MPS_COLUMNS )
3672 {
3673 SCIP_CALL_TERMINATE( retcode, readColsExact(mpsi, scip, varnames, varnamessize, nvarnames), TERMINATE );
3674 }
3675 if( mpsinputSection(mpsi) == MPS_RHS )
3676 {
3677 SCIP_CALL_TERMINATE( retcode, readRhsExact(mpsi, scip), TERMINATE );
3678 }
3679 if( mpsinputSection(mpsi) == MPS_RANGES )
3680 {
3681 SCIP_CALL_TERMINATE( retcode, readRangesExact(mpsi, scip), TERMINATE );
3682 }
3683 if( mpsinputSection(mpsi) == MPS_BOUNDS )
3684 {
3685 SCIP_CALL_TERMINATE( retcode, readBoundsExact(mpsi, scip), TERMINATE );
3686 }
3687 if( mpsinputSection(mpsi) == MPS_SOS )
3688 {
3689 SCIP_CALL_TERMINATE( retcode, readSOS(mpsi, scip), TERMINATE );
3690 }
3691 while( mpsinputSection(mpsi) == MPS_QCMATRIX )
3692 {
3693 SCIP_CALL_TERMINATE( retcode, readQCMatrix(mpsi, scip), TERMINATE );
3694 }
3695 if( mpsinputSection(mpsi) == MPS_QMATRIX )
3696 {
3697 SCIP_CALL_TERMINATE( retcode, readQMatrix(mpsi, FALSE, scip), TERMINATE );
3698 }
3699 if( mpsinputSection(mpsi) == MPS_QUADOBJ )
3700 {
3701 SCIP_CALL_TERMINATE( retcode, readQMatrix(mpsi, TRUE, scip), TERMINATE );
3702 }
3703 while( mpsinputSection(mpsi) == MPS_QCMATRIX )
3704 {
3705 SCIP_CALL_TERMINATE( retcode, readQCMatrix(mpsi, scip), TERMINATE );
3706 }
3707 if( mpsinputSection(mpsi) == MPS_INDICATORS )
3708 {
3709 SCIP_CALL_TERMINATE( retcode, readIndicators(mpsi, scip), TERMINATE );
3710 }
3711 if( mpsinputSection(mpsi) != MPS_ENDATA )
3712 mpsinputSyntaxerror(mpsi);
3713
3714 if( mpsinputHasError(mpsi) )
3715 {
3716 retcode = SCIP_READERROR;
3717 goto TERMINATE;
3718 }
3719
3720 SCIP_CALL_TERMINATE( retcode, SCIPsetObjsense(scip, mpsinputObjsense(mpsi)), TERMINATE );
3721
3722 TERMINATE:
3723 mpsinputFree(scip, &mpsi);
3724 SCIPfclose(fp);
3725
3726 return retcode;
3727}
3728
3729/*
3730 * local methods for writing problem
3731 */
3732
3733/** gets the key (i.e. the name) of the given namefreq */
3734static
3735SCIP_DECL_HASHGETKEY(hashGetKeyNamefreq)
3736{ /*lint --e{715}*/
3737 CONSNAMEFREQ* consnamefreq = (CONSNAMEFREQ*)elem;
3738
3739 assert(consnamefreq != NULL);
3740 assert(consnamefreq->consname != NULL);
3741
3742 return (void*)consnamefreq->consname;
3743}
3744
3745/** returns TRUE iff both keys (i.e. strings) are equal up to max length*/
3746static
3747SCIP_DECL_HASHKEYEQ(hashKeyEqString)
3748{ /*lint --e{715}*/
3749 const char* string1 = (const char*)key1;
3750 const char* string2 = (const char*)key2;
3751
3752 return (strncmp(string1, string2, MPS_MAX_NAMELEN - 1) == 0);
3753}
3754
3755/** hash key retrieval function for variables */
3756static
3758{ /*lint --e{715}*/
3759 return elem;
3760}
3761
3762/** returns TRUE iff the indices of both variables are equal */
3763static
3765{ /*lint --e{715}*/
3766 if( key1 == key2 )
3767 return TRUE;
3768 return FALSE;
3769}
3770
3771/** returns the hash value of the key */
3772static
3774{ /*lint --e{715}*/
3775 assert( SCIPvarGetIndex((SCIP_VAR*) key) >= 0 );
3776 return (unsigned int) SCIPvarGetIndex((SCIP_VAR*) key);
3777}
3778
3779
3780/** computes the field width such that the output file is nicely arranged */
3781static
3783 unsigned int width /**< required width */
3784 )
3785{
3786 width = MAX(8u, width);
3787 return MIN(MPS_MAX_FIELDLEN, width);
3788}
3789
3790
3791/** output two strings in columns 1 and 2 with computed widths */
3792static
3794 SCIP* scip, /**< SCIP data structure */
3795 FILE* file, /**< output file (or NULL for standard output) */
3796 const char* col1, /**< column 1 */
3797 const char* col2, /**< column 2 */
3798 unsigned int maxnamelen /**< maximum name length */
3799 )
3800{
3801 unsigned int fieldwidth;
3802 char format[32];
3803
3804 assert( scip != NULL );
3805 assert( col1 != NULL );
3806 assert( col2 != NULL );
3807 assert( strlen(col1) < MPS_MAX_NAMELEN );
3808 assert( strlen(col2) < MPS_MAX_VALUELEN );
3809 assert( maxnamelen > 0 );
3810
3811 fieldwidth = computeFieldWidth(maxnamelen);
3812 (void) SCIPsnprintf(format, 32," %%-%ds %%%ds ", fieldwidth, MPS_MAX_VALUELEN - 1);
3813
3814 SCIPinfoMessage(scip, file, (const char *)format, col1, col2);
3815}
3816
3817/** output two strings in columns 1 (width 2) and 2 (width 8) */
3818static
3820 SCIP* scip, /**< SCIP data structure */
3821 FILE* file, /**< output file (or NULL for standard output) */
3822 const char* col1, /**< column 1 */
3823 const char* col2, /**< column 2 */
3824 int maxnamelen /**< maximum name length (-1 if irrelevant) */
3825 )
3826{
3827 unsigned int fieldwidth;
3828 char format[32];
3829
3830 assert( scip != NULL );
3831 assert( col1 != NULL );
3832 assert( col2 != NULL );
3833 assert( strlen(col1) <= 2 );
3834 assert( strlen(col2) < MPS_MAX_NAMELEN );
3835 assert( maxnamelen == -1 || maxnamelen > 0 );
3836
3837 if( maxnamelen < 0 )
3838 {
3839 /* format does not matter */
3840 (void) SCIPsnprintf(format, 32, " %%-2.2s %%-s ");
3841 }
3842 else
3843 {
3844 fieldwidth = computeFieldWidth((unsigned int) maxnamelen);
3845 (void) SCIPsnprintf(format, 32, " %%-2.2s %%-%ds ", fieldwidth);
3846 }
3847
3848 SCIPinfoMessage(scip, file, (const char*)format, col1, col2);
3849}
3850
3851/** prints the given data as column entry */
3852static
3854 SCIP* scip, /**< SCIP data structure */
3855 FILE* file, /**< output file (or NULL for standard output) */
3856 const char* varname, /**< variable name */
3857 const char* consname, /**< constraint name */
3858 SCIP_Real value, /**< value to display */
3859 int* recordcnt, /**< pointer to store the number of records per line */
3860 unsigned int maxnamelen /**< maximum name length */
3861 )
3862{
3863 char valuestr[MPS_MAX_VALUELEN] = { '\0' };
3864
3865 assert( scip != NULL );
3866 assert( recordcnt != NULL );
3867 assert( *recordcnt >= 0 && *recordcnt < 2 );
3868
3869 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", value);
3870
3871 if( *recordcnt == 0 )
3872 {
3873 /* start new line with an empty first column and the variable name in the second column */
3874 printStart(scip, file, "", varname, (int) maxnamelen);
3875 *recordcnt = 0;
3876 }
3877
3878 printRecord(scip, file, consname, valuestr, maxnamelen);
3879 (*recordcnt)++;
3880
3881 if( *recordcnt == 2 )
3882 {
3883 /* each line can have at most two records */
3884 SCIPinfoMessage(scip, file, "\n");
3885 *recordcnt = 0;
3886 }
3887}
3888
3889/** prints the constraint type to file stream */
3890static
3892 SCIP* scip, /**< SCIP data structure */
3893 FILE* file, /**< output file (or NULL for standard output) */
3894 SCIP_Real lhs, /**< left hand side */
3895 SCIP_Real rhs, /**< right hand side */
3896 const char* name /**< constraint name */
3897 )
3898{
3899 char rowtype[2];
3900
3901 assert( scip != NULL );
3902 assert( !SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs) );
3903 assert( SCIPisGT(scip, rhs, lhs) || SCIPisEQ(scip, lhs, rhs) );
3904 assert( name != NULL );
3905
3906 if( SCIPisEQ(scip, lhs, rhs) )
3907 (void) SCIPsnprintf(rowtype, 2, "%s", "E");
3908 else
3909 {
3910 /* in case the right hand side and the left hand side are not infinity we print a
3911 * less or equal constraint and put the right hand side in the RHS section and the
3912 * left hand side (hidden) in the RANGE section */
3913 if( !SCIPisInfinity(scip, rhs) )
3914 (void) SCIPsnprintf(rowtype, 2, "%s", "L");
3915 else
3916 {
3917 assert( !SCIPisInfinity(scip, -lhs) );
3918 (void) SCIPsnprintf(rowtype, 2, "%s", "G");
3919 }
3920 }
3921
3922 printStart(scip, file, rowtype, name, -1);
3923 SCIPinfoMessage(scip, file, "\n");
3924}
3925
3926
3927/** initializes the sparse matrix */
3928static
3930 SCIP* scip, /**< SCIP data structure */
3931 SPARSEMATRIX** matrix, /**< pointer to sparse matrix containing the entries */
3932 int slots /**< number of slots */
3933 )
3934{
3935 SCIP_CALL( SCIPallocBuffer(scip, matrix) );
3936 (*matrix)->nentries = 0;
3937 (*matrix)->sentries = slots;
3938 SCIP_CALL( SCIPallocBufferArray(scip, &(*matrix)->values, (*matrix)->sentries) );
3939 SCIP_CALL( SCIPallocBufferArray(scip, &(*matrix)->columns, (*matrix)->sentries) );
3940 SCIP_CALL( SCIPallocBufferArray(scip, &(*matrix)->rows, (*matrix)->sentries) );
3941
3942 return SCIP_OKAY;
3943}
3944
3945/** this method takes care that the required capacity is available in the sparse matrix */
3946static
3948 SCIP* scip, /**< SCIP data structure */
3949 SPARSEMATRIX* matrix, /**< sparse matrix for storing the coefficient */
3950 int capacity /**< needed capacity */
3951 )
3952{
3953 if( matrix->nentries + capacity >= matrix->sentries )
3954 {
3955 matrix->sentries = matrix->sentries * 2 + capacity;
3956 SCIP_CALL( SCIPreallocBufferArray(scip, &matrix->values, matrix->sentries) );
3957 SCIP_CALL( SCIPreallocBufferArray(scip, &matrix->columns, matrix->sentries) );
3958 SCIP_CALL( SCIPreallocBufferArray(scip, &matrix->rows, matrix->sentries) );
3959 }
3960 return SCIP_OKAY;
3961}
3962
3963/** frees the sparse matrix */
3964static
3966 SCIP* scip, /**< SCIP data structure */
3967 SPARSEMATRIX* matrix /**< sparse matrix to free */
3968 )
3969{
3970 SCIPfreeBufferArray(scip, &matrix->rows);
3971 SCIPfreeBufferArray(scip, &matrix->columns);
3972 SCIPfreeBufferArray(scip, &matrix->values);
3973
3974 SCIPfreeBuffer(scip, &matrix);
3975}
3976
3977
3978/** computes the coefficient for the given variables and linear constraint information */
3979static
3981 SCIP* scip, /**< SCIP data structure */
3982 const char* consname, /**< name of the constraint */
3983 SCIP_VAR** vars, /**< array of variables */
3984 SCIP_Real* vals, /**< array of coefficients values (or NULL if all coefficient values are 1) */
3985 int nvars, /**< number of variables */
3986 SCIP_Bool transformed, /**< transformed constraint? */
3987 SPARSEMATRIX* matrix, /**< sparse matrix for storing the coefficient */
3988 SCIP_Real* rhs /**< pointer to right hand side */
3989 )
3990{
3991 SCIP_VAR** activevars;
3992 SCIP_Real* activevals;
3993 SCIP_Real activeconstant = 0.0;
3994
3995 int nactivevars;
3996 int requiredsize;
3997 int v;
3998
3999 assert( scip != NULL );
4000 assert( nvars == 0 || vars != NULL );
4001 assert( !SCIPisInfinity(scip, *rhs) );
4002 assert( matrix != NULL );
4003
4004 /* if the variables array contains no variables, then return without
4005 * doing any thing; The MPS format and LP format do not forbid this
4006 * situation */
4007 if( nvars == 0 )
4008 return SCIP_OKAY;
4009
4010 /* duplicate variable and value array */
4011 nactivevars = nvars;
4012 SCIP_CALL( SCIPduplicateBufferArray(scip, &activevars, vars, nactivevars ) );
4013
4014 if( vals != NULL )
4015 {
4016 SCIP_CALL( SCIPduplicateBufferArray(scip, &activevals, vals, nactivevars ) );
4017 }
4018 else
4019 {
4020 SCIP_CALL( SCIPallocBufferArray(scip, &activevals, nactivevars) );
4021
4022 for( v = 0; v < nactivevars; ++v )
4023 activevals[v] = 1.0;
4024 }
4025
4026 /* retransform given variables to active variables */
4027 if( transformed )
4028 {
4029 SCIP_CALL( SCIPgetProbvarLinearSum(scip, activevars, activevals, &nactivevars, nactivevars, &activeconstant, &requiredsize) );
4030
4031 if( requiredsize > nactivevars )
4032 {
4033 SCIP_CALL( SCIPreallocBufferArray(scip, &activevars, requiredsize) );
4034 SCIP_CALL( SCIPreallocBufferArray(scip, &activevals, requiredsize) );
4035
4036 SCIP_CALL( SCIPgetProbvarLinearSum(scip, activevars, activevals, &nactivevars, requiredsize, &activeconstant, &requiredsize) );
4037 }
4038 assert( requiredsize == nactivevars );
4039 }
4040 else
4041 {
4042 for( v = 0; v < nactivevars; ++v )
4043 {
4044 SCIP_CALL( SCIPvarGetOrigvarSum(&activevars[v], &activevals[v], &activeconstant) );
4045
4046 /* negated variables with an original counterpart may also be returned by SCIPvarGetOrigvarSum();
4047 * make sure we get the original variable in that case
4048 */
4049 if( SCIPvarGetStatus(activevars[v]) == SCIP_VARSTATUS_NEGATED )
4050 {
4051 activevars[v] = SCIPvarGetNegatedVar(activevars[v]);
4052 activeconstant += activevals[v];
4053 activevals[v] *= -1.0;
4054 }
4055 }
4056 }
4057
4058 /* copy the (matrix) row into the sparse matrix */
4059 SCIP_CALL( checkSparseMatrixCapacity(scip, matrix, nactivevars) );
4060 assert( matrix->nentries + nactivevars < matrix->sentries );
4061
4062 for( v = 0; v < nactivevars; ++v )
4063 {
4064 matrix->values[matrix->nentries] = activevals[v];
4065 matrix->columns[matrix->nentries] = activevars[v];
4066 matrix->rows[matrix->nentries] = consname;
4067 matrix->nentries++;
4068 }
4069
4070 /* adjust right hand side */
4071 (*rhs) -= activeconstant;
4072
4073 /* free buffer arrays */
4074 SCIPfreeBufferArray(scip, &activevals);
4075 SCIPfreeBufferArray(scip, &activevars);
4076
4077 return SCIP_OKAY;
4078}
4079
4080
4081/** check whether given variables are aggregated and put them into an array without duplication */
4082static
4084 SCIP* scip, /**< SCIP data structure */
4085 SCIP_VAR** vars, /**< variable array */
4086 int nvars, /**< number of active variables in the problem */
4087 SCIP_VAR*** aggvars, /**< pointer to array storing the aggregated variables on output */
4088 int* naggvars, /**< pointer to number of aggregated variables on output */
4089 int* saggvars, /**< pointer to number of slots in aggvars array */
4090 SCIP_HASHTABLE* varAggregated /**< hashtable for checking duplicates */
4091 )
4092{
4093 int v;
4094
4095 assert( scip != NULL );
4096 assert( aggvars != NULL );
4097 assert( naggvars != NULL );
4098 assert( saggvars != NULL );
4099
4100 /* check variables */
4101 for( v = 0; v < nvars; ++v )
4102 {
4103 SCIP_VARSTATUS status;
4104 SCIP_VAR* var;
4105
4106 var = vars[v];
4107 status = SCIPvarGetStatus(var);
4108
4109 /* collect aggregated variables in a list */
4110 if( status >= SCIP_VARSTATUS_AGGREGATED )
4111 {
4112 assert( status == SCIP_VARSTATUS_AGGREGATED || status == SCIP_VARSTATUS_MULTAGGR || status == SCIP_VARSTATUS_NEGATED );
4113 assert( varAggregated != NULL );
4114
4115 if( ! SCIPhashtableExists(varAggregated, (void*) var) )
4116 {
4117 /* possibly enlarge array */
4118 if ( *saggvars <= *naggvars )
4119 {
4120 int newsize;
4121 newsize = SCIPcalcMemGrowSize(scip, *naggvars + 1);
4122 assert( newsize > *saggvars );
4123 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &aggvars, *saggvars, newsize) );
4124 *saggvars = newsize;
4125 }
4126
4127 (*aggvars)[*naggvars] = var;
4128 (*naggvars)++;
4129 SCIP_CALL( SCIPhashtableInsert(varAggregated, (void*) var) );
4130 assert( *naggvars <= *saggvars );
4131 }
4132 }
4133 }
4134 return SCIP_OKAY;
4135}
4136
4137
4138/** method check if the variable names are not longer than MPS_MAX_NAMELEN - 1*/
4139static
4141 SCIP* scip, /**< SCIP data structure */
4142 SCIP_VAR** vars, /**< array of variables */
4143 int nvars, /**< number of variables */
4144 unsigned int* maxnamelen, /**< pointer to store the maximum name length */
4145 const char*** varnames, /**< pointer to array of variable names */
4146 SCIP_HASHMAP** varnameHashmap /**< pointer to hash map storing variable, variable name mapping */
4147 )
4148{
4149 int v;
4150 int faulty;
4151 char* varname;
4152 SCIP_VAR* var;
4153
4154 assert( scip != NULL );
4155 assert( vars != NULL );
4156 assert( maxnamelen != NULL );
4157
4158 faulty = 0;
4159
4160 /* allocate memory */
4161 SCIP_CALL( SCIPhashmapCreate(varnameHashmap, SCIPblkmem(scip), nvars) );
4162 SCIP_CALL( SCIPallocBufferArray(scip, varnames, nvars) );
4163
4164 /* check if the variable names are not to long */
4165 for( v = 0; v < nvars; ++v )
4166 {
4167 size_t l;
4168
4169 var = vars[v];
4170 assert( var != NULL );
4171
4172 l = strlen(SCIPvarGetName(var));
4173
4174 if( l >= MPS_MAX_NAMELEN )
4175 {
4176 faulty++;
4177 (*maxnamelen) = MPS_MAX_NAMELEN - 1;
4178 }
4179 else
4180 {
4181 (*maxnamelen) = MAX(*maxnamelen, (unsigned int) l);
4182 }
4183
4184 SCIP_CALL( SCIPallocBufferArray(scip, &varname, (int) *maxnamelen + 1) );
4185 (void) SCIPsnprintf(varname, (int)(*maxnamelen) + 1, "%s", SCIPvarGetName(var) );
4186
4187 /* insert variable with variable name into hash map */
4188 assert( !SCIPhashmapExists(*varnameHashmap, var) );
4189 SCIP_CALL( SCIPhashmapInsert(*varnameHashmap, var, (void*) varname) );
4190
4191 (*varnames)[v] = varname;
4192 }
4193
4194 if( faulty > 0 )
4195 {
4196 SCIPwarningMessage(scip, "there are %d variable names which have to be cut down to %d characters; LP might be corrupted\n",
4197 faulty, MPS_MAX_NAMELEN - 1);
4198 }
4199 return SCIP_OKAY;
4200}
4201
4202/** method check if the constraint names are not longer than MPS_MAX_NAMELEN - 1 */
4203static
4205 SCIP* scip, /**< SCIP data structure */
4206 SCIP_CONS** conss, /**< array of all constraints */
4207 int nconss, /**< number of all constraints */
4208 SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
4209 unsigned int* maxnamelen, /**< pointer to store the maximum name length */
4210 const char*** consnames, /**< pointer to array of constraint names */
4211 SCIP_Bool* error /**< pointer to store whether all constraint names exist */
4212 )
4213{
4214 SCIP_HASHTABLE* consfreq;
4215 CONSNAMEFREQ* consnamefreqs;
4216 SCIP_CONS* cons;
4217 char* consname;
4218 int i;
4219
4220 assert(scip != NULL);
4221 assert(maxnamelen != NULL);
4222
4223 *error = FALSE;
4224
4225 /* allocate memory */
4226 SCIP_CALL( SCIPallocBufferArray(scip, &consnamefreqs, nconss) );
4227 SCIP_CALL( SCIPallocBufferArray(scip, consnames, nconss) );
4229 hashGetKeyNamefreq, hashKeyEqString, SCIPhashKeyValString, NULL) );
4230
4231 for( i = 0; i < nconss; ++i )
4232 {
4233 CONSNAMEFREQ* consnamefreq;
4234 size_t l;
4235 int freq;
4236
4237 cons = conss[i];
4238 assert( cons != NULL );
4239
4240 /* in case the transformed problem is written, only constraints are posted which are enabled in the current node */
4241 assert(!transformed || SCIPconsIsEnabled(cons));
4242
4243 l = strlen(SCIPconsGetName(cons));
4244
4245 if( l == 0 )
4246 {
4247 SCIPwarningMessage(scip, "At least one name of a constraint is empty, so file will be written with generic names.\n");
4248 *error = TRUE;
4249
4250 goto TERMINATE;
4251 }
4252
4253 consnamefreqs[i].consname = SCIPconsGetName(cons);
4254 consnamefreqs[i].freq = 0;
4255 freq = 0;
4256
4257 /* check for duplicate names */
4258 if( NULL != (consnamefreq = (CONSNAMEFREQ *)SCIPhashtableRetrieve(consfreq, (void*)SCIPconsGetName(cons))) )
4259 {
4260 consnamefreq->freq += 1;
4261 consnamefreqs[i] = *consnamefreq;
4262 freq = consnamefreq->freq;
4263 }
4264 SCIP_CALL( SCIPhashtableInsert(consfreq, (void*)(&consnamefreqs[i])) );
4265
4266 /* the new length is the length of the old name + a '_' and the freq number which has floor(log10(freq)) + 1 characters */
4267 if( freq > 0 )
4268 l = l + 1 + (size_t)log10((SCIP_Real) freq) + 1;
4269
4270 if( l >= MPS_MAX_NAMELEN )
4271 {
4272 SCIPwarningMessage(scip, "Constraints have duplicate name and are too long to fix, so file will be written with generic names.\n");
4273 *error = TRUE;
4274
4275 goto TERMINATE;
4276 }
4277
4278 (*maxnamelen) = MAX(*maxnamelen, (unsigned int) l);
4279
4280 SCIP_CALL( SCIPallocBufferArray(scip, &consname, (int) l + 1) );
4281 if( freq > 0 )
4282 (void) SCIPsnprintf(consname, (int)l + 1, "%s_%d", SCIPconsGetName(cons), freq);
4283 else
4284 (void) SCIPsnprintf(consname, (int)l + 1, "%s", SCIPconsGetName(cons));
4285
4286 (*consnames)[i] = consname;
4287 }
4288
4289TERMINATE:
4290 SCIPfreeBufferArray(scip, &consnamefreqs);
4291
4292 if( *error )
4293 {
4294 --i; /*lint !e445*/
4295 for( ; i >= 0; --i) /*lint !e445*/
4296 {
4297 SCIPfreeBufferArray(scip, &((*consnames)[i]));
4298 }
4299 SCIPfreeBufferArray(scip, consnames);
4300 }
4301
4302 SCIPhashtableFree(&consfreq);
4303
4304 return SCIP_OKAY;
4305}
4306
4307/** returns whether to print an integrality constraint for the given variable */
4308static
4310 SCIP_VAR* var, /**< variable to check */
4311 int implintlevel /**< implied integral level */
4312 )
4313{
4314 assert(implintlevel >= -2);
4315 assert(implintlevel <= 2);
4316
4318 return (int)SCIPvarGetImplType(var) > 2 - implintlevel;
4319 else
4320 return (int)SCIPvarGetImplType(var) <= 2 + implintlevel;
4321}
4322
4323/** template implementation of mpsIntComp for given implied integral level */
4324#define MPSINTCOMP_LEVEL(IMPLINTLEVEL) \
4325{ \
4326 SCIP_Bool integral1 = writeVarIsIntegral((SCIP_VAR*)elem1, IMPLINTLEVEL); \
4327 SCIP_Bool integral2 = writeVarIsIntegral((SCIP_VAR*)elem2, IMPLINTLEVEL); \
4328 \
4329 if( integral1 != integral2 ) \
4330 return integral1 ? -1 : +1; \
4331 \
4332 return SCIPvarComp(elem1, elem2); \
4333}
4334
4335/* comparison methods for sorting variables along their original indices grouping integer variables at the front */
4337static SCIP_DECL_SORTPTRCOMP(mpsIntCompM1) MPSINTCOMP_LEVEL(-1)
4338static SCIP_DECL_SORTPTRCOMP(mpsIntCompZ) MPSINTCOMP_LEVEL(0)
4339static SCIP_DECL_SORTPTRCOMP(mpsIntCompP1) MPSINTCOMP_LEVEL(1)
4340static SCIP_DECL_SORTPTRCOMP(mpsIntCompP2) MPSINTCOMP_LEVEL(2)
4341
4342/** outputs the COLUMNS section of the MPS format */
4343static
4344void printColumnSection(
4345 SCIP* scip, /**< SCIP data structure */
4346 FILE* file, /**< output file, or NULL if standard output should be used */
4347 SPARSEMATRIX* matrix, /**< sparse matrix containing the entries */
4348 SCIP_HASHMAP* varnameHashmap, /**< map from SCIP_VAR* to variable name */
4349 SCIP_HASHTABLE* indicatorSlackHash, /**< hashtable containing slack variables from indicators (or NULL) */
4350 unsigned int maxnamelen, /**< maximum name length */
4351 int implintlevel /**< implied integral level */
4352 )
4353{
4354 SCIP_Bool intSection;
4355 SCIP_VAR* var;
4356 const char* varname;
4357 SCIP_Real value;
4358 int v;
4359 int recordcnt;
4360
4361 /* @todo: create column matrix instead of sort sparse entries */
4362 /* sort sparse matrix w.r.t. the written integralities and variable indices */
4363 switch( implintlevel )
4364 {
4365 case -2:
4366 SCIPsortPtrPtrReal((void**) matrix->columns, (void**) matrix->rows, matrix->values, mpsIntCompM2, matrix->nentries);
4367 break;
4368 case -1:
4369 SCIPsortPtrPtrReal((void**) matrix->columns, (void**) matrix->rows, matrix->values, mpsIntCompM1, matrix->nentries);
4370 break;
4371 case 0:
4372 SCIPsortPtrPtrReal((void**) matrix->columns, (void**) matrix->rows, matrix->values, mpsIntCompZ, matrix->nentries);
4373 break;
4374 case 1:
4375 SCIPsortPtrPtrReal((void**) matrix->columns, (void**) matrix->rows, matrix->values, mpsIntCompP1, matrix->nentries);
4376 break;
4377 case 2:
4378 SCIPsortPtrPtrReal((void**) matrix->columns, (void**) matrix->rows, matrix->values, mpsIntCompP2, matrix->nentries);
4379 break;
4380 default:
4381 SCIPerrorMessage("invalid implintlevel\n");
4382 SCIPABORT();
4383 }
4384
4385 /* print COLUMNS section */
4386 SCIPinfoMessage(scip, file, "COLUMNS\n");
4387
4388 intSection = FALSE;
4389
4390 for( v = 0; v < matrix->nentries; )
4391 {
4392 var = matrix->columns[v];
4393 assert( var != NULL );
4394
4395 /* skip slack variables in output */
4396 if( indicatorSlackHash != NULL && SCIPhashtableExists(indicatorSlackHash, var) )
4397 {
4398 ++v;
4399 continue;
4400 }
4401
4402 /* section integer variables */
4403 if( writeVarIsIntegral(var, implintlevel) != intSection )
4404 {
4405 /* end integer section in MPS format */
4406 if( intSection )
4407 {
4408 printStart(scip, file, "", "INTEND", (int) maxnamelen);
4409 printRecord(scip, file, "'MARKER'", "", maxnamelen);
4410 printRecord(scip, file, "'INTEND'", "", maxnamelen);
4411 SCIPinfoMessage(scip, file, "\n");
4412 intSection = FALSE;
4413 }
4414 /* start integer section in MPS format */
4415 else
4416 {
4417 printStart(scip, file, "", "INTSTART", (int) maxnamelen);
4418 printRecord(scip, file, "'MARKER'", "", maxnamelen);
4419 printRecord(scip, file, "'INTORG'", "", maxnamelen);
4420 SCIPinfoMessage(scip, file, "\n");
4421 intSection = TRUE;
4422 }
4423 }
4424
4425 SCIPdebugMsg(scip, "create entries for variable <%s>\n", SCIPvarGetName(var));
4426
4427 /* record count; there are at most two records per line */
4428 recordcnt = 0;
4429
4430 /* get variable name */
4431 assert ( SCIPhashmapExists(varnameHashmap, var) );
4432 varname = (const char*) SCIPhashmapGetImage(varnameHashmap, var);
4433
4434 /* output all entries of the same variable */
4435 do
4436 {
4437 value = matrix->values[v];
4438
4439 /* print record to file */
4440 printEntry(scip, file, varname, matrix->rows[v], value, &recordcnt, maxnamelen);
4441 v++;
4442 }
4443 while( v < matrix->nentries && var == matrix->columns[v] );
4444
4445 if( recordcnt == 1 )
4446 SCIPinfoMessage(scip, file, "\n");
4447 }
4448 /* end integer section, if the columns sections ends with integer variables */
4449 if( intSection )
4450 {
4451 /* end integer section in MPS format */
4452 printStart(scip, file, "", "INTEND", (int) maxnamelen);
4453 printRecord(scip, file, "'MARKER'", "", maxnamelen);
4454 printRecord(scip, file, "'INTEND'", "", maxnamelen);
4455 SCIPinfoMessage(scip, file, "\n");
4456 }
4457}
4458
4459/** outputs the right hand side section */
4460static
4462 SCIP* scip, /**< SCIP data structure */
4463 FILE* file, /**< output file, or NULL if standard output should be used */
4464 int nconss, /**< number of constraints */
4465 const char** consnames, /**< constraint names */
4466 SCIP_Real* rhss, /**< right hand side array */
4467 unsigned int maxnamelen, /**< maximum name length */
4468 SCIP_Real objoffset /**< objective offset */
4469 )
4470{
4471 int recordcnt = 0;
4472 int c;
4473
4474 assert( rhss != NULL );
4475
4476 SCIPinfoMessage(scip, file, "RHS\n");
4477 SCIPdebugMsg(scip, "start printing RHS section\n");
4478
4479 /* take care of the linear constraints */
4480 for( c = 0; c < nconss; ++c )
4481 {
4482 /* skip all constraints which have a right hand side of infinity */
4483 if( SCIPisInfinity(scip, rhss[c]) )
4484 continue;
4485
4486 assert(consnames[c] != NULL);
4487
4488 printEntry(scip, file, "RHS", consnames[c], rhss[c], &recordcnt, maxnamelen);
4489 }
4490
4491 if( ! SCIPisZero(scip, objoffset) )
4492 {
4493 /* write objective offset (-1 because it is moved to the rhs) */
4494 printEntry(scip, file, "RHS", "Obj", -objoffset, &recordcnt, maxnamelen);
4495 }
4496
4497 if( recordcnt == 1 )
4498 SCIPinfoMessage(scip, file, "\n");
4499}
4500
4501/** outputs the range section */
4502static
4504 SCIP* scip, /**< SCIP data structure */
4505 FILE* file, /**< output file, or NULL if standard output should be used */
4506 SCIP_CONS** conss, /**< constraint array */
4507 int nconss, /**< number of constraints */
4508 const char** consnames, /**< constraint names */
4509 SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
4510 unsigned int maxnamelen /**< maximum name length */
4511 )
4512{
4513 int c;
4514 int recordcnt = 0;
4515
4516 SCIP_CONSHDLR* conshdlr;
4517 const char* conshdlrname;
4518
4519 SCIP_CONS* cons;
4520 SCIP_Real lhs;
4521 SCIP_Real rhs;
4522
4523 SCIPinfoMessage(scip, file, "RANGES\n");
4524 SCIPdebugMsg(scip, "start printing RANGES section\n");
4525
4526 for( c = 0; c < nconss; ++c )
4527 {
4528 cons = conss[c];
4529 assert( cons != NULL);
4530
4531 /* in case the transformed problems is written only constraint are posted which are enabled in the current node;
4532 * the conss array should only contain relevant constraints
4533 */
4534 assert( !transformed || SCIPconsIsEnabled(cons) );
4535
4536 assert( consnames[c] != NULL );
4537
4538 conshdlr = SCIPconsGetHdlr(cons);
4539 assert( conshdlr != NULL );
4540
4541 conshdlrname = SCIPconshdlrGetName(conshdlr);
4542
4543 if( strcmp(conshdlrname, "linear") == 0 )
4544 {
4545 lhs = SCIPgetLhsLinear(scip, cons);
4546 rhs = SCIPgetRhsLinear(scip, cons);
4547 }
4548 else if( strcmp(conshdlrname, "varbound") == 0 )
4549 {
4550 lhs = SCIPgetLhsVarbound(scip, cons);
4551 rhs = SCIPgetRhsVarbound(scip, cons);
4552 }
4553 else
4554 continue;
4555
4556 if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && !SCIPisEQ(scip, rhs, lhs) )
4557 {
4558 assert( SCIPisGT(scip, rhs, lhs) );
4559 printEntry(scip, file, "RANGE", consnames[c], rhs - lhs, &recordcnt, maxnamelen);
4560 }
4561 }
4562 if(recordcnt == 1 )
4563 SCIPinfoMessage(scip, file, "\n");
4564}
4565
4566/** print bound section name */
4567static
4569 SCIP* scip, /**< SCIP data structure */
4570 FILE* file /**< output file, or NULL if standard output should be used */
4571 )
4572{
4573 SCIPinfoMessage(scip, file, "BOUNDS\n");
4574 SCIPdebugMsg(scip, "start printing BOUNDS section\n");
4575}
4576
4577/** output bound section */
4578static
4580 SCIP* scip, /**< SCIP data structure */
4581 FILE* file, /**< output file, or NULL if standard output should be used */
4582 SCIP_VAR** vars, /**< active variables */
4583 int nvars, /**< number of active variables */
4584 SCIP_VAR** aggvars, /**< needed aggregated variables */
4585 int naggvars, /**< number of aggregated variables */
4586 SCIP_VAR** fixvars, /**< all fixed variables (or NULL if nfixvars is 0) */
4587 int nfixvars, /**< number of fixed variables */
4588 SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
4589 const char** varnames, /**< array with variable names */
4590 SCIP_HASHTABLE* indicatorSlackHash, /**< hashtable containing slack variables from indicators (or NULL) */
4591 unsigned int maxnamelen /**< maximum name length */
4592 )
4593{
4594 int v;
4595 SCIP_VAR* var;
4596 SCIP_Real lb;
4597 SCIP_Real ub;
4598 SCIP_Bool sectionName;
4599 const char* varname;
4600 char valuestr[MPS_MAX_VALUELEN] = { '\0' };
4601
4602 assert(scip != NULL);
4603 assert(vars != NULL);
4604 assert(nfixvars == 0 || fixvars != NULL);
4605
4606 sectionName = FALSE;
4607
4608 /* output the active variables */
4609 for( v = 0; v < nvars; ++v )
4610 {
4611 var = vars[v];
4612 assert( var != NULL );
4613
4614 /* skip slack variables in output */
4615 if( indicatorSlackHash != NULL && SCIPhashtableExists(indicatorSlackHash, var) )
4616 continue;
4617
4618 /* get variable name */
4619 varname = varnames[v];
4620 assert(strncmp(varname, SCIPvarGetName(var), maxnamelen) == 0);
4621
4622 if( transformed )
4623 {
4624 /* in case the transformed is written only local bounds are posted
4625 * which are valid in the current node */
4626 lb = SCIPvarGetLbLocal(var);
4627 ub = SCIPvarGetUbLocal(var);
4628 }
4629 else
4630 {
4631 lb = SCIPvarGetLbOriginal(var);
4632 ub = SCIPvarGetUbOriginal(var);
4633 }
4634
4635 /* take care of binary variables */
4637 {
4638 if( !sectionName )
4639 {
4641 sectionName = TRUE;
4642 }
4643
4644 if( !SCIPisFeasZero(scip, lb) || !SCIPisFeasEQ(scip, ub, 1.0) )
4645 {
4646 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", lb);
4647 printStart(scip, file, "LO", "Bound", (int) maxnamelen);
4648 printRecord(scip, file, varname, valuestr, maxnamelen);
4649 SCIPinfoMessage(scip, file, "\n");
4650
4651 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", ub);
4652 printStart(scip, file, "UP", "Bound", (int) maxnamelen);
4653 printRecord(scip, file, varname, valuestr, maxnamelen);
4654 }
4655 else
4656 {
4657 printStart(scip, file, "BV", "Bound", (int) maxnamelen);
4658 printRecord(scip, file, varname, "", maxnamelen);
4659 }
4660 SCIPinfoMessage(scip, file, "\n");
4661
4662 continue;
4663 }
4664
4665 /* take care of free variables */
4666 if( SCIPisInfinity(scip, -lb) && SCIPisInfinity(scip, ub) )
4667 {
4668 if( !sectionName )
4669 {
4671 sectionName = TRUE;
4672 }
4673
4674 /* variable is free */
4675 printStart(scip, file, "FR", "Bound", (int) maxnamelen);
4676 printRecord(scip, file, varname, "", maxnamelen);
4677 SCIPinfoMessage(scip, file, "\n");
4678 continue;
4679 }
4680
4681 /* take care of fixed variables */
4682 if( SCIPisEQ(scip, lb, ub) )
4683 {
4684 if( !sectionName )
4685 {
4687 sectionName = TRUE;
4688 }
4689
4690 /* variable is fixed */
4691 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", lb);
4692 printStart(scip, file, "FX", "Bound", (int) maxnamelen);
4693 printRecord(scip, file, varname, valuestr, maxnamelen);
4694 SCIPinfoMessage(scip, file, "\n");
4695 continue;
4696 }
4697
4698 /* print lower bound */
4699 if( SCIPisInfinity(scip, -lb) )
4700 {
4701 if( !sectionName )
4702 {
4704 sectionName = TRUE;
4705 }
4706
4707 /* the free variables are processed above */
4708 assert( !SCIPisInfinity(scip, ub) );
4709 printStart(scip, file, "MI", "Bound", (int) maxnamelen);
4710 printRecord(scip, file, varname, "", maxnamelen);
4711 SCIPinfoMessage(scip, file, "\n");
4712 }
4713 else
4714 {
4715 if( SCIPisZero(scip, lb) )
4716 {
4717 lb = 0.0;
4718 }
4719 else
4720 {
4721 if( !sectionName )
4722 {
4724 sectionName = TRUE;
4725 }
4726
4727 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", lb);
4728 printStart(scip, file, "LO", "Bound", (int) maxnamelen);
4729 printRecord(scip, file, varname, valuestr, maxnamelen);
4730 SCIPinfoMessage(scip, file, "\n");
4731 }
4732 }
4733
4734 /* print upper bound, infinity has to be printed for integer (!) variables, because during
4735 * reading an mps file no upper bound of an integer variable means that the upper bound will
4736 * be set to 1 instead of +infinity (like it is for continuous variables) */
4737 if( SCIPisInfinity(scip, ub) )
4738 {
4739 if( !sectionName )
4740 {
4742 sectionName = TRUE;
4743 }
4744
4745 /* the free variables are processed above */
4746 assert( !SCIPisInfinity(scip, -lb) );
4747 printStart(scip, file, "PL", "Bound", (int) maxnamelen);
4748 printRecord(scip, file, varname, "", maxnamelen);
4749 SCIPinfoMessage(scip, file, "\n");
4750 }
4751 else
4752 {
4753 if( !sectionName )
4754 {
4756 sectionName = TRUE;
4757 }
4758
4759 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", ub);
4760 printStart(scip, file, "UP", "Bound", (int) maxnamelen);
4761 printRecord(scip, file, varname, valuestr, maxnamelen);
4762 SCIPinfoMessage(scip, file, "\n");
4763 }
4764 }
4765
4766 /* output aggregated variables as 'free', except if they are binary */
4767 for( v = 0; v < naggvars; ++v )
4768 {
4769 if( !sectionName )
4770 {
4772 sectionName = TRUE;
4773 }
4774
4775 var = aggvars[v];
4776 assert( var != NULL );
4777
4778 /* get variable name */
4779 varname = varnames[nvars + v];
4780 assert(strncmp(varname, SCIPvarGetName(var), maxnamelen) == 0);
4781
4782 /* take care of binary variables */
4784 {
4785 printStart(scip, file, "BV", "Bound", (int) maxnamelen);
4786 printRecord(scip, file, varname, "", maxnamelen);
4787 SCIPinfoMessage(scip, file, "\n");
4788 }
4789 else
4790 {
4791 /* variable is free */
4792 printStart(scip, file, "FR", "Bound", (int) maxnamelen);
4793 printRecord(scip, file, varname, "", maxnamelen);
4794 SCIPinfoMessage(scip, file, "\n");
4795 }
4796 }
4797
4798 /* output all fixed variables */
4799 for( v = 0; v < nfixvars; ++v )
4800 {
4801 /* we should print the transformed problem, otherwise no fixed variable should exists */
4802 assert(transformed);
4803 assert(fixvars != NULL && fixvars[v] != NULL);
4804
4805 var = fixvars[v];
4806
4807 assert(var != NULL);
4808 assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_FIXED);
4809
4810 /* get variable name */
4811 varname = varnames[nvars + naggvars + v];
4812 assert(strncmp(varname, SCIPvarGetName(var), maxnamelen) == 0);
4813
4814 /* only local bounds are posted which are valid in the current node */
4815 lb = SCIPvarGetLbLocal(var);
4816 ub = SCIPvarGetUbLocal(var);
4817 assert(SCIPisEQ(scip, lb, ub));
4818
4819 if( !sectionName )
4820 {
4822 sectionName = TRUE;
4823 }
4824
4825 /* print fixed variable */
4826 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", lb);
4827 printStart(scip, file, "FX", "Bound", (int) maxnamelen);
4828 printRecord(scip, file, varname, valuestr, maxnamelen);
4829 SCIPinfoMessage(scip, file, "\n");
4830 }
4831}
4832
4833
4834/*
4835 * Callback methods of reader
4836 */
4837
4838/** copy method for reader plugins (called when SCIP copies plugins) */
4839/**! [SnippetReaderCopyMps] */
4840static
4842{ /*lint --e{715}*/
4843 assert(scip != NULL);
4844 assert(reader != NULL);
4845 assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
4846
4847 /* call inclusion method of reader */
4849
4850 return SCIP_OKAY;
4851}
4852/**! [SnippetReaderCopyMps] */
4853
4854/** destructor of reader to free user data (called when SCIP is exiting) */
4855/**! [SnippetReaderFreeMps] */
4856static
4858{
4859 SCIP_READERDATA* readerdata;
4860
4861 assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
4862 readerdata = SCIPreaderGetData(reader);
4863 assert(readerdata != NULL);
4864 SCIPfreeBlockMemory(scip, &readerdata);
4865
4866 return SCIP_OKAY;
4867}
4868/**! [SnippetReaderFreeMps] */
4869
4870/** problem reading method of reader */
4871static
4873{ /*lint --e{715}*/
4874 assert(reader != NULL);
4875 assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
4876
4877 SCIP_CALL( SCIPreadMps(scip, reader, filename, result, NULL, NULL, NULL, NULL, NULL, NULL) );
4878
4879 return SCIP_OKAY;
4880}
4881
4882
4883/** problem writing method of reader */
4884static
4886{ /*lint --e{715}*/
4887 assert(reader != NULL);
4888 assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
4889
4890 if( SCIPisExact(scip) )
4891 {
4892 SCIPerrorMessage("MPS reader cannot yet write problems in exact solving mode\n");
4893 return SCIP_WRITEERROR;
4894 }
4895
4896 SCIP_CALL( SCIPwriteMps(scip, reader, file, name, transformed, objsense, objoffset, objscale, objoffsetexact, objscaleexact,
4897 vars, nvars, nbinvars, nintvars, nimplvars, ncontvars, fixedvars, nfixedvars, conss, nconss, result) );
4898
4899 return SCIP_OKAY;
4900}
4901
4902
4903/*
4904 * mps file reader specific interface methods
4905 */
4906
4907/** includes the mps file reader in SCIP */
4909 SCIP* scip /**< SCIP data structure */
4910 )
4911{
4912 SCIP_READERDATA* readerdata;
4913 SCIP_READER* reader;
4914
4915 /* create reader data */
4916 SCIP_CALL( SCIPallocBlockMemory(scip, &readerdata) );
4917
4918 /* include reader */
4920
4921 /* reader is safe to use in exact solving mode, but exact writing still needs to be implemented */
4922 SCIPreaderMarkExact(reader);
4923
4924 /* set non fundamental callbacks via setter functions */
4925 SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopyMps) );
4926 SCIP_CALL( SCIPsetReaderFree(scip, reader, readerFreeMps) );
4927 SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadMps) );
4928 SCIP_CALL( SCIPsetReaderWrite(scip, reader, readerWriteMps) );
4929
4930 /* add lp-reader parameters */
4932 "reading/" READER_NAME "/linearize-and-constraints",
4933 "should possible \"and\" constraint be linearized when writing the mps file?",
4934 &readerdata->linearizeands, TRUE, DEFAULT_LINEARIZE_ANDS, NULL, NULL) );
4936 "reading/" READER_NAME "/aggrlinearization-ands",
4937 "should an aggregated linearization for and constraints be used?",
4938 &readerdata->aggrlinearizationands, TRUE, DEFAULT_AGGRLINEARIZATION_ANDS, NULL, NULL) );
4939
4940 return SCIP_OKAY;
4941}
4942
4943
4944/** reads problem from file */
4946 SCIP* scip, /**< SCIP data structure */
4947 SCIP_READER* reader, /**< the file reader itself */
4948 const char* filename, /**< full path and name of file to read, or NULL if stdin should be used */
4949 SCIP_RESULT* result, /**< pointer to store the result of the file reading call */
4950 const char*** varnames, /**< storage for the variable names, or NULL */
4951 const char*** consnames, /**< storage for the constraint names, or NULL */
4952 int* varnamessize, /**< the size of the variable names storage, or NULL */
4953 int* consnamessize, /**< the size of the constraint names storage, or NULL */
4954 int* nvarnames, /**< the number of stored variable names, or NULL */
4955 int* nconsnames /**< the number of stored constraint names, or NULL */
4956 )
4957{
4958 SCIP_RETCODE retcode;
4959
4960 assert(reader != NULL);
4961 assert(scip != NULL);
4962 assert(result != NULL);
4963
4964 if( !SCIPisExact(scip) )
4965 retcode = readMps(scip, filename, varnames, consnames, varnamessize, consnamessize, nvarnames, nconsnames);
4966 else
4967 retcode = readMpsExact(scip, filename, varnames, consnames, varnamessize, consnamessize, nvarnames, nconsnames);
4968
4969 if( retcode == SCIP_PLUGINNOTFOUND )
4970 retcode = SCIP_READERROR;
4971
4972 if( retcode == SCIP_NOFILE || retcode == SCIP_READERROR )
4973 return retcode;
4974
4975 SCIP_CALL( retcode );
4976
4977 *result = SCIP_SUCCESS;
4978
4979 return SCIP_OKAY;
4980}
4981
4982/** writes problem to file */
4984 SCIP* scip, /**< SCIP data structure */
4985 SCIP_READER* reader, /**< the file reader itself */
4986 FILE* file, /**< output file, or NULL if standard output should be used */
4987 const char* name, /**< problem name */
4988 SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
4989 SCIP_OBJSENSE objsense, /**< objective sense */
4990 SCIP_Real objoffset, /**< objective offset from bound shifting and fixing */
4991 SCIP_Real objscale, /**< scalar applied to objective function; external objective value is
4992 * extobj = objsense * objscale * (intobj + objoffset) */
4993 SCIP_RATIONAL* objoffsetexact, /**< exact objective offset from bound shifting and fixing */
4994 SCIP_RATIONAL* objscaleexact, /**< exact scalar applied to objective function; external objective value is
4995 * extobjexact = objsense * objscaleexact * (intobjexact + objoffsetexact) */
4996 SCIP_VAR** vars, /**< array with active variables ordered binary, integer, implicit, continuous */
4997 int nvars, /**< number of active variables in the problem */
4998 int nbinvars, /**< number of binary variables */
4999 int nintvars, /**< number of general integer variables */
5000 int nimplvars, /**< number of implicit integer variables */
5001 int ncontvars, /**< number of continuous variables */
5002 SCIP_VAR** fixedvars, /**< array with fixed and aggregated variables */
5003 int nfixedvars, /**< number of fixed and aggregated variables in the problem */
5004 SCIP_CONS** conss, /**< array with constraints of the problem */
5005 int nconss, /**< number of constraints in the problem */
5006 SCIP_RESULT* result /**< pointer to store the result of the file writing call */
5007 )
5008{
5009 SCIP_READERDATA* readerdata;
5010 int naddrows;
5011 int faulty = 0;
5012 int c;
5013 int v;
5014 int k;
5015 char* namestr;
5016
5017 SCIP_CONS* cons = NULL;
5018 const char* consname;
5019 const char** consnames;
5020
5021 SCIP_CONSHDLR* conshdlr;
5022 const char* conshdlrname;
5023
5024 SCIP_Real lhs;
5025 SCIP_Real rhs;
5026 SCIP_Real* rhss;
5027 SCIP_Real value;
5028
5029 SCIP_VAR* var = NULL;
5030 const char* varname;
5031 const char** varnames;
5032
5033 char valuestr[MPS_MAX_VALUELEN] = { '\0' };
5034
5035 SCIP_CONS** consIndicator;
5036 SCIP_CONS** consSOS1;
5037 SCIP_CONS** consSOS2;
5038 SCIP_CONS** consQuadratic;
5039 SCIP_EXPR** exprQuadratic; /* expressions to quadratic constraints */
5040 int nConsIndicator;
5041 int nConsSOS1;
5042 int nConsSOS2;
5043 int nConsQuadratic;
5044
5045 SCIP_HASHMAP* varnameHashmap; /* hash map from SCIP_VAR* to variable name */
5046 SPARSEMATRIX* matrix;
5047
5048 SCIP_VAR** aggvars;
5049 int naggvars = 0;
5050 int saggvars;
5051 SCIP_HASHTABLE* varFixedHash;
5052 SCIP_HASHTABLE* indicatorSlackHash;
5053
5054 SCIP_VAR** fixvars = NULL;
5055 int nfixvars = 0;
5056
5057 SCIP_VAR** consvars;
5058 int nconsvars;
5059 SCIP_Real* vals;
5060 SCIP_Longint* weights;
5061
5062 SCIP_Bool needRANGES;
5063 unsigned int maxnamelen;
5064 int implintlevel;
5065
5066 SCIP_Bool error;
5067
5068 assert(reader != NULL);
5069 assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
5070 assert(scip != NULL);
5071 assert(result != NULL);
5072
5073 /* get implied integral level for writeVarIsIntegral() and printColumnSection() */
5074 SCIP_CALL( SCIPgetIntParam(scip, "write/implintlevel", &implintlevel) );
5075
5076 /**@todo write exact offset */
5077 if( objoffsetexact != NULL )
5078 {
5079 assert(SCIPisExact(scip));
5080 objoffset = SCIPrationalGetReal(objoffsetexact);
5081 }
5082
5083 /**@todo write exact scale */
5084 if( objscaleexact != NULL )
5085 {
5086 assert(SCIPisExact(scip));
5087 objscale = SCIPrationalGetReal(objscaleexact);
5088 }
5089
5090 needRANGES = FALSE;
5091 maxnamelen = 0;
5092 nConsSOS1 = 0;
5093 nConsSOS2 = 0;
5094 nConsQuadratic = 0;
5095 nConsIndicator = 0;
5096
5097 /* check if the constraint names are too long and build the constraint names */
5098 SCIP_CALL( checkConsnames(scip, conss, nconss, transformed, &maxnamelen, &consnames, &error) );
5099 if( error )
5100 {
5101 /* call writing with generic names */
5102 if( transformed )
5103 {
5104 SCIPwarningMessage(scip, "write transformed problem with generic variable and constraint names\n");
5105 SCIP_CALL( SCIPprintTransProblem(scip, file, "mps", TRUE) );
5106 }
5107 else
5108 {
5109 SCIPwarningMessage(scip, "write original problem with generic variable and constraint names\n");
5110 SCIP_CALL( SCIPprintOrigProblem(scip, file, "mps", TRUE) );
5111 }
5112 *result = SCIP_SUCCESS;
5113
5114 return SCIP_OKAY;
5115 }
5116
5117 /* check if the variable names are not too long and build the "variable" -> "variable name" hash map */
5118 SCIP_CALL( checkVarnames(scip, vars, nvars, &maxnamelen, &varnames, &varnameHashmap) );
5119
5120 /* collect SOS, quadratic, and indicator constraints in array for later output */
5121 SCIP_CALL( SCIPallocBufferArray(scip, &consSOS1, nconss) );
5122 SCIP_CALL( SCIPallocBufferArray(scip, &consSOS2, nconss) );
5123 SCIP_CALL( SCIPallocBufferArray(scip, &consQuadratic, nconss) );
5124 SCIP_CALL( SCIPallocBufferArray(scip, &exprQuadratic, nconss) );
5125 SCIP_CALL( SCIPallocBufferArray(scip, &consIndicator, nconss) );
5126
5127 /* nfixedvars counts all variables with status SCIP_VARSTATUS_FIXED, SCIP_VARSTATUS_AGGREGATED, SCIP_VARSTATUS_MULTAGGR, but not SCIP_VARSTATUS_NEGATED */
5128 saggvars = nfixedvars;
5129 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &aggvars, saggvars) );
5130
5131 /* create hashtable for storing aggregated variables */
5132 if( nfixedvars > 0 )
5133 {
5134 SCIP_CALL( SCIPhashtableCreate(&varFixedHash, SCIPblkmem(scip), nfixedvars, hashGetKeyVar, hashKeyEqVar, hashKeyValVar, NULL) );
5135 }
5136 else
5137 varFixedHash = NULL;
5138
5139 if( nvars > 0 )
5140 {
5141 SCIP_CALL( SCIPhashtableCreate(&indicatorSlackHash, SCIPblkmem(scip), nvars, hashGetKeyVar, hashKeyEqVar, hashKeyValVar, NULL) );
5142 }
5143 else
5144 indicatorSlackHash = NULL;
5145
5146 /* initialize sparse matrix */
5147 SCIP_CALL( initializeMatrix(scip, &matrix, (nvars * 2 + nfixedvars)) );
5148 assert( matrix->sentries >= nvars );
5149
5150 readerdata = SCIPreaderGetData(reader);
5151 assert(readerdata != NULL);
5152
5153 naddrows = 0;
5154
5155 /* determine and-constraints and printing format to resize necessary arrays */
5156 if( readerdata->linearizeands )
5157 {
5158 SCIP_CONSHDLR* andconshdlr = SCIPfindConshdlr(scip, "and");
5159
5160 if( andconshdlr != NULL )
5161 {
5162 /* need to check for and-constraints, note that in the original problem you cannot get the number of
5163 * and-constraints by one call */
5164 for( c = nconss - 1; c >= 0; --c )
5165 {
5166 conshdlr = SCIPconsGetHdlr(conss[c]);
5167 assert(conshdlr != NULL);
5168
5169 conshdlrname = SCIPconshdlrGetName(conshdlr);
5170
5171 if( strcmp(conshdlrname, "and") == 0 )
5172 {
5173 if( readerdata->aggrlinearizationands )
5174 ++naddrows;
5175 else
5176 naddrows += SCIPgetNVarsAnd(scip, conss[c]);
5177 }
5178 }
5179 assert(naddrows >= 0);
5180
5181 if( naddrows > 0 )
5182 {
5183 /* resize consnames vector */
5184 SCIP_CALL( SCIPreallocBufferArray(scip, &consnames, nconss + naddrows) );
5185 }
5186 }
5187 }
5188
5189 /* initialize rhs vector */
5190 SCIP_CALL( SCIPallocBufferArray(scip, &rhss, nconss + naddrows) );
5191
5192 /* print statistics as comment to file stream */
5193 SCIPinfoMessage(scip, file, "* SCIP STATISTICS\n");
5194 SCIPinfoMessage(scip, file, "* Problem name : %s\n", name);
5195 SCIPinfoMessage(scip, file, "* Variables : %d (%d binary, %d integer, %d implicit integer, %d continuous)\n",
5196 nvars, nbinvars, nintvars, nimplvars, ncontvars);
5197 SCIPinfoMessage(scip, file, "* Constraints : %d\n", nconss);
5198
5199 /* print NAME of the problem */
5200 SCIPinfoMessage(scip, file, "%-14s%s\n", "NAME", name);
5201
5202 /* print OBJSENSE of the problem */
5203 SCIPinfoMessage(scip, file, "OBJSENSE\n");
5204 SCIPinfoMessage(scip, file, "%s\n", objsense == SCIP_OBJSENSE_MAXIMIZE ? " MAX" : " MIN");
5205
5206 /* start ROWS section */
5207 SCIPinfoMessage(scip, file, "ROWS\n");
5208
5209 /* print row type for the objective function */
5210 printStart(scip, file, "N", "Obj", -1);
5211 SCIPinfoMessage(scip, file, "\n");
5212
5213 /* first fill the matrix with the objective coefficients */
5214 for( v = 0; v < nvars; ++v )
5215 {
5216 /* take care of the objective entry */
5217 var = vars[v];
5218 value = SCIPvarGetObj(var);
5219
5220 /* @todo: only add entry for empty column */
5221 /* we also want to add integer variables to the columns section, even if the objective value is 0, because it
5222 * might happen that they only exist in non-linear constraints, which leads to no other line in the column section
5223 * and therefore do not mark the variable as an integer
5224 */
5225 if( !SCIPisZero(scip, value) || writeVarIsIntegral(var, implintlevel)
5228 {
5229 assert( matrix->nentries < matrix->sentries );
5230
5231 matrix->values[matrix->nentries] = objscale * value;
5232 matrix->columns[matrix->nentries] = var;
5233 matrix->rows[matrix->nentries] = "Obj";
5234 matrix->nentries++;
5235 }
5236 }
5237
5238 /* loop over all constraints */
5239 k = nconss;
5240 for( c = 0; c < nconss; ++c )
5241 {
5242 cons = conss[c];
5243 assert( cons != NULL);
5244
5245 /* in case the transformed problems is written only constraint are posted which are enabled in the current node;
5246 * the conss array should only contain relevant constraints
5247 */
5248 assert( !transformed || SCIPconsIsEnabled(cons) );
5249
5250 conshdlr = SCIPconsGetHdlr(cons);
5251 assert( conshdlr != NULL );
5252
5253 conshdlrname = SCIPconshdlrGetName(conshdlr);
5254
5255 /* construct constraint name */
5256 consname = consnames[c];
5257
5258 /* init rhs value to infinity (would then ignored) */
5259 rhss[c] = SCIPinfinity(scip);
5260
5261 if( strcmp(conshdlrname, "linear") == 0 )
5262 {
5263 lhs = SCIPgetLhsLinear(scip, cons);
5264 rhs = SCIPgetRhsLinear(scip, cons);
5265
5266 /* there is nothing to do if the left hand side is minus infinity and the right side is infinity */
5267 if( !SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs) )
5268 {
5269 if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && !SCIPisEQ(scip, lhs, rhs) )
5270 needRANGES = TRUE;
5271
5272 /* print row entry */
5273 printRowType(scip, file, lhs, rhs, consname);
5274
5275 if( SCIPisInfinity(scip, rhs) )
5276 rhss[c] = lhs;
5277 else
5278 rhss[c] = rhs;
5279
5280 assert( !SCIPisInfinity(scip, rhss[c]) );
5281
5282 /* compute column entries */
5284 SCIPgetNVarsLinear(scip, cons), transformed, matrix, &rhss[c]) );
5285 }
5286 }
5287 else if( strcmp(conshdlrname, "setppc") == 0 )
5288 {
5289 /* print row entry */
5290 switch( SCIPgetTypeSetppc(scip, cons) )
5291 {
5293 printRowType(scip, file, 1.0, 1.0, consname);
5294 break;
5296 printRowType(scip, file, -SCIPinfinity(scip), 1.0, consname);
5297 break;
5300 break;
5301 }
5302
5303 rhss[c] = 1.0;
5304
5305 /* compute column entries */
5306 SCIP_CALL( getLinearCoeffs(scip, consname, SCIPgetVarsSetppc(scip, cons), NULL, SCIPgetNVarsSetppc(scip, cons), transformed, matrix, &rhss[c]) );
5307 }
5308 else if( strcmp(conshdlrname, "logicor") == 0 )
5309 {
5310 /* print row entry */
5312
5313 rhss[c] = 1.0;
5314
5315 /* compute column entries */
5316 SCIP_CALL( getLinearCoeffs(scip, consname, SCIPgetVarsLogicor(scip, cons), NULL, SCIPgetNVarsLogicor(scip, cons), transformed, matrix, &rhss[c]) );
5317 }
5318 else if( strcmp(conshdlrname, "knapsack") == 0 )
5319 {
5320 int i;
5321
5322 /* print row entry */
5324
5325 nconsvars = SCIPgetNVarsKnapsack(scip, cons);
5326 weights = SCIPgetWeightsKnapsack(scip, cons);
5327
5328 /* copy Longint array to SCIP_Real array */
5329 SCIP_CALL( SCIPallocBufferArray(scip, &vals, nconsvars ) );
5330 for( i = 0; i < nconsvars; ++i )
5331 vals[i] = (SCIP_Real)weights[i];
5332
5333 rhss[c] = (SCIP_Real) SCIPgetCapacityKnapsack(scip, cons);
5334
5335 /* compute column entries */
5336 SCIP_CALL( getLinearCoeffs(scip, consname, SCIPgetVarsKnapsack(scip, cons), vals, nconsvars, transformed, matrix, &rhss[c]) );
5337
5338 SCIPfreeBufferArray(scip, &vals);
5339 }
5340 else if( strcmp(conshdlrname, "varbound") == 0 )
5341 {
5342 lhs = SCIPgetLhsVarbound(scip, cons);
5343 rhs = SCIPgetRhsVarbound(scip, cons);
5344
5345 /* there is nothing to do if the left hand side is minus infinity and the right side is infinity */
5346 if( !SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs) )
5347 {
5348 if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && !SCIPisEQ(scip, lhs, rhs) )
5349 needRANGES = TRUE;
5350
5351 /* print row entry */
5352 printRowType(scip, file, lhs, rhs, consname);
5353
5354 /* allocate memory */
5355 SCIP_CALL( SCIPallocBufferArray(scip, &consvars, 2) );
5356 SCIP_CALL( SCIPallocBufferArray(scip, &vals, 2) );
5357
5358 consvars[0] = SCIPgetVarVarbound(scip, cons);
5359 consvars[1] = SCIPgetVbdvarVarbound(scip, cons);
5360
5361 vals[0] = 1.0;
5362 vals[1] = SCIPgetVbdcoefVarbound(scip, cons);
5363
5364 if( SCIPisInfinity(scip, rhs) )
5365 rhss[c] = lhs;
5366 else
5367 rhss[c] = rhs;
5368
5369 assert( !SCIPisInfinity(scip, rhss[c]) );
5370
5371 /* compute column entries */
5372 SCIP_CALL( getLinearCoeffs(scip, consname, consvars, vals, 2, transformed, matrix, &rhss[c]) );
5373
5374 SCIPfreeBufferArray(scip, &vals);
5375 SCIPfreeBufferArray(scip, &consvars);
5376 }
5377 }
5378 else if( strcmp(conshdlrname, "indicator") == 0 )
5379 {
5380 SCIP_VAR* slackvar;
5381 SCIP_VAR* binvar;
5382
5383 /* store slack variable in hash */
5384 slackvar = SCIPgetSlackVarIndicator(cons);
5385 assert( slackvar != NULL );
5386 assert( indicatorSlackHash != NULL );
5387 assert( !SCIPhashtableExists(indicatorSlackHash, (void*) slackvar) );
5388 SCIP_CALL( SCIPhashtableInsert(indicatorSlackHash, (void*) slackvar) );
5389
5390 /* if slackvariable is aggregated, we store it in the list of aggregated variables */
5392 {
5393 SCIP_CALL( collectAggregatedVars(scip, &slackvar, 1, &aggvars, &naggvars, &saggvars, varFixedHash) );
5394 }
5395
5396 /* store aggregated variables */
5397 binvar = SCIPgetBinaryVarIndicator(cons);
5398 if( SCIPvarIsNegated(binvar) )
5399 binvar = SCIPvarGetNegatedVar(binvar);
5400 assert( binvar != NULL );
5401 SCIP_CALL( collectAggregatedVars(scip, &binvar, 1, &aggvars, &naggvars, &saggvars, varFixedHash) );
5402
5403 /* indicator constraint do not have a right hand side; mark this with SCIPinfinity(scip) */
5404 rhss[c] = SCIPinfinity(scip);
5405
5406 /* store constraint */
5407 consIndicator[nConsIndicator++] = cons;
5408 continue;
5409 }
5410 else if( strcmp(conshdlrname, "SOS1") == 0 )
5411 {
5412 /* store constraint */
5413 consSOS1[nConsSOS1++] = cons;
5414
5415 /* check for aggregated variables in SOS1 constraints for later output
5416 * of aggregations as linear constraints */
5417 consvars = SCIPgetVarsSOS1(scip, cons);
5418 nconsvars = SCIPgetNVarsSOS1(scip, cons);
5419
5420 /* SOS constraint do not have a right hand side; mark this with SCIPinfinity(scip) */
5421 rhss[c] = SCIPinfinity(scip);
5422
5423 SCIP_CALL( collectAggregatedVars(scip, consvars, nconsvars, &aggvars, &naggvars, &saggvars, varFixedHash) );
5424 }
5425 else if( strcmp(conshdlrname, "SOS2") == 0 )
5426 {
5427 /* store constraint */
5428 consSOS2[nConsSOS2++] = cons;
5429
5430 /* check for aggregated variables in SOS2 constraints for later output aggregations as linear constraints */
5431 consvars = SCIPgetVarsSOS2(scip, cons);
5432 nconsvars = SCIPgetNVarsSOS2(scip, cons);
5433
5434 /* SOS constraint do not have a right hand side; mark this with SCIPinfinity(scip) */
5435 rhss[c] = SCIPinfinity(scip);
5436
5437 SCIP_CALL( collectAggregatedVars(scip, consvars, nconsvars, &aggvars, &naggvars, &saggvars, varFixedHash) );
5438 }
5439 else if( strcmp(conshdlrname, "nonlinear") == 0 )
5440 {
5441 SCIP_EXPR* expr;
5442 SCIP_VAR** quadvars;
5443 SCIP_Real* quadvarlincoefs;
5444 SCIP_Real* lincoefs;
5445 SCIP_Real constant;
5446 SCIP_EXPR** linexprs;
5447 SCIP_Bool isquadratic;
5448 int nquadexprs;
5449 int nlinexprs;
5450 int j;
5451
5452 /* check if it is a quadratic constraint */
5453 expr = SCIPgetExprNonlinear(cons);
5454 SCIP_CALL( SCIPcheckExprQuadratic(scip, expr, &isquadratic) );
5455 if( !isquadratic || !SCIPexprAreQuadraticExprsVariables(expr) )
5456 {
5457 SCIP_EXPR* exprcopy;
5458 SCIP_Bool changed;
5459 SCIP_Bool infeasible;
5460
5461 SCIP_CALL( SCIPduplicateExpr(scip, expr, &exprcopy, NULL, NULL, NULL, NULL) );
5462 SCIP_CALL( SCIPsimplifyExpr(scip, exprcopy, &expr, &changed, &infeasible, NULL, NULL) );
5463 SCIP_CALL( SCIPreleaseExpr(scip, &exprcopy) );
5464 /* the corresponding releaseExpr is in the writing of the QCMATRIX sections at the end */
5465 if( changed && !infeasible )
5466 {
5467 SCIP_CALL( SCIPcheckExprQuadratic(scip, expr, &isquadratic) );
5468 isquadratic &= SCIPexprAreQuadraticExprsVariables(expr);
5469 }
5470 }
5471
5472 if( !isquadratic )
5473 {
5474 /* unknown constraint type; mark this with SCIPinfinity(scip) */
5475 rhss[c] = SCIPinfinity(scip);
5476
5477 SCIPwarningMessage(scip, "nonlinear constraint <%s> not recognized as quadratic: cannot print as MPS\n", SCIPconsGetName(cons));
5478 if( expr != SCIPgetExprNonlinear(cons) )
5479 {
5480 SCIP_CALL( SCIPreleaseExpr(scip, &expr) );
5481 }
5482 continue;
5483 }
5484
5485 /* store constraint and corresponding expression (may be the simplified one) */
5486 consQuadratic[nConsQuadratic] = cons;
5487 exprQuadratic[nConsQuadratic] = expr;
5488 ++nConsQuadratic;
5489
5490 /* collect linear coefficients of quadratic part */
5491 SCIPexprGetQuadraticData(expr, &constant, &nlinexprs, &linexprs, &lincoefs, &nquadexprs, NULL, NULL,
5492 NULL);
5493
5494 SCIP_CALL( SCIPallocBufferArray(scip, &quadvars, nquadexprs) );
5495 SCIP_CALL( SCIPallocBufferArray(scip, &quadvarlincoefs, nquadexprs) );
5496 for( j = 0; j < nquadexprs; ++j )
5497 {
5498 SCIP_EXPR* qexpr;
5499
5500 SCIPexprGetQuadraticQuadTerm(expr, j, &qexpr, &quadvarlincoefs[j], NULL, NULL, NULL, NULL);
5501
5502 assert(SCIPisExprVar(scip, qexpr));
5503 quadvars[j] = SCIPgetVarExprVar(qexpr);
5504 }
5505
5506 lhs = SCIPgetLhsNonlinear(cons);
5507 rhs = SCIPgetRhsNonlinear(cons);
5508
5509 /* correct side by constant */
5510 lhs -= SCIPisInfinity(scip, -lhs) ? 0.0 : constant;
5511 rhs -= SCIPisInfinity(scip, rhs) ? 0.0 : constant;
5512
5513 /* there is nothing to do if the left hand side is minus infinity and the right side is infinity */
5514 if( !SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs) )
5515 {
5516 SCIP_VAR** linvars;
5517
5518 if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && !SCIPisEQ(scip, lhs, rhs) )
5519 needRANGES = TRUE;
5520
5521 /* print row entry */
5522 printRowType(scip, file, lhs, rhs, consname);
5523
5524 if( SCIPisInfinity(scip, rhs) )
5525 rhss[c] = lhs;
5526 else
5527 rhss[c] = rhs;
5528
5529 assert( !SCIPisInfinity(scip, rhss[c]) );
5530
5531 /* get linear vars */
5532 SCIP_CALL( SCIPallocBufferArray(scip, &linvars, nlinexprs) );
5533 for( j = 0; j < nlinexprs; ++j )
5534 linvars[j] = SCIPgetVarExprVar(linexprs[j]);
5535
5536 /* compute column entries for linear part */
5537 SCIP_CALL( getLinearCoeffs(scip, consname, linvars, lincoefs, nlinexprs, transformed, matrix, &rhss[c]) );
5538
5539 /* compute column entries for linear part in quadratic part */
5540 SCIP_CALL( getLinearCoeffs(scip, consname, quadvars, quadvarlincoefs, nquadexprs, transformed, matrix,
5541 &rhss[c]) );
5542
5543 SCIPfreeBufferArray(scip, &linvars);
5544 }
5545
5546 /* check for aggregated variables in quadratic part of quadratic constraints for later output of
5547 * aggregations as linear constraints */
5548 consvars = quadvars;
5549 nconsvars = nquadexprs;
5550
5551 SCIP_CALL( collectAggregatedVars(scip, consvars, nconsvars, &aggvars, &naggvars, &saggvars, varFixedHash) );
5552
5553 SCIPfreeBufferArray(scip, &quadvars);
5554 SCIPfreeBufferArray(scip, &quadvarlincoefs);
5555 }
5556 else if( strcmp(conshdlrname, "and") == 0 )
5557 {
5558 if( readerdata->linearizeands )
5559 {
5560 SCIP_VAR** rowvars;
5561 SCIP_VAR** operands;
5562 SCIP_VAR* resultant;
5563 SCIP_Real* rowvals;
5564 char* rowname;
5565 int nrowvars;
5566 int l;
5567 int n;
5568
5569 nrowvars = SCIPgetNVarsAnd(scip, cons);
5570 operands = SCIPgetVarsAnd(scip, cons);
5571 resultant = SCIPgetResultantAnd(scip, cons);
5572
5573 /* allocate buffer array */
5574 SCIP_CALL( SCIPallocBufferArray(scip, &rowvars, nrowvars + 1) );
5575 SCIP_CALL( SCIPallocBufferArray(scip, &rowvals, nrowvars + 1) );
5576
5577 /* get length of constraint name */
5578 l = (int) strlen(consname);
5579
5580 /* the tight relaxtion, number of and-constraint operands rows */
5581 if( !readerdata->aggrlinearizationands )
5582 {
5583 rowvars[0] = resultant;
5584 rowvals[0] = 1.0;
5585 rowvals[1] = -1.0;
5586
5587 /* compute maximal length for rowname */
5588 /* coverity[negative_returns] */
5589 n = (int) log10((double)nrowvars) + 1 + l;
5590
5591 /* assure maximal allowed value */
5592 if( n >= MPS_MAX_NAMELEN )
5593 n = MPS_MAX_NAMELEN - 1;
5594
5595 /* update maxnamelen */
5596 maxnamelen = MAX(maxnamelen, (unsigned int) n);
5597
5598 /* print operator rows */
5599 for( v = 0; v < nrowvars; ++v )
5600 {
5601 /* compute maximal length for rowname */
5602 if( v == 0 )
5603 n = 2;
5604 else
5605 n = (int) log10((double)v) + 2;
5606 n += l;
5607
5608 /* assure maximal allowed value */
5609 if( n >= MPS_MAX_NAMELEN )
5610 {
5611 n = MPS_MAX_NAMELEN - 1;
5612 ++faulty;
5613 }
5614
5615 /* need memory for additional row */
5616 SCIP_CALL( SCIPallocBufferArray(scip, &rowname, n + 1) );
5617
5618 assert(k < nconss + naddrows);
5619 consnames[k] = rowname;
5620
5621 (void) SCIPsnprintf(rowname, n + 1, "%s_%d", consname, v);
5622 rowvars[1] = operands[v];
5623
5624 /* print row entry */
5625 printRowType(scip, file, -SCIPinfinity(scip), 0.0, rowname);
5626
5627 rhss[k] = 0.0;
5628
5629 /* compute column entries */
5630 SCIP_CALL( getLinearCoeffs(scip, rowname, rowvars, rowvals, 2, transformed, matrix, &rhss[k]) );
5631 ++k;
5632 }
5633 }
5634
5635 /* prepare for next row */
5636 for( v = nrowvars - 1; v >= 0; --v )
5637 {
5638 rowvars[v] = operands[v];
5639 rowvals[v] = -1.0;
5640 }
5641
5642 rowvars[nrowvars] = resultant;
5643
5644 /* the weak relaxtion, only one constraint */
5645 if( readerdata->aggrlinearizationands )
5646 {
5647 /* compute maximal length for rowname */
5648 n = l + 3;
5649
5650 /* assure maximal allowed value */
5651 if( n >= MPS_MAX_NAMELEN )
5652 {
5653 n = MPS_MAX_NAMELEN - 1;
5654 ++faulty;
5655 }
5656
5657 /* update maxnamelen */
5658 maxnamelen = MAX(maxnamelen, (unsigned int) n);
5659
5660 /* need memory for additional row */
5661 SCIP_CALL( SCIPallocBufferArray(scip, &rowname, n + 1) );
5662
5663 assert(k < nconss + naddrows);
5664 consnames[k] = rowname;
5665
5666 /* adjust rowname of constraint */
5667 (void) SCIPsnprintf(rowname, n + 1, "%s_op", consname);
5668
5669 rowvals[nrowvars] = (SCIP_Real) nrowvars;
5670
5671 /* print row entry */
5672 printRowType(scip, file, -SCIPinfinity(scip), 0.0, rowname);
5673
5674 rhss[k] = 0.0;
5675
5676 /* compute column entries */
5677 SCIP_CALL( getLinearCoeffs(scip, rowname, rowvars, rowvals, nrowvars + 1, transformed, matrix, &rhss[k]) );
5678
5679 SCIPdebugMsg(scip, "%g, %g\n", rowvals[1], rhss[k]);
5680 ++k;
5681 }
5682
5683 rowvals[nrowvars] = 1.0;
5684
5685 /* print row entry */
5686 printRowType(scip, file, -nrowvars + 1.0, SCIPinfinity(scip), consname);
5687
5688 rhss[c] = -nrowvars + 1.0;
5689
5690 /* compute column entries */
5691 SCIP_CALL( getLinearCoeffs(scip, consname, rowvars, rowvals, nrowvars + 1, transformed, matrix, &rhss[c]) );
5692
5693 /* free buffer array */
5694 SCIPfreeBufferArray(scip, &rowvals);
5695 SCIPfreeBufferArray(scip, &rowvars);
5696 }
5697 else
5698 {
5699 /* and constraint printing not enabled; mark this with SCIPinfinity(scip) */
5700 rhss[c] = SCIPinfinity(scip);
5701
5702 SCIPwarningMessage(scip, "change parameter \"reading/" READER_NAME "/linearize-and-constraints\" to TRUE to print and-constraints\n");
5703 }
5704 }
5705 else
5706 {
5707 /* unknown constraint type; mark this with SCIPinfinity(scip) */
5708 rhss[c] = SCIPinfinity(scip);
5709
5710 SCIPwarningMessage(scip, "constraint handler <%s> cannot print requested format\n", conshdlrname );
5711 }
5712 }
5713
5714 if( faulty > 0 )
5715 {
5716 SCIPwarningMessage(scip, "there are %d and-constraint-rownames which have to be cut down to %d characters; MPS file might be corrupted\n",
5717 faulty, MPS_MAX_NAMELEN - 1);
5718 }
5719
5720 /* free hash table */
5721 if( varFixedHash != NULL )
5722 SCIPhashtableFree(&varFixedHash);
5723
5724 if( indicatorSlackHash != NULL && nConsIndicator == 0 )
5725 {
5726 SCIPhashtableFree(&indicatorSlackHash);
5727 assert( indicatorSlackHash == NULL );
5728 }
5729
5730 if( naggvars > 0 )
5731 {
5732 /* construct variables name of the needed aggregated variables and the constraint names for the aggregation constraints */
5733
5734 /* realloc memory */
5735 SCIP_CALL( SCIPreallocBufferArray(scip, &consnames, nconss + naddrows + naggvars) );
5736 SCIP_CALL( SCIPreallocBufferArray(scip, &rhss, nconss + naddrows + naggvars) );
5737 SCIP_CALL( SCIPreallocBufferArray(scip, &varnames, nvars + naggvars) );
5738
5739 for( c = 0; c < naggvars; ++c )
5740 {
5741 size_t l;
5742
5743 /* create variable name */
5744 var = aggvars[c];
5745
5746 l = strlen(SCIPvarGetName(var));
5747 if( l >= MPS_MAX_NAMELEN )
5748 maxnamelen = MPS_MAX_NAMELEN - 1;
5749 else
5750 maxnamelen = MAX(maxnamelen, (unsigned int) l);
5751
5753 (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
5754
5755 /* insert variable with variable name into hash map */
5756 varnames[nvars + c] = namestr;
5757 assert( !SCIPhashmapExists(varnameHashmap, var) );
5758 SCIP_CALL( SCIPhashmapInsert(varnameHashmap, var, (void*) namestr) );
5759
5760 /* output row type (it is an equation) */
5761 SCIP_CALL( SCIPallocBufferArray(scip, &namestr, MPS_MAX_NAMELEN) ); /* note that namestr above is freed via varnames */
5762 (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "aggr_%s", SCIPvarGetName(var));
5763 printRowType(scip, file, 1.0, 1.0, namestr);
5764
5765 l = strlen(namestr);
5766 maxnamelen = MAX(maxnamelen, (unsigned int) l);
5767 consnames[nconss + naddrows + c] = namestr;
5768 rhss[nconss + naddrows + c] = 0.0;
5769
5770 /* compute column entries */
5771 SCIP_CALL( getLinearCoeffs(scip, namestr, &(aggvars[c]), NULL, 1, transformed, matrix, &rhss[nconss + naddrows + c]) );
5772
5773 /* add the aggregated variables to the sparse matrix */
5775 matrix->values[matrix->nentries] = -1.0;
5776 matrix->columns[matrix->nentries] = aggvars[c];
5777 matrix->rows[matrix->nentries] = namestr;
5778 matrix->nentries++;
5779 }
5780 }
5781
5782 /* collect also fixed variables, because they might not be removed from all constraints */
5783 /* @todo only collect fixed variables in the non-linear constraint types, where they (could not be)/(were not) removed */
5784 if( nfixedvars > 0 )
5785 {
5786 int startpos = nvars + naggvars;
5787 /* construct variables name of fixed variables */
5788
5789 /* realloc memory */
5790 SCIP_CALL( SCIPreallocBufferArray(scip, &varnames, startpos + nfixedvars) );
5791
5792 /* allocate memory for fixed variables */
5793 SCIP_CALL( SCIPallocBufferArray(scip, &fixvars, nfixedvars) );
5794
5795 for( v = nfixedvars - 1; v >= 0; --v )
5796 {
5797 /* create variable name */
5798 var = fixedvars[v];
5799
5801 {
5802 size_t l;
5803 l = strlen(SCIPvarGetName(var));
5804 if( l >= MPS_MAX_NAMELEN )
5805 maxnamelen = MPS_MAX_NAMELEN - 1;
5806 else
5807 maxnamelen = MAX(maxnamelen, (unsigned int) l);
5808
5810 (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
5811
5812 varnames[startpos + nfixvars] = namestr;
5813 fixvars[nfixvars] = var;
5814 ++nfixvars;
5815
5816 /* insert variable with variable name into hash map */
5817 assert(!SCIPhashmapExists(varnameHashmap, var));
5818 SCIP_CALL( SCIPhashmapInsert(varnameHashmap, var, (void*) namestr) );
5819
5820 /* add the fixed variables to the sparse matrix, needed for columns section */
5822 matrix->values[matrix->nentries] = 0.0;
5823 matrix->columns[matrix->nentries] = var;
5824 matrix->rows[matrix->nentries] = "Obj";
5825 matrix->nentries++;
5826 }
5827 }
5828 }
5829
5830 /* output COLUMNS section */
5831 printColumnSection(scip, file, matrix, varnameHashmap, indicatorSlackHash, maxnamelen, implintlevel);
5832
5833 /* output RHS section */
5834 printRhsSection(scip, file, nconss + naddrows +naggvars, consnames, rhss, maxnamelen, objscale * objoffset);
5835
5836 /* output RANGES section */
5837 if( needRANGES )
5838 printRangeSection(scip, file, conss, nconss, consnames, transformed, maxnamelen);
5839
5840 /* output BOUNDS section */
5841 printBoundSection(scip, file, vars, nvars, aggvars, naggvars, fixvars, nfixvars, transformed, varnames, indicatorSlackHash, maxnamelen);
5842
5843 if( nfixedvars > 0 )
5844 {
5845 SCIPfreeBufferArray(scip, &fixvars);
5846 }
5847
5848 /* print SOS section */
5849 if( nConsSOS1 > 0 || nConsSOS2 > 0 )
5850 {
5851 SCIP_Real* sosweights;
5852
5853 SCIPinfoMessage(scip, file, "SOS\n");
5854 SCIPdebugMsg(scip, "start printing SOS section\n");
5855
5857
5858 /* first output SOS1 constraints */
5859 for( c = 0; c < nConsSOS1; ++c )
5860 {
5861 cons = consSOS1[c];
5862 consvars = SCIPgetVarsSOS1(scip, cons);
5863 nconsvars = SCIPgetNVarsSOS1(scip, cons);
5864 sosweights = SCIPgetWeightsSOS1(scip, cons);
5865 (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "%s", SCIPconsGetName(cons) );
5866
5867 printStart(scip, file, "S1", namestr, -1);
5868 SCIPinfoMessage(scip, file, "\n");
5869
5870 for( v = 0; v < nconsvars; ++v )
5871 {
5872 /* get variable name */
5873 assert ( SCIPhashmapExists(varnameHashmap, consvars[v]) );
5874 varname = (const char*) SCIPhashmapGetImage(varnameHashmap, consvars[v]);
5875
5876 printStart(scip, file, "", varname, (int) maxnamelen);
5877
5878 if( sosweights != NULL )
5879 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", sosweights[v]);
5880 else
5881 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25d ", v);
5882
5883 SCIPinfoMessage(scip, file, "%25s\n", valuestr);
5884 }
5885 }
5886
5887 /* next output SOS2 constraints */
5888 for( c = 0; c < nConsSOS2; ++c )
5889 {
5890 cons = consSOS2[c];
5891 consvars = SCIPgetVarsSOS2(scip, cons);
5892 nconsvars = SCIPgetNVarsSOS2(scip, cons);
5893 sosweights = SCIPgetWeightsSOS2(scip, cons);
5894 (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "%s", SCIPconsGetName(cons) );
5895
5896 printStart(scip, file, "S2", namestr, -1);
5897 SCIPinfoMessage(scip, file, "\n");
5898
5899 for( v = 0; v < nconsvars; ++v )
5900 {
5901 /* get variable name */
5902 assert ( SCIPhashmapExists(varnameHashmap, consvars[v]) );
5903 varname = (const char*) SCIPhashmapGetImage(varnameHashmap, consvars[v]);
5904
5905 printStart(scip, file, "", varname, (int) maxnamelen);
5906
5907 if( sosweights != NULL )
5908 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", sosweights[v]);
5909 else
5910 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25d ", v);
5911
5912 SCIPinfoMessage(scip, file, "%25s\n", valuestr);
5913 }
5914 }
5915 SCIPfreeBufferArray(scip, &namestr);
5916 }
5917
5918 /* print QCMATRIX sections for quadratic constraints
5919 * in difference to a quadratic term in the objective function, the quadratic part is not divided by 2 here
5920 */
5921 if( nConsQuadratic > 0 )
5922 {
5923 const char* varname2;
5924 int nbilin;
5925
5926 SCIPdebugMsg(scip, "start printing QCMATRIX sections for quadratic constraints\n");
5928
5929 for( c = 0; c < nConsQuadratic; ++c )
5930 {
5931 SCIP_EXPR* expr;
5932
5933 cons = consQuadratic[c];
5934 expr = exprQuadratic[c];
5935
5936 SCIPexprGetQuadraticData(expr, NULL, NULL, NULL, NULL, &nconsvars, &nbilin, NULL, NULL);
5937
5938 (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "%s", SCIPconsGetName(cons) );
5939
5940 SCIPinfoMessage(scip, file, "QCMATRIX %s\n", namestr);
5941
5942 /* print x^2 terms */
5943 for( v = 0; v < nconsvars; ++v )
5944 {
5945 SCIP_EXPR* qexpr;
5946 SCIP_VAR* qvar;
5947 SCIP_Real sqrcoef;
5948
5949 SCIPexprGetQuadraticQuadTerm(expr, v, &qexpr, NULL, &sqrcoef, NULL, NULL, NULL);
5950 if( sqrcoef == 0.0 )
5951 continue;
5952
5953 assert(SCIPisExprVar(scip, qexpr));
5954 qvar = SCIPgetVarExprVar(qexpr);
5955
5956 /* get variable name */
5957 assert(SCIPhashmapExists(varnameHashmap, qvar));
5958 varname = (const char*) SCIPhashmapGetImage(varnameHashmap, qvar);
5959
5960 /* get coefficient as string */
5961 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", sqrcoef);
5962
5963 /* print "x x coeff" line */
5964 printStart(scip, file, "", varname, (int) maxnamelen);
5965 printRecord(scip, file, varname, valuestr, maxnamelen);
5966 SCIPinfoMessage(scip, file, "\n");
5967 }
5968
5969 /* print bilinear terms; CPLEX format expects a symmetric matrix with all coefficients specified,
5970 * i.e., we have to split bilinear coefficients into two off diagonal elements */
5971 for( v = 0; v < nbilin; ++v )
5972 {
5973 SCIP_EXPR* expr1;
5974 SCIP_EXPR* expr2;
5975 SCIP_VAR* var1;
5976 SCIP_VAR* var2;
5977 SCIP_Real coef;
5978
5979 SCIPexprGetQuadraticBilinTerm(expr, v, &expr1, &expr2, &coef, NULL, NULL);
5980 assert(SCIPisExprVar(scip, expr1));
5981 assert(SCIPisExprVar(scip, expr2));
5982
5983 if( coef == 0.0 )
5984 continue;
5985
5986 var1 = SCIPgetVarExprVar(expr1);
5987 var2 = SCIPgetVarExprVar(expr2);
5988
5989 /* get name of first variable */
5990 assert ( SCIPhashmapExists(varnameHashmap, var1) );
5991 varname = (const char*) SCIPhashmapGetImage(varnameHashmap, var1);
5992
5993 /* get name of second variable */
5994 assert ( SCIPhashmapExists(varnameHashmap, var2) );
5995 varname2 = (const char*) SCIPhashmapGetImage(varnameHashmap, var2);
5996
5997 /* get coefficient as string */
5998 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", 0.5*coef);
5999
6000 /* print "x y coeff/2" line */
6001 printStart(scip, file, "", varname, (int) maxnamelen);
6002 printRecord(scip, file, varname2, valuestr, maxnamelen);
6003 SCIPinfoMessage(scip, file, "\n");
6004
6005 /* print "y x coeff/2" line */
6006 printStart(scip, file, "", varname2, (int) maxnamelen);
6007 printRecord(scip, file, varname, valuestr, maxnamelen);
6008 SCIPinfoMessage(scip, file, "\n");
6009 }
6010
6011 if( expr != SCIPgetExprNonlinear(cons) )
6012 {
6013 SCIP_CALL( SCIPreleaseExpr(scip, &expr) );
6014 }
6015 }
6016
6017 SCIPfreeBufferArray(scip, &namestr);
6018 }
6019
6020 /* print indicator section */
6021 if( nConsIndicator > 0 )
6022 {
6024
6025 SCIPinfoMessage(scip, file, "INDICATORS\n");
6026 SCIPdebugMsg(scip, "start printing INDICATOR section\n");
6027
6028 /* output each indicator constraint */
6029 for( c = 0; c < nConsIndicator; ++c )
6030 {
6031 SCIP_CONS* lincons;
6032 SCIP_VAR* slackvar;
6033 SCIP_VAR* binvar;
6034
6035 cons = consIndicator[c];
6036 binvar = SCIPgetBinaryVarIndicator(cons);
6037 lincons = SCIPgetLinearConsIndicator(cons);
6038 slackvar = SCIPgetSlackVarIndicator(cons);
6039
6040 /* linvars always contains slack variable, thus nlinvars >= 1 */
6041 if( SCIPgetNVarsLinear(scip, lincons) <= 1 || SCIPconsIsDeleted(lincons) )
6042 continue;
6043
6044 /* create variable and value strings */
6045 if( SCIPvarIsNegated(binvar) )
6046 {
6047 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25d", 0);
6048 assert( SCIPvarGetNegatedVar(binvar) != NULL );
6049 assert( SCIPhashmapExists(varnameHashmap, SCIPvarGetNegatedVar(binvar)) );
6050 varname = (const char*) SCIPhashmapGetImage(varnameHashmap, SCIPvarGetNegatedVar(binvar));
6051 }
6052 else
6053 {
6054 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25d", 1);
6055 assert ( SCIPhashmapExists(varnameHashmap, binvar) );
6056 varname = (const char*) SCIPhashmapGetImage(varnameHashmap, binvar);
6057 }
6058
6059 /* write records */
6061 {
6062 /* for aggregated variables output name of aggregating constraint */
6063 (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "aggr_%s", SCIPvarGetName(slackvar));
6064 printStart(scip, file, "IF", namestr, (int) maxnamelen);
6065 printRecord(scip, file, varname, valuestr, maxnamelen);
6066 SCIPinfoMessage(scip, file, "\n");
6067 }
6068 else
6069 {
6070 printStart(scip, file, "IF", SCIPconsGetName(lincons), (int) maxnamelen);
6071 printRecord(scip, file, varname, valuestr, maxnamelen);
6072 SCIPinfoMessage(scip, file, "\n");
6073 }
6074 }
6075 SCIPfreeBufferArray(scip, &namestr);
6076 }
6077
6078 /* free matrix data structure */
6079 freeMatrix(scip, matrix);
6080
6081 /* free slackvar hashtable */
6082 if( indicatorSlackHash != NULL )
6083 SCIPhashtableFree(&indicatorSlackHash);
6084
6085 /* free variable hashmap */
6086 SCIPhashmapFree(&varnameHashmap);
6087
6088 SCIPfreeBlockMemoryArray(scip, &aggvars, saggvars);
6089 SCIPfreeBufferArray(scip, &rhss);
6090
6091 /* free buffer arrays for SOS1, SOS2, and quadratic */
6092 SCIPfreeBufferArray(scip, &consIndicator);
6093 SCIPfreeBufferArray(scip, &exprQuadratic);
6094 SCIPfreeBufferArray(scip, &consQuadratic);
6095 SCIPfreeBufferArray(scip, &consSOS2);
6096 SCIPfreeBufferArray(scip, &consSOS1);
6097
6098 /* free variable and constraint name array */
6099 for( v = nvars + naggvars + nfixvars - 1; v >= 0; --v )
6100 SCIPfreeBufferArray(scip, &varnames[v]);
6101 SCIPfreeBufferArray(scip, &varnames);
6102
6103 for( c = nconss + naddrows + naggvars - 1; c >= 0; --c )
6104 SCIPfreeBufferArray(scip, &consnames[c]);
6105 SCIPfreeBufferArray(scip, &consnames);
6106
6107 /* print end of data line */
6108 SCIPinfoMessage(scip, file, "ENDATA");
6109
6110 *result = SCIP_SUCCESS;
6111
6112 return SCIP_OKAY;
6113}
static long * number
Constraint handler for AND constraints, .
constraint handler for bound disjunction constraints
Constraint handler for linear constraints in their most general form, .
constraint handler for indicator 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 SOS type 1 constraints
constraint handler for SOS type 2 constraints
Constraint handler for variable bound constraints .
#define NULL
Definition: def.h:248
#define SCIP_MAXSTRLEN
Definition: def.h:269
#define SCIP_Longint
Definition: def.h:141
#define SCIP_Bool
Definition: def.h:91
#define MIN(x, y)
Definition: def.h:224
#define SCIP_Real
Definition: def.h:156
#define SCIP_HASHSIZE_NAMES
Definition: def.h:280
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define MAX(x, y)
Definition: def.h:220
#define SCIP_CALL_TERMINATE(retcode, x, TERM)
Definition: def.h:376
#define SCIPABORT()
Definition: def.h:327
#define REALABS(x)
Definition: def.h:182
#define SCIP_CALL(x)
Definition: def.h:355
SCIP_FILE * SCIPfopen(const char *path, const char *mode)
Definition: fileio.c:153
int SCIPfclose(SCIP_FILE *fp)
Definition: fileio.c:232
char * SCIPfgets(char *s, int size, SCIP_FILE *stream)
Definition: fileio.c:200
int SCIPgetNVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPchgLhsExactLinear(SCIP *scip, SCIP_CONS *cons, SCIP_RATIONAL *lhs)
SCIP_Real SCIPgetVbdcoefVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_RATIONAL * SCIPgetLhsExactLinear(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_RETCODE SCIPchgRhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real rhs)
SCIP_RATIONAL * SCIPgetRhsExactLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPchgRhsExactLinear(SCIP *scip, SCIP_CONS *cons, SCIP_RATIONAL *rhs)
SCIP_RETCODE SCIPcreateConsExactLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_RATIONAL **vals, SCIP_RATIONAL *lhs, SCIP_RATIONAL *rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_Real * SCIPgetWeightsSOS2(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos2.c:2790
SCIP_VAR ** SCIPgetVarsSOS2(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos2.c:2765
SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
int SCIPgetNVarsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_VAR * SCIPgetResultantAnd(SCIP *scip, SCIP_CONS *cons)
Definition: cons_and.c:5248
SCIP_RETCODE SCIPaddVarSOS1(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real weight)
Definition: cons_sos1.c:10725
SCIP_RETCODE SCIPcreateConsBounddisjunction(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_BOUNDTYPE *boundtypes, SCIP_Real *bounds, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_RETCODE SCIPcreateConsIndicator(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *binvar, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
int SCIPgetNVarsAnd(SCIP *scip, SCIP_CONS *cons)
Definition: cons_and.c:5199
SCIP_Real * SCIPgetValsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPcreateConsSOS1(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *weights, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
Definition: cons_sos1.c:10579
SCIP_RETCODE SCIPaddCoefExactLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_RATIONAL *val)
SCIP_VAR * SCIPgetVbdvarVarbound(SCIP *scip, SCIP_CONS *cons)
int SCIPgetNVarsSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9596
int SCIPgetNVarsSOS2(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos2.c:2740
SCIP_Real * SCIPgetWeightsSOS1(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos1.c:10844
SCIP_VAR ** SCIPgetVarsSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9619
SCIP_EXPR * SCIPgetExprNonlinear(SCIP_CONS *cons)
SCIP_Real SCIPgetRhsNonlinear(SCIP_CONS *cons)
SCIP_VAR * SCIPgetBinaryVarIndicator(SCIP_CONS *cons)
SCIP_VAR * SCIPgetVarVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_Longint * SCIPgetWeightsKnapsack(SCIP *scip, SCIP_CONS *cons)
SCIP_VAR * SCIPgetSlackVarIndicator(SCIP_CONS *cons)
SCIP_Longint SCIPgetCapacityKnapsack(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPgetLhsVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_SETPPCTYPE SCIPgetTypeSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9642
SCIP_CONS * SCIPgetLinearConsIndicator(SCIP_CONS *cons)
SCIP_RETCODE SCIPcreateConsSOS2(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *weights, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
Definition: cons_sos2.c:2578
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 ** SCIPgetVarsSOS1(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos1.c:10819
SCIP_VAR ** SCIPgetVarsLogicor(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPgetRhsVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_VAR ** SCIPgetVarsAnd(SCIP *scip, SCIP_CONS *cons)
Definition: cons_and.c:5223
SCIP_VAR ** SCIPgetVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPcreateConsQuadraticNonlinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nlinvars, SCIP_VAR **linvars, SCIP_Real *lincoefs, int nquadterms, SCIP_VAR **quadvars1, SCIP_VAR **quadvars2, SCIP_Real *quadcoefs, 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_RETCODE SCIPcreateConsIndicatorLinConsPure(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *binvar, SCIP_CONS *lincons, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_RETCODE SCIPchgLhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real lhs)
int SCIPgetNVarsSOS1(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos1.c:10794
SCIP_Real SCIPgetLhsNonlinear(SCIP_CONS *cons)
SCIP_RETCODE SCIPaddVarSOS2(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real weight)
Definition: cons_sos2.c:2687
@ 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 SCIPwriteMps(SCIP *scip, SCIP_READER *reader, FILE *file, const char *name, SCIP_Bool transformed, SCIP_OBJSENSE objsense, SCIP_Real objoffset, SCIP_Real objscale, SCIP_RATIONAL *objoffsetexact, SCIP_RATIONAL *objscaleexact, SCIP_VAR **vars, int nvars, int nbinvars, int nintvars, int nimplvars, int ncontvars, SCIP_VAR **fixedvars, int nfixedvars, SCIP_CONS **conss, int nconss, SCIP_RESULT *result)
Definition: reader_mps.c:4983
SCIP_RETCODE SCIPreadMps(SCIP *scip, SCIP_READER *reader, const char *filename, SCIP_RESULT *result, const char ***varnames, const char ***consnames, int *varnamessize, int *consnamessize, int *nvarnames, int *nconsnames)
Definition: reader_mps.c:4945
SCIP_RETCODE SCIPincludeReaderMps(SCIP *scip)
Definition: reader_mps.c:4908
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 SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:3420
SCIP_RETCODE SCIPprintTransProblem(SCIP *scip, FILE *file, const char *extension, SCIP_Bool genericnames)
Definition: scip_prob.c:696
SCIP_RETCODE SCIPprintOrigProblem(SCIP *scip, FILE *file, const char *extension, SCIP_Bool genericnames)
Definition: scip_prob.c:652
SCIP_RETCODE SCIPsetObjsense(SCIP *scip, SCIP_OBJSENSE objsense)
Definition: scip_prob.c:1417
SCIP_RETCODE SCIPaddOrigObjoffset(SCIP *scip, SCIP_Real addval)
Definition: scip_prob.c:1486
SCIP_RETCODE SCIPcreateProb(SCIP *scip, const char *name, SCIP_DECL_PROBDELORIG((*probdelorig)), SCIP_DECL_PROBTRANS((*probtrans)), SCIP_DECL_PROBDELTRANS((*probdeltrans)), SCIP_DECL_PROBINITSOL((*probinitsol)), SCIP_DECL_PROBEXITSOL((*probexitsol)), SCIP_DECL_PROBCOPY((*probcopy)), SCIP_PROBDATA *probdata)
Definition: scip_prob.c:119
SCIP_VAR * SCIPfindVar(SCIP *scip, const char *name)
Definition: scip_prob.c:3189
SCIP_CONS * SCIPfindCons(SCIP *scip, const char *name)
Definition: scip_prob.c:3525
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:3095
void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3284
SCIP_RETCODE SCIPhashmapInsert(SCIP_HASHMAP *hashmap, void *origin, void *image)
Definition: misc.c:3143
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:3061
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3466
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
void * SCIPhashtableRetrieve(SCIP_HASHTABLE *hashtable, void *key)
Definition: misc.c:2596
SCIP_RETCODE SCIPhashtableInsert(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2535
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:208
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: scip_message.c:225
#define SCIPdebugMsg
Definition: scip_message.h:78
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:120
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition: scip_param.c:250
SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:57
SCIP_RETCODE SCIPgetIntParam(SCIP *scip, const char *name, int *value)
Definition: scip_param.c:269
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4316
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip_cons.c:940
SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
Definition: cons.c:8648
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:8409
SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
Definition: cons.c:8558
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
Definition: cons.c:8588
SCIP_Bool SCIPconsIsDeleted(SCIP_CONS *cons)
Definition: cons.c:8518
SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
Definition: cons.c:8578
SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
Definition: cons.c:8608
SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
Definition: cons.c:8628
SCIP_Bool SCIPconsIsEnabled(SCIP_CONS *cons)
Definition: cons.c:8486
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:8389
SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
Definition: cons.c:8638
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1173
SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
Definition: cons.c:8568
SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
Definition: cons.c:8658
SCIP_Bool SCIPisExact(SCIP *scip)
Definition: scip_exact.c:193
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_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_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 SCIPcheckExprQuadratic(SCIP *scip, SCIP_EXPR *expr, SCIP_Bool *isquadratic)
Definition: scip_expr.c:2402
SCIP_VAR * SCIPgetVarExprVar(SCIP_EXPR *expr)
Definition: expr_var.c:424
void SCIPexprGetQuadraticQuadTerm(SCIP_EXPR *quadexpr, int termidx, SCIP_EXPR **expr, SCIP_Real *lincoef, SCIP_Real *sqrcoef, int *nadjbilin, int **adjbilin, SCIP_EXPR **sqrexpr)
Definition: expr.c:4186
SCIP_RETCODE SCIPduplicateExpr(SCIP *scip, SCIP_EXPR *expr, SCIP_EXPR **copyexpr, SCIP_DECL_EXPR_MAPEXPR((*mapexpr)), void *mapexprdata, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: scip_expr.c:1307
SCIP_RETCODE SCIPsimplifyExpr(SCIP *scip, SCIP_EXPR *rootexpr, SCIP_EXPR **simplified, SCIP_Bool *changed, SCIP_Bool *infeasible, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: scip_expr.c:1798
#define SCIPfreeBuffer(scip, ptr)
Definition: scip_mem.h:134
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:110
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip_mem.c:57
#define SCIPensureBlockMemoryArray(scip, ptr, arraysizeptr, minsize)
Definition: scip_mem.h:107
BMS_BUFMEM * SCIPbuffer(SCIP *scip)
Definition: scip_mem.c:72
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip_mem.c:139
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:124
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:128
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:136
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip_mem.h:132
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:93
#define SCIPallocBuffer(scip, ptr)
Definition: scip_mem.h:122
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
Definition: scip_mem.h:99
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip_mem.h:108
#define SCIPfreeBufferArrayNull(scip, ptr)
Definition: scip_mem.h:137
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip_mem.h:89
#define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
Definition: scip_mem.h:105
void SCIPrationalSetInfinity(SCIP_RATIONAL *res)
Definition: rational.cpp:618
void SCIPrationalAdd(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
Definition: rational.cpp:935
SCIP_Real SCIPrationalGetReal(SCIP_RATIONAL *rational)
Definition: rational.cpp:2085
#define SCIPrationalDebugMessage
Definition: rational.h:641
void SCIPrationalAbs(SCIP_RATIONAL *res, SCIP_RATIONAL *op)
Definition: rational.cpp:1310
SCIP_Bool SCIPrationalIsLT(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
Definition: rational.cpp:1503
void SCIPrationalSetReal(SCIP_RATIONAL *res, SCIP_Real real)
Definition: rational.cpp:603
SCIP_Bool SCIPrationalIsGT(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
Definition: rational.cpp:1474
void SCIPrationalFreeBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
Definition: rational.cpp:473
void SCIPrationalDiff(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
Definition: rational.cpp:983
SCIP_RETCODE SCIPrationalCreateBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
Definition: rational.cpp:123
SCIP_Bool SCIPrationalIsZero(SCIP_RATIONAL *rational)
Definition: rational.cpp:1624
void SCIPrationalSetString(SCIP_RATIONAL *res, const char *desc)
Definition: rational.cpp:716
SCIP_Bool SCIPrationalIsIntegral(SCIP_RATIONAL *rational)
Definition: rational.cpp:1691
void SCIPrationalCanonicalize(SCIP_RATIONAL *rational)
Definition: rational.cpp:538
void SCIPrationalSetNegInfinity(SCIP_RATIONAL *res)
Definition: rational.cpp:630
SCIP_Bool SCIPrationalIsNegative(SCIP_RATIONAL *rational)
Definition: rational.cpp:1650
SCIP_Bool SCIPrationalIsInfinity(SCIP_RATIONAL *rational)
Definition: rational.cpp:1660
SCIP_Bool SCIPrationalIsNegInfinity(SCIP_RATIONAL *rational)
Definition: rational.cpp:1670
SCIP_Bool SCIPrationalIsGTReal(SCIP_RATIONAL *rat, SCIP_Real real)
Definition: rational.cpp:1546
SCIP_Bool SCIPrationalIsEQ(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
Definition: rational.cpp:1404
SCIP_RETCODE SCIPincludeReaderBasic(SCIP *scip, SCIP_READER **readerptr, const char *name, const char *desc, const char *extension, SCIP_READERDATA *readerdata)
Definition: scip_reader.c:109
SCIP_RETCODE SCIPsetReaderCopy(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERCOPY((*readercopy)))
Definition: scip_reader.c:147
SCIP_READERDATA * SCIPreaderGetData(SCIP_READER *reader)
Definition: reader.c:605
SCIP_RETCODE SCIPsetReaderFree(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERFREE((*readerfree)))
Definition: scip_reader.c:171
const char * SCIPreaderGetName(SCIP_READER *reader)
Definition: reader.c:680
SCIP_RETCODE SCIPsetReaderRead(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERREAD((*readerread)))
Definition: scip_reader.c:195
void SCIPreaderMarkExact(SCIP_READER *reader)
Definition: reader.c:670
SCIP_RETCODE SCIPsetReaderWrite(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERWRITE((*readerwrite)))
Definition: scip_reader.c:219
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasNegative(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_RETCODE SCIPtightenVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:6401
SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:18320
SCIP_RETCODE SCIPtightenVarUbExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *newbound, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:6768
SCIP_VAR * SCIPvarGetNegatedVar(SCIP_VAR *var)
Definition: var.c:23868
SCIP_RETCODE SCIPchgVarUbExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *newbound)
Definition: scip_var.c:5964
SCIP_RETCODE SCIPchgVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:5697
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:23386
int SCIPvarGetNLocksUpType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
Definition: var.c:4386
SCIP_Bool SCIPvarIsImpliedIntegral(SCIP_VAR *var)
Definition: var.c:23498
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:24268
SCIP_Real SCIPvarGetLbOriginal(SCIP_VAR *var)
Definition: var.c:24020
SCIP_RETCODE SCIPaddVarExactData(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *lb, SCIP_RATIONAL *ub, SCIP_RATIONAL *obj)
Definition: scip_var.c:299
SCIP_RETCODE SCIPchgVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:5875
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:23900
SCIP_RETCODE SCIPtightenVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:6651
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:23453
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:24142
int SCIPvarGetIndex(SCIP_VAR *var)
Definition: var.c:23652
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:23267
SCIP_Real SCIPvarGetUbOriginal(SCIP_VAR *var)
Definition: var.c:24063
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip_var.c:1887
SCIP_RETCODE SCIPgetProbvarLinearSum(SCIP *scip, SCIP_VAR **vars, SCIP_Real *scalars, int *nvars, int varssize, SCIP_Real *constant, int *requiredsize)
Definition: scip_var.c:2378
SCIP_RETCODE SCIPchgVarType(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
Definition: scip_var.c:10113
SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
Definition: scip_var.c:2166
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:24234
SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
Definition: var.c:23443
SCIP_RATIONAL * SCIPvarGetLbGlobalExact(SCIP_VAR *var)
Definition: var.c:24130
SCIP_RETCODE SCIPcreateVar(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_DECL_VARCOPY((*varcopy)), SCIP_VARDATA *vardata)
Definition: scip_var.c:120
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:24120
SCIP_IMPLINTTYPE SCIPvarGetImplType(SCIP_VAR *var)
Definition: var.c:23463
SCIP_RETCODE SCIPchgVarObjExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *newobj)
Definition: scip_var.c:5420
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip_var.c:5372
SCIP_RETCODE SCIPchgVarLbExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *newbound)
Definition: scip_var.c:5786
int SCIPvarGetNLocksDownType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
Definition: var.c:4328
SCIP_RETCODE SCIPtightenVarLbExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *newbound, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:6518
SCIP_RATIONAL * SCIPvarGetUbGlobalExact(SCIP_VAR *var)
Definition: var.c:24152
void SCIPsortPtrPtrReal(void **ptrarray1, void **ptrarray2, SCIP_Real *realarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), int len)
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10827
void SCIPprintSysError(const char *message)
Definition: misc.c:10719
char * SCIPstrtok(char *s, const char *delim, char **ptrptr)
Definition: misc.c:10768
int SCIPmemccpy(char *dest, const char *src, char stop, unsigned int cnt)
Definition: misc.c:10694
memory allocation routines
public methods for managing constraints
wrapper functions to map file i/o to standard or zlib file i/o
struct SCIP_File SCIP_FILE
Definition: pub_fileio.h:43
public methods for message output
#define SCIPerrorMessage
Definition: pub_message.h:64
#define SCIPdebugPrintCons(x, y, z)
Definition: pub_message.h:102
#define SCIPdebugMessage
Definition: pub_message.h:96
public data structures and miscellaneous methods
methods for sorting joint arrays of various types
public methods for input file readers
public methods for problem variables
wrapper for rational number arithmetic
static void mpsinputEntryIgnored(SCIP *scip, MPSINPUT *mpsi, const char *what, const char *what_name, const char *entity, const char *entity_name, SCIP_VERBLEVEL verblevel)
Definition: reader_mps.c:409
static void mpsinputInsertField4(MPSINPUT *mpsi, const char *str)
Definition: reader_mps.c:649
static const char * mpsinputField5(const MPSINPUT *mpsi)
Definition: reader_mps.c:290
static SCIP_RETCODE checkVarnames(SCIP *scip, SCIP_VAR **vars, int nvars, unsigned int *maxnamelen, const char ***varnames, SCIP_HASHMAP **varnameHashmap)
Definition: reader_mps.c:4140
static SCIP_RETCODE readMpsExact(SCIP *scip, const char *filename, const char ***varnames, const char ***consnames, int *varnamessize, int *consnamessize, int *nvarnames, int *nconsnames)
Definition: reader_mps.c:3624
static SCIP_RETCODE readSOS(MPSINPUT *mpsi, SCIP *scip)
Definition: reader_mps.c:2680
static void printRhsSection(SCIP *scip, FILE *file, int nconss, const char **consnames, SCIP_Real *rhss, unsigned int maxnamelen, SCIP_Real objoffset)
Definition: reader_mps.c:4461
static SCIP_DECL_READERWRITE(readerWriteMps)
Definition: reader_mps.c:4885
struct SparseMatrix SPARSEMATRIX
Definition: reader_mps.c:164
static const char * mpsinputField1(const MPSINPUT *mpsi)
Definition: reader_mps.c:246
static SCIP_DECL_HASHKEYEQ(hashKeyEqString)
Definition: reader_mps.c:3747
MpsSection
Definition: reader_mps.c:109
@ MPS_QCMATRIX
Definition: reader_mps.c:123
@ MPS_COLUMNS
Definition: reader_mps.c:116
@ MPS_NAME
Definition: reader_mps.c:110
@ MPS_BOUNDS
Definition: reader_mps.c:119
@ MPS_USERCUTS
Definition: reader_mps.c:114
@ MPS_SOS
Definition: reader_mps.c:120
@ MPS_ROWS
Definition: reader_mps.c:113
@ MPS_LAZYCONS
Definition: reader_mps.c:115
@ MPS_INDICATORS
Definition: reader_mps.c:124
@ MPS_OBJSEN
Definition: reader_mps.c:111
@ MPS_OBJNAME
Definition: reader_mps.c:112
@ MPS_QMATRIX
Definition: reader_mps.c:122
@ MPS_RHS
Definition: reader_mps.c:117
@ MPS_RANGES
Definition: reader_mps.c:118
@ MPS_ENDATA
Definition: reader_mps.c:125
@ MPS_QUADOBJ
Definition: reader_mps.c:121
static SCIP_RETCODE readObjsen(SCIP *scip, MPSINPUT *mpsi)
Definition: reader_mps.c:779
static SCIP_RETCODE checkSparseMatrixCapacity(SCIP *scip, SPARSEMATRIX *matrix, int capacity)
Definition: reader_mps.c:3947
static SCIP_RETCODE readQMatrix(MPSINPUT *mpsi, SCIP_Bool isQuadObj, SCIP *scip)
Definition: reader_mps.c:2880
#define MPSINTCOMP_LEVEL(IMPLINTLEVEL)
Definition: reader_mps.c:4324
static SCIP_Bool mpsinputHasError(const MPSINPUT *mpsi)
Definition: reader_mps.c:323
static SCIP_DECL_READERFREE(readerFreeMps)
Definition: reader_mps.c:4857
static SCIP_RETCODE readRows(MPSINPUT *mpsi, SCIP *scip, const char ***consnames, int *consnamessize, int *nconsnames)
Definition: reader_mps.c:877
static void printBoundSectionName(SCIP *scip, FILE *file)
Definition: reader_mps.c:4568
static const char * mpsinputField2(const MPSINPUT *mpsi)
Definition: reader_mps.c:257
static void clearFrom(char *buf, unsigned int pos)
Definition: reader_mps.c:431
static SCIP_RETCODE readColsExact(MPSINPUT *mpsi, SCIP *scip, const char ***varnames, int *varnamessize, int *nvarnames)
Definition: reader_mps.c:1210
static SCIP_RETCODE readRhs(MPSINPUT *mpsi, SCIP *scip)
Definition: reader_mps.c:1355
static void mpsinputSetObjname(MPSINPUT *mpsi, const char *objname)
Definition: reader_mps.c:371
static SCIP_RETCODE initializeMatrix(SCIP *scip, SPARSEMATRIX **matrix, int slots)
Definition: reader_mps.c:3929
static void freeMatrix(SCIP *scip, SPARSEMATRIX *matrix)
Definition: reader_mps.c:3965
static SCIP_RETCODE readObjname(SCIP *scip, MPSINPUT *mpsi)
Definition: reader_mps.c:838
enum MpsSection MPSSECTION
Definition: reader_mps.c:127
static SCIP_Bool mpsinputIsInteger(const MPSINPUT *mpsi)
Definition: reader_mps.c:334
struct MpsInput MPSINPUT
Definition: reader_mps.c:153
static SCIP_RETCODE getLinearCoeffs(SCIP *scip, const char *consname, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_Bool transformed, SPARSEMATRIX *matrix, SCIP_Real *rhs)
Definition: reader_mps.c:3980
static void mpsinputSetProbname(MPSINPUT *mpsi, const char *probname)
Definition: reader_mps.c:357
static SCIP_DECL_HASHGETKEY(hashGetKeyNamefreq)
Definition: reader_mps.c:3735
static void printRangeSection(SCIP *scip, FILE *file, SCIP_CONS **conss, int nconss, const char **consnames, SCIP_Bool transformed, unsigned int maxnamelen)
Definition: reader_mps.c:4503
#define BLANK
Definition: reader_mps.c:98
static SCIP_OBJSENSE mpsinputObjsense(const MPSINPUT *mpsi)
Definition: reader_mps.c:312
static SCIP_RETCODE readCols(MPSINPUT *mpsi, SCIP *scip, const char ***varnames, int *varnamessize, int *nvarnames)
Definition: reader_mps.c:1079
static SCIP_Bool mpsinputReadLine(MPSINPUT *mpsi)
Definition: reader_mps.c:466
static void mpsinputSetObjsense(MPSINPUT *mpsi, SCIP_OBJSENSE sense)
Definition: reader_mps.c:385
static void mpsinputInsertName(MPSINPUT *mpsi, const char *name, SCIP_Bool second)
Definition: reader_mps.c:663
static MPSSECTION mpsinputSection(const MPSINPUT *mpsi)
Definition: reader_mps.c:224
static SCIP_RETCODE addVarNameToStorage(SCIP *scip, const char ***varnames, int *varnamessize, int *nvars, const char *colname)
Definition: reader_mps.c:687
#define READER_DESC
Definition: reader_mps.c:82
static const char * mpsinputField3(const MPSINPUT *mpsi)
Definition: reader_mps.c:268
static SCIP_RETCODE checkConsnames(SCIP *scip, SCIP_CONS **conss, int nconss, SCIP_Bool transformed, unsigned int *maxnamelen, const char ***consnames, SCIP_Bool *error)
Definition: reader_mps.c:4204
#define MPS_MAX_FIELDLEN
Definition: reader_mps.c:95
static SCIP_DECL_READERCOPY(readerCopyMps)
Definition: reader_mps.c:4841
static SCIP_RETCODE readRhsExact(MPSINPUT *mpsi, SCIP *scip)
Definition: reader_mps.c:1502
static SCIP_RETCODE addConsNameToStorage(SCIP *scip, const char ***consnames, int *consnamessize, int *ncons, const char *rowname)
Definition: reader_mps.c:709
#define MPS_MAX_VALUELEN
Definition: reader_mps.c:94
#define READER_EXTENSION
Definition: reader_mps.c:83
static SCIP_RETCODE readMps(SCIP *scip, const char *filename, const char ***varnames, const char ***consnames, int *varnamessize, int *consnamessize, int *nvarnames, int *nconsnames)
Definition: reader_mps.c:3504
static SCIP_DECL_READERREAD(readerReadMps)
Definition: reader_mps.c:4872
static void printRowType(SCIP *scip, FILE *file, SCIP_Real lhs, SCIP_Real rhs, const char *name)
Definition: reader_mps.c:3891
static SCIP_RETCODE readRanges(MPSINPUT *mpsi, SCIP *scip)
Definition: reader_mps.c:1657
static SCIP_DECL_SORTPTRCOMP(mpsIntCompM2)
Definition: reader_mps.c:4336
static SCIP_RETCODE mpsinputCreate(SCIP *scip, MPSINPUT **mpsi, SCIP_FILE *fp)
Definition: reader_mps.c:176
static unsigned int computeFieldWidth(unsigned int width)
Definition: reader_mps.c:3782
static void printBoundSection(SCIP *scip, FILE *file, SCIP_VAR **vars, int nvars, SCIP_VAR **aggvars, int naggvars, SCIP_VAR **fixvars, int nfixvars, SCIP_Bool transformed, const char **varnames, SCIP_HASHTABLE *indicatorSlackHash, unsigned int maxnamelen)
Definition: reader_mps.c:4579
static const char * mpsinputField4(const MPSINPUT *mpsi)
Definition: reader_mps.c:279
static void printEntry(SCIP *scip, FILE *file, const char *varname, const char *consname, SCIP_Real value, int *recordcnt, unsigned int maxnamelen)
Definition: reader_mps.c:3853
static void printStart(SCIP *scip, FILE *file, const char *col1, const char *col2, int maxnamelen)
Definition: reader_mps.c:3819
static SCIP_RETCODE readIndicators(MPSINPUT *mpsi, SCIP *scip)
Definition: reader_mps.c:3289
#define READER_NAME
Definition: reader_mps.c:81
static SCIP_DECL_HASHKEYVAL(hashKeyValVar)
Definition: reader_mps.c:3773
static void mpsinputSetSection(MPSINPUT *mpsi, MPSSECTION section)
Definition: reader_mps.c:345
static void printRecord(SCIP *scip, FILE *file, const char *col1, const char *col2, unsigned int maxnamelen)
Definition: reader_mps.c:3793
static SCIP_RETCODE readRowsExact(MPSINPUT *mpsi, SCIP *scip, const char ***consnames, int *consnamessize, int *nconsnames)
Definition: reader_mps.c:973
static const char * mpsinputObjname(const MPSINPUT *mpsi)
Definition: reader_mps.c:301
#define DEFAULT_AGGRLINEARIZATION_ANDS
Definition: reader_mps.c:86
static const char * mpsinputField0(const MPSINPUT *mpsi)
Definition: reader_mps.c:235
static void mpsinputSyntaxerror(MPSINPUT *mpsi)
Definition: reader_mps.c:396
static SCIP_RETCODE collectAggregatedVars(SCIP *scip, SCIP_VAR **vars, int nvars, SCIP_VAR ***aggvars, int *naggvars, int *saggvars, SCIP_HASHTABLE *varAggregated)
Definition: reader_mps.c:4083
static SCIP_RETCODE readName(SCIP *scip, MPSINPUT *mpsi)
Definition: reader_mps.c:731
#define MPS_MAX_NAMELEN
Definition: reader_mps.c:93
#define PATCH_CHAR
Definition: reader_mps.c:97
static SCIP_RETCODE readQCMatrix(MPSINPUT *mpsi, SCIP *scip)
Definition: reader_mps.c:3099
static SCIP_RETCODE readRangesExact(MPSINPUT *mpsi, SCIP *scip)
Definition: reader_mps.c:1797
static SCIP_RETCODE readBounds(MPSINPUT *mpsi, SCIP *scip)
Definition: reader_mps.c:1956
#define MPS_MAX_LINELEN
Definition: reader_mps.c:92
static SCIP_RETCODE readBoundsExact(MPSINPUT *mpsi, SCIP *scip)
Definition: reader_mps.c:2329
#define DEFAULT_LINEARIZE_ANDS
Definition: reader_mps.c:85
static SCIP_Bool writeVarIsIntegral(SCIP_VAR *var, int implintlevel)
Definition: reader_mps.c:4309
static void patchField(char *buf, int beg, int end)
Definition: reader_mps.c:445
static void mpsinputFree(SCIP *scip, MPSINPUT **mpsi)
Definition: reader_mps.c:214
(extended) MPS file reader
public methods for constraint handler plugins and constraints
public methods for exact solving
public methods for memory management
public methods for message handling
public methods for numerical tolerances
public methods for SCIP parameter handling
public methods for global and local (sub)problems
public methods for reader plugins
public methods for querying solving statistics
public methods for SCIP variables
static SCIP_RETCODE separate(SCIP *scip, SCIP_SEPA *sepa, SCIP_SOL *sol, SCIP_RESULT *result)
Main separation function.
Definition: sepa_flower.c:1221
const char * consname
Definition: reader_mps.c:169
@ SCIP_BOUNDTYPE_UPPER
Definition: type_lp.h:58
@ SCIP_BOUNDTYPE_LOWER
Definition: type_lp.h:57
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:60
enum SCIP_VerbLevel SCIP_VERBLEVEL
Definition: type_message.h:64
@ SCIP_VERBLEVEL_NORMAL
Definition: type_message.h:60
@ SCIP_VERBLEVEL_FULL
Definition: type_message.h:62
@ SCIP_OBJSENSE_MAXIMIZE
Definition: type_prob.h:47
@ SCIP_OBJSENSE_MINIMIZE
Definition: type_prob.h:48
enum SCIP_Objsense SCIP_OBJSENSE
Definition: type_prob.h:50
struct SCIP_ReaderData SCIP_READERDATA
Definition: type_reader.h:54
@ SCIP_SUCCESS
Definition: type_result.h:58
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:61
@ SCIP_NOFILE
Definition: type_retcode.h:47
@ SCIP_READERROR
Definition: type_retcode.h:45
@ SCIP_INVALIDDATA
Definition: type_retcode.h:52
@ SCIP_PLUGINNOTFOUND
Definition: type_retcode.h:54
@ SCIP_WRITEERROR
Definition: type_retcode.h:46
@ SCIP_OKAY
Definition: type_retcode.h:42
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
@ SCIP_VARTYPE_INTEGER
Definition: type_var.h:65
@ SCIP_VARTYPE_CONTINUOUS
Definition: type_var.h:71
@ SCIP_VARTYPE_BINARY
Definition: type_var.h:64
@ SCIP_VARSTATUS_FIXED
Definition: type_var.h:54
@ SCIP_VARSTATUS_MULTAGGR
Definition: type_var.h:56
@ SCIP_VARSTATUS_NEGATED
Definition: type_var.h:57
@ SCIP_VARSTATUS_AGGREGATED
Definition: type_var.h:55
@ SCIP_LOCKTYPE_MODEL
Definition: type_var.h:141
enum SCIP_Vartype SCIP_VARTYPE
Definition: type_var.h:73
enum SCIP_Varstatus SCIP_VARSTATUS
Definition: type_var.h:59