Scippy

SCIP

Solving Constraint Integer Programs

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