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