SCIP Doxygen Documentation
 
Loading...
Searching...
No Matches
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-2023 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 */
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);
419 assert(entity != 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;
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 */
538 SCIP_Bool number;
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. */
732 {
734 return SCIP_OKAY;
735 }
736
737 /* Sometimes the name is omitted. */
739
740 /* This hat to be a new section */
741 /* coverity[tainted_data] */
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. */
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] */
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. */
839 {
841 return SCIP_OKAY;
842 }
843
845
846 /* Look for ROWS, USERCUTS, or LAZYCONS Section */
847 /* coverity[tainted_data] */
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
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' :
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 {
993 }
994 assert(var == NULL);
995
997 return SCIP_OKAY;
998 }
1000 break;
1001
1002 /* new column? */
1004 {
1005 /* add the last variable to the problem */
1006 if( var != NULL )
1007 {
1010 }
1011 assert(var == NULL);
1012
1014
1015 /* check whether we have seen this variable before, this would not allowed */
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 */
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
1045 {
1046 SCIP_CALL( SCIPchgVarObj(scip, var, val) );
1047 }
1048 else
1049 {
1051 if( cons == NULL )
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 {
1067
1068 val = atof(mpsinputField5(mpsi));
1069
1071 {
1072 SCIP_CALL( SCIPchgVarObj(scip, var, val) );
1073 }
1074 else
1075 {
1077 if( cons == NULL )
1079 else if( !SCIPisZero(scip, val) )
1080 {
1081 SCIP_CALL( SCIPaddCoefLinear(scip, cons, var, val) );
1082 }
1083 }
1084 }
1085 }
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 }
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
1139 break;
1140
1141 if( *rhsname == '\0' )
1143
1145 {
1147 if( cons == NULL )
1148 {
1149 /* the rhs of the objective row is treated as objective constant */
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 {
1190 if( cons == NULL )
1191 {
1192 /* the rhs of the objective row is treated as objective constant */
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 }
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 }
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
1284 break;
1285
1286 if( *rngname == '\0' )
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 */
1299 {
1301 if( cons == NULL )
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 {
1337 if( cons == NULL )
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 }
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
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 {
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 {
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 {
1480 return SCIP_OKAY;
1481 }
1482
1484 break;
1485
1486 if( *bndname == '\0' )
1488
1489 /* Only read the first Bound in section */
1491 {
1493 SCIP_Bool infeasible;
1494
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 {
1501
1503 SCIP_VARTYPE_CONTINUOUS, !mpsi->dynamiccols, mpsi->dynamiccols, NULL, NULL, NULL, NULL, NULL) );
1504
1506 varcpy = var;
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 */
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 {
1530 assert(!infeasible);
1531
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 */
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 }
1564 /* don't assert feasibility here because the presolver will and should detect a infeasibility */
1565 }
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
1590 /* don't assert feasibility here because the presolver will and should detect an infeasibility */
1591 }
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 {
1606 if( semicont == NULL )
1607 {
1609 }
1610 else
1611 {
1613 }
1614 }
1615 assert(semicont != NULL);
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 {
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) );
1658 /* don't assert feasibility here because the presolver will and should detect a infeasibility */
1659 break;
1660 default:
1662 return SCIP_OKAY;
1663 }
1664
1665 /* switch variable type back to old type if necessary */
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 {
1678 return SCIP_OKAY;
1679 }
1680
1682 }
1683 }
1685
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
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
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");
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 )
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");
1869 return SCIP_OKAY;
1870 }
1871
1872 /* get variable */
1874 if( var == NULL )
1875 {
1876 /* ignore unknown variables - we would not know the type anyway */
1878 }
1879 else
1880 {
1881 /* get weight */
1882 if( NULL == mpsinputField2(mpsi) )
1883 {
1884 SCIPerrorMessage("weight for variable <%s> not specified.\n", mpsinputField1(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));
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",
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{
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;
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 }
1993 {
1994 SCIPerrorMessage("empty data in a non-comment line.\n");
1999 return SCIP_OKAY;
2000 }
2001
2002 /* get first variable */
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 */
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 */
2028 if( NULL == field )
2029 {
2030 SCIPerrorMessage("coefficient of term <%s>*<%s> not specified.\n", SCIPvarGetName(var1), SCIPvarGetName(var2));
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));
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);
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;
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
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) );
2138 }
2139 }
2140 else
2141 {
2142 SCIPwarningMessage(scip, "%s section has no entries.\n", isQuadObj ? "QUADOBJ" : "QMATRIX");
2143 }
2144
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 */
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");
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));
2192 return SCIP_OKAY;
2193 }
2194
2195 size = 1;
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 }
2225 {
2226 SCIPerrorMessage("empty data in a non-comment line.\n");
2228
2229 goto TERMINATE;
2230 }
2231
2232 /* get first variable */
2234 if( var1 == NULL )
2235 {
2236 /* ignore unknown variables - we would not know the type anyway */
2238 }
2239 else
2240 {
2241 /* get second variable */
2243 if( var2 == NULL )
2244 {
2245 /* ignore unknown variables - we would not know the type anyway */
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));
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));
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);
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),
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:
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;
2381 SCIP_CONS* cons;
2382 SCIP_CONS* lincons;
2383 SCIP_VAR* binvar;
2384 SCIP_VAR* slackvar;
2385 SCIP_Real lhs;
2386 SCIP_Real rhs;
2387 SCIP_Real sign;
2388 SCIP_VAR** linvars;
2389 SCIP_Real* linvals;
2390 int nlinvars;
2391 int i;
2392
2393 /* check if next section is found */
2394 if( mpsinputField0(mpsi) != NULL )
2395 {
2396 if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
2398 break;
2399 }
2401 {
2402 SCIPerrorMessage("empty data in a non-comment line.\n");
2404 return SCIP_OKAY;
2405 }
2406
2407 /* check for new indicator constraint */
2408 if( strcmp(mpsinputField1(mpsi), "IF") != 0 )
2409 {
2410 SCIPerrorMessage("Indicator constraints need to be introduced by 'IF' in column 1.\n");
2412 return SCIP_OKAY;
2413 }
2414
2415 /* get linear constraint (row) */
2416 lincons = SCIPfindCons(scip, mpsinputField2(mpsi));
2417 if( lincons == NULL )
2418 {
2419 SCIPerrorMessage("row <%s> does not exist.\n", mpsinputField2(mpsi));
2421 return SCIP_OKAY;
2422 }
2423
2424 /* check whether constraint is really linear */
2425 conshdlr = SCIPconsGetHdlr(lincons);
2426 if( strcmp(SCIPconshdlrGetName(conshdlr), "linear") != 0 )
2427 {
2428 SCIPerrorMessage("constraint <%s> is not linear.\n", mpsinputField2(mpsi));
2430 return SCIP_OKAY;
2431 }
2432
2433 /* get binary variable */
2434 binvar = SCIPfindVar(scip, mpsinputField3(mpsi));
2435 if( binvar == NULL )
2436 {
2437 SCIPerrorMessage("binary variable <%s> does not exist.\n", mpsinputField3(mpsi));
2439 return SCIP_OKAY;
2440 }
2441
2442 /* check type */
2443 if( SCIPvarGetType(binvar) != SCIP_VARTYPE_BINARY )
2444 {
2445 SCIPerrorMessage("variable <%s> is not binary.\n", mpsinputField3(mpsi));
2447 return SCIP_OKAY;
2448 }
2449
2450 /* check whether we need the negated variable */
2451 if( mpsinputField4(mpsi) != NULL )
2452 {
2453 if( *mpsinputField4(mpsi) == '0' )
2454 {
2455 SCIP_VAR* var;
2456 SCIP_CALL( SCIPgetNegatedVar(scip, binvar, &var) );
2457 binvar = var;
2458 assert( binvar != NULL );
2459 }
2460 else
2461 {
2462 if( *mpsinputField4(mpsi) != '1' )
2463 {
2464 SCIPerrorMessage("binary variable <%s> can only take values 0/1 (%s).\n", mpsinputField3(mpsi), mpsinputField4(mpsi));
2466 return SCIP_OKAY;
2467 }
2468 }
2469 }
2470
2471 /* check lhs/rhs */
2472 lhs = SCIPgetLhsLinear(scip, lincons);
2473 rhs = SCIPgetRhsLinear(scip, lincons);
2474 nlinvars = SCIPgetNVarsLinear(scip, lincons);
2475 linvars = SCIPgetVarsLinear(scip, lincons);
2476 linvals = SCIPgetValsLinear(scip, lincons);
2477
2478 sign = -1.0;
2479 if( !SCIPisInfinity(scip, -lhs) )
2480 {
2481 if( SCIPisInfinity(scip, rhs) )
2482 sign = 1.0;
2483 else
2484 {
2485 /* create second indicator constraint */
2486 SCIP_VAR** vars;
2487 SCIP_Real* vals;
2488 SCIP_RETCODE retcode;
2489
2490 SCIP_CALL( SCIPallocBufferArray(scip, &vars, nlinvars) );
2491 SCIP_CALL( SCIPallocBufferArray(scip, &vals, nlinvars) );
2492 for( i = 0; i < nlinvars; ++i )
2493 {
2494 vars[i] = linvars[i];
2495 vals[i] = -linvals[i];
2496 }
2497
2498 /* create new name */
2499 (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "indlhs_%s", SCIPconsGetName(lincons));
2500
2501 /* create indicator constraint */
2502 retcode = SCIPcreateConsIndicator(scip, &cons, name, binvar, nlinvars, vars, vals, -lhs,
2503 initial, separate, enforce, check, propagate, local, dynamic, removable, stickingatnode);
2504
2505 if( retcode == SCIP_OKAY )
2506 {
2507 SCIP_CALL( SCIPaddCons(scip, cons) );
2508 SCIPdebugMsg(scip, "created indicator constraint <%s>\n", mpsinputField2(mpsi));
2510 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
2511 }
2512
2513 SCIPfreeBufferArray(scip, &vals);
2515
2516 SCIP_CALL( retcode );
2517 }
2518 }
2519
2520 /* check if slack variable can be made implicitly integer */
2522 for (i = 0; i < nlinvars; ++i)
2523 {
2524 if( ! SCIPvarIsIntegral(linvars[i]) || ! SCIPisIntegral(scip, linvals[i]) )
2525 {
2527 break;
2528 }
2529 }
2530
2531 /* create slack variable */
2532 if ( ! SCIPisInfinity(scip, -lhs) )
2533 (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "indslack_indrhs_%s", SCIPconsGetName(lincons));
2534 else
2535 (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "indslack_%s", SCIPconsGetName(lincons));
2536 SCIP_CALL( SCIPcreateVar(scip, &slackvar, name, 0.0, SCIPinfinity(scip), 0.0, slackvartype, TRUE, FALSE,
2537 NULL, NULL, NULL, NULL, NULL) );
2538
2539 /* add slack variable */
2540 SCIP_CALL( SCIPaddVar(scip, slackvar) );
2541 SCIP_CALL( SCIPaddCoefLinear(scip, lincons, slackvar, sign) );
2542
2543 /* correct linear constraint and create new name */
2544 if ( ! SCIPisInfinity(scip, -lhs) && ! SCIPisInfinity(scip, rhs) )
2545 {
2546 /* we have added lhs above and only need the rhs */
2548 (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "indrhs_%s", SCIPconsGetName(lincons));
2549 }
2550 else
2551 (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "ind_%s", SCIPconsGetName(lincons));
2552
2553 /* create indicator constraint */
2554 SCIP_CALL( SCIPcreateConsIndicatorLinCons(scip, &cons, name, binvar, lincons, slackvar,
2555 initial, separate, enforce, check, propagate, local, dynamic, removable, stickingatnode) );
2556
2557 SCIP_CALL( SCIPaddCons(scip, cons) );
2558 SCIPdebugMsg(scip, "created indicator constraint <%s>", mpsinputField2(mpsi));
2560 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
2561 SCIP_CALL( SCIPreleaseVar(scip, &slackvar) );
2562 }
2563
2564 return SCIP_OKAY;
2565}
2566
2567
2568/** Read LP in "MPS File Format".
2569 *
2570 * A specification of the MPS format can be found at
2571 *
2572 * http://plato.asu.edu/ftp/mps_format.txt,
2573 * ftp://ftp.caam.rice.edu/pub/people/bixby/miplib/mps_format,
2574 *
2575 * and in the
2576 *
2577 * CPLEX Reference Manual
2578 *
2579 * This routine should read all valid MPS format files.
2580 * What it will not do, is to find all cases where a file is ill formed.
2581 * If this happens it may complain and read nothing or read "something".
2582 */
2583static
2585 SCIP* scip, /**< SCIP data structure */
2586 const char* filename, /**< name of the input file */
2587 const char*** varnames, /**< storage for the variable names, or NULL */
2588 const char*** consnames, /**< storage for the constraint names, or NULL */
2589 int* varnamessize, /**< the size of the variable names storage, or NULL */
2590 int* consnamessize, /**< the size of the constraint names storage, or NULL */
2591 int* nvarnames, /**< the number of stored variable names, or NULL */
2592 int* nconsnames /**< the number of stored constraint names, or NULL */
2593 )
2594{
2595 SCIP_FILE* fp;
2596 MPSINPUT* mpsi;
2597 SCIP_RETCODE retcode;
2598 SCIP_Bool error = TRUE;
2599
2600 assert(scip != NULL);
2601 assert(filename != NULL);
2602
2603 fp = SCIPfopen(filename, "r");
2604 if( fp == NULL )
2605 {
2606 SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
2607 SCIPprintSysError(filename);
2608 return SCIP_NOFILE;
2609 }
2610
2612
2614
2616
2618 {
2620 }
2622 {
2624 }
2625 while( mpsinputSection(mpsi) == MPS_ROWS
2628 {
2629 SCIP_CALL_TERMINATE( retcode, readRows(mpsi, scip, consnames, consnamessize, nconsnames), TERMINATE );
2630 }
2632 {
2633 SCIP_CALL_TERMINATE( retcode, readCols(mpsi, scip, varnames, varnamessize, nvarnames), TERMINATE );
2634 }
2635 if( mpsinputSection(mpsi) == MPS_RHS )
2636 {
2638 }
2640 {
2642 }
2644 {
2646 }
2647 if( mpsinputSection(mpsi) == MPS_SOS )
2648 {
2650 }
2651 while( mpsinputSection(mpsi) == MPS_QCMATRIX )
2652 {
2654 }
2656 {
2658 }
2660 {
2662 }
2663 while( mpsinputSection(mpsi) == MPS_QCMATRIX )
2664 {
2666 }
2668 {
2670 }
2673
2674 SCIPfclose(fp);
2675
2677
2678 if( !error )
2679 {
2681 }
2682
2683 TERMINATE:
2685
2686 if( error )
2687 return SCIP_READERROR;
2688 else
2689 return SCIP_OKAY;
2690}
2691
2692/*
2693 * local methods for writing problem
2694 */
2695
2696/** gets the key (i.e. the name) of the given namefreq */
2697static
2699{ /*lint --e{715}*/
2701
2703 assert(consnamefreq->consname != NULL);
2704
2705 return (void*)consnamefreq->consname;
2706}
2707
2708/** returns TRUE iff both keys (i.e. strings) are equal up to max length*/
2709static
2711{ /*lint --e{715}*/
2712 const char* string1 = (const char*)key1;
2713 const char* string2 = (const char*)key2;
2714
2715 return (strncmp(string1, string2, MPS_MAX_NAMELEN - 1) == 0);
2716}
2717
2718/** hash key retrieval function for variables */
2719static
2721{ /*lint --e{715}*/
2722 return elem;
2723}
2724
2725/** returns TRUE iff the indices of both variables are equal */
2726static
2728{ /*lint --e{715}*/
2729 if( key1 == key2 )
2730 return TRUE;
2731 return FALSE;
2732}
2733
2734/** returns the hash value of the key */
2735static
2737{ /*lint --e{715}*/
2738 assert( SCIPvarGetIndex((SCIP_VAR*) key) >= 0 );
2739 return (unsigned int) SCIPvarGetIndex((SCIP_VAR*) key);
2740}
2741
2742
2743/** computes the field width such that the output file is nicely arranged */
2744static
2746 unsigned int width /**< required width */
2747 )
2748{
2749 width = MAX(8u, width);
2750 return MIN(MPS_MAX_FIELDLEN, width);
2751}
2752
2753
2754/** output two strings in columns 1 and 2 with computed widths */
2755static
2757 SCIP* scip, /**< SCIP data structure */
2758 FILE* file, /**< output file (or NULL for standard output) */
2759 const char* col1, /**< column 1 */
2760 const char* col2, /**< column 2 */
2761 unsigned int maxnamelen /**< maximum name length */
2762 )
2763{
2764 unsigned int fieldwidth;
2765 char format[32];
2766
2767 assert( scip != NULL );
2768 assert( col1 != NULL );
2769 assert( col2 != NULL );
2772 assert( maxnamelen > 0 );
2773
2775 (void) SCIPsnprintf(format, 32," %%-%ds %%%ds ", fieldwidth, MPS_MAX_VALUELEN - 1);
2776
2777 SCIPinfoMessage(scip, file, (const char *)format, col1, col2);
2778}
2779
2780/** output two strings in columns 1 (width 2) and 2 (width 8) */
2781static
2783 SCIP* scip, /**< SCIP data structure */
2784 FILE* file, /**< output file (or NULL for standard output) */
2785 const char* col1, /**< column 1 */
2786 const char* col2, /**< column 2 */
2787 int maxnamelen /**< maximum name length (-1 if irrelevant) */
2788 )
2789{
2790 unsigned int fieldwidth;
2791 char format[32];
2792
2793 assert( scip != NULL );
2794 assert( col1 != NULL );
2795 assert( col2 != NULL );
2796 assert( strlen(col1) <= 2 );
2798 assert( maxnamelen == -1 || maxnamelen > 0 );
2799
2800 if( maxnamelen < 0 )
2801 {
2802 /* format does not matter */
2803 (void) SCIPsnprintf(format, 32, " %%-2.2s %%-s ");
2804 }
2805 else
2806 {
2807 fieldwidth = computeFieldWidth((unsigned int) maxnamelen);
2808 (void) SCIPsnprintf(format, 32, " %%-2.2s %%-%ds ", fieldwidth);
2809 }
2810
2811 SCIPinfoMessage(scip, file, (const char*)format, col1, col2);
2812}
2813
2814/** prints the given data as column entry */
2815static
2817 SCIP* scip, /**< SCIP data structure */
2818 FILE* file, /**< output file (or NULL for standard output) */
2819 const char* varname, /**< variable name */
2820 const char* consname, /**< constraint name */
2821 SCIP_Real value, /**< value to display */
2822 int* recordcnt, /**< pointer to store the number of records per line */
2823 unsigned int maxnamelen /**< maximum name length */
2824 )
2825{
2826 char valuestr[MPS_MAX_VALUELEN] = { '\0' };
2827
2828 assert( scip != NULL );
2829 assert( recordcnt != NULL );
2830 assert( *recordcnt >= 0 && *recordcnt < 2 );
2831
2832 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", value);
2833
2834 if( *recordcnt == 0 )
2835 {
2836 /* start new line with an empty first column and the variable name in the second column */
2837 printStart(scip, file, "", varname, (int) maxnamelen);
2838 *recordcnt = 0;
2839 }
2840
2842 (*recordcnt)++;
2843
2844 if( *recordcnt == 2 )
2845 {
2846 /* each line can have at most two records */
2847 SCIPinfoMessage(scip, file, "\n");
2848 *recordcnt = 0;
2849 }
2850}
2851
2852/** prints the constraint type to file stream */
2853static
2855 SCIP* scip, /**< SCIP data structure */
2856 FILE* file, /**< output file (or NULL for standard output) */
2857 SCIP_Real lhs, /**< left hand side */
2858 SCIP_Real rhs, /**< right hand side */
2859 const char* name /**< constraint name */
2860 )
2861{
2862 char rowtype[2];
2863
2864 assert( scip != NULL );
2865 assert( !SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs) );
2866 assert( SCIPisGT(scip, rhs, lhs) || SCIPisEQ(scip, lhs, rhs) );
2867 assert( name != NULL );
2868
2869 if( SCIPisEQ(scip, lhs, rhs) )
2870 (void) SCIPsnprintf(rowtype, 2, "%s", "E");
2871 else
2872 {
2873 /* in case the right hand side and the left hand side are not infinity we print a
2874 * less or equal constraint and put the right hand side in the RHS section and the
2875 * left hand side (hidden) in the RANGE section */
2876 if( !SCIPisInfinity(scip, rhs) )
2877 (void) SCIPsnprintf(rowtype, 2, "%s", "L");
2878 else
2879 {
2880 assert( !SCIPisInfinity(scip, -lhs) );
2881 (void) SCIPsnprintf(rowtype, 2, "%s", "G");
2882 }
2883 }
2884
2885 printStart(scip, file, rowtype, name, -1);
2886 SCIPinfoMessage(scip, file, "\n");
2887}
2888
2889
2890/** initializes the sparse matrix */
2891static
2893 SCIP* scip, /**< SCIP data structure */
2894 SPARSEMATRIX** matrix, /**< pointer to sparse matrix containing the entries */
2895 int slots /**< number of slots */
2896 )
2897{
2898 SCIP_CALL( SCIPallocBuffer(scip, matrix) );
2899 (*matrix)->nentries = 0;
2900 (*matrix)->sentries = slots;
2901 SCIP_CALL( SCIPallocBufferArray(scip, &(*matrix)->values, (*matrix)->sentries) );
2902 SCIP_CALL( SCIPallocBufferArray(scip, &(*matrix)->columns, (*matrix)->sentries) );
2903 SCIP_CALL( SCIPallocBufferArray(scip, &(*matrix)->rows, (*matrix)->sentries) );
2904
2905 return SCIP_OKAY;
2906}
2907
2908/** this method takes care that the required capacity is available in the sparse matrix */
2909static
2911 SCIP* scip, /**< SCIP data structure */
2912 SPARSEMATRIX* matrix, /**< sparse matrix for storing the coefficient */
2913 int capacity /**< needed capacity */
2914 )
2915{
2916 if( matrix->nentries + capacity >= matrix->sentries )
2917 {
2918 matrix->sentries = matrix->sentries * 2 + capacity;
2919 SCIP_CALL( SCIPreallocBufferArray(scip, &matrix->values, matrix->sentries) );
2920 SCIP_CALL( SCIPreallocBufferArray(scip, &matrix->columns, matrix->sentries) );
2921 SCIP_CALL( SCIPreallocBufferArray(scip, &matrix->rows, matrix->sentries) );
2922 }
2923 return SCIP_OKAY;
2924}
2925
2926/** frees the sparse matrix */
2927static
2929 SCIP* scip, /**< SCIP data structure */
2930 SPARSEMATRIX* matrix /**< sparse matrix to free */
2931 )
2932{
2933 SCIPfreeBufferArray(scip, &matrix->rows);
2934 SCIPfreeBufferArray(scip, &matrix->columns);
2935 SCIPfreeBufferArray(scip, &matrix->values);
2936
2937 SCIPfreeBuffer(scip, &matrix);
2938}
2939
2940
2941/** computes the coefficient for the given variables and linear constraint information */
2942static
2944 SCIP* scip, /**< SCIP data structure */
2945 const char* consname, /**< name of the constraint */
2946 SCIP_VAR** vars, /**< array of variables */
2947 SCIP_Real* vals, /**< array of coefficients values (or NULL if all coefficient values are 1) */
2948 int nvars, /**< number of variables */
2949 SCIP_Bool transformed, /**< transformed constraint? */
2950 SPARSEMATRIX* matrix, /**< sparse matrix for storing the coefficient */
2951 SCIP_Real* rhs /**< pointer to right hand side */
2952 )
2953{
2955 SCIP_Real* activevals;
2956 SCIP_Real activeconstant = 0.0;
2957
2958 int nactivevars;
2959 int requiredsize;
2960 int v;
2961
2962 assert( scip != NULL );
2963 assert( nvars == 0 || vars != NULL );
2964 assert( !SCIPisInfinity(scip, *rhs) );
2965 assert( matrix != NULL );
2966
2967 /* if the variables array contains no variables, then return without
2968 * doing any thing; The MPS format and LP format do not forbid this
2969 * situation */
2970 if( nvars == 0 )
2971 return SCIP_OKAY;
2972
2973 /* duplicate variable and value array */
2976
2977 if( vals != NULL )
2978 {
2980 }
2981 else
2982 {
2984
2985 for( v = 0; v < nactivevars; ++v )
2986 activevals[v] = 1.0;
2987 }
2988
2989 /* retransform given variables to active variables */
2990 if( transformed )
2991 {
2993
2995 {
2998
3001 }
3002 }
3003 else
3004 {
3005 for( v = 0; v < nactivevars; ++v )
3006 {
3008
3009 /* negated variables with an original counterpart may also be returned by SCIPvarGetOrigvarSum();
3010 * make sure we get the original variable in that case
3011 */
3013 {
3016 activevals[v] *= -1.0;
3017 }
3018 }
3019 }
3020
3021 /* copy the (matrix) row into the sparse matrix */
3023 assert( matrix->nentries + nactivevars < matrix->sentries );
3024
3025 for( v = 0; v < nactivevars; ++v )
3026 {
3027 matrix->values[matrix->nentries] = activevals[v];
3028 matrix->columns[matrix->nentries] = activevars[v];
3029 matrix->rows[matrix->nentries] = consname;
3030 matrix->nentries++;
3031 }
3032
3033 /* adjust right hand side */
3034 (*rhs) -= activeconstant;
3035
3036 /* free buffer arrays */
3039
3040 return SCIP_OKAY;
3041}
3042
3043
3044/** check whether given variables are aggregated and put them into an array without duplication */
3045static
3047 SCIP* scip, /**< SCIP data structure */
3048 SCIP_VAR** vars, /**< variable array */
3049 int nvars, /**< number of active variables in the problem */
3050 SCIP_VAR*** aggvars, /**< pointer to array storing the aggregated variables on output */
3051 int* naggvars, /**< pointer to number of aggregated variables on output */
3052 int* saggvars, /**< pointer to number of slots in aggvars array */
3053 SCIP_HASHTABLE* varAggregated /**< hashtable for checking duplicates */
3054 )
3055{
3056 int v;
3057
3058 assert( scip != NULL );
3059 assert( aggvars != NULL );
3060 assert( naggvars != NULL );
3061 assert( saggvars != NULL );
3062
3063 /* check variables */
3064 for( v = 0; v < nvars; ++v )
3065 {
3066 SCIP_VARSTATUS status;
3067 SCIP_VAR* var;
3068
3069 var = vars[v];
3070 status = SCIPvarGetStatus(var);
3071
3072 /* collect aggregated variables in a list */
3073 if( status >= SCIP_VARSTATUS_AGGREGATED )
3074 {
3077
3078 if( ! SCIPhashtableExists(varAggregated, (void*) var) )
3079 {
3080 /* possibly enlarge array */
3081 if ( *saggvars <= *naggvars )
3082 {
3083 int newsize;
3085 assert( newsize > *saggvars );
3087 *saggvars = newsize;
3088 }
3089
3090 (*aggvars)[*naggvars] = var;
3091 (*naggvars)++;
3093 assert( *naggvars <= *saggvars );
3094 }
3095 }
3096 }
3097 return SCIP_OKAY;
3098}
3099
3100
3101/** method check if the variable names are not longer than MPS_MAX_NAMELEN - 1*/
3102static
3104 SCIP* scip, /**< SCIP data structure */
3105 SCIP_VAR** vars, /**< array of variables */
3106 int nvars, /**< number of variables */
3107 unsigned int* maxnamelen, /**< pointer to store the maximum name length */
3108 const char*** varnames, /**< pointer to array of variable names */
3109 SCIP_HASHMAP** varnameHashmap /**< pointer to hash map storing variable, variable name mapping */
3110 )
3111{
3112 int v;
3113 int faulty;
3114 char* varname;
3115 SCIP_VAR* var;
3116
3117 assert( scip != NULL );
3118 assert( vars != NULL );
3119 assert( maxnamelen != NULL );
3120
3121 faulty = 0;
3122
3123 /* allocate memory */
3126
3127 /* check if the variable names are not to long */
3128 for( v = 0; v < nvars; ++v )
3129 {
3130 size_t l;
3131
3132 var = vars[v];
3133 assert( var != NULL );
3134
3136
3137 if( l >= MPS_MAX_NAMELEN )
3138 {
3139 faulty++;
3140 (*maxnamelen) = MPS_MAX_NAMELEN - 1;
3141 }
3142 else
3143 {
3144 (*maxnamelen) = MAX(*maxnamelen, (unsigned int) l);
3145 }
3146
3148 (void) SCIPsnprintf(varname, (int)(*maxnamelen) + 1, "%s", SCIPvarGetName(var) );
3149
3150 /* insert variable with variable name into hash map */
3153
3154 (*varnames)[v] = varname;
3155 }
3156
3157 if( faulty > 0 )
3158 {
3159 SCIPwarningMessage(scip, "there are %d variable names which have to be cut down to %d characters; LP might be corrupted\n",
3160 faulty, MPS_MAX_NAMELEN - 1);
3161 }
3162 return SCIP_OKAY;
3163}
3164
3165/** method check if the constraint names are not longer than MPS_MAX_NAMELEN - 1 */
3166static
3168 SCIP* scip, /**< SCIP data structure */
3169 SCIP_CONS** conss, /**< array of all constraints */
3170 int nconss, /**< number of all constraints */
3171 SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
3172 unsigned int* maxnamelen, /**< pointer to store the maximum name length */
3173 const char*** consnames, /**< pointer to array of constraint names */
3174 SCIP_Bool* error /**< pointer to store whether all constraint names exist */
3175 )
3176{
3179 SCIP_CONS* cons;
3180 char* consname;
3181 int i;
3182
3183 assert(scip != NULL);
3185
3186 *error = FALSE;
3187
3188 /* allocate memory */
3190 SCIP_CALL( SCIPallocBufferArray(scip, consnames, nconss) );
3193
3194 for( i = 0; i < nconss; ++i )
3195 {
3197 size_t l;
3198 int freq;
3199
3200 cons = conss[i];
3201 assert( cons != NULL );
3202
3203 /* in case the transformed problem is written, only constraints are posted which are enabled in the current node */
3204 assert(!transformed || SCIPconsIsEnabled(cons));
3205
3206 l = strlen(SCIPconsGetName(cons));
3207
3208 if( l == 0 )
3209 {
3210 SCIPwarningMessage(scip, "At least one name of a constraint is empty, so file will be written with generic names.\n");
3211 *error = TRUE;
3212
3213 goto TERMINATE;
3214 }
3215
3216 consnamefreqs[i].consname = SCIPconsGetName(cons);
3217 consnamefreqs[i].freq = 0;
3218 freq = 0;
3219
3220 /* check for duplicate names */
3222 {
3223 consnamefreq->freq += 1;
3225 freq = consnamefreq->freq;
3226 }
3228
3229 /* the new length is the length of the old name + a '_' and the freq number which has floor(log10(freq)) + 1 characters */
3230 if( freq > 0 )
3231 l = l + 1 + (size_t)log10((SCIP_Real) freq) + 1;
3232
3233 if( l >= MPS_MAX_NAMELEN )
3234 {
3235 SCIPwarningMessage(scip, "Constraints have duplicate name and are too long to fix, so file will be written with generic names.\n");
3236 *error = TRUE;
3237
3238 goto TERMINATE;
3239 }
3240
3241 (*maxnamelen) = MAX(*maxnamelen, (unsigned int) l);
3242
3243 SCIP_CALL( SCIPallocBufferArray(scip, &consname, (int) l + 1) );
3244 if( freq > 0 )
3245 (void) SCIPsnprintf(consname, (int)l + 1, "%s_%d", SCIPconsGetName(cons), freq);
3246 else
3247 (void) SCIPsnprintf(consname, (int)l + 1, "%s", SCIPconsGetName(cons));
3248
3249 (*consnames)[i] = consname;
3250 }
3251
3252TERMINATE:
3254
3255 if( *error )
3256 {
3257 --i; /*lint !e445*/
3258 for( ; i >= 0; --i) /*lint !e445*/
3259 {
3260 SCIPfreeBufferArray(scip, &((*consnames)[i]));
3261 }
3262 SCIPfreeBufferArray(scip, consnames);
3263 }
3264
3266
3267 return SCIP_OKAY;
3268}
3269
3270
3271/** outputs the COLUMNS section of the MPS format */
3272static
3274 SCIP* scip, /**< SCIP data structure */
3275 FILE* file, /**< output file, or NULL if standard output should be used */
3276 SPARSEMATRIX* matrix, /**< sparse matrix containing the entries */
3277 SCIP_HASHMAP* varnameHashmap, /**< map from SCIP_VAR* to variable name */
3278 SCIP_HASHTABLE* indicatorSlackHash, /**< hashtable containing slack variables from indicators (or NULL) */
3279 unsigned int maxnamelen /**< maximum name length */
3280 )
3281{
3282 SCIP_Bool intSection;
3283 SCIP_VAR* var;
3284 const char* varname;
3285 SCIP_Real value;
3286 int v;
3287 int recordcnt;
3288
3289 /* sort sparse matrix w.r.t. the variable indices */
3290 SCIPsortPtrPtrReal((void**) matrix->columns, (void**) matrix->rows, matrix->values, SCIPvarComp, matrix->nentries);
3291
3292 /* print COLUMNS section */
3293 SCIPinfoMessage(scip, file, "COLUMNS\n");
3294
3295 intSection = FALSE;
3296
3297 for( v = 0; v < matrix->nentries; )
3298 {
3299 var = matrix->columns[v];
3300 assert( var != NULL );
3301
3302 /* skip slack variables in output */
3304 {
3305 ++v;
3306 continue;
3307 }
3308
3310 {
3311 /* end integer section in MPS format */
3312 printStart(scip, file, "", "INTEND", (int) maxnamelen);
3313 printRecord(scip, file, "'MARKER'", "", maxnamelen);
3314 printRecord(scip, file, "'INTEND'", "", maxnamelen);
3315 SCIPinfoMessage(scip, file, "\n");
3316 intSection = FALSE;
3317 }
3319 {
3320 /* start integer section in MPS format */
3321 printStart(scip, file, "", "INTSTART", (int) maxnamelen);
3322 printRecord(scip, file, "'MARKER'", "", maxnamelen);
3323 printRecord(scip, file, "'INTORG'", "", maxnamelen);
3324 SCIPinfoMessage(scip, file, "\n");
3325 intSection = TRUE;
3326 }
3327
3328 SCIPdebugMsg(scip, "create entries for variable <%s>\n", SCIPvarGetName(var));
3329
3330 /* record count; there are at most two records per line */
3331 recordcnt = 0;
3332
3333 /* get variable name */
3336
3337 /* output all entries of the same variable */
3338 do
3339 {
3340 value = matrix->values[v];
3341
3342 /* print record to file */
3343 printEntry(scip, file, varname, matrix->rows[v], value, &recordcnt, maxnamelen);
3344 v++;
3345 }
3346 while( v < matrix->nentries && var == matrix->columns[v] );
3347
3348 if( recordcnt == 1 )
3349 SCIPinfoMessage(scip, file, "\n");
3350 }
3351 /* end integer section, if the columns sections ends with integer variables */
3352 if( intSection )
3353 {
3354 /* end integer section in MPS format */
3355 printStart(scip, file, "", "INTEND", (int) maxnamelen);
3356 printRecord(scip, file, "'MARKER'", "", maxnamelen);
3357 printRecord(scip, file, "'INTEND'", "", maxnamelen);
3358 SCIPinfoMessage(scip, file, "\n");
3359 }
3360}
3361
3362
3363/** outputs the right hand side section */
3364static
3366 SCIP* scip, /**< SCIP data structure */
3367 FILE* file, /**< output file, or NULL if standard output should be used */
3368 int nconss, /**< number of constraints */
3369 const char** consnames, /**< constraint names */
3370 SCIP_Real* rhss, /**< right hand side array */
3371 unsigned int maxnamelen, /**< maximum name length */
3372 SCIP_Real objoffset /**< objective offset */
3373 )
3374{
3375 int recordcnt = 0;
3376 int c;
3377
3378 assert( rhss != NULL );
3379
3380 SCIPinfoMessage(scip, file, "RHS\n");
3381 SCIPdebugMsg(scip, "start printing RHS section\n");
3382
3383 /* take care of the linear constraints */
3384 for( c = 0; c < nconss; ++c )
3385 {
3386 /* skip all constraints which have a right hand side of infinity */
3387 if( SCIPisInfinity(scip, rhss[c]) )
3388 continue;
3389
3390 assert(consnames[c] != NULL);
3391
3392 printEntry(scip, file, "RHS", consnames[c], rhss[c], &recordcnt, maxnamelen);
3393 }
3394
3395 if( ! SCIPisZero(scip, objoffset) )
3396 {
3397 /* write objective offset (-1 because it is moved to the rhs) */
3398 printEntry(scip, file, "RHS", "Obj", -objoffset, &recordcnt, maxnamelen);
3399 }
3400
3401 if( recordcnt == 1 )
3402 SCIPinfoMessage(scip, file, "\n");
3403}
3404
3405
3406/** outputs the range section */
3407static
3409 SCIP* scip, /**< SCIP data structure */
3410 FILE* file, /**< output file, or NULL if standard output should be used */
3411 SCIP_CONS** conss, /**< constraint array */
3412 int nconss, /**< number of constraints */
3413 const char** consnames, /**< constraint names */
3414 SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
3415 unsigned int maxnamelen /**< maximum name length */
3416 )
3417{
3418 int c;
3419 int recordcnt = 0;
3420
3421 SCIP_CONSHDLR* conshdlr;
3422 const char* conshdlrname;
3423
3424 SCIP_CONS* cons;
3425 SCIP_Real lhs;
3426 SCIP_Real rhs;
3427
3428 SCIPinfoMessage(scip, file, "RANGES\n");
3429 SCIPdebugMsg(scip, "start printing RANGES section\n");
3430
3431 for( c = 0; c < nconss; ++c )
3432 {
3433 cons = conss[c];
3434 assert( cons != NULL);
3435
3436 /* in case the transformed problems is written only constraint are posted which are enabled in the current node;
3437 * the conss array should only contain relevant constraints
3438 */
3439 assert( !transformed || SCIPconsIsEnabled(cons) );
3440
3441 assert( consnames[c] != NULL );
3442
3443 conshdlr = SCIPconsGetHdlr(cons);
3444 assert( conshdlr != NULL );
3445
3447
3448 if( strcmp(conshdlrname, "linear") == 0 )
3449 {
3450 lhs = SCIPgetLhsLinear(scip, cons);
3451 rhs = SCIPgetRhsLinear(scip, cons);
3452 }
3453 else if( strcmp(conshdlrname, "varbound") == 0 )
3454 {
3455 lhs = SCIPgetLhsVarbound(scip, cons);
3456 rhs = SCIPgetRhsVarbound(scip, cons);
3457 }
3458 else
3459 continue;
3460
3461 if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && !SCIPisEQ(scip, rhs, lhs) )
3462 {
3463 assert( SCIPisGT(scip, rhs, lhs) );
3464 printEntry(scip, file, "RANGE", consnames[c], rhs - lhs, &recordcnt, maxnamelen);
3465 }
3466 }
3467 if(recordcnt == 1 )
3468 SCIPinfoMessage(scip, file, "\n");
3469}
3470
3471/** print bound section name */
3472static
3474 SCIP* scip, /**< SCIP data structure */
3475 FILE* file /**< output file, or NULL if standard output should be used */
3476 )
3477{
3478 SCIPinfoMessage(scip, file, "BOUNDS\n");
3479 SCIPdebugMsg(scip, "start printing BOUNDS section\n");
3480}
3481
3482/** output bound section */
3483static
3485 SCIP* scip, /**< SCIP data structure */
3486 FILE* file, /**< output file, or NULL if standard output should be used */
3487 SCIP_VAR** vars, /**< active variables */
3488 int nvars, /**< number of active variables */
3489 SCIP_VAR** aggvars, /**< needed aggregated variables */
3490 int naggvars, /**< number of aggregated variables */
3491 SCIP_VAR** fixvars, /**< all fixed variables (or NULL if nfixvars is 0) */
3492 int nfixvars, /**< number of fixed variables */
3493 SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
3494 const char** varnames, /**< array with variable names */
3495 SCIP_HASHTABLE* indicatorSlackHash, /**< hashtable containing slack variables from indicators (or NULL) */
3496 unsigned int maxnamelen /**< maximum name length */
3497 )
3498{
3499 int v;
3500 SCIP_VAR* var;
3501 SCIP_Real lb;
3502 SCIP_Real ub;
3503 SCIP_Bool sectionName;
3504 const char* varname;
3505 char valuestr[MPS_MAX_VALUELEN] = { '\0' };
3506
3507 assert(scip != NULL);
3508 assert(vars != NULL);
3509 assert(nfixvars == 0 || fixvars != NULL);
3510
3512
3513 /* output the active variables */
3514 for( v = 0; v < nvars; ++v )
3515 {
3516 var = vars[v];
3517 assert( var != NULL );
3518
3519 /* skip slack variables in output */
3521 continue;
3522
3523 /* get variable name */
3524 varname = varnames[v];
3526
3527 if( transformed )
3528 {
3529 /* in case the transformed is written only local bounds are posted
3530 * which are valid in the current node */
3531 lb = SCIPvarGetLbLocal(var);
3532 ub = SCIPvarGetUbLocal(var);
3533 }
3534 else
3535 {
3538 }
3539
3540 /* take care of binary variables */
3542 {
3543 if( !sectionName )
3544 {
3546 sectionName = TRUE;
3547 }
3548
3549 if( !SCIPisFeasZero(scip, lb) || !SCIPisFeasEQ(scip, ub, 1.0) )
3550 {
3551 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", lb);
3552 printStart(scip, file, "LO", "Bound", (int) maxnamelen);
3554 SCIPinfoMessage(scip, file, "\n");
3555
3556 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", ub);
3557 printStart(scip, file, "UP", "Bound", (int) maxnamelen);
3559 }
3560 else
3561 {
3562 printStart(scip, file, "BV", "Bound", (int) maxnamelen);
3563 printRecord(scip, file, varname, "", maxnamelen);
3564 }
3565 SCIPinfoMessage(scip, file, "\n");
3566
3567 continue;
3568 }
3569
3570 /* take care of free variables */
3571 if( SCIPisInfinity(scip, -lb) && SCIPisInfinity(scip, ub) )
3572 {
3573 if( !sectionName )
3574 {
3576 sectionName = TRUE;
3577 }
3578
3579 /* variable is free */
3580 printStart(scip, file, "FR", "Bound", (int) maxnamelen);
3581 printRecord(scip, file, varname, "", maxnamelen);
3582 SCIPinfoMessage(scip, file, "\n");
3583 continue;
3584 }
3585
3586 /* take care of fixed variables */
3587 if( SCIPisEQ(scip, lb, ub) )
3588 {
3589 if( !sectionName )
3590 {
3592 sectionName = TRUE;
3593 }
3594
3595 /* variable is fixed */
3596 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", lb);
3597 printStart(scip, file, "FX", "Bound", (int) maxnamelen);
3599 SCIPinfoMessage(scip, file, "\n");
3600 continue;
3601 }
3602
3603 /* print lower bound */
3604 if( SCIPisInfinity(scip, -lb) )
3605 {
3606 if( !sectionName )
3607 {
3609 sectionName = TRUE;
3610 }
3611
3612 /* the free variables are processed above */
3613 assert( !SCIPisInfinity(scip, ub) );
3614 printStart(scip, file, "MI", "Bound", (int) maxnamelen);
3615 printRecord(scip, file, varname, "", maxnamelen);
3616 SCIPinfoMessage(scip, file, "\n");
3617 }
3618 else
3619 {
3620 if( SCIPisZero(scip, lb) )
3621 {
3622 lb = 0.0;
3623 }
3624 else
3625 {
3626 if( !sectionName )
3627 {
3629 sectionName = TRUE;
3630 }
3631
3632 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", lb);
3633 printStart(scip, file, "LO", "Bound", (int) maxnamelen);
3635 SCIPinfoMessage(scip, file, "\n");
3636 }
3637 }
3638
3639 /* print upper bound, infinity has to be printed for integer (!) variables, because during
3640 * reading an mps file no upper bound of an integer variable means that the upper bound will
3641 * be set to 1 instead of +infinity (like it is for continuous variables) */
3642 if( SCIPisInfinity(scip, ub) )
3643 {
3644 if( !sectionName )
3645 {
3647 sectionName = TRUE;
3648 }
3649
3650 /* the free variables are processed above */
3651 assert( !SCIPisInfinity(scip, -lb) );
3652 printStart(scip, file, "PL", "Bound", (int) maxnamelen);
3653 printRecord(scip, file, varname, "", maxnamelen);
3654 SCIPinfoMessage(scip, file, "\n");
3655 }
3656 else
3657 {
3658 if( !sectionName )
3659 {
3661 sectionName = TRUE;
3662 }
3663
3664 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", ub);
3665 printStart(scip, file, "UP", "Bound", (int) maxnamelen);
3667 SCIPinfoMessage(scip, file, "\n");
3668 }
3669 }
3670
3671 /* output aggregated variables as 'free', except if they are binary */
3672 for( v = 0; v < naggvars; ++v )
3673 {
3674 if( !sectionName )
3675 {
3677 sectionName = TRUE;
3678 }
3679
3680 var = aggvars[v];
3681 assert( var != NULL );
3682
3683 /* get variable name */
3684 varname = varnames[nvars + v];
3686
3687 /* take care of binary variables */
3689 {
3690 printStart(scip, file, "BV", "Bound", (int) maxnamelen);
3691 printRecord(scip, file, varname, "", maxnamelen);
3692 SCIPinfoMessage(scip, file, "\n");
3693 }
3694 else
3695 {
3696 /* variable is free */
3697 printStart(scip, file, "FR", "Bound", (int) maxnamelen);
3698 printRecord(scip, file, varname, "", maxnamelen);
3699 SCIPinfoMessage(scip, file, "\n");
3700 }
3701 }
3702
3703 /* output all fixed variables */
3704 for( v = 0; v < nfixvars; ++v )
3705 {
3706 /* we should print the transformed problem, otherwise no fixed variable should exists */
3707 assert(transformed);
3708 assert(fixvars != NULL && fixvars[v] != NULL);
3709
3710 /* cppcheck-suppress nullPointer */
3711 var = fixvars[v];
3712
3713 assert(var != NULL);
3715
3716 /* get variable name */
3717 varname = varnames[nvars + naggvars + v];
3719
3720 /* only local bounds are posted which are valid in the current node */
3721 lb = SCIPvarGetLbLocal(var);
3722 ub = SCIPvarGetUbLocal(var);
3723 assert(SCIPisEQ(scip, lb, ub));
3724
3725 if( !sectionName )
3726 {
3728 sectionName = TRUE;
3729 }
3730
3731 /* print fixed variable */
3732 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", lb);
3733 printStart(scip, file, "FX", "Bound", (int) maxnamelen);
3735 SCIPinfoMessage(scip, file, "\n");
3736 }
3737}
3738
3739
3740/*
3741 * Callback methods of reader
3742 */
3743
3744/** copy method for reader plugins (called when SCIP copies plugins) */
3745/**! [SnippetReaderCopyMps] */
3746static
3748{ /*lint --e{715}*/
3749 assert(scip != NULL);
3750 assert(reader != NULL);
3752
3753 /* call inclusion method of reader */
3755
3756 return SCIP_OKAY;
3757}
3758/**! [SnippetReaderCopyMps] */
3759
3760/** destructor of reader to free user data (called when SCIP is exiting) */
3761/**! [SnippetReaderFreeMps] */
3762static
3764{
3765 SCIP_READERDATA* readerdata;
3766
3768 readerdata = SCIPreaderGetData(reader);
3769 assert(readerdata != NULL);
3770 SCIPfreeBlockMemory(scip, &readerdata);
3771
3772 return SCIP_OKAY;
3773}
3774/**! [SnippetReaderFreeMps] */
3775
3776/** problem reading method of reader */
3777static
3779{ /*lint --e{715}*/
3780 assert(reader != NULL);
3782
3784
3785 return SCIP_OKAY;
3786}
3787
3788
3789/** problem writing method of reader */
3790static
3792{ /*lint --e{715}*/
3793 assert(reader != NULL);
3795
3796 SCIP_CALL( SCIPwriteMps(scip, reader, file, name, transformed, objsense, objscale, objoffset, vars,
3797 nvars, nbinvars, nintvars, nimplvars, ncontvars, fixedvars, nfixedvars, conss, nconss, result) );
3798
3799 return SCIP_OKAY;
3800}
3801
3802
3803/*
3804 * mps file reader specific interface methods
3805 */
3806
3807/** includes the mps file reader in SCIP */
3809 SCIP* scip /**< SCIP data structure */
3810 )
3811{
3812 SCIP_READERDATA* readerdata;
3814
3815 /* create reader data */
3816 SCIP_CALL( SCIPallocBlockMemory(scip, &readerdata) );
3817
3818 /* include reader */
3820
3821 /* set non fundamental callbacks via setter functions */
3826
3827 /* add lp-reader parameters */
3829 "reading/" READER_NAME "/linearize-and-constraints",
3830 "should possible \"and\" constraint be linearized when writing the mps file?",
3831 &readerdata->linearizeands, TRUE, DEFAULT_LINEARIZE_ANDS, NULL, NULL) );
3833 "reading/" READER_NAME "/aggrlinearization-ands",
3834 "should an aggregated linearization for and constraints be used?",
3835 &readerdata->aggrlinearizationands, TRUE, DEFAULT_AGGRLINEARIZATION_ANDS, NULL, NULL) );
3836
3837 return SCIP_OKAY;
3838}
3839
3840
3841/** reads problem from file */
3843 SCIP* scip, /**< SCIP data structure */
3844 SCIP_READER* reader, /**< the file reader itself */
3845 const char* filename, /**< full path and name of file to read, or NULL if stdin should be used */
3846 SCIP_RESULT* result, /**< pointer to store the result of the file reading call */
3847 const char*** varnames, /**< storage for the variable names, or NULL */
3848 const char*** consnames, /**< storage for the constraint names, or NULL */
3849 int* varnamessize, /**< the size of the variable names storage, or NULL */
3850 int* consnamessize, /**< the size of the constraint names storage, or NULL */
3851 int* nvarnames, /**< the number of stored variable names, or NULL */
3852 int* nconsnames /**< the number of stored constraint names, or NULL */
3853 )
3854{
3855 SCIP_RETCODE retcode;
3856
3857 assert(reader != NULL);
3858 assert(scip != NULL);
3859 assert(result != NULL);
3860
3861 retcode = readMps(scip, filename, varnames, consnames, varnamessize, consnamessize, nvarnames, nconsnames);
3862
3863 if( retcode == SCIP_PLUGINNOTFOUND )
3864 retcode = SCIP_READERROR;
3865
3866 if( retcode == SCIP_NOFILE || retcode == SCIP_READERROR )
3867 return retcode;
3868
3869 SCIP_CALL( retcode );
3870
3872
3873 return SCIP_OKAY;
3874}
3875
3876
3877/** writes problem to file */
3879 SCIP* scip, /**< SCIP data structure */
3880 SCIP_READER* reader, /**< the file reader itself */
3881 FILE* file, /**< output file, or NULL if standard output should be used */
3882 const char* name, /**< problem name */
3883 SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
3884 SCIP_OBJSENSE objsense, /**< objective sense */
3885 SCIP_Real objscale, /**< scalar applied to objective function; external objective value is
3886 * extobj = objsense * objscale * (intobj + objoffset) */
3887 SCIP_Real objoffset, /**< objective offset from bound shifting and fixing */
3888 SCIP_VAR** vars, /**< array with active variables ordered binary, integer, implicit, continuous */
3889 int nvars, /**< number of active variables in the problem */
3890 int nbinvars, /**< number of binary variables */
3891 int nintvars, /**< number of general integer variables */
3892 int nimplvars, /**< number of implicit integer variables */
3893 int ncontvars, /**< number of continuous variables */
3894 SCIP_VAR** fixedvars, /**< array with fixed and aggregated variables */
3895 int nfixedvars, /**< number of fixed and aggregated variables in the problem */
3896 SCIP_CONS** conss, /**< array with constraints of the problem */
3897 int nconss, /**< number of constraints in the problem */
3898 SCIP_RESULT* result /**< pointer to store the result of the file writing call */
3899 )
3900{
3901 SCIP_READERDATA* readerdata;
3902 int naddrows;
3903 int faulty = 0;
3904 int c;
3905 int v;
3906 int k;
3907 char* namestr;
3908
3909 SCIP_CONS* cons = NULL;
3910 const char* consname;
3911 const char** consnames;
3912
3913 SCIP_CONSHDLR* conshdlr;
3914 const char* conshdlrname;
3915
3916 SCIP_Real lhs;
3917 SCIP_Real rhs;
3918 SCIP_Real* rhss;
3919 SCIP_Real value;
3920
3921 SCIP_VAR* var = NULL;
3922 const char* varname;
3923 const char** varnames;
3924
3925 char valuestr[MPS_MAX_VALUELEN] = { '\0' };
3926
3931 int nConsIndicator;
3932 int nConsSOS1;
3933 int nConsSOS2;
3934 int nConsQuadratic;
3935
3936 SCIP_HASHMAP* varnameHashmap; /* hash map from SCIP_VAR* to variable name */
3937 SPARSEMATRIX* matrix;
3938
3939 SCIP_VAR** aggvars;
3940 int naggvars = 0;
3941 int saggvars;
3944
3945 SCIP_VAR** fixvars = NULL;
3946 int nfixvars = 0;
3947
3948 SCIP_VAR** consvars;
3949 int nconsvars;
3950 SCIP_Real* vals;
3951 SCIP_Longint* weights;
3952
3953 SCIP_Bool needRANGES;
3954 unsigned int maxnamelen;
3955
3956 SCIP_Bool error;
3957
3958 assert(reader != NULL);
3960 assert(scip != NULL);
3961 assert(result != NULL);
3962
3963 needRANGES = FALSE;
3964 maxnamelen = 0;
3965 nConsSOS1 = 0;
3966 nConsSOS2 = 0;
3967 nConsQuadratic = 0;
3968 nConsIndicator = 0;
3969
3970 /* check if the constraint names are too long and build the constraint names */
3971 SCIP_CALL( checkConsnames(scip, conss, nconss, transformed, &maxnamelen, &consnames, &error) );
3972 if( error )
3973 {
3974 /* call writing with generic names */
3975 if( transformed )
3976 {
3977 SCIPwarningMessage(scip, "write transformed problem with generic variable and constraint names\n");
3978 SCIP_CALL( SCIPprintTransProblem(scip, file, "mps", TRUE) );
3979 }
3980 else
3981 {
3982 SCIPwarningMessage(scip, "write original problem with generic variable and constraint names\n");
3983 SCIP_CALL( SCIPprintOrigProblem(scip, file, "mps", TRUE) );
3984 }
3986
3987 return SCIP_OKAY;
3988 }
3989
3990 /* check if the variable names are not too long and build the "variable" -> "variable name" hash map */
3992
3993 /* collect SOS, quadratic, and indicator constraints in array for later output */
3998
3999 /* nfixedvars counts all variables with status SCIP_VARSTATUS_FIXED, SCIP_VARSTATUS_AGGREGATED, SCIP_VARSTATUS_MULTAGGR, but not SCIP_VARSTATUS_NEGATED */
4000 saggvars = nfixedvars;
4002
4003 /* create hashtable for storing aggregated variables */
4004 if( nfixedvars > 0 )
4005 {
4007 }
4008 else
4010
4011 if( nvars > 0 )
4012 {
4014 }
4015 else
4017
4018 /* initialize sparse matrix */
4019 SCIP_CALL( initializeMatrix(scip, &matrix, (nvars * 2 + nfixedvars)) );
4020 assert( matrix->sentries >= nvars );
4021
4022 readerdata = SCIPreaderGetData(reader);
4023 assert(readerdata != NULL);
4024
4025 naddrows = 0;
4026
4027 /* determine and-constraints and printing format to resize necessary arrays */
4028 if( readerdata->linearizeands )
4029 {
4031
4032 if( andconshdlr != NULL )
4033 {
4034 /* need to check for and-constraints, note that in the original problem you cannot get the number of
4035 * and-constraints by one call */
4036 for( c = nconss - 1; c >= 0; --c )
4037 {
4038 conshdlr = SCIPconsGetHdlr(conss[c]);
4039 assert(conshdlr != NULL);
4040
4042
4043 if( strcmp(conshdlrname, "and") == 0 )
4044 {
4045 if( readerdata->aggrlinearizationands )
4046 ++naddrows;
4047 else
4048 naddrows += SCIPgetNVarsAnd(scip, conss[c]);
4049 }
4050 }
4051 assert(naddrows >= 0);
4052
4053 if( naddrows > 0 )
4054 {
4055 /* resize consnames vector */
4056 SCIP_CALL( SCIPreallocBufferArray(scip, &consnames, nconss + naddrows) );
4057 }
4058 }
4059 }
4060
4061 /* initialize rhs vector */
4063
4064 /* print statistics as comment to file stream */
4065 SCIPinfoMessage(scip, file, "* SCIP STATISTICS\n");
4066 SCIPinfoMessage(scip, file, "* Problem name : %s\n", name);
4067 SCIPinfoMessage(scip, file, "* Variables : %d (%d binary, %d integer, %d implicit integer, %d continuous)\n",
4068 nvars, nbinvars, nintvars, nimplvars, ncontvars);
4069 SCIPinfoMessage(scip, file, "* Constraints : %d\n", nconss);
4070
4071 /* print NAME of the problem */
4072 SCIPinfoMessage(scip, file, "%-14s%s\n", "NAME", name);
4073
4074 /* print OBJSENSE of the problem */
4075 SCIPinfoMessage(scip, file, "OBJSENSE\n");
4076 SCIPinfoMessage(scip, file, "%s\n", objsense == SCIP_OBJSENSE_MAXIMIZE ? " MAX" : " MIN");
4077
4078 /* start ROWS section */
4079 SCIPinfoMessage(scip, file, "ROWS\n");
4080
4081 /* print row type for the objective function */
4082 printStart(scip, file, "N", "Obj", -1);
4083 SCIPinfoMessage(scip, file, "\n");
4084
4085 /* first fill the matrix with the objective coefficients */
4086 for( v = 0; v < nvars; ++v )
4087 {
4088 /* take care of the objective entry */
4089 var = vars[v];
4090 value = SCIPvarGetObj(var);
4091
4092 /* we also want to add integer variables to the columns section, even if the objective value is 0, because it
4093 * might happen that they only exist in non-linear constraints, which leads to no other line in the column section
4094 * and therefore do not mark the variable as an integer
4095 */
4099 {
4100 assert( matrix->nentries < matrix->sentries );
4101
4102 matrix->values[matrix->nentries] = objscale * value;
4103 matrix->columns[matrix->nentries] = var;
4104 matrix->rows[matrix->nentries] = "Obj";
4105 matrix->nentries++;
4106 }
4107 }
4108
4109 /* loop over all constraints */
4110 k = nconss;
4111 for( c = 0; c < nconss; ++c )
4112 {
4113 cons = conss[c];
4114 assert( cons != NULL);
4115
4116 /* in case the transformed problems is written only constraint are posted which are enabled in the current node;
4117 * the conss array should only contain relevant constraints
4118 */
4119 assert( !transformed || SCIPconsIsEnabled(cons) );
4120
4121 conshdlr = SCIPconsGetHdlr(cons);
4122 assert( conshdlr != NULL );
4123
4125
4126 /* construct constraint name */
4127 consname = consnames[c];
4128
4129 /* init rhs value to infinity (would then ignored) */
4130 rhss[c] = SCIPinfinity(scip);
4131
4132 if( strcmp(conshdlrname, "linear") == 0 )
4133 {
4134 lhs = SCIPgetLhsLinear(scip, cons);
4135 rhs = SCIPgetRhsLinear(scip, cons);
4136
4137 /* there is nothing to do if the left hand side is minus infinity and the right side is infinity */
4138 if( !SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs) )
4139 {
4140 if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && !SCIPisEQ(scip, lhs, rhs) )
4141 needRANGES = TRUE;
4142
4143 /* print row entry */
4144 printRowType(scip, file, lhs, rhs, consname);
4145
4146 if( SCIPisInfinity(scip, rhs) )
4147 rhss[c] = lhs;
4148 else
4149 rhss[c] = rhs;
4150
4152
4153 /* compute column entries */
4155 SCIPgetNVarsLinear(scip, cons), transformed, matrix, &rhss[c]) );
4156 }
4157 }
4158 else if( strcmp(conshdlrname, "setppc") == 0 )
4159 {
4160 /* print row entry */
4161 switch( SCIPgetTypeSetppc(scip, cons) )
4162 {
4164 printRowType(scip, file, 1.0, 1.0, consname);
4165 break;
4167 printRowType(scip, file, -SCIPinfinity(scip), 1.0, consname);
4168 break;
4171 break;
4172 }
4173
4174 rhss[c] = 1.0;
4175
4176 /* compute column entries */
4177 SCIP_CALL( getLinearCoeffs(scip, consname, SCIPgetVarsSetppc(scip, cons), NULL, SCIPgetNVarsSetppc(scip, cons), transformed, matrix, &rhss[c]) );
4178 }
4179 else if( strcmp(conshdlrname, "logicor") == 0 )
4180 {
4181 /* print row entry */
4183
4184 rhss[c] = 1.0;
4185
4186 /* compute column entries */
4187 SCIP_CALL( getLinearCoeffs(scip, consname, SCIPgetVarsLogicor(scip, cons), NULL, SCIPgetNVarsLogicor(scip, cons), transformed, matrix, &rhss[c]) );
4188 }
4189 else if( strcmp(conshdlrname, "knapsack") == 0 )
4190 {
4191 int i;
4192
4193 /* print row entry */
4195
4196 nconsvars = SCIPgetNVarsKnapsack(scip, cons);
4197 weights = SCIPgetWeightsKnapsack(scip, cons);
4198
4199 /* copy Longint array to SCIP_Real array */
4200 SCIP_CALL( SCIPallocBufferArray(scip, &vals, nconsvars ) );
4201 for( i = 0; i < nconsvars; ++i )
4202 vals[i] = (SCIP_Real)weights[i];
4203
4205
4206 /* compute column entries */
4207 SCIP_CALL( getLinearCoeffs(scip, consname, SCIPgetVarsKnapsack(scip, cons), vals, nconsvars, transformed, matrix, &rhss[c]) );
4208
4209 SCIPfreeBufferArray(scip, &vals);
4210 }
4211 else if( strcmp(conshdlrname, "varbound") == 0 )
4212 {
4213 lhs = SCIPgetLhsVarbound(scip, cons);
4214 rhs = SCIPgetRhsVarbound(scip, cons);
4215
4216 /* there is nothing to do if the left hand side is minus infinity and the right side is infinity */
4217 if( !SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs) )
4218 {
4219 if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && !SCIPisEQ(scip, lhs, rhs) )
4220 needRANGES = TRUE;
4221
4222 /* print row entry */
4223 printRowType(scip, file, lhs, rhs, consname);
4224
4225 /* allocate memory */
4226 SCIP_CALL( SCIPallocBufferArray(scip, &consvars, 2) );
4227 SCIP_CALL( SCIPallocBufferArray(scip, &vals, 2) );
4228
4229 consvars[0] = SCIPgetVarVarbound(scip, cons);
4230 consvars[1] = SCIPgetVbdvarVarbound(scip, cons);
4231
4232 vals[0] = 1.0;
4233 vals[1] = SCIPgetVbdcoefVarbound(scip, cons);
4234
4235 if( SCIPisInfinity(scip, rhs) )
4236 rhss[c] = lhs;
4237 else
4238 rhss[c] = rhs;
4239
4241
4242 /* compute column entries */
4243 SCIP_CALL( getLinearCoeffs(scip, consname, consvars, vals, 2, transformed, matrix, &rhss[c]) );
4244
4245 SCIPfreeBufferArray(scip, &vals);
4246 SCIPfreeBufferArray(scip, &consvars);
4247 }
4248 }
4249 else if( strcmp(conshdlrname, "indicator") == 0 )
4250 {
4251 SCIP_VAR* slackvar;
4252 SCIP_VAR* binvar;
4253
4254 /* store slack variable in hash */
4255 slackvar = SCIPgetSlackVarIndicator(cons);
4256 assert( slackvar != NULL );
4258 assert( !SCIPhashtableExists(indicatorSlackHash, (void*) slackvar) );
4259 SCIP_CALL( SCIPhashtableInsert(indicatorSlackHash, (void*) slackvar) );
4260
4261 /* if slackvariable is aggregated, we store it in the list of aggregated variables */
4263 {
4265 }
4266
4267 /* store aggregated variables */
4268 binvar = SCIPgetBinaryVarIndicator(cons);
4269 if( SCIPvarIsNegated(binvar) )
4270 binvar = SCIPvarGetNegatedVar(binvar);
4271 assert( binvar != NULL );
4273
4274 /* indicator constraint do not have a right hand side; mark this with SCIPinfinity(scip) */
4275 rhss[c] = SCIPinfinity(scip);
4276
4277 /* store constraint */
4278 consIndicator[nConsIndicator++] = cons;
4279 continue;
4280 }
4281 else if( strcmp(conshdlrname, "SOS1") == 0 )
4282 {
4283 /* store constraint */
4284 consSOS1[nConsSOS1++] = cons;
4285
4286 /* check for aggregated variables in SOS1 constraints for later output
4287 * of aggregations as linear constraints */
4288 consvars = SCIPgetVarsSOS1(scip, cons);
4289 nconsvars = SCIPgetNVarsSOS1(scip, cons);
4290
4291 /* SOS constraint do not have a right hand side; mark this with SCIPinfinity(scip) */
4292 rhss[c] = SCIPinfinity(scip);
4293
4295 }
4296 else if( strcmp(conshdlrname, "SOS2") == 0 )
4297 {
4298 /* store constraint */
4299 consSOS2[nConsSOS2++] = cons;
4300
4301 /* check for aggregated variables in SOS2 constraints for later output aggregations as linear constraints */
4302 consvars = SCIPgetVarsSOS2(scip, cons);
4303 nconsvars = SCIPgetNVarsSOS2(scip, cons);
4304
4305 /* SOS constraint do not have a right hand side; mark this with SCIPinfinity(scip) */
4306 rhss[c] = SCIPinfinity(scip);
4307
4309 }
4310 else if( strcmp(conshdlrname, "nonlinear") == 0 )
4311 {
4312 SCIP_EXPR* expr;
4313 SCIP_VAR** quadvars;
4314 SCIP_Real* quadvarlincoefs;
4315 SCIP_Real* lincoefs;
4316 SCIP_Real constant;
4317 SCIP_EXPR** linexprs;
4318 SCIP_Bool isquadratic;
4319 int nquadexprs;
4320 int nlinexprs;
4321 int j;
4322
4323 /* check if it is a quadratic constraint */
4325 if( !isquadratic )
4326 {
4327 /* unknown constraint type; mark this with SCIPinfinity(scip) */
4328 rhss[c] = SCIPinfinity(scip);
4329
4330 SCIPwarningMessage(scip, "constraint handler <%s> cannot print requested format\n", conshdlrname );
4331 continue;
4332 }
4333
4334 /* store constraint */
4335 consQuadratic[nConsQuadratic++] = cons;
4336
4337 expr = SCIPgetExprNonlinear(cons);
4338
4339 /* collect linear coefficients of quadratic part */
4340 SCIPexprGetQuadraticData(expr, &constant, &nlinexprs, &linexprs, &lincoefs, &nquadexprs, NULL, NULL,
4341 NULL);
4342
4343 SCIP_CALL( SCIPallocBufferArray(scip, &quadvars, nquadexprs) );
4345 for( j = 0; j < nquadexprs; ++j )
4346 {
4347 SCIP_EXPR* qexpr;
4348
4350
4351 assert(SCIPisExprVar(scip, qexpr));
4352 quadvars[j] = SCIPgetVarExprVar(qexpr);
4353 }
4354
4355 lhs = SCIPgetLhsNonlinear(cons);
4356 rhs = SCIPgetRhsNonlinear(cons);
4357
4358 /* correct side by constant */
4359 lhs -= SCIPisInfinity(scip, -lhs) ? 0.0 : constant;
4360 rhs -= SCIPisInfinity(scip, rhs) ? 0.0 : constant;
4361
4362 /* there is nothing to do if the left hand side is minus infinity and the right side is infinity */
4363 if( !SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs) )
4364 {
4365 SCIP_VAR** linvars;
4366
4367 if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && !SCIPisEQ(scip, lhs, rhs) )
4368 needRANGES = TRUE;
4369
4370 /* print row entry */
4371 printRowType(scip, file, lhs, rhs, consname);
4372
4373 if( SCIPisInfinity(scip, rhs) )
4374 rhss[c] = lhs;
4375 else
4376 rhss[c] = rhs;
4377
4379
4380 /* get linear vars */
4381 SCIP_CALL( SCIPallocBufferArray(scip, &linvars, nlinexprs) );
4382 for( j = 0; j < nlinexprs; ++j )
4383 linvars[j] = SCIPgetVarExprVar(linexprs[j]);
4384
4385 /* compute column entries for linear part */
4386 SCIP_CALL( getLinearCoeffs(scip, consname, linvars, lincoefs, nlinexprs, transformed, matrix, &rhss[c]) );
4387
4388 /* compute column entries for linear part in quadratic part */
4389 SCIP_CALL( getLinearCoeffs(scip, consname, quadvars, quadvarlincoefs, nquadexprs, transformed, matrix,
4390 &rhss[c]) );
4391
4392 SCIPfreeBufferArray(scip, &linvars);
4393 }
4394
4395 /* check for aggregated variables in quadratic part of quadratic constraints for later output of
4396 * aggregations as linear constraints */
4397 consvars = quadvars;
4398 nconsvars = nquadexprs;
4399
4401
4402 SCIPfreeBufferArray(scip, &quadvars);
4404 }
4405 else if( strcmp(conshdlrname, "and") == 0 )
4406 {
4407 if( readerdata->linearizeands )
4408 {
4409 SCIP_VAR** rowvars;
4412 SCIP_Real* rowvals;
4413 char* rowname;
4414 int nrowvars;
4415 int l;
4416 int n;
4417
4418 nrowvars = SCIPgetNVarsAnd(scip, cons);
4419 operands = SCIPgetVarsAnd(scip, cons);
4421
4422 /* allocate buffer array */
4425
4426 /* get length of constraint name */
4427 l = (int) strlen(consname);
4428
4429 /* the tight relaxtion, number of and-constraint operands rows */
4430 if( !readerdata->aggrlinearizationands )
4431 {
4432 rowvars[0] = resultant;
4433 rowvals[0] = 1.0;
4434 rowvals[1] = -1.0;
4435
4436 /* compute maximal length for rowname */
4437 /* coverity[negative_returns] */
4438 n = (int) log10((double)nrowvars) + 1 + l;
4439
4440 /* assure maximal allowed value */
4441 if( n >= MPS_MAX_NAMELEN )
4442 n = MPS_MAX_NAMELEN - 1;
4443
4444 /* update maxnamelen */
4445 maxnamelen = MAX(maxnamelen, (unsigned int) n);
4446
4447 /* print operator rows */
4448 for( v = 0; v < nrowvars; ++v )
4449 {
4450 /* compute maximal length for rowname */
4451 if( v == 0 )
4452 n = 2;
4453 else
4454 n = (int) log10((double)v) + 2;
4455 n += l;
4456
4457 /* assure maximal allowed value */
4458 if( n >= MPS_MAX_NAMELEN )
4459 {
4460 n = MPS_MAX_NAMELEN - 1;
4461 ++faulty;
4462 }
4463
4464 /* need memory for additional row */
4466
4467 assert(k < nconss + naddrows);
4468 consnames[k] = rowname;
4469
4470 (void) SCIPsnprintf(rowname, n + 1, "%s_%d", consname, v);
4471 rowvars[1] = operands[v];
4472
4473 /* print row entry */
4474 printRowType(scip, file, -SCIPinfinity(scip), 0.0, rowname);
4475
4476 rhss[k] = 0.0;
4477
4478 /* compute column entries */
4479 SCIP_CALL( getLinearCoeffs(scip, rowname, rowvars, rowvals, 2, transformed, matrix, &rhss[k]) );
4480 ++k;
4481 }
4482 }
4483
4484 /* prepare for next row */
4485 for( v = nrowvars - 1; v >= 0; --v )
4486 {
4487 rowvars[v] = operands[v];
4488 rowvals[v] = -1.0;
4489 }
4490
4492
4493 /* the weak relaxtion, only one constraint */
4494 if( readerdata->aggrlinearizationands )
4495 {
4496 /* compute maximal length for rowname */
4497 n = l + 3;
4498
4499 /* assure maximal allowed value */
4500 if( n >= MPS_MAX_NAMELEN )
4501 {
4502 n = MPS_MAX_NAMELEN - 1;
4503 ++faulty;
4504 }
4505
4506 /* update maxnamelen */
4507 maxnamelen = MAX(maxnamelen, (unsigned int) n);
4508
4509 /* need memory for additional row */
4511
4512 assert(k < nconss + naddrows);
4513 consnames[k] = rowname;
4514
4515 /* adjust rowname of constraint */
4516 (void) SCIPsnprintf(rowname, n + 1, "%s_op", consname);
4517
4519
4520 /* print row entry */
4521 printRowType(scip, file, -SCIPinfinity(scip), 0.0, rowname);
4522
4523 rhss[k] = 0.0;
4524
4525 /* compute column entries */
4526 SCIP_CALL( getLinearCoeffs(scip, rowname, rowvars, rowvals, nrowvars + 1, transformed, matrix, &rhss[k]) );
4527
4528 SCIPdebugMsg(scip, "%g, %g\n", rowvals[1], rhss[k]);
4529 ++k;
4530 }
4531
4532 rowvals[nrowvars] = 1.0;
4533
4534 /* print row entry */
4536
4537 rhss[c] = -nrowvars + 1.0;
4538
4539 /* compute column entries */
4540 SCIP_CALL( getLinearCoeffs(scip, consname, rowvars, rowvals, nrowvars + 1, transformed, matrix, &rhss[c]) );
4541
4542 /* free buffer array */
4545 }
4546 else
4547 {
4548 /* and constraint printing not enabled; mark this with SCIPinfinity(scip) */
4549 rhss[c] = SCIPinfinity(scip);
4550
4551 SCIPwarningMessage(scip, "change parameter \"reading/" READER_NAME "/linearize-and-constraints\" to TRUE to print and-constraints\n");
4552 }
4553 }
4554 else
4555 {
4556 /* unknown constraint type; mark this with SCIPinfinity(scip) */
4557 rhss[c] = SCIPinfinity(scip);
4558
4559 SCIPwarningMessage(scip, "constraint handler <%s> cannot print requested format\n", conshdlrname );
4560 }
4561 }
4562
4563 if( faulty > 0 )
4564 {
4565 SCIPwarningMessage(scip, "there are %d and-constraint-rownames which have to be cut down to %d characters; MPS file might be corrupted\n",
4566 faulty, MPS_MAX_NAMELEN - 1);
4567 }
4568
4569 /* free hash table */
4570 if( varFixedHash != NULL )
4572
4573 if( indicatorSlackHash != NULL && nConsIndicator == 0 )
4574 {
4577 }
4578
4579 if( naggvars > 0 )
4580 {
4581 /* construct variables name of the needed aggregated variables and the constraint names for the aggregation constraints */
4582
4583 /* realloc memory */
4584 SCIP_CALL( SCIPreallocBufferArray(scip, &consnames, nconss + naddrows + naggvars) );
4587
4588 for( c = 0; c < naggvars; ++c )
4589 {
4590 size_t l;
4591
4592 /* create variable name */
4593 var = aggvars[c];
4594
4596 if( l >= MPS_MAX_NAMELEN )
4598 else
4599 maxnamelen = MAX(maxnamelen, (unsigned int) l);
4600
4603
4604 /* insert variable with variable name into hash map */
4605 varnames[nvars + c] = namestr;
4608
4609 /* output row type (it is an equation) */
4610 SCIP_CALL( SCIPallocBufferArray(scip, &namestr, MPS_MAX_NAMELEN) ); /* note that namestr above is freed via varnames */
4612 printRowType(scip, file, 1.0, 1.0, namestr);
4613
4614 l = strlen(namestr);
4615 maxnamelen = MAX(maxnamelen, (unsigned int) l);
4616 consnames[nconss + naddrows + c] = namestr;
4617 rhss[nconss + naddrows + c] = 0.0;
4618
4619 /* compute column entries */
4620 SCIP_CALL( getLinearCoeffs(scip, namestr, &(aggvars[c]), NULL, 1, transformed, matrix, &rhss[nconss + naddrows + c]) );
4621
4622 /* add the aggregated variables to the sparse matrix */
4624 matrix->values[matrix->nentries] = -1.0;
4625 matrix->columns[matrix->nentries] = aggvars[c];
4626 matrix->rows[matrix->nentries] = namestr;
4627 matrix->nentries++;
4628 }
4629 }
4630
4631 /* collect also fixed variables, because they might not be removed from all constraints */
4632 /* @todo only collect fixed variables in the non-linear constraint types, where they (could not be)/(were not) removed */
4633 if( nfixedvars > 0 )
4634 {
4635 int startpos = nvars + naggvars;
4636 /* construct variables name of fixed variables */
4637
4638 /* realloc memory */
4639 SCIP_CALL( SCIPreallocBufferArray(scip, &varnames, startpos + nfixedvars) );
4640
4641 /* allocate memory for fixed variables */
4642 SCIP_CALL( SCIPallocBufferArray(scip, &fixvars, nfixedvars) );
4643
4644 for( v = nfixedvars - 1; v >= 0; --v )
4645 {
4646 /* create variable name */
4647 var = fixedvars[v];
4648
4650 {
4651 size_t l;
4653 if( l >= MPS_MAX_NAMELEN )
4655 else
4656 maxnamelen = MAX(maxnamelen, (unsigned int) l);
4657
4660
4661 varnames[startpos + nfixvars] = namestr;
4662 fixvars[nfixvars] = var;
4663 ++nfixvars;
4664
4665 /* insert variable with variable name into hash map */
4668
4669 /* add the fixed variables to the sparse matrix, needed for columns section */
4671 matrix->values[matrix->nentries] = 0.0;
4672 matrix->columns[matrix->nentries] = var;
4673 matrix->rows[matrix->nentries] = "Obj";
4674 matrix->nentries++;
4675 }
4676 }
4677 }
4678
4679 /* output COLUMNS section */
4681
4682 /* output RHS section */
4683 printRhsSection(scip, file, nconss + naddrows +naggvars, consnames, rhss, maxnamelen, objscale * objoffset);
4684
4685 /* output RANGES section */
4686 if( needRANGES )
4687 printRangeSection(scip, file, conss, nconss, consnames, transformed, maxnamelen);
4688
4689 /* output BOUNDS section */
4691
4692 if( nfixedvars > 0 )
4693 {
4695 }
4696
4697 /* print SOS section */
4698 if( nConsSOS1 > 0 || nConsSOS2 > 0 )
4699 {
4700 SCIP_Real* sosweights;
4701
4702 SCIPinfoMessage(scip, file, "SOS\n");
4703 SCIPdebugMsg(scip, "start printing SOS section\n");
4704
4706
4707 /* first output SOS1 constraints */
4708 for( c = 0; c < nConsSOS1; ++c )
4709 {
4710 cons = consSOS1[c];
4711 consvars = SCIPgetVarsSOS1(scip, cons);
4712 nconsvars = SCIPgetNVarsSOS1(scip, cons);
4713 sosweights = SCIPgetWeightsSOS1(scip, cons);
4715
4716 printStart(scip, file, "S1", namestr, -1);
4717 SCIPinfoMessage(scip, file, "\n");
4718
4719 for( v = 0; v < nconsvars; ++v )
4720 {
4721 /* get variable name */
4722 assert ( SCIPhashmapExists(varnameHashmap, consvars[v]) );
4723 varname = (const char*) SCIPhashmapGetImage(varnameHashmap, consvars[v]);
4724
4725 printStart(scip, file, "", varname, (int) maxnamelen);
4726
4727 if( sosweights != NULL )
4728 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", sosweights[v]);
4729 else
4730 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25d ", v);
4731
4732 SCIPinfoMessage(scip, file, "%25s\n", valuestr);
4733 }
4734 }
4735
4736 /* next output SOS2 constraints */
4737 for( c = 0; c < nConsSOS2; ++c )
4738 {
4739 cons = consSOS2[c];
4740 consvars = SCIPgetVarsSOS2(scip, cons);
4741 nconsvars = SCIPgetNVarsSOS2(scip, cons);
4742 sosweights = SCIPgetWeightsSOS2(scip, cons);
4744
4745 printStart(scip, file, "S2", namestr, -1);
4746 SCIPinfoMessage(scip, file, "\n");
4747
4748 for( v = 0; v < nconsvars; ++v )
4749 {
4750 /* get variable name */
4751 assert ( SCIPhashmapExists(varnameHashmap, consvars[v]) );
4752 varname = (const char*) SCIPhashmapGetImage(varnameHashmap, consvars[v]);
4753
4754 printStart(scip, file, "", varname, (int) maxnamelen);
4755
4756 if( sosweights != NULL )
4757 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", sosweights[v]);
4758 else
4759 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25d ", v);
4760
4761 SCIPinfoMessage(scip, file, "%25s\n", valuestr);
4762 }
4763 }
4765 }
4766
4767 /* print QCMATRIX sections for quadratic constraints
4768 * in difference to a quadratic term in the objective function, the quadratic part is not divided by 2 here
4769 */
4770 if( nConsQuadratic > 0 )
4771 {
4772 const char* varname2;
4773 int nbilin;
4774
4775 SCIPdebugMsg(scip, "start printing QCMATRIX sections for quadratic constraints\n");
4777
4778 for( c = 0; c < nConsQuadratic; ++c )
4779 {
4780 SCIP_EXPR* expr;
4781
4782 cons = consQuadratic[c];
4783 expr = SCIPgetExprNonlinear(cons);
4784
4785 SCIPexprGetQuadraticData(expr, NULL, NULL, NULL, NULL, &nconsvars, &nbilin, NULL, NULL);
4786
4788
4789 SCIPinfoMessage(scip, file, "QCMATRIX %s\n", namestr);
4790
4791 /* print x^2 terms */
4792 for( v = 0; v < nconsvars; ++v )
4793 {
4794 SCIP_EXPR* qexpr;
4795 SCIP_VAR* qvar;
4796 SCIP_Real sqrcoef;
4797
4798 SCIPexprGetQuadraticQuadTerm(expr, v, &qexpr, NULL, &sqrcoef, NULL, NULL, NULL);
4799 if( sqrcoef == 0.0 )
4800 continue;
4801
4802 assert(SCIPisExprVar(scip, qexpr));
4803 qvar = SCIPgetVarExprVar(qexpr);
4804
4805 /* get variable name */
4808
4809 /* get coefficient as string */
4810 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", sqrcoef);
4811
4812 /* print "x x coeff" line */
4813 printStart(scip, file, "", varname, (int) maxnamelen);
4815 SCIPinfoMessage(scip, file, "\n");
4816 }
4817
4818 /* print bilinear terms; CPLEX format expects a symmetric matrix with all coefficients specified,
4819 * i.e., we have to split bilinear coefficients into two off diagonal elements */
4820 for( v = 0; v < nbilin; ++v )
4821 {
4822 SCIP_EXPR* expr1;
4823 SCIP_EXPR* expr2;
4824 SCIP_VAR* var1;
4825 SCIP_VAR* var2;
4826 SCIP_Real coef;
4827
4828 SCIPexprGetQuadraticBilinTerm(expr, v, &expr1, &expr2, &coef, NULL, NULL);
4829 assert(SCIPisExprVar(scip, expr1));
4830 assert(SCIPisExprVar(scip, expr2));
4831
4832 if( coef == 0.0 )
4833 continue;
4834
4835 var1 = SCIPgetVarExprVar(expr1);
4836 var2 = SCIPgetVarExprVar(expr2);
4837
4838 /* get name of first variable */
4841
4842 /* get name of second variable */
4845
4846 /* get coefficient as string */
4847 (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", 0.5*coef);
4848
4849 /* print "x y coeff/2" line */
4850 printStart(scip, file, "", varname, (int) maxnamelen);
4852 SCIPinfoMessage(scip, file, "\n");
4853
4854 /* print "y x coeff/2" line */
4855 printStart(scip, file, "", varname2, (int) maxnamelen);
4857 SCIPinfoMessage(scip, file, "\n");
4858 }
4859 }
4860
4862 }
4863
4864 /* print indicator section */
4865 if( nConsIndicator > 0 )
4866 {
4868
4869 SCIPinfoMessage(scip, file, "INDICATORS\n");
4870 SCIPdebugMsg(scip, "start printing INDICATOR section\n");
4871
4872 /* output each indicator constraint */
4873 for( c = 0; c < nConsIndicator; ++c )
4874 {
4875 SCIP_CONS* lincons;
4876 SCIP_VAR* slackvar;
4877 SCIP_VAR* binvar;
4878
4879 cons = consIndicator[c];
4880 binvar = SCIPgetBinaryVarIndicator(cons);
4881 lincons = SCIPgetLinearConsIndicator(cons);
4882 slackvar = SCIPgetSlackVarIndicator(cons);
4883
4884 /* linvars always contains slack variable, thus nlinvars >= 1 */
4885 if( SCIPgetNVarsLinear(scip, lincons) <= 1 || SCIPconsIsDeleted(lincons) )
4886 continue;
4887
4888 /* create variable and value strings */
4889 if( SCIPvarIsNegated(binvar) )
4890 {
4892 assert( SCIPvarGetNegatedVar(binvar) != NULL );
4895 }
4896 else
4897 {
4900 varname = (const char*) SCIPhashmapGetImage(varnameHashmap, binvar);
4901 }
4902
4903 /* write records */
4905 {
4906 /* for aggregated variables output name of aggregating constraint */
4907 (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "aggr_%s", SCIPvarGetName(slackvar));
4908 printStart(scip, file, "IF", namestr, (int) maxnamelen);
4910 SCIPinfoMessage(scip, file, "\n");
4911 }
4912 else
4913 {
4914 printStart(scip, file, "IF", SCIPconsGetName(lincons), (int) maxnamelen);
4916 SCIPinfoMessage(scip, file, "\n");
4917 }
4918 }
4920 }
4921
4922 /* free matrix data structure */
4923 freeMatrix(scip, matrix);
4924
4925 /* free slackvar hashtable */
4926 if( indicatorSlackHash != NULL )
4928
4929 /* free variable hashmap */
4931
4934
4935 /* free buffer arrays for SOS1, SOS2, and quadratic */
4940
4941 /* free variable and constraint name array */
4942 for( v = nvars + naggvars + nfixvars - 1; v >= 0; --v )
4943 SCIPfreeBufferArray(scip, &varnames[v]);
4944 SCIPfreeBufferArray(scip, &varnames);
4945
4946 for( c = nconss + naddrows + naggvars - 1; c >= 0; --c )
4947 SCIPfreeBufferArray(scip, &consnames[c]);
4948 SCIPfreeBufferArray(scip, &consnames);
4949
4950 /* print end of data line */
4951 SCIPinfoMessage(scip, file, "ENDATA");
4952
4954
4955 return SCIP_OKAY;
4956}
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 SCIP_MAXSTRLEN
Definition def.h:302
#define SCIP_Real
Definition def.h:186
#define SCIP_HASHSIZE_NAMES
Definition def.h:313
#define TRUE
Definition def.h:95
#define FALSE
Definition def.h:96
#define SCIP_CALL_TERMINATE(retcode, x, TERM)
Definition def.h:409
#define SCIPABORT()
Definition def.h:360
#define REALABS(x)
Definition def.h:210
#define SCIP_CALL(x)
Definition def.h:388
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 SCIPcreateConsIndicatorLinCons(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *binvar, SCIP_CONS *lincons, SCIP_VAR *slackvar, 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 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:2582
SCIP_VAR ** SCIPgetVarsSOS2(SCIP *scip, SCIP_CONS *cons)
Definition cons_sos2.c:2557
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:5175
SCIP_RETCODE SCIPaddVarSOS1(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real weight)
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:5126
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)
SCIP_VAR * SCIPgetVbdvarVarbound(SCIP *scip, SCIP_CONS *cons)
int SCIPgetNVarsSetppc(SCIP *scip, SCIP_CONS *cons)
int SCIPgetNVarsSOS2(SCIP *scip, SCIP_CONS *cons)
Definition cons_sos2.c:2532
SCIP_Real * SCIPgetWeightsSOS1(SCIP *scip, SCIP_CONS *cons)
SCIP_VAR ** SCIPgetVarsSetppc(SCIP *scip, SCIP_CONS *cons)
SCIP_EXPR * SCIPgetExprNonlinear(SCIP_CONS *cons)
SCIP_Real SCIPgetRhsNonlinear(SCIP_CONS *cons)
SCIP_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)
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:2382
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)
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:5150
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 SCIPchgLhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real lhs)
int SCIPgetNVarsSOS1(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPgetLhsNonlinear(SCIP_CONS *cons)
SCIP_RETCODE SCIPaddVarSOS2(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real weight)
Definition cons_sos2.c:2481
@ 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)
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)
SCIP_RETCODE SCIPincludeReaderMps(SCIP *scip)
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:3058
void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
Definition misc.c:3211
SCIP_RETCODE SCIPhashmapInsert(SCIP_HASHMAP *hashmap, void *origin, void *image)
Definition misc.c:3106
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition misc.c:3024
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
Definition misc.c:3373
void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
Definition misc.c:2296
SCIP_Bool SCIPhashtableExists(SCIP_HASHTABLE *hashtable, void *element)
Definition misc.c:2609
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:2246
void * SCIPhashtableRetrieve(SCIP_HASHTABLE *hashtable, void *key)
Definition misc.c:2558
SCIP_RETCODE SCIPhashtableInsert(SCIP_HASHTABLE *hashtable, void *element)
Definition misc.c:2497
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
#define SCIPdebugMsg
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition scip_param.c:250
SCIP_RETCODE 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:4180
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition scip_cons.c:886
SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
Definition cons.c:8347
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition cons.c:8108
SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
Definition cons.c:8257
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
Definition cons.c:8287
SCIP_Bool SCIPconsIsDeleted(SCIP_CONS *cons)
Definition cons.c:8217
SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
Definition cons.c:8277
SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
Definition cons.c:8307
SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
Definition cons.c:8327
SCIP_Bool SCIPconsIsEnabled(SCIP_CONS *cons)
Definition cons.c:8185
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition cons.c:8088
SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
Definition cons.c:8337
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition scip_cons.c:1119
SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
Definition cons.c:8267
SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
Definition cons.c:8357
void SCIPexprGetQuadraticBilinTerm(SCIP_EXPR *expr, int termidx, SCIP_EXPR **expr1, SCIP_EXPR **expr2, SCIP_Real *coef, int *pos2, SCIP_EXPR **prodexpr)
Definition expr.c:4145
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:4060
SCIP_Bool SCIPisExprVar(SCIP *scip, SCIP_EXPR *expr)
Definition scip_expr.c:1421
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:4105
#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 SCIPsetReaderCopy(SCIP *scip, SCIP_READER *reader,)
SCIP_RETCODE SCIPincludeReaderBasic(SCIP *scip, SCIP_READER **readerptr, const char *name, const char *desc, const char *extension, SCIP_READERDATA *readerdata)
SCIP_READERDATA * SCIPreaderGetData(SCIP_READER *reader)
Definition reader.c:492
SCIP_RETCODE SCIPsetReaderWrite(SCIP *scip, SCIP_READER *reader,)
SCIP_RETCODE SCIPsetReaderRead(SCIP *scip, SCIP_READER *reader,)
const char * SCIPreaderGetName(SCIP_READER *reader)
Definition reader.c:557
SCIP_RETCODE SCIPsetReaderFree(SCIP *scip, SCIP_READER *reader,)
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 SCIPisIntegral(SCIP *scip, SCIP_Real val)
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:12763
SCIP_VAR * SCIPvarGetNegatedVar(SCIP_VAR *var)
Definition var.c:17716
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:17360
int SCIPvarGetNLocksUpType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
Definition var.c:3353
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition var.c:17966
SCIP_Real SCIPvarGetLbOriginal(SCIP_VAR *var)
Definition var.c:17846
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:17748
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition var.c:17406
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition var.c:17910
int SCIPvarGetIndex(SCIP_VAR *var)
Definition var.c:17580
const char * SCIPvarGetName(SCIP_VAR *var)
Definition var.c:17241
SCIP_Real SCIPvarGetUbOriginal(SCIP_VAR *var)
Definition var.c:17866
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition scip_var.c:1248
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition var.c:17432
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:17956
SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
Definition var.c:17396
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:17900
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:10788
void SCIPprintSysError(const char *message)
Definition misc.c:10680
char * SCIPstrtok(char *s, const char *delim, char **ptrptr)
Definition misc.c:10729
int SCIPmemccpy(char *dest, const char *src, char stop, unsigned int cnt)
Definition misc.c:10655
return SCIP_OKAY
int c
assert(minobj< SCIPgetCutoffbound(scip))
int nvars
SCIP_VAR * var
SCIP_Real objscale
static SCIP_Bool propagate
static SCIP_VAR ** vars
int nbinvars
int nintvars
#define NULL
Definition lpi_spx1.cpp:161
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)
#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)
static SCIP_RETCODE readSOS(MPSINPUT *mpsi, SCIP *scip)
static void printRhsSection(SCIP *scip, FILE *file, int nconss, const char **consnames, SCIP_Real *rhss, unsigned int maxnamelen, SCIP_Real objoffset)
struct SparseMatrix SPARSEMATRIX
Definition reader_mps.c:161
static const char * mpsinputField1(const MPSINPUT *mpsi)
Definition reader_mps.c:243
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)
static SCIP_RETCODE readQMatrix(MPSINPUT *mpsi, SCIP_Bool isQuadObj, SCIP *scip)
static SCIP_Bool mpsinputHasError(const MPSINPUT *mpsi)
Definition reader_mps.c:320
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)
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)
static void mpsinputSetObjname(MPSINPUT *mpsi, const char *objname)
Definition reader_mps.c:368
static SCIP_RETCODE initializeMatrix(SCIP *scip, SPARSEMATRIX **matrix, int slots)
static void freeMatrix(SCIP *scip, SPARSEMATRIX *matrix)
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)
static void mpsinputSetProbname(MPSINPUT *mpsi, const char *probname)
Definition reader_mps.c:354
static void printRangeSection(SCIP *scip, FILE *file, SCIP_CONS **conss, int nconss, const char **consnames, SCIP_Bool transformed, unsigned int maxnamelen)
#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)
#define MPS_MAX_FIELDLEN
Definition reader_mps.c:92
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)
#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)
static void printRowType(SCIP *scip, FILE *file, SCIP_Real lhs, SCIP_Real rhs, const char *name)
static SCIP_RETCODE readRanges(MPSINPUT *mpsi, SCIP *scip)
static SCIP_RETCODE mpsinputCreate(SCIP *scip, MPSINPUT **mpsi, SCIP_FILE *fp)
Definition reader_mps.c:173
static unsigned int computeFieldWidth(unsigned int width)
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)
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)
static void printStart(SCIP *scip, FILE *file, const char *col1, const char *col2, int maxnamelen)
static SCIP_RETCODE readIndicators(MPSINPUT *mpsi, SCIP *scip)
#define READER_NAME
Definition reader_mps.c:78
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)
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)
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)
static SCIP_RETCODE readBounds(MPSINPUT *mpsi, SCIP *scip)
#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
#define MAX(x, y)
Definition tclique_def.h:92
@ 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
@ SCIP_VERBLEVEL_NORMAL
@ SCIP_VERBLEVEL_FULL
#define SCIP_DECL_HASHKEYEQ(x)
Definition type_misc.h:194
#define SCIP_DECL_HASHGETKEY(x)
Definition type_misc.h:191
#define SCIP_DECL_HASHKEYVAL(x)
Definition type_misc.h:197
@ SCIP_OBJSENSE_MAXIMIZE
Definition type_prob.h:47
@ SCIP_OBJSENSE_MINIMIZE
Definition type_prob.h:48
enum SCIP_Objsense SCIP_OBJSENSE
Definition type_prob.h:50
#define SCIP_DECL_READERWRITE(x)
struct SCIP_ReaderData SCIP_READERDATA
Definition type_reader.h:53
#define SCIP_DECL_READERREAD(x)
Definition type_reader.h:87
#define SCIP_DECL_READERCOPY(x)
Definition type_reader.h:62
#define SCIP_DECL_READERFREE(x)
Definition type_reader.h:71
@ SCIP_SUCCESS
Definition type_result.h:58
enum SCIP_Result SCIP_RESULT
Definition type_result.h:61
@ SCIP_NOFILE
@ SCIP_READERROR
@ SCIP_INVALIDDATA
@ SCIP_PLUGINNOTFOUND
enum SCIP_Retcode SCIP_RETCODE
@ 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