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