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