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-2024 Zuse Institute Berlin (ZIB) */
7/* */
8/* Licensed under the Apache License, Version 2.0 (the "License"); */
9/* you may not use this file except in compliance with the License. */
10/* You may obtain a copy of the License at */
11/* */
12/* http://www.apache.org/licenses/LICENSE-2.0 */
13/* */
14/* Unless required by applicable law or agreed to in writing, software */
15/* distributed under the License is distributed on an "AS IS" BASIS, */
16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17/* See the License for the specific language governing permissions and */
18/* limitations under the License. */
19/* */
20/* You should have received a copy of the Apache-2.0 license */
21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22/* */
23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25/**@file reader_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"
50#include "scip/cons_indicator.h"
51#include "scip/cons_knapsack.h"
52#include "scip/cons_linear.h"
53#include "scip/cons_logicor.h"
54#include "scip/cons_setppc.h"
55#include "scip/cons_sos1.h"
56#include "scip/cons_sos2.h"
57#include "scip/cons_varbound.h"
58#include "scip/pub_cons.h"
59#include "scip/pub_fileio.h"
60#include "scip/pub_message.h"
61#include "scip/pub_misc.h"
62#include "scip/pub_misc_sort.h"
63#include "scip/pub_reader.h"
64#include "scip/pub_var.h"
65#include "scip/reader_mps.h"
66#include "scip/scip_cons.h"
67#include "scip/scip_mem.h"
68#include "scip/scip_message.h"
69#include "scip/scip_numerics.h"
70#include "scip/scip_param.h"
71#include "scip/scip_prob.h"
72#include "scip/scip_reader.h"
74#include "scip/scip_var.h"
75#include <stdlib.h>
76#include <string.h>
77
78#define READER_NAME "mpsreader"
79#define READER_DESC "file reader for MIQPs in IBM's Mathematical Programming System format"
80#define READER_EXTENSION "mps"
81
82#define DEFAULT_LINEARIZE_ANDS TRUE /**< should possible \"and\" constraint be linearized when writing the mps file? */
83#define DEFAULT_AGGRLINEARIZATION_ANDS TRUE /**< should an aggregated linearization for and constraints be used? */
84
85/*
86 * mps reader internal methods
87 */
88
89#define MPS_MAX_LINELEN 1024
90#define MPS_MAX_NAMELEN 256
91#define MPS_MAX_VALUELEN 26
92#define MPS_MAX_FIELDLEN 20
93
94#define PATCH_CHAR '_'
95#define BLANK ' '
96
97/** MPS reading data */
98struct SCIP_ReaderData
99{
100 SCIP_Bool linearizeands;
101 SCIP_Bool aggrlinearizationands;
102};
103
104/** enum containing all mps sections */
106{
125
126/** mps input structure */
127struct MpsInput
128{
129 MPSSECTION section;
130 SCIP_FILE* fp;
131 int lineno;
132 SCIP_OBJSENSE objsense;
133 SCIP_Bool haserror;
134 char buf[MPS_MAX_LINELEN];
135 const char* f0;
136 const char* f1;
137 const char* f2;
138 const char* f3;
139 const char* f4;
140 const char* f5;
141 char probname[MPS_MAX_NAMELEN];
142 char objname [MPS_MAX_NAMELEN];
143 SCIP_Bool initialconss; /**< should model constraints be marked as initial? */
144 SCIP_Bool dynamicconss; /**< should model constraints be subject to aging? */
145 SCIP_Bool dynamiccols; /**< should columns be added and removed dynamically to the LP? */
146 SCIP_Bool dynamicrows; /**< should rows be added and removed dynamically to the LP? */
147 SCIP_Bool isinteger;
148 SCIP_Bool isnewformat;
149};
150typedef struct MpsInput MPSINPUT;
151
152/** sparse matrix representation */
153struct SparseMatrix
154{
155 SCIP_Real* values; /**< matrix element */
156 SCIP_VAR** columns; /**< corresponding variables */
157 const char** rows; /**< corresponding constraint names */
158 int nentries; /**< number of elements in the arrays */
159 int sentries; /**< number of slots in the arrays */
160};
161typedef struct SparseMatrix SPARSEMATRIX;
162
163/** struct for mapping cons names to numbers */
165{
166 const char* consname; /**< name of the constraint */
167 int freq; /**< how often we have seen the name */
168};
170
171/** creates the mps input structure */
172static
174 SCIP* scip, /**< SCIP data structure */
175 MPSINPUT** mpsi, /**< mps input structure */
176 SCIP_FILE* fp /**< file object for the input file */
177 )
178{
179 assert(mpsi != NULL);
180 assert(fp != NULL);
181
183
184 (*mpsi)->section = MPS_NAME;
185 (*mpsi)->fp = fp;
186 (*mpsi)->lineno = 0;
187 (*mpsi)->objsense = SCIP_OBJSENSE_MINIMIZE;
188 (*mpsi)->haserror = FALSE;
189 (*mpsi)->isinteger = FALSE;
190 (*mpsi)->isnewformat = FALSE;
191 (*mpsi)->buf [0] = '\0';
192 (*mpsi)->probname[0] = '\0';
193 (*mpsi)->objname [0] = '\0';
194 (*mpsi)->f0 = NULL;
195 (*mpsi)->f1 = NULL;
196 (*mpsi)->f2 = NULL;
197 (*mpsi)->f3 = NULL;
198 (*mpsi)->f4 = NULL;
199 (*mpsi)->f5 = NULL;
200
201 SCIP_CALL( SCIPgetBoolParam(scip, "reading/initialconss", &((*mpsi)->initialconss)) );
202 SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicconss", &((*mpsi)->dynamicconss)) );
203 SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamiccols", &((*mpsi)->dynamiccols)) );
204 SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicrows", &((*mpsi)->dynamicrows)) );
205
206 return SCIP_OKAY;
207}
208
209/** free the mps input structure */
210static
212 SCIP* scip, /**< SCIP data structure */
213 MPSINPUT** mpsi /**< mps input structure */
214 )
215{
217}
218
219/** returns the current section */
220static
222 const MPSINPUT* mpsi /**< mps input structure */
223 )
224{
225 assert(mpsi != NULL);
226
227 return mpsi->section;
228}
229
230/** return the current value of field 0 */
231static
232const char* mpsinputField0(
233 const MPSINPUT* mpsi /**< mps input structure */
234 )
235{
236 assert(mpsi != NULL);
237
238 return mpsi->f0;
239}
240
241/** return the current value of field 1 */
242static
243const char* mpsinputField1(
244 const MPSINPUT* mpsi /**< mps input structure */
245 )
246{
247 assert(mpsi != NULL);
248
249 return mpsi->f1;
250}
251
252/** return the current value of field 2 */
253static
254const char* mpsinputField2(
255 const MPSINPUT* mpsi /**< mps input structure */
256 )
257{
258 assert(mpsi != NULL);
259
260 return mpsi->f2;
261}
262
263/** return the current value of field 3 */
264static
265const char* mpsinputField3(
266 const MPSINPUT* mpsi /**< mps input structure */
267 )
268{
269 assert(mpsi != NULL);
270
271 return mpsi->f3;
272}
273
274/** return the current value of field 4 */
275static
276const char* mpsinputField4(
277 const MPSINPUT* mpsi /**< mps input structure */
278 )
279{
280 assert(mpsi != NULL);
281
282 return mpsi->f4;
283}
284
285/** return the current value of field 5 */
286static
287const char* mpsinputField5(
288 const MPSINPUT* mpsi /**< mps input structure */
289 )
290{
291 assert(mpsi != NULL);
292
293 return mpsi->f5;
294}
295
296/** returns the objective name */
297static
298const char* mpsinputObjname(
299 const MPSINPUT* mpsi /**< mps input structure */
300 )
301{
302 assert(mpsi != NULL);
303
304 return mpsi->objname;
305}
306
307/** returns the objective sense */
308static
310 const MPSINPUT* mpsi /**< mps input structure */
311 )
312{
313 assert(mpsi != NULL);
314
315 return mpsi->objsense;
316}
317
318/** returns if an error was detected */
319static
321 const MPSINPUT* mpsi /**< mps input structure */
322 )
323{
324 assert(mpsi != NULL);
325
326 return mpsi->haserror;
327}
328
329/** returns the value of the Bool "is integer" in the mps input */
330static
332 const MPSINPUT* mpsi /**< mps input structure */
333 )
334{
335 assert(mpsi != NULL);
336
337 return mpsi->isinteger;
338}
339
340/** set the section in the mps input structure to given section */
341static
343 MPSINPUT* mpsi, /**< mps input structure */
344 MPSSECTION section /**< section that is set */
345 )
346{
347 assert(mpsi != NULL);
348
349 mpsi->section = section;
350}
351
352/** set the problem name in the mps input structure to given problem name */
353static
355 MPSINPUT* mpsi, /**< mps input structure */
356 const char* probname /**< name of the problem to set */
357 )
358{
359 assert(mpsi != NULL);
360 assert(probname != NULL);
361 assert(strlen(probname) < sizeof(mpsi->probname));
362
363 (void)SCIPmemccpy(mpsi->probname, probname, '\0', MPS_MAX_NAMELEN - 1);
364}
365
366/** set the objective name in the mps input structure to given objective name */
367static
369 MPSINPUT* mpsi, /**< mps input structure */
370 const char* objname /**< name of the objective function to set */
371 )
372{
373 assert(mpsi != NULL);
374 assert(objname != NULL);
375 assert(strlen(objname) < sizeof(mpsi->objname));
376
377 (void)SCIPmemccpy(mpsi->objname, objname, '\0', MPS_MAX_NAMELEN - 1);
378}
379
380/** set the objective sense in the mps input structure to given objective sense */
381static
383 MPSINPUT* mpsi, /**< mps input structure */
384 SCIP_OBJSENSE sense /**< sense of the objective function */
385 )
386{
387 assert(mpsi != NULL);
388
389 mpsi->objsense = sense;
390}
391
392static
394 MPSINPUT* mpsi /**< mps input structure */
395 )
396{
397 assert(mpsi != NULL);
398
399 SCIPerrorMessage("Syntax error in line %d\n", mpsi->lineno);
400 mpsi->section = MPS_ENDATA;
401 mpsi->haserror = TRUE;
402}
403
404/** method post a ignore message */
405static
407 SCIP* scip, /**< SCIP data structure */
408 MPSINPUT* mpsi, /**< mps input structure */
409 const char* what, /**< what get ignored */
410 const char* what_name, /**< name of that object */
411 const char* entity, /**< entity */
412 const char* entity_name, /**< entity name */
413 SCIP_VERBLEVEL verblevel /**< SCIP verblevel for this message */
414 )
415{
416 assert(mpsi != NULL);
417 assert(what != NULL);
418 assert(what_name != NULL);
419 assert(entity != NULL);
420 assert(entity_name != NULL);
421
422 SCIPverbMessage(scip, verblevel, NULL,
423 "Warning line %d: %s \"%s\" for %s \"%s\" ignored\n", mpsi->lineno, what, what_name, entity, entity_name);
424}
425
426/** fill the line from \p pos up to column 80 with blanks. */
427static
429 char* buf, /**< buffer to clear */
430 unsigned int pos /**< position to start the clearing process */
431 )
432{
433 unsigned int i;
434
435 for(i = pos; i < 80; i++)
436 buf[i] = BLANK;
437 buf[80] = '\0';
438}
439
440/** change all blanks inside a field to #PATCH_CHAR. */
441static
443 char* buf, /**< buffer to patch */
444 int beg, /**< position to begin */
445 int end /**< position to end */
446 )
447{
448 int i;
449
450 while( (beg <= end) && (buf[end] == BLANK) )
451 end--;
452
453 while( (beg <= end) && (buf[beg] == BLANK) )
454 beg++;
455
456 for( i = beg; i <= end; i++ )
457 if( buf[i] == BLANK )
458 buf[i] = PATCH_CHAR;
459}
460
461/** read a mps format data line and parse the fields. */
462static
464 MPSINPUT* mpsi /**< mps input structure */
465 )
466{
467 unsigned int len;
468 unsigned int i;
469 int space;
470 char* s;
471 SCIP_Bool is_marker;
472 SCIP_Bool is_empty;
473 char* nexttok;
474
475 do
476 {
477 mpsi->f0 = mpsi->f1 = mpsi->f2 = mpsi->f3 = mpsi->f4 = mpsi->f5 = 0;
478 is_marker = FALSE;
479
480 /* Read until we have not a comment line. */
481 do
482 {
483 mpsi->buf[MPS_MAX_LINELEN-1] = '\0';
484 if( NULL == SCIPfgets(mpsi->buf, (int) sizeof(mpsi->buf), mpsi->fp) )
485 return FALSE;
486 mpsi->lineno++;
487 }
488 while( *mpsi->buf == '*' ); /* coverity[a_loop_bound] */
489
490 /* Normalize line */
491 len = (unsigned int) strlen(mpsi->buf);
492
493 for( i = 0; i < len; i++ )
494 if( (mpsi->buf[i] == '\t') || (mpsi->buf[i] == '\n') || (mpsi->buf[i] == '\r') )
495 mpsi->buf[i] = BLANK;
496
497 if( len < 80 )
498 clearFrom(mpsi->buf, len);
499
500 SCIPdebugMessage("line %d: <%s>\n", mpsi->lineno, mpsi->buf);
501
502 assert(strlen(mpsi->buf) >= 80);
503
504 /* Look for new section */
505 if( *mpsi->buf != BLANK )
506 {
507 mpsi->f0 = SCIPstrtok(&mpsi->buf[0], " ", &nexttok);
508
509 assert(mpsi->f0 != 0);
510
511 mpsi->f1 = SCIPstrtok(NULL, " ", &nexttok);
512
513 return TRUE;
514 }
515
516 /* If we decide to use the new format we never revert this decision */
517 if( !mpsi->isnewformat )
518 {
519 /* Test for fixed format comments */
520 if( (mpsi->buf[14] == '$') && (mpsi->buf[13] == ' ') )
521 clearFrom(mpsi->buf, 14);
522 else if( (mpsi->buf[39] == '$') && (mpsi->buf[38] == ' ') )
523 clearFrom(mpsi->buf, 39);
524
525 /* Test for fixed format */
526 space = mpsi->buf[12] | mpsi->buf[13]
527 | mpsi->buf[22] | mpsi->buf[23]
528 | mpsi->buf[36] | mpsi->buf[37] | mpsi->buf[38]
529 | mpsi->buf[47] | mpsi->buf[48]
530 | mpsi->buf[61] | mpsi->buf[62] | mpsi->buf[63];
531
532 if( space == BLANK )
533 {
534 /* Now we have space at the right positions.
535 * But are there also the non space where they
536 * should be ?
537 */
539
540 number = isdigit((unsigned char)mpsi->buf[24]) || isdigit((unsigned char)mpsi->buf[25])
541 || isdigit((unsigned char)mpsi->buf[26]) || isdigit((unsigned char)mpsi->buf[27])
542 || isdigit((unsigned char)mpsi->buf[28]) || isdigit((unsigned char)mpsi->buf[29])
543 || isdigit((unsigned char)mpsi->buf[30]) || isdigit((unsigned char)mpsi->buf[31])
544 || isdigit((unsigned char)mpsi->buf[32]) || isdigit((unsigned char)mpsi->buf[33])
545 || isdigit((unsigned char)mpsi->buf[34]) || isdigit((unsigned char)mpsi->buf[35]);
546
547 /* len < 14 is handle ROW lines with embedded spaces
548 * in the names correctly
549 */
550 if( number || len < 14 )
551 {
552 /* We assume fixed format, so we patch possible embedded spaces. */
553 patchField(mpsi->buf, 4, 12);
554 patchField(mpsi->buf, 14, 22);
555 patchField(mpsi->buf, 39, 47);
556 }
557 else
558 {
559 if( mpsi->section == MPS_COLUMNS || mpsi->section == MPS_RHS
560 || mpsi->section == MPS_RANGES || mpsi->section == MPS_BOUNDS )
561 mpsi->isnewformat = TRUE;
562 }
563 }
564 else
565 {
566 mpsi->isnewformat = TRUE;
567 }
568 }
569 s = &mpsi->buf[1];
570
571 /* At this point it is not clear if we have a indicator field.
572 * If there is none (e.g. empty) f1 will be the first name field.
573 * If there is one, f2 will be the first name field.
574 *
575 * Initially comment marks '$' are only allowed in the beginning
576 * of the 2nd and 3rd name field. We test all fields but the first.
577 * This makes no difference, since if the $ is at the start of a value
578 * field, the line will be erroneous anyway.
579 */
580 do
581 {
582 if( NULL == (mpsi->f1 = SCIPstrtok(s, " ", &nexttok)) )
583 break;
584
585 if( (NULL == (mpsi->f2 = SCIPstrtok(NULL, " ", &nexttok))) || (*mpsi->f2 == '$') )
586 {
587 mpsi->f2 = 0;
588 break;
589 }
590 if( !strcmp(mpsi->f2, "'MARKER'") )
591 is_marker = TRUE;
592
593 if( (NULL == (mpsi->f3 = SCIPstrtok(NULL, " ", &nexttok))) || (*mpsi->f3 == '$') )
594 {
595 mpsi->f3 = 0;
596 break;
597 }
598 if( is_marker )
599 {
600 if( !strcmp(mpsi->f3, "'INTORG'") )
601 mpsi->isinteger = TRUE;
602 else if( !strcmp(mpsi->f3, "'INTEND'") )
603 mpsi->isinteger = FALSE;
604 else
605 break; /* unknown marker */
606 }
607 if( !strcmp(mpsi->f3, "'MARKER'") )
608 is_marker = TRUE;
609
610 if( (NULL == (mpsi->f4 = SCIPstrtok(NULL, " ", &nexttok))) || (*mpsi->f4 == '$') )
611 {
612 mpsi->f4 = 0;
613 break;
614 }
615 if( is_marker )
616 {
617 if( !strcmp(mpsi->f4, "'INTORG'") )
618 mpsi->isinteger = TRUE;
619 else if( !strcmp(mpsi->f4, "'INTEND'") )
620 mpsi->isinteger = FALSE;
621 else
622 break; /* unknown marker */
623 }
624 if( (NULL == (mpsi->f5 = SCIPstrtok(NULL, " ", &nexttok))) || (*mpsi->f5 == '$') )
625 mpsi->f5 = 0;
626 }
627 while( FALSE );
628
629 /* check for empty lines */
630 is_empty = (mpsi->f0 == NULL && mpsi->f1 == NULL);
631 }
632 while( is_marker || is_empty );
633
634 return TRUE;
635}
636
637/** Insert \p str as field 4 and shift all other fields up. */
638static
640 MPSINPUT* mpsi, /**< mps input structure */
641 const char* str /**< str to insert */
642 )
643{
644 assert(mpsi != NULL);
645 assert(str != NULL);
646
647 mpsi->f5 = mpsi->f4;
648 mpsi->f4 = str;
649}
650
651/** Insert \p name as field 1 or 2 and shift all other fields up. */
652static
654 MPSINPUT* mpsi, /**< mps input structure */
655 const char* name, /**< name to insert */
656 SCIP_Bool second /**< insert as second field? */
657 )
658{
659 assert(mpsi != NULL);
660 assert(name != NULL);
661
662 mpsi->f5 = mpsi->f4;
663 mpsi->f4 = mpsi->f3;
664 mpsi->f3 = mpsi->f2;
665
666 if( second )
667 mpsi->f2 = name;
668 else
669 {
670 mpsi->f2 = mpsi->f1;
671 mpsi->f1 = name;
672 }
673}
674
675/** Add variable name to storage */
676static
678 SCIP* scip, /**< SCIP data structure */
679 const char*** varnames, /**< the variable name storage */
680 int* varnamessize, /**< the size of the variable names storage */
681 int* nvars, /**< the number of variables */
682 const char* colname /**< the name of the variable */
683 )
684{
685 assert(scip != NULL);
686
687 if( varnames != NULL )
688 {
689 SCIP_CALL( SCIPensureBlockMemoryArray(scip, varnames, varnamessize, (*nvars) + 1) );
690 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*varnames)[(*nvars)], colname, strlen(colname) + 1) ); /*lint !e866*/
691 (*nvars)++;
692 }
693
694 return SCIP_OKAY;
695}
696
697/** Add constraint name to storage */
698static
700 SCIP* scip, /**< SCIP data structure */
701 const char*** consnames, /**< the constraint name storage */
702 int* consnamessize, /**< the size of the constraint names storage */
703 int* ncons, /**< the number of constraint */
704 const char* rowname /**< the name of the constraint */
705 )
706{
707 assert(scip != NULL);
708
709 if( consnames != NULL )
710 {
711 SCIP_CALL( SCIPensureBlockMemoryArray(scip, consnames, consnamessize, (*ncons) + 1) );
712 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consnames)[(*ncons)], rowname, strlen(rowname) + 1) ); /*lint !e866*/
713 (*ncons)++;
714 }
715
716 return SCIP_OKAY;
717}
718
719/** Process NAME section. */
720static
722 SCIP* scip, /**< SCIP data structure */
723 MPSINPUT* mpsi /**< mps input structure */
724 )
725{
726 assert(mpsi != NULL);
727
728 SCIPdebugMsg(scip, "read problem name\n");
729
730 /* This has to be the Line with the NAME section. */
731 if( !mpsinputReadLine(mpsi) || mpsinputField0(mpsi) == NULL || strcmp(mpsinputField0(mpsi), "NAME") )
732 {
734 return SCIP_OKAY;
735 }
736
737 /* Sometimes the name is omitted. */
738 mpsinputSetProbname(mpsi, (mpsinputField1(mpsi) == 0) ? "_MPS_" : mpsinputField1(mpsi));
739
740 /* This hat to be a new section */
741 /* coverity[tainted_data] */
742 if( !mpsinputReadLine(mpsi) || (mpsinputField0(mpsi) == NULL) )
743 {
745 return SCIP_OKAY;
746 }
747
748 if( !strncmp(mpsinputField0(mpsi), "ROWS", 4) )
750 else if( !strncmp(mpsinputField0(mpsi), "USERCUTS", 8) )
752 else if( !strncmp(mpsinputField0(mpsi), "LAZYCONS", 8) )
754 else if( !strncmp(mpsinputField0(mpsi), "OBJSEN", 6) )
756 else if( !strncmp(mpsinputField0(mpsi), "OBJNAME", 7) )
758 else
759 {
761 return SCIP_OKAY;
762 }
763
764 return SCIP_OKAY;
765}
766
767/** Process OBJSEN section. This Section is a CPLEX extension. */
768static
770 SCIP* scip, /**< SCIP data structure */
771 MPSINPUT* mpsi /**< mps input structure */
772 )
773{
774 assert(mpsi != NULL);
775
776 SCIPdebugMsg(scip, "read objective sense\n");
777
778 /* Although this is not explicitly in the MPS extensions as provided by CPLEX, some other MIP solvers
779 * (in particular gurobi), put 'MIN' or 'MAX' as the input field on the same line as the section declaration */
780 if( mpsinputField1(mpsi) == NULL){
781 /* Normal Cplex extension; info should be on the next line, in field 1 */
782 /* This has to be the Line with MIN or MAX. */
783 if( !mpsinputReadLine(mpsi) || (mpsinputField1(mpsi) == NULL) )
784 {
786 return SCIP_OKAY;
787 }
788 }
789 /* Otherwise, the input should read e.g. "OBJSENSE MAX" so that MAX is also the first field */
790
791 if( !strncmp(mpsinputField1(mpsi), "MIN", 3) )
793 else if( !strncmp(mpsinputField1(mpsi), "MAX", 3) )
795 else
796 {
798 return SCIP_OKAY;
799 }
800
801 /* Look for ROWS, USERCUTS, LAZYCONS, or OBJNAME Section */
802 /* coverity[tainted_data] */
803 if( !mpsinputReadLine(mpsi) || mpsinputField0(mpsi) == NULL )
804 {
806 return SCIP_OKAY;
807 }
808
809 if( !strcmp(mpsinputField0(mpsi), "ROWS") )
811 else if( !strcmp(mpsinputField0(mpsi), "USERCUTS") )
813 else if( !strcmp(mpsinputField0(mpsi), "LAZYCONS") )
815 else if( !strcmp(mpsinputField0(mpsi), "OBJNAME") )
817 else
818 {
820 return SCIP_OKAY;
821 }
822
823 return SCIP_OKAY;
824}
825
826/** Process OBJNAME section. This Section is a CPLEX extension. */
827static
829 SCIP* scip, /**< SCIP data structure */
830 MPSINPUT* mpsi /**< mps input structure */
831 )
832{
833 assert(mpsi != NULL);
834
835 SCIPdebugMsg(scip, "read objective name\n");
836
837 /* This has to be the Line with the name. */
838 if( !mpsinputReadLine(mpsi) || mpsinputField1(mpsi) == NULL )
839 {
841 return SCIP_OKAY;
842 }
843
845
846 /* Look for ROWS, USERCUTS, or LAZYCONS Section */
847 /* coverity[tainted_data] */
848 if( !mpsinputReadLine(mpsi) || mpsinputField0(mpsi) == NULL )
849 {
851 return SCIP_OKAY;
852 }
853 if( !strcmp(mpsinputField0(mpsi), "ROWS") )
855 else if( !strcmp(mpsinputField0(mpsi), "USERCUTS") )
857 else if( !strcmp(mpsinputField0(mpsi), "LAZYCONS") )
859 else
861
862 return SCIP_OKAY;
863}
864
865/** Process ROWS, USERCUTS, or LAZYCONS section. */
866static
868 MPSINPUT* mpsi, /**< mps input structure */
869 SCIP* scip, /**< SCIP data structure */
870 const char*** consnames, /**< storage for the constraint names, or NULL */
871 int* consnamessize, /**< the size of the constraint names storage, or NULL */
872 int* nconsnames /**< the number of stored constraint names, or NULL */
873 )
874{
875 SCIPdebugMsg(scip, "read rows\n");
876
877 /* coverity[tainted_data] */
878 while( mpsinputReadLine(mpsi) )
879 {
880 if( mpsinputField0(mpsi) != NULL )
881 {
882 if( !strcmp(mpsinputField0(mpsi), "ROWS") )
884 else if( !strcmp(mpsinputField0(mpsi), "USERCUTS") )
886 else if( !strcmp(mpsinputField0(mpsi), "LAZYCONS") )
888 else if( !strcmp(mpsinputField0(mpsi), "COLUMNS") )
890 else
892
893 return SCIP_OKAY;
894 }
895
896 if( *mpsinputField1(mpsi) == 'N' )
897 {
898 if( *mpsinputObjname(mpsi) == '\0' )
900 else
901 mpsinputEntryIgnored(scip, mpsi, "row", mpsinputField2(mpsi), "objective function", "N", SCIP_VERBLEVEL_NORMAL);
902 }
903 else
904 {
905 SCIP_CONS* cons;
906 SCIP_Bool initial;
907 SCIP_Bool separate;
908 SCIP_Bool enforce;
909 SCIP_Bool check;
910 SCIP_Bool propagate;
911 SCIP_Bool local;
912 SCIP_Bool modifiable;
913 SCIP_Bool dynamic;
914 SCIP_Bool removable;
915
916 cons = SCIPfindCons(scip, mpsinputField2(mpsi));
917 if( cons != NULL )
918 break;
919
920 initial = mpsi->initialconss && (mpsinputSection(mpsi) == MPS_ROWS);
921 separate = TRUE;
922 enforce = (mpsinputSection(mpsi) != MPS_USERCUTS);
923 check = (mpsinputSection(mpsi) != MPS_USERCUTS);
924 propagate = TRUE;
925 local = FALSE;
926 modifiable = FALSE;
927 dynamic = mpsi->dynamicconss;
928 removable = mpsi->dynamicrows || (mpsinputSection(mpsi) == MPS_USERCUTS);
929
930 switch(*mpsinputField1(mpsi))
931 {
932 case 'G' :
934 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE) );
935 break;
936 case 'E' :
937 SCIP_CALL( SCIPcreateConsLinear(scip, &cons, mpsinputField2(mpsi), 0, NULL, NULL, 0.0, 0.0,
938 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE) );
939 break;
940 case 'L' :
942 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE) );
943 break;
944 default :
946 return SCIP_OKAY;
947 }
948 SCIP_CALL( SCIPaddCons(scip, cons) );
949 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
950
951 /* if the file is of type cor, then the constraint names must be stored */
952 SCIP_CALL( addConsNameToStorage(scip, consnames, consnamessize, nconsnames, mpsinputField2(mpsi)) );
953 }
954 }
956
957 return SCIP_OKAY;
958}
959
960/** Process COLUMNS section. */
961static
963 MPSINPUT* mpsi, /**< mps input structure */
964 SCIP* scip, /**< SCIP data structure */
965 const char*** varnames, /**< storage for the variable names, or NULL */
966 int* varnamessize, /**< the size of the variable names storage, or NULL */
967 int* nvarnames /**< the number of stored variable names, or NULL */
968 )
969{
970 char colname[MPS_MAX_NAMELEN] = { '\0' };
971 SCIP_CONS* cons;
972 SCIP_VAR* var;
973 SCIP_Real val;
974 SCIP_Bool usevartable;
975
976 SCIPdebugMsg(scip, "read columns\n");
977
978 var = NULL;
979 SCIP_CALL( SCIPgetBoolParam(scip, "misc/usevartable", &usevartable) );
980
981 while( mpsinputReadLine(mpsi) )
982 {
983 if( mpsinputField0(mpsi) != 0 )
984 {
985 if( strcmp(mpsinputField0(mpsi), "RHS") )
986 break;
987
988 /* add the last variable to the problem */
989 if( var != NULL )
990 {
991 SCIP_CALL( SCIPaddVar(scip, var) );
992 SCIP_CALL( SCIPreleaseVar(scip, &var) );
993 }
994 assert(var == NULL);
995
997 return SCIP_OKAY;
998 }
999 if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL || mpsinputField3(mpsi) == NULL )
1000 break;
1001
1002 /* new column? */
1003 if( strcmp(colname, mpsinputField1(mpsi)) )
1004 {
1005 /* add the last variable to the problem */
1006 if( var != NULL )
1007 {
1008 SCIP_CALL( SCIPaddVar(scip, var) );
1009 SCIP_CALL( SCIPreleaseVar(scip, &var) );
1010 }
1011 assert(var == NULL);
1012
1013 (void)SCIPmemccpy(colname, mpsinputField1(mpsi), '\0', MPS_MAX_NAMELEN - 1);
1014
1015 /* check whether we have seen this variable before, this would not allowed */
1016 if( usevartable && SCIPfindVar(scip, colname) != NULL )
1017 {
1018 SCIPerrorMessage("Coeffients of column <%s> don't appear consecutively (line: %d)\n",
1019 colname, mpsi->lineno);
1020
1021 return SCIP_READERROR;
1022 }
1023
1024 /* if the file type is a cor file, the the variable name must be stored */
1025 SCIP_CALL( addVarNameToStorage(scip, varnames, varnamessize, nvarnames, colname) );
1026
1027 if( mpsinputIsInteger(mpsi) )
1028 {
1029 /* for integer variables, default bounds are 0 <= x < 1(not +infinity, like it is for continuous variables), and default cost is 0 */
1030 SCIP_CALL( SCIPcreateVar(scip, &var, colname, 0.0, 1.0, 0.0, SCIP_VARTYPE_BINARY,
1031 !mpsi->dynamiccols, mpsi->dynamiccols, NULL, NULL, NULL, NULL, NULL) );
1032 }
1033 else
1034 {
1035 /* for continuous variables, default bounds are 0 <= x, and default cost is 0 */
1037 !mpsi->dynamiccols, mpsi->dynamiccols, NULL, NULL, NULL, NULL, NULL) );
1038 }
1039 }
1040 assert(var != NULL);
1041
1042 val = atof(mpsinputField3(mpsi));
1043
1044 if( !strcmp(mpsinputField2(mpsi), mpsinputObjname(mpsi)) )
1045 {
1046 SCIP_CALL( SCIPchgVarObj(scip, var, val) );
1047 }
1048 else
1049 {
1050 cons = SCIPfindCons(scip, mpsinputField2(mpsi));
1051 if( cons == NULL )
1052 mpsinputEntryIgnored(scip, mpsi, "Column", mpsinputField1(mpsi), "row", mpsinputField2(mpsi), SCIP_VERBLEVEL_FULL);
1053 else if( !SCIPisZero(scip, val) )
1054 {
1055 /* warn the user in case the coefficient is infinite */
1056 if( SCIPisInfinity(scip, REALABS(val)) )
1057 {
1058 SCIPwarningMessage(scip, "Coefficient of variable <%s> in constraint <%s> contains infinite value <%e>,"
1059 " consider adjusting SCIP infinity.\n", SCIPvarGetName(var), SCIPconsGetName(cons), val);
1060 }
1061 SCIP_CALL( SCIPaddCoefLinear(scip, cons, var, val) );
1062 }
1063 }
1064 if( mpsinputField5(mpsi) != NULL )
1065 {
1066 assert(mpsinputField4(mpsi) != NULL);
1067
1068 val = atof(mpsinputField5(mpsi));
1069
1070 if( !strcmp(mpsinputField4(mpsi), mpsinputObjname(mpsi)) )
1071 {
1072 SCIP_CALL( SCIPchgVarObj(scip, var, val) );
1073 }
1074 else
1075 {
1076 cons = SCIPfindCons(scip, mpsinputField4(mpsi));
1077 if( cons == NULL )
1078 mpsinputEntryIgnored(scip, mpsi, "Column", mpsinputField1(mpsi), "row", mpsinputField4(mpsi), SCIP_VERBLEVEL_FULL);
1079 else if( !SCIPisZero(scip, val) )
1080 {
1081 SCIP_CALL( SCIPaddCoefLinear(scip, cons, var, val) );
1082 }
1083 }
1084 }
1085 }
1086 mpsinputSyntaxerror(mpsi);
1087
1088 return SCIP_OKAY;
1089}
1090
1091/** Process RHS section. */
1092static
1094 MPSINPUT* mpsi, /**< mps input structure */
1095 SCIP* scip /**< SCIP data structure */
1096 )
1097{
1098 char rhsname[MPS_MAX_NAMELEN] = { '\0' };
1099 SCIP_CONS* cons;
1100 SCIP_Real lhs;
1101 SCIP_Real rhs;
1102 SCIP_Real val;
1103
1104 SCIPdebugMsg(scip, "read right hand sides\n");
1105
1106 while( mpsinputReadLine(mpsi) )
1107 {
1108 if( mpsinputField0(mpsi) != NULL )
1109 {
1110 if( !strcmp(mpsinputField0(mpsi), "RANGES") )
1112 else if( !strcmp(mpsinputField0(mpsi), "BOUNDS") )
1114 else if( !strcmp(mpsinputField0(mpsi), "SOS") )
1116 else if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
1118 else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
1120 else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
1122 else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
1124 else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
1126 else
1127 break;
1128 return SCIP_OKAY;
1129 }
1130 if( (mpsinputField2(mpsi) != NULL && mpsinputField3(mpsi) == NULL)
1131 || (mpsinputField4(mpsi) != NULL && mpsinputField5(mpsi) == NULL) )
1132 {
1133 SCIPwarningMessage(scip, "reading rhs section, a field is missing, assuming that the vector name is the missing one(, row identfier <%s>)\n", mpsinputField2(mpsi));
1134
1135 mpsinputInsertName(mpsi, "_RHS_", FALSE);
1136 }
1137
1138 if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL || mpsinputField3(mpsi) == NULL )
1139 break;
1140
1141 if( *rhsname == '\0' )
1142 (void)SCIPmemccpy(rhsname, mpsinputField1(mpsi), '\0', MPS_MAX_NAMELEN - 1);
1143
1144 if( !strcmp(rhsname, mpsinputField1(mpsi)) )
1145 {
1146 cons = SCIPfindCons(scip, mpsinputField2(mpsi));
1147 if( cons == NULL )
1148 {
1149 /* the rhs of the objective row is treated as objective constant */
1150 if( strcmp(mpsinputField2(mpsi), mpsinputObjname(mpsi)) == 0 )
1151 {
1152 val = atof(mpsinputField3(mpsi));
1154 }
1155 else
1157 }
1158 else
1159 {
1160 val = atof(mpsinputField3(mpsi));
1161
1162 /* find out the row sense */
1163 lhs = SCIPgetLhsLinear(scip, cons);
1164 rhs = SCIPgetRhsLinear(scip, cons);
1165 if( SCIPisInfinity(scip, -lhs) )
1166 {
1167 /* lhs = -infinity -> lower or equal */
1168 assert(SCIPisZero(scip, rhs));
1169 SCIP_CALL( SCIPchgRhsLinear(scip, cons, val) );
1170 }
1171 else if( SCIPisInfinity(scip, rhs) )
1172 {
1173 /* rhs = +infinity -> greater or equal */
1174 assert(SCIPisZero(scip, lhs));
1175 SCIP_CALL( SCIPchgLhsLinear(scip, cons, val) );
1176 }
1177 else
1178 {
1179 /* lhs > -infinity, rhs < infinity -> equality */
1180 assert(SCIPisZero(scip, lhs));
1181 assert(SCIPisZero(scip, rhs));
1182 SCIP_CALL( SCIPchgLhsLinear(scip, cons, val) );
1183 SCIP_CALL( SCIPchgRhsLinear(scip, cons, val) );
1184 }
1185 SCIPdebugMsg(scip, "RHS <%s> lhs: %g rhs: %g val: <%22.12g>\n", mpsinputField2(mpsi), lhs, rhs, val);
1186 }
1187 if( mpsinputField5(mpsi) != NULL )
1188 {
1189 cons = SCIPfindCons(scip, mpsinputField4(mpsi));
1190 if( cons == NULL )
1191 {
1192 /* the rhs of the objective row is treated as objective constant */
1193 if( strcmp(mpsinputField4(mpsi), mpsinputObjname(mpsi)) == 0 )
1194 {
1195 val = atof(mpsinputField5(mpsi));
1197 }
1198 else
1200 }
1201 else
1202 {
1203 val = atof(mpsinputField5(mpsi));
1204
1205 /* find out the row sense */
1206 lhs = SCIPgetLhsLinear(scip, cons);
1207 rhs = SCIPgetRhsLinear(scip, cons);
1208 if( SCIPisInfinity(scip, -lhs) )
1209 {
1210 /* lhs = -infinity -> lower or equal */
1211 assert(SCIPisZero(scip, rhs));
1212 SCIP_CALL( SCIPchgRhsLinear(scip, cons, val) );
1213 }
1214 else if( SCIPisInfinity(scip, rhs) )
1215 {
1216 /* rhs = +infinity -> greater or equal */
1217 assert(SCIPisZero(scip, lhs));
1218 SCIP_CALL( SCIPchgLhsLinear(scip, cons, val) );
1219 }
1220 else
1221 {
1222 /* lhs > -infinity, rhs < infinity -> equality */
1223 assert(SCIPisZero(scip, lhs));
1224 assert(SCIPisZero(scip, rhs));
1225 SCIP_CALL( SCIPchgLhsLinear(scip, cons, val) );
1226 SCIP_CALL( SCIPchgRhsLinear(scip, cons, val) );
1227 }
1228 SCIPdebugMsg(scip, "RHS <%s> lhs: %g rhs: %g val: <%22.12g>\n", mpsinputField4(mpsi), lhs, rhs, val);
1229 }
1230 }
1231 }
1232 }
1233 mpsinputSyntaxerror(mpsi);
1234
1235 return SCIP_OKAY;
1236}
1237
1238/** Process RANGES section */
1239static
1241 MPSINPUT* mpsi, /**< mps input structure */
1242 SCIP* scip /**< SCIP data structure */
1243 )
1244{
1245 char rngname[MPS_MAX_NAMELEN] = { '\0' };
1246 SCIP_CONS* cons;
1247 SCIP_Real lhs;
1248 SCIP_Real rhs;
1249 SCIP_Real val;
1250
1251 SCIPdebugMsg(scip, "read ranges\n");
1252
1253 while( mpsinputReadLine(mpsi) )
1254 {
1255 if( mpsinputField0(mpsi) != NULL )
1256 {
1257 if( !strcmp(mpsinputField0(mpsi), "BOUNDS") )
1259 else if( !strcmp(mpsinputField0(mpsi), "SOS") )
1261 else if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
1263 else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
1265 else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
1267 else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
1269 else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
1271 else
1272 break;
1273 return SCIP_OKAY;
1274 }
1275 if( (mpsinputField2(mpsi) != NULL && mpsinputField3(mpsi) == NULL)
1276 || (mpsinputField4(mpsi) != NULL && mpsinputField5(mpsi) == NULL) )
1277 {
1278 SCIPwarningMessage(scip, "reading ranged section, a field is missing, assuming that the vector name is the missing one(, row identfier <%s>)\n", mpsinputField2(mpsi));
1279
1280 mpsinputInsertName(mpsi, "_RNG_", FALSE);
1281 }
1282
1283 if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL || mpsinputField3(mpsi) == NULL )
1284 break;
1285
1286 if( *rngname == '\0' )
1287 (void)SCIPmemccpy(rngname, mpsinputField1(mpsi), '\0', MPS_MAX_NAMELEN - 1);
1288
1289 /* The rules are:
1290 * Row Sign LHS RHS
1291 * ----------------------------------------
1292 * G +/- rhs rhs + |range|
1293 * L +/- rhs - |range| rhs
1294 * E + rhs rhs + range
1295 * E - rhs + range rhs
1296 * ----------------------------------------
1297 */
1298 if( !strcmp(rngname, mpsinputField1(mpsi)) )
1299 {
1300 cons = SCIPfindCons(scip, mpsinputField2(mpsi));
1301 if( cons == NULL )
1302 mpsinputEntryIgnored(scip, mpsi, "Range", mpsinputField1(mpsi), "row", mpsinputField2(mpsi), SCIP_VERBLEVEL_NORMAL);
1303 else
1304 {
1305 val = atof(mpsinputField3(mpsi));
1306
1307 /* find out the row sense */
1308 lhs = SCIPgetLhsLinear(scip, cons);
1309 rhs = SCIPgetRhsLinear(scip, cons);
1310 if( SCIPisInfinity(scip, -lhs) )
1311 {
1312 /* lhs = -infinity -> lower or equal */
1313 SCIP_CALL( SCIPchgLhsLinear(scip, cons, rhs - REALABS(val)) );
1314 }
1315 else if( SCIPisInfinity(scip, rhs) )
1316 {
1317 /* rhs = +infinity -> greater or equal */
1318 SCIP_CALL( SCIPchgRhsLinear(scip, cons, lhs + REALABS(val)) );
1319 }
1320 else
1321 {
1322 /* lhs > -infinity, rhs < infinity -> equality */
1323 assert(SCIPisEQ(scip, lhs, rhs));
1324 if( val >= 0.0 )
1325 {
1326 SCIP_CALL( SCIPchgRhsLinear(scip, cons, rhs + val) );
1327 }
1328 else
1329 {
1330 SCIP_CALL( SCIPchgLhsLinear(scip, cons, lhs + val) );
1331 }
1332 }
1333 }
1334 if( mpsinputField5(mpsi) != NULL )
1335 {
1336 cons = SCIPfindCons(scip, mpsinputField4(mpsi));
1337 if( cons == NULL )
1338 mpsinputEntryIgnored(scip, mpsi, "Range", mpsinputField1(mpsi), "row", mpsinputField4(mpsi), SCIP_VERBLEVEL_NORMAL);
1339 else
1340 {
1341 val = atof(mpsinputField5(mpsi));
1342
1343 /* find out the row sense */
1344 lhs = SCIPgetLhsLinear(scip, cons);
1345 rhs = SCIPgetRhsLinear(scip, cons);
1346 if( SCIPisInfinity(scip, -lhs) )
1347 {
1348 /* lhs = -infinity -> lower or equal */
1349 SCIP_CALL( SCIPchgLhsLinear(scip, cons, rhs - REALABS(val)) );
1350 }
1351 else if( SCIPisInfinity(scip, rhs) )
1352 {
1353 /* rhs = +infinity -> greater or equal */
1354 SCIP_CALL( SCIPchgRhsLinear(scip, cons, lhs + REALABS(val)) );
1355 }
1356 else
1357 {
1358 /* lhs > -infinity, rhs < infinity -> equality */
1359 assert(SCIPisEQ(scip, lhs, rhs));
1360 if( val >= 0.0 )
1361 {
1362 SCIP_CALL( SCIPchgRhsLinear(scip, cons, rhs + val) );
1363 }
1364 else
1365 {
1366 SCIP_CALL( SCIPchgLhsLinear(scip, cons, lhs + val) );
1367 }
1368 }
1369 }
1370 }
1371 }
1372 }
1373 mpsinputSyntaxerror(mpsi);
1374
1375 return SCIP_OKAY;
1376}
1377
1378/** Process BOUNDS section. */
1379static
1381 MPSINPUT* mpsi, /**< mps input structure */
1382 SCIP* scip /**< SCIP data structure */
1383 )
1384{
1385 char bndname[MPS_MAX_NAMELEN] = { '\0' };
1386 SCIP_VAR* var;
1387 SCIP_RETCODE retcode;
1388 SCIP_Real val;
1389 SCIP_Bool shifted;
1390
1391 SCIP_VAR** semicont;
1392 int nsemicont;
1393 int semicontsize;
1394
1395 retcode = SCIP_OKAY;
1396
1397 semicont = NULL;
1398 nsemicont = 0;
1399 semicontsize = 0;
1400
1401 SCIPdebugMsg(scip, "read bounds\n");
1402
1403 while( mpsinputReadLine(mpsi) )
1404 {
1405 if( mpsinputField0(mpsi) != 0 )
1406 {
1407 if( !strcmp(mpsinputField0(mpsi), "SOS") )
1409 else if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
1411 else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
1413 else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
1415 else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
1417 else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
1419 else
1420 break;
1421 goto READBOUNDS_FINISH;
1422 }
1423
1424 shifted = FALSE;
1425
1426 /* Is the value field used ? */
1427 if( !strcmp(mpsinputField1(mpsi), "LO") /* lower bound given in field 4 */
1428 || !strcmp(mpsinputField1(mpsi), "UP") /* upper bound given in field 4 */
1429 || !strcmp(mpsinputField1(mpsi), "FX") /* fixed value given in field 4 */
1430 || !strcmp(mpsinputField1(mpsi), "LI") /* CPLEX extension: lower bound of integer variable given in field 4 */
1431 || !strcmp(mpsinputField1(mpsi), "UI") /* CPLEX extension: upper bound of integer variable given in field 4 */
1432 || !strcmp(mpsinputField1(mpsi), "SC") /* CPLEX extension: semi-continuous variable, upper bound given in field 4 */
1433 || !strcmp(mpsinputField1(mpsi), "SI") )/* CPLEX extension: semi-integer variable, upper bound given in field 4 */
1434 {
1435 if( mpsinputField3(mpsi) != NULL && mpsinputField4(mpsi) == NULL )
1436 {
1437 int l;
1438
1439 /* check what might be missing, if field 3 is a number the bound name might be missing */
1440 for( l = (int) strlen(mpsinputField3(mpsi)) - 1; l >= 0; --l )
1441 {
1442 if( mpsinputField3(mpsi)[l] != '.' && !isdigit(mpsinputField3(mpsi)[l]) )
1443 break;
1444 }
1445
1446 /* the bound name?! is missing */
1447 if( l < 0 )
1448 {
1449 SCIPwarningMessage(scip, "in bound section a name for value <%s> might be missing\n", mpsinputField3(mpsi));
1450
1451 mpsinputInsertName(mpsi, "_BND_", TRUE);
1452 shifted = TRUE;
1453 }
1454 /* the bound is be missing */
1455 else
1456 {
1457 SCIPwarningMessage(scip, "in bound section a value for column <%s> is missing, assuming 0.0\n", mpsinputField3(mpsi));
1458
1459 mpsinputInsertField4(mpsi, "0.0");
1460 shifted = TRUE;
1461 }
1462 }
1463 }
1464 else if( !strcmp(mpsinputField1(mpsi), "FR") /* free variable */
1465 || !strcmp(mpsinputField1(mpsi), "MI") /* lower bound is minus infinity */
1466 || !strcmp(mpsinputField1(mpsi), "PL") /* upper bound is plus infinity */
1467 || !strcmp(mpsinputField1(mpsi), "BV") ) /* CPLEX extension: binary variable */
1468 {
1469 if( mpsinputField2(mpsi) != NULL && mpsinputField3(mpsi) == NULL )
1470 {
1471 SCIPwarningMessage(scip, "in bound section a name for a column is missing\n");
1472
1473 mpsinputInsertName(mpsi, "_BND_", TRUE);
1474 shifted = TRUE;
1475 }
1476 }
1477 else
1478 {
1479 mpsinputSyntaxerror(mpsi);
1480 return SCIP_OKAY;
1481 }
1482
1483 if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL || mpsinputField3(mpsi) == NULL )
1484 break;
1485
1486 if( *bndname == '\0' )
1487 (void)SCIPmemccpy(bndname, mpsinputField2(mpsi), '\0', MPS_MAX_NAMELEN - 1);
1488
1489 /* Only read the first Bound in section */
1490 if( !strcmp(bndname, mpsinputField2(mpsi)) )
1491 {
1492 SCIP_VARTYPE oldvartype;
1493 SCIP_Bool infeasible;
1494
1495 var = SCIPfindVar(scip, mpsinputField3(mpsi));
1496 /* if variable did not appear in columns section before, then it may still come in later sections (QCMATRIX, QMATRIX, SOS, ...)
1497 * thus add it as continuous variables, which has default bounds 0.0 <= x, and default cost 0.0 */
1498 if( var == NULL )
1499 {
1500 SCIP_VAR* varcpy;
1501
1502 SCIP_CALL( SCIPcreateVar(scip, &var, mpsinputField3(mpsi), 0.0, SCIPinfinity(scip), 0.0,
1503 SCIP_VARTYPE_CONTINUOUS, !mpsi->dynamiccols, mpsi->dynamiccols, NULL, NULL, NULL, NULL, NULL) );
1504
1505 SCIP_CALL( SCIPaddVar(scip, var) );
1506 varcpy = var;
1507 SCIP_CALL( SCIPreleaseVar(scip, &varcpy) );
1508 /* mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField3(mpsi), "bound", bndname, SCIP_VERBLEVEL_NORMAL); */
1509 }
1510 assert(var != NULL);
1511
1512 if( mpsinputField4(mpsi) == NULL )
1513 val = 0.0;
1514 else
1515 val = atof(mpsinputField4(mpsi));
1516
1517 /* remember variable type */
1518 oldvartype = SCIPvarGetType(var);
1519
1520 /* If a bound of a binary variable is given, the variable is converted into an integer variable
1521 * with default bounds 0 <= x <= infinity before applying the bound. Note that integer variables
1522 * are by default assumed to be binary, but an explicit lower bound of 0 turns them into integer variables.
1523 * Only if the upper bound is explicitly set to 1, we leave the variable as a binary one.
1524 */
1525 if( oldvartype == SCIP_VARTYPE_BINARY && !((mpsinputField1(mpsi)[0] == 'U' ||
1526 (mpsinputField1(mpsi)[0] == 'F' && mpsinputField1(mpsi)[1] == 'X')) && SCIPisFeasEQ(scip, val, 1.0))
1527 && !(mpsinputField1(mpsi)[0] == 'F' && mpsinputField1(mpsi)[1] == 'X'&& SCIPisFeasEQ(scip, val, 0.0)) )
1528 {
1529 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
1530 assert(!infeasible);
1531
1532 oldvartype = SCIP_VARTYPE_INTEGER;
1534 }
1535
1536 /* switch variable type to continuous before applying the bound, this is necessary for stupid non-integral
1537 * bounds on general variables, which even might lead to infeasibility
1538 */
1539 if( oldvartype != SCIP_VARTYPE_CONTINUOUS )
1540 {
1542 /* relaxing variable type */
1544 }
1546
1547 switch( mpsinputField1(mpsi)[0] )
1548 {
1549 case 'L':
1551 {
1552 SCIPwarningMessage(scip, "Relaxing already defined lower bound %g of variable <%s> to %g not allowed.\n", SCIPvarGetLbGlobal(var), SCIPvarGetName(var), val);
1553 }
1554
1555 SCIP_CALL( SCIPchgVarLb(scip, var, val) );
1556
1557 if( mpsinputField1(mpsi)[1] == 'I' ) /* CPLEX extension (Integer Bound) */
1558 {
1559 if( !SCIPisFeasIntegral(scip, val) )
1560 {
1561 SCIPwarningMessage(scip, "variable <%s> declared as integral has a non-integral lower bound (%.14g) -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), val);
1562 }
1563 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
1564 /* don't assert feasibility here because the presolver will and should detect a infeasibility */
1565 }
1566 else if( oldvartype < SCIP_VARTYPE_CONTINUOUS )
1567 {
1568 if( !SCIPisFeasIntegral(scip, val) )
1569 {
1570 SCIPwarningMessage(scip, "variable <%s> declared as integral has a non-integral lower bound (%.14g) -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), val);
1571 }
1572 }
1573
1574 break;
1575 case 'U':
1576 if( SCIPisGT(scip, val, SCIPvarGetUbGlobal(var)) )
1577 {
1578 SCIPwarningMessage(scip, "Relaxing already defined upper bound %g of variable <%s> to %g not allowed.\n", SCIPvarGetUbGlobal(var), SCIPvarGetName(var), val);
1579 }
1580
1581 SCIP_CALL( SCIPchgVarUb(scip, var, val) );
1582 if( mpsinputField1(mpsi)[1] == 'I' ) /* CPLEX extension (Integer Bound) */
1583 {
1584 if( !SCIPisFeasIntegral(scip, val) )
1585 {
1586 SCIPwarningMessage(scip, "variable <%s> declared as integral has a non-integral upper bound (%.14g) -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), val);
1587 }
1588
1589 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
1590 /* don't assert feasibility here because the presolver will and should detect an infeasibility */
1591 }
1592 else if( oldvartype < SCIP_VARTYPE_CONTINUOUS )
1593 {
1594 if( !SCIPisFeasIntegral(scip, val) )
1595 {
1596 SCIPwarningMessage(scip, "variable <%s> declared as integral has a non-integral upper bound (%.14g) -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), val);
1597 }
1598 }
1599 break;
1600 case 'S':
1601 assert(mpsinputField1(mpsi)[1] == 'C' || mpsinputField1(mpsi)[1] == 'I'); /* semi-continuous or semi-integer (CPLEX extension) */
1602 /* remember that variable is semi-continuous/-integer */
1603 if( semicontsize <= nsemicont )
1604 {
1605 semicontsize = SCIPcalcMemGrowSize(scip, nsemicont+1);
1606 if( semicont == NULL )
1607 {
1608 SCIP_CALL( SCIPallocBufferArray(scip, &semicont, semicontsize) );
1609 }
1610 else
1611 {
1612 SCIP_CALL( SCIPreallocBufferArray(scip, &semicont, semicontsize) );
1613 }
1614 }
1615 assert(semicont != NULL);
1616 semicont[nsemicont] = var;
1617 ++nsemicont;
1618
1619 if( mpsinputField1(mpsi)[1] == 'I' ) /* variable is semi-integer, hence change its type to integer (the "semi" part will be handled below) */
1620 {
1621 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
1622 /* don't assert feasibility here because the presolver will and should detect an infeasibility */
1623 }
1624
1625 /* if both bounds are infinite anyway, we do not need to print a warning or change the bound */
1627 {
1628 if( SCIPisGT(scip, val, SCIPvarGetUbGlobal(var)) )
1629 {
1630 SCIPwarningMessage(scip, "Relaxing already defined upper bound %g of variable <%s> to %g not allowed.\n", SCIPvarGetUbGlobal(var), SCIPvarGetName(var), val);
1631 }
1632
1633 SCIP_CALL( SCIPchgVarUb(scip, var, val) );
1634 }
1635 break;
1636 case 'F':
1637 if( mpsinputField1(mpsi)[1] == 'X' )
1638 {
1639 SCIP_CALL( SCIPchgVarLb(scip, var, val) );
1640 SCIP_CALL( SCIPchgVarUb(scip, var, val) );
1641 }
1642 else
1643 {
1646 }
1647 break;
1648 case 'M':
1650 break;
1651 case 'P':
1653 break;
1654 case 'B' : /* CPLEX extension (Binary) */
1655 SCIP_CALL( SCIPchgVarLb(scip, var, 0.0) );
1656 SCIP_CALL( SCIPchgVarUb(scip, var, 1.0) );
1657 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
1658 /* don't assert feasibility here because the presolver will and should detect a infeasibility */
1659 break;
1660 default:
1661 mpsinputSyntaxerror(mpsi);
1662 return SCIP_OKAY;
1663 }
1664
1665 /* switch variable type back to old type if necessary */
1666 if( oldvartype < SCIPvarGetType(var) )
1667 {
1668 SCIP_CALL( SCIPchgVarType(scip, var, oldvartype, &infeasible) );
1669 }
1670 }
1671 else
1672 {
1673 /* check for syntax error */
1674 assert(*bndname != '\0');
1675 if( strcmp(bndname, mpsinputField3(mpsi)) == 0 && shifted )
1676 {
1677 mpsinputSyntaxerror(mpsi);
1678 return SCIP_OKAY;
1679 }
1680
1681 mpsinputEntryIgnored(scip, mpsi, "bound", mpsinputField2(mpsi), "variable", mpsinputField3(mpsi), SCIP_VERBLEVEL_NORMAL);
1682 }
1683 }
1684 mpsinputSyntaxerror(mpsi);
1685
1686 READBOUNDS_FINISH:
1687 if( nsemicont > 0 )
1688 {
1689 SCIP_CONS* cons;
1690 SCIP_VAR* vars[2];
1691 SCIP_BOUNDTYPE boundtypes[2];
1692 SCIP_Real bounds[2];
1693 char name[SCIP_MAXSTRLEN];
1694 SCIP_Real oldlb;
1695 int i;
1696
1697 assert(semicont != NULL);
1698
1699 /* add bound disjunction constraints for semi-continuous and semi-integer variables */
1700 for( i = 0; i < nsemicont; ++i )
1701 {
1702 var = semicont[i];
1704
1705 oldlb = SCIPvarGetLbGlobal(var);
1706 assert(oldlb >= 0.0);
1707
1708 /* if no bound was specified (which we assume if we see lower bound 0.0),
1709 * then the default lower bound for a semi-continuous variable is 1.0 */
1710 if( oldlb == 0.0 )
1711 oldlb = 1.0;
1712
1713 /* change the lower bound to 0.0 */
1714 SCIP_CALL( SCIPchgVarLb(scip, var, 0.0) );
1715
1716 /* add a bound disjunction constraint to say var <= 0.0 or var >= oldlb */
1717 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "semicont_%s", SCIPvarGetName(var));
1718
1719 vars[0] = var;
1720 vars[1] = var;
1721 boundtypes[0] = SCIP_BOUNDTYPE_UPPER;
1722 boundtypes[1] = SCIP_BOUNDTYPE_LOWER;
1723 bounds[0] = 0.0;
1724 bounds[1] = oldlb;
1725
1726 retcode = SCIPcreateConsBounddisjunction(scip, &cons, name, 2, vars, boundtypes, bounds,
1727 !mpsi->dynamiccols, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, mpsi->dynamicconss, mpsi->dynamiccols, FALSE);
1728
1729 if( retcode != SCIP_OKAY )
1730 break;
1731
1732 SCIP_CALL( SCIPaddCons(scip, cons) );
1733
1734 SCIPdebugMsg(scip, "add bound disjunction constraint for semi-continuity/-integrality of <%s>:\n\t", SCIPvarGetName(var));
1736
1737 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1738 }
1739 }
1740
1741 SCIPfreeBufferArrayNull(scip, &semicont);
1742
1743 SCIP_CALL( retcode );
1744
1745 return SCIP_OKAY;
1746}
1747
1748
1749/** Process SOS section.
1750 *
1751 * We read the SOS section, which is a nonstandard section introduced by CPLEX.
1752 *
1753 * @note Currently we do not support the standard way of specifying SOS constraints via markers.
1754 */
1755static
1757 MPSINPUT* mpsi, /**< mps input structure */
1758 SCIP* scip /**< SCIP data structure */
1759 )
1760{
1761 SCIP_Bool initial;
1762 SCIP_Bool separate;
1763 SCIP_Bool enforce;
1764 SCIP_Bool check;
1765 SCIP_Bool propagate;
1766 SCIP_Bool local;
1767 SCIP_Bool dynamic;
1768 SCIP_Bool removable;
1769 char name[MPS_MAX_NAMELEN] = { '\0' };
1770 SCIP_CONS* cons = NULL;
1771 int consType = -1;
1772 int cnt = 0;
1773
1774 SCIPdebugMsg(scip, "read SOS constraints\n");
1775
1776 /* standard settings for SOS constraints: */
1777 initial = mpsi->initialconss;
1778 separate = TRUE;
1779 enforce = TRUE;
1780 check = TRUE;
1781 propagate = TRUE;
1782 local = FALSE;
1783 dynamic = mpsi->dynamicconss;
1784 removable = mpsi->dynamicrows;
1785
1786 /* loop through section */
1787 while( mpsinputReadLine(mpsi) )
1788 {
1789 int type = -1;
1790
1791 /* check if next section is found */
1792 if( mpsinputField0(mpsi) != NULL )
1793 {
1794 if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
1796 else if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
1798 else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
1800 else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
1802 else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
1804 break;
1805 }
1806 if( mpsinputField1(mpsi) == NULL )
1807 {
1808 SCIPerrorMessage("empty data in a non-comment line.\n");
1809 mpsinputSyntaxerror(mpsi);
1810 return SCIP_OKAY;
1811 }
1812
1813 /* check for new SOS set */
1814 if( strcmp(mpsinputField1(mpsi), "S1") == 0 )
1815 type = 1;
1816 if( strcmp(mpsinputField1(mpsi), "S2") == 0 )
1817 type = 2;
1818
1819 /* add last constraint and create a new one */
1820 if( type > 0 )
1821 {
1822 assert( type == 1 || type == 2 );
1823 if( cons != NULL )
1824 {
1825 /* add last constraint */
1826 SCIP_CALL( SCIPaddCons(scip, cons) );
1827 SCIPdebugMsg(scip, "(line %d) added constraint <%s>: ", mpsi->lineno, SCIPconsGetName(cons));
1829 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1830 }
1831
1832 /* check name */
1833 if( mpsinputField2(mpsi) != NULL )
1834 (void)SCIPmemccpy(name, mpsinputField2(mpsi), '\0', MPS_MAX_NAMELEN - 1);
1835 else
1836 {
1837 /* create new name */
1838 (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "SOS%d", ++cnt);
1839 }
1840
1841 /* create new SOS constraint */
1842 if( type == 1 )
1843 {
1844 /* we do not know the name of the constraint */
1845 SCIP_CALL( SCIPcreateConsSOS1(scip, &cons, name, 0, NULL, NULL, initial, separate, enforce, check, propagate,
1846 local, dynamic, removable, FALSE) );
1847 }
1848 else
1849 {
1850 assert( type == 2 );
1851 SCIP_CALL( SCIPcreateConsSOS2(scip, &cons, name, 0, NULL, NULL, initial, separate, enforce, check, propagate,
1852 local, dynamic, removable, FALSE) );
1853 }
1854 consType = type;
1855 SCIPdebugMsg(scip, "created constraint <%s> of type %d.\n", name, type);
1856 /* note: we ignore the priorities! */
1857 }
1858 else
1859 {
1860 /* otherwise we are in the section given variables */
1861 SCIP_VAR* var;
1862 SCIP_Real weight;
1863 char* endptr;
1864
1865 if( consType != 1 && consType != 2 )
1866 {
1867 SCIPerrorMessage("missing SOS type specification.\n");
1868 mpsinputSyntaxerror(mpsi);
1869 return SCIP_OKAY;
1870 }
1871
1872 /* get variable */
1873 var = SCIPfindVar(scip, mpsinputField1(mpsi));
1874 if( var == NULL )
1875 {
1876 /* ignore unknown variables - we would not know the type anyway */
1877 mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField1(mpsi), "SOS", name, SCIP_VERBLEVEL_NORMAL);
1878 }
1879 else
1880 {
1881 /* get weight */
1882 if( NULL == mpsinputField2(mpsi) )
1883 {
1884 SCIPerrorMessage("weight for variable <%s> not specified.\n", mpsinputField1(mpsi));
1885 mpsinputSyntaxerror(mpsi);
1886 return SCIP_OKAY;
1887 }
1888
1889 weight = strtod(mpsinputField2(mpsi), &endptr);
1890 if( endptr == mpsinputField2(mpsi) || *endptr != '\0' )
1891 {
1892 SCIPerrorMessage("weight for variable <%s> not specified.\n", mpsinputField1(mpsi));
1893 mpsinputSyntaxerror(mpsi);
1894 return SCIP_OKAY;
1895 }
1896
1897 /* add variable and weight */
1898 assert( consType == 1 || consType == 2 );
1899 switch( consType )
1900 {
1901 case 1:
1902 SCIP_CALL( SCIPaddVarSOS1(scip, cons, var, weight) );
1903 break;
1904 case 2:
1905 SCIP_CALL( SCIPaddVarSOS2(scip, cons, var, weight) );
1906 break;
1907 /* coverity[dead_error_begin] */
1908 default:
1909 SCIPerrorMessage("unknown SOS type: <%d>\n", type); /* should not happen */
1910 SCIPABORT();
1911 return SCIP_INVALIDDATA; /*lint !e527*/
1912 }
1913 SCIPdebugMsg(scip, "added variable <%s> with weight %g.\n", SCIPvarGetName(var), weight);
1914 }
1915 /* check other fields */
1916 if( (mpsinputField3(mpsi) != NULL && *mpsinputField3(mpsi) != '\0' ) ||
1917 (mpsinputField4(mpsi) != NULL && *mpsinputField4(mpsi) != '\0' ) ||
1918 (mpsinputField5(mpsi) != NULL && *mpsinputField5(mpsi) != '\0' ) )
1919 {
1920 SCIPwarningMessage(scip, "ignoring data in fields 3-5 <%s> <%s> <%s>.\n",
1921 mpsinputField3(mpsi), mpsinputField4(mpsi), mpsinputField5(mpsi));
1922 }
1923 }
1924 }
1925
1926 if( cons != NULL )
1927 {
1928 /* add last constraint */
1929 SCIP_CALL( SCIPaddCons(scip, cons) );
1930 SCIPdebugMsg(scip, "(line %d) added constraint <%s>: ", mpsi->lineno, SCIPconsGetName(cons));
1932 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1933 }
1934
1935 return SCIP_OKAY;
1936}
1937
1938
1939/** Process QMATRIX or QUADOBJ section.
1940 *
1941 * - We read the QMATRIX or QUADOBJ section, which is a nonstandard section introduced by CPLEX.
1942 * - We create a quadratic constraint for this matrix and add a variable to the objective to
1943 * represent the value of the QMATRIX.
1944 * - For a QMATRIX, we expect that both lower and upper diagonal elements are given and every
1945 * coefficient has to be divided by 2.0.
1946 * - For a QUADOBJ, we expect that only the upper diagonal elements are given and thus only
1947 * coefficients on the diagonal have to be divided by 2.0.
1948 */
1949static
1951 MPSINPUT* mpsi, /**< mps input structure */
1952 SCIP_Bool isQuadObj, /**< whether we actually read a QUADOBJ section */
1953 SCIP* scip /**< SCIP data structure */
1954 )
1955{
1956 SCIP_VAR** quadvars1;
1957 SCIP_VAR** quadvars2;
1958 SCIP_Real* quadcoefs;
1959 SCIP_RETCODE retcode;
1960 int cnt = 0; /* number of qmatrix elements processed so far */
1961 int size; /* size of quad* arrays */
1962
1963 SCIPdebugMsg(scip, "read %s objective\n", isQuadObj ? "QUADOBJ" : "QMATRIX");
1964
1965 retcode = SCIP_OKAY;
1966
1967 size = 1;
1968 SCIP_CALL( SCIPallocBufferArray(scip, &quadvars1, size) );
1969 SCIP_CALL( SCIPallocBufferArray(scip, &quadvars2, size) );
1970 SCIP_CALL( SCIPallocBufferArray(scip, &quadcoefs, size) );
1971
1972 /* loop through section */
1973 /* coverity[tainted_data] */
1974 while( mpsinputReadLine(mpsi) )
1975 {
1976 /* otherwise we are in the section given variables */
1977 SCIP_VAR* var1;
1978 SCIP_VAR* var2;
1979 SCIP_Real coef;
1980
1981 /* check if next section is found */
1982 if( mpsinputField0(mpsi) != NULL )
1983 {
1984 if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
1986 else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
1988 else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
1990 break;
1991 }
1992 if( mpsinputField1(mpsi) == NULL && mpsinputField2(mpsi) == NULL )
1993 {
1994 SCIPerrorMessage("empty data in a non-comment line.\n");
1995 mpsinputSyntaxerror(mpsi);
1996 SCIPfreeBufferArray(scip, &quadvars1);
1997 SCIPfreeBufferArray(scip, &quadvars2);
1998 SCIPfreeBufferArray(scip, &quadcoefs);
1999 return SCIP_OKAY;
2000 }
2001
2002 /* get first variable */
2003 var1 = SCIPfindVar(scip, mpsinputField1(mpsi));
2004 if( var1 == NULL )
2005 {
2006 /* ignore unknown variables - we would not know the type anyway */
2007 mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField1(mpsi), "QMatrix", "QMATRIX", SCIP_VERBLEVEL_NORMAL);
2008 }
2009 else
2010 {
2011 int k;
2012 for( k = 1; k <= 2; ++k )
2013 {
2014 /* get second variable */
2015 var2 = SCIPfindVar(scip, k == 1 ? mpsinputField2(mpsi) : mpsinputField4(mpsi));
2016 if( var2 == NULL )
2017 {
2018 /* ignore unknown variables - we would not know the type anyway */
2019 mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField2(mpsi), "QMatrix", "QMATRIX", SCIP_VERBLEVEL_NORMAL);
2020 }
2021 else
2022 {
2023 const char* field;
2024 char* endptr;
2025
2026 /* get coefficient */
2027 field = (k == 1 ? mpsinputField3(mpsi) : mpsinputField5(mpsi));
2028 if( NULL == field )
2029 {
2030 SCIPerrorMessage("coefficient of term <%s>*<%s> not specified.\n", SCIPvarGetName(var1), SCIPvarGetName(var2));
2031 mpsinputSyntaxerror(mpsi);
2032 SCIPfreeBufferArray(scip, &quadvars1);
2033 SCIPfreeBufferArray(scip, &quadvars2);
2034 SCIPfreeBufferArray(scip, &quadcoefs);
2035 return SCIP_OKAY;
2036 }
2037
2038 coef = strtod(field, &endptr);
2039 if( endptr == field || *endptr != '\0' )
2040 {
2041 SCIPerrorMessage("coefficient of term <%s>*<%s> not specified.\n", SCIPvarGetName(var1), SCIPvarGetName(var2));
2042 mpsinputSyntaxerror(mpsi);
2043 SCIPfreeBufferArray(scip, &quadvars1);
2044 SCIPfreeBufferArray(scip, &quadvars2);
2045 SCIPfreeBufferArray(scip, &quadcoefs);
2046 return SCIP_OKAY;
2047 }
2048
2049 /* store variables and coefficient */
2050 if( cnt >= size )
2051 {
2052 int newsize = SCIPcalcMemGrowSize(scip, size+1);
2053 assert(newsize > size);
2054 SCIP_CALL( SCIPreallocBufferArray(scip, &quadvars1, newsize) );
2055 SCIP_CALL( SCIPreallocBufferArray(scip, &quadvars2, newsize) );
2056 SCIP_CALL( SCIPreallocBufferArray(scip, &quadcoefs, newsize) );
2057 size = newsize;
2058 }
2059 assert(cnt < size);
2060 quadvars1[cnt] = var1;
2061 quadvars2[cnt] = var2;
2062 quadcoefs[cnt] = coef;
2063
2064 /* diagonal elements have to be divided by 2.0
2065 * in a QMATRIX section also off-diagonal have to be divided by 2.0, since both lower and upper diagonal elements are given
2066 */
2067 if( var1 == var2 || !isQuadObj )
2068 quadcoefs[cnt] /= 2.0;
2069 ++cnt;
2070
2071 SCIPdebugMsg(scip, "stored term %g*<%s>*<%s>.\n", coef, SCIPvarGetName(var1), SCIPvarGetName(var2));
2072 }
2073
2074 if( mpsinputField4(mpsi) == NULL || *mpsinputField4(mpsi) == '\0' )
2075 break;
2076
2077 if( mpsinputField5(mpsi) == NULL || *mpsinputField5(mpsi) == '\0' )
2078 {
2079 /* ignore unknown variables - we would not know the type anyway */
2080 mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField4(mpsi), "QMatrix", "QMATRIX", SCIP_VERBLEVEL_NORMAL);
2081 break;
2082 }
2083 }
2084 }
2085 }
2086
2087 /* add constraint */
2088 if( cnt )
2089 {
2090 SCIP_Bool initial, separate, enforce, check, propagate;
2091 SCIP_Bool local, modifiable, dynamic, removable;
2092 SCIP_CONS* cons = NULL;
2093 SCIP_VAR* qmatrixvar = NULL;
2094 SCIP_Real lhs, rhs;
2095 SCIP_Real minusone = -1.0;
2096
2097 /* determine settings; note that reading/{initialconss,dynamicconss,dynamicrows,dynamiccols} apply only to model
2098 * constraints and variables, not to an auxiliary objective constraint (otherwise it can happen that an auxiliary
2099 * objective variable is loose with infinite best bound, triggering the problem that an LP that is unbounded
2100 * because of loose variables with infinite best bound cannot be solved)
2101 */
2102 initial = TRUE;
2103 separate = TRUE;
2104 enforce = TRUE;
2105 check = TRUE;
2106 propagate = TRUE;
2107 local = FALSE;
2108 modifiable = FALSE;
2109 dynamic = FALSE;
2110 removable = FALSE;
2111
2112 SCIP_CALL( SCIPcreateVar(scip, &qmatrixvar, "qmatrixvar", -SCIPinfinity(scip), SCIPinfinity(scip), 1.0,
2114 SCIP_CALL( SCIPaddVar(scip, qmatrixvar) );
2115
2117 {
2118 lhs = -SCIPinfinity(scip);
2119 rhs = 0.0;
2120 }
2121 else
2122 {
2123 lhs = 0.0;
2124 rhs = SCIPinfinity(scip);
2125 }
2126
2127 retcode = SCIPcreateConsQuadraticNonlinear(scip, &cons, "qmatrix", 1, &qmatrixvar, &minusone, cnt, quadvars1, quadvars2, quadcoefs, lhs, rhs,
2128 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable);
2129
2130 if( retcode == SCIP_OKAY )
2131 {
2132 SCIP_CALL( SCIPaddCons(scip, cons) );
2133 SCIPdebugMsg(scip, "(line %d) added constraint <%s>: ", mpsi->lineno, SCIPconsGetName(cons));
2135
2136 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
2137 SCIP_CALL( SCIPreleaseVar(scip, &qmatrixvar) );
2138 }
2139 }
2140 else
2141 {
2142 SCIPwarningMessage(scip, "%s section has no entries.\n", isQuadObj ? "QUADOBJ" : "QMATRIX");
2143 }
2144
2145 SCIPfreeBufferArray(scip, &quadvars1);
2146 SCIPfreeBufferArray(scip, &quadvars2);
2147 SCIPfreeBufferArray(scip, &quadcoefs);
2148
2149 SCIP_CALL( retcode );
2150
2151 return SCIP_OKAY;
2152}
2153
2154
2155/** Process QCMATRIX section.
2156 *
2157 * We read the QCMATRIX section, which is a nonstandard section introduced by CPLEX.
2158 *
2159 * We replace the corresponding linear constraint by a quadratic constraint which contains the
2160 * original linear constraint plus the quadratic part specified in the QCMATRIX.
2161 */
2162static
2164 MPSINPUT* mpsi, /**< mps input structure */
2165 SCIP* scip /**< SCIP data structure */
2166 )
2167{
2168 SCIP_CONS* lincons; /* the linear constraint that was added for the corresponding row */
2169 SCIP_VAR** quadvars1;
2170 SCIP_VAR** quadvars2;
2171 SCIP_Real* quadcoefs;
2172 SCIP_RETCODE retcode;
2173 int cnt = 0; /* number of qcmatrix elements processed so far */
2174 int size; /* size of quad* arrays */
2175
2176 if( mpsinputField1(mpsi) == NULL )
2177 {
2178 SCIPerrorMessage("no row name in QCMATRIX line.\n");
2179 mpsinputSyntaxerror(mpsi);
2180 return SCIP_OKAY;
2181 }
2182
2183 retcode = SCIP_OKAY;
2184
2185 SCIPdebugMsg(scip, "read QCMATRIX section for row <%s>\n", mpsinputField1(mpsi));
2186
2187 lincons = SCIPfindCons(scip, mpsinputField1(mpsi));
2188 if( lincons == NULL )
2189 {
2190 SCIPerrorMessage("no row under name <%s> processed so far.\n", mpsinputField1(mpsi));
2191 mpsinputSyntaxerror(mpsi);
2192 return SCIP_OKAY;
2193 }
2194
2195 size = 1;
2196 SCIP_CALL( SCIPallocBufferArray(scip, &quadvars1, size) );
2197 SCIP_CALL( SCIPallocBufferArray(scip, &quadvars2, size) );
2198 SCIP_CALL( SCIPallocBufferArray(scip, &quadcoefs, size) );
2199
2200 /* loop through section */
2201 /* coverity[tainted_data] */
2202 while( mpsinputReadLine(mpsi) )
2203 {
2204 /* otherwise we are in the section given variables */
2205 SCIP_VAR* var1;
2206 SCIP_VAR* var2;
2207 SCIP_Real coef;
2208
2209 /* check if next section is found */
2210 if( mpsinputField0(mpsi) != NULL )
2211 {
2212 if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
2214 else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
2216 else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
2218 else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
2220 else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
2222 break;
2223 }
2224 if( mpsinputField1(mpsi) == NULL && mpsinputField2(mpsi) == NULL )
2225 {
2226 SCIPerrorMessage("empty data in a non-comment line.\n");
2227 mpsinputSyntaxerror(mpsi);
2228
2229 goto TERMINATE;
2230 }
2231
2232 /* get first variable */
2233 var1 = SCIPfindVar(scip, mpsinputField1(mpsi));
2234 if( var1 == NULL )
2235 {
2236 /* ignore unknown variables - we would not know the type anyway */
2237 mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField1(mpsi), "QCMatrix", SCIPconsGetName(lincons), SCIP_VERBLEVEL_NORMAL);
2238 }
2239 else
2240 {
2241 /* get second variable */
2242 var2 = SCIPfindVar(scip, mpsinputField2(mpsi));
2243 if( var2 == NULL )
2244 {
2245 /* ignore unknown variables - we would not know the type anyway */
2246 mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField2(mpsi), "QCMatrix", SCIPconsGetName(lincons), SCIP_VERBLEVEL_NORMAL);
2247 }
2248 else
2249 {
2250 char* endptr;
2251 if( mpsinputField3(mpsi) == NULL )
2252 {
2253 SCIPerrorMessage("coefficient of term <%s>*<%s> not specified.\n", mpsinputField1(mpsi), mpsinputField2(mpsi));
2254 mpsinputSyntaxerror(mpsi);
2255
2256 goto TERMINATE;
2257 }
2258
2259 /* get coefficient */
2260 coef = strtod(mpsinputField3(mpsi), &endptr);
2261 if( endptr == mpsinputField3(mpsi) || *endptr != '\0' )
2262 {
2263 SCIPerrorMessage("coefficient of term <%s>*<%s> not specified.\n", mpsinputField1(mpsi), mpsinputField2(mpsi));
2264 mpsinputSyntaxerror(mpsi);
2265
2266 goto TERMINATE;
2267 }
2268
2269 /* store variables and coefficient */
2270 if( cnt >= size )
2271 {
2272 int newsize = SCIPcalcMemGrowSize(scip, size+1);
2273 assert(newsize > size);
2274 SCIP_CALL( SCIPreallocBufferArray(scip, &quadvars1, newsize) );
2275 SCIP_CALL( SCIPreallocBufferArray(scip, &quadvars2, newsize) );
2276 SCIP_CALL( SCIPreallocBufferArray(scip, &quadcoefs, newsize) );
2277 size = newsize;
2278 }
2279 assert(cnt < size);
2280 quadvars1[cnt] = var1;
2281 quadvars2[cnt] = var2;
2282 quadcoefs[cnt] = coef;
2283 ++cnt;
2284
2285 SCIPdebugMsg(scip, "stored term %g*<%s>*<%s>.\n", coef, SCIPvarGetName(var1), SCIPvarGetName(var2));
2286
2287 /* check other fields */
2288 if( (mpsinputField4(mpsi) != NULL && *mpsinputField4(mpsi) != '\0' ) ||
2289 (mpsinputField5(mpsi) != NULL && *mpsinputField5(mpsi) != '\0' ) )
2290 {
2291 SCIPwarningMessage(scip, "ignoring data in fields 4 and 5 <%s> <%s>.\n", mpsinputField4(mpsi), mpsinputField5(mpsi));
2292 }
2293 }
2294 }
2295 }
2296
2297 /* replace linear constraint by quadratic constraint */
2298 if( cnt )
2299 {
2300 SCIP_CONS* cons = NULL;
2301
2302 retcode = SCIPcreateConsQuadraticNonlinear(scip, &cons, SCIPconsGetName(lincons),
2303 SCIPgetNVarsLinear(scip, lincons), SCIPgetVarsLinear(scip, lincons), SCIPgetValsLinear(scip, lincons),
2304 cnt, quadvars1, quadvars2, quadcoefs, SCIPgetLhsLinear(scip, lincons), SCIPgetRhsLinear(scip, lincons),
2305 SCIPconsIsInitial(lincons), SCIPconsIsSeparated(lincons), SCIPconsIsEnforced(lincons), SCIPconsIsChecked(lincons),
2306 SCIPconsIsPropagated(lincons), SCIPconsIsLocal(lincons), SCIPconsIsModifiable(lincons), SCIPconsIsDynamic(lincons),
2307 SCIPconsIsRemovable(lincons));
2308
2309 if( retcode != SCIP_OKAY )
2310 goto TERMINATE;
2311
2312 SCIP_CALL( SCIPaddCons(scip, cons) );
2313 SCIPdebugMsg(scip, "(line %d) added constraint <%s>: ", mpsi->lineno, SCIPconsGetName(cons));
2315
2316 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
2317
2318 SCIP_CALL( SCIPdelCons(scip, lincons) );
2319 }
2320 else
2321 {
2322 SCIPwarningMessage(scip, "QCMATRIX section has no entries.\n");
2323 }
2324
2325 TERMINATE:
2326 SCIPfreeBufferArray(scip, &quadcoefs);
2327 SCIPfreeBufferArray(scip, &quadvars2);
2328 SCIPfreeBufferArray(scip, &quadvars1);
2329
2330 SCIP_CALL( retcode );
2331
2332 return SCIP_OKAY;
2333}
2334
2335
2336/** Process INDICATORS section.
2337 *
2338 * We read the INDICATORS section, which is a nonstandard section introduced by CPLEX.
2339 * Note that CPLEX does not allow ranged rows.
2340 *
2341 * If the linear constraints are equations or ranged rows, we generate two indicator
2342 * constraints.
2343 *
2344 * The section has to come after the QMATRIX* sections.
2345 */
2346static
2348 MPSINPUT* mpsi, /**< mps input structure */
2349 SCIP* scip /**< SCIP data structure */
2350 )
2351{
2352 SCIP_Bool initial;
2353 SCIP_Bool separate;
2354 SCIP_Bool enforce;
2355 SCIP_Bool check;
2356 SCIP_Bool propagate;
2357 SCIP_Bool local;
2358 SCIP_Bool dynamic;
2359 SCIP_Bool removable;
2360 SCIP_Bool stickingatnode;
2361 char name[MPS_MAX_NAMELEN] = { '\0' };
2362
2363 SCIPdebugMsg(scip, "read INDICATORS constraints\n");
2364
2365 /* standard settings for indicator constraints: */
2366 initial = mpsi->initialconss;
2367 separate = TRUE;
2368 enforce = TRUE;
2369 check = TRUE;
2370 propagate = TRUE;
2371 local = FALSE;
2372 dynamic = mpsi->dynamicconss;
2373 removable = mpsi->dynamicrows;
2374 stickingatnode = FALSE;
2375
2376 /* loop through section */
2377 while( mpsinputReadLine(mpsi) )
2378 {
2379 SCIP_CONSHDLR* conshdlr;
2380 SCIP_CONS* cons;
2381 SCIP_CONS* lincons;
2382 SCIP_VAR* binvar;
2383 SCIP_Real lhs;
2384 SCIP_Real rhs;
2385
2386 /* check if next section is found */
2387 if( mpsinputField0(mpsi) != NULL )
2388 {
2389 if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
2391 break;
2392 }
2393
2394 if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL )
2395 {
2396 SCIPerrorMessage("empty data in a non-comment line.\n");
2397 mpsinputSyntaxerror(mpsi);
2398 return SCIP_OKAY;
2399 }
2400
2401 /* check for new indicator constraint */
2402 if( strcmp(mpsinputField1(mpsi), "IF") != 0 )
2403 {
2404 SCIPerrorMessage("Indicator constraints need to be introduced by 'IF' in column 1.\n");
2405 mpsinputSyntaxerror(mpsi);
2406 return SCIP_OKAY;
2407 }
2408
2409 /* get linear constraint (row) */
2410 lincons = SCIPfindCons(scip, mpsinputField2(mpsi));
2411 if( lincons == NULL )
2412 {
2413 SCIPerrorMessage("row <%s> does not exist.\n", mpsinputField2(mpsi));
2414 mpsinputSyntaxerror(mpsi);
2415 return SCIP_OKAY;
2416 }
2417
2418 /* check whether constraint is really linear */
2419 conshdlr = SCIPconsGetHdlr(lincons);
2420 if( strcmp(SCIPconshdlrGetName(conshdlr), "linear") != 0 )
2421 {
2422 SCIPerrorMessage("constraint <%s> is not linear.\n", mpsinputField2(mpsi));
2423 mpsinputSyntaxerror(mpsi);
2424 return SCIP_OKAY;
2425 }
2426
2427 /* get binary variable */
2428 binvar = SCIPfindVar(scip, mpsinputField3(mpsi));
2429 if( binvar == NULL )
2430 {
2431 SCIPerrorMessage("binary variable <%s> does not exist.\n", mpsinputField3(mpsi));
2432 mpsinputSyntaxerror(mpsi);
2433 return SCIP_OKAY;
2434 }
2435
2436 /* check type */
2437 if( SCIPvarGetType(binvar) != SCIP_VARTYPE_BINARY )
2438 {
2439 SCIPerrorMessage("variable <%s> is not binary.\n", mpsinputField3(mpsi));
2440 mpsinputSyntaxerror(mpsi);
2441 return SCIP_OKAY;
2442 }
2443
2444 /* check whether we need the negated variable */
2445 if( mpsinputField4(mpsi) != NULL )
2446 {
2447 if( *mpsinputField4(mpsi) == '0' )
2448 {
2449 SCIP_VAR* var;
2450 SCIP_CALL( SCIPgetNegatedVar(scip, binvar, &var) );
2451 binvar = var;
2452 assert( binvar != NULL );
2453 }
2454 else
2455 {
2456 if( *mpsinputField4(mpsi) != '1' )
2457 {
2458 SCIPerrorMessage("binary variable <%s> can only take values 0/1 (%s).\n", mpsinputField3(mpsi), mpsinputField4(mpsi));
2459 mpsinputSyntaxerror(mpsi);
2460 return SCIP_OKAY;
2461 }
2462 }
2463 }
2464
2465 /* get lhs/rhs */
2466 lhs = SCIPgetLhsLinear(scip, lincons);
2467 rhs = SCIPgetRhsLinear(scip, lincons);
2468
2469 if( !SCIPisInfinity(scip, -lhs) )
2470 {
2471 if( ! SCIPisInfinity(scip, rhs) )
2472 {
2473 /* create second indicator constraint */
2474 SCIP_VAR** vars;
2475 SCIP_Real* vals;
2476 SCIP_RETCODE retcode;
2477 SCIP_VAR** linvars;
2478 SCIP_Real* linvals;
2479 int nlinvars;
2480 int i;
2481
2482 nlinvars = SCIPgetNVarsLinear(scip, lincons);
2483 linvars = SCIPgetVarsLinear(scip, lincons);
2484 linvals = SCIPgetValsLinear(scip, lincons);
2485
2486 SCIP_CALL( SCIPallocBufferArray(scip, &vars, nlinvars) );
2487 SCIP_CALL( SCIPallocBufferArray(scip, &vals, nlinvars) );
2488 for( i = 0; i < nlinvars; ++i )
2489 {
2490 vars[i] = linvars[i];
2491 vals[i] = -linvals[i];
2492 }
2493
2494 /* create new name */
2495 (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "indlhs_%s", SCIPconsGetName(lincons));
2496
2497 /* create indicator constraint */
2498 retcode = SCIPcreateConsIndicator(scip, &cons, name, binvar, nlinvars, vars, vals, -lhs,
2499 initial, separate, enforce, check, propagate, local, dynamic, removable, stickingatnode);
2500
2501 if( retcode == SCIP_OKAY )
2502 {
2503 SCIP_CALL( SCIPaddCons(scip, cons) );
2504 SCIPdebugMsg(scip, "created indicator constraint <%s>\n", mpsinputField2(mpsi));
2506 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
2507 }
2508
2509 SCIPfreeBufferArray(scip, &vals);
2510 SCIPfreeBufferArray(scip, &vars);
2511
2512 SCIP_CALL( retcode );
2513 }
2514 }
2515
2516 /* correct linear constraint and create new name */
2517 if ( ! SCIPisInfinity(scip, -lhs) && ! SCIPisInfinity(scip, rhs) )
2518 {
2519 /* we have added lhs above and only need the rhs */
2521 (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "indrhs_%s", SCIPconsGetName(lincons));
2522 }
2523 else
2524 (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "ind_%s", SCIPconsGetName(lincons));
2525
2526 /* create indicator constraint */
2527 SCIP_CALL( SCIPcreateConsIndicatorLinConsPure(scip, &cons, name, binvar, lincons,
2528 initial, separate, enforce, check, propagate, local, dynamic, removable, stickingatnode) );
2529
2530 SCIP_CALL( SCIPaddCons(scip, cons) );
2531 SCIPdebugMsg(scip, "created indicator constraint <%s>", mpsinputField2(mpsi));
2533 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
2534 }
2535
2536 return SCIP_OKAY;
2537}
2538
2539
2540/** Read LP in "MPS File Format".
2541 *
2542 * A specification of the MPS format can be found at
2543 *
2544 * http://plato.asu.edu/ftp/mps_format.txt,
2545 * ftp://ftp.caam.rice.edu/pub/people/bixby/miplib/mps_format,
2546 *
2547 * and in the
2548 *
2549 * CPLEX Reference Manual
2550 *
2551 * This routine should read all valid MPS format files.
2552 * What it will not do, is to find all cases where a file is ill formed.
2553 * If this happens it may complain and read nothing or read "something".
2554 */
2555static
2557 SCIP* scip, /**< SCIP data structure */
2558 const char* filename, /**< name of the input file */
2559 const char*** varnames, /**< storage for the variable names, or NULL */
2560 const char*** consnames, /**< storage for the constraint names, or NULL */
2561 int* varnamessize, /**< the size of the variable names storage, or NULL */
2562 int* consnamessize, /**< the size of the constraint names storage, or NULL */
2563 int* nvarnames, /**< the number of stored variable names, or NULL */
2564 int* nconsnames /**< the number of stored constraint names, or NULL */
2565 )
2566{
2567 SCIP_FILE* fp;
2568 MPSINPUT* mpsi;
2569 SCIP_RETCODE retcode;
2570 SCIP_Bool error = TRUE;
2571
2572 assert(scip != NULL);
2573 assert(filename != NULL);
2574
2575 fp = SCIPfopen(filename, "r");
2576 if( fp == NULL )
2577 {
2578 SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
2579 SCIPprintSysError(filename);
2580 return SCIP_NOFILE;
2581 }
2582
2583 SCIP_CALL( mpsinputCreate(scip, &mpsi, fp) );
2584
2585 SCIP_CALL_TERMINATE( retcode, readName(scip, mpsi), TERMINATE );
2586
2587 SCIP_CALL_TERMINATE( retcode, SCIPcreateProb(scip, mpsi->probname, NULL, NULL, NULL, NULL, NULL, NULL, NULL), TERMINATE );
2588
2589 if( mpsinputSection(mpsi) == MPS_OBJSEN )
2590 {
2591 SCIP_CALL_TERMINATE( retcode, readObjsen(scip, mpsi), TERMINATE );
2592 }
2593 if( mpsinputSection(mpsi) == MPS_OBJNAME )
2594 {
2595 SCIP_CALL_TERMINATE( retcode, readObjname(scip, mpsi), TERMINATE );
2596 }
2597 while( mpsinputSection(mpsi) == MPS_ROWS
2598 || mpsinputSection(mpsi) == MPS_USERCUTS
2599 || mpsinputSection(mpsi) == MPS_LAZYCONS )
2600 {
2601 SCIP_CALL_TERMINATE( retcode, readRows(mpsi, scip, consnames, consnamessize, nconsnames), TERMINATE );
2602 }
2603 if( mpsinputSection(mpsi) == MPS_COLUMNS )
2604 {
2605 SCIP_CALL_TERMINATE( retcode, readCols(mpsi, scip, varnames, varnamessize, nvarnames), TERMINATE );
2606 }
2607 if( mpsinputSection(mpsi) == MPS_RHS )
2608 {
2609 SCIP_CALL_TERMINATE( retcode, readRhs(mpsi, scip), TERMINATE );
2610 }
2611 if( mpsinputSection(mpsi) == MPS_RANGES )
2612 {
2613 SCIP_CALL_TERMINATE( retcode, readRanges(mpsi, scip), TERMINATE );
2614 }
2615 if( mpsinputSection(mpsi) == MPS_BOUNDS )
2616 {
2617 SCIP_CALL_TERMINATE( retcode, readBounds(mpsi, scip), TERMINATE );
2618 }
2619 if( mpsinputSection(mpsi) == MPS_SOS )
2620 {
2621 SCIP_CALL_TERMINATE( retcode, readSOS(mpsi, scip), TERMINATE );
2622 }
2623 while( mpsinputSection(mpsi) == MPS_QCMATRIX )
2624 {
2625 SCIP_CALL_TERMINATE( retcode, readQCMatrix(mpsi, scip), TERMINATE );
2626 }
2627 if( mpsinputSection(mpsi) == MPS_QMATRIX )
2628 {
2629 SCIP_CALL_TERMINATE( retcode, readQMatrix(mpsi, FALSE, scip), TERMINATE );
2630 }
2631 if( mpsinputSection(mpsi) == MPS_QUADOBJ )
2632 {
2633 SCIP_CALL_TERMINATE( retcode, readQMatrix(mpsi, TRUE, scip), TERMINATE );
2634 }
2635 while( mpsinputSection(mpsi) == MPS_QCMATRIX )
2636 {
2637 SCIP_CALL_TERMINATE( retcode, readQCMatrix(mpsi, scip), TERMINATE );
2638 }
2639 if( mpsinputSection(mpsi) == MPS_INDICATORS )
2640 {
2641 SCIP_CALL_TERMINATE( retcode, readIndicators(mpsi, scip), TERMINATE );
2642 }
2643 if( mpsinputSection(mpsi) != MPS_ENDATA )
2644 mpsinputSyntaxerror(mpsi);
2645
2646 SCIPfclose(fp);
2647
2648 error = mpsinputHasError(mpsi);
2649
2650 if( !error )
2651 {
2652 SCIP_CALL_TERMINATE( retcode, SCIPsetObjsense(scip, mpsinputObjsense(mpsi)), TERMINATE );
2653 }
2654
2655 TERMINATE:
2656 mpsinputFree(scip, &mpsi);
2657
2658 if( error )
2659 return SCIP_READERROR;
2660 else
2661 return SCIP_OKAY;
2662}
2663
2664/*
2665 * local methods for writing problem
2666 */
2667
2668/** gets the key (i.e. the name) of the given namefreq */
2669static
2670SCIP_DECL_HASHGETKEY(hashGetKeyNamefreq)
2671{ /*lint --e{715}*/
2672 CONSNAMEFREQ* consnamefreq = (CONSNAMEFREQ*)elem;
2673
2674 assert(consnamefreq != NULL);
2675 assert(consnamefreq->consname != NULL);
2676
2677 return (void*)consnamefreq->consname;
2678}
2679
2680/** returns TRUE iff both keys (i.e. strings) are equal up to max length*/
2681static
2682SCIP_DECL_HASHKEYEQ(hashKeyEqString)
2683{ /*lint --e{715}*/
2684 const char* string1 = (const char*)key1;
2685 const char* string2 = (const char*)key2;
2686
2687 return (strncmp(string1, string2, MPS_MAX_NAMELEN - 1) == 0);
2688}
2689
2690/** hash key retrieval function for variables */
2691static
2693{ /*lint --e{715}*/
2694 return elem;
2695}
2696
2697/** returns TRUE iff the indices of both variables are equal */
2698static
2700{ /*lint --e{715}*/
2701 if( key1 == key2 )
2702 return TRUE;
2703 return FALSE;
2704}
2705
2706/** returns the hash value of the key */
2707static
2709{ /*lint --e{715}*/
2710 assert( SCIPvarGetIndex((SCIP_VAR*) key) >= 0 );
2711 return (unsigned int) SCIPvarGetIndex((SCIP_VAR*) key);
2712}
2713
2714
2715/** computes the field width such that the output file is nicely arranged */
2716static
2718 unsigned int width /**< required width */
2719 )
2720{
2721 width = MAX(8u, width);
2722 return MIN(MPS_MAX_FIELDLEN, width);
2723}
2724
2725
2726/** output two strings in columns 1 and 2 with computed widths */
2727static
2729 SCIP* scip, /**< SCIP data structure */
2730 FILE* file, /**< output file (or NULL for standard output) */
2731 const char* col1, /**< column 1 */
2732 const char* col2, /**< column 2 */
2733 unsigned int maxnamelen /**< maximum name length */
2734 )
2735{
2736 unsigned int fieldwidth;
2737 char format[32];
2738
2739 assert( scip != NULL );
2740 assert( col1 != NULL );
2741 assert( col2 != NULL );
2742 assert( strlen(col1) < MPS_MAX_NAMELEN );
2743 assert( strlen(col2) < MPS_MAX_VALUELEN );
2744 assert( maxnamelen > 0 );
2745
2746 fieldwidth = computeFieldWidth(maxnamelen);
2747 (void) SCIPsnprintf(format, 32," %%-%ds %%%ds ", fieldwidth, MPS_MAX_VALUELEN - 1);
2748
2749 SCIPinfoMessage(scip, file, (const char *)format, col1, col2);
2750}
2751
2752/** output two strings in columns 1 (width 2) and 2 (width 8) */
2753static
2755 SCIP* scip, /**< SCIP data structure */
2756 FILE* file, /**< output file (or NULL for standard output) */
2757 const char* col1, /**< column 1 */
2758 const char* col2, /**< column 2 */
2759 int maxnamelen /**< maximum name length (-1 if irrelevant) */
2760 )
2761{
2762 unsigned int fieldwidth;
2763 char format[32];
2764
2765 assert( scip != NULL );
2766 assert( col1 != NULL );
2767 assert( col2 != NULL );
2768 assert( strlen(col1) <= 2 );
2769 assert( strlen(col2) < MPS_MAX_NAMELEN );
2770 assert( maxnamelen == -1 || maxnamelen > 0 );
2771
2772 if( maxnamelen < 0 )
2773 {
2774 /* format does not matter */
2775 (void) SCIPsnprintf(format, 32, " %%-2.2s %%-s ");
2776 }
2777 else
2778 {
2779 fieldwidth = computeFieldWidth((unsigned int) maxnamelen);
2780 (void) SCIPsnprintf(format, 32, " %%-2.2s %%-%ds ", fieldwidth);
2781 }
2782
2783 SCIPinfoMessage(scip, file, (const char*)format, col1, col2);
2784}
2785
2786/** prints the given data as column entry */
2787static
2789 SCIP* scip, /**< SCIP data structure */
2790 FILE* file, /**< output file (or NULL for standard output) */
2791 const char* varname, /**< variable name */
2792 const char* consname, /**< constraint name */
2793 SCIP_Real value, /**< value to display */
2794 int* recordcnt, /**< pointer to store the number of records per line */
2795 unsigned int maxnamelen /**< maximum name length */
2796 )
2797{
2798 char valuestr[MPS_MAX_VALUELEN] = { '\0' };
2799
2800 assert( scip != NULL );
2801 assert( recordcnt != NULL );
2802 assert( *recordcnt >= 0 && *recordcnt < 2 );
2803
2804 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", value);
2805
2806 if( *recordcnt == 0 )
2807 {
2808 /* start new line with an empty first column and the variable name in the second column */
2809 printStart(scip, file, "", varname, (int) maxnamelen);
2810 *recordcnt = 0;
2811 }
2812
2813 printRecord(scip, file, consname, valuestr, maxnamelen);
2814 (*recordcnt)++;
2815
2816 if( *recordcnt == 2 )
2817 {
2818 /* each line can have at most two records */
2819 SCIPinfoMessage(scip, file, "\n");
2820 *recordcnt = 0;
2821 }
2822}
2823
2824/** prints the constraint type to file stream */
2825static
2827 SCIP* scip, /**< SCIP data structure */
2828 FILE* file, /**< output file (or NULL for standard output) */
2829 SCIP_Real lhs, /**< left hand side */
2830 SCIP_Real rhs, /**< right hand side */
2831 const char* name /**< constraint name */
2832 )
2833{
2834 char rowtype[2];
2835
2836 assert( scip != NULL );
2837 assert( !SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs) );
2838 assert( SCIPisGT(scip, rhs, lhs) || SCIPisEQ(scip, lhs, rhs) );
2839 assert( name != NULL );
2840
2841 if( SCIPisEQ(scip, lhs, rhs) )
2842 (void) SCIPsnprintf(rowtype, 2, "%s", "E");
2843 else
2844 {
2845 /* in case the right hand side and the left hand side are not infinity we print a
2846 * less or equal constraint and put the right hand side in the RHS section and the
2847 * left hand side (hidden) in the RANGE section */
2848 if( !SCIPisInfinity(scip, rhs) )
2849 (void) SCIPsnprintf(rowtype, 2, "%s", "L");
2850 else
2851 {
2852 assert( !SCIPisInfinity(scip, -lhs) );
2853 (void) SCIPsnprintf(rowtype, 2, "%s", "G");
2854 }
2855 }
2856
2857 printStart(scip, file, rowtype, name, -1);
2858 SCIPinfoMessage(scip, file, "\n");
2859}
2860
2861
2862/** initializes the sparse matrix */
2863static
2865 SCIP* scip, /**< SCIP data structure */
2866 SPARSEMATRIX** matrix, /**< pointer to sparse matrix containing the entries */
2867 int slots /**< number of slots */
2868 )
2869{
2870 SCIP_CALL( SCIPallocBuffer(scip, matrix) );
2871 (*matrix)->nentries = 0;
2872 (*matrix)->sentries = slots;
2873 SCIP_CALL( SCIPallocBufferArray(scip, &(*matrix)->values, (*matrix)->sentries) );
2874 SCIP_CALL( SCIPallocBufferArray(scip, &(*matrix)->columns, (*matrix)->sentries) );
2875 SCIP_CALL( SCIPallocBufferArray(scip, &(*matrix)->rows, (*matrix)->sentries) );
2876
2877 return SCIP_OKAY;
2878}
2879
2880/** this method takes care that the required capacity is available in the sparse matrix */
2881static
2883 SCIP* scip, /**< SCIP data structure */
2884 SPARSEMATRIX* matrix, /**< sparse matrix for storing the coefficient */
2885 int capacity /**< needed capacity */
2886 )
2887{
2888 if( matrix->nentries + capacity >= matrix->sentries )
2889 {
2890 matrix->sentries = matrix->sentries * 2 + capacity;
2891 SCIP_CALL( SCIPreallocBufferArray(scip, &matrix->values, matrix->sentries) );
2892 SCIP_CALL( SCIPreallocBufferArray(scip, &matrix->columns, matrix->sentries) );
2893 SCIP_CALL( SCIPreallocBufferArray(scip, &matrix->rows, matrix->sentries) );
2894 }
2895 return SCIP_OKAY;
2896}
2897
2898/** frees the sparse matrix */
2899static
2901 SCIP* scip, /**< SCIP data structure */
2902 SPARSEMATRIX* matrix /**< sparse matrix to free */
2903 )
2904{
2905 SCIPfreeBufferArray(scip, &matrix->rows);
2906 SCIPfreeBufferArray(scip, &matrix->columns);
2907 SCIPfreeBufferArray(scip, &matrix->values);
2908
2909 SCIPfreeBuffer(scip, &matrix);
2910}
2911
2912
2913/** computes the coefficient for the given variables and linear constraint information */
2914static
2916 SCIP* scip, /**< SCIP data structure */
2917 const char* consname, /**< name of the constraint */
2918 SCIP_VAR** vars, /**< array of variables */
2919 SCIP_Real* vals, /**< array of coefficients values (or NULL if all coefficient values are 1) */
2920 int nvars, /**< number of variables */
2921 SCIP_Bool transformed, /**< transformed constraint? */
2922 SPARSEMATRIX* matrix, /**< sparse matrix for storing the coefficient */
2923 SCIP_Real* rhs /**< pointer to right hand side */
2924 )
2925{
2926 SCIP_VAR** activevars;
2927 SCIP_Real* activevals;
2928 SCIP_Real activeconstant = 0.0;
2929
2930 int nactivevars;
2931 int requiredsize;
2932 int v;
2933
2934 assert( scip != NULL );
2935 assert( nvars == 0 || vars != NULL );
2936 assert( !SCIPisInfinity(scip, *rhs) );
2937 assert( matrix != NULL );
2938
2939 /* if the variables array contains no variables, then return without
2940 * doing any thing; The MPS format and LP format do not forbid this
2941 * situation */
2942 if( nvars == 0 )
2943 return SCIP_OKAY;
2944
2945 /* duplicate variable and value array */
2946 nactivevars = nvars;
2947 SCIP_CALL( SCIPduplicateBufferArray(scip, &activevars, vars, nactivevars ) );
2948
2949 if( vals != NULL )
2950 {
2951 SCIP_CALL( SCIPduplicateBufferArray(scip, &activevals, vals, nactivevars ) );
2952 }
2953 else
2954 {
2955 SCIP_CALL( SCIPallocBufferArray(scip, &activevals, nactivevars) );
2956
2957 for( v = 0; v < nactivevars; ++v )
2958 activevals[v] = 1.0;
2959 }
2960
2961 /* retransform given variables to active variables */
2962 if( transformed )
2963 {
2964 SCIP_CALL( SCIPgetProbvarLinearSum(scip, activevars, activevals, &nactivevars, nactivevars, &activeconstant, &requiredsize, TRUE) );
2965
2966 if( requiredsize > nactivevars )
2967 {
2968 SCIP_CALL( SCIPreallocBufferArray(scip, &activevars, requiredsize) );
2969 SCIP_CALL( SCIPreallocBufferArray(scip, &activevals, requiredsize) );
2970
2971 SCIP_CALL( SCIPgetProbvarLinearSum(scip, activevars, activevals, &nactivevars, requiredsize, &activeconstant, &requiredsize, TRUE) );
2972 assert( requiredsize <= nactivevars );
2973 }
2974 }
2975 else
2976 {
2977 for( v = 0; v < nactivevars; ++v )
2978 {
2979 SCIP_CALL( SCIPvarGetOrigvarSum(&activevars[v], &activevals[v], &activeconstant) );
2980
2981 /* negated variables with an original counterpart may also be returned by SCIPvarGetOrigvarSum();
2982 * make sure we get the original variable in that case
2983 */
2984 if( SCIPvarGetStatus(activevars[v]) == SCIP_VARSTATUS_NEGATED )
2985 {
2986 activevars[v] = SCIPvarGetNegatedVar(activevars[v]);
2987 activeconstant += activevals[v];
2988 activevals[v] *= -1.0;
2989 }
2990 }
2991 }
2992
2993 /* copy the (matrix) row into the sparse matrix */
2994 SCIP_CALL( checkSparseMatrixCapacity(scip, matrix, nactivevars) );
2995 assert( matrix->nentries + nactivevars < matrix->sentries );
2996
2997 for( v = 0; v < nactivevars; ++v )
2998 {
2999 matrix->values[matrix->nentries] = activevals[v];
3000 matrix->columns[matrix->nentries] = activevars[v];
3001 matrix->rows[matrix->nentries] = consname;
3002 matrix->nentries++;
3003 }
3004
3005 /* adjust right hand side */
3006 (*rhs) -= activeconstant;
3007
3008 /* free buffer arrays */
3009 SCIPfreeBufferArray(scip, &activevals);
3010 SCIPfreeBufferArray(scip, &activevars);
3011
3012 return SCIP_OKAY;
3013}
3014
3015
3016/** check whether given variables are aggregated and put them into an array without duplication */
3017static
3019 SCIP* scip, /**< SCIP data structure */
3020 SCIP_VAR** vars, /**< variable array */
3021 int nvars, /**< number of active variables in the problem */
3022 SCIP_VAR*** aggvars, /**< pointer to array storing the aggregated variables on output */
3023 int* naggvars, /**< pointer to number of aggregated variables on output */
3024 int* saggvars, /**< pointer to number of slots in aggvars array */
3025 SCIP_HASHTABLE* varAggregated /**< hashtable for checking duplicates */
3026 )
3027{
3028 int v;
3029
3030 assert( scip != NULL );
3031 assert( aggvars != NULL );
3032 assert( naggvars != NULL );
3033 assert( saggvars != NULL );
3034
3035 /* check variables */
3036 for( v = 0; v < nvars; ++v )
3037 {
3038 SCIP_VARSTATUS status;
3039 SCIP_VAR* var;
3040
3041 var = vars[v];
3042 status = SCIPvarGetStatus(var);
3043
3044 /* collect aggregated variables in a list */
3045 if( status >= SCIP_VARSTATUS_AGGREGATED )
3046 {
3047 assert( status == SCIP_VARSTATUS_AGGREGATED || status == SCIP_VARSTATUS_MULTAGGR || status == SCIP_VARSTATUS_NEGATED );
3048 assert( varAggregated != NULL );
3049
3050 if( ! SCIPhashtableExists(varAggregated, (void*) var) )
3051 {
3052 /* possibly enlarge array */
3053 if ( *saggvars <= *naggvars )
3054 {
3055 int newsize;
3056 newsize = SCIPcalcMemGrowSize(scip, *naggvars + 1);
3057 assert( newsize > *saggvars );
3058 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &aggvars, *saggvars, newsize) );
3059 *saggvars = newsize;
3060 }
3061
3062 (*aggvars)[*naggvars] = var;
3063 (*naggvars)++;
3064 SCIP_CALL( SCIPhashtableInsert(varAggregated, (void*) var) );
3065 assert( *naggvars <= *saggvars );
3066 }
3067 }
3068 }
3069 return SCIP_OKAY;
3070}
3071
3072
3073/** method check if the variable names are not longer than MPS_MAX_NAMELEN - 1*/
3074static
3076 SCIP* scip, /**< SCIP data structure */
3077 SCIP_VAR** vars, /**< array of variables */
3078 int nvars, /**< number of variables */
3079 unsigned int* maxnamelen, /**< pointer to store the maximum name length */
3080 const char*** varnames, /**< pointer to array of variable names */
3081 SCIP_HASHMAP** varnameHashmap /**< pointer to hash map storing variable, variable name mapping */
3082 )
3083{
3084 int v;
3085 int faulty;
3086 char* varname;
3087 SCIP_VAR* var;
3088
3089 assert( scip != NULL );
3090 assert( vars != NULL );
3091 assert( maxnamelen != NULL );
3092
3093 faulty = 0;
3094
3095 /* allocate memory */
3096 SCIP_CALL( SCIPhashmapCreate(varnameHashmap, SCIPblkmem(scip), nvars) );
3097 SCIP_CALL( SCIPallocBufferArray(scip, varnames, nvars) );
3098
3099 /* check if the variable names are not to long */
3100 for( v = 0; v < nvars; ++v )
3101 {
3102 size_t l;
3103
3104 var = vars[v];
3105 assert( var != NULL );
3106
3107 l = strlen(SCIPvarGetName(var));
3108
3109 if( l >= MPS_MAX_NAMELEN )
3110 {
3111 faulty++;
3112 (*maxnamelen) = MPS_MAX_NAMELEN - 1;
3113 }
3114 else
3115 {
3116 (*maxnamelen) = MAX(*maxnamelen, (unsigned int) l);
3117 }
3118
3119 SCIP_CALL( SCIPallocBufferArray(scip, &varname, (int) *maxnamelen + 1) );
3120 (void) SCIPsnprintf(varname, (int)(*maxnamelen) + 1, "%s", SCIPvarGetName(var) );
3121
3122 /* insert variable with variable name into hash map */
3123 assert( !SCIPhashmapExists(*varnameHashmap, var) );
3124 SCIP_CALL( SCIPhashmapInsert(*varnameHashmap, var, (void*) varname) );
3125
3126 (*varnames)[v] = varname;
3127 }
3128
3129 if( faulty > 0 )
3130 {
3131 SCIPwarningMessage(scip, "there are %d variable names which have to be cut down to %d characters; LP might be corrupted\n",
3132 faulty, MPS_MAX_NAMELEN - 1);
3133 }
3134 return SCIP_OKAY;
3135}
3136
3137/** method check if the constraint names are not longer than MPS_MAX_NAMELEN - 1 */
3138static
3140 SCIP* scip, /**< SCIP data structure */
3141 SCIP_CONS** conss, /**< array of all constraints */
3142 int nconss, /**< number of all constraints */
3143 SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
3144 unsigned int* maxnamelen, /**< pointer to store the maximum name length */
3145 const char*** consnames, /**< pointer to array of constraint names */
3146 SCIP_Bool* error /**< pointer to store whether all constraint names exist */
3147 )
3148{
3149 SCIP_HASHTABLE* consfreq;
3150 CONSNAMEFREQ* consnamefreqs;
3151 SCIP_CONS* cons;
3152 char* consname;
3153 int i;
3154
3155 assert(scip != NULL);
3156 assert(maxnamelen != NULL);
3157
3158 *error = FALSE;
3159
3160 /* allocate memory */
3161 SCIP_CALL( SCIPallocBufferArray(scip, &consnamefreqs, nconss) );
3162 SCIP_CALL( SCIPallocBufferArray(scip, consnames, nconss) );
3164 hashGetKeyNamefreq, hashKeyEqString, SCIPhashKeyValString, NULL) );
3165
3166 for( i = 0; i < nconss; ++i )
3167 {
3168 CONSNAMEFREQ* consnamefreq;
3169 size_t l;
3170 int freq;
3171
3172 cons = conss[i];
3173 assert( cons != NULL );
3174
3175 /* in case the transformed problem is written, only constraints are posted which are enabled in the current node */
3176 assert(!transformed || SCIPconsIsEnabled(cons));
3177
3178 l = strlen(SCIPconsGetName(cons));
3179
3180 if( l == 0 )
3181 {
3182 SCIPwarningMessage(scip, "At least one name of a constraint is empty, so file will be written with generic names.\n");
3183 *error = TRUE;
3184
3185 goto TERMINATE;
3186 }
3187
3188 consnamefreqs[i].consname = SCIPconsGetName(cons);
3189 consnamefreqs[i].freq = 0;
3190 freq = 0;
3191
3192 /* check for duplicate names */
3193 if( NULL != (consnamefreq = (CONSNAMEFREQ *)SCIPhashtableRetrieve(consfreq, (void*)SCIPconsGetName(cons))) )
3194 {
3195 consnamefreq->freq += 1;
3196 consnamefreqs[i] = *consnamefreq;
3197 freq = consnamefreq->freq;
3198 }
3199 SCIP_CALL( SCIPhashtableInsert(consfreq, (void*)(&consnamefreqs[i])) );
3200
3201 /* the new length is the length of the old name + a '_' and the freq number which has floor(log10(freq)) + 1 characters */
3202 if( freq > 0 )
3203 l = l + 1 + (size_t)log10((SCIP_Real) freq) + 1;
3204
3205 if( l >= MPS_MAX_NAMELEN )
3206 {
3207 SCIPwarningMessage(scip, "Constraints have duplicate name and are too long to fix, so file will be written with generic names.\n");
3208 *error = TRUE;
3209
3210 goto TERMINATE;
3211 }
3212
3213 (*maxnamelen) = MAX(*maxnamelen, (unsigned int) l);
3214
3215 SCIP_CALL( SCIPallocBufferArray(scip, &consname, (int) l + 1) );
3216 if( freq > 0 )
3217 (void) SCIPsnprintf(consname, (int)l + 1, "%s_%d", SCIPconsGetName(cons), freq);
3218 else
3219 (void) SCIPsnprintf(consname, (int)l + 1, "%s", SCIPconsGetName(cons));
3220
3221 (*consnames)[i] = consname;
3222 }
3223
3224TERMINATE:
3225 SCIPfreeBufferArray(scip, &consnamefreqs);
3226
3227 if( *error )
3228 {
3229 --i; /*lint !e445*/
3230 for( ; i >= 0; --i) /*lint !e445*/
3231 {
3232 SCIPfreeBufferArray(scip, &((*consnames)[i]));
3233 }
3234 SCIPfreeBufferArray(scip, consnames);
3235 }
3236
3237 SCIPhashtableFree(&consfreq);
3238
3239 return SCIP_OKAY;
3240}
3241
3242
3243/** outputs the COLUMNS section of the MPS format */
3244static
3246 SCIP* scip, /**< SCIP data structure */
3247 FILE* file, /**< output file, or NULL if standard output should be used */
3248 SPARSEMATRIX* matrix, /**< sparse matrix containing the entries */
3249 SCIP_HASHMAP* varnameHashmap, /**< map from SCIP_VAR* to variable name */
3250 SCIP_HASHTABLE* indicatorSlackHash, /**< hashtable containing slack variables from indicators (or NULL) */
3251 unsigned int maxnamelen /**< maximum name length */
3252 )
3253{
3254 SCIP_Bool intSection;
3255 SCIP_VAR* var;
3256 const char* varname;
3257 SCIP_Real value;
3258 int v;
3259 int recordcnt;
3260
3261 /* sort sparse matrix w.r.t. the variable indices */
3262 SCIPsortPtrPtrReal((void**) matrix->columns, (void**) matrix->rows, matrix->values, SCIPvarComp, matrix->nentries);
3263
3264 /* print COLUMNS section */
3265 SCIPinfoMessage(scip, file, "COLUMNS\n");
3266
3267 intSection = FALSE;
3268
3269 for( v = 0; v < matrix->nentries; )
3270 {
3271 var = matrix->columns[v];
3272 assert( var != NULL );
3273
3274 /* skip slack variables in output */
3275 if( indicatorSlackHash != NULL && SCIPhashtableExists(indicatorSlackHash, var) )
3276 {
3277 ++v;
3278 continue;
3279 }
3280
3281 if( SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS && intSection )
3282 {
3283 /* end integer section in MPS format */
3284 printStart(scip, file, "", "INTEND", (int) maxnamelen);
3285 printRecord(scip, file, "'MARKER'", "", maxnamelen);
3286 printRecord(scip, file, "'INTEND'", "", maxnamelen);
3287 SCIPinfoMessage(scip, file, "\n");
3288 intSection = FALSE;
3289 }
3290 else if( SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !intSection )
3291 {
3292 /* start integer section in MPS format */
3293 printStart(scip, file, "", "INTSTART", (int) maxnamelen);
3294 printRecord(scip, file, "'MARKER'", "", maxnamelen);
3295 printRecord(scip, file, "'INTORG'", "", maxnamelen);
3296 SCIPinfoMessage(scip, file, "\n");
3297 intSection = TRUE;
3298 }
3299
3300 SCIPdebugMsg(scip, "create entries for variable <%s>\n", SCIPvarGetName(var));
3301
3302 /* record count; there are at most two records per line */
3303 recordcnt = 0;
3304
3305 /* get variable name */
3306 assert ( SCIPhashmapExists(varnameHashmap, var) );
3307 varname = (const char*) SCIPhashmapGetImage(varnameHashmap, var);
3308
3309 /* output all entries of the same variable */
3310 do
3311 {
3312 value = matrix->values[v];
3313
3314 /* print record to file */
3315 printEntry(scip, file, varname, matrix->rows[v], value, &recordcnt, maxnamelen);
3316 v++;
3317 }
3318 while( v < matrix->nentries && var == matrix->columns[v] );
3319
3320 if( recordcnt == 1 )
3321 SCIPinfoMessage(scip, file, "\n");
3322 }
3323 /* end integer section, if the columns sections ends with integer variables */
3324 if( intSection )
3325 {
3326 /* end integer section in MPS format */
3327 printStart(scip, file, "", "INTEND", (int) maxnamelen);
3328 printRecord(scip, file, "'MARKER'", "", maxnamelen);
3329 printRecord(scip, file, "'INTEND'", "", maxnamelen);
3330 SCIPinfoMessage(scip, file, "\n");
3331 }
3332}
3333
3334
3335/** outputs the right hand side section */
3336static
3338 SCIP* scip, /**< SCIP data structure */
3339 FILE* file, /**< output file, or NULL if standard output should be used */
3340 int nconss, /**< number of constraints */
3341 const char** consnames, /**< constraint names */
3342 SCIP_Real* rhss, /**< right hand side array */
3343 unsigned int maxnamelen, /**< maximum name length */
3344 SCIP_Real objoffset /**< objective offset */
3345 )
3346{
3347 int recordcnt = 0;
3348 int c;
3349
3350 assert( rhss != NULL );
3351
3352 SCIPinfoMessage(scip, file, "RHS\n");
3353 SCIPdebugMsg(scip, "start printing RHS section\n");
3354
3355 /* take care of the linear constraints */
3356 for( c = 0; c < nconss; ++c )
3357 {
3358 /* skip all constraints which have a right hand side of infinity */
3359 if( SCIPisInfinity(scip, rhss[c]) )
3360 continue;
3361
3362 assert(consnames[c] != NULL);
3363
3364 printEntry(scip, file, "RHS", consnames[c], rhss[c], &recordcnt, maxnamelen);
3365 }
3366
3367 if( ! SCIPisZero(scip, objoffset) )
3368 {
3369 /* write objective offset (-1 because it is moved to the rhs) */
3370 printEntry(scip, file, "RHS", "Obj", -objoffset, &recordcnt, maxnamelen);
3371 }
3372
3373 if( recordcnt == 1 )
3374 SCIPinfoMessage(scip, file, "\n");
3375}
3376
3377
3378/** outputs the range section */
3379static
3381 SCIP* scip, /**< SCIP data structure */
3382 FILE* file, /**< output file, or NULL if standard output should be used */
3383 SCIP_CONS** conss, /**< constraint array */
3384 int nconss, /**< number of constraints */
3385 const char** consnames, /**< constraint names */
3386 SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
3387 unsigned int maxnamelen /**< maximum name length */
3388 )
3389{
3390 int c;
3391 int recordcnt = 0;
3392
3393 SCIP_CONSHDLR* conshdlr;
3394 const char* conshdlrname;
3395
3396 SCIP_CONS* cons;
3397 SCIP_Real lhs;
3398 SCIP_Real rhs;
3399
3400 SCIPinfoMessage(scip, file, "RANGES\n");
3401 SCIPdebugMsg(scip, "start printing RANGES section\n");
3402
3403 for( c = 0; c < nconss; ++c )
3404 {
3405 cons = conss[c];
3406 assert( cons != NULL);
3407
3408 /* in case the transformed problems is written only constraint are posted which are enabled in the current node;
3409 * the conss array should only contain relevant constraints
3410 */
3411 assert( !transformed || SCIPconsIsEnabled(cons) );
3412
3413 assert( consnames[c] != NULL );
3414
3415 conshdlr = SCIPconsGetHdlr(cons);
3416 assert( conshdlr != NULL );
3417
3418 conshdlrname = SCIPconshdlrGetName(conshdlr);
3419
3420 if( strcmp(conshdlrname, "linear") == 0 )
3421 {
3422 lhs = SCIPgetLhsLinear(scip, cons);
3423 rhs = SCIPgetRhsLinear(scip, cons);
3424 }
3425 else if( strcmp(conshdlrname, "varbound") == 0 )
3426 {
3427 lhs = SCIPgetLhsVarbound(scip, cons);
3428 rhs = SCIPgetRhsVarbound(scip, cons);
3429 }
3430 else
3431 continue;
3432
3433 if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && !SCIPisEQ(scip, rhs, lhs) )
3434 {
3435 assert( SCIPisGT(scip, rhs, lhs) );
3436 printEntry(scip, file, "RANGE", consnames[c], rhs - lhs, &recordcnt, maxnamelen);
3437 }
3438 }
3439 if(recordcnt == 1 )
3440 SCIPinfoMessage(scip, file, "\n");
3441}
3442
3443/** print bound section name */
3444static
3446 SCIP* scip, /**< SCIP data structure */
3447 FILE* file /**< output file, or NULL if standard output should be used */
3448 )
3449{
3450 SCIPinfoMessage(scip, file, "BOUNDS\n");
3451 SCIPdebugMsg(scip, "start printing BOUNDS section\n");
3452}
3453
3454/** output bound section */
3455static
3457 SCIP* scip, /**< SCIP data structure */
3458 FILE* file, /**< output file, or NULL if standard output should be used */
3459 SCIP_VAR** vars, /**< active variables */
3460 int nvars, /**< number of active variables */
3461 SCIP_VAR** aggvars, /**< needed aggregated variables */
3462 int naggvars, /**< number of aggregated variables */
3463 SCIP_VAR** fixvars, /**< all fixed variables (or NULL if nfixvars is 0) */
3464 int nfixvars, /**< number of fixed variables */
3465 SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
3466 const char** varnames, /**< array with variable names */
3467 SCIP_HASHTABLE* indicatorSlackHash, /**< hashtable containing slack variables from indicators (or NULL) */
3468 unsigned int maxnamelen /**< maximum name length */
3469 )
3470{
3471 int v;
3472 SCIP_VAR* var;
3473 SCIP_Real lb;
3474 SCIP_Real ub;
3475 SCIP_Bool sectionName;
3476 const char* varname;
3477 char valuestr[MPS_MAX_VALUELEN] = { '\0' };
3478
3479 assert(scip != NULL);
3480 assert(vars != NULL);
3481 assert(nfixvars == 0 || fixvars != NULL);
3482
3483 sectionName = FALSE;
3484
3485 /* output the active variables */
3486 for( v = 0; v < nvars; ++v )
3487 {
3488 var = vars[v];
3489 assert( var != NULL );
3490
3491 /* skip slack variables in output */
3492 if( indicatorSlackHash != NULL && SCIPhashtableExists(indicatorSlackHash, var) )
3493 continue;
3494
3495 /* get variable name */
3496 varname = varnames[v];
3497 assert(strncmp(varname, SCIPvarGetName(var), maxnamelen) == 0);
3498
3499 if( transformed )
3500 {
3501 /* in case the transformed is written only local bounds are posted
3502 * which are valid in the current node */
3503 lb = SCIPvarGetLbLocal(var);
3504 ub = SCIPvarGetUbLocal(var);
3505 }
3506 else
3507 {
3508 lb = SCIPvarGetLbOriginal(var);
3509 ub = SCIPvarGetUbOriginal(var);
3510 }
3511
3512 /* take care of binary variables */
3514 {
3515 if( !sectionName )
3516 {
3518 sectionName = TRUE;
3519 }
3520
3521 if( !SCIPisFeasZero(scip, lb) || !SCIPisFeasEQ(scip, ub, 1.0) )
3522 {
3523 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", lb);
3524 printStart(scip, file, "LO", "Bound", (int) maxnamelen);
3525 printRecord(scip, file, varname, valuestr, maxnamelen);
3526 SCIPinfoMessage(scip, file, "\n");
3527
3528 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", ub);
3529 printStart(scip, file, "UP", "Bound", (int) maxnamelen);
3530 printRecord(scip, file, varname, valuestr, maxnamelen);
3531 }
3532 else
3533 {
3534 printStart(scip, file, "BV", "Bound", (int) maxnamelen);
3535 printRecord(scip, file, varname, "", maxnamelen);
3536 }
3537 SCIPinfoMessage(scip, file, "\n");
3538
3539 continue;
3540 }
3541
3542 /* take care of free variables */
3543 if( SCIPisInfinity(scip, -lb) && SCIPisInfinity(scip, ub) )
3544 {
3545 if( !sectionName )
3546 {
3548 sectionName = TRUE;
3549 }
3550
3551 /* variable is free */
3552 printStart(scip, file, "FR", "Bound", (int) maxnamelen);
3553 printRecord(scip, file, varname, "", maxnamelen);
3554 SCIPinfoMessage(scip, file, "\n");
3555 continue;
3556 }
3557
3558 /* take care of fixed variables */
3559 if( SCIPisEQ(scip, lb, ub) )
3560 {
3561 if( !sectionName )
3562 {
3564 sectionName = TRUE;
3565 }
3566
3567 /* variable is fixed */
3568 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", lb);
3569 printStart(scip, file, "FX", "Bound", (int) maxnamelen);
3570 printRecord(scip, file, varname, valuestr, maxnamelen);
3571 SCIPinfoMessage(scip, file, "\n");
3572 continue;
3573 }
3574
3575 /* print lower bound */
3576 if( SCIPisInfinity(scip, -lb) )
3577 {
3578 if( !sectionName )
3579 {
3581 sectionName = TRUE;
3582 }
3583
3584 /* the free variables are processed above */
3585 assert( !SCIPisInfinity(scip, ub) );
3586 printStart(scip, file, "MI", "Bound", (int) maxnamelen);
3587 printRecord(scip, file, varname, "", maxnamelen);
3588 SCIPinfoMessage(scip, file, "\n");
3589 }
3590 else
3591 {
3592 if( SCIPisZero(scip, lb) )
3593 {
3594 lb = 0.0;
3595 }
3596 else
3597 {
3598 if( !sectionName )
3599 {
3601 sectionName = TRUE;
3602 }
3603
3604 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", lb);
3605 printStart(scip, file, "LO", "Bound", (int) maxnamelen);
3606 printRecord(scip, file, varname, valuestr, maxnamelen);
3607 SCIPinfoMessage(scip, file, "\n");
3608 }
3609 }
3610
3611 /* print upper bound, infinity has to be printed for integer (!) variables, because during
3612 * reading an mps file no upper bound of an integer variable means that the upper bound will
3613 * be set to 1 instead of +infinity (like it is for continuous variables) */
3614 if( SCIPisInfinity(scip, ub) )
3615 {
3616 if( !sectionName )
3617 {
3619 sectionName = TRUE;
3620 }
3621
3622 /* the free variables are processed above */
3623 assert( !SCIPisInfinity(scip, -lb) );
3624 printStart(scip, file, "PL", "Bound", (int) maxnamelen);
3625 printRecord(scip, file, varname, "", maxnamelen);
3626 SCIPinfoMessage(scip, file, "\n");
3627 }
3628 else
3629 {
3630 if( !sectionName )
3631 {
3633 sectionName = TRUE;
3634 }
3635
3636 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", ub);
3637 printStart(scip, file, "UP", "Bound", (int) maxnamelen);
3638 printRecord(scip, file, varname, valuestr, maxnamelen);
3639 SCIPinfoMessage(scip, file, "\n");
3640 }
3641 }
3642
3643 /* output aggregated variables as 'free', except if they are binary */
3644 for( v = 0; v < naggvars; ++v )
3645 {
3646 if( !sectionName )
3647 {
3649 sectionName = TRUE;
3650 }
3651
3652 var = aggvars[v];
3653 assert( var != NULL );
3654
3655 /* get variable name */
3656 varname = varnames[nvars + v];
3657 assert(strncmp(varname, SCIPvarGetName(var), maxnamelen) == 0);
3658
3659 /* take care of binary variables */
3661 {
3662 printStart(scip, file, "BV", "Bound", (int) maxnamelen);
3663 printRecord(scip, file, varname, "", maxnamelen);
3664 SCIPinfoMessage(scip, file, "\n");
3665 }
3666 else
3667 {
3668 /* variable is free */
3669 printStart(scip, file, "FR", "Bound", (int) maxnamelen);
3670 printRecord(scip, file, varname, "", maxnamelen);
3671 SCIPinfoMessage(scip, file, "\n");
3672 }
3673 }
3674
3675 /* output all fixed variables */
3676 for( v = 0; v < nfixvars; ++v )
3677 {
3678 /* we should print the transformed problem, otherwise no fixed variable should exists */
3679 assert(transformed);
3680 assert(fixvars != NULL && fixvars[v] != NULL);
3681
3682 /* cppcheck-suppress nullPointer */
3683 var = fixvars[v];
3684
3685 assert(var != NULL);
3686 assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_FIXED);
3687
3688 /* get variable name */
3689 varname = varnames[nvars + naggvars + v];
3690 assert(strncmp(varname, SCIPvarGetName(var), maxnamelen) == 0);
3691
3692 /* only local bounds are posted which are valid in the current node */
3693 lb = SCIPvarGetLbLocal(var);
3694 ub = SCIPvarGetUbLocal(var);
3695 assert(SCIPisEQ(scip, lb, ub));
3696
3697 if( !sectionName )
3698 {
3700 sectionName = TRUE;
3701 }
3702
3703 /* print fixed variable */
3704 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", lb);
3705 printStart(scip, file, "FX", "Bound", (int) maxnamelen);
3706 printRecord(scip, file, varname, valuestr, maxnamelen);
3707 SCIPinfoMessage(scip, file, "\n");
3708 }
3709}
3710
3711
3712/*
3713 * Callback methods of reader
3714 */
3715
3716/** copy method for reader plugins (called when SCIP copies plugins) */
3717/**! [SnippetReaderCopyMps] */
3718static
3720{ /*lint --e{715}*/
3721 assert(scip != NULL);
3722 assert(reader != NULL);
3723 assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
3724
3725 /* call inclusion method of reader */
3727
3728 return SCIP_OKAY;
3729}
3730/**! [SnippetReaderCopyMps] */
3731
3732/** destructor of reader to free user data (called when SCIP is exiting) */
3733/**! [SnippetReaderFreeMps] */
3734static
3736{
3737 SCIP_READERDATA* readerdata;
3738
3739 assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
3740 readerdata = SCIPreaderGetData(reader);
3741 assert(readerdata != NULL);
3742 SCIPfreeBlockMemory(scip, &readerdata);
3743
3744 return SCIP_OKAY;
3745}
3746/**! [SnippetReaderFreeMps] */
3747
3748/** problem reading method of reader */
3749static
3751{ /*lint --e{715}*/
3752 assert(reader != NULL);
3753 assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
3754
3755 SCIP_CALL( SCIPreadMps(scip, reader, filename, result, NULL, NULL, NULL, NULL, NULL, NULL) );
3756
3757 return SCIP_OKAY;
3758}
3759
3760
3761/** problem writing method of reader */
3762static
3764{ /*lint --e{715}*/
3765 assert(reader != NULL);
3766 assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
3767
3768 SCIP_CALL( SCIPwriteMps(scip, reader, file, name, transformed, objsense, objscale, objoffset, vars,
3769 nvars, nbinvars, nintvars, nimplvars, ncontvars, fixedvars, nfixedvars, conss, nconss, result) );
3770
3771 return SCIP_OKAY;
3772}
3773
3774
3775/*
3776 * mps file reader specific interface methods
3777 */
3778
3779/** includes the mps file reader in SCIP */
3781 SCIP* scip /**< SCIP data structure */
3782 )
3783{
3784 SCIP_READERDATA* readerdata;
3785 SCIP_READER* reader;
3786
3787 /* create reader data */
3788 SCIP_CALL( SCIPallocBlockMemory(scip, &readerdata) );
3789
3790 /* include reader */
3792
3793 /* set non fundamental callbacks via setter functions */
3794 SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopyMps) );
3795 SCIP_CALL( SCIPsetReaderFree(scip, reader, readerFreeMps) );
3796 SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadMps) );
3797 SCIP_CALL( SCIPsetReaderWrite(scip, reader, readerWriteMps) );
3798
3799 /* add lp-reader parameters */
3801 "reading/" READER_NAME "/linearize-and-constraints",
3802 "should possible \"and\" constraint be linearized when writing the mps file?",
3803 &readerdata->linearizeands, TRUE, DEFAULT_LINEARIZE_ANDS, NULL, NULL) );
3805 "reading/" READER_NAME "/aggrlinearization-ands",
3806 "should an aggregated linearization for and constraints be used?",
3807 &readerdata->aggrlinearizationands, TRUE, DEFAULT_AGGRLINEARIZATION_ANDS, NULL, NULL) );
3808
3809 return SCIP_OKAY;
3810}
3811
3812
3813/** reads problem from file */
3815 SCIP* scip, /**< SCIP data structure */
3816 SCIP_READER* reader, /**< the file reader itself */
3817 const char* filename, /**< full path and name of file to read, or NULL if stdin should be used */
3818 SCIP_RESULT* result, /**< pointer to store the result of the file reading call */
3819 const char*** varnames, /**< storage for the variable names, or NULL */
3820 const char*** consnames, /**< storage for the constraint names, or NULL */
3821 int* varnamessize, /**< the size of the variable names storage, or NULL */
3822 int* consnamessize, /**< the size of the constraint names storage, or NULL */
3823 int* nvarnames, /**< the number of stored variable names, or NULL */
3824 int* nconsnames /**< the number of stored constraint names, or NULL */
3825 )
3826{
3827 SCIP_RETCODE retcode;
3828
3829 assert(reader != NULL);
3830 assert(scip != NULL);
3831 assert(result != NULL);
3832
3833 retcode = readMps(scip, filename, varnames, consnames, varnamessize, consnamessize, nvarnames, nconsnames);
3834
3835 if( retcode == SCIP_PLUGINNOTFOUND )
3836 retcode = SCIP_READERROR;
3837
3838 if( retcode == SCIP_NOFILE || retcode == SCIP_READERROR )
3839 return retcode;
3840
3841 SCIP_CALL( retcode );
3842
3843 *result = SCIP_SUCCESS;
3844
3845 return SCIP_OKAY;
3846}
3847
3848
3849/** writes problem to file */
3851 SCIP* scip, /**< SCIP data structure */
3852 SCIP_READER* reader, /**< the file reader itself */
3853 FILE* file, /**< output file, or NULL if standard output should be used */
3854 const char* name, /**< problem name */
3855 SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
3856 SCIP_OBJSENSE objsense, /**< objective sense */
3857 SCIP_Real objscale, /**< scalar applied to objective function; external objective value is
3858 * extobj = objsense * objscale * (intobj + objoffset) */
3859 SCIP_Real objoffset, /**< objective offset from bound shifting and fixing */
3860 SCIP_VAR** vars, /**< array with active variables ordered binary, integer, implicit, continuous */
3861 int nvars, /**< number of active variables in the problem */
3862 int nbinvars, /**< number of binary variables */
3863 int nintvars, /**< number of general integer variables */
3864 int nimplvars, /**< number of implicit integer variables */
3865 int ncontvars, /**< number of continuous variables */
3866 SCIP_VAR** fixedvars, /**< array with fixed and aggregated variables */
3867 int nfixedvars, /**< number of fixed and aggregated variables in the problem */
3868 SCIP_CONS** conss, /**< array with constraints of the problem */
3869 int nconss, /**< number of constraints in the problem */
3870 SCIP_RESULT* result /**< pointer to store the result of the file writing call */
3871 )
3872{
3873 SCIP_READERDATA* readerdata;
3874 int naddrows;
3875 int faulty = 0;
3876 int c;
3877 int v;
3878 int k;
3879 char* namestr;
3880
3881 SCIP_CONS* cons = NULL;
3882 const char* consname;
3883 const char** consnames;
3884
3885 SCIP_CONSHDLR* conshdlr;
3886 const char* conshdlrname;
3887
3888 SCIP_Real lhs;
3889 SCIP_Real rhs;
3890 SCIP_Real* rhss;
3891 SCIP_Real value;
3892
3893 SCIP_VAR* var = NULL;
3894 const char* varname;
3895 const char** varnames;
3896
3897 char valuestr[MPS_MAX_VALUELEN] = { '\0' };
3898
3899 SCIP_CONS** consIndicator;
3900 SCIP_CONS** consSOS1;
3901 SCIP_CONS** consSOS2;
3902 SCIP_CONS** consQuadratic;
3903 int nConsIndicator;
3904 int nConsSOS1;
3905 int nConsSOS2;
3906 int nConsQuadratic;
3907
3908 SCIP_HASHMAP* varnameHashmap; /* hash map from SCIP_VAR* to variable name */
3909 SPARSEMATRIX* matrix;
3910
3911 SCIP_VAR** aggvars;
3912 int naggvars = 0;
3913 int saggvars;
3914 SCIP_HASHTABLE* varFixedHash;
3915 SCIP_HASHTABLE* indicatorSlackHash;
3916
3917 SCIP_VAR** fixvars = NULL;
3918 int nfixvars = 0;
3919
3920 SCIP_VAR** consvars;
3921 int nconsvars;
3922 SCIP_Real* vals;
3923 SCIP_Longint* weights;
3924
3925 SCIP_Bool needRANGES;
3926 unsigned int maxnamelen;
3927
3928 SCIP_Bool error;
3929
3930 assert(reader != NULL);
3931 assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
3932 assert(scip != NULL);
3933 assert(result != NULL);
3934
3935 needRANGES = FALSE;
3936 maxnamelen = 0;
3937 nConsSOS1 = 0;
3938 nConsSOS2 = 0;
3939 nConsQuadratic = 0;
3940 nConsIndicator = 0;
3941
3942 /* check if the constraint names are too long and build the constraint names */
3943 SCIP_CALL( checkConsnames(scip, conss, nconss, transformed, &maxnamelen, &consnames, &error) );
3944 if( error )
3945 {
3946 /* call writing with generic names */
3947 if( transformed )
3948 {
3949 SCIPwarningMessage(scip, "write transformed problem with generic variable and constraint names\n");
3950 SCIP_CALL( SCIPprintTransProblem(scip, file, "mps", TRUE) );
3951 }
3952 else
3953 {
3954 SCIPwarningMessage(scip, "write original problem with generic variable and constraint names\n");
3955 SCIP_CALL( SCIPprintOrigProblem(scip, file, "mps", TRUE) );
3956 }
3957 *result = SCIP_SUCCESS;
3958
3959 return SCIP_OKAY;
3960 }
3961
3962 /* check if the variable names are not too long and build the "variable" -> "variable name" hash map */
3963 SCIP_CALL( checkVarnames(scip, vars, nvars, &maxnamelen, &varnames, &varnameHashmap) );
3964
3965 /* collect SOS, quadratic, and indicator constraints in array for later output */
3966 SCIP_CALL( SCIPallocBufferArray(scip, &consSOS1, nconss) );
3967 SCIP_CALL( SCIPallocBufferArray(scip, &consSOS2, nconss) );
3968 SCIP_CALL( SCIPallocBufferArray(scip, &consQuadratic, nconss) );
3969 SCIP_CALL( SCIPallocBufferArray(scip, &consIndicator, nconss) );
3970
3971 /* nfixedvars counts all variables with status SCIP_VARSTATUS_FIXED, SCIP_VARSTATUS_AGGREGATED, SCIP_VARSTATUS_MULTAGGR, but not SCIP_VARSTATUS_NEGATED */
3972 saggvars = nfixedvars;
3973 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &aggvars, saggvars) );
3974
3975 /* create hashtable for storing aggregated variables */
3976 if( nfixedvars > 0 )
3977 {
3978 SCIP_CALL( SCIPhashtableCreate(&varFixedHash, SCIPblkmem(scip), nfixedvars, hashGetKeyVar, hashKeyEqVar, hashKeyValVar, NULL) );
3979 }
3980 else
3981 varFixedHash = NULL;
3982
3983 if( nvars > 0 )
3984 {
3985 SCIP_CALL( SCIPhashtableCreate(&indicatorSlackHash, SCIPblkmem(scip), nvars, hashGetKeyVar, hashKeyEqVar, hashKeyValVar, NULL) );
3986 }
3987 else
3988 indicatorSlackHash = NULL;
3989
3990 /* initialize sparse matrix */
3991 SCIP_CALL( initializeMatrix(scip, &matrix, (nvars * 2 + nfixedvars)) );
3992 assert( matrix->sentries >= nvars );
3993
3994 readerdata = SCIPreaderGetData(reader);
3995 assert(readerdata != NULL);
3996
3997 naddrows = 0;
3998
3999 /* determine and-constraints and printing format to resize necessary arrays */
4000 if( readerdata->linearizeands )
4001 {
4002 SCIP_CONSHDLR* andconshdlr = SCIPfindConshdlr(scip, "and");
4003
4004 if( andconshdlr != NULL )
4005 {
4006 /* need to check for and-constraints, note that in the original problem you cannot get the number of
4007 * and-constraints by one call */
4008 for( c = nconss - 1; c >= 0; --c )
4009 {
4010 conshdlr = SCIPconsGetHdlr(conss[c]);
4011 assert(conshdlr != NULL);
4012
4013 conshdlrname = SCIPconshdlrGetName(conshdlr);
4014
4015 if( strcmp(conshdlrname, "and") == 0 )
4016 {
4017 if( readerdata->aggrlinearizationands )
4018 ++naddrows;
4019 else
4020 naddrows += SCIPgetNVarsAnd(scip, conss[c]);
4021 }
4022 }
4023 assert(naddrows >= 0);
4024
4025 if( naddrows > 0 )
4026 {
4027 /* resize consnames vector */
4028 SCIP_CALL( SCIPreallocBufferArray(scip, &consnames, nconss + naddrows) );
4029 }
4030 }
4031 }
4032
4033 /* initialize rhs vector */
4034 SCIP_CALL( SCIPallocBufferArray(scip, &rhss, nconss + naddrows) );
4035
4036 /* print statistics as comment to file stream */
4037 SCIPinfoMessage(scip, file, "* SCIP STATISTICS\n");
4038 SCIPinfoMessage(scip, file, "* Problem name : %s\n", name);
4039 SCIPinfoMessage(scip, file, "* Variables : %d (%d binary, %d integer, %d implicit integer, %d continuous)\n",
4040 nvars, nbinvars, nintvars, nimplvars, ncontvars);
4041 SCIPinfoMessage(scip, file, "* Constraints : %d\n", nconss);
4042
4043 /* print NAME of the problem */
4044 SCIPinfoMessage(scip, file, "%-14s%s\n", "NAME", name);
4045
4046 /* print OBJSENSE of the problem */
4047 SCIPinfoMessage(scip, file, "OBJSENSE\n");
4048 SCIPinfoMessage(scip, file, "%s\n", objsense == SCIP_OBJSENSE_MAXIMIZE ? " MAX" : " MIN");
4049
4050 /* start ROWS section */
4051 SCIPinfoMessage(scip, file, "ROWS\n");
4052
4053 /* print row type for the objective function */
4054 printStart(scip, file, "N", "Obj", -1);
4055 SCIPinfoMessage(scip, file, "\n");
4056
4057 /* first fill the matrix with the objective coefficients */
4058 for( v = 0; v < nvars; ++v )
4059 {
4060 /* take care of the objective entry */
4061 var = vars[v];
4062 value = SCIPvarGetObj(var);
4063
4064 /* we also want to add integer variables to the columns section, even if the objective value is 0, because it
4065 * might happen that they only exist in non-linear constraints, which leads to no other line in the column section
4066 * and therefore do not mark the variable as an integer
4067 */
4068 if( !SCIPisZero(scip, value) || SCIPvarGetType(var) < SCIP_VARTYPE_IMPLINT
4071 {
4072 assert( matrix->nentries < matrix->sentries );
4073
4074 matrix->values[matrix->nentries] = objscale * value;
4075 matrix->columns[matrix->nentries] = var;
4076 matrix->rows[matrix->nentries] = "Obj";
4077 matrix->nentries++;
4078 }
4079 }
4080
4081 /* loop over all constraints */
4082 k = nconss;
4083 for( c = 0; c < nconss; ++c )
4084 {
4085 cons = conss[c];
4086 assert( cons != NULL);
4087
4088 /* in case the transformed problems is written only constraint are posted which are enabled in the current node;
4089 * the conss array should only contain relevant constraints
4090 */
4091 assert( !transformed || SCIPconsIsEnabled(cons) );
4092
4093 conshdlr = SCIPconsGetHdlr(cons);
4094 assert( conshdlr != NULL );
4095
4096 conshdlrname = SCIPconshdlrGetName(conshdlr);
4097
4098 /* construct constraint name */
4099 consname = consnames[c];
4100
4101 /* init rhs value to infinity (would then ignored) */
4102 rhss[c] = SCIPinfinity(scip);
4103
4104 if( strcmp(conshdlrname, "linear") == 0 )
4105 {
4106 lhs = SCIPgetLhsLinear(scip, cons);
4107 rhs = SCIPgetRhsLinear(scip, cons);
4108
4109 /* there is nothing to do if the left hand side is minus infinity and the right side is infinity */
4110 if( !SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs) )
4111 {
4112 if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && !SCIPisEQ(scip, lhs, rhs) )
4113 needRANGES = TRUE;
4114
4115 /* print row entry */
4116 printRowType(scip, file, lhs, rhs, consname);
4117
4118 if( SCIPisInfinity(scip, rhs) )
4119 rhss[c] = lhs;
4120 else
4121 rhss[c] = rhs;
4122
4123 assert( !SCIPisInfinity(scip, rhss[c]) );
4124
4125 /* compute column entries */
4127 SCIPgetNVarsLinear(scip, cons), transformed, matrix, &rhss[c]) );
4128 }
4129 }
4130 else if( strcmp(conshdlrname, "setppc") == 0 )
4131 {
4132 /* print row entry */
4133 switch( SCIPgetTypeSetppc(scip, cons) )
4134 {
4136 printRowType(scip, file, 1.0, 1.0, consname);
4137 break;
4139 printRowType(scip, file, -SCIPinfinity(scip), 1.0, consname);
4140 break;
4143 break;
4144 }
4145
4146 rhss[c] = 1.0;
4147
4148 /* compute column entries */
4149 SCIP_CALL( getLinearCoeffs(scip, consname, SCIPgetVarsSetppc(scip, cons), NULL, SCIPgetNVarsSetppc(scip, cons), transformed, matrix, &rhss[c]) );
4150 }
4151 else if( strcmp(conshdlrname, "logicor") == 0 )
4152 {
4153 /* print row entry */
4155
4156 rhss[c] = 1.0;
4157
4158 /* compute column entries */
4159 SCIP_CALL( getLinearCoeffs(scip, consname, SCIPgetVarsLogicor(scip, cons), NULL, SCIPgetNVarsLogicor(scip, cons), transformed, matrix, &rhss[c]) );
4160 }
4161 else if( strcmp(conshdlrname, "knapsack") == 0 )
4162 {
4163 int i;
4164
4165 /* print row entry */
4167
4168 nconsvars = SCIPgetNVarsKnapsack(scip, cons);
4169 weights = SCIPgetWeightsKnapsack(scip, cons);
4170
4171 /* copy Longint array to SCIP_Real array */
4172 SCIP_CALL( SCIPallocBufferArray(scip, &vals, nconsvars ) );
4173 for( i = 0; i < nconsvars; ++i )
4174 vals[i] = (SCIP_Real)weights[i];
4175
4176 rhss[c] = (SCIP_Real) SCIPgetCapacityKnapsack(scip, cons);
4177
4178 /* compute column entries */
4179 SCIP_CALL( getLinearCoeffs(scip, consname, SCIPgetVarsKnapsack(scip, cons), vals, nconsvars, transformed, matrix, &rhss[c]) );
4180
4181 SCIPfreeBufferArray(scip, &vals);
4182 }
4183 else if( strcmp(conshdlrname, "varbound") == 0 )
4184 {
4185 lhs = SCIPgetLhsVarbound(scip, cons);
4186 rhs = SCIPgetRhsVarbound(scip, cons);
4187
4188 /* there is nothing to do if the left hand side is minus infinity and the right side is infinity */
4189 if( !SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs) )
4190 {
4191 if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && !SCIPisEQ(scip, lhs, rhs) )
4192 needRANGES = TRUE;
4193
4194 /* print row entry */
4195 printRowType(scip, file, lhs, rhs, consname);
4196
4197 /* allocate memory */
4198 SCIP_CALL( SCIPallocBufferArray(scip, &consvars, 2) );
4199 SCIP_CALL( SCIPallocBufferArray(scip, &vals, 2) );
4200
4201 consvars[0] = SCIPgetVarVarbound(scip, cons);
4202 consvars[1] = SCIPgetVbdvarVarbound(scip, cons);
4203
4204 vals[0] = 1.0;
4205 vals[1] = SCIPgetVbdcoefVarbound(scip, cons);
4206
4207 if( SCIPisInfinity(scip, rhs) )
4208 rhss[c] = lhs;
4209 else
4210 rhss[c] = rhs;
4211
4212 assert( !SCIPisInfinity(scip, rhss[c]) );
4213
4214 /* compute column entries */
4215 SCIP_CALL( getLinearCoeffs(scip, consname, consvars, vals, 2, transformed, matrix, &rhss[c]) );
4216
4217 SCIPfreeBufferArray(scip, &vals);
4218 SCIPfreeBufferArray(scip, &consvars);
4219 }
4220 }
4221 else if( strcmp(conshdlrname, "indicator") == 0 )
4222 {
4223 SCIP_VAR* slackvar;
4224 SCIP_VAR* binvar;
4225
4226 /* store slack variable in hash */
4227 slackvar = SCIPgetSlackVarIndicator(cons);
4228 assert( slackvar != NULL );
4229 assert( indicatorSlackHash != NULL );
4230 assert( !SCIPhashtableExists(indicatorSlackHash, (void*) slackvar) );
4231 SCIP_CALL( SCIPhashtableInsert(indicatorSlackHash, (void*) slackvar) );
4232
4233 /* if slackvariable is aggregated, we store it in the list of aggregated variables */
4235 {
4236 SCIP_CALL( collectAggregatedVars(scip, &slackvar, 1, &aggvars, &naggvars, &saggvars, varFixedHash) );
4237 }
4238
4239 /* store aggregated variables */
4240 binvar = SCIPgetBinaryVarIndicator(cons);
4241 if( SCIPvarIsNegated(binvar) )
4242 binvar = SCIPvarGetNegatedVar(binvar);
4243 assert( binvar != NULL );
4244 SCIP_CALL( collectAggregatedVars(scip, &binvar, 1, &aggvars, &naggvars, &saggvars, varFixedHash) );
4245
4246 /* indicator constraint do not have a right hand side; mark this with SCIPinfinity(scip) */
4247 rhss[c] = SCIPinfinity(scip);
4248
4249 /* store constraint */
4250 consIndicator[nConsIndicator++] = cons;
4251 continue;
4252 }
4253 else if( strcmp(conshdlrname, "SOS1") == 0 )
4254 {
4255 /* store constraint */
4256 consSOS1[nConsSOS1++] = cons;
4257
4258 /* check for aggregated variables in SOS1 constraints for later output
4259 * of aggregations as linear constraints */
4260 consvars = SCIPgetVarsSOS1(scip, cons);
4261 nconsvars = SCIPgetNVarsSOS1(scip, cons);
4262
4263 /* SOS constraint do not have a right hand side; mark this with SCIPinfinity(scip) */
4264 rhss[c] = SCIPinfinity(scip);
4265
4266 SCIP_CALL( collectAggregatedVars(scip, consvars, nconsvars, &aggvars, &naggvars, &saggvars, varFixedHash) );
4267 }
4268 else if( strcmp(conshdlrname, "SOS2") == 0 )
4269 {
4270 /* store constraint */
4271 consSOS2[nConsSOS2++] = cons;
4272
4273 /* check for aggregated variables in SOS2 constraints for later output aggregations as linear constraints */
4274 consvars = SCIPgetVarsSOS2(scip, cons);
4275 nconsvars = SCIPgetNVarsSOS2(scip, cons);
4276
4277 /* SOS constraint do not have a right hand side; mark this with SCIPinfinity(scip) */
4278 rhss[c] = SCIPinfinity(scip);
4279
4280 SCIP_CALL( collectAggregatedVars(scip, consvars, nconsvars, &aggvars, &naggvars, &saggvars, varFixedHash) );
4281 }
4282 else if( strcmp(conshdlrname, "nonlinear") == 0 )
4283 {
4284 SCIP_EXPR* expr;
4285 SCIP_VAR** quadvars;
4286 SCIP_Real* quadvarlincoefs;
4287 SCIP_Real* lincoefs;
4288 SCIP_Real constant;
4289 SCIP_EXPR** linexprs;
4290 SCIP_Bool isquadratic;
4291 int nquadexprs;
4292 int nlinexprs;
4293 int j;
4294
4295 /* check if it is a quadratic constraint */
4296 SCIP_CALL( SCIPcheckQuadraticNonlinear(scip, cons, &isquadratic) );
4297 if( !isquadratic )
4298 {
4299 /* unknown constraint type; mark this with SCIPinfinity(scip) */
4300 rhss[c] = SCIPinfinity(scip);
4301
4302 SCIPwarningMessage(scip, "constraint handler <%s> cannot print requested format\n", conshdlrname );
4303 continue;
4304 }
4305
4306 /* store constraint */
4307 consQuadratic[nConsQuadratic++] = cons;
4308
4309 expr = SCIPgetExprNonlinear(cons);
4310
4311 /* collect linear coefficients of quadratic part */
4312 SCIPexprGetQuadraticData(expr, &constant, &nlinexprs, &linexprs, &lincoefs, &nquadexprs, NULL, NULL,
4313 NULL);
4314
4315 SCIP_CALL( SCIPallocBufferArray(scip, &quadvars, nquadexprs) );
4316 SCIP_CALL( SCIPallocBufferArray(scip, &quadvarlincoefs, nquadexprs) );
4317 for( j = 0; j < nquadexprs; ++j )
4318 {
4319 SCIP_EXPR* qexpr;
4320
4321 SCIPexprGetQuadraticQuadTerm(expr, j, &qexpr, &quadvarlincoefs[j], NULL, NULL, NULL, NULL);
4322
4323 assert(SCIPisExprVar(scip, qexpr));
4324 quadvars[j] = SCIPgetVarExprVar(qexpr);
4325 }
4326
4327 lhs = SCIPgetLhsNonlinear(cons);
4328 rhs = SCIPgetRhsNonlinear(cons);
4329
4330 /* correct side by constant */
4331 lhs -= SCIPisInfinity(scip, -lhs) ? 0.0 : constant;
4332 rhs -= SCIPisInfinity(scip, rhs) ? 0.0 : constant;
4333
4334 /* there is nothing to do if the left hand side is minus infinity and the right side is infinity */
4335 if( !SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs) )
4336 {
4337 SCIP_VAR** linvars;
4338
4339 if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && !SCIPisEQ(scip, lhs, rhs) )
4340 needRANGES = TRUE;
4341
4342 /* print row entry */
4343 printRowType(scip, file, lhs, rhs, consname);
4344
4345 if( SCIPisInfinity(scip, rhs) )
4346 rhss[c] = lhs;
4347 else
4348 rhss[c] = rhs;
4349
4350 assert( !SCIPisInfinity(scip, rhss[c]) );
4351
4352 /* get linear vars */
4353 SCIP_CALL( SCIPallocBufferArray(scip, &linvars, nlinexprs) );
4354 for( j = 0; j < nlinexprs; ++j )
4355 linvars[j] = SCIPgetVarExprVar(linexprs[j]);
4356
4357 /* compute column entries for linear part */
4358 SCIP_CALL( getLinearCoeffs(scip, consname, linvars, lincoefs, nlinexprs, transformed, matrix, &rhss[c]) );
4359
4360 /* compute column entries for linear part in quadratic part */
4361 SCIP_CALL( getLinearCoeffs(scip, consname, quadvars, quadvarlincoefs, nquadexprs, transformed, matrix,
4362 &rhss[c]) );
4363
4364 SCIPfreeBufferArray(scip, &linvars);
4365 }
4366
4367 /* check for aggregated variables in quadratic part of quadratic constraints for later output of
4368 * aggregations as linear constraints */
4369 consvars = quadvars;
4370 nconsvars = nquadexprs;
4371
4372 SCIP_CALL( collectAggregatedVars(scip, consvars, nconsvars, &aggvars, &naggvars, &saggvars, varFixedHash) );
4373
4374 SCIPfreeBufferArray(scip, &quadvars);
4375 SCIPfreeBufferArray(scip, &quadvarlincoefs);
4376 }
4377 else if( strcmp(conshdlrname, "and") == 0 )
4378 {
4379 if( readerdata->linearizeands )
4380 {
4381 SCIP_VAR** rowvars;
4382 SCIP_VAR** operands;
4383 SCIP_VAR* resultant;
4384 SCIP_Real* rowvals;
4385 char* rowname;
4386 int nrowvars;
4387 int l;
4388 int n;
4389
4390 nrowvars = SCIPgetNVarsAnd(scip, cons);
4391 operands = SCIPgetVarsAnd(scip, cons);
4392 resultant = SCIPgetResultantAnd(scip, cons);
4393
4394 /* allocate buffer array */
4395 SCIP_CALL( SCIPallocBufferArray(scip, &rowvars, nrowvars + 1) );
4396 SCIP_CALL( SCIPallocBufferArray(scip, &rowvals, nrowvars + 1) );
4397
4398 /* get length of constraint name */
4399 l = (int) strlen(consname);
4400
4401 /* the tight relaxtion, number of and-constraint operands rows */
4402 if( !readerdata->aggrlinearizationands )
4403 {
4404 rowvars[0] = resultant;
4405 rowvals[0] = 1.0;
4406 rowvals[1] = -1.0;
4407
4408 /* compute maximal length for rowname */
4409 /* coverity[negative_returns] */
4410 n = (int) log10((double)nrowvars) + 1 + l;
4411
4412 /* assure maximal allowed value */
4413 if( n >= MPS_MAX_NAMELEN )
4414 n = MPS_MAX_NAMELEN - 1;
4415
4416 /* update maxnamelen */
4417 maxnamelen = MAX(maxnamelen, (unsigned int) n);
4418
4419 /* print operator rows */
4420 for( v = 0; v < nrowvars; ++v )
4421 {
4422 /* compute maximal length for rowname */
4423 if( v == 0 )
4424 n = 2;
4425 else
4426 n = (int) log10((double)v) + 2;
4427 n += l;
4428
4429 /* assure maximal allowed value */
4430 if( n >= MPS_MAX_NAMELEN )
4431 {
4432 n = MPS_MAX_NAMELEN - 1;
4433 ++faulty;
4434 }
4435
4436 /* need memory for additional row */
4437 SCIP_CALL( SCIPallocBufferArray(scip, &rowname, n + 1) );
4438
4439 assert(k < nconss + naddrows);
4440 consnames[k] = rowname;
4441
4442 (void) SCIPsnprintf(rowname, n + 1, "%s_%d", consname, v);
4443 rowvars[1] = operands[v];
4444
4445 /* print row entry */
4446 printRowType(scip, file, -SCIPinfinity(scip), 0.0, rowname);
4447
4448 rhss[k] = 0.0;
4449
4450 /* compute column entries */
4451 SCIP_CALL( getLinearCoeffs(scip, rowname, rowvars, rowvals, 2, transformed, matrix, &rhss[k]) );
4452 ++k;
4453 }
4454 }
4455
4456 /* prepare for next row */
4457 for( v = nrowvars - 1; v >= 0; --v )
4458 {
4459 rowvars[v] = operands[v];
4460 rowvals[v] = -1.0;
4461 }
4462
4463 rowvars[nrowvars] = resultant;
4464
4465 /* the weak relaxtion, only one constraint */
4466 if( readerdata->aggrlinearizationands )
4467 {
4468 /* compute maximal length for rowname */
4469 n = l + 3;
4470
4471 /* assure maximal allowed value */
4472 if( n >= MPS_MAX_NAMELEN )
4473 {
4474 n = MPS_MAX_NAMELEN - 1;
4475 ++faulty;
4476 }
4477
4478 /* update maxnamelen */
4479 maxnamelen = MAX(maxnamelen, (unsigned int) n);
4480
4481 /* need memory for additional row */
4482 SCIP_CALL( SCIPallocBufferArray(scip, &rowname, n + 1) );
4483
4484 assert(k < nconss + naddrows);
4485 consnames[k] = rowname;
4486
4487 /* adjust rowname of constraint */
4488 (void) SCIPsnprintf(rowname, n + 1, "%s_op", consname);
4489
4490 rowvals[nrowvars] = (SCIP_Real) nrowvars;
4491
4492 /* print row entry */
4493 printRowType(scip, file, -SCIPinfinity(scip), 0.0, rowname);
4494
4495 rhss[k] = 0.0;
4496
4497 /* compute column entries */
4498 SCIP_CALL( getLinearCoeffs(scip, rowname, rowvars, rowvals, nrowvars + 1, transformed, matrix, &rhss[k]) );
4499
4500 SCIPdebugMsg(scip, "%g, %g\n", rowvals[1], rhss[k]);
4501 ++k;
4502 }
4503
4504 rowvals[nrowvars] = 1.0;
4505
4506 /* print row entry */
4507 printRowType(scip, file, -nrowvars + 1.0, SCIPinfinity(scip), consname);
4508
4509 rhss[c] = -nrowvars + 1.0;
4510
4511 /* compute column entries */
4512 SCIP_CALL( getLinearCoeffs(scip, consname, rowvars, rowvals, nrowvars + 1, transformed, matrix, &rhss[c]) );
4513
4514 /* free buffer array */
4515 SCIPfreeBufferArray(scip, &rowvals);
4516 SCIPfreeBufferArray(scip, &rowvars);
4517 }
4518 else
4519 {
4520 /* and constraint printing not enabled; mark this with SCIPinfinity(scip) */
4521 rhss[c] = SCIPinfinity(scip);
4522
4523 SCIPwarningMessage(scip, "change parameter \"reading/" READER_NAME "/linearize-and-constraints\" to TRUE to print and-constraints\n");
4524 }
4525 }
4526 else
4527 {
4528 /* unknown constraint type; mark this with SCIPinfinity(scip) */
4529 rhss[c] = SCIPinfinity(scip);
4530
4531 SCIPwarningMessage(scip, "constraint handler <%s> cannot print requested format\n", conshdlrname );
4532 }
4533 }
4534
4535 if( faulty > 0 )
4536 {
4537 SCIPwarningMessage(scip, "there are %d and-constraint-rownames which have to be cut down to %d characters; MPS file might be corrupted\n",
4538 faulty, MPS_MAX_NAMELEN - 1);
4539 }
4540
4541 /* free hash table */
4542 if( varFixedHash != NULL )
4543 SCIPhashtableFree(&varFixedHash);
4544
4545 if( indicatorSlackHash != NULL && nConsIndicator == 0 )
4546 {
4547 SCIPhashtableFree(&indicatorSlackHash);
4548 assert( indicatorSlackHash == NULL );
4549 }
4550
4551 if( naggvars > 0 )
4552 {
4553 /* construct variables name of the needed aggregated variables and the constraint names for the aggregation constraints */
4554
4555 /* realloc memory */
4556 SCIP_CALL( SCIPreallocBufferArray(scip, &consnames, nconss + naddrows + naggvars) );
4557 SCIP_CALL( SCIPreallocBufferArray(scip, &rhss, nconss + naddrows + naggvars) );
4558 SCIP_CALL( SCIPreallocBufferArray(scip, &varnames, nvars + naggvars) );
4559
4560 for( c = 0; c < naggvars; ++c )
4561 {
4562 size_t l;
4563
4564 /* create variable name */
4565 var = aggvars[c];
4566
4567 l = strlen(SCIPvarGetName(var));
4568 if( l >= MPS_MAX_NAMELEN )
4569 maxnamelen = MPS_MAX_NAMELEN - 1;
4570 else
4571 maxnamelen = MAX(maxnamelen, (unsigned int) l);
4572
4574 (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
4575
4576 /* insert variable with variable name into hash map */
4577 varnames[nvars + c] = namestr;
4578 assert( !SCIPhashmapExists(varnameHashmap, var) );
4579 SCIP_CALL( SCIPhashmapInsert(varnameHashmap, var, (void*) namestr) );
4580
4581 /* output row type (it is an equation) */
4582 SCIP_CALL( SCIPallocBufferArray(scip, &namestr, MPS_MAX_NAMELEN) ); /* note that namestr above is freed via varnames */
4583 (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "aggr_%s", SCIPvarGetName(var));
4584 printRowType(scip, file, 1.0, 1.0, namestr);
4585
4586 l = strlen(namestr);
4587 maxnamelen = MAX(maxnamelen, (unsigned int) l);
4588 consnames[nconss + naddrows + c] = namestr;
4589 rhss[nconss + naddrows + c] = 0.0;
4590
4591 /* compute column entries */
4592 SCIP_CALL( getLinearCoeffs(scip, namestr, &(aggvars[c]), NULL, 1, transformed, matrix, &rhss[nconss + naddrows + c]) );
4593
4594 /* add the aggregated variables to the sparse matrix */
4596 matrix->values[matrix->nentries] = -1.0;
4597 matrix->columns[matrix->nentries] = aggvars[c];
4598 matrix->rows[matrix->nentries] = namestr;
4599 matrix->nentries++;
4600 }
4601 }
4602
4603 /* collect also fixed variables, because they might not be removed from all constraints */
4604 /* @todo only collect fixed variables in the non-linear constraint types, where they (could not be)/(were not) removed */
4605 if( nfixedvars > 0 )
4606 {
4607 int startpos = nvars + naggvars;
4608 /* construct variables name of fixed variables */
4609
4610 /* realloc memory */
4611 SCIP_CALL( SCIPreallocBufferArray(scip, &varnames, startpos + nfixedvars) );
4612
4613 /* allocate memory for fixed variables */
4614 SCIP_CALL( SCIPallocBufferArray(scip, &fixvars, nfixedvars) );
4615
4616 for( v = nfixedvars - 1; v >= 0; --v )
4617 {
4618 /* create variable name */
4619 var = fixedvars[v];
4620
4622 {
4623 size_t l;
4624 l = strlen(SCIPvarGetName(var));
4625 if( l >= MPS_MAX_NAMELEN )
4626 maxnamelen = MPS_MAX_NAMELEN - 1;
4627 else
4628 maxnamelen = MAX(maxnamelen, (unsigned int) l);
4629
4631 (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
4632
4633 varnames[startpos + nfixvars] = namestr;
4634 fixvars[nfixvars] = var;
4635 ++nfixvars;
4636
4637 /* insert variable with variable name into hash map */
4638 assert(!SCIPhashmapExists(varnameHashmap, var));
4639 SCIP_CALL( SCIPhashmapInsert(varnameHashmap, var, (void*) namestr) );
4640
4641 /* add the fixed variables to the sparse matrix, needed for columns section */
4643 matrix->values[matrix->nentries] = 0.0;
4644 matrix->columns[matrix->nentries] = var;
4645 matrix->rows[matrix->nentries] = "Obj";
4646 matrix->nentries++;
4647 }
4648 }
4649 }
4650
4651 /* output COLUMNS section */
4652 printColumnSection(scip, file, matrix, varnameHashmap, indicatorSlackHash, maxnamelen);
4653
4654 /* output RHS section */
4655 printRhsSection(scip, file, nconss + naddrows +naggvars, consnames, rhss, maxnamelen, objscale * objoffset);
4656
4657 /* output RANGES section */
4658 if( needRANGES )
4659 printRangeSection(scip, file, conss, nconss, consnames, transformed, maxnamelen);
4660
4661 /* output BOUNDS section */
4662 printBoundSection(scip, file, vars, nvars, aggvars, naggvars, fixvars, nfixvars, transformed, varnames, indicatorSlackHash, maxnamelen);
4663
4664 if( nfixedvars > 0 )
4665 {
4666 SCIPfreeBufferArray(scip, &fixvars);
4667 }
4668
4669 /* print SOS section */
4670 if( nConsSOS1 > 0 || nConsSOS2 > 0 )
4671 {
4672 SCIP_Real* sosweights;
4673
4674 SCIPinfoMessage(scip, file, "SOS\n");
4675 SCIPdebugMsg(scip, "start printing SOS section\n");
4676
4678
4679 /* first output SOS1 constraints */
4680 for( c = 0; c < nConsSOS1; ++c )
4681 {
4682 cons = consSOS1[c];
4683 consvars = SCIPgetVarsSOS1(scip, cons);
4684 nconsvars = SCIPgetNVarsSOS1(scip, cons);
4685 sosweights = SCIPgetWeightsSOS1(scip, cons);
4686 (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "%s", SCIPconsGetName(cons) );
4687
4688 printStart(scip, file, "S1", namestr, -1);
4689 SCIPinfoMessage(scip, file, "\n");
4690
4691 for( v = 0; v < nconsvars; ++v )
4692 {
4693 /* get variable name */
4694 assert ( SCIPhashmapExists(varnameHashmap, consvars[v]) );
4695 varname = (const char*) SCIPhashmapGetImage(varnameHashmap, consvars[v]);
4696
4697 printStart(scip, file, "", varname, (int) maxnamelen);
4698
4699 if( sosweights != NULL )
4700 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", sosweights[v]);
4701 else
4702 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25d ", v);
4703
4704 SCIPinfoMessage(scip, file, "%25s\n", valuestr);
4705 }
4706 }
4707
4708 /* next output SOS2 constraints */
4709 for( c = 0; c < nConsSOS2; ++c )
4710 {
4711 cons = consSOS2[c];
4712 consvars = SCIPgetVarsSOS2(scip, cons);
4713 nconsvars = SCIPgetNVarsSOS2(scip, cons);
4714 sosweights = SCIPgetWeightsSOS2(scip, cons);
4715 (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "%s", SCIPconsGetName(cons) );
4716
4717 printStart(scip, file, "S2", namestr, -1);
4718 SCIPinfoMessage(scip, file, "\n");
4719
4720 for( v = 0; v < nconsvars; ++v )
4721 {
4722 /* get variable name */
4723 assert ( SCIPhashmapExists(varnameHashmap, consvars[v]) );
4724 varname = (const char*) SCIPhashmapGetImage(varnameHashmap, consvars[v]);
4725
4726 printStart(scip, file, "", varname, (int) maxnamelen);
4727
4728 if( sosweights != NULL )
4729 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", sosweights[v]);
4730 else
4731 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25d ", v);
4732
4733 SCIPinfoMessage(scip, file, "%25s\n", valuestr);
4734 }
4735 }
4736 SCIPfreeBufferArray(scip, &namestr);
4737 }
4738
4739 /* print QCMATRIX sections for quadratic constraints
4740 * in difference to a quadratic term in the objective function, the quadratic part is not divided by 2 here
4741 */
4742 if( nConsQuadratic > 0 )
4743 {
4744 const char* varname2;
4745 int nbilin;
4746
4747 SCIPdebugMsg(scip, "start printing QCMATRIX sections for quadratic constraints\n");
4749
4750 for( c = 0; c < nConsQuadratic; ++c )
4751 {
4752 SCIP_EXPR* expr;
4753
4754 cons = consQuadratic[c];
4755 expr = SCIPgetExprNonlinear(cons);
4756
4757 SCIPexprGetQuadraticData(expr, NULL, NULL, NULL, NULL, &nconsvars, &nbilin, NULL, NULL);
4758
4759 (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "%s", SCIPconsGetName(cons) );
4760
4761 SCIPinfoMessage(scip, file, "QCMATRIX %s\n", namestr);
4762
4763 /* print x^2 terms */
4764 for( v = 0; v < nconsvars; ++v )
4765 {
4766 SCIP_EXPR* qexpr;
4767 SCIP_VAR* qvar;
4768 SCIP_Real sqrcoef;
4769
4770 SCIPexprGetQuadraticQuadTerm(expr, v, &qexpr, NULL, &sqrcoef, NULL, NULL, NULL);
4771 if( sqrcoef == 0.0 )
4772 continue;
4773
4774 assert(SCIPisExprVar(scip, qexpr));
4775 qvar = SCIPgetVarExprVar(qexpr);
4776
4777 /* get variable name */
4778 assert(SCIPhashmapExists(varnameHashmap, qvar));
4779 varname = (const char*) SCIPhashmapGetImage(varnameHashmap, qvar);
4780
4781 /* get coefficient as string */
4782 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", sqrcoef);
4783
4784 /* print "x x coeff" line */
4785 printStart(scip, file, "", varname, (int) maxnamelen);
4786 printRecord(scip, file, varname, valuestr, maxnamelen);
4787 SCIPinfoMessage(scip, file, "\n");
4788 }
4789
4790 /* print bilinear terms; CPLEX format expects a symmetric matrix with all coefficients specified,
4791 * i.e., we have to split bilinear coefficients into two off diagonal elements */
4792 for( v = 0; v < nbilin; ++v )
4793 {
4794 SCIP_EXPR* expr1;
4795 SCIP_EXPR* expr2;
4796 SCIP_VAR* var1;
4797 SCIP_VAR* var2;
4798 SCIP_Real coef;
4799
4800 SCIPexprGetQuadraticBilinTerm(expr, v, &expr1, &expr2, &coef, NULL, NULL);
4801 assert(SCIPisExprVar(scip, expr1));
4802 assert(SCIPisExprVar(scip, expr2));
4803
4804 if( coef == 0.0 )
4805 continue;
4806
4807 var1 = SCIPgetVarExprVar(expr1);
4808 var2 = SCIPgetVarExprVar(expr2);
4809
4810 /* get name of first variable */
4811 assert ( SCIPhashmapExists(varnameHashmap, var1) );
4812 varname = (const char*) SCIPhashmapGetImage(varnameHashmap, var1);
4813
4814 /* get name of second variable */
4815 assert ( SCIPhashmapExists(varnameHashmap, var2) );
4816 varname2 = (const char*) SCIPhashmapGetImage(varnameHashmap, var2);
4817
4818 /* get coefficient as string */
4819 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", 0.5*coef);
4820
4821 /* print "x y coeff/2" line */
4822 printStart(scip, file, "", varname, (int) maxnamelen);
4823 printRecord(scip, file, varname2, valuestr, maxnamelen);
4824 SCIPinfoMessage(scip, file, "\n");
4825
4826 /* print "y x coeff/2" line */
4827 printStart(scip, file, "", varname2, (int) maxnamelen);
4828 printRecord(scip, file, varname, valuestr, maxnamelen);
4829 SCIPinfoMessage(scip, file, "\n");
4830 }
4831 }
4832
4833 SCIPfreeBufferArray(scip, &namestr);
4834 }
4835
4836 /* print indicator section */
4837 if( nConsIndicator > 0 )
4838 {
4840
4841 SCIPinfoMessage(scip, file, "INDICATORS\n");
4842 SCIPdebugMsg(scip, "start printing INDICATOR section\n");
4843
4844 /* output each indicator constraint */
4845 for( c = 0; c < nConsIndicator; ++c )
4846 {
4847 SCIP_CONS* lincons;
4848 SCIP_VAR* slackvar;
4849 SCIP_VAR* binvar;
4850
4851 cons = consIndicator[c];
4852 binvar = SCIPgetBinaryVarIndicator(cons);
4853 lincons = SCIPgetLinearConsIndicator(cons);
4854 slackvar = SCIPgetSlackVarIndicator(cons);
4855
4856 /* linvars always contains slack variable, thus nlinvars >= 1 */
4857 if( SCIPgetNVarsLinear(scip, lincons) <= 1 || SCIPconsIsDeleted(lincons) )
4858 continue;
4859
4860 /* create variable and value strings */
4861 if( SCIPvarIsNegated(binvar) )
4862 {
4863 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25d", 0);
4864 assert( SCIPvarGetNegatedVar(binvar) != NULL );
4865 assert( SCIPhashmapExists(varnameHashmap, SCIPvarGetNegatedVar(binvar)) );
4866 varname = (const char*) SCIPhashmapGetImage(varnameHashmap, SCIPvarGetNegatedVar(binvar));
4867 }
4868 else
4869 {
4870 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25d", 1);
4871 assert ( SCIPhashmapExists(varnameHashmap, binvar) );
4872 varname = (const char*) SCIPhashmapGetImage(varnameHashmap, binvar);
4873 }
4874
4875 /* write records */
4877 {
4878 /* for aggregated variables output name of aggregating constraint */
4879 (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "aggr_%s", SCIPvarGetName(slackvar));
4880 printStart(scip, file, "IF", namestr, (int) maxnamelen);
4881 printRecord(scip, file, varname, valuestr, maxnamelen);
4882 SCIPinfoMessage(scip, file, "\n");
4883 }
4884 else
4885 {
4886 printStart(scip, file, "IF", SCIPconsGetName(lincons), (int) maxnamelen);
4887 printRecord(scip, file, varname, valuestr, maxnamelen);
4888 SCIPinfoMessage(scip, file, "\n");
4889 }
4890 }
4891 SCIPfreeBufferArray(scip, &namestr);
4892 }
4893
4894 /* free matrix data structure */
4895 freeMatrix(scip, matrix);
4896
4897 /* free slackvar hashtable */
4898 if( indicatorSlackHash != NULL )
4899 SCIPhashtableFree(&indicatorSlackHash);
4900
4901 /* free variable hashmap */
4902 SCIPhashmapFree(&varnameHashmap);
4903
4904 SCIPfreeBlockMemoryArray(scip, &aggvars, saggvars);
4905 SCIPfreeBufferArray(scip, &rhss);
4906
4907 /* free buffer arrays for SOS1, SOS2, and quadratic */
4908 SCIPfreeBufferArray(scip, &consIndicator);
4909 SCIPfreeBufferArray(scip, &consQuadratic);
4910 SCIPfreeBufferArray(scip, &consSOS2);
4911 SCIPfreeBufferArray(scip, &consSOS1);
4912
4913 /* free variable and constraint name array */
4914 for( v = nvars + naggvars + nfixvars - 1; v >= 0; --v )
4915 SCIPfreeBufferArray(scip, &varnames[v]);
4916 SCIPfreeBufferArray(scip, &varnames);
4917
4918 for( c = nconss + naddrows + naggvars - 1; c >= 0; --c )
4919 SCIPfreeBufferArray(scip, &consnames[c]);
4920 SCIPfreeBufferArray(scip, &consnames);
4921
4922 /* print end of data line */
4923 SCIPinfoMessage(scip, file, "ENDATA");
4924
4925 *result = SCIP_SUCCESS;
4926
4927 return SCIP_OKAY;
4928}
static long * number
Constraint handler for AND constraints, .
constraint handler for bound disjunction constraints
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:267
#define SCIP_MAXSTRLEN
Definition: def.h:288
#define SCIP_Longint
Definition: def.h:158
#define SCIP_Bool
Definition: def.h:91
#define MIN(x, y)
Definition: def.h:243
#define SCIP_Real
Definition: def.h:173
#define SCIP_HASHSIZE_NAMES
Definition: def.h:299
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define MAX(x, y)
Definition: def.h:239
#define SCIP_CALL_TERMINATE(retcode, x, TERM)
Definition: def.h:395
#define SCIPABORT()
Definition: def.h:346
#define REALABS(x)
Definition: def.h:197
#define SCIP_CALL(x)
Definition: def.h:374
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
SCIP_RETCODE SCIPcheckQuadraticNonlinear(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *isquadratic)
int SCIPgetNVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPgetVbdcoefVarbound(SCIP *scip, SCIP_CONS *cons)
int SCIPgetNVarsLogicor(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_VAR ** SCIPgetVarsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPchgRhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real rhs)
SCIP_Real * SCIPgetWeightsSOS2(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos2.c:2778
SCIP_VAR ** SCIPgetVarsSOS2(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos2.c:2753
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:10716
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_VAR * SCIPgetVbdvarVarbound(SCIP *scip, SCIP_CONS *cons)
int SCIPgetNVarsSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9545
int SCIPgetNVarsSOS2(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos2.c:2728
SCIP_Real * SCIPgetWeightsSOS1(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos1.c:10833
SCIP_VAR ** SCIPgetVarsSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9568
SCIP_EXPR * SCIPgetExprNonlinear(SCIP_CONS *cons)
SCIP_Real SCIPgetRhsNonlinear(SCIP_CONS *cons)
SCIP_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:9591
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:10808
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:10783
SCIP_Real SCIPgetLhsNonlinear(SCIP_CONS *cons)
SCIP_RETCODE SCIPaddVarSOS2(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real weight)
Definition: cons_sos2.c:2677
@ 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 objscale, SCIP_Real objoffset, 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:3850
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:3814
SCIP_RETCODE SCIPincludeReaderMps(SCIP *scip)
Definition: reader_mps.c:3780
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_prob.c:1668
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2770
SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2843
SCIP_RETCODE SCIPsetObjsense(SCIP *scip, SCIP_OBJSENSE objsense)
Definition: scip_prob.c:1242
SCIP_RETCODE SCIPaddOrigObjoffset(SCIP *scip, SCIP_Real addval)
Definition: scip_prob.c:1290
SCIP_RETCODE SCIPcreateProb(SCIP *scip, const char *name, SCIP_DECL_PROBDELORIG((*probdelorig)), SCIP_DECL_PROBTRANS((*probtrans)), SCIP_DECL_PROBDELTRANS((*probdeltrans)), SCIP_DECL_PROBINITSOL((*probinitsol)), SCIP_DECL_PROBEXITSOL((*probexitsol)), SCIP_DECL_PROBCOPY((*probcopy)), SCIP_PROBDATA *probdata)
Definition: scip_prob.c:117
SCIP_VAR * SCIPfindVar(SCIP *scip, const char *name)
Definition: scip_prob.c:2685
SCIP_CONS * SCIPfindCons(SCIP *scip, const char *name)
Definition: scip_prob.c:2947
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:3108
void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3261
SCIP_RETCODE SCIPhashmapInsert(SCIP_HASHMAP *hashmap, void *origin, void *image)
Definition: misc.c:3156
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:3074
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3423
void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
Definition: misc.c:2346
SCIP_Bool SCIPhashtableExists(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2659
SCIP_RETCODE SCIPhashtableCreate(SCIP_HASHTABLE **hashtable, BMS_BLKMEM *blkmem, int tablesize, SCIP_DECL_HASHGETKEY((*hashgetkey)), SCIP_DECL_HASHKEYEQ((*hashkeyeq)), SCIP_DECL_HASHKEYVAL((*hashkeyval)), void *userptr)
Definition: misc.c:2296
void * SCIPhashtableRetrieve(SCIP_HASHTABLE *hashtable, void *key)
Definition: misc.c:2608
SCIP_RETCODE SCIPhashtableInsert(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2547
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:208
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: scip_message.c:225
#define SCIPdebugMsg
Definition: scip_message.h:78
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:120
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition: scip_param.c:250
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
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4197
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip_cons.c:941
SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
Definition: cons.c:8473
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:8234
SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
Definition: cons.c:8383
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
Definition: cons.c:8413
SCIP_Bool SCIPconsIsDeleted(SCIP_CONS *cons)
Definition: cons.c:8343
SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
Definition: cons.c:8403
SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
Definition: cons.c:8433
SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
Definition: cons.c:8453
SCIP_Bool SCIPconsIsEnabled(SCIP_CONS *cons)
Definition: cons.c:8311
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:8214
SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
Definition: cons.c:8463
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1174
SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
Definition: cons.c:8393
SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
Definition: cons.c:8483
void SCIPexprGetQuadraticBilinTerm(SCIP_EXPR *expr, int termidx, SCIP_EXPR **expr1, SCIP_EXPR **expr2, SCIP_Real *coef, int *pos2, SCIP_EXPR **prodexpr)
Definition: expr.c:4204
void SCIPexprGetQuadraticData(SCIP_EXPR *expr, SCIP_Real *constant, int *nlinexprs, SCIP_EXPR ***linexprs, SCIP_Real **lincoefs, int *nquadexprs, int *nbilinexprs, SCIP_Real **eigenvalues, SCIP_Real **eigenvectors)
Definition: expr.c:4119
SCIP_Bool SCIPisExprVar(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1431
SCIP_VAR * SCIPgetVarExprVar(SCIP_EXPR *expr)
Definition: expr_var.c:416
void SCIPexprGetQuadraticQuadTerm(SCIP_EXPR *quadexpr, int termidx, SCIP_EXPR **expr, SCIP_Real *lincoef, SCIP_Real *sqrcoef, int *nadjbilin, int **adjbilin, SCIP_EXPR **sqrexpr)
Definition: expr.c:4164
#define SCIPfreeBuffer(scip, ptr)
Definition: scip_mem.h:134
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:110
#define SCIPensureBlockMemoryArray(scip, ptr, arraysizeptr, minsize)
Definition: scip_mem.h:107
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
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:492
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:557
SCIP_RETCODE SCIPsetReaderRead(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERREAD((*readerread)))
Definition: scip_reader.c:195
SCIP_RETCODE SCIPsetReaderWrite(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERWRITE((*readerwrite)))
Definition: scip_reader.c:219
SCIP_RETCODE SCIPprintTransProblem(SCIP *scip, FILE *file, const char *extension, SCIP_Bool genericnames)
SCIP_RETCODE SCIPprintOrigProblem(SCIP *scip, FILE *file, const char *extension, SCIP_Bool genericnames)
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 SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisGT(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 SCIPgetProbvarLinearSum(SCIP *scip, SCIP_VAR **vars, SCIP_Real *scalars, int *nvars, int varssize, SCIP_Real *constant, int *requiredsize, SCIP_Bool mergemultiples)
Definition: scip_var.c:1738
SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:12774
SCIP_VAR * SCIPvarGetNegatedVar(SCIP_VAR *var)
Definition: var.c:17894
SCIP_RETCODE SCIPchgVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4676
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17538
int SCIPvarGetNLocksUpType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
Definition: var.c:3353
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:18144
SCIP_Real SCIPvarGetLbOriginal(SCIP_VAR *var)
Definition: var.c:18024
SCIP_RETCODE SCIPchgVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4766
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17926
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:17584
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:18088
int SCIPvarGetIndex(SCIP_VAR *var)
Definition: var.c:17758
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17419
SCIP_Real SCIPvarGetUbOriginal(SCIP_VAR *var)
Definition: var.c:18044
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip_var.c:1248
SCIP_RETCODE SCIPchgVarType(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
Definition: scip_var.c:8176
SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
Definition: scip_var.c:1527
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:18134
SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
Definition: var.c:17574
SCIP_RETCODE SCIPcreateVar(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_DECL_VARCOPY((*varcopy)), SCIP_VARDATA *vardata)
Definition: scip_var.c:114
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:18078
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip_var.c:4513
int SCIPvarGetNLocksDownType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
Definition: var.c:3295
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:10877
void SCIPprintSysError(const char *message)
Definition: misc.c:10769
char * SCIPstrtok(char *s, const char *delim, char **ptrptr)
Definition: misc.c:10818
int SCIPmemccpy(char *dest, const char *src, char stop, unsigned int cnt)
Definition: misc.c:10744
memory allocation routines
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip_mem.c:57
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
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:406
static void mpsinputInsertField4(MPSINPUT *mpsi, const char *str)
Definition: reader_mps.c:639
static const char * mpsinputField5(const MPSINPUT *mpsi)
Definition: reader_mps.c:287
static SCIP_RETCODE checkVarnames(SCIP *scip, SCIP_VAR **vars, int nvars, unsigned int *maxnamelen, const char ***varnames, SCIP_HASHMAP **varnameHashmap)
Definition: reader_mps.c:3075
static SCIP_RETCODE readSOS(MPSINPUT *mpsi, SCIP *scip)
Definition: reader_mps.c:1756
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:3337
static SCIP_DECL_READERWRITE(readerWriteMps)
Definition: reader_mps.c:3763
struct SparseMatrix SPARSEMATRIX
Definition: reader_mps.c:161
static const char * mpsinputField1(const MPSINPUT *mpsi)
Definition: reader_mps.c:243
static SCIP_DECL_HASHKEYEQ(hashKeyEqString)
Definition: reader_mps.c:2682
MpsSection
Definition: reader_mps.c:106
@ MPS_QCMATRIX
Definition: reader_mps.c:120
@ MPS_COLUMNS
Definition: reader_mps.c:113
@ MPS_NAME
Definition: reader_mps.c:107
@ MPS_BOUNDS
Definition: reader_mps.c:116
@ MPS_USERCUTS
Definition: reader_mps.c:111
@ MPS_SOS
Definition: reader_mps.c:117
@ MPS_ROWS
Definition: reader_mps.c:110
@ MPS_LAZYCONS
Definition: reader_mps.c:112
@ MPS_INDICATORS
Definition: reader_mps.c:121
@ MPS_OBJSEN
Definition: reader_mps.c:108
@ MPS_OBJNAME
Definition: reader_mps.c:109
@ MPS_QMATRIX
Definition: reader_mps.c:119
@ MPS_RHS
Definition: reader_mps.c:114
@ MPS_RANGES
Definition: reader_mps.c:115
@ MPS_ENDATA
Definition: reader_mps.c:122
@ MPS_QUADOBJ
Definition: reader_mps.c:118
static SCIP_RETCODE readObjsen(SCIP *scip, MPSINPUT *mpsi)
Definition: reader_mps.c:769
static SCIP_RETCODE checkSparseMatrixCapacity(SCIP *scip, SPARSEMATRIX *matrix, int capacity)
Definition: reader_mps.c:2882
static SCIP_RETCODE readQMatrix(MPSINPUT *mpsi, SCIP_Bool isQuadObj, SCIP *scip)
Definition: reader_mps.c:1950
static SCIP_Bool mpsinputHasError(const MPSINPUT *mpsi)
Definition: reader_mps.c:320
static SCIP_DECL_READERFREE(readerFreeMps)
Definition: reader_mps.c:3735
static SCIP_RETCODE readRows(MPSINPUT *mpsi, SCIP *scip, const char ***consnames, int *consnamessize, int *nconsnames)
Definition: reader_mps.c:867
static void printBoundSectionName(SCIP *scip, FILE *file)
Definition: reader_mps.c:3445
static const char * mpsinputField2(const MPSINPUT *mpsi)
Definition: reader_mps.c:254
static void clearFrom(char *buf, unsigned int pos)
Definition: reader_mps.c:428
static SCIP_RETCODE readRhs(MPSINPUT *mpsi, SCIP *scip)
Definition: reader_mps.c:1093
static void mpsinputSetObjname(MPSINPUT *mpsi, const char *objname)
Definition: reader_mps.c:368
static SCIP_RETCODE initializeMatrix(SCIP *scip, SPARSEMATRIX **matrix, int slots)
Definition: reader_mps.c:2864
static void freeMatrix(SCIP *scip, SPARSEMATRIX *matrix)
Definition: reader_mps.c:2900
static SCIP_RETCODE readObjname(SCIP *scip, MPSINPUT *mpsi)
Definition: reader_mps.c:828
enum MpsSection MPSSECTION
Definition: reader_mps.c:124
static SCIP_Bool mpsinputIsInteger(const MPSINPUT *mpsi)
Definition: reader_mps.c:331
struct MpsInput MPSINPUT
Definition: reader_mps.c:150
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:2915
static void mpsinputSetProbname(MPSINPUT *mpsi, const char *probname)
Definition: reader_mps.c:354
static SCIP_DECL_HASHGETKEY(hashGetKeyNamefreq)
Definition: reader_mps.c:2670
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:3380
#define BLANK
Definition: reader_mps.c:95
static SCIP_OBJSENSE mpsinputObjsense(const MPSINPUT *mpsi)
Definition: reader_mps.c:309
static SCIP_RETCODE readCols(MPSINPUT *mpsi, SCIP *scip, const char ***varnames, int *varnamessize, int *nvarnames)
Definition: reader_mps.c:962
static SCIP_Bool mpsinputReadLine(MPSINPUT *mpsi)
Definition: reader_mps.c:463
static void mpsinputSetObjsense(MPSINPUT *mpsi, SCIP_OBJSENSE sense)
Definition: reader_mps.c:382
static void mpsinputInsertName(MPSINPUT *mpsi, const char *name, SCIP_Bool second)
Definition: reader_mps.c:653
static MPSSECTION mpsinputSection(const MPSINPUT *mpsi)
Definition: reader_mps.c:221
static SCIP_RETCODE addVarNameToStorage(SCIP *scip, const char ***varnames, int *varnamessize, int *nvars, const char *colname)
Definition: reader_mps.c:677
#define READER_DESC
Definition: reader_mps.c:79
static const char * mpsinputField3(const MPSINPUT *mpsi)
Definition: reader_mps.c:265
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:3139
#define MPS_MAX_FIELDLEN
Definition: reader_mps.c:92
static SCIP_DECL_READERCOPY(readerCopyMps)
Definition: reader_mps.c:3719
static SCIP_RETCODE addConsNameToStorage(SCIP *scip, const char ***consnames, int *consnamessize, int *ncons, const char *rowname)
Definition: reader_mps.c:699
static void printColumnSection(SCIP *scip, FILE *file, SPARSEMATRIX *matrix, SCIP_HASHMAP *varnameHashmap, SCIP_HASHTABLE *indicatorSlackHash, unsigned int maxnamelen)
Definition: reader_mps.c:3245
#define MPS_MAX_VALUELEN
Definition: reader_mps.c:91
#define READER_EXTENSION
Definition: reader_mps.c:80
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:2556
static SCIP_DECL_READERREAD(readerReadMps)
Definition: reader_mps.c:3750
static void printRowType(SCIP *scip, FILE *file, SCIP_Real lhs, SCIP_Real rhs, const char *name)
Definition: reader_mps.c:2826
static SCIP_RETCODE readRanges(MPSINPUT *mpsi, SCIP *scip)
Definition: reader_mps.c:1240
static SCIP_RETCODE mpsinputCreate(SCIP *scip, MPSINPUT **mpsi, SCIP_FILE *fp)
Definition: reader_mps.c:173
static unsigned int computeFieldWidth(unsigned int width)
Definition: reader_mps.c:2717
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:3456
static const char * mpsinputField4(const MPSINPUT *mpsi)
Definition: reader_mps.c:276
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:2788
static void printStart(SCIP *scip, FILE *file, const char *col1, const char *col2, int maxnamelen)
Definition: reader_mps.c:2754
static SCIP_RETCODE readIndicators(MPSINPUT *mpsi, SCIP *scip)
Definition: reader_mps.c:2347
#define READER_NAME
Definition: reader_mps.c:78
static SCIP_DECL_HASHKEYVAL(hashKeyValVar)
Definition: reader_mps.c:2708
static void mpsinputSetSection(MPSINPUT *mpsi, MPSSECTION section)
Definition: reader_mps.c:342
static void printRecord(SCIP *scip, FILE *file, const char *col1, const char *col2, unsigned int maxnamelen)
Definition: reader_mps.c:2728
static const char * mpsinputObjname(const MPSINPUT *mpsi)
Definition: reader_mps.c:298
#define DEFAULT_AGGRLINEARIZATION_ANDS
Definition: reader_mps.c:83
static const char * mpsinputField0(const MPSINPUT *mpsi)
Definition: reader_mps.c:232
static void mpsinputSyntaxerror(MPSINPUT *mpsi)
Definition: reader_mps.c:393
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:3018
static SCIP_RETCODE readName(SCIP *scip, MPSINPUT *mpsi)
Definition: reader_mps.c:721
#define MPS_MAX_NAMELEN
Definition: reader_mps.c:90
#define PATCH_CHAR
Definition: reader_mps.c:94
static SCIP_RETCODE readQCMatrix(MPSINPUT *mpsi, SCIP *scip)
Definition: reader_mps.c:2163
static SCIP_RETCODE readBounds(MPSINPUT *mpsi, SCIP *scip)
Definition: reader_mps.c:1380
#define MPS_MAX_LINELEN
Definition: reader_mps.c:89
#define DEFAULT_LINEARIZE_ANDS
Definition: reader_mps.c:82
static void patchField(char *buf, int beg, int end)
Definition: reader_mps.c:442
static void mpsinputFree(SCIP *scip, MPSINPUT **mpsi)
Definition: reader_mps.c:211
(extended) MPS file reader
public methods for constraint handler plugins and constraints
public methods for memory management
public methods for message handling
public methods for numerical tolerances
public methods for SCIP parameter handling
public methods for global and local (sub)problems
public methods for reader plugins
public methods for querying solving statistics
public methods for SCIP variables
const char * consname
Definition: reader_mps.c:166
@ SCIP_BOUNDTYPE_UPPER
Definition: type_lp.h:57
@ SCIP_BOUNDTYPE_LOWER
Definition: type_lp.h:56
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:59
enum SCIP_VerbLevel SCIP_VERBLEVEL
Definition: type_message.h:59
@ SCIP_VERBLEVEL_NORMAL
Definition: type_message.h:55
@ SCIP_VERBLEVEL_FULL
Definition: type_message.h:57
@ 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:53
@ SCIP_SUCCESS
Definition: type_result.h:58
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:61
@ SCIP_NOFILE
Definition: type_retcode.h:47
@ SCIP_READERROR
Definition: type_retcode.h:45
@ SCIP_INVALIDDATA
Definition: type_retcode.h:52
@ SCIP_PLUGINNOTFOUND
Definition: type_retcode.h:54
@ SCIP_OKAY
Definition: type_retcode.h:42
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
@ SCIP_VARTYPE_INTEGER
Definition: type_var.h:63
@ SCIP_VARTYPE_CONTINUOUS
Definition: type_var.h:71
@ SCIP_VARTYPE_IMPLINT
Definition: type_var.h:64
@ SCIP_VARTYPE_BINARY
Definition: type_var.h:62
@ SCIP_VARSTATUS_FIXED
Definition: type_var.h:52
@ SCIP_VARSTATUS_MULTAGGR
Definition: type_var.h:54
@ SCIP_VARSTATUS_NEGATED
Definition: type_var.h:55
@ SCIP_VARSTATUS_AGGREGATED
Definition: type_var.h:53
@ SCIP_LOCKTYPE_MODEL
Definition: type_var.h:97
enum SCIP_Vartype SCIP_VARTYPE
Definition: type_var.h:73
enum SCIP_Varstatus SCIP_VARSTATUS
Definition: type_var.h:57