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