Scippy

SCIP

Solving Constraint Integer Programs

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